PageSourceSearch

https://www.crowcombe-pc.gov.uk/js/css3-mediaqueries.js

js crowcombe-pc.gov.uk collected 2026-10-09 17:08:16 UTC 30,539 bytes, 1,160 lines download raw bytes

vendor: 30,415 bytes, lines 1-1156
1/*
2css3-mediaqueries.js - CSS Helper and CSS3 Media Queries Enabler
3
4author: Wouter van der Graaf <wouter at dynora nl>
5version: 1.0 (20110330)
6license: MIT
7website: http://code.google.com/p/css3-mediaqueries-js/
8
9W3C spec: http://www.w3.org/TR/css3-mediaqueries/
10
11Note: use of embedded <style> is not recommended when using media queries, because IE  has no way of returning the raw literal css text from a <style> element.
12*/
13
14
15// true prototypal inheritance (http://javascript.crockford.com/prototypal.html)
16if (typeof Object.create !== 'function') {
17	Object.create = function (o) {
18		function F() {}
19		F.prototype = o;
20		return new F();
21	};
22}
23
24
25// user agent sniffing shortcuts
26var ua = {
27	toString: function () {
28		return navigator.userAgent;
29	},
30	test: function (s) {
31		return this.toString().toLowerCase().indexOf(s.toLowerCase()) > -1;
32	}
33};
34ua.version = (ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1];
35ua.webkit = ua.test('webkit');
36ua.gecko = ua.test('gecko') && !ua.webkit;
37ua.opera = ua.test('opera');
38ua.ie = ua.test('msie') && !ua.opera;
39ua.ie6 = ua.ie && document.compatMode && typeof document.documentElement.style.maxHeight === 'undefined';
40ua.ie7 = ua.ie && document.documentElement && typeof document.documentElement.style.maxHeight !== 'undefined' && typeof XDomainRequest === 'undefined';
41ua.ie8 = ua.ie && typeof XDomainRequest !== 'undefined';
42
43
44
45// initialize when DOM content is loaded
46var domReady = function () {
47	var fns = [];
48	var init = function () {
49		if (!arguments.callee.done) { // run init functions once
50			arguments.callee.done = true;
51			for (var i = 0; i < fns.length; i++) {
52				fns[i]();
53			}
54		}
55	};
56
57	// listeners for different browsers
58	if (document.addEventListener) {
59		document.addEventListener('DOMContentLoaded', init, false);
60	}
61	if (ua.ie) {
62		(function () {
63			try {
64				// throws errors until after ondocumentready
65				document.documentElement.doScroll('left');
66
67				// If we are in an iframe, the above does not work properly.
68        // Trying to access the length attribute of document.body, however,
69        // does throw an error until ondocumentready, fixing this issue.
70        document.body.length;
71			}
72			catch (e) {
73				setTimeout(arguments.callee, 50);
74				return;
75			}
76			// no errors, fire
77			init();
78		})();
79		// trying to always fire before onload
80		document.onreadystatechange = function () {
81			if (document.readyState === 'complete') {
82				document.onreadystatechange = null;
83				init();
84			}
85		};
86	}
87	if (ua.webkit && document.readyState) {
88		(function () {
89			if (document.readyState !== 'loading') {
90				init();
91			}
92			else {
93				setTimeout(arguments.callee, 10);
94			}
95		})();
96	}
97	window.onload = init; // fallback
98
99  return function (fn) { // add fn to init functions
100    if (typeof fn === 'function') {
101      // If DOM ready has already been fired, fire the function
102      // right away.
103      if(init.done) {
104        fn();
105      } else {
106        // Add to the queue
107        fns[fns.length] = fn;
108      }
109    }
110    return fn;
111  };
112}();
113
114
115// helper library for parsing css to objects
116var cssHelper = function () {
117
118	var regExp = {
119		BLOCKS: /[^\s{;][^{;]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g,
120		BLOCKS_INSIDE: /[^\s{][^{]*\{[^{}]*\}/g,
121		DECLARATIONS: /[a-zA-Z\-]+[^;]*:[^;]+;/g,
122		RELATIVE_URLS: /url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g,
123		// strip whitespace and comments, @import is evil
124		REDUNDANT_COMPONENTS: /(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;|@-moz-document\s*url-prefix\(\)\s*{(([^{}])+{([^{}])+}([^{}])+)+})/g,
125		REDUNDANT_WHITESPACE: /\s*(,|:|;|\{|\})\s*/g,
126		WHITESPACE_IN_PARENTHESES: /\(\s*(\S*)\s*\)/g,
127		MORE_WHITESPACE: /\s{2,}/g,
128		FINAL_SEMICOLONS: /;\}/g,
129		NOT_WHITESPACE: /\S+/g
130	};
131
132	var parsed, parsing = false;
133
134	var waiting = [];
135	var wait = function (fn) {
136		if (typeof fn === 'function') {
137			waiting[waiting.length] = fn;
138		}
139	};
140	var ready = function () {
141		for (var i = 0; i < waiting.length; i++) {
142			waiting[i](parsed);
143		}
144	};
145	var events = {};
146	var broadcast = function (n, v) {
147		if (events[n]) {
148			var listeners = events[n].listeners;
149			if (listeners) {
150				for (var i = 0; i < listeners.length; i++) {
151					listeners[i](v);
152				}
153			}
154		}
155	};
156
157	var requestText = function (url, fnSuccess, fnFailure) {
158		if (ua.ie && !window.XMLHttpRequest) {
159			window.XMLHttpRequest = function () {
160				return new ActiveXObject('Microsoft.XMLHTTP');
161			};
162		}
163		if (!XMLHttpRequest) {
164			return '';
165		}
166		var r = new XMLHttpRequest();
167		try {
168			r.open('get', url, true);
169			r.setRequestHeader('X_REQUESTED_WITH', 'XMLHttpRequest');
170		}
171		catch (e) {
172			fnFailure();
173			return;
174		}
175		var done = false;
176		setTimeout(function () {
177			done = true;
178		}, 5000);
179		document.documentElement.style.cursor = 'progress';
180		r.onreadystatechange = function () {
181			if (r.readyState === 4 && !done) {
182				if (!r.status && location.protocol === 'file:' ||
183						(r.status >= 200 && r.status < 300) ||
184						r.status === 304 ||
185						navigator.userAgent.indexOf('Safari') > -1 && typeof r.status === 'undefined') {
186					fnSuccess(r.responseText);
187				}
188				else {
189					fnFailure();
190				}
191				document.documentElement.style.cursor = '';
192				r = null; // avoid memory leaks
193			}
194		};
195		r.send('');
196	};
197
198	var sanitize = function (text) {
199		text = text.replace(regExp.REDUNDANT_COMPONENTS, '');
200		text = text.replace(regExp.REDUNDANT_WHITESPACE, '$1');
201        text = text.replace(regExp.WHITESPACE_IN_PARENTHESES, '($1)');
202		text = text.replace(regExp.MORE_WHITESPACE, ' ');
203		text = text.replace(regExp.FINAL_SEMICOLONS, '}'); // optional final semicolons
204		return text;
205	};
206
207	var objects = {
208	    stylesheet: function (el) {
209	        var o = {};
210	        var amqs = [], mqls = [], rs = [], rsw = [];
211	        var s = el.cssHelperText;
212
213	        // add attribute media queries
214	        var attr = el.getAttribute('media');
215	        if (attr) {
216	            var qts = attr.toLowerCase().split(',')
217	        }
218	        else {
219	            var qts = ['all'] // imply 'all'
220            }
221	        for (var i = 0; i < qts.length; i++) {
222	            amqs[amqs.length] = objects.mediaQuery(qts[i], o);
223	        }
224
225	        // add media query lists and rules (top down order)
226		    var blocks = s.match(regExp.BLOCKS); // @charset is not a block
227		    if (blocks !== null) {
228			    for (var i = 0; i < blocks.length; i++) {
229				    if (blocks[i].substring(0, 7) === '@media ') { // media query (list)
230					    var mql = objects.mediaQueryList(blocks[i], o);
231					    rs = rs.concat(mql.getRules());
232					    mqls[mqls.length] = mql;
233				    }
234				    else { // regular rule set, page context (@page) or font description (@font-face)
235					    rs[rs.length] = rsw[rsw.length] = objects.rule(blocks[i], o, null);
236				    }
237			    }
238		    }
239
240	        o.element = el;
241	        o.getCssText = function () {
242	            return s;
243	        };
244	        o.getAttrMediaQueries = function () {
245	            return amqs;
246	        };
247	        o.getMediaQueryLists = function () {
248	            return mqls;
249	        };
250	        o.getRules = function () {
251	            return rs;
252	        };
253	        o.getRulesWithoutMQ = function () {
254	            return rsw;
255	        };
256	        return o;
257	    },
258
259		mediaQueryList: function (s, stsh) {
260			var o = {};
261			var idx = s.indexOf('{');
262			var lt = s.substring(0, idx);
263			s = s.substring(idx + 1, s.length - 1);
264			var mqs = [], rs = [];
265
266			// add media queries
267			var qts = lt.toLowerCase().substring(7).split(',');
268			for (var i = 0; i < qts.length; i++) { // parse each media query
269				mqs[mqs.length] = objects.mediaQuery(qts[i], o);
270			}
271
272			// add rule sets
273			var rts = s.match(regExp.BLOCKS_INSIDE);
274			if (rts !== null) {
275				for (i = 0; i < rts.length; i++) {
276					rs[rs.length] = objects.rule(rts[i], stsh, o);
277				}
278			}
279
280			o.type = 'mediaQueryList';
281			o.getMediaQueries = function () {
282				return mqs;
283			};
284			o.getRules = function () {
285				return rs;
286			};
287			o.getListText = function () {
288				return lt;
289			};
290			o.getCssText = function () {
291				return s;
292			};
293			return o;
294		},
295
296		mediaQuery: function (s, listOrSheet) {
297			s = s || '';
298			var mql, stsh;
299			if (listOrSheet.type === 'mediaQueryList') {
300			    mql = listOrSheet;
301		    }
302		    else {
303		        stsh = listOrSheet;
304		    }
305			var not = false, type;
306			var expr = [];
307			var valid = true;
308			var tokens = s.match(regExp.NOT_WHITESPACE);
309
310
311
312			for (var i = 0; i < tokens.length; i++) {
313				var token = tokens[i];
314				if (!type && (token === 'not' || token === 'only')) { // 'not' and 'only' keywords
315					// keyword 'only' does nothing, as if it was not present
316					if (token === 'not') {
317						not = true;
318					}
319				}
320				else if (!type) { // media type
321					type = token;
322				}
323				else if (token.charAt(0) === '(') { // media feature expression
324					var pair = token.substring(1, token.length - 1).split(':');
325					expr[expr.length] = {
326						mediaFeature: pair[0],
327						value: pair[1] || null
328					};
329				}
330			}
331
332			return {
333			    getQueryText: function () {
334			        return s;
335			    },
336			    getAttrStyleSheet: function () {
337			        return stsh || null;
338			    },
339				getList: function () {
340					return mql || null;
341				},
342				getValid: function () {
343					return valid;
344				},
345				getNot: function () {
346					return not;
347				},
348				getMediaType: function () {
349					return type;
350				},
351				getExpressions: function () {
352					return expr;
353				}
354			};
355		},
356
357		rule: function (s, stsh, mql) {
358			var o = {};
359			var idx = s.indexOf('{');
360			var st = s.substring(0, idx);
361			var ss = st.split(',');
362			var ds = [];
363			var dts = s.substring(idx + 1, s.length - 1).split(';');
364			for (var i = 0; i < dts.length; i++) {
365				ds[ds.length] = objects.declaration(dts[i], o);
366			}
367
368			o.getStylesheet = function () {
369			    return stsh || null;
370			};
371			o.getMediaQueryList = function () {
372				return mql || null;
373			};
374			o.getSelectors = function () {
375				return ss;
376			};
377			o.getSelectorText = function () {
378				return st;
379			};
380			o.getDeclarations = function () {
381				return ds;
382			};
383			o.getPropertyValue = function (n) {
384				for (var i = 0; i < ds.length; i++) {
385					if (ds[i].getProperty() === n) {
386						return ds[i].getValue();
387					}
388				}
389				return null;
390			};
391			return o;
392		},
393
394		declaration: function (s, r) {
395			var idx = s.indexOf(':');
396			var p = s.substring(0, idx);
397			var v = s.substring(idx + 1);
398			return {
399				getRule: function () {
400					return r || null;
401				},
402				getProperty: function () {
403					return p;
404				},
405				getValue: function () {
406					return v;
407				}
408			};
409		}
410	};
411
412	var parseText = function (el) {
413		if (typeof el.cssHelperText !== 'string') {
414			return;
415		}
416		var o = {
417		    stylesheet: null,
418			mediaQueryLists: [],
419			rules: [],
420			selectors: {},
421			declarations: [],
422			properties: {}
423		};
424
425		// build stylesheet object
426		var stsh = o.stylesheet = objects.stylesheet(el);
427
428		// collect media query lists
429		var mqls = o.mediaQueryLists = stsh.getMediaQueryLists();
430
431		// collect all rules
432		var ors = o.rules = stsh.getRules();
433
434		// collect all selectors
435		var oss = o.selectors;
436		var collectSelectors = function (r) {
437			var ss = r.getSelectors();
438			for (var i = 0; i < ss.length; i++) {
439				var n = ss[i];
440				if (!oss[n]) {
441					oss[n] = [];
442				}
443				oss[n][oss[n].length] = r;
444			}
445		};
446		for (i = 0; i < ors.length; i++) {
447			collectSelectors(ors[i]);
448		}
449
450		// collect all declarations
451		var ods = o.declarations;
452		for (i = 0; i < ors.length; i++) {
453			ods = o.declarations = ods.concat(ors[i].getDeclarations());
454		}
455
456		// collect all properties
457		var ops = o.properties;
458		for (i = 0; i < ods.length; i++) {
459			var n = ods[i].getProperty();
460			if (!ops[n]) {
461				ops[n] = [];
462			}
463			ops[n][ops[n].length] = ods[i];
464		}
465
466		el.cssHelperParsed = o;
467		parsed[parsed.length] = el;
468		return o;
469	};
470
471	var parseEmbedded = function (el, s) {
472	    return;
473	    // This function doesn't work because of a bug in IE, where innerHTML gives us parsed css instead of raw literal.
474		el.cssHelperText = sanitize(s || el.innerHTML);
475		return parseText(el);
476	};
477
478	var parse = function () {
479		parsing = true;
480		parsed = [];
481		var linked = [];
482		var finish = function () {
483			for (var i = 0; i < linked.length; i++) {
484				parseText(linked[i]);
485			}
486			var styles = document.getElementsByTagName('style');
487			for (i = 0; i < styles.length; i++) {
488				parseEmbedded(styles[i]);
489			}
490			parsing = false;
491			ready();
492		};
493		var links = document.getElementsByTagName('link');
494		for (var i = 0; i < links.length; i++) {
495			var link = links[i];
496			if (link.getAttribute('rel').indexOf('style') > -1 && link.href && link.href.length !== 0 && !link.disabled) {
497				linked[linked.length] = link;
498			}
499		}
500		if (linked.length > 0) {
501			var c = 0;
502			var checkForFinish = function () {
503				c++;
504				if (c === linked.length) { // parse in right order, so after last link is read
505					finish();
506				}
507			};
508			var processLink = function (link) {
509				var href = link.href;
510				requestText(href, function (text) {
511					// fix url's
512					text = sanitize(text).replace(regExp.RELATIVE_URLS, 'url(' + href.substring(0, href.lastIndexOf('/')) + '/$1)');
513					link.cssHelperText = text;
514					checkForFinish();
515				}, checkForFinish);
516			};
517			for (i = 0; i < linked.length; i++) {
518				processLink(linked[i]);
519			}
520		}
521		else {
522			finish();
523		}
524	};
525
526	var types = {
527	    stylesheets: 'array',
528		mediaQueryLists: 'array',
529		rules: 'array',
530		selectors: 'object',
531		declarations: 'array',
532		properties: 'object'
533	};
534
535	var collections = {
536	    stylesheets: null,
537		mediaQueryLists: null,
538		rules: null,
539		selectors: null,
540		declarations: null,
541		properties: null
542	};
543
544	var addToCollection = function (name, v) {
545		if (collections[name] !== null) {
546			if (types[name] === 'array') {
547				return (collections[name] = collections[name].concat(v));
548			}
549			else {
550				var c = collections[name];
551				for (var n in v) {
552					if (v.hasOwnProperty(n)) {
553						if (!c[n]) {
554							c[n] = v[n];
555						}
556						else {
557							c[n] = c[n].concat(v[n]);
558						}
559					}
560				}
561				return c;
562			}
563		}
564	};
565
566	var collect = function (name) {
567		collections[name] = (types[name] === 'array') ? [] : {};
568		for (var i = 0; i < parsed.length; i++) {
569		    var pname = name === 'stylesheets' ? 'stylesheet' : name; // the exception
570			addToCollection(name, parsed[i].cssHelperParsed[pname]);
571		}
572		return collections[name];
573	};
574
575	// viewport size
576	var getViewportSize = function (d) {
577		if (typeof window.innerWidth != 'undefined') {
578			return window['inner' + d];
579		}
580		else if (typeof document.documentElement !== 'undefined'
581				&& typeof document.documentElement.clientWidth !== 'undefined'
582				&& document.documentElement.clientWidth != 0) {
583			return document.documentElement['client' + d];
584		}
585	};
586
587	// public static functions
588	return {
589		addStyle: function (s, mediaTypes, process) {
590			var el;
591			var styleElId = 'css-mediaqueries-js';
592			var styleMedia = '';
593
594			var styleEl = document.getElementById(styleElId);
595
596			if (mediaTypes && mediaTypes.length > 0) {
597			    styleMedia = mediaTypes.join(',');
598					styleElId += styleMedia;
599			}
600
601      if (null !== styleEl) {
602          el = styleEl;
603      }
604      else {
605          el = document.createElement('style');
606          el.setAttribute('type', 'text/css');
607          el.setAttribute('id', styleElId);
608          el.setAttribute('media', styleMedia);
609          document.getElementsByTagName('head')[0].appendChild(el);
610      }
611
612      if (el.styleSheet) { // IE
613          el.styleSheet.cssText += s;
614      }
615      else {
616	        el.appendChild(document.createTextNode(s));
617      }
618
619			el.addedWithCssHelper = true;
620
621			if (typeof process === 'undefined' || process === true) {
622				cssHelper.parsed(function (parsed) {
623					var o = parseEmbedded(el, s);
624					for (var n in o) {
625						if (o.hasOwnProperty(n)) {
626							addToCollection(n, o[n]);
627						}
628					}
629					broadcast('newStyleParsed', el);
630				});
631			}
632			else {
633				el.parsingDisallowed = true;
634			}
635			return el;
636		},
637
638		removeStyle: function (el) {
639			if (el.parentNode)
640				return el.parentNode.removeChild(el);
641		},
642
643		parsed: function (fn) {
644			if (parsing) {
645				wait(fn);
646			}
647			else {
648				if (typeof parsed !== 'undefined') {
649					if (typeof fn === 'function') {
650						fn(parsed);
651					}
652				}
653				else {
654					wait(fn);
655					parse();
656				}
657			}
658		},
659
660		stylesheets: function (fn) {
661		    cssHelper.parsed(function (parsed) {
662		        fn(collections.stylesheets || collect('stylesheets'));
663		    });
664		},
665
666		mediaQueryLists: function (fn) {
667			cssHelper.parsed(function (parsed) {
668				fn(collections.mediaQueryLists || collect('mediaQueryLists'));
669			});
670		},
671
672		rules: function (fn) {
673			cssHelper.parsed(function (parsed) {
674				fn(collections.rules || collect('rules'));
675			});
676		},
677
678		selectors: function (fn) {
679			cssHelper.parsed(function (parsed) {
680				fn(collections.selectors || collect('selectors'));
681			});
682		},
683
684		declarations: function (fn) {
685			cssHelper.parsed(function (parsed) {
686				fn(collections.declarations || collect('declarations'));
687			});
688		},
689
690		properties: function (fn) {
691			cssHelper.parsed(function (parsed) {
692				fn(collections.properties || collect('properties'));
693			});
694		},
695
696		broadcast: broadcast,
697
698		addListener: function (n, fn) { // in case n is 'styleadd': added function is called everytime style is added and parsed
699			if (typeof fn === 'function') {
700				if (!events[n]) {
701					events[n] = {
702						listeners: []
703					};
704				}
705				events[n].listeners[events[n].listeners.length] = fn;
706			}
707		},
708
709		removeListener: function (n, fn) {
710			if (typeof fn === 'function' && events[n]) {
711				var ls = events[n].listeners;
712				for (var i = 0; i < ls.length; i++) {
713					if (ls[i] === fn) {
714						ls.splice(i, 1);
715						i -= 1;
716					}
717				}
718			}
719		},
720
721		getViewportWidth: function () {
722			return getViewportSize('Width');
723		},
724
725		getViewportHeight: function () {
726			return getViewportSize('Height');
727		}
728	};
729}();
730
731
732
733// function to test and apply parsed media queries against browser capabilities
734domReady(function enableCssMediaQueries() {
735	var meter;
736
737	var regExp = {
738		LENGTH_UNIT: /[0-9]+(em|ex|px|in|cm|mm|pt|pc)$/,
739		RESOLUTION_UNIT: /[0-9]+(dpi|dpcm)$/,
740		ASPECT_RATIO: /^[0-9]+\/[0-9]+$/,
741		ABSOLUTE_VALUE: /^[0-9]*(\.[0-9]+)*$/
742	};
743
744	var styles = [];
745
746	var nativeSupport = function () {
747		// check support for media queries
748		var id = 'css3-mediaqueries-test';
749		var el = document.createElement('div');
750		el.id = id;
751		var style = cssHelper.addStyle('@media all and (width) { #' + id +
752			' { width: 1px !important; } }', [], false); // false means don't parse this temp style
753		document.body.appendChild(el);
754		var ret = el.offsetWidth === 1;
755		style.parentNode.removeChild(style);
756		el.parentNode.removeChild(el);
757		nativeSupport = function () {
758			return ret;
759		};
760		return ret;
761	};
762
763	var createMeter = function () { // create measuring element
764		meter = document.createElement('div');
765		meter.style.cssText = 'position:absolute;top:-9999em;left:-9999em;' +
766			'margin:0;border:none;padding:0;width:1em;font-size:1em;'; // cssText is needed for IE, works for the others
767		document.body.appendChild(meter);
768		// meter must have browser default font size of 16px
769		if (meter.offsetWidth !== 16) {
770			meter.style.fontSize = 16 / meter.offsetWidth + 'em';
771		}
772		meter.style.width = '';
773	};
774
775	var measure = function (value) {
776		meter.style.width = value;
777		var amount = meter.offsetWidth;
778		meter.style.width = '';
779		return amount;
780	};
781
782	var testMediaFeature = function (feature, value) {
783		// non-testable features: monochrome|min-monochrome|max-monochrome|scan|grid
784		var l = feature.length;
785		var min = (feature.substring(0, 4) === 'min-');
786		var max = (!min && feature.substring(0, 4) === 'max-');
787
788		if (value !== null) { // determine value type and parse to usable amount
789			var valueType;
790			var amount;
791			if (regExp.LENGTH_UNIT.exec(value)) {
792				valueType = 'length';
793				amount = measure(value);
794			}
795			else if (regExp.RESOLUTION_UNIT.exec(value)) {
796				valueType = 'resolution';
797				amount = parseInt(value, 10);
798				var unit = value.substring((amount + '').length);
799			}
800			else if (regExp.ASPECT_RATIO.exec(value)) {
801				valueType = 'aspect-ratio';
802				amount = value.split('/');
803			}
804			else if (regExp.ABSOLUTE_VALUE) {
805				valueType = 'absolute';
806				amount = value;
807			}
808			else {
809				valueType = 'unknown';
810			}
811		}
812
813		var width, height;
814		if ('device-width' === feature.substring(l - 12, l)) { // screen width
815			width = screen.width;
816			if (value !== null) {
817				if (valueType === 'length') {
818					return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount));
819				}
820				else {
821					return false;
822				}
823			}
824			else { // test width without value
825				return width > 0;
826			}
827		}
828		else if ('device-height' === feature.substring(l - 13, l)) { // screen height
829			height = screen.height;
830			if (value !== null) {
831				if (valueType === 'length') {
832					return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount));
833				}
834				else {
835					return false;
836				}
837			}
838			else { // test height without value
839				return height > 0;
840			}
841		}
842		else if ('width' === feature.substring(l - 5, l)) { // viewport width
843			width = document.documentElement.clientWidth || document.body.clientWidth; // the latter for IE quirks mode
844			if (value !== null) {
845				if (valueType === 'length') {
846					return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount));
847				}
848				else {
849					return false;
850				}
851			}
852			else { // test width without value
853				return width > 0;
854			}
855		}
856		else if ('height' === feature.substring(l - 6, l)) { // viewport height
857			height = document.documentElement.clientHeight || document.body.clientHeight; // the latter for IE quirks mode
858			if (value !== null) {
859				if (valueType === 'length') {
860					return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount));
861				}
862				else {
863					return false;
864				}
865			}
866			else { // test height without value
867				return height > 0;
868			}
869		}
870		else if ('orientation' === feature.substring(l - 11, l)) { // orientation
871
872			width = document.documentElement.clientWidth || document.body.clientWidth; // the latter for IE quirks mode
873			height = document.documentElement.clientHeight || document.body.clientHeight; // the latter for IE quirks mode
874
875			if (valueType === 'absolute') {
876				return (amount === 'portrait') ? (width <= height) : (width > height);
877			}
878			else {
879				return false;
880			}
881		}
882		else if ('aspect-ratio' === feature.substring(l - 12, l)) { // window aspect ratio
883			width = document.documentElement.clientWidth || document.body.clientWidth; // the latter for IE quirks mode
884			height = document.documentElement.clientHeight || document.body.clientHeight; // the latter for IE quirks mode
885
886			var curRatio = width / height;
887			var ratio = amount[1] / amount[0];
888
889			if (valueType === 'aspect-ratio') {
890				return ((min && curRatio >= ratio) || (max && curRatio < ratio) || (!min && !max && curRatio === ratio));
891			}
892			else {
893				return false;
894			}
895		}
896		else if ('device-aspect-ratio' === feature.substring(l - 19, l)) { // screen aspect ratio
897			return valueType === 'aspect-ratio' && screen.width * amount[1] === screen.height * amount[0];
898		}
899		else if ('color-index' === feature.substring(l - 11, l)) { // number of colors
900			var colors = Math.pow(2, screen.colorDepth);
901			if (value !== null) {
902				if (valueType === 'absolute') {
903					return ((min && colors >= amount) || (max && colors < amount) || (!min && !max && colors === amount));
904				}
905				else {
906					return false;
907				}
908			}
909			else { // test height without value
910				return colors > 0;
911			}
912		}
913		else if ('color' === feature.substring(l - 5, l)) { // bits per color component
914			var color = screen.colorDepth;
915			if (value !== null) {
916				if (valueType === 'absolute') {
917					return ((min && color >= amount) || (max && color < amount) || (!min && !max && color === amount));
918				}
919				else {
920					return false;
921				}
922			}
923			else { // test height without value
924				return color > 0;
925			}
926		}
927		else if ('resolution' === feature.substring(l - 10, l)) {
928			var res;
929			if (unit === 'dpcm') {
930				res = measure('1cm');
931			}
932			else {
933				res = measure('1in');
934			}
935			if (value !== null) {
936				if (valueType === 'resolution') {
937					return ((min && res >= amount) || (max && res < amount) || (!min && !max && res === amount));
938				}
939				else {
940					return false;
941				}
942			}
943			else { // test height without value
944				return res > 0;
945			}
946		}
947		else {
948			return false;
949		}
950	};
951
952	var testMediaQuery = function (mq) {
953		var test = mq.getValid();
954		var expressions = mq.getExpressions();
955		var l = expressions.length;
956		if (l > 0) {
957			for (var i = 0; i < l && test; i++) {
958				test = testMediaFeature(expressions[i].mediaFeature, expressions[i].value);
959			}
960			var not = mq.getNot();
961			return (test && !not || not && !test);
962		}
963		return test;
964	};
965
966	var testMediaQueryList = function (mql, ts) {
967	    // ts is null or an array with any media type but 'all'.
968		var mqs = mql.getMediaQueries();
969		var t = {};
970		for (var i = 0; i < mqs.length; i++) {
971		    var type = mqs[i].getMediaType();
972		    if (mqs[i].getExpressions().length === 0) {
973		        continue;
974		        // TODO: Browser check! Assuming old browsers do apply the bare media types, even in a list with media queries.
975		    }
976		    var typeAllowed = true;
977		    if (type !== 'all' && ts && ts.length > 0) {
978		        typeAllowed = false;
979		        for (var j = 0; j < ts.length; j++) {
980		            if (ts[j] === type) {
981		                typeAllowed = true;
982                    }
983		        }
984		    }
985			if (typeAllowed && testMediaQuery(mqs[i])) {
986				t[type] = true;
987			}
988		}
989		var s = [], c = 0;
990		for (var n in t) {
991			if (t.hasOwnProperty(n)) {
992				if (c > 0) {
993					s[c++] = ',';
994				}
995				s[c++] = n;
996			}
997		}
998		if (s.length > 0) {
999			styles[styles.length] = cssHelper.addStyle('@media ' + s.join('') + '{' + mql.getCssText() + '}', ts, false);
1000		}
1001	};
1002
1003	var testMediaQueryLists = function (mqls, ts) {
1004		for (var i = 0; i < mqls.length; i++) {
1005			testMediaQueryList(mqls[i], ts);
1006		}
1007	};
1008
1009	var testStylesheet = function (stsh) {
1010	    var amqs = stsh.getAttrMediaQueries();
1011	    var allPassed = false;
1012	    var t = {};
1013		for (var i = 0; i < amqs.length; i++) {
1014			if (testMediaQuery(amqs[i])) {
1015				t[amqs[i].getMediaType()] = amqs[i].getExpressions().length > 0;
1016			}
1017		}
1018		var ts = [], tswe = [];
1019		for (var n in t) {
1020			if (t.hasOwnProperty(n)) {
1021				ts[ts.length] = n;
1022				if (t[n]) {
1023				    tswe[tswe.length] = n
1024				}
1025			    if (n === 'all') {
1026			        allPassed = true;
1027                }
1028			}
1029		}
1030		if (tswe.length > 0) { // types with query expressions that passed the test
1031		    styles[styles.length] = cssHelper.addStyle(stsh.getCssText(), tswe, false);
1032		}
1033		var mqls = stsh.getMediaQueryLists();
1034		if (allPassed) {
1035		    // If 'all' in media attribute passed the test, then test all @media types in linked CSS and create style with those types.
1036		    testMediaQueryLists(mqls);
1037		}
1038		else {
1039		    // Or else, test only media attribute types that passed the test and also 'all'.
1040		    // For positive '@media all', create style with attribute types that passed their test.
1041		    testMediaQueryLists(mqls, ts);
1042	    }
1043    };
1044
1045	var testStylesheets = function (stshs) {
1046	    for (var i = 0; i < stshs.length; i++) {
1047	        testStylesheet(stshs[i]);
1048	    }
1049	    if (ua.ie) {
1050			// force repaint in IE
1051			document.documentElement.style.display = 'block';
1052			setTimeout(function () {
1053				document.documentElement.style.display = '';
1054			}, 0);
1055			// delay broadcast somewhat for IE
1056			setTimeout(function () {
1057				cssHelper.broadcast('cssMediaQueriesTested');
1058			}, 100);
1059		}
1060		else {
1061			cssHelper.broadcast('cssMediaQueriesTested');
1062		}
1063	};
1064
1065	var test = function () {
1066		for (var i = 0; i < styles.length; i++) {
1067			cssHelper.removeStyle(styles[i]);
1068		}
1069		styles = [];
1070		cssHelper.stylesheets(testStylesheets);
1071	};
1072
1073	var scrollbarWidth = 0;
1074	var checkForResize = function () {
1075		var cvpw = cssHelper.getViewportWidth();
1076		var cvph = cssHelper.getViewportHeight();
1077
1078		// determine scrollbar width in IE, see resizeHandler
1079		if (ua.ie) {
1080			var el = document.createElement('div');
1081			el.style.position = 'absolute';
1082			el.style.top = '-9999em';
1083			el.style.overflow = 'scroll';
1084			document.body.appendChild(el);
1085			scrollbarWidth = el.offsetWidth - el.clientWidth;
1086			document.body.removeChild(el);
1087		}
1088
1089		var timer;
1090		var resizeHandler = function () {
1091			var vpw = cssHelper.getViewportWidth();
1092			var vph = cssHelper.getViewportHeight();
1093			// check whether vp size has really changed, because IE also triggers resize event when body size changes
1094			// 20px allowance to accomodate short appearance of scrollbars in IE in some cases
1095			if (Math.abs(vpw - cvpw) > scrollbarWidth || Math.abs(vph - cvph) > scrollbarWidth) {
1096				cvpw = vpw;
1097				cvph = vph;
1098				clearTimeout(timer);
1099				timer = setTimeout(function () {
1100					if (!nativeSupport()) {
1101						test();
1102					}
1103					else {
1104						cssHelper.broadcast('cssMediaQueriesTested');
1105					}
1106				}, 500);
1107			}
1108		};
1109
1110		window.onresize = function () {
1111			var x = window.onresize || function () {}; // save original
1112			return function () {
1113				x();
1114				resizeHandler();
1115			};
1116		}();
1117	};
1118
1119	// prevent jumping of layout by hiding everything before painting <body>
1120    var docEl = document.documentElement;
1121	docEl.style.marginLeft = '-32767px';
1122
1123	// make sure it comes back after a while
1124	setTimeout(function () {
1125		docEl.style.marginLeft = '';
1126	}, 5000);
1127
1128	return function () {
1129		if (!nativeSupport()) { // if browser doesn't support media queries
1130			cssHelper.addListener('newStyleParsed', function (el) {
1131				testStylesheet(el.cssHelperParsed.stylesheet);
1132			});
1133			// return visibility after media queries are tested
1134			cssHelper.addListener('cssMediaQueriesTested', function () {
1135				// force repaint in IE by changing width
1136				if (ua.ie) {
1137					docEl.style.width = '1px';
1138				}
1139				setTimeout(function () {
1140					docEl.style.width = ''; // undo width
1141					docEl.style.marginLeft = ''; // undo hide
1142				}, 0);
1143				// remove this listener to prevent following execution
1144				cssHelper.removeListener('cssMediaQueriesTested', arguments.callee);
1145			});
1146			createMeter();
1147			test();
1148		}
1149		else {
1150			docEl.style.marginLeft = ''; // undo visibility hidden
1151		}
1152		checkForResize();
1153	};
1154}());
1155
1156
1157// bonus: hotfix for IE6 SP1 (bug KB823727)
1158try {
1159	document.execCommand('BackgroundImageCache', false, true);
1160} catch (e) {}

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.