| /* |
| * Copyright (C) 2007-2018 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, selector) { |
| |
| var status = true, ACCEPT_NODE = NW.Dom.ACCEPT_NODE; |
| |
| switch (match[1].toLowerCase()) { |
| case 'odd': |
| source = source.replace(ACCEPT_NODE, 'if((x=x^1)==0){' + ACCEPT_NODE + '}'); |
| break; |
| case 'even': |
| source = source.replace(ACCEPT_NODE, 'if((x=x^1)==1){' + ACCEPT_NODE + '}'); |
| break; |
| case 'first': |
| source = 'n=h.getElementsByTagName(e.nodeName);if(n.length&&n[0]===e){' + source + '}'; |
| break; |
| case 'last': |
| source = 'n=h.getElementsByTagName(e.nodeName);if(n.length&&n[n.length-1]===e){' + source + '}'; |
| break; |
| default: |
| switch (match[2].toLowerCase()) { |
| case 'nth': |
| source = 'n=h.getElementsByTagName(e.nodeName);if(n.length&&n[' + match[3] + ']===e){' + source + '}'; |
| break; |
| case 'eq': |
| source = source.replace(ACCEPT_NODE, 'if(x++==' + match[3] + '){' + ACCEPT_NODE + '}'); |
| break; |
| case 'lt': |
| source = source.replace(ACCEPT_NODE, 'if(x++<' + match[3] + '){' + ACCEPT_NODE + '}'); |
| break; |
| case 'gt': |
| source = source.replace(ACCEPT_NODE, 'if(x++>' + match[3] + '){' + ACCEPT_NODE + '}'); |
| break; |
| default: |
| status = false; |
| break; |
| } |
| break; |
| } |
| |
| // compiler will add this to "source" |
| return { |
| 'source': source, |
| 'status': status |
| }; |
| |
| }; |
| |
| })(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) { |
| |
| var status = true, ACCEPT_NODE = NW.Dom.ACCEPT_NODE; |
| |
| switch(match[1].toLowerCase()) { |
| case 'has': |
| source = source.replace(ACCEPT_NODE, 'if(e.getElementsByTagName("' + match[3].replace(/^\s|\s$/g, '') + '")[0]){' + ACCEPT_NODE + '}'); |
| 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': |
| case 'input': |
| source = 'if(e.type||/button/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)); |