1var Behaviour = { 2 list : new Array, 3 4 register : function(sheet){ 5 Behaviour.list.push(sheet); 6 }, 7 8 start : function(){ 9 Behaviour.addLoadEvent(function(){ 10 Behaviour.apply(); 11 }); 12 }, 13 14 apply : function(){ 15 for (h=0;sheet=Behaviour.list[h];h++){ 16 for (selector in sheet){ 17 list = document.getElementsBySelector(selector); 18 19 if (!list){ 20 continue; 21 } 22 23 for (i=0;element=list[i];i++){ 24 sheet[selector](element); 25 } 26 } 27 } 28 }, 29 30 addLoadEvent : function(func){ 31 var oldonload = window.onload; 32 33 if (typeof window.onload != 'function') { 34 window.onload = func; 35 } else { 36 window.onload = function() { 37 oldonload(); 38 func(); 39 } 40 } 41 } 42} 43 44Behaviour.start(); 45 46function getAllChildren(e) { 47 // Returns all children of element. Workaround required for IE5/Windows. Ugh. 48 return e.all ? e.all : e.getElementsByTagName('*'); 49} 50 51document.getElementsBySelector = function(selector) { 52 // Attempt to fail gracefully in lesser browsers 53 if (!document.getElementsByTagName) { 54 return new Array(); 55 } 56 // Split selector in to tokens 57 var tokens = selector.split(' '); 58 var currentContext = new Array(document); 59 for (var i = 0; i < tokens.length; i++) { 60 token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');; 61 if (token.indexOf('#') > -1) { 62 // Token is an ID selector 63 var bits = token.split('#'); 64 var tagName = bits[0]; 65 var id = bits[1]; 66 var element = document.getElementById(id); 67 if (tagName && element.nodeName.toLowerCase() != tagName) { 68 // tag with that ID not found, return false 69 return new Array(); 70 } 71 // Set currentContext to contain just this element 72 currentContext = new Array(element); 73 continue; // Skip to next token 74 } 75 if (token.indexOf('.') > -1) { 76 // Token contains a class selector 77 var bits = token.split('.'); 78 var tagName = bits[0]; 79 var className = bits[1]; 80 if (!tagName) { 81 tagName = '*'; 82 } 83 // Get elements matching tag, filter them for class selector 84 var found = new Array; 85 var foundCount = 0; 86 for (var h = 0; h < currentContext.length; h++) { 87 var elements; 88 if (tagName == '*') { 89 elements = getAllChildren(currentContext[h]); 90 } else { 91 elements = currentContext[h].getElementsByTagName(tagName); 92 } 93 for (var j = 0; j < elements.length; j++) { 94 found[foundCount++] = elements[j]; 95 } 96 } 97 currentContext = new Array; 98 var currentContextIndex = 0; 99 for (var k = 0; k < found.length; k++) { 100 if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) { 101 currentContext[currentContextIndex++] = found[k]; 102 } 103 } 104 continue; // Skip to next token 105 } 106 // Code to deal with attribute selectors 107 if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { 108 var tagName = RegExp.$1; 109 var attrName = RegExp.$2; 110 var attrOperator = RegExp.$3; 111 var attrValue = RegExp.$4; 112 if (!tagName) { 113 tagName = '*'; 114 } 115 // Grab all of the tagName elements within current context 116 var found = new Array; 117 var foundCount = 0; 118 for (var h = 0; h < currentContext.length; h++) { 119 var elements; 120 if (tagName == '*') { 121 elements = getAllChildren(currentContext[h]); 122 } else { 123 elements = currentContext[h].getElementsByTagName(tagName); 124 } 125 for (var j = 0; j < elements.length; j++) { 126 found[foundCount++] = elements[j]; 127 } 128 } 129 currentContext = new Array; 130 var currentContextIndex = 0; 131 var checkFunction; // This function will be used to filter the elements 132 switch (attrOperator) { 133 case '=': // Equality 134 checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); }; 135 break; 136 case '~': // Match one of space seperated words 137 checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); }; 138 break; 139 case '|': // Match start with value followed by optional hyphen 140 checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); }; 141 break; 142 case '^': // Match starts with value 143 checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); }; 144 break; 145 case '$': // Match ends with value - fails with "Warning" in Opera 7 146 checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); }; 147 break; 148 case '*': // Match ends with value 149 checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); }; 150 break; 151 default : 152 // Just test for existence of attribute 153 checkFunction = function(e) { return e.getAttribute(attrName); }; 154 } 155 currentContext = new Array; 156 var currentContextIndex = 0; 157 for (var k = 0; k < found.length; k++) { 158 if (checkFunction(found[k])) { 159 currentContext[currentContextIndex++] = found[k]; 160 } 161 } 162 // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue); 163 continue; // Skip to next token 164 } 165 166 if (!currentContext[0]){ 167 return; 168 } 169 170 // If we get here, token is JUST an element (not a class or ID selector) 171 tagName = token; 172 var found = new Array; 173 var foundCount = 0; 174 for (var h = 0; h < currentContext.length; h++) { 175 var elements = currentContext[h].getElementsByTagName(tagName); 176 for (var j = 0; j < elements.length; j++) { 177 found[foundCount++] = elements[j]; 178 } 179 } 180 currentContext = found; 181 } 182 return currentContext; 183}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.