webfontloader 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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,11 +1,12 @@
1
+ goog.provide('webfont.FontWatchRunner');
2
+
3
+ goog.require('webfont.FontRuler');
4
+
1
5
  /**
2
6
  * @constructor
3
7
  * @param {function(string, string)} activeCallback
4
8
  * @param {function(string, string)} inactiveCallback
5
9
  * @param {webfont.DomHelper} domHelper
6
- * @param {Object.<string, function(Object): webfont.Size>} fontSizer
7
- * @param {function(function(), number=)} asyncCall
8
- * @param {function(): number} getTime
9
10
  * @param {string} fontFamily
10
11
  * @param {string} fontDescription
11
12
  * @param {webfont.BrowserInfo} browserInfo
@@ -14,14 +15,10 @@
14
15
  * @param {string=} opt_fontTestString
15
16
  */
16
17
  webfont.FontWatchRunner = function(activeCallback, inactiveCallback, domHelper,
17
- fontSizer, asyncCall, getTime, fontFamily, fontDescription, browserInfo,
18
- opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
18
+ fontFamily, fontDescription, browserInfo, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
19
19
  this.activeCallback_ = activeCallback;
20
20
  this.inactiveCallback_ = inactiveCallback;
21
21
  this.domHelper_ = domHelper;
22
- this.fontSizer_ = fontSizer;
23
- this.asyncCall_ = asyncCall;
24
- this.getTime_ = getTime;
25
22
  this.fontFamily_ = fontFamily;
26
23
  this.fontDescription_ = fontDescription;
27
24
  this.fontTestString_ = opt_fontTestString || webfont.FontWatchRunner.DEFAULT_TEST_STRING;
@@ -65,164 +62,167 @@ webfont.FontWatchRunner.LastResortFonts = {
65
62
  */
66
63
  webfont.FontWatchRunner.DEFAULT_TEST_STRING = 'BESbswy';
67
64
 
68
- /**
69
- * @private
70
- */
71
- webfont.FontWatchRunner.prototype.setupLastResortSizes_ = function() {
72
- var fontRuler = new webfont.FontRuler(this.domHelper_, this.fontSizer_, this.fontTestString_);
65
+ goog.scope(function () {
66
+ var FontWatchRunner = webfont.FontWatchRunner,
67
+ FontRuler = webfont.FontRuler;
73
68
 
74
- fontRuler.insert();
75
-
76
- for (var font in webfont.FontWatchRunner.LastResortFonts) {
77
- if (webfont.FontWatchRunner.LastResortFonts.hasOwnProperty(font)) {
78
- fontRuler.setFont(webfont.FontWatchRunner.LastResortFonts[font], this.fontDescription_);
79
- this.lastResortSizes_[webfont.FontWatchRunner.LastResortFonts[font]] = fontRuler.getSize();
80
- }
81
- }
82
- fontRuler.remove();
83
- };
69
+ /**
70
+ * @private
71
+ */
72
+ FontWatchRunner.prototype.setupLastResortSizes_ = function() {
73
+ var fontRuler = new FontRuler(this.domHelper_, this.fontTestString_);
84
74
 
85
- webfont.FontWatchRunner.prototype.start = function() {
86
- this.fontRulerA_ = new webfont.FontRuler(this.domHelper_, this.fontSizer_, this.fontTestString_);
87
- this.fontRulerA_.insert();
88
- this.fontRulerB_ = new webfont.FontRuler(this.domHelper_, this.fontSizer_, this.fontTestString_);
89
- this.fontRulerB_.insert();
90
-
91
- this.started_ = this.getTime_();
92
-
93
- this.fontRulerA_.setFont(this.fontFamily_ + ',' + webfont.FontWatchRunner.LastResortFonts.SERIF, this.fontDescription_);
94
- this.fontRulerB_.setFont(this.fontFamily_ + ',' + webfont.FontWatchRunner.LastResortFonts.SANS_SERIF, this.fontDescription_);
95
-
96
- this.check_();
97
- };
98
-
99
- /**
100
- * Returns true if the given size matches the generic font family size.
101
- *
102
- * @private
103
- * @param {?webfont.Size} size
104
- * @param {string} lastResortFont
105
- * @return {boolean}
106
- */
107
- webfont.FontWatchRunner.prototype.sizeMatches_ = function(size, lastResortFont) {
108
- if (this.browserInfo_.hasWebKitMetricsBug()) {
109
- return size.equalsWidth(this.lastResortSizes_[lastResortFont]);
110
- } else {
111
- return size.equals(this.lastResortSizes_[lastResortFont]);
112
- }
113
- };
75
+ fontRuler.insert();
114
76
 
115
- /**
116
- * Return true if the given sizes match any of the generic font family
117
- * sizes.
118
- *
119
- * @private
120
- * @param {?webfont.Size} a
121
- * @param {?webfont.Size} b
122
- * @return {boolean}
123
- */
124
- webfont.FontWatchRunner.prototype.sizesMatchLastResortSizes_ = function(a, b) {
125
- for (var font in webfont.FontWatchRunner.LastResortFonts) {
126
- if (webfont.FontWatchRunner.LastResortFonts.hasOwnProperty(font)) {
127
- if (this.sizeMatches_(a, webfont.FontWatchRunner.LastResortFonts[font]) &&
128
- this.sizeMatches_(b, webfont.FontWatchRunner.LastResortFonts[font])) {
129
- return true;
77
+ for (var font in FontWatchRunner.LastResortFonts) {
78
+ if (FontWatchRunner.LastResortFonts.hasOwnProperty(font)) {
79
+ fontRuler.setFont(FontWatchRunner.LastResortFonts[font], this.fontDescription_);
80
+ this.lastResortSizes_[FontWatchRunner.LastResortFonts[font]] = fontRuler.getSize();
130
81
  }
131
82
  }
132
- }
133
- return false;
134
- };
135
-
136
- /**
137
- * @private
138
- * Returns true if the loading has timed out.
139
- * @return {boolean}
140
- */
141
- webfont.FontWatchRunner.prototype.hasTimedOut_ = function() {
142
- return this.getTime_() - this.started_ >= this.timeout_;
143
- };
144
-
145
- /**
146
- * Returns true if both fonts match the normal fallback fonts.
147
- *
148
- * @private
149
- * @param {webfont.Size} sizeA
150
- * @param {webfont.Size} sizeB
151
- * @return {boolean}
152
- */
153
- webfont.FontWatchRunner.prototype.isFallbackFont_ = function (sizeA, sizeB) {
154
- return this.sizeMatches_(sizeA, webfont.FontWatchRunner.LastResortFonts.SERIF) &&
155
- this.sizeMatches_(sizeB, webfont.FontWatchRunner.LastResortFonts.SANS_SERIF);
156
- };
157
-
158
- /**
159
- * Returns true if the WebKit bug is present and both sizes match a last resort font.
160
- *
161
- * @private
162
- * @param {webfont.Size} sizeA
163
- * @param {webfont.Size} sizeB
164
- * @return {boolean}
165
- */
166
- webfont.FontWatchRunner.prototype.isLastResortFont_ = function (sizeA, sizeB) {
167
- return this.browserInfo_.hasWebKitFallbackBug() && this.sizesMatchLastResortSizes_(sizeA, sizeB);
168
- };
169
-
170
- /**
171
- * Returns true if the current font is metric compatible. Also returns true
172
- * if we do not have a list of metric compatible fonts.
173
- *
174
- * @private
175
- * @return {boolean}
176
- */
177
- webfont.FontWatchRunner.prototype.isMetricCompatibleFont_ = function () {
178
- return this.metricCompatibleFonts_ === null || this.metricCompatibleFonts_.hasOwnProperty(this.fontFamily_);
179
- };
180
-
181
- /**
182
- * Checks the size of the two spans against their original sizes during each
183
- * async loop. If the size of one of the spans is different than the original
184
- * size, then we know that the font is rendering and finish with the active
185
- * callback. If we wait more than 5 seconds and nothing has changed, we finish
186
- * with the inactive callback.
187
- *
188
- * @private
189
- */
190
- webfont.FontWatchRunner.prototype.check_ = function() {
191
- var sizeA = this.fontRulerA_.getSize();
192
- var sizeB = this.fontRulerB_.getSize();
193
-
194
- if (this.isFallbackFont_(sizeA, sizeB) || this.isLastResortFont_(sizeA, sizeB)) {
195
- if (this.hasTimedOut_()) {
196
- if (this.isLastResortFont_(sizeA, sizeB) && this.isMetricCompatibleFont_()) {
197
- this.finish_(this.activeCallback_);
198
- } else {
199
- this.finish_(this.inactiveCallback_);
200
- }
83
+ fontRuler.remove();
84
+ };
85
+
86
+ FontWatchRunner.prototype.start = function() {
87
+ this.fontRulerA_ = new FontRuler(this.domHelper_, this.fontTestString_);
88
+ this.fontRulerA_.insert();
89
+ this.fontRulerB_ = new FontRuler(this.domHelper_, this.fontTestString_);
90
+ this.fontRulerB_.insert();
91
+
92
+ this.started_ = goog.now();
93
+
94
+ this.fontRulerA_.setFont(this.fontFamily_ + ',' + FontWatchRunner.LastResortFonts.SERIF, this.fontDescription_);
95
+ this.fontRulerB_.setFont(this.fontFamily_ + ',' + FontWatchRunner.LastResortFonts.SANS_SERIF, this.fontDescription_);
96
+
97
+ this.check_();
98
+ };
99
+
100
+ /**
101
+ * Returns true if the given size matches the generic font family size.
102
+ *
103
+ * @private
104
+ * @param {?webfont.Size} size
105
+ * @param {string} lastResortFont
106
+ * @return {boolean}
107
+ */
108
+ FontWatchRunner.prototype.sizeMatches_ = function(size, lastResortFont) {
109
+ if (this.browserInfo_.hasWebKitMetricsBug()) {
110
+ return size.equalsWidth(this.lastResortSizes_[lastResortFont]);
201
111
  } else {
202
- this.asyncCheck_();
112
+ return size.equals(this.lastResortSizes_[lastResortFont]);
203
113
  }
204
- } else {
205
- this.finish_(this.activeCallback_);
206
- }
207
- };
208
-
209
- /**
210
- * @private
211
- */
212
- webfont.FontWatchRunner.prototype.asyncCheck_ = function() {
213
- this.asyncCall_(function(context, func) {
214
- return function() {
215
- func.call(context);
114
+ };
115
+
116
+ /**
117
+ * Return true if the given sizes match any of the generic font family
118
+ * sizes.
119
+ *
120
+ * @private
121
+ * @param {?webfont.Size} a
122
+ * @param {?webfont.Size} b
123
+ * @return {boolean}
124
+ */
125
+ FontWatchRunner.prototype.sizesMatchLastResortSizes_ = function(a, b) {
126
+ for (var font in FontWatchRunner.LastResortFonts) {
127
+ if (FontWatchRunner.LastResortFonts.hasOwnProperty(font)) {
128
+ if (this.sizeMatches_(a, FontWatchRunner.LastResortFonts[font]) &&
129
+ this.sizeMatches_(b, FontWatchRunner.LastResortFonts[font])) {
130
+ return true;
131
+ }
132
+ }
216
133
  }
217
- }(this, this.check_), 25);
218
- };
219
-
220
- /**
221
- * @private
222
- * @param {function(string, string)} callback
223
- */
224
- webfont.FontWatchRunner.prototype.finish_ = function(callback) {
225
- this.fontRulerA_.remove();
226
- this.fontRulerB_.remove();
227
- callback(this.fontFamily_, this.fontDescription_);
228
- };
134
+ return false;
135
+ };
136
+
137
+ /**
138
+ * @private
139
+ * Returns true if the loading has timed out.
140
+ * @return {boolean}
141
+ */
142
+ FontWatchRunner.prototype.hasTimedOut_ = function() {
143
+ return goog.now() - this.started_ >= this.timeout_;
144
+ };
145
+
146
+ /**
147
+ * Returns true if both fonts match the normal fallback fonts.
148
+ *
149
+ * @private
150
+ * @param {webfont.Size} sizeA
151
+ * @param {webfont.Size} sizeB
152
+ * @return {boolean}
153
+ */
154
+ FontWatchRunner.prototype.isFallbackFont_ = function (sizeA, sizeB) {
155
+ return this.sizeMatches_(sizeA, FontWatchRunner.LastResortFonts.SERIF) &&
156
+ this.sizeMatches_(sizeB, FontWatchRunner.LastResortFonts.SANS_SERIF);
157
+ };
158
+
159
+ /**
160
+ * Returns true if the WebKit bug is present and both sizes match a last resort font.
161
+ *
162
+ * @private
163
+ * @param {webfont.Size} sizeA
164
+ * @param {webfont.Size} sizeB
165
+ * @return {boolean}
166
+ */
167
+ FontWatchRunner.prototype.isLastResortFont_ = function (sizeA, sizeB) {
168
+ return this.browserInfo_.hasWebKitFallbackBug() && this.sizesMatchLastResortSizes_(sizeA, sizeB);
169
+ };
170
+
171
+ /**
172
+ * Returns true if the current font is metric compatible. Also returns true
173
+ * if we do not have a list of metric compatible fonts.
174
+ *
175
+ * @private
176
+ * @return {boolean}
177
+ */
178
+ FontWatchRunner.prototype.isMetricCompatibleFont_ = function () {
179
+ return this.metricCompatibleFonts_ === null || this.metricCompatibleFonts_.hasOwnProperty(this.fontFamily_);
180
+ };
181
+
182
+ /**
183
+ * Checks the size of the two spans against their original sizes during each
184
+ * async loop. If the size of one of the spans is different than the original
185
+ * size, then we know that the font is rendering and finish with the active
186
+ * callback. If we wait more than 5 seconds and nothing has changed, we finish
187
+ * with the inactive callback.
188
+ *
189
+ * @private
190
+ */
191
+ FontWatchRunner.prototype.check_ = function() {
192
+ var sizeA = this.fontRulerA_.getSize();
193
+ var sizeB = this.fontRulerB_.getSize();
194
+
195
+ if (this.isFallbackFont_(sizeA, sizeB) || this.isLastResortFont_(sizeA, sizeB)) {
196
+ if (this.hasTimedOut_()) {
197
+ if (this.isLastResortFont_(sizeA, sizeB) && this.isMetricCompatibleFont_()) {
198
+ this.finish_(this.activeCallback_);
199
+ } else {
200
+ this.finish_(this.inactiveCallback_);
201
+ }
202
+ } else {
203
+ this.asyncCheck_();
204
+ }
205
+ } else {
206
+ this.finish_(this.activeCallback_);
207
+ }
208
+ };
209
+
210
+ /**
211
+ * @private
212
+ */
213
+ FontWatchRunner.prototype.asyncCheck_ = function() {
214
+ setTimeout(goog.bind(function () {
215
+ this.check_();
216
+ }, this), 25);
217
+ };
218
+
219
+ /**
220
+ * @private
221
+ * @param {function(string, string)} callback
222
+ */
223
+ FontWatchRunner.prototype.finish_ = function(callback) {
224
+ this.fontRulerA_.remove();
225
+ this.fontRulerB_.remove();
226
+ callback(this.fontFamily_, this.fontDescription_);
227
+ };
228
+ });
@@ -1,3 +1,24 @@
1
+ goog.provide('webfont');
2
+
3
+ goog.require('webfont.UserAgentParser');
4
+ goog.require('webfont.FontModuleLoader');
5
+ goog.require('webfont.WebFont');
6
+
7
+ /**
8
+ * @typedef {Array.<string>}
9
+ */
10
+ webfont.FontFamilies;
11
+
12
+ /**
13
+ * @typedef {Object.<string, Array.<string>>}
14
+ */
15
+ webfont.FontVariations;
16
+
17
+ /**
18
+ * @typedef {Object.<string, Array.<string>>}
19
+ */
20
+ webfont.FontTestStrings;
21
+
1
22
  // Name of the global object.
2
23
  var globalName = 'WebFont';
3
24
 
@@ -6,23 +27,9 @@ var globalNamespaceObject = window[globalName] = (function() {
6
27
  var userAgentParser = new webfont.UserAgentParser(navigator.userAgent, document);
7
28
  var userAgent = userAgentParser.parse();
8
29
  var fontModuleLoader = new webfont.FontModuleLoader();
9
- var asyncCall = function(func, timeout) { setTimeout(func, timeout); };
10
-
11
- return new webfont.WebFont(window, fontModuleLoader, asyncCall, userAgent);
30
+ return new webfont.WebFont(window, fontModuleLoader, userAgent);
12
31
  })();
13
32
 
14
33
  // Export the public API.
15
34
  globalNamespaceObject['load'] = globalNamespaceObject.load;
16
35
  globalNamespaceObject['addModule'] = globalNamespaceObject.addModule;
17
-
18
- // Export the UserAgent API because we pass this object to external modules.
19
- webfont.UserAgent.prototype['getName'] = webfont.UserAgent.prototype.getName;
20
- webfont.UserAgent.prototype['getVersion'] = webfont.UserAgent.prototype.getVersion;
21
- webfont.UserAgent.prototype['getEngine'] = webfont.UserAgent.prototype.getEngine;
22
- webfont.UserAgent.prototype['getEngineVersion'] = webfont.UserAgent.prototype.getEngineVersion;
23
- webfont.UserAgent.prototype['getPlatform'] = webfont.UserAgent.prototype.getPlatform;
24
- webfont.UserAgent.prototype['getPlatformVersion'] = webfont.UserAgent.prototype.getPlatformVersion;
25
- webfont.UserAgent.prototype['getDocumentMode'] = webfont.UserAgent.prototype.getDocumentMode;
26
- webfont.UserAgent.prototype['getBrowserInfo'] = webfont.UserAgent.prototype.getBrowserInfo;
27
- webfont.BrowserInfo.prototype['hasWebFontSupport'] = webfont.BrowserInfo.prototype.hasWebFontSupport;
28
- webfont.BrowserInfo.prototype['hasWebKitFallbackBug'] = webfont.BrowserInfo.prototype.hasWebKitFallbackBug;
@@ -1,30 +1 @@
1
1
  var webfont = {};
2
-
3
- /**
4
- * @param {Object} context
5
- * @param {function(...)} func
6
- * @param {...*} opt_args
7
- */
8
- webfont.bind = function(context, func, opt_args) {
9
- var args = arguments.length > 2 ?
10
- Array.prototype.slice.call(arguments, 2) : [];
11
-
12
- return function() {
13
- args.push.apply(args, arguments);
14
- return func.apply(context, args);
15
- };
16
- };
17
-
18
- webfont.extendsClass = function(baseClass, subClass) {
19
-
20
- // Avoid polluting the baseClass prototype object with methods from the
21
- // subClass
22
- /** @constructor */
23
- function baseExtendClass() {};
24
- baseExtendClass.prototype = baseClass.prototype;
25
- subClass.prototype = new baseExtendClass();
26
-
27
- subClass.prototype.constructor = subClass;
28
- subClass.superCtor_ = baseClass;
29
- subClass.super_ = baseClass.prototype;
30
- };
data/src/core/size.js CHANGED
@@ -1,3 +1,5 @@
1
+ goog.provide('webfont.Size');
2
+
1
3
  /**
2
4
  * @constructor
3
5
  * @param {number} width
@@ -8,30 +10,34 @@ webfont.Size = function (width, height) {
8
10
  this.height = height;
9
11
  };
10
12
 
11
- /**
12
- * Returns true if this size equals other.
13
- *
14
- * @param {webfont.Size} other
15
- * @return {boolean}
16
- */
17
- webfont.Size.prototype.equals = function (other) {
18
- return this.equalsWidth(other) && this.equalsHeight(other);
19
- };
13
+ goog.scope(function () {
14
+ var Size = webfont.Size;
20
15
 
21
- /**
22
- * Returns true if this.width equals other.width
23
- * @param {webfont.Size} other
24
- * @return {boolean}
25
- */
26
- webfont.Size.prototype.equalsWidth = function (other) {
27
- return !!other && this.width == other.width;
28
- };
16
+ /**
17
+ * Returns true if this size equals other.
18
+ *
19
+ * @param {webfont.Size} other
20
+ * @return {boolean}
21
+ */
22
+ Size.prototype.equals = function (other) {
23
+ return this.equalsWidth(other) && this.equalsHeight(other);
24
+ };
29
25
 
30
- /**
31
- * Returns true if this.height equals other.height
32
- * @param {webfont.Size} other
33
- * @return {boolean}
34
- */
35
- webfont.Size.prototype.equalsHeight = function (other) {
36
- return !!other && this.height == other.height;
37
- };
26
+ /**
27
+ * Returns true if this.width equals other.width
28
+ * @param {webfont.Size} other
29
+ * @return {boolean}
30
+ */
31
+ Size.prototype.equalsWidth = function (other) {
32
+ return !!other && this.width == other.width;
33
+ };
34
+
35
+ /**
36
+ * Returns true if this.height equals other.height
37
+ * @param {webfont.Size} other
38
+ * @return {boolean}
39
+ */
40
+ Size.prototype.equalsHeight = function (other) {
41
+ return !!other && this.height == other.height;
42
+ };
43
+ });