ie-compat 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![⚠️ 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,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));
|