Fix typos in manpages.
[vimprobable2.git] / input_hinting_mode.js
blob6118cd4757bfff4ea1012a290320b542fd4760ee
1 /*
2     (c) 2009 by Leon Winter
3     (c) 2009 by Hannes Schueller
4     see LICENSE file
5 */
7 function clearfocus() {
8     if(document.activeElement && document.activeElement.blur)
9         document.activeElement.blur();
12 function v(e, y) {
13     t = e.nodeName.toLowerCase();
14     if((t == 'input' && /^(text|password|checkbox|radio)$/.test(e.type))
15     || /^(select|textarea)$/.test(t)
16     || e.contentEditable == 'true')
17         console.log('insertmode_'+(y=='focus'?'on':'off'));
20 if(document.activeElement)
21     v(document.activeElement,'focus');
23 m=['focus','blur'];
25 if (document.getElementsByTagName("body")[0] !== null && typeof(document.getElementsByTagName("body")[0]) == "object") {
26     for(i in m)
27         document.getElementsByTagName('body')[0].addEventListener(m[i], function(x) {
28             v(x.target,x.type);
29         }, true);
31     document.getElementsByTagName("body")[0].appendChild(document.createElement("style"));
32     document.styleSheets[0].addRule('.hinting_mode_hint', 'color: #000; background: #ff0;');
33     document.styleSheets[0].addRule('.hinting_mode_hint_focus', 'color: #000; background: #8f0;');
36 self.onunload = function() {
37     v(document.activeElement, '');
40 function show_hints(inputText) {
41     if (document.getElementsByTagName("body")[0] !== null && typeof(document.getElementsByTagName("body")[0]) == "object") {
42         var height = window.innerHeight;
43         var width = window.innerWidth;
44         var scrollX = document.defaultView.scrollX;
45         var scrollY = document.defaultView.scrollY;
46         /* prefixing html: will result in namespace error */
47         var hinttags;
48         if (typeof(inputText) == "undefined" || inputText == "") {
49             hinttags = "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href] | //input[not(@type='hidden')] | //a | //area | //iframe | //textarea | //button | //select";
50         } else {
51             /* only elements which match the text entered so far */
52             hinttags = "//*[(@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href) and contains(., '" + inputText + "')] | //input[not(@type='hidden') and contains(., '" + inputText + "')] | //a[contains(., '" + inputText + "')] | //area[contains(., '" + inputText + "')] | //iframe[contains(@name, '" + inputText + "')] | //textarea[contains(., '" + inputText + "')] | //button[contains(@value, '" + inputText + "')] | //select[contains(., '" + inputText + "')]";
53         }
55         /* iterator type isn't suitable here, because: "DOMException NVALID_STATE_ERR: The document has been mutated since the result was returned." */
56         var r = document.evaluate(hinttags, document,
57             function(p) {
58                 return 'http://www.w3.org/1999/xhtml';
59             }, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
60         div = document.createElement("div");
61         /* due to the different XPath result type, we will need two counter variables */
62         j = 1;
63         var i;
64         a = [];
65         colors = [];
66         for (i = 0; i < r.snapshotLength; i++)
67         {
68             var elem = r.snapshotItem(i);
69             rect = elem.getBoundingClientRect();
70             if (!rect || rect.top > height || rect.bottom < 0 || rect.left > width || rect.right < 0 || !(elem.getClientRects()[0]))
71                 continue;
72             var computedStyle = document.defaultView.getComputedStyle(elem, null);
73             if (computedStyle.getPropertyValue("visibility") != "visible" || computedStyle.getPropertyValue("display") == "none")
74                 continue;
75             var leftpos = Math.max((rect.left + scrollX), scrollX);
76             var toppos = Math.max((rect.top + scrollY), scrollY);
77             a.push(elem);
78             /* making this block DOM compliant */
79             var hint = document.createElement("span");
80             hint.setAttribute("class", "hinting_mode_hint");
81             hint.setAttribute("id", "vimprobablehint" + j);
82             hint.style.position = "absolute";
83             hint.style.left = leftpos + "px";
84             hint.style.top =  toppos + "px";
85             hint.style.background = "red";
86             hint.style.color = "#fff";
87             hint.style.font = "bold 10px monospace";
88             hint.style.zIndex = "99";
89             var text = document.createTextNode(j);
90             hint.appendChild(text);
91             div.appendChild(hint);
92             /* remember site-defined colour of this element */
93             colors[j] = elem.style.color;
94             /* make the link black to ensure it's readable */
95             elem.style.color = "#000";
96             j++;
97         }
98         i = 0;
99         while (typeof(a[i]) != "undefined") {
100             a[i].className += " hinting_mode_hint";
101             i++;
102         }
103         document.getElementsByTagName("body")[0].appendChild(div);
104         clearfocus();
105         h = null;
106         if (i == 1) {
107             /* just one hinted element - might as well follow it */
108             return fire(1);
109         }
110     }
112 function fire(n)
114     if (typeof(a[n - 1]) != "undefined") {
115         el = a[n - 1];
116         tag = el.nodeName.toLowerCase();
117         clear();
118         if(tag == "iframe" || tag == "frame" || tag == "textarea" || tag == "input" && (el.type == "text" || el.type == "password" || el.type == "checkbox" || el.type == "radio")) {
119             el.focus();
120             if (tag == "textarea" || tag == "input")
121                 console.log('insertmode_on');
122         } else {
123             if (el.onclick) {
124                 var evObj = document.createEvent('MouseEvents');
125                 evObj.initMouseEvent('click', true, true, window, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, null);
126                 el.dispatchEvent(evObj);
127             } else if (el.href) {
128                 if (el.href.match(/^javascript:/)) {
129                     var evObj = document.createEvent('MouseEvents');
130                     evObj.initMouseEvent('click', true, true, window, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, null);
131                     el.dispatchEvent(evObj);
132                 } else {
133                     /* send signal to open link */
134                     return "open;" + el.href;
135                 }
136             } else {
137                 var evObj = document.createEvent('MouseEvents');
138                 evObj.initMouseEvent('click', true, true, window, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, null);
139                 el.dispatchEvent(evObj);
140             }
141         }
142     }
144 function cleanup()
146     for(e in a) {
147         if (typeof(a[e].className) != "undefined") {
148             a[e].className = a[e].className.replace(/hinting_mode_hint/,'');
149             /* reset to site-defined colour */
150             a[e].style.color = colors[e];
151         }
152     }
153     div.parentNode.removeChild(div);
154     window.onkeyup = null;
156 function clear()
158     cleanup();
159     console.log("hintmode_off")
162 function update_hints(n) 
164     if(h != null)
165         h.className = h.className.replace("_focus","");
166     if (j - 1 < n * 10 && typeof(a[n - 1]) != "undefined") {
167         /* return signal to follow the link */
168         return "fire;" + n;
169     } else
170         if (typeof(a[n - 1]) != "undefined")
171             (h = a[n - 1]).className = a[n - 1].className.replace("hinting_mode_hint", "hinting_mode_hint_focus");
174 function focus_input()
176     if (document.getElementsByTagName("body")[0] !== null && typeof(document.getElementsByTagName("body")[0]) == "object") {
177         /* prefixing html: will result in namespace error */
178         var hinttags = "//input[@type='text'] | //input[@type='password'] | //textarea";
179         var r = document.evaluate(hinttags, document,
180             function(p) {
181                 return 'http://www.w3.org/1999/xhtml';
182             }, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
183         var i;
184         var j = 0;
185         var first = null;
186         for (i = 0; i < r.snapshotLength; i++) {
187             var elem = r.snapshotItem(i);
188             if (i == 0) {
189                 first = elem;
190             }
191             if (j == 1) {
192                 elem.focus();
193                 var tag = elem.nodeName.toLowerCase();
194                 if (tag == "textarea" || tag == "input")
195                     console.log('insertmode_on');
196                 break;
197             } else {
198                 if (elem == document.activeElement)
199                     j = 1;
200             }
201         }
202         if (j == 0) {
203             /* no appropriate field found focused - focus the first one */
204             if (first !== null) {
205                 first.focus();
206                 var tag = elem.nodeName.toLowerCase();
207                 if (tag == "textarea" || tag == "input")
208                     console.log('insertmode_on');
209             }
210         }
211     }