Major overhaul to the theme and now functioning.
This commit is contained in:
+419
@@ -0,0 +1,419 @@
|
||||
v1.6.28 (March 27, 2017)
|
||||
|
||||
* Clear timer timeout when promise resolves.
|
||||
|
||||
v1.6.27 (November 29, 2016)
|
||||
|
||||
* Disable native font loading for Safari 10
|
||||
|
||||
v1.6.26 (July 8, 2016)
|
||||
|
||||
* Add support for latin extended in the Google Fonts module.
|
||||
|
||||
v1.6.25 (July 7, 2016)
|
||||
|
||||
* Add "loadAllFonts" option to Monotype module.
|
||||
* Add documentation on how to use Web Font Loader with Edge Web Fonts.
|
||||
|
||||
v1.6.24 (March 20, 2016)
|
||||
|
||||
* Fix type annotation in DomHelper.
|
||||
|
||||
v1.6.23 (March 20, 2016)
|
||||
|
||||
* Add bower.json
|
||||
* Small code rewrite in order to workaround a bad type cast (Closure Compiler
|
||||
is correct, but reality doesn't always match).
|
||||
|
||||
v1.6.22 (February 29, 2016)
|
||||
|
||||
* Fix bug that caused long loading fonts to get stuck on wf-loading because
|
||||
the timeout never fired (or took a really long time).
|
||||
|
||||
v1.6.21 (February 2, 2016)
|
||||
|
||||
* Fix bug in Google module that caused non-latin to fail on browsers that
|
||||
support the native font loading API.
|
||||
* Fix bug in IE8 where font events sometimes failed due to a timing issue.
|
||||
|
||||
v1.6.20 (January 4, 2016)
|
||||
|
||||
* Add all source files to the npm package.
|
||||
|
||||
v1.6.19 (January 4, 2016)
|
||||
|
||||
* Add src/core files to npm package.
|
||||
|
||||
v1.6.18 (January 4, 2016)
|
||||
|
||||
* Version bump.
|
||||
|
||||
v1.6.17 (January 4, 2016)
|
||||
|
||||
* Upgrade closure compiler and base.js to latest version (no code changes).
|
||||
|
||||
v1.6.16 (December 8, 2015)
|
||||
|
||||
* Add support for detecting font loads even if the font isn't in the CSSOM yet (workaround for a Chrome bug).
|
||||
|
||||
v1.6.15 (November 26, 2015)
|
||||
|
||||
* Temporarily disable the native font loading API in Firefox 42 and below due to a bug.
|
||||
|
||||
v1.6.14 (November 24, 2015)
|
||||
|
||||
* Change media type check to be more reliable on old IE.
|
||||
|
||||
v1.6.13 (November 24, 2015)
|
||||
|
||||
* Fix media type check in IE/Edge.
|
||||
|
||||
v1.6.12 (November 23, 2015)
|
||||
|
||||
* Fix bug that sometimes caused wf-inactive to show when asynchronously loading CSS.
|
||||
|
||||
v1.6.11 (November 17, 2015)
|
||||
|
||||
* Only include production build in npm package
|
||||
* Fix bug that caused duplicate font loads to fail (using the native font loading code)
|
||||
|
||||
v1.6.10 (October 9, 2015)
|
||||
|
||||
* Fix compile warning
|
||||
|
||||
v1.6.9 (October 9, 2015)
|
||||
|
||||
* Fix native font load detection when combined with asynchronous CSS loading
|
||||
* Fix support for font family names starting with a number
|
||||
|
||||
v1.6.8 (October 1, 2015)
|
||||
|
||||
* Add support for the native font loading API.
|
||||
|
||||
v1.6.7 (September 24, 2015)
|
||||
|
||||
* Update Monotype module
|
||||
|
||||
v1.6.6 (August 7, 2015)
|
||||
|
||||
* Fix weird check in insertInto that disallowed adding a link to an empty head element.
|
||||
* Load fonts asynchronously for the Typekit module.
|
||||
* Remove font rulers and trigger callback asynchronously to avoid unnecessary reflows.
|
||||
|
||||
v1.6.5 (July 25, 2015)
|
||||
* Optimise layout calculations
|
||||
* Fix Rubygems source
|
||||
* Simplify internal Google module code
|
||||
|
||||
v1.6.4 (July 9, 2015)
|
||||
* Optimise reflows when setting up test spans.
|
||||
|
||||
v1.6.3 (June 1, 2015)
|
||||
* Fix invalid references to global this (window).
|
||||
|
||||
v1.6.2 (May 29, 2015)
|
||||
* No changes.
|
||||
|
||||
v1.6.1 (May 29, 2015)
|
||||
* Automatically update npm version.
|
||||
|
||||
v1.6.0 (May 28, 2015)
|
||||
* Remove user agent string sniffing. From now on the Web Font Loader will always try to load fonts.
|
||||
|
||||
v1.5.21 (May 26, 2015)
|
||||
* No changes.
|
||||
|
||||
v1.5.20 (May 26, 2015)
|
||||
* Use setTimeout instead of window.setTimeout
|
||||
|
||||
v1.5.19 (May 24, 2015)
|
||||
* Add UMD wrapper
|
||||
|
||||
v1.5.18 (April 15, 2015)
|
||||
* Add configuration option to enable asynchronous CSS (internal API)
|
||||
|
||||
v1.5.17 (April 14, 2015)
|
||||
* Load CSS files asynchronously
|
||||
|
||||
v1.5.16 (March 30, 2015)
|
||||
* Optimise DOM performance in the font watcher.
|
||||
|
||||
v1.5.15 (March 25, 2015)
|
||||
* Increase offset position for ruler so scrollbars are less likely to be triggered by large test strings
|
||||
|
||||
v1.5.14 (January 23, 2015)
|
||||
* Refactor EventDispatcher
|
||||
|
||||
v1.5.13 (January 20, 2015)
|
||||
* Remove unused exports
|
||||
* Move definition of FontTestStrings to where it is first used
|
||||
|
||||
v1.5.12 (January 19, 2015)
|
||||
* Revert using visibility hidden (caused strange artifacts on some sites on iOS browsers)
|
||||
* Fix compiler warnings
|
||||
|
||||
v1.5.11 (January 7, 2015)
|
||||
* Add support for explicitly setting the protocol
|
||||
|
||||
v1.5.10 (December 18, 2014)
|
||||
* Fix parameters passed to Typekit KitJS
|
||||
|
||||
v1.5.9 (December 18, 2014)
|
||||
* Use visibility hidden instead of off-screen positioning
|
||||
* Decouple Typekit internal API
|
||||
* Disable native font loading (see comment)
|
||||
|
||||
v1.5.8 (November 17, 2014)
|
||||
* Add prebuilt library to repository
|
||||
|
||||
v1.5.7 (November 17, 2014)
|
||||
* Decrease default timeout to 3 seconds
|
||||
* Add support for native font loading
|
||||
|
||||
v1.5.6 (September 3, 2014)
|
||||
* Fix double inactive event when all modules fail to load
|
||||
|
||||
v1.5.5 (June 5, 2014)
|
||||
* Add support for the Chromecast browser
|
||||
|
||||
v1.5.4 (May 2, 2014)
|
||||
* Add support for the PlayStation 4 browser
|
||||
|
||||
v1.5.3 (April 8, 2014)
|
||||
* Prevent a potential FOUT when setting the font event classes.
|
||||
* Add "display:block" to test rulers so "* { display: none; }" doesn't override it
|
||||
|
||||
v1.5.2 (January 3, 2014)
|
||||
* Add Copyright, License and Version to the compiled output file(s)
|
||||
* Fix small bug in Google Font module that rejected font variations with dashes
|
||||
|
||||
v1.5.1 (October 15, 2013)
|
||||
* Dispatch wf-loading event synchronously instead of waiting for asynchronous modules
|
||||
* Update README explaining how to use custom fonts without a stylesheet
|
||||
* Add license information to gemspec
|
||||
|
||||
v1.5.0 (September 9, 2013)
|
||||
* Correctly categorize Internet Explorer 11 as an Internet Explorer version.
|
||||
* Add support for custom test strings in the custom module.
|
||||
* Various small bug fixes to the test suite so it runs on all browsers automatically.
|
||||
|
||||
v1.4.12 (August 21, 2013)
|
||||
* Cleared up initialization code and made all modules optional and configurable at compile time
|
||||
|
||||
v1.4.11 (August 8, 2013)
|
||||
* Remove Ascender module (according to Monotype the service has now been shutdown completely.)
|
||||
* Switch Monotype module to use fast.fonts.net instead of fast.fonts.com
|
||||
* Update license
|
||||
|
||||
v1.4.10 (July 31, 2013)
|
||||
* Add loadStylesheet method with optional callback that replaces createCssLink
|
||||
* Remove supportForStyle check because it breaks XHTML/SVG and is no longer necessary
|
||||
* Fix inactive never called when script loading times out
|
||||
* Move test assets into fixtures directory
|
||||
|
||||
v1.4.9 (July 24, 2013)
|
||||
* Disable terminal spec report when not using PhantomJS
|
||||
* Remove obsolete namespace declaration
|
||||
|
||||
v1.4.8 (June 24, 2013)
|
||||
* Add support for the Chromium based Opera browser
|
||||
* Change the debug task to do a Closure Compiler debug build
|
||||
* Fix a global variable leak in the compiled output
|
||||
* Add support for the PhantomJS user agent string
|
||||
|
||||
v1.4.7 (June 6, 2013)
|
||||
* Fix backwards compatibility with version strings for Chrome
|
||||
* Restore specs that test against version strings for backwards compatibility with the old UserAgent API.
|
||||
|
||||
v1.4.6 (May 29, 2013)
|
||||
* Merge font watching strategies from core and the Google module
|
||||
* Add support for the Samsung Galaxy S4 user agent string
|
||||
|
||||
v1.4.5 (May 23, 2013)
|
||||
* Move modules into their own namespace
|
||||
* Add new methods into DomHelper and add specs for all DomHelper methods
|
||||
* Rename watch method so as not to conflict with Firefox Object.prototype.watch
|
||||
|
||||
v1.4.4 (May 22, 2013)
|
||||
* Change the UserAgent API so that it is backwards compatible with older Typekit kits.
|
||||
|
||||
v1.4.3 (May 16, 2013)
|
||||
* UserAgent now maintains version numbers as instances of the Version class.
|
||||
|
||||
v1.4.2 (April 11, 2013)
|
||||
* Namespace is now configurable at compile time
|
||||
* BrowserInfo and UserAgent are exported so Typekit KitJS and the standalone webfontloader can share data
|
||||
* Add "aria-hidden=true" to test spans so screen readers do not read test spans
|
||||
* Fix passing the test strings from the modules to core.
|
||||
|
||||
v1.4.1 (April 8, 2013)
|
||||
* Internal rewrite of font and variations
|
||||
* Fix for the configurable timeout on the Google module
|
||||
|
||||
v1.4.0 (March 28, 2013)
|
||||
* Stop exporting the `addModule` API to dynamically add modules (it didn't work anyway.)
|
||||
* Stop checking the height when monitoring for font load. This turned out to be inconsistent across platforms.
|
||||
|
||||
v1.3.2 (March 27, 2013)
|
||||
* Add support for the Amazon 1 and 2+ browsers.
|
||||
|
||||
v1.3.1 (March 14, 2013)
|
||||
* Change code to use explicit dependencies
|
||||
* Fix unit tests in older browsers
|
||||
* Fix google/FontApiParser.js to work in IE <= 8
|
||||
|
||||
v1.3.0 (February 28, 2013)
|
||||
* New optional configuration parameter `timeout` which lets you customize the default timeout.
|
||||
* Change the Typekit module to use `use.typekit.net` instead of `use.typekit.com`.
|
||||
* Disable height check on OSX and iOS WebKit based browsers which suffer from a metrics bug when loading web fonts.
|
||||
|
||||
v1.2.1 (February 26, 2013)
|
||||
* Fix the possibility of test strings wrapping to a new line and thereby breaking font watching.
|
||||
* Change the FontWatchRunner to not create DOM elements until it is started.
|
||||
* Fix the possibility of extraneous whitespace in class names.
|
||||
* Add a cache buster parameter to the Monotype/Fonts.com module.
|
||||
* Fix the case where there are no fonts to load. Webfontloader will now fire the inactive event correctly.
|
||||
* Test suite now uses the active browser to test font watching in addition to the mocked font watching tests.
|
||||
* Test suite is now using Jasmine instead of JSTestDriver.
|
||||
|
||||
v1.2.0 (January 30, 2013)
|
||||
* Improved font watching for browsers with the WebKit web font fallback bug
|
||||
* Improved font watching in general by comparing both width and height
|
||||
* UserAgent user interface has changed with the introduction of a BrowserInfo object that contains information derived from the user agent string
|
||||
* The custom module now supports loading font variations
|
||||
|
||||
v1.1.2 (January 21, 2013)
|
||||
* Added parameter to Google module to do character based subsetting.
|
||||
* Made WebKit useragent check less strict about capitalization for LG L160 phones that apparently use 'AppleWebkit' instead of 'AppleWebKit' in their useragent strings.
|
||||
|
||||
v1.1.1 (December 12, 2012)
|
||||
* Added the ability to recognize BlackBerry devices, which have web font support (WOFF) in platform version 10+
|
||||
* Added a new browser name "BuiltinBrowser" to recognize built-in browsers on mobile platforms which we previously called "Safari" (applies to Android's "Browser" app and BlackBerry's built-in browser)
|
||||
* Fixed a bug in the Monotype module which caused a double active event in IE9 and no active event in IE8 (reported in issue #64)
|
||||
* Fixed some typos in the demo pages
|
||||
|
||||
v1.1.0 (December 5, 2012)
|
||||
* Adds the ability to load fonts into a same-origin child window or iframe using the new optional `context` configuration option (thanks to @ryanwolf of Google).
|
||||
* Updates the demos to fix broken stuff and demonstrate the new context option in action.
|
||||
* DomHelper interface changed to take the main window and an optional separate window for loading.
|
||||
* Methods added to retrieve both windows and get the correct protocol for assets from the location's protocol.
|
||||
|
||||
v1.0.31 (September 11, 2012)
|
||||
* Improvements to Google's module to recognize more variation descriptor formats (such as 100italic and 200n).
|
||||
|
||||
v1.0.30 (August 17, 2012)
|
||||
* Added support for detecting the Windows Phone platform in UserAgentParser, which supports web fonts at version 8 and above.
|
||||
* Changes to make the global namespace of the library easier to configure when used in 3rd-party projects. (Thanks cbosco!)
|
||||
|
||||
v1.0.29 (July 26, 2012)
|
||||
* Added test to ensure Firefox for Android is properly detected as "Firefox" by UserAgentParser.
|
||||
* Added test to ensure Opera Mobile for Android is properly detected as "Opera" by UserAgentParser.
|
||||
* Changed detection so that Chrome for iOS is detected as "Chrome" instead of "Safari".
|
||||
* Changed detection so that Opera Mini is correctly detected as "OperaMini" (without font support) instead of "Opera" (with font support).
|
||||
* Fixed a bug in Google Web Fonts module when requesting a font family with character sets and no variations.
|
||||
* Scaled back the number of fall back fonts used in the Google Web Fonts font watching code.
|
||||
|
||||
v1.0.28 (June 4, 2012)
|
||||
* Added support for detecting the Chrome OS platform ("CrOS") in the UserAgentParser.
|
||||
|
||||
v1.0.27 (April 20, 2012)
|
||||
* Updated DomHelper to not require a UserAgent instance. Feature-detection is not used instead of UA detection for switching DOM methods.
|
||||
|
||||
v1.0.26 (February 8, 2012)
|
||||
* Updated the included version of the Closure JS compiler jar to 1741, to handle newer annotation styles.
|
||||
* Added a missing param annotation for the new FontWatcher.watch argument.
|
||||
* Added param annotations for Google's custom FontWatchRunner implementation.
|
||||
* Updated the Google Web Fonts API parser to accept family names with a plus sign.
|
||||
|
||||
v1.0.25 (February 7, 2012)
|
||||
* Updated the user agent parser to recognize Chrome for Android properly as a Chrome browser.
|
||||
|
||||
v1.0.24 (January 9, 2012)
|
||||
* Updated the standard test string from "BESs" to "BESbswy" for more width variability.
|
||||
* Improved Google's custom FontWatchRunner implementation for Webkit to work around an issue where the browser reports the 400 weight's width when it is already loaded.
|
||||
|
||||
v1.0.23 (November 29, 2011)
|
||||
* Made the FontWatchRunner implementation configurable on a module-by-module basis.
|
||||
* Added a new .start() method to FontWatchRunner to actually kick off font loading detection.
|
||||
* Added a different FontWatchRunner implementation that Google's module uses to work around a Webkit browser bug. This implementation won't trigger active early, but may trigger active much later, so it's not the default for all modules.
|
||||
* Updated the implementation of Fontdeck's module to defer loading responsibility to their JS.
|
||||
|
||||
v1.0.22 (July 1, 2011)
|
||||
* Fixed a bug in Webkit-based browsers with font detection where active would trigger without the font actually being active yet.
|
||||
* Increased the frequency of checking the widths of the font watcher spans.
|
||||
|
||||
v1.0.21 (June 17, 2011)
|
||||
* Added a protocol detect for the Typekit module so JS is loaded securely on secure pages. Thanks to bee525 for the pull request.
|
||||
|
||||
v1.0.20 (March 30, 2011)
|
||||
* Changed CSS style for hidden span so it's not affected by inline or floated elements at the end of the body
|
||||
|
||||
v1.0.19 (March 3, 2011)
|
||||
* Add a module for Monotype.
|
||||
|
||||
v1.0.18 (January 24, 2011)
|
||||
* Improve behavior of CSS classes over multiple loads on a single page. (Documented in docs/EVENTS.md)
|
||||
* Add support for international subsets in the Google module.
|
||||
* Add a module for Fontdeck.
|
||||
|
||||
v1.0.17 (December 1, 2010)
|
||||
* Changed CSS style for hidden span in order to be less affected by environment
|
||||
* Removed restriction on iPhone/iPad/iPod in the google modules
|
||||
|
||||
v1.0.16 (November 18, 2010)
|
||||
* Fix a bug where we fail to detect that fonts have loaded if they have the same width as the fallback font.
|
||||
|
||||
v1.0.15 (October 14, 2010)
|
||||
* Fix an error parsing platform version in IE, when it has no items following the platform in the UA string.
|
||||
|
||||
v1.0.14 (October 14, 2010)
|
||||
* Bugfix: fixed IE issue in google module.
|
||||
|
||||
v1.0.13 (September 30, 2010)
|
||||
* Added support for detecting Adobe Air.
|
||||
|
||||
v1.0.12 (September 30, 2010)
|
||||
* Bugfix: google module, change the url builder to handle integrations.
|
||||
|
||||
v1.0.10 (September 24, 2010)
|
||||
* Bugfix: extra alert
|
||||
|
||||
v1.0.10 (September 22, 2010)
|
||||
* Add support for customizable FontWatcher test string, for international
|
||||
fonts.
|
||||
|
||||
v1.0.9 (September 10, 2010)
|
||||
* Bugfix: of the bug fix
|
||||
|
||||
v1.0.8 (September 10, 2010)
|
||||
* Bugfix: fix type definitions
|
||||
|
||||
v1.0.7 (August 31, 2010)
|
||||
* Fix that wf-loading was not removed in the case of wf-inactive because of
|
||||
a timeout.
|
||||
* Add UserAgent#getDocumentMode to aid in determining font support in IE.
|
||||
|
||||
v1.0.6 (July 20, 2010)
|
||||
* Add JsDoc comments and type annotations for the Closure compiler. Fixes
|
||||
several small bugs caught by the compiler in doing so.
|
||||
|
||||
v1.0.5 (July 12, 2010)
|
||||
* webfont.UserAgent now provides getPlatformVersion. WebFont Loader is now
|
||||
packaged as a ruby gem.
|
||||
|
||||
v1.0.4 (June 14, 2010)
|
||||
* Add a module for Ascender's Fonts Live.
|
||||
|
||||
v1.0.3 (June 6, 2010)
|
||||
* IE fixes.
|
||||
|
||||
v1.0.2 (June 1, 2010)
|
||||
* Added a way of loading the WebFont Loader script asynchronously.
|
||||
|
||||
v1.0.1 (May 20, 2010)
|
||||
* Fix namespace pollution by wrapping all of the code in a closure.
|
||||
|
||||
v1.0.0 (May 19, 2010)
|
||||
* Initial release!
|
||||
* Modules: google, typekit, custom
|
||||
* Events: loading, active, inactive, fontloading, fontactive, fontintactive
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
+394
@@ -0,0 +1,394 @@
|
||||
# Web Font Loader
|
||||
|
||||
Web Font Loader gives you added control when using linked fonts via `@font-face`. It provides a common interface to loading fonts regardless of the source, then adds a standard set of events you may use to control the loading experience. The Web Font Loader is able to load fonts from [Google Fonts](http://www.google.com/fonts/), [Typekit](http://www.typekit.com/), [Fonts.com](http://www.fonts.com/), and [Fontdeck](http://fontdeck.com/), as well as self-hosted web fonts. It is co-developed by [Google](http://www.google.com/) and [Typekit](http://www.typekit.com).
|
||||
|
||||
[](https://travis-ci.org/typekit/webfontloader)
|
||||
|
||||
## Contents
|
||||
|
||||
* [Get started](#get-started)
|
||||
* [Configuration](#configuration)
|
||||
* [Events](#events)
|
||||
* [Timeout](#timeouts)
|
||||
* [Iframes](#iframes)
|
||||
* [Modules](#modules)
|
||||
* [Adobe Edge Web Fonts](#adobe-edge-web-fonts)
|
||||
* [Custom](#custom)
|
||||
* [Fontdeck](#fontdeck)
|
||||
* [Fonts.com](#fontscom)
|
||||
* [Google](#google)
|
||||
* [Typekit](#typekit)
|
||||
* [Browser support](#browser-support)
|
||||
* [License](#copyright-and-license)
|
||||
|
||||
## Get Started
|
||||
|
||||
To use the Web Font Loader library, just include it in your page and tell it which fonts to load. For example, you could load fonts from [Google Fonts](http://www.google.com/fonts/) using the Web Font Loader hosted on [Google Hosted Libraries](https://developers.google.com/speed/libraries/) using the following code.
|
||||
|
||||
```html
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
|
||||
<script>
|
||||
WebFont.load({
|
||||
google: {
|
||||
families: ['Droid Sans', 'Droid Serif']
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
Alternatively, you can link to the latest `1.x` version of the Web Font Loader by using `https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js` as the `script` source. Note that the version in this url is less specific. It will always load the latest `1.x` version, but it also has a shorter cache time to ensure that your page gets updates in a timely manner. For performance reasons, we recommend using an explicit version number (such as `1.6.26`) in urls when using the Web Font Loader in production. You can manually update the Web Font Loader version number in the url when you want to adopt a new version.
|
||||
|
||||
Web Font Loader is also available on the [jsDelivr](http://www.jsdelivr.com/projects/webfontloader) & [CDNJS](https://cdnjs.com/libraries/webfont) CDNs.
|
||||
|
||||
It is also possible to use the Web Font Loader asynchronously. For example, to load [Typekit](http://www.typekit.com) fonts asynchronously, you could use the following code.
|
||||
|
||||
```html
|
||||
<script>
|
||||
WebFontConfig = {
|
||||
typekit: { id: 'xxxxxx' }
|
||||
};
|
||||
|
||||
(function(d) {
|
||||
var wf = d.createElement('script'), s = d.scripts[0];
|
||||
wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
|
||||
wf.async = true;
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})(document);
|
||||
</script>
|
||||
```
|
||||
|
||||
Using the Web Font Loader asynchronously avoids blocking your page while loading the JavaScript. Be aware that if the script is used asynchronously, the rest of the page might render before the Web Font Loader is loaded and executed, which can cause a [Flash of Unstyled Text (FOUT)](http://help.typekit.com/customer/portal/articles/6852).
|
||||
|
||||
The FOUT can be more easily avoided when loading the Web Font Loader synchronously, as it will automatically set the `wf-loading` class on the HTML element as soon as `Webfont.load` has been called. The browser will wait for the script to load before continuing to load the rest of the content, FOUT is avoided.
|
||||
|
||||
Web Font Loader is also available on npm as a CommonJS module. Just `npm install webfontloader` and then require it in your code.
|
||||
|
||||
```js
|
||||
var WebFont = require('webfontloader');
|
||||
|
||||
WebFont.load({
|
||||
google: {
|
||||
families: ['Droid Sans', 'Droid Serif']
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The Web Font Loader configuration is defined by a global variable named `WebFontConfig`, or passed directly to the `WebFont.load` method. It defines which fonts to load from each web font provider and gives you the option to specify callbacks for certain events. When using the asynchronous approach, you must define the global variable `WebFontConfig` before the code that loads the Web Font Loader (as in the example above).
|
||||
|
||||
### Events
|
||||
|
||||
Web Font Loader provides an event system that developers can hook into. It gives you notifications of the font loading sequence in both CSS and JavaScript.
|
||||
|
||||
* `loading` - This event is triggered when all fonts have been requested.
|
||||
* `active` - This event is triggered when the fonts have rendered.
|
||||
* `inactive` - This event is triggered when the browser does not support linked fonts *or* if none of the fonts could be loaded.
|
||||
* `fontloading` - This event is triggered once for each font that's loaded.
|
||||
* `fontactive` - This event is triggered once for each font that renders.
|
||||
* `fontinactive` - This event is triggered if the font can't be loaded.
|
||||
|
||||
CSS events are implemented as classes on the `html` element. The following classes are set on the `html` element:
|
||||
|
||||
```css
|
||||
.wf-loading
|
||||
.wf-active
|
||||
.wf-inactive
|
||||
.wf-<familyname>-<fvd>-loading
|
||||
.wf-<familyname>-<fvd>-active
|
||||
.wf-<familyname>-<fvd>-inactive
|
||||
```
|
||||
|
||||
The `<familyname>` placeholder will be replaced by a sanitized version of the name of each font family. Spaces and underscores are removed from the name, and all characters are converted to lower case. For example, `Droid Sans` becomes `droidsans`. The `<fvd>` placeholder is a [Font Variation Description](https://github.com/typekit/fvd). Put simply, it's a shorthand for describing the style and weight of a particular font. Here are a few examples:
|
||||
|
||||
```css
|
||||
/* n4 */
|
||||
@font-face { font-style: normal; font-weight: normal; }
|
||||
|
||||
/* i7 */
|
||||
@font-face { font-style: italic; font-weight: bold; }
|
||||
```
|
||||
|
||||
Keep in mind that `font-weight: normal` maps to `font-weight: 400` and `font-weight: bold` maps to `font-weight: 700`. If no style/weight is specified, the default `n4` (`font-style: normal; font-weight: normal;`) will be used.
|
||||
|
||||
If fonts are loaded multiple times on a single page, the CSS classes continue to update to reflect the current state of the page. The global `wf-loading` class is applied whenever fonts are being requested (even if other fonts are already active or inactive). The `wf-inactive` class is applied only if none of the fonts on the page have rendered. Otherwise, the `wf-active` class is applied (even if some fonts are inactive).
|
||||
|
||||
JavaScript events are implemented as callback functions on the `WebFontConfig` configuration object.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
loading: function() {},
|
||||
active: function() {},
|
||||
inactive: function() {},
|
||||
fontloading: function(familyName, fvd) {},
|
||||
fontactive: function(familyName, fvd) {},
|
||||
fontinactive: function(familyName, fvd) {}
|
||||
};
|
||||
```
|
||||
|
||||
The `fontloading`, `fontactive` and `fontinactive` callbacks are passed the family name and font variation description of the font that concerns the event.
|
||||
|
||||
It is possible to disable setting classes on the HTML element by setting the `classes` configuration parameter to `false` (defaults to `true`).
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
classes: false
|
||||
};
|
||||
```
|
||||
|
||||
You can also disable font events (callbacks) by setting the `events` parameter to `false` (defaults to `true`).
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
events: false
|
||||
};
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### Timeouts
|
||||
|
||||
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 successfully renders, the `active` event will be triggered, else the `inactive` event will be triggered.
|
||||
|
||||
You can change the default timeout by using the `timeout` option on the `WebFontConfig` object.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
google: {
|
||||
families: ['Droid Sans']
|
||||
},
|
||||
timeout: 2000 // Set the timeout to two seconds
|
||||
};
|
||||
```
|
||||
|
||||
The timeout value should be in milliseconds, and defaults to 3000 milliseconds (3 seconds) if not supplied.
|
||||
|
||||
### Iframes
|
||||
|
||||
Usually, it's easiest to include a copy of Web Font Loader in every window where fonts are needed, so that each window manages its own fonts. However, if you need to have a single window manage fonts for multiple same-origin child windows or iframes that are built up using JavaScript, Web Font Loader supports that as well. Just use the optional `context` configuration option and give it a reference to the target window for loading:
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
google: {
|
||||
families: ['Droid Sans']
|
||||
},
|
||||
context: frames['my-child']
|
||||
};
|
||||
```
|
||||
|
||||
This is an advanced configuration option that isn't needed for most use cases.
|
||||
|
||||
## Modules
|
||||
|
||||
Web Font Loader provides a module system so that any web font provider can contribute code that allows their fonts to be loaded. This makes it possible to use multiple web font providers at the same time. The specifics of each provider currently supported by the library are documented here.
|
||||
|
||||
### Adobe Edge Web Fonts
|
||||
|
||||
When using [Adobe Edge Web Fonts](https://edgewebfonts.adobe.com/), you can use the `typekit` module by passing in a catenated list of fonts in the `id` parameter and set the `api` parameter to point to the Edge Web Fonts URL.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
typekit: {
|
||||
id: 'adamina;advent-pro',
|
||||
api: '//use.edgefonts.net'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Custom
|
||||
|
||||
To load fonts from any external stylesheet, use the `custom` module. Here you'll
|
||||
need to specify the font family names you're trying to load, and optionally the url of the stylesheet that provides the `@font-face` declarations for those fonts.
|
||||
|
||||
You can specify a specific font variation or set of variations to load and watch
|
||||
by appending the variations separated by commas to the family name separated by
|
||||
a colon. Variations are specified using [FVD notation](https://github.com/typekit/fvd).
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
custom: {
|
||||
families: ['My Font', 'My Other Font:n4,i4,n7'],
|
||||
urls: ['/fonts.css']
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
In this example, the `fonts.css` file might look something like this:
|
||||
|
||||
```css
|
||||
@font-face {
|
||||
font-family: 'My Font';
|
||||
src: ...;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'My Other Font';
|
||||
font-style: normal;
|
||||
font-weight: normal; /* or 400 */
|
||||
src: ...;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'My Other Font';
|
||||
font-style: italic;
|
||||
font-weight: normal; /* or 400 */
|
||||
src: ...;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'My Other Font';
|
||||
font-style: normal;
|
||||
font-weight: bold; /* or 700 */
|
||||
src: ...;
|
||||
}
|
||||
```
|
||||
|
||||
If your fonts are already included in another stylesheet you can also leave out the `urls` array and just specify font family names to start font loading. As long as the names match those that are declared in the `families` array, the proper loading classes will be applied to the html element.
|
||||
|
||||
```html
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
|
||||
<script>
|
||||
WebFont.load({
|
||||
custom: {
|
||||
families: ['My Font']
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family:"My Font";
|
||||
src:url("assets/fonts/my_font.woff") format("woff");
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
The custom module also supports customizing the test strings that are used to determine whether or not a font has loaded. This can be used to load fonts with custom subsets or glyphs in the private use unicode area.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
custom: {
|
||||
families: ['My Font'],
|
||||
testStrings: {
|
||||
'My Font': '\uE003\uE005'
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Tests strings should be specified on a per font basis and contain at least one character. If not specified the default test string (`BESbswy`) is used.
|
||||
|
||||
### Fontdeck
|
||||
|
||||
To use the [Fontdeck](http://fontdeck.com/) module, specify the ID of your website. You can find this ID on the website page within your account settings.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
fontdeck: {
|
||||
id: 'xxxxx'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Fonts.com
|
||||
|
||||
When using [Fonts.com web fonts](http://www.fonts.com/web-fonts/) specify your Project ID.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
monotype: {
|
||||
projectId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
||||
version: 12345, // (optional, flushes the CDN cache)
|
||||
loadAllFonts: true //(optional, loads all project fonts)
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The Fonts.com module has an optional `version` option which acts as a cache-buster, optional `loadAllFonts` loads all project fonts. By default, Fonts.com module loads only fonts used on the page.
|
||||
|
||||
### Google
|
||||
|
||||
Using [Google's Font API](https://code.google.com/apis/webfonts/docs/getting_started.html), name the font families you'd like to load. You can use the same [syntax](https://developers.google.com/fonts/docs/getting_started#Syntax) as in the Font API to specify styles. Please note that the Google module does not support the FVD syntax that is used in the custom module.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
google: {
|
||||
families: ['Droid Sans', 'Droid Serif:bold']
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Sometimes the font you requested doesn't come in the default weight (e.g. 400) and you need to explicitly request the variation you want for font events to work (e.g. `300`, `700`, etc.):
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
google: {
|
||||
families: ['Open Sans Condensed:300,700']
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
If you need to specify character subsets other than the default (e.g.: greek script in addition to latin), you must append the subset string to the requested family string after a colon. The subset string should follow the [Google documentation](https://developers.google.com/fonts/docs/getting_started#Subsets) (subset names separated by commas):
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
google: {
|
||||
families: ['Open Sans Condensed:300,700:latin,greek']
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
You can also supply the `text` parameter to perform character subsetting:
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
google: {
|
||||
families: ['Droid Sans', 'Droid Serif'],
|
||||
text: 'abcdefghijklmnopqrstuvwxyz!'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The `text` subsetting functionality is only available for the Google module.
|
||||
|
||||
### Typekit
|
||||
|
||||
When using [Typekit](http://www.typekit.com), specify the Kit to retrieve by its ID. You can find the Kit ID within Typekit's Kit Editor interface.
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
typekit: {
|
||||
id: 'xxxxxx'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**FYI:** Typekit's own JavaScript is built using the Web Font Loader library and already provides all of the same font event functionality. If you're using Typekit, you should use their embed codes directly unless you also need to load web fonts from other providers on the same page.
|
||||
|
||||
## Browser Support
|
||||
|
||||
Every web browser has varying levels of support for fonts linked via `@font-face`. Web Font Loader determines support for web fonts is using the browser's user agent string. The user agent string may claim to support a web font format when it in fact does not. This is especially noticeable on mobile browsers with a "Desktop" mode, which usually identify as Chrome on Linux. In this case a web font provider may decide to send WOFF fonts to the device because the real desktop Chrome supports it, while the mobile browser does not. The Web Font Loader is not designed to handle these cases and it defaults to believing what's in the user agent string. Web font providers can build on top of the basic Web Font Loader functionality to handle these special cases individually.
|
||||
|
||||
If Web Font Loader determines that the current browser does not support `@font-face`, the `inactive` event will be triggered.
|
||||
|
||||
When loading fonts from multiple providers, each provider may or may not support a given browser. If Web Font Loader determines that the current browser can support `@font-face`, and *at least* one provider is able to serve fonts, the fonts from that provider will be loaded. When finished, the `active` event will be triggered.
|
||||
|
||||
For fonts loaded from supported providers, the `fontactive` event will be triggered. For fonts loaded from a provider that *does not* support the current browser, the `fontinactive` event will be triggered.
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
WebFontConfig = {
|
||||
providerA: 'Family1',
|
||||
providerB: 'Family2'
|
||||
};
|
||||
```
|
||||
|
||||
If `providerA` can serve fonts to a browser, but `providerB` cannot, The `fontinactive` event will be triggered for `Family2`. The `fontactive` event will be triggered for `Family1` once it loads, as will the `active` event.
|
||||
|
||||
## Copyright and License
|
||||
|
||||
Web Font Loader Copyright (c) 2010-2017 Adobe Systems Incorporated, Google Incorporated.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "webfontloader",
|
||||
"version": "1.6.28",
|
||||
"description": "Web Font Loader gives you added control when using linked fonts via @font-face.",
|
||||
"main": "webfontloader.js",
|
||||
"scripts": {
|
||||
"test": "phantomjs tools/jasmine-phantomjs/jasmine-phantomjs.js spec/index.html"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/typekit/webfontloader.git"
|
||||
},
|
||||
"keywords": [
|
||||
"web",
|
||||
"fonts",
|
||||
"webfonts",
|
||||
"font",
|
||||
"loader",
|
||||
"@font-face"
|
||||
],
|
||||
"files": [
|
||||
"webfontloader.js",
|
||||
"src/**/*.js"
|
||||
],
|
||||
"contributors": [
|
||||
"Ryan Carver <ryan@typekit.com>",
|
||||
"Jeremie Lenfant-engelmann <jeremiele@google.com>",
|
||||
"Sean McBride <sean@typekit.com>",
|
||||
"Bram Stein <bram@typekit.com>"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/typekit/webfontloader/issues"
|
||||
},
|
||||
"homepage": "https://github.com/typekit/webfontloader",
|
||||
"devDependencies": {}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
/* Web Font Loader v{{version}} - (c) Adobe Systems, Google. License: Apache 2.0 */
|
||||
(function(){{{source}}}());
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
goog.provide('webfont.CssClassName');
|
||||
|
||||
/**
|
||||
* Handles sanitization and construction of css class names.
|
||||
* @param {string=} opt_joinChar The character to join parts of the name on.
|
||||
* Defaults to '-'.
|
||||
* @constructor
|
||||
*/
|
||||
webfont.CssClassName = function(opt_joinChar) {
|
||||
/** @type {string} */
|
||||
this.joinChar_ = opt_joinChar || webfont.CssClassName.DEFAULT_JOIN_CHAR;
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.CssClassName.DEFAULT_JOIN_CHAR = '-';
|
||||
|
||||
goog.scope(function () {
|
||||
var CssClassName = webfont.CssClassName;
|
||||
|
||||
/**
|
||||
* Sanitizes a string for use as a css class name. Removes non-word and
|
||||
* underscore characters.
|
||||
* @param {string} name The string.
|
||||
* @return {string} The sanitized string.
|
||||
*/
|
||||
CssClassName.prototype.sanitize = function(name) {
|
||||
return name.replace(/[\W_]+/g, '').toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds a complete css class name given a variable number of parts.
|
||||
* Sanitizes, then joins the parts together.
|
||||
* @param {...string} var_args The parts to join.
|
||||
* @return {string} The sanitized and joined string.
|
||||
*/
|
||||
CssClassName.prototype.build = function(var_args) {
|
||||
var parts = []
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
parts.push(this.sanitize(arguments[i]));
|
||||
}
|
||||
return parts.join(this.joinChar_);
|
||||
};
|
||||
});
|
||||
+405
@@ -0,0 +1,405 @@
|
||||
goog.provide('webfont.DomHelper');
|
||||
|
||||
/**
|
||||
* Handles common DOM manipulation tasks. The aim of this library is to cover
|
||||
* the needs of typical font loading. Not more, not less.
|
||||
* @param {Window} mainWindow The main window webfontloader.js is loaded in.
|
||||
* @param {Window=} opt_loadWindow The window we'll load the font into. By
|
||||
* default, the main window is used.
|
||||
* @constructor
|
||||
*/
|
||||
webfont.DomHelper = function(mainWindow, opt_loadWindow) {
|
||||
this.mainWindow_ = mainWindow;
|
||||
this.loadWindow_ = opt_loadWindow || mainWindow;
|
||||
|
||||
/** @type {string} */
|
||||
this.protocol_;
|
||||
|
||||
/** @type {Document} */
|
||||
this.document_ = this.loadWindow_.document;
|
||||
};
|
||||
|
||||
goog.scope(function () {
|
||||
var DomHelper = webfont.DomHelper;
|
||||
|
||||
/**
|
||||
* The NativeFontWatchRunnner depends on the correct and reliable
|
||||
* |onload| event, and browsers with the native font loading API
|
||||
* have reliable @onload support as far as we know. So we use the
|
||||
* event for such a case and unconditionally invokes the callback
|
||||
* otherwise.
|
||||
*
|
||||
* @const
|
||||
* @type {boolean}
|
||||
*/
|
||||
DomHelper.CAN_WAIT_STYLESHEET = !!window['FontFace'];
|
||||
|
||||
/**
|
||||
* Creates an element.
|
||||
* @param {string} elem The element type.
|
||||
* @param {Object=} opt_attr A hash of attribute key/value pairs.
|
||||
* @param {string=} opt_innerHtml Contents of the element.
|
||||
* @return {Element} the new element.
|
||||
*/
|
||||
DomHelper.prototype.createElement = function(elem, opt_attr,
|
||||
opt_innerHtml) {
|
||||
var domElement = this.document_.createElement(elem);
|
||||
|
||||
if (opt_attr) {
|
||||
for (var attr in opt_attr) {
|
||||
// protect against native prototype augmentations
|
||||
if (opt_attr.hasOwnProperty(attr)) {
|
||||
if (attr == "style") {
|
||||
this.setStyle(domElement, opt_attr[attr]);
|
||||
} else {
|
||||
domElement.setAttribute(attr, opt_attr[attr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opt_innerHtml) {
|
||||
domElement.appendChild(this.document_.createTextNode(opt_innerHtml));
|
||||
}
|
||||
return domElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts an element into the document. This is intended for unambiguous
|
||||
* elements such as html, body, head.
|
||||
* @param {string} tagName The element name.
|
||||
* @param {Element} e The element to append.
|
||||
* @return {boolean} True if the element was inserted.
|
||||
*/
|
||||
DomHelper.prototype.insertInto = function(tagName, e) {
|
||||
var t = this.document_.getElementsByTagName(tagName)[0];
|
||||
|
||||
if (!t) { // opera allows documents without a head
|
||||
t = document.documentElement;
|
||||
}
|
||||
|
||||
// This is safer than appendChild in IE. appendChild causes random
|
||||
// JS errors in IE. Sometimes errors in other JS exectution, sometimes
|
||||
// complete 'This page cannot be displayed' errors. For our purposes,
|
||||
// it's equivalent because we don't need to insert at any specific
|
||||
// location.
|
||||
t.insertBefore(e, t.lastChild);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls a function when the body tag exists.
|
||||
* @param {function()} callback The function to call.
|
||||
*/
|
||||
DomHelper.prototype.whenBodyExists = function(callback) {
|
||||
var that = this;
|
||||
|
||||
if (that.document_.body) {
|
||||
callback();
|
||||
} else {
|
||||
if (that.document_.addEventListener) {
|
||||
that.document_.addEventListener('DOMContentLoaded', callback);
|
||||
} else {
|
||||
that.document_.attachEvent('onreadystatechange', function () {
|
||||
if (that.document_.readyState == 'interactive' || that.document_.readyState == 'complete') {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes an element from the DOM.
|
||||
* @param {Element} node The element to remove.
|
||||
* @return {boolean} True if the element was removed.
|
||||
*/
|
||||
DomHelper.prototype.removeElement = function(node) {
|
||||
if (node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use updateClassName().
|
||||
*
|
||||
* Appends a name to an element's class attribute.
|
||||
* @param {Element} e The element.
|
||||
* @param {string} name The class name to add.
|
||||
*/
|
||||
DomHelper.prototype.appendClassName = function(e, name) {
|
||||
this.updateClassName(e, [name]);
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use updateClassName().
|
||||
*
|
||||
* Removes a name to an element's class attribute.
|
||||
* @param {Element} e The element.
|
||||
* @param {string} name The class name to remove.
|
||||
*/
|
||||
DomHelper.prototype.removeClassName = function(e, name) {
|
||||
this.updateClassName(e, null, [name]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates an element's class attribute in a single change. This
|
||||
* allows multiple updates in a single class name change so there
|
||||
* is no chance for a browser to relayout in between changes.
|
||||
*
|
||||
* @param {Element} e The element.
|
||||
* @param {Array.<string>=} opt_add List of class names to add.
|
||||
* @param {Array.<string>=} opt_remove List of class names to remove.
|
||||
*/
|
||||
DomHelper.prototype.updateClassName = function (e, opt_add, opt_remove) {
|
||||
var add = opt_add || [],
|
||||
remove = opt_remove || [];
|
||||
|
||||
var classes = e.className.split(/\s+/);
|
||||
|
||||
for (var i = 0; i < add.length; i += 1) {
|
||||
var found = false;
|
||||
|
||||
for (var j = 0; j < classes.length; j += 1) {
|
||||
if (add[i] === classes[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
classes.push(add[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var remainingClasses = [];
|
||||
|
||||
for (var i = 0; i < classes.length; i += 1) {
|
||||
var found = false;
|
||||
|
||||
for (var j = 0; j < remove.length; j += 1) {
|
||||
if (classes[i] === remove[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
remainingClasses.push(classes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
e.className = remainingClasses.join(' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/^\s+|\s+$/, '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if an element has a given class name and false otherwise.
|
||||
* @param {Element} e The element.
|
||||
* @param {string} name The class name to check for.
|
||||
* @return {boolean} Whether or not the element has this class name.
|
||||
*/
|
||||
DomHelper.prototype.hasClassName = function(e, name) {
|
||||
var classes = e.className.split(/\s+/);
|
||||
for (var i = 0, len = classes.length; i < len; i++) {
|
||||
if (classes[i] == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the style attribute on an element.
|
||||
* @param {Element} e The element.
|
||||
* @param {string} styleString The style string.
|
||||
*/
|
||||
DomHelper.prototype.setStyle = function(e, styleString) {
|
||||
e.style.cssText = styleString;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {Window} The main window webfontloader.js is loaded in (for config).
|
||||
*/
|
||||
DomHelper.prototype.getMainWindow = function() {
|
||||
return this.mainWindow_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {Window} The window that we're loading the font(s) into.
|
||||
*/
|
||||
DomHelper.prototype.getLoadWindow = function() {
|
||||
return this.loadWindow_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the hostname of the current document.
|
||||
* @return {string} hostname.
|
||||
*/
|
||||
DomHelper.prototype.getHostName = function() {
|
||||
return this.getLoadWindow().location.hostname || this.getMainWindow().location.hostname;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a style element.
|
||||
* @param {string} css Contents of the style element.
|
||||
* @return {Element} a DOM element.
|
||||
*/
|
||||
DomHelper.prototype.createStyle = function(css) {
|
||||
var e = this.createElement('style');
|
||||
|
||||
e.setAttribute('type', 'text/css');
|
||||
if (e.styleSheet) { // IE
|
||||
e.styleSheet.cssText = css;
|
||||
} else {
|
||||
e.appendChild(document.createTextNode(css));
|
||||
}
|
||||
return e;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads an external stylesheet.
|
||||
*
|
||||
* @param {string} href the URL of the stylesheet
|
||||
* @param {function(Error)=} opt_callback Called when the stylesheet has loaded or failed to
|
||||
* load. Note that the callback is *NOT* guaranteed to be called in all browsers. The first
|
||||
* argument to the callback is an error object that is falsy when there are no errors and
|
||||
* truthy when there are.
|
||||
* @param {boolean=} opt_async True if the stylesheet should be loaded asynchronously. Defaults to false.
|
||||
* @return {Element} The link element
|
||||
*/
|
||||
DomHelper.prototype.loadStylesheet = function (href, opt_callback, opt_async) {
|
||||
var link = this.createElement('link', {
|
||||
'rel': 'stylesheet',
|
||||
'href': href,
|
||||
'media': (opt_async ? 'only x' : 'all')
|
||||
});
|
||||
|
||||
var sheets = this.document_.styleSheets,
|
||||
eventFired = false,
|
||||
asyncResolved = !opt_async,
|
||||
callbackArg = null,
|
||||
callback = opt_callback || null;
|
||||
|
||||
function mayInvokeCallback() {
|
||||
if (callback && eventFired && asyncResolved) {
|
||||
callback(callbackArg);
|
||||
callback = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (DomHelper.CAN_WAIT_STYLESHEET) {
|
||||
link.onload = function () {
|
||||
eventFired = true;
|
||||
mayInvokeCallback();
|
||||
};
|
||||
|
||||
link.onerror = function () {
|
||||
eventFired = true;
|
||||
callbackArg = new Error('Stylesheet failed to load');
|
||||
mayInvokeCallback();
|
||||
};
|
||||
} else {
|
||||
// Some callers expect opt_callback being called asynchronously.
|
||||
setTimeout(function () {
|
||||
eventFired = true;
|
||||
mayInvokeCallback();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function onStylesheetAvailable(callback) {
|
||||
for (var i = 0; i < sheets.length; i++) {
|
||||
if (sheets[i].href && sheets[i].href.indexOf(href) !== -1) {
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
onStylesheetAvailable(callback);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function onMediaAvailable(callback) {
|
||||
for (var i = 0; i < sheets.length; i++) {
|
||||
if (sheets[i].href && sheets[i].href.indexOf(href) !== -1 && sheets[i].media) {
|
||||
/**
|
||||
* @type {string|MediaList|null}
|
||||
*/
|
||||
var media = sheets[i].media;
|
||||
|
||||
if (media === "all" || (media.mediaText && media.mediaText === "all")) {
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
onMediaAvailable(callback);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
this.insertInto('head', link);
|
||||
|
||||
if (opt_async) {
|
||||
onStylesheetAvailable(function () {
|
||||
link.media = "all";
|
||||
// The media type change doesn't take effect immediately on Chrome, so
|
||||
// we'll query the media attribute on the stylesheet until it changes
|
||||
// to "all".
|
||||
onMediaAvailable(function () {
|
||||
asyncResolved = true;
|
||||
mayInvokeCallback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return link;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads an external script file.
|
||||
* @param {string} src URL of the script.
|
||||
* @param {function(Error)=} opt_callback callback when the script has loaded. The first argument to
|
||||
* the callback is an error object that is falsy when there are no errors and truthy when there are.
|
||||
* @param {number=} opt_timeout The number of milliseconds after which the callback will be called
|
||||
* with a timeout error. Defaults to 5 seconds.
|
||||
* @return {Element} The script element
|
||||
*/
|
||||
DomHelper.prototype.loadScript = function(src, opt_callback, opt_timeout) {
|
||||
var head = this.document_.getElementsByTagName('head')[0];
|
||||
|
||||
if (head) {
|
||||
var script = this.createElement('script', {
|
||||
'src': src
|
||||
});
|
||||
var done = false;
|
||||
script.onload = script.onreadystatechange = function() {
|
||||
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
|
||||
done = true;
|
||||
if (opt_callback) {
|
||||
opt_callback(null);
|
||||
}
|
||||
script.onload = script.onreadystatechange = null;
|
||||
// Avoid a bizarre issue with unclosed <base> tag in IE6 - http://blog.dotsmart.net/2008/04/
|
||||
if (script.parentNode.tagName == 'HEAD') head.removeChild(script);
|
||||
}
|
||||
};
|
||||
head.appendChild(script);
|
||||
|
||||
setTimeout(function () {
|
||||
if (!done) {
|
||||
done = true;
|
||||
if (opt_callback) {
|
||||
opt_callback(new Error('Script load timeout'));
|
||||
}
|
||||
}
|
||||
}, opt_timeout || 5000);
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
});
|
||||
Generated
Vendored
+195
@@ -0,0 +1,195 @@
|
||||
goog.provide('webfont.EventDispatcher');
|
||||
|
||||
goog.require('webfont.CssClassName');
|
||||
|
||||
/**
|
||||
* A class to dispatch events and manage the event class names on an html
|
||||
* element that represent the current state of fonts on the page. Active class
|
||||
* names always overwrite inactive class names of the same type, while loading
|
||||
* class names may be present whenever a font is loading (regardless of if an
|
||||
* associated active or inactive class name is also present).
|
||||
*
|
||||
* @param {webfont.DomHelper} domHelper
|
||||
* @param {Object} config
|
||||
* @constructor
|
||||
*/
|
||||
webfont.EventDispatcher = function(domHelper, config) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.htmlElement_ = domHelper.getLoadWindow().document.documentElement;
|
||||
this.callbacks_ = config;
|
||||
this.namespace_ = webfont.EventDispatcher.DEFAULT_NAMESPACE;
|
||||
this.cssClassName_ = new webfont.CssClassName('-');
|
||||
this.dispatchEvents_ = config['events'] !== false;
|
||||
this.setClasses_ = config['classes'] !== false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.EventDispatcher.DEFAULT_NAMESPACE = 'wf';
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.EventDispatcher.LOADING = 'loading';
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.EventDispatcher.ACTIVE = 'active';
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.EventDispatcher.INACTIVE = 'inactive';
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.EventDispatcher.FONT = 'font';
|
||||
|
||||
goog.scope(function () {
|
||||
var EventDispatcher = webfont.EventDispatcher;
|
||||
|
||||
/**
|
||||
* Dispatch the loading event and append the loading class name.
|
||||
*/
|
||||
EventDispatcher.prototype.dispatchLoading = function() {
|
||||
if (this.setClasses_) {
|
||||
this.domHelper_.updateClassName(this.htmlElement_,
|
||||
[
|
||||
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
this.dispatch_(webfont.EventDispatcher.LOADING);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch the font loading event and append the font loading class name.
|
||||
* @param {webfont.Font} font
|
||||
*/
|
||||
EventDispatcher.prototype.dispatchFontLoading = function(font) {
|
||||
if (this.setClasses_) {
|
||||
this.domHelper_.updateClassName(this.htmlElement_,
|
||||
[
|
||||
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
this.dispatch_(webfont.EventDispatcher.FONT + webfont.EventDispatcher.LOADING, font);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch the font active event, remove the font loading class name, remove
|
||||
* the font inactive class name, and append the font active class name.
|
||||
* @param {webfont.Font} font
|
||||
*/
|
||||
EventDispatcher.prototype.dispatchFontActive = function(font) {
|
||||
if (this.setClasses_) {
|
||||
this.domHelper_.updateClassName(
|
||||
this.htmlElement_,
|
||||
[
|
||||
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.ACTIVE)
|
||||
],
|
||||
[
|
||||
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING),
|
||||
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.INACTIVE)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
this.dispatch_(webfont.EventDispatcher.FONT + webfont.EventDispatcher.ACTIVE, font);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch the font inactive event, remove the font loading class name, and
|
||||
* append the font inactive class name (unless the font active class name is
|
||||
* already present).
|
||||
* @param {webfont.Font} font
|
||||
*/
|
||||
EventDispatcher.prototype.dispatchFontInactive = function(font) {
|
||||
if (this.setClasses_) {
|
||||
var hasFontActive = this.domHelper_.hasClassName(this.htmlElement_,
|
||||
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.ACTIVE)
|
||||
),
|
||||
add = [],
|
||||
remove = [
|
||||
this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.LOADING)
|
||||
];
|
||||
|
||||
if (!hasFontActive) {
|
||||
add.push(this.cssClassName_.build(this.namespace_, font.getName(), font.getVariation().toString(), webfont.EventDispatcher.INACTIVE));
|
||||
}
|
||||
|
||||
this.domHelper_.updateClassName(this.htmlElement_, add, remove);
|
||||
}
|
||||
|
||||
this.dispatch_(webfont.EventDispatcher.FONT + webfont.EventDispatcher.INACTIVE, font);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch the inactive event, remove the loading class name, and append the
|
||||
* inactive class name (unless the active class name is already present).
|
||||
*/
|
||||
EventDispatcher.prototype.dispatchInactive = function() {
|
||||
if (this.setClasses_) {
|
||||
var hasActive = this.domHelper_.hasClassName(this.htmlElement_,
|
||||
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.ACTIVE)
|
||||
),
|
||||
add = [],
|
||||
remove = [
|
||||
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING)
|
||||
];
|
||||
|
||||
if (!hasActive) {
|
||||
add.push(this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.INACTIVE));
|
||||
}
|
||||
|
||||
this.domHelper_.updateClassName(this.htmlElement_, add, remove);
|
||||
}
|
||||
|
||||
this.dispatch_(webfont.EventDispatcher.INACTIVE);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch the active event, remove the loading class name, remove the inactive
|
||||
* class name, and append the active class name.
|
||||
*/
|
||||
EventDispatcher.prototype.dispatchActive = function() {
|
||||
if (this.setClasses_) {
|
||||
this.domHelper_.updateClassName(this.htmlElement_,
|
||||
[
|
||||
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.ACTIVE)
|
||||
],
|
||||
[
|
||||
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.LOADING),
|
||||
this.cssClassName_.build(this.namespace_, webfont.EventDispatcher.INACTIVE)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
this.dispatch_(webfont.EventDispatcher.ACTIVE);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} event
|
||||
* @param {webfont.Font=} opt_font
|
||||
*/
|
||||
EventDispatcher.prototype.dispatch_ = function(event, opt_font) {
|
||||
if (this.dispatchEvents_ && this.callbacks_[event]) {
|
||||
if (opt_font) {
|
||||
this.callbacks_[event](opt_font.getName(), opt_font.getVariation());
|
||||
} else {
|
||||
this.callbacks_[event]();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
goog.provide('webfont.Font');
|
||||
|
||||
/**
|
||||
* This class is an abstraction for a single font or typeface.
|
||||
* It contains the font name and the variation (i.e. style
|
||||
* and weight.) A collection Font instances can represent a
|
||||
* font family.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} name The font family name
|
||||
* @param {string=} opt_variation A font variation description
|
||||
*/
|
||||
webfont.Font = function (name, opt_variation) {
|
||||
this.name_ = name;
|
||||
this.weight_ = 4;
|
||||
this.style_ = 'n'
|
||||
|
||||
var variation = opt_variation || 'n4',
|
||||
match = variation.match(/^([nio])([1-9])$/i);
|
||||
|
||||
if (match) {
|
||||
this.style_ = match[1];
|
||||
this.weight_ = parseInt(match[2], 10);
|
||||
}
|
||||
};
|
||||
|
||||
goog.scope(function () {
|
||||
var Font = webfont.Font;
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.getName = function () {
|
||||
return this.name_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.getCssName = function () {
|
||||
return this.quote_(this.name_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a CSS string representation of the font that
|
||||
* can be used as the CSS font property shorthand.
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.toCssString = function () {
|
||||
return this.getCssStyle() + ' ' + this.getCssWeight() + ' 300px ' + this.getCssName();
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {string} name
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.quote_ = function (name) {
|
||||
var quoted = [];
|
||||
var split = name.split(/,\s*/);
|
||||
for (var i = 0; i < split.length; i++) {
|
||||
var part = split[i].replace(/['"]/g, '');
|
||||
if (part.indexOf(' ') == -1 && !(/^\d/.test(part))) {
|
||||
quoted.push(part);
|
||||
} else {
|
||||
quoted.push("'" + part + "'");
|
||||
}
|
||||
}
|
||||
return quoted.join(',');
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.getVariation = function () {
|
||||
return this.style_ + this.weight_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.getCssVariation = function () {
|
||||
return 'font-style:' + this.getCssStyle() + ';font-weight:' + this.getCssWeight() + ';';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.getCssWeight = function () {
|
||||
return this.weight_ + '00';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Font.prototype.getCssStyle = function () {
|
||||
var style = 'normal';
|
||||
|
||||
if (this.style_ === 'o') {
|
||||
style = 'oblique';
|
||||
} else if (this.style_ === 'i') {
|
||||
style = 'italic';
|
||||
}
|
||||
|
||||
return style;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses a CSS font declaration and returns a font
|
||||
* variation description.
|
||||
*
|
||||
* @param {string} css
|
||||
* @return {string}
|
||||
*/
|
||||
Font.parseCssVariation = function (css) {
|
||||
var weight = 4,
|
||||
style = 'n',
|
||||
m = null;
|
||||
|
||||
if (css) {
|
||||
m = css.match(/(normal|oblique|italic)/i);
|
||||
|
||||
if (m && m[1]) {
|
||||
style = m[1].substr(0, 1).toLowerCase();
|
||||
}
|
||||
|
||||
m = css.match(/([1-9]00|normal|bold)/i);
|
||||
|
||||
if (m && m[1]) {
|
||||
if (/bold/i.test(m[1])) {
|
||||
weight = 7;
|
||||
} else if (/[1-9]00/.test(m[1])) {
|
||||
weight = parseInt(m[1].substr(0, 1), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
return style + weight;
|
||||
}
|
||||
});
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
goog.provide('webfont.FontModule');
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
webfont.FontModule = function () {};
|
||||
|
||||
goog.scope(function () {
|
||||
var FontModule = webfont.FontModule;
|
||||
|
||||
/**
|
||||
* @param {function(Array.<webfont.Font>, webfont.FontTestStrings=, Object.<string, boolean>=)} onReady
|
||||
*/
|
||||
FontModule.prototype.load = function (onReady) {};
|
||||
});
|
||||
|
||||
Generated
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
goog.provide('webfont.FontModuleLoader');
|
||||
goog.provide('webfont.FontModuleFactory');
|
||||
|
||||
/** @typedef {function(Object, webfont.DomHelper): webfont.FontModule} */
|
||||
webfont.FontModuleFactory;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
webfont.FontModuleLoader = function() {
|
||||
/**
|
||||
* @type {Object.<string, webfont.FontModuleFactory>}
|
||||
*/
|
||||
this.modules_ = {};
|
||||
};
|
||||
|
||||
goog.scope(function () {
|
||||
var FontModuleLoader = webfont.FontModuleLoader;
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {webfont.FontModuleFactory} factory
|
||||
*/
|
||||
FontModuleLoader.prototype.addModuleFactory = function(name, factory) {
|
||||
this.modules_[name] = factory;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} configuration
|
||||
* @param {webfont.DomHelper} domHelper
|
||||
* @return {Array.<webfont.FontModule>}
|
||||
*/
|
||||
FontModuleLoader.prototype.getModules = function(configuration, domHelper) {
|
||||
var modules = [];
|
||||
|
||||
for (var key in configuration) {
|
||||
if (configuration.hasOwnProperty(key)) {
|
||||
var moduleFactory = this.modules_[key];
|
||||
|
||||
if (moduleFactory) {
|
||||
modules.push(moduleFactory(configuration[key], domHelper));
|
||||
}
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
};
|
||||
});
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
goog.provide('webfont.FontRuler');
|
||||
|
||||
/**
|
||||
* An element that can be used to measure the metrics
|
||||
* of a given font and string.
|
||||
* @constructor
|
||||
* @param {webfont.DomHelper} domHelper
|
||||
* @param {string} fontTestString
|
||||
*/
|
||||
webfont.FontRuler = function (domHelper, fontTestString) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.fontTestString_ = fontTestString;
|
||||
this.el_ = this.domHelper_.createElement('span', {
|
||||
"aria-hidden": "true"
|
||||
}, this.fontTestString_);
|
||||
};
|
||||
|
||||
goog.scope(function () {
|
||||
var FontRuler = webfont.FontRuler;
|
||||
|
||||
/**
|
||||
* @param {webfont.Font} font
|
||||
*/
|
||||
FontRuler.prototype.setFont = function(font) {
|
||||
this.domHelper_.setStyle(this.el_, this.computeStyleString_(font));
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts the ruler into the DOM.
|
||||
*/
|
||||
FontRuler.prototype.insert = function() {
|
||||
this.domHelper_.insertInto('body', this.el_);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {webfont.Font} font
|
||||
* @return {string}
|
||||
*/
|
||||
FontRuler.prototype.computeStyleString_ = function(font) {
|
||||
return "display:block;position:absolute;top:-9999px;left:-9999px;" +
|
||||
"font-size:300px;width:auto;height:auto;line-height:normal;margin:0;" +
|
||||
"padding:0;font-variant:normal;white-space:nowrap;font-family:" +
|
||||
font.getCssName() + ";" + font.getCssVariation();
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
FontRuler.prototype.getWidth = function() {
|
||||
return this.el_.offsetWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the ruler element from the DOM.
|
||||
*/
|
||||
FontRuler.prototype.remove = function() {
|
||||
this.domHelper_.removeElement(this.el_);
|
||||
};
|
||||
});
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
Generated
Vendored
+249
@@ -0,0 +1,249 @@
|
||||
goog.provide('webfont.FontWatchRunner');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
goog.require('webfont.FontRuler');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {function(webfont.Font)} activeCallback
|
||||
* @param {function(webfont.Font)} inactiveCallback
|
||||
* @param {webfont.DomHelper} domHelper
|
||||
* @param {webfont.Font} font
|
||||
* @param {number=} opt_timeout
|
||||
* @param {Object.<string, boolean>=} opt_metricCompatibleFonts
|
||||
* @param {string=} opt_fontTestString
|
||||
*/
|
||||
webfont.FontWatchRunner = function(activeCallback, inactiveCallback, domHelper,
|
||||
font, opt_timeout, opt_metricCompatibleFonts, opt_fontTestString) {
|
||||
this.activeCallback_ = activeCallback;
|
||||
this.inactiveCallback_ = inactiveCallback;
|
||||
this.domHelper_ = domHelper;
|
||||
this.font_ = font;
|
||||
this.fontTestString_ = opt_fontTestString || webfont.FontWatchRunner.DEFAULT_TEST_STRING;
|
||||
this.lastResortWidths_ = {};
|
||||
this.timeout_ = opt_timeout || 3000;
|
||||
|
||||
this.metricCompatibleFonts_ = opt_metricCompatibleFonts || null;
|
||||
|
||||
this.fontRulerA_ = null;
|
||||
this.fontRulerB_ = null;
|
||||
this.lastResortRulerA_ = null;
|
||||
this.lastResortRulerB_ = null;
|
||||
|
||||
this.setupRulers_();
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @const
|
||||
*/
|
||||
webfont.FontWatchRunner.LastResortFonts = {
|
||||
SERIF: 'serif',
|
||||
SANS_SERIF: 'sans-serif'
|
||||
};
|
||||
|
||||
/**
|
||||
* Default test string. Characters are chosen so that their widths vary a lot
|
||||
* between the fonts in the default stacks. We want each fallback stack
|
||||
* to always start out at a different width than the other.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
webfont.FontWatchRunner.DEFAULT_TEST_STRING = 'BESbswy';
|
||||
|
||||
goog.scope(function () {
|
||||
var FontWatchRunner = webfont.FontWatchRunner,
|
||||
Font = webfont.Font,
|
||||
FontRuler = webfont.FontRuler;
|
||||
|
||||
/**
|
||||
* @type {null|boolean}
|
||||
*/
|
||||
FontWatchRunner.HAS_WEBKIT_FALLBACK_BUG = null;
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
FontWatchRunner.getUserAgent = function () {
|
||||
return window.navigator.userAgent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this browser is WebKit and it has the fallback bug
|
||||
* which is present in WebKit 536.11 and earlier.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.hasWebKitFallbackBug = function () {
|
||||
if (FontWatchRunner.HAS_WEBKIT_FALLBACK_BUG === null) {
|
||||
var match = /AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(FontWatchRunner.getUserAgent());
|
||||
|
||||
FontWatchRunner.HAS_WEBKIT_FALLBACK_BUG = !!match &&
|
||||
(parseInt(match[1], 10) < 536 ||
|
||||
(parseInt(match[1], 10) === 536 &&
|
||||
parseInt(match[2], 10) <= 11));
|
||||
}
|
||||
return FontWatchRunner.HAS_WEBKIT_FALLBACK_BUG;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
FontWatchRunner.prototype.setupRulers_ = function() {
|
||||
this.fontRulerA_ = new FontRuler(this.domHelper_, this.fontTestString_);
|
||||
this.fontRulerB_ = new FontRuler(this.domHelper_, this.fontTestString_);
|
||||
this.lastResortRulerA_ = new FontRuler(this.domHelper_, this.fontTestString_);
|
||||
this.lastResortRulerB_ = new FontRuler(this.domHelper_, this.fontTestString_);
|
||||
|
||||
this.fontRulerA_.setFont(new Font(this.font_.getName() + ',' + FontWatchRunner.LastResortFonts.SERIF, this.font_.getVariation()));
|
||||
this.fontRulerB_.setFont(new Font(this.font_.getName() + ',' + FontWatchRunner.LastResortFonts.SANS_SERIF, this.font_.getVariation()));
|
||||
this.lastResortRulerA_.setFont(new Font(FontWatchRunner.LastResortFonts.SERIF, this.font_.getVariation()));
|
||||
this.lastResortRulerB_.setFont(new Font(FontWatchRunner.LastResortFonts.SANS_SERIF, this.font_.getVariation()));
|
||||
|
||||
this.fontRulerA_.insert();
|
||||
this.fontRulerB_.insert();
|
||||
this.lastResortRulerA_.insert();
|
||||
this.lastResortRulerB_.insert();
|
||||
};
|
||||
|
||||
FontWatchRunner.prototype.start = function() {
|
||||
this.lastResortWidths_[FontWatchRunner.LastResortFonts.SERIF] = this.lastResortRulerA_.getWidth();
|
||||
this.lastResortWidths_[FontWatchRunner.LastResortFonts.SANS_SERIF] = this.lastResortRulerB_.getWidth();
|
||||
|
||||
this.started_ = goog.now();
|
||||
|
||||
this.check_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given width matches the generic font family width.
|
||||
*
|
||||
* @private
|
||||
* @param {number} width
|
||||
* @param {string} lastResortFont
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.prototype.widthMatches_ = function(width, lastResortFont) {
|
||||
return width === this.lastResortWidths_[lastResortFont];
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if the given widths match any of the generic font family
|
||||
* widths.
|
||||
*
|
||||
* @private
|
||||
* @param {number} a
|
||||
* @param {number} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.prototype.widthsMatchLastResortWidths_ = function(a, b) {
|
||||
for (var font in FontWatchRunner.LastResortFonts) {
|
||||
if (FontWatchRunner.LastResortFonts.hasOwnProperty(font)) {
|
||||
if (this.widthMatches_(a, FontWatchRunner.LastResortFonts[font]) &&
|
||||
this.widthMatches_(b, FontWatchRunner.LastResortFonts[font])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Returns true if the loading has timed out.
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.prototype.hasTimedOut_ = function() {
|
||||
return goog.now() - this.started_ >= this.timeout_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if both fonts match the normal fallback fonts.
|
||||
*
|
||||
* @private
|
||||
* @param {number} a
|
||||
* @param {number} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.prototype.isFallbackFont_ = function (a, b) {
|
||||
return this.widthMatches_(a, FontWatchRunner.LastResortFonts.SERIF) &&
|
||||
this.widthMatches_(b, FontWatchRunner.LastResortFonts.SANS_SERIF);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the WebKit bug is present and both widths match a last resort font.
|
||||
*
|
||||
* @private
|
||||
* @param {number} a
|
||||
* @param {number} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.prototype.isLastResortFont_ = function (a, b) {
|
||||
return FontWatchRunner.hasWebKitFallbackBug() && this.widthsMatchLastResortWidths_(a, b);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the current font is metric compatible. Also returns true
|
||||
* if we do not have a list of metric compatible fonts.
|
||||
*
|
||||
* @private
|
||||
* @return {boolean}
|
||||
*/
|
||||
FontWatchRunner.prototype.isMetricCompatibleFont_ = function () {
|
||||
return this.metricCompatibleFonts_ === null || this.metricCompatibleFonts_.hasOwnProperty(this.font_.getName());
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks the width of the two spans against their original widths during each
|
||||
* async loop. If the width of one of the spans is different than the original
|
||||
* width, then we know that the font is rendering and finish with the active
|
||||
* callback. If we wait more than 5 seconds and nothing has changed, we finish
|
||||
* with the inactive callback.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
FontWatchRunner.prototype.check_ = function() {
|
||||
var widthA = this.fontRulerA_.getWidth();
|
||||
var widthB = this.fontRulerB_.getWidth();
|
||||
|
||||
if (this.isFallbackFont_(widthA, widthB) || this.isLastResortFont_(widthA, widthB)) {
|
||||
if (this.hasTimedOut_()) {
|
||||
if (this.isLastResortFont_(widthA, widthB) && this.isMetricCompatibleFont_()) {
|
||||
this.finish_(this.activeCallback_);
|
||||
} else {
|
||||
this.finish_(this.inactiveCallback_);
|
||||
}
|
||||
} else {
|
||||
this.asyncCheck_();
|
||||
}
|
||||
} else {
|
||||
this.finish_(this.activeCallback_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
FontWatchRunner.prototype.asyncCheck_ = function() {
|
||||
setTimeout(goog.bind(function () {
|
||||
this.check_();
|
||||
}, this), 50);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {function(webfont.Font)} callback
|
||||
*/
|
||||
FontWatchRunner.prototype.finish_ = function(callback) {
|
||||
// Remove elements and trigger callback (which adds active/inactive class) asynchronously to avoid reflow chain if
|
||||
// several fonts are finished loading right after each other
|
||||
setTimeout(goog.bind(function () {
|
||||
this.fontRulerA_.remove();
|
||||
this.fontRulerB_.remove();
|
||||
this.lastResortRulerA_.remove();
|
||||
this.lastResortRulerB_.remove();
|
||||
callback(this.font_);
|
||||
}, this), 0);
|
||||
};
|
||||
|
||||
});
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
goog.provide('webfont');
|
||||
|
||||
goog.require('webfont.WebFont');
|
||||
|
||||
goog.require('webfont.modules.Typekit');
|
||||
goog.require('webfont.modules.Fontdeck');
|
||||
goog.require('webfont.modules.Monotype');
|
||||
goog.require('webfont.modules.Custom');
|
||||
goog.require('webfont.modules.google.GoogleFontApi');
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*/
|
||||
var INCLUDE_CUSTOM_MODULE = false;
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*/
|
||||
var INCLUDE_FONTDECK_MODULE = false;
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*/
|
||||
var INCLUDE_MONOTYPE_MODULE = false;
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*/
|
||||
var INCLUDE_TYPEKIT_MODULE = false;
|
||||
|
||||
/**
|
||||
* @define {boolean}
|
||||
*/
|
||||
var INCLUDE_GOOGLE_MODULE = false;
|
||||
|
||||
/**
|
||||
* @define {string}
|
||||
*/
|
||||
var WEBFONT = 'WebFont';
|
||||
|
||||
/**
|
||||
* @define {string}
|
||||
*/
|
||||
var WEBFONT_CONFIG = 'WebFontConfig';
|
||||
|
||||
/**
|
||||
* @type {webfont.WebFont}
|
||||
*/
|
||||
var webFontLoader = new webfont.WebFont(window);
|
||||
|
||||
if (INCLUDE_CUSTOM_MODULE) {
|
||||
webFontLoader.addModule(webfont.modules.Custom.NAME, function (configuration, domHelper) {
|
||||
return new webfont.modules.Custom(domHelper, configuration);
|
||||
});
|
||||
}
|
||||
|
||||
if (INCLUDE_FONTDECK_MODULE) {
|
||||
webFontLoader.addModule(webfont.modules.Fontdeck.NAME, function (configuration, domHelper) {
|
||||
return new webfont.modules.Fontdeck(domHelper, configuration);
|
||||
});
|
||||
}
|
||||
|
||||
if (INCLUDE_MONOTYPE_MODULE) {
|
||||
webFontLoader.addModule(webfont.modules.Monotype.NAME, function (configuration, domHelper) {
|
||||
return new webfont.modules.Monotype(domHelper, configuration);
|
||||
});
|
||||
}
|
||||
|
||||
if (INCLUDE_TYPEKIT_MODULE) {
|
||||
webFontLoader.addModule(webfont.modules.Typekit.NAME, function (configuration, domHelper) {
|
||||
return new webfont.modules.Typekit(domHelper, configuration);
|
||||
});
|
||||
}
|
||||
|
||||
if (INCLUDE_GOOGLE_MODULE) {
|
||||
webFontLoader.addModule(webfont.modules.google.GoogleFontApi.NAME, function (configuration, domHelper) {
|
||||
return new webfont.modules.google.GoogleFontApi(domHelper, configuration);
|
||||
});
|
||||
}
|
||||
|
||||
var exports = {
|
||||
'load': goog.bind(webFontLoader.load, webFontLoader)
|
||||
};
|
||||
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(function () {
|
||||
return exports;
|
||||
});
|
||||
} else if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = exports;
|
||||
} else {
|
||||
window[WEBFONT] = exports;
|
||||
|
||||
if (window[WEBFONT_CONFIG]) {
|
||||
webFontLoader.load(window[WEBFONT_CONFIG]);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+69
@@ -0,0 +1,69 @@
|
||||
goog.provide('webfont.NativeFontWatchRunner');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
|
||||
goog.scope(function () {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {function(webfont.Font)} activeCallback
|
||||
* @param {function(webfont.Font)} inactiveCallback
|
||||
* @param {webfont.DomHelper} domHelper
|
||||
* @param {webfont.Font} font
|
||||
* @param {number=} opt_timeout
|
||||
* @param {string=} opt_fontTestString
|
||||
*/
|
||||
webfont.NativeFontWatchRunner = function(activeCallback, inactiveCallback, domHelper, font, opt_timeout, opt_fontTestString) {
|
||||
this.activeCallback_ = activeCallback;
|
||||
this.inactiveCallback_ = inactiveCallback;
|
||||
this.font_ = font;
|
||||
this.domHelper_ = domHelper;
|
||||
this.timeout_ = opt_timeout || 3000;
|
||||
this.fontTestString_ = opt_fontTestString || undefined;
|
||||
};
|
||||
|
||||
var NativeFontWatchRunner = webfont.NativeFontWatchRunner;
|
||||
|
||||
NativeFontWatchRunner.prototype.start = function () {
|
||||
var doc = this.domHelper_.getLoadWindow().document,
|
||||
that = this;
|
||||
|
||||
var start = goog.now();
|
||||
|
||||
var loader = new Promise(function (resolve, reject) {
|
||||
var check = function () {
|
||||
var now = goog.now();
|
||||
|
||||
if (now - start >= that.timeout_) {
|
||||
reject();
|
||||
} else {
|
||||
doc.fonts.load(that.font_.toCssString(), that.fontTestString_).then(function (fonts) {
|
||||
if (fonts.length >= 1) {
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(check, 25);
|
||||
}
|
||||
}, function () {
|
||||
reject();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
check();
|
||||
});
|
||||
|
||||
var timeoutId = null,
|
||||
timer = new Promise(function (resolve, reject) {
|
||||
timeoutId = setTimeout(reject, that.timeout_);
|
||||
});
|
||||
|
||||
Promise.race([timer, loader]).then(function () {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
}
|
||||
that.activeCallback_(that.font_);
|
||||
}, function () {
|
||||
that.inactiveCallback_(that.font_);
|
||||
});
|
||||
};
|
||||
});
|
||||
Generated
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
goog.provide('webfont.StyleSheetWaiter');
|
||||
|
||||
/**
|
||||
* A utility class for handling callback from DomHelper.loadStylesheet().
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
webfont.StyleSheetWaiter = function() {
|
||||
/** @private @type {number} */
|
||||
this.waitingCount_ = 0;
|
||||
/** @private @type {Function} */
|
||||
this.onReady_ = null;
|
||||
};
|
||||
|
||||
goog.scope(function () {
|
||||
var StyleSheetWaiter = webfont.StyleSheetWaiter;
|
||||
|
||||
/**
|
||||
* @return {function(Error)}
|
||||
*/
|
||||
StyleSheetWaiter.prototype.startWaitingLoad = function() {
|
||||
var self = this;
|
||||
self.waitingCount_++;
|
||||
return function(error) {
|
||||
self.waitingCount_--;
|
||||
self.fireIfReady_();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Function} fn
|
||||
*/
|
||||
StyleSheetWaiter.prototype.waitWhileNeededThen = function(fn) {
|
||||
this.onReady_ = fn;
|
||||
this.fireIfReady_();
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
StyleSheetWaiter.prototype.fireIfReady_ = function() {
|
||||
var isReady = 0 == this.waitingCount_;
|
||||
if (isReady && this.onReady_) {
|
||||
this.onReady_();
|
||||
this.onReady_ = null;
|
||||
}
|
||||
};
|
||||
});
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
goog.provide('webfont.WebFont');
|
||||
|
||||
goog.require('webfont.DomHelper');
|
||||
goog.require('webfont.EventDispatcher');
|
||||
goog.require('webfont.FontWatcher');
|
||||
goog.require('webfont.FontModuleLoader');
|
||||
|
||||
/**
|
||||
* @param {Window} mainWindow The main application window containing
|
||||
* webfontloader.js.
|
||||
* @constructor
|
||||
*/
|
||||
webfont.WebFont = function(mainWindow) {
|
||||
this.mainWindow_ = mainWindow;
|
||||
this.fontModuleLoader_ = new webfont.FontModuleLoader();
|
||||
this.moduleLoading_ = 0;
|
||||
this.events_ = true;
|
||||
this.classes_ = true;
|
||||
};
|
||||
|
||||
goog.scope(function () {
|
||||
var WebFont = webfont.WebFont,
|
||||
DomHelper = webfont.DomHelper,
|
||||
EventDispatcher = webfont.EventDispatcher,
|
||||
FontWatcher = webfont.FontWatcher;
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {webfont.FontModuleFactory} factory
|
||||
*/
|
||||
WebFont.prototype.addModule = function(name, factory) {
|
||||
this.fontModuleLoader_.addModuleFactory(name, factory);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} configuration
|
||||
*/
|
||||
WebFont.prototype.load = function(configuration) {
|
||||
var context = configuration['context'] || this.mainWindow_;
|
||||
this.domHelper_ = new DomHelper(this.mainWindow_, context);
|
||||
|
||||
this.events_ = configuration['events'] !== false;
|
||||
this.classes_ = configuration['classes'] !== false;
|
||||
|
||||
var eventDispatcher = new EventDispatcher(
|
||||
this.domHelper_,
|
||||
configuration
|
||||
);
|
||||
|
||||
this.load_(eventDispatcher, configuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {webfont.EventDispatcher} eventDispatcher
|
||||
* @param {webfont.FontWatcher} fontWatcher
|
||||
* @param {Array.<webfont.Font>} fonts
|
||||
* @param {webfont.FontTestStrings=} opt_fontTestStrings
|
||||
* @param {Object.<string, boolean>=} opt_metricCompatibleFonts
|
||||
*/
|
||||
WebFont.prototype.onModuleReady_ = function(eventDispatcher, fontWatcher, fonts, opt_fontTestStrings, opt_metricCompatibleFonts) {
|
||||
var allModulesLoaded = --this.moduleLoading_ == 0;
|
||||
|
||||
if (this.classes_ || this.events_) {
|
||||
setTimeout(function () {
|
||||
fontWatcher.watchFonts(fonts, opt_fontTestStrings || null, opt_metricCompatibleFonts || null, allModulesLoaded);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {webfont.EventDispatcher} eventDispatcher
|
||||
* @param {Object} configuration
|
||||
*/
|
||||
WebFont.prototype.load_ = function(eventDispatcher, configuration) {
|
||||
var modules = [],
|
||||
timeout = configuration['timeout'],
|
||||
self = this;
|
||||
|
||||
// Immediately dispatch the loading event before initializing the modules
|
||||
// so we know for sure that the loading event is synchronous.
|
||||
eventDispatcher.dispatchLoading();
|
||||
|
||||
modules = this.fontModuleLoader_.getModules(configuration, this.domHelper_);
|
||||
|
||||
var fontWatcher = new webfont.FontWatcher(this.domHelper_, eventDispatcher, timeout);
|
||||
|
||||
this.moduleLoading_ = modules.length;
|
||||
|
||||
for (var i = 0, len = modules.length; i < len; i++) {
|
||||
var module = modules[i];
|
||||
|
||||
module.load(function (fonts, opt_fontTestStrings, opt_metricCompatibleFonts) {
|
||||
self.onModuleReady_(eventDispatcher, fontWatcher, fonts, opt_fontTestStrings, opt_metricCompatibleFonts);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
goog.provide('webfont.modules.Custom');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
goog.require('webfont.StyleSheetWaiter');
|
||||
|
||||
/**
|
||||
*
|
||||
* WebFont.load({
|
||||
* custom: {
|
||||
* families: ['Font1', 'Font2'],
|
||||
* urls: [ 'https://moo', 'https://meuh' ] }
|
||||
* });
|
||||
*
|
||||
* @constructor
|
||||
* @implements {webfont.FontModule}
|
||||
*/
|
||||
webfont.modules.Custom = function(domHelper, configuration) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.configuration_ = configuration;
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.modules.Custom.NAME = 'custom';
|
||||
|
||||
goog.scope(function () {
|
||||
var Custom = webfont.modules.Custom,
|
||||
Font = webfont.Font,
|
||||
StyleSheetWaiter = webfont.StyleSheetWaiter;
|
||||
|
||||
Custom.prototype.load = function(onReady) {
|
||||
var i, len;
|
||||
var urls = this.configuration_['urls'] || [];
|
||||
var familiesConfiguration = this.configuration_['families'] || [];
|
||||
var fontTestStrings = this.configuration_['testStrings'] || {};
|
||||
var waiter = new StyleSheetWaiter();
|
||||
for (i = 0, len = urls.length; i < len; i++) {
|
||||
this.domHelper_.loadStylesheet(urls[i], waiter.startWaitingLoad());
|
||||
}
|
||||
|
||||
var fonts = [];
|
||||
|
||||
for (i = 0, len = familiesConfiguration.length; i < len; i++) {
|
||||
var components = familiesConfiguration[i].split(":");
|
||||
|
||||
if (components[1]) {
|
||||
var variations = components[1].split(",");
|
||||
|
||||
for (var j = 0; j < variations.length; j += 1) {
|
||||
fonts.push(new Font(components[0], variations[j]));
|
||||
}
|
||||
} else {
|
||||
fonts.push(new Font(components[0]));
|
||||
}
|
||||
}
|
||||
|
||||
waiter.waitWhileNeededThen(function() {
|
||||
onReady(fonts, fontTestStrings);
|
||||
});
|
||||
};
|
||||
});
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
goog.provide('webfont.modules.Fontdeck');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {webfont.FontModule}
|
||||
*/
|
||||
webfont.modules.Fontdeck = function(domHelper, configuration) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.configuration_ = configuration;
|
||||
this.fonts_ = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.modules.Fontdeck.NAME = 'fontdeck';
|
||||
webfont.modules.Fontdeck.HOOK = '__webfontfontdeckmodule__';
|
||||
webfont.modules.Fontdeck.API = 'https://f.fontdeck.com/s/css/js/';
|
||||
|
||||
goog.scope(function () {
|
||||
var Fontdeck = webfont.modules.Fontdeck,
|
||||
Font = webfont.Font,
|
||||
FontVariationDescription = webfont.FontVariationDescription;
|
||||
|
||||
Fontdeck.prototype.getScriptSrc = function(projectId) {
|
||||
// For empty iframes, fall back to main window's hostname.
|
||||
var hostname = this.domHelper_.getHostName();
|
||||
var api = this.configuration_['api'] || webfont.modules.Fontdeck.API;
|
||||
return api + hostname + '/' + projectId + '.js';
|
||||
};
|
||||
|
||||
Fontdeck.prototype.load = function(onReady) {
|
||||
var projectId = this.configuration_['id'];
|
||||
var loadWindow = this.domHelper_.getLoadWindow();
|
||||
var self = this;
|
||||
|
||||
if (projectId) {
|
||||
// Provide data to Fontdeck for processing.
|
||||
if (!loadWindow[webfont.modules.Fontdeck.HOOK]) {
|
||||
loadWindow[webfont.modules.Fontdeck.HOOK] = {};
|
||||
}
|
||||
|
||||
// Fontdeck will call this function to indicate support status
|
||||
// and what fonts are provided.
|
||||
loadWindow[webfont.modules.Fontdeck.HOOK][projectId] = function(fontdeckSupports, data) {
|
||||
for (var i = 0, j = data['fonts'].length; i<j; ++i) {
|
||||
var font = data['fonts'][i];
|
||||
self.fonts_.push(new Font(font['name'], Font.parseCssVariation('font-weight:' + font['weight'] + ';font-style:' + font['style'])));
|
||||
}
|
||||
onReady(self.fonts_);
|
||||
};
|
||||
|
||||
// Call the Fontdeck API.
|
||||
this.domHelper_.loadScript(this.getScriptSrc(projectId), function (err) {
|
||||
if (err) {
|
||||
onReady([]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
onReady([]);
|
||||
}
|
||||
};
|
||||
});
|
||||
Generated
Vendored
+181
@@ -0,0 +1,181 @@
|
||||
goog.provide('webfont.modules.google.FontApiParser');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
webfont.modules.google.FontApiParser = function(fontFamilies) {
|
||||
this.fontFamilies_ = fontFamilies;
|
||||
this.parsedFonts_ = [];
|
||||
this.fontTestStrings_ = {};
|
||||
};
|
||||
|
||||
webfont.modules.google.FontApiParser.INT_FONTS = {
|
||||
'latin': webfont.FontWatchRunner.DEFAULT_TEST_STRING,
|
||||
'latin-ext': '\u00E7\u00F6\u00FC\u011F\u015F',
|
||||
'cyrillic': '\u0439\u044f\u0416',
|
||||
'greek': '\u03b1\u03b2\u03a3',
|
||||
'khmer': '\u1780\u1781\u1782',
|
||||
'Hanuman': '\u1780\u1781\u1782' // For backward compatibility
|
||||
};
|
||||
|
||||
webfont.modules.google.FontApiParser.WEIGHTS = {
|
||||
'thin': '1',
|
||||
'extralight': '2',
|
||||
'extra-light': '2',
|
||||
'ultralight': '2',
|
||||
'ultra-light': '2',
|
||||
'light': '3',
|
||||
'regular': '4',
|
||||
'book': '4',
|
||||
'medium': '5',
|
||||
'semi-bold': '6',
|
||||
'semibold': '6',
|
||||
'demi-bold': '6',
|
||||
'demibold': '6',
|
||||
'bold': '7',
|
||||
'extra-bold': '8',
|
||||
'extrabold': '8',
|
||||
'ultra-bold': '8',
|
||||
'ultrabold': '8',
|
||||
'black': '9',
|
||||
'heavy': '9',
|
||||
'l': '3',
|
||||
'r': '4',
|
||||
'b': '7'
|
||||
};
|
||||
|
||||
webfont.modules.google.FontApiParser.STYLES = {
|
||||
'i': 'i',
|
||||
'italic': 'i',
|
||||
'n': 'n',
|
||||
'normal': 'n'
|
||||
};
|
||||
|
||||
webfont.modules.google.FontApiParser.VARIATION_MATCH =
|
||||
new RegExp("^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|" +
|
||||
"(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i" +
|
||||
"|normal|italic)?$");
|
||||
|
||||
goog.scope(function () {
|
||||
var FontApiParser = webfont.modules.google.FontApiParser,
|
||||
Font = webfont.Font;
|
||||
|
||||
FontApiParser.prototype.parse = function() {
|
||||
var length = this.fontFamilies_.length;
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
var elements = this.fontFamilies_[i].split(":");
|
||||
var fontFamily = elements[0].replace(/\+/g, " ");
|
||||
var variations = ['n4'];
|
||||
|
||||
if (elements.length >= 2) {
|
||||
var fvds = this.parseVariations_(elements[1]);
|
||||
|
||||
if (fvds.length > 0) {
|
||||
variations = fvds;
|
||||
}
|
||||
if (elements.length == 3) {
|
||||
var subsets = this.parseSubsets_(elements[2]);
|
||||
if (subsets.length > 0) {
|
||||
var fontTestString = FontApiParser.INT_FONTS[subsets[0]];
|
||||
|
||||
if (fontTestString) {
|
||||
this.fontTestStrings_[fontFamily] = fontTestString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For backward compatibility
|
||||
if (!this.fontTestStrings_[fontFamily]) {
|
||||
var hanumanTestString = FontApiParser.INT_FONTS[fontFamily];
|
||||
if (hanumanTestString) {
|
||||
this.fontTestStrings_[fontFamily] = hanumanTestString;
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < variations.length; j += 1) {
|
||||
this.parsedFonts_.push(new Font(fontFamily, variations[j]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
FontApiParser.prototype.generateFontVariationDescription_ = function(variation) {
|
||||
if (!variation.match(/^[\w-]+$/)) {
|
||||
return '';
|
||||
}
|
||||
var normalizedVariation = variation.toLowerCase();
|
||||
var groups = FontApiParser.VARIATION_MATCH.exec(normalizedVariation);
|
||||
if (groups == null) {
|
||||
return '';
|
||||
}
|
||||
var styleMatch = this.normalizeStyle_(groups[2]);
|
||||
var weightMatch = this.normalizeWeight_(groups[1]);
|
||||
return [styleMatch, weightMatch].join('');
|
||||
};
|
||||
|
||||
|
||||
FontApiParser.prototype.normalizeStyle_ = function(parsedStyle) {
|
||||
if (parsedStyle == null || parsedStyle == '') {
|
||||
return 'n';
|
||||
}
|
||||
return FontApiParser.STYLES[parsedStyle];
|
||||
};
|
||||
|
||||
|
||||
FontApiParser.prototype.normalizeWeight_ = function(parsedWeight) {
|
||||
if (parsedWeight == null || parsedWeight == '') {
|
||||
return '4';
|
||||
}
|
||||
var weight = FontApiParser.WEIGHTS[parsedWeight];
|
||||
if (weight) {
|
||||
return weight;
|
||||
}
|
||||
if (isNaN(parsedWeight)) {
|
||||
return '4';
|
||||
}
|
||||
return parsedWeight.substr(0, 1);
|
||||
};
|
||||
|
||||
|
||||
FontApiParser.prototype.parseVariations_ = function(variations) {
|
||||
var finalVariations = [];
|
||||
|
||||
if (!variations) {
|
||||
return finalVariations;
|
||||
}
|
||||
var providedVariations = variations.split(",");
|
||||
var length = providedVariations.length;
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
var variation = providedVariations[i];
|
||||
var fvd = this.generateFontVariationDescription_(variation);
|
||||
|
||||
if (fvd) {
|
||||
finalVariations.push(fvd);
|
||||
}
|
||||
}
|
||||
return finalVariations;
|
||||
};
|
||||
|
||||
|
||||
FontApiParser.prototype.parseSubsets_ = function(subsets) {
|
||||
var finalSubsets = [];
|
||||
|
||||
if (!subsets) {
|
||||
return finalSubsets;
|
||||
}
|
||||
return subsets.split(",");
|
||||
};
|
||||
|
||||
|
||||
FontApiParser.prototype.getFonts = function() {
|
||||
return this.parsedFonts_;
|
||||
};
|
||||
|
||||
FontApiParser.prototype.getFontTestStrings = function() {
|
||||
return this.fontTestStrings_;
|
||||
};
|
||||
});
|
||||
Generated
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
goog.provide('webfont.modules.google.FontApiUrlBuilder');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
webfont.modules.google.FontApiUrlBuilder = function(apiUrl, text) {
|
||||
if (apiUrl) {
|
||||
this.apiUrl_ = apiUrl;
|
||||
} else {
|
||||
this.apiUrl_ = webfont.modules.google.FontApiUrlBuilder.DEFAULT_API_URL;
|
||||
}
|
||||
this.fontFamilies_ = [];
|
||||
this.subsets_ = [];
|
||||
this.text_ = text || '';
|
||||
};
|
||||
|
||||
|
||||
webfont.modules.google.FontApiUrlBuilder.DEFAULT_API_URL = 'https://fonts.googleapis.com/css';
|
||||
|
||||
goog.scope(function () {
|
||||
var FontApiUrlBuilder = webfont.modules.google.FontApiUrlBuilder;
|
||||
|
||||
FontApiUrlBuilder.prototype.setFontFamilies = function(fontFamilies) {
|
||||
this.parseFontFamilies_(fontFamilies);
|
||||
};
|
||||
|
||||
|
||||
FontApiUrlBuilder.prototype.parseFontFamilies_ =
|
||||
function(fontFamilies) {
|
||||
var length = fontFamilies.length;
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
var elements = fontFamilies[i].split(':');
|
||||
|
||||
if (elements.length == 3) {
|
||||
this.subsets_.push(elements.pop());
|
||||
}
|
||||
var joinCharacter = '';
|
||||
if (elements.length == 2 && elements[1] != ''){
|
||||
joinCharacter = ':';
|
||||
}
|
||||
this.fontFamilies_.push(elements.join(joinCharacter));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
FontApiUrlBuilder.prototype.webSafe = function(string) {
|
||||
return string.replace(/ /g, '+');
|
||||
};
|
||||
|
||||
|
||||
FontApiUrlBuilder.prototype.build = function() {
|
||||
if (this.fontFamilies_.length == 0) {
|
||||
throw new Error('No fonts to load!');
|
||||
}
|
||||
if (this.apiUrl_.indexOf("kit=") != -1) {
|
||||
return this.apiUrl_;
|
||||
}
|
||||
var length = this.fontFamilies_.length;
|
||||
var sb = [];
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
sb.push(this.webSafe(this.fontFamilies_[i]));
|
||||
}
|
||||
var url = this.apiUrl_ + '?family=' + sb.join('%7C'); // '|' escaped.
|
||||
|
||||
if (this.subsets_.length > 0) {
|
||||
url += '&subset=' + this.subsets_.join(',');
|
||||
}
|
||||
|
||||
if (this.text_.length > 0) {
|
||||
url += '&text=' + encodeURIComponent(this.text_);
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
});
|
||||
Generated
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
goog.provide('webfont.modules.google.GoogleFontApi');
|
||||
|
||||
goog.require('webfont.modules.google.FontApiUrlBuilder');
|
||||
goog.require('webfont.modules.google.FontApiParser');
|
||||
goog.require('webfont.FontWatchRunner');
|
||||
goog.require('webfont.StyleSheetWaiter');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {webfont.FontModule}
|
||||
*/
|
||||
webfont.modules.google.GoogleFontApi = function(domHelper, configuration) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.configuration_ = configuration;
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.modules.google.GoogleFontApi.NAME = 'google';
|
||||
|
||||
goog.scope(function () {
|
||||
var GoogleFontApi = webfont.modules.google.GoogleFontApi,
|
||||
FontWatchRunner = webfont.FontWatchRunner,
|
||||
StyleSheetWaiter = webfont.StyleSheetWaiter,
|
||||
FontApiUrlBuilder = webfont.modules.google.FontApiUrlBuilder,
|
||||
FontApiParser = webfont.modules.google.FontApiParser;
|
||||
|
||||
GoogleFontApi.METRICS_COMPATIBLE_FONTS = {
|
||||
"Arimo": true,
|
||||
"Cousine": true,
|
||||
"Tinos": true
|
||||
};
|
||||
|
||||
GoogleFontApi.prototype.load = function(onReady) {
|
||||
var waiter = new StyleSheetWaiter();
|
||||
var domHelper = this.domHelper_;
|
||||
var fontApiUrlBuilder = new FontApiUrlBuilder(
|
||||
this.configuration_['api'],
|
||||
this.configuration_['text']
|
||||
);
|
||||
var fontFamilies = this.configuration_['families'];
|
||||
fontApiUrlBuilder.setFontFamilies(fontFamilies);
|
||||
|
||||
var fontApiParser = new FontApiParser(fontFamilies);
|
||||
fontApiParser.parse();
|
||||
|
||||
domHelper.loadStylesheet(fontApiUrlBuilder.build(), waiter.startWaitingLoad());
|
||||
waiter.waitWhileNeededThen(function() {
|
||||
onReady(fontApiParser.getFonts(), fontApiParser.getFontTestStrings(), GoogleFontApi.METRICS_COMPATIBLE_FONTS);
|
||||
});
|
||||
};
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
goog.provide('webfont.modules.Monotype');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
|
||||
/**
|
||||
webfont.load({
|
||||
monotype: {
|
||||
projectId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'//this is your Fonts.com Web fonts projectId
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {webfont.FontModule}
|
||||
*/
|
||||
webfont.modules.Monotype = function(domHelper, configuration) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.configuration_ = configuration;
|
||||
};
|
||||
|
||||
/**
|
||||
* name of the module through which external API is supposed to call the MonotypeFontAPI.
|
||||
*
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.modules.Monotype.NAME = 'monotype';
|
||||
|
||||
/**
|
||||
* __mti_fntLst is the name of function that exposes Monotype's font list.
|
||||
* @const
|
||||
*/
|
||||
webfont.modules.Monotype.HOOK = '__mti_fntLst';
|
||||
|
||||
/**
|
||||
* __MonotypeAPIScript__ is the id of script added by google API. Currently 'fonts.com' supports only one script in a page.
|
||||
* This may require change in future if 'fonts.com' begins supporting multiple scripts per page.
|
||||
* @const
|
||||
*/
|
||||
webfont.modules.Monotype.SCRIPTID = '__MonotypeAPIScript__';
|
||||
|
||||
/**
|
||||
* __MonotypeConfiguration__ is function exposed to fonts.com. fonts.com will use this function to get webfontloader configuration
|
||||
* @const
|
||||
*/
|
||||
webfont.modules.Monotype.CONFIGURATION = '__MonotypeConfiguration__';
|
||||
|
||||
goog.scope(function() {
|
||||
var Monotype = webfont.modules.Monotype,
|
||||
Font = webfont.Font;
|
||||
|
||||
|
||||
Monotype.prototype.getScriptSrc = function(projectId, version) {
|
||||
var api = (this.configuration_['api'] || 'https://fast.fonts.net/jsapi')
|
||||
return api + '/' + projectId + '.js' + (version ? '?v=' + version : '');
|
||||
};
|
||||
|
||||
Monotype.prototype.load = function(onReady) {
|
||||
var self = this;
|
||||
var projectId = self.configuration_['projectId'];
|
||||
var version = self.configuration_['version'];
|
||||
|
||||
|
||||
function checkAndLoadIfDownloaded() {
|
||||
if (loadWindow[Monotype.HOOK + projectId]) {
|
||||
var mti_fnts = loadWindow[Monotype.HOOK + projectId](),
|
||||
fonts = [],
|
||||
fntVariation;
|
||||
|
||||
if (mti_fnts) {
|
||||
for (var i = 0; i < mti_fnts.length; i++) {
|
||||
var fnt = mti_fnts[i]["fontfamily"];
|
||||
|
||||
//Check if font-style and font-weight is available
|
||||
if (mti_fnts[i]["fontStyle"] != undefined && mti_fnts[i]["fontWeight"] != undefined) {
|
||||
fntVariation = mti_fnts[i]["fontStyle"] + mti_fnts[i]["fontWeight"];
|
||||
fonts.push(new Font(fnt, fntVariation));
|
||||
} else {
|
||||
fonts.push(new Font(fnt));
|
||||
}
|
||||
}
|
||||
}
|
||||
onReady(fonts);
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
checkAndLoadIfDownloaded();
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
if (projectId) {
|
||||
var loadWindow = self.domHelper_.getLoadWindow();
|
||||
|
||||
var script = this.domHelper_.loadScript(self.getScriptSrc(projectId, version), function(err) {
|
||||
if (err) {
|
||||
onReady([]);
|
||||
} else {
|
||||
loadWindow[Monotype.CONFIGURATION+ projectId] = function() {
|
||||
return self.configuration_;
|
||||
};
|
||||
|
||||
checkAndLoadIfDownloaded();
|
||||
}
|
||||
});
|
||||
script["id"] = Monotype.SCRIPTID + projectId;
|
||||
} else {
|
||||
onReady([]);
|
||||
}
|
||||
};
|
||||
});
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
goog.provide('webfont.modules.Typekit');
|
||||
|
||||
goog.require('webfont.Font');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {webfont.FontModule}
|
||||
*/
|
||||
webfont.modules.Typekit = function(domHelper, configuration) {
|
||||
this.domHelper_ = domHelper;
|
||||
this.configuration_ = configuration;
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
webfont.modules.Typekit.NAME = 'typekit';
|
||||
|
||||
goog.scope(function () {
|
||||
var Typekit = webfont.modules.Typekit,
|
||||
Font = webfont.Font;
|
||||
|
||||
Typekit.prototype.getScriptSrc = function(kitId) {
|
||||
var api = this.configuration_['api'] || 'https://use.typekit.net';
|
||||
return api + '/' + kitId + '.js';
|
||||
};
|
||||
|
||||
Typekit.prototype.load = function(onReady) {
|
||||
var kitId = this.configuration_['id'];
|
||||
var configuration = this.configuration_;
|
||||
var loadWindow = this.domHelper_.getLoadWindow();
|
||||
var that = this;
|
||||
|
||||
if (kitId) {
|
||||
// Load the Typekit script. Once it is done loading we grab its configuration
|
||||
// and use that to populate the fonts we should watch.
|
||||
this.domHelper_.loadScript(this.getScriptSrc(kitId), function (err) {
|
||||
if (err) {
|
||||
onReady([]);
|
||||
} else {
|
||||
if (loadWindow['Typekit'] && loadWindow['Typekit']['config'] && loadWindow['Typekit']['config']['fn']) {
|
||||
var fn = loadWindow['Typekit']['config']['fn'],
|
||||
fonts = [];
|
||||
|
||||
for (var i = 0; i < fn.length; i += 2) {
|
||||
var font = fn[i],
|
||||
variations = fn[i + 1];
|
||||
|
||||
for (var j = 0; j < variations.length; j++) {
|
||||
fonts.push(new Font(font, variations[j]));
|
||||
}
|
||||
}
|
||||
|
||||
// Kick off font loading but disable font events so
|
||||
// we don't duplicate font watching.
|
||||
try {
|
||||
loadWindow['Typekit']['load']({
|
||||
'events': false,
|
||||
'classes': false,
|
||||
'async': true
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
onReady(fonts);
|
||||
}
|
||||
}
|
||||
}, 2000);
|
||||
} else {
|
||||
onReady([]);
|
||||
}
|
||||
};
|
||||
});
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/* Web Font Loader v1.6.28 - (c) Adobe Systems, Google. License: Apache 2.0 */(function(){function aa(a,b,c){return a.call.apply(a.bind,arguments)}function ba(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function p(a,b,c){p=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?aa:ba;return p.apply(null,arguments)}var q=Date.now||function(){return+new Date};function ca(a,b){this.a=a;this.o=b||a;this.c=this.o.document}var da=!!window.FontFace;function t(a,b,c,d){b=a.c.createElement(b);if(c)for(var e in c)c.hasOwnProperty(e)&&("style"==e?b.style.cssText=c[e]:b.setAttribute(e,c[e]));d&&b.appendChild(a.c.createTextNode(d));return b}function u(a,b,c){a=a.c.getElementsByTagName(b)[0];a||(a=document.documentElement);a.insertBefore(c,a.lastChild)}function v(a){a.parentNode&&a.parentNode.removeChild(a)}
|
||||
function w(a,b,c){b=b||[];c=c||[];for(var d=a.className.split(/\s+/),e=0;e<b.length;e+=1){for(var f=!1,g=0;g<d.length;g+=1)if(b[e]===d[g]){f=!0;break}f||d.push(b[e])}b=[];for(e=0;e<d.length;e+=1){f=!1;for(g=0;g<c.length;g+=1)if(d[e]===c[g]){f=!0;break}f||b.push(d[e])}a.className=b.join(" ").replace(/\s+/g," ").replace(/^\s+|\s+$/,"")}function y(a,b){for(var c=a.className.split(/\s+/),d=0,e=c.length;d<e;d++)if(c[d]==b)return!0;return!1}
|
||||
function ea(a){return a.o.location.hostname||a.a.location.hostname}function z(a,b,c){function d(){m&&e&&f&&(m(g),m=null)}b=t(a,"link",{rel:"stylesheet",href:b,media:"all"});var e=!1,f=!0,g=null,m=c||null;da?(b.onload=function(){e=!0;d()},b.onerror=function(){e=!0;g=Error("Stylesheet failed to load");d()}):setTimeout(function(){e=!0;d()},0);u(a,"head",b)}
|
||||
function A(a,b,c,d){var e=a.c.getElementsByTagName("head")[0];if(e){var f=t(a,"script",{src:b}),g=!1;f.onload=f.onreadystatechange=function(){g||this.readyState&&"loaded"!=this.readyState&&"complete"!=this.readyState||(g=!0,c&&c(null),f.onload=f.onreadystatechange=null,"HEAD"==f.parentNode.tagName&&e.removeChild(f))};e.appendChild(f);setTimeout(function(){g||(g=!0,c&&c(Error("Script load timeout")))},d||5E3);return f}return null};function B(){this.a=0;this.c=null}function C(a){a.a++;return function(){a.a--;D(a)}}function E(a,b){a.c=b;D(a)}function D(a){0==a.a&&a.c&&(a.c(),a.c=null)};function F(a){this.a=a||"-"}F.prototype.c=function(a){for(var b=[],c=0;c<arguments.length;c++)b.push(arguments[c].replace(/[\W_]+/g,"").toLowerCase());return b.join(this.a)};function G(a,b){this.c=a;this.f=4;this.a="n";var c=(b||"n4").match(/^([nio])([1-9])$/i);c&&(this.a=c[1],this.f=parseInt(c[2],10))}function fa(a){return H(a)+" "+(a.f+"00")+" 300px "+I(a.c)}function I(a){var b=[];a=a.split(/,\s*/);for(var c=0;c<a.length;c++){var d=a[c].replace(/['"]/g,"");-1!=d.indexOf(" ")||/^\d/.test(d)?b.push("'"+d+"'"):b.push(d)}return b.join(",")}function J(a){return a.a+a.f}function H(a){var b="normal";"o"===a.a?b="oblique":"i"===a.a&&(b="italic");return b}
|
||||
function ga(a){var b=4,c="n",d=null;a&&((d=a.match(/(normal|oblique|italic)/i))&&d[1]&&(c=d[1].substr(0,1).toLowerCase()),(d=a.match(/([1-9]00|normal|bold)/i))&&d[1]&&(/bold/i.test(d[1])?b=7:/[1-9]00/.test(d[1])&&(b=parseInt(d[1].substr(0,1),10))));return c+b};function ha(a,b){this.c=a;this.f=a.o.document.documentElement;this.h=b;this.a=new F("-");this.j=!1!==b.events;this.g=!1!==b.classes}function ia(a){a.g&&w(a.f,[a.a.c("wf","loading")]);K(a,"loading")}function L(a){if(a.g){var b=y(a.f,a.a.c("wf","active")),c=[],d=[a.a.c("wf","loading")];b||c.push(a.a.c("wf","inactive"));w(a.f,c,d)}K(a,"inactive")}function K(a,b,c){if(a.j&&a.h[b])if(c)a.h[b](c.c,J(c));else a.h[b]()};function ja(){this.c={}}function ka(a,b,c){var d=[],e;for(e in b)if(b.hasOwnProperty(e)){var f=a.c[e];f&&d.push(f(b[e],c))}return d};function M(a,b){this.c=a;this.f=b;this.a=t(this.c,"span",{"aria-hidden":"true"},this.f)}function N(a){u(a.c,"body",a.a)}function O(a){return"display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:"+I(a.c)+";"+("font-style:"+H(a)+";font-weight:"+(a.f+"00")+";")};function P(a,b,c,d,e,f){this.g=a;this.j=b;this.a=d;this.c=c;this.f=e||3E3;this.h=f||void 0}P.prototype.start=function(){var a=this.c.o.document,b=this,c=q(),d=new Promise(function(d,e){function f(){q()-c>=b.f?e():a.fonts.load(fa(b.a),b.h).then(function(a){1<=a.length?d():setTimeout(f,25)},function(){e()})}f()}),e=null,f=new Promise(function(a,d){e=setTimeout(d,b.f)});Promise.race([f,d]).then(function(){e&&(clearTimeout(e),e=null);b.g(b.a)},function(){b.j(b.a)})};function Q(a,b,c,d,e,f,g){this.v=a;this.B=b;this.c=c;this.a=d;this.s=g||"BESbswy";this.f={};this.w=e||3E3;this.u=f||null;this.m=this.j=this.h=this.g=null;this.g=new M(this.c,this.s);this.h=new M(this.c,this.s);this.j=new M(this.c,this.s);this.m=new M(this.c,this.s);a=new G(this.a.c+",serif",J(this.a));a=O(a);this.g.a.style.cssText=a;a=new G(this.a.c+",sans-serif",J(this.a));a=O(a);this.h.a.style.cssText=a;a=new G("serif",J(this.a));a=O(a);this.j.a.style.cssText=a;a=new G("sans-serif",J(this.a));a=
|
||||
O(a);this.m.a.style.cssText=a;N(this.g);N(this.h);N(this.j);N(this.m)}var R={D:"serif",C:"sans-serif"},S=null;function T(){if(null===S){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent);S=!!a&&(536>parseInt(a[1],10)||536===parseInt(a[1],10)&&11>=parseInt(a[2],10))}return S}Q.prototype.start=function(){this.f.serif=this.j.a.offsetWidth;this.f["sans-serif"]=this.m.a.offsetWidth;this.A=q();U(this)};
|
||||
function la(a,b,c){for(var d in R)if(R.hasOwnProperty(d)&&b===a.f[R[d]]&&c===a.f[R[d]])return!0;return!1}function U(a){var b=a.g.a.offsetWidth,c=a.h.a.offsetWidth,d;(d=b===a.f.serif&&c===a.f["sans-serif"])||(d=T()&&la(a,b,c));d?q()-a.A>=a.w?T()&&la(a,b,c)&&(null===a.u||a.u.hasOwnProperty(a.a.c))?V(a,a.v):V(a,a.B):ma(a):V(a,a.v)}function ma(a){setTimeout(p(function(){U(this)},a),50)}function V(a,b){setTimeout(p(function(){v(this.g.a);v(this.h.a);v(this.j.a);v(this.m.a);b(this.a)},a),0)};function W(a,b,c){this.c=a;this.a=b;this.f=0;this.m=this.j=!1;this.s=c}var X=null;W.prototype.g=function(a){var b=this.a;b.g&&w(b.f,[b.a.c("wf",a.c,J(a).toString(),"active")],[b.a.c("wf",a.c,J(a).toString(),"loading"),b.a.c("wf",a.c,J(a).toString(),"inactive")]);K(b,"fontactive",a);this.m=!0;na(this)};
|
||||
W.prototype.h=function(a){var b=this.a;if(b.g){var c=y(b.f,b.a.c("wf",a.c,J(a).toString(),"active")),d=[],e=[b.a.c("wf",a.c,J(a).toString(),"loading")];c||d.push(b.a.c("wf",a.c,J(a).toString(),"inactive"));w(b.f,d,e)}K(b,"fontinactive",a);na(this)};function na(a){0==--a.f&&a.j&&(a.m?(a=a.a,a.g&&w(a.f,[a.a.c("wf","active")],[a.a.c("wf","loading"),a.a.c("wf","inactive")]),K(a,"active")):L(a.a))};function oa(a){this.j=a;this.a=new ja;this.h=0;this.f=this.g=!0}oa.prototype.load=function(a){this.c=new ca(this.j,a.context||this.j);this.g=!1!==a.events;this.f=!1!==a.classes;pa(this,new ha(this.c,a),a)};
|
||||
function qa(a,b,c,d,e){var f=0==--a.h;(a.f||a.g)&&setTimeout(function(){var a=e||null,m=d||null||{};if(0===c.length&&f)L(b.a);else{b.f+=c.length;f&&(b.j=f);var h,l=[];for(h=0;h<c.length;h++){var k=c[h],n=m[k.c],r=b.a,x=k;r.g&&w(r.f,[r.a.c("wf",x.c,J(x).toString(),"loading")]);K(r,"fontloading",x);r=null;if(null===X)if(window.FontFace){var x=/Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent),xa=/OS X.*Version\/10\..*Safari/.exec(window.navigator.userAgent)&&/Apple/.exec(window.navigator.vendor);
|
||||
X=x?42<parseInt(x[1],10):xa?!1:!0}else X=!1;X?r=new P(p(b.g,b),p(b.h,b),b.c,k,b.s,n):r=new Q(p(b.g,b),p(b.h,b),b.c,k,b.s,a,n);l.push(r)}for(h=0;h<l.length;h++)l[h].start()}},0)}function pa(a,b,c){var d=[],e=c.timeout;ia(b);var d=ka(a.a,c,a.c),f=new W(a.c,b,e);a.h=d.length;b=0;for(c=d.length;b<c;b++)d[b].load(function(b,d,c){qa(a,f,b,d,c)})};function ra(a,b){this.c=a;this.a=b}
|
||||
ra.prototype.load=function(a){function b(){if(f["__mti_fntLst"+d]){var c=f["__mti_fntLst"+d](),e=[],h;if(c)for(var l=0;l<c.length;l++){var k=c[l].fontfamily;void 0!=c[l].fontStyle&&void 0!=c[l].fontWeight?(h=c[l].fontStyle+c[l].fontWeight,e.push(new G(k,h))):e.push(new G(k))}a(e)}else setTimeout(function(){b()},50)}var c=this,d=c.a.projectId,e=c.a.version;if(d){var f=c.c.o;A(this.c,(c.a.api||"https://fast.fonts.net/jsapi")+"/"+d+".js"+(e?"?v="+e:""),function(e){e?a([]):(f["__MonotypeConfiguration__"+
|
||||
d]=function(){return c.a},b())}).id="__MonotypeAPIScript__"+d}else a([])};function sa(a,b){this.c=a;this.a=b}sa.prototype.load=function(a){var b,c,d=this.a.urls||[],e=this.a.families||[],f=this.a.testStrings||{},g=new B;b=0;for(c=d.length;b<c;b++)z(this.c,d[b],C(g));var m=[];b=0;for(c=e.length;b<c;b++)if(d=e[b].split(":"),d[1])for(var h=d[1].split(","),l=0;l<h.length;l+=1)m.push(new G(d[0],h[l]));else m.push(new G(d[0]));E(g,function(){a(m,f)})};function ta(a,b){a?this.c=a:this.c=ua;this.a=[];this.f=[];this.g=b||""}var ua="https://fonts.googleapis.com/css";function va(a,b){for(var c=b.length,d=0;d<c;d++){var e=b[d].split(":");3==e.length&&a.f.push(e.pop());var f="";2==e.length&&""!=e[1]&&(f=":");a.a.push(e.join(f))}}
|
||||
function wa(a){if(0==a.a.length)throw Error("No fonts to load!");if(-1!=a.c.indexOf("kit="))return a.c;for(var b=a.a.length,c=[],d=0;d<b;d++)c.push(a.a[d].replace(/ /g,"+"));b=a.c+"?family="+c.join("%7C");0<a.f.length&&(b+="&subset="+a.f.join(","));0<a.g.length&&(b+="&text="+encodeURIComponent(a.g));return b};function ya(a){this.f=a;this.a=[];this.c={}}
|
||||
var za={latin:"BESbswy","latin-ext":"\u00e7\u00f6\u00fc\u011f\u015f",cyrillic:"\u0439\u044f\u0416",greek:"\u03b1\u03b2\u03a3",khmer:"\u1780\u1781\u1782",Hanuman:"\u1780\u1781\u1782"},Aa={thin:"1",extralight:"2","extra-light":"2",ultralight:"2","ultra-light":"2",light:"3",regular:"4",book:"4",medium:"5","semi-bold":"6",semibold:"6","demi-bold":"6",demibold:"6",bold:"7","extra-bold":"8",extrabold:"8","ultra-bold":"8",ultrabold:"8",black:"9",heavy:"9",l:"3",r:"4",b:"7"},Ba={i:"i",italic:"i",n:"n",normal:"n"},
|
||||
Ca=/^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i|normal|italic)?$/;
|
||||
function Da(a){for(var b=a.f.length,c=0;c<b;c++){var d=a.f[c].split(":"),e=d[0].replace(/\+/g," "),f=["n4"];if(2<=d.length){var g;var m=d[1];g=[];if(m)for(var m=m.split(","),h=m.length,l=0;l<h;l++){var k;k=m[l];if(k.match(/^[\w-]+$/)){var n=Ca.exec(k.toLowerCase());if(null==n)k="";else{k=n[2];k=null==k||""==k?"n":Ba[k];n=n[1];if(null==n||""==n)n="4";else var r=Aa[n],n=r?r:isNaN(n)?"4":n.substr(0,1);k=[k,n].join("")}}else k="";k&&g.push(k)}0<g.length&&(f=g);3==d.length&&(d=d[2],g=[],d=d?d.split(","):
|
||||
g,0<d.length&&(d=za[d[0]])&&(a.c[e]=d))}a.c[e]||(d=za[e])&&(a.c[e]=d);for(d=0;d<f.length;d+=1)a.a.push(new G(e,f[d]))}};function Ea(a,b){this.c=a;this.a=b}var Fa={Arimo:!0,Cousine:!0,Tinos:!0};Ea.prototype.load=function(a){var b=new B,c=this.c,d=new ta(this.a.api,this.a.text),e=this.a.families;va(d,e);var f=new ya(e);Da(f);z(c,wa(d),C(b));E(b,function(){a(f.a,f.c,Fa)})};function Ga(a,b){this.c=a;this.a=b}Ga.prototype.load=function(a){var b=this.a.id,c=this.c.o;b?A(this.c,(this.a.api||"https://use.typekit.net")+"/"+b+".js",function(b){if(b)a([]);else if(c.Typekit&&c.Typekit.config&&c.Typekit.config.fn){b=c.Typekit.config.fn;for(var e=[],f=0;f<b.length;f+=2)for(var g=b[f],m=b[f+1],h=0;h<m.length;h++)e.push(new G(g,m[h]));try{c.Typekit.load({events:!1,classes:!1,async:!0})}catch(l){}a(e)}},2E3):a([])};function Ha(a,b){this.c=a;this.f=b;this.a=[]}Ha.prototype.load=function(a){var b=this.f.id,c=this.c.o,d=this;b?(c.__webfontfontdeckmodule__||(c.__webfontfontdeckmodule__={}),c.__webfontfontdeckmodule__[b]=function(b,c){for(var g=0,m=c.fonts.length;g<m;++g){var h=c.fonts[g];d.a.push(new G(h.name,ga("font-weight:"+h.weight+";font-style:"+h.style)))}a(d.a)},A(this.c,(this.f.api||"https://f.fontdeck.com/s/css/js/")+ea(this.c)+"/"+b+".js",function(b){b&&a([])})):a([])};var Y=new oa(window);Y.a.c.custom=function(a,b){return new sa(b,a)};Y.a.c.fontdeck=function(a,b){return new Ha(b,a)};Y.a.c.monotype=function(a,b){return new ra(b,a)};Y.a.c.typekit=function(a,b){return new Ga(b,a)};Y.a.c.google=function(a,b){return new Ea(b,a)};var Z={load:p(Y.load,Y)};"function"===typeof define&&define.amd?define(function(){return Z}):"undefined"!==typeof module&&module.exports?module.exports=Z:(window.WebFont=Z,window.WebFontConfig&&Y.load(window.WebFontConfig));}());
|
||||
Reference in New Issue
Block a user