ie-compat 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9b4f7088415a7dc8f035348ed81fc0d592b08348
4
+ data.tar.gz: f9ea8270545de0717d1c088c021263b4515671b3
5
+ SHA512:
6
+ metadata.gz: 0289991b634aa58900ebe7e86ae9f3177316d0240393891662176a48d765815b705a84cc639f368176382ceeac5f4bca9d477fb6dffe6d6b1faa67ca6659b631
7
+ data.tar.gz: 328c0d7d2abe4529b7b34848cd6fb96fc7e000619d3e500d780c5d36e8af3e23f2ff1283b63609c90f1c43ebd5441c931f9ba841a387ca727d1c293e731b5fcc
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ie-compat.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Elia Schito
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # IE::Compat
2
+
3
+ Sick of reimplementing `console.log` every time you have to support Microsoft Internet Explorer < 10?
4
+
5
+ ## Features
6
+
7
+ - `console` stubs
8
+ - JSON
9
+ - CSS3 selectors (via http://selectivizr.com)
10
+ - `Function.prototype.bind`
11
+ - `Array.prototype.forEach`
12
+
13
+
14
+ ![⚠️ Done](http://cl.ly/image/272i1m2U0H0j/javascript-error-icon.gif)
15
+
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ gem 'ie-compat'
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install ie-compat
30
+
31
+ ### Opal, Rails, Sprockets, ActiveAdmin
32
+
33
+ Happy days, got you covered!
34
+
35
+ (at least if they're required *before* `IE::Compat`)
36
+
37
+
38
+ ### Everything Else
39
+
40
+ The base path of all the provided assets is available here:
41
+
42
+ ```ruby
43
+ IE::Compat.assets_path
44
+ ```
45
+
46
+
47
+ ## Usage
48
+
49
+ ### Rails
50
+
51
+ In your application layout add this line:
52
+
53
+ ```erb
54
+ <%= ie_compat_tags =>
55
+ ```
56
+
57
+ That will be translated into something like this:
58
+
59
+ ```html
60
+ <!--[if lt IE 9]>
61
+ <script src="/assets/ie-compat/lt-9-8df327478e15576a740b24b7f3f746af.js" type="text/javascript"></script>
62
+ <![endif]-->
63
+
64
+ <!--[if IE 9]>
65
+ <script src="/assets/ie-compat/9-f7b8808e991e7cd9ee6c161d2c31473f.js" type="text/javascript"></script>
66
+ <![endif]-->
67
+ ```
68
+
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it ( https://github.com/[my-github-username]/ie-compat/fork )
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,3 @@
1
+ //= require ie-compat/function_bind
2
+ //= require ie-compat/array_foreach
3
+ //= require ie-compat/console
@@ -0,0 +1,58 @@
1
+ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Compatibility
2
+ // Production steps of ECMA-262, Edition 5, 15.4.4.18
3
+ // Reference: http://es5.github.com/#x15.4.4.18
4
+ if (!Array.prototype.forEach) {
5
+
6
+ Array.prototype.forEach = function forEach(callback, thisArg) {
7
+ 'use strict';
8
+ var T, k;
9
+
10
+ if (this == null) {
11
+ throw new TypeError("this is null or not defined");
12
+ }
13
+
14
+ var kValue,
15
+ // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
16
+ O = Object(this),
17
+
18
+ // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
19
+ // 3. Let len be ToUint32(lenValue).
20
+ len = O.length >>> 0; // Hack to convert O.length to a UInt32
21
+
22
+ // 4. If IsCallable(callback) is false, throw a TypeError exception.
23
+ // See: http://es5.github.com/#x9.11
24
+ if ({}.toString.call(callback) !== "[object Function]") {
25
+ throw new TypeError(callback + " is not a function");
26
+ }
27
+
28
+ // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
29
+ if (arguments.length >= 2) {
30
+ T = thisArg;
31
+ }
32
+
33
+ // 6. Let k be 0
34
+ k = 0;
35
+
36
+ // 7. Repeat, while k < len
37
+ while (k < len) {
38
+
39
+ // a. Let Pk be ToString(k).
40
+ // This is implicit for LHS operands of the in operator
41
+ // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
42
+ // This step can be combined with c
43
+ // c. If kPresent is true, then
44
+ if (k in O) {
45
+
46
+ // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
47
+ kValue = O[k];
48
+
49
+ // ii. Call the Call internal method of callback with T as the this value and
50
+ // argument list containing kValue, k, and O.
51
+ callback.call(T, kValue, k, O);
52
+ }
53
+ // d. Increase k by 1.
54
+ k++;
55
+ }
56
+ // 8. return undefined
57
+ };
58
+ }
@@ -0,0 +1,20 @@
1
+ // Fix console for IE, lolz, now
2
+ if (!window.console) {
3
+ window.console = {};
4
+ [
5
+ "log","info","warn","error","assert","dir","clear","profile","profileEnd"
6
+ ].forEach(function (method) {
7
+ window.console[method] = function() {};
8
+ });
9
+ }
10
+
11
+ // From: http://stackoverflow.com/a/5539378
12
+ if (Function.prototype.bind && window.console && typeof console.log == "object"){
13
+ [
14
+ "log","info","warn","error","assert","dir","clear","profile","profileEnd"
15
+ ].forEach(function (method) {
16
+ console[method] = this.bind(console[method], console);
17
+ }, Function.prototype.call);
18
+ }
19
+
20
+
@@ -0,0 +1,25 @@
1
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility
2
+ if (!Function.prototype.bind) {
3
+ Function.prototype.bind = function (oThis) {
4
+ if (typeof this !== "function") {
5
+ // closest thing possible to the ECMAScript 5 internal IsCallable function
6
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
7
+ }
8
+
9
+ var aArgs = Array.prototype.slice.call(arguments, 1),
10
+ fToBind = this,
11
+ fNOP = function () {},
12
+ fBound = function () {
13
+ return fToBind.apply(this instanceof fNOP && oThis
14
+ ? this
15
+ : oThis,
16
+ aArgs.concat(Array.prototype.slice.call(arguments)));
17
+ };
18
+
19
+ fNOP.prototype = this.prototype;
20
+ fBound.prototype = new fNOP();
21
+
22
+ return fBound;
23
+ };
24
+ }
25
+
@@ -0,0 +1,4 @@
1
+ //= require ie-compat/9
2
+ //= require ie-compat/vendor/html5shiv-printshiv
3
+ //= require ie-compat/vendor/json2
4
+ //= require ie-compat/vendor/selectivizr-min
@@ -0,0 +1,404 @@
1
+ /*! HTML5 Shiv vpre3.6 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */
2
+ ;(function(window, document) {
3
+
4
+ /** Preset options */
5
+ var options = window.html5 || {};
6
+
7
+ /** Used to skip problem elements */
8
+ var reSkip = /^<|^(?:button|form|map|select|textarea|object|iframe|option|optgroup)$/i;
9
+
10
+ /** Not all elements can be cloned in IE (this list can be shortend) **/
11
+ 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;
12
+
13
+ /** Detect whether the browser supports default html5 styles */
14
+ var supportsHtml5Styles;
15
+
16
+ /** Detect whether the browser supports unknown elements */
17
+ var supportsUnknownElements;
18
+
19
+ (function() {
20
+ var a = document.createElement('a');
21
+
22
+ a.innerHTML = '<xyz></xyz>';
23
+
24
+ //if the hidden property is implemented we can assume, that the browser supports HTML5 Styles | this fails in Chrome 8
25
+ supportsHtml5Styles = ('hidden' in a);
26
+ //if we are part of Modernizr, we do an additional test to solve the Chrome 8 fail
27
+ if(supportsHtml5Styles && typeof injectElementWithStyles == 'function'){
28
+ injectElementWithStyles('#modernizr{}', function(node){
29
+ node.hidden = true;
30
+ supportsHtml5Styles = (window.getComputedStyle ?
31
+ getComputedStyle(node, null) :
32
+ node.currentStyle).display == 'none';
33
+ });
34
+ }
35
+
36
+ supportsUnknownElements = a.childNodes.length == 1 || (function() {
37
+ // assign a false positive if unable to shiv
38
+ try {
39
+ (document.createElement)('a');
40
+ } catch(e) {
41
+ return true;
42
+ }
43
+ var frag = document.createDocumentFragment();
44
+ return (
45
+ typeof frag.cloneNode == 'undefined' ||
46
+ typeof frag.createDocumentFragment == 'undefined' ||
47
+ typeof frag.createElement == 'undefined'
48
+ );
49
+ }());
50
+
51
+ }());
52
+
53
+ /*--------------------------------------------------------------------------*/
54
+
55
+ /**
56
+ * Creates a style sheet with the given CSS text and adds it to the document.
57
+ * @private
58
+ * @param {Document} ownerDocument The document.
59
+ * @param {String} cssText The CSS text.
60
+ * @returns {StyleSheet} The style element.
61
+ */
62
+ function addStyleSheet(ownerDocument, cssText) {
63
+ var p = ownerDocument.createElement('p'),
64
+ parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
65
+
66
+ p.innerHTML = 'x<style>' + cssText + '</style>';
67
+ return parent.insertBefore(p.lastChild, parent.firstChild);
68
+ }
69
+
70
+ /**
71
+ * Returns the value of `html5.elements` as an array.
72
+ * @private
73
+ * @returns {Array} An array of shived element node names.
74
+ */
75
+ function getElements() {
76
+ var elements = html5.elements;
77
+ return typeof elements == 'string' ? elements.split(' ') : elements;
78
+ }
79
+
80
+ /**
81
+ * Shivs the `createElement` and `createDocumentFragment` methods of the document.
82
+ * @private
83
+ * @param {Document|DocumentFragment} ownerDocument The document.
84
+ */
85
+ function shivMethods(ownerDocument) {
86
+ var cache = {},
87
+ docCreateElement = ownerDocument.createElement,
88
+ docCreateFragment = ownerDocument.createDocumentFragment,
89
+ frag = docCreateFragment();
90
+
91
+ ownerDocument.createElement = function(nodeName) {
92
+ //abort shiv
93
+ if(!html5.shivMethods){
94
+ return docCreateElement(nodeName);
95
+ }
96
+
97
+ var node;
98
+
99
+ if(cache[nodeName]){
100
+ node = cache[nodeName].cloneNode();
101
+ } else if(saveClones.test(nodeName)){
102
+ node = (cache[nodeName] = docCreateElement(nodeName)).cloneNode();
103
+ } else {
104
+ node = docCreateElement(nodeName);
105
+ }
106
+
107
+ // Avoid adding some elements to fragments in IE < 9 because
108
+ // * Attributes like `name` or `type` cannot be set/changed once an element
109
+ // is inserted into a document/fragment
110
+ // * Link elements with `src` attributes that are inaccessible, as with
111
+ // a 403 response, will cause the tab/window to crash
112
+ // * Script elements appended to fragments will execute when their `src`
113
+ // or `text` property is set
114
+
115
+ return node.canHaveChildren && !reSkip.test(nodeName) ? frag.appendChild(node) : node;
116
+ };
117
+
118
+ ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
119
+ 'var n=f.cloneNode(),c=n.createElement;' +
120
+ 'h.shivMethods&&(' +
121
+ // unroll the `createElement` calls
122
+ getElements().join().replace(/\w+/g, function(nodeName) {
123
+ docCreateElement(nodeName);
124
+ frag.createElement(nodeName);
125
+ return 'c("' + nodeName + '")';
126
+ }) +
127
+ ');return n}'
128
+ )(html5, frag);
129
+ }
130
+
131
+ /*--------------------------------------------------------------------------*/
132
+
133
+ /**
134
+ * Shivs the given document.
135
+ * @memberOf html5
136
+ * @param {Document} ownerDocument The document to shiv.
137
+ * @returns {Document} The shived document.
138
+ */
139
+ function shivDocument(ownerDocument) {
140
+ var shived;
141
+ if (ownerDocument.documentShived) {
142
+ return ownerDocument;
143
+ }
144
+ if (html5.shivCSS && !supportsHtml5Styles) {
145
+ shived = !!addStyleSheet(ownerDocument,
146
+ // corrects block display not defined in IE6/7/8/9
147
+ 'article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}' +
148
+ // corrects audio display not defined in IE6/7/8/9
149
+ 'audio{display:none}' +
150
+ // corrects canvas and video display not defined in IE6/7/8/9
151
+ 'canvas,video{display:inline-block;*display:inline;*zoom:1}' +
152
+ // corrects 'hidden' attribute and audio[controls] display not present in IE7/8/9
153
+ '[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}' +
154
+ // adds styling not present in IE6/7/8/9
155
+ 'mark{background:#FF0;color:#000}'
156
+ );
157
+ }
158
+ if (!supportsUnknownElements) {
159
+ shived = !shivMethods(ownerDocument);
160
+ }
161
+ if (shived) {
162
+ ownerDocument.documentShived = shived;
163
+ }
164
+ return ownerDocument;
165
+ }
166
+
167
+ /*--------------------------------------------------------------------------*/
168
+
169
+ /**
170
+ * The `html5` object is exposed so that more elements can be shived and
171
+ * existing shiving can be detected on iframes.
172
+ * @type Object
173
+ * @example
174
+ *
175
+ * // options can be changed before the script is included
176
+ * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
177
+ */
178
+ var html5 = {
179
+
180
+ /**
181
+ * An array or space separated string of node names of the elements to shiv.
182
+ * @memberOf html5
183
+ * @type Array|String
184
+ */
185
+ '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',
186
+
187
+ /**
188
+ * A flag to indicate that the HTML5 style sheet should be inserted.
189
+ * @memberOf html5
190
+ * @type Boolean
191
+ */
192
+ 'shivCSS': !(options.shivCSS === false),
193
+
194
+ /**
195
+ * A flag to indicate that the document's `createElement` and `createDocumentFragment`
196
+ * methods should be overwritten.
197
+ * @memberOf html5
198
+ * @type Boolean
199
+ */
200
+ 'shivMethods': !(options.shivMethods === false),
201
+
202
+ /**
203
+ * A string to describe the type of `html5` object ("default" or "default print").
204
+ * @memberOf html5
205
+ * @type String
206
+ */
207
+ 'type': 'default',
208
+
209
+ // shivs the document according to the specified `html5` object options
210
+ 'shivDocument': shivDocument
211
+ };
212
+
213
+ /*--------------------------------------------------------------------------*/
214
+
215
+ // expose html5
216
+ window.html5 = html5;
217
+
218
+ // shiv the document
219
+ shivDocument(document);
220
+
221
+ /*------------------------------- Print Shiv -------------------------------*/
222
+
223
+ /** Used to filter media types */
224
+ var reMedia = /^$|\b(?:all|print)\b/;
225
+
226
+ /** Used to namespace printable elements */
227
+ var shivNamespace = 'html5shiv';
228
+
229
+ /** Detect whether the browser supports shivable style sheets */
230
+ var supportsShivableSheets = !supportsUnknownElements && (function() {
231
+ // assign a false negative if unable to shiv
232
+ var docEl = document.documentElement;
233
+ return !(
234
+ typeof document.namespaces == 'undefined' ||
235
+ typeof document.parentWindow == 'undefined' ||
236
+ typeof docEl.applyElement == 'undefined' ||
237
+ typeof docEl.removeNode == 'undefined' ||
238
+ typeof window.attachEvent == 'undefined'
239
+ );
240
+ }());
241
+
242
+ /*--------------------------------------------------------------------------*/
243
+
244
+ /**
245
+ * Wraps all HTML5 elements in the given document with printable elements.
246
+ * (eg. the "header" element is wrapped with the "html5shiv:header" element)
247
+ * @private
248
+ * @param {Document} ownerDocument The document.
249
+ * @returns {Array} An array wrappers added.
250
+ */
251
+ function addWrappers(ownerDocument) {
252
+ var node,
253
+ nodes = ownerDocument.getElementsByTagName('*'),
254
+ index = nodes.length,
255
+ reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'),
256
+ result = [];
257
+
258
+ while (index--) {
259
+ node = nodes[index];
260
+ if (reElements.test(node.nodeName)) {
261
+ result.push(node.applyElement(createWrapper(node)));
262
+ }
263
+ }
264
+ return result;
265
+ }
266
+
267
+ /**
268
+ * Creates a printable wrapper for the given element.
269
+ * @private
270
+ * @param {Element} element The element.
271
+ * @returns {Element} The wrapper.
272
+ */
273
+ function createWrapper(element) {
274
+ var node,
275
+ nodes = element.attributes,
276
+ index = nodes.length,
277
+ wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName);
278
+
279
+ // copy element attributes to the wrapper
280
+ while (index--) {
281
+ node = nodes[index];
282
+ node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue);
283
+ }
284
+ // copy element styles to the wrapper
285
+ wrapper.style.cssText = element.style.cssText;
286
+ return wrapper;
287
+ }
288
+
289
+ /**
290
+ * Shivs the given CSS text.
291
+ * (eg. header{} becomes html5shiv\:header{})
292
+ * @private
293
+ * @param {String} cssText The CSS text to shiv.
294
+ * @returns {String} The shived CSS text.
295
+ */
296
+ function shivCssText(cssText) {
297
+ var pair,
298
+ parts = cssText.split('{'),
299
+ index = parts.length,
300
+ reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
301
+ replacement = '$1' + shivNamespace + '\\:$2';
302
+
303
+ while (index--) {
304
+ pair = parts[index] = parts[index].split('}');
305
+ pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
306
+ parts[index] = pair.join('}');
307
+ }
308
+ return parts.join('{');
309
+ }
310
+
311
+ /**
312
+ * Removes the given wrappers, leaving the original elements.
313
+ * @private
314
+ * @params {Array} wrappers An array of printable wrappers.
315
+ */
316
+ function removeWrappers(wrappers) {
317
+ var index = wrappers.length;
318
+ while (index--) {
319
+ wrappers[index].removeNode();
320
+ }
321
+ }
322
+
323
+ /*--------------------------------------------------------------------------*/
324
+
325
+ /**
326
+ * Shivs the given document for print.
327
+ * @memberOf html5
328
+ * @param {Document} ownerDocument The document to shiv.
329
+ * @returns {Document} The shived document.
330
+ */
331
+ function shivPrint(ownerDocument) {
332
+ var shivedSheet,
333
+ wrappers,
334
+ namespaces = ownerDocument.namespaces,
335
+ ownerWindow = ownerDocument.parentWindow;
336
+
337
+ if (!supportsShivableSheets || ownerDocument.printShived) {
338
+ return ownerDocument;
339
+ }
340
+ if (typeof namespaces[shivNamespace] == 'undefined') {
341
+ namespaces.add(shivNamespace);
342
+ }
343
+
344
+ ownerWindow.attachEvent('onbeforeprint', function() {
345
+ var imports,
346
+ length,
347
+ sheet,
348
+ collection = ownerDocument.styleSheets,
349
+ cssText = [],
350
+ index = collection.length,
351
+ sheets = Array(index);
352
+
353
+ // convert styleSheets collection to an array
354
+ while (index--) {
355
+ sheets[index] = collection[index];
356
+ }
357
+ // concat all style sheet CSS text
358
+ while ((sheet = sheets.pop())) {
359
+ // IE does not enforce a same origin policy for external style sheets...
360
+ // but has trouble with some dynamically created stylesheets
361
+ if (!sheet.disabled && reMedia.test(sheet.media)) {
362
+
363
+ try {
364
+ imports = sheet.imports;
365
+ length = imports.length;
366
+ } catch(er){
367
+ length = 0;
368
+ }
369
+
370
+ for (index = 0; index < length; index++) {
371
+ sheets.push(imports[index]);
372
+ }
373
+
374
+ try {
375
+ cssText.push(sheet.cssText);
376
+ } catch(er){}
377
+ }
378
+ }
379
+ // wrap all HTML5 elements with printable elements and add the shived style sheet
380
+ cssText = shivCssText(cssText.reverse().join(''));
381
+ wrappers = addWrappers(ownerDocument);
382
+ shivedSheet = addStyleSheet(ownerDocument, cssText);
383
+ });
384
+
385
+ ownerWindow.attachEvent('onafterprint', function() {
386
+ // remove wrappers, leaving the original elements, and remove the shived style sheet
387
+ removeWrappers(wrappers);
388
+ shivedSheet.removeNode(true);
389
+ });
390
+
391
+ ownerDocument.printShived = true;
392
+ return ownerDocument;
393
+ }
394
+
395
+ /*--------------------------------------------------------------------------*/
396
+
397
+ // expose API
398
+ html5.type += ' print';
399
+ html5.shivPrint = shivPrint;
400
+
401
+ // shiv for print
402
+ shivPrint(document);
403
+
404
+ }(this, document));