Renamed hinting js file from hint.js -> hints.js.
authorDaniel Carl <danielcarl@gmx.de>
Fri, 1 Mar 2013 14:13:42 +0000 (15:13 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Fri, 1 Mar 2013 14:30:34 +0000 (15:30 +0100)
Makefile
src/hint.js [deleted file]
src/hints.c
src/hints.js [new file with mode: 0644]

index b088b3c..620dadc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,8 +12,8 @@ options:
        @echo "CPPFLAGS  = $(CPPFLAGS)"
        @echo "LDFLAGS   = $(LDFLAGS)"
 
-src/hints.o: src/hint.js.h
-src/hint.js.h: src/hint.js
+src/hints.o: src/hints.js.h
+src/hints.js.h: src/hints.js
        @echo "minify $<"
        @cat $< | src/js2h.sh > $@
 
diff --git a/src/hint.js b/src/hint.js
deleted file mode 100644 (file)
index 84aeb27..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-VimpHints = function Hints(bg, bgf, fg, style) {
-    var config = {
-        maxHints: 200,
-        hintCss: style,
-        hintClass: "__hint",
-        hintClassFocus: "__hint_container",
-        eBg: bg,
-        eBgf: bgf,
-        eFg: fg
-    };
-
-    var hCont;
-    var curFocusNum = 1;
-    var hints = [];
-    var mode;
-
-    this.create = function(inputText, hintMode)
-    {
-        if (hintMode) {
-            mode = hintMode;
-        }
-
-        var topwin = window;
-        var top_height = topwin.innerHeight;
-        var top_width = topwin.innerWidth;
-        var xpath_expr;
-
-        var hintCount = 0;
-        this.clear();
-
-        function _helper (win, offsetX, offsetY) {
-            var doc = win.document;
-
-            var win_height = win.height;
-            var win_width = win.width;
-
-            /* Bounds */
-            var minX = offsetX < 0 ? -offsetX : 0;
-            var minY = offsetY < 0 ? -offsetY : 0;
-            var maxX = offsetX + win_width > top_width ? top_width - offsetX : top_width;
-            var maxY = offsetY + win_height > top_height ? top_height - offsetY : top_height;
-
-            var scrollX = win.scrollX;
-            var scrollY = win.scrollY;
-
-            hCont = doc.createElement("div");
-            hCont.id = "hint_container";
-
-            xpath_expr = _getXpathXpression(inputText);
-
-            var res = doc.evaluate(xpath_expr, doc,
-                function (p) {
-                    return "http://www.w3.org/1999/xhtml";
-                }, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
-
-            /* generate basic hint element which will be cloned and updated later */
-            var hintSpan = doc.createElement("span");
-            hintSpan.setAttribute("class", config.hintClass);
-            hintSpan.style.cssText = config.hintCss;
-
-            /* due to the different XPath result type, we will need two counter variables */
-            var rect, elem, text, node, show_text;
-            for (i = 0; i < res.snapshotLength; i++) {
-                if (hintCount >= config.maxHints) {
-                    break;
-                }
-
-                elem = res.snapshotItem(i);
-                rect = elem.getBoundingClientRect();
-                if (!rect || rect.left > maxX || rect.right < minX || rect.top > maxY || rect.bottom < minY) {
-                    continue;
-                }
-
-                var style = topwin.getComputedStyle(elem, "");
-                if (style.display == "none" || style.visibility != "visible") {
-                    continue;
-                }
-
-                var leftpos = Math.max((rect.left + scrollX), scrollX);
-                var toppos = Math.max((rect.top + scrollY), scrollY);
-
-                /* making this block DOM compliant */
-                var hint = hintSpan.cloneNode(false);
-                hint.style.left = leftpos - 3 + "px";
-                hint.style.top =  toppos - 3 + "px";
-                text = doc.createTextNode(hintCount + 1);
-                hint.appendChild(text);
-
-                hCont.appendChild(hint);
-                hintCount++;
-                hints.push({
-                    elem:       elem,
-                    number:     hintCount,
-                    span:       hint,
-                    background: elem.style.background,
-                    foreground: elem.style.color}
-                );
-
-                /* make the link black to ensure it's readable */
-                elem.style.color = config.eFg;
-                elem.style.background = config.eBg;
-            }
-
-            doc.documentElement.appendChild(hCont);
-
-            /* recurse into any iframe or frame element */
-            var frameTags = ["frame","iframe"];
-            for (var f = 0; f < frameTags.length; ++f) {
-                var frames = doc.getElementsByTagName(frameTags[f]);
-                for (var i = 0, nframes = frames.length; i < nframes; ++i) {
-                    elem = frames[i];
-                    rect = elem.getBoundingClientRect();
-                    if (!elem.contentWindow || !rect || rect.left > maxX || rect.right < minX || rect.top > maxY || rect.bottom < minY) {
-                        continue;
-                    }
-                    _helper(elem.contentWindow, offsetX + rect.left, offsetY + rect.top);
-                }
-            }
-        }
-
-        _helper(topwin, 0, 0);
-
-        _focus(1);
-        if (hintCount == 1) {
-            /* just one hinted element - might as well follow it */
-            return this.fire(1);
-        }
-    };
-
-    /* set focus to next avaiable hint */
-    this.focusNext = function()
-    {
-        var index = _getHintIdByNumber(curFocusNum);
-
-        if (typeof(hints[index + 1]) !== "undefined") {
-            _focus(hints[index + 1].number);
-        } else {
-            _focus(hints[0].number);
-        }
-    };
-
-    /* set focus to previous avaiable hint */
-    this.focusPrev = function()
-    {
-        var index = _getHintIdByNumber(curFocusNum);
-        if (index !== 0 && typeof(hints[index - 1].number) !== "undefined") {
-            _focus(hints[index - 1].number);
-        } else {
-            _focus(hints[hints.length - 1].number);
-        }
-    };
-
-    /* filters hints matching given number */
-    this.update = function(n)
-    {
-        if (n === 0) {
-            return this.create();
-        }
-        /* remove none matching hints */
-        var remove = [];
-        var i;
-        for (i = 0; i < hints.length; ++i) {
-            var hint = hints[i];
-            if (0 !== hint.number.toString().indexOf(n.toString())) {
-                remove.push(hint.number);
-            }
-        }
-
-        for (i = 0; i < remove.length; ++i) {
-            _removeHint(remove[i]);
-        }
-
-        if (hints.length === 1) {
-            return this.fire(hints[0].number);
-        }
-        return _focus(n);
-    };
-
-    /* remove all hints and set previous style to them */
-    this.clear = function()
-    {
-        if (hints.length === 0) {
-            return;
-        }
-        for (var i = 0; i < hints.length; ++i) {
-            var hint = hints[i];
-            if (typeof(hint.elem) !== "undefined") {
-                hint.elem.style.background = hint.background;
-                hint.elem.style.color = hint.foreground;
-                hint.span.parentNode.removeChild(hint.span);
-            }
-        }
-        hints = [];
-        hCont.parentNode.removeChild(hCont);
-        window.onkeyup = null;
-    };
-
-    /* fires the modeevent on hint with given number */
-    this.fire = function(n)
-    {
-        n = n ? n : curFocusNum;
-        var result;
-        var hint = _getHintByNumber(n);
-        if (typeof(hint.elem) == "undefined") {
-            return "DONE:";
-        }
-
-        var el  = hint.elem;
-        var tag = el.nodeName.toLowerCase();
-
-        this.clear();
-
-        if (tag === "iframe" || tag === "frame" || tag === "textarea" || tag === "input" && (el.type === "text" || el.type === "password" || el.type === "checkbox" || el.type === "radio") || tag === "select") {
-            el.focus();
-            if (tag === "input" || tag === "textarea") {
-                return "INSERT:";
-            }
-            return "DONE:";
-        }
-
-        result = "DONE:";
-        switch (mode) {
-            case "f":
-                _open(el);
-                break;
-            case "F":
-                _openNewWindow(el);
-                break;
-            case "i":
-                _open(el);
-                break;
-            case "I":
-                _openNewWindow(el);
-                break;
-            default:
-                result = "DATA:" + _getElemtSource(el);
-                break;
-        }
-
-        return result;
-    };
-
-    /* set focus on hint with given number */
-    function _focus(n)
-    {
-        /* reset previous focused hint */
-        var hint = _getHintByNumber(curFocusNum);
-        if (hint !== null) {
-            hint.elem.className = hint.elem.className.replace(config.hintClassFocus, config.hintClass);
-            hint.elem.style.background = config.eBg;
-            _mouseEvent(hint.elem, "mouseout");
-        }
-
-        curFocusNum = n;
-
-        /* mark new hint as focused */
-        hint = _getHintByNumber(curFocusNum);
-        if (hint !== null) {
-            hint.elem.className = hint.elem.className.replace(config.hintClass, config.hintClassFocus);
-            hint.elem.style.background = config.eBgf;
-            _mouseEvent(hint.elem, "mouseover");
-        }
-    }
-
-    /* retrieves text content fro given element */
-    function _getTextFromElement(el)
-    {
-        var text;
-        if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
-            text = el.value;
-        } else if (el instanceof HTMLSelectElement) {
-            if (el.selectedIndex >= 0) {
-                text = el.item(el.selectedIndex).text;
-            } else{
-                text = "";
-            }
-        } else {
-            text = el.textContent;
-        }
-        return text.toLowerCase();
-    }
-
-    /* retrieves the hint for given hint number */
-    function _getHintByNumber(n)
-    {
-        var index = _getHintIdByNumber(n);
-        if (index !== null) {
-            return hints[index];
-        }
-        return null;
-    }
-
-    /* retrieves the id of hint with given number */
-    function _getHintIdByNumber(n)
-    {
-        var hint;
-        for (var i = 0; i < hints.length; ++i) {
-            hint = hints[i];
-            if (hint.number === n) {
-                return i;
-            }
-        }
-        return null;
-    }
-
-    /* removes hint with given number from hints array */
-    function _removeHint(n)
-    {
-        var index = _getHintIdByNumber(n);
-        if (index === null) {
-            return;
-        }
-        var hint = hints[index];
-        if (hint.number === n) {
-            hint.elem.style.background = hint.background;
-            hint.elem.style.color = hint.foreground;
-            hint.span.parentNode.removeChild(hint.span);
-
-            /* remove hints from all hints */
-            hints.splice(index, 1);
-        }
-    }
-
-    /* opens given element */
-    function _open(elem)
-    {
-        if (elem.target == "_blank") {
-            elem.removeAttribute("target");
-        }
-        _mouseEvent(elem, "moudedown");
-        _mouseEvent(elem, "click");
-    }
-
-    /* opens given element into new window */
-    function _openNewWindow(elem)
-    {
-        var oldTarget = elem.target;
-
-        /* set target to open in new window */
-        elem.target = "_blank";
-        _mouseEvent(elem, "moudedown");
-        _mouseEvent(elem, "click");
-        elem.target = oldTarget;
-    }
-
-    function _mouseEvent(elem, name)
-    {
-        var doc = elem.ownerDocument;
-        var view = elem.contentWindow;
-
-        var evObj = doc.createEvent("MouseEvents");
-        evObj.initMouseEvent(name, true, true, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
-        elem.dispatchEvent(evObj);
-    }
-
-    /* retrieves the url of given element */
-    function _getElemtSource(elem)
-    {
-        var url = elem.href || elem.src;
-        return url;
-    }
-
-    /* retrieves the xpath expression according to mode */
-    function _getXpathXpression(text)
-    {
-        var expr;
-        if (typeof(text) === "undefined") {
-            text = "";
-        }
-        switch (mode) {
-            case "f":
-            case "F":
-                if (text === "") {
-                    expr = "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href] | //input[not(@type='hidden')] | //a[href] | //area | //textarea | //button | //select";
-                } else {
-                    expr = "//*[(@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href) and contains(., '" + text + "')] | //input[not(@type='hidden') and contains(., '" + text + "')] | //a[@href and contains(., '" + text + "')] | //area[contains(., '" + text + "')] |  //textarea[contains(., '" + text + "')] | //button[contains(@value, '" + text + "')] | //select[contains(., '" + text + "')]";
-                }
-                break;
-            case "i":
-            case "I":
-                if (text === "") {
-                    expr = "//img[@src]";
-                } else {
-                    expr = "//img[@src and contains(., '" + text + "')]";
-                }
-                break;
-            default:
-                if (text === "") {
-                    expr = "//*[@role='link' or @href] | //a[href] | //area | //img[not(ancestor::a)]";
-                } else {
-                    expr = "//*[(@role='link' or @href) and contains(., '" + text + "')] | //a[@href and contains(., '" + text + "')] | //area[contains(., '" + text + "')] | //img[not(ancestor::a) and contains(., '" + text + "')]";
-                }
-                break;
-        }
-        return expr;
-    }
-};
index bb64e10..56d7155 100644 (file)
@@ -22,7 +22,7 @@
 #include "hints.h"
 #include "dom.h"
 #include "command.h"
-#include "hint.js.h"
+#include "hints.js.h"
 
 #define HINT_VAR "VpHint"
 
diff --git a/src/hints.js b/src/hints.js
new file mode 100644 (file)
index 0000000..84aeb27
--- /dev/null
@@ -0,0 +1,397 @@
+VimpHints = function Hints(bg, bgf, fg, style) {
+    var config = {
+        maxHints: 200,
+        hintCss: style,
+        hintClass: "__hint",
+        hintClassFocus: "__hint_container",
+        eBg: bg,
+        eBgf: bgf,
+        eFg: fg
+    };
+
+    var hCont;
+    var curFocusNum = 1;
+    var hints = [];
+    var mode;
+
+    this.create = function(inputText, hintMode)
+    {
+        if (hintMode) {
+            mode = hintMode;
+        }
+
+        var topwin = window;
+        var top_height = topwin.innerHeight;
+        var top_width = topwin.innerWidth;
+        var xpath_expr;
+
+        var hintCount = 0;
+        this.clear();
+
+        function _helper (win, offsetX, offsetY) {
+            var doc = win.document;
+
+            var win_height = win.height;
+            var win_width = win.width;
+
+            /* Bounds */
+            var minX = offsetX < 0 ? -offsetX : 0;
+            var minY = offsetY < 0 ? -offsetY : 0;
+            var maxX = offsetX + win_width > top_width ? top_width - offsetX : top_width;
+            var maxY = offsetY + win_height > top_height ? top_height - offsetY : top_height;
+
+            var scrollX = win.scrollX;
+            var scrollY = win.scrollY;
+
+            hCont = doc.createElement("div");
+            hCont.id = "hint_container";
+
+            xpath_expr = _getXpathXpression(inputText);
+
+            var res = doc.evaluate(xpath_expr, doc,
+                function (p) {
+                    return "http://www.w3.org/1999/xhtml";
+                }, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+
+            /* generate basic hint element which will be cloned and updated later */
+            var hintSpan = doc.createElement("span");
+            hintSpan.setAttribute("class", config.hintClass);
+            hintSpan.style.cssText = config.hintCss;
+
+            /* due to the different XPath result type, we will need two counter variables */
+            var rect, elem, text, node, show_text;
+            for (i = 0; i < res.snapshotLength; i++) {
+                if (hintCount >= config.maxHints) {
+                    break;
+                }
+
+                elem = res.snapshotItem(i);
+                rect = elem.getBoundingClientRect();
+                if (!rect || rect.left > maxX || rect.right < minX || rect.top > maxY || rect.bottom < minY) {
+                    continue;
+                }
+
+                var style = topwin.getComputedStyle(elem, "");
+                if (style.display == "none" || style.visibility != "visible") {
+                    continue;
+                }
+
+                var leftpos = Math.max((rect.left + scrollX), scrollX);
+                var toppos = Math.max((rect.top + scrollY), scrollY);
+
+                /* making this block DOM compliant */
+                var hint = hintSpan.cloneNode(false);
+                hint.style.left = leftpos - 3 + "px";
+                hint.style.top =  toppos - 3 + "px";
+                text = doc.createTextNode(hintCount + 1);
+                hint.appendChild(text);
+
+                hCont.appendChild(hint);
+                hintCount++;
+                hints.push({
+                    elem:       elem,
+                    number:     hintCount,
+                    span:       hint,
+                    background: elem.style.background,
+                    foreground: elem.style.color}
+                );
+
+                /* make the link black to ensure it's readable */
+                elem.style.color = config.eFg;
+                elem.style.background = config.eBg;
+            }
+
+            doc.documentElement.appendChild(hCont);
+
+            /* recurse into any iframe or frame element */
+            var frameTags = ["frame","iframe"];
+            for (var f = 0; f < frameTags.length; ++f) {
+                var frames = doc.getElementsByTagName(frameTags[f]);
+                for (var i = 0, nframes = frames.length; i < nframes; ++i) {
+                    elem = frames[i];
+                    rect = elem.getBoundingClientRect();
+                    if (!elem.contentWindow || !rect || rect.left > maxX || rect.right < minX || rect.top > maxY || rect.bottom < minY) {
+                        continue;
+                    }
+                    _helper(elem.contentWindow, offsetX + rect.left, offsetY + rect.top);
+                }
+            }
+        }
+
+        _helper(topwin, 0, 0);
+
+        _focus(1);
+        if (hintCount == 1) {
+            /* just one hinted element - might as well follow it */
+            return this.fire(1);
+        }
+    };
+
+    /* set focus to next avaiable hint */
+    this.focusNext = function()
+    {
+        var index = _getHintIdByNumber(curFocusNum);
+
+        if (typeof(hints[index + 1]) !== "undefined") {
+            _focus(hints[index + 1].number);
+        } else {
+            _focus(hints[0].number);
+        }
+    };
+
+    /* set focus to previous avaiable hint */
+    this.focusPrev = function()
+    {
+        var index = _getHintIdByNumber(curFocusNum);
+        if (index !== 0 && typeof(hints[index - 1].number) !== "undefined") {
+            _focus(hints[index - 1].number);
+        } else {
+            _focus(hints[hints.length - 1].number);
+        }
+    };
+
+    /* filters hints matching given number */
+    this.update = function(n)
+    {
+        if (n === 0) {
+            return this.create();
+        }
+        /* remove none matching hints */
+        var remove = [];
+        var i;
+        for (i = 0; i < hints.length; ++i) {
+            var hint = hints[i];
+            if (0 !== hint.number.toString().indexOf(n.toString())) {
+                remove.push(hint.number);
+            }
+        }
+
+        for (i = 0; i < remove.length; ++i) {
+            _removeHint(remove[i]);
+        }
+
+        if (hints.length === 1) {
+            return this.fire(hints[0].number);
+        }
+        return _focus(n);
+    };
+
+    /* remove all hints and set previous style to them */
+    this.clear = function()
+    {
+        if (hints.length === 0) {
+            return;
+        }
+        for (var i = 0; i < hints.length; ++i) {
+            var hint = hints[i];
+            if (typeof(hint.elem) !== "undefined") {
+                hint.elem.style.background = hint.background;
+                hint.elem.style.color = hint.foreground;
+                hint.span.parentNode.removeChild(hint.span);
+            }
+        }
+        hints = [];
+        hCont.parentNode.removeChild(hCont);
+        window.onkeyup = null;
+    };
+
+    /* fires the modeevent on hint with given number */
+    this.fire = function(n)
+    {
+        n = n ? n : curFocusNum;
+        var result;
+        var hint = _getHintByNumber(n);
+        if (typeof(hint.elem) == "undefined") {
+            return "DONE:";
+        }
+
+        var el  = hint.elem;
+        var tag = el.nodeName.toLowerCase();
+
+        this.clear();
+
+        if (tag === "iframe" || tag === "frame" || tag === "textarea" || tag === "input" && (el.type === "text" || el.type === "password" || el.type === "checkbox" || el.type === "radio") || tag === "select") {
+            el.focus();
+            if (tag === "input" || tag === "textarea") {
+                return "INSERT:";
+            }
+            return "DONE:";
+        }
+
+        result = "DONE:";
+        switch (mode) {
+            case "f":
+                _open(el);
+                break;
+            case "F":
+                _openNewWindow(el);
+                break;
+            case "i":
+                _open(el);
+                break;
+            case "I":
+                _openNewWindow(el);
+                break;
+            default:
+                result = "DATA:" + _getElemtSource(el);
+                break;
+        }
+
+        return result;
+    };
+
+    /* set focus on hint with given number */
+    function _focus(n)
+    {
+        /* reset previous focused hint */
+        var hint = _getHintByNumber(curFocusNum);
+        if (hint !== null) {
+            hint.elem.className = hint.elem.className.replace(config.hintClassFocus, config.hintClass);
+            hint.elem.style.background = config.eBg;
+            _mouseEvent(hint.elem, "mouseout");
+        }
+
+        curFocusNum = n;
+
+        /* mark new hint as focused */
+        hint = _getHintByNumber(curFocusNum);
+        if (hint !== null) {
+            hint.elem.className = hint.elem.className.replace(config.hintClass, config.hintClassFocus);
+            hint.elem.style.background = config.eBgf;
+            _mouseEvent(hint.elem, "mouseover");
+        }
+    }
+
+    /* retrieves text content fro given element */
+    function _getTextFromElement(el)
+    {
+        var text;
+        if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
+            text = el.value;
+        } else if (el instanceof HTMLSelectElement) {
+            if (el.selectedIndex >= 0) {
+                text = el.item(el.selectedIndex).text;
+            } else{
+                text = "";
+            }
+        } else {
+            text = el.textContent;
+        }
+        return text.toLowerCase();
+    }
+
+    /* retrieves the hint for given hint number */
+    function _getHintByNumber(n)
+    {
+        var index = _getHintIdByNumber(n);
+        if (index !== null) {
+            return hints[index];
+        }
+        return null;
+    }
+
+    /* retrieves the id of hint with given number */
+    function _getHintIdByNumber(n)
+    {
+        var hint;
+        for (var i = 0; i < hints.length; ++i) {
+            hint = hints[i];
+            if (hint.number === n) {
+                return i;
+            }
+        }
+        return null;
+    }
+
+    /* removes hint with given number from hints array */
+    function _removeHint(n)
+    {
+        var index = _getHintIdByNumber(n);
+        if (index === null) {
+            return;
+        }
+        var hint = hints[index];
+        if (hint.number === n) {
+            hint.elem.style.background = hint.background;
+            hint.elem.style.color = hint.foreground;
+            hint.span.parentNode.removeChild(hint.span);
+
+            /* remove hints from all hints */
+            hints.splice(index, 1);
+        }
+    }
+
+    /* opens given element */
+    function _open(elem)
+    {
+        if (elem.target == "_blank") {
+            elem.removeAttribute("target");
+        }
+        _mouseEvent(elem, "moudedown");
+        _mouseEvent(elem, "click");
+    }
+
+    /* opens given element into new window */
+    function _openNewWindow(elem)
+    {
+        var oldTarget = elem.target;
+
+        /* set target to open in new window */
+        elem.target = "_blank";
+        _mouseEvent(elem, "moudedown");
+        _mouseEvent(elem, "click");
+        elem.target = oldTarget;
+    }
+
+    function _mouseEvent(elem, name)
+    {
+        var doc = elem.ownerDocument;
+        var view = elem.contentWindow;
+
+        var evObj = doc.createEvent("MouseEvents");
+        evObj.initMouseEvent(name, true, true, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+        elem.dispatchEvent(evObj);
+    }
+
+    /* retrieves the url of given element */
+    function _getElemtSource(elem)
+    {
+        var url = elem.href || elem.src;
+        return url;
+    }
+
+    /* retrieves the xpath expression according to mode */
+    function _getXpathXpression(text)
+    {
+        var expr;
+        if (typeof(text) === "undefined") {
+            text = "";
+        }
+        switch (mode) {
+            case "f":
+            case "F":
+                if (text === "") {
+                    expr = "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href] | //input[not(@type='hidden')] | //a[href] | //area | //textarea | //button | //select";
+                } else {
+                    expr = "//*[(@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href) and contains(., '" + text + "')] | //input[not(@type='hidden') and contains(., '" + text + "')] | //a[@href and contains(., '" + text + "')] | //area[contains(., '" + text + "')] |  //textarea[contains(., '" + text + "')] | //button[contains(@value, '" + text + "')] | //select[contains(., '" + text + "')]";
+                }
+                break;
+            case "i":
+            case "I":
+                if (text === "") {
+                    expr = "//img[@src]";
+                } else {
+                    expr = "//img[@src and contains(., '" + text + "')]";
+                }
+                break;
+            default:
+                if (text === "") {
+                    expr = "//*[@role='link' or @href] | //a[href] | //area | //img[not(ancestor::a)]";
+                } else {
+                    expr = "//*[(@role='link' or @href) and contains(., '" + text + "')] | //a[@href and contains(., '" + text + "')] | //area[contains(., '" + text + "')] | //img[not(ancestor::a) and contains(., '" + text + "')]";
+                }
+                break;
+        }
+        return expr;
+    }
+};