/*
|
* Copyright (C) 2007-2017 Diego Perini
|
* All rights reserved.
|
*
|
* this is just a small example to show
|
* how an extension for NWMatcher could be
|
* adapted to handle special jQuery selectors
|
*
|
* Child Selectors
|
* :even, :odd, :eq, :lt, :gt, :first, :last, :nth
|
*
|
* Pseudo Selectors
|
* :has, :button, :header, :input, :checkbox, :radio, :file, :image
|
* :password, :reset, :submit, :text, :hidden, :visible, :parent
|
*
|
*/
|
|
// for structural pseudo-classes extensions
|
NW.Dom.registerSelector(
|
'jquery:child',
|
/^\:((?:(nth|eq|lt|gt)\(([^()]*)\))|(?:even|odd|first|last))(.*)/i,
|
(function(global) {
|
|
return function(match, source, mode, callback) {
|
|
var status = true,
|
macro = mode ? NW.Dom.S_BODY : NW.Dom.M_BODY;
|
|
macro = macro.replace('@', typeof callback == 'function' ? (mode ? NW.Dom.S_TEST : NW.Dom.M_TEST) : '');
|
|
switch (match[1].toLowerCase()) {
|
case 'odd':
|
source = source.replace(macro, 'if((n=n^1)==0){' + macro + '}');
|
break;
|
case 'even':
|
source = source.replace(macro, 'if((n=n^1)==1){' + macro + '}');
|
break;
|
case 'first':
|
source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[0]===e){' + source + '}';
|
break;
|
case 'last':
|
source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[n.length-1]===e){' + source + '}';
|
break;
|
default:
|
switch (match[2].toLowerCase()) {
|
case 'nth':
|
source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[' + match[3] + ']===e){' + source + '}';
|
break;
|
case 'eq':
|
source = source.replace(macro, 'if(x++==' + match[3] + '){' + macro + '}');
|
break;
|
case 'lt':
|
source = source.replace(macro, 'if(x++<' + match[3] + '){' + macro + '}');
|
break;
|
case 'gt':
|
source = source.replace(macro, 'if(x++>' + match[3] + '){' + macro + '}');
|
break;
|
default:
|
status = false;
|
break;
|
}
|
break;
|
}
|
|
// compiler will add this to "source"
|
return {
|
'source': source,
|
'status': status,
|
'modvar': 'x=0'
|
};
|
|
};
|
|
})(this));
|
|
// for element pseudo-classes extensions
|
NW.Dom.registerSelector(
|
'jquery:pseudo',
|
/^\:(has|checkbox|file|image|password|radio|reset|submit|text|button|input|header|hidden|visible|parent)(?:\(\s*(["']*)?([^'"()]*)\2\s*\))?(.*)/i,
|
(function(global) {
|
|
return function(match, source, mode, callback) {
|
|
var status = true,
|
macro = mode ? NW.Dom.S_BODY : NW.Dom.M_BODY;
|
|
macro = macro.replace('@', typeof callback == 'function' ? (mode ? NW.Dom.S_TEST : NW.Dom.M_TEST) : '');
|
|
switch(match[1].toLowerCase()) {
|
case 'has':
|
source = source.replace(macro, 'if(e.getElementsByTagName("' + match[3].replace(/^\s|\s$/g, '') + '")[0]){' + macro + '}');
|
break;
|
case 'checkbox':
|
case 'file':
|
case 'image':
|
case 'password':
|
case 'radio':
|
case 'reset':
|
case 'submit':
|
case 'text':
|
// :checkbox, :file, :image, :password, :radio, :reset, :submit, :text
|
source = 'if(/^' + match[1] + '$/i.test(e.type)){' + source + '}';
|
break;
|
case 'button':
|
source = 'if(/^button$/i.test(e.nodeName)){' + source + '}';
|
break;
|
case 'input':
|
source = 'if(/^(?:button|input|select|textarea)$/i.test(e.nodeName)){' + source + '}';
|
break;
|
case 'header':
|
source = 'if(/^h[1-6]$/i.test(e.nodeName)){' + source + '}';
|
break;
|
case 'hidden':
|
source = 'if(!e.offsetWidth&&!e.offsetHeight){' + source + '}';
|
break;
|
case 'visible':
|
source = 'if(e.offsetWidth||e.offsetHeight){' + source + '}';
|
break;
|
case 'parent':
|
source = 'if(e.firstChild){' + source + '}';
|
break;
|
default:
|
status = false;
|
break;
|
}
|
|
// compiler will add this to "source"
|
return {
|
'source': source,
|
'status': status
|
};
|
|
};
|
|
})(this));
|