webfontloader 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ });