webfontloader 1.4.0 → 1.4.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 (44) hide show
  1. data/CHANGELOG +4 -0
  2. data/lib/webfontloader.rb +1 -1
  3. data/spec/ascender/ascenderscript_spec.js +24 -1
  4. data/spec/core/eventdispatcher_spec.js +15 -11
  5. data/spec/core/font_spec.js +83 -192
  6. data/spec/core/fontruler_spec.js +7 -4
  7. data/spec/core/fontwatcher_spec.js +78 -61
  8. data/spec/core/fontwatchrunner_spec.js +85 -33
  9. data/spec/core/webfont_spec.js +224 -0
  10. data/spec/custom/customcss_spec.js +5 -2
  11. data/spec/deps.js +13 -13
  12. data/spec/fontdeck/fontdeckscript_spec.js +4 -6
  13. data/spec/fonts/sourcesansc.css +1 -0
  14. data/spec/fonts/sourcesanscbold.css +1 -0
  15. data/spec/fonts/sourcesanscbold.otf +0 -0
  16. data/spec/google/fontapiparser_spec.js +58 -178
  17. data/spec/google/googlefontapi_spec.js +14 -42
  18. data/spec/google/lastresortwebkitfontwatchrunner_spec.js +12 -10
  19. data/spec/index.html +5 -3
  20. data/spec/monotype/monotypescript_spec.js +3 -2
  21. data/spec/typekit/typekitscript_spec.js +9 -4
  22. data/src/ascender/ascender_script.js +43 -26
  23. data/src/core/eventdispatcher.js +23 -23
  24. data/src/core/font.js +80 -99
  25. data/src/core/fontmoduleloader.js +1 -1
  26. data/src/core/fontruler.js +10 -20
  27. data/src/core/fontwatcher.js +24 -46
  28. data/src/core/fontwatchrunner.js +13 -13
  29. data/src/core/initialize.js +0 -10
  30. data/src/core/webfont.js +134 -0
  31. data/src/custom/customcss.js +14 -10
  32. data/src/fontdeck/fontdeck_script.js +7 -9
  33. data/src/google/fontapiparser.js +11 -15
  34. data/src/google/googlefontapi.js +1 -2
  35. data/src/google/lastresortwebkitfontwatchrunner.js +15 -13
  36. data/src/modules.yml +2 -3
  37. data/src/monotype/monotype_script.js +9 -8
  38. data/src/typekit/typekit_script.js +17 -7
  39. data/webfontloader.gemspec +7 -6
  40. metadata +9 -8
  41. data/spec/core/cssfontfamilyname_spec.js +0 -38
  42. data/spec/core/fontvariationdescription_spec.js +0 -67
  43. data/src/core/cssfontfamilyname.js +0 -33
  44. data/src/core/fontvariationdescription.js +0 -140
@@ -4,16 +4,6 @@ goog.require('webfont.UserAgentParser');
4
4
  goog.require('webfont.FontModuleLoader');
5
5
  goog.require('webfont.WebFont');
6
6
 
7
- /**
8
- * @typedef {Array.<string>}
9
- */
10
- webfont.FontFamilies;
11
-
12
- /**
13
- * @typedef {Object.<string, Array.<string>>}
14
- */
15
- webfont.FontVariations;
16
-
17
7
  /**
18
8
  * @typedef {Object.<string, Array.<string>>}
19
9
  */
@@ -0,0 +1,134 @@
1
+ goog.provide('webfont.WebFont');
2
+
3
+ goog.require('webfont.DomHelper');
4
+ goog.require('webfont.EventDispatcher');
5
+ goog.require('webfont.FontWatcher');
6
+
7
+ /**
8
+ * @param {Window} mainWindow The main application window containing
9
+ * webfontloader.js.
10
+ * @param {webfont.FontModuleLoader} fontModuleLoader A loader instance to use.
11
+ * @param {webfont.UserAgent} userAgent The detected user agent to load for.
12
+ * @constructor
13
+ */
14
+ webfont.WebFont = function(mainWindow, fontModuleLoader, userAgent) {
15
+ this.mainWindow_ = mainWindow;
16
+ this.fontModuleLoader_ = fontModuleLoader;
17
+ this.userAgent_ = userAgent;
18
+ this.moduleLoading_ = 0;
19
+ this.moduleFailedLoading_ = 0;
20
+ };
21
+
22
+ goog.scope(function () {
23
+ var WebFont = webfont.WebFont,
24
+ DomHelper = webfont.DomHelper,
25
+ EventDispatcher = webfont.EventDispatcher,
26
+ FontWatcher = webfont.FontWatcher;
27
+
28
+ /**
29
+ * @param {string} name
30
+ * @param {webfont.FontModuleFactory} factory
31
+ */
32
+ WebFont.prototype.addModule = function(name, factory) {
33
+ this.fontModuleLoader_.addModuleFactory(name, factory);
34
+ };
35
+
36
+ /**
37
+ * @param {Object} configuration
38
+ */
39
+ WebFont.prototype.load = function(configuration) {
40
+ var context = configuration['context'] || this.mainWindow_;
41
+ this.domHelper_ = new DomHelper(this.mainWindow_, context);
42
+
43
+ var eventDispatcher = new EventDispatcher(
44
+ this.domHelper_, context.document.documentElement, configuration);
45
+
46
+ if (this.userAgent_.getBrowserInfo().hasWebFontSupport()) {
47
+ this.load_(eventDispatcher, configuration);
48
+ } else {
49
+ eventDispatcher.dispatchInactive();
50
+ }
51
+ };
52
+
53
+ /**
54
+ * @param {webfont.FontModule} module
55
+ * @param {webfont.EventDispatcher} eventDispatcher
56
+ * @param {webfont.FontWatcher} fontWatcher
57
+ * @param {boolean} support
58
+ */
59
+ WebFont.prototype.isModuleSupportingUserAgent_ = function(module, eventDispatcher,
60
+ fontWatcher, support) {
61
+ var fontWatchRunnerCtor = module.getFontWatchRunnerCtor ?
62
+ module.getFontWatchRunnerCtor() : webfont.FontWatchRunner,
63
+ that = this;
64
+
65
+ if (!support) {
66
+ var allModulesLoaded = --this.moduleLoading_ == 0;
67
+
68
+ this.moduleFailedLoading_--;
69
+ if (allModulesLoaded) {
70
+ if (this.moduleFailedLoading_ == 0) {
71
+ eventDispatcher.dispatchInactive();
72
+ } else {
73
+ eventDispatcher.dispatchLoading();
74
+ }
75
+ }
76
+ fontWatcher.watch([], {}, fontWatchRunnerCtor, allModulesLoaded);
77
+ return;
78
+ }
79
+
80
+ module.load(function (fonts) {
81
+ that.onModuleReady_(eventDispatcher, fontWatcher, fontWatchRunnerCtor, fonts);
82
+ });
83
+ };
84
+
85
+ /**
86
+ * @param {webfont.EventDispatcher} eventDispatcher
87
+ * @param {webfont.FontWatcher} fontWatcher
88
+ * @param {function(new:webfont.FontWatchRunner,
89
+ * function(webfont.Font),
90
+ * function(webfont.Font),
91
+ * webfont.DomHelper,
92
+ * webfont.Font,
93
+ * webfont.BrowserInfo,
94
+ * number=,
95
+ * Object.<string, boolean>=,
96
+ * string=)} fontWatchRunnerCtor
97
+ * @param {Array.<webfont.Font>} fonts
98
+ * @param {webfont.FontTestStrings=} opt_fontTestStrings
99
+ */
100
+ WebFont.prototype.onModuleReady_ = function(eventDispatcher, fontWatcher,
101
+ fontWatchRunnerCtor, fonts, opt_fontTestStrings) {
102
+ var allModulesLoaded = --this.moduleLoading_ == 0;
103
+
104
+ if (allModulesLoaded) {
105
+ eventDispatcher.dispatchLoading();
106
+ }
107
+
108
+ setTimeout(function () {
109
+ fontWatcher.watch(fonts, opt_fontTestStrings || {}, fontWatchRunnerCtor, allModulesLoaded);
110
+ }, 0);
111
+ };
112
+
113
+ /**
114
+ * @param {webfont.EventDispatcher} eventDispatcher
115
+ * @param {Object} configuration
116
+ */
117
+ WebFont.prototype.load_ = function(eventDispatcher, configuration) {
118
+ var modules = this.fontModuleLoader_.getModules(configuration, this.domHelper_),
119
+ timeout = configuration['timeout'],
120
+ self = this;
121
+
122
+ this.moduleFailedLoading_ = this.moduleLoading_ = modules.length;
123
+
124
+ var fontWatcher = new webfont.FontWatcher(this.userAgent_, this.domHelper_, eventDispatcher, timeout);
125
+
126
+ for (var i = 0, len = modules.length; i < len; i++) {
127
+ var module = modules[i];
128
+
129
+ module.supportUserAgent(this.userAgent_,
130
+ goog.bind(this.isModuleSupportingUserAgent_, this, module,
131
+ eventDispatcher, fontWatcher));
132
+ }
133
+ };
134
+ });
@@ -1,5 +1,7 @@
1
1
  goog.provide('webfont.CustomCss');
2
2
 
3
+ goog.require('webfont.Font');
4
+
3
5
  /**
4
6
  *
5
7
  * WebFont.load({
@@ -19,7 +21,8 @@ webfont.CustomCss = function(domHelper, configuration) {
19
21
  webfont.CustomCss.NAME = 'custom';
20
22
 
21
23
  goog.scope(function () {
22
- var CustomCss = webfont.CustomCss;
24
+ var CustomCss = webfont.CustomCss,
25
+ Font = webfont.Font;
23
26
 
24
27
  CustomCss.prototype.load = function(onReady) {
25
28
  var i, len;
@@ -32,22 +35,23 @@ goog.scope(function () {
32
35
  this.domHelper_.insertInto('head', this.domHelper_.createCssLink(url));
33
36
  }
34
37
 
35
- var families = [];
36
- var variations = {};
38
+ var fonts = [];
39
+
37
40
  for (i = 0, len = familiesConfiguration.length; i < len; i++) {
38
41
  var components = familiesConfiguration[i].split(":");
39
- var family = components[0];
40
- var familyVariations = components[1];
41
42
 
42
- families.push(family);
43
+ if (components[1]) {
44
+ var variations = components[1].split(",");
43
45
 
44
- if (familyVariations) {
45
- var newVariations = familyVariations.split(",");
46
- variations[family] = (variations[family] || []).concat(newVariations);
46
+ for (var j = 0; j < variations.length; j += 1) {
47
+ fonts.push(new Font(components[0], variations[j]));
48
+ }
49
+ } else {
50
+ fonts.push(new Font(components[0]));
47
51
  }
48
52
  }
49
53
 
50
- onReady(families, variations);
54
+ onReady(fonts);
51
55
  };
52
56
 
53
57
  CustomCss.prototype.supportUserAgent = function(userAgent, support) {
@@ -1,6 +1,6 @@
1
1
  goog.provide('webfont.FontdeckScript');
2
2
 
3
- goog.require('webfont.FontVariationDescription');
3
+ goog.require('webfont.Font');
4
4
 
5
5
  /**
6
6
  * @constructor
@@ -9,9 +9,7 @@ goog.require('webfont.FontVariationDescription');
9
9
  webfont.FontdeckScript = function(domHelper, configuration) {
10
10
  this.domHelper_ = domHelper;
11
11
  this.configuration_ = configuration;
12
- this.fontFamilies_ = [];
13
- this.fontVariations_ = {};
14
- this.fvd_ = new webfont.FontVariationDescription();
12
+ this.fonts_ = [];
15
13
  };
16
14
 
17
15
  webfont.FontdeckScript.NAME = 'fontdeck';
@@ -19,7 +17,9 @@ webfont.FontdeckScript.HOOK = '__webfontfontdeckmodule__';
19
17
  webfont.FontdeckScript.API = '//f.fontdeck.com/s/css/js/';
20
18
 
21
19
  goog.scope(function () {
22
- var FontdeckScript = webfont.FontdeckScript;
20
+ var FontdeckScript = webfont.FontdeckScript,
21
+ Font = webfont.Font,
22
+ FontVariationDescription = webfont.FontVariationDescription;
23
23
 
24
24
  FontdeckScript.prototype.getScriptSrc = function(projectId) {
25
25
  var protocol = this.domHelper_.getProtocol();
@@ -46,9 +46,7 @@ goog.scope(function () {
46
46
  loadWindow[webfont.FontdeckScript.HOOK][projectId] = function(fontdeckSupports, data) {
47
47
  for (var i = 0, j = data['fonts'].length; i<j; ++i) {
48
48
  var font = data['fonts'][i];
49
- // Add the FVDs
50
- self.fontFamilies_.push(font['name']);
51
- self.fontVariations_[font['name']] = [self.fvd_.compact("font-weight:" + font['weight'] + ";font-style:" + font['style'])];
49
+ self.fonts_.push(new Font(font['name'], Font.parseCssVariation('font-weight:' + font['weight'] + ';font-style:' + font['style'])));
52
50
  }
53
51
  support(fontdeckSupports);
54
52
  };
@@ -63,7 +61,7 @@ goog.scope(function () {
63
61
  };
64
62
 
65
63
  FontdeckScript.prototype.load = function(onReady) {
66
- onReady(this.fontFamilies_, this.fontVariations_);
64
+ onReady(this.fonts_);
67
65
  };
68
66
  });
69
67
 
@@ -1,16 +1,14 @@
1
1
  goog.provide('webfont.FontApiParser');
2
2
 
3
- goog.require('webfont.FontVariationDescription');
3
+ goog.require('webfont.Font');
4
4
 
5
5
  /**
6
6
  * @constructor
7
7
  */
8
8
  webfont.FontApiParser = function(fontFamilies) {
9
9
  this.fontFamilies_ = fontFamilies;
10
- this.parsedFontFamilies_ = [];
11
- this.variations_ = {};
10
+ this.parsedFonts_ = [];
12
11
  this.fontTestStrings_ = {};
13
- this.fvd_ = new webfont.FontVariationDescription();
14
12
  };
15
13
 
16
14
 
@@ -61,7 +59,8 @@ webfont.FontApiParser.VARIATION_MATCH =
61
59
  "|normal|italic)?$");
62
60
 
63
61
  goog.scope(function () {
64
- var FontApiParser = webfont.FontApiParser;
62
+ var FontApiParser = webfont.FontApiParser,
63
+ Font = webfont.Font;
65
64
 
66
65
  FontApiParser.prototype.parse = function() {
67
66
  var length = this.fontFamilies_.length;
@@ -96,8 +95,10 @@ goog.scope(function () {
96
95
  this.fontTestStrings_[fontFamily] = hanumanTestString;
97
96
  }
98
97
  }
99
- this.parsedFontFamilies_.push(fontFamily);
100
- this.variations_[fontFamily] = variations;
98
+
99
+ for (var j = 0; j < variations.length; j += 1) {
100
+ this.parsedFonts_.push(new Font(fontFamily, variations[j]));
101
+ }
101
102
  }
102
103
  };
103
104
 
@@ -112,8 +113,7 @@ goog.scope(function () {
112
113
  }
113
114
  var styleMatch = this.normalizeStyle_(groups[2]);
114
115
  var weightMatch = this.normalizeWeight_(groups[1]);
115
- var css = this.fvd_.expand([styleMatch, weightMatch].join(''));
116
- return css ? this.fvd_.compact(css) : null;
116
+ return [styleMatch, weightMatch].join('');
117
117
  };
118
118
 
119
119
 
@@ -171,12 +171,8 @@ goog.scope(function () {
171
171
  };
172
172
 
173
173
 
174
- FontApiParser.prototype.getFontFamilies = function() {
175
- return this.parsedFontFamilies_;
176
- };
177
-
178
- FontApiParser.prototype.getVariations = function() {
179
- return this.variations_;
174
+ FontApiParser.prototype.getFonts = function() {
175
+ return this.parsedFonts_;
180
176
  };
181
177
 
182
178
  FontApiParser.prototype.getFontTestStrings = function() {
@@ -59,8 +59,7 @@ goog.scope(function () {
59
59
 
60
60
  domHelper.insertInto('head', domHelper.createCssLink(
61
61
  fontApiUrlBuilder.build()));
62
- onReady(fontApiParser.getFontFamilies(), fontApiParser.getVariations(),
63
- fontApiParser.getFontTestStrings());
62
+ onReady(fontApiParser.getFonts(), fontApiParser.getFontTestStrings());
64
63
  };
65
64
  });
66
65
 
@@ -1,14 +1,14 @@
1
1
  goog.provide('webfont.LastResortWebKitFontWatchRunner');
2
2
 
3
+ goog.require('webfont.Font');
3
4
  goog.require('webfont.FontRuler');
4
5
 
5
6
  /**
6
7
  * @constructor
7
- * @param {function(string, string)} activeCallback
8
- * @param {function(string, string)} inactiveCallback
8
+ * @param {function(webfont.Font)} activeCallback
9
+ * @param {function(webfont.Font)} inactiveCallback
9
10
  * @param {webfont.DomHelper} domHelper
10
- * @param {string} fontFamily
11
- * @param {string} fontDescription
11
+ * @param {webfont.Font} font
12
12
  * @param {webfont.BrowserInfo} browserInfo
13
13
  * @param {number=} opt_timeout
14
14
  * @param {Object.<string, boolean>=} opt_metricCompatibleFonts
@@ -16,11 +16,11 @@ goog.require('webfont.FontRuler');
16
16
  * @extends webfont.FontWatchRunner
17
17
  */
18
18
  webfont.LastResortWebKitFontWatchRunner = function(activeCallback,
19
- inactiveCallback, domHelper, fontFamily,
20
- fontDescription, browserInfo, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
19
+ inactiveCallback, domHelper, font,
20
+ browserInfo, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
21
21
 
22
22
  goog.base(this, activeCallback, inactiveCallback, domHelper,
23
- fontFamily, fontDescription, browserInfo, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString);
23
+ font, browserInfo, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString);
24
24
 
25
25
  this.webKitLastResortFontWidths_ = this.setUpWebKitLastResortFontWidths_();
26
26
  this.webKitLastResortWidthChange_ = false;
@@ -38,6 +38,7 @@ webfont.LastResortWebKitFontWatchRunner.METRICS_COMPATIBLE_FONTS = {
38
38
 
39
39
  goog.scope(function () {
40
40
  var LastResortWebKitFontWatchRunner = webfont.LastResortWebKitFontWatchRunner,
41
+ Font = webfont.Font,
41
42
  FontRuler = webfont.FontRuler;
42
43
 
43
44
  /**
@@ -51,23 +52,24 @@ goog.scope(function () {
51
52
  LastResortWebKitFontWatchRunner.prototype
52
53
  .setUpWebKitLastResortFontWidths_ = function() {
53
54
  var lastResortFonts = ['Times New Roman', 'Arial', 'Times', 'Sans', 'Serif'];
55
+ var variation = this.font_.getVariation();
54
56
  var lastResortFontWidths = lastResortFonts.length;
55
57
  var webKitLastResortFontWidths = {};
56
58
  var fontRuler = new FontRuler(this.domHelper_, this.fontTestString_);
57
59
 
58
60
  fontRuler.insert();
59
- fontRuler.setFont(lastResortFonts[0], this.fontDescription_);
61
+ fontRuler.setFont(new Font(lastResortFonts[0], variation));
60
62
 
61
63
  webKitLastResortFontWidths[fontRuler.getWidth()] = true;
62
64
  for (var i = 1; i < lastResortFontWidths; i++) {
63
65
  var font = lastResortFonts[i];
64
- fontRuler.setFont(font, this.fontDescription_);
66
+ fontRuler.setFont(new Font(font, variation));
65
67
  webKitLastResortFontWidths[fontRuler.getWidth()] = true;
66
68
 
67
69
  // Another WebKit quirk if the normal weight/style is loaded first,
68
70
  // the size of the normal weight is returned when loading another weight.
69
- if (this.fontDescription_[1] != '4') {
70
- fontRuler.setFont(font, this.fontDescription_[0] + '4');
71
+ if (variation.toString().charAt(1) != '4') {
72
+ fontRuler.setFont(new Font(font, variation.charAt(0) + '4'));
71
73
  webKitLastResortFontWidths[fontRuler.getWidth()] = true;
72
74
  }
73
75
  }
@@ -92,7 +94,7 @@ goog.scope(function () {
92
94
  (!this.webKitLastResortFontWidths_[widthA] &&
93
95
  !this.webKitLastResortFontWidths_[widthB])) {
94
96
  this.finish_(this.activeCallback_);
95
- } else if (goog.now() - this.started_ >= 5000) {
97
+ } else if (this.hasTimedOut_()) {
96
98
 
97
99
  // In order to handle the fact that a font could be the same size as the
98
100
  // default browser font on a webkit browser, mark the font as active
@@ -101,7 +103,7 @@ goog.scope(function () {
101
103
  if (this.webKitLastResortFontWidths_[widthA]
102
104
  && this.webKitLastResortFontWidths_[widthB] &&
103
105
  LastResortWebKitFontWatchRunner.METRICS_COMPATIBLE_FONTS[
104
- this.fontFamily_]) {
106
+ this.font_.getName()]) {
105
107
  this.finish_(this.activeCallback_);
106
108
  } else {
107
109
  this.finish_(this.inactiveCallback_);
data/src/modules.yml CHANGED
@@ -5,14 +5,13 @@ core:
5
5
  - core/useragent.js
6
6
  - core/useragentparser.js
7
7
  - core/cssclassname.js
8
- - core/cssfontfamilyname.js
9
- - core/fontvariationdescription.js
8
+ - core/font.js
10
9
  - core/eventdispatcher.js
11
10
  - core/fontmoduleloader.js
12
11
  - core/fontruler.js
13
12
  - core/fontwatchrunner.js
14
13
  - core/fontwatcher.js
15
- - core/font.js
14
+ - core/webfont.js
16
15
  - core/initialize.js
17
16
 
18
17
  ascender:
@@ -1,5 +1,7 @@
1
1
  goog.provide('webfont.MonotypeScript');
2
2
 
3
+ goog.require('webfont.Font');
4
+
3
5
  /**
4
6
  webfont.load({
5
7
  monotype: {
@@ -16,8 +18,7 @@ webfont.MonotypeScript = function (userAgent, domHelper, configuration) {
16
18
  this.userAgent_ = userAgent;
17
19
  this.domHelper_ = domHelper;
18
20
  this.configuration_ = configuration;
19
- this.fontFamilies_ = [];
20
- this.fontVariations_ = {};
21
+ this.fonts_ = [];
21
22
  };
22
23
 
23
24
  /**
@@ -40,7 +41,8 @@ webfont.MonotypeScript.HOOK = '__mti_fntLst';
40
41
  webfont.MonotypeScript.SCRIPTID = '__MonotypeAPIScript__';
41
42
 
42
43
  goog.scope(function () {
43
- var MonotypeScript = webfont.MonotypeScript;
44
+ var MonotypeScript = webfont.MonotypeScript,
45
+ Font = webfont.Font;
44
46
 
45
47
  MonotypeScript.prototype.supportUserAgent = function (userAgent, support) {
46
48
  var self = this;
@@ -55,10 +57,9 @@ goog.scope(function () {
55
57
  function onload() {
56
58
  if (loadWindow[MonotypeScript.HOOK + projectId]) {
57
59
  var mti_fnts = loadWindow[webfont.MonotypeScript.HOOK + projectId]();
58
- if (mti_fnts && mti_fnts.length) {
59
- var i;
60
- for (i = 0; i < mti_fnts.length; i++) {
61
- self.fontFamilies_.push(mti_fnts[i]["fontfamily"]);
60
+ if (mti_fnts) {
61
+ for (var i = 0; i < mti_fnts.length; i++) {
62
+ self.fonts_.push(new Font(mti_fnts[i]["fontfamily"]));
62
63
  }
63
64
  }
64
65
  }
@@ -90,7 +91,7 @@ goog.scope(function () {
90
91
  };
91
92
 
92
93
  MonotypeScript.prototype.load = function (onReady) {
93
- onReady(this.fontFamilies_, this.fontVariations_);
94
+ onReady(this.fonts_);
94
95
  };
95
96
  });
96
97