You are not logged in.

#1 2010-04-25 18:55:15

Meskarune
Member
From: Helsinki, Finland
Registered: 2009-03-21
Posts: 361
Website

Midori Web Browser and user scripts

I've fallen in love with Midori. Its very fast and lightweight (uses a fourth of FF's memory use) And it supports user css and scripts. Its really come unto its own as a fast and full featured browser. Save for a crash once in a while from sites with tons of flash ads...

I do adblocking with my host file
I use the myfavcolors script from user styles to theme sites dark with light text

I am only missing two things. Flash block and some sort of delicious bookmarks support. (not as important as flash block)

I've tried different flash block scripts I've found online. (where you double click or click "play" to have flash run) But I haven't found one that works with Midori. Perferebly it would also have a white list. This seemed promising:

// ==UserScript==
// @name        BlockFlash-Revisited
// @namespace        http://snippets.dzone.com/posts/show/3054
// @description    Do not start Flash animation until you click on them.
// @include        *
// @exclude        http://www.macromedia.com/*
// @exclude        http://www.atomfilms.com/*
// @exclude        http://uploads.ungrounded.net/*
// @exclude        http://www.albinoblacksheep.com/*
// ==/UserScript==

/*
    Revised by Andrew Pennebaker (andrew.pennebaker@gmail.com)

    Author: Jos van den Oever (jos@vandenoever.info)

    Version history:
        2006-02-12: initial version
        2006-11-28: changed appearance

Inspiration for this script comes from the removeFlash script and the FlashBlock firefox extension.
*/

(function () {
    var objects=document.getElementsByTagName("object");

    for (i=0; i<objects.length; i++) {
        var flash=objects[i];

        if (flash.innerHTML.match(/.swf|shockwave|flash/)) {
            var placeholder=document.createElement("div");

            placeholder.style.cursor='pointer';
            placeholder.style.background='orange'; // 'gray '
            placeholder.style.textAlign='center';
            placeholder.style.color='black';
            placeholder.innerHTML="[Play Flash]";

            flash.parentNode.insertBefore(placeholder, flash);
            flash.on=false;

            placeholder.addEventListener(
                'click',
                function() {
                    if (flash.on) {
                        flash.style.display='none';
                        placeholder.innerHTML="[Play Flash]";
                        flash.on=false;
                    }
                    else {
                        flash.style.display='';
                        placeholder.innerHTML="[Stop Flash]";
                        flash.on=true;
                    }
                },
                true
            );

            flash.style.display='none';
        }
    }
})();

What scripts do you guys/gals use with Midori? (or opera or chrome for that matter) Does anyone have a good flashblock script available?


Homepage  | Arch Linux Women | Arch Linux Classroom
Acer Aspire E5-575G-53VG:
Intel Dual-Core i5-6200U 2.3 GHz; Skylake rev3 | 8GB DDR4 ram | Intel HD Graphics 520 + NVIDIA GeForce 940MX
Qualcomm Atheros QCA9377 802.11ac | Realtek RTL8111/8168/8411 Gigabit Ethernet Controller

Offline

#2 2010-04-25 21:47:54

Andrwe
Member
From: Leipzig/Germany
Registered: 2009-06-17
Posts: 322
Website

Re: Midori Web Browser and user scripts

Hi,

I'm fallen for midori too. smile

This is the script I'm using for flashblocking:
http://userscripts.org/scripts/show/45343

And if you want to do hinting vimperator-like here are the scripts I'm using:

// KeyNav
// version 0.1.1 beta
// Itamar Benzaken
//
// --------------------------------------------------------------------
//
// This is a Greasemonkey user script.
//
// To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "KeyNav", and click Uninstall.
//
// --------------------------------------------------------------------
//
// ==UserScript==
// @name          KeyNav
// @description   Enables keyboard navigation
// @namespace     tag:itamar.benzaken@gmail.com,2008-09-10:KeyNav
// @include       *
// ==/UserScript==

/*

@what

The script enables keyboard navigation.

@how

Pressing a hotkey displays a (or hides the) label near each clickable element.
Pressing the shortcut triggers the "click" for the associated element.

@structure

- A Map object: enables mapping of a String (the shortcut) to an Object (the DOM element).
- A Configuration object: contains anything that can be "externalized" (preferences, actual label generation, etc).
- A KeyNav object: the main object that handles all the messy stuff.

@changelog

0.1
    initial
    
0.1.1
    - added labels index for faster looking up of labels
    - moved creation of labels to initialization
    - added event handler for invalidating labels when document changes
*/

//javascript.options.strict = true;
//browser.dom.window.dump.enabled = true;

function Map() {
    function LOG(message) {
        //window.dump( "[Map] " + message + "\n");
    }
    
    // internal map
    var map;
    
    var bEmpty;
    
    /* returns the value associated with the given key
    * 
    * @param key
    * @return the associated value, or null if none
    */
    this.getValue = function (key) {
        if (key in map)
        return map[key];
        
        return null;
    }
    
    /* returns a set of values whose keys pass a certain filter
    *
    * @param predicate a filter Function [key->Boolean] that returns True
    *        iff the key's value should be included in the result set
    * @return a values Array 
    */
    this.getValuesByPredicate = function (predicate) {
        var values = new Array(0);
        
        for (key in map) {
            if ( predicate(key) ) {
                values.push( map[key] );
            }
        }
        
        return values;
    }
    
    /* add a key=value binding
    *
    * @param val
    * @param key
    */
    this.setValue = function (key, val) {
        bEmpty = false;
        map[key] = val;
        LOG( "bound \"" + key + "\" to " + val);
    }
    
    this.clear = function () {
        map = new Object();
        bEmpty = true;
    }
    
    this.isEmpty = function() {
        return bEmpty;
    }
    
    this.keys = function () {
        var keys = new Array();
        
        for ( var key in map ) {
            keys.push(key);
        }
        
        return keys;
    }
    
    this.values = function () {
        var values = new Array();
        
        for ( var key in map ) {
            values.push( map[key] );
        }
        
        return values;
    }
    
    this.clear();
}

/* Configuration object */
function Configuration() {
    function LOG(message) {
        //window.dump( "[Configuration] " + message + "\n");
    }
    
    this.getPreference = function (key) {
        if ( key=="activationKeyCode" ) {
            return 70; //f
        }
        else if ( key=="deactivationKeyCode" ) {
            return 70; //f
        }
        else
            return null;
    }
    
    /* returns a UNIQUE shortcut calculated using `ndx`
    *
    * @param ndx a non negative integer Number
    * @return a unique (in terms of ndx) String
    */
    this.generateShortcut = function (ndx) {
        return ndx;
    }
    
    this.createLabel = function(element,shortcut) {
        var overlay = getElementOverlay(element);
        var overlayId = "keynav.shortcut["+shortcut+"]";
        
        // no overlay at all yet? create one
        if (!overlay) {
            LOG("creating a new empty, hidden overlay");
            
            overlay = document.createElement("span");
            overlay.style.position = "absolute";
            overlay.style.background = "lightyellow";
            overlay.style.fontSize = "small";
            overlay.style.fontColor = "black";
            overlay.style.border = "1px dashed darkgray";
            overlay.style.fontColor = "black";
            overlay.style.visibility = "hidden";
            overlay.style.padding = "1px";
            
            // insert as a sibling, because the element itself might not be able
            // to have children (like a Button, for example)
            element.parentNode.insertBefore(overlay,element);
        }
        
        // new/wrong shortcut? fix shortcut
        if ( (!overlay.id) | (overlay.id!=overlayId) ) {
            LOG("changing overlay id from '" + overlay.id + "' to '" + overlayId + "'");
            
            overlay.id = overlayId;
            overlay.innerHTML = "<font color=\"black\">" + shortcut + "</font>";
            element.setAttribute( "keynav:shortcut", shortcut );
        }
        else {
            LOG("overlay already exists for id: " + overlayId);
        }
        
        return overlay;
    }
    
    /** Returns the shortcut overlay of the specified element
    * 
    * @param element
    * @return 
    */
    function getElementOverlay(element) {
        if ( element.hasAttribute("keynav:shortcut") ) {
            var shortcutElementId = "keynav.shortcut[" + 
                    element.getAttribute("keynav:shortcut") + "]";
            
            var shortcutElement = document.getElementById(shortcutElementId);
            
            return shortcutElement;
        } else {
            return null;
        }
    }
    
    /** highlights (or dims) the element's shortcut.
    *
    * @param element the Element whose shortcut is to be highlighted/dimmed
    * @param on a Boolean - true to highlight, false to dim.
    */
    this.highlightShortcut = function (element,on) {
        var overlay = getElementOverlay(element);
        
        if (overlay) {
            overlay.style.background = on ? "lightgreen" : "lightyellow";
            overlay.style.border = on ? "1px solid black" : "1px dashed darkgray";
        }
    }
    
    /** Selects the elements of the document to assign shortcuts to
    *
    * @return an array of Elements
    */
    this.getClickableElements = function() {
        var ems = new Array(0);
        
        function addClickableElementsIn( parent ) {
            
            for (var i=0; i<parent.childNodes.length; ++i) {
                var node = parent.childNodes[i];
                
                if (node.nodeType!=1) {
                    continue;
                }
                
                var clickable = node.nodeName.toLowerCase()=="input" |
                        node.nodeName.toLowerCase()=="select" |
                        node.hasAttribute("href") |
                        node.hasAttribute("onclick");
                
                if ( clickable ) {
                    ems.push(node);
                }
                
                addClickableElementsIn(node);
            }
        }
        
        addClickableElementsIn(document);
        
        return ems;
    }
    
    /** Simulates a user-click on an element
    * 
    * @param element the element that should be "clicked"
    */
    this.simulateClick = function (element, wind) {
        
        if ( element.nodeName.toLowerCase()=="input" ) {
            // only INPUT elements implement the click() method
            
            element.focus();
            element.click();
        }
        if ( element.nodeName.toLowerCase()=="select" ) {
            element.focus();
        }
        else if (element.hasAttribute("onclick")) {
            // must come before checking "href" because links may have a
            // pseudo "href" but a real "onclick"
            var evt = document.createEvent("MouseEvents");
            evt.initMouseEvent("click", true, true, window, 0,
   0, 0, 0, 0, false, false, false, false, 0, null);
   element.dispatchEvent(evt);
        }
        else if (element.hasAttribute("href")) {
            window.location = element.getAttribute("href");
        }
        
    }
}

function KeyNav() {
    function LOG(message) {
        //window.dump( "[KeyNav] " + message + "\n");
    }
    
    /** displays information that most users will find useful
    *
    * @param message a String to display to the user
    */
    var displayOverlay;
    function display(message) {
        if (!displayOverlay) {
            displayOverlay = document.createElement("div");
            
            displayOverlay.style.position = "fixed";
            displayOverlay.style.display = "block";
            displayOverlay.style.left = "40%";
            displayOverlay.style.top = "40%";
            displayOverlay.style.background = "lightgreen";
            displayOverlay.style.border = "1px dashed black";
            displayOverlay.style.padding = "2px";
            displayOverlay.style.zorder = 500;
            displayOverlay.style.opacity = 0.8;
            displayOverlay.setAttribute("align","center");
            
            document.getElementsByTagName("body")[0].appendChild( displayOverlay );
        }
        
        if (message=="") {
            displayOverlay.style.visibility = "hidden";
        } else {
            displayOverlay.style.visibility = "visible";
            displayOverlay.innerHTML = message;
        }
    }
    
    var conf = new Configuration();
    var bindings = new Map(); //maps Strings (shortcuts) to Elements
    
    var acceptInput = false; //off by default
    
    // last searched shortcut.
    // the shortcut is searched incrementally
    var lastShortcut = "";
    
    /** highlights the overlays for the specified elements. Dims all other
    *  elements
    *
    * @param targets an Elements array whose overlays should be highlighted
    */
    function highlightOverlays( targets ) {
        //TODO use _labels instead of bindings.values()
        
        // trivial implementation: dims all elements and highlights the
        // specified ones
        
        // dim all elements
        var allTargets = bindings.values();
        for (var i=0; i<allTargets.length; ++i) {
            conf.highlightShortcut( allTargets[i], false );
        }
        
        // highlight specified elements
        for (var i=0; i<targets.length; ++i) {
            conf.highlightShortcut( targets[i], true );
        }
    }
    
    var _labels = new Array(0);
    var _labelsValid = false;
    
    function invalidate() {
        _labelsValid = false;
        LOG("invalidated");
    }
    
    function isValid() {
        return _labelsValid;
    }
    
    function createLabels() {
        _labels = new Array(0);
        bindings.clear();
        
        var clickableElements = conf.getClickableElements();
        
        for (var i=0; i<clickableElements.length; ++i) {
            var element = clickableElements[i];
            var shortcut = conf.generateShortcut(i);
            var label = conf.createLabel(element,shortcut);
            
            bindings.setValue( shortcut, element );
            _labels.push( label );
        }
        
        _labelsValid = true;
        LOG("labels are now valid");
    }
    
    function showLabels() {
        for (var i=0; i<_labels.length; ++i) {
            _labels[i].style.visibility = "visible";
        }
    }
    
    function hideLabels() {
        for (var i=0; i<_labels.length; ++i) {
            _labels[i].style.visibility = "hidden";
        }
    }
    
    /* toggles keyboard navigation on/off for the current document
    *
    * @param en a Boolean
    */
    function toggle(en) {
        if (en) {
            // suspend the event handler until all labels are created (and 
            // inserted to the document)
            document.removeEventListener("DOMNodeInserted",invalidate,true);
            
            if (!isValid()) {
                createLabels();
            }
            
            showLabels();
            
            acceptInput = true;
            display("");
            
            // whenever the document changes, invalidate the labels
            document.addEventListener("DOMNodeInserted",invalidate,true);
            
            LOG("enabled");
        }
        else {
            acceptInput = false;
            hideLabels();
            display("");
            LOG("disabled");
        }
    }
    
    function onKeyPress(evt) {
        if (!acceptInput) return;
        
        // append pressed character to the shortcut we are going to lookup
        var ch = String.fromCharCode(evt.charCode).toLowerCase();
        lastShortcut += ch;
        
        // lookup targets starting with the shortcut
        var targets = bindings.getValuesByPredicate( function(key){
            if ( key.substring(0,lastShortcut.length)==lastShortcut )
            return true;
            else
                return false;
        } );
        
        highlightOverlays( targets );
        
        if ( targets.length==0 ) {
            // no targets at all - start a new search next time
            display("");
            
            LOG(lastShortcut + " is unbound. clearing");
            lastShortcut = "";
        }
        else if ( targets.length==1 ) {
            // exactly one match - navigate to target, and start a new search
            // next time
            display("");
            
            LOG(lastShortcut + " bound to 1 target. clearing. navigating");
            
            if (targets[0]) {
                toggle(false);
                conf.simulateClick(targets[0]);
            }
            else {
                LOG("no target for sequence: " + lastShortcut);
            }
            
            lastShortcut = "";
        }
        else {
            // more than one match - do nothing. next search will be appended
            display("Keep typing.. " + targets.length +
                    " elements match so far<br>(or press Enter to \"click\" " +
                    lastShortcut + ")");
            
            LOG(lastShortcut + " bound to " + targets.length + " targets");
        }
    }
    
    function onKeyDown(evt) {
        var currEle = document.activeElement;
        if ( currEle.tagName == "input" | currEle.tagName == "INPUT" | currEle.tagName == "textarea" | currEle.tagName == "TEXTAREA" )
        {
            toggle(false);
            return;
        }
        // activation
        if (!acceptInput & evt.keyCode==conf.getPreference("activationKeyCode")) {
            toggle(true);
        }
        // deactivation
        else if (acceptInput & evt.keyCode==conf.getPreference("deactivationKeyCode")) {
            toggle(false);
            return;
        }
        
        if (!acceptInput) return;
        
        switch (evt.keyCode) {
            //case KeyEvent.DOM_VK_RETURN:
            case 0x0D: //KeyEvent.DOM_VK_ENTER:
                    // match the exact shortcut typed so far
                    
                    var target = bindings.getValue(lastShortcut);
            LOG("match for exact shortcut " + lastShortcut + ": " + target);
                    
            if (target) {
                toggle(false);
                conf.simulateClick(target);
            }
            
            lastShortcut = "";
            
            break;
        }
    }
    
    function installEventListeners() {
        window.addEventListener("keydown",onKeyDown,true);
        window.addEventListener("keypress",onKeyPress,true);
    }
    
    createLabels();
    installEventListeners();
}

var keynav = new KeyNav();

This one is for opening a link in the same tab using 'f'.

// KeyNav
// version 0.1.1 beta
// Itamar Benzaken
//
// --------------------------------------------------------------------
//
// This is a Greasemonkey user script.
//
// To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "KeyNav", and click Uninstall.
//
// --------------------------------------------------------------------
//
// ==UserScript==
// @name          KeyNavNT
// @description   Enables keyboard navigation
// @namespace     tag:itamar.benzaken@gmail.com,2008-09-10:KeyNav
// @include       *
// ==/UserScript==

/*

@what

The script enables keyboard navigation.

@how

Pressing a hotkey displays a (or hides the) label near each clickable element.
Pressing the shortcut triggers the "click" for the associated element.

@structure

- A Map object: enables mapping of a String (the shortcut) to an Object (the DOM element).
- A Configuration object: contains anything that can be "externalized" (preferences, actual label generation, etc).
- A KeyNav object: the main object that handles all the messy stuff.

@changelog

0.1
    initial
    
0.1.1
    - added labels index for faster looking up of labels
    - moved creation of labels to initialization
    - added event handler for invalidating labels when document changes
*/

//javascript.options.strict = true;
//browser.dom.window.dump.enabled = true;

function Map() {
    function LOG(message) {
        //window.dump( "[Map] " + message + "\n");
    }
    
    // internal map
    var map;
    
    var bEmpty;
    
    /* returns the value associated with the given key
    * 
    * @param key
    * @return the associated value, or null if none
    */
    this.getValue = function (key) {
        if (key in map)
        return map[key];
        
        return null;
    }
    
    /* returns a set of values whose keys pass a certain filter
    *
    * @param predicate a filter Function [key->Boolean] that returns True
    *        iff the key's value should be included in the result set
    * @return a values Array 
    */
    this.getValuesByPredicate = function (predicate) {
        var values = new Array(0);
        
        for (key in map) {
            if ( predicate(key) ) {
                values.push( map[key] );
            }
        }
        
        return values;
    }
    
    /* add a key=value binding
    *
    * @param val
    * @param key
    */
    this.setValue = function (key, val) {
        bEmpty = false;
        map[key] = val;
        LOG( "bound \"" + key + "\" to " + val);
    }
    
    this.clear = function () {
        map = new Object();
        bEmpty = true;
    }
    
    this.isEmpty = function() {
        return bEmpty;
    }
    
    this.keys = function () {
        var keys = new Array();
        
        for ( var key in map ) {
            keys.push(key);
        }
        
        return keys;
    }
    
    this.values = function () {
        var values = new Array();
        
        for ( var key in map ) {
            values.push( map[key] );
        }
        
        return values;
    }
    
    this.clear();
}

/* Configuration object */
function Configuration() {
    function LOG(message) {
        //window.dump( "[Configuration] " + message + "\n");
    }
    
    this.getPreference = function (key) {
        if ( key=="activationKeyCode" ) {
            return 78; //F12
        }
        else if ( key=="deactivationKeyCode" ) {
            return 78; //F12
        }
        else
            return null;
    }
    
    /* returns a UNIQUE shortcut calculated using `ndx`
    *
    * @param ndx a non negative integer Number
    * @return a unique (in terms of ndx) String
    */
    this.generateShortcut = function (ndx) {
        return ndx;
    }
    
    this.createLabel = function(element,shortcut) {
        var overlay = getElementOverlay(element);
        var overlayId = "keynav.shortcut["+shortcut+"]";
        
        // no overlay at all yet? create one
        if (!overlay) {
            LOG("creating a new empty, hidden overlay");
            
            overlay = document.createElement("span");
            overlay.style.position = "absolute";
            overlay.style.background = "lightyellow";
            overlay.style.fontSize = "small";
            overlay.style.fontColor = "black";
            overlay.style.border = "1px dashed darkgray";
            overlay.style.fontColor = "black";
            overlay.style.visibility = "hidden";
            overlay.style.padding = "1px";
            
            // insert as a sibling, because the element itself might not be able
            // to have children (like a Button, for example)
            element.parentNode.insertBefore(overlay,element);
        }
        
        // new/wrong shortcut? fix shortcut
        if ( (!overlay.id) | (overlay.id!=overlayId) ) {
            LOG("changing overlay id from '" + overlay.id + "' to '" + overlayId + "'");
            
            overlay.id = overlayId;
            overlay.innerHTML = "<font color=\"black\">" + shortcut + "</font>";
            element.setAttribute( "keynav:shortcut", shortcut );
        }
        else {
            LOG("overlay already exists for id: " + overlayId);
        }
        
        return overlay;
    }
    
    /** Returns the shortcut overlay of the specified element
    * 
    * @param element
    * @return 
    */
    function getElementOverlay(element) {
        if ( element.hasAttribute("keynav:shortcut") ) {
            var shortcutElementId = "keynav.shortcut[" + 
                    element.getAttribute("keynav:shortcut") + "]";
            
            var shortcutElement = document.getElementById(shortcutElementId);
            
            return shortcutElement;
        } else {
            return null;
        }
    }
    
    /** highlights (or dims) the element's shortcut.
    *
    * @param element the Element whose shortcut is to be highlighted/dimmed
    * @param on a Boolean - true to highlight, false to dim.
    */
    this.highlightShortcut = function (element,on) {
        var overlay = getElementOverlay(element);
        
        if (overlay) {
            overlay.style.background = on ? "lightgreen" : "lightyellow";
            overlay.style.border = on ? "1px solid black" : "1px dashed darkgray";
        }
    }
    
    /** Selects the elements of the document to assign shortcuts to
    *
    * @return an array of Elements
    */
    this.getClickableElements = function() {
        var ems = new Array(0);
        
        function addClickableElementsIn( parent ) {
            
            for (var i=0; i<parent.childNodes.length; ++i) {
                var node = parent.childNodes[i];
                
                if (node.nodeType!=1) {
                    continue;
                }
                
                var clickable = node.nodeName.toLowerCase()=="input" |
                        node.nodeName.toLowerCase()=="select" |
                        node.hasAttribute("href") |
                        node.hasAttribute("onclick");
                
                if ( clickable ) {
                    ems.push(node);
                }
                
                addClickableElementsIn(node);
            }
        }
        
        addClickableElementsIn(document);
        
        return ems;
    }
    
    /** Simulates a user-click on an element
    * 
    * @param element the element that should be "clicked"
    */
    this.simulateClick = function (element) {
        
        if ( element.nodeName.toLowerCase()=="input" ) {
            // only INPUT elements implement the click() method
            
            element.focus();
            element.click();
        }
        if ( element.nodeName.toLowerCase()=="select" ) {
            element.focus();
        }
        else if (element.hasAttribute("onclick")) {
            // must come before checking "href" because links may have a
            // pseudo "href" but a real "onclick"
            var evt = document.createEvent("MouseEvents");
            evt.initMouseEvent("click", true, true, window, 0,
   0, 0, 0, 0, false, false, false, false, 0, null);
   element.dispatchEvent(evt);
        }
        else if (element.hasAttribute("href")) {
            //window.location = element.getAttribute("href");
            var win = window.open(element.getAttribute("href"), "", "");
//            win.focus();
        }
        
    }
}

function KeyNav() {
    function LOG(message) {
        //window.dump( "[KeyNav] " + message + "\n");
    }
    
    /** displays information that most users will find useful
    *
    * @param message a String to display to the user
    */
    var displayOverlay;
    function display(message) {
        if (!displayOverlay) {
            displayOverlay = document.createElement("div");
            
            displayOverlay.style.position = "fixed";
            displayOverlay.style.display = "block";
            displayOverlay.style.left = "40%";
            displayOverlay.style.top = "40%";
            displayOverlay.style.background = "lightgreen";
            displayOverlay.style.border = "1px dashed black";
            displayOverlay.style.padding = "2px";
            displayOverlay.style.zorder = 500;
            displayOverlay.style.opacity = 0.8;
            displayOverlay.setAttribute("align","center");
            
            document.getElementsByTagName("body")[0].appendChild( displayOverlay );
        }
        
        if (message=="") {
            displayOverlay.style.visibility = "hidden";
        } else {
            displayOverlay.style.visibility = "visible";
            displayOverlay.innerHTML = message;
        }
    }
    
    var conf = new Configuration();
    var bindings = new Map(); //maps Strings (shortcuts) to Elements
    
    var acceptInput = false; //off by default
    
    // last searched shortcut.
    // the shortcut is searched incrementally
    var lastShortcut = "";
    
    /** highlights the overlays for the specified elements. Dims all other
    *  elements
    *
    * @param targets an Elements array whose overlays should be highlighted
    */
    function highlightOverlays( targets ) {
        //TODO use _labels instead of bindings.values()
        
        // trivial implementation: dims all elements and highlights the
        // specified ones
        
        // dim all elements
        var allTargets = bindings.values();
        for (var i=0; i<allTargets.length; ++i) {
            conf.highlightShortcut( allTargets[i], false );
        }
        
        // highlight specified elements
        for (var i=0; i<targets.length; ++i) {
            conf.highlightShortcut( targets[i], true );
        }
    }
    
    var _labels = new Array(0);
    var _labelsValid = false;
    
    function invalidate() {
        _labelsValid = false;
        LOG("invalidated");
    }
    
    function isValid() {
        return _labelsValid;
    }
    
    function createLabels() {
        _labels = new Array(0);
        bindings.clear();
        
        var clickableElements = conf.getClickableElements();
        
        for (var i=0; i<clickableElements.length; ++i) {
            var element = clickableElements[i];
            var shortcut = conf.generateShortcut(i);
            var label = conf.createLabel(element,shortcut);
            
            bindings.setValue( shortcut, element );
            _labels.push( label );
        }
        
        _labelsValid = true;
        LOG("labels are now valid");
    }
    
    function showLabels() {
        for (var i=0; i<_labels.length; ++i) {
            _labels[i].style.visibility = "visible";
        }
    }
    
    function hideLabels() {
        for (var i=0; i<_labels.length; ++i) {
            _labels[i].style.visibility = "hidden";
        }
    }
    
    /* toggles keyboard navigation on/off for the current document
    *
    * @param en a Boolean
    */
    function toggle(en) {
        if (en) {
            // suspend the event handler until all labels are created (and 
            // inserted to the document)
            document.removeEventListener("DOMNodeInserted",invalidate,true);
            
            if (!isValid()) {
                createLabels();
            }
            
            showLabels();
            
            acceptInput = true;
            display("");
            
            // whenever the document changes, invalidate the labels
            document.addEventListener("DOMNodeInserted",invalidate,true);
            
            LOG("enabled");
        }
        else {
            acceptInput = false;
            hideLabels();
            display("");
            LOG("disabled");
        }
    }
    
    function onKeyPress(evt) {
        if (!acceptInput) return;
        
        // append pressed character to the shortcut we are going to lookup
        var ch = String.fromCharCode(evt.charCode).toLowerCase();
        lastShortcut += ch;
        
        // lookup targets starting with the shortcut
        var targets = bindings.getValuesByPredicate( function(key){
            if ( key.substring(0,lastShortcut.length)==lastShortcut )
            return true;
            else
                return false;
        } );
        
        highlightOverlays( targets );
        
        if ( targets.length==0 ) {
            // no targets at all - start a new search next time
            display("");
            
            LOG(lastShortcut + " is unbound. clearing");
            lastShortcut = "";
        }
        else if ( targets.length==1 ) {
            // exactly one match - navigate to target, and start a new search
            // next time
            display("");
            
            LOG(lastShortcut + " bound to 1 target. clearing. navigating");
            
            if (targets[0]) {
                toggle(false);
                conf.simulateClick(targets[0]);
            }
            else {
                LOG("no target for sequence: " + lastShortcut);
            }
            
            lastShortcut = "";
        }
        else {
            // more than one match - do nothing. next search will be appended
            display("Keep typing.. " + targets.length +
                    " elements match so far<br>(or press Enter to \"click\" " +
                    lastShortcut + ")");
            
            LOG(lastShortcut + " bound to " + targets.length + " targets");
        }
    }
    
    function onKeyDown(evt) {
        var currEle = document.activeElement;
        if ( currEle.tagName == "input" | currEle.tagName == "INPUT" | currEle.tagName == "textarea" | currEle.tagName == "TEXTAREA" )
        {
            toggle(false);
            return;
        }
        // activation
        if (!acceptInput & evt.keyCode==conf.getPreference("activationKeyCode")) {
            toggle(true);
        }
        // deactivation
        else if (acceptInput & evt.keyCode==conf.getPreference("deactivationKeyCode")) {
            toggle(false);
            return;
        }
        
        if (!acceptInput) return;
        
        switch (evt.keyCode) {
            //case KeyEvent.DOM_VK_RETURN:
            case 0x0D: //KeyEvent.DOM_VK_ENTER:
                    // match the exact shortcut typed so far
                    
                    var target = bindings.getValue(lastShortcut);
            LOG("match for exact shortcut " + lastShortcut + ": " + target);
                    
            if (target) {
                toggle(false);
                conf.simulateClick(target);
            }
            
            lastShortcut = "";
            
            break;
        }
    }
    
    function installEventListeners() {
        window.addEventListener("keydown",onKeyDown,true);
        window.addEventListener("keypress",onKeyPress,true);
    }
    
    createLabels();
    installEventListeners();
}

var keynav = new KeyNav();

And this one for opening in a new tab/window using 'n'.

Last edited by Andrwe (2010-05-01 14:33:35)

Offline

#3 2010-04-25 23:49:08

Meskarune
Member
From: Helsinki, Finland
Registered: 2009-03-21
Posts: 361
Website

Re: Midori Web Browser and user scripts

These are awesome! Thanks for sharing them!


Homepage  | Arch Linux Women | Arch Linux Classroom
Acer Aspire E5-575G-53VG:
Intel Dual-Core i5-6200U 2.3 GHz; Skylake rev3 | 8GB DDR4 ram | Intel HD Graphics 520 + NVIDIA GeForce 940MX
Qualcomm Atheros QCA9377 802.11ac | Realtek RTL8111/8168/8411 Gigabit Ethernet Controller

Offline

#4 2010-04-26 14:26:50

Andrwe
Member
From: Leipzig/Germany
Registered: 2009-06-17
Posts: 322
Website

Re: Midori Web Browser and user scripts

No problem.

Also, if you like vim-like bindings this is the vimbind-script I'm using:
http://userscripts.org/scripts/show/32369

For blocking google-ads I'm using:
http://userscripts.org/scripts/show/1669
and
http://userscripts.org/scripts/review/62890

Offline

#5 2010-04-28 10:34:39

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

Those navigation scripts look great and the vimkeybindings work as expected. But somehow I don't get neither of the KeyNav scripts working. Pressing "f" (or F12 depending on the installed script) does not have any effect.

The scripts are installed in ~/.local/share/midori/scripts:

~/.local/share/midori/scripts$ ls
KeyNav.user.js  vvimkeybindings.user.js

and were properly found by midori.

Is there some additional setup necessary I did miss?

Edit:
Just found out, that I can navigate the links via the Tab key now. (This used not to work on previous attempts.) Any idea whether this is a built-in webkit feature? And could this possibly interfere with KeyNav?

Last edited by bernarcher (2010-04-28 10:39:19)


To know or not to know ...
... the questions remain forever.

Offline

#6 2010-04-28 18:13:32

Andrwe
Member
From: Leipzig/Germany
Registered: 2009-06-17
Posts: 322
Website

Re: Midori Web Browser and user scripts

First of all after installing navkey you have to restart midori.

I think you already did.
A requirement for navkey to work is that the tab has focus I've for example set 'v' for the midori method in Tools->Customize shortcuts called 'Focus current Tab' and first try to use this key.
Then there sometimes is something fishy about the focus and it is set to the tabbar. In that case you can try to use tab-key twice so the focus changes to site.
So if the hinting doesn't work first try setting focus afterwards if it doesn't work try tab-key twice. Then it should work.

One thing for my presented script if the focus is set on an input or textarea field the hinting isn't activated like the original script on userscripts.org does.

If these solution doesn't work for you than have a look in console-window of midori (<F9> -> Console) if there are any error messages after starting midori.
If there are post them here. Please

Offline

#7 2010-04-28 20:50:44

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

@Andrwe

Thanks for the hints. I tried most of them, esp. the focus settings, (again) to no avail. Yet, I did not think of the midori built-in console. There is not much information, however, except this line:

1 @ : SyntaxError: Parse error

whenever another page was loaded. This appears to happen only with the KeyNav script activated but as I cannot see a real cause within the script itself there most probably is some setup I do miss.

Well, I am not too proficient with greasemonkey scripting so I merely skimmed the script leaving me without a real clue about how to proceed.


To know or not to know ...
... the questions remain forever.

Offline

#8 2010-05-01 10:16:39

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

All right, at least I got rid of the "SyntaxError" message. It turned out there was a formatting issue in your post #2 above:

function Map() {
    function LOG(message) {
        //window.dump( "[Map] " + message + "
");

Note the break in the commented line. This occured on several places. Joining the lines cured this error.

But, alas, the KeyNav scripts still do not work here. And there is no message about the causes whatsoever. Perhaps you can hint me on how to debug this kind of scripts.


To know or not to know ...
... the questions remain forever.

Offline

#9 2010-05-01 14:28:57

Andrwe
Member
From: Leipzig/Germany
Registered: 2009-06-17
Posts: 322
Website

Re: Midori Web Browser and user scripts

I've changed the posted scripts, the \n were changed into new lines that is why the errors appeared.
Try to copy the new scripts and look for the correct copying of "\n".

Please add

alert(evt.keyCode);

at line 503 restart midori and press the shortcut.
A window printing something should appear everytime you press it.

Does it work?

Last edited by Andrwe (2010-05-01 14:36:01)

Offline

#10 2010-05-01 17:41:21

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

I got a bit farther. It appears there is a problem with the keyboard handler in my system.

1) The labels displayed on activation and were immediately hidden again. So I temporarily set up an extra deactivation key ("g" in this case). Now at least the labels show up and keypresses will be evaluated.

2) Still selection does not work properly, so I inserted a display message for debugging (commenting other messages display instructions of course):

    function onKeyPress(evt) {
        if (!acceptInput) return;
        
        // append pressed character to the shortcut we are going to lookup
        var ch = String.fromCharCode(evt.charCode).toLowerCase();
    display("lastShortcut = '" + lastShortcut + "' appending '" + ch + "'");
        lastShortcut += ch;

If I navigated to a page with a lot of targets, I then get the following sequence of messages.
a) On activation: lastShortcut = '' appending 'f' which appears probably o.k.
b) Pressing a number key, say "1", however results in: lastShortcut = '1' appending '1'. This is clearly wrong, lastShortcut should be empty at this stage. Effectively this doubles the input resulting in lastShortcut = '11' instead.
c) There is something fishy with the target label mapping. E.g., on the Forums page the labels are not consecutive but result in a disruptive series going up to label number 357. I did not follow the algorithm yet, but, is this ok?

So far I have not been able to trace this down to the instruction where the the lastShortcut is altered. Things would be easier if I could follow the LOG messages. Is there a log file or something where they can be looked up during debugging?

Last edited by bernarcher (2010-05-01 17:43:59)


To know or not to know ...
... the questions remain forever.

Offline

#11 2010-05-02 16:15:09

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

Somehow the keyboard event handlers are both called twice in a row. Changing some of the LOG statements to alerts and putting an alert right at the beginning of onKeyDown and onKeyPress resulted in the following sequence of events (<BS> being the backspace key representation):

Activation key 'f' pressed:
onKeyDown, evt.keyCode='70', lastShortcut=''
onKeyPress, evt.keyCode='102', lastShortcut=''
f is unbound. clearing
onKeyDown, evt.keyCode='70', lastShortcut=''
onKeyPress, evt.keyCode='102', lastShortcut=''
f is unbound. clearing

Selection key '1' pressed:
onKeyDown, evt.keyCode='49', lastShortcut=''
onKeyPress, evt.keyCode='49', lastShortcut=''
1 bound to 111 targets
onKeyDown, evt.keyCode='49', lastShortcut='1'
onKeyPress, evt.keyCode='49', lastShortcut='1'
11 bound to 11 targets

Backspace key pressed:
onKeyDown, evt.keyCode='8', lastShortcut='11'
onKeyPress, evt.keyCode='8', lastShortcut='11'
11<BS> is unbound. clearing
onKeyDown, evt.keyCode='8', lastShortcut=''
onKeyPress, evt.keyCode='8', lastShortcut=''
<BS> is unbound. clearing

Deactivation key 'g' pressed:
onKeyDown, evt.keyCode='71', lastShortcut=''
onKeyDown, evt.keyCode='71', lastShortcut=''

This is as far as I can get. I have no idea what might cause this behaviour.
As far as I can tell, this is not with midori. It  happens both with midori 0.2.4-1 and the latest midori-git.
I suspect some system setting but have no idea where to look.

It's a pity. sad

Edit:
I inserted some very hackish tests to prevent the handlers from being called twice.
Not a real solution but at least KeyNav appears to work now.

Perhaps some day I'll find out the real cause by chance (hopefully). smile

Last edited by bernarcher (2010-05-02 18:28:41)


To know or not to know ...
... the questions remain forever.

Offline

#12 2010-05-02 16:32:16

dmz
Member
From: Sweden
Registered: 2008-08-27
Posts: 881
Website

Re: Midori Web Browser and user scripts

Is there something like vimperator? hmm

Offline

#13 2010-05-03 15:31:28

Andrwe
Member
From: Leipzig/Germany
Registered: 2009-06-17
Posts: 322
Website

Re: Midori Web Browser and user scripts

@bernarcher
Now I remember the fault.
You have to deactivate numlock otherwise each key in javascript is send twice.
Until now I couldn't find a solution.

@dmz
No, you just can change shortcuts and add functionalities like I do using scripts and the build-in shortcuts.

Offline

#14 2010-05-03 21:13:32

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

Andrwe wrote:

You have to deactivate numlock otherwise each key in javascript is send twice.

Great!
Now it works.
(And now I do know how the script works...)
Many, many thanks! big_smile


To know or not to know ...
... the questions remain forever.

Offline

#15 2010-05-15 07:54:20

Larsson
Member
From: Sweden
Registered: 2010-03-22
Posts: 156

Re: Midori Web Browser and user scripts

Does anyone know how to disable flash for different sites, or possibly disable flash in the extension panel? As it is now it's shaded out and can't be unselected.


"If the person you are talking to doesn't appear to be listening, be patient. It may simply be that he has a small piece of fluff in his ear." - A.A. Milne (Winnie-the-Pooh)

Offline

#16 2010-05-19 15:12:53

bernarcher
Forum Fellow
From: Germany
Registered: 2009-02-17
Posts: 2,281

Re: Midori Web Browser and user scripts

In an effort to better understand navigation programming for Midori I did combine the "vimkeybindings" and "KeyNav" scripts, adding some ideas from the uzbl "follow.js" script. This grew into a major rewrite, almost doubling in size.

The results are available here. I put the file as "VimNav.user.js" in my "~/.local/share/midori/scripts" folder.

VimNav is widely configurable by the way. Read the configuration section at the beginning to learn more. And other than KeyNav it does work here regardless whether NumLock is on or not.

It is not without issues however and as yet only sloppily tested. But is appears to be quite useable. So, have fun! smile

Edit:
As this could possibly be interesting for a more general audience, I put a more advanced version in this new thread.

Last edited by bernarcher (2010-05-23 09:42:58)


To know or not to know ...
... the questions remain forever.

Offline

#17 2014-03-01 04:47:05

sw2wolf
Member
From: China
Registered: 2009-06-08
Posts: 99
Website

Re: Midori Web Browser and user scripts

There are "last-window-width, last-window-height" in     ~/.config/midori/config, but how can control its postion ?

Sincerely!


e^(π⋅i) + 1 = 0

Offline

#18 2014-03-01 16:41:41

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 19,785

Re: Midori Web Browser and user scripts

Hi sw2wolf,
This thread is pretty old. Your request is also a bit off topic.  I am going to go ahead and close this thread.  Feel free to go ahead and start a new thread with your question.  Thanks.   BTW, I love your signature, but as an EE, I think you could improve it my changing i to j. big_smile


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

Board footer

Powered by FluxBB