ie-compat 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +2 -0
- data/assets/ie-compat/9.js +3 -0
- data/assets/ie-compat/array_foreach.js +58 -0
- data/assets/ie-compat/console.js +20 -0
- data/assets/ie-compat/function_bind.js +25 -0
- data/assets/ie-compat/lt-9.js +4 -0
- data/assets/ie-compat/vendor/html5shiv-printshiv.js +404 -0
- data/assets/ie-compat/vendor/html5shiv.js +220 -0
- data/assets/ie-compat/vendor/json2.js +486 -0
- data/assets/ie-compat/vendor/selectivizr-min.js +5 -0
- data/ie-compat.gemspec +23 -0
- data/lib/ie/compat.rb +6 -0
- data/lib/ie/compat/active_admin.rb +22 -0
- data/lib/ie/compat/assets_path.rb +13 -0
- data/lib/ie/compat/opal.rb +3 -0
- data/lib/ie/compat/railtie.rb +19 -0
- data/lib/ie/compat/sprockets.rb +3 -0
- data/lib/ie/compat/version.rb +5 -0
- data/lib/ie/compat/view_helper.rb +12 -0
- metadata +96 -0
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
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
|
+

|
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,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,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));
|