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
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ v1.3.1 (March 14, 2013)
2
+ * Change code to use explicit dependencies
3
+ * Fix unit tests in older browsers
4
+ * Fix google/FontApiParser.js to work in IE <= 8
5
+
1
6
  v1.3.0 (February 28, 2013)
2
7
  * New optional configuration parameter `timeout` which lets you customize the default timeout.
3
8
  * Change the Typekit module to use `use.typekit.net` instead of `use.typekit.com`.
data/Rakefile CHANGED
@@ -92,6 +92,7 @@ file "target/webfont.js" => SourceJs + ["target"] do |t|
92
92
  ["-jar", JsCompilerJar],
93
93
  ["--compilation_level", "ADVANCED_OPTIMIZATIONS"],
94
94
  ["--js_output_file", t.name],
95
+ "--generate_exports",
95
96
  ["--output_wrapper", %("#{output_wrapper}")],
96
97
  ["--warning_level", "VERBOSE"],
97
98
  ["--summary_detail_level", "3"]
@@ -107,7 +108,7 @@ file "target/webfont.js" => SourceJs + ["target"] do |t|
107
108
  args.concat source.map { |f| ["--js", f] }
108
109
 
109
110
  output = `java #{args.flatten.join(' ')} 2>&1`
110
- fail output unless output.empty?
111
+ $?.success? ? (puts output) : (fail output)
111
112
  end
112
113
 
113
114
  desc "Creates debug version into target/webfont.js"
data/lib/webfontloader.rb CHANGED
@@ -3,7 +3,7 @@ require 'yaml'
3
3
  require 'webfontloader/modules'
4
4
 
5
5
  module WebFontLoader
6
- VERSION = '1.3.0'
6
+ VERSION = '1.3.1'
7
7
 
8
8
  ProjectRoot = File.expand_path(File.dirname(__FILE__) + "/..")
9
9
 
@@ -16,7 +16,7 @@ describe('WebFont', function () {
16
16
  testModule = null;
17
17
 
18
18
  beforeEach(function () {
19
- font = new WebFont(window, fontModuleLoader, function (func, timeout) { func(); }, userAgent);
19
+ font = new WebFont(window, fontModuleLoader, userAgent);
20
20
  font.addModule('test', function (conf, domHelper) {
21
21
  testModule = new function () {
22
22
  this.conf = conf;
@@ -80,7 +80,7 @@ describe('WebFont', function () {
80
80
  fakeMainWindow = {};
81
81
 
82
82
  beforeEach(function () {
83
- font = new WebFont(fakeMainWindow, fontModuleLoader, function (func, timeout) { func(); }, userAgent);
83
+ font = new WebFont(fakeMainWindow, fontModuleLoader, userAgent);
84
84
  font.addModule('test', function (conf, domHelper) {
85
85
  testModule = new function () {
86
86
  this.domHelper = domHelper;
@@ -117,7 +117,8 @@ describe('WebFont', function () {
117
117
  active = jasmine.createSpy('active');
118
118
 
119
119
  beforeEach(function () {
120
- font = new WebFont(window, fontModuleLoader, function (func, timeout) { func(); }, new UserAgent('Firefox', '3.6', 'Gecko', '1.9.2', 'Macintosh', '10.6', undefined, new BrowserInfo(true, false)));
120
+ jasmine.Clock.useMock();
121
+ font = new WebFont(window, fontModuleLoader, new UserAgent('Firefox', '3.6', 'Gecko', '1.9.2', 'Macintosh', '10.6', undefined, new BrowserInfo(true, false)));
121
122
  font.addModule('test', function (conf, domHelper) {
122
123
  testModule = new function () {
123
124
  this.conf = conf;
@@ -168,6 +169,8 @@ describe('WebFont', function () {
168
169
  active: active
169
170
  });
170
171
 
172
+ jasmine.Clock.tick(1);
173
+
171
174
  expect(testModule).not.toBeNull();
172
175
  expect(active).toHaveBeenCalled();
173
176
  });
@@ -180,6 +183,8 @@ describe('WebFont', function () {
180
183
  active: active
181
184
  });
182
185
 
186
+ jasmine.Clock.tick(1);
187
+
183
188
  expect(testModule).not.toBeNull();
184
189
  expect(inactive).toHaveBeenCalled();
185
190
  });
@@ -190,7 +195,7 @@ describe('WebFont', function () {
190
195
  testModule = null;
191
196
 
192
197
  beforeEach(function () {
193
- font = new WebFont(window, fontModuleLoader, function (func, timeout) { func(); }, new UserAgent('Firefox', '3.6', 'Gecko', '1.9.2', 'Macintosh', '10.6', undefined, new BrowserInfo(false, false, false)));
198
+ font = new WebFont(window, fontModuleLoader, new UserAgent('Firefox', '3.6', 'Gecko', '1.9.2', 'Macintosh', '10.6', undefined, new BrowserInfo(false, false, false)));
194
199
  font.addModule('test', function (conf, domHelper) {
195
200
  testModule = new function () {
196
201
  this.conf = conf;
@@ -2,22 +2,15 @@ describe('FontRuler', function () {
2
2
  var FontRuler = webfont.FontRuler,
3
3
  DomHelper = webfont.DomHelper,
4
4
  Size = webfont.Size,
5
- domHelper = null,
6
- fontSizer = null;
5
+ domHelper = null;
7
6
 
8
7
  beforeEach(function () {
9
8
  domHelper = new DomHelper(window);
10
-
11
- fontSizer = {
12
- getSize: function (el) {
13
- return new Size(el.offsetWidth, el.offsetHeight);
14
- }
15
- };
16
9
  });
17
10
 
18
11
  it('should prevent a long test string from word wrapping', function () {
19
- var fontRulerA = new FontRuler(domHelper, fontSizer, 'abc'),
20
- fontRulerB = new FontRuler(domHelper, fontSizer, 'Hello World, this should wrap!');
12
+ var fontRulerA = new FontRuler(domHelper, 'abc'),
13
+ fontRulerB = new FontRuler(domHelper, 'Hello World, this should wrap!');
21
14
 
22
15
  fontRulerA.insert();
23
16
  fontRulerB.insert();
@@ -23,8 +23,8 @@ describe('FontWatcher', function () {
23
23
  eventDispatcher.dispatchInactive = jasmine.createSpy('dispatchInactive');
24
24
  });
25
25
 
26
- function FakeFontWatchRunner(activeCallback, inactiveCallback, domHelper, fontSizer, asyncCall, getTime,
27
- fontFamily, fontDescription, hasWebKitFallbackBug, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
26
+ function FakeFontWatchRunner(activeCallback, inactiveCallback, domHelper,
27
+ fontFamily, fontDescription, browserInfo, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
28
28
  this.activeCallback = activeCallback;
29
29
  this.inactiveCallback = inactiveCallback;
30
30
  this.fontFamily = fontFamily;
@@ -37,7 +37,16 @@ describe('FontWatcher', function () {
37
37
  }
38
38
 
39
39
  FakeFontWatchRunner.prototype.start = function () {
40
- if (activeFontFamilies.indexOf(this.fontFamily) > -1) {
40
+ var found = false;
41
+
42
+ for (var i = 0; i < activeFontFamilies.length; i += 1) {
43
+ if (activeFontFamilies[i] === this.fontFamily) {
44
+ found = true;
45
+ break;
46
+ }
47
+ }
48
+
49
+ if (found) {
41
50
  this.activeCallback(this.fontFamily, this.fontDescription);
42
51
  } else {
43
52
  this.inactiveCallback(this.fontFamily, this.fontDescription);
@@ -47,8 +56,7 @@ describe('FontWatcher', function () {
47
56
  describe('watch zero fonts', function () {
48
57
  it('should call inactive when there are no fonts to load', function () {
49
58
  activeFontFamilies = [];
50
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
51
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
59
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
52
60
 
53
61
  fontWatcher.watch([], {}, {}, FakeFontWatchRunner, true);
54
62
  expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
@@ -58,8 +66,7 @@ describe('FontWatcher', function () {
58
66
  describe('watch one font not last', function () {
59
67
  it('should not call font inactive, inactive or active', function () {
60
68
  activeFontFamilies = ['fontFamily1'];
61
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
62
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
69
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
63
70
 
64
71
  fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, false);
65
72
  expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
@@ -71,8 +78,7 @@ describe('FontWatcher', function () {
71
78
  describe('watch one font active', function () {
72
79
  it('should call font active and active', function () {
73
80
  activeFontFamilies = ['fontFamily1'];
74
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
75
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
81
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
76
82
 
77
83
  fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, true);
78
84
  expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
@@ -86,8 +92,7 @@ describe('FontWatcher', function () {
86
92
  describe('watch one font inactive', function () {
87
93
  it('should call inactive', function () {
88
94
  activeFontFamilies = [];
89
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
90
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
95
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
91
96
 
92
97
  fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, true);
93
98
  expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
@@ -101,8 +106,7 @@ describe('FontWatcher', function () {
101
106
  describe('watch multiple fonts active', function () {
102
107
  it('should call font active and active', function () {
103
108
  activeFontFamilies = ['fontFamily1', 'fontFamily2', 'fontFamily3'];
104
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
105
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
109
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
106
110
 
107
111
  fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {}, {}, FakeFontWatchRunner, true);
108
112
  expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
@@ -116,8 +120,7 @@ describe('FontWatcher', function () {
116
120
  describe('watch multiple fonts inactive', function () {
117
121
  it('should call inactive', function () {
118
122
  activeFontFamilies = [];
119
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
120
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
123
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
121
124
 
122
125
  fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {}, {}, FakeFontWatchRunner, true);
123
126
  expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
@@ -131,8 +134,7 @@ describe('FontWatcher', function () {
131
134
  describe('watch multiple fonts mixed', function () {
132
135
  it('should call the correct callbacks', function () {
133
136
  activeFontFamilies = ['fontFamily1', 'fontFamily3'];
134
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
135
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
137
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
136
138
 
137
139
  fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {}, {}, FakeFontWatchRunner, true);
138
140
  expect(eventDispatcher.dispatchFontLoading.callCount).toEqual(3);
@@ -155,8 +157,7 @@ describe('FontWatcher', function () {
155
157
  describe('watch multiple fonts with descriptions', function () {
156
158
  it('should call the correct callbacks', function () {
157
159
  activeFontFamilies = ['fontFamily1', 'fontFamily2'];
158
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
159
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
160
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
160
161
 
161
162
  fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {
162
163
  'fontFamily1': ['i7'],
@@ -189,8 +190,7 @@ describe('FontWatcher', function () {
189
190
  it('should use the correct tests strings', function () {
190
191
  activeFontFamilies = ['fontFamily1', 'fontFamily2'];
191
192
 
192
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
193
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
193
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher);
194
194
 
195
195
  fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3', 'fontFamily4'], {}, {
196
196
  'fontFamily1': 'testString1',
@@ -206,8 +206,7 @@ describe('FontWatcher', function () {
206
206
  });
207
207
 
208
208
  it('should pass on the timeout to FontWatchRunner', function () {
209
- var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
210
- jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'), 4000);
209
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, 4000);
211
210
 
212
211
  fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, true);
213
212
 
@@ -4,273 +4,286 @@ describe('FontWatchRunner', function () {
4
4
  UserAgentParser = webfont.UserAgentParser,
5
5
  Size = webfont.Size,
6
6
  DomHelper = webfont.DomHelper,
7
- FontRuler = webfont.FontRuler,
8
- domHelper = new DomHelper(window),
9
- fontFamily = 'My Family',
10
- fontDescription = 'n4';
11
-
12
- var timesToCheckSizeBeforeChange = 0,
13
- TARGET_SIZE = new Size(3, 3),
14
- FALLBACK_SIZE_A = new Size(1, 1),
15
- FALLBACK_SIZE_B = new Size(2, 2),
16
- LAST_RESORT_SIZE = new Size(4, 4),
17
-
18
- browserInfo = new BrowserInfo(true, false, false),
19
- setupSizes = [FALLBACK_SIZE_A, FALLBACK_SIZE_B, LAST_RESORT_SIZE],
20
- actualSizes = [],
21
- fakeGetSizeCount = 0,
22
- setupFinished = false,
23
- fakeFontSizer = {
24
- getSize: function (el) {
25
- var result = null;
26
-
27
- if (setupFinished) {
28
- // If you are getting an exception here your tests does not specify enough
29
- // size data to run properly.
30
- if (fakeGetSizeCount >= actualSizes.length) {
31
- throw 'Invalid test data';
32
- }
33
- result = actualSizes[fakeGetSizeCount];
34
- fakeGetSizeCount += 1;
35
- } else {
36
- result = setupSizes[Math.min(fakeGetSizeCount, setupSizes.length - 1)];
37
- fakeGetSizeCount += 1;
38
- }
39
- return result;
40
- }
41
- },
42
- timesToGetTimeBeforeTimeout = 10,
43
- fakeGetTime = function () {
44
- if (timesToGetTimeBeforeTimeout <= 0) {
45
- return 6000;
46
- } else {
47
- timesToGetTimeBeforeTimeout -= 1;
48
- return 1;
49
- }
50
- },
51
- asyncCount = 0,
52
- fakeAsyncCall = function (func, timeout) {
53
- asyncCount += 1;
54
- func();
55
- },
56
- setupFinished = false,
57
- originalStartMethod = null,
7
+ FontRuler = webfont.FontRuler;
8
+
9
+ var domHelper = null,
58
10
  activeCallback = null,
59
11
  inactiveCallback = null;
60
12
 
61
13
  beforeEach(function () {
62
- actualSizes = [];
63
- setupFinished = false;
64
- fakeGetSizeCount = 0;
14
+ domHelper = new DomHelper(window);
65
15
 
66
- asyncCount = 0;
67
- timesToGetTimeBeforeTimeout = 10;
68
16
  activeCallback = jasmine.createSpy('activeCallback');
69
17
  inactiveCallback = jasmine.createSpy('inactiveCallback');
70
-
71
- originalStartMethod = FontWatchRunner.prototype.start;
72
-
73
- FontWatchRunner.prototype.start = function () {
74
- setupFinished = true;
75
- fakeGetSizeCount = 0;
76
- originalStartMethod.apply(this);
77
- };
78
- });
79
-
80
- afterEach(function () {
81
- FontWatchRunner.prototype.start = originalStartMethod;
82
18
  });
83
19
 
84
- it('should call active if fonts are already loaded', function () {
85
- actualSizes = [
86
- TARGET_SIZE, TARGET_SIZE
87
- ];
20
+ describe('Fake browser', function () {
21
+ var fontFamily = 'My Family',
22
+ fontDescription = 'n4',
23
+ TARGET_SIZE = new Size(3, 3),
24
+ FALLBACK_SIZE_A = new Size(1, 1),
25
+ FALLBACK_SIZE_B = new Size(2, 2),
26
+ LAST_RESORT_SIZE = new Size(4, 4),
88
27
 
89
- var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
90
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, browserInfo);
28
+ browserInfo = new BrowserInfo(true, false, false),
29
+ fallbackBugBrowserInfo = new BrowserInfo(true, true, false),
30
+ setupSizes = [],
31
+ actualSizes = [],
32
+ timesToGetTimeBeforeTimeout = 10;
91
33
 
92
- fontWatchRunner.start();
93
-
94
- expect(asyncCount).toEqual(0);
95
- expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
96
- });
34
+ beforeEach(function () {
35
+ jasmine.Clock.useMock();
97
36
 
98
- it('should wait for font load and call active', function () {
99
- actualSizes = [
100
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
101
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
102
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
103
- TARGET_SIZE, TARGET_SIZE
104
- ];
37
+ setupSizes = [FALLBACK_SIZE_A, FALLBACK_SIZE_B, LAST_RESORT_SIZE];
105
38
 
106
- var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
107
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, browserInfo);
39
+ actualSizes = [];
108
40
 
109
- fontWatchRunner.start();
110
- expect(asyncCount).toEqual(3);
111
- expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
112
- });
41
+ var setupFinished = false,
42
+ fakeGetSizeCount = 0;
113
43
 
114
- it('should wait for font inactive and call inactive', function () {
115
- timesToGetTimeBeforeTimeout = 5;
116
-
117
- actualSizes = [
118
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
119
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
120
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
121
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
122
- FALLBACK_SIZE_A, FALLBACK_SIZE_B
123
- ];
44
+ spyOn(FontRuler.prototype, 'getSize').andCallFake(function () {
45
+ var result = null;
46
+ if (setupFinished) {
47
+ // If you are getting an exception here your tests does not specify enough
48
+ // size data to run properly.
49
+ if (fakeGetSizeCount >= actualSizes.length) {
50
+ throw 'Invalid test data';
51
+ }
52
+ result = actualSizes[fakeGetSizeCount];
53
+ fakeGetSizeCount += 1;
54
+ } else {
55
+ result = setupSizes[Math.min(fakeGetSizeCount, setupSizes.length - 1)];
56
+ fakeGetSizeCount += 1;
57
+ }
58
+ return result;
59
+ });
124
60
 
125
- var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
126
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, browserInfo);
61
+ timesToGetBeforeTimeout = 10;
127
62
 
128
- fontWatchRunner.start();
63
+ spyOn(goog, 'now').andCallFake(function () {
64
+ if (timesToGetTimeBeforeTimeout <= 0) {
65
+ return 6000;
66
+ } else {
67
+ timesToGetTimeBeforeTimeout -= 1;
68
+ return 1;
69
+ }
70
+ });
129
71
 
130
- expect(asyncCount).toEqual(4);
131
- expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
132
- });
72
+ var originalStart = FontWatchRunner.prototype.start;
133
73
 
134
- describe('WebKit fallback bug', function () {
135
- var fallbackBugBrowserInfo = null;
74
+ spyOn(FontWatchRunner.prototype, 'start').andCallFake(function () {
75
+ setupFinished = true;
76
+ fakeGetSizeCount = 0;
136
77
 
137
- beforeEach(function () {
138
- fallbackBugBrowserInfo = new BrowserInfo(true, true, false);
78
+ originalStart.apply(this);
79
+ });
139
80
  });
140
81
 
141
- it('should ignore fallback size and call active', function () {
82
+ it('should call active if fonts are already loaded', function () {
142
83
  actualSizes = [
143
- LAST_RESORT_SIZE, LAST_RESORT_SIZE,
144
84
  TARGET_SIZE, TARGET_SIZE
145
85
  ];
146
86
 
147
87
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
148
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, fallbackBugBrowserInfo);
88
+ domHelper, fontFamily, fontDescription, browserInfo);
149
89
 
150
90
  fontWatchRunner.start();
151
91
 
152
- expect(asyncCount).toEqual(1);
92
+ jasmine.Clock.tick(1 * 25);
153
93
  expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
154
94
  });
155
95
 
156
- it('should consider last resort font as having identical metrics and call active', function () {
96
+ it('should wait for font load and call active', function () {
157
97
  actualSizes = [
158
- LAST_RESORT_SIZE, LAST_RESORT_SIZE,
159
- LAST_RESORT_SIZE, LAST_RESORT_SIZE
98
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
99
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
100
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
101
+ TARGET_SIZE, TARGET_SIZE
160
102
  ];
161
103
 
162
- timesToGetTimeBeforeTimeout = 2;
163
-
164
104
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
165
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, fallbackBugBrowserInfo);
105
+ domHelper, fontFamily, fontDescription, browserInfo);
166
106
 
167
107
  fontWatchRunner.start();
168
108
 
169
- expect(asyncCount).toEqual(1);
109
+ jasmine.Clock.tick(3 * 25);
170
110
  expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
171
111
  });
172
112
 
173
- it('should fail to load font and call inactive', function () {
113
+ it('should wait for font inactive and call inactive', function () {
114
+ timesToGetTimeBeforeTimeout = 5;
115
+
174
116
  actualSizes = [
175
- LAST_RESORT_SIZE, LAST_RESORT_SIZE,
176
- LAST_RESORT_SIZE, LAST_RESORT_SIZE,
117
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
118
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
119
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
120
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
177
121
  FALLBACK_SIZE_A, FALLBACK_SIZE_B
178
122
  ];
179
123
 
180
- timesToGetTimeBeforeTimeout = 3;
181
-
182
124
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
183
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, fallbackBugBrowserInfo);
125
+ domHelper, fontFamily, fontDescription, browserInfo);
184
126
 
185
127
  fontWatchRunner.start();
186
128
 
187
- expect(asyncCount).toEqual(2);
129
+ jasmine.Clock.tick(4 * 25);
188
130
  expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
189
131
  });
190
132
 
191
- it('should call inactive when we are loading a metric incompatible font', function () {
192
- actualSizes = [
193
- LAST_RESORT_SIZE, LAST_RESORT_SIZE,
194
- LAST_RESORT_SIZE, LAST_RESORT_SIZE
195
- ];
133
+ describe('WebKit fallback bug', function () {
134
+ it('should ignore fallback size and call active', function () {
135
+ actualSizes = [
136
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
137
+ TARGET_SIZE, TARGET_SIZE
138
+ ];
196
139
 
197
- timesToGetTimeBeforeTimeout = 2;
140
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
141
+ domHelper, fontFamily, fontDescription, fallbackBugBrowserInfo);
198
142
 
199
- var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
200
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, fallbackBugBrowserInfo,
201
- 0, { 'My Other Family': true });
143
+ fontWatchRunner.start();
202
144
 
203
- fontWatchRunner.start();
204
- expect(asyncCount).toEqual(1);
205
- expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
145
+ jasmine.Clock.tick(1 * 25);
146
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
147
+ });
148
+
149
+ it('should consider last resort font as having identical metrics and call active', function () {
150
+ actualSizes = [
151
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
152
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE
153
+ ];
154
+
155
+ timesToGetTimeBeforeTimeout = 2;
156
+
157
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
158
+ domHelper, fontFamily, fontDescription, fallbackBugBrowserInfo);
159
+
160
+ fontWatchRunner.start();
161
+
162
+ jasmine.Clock.tick(1 * 25);
163
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
164
+ });
165
+
166
+ it('should fail to load font and call inactive', function () {
167
+ actualSizes = [
168
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
169
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
170
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B
171
+ ];
172
+
173
+ timesToGetTimeBeforeTimeout = 3;
174
+
175
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
176
+ domHelper, fontFamily, fontDescription, fallbackBugBrowserInfo);
177
+
178
+ fontWatchRunner.start();
179
+
180
+ jasmine.Clock.tick(2 * 25);
181
+ expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
182
+ });
183
+
184
+ it('should call inactive when we are loading a metric incompatible font', function () {
185
+ actualSizes = [
186
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
187
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE
188
+ ];
189
+
190
+ timesToGetTimeBeforeTimeout = 2;
191
+
192
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
193
+ domHelper, fontFamily, fontDescription, fallbackBugBrowserInfo,
194
+ 0, { 'My Other Family': true });
195
+
196
+ fontWatchRunner.start();
197
+
198
+ jasmine.Clock.tick(1 * 25);
199
+ expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
200
+ });
201
+
202
+ it('should call active when we are loading a metric compatible font', function () {
203
+ actualSizes = [
204
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
205
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE
206
+ ];
207
+
208
+ timesToGetTimeBeforeTimeout = 2;
209
+
210
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
211
+ domHelper, fontFamily, fontDescription, fallbackBugBrowserInfo,
212
+ 0, { 'My Family': true });
213
+
214
+ fontWatchRunner.start();
215
+
216
+ jasmine.Clock.tick(1 * 25);
217
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
218
+ });
206
219
  });
207
220
 
208
- it('should call active when we are loading a metric compatible font', function () {
209
- actualSizes = [
210
- LAST_RESORT_SIZE, LAST_RESORT_SIZE,
211
- LAST_RESORT_SIZE, LAST_RESORT_SIZE
212
- ];
221
+ describe('webkit metrics bug', function () {
222
+ it('should correctly call active even though the height is different', function () {
223
+ actualSizes = [
224
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
225
+ new Size(1, 2), new Size(2, 3), // Same as FALLBACK_SIZE_A and FALLBACK_SIZE_B except that the height is different.
226
+ TARGET_SIZE, TARGET_SIZE
227
+ ];
213
228
 
214
- timesToGetTimeBeforeTimeout = 2;
229
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
230
+ domHelper, fontFamily, fontDescription, new BrowserInfo(true, false, true));
215
231
 
216
- var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
217
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, fallbackBugBrowserInfo,
218
- 0, { 'My Family': true });
232
+ fontWatchRunner.start();
219
233
 
220
- fontWatchRunner.start();
221
- expect(asyncCount).toEqual(1);
222
- expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
234
+ jasmine.Clock.tick(2 * 25);
235
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
236
+ });
223
237
  });
224
- });
225
238
 
226
- describe('webkit metrics bug', function () {
227
- it('should correctly call active even though the height is different', function () {
228
- actualSizes = [
229
- FALLBACK_SIZE_A, FALLBACK_SIZE_B,
230
- new Size(1, 2), new Size(2, 3), // Same as FALLBACK_SIZE_A and FALLBACK_SIZE_B except that the height is different.
231
- TARGET_SIZE, TARGET_SIZE
232
- ];
239
+ describe('test string', function () {
240
+ var fontWatchRunner = null;
233
241
 
234
- var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
235
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, new BrowserInfo(true, false, true));
242
+ beforeEach(function () {
243
+ spyOn(domHelper, 'createElement').andCallThrough();
244
+ });
236
245
 
237
- fontWatchRunner.start();
246
+ it('should be the default', function () {
247
+ actualSizes = [
248
+ TARGET_SIZE, TARGET_SIZE
249
+ ];
250
+ fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
251
+ domHelper, fontFamily, fontDescription, browserInfo);
238
252
 
239
- expect(asyncCount).toEqual(2);
240
- expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
253
+ fontWatchRunner.start();
254
+
255
+ jasmine.Clock.tick(1 * 25);
256
+ expect(domHelper.createElement.mostRecentCall.args[2]).toEqual('BESbswy');
257
+ });
258
+
259
+ it('should be a custom string', function () {
260
+ actualSizes = [
261
+ TARGET_SIZE, TARGET_SIZE
262
+ ];
263
+
264
+ fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
265
+ domHelper, fontFamily, fontDescription, browserInfo, 0, {}, 'TestString');
266
+
267
+ fontWatchRunner.start();
268
+
269
+ jasmine.Clock.tick(1 * 25);
270
+ expect(domHelper.createElement.mostRecentCall.args[2]).toEqual('TestString');
271
+ });
241
272
  });
242
273
  });
243
274
 
244
275
  describe('real browser testing', function () {
245
- var fontSizer = null,
246
- asyncCall = null,
247
- getTime = null,
248
- userAgent = null;
276
+ var userAgent = null;
249
277
 
250
278
  beforeEach(function () {
251
279
  var userAgentParser = new UserAgentParser(window.navigator.userAgent, window.document);
252
280
 
253
281
  userAgent = userAgentParser.parse();
254
-
255
- fontSizer = {
256
- getSize: function (el) {
257
- return new Size(el.offsetWidth, el.offsetHeight);
258
- }
259
- };
260
-
261
- asyncCall = function (func, timeout) {
262
- window.setTimeout(func, timeout);
263
- };
264
-
265
- getTime = function () {
266
- return new Date().getTime();
267
- };
268
282
  });
269
283
 
270
284
  it('should fail to load a null font', function () {
271
285
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
272
- domHelper, fontSizer, asyncCall, getTime, '__webfontloader_test__', '',
273
- userAgent.getBrowserInfo(), 500);
286
+ domHelper, '__webfontloader_test__', '', userAgent.getBrowserInfo(), 500);
274
287
 
275
288
  runs(function () {
276
289
  fontWatchRunner.start();
@@ -287,9 +300,8 @@ describe('FontWatchRunner', function () {
287
300
 
288
301
  it('should load font succesfully', function () {
289
302
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
290
- domHelper, fontSizer, asyncCall, getTime, 'SourceSansA', '',
291
- userAgent.getBrowserInfo(), 500),
292
- ruler = new FontRuler(domHelper, fontSizer, 'abcdef'),
303
+ domHelper, 'SourceSansA', '', userAgent.getBrowserInfo(), 500),
304
+ ruler = new FontRuler(domHelper, 'abcdef'),
293
305
  activeSize = null,
294
306
  originalSize = null,
295
307
  finalCheck = false;
@@ -328,8 +340,7 @@ describe('FontWatchRunner', function () {
328
340
 
329
341
  it('should attempt to load a non-existing font', function () {
330
342
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
331
- domHelper, fontSizer, asyncCall, getTime, 'Elena', '',
332
- userAgent.getBrowserInfo(), 500);
343
+ domHelper, 'Elena', '', userAgent.getBrowserInfo(), 500);
333
344
 
334
345
  runs(function () {
335
346
  fontWatchRunner.start();
@@ -346,9 +357,8 @@ describe('FontWatchRunner', function () {
346
357
 
347
358
  it('should load even if @font-face is inserted after watching has started', function () {
348
359
  var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
349
- domHelper, fontSizer, asyncCall, getTime, 'SourceSansB', '',
350
- userAgent.getBrowserInfo(), 500),
351
- ruler = new FontRuler(domHelper, fontSizer, 'abcdef'),
360
+ domHelper, 'SourceSansB', '', userAgent.getBrowserInfo(), 500),
361
+ ruler = new FontRuler(domHelper, 'abcdef'),
352
362
  activeSize = null,
353
363
  originalSize = null,
354
364
  finalCheck = false;
@@ -364,7 +374,7 @@ describe('FontWatchRunner', function () {
364
374
  link.rel = "stylesheet";
365
375
  link.href= "fonts/sourcesansb.css";
366
376
 
367
- document.head.appendChild(link);
377
+ domHelper.insertInto('head', link);
368
378
  });
369
379
 
370
380
  waitsFor(function () {
@@ -391,39 +401,4 @@ describe('FontWatchRunner', function () {
391
401
  });
392
402
  });
393
403
  });
394
-
395
- describe('test string', function () {
396
- var fontWatchRunner = null;
397
-
398
- beforeEach(function () {
399
- spyOn(domHelper, 'createElement').andCallThrough();
400
- });
401
-
402
- it('should be the default', function () {
403
- actualSizes = [
404
- TARGET_SIZE, TARGET_SIZE
405
- ];
406
-
407
- fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
408
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, browserInfo);
409
-
410
- fontWatchRunner.start();
411
-
412
- expect(domHelper.createElement.mostRecentCall.args[2]).toEqual('BESbswy');
413
- });
414
-
415
- it('should be a custom string', function () {
416
- actualSizes = [
417
- TARGET_SIZE, TARGET_SIZE
418
- ];
419
-
420
- fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
421
- domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily,
422
- fontDescription, browserInfo, 0, {}, 'TestString');
423
-
424
- fontWatchRunner.start();
425
-
426
- expect(domHelper.createElement.mostRecentCall.args[2]).toEqual('TestString');
427
- });
428
- });
429
404
  });