root / snf-cyclades-app / synnefo / ui / static / snf / js / lib / selectivizr.js @ 3b463c5a
History | View | Annotate | Download (18.6 kB)
1 | 8d08f18a | Kostas Papadimitriou | /*
|
---|---|---|---|
2 | 8d08f18a | Kostas Papadimitriou | selectivizr v1.0.2 - (c) Keith Clark, freely distributable under the terms
|
3 | 8d08f18a | Kostas Papadimitriou | of the MIT license.
|
4 | 8d08f18a | Kostas Papadimitriou | |
5 | 8d08f18a | Kostas Papadimitriou | selectivizr.com
|
6 | 8d08f18a | Kostas Papadimitriou | */
|
7 | 8d08f18a | Kostas Papadimitriou | /*
|
8 | 8d08f18a | Kostas Papadimitriou |
|
9 | 8d08f18a | Kostas Papadimitriou | Notes about this source
|
10 | 8d08f18a | Kostas Papadimitriou | -----------------------
|
11 | 8d08f18a | Kostas Papadimitriou | |
12 | 8d08f18a | Kostas Papadimitriou | * The #DEBUG_START and #DEBUG_END comments are used to mark blocks of code
|
13 | 8d08f18a | Kostas Papadimitriou | that will be removed prior to building a final release version (using a
|
14 | 8d08f18a | Kostas Papadimitriou | pre-compression script)
|
15 | 8d08f18a | Kostas Papadimitriou |
|
16 | 8d08f18a | Kostas Papadimitriou |
|
17 | 8d08f18a | Kostas Papadimitriou | References:
|
18 | 8d08f18a | Kostas Papadimitriou | -----------
|
19 | 8d08f18a | Kostas Papadimitriou |
|
20 | 8d08f18a | Kostas Papadimitriou | * CSS Syntax : http://www.w3.org/TR/2003/WD-css3-syntax-20030813/#style
|
21 | 8d08f18a | Kostas Papadimitriou | * Selectors : http://www.w3.org/TR/css3-selectors/#selectors
|
22 | 8d08f18a | Kostas Papadimitriou | * IE Compatability : http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
|
23 | 8d08f18a | Kostas Papadimitriou | * W3C Selector Tests : http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/
|
24 | 8d08f18a | Kostas Papadimitriou |
|
25 | 8d08f18a | Kostas Papadimitriou | */
|
26 | 8d08f18a | Kostas Papadimitriou | |
27 | 8d08f18a | Kostas Papadimitriou | (function(win) {
|
28 | 8d08f18a | Kostas Papadimitriou | |
29 | 8d08f18a | Kostas Papadimitriou | // If browser isn't IE, then stop execution! This handles the script
|
30 | 8d08f18a | Kostas Papadimitriou | // being loaded by non IE browsers because the developer didn't use
|
31 | 8d08f18a | Kostas Papadimitriou | // conditional comments.
|
32 | 8d08f18a | Kostas Papadimitriou | if (/*@cc_on!@*/true) return; |
33 | 8d08f18a | Kostas Papadimitriou | |
34 | 8d08f18a | Kostas Papadimitriou | // =========================== Init Objects ============================
|
35 | 8d08f18a | Kostas Papadimitriou | |
36 | 8d08f18a | Kostas Papadimitriou | var doc = document;
|
37 | 8d08f18a | Kostas Papadimitriou | var root = doc.documentElement;
|
38 | 8d08f18a | Kostas Papadimitriou | var xhr = getXHRObject();
|
39 | 8d08f18a | Kostas Papadimitriou | var ieVersion = /MSIE (\d+)/.exec(navigator.userAgent)[1]; |
40 | 8d08f18a | Kostas Papadimitriou | |
41 | 8d08f18a | Kostas Papadimitriou | // If were not in standards mode, IE is too old / new or we can't create
|
42 | 8d08f18a | Kostas Papadimitriou | // an XMLHttpRequest object then we should get out now.
|
43 | 8d08f18a | Kostas Papadimitriou | if (doc.compatMode != 'CSS1Compat' || ieVersion<6 || ieVersion>8 || !xhr) { |
44 | 8d08f18a | Kostas Papadimitriou | return;
|
45 | 8d08f18a | Kostas Papadimitriou | } |
46 | 8d08f18a | Kostas Papadimitriou | |
47 | 8d08f18a | Kostas Papadimitriou | |
48 | 8d08f18a | Kostas Papadimitriou | // ========================= Common Objects ============================
|
49 | 8d08f18a | Kostas Papadimitriou | |
50 | 8d08f18a | Kostas Papadimitriou | // Compatiable selector engines in order of CSS3 support. Note: '*' is
|
51 | 8d08f18a | Kostas Papadimitriou | // a placholder for the object key name. (basically, crude compression)
|
52 | 8d08f18a | Kostas Papadimitriou | var selectorEngines = {
|
53 | 8d08f18a | Kostas Papadimitriou | "NW" : "*.Dom.select", |
54 | 8d08f18a | Kostas Papadimitriou | "MooTools" : "$$", |
55 | 8d08f18a | Kostas Papadimitriou | "DOMAssistant" : "*.$", |
56 | 8d08f18a | Kostas Papadimitriou | "Prototype" : "$$", |
57 | 8d08f18a | Kostas Papadimitriou | "YAHOO" : "*.util.Selector.query", |
58 | 8d08f18a | Kostas Papadimitriou | "Sizzle" : "*", |
59 | 8d08f18a | Kostas Papadimitriou | "jQuery" : "*", |
60 | 8d08f18a | Kostas Papadimitriou | "dojo" : "*.query" |
61 | 8d08f18a | Kostas Papadimitriou | }; |
62 | 8d08f18a | Kostas Papadimitriou | |
63 | 8d08f18a | Kostas Papadimitriou | var selectorMethod;
|
64 | 8d08f18a | Kostas Papadimitriou | var enabledWatchers = []; // array of :enabled/:disabled elements to poll |
65 | 8d08f18a | Kostas Papadimitriou | var ie6PatchID = 0; // used to solve ie6's multiple class bug |
66 | 8d08f18a | Kostas Papadimitriou | var patchIE6MultipleClasses = true; // if true adds class bloat to ie6 |
67 | 8d08f18a | Kostas Papadimitriou | var namespace = "slvzr"; |
68 | 8d08f18a | Kostas Papadimitriou | |
69 | 8d08f18a | Kostas Papadimitriou | // Stylesheet parsing regexp's
|
70 | 8d08f18a | Kostas Papadimitriou | var RE_COMMENT = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g; |
71 | 8d08f18a | Kostas Papadimitriou | var RE_IMPORT = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g; |
72 | 8d08f18a | Kostas Papadimitriou | var RE_ASSET_URL = /\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g; |
73 | 8d08f18a | Kostas Papadimitriou | var RE_PSEUDO_STRUCTURAL = /^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/; |
74 | 8d08f18a | Kostas Papadimitriou | var RE_PSEUDO_ELEMENTS = /:(:first-(?:line|letter))/g; |
75 | 8d08f18a | Kostas Papadimitriou | var RE_SELECTOR_GROUP = /(^|})\s*([^\{]*?[\[:][^{]+)/g; |
76 | 8d08f18a | Kostas Papadimitriou | var RE_SELECTOR_PARSE = /([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g; |
77 | 8d08f18a | Kostas Papadimitriou | var RE_LIBRARY_INCOMPATIBLE_PSEUDOS = /(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g; |
78 | 8d08f18a | Kostas Papadimitriou | var RE_PATCH_CLASS_NAME_REPLACE = /[^\w-]/g; |
79 | 8d08f18a | Kostas Papadimitriou | |
80 | 8d08f18a | Kostas Papadimitriou | // HTML UI element regexp's
|
81 | 8d08f18a | Kostas Papadimitriou | var RE_INPUT_ELEMENTS = /^(INPUT|SELECT|TEXTAREA|BUTTON)$/; |
82 | 8d08f18a | Kostas Papadimitriou | var RE_INPUT_CHECKABLE_TYPES = /^(checkbox|radio)$/; |
83 | 8d08f18a | Kostas Papadimitriou | |
84 | 8d08f18a | Kostas Papadimitriou | // Broken attribute selector implementations (IE7/8 native [^=""], [$=""] and [*=""])
|
85 | 8d08f18a | Kostas Papadimitriou | var BROKEN_ATTR_IMPLEMENTATIONS = ieVersion>6 ? /[\$\^*]=(['"])\1/ : null; |
86 | 8d08f18a | Kostas Papadimitriou | |
87 | 8d08f18a | Kostas Papadimitriou | // Whitespace normalization regexp's
|
88 | 8d08f18a | Kostas Papadimitriou | var RE_TIDY_TRAILING_WHITESPACE = /([(\[+~])\s+/g; |
89 | 8d08f18a | Kostas Papadimitriou | var RE_TIDY_LEADING_WHITESPACE = /\s+([)\]+~])/g; |
90 | 8d08f18a | Kostas Papadimitriou | var RE_TIDY_CONSECUTIVE_WHITESPACE = /\s+/g; |
91 | 8d08f18a | Kostas Papadimitriou | var RE_TIDY_TRIM_WHITESPACE = /^\s*((?:[\S\s]*\S)?)\s*$/; |
92 | 8d08f18a | Kostas Papadimitriou | |
93 | 8d08f18a | Kostas Papadimitriou | // String constants
|
94 | 8d08f18a | Kostas Papadimitriou | var EMPTY_STRING = ""; |
95 | 8d08f18a | Kostas Papadimitriou | var SPACE_STRING = " "; |
96 | 8d08f18a | Kostas Papadimitriou | var PLACEHOLDER_STRING = "$1"; |
97 | 8d08f18a | Kostas Papadimitriou | |
98 | 8d08f18a | Kostas Papadimitriou | // =========================== Patching ================================
|
99 | 8d08f18a | Kostas Papadimitriou | |
100 | 8d08f18a | Kostas Papadimitriou | // --[ patchStyleSheet() ]----------------------------------------------
|
101 | 8d08f18a | Kostas Papadimitriou | // Scans the passed cssText for selectors that require emulation and
|
102 | 8d08f18a | Kostas Papadimitriou | // creates one or more patches for each matched selector.
|
103 | 8d08f18a | Kostas Papadimitriou | function patchStyleSheet( cssText ) { |
104 | 8d08f18a | Kostas Papadimitriou | return cssText.replace(RE_PSEUDO_ELEMENTS, PLACEHOLDER_STRING).
|
105 | 8d08f18a | Kostas Papadimitriou | replace(RE_SELECTOR_GROUP, function(m, prefix, selectorText) {
|
106 | 8d08f18a | Kostas Papadimitriou | var selectorGroups = selectorText.split(","); |
107 | 8d08f18a | Kostas Papadimitriou | for (var c = 0, cs = selectorGroups.length; c < cs; c++) { |
108 | 8d08f18a | Kostas Papadimitriou | var selector = normalizeSelectorWhitespace(selectorGroups[c]) + SPACE_STRING;
|
109 | 8d08f18a | Kostas Papadimitriou | var patches = [];
|
110 | 8d08f18a | Kostas Papadimitriou | selectorGroups[c] = selector.replace(RE_SELECTOR_PARSE, |
111 | 8d08f18a | Kostas Papadimitriou | function(match, combinator, pseudo, attribute, index) {
|
112 | 8d08f18a | Kostas Papadimitriou | if (combinator) {
|
113 | 8d08f18a | Kostas Papadimitriou | if (patches.length>0) { |
114 | 8d08f18a | Kostas Papadimitriou | applyPatches( selector.substring(0, index), patches );
|
115 | 8d08f18a | Kostas Papadimitriou | patches = []; |
116 | 8d08f18a | Kostas Papadimitriou | } |
117 | 8d08f18a | Kostas Papadimitriou | return combinator;
|
118 | 8d08f18a | Kostas Papadimitriou | } |
119 | 8d08f18a | Kostas Papadimitriou | else {
|
120 | 8d08f18a | Kostas Papadimitriou | var patch = (pseudo) ? patchPseudoClass( pseudo ) : patchAttribute( attribute );
|
121 | 8d08f18a | Kostas Papadimitriou | if (patch) {
|
122 | 8d08f18a | Kostas Papadimitriou | patches.push(patch); |
123 | 8d08f18a | Kostas Papadimitriou | return "." + patch.className; |
124 | 8d08f18a | Kostas Papadimitriou | } |
125 | 8d08f18a | Kostas Papadimitriou | return match;
|
126 | 8d08f18a | Kostas Papadimitriou | } |
127 | 8d08f18a | Kostas Papadimitriou | } |
128 | 8d08f18a | Kostas Papadimitriou | ); |
129 | 8d08f18a | Kostas Papadimitriou | } |
130 | 8d08f18a | Kostas Papadimitriou | return prefix + selectorGroups.join(","); |
131 | 8d08f18a | Kostas Papadimitriou | }); |
132 | 8d08f18a | Kostas Papadimitriou | }; |
133 | 8d08f18a | Kostas Papadimitriou | |
134 | 8d08f18a | Kostas Papadimitriou | // --[ patchAttribute() ]-----------------------------------------------
|
135 | 8d08f18a | Kostas Papadimitriou | // returns a patch for an attribute selector.
|
136 | 8d08f18a | Kostas Papadimitriou | function patchAttribute( attr ) { |
137 | 8d08f18a | Kostas Papadimitriou | return (!BROKEN_ATTR_IMPLEMENTATIONS || BROKEN_ATTR_IMPLEMENTATIONS.test(attr)) ?
|
138 | 8d08f18a | Kostas Papadimitriou | { className: createClassName(attr), applyClass: true } : null; |
139 | 8d08f18a | Kostas Papadimitriou | }; |
140 | 8d08f18a | Kostas Papadimitriou | |
141 | 8d08f18a | Kostas Papadimitriou | // --[ patchPseudoClass() ]---------------------------------------------
|
142 | 8d08f18a | Kostas Papadimitriou | // returns a patch for a pseudo-class
|
143 | 8d08f18a | Kostas Papadimitriou | function patchPseudoClass( pseudo ) { |
144 | 8d08f18a | Kostas Papadimitriou | |
145 | 8d08f18a | Kostas Papadimitriou | var applyClass = true; |
146 | 8d08f18a | Kostas Papadimitriou | var className = createClassName(pseudo.slice(1)); |
147 | 8d08f18a | Kostas Papadimitriou | var isNegated = pseudo.substring(0, 5) == ":not("; |
148 | 8d08f18a | Kostas Papadimitriou | var activateEventName;
|
149 | 8d08f18a | Kostas Papadimitriou | var deactivateEventName;
|
150 | 8d08f18a | Kostas Papadimitriou | |
151 | 8d08f18a | Kostas Papadimitriou | // if negated, remove :not()
|
152 | 8d08f18a | Kostas Papadimitriou | if (isNegated) {
|
153 | 8d08f18a | Kostas Papadimitriou | pseudo = pseudo.slice(5, -1); |
154 | 8d08f18a | Kostas Papadimitriou | } |
155 | 8d08f18a | Kostas Papadimitriou | |
156 | 8d08f18a | Kostas Papadimitriou | // bracket contents are irrelevant - remove them
|
157 | 8d08f18a | Kostas Papadimitriou | var bracketIndex = pseudo.indexOf("(") |
158 | 8d08f18a | Kostas Papadimitriou | if (bracketIndex > -1) { |
159 | 8d08f18a | Kostas Papadimitriou | pseudo = pseudo.substring(0, bracketIndex);
|
160 | 8d08f18a | Kostas Papadimitriou | } |
161 | 8d08f18a | Kostas Papadimitriou | |
162 | 8d08f18a | Kostas Papadimitriou | // check we're still dealing with a pseudo-class
|
163 | 8d08f18a | Kostas Papadimitriou | if (pseudo.charAt(0) == ":") { |
164 | 8d08f18a | Kostas Papadimitriou | switch (pseudo.slice(1)) { |
165 | 8d08f18a | Kostas Papadimitriou | |
166 | 8d08f18a | Kostas Papadimitriou | case "root": |
167 | 8d08f18a | Kostas Papadimitriou | applyClass = function(e) { |
168 | 8d08f18a | Kostas Papadimitriou | return isNegated ? e != root : e == root;
|
169 | 8d08f18a | Kostas Papadimitriou | } |
170 | 8d08f18a | Kostas Papadimitriou | break;
|
171 | 8d08f18a | Kostas Papadimitriou | |
172 | 8d08f18a | Kostas Papadimitriou | case "target": |
173 | 8d08f18a | Kostas Papadimitriou | // :target is only supported in IE8
|
174 | 8d08f18a | Kostas Papadimitriou | if (ieVersion == 8) { |
175 | 8d08f18a | Kostas Papadimitriou | applyClass = function(e) { |
176 | 8d08f18a | Kostas Papadimitriou | var handler = function() { |
177 | 8d08f18a | Kostas Papadimitriou | var hash = location.hash;
|
178 | 8d08f18a | Kostas Papadimitriou | var hashID = hash.slice(1); |
179 | 8d08f18a | Kostas Papadimitriou | return isNegated ? (hash == EMPTY_STRING || e.id != hashID) : (hash != EMPTY_STRING && e.id == hashID);
|
180 | 8d08f18a | Kostas Papadimitriou | }; |
181 | 8d08f18a | Kostas Papadimitriou | addEvent( win, "hashchange", function() { |
182 | 8d08f18a | Kostas Papadimitriou | toggleElementClass(e, className, handler()); |
183 | 8d08f18a | Kostas Papadimitriou | }) |
184 | 8d08f18a | Kostas Papadimitriou | return handler();
|
185 | 8d08f18a | Kostas Papadimitriou | } |
186 | 8d08f18a | Kostas Papadimitriou | break;
|
187 | 8d08f18a | Kostas Papadimitriou | } |
188 | 8d08f18a | Kostas Papadimitriou | return false; |
189 | 8d08f18a | Kostas Papadimitriou | |
190 | 8d08f18a | Kostas Papadimitriou | case "checked": |
191 | 8d08f18a | Kostas Papadimitriou | applyClass = function(e) { |
192 | 8d08f18a | Kostas Papadimitriou | if (RE_INPUT_CHECKABLE_TYPES.test(e.type)) {
|
193 | 8d08f18a | Kostas Papadimitriou | addEvent( e, "propertychange", function() { |
194 | 8d08f18a | Kostas Papadimitriou | if (event.propertyName == "checked") { |
195 | 8d08f18a | Kostas Papadimitriou | toggleElementClass( e, className, e.checked !== isNegated ); |
196 | 8d08f18a | Kostas Papadimitriou | } |
197 | 8d08f18a | Kostas Papadimitriou | }) |
198 | 8d08f18a | Kostas Papadimitriou | } |
199 | 8d08f18a | Kostas Papadimitriou | return e.checked !== isNegated;
|
200 | 8d08f18a | Kostas Papadimitriou | } |
201 | 8d08f18a | Kostas Papadimitriou | break;
|
202 | 8d08f18a | Kostas Papadimitriou | |
203 | 8d08f18a | Kostas Papadimitriou | case "disabled": |
204 | 8d08f18a | Kostas Papadimitriou | isNegated = !isNegated; |
205 | 8d08f18a | Kostas Papadimitriou | |
206 | 8d08f18a | Kostas Papadimitriou | case "enabled": |
207 | 8d08f18a | Kostas Papadimitriou | applyClass = function(e) { |
208 | 8d08f18a | Kostas Papadimitriou | if (RE_INPUT_ELEMENTS.test(e.tagName)) {
|
209 | 8d08f18a | Kostas Papadimitriou | addEvent( e, "propertychange", function() { |
210 | 8d08f18a | Kostas Papadimitriou | if (event.propertyName == "$disabled") { |
211 | 8d08f18a | Kostas Papadimitriou | toggleElementClass( e, className, e.$disabled === isNegated );
|
212 | 8d08f18a | Kostas Papadimitriou | } |
213 | 8d08f18a | Kostas Papadimitriou | }); |
214 | 8d08f18a | Kostas Papadimitriou | enabledWatchers.push(e); |
215 | 8d08f18a | Kostas Papadimitriou | e.$disabled = e.disabled;
|
216 | 8d08f18a | Kostas Papadimitriou | return e.disabled === isNegated;
|
217 | 8d08f18a | Kostas Papadimitriou | } |
218 | 8d08f18a | Kostas Papadimitriou | return pseudo == ":enabled" ? isNegated : !isNegated; |
219 | 8d08f18a | Kostas Papadimitriou | } |
220 | 8d08f18a | Kostas Papadimitriou | break;
|
221 | 8d08f18a | Kostas Papadimitriou | |
222 | 8d08f18a | Kostas Papadimitriou | case "focus": |
223 | 8d08f18a | Kostas Papadimitriou | activateEventName = "focus";
|
224 | 8d08f18a | Kostas Papadimitriou | deactivateEventName = "blur";
|
225 | 8d08f18a | Kostas Papadimitriou | |
226 | 8d08f18a | Kostas Papadimitriou | case "hover": |
227 | 8d08f18a | Kostas Papadimitriou | if (!activateEventName) {
|
228 | 8d08f18a | Kostas Papadimitriou | activateEventName = "mouseenter";
|
229 | 8d08f18a | Kostas Papadimitriou | deactivateEventName = "mouseleave";
|
230 | 8d08f18a | Kostas Papadimitriou | } |
231 | 8d08f18a | Kostas Papadimitriou | applyClass = function(e) { |
232 | 8d08f18a | Kostas Papadimitriou | addEvent( e, isNegated ? deactivateEventName : activateEventName, function() {
|
233 | 8d08f18a | Kostas Papadimitriou | toggleElementClass( e, className, true );
|
234 | 8d08f18a | Kostas Papadimitriou | }) |
235 | 8d08f18a | Kostas Papadimitriou | addEvent( e, isNegated ? activateEventName : deactivateEventName, function() {
|
236 | 8d08f18a | Kostas Papadimitriou | toggleElementClass( e, className, false );
|
237 | 8d08f18a | Kostas Papadimitriou | }) |
238 | 8d08f18a | Kostas Papadimitriou | return isNegated;
|
239 | 8d08f18a | Kostas Papadimitriou | } |
240 | 8d08f18a | Kostas Papadimitriou | break;
|
241 | 8d08f18a | Kostas Papadimitriou | |
242 | 8d08f18a | Kostas Papadimitriou | // everything else
|
243 | 8d08f18a | Kostas Papadimitriou | default:
|
244 | 8d08f18a | Kostas Papadimitriou | // If we don't support this pseudo-class don't create
|
245 | 8d08f18a | Kostas Papadimitriou | // a patch for it
|
246 | 8d08f18a | Kostas Papadimitriou | if (!RE_PSEUDO_STRUCTURAL.test(pseudo)) {
|
247 | 8d08f18a | Kostas Papadimitriou | return false; |
248 | 8d08f18a | Kostas Papadimitriou | } |
249 | 8d08f18a | Kostas Papadimitriou | break;
|
250 | 8d08f18a | Kostas Papadimitriou | } |
251 | 8d08f18a | Kostas Papadimitriou | } |
252 | 8d08f18a | Kostas Papadimitriou | return { className: className, applyClass: applyClass }; |
253 | 8d08f18a | Kostas Papadimitriou | }; |
254 | 8d08f18a | Kostas Papadimitriou | |
255 | 8d08f18a | Kostas Papadimitriou | // --[ applyPatches() ]-------------------------------------------------
|
256 | 8d08f18a | Kostas Papadimitriou | // uses the passed selector text to find DOM nodes and patch them
|
257 | 8d08f18a | Kostas Papadimitriou | function applyPatches(selectorText, patches) { |
258 | 8d08f18a | Kostas Papadimitriou | var elms;
|
259 | 8d08f18a | Kostas Papadimitriou | |
260 | 8d08f18a | Kostas Papadimitriou | // Although some selector libraries can find :checked :enabled etc.
|
261 | 8d08f18a | Kostas Papadimitriou | // we need to find all elements that could have that state because
|
262 | 8d08f18a | Kostas Papadimitriou | // it can be changed by the user.
|
263 | 8d08f18a | Kostas Papadimitriou | var domSelectorText = selectorText.replace(RE_LIBRARY_INCOMPATIBLE_PSEUDOS, EMPTY_STRING);
|
264 | 8d08f18a | Kostas Papadimitriou | |
265 | 8d08f18a | Kostas Papadimitriou | // If the dom selector equates to an empty string or ends with
|
266 | 8d08f18a | Kostas Papadimitriou | // whitespace then we need to append a universal selector (*) to it.
|
267 | 8d08f18a | Kostas Papadimitriou | if (domSelectorText == EMPTY_STRING || domSelectorText.charAt(domSelectorText.length - 1) == SPACE_STRING) { |
268 | 8d08f18a | Kostas Papadimitriou | domSelectorText += "*";
|
269 | 8d08f18a | Kostas Papadimitriou | } |
270 | 8d08f18a | Kostas Papadimitriou | |
271 | 8d08f18a | Kostas Papadimitriou | // Ensure we catch errors from the selector library
|
272 | 8d08f18a | Kostas Papadimitriou | try {
|
273 | 8d08f18a | Kostas Papadimitriou | elms = selectorMethod( domSelectorText ); |
274 | 8d08f18a | Kostas Papadimitriou | } catch (ex) {
|
275 | 8d08f18a | Kostas Papadimitriou | // #DEBUG_START
|
276 | 8d08f18a | Kostas Papadimitriou | log( "Selector '" + selectorText + "' threw exception '" + ex + "'" ); |
277 | 8d08f18a | Kostas Papadimitriou | // #DEBUG_END
|
278 | 8d08f18a | Kostas Papadimitriou | } |
279 | 8d08f18a | Kostas Papadimitriou | |
280 | 8d08f18a | Kostas Papadimitriou | |
281 | 8d08f18a | Kostas Papadimitriou | if (elms) {
|
282 | 8d08f18a | Kostas Papadimitriou | for (var d = 0, dl = elms.length; d < dl; d++) { |
283 | 8d08f18a | Kostas Papadimitriou | var elm = elms[d];
|
284 | 8d08f18a | Kostas Papadimitriou | var cssClasses = elm.className;
|
285 | 8d08f18a | Kostas Papadimitriou | for (var f = 0, fl = patches.length; f < fl; f++) { |
286 | 8d08f18a | Kostas Papadimitriou | var patch = patches[f];
|
287 | 8d08f18a | Kostas Papadimitriou | |
288 | 8d08f18a | Kostas Papadimitriou | if (!hasPatch(elm, patch)) {
|
289 | 8d08f18a | Kostas Papadimitriou | if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) { |
290 | 8d08f18a | Kostas Papadimitriou | cssClasses = toggleClass(cssClasses, patch.className, true );
|
291 | 8d08f18a | Kostas Papadimitriou | } |
292 | 8d08f18a | Kostas Papadimitriou | } |
293 | 8d08f18a | Kostas Papadimitriou | } |
294 | 8d08f18a | Kostas Papadimitriou | elm.className = cssClasses; |
295 | 8d08f18a | Kostas Papadimitriou | } |
296 | 8d08f18a | Kostas Papadimitriou | } |
297 | 8d08f18a | Kostas Papadimitriou | }; |
298 | 8d08f18a | Kostas Papadimitriou | |
299 | 8d08f18a | Kostas Papadimitriou | // --[ hasPatch() ]-----------------------------------------------------
|
300 | 8d08f18a | Kostas Papadimitriou | // checks for the exsistence of a patch on an element
|
301 | 8d08f18a | Kostas Papadimitriou | function hasPatch( elm, patch ) { |
302 | 8d08f18a | Kostas Papadimitriou | return new RegExp("(^|\\s)" + patch.className + "(\\s|$)").test(elm.className); |
303 | 8d08f18a | Kostas Papadimitriou | }; |
304 | 8d08f18a | Kostas Papadimitriou | |
305 | 8d08f18a | Kostas Papadimitriou | |
306 | 8d08f18a | Kostas Papadimitriou | // =========================== Utility =================================
|
307 | 8d08f18a | Kostas Papadimitriou | |
308 | 8d08f18a | Kostas Papadimitriou | function createClassName( className ) { |
309 | 8d08f18a | Kostas Papadimitriou | return namespace + "-" + ((ieVersion == 6 && patchIE6MultipleClasses) ? |
310 | 8d08f18a | Kostas Papadimitriou | ie6PatchID++ |
311 | 8d08f18a | Kostas Papadimitriou | : |
312 | 8d08f18a | Kostas Papadimitriou | className.replace(RE_PATCH_CLASS_NAME_REPLACE, function(a) { return a.charCodeAt(0) })); |
313 | 8d08f18a | Kostas Papadimitriou | }; |
314 | 8d08f18a | Kostas Papadimitriou | |
315 | 8d08f18a | Kostas Papadimitriou | // --[ log() ]----------------------------------------------------------
|
316 | 8d08f18a | Kostas Papadimitriou | // #DEBUG_START
|
317 | 8d08f18a | Kostas Papadimitriou | function log( message ) { |
318 | 8d08f18a | Kostas Papadimitriou | if (win.console) {
|
319 | 8d08f18a | Kostas Papadimitriou | win.console.log(message); |
320 | 8d08f18a | Kostas Papadimitriou | } |
321 | 8d08f18a | Kostas Papadimitriou | }; |
322 | 8d08f18a | Kostas Papadimitriou | // #DEBUG_END
|
323 | 8d08f18a | Kostas Papadimitriou | |
324 | 8d08f18a | Kostas Papadimitriou | // --[ trim() ]---------------------------------------------------------
|
325 | 8d08f18a | Kostas Papadimitriou | // removes leading, trailing whitespace from a string
|
326 | 8d08f18a | Kostas Papadimitriou | function trim( text ) { |
327 | 8d08f18a | Kostas Papadimitriou | return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING);
|
328 | 8d08f18a | Kostas Papadimitriou | }; |
329 | 8d08f18a | Kostas Papadimitriou | |
330 | 8d08f18a | Kostas Papadimitriou | // --[ normalizeWhitespace() ]------------------------------------------
|
331 | 8d08f18a | Kostas Papadimitriou | // removes leading, trailing and consecutive whitespace from a string
|
332 | 8d08f18a | Kostas Papadimitriou | function normalizeWhitespace( text ) { |
333 | 8d08f18a | Kostas Papadimitriou | return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING);
|
334 | 8d08f18a | Kostas Papadimitriou | }; |
335 | 8d08f18a | Kostas Papadimitriou | |
336 | 8d08f18a | Kostas Papadimitriou | // --[ normalizeSelectorWhitespace() ]----------------------------------
|
337 | 8d08f18a | Kostas Papadimitriou | // tidies whitespace around selector brackets and combinators
|
338 | 8d08f18a | Kostas Papadimitriou | function normalizeSelectorWhitespace( selectorText ) { |
339 | 8d08f18a | Kostas Papadimitriou | return normalizeWhitespace(selectorText.
|
340 | 8d08f18a | Kostas Papadimitriou | replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING). |
341 | 8d08f18a | Kostas Papadimitriou | replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING) |
342 | 8d08f18a | Kostas Papadimitriou | ); |
343 | 8d08f18a | Kostas Papadimitriou | }; |
344 | 8d08f18a | Kostas Papadimitriou | |
345 | 8d08f18a | Kostas Papadimitriou | // --[ toggleElementClass() ]-------------------------------------------
|
346 | 8d08f18a | Kostas Papadimitriou | // toggles a single className on an element
|
347 | 8d08f18a | Kostas Papadimitriou | function toggleElementClass( elm, className, on ) { |
348 | 8d08f18a | Kostas Papadimitriou | var oldClassName = elm.className;
|
349 | 8d08f18a | Kostas Papadimitriou | var newClassName = toggleClass(oldClassName, className, on);
|
350 | 8d08f18a | Kostas Papadimitriou | if (newClassName != oldClassName) {
|
351 | 8d08f18a | Kostas Papadimitriou | elm.className = newClassName; |
352 | 8d08f18a | Kostas Papadimitriou | elm.parentNode.className += EMPTY_STRING; |
353 | 8d08f18a | Kostas Papadimitriou | } |
354 | 8d08f18a | Kostas Papadimitriou | }; |
355 | 8d08f18a | Kostas Papadimitriou | |
356 | 8d08f18a | Kostas Papadimitriou | // --[ toggleClass() ]--------------------------------------------------
|
357 | 8d08f18a | Kostas Papadimitriou | // adds / removes a className from a string of classNames. Used to
|
358 | 8d08f18a | Kostas Papadimitriou | // manage multiple class changes without forcing a DOM redraw
|
359 | 8d08f18a | Kostas Papadimitriou | function toggleClass( classList, className, on ) { |
360 | 8d08f18a | Kostas Papadimitriou | var re = RegExp("(^|\\s)" + className + "(\\s|$)"); |
361 | 8d08f18a | Kostas Papadimitriou | var classExists = re.test(classList);
|
362 | 8d08f18a | Kostas Papadimitriou | if (on) {
|
363 | 8d08f18a | Kostas Papadimitriou | return classExists ? classList : classList + SPACE_STRING + className;
|
364 | 8d08f18a | Kostas Papadimitriou | } else {
|
365 | 8d08f18a | Kostas Papadimitriou | return classExists ? trim(classList.replace(re, PLACEHOLDER_STRING)) : classList;
|
366 | 8d08f18a | Kostas Papadimitriou | } |
367 | 8d08f18a | Kostas Papadimitriou | }; |
368 | 8d08f18a | Kostas Papadimitriou | |
369 | 8d08f18a | Kostas Papadimitriou | // --[ addEvent() ]-----------------------------------------------------
|
370 | 8d08f18a | Kostas Papadimitriou | function addEvent(elm, eventName, eventHandler) { |
371 | 8d08f18a | Kostas Papadimitriou | elm.attachEvent("on" + eventName, eventHandler);
|
372 | 8d08f18a | Kostas Papadimitriou | }; |
373 | 8d08f18a | Kostas Papadimitriou | |
374 | 8d08f18a | Kostas Papadimitriou | // --[ getXHRObject() ]-------------------------------------------------
|
375 | 8d08f18a | Kostas Papadimitriou | function getXHRObject() |
376 | 8d08f18a | Kostas Papadimitriou | { |
377 | 8d08f18a | Kostas Papadimitriou | if (win.XMLHttpRequest) {
|
378 | 8d08f18a | Kostas Papadimitriou | return new XMLHttpRequest; |
379 | 8d08f18a | Kostas Papadimitriou | } |
380 | 8d08f18a | Kostas Papadimitriou | try {
|
381 | 8d08f18a | Kostas Papadimitriou | return new ActiveXObject('Microsoft.XMLHTTP'); |
382 | 8d08f18a | Kostas Papadimitriou | } catch(e) {
|
383 | 8d08f18a | Kostas Papadimitriou | return null; |
384 | 8d08f18a | Kostas Papadimitriou | } |
385 | 8d08f18a | Kostas Papadimitriou | }; |
386 | 8d08f18a | Kostas Papadimitriou | |
387 | 8d08f18a | Kostas Papadimitriou | // --[ loadStyleSheet() ]-----------------------------------------------
|
388 | 8d08f18a | Kostas Papadimitriou | function loadStyleSheet( url ) { |
389 | 8d08f18a | Kostas Papadimitriou | xhr.open("GET", url, false); |
390 | 8d08f18a | Kostas Papadimitriou | xhr.send(); |
391 | 8d08f18a | Kostas Papadimitriou | return (xhr.status==200) ? xhr.responseText : EMPTY_STRING; |
392 | 8d08f18a | Kostas Papadimitriou | }; |
393 | 8d08f18a | Kostas Papadimitriou | |
394 | 8d08f18a | Kostas Papadimitriou | // --[ resolveUrl() ]---------------------------------------------------
|
395 | 8d08f18a | Kostas Papadimitriou | // Converts a URL fragment to a fully qualified URL using the specified
|
396 | 8d08f18a | Kostas Papadimitriou | // context URL. Returns null if same-origin policy is broken
|
397 | 8d08f18a | Kostas Papadimitriou | function resolveUrl( url, contextUrl ) { |
398 | 8d08f18a | Kostas Papadimitriou | |
399 | 8d08f18a | Kostas Papadimitriou | function getProtocolAndHost( url ) { |
400 | 8d08f18a | Kostas Papadimitriou | return url.substring(0, url.indexOf("/", 8)); |
401 | 8d08f18a | Kostas Papadimitriou | }; |
402 | 8d08f18a | Kostas Papadimitriou | |
403 | 8d08f18a | Kostas Papadimitriou | // absolute path
|
404 | 8d08f18a | Kostas Papadimitriou | if (/^https?:\/\//i.test(url)) { |
405 | 8d08f18a | Kostas Papadimitriou | return getProtocolAndHost(contextUrl) == getProtocolAndHost(url) ? url : null; |
406 | 8d08f18a | Kostas Papadimitriou | } |
407 | 8d08f18a | Kostas Papadimitriou | |
408 | 8d08f18a | Kostas Papadimitriou | // root-relative path
|
409 | 8d08f18a | Kostas Papadimitriou | if (url.charAt(0)=="/") { |
410 | 8d08f18a | Kostas Papadimitriou | return getProtocolAndHost(contextUrl) + url;
|
411 | 8d08f18a | Kostas Papadimitriou | } |
412 | 8d08f18a | Kostas Papadimitriou | |
413 | 8d08f18a | Kostas Papadimitriou | // relative path
|
414 | 8d08f18a | Kostas Papadimitriou | var contextUrlPath = contextUrl.split(/[?#]/)[0]; // ignore query string in the contextUrl |
415 | 8d08f18a | Kostas Papadimitriou | if (url.charAt(0) != "?" && contextUrlPath.charAt(contextUrlPath.length - 1) != "/") { |
416 | 8d08f18a | Kostas Papadimitriou | contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1); |
417 | 8d08f18a | Kostas Papadimitriou | } |
418 | 8d08f18a | Kostas Papadimitriou | |
419 | 8d08f18a | Kostas Papadimitriou | return contextUrlPath + url;
|
420 | 8d08f18a | Kostas Papadimitriou | }; |
421 | 8d08f18a | Kostas Papadimitriou | |
422 | 8d08f18a | Kostas Papadimitriou | // --[ parseStyleSheet() ]----------------------------------------------
|
423 | 8d08f18a | Kostas Papadimitriou | // Downloads the stylesheet specified by the URL, removes it's comments
|
424 | 8d08f18a | Kostas Papadimitriou | // and recursivly replaces @import rules with their contents, ultimately
|
425 | 8d08f18a | Kostas Papadimitriou | // returning the full cssText.
|
426 | 8d08f18a | Kostas Papadimitriou | function parseStyleSheet( url ) { |
427 | 8d08f18a | Kostas Papadimitriou | if (url) {
|
428 | 8d08f18a | Kostas Papadimitriou | return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING).
|
429 | 8d08f18a | Kostas Papadimitriou | replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2 ) {
|
430 | 8d08f18a | Kostas Papadimitriou | return parseStyleSheet(resolveUrl(importUrl || importUrl2, url));
|
431 | 8d08f18a | Kostas Papadimitriou | }). |
432 | 8d08f18a | Kostas Papadimitriou | replace(RE_ASSET_URL, function( match, quoteChar, assetUrl ) {
|
433 | 8d08f18a | Kostas Papadimitriou | quoteChar = quoteChar || EMPTY_STRING; |
434 | 8d08f18a | Kostas Papadimitriou | return " url(" + quoteChar + resolveUrl(assetUrl, url) + quoteChar + ") "; |
435 | 8d08f18a | Kostas Papadimitriou | }); |
436 | 8d08f18a | Kostas Papadimitriou | } |
437 | 8d08f18a | Kostas Papadimitriou | return EMPTY_STRING;
|
438 | 8d08f18a | Kostas Papadimitriou | }; |
439 | 8d08f18a | Kostas Papadimitriou | |
440 | 8d08f18a | Kostas Papadimitriou | // --[ init() ]---------------------------------------------------------
|
441 | 8d08f18a | Kostas Papadimitriou | function init() { |
442 | 8d08f18a | Kostas Papadimitriou | // honour the <base> tag
|
443 | 8d08f18a | Kostas Papadimitriou | var url, stylesheet;
|
444 | 8d08f18a | Kostas Papadimitriou | var baseTags = doc.getElementsByTagName("BASE"); |
445 | 8d08f18a | Kostas Papadimitriou | var baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href; |
446 | 8d08f18a | Kostas Papadimitriou | |
447 | 8d08f18a | Kostas Papadimitriou | /* Note: This code prevents IE from freezing / crashing when using
|
448 | 8d08f18a | Kostas Papadimitriou | @font-face .eot files but it modifies the <head> tag and could
|
449 | 8d08f18a | Kostas Papadimitriou | trigger the IE stylesheet limit. It will also cause FOUC issues.
|
450 | 8d08f18a | Kostas Papadimitriou | If you choose to use it, make sure you comment out the for loop
|
451 | 8d08f18a | Kostas Papadimitriou | directly below this comment.
|
452 | 8d08f18a | Kostas Papadimitriou | |
453 | 8d08f18a | Kostas Papadimitriou | var head = doc.getElementsByTagName("head")[0];
|
454 | 8d08f18a | Kostas Papadimitriou | for (var c=doc.styleSheets.length-1; c>=0; c--) {
|
455 | 8d08f18a | Kostas Papadimitriou | stylesheet = doc.styleSheets[c]
|
456 | 8d08f18a | Kostas Papadimitriou | head.appendChild(doc.createElement("style"))
|
457 | 8d08f18a | Kostas Papadimitriou | var patchedStylesheet = doc.styleSheets[doc.styleSheets.length-1];
|
458 | 8d08f18a | Kostas Papadimitriou |
|
459 | 8d08f18a | Kostas Papadimitriou | if (stylesheet.href != EMPTY_STRING) {
|
460 | 8d08f18a | Kostas Papadimitriou | url = resolveUrl(stylesheet.href, baseUrl)
|
461 | 8d08f18a | Kostas Papadimitriou | if (url) {
|
462 | 8d08f18a | Kostas Papadimitriou | patchedStylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) )
|
463 | 8d08f18a | Kostas Papadimitriou | stylesheet.disabled = true
|
464 | 8d08f18a | Kostas Papadimitriou | setTimeout( function () {
|
465 | 8d08f18a | Kostas Papadimitriou | stylesheet.owningElement.parentNode.removeChild(stylesheet.owningElement)
|
466 | 8d08f18a | Kostas Papadimitriou | })
|
467 | 8d08f18a | Kostas Papadimitriou | }
|
468 | 8d08f18a | Kostas Papadimitriou | }
|
469 | 8d08f18a | Kostas Papadimitriou | }
|
470 | 8d08f18a | Kostas Papadimitriou | */
|
471 | 8d08f18a | Kostas Papadimitriou | |
472 | 8d08f18a | Kostas Papadimitriou | for (var c = 0; c < doc.styleSheets.length; c++) { |
473 | 8d08f18a | Kostas Papadimitriou | stylesheet = doc.styleSheets[c] |
474 | 8d08f18a | Kostas Papadimitriou | if (stylesheet.href != EMPTY_STRING) {
|
475 | 8d08f18a | Kostas Papadimitriou | url = resolveUrl(stylesheet.href, baseUrl); |
476 | 8d08f18a | Kostas Papadimitriou | if (url) {
|
477 | 8d08f18a | Kostas Papadimitriou | stylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) ); |
478 | 8d08f18a | Kostas Papadimitriou | } |
479 | 8d08f18a | Kostas Papadimitriou | } |
480 | 8d08f18a | Kostas Papadimitriou | } |
481 | 8d08f18a | Kostas Papadimitriou | |
482 | 8d08f18a | Kostas Papadimitriou | // :enabled & :disabled polling script (since we can't hook
|
483 | 8d08f18a | Kostas Papadimitriou | // onpropertychange event when an element is disabled)
|
484 | 8d08f18a | Kostas Papadimitriou | if (enabledWatchers.length > 0) { |
485 | 8d08f18a | Kostas Papadimitriou | setInterval( function() {
|
486 | 8d08f18a | Kostas Papadimitriou | for (var c = 0, cl = enabledWatchers.length; c < cl; c++) { |
487 | 8d08f18a | Kostas Papadimitriou | var e = enabledWatchers[c];
|
488 | 8d08f18a | Kostas Papadimitriou | if (e.disabled !== e.$disabled) { |
489 | 8d08f18a | Kostas Papadimitriou | if (e.disabled) {
|
490 | 8d08f18a | Kostas Papadimitriou | e.disabled = false;
|
491 | 8d08f18a | Kostas Papadimitriou | e.$disabled = true; |
492 | 8d08f18a | Kostas Papadimitriou | e.disabled = true;
|
493 | 8d08f18a | Kostas Papadimitriou | } |
494 | 8d08f18a | Kostas Papadimitriou | else {
|
495 | 8d08f18a | Kostas Papadimitriou | e.$disabled = e.disabled;
|
496 | 8d08f18a | Kostas Papadimitriou | } |
497 | 8d08f18a | Kostas Papadimitriou | } |
498 | 8d08f18a | Kostas Papadimitriou | } |
499 | 8d08f18a | Kostas Papadimitriou | },250)
|
500 | 8d08f18a | Kostas Papadimitriou | } |
501 | 8d08f18a | Kostas Papadimitriou | }; |
502 | 8d08f18a | Kostas Papadimitriou | |
503 | 8d08f18a | Kostas Papadimitriou | // Bind selectivizr to the ContentLoaded event.
|
504 | 8d08f18a | Kostas Papadimitriou | ContentLoaded(win, function() {
|
505 | 8d08f18a | Kostas Papadimitriou | // Determine the "best fit" selector engine
|
506 | 8d08f18a | Kostas Papadimitriou | for (var engine in selectorEngines) { |
507 | 8d08f18a | Kostas Papadimitriou | var members, member, context = win;
|
508 | 8d08f18a | Kostas Papadimitriou | if (win[engine]) {
|
509 | 8d08f18a | Kostas Papadimitriou | members = selectorEngines[engine].replace("*", engine).split("."); |
510 | 8d08f18a | Kostas Papadimitriou | while ((member = members.shift()) && (context = context[member])) {}
|
511 | 8d08f18a | Kostas Papadimitriou | if (typeof context == "function") { |
512 | 8d08f18a | Kostas Papadimitriou | selectorMethod = context; |
513 | 8d08f18a | Kostas Papadimitriou | init(); |
514 | 8d08f18a | Kostas Papadimitriou | return;
|
515 | 8d08f18a | Kostas Papadimitriou | } |
516 | 8d08f18a | Kostas Papadimitriou | } |
517 | 8d08f18a | Kostas Papadimitriou | } |
518 | 8d08f18a | Kostas Papadimitriou | }); |
519 | 8d08f18a | Kostas Papadimitriou | |
520 | 8d08f18a | Kostas Papadimitriou | |
521 | 8d08f18a | Kostas Papadimitriou | /*!
|
522 | 8d08f18a | Kostas Papadimitriou | * ContentLoaded.js by Diego Perini, modified for IE<9 only (to save space)
|
523 | 8d08f18a | Kostas Papadimitriou | *
|
524 | 8d08f18a | Kostas Papadimitriou | * Author: Diego Perini (diego.perini at gmail.com)
|
525 | 8d08f18a | Kostas Papadimitriou | * Summary: cross-browser wrapper for DOMContentLoaded
|
526 | 8d08f18a | Kostas Papadimitriou | * Updated: 20101020
|
527 | 8d08f18a | Kostas Papadimitriou | * License: MIT
|
528 | 8d08f18a | Kostas Papadimitriou | * Version: 1.2
|
529 | 8d08f18a | Kostas Papadimitriou | *
|
530 | 8d08f18a | Kostas Papadimitriou | * URL:
|
531 | 8d08f18a | Kostas Papadimitriou | * http://javascript.nwbox.com/ContentLoaded/
|
532 | 8d08f18a | Kostas Papadimitriou | * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
|
533 | 8d08f18a | Kostas Papadimitriou | *
|
534 | 8d08f18a | Kostas Papadimitriou | */
|
535 | 8d08f18a | Kostas Papadimitriou | |
536 | 8d08f18a | Kostas Papadimitriou | // @w window reference
|
537 | 8d08f18a | Kostas Papadimitriou | // @f function reference
|
538 | 8d08f18a | Kostas Papadimitriou | function ContentLoaded(win, fn) { |
539 | 8d08f18a | Kostas Papadimitriou | |
540 | 8d08f18a | Kostas Papadimitriou | var done = false, top = true, |
541 | 8d08f18a | Kostas Papadimitriou | init = function(e) { |
542 | 8d08f18a | Kostas Papadimitriou | if (e.type == "readystatechange" && doc.readyState != "complete") return; |
543 | 8d08f18a | Kostas Papadimitriou | (e.type == "load" ? win : doc).detachEvent("on" + e.type, init, false); |
544 | 8d08f18a | Kostas Papadimitriou | if (!done && (done = true)) fn.call(win, e.type || e); |
545 | 8d08f18a | Kostas Papadimitriou | }, |
546 | 8d08f18a | Kostas Papadimitriou | poll = function() { |
547 | 8d08f18a | Kostas Papadimitriou | try { root.doScroll("left"); } catch(e) { setTimeout(poll, 50); return; } |
548 | 8d08f18a | Kostas Papadimitriou | init('poll');
|
549 | 8d08f18a | Kostas Papadimitriou | }; |
550 | 8d08f18a | Kostas Papadimitriou | |
551 | 8d08f18a | Kostas Papadimitriou | if (doc.readyState == "complete") fn.call(win, EMPTY_STRING); |
552 | 8d08f18a | Kostas Papadimitriou | else {
|
553 | 8d08f18a | Kostas Papadimitriou | if (doc.createEventObject && root.doScroll) {
|
554 | 8d08f18a | Kostas Papadimitriou | try { top = !win.frameElement; } catch(e) { } |
555 | 8d08f18a | Kostas Papadimitriou | if (top) poll();
|
556 | 8d08f18a | Kostas Papadimitriou | } |
557 | 8d08f18a | Kostas Papadimitriou | addEvent(doc,"readystatechange", init);
|
558 | 8d08f18a | Kostas Papadimitriou | addEvent(win,"load", init);
|
559 | 8d08f18a | Kostas Papadimitriou | } |
560 | 8d08f18a | Kostas Papadimitriou | }; |
561 | 8d08f18a | Kostas Papadimitriou | })(this); |