grunt-modernizr
Advanced tools
Comparing version 0.6.0 to 0.6.1
/* Modernizr (Custom Build) | MIT & BSD | ||
* Build: http://modernizr.com/download/#-shiv-load-cssclasses-cssclassprefix:prefixed!-smil-input-cors-file_api | ||
* Build: http://modernizr.com/download/#-shiv-load-cssclasses-canvastext-csstransforms3d-flexbox-cssgradients-opacity-indexedDB-backgroundsize-borderimage-borderradius-boxshadow-cssanimations-csscolumns-cssreflections-csstransitions-flexboxlegacy-prefixed-csstransforms-mq-hashchange-draganddrop-generatedcontent-svg-inlinesvg-smil-svgclippaths-input-inputtypes-touch-fontface-websockets-applicationcache-audio-canvas-geolocation-history-hsla-localstorage-multiplebgs-postmessage-sessionstorage-textshadow-rgba-video-webgl-websqldatabase-webworkers-testallprops-testbundle-respond-contextmenu-emoji-json-indexeddb-script_defer | ||
*/ | ||
; | ||
window.Modernizr = (function( window, document, undefined ) { | ||
var version = '2.8.3', | ||
Modernizr = {}, | ||
enableClasses = true, | ||
docElement = document.documentElement, | ||
mod = 'modernizr', | ||
modElem = document.createElement(mod), | ||
mStyle = modElem.style, | ||
inputElem = document.createElement('input') , | ||
toString = {}.toString, | ||
ns = {'svg': 'http://www.w3.org/2000/svg'}, | ||
tests = {}, | ||
inputs = {}, | ||
attrs = {}, | ||
classes = [], | ||
slice = classes.slice, | ||
featureName, | ||
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp; | ||
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) { | ||
hasOwnProp = function (object, property) { | ||
return _hasOwnProperty.call(object, property); | ||
}; | ||
} | ||
else { | ||
hasOwnProp = function (object, property) { | ||
return ((property in object) && is(object.constructor.prototype[property], 'undefined')); | ||
}; | ||
} | ||
if (!Function.prototype.bind) { | ||
Function.prototype.bind = function bind(that) { | ||
var target = this; | ||
if (typeof target != "function") { | ||
throw new TypeError(); | ||
} | ||
var args = slice.call(arguments, 1), | ||
bound = function () { | ||
if (this instanceof bound) { | ||
var F = function(){}; | ||
F.prototype = target.prototype; | ||
var self = new F(); | ||
var result = target.apply( | ||
self, | ||
args.concat(slice.call(arguments)) | ||
); | ||
if (Object(result) === result) { | ||
return result; | ||
} | ||
return self; | ||
} else { | ||
return target.apply( | ||
that, | ||
args.concat(slice.call(arguments)) | ||
); | ||
} | ||
}; | ||
return bound; | ||
}; | ||
} | ||
function setCss( str ) { | ||
mStyle.cssText = str; | ||
} | ||
function setCssAll( str1, str2 ) { | ||
return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); | ||
} | ||
function is( obj, type ) { | ||
return typeof obj === type; | ||
} | ||
function contains( str, substr ) { | ||
return !!~('' + str).indexOf(substr); | ||
} | ||
function testDOMProps( props, obj, elem ) { | ||
for ( var i in props ) { | ||
var item = obj[props[i]]; | ||
if ( item !== undefined) { | ||
if (elem === false) return props[i]; | ||
if (is(item, 'function')){ | ||
return item.bind(elem || obj); | ||
} | ||
return item; | ||
} | ||
} | ||
return false; | ||
} | ||
tests['smil'] = function() { | ||
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate'))); | ||
}; | ||
function webforms() { | ||
Modernizr['input'] = (function( props ) { | ||
for ( var i = 0, len = props.length; i < len; i++ ) { | ||
attrs[ props[i] ] = !!(props[i] in inputElem); | ||
} | ||
if (attrs.list){ | ||
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement); | ||
} | ||
return attrs; | ||
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ')); | ||
} | ||
for ( var feature in tests ) { | ||
if ( hasOwnProp(tests, feature) ) { | ||
featureName = feature.toLowerCase(); | ||
Modernizr[featureName] = tests[feature](); | ||
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); | ||
} | ||
} | ||
Modernizr.input || webforms(); | ||
Modernizr.addTest = function ( feature, test ) { | ||
if ( typeof feature == 'object' ) { | ||
for ( var key in feature ) { | ||
if ( hasOwnProp( feature, key ) ) { | ||
Modernizr.addTest( key, feature[ key ] ); | ||
} | ||
} | ||
} else { | ||
feature = feature.toLowerCase(); | ||
if ( Modernizr[feature] !== undefined ) { | ||
return Modernizr; | ||
} | ||
test = typeof test == 'function' ? test() : test; | ||
if (typeof enableClasses !== "undefined" && enableClasses) { | ||
docElement.className+=" prefixed-" + (test ? '' : 'no-') + feature; | ||
} | ||
Modernizr[feature] = test; | ||
} | ||
return Modernizr; | ||
}; | ||
setCss(''); | ||
modElem = inputElem = null; | ||
;(function(window, document) { | ||
var version = '3.7.0'; | ||
var options = window.html5 || {}; | ||
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; | ||
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; | ||
var supportsHtml5Styles; | ||
var expando = '_html5shiv'; | ||
var expanID = 0; | ||
var expandoData = {}; | ||
var supportsUnknownElements; | ||
(function() { | ||
try { | ||
var a = document.createElement('a'); | ||
a.innerHTML = '<xyz></xyz>'; | ||
supportsHtml5Styles = ('hidden' in a); | ||
supportsUnknownElements = a.childNodes.length == 1 || (function() { | ||
(document.createElement)('a'); | ||
var frag = document.createDocumentFragment(); | ||
return ( | ||
typeof frag.cloneNode == 'undefined' || | ||
typeof frag.createDocumentFragment == 'undefined' || | ||
typeof frag.createElement == 'undefined' | ||
); | ||
}()); | ||
} catch(e) { | ||
supportsHtml5Styles = true; | ||
supportsUnknownElements = true; | ||
} | ||
}()); | ||
function addStyleSheet(ownerDocument, cssText) { | ||
var p = ownerDocument.createElement('p'), | ||
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; | ||
p.innerHTML = 'x<style>' + cssText + '</style>'; | ||
return parent.insertBefore(p.lastChild, parent.firstChild); | ||
} | ||
function getElements() { | ||
var elements = html5.elements; | ||
return typeof elements == 'string' ? elements.split(' ') : elements; | ||
} | ||
function getExpandoData(ownerDocument) { | ||
var data = expandoData[ownerDocument[expando]]; | ||
if (!data) { | ||
data = {}; | ||
expanID++; | ||
ownerDocument[expando] = expanID; | ||
expandoData[expanID] = data; | ||
} | ||
return data; | ||
} | ||
function createElement(nodeName, ownerDocument, data){ | ||
if (!ownerDocument) { | ||
ownerDocument = document; | ||
} | ||
if(supportsUnknownElements){ | ||
return ownerDocument.createElement(nodeName); | ||
} | ||
if (!data) { | ||
data = getExpandoData(ownerDocument); | ||
} | ||
var node; | ||
if (data.cache[nodeName]) { | ||
node = data.cache[nodeName].cloneNode(); | ||
} else if (saveClones.test(nodeName)) { | ||
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); | ||
} else { | ||
node = data.createElem(nodeName); | ||
} | ||
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; | ||
} | ||
function createDocumentFragment(ownerDocument, data){ | ||
if (!ownerDocument) { | ||
ownerDocument = document; | ||
} | ||
if(supportsUnknownElements){ | ||
return ownerDocument.createDocumentFragment(); | ||
} | ||
data = data || getExpandoData(ownerDocument); | ||
var clone = data.frag.cloneNode(), | ||
i = 0, | ||
elems = getElements(), | ||
l = elems.length; | ||
for(;i<l;i++){ | ||
clone.createElement(elems[i]); | ||
} | ||
return clone; | ||
} | ||
function shivMethods(ownerDocument, data) { | ||
if (!data.cache) { | ||
data.cache = {}; | ||
data.createElem = ownerDocument.createElement; | ||
data.createFrag = ownerDocument.createDocumentFragment; | ||
data.frag = data.createFrag(); | ||
} | ||
ownerDocument.createElement = function(nodeName) { | ||
if (!html5.shivMethods) { | ||
return data.createElem(nodeName); | ||
} | ||
return createElement(nodeName, ownerDocument, data); | ||
}; | ||
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + | ||
'var n=f.cloneNode(),c=n.createElement;' + | ||
'h.shivMethods&&(' + | ||
getElements().join().replace(/[\w\-]+/g, function(nodeName) { | ||
data.createElem(nodeName); | ||
data.frag.createElement(nodeName); | ||
return 'c("' + nodeName + '")'; | ||
}) + | ||
');return n}' | ||
)(html5, data.frag); | ||
} | ||
function shivDocument(ownerDocument) { | ||
if (!ownerDocument) { | ||
ownerDocument = document; | ||
} | ||
var data = getExpandoData(ownerDocument); | ||
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { | ||
data.hasCSS = !!addStyleSheet(ownerDocument, | ||
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' + | ||
'mark{background:#FF0;color:#000}' + | ||
'template{display:none}' | ||
); | ||
} | ||
if (!supportsUnknownElements) { | ||
shivMethods(ownerDocument, data); | ||
} | ||
return ownerDocument; | ||
} | ||
var html5 = { | ||
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video', | ||
'version': version, | ||
'shivCSS': (options.shivCSS !== false), | ||
'supportsUnknownElements': supportsUnknownElements, | ||
'shivMethods': (options.shivMethods !== false), | ||
'type': 'default', | ||
'shivDocument': shivDocument, | ||
createElement: createElement, | ||
createDocumentFragment: createDocumentFragment | ||
}; | ||
window.html5 = html5; | ||
shivDocument(document); | ||
}(this, document)); | ||
Modernizr._version = version; | ||
docElement.className = docElement.className.replace(/(^|\s)prefixed-no-js(\s|$)/, '$1$2') + | ||
(enableClasses ? ' prefixed-js prefixed-'+classes.join(' prefixed-') : ''); | ||
return Modernizr; | ||
})(this, this.document); | ||
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document); | ||
Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));}; | ||
Modernizr.addTest('cors', !!(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest())); | ||
Modernizr.addTest('filereader', function () { | ||
return !!(window.File && window.FileList && window.FileReader); | ||
}); | ||
; | ||
;window.Modernizr=function(e,t,n){function A(e){f.cssText=e}function O(e,t){return A(p.join(e+";")+(t||""))}function M(e,t){return typeof e===t}function _(e,t){return!!~(""+e).indexOf(t)}function D(e,t){for(var r in e){var i=e[r];if(!_(i,"-")&&f[i]!==n)return t=="pfx"?i:!0}return!1}function P(e,t,r){for(var i in e){var s=t[e[i]];if(s!==n)return r===!1?e[i]:M(s,"function")?s.bind(r||t):s}return!1}function H(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),i=(e+" "+v.join(r+" ")+r).split(" ");return M(t,"string")||M(t,"undefined")?D(i,t):(i=(e+" "+m.join(r+" ")+r).split(" "),P(i,t,n))}function B(){i.input=function(n){for(var r=0,i=n.length;r<i;r++)w[n[r]]=n[r]in l;return w.list&&(w.list=!!t.createElement("datalist")&&!!e.HTMLDataListElement),w}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),i.inputtypes=function(e){for(var r=0,i,s,u,a=e.length;r<a;r++)l.setAttribute("type",s=e[r]),i=l.type!=="text",i&&(l.value=c,l.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(s)&&l.style.WebkitAppearance!==n?(o.appendChild(l),u=t.defaultView,i=u.getComputedStyle&&u.getComputedStyle(l,null).WebkitAppearance!=="textfield"&&l.offsetHeight!==0,o.removeChild(l)):/^(search|tel)$/.test(s)||(/^(url|email)$/.test(s)?i=l.checkValidity&&l.checkValidity()===!1:i=l.value!=c)),b[e[r]]=!!i;return b}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var r="2.8.3",i={},s=!0,o=t.documentElement,u="modernizr",a=t.createElement(u),f=a.style,l=t.createElement("input"),c=":)",h={}.toString,p=" -webkit- -moz- -o- -ms- ".split(" "),d="Webkit Moz O ms",v=d.split(" "),m=d.toLowerCase().split(" "),g={svg:"http://www.w3.org/2000/svg"},y={},b={},w={},E=[],S=E.slice,x,T=function(e,n,r,i){var s,a,f,l,c=t.createElement("div"),h=t.body,p=h||t.createElement("body");if(parseInt(r,10))while(r--)f=t.createElement("div"),f.id=i?i[r]:u+(r+1),c.appendChild(f);return s=["­",'<style id="s',u,'">',e,"</style>"].join(""),c.id=u,(h?c:p).innerHTML+=s,p.appendChild(c),h||(p.style.background="",p.style.overflow="hidden",l=o.style.overflow,o.style.overflow="hidden",o.appendChild(p)),a=n(c,e),h?c.parentNode.removeChild(c):(p.parentNode.removeChild(p),o.style.overflow=l),!!a},N=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return T("@media "+t+" { #"+u+" { position: absolute; } }",function(t){r=(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle)["position"]=="absolute"}),r},C=function(){function r(r,i){i=i||t.createElement(e[r]||"div"),r="on"+r;var s=r in i;return s||(i.setAttribute||(i=t.createElement("div")),i.setAttribute&&i.removeAttribute&&(i.setAttribute(r,""),s=M(i[r],"function"),M(i[r],"undefined")||(i[r]=n),i.removeAttribute(r))),i=null,s}var e={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return r}(),k={}.hasOwnProperty,L;!M(k,"undefined")&&!M(k.call,"undefined")?L=function(e,t){return k.call(e,t)}:L=function(e,t){return t in e&&M(e.constructor.prototype[t],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError;var r=S.call(arguments,1),i=function(){if(this instanceof i){var e=function(){};e.prototype=n.prototype;var s=new e,o=n.apply(s,r.concat(S.call(arguments)));return Object(o)===o?o:s}return n.apply(t,r.concat(S.call(arguments)))};return i}),y.flexbox=function(){return H("flexWrap")},y.flexboxlegacy=function(){return H("boxDirection")},y.canvas=function(){var e=t.createElement("canvas");return!!e.getContext&&!!e.getContext("2d")},y.canvastext=function(){return!!i.canvas&&!!M(t.createElement("canvas").getContext("2d").fillText,"function")},y.webgl=function(){return!!e.WebGLRenderingContext},y.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:T(["@media (",p.join("touch-enabled),("),u,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=e.offsetTop===9}),n},y.geolocation=function(){return"geolocation"in navigator},y.postmessage=function(){return!!e.postMessage},y.websqldatabase=function(){return!!e.openDatabase},y.indexedDB=function(){return!!H("indexedDB",e)},y.hashchange=function(){return C("hashchange",e)&&(t.documentMode===n||t.documentMode>7)},y.history=function(){return!!e.history&&!!history.pushState},y.draganddrop=function(){var e=t.createElement("div");return"draggable"in e||"ondragstart"in e&&"ondrop"in e},y.websockets=function(){return"WebSocket"in e||"MozWebSocket"in e},y.rgba=function(){return A("background-color:rgba(150,255,150,.5)"),_(f.backgroundColor,"rgba")},y.hsla=function(){return A("background-color:hsla(120,40%,100%,.5)"),_(f.backgroundColor,"rgba")||_(f.backgroundColor,"hsla")},y.multiplebgs=function(){return A("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(f.background)},y.backgroundsize=function(){return H("backgroundSize")},y.borderimage=function(){return H("borderImage")},y.borderradius=function(){return H("borderRadius")},y.boxshadow=function(){return H("boxShadow")},y.textshadow=function(){return t.createElement("div").style.textShadow===""},y.opacity=function(){return O("opacity:.55"),/^0.55$/.test(f.opacity)},y.cssanimations=function(){return H("animationName")},y.csscolumns=function(){return H("columnCount")},y.cssgradients=function(){var e="background-image:",t="gradient(linear,left top,right bottom,from(#9f9),to(white));",n="linear-gradient(left top,#9f9, white);";return A((e+"-webkit- ".split(" ").join(t+e)+p.join(n+e)).slice(0,-e.length)),_(f.backgroundImage,"gradient")},y.cssreflections=function(){return H("boxReflect")},y.csstransforms=function(){return!!H("transform")},y.csstransforms3d=function(){var e=!!H("perspective");return e&&"webkitPerspective"in o.style&&T("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t,n){e=t.offsetLeft===9&&t.offsetHeight===3}),e},y.csstransitions=function(){return H("transition")},y.fontface=function(){var e;return T('@font-face {font-family:"font";src:url("https://")}',function(n,r){var i=t.getElementById("smodernizr"),s=i.sheet||i.styleSheet,o=s?s.cssRules&&s.cssRules[0]?s.cssRules[0].cssText:s.cssText||"":"";e=/src/i.test(o)&&o.indexOf(r.split(" ")[0])===0}),e},y.generatedcontent=function(){var e;return T(["#",u,"{font:0/0 a}#",u,':after{content:"',c,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){e=t.offsetHeight>=3}),e},y.video=function(){var e=t.createElement("video"),n=!1;try{if(n=!!e.canPlayType)n=new Boolean(n),n.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(r){}return n},y.audio=function(){var e=t.createElement("audio"),n=!1;try{if(n=!!e.canPlayType)n=new Boolean(n),n.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=e.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(r){}return n},y.localstorage=function(){try{return localStorage.setItem(u,u),localStorage.removeItem(u),!0}catch(e){return!1}},y.sessionstorage=function(){try{return sessionStorage.setItem(u,u),sessionStorage.removeItem(u),!0}catch(e){return!1}},y.webworkers=function(){return!!e.Worker},y.applicationcache=function(){return!!e.applicationCache},y.svg=function(){return!!t.createElementNS&&!!t.createElementNS(g.svg,"svg").createSVGRect},y.inlinesvg=function(){var e=t.createElement("div");return e.innerHTML="<svg/>",(e.firstChild&&e.firstChild.namespaceURI)==g.svg},y.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(h.call(t.createElementNS(g.svg,"animate")))},y.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(h.call(t.createElementNS(g.svg,"clipPath")))};for(var j in y)L(y,j)&&(x=j.toLowerCase(),i[x]=y[j](),E.push((i[x]?"":"no-")+x));return i.input||B(),i.addTest=function(e,t){if(typeof e=="object")for(var r in e)L(e,r)&&i.addTest(r,e[r]);else{e=e.toLowerCase();if(i[e]!==n)return i;t=typeof t=="function"?t():t,typeof s!="undefined"&&s&&(o.className+=" "+(t?"":"no-")+e),i[e]=t}return i},A(""),a=l=null,function(e,t){function c(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function h(){var e=y.elements;return typeof e=="string"?e.split(" "):e}function p(e){var t=f[e[u]];return t||(t={},a++,e[u]=a,f[a]=t),t}function d(e,n,r){n||(n=t);if(l)return n.createElement(e);r||(r=p(n));var o;return r.cache[e]?o=r.cache[e].cloneNode():s.test(e)?o=(r.cache[e]=r.createElem(e)).cloneNode():o=r.createElem(e),o.canHaveChildren&&!i.test(e)&&!o.tagUrn?r.frag.appendChild(o):o}function v(e,n){e||(e=t);if(l)return e.createDocumentFragment();n=n||p(e);var r=n.frag.cloneNode(),i=0,s=h(),o=s.length;for(;i<o;i++)r.createElement(s[i]);return r}function m(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?d(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function g(e){e||(e=t);var n=p(e);return y.shivCSS&&!o&&!n.hasCSS&&(n.hasCSS=!!c(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||m(e,n),e}var n="3.7.0",r=e.html5||{},i=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,s=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,o,u="_html5shiv",a=0,f={},l;(function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",o="hidden"in e,l=e.childNodes.length==1||function(){t.createElement("a");var e=t.createDocumentFragment();return typeof e.cloneNode=="undefined"||typeof e.createDocumentFragment=="undefined"||typeof e.createElement=="undefined"}()}catch(n){o=!0,l=!0}})();var y={elements:r.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:n,shivCSS:r.shivCSS!==!1,supportsUnknownElements:l,shivMethods:r.shivMethods!==!1,type:"default",shivDocument:g,createElement:d,createDocumentFragment:v};e.html5=y,g(t)}(this,t),i._version=r,i._prefixes=p,i._domPrefixes=m,i._cssomPrefixes=v,i.mq=N,i.hasEvent=C,i.testProp=function(e){return D([e])},i.testAllProps=H,i.testStyles=T,i.prefixed=function(e,t,n){return t?H(e,t,n):H(e,"pfx")},o.className=o.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(s?" js "+E.join(" "):""),i}(this,this.document),function(e,t,n){function r(e){return"[object Function]"==d.call(e)}function i(e){return"string"==typeof e}function s(){}function o(e){return!e||"loaded"==e||"complete"==e||"uninitialized"==e}function u(){var e=v.shift();m=1,e?e.t?h(function(){("c"==e.t?k.injectCss:k.injectJs)(e.s,0,e.a,e.x,e.e,1)},0):(e(),u()):m=0}function a(e,n,r,i,s,a,f){function l(t){if(!d&&o(c.readyState)&&(w.r=d=1,!m&&u(),c.onload=c.onreadystatechange=null,t)){"img"!=e&&h(function(){b.removeChild(c)},50);for(var r in T[n])T[n].hasOwnProperty(r)&&T[n][r].onload()}}var f=f||k.errorTimeout,c=t.createElement(e),d=0,g=0,w={t:r,s:n,e:s,a:a,x:f};1===T[n]&&(g=1,T[n]=[]),"object"==e?c.data=n:(c.src=n,c.type=e),c.width=c.height="0",c.onerror=c.onload=c.onreadystatechange=function(){l.call(this,g)},v.splice(i,0,w),"img"!=e&&(g||2===T[n]?(b.insertBefore(c,y?null:p),h(l,f)):T[n].push(c))}function f(e,t,n,r,s){return m=0,t=t||"j",i(e)?a("c"==t?E:w,e,t,this.i++,n,r,s):(v.splice(this.i++,0,e),1==v.length&&u()),this}function l(){var e=k;return e.loader={load:f,i:0},e}var c=t.documentElement,h=e.setTimeout,p=t.getElementsByTagName("script")[0],d={}.toString,v=[],m=0,g="MozAppearance"in c.style,y=g&&!!t.createRange().compareNode,b=y?c:p.parentNode,c=e.opera&&"[object Opera]"==d.call(e.opera),c=!!t.attachEvent&&!c,w=g?"object":c?"script":"img",E=c?"script":w,S=Array.isArray||function(e){return"[object Array]"==d.call(e)},x=[],T={},N={timeout:function(e,t){return t.length&&(e.timeout=t[0]),e}},C,k;k=function(e){function t(e){var e=e.split("!"),t=x.length,n=e.pop(),r=e.length,n={url:n,origUrl:n,prefixes:e},i,s,o;for(s=0;s<r;s++)o=e[s].split("="),(i=N[o.shift()])&&(n=i(n,o));for(s=0;s<t;s++)n=x[s](n);return n}function o(e,i,s,o,u){var a=t(e),f=a.autoCallback;a.url.split(".").pop().split("?").shift(),a.bypass||(i&&(i=r(i)?i:i[e]||i[o]||i[e.split("/").pop().split("?")[0]]),a.instead?a.instead(e,i,s,o,u):(T[a.url]?a.noexec=!0:T[a.url]=1,s.load(a.url,a.forceCSS||!a.forceJS&&"css"==a.url.split(".").pop().split("?").shift()?"c":n,a.noexec,a.attrs,a.timeout),(r(i)||r(f))&&s.load(function(){l(),i&&i(a.origUrl,u,o),f&&f(a.origUrl,u,o),T[a.url]=2})))}function u(e,t){function n(e,n){if(e){if(i(e))n||(f=function(){var e=[].slice.call(arguments);l.apply(this,e),c()}),o(e,f,t,0,u);else if(Object(e)===e)for(p in h=function(){var t=0,n;for(n in e)e.hasOwnProperty(n)&&t++;return t}(),e)e.hasOwnProperty(p)&&(!n&&!--h&&(r(f)?f=function(){var e=[].slice.call(arguments);l.apply(this,e),c()}:f[p]=function(e){return function(){var t=[].slice.call(arguments);e&&e.apply(this,t),c()}}(l[p])),o(e[p],f,t,p,u))}else!n&&c()}var u=!!e.test,a=e.load||e.both,f=e.callback||s,l=f,c=e.complete||s,h,p;n(u?e.yep:e.nope,!!a),a&&n(a)}var a,f,c=this.yepnope.loader;if(i(e))o(e,0,c,0);else if(S(e))for(a=0;a<e.length;a++)f=e[a],i(f)?o(f,0,c,0):S(f)?k(f):Object(f)===f&&u(f,c);else Object(e)===e&&u(e,c)},k.addPrefix=function(e,t){N[e]=t},k.addFilter=function(e){x.push(e)},k.errorTimeout=1e4,null==t.readyState&&t.addEventListener&&(t.readyState="loading",t.addEventListener("DOMContentLoaded",C=function(){t.removeEventListener("DOMContentLoaded",C,0),t.readyState="complete"},0)),e.yepnope=l(),e.yepnope.executeStack=u,e.yepnope.injectJs=function(e,n,r,i,a,f){var l=t.createElement("script"),c,d,i=i||k.errorTimeout;l.src=e;for(d in r)l.setAttribute(d,r[d]);n=f?u:n||s,l.onreadystatechange=l.onload=function(){!c&&o(l.readyState)&&(c=1,n(),l.onload=l.onreadystatechange=null)},h(function(){c||(c=1,n(1))},i),a?l.onload():p.parentNode.insertBefore(l,p)},e.yepnope.injectCss=function(e,n,r,i,o,a){var i=t.createElement("link"),f,n=a?u:n||s;i.href=e,i.rel="stylesheet",i.type="text/css";for(f in r)i.setAttribute(f,r[f]);o||(p.parentNode.insertBefore(i,p),h(n,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))}; |
@@ -427,2 +427,6 @@ /* jshint node:true, newcap:false */ | ||
readFile : function (filename) { | ||
return grunt.file.read(path.join(__dirname, filename)); | ||
}, | ||
makeRequests : function (tests) { | ||
@@ -433,11 +437,11 @@ var communityRequests = this.setupCommunityRequests(tests), | ||
if (!_quiet) { | ||
grunt.log.subhead("Downloading source files"); | ||
grunt.log.subhead("Loading source files"); | ||
} | ||
promise.all( | ||
this.xhr(_private.url.domain, _private.paths.modernizr), | ||
this.readFile(_private.files.modernizr), | ||
// Check for special case flags, load conditionally | ||
(config.extra.printshiv) ? this.xhr(_private.url.domain, _private.paths.printshiv) : null, | ||
(config.extra.load) ? this.xhr(_private.url.domain, _private.paths.load) : null | ||
(config.extra.printshiv) ? this.readFile(_private.files.printshiv) : null, | ||
(config.extra.load) ? this.readFile(_private.files.load) : null | ||
).then(function (data) { | ||
@@ -444,0 +448,0 @@ main = data.join(""); |
@@ -9,4 +9,3 @@ (function () { | ||
"url" : { | ||
"github" : "https://github.com/doctyper/grunt-modernizr", | ||
"domain" : "http://modernizr.com", | ||
"github" : "https://github.com/Modernizr/grunt-modernizr", | ||
"raw" : "https://raw.github.com", | ||
@@ -75,8 +74,11 @@ "modulizr" : "https://github.com/Modernizr/modernizr.com/blob/gh-pages/i/js/modulizr.js#L15-157" | ||
"paths" : { | ||
"modernizr" : "downloads/modernizr-latest.js", | ||
"printshiv" : "i/js/html5shiv-printshiv-3.6.js", | ||
"load" : "i/js/modernizr.load.1.5.4.js", | ||
"community" : "Modernizr/Modernizr/87c723720a48254ae37ffd56829e32a96f5c5496/feature-detects/%s.js" | ||
}, | ||
"files" : { | ||
"modernizr" : "build-files/modernizr-latest.js", | ||
"printshiv" : "build-files/html5shiv-printshiv-3.6.js", | ||
"load" : "build-files/modernizr.load.1.5.4.js" | ||
} | ||
}; | ||
}()); |
@@ -1,1406 +0,7 @@ | ||
/*! | ||
* Modernizr v2.8.3 | ||
* www.modernizr.com | ||
* | ||
* Copyright (c) Faruk Ates, Paul Irish, Alex Sexton | ||
* Available under the BSD and MIT licenses: www.modernizr.com/license/ | ||
*/ | ||
/* | ||
* Modernizr tests which native CSS3 and HTML5 features are available in | ||
* the current UA and makes the results available to you in two ways: | ||
* as properties on a global Modernizr object, and as classes on the | ||
* <html> element. This information allows you to progressively enhance | ||
* your pages with a granular level of control over the experience. | ||
* | ||
* Modernizr has an optional (not included) conditional resource loader | ||
* called Modernizr.load(), based on Yepnope.js (yepnopejs.com). | ||
* To get a build that includes Modernizr.load(), as well as choosing | ||
* which tests to include, go to www.modernizr.com/download/ | ||
* | ||
* Authors Faruk Ates, Paul Irish, Alex Sexton | ||
* Contributors Ryan Seddon, Ben Alman | ||
*/ | ||
window.Modernizr = (function( window, document, undefined ) { | ||
var version = '2.8.3', | ||
Modernizr = {}, | ||
/*>>cssclasses*/ | ||
// option for enabling the HTML classes to be added | ||
enableClasses = true, | ||
/*>>cssclasses*/ | ||
docElement = document.documentElement, | ||
/** | ||
* Create our "modernizr" element that we do most feature tests on. | ||
*/ | ||
mod = 'modernizr', | ||
modElem = document.createElement(mod), | ||
mStyle = modElem.style, | ||
/** | ||
* Create the input element for various Web Forms feature tests. | ||
*/ | ||
inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ , | ||
/*>>smile*/ | ||
smile = ':)', | ||
/*>>smile*/ | ||
toString = {}.toString, | ||
// TODO :: make the prefixes more granular | ||
/*>>prefixes*/ | ||
// List of property values to set for css tests. See ticket #21 | ||
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '), | ||
/*>>prefixes*/ | ||
/*>>domprefixes*/ | ||
// Following spec is to expose vendor-specific style properties as: | ||
// elem.style.WebkitBorderRadius | ||
// and the following would be incorrect: | ||
// elem.style.webkitBorderRadius | ||
// Webkit ghosts their properties in lowercase but Opera & Moz do not. | ||
// Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ | ||
// erik.eae.net/archives/2008/03/10/21.48.10/ | ||
// More here: github.com/Modernizr/Modernizr/issues/issue/21 | ||
omPrefixes = 'Webkit Moz O ms', | ||
cssomPrefixes = omPrefixes.split(' '), | ||
domPrefixes = omPrefixes.toLowerCase().split(' '), | ||
/*>>domprefixes*/ | ||
/*>>ns*/ | ||
ns = {'svg': 'http://www.w3.org/2000/svg'}, | ||
/*>>ns*/ | ||
tests = {}, | ||
inputs = {}, | ||
attrs = {}, | ||
classes = [], | ||
slice = classes.slice, | ||
featureName, // used in testing loop | ||
/*>>teststyles*/ | ||
// Inject element with style element and some CSS rules | ||
injectElementWithStyles = function( rule, callback, nodes, testnames ) { | ||
var style, ret, node, docOverflow, | ||
div = document.createElement('div'), | ||
// After page load injecting a fake body doesn't work so check if body exists | ||
body = document.body, | ||
// IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it. | ||
fakeBody = body || document.createElement('body'); | ||
if ( parseInt(nodes, 10) ) { | ||
// In order not to give false positives we create a node for each test | ||
// This also allows the method to scale for unspecified uses | ||
while ( nodes-- ) { | ||
node = document.createElement('div'); | ||
node.id = testnames ? testnames[nodes] : mod + (nodes + 1); | ||
div.appendChild(node); | ||
} | ||
} | ||
// <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed | ||
// when injected with innerHTML. To get around this you need to prepend the 'NoScope' element | ||
// with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements. | ||
// msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx | ||
// Documents served as xml will throw if using ­ so use xml friendly encoded version. See issue #277 | ||
style = ['­','<style id="s', mod, '">', rule, '</style>'].join(''); | ||
div.id = mod; | ||
// IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. | ||
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 | ||
(body ? div : fakeBody).innerHTML += style; | ||
fakeBody.appendChild(div); | ||
if ( !body ) { | ||
//avoid crashing IE8, if background image is used | ||
fakeBody.style.background = ''; | ||
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible | ||
fakeBody.style.overflow = 'hidden'; | ||
docOverflow = docElement.style.overflow; | ||
docElement.style.overflow = 'hidden'; | ||
docElement.appendChild(fakeBody); | ||
} | ||
ret = callback(div, rule); | ||
// If this is done after page load we don't want to remove the body so check if body exists | ||
if ( !body ) { | ||
fakeBody.parentNode.removeChild(fakeBody); | ||
docElement.style.overflow = docOverflow; | ||
} else { | ||
div.parentNode.removeChild(div); | ||
} | ||
return !!ret; | ||
}, | ||
/*>>teststyles*/ | ||
/*>>mq*/ | ||
// adapted from matchMedia polyfill | ||
// by Scott Jehl and Paul Irish | ||
// gist.github.com/786768 | ||
testMediaQuery = function( mq ) { | ||
var matchMedia = window.matchMedia || window.msMatchMedia; | ||
if ( matchMedia ) { | ||
return matchMedia(mq) && matchMedia(mq).matches || false; | ||
} | ||
var bool; | ||
injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) { | ||
bool = (window.getComputedStyle ? | ||
getComputedStyle(node, null) : | ||
node.currentStyle)['position'] == 'absolute'; | ||
}); | ||
return bool; | ||
}, | ||
/*>>mq*/ | ||
/*>>hasevent*/ | ||
// | ||
// isEventSupported determines if a given element supports the given event | ||
// kangax.github.com/iseventsupported/ | ||
// | ||
// The following results are known incorrects: | ||
// Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative | ||
// Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333 | ||
// ... | ||
isEventSupported = (function() { | ||
var TAGNAMES = { | ||
'select': 'input', 'change': 'input', | ||
'submit': 'form', 'reset': 'form', | ||
'error': 'img', 'load': 'img', 'abort': 'img' | ||
}; | ||
function isEventSupported( eventName, element ) { | ||
element = element || document.createElement(TAGNAMES[eventName] || 'div'); | ||
eventName = 'on' + eventName; | ||
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those | ||
var isSupported = eventName in element; | ||
if ( !isSupported ) { | ||
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element | ||
if ( !element.setAttribute ) { | ||
element = document.createElement('div'); | ||
} | ||
if ( element.setAttribute && element.removeAttribute ) { | ||
element.setAttribute(eventName, ''); | ||
isSupported = is(element[eventName], 'function'); | ||
// If property was created, "remove it" (by setting value to `undefined`) | ||
if ( !is(element[eventName], 'undefined') ) { | ||
element[eventName] = undefined; | ||
} | ||
element.removeAttribute(eventName); | ||
} | ||
} | ||
element = null; | ||
return isSupported; | ||
} | ||
return isEventSupported; | ||
})(), | ||
/*>>hasevent*/ | ||
// TODO :: Add flag for hasownprop ? didn't last time | ||
// hasOwnProperty shim by kangax needed for Safari 2.0 support | ||
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp; | ||
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) { | ||
hasOwnProp = function (object, property) { | ||
return _hasOwnProperty.call(object, property); | ||
}; | ||
} | ||
else { | ||
hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ | ||
return ((property in object) && is(object.constructor.prototype[property], 'undefined')); | ||
}; | ||
} | ||
// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js | ||
// es5.github.com/#x15.3.4.5 | ||
if (!Function.prototype.bind) { | ||
Function.prototype.bind = function bind(that) { | ||
var target = this; | ||
if (typeof target != "function") { | ||
throw new TypeError(); | ||
} | ||
var args = slice.call(arguments, 1), | ||
bound = function () { | ||
if (this instanceof bound) { | ||
var F = function(){}; | ||
F.prototype = target.prototype; | ||
var self = new F(); | ||
var result = target.apply( | ||
self, | ||
args.concat(slice.call(arguments)) | ||
); | ||
if (Object(result) === result) { | ||
return result; | ||
} | ||
return self; | ||
} else { | ||
return target.apply( | ||
that, | ||
args.concat(slice.call(arguments)) | ||
); | ||
} | ||
}; | ||
return bound; | ||
}; | ||
} | ||
/** | ||
* setCss applies given styles to the Modernizr DOM node. | ||
*/ | ||
function setCss( str ) { | ||
mStyle.cssText = str; | ||
} | ||
/** | ||
* setCssAll extrapolates all vendor-specific css strings. | ||
*/ | ||
function setCssAll( str1, str2 ) { | ||
return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); | ||
} | ||
/** | ||
* is returns a boolean for if typeof obj is exactly type. | ||
*/ | ||
function is( obj, type ) { | ||
return typeof obj === type; | ||
} | ||
/** | ||
* contains returns a boolean for if substr is found within str. | ||
*/ | ||
function contains( str, substr ) { | ||
return !!~('' + str).indexOf(substr); | ||
} | ||
/*>>testprop*/ | ||
// testProps is a generic CSS / DOM property test. | ||
// In testing support for a given CSS property, it's legit to test: | ||
// `elem.style[styleName] !== undefined` | ||
// If the property is supported it will return an empty string, | ||
// if unsupported it will return undefined. | ||
// We'll take advantage of this quick test and skip setting a style | ||
// on our modernizr element, but instead just testing undefined vs | ||
// empty string. | ||
// Because the testing of the CSS property names (with "-", as | ||
// opposed to the camelCase DOM properties) is non-portable and | ||
// non-standard but works in WebKit and IE (but not Gecko or Opera), | ||
// we explicitly reject properties with dashes so that authors | ||
// developing in WebKit or IE first don't end up with | ||
// browser-specific content by accident. | ||
function testProps( props, prefixed ) { | ||
for ( var i in props ) { | ||
var prop = props[i]; | ||
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) { | ||
return prefixed == 'pfx' ? prop : true; | ||
} | ||
} | ||
return false; | ||
} | ||
/*>>testprop*/ | ||
// TODO :: add testDOMProps | ||
/** | ||
* testDOMProps is a generic DOM property test; if a browser supports | ||
* a certain property, it won't return undefined for it. | ||
*/ | ||
function testDOMProps( props, obj, elem ) { | ||
for ( var i in props ) { | ||
var item = obj[props[i]]; | ||
if ( item !== undefined) { | ||
// return the property name as a string | ||
if (elem === false) return props[i]; | ||
// let's bind a function | ||
if (is(item, 'function')){ | ||
// default to autobind unless override | ||
return item.bind(elem || obj); | ||
} | ||
// return the unbound function or obj or value | ||
return item; | ||
} | ||
} | ||
return false; | ||
} | ||
/*>>testallprops*/ | ||
/** | ||
* testPropsAll tests a list of DOM properties we want to check against. | ||
* We specify literally ALL possible (known and/or likely) properties on | ||
* the element including the non-vendor prefixed one, for forward- | ||
* compatibility. | ||
*/ | ||
function testPropsAll( prop, prefixed, elem ) { | ||
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), | ||
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); | ||
// did they call .prefixed('boxSizing') or are we just testing a prop? | ||
if(is(prefixed, "string") || is(prefixed, "undefined")) { | ||
return testProps(props, prefixed); | ||
// otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) | ||
} else { | ||
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); | ||
return testDOMProps(props, prefixed, elem); | ||
} | ||
} | ||
/*>>testallprops*/ | ||
/** | ||
* Tests | ||
* ----- | ||
*/ | ||
// The *new* flexbox | ||
// dev.w3.org/csswg/css3-flexbox | ||
tests['flexbox'] = function() { | ||
return testPropsAll('flexWrap'); | ||
}; | ||
// The *old* flexbox | ||
// www.w3.org/TR/2009/WD-css3-flexbox-20090723/ | ||
tests['flexboxlegacy'] = function() { | ||
return testPropsAll('boxDirection'); | ||
}; | ||
// On the S60 and BB Storm, getContext exists, but always returns undefined | ||
// so we actually have to call getContext() to verify | ||
// github.com/Modernizr/Modernizr/issues/issue/97/ | ||
tests['canvas'] = function() { | ||
var elem = document.createElement('canvas'); | ||
return !!(elem.getContext && elem.getContext('2d')); | ||
}; | ||
tests['canvastext'] = function() { | ||
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function')); | ||
}; | ||
// webk.it/70117 is tracking a legit WebGL feature detect proposal | ||
// We do a soft detect which may false positive in order to avoid | ||
// an expensive context creation: bugzil.la/732441 | ||
tests['webgl'] = function() { | ||
return !!window.WebGLRenderingContext; | ||
}; | ||
/* | ||
* The Modernizr.touch test only indicates if the browser supports | ||
* touch events, which does not necessarily reflect a touchscreen | ||
* device, as evidenced by tablets running Windows 7 or, alas, | ||
* the Palm Pre / WebOS (touch) phones. | ||
* | ||
* Additionally, Chrome (desktop) used to lie about its support on this, | ||
* but that has since been rectified: crbug.com/36415 | ||
* | ||
* We also test for Firefox 4 Multitouch Support. | ||
* | ||
* For more info, see: modernizr.github.com/Modernizr/touch.html | ||
*/ | ||
tests['touch'] = function() { | ||
var bool; | ||
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { | ||
bool = true; | ||
} else { | ||
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) { | ||
bool = node.offsetTop === 9; | ||
}); | ||
} | ||
return bool; | ||
}; | ||
// geolocation is often considered a trivial feature detect... | ||
// Turns out, it's quite tricky to get right: | ||
// | ||
// Using !!navigator.geolocation does two things we don't want. It: | ||
// 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513 | ||
// 2. Disables page caching in WebKit: webk.it/43956 | ||
// | ||
// Meanwhile, in Firefox < 8, an about:config setting could expose | ||
// a false positive that would throw an exception: bugzil.la/688158 | ||
tests['geolocation'] = function() { | ||
return 'geolocation' in navigator; | ||
}; | ||
tests['postmessage'] = function() { | ||
return !!window.postMessage; | ||
}; | ||
// Chrome incognito mode used to throw an exception when using openDatabase | ||
// It doesn't anymore. | ||
tests['websqldatabase'] = function() { | ||
return !!window.openDatabase; | ||
}; | ||
// Vendors had inconsistent prefixing with the experimental Indexed DB: | ||
// - Webkit's implementation is accessible through webkitIndexedDB | ||
// - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB | ||
// For speed, we don't test the legacy (and beta-only) indexedDB | ||
tests['indexedDB'] = function() { | ||
return !!testPropsAll("indexedDB", window); | ||
}; | ||
// documentMode logic from YUI to filter out IE8 Compat Mode | ||
// which false positives. | ||
tests['hashchange'] = function() { | ||
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7); | ||
}; | ||
// Per 1.6: | ||
// This used to be Modernizr.historymanagement but the longer | ||
// name has been deprecated in favor of a shorter and property-matching one. | ||
// The old API is still available in 1.6, but as of 2.0 will throw a warning, | ||
// and in the first release thereafter disappear entirely. | ||
tests['history'] = function() { | ||
return !!(window.history && history.pushState); | ||
}; | ||
tests['draganddrop'] = function() { | ||
var div = document.createElement('div'); | ||
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div); | ||
}; | ||
// FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10 | ||
// will be supported until FF19 (2/12/13), at which time, ESR becomes FF17. | ||
// FF10 still uses prefixes, so check for it until then. | ||
// for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/ | ||
tests['websockets'] = function() { | ||
return 'WebSocket' in window || 'MozWebSocket' in window; | ||
}; | ||
// css-tricks.com/rgba-browser-support/ | ||
tests['rgba'] = function() { | ||
// Set an rgba() color and check the returned value | ||
setCss('background-color:rgba(150,255,150,.5)'); | ||
return contains(mStyle.backgroundColor, 'rgba'); | ||
}; | ||
tests['hsla'] = function() { | ||
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally, | ||
// except IE9 who retains it as hsla | ||
setCss('background-color:hsla(120,40%,100%,.5)'); | ||
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla'); | ||
}; | ||
tests['multiplebgs'] = function() { | ||
// Setting multiple images AND a color on the background shorthand property | ||
// and then querying the style.background property value for the number of | ||
// occurrences of "url(" is a reliable method for detecting ACTUAL support for this! | ||
setCss('background:url(https://),url(https://),red url(https://)'); | ||
// If the UA supports multiple backgrounds, there should be three occurrences | ||
// of the string "url(" in the return value for elemStyle.background | ||
return (/(url\s*\(.*?){3}/).test(mStyle.background); | ||
}; | ||
// this will false positive in Opera Mini | ||
// github.com/Modernizr/Modernizr/issues/396 | ||
tests['backgroundsize'] = function() { | ||
return testPropsAll('backgroundSize'); | ||
}; | ||
tests['borderimage'] = function() { | ||
return testPropsAll('borderImage'); | ||
}; | ||
// Super comprehensive table about all the unique implementations of | ||
// border-radius: muddledramblings.com/table-of-css3-border-radius-compliance | ||
tests['borderradius'] = function() { | ||
return testPropsAll('borderRadius'); | ||
}; | ||
// WebOS unfortunately false positives on this test. | ||
tests['boxshadow'] = function() { | ||
return testPropsAll('boxShadow'); | ||
}; | ||
// FF3.0 will false positive on this test | ||
tests['textshadow'] = function() { | ||
return document.createElement('div').style.textShadow === ''; | ||
}; | ||
tests['opacity'] = function() { | ||
// Browsers that actually have CSS Opacity implemented have done so | ||
// according to spec, which means their return values are within the | ||
// range of [0.0,1.0] - including the leading zero. | ||
setCssAll('opacity:.55'); | ||
// The non-literal . in this regex is intentional: | ||
// German Chrome returns this value as 0,55 | ||
// github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632 | ||
return (/^0.55$/).test(mStyle.opacity); | ||
}; | ||
// Note, Android < 4 will pass this test, but can only animate | ||
// a single property at a time | ||
// goo.gl/v3V4Gp | ||
tests['cssanimations'] = function() { | ||
return testPropsAll('animationName'); | ||
}; | ||
tests['csscolumns'] = function() { | ||
return testPropsAll('columnCount'); | ||
}; | ||
tests['cssgradients'] = function() { | ||
/** | ||
* For CSS Gradients syntax, please see: | ||
* webkit.org/blog/175/introducing-css-gradients/ | ||
* developer.mozilla.org/en/CSS/-moz-linear-gradient | ||
* developer.mozilla.org/en/CSS/-moz-radial-gradient | ||
* dev.w3.org/csswg/css3-images/#gradients- | ||
*/ | ||
var str1 = 'background-image:', | ||
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));', | ||
str3 = 'linear-gradient(left top,#9f9, white);'; | ||
setCss( | ||
// legacy webkit syntax (FIXME: remove when syntax not in use anymore) | ||
(str1 + '-webkit- '.split(' ').join(str2 + str1) + | ||
// standard syntax // trailing 'background-image:' | ||
prefixes.join(str3 + str1)).slice(0, -str1.length) | ||
); | ||
return contains(mStyle.backgroundImage, 'gradient'); | ||
}; | ||
tests['cssreflections'] = function() { | ||
return testPropsAll('boxReflect'); | ||
}; | ||
tests['csstransforms'] = function() { | ||
return !!testPropsAll('transform'); | ||
}; | ||
tests['csstransforms3d'] = function() { | ||
var ret = !!testPropsAll('perspective'); | ||
// Webkit's 3D transforms are passed off to the browser's own graphics renderer. | ||
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in | ||
// some conditions. As a result, Webkit typically recognizes the syntax but | ||
// will sometimes throw a false positive, thus we must do a more thorough check: | ||
if ( ret && 'webkitPerspective' in docElement.style ) { | ||
// Webkit allows this media query to succeed only if the feature is enabled. | ||
// `@media (transform-3d),(-webkit-transform-3d){ ... }` | ||
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) { | ||
ret = node.offsetLeft === 9 && node.offsetHeight === 3; | ||
}); | ||
} | ||
return ret; | ||
}; | ||
tests['csstransitions'] = function() { | ||
return testPropsAll('transition'); | ||
}; | ||
/*>>fontface*/ | ||
// @font-face detection routine by Diego Perini | ||
// javascript.nwbox.com/CSSSupport/ | ||
// false positives: | ||
// WebOS github.com/Modernizr/Modernizr/issues/342 | ||
// WP7 github.com/Modernizr/Modernizr/issues/538 | ||
tests['fontface'] = function() { | ||
var bool; | ||
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) { | ||
var style = document.getElementById('smodernizr'), | ||
sheet = style.sheet || style.styleSheet, | ||
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : ''; | ||
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0; | ||
}); | ||
return bool; | ||
}; | ||
/*>>fontface*/ | ||
// CSS generated content detection | ||
tests['generatedcontent'] = function() { | ||
var bool; | ||
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) { | ||
bool = node.offsetHeight >= 3; | ||
}); | ||
return bool; | ||
}; | ||
// These tests evaluate support of the video/audio elements, as well as | ||
// testing what types of content they support. | ||
// | ||
// We're using the Boolean constructor here, so that we can extend the value | ||
// e.g. Modernizr.video // true | ||
// Modernizr.video.ogg // 'probably' | ||
// | ||
// Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 | ||
// thx to NielsLeenheer and zcorpan | ||
// Note: in some older browsers, "no" was a return value instead of empty string. | ||
// It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2 | ||
// It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5 | ||
tests['video'] = function() { | ||
var elem = document.createElement('video'), | ||
bool = false; | ||
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224 | ||
try { | ||
if ( bool = !!elem.canPlayType ) { | ||
bool = new Boolean(bool); | ||
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,''); | ||
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546 | ||
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,''); | ||
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,''); | ||
} | ||
} catch(e) { } | ||
return bool; | ||
}; | ||
tests['audio'] = function() { | ||
var elem = document.createElement('audio'), | ||
bool = false; | ||
try { | ||
if ( bool = !!elem.canPlayType ) { | ||
bool = new Boolean(bool); | ||
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,''); | ||
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,''); | ||
// Mimetypes accepted: | ||
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements | ||
// bit.ly/iphoneoscodecs | ||
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,''); | ||
bool.m4a = ( elem.canPlayType('audio/x-m4a;') || | ||
elem.canPlayType('audio/aac;')) .replace(/^no$/,''); | ||
} | ||
} catch(e) { } | ||
return bool; | ||
}; | ||
// In FF4, if disabled, window.localStorage should === null. | ||
// Normally, we could not test that directly and need to do a | ||
// `('localStorage' in window) && ` test first because otherwise Firefox will | ||
// throw bugzil.la/365772 if cookies are disabled | ||
// Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem | ||
// will throw the exception: | ||
// QUOTA_EXCEEDED_ERRROR DOM Exception 22. | ||
// Peculiarly, getItem and removeItem calls do not throw. | ||
// Because we are forced to try/catch this, we'll go aggressive. | ||
// Just FWIW: IE8 Compat mode supports these features completely: | ||
// www.quirksmode.org/dom/html5.html | ||
// But IE8 doesn't support either with local files | ||
tests['localstorage'] = function() { | ||
try { | ||
localStorage.setItem(mod, mod); | ||
localStorage.removeItem(mod); | ||
return true; | ||
} catch(e) { | ||
return false; | ||
} | ||
}; | ||
tests['sessionstorage'] = function() { | ||
try { | ||
sessionStorage.setItem(mod, mod); | ||
sessionStorage.removeItem(mod); | ||
return true; | ||
} catch(e) { | ||
return false; | ||
} | ||
}; | ||
tests['webworkers'] = function() { | ||
return !!window.Worker; | ||
}; | ||
tests['applicationcache'] = function() { | ||
return !!window.applicationCache; | ||
}; | ||
// Thanks to Erik Dahlstrom | ||
tests['svg'] = function() { | ||
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect; | ||
}; | ||
// specifically for SVG inline in HTML, not within XHTML | ||
// test page: paulirish.com/demo/inline-svg | ||
tests['inlinesvg'] = function() { | ||
var div = document.createElement('div'); | ||
div.innerHTML = '<svg/>'; | ||
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg; | ||
}; | ||
// SVG SMIL animation | ||
tests['smil'] = function() { | ||
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate'))); | ||
}; | ||
// This test is only for clip paths in SVG proper, not clip paths on HTML content | ||
// demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg | ||
// However read the comments to dig into applying SVG clippaths to HTML content here: | ||
// github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491 | ||
tests['svgclippaths'] = function() { | ||
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath'))); | ||
}; | ||
/*>>webforms*/ | ||
// input features and input types go directly onto the ret object, bypassing the tests loop. | ||
// Hold this guy to execute in a moment. | ||
function webforms() { | ||
/*>>input*/ | ||
// Run through HTML5's new input attributes to see if the UA understands any. | ||
// We're using f which is the <input> element created early on | ||
// Mike Taylr has created a comprehensive resource for testing these attributes | ||
// when applied to all input types: | ||
// miketaylr.com/code/input-type-attr.html | ||
// spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary | ||
// Only input placeholder is tested while textarea's placeholder is not. | ||
// Currently Safari 4 and Opera 11 have support only for the input placeholder | ||
// Both tests are available in feature-detects/forms-placeholder.js | ||
Modernizr['input'] = (function( props ) { | ||
for ( var i = 0, len = props.length; i < len; i++ ) { | ||
attrs[ props[i] ] = !!(props[i] in inputElem); | ||
} | ||
if (attrs.list){ | ||
// safari false positive's on datalist: webk.it/74252 | ||
// see also github.com/Modernizr/Modernizr/issues/146 | ||
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement); | ||
} | ||
return attrs; | ||
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ')); | ||
/*>>input*/ | ||
/*>>inputtypes*/ | ||
// Run through HTML5's new input types to see if the UA understands any. | ||
// This is put behind the tests runloop because it doesn't return a | ||
// true/false like all the other tests; instead, it returns an object | ||
// containing each input type with its corresponding true/false value | ||
// Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/ | ||
Modernizr['inputtypes'] = (function(props) { | ||
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) { | ||
inputElem.setAttribute('type', inputElemType = props[i]); | ||
bool = inputElem.type !== 'text'; | ||
// We first check to see if the type we give it sticks.. | ||
// If the type does, we feed it a textual value, which shouldn't be valid. | ||
// If the value doesn't stick, we know there's input sanitization which infers a custom UI | ||
if ( bool ) { | ||
inputElem.value = smile; | ||
inputElem.style.cssText = 'position:absolute;visibility:hidden;'; | ||
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) { | ||
docElement.appendChild(inputElem); | ||
defaultView = document.defaultView; | ||
// Safari 2-4 allows the smiley as a value, despite making a slider | ||
bool = defaultView.getComputedStyle && | ||
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' && | ||
// Mobile android web browser has false positive, so must | ||
// check the height to see if the widget is actually there. | ||
(inputElem.offsetHeight !== 0); | ||
docElement.removeChild(inputElem); | ||
} else if ( /^(search|tel)$/.test(inputElemType) ){ | ||
// Spec doesn't define any special parsing or detectable UI | ||
// behaviors so we pass these through as true | ||
// Interestingly, opera fails the earlier test, so it doesn't | ||
// even make it here. | ||
} else if ( /^(url|email)$/.test(inputElemType) ) { | ||
// Real url and email support comes with prebaked validation. | ||
bool = inputElem.checkValidity && inputElem.checkValidity() === false; | ||
} else { | ||
// If the upgraded input compontent rejects the :) text, we got a winner | ||
bool = inputElem.value != smile; | ||
} | ||
} | ||
inputs[ props[i] ] = !!bool; | ||
} | ||
return inputs; | ||
})('search tel url email datetime date month week time datetime-local number range color'.split(' ')); | ||
/*>>inputtypes*/ | ||
} | ||
/*>>webforms*/ | ||
// End of test definitions | ||
// ----------------------- | ||
// Run through all tests and detect their support in the current UA. | ||
// todo: hypothetically we could be doing an array of tests and use a basic loop here. | ||
for ( var feature in tests ) { | ||
if ( hasOwnProp(tests, feature) ) { | ||
// run the test, throw the return value into the Modernizr, | ||
// then based on that boolean, define an appropriate className | ||
// and push it into an array of classes we'll join later. | ||
featureName = feature.toLowerCase(); | ||
Modernizr[featureName] = tests[feature](); | ||
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); | ||
} | ||
} | ||
/*>>webforms*/ | ||
// input tests need to run. | ||
Modernizr.input || webforms(); | ||
/*>>webforms*/ | ||
/** | ||
* addTest allows the user to define their own feature tests | ||
* the result will be added onto the Modernizr object, | ||
* as well as an appropriate className set on the html element | ||
* | ||
* @param feature - String naming the feature | ||
* @param test - Function returning true if feature is supported, false if not | ||
*/ | ||
Modernizr.addTest = function ( feature, test ) { | ||
if ( typeof feature == 'object' ) { | ||
for ( var key in feature ) { | ||
if ( hasOwnProp( feature, key ) ) { | ||
Modernizr.addTest( key, feature[ key ] ); | ||
} | ||
} | ||
} else { | ||
feature = feature.toLowerCase(); | ||
if ( Modernizr[feature] !== undefined ) { | ||
// we're going to quit if you're trying to overwrite an existing test | ||
// if we were to allow it, we'd do this: | ||
// var re = new RegExp("\\b(no-)?" + feature + "\\b"); | ||
// docElement.className = docElement.className.replace( re, '' ); | ||
// but, no rly, stuff 'em. | ||
return Modernizr; | ||
} | ||
test = typeof test == 'function' ? test() : test; | ||
if (typeof enableClasses !== "undefined" && enableClasses) { | ||
docElement.className += ' ' + (test ? '' : 'no-') + feature; | ||
} | ||
Modernizr[feature] = test; | ||
} | ||
return Modernizr; // allow chaining. | ||
}; | ||
// Reset modElem.cssText to nothing to reduce memory footprint. | ||
setCss(''); | ||
modElem = inputElem = null; | ||
/*>>shiv*/ | ||
/** | ||
* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed | ||
*/ | ||
;(function(window, document) { | ||
/*jshint evil:true */ | ||
/** version */ | ||
var version = '3.7.0'; | ||
/** Preset options */ | ||
var options = window.html5 || {}; | ||
/** Used to skip problem elements */ | ||
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; | ||
/** Not all elements can be cloned in IE **/ | ||
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; | ||
/** Detect whether the browser supports default html5 styles */ | ||
var supportsHtml5Styles; | ||
/** Name of the expando, to work with multiple documents or to re-shiv one document */ | ||
var expando = '_html5shiv'; | ||
/** The id for the the documents expando */ | ||
var expanID = 0; | ||
/** Cached data for each document */ | ||
var expandoData = {}; | ||
/** Detect whether the browser supports unknown elements */ | ||
var supportsUnknownElements; | ||
(function() { | ||
try { | ||
var a = document.createElement('a'); | ||
a.innerHTML = '<xyz></xyz>'; | ||
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles | ||
supportsHtml5Styles = ('hidden' in a); | ||
supportsUnknownElements = a.childNodes.length == 1 || (function() { | ||
// assign a false positive if unable to shiv | ||
(document.createElement)('a'); | ||
var frag = document.createDocumentFragment(); | ||
return ( | ||
typeof frag.cloneNode == 'undefined' || | ||
typeof frag.createDocumentFragment == 'undefined' || | ||
typeof frag.createElement == 'undefined' | ||
); | ||
}()); | ||
} catch(e) { | ||
// assign a false positive if detection fails => unable to shiv | ||
supportsHtml5Styles = true; | ||
supportsUnknownElements = true; | ||
} | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
/** | ||
* Creates a style sheet with the given CSS text and adds it to the document. | ||
* @private | ||
* @param {Document} ownerDocument The document. | ||
* @param {String} cssText The CSS text. | ||
* @returns {StyleSheet} The style element. | ||
*/ | ||
function addStyleSheet(ownerDocument, cssText) { | ||
var p = ownerDocument.createElement('p'), | ||
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; | ||
p.innerHTML = 'x<style>' + cssText + '</style>'; | ||
return parent.insertBefore(p.lastChild, parent.firstChild); | ||
} | ||
/** | ||
* Returns the value of `html5.elements` as an array. | ||
* @private | ||
* @returns {Array} An array of shived element node names. | ||
*/ | ||
function getElements() { | ||
var elements = html5.elements; | ||
return typeof elements == 'string' ? elements.split(' ') : elements; | ||
} | ||
/** | ||
* Returns the data associated to the given document | ||
* @private | ||
* @param {Document} ownerDocument The document. | ||
* @returns {Object} An object of data. | ||
*/ | ||
function getExpandoData(ownerDocument) { | ||
var data = expandoData[ownerDocument[expando]]; | ||
if (!data) { | ||
data = {}; | ||
expanID++; | ||
ownerDocument[expando] = expanID; | ||
expandoData[expanID] = data; | ||
} | ||
return data; | ||
} | ||
/** | ||
* returns a shived element for the given nodeName and document | ||
* @memberOf html5 | ||
* @param {String} nodeName name of the element | ||
* @param {Document} ownerDocument The context document. | ||
* @returns {Object} The shived element. | ||
*/ | ||
function createElement(nodeName, ownerDocument, data){ | ||
if (!ownerDocument) { | ||
ownerDocument = document; | ||
} | ||
if(supportsUnknownElements){ | ||
return ownerDocument.createElement(nodeName); | ||
} | ||
if (!data) { | ||
data = getExpandoData(ownerDocument); | ||
} | ||
var node; | ||
if (data.cache[nodeName]) { | ||
node = data.cache[nodeName].cloneNode(); | ||
} else if (saveClones.test(nodeName)) { | ||
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); | ||
} else { | ||
node = data.createElem(nodeName); | ||
} | ||
// Avoid adding some elements to fragments in IE < 9 because | ||
// * Attributes like `name` or `type` cannot be set/changed once an element | ||
// is inserted into a document/fragment | ||
// * Link elements with `src` attributes that are inaccessible, as with | ||
// a 403 response, will cause the tab/window to crash | ||
// * Script elements appended to fragments will execute when their `src` | ||
// or `text` property is set | ||
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; | ||
} | ||
/** | ||
* returns a shived DocumentFragment for the given document | ||
* @memberOf html5 | ||
* @param {Document} ownerDocument The context document. | ||
* @returns {Object} The shived DocumentFragment. | ||
*/ | ||
function createDocumentFragment(ownerDocument, data){ | ||
if (!ownerDocument) { | ||
ownerDocument = document; | ||
} | ||
if(supportsUnknownElements){ | ||
return ownerDocument.createDocumentFragment(); | ||
} | ||
data = data || getExpandoData(ownerDocument); | ||
var clone = data.frag.cloneNode(), | ||
i = 0, | ||
elems = getElements(), | ||
l = elems.length; | ||
for(;i<l;i++){ | ||
clone.createElement(elems[i]); | ||
} | ||
return clone; | ||
} | ||
/** | ||
* Shivs the `createElement` and `createDocumentFragment` methods of the document. | ||
* @private | ||
* @param {Document|DocumentFragment} ownerDocument The document. | ||
* @param {Object} data of the document. | ||
*/ | ||
function shivMethods(ownerDocument, data) { | ||
if (!data.cache) { | ||
data.cache = {}; | ||
data.createElem = ownerDocument.createElement; | ||
data.createFrag = ownerDocument.createDocumentFragment; | ||
data.frag = data.createFrag(); | ||
} | ||
ownerDocument.createElement = function(nodeName) { | ||
//abort shiv | ||
if (!html5.shivMethods) { | ||
return data.createElem(nodeName); | ||
} | ||
return createElement(nodeName, ownerDocument, data); | ||
}; | ||
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + | ||
'var n=f.cloneNode(),c=n.createElement;' + | ||
'h.shivMethods&&(' + | ||
// unroll the `createElement` calls | ||
getElements().join().replace(/[\w\-]+/g, function(nodeName) { | ||
data.createElem(nodeName); | ||
data.frag.createElement(nodeName); | ||
return 'c("' + nodeName + '")'; | ||
}) + | ||
');return n}' | ||
)(html5, data.frag); | ||
} | ||
/*--------------------------------------------------------------------------*/ | ||
/** | ||
* Shivs the given document. | ||
* @memberOf html5 | ||
* @param {Document} ownerDocument The document to shiv. | ||
* @returns {Document} The shived document. | ||
*/ | ||
function shivDocument(ownerDocument) { | ||
if (!ownerDocument) { | ||
ownerDocument = document; | ||
} | ||
var data = getExpandoData(ownerDocument); | ||
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { | ||
data.hasCSS = !!addStyleSheet(ownerDocument, | ||
// corrects block display not defined in IE6/7/8/9 | ||
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' + | ||
// adds styling not present in IE6/7/8/9 | ||
'mark{background:#FF0;color:#000}' + | ||
// hides non-rendered elements | ||
'template{display:none}' | ||
); | ||
} | ||
if (!supportsUnknownElements) { | ||
shivMethods(ownerDocument, data); | ||
} | ||
return ownerDocument; | ||
} | ||
/*--------------------------------------------------------------------------*/ | ||
/** | ||
* The `html5` object is exposed so that more elements can be shived and | ||
* existing shiving can be detected on iframes. | ||
* @type Object | ||
* @example | ||
* | ||
* // options can be changed before the script is included | ||
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; | ||
*/ | ||
var html5 = { | ||
/** | ||
* An array or space separated string of node names of the elements to shiv. | ||
* @memberOf html5 | ||
* @type Array|String | ||
*/ | ||
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video', | ||
/** | ||
* current version of html5shiv | ||
*/ | ||
'version': version, | ||
/** | ||
* A flag to indicate that the HTML5 style sheet should be inserted. | ||
* @memberOf html5 | ||
* @type Boolean | ||
*/ | ||
'shivCSS': (options.shivCSS !== false), | ||
/** | ||
* Is equal to true if a browser supports creating unknown/HTML5 elements | ||
* @memberOf html5 | ||
* @type boolean | ||
*/ | ||
'supportsUnknownElements': supportsUnknownElements, | ||
/** | ||
* A flag to indicate that the document's `createElement` and `createDocumentFragment` | ||
* methods should be overwritten. | ||
* @memberOf html5 | ||
* @type Boolean | ||
*/ | ||
'shivMethods': (options.shivMethods !== false), | ||
/** | ||
* A string to describe the type of `html5` object ("default" or "default print"). | ||
* @memberOf html5 | ||
* @type String | ||
*/ | ||
'type': 'default', | ||
// shivs the document according to the specified `html5` object options | ||
'shivDocument': shivDocument, | ||
//creates a shived element | ||
createElement: createElement, | ||
//creates a shived documentFragment | ||
createDocumentFragment: createDocumentFragment | ||
}; | ||
/*--------------------------------------------------------------------------*/ | ||
// expose html5 | ||
window.html5 = html5; | ||
// shiv the document | ||
shivDocument(document); | ||
}(this, document)); | ||
/*>>shiv*/ | ||
// Assign private properties to the return object with prefix | ||
Modernizr._version = version; | ||
// expose these for the plugin API. Look in the source for how to join() them against your input | ||
/*>>prefixes*/ | ||
Modernizr._prefixes = prefixes; | ||
/*>>prefixes*/ | ||
/*>>domprefixes*/ | ||
Modernizr._domPrefixes = domPrefixes; | ||
Modernizr._cssomPrefixes = cssomPrefixes; | ||
/*>>domprefixes*/ | ||
/*>>mq*/ | ||
// Modernizr.mq tests a given media query, live against the current state of the window | ||
// A few important notes: | ||
// * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false | ||
// * A max-width or orientation query will be evaluated against the current state, which may change later. | ||
// * You must specify values. Eg. If you are testing support for the min-width media query use: | ||
// Modernizr.mq('(min-width:0)') | ||
// usage: | ||
// Modernizr.mq('only screen and (max-width:768)') | ||
Modernizr.mq = testMediaQuery; | ||
/*>>mq*/ | ||
/*>>hasevent*/ | ||
// Modernizr.hasEvent() detects support for a given event, with an optional element to test on | ||
// Modernizr.hasEvent('gesturestart', elem) | ||
Modernizr.hasEvent = isEventSupported; | ||
/*>>hasevent*/ | ||
/*>>testprop*/ | ||
// Modernizr.testProp() investigates whether a given style property is recognized | ||
// Note that the property names must be provided in the camelCase variant. | ||
// Modernizr.testProp('pointerEvents') | ||
Modernizr.testProp = function(prop){ | ||
return testProps([prop]); | ||
}; | ||
/*>>testprop*/ | ||
/*>>testallprops*/ | ||
// Modernizr.testAllProps() investigates whether a given style property, | ||
// or any of its vendor-prefixed variants, is recognized | ||
// Note that the property names must be provided in the camelCase variant. | ||
// Modernizr.testAllProps('boxSizing') | ||
Modernizr.testAllProps = testPropsAll; | ||
/*>>testallprops*/ | ||
/*>>teststyles*/ | ||
// Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards | ||
// Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... }) | ||
Modernizr.testStyles = injectElementWithStyles; | ||
/*>>teststyles*/ | ||
/*>>prefixed*/ | ||
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input | ||
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing' | ||
// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style. | ||
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use: | ||
// | ||
// str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-'); | ||
// If you're trying to ascertain which transition end event to bind to, you might do something like... | ||
// | ||
// var transEndEventNames = { | ||
// 'WebkitTransition' : 'webkitTransitionEnd', | ||
// 'MozTransition' : 'transitionend', | ||
// 'OTransition' : 'oTransitionEnd', | ||
// 'msTransition' : 'MSTransitionEnd', | ||
// 'transition' : 'transitionend' | ||
// }, | ||
// transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; | ||
Modernizr.prefixed = function(prop, obj, elem){ | ||
if(!obj) { | ||
return testPropsAll(prop, 'pfx'); | ||
} else { | ||
// Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame' | ||
return testPropsAll(prop, obj, elem); | ||
} | ||
}; | ||
/*>>prefixed*/ | ||
/*>>cssclasses*/ | ||
// Remove "no-js" class from <html> element, if it exists: | ||
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') + | ||
// Add the new classes to the <html> element. | ||
(enableClasses ? ' js ' + classes.join(' ') : ''); | ||
/*>>cssclasses*/ | ||
return Modernizr; | ||
})(this, this.document); | ||
<html> | ||
<head><title>301 Moved Permanently</title></head> | ||
<body bgcolor="white"> | ||
<center><h1>301 Moved Permanently</h1></center> | ||
<hr><center>nginx/1.4.6 (Ubuntu)</center> | ||
</body> | ||
</html> |
{ | ||
"name": "grunt-modernizr", | ||
"description": "Build out a lean, mean Modernizr machine.", | ||
"version": "0.6.0", | ||
"homepage": "https://github.com/doctyper/grunt-modernizr", | ||
"author": { | ||
"name": "Richard Herrera", | ||
"email": "rich@doctyper.com", | ||
"url": "http://doctyper.com" | ||
}, | ||
"version": "0.6.1", | ||
"homepage": "https://github.com/Modernizr/grunt-modernizr", | ||
"author": "Richard Herrera <rich@doctyper.com> (http://doctyper.com)", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/doctyper/grunt-modernizr.git" | ||
"url": "git://github.com/Modernizr/grunt-modernizr.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/doctyper/grunt-modernizr/issues" | ||
"url": "https://github.com/Modernizr/grunt-modernizr/issues" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://github.com/doctyper/grunt-modernizr/blob/master/LICENSE-MIT" | ||
} | ||
], | ||
"license": "MIT", | ||
"main": "grunt.js", | ||
@@ -40,3 +31,3 @@ "bin": { | ||
"grunt-contrib-jshint": "~0.7.0", | ||
"grunt-contrib-nodeunit": "0.1.2", | ||
"grunt-contrib-nodeunit": "0.4.1", | ||
"grunt-contrib-watch": "~0.3.1", | ||
@@ -52,3 +43,6 @@ "mocha": ">=1.6.0", | ||
"modernizr" | ||
] | ||
], | ||
"directories": { | ||
"test": "test" | ||
} | ||
} |
/* | ||
* grunt-modernizr | ||
* https://github.com/doctyper/grunt-modernizr | ||
* https://github.com/Modernizr/grunt-modernizr | ||
* | ||
@@ -5,0 +5,0 @@ * Copyright (c) 2012 Richard Herrera |
@@ -29,2 +29,50 @@ /*jshint node:true*/ | ||
.expect("in lib/build-files/modernizr-latest.js") | ||
.expect(">> canvastext") | ||
.expect(">> csstransforms3d") | ||
.expect(">> flexbox") | ||
.expect(">> cssgradients") | ||
.expect(">> opacity") | ||
.expect(">> indexedDB") | ||
.expect(">> backgroundsize") | ||
.expect(">> borderimage") | ||
.expect(">> borderradius") | ||
.expect(">> boxshadow") | ||
.expect(">> cssanimations") | ||
.expect(">> csscolumns") | ||
.expect(">> cssreflections") | ||
.expect(">> csstransitions") | ||
.expect(">> flexboxlegacy") | ||
.expect(">> prefixed") | ||
.expect(">> csstransforms") | ||
.expect(">> mq") | ||
.expect(">> hashchange") | ||
.expect(">> draganddrop") | ||
.expect(">> generatedcontent") | ||
.expect(">> svg") | ||
.expect(">> inlinesvg") | ||
.expect(">> smil") | ||
.expect(">> svgclippaths") | ||
.expect(">> input") | ||
.expect(">> inputtypes") | ||
.expect(">> touch") | ||
.expect(">> fontface") | ||
.expect(">> websockets") | ||
.expect(">> applicationcache") | ||
.expect(">> audio") | ||
.expect(">> canvas") | ||
.expect(">> geolocation") | ||
.expect(">> history") | ||
.expect(">> hsla") | ||
.expect(">> localstorage") | ||
.expect(">> multiplebgs") | ||
.expect(">> postmessage") | ||
.expect(">> sessionstorage") | ||
.expect(">> textshadow") | ||
.expect(">> rgba") | ||
.expect(">> video") | ||
.expect(">> webgl") | ||
.expect(">> websqldatabase") | ||
.expect(">> webworkers") | ||
.expect("in lib/modulizr.js") | ||
@@ -261,3 +309,3 @@ .expect(">> testallprops") | ||
.expect("Downloading source files") | ||
.expect("Loading source files") | ||
@@ -306,2 +354,51 @@ .wait(">> Generating a custom Modernizr build") | ||
.expect("in lib/build-files/modernizr-latest.js") | ||
.expect(">> canvastext") | ||
.expect(">> csstransforms3d") | ||
.expect(">> flexbox") | ||
.expect(">> cssgradients") | ||
.expect(">> opacity") | ||
.expect(">> indexedDB") | ||
.expect(">> backgroundsize") | ||
.expect(">> borderimage") | ||
.expect(">> borderradius") | ||
.expect(">> boxshadow") | ||
.expect(">> cssanimations") | ||
.expect(">> csscolumns") | ||
.expect(">> cssreflections") | ||
.expect(">> csstransitions") | ||
.expect(">> flexboxlegacy") | ||
.expect(">> prefixed") | ||
.expect(">> csstransforms") | ||
.expect(">> mq") | ||
.expect(">> hashchange") | ||
.expect(">> draganddrop") | ||
.expect(">> generatedcontent") | ||
.expect(">> svg") | ||
.expect(">> inlinesvg") | ||
.expect(">> smil") | ||
.expect(">> svgclippaths") | ||
.expect(">> input") | ||
.expect(">> inputtypes") | ||
.expect(">> touch") | ||
.expect(">> fontface") | ||
.expect(">> websockets") | ||
.expect(">> applicationcache") | ||
.expect(">> audio") | ||
.expect(">> canvas") | ||
.expect(">> geolocation") | ||
.expect(">> history") | ||
.expect(">> hsla") | ||
.expect(">> localstorage") | ||
.expect(">> multiplebgs") | ||
.expect(">> postmessage") | ||
.expect(">> sessionstorage") | ||
.expect(">> textshadow") | ||
.expect(">> rgba") | ||
.expect(">> video") | ||
.expect(">> webgl") | ||
.expect(">> websqldatabase") | ||
.expect(">> webworkers") | ||
.expect("in lib/modulizr.js") | ||
@@ -554,3 +651,3 @@ .expect(">> testallprops") | ||
.expect("Downloading source files") | ||
.expect("Loading source files") | ||
@@ -607,3 +704,3 @@ .wait(">> Generating a custom Modernizr build") | ||
.expect("Downloading source files") | ||
.expect("Loading source files") | ||
@@ -610,0 +707,0 @@ .wait(">> Generating a custom Modernizr build") |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
172821
39
3959
3