diff options
Diffstat (limited to 'afm-client/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js')
-rwxr-xr-x | afm-client/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/afm-client/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js b/afm-client/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js new file mode 100755 index 0000000..242af2a --- /dev/null +++ b/afm-client/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js @@ -0,0 +1,347 @@ +/*! + * viewport-units-buggyfill v0.4.1 + * @web: https://github.com/rodneyrehm/viewport-units-buggyfill/ + * @author: Rodney Rehm - http://rodneyrehm.de/en/ + */ + +(function (root, factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like enviroments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.viewportUnitsBuggyfill = factory(); + } +}(this, function () { + 'use strict'; + /*global document, window, location, XMLHttpRequest, XDomainRequest*/ + + var initialized = false; + var options; + var isMobileSafari = /(iPhone|iPod|iPad).+AppleWebKit/i.test(window.navigator.userAgent); + var viewportUnitExpression = /([+-]?[0-9.]+)(vh|vw|vmin|vmax)/g; + var forEach = [].forEach; + var dimensions; + var declarations; + var styleNode; + var isOldInternetExplorer = false; + + // Do not remove the following comment! + // It is a conditional comment used to + // identify old Internet Explorer versions + + /*@cc_on + + @if (@_jscript_version <= 10) + isOldInternetExplorer = true; + @end + + @*/ + + function debounce(func, wait) { + var timeout; + return function() { + var context = this; + var args = arguments; + var callback = function() { + func.apply(context, args); + }; + + clearTimeout(timeout); + timeout = setTimeout(callback, wait); + }; + } + + // from http://stackoverflow.com/questions/326069/how-to-identify-if-a-webpage-is-being-loaded-inside-an-iframe-or-directly-into-t + function inIframe() { + try { + return window.self !== window.top; + } catch (e) { + return true; + } + } + + function initialize(initOptions) { + if (initialized) { + return; + } + + if (initOptions === true) { + initOptions = { + force: true + }; + } + + options = initOptions || {}; + options.isMobileSafari = isMobileSafari; + + if (!options.force && !isMobileSafari && !isOldInternetExplorer && (!options.hacks || !options.hacks.required(options))) { + // this buggyfill only applies to mobile safari + return; + } + + options.hacks && options.hacks.initialize(options); + + initialized = true; + styleNode = document.createElement('style'); + styleNode.id = 'patched-viewport'; + document.head.appendChild(styleNode); + + // Issue #6: Cross Origin Stylesheets are not accessible through CSSOM, + // therefore download and inject them as <style> to circumvent SOP. + importCrossOriginLinks(function() { + var _refresh = debounce(refresh, options.refreshDebounceWait || 100); + // doing a full refresh rather than updateStyles because an orientationchange + // could activate different stylesheets + window.addEventListener('orientationchange', _refresh, true); + // orientationchange might have happened while in a different window + window.addEventListener('pageshow', _refresh, true); + + if (options.force || isOldInternetExplorer || inIframe()) { + window.addEventListener('resize', _refresh, true); + options._listeningToResize = true; + } + + options.hacks && options.hacks.initializeEvents(options, refresh, _refresh); + + refresh(); + }); + } + + function updateStyles() { + styleNode.textContent = getReplacedViewportUnits(); + } + + function refresh() { + if (!initialized) { + return; + } + + findProperties(); + + // iOS Safari will report window.innerWidth and .innerHeight as 0 + // unless a timeout is used here. + // TODO: figure out WHY innerWidth === 0 + setTimeout(function() { + updateStyles(); + }, 1); + } + + function findProperties() { + declarations = []; + forEach.call(document.styleSheets, function(sheet) { + if (sheet.ownerNode.id === 'patched-viewport' || !sheet.cssRules) { + // skip entire sheet because no rules ara present or it's the target-element of the buggyfill + return; + } + + if (sheet.media && sheet.media.mediaText && window.matchMedia && !window.matchMedia(sheet.media.mediaText).matches) { + // skip entire sheet because media attribute doesn't match + return; + } + + forEach.call(sheet.cssRules, findDeclarations); + }); + + return declarations; + } + + function findDeclarations(rule) { + if (rule.type === 7) { + var value = rule.cssText; + viewportUnitExpression.lastIndex = 0; + if (viewportUnitExpression.test(value)) { + // KeyframesRule does not have a CSS-PropertyName + declarations.push([rule, null, value]); + options.hacks && options.hacks.findDeclarations(declarations, rule, null, value); + } + + return; + } + + if (!rule.style) { + if (!rule.cssRules) { + return; + } + + forEach.call(rule.cssRules, function(_rule) { + findDeclarations(_rule); + }); + + return; + } + + forEach.call(rule.style, function(name) { + var value = rule.style.getPropertyValue(name); + viewportUnitExpression.lastIndex = 0; + if (viewportUnitExpression.test(value)) { + declarations.push([rule, name, value]); + options.hacks && options.hacks.findDeclarations(declarations, rule, name, value); + } + }); + } + + function getReplacedViewportUnits() { + dimensions = getViewport(); + + var css = []; + var buffer = []; + var open; + var close; + + declarations.forEach(function(item) { + var _item = overwriteDeclaration.apply(null, item); + var _open = _item.selector.length ? (_item.selector.join(' {\n') + ' {\n') : ''; + var _close = new Array(_item.selector.length + 1).join('\n}'); + + if (!_open || _open !== open) { + if (buffer.length) { + css.push(open + buffer.join('\n') + close); + buffer.length = 0; + } + + if (_open) { + open = _open; + close = _close; + buffer.push(_item.content); + } else { + css.push(_item.content); + open = null; + close = null; + } + + return; + } + + if (_open && !open) { + open = _open; + close = _close; + } + + buffer.push(_item.content); + }); + + if (buffer.length) { + css.push(open + buffer.join('\n') + close); + } + + return css.join('\n\n'); + } + + function overwriteDeclaration(rule, name, value) { + var _value = value.replace(viewportUnitExpression, replaceValues); + var _selectors = []; + + if (options.hacks) { + _value = options.hacks.overwriteDeclaration(rule, name, _value); + } + + if (name) { + // skipping KeyframesRule + _selectors.push(rule.selectorText); + _value = name + ': ' + _value + ';'; + } + + var _rule = rule.parentRule; + while (_rule) { + _selectors.unshift('@media ' + _rule.media.mediaText); + _rule = _rule.parentRule; + } + + return { + selector: _selectors, + content: _value + }; + } + + function replaceValues(match, number, unit) { + var _base = dimensions[unit]; + var _number = parseFloat(number) / 100; + return (_number * _base) + 'px'; + } + + function getViewport() { + var vh = window.innerHeight; + var vw = window.innerWidth; + + return { + vh: vh, + vw: vw, + vmax: Math.max(vw, vh), + vmin: Math.min(vw, vh) + }; + } + + function importCrossOriginLinks(next) { + var _waiting = 0; + var decrease = function() { + _waiting--; + if (!_waiting) { + next(); + } + }; + + forEach.call(document.styleSheets, function(sheet) { + if (!sheet.href || origin(sheet.href) === origin(location.href)) { + // skip <style> and <link> from same origin + return; + } + + _waiting++; + convertLinkToStyle(sheet.ownerNode, decrease); + }); + + if (!_waiting) { + next(); + } + } + + function origin(url) { + return url.slice(0, url.indexOf('/', url.indexOf('://') + 3)); + } + + function convertLinkToStyle(link, next) { + getCors(link.href, function() { + var style = document.createElement('style'); + style.media = link.media; + style.setAttribute('data-href', link.href); + style.textContent = this.responseText; + link.parentNode.replaceChild(style, link); + next(); + }, next); + } + + function getCors(url, success, error) { + var xhr = new XMLHttpRequest(); + if ('withCredentials' in xhr) { + // XHR for Chrome/Firefox/Opera/Safari. + xhr.open('GET', url, true); + } else if (typeof XDomainRequest !== 'undefined') { + // XDomainRequest for IE. + xhr = new XDomainRequest(); + xhr.open('GET', url); + } else { + throw new Error('cross-domain XHR not supported'); + } + + xhr.onload = success; + xhr.onerror = error; + xhr.send(); + return xhr; + } + + return { + version: '0.4.1', + findProperties: findProperties, + getCss: getReplacedViewportUnits, + init: initialize, + refresh: refresh + }; + +})); |