modernizr-rails 2.6.2.2 → 2.6.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -2
- data/lib/modernizr/rails/version.rb +1 -1
- data/vendor/assets/javascripts/modernizr.js +754 -2102
- metadata +2 -2
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# modernizr-rails
|
2
2
|
|
3
|
-
The modernizr-rails gem will include the [Modernizr.js](https://github.com/Modernizr/Modernizr) library into your `Rails 3.1+` app via the asset pipeline. This
|
3
|
+
The modernizr-rails gem will include the [Modernizr.js](https://github.com/Modernizr/Modernizr) library into your `Rails 3.1+` app via the asset pipeline. This gem is bundled with the development version from the [Modernizr site](http://modernizr.com), which is minified by the Rails Assets Pipeline for you automatically. If you need custom feature detection tests, consider the [Custom feature detection tests](#custom-feature-detection-tests) section in this README.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
Add the following to your `assets` group in your Gemfile:
|
@@ -21,7 +21,7 @@ Example of your `app/views/layouts/application.html.erb`:
|
|
21
21
|
```erb
|
22
22
|
<html>
|
23
23
|
<head>
|
24
|
-
<title>Your App</title>
|
24
|
+
<title>Your Awesome App</title>
|
25
25
|
<%= stylesheet_link_tag :application, media: :all %>
|
26
26
|
<%= javascript_include_tag :modernizr %>
|
27
27
|
<%= csrf_meta_tags %>
|
@@ -33,6 +33,15 @@ Example of your `app/views/layouts/application.html.erb`:
|
|
33
33
|
</html>
|
34
34
|
```
|
35
35
|
|
36
|
+
## Custom feature detection tests
|
37
|
+
I you need a custom feature detection test not included in the Modernizr build shipped with this gem, please consider using your own version instead of sending a pull request to include your test. You can easily do this by moving your Modernizr build in to one of the assets folder. Rails will automagically use your build instead of the shipped one. However you can still continue to use this gem and its features (like the precompile hook, and so on).
|
38
|
+
|
39
|
+
1. Configure your build on [modernizr.com/download](http://modernizr.com/download/).
|
40
|
+
2. Download it.
|
41
|
+
3. Rename it from `modernizr.custom.12345.js` to just `modernizr.js`.
|
42
|
+
4. Move it to your asset pipeline folder, ideally `vendor/assets/javascripts`.
|
43
|
+
5. Enjoy your custom build! :)
|
44
|
+
|
36
45
|
## Contributing
|
37
46
|
|
38
47
|
1. Fork it
|
@@ -1,9 +1,26 @@
|
|
1
|
-
|
2
|
-
*
|
1
|
+
/*!
|
2
|
+
* Modernizr v2.6.2
|
3
|
+
* www.modernizr.com
|
4
|
+
*
|
5
|
+
* Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
|
6
|
+
* Available under the BSD and MIT licenses: www.modernizr.com/license/
|
3
7
|
*/
|
4
|
-
;
|
5
|
-
|
6
8
|
|
9
|
+
/*
|
10
|
+
* Modernizr tests which native CSS3 and HTML5 features are available in
|
11
|
+
* the current UA and makes the results available to you in two ways:
|
12
|
+
* as properties on a global Modernizr object, and as classes on the
|
13
|
+
* <html> element. This information allows you to progressively enhance
|
14
|
+
* your pages with a granular level of control over the experience.
|
15
|
+
*
|
16
|
+
* Modernizr has an optional (not included) conditional resource loader
|
17
|
+
* called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
|
18
|
+
* To get a build that includes Modernizr.load(), as well as choosing
|
19
|
+
* which tests to include, go to www.modernizr.com/download/
|
20
|
+
*
|
21
|
+
* Authors Faruk Ates, Paul Irish, Alex Sexton
|
22
|
+
* Contributors Ryan Seddon, Ben Alman
|
23
|
+
*/
|
7
24
|
|
8
25
|
window.Modernizr = (function( window, document, undefined ) {
|
9
26
|
|
@@ -11,31 +28,58 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
11
28
|
|
12
29
|
Modernizr = {},
|
13
30
|
|
31
|
+
/*>>cssclasses*/
|
32
|
+
// option for enabling the HTML classes to be added
|
14
33
|
enableClasses = true,
|
34
|
+
/*>>cssclasses*/
|
15
35
|
|
16
36
|
docElement = document.documentElement,
|
17
37
|
|
38
|
+
/**
|
39
|
+
* Create our "modernizr" element that we do most feature tests on.
|
40
|
+
*/
|
18
41
|
mod = 'modernizr',
|
19
42
|
modElem = document.createElement(mod),
|
20
43
|
mStyle = modElem.style,
|
21
44
|
|
22
|
-
|
45
|
+
/**
|
46
|
+
* Create the input element for various Web Forms feature tests.
|
47
|
+
*/
|
48
|
+
inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
|
23
49
|
|
50
|
+
/*>>smile*/
|
24
51
|
smile = ':)',
|
52
|
+
/*>>smile*/
|
25
53
|
|
26
54
|
toString = {}.toString,
|
27
55
|
|
56
|
+
// TODO :: make the prefixes more granular
|
57
|
+
/*>>prefixes*/
|
58
|
+
// List of property values to set for css tests. See ticket #21
|
28
59
|
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
|
60
|
+
/*>>prefixes*/
|
29
61
|
|
62
|
+
/*>>domprefixes*/
|
63
|
+
// Following spec is to expose vendor-specific style properties as:
|
64
|
+
// elem.style.WebkitBorderRadius
|
65
|
+
// and the following would be incorrect:
|
66
|
+
// elem.style.webkitBorderRadius
|
30
67
|
|
68
|
+
// Webkit ghosts their properties in lowercase but Opera & Moz do not.
|
69
|
+
// Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
|
70
|
+
// erik.eae.net/archives/2008/03/10/21.48.10/
|
31
71
|
|
72
|
+
// More here: github.com/Modernizr/Modernizr/issues/issue/21
|
32
73
|
omPrefixes = 'Webkit Moz O ms',
|
33
74
|
|
34
75
|
cssomPrefixes = omPrefixes.split(' '),
|
35
76
|
|
36
77
|
domPrefixes = omPrefixes.toLowerCase().split(' '),
|
78
|
+
/*>>domprefixes*/
|
37
79
|
|
80
|
+
/*>>ns*/
|
38
81
|
ns = {'svg': 'http://www.w3.org/2000/svg'},
|
82
|
+
/*>>ns*/
|
39
83
|
|
40
84
|
tests = {},
|
41
85
|
inputs = {},
|
@@ -45,38 +89,54 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
45
89
|
|
46
90
|
slice = classes.slice,
|
47
91
|
|
48
|
-
featureName,
|
92
|
+
featureName, // used in testing loop
|
49
93
|
|
50
94
|
|
95
|
+
/*>>teststyles*/
|
96
|
+
// Inject element with style element and some CSS rules
|
51
97
|
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
|
52
98
|
|
53
99
|
var style, ret, node, docOverflow,
|
54
100
|
div = document.createElement('div'),
|
55
|
-
|
56
|
-
|
101
|
+
// After page load injecting a fake body doesn't work so check if body exists
|
102
|
+
body = document.body,
|
103
|
+
// IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
|
104
|
+
fakeBody = body || document.createElement('body');
|
57
105
|
|
58
106
|
if ( parseInt(nodes, 10) ) {
|
59
|
-
|
107
|
+
// In order not to give false positives we create a node for each test
|
108
|
+
// This also allows the method to scale for unspecified uses
|
109
|
+
while ( nodes-- ) {
|
60
110
|
node = document.createElement('div');
|
61
111
|
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
|
62
112
|
div.appendChild(node);
|
63
113
|
}
|
64
114
|
}
|
65
115
|
|
66
|
-
|
116
|
+
// <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
|
117
|
+
// when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
|
118
|
+
// with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
|
119
|
+
// msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
|
120
|
+
// Documents served as xml will throw if using ­ so use xml friendly encoded version. See issue #277
|
121
|
+
style = ['­','<style id="s', mod, '">', rule, '</style>'].join('');
|
67
122
|
div.id = mod;
|
68
|
-
|
123
|
+
// 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.
|
124
|
+
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
|
125
|
+
(body ? div : fakeBody).innerHTML += style;
|
69
126
|
fakeBody.appendChild(div);
|
70
127
|
if ( !body ) {
|
71
|
-
|
72
|
-
|
128
|
+
//avoid crashing IE8, if background image is used
|
129
|
+
fakeBody.style.background = '';
|
130
|
+
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
|
131
|
+
fakeBody.style.overflow = 'hidden';
|
73
132
|
docOverflow = docElement.style.overflow;
|
74
133
|
docElement.style.overflow = 'hidden';
|
75
134
|
docElement.appendChild(fakeBody);
|
76
135
|
}
|
77
136
|
|
78
137
|
ret = callback(div, rule);
|
79
|
-
|
138
|
+
// If this is done after page load we don't want to remove the body so check if body exists
|
139
|
+
if ( !body ) {
|
80
140
|
fakeBody.parentNode.removeChild(fakeBody);
|
81
141
|
docElement.style.overflow = docOverflow;
|
82
142
|
} else {
|
@@ -86,7 +146,12 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
86
146
|
return !!ret;
|
87
147
|
|
88
148
|
},
|
149
|
+
/*>>teststyles*/
|
89
150
|
|
151
|
+
/*>>mq*/
|
152
|
+
// adapted from matchMedia polyfill
|
153
|
+
// by Scott Jehl and Paul Irish
|
154
|
+
// gist.github.com/786768
|
90
155
|
testMediaQuery = function( mq ) {
|
91
156
|
|
92
157
|
var matchMedia = window.matchMedia || window.msMatchMedia;
|
@@ -105,8 +170,18 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
105
170
|
return bool;
|
106
171
|
|
107
172
|
},
|
108
|
-
|
109
|
-
|
173
|
+
/*>>mq*/
|
174
|
+
|
175
|
+
|
176
|
+
/*>>hasevent*/
|
177
|
+
//
|
178
|
+
// isEventSupported determines if a given element supports the given event
|
179
|
+
// kangax.github.com/iseventsupported/
|
180
|
+
//
|
181
|
+
// The following results are known incorrects:
|
182
|
+
// Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
|
183
|
+
// Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
|
184
|
+
// ...
|
110
185
|
isEventSupported = (function() {
|
111
186
|
|
112
187
|
var TAGNAMES = {
|
@@ -120,17 +195,20 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
120
195
|
element = element || document.createElement(TAGNAMES[eventName] || 'div');
|
121
196
|
eventName = 'on' + eventName;
|
122
197
|
|
123
|
-
|
198
|
+
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
|
199
|
+
var isSupported = eventName in element;
|
124
200
|
|
125
201
|
if ( !isSupported ) {
|
126
|
-
|
202
|
+
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
|
203
|
+
if ( !element.setAttribute ) {
|
127
204
|
element = document.createElement('div');
|
128
205
|
}
|
129
206
|
if ( element.setAttribute && element.removeAttribute ) {
|
130
207
|
element.setAttribute(eventName, '');
|
131
208
|
isSupported = is(element[eventName], 'function');
|
132
209
|
|
133
|
-
|
210
|
+
// If property was created, "remove it" (by setting value to `undefined`)
|
211
|
+
if ( !is(element[eventName], 'undefined') ) {
|
134
212
|
element[eventName] = undefined;
|
135
213
|
}
|
136
214
|
element.removeAttribute(eventName);
|
@@ -142,8 +220,11 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
142
220
|
}
|
143
221
|
return isEventSupported;
|
144
222
|
})(),
|
223
|
+
/*>>hasevent*/
|
145
224
|
|
225
|
+
// TODO :: Add flag for hasownprop ? didn't last time
|
146
226
|
|
227
|
+
// hasOwnProperty shim by kangax needed for Safari 2.0 support
|
147
228
|
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
|
148
229
|
|
149
230
|
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
|
@@ -152,11 +233,13 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
152
233
|
};
|
153
234
|
}
|
154
235
|
else {
|
155
|
-
hasOwnProp = function (object, property) {
|
236
|
+
hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
|
156
237
|
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
|
157
238
|
};
|
158
239
|
}
|
159
240
|
|
241
|
+
// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
|
242
|
+
// es5.github.com/#x15.3.4.5
|
160
243
|
|
161
244
|
if (!Function.prototype.bind) {
|
162
245
|
Function.prototype.bind = function bind(that) {
|
@@ -200,22 +283,54 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
200
283
|
};
|
201
284
|
}
|
202
285
|
|
286
|
+
/**
|
287
|
+
* setCss applies given styles to the Modernizr DOM node.
|
288
|
+
*/
|
203
289
|
function setCss( str ) {
|
204
290
|
mStyle.cssText = str;
|
205
291
|
}
|
206
292
|
|
293
|
+
/**
|
294
|
+
* setCssAll extrapolates all vendor-specific css strings.
|
295
|
+
*/
|
207
296
|
function setCssAll( str1, str2 ) {
|
208
297
|
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
|
209
298
|
}
|
210
299
|
|
300
|
+
/**
|
301
|
+
* is returns a boolean for if typeof obj is exactly type.
|
302
|
+
*/
|
211
303
|
function is( obj, type ) {
|
212
304
|
return typeof obj === type;
|
213
305
|
}
|
214
306
|
|
307
|
+
/**
|
308
|
+
* contains returns a boolean for if substr is found within str.
|
309
|
+
*/
|
215
310
|
function contains( str, substr ) {
|
216
311
|
return !!~('' + str).indexOf(substr);
|
217
312
|
}
|
218
313
|
|
314
|
+
/*>>testprop*/
|
315
|
+
|
316
|
+
// testProps is a generic CSS / DOM property test.
|
317
|
+
|
318
|
+
// In testing support for a given CSS property, it's legit to test:
|
319
|
+
// `elem.style[styleName] !== undefined`
|
320
|
+
// If the property is supported it will return an empty string,
|
321
|
+
// if unsupported it will return undefined.
|
322
|
+
|
323
|
+
// We'll take advantage of this quick test and skip setting a style
|
324
|
+
// on our modernizr element, but instead just testing undefined vs
|
325
|
+
// empty string.
|
326
|
+
|
327
|
+
// Because the testing of the CSS property names (with "-", as
|
328
|
+
// opposed to the camelCase DOM properties) is non-portable and
|
329
|
+
// non-standard but works in WebKit and IE (but not Gecko or Opera),
|
330
|
+
// we explicitly reject properties with dashes so that authors
|
331
|
+
// developing in WebKit or IE first don't end up with
|
332
|
+
// browser-specific content by accident.
|
333
|
+
|
219
334
|
function testProps( props, prefixed ) {
|
220
335
|
for ( var i in props ) {
|
221
336
|
var prop = props[i];
|
@@ -225,45 +340,81 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
225
340
|
}
|
226
341
|
return false;
|
227
342
|
}
|
343
|
+
/*>>testprop*/
|
228
344
|
|
345
|
+
// TODO :: add testDOMProps
|
346
|
+
/**
|
347
|
+
* testDOMProps is a generic DOM property test; if a browser supports
|
348
|
+
* a certain property, it won't return undefined for it.
|
349
|
+
*/
|
229
350
|
function testDOMProps( props, obj, elem ) {
|
230
351
|
for ( var i in props ) {
|
231
352
|
var item = obj[props[i]];
|
232
353
|
if ( item !== undefined) {
|
233
354
|
|
234
|
-
|
355
|
+
// return the property name as a string
|
356
|
+
if (elem === false) return props[i];
|
235
357
|
|
236
|
-
|
237
|
-
|
358
|
+
// let's bind a function
|
359
|
+
if (is(item, 'function')){
|
360
|
+
// default to autobind unless override
|
361
|
+
return item.bind(elem || obj);
|
238
362
|
}
|
239
363
|
|
240
|
-
|
364
|
+
// return the unbound function or obj or value
|
365
|
+
return item;
|
241
366
|
}
|
242
367
|
}
|
243
368
|
return false;
|
244
369
|
}
|
245
370
|
|
371
|
+
/*>>testallprops*/
|
372
|
+
/**
|
373
|
+
* testPropsAll tests a list of DOM properties we want to check against.
|
374
|
+
* We specify literally ALL possible (known and/or likely) properties on
|
375
|
+
* the element including the non-vendor prefixed one, for forward-
|
376
|
+
* compatibility.
|
377
|
+
*/
|
246
378
|
function testPropsAll( prop, prefixed, elem ) {
|
247
379
|
|
248
380
|
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
|
249
381
|
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
|
250
382
|
|
251
|
-
|
383
|
+
// did they call .prefixed('boxSizing') or are we just testing a prop?
|
384
|
+
if(is(prefixed, "string") || is(prefixed, "undefined")) {
|
252
385
|
return testProps(props, prefixed);
|
253
386
|
|
254
|
-
|
387
|
+
// otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
|
388
|
+
} else {
|
255
389
|
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
|
256
390
|
return testDOMProps(props, prefixed, elem);
|
257
391
|
}
|
258
|
-
}
|
392
|
+
}
|
393
|
+
/*>>testallprops*/
|
394
|
+
|
395
|
+
|
396
|
+
/**
|
397
|
+
* Tests
|
398
|
+
* -----
|
399
|
+
*/
|
400
|
+
|
401
|
+
// The *new* flexbox
|
402
|
+
// dev.w3.org/csswg/css3-flexbox
|
403
|
+
|
404
|
+
tests['flexbox'] = function() {
|
259
405
|
return testPropsAll('flexWrap');
|
260
406
|
};
|
261
407
|
|
408
|
+
// The *old* flexbox
|
409
|
+
// www.w3.org/TR/2009/WD-css3-flexbox-20090723/
|
262
410
|
|
263
411
|
tests['flexboxlegacy'] = function() {
|
264
412
|
return testPropsAll('boxDirection');
|
265
413
|
};
|
266
414
|
|
415
|
+
// On the S60 and BB Storm, getContext exists, but always returns undefined
|
416
|
+
// so we actually have to call getContext() to verify
|
417
|
+
// github.com/Modernizr/Modernizr/issues/issue/97/
|
267
418
|
|
268
419
|
tests['canvas'] = function() {
|
269
420
|
var elem = document.createElement('canvas');
|
@@ -274,12 +425,28 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
274
425
|
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
|
275
426
|
};
|
276
427
|
|
428
|
+
// webk.it/70117 is tracking a legit WebGL feature detect proposal
|
277
429
|
|
430
|
+
// We do a soft detect which may false positive in order to avoid
|
431
|
+
// an expensive context creation: bugzil.la/732441
|
278
432
|
|
279
433
|
tests['webgl'] = function() {
|
280
434
|
return !!window.WebGLRenderingContext;
|
281
435
|
};
|
282
436
|
|
437
|
+
/*
|
438
|
+
* The Modernizr.touch test only indicates if the browser supports
|
439
|
+
* touch events, which does not necessarily reflect a touchscreen
|
440
|
+
* device, as evidenced by tablets running Windows 7 or, alas,
|
441
|
+
* the Palm Pre / WebOS (touch) phones.
|
442
|
+
*
|
443
|
+
* Additionally, Chrome (desktop) used to lie about its support on this,
|
444
|
+
* but that has since been rectified: crbug.com/36415
|
445
|
+
*
|
446
|
+
* We also test for Firefox 4 Multitouch Support.
|
447
|
+
*
|
448
|
+
* For more info, see: modernizr.github.com/Modernizr/touch.html
|
449
|
+
*/
|
283
450
|
|
284
451
|
tests['touch'] = function() {
|
285
452
|
var bool;
|
@@ -296,6 +463,15 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
296
463
|
};
|
297
464
|
|
298
465
|
|
466
|
+
// geolocation is often considered a trivial feature detect...
|
467
|
+
// Turns out, it's quite tricky to get right:
|
468
|
+
//
|
469
|
+
// Using !!navigator.geolocation does two things we don't want. It:
|
470
|
+
// 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
|
471
|
+
// 2. Disables page caching in WebKit: webk.it/43956
|
472
|
+
//
|
473
|
+
// Meanwhile, in Firefox < 8, an about:config setting could expose
|
474
|
+
// a false positive that would throw an exception: bugzil.la/688158
|
299
475
|
|
300
476
|
tests['geolocation'] = function() {
|
301
477
|
return 'geolocation' in navigator;
|
@@ -307,18 +483,31 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
307
483
|
};
|
308
484
|
|
309
485
|
|
486
|
+
// Chrome incognito mode used to throw an exception when using openDatabase
|
487
|
+
// It doesn't anymore.
|
310
488
|
tests['websqldatabase'] = function() {
|
311
489
|
return !!window.openDatabase;
|
312
490
|
};
|
313
491
|
|
492
|
+
// Vendors had inconsistent prefixing with the experimental Indexed DB:
|
493
|
+
// - Webkit's implementation is accessible through webkitIndexedDB
|
494
|
+
// - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
|
495
|
+
// For speed, we don't test the legacy (and beta-only) indexedDB
|
314
496
|
tests['indexedDB'] = function() {
|
315
497
|
return !!testPropsAll("indexedDB", window);
|
316
498
|
};
|
317
499
|
|
500
|
+
// documentMode logic from YUI to filter out IE8 Compat Mode
|
501
|
+
// which false positives.
|
318
502
|
tests['hashchange'] = function() {
|
319
503
|
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
|
320
504
|
};
|
321
505
|
|
506
|
+
// Per 1.6:
|
507
|
+
// This used to be Modernizr.historymanagement but the longer
|
508
|
+
// name has been deprecated in favor of a shorter and property-matching one.
|
509
|
+
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
|
510
|
+
// and in the first release thereafter disappear entirely.
|
322
511
|
tests['history'] = function() {
|
323
512
|
return !!(window.history && history.pushState);
|
324
513
|
};
|
@@ -328,28 +517,52 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
328
517
|
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
|
329
518
|
};
|
330
519
|
|
520
|
+
// FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
|
521
|
+
// will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
|
522
|
+
// FF10 still uses prefixes, so check for it until then.
|
523
|
+
// for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
|
331
524
|
tests['websockets'] = function() {
|
332
525
|
return 'WebSocket' in window || 'MozWebSocket' in window;
|
333
526
|
};
|
334
527
|
|
335
528
|
|
529
|
+
// css-tricks.com/rgba-browser-support/
|
336
530
|
tests['rgba'] = function() {
|
531
|
+
// Set an rgba() color and check the returned value
|
532
|
+
|
337
533
|
setCss('background-color:rgba(150,255,150,.5)');
|
338
534
|
|
339
535
|
return contains(mStyle.backgroundColor, 'rgba');
|
340
536
|
};
|
341
537
|
|
342
538
|
tests['hsla'] = function() {
|
343
|
-
|
539
|
+
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
|
540
|
+
// except IE9 who retains it as hsla
|
541
|
+
|
542
|
+
setCss('background-color:hsla(120,40%,100%,.5)');
|
344
543
|
|
345
544
|
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
|
346
545
|
};
|
347
546
|
|
348
547
|
tests['multiplebgs'] = function() {
|
349
|
-
|
548
|
+
// Setting multiple images AND a color on the background shorthand property
|
549
|
+
// and then querying the style.background property value for the number of
|
550
|
+
// occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
|
350
551
|
|
351
|
-
|
352
|
-
|
552
|
+
setCss('background:url(https://),url(https://),red url(https://)');
|
553
|
+
|
554
|
+
// If the UA supports multiple backgrounds, there should be three occurrences
|
555
|
+
// of the string "url(" in the return value for elemStyle.background
|
556
|
+
|
557
|
+
return (/(url\s*\(.*?){3}/).test(mStyle.background);
|
558
|
+
};
|
559
|
+
|
560
|
+
|
561
|
+
|
562
|
+
// this will false positive in Opera Mini
|
563
|
+
// github.com/Modernizr/Modernizr/issues/396
|
564
|
+
|
565
|
+
tests['backgroundsize'] = function() {
|
353
566
|
return testPropsAll('backgroundSize');
|
354
567
|
};
|
355
568
|
|
@@ -358,27 +571,41 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
358
571
|
};
|
359
572
|
|
360
573
|
|
574
|
+
// Super comprehensive table about all the unique implementations of
|
575
|
+
// border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
|
361
576
|
|
362
577
|
tests['borderradius'] = function() {
|
363
578
|
return testPropsAll('borderRadius');
|
364
579
|
};
|
365
580
|
|
581
|
+
// WebOS unfortunately false positives on this test.
|
366
582
|
tests['boxshadow'] = function() {
|
367
583
|
return testPropsAll('boxShadow');
|
368
584
|
};
|
369
585
|
|
586
|
+
// FF3.0 will false positive on this test
|
370
587
|
tests['textshadow'] = function() {
|
371
588
|
return document.createElement('div').style.textShadow === '';
|
372
589
|
};
|
373
590
|
|
374
591
|
|
375
592
|
tests['opacity'] = function() {
|
376
|
-
|
593
|
+
// Browsers that actually have CSS Opacity implemented have done so
|
594
|
+
// according to spec, which means their return values are within the
|
595
|
+
// range of [0.0,1.0] - including the leading zero.
|
377
596
|
|
378
|
-
|
597
|
+
setCssAll('opacity:.55');
|
598
|
+
|
599
|
+
// The non-literal . in this regex is intentional:
|
600
|
+
// German Chrome returns this value as 0,55
|
601
|
+
// github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
|
602
|
+
return (/^0.55$/).test(mStyle.opacity);
|
379
603
|
};
|
380
604
|
|
381
605
|
|
606
|
+
// Note, Android < 4 will pass this test, but can only animate
|
607
|
+
// a single property at a time
|
608
|
+
// daneden.me/2011/12/putting-up-with-androids-bullshit/
|
382
609
|
tests['cssanimations'] = function() {
|
383
610
|
return testPropsAll('animationName');
|
384
611
|
};
|
@@ -390,13 +617,23 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
390
617
|
|
391
618
|
|
392
619
|
tests['cssgradients'] = function() {
|
620
|
+
/**
|
621
|
+
* For CSS Gradients syntax, please see:
|
622
|
+
* webkit.org/blog/175/introducing-css-gradients/
|
623
|
+
* developer.mozilla.org/en/CSS/-moz-linear-gradient
|
624
|
+
* developer.mozilla.org/en/CSS/-moz-radial-gradient
|
625
|
+
* dev.w3.org/csswg/css3-images/#gradients-
|
626
|
+
*/
|
627
|
+
|
393
628
|
var str1 = 'background-image:',
|
394
629
|
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
|
395
630
|
str3 = 'linear-gradient(left top,#9f9, white);';
|
396
631
|
|
397
632
|
setCss(
|
398
|
-
|
399
|
-
|
633
|
+
// legacy webkit syntax (FIXME: remove when syntax not in use anymore)
|
634
|
+
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
|
635
|
+
// standard syntax // trailing 'background-image:'
|
636
|
+
prefixes.join(str3 + str1)).slice(0, -str1.length)
|
400
637
|
);
|
401
638
|
|
402
639
|
return contains(mStyle.backgroundImage, 'gradient');
|
@@ -417,9 +654,15 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
417
654
|
|
418
655
|
var ret = !!testPropsAll('perspective');
|
419
656
|
|
420
|
-
|
657
|
+
// Webkit's 3D transforms are passed off to the browser's own graphics renderer.
|
658
|
+
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
|
659
|
+
// some conditions. As a result, Webkit typically recognizes the syntax but
|
660
|
+
// will sometimes throw a false positive, thus we must do a more thorough check:
|
661
|
+
if ( ret && 'webkitPerspective' in docElement.style ) {
|
421
662
|
|
422
|
-
|
663
|
+
// Webkit allows this media query to succeed only if the feature is enabled.
|
664
|
+
// `@media (transform-3d),(-webkit-transform-3d){ ... }`
|
665
|
+
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
|
423
666
|
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
|
424
667
|
});
|
425
668
|
}
|
@@ -432,7 +675,13 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
432
675
|
};
|
433
676
|
|
434
677
|
|
678
|
+
/*>>fontface*/
|
679
|
+
// @font-face detection routine by Diego Perini
|
680
|
+
// javascript.nwbox.com/CSSSupport/
|
435
681
|
|
682
|
+
// false positives:
|
683
|
+
// WebOS github.com/Modernizr/Modernizr/issues/342
|
684
|
+
// WP7 github.com/Modernizr/Modernizr/issues/538
|
436
685
|
tests['fontface'] = function() {
|
437
686
|
var bool;
|
438
687
|
|
@@ -446,7 +695,9 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
446
695
|
|
447
696
|
return bool;
|
448
697
|
};
|
698
|
+
/*>>fontface*/
|
449
699
|
|
700
|
+
// CSS generated content detection
|
450
701
|
tests['generatedcontent'] = function() {
|
451
702
|
var bool;
|
452
703
|
|
@@ -456,16 +707,35 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
456
707
|
|
457
708
|
return bool;
|
458
709
|
};
|
710
|
+
|
711
|
+
|
712
|
+
|
713
|
+
// These tests evaluate support of the video/audio elements, as well as
|
714
|
+
// testing what types of content they support.
|
715
|
+
//
|
716
|
+
// We're using the Boolean constructor here, so that we can extend the value
|
717
|
+
// e.g. Modernizr.video // true
|
718
|
+
// Modernizr.video.ogg // 'probably'
|
719
|
+
//
|
720
|
+
// Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
|
721
|
+
// thx to NielsLeenheer and zcorpan
|
722
|
+
|
723
|
+
// Note: in some older browsers, "no" was a return value instead of empty string.
|
724
|
+
// It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
|
725
|
+
// It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
|
726
|
+
|
459
727
|
tests['video'] = function() {
|
460
728
|
var elem = document.createElement('video'),
|
461
729
|
bool = false;
|
462
730
|
|
463
|
-
|
731
|
+
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
|
732
|
+
try {
|
464
733
|
if ( bool = !!elem.canPlayType ) {
|
465
734
|
bool = new Boolean(bool);
|
466
735
|
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
|
467
736
|
|
468
|
-
|
737
|
+
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
|
738
|
+
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
|
469
739
|
|
470
740
|
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
|
471
741
|
}
|
@@ -485,7 +755,10 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
485
755
|
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
|
486
756
|
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
|
487
757
|
|
488
|
-
|
758
|
+
// Mimetypes accepted:
|
759
|
+
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
|
760
|
+
// bit.ly/iphoneoscodecs
|
761
|
+
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
|
489
762
|
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
|
490
763
|
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
|
491
764
|
}
|
@@ -495,6 +768,23 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
495
768
|
};
|
496
769
|
|
497
770
|
|
771
|
+
// In FF4, if disabled, window.localStorage should === null.
|
772
|
+
|
773
|
+
// Normally, we could not test that directly and need to do a
|
774
|
+
// `('localStorage' in window) && ` test first because otherwise Firefox will
|
775
|
+
// throw bugzil.la/365772 if cookies are disabled
|
776
|
+
|
777
|
+
// Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
|
778
|
+
// will throw the exception:
|
779
|
+
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
|
780
|
+
// Peculiarly, getItem and removeItem calls do not throw.
|
781
|
+
|
782
|
+
// Because we are forced to try/catch this, we'll go aggressive.
|
783
|
+
|
784
|
+
// Just FWIW: IE8 Compat mode supports these features completely:
|
785
|
+
// www.quirksmode.org/dom/html5.html
|
786
|
+
// But IE8 doesn't support either with local files
|
787
|
+
|
498
788
|
tests['localstorage'] = function() {
|
499
789
|
try {
|
500
790
|
localStorage.setItem(mod, mod);
|
@@ -526,43 +816,79 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
526
816
|
};
|
527
817
|
|
528
818
|
|
819
|
+
// Thanks to Erik Dahlstrom
|
529
820
|
tests['svg'] = function() {
|
530
821
|
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
|
531
822
|
};
|
532
823
|
|
824
|
+
// specifically for SVG inline in HTML, not within XHTML
|
825
|
+
// test page: paulirish.com/demo/inline-svg
|
533
826
|
tests['inlinesvg'] = function() {
|
534
827
|
var div = document.createElement('div');
|
535
828
|
div.innerHTML = '<svg/>';
|
536
829
|
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
|
537
830
|
};
|
538
831
|
|
832
|
+
// SVG SMIL animation
|
539
833
|
tests['smil'] = function() {
|
540
834
|
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
|
541
835
|
};
|
542
836
|
|
837
|
+
// This test is only for clip paths in SVG proper, not clip paths on HTML content
|
838
|
+
// demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
|
543
839
|
|
840
|
+
// However read the comments to dig into applying SVG clippaths to HTML content here:
|
841
|
+
// github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
|
544
842
|
tests['svgclippaths'] = function() {
|
545
843
|
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
|
546
844
|
};
|
547
845
|
|
846
|
+
/*>>webforms*/
|
847
|
+
// input features and input types go directly onto the ret object, bypassing the tests loop.
|
848
|
+
// Hold this guy to execute in a moment.
|
548
849
|
function webforms() {
|
549
|
-
|
850
|
+
/*>>input*/
|
851
|
+
// Run through HTML5's new input attributes to see if the UA understands any.
|
852
|
+
// We're using f which is the <input> element created early on
|
853
|
+
// Mike Taylr has created a comprehensive resource for testing these attributes
|
854
|
+
// when applied to all input types:
|
855
|
+
// miketaylr.com/code/input-type-attr.html
|
856
|
+
// spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
|
857
|
+
|
858
|
+
// Only input placeholder is tested while textarea's placeholder is not.
|
859
|
+
// Currently Safari 4 and Opera 11 have support only for the input placeholder
|
860
|
+
// Both tests are available in feature-detects/forms-placeholder.js
|
861
|
+
Modernizr['input'] = (function( props ) {
|
550
862
|
for ( var i = 0, len = props.length; i < len; i++ ) {
|
551
863
|
attrs[ props[i] ] = !!(props[i] in inputElem);
|
552
864
|
}
|
553
865
|
if (attrs.list){
|
554
|
-
|
866
|
+
// safari false positive's on datalist: webk.it/74252
|
867
|
+
// see also github.com/Modernizr/Modernizr/issues/146
|
868
|
+
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
|
555
869
|
}
|
556
870
|
return attrs;
|
557
871
|
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
|
558
|
-
|
872
|
+
/*>>input*/
|
873
|
+
|
874
|
+
/*>>inputtypes*/
|
875
|
+
// Run through HTML5's new input types to see if the UA understands any.
|
876
|
+
// This is put behind the tests runloop because it doesn't return a
|
877
|
+
// true/false like all the other tests; instead, it returns an object
|
878
|
+
// containing each input type with its corresponding true/false value
|
879
|
+
|
880
|
+
// Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
|
881
|
+
Modernizr['inputtypes'] = (function(props) {
|
559
882
|
|
560
883
|
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
|
561
884
|
|
562
885
|
inputElem.setAttribute('type', inputElemType = props[i]);
|
563
886
|
bool = inputElem.type !== 'text';
|
564
887
|
|
565
|
-
|
888
|
+
// We first check to see if the type we give it sticks..
|
889
|
+
// If the type does, we feed it a textual value, which shouldn't be valid.
|
890
|
+
// If the value doesn't stick, we know there's input sanitization which infers a custom UI
|
891
|
+
if ( bool ) {
|
566
892
|
|
567
893
|
inputElem.value = smile;
|
568
894
|
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
|
@@ -572,18 +898,29 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
572
898
|
docElement.appendChild(inputElem);
|
573
899
|
defaultView = document.defaultView;
|
574
900
|
|
575
|
-
|
901
|
+
// Safari 2-4 allows the smiley as a value, despite making a slider
|
902
|
+
bool = defaultView.getComputedStyle &&
|
576
903
|
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
|
577
|
-
|
904
|
+
// Mobile android web browser has false positive, so must
|
905
|
+
// check the height to see if the widget is actually there.
|
906
|
+
(inputElem.offsetHeight !== 0);
|
578
907
|
|
579
908
|
docElement.removeChild(inputElem);
|
580
909
|
|
581
910
|
} else if ( /^(search|tel)$/.test(inputElemType) ){
|
582
|
-
|
583
|
-
|
911
|
+
// Spec doesn't define any special parsing or detectable UI
|
912
|
+
// behaviors so we pass these through as true
|
913
|
+
|
914
|
+
// Interestingly, opera fails the earlier test, so it doesn't
|
915
|
+
// even make it here.
|
916
|
+
|
917
|
+
} else if ( /^(url|email)$/.test(inputElemType) ) {
|
918
|
+
// Real url and email support comes with prebaked validation.
|
919
|
+
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
|
584
920
|
|
585
921
|
} else {
|
586
|
-
|
922
|
+
// If the upgraded input compontent rejects the :) text, we got a winner
|
923
|
+
bool = inputElem.value != smile;
|
587
924
|
}
|
588
925
|
}
|
589
926
|
|
@@ -591,19 +928,44 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
591
928
|
}
|
592
929
|
return inputs;
|
593
930
|
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
|
594
|
-
|
931
|
+
/*>>inputtypes*/
|
932
|
+
}
|
933
|
+
/*>>webforms*/
|
934
|
+
|
935
|
+
|
936
|
+
// End of test definitions
|
937
|
+
// -----------------------
|
938
|
+
|
939
|
+
|
940
|
+
|
941
|
+
// Run through all tests and detect their support in the current UA.
|
942
|
+
// todo: hypothetically we could be doing an array of tests and use a basic loop here.
|
595
943
|
for ( var feature in tests ) {
|
596
944
|
if ( hasOwnProp(tests, feature) ) {
|
597
|
-
|
945
|
+
// run the test, throw the return value into the Modernizr,
|
946
|
+
// then based on that boolean, define an appropriate className
|
947
|
+
// and push it into an array of classes we'll join later.
|
948
|
+
featureName = feature.toLowerCase();
|
598
949
|
Modernizr[featureName] = tests[feature]();
|
599
950
|
|
600
951
|
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
|
601
952
|
}
|
602
953
|
}
|
603
954
|
|
955
|
+
/*>>webforms*/
|
956
|
+
// input tests need to run.
|
604
957
|
Modernizr.input || webforms();
|
958
|
+
/*>>webforms*/
|
605
959
|
|
606
960
|
|
961
|
+
/**
|
962
|
+
* addTest allows the user to define their own feature tests
|
963
|
+
* the result will be added onto the Modernizr object,
|
964
|
+
* as well as an appropriate className set on the html element
|
965
|
+
*
|
966
|
+
* @param feature - String naming the feature
|
967
|
+
* @param test - Function returning true if feature is supported, false if not
|
968
|
+
*/
|
607
969
|
Modernizr.addTest = function ( feature, test ) {
|
608
970
|
if ( typeof feature == 'object' ) {
|
609
971
|
for ( var key in feature ) {
|
@@ -616,7 +978,12 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
616
978
|
feature = feature.toLowerCase();
|
617
979
|
|
618
980
|
if ( Modernizr[feature] !== undefined ) {
|
619
|
-
|
981
|
+
// we're going to quit if you're trying to overwrite an existing test
|
982
|
+
// if we were to allow it, we'd do this:
|
983
|
+
// var re = new RegExp("\\b(no-)?" + feature + "\\b");
|
984
|
+
// docElement.className = docElement.className.replace( re, '' );
|
985
|
+
// but, no rly, stuff 'em.
|
986
|
+
return Modernizr;
|
620
987
|
}
|
621
988
|
|
622
989
|
test = typeof test == 'function' ? test() : test;
|
@@ -628,2114 +995,399 @@ window.Modernizr = (function( window, document, undefined ) {
|
|
628
995
|
|
629
996
|
}
|
630
997
|
|
631
|
-
return Modernizr;
|
998
|
+
return Modernizr; // allow chaining.
|
632
999
|
};
|
633
1000
|
|
634
1001
|
|
1002
|
+
// Reset modElem.cssText to nothing to reduce memory footprint.
|
635
1003
|
setCss('');
|
636
1004
|
modElem = inputElem = null;
|
637
1005
|
|
1006
|
+
/*>>shiv*/
|
1007
|
+
/*! HTML5 Shiv v3.6.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */
|
1008
|
+
;(function(window, document) {
|
1009
|
+
/*jshint evil:true */
|
1010
|
+
/** Preset options */
|
1011
|
+
var options = window.html5 || {};
|
638
1012
|
|
639
|
-
|
1013
|
+
/** Used to skip problem elements */
|
1014
|
+
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
|
640
1015
|
|
641
|
-
|
642
|
-
|
643
|
-
Modernizr._cssomPrefixes = cssomPrefixes;
|
1016
|
+
/** Not all elements can be cloned in IE **/
|
1017
|
+
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;
|
644
1018
|
|
645
|
-
|
1019
|
+
/** Detect whether the browser supports default html5 styles */
|
1020
|
+
var supportsHtml5Styles;
|
646
1021
|
|
647
|
-
|
1022
|
+
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
1023
|
+
var expando = '_html5shiv';
|
648
1024
|
|
649
|
-
|
650
|
-
|
651
|
-
};
|
1025
|
+
/** The id for the the documents expando */
|
1026
|
+
var expanID = 0;
|
652
1027
|
|
653
|
-
|
1028
|
+
/** Cached data for each document */
|
1029
|
+
var expandoData = {};
|
654
1030
|
|
1031
|
+
/** Detect whether the browser supports unknown elements */
|
1032
|
+
var supportsUnknownElements;
|
655
1033
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
1034
|
+
(function() {
|
1035
|
+
try {
|
1036
|
+
var a = document.createElement('a');
|
1037
|
+
a.innerHTML = '<xyz></xyz>';
|
1038
|
+
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
|
1039
|
+
supportsHtml5Styles = ('hidden' in a);
|
1040
|
+
|
1041
|
+
supportsUnknownElements = a.childNodes.length == 1 || (function() {
|
1042
|
+
// assign a false positive if unable to shiv
|
1043
|
+
(document.createElement)('a');
|
1044
|
+
var frag = document.createDocumentFragment();
|
1045
|
+
return (
|
1046
|
+
typeof frag.cloneNode == 'undefined' ||
|
1047
|
+
typeof frag.createDocumentFragment == 'undefined' ||
|
1048
|
+
typeof frag.createElement == 'undefined'
|
1049
|
+
);
|
1050
|
+
}());
|
1051
|
+
} catch(e) {
|
1052
|
+
supportsHtml5Styles = true;
|
1053
|
+
supportsUnknownElements = true;
|
1054
|
+
}
|
667
1055
|
|
668
|
-
|
1056
|
+
}());
|
669
1057
|
|
670
|
-
|
1058
|
+
/*--------------------------------------------------------------------------*/
|
671
1059
|
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
/** Not all elements can be cloned in IE (this list can be shortend) **/
|
683
|
-
var saveClones = /^<|^(?:a|b|button|code|div|fieldset|form|h1|h2|h3|h4|h5|h6|i|iframe|img|input|label|li|link|ol|option|p|param|q|script|select|span|strong|style|table|tbody|td|textarea|tfoot|th|thead|tr|ul)$/i;
|
684
|
-
|
685
|
-
/** Detect whether the browser supports default html5 styles */
|
686
|
-
var supportsHtml5Styles;
|
687
|
-
|
688
|
-
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
689
|
-
var expando = '_html5shiv';
|
690
|
-
|
691
|
-
/** The id for the the documents expando */
|
692
|
-
var expanID = 0;
|
693
|
-
|
694
|
-
/** Cached data for each document */
|
695
|
-
var expandoData = {};
|
696
|
-
|
697
|
-
/** Detect whether the browser supports unknown elements */
|
698
|
-
var supportsUnknownElements;
|
699
|
-
|
700
|
-
(function() {
|
701
|
-
try {
|
702
|
-
var a = document.createElement('a');
|
703
|
-
a.innerHTML = '<xyz></xyz>';
|
704
|
-
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
|
705
|
-
supportsHtml5Styles = ('hidden' in a);
|
706
|
-
|
707
|
-
supportsUnknownElements = a.childNodes.length == 1 || (function() {
|
708
|
-
// assign a false positive if unable to shiv
|
709
|
-
(document.createElement)('a');
|
710
|
-
var frag = document.createDocumentFragment();
|
711
|
-
return (
|
712
|
-
typeof frag.cloneNode == 'undefined' ||
|
713
|
-
typeof frag.createDocumentFragment == 'undefined' ||
|
714
|
-
typeof frag.createElement == 'undefined'
|
715
|
-
);
|
716
|
-
}());
|
717
|
-
} catch(e) {
|
718
|
-
supportsHtml5Styles = true;
|
719
|
-
supportsUnknownElements = true;
|
720
|
-
}
|
1060
|
+
/**
|
1061
|
+
* Creates a style sheet with the given CSS text and adds it to the document.
|
1062
|
+
* @private
|
1063
|
+
* @param {Document} ownerDocument The document.
|
1064
|
+
* @param {String} cssText The CSS text.
|
1065
|
+
* @returns {StyleSheet} The style element.
|
1066
|
+
*/
|
1067
|
+
function addStyleSheet(ownerDocument, cssText) {
|
1068
|
+
var p = ownerDocument.createElement('p'),
|
1069
|
+
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
|
721
1070
|
|
722
|
-
|
723
|
-
|
724
|
-
/*--------------------------------------------------------------------------*/
|
725
|
-
|
726
|
-
/**
|
727
|
-
* Creates a style sheet with the given CSS text and adds it to the document.
|
728
|
-
* @private
|
729
|
-
* @param {Document} ownerDocument The document.
|
730
|
-
* @param {String} cssText The CSS text.
|
731
|
-
* @returns {StyleSheet} The style element.
|
732
|
-
*/
|
733
|
-
function addStyleSheet(ownerDocument, cssText) {
|
734
|
-
var p = ownerDocument.createElement('p'),
|
735
|
-
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
|
736
|
-
|
737
|
-
p.innerHTML = 'x<style>' + cssText + '</style>';
|
738
|
-
return parent.insertBefore(p.lastChild, parent.firstChild);
|
739
|
-
}
|
740
|
-
|
741
|
-
/**
|
742
|
-
* Returns the value of `html5.elements` as an array.
|
743
|
-
* @private
|
744
|
-
* @returns {Array} An array of shived element node names.
|
745
|
-
*/
|
746
|
-
function getElements() {
|
747
|
-
var elements = html5.elements;
|
748
|
-
return typeof elements == 'string' ? elements.split(' ') : elements;
|
749
|
-
}
|
750
|
-
|
751
|
-
/**
|
752
|
-
* Returns the data associated to the given document
|
753
|
-
* @private
|
754
|
-
* @param {Document} ownerDocument The document.
|
755
|
-
* @returns {Object} An object of data.
|
756
|
-
*/
|
757
|
-
function getExpandoData(ownerDocument) {
|
758
|
-
var data = expandoData[ownerDocument[expando]];
|
759
|
-
if (!data) {
|
760
|
-
data = {};
|
761
|
-
expanID++;
|
762
|
-
ownerDocument[expando] = expanID;
|
763
|
-
expandoData[expanID] = data;
|
764
|
-
}
|
765
|
-
return data;
|
766
|
-
}
|
767
|
-
|
768
|
-
/**
|
769
|
-
* returns a shived element for the given nodeName and document
|
770
|
-
* @memberOf html5
|
771
|
-
* @param {String} nodeName name of the element
|
772
|
-
* @param {Document} ownerDocument The context document.
|
773
|
-
* @returns {Object} The shived element.
|
774
|
-
*/
|
775
|
-
function createElement(nodeName, ownerDocument, data){
|
776
|
-
if (!ownerDocument) {
|
777
|
-
ownerDocument = document;
|
778
|
-
}
|
779
|
-
if(supportsUnknownElements){
|
780
|
-
return ownerDocument.createElement(nodeName);
|
781
|
-
}
|
782
|
-
if (!data) {
|
783
|
-
data = getExpandoData(ownerDocument);
|
784
|
-
}
|
785
|
-
var node;
|
786
|
-
|
787
|
-
if (data.cache[nodeName]) {
|
788
|
-
node = data.cache[nodeName].cloneNode();
|
789
|
-
} else if (saveClones.test(nodeName)) {
|
790
|
-
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
|
791
|
-
} else {
|
792
|
-
node = data.createElem(nodeName);
|
793
|
-
}
|
794
|
-
|
795
|
-
// Avoid adding some elements to fragments in IE < 9 because
|
796
|
-
// * Attributes like `name` or `type` cannot be set/changed once an element
|
797
|
-
// is inserted into a document/fragment
|
798
|
-
// * Link elements with `src` attributes that are inaccessible, as with
|
799
|
-
// a 403 response, will cause the tab/window to crash
|
800
|
-
// * Script elements appended to fragments will execute when their `src`
|
801
|
-
// or `text` property is set
|
802
|
-
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
|
803
|
-
}
|
804
|
-
|
805
|
-
/**
|
806
|
-
* returns a shived DocumentFragment for the given document
|
807
|
-
* @memberOf html5
|
808
|
-
* @param {Document} ownerDocument The context document.
|
809
|
-
* @returns {Object} The shived DocumentFragment.
|
810
|
-
*/
|
811
|
-
function createDocumentFragment(ownerDocument, data){
|
812
|
-
if (!ownerDocument) {
|
813
|
-
ownerDocument = document;
|
814
|
-
}
|
815
|
-
if(supportsUnknownElements){
|
816
|
-
return ownerDocument.createDocumentFragment();
|
817
|
-
}
|
818
|
-
data = data || getExpandoData(ownerDocument);
|
819
|
-
var clone = data.frag.cloneNode(),
|
820
|
-
i = 0,
|
821
|
-
elems = getElements(),
|
822
|
-
l = elems.length;
|
823
|
-
for(;i<l;i++){
|
824
|
-
clone.createElement(elems[i]);
|
825
|
-
}
|
826
|
-
return clone;
|
827
|
-
}
|
828
|
-
|
829
|
-
/**
|
830
|
-
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
|
831
|
-
* @private
|
832
|
-
* @param {Document|DocumentFragment} ownerDocument The document.
|
833
|
-
* @param {Object} data of the document.
|
834
|
-
*/
|
835
|
-
function shivMethods(ownerDocument, data) {
|
836
|
-
if (!data.cache) {
|
837
|
-
data.cache = {};
|
838
|
-
data.createElem = ownerDocument.createElement;
|
839
|
-
data.createFrag = ownerDocument.createDocumentFragment;
|
840
|
-
data.frag = data.createFrag();
|
841
|
-
}
|
842
|
-
|
843
|
-
|
844
|
-
ownerDocument.createElement = function(nodeName) {
|
845
|
-
//abort shiv
|
846
|
-
if (!html5.shivMethods) {
|
847
|
-
return data.createElem(nodeName);
|
1071
|
+
p.innerHTML = 'x<style>' + cssText + '</style>';
|
1072
|
+
return parent.insertBefore(p.lastChild, parent.firstChild);
|
848
1073
|
}
|
849
|
-
return createElement(nodeName, ownerDocument, data);
|
850
|
-
};
|
851
1074
|
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
}) +
|
861
|
-
');return n}'
|
862
|
-
)(html5, data.frag);
|
863
|
-
}
|
864
|
-
|
865
|
-
/*--------------------------------------------------------------------------*/
|
866
|
-
|
867
|
-
/**
|
868
|
-
* Shivs the given document.
|
869
|
-
* @memberOf html5
|
870
|
-
* @param {Document} ownerDocument The document to shiv.
|
871
|
-
* @returns {Document} The shived document.
|
872
|
-
*/
|
873
|
-
function shivDocument(ownerDocument) {
|
874
|
-
if (!ownerDocument) {
|
875
|
-
ownerDocument = document;
|
876
|
-
}
|
877
|
-
var data = getExpandoData(ownerDocument);
|
878
|
-
|
879
|
-
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
|
880
|
-
data.hasCSS = !!addStyleSheet(ownerDocument,
|
881
|
-
// corrects block display not defined in IE6/7/8/9
|
882
|
-
'article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}' +
|
883
|
-
// adds styling not present in IE6/7/8/9
|
884
|
-
'mark{background:#FF0;color:#000}'
|
885
|
-
);
|
886
|
-
}
|
887
|
-
if (!supportsUnknownElements) {
|
888
|
-
shivMethods(ownerDocument, data);
|
889
|
-
}
|
890
|
-
return ownerDocument;
|
891
|
-
}
|
892
|
-
|
893
|
-
/*--------------------------------------------------------------------------*/
|
894
|
-
|
895
|
-
/**
|
896
|
-
* The `html5` object is exposed so that more elements can be shived and
|
897
|
-
* existing shiving can be detected on iframes.
|
898
|
-
* @type Object
|
899
|
-
* @example
|
900
|
-
*
|
901
|
-
* // options can be changed before the script is included
|
902
|
-
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
|
903
|
-
*/
|
904
|
-
var html5 = {
|
905
|
-
|
906
|
-
/**
|
907
|
-
* An array or space separated string of node names of the elements to shiv.
|
908
|
-
* @memberOf html5
|
909
|
-
* @type Array|String
|
910
|
-
*/
|
911
|
-
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video',
|
912
|
-
|
913
|
-
/**
|
914
|
-
* A flag to indicate that the HTML5 style sheet should be inserted.
|
915
|
-
* @memberOf html5
|
916
|
-
* @type Boolean
|
917
|
-
*/
|
918
|
-
'shivCSS': (options.shivCSS !== false),
|
919
|
-
|
920
|
-
/**
|
921
|
-
* Is equal to true if a browser supports creating unknown/HTML5 elements
|
922
|
-
* @memberOf html5
|
923
|
-
* @type boolean
|
924
|
-
*/
|
925
|
-
'supportsUnknownElements': supportsUnknownElements,
|
926
|
-
|
927
|
-
/**
|
928
|
-
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
|
929
|
-
* methods should be overwritten.
|
930
|
-
* @memberOf html5
|
931
|
-
* @type Boolean
|
932
|
-
*/
|
933
|
-
'shivMethods': (options.shivMethods !== false),
|
934
|
-
|
935
|
-
/**
|
936
|
-
* A string to describe the type of `html5` object ("default" or "default print").
|
937
|
-
* @memberOf html5
|
938
|
-
* @type String
|
939
|
-
*/
|
940
|
-
'type': 'default',
|
941
|
-
|
942
|
-
// shivs the document according to the specified `html5` object options
|
943
|
-
'shivDocument': shivDocument,
|
944
|
-
|
945
|
-
//creates a shived element
|
946
|
-
createElement: createElement,
|
947
|
-
|
948
|
-
//creates a shived documentFragment
|
949
|
-
createDocumentFragment: createDocumentFragment
|
950
|
-
};
|
951
|
-
|
952
|
-
/*--------------------------------------------------------------------------*/
|
953
|
-
|
954
|
-
// expose html5
|
955
|
-
window.html5 = html5;
|
956
|
-
|
957
|
-
// shiv the document
|
958
|
-
shivDocument(document);
|
959
|
-
|
960
|
-
/*------------------------------- Print Shiv -------------------------------*/
|
961
|
-
|
962
|
-
/** Used to filter media types */
|
963
|
-
var reMedia = /^$|\b(?:all|print)\b/;
|
964
|
-
|
965
|
-
/** Used to namespace printable elements */
|
966
|
-
var shivNamespace = 'html5shiv';
|
967
|
-
|
968
|
-
/** Detect whether the browser supports shivable style sheets */
|
969
|
-
var supportsShivableSheets = !supportsUnknownElements && (function() {
|
970
|
-
// assign a false negative if unable to shiv
|
971
|
-
var docEl = document.documentElement;
|
972
|
-
return !(
|
973
|
-
typeof document.namespaces == 'undefined' ||
|
974
|
-
typeof document.parentWindow == 'undefined' ||
|
975
|
-
typeof docEl.applyElement == 'undefined' ||
|
976
|
-
typeof docEl.removeNode == 'undefined' ||
|
977
|
-
typeof window.attachEvent == 'undefined'
|
978
|
-
);
|
979
|
-
}());
|
980
|
-
|
981
|
-
/*--------------------------------------------------------------------------*/
|
982
|
-
|
983
|
-
/**
|
984
|
-
* Wraps all HTML5 elements in the given document with printable elements.
|
985
|
-
* (eg. the "header" element is wrapped with the "html5shiv:header" element)
|
986
|
-
* @private
|
987
|
-
* @param {Document} ownerDocument The document.
|
988
|
-
* @returns {Array} An array wrappers added.
|
989
|
-
*/
|
990
|
-
function addWrappers(ownerDocument) {
|
991
|
-
var node,
|
992
|
-
nodes = ownerDocument.getElementsByTagName('*'),
|
993
|
-
index = nodes.length,
|
994
|
-
reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'),
|
995
|
-
result = [];
|
996
|
-
|
997
|
-
while (index--) {
|
998
|
-
node = nodes[index];
|
999
|
-
if (reElements.test(node.nodeName)) {
|
1000
|
-
result.push(node.applyElement(createWrapper(node)));
|
1075
|
+
/**
|
1076
|
+
* Returns the value of `html5.elements` as an array.
|
1077
|
+
* @private
|
1078
|
+
* @returns {Array} An array of shived element node names.
|
1079
|
+
*/
|
1080
|
+
function getElements() {
|
1081
|
+
var elements = html5.elements;
|
1082
|
+
return typeof elements == 'string' ? elements.split(' ') : elements;
|
1001
1083
|
}
|
1002
|
-
}
|
1003
|
-
return result;
|
1004
|
-
}
|
1005
|
-
|
1006
|
-
/**
|
1007
|
-
* Creates a printable wrapper for the given element.
|
1008
|
-
* @private
|
1009
|
-
* @param {Element} element The element.
|
1010
|
-
* @returns {Element} The wrapper.
|
1011
|
-
*/
|
1012
|
-
function createWrapper(element) {
|
1013
|
-
var node,
|
1014
|
-
nodes = element.attributes,
|
1015
|
-
index = nodes.length,
|
1016
|
-
wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName);
|
1017
|
-
|
1018
|
-
// copy element attributes to the wrapper
|
1019
|
-
while (index--) {
|
1020
|
-
node = nodes[index];
|
1021
|
-
node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue);
|
1022
|
-
}
|
1023
|
-
// copy element styles to the wrapper
|
1024
|
-
wrapper.style.cssText = element.style.cssText;
|
1025
|
-
return wrapper;
|
1026
|
-
}
|
1027
|
-
|
1028
|
-
/**
|
1029
|
-
* Shivs the given CSS text.
|
1030
|
-
* (eg. header{} becomes html5shiv\:header{})
|
1031
|
-
* @private
|
1032
|
-
* @param {String} cssText The CSS text to shiv.
|
1033
|
-
* @returns {String} The shived CSS text.
|
1034
|
-
*/
|
1035
|
-
function shivCssText(cssText) {
|
1036
|
-
var pair,
|
1037
|
-
parts = cssText.split('{'),
|
1038
|
-
index = parts.length,
|
1039
|
-
reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
|
1040
|
-
replacement = '$1' + shivNamespace + '\\:$2';
|
1041
|
-
|
1042
|
-
while (index--) {
|
1043
|
-
pair = parts[index] = parts[index].split('}');
|
1044
|
-
pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
|
1045
|
-
parts[index] = pair.join('}');
|
1046
|
-
}
|
1047
|
-
return parts.join('{');
|
1048
|
-
}
|
1049
|
-
|
1050
|
-
/**
|
1051
|
-
* Removes the given wrappers, leaving the original elements.
|
1052
|
-
* @private
|
1053
|
-
* @params {Array} wrappers An array of printable wrappers.
|
1054
|
-
*/
|
1055
|
-
function removeWrappers(wrappers) {
|
1056
|
-
var index = wrappers.length;
|
1057
|
-
while (index--) {
|
1058
|
-
wrappers[index].removeNode();
|
1059
|
-
}
|
1060
|
-
}
|
1061
|
-
|
1062
|
-
/*--------------------------------------------------------------------------*/
|
1063
|
-
|
1064
|
-
/**
|
1065
|
-
* Shivs the given document for print.
|
1066
|
-
* @memberOf html5
|
1067
|
-
* @param {Document} ownerDocument The document to shiv.
|
1068
|
-
* @returns {Document} The shived document.
|
1069
|
-
*/
|
1070
|
-
function shivPrint(ownerDocument) {
|
1071
|
-
var shivedSheet,
|
1072
|
-
wrappers,
|
1073
|
-
data = getExpandoData(ownerDocument),
|
1074
|
-
namespaces = ownerDocument.namespaces,
|
1075
|
-
ownerWindow = ownerDocument.parentWindow;
|
1076
|
-
|
1077
|
-
if (!supportsShivableSheets || ownerDocument.printShived) {
|
1078
|
-
return ownerDocument;
|
1079
|
-
}
|
1080
|
-
if (typeof namespaces[shivNamespace] == 'undefined') {
|
1081
|
-
namespaces.add(shivNamespace);
|
1082
|
-
}
|
1083
1084
|
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1085
|
+
/**
|
1086
|
+
* Returns the data associated to the given document
|
1087
|
+
* @private
|
1088
|
+
* @param {Document} ownerDocument The document.
|
1089
|
+
* @returns {Object} An object of data.
|
1090
|
+
*/
|
1091
|
+
function getExpandoData(ownerDocument) {
|
1092
|
+
var data = expandoData[ownerDocument[expando]];
|
1093
|
+
if (!data) {
|
1094
|
+
data = {};
|
1095
|
+
expanID++;
|
1096
|
+
ownerDocument[expando] = expanID;
|
1097
|
+
expandoData[expanID] = data;
|
1098
|
+
}
|
1099
|
+
return data;
|
1088
1100
|
}
|
1089
|
-
shivedSheet= null;
|
1090
|
-
}
|
1091
|
-
|
1092
|
-
ownerWindow.attachEvent('onbeforeprint', function() {
|
1093
1101
|
|
1094
|
-
|
1102
|
+
/**
|
1103
|
+
* returns a shived element for the given nodeName and document
|
1104
|
+
* @memberOf html5
|
1105
|
+
* @param {String} nodeName name of the element
|
1106
|
+
* @param {Document} ownerDocument The context document.
|
1107
|
+
* @returns {Object} The shived element.
|
1108
|
+
*/
|
1109
|
+
function createElement(nodeName, ownerDocument, data){
|
1110
|
+
if (!ownerDocument) {
|
1111
|
+
ownerDocument = document;
|
1112
|
+
}
|
1113
|
+
if(supportsUnknownElements){
|
1114
|
+
return ownerDocument.createElement(nodeName);
|
1115
|
+
}
|
1116
|
+
if (!data) {
|
1117
|
+
data = getExpandoData(ownerDocument);
|
1118
|
+
}
|
1119
|
+
var node;
|
1095
1120
|
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1121
|
+
if (data.cache[nodeName]) {
|
1122
|
+
node = data.cache[nodeName].cloneNode();
|
1123
|
+
} else if (saveClones.test(nodeName)) {
|
1124
|
+
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
|
1125
|
+
} else {
|
1126
|
+
node = data.createElem(nodeName);
|
1127
|
+
}
|
1103
1128
|
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1129
|
+
// Avoid adding some elements to fragments in IE < 9 because
|
1130
|
+
// * Attributes like `name` or `type` cannot be set/changed once an element
|
1131
|
+
// is inserted into a document/fragment
|
1132
|
+
// * Link elements with `src` attributes that are inaccessible, as with
|
1133
|
+
// a 403 response, will cause the tab/window to crash
|
1134
|
+
// * Script elements appended to fragments will execute when their `src`
|
1135
|
+
// or `text` property is set
|
1136
|
+
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
|
1107
1137
|
}
|
1108
|
-
// concat all style sheet CSS text
|
1109
|
-
while ((sheet = sheets.pop())) {
|
1110
|
-
// IE does not enforce a same origin policy for external style sheets...
|
1111
|
-
// but has trouble with some dynamically created stylesheets
|
1112
|
-
if (!sheet.disabled && reMedia.test(sheet.media)) {
|
1113
|
-
|
1114
|
-
try {
|
1115
|
-
imports = sheet.imports;
|
1116
|
-
length = imports.length;
|
1117
|
-
} catch(er){
|
1118
|
-
length = 0;
|
1119
|
-
}
|
1120
|
-
|
1121
|
-
for (index = 0; index < length; index++) {
|
1122
|
-
sheets.push(imports[index]);
|
1123
|
-
}
|
1124
1138
|
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1139
|
+
/**
|
1140
|
+
* returns a shived DocumentFragment for the given document
|
1141
|
+
* @memberOf html5
|
1142
|
+
* @param {Document} ownerDocument The context document.
|
1143
|
+
* @returns {Object} The shived DocumentFragment.
|
1144
|
+
*/
|
1145
|
+
function createDocumentFragment(ownerDocument, data){
|
1146
|
+
if (!ownerDocument) {
|
1147
|
+
ownerDocument = document;
|
1128
1148
|
}
|
1149
|
+
if(supportsUnknownElements){
|
1150
|
+
return ownerDocument.createDocumentFragment();
|
1151
|
+
}
|
1152
|
+
data = data || getExpandoData(ownerDocument);
|
1153
|
+
var clone = data.frag.cloneNode(),
|
1154
|
+
i = 0,
|
1155
|
+
elems = getElements(),
|
1156
|
+
l = elems.length;
|
1157
|
+
for(;i<l;i++){
|
1158
|
+
clone.createElement(elems[i]);
|
1159
|
+
}
|
1160
|
+
return clone;
|
1129
1161
|
}
|
1130
1162
|
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
});
|
1144
|
-
|
1145
|
-
ownerDocument.printShived = true;
|
1146
|
-
return ownerDocument;
|
1147
|
-
}
|
1148
|
-
|
1149
|
-
/*--------------------------------------------------------------------------*/
|
1150
|
-
|
1151
|
-
// expose API
|
1152
|
-
html5.type += ' print';
|
1153
|
-
html5.shivPrint = shivPrint;
|
1154
|
-
|
1155
|
-
// shiv for print
|
1156
|
-
shivPrint(document);
|
1157
|
-
|
1158
|
-
}(this, document));/*yepnope1.5.4|WTFPL*/
|
1159
|
-
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);
|
1160
|
-
Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));};
|
1161
|
-
|
1162
|
-
// a[download] attribute
|
1163
|
-
// When used on an <a>, this attribute signifies that the resource it
|
1164
|
-
// points to should be downloaded by the browser rather than navigating to it.
|
1165
|
-
// http://developers.whatwg.org/links.html#downloading-resources
|
1166
|
-
// By Addy Osmani
|
1167
|
-
|
1168
|
-
Modernizr.addTest('adownload', 'download' in document.createElement('a'));
|
1169
|
-
// Mozilla Audio Data API
|
1170
|
-
// https://wiki.mozilla.org/Audio_Data_API
|
1171
|
-
// by Addy Osmani
|
1172
|
-
Modernizr.addTest('audiodata', !!(window.Audio));
|
1173
|
-
// Web Audio API
|
1174
|
-
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
|
1175
|
-
// By Addy Osmani
|
1176
|
-
Modernizr.addTest('webaudio', !!(window.webkitAudioContext || window.AudioContext));
|
1177
|
-
// Blob constructor
|
1178
|
-
// http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob
|
1179
|
-
|
1180
|
-
Modernizr.addTest('blobconstructor', function () {
|
1181
|
-
try {
|
1182
|
-
return !!new Blob();
|
1183
|
-
} catch (e) {
|
1184
|
-
return false;
|
1185
|
-
}
|
1186
|
-
});
|
1187
|
-
|
1188
|
-
// Low Battery Level
|
1189
|
-
// Enable a developer to remove CPU intensive CSS/JS when battery is low
|
1190
|
-
// developer.mozilla.org/en/DOM/window.navigator.mozBattery
|
1191
|
-
// By: Paul Sayre
|
1192
|
-
|
1193
|
-
Modernizr.addTest('lowbattery', function () {
|
1194
|
-
var minLevel = 0.20,
|
1195
|
-
battery = Modernizr.prefixed('battery', navigator);
|
1196
|
-
return !!(battery && !battery.charging && battery.level <= minLevel);
|
1197
|
-
});
|
1198
|
-
|
1199
|
-
// Battery API
|
1200
|
-
// https://developer.mozilla.org/en/DOM/window.navigator.mozBattery
|
1201
|
-
// By: Paul Sayre
|
1202
|
-
|
1203
|
-
Modernizr.addTest('battery',
|
1204
|
-
!!Modernizr.prefixed('battery', navigator)
|
1205
|
-
);// canvas.toDataURL type support
|
1206
|
-
// http://www.w3.org/TR/html5/the-canvas-element.html#dom-canvas-todataurl
|
1207
|
-
|
1208
|
-
// This test is asynchronous. Watch out.
|
1209
|
-
|
1210
|
-
(function () {
|
1211
|
-
|
1212
|
-
if (!Modernizr.canvas) {
|
1213
|
-
return false;
|
1214
|
-
}
|
1215
|
-
|
1216
|
-
var image = new Image(),
|
1217
|
-
canvas = document.createElement('canvas'),
|
1218
|
-
ctx = canvas.getContext('2d');
|
1219
|
-
|
1220
|
-
image.onload = function() {
|
1221
|
-
ctx.drawImage(image, 0, 0);
|
1222
|
-
|
1223
|
-
Modernizr.addTest('todataurljpeg', function() {
|
1224
|
-
return canvas.toDataURL('image/jpeg').indexOf('data:image/jpeg') === 0;
|
1225
|
-
});
|
1226
|
-
Modernizr.addTest('todataurlwebp', function() {
|
1227
|
-
return canvas.toDataURL('image/webp').indexOf('data:image/webp') === 0;
|
1228
|
-
});
|
1229
|
-
};
|
1230
|
-
|
1231
|
-
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==';
|
1232
|
-
}());
|
1233
|
-
// contentEditable
|
1234
|
-
// http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#contenteditable
|
1235
|
-
|
1236
|
-
// this is known to false positive in some mobile browsers
|
1237
|
-
// here is a whitelist of verified working browsers:
|
1238
|
-
// https://github.com/NielsLeenheer/html5test/blob/549f6eac866aa861d9649a0707ff2c0157895706/scripts/engine.js#L2083
|
1239
|
-
|
1240
|
-
Modernizr.addTest('contenteditable',
|
1241
|
-
'contentEditable' in document.documentElement);
|
1242
|
-
// http://www.w3.org/TR/html5/interactive-elements.html#context-menus
|
1243
|
-
// Demo at http://thewebrocks.com/demos/context-menu/
|
1244
|
-
Modernizr.addTest(
|
1245
|
-
'contextmenu',
|
1246
|
-
('contextMenu' in document.documentElement && 'HTMLMenuItemElement' in window)
|
1247
|
-
);
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
// Test for (experimental) Content Security Policy 1.1 support.
|
1254
|
-
//
|
1255
|
-
// This feature is still quite experimental, but is available now in Chrome 22.
|
1256
|
-
// If the `SecurityPolicy` property is available, you can be sure the browser
|
1257
|
-
// supports CSP. If it's not available, the browser still might support an
|
1258
|
-
// earlier version of the CSP spec.
|
1259
|
-
//
|
1260
|
-
// Editor's Draft: https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html
|
1261
|
-
|
1262
|
-
Modernizr.addTest('contentsecuritypolicy', 'SecurityPolicy' in document);
|
1263
|
-
|
1264
|
-
// by tauren
|
1265
|
-
// https://github.com/Modernizr/Modernizr/issues/191
|
1266
|
-
|
1267
|
-
Modernizr.addTest('cookies', function () {
|
1268
|
-
// Quick test if browser has cookieEnabled host property
|
1269
|
-
if (navigator.cookieEnabled) return true;
|
1270
|
-
// Create cookie
|
1271
|
-
document.cookie = "cookietest=1";
|
1272
|
-
var ret = document.cookie.indexOf("cookietest=") != -1;
|
1273
|
-
// Delete cookie
|
1274
|
-
document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
|
1275
|
-
return ret;
|
1276
|
-
});
|
1277
|
-
|
1278
|
-
// cors
|
1279
|
-
// By Theodoor van Donge
|
1280
|
-
Modernizr.addTest('cors', !!(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()));/*
|
1281
|
-
https://developer.mozilla.org/en/CSS/background-position
|
1282
|
-
http://www.w3.org/TR/css3-background/#background-position
|
1283
|
-
|
1284
|
-
Example: http://jsfiddle.net/Blink/bBXvt/
|
1285
|
-
*/
|
1286
|
-
|
1287
|
-
(function() {
|
1288
|
-
|
1289
|
-
var elem = document.createElement('a'),
|
1290
|
-
eStyle = elem.style,
|
1291
|
-
val = "right 10px bottom 10px";
|
1292
|
-
|
1293
|
-
Modernizr.addTest('bgpositionshorthand', function(){
|
1294
|
-
eStyle.cssText = "background-position: " + val + ";";
|
1295
|
-
return (eStyle.backgroundPosition === val);
|
1296
|
-
});
|
1297
|
-
|
1298
|
-
}());
|
1299
|
-
/*
|
1300
|
-
Allan Lei https://github.com/allanlei
|
1301
|
-
|
1302
|
-
Check adapted from https://github.com/brandonaaron/jquery-cssHooks/blob/master/bgpos.js
|
1303
|
-
|
1304
|
-
Test: http://jsfiddle.net/allanlei/R8AYS/
|
1305
|
-
*/
|
1306
|
-
Modernizr.addTest('bgpositionxy', function() {
|
1307
|
-
return Modernizr.testStyles('#modernizr {background-position: 3px 5px;}', function(elem) {
|
1308
|
-
var cssStyleDeclaration = window.getComputedStyle ? getComputedStyle(elem, null) : elem.currentStyle;
|
1309
|
-
var xSupport = (cssStyleDeclaration.backgroundPositionX == '3px') || (cssStyleDeclaration['background-position-x'] == '3px');
|
1310
|
-
var ySupport = (cssStyleDeclaration.backgroundPositionY == '5px') || (cssStyleDeclaration['background-position-y'] == '5px');
|
1311
|
-
return xSupport && ySupport;
|
1312
|
-
});
|
1313
|
-
});
|
1314
|
-
// developer.mozilla.org/en/CSS/background-size
|
1315
|
-
|
1316
|
-
Modernizr.testStyles( '#modernizr{background-size:cover}', function( elem ) {
|
1317
|
-
var style = window.getComputedStyle ?
|
1318
|
-
window.getComputedStyle( elem, null )
|
1319
|
-
: elem.currentStyle;
|
1320
|
-
|
1321
|
-
Modernizr.addTest( 'bgsizecover', style.backgroundSize == 'cover' );
|
1322
|
-
});// developer.mozilla.org/en/CSS/background-repeat
|
1323
|
-
|
1324
|
-
// test page: jsbin.com/uzesun/
|
1325
|
-
// http://jsfiddle.net/ryanseddon/yMLTQ/6/
|
1326
|
-
|
1327
|
-
(function(){
|
1328
|
-
|
1329
|
-
|
1330
|
-
function getBgRepeatValue(elem){
|
1331
|
-
return (window.getComputedStyle ?
|
1332
|
-
getComputedStyle(elem, null).getPropertyValue('background') :
|
1333
|
-
elem.currentStyle['background']);
|
1334
|
-
}
|
1335
|
-
|
1336
|
-
|
1337
|
-
Modernizr.testStyles(' #modernizr { background-repeat: round; } ', function(elem, rule){
|
1338
|
-
|
1339
|
-
Modernizr.addTest('bgrepeatround', getBgRepeatValue(elem) == 'round');
|
1340
|
-
|
1341
|
-
});
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
Modernizr.testStyles(' #modernizr { background-repeat: space; } ', function(elem, rule){
|
1346
|
-
|
1347
|
-
Modernizr.addTest('bgrepeatspace', getBgRepeatValue(elem) == 'space');
|
1348
|
-
|
1349
|
-
});
|
1350
|
-
|
1351
|
-
|
1352
|
-
})();
|
1353
|
-
|
1354
|
-
// developer.mozilla.org/en/CSS/box-sizing
|
1355
|
-
// github.com/Modernizr/Modernizr/issues/248
|
1356
|
-
|
1357
|
-
Modernizr.addTest("boxsizing",function(){
|
1358
|
-
return Modernizr.testAllProps("boxSizing") && (document.documentMode === undefined || document.documentMode > 7);
|
1359
|
-
});
|
1360
|
-
|
1361
|
-
|
1362
|
-
// Method of allowing calculated values for length units, i.e. width: calc(100%-3em) http://caniuse.com/#search=calc
|
1363
|
-
// By @calvein
|
1364
|
-
|
1365
|
-
Modernizr.addTest('csscalc', function() {
|
1366
|
-
var prop = 'width:';
|
1367
|
-
var value = 'calc(10px);';
|
1368
|
-
var el = document.createElement('div');
|
1369
|
-
|
1370
|
-
el.style.cssText = prop + Modernizr._prefixes.join(value + prop);
|
1371
|
-
|
1372
|
-
return !!el.style.length;
|
1373
|
-
});
|
1374
|
-
// cubic-bezier values can't be > 1 for Webkit until bug #45761 (https://bugs.webkit.org/show_bug.cgi?id=45761) is fixed
|
1375
|
-
// By @calvein
|
1376
|
-
|
1377
|
-
Modernizr.addTest('cubicbezierrange', function() {
|
1378
|
-
var el = document.createElement('div');
|
1379
|
-
el.style.cssText = Modernizr._prefixes.join('transition-timing-function' + ':cubic-bezier(1,0,0,1.1); ');
|
1380
|
-
return !!el.style.length;
|
1381
|
-
});
|
1382
|
-
|
1383
|
-
// by alanhogan
|
1384
|
-
|
1385
|
-
// https://github.com/Modernizr/Modernizr/issues/198
|
1386
|
-
// http://css-tricks.com/596-run-in/
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
Modernizr.testStyles(' #modernizr { display: run-in; } ', function(elem, rule){
|
1391
|
-
|
1392
|
-
var ret = (window.getComputedStyle ?
|
1393
|
-
getComputedStyle(elem, null).getPropertyValue('display') :
|
1394
|
-
elem.currentStyle['display']);
|
1395
|
-
|
1396
|
-
Modernizr.addTest('display-runin', ret == 'run-in');
|
1397
|
-
|
1398
|
-
});
|
1399
|
-
|
1400
|
-
// https://github.com/Modernizr/Modernizr/issues/615
|
1401
|
-
// documentMode is needed for false positives in oldIE, please see issue above
|
1402
|
-
Modernizr.addTest('cssfilters', function() {
|
1403
|
-
var el = document.createElement('div');
|
1404
|
-
el.style.cssText = Modernizr._prefixes.join('filter' + ':blur(2px); ');
|
1405
|
-
return !!el.style.length && ((document.documentMode === undefined || document.documentMode > 9));
|
1406
|
-
});// display: table and table-cell test. (both are tested under one name "table-cell" )
|
1407
|
-
// By @scottjehl
|
1408
|
-
|
1409
|
-
// all additional table display values are here: http://pastebin.com/Gk9PeVaQ though Scott has seen some IE false positives with that sort of weak detection.
|
1410
|
-
// more testing neccessary perhaps.
|
1411
|
-
|
1412
|
-
Modernizr.addTest( "display-table",function(){
|
1413
|
-
|
1414
|
-
var doc = window.document,
|
1415
|
-
docElem = doc.documentElement,
|
1416
|
-
parent = doc.createElement( "div" ),
|
1417
|
-
child = doc.createElement( "div" ),
|
1418
|
-
childb = doc.createElement( "div" ),
|
1419
|
-
ret;
|
1420
|
-
|
1421
|
-
parent.style.cssText = "display: table";
|
1422
|
-
child.style.cssText = childb.style.cssText = "display: table-cell; padding: 10px";
|
1423
|
-
|
1424
|
-
parent.appendChild( child );
|
1425
|
-
parent.appendChild( childb );
|
1426
|
-
docElem.insertBefore( parent, docElem.firstChild );
|
1427
|
-
|
1428
|
-
ret = child.offsetLeft < childb.offsetLeft;
|
1429
|
-
docElem.removeChild(parent);
|
1430
|
-
return ret;
|
1431
|
-
});
|
1432
|
-
|
1433
|
-
// last-child pseudo selector
|
1434
|
-
// https://github.com/Modernizr/Modernizr/pull/304
|
1435
|
-
|
1436
|
-
|
1437
|
-
Modernizr.addTest('lastchild', function(){
|
1438
|
-
|
1439
|
-
return Modernizr.testStyles("#modernizr div {width:100px} #modernizr :last-child{width:200px;display:block}", function (elem) {
|
1440
|
-
return elem.lastChild.offsetWidth > elem.firstChild.offsetWidth;
|
1441
|
-
}, 2);
|
1442
|
-
|
1443
|
-
});
|
1444
|
-
/* see http://davidnewton.ca/the-current-state-of-hyphenation-on-the-web
|
1445
|
-
http://davidnewton.ca/demos/hyphenation/test.html
|
1446
|
-
|
1447
|
-
|
1448
|
-
There are three tests:
|
1449
|
-
1. csshyphens - tests hyphens:auto actually adds hyphens to text
|
1450
|
-
2. softhyphens - tests that ­ does its job
|
1451
|
-
3. softhyphensfind - tests that in-browser Find functionality still works correctly with ­
|
1452
|
-
|
1453
|
-
These tests currently require document.body to be present
|
1454
|
-
|
1455
|
-
Hyphenation is language specific, sometimes.
|
1456
|
-
See for more details: http://code.google.com/p/hyphenator/source/diff?spec=svn975&r=975&format=side&path=/trunk/Hyphenator.js#sc_svn975_313
|
1457
|
-
|
1458
|
-
If loading Hyphenator.js via Modernizr.load, be cautious of issue 158: http://code.google.com/p/hyphenator/issues/detail?id=158
|
1459
|
-
|
1460
|
-
More details at https://github.com/Modernizr/Modernizr/issues/312
|
1461
|
-
|
1462
|
-
*/
|
1463
|
-
|
1464
|
-
(function() {
|
1465
|
-
|
1466
|
-
if (!document.body){
|
1467
|
-
window.console && console.warn('document.body doesn\'t exist. Modernizr hyphens test needs it.');
|
1468
|
-
return;
|
1469
|
-
}
|
1470
|
-
|
1471
|
-
// functional test of adding hyphens:auto
|
1472
|
-
function test_hyphens_css() {
|
1473
|
-
try {
|
1474
|
-
/* create a div container and a span within that
|
1475
|
-
* these have to be appended to document.body, otherwise some browsers can give false negative */
|
1476
|
-
var div = document.createElement('div'),
|
1477
|
-
span = document.createElement('span'),
|
1478
|
-
divStyle = div.style,
|
1479
|
-
spanHeight = 0,
|
1480
|
-
spanWidth = 0,
|
1481
|
-
result = false,
|
1482
|
-
firstChild = document.body.firstElementChild || document.body.firstChild;
|
1483
|
-
|
1484
|
-
div.appendChild(span);
|
1485
|
-
span.innerHTML = 'Bacon ipsum dolor sit amet jerky velit in culpa hamburger et. Laborum dolor proident, enim dolore duis commodo et strip steak. Salami anim et, veniam consectetur dolore qui tenderloin jowl velit sirloin. Et ad culpa, fatback cillum jowl ball tip ham hock nulla short ribs pariatur aute. Pig pancetta ham bresaola, ut boudin nostrud commodo flank esse cow tongue culpa. Pork belly bresaola enim pig, ea consectetur nisi. Fugiat officia turkey, ea cow jowl pariatur ullamco proident do laborum velit sausage. Magna biltong sint tri-tip commodo sed bacon, esse proident aliquip. Ullamco ham sint fugiat, velit in enim sed mollit nulla cow ut adipisicing nostrud consectetur. Proident dolore beef ribs, laborum nostrud meatball ea laboris rump cupidatat labore culpa. Shankle minim beef, velit sint cupidatat fugiat tenderloin pig et ball tip. Ut cow fatback salami, bacon ball tip et in shank strip steak bresaola. In ut pork belly sed mollit tri-tip magna culpa veniam, short ribs qui in andouille ham consequat. Dolore bacon t-bone, velit short ribs enim strip steak nulla. Voluptate labore ut, biltong swine irure jerky. Cupidatat excepteur aliquip salami dolore. Ball tip strip steak in pork dolor. Ad in esse biltong. Dolore tenderloin exercitation ad pork loin t-bone, dolore in chicken ball tip qui pig. Ut culpa tongue, sint ribeye dolore ex shank voluptate hamburger. Jowl et tempor, boudin pork chop labore ham hock drumstick consectetur tri-tip elit swine meatball chicken ground round. Proident shankle mollit dolore. Shoulder ut duis t-bone quis reprehenderit. Meatloaf dolore minim strip steak, laboris ea aute bacon beef ribs elit shank in veniam drumstick qui. Ex laboris meatball cow tongue pork belly. Ea ball tip reprehenderit pig, sed fatback boudin dolore flank aliquip laboris eu quis. Beef ribs duis beef, cow corned beef adipisicing commodo nisi deserunt exercitation. Cillum dolor t-bone spare ribs, ham hock est sirloin. Brisket irure meatloaf in, boudin pork belly sirloin ball tip. Sirloin sint irure nisi nostrud aliqua. Nostrud nulla aute, enim officia culpa ham hock. Aliqua reprehenderit dolore sunt nostrud sausage, ea boudin pork loin ut t-bone ham tempor. Tri-tip et pancetta drumstick laborum. Ham hock magna do nostrud in proident. Ex ground round fatback, venison non ribeye in.';
|
1486
|
-
|
1487
|
-
document.body.insertBefore(div, firstChild);
|
1488
|
-
|
1489
|
-
/* get size of unhyphenated text */
|
1490
|
-
divStyle.cssText = 'position:absolute;top:0;left:0;width:5em;text-align:justify;text-justification:newspaper;';
|
1491
|
-
spanHeight = span.offsetHeight;
|
1492
|
-
spanWidth = span.offsetWidth;
|
1493
|
-
|
1494
|
-
/* compare size with hyphenated text */
|
1495
|
-
divStyle.cssText = 'position:absolute;top:0;left:0;width:5em;text-align:justify;'+
|
1496
|
-
'text-justification:newspaper;'+
|
1497
|
-
Modernizr._prefixes.join('hyphens:auto; ');
|
1498
|
-
|
1499
|
-
result = (span.offsetHeight != spanHeight || span.offsetWidth != spanWidth);
|
1500
|
-
|
1501
|
-
/* results and cleanup */
|
1502
|
-
document.body.removeChild(div);
|
1503
|
-
div.removeChild(span);
|
1504
|
-
|
1505
|
-
return result;
|
1506
|
-
} catch(e) {
|
1507
|
-
return false;
|
1508
|
-
}
|
1509
|
-
}
|
1510
|
-
|
1511
|
-
// for the softhyphens test
|
1512
|
-
function test_hyphens(delimiter, testWidth) {
|
1513
|
-
try {
|
1514
|
-
/* create a div container and a span within that
|
1515
|
-
* these have to be appended to document.body, otherwise some browsers can give false negative */
|
1516
|
-
var div = document.createElement('div'),
|
1517
|
-
span = document.createElement('span'),
|
1518
|
-
divStyle = div.style,
|
1519
|
-
spanSize = 0,
|
1520
|
-
result = false,
|
1521
|
-
result1 = false,
|
1522
|
-
result2 = false,
|
1523
|
-
firstChild = document.body.firstElementChild || document.body.firstChild;
|
1524
|
-
|
1525
|
-
divStyle.cssText = 'position:absolute;top:0;left:0;overflow:visible;width:1.25em;';
|
1526
|
-
div.appendChild(span);
|
1527
|
-
document.body.insertBefore(div, firstChild);
|
1528
|
-
|
1529
|
-
|
1530
|
-
/* get height of unwrapped text */
|
1531
|
-
span.innerHTML = 'mm';
|
1532
|
-
spanSize = span.offsetHeight;
|
1533
|
-
|
1534
|
-
/* compare height w/ delimiter, to see if it wraps to new line */
|
1535
|
-
span.innerHTML = 'm' + delimiter + 'm';
|
1536
|
-
result1 = (span.offsetHeight > spanSize);
|
1537
|
-
|
1538
|
-
/* if we're testing the width too (i.e. for soft-hyphen, not zws),
|
1539
|
-
* this is because tested Blackberry devices will wrap the text but not display the hyphen */
|
1540
|
-
if (testWidth) {
|
1541
|
-
/* get width of wrapped, non-hyphenated text */
|
1542
|
-
span.innerHTML = 'm<br />m';
|
1543
|
-
spanSize = span.offsetWidth;
|
1544
|
-
|
1545
|
-
/* compare width w/ wrapped w/ delimiter to see if hyphen is present */
|
1546
|
-
span.innerHTML = 'm' + delimiter + 'm';
|
1547
|
-
result2 = (span.offsetWidth > spanSize);
|
1548
|
-
} else {
|
1549
|
-
result2 = true;
|
1550
|
-
}
|
1551
|
-
|
1552
|
-
/* results and cleanup */
|
1553
|
-
if (result1 === true && result2 === true) { result = true; }
|
1554
|
-
document.body.removeChild(div);
|
1555
|
-
div.removeChild(span);
|
1556
|
-
|
1557
|
-
return result;
|
1558
|
-
} catch(e) {
|
1559
|
-
return false;
|
1560
|
-
}
|
1561
|
-
}
|
1562
|
-
|
1563
|
-
// testing if in-browser Find functionality will work on hyphenated text
|
1564
|
-
function test_hyphens_find(delimiter) {
|
1565
|
-
try {
|
1566
|
-
/* create a dummy input for resetting selection location, and a div container
|
1567
|
-
* these have to be appended to document.body, otherwise some browsers can give false negative
|
1568
|
-
* div container gets the doubled testword, separated by the delimiter
|
1569
|
-
* Note: giving a width to div gives false positive in iOS Safari */
|
1570
|
-
var dummy = document.createElement('input'),
|
1571
|
-
div = document.createElement('div'),
|
1572
|
-
testword = 'lebowski',
|
1573
|
-
result = false,
|
1574
|
-
textrange,
|
1575
|
-
firstChild = document.body.firstElementChild || document.body.firstChild;
|
1576
|
-
|
1577
|
-
div.innerHTML = testword + delimiter + testword;
|
1578
|
-
|
1579
|
-
document.body.insertBefore(div, firstChild);
|
1580
|
-
document.body.insertBefore(dummy, div);
|
1581
|
-
|
1582
|
-
|
1583
|
-
/* reset the selection to the dummy input element, i.e. BEFORE the div container
|
1584
|
-
* stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area */
|
1585
|
-
if (dummy.setSelectionRange) {
|
1586
|
-
dummy.focus();
|
1587
|
-
dummy.setSelectionRange(0,0);
|
1588
|
-
} else if (dummy.createTextRange) {
|
1589
|
-
textrange = dummy.createTextRange();
|
1590
|
-
textrange.collapse(true);
|
1591
|
-
textrange.moveEnd('character', 0);
|
1592
|
-
textrange.moveStart('character', 0);
|
1593
|
-
textrange.select();
|
1594
|
-
}
|
1595
|
-
|
1596
|
-
/* try to find the doubled testword, without the delimiter */
|
1597
|
-
if (window.find) {
|
1598
|
-
result = window.find(testword + testword);
|
1599
|
-
} else {
|
1600
|
-
try {
|
1601
|
-
textrange = window.self.document.body.createTextRange();
|
1602
|
-
result = textrange.findText(testword + testword);
|
1603
|
-
} catch(e) {
|
1604
|
-
result = false;
|
1605
|
-
}
|
1606
|
-
}
|
1607
|
-
|
1608
|
-
document.body.removeChild(div);
|
1609
|
-
document.body.removeChild(dummy);
|
1610
|
-
|
1611
|
-
return result;
|
1612
|
-
} catch(e) {
|
1613
|
-
return false;
|
1614
|
-
}
|
1615
|
-
}
|
1616
|
-
|
1617
|
-
Modernizr.addTest("csshyphens", function() {
|
1618
|
-
|
1619
|
-
if (!Modernizr.testAllProps('hyphens')) return false;
|
1620
|
-
|
1621
|
-
/* Chrome lies about its hyphens support so we need a more robust test
|
1622
|
-
crbug.com/107111
|
1623
|
-
*/
|
1624
|
-
try {
|
1625
|
-
return test_hyphens_css();
|
1626
|
-
} catch(e) {
|
1627
|
-
return false;
|
1628
|
-
}
|
1629
|
-
});
|
1630
|
-
|
1631
|
-
Modernizr.addTest("softhyphens", function() {
|
1632
|
-
try {
|
1633
|
-
// use numeric entity instead of ­ in case it's XHTML
|
1634
|
-
return test_hyphens('­', true) && test_hyphens('​', false);
|
1635
|
-
} catch(e) {
|
1636
|
-
return false;
|
1637
|
-
}
|
1638
|
-
});
|
1639
|
-
|
1640
|
-
Modernizr.addTest("softhyphensfind", function() {
|
1641
|
-
try {
|
1642
|
-
return test_hyphens_find('­') && test_hyphens_find('​');
|
1643
|
-
} catch(e) {
|
1644
|
-
return false;
|
1645
|
-
}
|
1646
|
-
});
|
1647
|
-
|
1648
|
-
})();
|
1649
|
-
|
1650
|
-
// this tests passes for webkit's proprietary `-webkit-mask` feature
|
1651
|
-
// www.webkit.org/blog/181/css-masks/
|
1652
|
-
// developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Masks/Masks.html
|
1653
|
-
|
1654
|
-
// it does not pass mozilla's implementation of `mask` for SVG
|
1655
|
-
|
1656
|
-
// developer.mozilla.org/en/CSS/mask
|
1657
|
-
// developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content
|
1658
|
-
|
1659
|
-
// Can combine with clippaths for awesomeness: http://generic.cx/for/webkit/test.html
|
1660
|
-
|
1661
|
-
Modernizr.addTest('cssmask', Modernizr.testAllProps('mask-repeat'));
|
1662
|
-
|
1663
|
-
|
1664
|
-
Modernizr.addTest('mediaqueries', Modernizr.mq('only all'));
|
1665
|
-
// dev.opera.com/articles/view/css3-object-fit-object-position/
|
1666
|
-
|
1667
|
-
Modernizr.addTest('object-fit',
|
1668
|
-
!!Modernizr.prefixed('objectFit')
|
1669
|
-
);
|
1670
|
-
// johanbrook.com/browsers/native-momentum-scrolling-ios-5/
|
1671
|
-
// introduced in iOS5b2. Possible API may change...
|
1672
|
-
|
1673
|
-
Modernizr.addTest("overflowscrolling",function(){
|
1674
|
-
return Modernizr.testAllProps("overflowScrolling");
|
1675
|
-
});
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
// developer.mozilla.org/en/CSS/pointer-events
|
1680
|
-
|
1681
|
-
// Test and project pages:
|
1682
|
-
// ausi.github.com/Feature-detection-technique-for-pointer-events/
|
1683
|
-
// github.com/ausi/Feature-detection-technique-for-pointer-events/wiki
|
1684
|
-
// github.com/Modernizr/Modernizr/issues/80
|
1685
|
-
|
1686
|
-
|
1687
|
-
Modernizr.addTest('pointerevents', function(){
|
1688
|
-
var element = document.createElement('x'),
|
1689
|
-
documentElement = document.documentElement,
|
1690
|
-
getComputedStyle = window.getComputedStyle,
|
1691
|
-
supports;
|
1692
|
-
if(!('pointerEvents' in element.style)){
|
1693
|
-
return false;
|
1694
|
-
}
|
1695
|
-
element.style.pointerEvents = 'auto';
|
1696
|
-
element.style.pointerEvents = 'x';
|
1697
|
-
documentElement.appendChild(element);
|
1698
|
-
supports = getComputedStyle &&
|
1699
|
-
getComputedStyle(element, '').pointerEvents === 'auto';
|
1700
|
-
documentElement.removeChild(element);
|
1701
|
-
return !!supports;
|
1702
|
-
});
|
1703
|
-
// Sticky positioning - constrains an element to be positioned inside the
|
1704
|
-
// intersection of its container box, and the viewport.
|
1705
|
-
Modernizr.addTest('csspositionsticky', function () {
|
1706
|
-
|
1707
|
-
var prop = 'position:';
|
1708
|
-
var value = 'sticky';
|
1709
|
-
var el = document.createElement('modernizr');
|
1710
|
-
var mStyle = el.style;
|
1711
|
-
|
1712
|
-
mStyle.cssText = prop + Modernizr._prefixes.join(value + ';' + prop).slice(0, -prop.length);
|
1713
|
-
|
1714
|
-
return mStyle.position.indexOf(value) !== -1;
|
1715
|
-
});
|
1716
|
-
|
1717
|
-
// test by github.com/nsfmc
|
1718
|
-
|
1719
|
-
// "The 'rem' unit ('root em') is relative to the computed
|
1720
|
-
// value of the 'font-size' value of the root element."
|
1721
|
-
// http://www.w3.org/TR/css3-values/#relative0
|
1722
|
-
// you can test by checking if the prop was ditched
|
1723
|
-
|
1724
|
-
// http://snook.ca/archives/html_and_css/font-size-with-rem
|
1725
|
-
|
1726
|
-
Modernizr.addTest('cssremunit', function(){
|
1727
|
-
|
1728
|
-
var div = document.createElement('div');
|
1729
|
-
try {
|
1730
|
-
div.style.fontSize = '3rem';
|
1731
|
-
} catch(er){}
|
1732
|
-
return (/rem/).test(div.style.fontSize);
|
1733
|
-
|
1734
|
-
});
|
1735
|
-
// CSS Regions
|
1736
|
-
// http://www.w3.org/TR/css3-regions/
|
1737
|
-
// By: Mihai Balan
|
1738
|
-
|
1739
|
-
// We start with a CSS parser test then we check page geometry to see if it's affected by regions
|
1740
|
-
// Later we might be able to retire the second part, as WebKit builds with the false positives die out
|
1741
|
-
|
1742
|
-
Modernizr.addTest('regions', function() {
|
1743
|
-
|
1744
|
-
/* Get the 'flowFrom' property name available in the browser. Either default or vendor prefixed.
|
1745
|
-
If the property name can't be found we'll get Boolean 'false' and fail quickly */
|
1746
|
-
var flowFromProperty = Modernizr.prefixed("flowFrom"),
|
1747
|
-
flowIntoProperty = Modernizr.prefixed("flowInto");
|
1748
|
-
|
1749
|
-
if (!flowFromProperty || !flowIntoProperty){
|
1750
|
-
return false;
|
1751
|
-
}
|
1752
|
-
|
1753
|
-
/* If CSS parsing is there, try to determine if regions actually work. */
|
1754
|
-
var container = document.createElement('div'),
|
1755
|
-
content = document.createElement('div'),
|
1756
|
-
region = document.createElement('div'),
|
1757
|
-
|
1758
|
-
/* we create a random, unlikely to be generated flow number to make sure we don't
|
1759
|
-
clash with anything more vanilla, like 'flow', or 'article', or 'f1' */
|
1760
|
-
flowName = 'modernizr_flow_for_regions_check';
|
1761
|
-
|
1762
|
-
/* First create a div with two adjacent divs inside it. The first will be the
|
1763
|
-
content, the second will be the region. To be able to distinguish between the two,
|
1764
|
-
we'll give the region a particular padding */
|
1765
|
-
content.innerText = 'M';
|
1766
|
-
container.style.cssText = 'top: 150px; left: 150px; padding: 0px;';
|
1767
|
-
region.style.cssText = 'width: 50px; height: 50px; padding: 42px;';
|
1768
|
-
|
1769
|
-
region.style[flowFromProperty] = flowName;
|
1770
|
-
container.appendChild(content);
|
1771
|
-
container.appendChild(region);
|
1772
|
-
document.documentElement.appendChild(container);
|
1773
|
-
|
1774
|
-
/* Now compute the bounding client rect, before and after attempting to flow the
|
1775
|
-
content div in the region div. If regions are enabled, the after bounding rect
|
1776
|
-
should reflect the padding of the region div.*/
|
1777
|
-
var flowedRect, delta,
|
1778
|
-
plainRect = content.getBoundingClientRect();
|
1779
|
-
|
1780
|
-
|
1781
|
-
content.style[flowIntoProperty] = flowName;
|
1782
|
-
flowedRect = content.getBoundingClientRect();
|
1783
|
-
|
1784
|
-
delta = flowedRect.left - plainRect.left;
|
1785
|
-
document.documentElement.removeChild(container);
|
1786
|
-
content = region = container = undefined;
|
1787
|
-
|
1788
|
-
return (delta == 42);
|
1789
|
-
});
|
1790
|
-
|
1791
|
-
// Test for CSS 3 UI "resize" property
|
1792
|
-
// http://www.w3.org/TR/css3-ui/#resize
|
1793
|
-
// https://developer.mozilla.org/en/CSS/resize
|
1794
|
-
|
1795
|
-
Modernizr.addTest('cssresize', Modernizr.testAllProps('resize'));
|
1796
|
-
|
1797
|
-
|
1798
|
-
// Stylable scrollbars detection
|
1799
|
-
Modernizr.addTest('cssscrollbar', function() {
|
1800
|
-
|
1801
|
-
var bool,
|
1802
|
-
|
1803
|
-
styles = "#modernizr{overflow: scroll; width: 40px }#" +
|
1804
|
-
Modernizr._prefixes
|
1805
|
-
.join("scrollbar{width:0px}"+' #modernizr::')
|
1806
|
-
.split('#')
|
1807
|
-
.slice(1)
|
1808
|
-
.join('#') + "scrollbar{width:0px}";
|
1809
|
-
|
1810
|
-
Modernizr.testStyles(styles, function(node) {
|
1811
|
-
bool = 'scrollWidth' in node && node.scrollWidth == 40;
|
1812
|
-
});
|
1813
|
-
|
1814
|
-
return bool;
|
1815
|
-
|
1816
|
-
});
|
1817
|
-
/*
|
1818
|
-
* Test for SubPixel Font Rendering
|
1819
|
-
* (to infer if GDI or DirectWrite is used on Windows)
|
1820
|
-
* Authors: @derSchepp, @gerritvanaaken, @rodneyrehm, @yatil, @ryanseddon
|
1821
|
-
* Web: https://github.com/gerritvanaaken/subpixeldetect
|
1822
|
-
*/
|
1823
|
-
Modernizr.addTest('subpixelfont', function() {
|
1824
|
-
var bool,
|
1825
|
-
styles = "#modernizr{position: absolute; top: -10em; visibility:hidden; font: normal 10px arial;}#subpixel{float: left; font-size: 33.3333%;}";
|
1826
|
-
|
1827
|
-
// see https://github.com/Modernizr/Modernizr/blob/master/modernizr.js#L97
|
1828
|
-
Modernizr.testStyles(styles, function(elem) {
|
1829
|
-
var subpixel = elem.firstChild;
|
1830
|
-
|
1831
|
-
subpixel.innerHTML = 'This is a text written in Arial';
|
1832
|
-
|
1833
|
-
bool = window.getComputedStyle ?
|
1834
|
-
window.getComputedStyle(subpixel, null).getPropertyValue("width") !== '44px'
|
1835
|
-
: false;
|
1836
|
-
}, 1, ['subpixel']);
|
1837
|
-
|
1838
|
-
return bool;
|
1839
|
-
});
|
1840
|
-
// http://dev.w3.org/csswg/css3-conditional/#at-supports
|
1841
|
-
// github.com/Modernizr/Modernizr/issues/648
|
1842
|
-
// Relies on the fact that a browser vendor should expose the CSSSupportsRule interface
|
1843
|
-
// http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface
|
1844
|
-
|
1845
|
-
Modernizr.addTest("supports","CSSSupportsRule" in window);// -moz-user-select:none test.
|
1846
|
-
|
1847
|
-
// by ryan seddon
|
1848
|
-
//https://github.com/Modernizr/Modernizr/issues/250
|
1849
|
-
|
1850
|
-
|
1851
|
-
Modernizr.addTest("userselect",function(){
|
1852
|
-
return Modernizr.testAllProps("user-select");
|
1853
|
-
});
|
1854
|
-
|
1855
|
-
// https://github.com/Modernizr/Modernizr/issues/572
|
1856
|
-
// Similar to http://jsfiddle.net/FWeinb/etnYC/
|
1857
|
-
Modernizr.addTest('cssvhunit', function() {
|
1858
|
-
var bool;
|
1859
|
-
Modernizr.testStyles("#modernizr { height: 50vh; }", function(elem, rule) {
|
1860
|
-
var height = parseInt(window.innerHeight/2,10),
|
1861
|
-
compStyle = parseInt((window.getComputedStyle ?
|
1862
|
-
getComputedStyle(elem, null) :
|
1863
|
-
elem.currentStyle)["height"],10);
|
1864
|
-
|
1865
|
-
bool= (compStyle == height);
|
1866
|
-
});
|
1867
|
-
return bool;
|
1868
|
-
});// https://github.com/Modernizr/Modernizr/issues/572
|
1869
|
-
// http://jsfiddle.net/glsee/JDsWQ/4/
|
1870
|
-
Modernizr.addTest('cssvmaxunit', function(){
|
1871
|
-
var bool;
|
1872
|
-
Modernizr.testStyles("#modernizr { width: 50vmax; }", function(elem, rule) {
|
1873
|
-
var one_vw = window.innerWidth/100,
|
1874
|
-
one_vh = window.innerHeight/100,
|
1875
|
-
compWidth = parseInt((window.getComputedStyle ?
|
1876
|
-
getComputedStyle(elem, null) :
|
1877
|
-
elem.currentStyle)['width'],10);
|
1878
|
-
bool = ( parseInt(Math.max(one_vw, one_vh)*50,10) == compWidth );
|
1879
|
-
});
|
1880
|
-
return bool;
|
1881
|
-
});// https://github.com/Modernizr/Modernizr/issues/572
|
1882
|
-
// http://jsfiddle.net/glsee/JRmdq/8/
|
1883
|
-
Modernizr.addTest('cssvminunit', function(){
|
1884
|
-
var bool;
|
1885
|
-
Modernizr.testStyles("#modernizr { width: 50vmin; }", function(elem, rule) {
|
1886
|
-
var one_vw = window.innerWidth/100,
|
1887
|
-
one_vh = window.innerHeight/100,
|
1888
|
-
compWidth = parseInt((window.getComputedStyle ?
|
1889
|
-
getComputedStyle(elem, null) :
|
1890
|
-
elem.currentStyle)['width'],10);
|
1891
|
-
bool = ( parseInt(Math.min(one_vw, one_vh)*50,10) == compWidth );
|
1892
|
-
});
|
1893
|
-
return bool;
|
1894
|
-
});
|
1895
|
-
/*
|
1896
|
-
Custom protocol handler support
|
1897
|
-
http://developers.whatwg.org/timers.html#custom-handlers
|
1898
|
-
|
1899
|
-
Added by @benschwarz
|
1900
|
-
*/
|
1901
|
-
|
1902
|
-
Modernizr.addTest('customprotocolhandler', function () {
|
1903
|
-
return !!navigator.registerProtocolHandler;
|
1904
|
-
});
|
1905
|
-
// https://github.com/Modernizr/Modernizr/issues/572
|
1906
|
-
// http://jsfiddle.net/FWeinb/etnYC/
|
1907
|
-
Modernizr.addTest('cssvwunit', function(){
|
1908
|
-
var bool;
|
1909
|
-
Modernizr.testStyles("#modernizr { width: 50vw; }", function(elem, rule) {
|
1910
|
-
var width = parseInt(window.innerWidth/2,10),
|
1911
|
-
compStyle = parseInt((window.getComputedStyle ?
|
1912
|
-
getComputedStyle(elem, null) :
|
1913
|
-
elem.currentStyle)["width"],10);
|
1914
|
-
|
1915
|
-
bool= (compStyle == width);
|
1916
|
-
});
|
1917
|
-
return bool;
|
1918
|
-
});
|
1919
|
-
// DataView
|
1920
|
-
// https://developer.mozilla.org/en/JavaScript_typed_arrays/DataView
|
1921
|
-
// By Addy Osmani
|
1922
|
-
Modernizr.addTest('dataview', (typeof DataView !== 'undefined' && 'getFloat64' in DataView.prototype));// classList
|
1923
|
-
// https://developer.mozilla.org/en/DOM/element.classList
|
1924
|
-
// By Addy Osmani
|
1925
|
-
Modernizr.addTest('classlist', 'classList' in document.documentElement);
|
1926
|
-
|
1927
|
-
// dataset API for data-* attributes
|
1928
|
-
// test by @phiggins42
|
1929
|
-
|
1930
|
-
Modernizr.addTest('dataset', function(){
|
1931
|
-
var n = document.createElement("div");
|
1932
|
-
n.setAttribute("data-a-b", "c");
|
1933
|
-
return !!(n.dataset && n.dataset.aB === "c");
|
1934
|
-
});
|
1935
|
-
// by james a rosen.
|
1936
|
-
// https://github.com/Modernizr/Modernizr/issues/258
|
1937
|
-
|
1938
|
-
Modernizr.addTest('createelement-attrs', function() {
|
1939
|
-
try {
|
1940
|
-
return document.createElement("<input name='test' />").getAttribute('name') == 'test';
|
1941
|
-
} catch(e) {
|
1942
|
-
return false;
|
1943
|
-
}
|
1944
|
-
});
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
// lol. we already have a test for datalist built in! silly you.
|
1949
|
-
|
1950
|
-
|
1951
|
-
// Helpful links while you're here, though..
|
1952
|
-
|
1953
|
-
// http://css-tricks.com/15346-relevant-dropdowns-polyfill-for-datalist/
|
1954
|
-
// http://miketaylr.com/test/datalist.html
|
1955
|
-
// http://miketaylr.com/code/datalist.html
|
1956
|
-
|
1957
|
-
Modernizr.addTest('datalistelem', Modernizr.input.list );
|
1958
|
-
// Microdata support
|
1959
|
-
// http://www.w3.org/TR/html5/microdata.html
|
1960
|
-
// By Addy Osmani
|
1961
|
-
Modernizr.addTest('microdata', !!(document['getItems']));// By @mathias, based on http://mths.be/axh
|
1962
|
-
Modernizr.addTest('details', function() {
|
1963
|
-
var doc = document,
|
1964
|
-
el = doc.createElement('details'),
|
1965
|
-
fake,
|
1966
|
-
root,
|
1967
|
-
diff;
|
1968
|
-
if (!('open' in el)) { // return early if possible; thanks @aFarkas!
|
1969
|
-
return false;
|
1970
|
-
}
|
1971
|
-
root = doc.body || (function() {
|
1972
|
-
var de = doc.documentElement;
|
1973
|
-
fake = true;
|
1974
|
-
return de.insertBefore(doc.createElement('body'), de.firstElementChild || de.firstChild);
|
1975
|
-
}());
|
1976
|
-
el.innerHTML = '<summary>a</summary>b';
|
1977
|
-
el.style.display = 'block';
|
1978
|
-
root.appendChild(el);
|
1979
|
-
diff = el.offsetHeight;
|
1980
|
-
el.open = true;
|
1981
|
-
diff = diff != el.offsetHeight;
|
1982
|
-
root.removeChild(el);
|
1983
|
-
fake && root.parentNode.removeChild(root);
|
1984
|
-
return diff;
|
1985
|
-
});// Browser support test for the HTML5 <ruby>, <rt> and <rp> elements
|
1986
|
-
// http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-ruby-element
|
1987
|
-
//
|
1988
|
-
// by @alrra
|
1989
|
-
|
1990
|
-
Modernizr.addTest('ruby', function () {
|
1991
|
-
|
1992
|
-
var ruby = document.createElement('ruby'),
|
1993
|
-
rt = document.createElement('rt'),
|
1994
|
-
rp = document.createElement('rp'),
|
1995
|
-
docElement = document.documentElement,
|
1996
|
-
displayStyleProperty = 'display',
|
1997
|
-
fontSizeStyleProperty = 'fontSize'; // 'fontSize' - because it`s only used for IE6 and IE7
|
1998
|
-
|
1999
|
-
ruby.appendChild(rp);
|
2000
|
-
ruby.appendChild(rt);
|
2001
|
-
docElement.appendChild(ruby);
|
2002
|
-
|
2003
|
-
// browsers that support <ruby> hide the <rp> via "display:none"
|
2004
|
-
if ( getStyle(rp, displayStyleProperty) == 'none' || // for non-IE browsers
|
2005
|
-
// but in IE browsers <rp> has "display:inline" so, the test needs other conditions:
|
2006
|
-
getStyle(ruby, displayStyleProperty) == 'ruby' && getStyle(rt, displayStyleProperty) == 'ruby-text' || // for IE8 & IE9
|
2007
|
-
getStyle(rp, fontSizeStyleProperty) == '6pt' && getStyle(rt, fontSizeStyleProperty) == '6pt' ) { // for IE6 & IE7
|
2008
|
-
|
2009
|
-
cleanUp();
|
2010
|
-
return true;
|
2011
|
-
|
2012
|
-
} else {
|
2013
|
-
cleanUp();
|
2014
|
-
return false;
|
2015
|
-
}
|
2016
|
-
|
2017
|
-
function getStyle( element, styleProperty ) {
|
2018
|
-
var result;
|
2019
|
-
|
2020
|
-
if ( window.getComputedStyle ) { // for non-IE browsers
|
2021
|
-
result = document.defaultView.getComputedStyle(element,null).getPropertyValue(styleProperty);
|
2022
|
-
} else if ( element.currentStyle ) { // for IE
|
2023
|
-
result = element.currentStyle[styleProperty];
|
1163
|
+
/**
|
1164
|
+
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
|
1165
|
+
* @private
|
1166
|
+
* @param {Document|DocumentFragment} ownerDocument The document.
|
1167
|
+
* @param {Object} data of the document.
|
1168
|
+
*/
|
1169
|
+
function shivMethods(ownerDocument, data) {
|
1170
|
+
if (!data.cache) {
|
1171
|
+
data.cache = {};
|
1172
|
+
data.createElem = ownerDocument.createElement;
|
1173
|
+
data.createFrag = ownerDocument.createDocumentFragment;
|
1174
|
+
data.frag = data.createFrag();
|
2024
1175
|
}
|
2025
1176
|
|
2026
|
-
return result;
|
2027
|
-
}
|
2028
|
-
|
2029
|
-
function cleanUp() {
|
2030
|
-
docElement.removeChild(ruby);
|
2031
|
-
// the removed child node still exists in memory, so ...
|
2032
|
-
ruby = null;
|
2033
|
-
rt = null;
|
2034
|
-
rp = null;
|
2035
|
-
}
|
2036
|
-
|
2037
|
-
});
|
2038
|
-
//By Stefan Wallin
|
2039
|
-
|
2040
|
-
//tests for progressbar-support. All browsers that don't support progressbar returns undefined =)
|
2041
|
-
Modernizr.addTest("progressbar",function(){
|
2042
|
-
return document.createElement('progress').max !== undefined;
|
2043
|
-
});
|
2044
|
-
|
2045
|
-
//tests for meter-support. All browsers that don't support meters returns undefined =)
|
2046
|
-
Modernizr.addTest("meter",function(){
|
2047
|
-
return document.createElement('meter').max !== undefined;
|
2048
|
-
});
|
2049
|
-
// <time> element
|
2050
|
-
// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#the-time-element-0
|
2051
|
-
// by Addy Osmani
|
2052
|
-
Modernizr.addTest('time', 'valueAsDate' in document.createElement('time'));
|
2053
|
-
// Track element + Timed Text Track API
|
2054
|
-
// http://www.w3.org/TR/html5/video.html#the-track-element
|
2055
|
-
// http://www.w3.org/TR/html5/media-elements.html#text-track-api
|
2056
|
-
//
|
2057
|
-
// While IE10 has implemented the track element, IE10 does not expose the underlying APIs to create timed text tracks by JS (really sad)
|
2058
|
-
// By Addy Osmani
|
2059
|
-
Modernizr.addTest({
|
2060
|
-
texttrackapi: (typeof (document.createElement('video').addTextTrack) === 'function'),
|
2061
|
-
// a more strict test for track including UI support: document.createElement('track').kind === 'subtitles'
|
2062
|
-
track: ('kind' in document.createElement('track'))
|
2063
|
-
});
|
2064
|
-
// <output>
|
2065
|
-
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-output-element
|
2066
|
-
// by Addy Osmani
|
2067
|
-
Modernizr.addTest('outputelem', 'value' in document.createElement('output'));
|
2068
|
-
// Requires a Modernizr build with `canvastext` included
|
2069
|
-
// http://www.modernizr.com/download/#-canvas-canvastext
|
2070
|
-
Modernizr.addTest('emoji', function() {
|
2071
|
-
if (!Modernizr.canvastext) return false;
|
2072
|
-
var node = document.createElement('canvas'),
|
2073
|
-
ctx = node.getContext('2d');
|
2074
|
-
ctx.textBaseline = 'top';
|
2075
|
-
ctx.font = '32px Arial';
|
2076
|
-
ctx.fillText('\ud83d\ude03', 0, 0); // "smiling face with open mouth" emoji
|
2077
|
-
return ctx.getImageData(16, 16, 1, 1).data[0] !== 0;
|
2078
|
-
});// strict mode
|
2079
|
-
|
2080
|
-
// test by @kangax
|
2081
|
-
|
2082
|
-
Modernizr.addTest('strictmode', function(){
|
2083
|
-
return (function(){ "use strict"; return !this; })();
|
2084
|
-
});//By Shi Chuan
|
2085
|
-
//Part of Device Access aspect of HTML5, same category as geolocation
|
2086
|
-
//W3C Editor's Draft at http://dev.w3.org/geo/api/spec-source-orientation.html
|
2087
|
-
//Implementation by iOS Safari at http://goo.gl/fhce3 and http://goo.gl/rLKz8
|
2088
|
-
|
2089
|
-
|
2090
|
-
//test for Device Motion Event support, returns boolean value true/false
|
2091
|
-
Modernizr.addTest('devicemotion', ('DeviceMotionEvent' in window) );
|
2092
|
-
|
2093
|
-
//test for Device Orientation Event support, returns boolean value true/false
|
2094
|
-
Modernizr.addTest('deviceorientation', ('DeviceOrientationEvent' in window) );
|
2095
|
-
// EXIF Orientation test
|
2096
|
-
|
2097
|
-
// iOS looks at the EXIF Orientation flag in jpgs and rotates the image
|
2098
|
-
// accordingly. Looks like most desktop browsers just ignore this data.
|
2099
|
-
|
2100
|
-
// description: www.impulseadventure.com/photo/exif-orientation.html
|
2101
|
-
|
2102
|
-
// Bug trackers:
|
2103
|
-
// bugzil.la/298619 (unimplemented)
|
2104
|
-
// crbug.com/56845 (looks incomplete)
|
2105
|
-
// webk.it/19688 (available upstream but its up all ports to turn on individually)
|
2106
|
-
//
|
2107
|
-
|
2108
|
-
// detect by Paul Sayre
|
2109
|
-
|
2110
|
-
|
2111
|
-
(function(){
|
2112
|
-
|
2113
|
-
var img = new Image();
|
2114
|
-
|
2115
|
-
img.onerror = function() {
|
2116
|
-
Modernizr.addTest('exif-orientation', function () { return false; });
|
2117
|
-
};
|
2118
|
-
|
2119
|
-
img.onload = function() {
|
2120
|
-
Modernizr.addTest('exif-orientation', function () { return img.width !== 2; });
|
2121
|
-
};
|
2122
|
-
|
2123
|
-
// There may be a way to shrink this more, it's a 1x2 white jpg with the orientation flag set to 6
|
2124
|
-
img.src = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAABAAIDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iiiigD/2Q==";
|
2125
|
-
|
2126
|
-
})();
|
2127
|
-
/**
|
2128
|
-
* file tests for the File API specification
|
2129
|
-
* Tests for objects specific to the File API W3C specification without
|
2130
|
-
* being redundant (don't bother testing for Blob since it is assumed
|
2131
|
-
* to be the File object's prototype.
|
2132
|
-
*
|
2133
|
-
* Will fail in Safari 5 due to its lack of support for the standards
|
2134
|
-
* defined FileReader object
|
2135
|
-
*/
|
2136
|
-
Modernizr.addTest('filereader', function () {
|
2137
|
-
return !!(window.File && window.FileList && window.FileReader);
|
2138
|
-
});
|
2139
|
-
|
2140
|
-
|
2141
|
-
// Detects whether input type="file" is available on the platform
|
2142
|
-
// E.g. iOS < 6 and some android version don't support this
|
2143
|
-
|
2144
|
-
// It's useful if you want to hide the upload feature of your app on devices that
|
2145
|
-
// don't support it (iphone, ipad, etc).
|
2146
|
-
|
2147
|
-
Modernizr.addTest('fileinput', function() {
|
2148
|
-
var elem = document.createElement('input');
|
2149
|
-
elem.type = 'file';
|
2150
|
-
return !elem.disabled;
|
2151
|
-
});
|
2152
|
-
// Detects whether input form="form_id" is available on the platform
|
2153
|
-
// E.g. IE 10 (and below), don't support this
|
2154
|
-
Modernizr.addTest("formattribute", function() {
|
2155
|
-
var form = document.createElement("form"),
|
2156
|
-
input = document.createElement("input"),
|
2157
|
-
div = document.createElement("div"),
|
2158
|
-
id = "formtest"+(new Date().getTime()),
|
2159
|
-
attr,
|
2160
|
-
bool = false;
|
2161
|
-
|
2162
|
-
form.id = id;
|
2163
|
-
|
2164
|
-
//IE6/7 confuses the form idl attribute and the form content attribute
|
2165
|
-
if(document.createAttribute){
|
2166
|
-
attr = document.createAttribute("form");
|
2167
|
-
attr.nodeValue = id;
|
2168
|
-
input.setAttributeNode(attr);
|
2169
|
-
div.appendChild(form);
|
2170
|
-
div.appendChild(input);
|
2171
|
-
|
2172
|
-
document.documentElement.appendChild(div);
|
2173
|
-
|
2174
|
-
bool = form.elements.length === 1 && input.form == form;
|
2175
|
-
|
2176
|
-
div.parentNode.removeChild(div);
|
2177
|
-
}
|
2178
|
-
|
2179
|
-
return bool;
|
2180
|
-
});// Filesystem API
|
2181
|
-
// dev.w3.org/2009/dap/file-system/file-dir-sys.html
|
2182
|
-
|
2183
|
-
// The API will be present in Chrome incognito, but will throw an exception.
|
2184
|
-
// See crbug.com/93417
|
2185
|
-
//
|
2186
|
-
// By Eric Bidelman (@ebidel)
|
2187
|
-
|
2188
|
-
Modernizr.addTest('filesystem', !!Modernizr.prefixed('requestFileSystem', window));// testing for placeholder attribute in inputs and textareas
|
2189
|
-
// re-using Modernizr.input if available
|
2190
|
-
|
2191
|
-
Modernizr.addTest('placeholder', function(){
|
2192
|
-
|
2193
|
-
return !!( 'placeholder' in ( Modernizr.input || document.createElement('input') ) &&
|
2194
|
-
'placeholder' in ( Modernizr.textarea || document.createElement('textarea') )
|
2195
|
-
);
|
2196
|
-
|
2197
|
-
});
|
2198
|
-
// speech input for inputs
|
2199
|
-
// by @alrra
|
2200
|
-
|
2201
|
-
|
2202
|
-
// `webkitSpeech` in elem
|
2203
|
-
// doesn`t work correctly in all versions of Chromium based browsers.
|
2204
|
-
// It can return false even if they have support for speech i.imgur.com/2Y40n.png
|
2205
|
-
// Testing with 'onwebkitspeechchange' seems to fix this problem
|
2206
1177
|
|
2207
|
-
|
2208
|
-
//
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
var elem = document.createElement('input');
|
2215
|
-
return 'speech' in elem || 'onwebkitspeechchange' in elem;
|
2216
|
-
});// This implementation only tests support for interactive form validation.
|
2217
|
-
// To check validation for a specific type or a specific other constraint,
|
2218
|
-
// the test can be combined:
|
2219
|
-
// - Modernizr.inputtypes.numer && Modernizr.formvalidation (browser supports rangeOverflow, typeMismatch etc. for type=number)
|
2220
|
-
// - Modernizr.input.required && Modernizr.formvalidation (browser supports valueMissing)
|
2221
|
-
//
|
2222
|
-
(function(document, Modernizr){
|
2223
|
-
|
2224
|
-
|
2225
|
-
Modernizr.formvalidationapi = false;
|
2226
|
-
Modernizr.formvalidationmessage = false;
|
2227
|
-
|
2228
|
-
Modernizr.addTest('formvalidation', function(){
|
2229
|
-
var form = document.createElement('form');
|
2230
|
-
if ( !('checkValidity' in form) ) {
|
2231
|
-
return false;
|
2232
|
-
}
|
2233
|
-
var body = document.body,
|
2234
|
-
|
2235
|
-
html = document.documentElement,
|
2236
|
-
|
2237
|
-
bodyFaked = false,
|
2238
|
-
|
2239
|
-
invaildFired = false,
|
2240
|
-
|
2241
|
-
input;
|
1178
|
+
ownerDocument.createElement = function(nodeName) {
|
1179
|
+
//abort shiv
|
1180
|
+
if (!html5.shivMethods) {
|
1181
|
+
return data.createElem(nodeName);
|
1182
|
+
}
|
1183
|
+
return createElement(nodeName, ownerDocument, data);
|
1184
|
+
};
|
2242
1185
|
|
2243
|
-
|
1186
|
+
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
|
1187
|
+
'var n=f.cloneNode(),c=n.createElement;' +
|
1188
|
+
'h.shivMethods&&(' +
|
1189
|
+
// unroll the `createElement` calls
|
1190
|
+
getElements().join().replace(/\w+/g, function(nodeName) {
|
1191
|
+
data.createElem(nodeName);
|
1192
|
+
data.frag.createElement(nodeName);
|
1193
|
+
return 'c("' + nodeName + '")';
|
1194
|
+
}) +
|
1195
|
+
');return n}'
|
1196
|
+
)(html5, data.frag);
|
1197
|
+
}
|
2244
1198
|
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
1199
|
+
/*--------------------------------------------------------------------------*/
|
1200
|
+
|
1201
|
+
/**
|
1202
|
+
* Shivs the given document.
|
1203
|
+
* @memberOf html5
|
1204
|
+
* @param {Document} ownerDocument The document to shiv.
|
1205
|
+
* @returns {Document} The shived document.
|
1206
|
+
*/
|
1207
|
+
function shivDocument(ownerDocument) {
|
1208
|
+
if (!ownerDocument) {
|
1209
|
+
ownerDocument = document;
|
2250
1210
|
}
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2266
|
-
bodyFaked = true;
|
2267
|
-
body = document.createElement('body');
|
2268
|
-
//avoid crashing IE8, if background image is used
|
2269
|
-
body.style.background = "";
|
2270
|
-
html.appendChild(body);
|
2271
|
-
}
|
1211
|
+
var data = getExpandoData(ownerDocument);
|
1212
|
+
|
1213
|
+
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
|
1214
|
+
data.hasCSS = !!addStyleSheet(ownerDocument,
|
1215
|
+
// corrects block display not defined in IE6/7/8/9
|
1216
|
+
'article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}' +
|
1217
|
+
// adds styling not present in IE6/7/8/9
|
1218
|
+
'mark{background:#FF0;color:#000}'
|
1219
|
+
);
|
1220
|
+
}
|
1221
|
+
if (!supportsUnknownElements) {
|
1222
|
+
shivMethods(ownerDocument, data);
|
1223
|
+
}
|
1224
|
+
return ownerDocument;
|
1225
|
+
}
|
2272
1226
|
|
2273
|
-
|
1227
|
+
/*--------------------------------------------------------------------------*/
|
1228
|
+
|
1229
|
+
/**
|
1230
|
+
* The `html5` object is exposed so that more elements can be shived and
|
1231
|
+
* existing shiving can be detected on iframes.
|
1232
|
+
* @type Object
|
1233
|
+
* @example
|
1234
|
+
*
|
1235
|
+
* // options can be changed before the script is included
|
1236
|
+
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
|
1237
|
+
*/
|
1238
|
+
var html5 = {
|
1239
|
+
|
1240
|
+
/**
|
1241
|
+
* An array or space separated string of node names of the elements to shiv.
|
1242
|
+
* @memberOf html5
|
1243
|
+
* @type Array|String
|
1244
|
+
*/
|
1245
|
+
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video',
|
1246
|
+
|
1247
|
+
/**
|
1248
|
+
* A flag to indicate that the HTML5 style sheet should be inserted.
|
1249
|
+
* @memberOf html5
|
1250
|
+
* @type Boolean
|
1251
|
+
*/
|
1252
|
+
'shivCSS': (options.shivCSS !== false),
|
1253
|
+
|
1254
|
+
/**
|
1255
|
+
* Is equal to true if a browser supports creating unknown/HTML5 elements
|
1256
|
+
* @memberOf html5
|
1257
|
+
* @type boolean
|
1258
|
+
*/
|
1259
|
+
'supportsUnknownElements': supportsUnknownElements,
|
1260
|
+
|
1261
|
+
/**
|
1262
|
+
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
|
1263
|
+
* methods should be overwritten.
|
1264
|
+
* @memberOf html5
|
1265
|
+
* @type Boolean
|
1266
|
+
*/
|
1267
|
+
'shivMethods': (options.shivMethods !== false),
|
1268
|
+
|
1269
|
+
/**
|
1270
|
+
* A string to describe the type of `html5` object ("default" or "default print").
|
1271
|
+
* @memberOf html5
|
1272
|
+
* @type String
|
1273
|
+
*/
|
1274
|
+
'type': 'default',
|
1275
|
+
|
1276
|
+
// shivs the document according to the specified `html5` object options
|
1277
|
+
'shivDocument': shivDocument,
|
1278
|
+
|
1279
|
+
//creates a shived element
|
1280
|
+
createElement: createElement,
|
1281
|
+
|
1282
|
+
//creates a shived documentFragment
|
1283
|
+
createDocumentFragment: createDocumentFragment
|
1284
|
+
};
|
2274
1285
|
|
2275
|
-
|
1286
|
+
/*--------------------------------------------------------------------------*/
|
2276
1287
|
|
2277
|
-
|
2278
|
-
|
2279
|
-
invaildFired = true;
|
2280
|
-
e.preventDefault();
|
2281
|
-
e.stopPropagation();
|
2282
|
-
};
|
1288
|
+
// expose html5
|
1289
|
+
window.html5 = html5;
|
2283
1290
|
|
2284
|
-
|
2285
|
-
|
1291
|
+
// shiv the document
|
1292
|
+
shivDocument(document);
|
2286
1293
|
|
2287
|
-
|
2288
|
-
|
1294
|
+
}(this, document));
|
1295
|
+
/*>>shiv*/
|
2289
1296
|
|
2290
|
-
//
|
2291
|
-
|
2292
|
-
bodyFaked && html.removeChild(body);
|
1297
|
+
// Assign private properties to the return object with prefix
|
1298
|
+
Modernizr._version = version;
|
2293
1299
|
|
2294
|
-
|
2295
|
-
|
1300
|
+
// expose these for the plugin API. Look in the source for how to join() them against your input
|
1301
|
+
/*>>prefixes*/
|
1302
|
+
Modernizr._prefixes = prefixes;
|
1303
|
+
/*>>prefixes*/
|
1304
|
+
/*>>domprefixes*/
|
1305
|
+
Modernizr._domPrefixes = domPrefixes;
|
1306
|
+
Modernizr._cssomPrefixes = cssomPrefixes;
|
1307
|
+
/*>>domprefixes*/
|
1308
|
+
|
1309
|
+
/*>>mq*/
|
1310
|
+
// Modernizr.mq tests a given media query, live against the current state of the window
|
1311
|
+
// A few important notes:
|
1312
|
+
// * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
|
1313
|
+
// * A max-width or orientation query will be evaluated against the current state, which may change later.
|
1314
|
+
// * You must specify values. Eg. If you are testing support for the min-width media query use:
|
1315
|
+
// Modernizr.mq('(min-width:0)')
|
1316
|
+
// usage:
|
1317
|
+
// Modernizr.mq('only screen and (max-width:768)')
|
1318
|
+
Modernizr.mq = testMediaQuery;
|
1319
|
+
/*>>mq*/
|
2296
1320
|
|
1321
|
+
/*>>hasevent*/
|
1322
|
+
// Modernizr.hasEvent() detects support for a given event, with an optional element to test on
|
1323
|
+
// Modernizr.hasEvent('gesturestart', elem)
|
1324
|
+
Modernizr.hasEvent = isEventSupported;
|
1325
|
+
/*>>hasevent*/
|
2297
1326
|
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
});
|
2305
|
-
|
2306
|
-
// http://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/ControllingMediaWithJavaScript/ControllingMediaWithJavaScript.html#//apple_ref/doc/uid/TP40009523-CH3-SW20
|
2307
|
-
// https://developer.mozilla.org/en/API/Fullscreen
|
2308
|
-
// GamePad API
|
2309
|
-
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html
|
2310
|
-
// By Eric Bidelman
|
2311
|
-
|
2312
|
-
// FF has Gamepad API support only in special builds, but not in any release (even behind a flag)
|
2313
|
-
// Their current implementation has no way to feature detect, only events to bind to.
|
2314
|
-
// http://www.html5rocks.com/en/tutorials/doodles/gamepad/#toc-featuredetect
|
2315
|
-
|
2316
|
-
// but a patch will bring them up to date with the spec when it lands (and they'll pass this test)
|
2317
|
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=690935
|
2318
|
-
|
2319
|
-
Modernizr.addTest('gamepads', !!Modernizr.prefixed('getGamepads', navigator));
|
2320
|
-
// getUserMedia
|
2321
|
-
// http://www.whatwg.org/specs/web-apps/current-work/multipage/video-conferencing-and-peer-to-peer-communication.html
|
2322
|
-
// By Eric Bidelman
|
2323
|
-
|
2324
|
-
Modernizr.addTest('getusermedia', !!Modernizr.prefixed('getUserMedia', navigator));
|
2325
|
-
// IE8 compat mode aka Fake IE7
|
2326
|
-
// by Erich Ocean
|
2327
|
-
|
2328
|
-
// In this case, IE8 will be acting as IE7. You may choose to remove features in this case.
|
2329
|
-
|
2330
|
-
// related:
|
2331
|
-
// james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/
|
2332
|
-
|
2333
|
-
Modernizr.addTest('ie8compat',function(){
|
2334
|
-
return (!window.addEventListener && document.documentMode && document.documentMode === 7);
|
2335
|
-
});
|
2336
|
-
// Test for `seamless` attribute in iframes.
|
2337
|
-
//
|
2338
|
-
// Spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-seamless
|
2339
|
-
|
2340
|
-
Modernizr.addTest('seamless', 'seamless' in document.createElement('iframe'));
|
2341
|
-
// Test for `sandbox` attribute in iframes.
|
2342
|
-
//
|
2343
|
-
// Spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox
|
2344
|
-
|
2345
|
-
Modernizr.addTest('sandbox', 'sandbox' in document.createElement('iframe'));
|
2346
|
-
// Test for `srcdoc` attribute in iframes.
|
2347
|
-
//
|
2348
|
-
// Spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-srcdoc
|
2349
|
-
|
2350
|
-
Modernizr.addTest('srcdoc', 'srcdoc' in document.createElement('iframe'));
|
2351
|
-
// Animated PNG
|
2352
|
-
// http://en.wikipedia.org/wiki/APNG
|
2353
|
-
// By Addy Osmani
|
2354
|
-
(function () {
|
2355
|
-
|
2356
|
-
if (!Modernizr.canvas) return false;
|
2357
|
-
|
2358
|
-
var image = new Image(),
|
2359
|
-
canvas = document.createElement('canvas'),
|
2360
|
-
ctx = canvas.getContext('2d');
|
2361
|
-
|
2362
|
-
|
2363
|
-
image.onload = function () {
|
2364
|
-
Modernizr.addTest('apng', function () {
|
2365
|
-
if (typeof canvas.getContext == 'undefined') {
|
2366
|
-
return false;
|
2367
|
-
} else {
|
2368
|
-
ctx.drawImage(image, 0, 0);
|
2369
|
-
return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
|
2370
|
-
}
|
2371
|
-
});
|
1327
|
+
/*>>testprop*/
|
1328
|
+
// Modernizr.testProp() investigates whether a given style property is recognized
|
1329
|
+
// Note that the property names must be provided in the camelCase variant.
|
1330
|
+
// Modernizr.testProp('pointerEvents')
|
1331
|
+
Modernizr.testProp = function(prop){
|
1332
|
+
return testProps([prop]);
|
2372
1333
|
};
|
1334
|
+
/*>>testprop*/
|
2373
1335
|
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
//
|
2378
|
-
//
|
2379
|
-
|
2380
|
-
|
2381
|
-
// This test is asynchronous. Watch out.
|
2382
|
-
|
2383
|
-
(function(){
|
2384
|
-
|
2385
|
-
var image = new Image();
|
2386
|
-
|
2387
|
-
image.onerror = function() {
|
2388
|
-
Modernizr.addTest('webp', false);
|
2389
|
-
};
|
2390
|
-
image.onload = function() {
|
2391
|
-
Modernizr.addTest('webp', function() { return image.width == 1; });
|
2392
|
-
};
|
2393
|
-
|
2394
|
-
image.src = 'data:image/webp;base64,UklGRiwAAABXRUJQVlA4ICAAAAAUAgCdASoBAAEAL/3+/3+CAB/AAAFzrNsAAP5QAAAAAA==';
|
2395
|
-
|
2396
|
-
}());// native JSON support.
|
2397
|
-
// developer.mozilla.org/en/JSON
|
2398
|
-
|
2399
|
-
// this will also succeed if you've loaded the JSON2.js polyfill ahead of time
|
2400
|
-
// ... but that should be obvious. :)
|
2401
|
-
|
2402
|
-
Modernizr.addTest('json', !!window.JSON && !!JSON.parse);
|
2403
|
-
|
2404
|
-
// impressivewebs.com/reverse-ordered-lists-html5
|
2405
|
-
// polyfill: github.com/impressivewebs/HTML5-Reverse-Ordered-Lists
|
2406
|
-
|
2407
|
-
|
2408
|
-
Modernizr.addTest('olreversed', 'reversed' in document.createElement('ol'));
|
2409
|
-
// determining low-bandwidth via navigator.connection
|
2410
|
-
|
2411
|
-
// There are two iterations of the navigator.connection interface:
|
2412
|
-
|
2413
|
-
// The first is present in Android 2.2+ and only in the Browser (not WebView)
|
2414
|
-
// : docs.phonegap.com/en/1.2.0/phonegap_connection_connection.md.html#connection.type
|
2415
|
-
// : davidbcalhoun.com/2010/using-navigator-connection-android
|
2416
|
-
|
2417
|
-
// The second is specced at dev.w3.org/2009/dap/netinfo/ and perhaps landing in WebKit
|
2418
|
-
// : bugs.webkit.org/show_bug.cgi?id=73528
|
2419
|
-
|
2420
|
-
// unknown devices are assumed as fast
|
2421
|
-
// for more rigorous network testing, consider boomerang.js: github.com/bluesmoon/boomerang/
|
2422
|
-
|
2423
|
-
Modernizr.addTest('lowbandwidth', function() {
|
2424
|
-
|
2425
|
-
var connection = navigator.connection || { type: 0 }; // polyfill
|
2426
|
-
|
2427
|
-
return connection.type == 3 || // connection.CELL_2G
|
2428
|
-
connection.type == 4 || // connection.CELL_3G
|
2429
|
-
/^[23]g$/.test(connection.type); // string value in new spec
|
2430
|
-
});
|
2431
|
-
// MathML
|
2432
|
-
// http://www.w3.org/Math/
|
2433
|
-
// By Addy Osmani
|
2434
|
-
// Based on work by Davide (@dpvc) and David (@davidcarlisle)
|
2435
|
-
// in https://github.com/mathjax/MathJax/issues/182
|
2436
|
-
|
2437
|
-
Modernizr.addTest('mathml', function(){
|
2438
|
-
var hasMathML = false;
|
2439
|
-
if ( document.createElementNS ) {
|
2440
|
-
var ns = "http://www.w3.org/1998/Math/MathML",
|
2441
|
-
div = document.createElement("div");
|
2442
|
-
div.style.position = "absolute";
|
2443
|
-
var mfrac = div.appendChild(document.createElementNS(ns,"math"))
|
2444
|
-
.appendChild(document.createElementNS(ns,"mfrac"));
|
2445
|
-
mfrac.appendChild(document.createElementNS(ns,"mi"))
|
2446
|
-
.appendChild(document.createTextNode("xx"));
|
2447
|
-
mfrac.appendChild(document.createElementNS(ns,"mi"))
|
2448
|
-
.appendChild(document.createTextNode("yy"));
|
2449
|
-
document.body.appendChild(div);
|
2450
|
-
hasMathML = div.offsetHeight > div.offsetWidth;
|
2451
|
-
}
|
2452
|
-
return hasMathML;
|
2453
|
-
});
|
2454
|
-
// server sent events aka eventsource
|
2455
|
-
// dev.w3.org/html5/eventsource/
|
2456
|
-
|
2457
|
-
Modernizr.addTest('eventsource', !!window.EventSource);
|
2458
|
-
|
2459
|
-
|
2460
|
-
// XML HTTP Request Level 2
|
2461
|
-
// www.w3.org/TR/XMLHttpRequest2/
|
2462
|
-
|
2463
|
-
// Much more details at github.com/Modernizr/Modernizr/issues/385
|
2464
|
-
|
2465
|
-
// all three of these details report consistently across all target browsers:
|
2466
|
-
// !!(window.ProgressEvent);
|
2467
|
-
// !!(window.FormData);
|
2468
|
-
// window.XMLHttpRequest && "withCredentials" in new XMLHttpRequest;
|
2469
|
-
|
2470
|
-
Modernizr.addTest('xhr2', 'FormData' in window);
|
2471
|
-
// https://developer.mozilla.org/en-US/docs/API/Pointer_Lock_API
|
2472
|
-
|
2473
|
-
Modernizr.addTest('pointerlock',!!Modernizr.prefixed('pointerLockElement', document));
|
2474
|
-
|
2475
|
-
// Notifications
|
2476
|
-
// By Theodoor van Donge
|
2477
|
-
|
2478
|
-
// window.webkitNotifications is only used by Chrome
|
2479
|
-
// http://www.html5rocks.com/en/tutorials/notifications/quick/
|
2480
|
-
|
2481
|
-
// window.Notification only exist in the draft specs
|
2482
|
-
// http://dev.w3.org/2006/webapi/WebNotifications/publish/Notifications.html#idl-if-Notification
|
2483
|
-
|
2484
|
-
Modernizr.addTest('notification', !!Modernizr.prefixed('Notifications', window));// Navigation Timing (Performance)
|
2485
|
-
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/
|
2486
|
-
// http://www.html5rocks.com/en/tutorials/webperformance/basics/
|
2487
|
-
// By Scott Murphy (uxder)
|
2488
|
-
Modernizr.addTest('performance', !!Modernizr.prefixed('performance', window));// Quota Storage Management API
|
2489
|
-
// This API can be used to check how much quota an origin is using and request more
|
2490
|
-
|
2491
|
-
// Currently only implemented in Chrome.
|
2492
|
-
// https://developers.google.com/chrome/whitepapers/storage
|
2493
|
-
// By Addy Osmani
|
2494
|
-
|
2495
|
-
Modernizr.addTest('quotamanagement', function(){
|
2496
|
-
var storage = Modernizr.prefixed('StorageInfo', window);
|
2497
|
-
return !!(storage && 'TEMPORARY' in storage && 'PERSISTENT' in storage);
|
2498
|
-
});
|
2499
|
-
|
2500
|
-
// requestAnimationFrame
|
2501
|
-
// Offload animation repainting to browser for optimized performance.
|
2502
|
-
// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html
|
2503
|
-
// By Addy Osmani
|
2504
|
-
|
2505
|
-
Modernizr.addTest('raf', !!Modernizr.prefixed('requestAnimationFrame', window));// async script
|
2506
|
-
// By Theodoor van Donge
|
2507
|
-
Modernizr.addTest('scriptasync', 'async' in document.createElement('script'));// defer script
|
2508
|
-
// By Theodoor van Donge
|
2509
|
-
Modernizr.addTest('scriptdefer', 'defer' in document.createElement('script'));// Browser support test for <style scoped>
|
2510
|
-
// http://www.w3.org/TR/html5/the-style-element.html#attr-style-scoped
|
2511
|
-
//
|
2512
|
-
// by @alrra
|
2513
|
-
|
2514
|
-
Modernizr.addTest( 'stylescoped', 'scoped' in document.createElement('style') );
|
2515
|
-
// Detect support for svg filters - http://www.w3.org/TR/SVG11/filters.html.
|
2516
|
-
// Should fail in Safari: http://stackoverflow.com/questions/9739955/feature-detecting-support-for-svg-filters.
|
2517
|
-
// detect by erik dahlstrom
|
2518
|
-
|
2519
|
-
Modernizr.addTest('svgfilters', function(){
|
2520
|
-
var result = false;
|
2521
|
-
try {
|
2522
|
-
result = typeof SVGFEColorMatrixElement !== undefined &&
|
2523
|
-
SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE == 2;
|
2524
|
-
}
|
2525
|
-
catch(e) {}
|
2526
|
-
return result;
|
2527
|
-
});
|
2528
|
-
/**
|
2529
|
-
* Unicode special character support
|
2530
|
-
*
|
2531
|
-
* Detection is made by testing missing glyph box rendering against star character
|
2532
|
-
* If widths are the same, this "probably" means the browser didn't support the star character and rendered a glyph box instead
|
2533
|
-
* Just need to ensure the font characters have different widths
|
2534
|
-
*
|
2535
|
-
* Warning : positive Unicode support doesn't mean you can use it inside <title>, this seams more related to OS & Language packs
|
2536
|
-
*/
|
2537
|
-
Modernizr.addTest('unicode', function() {
|
2538
|
-
|
2539
|
-
|
2540
|
-
var bool,
|
2541
|
-
|
2542
|
-
missingGlyph = document.createElement('span'),
|
2543
|
-
|
2544
|
-
star = document.createElement('span');
|
2545
|
-
|
2546
|
-
Modernizr.testStyles('#modernizr{font-family:Arial,sans;font-size:300em;}', function(node) {
|
2547
|
-
|
2548
|
-
missingGlyph.innerHTML = 'ᝣ';
|
2549
|
-
star.innerHTML = '☆';
|
2550
|
-
|
2551
|
-
node.appendChild(missingGlyph);
|
2552
|
-
node.appendChild(star);
|
2553
|
-
|
2554
|
-
bool = 'offsetWidth' in missingGlyph && missingGlyph.offsetWidth !== star.offsetWidth;
|
2555
|
-
});
|
2556
|
-
|
2557
|
-
return bool;
|
2558
|
-
|
2559
|
-
});// data uri test.
|
2560
|
-
// https://github.com/Modernizr/Modernizr/issues/14
|
2561
|
-
|
2562
|
-
// This test is asynchronous. Watch out.
|
2563
|
-
|
2564
|
-
|
2565
|
-
// in IE7 in HTTPS this can cause a Mixed Content security popup.
|
2566
|
-
// github.com/Modernizr/Modernizr/issues/362
|
2567
|
-
// To avoid that you can create a new iframe and inject this.. perhaps..
|
2568
|
-
|
2569
|
-
|
2570
|
-
(function(){
|
2571
|
-
|
2572
|
-
var datauri = new Image();
|
2573
|
-
|
2574
|
-
|
2575
|
-
datauri.onerror = function() {
|
2576
|
-
Modernizr.addTest('datauri', function () { return false; });
|
2577
|
-
};
|
2578
|
-
datauri.onload = function() {
|
2579
|
-
Modernizr.addTest('datauri', function () { return (datauri.width == 1 && datauri.height == 1); });
|
2580
|
-
};
|
2581
|
-
|
2582
|
-
datauri.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
|
2583
|
-
|
2584
|
-
})();
|
2585
|
-
// test if IE userdata supported
|
2586
|
-
// msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx
|
2587
|
-
// test by @stereobooster
|
2588
|
-
|
2589
|
-
Modernizr.addTest('userdata', function(){
|
2590
|
-
return !!document.createElement('div').addBehavior;
|
2591
|
-
});
|
2592
|
-
// Vibration API
|
2593
|
-
// http://www.w3.org/TR/vibration/
|
2594
|
-
// https://developer.mozilla.org/en/DOM/window.navigator.mozVibrate
|
2595
|
-
Modernizr.addTest('vibrate', !!Modernizr.prefixed('vibrate', navigator));// Tests for the ability to use Web Intents (http://webintents.org).
|
2596
|
-
// By Eric Bidelman
|
2597
|
-
|
2598
|
-
Modernizr.addTest('webintents', function() {
|
2599
|
-
return !!Modernizr.prefixed('startActivity', navigator);
|
2600
|
-
});
|
2601
|
-
|
2602
|
-
// binaryType is truthy if there is support.. returns "blob" in new-ish chrome.
|
2603
|
-
// plus.google.com/115535723976198353696/posts/ERN6zYozENV
|
2604
|
-
|
2605
|
-
Modernizr.addTest('websocketsbinary',
|
2606
|
-
!!(window.WebSocket && (new WebSocket('ws://.')).binaryType)
|
2607
|
-
);
|
2608
|
-
|
2609
|
-
// Grab the WebGL extensions currently supported and add to the Modernizr.webgl object
|
2610
|
-
// spec: www.khronos.org/registry/webgl/specs/latest/#5.13.14
|
2611
|
-
|
2612
|
-
// based on code from ilmari heikkinen
|
2613
|
-
// code.google.com/p/graphics-detect/source/browse/js/detect.js
|
2614
|
-
|
2615
|
-
|
2616
|
-
(function(){
|
2617
|
-
|
2618
|
-
if (!Modernizr.webgl) return;
|
2619
|
-
|
2620
|
-
var canvas, ctx, exts;
|
2621
|
-
|
2622
|
-
try {
|
2623
|
-
canvas = document.createElement('canvas');
|
2624
|
-
ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
|
2625
|
-
exts = ctx.getSupportedExtensions();
|
2626
|
-
}
|
2627
|
-
catch (e) {
|
2628
|
-
return;
|
2629
|
-
}
|
2630
|
-
|
2631
|
-
if (ctx === undefined) {
|
2632
|
-
Modernizr.webgl = new Boolean(false);
|
2633
|
-
}
|
2634
|
-
else {
|
2635
|
-
Modernizr.webgl = new Boolean(true);
|
2636
|
-
}
|
2637
|
-
|
2638
|
-
|
2639
|
-
for (var i = -1, len = exts.length; ++i < len; ){
|
2640
|
-
Modernizr.webgl[exts[i]] = true;
|
2641
|
-
}
|
2642
|
-
|
2643
|
-
// hack for addressing modernizr testsuite failures. sorry.
|
2644
|
-
if (window.TEST && TEST.audvid){
|
2645
|
-
TEST.audvid.push('webgl');
|
2646
|
-
}
|
2647
|
-
|
2648
|
-
canvas = undefined;
|
2649
|
-
})();
|
2650
|
-
// tests if page is iframed
|
2651
|
-
|
2652
|
-
// github.com/Modernizr/Modernizr/issues/242
|
2653
|
-
|
2654
|
-
Modernizr.addTest('framed', function(){
|
2655
|
-
return window.location != top.location;
|
2656
|
-
});
|
2657
|
-
// by jussi-kalliokoski
|
2658
|
-
|
2659
|
-
|
2660
|
-
// This test is asynchronous. Watch out.
|
2661
|
-
|
2662
|
-
// The test will potentially add garbage to console.
|
2663
|
-
|
2664
|
-
(function(){
|
2665
|
-
try {
|
1336
|
+
/*>>testallprops*/
|
1337
|
+
// Modernizr.testAllProps() investigates whether a given style property,
|
1338
|
+
// or any of its vendor-prefixed variants, is recognized
|
1339
|
+
// Note that the property names must be provided in the camelCase variant.
|
1340
|
+
// Modernizr.testAllProps('boxSizing')
|
1341
|
+
Modernizr.testAllProps = testPropsAll;
|
1342
|
+
/*>>testallprops*/
|
2666
1343
|
|
2667
|
-
// we're avoiding using Modernizr._domPrefixes as the prefix capitalization on
|
2668
|
-
// these guys are notoriously peculiar.
|
2669
|
-
var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder || window.OBlobBuilder || window.BlobBuilder,
|
2670
|
-
URL = window.MozURL || window.webkitURL || window.MSURL || window.OURL || window.URL;
|
2671
1344
|
|
2672
|
-
|
2673
|
-
|
1345
|
+
/*>>teststyles*/
|
1346
|
+
// Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
|
1347
|
+
// Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
|
1348
|
+
Modernizr.testStyles = injectElementWithStyles;
|
1349
|
+
/*>>teststyles*/
|
2674
1350
|
|
2675
|
-
bb.append('this.onmessage=function(e){postMessage(e.data)}');
|
2676
1351
|
|
2677
|
-
|
2678
|
-
|
1352
|
+
/*>>prefixed*/
|
1353
|
+
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
|
1354
|
+
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
|
2679
1355
|
|
2680
|
-
|
1356
|
+
// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
|
1357
|
+
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
|
1358
|
+
//
|
1359
|
+
// str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
|
2681
1360
|
|
2682
|
-
|
2683
|
-
|
2684
|
-
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
1361
|
+
// If you're trying to ascertain which transition end event to bind to, you might do something like...
|
1362
|
+
//
|
1363
|
+
// var transEndEventNames = {
|
1364
|
+
// 'WebkitTransition' : 'webkitTransitionEnd',
|
1365
|
+
// 'MozTransition' : 'transitionend',
|
1366
|
+
// 'OTransition' : 'oTransitionEnd',
|
1367
|
+
// 'msTransition' : 'MSTransitionEnd',
|
1368
|
+
// 'transition' : 'transitionend'
|
1369
|
+
// },
|
1370
|
+
// transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
|
2688
1371
|
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
1372
|
+
Modernizr.prefixed = function(prop, obj, elem){
|
1373
|
+
if(!obj) {
|
1374
|
+
return testPropsAll(prop, 'pfx');
|
1375
|
+
} else {
|
1376
|
+
// Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
|
1377
|
+
return testPropsAll(prop, obj, elem);
|
1378
|
+
}
|
2693
1379
|
};
|
1380
|
+
/*>>prefixed*/
|
2694
1381
|
|
2695
|
-
setTimeout(function() {
|
2696
|
-
Modernizr.addTest('blobworkers', false);
|
2697
|
-
}, 200);
|
2698
|
-
|
2699
|
-
worker.postMessage(data);
|
2700
|
-
|
2701
|
-
} catch (e) {
|
2702
|
-
Modernizr.addTest('blobworkers', false);
|
2703
|
-
}
|
2704
|
-
}());
|
2705
|
-
// by jussi-kalliokoski
|
2706
|
-
|
2707
|
-
|
2708
|
-
// This test is asynchronous. Watch out.
|
2709
|
-
|
2710
|
-
// The test will potentially add garbage to console.
|
2711
|
-
|
2712
|
-
(function(){
|
2713
|
-
try {
|
2714
|
-
var data = 'Modernizr',
|
2715
|
-
worker = new Worker('data:text/javascript;base64,dGhpcy5vbm1lc3NhZ2U9ZnVuY3Rpb24oZSl7cG9zdE1lc3NhZ2UoZS5kYXRhKX0=');
|
2716
1382
|
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
worker = null;
|
2721
|
-
};
|
2722
|
-
|
2723
|
-
// Just in case...
|
2724
|
-
worker.onerror = function() {
|
2725
|
-
Modernizr.addTest('dataworkers', false);
|
2726
|
-
worker = null;
|
2727
|
-
};
|
1383
|
+
/*>>cssclasses*/
|
1384
|
+
// Remove "no-js" class from <html> element, if it exists:
|
1385
|
+
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
|
2728
1386
|
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
1387
|
+
// Add the new classes to the <html> element.
|
1388
|
+
(enableClasses ? ' js ' + classes.join(' ') : '');
|
1389
|
+
/*>>cssclasses*/
|
2732
1390
|
|
2733
|
-
|
1391
|
+
return Modernizr;
|
2734
1392
|
|
2735
|
-
|
2736
|
-
Modernizr.addTest('dataworkers', false);
|
2737
|
-
}
|
2738
|
-
}());
|
2739
|
-
Modernizr.addTest('sharedworkers', function(){
|
2740
|
-
return !!window.SharedWorker;
|
2741
|
-
});;
|
1393
|
+
})(this, this.document);
|