goog.provide('webfont.FontWatcher');
goog.require('webfont.FontWatchRunner'); goog.require('webfont.NativeFontWatchRunner');
/**
* @typedef {Object.<string, Array.<string>>} */
webfont.FontTestStrings;
/**
* @constructor * @param {webfont.DomHelper} domHelper * @param {webfont.EventDispatcher} eventDispatcher * @param {number=} opt_timeout */
webfont.FontWatcher = function(domHelper, eventDispatcher, opt_timeout) {
this.domHelper_ = domHelper; this.eventDispatcher_ = eventDispatcher; this.currentlyWatched_ = 0; this.last_ = false; this.success_ = false; this.timeout_ = opt_timeout;
};
goog.scope(function () {
var FontWatcher = webfont.FontWatcher, FontWatchRunner = webfont.FontWatchRunner, NativeFontWatchRunner = webfont.NativeFontWatchRunner; /** * @type {null|boolean} */ FontWatcher.SHOULD_USE_NATIVE_LOADER = null; /** * @return {string} */ FontWatcher.getUserAgent = function () { return window.navigator.userAgent; }; /** * @return {string} */ FontWatcher.getVendor = function () { return window.navigator.vendor; }; /** * Returns true if this browser has support for * the CSS font loading API. * * @return {boolean} */ FontWatcher.shouldUseNativeLoader = function () { if (FontWatcher.SHOULD_USE_NATIVE_LOADER === null) { if (!!window.FontFace) { var match = /Gecko.*Firefox\/(\d+)/.exec(FontWatcher.getUserAgent()); var safari10Match = /OS X.*Version\/10\..*Safari/.exec(FontWatcher.getUserAgent()) && /Apple/.exec(FontWatcher.getVendor()); if (match) { FontWatcher.SHOULD_USE_NATIVE_LOADER = parseInt(match[1], 10) > 42; } else if (safari10Match) { FontWatcher.SHOULD_USE_NATIVE_LOADER = false; } else { FontWatcher.SHOULD_USE_NATIVE_LOADER = true; } } else { FontWatcher.SHOULD_USE_NATIVE_LOADER = false; } } return FontWatcher.SHOULD_USE_NATIVE_LOADER; }; /** * Watches a set of font families. * @param {Array.<webfont.Font>} fonts The fonts to watch. * @param {webfont.FontTestStrings} fontTestStrings The font test strings for * each family. * @param {Object.<String, boolean>} metricCompatibleFonts * @param {boolean} last True if this is the last set of fonts to watch. */ FontWatcher.prototype.watchFonts = function(fonts, fontTestStrings, metricCompatibleFonts, last) { var length = fonts.length, testStrings = fontTestStrings || {}; if (length === 0 && last) { this.eventDispatcher_.dispatchInactive(); return; } this.currentlyWatched_ += fonts.length; if (last) { this.last_ = last; } var i, fontWatchRunners = []; for (i = 0; i < fonts.length; i++) { var font = fonts[i], testString = testStrings[font.getName()]; this.eventDispatcher_.dispatchFontLoading(font); var fontWatchRunner = null; if (FontWatcher.shouldUseNativeLoader()) { fontWatchRunner = new NativeFontWatchRunner( goog.bind(this.fontActive_, this), goog.bind(this.fontInactive_, this), this.domHelper_, font, this.timeout_, testString ); } else { fontWatchRunner = new FontWatchRunner( goog.bind(this.fontActive_, this), goog.bind(this.fontInactive_, this), this.domHelper_, font, this.timeout_, metricCompatibleFonts, testString ); } fontWatchRunners.push(fontWatchRunner); } for (i = 0; i < fontWatchRunners.length; i++) { fontWatchRunners[i].start(); } }; /** * Called by a FontWatchRunner when a font has been detected as active. * @param {webfont.Font} font * @private */ FontWatcher.prototype.fontActive_ = function(font) { this.eventDispatcher_.dispatchFontActive(font); this.success_ = true; this.decreaseCurrentlyWatched_(); }; /** * Called by a FontWatchRunner when a font has been detected as inactive. * @param {webfont.Font} font * @private */ FontWatcher.prototype.fontInactive_ = function(font) { this.eventDispatcher_.dispatchFontInactive(font); this.decreaseCurrentlyWatched_(); }; /** * @private */ FontWatcher.prototype.decreaseCurrentlyWatched_ = function() { if (--this.currentlyWatched_ == 0 && this.last_) { if (this.success_) { this.eventDispatcher_.dispatchActive(); } else { this.eventDispatcher_.dispatchInactive(); } } };
});