webfontloader 1.2.0 → 1.2.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 (74) hide show
  1. data/CHANGELOG +9 -0
  2. data/Gemfile +2 -8
  3. data/README.md +31 -32
  4. data/Rakefile +2 -33
  5. data/docs/EVENTS.md +10 -1
  6. data/docs/MODULES.md +4 -3
  7. data/lib/webfontloader.rb +1 -1
  8. data/spec/ascender/ascenderscript_spec.js +43 -0
  9. data/spec/core/cssclassname_spec.js +42 -0
  10. data/spec/core/cssfontfamilyname_spec.js +38 -0
  11. data/spec/core/domhelper_spec.js +158 -0
  12. data/spec/core/eventdispatcher_spec.js +209 -0
  13. data/spec/core/font_spec.js +218 -0
  14. data/spec/core/fontmoduleloader_spec.js +55 -0
  15. data/spec/core/fontruler_spec.js +33 -0
  16. data/spec/core/fontvariationdescription_spec.js +67 -0
  17. data/spec/core/fontwatcher_spec.js +204 -0
  18. data/spec/core/fontwatchrunner_spec.js +398 -0
  19. data/spec/core/size_spec.js +17 -0
  20. data/spec/core/useragentparser_spec.js +921 -0
  21. data/spec/custom/customcss_spec.js +36 -0
  22. data/spec/fontdeck/fontdeckscript_spec.js +111 -0
  23. data/spec/fonts/LICENSE.txt +93 -0
  24. data/spec/fonts/nullfont.css +1 -0
  25. data/spec/fonts/nullfont1.css +1 -0
  26. data/spec/fonts/nullfont2.css +1 -0
  27. data/spec/fonts/nullfont3.css +1 -0
  28. data/spec/fonts/sourcesans.eot +0 -0
  29. data/spec/fonts/sourcesans.otf +0 -0
  30. data/spec/fonts/sourcesans.svg +2523 -0
  31. data/spec/fonts/sourcesans.ttf +0 -0
  32. data/spec/fonts/sourcesans.woff +0 -0
  33. data/spec/fonts/sourcesansa.css +1 -0
  34. data/spec/fonts/sourcesansb.css +1 -0
  35. data/spec/google/fontapiparser_spec.js +348 -0
  36. data/spec/google/fontapiurlbuilder_spec.js +40 -0
  37. data/spec/google/googlefontapi_spec.js +123 -0
  38. data/spec/google/lastresortwebkitfontwatchrunner_spec.js +145 -0
  39. data/spec/index.html +95 -0
  40. data/spec/monotype/monotypescript_spec.js +49 -0
  41. data/spec/typekit/typekitscript_spec.js +93 -0
  42. data/src/core/domhelper.js +6 -3
  43. data/src/core/fontruler.js +1 -1
  44. data/src/core/fontwatcher.js +5 -0
  45. data/src/core/fontwatchrunner.js +7 -4
  46. data/src/monotype/monotype_script.js +4 -3
  47. data/tools/jasmine-phantomjs/jasmine-phantomjs.js +26 -0
  48. data/tools/jasmine-phantomjs/terminal-reporter.js +177 -0
  49. data/tools/jasmine/MIT.LICENSE +20 -0
  50. data/tools/jasmine/jasmine-html.js +681 -0
  51. data/tools/jasmine/jasmine.css +82 -0
  52. data/tools/jasmine/jasmine.js +2600 -0
  53. data/webfontloader.gemspec +46 -25
  54. metadata +77 -42
  55. data/src-test/ascender/ascender_script_test.js +0 -51
  56. data/src-test/core/cssclassnametest.js +0 -42
  57. data/src-test/core/cssfontfamilynametest.js +0 -54
  58. data/src-test/core/domhelpertest.js +0 -151
  59. data/src-test/core/eventdispatchertest.js +0 -275
  60. data/src-test/core/fontmoduleloadertest.js +0 -30
  61. data/src-test/core/fonttest.js +0 -121
  62. data/src-test/core/fontvariationdescriptiontest.js +0 -76
  63. data/src-test/core/fontwatchertest.js +0 -287
  64. data/src-test/core/fontwatchrunnertest.js +0 -454
  65. data/src-test/core/useragenttest.js +0 -755
  66. data/src-test/custom/customcsstest.js +0 -35
  67. data/src-test/fontdeck/fontdeck_script_test.js +0 -116
  68. data/src-test/google/fontapiparsertest.js +0 -252
  69. data/src-test/google/fontapiurlbuildertest.js +0 -71
  70. data/src-test/google/googlefontapitest.js +0 -185
  71. data/src-test/google/lastresortwebkitfontwatchrunnertest.js +0 -204
  72. data/src-test/monotype/monotype_script_test.js +0 -304
  73. data/src-test/typekit/typekit_script_test.js +0 -195
  74. data/tools/jstestdriver/JsTestDriver-1.2.1.jar +0 -0
@@ -0,0 +1,33 @@
1
+ describe('FontRuler', function () {
2
+ var FontRuler = webfont.FontRuler,
3
+ DomHelper = webfont.DomHelper,
4
+ Size = webfont.Size,
5
+ domHelper = null,
6
+ fontSizer = null;
7
+
8
+ beforeEach(function () {
9
+ domHelper = new DomHelper(window);
10
+
11
+ fontSizer = {
12
+ getSize: function (el) {
13
+ return new Size(el.offsetWidth, el.offsetHeight);
14
+ }
15
+ };
16
+ });
17
+
18
+ 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!');
21
+
22
+ fontRulerA.insert();
23
+ fontRulerB.insert();
24
+
25
+ fontRulerA.setFont('sans-serif');
26
+ fontRulerB.setFont('sans-serif');
27
+
28
+ var sizeA = fontRulerA.getSize(),
29
+ sizeB = fontRulerB.getSize();
30
+
31
+ expect(sizeA.height).toEqual(sizeB.height);
32
+ });
33
+ });
@@ -0,0 +1,67 @@
1
+ describe('FontVariationDescription', function () {
2
+ var FontVariationDescription = webfont.FontVariationDescription,
3
+ fvd = new FontVariationDescription();
4
+
5
+ describe('#compact', function () {
6
+ it('should default to n4 when there is no description', function () {
7
+ expect(fvd.compact('')).toEqual('n4');
8
+ });
9
+
10
+ it('should compact font style', function () {
11
+ expect(fvd.compact('font-style: normal;')).toEqual('n4');
12
+ expect(fvd.compact('font-style: italic;')).toEqual('i4');
13
+ expect(fvd.compact('font-style: oblique;')).toEqual('o4');
14
+ });
15
+
16
+ it('should return the default value when font-style is incorrect', function () {
17
+ expect(fvd.compact('font-style: other;')).toEqual('n4');
18
+ });
19
+
20
+ it('should compact font weight', function () {
21
+ expect(fvd.compact('font-weight: normal;')).toEqual('n4');
22
+ expect(fvd.compact('font-weight: bold;')).toEqual('n7');
23
+ for (var i = 1; i < 10; i += 1) {
24
+ expect(fvd.compact('font-weight: ' + (i * 100) + ';')).toEqual('n' + i);
25
+ }
26
+ });
27
+
28
+ it('should return the default value when font-weight is incorrect', function () {
29
+ expect(fvd.compact('font-weight: 140;')).toEqual('n4');
30
+ expect(fvd.compact('font-weight: other;')).toEqual('n4');
31
+ });
32
+
33
+ it('should compact multiple properties', function () {
34
+ expect(fvd.compact('font-weight: bold; font-style: italic;')).toEqual('i7');
35
+ expect(fvd.compact('; font-weight: bold; font-style: italic;')).toEqual('i7');
36
+ expect(fvd.compact('font-style:italic;font-weight:bold;')).toEqual('i7');
37
+ expect(fvd.compact(' font-style: italic ;\n\nfont-weight: bold; ')).toEqual('i7');
38
+ });
39
+
40
+ it('should return default values for incorrect individual properties', function () {
41
+ expect(fvd.compact('src: url(/font.otf)')).toEqual('n4');
42
+ expect(fvd.compact('font-weight: 900; src: url(/font.otf);')).toEqual('n9');
43
+ expect(fvd.compact('font-weight: 800; font-stretch:condensed;')).toEqual('n8');
44
+ });
45
+ });
46
+
47
+ describe('#expand', function () {
48
+ it('should expand font-style', function () {
49
+ expect(fvd.expand('n4')).toEqual('font-style:normal;font-weight:400;');
50
+ expect(fvd.expand('i4')).toEqual('font-style:italic;font-weight:400;');
51
+ expect(fvd.expand('o4')).toEqual('font-style:oblique;font-weight:400;');
52
+ });
53
+
54
+ it('should expand weights correctly', function () {
55
+ for (var i = 1; i < 10; i += 1) {
56
+ expect(fvd.expand('n' + i)).toEqual('font-style:normal;font-weight:' + (i * 100) + ';');
57
+ }
58
+ });
59
+
60
+ it('should not expand incorrect input', function () {
61
+ expect(fvd.expand('')).toBeNull();
62
+ expect(fvd.expand('n')).toBeNull();
63
+ expect(fvd.expand('1')).toBeNull();
64
+ expect(fvd.expand('n1x')).toBeNull();
65
+ });
66
+ });
67
+ });
@@ -0,0 +1,204 @@
1
+ describe('FontWatcher', function () {
2
+ var FontWatcher = webfont.FontWatcher,
3
+ UserAgent = webfont.UserAgent,
4
+ BrowserInfo = webfont.BrowserInfo,
5
+ DomHelper = webfont.DomHelper,
6
+ domHelper = new DomHelper(window),
7
+ eventDispatcher = {},
8
+ testStrings = null,
9
+ userAgent = null,
10
+ activeFontFamilies = [];
11
+
12
+ beforeEach(function () {
13
+ userAgent = new UserAgent('Firefox', '3.6', 'Gecko', '1.9.3', 'Macintosh', '10.6', undefined, new BrowserInfo(true, false));
14
+ activeFontFamilies = [];
15
+ testStrings = jasmine.createSpy('testStrings');
16
+ eventDispatcher.dispatchLoading = jasmine.createSpy('dispatchLoading');
17
+ eventDispatcher.dispatchFontLoading = jasmine.createSpy('dispatchFontLoading');
18
+ eventDispatcher.dispatchFontActive = jasmine.createSpy('dispatchFontActive');
19
+ eventDispatcher.dispatchFontInactive = jasmine.createSpy('dispatchFontInactive');
20
+ eventDispatcher.dispatchActive = jasmine.createSpy('dispatchActive');
21
+ eventDispatcher.dispatchInactive = jasmine.createSpy('dispatchInactive');
22
+ });
23
+
24
+ function FakeFontWatchRunner(activeCallback, inactiveCallback, domHelper, fontSizer, asyncCall, getTime,
25
+ fontFamily, fontDescription, hasWebKitFallbackBug, opt_metricCompatibleFonts, opt_fontTestString) {
26
+ this.activeCallback = activeCallback;
27
+ this.inactiveCallback = inactiveCallback;
28
+ this.fontFamily = fontFamily;
29
+ this.fontDescription = fontDescription;
30
+
31
+ if (opt_fontTestString) {
32
+ testStrings(opt_fontTestString);
33
+ }
34
+ }
35
+
36
+ FakeFontWatchRunner.prototype.start = function () {
37
+ if (activeFontFamilies.indexOf(this.fontFamily) > -1) {
38
+ this.activeCallback(this.fontFamily, this.fontDescription);
39
+ } else {
40
+ this.inactiveCallback(this.fontFamily, this.fontDescription);
41
+ }
42
+ };
43
+
44
+ describe('watch zero fonts', function () {
45
+ it('should call inactive when there are no fonts to load', function () {
46
+ activeFontFamilies = [];
47
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
48
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
49
+
50
+ fontWatcher.watch([], {}, {}, FakeFontWatchRunner, true);
51
+ expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
52
+ });
53
+ });
54
+
55
+ describe('watch one font not last', function () {
56
+ it('should not call font inactive, inactive or active', function () {
57
+ activeFontFamilies = ['fontFamily1'];
58
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
59
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
60
+
61
+ fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, false);
62
+ expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
63
+ expect(eventDispatcher.dispatchActive).not.toHaveBeenCalled();
64
+ expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
65
+ });
66
+ });
67
+
68
+ describe('watch one font active', function () {
69
+ it('should call font active and active', function () {
70
+ activeFontFamilies = ['fontFamily1'];
71
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
72
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
73
+
74
+ fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, true);
75
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
76
+ expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith('fontFamily1', 'n4');
77
+ expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
78
+ expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
79
+ expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
80
+ });
81
+ });
82
+
83
+ describe('watch one font inactive', function () {
84
+ it('should call inactive', function () {
85
+ activeFontFamilies = [];
86
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
87
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
88
+
89
+ fontWatcher.watch(['fontFamily1'], {}, {}, FakeFontWatchRunner, true);
90
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
91
+ expect(eventDispatcher.dispatchFontActive).not.toHaveBeenCalled();
92
+ expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith('fontFamily1', 'n4');
93
+ expect(eventDispatcher.dispatchActive).not.toHaveBeenCalled();
94
+ expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
95
+ });
96
+ });
97
+
98
+ describe('watch multiple fonts active', function () {
99
+ it('should call font active and active', function () {
100
+ activeFontFamilies = ['fontFamily1', 'fontFamily2', 'fontFamily3'];
101
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
102
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
103
+
104
+ fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {}, {}, FakeFontWatchRunner, true);
105
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
106
+ expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith('fontFamily1', 'n4');
107
+ expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
108
+ expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
109
+ expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
110
+ });
111
+ });
112
+
113
+ describe('watch multiple fonts inactive', function () {
114
+ it('should call inactive', function () {
115
+ activeFontFamilies = [];
116
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
117
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
118
+
119
+ fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {}, {}, FakeFontWatchRunner, true);
120
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'n4');
121
+ expect(eventDispatcher.dispatchFontActive).not.toHaveBeenCalled();
122
+ expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith('fontFamily1', 'n4');
123
+ expect(eventDispatcher.dispatchActive).not.toHaveBeenCalled();
124
+ expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
125
+ });
126
+ });
127
+
128
+ describe('watch multiple fonts mixed', function () {
129
+ it('should call the correct callbacks', function () {
130
+ activeFontFamilies = ['fontFamily1', 'fontFamily3'];
131
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
132
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
133
+
134
+ fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {}, {}, FakeFontWatchRunner, true);
135
+ expect(eventDispatcher.dispatchFontLoading.callCount).toEqual(3);
136
+ expect(eventDispatcher.dispatchFontLoading.calls[0].args[0]).toEqual('fontFamily1');
137
+ expect(eventDispatcher.dispatchFontLoading.calls[1].args[0]).toEqual('fontFamily2');
138
+ expect(eventDispatcher.dispatchFontLoading.calls[2].args[0]).toEqual('fontFamily3');
139
+
140
+ expect(eventDispatcher.dispatchFontActive.callCount).toEqual(2);
141
+ expect(eventDispatcher.dispatchFontActive.calls[0].args[0]).toEqual('fontFamily1');
142
+ expect(eventDispatcher.dispatchFontActive.calls[1].args[0]).toEqual('fontFamily3');
143
+
144
+ expect(eventDispatcher.dispatchFontInactive.callCount).toEqual(1);
145
+ expect(eventDispatcher.dispatchFontInactive.calls[0].args[0]).toEqual('fontFamily2');
146
+
147
+ expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
148
+ expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
149
+ });
150
+ });
151
+
152
+ describe('watch multiple fonts with descriptions', function () {
153
+ it('should call the correct callbacks', function () {
154
+ activeFontFamilies = ['fontFamily1', 'fontFamily2'];
155
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
156
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
157
+
158
+ fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3'], {
159
+ 'fontFamily1': ['i7'],
160
+ 'fontFamily2': null,
161
+ 'fontFamily3': ['n4', 'i4', 'n7']
162
+ }, {}, FakeFontWatchRunner, true);
163
+
164
+ expect(eventDispatcher.dispatchFontLoading.callCount).toEqual(5);
165
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily1', 'i7');
166
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily2', 'n4');
167
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily3', 'n4');
168
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily3', 'i4');
169
+ expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith('fontFamily3', 'n7');
170
+
171
+ expect(eventDispatcher.dispatchFontActive.callCount).toEqual(2);
172
+ expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith('fontFamily1', 'i7');
173
+ expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith('fontFamily2', 'n4');
174
+
175
+ expect(eventDispatcher.dispatchFontInactive.callCount).toEqual(3);
176
+ expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith('fontFamily3', 'n4');
177
+ expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith('fontFamily3', 'i4');
178
+ expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith('fontFamily3', 'n7');
179
+
180
+ expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
181
+ expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
182
+ });
183
+ });
184
+
185
+ describe('watch multiple fonts with test strings', function () {
186
+ it('should use the correct tests strings', function () {
187
+ activeFontFamilies = ['fontFamily1', 'fontFamily2'];
188
+
189
+ var fontWatcher = new FontWatcher(userAgent, domHelper, eventDispatcher, jasmine.createSpy('fakeFontSizer'),
190
+ jasmine.createSpy('fakeAsyncCall'), jasmine.createSpy('fakeGetTime'));
191
+
192
+ fontWatcher.watch(['fontFamily1', 'fontFamily2', 'fontFamily3', 'fontFamily4'], {}, {
193
+ 'fontFamily1': 'testString1',
194
+ 'fontFamily2': null,
195
+ 'fontFamily3': 'testString2',
196
+ 'fontFamily4': null
197
+ }, FakeFontWatchRunner, true);
198
+
199
+ expect(testStrings.callCount).toEqual(2);
200
+ expect(testStrings).toHaveBeenCalledWith('testString1');
201
+ expect(testStrings).toHaveBeenCalledWith('testString2');
202
+ });
203
+ });
204
+ });
@@ -0,0 +1,398 @@
1
+ describe('FontWatchRunner', function () {
2
+ var FontWatchRunner = webfont.FontWatchRunner,
3
+ UserAgentParser = webfont.UserAgentParser,
4
+ Size = webfont.Size,
5
+ DomHelper = webfont.DomHelper,
6
+ FontRuler = webfont.FontRuler,
7
+ domHelper = new DomHelper(window),
8
+ fontFamily = 'My Family',
9
+ fontDescription = 'n4';
10
+
11
+ var timesToCheckSizeBeforeChange = 0,
12
+ TARGET_SIZE = new Size(3, 3),
13
+ FALLBACK_SIZE_A = new Size(1, 1),
14
+ FALLBACK_SIZE_B = new Size(2, 2),
15
+ LAST_RESORT_SIZE = new Size(4, 4),
16
+
17
+ setupSizes = [FALLBACK_SIZE_A, FALLBACK_SIZE_B, LAST_RESORT_SIZE],
18
+ actualSizes = [],
19
+ fakeGetSizeCount = 0,
20
+ setupFinished = false,
21
+ fakeFontSizer = {
22
+ getSize: function (el) {
23
+ var result = null;
24
+
25
+ if (setupFinished) {
26
+ // If you are getting an exception here your tests does not specify enough
27
+ // size data to run properly.
28
+ if (fakeGetSizeCount >= actualSizes.length) {
29
+ throw 'Invalid test data';
30
+ }
31
+ result = actualSizes[fakeGetSizeCount];
32
+ fakeGetSizeCount += 1;
33
+ } else {
34
+ result = setupSizes[Math.min(fakeGetSizeCount, setupSizes.length - 1)];
35
+ fakeGetSizeCount += 1;
36
+ }
37
+ return result;
38
+ }
39
+ },
40
+ timesToGetTimeBeforeTimeout = 10,
41
+ fakeGetTime = function () {
42
+ if (timesToGetTimeBeforeTimeout <= 0) {
43
+ return 6000;
44
+ } else {
45
+ timesToGetTimeBeforeTimeout -= 1;
46
+ return 1;
47
+ }
48
+ },
49
+ asyncCount = 0,
50
+ fakeAsyncCall = function (func, timeout) {
51
+ asyncCount += 1;
52
+ func();
53
+ },
54
+ setupFinished = false,
55
+ originalStartMethod = null,
56
+ activeCallback = null,
57
+ inactiveCallback = null;
58
+
59
+ beforeEach(function () {
60
+ actualSizes = [];
61
+ setupFinished = false;
62
+ fakeGetSizeCount = 0;
63
+
64
+ asyncCount = 0;
65
+ timesToGetTimeBeforeTimeout = 10;
66
+ activeCallback = jasmine.createSpy('activeCallback');
67
+ inactiveCallback = jasmine.createSpy('inactiveCallback');
68
+
69
+ originalStartMethod = FontWatchRunner.prototype.start;
70
+
71
+ FontWatchRunner.prototype.start = function () {
72
+ setupFinished = true;
73
+ fakeGetSizeCount = 0;
74
+ originalStartMethod.apply(this);
75
+ };
76
+ });
77
+
78
+ afterEach(function () {
79
+ FontWatchRunner.prototype.start = originalStartMethod;
80
+ });
81
+
82
+ it('should call active if fonts are already loaded', function () {
83
+ actualSizes = [
84
+ TARGET_SIZE, TARGET_SIZE
85
+ ];
86
+
87
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
88
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, false);
89
+
90
+ fontWatchRunner.start();
91
+
92
+ expect(asyncCount).toEqual(0);
93
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
94
+ });
95
+
96
+ it('should wait for font load and call active', function () {
97
+ actualSizes = [
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
102
+ ];
103
+
104
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
105
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, false);
106
+
107
+ fontWatchRunner.start();
108
+ expect(asyncCount).toEqual(3);
109
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
110
+ });
111
+
112
+ it('should wait for font inactive and call inactive', function () {
113
+ timesToGetTimeBeforeTimeout = 5;
114
+
115
+ actualSizes = [
116
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B,
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
121
+ ];
122
+
123
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
124
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, false);
125
+
126
+ fontWatchRunner.start();
127
+
128
+ expect(asyncCount).toEqual(4);
129
+ expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
130
+ });
131
+
132
+ describe('WebKit fallback bug', function () {
133
+ it('should ignore fallback size and call active', function () {
134
+ actualSizes = [
135
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
136
+ TARGET_SIZE, TARGET_SIZE
137
+ ];
138
+
139
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
140
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, true);
141
+
142
+ fontWatchRunner.start();
143
+
144
+ expect(asyncCount).toEqual(1);
145
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
146
+ });
147
+
148
+ it('should consider last resort font as having identical metrics and call active', function () {
149
+ actualSizes = [
150
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
151
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE
152
+ ];
153
+
154
+ timesToGetTimeBeforeTimeout = 2;
155
+
156
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
157
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, true);
158
+
159
+ fontWatchRunner.start();
160
+
161
+ expect(asyncCount).toEqual(1);
162
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
163
+ });
164
+
165
+ it('should fail to load font and call inactive', function () {
166
+ actualSizes = [
167
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
168
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
169
+ FALLBACK_SIZE_A, FALLBACK_SIZE_B
170
+ ];
171
+
172
+ timesToGetTimeBeforeTimeout = 3;
173
+
174
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
175
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, true);
176
+
177
+ fontWatchRunner.start();
178
+
179
+ expect(asyncCount).toEqual(2);
180
+ expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
181
+ });
182
+
183
+ it('should call inactive when we are loading a metric incompatible font', function () {
184
+ actualSizes = [
185
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
186
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE
187
+ ];
188
+
189
+ timesToGetTimeBeforeTimeout = 2;
190
+
191
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
192
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, true,
193
+ { 'My Other Family': true });
194
+
195
+ fontWatchRunner.start();
196
+ expect(asyncCount).toEqual(1);
197
+ expect(inactiveCallback).toHaveBeenCalledWith('My Family', 'n4');
198
+ });
199
+
200
+ it('should call active when we are loading a metric compatible font', function () {
201
+ actualSizes = [
202
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE,
203
+ LAST_RESORT_SIZE, LAST_RESORT_SIZE
204
+ ];
205
+
206
+ timesToGetTimeBeforeTimeout = 2;
207
+
208
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
209
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, true,
210
+ { 'My Family': true });
211
+
212
+ fontWatchRunner.start();
213
+ expect(asyncCount).toEqual(1);
214
+ expect(activeCallback).toHaveBeenCalledWith('My Family', 'n4');
215
+ });
216
+ });
217
+
218
+ describe('real browser testing', function () {
219
+ var fontSizer = null,
220
+ asyncCall = null,
221
+ getTime = null,
222
+ userAgent = null;
223
+
224
+ beforeEach(function () {
225
+ var userAgentParser = new UserAgentParser(window.navigator.userAgent, window.document);
226
+
227
+ userAgent = userAgentParser.parse();
228
+
229
+ fontSizer = {
230
+ getSize: function (el) {
231
+ return new Size(el.offsetWidth, el.offsetHeight);
232
+ }
233
+ };
234
+
235
+ asyncCall = function (func, timeout) {
236
+ window.setTimeout(func, timeout);
237
+ };
238
+
239
+ getTime = function () {
240
+ return new Date().getTime();
241
+ };
242
+ });
243
+
244
+ it('should fail to load a null font', function () {
245
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
246
+ domHelper, fontSizer, asyncCall, getTime, '__webfontloader_test__', '', userAgent.getBrowserInfo().hasWebKitFallbackBug());
247
+
248
+ runs(function () {
249
+ fontWatchRunner.start();
250
+ });
251
+
252
+ waitsFor(function () {
253
+ return activeCallback.wasCalled || inactiveCallback.wasCalled;
254
+ });
255
+
256
+ runs(function () {
257
+ expect(inactiveCallback).toHaveBeenCalledWith('__webfontloader_test__', '');
258
+ });
259
+ });
260
+
261
+ it('should load font succesfully', function () {
262
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
263
+ domHelper, fontSizer, asyncCall, getTime, 'SourceSansA', '', userAgent.getBrowserInfo().hasWebKitFallbackBug()),
264
+ ruler = new FontRuler(domHelper, fontSizer, 'abcdef'),
265
+ activeSize = null,
266
+ originalSize = null,
267
+ finalCheck = false;
268
+
269
+ runs(function () {
270
+ ruler.insert();
271
+ ruler.setFont('monospace');
272
+ originalSize = ruler.getSize();
273
+ ruler.setFont("'SourceSansA', monospace");
274
+ fontWatchRunner.start();
275
+ });
276
+
277
+ waitsFor(function () {
278
+ return activeCallback.wasCalled || inactiveCallback.wasCalled;
279
+ });
280
+
281
+ runs(function () {
282
+ expect(activeCallback).toHaveBeenCalledWith('SourceSansA', '');
283
+ activeSize = ruler.getSize();
284
+ expect(activeSize).not.toEqual(originalSize);
285
+
286
+ window.setTimeout(function () {
287
+ finalCheck = true;
288
+ }, 200);
289
+ });
290
+
291
+ waitsFor(function () {
292
+ return finalCheck;
293
+ });
294
+
295
+ runs(function () {
296
+ expect(ruler.getSize()).not.toEqual(originalSize);
297
+ expect(ruler.getSize()).toEqual(activeSize);
298
+ });
299
+ });
300
+
301
+ it('should attempt to load a non-existing font', function () {
302
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
303
+ domHelper, fontSizer, asyncCall, getTime, 'Elena', '', userAgent.getBrowserInfo().hasWebKitFallbackBug());
304
+
305
+ runs(function () {
306
+ fontWatchRunner.start();
307
+ });
308
+
309
+ waitsFor(function () {
310
+ return activeCallback.wasCalled || inactiveCallback.wasCalled;
311
+ });
312
+
313
+ runs(function () {
314
+ expect(inactiveCallback).toHaveBeenCalledWith('Elena', '');
315
+ });
316
+ });
317
+
318
+ it('should load even if @font-face is inserted after watching has started', function () {
319
+ var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
320
+ domHelper, fontSizer, asyncCall, getTime, 'SourceSansB', '', userAgent.getBrowserInfo().hasWebKitFallbackBug()),
321
+ ruler = new FontRuler(domHelper, fontSizer, 'abcdef'),
322
+ activeSize = null,
323
+ originalSize = null,
324
+ finalCheck = false;
325
+
326
+ runs(function () {
327
+ ruler.insert();
328
+ ruler.setFont('monospace');
329
+ originalSize = ruler.getSize();
330
+ ruler.setFont("'SourceSansB', monospace");
331
+ fontWatchRunner.start();
332
+ var link = document.createElement('link');
333
+
334
+ link.rel = "stylesheet";
335
+ link.href= "fonts/sourcesansb.css";
336
+
337
+ document.head.appendChild(link);
338
+ });
339
+
340
+ waitsFor(function () {
341
+ return activeCallback.wasCalled || inactiveCallback.wasCalled;
342
+ });
343
+
344
+ runs(function () {
345
+ expect(activeCallback).toHaveBeenCalledWith('SourceSansB', '');
346
+ activeSize = ruler.getSize();
347
+ expect(activeSize).not.toEqual(originalSize);
348
+
349
+ window.setTimeout(function () {
350
+ finalCheck = true;
351
+ }, 200);
352
+ });
353
+
354
+ waitsFor(function () {
355
+ return finalCheck;
356
+ });
357
+
358
+ runs(function () {
359
+ expect(ruler.getSize()).not.toEqual(originalSize);
360
+ expect(ruler.getSize()).toEqual(activeSize);
361
+ });
362
+ });
363
+ });
364
+
365
+ describe('test string', function () {
366
+ var fontWatchRunner = null;
367
+
368
+ beforeEach(function () {
369
+ spyOn(domHelper, 'createElement').andCallThrough();
370
+ });
371
+
372
+ it('should be the default', function () {
373
+ actualSizes = [
374
+ TARGET_SIZE, TARGET_SIZE
375
+ ];
376
+
377
+ fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
378
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, false);
379
+
380
+ fontWatchRunner.start();
381
+
382
+ expect(domHelper.createElement.mostRecentCall.args[2]).toEqual('BESbswy');
383
+ });
384
+
385
+ it('should be a custom string', function () {
386
+ actualSizes = [
387
+ TARGET_SIZE, TARGET_SIZE
388
+ ];
389
+
390
+ fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
391
+ domHelper, fakeFontSizer, fakeAsyncCall, fakeGetTime, fontFamily, fontDescription, false, {}, 'TestString');
392
+
393
+ fontWatchRunner.start();
394
+
395
+ expect(domHelper.createElement.mostRecentCall.args[2]).toEqual('TestString');
396
+ });
397
+ });
398
+ });