PageSourceSearch

https://www.longwood.edu/media/site-assets/public-site/javascript/modernizr-custom.js

js longwood.edu collected 2026-10-01 10:36:33 UTC 59,464 bytes, 1,841 lines download raw bytes

1/*!
2 * modernizr v3.3.1
3 * Build http://modernizr.com/download?-csstransforms-details-ellipsis-search-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.3.1',
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            /* jshint -W053 */
163            if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
164              Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
165            }
166
167            Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
168          }
169
170          classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
171        }
172      }
173    }
174  }
175  ;
176
177  /**
178   * docElement is a convenience wrapper to grab the root element of the document
179   *
180   * @access private
181   * @returns {HTMLElement|SVGElement} The root element of the document
182   */
183
184  var docElement = document.documentElement;
185  
186
187  /**
188   * A convenience helper to check if the document we are running in is an SVG document
189   *
190   * @access private
191   * @returns {boolean}
192   */
193
194  var isSVG = docElement.nodeName.toLowerCase() === 'svg';
195  
196
197  /**
198   * setClasses takes an array of class names and adds them to the root element
199   *
200   * @access private
201   * @function setClasses
202   * @param {string[]} classes - Array of class names
203   */
204
205  // Pass in an and array of class names, e.g.:
206  //  ['no-webp', 'borderradius', ...]
207  function setClasses(classes) {
208    var className = docElement.className;
209    var classPrefix = Modernizr._config.classPrefix || '';
210
211    if (isSVG) {
212      className = className.baseVal;
213    }
214
215    // Change `no-js` to `js` (independently of the `enableClasses` option)
216    // Handle classPrefix on this too
217    if (Modernizr._config.enableJSClass) {
218      var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
219      className = className.replace(reJS, '$1' + classPrefix + 'js$2');
220    }
221
222    if (Modernizr._config.enableClasses) {
223      // Add the new classes
224      className += ' ' + classPrefix + classes.join(' ' + classPrefix);
225      isSVG ? docElement.className.baseVal = className : docElement.className = className;
226    }
227
228  }
229
230  ;
231
232  /**
233   * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support
234   *
235   * @author kangax
236   * @access private
237   * @function hasOwnProp
238   * @param {object} object - The object to check for a property
239   * @param {string} property - The property to check for
240   * @returns {boolean}
241   */
242
243  // hasOwnProperty shim by kangax needed for Safari 2.0 support
244  var hasOwnProp;
245
246  (function() {
247    var _hasOwnProperty = ({}).hasOwnProperty;
248    /* istanbul ignore else */
249    /* we have no way of testing IE 5.5 or safari 2,
250     * so just assume the else gets hit */
251    if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
252      hasOwnProp = function(object, property) {
253        return _hasOwnProperty.call(object, property);
254      };
255    }
256    else {
257      hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
258        return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
259      };
260    }
261  })();
262
263  
264
265
266   // _l tracks listeners for async tests, as well as tests that execute after the initial run
267  ModernizrProto._l = {};
268
269  /**
270   * Modernizr.on is a way to listen for the completion of async tests. Being
271   * asynchronous, they may not finish before your scripts run. As a result you
272   * will get a possibly false negative `undefined` value.
273   *
274   * @memberof Modernizr
275   * @name Modernizr.on
276   * @access public
277   * @function on
278   * @param {string} feature - String name of the feature detect
279   * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not
280   * @example
281   *
282   * ```js
283   * Modernizr.on('flash', function( result ) {
284   *   if (result) {
285   *    // the browser has flash
286   *   } else {
287   *     // the browser does not have flash
288   *   }
289   * });
290   * ```
291   */
292
293  ModernizrProto.on = function(feature, cb) {
294    // Create the list of listeners if it doesn't exist
295    if (!this._l[feature]) {
296      this._l[feature] = [];
297    }
298
299    // Push this test on to the listener list
300    this._l[feature].push(cb);
301
302    // If it's already been resolved, trigger it on next tick
303    if (Modernizr.hasOwnProperty(feature)) {
304      // Next Tick
305      setTimeout(function() {
306        Modernizr._trigger(feature, Modernizr[feature]);
307      }, 0);
308    }
309  };
310
311  /**
312   * _trigger is the private function used to signal test completion and run any
313   * callbacks registered through [Modernizr.on](#modernizr-on)
314   *
315   * @memberof Modernizr
316   * @name Modernizr._trigger
317   * @access private
318   * @function _trigger
319   * @param {string} feature - string name of the feature detect
320   * @param {function|boolean} [res] - A feature detection function, or the boolean =
321   * result of a feature detection function
322   */
323
324  ModernizrProto._trigger = function(feature, res) {
325    if (!this._l[feature]) {
326      return;
327    }
328
329    var cbs = this._l[feature];
330
331    // Force async
332    setTimeout(function() {
333      var i, cb;
334      for (i = 0; i < cbs.length; i++) {
335        cb = cbs[i];
336        cb(res);
337      }
338    }, 0);
339
340    // Don't trigger these again
341    delete this._l[feature];
342  };
343
344  /**
345   * addTest allows you to define your own feature detects that are not currently
346   * included in Modernizr (under the covers it's the exact same code Modernizr
347   * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result
348   * will be added onto the Modernizr object, as well as an appropriate className set on
349   * the html element when configured to do so
350   *
351   * @memberof Modernizr
352   * @name Modernizr.addTest
353   * @optionName Modernizr.addTest()
354   * @optionProp addTest
355   * @access public
356   * @function addTest
357   * @param {string|object} feature - The string name of the feature detect, or an
358   * object of feature detect names and test
359   * @param {function|boolean} test - Function returning true if feature is supported,
360   * false if not. Otherwise a boolean representing the results of a feature detection
361   * @example
362   *
363   * The most common way of creating your own feature detects is by calling
364   * `Modernizr.addTest` with a string (preferably just lowercase, without any
365   * punctuation), and a function you want executed that will return a boolean result
366   *
367   * ```js
368   * Modernizr.addTest('itsTuesday', function() {
369   *  var d = new Date();
370   *  return d.getDay() === 2;
371   * });
372   * ```
373   *
374   * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday,
375   * and to `false` every other day of the week. One thing to notice is that the names of
376   * feature detect functions are always lowercased when added to the Modernizr object. That
377   * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will.
378   *
379   *
380   *  Since we only look at the returned value from any feature detection function,
381   *  you do not need to actually use a function. For simple detections, just passing
382   *  in a statement that will return a boolean value works just fine.
383   *
384   * ```js
385   * Modernizr.addTest('hasJquery', 'jQuery' in window);
386   * ```
387   *
388   * Just like before, when the above runs `Modernizr.hasjquery` will be true if
389   * jQuery has been included on the page. Not using a function saves a small amount
390   * of overhead for the browser, as well as making your code much more readable.
391   *
392   * Finally, you also have the ability to pass in an object of feature names and
393   * their tests. This is handy if you want to add multiple detections in one go.
394   * The keys should always be a string, and the value can be either a boolean or
395   * function that returns a boolean.
396   *
397   * ```js
398   * var detects = {
399   *  'hasjquery': 'jQuery' in window,
400   *  'itstuesday': function() {
401   *    var d = new Date();
402   *    return d.getDay() === 2;
403   *  }
404   * }
405   *
406   * Modernizr.addTest(detects);
407   * ```
408   *
409   * There is really no difference between the first methods and this one, it is
410   * just a convenience to let you write more readable code.
411   */
412
413  function addTest(feature, test) {
414
415    if (typeof feature == 'object') {
416      for (var key in feature) {
417        if (hasOwnProp(feature, key)) {
418          addTest(key, feature[ key ]);
419        }
420      }
421    } else {
422
423      feature = feature.toLowerCase();
424      var featureNameSplit = feature.split('.');
425      var last = Modernizr[featureNameSplit[0]];
426
427      // Again, we don't check for parent test existence. Get that right, though.
428      if (featureNameSplit.length == 2) {
429        last = last[featureNameSplit[1]];
430      }
431
432      if (typeof last != 'undefined') {
433        // we're going to quit if you're trying to overwrite an existing test
434        // if we were to allow it, we'd do this:
435        //   var re = new RegExp("\\b(no-)?" + feature + "\\b");
436        //   docElement.className = docElement.className.replace( re, '' );
437        // but, no rly, stuff 'em.
438        return Modernizr;
439      }
440
441      test = typeof test == 'function' ? test() : test;
442
443      // Set the value (this is the magic, right here).
444      if (featureNameSplit.length == 1) {
445        Modernizr[featureNameSplit[0]] = test;
446      } else {
447        // cast to a Boolean, if not one already
448        /* jshint -W053 */
449        if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
450          Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
451        }
452
453        Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test;
454      }
455
456      // Set a single class (either `feature` or `no-feature`)
457      /* jshint -W041 */
458      setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]);
459      /* jshint +W041 */
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      /*jshint evil:true */
490      /** version */
491      var version = '3.7.3';
492
493      /** Preset options */
494      var options = window.html5 || {};
495
496      /** Used to skip problem elements */
497      var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
498
499      /** Not all elements can be cloned in IE **/
500      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;
501
502      /** Detect whether the browser supports default html5 styles */
503      var supportsHtml5Styles;
504
505      /** Name of the expando, to work with multiple documents or to re-shiv one document */
506      var expando = '_html5shiv';
507
508      /** The id for the the documents expando */
509      var expanID = 0;
510
511      /** Cached data for each document */
512      var expandoData = {};
513
514      /** Detect whether the browser supports unknown elements */
515      var supportsUnknownElements;
516
517      (function() {
518        try {
519          var a = document.createElement('a');
520          a.innerHTML = '<xyz></xyz>';
521          //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
522          supportsHtml5Styles = ('hidden' in a);
523
524          supportsUnknownElements = a.childNodes.length == 1 || (function() {
525            // assign a false positive if unable to shiv
526            (document.createElement)('a');
527            var frag = document.createDocumentFragment();
528            return (
529              typeof frag.cloneNode == 'undefined' ||
530                typeof frag.createDocumentFragment == 'undefined' ||
531                typeof frag.createElement == 'undefined'
532            );
533          }());
534        } catch(e) {
535          // assign a false positive if detection fails => unable to shiv
536          supportsHtml5Styles = true;
537          supportsUnknownElements = true;
538        }
539
540      }());
541
542      /*--------------------------------------------------------------------------*/
543
544      /**
545       * Creates a style sheet with the given CSS text and adds it to the document.
546       * @private
547       * @param {Document} ownerDocument The document.
548       * @param {String} cssText The CSS text.
549       * @returns {StyleSheet} The style element.
550       */
551      function addStyleSheet(ownerDocument, cssText) {
552        var p = ownerDocument.createElement('p'),
553          parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
554
555        p.innerHTML = 'x<style>' + cssText + '</style>';
556        return parent.insertBefore(p.lastChild, parent.firstChild);
557      }
558
559      /**
560       * Returns the value of `html5.elements` as an array.
vendor: 5,922 bytes, lines 561-718
561       * @private
562       * @returns {Array} An array of shived element node names.
563       */
564      function getElements() {
565        var elements = html5.elements;
566        return typeof elements == 'string' ? elements.split(' ') : elements;
567      }
568
569      /**
570       * Extends the built-in list of html5 elements
571       * @memberOf html5
572       * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
573       * @param {Document} ownerDocument The context document.
574       */
575      function addElements(newElements, ownerDocument) {
576        var elements = html5.elements;
577        if(typeof elements != 'string'){
578          elements = elements.join(' ');
579        }
580        if(typeof newElements != 'string'){
581          newElements = newElements.join(' ');
582        }
583        html5.elements = elements +' '+ newElements;
584        shivDocument(ownerDocument);
585      }
586
587      /**
588       * Returns the data associated to the given document
589       * @private
590       * @param {Document} ownerDocument The document.
591       * @returns {Object} An object of data.
592       */
593      function getExpandoData(ownerDocument) {
594        var data = expandoData[ownerDocument[expando]];
595        if (!data) {
596          data = {};
597          expanID++;
598          ownerDocument[expando] = expanID;
599          expandoData[expanID] = data;
600        }
601        return data;
602      }
603
604      /**
605       * returns a shived element for the given nodeName and document
606       * @memberOf html5
607       * @param {String} nodeName name of the element
608       * @param {Document} ownerDocument The context document.
609       * @returns {Object} The shived element.
610       */
611      function createElement(nodeName, ownerDocument, data){
612        if (!ownerDocument) {
613          ownerDocument = document;
614        }
615        if(supportsUnknownElements){
616          return ownerDocument.createElement(nodeName);
617        }
618        if (!data) {
619          data = getExpandoData(ownerDocument);
620        }
621        var node;
622
623        if (data.cache[nodeName]) {
624          node = data.cache[nodeName].cloneNode();
625        } else if (saveClones.test(nodeName)) {
626          node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
627        } else {
628          node = data.createElem(nodeName);
629        }
630
631        // Avoid adding some elements to fragments in IE < 9 because
632        // * Attributes like `name` or `type` cannot be set/changed once an element
633        //   is inserted into a document/fragment
634        // * Link elements with `src` attributes that are inaccessible, as with
635        //   a 403 response, will cause the tab/window to crash
636        // * Script elements appended to fragments will execute when their `src`
637        //   or `text` property is set
638        return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
639      }
640
641      /**
642       * returns a shived DocumentFragment for the given document
643       * @memberOf html5
644       * @param {Document} ownerDocument The context document.
645       * @returns {Object} The shived DocumentFragment.
646       */
647      function createDocumentFragment(ownerDocument, data){
648        if (!ownerDocument) {
649          ownerDocument = document;
650        }
651        if(supportsUnknownElements){
652          return ownerDocument.createDocumentFragment();
653        }
654        data = data || getExpandoData(ownerDocument);
655        var clone = data.frag.cloneNode(),
656          i = 0,
657          elems = getElements(),
658          l = elems.length;
659        for(;i<l;i++){
660          clone.createElement(elems[i]);
661        }
662        return clone;
663      }
664
665      /**
666       * Shivs the `createElement` and `createDocumentFragment` methods of the document.
667       * @private
668       * @param {Document|DocumentFragment} ownerDocument The document.
669       * @param {Object} data of the document.
670       */
671      function shivMethods(ownerDocument, data) {
672        if (!data.cache) {
673          data.cache = {};
674          data.createElem = ownerDocument.createElement;
675          data.createFrag = ownerDocument.createDocumentFragment;
676          data.frag = data.createFrag();
677        }
678
679
680        ownerDocument.createElement = function(nodeName) {
681          //abort shiv
682          if (!html5.shivMethods) {
683            return data.createElem(nodeName);
684          }
685          return createElement(nodeName, ownerDocument, data);
686        };
687
688        ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
689                                                        'var n=f.cloneNode(),c=n.createElement;' +
690                                                        'h.shivMethods&&(' +
691                                                        // unroll the `createElement` calls
692                                                        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
693          data.createElem(nodeName);
694          data.frag.createElement(nodeName);
695          return 'c("' + nodeName + '")';
696        }) +
697          ');return n}'
698                                                       )(html5, data.frag);
699      }
700
701      /*--------------------------------------------------------------------------*/
702
703      /**
704       * Shivs the given document.
705       * @memberOf html5
706       * @param {Document} ownerDocument The document to shiv.
707       * @returns {Document} The shived document.
708       */
709      function shivDocument(ownerDocument) {
710        if (!ownerDocument) {
711          ownerDocument = document;
712        }
713        var data = getExpandoData(ownerDocument);
714
715        if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
716          data.hasCSS = !!addStyleSheet(ownerDocument,
717                                        // corrects block display not defined in IE6/7/8/9
718                                        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
718play:block}' +
719                                        // adds styling not present in IE6/7/8/9
720                                        'mark{background:#FF0;color:#000}' +
721                                        // hides non-rendered elements
722                                        'template{display:none}'
723                                       );
724        }
725        if (!supportsUnknownElements) {
726          shivMethods(ownerDocument, data);
727        }
728        return ownerDocument;
729      }
730
731      /*--------------------------------------------------------------------------*/
732
733      /**
734       * The `html5` object is exposed so that more elements can be shived and
735       * existing shiving can be detected on iframes.
736       * @type Object
737       * @example
738       *
739       * // options can be changed before the script is included
740       * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
741       */
742      var html5 = {
743
744        /**
745         * An array or space separated string of node names of the elements to shiv.
746         * @memberOf html5
747         * @type Array|String
748         */
749        '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',
750
751        /**
752         * current version of html5shiv
753         */
754        'version': version,
755
756        /**
757         * A flag to indicate that the HTML5 style sheet should be inserted.
758         * @memberOf html5
759         * @type Boolean
760         */
761        'shivCSS': (options.shivCSS !== false),
762
763        /**
764         * Is equal to true if a browser supports creating unknown/HTML5 elements
765         * @memberOf html5
766         * @type boolean
767         */
768        'supportsUnknownElements': supportsUnknownElements,
769
770        /**
771         * A flag to indicate that the document's `createElement` and `createDocumentFragment`
772         * methods should be overwritten.
773         * @memberOf html5
774         * @type Boolean
775         */
776        'shivMethods': (options.shivMethods !== false),
777
778        /**
779         * A string to describe the type of `html5` object ("default" or "default print").
780         * @memberOf html5
vendor: 7,715 bytes, lines 781-1024
781         * @type String
782         */
783        'type': 'default',
784
785        // shivs the document according to the specified `html5` object options
786        'shivDocument': shivDocument,
787
788        //creates a shived element
789        createElement: createElement,
790
791        //creates a shived documentFragment
792        createDocumentFragment: createDocumentFragment,
793
794        //extends list of elements
795        addElements: addElements
796      };
797
798      /*--------------------------------------------------------------------------*/
799
800      // expose html5
801      window.html5 = html5;
802
803      // shiv the document
804      shivDocument(document);
805
806      /*------------------------------- Print Shiv -------------------------------*/
807
808      /** Used to filter media types */
809      var reMedia = /^$|\b(?:all|print)\b/;
810
811      /** Used to namespace printable elements */
812      var shivNamespace = 'html5shiv';
813
814      /** Detect whether the browser supports shivable style sheets */
815      var supportsShivableSheets = !supportsUnknownElements && (function() {
816        // assign a false negative if unable to shiv
817        var docEl = document.documentElement;
818        return !(
819          typeof document.namespaces == 'undefined' ||
820            typeof document.parentWindow == 'undefined' ||
821            typeof docEl.applyElement == 'undefined' ||
822            typeof docEl.removeNode == 'undefined' ||
823            typeof window.attachEvent == 'undefined'
824        );
825      }());
826
827      /*--------------------------------------------------------------------------*/
828
829      /**
830       * Wraps all HTML5 elements in the given document with printable elements.
831       * (eg. the "header" element is wrapped with the "html5shiv:header" element)
832       * @private
833       * @param {Document} ownerDocument The document.
834       * @returns {Array} An array wrappers added.
835       */
836      function addWrappers(ownerDocument) {
837        var node,
838        nodes = ownerDocument.getElementsByTagName('*'),
839          index = nodes.length,
840          reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'),
841          result = [];
842
843        while (index--) {
844          node = nodes[index];
845          if (reElements.test(node.nodeName)) {
846            result.push(node.applyElement(createWrapper(node)));
847          }
848        }
849        return result;
850      }
851
852      /**
853       * Creates a printable wrapper for the given element.
854       * @private
855       * @param {Element} element The element.
856       * @returns {Element} The wrapper.
857       */
858      function createWrapper(element) {
859        var node,
860        nodes = element.attributes,
861          index = nodes.length,
862          wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName);
863
864        // copy element attributes to the wrapper
865        while (index--) {
866          node = nodes[index];
867          node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue);
868        }
869        // copy element styles to the wrapper
870        wrapper.style.cssText = element.style.cssText;
871        return wrapper;
872      }
873
874      /**
875       * Shivs the given CSS text.
876       * (eg. header{} becomes html5shiv\:header{})
877       * @private
878       * @param {String} cssText The CSS text to shiv.
879       * @returns {String} The shived CSS text.
880       */
881      function shivCssText(cssText) {
882        var pair,
883        parts = cssText.split('{'),
884          index = parts.length,
885          reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
886          replacement = '$1' + shivNamespace + '\\:$2';
887
888        while (index--) {
889          pair = parts[index] = parts[index].split('}');
890          pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
891          parts[index] = pair.join('}');
892        }
893        return parts.join('{');
894      }
895
896      /**
897       * Removes the given wrappers, leaving the original elements.
898       * @private
899       * @params {Array} wrappers An array of printable wrappers.
900       */
901      function removeWrappers(wrappers) {
902        var index = wrappers.length;
903        while (index--) {
904          wrappers[index].removeNode();
905        }
906      }
907
908      /*--------------------------------------------------------------------------*/
909
910      /**
911       * Shivs the given document for print.
912       * @memberOf html5
913       * @param {Document} ownerDocument The document to shiv.
914       * @returns {Document} The shived document.
915       */
916      function shivPrint(ownerDocument) {
917        var shivedSheet,
918        wrappers,
919        data = getExpandoData(ownerDocument),
920          namespaces = ownerDocument.namespaces,
921          ownerWindow = ownerDocument.parentWindow;
922
923        if (!supportsShivableSheets || ownerDocument.printShived) {
924          return ownerDocument;
925        }
926        if (typeof namespaces[shivNamespace] == 'undefined') {
927          namespaces.add(shivNamespace);
928        }
929
930        function removeSheet() {
931          clearTimeout(data._removeSheetTimer);
932          if (shivedSheet) {
933            shivedSheet.removeNode(true);
934          }
935          shivedSheet= null;
936        }
937
938        ownerWindow.attachEvent('onbeforeprint', function() {
939
940          removeSheet();
941
942          var imports,
943          length,
944          sheet,
945          collection = ownerDocument.styleSheets,
946            cssText = [],
947            index = collection.length,
948            sheets = Array(index);
949
950          // convert styleSheets collection to an array
951          while (index--) {
952            sheets[index] = collection[index];
953          }
954          // concat all style sheet CSS text
955          while ((sheet = sheets.pop())) {
956            // IE does not enforce a same origin policy for external style sheets...
957            // but has trouble with some dynamically created stylesheets
958            if (!sheet.disabled && reMedia.test(sheet.media)) {
959
960              try {
961                imports = sheet.imports;
962                length = imports.length;
963              } catch(er){
964                length = 0;
965              }
966
967              for (index = 0; index < length; index++) {
968                sheets.push(imports[index]);
969              }
970
971              try {
972                cssText.push(sheet.cssText);
973              } catch(er){}
974            }
975          }
976
977          // wrap all HTML5 elements with printable elements and add the shived style sheet
978          cssText = shivCssText(cssText.reverse().join(''));
979          wrappers = addWrappers(ownerDocument);
980          shivedSheet = addStyleSheet(ownerDocument, cssText);
981
982        });
983
984        ownerWindow.attachEvent('onafterprint', function() {
985          // remove wrappers, leaving the original elements, and remove the shived style sheet
986          removeWrappers(wrappers);
987          clearTimeout(data._removeSheetTimer);
988          data._removeSheetTimer = setTimeout(removeSheet, 500);
989        });
990
991        ownerDocument.printShived = true;
992        return ownerDocument;
993      }
994
995      /*--------------------------------------------------------------------------*/
996
997      // expose API
998      html5.type += ' print';
999      html5.shivPrint = shivPrint;
1000
1001      // shiv for print
1002      shivPrint(document);
1003
1004      if(typeof module == 'object' && module.exports){
1005        module.exports = html5;
1006      }
1007
1008    }(typeof window !== "undefined" ? window : this, document));
1009  }
1010
1011  ;
1012
1013
1014  /**
1015   * contains checks to see if a string contains another string
1016   *
1017   * @access private
1018   * @function contains
1019   * @param {string} str - The string we want to check for substrings
1020   * @param {string} substr - The substring we want to search the first string for
1021   * @returns {boolean}
1022   */
1023
1024  function contains(str, substr) {
1025    return !!~('' + str).indexOf(substr);
1026  }
1027
1028  ;
1029
1030  /**
1031   * createElement is a convenience wrapper around document.createElement. Since we
1032   * use createElement all over the place, this allows for (slightly) smaller code
1033   * as well as abstracting away issues with creating elements in contexts other than
1034   * HTML documents (e.g. SVG documents).
1035   *
1036   * @access private
1037   * @function createElement
1038   * @returns {HTMLElement|SVGElement} An HTML or SVG element
1039   */
1040
1041  function createElement() {
1042    if (typeof document.createElement !== 'function') {
1043      // This is the case in IE7, where the type of createElement is "object".
1044      // For this reason, we cannot call apply() as Object is not a Function.
1045      return document.createElement(arguments[0]);
1046    } else if (isSVG) {
1047      return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);
1048    } else {
1049      return document.createElement.apply(document, arguments);
1050    }
1051  }
1052
1053  ;
1054
1055  /**
1056   * Create our "modernizr" element that we do most feature tests on.
1057   *
1058   * @access private
1059   */
1060
1061  var modElem = {
1062    elem: createElement('modernizr')
1063  };
1064
1065  // Clean up this element
1066  Modernizr._q.push(function() {
1067    delete modElem.elem;
1068  });
1069
1070  
1071
1072  var mStyle = {
1073    style: modElem.elem.style
1074  };
1075
1076  // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
1077  // the front of the queue.
1078  Modernizr._q.unshift(function() {
1079    delete mStyle.style;
1080  });
1081
1082  
1083
1084  /**
1085   * getBody returns the body of a document, or an element that can stand in for
1086   * the body if a real body does not exist
1087   *
1088   * @access private
1089   * @function getBody
1090   * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an
1091   * artificially created element that stands in for the body
1092   */
1093
1094  function getBody() {
1095    // After page load injecting a fake body doesn't work so check if body exists
1096    var body = document.body;
1097
1098    if (!body) {
1099      // Can't use the real body create a fake one.
1100      body = createElement(isSVG ? 'svg' : 'body');
1101      body.fake = true;
1102    }
1103
1104    return body;
1105  }
1106
1107  ;
1108
1109  /**
1110   * injectElementWithStyles injects an element with style element and some CSS rules
1111   *
1112   * @access private
1113   * @function injectElementWithStyles
1114   * @param {string} rule - String representing a css rule
1115   * @param {function} callback - A function that is used to test the injected element
1116   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
1117   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
1118   * @returns {boolean}
1119   */
1120
1121  function injectElementWithStyles(rule, callback, nodes, testnames) {
1122    var mod = 'modernizr';
1123    var style;
1124    var ret;
1125    var node;
1126    var docOverflow;
1127    var div = createElement('div');
1128    var body = getBody();
1129
1130    if (parseInt(nodes, 10)) {
1131      // In order not to give false positives we create a node for each test
1132      // This also allows the method to scale for unspecified uses
1133      while (nodes--) {
1134        node = createElement('div');
1135        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
1136        div.appendChild(node);
1137      }
1138    }
1139
1140    style = createElement('style');
1141    style.type = 'text/css';
1142    style.id = 's' + mod;
1143
1144    // 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.
1145    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
1146    (!body.fake ? div : body).appendChild(style);
1147    body.appendChild(div);
1148
1149    if (style.styleSheet) {
1150      style.styleSheet.cssText = rule;
1151    } else {
1152      style.appendChild(document.createTextNode(rule));
1153    }
1154    div.id = mod;
1155
1156    if (body.fake) {
1157      //avoid crashing IE8, if background image is used
1158      body.style.background = '';
1159      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
1160      body.style.overflow = 'hidden';
1161      docOverflow = docElement.style.overflow;
1162      docElement.style.overflow = 'hidden';
1163      docElement.appendChild(body);
1164    }
1165
1166    ret = callback(div, rule);
1167    // If this is done after page load we don't want to remove the body so check if body exists
1168    if (body.fake) {
1169      body.parentNode.removeChild(body);
1170      docElement.style.overflow = docOverflow;
1171      // Trigger layout so kinetic scrolling isn't disabled in iOS6+
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   * nativeTestProps allows for us to use native feature detection functionality if available.
1202   * some prefixed form, or false, in the case of an unsupported rule
1203   *
1204   * @access private
1205   * @function nativeTestProps
1206   * @param {array} props - An array of property names
1207   * @param {string} value - A string representing the value we want to check via @supports
1208   * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
1209   */
1210
1211  // Accepts a list of property names and a single value
1212  // Returns `undefined` if native detection not available
1213  function nativeTestProps(props, value) {
1214    var i = props.length;
1215    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
1216    if ('CSS' in window && 'supports' in window.CSS) {
1217      // Try every prefixed variant of the property
1218      while (i--) {
1219        if (window.CSS.supports(domToCSS(props[i]), value)) {
1220          return true;
1221        }
1222      }
1223      return false;
1224    }
1225    // Otherwise fall back to at-rule (for Opera 12.x)
1226    else if ('CSSSupportsRule' in window) {
1227      // Build a condition string for every prefixed variant
1228      var conditionText = [];
1229      while (i--) {
1230        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
1231      }
1232      conditionText = conditionText.join(' or ');
1233      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
1234        return getComputedStyle(node, null).position == 'absolute';
1235      });
1236    }
1237    return undefined;
1238  }
1239  ;
1240
1241  /**
1242   * cssToDOM takes a kebab-case string and converts it to camelCase
1243   * e.g. box-sizing -> boxSizing
1244   *
1245   * @access private
1246   * @function cssToDOM
1247   * @param {string} name - String name of kebab-case prop we want to convert
1248   * @returns {string} The camelCase version of the supplied name
1249   */
1250
1251  function cssToDOM(name) {
1252    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
1253      return m1 + m2.toUpperCase();
1254    }).replace(/^-/, '');
1255  }
1256  ;
1257
1258  // testProps is a generic CSS / DOM property test.
1259
1260  // In testing support for a given CSS property, it's legit to test:
1261  //    `elem.style[styleName] !== undefined`
1262  // If the property is supported it will return an empty string,
1263  // if unsupported it will return undefined.
1264
1265  // We'll take advantage of this quick test and skip setting a style
1266  // on our modernizr element, but instead just testing undefined vs
1267  // empty string.
1268
1269  // Property names can be provided in either camelCase or kebab-case.
1270
1271  function testProps(props, prefixed, value, skipValueTest) {
1272    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
1273
1274    // Try native detect first
1275    if (!is(value, 'undefined')) {
1276      var result = nativeTestProps(props, value);
1277      if (!is(result, 'undefined')) {
1278        return result;
1279      }
1280    }
1281
1282    // Otherwise do it properly
1283    var afterInit, i, propsLength, prop, before;
1284
1285    // If we don't have a style element, that means we're running async or after
1286    // the core tests, so we'll need to create our own elements to use
1287
1288    // inside of an SVG element, in certain browsers, the `style` element is only
1289    // defined for valid tags. Therefore, if `modernizr` does not have one, we
1290    // fall back to a less used element and hope for the best.
1291    var elems = ['modernizr', 'tspan'];
1292    while (!mStyle.style) {
1293      afterInit = true;
1294      mStyle.modElem = createElement(elems.shift());
1295      mStyle.style = mStyle.modElem.style;
1296    }
1297
1298    // Delete the objects if we created them.
1299    function cleanElems() {
1300      if (afterInit) {
1301        delete mStyle.style;
1302        delete mStyle.modElem;
1303      }
1304    }
1305
1306    propsLength = props.length;
1307    for (i = 0; i < propsLength; i++) {
1308      prop = props[i];
1309      before = mStyle.style[prop];
1310
1311      if (contains(prop, '-')) {
1312        prop = cssToDOM(prop);
1313      }
1314
1315      if (mStyle.style[prop] !== undefined) {
1316
1317        // If value to test has been passed in, do a set-and-check test.
1318        // 0 (integer) is a valid property value, so check that `value` isn't
1319        // undefined, rather than just checking it's truthy.
1320        if (!skipValueTest && !is(value, 'undefined')) {
1321
1322          // Needs a try catch block because of old IE. This is slow, but will
1323          // be avoided in most cases because `skipValueTest` will be used.
1324          try {
1325            mStyle.style[prop] = value;
1326          } catch (e) {}
1327
1328          // If the property value has changed, we assume the value used is
1329          // supported. If `value` is empty string, it'll fail here (because
1330          // it hasn't changed), which matches how browsers have implemented
1331          // CSS.supports()
1332          if (mStyle.style[prop] != before) {
1333            cleanElems();
1334            return prefixed == 'pfx' ? prop : true;
1335          }
1336        }
1337        // Otherwise just return true, or the property name if this is a
1338        // `prefixed()` call
1339        else {
1340          cleanElems();
1341          return prefixed == 'pfx' ? prop : true;
1342        }
1343      }
1344    }
1345    cleanElems();
1346    return false;
1347  }
1348
1349  ;
1350
1351  /**
1352   * testProp() investigates whether a given style property is recognized
1353   * Property names can be provided in either camelCase or kebab-case.
1354   *
1355   * @memberof Modernizr
1356   * @name Modernizr.testProp
1357   * @access public
1358   * @optionName Modernizr.testProp()
1359   * @optionProp testProp
1360   * @function testProp
1361   * @param {string} prop - Name of the CSS property to check
1362   * @param {string} [value] - Name of the CSS value to check
1363   * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
1364   * @returns {boolean}
1365   * @example
1366   *
1367   * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
1368   * version of the string.
1369   *
1370   * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
1371   *
1372   * ```js
1373   * Modernizr.testProp('pointerEvents')  // true
1374   * ```
1375   *
1376   * You can also provide a value as an optional second argument to check if a
1377   * specific value is supported
1378   *
1379   * ```js
1380   * Modernizr.testProp('pointerEvents', 'none') // true
1381   * Modernizr.testProp('pointerEvents', 'penguin') // false
1382   * ```
1383   */
1384
1385  var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
1386    return testProps([prop], undefined, value, useValue);
1387  };
1388  
1389
1390  /**
1391   * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
1392   *
1393   * @access private
1394   * @function fnBind
1395   * @param {function} fn - a function you want to change `this` reference to
1396   * @param {object} that - the `this` you want to call the function with
1397   * @returns {function} The wrapped version of the supplied function
1398   */
1399
1400  function fnBind(fn, that) {
1401    return function() {
1402      return fn.apply(that, arguments);
1403    };
1404  }
1405
1406  ;
1407
1408  /**
1409   * Modernizr.hasEvent() detects support for a given event
1410   *
1411   * @memberof Modernizr
1412   * @name Modernizr.hasEvent
1413   * @optionName Modernizr.hasEvent()
1414   * @optionProp hasEvent
1415   * @access public
1416   * @function hasEvent
1417   * @param  {string|*} eventName - the name of an event to test for (e.g. "resize")
1418   * @param  {Element|string} [element=HTMLDivElement] - is the element|document|window|tagName to test on
1419   * @returns {boolean}
1420   * @example
1421   *  `Modernizr.hasEvent` lets you determine if the browser supports a supplied event.
1422   *  By default, it does this detection on a div element
1423   *
1424   * ```js
1425   *  hasEvent('blur') // true;
1426   * ```
1427   *
1428   * However, you are able to give an object as a second argument to hasEvent to
1429   * detect an event on something other than a div.
1430   *
1431   * ```js
1432   *  hasEvent('devicelight', window) // true;
1433   * ```
1434   *
1435   */
1436
1437  var hasEvent = (function() {
1438
1439    // Detect whether event support can be detected via `in`. Test on a DOM element
1440    // using the "blur" event b/c it should always exist. bit.ly/event-detection
1441    var needsFallback = !('onblur' in document.documentElement);
1442
1443    function inner(eventName, element) {
1444
1445      var isSupported;
1446      if (!eventName) { return false; }
1447      if (!element || typeof element === 'string') {
1448        element = createElement(element || 'div');
1449      }
1450
1451      // Testing via the `in` operator is sufficient for modern browsers and IE.
1452      // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and
1453      // "resize", whereas `in` "catches" those.
1454      eventName = 'on' + eventName;
1455      isSupported = eventName in element;
1456
1457      // Fallback technique for old Firefox - bit.ly/event-detection
1458      if (!isSupported && needsFallback) {
1459        if (!element.setAttribute) {
1460          // Switch to generic element if it lacks `setAttribute`.
1461          // It could be the `document`, `window`, or something else.
1462          element = createElement('div');
1463        }
1464
1465        element.setAttribute(eventName, '');
1466        isSupported = typeof element[eventName] === 'function';
1467
1468        if (element[eventName] !== undefined) {
1469          // If property was created, "remove it" by setting value to `undefined`.
1470          element[eventName] = undefined;
1471        }
1472        element.removeAttribute(eventName);
1473      }
1474
1475      return isSupported;
1476    }
1477    return inner;
1478  })();
1479
1480
1481  ModernizrProto.hasEvent = hasEvent;
1482  
1483/*!
1484{
1485  "name": "input[search] search event",
1486  "property": "search",
1487  "tags": ["input","search"],
1488  "authors": ["Calvin Webster"],
1489  "notes": [{
1490    "name": "Wufoo demo",
1491    "href": "https://www.wufoo.com/html5/types/5-search.html?"
1492  }, {
1493    "name": "CSS Tricks",
1494    "href": "https://css-tricks.com/webkit-html5-search-inputs/"
1495  }]
1496}
1497!*/
1498/* DOC
1499There is a custom `search` event implemented in webkit browsers when using an `input[search]` element.
1500*/
1501
1502  Modernizr.addTest('inputsearchevent',  hasEvent('search'));
1503
1504/*!
1505{
1506  "name": "SVG",
1507  "property": "svg",
1508  "caniuse": "svg",
1509  "tags": ["svg"],
1510  "authors": ["Erik Dahlstrom"],
1511  "polyfills": [
1512    "svgweb",
1513    "raphael",
1514    "amplesdk",
1515    "canvg",
1516    "svg-boilerplate",
1517    "sie",
1518    "dojogfx",
1519    "fabricjs"
1520  ]
1521}
1522!*/
1523/* DOC
1524Detects support for SVG in `<embed>` or `<object>` elements.
1525*/
1526
1527  Modernizr.addTest('svg', !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect);
1528
1529
1530  /**
1531   * If the browsers follow the spec, then they would expose vendor-specific style as:
1532   *   elem.style.WebkitBorderRadius
1533   * instead of something like the following, which would be technically incorrect:
1534   *   elem.style.webkitBorderRadius
1535
1536   * Webkit ghosts their properties in lowercase but Opera & Moz do not.
1537   * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
1538   *   erik.eae.net/archives/2008/03/10/21.48.10/
1539
1540   * More here: github.com/Modernizr/Modernizr/issues/issue/21
1541   *
1542   * @access private
1543   * @returns {string} The string representing the vendor-specific style properties
1544   */
1545
1546  var omPrefixes = 'Moz O ms Webkit';
1547  
1548
1549  var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
1550  ModernizrProto._cssomPrefixes = cssomPrefixes;
1551  
1552
1553  /**
1554   * List of JavaScript DOM values used for tests
1555   *
1556   * @memberof Modernizr
1557   * @name Modernizr._domPrefixes
1558   * @optionName Modernizr._domPrefixes
1559   * @optionProp domPrefixes
1560   * @access public
1561   * @example
1562   *
1563   * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather
1564   * than kebab-case properties, all properties are their Capitalized variant
1565   *
1566   * ```js
1567   * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ];
1568   * ```
1569   */
1570
1571  var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
1572  ModernizrProto._domPrefixes = domPrefixes;
1573  
1574
1575  /**
1576   * testDOMProps is a generic DOM property test; if a browser supports
1577   *   a certain property, it won't return undefined for it.
1578   *
1579   * @access private
1580   * @function testDOMProps
1581   * @param {array.<string>} props - An array of properties to test for
1582   * @param {object} obj - An object or Element you want to use to test the parameters again
1583   * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check
1584   */
1585  function testDOMProps(props, obj, elem) {
1586    var item;
1587
1588    for (var i in props) {
1589      if (props[i] in obj) {
1590
1591        // return the property name as a string
1592        if (elem === false) {
1593          return props[i];
1594        }
1595
1596        item = obj[props[i]];
1597
1598        // let's bind a function
1599        if (is(item, 'function')) {
1600          // bind to obj unless overriden
1601          return fnBind(item, elem || obj);
1602        }
1603
1604        // return the unbound function or obj or value
1605        return item;
1606      }
1607    }
1608    return false;
1609  }
1610
1611  ;
1612
1613  /**
1614   * testPropsAll tests a list of DOM properties we want to check against.
1615   * We specify literally ALL possible (known and/or likely) properties on
1616   * the element including the non-vendor prefixed one, for forward-
1617   * compatibility.
1618   *
1619   * @access private
1620   * @function testPropsAll
1621   * @param {string} prop - A string of the property to test for
1622   * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip
1623   * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against
1624   * @param {string} [value] - A string of a css value
1625   * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set
1626   */
1627  function testPropsAll(prop, prefixed, elem, value, skipValueTest) {
1628
1629    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
1630    props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
1631
1632    // did they call .prefixed('boxSizing') or are we just testing a prop?
1633    if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
1634      return testProps(props, prefixed, value, skipValueTest);
1635
1636      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
1637    } else {
1638      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
1639      return testDOMProps(props, prefixed, elem);
1640    }
1641  }
1642
1643  // Modernizr.testAllProps() investigates whether a given style property,
1644  // or any of its vendor-prefixed variants, is recognized
1645  //
1646  // Note that the property names must be provided in the camelCase variant.
1647  // Modernizr.testAllProps('boxSizing')
1648  ModernizrProto.testAllProps = testPropsAll;
1649
1650  
1651
1652  /**
1653   * testAllProps determines whether a given CSS property is supported in the browser
1654   *
1655   * @memberof Modernizr
1656   * @name Modernizr.testAllProps
1657   * @optionName Modernizr.testAllProps()
1658   * @optionProp testAllProps
1659   * @access public
1660   * @function testAllProps
1661   * @param {string} prop - String naming the property to test (either camelCase or kebab-case)
1662   * @param {string} [value] - String of the value to test
1663   * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection
1664   * @example
1665   *
1666   * testAllProps determines whether a given CSS property, in some prefixed form,
1667   * is supported by the browser.
1668   *
1669   * ```js
1670   * testAllProps('boxSizing')  // true
1671   * ```
1672   *
1673   * It can optionally be given a CSS value in string form to test if a property
1674   * value is valid
1675   *
1676   * ```js
1677   * testAllProps('display', 'block') // true
1678   * testAllProps('display', 'penguin') // false
1679   * ```
1680   *
1681   * A boolean can be passed as a third parameter to skip the value check when
1682   * native detection (@supports) isn't available.
1683   *
1684   * ```js
1685   * testAllProps('shapeOutside', 'content-box', true);
1686   * ```
1687   */
1688
1689  function testAllProps(prop, value, skipValueTest) {
1690    return testPropsAll(prop, undefined, undefined, value, skipValueTest);
1691  }
1692  ModernizrProto.testAllProps = testAllProps;
1693  
1694/*!
1695{
1696  "name": "CSS text-overflow ellipsis",
1697  "property": "ellipsis",
1698  "caniuse": "text-overflow",
1699  "polyfills": [
1700    "text-overflow"
1701  ],
1702  "tags": ["css"]
1703}
1704!*/
1705
1706  Modernizr.addTest('ellipsis', testAllProps('textOverflow', 'ellipsis'));
1707
1708/*!
1709{
1710  "name": "CSS Transforms",
1711  "property": "csstransforms",
1712  "caniuse": "transforms2d",
1713  "tags": ["css"]
1714}
1715!*/
1716
1717  Modernizr.addTest('csstransforms', function() {
1718    // Android < 3.0 is buggy, so we sniff and blacklist
1719    // http://git.io/hHzL7w
1720    return navigator.userAgent.indexOf('Android 2.') === -1 &&
1721           testAllProps('transform', 'scale(1)', true);
1722  });
1723
1724
1725  /**
1726   * testStyles injects an element with style element and some CSS rules
1727   *
1728   * @memberof Modernizr
1729   * @name Modernizr.testStyles
1730   * @optionName Modernizr.testStyles()
1731   * @optionProp testStyles
1732   * @access public
1733   * @function testStyles
1734   * @param {string} rule - String representing a css rule
1735   * @param {function} callback - A function that is used to test the injected element
1736   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
1737   * @param {string[]}
1737 [testnames] - An array of strings that are used as ids for the additional nodes
1738   * @returns {boolean}
1739   * @example
1740   *
1741   * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page
1742   * along with (possibly multiple) DOM elements. This lets you check for features
1743   * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).
1744   *
1745   * ```js
1746   * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {
1747   *   // elem is the first DOM node in the page (by default #modernizr)
1748   *   // rule is the first argument you supplied - the CSS rule in string form
1749   *
1750   *   addTest('widthworks', elem.style.width === '9px')
1751   * });
1752   * ```
1753   *
1754   * If your test requires multiple nodes, you can include a third argument
1755   * indicating how many additional div elements to include on the page. The
1756   * additional nodes are injected as children of the `elem` that is returned as
1757   * the first argument to the callback.
1758   *
1759   * ```js
1760   * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {
1761   *   document.getElementById('modernizr').style.width === '1px'; // true
1762   *   document.getElementById('modernizr2').style.width === '2px'; // true
1763   *   elem.firstChild === document.getElementById('modernizr2'); // true
1764   * }, 1);
1765   * ```
1766   *
1767   * By default, all of the additional elements have an ID of `modernizr[n]`, where
1768   * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,
1769   * the second additional is `#modernizr3`, etc.).
1770   * If you want to have more meaningful IDs for your function, you can provide
1771   * them as the fourth argument, as an array of strings
1772   *
1773   * ```js
1774   * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {
1775   *   elem.firstChild === document.getElementById('foo'); // true
1776   *   elem.lastChild === document.getElementById('bar'); // true
1777   * }, 2, ['foo', 'bar']);
1778   * ```
1779   *
1780   */
1781
1782  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;
1783  
1784/*!
1785{
1786  "name": "details Element",
1787  "caniuse": "details",
1788  "property": "details",
1789  "tags": ["elem"],
1790  "builderAliases": ["elem_details"],
1791  "authors": ["@mathias"],
1792  "notes": [{
1793    "name": "Mathias' Original",
1794    "href": "https://mathiasbynens.be/notes/html5-details-jquery#comment-35"
1795  }]
1796}
1797!*/
1798
1799  Modernizr.addTest('details', function() {
1800    var el = createElement('details');
1801    var diff;
1802
1803    // return early if possible; thanks @aFarkas!
1804    if (!('open' in el)) {
1805      return false;
1806    }
1807
1808    testStyles('#modernizr details{display:block}', function(node) {
1809      node.appendChild(el);
1810      el.innerHTML = '<summary>a</summary>b';
1811      diff = el.offsetHeight;
1812      el.open = true;
1813      diff = diff != el.offsetHeight;
1814    });
1815
1816
1817    return diff;
1818  });
1819
1820
1821  // Run each test
1822  testRunner();
1823
1824  // Remove the "no-js" class if it exists
1825  setClasses(classes);
1826
1827  delete ModernizrProto.addTest;
1828  delete ModernizrProto.addAsyncTest;
1829
1830  // Run the things that are supposed to run after the tests
1831  for (var i = 0; i < Modernizr._q.length; i++) {
1832    Modernizr._q[i]();
1833  }
1834
1835  // Leak Modernizr namespace
1836  window.Modernizr = Modernizr;
1837
1838
1839;
1840
1841})(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.