Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Services.Optimization.Web/Scripts/modernizr-1.7.js @ 16038

Last change on this file since 16038 was 9582, checked in by fschoepp, 11 years ago

#1888:

  • Added an overview for users to inspect their orders
  • Order Administrators may now suspend or reactivate orders
  • When creating an order, its necessary to enter payment information (paypal, credit card,...) before
  • Also, the billing period and type must be entered during the creation of an order.
File size: 36.0 KB
RevLine 
[8384]1/*!
[9582]2 * Modernizr v1.7
3 * http://www.modernizr.com
4 *
5 * Developed by:
6 * - Faruk Ates  http://farukat.es/
7 * - Paul Irish  http://paulirish.com/
8 *
9 * Copyright (c) 2009-2011
10 * Dual-licensed under the BSD or MIT licenses.
11 * http://www.modernizr.com/license/
12 */
[8384]13
14 
15/*
16 * Modernizr is a script that detects native CSS3 and HTML5 features
17 * available in the current UA and provides an object containing all
18 * features with a true/false value, depending on whether the UA has
19 * native support for it or not.
20 *
21 * Modernizr will also add classes to the <html> element of the page,
22 * one for each feature it detects. If the UA supports it, a class
23 * like "cssgradients" will be added. If not, the class name will be
24 * "no-cssgradients". This allows for simple if-conditionals in your
25 * CSS, giving you fine control over the look & feel of your website.
26 *
27 * @author        Faruk Ates
28 * @author        Paul Irish
29 * @copyright     (c) 2009-2011 Faruk Ates.
30 * @contributor   Ben Alman
31 */
32
33window.Modernizr = (function(window,document,undefined){
34   
35    var version = '1.7',
36
37    ret = {},
38
39    /**
40     * !! DEPRECATED !!
41     *
42     * enableHTML5 is a private property for advanced use only. If enabled,
43     * it will make Modernizr.init() run through a brief while() loop in
44     * which it will create all HTML5 elements in the DOM to allow for
45     * styling them in Internet Explorer, which does not recognize any
46     * non-HTML4 elements unless created in the DOM this way.
47     *
48     * enableHTML5 is ON by default.
49     *
50     * The enableHTML5 toggle option is DEPRECATED as per 1.6, and will be
51     * replaced in 2.0 in lieu of the modular, configurable nature of 2.0.
52     */
53    enableHTML5 = true,
54   
55   
56    docElement = document.documentElement,
57    docHead = document.head || document.getElementsByTagName('head')[0],
58
59    /**
60     * Create our "modernizr" element that we do most feature tests on.
61     */
62    mod = 'modernizr',
63    modElem = document.createElement( mod ),
64    m_style = modElem.style,
65
66    /**
67     * Create the input element for various Web Forms feature tests.
68     */
69    inputElem = document.createElement( 'input' ),
70   
71    smile = ':)',
72   
73    tostring = Object.prototype.toString,
74   
75    // List of property values to set for css tests. See ticket #21
76    prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
77
78    // Following spec is to expose vendor-specific style properties as:
79    //   elem.style.WebkitBorderRadius
80    // and the following would be incorrect:
81    //   elem.style.webkitBorderRadius
82   
83    // Webkit ghosts their properties in lowercase but Opera & Moz do not.
84    // Microsoft foregoes prefixes entirely <= IE8, but appears to
85    //   use a lowercase `ms` instead of the correct `Ms` in IE9
86   
87    // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
88    domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
89
90    ns = {'svg': 'http://www.w3.org/2000/svg'},
91
92    tests = {},
93    inputs = {},
94    attrs = {},
95   
96    classes = [],
97   
98    featurename, // used in testing loop
99   
100   
101   
102    // todo: consider using http://javascript.nwbox.com/CSSSupport/css-support.js instead
103    testMediaQuery = function(mq){
104
105      var st = document.createElement('style'),
106          div = document.createElement('div'),
107          ret;
108
109      st.textContent = mq + '{#modernizr{height:3px}}';
110      docHead.appendChild(st);
111      div.id = 'modernizr';
112      docElement.appendChild(div);
113
114      ret = div.offsetHeight === 3;
115
116      st.parentNode.removeChild(st);
117      div.parentNode.removeChild(div);
118
119      return !!ret;
120
121    },
122   
123   
124    /**
125      * isEventSupported determines if a given element supports the given event
126      * function from http://yura.thinkweb2.com/isEventSupported/
127      */
128    isEventSupported = (function(){
129
130      var TAGNAMES = {
131        'select':'input','change':'input',
132        'submit':'form','reset':'form',
133        'error':'img','load':'img','abort':'img'
134      };
135
136      function isEventSupported(eventName, element) {
137
138        element = element || document.createElement(TAGNAMES[eventName] || 'div');
139        eventName = 'on' + eventName;
140
141        // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
142        var isSupported = (eventName in element);
143
144        if (!isSupported) {
145          // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
146          if (!element.setAttribute) {
147            element = document.createElement('div');
148          }
149          if (element.setAttribute && element.removeAttribute) {
150            element.setAttribute(eventName, '');
151            isSupported = is(element[eventName], 'function');
152
153            // If property was created, "remove it" (by setting value to `undefined`)
154            if (!is(element[eventName], undefined)) {
155              element[eventName] = undefined;
156            }
157            element.removeAttribute(eventName);
158          }
159        }
160
161        element = null;
162        return isSupported;
163      }
164      return isEventSupported;
165    })();
166   
167   
168    // hasOwnProperty shim by kangax needed for Safari 2.0 support
169    var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
170    if (!is(_hasOwnProperty, undefined) && !is(_hasOwnProperty.call, undefined)) {
171      hasOwnProperty = function (object, property) {
172        return _hasOwnProperty.call(object, property);
173      };
174    }
175    else {
176      hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
177        return ((property in object) && is(object.constructor.prototype[property], undefined));
178      };
179    }
180   
181    /**
182     * set_css applies given styles to the Modernizr DOM node.
183     */
184    function set_css( str ) {
185        m_style.cssText = str;
186    }
187
188    /**
189     * set_css_all extrapolates all vendor-specific css strings.
190     */
191    function set_css_all( str1, str2 ) {
192        return set_css(prefixes.join(str1 + ';') + ( str2 || '' ));
193    }
194
195    /**
196     * is returns a boolean for if typeof obj is exactly type.
197     */
198    function is( obj, type ) {
199        return typeof obj === type;
200    }
201
202    /**
203     * contains returns a boolean for if substr is found within str.
204     */
205    function contains( str, substr ) {
206        return (''+str).indexOf( substr ) !== -1;
207    }
208
209    /**
210     * test_props is a generic CSS / DOM property test; if a browser supports
211     *   a certain property, it won't return undefined for it.
212     *   A supported CSS property returns empty string when its not yet set.
213     */
214    function test_props( props, callback ) {
215        for ( var i in props ) {
216            if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], modElem ) ) ) {
217                return true;
218            }
219        }
220    }
221
222    /**
223     * test_props_all tests a list of DOM properties we want to check against.
224     *   We specify literally ALL possible (known and/or likely) properties on
225     *   the element including the non-vendor prefixed one, for forward-
226     *   compatibility.
227     */
228    function test_props_all( prop, callback ) {
229     
230        var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1),
231            props   = (prop + ' ' + domPrefixes.join(uc_prop + ' ') + uc_prop).split(' ');
232
233        return !!test_props( props, callback );
234    }
235   
236
237    /**
238     * Tests
239     * -----
240     */
241
242    tests['flexbox'] = function() {
243        /**
244         * set_prefixed_value_css sets the property of a specified element
245         * adding vendor prefixes to the VALUE of the property.
246         * @param {Element} element
247         * @param {string} property The property name. This will not be prefixed.
248         * @param {string} value The value of the property. This WILL be prefixed.
249         * @param {string=} extra Additional CSS to append unmodified to the end of
250         * the CSS string.
251         */
252        function set_prefixed_value_css(element, property, value, extra) {
253            property += ':';
254            element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
255        }
256
257        /**
258         * set_prefixed_property_css sets the property of a specified element
259         * adding vendor prefixes to the NAME of the property.
260         * @param {Element} element
261         * @param {string} property The property name. This WILL be prefixed.
262         * @param {string} value The value of the property. This will not be prefixed.
263         * @param {string=} extra Additional CSS to append unmodified to the end of
264         * the CSS string.
265         */
266        function set_prefixed_property_css(element, property, value, extra) {
267            element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
268        }
269
270        var c = document.createElement('div'),
271            elem = document.createElement('div');
272
273        set_prefixed_value_css(c, 'display', 'box', 'width:42px;padding:0;');
274        set_prefixed_property_css(elem, 'box-flex', '1', 'width:10px;');
275
276        c.appendChild(elem);
277        docElement.appendChild(c);
278
279        var ret = elem.offsetWidth === 42;
280
281        c.removeChild(elem);
282        docElement.removeChild(c);
283
284        return ret;
285    };
286   
287    // On the S60 and BB Storm, getContext exists, but always returns undefined
288    // http://github.com/Modernizr/Modernizr/issues/issue/97/
289   
290    tests['canvas'] = function() {
291        var elem = document.createElement( 'canvas' );
292        return !!(elem.getContext && elem.getContext('2d'));
293    };
294   
295    tests['canvastext'] = function() {
296        return !!(ret['canvas'] && is(document.createElement( 'canvas' ).getContext('2d').fillText, 'function'));
297    };
298   
299    // This WebGL test false positives in FF depending on graphics hardware. But really it's quite impossible to know
300    // wether webgl will succeed until after you create the context. You might have hardware that can support
301    // a 100x100 webgl canvas, but will not support a 1000x1000 webgl canvas. So this feature inference is weak,
302    // but intentionally so.
303    tests['webgl'] = function(){
304        return !!window.WebGLRenderingContext;
305    };
306   
307    /*
308     * The Modernizr.touch test only indicates if the browser supports
309     *    touch events, which does not necessarily reflect a touchscreen
310     *    device, as evidenced by tablets running Windows 7 or, alas,
311     *    the Palm Pre / WebOS (touch) phones.
312     *   
313     * Additionally, Chrome (desktop) used to lie about its support on this,
314     *    but that has since been rectified: http://crbug.com/36415
315     *   
316     * We also test for Firefox 4 Multitouch Support.
317     *
318     * For more info, see: http://modernizr.github.com/Modernizr/touch.html
319     */
320     
321    tests['touch'] = function() {
322
323        return ('ontouchstart' in window) || testMediaQuery('@media ('+prefixes.join('touch-enabled),(')+'modernizr)');
324
325    };
326
327
328    /**
329     * geolocation tests for the new Geolocation API specification.
330     *   This test is a standards compliant-only test; for more complete
331     *   testing, including a Google Gears fallback, please see:
332     *   http://code.google.com/p/geo-location-javascript/
333     * or view a fallback solution using google's geo API:
334     *   http://gist.github.com/366184
335     */
336    tests['geolocation'] = function() {
337        return !!navigator.geolocation;
338    };
339
340    // Per 1.6:
341    // This used to be Modernizr.crosswindowmessaging but the longer
342    // name has been deprecated in favor of a shorter and property-matching one.
343    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
344    // and in the first release thereafter disappear entirely.
345    tests['postmessage'] = function() {
346      return !!window.postMessage;
347    };
348
349    // Web SQL database detection is tricky:
350
351    // In chrome incognito mode, openDatabase is truthy, but using it will
352    //   throw an exception: http://crbug.com/42380
353    // We can create a dummy database, but there is no way to delete it afterwards.
354   
355    // Meanwhile, Safari users can get prompted on any database creation.
356    //   If they do, any page with Modernizr will give them a prompt:
357    //   http://github.com/Modernizr/Modernizr/issues/closed#issue/113
358   
359    // We have chosen to allow the Chrome incognito false positive, so that Modernizr
360    //   doesn't litter the web with these test databases. As a developer, you'll have
361    //   to account for this gotcha yourself.
362    tests['websqldatabase'] = function() {
363      var result = !!window.openDatabase;
364      /*  if (result){
365            try {
366              result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
367            } catch(e) {
368            }
369          }  */
370      return result;
371    };
372   
373    // Vendors have inconsistent prefixing with the experimental Indexed DB:
374    // - Firefox is shipping indexedDB in FF4 as moz_indexedDB
375    // - Webkit's implementation is accessible through webkitIndexedDB
376    // We test both styles.
377    tests['indexedDB'] = function(){
378      for (var i = -1, len = domPrefixes.length; ++i < len; ){
379        var prefix = domPrefixes[i].toLowerCase();
380        if (window[prefix + '_indexedDB'] || window[prefix + 'IndexedDB']){
381          return true;
382        }
383      }
384      return false;
385    };
386
387    // documentMode logic from YUI to filter out IE8 Compat Mode
388    //   which false positives.
389    tests['hashchange'] = function() {
390      return isEventSupported('hashchange', window) && ( document.documentMode === undefined || document.documentMode > 7 );
391    };
392
393    // Per 1.6:
394    // This used to be Modernizr.historymanagement but the longer
395    // name has been deprecated in favor of a shorter and property-matching one.
396    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
397    // and in the first release thereafter disappear entirely.
398    tests['history'] = function() {
399      return !!(window.history && history.pushState);
400    };
401
402    tests['draganddrop'] = function() {
403        return isEventSupported('dragstart') && isEventSupported('drop');
404    };
405   
406    tests['websockets'] = function(){
407        return ('WebSocket' in window);
408    };
409   
410   
411    // http://css-tricks.com/rgba-browser-support/
412    tests['rgba'] = function() {
413        // Set an rgba() color and check the returned value
414       
415        set_css(  'background-color:rgba(150,255,150,.5)' );
416       
417        return contains( m_style.backgroundColor, 'rgba' );
418    };
419   
420    tests['hsla'] = function() {
421        // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
422        //   except IE9 who retains it as hsla
423       
424        set_css('background-color:hsla(120,40%,100%,.5)' );
425       
426        return contains( m_style.backgroundColor, 'rgba' ) || contains( m_style.backgroundColor, 'hsla' );
427    };
428   
429    tests['multiplebgs'] = function() {
430        // Setting multiple images AND a color on the background shorthand property
431        //  and then querying the style.background property value for the number of
432        //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
433       
434        set_css( 'background:url(//:),url(//:),red url(//:)' );
435       
436        // If the UA supports multiple backgrounds, there should be three occurrences
437        //   of the string "url(" in the return value for elem_style.background
438
439        return new RegExp("(url\\s*\\(.*?){3}").test(m_style.background);
440    };
441   
442   
443    // In testing support for a given CSS property, it's legit to test:
444    //    `elem.style[styleName] !== undefined`
445    // If the property is supported it will return an empty string,
446    // if unsupported it will return undefined.
447   
448    // We'll take advantage of this quick test and skip setting a style
449    // on our modernizr element, but instead just testing undefined vs
450    // empty string.
451   
452
453    tests['backgroundsize'] = function() {
454        return test_props_all( 'backgroundSize' );
455    };
456   
457    tests['borderimage'] = function() {
458        return test_props_all( 'borderImage' );
459    };
460   
461   
462    // Super comprehensive table about all the unique implementations of
463    // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
464   
465    tests['borderradius'] = function() {
466        return test_props_all( 'borderRadius', '', function( prop ) {
467            return contains( prop, 'orderRadius' );
468        });
469    };
470   
471    // WebOS unfortunately false positives on this test.
472    tests['boxshadow'] = function() {
473        return test_props_all( 'boxShadow' );
474    };
475   
476    // FF3.0 will false positive on this test
477    tests['textshadow'] = function(){
478        return document.createElement('div').style.textShadow === '';
479    };
480   
481   
482    tests['opacity'] = function() {
483        // Browsers that actually have CSS Opacity implemented have done so
484        //  according to spec, which means their return values are within the
485        //  range of [0.0,1.0] - including the leading zero.
486       
487        set_css_all( 'opacity:.55' );
488       
489        // The non-literal . in this regex is intentional:
490        //   German Chrome returns this value as 0,55
491        // https://github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
492        return /^0.55$/.test(m_style.opacity);
493    };
494   
495   
496    tests['cssanimations'] = function() {
497        return test_props_all( 'animationName' );
498    };
499   
500   
501    tests['csscolumns'] = function() {
502        return test_props_all( 'columnCount' );
503    };
504   
505   
506    tests['cssgradients'] = function() {
507        /**
508         * For CSS Gradients syntax, please see:
509         * http://webkit.org/blog/175/introducing-css-gradients/
510         * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
511         * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
512         * http://dev.w3.org/csswg/css3-images/#gradients-
513         */
514       
515        var str1 = 'background-image:',
516            str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
517            str3 = 'linear-gradient(left top,#9f9, white);';
518       
519        set_css(
520            (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length)
521        );
522       
523        return contains( m_style.backgroundImage, 'gradient' );
524    };
525   
526   
527    tests['cssreflections'] = function() {
528        return test_props_all( 'boxReflect' );
529    };
530   
531   
532    tests['csstransforms'] = function() {
533        return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
534    };
535   
536   
537    tests['csstransforms3d'] = function() {
538       
539        var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]);
540       
541        // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
542        //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
543        //   some conditions. As a result, Webkit typically recognizes the syntax but
544        //   will sometimes throw a false positive, thus we must do a more thorough check:
545        if (ret && 'webkitPerspective' in docElement.style){
546         
547          // Webkit allows this media query to succeed only if the feature is enabled.   
548          // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }`   
549          ret = testMediaQuery('@media ('+prefixes.join('transform-3d),(')+'modernizr)');
550        }
551        return ret;
552    };
553   
554   
555    tests['csstransitions'] = function() {
556        return test_props_all( 'transitionProperty' );
557    };
558
559
560    // @font-face detection routine by Diego Perini
561    // http://javascript.nwbox.com/CSSSupport/
562    tests['fontface'] = function(){
563
564        var
565        sheet, bool,
566        head = docHead || docElement,
567        style = document.createElement("style"),
568        impl = document.implementation || { hasFeature: function() { return false; } };
569       
570        style.type = 'text/css';
571        head.insertBefore(style, head.firstChild);
572        sheet = style.sheet || style.styleSheet;
573
574        var supportAtRule = impl.hasFeature('CSS2', '') ?
575                function(rule) {
576                    if (!(sheet && rule)) return false;
577                    var result = false;
578                    try {
579                        sheet.insertRule(rule, 0);
580                        result = (/src/i).test(sheet.cssRules[0].cssText);
581                        sheet.deleteRule(sheet.cssRules.length - 1);
582                    } catch(e) { }
583                    return result;
584                } :
585                function(rule) {
586                    if (!(sheet && rule)) return false;
587                    sheet.cssText = rule;
588                   
589                    return sheet.cssText.length !== 0 && (/src/i).test(sheet.cssText) &&
590                      sheet.cssText
591                            .replace(/\r+|\n+/g, '')
592                            .indexOf(rule.split(' ')[0]) === 0;
593                };
594       
595        bool = supportAtRule('@font-face { font-family: "font"; src: url(data:,); }');
596        head.removeChild(style);
597        return bool;
598    };
599   
600
601    // These tests evaluate support of the video/audio elements, as well as
602    // testing what types of content they support.
603    //
604    // We're using the Boolean constructor here, so that we can extend the value
605    // e.g.  Modernizr.video     // true
606    //       Modernizr.video.ogg // 'probably'
607    //
608    // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
609    //                     thx to NielsLeenheer and zcorpan
610   
611    // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
612    //   Modernizr does not normalize for that.
613   
614    tests['video'] = function() {
615        var elem = document.createElement('video'),
616            bool = !!elem.canPlayType;
617       
618        if (bool){ 
619            bool      = new Boolean(bool); 
620            bool.ogg  = elem.canPlayType('video/ogg; codecs="theora"');
621           
622            // Workaround required for IE9, which doesn't report video support without audio codec specified.
623            //   bug 599718 @ msft connect
624            var h264 = 'video/mp4; codecs="avc1.42E01E';
625            bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
626           
627            bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
628        }
629        return bool;
630    };
631   
632    tests['audio'] = function() {
633        var elem = document.createElement('audio'),
634            bool = !!elem.canPlayType;
635       
636        if (bool){ 
637            bool      = new Boolean(bool); 
638            bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"');
639            bool.mp3  = elem.canPlayType('audio/mpeg;');
640           
641            // Mimetypes accepted:
642            //   https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
643            //   http://bit.ly/iphoneoscodecs
644            bool.wav  = elem.canPlayType('audio/wav; codecs="1"');
645            bool.m4a  = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
646        }
647        return bool;
648    };
649
650
651    // Firefox has made these tests rather unfun.
652
653    // In FF4, if disabled, window.localStorage should === null.
654
655    // Normally, we could not test that directly and need to do a
656    //   `('localStorage' in window) && ` test first because otherwise Firefox will
657    //   throw http://bugzil.la/365772 if cookies are disabled
658
659    // However, in Firefox 4 betas, if dom.storage.enabled == false, just mentioning
660    //   the property will throw an exception. http://bugzil.la/599479
661    // This looks to be fixed for FF4 Final.
662
663    // Because we are forced to try/catch this, we'll go aggressive.
664
665    // FWIW: IE8 Compat mode supports these features completely:
666    //   http://www.quirksmode.org/dom/html5.html
667    // But IE8 doesn't support either with local files
668
669    tests['localstorage'] = function() {
670        try {
671            return !!localStorage.getItem;
672        } catch(e) {
673            return false;
674        }
675    };
676
677    tests['sessionstorage'] = function() {
678        try {
679            return !!sessionStorage.getItem;
680        } catch(e){
681            return false;
682        }
683    };
684
685
686    tests['webWorkers'] = function () {
687        return !!window.Worker;
688    };
689
690
691    tests['applicationcache'] =  function() {
692        return !!window.applicationCache;
693    };
694
695 
696    // Thanks to Erik Dahlstrom
697    tests['svg'] = function(){
698        return !!document.createElementNS && !!document.createElementNS(ns.svg, "svg").createSVGRect;
699    };
700
701    tests['inlinesvg'] = function() {
702      var div = document.createElement('div');
703      div.innerHTML = '<svg/>';
704      return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
705    };
706
707    // Thanks to F1lt3r and lucideer
708    // http://github.com/Modernizr/Modernizr/issues#issue/35
709    tests['smil'] = function(){
710        return !!document.createElementNS && /SVG/.test(tostring.call(document.createElementNS(ns.svg,'animate')));
711    };
712
713    tests['svgclippaths'] = function(){
714        // Possibly returns a false positive in Safari 3.2?
715        return !!document.createElementNS && /SVG/.test(tostring.call(document.createElementNS(ns.svg,'clipPath')));
716    };
717
718
719    // input features and input types go directly onto the ret object, bypassing the tests loop.
720    // Hold this guy to execute in a moment.
721    function webforms(){
722   
723        // Run through HTML5's new input attributes to see if the UA understands any.
724        // We're using f which is the <input> element created early on
725        // Mike Taylr has created a comprehensive resource for testing these attributes
726        //   when applied to all input types:
727        //   http://miketaylr.com/code/input-type-attr.html
728        // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
729        ret['input'] = (function(props) {
730            for (var i = 0, len = props.length; i<len; i++) {
731                attrs[ props[i] ] = !!(props[i] in inputElem);
732            }
733            return attrs;
734        })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
735
736        // Run through HTML5's new input types to see if the UA understands any.
737        //   This is put behind the tests runloop because it doesn't return a
738        //   true/false like all the other tests; instead, it returns an object
739        //   containing each input type with its corresponding true/false value
740       
741        // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
742        ret['inputtypes'] = (function(props) {
743         
744            for (var i = 0, bool, inputElemType, defaultView, len=props.length; i < len; i++) {
745             
746                inputElem.setAttribute('type', inputElemType = props[i]);
747                bool = inputElem.type !== 'text';
748               
749                // We first check to see if the type we give it sticks..
750                // If the type does, we feed it a textual value, which shouldn't be valid.
751                // If the value doesn't stick, we know there's input sanitization which infers a custom UI
752                if (bool){ 
753                 
754                    inputElem.value         = smile;
755                    inputElem.style.cssText = 'position:absolute;visibility:hidden;';
756     
757                    if (/^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined){
758                     
759                      docElement.appendChild(inputElem);
760                      defaultView = document.defaultView;
761                     
762                      // Safari 2-4 allows the smiley as a value, despite making a slider
763                      bool =  defaultView.getComputedStyle &&
764                              defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&                 
765                              // Mobile android web browser has false positive, so must
766                              // check the height to see if the widget is actually there.
767                              (inputElem.offsetHeight !== 0);
768                             
769                      docElement.removeChild(inputElem);
770                             
771                    } else if (/^(search|tel)$/.test(inputElemType)){
772                      // Spec doesnt define any special parsing or detectable UI
773                      //   behaviors so we pass these through as true
774                     
775                      // Interestingly, opera fails the earlier test, so it doesn't
776                      //  even make it here.
777                     
778                    } else if (/^(url|email)$/.test(inputElemType)) {
779                      // Real url and email support comes with prebaked validation.
780                      bool = inputElem.checkValidity && inputElem.checkValidity() === false;
781                     
782                    } else if (/^color$/.test(inputElemType)) {
783                        // chuck into DOM and force reflow for Opera bug in 11.00
784                        // github.com/Modernizr/Modernizr/issues#issue/159
785                        docElement.appendChild(inputElem);
786                        docElement.offsetWidth;
787                        bool = inputElem.value != smile;
788                        docElement.removeChild(inputElem);
789
790                    } else {
791                      // If the upgraded input compontent rejects the :) text, we got a winner
792                      bool = inputElem.value != smile;
793                    }
794                }
795               
796                inputs[ props[i] ] = !!bool;
797            }
798            return inputs;
799        })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
800
801    }
802
803
804
805    // End of test definitions
806    // -----------------------
807
808
809
810    // Run through all tests and detect their support in the current UA.
811    // todo: hypothetically we could be doing an array of tests and use a basic loop here.
812    for ( var feature in tests ) {
813        if ( hasOwnProperty( tests, feature ) ) {
814            // run the test, throw the return value into the Modernizr,
815            //   then based on that boolean, define an appropriate className
816            //   and push it into an array of classes we'll join later.
817            featurename  = feature.toLowerCase();
818            ret[ featurename ] = tests[ feature ]();
819
820            classes.push( ( ret[ featurename ] ? '' : 'no-' ) + featurename );
821        }
822    }
823   
824    // input tests need to run.
825    if (!ret.input) webforms();
826   
827
828   
829    // Per 1.6: deprecated API is still accesible for now:
830    ret.crosswindowmessaging = ret.postmessage;
831    ret.historymanagement = ret.history;
832
833
834
835    /**
836     * Addtest allows the user to define their own feature tests
837     * the result will be added onto the Modernizr object,
838     * as well as an appropriate className set on the html element
839     *
840     * @param feature - String naming the feature
841     * @param test - Function returning true if feature is supported, false if not
842     */
843    ret.addTest = function (feature, test) {
844      feature = feature.toLowerCase();
845     
846      if (ret[ feature ]) {
847        return; // quit if you're trying to overwrite an existing test
848      }
849      test = !!(test());
850      docElement.className += ' ' + (test ? '' : 'no-') + feature;
851      ret[ feature ] = test;
852      return ret; // allow chaining.
853    };
854
855    /**
856     * Reset m.style.cssText to nothing to reduce memory footprint.
857     */
858    set_css( '' );
859    modElem = inputElem = null;
860
861    //>>BEGIN IEPP
862    // Enable HTML 5 elements for styling in IE.
863    // fyi: jscript version does not reflect trident version
864    //      therefore ie9 in ie7 mode will still have a jScript v.9
865    if ( enableHTML5 && window.attachEvent && (function(){ var elem = document.createElement("div");
866                                      elem.innerHTML = "<elem></elem>";
867                                      return elem.childNodes.length !== 1; })()) {
868        // iepp v1.6.2 by @jon_neal : code.google.com/p/ie-print-protector
869        (function(win, doc) {
870          var elems = 'abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video',
871            elemsArr = elems.split('|'),
872            elemsArrLen = elemsArr.length,
873            elemRegExp = new RegExp('(^|\\s)('+elems+')', 'gi'),
874            tagRegExp = new RegExp('<(\/*)('+elems+')', 'gi'),
875            ruleRegExp = new RegExp('(^|[^\\n]*?\\s)('+elems+')([^\\n]*)({[\\n\\w\\W]*?})', 'gi'),
876            docFrag = doc.createDocumentFragment(),
877            html = doc.documentElement,
878            head = html.firstChild,
879            bodyElem = doc.createElement('body'),
880            styleElem = doc.createElement('style'),
881            body;
882          function shim(doc) {
883            var a = -1;
884            while (++a < elemsArrLen)
885              // Use createElement so IE allows HTML5-named elements in a document
886              doc.createElement(elemsArr[a]);
887          }
888          function getCSS(styleSheetList, mediaType) {
889            var a = -1,
890              len = styleSheetList.length,
891              styleSheet,
892              cssTextArr = [];
893            while (++a < len) {
894              styleSheet = styleSheetList[a];
895              // Get css from all non-screen stylesheets and their imports
896              if ((mediaType = styleSheet.media || mediaType) != 'screen') cssTextArr.push(getCSS(styleSheet.imports, mediaType), styleSheet.cssText);
897            }
898            return cssTextArr.join('');
899          }
900          // Shim the document and iepp fragment
901          shim(doc);
902          shim(docFrag);
903          // Add iepp custom print style element
904          head.insertBefore(styleElem, head.firstChild);
905          styleElem.media = 'print';
906          win.attachEvent(
907            'onbeforeprint',
908            function() {
909              var a = -1,
910                cssText = getCSS(doc.styleSheets, 'all'),
911                cssTextArr = [],
912                rule;
913              body = body || doc.body;
914              // Get only rules which reference HTML5 elements by name
915              while ((rule = ruleRegExp.exec(cssText)) != null)
916                // Replace all html5 element references with iepp substitute classnames
917                cssTextArr.push((rule[1]+rule[2]+rule[3]).replace(elemRegExp, '$1.iepp_$2')+rule[4]);
918              // Write iepp custom print CSS
919              styleElem.styleSheet.cssText = cssTextArr.join('\n');
920              while (++a < elemsArrLen) {
921                var nodeList = doc.getElementsByTagName(elemsArr[a]),
922                  nodeListLen = nodeList.length,
923                  b = -1;
924                while (++b < nodeListLen)
925                  if (nodeList[b].className.indexOf('iepp_') < 0)
926                    // Append iepp substitute classnames to all html5 elements
927                    nodeList[b].className += ' iepp_'+elemsArr[a];
928              }
929              docFrag.appendChild(body);
930              html.appendChild(bodyElem);
931              // Write iepp substitute print-safe document
932              bodyElem.className = body.className;
933              // Replace HTML5 elements with <font> which is print-safe and shouldn't conflict since it isn't part of html5
934              bodyElem.innerHTML = body.innerHTML.replace(tagRegExp, '<$1font');
935            }
936          );
937          win.attachEvent(
938            'onafterprint',
939            function() {
940              // Undo everything done in onbeforeprint
941              bodyElem.innerHTML = '';
942              html.removeChild(bodyElem);
943              html.appendChild(body);
944              styleElem.styleSheet.cssText = '';
945            }
946          );
947        })(window, document);
948    }
949    //>>END IEPP
950
951    // Assign private properties to the return object with prefix
952    ret._enableHTML5     = enableHTML5;
953    ret._version         = version;
954
955    // Remove "no-js" class from <html> element, if it exists:
956    docElement.className = docElement.className.replace(/\bno-js\b/,'')
957                            + ' js '
958
959                            // Add the new classes to the <html> element.
960                            + classes.join( ' ' );
961   
962    return ret;
963
964})(this,this.document);
Note: See TracBrowser for help on using the repository browser.