1/*! 2 * modernizr v3.5.0 3 * Build https://modernizr.com/download?-arrow-ellipsis-svg-addtest-fnbind-printshiv-setclasses-testprop-dontmin 4 * 5 * Copyright (c) 6 * Faruk Ates 7 * Paul Irish 8 * Alex Sexton 9 * Ryan Seddon 10 * Patrick Kettner 11 * Stu Cox 12 * Richard Herrera 13 14 * MIT License 15 */ 16 17/* 18 * Modernizr tests which native CSS3 and HTML5 features are available in the 19 * current UA and makes the results available to you in two ways: as properties on 20 * a global `Modernizr` object, and as classes on the `<html>` element. This 21 * information allows you to progressively enhance your pages with a granular level 22 * of control over the experience. 23*/ 24 25;(function(window, document, undefined){ 26 var tests = []; 27 28 29 /** 30 * 31 * ModernizrProto is the constructor for Modernizr 32 * 33 * @class 34 * @access public 35 */ 36 37 var ModernizrProto = { 38 // The current version, dummy 39 _version: '3.5.0', 40 41 // Any settings that don't work as separate modules 42 // can go in here as configuration. 43 _config: { 44 'classPrefix': '', 45 'enableClasses': true, 46 'enableJSClass': true, 47 'usePrefixes': true 48 }, 49 50 // Queue of tests 51 _q: [], 52 53 // Stub these for people who are listening 54 on: function(test, cb) { 55 // I don't really think people should do this, but we can 56 // safe guard it a bit. 57 // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests. 58 // This is in case people listen to synchronous tests. I would leave it out, 59 // but the code to *disallow* sync tests in the real version of this 60 // function is actually larger than this. 61 var self = this; 62 setTimeout(function() { 63 cb(self[test]); 64 }, 0); 65 }, 66 67 addTest: function(name, fn, options) { 68 tests.push({name: name, fn: fn, options: options}); 69 }, 70 71 addAsyncTest: function(fn) { 72 tests.push({name: null, fn: fn}); 73 } 74 }; 75 76 77 78 // Fake some of Object.create so we can force non test results to be non "own" properties. 79 var Modernizr = function() {}; 80 Modernizr.prototype = ModernizrProto; 81 82 // Leak modernizr globally when you `require` it rather than force it here. 83 // Overwrite name so constructor name is nicer :D 84 Modernizr = new Modernizr(); 85 86 87 88 var classes = []; 89 90 91 /** 92 * is returns a boolean if the typeof an obj is exactly type. 93 * 94 * @access private 95 * @function is 96 * @param {*} obj - A thing we want to check the type of 97 * @param {string} type - A string to compare the typeof against 98 * @returns {boolean} 99 */ 100 101 function is(obj, type) { 102 return typeof obj === type; 103 } 104 ; 105 106 /** 107 * Run through all tests and detect their support in the current UA. 108 * 109 * @access private 110 */ 111 112 function testRunner() { 113 var featureNames; 114 var feature; 115 var aliasIdx; 116 var result; 117 var nameIdx; 118 var featureName; 119 var featureNameSplit; 120 121 for (var featureIdx in tests) { 122 if (tests.hasOwnProperty(featureIdx)) { 123 featureNames = []; 124 feature = tests[featureIdx]; 125 // run the test, throw the return value into the Modernizr, 126 // then based on that boolean, define an appropriate className 127 // and push it into an array of classes we'll join later. 128 // 129 // If there is no name, it's an 'async' test that is run, 130 // but not directly added to the object. That should 131 // be done with a post-run addTest call. 132 if (feature.name) { 133 featureNames.push(feature.name.toLowerCase()); 134 135 if (feature.options && feature.options.aliases && feature.options.aliases.length) { 136 // Add all the aliases into the names list 137 for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) { 138 featureNames.push(feature.options.aliases[aliasIdx].toLowerCase()); 139 } 140 } 141 } 142 143 // Run the test, or use the raw value if it's not a function 144 result = is(feature.fn, 'function') ? feature.fn() : feature.fn; 145 146 147 // Set each of the names on the Modernizr object 148 for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) { 149 featureName = featureNames[nameIdx];
150 // Support dot properties as sub tests. We don't do checking to make sure 151 // that the implied parent tests have been added. You must call them in 152 // order (either in the test, or make the parent test a dependency). 153 // 154 // Cap it to TWO to make the logic simple and because who needs that kind of subtesting 155 // hashtag famous last words 156 featureNameSplit = featureName.split('.'); 157 158 if (featureNameSplit.length === 1) { 159 Modernizr[featureNameSplit[0]] = result; 160 } else { 161 // cast to a Boolean, if not one already 162 if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { 163 Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); 164 } 165 166 Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result; 167 } 168 169 classes.push((result ? '' : 'no-') + featureNameSplit.join('-')); 170 } 171 } 172 } 173 } 174 ; 175 176 /** 177 * docElement is a convenience wrapper to grab the root element of the document 178 * 179 * @access private 180 * @returns {HTMLElement|SVGElement} The root element of the document 181 */ 182 183 var docElement = document.documentElement; 184 185 186 /** 187 * A convenience helper to check if the document we are running in is an SVG document 188 * 189 * @access private 190 * @returns {boolean} 191 */ 192 193 var isSVG = docElement.nodeName.toLowerCase() === 'svg'; 194 195 196 /** 197 * setClasses takes an array of class names and adds them to the root element 198 * 199 * @access private 200 * @function setClasses 201 * @param {string[]} classes - Array of class names 202 */ 203 204 // Pass in an and array of class names, e.g.:
205 // ['no-webp', 'borderradius', ...] 206 function setClasses(classes) { 207 var className = docElement.className; 208 var classPrefix = Modernizr._config.classPrefix || ''; 209 210 if (isSVG) { 211 className = className.baseVal; 212 } 213 214 // Change `no-js` to `js` (independently of the `enableClasses` option) 215 // Handle classPrefix on this too 216 if (Modernizr._config.enableJSClass) { 217 var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)'); 218 className = className.replace(reJS, '$1' + classPrefix + 'js$2'); 219 } 220 221 if (Modernizr._config.enableClasses) { 222 // Add the new classes 223 className += ' ' + classPrefix + classes.join(' ' + classPrefix); 224 if (isSVG) { 225 docElement.className.baseVal = className; 226 } else { 227 docElement.className = className; 228 } 229 } 230 231 } 232 233 ; 234 235 /** 236 * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support 237 * 238 * @author kangax 239 * @access private 240 * @function hasOwnProp 241 * @param {object} object - The object to check for a property 242 * @param {string} property - The property to check for 243 * @returns {boolean} 244 */ 245 246 // hasOwnProperty shim by kangax needed for Safari 2.0 support 247 var hasOwnProp; 248 249 (function() { 250 var _hasOwnProperty = ({}).hasOwnProperty; 251 /* istanbul ignore else */ 252 /* we have no way of testing IE 5.5 or safari 2, 253 * so just assume the else gets hit */ 254 if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) { 255 hasOwnProp = function(object, property) { 256 return _hasOwnProperty.call(object, property); 257 }; 258 } 259 else { 260 hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ 261 return ((property in object) && is(object.constructor.prototype[property], 'undefined')); 262 }; 263 } 264 })(); 265 266 267 268 269 // _l tracks listeners for async tests, as well as tests that execute after the initial run 270 ModernizrProto._l = {}; 271 272 /** 273 * Modernizr.on is a way to listen for the completion of async tests. Being 274 * asynchronous, they may not finish before your scripts run. As a result you 275 * will get a possibly false negative `undefined` value. 276 * 277 * @memberof Modernizr 278 * @name Modernizr.on 279 * @access public 280 * @function on 281 * @param {string} feature - String name of the feature detect 282 * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not 283 * @example 284 * 285 * ```js 286 * Modernizr.on('flash', function( result ) { 287 * if (result) { 288 * // the browser has flash 289 * } else { 290 * // the browser does not have flash 291 * } 292 * }); 293 * ``` 294 */ 295 296 ModernizrProto.on = function(feature, cb) { 297 // Create the list of listeners if it doesn't exist 298 if (!this._l[feature]) { 299 this._l[feature] = []; 300 } 301 302 // Push this test on to the listener list 303 this._l[feature].push(cb); 304 305 // If it's already been resolved, trigger it on next tick 306 if (Modernizr.hasOwnProperty(feature)) { 307 // Next Tick 308 setTimeout(function() { 309 Modernizr._trigger(feature, Modernizr[feature]); 310 }, 0); 311 } 312 }; 313 314 /** 315 * _trigger is the private function used to signal test completion and run any 316 * callbacks registered through [Modernizr.on](#modernizr-on) 317 * 318 * @memberof Modernizr 319 * @name Modernizr._trigger 320 * @access private 321 * @function _trigger 322 * @param {string} feature - string name of the feature detect 323 * @param {function|boolean} [res] - A feature detection function, or the boolean = 324 * result of a feature detection function 325 */ 326 327 ModernizrProto._trigger = function(feature, res) { 328 if (!this._l[feature]) { 329 return; 330 } 331 332 var cbs = this._l[feature]; 333 334 // Force async 335 setTimeout(function() { 336 var i, cb; 337 for (i = 0; i < cbs.length; i++) { 338 cb = cbs[i]; 339 cb(res); 340 } 341 }, 0); 342 343 // Don't trigger these again 344 delete this._l[feature]; 345 }; 346 347 /** 348 * addTest allows you to define your own feature detects that are not currently 349 * included in Modernizr (under the covers it's the exact same code Modernizr 350 * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result 351 * will be added onto the Modernizr object, as well as an appropriate className set on 352 * the html element when configured to do so 353 * 354 * @memberof Modernizr 355 * @name Modernizr.addTest 356 * @optionName Modernizr.addTest() 357 * @optionProp addTest 358 * @access public 359 * @function addTest 360 * @param {string|object} feature - The string name of the feature detect, or an 361 * object of feature detect names and test 362 * @param {function|boolean} test - Function returning true if feature is supported, 363 * false if not. Otherwise a boolean representing the results of a feature detection 364 * @example 365 * 366 * The most common way of creating your own feature detects is by calling 367 * `Modernizr.addTest` with a string (preferably just lowercase, without any 368 * punctuation), and a function you want executed that will return a boolean result 369 * 370 * ```js 371 * Modernizr.addTest('itsTuesday', function() { 372 * var d = new Date(); 373 * return d.getDay() === 2; 374 * }); 375 * ``` 376 * 377 * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday, 378 * and to `false` every other day of the week. One thing to notice is that the names of 379 * feature detect functions are always lowercased when added to the Modernizr object. That 380 * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will. 381 * 382 * 383 * Since we only look at the returned value from any feature detection function, 384 * you do not need to actually use a function. For simple detections, just passing 385 * in a statement that will return a boolean value works just fine. 386 * 387 * ```js 388 * Modernizr.addTest('hasJquery', 'jQuery' in window); 389 * ``` 390 * 391 * Just like before, when the above runs `Modernizr.hasjquery` will be true if 392 * jQuery has been included on the page. Not using a function saves a small amount
393 * of overhead for the browser, as well as making your code much more readable. 394 * 395 * Finally, you also have the ability to pass in an object of feature names and 396 * their tests. This is handy if you want to add multiple detections in one go. 397 * The keys should always be a string, and the value can be either a boolean or 398 * function that returns a boolean. 399 * 400 * ```js 401 * var detects = { 402 * 'hasjquery': 'jQuery' in window, 403 * 'itstuesday': function() { 404 * var d = new Date(); 405 * return d.getDay() === 2; 406 * } 407 * } 408 * 409 * Modernizr.addTest(detects); 410 * ``` 411 * 412 * There is really no difference between the first methods and this one, it is 413 * just a convenience to let you write more readable code. 414 */ 415 416 function addTest(feature, test) { 417 418 if (typeof feature == 'object') { 419 for (var key in feature) { 420 if (hasOwnProp(feature, key)) { 421 addTest(key, feature[ key ]); 422 } 423 } 424 } else { 425 426 feature = feature.toLowerCase(); 427 var featureNameSplit = feature.split('.'); 428 var last = Modernizr[featureNameSplit[0]]; 429 430 // Again, we don't check for parent test existence. Get that right, though. 431 if (featureNameSplit.length == 2) { 432 last = last[featureNameSplit[1]]; 433 } 434 435 if (typeof last != 'undefined') { 436 // we're going to quit if you're trying to overwrite an existing test 437 // if we were to allow it, we'd do this: 438 // var re = new RegExp("\\b(no-)?" + feature + "\\b"); 439 // docElement.className = docElement.className.replace( re, '' ); 440 // but, no rly, stuff 'em. 441 return Modernizr; 442 } 443 444 test = typeof test == 'function' ? test() : test; 445 446 // Set the value (this is the magic, right here). 447 if (featureNameSplit.length == 1) { 448 Modernizr[featureNameSplit[0]] = test; 449 } else { 450 // cast to a Boolean, if not one already 451 if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { 452 Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); 453 } 454 455 Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test; 456 } 457 458 // Set a single class (either `feature` or `no-feature`) 459 setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]); 460 461 // Trigger the event 462 Modernizr._trigger(feature, test); 463 } 464 465 return Modernizr; // allow chaining. 466 } 467 468 // After all the tests are run, add self to the Modernizr prototype 469 Modernizr._q.push(function() { 470 ModernizrProto.addTest = addTest; 471 }); 472 473 474 475 476/** 477 * @optionName html5printshiv 478 * @optionProp html5printshiv 479 */ 480 481 // Take the html5 variable out of the html5shiv scope so we can return it. 482 var html5; 483 if (!isSVG) { 484 485 /** 486 * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 487 */ 488 ;(function(window, document) { 489 /** version */ 490 var version = '3.7.3'; 491 492 /** Preset options */ 493 var options = window.html5 || {}; 494 495 /** Used to skip problem elements */ 496 var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; 497 498 /** Not all elements can be cloned in IE **/ 499 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; 500 501 /** Detect whether the browser supports default html5 styles */ 502 var supportsHtml5Styles; 503 504 /** Name of the expando, to work with multiple documents or to re-shiv one document */ 505 var expando = '_html5shiv'; 506 507 /** The id for the the documents expando */ 508 var expanID = 0; 509 510 /** Cached data for each document */ 511 var expandoData = {}; 512 513 /** Detect whether the browser supports unknown elements */ 514 var supportsUnknownElements; 515 516 (function() { 517 try { 518 var a = document.createElement('a'); 519 a.innerHTML = '<xyz></xyz>'; 520 //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles 521 supportsHtml5Styles = ('hidden' in a); 522 523 supportsUnknownElements = a.childNodes.length == 1 || (function() { 524 // assign a false positive if unable to shiv 525 (document.createElement)('a'); 526 var frag = document.createDocumentFragment(); 527 return ( 528 typeof frag.cloneNode == 'undefined' || 529 typeof frag.createDocumentFragment == 'undefined' || 530 typeof frag.createElement == 'undefined' 531 ); 532 }()); 533 } catch(e) { 534 // assign a false positive if detection fails => unable to shiv 535 supportsHtml5Styles = true; 536 supportsUnknownElements = true; 537 } 538 539 }()); 540 541 /*--------------------------------------------------------------------------*/ 542 543 /** 544 * Creates a style sheet with the given CSS text and adds it to the document. 545 * @private 546 * @param {Document} ownerDocument The document. 547 * @param {String} cssText The CSS text. 548 * @returns {StyleSheet} The style element. 549 */ 550 function addStyleSheet(ownerDocument, cssText) { 551 var p = ownerDocument.createElement('p'), 552 parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; 553 554 p.innerHTML = 'x<style>' + cssText + '</style>'; 555 return parent.insertBefore(p.lastChild, parent.firstChild); 556 } 557 558 /** 559 * Returns the value of `html5.elements` as an array.
vendor: 6,114 bytes, lines 560-717
560 * @private 561 * @returns {Array} An array of shived element node names. 562 */ 563 function getElements() { 564 var elements = html5.elements; 565 return typeof elements == 'string' ? elements.split(' ') : elements; 566 } 567 568 /** 569 * Extends the built-in list of html5 elements 570 * @memberOf html5 571 * @param {String|Array} newElements whitespace separated list or array of new element names to shiv 572 * @param {Document} ownerDocument The context document. 573 */ 574 function addElements(newElements, ownerDocument) { 575 var elements = html5.elements; 576 if(typeof elements != 'string'){ 577 elements = elements.join(' '); 578 } 579 if(typeof newElements != 'string'){ 580 newElements = newElements.join(' '); 581 } 582 html5.elements = elements +' '+ newElements; 583 shivDocument(ownerDocument); 584 } 585 586 /** 587 * Returns the data associated to the given document 588 * @private 589 * @param {Document} ownerDocument The document. 590 * @returns {Object} An object of data. 591 */ 592 function getExpandoData(ownerDocument) { 593 var data = expandoData[ownerDocument[expando]]; 594 if (!data) { 595 data = {}; 596 expanID++; 597 ownerDocument[expando] = expanID; 598 expandoData[expanID] = data; 599 } 600 return data; 601 } 602 603 /** 604 * returns a shived element for the given nodeName and document 605 * @memberOf html5 606 * @param {String} nodeName name of the element 607 * @param {Document} ownerDocument The context document. 608 * @returns {Object} The shived element. 609 */ 610 function createElement(nodeName, ownerDocument, data){ 611 if (!ownerDocument) { 612 ownerDocument = document; 613 } 614 if(supportsUnknownElements){ 615 return ownerDocument.createElement(nodeName); 616 } 617 if (!data) { 618 data = getExpandoData(ownerDocument); 619 } 620 var node; 621 622 if (data.cache[nodeName]) { 623 node = data.cache[nodeName].cloneNode(); 624 } else if (saveClones.test(nodeName)) { 625 node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); 626 } else { 627 node = data.createElem(nodeName); 628 } 629 630 // Avoid adding some elements to fragments in IE < 9 because 631 // * Attributes like `name` or `type` cannot be set/changed once an element 632 // is inserted into a document/fragment 633 // * Link elements with `src` attributes that are inaccessible, as with 634 // a 403 response, will cause the tab/window to crash 635 // * Script elements appended to fragments will execute when their `src` 636 // or `text` property is set 637 return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; 638 } 639 640 /** 641 * returns a shived DocumentFragment for the given document 642 * @memberOf html5 643 * @param {Document} ownerDocument The context document. 644 * @returns {Object} The shived DocumentFragment. 645 */ 646 function createDocumentFragment(ownerDocument, data){ 647 if (!ownerDocument) { 648 ownerDocument = document; 649 } 650 if(supportsUnknownElements){ 651 return ownerDocument.createDocumentFragment(); 652 } 653 data = data || getExpandoData(ownerDocument); 654 var clone = data.frag.cloneNode(), 655 i = 0, 656 elems = getElements(), 657 l = elems.length; 658 for(;i<l;i++){ 659 clone.createElement(elems[i]); 660 } 661 return clone; 662 } 663 664 /** 665 * Shivs the `createElement` and `createDocumentFragment` methods of the document. 666 * @private 667 * @param {Document|DocumentFragment} ownerDocument The document. 668 * @param {Object} data of the document. 669 */ 670 function shivMethods(ownerDocument, data) { 671 if (!data.cache) { 672 data.cache = {}; 673 data.createElem = ownerDocument.createElement; 674 data.createFrag = ownerDocument.createDocumentFragment; 675 data.frag = data.createFrag(); 676 } 677 678 679 ownerDocument.createElement = function(nodeName) { 680 //abort shiv 681 if (!html5.shivMethods) { 682 return data.createElem(nodeName); 683 } 684 return createElement(nodeName, ownerDocument, data); 685 }; 686 687 ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 688 'var n=f.cloneNode(),c=n.createElement;' + 689 'h.shivMethods&&(' + 690 // unroll the `createElement` calls 691 getElements().join().replace(/[\w\-:]+/g, function(nodeName) { 692 data.createElem(nodeName); 693 data.frag.createElement(nodeName); 694 return 'c("' + nodeName + '")'; 695 }) + 696 ');return n}' 697 )(html5, data.frag); 698 } 699 700 /*--------------------------------------------------------------------------*/ 701 702 /** 703 * Shivs the given document. 704 * @memberOf html5 705 * @param {Document} ownerDocument The document to shiv. 706 * @returns {Document} The shived document. 707 */ 708 function shivDocument(ownerDocument) { 709 if (!ownerDocument) { 710 ownerDocument = document; 711 } 712 var data = getExpandoData(ownerDocument); 713 714 if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { 715 data.hasCSS = !!addStyleSheet(ownerDocument, 716 // corrects block display not defined in IE6/7/8/9 717 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
717play:block}' + 718 // adds styling not present in IE6/7/8/9 719 'mark{background:#FF0;color:#000}' + 720 // hides non-rendered elements 721 'template{display:none}' 722 ); 723 } 724 if (!supportsUnknownElements) { 725 shivMethods(ownerDocument, data); 726 } 727 return ownerDocument; 728 } 729 730 /*--------------------------------------------------------------------------*/ 731 732 /** 733 * The `html5` object is exposed so that more elements can be shived and 734 * existing shiving can be detected on iframes. 735 * @type Object 736 * @example 737 * 738 * // options can be changed before the script is included 739 * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; 740 */ 741 var html5 = { 742 743 /** 744 * An array or space separated string of node names of the elements to shiv. 745 * @memberOf html5 746 * @type Array|String 747 */ 748 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video', 749 750 /** 751 * current version of html5shiv 752 */ 753 'version': version, 754 755 /** 756 * A flag to indicate that the HTML5 style sheet should be inserted. 757 * @memberOf html5 758 * @type Boolean 759 */ 760 'shivCSS': (options.shivCSS !== false), 761 762 /** 763 * Is equal to true if a browser supports creating unknown/HTML5 elements 764 * @memberOf html5 765 * @type boolean 766 */ 767 'supportsUnknownElements': supportsUnknownElements, 768 769 /** 770 * A flag to indicate that the document's `createElement` and `createDocumentFragment` 771 * methods should be overwritten. 772 * @memberOf html5 773 * @type Boolean 774 */ 775 'shivMethods': (options.shivMethods !== false), 776 777 /** 778 * A string to describe the type of `html5` object ("default" or "default print"). 779 * @memberOf html5
vendor: 7,731 bytes, lines 780-1023
780 * @type String 781 */ 782 'type': 'default', 783 784 // shivs the document according to the specified `html5` object options 785 'shivDocument': shivDocument, 786 787 //creates a shived element 788 createElement: createElement, 789 790 //creates a shived documentFragment 791 createDocumentFragment: createDocumentFragment, 792 793 //extends list of elements 794 addElements: addElements 795 }; 796 797 /*--------------------------------------------------------------------------*/ 798 799 // expose html5 800 window.html5 = html5; 801 802 // shiv the document 803 shivDocument(document); 804 805 /*------------------------------- Print Shiv -------------------------------*/ 806 807 /** Used to filter media types */ 808 var reMedia = /^$|\b(?:all|print)\b/; 809 810 /** Used to namespace printable elements */ 811 var shivNamespace = 'html5shiv'; 812 813 /** Detect whether the browser supports shivable style sheets */ 814 var supportsShivableSheets = !supportsUnknownElements && (function() { 815 // assign a false negative if unable to shiv 816 var docEl = document.documentElement; 817 return !( 818 typeof document.namespaces == 'undefined' || 819 typeof document.parentWindow == 'undefined' || 820 typeof docEl.applyElement == 'undefined' || 821 typeof docEl.removeNode == 'undefined' || 822 typeof window.attachEvent == 'undefined' 823 ); 824 }()); 825 826 /*--------------------------------------------------------------------------*/ 827 828 /** 829 * Wraps all HTML5 elements in the given document with printable elements. 830 * (eg. the "header" element is wrapped with the "html5shiv:header" element) 831 * @private 832 * @param {Document} ownerDocument The document. 833 * @returns {Array} An array wrappers added. 834 */ 835 function addWrappers(ownerDocument) { 836 var node, 837 nodes = ownerDocument.getElementsByTagName('*'), 838 index = nodes.length, 839 reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'), 840 result = []; 841 842 while (index--) { 843 node = nodes[index]; 844 if (reElements.test(node.nodeName)) { 845 result.push(node.applyElement(createWrapper(node))); 846 } 847 } 848 return result; 849 } 850 851 /** 852 * Creates a printable wrapper for the given element. 853 * @private 854 * @param {Element} element The element. 855 * @returns {Element} The wrapper. 856 */ 857 function createWrapper(element) { 858 var node, 859 nodes = element.attributes, 860 index = nodes.length, 861 wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName); 862 863 // copy element attributes to the wrapper 864 while (index--) { 865 node = nodes[index]; 866 node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue); 867 } 868 // copy element styles to the wrapper 869 wrapper.style.cssText = element.style.cssText; 870 return wrapper; 871 } 872 873 /** 874 * Shivs the given CSS text. 875 * (eg. header{} becomes html5shiv\:header{}) 876 * @private 877 * @param {String} cssText The CSS text to shiv. 878 * @returns {String} The shived CSS text. 879 */ 880 function shivCssText(cssText) { 881 var pair, 882 parts = cssText.split('{'), 883 index = parts.length, 884 reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'), 885 replacement = '$1' + shivNamespace + '\\:$2'; 886 887 while (index--) { 888 pair = parts[index] = parts[index].split('}'); 889 pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement); 890 parts[index] = pair.join('}'); 891 } 892 return parts.join('{'); 893 } 894 895 /** 896 * Removes the given wrappers, leaving the original elements. 897 * @private 898 * @params {Array} wrappers An array of printable wrappers. 899 */ 900 function removeWrappers(wrappers) { 901 var index = wrappers.length; 902 while (index--) { 903 wrappers[index].removeNode(); 904 } 905 } 906 907 /*--------------------------------------------------------------------------*/ 908 909 /** 910 * Shivs the given document for print. 911 * @memberOf html5 912 * @param {Document} ownerDocument The document to shiv. 913 * @returns {Document} The shived document. 914 */ 915 function shivPrint(ownerDocument) { 916 var shivedSheet, 917 wrappers, 918 data = getExpandoData(ownerDocument), 919 namespaces = ownerDocument.namespaces, 920 ownerWindow = ownerDocument.parentWindow; 921 922 if (!supportsShivableSheets || ownerDocument.printShived) { 923 return ownerDocument; 924 } 925 if (typeof namespaces[shivNamespace] == 'undefined') { 926 namespaces.add(shivNamespace); 927 } 928 929 function removeSheet() { 930 clearTimeout(data._removeSheetTimer); 931 if (shivedSheet) { 932 shivedSheet.removeNode(true); 933 } 934 shivedSheet= null; 935 } 936 937 ownerWindow.attachEvent('onbeforeprint', function() { 938 939 removeSheet(); 940 941 var imports, 942 length, 943 sheet, 944 collection = ownerDocument.styleSheets, 945 cssText = [], 946 index = collection.length, 947 sheets = Array(index); 948 949 // convert styleSheets collection to an array 950 while (index--) { 951 sheets[index] = collection[index]; 952 } 953 // concat all style sheet CSS text 954 while ((sheet = sheets.pop())) { 955 // IE does not enforce a same origin policy for external style sheets... 956 // but has trouble with some dynamically created stylesheets 957 if (!sheet.disabled && reMedia.test(sheet.media)) { 958 959 try { 960 imports = sheet.imports; 961 length = imports.length; 962 } catch(er){ 963 length = 0; 964 } 965 966 for (index = 0; index < length; index++) { 967 sheets.push(imports[index]); 968 } 969 970 try { 971 cssText.push(sheet.cssText); 972 } catch(er){} 973 } 974 } 975 976 // wrap all HTML5 elements with printable elements and add the shived style sheet 977 cssText = shivCssText(cssText.reverse().join('')); 978 wrappers = addWrappers(ownerDocument); 979 shivedSheet = addStyleSheet(ownerDocument, cssText); 980 981 }); 982 983 ownerWindow.attachEvent('onafterprint', function() { 984 // remove wrappers, leaving the original elements, and remove the shived style sheet 985 removeWrappers(wrappers); 986 clearTimeout(data._removeSheetTimer); 987 data._removeSheetTimer = setTimeout(removeSheet, 500); 988 }); 989 990 ownerDocument.printShived = true; 991 return ownerDocument; 992 } 993 994 /*--------------------------------------------------------------------------*/ 995 996 // expose API 997 html5.type += ' print'; 998 html5.shivPrint = shivPrint; 999 1000 // shiv for print 1001 shivPrint(document); 1002 1003 if(typeof module == 'object' && module.exports){ 1004 module.exports = html5; 1005 } 1006 1007 }(typeof window !== 'undefined' ? window : this, document)); 1008 } 1009 1010 ; 1011 1012 1013 /** 1014 * contains checks to see if a string contains another string 1015 * 1016 * @access private 1017 * @function contains 1018 * @param {string} str - The string we want to check for substrings 1019 * @param {string} substr - The substring we want to search the first string for 1020 * @returns {boolean} 1021 */ 1022 1023 function contains(str, substr) {
1024 return !!~('' + str).indexOf(substr); 1025 } 1026 1027 ; 1028 1029 /** 1030 * createElement is a convenience wrapper around document.createElement. Since we 1031 * use createElement all over the place, this allows for (slightly) smaller code 1032 * as well as abstracting away issues with creating elements in contexts other than 1033 * HTML documents (e.g. SVG documents). 1034 * 1035 * @access private 1036 * @function createElement 1037 * @returns {HTMLElement|SVGElement} An HTML or SVG element 1038 */ 1039 1040 function createElement() { 1041 if (typeof document.createElement !== 'function') { 1042 // This is the case in IE7, where the type of createElement is "object". 1043 // For this reason, we cannot call apply() as Object is not a Function. 1044 return document.createElement(arguments[0]); 1045 } else if (isSVG) { 1046 return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]); 1047 } else { 1048 return document.createElement.apply(document, arguments); 1049 } 1050 } 1051 1052 ; 1053 1054 /** 1055 * Create our "modernizr" element that we do most feature tests on. 1056 * 1057 * @access private 1058 */ 1059 1060 var modElem = { 1061 elem: createElement('modernizr') 1062 }; 1063 1064 // Clean up this element 1065 Modernizr._q.push(function() { 1066 delete modElem.elem; 1067 }); 1068 1069 1070 1071 var mStyle = { 1072 style: modElem.elem.style 1073 }; 1074 1075 // kill ref for gc, must happen before mod.elem is removed, so we unshift on to 1076 // the front of the queue. 1077 Modernizr._q.unshift(function() { 1078 delete mStyle.style; 1079 }); 1080 1081 1082 1083 /** 1084 * getBody returns the body of a document, or an element that can stand in for 1085 * the body if a real body does not exist 1086 * 1087 * @access private 1088 * @function getBody 1089 * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an 1090 * artificially created element that stands in for the body 1091 */ 1092 1093 function getBody() { 1094 // After page load injecting a fake body doesn't work so check if body exists 1095 var body = document.body; 1096 1097 if (!body) { 1098 // Can't use the real body create a fake one. 1099 body = createElement(isSVG ? 'svg' : 'body'); 1100 body.fake = true; 1101 } 1102 1103 return body; 1104 } 1105 1106 ; 1107 1108 /** 1109 * injectElementWithStyles injects an element with style element and some CSS rules 1110 * 1111 * @access private 1112 * @function injectElementWithStyles 1113 * @param {string} rule - String representing a css rule 1114 * @param {function} callback - A function that is used to test the injected element 1115 * @param {number} [nodes] - An integer representing the number of additional nodes you want injected 1116 * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes 1117 * @returns {boolean} 1118 */ 1119 1120 function injectElementWithStyles(rule, callback, nodes, testnames) { 1121 var mod = 'modernizr'; 1122 var style; 1123 var ret; 1124 var node; 1125 var docOverflow; 1126 var div = createElement('div'); 1127 var body = getBody(); 1128 1129 if (parseInt(nodes, 10)) { 1130 // In order not to give false positives we create a node for each test 1131 // This also allows the method to scale for unspecified uses 1132 while (nodes--) { 1133 node = createElement('div'); 1134 node.id = testnames ? testnames[nodes] : mod + (nodes + 1); 1135 div.appendChild(node); 1136 } 1137 } 1138 1139 style = createElement('style'); 1140 style.type = 'text/css'; 1141 style.id = 's' + mod; 1142 1143 // 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. 1144 // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 1145 (!body.fake ? div : body).appendChild(style); 1146 body.appendChild(div); 1147 1148 if (style.styleSheet) { 1149 style.styleSheet.cssText = rule; 1150 } else { 1151 style.appendChild(document.createTextNode(rule)); 1152 } 1153 div.id = mod; 1154 1155 if (body.fake) { 1156 //avoid crashing IE8, if background image is used 1157 body.style.background = ''; 1158 //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible 1159 body.style.overflow = 'hidden'; 1160 docOverflow = docElement.style.overflow; 1161 docElement.style.overflow = 'hidden'; 1162 docElement.appendChild(body); 1163 } 1164 1165 ret = callback(div, rule); 1166 // If this is done after page load we don't want to remove the body so check if body exists 1167 if (body.fake) { 1168 body.parentNode.removeChild(body); 1169 docElement.style.overflow = docOverflow; 1170 // Trigger layout so kinetic scrolling isn't disabled in iOS6+ 1171 // eslint-disable-next-line 1172 docElement.offsetHeight; 1173 } else { 1174 div.parentNode.removeChild(div); 1175 } 1176 1177 return !!ret; 1178 1179 } 1180 1181 ; 1182 1183 /** 1184 * domToCSS takes a camelCase string and converts it to kebab-case 1185 * e.g. boxSizing -> box-sizing 1186 * 1187 * @access private 1188 * @function domToCSS 1189 * @param {string} name - String name of camelCase prop we want to convert 1190 * @returns {string} The kebab-case version of the supplied name 1191 */ 1192 1193 function domToCSS(name) { 1194 return name.replace(/([A-Z])/g, function(str, m1) { 1195 return '-' + m1.toLowerCase(); 1196 }).replace(/^ms-/, '-ms-'); 1197 } 1198 ; 1199 1200 1201 /** 1202 * wrapper around getComputedStyle, to fix issues with Firefox returning null when
1203 * called inside of a hidden iframe 1204 * 1205 * @access private 1206 * @function computedStyle 1207 * @param {HTMLElement|SVGElement} - The element we want to find the computed styles of 1208 * @param {string|null} [pseudoSelector]- An optional pseudo element selector (e.g. :before), of null if none 1209 * @returns {CSSStyleDeclaration} 1210 */ 1211 1212 function computedStyle(elem, pseudo, prop) { 1213 var result; 1214 1215 if ('getComputedStyle' in window) { 1216 result = getComputedStyle.call(window, elem, pseudo); 1217 var console = window.console; 1218 1219 if (result !== null) { 1220 if (prop) { 1221 result = result.getPropertyValue(prop); 1222 } 1223 } else { 1224 if (console) { 1225 var method = console.error ? 'error' : 'log'; 1226 console[method].call(console, 'getComputedStyle returning null, its possible modernizr test results are inaccurate'); 1227 } 1228 } 1229 } else { 1230 result = !pseudo && elem.currentStyle && elem.currentStyle[prop]; 1231 } 1232 1233 return result; 1234 } 1235 1236 ; 1237 1238 /** 1239 * nativeTestProps allows for us to use native feature detection functionality if available. 1240 * some prefixed form, or false, in the case of an unsupported rule 1241 * 1242 * @access private 1243 * @function nativeTestProps 1244 * @param {array} props - An array of property names 1245 * @param {string} value - A string representing the value we want to check via @supports 1246 * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise 1247 */ 1248 1249 // Accepts a list of property names and a single value 1250 // Returns `undefined` if native detection not available 1251 function nativeTestProps(props, value) { 1252 var i = props.length; 1253 // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface 1254 if ('CSS' in window && 'supports' in window.CSS) { 1255 // Try every prefixed variant of the property 1256 while (i--) { 1257 if (window.CSS.supports(domToCSS(props[i]), value)) { 1258 return true; 1259 } 1260 } 1261 return false; 1262 } 1263 // Otherwise fall back to at-rule (for Opera 12.x) 1264 else if ('CSSSupportsRule' in window) { 1265 // Build a condition string for every prefixed variant 1266 var conditionText = []; 1267 while (i--) { 1268 conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')'); 1269 } 1270 conditionText = conditionText.join(' or '); 1271 return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) { 1272 return computedStyle(node, null, 'position') == 'absolute'; 1273 }); 1274 } 1275 return undefined; 1276 } 1277 ; 1278 1279 /** 1280 * cssToDOM takes a kebab-case string and converts it to camelCase 1281 * e.g. box-sizing -> boxSizing 1282 * 1283 * @access private 1284 * @function cssToDOM 1285 * @param {string} name - String name of kebab-case prop we want to convert 1286 * @returns {string} The camelCase version of the supplied name 1287 */ 1288 1289 function cssToDOM(name) { 1290 return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) { 1291 return m1 + m2.toUpperCase(); 1292 }).replace(/^-/, ''); 1293 } 1294 ; 1295 1296 // testProps is a generic CSS / DOM property test. 1297 1298 // In testing support for a given CSS property, it's legit to test: 1299 // `elem.style[styleName] !== undefined` 1300 // If the property is supported it will return an empty string, 1301 // if unsupported it will return undefined. 1302 1303 // We'll take advantage of this quick test and skip setting a style 1304 // on our modernizr element, but instead just testing undefined vs 1305 // empty string. 1306 1307 // Property names can be provided in either camelCase or kebab-case. 1308 1309 function testProps(props, prefixed, value, skipValueTest) { 1310 skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest; 1311 1312 // Try native detect first 1313 if (!is(value, 'undefined')) { 1314 var result = nativeTestProps(props, value); 1315 if (!is(result, 'undefined')) { 1316 return result; 1317 } 1318 } 1319 1320 // Otherwise do it properly 1321 var afterInit, i, propsLength, prop, before; 1322 1323 // If we don't have a style element, that means we're running async or after 1324 // the core tests, so we'll need to create our own elements to use 1325 1326 // inside of an SVG element, in certain browsers, the `style` element is only 1327 // defined for valid tags. Therefore, if `modernizr` does not have one, we 1328 // fall back to a less used element and hope for the best. 1329 // for strict XHTML browsers the hardly used samp element is used 1330 var elems = ['modernizr', 'tspan', 'samp']; 1331 while (!mStyle.style && elems.length) { 1332 afterInit = true; 1333 mStyle.modElem = createElement(elems.shift()); 1334 mStyle.style = mStyle.modElem.style; 1335 } 1336 1337 // Delete the objects if we created them. 1338 function cleanElems() { 1339 if (afterInit) { 1340 delete mStyle.style; 1341 delete mStyle.modElem; 1342 } 1343 } 1344 1345 propsLength = props.length; 1346 for (i = 0; i < propsLength; i++) { 1347 prop = props[i]; 1348 before = mStyle.style[prop]; 1349 1350 if (contains(prop, '-')) { 1351 prop = cssToDOM(prop); 1352 } 1353 1354 if (mStyle.style[prop] !== undefined) { 1355 1356 // If value to test has been passed in, do a set-and-check test. 1357 // 0 (integer) is a valid property value, so check that `value` isn't 1358 // undefined, rather than just checking it's truthy. 1359 if (!skipValueTest && !is(value, 'undefined')) { 1360 1361 // Needs a try catch block because of old IE. This is slow, but will 1362 // be avoided in most cases because `skipValueTest` will be used. 1363 try { 1364 mStyle.style[prop] = value; 1365 } catch (e) {} 1366 1367 // If the property value has changed, we assume the value used is 1368 // supported. If `value` is empty string, it'll fail here (because 1369 // it hasn't changed), which matches how browsers have implemented 1370 // CSS.supports() 1371 if (mStyle.style[prop] != before) { 1372 cleanElems(); 1373 return prefixed == 'pfx' ? prop : true; 1374 } 1375 } 1376 // Otherwise just return true, or the property name if this is a 1377 // `prefixed()` call 1378 else { 1379 cleanElems(); 1380 return prefixed == 'pfx' ? prop : true; 1381 } 1382 } 1383 } 1384 cleanElems(); 1385 return false;
1386 } 1387 1388 ; 1389 1390 /** 1391 * testProp() investigates whether a given style property is recognized 1392 * Property names can be provided in either camelCase or kebab-case. 1393 * 1394 * @memberof Modernizr 1395 * @name Modernizr.testProp 1396 * @access public 1397 * @optionName Modernizr.testProp() 1398 * @optionProp testProp 1399 * @function testProp 1400 * @param {string} prop - Name of the CSS property to check 1401 * @param {string} [value] - Name of the CSS value to check 1402 * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported 1403 * @returns {boolean} 1404 * @example 1405 * 1406 * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed 1407 * version of the string. 1408 * 1409 * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing) 1410 * 1411 * ```js 1412 * Modernizr.testProp('pointerEvents') // true 1413 * ``` 1414 * 1415 * You can also provide a value as an optional second argument to check if a 1416 * specific value is supported 1417 * 1418 * ```js
1419 * Modernizr.testProp('pointerEvents', 'none') // true 1420 * Modernizr.testProp('pointerEvents', 'penguin') // false 1421 * ``` 1422 */ 1423 1424 var testProp = ModernizrProto.testProp = function(prop, value, useValue) { 1425 return testProps([prop], undefined, value, useValue); 1426 }; 1427 1428 1429 /** 1430 * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill. 1431 * 1432 * @access private 1433 * @function fnBind 1434 * @param {function} fn - a function you want to change `this` reference to 1435 * @param {object} that - the `this` you want to call the function with 1436 * @returns {function} The wrapped version of the supplied function 1437 */ 1438 1439 function fnBind(fn, that) { 1440 return function() { 1441 return fn.apply(that, arguments); 1442 }; 1443 } 1444 1445 ; 1446/*! 1447{ 1448 "name": "SVG", 1449 "property": "svg", 1450 "caniuse": "svg", 1451 "tags": ["svg"], 1452 "authors": ["Erik Dahlstrom"], 1453 "polyfills": [ 1454 "svgweb", 1455 "raphael", 1456 "amplesdk", 1457 "canvg", 1458 "svg-boilerplate", 1459 "sie", 1460 "dojogfx", 1461 "fabricjs" 1462 ] 1463} 1464!*/ 1465/* DOC 1466Detects support for SVG in `<embed>` or `<object>` elements. 1467*/ 1468 1469 Modernizr.addTest('svg', !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect); 1470 1471 1472 /** 1473 * If the browsers follow the spec, then they would expose vendor-specific styles as: 1474 * elem.style.WebkitBorderRadius 1475 * instead of something like the following (which is technically incorrect): 1476 * elem.style.webkitBorderRadius 1477 1478 * WebKit ghosts their properties in lowercase but Opera & Moz do not. 1479 * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ 1480 * erik.eae.net/archives/2008/03/10/21.48.10/ 1481 1482 * More here: github.com/Modernizr/Modernizr/issues/issue/21 1483 * 1484 * @access private 1485 * @returns {string} The string representing the vendor-specific style properties 1486 */ 1487 1488 var omPrefixes = 'Moz O ms Webkit'; 1489 1490 1491 var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []); 1492 ModernizrProto._cssomPrefixes = cssomPrefixes; 1493 1494 1495 /** 1496 * List of JavaScript DOM values used for tests 1497 * 1498 * @memberof Modernizr 1499 * @name Modernizr._domPrefixes 1500 * @optionName Modernizr._domPrefixes 1501 * @optionProp domPrefixes 1502 * @access public 1503 * @example 1504 * 1505 * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather 1506 * than kebab-case properties, all properties are their Capitalized variant 1507 * 1508 * ```js 1509 * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ]; 1510 * ``` 1511 */ 1512 1513 var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []); 1514 ModernizrProto._domPrefixes = domPrefixes; 1515 1516 1517 /** 1518 * testDOMProps is a generic DOM property test; if a browser supports 1519 * a certain property, it won't return undefined for it. 1520 * 1521 * @access private 1522 * @function testDOMProps 1523 * @param {array.<string>} props - An array of properties to test for 1524 * @param {object} obj - An object or Element you want to use to test the parameters again 1525 * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check 1526 * @returns {false|*} returns false if the prop is unsupported, otherwise the value that is supported 1527 */ 1528 function testDOMProps(props, obj, elem) { 1529 var item; 1530 1531 for (var i in props) { 1532 if (props[i] in obj) { 1533 1534 // return the property name as a string 1535 if (elem === false) { 1536 return props[i]; 1537 } 1538 1539 item = obj[props[i]]; 1540 1541 // let's bind a function 1542 if (is(item, 'function')) { 1543 // bind to obj unless overriden 1544 return fnBind(item, elem || obj); 1545 } 1546 1547 // return the unbound function or obj or value 1548 return item; 1549 } 1550 } 1551 return false; 1552 } 1553 1554 ; 1555 1556 /** 1557 * testPropsAll tests a list of DOM properties we want to check against. 1558 * We specify literally ALL possible (known and/or likely) properties on 1559 * the element including the non-vendor prefixed one, for forward- 1560 * compatibility. 1561 * 1562 * @access private 1563 * @function testPropsAll 1564 * @param {string} prop - A string of the property to test for 1565 * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip 1566 * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against 1567 * @param {string} [value] - A string of a css value 1568 * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set 1569 * @returns {false|string} returns the string version of the property, or false if it is unsupported 1570 */ 1571 function testPropsAll(prop, prefixed, elem, value, skipValueTest) { 1572 1573 var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
1574 props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); 1575 1576 // did they call .prefixed('boxSizing') or are we just testing a prop? 1577 if (is(prefixed, 'string') || is(prefixed, 'undefined')) { 1578 return testProps(props, prefixed, value, skipValueTest); 1579 1580 // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) 1581 } else { 1582 props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); 1583 return testDOMProps(props, prefixed, elem); 1584 } 1585 } 1586 1587 // Modernizr.testAllProps() investigates whether a given style property, 1588 // or any of its vendor-prefixed variants, is recognized 1589 // 1590 // Note that the property names must be provided in the camelCase variant. 1591 // Modernizr.testAllProps('boxSizing') 1592 ModernizrProto.testAllProps = testPropsAll; 1593 1594 1595 1596 /** 1597 * testAllProps determines whether a given CSS property is supported in the browser 1598 * 1599 * @memberof Modernizr 1600 * @name Modernizr.testAllProps 1601 * @optionName Modernizr.testAllProps() 1602 * @optionProp testAllProps 1603 * @access public 1604 * @function testAllProps 1605 * @param {string} prop - String naming the property to test (either camelCase or kebab-case) 1606 * @param {string} [value] - String of the value to test 1607 * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection 1608 * @example 1609 * 1610 * testAllProps determines whether a given CSS property, in some prefixed form, 1611 * is supported by the browser. 1612 * 1613 * ```js 1614 * testAllProps('boxSizing') // true 1615 * ``` 1616 * 1617 * It can optionally be given a CSS value in string form to test if a property 1618 * value is valid 1619 * 1620 * ```js 1621 * testAllProps('display', 'block') // true 1622 * testAllProps('display', 'penguin') // false 1623 * ``` 1624 * 1625 * A boolean can be passed as a third parameter to skip the value check when 1626 * native detection (@supports) isn't available. 1627 * 1628 * ```js 1629 * testAllProps('shapeOutside', 'content-box', true); 1630 * ``` 1631 */ 1632 1633 function testAllProps(prop, value, skipValueTest) { 1634 return testPropsAll(prop, undefined, undefined, value, skipValueTest); 1635 } 1636 ModernizrProto.testAllProps = testAllProps; 1637 1638/*! 1639{ 1640 "name": "CSS text-overflow ellipsis", 1641 "property": "ellipsis", 1642 "caniuse": "text-overflow", 1643 "polyfills": [ 1644 "text-overflow" 1645 ], 1646 "tags": ["css"] 1647} 1648!*/ 1649 1650 Modernizr.addTest('ellipsis', testAllProps('textOverflow', 'ellipsis')); 1651 1652/*! 1653{ 1654 "name": "ES6 Arrow Functions", 1655 "property": "arrow", 1656 "authors": ["Vincent Riemer"], 1657 "tags": ["es6"] 1658} 1659!*/ 1660/* DOC 1661Check if browser implements ECMAScript 6 Arrow Functions per specification. 1662*/ 1663 1664 Modernizr.addTest('arrow', function() { 1665 try { 1666 // eslint-disable-next-line 1667 eval('()=>{}'); 1668 } catch (e) { 1669 return false; 1670 } 1671 return true; 1672 }); 1673 1674 1675 // Run each test 1676 testRunner(); 1677 1678 // Remove the "no-js" class if it exists 1679 setClasses(classes); 1680 1681 delete ModernizrProto.addTest; 1682 delete ModernizrProto.addAsyncTest; 1683 1684 // Run the things that are supposed to run after the tests 1685 for (var i = 0; i < Modernizr._q.length; i++) { 1686 Modernizr._q[i](); 1687 } 1688 1689 // Leak Modernizr namespace 1690 window.Modernizr = Modernizr; 1691 1692 1693; 1694 1695})(window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.