diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luapplib/html/_static/css3-mediaqueries_src.js')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luapplib/html/_static/css3-mediaqueries_src.js | 1104 |
1 files changed, 1104 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luapplib/html/_static/css3-mediaqueries_src.js b/Build/source/texk/web2c/luatexdir/luapplib/html/_static/css3-mediaqueries_src.js new file mode 100644 index 00000000000..f21dd4949aa --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luapplib/html/_static/css3-mediaqueries_src.js @@ -0,0 +1,1104 @@ +/* +css3-mediaqueries.js - CSS Helper and CSS3 Media Queries Enabler + +author: Wouter van der Graaf <wouter at dynora nl> +version: 1.0 (20110330) +license: MIT +website: http://code.google.com/p/css3-mediaqueries-js/ + +W3C spec: http://www.w3.org/TR/css3-mediaqueries/ + +Note: 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. +*/ + + +// true prototypal inheritance (http://javascript.crockford.com/prototypal.html) +if (typeof Object.create !== 'function') { + Object.create = function (o) { + function F() {} + F.prototype = o; + return new F(); + }; +} + + +// user agent sniffing shortcuts +var ua = { + toString: function () { + return navigator.userAgent; + }, + test: function (s) { + return this.toString().toLowerCase().indexOf(s.toLowerCase()) > -1; + } +}; +ua.version = (ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1]; +ua.webkit = ua.test('webkit'); +ua.gecko = ua.test('gecko') && !ua.webkit; +ua.opera = ua.test('opera'); +ua.ie = ua.test('msie') && !ua.opera; +ua.ie6 = ua.ie && document.compatMode && typeof document.documentElement.style.maxHeight === 'undefined'; +ua.ie7 = ua.ie && document.documentElement && typeof document.documentElement.style.maxHeight !== 'undefined' && typeof XDomainRequest === 'undefined'; +ua.ie8 = ua.ie && typeof XDomainRequest !== 'undefined'; + + + +// initialize when DOM content is loaded +var domReady = function () { + var fns = []; + var init = function () { + if (!arguments.callee.done) { // run init functions once + arguments.callee.done = true; + for (var i = 0; i < fns.length; i++) { + fns[i](); + } + } + }; + + // listeners for different browsers + if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', init, false); + } + if (ua.ie) { + (function () { + try { + // throws errors until after ondocumentready + document.documentElement.doScroll('left'); + } + catch (e) { + setTimeout(arguments.callee, 50); + return; + } + // no errors, fire + init(); + })(); + // trying to always fire before onload + document.onreadystatechange = function () { + if (document.readyState === 'complete') { + document.onreadystatechange = null; + init(); + } + }; + } + if (ua.webkit && document.readyState) { + (function () { + if (document.readyState !== 'loading') { + init(); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + window.onload = init; // fallback + + return function (fn) { // add fn to init functions + if (typeof fn === 'function') { + fns[fns.length] = fn; + } + return fn; + }; +}(); + + + +// helper library for parsing css to objects +var cssHelper = function () { + + var regExp = { + BLOCKS: /[^\s{;][^{;]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g, + BLOCKS_INSIDE: /[^\s{][^{]*\{[^{}]*\}/g, + DECLARATIONS: /[a-zA-Z\-]+[^;]*:[^;]+;/g, + RELATIVE_URLS: /url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g, + // strip whitespace and comments, @import is evil + REDUNDANT_COMPONENTS: /(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;)/g, + REDUNDANT_WHITESPACE: /\s*(,|:|;|\{|\})\s*/g, + WHITESPACE_IN_PARENTHESES: /\(\s*(\S*)\s*\)/g, + MORE_WHITESPACE: /\s{2,}/g, + FINAL_SEMICOLONS: /;\}/g, + NOT_WHITESPACE: /\S+/g + }; + + var parsed, parsing = false; + + var waiting = []; + var wait = function (fn) { + if (typeof fn === 'function') { + waiting[waiting.length] = fn; + } + }; + var ready = function () { + for (var i = 0; i < waiting.length; i++) { + waiting[i](parsed); + } + }; + var events = {}; + var broadcast = function (n, v) { + if (events[n]) { + var listeners = events[n].listeners; + if (listeners) { + for (var i = 0; i < listeners.length; i++) { + listeners[i](v); + } + } + } + }; + + var requestText = function (url, fnSuccess, fnFailure) { + if (ua.ie && !window.XMLHttpRequest) { + window.XMLHttpRequest = function () { + return new ActiveXObject('Microsoft.XMLHTTP'); + }; + } + if (!XMLHttpRequest) { + return ''; + } + var r = new XMLHttpRequest(); + try { + r.open('get', url, true); + r.setRequestHeader('X_REQUESTED_WITH', 'XMLHttpRequest'); + } + catch (e) { + fnFailure(); + return; + } + var done = false; + setTimeout(function () { + done = true; + }, 5000); + document.documentElement.style.cursor = 'progress'; + r.onreadystatechange = function () { + if (r.readyState === 4 && !done) { + if (!r.status && location.protocol === 'file:' || + (r.status >= 200 && r.status < 300) || + r.status === 304 || + navigator.userAgent.indexOf('Safari') > -1 && typeof r.status === 'undefined') { + fnSuccess(r.responseText); + } + else { + fnFailure(); + } + document.documentElement.style.cursor = ''; + r = null; // avoid memory leaks + } + }; + r.send(''); + }; + + var sanitize = function (text) { + text = text.replace(regExp.REDUNDANT_COMPONENTS, ''); + text = text.replace(regExp.REDUNDANT_WHITESPACE, '$1'); + text = text.replace(regExp.WHITESPACE_IN_PARENTHESES, '($1)'); + text = text.replace(regExp.MORE_WHITESPACE, ' '); + text = text.replace(regExp.FINAL_SEMICOLONS, '}'); // optional final semicolons + return text; + }; + + var objects = { + stylesheet: function (el) { + var o = {}; + var amqs = [], mqls = [], rs = [], rsw = []; + var s = el.cssHelperText; + + // add attribute media queries + var attr = el.getAttribute('media'); + if (attr) { + var qts = attr.toLowerCase().split(',') + } + else { + var qts = ['all'] // imply 'all' + } + for (var i = 0; i < qts.length; i++) { + amqs[amqs.length] = objects.mediaQuery(qts[i], o); + } + + // add media query lists and rules (top down order) + var blocks = s.match(regExp.BLOCKS); // @charset is not a block + if (blocks !== null) { + for (var i = 0; i < blocks.length; i++) { + if (blocks[i].substring(0, 7) === '@media ') { // media query (list) + var mql = objects.mediaQueryList(blocks[i], o); + rs = rs.concat(mql.getRules()); + mqls[mqls.length] = mql; + } + else { // regular rule set, page context (@page) or font description (@font-face) + rs[rs.length] = rsw[rsw.length] = objects.rule(blocks[i], o, null); + } + } + } + + o.element = el; + o.getCssText = function () { + return s; + }; + o.getAttrMediaQueries = function () { + return amqs; + }; + o.getMediaQueryLists = function () { + return mqls; + }; + o.getRules = function () { + return rs; + }; + o.getRulesWithoutMQ = function () { + return rsw; + }; + return o; + }, + + mediaQueryList: function (s, stsh) { + var o = {}; + var idx = s.indexOf('{'); + var lt = s.substring(0, idx); + s = s.substring(idx + 1, s.length - 1); + var mqs = [], rs = []; + + // add media queries + var qts = lt.toLowerCase().substring(7).split(','); + for (var i = 0; i < qts.length; i++) { // parse each media query + mqs[mqs.length] = objects.mediaQuery(qts[i], o); + } + + // add rule sets + var rts = s.match(regExp.BLOCKS_INSIDE); + if (rts !== null) { + for (i = 0; i < rts.length; i++) { + rs[rs.length] = objects.rule(rts[i], stsh, o); + } + } + + o.type = 'mediaQueryList'; + o.getMediaQueries = function () { + return mqs; + }; + o.getRules = function () { + return rs; + }; + o.getListText = function () { + return lt; + }; + o.getCssText = function () { + return s; + }; + return o; + }, + + mediaQuery: function (s, listOrSheet) { + s = s || ''; + var mql, stsh; + if (listOrSheet.type === 'mediaQueryList') { + mql = listOrSheet; + } + else { + stsh = listOrSheet; + } + var not = false, type; + var expr = []; + var valid = true; + var tokens = s.match(regExp.NOT_WHITESPACE); + + + + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (!type && (token === 'not' || token === 'only')) { // 'not' and 'only' keywords + // keyword 'only' does nothing, as if it was not present + if (token === 'not') { + not = true; + } + } + else if (!type) { // media type + type = token; + } + else if (token.charAt(0) === '(') { // media feature expression + var pair = token.substring(1, token.length - 1).split(':'); + expr[expr.length] = { + mediaFeature: pair[0], + value: pair[1] || null + }; + } + } + + return { + getQueryText: function () { + return s; + }, + getAttrStyleSheet: function () { + return stsh || null; + }, + getList: function () { + return mql || null; + }, + getValid: function () { + return valid; + }, + getNot: function () { + return not; + }, + getMediaType: function () { + return type; + }, + getExpressions: function () { + return expr; + } + }; + }, + + rule: function (s, stsh, mql) { + var o = {}; + var idx = s.indexOf('{'); + var st = s.substring(0, idx); + var ss = st.split(','); + var ds = []; + var dts = s.substring(idx + 1, s.length - 1).split(';'); + for (var i = 0; i < dts.length; i++) { + ds[ds.length] = objects.declaration(dts[i], o); + } + + o.getStylesheet = function () { + return stsh || null; + }; + o.getMediaQueryList = function () { + return mql || null; + }; + o.getSelectors = function () { + return ss; + }; + o.getSelectorText = function () { + return st; + }; + o.getDeclarations = function () { + return ds; + }; + o.getPropertyValue = function (n) { + for (var i = 0; i < ds.length; i++) { + if (ds[i].getProperty() === n) { + return ds[i].getValue(); + } + } + return null; + }; + return o; + }, + + declaration: function (s, r) { + var idx = s.indexOf(':'); + var p = s.substring(0, idx); + var v = s.substring(idx + 1); + return { + getRule: function () { + return r || null; + }, + getProperty: function () { + return p; + }, + getValue: function () { + return v; + } + }; + } + }; + + var parseText = function (el) { + if (typeof el.cssHelperText !== 'string') { + return; + } + var o = { + stylesheet: null, + mediaQueryLists: [], + rules: [], + selectors: {}, + declarations: [], + properties: {} + }; + + // build stylesheet object + var stsh = o.stylesheet = objects.stylesheet(el); + + // collect media query lists + var mqls = o.mediaQueryLists = stsh.getMediaQueryLists(); + + // collect all rules + var ors = o.rules = stsh.getRules(); + + // collect all selectors + var oss = o.selectors; + var collectSelectors = function (r) { + var ss = r.getSelectors(); + for (var i = 0; i < ss.length; i++) { + var n = ss[i]; + if (!oss[n]) { + oss[n] = []; + } + oss[n][oss[n].length] = r; + } + }; + for (var i = 0; i < ors.length; i++) { + collectSelectors(ors[i]); + } + + // collect all declarations + var ods = o.declarations; + for (i = 0; i < ors.length; i++) { + ods = o.declarations = ods.concat(ors[i].getDeclarations()); + } + + // collect all properties + var ops = o.properties; + for (i = 0; i < ods.length; i++) { + var n = ods[i].getProperty(); + if (!ops[n]) { + ops[n] = []; + } + ops[n][ops[n].length] = ods[i]; + } + + el.cssHelperParsed = o; + parsed[parsed.length] = el; + return o; + }; + + var parseEmbedded = function (el, s) { + return; + // This function doesn't work because of a bug in IE, where innerHTML gives us parsed css instead of raw literal. + el.cssHelperText = sanitize(s || el.innerHTML); + return parseText(el); + }; + + var parse = function () { + parsing = true; + parsed = []; + var linked = []; + var finish = function () { + for (var i = 0; i < linked.length; i++) { + parseText(linked[i]); + } + var styles = document.getElementsByTagName('style'); + for (i = 0; i < styles.length; i++) { + parseEmbedded(styles[i]); + } + parsing = false; + ready(); + }; + var links = document.getElementsByTagName('link'); + for (var i = 0; i < links.length; i++) { + var link = links[i]; + if (link.getAttribute('rel').indexOf('style') > -1 && link.href && link.href.length !== 0 && !link.disabled) { + linked[linked.length] = link; + } + } + if (linked.length > 0) { + var c = 0; + var checkForFinish = function () { + c++; + if (c === linked.length) { // parse in right order, so after last link is read + finish(); + } + }; + var processLink = function (link) { + var href = link.href; + requestText(href, function (text) { + // fix url's + text = sanitize(text).replace(regExp.RELATIVE_URLS, 'url(' + href.substring(0, href.lastIndexOf('/')) + '/$1)'); + link.cssHelperText = text; + checkForFinish(); + }, checkForFinish); + }; + for (i = 0; i < linked.length; i++) { + processLink(linked[i]); + } + } + else { + finish(); + } + }; + + var types = { + stylesheets: 'array', + mediaQueryLists: 'array', + rules: 'array', + selectors: 'object', + declarations: 'array', + properties: 'object' + }; + + var collections = { + stylesheets: null, + mediaQueryLists: null, + rules: null, + selectors: null, + declarations: null, + properties: null + }; + + var addToCollection = function (name, v) { + if (collections[name] !== null) { + if (types[name] === 'array') { + return (collections[name] = collections[name].concat(v)); + } + else { + var c = collections[name]; + for (var n in v) { + if (v.hasOwnProperty(n)) { + if (!c[n]) { + c[n] = v[n]; + } + else { + c[n] = c[n].concat(v[n]); + } + } + } + return c; + } + } + }; + + var collect = function (name) { + collections[name] = (types[name] === 'array') ? [] : {}; + for (var i = 0; i < parsed.length; i++) { + var pname = name === 'stylesheets' ? 'stylesheet' : name; // the exception + addToCollection(name, parsed[i].cssHelperParsed[pname]); + } + return collections[name]; + }; + + // viewport size + var getViewportSize = function (d) { + if (typeof window.innerWidth != 'undefined') { + return window['inner' + d]; + } + else if (typeof document.documentElement !== 'undefined' + && typeof document.documentElement.clientWidth !== 'undefined' + && document.documentElement.clientWidth != 0) { + return document.documentElement['client' + d]; + } + }; + + // public static functions + return { + addStyle: function (s, mediaTypes, process) { + var el = document.createElement('style'); + el.setAttribute('type', 'text/css'); + if (mediaTypes && mediaTypes.length > 0) { + el.setAttribute('media', mediaTypes.join(',')); + } + document.getElementsByTagName('head')[0].appendChild(el); + if (el.styleSheet) { // IE + el.styleSheet.cssText = s; + } + else { + el.appendChild(document.createTextNode(s)); + } + el.addedWithCssHelper = true; + if (typeof process === 'undefined' || process === true) { + cssHelper.parsed(function (parsed) { + var o = parseEmbedded(el, s); + for (var n in o) { + if (o.hasOwnProperty(n)) { + addToCollection(n, o[n]); + } + } + broadcast('newStyleParsed', el); + }); + } + else { + el.parsingDisallowed = true; + } + return el; + }, + + removeStyle: function (el) { + return el.parentNode.removeChild(el); + }, + + parsed: function (fn) { + if (parsing) { + wait(fn); + } + else { + if (typeof parsed !== 'undefined') { + if (typeof fn === 'function') { + fn(parsed); + } + } + else { + wait(fn); + parse(); + } + } + }, + + stylesheets: function (fn) { + cssHelper.parsed(function (parsed) { + fn(collections.stylesheets || collect('stylesheets')); + }); + }, + + mediaQueryLists: function (fn) { + cssHelper.parsed(function (parsed) { + fn(collections.mediaQueryLists || collect('mediaQueryLists')); + }); + }, + + rules: function (fn) { + cssHelper.parsed(function (parsed) { + fn(collections.rules || collect('rules')); + }); + }, + + selectors: function (fn) { + cssHelper.parsed(function (parsed) { + fn(collections.selectors || collect('selectors')); + }); + }, + + declarations: function (fn) { + cssHelper.parsed(function (parsed) { + fn(collections.declarations || collect('declarations')); + }); + }, + + properties: function (fn) { + cssHelper.parsed(function (parsed) { + fn(collections.properties || collect('properties')); + }); + }, + + broadcast: broadcast, + + addListener: function (n, fn) { // in case n is 'styleadd': added function is called everytime style is added and parsed + if (typeof fn === 'function') { + if (!events[n]) { + events[n] = { + listeners: [] + }; + } + events[n].listeners[events[n].listeners.length] = fn; + } + }, + + removeListener: function (n, fn) { + if (typeof fn === 'function' && events[n]) { + var ls = events[n].listeners; + for (var i = 0; i < ls.length; i++) { + if (ls[i] === fn) { + ls.splice(i, 1); + i -= 1; + } + } + } + }, + + getViewportWidth: function () { + return getViewportSize('Width'); + }, + + getViewportHeight: function () { + return getViewportSize('Height'); + } + }; +}(); + + + +// function to test and apply parsed media queries against browser capabilities +domReady(function enableCssMediaQueries() { + var meter; + + var regExp = { + LENGTH_UNIT: /[0-9]+(em|ex|px|in|cm|mm|pt|pc)$/, + RESOLUTION_UNIT: /[0-9]+(dpi|dpcm)$/, + ASPECT_RATIO: /^[0-9]+\/[0-9]+$/, + ABSOLUTE_VALUE: /^[0-9]*(\.[0-9]+)*$/ + }; + + var styles = []; + + var nativeSupport = function () { + // check support for media queries + var id = 'css3-mediaqueries-test'; + var el = document.createElement('div'); + el.id = id; + var style = cssHelper.addStyle('@media all and (width) { #' + id + + ' { width: 1px !important; } }', [], false); // false means don't parse this temp style + document.body.appendChild(el); + var ret = el.offsetWidth === 1; + style.parentNode.removeChild(style); + el.parentNode.removeChild(el); + nativeSupport = function () { + return ret; + }; + return ret; + }; + + var createMeter = function () { // create measuring element + meter = document.createElement('div'); + meter.style.cssText = 'position:absolute;top:-9999em;left:-9999em;' + + 'margin:0;border:none;padding:0;width:1em;font-size:1em;'; // cssText is needed for IE, works for the others + document.body.appendChild(meter); + // meter must have browser default font size of 16px + if (meter.offsetWidth !== 16) { + meter.style.fontSize = 16 / meter.offsetWidth + 'em'; + } + meter.style.width = ''; + }; + + var measure = function (value) { + meter.style.width = value; + var amount = meter.offsetWidth; + meter.style.width = ''; + return amount; + }; + + var testMediaFeature = function (feature, value) { + // non-testable features: monochrome|min-monochrome|max-monochrome|scan|grid + var l = feature.length; + var min = (feature.substring(0, 4) === 'min-'); + var max = (!min && feature.substring(0, 4) === 'max-'); + + if (value !== null) { // determine value type and parse to usable amount + var valueType; + var amount; + if (regExp.LENGTH_UNIT.exec(value)) { + valueType = 'length'; + amount = measure(value); + } + else if (regExp.RESOLUTION_UNIT.exec(value)) { + valueType = 'resolution'; + amount = parseInt(value, 10); + var unit = value.substring((amount + '').length); + } + else if (regExp.ASPECT_RATIO.exec(value)) { + valueType = 'aspect-ratio'; + amount = value.split('/'); + } + else if (regExp.ABSOLUTE_VALUE) { + valueType = 'absolute'; + amount = value; + } + else { + valueType = 'unknown'; + } + } + + var width, height; + if ('device-width' === feature.substring(l - 12, l)) { // screen width + width = screen.width; + if (value !== null) { + if (valueType === 'length') { + return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount)); + } + else { + return false; + } + } + else { // test width without value + return width > 0; + } + } + else if ('device-height' === feature.substring(l - 13, l)) { // screen height + height = screen.height; + if (value !== null) { + if (valueType === 'length') { + return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount)); + } + else { + return false; + } + } + else { // test height without value + return height > 0; + } + } + else if ('width' === feature.substring(l - 5, l)) { // viewport width + width = document.documentElement.clientWidth || document.body.clientWidth; // the latter for IE quirks mode + if (value !== null) { + if (valueType === 'length') { + return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount)); + } + else { + return false; + } + } + else { // test width without value + return width > 0; + } + } + else if ('height' === feature.substring(l - 6, l)) { // viewport height + height = document.documentElement.clientHeight || document.body.clientHeight; // the latter for IE quirks mode + if (value !== null) { + if (valueType === 'length') { + return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount)); + } + else { + return false; + } + } + else { // test height without value + return height > 0; + } + } + else if ('device-aspect-ratio' === feature.substring(l - 19, l)) { // screen aspect ratio + return valueType === 'aspect-ratio' && screen.width * amount[1] === screen.height * amount[0]; + } + else if ('color-index' === feature.substring(l - 11, l)) { // number of colors + var colors = Math.pow(2, screen.colorDepth); + if (value !== null) { + if (valueType === 'absolute') { + return ((min && colors >= amount) || (max && colors < amount) || (!min && !max && colors === amount)); + } + else { + return false; + } + } + else { // test height without value + return colors > 0; + } + } + else if ('color' === feature.substring(l - 5, l)) { // bits per color component + var color = screen.colorDepth; + if (value !== null) { + if (valueType === 'absolute') { + return ((min && color >= amount) || (max && color < amount) || (!min && !max && color === amount)); + } + else { + return false; + } + } + else { // test height without value + return color > 0; + } + } + else if ('resolution' === feature.substring(l - 10, l)) { + var res; + if (unit === 'dpcm') { + res = measure('1cm'); + } + else { + res = measure('1in'); + } + if (value !== null) { + if (valueType === 'resolution') { + return ((min && res >= amount) || (max && res < amount) || (!min && !max && res === amount)); + } + else { + return false; + } + } + else { // test height without value + return res > 0; + } + } + else { + return false; + } + }; + + var testMediaQuery = function (mq) { + var test = mq.getValid(); + var expressions = mq.getExpressions(); + var l = expressions.length; + if (l > 0) { + for (var i = 0; i < l && test; i++) { + test = testMediaFeature(expressions[i].mediaFeature, expressions[i].value); + } + var not = mq.getNot(); + return (test && !not || not && !test); + } + return test; + }; + + var testMediaQueryList = function (mql, ts) { + // ts is null or an array with any media type but 'all'. + var mqs = mql.getMediaQueries(); + var t = {}; + for (var i = 0; i < mqs.length; i++) { + var type = mqs[i].getMediaType(); + if (mqs[i].getExpressions().length === 0) { + continue; + // TODO: Browser check! Assuming old browsers do apply the bare media types, even in a list with media queries. + } + var typeAllowed = true; + if (type !== 'all' && ts && ts.length > 0) { + typeAllowed = false; + for (var j = 0; j < ts.length; j++) { + if (ts[j] === type) { + typeAllowed = true; + } + } + } + if (typeAllowed && testMediaQuery(mqs[i])) { + t[type] = true; + } + } + var s = [], c = 0; + for (var n in t) { + if (t.hasOwnProperty(n)) { + if (c > 0) { + s[c++] = ','; + } + s[c++] = n; + } + } + if (s.length > 0) { + styles[styles.length] = cssHelper.addStyle('@media ' + s.join('') + '{' + mql.getCssText() + '}', ts, false); + } + }; + + var testMediaQueryLists = function (mqls, ts) { + for (var i = 0; i < mqls.length; i++) { + testMediaQueryList(mqls[i], ts); + } + }; + + var testStylesheet = function (stsh) { + var amqs = stsh.getAttrMediaQueries(); + var allPassed = false; + var t = {}; + for (var i = 0; i < amqs.length; i++) { + if (testMediaQuery(amqs[i])) { + t[amqs[i].getMediaType()] = amqs[i].getExpressions().length > 0; + } + } + var ts = [], tswe = []; + for (var n in t) { + if (t.hasOwnProperty(n)) { + ts[ts.length] = n; + if (t[n]) { + tswe[tswe.length] = n + } + if (n === 'all') { + allPassed = true; + } + } + } + if (tswe.length > 0) { // types with query expressions that passed the test + styles[styles.length] = cssHelper.addStyle(stsh.getCssText(), tswe, false); + } + var mqls = stsh.getMediaQueryLists(); + if (allPassed) { + // If 'all' in media attribute passed the test, then test all @media types in linked CSS and create style with those types. + testMediaQueryLists(mqls); + } + else { + // Or else, test only media attribute types that passed the test and also 'all'. + // For positive '@media all', create style with attribute types that passed their test. + testMediaQueryLists(mqls, ts); + } + }; + + var testStylesheets = function (stshs) { + for (var i = 0; i < stshs.length; i++) { + testStylesheet(stshs[i]); + } + if (ua.ie) { + // force repaint in IE + document.documentElement.style.display = 'block'; + setTimeout(function () { + document.documentElement.style.display = ''; + }, 0); + // delay broadcast somewhat for IE + setTimeout(function () { + cssHelper.broadcast('cssMediaQueriesTested'); + }, 100); + } + else { + cssHelper.broadcast('cssMediaQueriesTested'); + } + }; + + var test = function () { + for (var i = 0; i < styles.length; i++) { + cssHelper.removeStyle(styles[i]); + } + styles = []; + cssHelper.stylesheets(testStylesheets); + }; + + var scrollbarWidth = 0; + var checkForResize = function () { + var cvpw = cssHelper.getViewportWidth(); + var cvph = cssHelper.getViewportHeight(); + + // determine scrollbar width in IE, see resizeHandler + if (ua.ie) { + var el = document.createElement('div'); + el.style.position = 'absolute'; + el.style.top = '-9999em'; + el.style.overflow = 'scroll'; + document.body.appendChild(el); + scrollbarWidth = el.offsetWidth - el.clientWidth; + document.body.removeChild(el); + } + + var timer; + var resizeHandler = function () { + var vpw = cssHelper.getViewportWidth(); + var vph = cssHelper.getViewportHeight(); + // check whether vp size has really changed, because IE also triggers resize event when body size changes + // 20px allowance to accomodate short appearance of scrollbars in IE in some cases + if (Math.abs(vpw - cvpw) > scrollbarWidth || Math.abs(vph - cvph) > scrollbarWidth) { + cvpw = vpw; + cvph = vph; + clearTimeout(timer); + timer = setTimeout(function () { + if (!nativeSupport()) { + test(); + } + else { + cssHelper.broadcast('cssMediaQueriesTested'); + } + }, 500); + } + }; + + window.onresize = function () { + var x = window.onresize || function () {}; // save original + return function () { + x(); + resizeHandler(); + }; + }(); + }; + + // prevent jumping of layout by hiding everything before painting <body> + var docEl = document.documentElement; + docEl.style.marginLeft = '-32767px'; + + // make sure it comes back after a while + setTimeout(function () { + docEl.style.marginLeft = ''; + }, 5000); + + return function () { + if (!nativeSupport()) { // if browser doesn't support media queries + cssHelper.addListener('newStyleParsed', function (el) { + testStylesheet(el.cssHelperParsed.stylesheet); + }); + // return visibility after media queries are tested + cssHelper.addListener('cssMediaQueriesTested', function () { + // force repaint in IE by changing width + if (ua.ie) { + docEl.style.width = '1px'; + } + setTimeout(function () { + docEl.style.width = ''; // undo width + docEl.style.marginLeft = ''; // undo hide + }, 0); + // remove this listener to prevent following execution + cssHelper.removeListener('cssMediaQueriesTested', arguments.callee); + }); + createMeter(); + test(); + } + else { + docEl.style.marginLeft = ''; // undo visibility hidden + } + checkForResize(); + }; +}()); + + +// bonus: hotfix for IE6 SP1 (bug KB823727) +try { + document.execCommand('BackgroundImageCache', false, true); +} catch (e) {} |