2009-06-03 18:55:02 +00:00
/ *
2009-10-21 18:53:19 +00:00
( c ) 2009 by Leon Winter
2010-11-01 20:18:57 +00:00
( c ) 2009 , 2010 by Hannes Schueller
( c ) 2010 by Hans - Peter Deifel
2009-10-21 18:53:19 +00:00
see LICENSE file
2009-06-03 18:55:02 +00:00
* /
2010-07-23 12:50:30 +00:00
function vimprobable _clearfocus ( ) {
2009-06-03 20:42:37 +00:00
if ( document . activeElement && document . activeElement . blur )
2009-06-03 18:55:02 +00:00
document . activeElement . blur ( ) ;
2009-06-03 20:42:37 +00:00
}
2009-06-03 18:55:02 +00:00
2010-07-23 12:50:30 +00:00
function vimprobable _show _hints ( inputText ) {
2009-11-15 10:56:40 +00:00
if ( document . getElementsByTagName ( "body" ) [ 0 ] !== null && typeof ( document . getElementsByTagName ( "body" ) [ 0 ] ) == "object" ) {
var height = window . innerHeight ;
var width = window . innerWidth ;
var scrollX = document . defaultView . scrollX ;
var scrollY = document . defaultView . scrollY ;
/* prefixing html: will result in namespace error */
2009-11-29 14:09:08 +00:00
var hinttags ;
if ( typeof ( inputText ) == "undefined" || inputText == "" ) {
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" ;
} else {
/* only elements which match the text entered so far */
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 + "')]" ;
}
2009-10-21 18:53:19 +00:00
2009-11-15 10:56:40 +00:00
/* iterator type isn't suitable here, because: "DOMException NVALID_STATE_ERR: The document has been mutated since the result was returned." */
var r = document . evaluate ( hinttags , document ,
function ( p ) {
return 'http://www.w3.org/1999/xhtml' ;
} , XPathResult . ORDERED _NODE _SNAPSHOT _TYPE , null ) ;
div = document . createElement ( "div" ) ;
/* due to the different XPath result type, we will need two counter variables */
2010-07-23 12:50:30 +00:00
vimprobable _j = 0 ;
2009-11-15 10:56:40 +00:00
var i ;
2010-07-23 12:50:30 +00:00
vimprobable _a = [ ] ;
vimprobable _colors = [ ] ;
vimprobable _backgrounds = [ ] ;
2009-11-15 10:56:40 +00:00
for ( i = 0 ; i < r . snapshotLength ; i ++ )
{
var elem = r . snapshotItem ( i ) ;
rect = elem . getBoundingClientRect ( ) ;
if ( ! rect || rect . top > height || rect . bottom < 0 || rect . left > width || rect . right < 0 || ! ( elem . getClientRects ( ) [ 0 ] ) )
continue ;
var computedStyle = document . defaultView . getComputedStyle ( elem , null ) ;
if ( computedStyle . getPropertyValue ( "visibility" ) != "visible" || computedStyle . getPropertyValue ( "display" ) == "none" )
continue ;
var leftpos = Math . max ( ( rect . left + scrollX ) , scrollX ) ;
var toppos = Math . max ( ( rect . top + scrollY ) , scrollY ) ;
2010-07-23 12:50:30 +00:00
vimprobable _a . push ( elem ) ;
2009-11-15 10:56:40 +00:00
/* making this block DOM compliant */
var hint = document . createElement ( "span" ) ;
hint . setAttribute ( "class" , "hinting_mode_hint" ) ;
2010-07-23 12:50:30 +00:00
hint . setAttribute ( "id" , "vimprobablehint" + vimprobable _j ) ;
2009-11-15 10:56:40 +00:00
hint . style . position = "absolute" ;
hint . style . left = leftpos + "px" ;
hint . style . top = toppos + "px" ;
hint . style . background = "red" ;
hint . style . color = "#fff" ;
hint . style . font = "bold 10px monospace" ;
hint . style . zIndex = "99" ;
2010-07-23 12:50:30 +00:00
var text = document . createTextNode ( vimprobable _j + 1 ) ;
2009-11-15 10:56:40 +00:00
hint . appendChild ( text ) ;
div . appendChild ( hint ) ;
2010-02-07 11:23:10 +00:00
/* remember site-defined colour of this element */
2010-07-23 12:50:30 +00:00
vimprobable _colors [ vimprobable _j ] = elem . style . color ;
vimprobable _backgrounds [ vimprobable _j ] = elem . style . background ;
2010-02-07 11:23:10 +00:00
/* make the link black to ensure it's readable */
elem . style . color = "#000" ;
2010-07-18 12:29:37 +00:00
elem . style . background = "#ff0" ;
2010-07-23 12:50:30 +00:00
vimprobable _j ++ ;
2009-11-15 10:56:40 +00:00
}
i = 0 ;
2010-07-23 12:50:30 +00:00
while ( typeof ( vimprobable _a [ i ] ) != "undefined" ) {
vimprobable _a [ i ] . className += " hinting_mode_hint" ;
2009-11-15 10:56:40 +00:00
i ++ ;
}
document . getElementsByTagName ( "body" ) [ 0 ] . appendChild ( div ) ;
2010-07-23 12:50:30 +00:00
vimprobable _clearfocus ( ) ;
vimprobable _h = null ;
2009-11-29 14:09:08 +00:00
if ( i == 1 ) {
/* just one hinted element - might as well follow it */
2010-07-23 12:50:30 +00:00
return vimprobable _fire ( 1 ) ;
2009-11-29 14:09:08 +00:00
}
2009-06-03 20:42:37 +00:00
}
}
2010-07-23 12:50:30 +00:00
function vimprobable _fire ( n )
2009-06-03 20:42:37 +00:00
{
2010-07-23 12:50:30 +00:00
if ( typeof ( vimprobable _a [ n - 1 ] ) != "undefined" ) {
el = vimprobable _a [ n - 1 ] ;
2009-10-21 18:53:19 +00:00
tag = el . nodeName . toLowerCase ( ) ;
2010-07-23 12:50:30 +00:00
vimprobable _clear ( ) ;
if ( tag == "iframe" || tag == "frame" || tag == "textarea" || tag == "input" && ( el . type == "text" || el . type == "password" || el . type == "checkbox" || el . type == "radio" ) || tag == "select" ) {
2009-10-21 18:53:19 +00:00
el . focus ( ) ;
2009-10-22 11:32:16 +00:00
if ( tag == "textarea" || tag == "input" )
console . log ( 'insertmode_on' ) ;
} else {
2010-06-01 09:27:05 +00:00
if ( el . onclick ) {
var evObj = document . createEvent ( 'MouseEvents' ) ;
evObj . initMouseEvent ( 'click' , true , true , window , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , null ) ;
el . dispatchEvent ( evObj ) ;
} else if ( el . href ) {
if ( el . href . match ( /^javascript:/ ) ) {
var evObj = document . createEvent ( 'MouseEvents' ) ;
evObj . initMouseEvent ( 'click' , true , true , window , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , null ) ;
el . dispatchEvent ( evObj ) ;
} else {
/* send signal to open link */
return "open;" + el . href ;
}
2009-12-13 14:13:30 +00:00
} else {
var evObj = document . createEvent ( 'MouseEvents' ) ;
evObj . initMouseEvent ( 'click' , true , true , window , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , null ) ;
el . dispatchEvent ( evObj ) ;
}
2009-10-21 18:53:19 +00:00
}
2009-06-03 20:42:37 +00:00
}
}
2010-07-23 12:50:30 +00:00
function vimprobable _cleanup ( )
2009-06-03 20:42:37 +00:00
{
2010-07-23 12:50:30 +00:00
for ( e in vimprobable _a ) {
if ( typeof ( vimprobable _a [ e ] . className ) != "undefined" ) {
vimprobable _a [ e ] . className = vimprobable _a [ e ] . className . replace ( /hinting_mode_hint/ , '' ) ;
2010-02-07 11:23:10 +00:00
/* reset to site-defined colour */
2010-07-23 12:50:30 +00:00
vimprobable _a [ e ] . style . color = vimprobable _colors [ e ] ;
vimprobable _a [ e ] . style . background = vimprobable _backgrounds [ e ] ;
2010-02-07 11:23:10 +00:00
}
2009-11-05 13:14:19 +00:00
}
2009-06-03 20:42:37 +00:00
div . parentNode . removeChild ( div ) ;
window . onkeyup = null ;
}
2010-07-23 12:50:30 +00:00
function vimprobable _clear ( )
2009-06-03 20:42:37 +00:00
{
2010-07-23 12:50:30 +00:00
vimprobable _cleanup ( ) ;
2009-06-03 20:42:37 +00:00
console . log ( "hintmode_off" )
}
2009-10-21 18:53:19 +00:00
2010-07-23 12:50:30 +00:00
function vimprobable _update _hints ( n )
2009-10-21 18:53:19 +00:00
{
2010-07-23 12:50:30 +00:00
if ( vimprobable _h != null ) {
vimprobable _h . className = vimprobable _h . className . replace ( "_focus" , "" ) ;
vimprobable _h . style . background = "#ff0" ;
}
if ( vimprobable _j - 1 < n * 10 && typeof ( vimprobable _a [ n - 1 ] ) != "undefined" ) {
2009-11-29 10:55:31 +00:00
/* return signal to follow the link */
return "fire;" + n ;
2010-07-23 12:50:30 +00:00
} else {
if ( typeof ( vimprobable _a [ n - 1 ] ) != "undefined" ) {
( vimprobable _h = vimprobable _a [ n - 1 ] ) . className = vimprobable _a [ n - 1 ] . className . replace ( "hinting_mode_hint" , "hinting_mode_hint_focus" ) ;
vimprobable _h . style . background = "#8f0" ;
}
}
2009-10-21 18:53:19 +00:00
}
2010-07-23 12:50:30 +00:00
function vimprobable _focus _input ( )
2010-02-07 12:58:06 +00:00
{
if ( document . getElementsByTagName ( "body" ) [ 0 ] !== null && typeof ( document . getElementsByTagName ( "body" ) [ 0 ] ) == "object" ) {
/* prefixing html: will result in namespace error */
2010-03-14 15:45:46 +00:00
var hinttags = "//input[@type='text'] | //input[@type='password'] | //textarea" ;
2010-02-07 12:58:06 +00:00
var r = document . evaluate ( hinttags , document ,
function ( p ) {
return 'http://www.w3.org/1999/xhtml' ;
} , XPathResult . ORDERED _NODE _SNAPSHOT _TYPE , null ) ;
var i ;
var j = 0 ;
2010-09-07 14:55:34 +00:00
var k = 0 ;
2010-03-15 09:40:51 +00:00
var first = null ;
2010-02-07 12:58:06 +00:00
for ( i = 0 ; i < r . snapshotLength ; i ++ ) {
var elem = r . snapshotItem ( i ) ;
2010-09-07 14:55:34 +00:00
if ( k == 0 ) {
if ( elem . style . display != "none" && elem . style . visibility != "hidden" ) {
first = elem ;
} else {
k -- ;
}
2010-02-07 12:58:06 +00:00
}
2010-09-07 14:55:34 +00:00
if ( j == 1 && elem . style . display != "none" && elem . style . visibility != "hidden" ) {
2010-02-07 12:58:06 +00:00
elem . focus ( ) ;
var tag = elem . nodeName . toLowerCase ( ) ;
if ( tag == "textarea" || tag == "input" )
console . log ( 'insertmode_on' ) ;
break ;
} else {
if ( elem == document . activeElement )
j = 1 ;
}
2010-09-07 14:55:34 +00:00
k ++ ;
2010-02-07 12:58:06 +00:00
}
if ( j == 0 ) {
/* no appropriate field found focused - focus the first one */
if ( first !== null ) {
2010-07-18 12:29:37 +00:00
first . focus ( ) ;
2010-02-07 12:58:06 +00:00
var tag = elem . nodeName . toLowerCase ( ) ;
if ( tag == "textarea" || tag == "input" )
console . log ( 'insertmode_on' ) ;
}
}
}
}