2 (c) 2009 by Leon Winter
3 (c) 2009, 2010 by Hannes Schueller
4 (c) 2010 by Hans-Peter Deifel
15 this.createHints = function (inputText
)
17 if (document
.getElementsByTagName("body")[0] === null || typeof(document
.getElementsByTagName("body")[0]) != "object")
20 var height
= window
.innerHeight
;
21 var width
= window
.innerWidth
;
22 var scrollX
= document
.defaultView
.scrollX
;
23 var scrollY
= document
.defaultView
.scrollY
;
24 this.genHintContainer();
26 /* prefixing html: will result in namespace error */
28 if (typeof(inputText
) == "undefined" || inputText
== "") {
29 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";
31 /* only elements which match the text entered so far */
32 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
+ "')]";
36 iterator type isn't suitable here, because: "DOMException NVALID_STATE_ERR:
37 The document has been mutated since the result was returned."
39 var r
= document
.evaluate(hinttags
, document
,
41 return 'http://www.w3.org/1999/xhtml';
42 }, XPathResult
.ORDERED_NODE_SNAPSHOT_TYPE
, null);
44 /* due to the different XPath result type, we will need two counter variables */
47 this.hintElements
= [];
49 this.backgrounds
= [];
50 for (i
= 0; i
< r
.snapshotLength
; i
++)
52 var elem
= r
.snapshotItem(i
);
53 var rect
= elem
.getBoundingClientRect();
54 if (!rect
|| rect
.top
> height
|| rect
.bottom
< 0 || rect
.left
> width
|| rect
.right
< 0 || !(elem
.getClientRects()[0]))
56 var computedStyle
= document
.defaultView
.getComputedStyle(elem
, null);
57 if (computedStyle
.getPropertyValue("visibility") != "visible" || computedStyle
.getPropertyValue("display") == "none")
59 var leftpos
= Math
.max((rect
.left
+ scrollX
), scrollX
);
60 var toppos
= Math
.max((rect
.top
+ scrollY
), scrollY
);
61 this.hintElements
.push(elem
);
62 /* making this block DOM compliant */
63 var hint
= document
.createElement("span");
64 hint
.setAttribute("class", "hinting_mode_hint");
65 hint
.setAttribute("id", "vimprobablehint" + this.hintCount
);
66 hint
.style
.position
= "absolute";
67 hint
.style
.left
= leftpos
+ "px";
68 hint
.style
.top
= toppos
+ "px";
69 hint
.style
.background
= "red";
70 hint
.style
.color
= "#fff";
71 hint
.style
.font
= "bold 10px monospace";
72 hint
.style
.zIndex
= "99";
73 var text
= document
.createTextNode(this.hintCount
+ 1);
74 hint
.appendChild(text
);
75 this.hintContainer
.appendChild(hint
);
76 /* remember site-defined colour of this element */
77 this.colors
[this.hintCount
] = elem
.style
.color
;
78 this.backgrounds
[this.hintCount
] = elem
.style
.background
;
79 /* make the link black to ensure it's readable */
80 elem
.style
.color
= "#000";
81 elem
.style
.background
= "#ff0";
85 this.focusedHint
= null;
86 if (this.hintCount
== 1) {
87 /* just one hinted element - might as well follow it */
92 this.updateHints = function (n
)
94 if(this.focusedHint
!= null) {
95 this.focusedHint
.className
= this.focusedHint
.className
.replace("_focus","");
96 this.focusedHint
.style
.background
= "#ff0";
98 if (this.hintCount
- 1 < n
* 10 && typeof(this.hintElements
[n
- 1]) != "undefined") {
99 /* return signal to follow the link */
102 if (typeof(this.hintElements
[n
- 1]) != "undefined") {
103 (this.focusedHint
= this.hintElements
[n
- 1]).className
= this.hintElements
[n
- 1].className
.replace("hinting_mode_hint", "hinting_mode_hint_focus");
104 this.focusedHint
.style
.background
= "#8f0";
109 this.clearFocus = function ()
111 if (document
.activeElement
&& document
.activeElement
.blur
)
112 document
.activeElement
.blur();
115 this.clearHints = function ()
117 for(e
in this.hintElements
) {
118 if (typeof(this.hintElements
[e
].className
) != "undefined") {
119 this.hintElements
[e
].className
= this.hintElements
[e
].className
.replace(/hinting_mode_hint/,'');
120 /* reset to site-defined colour */
121 this.hintElements
[e
].style
.color
= this.colors
[e
];
122 this.hintElements
[e
].style
.background
= this.backgrounds
[e
];
125 this.hintContainer
.parentNode
.removeChild(this.hintContainer
);
126 window
.onkeyup
= null;
129 this.fire = function (n
)
131 if (typeof(this.hintElements
[n
- 1]) == "undefined")
134 var el
= this.hintElements
[n
- 1];
135 var tag
= el
.nodeName
.toLowerCase();
137 if(tag
== "iframe" || tag
== "frame" || tag
== "textarea" || tag
== "input" && (el
.type
== "text" || el
.type
== "password" || el
.type
== "checkbox" || el
.type
== "radio") || tag
== "select") {
141 if (!el
.onclick
&& el
.href
&& !el
.href
.match('/^javascript:/')) {
142 /* send signal to open link */
143 return "open;" + el
.href
;
145 var evObj
= document
.createEvent('MouseEvents');
146 evObj
.initMouseEvent('click', true, true, window
, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, null);
147 el
.dispatchEvent(evObj
);
150 this.focusInput = function ()
152 if (document
.getElementsByTagName("body")[0] === null || typeof(document
.getElementsByTagName("body")[0]) != "object")
155 /* prefixing html: will result in namespace error */
156 var hinttags
= "//input[@type='text'] | //input[@type='password'] | //textarea";
157 var r
= document
.evaluate(hinttags
, document
,
159 return 'http://www.w3.org/1999/xhtml';
160 }, XPathResult
.ORDERED_NODE_SNAPSHOT_TYPE
, null);
165 for (i
= 0; i
< r
.snapshotLength
; i
++) {
166 var elem
= r
.snapshotItem(i
);
168 if (elem
.style
.display
!= "none" && elem
.style
.visibility
!= "hidden") {
174 if (j
== 1 && elem
.style
.display
!= "none" && elem
.style
.visibility
!= "hidden") {
178 if (elem
== document
.activeElement
) {
183 /* no appropriate field found focused - focus the first one */
184 if (j
== 0 && first
!== null)
188 this.genHintContainer = function ()
190 var body
= document
.getElementsByTagName('body')[0];
191 if (document
.getElementById('hint_container'))
194 this.hintContainer
= document
.createElement('div');
195 this.hintContainer
.id
= "hint_container";
198 body
.appendChild(this.hintContainer
);