PageSourceSearch

https://www.sightunseen.com/wordpress/wp-content/themes/sightunseen-wp-theme/js/plugins/modernizr.js?ver=1.0.0

js sightunseen.com collected 2026-09-24 08:59:03 UTC 39,676 bytes, 1,215 lines download raw bytes

vendor: 9,524 bytes, lines 1-282
1/*!
2 * modernizr v3.0.0-alpha.3
3 * Build http://v3.modernizr.com/download/#-csstransforms-csstransforms3d-csstransitions-touchevents-domprefixes-load-mq-prefixed-prefixes-shiv-testallprops-testprop-teststyles-dontmin
4 *
5 * Copyright (c)
6 *  Faruk Ates
7 *  Paul Irish
8 *  Alex Sexton
9 *  Ryan Seddon
10 *  Alexander Farkas
11 *  Patrick Kettner
12 *  Stu Cox
13 *  Richard Herrera
14
15 * MIT License
16 */
17
18/*
19 * Modernizr tests which native CSS3 and HTML5 features are available in the
20 * current UA and makes the results available to you in two ways: as properties on
21 * a global `Modernizr` object, and as classes on the `<html>` element. This
22 * information allows you to progressively enhance your pages with a granular level
23 * of control over the experience.
24*/
25
26;(function(window, document, undefined){
27  var classes = [];
28
29
30  // Take the html5 variable out of the
31  // html5shiv scope so we can return it.
32  var html5;
33  /**
34  * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
35  */
36  ;(function(window, document) {
37  /*jshint evil:true */
38    /** version */
39    var version = '3.7.2';
40
41    /** Preset options */
42    var options = window.html5 || {};
43
44    /** Used to skip problem elements */
45    var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
46
47    /** Not all elements can be cloned in IE **/
48    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;
49
50    /** Detect whether the browser supports default html5 styles */
51    var supportsHtml5Styles;
52
53    /** Name of the expando, to work with multiple documents or to re-shiv one document */
54    var expando = '_html5shiv';
55
56    /** The id for the the documents expando */
57    var expanID = 0;
58
59    /** Cached data for each document */
60    var expandoData = {};
61
62    /** Detect whether the browser supports unknown elements */
63    var supportsUnknownElements;
64
65    (function() {
66      try {
67          var a = document.createElement('a');
68          a.innerHTML = '<xyz></xyz>';
69          //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
70          supportsHtml5Styles = ('hidden' in a);
71
72          supportsUnknownElements = a.childNodes.length == 1 || (function() {
73            // assign a false positive if unable to shiv
74            (document.createElement)('a');
75            var frag = document.createDocumentFragment();
76            return (
77              typeof frag.cloneNode == 'undefined' ||
78              typeof frag.createDocumentFragment == 'undefined' ||
79              typeof frag.createElement == 'undefined'
80            );
81          }());
82      } catch(e) {
83        // assign a false positive if detection fails => unable to shiv
84        supportsHtml5Styles = true;
85        supportsUnknownElements = true;
86      }
87
88    }());
89
90    /*--------------------------------------------------------------------------*/
91
92    /**
93     * Creates a style sheet with the given CSS text and adds it to the document.
94     * @private
95     * @param {Document} ownerDocument The document.
96     * @param {String} cssText The CSS text.
97     * @returns {StyleSheet} The style element.
98     */
99    function addStyleSheet(ownerDocument, cssText) {
100      var p = ownerDocument.createElement('p'),
101          parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
102
103      p.innerHTML = 'x<style>' + cssText + '</style>';
104      return parent.insertBefore(p.lastChild, parent.firstChild);
105    }
106
107    /**
108     * Returns the value of `html5.elements` as an array.
109     * @private
110     * @returns {Array} An array of shived element node names.
111     */
112    function getElements() {
113      var elements = html5.elements;
114      return typeof elements == 'string' ? elements.split(' ') : elements;
115    }
116
117    /**
118     * Extends the built-in list of html5 elements
119     * @memberOf html5
120     * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
121     * @param {Document} ownerDocument The context document.
122     */
123    function addElements(newElements, ownerDocument) {
124      var elements = html5.elements;
125      if(typeof elements != 'string'){
126        elements = elements.join(' ');
127      }
128      if(typeof newElements != 'string'){
129        newElements = newElements.join(' ');
130      }
131      html5.elements = elements +' '+ newElements;
132      shivDocument(ownerDocument);
133    }
134
135     /**
136     * Returns the data associated to the given document
137     * @private
138     * @param {Document} ownerDocument The document.
139     * @returns {Object} An object of data.
140     */
141    function getExpandoData(ownerDocument) {
142      var data = expandoData[ownerDocument[expando]];
143      if (!data) {
144          data = {};
145          expanID++;
146          ownerDocument[expando] = expanID;
147          expandoData[expanID] = data;
148      }
149      return data;
150    }
151
152    /**
153     * returns a shived element for the given nodeName and document
154     * @memberOf html5
155     * @param {String} nodeName name of the element
156     * @param {Document} ownerDocument The context document.
157     * @returns {Object} The shived element.
158     */
159    function createElement(nodeName, ownerDocument, data){
160      if (!ownerDocument) {
161          ownerDocument = document;
162      }
163      if(supportsUnknownElements){
164          return ownerDocument.createElement(nodeName);
165      }
166      if (!data) {
167          data = getExpandoData(ownerDocument);
168      }
169      var node;
170
171      if (data.cache[nodeName]) {
172          node = data.cache[nodeName].cloneNode();
173      } else if (saveClones.test(nodeName)) {
174          node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
175      } else {
176          node = data.createElem(nodeName);
177      }
178
179      // Avoid adding some elements to fragments in IE < 9 because
180      // * Attributes like `name` or `type` cannot be set/changed once an element
181      //   is inserted into a document/fragment
182      // * Link elements with `src` attributes that are inaccessible, as with
183      //   a 403 response, will cause the tab/window to crash
184      // * Script elements appended to fragments will execute when their `src`
185      //   or `text` property is set
186      return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
187    }
188
189    /**
190     * returns a shived DocumentFragment for the given document
191     * @memberOf html5
192     * @param {Document} ownerDocument The context document.
193     * @returns {Object} The shived DocumentFragment.
194     */
195    function createDocumentFragment(ownerDocument, data){
196      if (!ownerDocument) {
197          ownerDocument = document;
198      }
199      if(supportsUnknownElements){
200          return ownerDocument.createDocumentFragment();
201      }
202      data = data || getExpandoData(ownerDocument);
203      var clone = data.frag.cloneNode(),
204          i = 0,
205          elems = getElements(),
206          l = elems.length;
207      for(;i<l;i++){
208          clone.createElement(elems[i]);
209      }
210      return clone;
211    }
212
213    /**
214     * Shivs the `createElement` and `createDocumentFragment` methods of the document.
215     * @private
216     * @param {Document|DocumentFragment} ownerDocument The document.
217     * @param {Object} data of the document.
218     */
219    function shivMethods(ownerDocument, data) {
220      if (!data.cache) {
221          data.cache = {};
222          data.createElem = ownerDocument.createElement;
223          data.createFrag = ownerDocument.createDocumentFragment;
224          data.frag = data.createFrag();
225      }
226
227
228      ownerDocument.createElement = function(nodeName) {
229        //abort shiv
230        if (!html5.shivMethods) {
231            return data.createElem(nodeName);
232        }
233        return createElement(nodeName, ownerDocument, data);
234      };
235
236      ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
237        'var n=f.cloneNode(),c=n.createElement;' +
238        'h.shivMethods&&(' +
239          // unroll the `createElement` calls
240          getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
241            data.createElem(nodeName);
242            data.frag.createElement(nodeName);
243            return 'c("' + nodeName + '")';
244          }) +
245        ');return n}'
246      )(html5, data.frag);
247    }
248
249    /*--------------------------------------------------------------------------*/
250
251    /**
252     * Shivs the given document.
253     * @memberOf html5
254     * @param {Document} ownerDocument The document to shiv.
255     * @returns {Document} The shived document.
256     */
257    function shivDocument(ownerDocument) {
258      if (!ownerDocument) {
259          ownerDocument = document;
260      }
261      var data = getExpandoData(ownerDocument);
262
263      if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
264        data.hasCSS = !!addStyleSheet(ownerDocument,
265          // corrects block display not defined in IE6/7/8/9
266          'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
267          // adds styling not present in IE6/7/8/9
268          'mark{background:#FF0;color:#000}' +
269          // hides non-rendered elements
270          'template{display:none}'
271        );
272      }
273      if (!supportsUnknownElements) {
274        shivMethods(ownerDocument, data);
275      }
276      return ownerDocument;
277    }
278
279    /*--------------------------------------------------------------------------*/
280
281    /**
282     * The `html5` object is exposed so that more elements can be shived and
283     * existing shiving can be detected on iframes.
284     * @type Object
285     * @example
286     *
287     * // options can be changed before the script is included
288     * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
289     */
290    var html5 = {
291
292      /**
293       * An array or space separated string of node names of the elements to shiv.
294       * @memberOf html5
295       * @type Array|String
296       */
297      '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',
298
299      /**
300       * current version of html5shiv
301       */
302      'version': version,
303
304      /**
305       * A flag to indicate that the HTML5 style sheet should be inserted.
306       * @memberOf html5
307       * @type Boolean
308       */
309      'shivCSS': (options.shivCSS !== false),
310
311      /**
312       * Is equal to true if a browser supports creating unknown/HTML5 elements
313       * @memberOf html5
314       * @type boolean
315       */
316      'supportsUnknownElements': supportsUnknownElements,
317
318      /**
319       * A flag to indicate that the document's `createElement` and `createDocumentFragment`
320       * methods should be overwritten.
321       * @memberOf html5
322       * @type Boolean
323       */
324      'shivMethods': (options.shivMethods !== false),
325
326      /**
327       * A string to describe the type of `html5` object ("default" or "default print").
328       * @memberOf html5
329       * @type String
330       */
331      'type': 'default',
332
333      // shivs the document according to the specified `html5` object options
334      'shivDocument': shivDocument,
335
336      //creates a shived element
337      createElement: createElement,
338
339      //creates a shived documentFragment
340      createDocumentFragment: createDocumentFragment,
341
342      //extends list of elements
343      addElements: addElements
344    };
345
346    /*--------------------------------------------------------------------------*/
347
348    // expose html5
349    window.html5 = html5;
350
351    // shiv the document
352    shivDocument(document);
353
354  }(this, document));
355
356
357  var tests = [];
358
359
360  var ModernizrProto = {
361    // The current version, dummy
362    _version: '3.0.0-alpha.3',
363
364    // Any settings that don't work as separate modules
365    // can go in here as configuration.
366    _config: {
367      'classPrefix' : '',
368      'enableClasses' : true,
369      'enableJSClass' : true,
370      'usePrefixes' : true
371    },
372
373    // Queue of tests
374    _q: [],
375
376    // Stub these for people who are listening
377    on: function( test, cb ) {
378      // I don't really think people should do this, but we can
379      // safe guard it a bit.
380      // -- NOTE:: this gets WAY overridden in src/addTest for
381      // actual async tests. This is in case people listen to
382      // synchronous tests. I would leave it out, but the code
383      // to *disallow* sync tests in the real version of this
384      // function is actually larger than this.
385      var self = this;
386      setTimeout(function() {
387        cb(self[test]);
388      }, 0);
389    },
390
391    addTest: function( name, fn, options ) {
392      tests.push({name : name, fn : fn, options : options });
393    },
394
395    addAsyncTest: function (fn) {
396      tests.push({name : null, fn : fn});
397    }
398  };
399
400
401
402  // Fake some of Object.create
403  // so we can force non test results
404  // to be non "own" properties.
405  var Modernizr = function(){};
406  Modernizr.prototype = ModernizrProto;
407
408  // Leak modernizr globally when you `require` it
409  // rather than force it here.
410  // Overwrite name so constructor name is nicer :D
411  Modernizr = new Modernizr();
412
413
414
415
416  var err = function() {};
417  var warn = function() {};
418
419  if (window.console) {
420    err = function() {
421      var method = console.error ? 'error' : 'log';
422      window.console[method].apply( window.console, Array.prototype.slice.call(arguments) );
423    };
424
425    warn = function() {
426      var method = console.warn ? 'warn' : 'log';
427      window.console[method].apply( window.console, Array.prototype.slice.call(arguments) );
428    };
429  }
430
431  ModernizrProto.load = function() {
432    if ('yepnope' in window) {
433      warn('yepnope.js (aka Modernizr.load) is no longer included as part of Modernizr. yepnope appears to be available on the page, so we’ll use it to handle this call to Modernizr.load, but please update your code to use yepnope directly.\n See http://github.com/Modernizr/Modernizr/issues/1182 for more information.');
434      window.yepnope.apply(window, [].slice.call(arguments,0));
435    } else {
436      err('yepnope.js (aka Modernizr.load) is no longer included as part of Modernizr. Get it from http://yepnopejs.com. See http://github.com/Modernizr/Modernizr/issues/1182 for more information.');
437    }
438  };
439
440
441
442  // List of property values to set for css tests. See ticket #21
443  var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : []);
444
445  // expose these for the plugin API. Look in the source for how to join() them against your input
446  ModernizrProto._prefixes = prefixes;
447
448
449
450  /**
451   * is returns a boolean for if typeof obj is exactly type.
452   */
453  function is( obj, type ) {
454    return typeof obj === type;
455  }
456  ;
457
458  // Run through all tests and detect their support in the current UA.
459  function testRunner() {
460    var featureNames;
461    var feature;
462    var aliasIdx;
463    var result;
464    var nameIdx;
465    var featureName;
466    var featureNameSplit;
467
468    for ( var featureIdx in tests ) {
469      featureNames = [];
470      feature = tests[featureIdx];
471      // run the test, throw the return value into the Modernizr,
472      //   then based on that boolean, define an appropriate className
473      //   and push it into an array of classes we'll join later.
474      //
475      //   If there is no name, it's an 'async' test that is run,
476      //   but not directly added to the object. That should
477      //   be done with a post-run addTest call.
478      if ( feature.name ) {
479        featureNames.push(feature.name.toLowerCase());
480
481        if (feature.options && feature.options.aliases && feature.options.aliases.length) {
482          // Add all the aliases into the names list
483          for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
484            featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
485          }
486        }
487      }
488
489      // Run the test, or use the raw value if it's not a function
490      result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
491
492
493      // Set each of the names on the Modernizr object
494      for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
495        featureName = featureNames[nameIdx];
496        // Support dot properties as sub tests. We don't do checking to make sure
497        // that the implied parent tests have been added. You must call them in
498        // order (either in the test, or make the parent test a dependency).
499        //
500        // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
501        // hashtag famous last words
502        featureNameSplit = featureName.split('.');
503
504        if (featureNameSplit.length === 1) {
505          Modernizr[featureNameSplit[0]] = result;
506        } else {
507          // cast to a Boolean, if not one already
508          /* jshint -W053 */
509          if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
510            Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
511          }
512
513          Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
514        }
515
516        classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
517      }
518    }
519  }
520
521  ;
522
523  var docElement = document.documentElement;
524
525
526  // Pass in an and array of class names, e.g.:
527  //  ['no-webp', 'borderradius', ...]
528  function setClasses( classes ) {
529    var className = docElement.className;
530    var classPrefix = Modernizr._config.classPrefix || '';
531
532    // Change `no-js` to `js` (we do this independently of the `enableClasses`
533    // option)
534    // Handle classPrefix on this too
535    if(Modernizr._config.enableJSClass) {
536      var reJS = new RegExp('(^|\\s)'+classPrefix+'no-js(\\s|$)');
537      className = className.replace(reJS, '$1'+classPrefix+'js$2');
538    }
539
540    if(Modernizr._config.enableClasses) {
541      // Add the new classes
542      className += ' ' + classPrefix + classes.join(' ' + classPrefix);
543      docElement.className = className;
544    }
545
546  }
547
548  ;
549
550  // Helper function for converting kebab-case to camelCase,
551  // e.g. box-sizing -> boxSizing
552  function cssToDOM( name ) {
553    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
554      return m1 + m2.toUpperCase();
555    }).replace(/^-/, '');
556  }
557  ;
558
559  // Following spec is to expose vendor-specific style properties as:
560  //   elem.style.WebkitBorderRadius
561  // and the following would be incorrect:
562  //   elem.style.webkitBorderRadius
563
564  // Webkit ghosts their properties in lowercase but Opera & Moz do not.
565  // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
566  //   erik.eae.net/archives/2008/03/10/21.48.10/
567
568  // More here: github.com/Modernizr/Modernizr/issues/issue/21
569  var omPrefixes = 'Moz O ms Webkit';
570
571
572  var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
573  ModernizrProto._domPrefixes = domPrefixes;
574
575/*!
576{
577  "name": "CSS Supports",
578  "property": "supports",
579  "caniuse": "css-featurequeries",
580  "tags": ["css"],
581  "builderAliases": ["css_supports"],
582  "notes": [{
583    "name": "W3 Spec",
584    "href": "http://dev.w3.org/csswg/css3-conditional/#at-supports"
585  },{
586    "name": "Related Github Issue",
587    "href": "github.com/Modernizr/Modernizr/issues/648"
588  },{
589    "name": "W3 Info",
590    "href": "http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface"
591  }]
592}
593!*/
594
595  var newSyntax = 'CSS' in window && 'supports' in window.CSS;
596  var oldSyntax = 'supportsCSS' in window;
597  Modernizr.addTest('supports', newSyntax || oldSyntax);
598
599
600  var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
601  ModernizrProto._cssomPrefixes = cssomPrefixes;
602
603
604  /**
605   * atRule returns a given CSS property at-rule (eg @keyframes), possibly in
606   * some prefixed form, or false, in the case of an unsupported rule
607   *
608   * @param prop - String naming the property to test
609   */
610
611  var atRule = function(prop) {
612    var length = prefixes.length;
613    var cssrule = window.CSSRule;
614    var rule;
615
616    if (typeof cssrule === 'undefined') {
617      return undefined;
618    }
619
620    if (!prop) {
621      return false;
622    }
623
624    // remove literal @ from beginning of provided property
625    prop = prop.replace(/^@/,'');
626
627    // CSSRules use underscores instead of dashes
628    rule = prop.replace(/-/g,'_').toUpperCase() + '_RULE';
629
630    if (rule in cssrule) {
631      return '@' + prop;
632    }
633
634    for ( var i = 0; i < length; i++ ) {
635      // prefixes gives us something like -o-, and we want O_
636      var prefix = prefixes[i];
637      var thisRule = prefix.toUpperCase() + '_' + rule;
638
639      if (thisRule in cssrule) {
640        return '@-' + prefix.toLowerCase() + '-' + prop;
641      }
642    }
643
644    return false;
645  };
646
647
648
649  var createElement = function() {
650    if (typeof document.createElement !== 'function') {
651      // This is the case in IE7, where the type of createElement is "object".
652      // For this reason, we cannot call apply() as Object is not a Function.
653      return document.createElement(arguments[0]);
654    } else {
655      return document.createElement.apply(document, arguments);
656    }
657  };
658
659
660  function getBody() {
661    // After page load injecting a fake body doesn't work so check if body exists
662    var body = document.body;
663
664    if(!body) {
665      // Can't use the real body create a fake one.
666      body = createElement('body');
667      body.fake = true;
668    }
669
670    return body;
671  }
672
673  ;
674
675  // Inject element with style element and some CSS rules
676  function injectElementWithStyles( rule, callback, nodes, testnames ) {
677    var mod = 'modernizr';
678    var style;
679    var ret;
680    var node;
681    var docOverflow;
682    var div = createElement('div');
683    var body = getBody();
684
685    if ( parseInt(nodes, 10) ) {
686      // In order not to give false positives we create a node for each test
687      // This also allows the method to scale for unspecified uses
688      while ( nodes-- ) {
689        node = createElement('div');
690        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
691        div.appendChild(node);
692      }
693    }
694
695    // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
696    // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
697    // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
698    // msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
699    // Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
700    style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
701    div.id = mod;
702    // 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.
703    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
704    (!body.fake ? div : body).innerHTML += style;
705    body.appendChild(div);
706    if ( body.fake ) {
707      //avoid crashing IE8, if background image is used
708      body.style.background = '';
709      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
710      body.style.overflow = 'hidden';
711      docOverflow = docElement.style.overflow;
712      docElement.style.overflow = 'hidden';
713      docElement.appendChild(body);
714    }
715
716    ret = callback(div, rule);
717    // If this is done after page load we don't want to remove the body so check if body exists
718    if ( body.fake ) {
719      body.parentNode.removeChild(body);
720      docElement.style.overflow = docOverflow;
721      // Trigger layout so kinetic scrolling isn't disabled in iOS6+
722      docElement.offsetHeight;
723    } else {
724      div.parentNode.removeChild(div);
725    }
726
727    return !!ret;
728
729  }
730
731  ;
732
733  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;
734
735/*!
736{
737  "name": "Touch Events",
738  "property": "touchevents",
739  "caniuse" : "touch",
740  "tags": ["media", "attribute"],
741  "notes": [{
742    "name": "Touch Events spec",
743    "href": "http://www.w3.org/TR/2013/WD-touch-events-20130124/"
744  }],
745  "warnings": [
746    "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device"
747  ],
748  "knownBugs": [
749    "False-positive on some configurations of Nokia N900",
750    "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695"
751  ]
752}
753!*/
754/* DOC
755Indicates if the browser supports the W3C Touch Events API.
756
757This *does not* necessarily reflect a touchscreen device:
758
759* Older touchscreen devices only emulate mouse events
760* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that
761* Some browsers & OS setups may enable touch APIs when no touchscreen is connected
762* Future browsers may implement other event models for touch interactions
763
764See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).
765
766It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/).
767
768This test will also return `true` for Firefox 4 Multitouch support.
769*/
770
771  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415
772  Modernizr.addTest('touchevents', function() {
773    var bool;
774    if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
775      bool = true;
776    } else {
777      var query = ['@media (',prefixes.join('touch-enabled),('),'heartz',')','{#modernizr{top:9px;position:absolute}}'].join('');
778      testStyles(query, function( node ) {
779        bool = node.offsetTop === 9;
780      });
781    }
782    return bool;
783  });
784
785
786  // adapted from matchMedia polyfill
787  // by Scott Jehl and Paul Irish
788  // gist.github.com/786768
789  var testMediaQuery = (function () {
790    var matchMedia = window.matchMedia || window.msMatchMedia;
791    if ( matchMedia ) {
792      return function ( mq ) {
793        var mql = matchMedia(mq);
794        return mql && mql.matches || false;
795      };
796    }
797
798    return function ( mq ) {
799      var bool = false;
800
801      injectElementWithStyles('@media ' + mq + ' { #modernizr { position: absolute; } }', function( node ) {
802        bool = (window.getComputedStyle ?
803                window.getComputedStyle(node, null) :
804                node.currentStyle)['position'] == 'absolute';
805      });
806
807      return bool;
808    };
809  })();
810
811
812
813  /** Modernizr.mq tests a given media query, live against the current state of the window
814   * A few important notes:
815        * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
816        * A max-width or orientation query will be evaluated against the current state, which may change later.
817        * You must specify values. Eg. If you are testing support for the min-width media query use:
818              Modernizr.mq('(min-width:0)')
819   * usage:
820   * Modernizr.mq('only screen and (max-width:768)')
821   */
822  var mq = ModernizrProto.mq = testMediaQuery;
823
824
825  /**
826   * contains returns a boolean for if substr is found within str.
827   */
828  function contains( str, substr ) {
829    return !!~('' + str).indexOf(substr);
830  }
831
832  ;
833
834  // Change the function's scope.
835  function fnBind(fn, that) {
836    return function() {
837      return fn.apply(that, arguments);
838    };
839  }
840
841  ;
842
843  /**
844   * testDOMProps is a generic DOM property test; if a browser supports
845   *   a certain property, it won't return undefined for it.
846   */
847  function testDOMProps( props, obj, elem ) {
848    var item;
849
850    for ( var i in props ) {
851      if ( props[i] in obj ) {
852
853        // return the property name as a string
854        if (elem === false) return props[i];
855
856        item = obj[props[i]];
857
858        // let's bind a function
859        if (is(item, 'function')) {
860          // bind to obj unless overriden
861          return fnBind(item, elem || obj);
862        }
863
864        // return the unbound function or obj or value
865        return item;
866      }
867    }
868    return false;
869  }
870
871  ;
872
873  /**
874   * Create our "modernizr" element that we do most feature tests on.
875   */
876  var modElem = {
877    elem : createElement('modernizr')
878  };
879
880  // Clean up this element
881  Modernizr._q.push(function() {
882    delete modElem.elem;
883  });
884
885
886
887  var mStyle = {
888    style : modElem.elem.style
889  };
890
891  // kill ref for gc, must happen before
892  // mod.elem is removed, so we unshift on to
893  // the front of the queue.
894  Modernizr._q.unshift(function() {
895    delete mStyle.style;
896  });
897
898
899
900  // Helper function for converting camelCase to kebab-case,
901  // e.g. boxSizing -> box-sizing
902  function domToCSS( name ) {
903    return name.replace(/([A-Z])/g, function(str, m1) {
904      return '-' + m1.toLowerCase();
905    }).replace(/^ms-/, '-ms-');
906  }
907  ;
908
909  // Function to allow us to use native feature detection functionality if available.
910  // Accepts a list of property names and a single value
911  // Returns `undefined` if native detection not available
912  function nativeTestProps ( props, value ) {
913    var i = props.length;
914    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
915    if ('CSS' in window && 'supports' in window.CSS) {
916      // Try every prefixed variant of the property
917      while (i--) {
918        if (window.CSS.supports(domToCSS(props[i]), value)) {
919          return true;
920        }
921      }
922      return false;
923    }
924    // Otherwise fall back to at-rule (for Opera 12.x)
925    else if ('CSSSupportsRule' in window) {
926      // Build a condition string for every prefixed variant
927      var conditionText = [];
928      while (i--) {
929        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
930      }
931      conditionText = conditionText.join(' or ');
932      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function( node ) {
933        return getComputedStyle(node, null).position == 'absolute';
934      });
935    }
936    return undefined;
937  }
938  ;
939
940  // testProps is a generic CSS / DOM property test.
941
942  // In testing support for a given CSS property, it's legit to test:
943  //    `elem.style[styleName] !== undefined`
944  // If the property is supported it will return an empty string,
945  // if unsupported it will return undefined.
946
947  // We'll take advantage of this quick test and skip setting a style
948  // on our modernizr element, but instead just testing undefined vs
949  // empty string.
950
951  // Property names can be provided in either camelCase or kebab-case.
952
953  function testProps( props, prefixed, value, skipValueTest ) {
954    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
955
956    // Try native detect first
957    if (!is(value, 'undefined')) {
958      var result = nativeTestProps(props, value);
959      if(!is(result, 'undefined')) {
960        return result;
961      }
962    }
963
964    // Otherwise do it properly
965    var afterInit, i, propsLength, prop, before;
966
967    // If we don't have a style element, that means
968    // we're running async or after the core tests,
969    // so we'll need to create our own elements to use
970    if ( !mStyle.style ) {
971      afterInit = true;
972      mStyle.modElem = createElement('modernizr');
973      mStyle.style = mStyle.modElem.style;
974    }
975
976    // Delete the objects if we
977    // we created them.
978    function cleanElems() {
979      if (afterInit) {
980        delete mStyle.style;
981        delete mStyle.modElem;
982      }
983    }
984
985    propsLength = props.length;
986    for ( i = 0; i < propsLength; i++ ) {
987      prop = props[i];
988      before = mStyle.style[prop];
989
990      if (contains(prop, '-')) {
991        prop = cssToDOM(prop);
992      }
993
994      if ( mStyle.style[prop] !== undefined ) {
995
996        // If value to test has been passed in, do a set-and-check test.
997        // 0 (integer) is a valid property value, so check that `value` isn't
998        // undefined, rather than just checking it's truthy.
999        if (!skipValueTest && !is(value, 'undefined')) {
1000
1001          // Needs a try catch block because of old IE. This is slow, but will
1002          // be avoided in most cases because `skipValueTest` will be used.
1003          try {
1004            mStyle.style[prop] = value;
1005          } catch (e) {}
1006
1007          // If the property value has changed, we assume the value used is
1008          // supported. If `value` is empty string, it'll fail here (because
1009          // it hasn't changed), which matches how browsers have implemented
1010          // CSS.supports()
1011          if (mStyle.style[prop] != before) {
1012            cleanElems();
1013            return prefixed == 'pfx' ? prop : true;
1014          }
1015        }
1016        // Otherwise just return true, or the property name if this is a
1017        // `prefixed()` call
1018        else {
1019          cleanElems();
1020          return prefixed == 'pfx' ? prop : true;
1021        }
1022      }
1023    }
1024    cleanElems();
1025    return false;
1026  }
1027
1028  ;
1029
1030  // Modernizr.testProp() investigates whether a given style property is recognized
1031  // Property names can be provided in either camelCase or kebab-case.
1032  // Modernizr.testProp('pointerEvents')
1033  // Also accepts optional 2nd arg, of a value to use for native feature detection, e.g.:
1034  // Modernizr.testProp('pointerEvents', 'none')
1035  var testProp = ModernizrProto.testProp = function( prop, value, useValue ) {
1036    return testProps([prop], undefined, value, useValue);
1037  };
1038
1039
1040  /**
1041   * testPropsAll tests a list of DOM properties we want to check against.
1042   *     We specify literally ALL possible (known and/or likely) properties on
1043   *     the element including the non-vendor prefixed one, for forward-
1044   *     compatibility.
1045   */
1046  function testPropsAll( prop, prefixed, elem, value, skipValueTest ) {
1047
1048    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
1049    props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
1050
1051    // did they call .prefixed('boxSizing') or are we just testing a prop?
1052    if(is(prefixed, 'string') || is(prefixed, 'undefined')) {
1053      return testProps(props, prefixed, value, skipValueTest);
1054
1055      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
1056    } else {
1057      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
1058      return testDOMProps(props, prefixed, elem);
1059    }
1060  }
1061
1062  // Modernizr.testAllProps() investigates whether a given style property,
1063  //     or any of its vendor-prefixed variants, is recognized
1064  // Note that the property names must be provided in the camelCase variant.
1065  // Modernizr.testAllProps('boxSizing')
1066  ModernizrProto.testAllProps = testPropsAll;
1067
1068
1069
1070  // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
1071  // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
1072
1073  // Properties can be passed as DOM-style camelCase or CSS-style kebab-case.
1074  // Return values will always be in camelCase; if you want kebab-case, use Modernizr.prefixedCSS().
1075
1076  // If you're trying to ascertain which transition end event to bind to, you might do something like...
1077  //
1078  //     var transEndEventNames = {
1079  //         'WebkitTransition' : 'webkitTransitionEnd',// Saf 6, Android Browser
1080  //         'MozTransition'    : 'transitionend',      // only for FF < 15
1081  //         'transition'       : 'transitionend'       // IE10, Opera, Chrome, FF 15+, Saf 7+
1082  //     },
1083  //     transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
1084
1085  var prefixed = ModernizrProto.prefixed = function( prop, obj, elem ) {
1086    if (prop.indexOf('@') === 0) {
1087      return atRule(prop);
1088    }
1089
1090    if (prop.indexOf('-') != -1) {
1091      // Convert kebab-case to camelCase
1092      prop = cssToDOM(prop);
1093    }
1094    if (!obj) {
1095      return testPropsAll(prop, 'pfx');
1096    } else {
1097      // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
1098      return testPropsAll(prop, obj, elem);
1099    }
1100  };
1101
1102
1103
1104  /**
1105   * testAllProps determines whether a given CSS property, in some prefixed
1106   * form, is supported by the browser. It can optionally be given a value; in
1107   * which case testAllProps will only return true if the browser supports that
1108   * value for the named property; this latter case will use native detection
1109   * (via window.CSS.supports) if available. A boolean can be passed as a 3rd
1110   * parameter to skip the value check when native detection isn't available,
1111   * to improve performance when simply testing for support of a property.
1112   *
1113   * @param prop - String naming the property to test (either camelCase or
1114   *               kebab-case)
1115   * @param value - [optional] String of the value to test
1116   * @param skipValueTest - [optional] Whether to skip testing that the value
1117   *                        is supported when using non-native detection
1118   *                        (default: false)
1119   */
1120  function testAllProps (prop, value, skipValueTest) {
1121    return testPropsAll(prop, undefined, undefined, value, skipValueTest);
1122  }
1123  ModernizrProto.testAllProps = testAllProps;
1124
1125/*!
1126{
1127  "name": "CSS Transforms",
1128  "property": "csstransforms",
1129  "caniuse": "transforms2d",
1130  "tags": ["css"]
1131}
1132!*/
1133
1134  Modernizr.addTest('csstransforms', function() {
1135    // Android < 3.0 is buggy, so we sniff and blacklist
1136    // http://git.io/hHzL7w
1137    return navigator.userAgent.indexOf('Android 2.') === -1 &&
1138           testAllProps('transform', 'scale(1)', true);
1139  });
1140
1141/*!
1142{
1143  "name": "CSS Transforms 3D",
1144  "property": "csstransforms3d",
1145  "caniuse": "transforms3d",
1146  "tags": ["css"],
1147  "warnings": [
1148    "Chrome may occassionally fail this test on some systems; more info: https://code.google.com/p/chromium/issues/detail?id=129004"
1149  ]
1150}
1151!*/
1152
1153  Modernizr.addTest('csstransforms3d', function() {
1154    var ret = !!testAllProps('perspective', '1px', true);
1155    var usePrefix = Modernizr._config.usePrefixes;
1156
1157    // Webkit's 3D transforms are passed off to the browser's own graphics renderer.
1158    //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
1159    //   some conditions. As a result, Webkit typically recognizes the syntax but
1160    //   will sometimes throw a false positive, thus we must do a more thorough check:
1161    if ( ret && (!usePrefix || 'webkitPerspective' in docElement.style )) {
1162      var mq;
1163      // Use CSS Conditional Rules if available
1164      if (Modernizr.supports) {
1165        mq = '@supports (perspective: 1px)';
1166      } else {
1167        // Otherwise, Webkit allows this media query to succeed only if the feature is enabled.
1168        // `@media (transform-3d),(-webkit-transform-3d){ ... }`
1169        mq = '@media (transform-3d)';
1170        if (usePrefix ) mq += ',(-webkit-transform-3d)';
1171      }
1172      // If loaded inside the body tag and the test element inherits any padding, margin or borders it will fail #740
1173      mq += '{#modernizr{left:9px;position:absolute;height:5px;margin:0;padding:0;border:0}}';
1174
1175      testStyles(mq, function( elem ) {
1176        ret = elem.offsetLeft === 9 && elem.offsetHeight === 5;
1177      });
1178    }
1179
1180    return ret;
1181  });
1182
1183/*!
1184{
1185  "name": "CSS Transitions",
1186  "property": "csstransitions",
1187  "caniuse": "css-transitions",
1188  "tags": ["css"]
1189}
1190!*/
1191
1192  Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));
1193
1194
1195  // Run each test
1196  testRunner();
1197
1198  // Remove the "no-js" class if it exists
1199  setClasses(classes);
1200
1201  delete ModernizrProto.addTest;
1202  delete ModernizrProto.addAsyncTest;
1203
1204  // Run the things that are supposed to run after the tests
1205  for (var i = 0; i < Modernizr._q.length; i++) {
1206    Modernizr._q[i]();
1207  }
1208
1209  // Leak Modernizr namespace
1210  window.Modernizr = Modernizr;
1211
1212
1213;
1214
1215})(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.