Skip to content

Commit 0607a7c

Browse files
author
Bram Stein
committed
Add options to disable events and setting of classes on the HTML element.
1 parent d361cdc commit 0607a7c

File tree

4 files changed

+156
-79
lines changed

4 files changed

+156
-79
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,24 @@ WebFontConfig = {
116116

117117
The `fontloading`, `fontactive` and `fontinactive` callbacks are passed the family name and font variation description of the font that concerns the event.
118118

119+
It is possible to disable setting classes on the HTML element by setting the `classes` configuration parameter to `false` (defaults to `true`).
120+
121+
```javascript
122+
WebFontConfig = {
123+
classes: false
124+
};
125+
```
126+
127+
You can also disable font events (callbacks) by setting the `events` parameter to `false` (defaults to `true`).
128+
129+
```javascript
130+
WebFontConfig = {
131+
events: false
132+
};
133+
```
134+
135+
If both events and classes are disabled, the Web Font Loader does not perform font watching and only acts as a way to insert @font-face rules in the document.
136+
119137
### Timeouts
120138

121139
Since the Internet is not 100% reliable, it's possible that a font will fail to load. The `fontinactive` event will be triggered after 5 seconds if the font fails to render. If *at least* one font succesfully renders, the `active` event will be triggered, else the `inactive` event will be triggered.

spec/core/eventdispatcher_spec.js

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,22 @@ describe('EventDispatcher', function () {
66
element = null
77
eventDispatcher = null,
88
namespace = 'ns',
9-
font = null,
10-
nullFn = function () {},
11-
callbacks = {
12-
loading: nullFn,
13-
active: nullFn,
14-
inactive: nullFn,
15-
fontloading: nullFn,
16-
fontactive: nullFn,
17-
fontinactive: nullFn
18-
};
9+
font = null;
1910

2011
beforeEach(function () {
2112
element = domHelper.createElement();
13+
callbacks = {
14+
loading: jasmine.createSpy('loading'),
15+
active: jasmine.createSpy('active'),
16+
inactive: jasmine.createSpy('inactive'),
17+
fontloading: jasmine.createSpy('fontloading'),
18+
fontactive: jasmine.createSpy('fontactive'),
19+
fontinactive: jasmine.createSpy('fontinactive')
20+
};
21+
2222
eventDispatcher = new EventDispatcher(domHelper, element, callbacks, namespace);
2323

2424
font = new Font('My Family', 'n4');
25-
26-
spyOn(callbacks, 'loading');
27-
spyOn(callbacks, 'active');
28-
spyOn(callbacks, 'inactive');
29-
spyOn(callbacks, 'fontloading');
30-
spyOn(callbacks, 'fontactive');
31-
spyOn(callbacks, 'fontinactive');
3225
});
3326

3427
describe('#dispatchLoading', function () {
@@ -210,4 +203,41 @@ describe('EventDispatcher', function () {
210203
expect(element.className).toEqual('ns-active');
211204
});
212205
});
206+
207+
describe('disable callbacks', function () {
208+
beforeEach(function () {
209+
eventDispatcher = new EventDispatcher(domHelper, element, callbacks, namespace, false);
210+
eventDispatcher.dispatchInactive();
211+
eventDispatcher.dispatchActive();
212+
eventDispatcher.dispatchLoading();
213+
eventDispatcher.dispatchFontInactive(font);
214+
eventDispatcher.dispatchFontActive(font);
215+
eventDispatcher.dispatchFontLoading(font);
216+
});
217+
218+
it('should not fire any events', function () {
219+
expect(callbacks.inactive).not.toHaveBeenCalled();
220+
expect(callbacks.active).not.toHaveBeenCalled();
221+
expect(callbacks.loading).not.toHaveBeenCalled();
222+
expect(callbacks.fontinactive).not.toHaveBeenCalled();
223+
expect(callbacks.fontactive).not.toHaveBeenCalled();
224+
expect(callbacks.fontloading).not.toHaveBeenCalled();
225+
});
226+
});
227+
228+
describe('disable classes', function () {
229+
beforeEach(function () {
230+
eventDispatcher = new EventDispatcher(domHelper, element, callbacks, namespace, true, false);
231+
eventDispatcher.dispatchInactive();
232+
eventDispatcher.dispatchActive();
233+
eventDispatcher.dispatchLoading();
234+
eventDispatcher.dispatchFontInactive(font);
235+
eventDispatcher.dispatchFontActive(font);
236+
eventDispatcher.dispatchFontLoading(font);
237+
});
238+
239+
it('should not fire any events', function () {
240+
expect(element.className).toEqual('');
241+
});
242+
});
213243
});

src/core/eventdispatcher.js

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ goog.require('webfont.CssClassName');
1212
* @param {HTMLElement} htmlElement
1313
* @param {Object} callbacks
1414
* @param {string=} opt_namespace
15+
* @param {boolean=} opt_dispatchEvents Set to false to not call any callbacks. Defaults to true.
16+
* @param {boolean=} opt_setClasses Set to false to not set classes on the HTML element. Defaults to true.
1517
* @constructor
1618
*/
17-
webfont.EventDispatcher = function(domHelper, htmlElement, callbacks,
18-
opt_namespace) {
19+
webfont.EventDispatcher = function(domHelper, htmlElement, callbacks, opt_namespace, opt_dispatchEvents, opt_setClasses) {
1920
this.domHelper_ = domHelper;
2021
this.htmlElement_ = htmlElement;
2122
this.callbacks_ = callbacks;
2223
this.namespace_ = opt_namespace || webfont.EventDispatcher.DEFAULT_NAMESPACE;
2324
this.cssClassName_ = new webfont.CssClassName('-');
25+
this.dispatchEvents_ = opt_dispatchEvents !== false;
26+
this.setClasses_ = opt_setClasses !== false;
2427
};
2528

2629
/**
@@ -60,11 +63,13 @@ goog.scope(function () {
6063
* Dispatch the loading event and append the loading class name.
6164
*/
6265
EventDispatcher.prototype.dispatchLoading = function() {
63-
this.domHelper_.updateClassName(this.htmlElement_,
64-
[
65-
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING)
66-
]
67-
);
66+
if (this.setClasses_) {
67+
this.domHelper_.updateClassName(this.htmlElement_,
68+
[
69+
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING)
70+
]
71+
);
72+
}
6873

6974
this.dispatch_(webfont.EventDispatcher.LOADING);
7075
};
@@ -74,14 +79,15 @@ goog.scope(function () {
7479
* @param {webfont.Font} font
7580
*/
7681
EventDispatcher.prototype.dispatchFontLoading = function(font) {
77-
this.domHelper_.updateClassName(this.htmlElement_,
78-
[
79-
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING)
80-
]
81-
);
82-
83-
this.dispatch_(
84-
webfont.EventDispatcher.FONT + webfont.EventDispatcher.LOADING, font);
82+
if (this.setClasses_) {
83+
this.domHelper_.updateClassName(this.htmlElement_,
84+
[
85+
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING)
86+
]
87+
);
88+
}
89+
90+
this.dispatch_(webfont.EventDispatcher.FONT + webfont.EventDispatcher.LOADING, font);
8591
};
8692

8793
/**
@@ -90,16 +96,18 @@ goog.scope(function () {
9096
* @param {webfont.Font} font
9197
*/
9298
EventDispatcher.prototype.dispatchFontActive = function(font) {
93-
this.domHelper_.updateClassName(
94-
this.htmlElement_,
95-
[
96-
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.ACTIVE)
97-
],
98-
[
99-
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING),
100-
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.INACTIVE)
101-
]
102-
);
99+
if (this.setClasses_) {
100+
this.domHelper_.updateClassName(
101+
this.htmlElement_,
102+
[
103+
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.ACTIVE)
104+
],
105+
[
106+
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING),
107+
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.INACTIVE)
108+
]
109+
);
110+
}
103111

104112
this.dispatch_(webfont.EventDispatcher.FONT + webfont.EventDispatcher.ACTIVE, font);
105113
};
@@ -111,20 +119,22 @@ goog.scope(function () {
111119
* @param {webfont.Font} font
112120
*/
113121
EventDispatcher.prototype.dispatchFontInactive = function(font) {
114-
var hasFontActive = this.domHelper_.hasClassName(this.htmlElement_,
115-
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.ACTIVE)
116-
),
117-
add = [],
118-
remove = [
119-
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING)
120-
];
122+
if (this.setClasses_) {
123+
var hasFontActive = this.domHelper_.hasClassName(this.htmlElement_,
124+
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.ACTIVE)
125+
),
126+
add = [],
127+
remove = [
128+
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING)
129+
];
130+
131+
if (!hasFontActive) {
132+
add.push(this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.INACTIVE));
133+
}
121134

122-
if (!hasFontActive) {
123-
add.push(this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.INACTIVE));
135+
this.domHelper_.updateClassName(this.htmlElement_, add, remove);
124136
}
125137

126-
this.domHelper_.updateClassName(this.htmlElement_, add, remove);
127-
128138
this.dispatch_(webfont.EventDispatcher.FONT + webfont.EventDispatcher.INACTIVE, font);
129139
};
130140

@@ -133,20 +143,22 @@ goog.scope(function () {
133143
* inactive class name (unless the active class name is already present).
134144
*/
135145
EventDispatcher.prototype.dispatchInactive = function() {
136-
var hasActive = this.domHelper_.hasClassName(this.htmlElement_,
137-
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.ACTIVE)
138-
),
139-
add = [],
140-
remove = [
141-
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING)
142-
];
146+
if (this.setClasses_) {
147+
var hasActive = this.domHelper_.hasClassName(this.htmlElement_,
148+
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.ACTIVE)
149+
),
150+
add = [],
151+
remove = [
152+
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING)
153+
];
154+
155+
if (!hasActive) {
156+
add.push(this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.INACTIVE));
157+
}
143158

144-
if (!hasActive) {
145-
add.push(this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.INACTIVE));
159+
this.domHelper_.updateClassName(this.htmlElement_, add, remove);
146160
}
147161

148-
this.domHelper_.updateClassName(this.htmlElement_, add, remove);
149-
150162
this.dispatch_(webfont.EventDispatcher.INACTIVE);
151163
};
152164

@@ -155,15 +167,17 @@ goog.scope(function () {
155167
* class name, and append the active class name.
156168
*/
157169
EventDispatcher.prototype.dispatchActive = function() {
158-
this.domHelper_.updateClassName(this.htmlElement_,
159-
[
160-
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.ACTIVE)
161-
],
162-
[
163-
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING),
164-
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.INACTIVE)
165-
]
166-
);
170+
if (this.setClasses_) {
171+
this.domHelper_.updateClassName(this.htmlElement_,
172+
[
173+
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.ACTIVE)
174+
],
175+
[
176+
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING),
177+
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.INACTIVE)
178+
]
179+
);
180+
}
167181

168182
this.dispatch_(webfont.EventDispatcher.ACTIVE);
169183
};
@@ -173,7 +187,7 @@ goog.scope(function () {
173187
* @param {webfont.Font=} opt_font
174188
*/
175189
EventDispatcher.prototype.dispatch_ = function(event, opt_font) {
176-
if (this.callbacks_[event]) {
190+
if (this.dispatchEvents_ && this.callbacks_[event]) {
177191
if (opt_font) {
178192
this.callbacks_[event](opt_font.getName(), opt_font.getVariation());
179193
} else {

src/core/webfont.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ webfont.WebFont = function(mainWindow) {
1818
this.userAgent_ = this.userAgentParser_.parse();
1919
this.moduleLoading_ = 0;
2020
this.moduleFailedLoading_ = 0;
21+
this.events_ = true;
22+
this.classes_ = true;
2123
};
2224

2325
goog.scope(function () {
@@ -41,8 +43,17 @@ goog.scope(function () {
4143
var context = configuration['context'] || this.mainWindow_;
4244
this.domHelper_ = new DomHelper(this.mainWindow_, context);
4345

46+
this.events_ = configuration['events'] !== false;
47+
this.classes_ = configuration['classes'] !== false;
48+
4449
var eventDispatcher = new EventDispatcher(
45-
this.domHelper_, context.document.documentElement, configuration);
50+
this.domHelper_,
51+
context.document.documentElement,
52+
configuration,
53+
undefined,
54+
this.events_,
55+
this.classes_
56+
);
4657

4758
this.load_(eventDispatcher, configuration);
4859
};
@@ -69,7 +80,9 @@ goog.scope(function () {
6980
if (allModulesLoaded && this.moduleFailedLoading_ == 0) {
7081
eventDispatcher.dispatchInactive();
7182
} else {
72-
fontWatcher.watchFonts([], {}, null, allModulesLoaded);
83+
if (this.classes_ || this.events_) {
84+
fontWatcher.watchFonts([], {}, null, allModulesLoaded);
85+
}
7386
}
7487
}
7588
};
@@ -84,9 +97,11 @@ goog.scope(function () {
8497
WebFont.prototype.onModuleReady_ = function(eventDispatcher, fontWatcher, fonts, opt_fontTestStrings, opt_metricCompatibleFonts) {
8598
var allModulesLoaded = --this.moduleLoading_ == 0;
8699

87-
setTimeout(function () {
88-
fontWatcher.watchFonts(fonts, opt_fontTestStrings || {}, opt_metricCompatibleFonts || null, allModulesLoaded);
89-
}, 0);
100+
if (this.classes_ || this.events_) {
101+
setTimeout(function () {
102+
fontWatcher.watchFonts(fonts, opt_fontTestStrings || {}, opt_metricCompatibleFonts || null, allModulesLoaded);
103+
}, 0);
104+
}
90105
};
91106

92107
/**

0 commit comments

Comments
 (0)