webfontloader 1.0.16 → 1.0.18

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ v1.0.18 (January 24, 2011)
2
+ * Improve behavior of CSS classes over multiple loads on a single page. (Documented in docs/EVENTS.md)
3
+ * Add support for international subsets in the Google module.
4
+ * Add a module for Fontdeck.
5
+
6
+ v1.0.17 (December 1, 2010)
7
+ * Changed CSS style for hidden span in order to be less affected by environment
8
+ * Removed restriction on iPhone/iPad/iPod in the google modules
9
+
1
10
  v1.0.16 (November 18, 2010)
2
11
  * Fix a bug where we fail to detect that fonts have loaded if they have the same width as the fallback font.
3
12
 
@@ -17,7 +17,7 @@ rescue LoadError => e
17
17
  abort "Please gem install vegas"
18
18
  end
19
19
 
20
- Vegas::Runner.new(WebFontLoader::Demo::Server, 'font-demos') do |runner, opts, app|
20
+ Vegas::Runner.new(WebFontLoader::Demo::Server, 'font-demos', :host => "localhost") do |runner, opts, app|
21
21
  opts.on('--compiled_js FILE', "Dynamically build the JS with the given modules") { |file|
22
22
  app.set :compiled_js, File.read(file)
23
23
  }
data/docs/EVENTS.md CHANGED
@@ -47,6 +47,40 @@ describing the style and weight of a particular font. Here are a few examples:
47
47
  If no style/weight is specified, the default "n4" (font-style: normal;
48
48
  font-weight: normal;) will be used.
49
49
 
50
+ If fonts are loaded multiple times on a single page, the CSS classes continue
51
+ to update to reflect the current state of the page. The global `wf-loading`
52
+ class is applied whenever fonts are being requested (even if other fonts are
53
+ already active or inactive). The `wf-inactive` class is applied only if none of
54
+ the fonts on the page have rendered. Otherwise, the `wf-active` class is applied
55
+ instead (even if some fonts are inactive).
56
+
57
+ Here's an example of CSS classes over multiple loads:
58
+
59
+ * Droid Sans n4 is requested
60
+ * The `html` element has `wf-loading wf-droidsans-n4-loading`
61
+ * Droid Sans n4 is detected as active
62
+ * The `html` element has `wf-active wf-droidsans-n4-active`
63
+ * Droid Sans n7 is subsequently requested
64
+ * The `html` element has `wf-active wf-loading wf-droidsans-n4-active
65
+ wf-droidsans-n7-loading`
66
+ * Droid Sans n7 is detected as active
67
+ * The `html` element has `wf-active wf-droidsans-n4-active
68
+ wf-droidsans-n7-active`
69
+
70
+ Here's another example of CSS classes over multiple loads when one of the
71
+ requested fonts is inactive:
72
+
73
+ * Droid Sans n9 is requested (which doesn't exist)
74
+ * The `html` element has `wf-loading wf-droidsans-n9-loading`
75
+ * Droid Sans n9 is detected as inactive
76
+ * The `html` element has `wf-inactive wf-droidsans-n9-inactive`
77
+ * Droid Sans n4 is subsequently requested
78
+ * The `html` element has `wf-inactive wf-loading wf-droidsans-n9-inactive
79
+ wf-droidsans-n4-loading`
80
+ * Droid Sans n4 is detected as active
81
+ * The `html` element has `wf-active wf-droidsans-n9-inactive
82
+ wf-droidsans-n4-active`
83
+
50
84
 
51
85
  ### JavaScript Flavored
52
86
 
data/docs/MODULES.md CHANGED
@@ -30,6 +30,18 @@ ID within Typekit's Kit Editor interface.
30
30
 
31
31
  Learn more about [Typekit][tk].
32
32
 
33
+ ## Fontdeck
34
+
35
+ To use Fontdeck, specify the ID of your website. You can find this ID on the
36
+ website page within your account settings.
37
+
38
+ WebFont.load({
39
+ fontdeck: {
40
+ id: 'xxxxx'
41
+ }
42
+ });
43
+
44
+ Learn more about [Fontdeck][fd].
33
45
 
34
46
  ## Custom
35
47
 
@@ -46,4 +58,5 @@ provides.
46
58
 
47
59
 
48
60
  [gfontapi]: https://code.google.com/apis/webfonts/docs/getting_started.html
49
- [tk]: http://typekit.com/
61
+ [tk]: http://typekit.com/
62
+ [fd]: http://fontdeck.com/
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.0.16'
6
+ VERSION = '1.0.18'
7
7
 
8
8
  ProjectRoot = File.expand_path(File.dirname(__FILE__) + "/..")
9
9
 
@@ -0,0 +1,75 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <link href="/basic.css" rel="stylesheet" type="text/css">
5
+ <script src="/webfont.js"></script>
6
+ <script>
7
+ function progress(message) {
8
+ var output = document.getElementById('events');
9
+ if (output) {
10
+ var e = document.createElement('li');
11
+ e.innerHTML = message;
12
+ output.appendChild(e);
13
+ }
14
+ if (window.console && window.console.log) {
15
+ window.console.log(message);
16
+ }
17
+ }
18
+ WebFont.load({
19
+ fontdeck: {
20
+ id: '2282'
21
+ },
22
+ loading: function() {
23
+ progress('loading');
24
+ },
25
+ active: function() {
26
+ progress('active');
27
+ },
28
+ inactive: function() {
29
+ progress('inactive');
30
+ },
31
+ fontloading: function(fontFamily, fontDescription) {
32
+ progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
33
+ },
34
+ fontactive: function(fontFamily, fontDescription) {
35
+ progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
36
+ },
37
+ fontinactive: function(fontFamily, fontDescription) {
38
+ progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
39
+ }
40
+ });
41
+ </script>
42
+ <style>
43
+ h1 {
44
+ font-family: 'Fertigo Pro Regular';
45
+ visibility: hidden;
46
+ }
47
+ h2 {
48
+ font-family: 'Bodoni Display Bold Italic';
49
+ font-weight: bold;
50
+ font-style: italic;
51
+ visibility: hidden;
52
+ }
53
+ .wf-fertigoproregular-n4-active h1,
54
+ .wf-bodonidisplaybolditalic-i7-active h2 {
55
+ visibility: visible;
56
+ }
57
+ </style>
58
+ </head>
59
+ <body>
60
+ <h1>Hello World. I am Fertigo Pro Regular.</h1>
61
+ <h2>Hello World. I am Bodoni Display Bold Italic.</h2>
62
+ <hr>
63
+ <p>
64
+ <a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
65
+ <a href="/fontdeck.html">Reload Cached</a>
66
+ </p>
67
+ <p>
68
+ The goal of this page is to show how Fontdeck fonts load.
69
+ </p>
70
+ <p>
71
+ You must use "localhost" when testing Fontdeck fonts.
72
+ </p>
73
+ <ol id="events"></ol>
74
+ </body>
75
+ </html>
@@ -24,6 +24,7 @@
24
24
  <li><a href="/typekit.html">Typekit / WebFont Loader</a>: Load fonts from Typekit with WebFont Loader.</li>
25
25
  <li><a href="/custom.html">Custom / WebFont Loader</a>: Load fonts from your own CSS with WebFont Loader.</li>
26
26
  <li><a href="/ascender.html">Ascender / WebFont Loader</a>: Load fonts from Ascender with WebFont Loader.</li>
27
+ <li><a href="/fontdeck.html">Fontdeck / WebFont Loader</a>: Load fonts from Fontdeck with WebFont Loader.</li>
27
28
  </ol>
28
29
 
29
30
  <h2>Events</h2>
@@ -7,31 +7,31 @@ CssFontFamilyNameTest.prototype.setUp = function() {
7
7
  CssFontFamilyNameTest.prototype.testSpaceNameWithoutQuotes = function() {
8
8
  var result = this.sanitizer_.quote('My Family');
9
9
 
10
- assertEquals('"My Family"', result);
10
+ assertEquals("'My Family'", result);
11
11
  };
12
12
 
13
13
  CssFontFamilyNameTest.prototype.testSpaceNameWithDoubleQuotes = function() {
14
14
  var result = this.sanitizer_.quote('"My Family"');
15
15
 
16
- assertEquals('"My Family"', result);
16
+ assertEquals("'My Family'", result);
17
17
  };
18
18
 
19
19
  CssFontFamilyNameTest.prototype.testSpaceNameWithSingleQuotes = function() {
20
20
  var result = this.sanitizer_.quote('\'My Family\'');
21
21
 
22
- assertEquals('"My Family"', result);
22
+ assertEquals("'My Family'", result);
23
23
  };
24
24
 
25
25
  CssFontFamilyNameTest.prototype.testSpaceNameWithCommasAndQuotes = function() {
26
26
  var result = this.sanitizer_.quote('\'family 1\',\'family 2\'');
27
27
 
28
- assertEquals('\"family 1\",\"family 2\"', result);
28
+ assertEquals("'family 1','family 2'", result);
29
29
  };
30
30
 
31
31
  CssFontFamilyNameTest.prototype.testSpaceNameWithCommaSpaceAndQuotes = function() {
32
32
  var result = this.sanitizer_.quote('\'family 1\', \'family 2\'');
33
33
 
34
- assertEquals('\"family 1\",\"family 2\"', result);
34
+ assertEquals("'family 1','family 2'", result);
35
35
  };
36
36
 
37
37
  CssFontFamilyNameTest.prototype.testNoSpaceNameWithoutQuotes = function() {
@@ -79,3 +79,15 @@ DomHelperTest.prototype.testAppendAndRemoveClassNames = function() {
79
79
  assertEquals('', div.className);
80
80
 
81
81
  };
82
+
83
+ DomHelperTest.prototype.testHasClassName = function() {
84
+ var div = this.domHelper_.createElement('div');
85
+
86
+ this.domHelper_.appendClassName(div, 'moo');
87
+ this.domHelper_.appendClassName(div, 'moo-meuh');
88
+
89
+ assertTrue(this.domHelper_.hasClassName(div, 'moo'));
90
+ assertTrue(this.domHelper_.hasClassName(div, 'moo-meuh'));
91
+ assertFalse(this.domHelper_.hasClassName(div, 'meuh'));
92
+ assertFalse(this.domHelper_.hasClassName(div, 'missingClassName'));
93
+ }
@@ -7,7 +7,7 @@ EventDispatcherTest.prototype.setUp = function() {
7
7
  this.fontLoading_ = '';
8
8
  this.fontActiveEventCalled_ = false;
9
9
  this.fontActive_ = '';
10
- this.fontInactvieEventCalled_ = false;
10
+ this.fontInactiveEventCalled_ = false;
11
11
  this.fontInactive_ = '';
12
12
  this.activeEventCalled_ = false;
13
13
  this.inactiveEventCalled_ = false;
@@ -34,7 +34,7 @@ EventDispatcherTest.prototype.setUp = function() {
34
34
  self.fontActive_ = fontFamily + ' ' + fontDescription;
35
35
  },
36
36
  fontinactive: function(fontFamily, fontDescription) {
37
- self.fontInactvieEventCalled_ = true;
37
+ self.fontInactiveEventCalled_ = true;
38
38
  self.fontInactive_ = fontFamily + ' ' + fontDescription;
39
39
  }
40
40
  }, namespace);
@@ -51,6 +51,19 @@ EventDispatcherTest.prototype.testClassNamesOnActiveLoad = function() {
51
51
  assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
52
52
  };
53
53
 
54
+ EventDispatcherTest.prototype.testEventsOnActiveLoad = function() {
55
+ this.eventDispatcher_.dispatchLoading();
56
+ assertTrue(this.loadingEventCalled_);
57
+ this.eventDispatcher_.dispatchFontLoading('fontFamilyLoading', 'n4');
58
+ assertTrue(this.fontLoadingEventCalled_);
59
+ assertEquals('fontFamilyLoading n4', this.fontLoading_);
60
+ this.eventDispatcher_.dispatchFontActive('fontFamilyActive', 'n4');
61
+ assertTrue(this.fontActiveEventCalled_);
62
+ assertEquals('fontFamilyActive n4', this.fontActive_);
63
+ this.eventDispatcher_.dispatchActive();
64
+ assertTrue(this.activeEventCalled_);
65
+ };
66
+
54
67
  EventDispatcherTest.prototype.testClassNamesOnInactiveFontButActive = function() {
55
68
  this.eventDispatcher_.dispatchLoading();
56
69
  assertEquals('ns-loading', this.fakeHtmlElement_.className);
@@ -62,19 +75,30 @@ EventDispatcherTest.prototype.testClassNamesOnInactiveFontButActive = function()
62
75
  assertEquals('ns-myfamily-n4-inactive ns-active', this.fakeHtmlElement_.className);
63
76
  };
64
77
 
65
- EventDispatcherTest.prototype.testEventsOnActiveLoad = function() {
78
+ EventDispatcherTest.prototype.testEventsOnInactiveFontButActive = function() {
66
79
  this.eventDispatcher_.dispatchLoading();
67
80
  assertTrue(this.loadingEventCalled_);
68
81
  this.eventDispatcher_.dispatchFontLoading('fontFamilyLoading', 'n4');
69
82
  assertTrue(this.fontLoadingEventCalled_);
70
83
  assertEquals('fontFamilyLoading n4', this.fontLoading_);
71
- this.eventDispatcher_.dispatchFontActive('fontFamilyActive', 'n4');
72
- assertTrue(this.fontActiveEventCalled_);
73
- assertEquals('fontFamilyActive n4', this.fontActive_);
84
+ this.eventDispatcher_.dispatchFontInactive('fontFamilyInactive', 'n4');
85
+ assertTrue(this.fontInactiveEventCalled_);
86
+ assertEquals('fontFamilyInactive n4', this.fontInactive_);
74
87
  this.eventDispatcher_.dispatchActive();
75
88
  assertTrue(this.activeEventCalled_);
76
89
  };
77
90
 
91
+ EventDispatcherTest.prototype.testClassNamesOnInactiveLoad = function() {
92
+ this.eventDispatcher_.dispatchLoading();
93
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
94
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
95
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
96
+ this.eventDispatcher_.dispatchFontInactive('My Family', 'n4');
97
+ assertEquals('ns-loading ns-myfamily-n4-inactive', this.fakeHtmlElement_.className);
98
+ this.eventDispatcher_.dispatchInactive();
99
+ assertEquals('ns-myfamily-n4-inactive ns-inactive', this.fakeHtmlElement_.className);
100
+ };
101
+
78
102
  EventDispatcherTest.prototype.testEventsOnInactiveLoad = function() {
79
103
  this.eventDispatcher_.dispatchLoading();
80
104
  assertTrue(this.loadingEventCalled_);
@@ -82,13 +106,42 @@ EventDispatcherTest.prototype.testEventsOnInactiveLoad = function() {
82
106
  assertTrue(this.fontLoadingEventCalled_);
83
107
  assertEquals('fontFamilyLoading n4', this.fontLoading_);
84
108
  this.eventDispatcher_.dispatchFontInactive('fontFamilyInactive', 'n4');
85
- assertTrue(this.fontInactvieEventCalled_);
109
+ assertTrue(this.fontInactiveEventCalled_);
86
110
  assertEquals('fontFamilyInactive n4', this.fontInactive_);
111
+ this.eventDispatcher_.dispatchInactive();
112
+ assertTrue(this.inactiveEventCalled_);
113
+ };
114
+
115
+ EventDispatcherTest.prototype.testClassNamesOnInactive = function() {
116
+ this.eventDispatcher_.dispatchInactive();
117
+ assertEquals('ns-inactive', this.fakeHtmlElement_.className);
118
+ };
119
+
120
+ EventDispatcherTest.prototype.testEventsOnInactive = function() {
121
+ this.eventDispatcher_.dispatchInactive();
122
+ assertTrue(this.inactiveEventCalled_);
123
+ };
124
+
125
+ EventDispatcherTest.prototype.testClassNamesOnInactiveThenActiveLoad = function() {
126
+ this.eventDispatcher_.dispatchLoading();
127
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
128
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
129
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
130
+ this.eventDispatcher_.dispatchFontInactive('My Family', 'n4');
131
+ assertEquals('ns-loading ns-myfamily-n4-inactive', this.fakeHtmlElement_.className);
132
+ this.eventDispatcher_.dispatchInactive();
133
+ assertEquals('ns-myfamily-n4-inactive ns-inactive', this.fakeHtmlElement_.className);
134
+ this.eventDispatcher_.dispatchLoading();
135
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading', this.fakeHtmlElement_.className);
136
+ this.eventDispatcher_.dispatchFontLoading('My Family 2', 'n4');
137
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading ns-myfamily2-n4-loading', this.fakeHtmlElement_.className);
138
+ this.eventDispatcher_.dispatchFontActive('My Family 2', 'n4');
139
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading ns-myfamily2-n4-active', this.fakeHtmlElement_.className);
87
140
  this.eventDispatcher_.dispatchActive();
88
- assertTrue(this.activeEventCalled_);
141
+ assertEquals('ns-myfamily-n4-inactive ns-myfamily2-n4-active ns-active', this.fakeHtmlElement_.className);
89
142
  };
90
143
 
91
- EventDispatcherTest.prototype.testClassNamesOnInactiveLoad = function() {
144
+ EventDispatcherTest.prototype.testClassNamesOnInactiveThenActiveLoadSameFont = function() {
92
145
  this.eventDispatcher_.dispatchLoading();
93
146
  assertEquals('ns-loading', this.fakeHtmlElement_.className);
94
147
  this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
@@ -97,14 +150,126 @@ EventDispatcherTest.prototype.testClassNamesOnInactiveLoad = function() {
97
150
  assertEquals('ns-loading ns-myfamily-n4-inactive', this.fakeHtmlElement_.className);
98
151
  this.eventDispatcher_.dispatchInactive();
99
152
  assertEquals('ns-myfamily-n4-inactive ns-inactive', this.fakeHtmlElement_.className);
153
+ this.eventDispatcher_.dispatchLoading();
154
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading', this.fakeHtmlElement_.className);
155
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
156
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
157
+ this.eventDispatcher_.dispatchFontActive('My Family', 'n4');
158
+ assertEquals('ns-inactive ns-loading ns-myfamily-n4-active', this.fakeHtmlElement_.className);
159
+ this.eventDispatcher_.dispatchActive();
160
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
100
161
  };
101
162
 
102
- EventDispatcherTest.prototype.testClassNamesOnInactive = function() {
163
+ EventDispatcherTest.prototype.testClassNamesOnActiveThenInactiveLoad = function() {
164
+ this.eventDispatcher_.dispatchLoading();
165
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
166
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
167
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
168
+ this.eventDispatcher_.dispatchFontActive('My Family', 'n4');
169
+ assertEquals('ns-loading ns-myfamily-n4-active', this.fakeHtmlElement_.className);
170
+ this.eventDispatcher_.dispatchActive();
171
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
172
+ this.eventDispatcher_.dispatchLoading();
173
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading', this.fakeHtmlElement_.className);
174
+ this.eventDispatcher_.dispatchFontLoading('My Family 2', 'n4');
175
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading ns-myfamily2-n4-loading', this.fakeHtmlElement_.className);
176
+ this.eventDispatcher_.dispatchFontInactive('My Family 2', 'n4');
177
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading ns-myfamily2-n4-inactive', this.fakeHtmlElement_.className);
103
178
  this.eventDispatcher_.dispatchInactive();
104
- assertEquals('ns-inactive', this.fakeHtmlElement_.className);
179
+ assertEquals('ns-myfamily-n4-active ns-active ns-myfamily2-n4-inactive', this.fakeHtmlElement_.className);
105
180
  };
106
181
 
107
- EventDispatcherTest.prototype.testEventsOnInactive = function() {
182
+ EventDispatcherTest.prototype.testClassNamesOnActiveThenInactiveLoadSameFont = function() {
183
+ this.eventDispatcher_.dispatchLoading();
184
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
185
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
186
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
187
+ this.eventDispatcher_.dispatchFontActive('My Family', 'n4');
188
+ assertEquals('ns-loading ns-myfamily-n4-active', this.fakeHtmlElement_.className);
189
+ this.eventDispatcher_.dispatchActive();
190
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
191
+ this.eventDispatcher_.dispatchLoading();
192
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading', this.fakeHtmlElement_.className);
193
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
194
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
195
+ this.eventDispatcher_.dispatchFontInactive('My Family', 'n4');
196
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading', this.fakeHtmlElement_.className);
108
197
  this.eventDispatcher_.dispatchInactive();
109
- assertTrue(this.inactiveEventCalled_);
198
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
199
+ };
200
+
201
+ EventDispatcherTest.prototype.testClassNamesOnActiveThenActiveLoad = function() {
202
+ this.eventDispatcher_.dispatchLoading();
203
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
204
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
205
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
206
+ this.eventDispatcher_.dispatchFontActive('My Family', 'n4');
207
+ assertEquals('ns-loading ns-myfamily-n4-active', this.fakeHtmlElement_.className);
208
+ this.eventDispatcher_.dispatchActive();
209
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
210
+ this.eventDispatcher_.dispatchLoading();
211
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading', this.fakeHtmlElement_.className);
212
+ this.eventDispatcher_.dispatchFontLoading('My Family 2', 'n4');
213
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading ns-myfamily2-n4-loading', this.fakeHtmlElement_.className);
214
+ this.eventDispatcher_.dispatchFontActive('My Family 2', 'n4');
215
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading ns-myfamily2-n4-active', this.fakeHtmlElement_.className);
216
+ this.eventDispatcher_.dispatchActive();
217
+ assertEquals('ns-myfamily-n4-active ns-active ns-myfamily2-n4-active', this.fakeHtmlElement_.className);
218
+ };
219
+
220
+ EventDispatcherTest.prototype.testClassNamesOnActiveThenActiveLoadSameFont = function() {
221
+ this.eventDispatcher_.dispatchLoading();
222
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
223
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
224
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
225
+ this.eventDispatcher_.dispatchFontActive('My Family', 'n4');
226
+ assertEquals('ns-loading ns-myfamily-n4-active', this.fakeHtmlElement_.className);
227
+ this.eventDispatcher_.dispatchActive();
228
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
229
+ this.eventDispatcher_.dispatchLoading();
230
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading', this.fakeHtmlElement_.className);
231
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
232
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
233
+ this.eventDispatcher_.dispatchFontActive('My Family', 'n4');
234
+ assertEquals('ns-myfamily-n4-active ns-active ns-loading', this.fakeHtmlElement_.className);
235
+ this.eventDispatcher_.dispatchActive();
236
+ assertEquals('ns-myfamily-n4-active ns-active', this.fakeHtmlElement_.className);
237
+ };
238
+
239
+ EventDispatcherTest.prototype.testClassNamesOnInactiveThenInactiveLoad = function() {
240
+ this.eventDispatcher_.dispatchLoading();
241
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
242
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
243
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
244
+ this.eventDispatcher_.dispatchFontInactive('My Family', 'n4');
245
+ assertEquals('ns-loading ns-myfamily-n4-inactive', this.fakeHtmlElement_.className);
246
+ this.eventDispatcher_.dispatchInactive();
247
+ assertEquals('ns-myfamily-n4-inactive ns-inactive', this.fakeHtmlElement_.className);
248
+ this.eventDispatcher_.dispatchLoading();
249
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading', this.fakeHtmlElement_.className);
250
+ this.eventDispatcher_.dispatchFontLoading('My Family 2', 'n4');
251
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading ns-myfamily2-n4-loading', this.fakeHtmlElement_.className);
252
+ this.eventDispatcher_.dispatchFontInactive('My Family 2', 'n4');
253
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading ns-myfamily2-n4-inactive', this.fakeHtmlElement_.className);
254
+ this.eventDispatcher_.dispatchInactive();
255
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-myfamily2-n4-inactive', this.fakeHtmlElement_.className);
256
+ };
257
+
258
+ EventDispatcherTest.prototype.testClassNamesOnInactiveThenInactiveLoadSameFont = function() {
259
+ this.eventDispatcher_.dispatchLoading();
260
+ assertEquals('ns-loading', this.fakeHtmlElement_.className);
261
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
262
+ assertEquals('ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
263
+ this.eventDispatcher_.dispatchFontInactive('My Family', 'n4');
264
+ assertEquals('ns-loading ns-myfamily-n4-inactive', this.fakeHtmlElement_.className);
265
+ this.eventDispatcher_.dispatchInactive();
266
+ assertEquals('ns-myfamily-n4-inactive ns-inactive', this.fakeHtmlElement_.className);
267
+ this.eventDispatcher_.dispatchLoading();
268
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading', this.fakeHtmlElement_.className);
269
+ this.eventDispatcher_.dispatchFontLoading('My Family', 'n4');
270
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading ns-myfamily-n4-loading', this.fakeHtmlElement_.className);
271
+ this.eventDispatcher_.dispatchFontInactive('My Family', 'n4');
272
+ assertEquals('ns-myfamily-n4-inactive ns-inactive ns-loading', this.fakeHtmlElement_.className);
273
+ this.eventDispatcher_.dispatchInactive();
274
+ assertEquals('ns-myfamily-n4-inactive ns-inactive', this.fakeHtmlElement_.className);
110
275
  };
@@ -5,6 +5,7 @@ FontTest.prototype.setUp = function() {
5
5
  this.fakeDomHelper_ = {
6
6
  appendClassName: function() {},
7
7
  removeClassName: function() {},
8
+ hasClassName: function() {},
8
9
  createElement: function(name) {
9
10
  return document.createElement(name);
10
11
  },
@@ -0,0 +1,49 @@
1
+ var FontdeckScriptTest = TestCase('FontdeckScriptTest');
2
+
3
+ FontdeckScriptTest.prototype.testSupportAndLoadLifecycle = function() {
4
+ var configuration = {
5
+ 'id': '2282'
6
+ };
7
+ var apiResponse = {
8
+ 'css':'http://fontdeck.com/s/css/uH5+KWQnibDTJRYggGJ9XZLTAgw/webfontloader/2282.css',
9
+ 'provides':[
10
+ {'font_size_adjust':null,'weight':'normal','style':'normal','name':'Fertigo Pro Regular'},
11
+ {'font_size_adjust':'0.5','weight':'bold','style':'italic','name':'Bodoni Display Bold Italic'}
12
+ ]
13
+ };
14
+ var insert = '';
15
+ var src = '';
16
+ var fakeDomHelper = {
17
+ insertInto: function(tag, e) {
18
+ insert = tag;
19
+ },
20
+ createScriptSrc: function(srcLink) {
21
+ src = srcLink;
22
+ },
23
+ createCssLink: function(cssLink) {
24
+ css = cssLink;
25
+ return '<link href="' + css + '" type="text/css" />';
26
+ }
27
+ };
28
+ var global = {};
29
+ var fontdeck = new webfont.FontdeckScript(global, fakeDomHelper, configuration);
30
+
31
+ // supportUserAgent
32
+ var userAgent = 'user agent';
33
+ var isSupport = null;
34
+
35
+ fontdeck.supportUserAgent(userAgent, function(support) { isSupport = support; });
36
+ assertEquals('head', insert);
37
+ assertEquals('http://fontdeck.com/api/v1/project-info?project=2282&domain=localhost&callback=window.__webfontfontdeckmodule__[2282]', src);
38
+ assertEquals(null, isSupport);
39
+
40
+ assertNotNull(global.__webfontfontdeckmodule__);
41
+ assertNotNull(global.__webfontfontdeckmodule__['2282']);
42
+
43
+ // Call the callback function passing in dummy API response.
44
+ global.__webfontfontdeckmodule__['2282'](apiResponse);
45
+
46
+ assertEquals(fontdeck.fontFamilies_, [apiResponse.provides[0].name, apiResponse.provides[1].name]);
47
+ assertEquals(fontdeck.fontVariations_[apiResponse.provides[0].name], ['n4']);
48
+ assertEquals(fontdeck.fontVariations_[apiResponse.provides[1].name], ['i7']);
49
+ };
@@ -73,7 +73,8 @@ FontApiParserTest.prototype.testTypoBildInsteadOfBold = function() {
73
73
 
74
74
  var variations = fontApiParser.getVariations();
75
75
  var nobile = variations['Nobile'];
76
- assertNull(nobile);
76
+ assertEquals(1, nobile.length);
77
+ assertEquals('n4', nobile[0]);
77
78
  };
78
79
 
79
80
  FontApiParserTest.prototype.testNonSense = function() {
@@ -88,5 +89,121 @@ FontApiParserTest.prototype.testNonSense = function() {
88
89
 
89
90
  var variations = fontApiParser.getVariations();
90
91
  var nobile = variations['Nobile'];
91
- assertNull(nobile);
92
+ assertEquals(1, nobile.length);
93
+ assertEquals('n4', nobile[0]);
94
+ };
95
+
96
+ FontApiParserTest.prototype.testNoWeightOneSubsetDefined = function() {
97
+ var fontFamilies = [ 'Cantarell::greek' ];
98
+ var fontApiParser = new webfont.FontApiParser(fontFamilies);
99
+
100
+ fontApiParser.parse();
101
+
102
+ var parsedFontFamilies = fontApiParser.getFontFamilies();
103
+ assertEquals(1, parsedFontFamilies.length);
104
+ assertEquals('Cantarell', parsedFontFamilies[0]);
105
+
106
+ var variations = fontApiParser.getVariations();
107
+ var cantarellVariations = variations['Cantarell'];
108
+ assertEquals(1, cantarellVariations.length);
109
+ assertEquals('n4', cantarellVariations[0]);
110
+
111
+ var testStrings = fontApiParser.getFontTestStrings();
112
+ var cantarellTestStrings = testStrings['Cantarell'];
113
+ assertNotUndefined(cantarellTestStrings);
114
+ assertEquals(webfont.FontApiParser.INT_FONTS['greek'],
115
+ cantarellTestStrings);
116
+ };
117
+
118
+
119
+ FontApiParserTest.prototype.testNoWeightMultipleSubsetsDefined = function() {
120
+ var fontFamilies = [ 'Cantarell::cyrillic,greek,latin' ];
121
+ var fontApiParser = new webfont.FontApiParser(fontFamilies);
122
+
123
+ fontApiParser.parse();
124
+
125
+ var parsedFontFamilies = fontApiParser.getFontFamilies();
126
+ assertEquals(1, parsedFontFamilies.length);
127
+ assertEquals('Cantarell', parsedFontFamilies[0]);
128
+
129
+ var variations = fontApiParser.getVariations();
130
+ var cantarellVariations = variations['Cantarell'];
131
+ assertEquals(1, cantarellVariations.length);
132
+ assertEquals('n4', cantarellVariations[0]);
133
+
134
+ var testStrings = fontApiParser.getFontTestStrings();
135
+ var cantarellTestStrings = testStrings['Cantarell'];
136
+ assertNotUndefined(cantarellTestStrings);
137
+ assertEquals(webfont.FontApiParser.INT_FONTS['cyrillic'],
138
+ cantarellTestStrings);
139
+ };
140
+
141
+
142
+ FontApiParserTest.prototype.testWeightAndMultipleSubsetsDefined = function() {
143
+ var fontFamilies = [ 'Cantarell:regular,bold:cyrillic,greek,latin' ];
144
+ var fontApiParser = new webfont.FontApiParser(fontFamilies);
145
+
146
+ fontApiParser.parse();
147
+
148
+ var parsedFontFamilies = fontApiParser.getFontFamilies();
149
+ assertEquals(1, parsedFontFamilies.length);
150
+ assertEquals('Cantarell', parsedFontFamilies[0]);
151
+
152
+ var variations = fontApiParser.getVariations();
153
+ var cantarellVariations = variations['Cantarell'];
154
+ assertEquals(2, cantarellVariations.length);
155
+ assertEquals('n4', cantarellVariations[0]);
156
+ assertEquals('n7', cantarellVariations[1]);
157
+
158
+ var testStrings = fontApiParser.getFontTestStrings();
159
+ var cantarellTestStrings = testStrings['Cantarell'];
160
+ assertNotUndefined(cantarellTestStrings);
161
+ assertEquals(webfont.FontApiParser.INT_FONTS['cyrillic'],
162
+ cantarellTestStrings);
163
+ };
164
+
165
+
166
+ FontApiParserTest.prototype.testHanumanIsBackwardCompatible = function() {
167
+ var fontFamilies = [ 'Hanuman' ];
168
+ var fontApiParser = new webfont.FontApiParser(fontFamilies);
169
+
170
+ fontApiParser.parse();
171
+
172
+ var parsedFontFamilies = fontApiParser.getFontFamilies();
173
+ assertEquals(1, parsedFontFamilies.length);
174
+ assertEquals('Hanuman', parsedFontFamilies[0]);
175
+
176
+ var variations = fontApiParser.getVariations();
177
+ var hanumanVariations = variations['Hanuman'];
178
+ assertEquals(1, hanumanVariations.length);
179
+ assertEquals('n4', hanumanVariations[0]);
180
+
181
+ var testStrings = fontApiParser.getFontTestStrings();
182
+ var hanumanTestStrings = testStrings['Hanuman'];
183
+ assertNotUndefined(hanumanTestStrings);
184
+ assertEquals(webfont.FontApiParser.INT_FONTS['Hanuman'],
185
+ hanumanTestStrings);
186
+ };
187
+
188
+
189
+ FontApiParserTest.prototype.testHanumanIsForwardCompatible = function() {
190
+ var fontFamilies = [ 'Hanuman::khmer' ];
191
+ var fontApiParser = new webfont.FontApiParser(fontFamilies);
192
+
193
+ fontApiParser.parse();
194
+
195
+ var parsedFontFamilies = fontApiParser.getFontFamilies();
196
+ assertEquals(1, parsedFontFamilies.length);
197
+ assertEquals('Hanuman', parsedFontFamilies[0]);
198
+
199
+ var variations = fontApiParser.getVariations();
200
+ var hanumanVariations = variations['Hanuman'];
201
+ assertEquals(1, hanumanVariations.length);
202
+ assertEquals('n4', hanumanVariations[0]);
203
+
204
+ var testStrings = fontApiParser.getFontTestStrings();
205
+ var hanumanTestStrings = testStrings['Hanuman'];
206
+ assertNotUndefined(hanumanTestStrings);
207
+ assertEquals(webfont.FontApiParser.INT_FONTS['khmer'],
208
+ hanumanTestStrings);
92
209
  };
@@ -26,3 +26,14 @@ FontApiUrlBuilderTest.prototype.testBuildProperDefaultUrl = function() {
26
26
  assertEquals("http:" + webfont.FontApiUrlBuilder.DEFAULT_API_URL +
27
27
  '?family=Font1%7CFont2', fontApiUrlBuilder.build());
28
28
  };
29
+
30
+
31
+ FontApiUrlBuilderTest.prototype.testBuildProperUrlWithSubsets = function() {
32
+ var fontApiUrlBuilder = new webfont.FontApiUrlBuilder();
33
+
34
+ fontApiUrlBuilder.setFontFamilies([ 'Font1:bold:greek,cyrillic',
35
+ 'Font2:italic', 'Font3' ]);
36
+ assertEquals("http:" + webfont.FontApiUrlBuilder.DEFAULT_API_URL +
37
+ '?family=Font1:bold%7CFont2:italic%7CFont3' +
38
+ '&subset=greek,cyrillic', fontApiUrlBuilder.build());
39
+ };
@@ -4,7 +4,7 @@
4
4
  */
5
5
  webfont.CssFontFamilyName = function() {
6
6
  /** @type {string} */
7
- this.quote_ = '"';
7
+ this.quote_ = "'";
8
8
  };
9
9
 
10
10
  /**
@@ -148,3 +148,19 @@ webfont.DomHelper.prototype.removeClassName = function(e, name) {
148
148
  e.className = remainingClasses.join(' ').replace(/^\s+/, '')
149
149
  .replace(/\s+$/, '');
150
150
  };
151
+
152
+ /**
153
+ * Returns true if an element has a given class name and false otherwise.
154
+ * @param {Element} e The element.
155
+ * @param {string} name The class name to check for.
156
+ * @return {boolean} Whether or not the element has this class name.
157
+ */
158
+ webfont.DomHelper.prototype.hasClassName = function(e, name) {
159
+ var classes = e.className.split(/\s+/);
160
+ for (var i = 0, len = classes.length; i < len; i++) {
161
+ if (classes[i] == name) {
162
+ return true;
163
+ }
164
+ }
165
+ return false;
166
+ };
@@ -1,4 +1,9 @@
1
1
  /**
2
+ * A class to dispatch events and manage the event class names on an html
3
+ * element that represent the current state of fonts on the page. Active class
4
+ * names always overwrite inactive class names of the same type, while loading
5
+ * class names may be present whenever a font is loading (regardless of if an
6
+ * associated active or inactive class name is also present).
2
7
  * @param {webfont.DomHelper} domHelper
3
8
  * @param {HTMLElement} htmlElement
4
9
  * @param {Object} callbacks
@@ -44,6 +49,9 @@ webfont.EventDispatcher.INACTIVE = 'inactive';
44
49
  */
45
50
  webfont.EventDispatcher.FONT = 'font';
46
51
 
52
+ /**
53
+ * Dispatch the loading event and append the loading class name.
54
+ */
47
55
  webfont.EventDispatcher.prototype.dispatchLoading = function() {
48
56
  this.domHelper_.appendClassName(this.htmlElement_,
49
57
  this.cssClassName_.build(
@@ -52,6 +60,7 @@ webfont.EventDispatcher.prototype.dispatchLoading = function() {
52
60
  };
53
61
 
54
62
  /**
63
+ * Dispatch the font loading event and append the font loading class name.
55
64
  * @param {string} fontFamily
56
65
  * @param {string} fontDescription
57
66
  */
@@ -64,6 +73,8 @@ webfont.EventDispatcher.prototype.dispatchFontLoading = function(fontFamily, fon
64
73
  };
65
74
 
66
75
  /**
76
+ * Dispatch the font active event, remove the font loading class name, remove
77
+ * the font inactive class name, and append the font active class name.
67
78
  * @param {string} fontFamily
68
79
  * @param {string} fontDescription
69
80
  */
@@ -71,6 +82,9 @@ webfont.EventDispatcher.prototype.dispatchFontActive = function(fontFamily, font
71
82
  this.domHelper_.removeClassName(this.htmlElement_,
72
83
  this.cssClassName_.build(
73
84
  this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.LOADING));
85
+ this.domHelper_.removeClassName(this.htmlElement_,
86
+ this.cssClassName_.build(
87
+ this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.INACTIVE));
74
88
  this.domHelper_.appendClassName(this.htmlElement_,
75
89
  this.cssClassName_.build(
76
90
  this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.ACTIVE));
@@ -79,6 +93,9 @@ webfont.EventDispatcher.prototype.dispatchFontActive = function(fontFamily, font
79
93
  };
80
94
 
81
95
  /**
96
+ * Dispatch the font inactive event, remove the font loading class name, and
97
+ * append the font inactive class name (unless the font active class name is
98
+ * already present).
82
99
  * @param {string} fontFamily
83
100
  * @param {string} fontDescription
84
101
  */
@@ -86,28 +103,48 @@ webfont.EventDispatcher.prototype.dispatchFontInactive = function(fontFamily, fo
86
103
  this.domHelper_.removeClassName(this.htmlElement_,
87
104
  this.cssClassName_.build(
88
105
  this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.LOADING));
89
- this.domHelper_.appendClassName(this.htmlElement_,
106
+ var hasFontActive = this.domHelper_.hasClassName(this.htmlElement_,
90
107
  this.cssClassName_.build(
91
- this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.INACTIVE));
108
+ this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.ACTIVE));
109
+ if (!hasFontActive) {
110
+ this.domHelper_.appendClassName(this.htmlElement_,
111
+ this.cssClassName_.build(
112
+ this.namespace_, fontFamily, fontDescription, webfont.EventDispatcher.INACTIVE));
113
+ }
92
114
  this.dispatch_(
93
115
  webfont.EventDispatcher.FONT + webfont.EventDispatcher.INACTIVE, fontFamily, fontDescription);
94
116
  };
95
117
 
118
+ /**
119
+ * Dispatch the inactive event, remove the loading class name, and append the
120
+ * inactive class name (unless the active class name is already present).
121
+ */
96
122
  webfont.EventDispatcher.prototype.dispatchInactive = function() {
97
123
  this.domHelper_.removeClassName(this.htmlElement_,
98
124
  this.cssClassName_.build(
99
125
  this.namespace_, webfont.EventDispatcher.LOADING));
100
- this.domHelper_.appendClassName(this.htmlElement_,
126
+ var hasActive = this.domHelper_.hasClassName(this.htmlElement_,
101
127
  this.cssClassName_.build(
102
- this.namespace_, webfont.EventDispatcher.INACTIVE));
128
+ this.namespace_, webfont.EventDispatcher.ACTIVE));
129
+ if (!hasActive) {
130
+ this.domHelper_.appendClassName(this.htmlElement_,
131
+ this.cssClassName_.build(
132
+ this.namespace_, webfont.EventDispatcher.INACTIVE));
133
+ }
103
134
  this.dispatch_(webfont.EventDispatcher.INACTIVE);
104
135
  };
105
136
 
137
+ /**
138
+ * Dispatch the active event, remove the loading class name, remove the inactive
139
+ * class name, and append the active class name.
140
+ */
106
141
  webfont.EventDispatcher.prototype.dispatchActive = function() {
107
- // what about inactive? maybe if all fonts failed to load?
108
142
  this.domHelper_.removeClassName(this.htmlElement_,
109
143
  this.cssClassName_.build(
110
144
  this.namespace_, webfont.EventDispatcher.LOADING));
145
+ this.domHelper_.removeClassName(this.htmlElement_,
146
+ this.cssClassName_.build(
147
+ this.namespace_, webfont.EventDispatcher.INACTIVE));
111
148
  this.domHelper_.appendClassName(this.htmlElement_,
112
149
  this.cssClassName_.build(
113
150
  this.namespace_, webfont.EventDispatcher.ACTIVE));
@@ -125,8 +125,10 @@ webfont.FontWatchRunner.prototype.getDefaultFontSize_ = function(defaultFonts) {
125
125
  webfont.FontWatchRunner.prototype.createHiddenElementWithFont_ = function(
126
126
  defaultFonts, opt_withoutFontFamily) {
127
127
  var variationCss = this.fvd_.expand(this.fontDescription_);
128
- var styleString = "position:absolute;top:-999px;font-size:300px;font-family:" +
129
- (opt_withoutFontFamily ? "" : this.nameHelper_.quote(this.fontFamily_) + ",") +
128
+ var styleString = "position:absolute;top:-999px;font-size:300px;" +
129
+ "width:auto;height:auto;line-height:normal;margin:0;padding:0;" +
130
+ "font-variant:normal;font-family:" + (opt_withoutFontFamily ? "" :
131
+ this.nameHelper_.quote(this.fontFamily_) + ",") +
130
132
  defaultFonts + ";" + variationCss;
131
133
  var span = this.domHelper_.createElement('span', { 'style': styleString },
132
134
  this.fontTestString_);
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @constructor
3
+ */
4
+ webfont.FontdeckScript = function(global, domHelper, configuration) {
5
+ this.global_ = global;
6
+ this.domHelper_ = domHelper;
7
+ this.configuration_ = configuration;
8
+ this.fontFamilies_ = [];
9
+ this.fontVariations_ = {};
10
+ this.fvd_ = new webfont.FontVariationDescription();
11
+ };
12
+
13
+ webfont.FontdeckScript.NAME = 'fontdeck';
14
+ webfont.FontdeckScript.HOOK = '__webfontfontdeckmodule__';
15
+ webfont.FontdeckScript.API = 'http://fontdeck.com/api/v1/project-info?'
16
+
17
+ webfont.FontdeckScript.prototype.getScriptSrc = function(projectId) {
18
+ var api = this.configuration_['api'] || webfont.FontdeckScript.API;
19
+ return api + 'project=' + projectId + '&domain=' + document.location.hostname + '&callback=window.__webfontfontdeckmodule__[' + projectId + ']';
20
+ };
21
+
22
+ webfont.FontdeckScript.prototype.supportUserAgent = function(userAgent, support) {
23
+ var projectId = this.configuration_['id'];
24
+ var families = this.configuration_['families'] || null;
25
+ var self = this;
26
+
27
+ if (projectId) {
28
+ // Provide data to Fontdeck for processing.
29
+ if (!this.global_[webfont.FontdeckScript.HOOK]) {
30
+ this.global_[webfont.FontdeckScript.HOOK] = {};
31
+ }
32
+
33
+ // The API will call this function with a link to the CSS
34
+ // and a list of supported fonts.
35
+ this.global_[webfont.FontdeckScript.HOOK][projectId] = function(data) {
36
+ self.domHelper_.insertInto('head', self.domHelper_.createCssLink(data['css']));
37
+ for (var i = 0, j = data['provides'].length; i < j; ++i) {
38
+ var font = data['provides'][i];
39
+ self.fontFamilies_.push(font['name']);
40
+ self.fontVariations_[font['name']] = [self.fvd_.compact("font-weight:" + font['weight'] + ";font-style:" + font['style'])];
41
+ }
42
+ // If families were passed into load, then use them instead.
43
+ if (families !== null) {
44
+ self.fontFamilies_ = families;
45
+ }
46
+ support(true);
47
+ };
48
+
49
+ // Call the Fontdeck API.
50
+ var script = this.domHelper_.createScriptSrc(this.getScriptSrc(projectId));
51
+ this.domHelper_.insertInto('head', script);
52
+
53
+ } else {
54
+ support(true);
55
+ }
56
+ };
57
+
58
+ webfont.FontdeckScript.prototype.load = function(onReady) {
59
+ onReady(this.fontFamilies_, this.fontVariations_);
60
+ };
61
+
62
+ window['WebFont'].addModule(webfont.FontdeckScript.NAME, function(configuration) {
63
+ var userAgentParser = new webfont.UserAgentParser(navigator.userAgent, document);
64
+ var userAgent = userAgentParser.parse();
65
+ var domHelper = new webfont.DomHelper(document, userAgent);
66
+ return new webfont.FontdeckScript(window, domHelper, configuration);
67
+ });
@@ -25,32 +25,47 @@ webfont.FontApiParser.VARIATIONS = {
25
25
  };
26
26
 
27
27
  webfont.FontApiParser.INT_FONTS = {
28
- 'Hanuman': '&#x1780;&#x1781;&#x1782;'
28
+ 'latin': webfont.FontWatchRunner.DEFAULT_TEST_STRING,
29
+ 'cyrillic': '&#1081;&#1103;&#1046;',
30
+ 'greek': '&#945;&#946;&#931;',
31
+ 'khmer': '&#x1780;&#x1781;&#x1782;',
32
+ 'Hanuman': '&#x1780;&#x1781;&#x1782;' // For backward compatibility
29
33
  };
30
34
 
31
35
  webfont.FontApiParser.prototype.parse = function() {
32
36
  var length = this.fontFamilies_.length;
33
37
 
34
38
  for (var i = 0; i < length; i++) {
35
- var pair = this.fontFamilies_[i].split(":");
36
- var fontFamily = pair[0];
37
- var variations = null;
39
+ var elements = this.fontFamilies_[i].split(":");
40
+ var fontFamily = elements[0];
41
+ var variations = ['n4'];
38
42
 
39
- if (pair.length == 2) {
40
- var fvds = this.parseVariations_(pair[1]);
43
+ if (elements.length >= 2) {
44
+ var fvds = this.parseVariations_(elements[1]);
41
45
 
42
46
  if (fvds.length > 0) {
43
47
  variations = fvds;
44
48
  }
45
- } else {
46
- variations = ['n4'];
49
+ if (elements.length == 3) {
50
+ var subsets = this.parseSubsets_(elements[2]);
51
+ if (subsets.length > 0) {
52
+ var fontTestString = webfont.FontApiParser.INT_FONTS[subsets[0]];
53
+
54
+ if (fontTestString) {
55
+ this.fontTestStrings_[fontFamily] = fontTestString;
56
+ }
57
+ }
58
+ }
47
59
  }
48
- this.parsedFontFamilies_.push(fontFamily);
49
- var fontTestString = webfont.FontApiParser.INT_FONTS[fontFamily];
50
60
 
51
- if (fontTestString) {
52
- this.fontTestStrings_[fontFamily] = fontTestString;
61
+ // For backward compatibility
62
+ if (!this.fontTestStrings_[fontFamily]) {
63
+ var hanumanTestString = webfont.FontApiParser.INT_FONTS[fontFamily];
64
+ if (hanumanTestString) {
65
+ this.fontTestStrings_[fontFamily] = hanumanTestString;
66
+ }
53
67
  }
68
+ this.parsedFontFamilies_.push(fontFamily);
54
69
  this.variations_[fontFamily] = variations;
55
70
  }
56
71
  };
@@ -81,6 +96,10 @@ webfont.FontApiParser.prototype.generateFontVariationDescription_ = function(var
81
96
 
82
97
  webfont.FontApiParser.prototype.parseVariations_ = function(variations) {
83
98
  var finalVariations = [];
99
+
100
+ if (!variations) {
101
+ return finalVariations;
102
+ }
84
103
  var providedVariations = variations.split(",");
85
104
  var length = providedVariations.length;
86
105
 
@@ -95,6 +114,17 @@ webfont.FontApiParser.prototype.parseVariations_ = function(variations) {
95
114
  return finalVariations;
96
115
  };
97
116
 
117
+
118
+ webfont.FontApiParser.prototype.parseSubsets_ = function(subsets) {
119
+ var finalSubsets = [];
120
+
121
+ if (!subsets) {
122
+ return finalSubsets;
123
+ }
124
+ return subsets.split(",");
125
+ };
126
+
127
+
98
128
  webfont.FontApiParser.prototype.getFontFamilies = function() {
99
129
  return this.parsedFontFamilies_;
100
130
  };
@@ -9,22 +9,41 @@ webfont.FontApiUrlBuilder = function(apiUrl) {
9
9
 
10
10
  this.apiUrl_ = protocol + webfont.FontApiUrlBuilder.DEFAULT_API_URL;
11
11
  }
12
- this.fontFamilies_ = null;
12
+ this.fontFamilies_ = [];
13
+ this.subsets_ = [];
13
14
  };
14
15
 
16
+
15
17
  webfont.FontApiUrlBuilder.DEFAULT_API_URL = '//fonts.googleapis.com/css';
16
18
 
19
+
17
20
  webfont.FontApiUrlBuilder.prototype.setFontFamilies = function(fontFamilies) {
18
- // maybe clone?
19
- this.fontFamilies_ = fontFamilies;
21
+ this.parseFontFamilies_(fontFamilies);
20
22
  };
21
23
 
24
+
25
+ webfont.FontApiUrlBuilder.prototype.parseFontFamilies_ =
26
+ function(fontFamilies) {
27
+ var length = fontFamilies.length;
28
+
29
+ for (var i = 0; i < length; i++) {
30
+ var elements = fontFamilies[i].split(':');
31
+
32
+ if (elements.length == 3) {
33
+ this.subsets_.push(elements.pop());
34
+ }
35
+ this.fontFamilies_.push(elements.join(':'));
36
+ }
37
+ };
38
+
39
+
22
40
  webfont.FontApiUrlBuilder.prototype.webSafe = function(string) {
23
41
  return string.replace(/ /g, '+');
24
42
  };
25
43
 
44
+
26
45
  webfont.FontApiUrlBuilder.prototype.build = function() {
27
- if (!this.fontFamilies_) {
46
+ if (this.fontFamilies_.length == 0) {
28
47
  throw new Error('No fonts to load !');
29
48
  }
30
49
  if (this.apiUrl_.indexOf("kit=") != -1) {
@@ -38,5 +57,9 @@ webfont.FontApiUrlBuilder.prototype.build = function() {
38
57
  }
39
58
  var url = this.apiUrl_ + '?family=' + sb.join('%7C'); // '|' escaped.
40
59
 
60
+ if (this.subsets_.length > 0) {
61
+ url += '&subset=' + this.subsets_.join(',');
62
+ }
63
+
41
64
  return url;
42
65
  };
@@ -10,10 +10,7 @@ webfont.GoogleFontApi = function(userAgent, domHelper, configuration) {
10
10
  webfont.GoogleFontApi.NAME = 'google';
11
11
 
12
12
  webfont.GoogleFontApi.prototype.supportUserAgent = function(userAgent, support) {
13
- if (userAgent.getPlatform().match(/iPad|iPod|iPhone/) != null) {
14
- support(false);
15
- }
16
- return support(userAgent.isSupportingWebFont());
13
+ support(userAgent.isSupportingWebFont());
17
14
  };
18
15
 
19
16
  webfont.GoogleFontApi.prototype.load = function(onReady) {
data/src/modules.yml CHANGED
@@ -21,6 +21,9 @@ google:
21
21
  - google/fontapiparser.js
22
22
  - google/googlefontapi.js
23
23
 
24
+ fontdeck:
25
+ - fontdeck/fontdeck_script.js
26
+
24
27
  typekit:
25
28
  - typekit/typekit_script.js
26
29
 
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'webfontloader'
16
- s.version = '1.0.16'
17
- s.date = '2010-11-18'
16
+ s.version = '1.0.18'
17
+ s.date = '2011-01-24'
18
18
 
19
19
  ## Make sure your summary is short. The description may be as long
20
20
  ## as you like.
@@ -87,6 +87,7 @@ DESC
87
87
  lib/webfontloader/demo/public/event-js-loading.html
88
88
  lib/webfontloader/demo/public/events-variations.html
89
89
  lib/webfontloader/demo/public/events.html
90
+ lib/webfontloader/demo/public/fontdeck.html
90
91
  lib/webfontloader/demo/public/fontwatchrunner-default-fonts.html
91
92
  lib/webfontloader/demo/public/google-css.html
92
93
  lib/webfontloader/demo/public/google.html
@@ -111,6 +112,7 @@ DESC
111
112
  src-test/core/fontwatchrunnertest.js
112
113
  src-test/core/useragenttest.js
113
114
  src-test/custom/customcsstest.js
115
+ src-test/fontdeck/fontdeck_script_test.js
114
116
  src-test/google/fontapiparsertest.js
115
117
  src-test/google/fontapiurlbuildertest.js
116
118
  src-test/google/googlefontapitest.js
@@ -132,6 +134,7 @@ DESC
132
134
  src/core/useragent.js
133
135
  src/core/useragentparser.js
134
136
  src/custom/customcss.js
137
+ src/fontdeck/fontdeck_script.js
135
138
  src/google/fontapiparser.js
136
139
  src/google/fontapiurlbuilder.js
137
140
  src/google/googlefontapi.js
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webfontloader
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
4
+ hash: 51
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 16
10
- version: 1.0.16
9
+ - 18
10
+ version: 1.0.18
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Carver
@@ -16,12 +16,10 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-11-18 00:00:00 -08:00
19
+ date: 2011-01-24 00:00:00 -08:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
- name: rack
24
- prerelease: false
25
23
  requirement: &id001 !ruby/object:Gem::Requirement
26
24
  none: false
27
25
  requirements:
@@ -34,10 +32,10 @@ dependencies:
34
32
  - 1
35
33
  version: 1.2.1
36
34
  type: :development
35
+ name: rack
36
+ prerelease: false
37
37
  version_requirements: *id001
38
38
  - !ruby/object:Gem::Dependency
39
- name: sinatra
40
- prerelease: false
41
39
  requirement: &id002 !ruby/object:Gem::Requirement
42
40
  none: false
43
41
  requirements:
@@ -49,10 +47,10 @@ dependencies:
49
47
  - 0
50
48
  version: "1.0"
51
49
  type: :development
50
+ name: sinatra
51
+ prerelease: false
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- name: vegas
55
- prerelease: false
56
54
  requirement: &id003 !ruby/object:Gem::Requirement
57
55
  none: false
58
56
  requirements:
@@ -65,6 +63,8 @@ dependencies:
65
63
  - 6
66
64
  version: 0.1.6
67
65
  type: :development
66
+ name: vegas
67
+ prerelease: false
68
68
  version_requirements: *id003
69
69
  description: |
70
70
  WebFont Loader gives you added control when using linked fonts via
@@ -105,6 +105,7 @@ files:
105
105
  - lib/webfontloader/demo/public/event-js-loading.html
106
106
  - lib/webfontloader/demo/public/events-variations.html
107
107
  - lib/webfontloader/demo/public/events.html
108
+ - lib/webfontloader/demo/public/fontdeck.html
108
109
  - lib/webfontloader/demo/public/fontwatchrunner-default-fonts.html
109
110
  - lib/webfontloader/demo/public/google-css.html
110
111
  - lib/webfontloader/demo/public/google.html
@@ -129,6 +130,7 @@ files:
129
130
  - src-test/core/fontwatchrunnertest.js
130
131
  - src-test/core/useragenttest.js
131
132
  - src-test/custom/customcsstest.js
133
+ - src-test/fontdeck/fontdeck_script_test.js
132
134
  - src-test/google/fontapiparsertest.js
133
135
  - src-test/google/fontapiurlbuildertest.js
134
136
  - src-test/google/googlefontapitest.js
@@ -150,6 +152,7 @@ files:
150
152
  - src/core/useragent.js
151
153
  - src/core/useragentparser.js
152
154
  - src/custom/customcss.js
155
+ - src/fontdeck/fontdeck_script.js
153
156
  - src/google/fontapiparser.js
154
157
  - src/google/fontapiurlbuilder.js
155
158
  - src/google/googlefontapi.js