webfontloader 1.3.0 → 1.3.1

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.
Files changed (40) hide show
  1. data/CHANGELOG +5 -0
  2. data/Rakefile +2 -1
  3. data/lib/webfontloader.rb +1 -1
  4. data/spec/core/font_spec.js +9 -4
  5. data/spec/core/fontruler_spec.js +3 -10
  6. data/spec/core/fontwatcher_spec.js +22 -23
  7. data/spec/core/fontwatchrunner_spec.js +206 -231
  8. data/spec/deps.js +27 -0
  9. data/spec/google/lastresortwebkitfontwatchrunner_spec.js +47 -58
  10. data/spec/index.html +14 -25
  11. data/src/ascender/ascender_script.js +52 -45
  12. data/src/core/browserinfo.js +54 -47
  13. data/src/core/cssclassname.js +27 -22
  14. data/src/core/cssfontfamilyname.js +23 -17
  15. data/src/core/domhelper.js +209 -203
  16. data/src/core/eventdispatcher.js +111 -103
  17. data/src/core/font.js +110 -68
  18. data/src/core/fontmoduleloader.js +56 -13
  19. data/src/core/fontruler.js +52 -43
  20. data/src/core/fontvariationdescription.js +82 -76
  21. data/src/core/fontwatcher.js +93 -88
  22. data/src/core/fontwatchrunner.js +161 -161
  23. data/src/core/initialize.js +22 -15
  24. data/src/core/namespace.js +0 -29
  25. data/src/core/size.js +31 -25
  26. data/src/core/useragent.js +63 -48
  27. data/src/core/useragentparser.js +317 -306
  28. data/src/custom/customcss.js +31 -24
  29. data/src/fontdeck/fontdeck_script.js +46 -37
  30. data/src/google/fontapiparser.js +105 -97
  31. data/src/google/fontapiurlbuilder.js +46 -41
  32. data/src/google/googlefontapi.js +48 -32
  33. data/src/google/lastresortwebkitfontwatchrunner.js +80 -67
  34. data/src/modules.yml +6 -6
  35. data/src/monotype/monotype_script.js +47 -40
  36. data/src/typekit/typekit_script.js +41 -35
  37. data/tools/compiler/base.js +1548 -0
  38. data/tools/compiler/compiler.jar +0 -0
  39. data/webfontloader.gemspec +4 -2
  40. metadata +18 -16
@@ -1,3 +1,5 @@
1
+ goog.provide('webfont.CssClassName');
2
+
1
3
  /**
2
4
  * Handles sanitization and construction of css class names.
3
5
  * @param {string=} opt_joinChar The character to join parts of the name on.
@@ -15,27 +17,30 @@ webfont.CssClassName = function(opt_joinChar) {
15
17
  */
16
18
  webfont.CssClassName.DEFAULT_JOIN_CHAR = '-';
17
19
 
18
- /**
19
- * Sanitizes a string for use as a css class name. Removes non-word and
20
- * underscore characters.
21
- * @param {string} name The string.
22
- * @return {string} The sanitized string.
23
- */
24
- webfont.CssClassName.prototype.sanitize = function(name) {
25
- return name.replace(/[\W_]+/g, '').toLowerCase();
26
- };
20
+ goog.scope(function () {
21
+ var CssClassName = webfont.CssClassName;
27
22
 
28
- /**
29
- * Builds a complete css class name given a variable number of parts.
30
- * Sanitizes, then joins the parts together.
31
- * @param {...string} var_args The parts to join.
32
- * @return {string} The sanitized and joined string.
33
- */
34
- webfont.CssClassName.prototype.build = function(var_args) {
35
- var parts = []
36
- for (var i = 0; i < arguments.length; i++) {
37
- parts.push(this.sanitize(arguments[i]));
38
- }
39
- return parts.join(this.joinChar_);
40
- };
23
+ /**
24
+ * Sanitizes a string for use as a css class name. Removes non-word and
25
+ * underscore characters.
26
+ * @param {string} name The string.
27
+ * @return {string} The sanitized string.
28
+ */
29
+ CssClassName.prototype.sanitize = function(name) {
30
+ return name.replace(/[\W_]+/g, '').toLowerCase();
31
+ };
41
32
 
33
+ /**
34
+ * Builds a complete css class name given a variable number of parts.
35
+ * Sanitizes, then joins the parts together.
36
+ * @param {...string} var_args The parts to join.
37
+ * @return {string} The sanitized and joined string.
38
+ */
39
+ CssClassName.prototype.build = function(var_args) {
40
+ var parts = []
41
+ for (var i = 0; i < arguments.length; i++) {
42
+ parts.push(this.sanitize(arguments[i]));
43
+ }
44
+ return parts.join(this.joinChar_);
45
+ };
46
+ });
@@ -1,3 +1,5 @@
1
+ goog.provide('webfont.CssFontFamilyName');
2
+
1
3
  /**
2
4
  * Handles quoting rules for a font family name in css.
3
5
  * @constructor
@@ -7,21 +9,25 @@ webfont.CssFontFamilyName = function() {
7
9
  this.quote_ = "'";
8
10
  };
9
11
 
10
- /**
11
- * Quotes the name.
12
- * @param {string} name The name to quote.
13
- * @return {string} The quoted name.
14
- */
15
- webfont.CssFontFamilyName.prototype.quote = function(name) {
16
- var quoted = [];
17
- var split = name.split(/,\s*/);
18
- for (var i = 0; i < split.length; i++) {
19
- var part = split[i].replace(/['"]/g, '');
20
- if (part.indexOf(' ') == -1) {
21
- quoted.push(part);
22
- } else {
23
- quoted.push(this.quote_ + part + this.quote_);
12
+ goog.scope(function () {
13
+ var CssFontFamilyName = webfont.CssFontFamilyName;
14
+
15
+ /**
16
+ * Quotes the name.
17
+ * @param {string} name The name to quote.
18
+ * @return {string} The quoted name.
19
+ */
20
+ CssFontFamilyName.prototype.quote = function(name) {
21
+ var quoted = [];
22
+ var split = name.split(/,\s*/);
23
+ for (var i = 0; i < split.length; i++) {
24
+ var part = split[i].replace(/['"]/g, '');
25
+ if (part.indexOf(' ') == -1) {
26
+ quoted.push(part);
27
+ } else {
28
+ quoted.push(this.quote_ + part + this.quote_);
29
+ }
24
30
  }
25
- }
26
- return quoted.join(',');
27
- };
31
+ return quoted.join(',');
32
+ };
33
+ });
@@ -1,3 +1,5 @@
1
+ goog.provide('webfont.DomHelper');
2
+
1
3
  /**
2
4
  * Handles common DOM manipulation tasks. The aim of this library is to cover
3
5
  * the needs of typical font loading. Not more, not less.
@@ -17,215 +19,219 @@ webfont.DomHelper = function(mainWindow, opt_loadWindow) {
17
19
  this.supportForStyle_ = undefined;
18
20
  };
19
21
 
20
- /**
21
- * Creates an element.
22
- * @param {string} elem The element type.
23
- * @param {Object=} opt_attr A hash of attribute key/value pairs.
24
- * @param {string=} opt_innerHtml Contents of the element.
25
- * @return {Element} the new element.
26
- */
27
- webfont.DomHelper.prototype.createElement = function(elem, opt_attr,
28
- opt_innerHtml) {
29
- var domElement = this.document_.createElement(elem);
30
-
31
- if (opt_attr) {
32
- for (var attr in opt_attr) {
33
- // protect against native prototype augmentations
34
- if (opt_attr.hasOwnProperty(attr)) {
35
- if (attr == "style") {
36
- this.setStyle(domElement, opt_attr[attr]);
37
- } else {
38
- domElement.setAttribute(attr, opt_attr[attr]);
22
+ goog.scope(function () {
23
+ var DomHelper = webfont.DomHelper;
24
+
25
+ /**
26
+ * Creates an element.
27
+ * @param {string} elem The element type.
28
+ * @param {Object=} opt_attr A hash of attribute key/value pairs.
29
+ * @param {string=} opt_innerHtml Contents of the element.
30
+ * @return {Element} the new element.
31
+ */
32
+ DomHelper.prototype.createElement = function(elem, opt_attr,
33
+ opt_innerHtml) {
34
+ var domElement = this.document_.createElement(elem);
35
+
36
+ if (opt_attr) {
37
+ for (var attr in opt_attr) {
38
+ // protect against native prototype augmentations
39
+ if (opt_attr.hasOwnProperty(attr)) {
40
+ if (attr == "style") {
41
+ this.setStyle(domElement, opt_attr[attr]);
42
+ } else {
43
+ domElement.setAttribute(attr, opt_attr[attr]);
44
+ }
39
45
  }
40
46
  }
41
47
  }
42
- }
43
- if (opt_innerHtml) {
44
- domElement.appendChild(this.document_.createTextNode(opt_innerHtml));
45
- }
46
- return domElement;
47
- };
48
-
49
- /**
50
- * Inserts an element into the document. This is intended for unambiguous
51
- * elements such as html, body, head.
52
- * @param {string} tagName The element name.
53
- * @param {Element} e The element to append.
54
- * @return {boolean} True if the element was inserted.
55
- */
56
- webfont.DomHelper.prototype.insertInto = function(tagName, e) {
57
- var t = this.document_.getElementsByTagName(tagName)[0];
58
-
59
- if (!t) { // opera allows documents without a head
60
- t = document.documentElement;
61
- }
62
-
63
- if (t && t.lastChild) {
64
- // This is safer than appendChild in IE. appendChild causes random
65
- // JS errors in IE. Sometimes errors in other JS exectution, sometimes
66
- // complete 'This page cannot be displayed' errors. For our purposes,
67
- // it's equivalent because we don't need to insert at any specific
68
- // location.
69
- t.insertBefore(e, t.lastChild);
70
- return true;
71
- }
72
- return false;
73
- };
74
-
75
- /**
76
- * Calls a function when the body tag exists.
77
- * @param {function()} callback The function to call.
78
- */
79
- webfont.DomHelper.prototype.whenBodyExists = function(callback) {
80
- var check = function() {
81
- if (document.body) {
82
- callback();
83
- } else {
84
- setTimeout(check, 0);
48
+ if (opt_innerHtml) {
49
+ domElement.appendChild(this.document_.createTextNode(opt_innerHtml));
85
50
  }
86
- }
87
- check();
88
- };
89
-
90
- /**
91
- * Removes an element from the DOM.
92
- * @param {Element} node The element to remove.
93
- * @return {boolean} True if the element was removed.
94
- */
95
- webfont.DomHelper.prototype.removeElement = function(node) {
96
- if (node.parentNode) {
97
- node.parentNode.removeChild(node);
98
- return true;
99
- }
100
- return false;
101
- };
102
-
103
- /**
104
- * Creates a link to a CSS document.
105
- * @param {string} src The URL of the stylesheet.
106
- * @return {Element} a link element.
107
- */
108
- webfont.DomHelper.prototype.createCssLink = function(src) {
109
- return this.createElement('link', {
110
- 'rel': 'stylesheet',
111
- 'href': src
112
- });
113
- };
114
-
115
- /**
116
- * Creates a link to a javascript document.
117
- * @param {string} src The URL of the script.
118
- * @return {Element} a script element.
119
- */
120
- webfont.DomHelper.prototype.createScriptSrc = function(src) {
121
- return this.createElement('script', {
122
- 'src': src
123
- });
124
- };
125
-
126
- /**
127
- * Appends a name to an element's class attribute.
128
- * @param {Element} e The element.
129
- * @param {string} name The class name to add.
130
- */
131
- webfont.DomHelper.prototype.appendClassName = function(e, name) {
132
- var classes = e.className.split(/\s+/);
133
- for (var i = 0, len = classes.length; i < len; i++) {
134
- if (classes[i] == name) {
135
- return;
51
+ return domElement;
52
+ };
53
+
54
+ /**
55
+ * Inserts an element into the document. This is intended for unambiguous
56
+ * elements such as html, body, head.
57
+ * @param {string} tagName The element name.
58
+ * @param {Element} e The element to append.
59
+ * @return {boolean} True if the element was inserted.
60
+ */
61
+ DomHelper.prototype.insertInto = function(tagName, e) {
62
+ var t = this.document_.getElementsByTagName(tagName)[0];
63
+
64
+ if (!t) { // opera allows documents without a head
65
+ t = document.documentElement;
136
66
  }
137
- }
138
- classes.push(name);
139
- e.className = classes.join(' ')
140
- .replace(/\s+/g, ' ')
141
- .replace(/^\s+|\s+$/, '');
142
- };
143
67
 
144
- /**
145
- * Removes a name to an element's class attribute.
146
- * @param {Element} e The element.
147
- * @param {string} name The class name to remove.
148
- */
149
- webfont.DomHelper.prototype.removeClassName = function(e, name) {
150
- var classes = e.className.split(/\s+/);
151
- var remainingClasses = [];
152
- for (var i = 0, len = classes.length; i < len; i++) {
153
- if (classes[i] != name) {
154
- remainingClasses.push(classes[i]);
68
+ if (t && t.lastChild) {
69
+ // This is safer than appendChild in IE. appendChild causes random
70
+ // JS errors in IE. Sometimes errors in other JS exectution, sometimes
71
+ // complete 'This page cannot be displayed' errors. For our purposes,
72
+ // it's equivalent because we don't need to insert at any specific
73
+ // location.
74
+ t.insertBefore(e, t.lastChild);
75
+ return true;
155
76
  }
156
- }
157
- e.className = remainingClasses.join(' ')
158
- .replace(/\s+/g, ' ')
159
- .replace(/^\s+|\s+$/, '');
160
- };
161
-
162
- /**
163
- * Returns true if an element has a given class name and false otherwise.
164
- * @param {Element} e The element.
165
- * @param {string} name The class name to check for.
166
- * @return {boolean} Whether or not the element has this class name.
167
- */
168
- webfont.DomHelper.prototype.hasClassName = function(e, name) {
169
- var classes = e.className.split(/\s+/);
170
- for (var i = 0, len = classes.length; i < len; i++) {
171
- if (classes[i] == name) {
77
+ return false;
78
+ };
79
+
80
+ /**
81
+ * Calls a function when the body tag exists.
82
+ * @param {function()} callback The function to call.
83
+ */
84
+ DomHelper.prototype.whenBodyExists = function(callback) {
85
+ var check = function() {
86
+ if (document.body) {
87
+ callback();
88
+ } else {
89
+ setTimeout(check, 0);
90
+ }
91
+ }
92
+ check();
93
+ };
94
+
95
+ /**
96
+ * Removes an element from the DOM.
97
+ * @param {Element} node The element to remove.
98
+ * @return {boolean} True if the element was removed.
99
+ */
100
+ DomHelper.prototype.removeElement = function(node) {
101
+ if (node.parentNode) {
102
+ node.parentNode.removeChild(node);
172
103
  return true;
173
104
  }
174
- }
175
- return false;
176
- };
177
-
178
- /**
179
- * Sets the style attribute on an element.
180
- * @param {Element} e The element.
181
- * @param {string} styleString The style string.
182
- */
183
- webfont.DomHelper.prototype.setStyle = function(e, styleString) {
184
- if (this.hasSupportForStyle_()) {
185
- e.setAttribute("style", styleString);
186
- } else {
187
- e.style.cssText = styleString;
188
- }
189
- };
190
-
191
- /**
192
- * Check if getting and setting the style attribute on an element with
193
- * getAttribute/setAttribute is supported. In old IE, you must use style.cssText
194
- * instead. Feature detection is only done the first time this is called.
195
- * @private
196
- * @return {boolean} Whether or not the feature is supported.
197
- */
198
- webfont.DomHelper.prototype.hasSupportForStyle_ = function() {
199
- if (this.supportForStyle_ === undefined) {
200
- var e = this.document_.createElement('p');
201
- e.innerHTML = '<a style="top:1px;">w</a>';
202
- this.supportForStyle_ = /top/.test(e.getElementsByTagName('a')[0].getAttribute('style'));
203
- }
204
- return this.supportForStyle_
205
- };
206
-
207
- /**
208
- * @return {Window} The main window webfontloader.js is loaded in (for config).
209
- */
210
- webfont.DomHelper.prototype.getMainWindow = function() {
211
- return this.mainWindow_;
212
- };
213
-
214
- /**
215
- * @return {Window} The window that we're loading the font(s) into.
216
- */
217
- webfont.DomHelper.prototype.getLoadWindow = function() {
218
- return this.loadWindow_;
219
- };
220
-
221
- /**
222
- * @return {string} The protocol (http: or https:) to request resources in.
223
- */
224
- webfont.DomHelper.prototype.getProtocol = function() {
225
- var protocol = this.loadWindow_.location.protocol;
226
- // For empty iframes, fallback to main window's protocol.
227
- if (protocol == 'about:') {
228
- protocol = this.mainWindow_.location.protocol;
229
- }
230
- return protocol == 'https:' ? 'https:' : 'http:';
231
- };
105
+ return false;
106
+ };
107
+
108
+ /**
109
+ * Creates a link to a CSS document.
110
+ * @param {string} src The URL of the stylesheet.
111
+ * @return {Element} a link element.
112
+ */
113
+ DomHelper.prototype.createCssLink = function(src) {
114
+ return this.createElement('link', {
115
+ 'rel': 'stylesheet',
116
+ 'href': src
117
+ });
118
+ };
119
+
120
+ /**
121
+ * Creates a link to a javascript document.
122
+ * @param {string} src The URL of the script.
123
+ * @return {Element} a script element.
124
+ */
125
+ DomHelper.prototype.createScriptSrc = function(src) {
126
+ return this.createElement('script', {
127
+ 'src': src
128
+ });
129
+ };
130
+
131
+ /**
132
+ * Appends a name to an element's class attribute.
133
+ * @param {Element} e The element.
134
+ * @param {string} name The class name to add.
135
+ */
136
+ DomHelper.prototype.appendClassName = function(e, name) {
137
+ var classes = e.className.split(/\s+/);
138
+ for (var i = 0, len = classes.length; i < len; i++) {
139
+ if (classes[i] == name) {
140
+ return;
141
+ }
142
+ }
143
+ classes.push(name);
144
+ e.className = classes.join(' ')
145
+ .replace(/\s+/g, ' ')
146
+ .replace(/^\s+|\s+$/, '');
147
+ };
148
+
149
+ /**
150
+ * Removes a name to an element's class attribute.
151
+ * @param {Element} e The element.
152
+ * @param {string} name The class name to remove.
153
+ */
154
+ DomHelper.prototype.removeClassName = function(e, name) {
155
+ var classes = e.className.split(/\s+/);
156
+ var remainingClasses = [];
157
+ for (var i = 0, len = classes.length; i < len; i++) {
158
+ if (classes[i] != name) {
159
+ remainingClasses.push(classes[i]);
160
+ }
161
+ }
162
+ e.className = remainingClasses.join(' ')
163
+ .replace(/\s+/g, ' ')
164
+ .replace(/^\s+|\s+$/, '');
165
+ };
166
+
167
+ /**
168
+ * Returns true if an element has a given class name and false otherwise.
169
+ * @param {Element} e The element.
170
+ * @param {string} name The class name to check for.
171
+ * @return {boolean} Whether or not the element has this class name.
172
+ */
173
+ DomHelper.prototype.hasClassName = function(e, name) {
174
+ var classes = e.className.split(/\s+/);
175
+ for (var i = 0, len = classes.length; i < len; i++) {
176
+ if (classes[i] == name) {
177
+ return true;
178
+ }
179
+ }
180
+ return false;
181
+ };
182
+
183
+ /**
184
+ * Sets the style attribute on an element.
185
+ * @param {Element} e The element.
186
+ * @param {string} styleString The style string.
187
+ */
188
+ DomHelper.prototype.setStyle = function(e, styleString) {
189
+ if (this.hasSupportForStyle_()) {
190
+ e.setAttribute("style", styleString);
191
+ } else {
192
+ e.style.cssText = styleString;
193
+ }
194
+ };
195
+
196
+ /**
197
+ * Check if getting and setting the style attribute on an element with
198
+ * getAttribute/setAttribute is supported. In old IE, you must use style.cssText
199
+ * instead. Feature detection is only done the first time this is called.
200
+ * @private
201
+ * @return {boolean} Whether or not the feature is supported.
202
+ */
203
+ DomHelper.prototype.hasSupportForStyle_ = function() {
204
+ if (this.supportForStyle_ === undefined) {
205
+ var e = this.document_.createElement('p');
206
+ e.innerHTML = '<a style="top:1px;">w</a>';
207
+ this.supportForStyle_ = /top/.test(e.getElementsByTagName('a')[0].getAttribute('style'));
208
+ }
209
+ return this.supportForStyle_
210
+ };
211
+
212
+ /**
213
+ * @return {Window} The main window webfontloader.js is loaded in (for config).
214
+ */
215
+ DomHelper.prototype.getMainWindow = function() {
216
+ return this.mainWindow_;
217
+ };
218
+
219
+ /**
220
+ * @return {Window} The window that we're loading the font(s) into.
221
+ */
222
+ DomHelper.prototype.getLoadWindow = function() {
223
+ return this.loadWindow_;
224
+ };
225
+
226
+ /**
227
+ * @return {string} The protocol (http: or https:) to request resources in.
228
+ */
229
+ DomHelper.prototype.getProtocol = function() {
230
+ var protocol = this.loadWindow_.location.protocol;
231
+ // For empty iframes, fallback to main window's protocol.
232
+ if (protocol == 'about:') {
233
+ protocol = this.mainWindow_.location.protocol;
234
+ }
235
+ return protocol == 'https:' ? 'https:' : 'http:';
236
+ };
237
+ });