| [9af201e] | 1 | /*
|
|---|
| 2 | * Copyright (C) 2007-2017 Diego Perini
|
|---|
| 3 | * All rights reserved.
|
|---|
| 4 | *
|
|---|
| 5 | * this is just a small example to show
|
|---|
| 6 | * how an extension for NWMatcher could be
|
|---|
| 7 | * adapted to handle special jQuery selectors
|
|---|
| 8 | *
|
|---|
| 9 | * Child Selectors
|
|---|
| 10 | * :even, :odd, :eq, :lt, :gt, :first, :last, :nth
|
|---|
| 11 | *
|
|---|
| 12 | * Pseudo Selectors
|
|---|
| 13 | * :has, :button, :header, :input, :checkbox, :radio, :file, :image
|
|---|
| 14 | * :password, :reset, :submit, :text, :hidden, :visible, :parent
|
|---|
| 15 | *
|
|---|
| 16 | */
|
|---|
| 17 |
|
|---|
| 18 | // for structural pseudo-classes extensions
|
|---|
| 19 | NW.Dom.registerSelector(
|
|---|
| 20 | 'jquery:child',
|
|---|
| 21 | /^\:((?:(nth|eq|lt|gt)\(([^()]*)\))|(?:even|odd|first|last))(.*)/i,
|
|---|
| 22 | (function(global) {
|
|---|
| 23 |
|
|---|
| 24 | return function(match, source, mode, callback) {
|
|---|
| 25 |
|
|---|
| 26 | var status = true,
|
|---|
| 27 | macro = mode ? NW.Dom.S_BODY : NW.Dom.M_BODY;
|
|---|
| 28 |
|
|---|
| 29 | macro = macro.replace('@', typeof callback == 'function' ? (mode ? NW.Dom.S_TEST : NW.Dom.M_TEST) : '');
|
|---|
| 30 |
|
|---|
| 31 | switch (match[1].toLowerCase()) {
|
|---|
| 32 | case 'odd':
|
|---|
| 33 | source = source.replace(macro, 'if((n=n^1)==0){' + macro + '}');
|
|---|
| 34 | break;
|
|---|
| 35 | case 'even':
|
|---|
| 36 | source = source.replace(macro, 'if((n=n^1)==1){' + macro + '}');
|
|---|
| 37 | break;
|
|---|
| 38 | case 'first':
|
|---|
| 39 | source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[0]===e){' + source + '}';
|
|---|
| 40 | break;
|
|---|
| 41 | case 'last':
|
|---|
| 42 | source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[n.length-1]===e){' + source + '}';
|
|---|
| 43 | break;
|
|---|
| 44 | default:
|
|---|
| 45 | switch (match[2].toLowerCase()) {
|
|---|
| 46 | case 'nth':
|
|---|
| 47 | source = 'n=s.root.getElementsByTagName(e.nodeName);if(n.length&&n[' + match[3] + ']===e){' + source + '}';
|
|---|
| 48 | break;
|
|---|
| 49 | case 'eq':
|
|---|
| 50 | source = source.replace(macro, 'if(x++==' + match[3] + '){' + macro + '}');
|
|---|
| 51 | break;
|
|---|
| 52 | case 'lt':
|
|---|
| 53 | source = source.replace(macro, 'if(x++<' + match[3] + '){' + macro + '}');
|
|---|
| 54 | break;
|
|---|
| 55 | case 'gt':
|
|---|
| 56 | source = source.replace(macro, 'if(x++>' + match[3] + '){' + macro + '}');
|
|---|
| 57 | break;
|
|---|
| 58 | default:
|
|---|
| 59 | status = false;
|
|---|
| 60 | break;
|
|---|
| 61 | }
|
|---|
| 62 | break;
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | // compiler will add this to "source"
|
|---|
| 66 | return {
|
|---|
| 67 | 'source': source,
|
|---|
| 68 | 'status': status,
|
|---|
| 69 | 'modvar': 'x=0'
|
|---|
| 70 | };
|
|---|
| 71 |
|
|---|
| 72 | };
|
|---|
| 73 |
|
|---|
| 74 | })(this));
|
|---|
| 75 |
|
|---|
| 76 | // for element pseudo-classes extensions
|
|---|
| 77 | NW.Dom.registerSelector(
|
|---|
| 78 | 'jquery:pseudo',
|
|---|
| 79 | /^\:(has|checkbox|file|image|password|radio|reset|submit|text|button|input|header|hidden|visible|parent)(?:\(\s*(["']*)?([^'"()]*)\2\s*\))?(.*)/i,
|
|---|
| 80 | (function(global) {
|
|---|
| 81 |
|
|---|
| 82 | return function(match, source, mode, callback) {
|
|---|
| 83 |
|
|---|
| 84 | var status = true,
|
|---|
| 85 | macro = mode ? NW.Dom.S_BODY : NW.Dom.M_BODY;
|
|---|
| 86 |
|
|---|
| 87 | macro = macro.replace('@', typeof callback == 'function' ? (mode ? NW.Dom.S_TEST : NW.Dom.M_TEST) : '');
|
|---|
| 88 |
|
|---|
| 89 | switch(match[1].toLowerCase()) {
|
|---|
| 90 | case 'has':
|
|---|
| 91 | source = source.replace(macro, 'if(e.getElementsByTagName("' + match[3].replace(/^\s|\s$/g, '') + '")[0]){' + macro + '}');
|
|---|
| 92 | break;
|
|---|
| 93 | case 'checkbox':
|
|---|
| 94 | case 'file':
|
|---|
| 95 | case 'image':
|
|---|
| 96 | case 'password':
|
|---|
| 97 | case 'radio':
|
|---|
| 98 | case 'reset':
|
|---|
| 99 | case 'submit':
|
|---|
| 100 | case 'text':
|
|---|
| 101 | // :checkbox, :file, :image, :password, :radio, :reset, :submit, :text
|
|---|
| 102 | source = 'if(/^' + match[1] + '$/i.test(e.type)){' + source + '}';
|
|---|
| 103 | break;
|
|---|
| 104 | case 'button':
|
|---|
| 105 | source = 'if(/^button$/i.test(e.nodeName)){' + source + '}';
|
|---|
| 106 | break;
|
|---|
| 107 | case 'input':
|
|---|
| 108 | source = 'if(/^(?:button|input|select|textarea)$/i.test(e.nodeName)){' + source + '}';
|
|---|
| 109 | break;
|
|---|
| 110 | case 'header':
|
|---|
| 111 | source = 'if(/^h[1-6]$/i.test(e.nodeName)){' + source + '}';
|
|---|
| 112 | break;
|
|---|
| 113 | case 'hidden':
|
|---|
| 114 | source = 'if(!e.offsetWidth&&!e.offsetHeight){' + source + '}';
|
|---|
| 115 | break;
|
|---|
| 116 | case 'visible':
|
|---|
| 117 | source = 'if(e.offsetWidth||e.offsetHeight){' + source + '}';
|
|---|
| 118 | break;
|
|---|
| 119 | case 'parent':
|
|---|
| 120 | source = 'if(e.firstChild){' + source + '}';
|
|---|
| 121 | break;
|
|---|
| 122 | default:
|
|---|
| 123 | status = false;
|
|---|
| 124 | break;
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| 127 | // compiler will add this to "source"
|
|---|
| 128 | return {
|
|---|
| 129 | 'source': source,
|
|---|
| 130 | 'status': status
|
|---|
| 131 | };
|
|---|
| 132 |
|
|---|
| 133 | };
|
|---|
| 134 |
|
|---|
| 135 | })(this));
|
|---|