Showing preview only (487K chars total). Download the full file or copy to clipboard to get everything.
Repository: typekit/webfontloader
Branch: master
Commit: 117e48d521d6
Files: 110
Total size: 457.7 KB
Directory structure:
gitextract_e9i9r2bx/
├── .gitignore
├── .travis.yml
├── CHANGELOG
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── bin/
│ └── webfontloader-demos
├── bower.json
├── browsers.json
├── externs.js
├── lib/
│ ├── webfontloader/
│ │ ├── demo/
│ │ │ ├── public/
│ │ │ │ ├── basic.css
│ │ │ │ ├── blank.html
│ │ │ │ ├── custom-iframe.html
│ │ │ │ ├── custom.html
│ │ │ │ ├── event-css-active-multiple.html
│ │ │ │ ├── event-css-active.html
│ │ │ │ ├── event-css-inactive.html
│ │ │ │ ├── event-css-loading.html
│ │ │ │ ├── event-js-active.html
│ │ │ │ ├── event-js-font-active.html
│ │ │ │ ├── event-js-loading.html
│ │ │ │ ├── events-variations.html
│ │ │ │ ├── events.html
│ │ │ │ ├── fontdeck.html
│ │ │ │ ├── fontwatchrunner-default-fonts.html
│ │ │ │ ├── google-css.html
│ │ │ │ ├── google-iframe.html
│ │ │ │ ├── google.html
│ │ │ │ ├── ie-fast-js.html
│ │ │ │ ├── ie-slow-js.html
│ │ │ │ ├── ie-slow-link.html
│ │ │ │ ├── index.html
│ │ │ │ ├── monotype-iframe.html
│ │ │ │ ├── monotype.html
│ │ │ │ ├── typekit-iframe.html
│ │ │ │ ├── typekit-variations.html
│ │ │ │ └── typekit.html
│ │ │ └── server.rb
│ │ └── modules.rb
│ └── webfontloader.rb
├── package.json
├── spec/
│ ├── core/
│ │ ├── cssclassname_spec.js
│ │ ├── domhelper_spec.js
│ │ ├── eventdispatcher_spec.js
│ │ ├── font_spec.js
│ │ ├── fontmoduleloader_spec.js
│ │ ├── fontruler_spec.js
│ │ ├── fontwatcher_spec.js
│ │ ├── fontwatchrunner_spec.js
│ │ ├── nativefontwatchrunner_spec.js
│ │ ├── size_spec.js
│ │ └── webfont_spec.js
│ ├── deps.js
│ ├── fixtures/
│ │ ├── external_script.js
│ │ ├── external_stylesheet.css
│ │ └── fonts/
│ │ ├── LICENSE.txt
│ │ ├── nullfont.css
│ │ ├── nullfont1.css
│ │ ├── nullfont2.css
│ │ ├── nullfont3.css
│ │ ├── sourcesans.otf
│ │ ├── sourcesansa.css
│ │ ├── sourcesansb.css
│ │ ├── sourcesansc.css
│ │ ├── sourcesansd.css
│ │ ├── sourcesansdup1.css
│ │ └── sourcesansdup2.css
│ ├── index.html
│ └── modules/
│ ├── custom_spec.js
│ ├── fontdeck_spec.js
│ ├── google/
│ │ ├── fontapiparser_spec.js
│ │ ├── fontapiurlbuilder_spec.js
│ │ └── googlefontapi_spec.js
│ ├── monotype_spec.js
│ └── typekit_spec.js
├── src/
│ ├── closure.js
│ ├── core/
│ │ ├── cssclassname.js
│ │ ├── domhelper.js
│ │ ├── eventdispatcher.js
│ │ ├── font.js
│ │ ├── fontmodule.js
│ │ ├── fontmoduleloader.js
│ │ ├── fontruler.js
│ │ ├── fontwatcher.js
│ │ ├── fontwatchrunner.js
│ │ ├── initialize.js
│ │ ├── nativefontwatchrunner.js
│ │ ├── stylesheetwaiter.js
│ │ └── webfont.js
│ ├── modules/
│ │ ├── custom.js
│ │ ├── fontdeck.js
│ │ ├── google/
│ │ │ ├── fontapiparser.js
│ │ │ ├── fontapiurlbuilder.js
│ │ │ └── googlefontapi.js
│ │ ├── monotype.js
│ │ └── typekit.js
│ └── modules.yml
├── tools/
│ ├── compiler/
│ │ ├── base.js
│ │ └── compiler.jar
│ ├── jasmine/
│ │ ├── MIT.LICENSE
│ │ ├── jasmine-html.js
│ │ ├── jasmine.css
│ │ └── jasmine.js
│ ├── jasmine-browserstack/
│ │ └── jasmine-browserstack.js
│ └── jasmine-phantomjs/
│ ├── jasmine-phantomjs.js
│ └── terminal-reporter.js
├── webfontloader.gemspec
└── webfontloader.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.bundle
*~
target
tmp
_site
pkg
================================================
FILE: .travis.yml
================================================
before_install:
- wget https://s3.amazonaws.com/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2
- tar -xjf phantomjs-2.0.0-ubuntu-12.04.tar.bz2
- sudo mv /usr/local/phantomjs/bin/phantomjs /usr/local/phantomjs/bin/phantomjs1
- sudo mv phantomjs /usr/local/phantomjs/bin/phantomjs
language: node_js
================================================
FILE: CHANGELOG
================================================
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
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Please open [an issue](https://github.com/typekit/webfontloader/issues) if you find or suspect any problems. Sample pages and test cases are greatly appreciated.
## Development requirements
You'll need a few rubygems to run the tests, demo server, and other rake tasks, which should be installed with [Bundler](http://gembundler.com/).
$ gem install bundler
$ bundle install
To run the tests in a headless WebKit you will also need to have [PhantomJS](http://www.phantomjs.org) installed. You can install PhantomJS by downloading a binary or using HomeBrew.
$ brew install phantomjs
## Building
To build a JS file from source, just run rake:
$ rake
If you want to build a JS file with only specific modules you can specify them on the command line:
$ rake compile['custom google typekit']
This will compile a JS file with only the `custom`, `google` and `typekit` modules. The available modules are: `custom`, `google`, `typekit`, `ascender`, `monotype`, `fontdeck`. By default all modules are included.
## Demos
A full suite of demo pages is included in this source. Here you can find some
live examples using the JS and CSS events. Run the demo server with:
$ rake demo
You can also run the demos with uncompressed, debuggable code to aid in
development. Just start the server in dev mode:
$ rake demodev
Browse the demos [source code](http://github.com/typekit/webfontloader/blob/master/lib/webfontloader/demo/public).
## Testing
Web Font Loader has an extensive test suite that runs via Jasmine. The test suite
should be passing before submitting a pull request, and new tests should be added for any new functionality.
To run tests, open up `spec/index.html` in a browser and check the results. The
test suite will run automatically. Again, before submitting a pull request
please run the test suite in multiple browsers and list them in the pull request.
To run tests in a headless WebKit using [PhantomJS](http://www.phantomjs.org) run:
$ rake test
================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'
gemspec
================================================
FILE: LICENSE
================================================
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
================================================
FILE: README.md
================================================
# 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.
================================================
FILE: Rakefile
================================================
require 'rubygems'
require 'rake'
require 'date'
#############################################################################
#
# Helper functions
#
#############################################################################
def name
@name ||= Dir['*.gemspec'].first.split('.').first
end
def version
line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
end
def date
Date.today.to_s
end
def gemspec_file
"#{name}.gemspec"
end
def gem_file
"#{name}-#{version}.gem"
end
def replace_header(head, header_name)
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
end
#############################################################################
#
# Standard tasks
#
#############################################################################
desc "Open an irb session preloaded with this library"
task :console do
sh "irb -rubygems -r ./lib/#{name}.rb"
end
#############################################################################
#
# Custom tasks (add your own tasks here)
#
#############################################################################
require 'rake/clean'
$LOAD_PATH.unshift File.dirname(__FILE__) + "/lib"
require 'webfontloader'
#
# Setup
#
# Build targets (remove with `rake clean`)
CLEAN.include("target")
CLEAN.include("tmp")
# JsCompiler
JsCompilerJar = "tools/compiler/compiler.jar"
# JS Source dependencies
AllJs = FileList["{src,src-test}/**/*"]
SourceJs = FileList["src/**/*"]
# JS Source loader
@modules = WebFontLoader::Modules.new
#
# Build
#
directory "target"
directory "tmp"
desc "Compile the JavaScript into target/webfont.js"
task :compile, [:modules] => "target/webfont.js"
file "webfontloader.js" => "target/webfont.js" do
cp "target/webfont.js", "webfontloader.js"
end
file "target/webfont.js", [:modules] => SourceJs + ["target"] do |t, args|
args.with_defaults(:modules => 'custom google typekit monotype fontdeck')
modules = args[:modules].split ' '
output_marker = "%output%"
output_wrapper = @modules.js_output_wrapper(output_marker, version)
args = [
["-jar", JsCompilerJar],
["--compilation_level", "ADVANCED_OPTIMIZATIONS"],
["--js_output_file", t.name],
["--output_wrapper", %("#{output_wrapper}")],
["--warning_level", "VERBOSE"],
["--summary_detail_level", "3"],
["--externs", "externs.js"],
"--define goog.DEBUG=false"
]
args.concat modules.map { |m| "--define INCLUDE_" + m.upcase + "_MODULE" }
# Extra args to add warnings.
args.concat([
["--warning_level", "VERBOSE"],
["--summary_detail_level", "1"]
])
source = @modules.all_source_files
args.concat source.map { |f| ["--js", f] }
output = `java #{args.flatten.join(' ')} 2>&1`
$?.success? ? (puts output) : (fail output)
end
desc "Creates debug version into target/webfont.js"
task :debug, [:modules] => "target/webfont_debug.js"
file "target/webfont_debug.js", [:modules] => SourceJs + ["target"] do |t, args|
args.with_defaults(:modules => 'custom google typekit monotype fontdeck')
modules = args[:modules].split ' '
output_marker = "%output%"
output_wrapper = @modules.js_output_wrapper(output_marker, version)
args = [
["-jar", JsCompilerJar],
["--compilation_level", "ADVANCED_OPTIMIZATIONS"],
["--js_output_file", t.name],
["--output_wrapper", %("#{output_wrapper}")],
["--warning_level", "VERBOSE"],
["--summary_detail_level", "3"],
["--externs", "externs.js"],
"--debug=true",
"--formatting=PRETTY_PRINT",
"--formatting=PRINT_INPUT_DELIMITER"
]
args.concat modules.map { |m| "--define INCLUDE_" + m.upcase + "_MODULE" }
# Extra args to add warnings.
args.concat([
["--warning_level", "VERBOSE"],
["--summary_detail_level", "1"]
])
source = @modules.all_source_files
args.concat source.map { |f| ["--js", f] }
output = `java #{args.flatten.join(' ')} 2>&1`
$?.success? ? (puts output) : (fail output)
end
#
# Run
#
desc "BrowserStack tests"
task :bstest do |t|
exec "browserstack-test -u $BROWSERSTACK_USERNAME -p $BROWSERSTACK_PASSWORD -k $BROWSERSTACK_KEY -b browsers.json -t 300 http://localhost:9999/spec/index.html"
end
desc "Test everything"
task :default => [:clean, :gzipbytes, :test]
desc "Run all tests"
task :test do |t|
exec "phantomjs tools/jasmine-phantomjs/jasmine-phantomjs.js spec/index.html"
end
desc "Start the demo server"
task :demo => "target/webfont.js" do |t|
js = t.prerequisites.first
exec "bin/webfontloader-demos -F --compiled_js #{js}"
end
desc "Start the demo server for development"
task :demodev do
exec "bin/webfontloader-demos -F -L --modules"
end
desc "Find out how many bytes the source is"
task :bytes => [:clean, "target/webfont.js"] do |t|
js = t.prerequisites.last
bytes = File.read(js).size
puts "#{bytes} bytes uncompressed"
end
desc "Find out how many bytes the source is when gzipped"
task :gzipbytes => [:clean, "target/webfont.js"] do |t|
require 'zlib'
js = t.prerequisites.last
bytes = Zlib::Deflate.deflate(File.read(js)).size
puts "#{bytes} bytes gzipped"
end
#############################################################################
#
# Packaging tasks
#
#############################################################################
task :release => [:build] do
unless `git branch` =~ /^\* master$/
puts "You must be on the master branch to release!"
exit!
end
sh "git add webfontloader.js"
sh "git commit --allow-empty -a -m 'Release #{version}'"
sh "npm version #{version}"
sh "git push --tags origin master"
sh "gem push pkg/#{name}-#{version}.gem"
sh "npm publish"
end
task :build => :gemspec do
Rake::Task["target/webfont.js"].execute
Rake::Task["webfontloader.js"].execute
sh "mkdir -p pkg"
sh "gem build #{gemspec_file}"
sh "mv #{gem_file} pkg"
end
task :gemspec => :validate do
# read spec file and split out manifest section
spec = File.read(gemspec_file)
head, manifest, tail = spec.split(" # = MANIFEST =\n")
# replace name version and date
replace_header(head, :name)
replace_header(head, :version)
replace_header(head, :date)
# determine file list from git ls-files
files = `git ls-files`.
split("\n").
sort.
reject { |file| file =~ /^\./ }.
reject { |file| file =~ /^(rdoc|pkg)/ }.
map { |file| " #{file.gsub(/\s/, '\ ')}" }.
join("\n")
# piece file back together and write
manifest = " s.files = %w[\n#{files}\n ]\n"
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
File.open(gemspec_file, 'w') { |io| io.write(spec) }
puts "Updated #{gemspec_file}"
end
task :validate do
libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
unless libfiles.empty?
puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
exit!
end
unless Dir['VERSION*'].empty?
puts "A `VERSION` file at root level violates Gem best practices."
exit!
end
end
================================================
FILE: bin/webfontloader-demos
================================================
#!/usr/bin/env ruby
require 'rubygems'
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
require 'webfontloader'
begin
require 'webfontloader/demo/server'
rescue LoadError => e
abort "Please gem install sinatra"
end
begin
require 'vegas'
rescue LoadError => e
abort "Please gem install vegas"
end
Vegas::Runner.new(WebFontLoader::Demo::Server, 'font-demos', :host => "localhost") do |runner, opts, app|
opts.on('--compiled_js FILE', "Dynamically build the JS with the given modules") { |file|
app.set :compiled_js, File.read(file)
}
opts.on('--modules [MODULES]', "Dynamically build the JS with the given modules") { |opt_modules|
modules = opt_modules ? opt_modules.split(",") : []
app.set :modules, WebFontLoader::Modules.new(*modules)
}
end
================================================
FILE: bower.json
================================================
{
"name": "webfontloader",
"main": "webfontloader.js",
"description": "Web Font Loader gives you added control when using linked fonts via @font-face.",
"moduleType": ["amd", "node"],
"license": "Apache-2.0",
"ignore": [
"**/.*",
"node_modules",
"spec",
"tools",
"lib",
"bin"
],
"keywords": [
"web",
"fonts",
"webfonts",
"font",
"loader",
"@font-face"
]
}
================================================
FILE: browsers.json
================================================
[
{
"os_version": "XP",
"os": "Windows",
"browser_version": "12.16",
"browser": "opera"
},
{
"os_version": "XP",
"os": "Windows",
"browser_version": "3.6",
"browser": "firefox"
},
{
"os_version": "XP",
"os": "Windows",
"browser_version": "20.0",
"browser": "firefox"
},
{
"os_version": "XP",
"os": "Windows",
"browser_version": "6.0",
"browser": "ie",
"timeout": "300"
},
{
"os_version": "XP",
"os": "Windows",
"browser_version": "7.0",
"browser": "ie",
"timeout": "300"
},
{
"os_version": "XP",
"os": "Windows",
"browser_version": "8.0",
"browser": "ie"
},
{
"os_version": "8",
"os": "Windows",
"browser_version": "10.0 Desktop",
"browser": "ie"
},
{
"os_version": "7",
"os": "Windows",
"browser_version": "9.0",
"browser": "ie"
},
{
"os_version": "Mountain Lion",
"os": "OS X",
"browser_version": "6.0",
"browser": "safari"
},
{
"os_version": "Mountain Lion",
"os": "OS X",
"browser_version": "25.0",
"browser": "chrome"
},
{
"os_version": "Snow Leopard",
"os": "OS X",
"browser_version": "5.0",
"browser": "safari"
},
{
"os_version": "5.0",
"device": "iPad 2 (5.0)",
"os": "ios",
"browser": "Mobile Safari",
"timeout": "300"
},
{
"os_version": "5.1",
"device": "iPad 3rd",
"os": "ios",
"browser": "Mobile Safari",
"timeout": "300"
},
{
"os_version": "6.0",
"device": "iPhone 5",
"os": "ios",
"browser": "Mobile Safari",
"timeout": "300"
},
{
"os_version": "4.3.2",
"device": "iPad 2",
"os": "ios",
"browser": "Mobile Safari",
"timeout": "300"
},
{
"os_version": "2.3",
"device": "Samsung Galaxy S II",
"os": "android",
"browser": "Android Browser",
"timeout": "300"
},
{
"os_version": "2.2",
"device": "Samsung Galaxy S",
"os": "android",
"browser": "Android Browser",
"timeout": "300"
},
{
"os_version": "4.2",
"device": "LG Nexus 4",
"os": "android",
"browser": "Android Browser",
"timeout": "300"
},
{
"os_version": "4.0",
"device": "Samsung Galaxy Nexus",
"os": "android",
"browser": "Android Browser",
"timeout": "300"
},
{
"os_version": "4.1",
"device": "Samsung Galaxy S III",
"os": "android",
"browser": "Android Browser",
"timeout": "300"
}
]
================================================
FILE: externs.js
================================================
/**
* @type {function(function():*)}
*/
var define;
/**
* @type {boolean?}
*/
define.amd;
/**
* @type {Object}
*/
var module;
/**
* @type {Object?}
*/
module.exports;
================================================
FILE: lib/webfontloader/demo/public/basic.css
================================================
body {
line-height: 1;
font-size: 14px;
margin: 10px;
}
h1 {
font-size: 5em;
margin: 0;
}
================================================
FILE: lib/webfontloader/demo/public/blank.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Blank page</title>
</head>
<body>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/custom-iframe.html
================================================
<!doctype html>
<html>
<head>
<title>Custom Module</title>
<script type="text/javascript" src="/webfont.js"></script>
<style >
iframe {
height: 100px;
width: 100%;
}
</style>
</head>
<body>
<script type="text/javascript">
function loaded() {
var child = frames["child"];
child.document.body.innerHTML = "<h1 style=\"font-family: 'ChunkFiveRegular'\">Hello World. I am ChunkFive.</h1>";
WebFont.load({
custom: {
families: ['ChunkFiveRegular'],
urls : ['http://seanmcb.com/typekit/wfl/stylesheet.css']
},
context: child
});
}
</script>
<iframe name="child" src="/blank.html" onload="loaded()"></iframe>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/custom.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how fonts load from a custom module in a
child iframe.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/custom.html
================================================
<!doctype html>
<html>
<head>
<title>Custom Module</title>
<script type="text/javascript" src="/webfont.js"></script>
<style type="text/css">
h1 {
font-family: 'ChunkFiveRegular';
}
/* All Class hooks */
#classes { color: #ddd; }
html.wf-loading #classes .Loading,
html.wf-active #classes .Active,
html.wf-inactive #classes .Inactive,
html.wf-chunkfiveregular-n4-loading #classes .ChunkFiveLoading,
html.wf-chunkfiveregular-n4-active #classes .ChunkFiveActive,
html.wf-chunkfiveregular-n4-inactive #classes .ChunkFiveInactive {
color: #000;
}
</style>
</head>
<body>
<h1 class="tagesschrift">
Hello World. I am ChunkFive.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/custom.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how fonts load from a custom module.
</p>
<h2>CSS Hook Status</h2>
<ul id="classes">
<li class="Loading">Loading</li>
<li class="Active">Active</li>
<li class="Inactive">Inactive</li>
<li class="ChunkFiveLoading">ChunkFive Loading</li>
<li class="ChunkFiveActive">ChunkFive Active</li>
<li class="ChunkFiveInactive">ChunkFive Inactive</li>
</ul>
<h2>JavaScript Event Progress</h2>
<ol id="events"></ol>
<!-- loading event may fire before page is completely ready -->
<script type="text/javascript">
function progress(message) {
var output = document.getElementById('events');
if (output) {
var e = document.createElement('li');
e.innerHTML = message;
output.appendChild(e);
}
if (window.console && window.console.log) {
window.console.log(message);
}
}
WebFont.load({
custom: {
families: ['ChunkFiveRegular'],
urls : ['http://seanmcb.com/typekit/wfl/stylesheet.css']
},
loading: function() {
progress('loading');
},
active: function() {
progress('active');
},
inactive: function() {
progress('inactive');
},
fontloading: function(fontFamily, fontDescription) {
progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
},
fontactive: function(fontFamily, fontDescription) {
progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
},
fontinactive: function(fontFamily, fontDescription) {
progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
}
});
</script>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-css-active-multiple.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans', 'Tangerine']
}
});
</script>
<style type="text/css">
h1 {
visibility: hidden;
}
html.wf-droidsans-n4-active h1.droid {
visibility: visible;
font-family: 'Droid Sans';
}
html.wf-tangerine-n4-active h1.tangerine {
visibility: visible;
font-family: 'Tangerine';
}
</style>
</head>
<body>
<h1 class="droid">
Hello World. I am Droid Sans.
</h1>
<h1 class="tangerine">
Hello World. I am Tangerine.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-css-active-multiple.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use CSS to show each part of the page when
its font has loaded.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-css-active.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
}
});
</script>
<style type="text/css">
h1 {
visibility: hidden;
}
html.wf-active h1 {
visibility: visible;
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1>
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-css-active.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use CSS to hide the headline until its font
has completely rendered.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-css-inactive.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
}
});
</script>
<style type="text/css">
h1 {
font-family: sans-serif;
font-weight: normal;
}
html.wf-active h1 {
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1>
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-css-inactive.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use CSS to present a fallback font until the custom font
has completely rendered.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-css-loading.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api',
blocking: false
}
});
</script>
<style type="text/css">
/* Show and style the loading message while fonts are loading */
html.wf-loading #loading-message {
display: block;
color: #999;
}
/* Hide the content while fonts are loading */
html.wf-loading #content {
display: none;
}
/* Hide the loading message after fonts render */
html.wf-active #loading-message {
display: none;
}
html.wf-active h1 {
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1 id="loading-message">
I'm loading!
</h1>
<h1 id="content">
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-css-loading.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use CSS to show a loading message while the
headline's font is loading, then hide the loading message and show the
headline once the font has rendered.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-js-active.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
},
active: function() {
var h1 = document.getElementsByTagName('h1')[0];
h1.style.visibility = 'visible';
h1.style.fontFamily = 'Droid Sans';
}
});
</script>
<style type="text/css">
h1 {
visibility: hidden;
}
</style>
</head>
<body>
<h1>
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-js-active.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use a combination of JavaScript and CSS to
hide the headline until its font has completely rendered.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-js-font-active.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
},
fontactive: function(familyName, fontDescription) {
if (familyName == 'Droid Sans') {
var h1 = document.getElementsByTagName('h1')[0];
h1.innerHTML = 'Hello World. I am ' + familyName + ' (' + fontDescription + ')';
}
}
});
</script>
<style type="text/css">
h1 {
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1>
Hello World.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-js-font-active.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use JavaScript to manipulate the page when
a particular font loads.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/event-js-loading.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
},
/*
* Style the document while fonts are loading.
*/
loading: function() {
// The <body> doesn't exist yet, so wait a moment.
setTimeout(function() {
document.body.style.color = '#999';
}, 10);
},
/*
* When fonts are rendered, hide the loading message, show the
* content, and change the style of the document.
*/
active: function() {
var loadingMessage = document.getElementById('loading-message');
var content = document.getElementById('content');
loadingMessage.style.display = 'none';
content.style.display = 'block';
document.body.style.color = '#000';
}
});
</script>
<style type="text/css">
h1 {
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1 id="loading-message">
I'm loading!
</h1>
<h1 id="content" style="display:none;">
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/event-js-loading.html">Reload Cached</a>
</p>
<p>
The goal of this page is to use JavaScript to manipulate the DOM while
fonts are loading, and once they have all rendered.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/events-variations.html
================================================
<!doctype html>
<html>
<head>
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
function progress(message) {
var output = document.getElementById('events');
if (output) {
var e = document.createElement('li');
e.innerHTML = message;
output.appendChild(e);
}
if (window.console && window.console.log) {
window.console.log(message);
}
}
WebFont.load({
google: {
families: ['Droid Serif:r,i,b,bi']
},
loading: function() {
progress('loading');
},
active: function() {
progress('active');
},
inactive: function() {
progress('inactive');
},
fontloading: function(fontFamily, fontDescription) {
progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
},
fontactive: function(fontFamily, fontDescription) {
progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
},
fontinactive: function(fontFamily, fontDescription) {
progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
}
});
</script>
<style type="text/css">
.droid p {
font-family: 'Droid Serif';
font-size: 2em;
margin-bottom: 0;
visibility: hidden;
}
.wf-droidserif-n4-active #droidregular {
visibility: visible;
}
.wf-droidserif-i4-active #droiditalic {
visibility: visible;
}
.wf-droidserif-n7-active #droidbold {
visibility: visible;
}
.wf-droidserif-i7-active #droidbolditalic {
visibility: visible;
}
/* All Class hooks */
#classes { color: #ddd; }
html.wf-loading #classes .Loading,
html.wf-active #classes .Active,
html.wf-inactive #classes .Inactive,
html.wf-droidserif-n4-loading #classes #DroidSerifRegularLoading,
html.wf-droidserif-n4-active #classes #DroidSerifRegularActive,
html.wf-droidserif-n4-inactive #classes #DroidSerifRegularInactive,
html.wf-droidserif-i4-loading #classes #DroidSerifItalicLoading,
html.wf-droidserif-i4-active #classes #DroidSerifItalicActive,
html.wf-droidserif-i4-inactive #classes #DroidSerifItalicInactive,
html.wf-droidserif-n7-loading #classes #DroidSerifBoldLoading,
html.wf-droidserif-n7-active #classes #DroidSerifBoldActive,
html.wf-droidserif-n7-inactive #classes #DroidSerifBoldInactive,
html.wf-droidserif-i7-loading #classes #DroidSerifBoldItalicLoading,
html.wf-droidserif-i7-active #classes #DroidSerifBoldItalicActive,
html.wf-droidserif-i7-inactive #classes #DroidSerifBoldItalicInactive {
color: #000;
}
</style>
</head>
<body>
<div class="droid">
<p id="droidregular">
Droid Serif Regular
</p>
<p id="droiditalic">
<em>Droid Serif Italic</em>
</p>
<p id="droidbold">
<strong>Droid Serif Bold</strong>
</p>
<p id="droidbolditalic">
<strong><em>Droid Serif Bold Italic</em></strong>
</p>
</div>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/events-variations.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show all of the font loading event callbacks when using
multiple weights and styles of one typeface.
</p>
<h2>CSS Hook Status</h2>
<ul id="classes">
<li class="Loading">Loading</li>
<li class="Active">Active</li>
<li class="Inactive">Inactive</li>
<li id="DroidSerifRegularLoading">Droid Serif Regular Loading</li>
<li id="DroidSerifRegularActive">Droid Serif Regular Active</li>
<li id="DroidSerifRegularInactive">Droid Serif Regular Inactive</li>
<li id="DroidSerifItalicLoading">Droid Serif Italic Loading</li>
<li id="DroidSerifItalicActive">Droid Serif Italic Active</li>
<li id="DroidSerifItalicInactive">Droid Serif Italic Inactive</li>
<li id="DroidSerifBoldLoading">Droid Serif Bold Loading</li>
<li id="DroidSerifBoldActive">Droid Serif Bold Active</li>
<li id="DroidSerifBoldInactive">Droid Serif Bold Inactive</li>
<li id="DroidSerifBoldItalicLoading">Droid Serif Bold Italic Loading</li>
<li id="DroidSerifBoldItalicActive">Droid Serif Bold Italic Active</li>
<li id="DroidSerifBoldItalicInactive">Droid Serif Bold Italic Inactive</li>
</ul>
<h2>JavaScript Event Progress</h2>
<ol id="events"></ol>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/events.html
================================================
<!doctype html>
<html>
<head>
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
function progress(message) {
var output = document.getElementById('events');
if (output) {
var e = document.createElement('li');
e.innerHTML = message;
output.appendChild(e);
}
if (window.console && window.console.log) {
window.console.log(message);
}
}
WebFont.load({
google: {
families: ['Droid Sans', 'Tangerine']
},
loading: function() {
progress('loading');
},
active: function() {
progress('active');
},
inactive: function() {
progress('inactive');
},
fontloading: function(fontFamily, fontDescription) {
progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
},
fontactive: function(fontFamily, fontDescription) {
progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
},
fontinactive: function(fontFamily, fontDescription) {
progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
}
});
</script>
<style type="text/css">
h1 {
visibility: hidden;
}
.wf-droidsans-n4-active h1.droid {
font-family: 'Droid Sans';
font-weight: normal;
visibility: visible;
}
.wf-tangerine-n4-active h1.tangerine {
font-family: 'Tangerine';
font-weight: normal;
visibility: visible;
}
/* All Class hooks */
#classes { color: #ddd; }
html.wf-loading #classes .Loading,
html.wf-active #classes .Active,
html.wf-inactive #classes .Inactive,
html.wf-droidsans-n4-loading #classes .DroidSansLoading,
html.wf-droidsans-n4-active #classes .DroidSansActive,
html.wf-droidsans-n4-inactive #classes .DroidSansInactive,
html.wf-tangerine-n4-loading #classes .TangerineLoading,
html.wf-tangerine-n4-active #classes .TangerineActive,
html.wf-tangerine-n4-inactive #classes .TangerineInactive {
color: #000;
}
</style>
</head>
<body>
<h1 class="droid">
Hello World. I am Droid Sans.
</h1>
<h1 class="tangerine">
Hello World. I am Tangerine.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/events.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show all of the font loading event callbacks when
using multiple typefaces.
</p>
<h2>CSS Hook Status</h2>
<ul id="classes">
<li class="Loading">Loading</li>
<li class="Active">Active</li>
<li class="Inactive">Inactive</li>
<li class="DroidSansLoading">Droid Sans Loading</li>
<li class="DroidSansActive">Droid Sans Active</li>
<li class="DroidSansInactive">Droid Sans Inactive</li>
<li class="TangerineLoading">Tangerine Loading</li>
<li class="TangerineActive">Tangerine Active</li>
<li class="TangerineInactive">Tangerine Inactive</li>
</ul>
<h2>JavaScript Event Progress</h2>
<ol id="events"></ol>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/fontdeck.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script src="/webfont.js"></script>
<script>
function progress(message) {
var output = document.getElementById('events');
if (output) {
var e = document.createElement('li');
e.innerHTML = message;
output.appendChild(e);
}
if (window.console && window.console.log) {
window.console.log(message);
}
}
WebFont.load({
fontdeck: {
id: 2282
},
loading: function() {
progress('loading');
},
active: function() {
progress('active');
},
inactive: function() {
progress('inactive');
},
fontloading: function(fontFamily, fontDescription) {
progress('fontloading: ' + fontFamily + ' (' + fontDescription + ')');
},
fontactive: function(fontFamily, fontDescription) {
progress('fontactive: ' + fontFamily + ' (' + fontDescription + ')');
},
fontinactive: function(fontFamily, fontDescription) {
progress('fontinactive: ' + fontFamily + ' (' + fontDescription + ')');
}
});
</script>
<style>
h1 {
font-family: 'Fertigo Pro Regular';
visibility: hidden;
}
h2 {
font-family: 'Bodoni Display Bold Italic';
font-weight: bold;
font-style: italic;
visibility: hidden;
}
.wf-fertigoproregular-n4-active h1,
.wf-bodonidisplaybolditalic-i7-active h2 {
visibility: visible;
}
</style>
</head>
<body>
<h1>Hello World. I am Fertigo Pro Regular.</h1>
<h2>Hello World. I am Bodoni Display Bold Italic.</h2>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/fontdeck.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how Fontdeck fonts load.
</p>
<p>
You must use "localhost" when testing Fontdeck fonts.
</p>
<ol id="events"></ol>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/fontwatchrunner-default-fonts.html
================================================
<!DOCTYPE html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/jquery.min.js"></script>
<script type="text/javascript" src="/webfont-fontwatchrunner.js"></script>
<style type="text/css">
#results {
font-family: arial, sans-serif;
font-size: 16px;
}
.test-case {
font-size: 300px;
}
</style>
<script type="text/javascript">
var styles = '<style type="text/css">';
styles += '.default-fonts-a {font-family: ' + webfont.FontWatchRunner.DEFAULT_FONTS_A + ';}';
styles += '.default-fonts-b {font-family: ' + webfont.FontWatchRunner.DEFAULT_FONTS_B + ';}';
styles += '</style>';
document.write(styles);
</script>
</head>
<body>
<p id="results">Calculating...</p>
<p>
The goal of this page is to verify that the two default font stacks in
FontWatchRunner have different widths on a given platform when rendering the
default test string. The pairs of headings below should render in different
fonts and the results above should indicate that they all have different
widths.
</p>
<hr>
<div id="test-cases"></div>
<script type="text/javascript">
// Calculate all the different combinations of styles to test
var styles = {
'font-weight': [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
'font-style': ['normal', 'italic'],
'text-rendering': [null, 'optimizeLegibility']
};
function calculateStyleCombos(props, styles) {
if (props.length <= 0) {
return [{}]
}
var remainingProps = $.extend(true, [], props);
var prop = remainingProps.pop();
var remainingCombos = calculateStyleCombos(remainingProps, styles);
var combos = [];
for (var i = 0; i < remainingCombos.length; i++) {
for (var j = 0; j < styles[prop].length; j++) {
var combo = {};
if (styles[prop][j] !== null) {
combo[prop] = styles[prop][j];
}
combos.push($.extend(combo, remainingCombos[i]));
}
}
return combos;
}
var styleCombos = calculateStyleCombos(['font-weight', 'font-style', 'text-rendering'], styles);
// Create test cases with default test strings for each style combo
var testCases = $('#test-cases');
for (var i = 0; i < styleCombos.length; i++) {
var test = $('<div class="test-case"></div>').css(styleCombos[i]);
test.append($('<span class="default-fonts-a"></span>').text(webfont.FontWatchRunner.DEFAULT_TEST_STRING));
test.append($('<span class="default-fonts-b"></span>').text(webfont.FontWatchRunner.DEFAULT_TEST_STRING));
testCases.append(test);
}
// Calculate the width of the spans after timeout
setTimeout(function() {
var comparisons = $('<span></span>');
var allPassed = true;
$('.test-case').each(function() {
var a = $(this).find('span').first().width();
var b = $(this).find('span').last().width();
comparisons.append($('<span></span>').css('color', a != b ? 'green' : 'red').text(a - b)).append(' ');
allPassed = allPassed && a != b;
});
$('#results').text(allPassed ? 'SUCCESS | ' : 'FAIL | ').append(comparisons);
}, 500);
</script>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/google-css.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<link href="/fonts/api?family=Droid+Sans" rel="stylesheet" type="text/css">
<style type="text/css">
h1 {
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1>
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/google-css.html">Reload Cached</a>
</p>
<p>
The goal of this page is simply to use fonts directly via CSS.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/google-iframe.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<style type="text/css">
iframe {
height: 100px;
width: 100%;
}
</style>
</head>
<body>
<script type="text/javascript">
function loaded() {
var child = frames["child"];
child.document.body.innerHTML = "<h1 style=\"font-family: 'Droid Sans'\">Hello World. I am Droid Sans.</h1>";
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
},
context: child
});
}
</script>
<iframe name="child" src="/blank.html" onload="loaded()"></iframe>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/google.html">Reload Cached</a>
</p>
<p>
The goal of this page is demonstrate fonts loading from Google via
Javascript into a child iframe.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/google.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api'
}
});
</script>
<style type="text/css">
h1 {
font-family: 'Droid Sans';
}
</style>
</head>
<body>
<h1>
Hello World. I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/google.html">Reload Cached</a>
</p>
<p>
The goal of this page is simply to use fonts via the JavaScript API.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/ie-fast-js.html
================================================
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Show me Fonts</title>
<!--
An external script will block page rendering in IE, but we take care to
correct that behavior.
-->
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
api: '/fonts/api',
}
});
</script>
<style type="text/css">
.serif {
font-family: serif;
}
.droid {
font-family: 'Droid Sans', serif;
}
</style>
</head>
<body>
<h1 class="serif">
I am a serif font.
</h1>
<h1 class="droid">
I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/ie-fast-js.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show non-blocking behavior in MSIE. This
causes IE to load fonts without blocking the entire page.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/ie-slow-js.html
================================================
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Show me Fonts</title>
<!--
An external script will block page rendering in IE. Normally we fix that
behavior, but here we'll undo the override.
-->
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Droid Sans'],
blocking: true,
api: '/fonts/api'
}
});
</script>
<style type="text/css">
.serif {
font-family: serif;
}
.droid {
font-family: 'Droid Sans', serif;
}
</style>
</head>
<body>
<h1 class="serif">
I am a serif font.
</h1>
<h1 class="droid">
I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/ie-slow-js.html">Reload Cached</a>
</p>
<p>
The goal of this page is to restore blocking behavior in MSIE. This causes
IE to block the entire page while loading fonts.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/ie-slow-link.html
================================================
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Show me Fonts</title>
<!--
An external stylesheet will block page rendering in IE
-->
<link href="/fonts/api?family=Droid+Sans" rel="stylesheet" type="text/css">
<style type="text/css">
.serif {
font-family: serif;
}
.droid {
font-family: 'Droid Sans', serif;
}
</style>
</head>
<body>
<h1 class="serif">
I am a serif font.
</h1>
<h1 class="droid">
I am Droid Sans.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/ie-slow-link.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show that by default, MSIE will block the entire
page while an external font loads.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/index.html
================================================
<!doctype html>
<html>
<head>
</head>
<body>
<h1>Web Font Loader Demos</h1>
<p>
Demonstrations of pure CSS and JavaScript-enhanced use of @font-face.
</p>
<p>
Note that many of these demonstrations use a <strong>slow proxy</strong> to
increase the amount of time it takes to load a font. We do this to make it
more obvious that the events system is working. It <em>does not</em> represent
real world usage.
</p>
<h2>Modules</h2>
<p>
Web Font Loader provides modules to load fonts from many places.
</p>
<ol>
<li><a href="/google-css.html">Google / CSS Link</a>: Load fonts from Google with a <code>link</code> tag. Consider this a base case for font loading.</li>
<li><a href="/google.html">Google / Web Font Loader</a>: Load fonts from Google with Web Font Loader.</li>
<li><a href="/typekit.html">Typekit / Web Font Loader</a>: Load fonts from Typekit with Web Font Loader.</li>
<li><a href="/custom.html">Custom / Web Font Loader</a>: Load fonts from your own CSS with Web Font Loader.</li>
<li><a href="/fontdeck.html">Fontdeck / Web Font Loader</a>: Load fonts from Fontdeck with Web Font Loader.</li>
<li><a href="/monotype.html">Monotype / Web Font Loader</a>: Load fonts from fonts.com with Web Font Loader.</li>
</ol>
<h2>Modules in Iframes</h2>
<p>
Web Font Loader provides the ability to load fonts in child iframes using modules, instead of the main window.
</p>
<ol>
<li><a href="/google-iframe.html">Google / Web Font Loader</a>: Load fonts from Google in a child iframe with Web Font Loader.</li>
<li><a href="/typekit-iframe.html">Typekit / Web Font Loader</a>: Load fonts from Typekit in a child iframe with Web Font Loader.</li>
<li><a href="/custom-iframe.html">Custom / Web Font Loader</a>: Load fonts from your own CSS in a child iframe with Web Font Loader.</li>
<li>Fontdeck / Web Font Loader: Their demo fonts seem to be broken at the moment, so we don't have an iframe demo of this module.</li>
<li><a href="/monotype-iframe.html">Monotype / Web Font Loader</a>: Load fonts from fonts.com in a child iframe with Web Font Loader.</li>
</ol>
<h2>Events</h2>
<p>
Web Font Loader provides events to help control font rendering across browsers. Here are some sample uses.
</p>
<ol>
<li><a href="/event-css-active.html">Show when rendered (CSS)</a>: Use CSS to show part of the page only when the font has rendered. (Webkit style)</li>
<li><a href="/event-js-active.html">Show when rendered (JS)</a>: Use JS to show part of the page only when the font has rendered. (Webkit style)</li>
<li><a href="/event-css-inactive.html">Fallback before rendered (CSS)</a>: Use CSS to show fallback font before the font has rendered. (Mozilla style)</li>
<li><a href="/event-css-loading.html">Show loading message (CSS)</a>: Use CSS to show a message while the font loads.</li>
<li><a href="/event-js-loading.html">Show loading message (JS)</a>: Use JS to show a message while the font loads.</li>
</ol>
<h2>More Events</h2>
<p>
More complex samples using events.
</p>
<ol>
<li><a href="/event-css-active-multiple.html">Multiple font loads</a>: Use CSS to control more than one font.</li>
<li><a href="/events.html">Multiple typefaces</a>: The full CSS and JS event cycle when using multiple typefaces.</li>
<li><a href="/events-variations.html">Multiple variations</a>: The full CSS and JS event cycle when using multiple weights and styles of one typeface.</li>
</ol>
<h2>IE Behavior</h2>
<p>
Web Font Loader helps workaround IE's page blocking behavior.
</p>
<ol>
<li><a href="/ie-slow-link.html">Slow Link</a>: Demonstrate that IE blocks the whole page when loading fonts via a LINK tag.</li>
<li><a href="/ie-fast-js.html">Fast JS</a>: By default, Web Font Loader works around the default IE loading behavior.</li>
<li><a href="/ie-slow-js.html">Slow JS</a>: Restore the default IE loading behavior.</li>
</ol>
<h2>Tests</h2>
<p>
Additional demo pages to test specific functionality.
</p>
<ol>
<li><a href="/typekit-variations.html">Typekit with Multiple Variations</a></li>
<li><a href="/fontwatchrunner-default-fonts.html">Default font stacks for FontWatchRunner</li>
</ol>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/monotype-iframe.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<style>
iframe {
height: 100px;
width: 100%;
}
</style>
</head>
<body>
<script type="text/javascript">
function loaded() {
frames["child"].document.body.innerHTML = "<h1>Hello World. I am DIN Next Bold.</h1>";
WebFont.load({
monotype: {
projectId: 'b726c28f-a28a-45be-993f-3db719bacfab'
},
context: frames["child"]
});
}
</script>
<iframe name="child" src="/blank.html" onload="loaded()"></iframe>
<hr>
<p>
<a href="#" onClick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/monotype.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how monotype fonts load in a child iframe.
</p>
<p>
You must use "localhost" when testing monotype fonts.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/monotype.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
monotype: {
projectId: 'b726c28f-a28a-45be-993f-3db719bacfab'
}
});
</script>
</head>
<body>
<h1>
Hello World. I am DIN Next Bold.
</h1>
<hr>
<p>
<a href="#" onClick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/monotype.html">Reload Cached</a>
</p>
<p class="c1">
The goal of this page is to show how monotype fonts load. And I'm Albertus Regular
</p>
<p class="c2">
You must use "localhost" when testing monotype fonts. And this is Trade Gothic Condensed
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/typekit-iframe.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<style type="text/css">
iframe {
height: 100px;
width: 100%;
}
</style>
</head>
<body>
<script type="text/javascript">
function loaded() {
var child = frames["child"];
child.document.body.innerHTML = "<h1>Hello World. I am Futura PT.</h1>";
WebFont.load({
typekit: {
id: 'bod7grh'
},
context: child
});
}
</script>
<iframe name="child" src="/blank.html" onload="loaded()"></iframe>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/typekit.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how Typekit fonts load into an iframe.
</p>
<p>
You must load the fonts on "localhost" for this demo to work.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/typekit-variations.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
typekit: {
id: 'kitwithgeorgia',
api: '/typekit'
}
});
</script>
<style type="text/css">
/* Use classes to prove that Typekit triggers the event system correctly */
.georgia p {
font-family: 'Georgia';
font-size: 3em;
visibility: hidden;
}
.wf-georgia-i4-active #georgiaitalic {
visibility: visible;
}
.wf-georgia-i7-active #georgiabolditalic {
visibility: visible;
}
</style>
</head>
<body>
<div class="georgia">
<p id="georgiaitalic">
<em>Georgia Italic</em>
</p>
<p id="georgiabolditalic">
<strong><em>Georgia Bold Italic</em></strong>
</p>
</div>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/typekit-variations.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how Typekit fonts load. Note that it uses
a minimal Typekit script in order to reduce dependencies. This script
simply provides the system font 'Georgia' in italic and bold italic
instead of loading a web font.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/public/typekit.html
================================================
<!doctype html>
<html>
<head>
<link href="/basic.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/webfont.js"></script>
<script type="text/javascript">
WebFont.load({
typekit: {
id: 'bod7grh'
}
});
</script>
<style type="text/css">
/* Use classes to prove that Typekit triggers the event system correctly */
h1 {
visibility: hidden;
}
.wf-futurapt-n7-active h1 {
visibility: visible;
}
</style>
</head>
<body>
<h1>
Hello World. I am Futura PT.
</h1>
<hr>
<p>
<a href="#" onclick="document.getElementsByTagName('body')[0].style.color = '#fff';return false;">Hide Page</a> |
<a href="/typekit.html">Reload Cached</a>
</p>
<p>
The goal of this page is to show how Typekit fonts load.
</p>
<p>
You must load this page on "localhost" in order for the fonts to load.
</p>
</body>
</html>
================================================
FILE: lib/webfontloader/demo/server.rb
================================================
require 'sinatra/base'
require 'open-uri'
module WebFontLoader
module Demo
class Server < Sinatra::Base
DemoRoot = File.expand_path(File.join(File.dirname(__FILE__)))
ProjectRoot = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", ".."))
GoogleApi = "https://fonts.googleapis.com/css"
GoogleFontApi = "https://themes.googleusercontent.com/font"
set :app_file, __FILE__
set :sessions, false
set :static, true
set :modules, nil
set :compiled_js, nil
get '/' do
File.read(File.join(DemoRoot, "public", "index.html"))
end
get '/webfont.js' do
headers 'Content-Type' => "application/javascript"
headers 'Cache-Control' => 'max-age=300'
get_js_code
end
get '/webfont-fontwatchrunner.js' do
headers 'Content-Type' => 'application/javascript'
headers 'Cache-Control' => 'max-age=300'
[
'var webfont = {};',
File.read(File.join(WebFontLoader::ProjectRoot, 'src/core/fontwatchrunner.js'))
]
end
get '/fonts/api' do
url = "#{GoogleApi}?#{env['QUERY_STRING']}"
headers 'Content-Type' => 'text/css'
headers 'Cache-Control' => 'max-age=300'
response = open(url, 'User-Agent' => env['HTTP_USER_AGENT'])
source = response.read
source.gsub!(%r[https://themes.googleusercontent.com/font], '/fonts/font')
source
end
get '/fonts/font' do
sleep 1
url = "#{GoogleFontApi}?#{env['QUERY_STRING']}"
headers 'Cache-Control' => 'max-age=300'
headers 'Content-Encoding' => 'gzip'
response = open(url, 'User-Agent' => env['HTTP_USER_AGENT'])
response.read
end
get %r[/typekit/(\w+)\.js] do |kit_id|
headers 'Content-Type' => 'application/javascript'
headers 'Cache-Control' => 'max-age=300'
case kit_id
when "kitwitharialblack"
families = "['Arial Black']"
variations = "{}"
when "kitwithgeorgia"
families = "['Georgia']"
variations = "{ 'Georgia': ['i4', 'i7' ]}"
else
families = "[]"
variations = "{}"
end
<<-JS
if (window.__webfonttypekitmodule__) {
var module = window.__webfonttypekitmodule__['#{kit_id}'];
if (module) {
module(function(userAgent, configuration, init) {
// Here you may use the userAgent object to determine
// browser support.
init(true, #{families}, #{variations});
});
}
}
JS
end
protected
def get_js_code
if settings.compiled_js
settings.compiled_js
elsif settings.modules
settings.modules.all_source_files.map { |file| File.read(File.join(WebFontLoader::ProjectRoot, file)) }
else
"alert('No JavaScript has been configured in the demo server');"
end
end
end
end
end
================================================
FILE: lib/webfontloader/modules.rb
================================================
module WebFontLoader
class Modules
def initialize(*modules)
@project_root = WebFontLoader::ProjectRoot
@js_src = "src"
@js_test = "src-test"
@modules = modules.empty? ? config.keys : modules
# Make sure 'core' is first.
@modules.unshift "core"
@modules.uniq!
end
attr_reader :modules
attr_accessor :project_root, :js_src, :js_test
def all_source_files
@all_source_files ||= begin
modules.map { |mod| config[mod] }.compact.flatten.map { |f| File.join(js_src, f) }
end
end
def all_test_globs
@all_test_globs ||= begin
js_test_dirs = Dir[File.join(project_root, js_test, "*")].map { |d| File.basename(d) }
js_test_dirs.map { |dir| File.join(js_test, dir, "*.js") if modules.include?(dir) }.compact
end
end
def js_output_wrapper(source, version)
File.read(File.join(js_src, "closure.js")).sub("{{source}}", source).sub("{{version}}", version).gsub(/\n|\r/,"")
end
protected
def config
@config ||= begin
path = File.join(project_root, js_src)
YAML.load_file(File.join(path, "modules.yml"))
end
end
end
end
================================================
FILE: lib/webfontloader.rb
================================================
require 'yaml'
require 'webfontloader/modules'
module WebFontLoader
VERSION = '1.6.28'
ProjectRoot = File.expand_path(File.dirname(__FILE__) + "/..")
end
================================================
FILE: package.json
================================================
{
"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": {}
}
================================================
FILE: spec/core/cssclassname_spec.js
================================================
describe('CssClassName', function () {
var CssClassName = webfont.CssClassName,
sanitizer = new CssClassName();
describe('#sanitize', function () {
it('should sanitize spaces in names', function () {
expect(sanitizer.sanitize(' My Family ')).toEqual('myfamily');
});
it('should sanitize numbers in names', function () {
expect(sanitizer.sanitize('99 My Family 99')).toEqual('99myfamily99');;
});
it('should sanitize other characters', function () {
expect(sanitizer.sanitize('_My+Family!-')).toEqual('myfamily');
});
});
describe('#build', function () {
it('should build many parts', function () {
expect(sanitizer.build('pre_', 'My Family', '_post')).toEqual('pre-myfamily-post');
});
it('should build some parts', function () {
expect(sanitizer.build('pre!', 'My Family')).toEqual('pre-myfamily');
});
});
describe('#constructor', function () {
it('should use a hyphen as a default separator', function () {
var sanitizer = new CssClassName();
expect(sanitizer.build('pre', 'post')).toEqual('pre-post');
});
it('should use the configured separator', function () {
var sanitizer = new CssClassName('_');
expect(sanitizer.build('pre', 'post')).toEqual('pre_post');
});
});
});
================================================
FILE: spec/core/domhelper_spec.js
================================================
describe('DomHelper', function () {
var DomHelper = webfont.DomHelper,
domHelper = new DomHelper(window);
describe('#createElement', function () {
it('should create an element', function () {
var div = domHelper.createElement('div');
expect(div).not.toBeNull();
});
it('should create an element with inline content', function () {
var div = domHelper.createElement('div', {}, 'moo');
expect(div).not.toBeNull();
expect(div.innerHTML).toEqual('moo');
});
it('should create an element with attributes and inline content', function () {
var div = domHelper.createElement('div', {
style: 'font-size: 42px',
id: 'mySpan'
}, 'hello');
expect(div).not.toBeNull();
expect(div.innerHTML).toEqual('hello');
expect(div.style.fontSize).toEqual('42px');
expect(div.id).toEqual('mySpan');
});
it('should work with augmented Object.prototype', function () {
Object.prototype.evil = function () {};
var div = domHelper.createElement('div', { id: 'augmented' });
var parentDiv = domHelper.createElement('div', { id: 'parentaugmented' });
parentDiv.appendChild(div);
expect(div).not.toBeNull();
expect(!!div.getAttribute('evil')).toBe(false);
expect(-1, parentDiv.innerHTML.indexOf('evil'));
delete Object.prototype.evil;
});
});
describe('#appendClassName', function () {
it('should have added a class name', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
expect(div.className).toEqual('moo');
});
it('should not add duplicate class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
domHelper.appendClassName(div, 'meu');
domHelper.appendClassName(div, 'moo');
expect(div.className).toEqual('moo meu');
});
it('should add multiple class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo meu moo');
expect(div.className).toEqual('moo meu moo');
});
it('should normalize spaces and tabs', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'meu');
domHelper.appendClassName(div, ' foo ');
expect(div.className).toEqual('meu foo');
});
});
describe('#removeClassName', function () {
it('should remove class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'meu moo');
expect(div.className).toEqual('meu moo');
domHelper.removeClassName(div, 'meu');
expect(div.className).toEqual('moo');
});
it('should not remove non-existing classes', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
expect(div.className).toEqual('moo');
domHelper.removeClassName(div, 'boo');
expect(div.className).toEqual('moo');
});
});
describe('#updateClassName', function () {
it('should handle optional arguments correctly', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
domHelper.updateClassName(div);
expect(div.className).toEqual('moo');
domHelper.updateClassName(div, [], []);
expect(div.className).toEqual('moo');
domHelper.updateClassName(div, null, null);
expect(div.className).toEqual('moo');
});
it('should have added a class name', function () {
var div = domHelper.createElement('div');
domHelper.updateClassName(div, ['moo']);
expect(div.className).toEqual('moo');
});
it('should not add duplicate class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
domHelper.updateClassName(div, ['moo']);
expect(div.className).toEqual('moo');
});
it('should add multiple class names', function () {
var div = domHelper.createElement('div');
domHelper.updateClassName(div, ['moo', 'meu', 'moo']);
expect(div.className).toEqual('moo meu');
});
it('should normalize spaces and tabs', function () {
var div = domHelper.createElement('div');
domHelper.updateClassName(div, ['meu', ' foo']);
expect(div.className).toEqual('meu foo');
});
it('should remove class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'meu moo');
expect(div.className).toEqual('meu moo');
domHelper.updateClassName(div, null, ['meu']);
expect(div.className).toEqual('moo');
});
it('should remove multiple class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'meu');
domHelper.appendClassName(div, 'moo');
expect(div.className).toEqual('meu moo');
domHelper.updateClassName(div, null, ['meu', 'moo']);
expect(div.className).toEqual('');
});
it('should not remove non-existing classes', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
expect(div.className).toEqual('moo');
domHelper.updateClassName(div, null, 'boo');
expect(div.className).toEqual('moo');
});
it('should add and remove class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
domHelper.appendClassName(div, 'meh');
expect(div.className).toEqual('moo meh');
domHelper.updateClassName(div, ['meu'], ['moo', 'meh']);
expect(div.className).toEqual('meu');
});
it('should update one of many class names', function () {
var div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo');
domHelper.appendClassName(div, 'meh');
expect(div.className).toEqual('moo meh');
domHelper.updateClassName(div, ['meu'], ['moo']);
expect(div.className).toEqual('meh meu');
});
});
describe('#hasClassName', function () {
var div = null;
beforeEach(function () {
div = domHelper.createElement('div');
domHelper.appendClassName(div, 'moo moo-meu');
});
it('should return true', function () {
expect(domHelper.hasClassName(div, 'moo')).toBe(true);
expect(domHelper.hasClassName(div, 'moo-meu')).toBe(true);
});
it('should return false', function () {
expect(domHelper.hasClassName(div, 'boo')).toBe(false);
expect(domHelper.hasClassName(div, 'meu')).toBe(false);
});
});
describe('#setStyle', function () {
var div = null;
beforeEach(function () {
div = domHelper.createElement('div');
});
it('should set the style correctly', function () {
domHelper.setStyle(div, 'left:3px;top:1px;');
expect(div.style.left).toEqual('3px');
expect(div.style.top).toEqual('1px');
});
});
describe('#createStyle', function () {
var style = null;
beforeEach(function () {
style = domHelper.createStyle('blockquote{font-size:300px}');
domHelper.insertInto('head', style);
});
afterEach(function () {
domHelper.removeElement(style);
});
it('should create a style element', function () {
expect(style).not.toBeNull();
expect(style.nodeName).toEqual('STYLE');
});
it('should set the css content correctly', function () {
var text = style.styleSheet ? style.styleSheet.cssText : style.textContent;
expect(text.replace(/[\s;]/g, '').toLowerCase()).toEqual('blockquote{font-size:300px}');
});
});
describe('#loadStylesheet', function () {
it('should load the stylesheet', function () {
var el = null,
width = null,
link = null;
runs(function () {
el = domHelper.createElement('div', { id: 'TEST_ELEMENT' });
domHelper.insertInto('body', el);
width = el.offsetWidth;
link = domHelper.loadStylesheet('fixtures/external_stylesheet.css');
});
waitsFor(function () {
return width !== el.offsetWidth;
});
runs(function () {
expect(link).not.toBeNull();
expect(link.rel).toEqual('stylesheet');
expect(el.offsetWidth).toEqual(300);
});
});
});
describe('#loadStylesheet with callback', function () {
it('should load the stylesheet', function () {
var el = null,
width = null,
callbackMade = false;
function callback() {
callbackMade = true;
}
runs(function () {
el = domHelper.createElement('div', { id: 'TEST_ELEMENT' });
domHelper.insertInto('body', el);
width = el.offsetWidth;
domHelper.loadStylesheet('fixtures/external_stylesheet.css', callback);
});
waitsFor(function () {
return callbackMade;
});
runs(function () {
expect(el.offsetWidth).toEqual(300);
});
});
});
describe('#loadStylesheet with async and callback', function () {
it('should load the stylesheet', function () {
var el = null,
width = null,
callbackMade = false;
function callback() {
callbackMade = true;
}
runs(function () {
el = domHelper.createElement('div', { id: 'TEST_ELEMENT' });
domHelper.insertInto('body', el);
width = el.offsetWidth;
domHelper.loadStylesheet('fixtures/external_stylesheet.css', callback, true);
});
waitsFor(function () {
return callbackMade;
});
runs(function () {
expect(el.offsetWidth).toEqual(300);
});
});
});
describe('#loadScript', function () {
it('should load the script', function () {
runs(function () {
domHelper.loadScript('fixtures/external_script.js');
});
waitsFor(function () {
return window.EXTERNAL_SCRIPT_LOADED;
}, 'script was never inserted', 1000);
runs(function () {
expect(window.EXTERNAL_SCRIPT_LOADED).toBe(true);
});
});
it('should call the callback', function () {
var called = false,
error = null;
runs(function () {
domHelper.loadScript('fixtures/external_script.js', function (err) {
called = true;
error = err;
});
});
waitsFor(function () {
return called;
}, 'callback was never called', 1000);
runs(function () {
expect(called).toBe(true);
expect(error).toBeFalsy();
});
});
it('should return a script element', function () {
var script = domHelper.loadScript('fixtures/external_script.js');
expect(script).not.toBeNull();
expect(script.nodeName).toEqual('SCRIPT');
});
it('should timeout if the script does not load or is very slow', function () {
var called = false,
error = false;
// Spy on createElement so the all loadScript code is executed but
// the "script" won't actually load.
spyOn(domHelper, 'createElement').andCallFake(function (name) {
return document.createElement('div');
});
runs(function () {
domHelper.loadScript('fixtures/external_script.js', function (err) {
called = true;
error = err;
}, 100);
});
waitsFor(function () {
return called;
});
runs(function () {
expect(called).toBe(true);
expect(error).toBeTruthy();
});
});
});
describe('#getHostname', function () {
it('should return the hostname', function () {
var domHelper = new DomHelper({
location: {
hostname: 'example.com'
}
});
expect(domHelper.getHostName()).toEqual('example.com');
});
it('should return the hostname from the iframe if present', function () {
var domHelper = new DomHelper({
location: {
hostname: 'example.com'
}
}, {
location: {
hostname: 'example.org'
}
});
expect(domHelper.getHostName()).toEqual('example.org');
});
});
describe('#insertInto', function () {
it('should insert an element', function () {
var a = domHelper.createElement('div');
var result = domHelper.insertInto('body', a);
expect(result).toBe(true);
expect(a.parentNode.nodeName).toEqual('BODY');
});
});
describe('#whenBodyExists', function () {
var domHelper = null,
callback = null;
beforeEach(function () {
domHelper = new DomHelper({
document: {
addEventListener: function (event, callback) {
function check() {
if (domHelper.document_.body) {
callback();
} else {
setTimeout(check, 10);
}
}
check();
}
}
});
callback = jasmine.createSpy('callback');
});
it('should wait until the body exists before calling the callback', function () {
runs(function () {
domHelper.whenBodyExists(callback);
});
waits(200);
runs(function () {
domHelper.document_.body = true;
});
waitsFor(function () {
return callback.wasCalled;
}, 'callback was never called', 100);
runs(function () {
expect(callback).toHaveBeenCalled();
});
});
it('should not call the callback if the body is not available', function () {
runs(function () {
domHelper.whenBodyExists(callback);
});
waits(100);
runs(function () {
expect(callback).not.toHaveBeenCalled();
});
});
});
describe('#removeElement', function () {
it('should remove an element', function () {
var a = domHelper.createElement('div'),
b = domHelper.createElement('div');
a.appendChild(b);
var result = domHelper.removeElement(b);
expect(result).toBe(true);
expect(b.parentNode).not.toEqual(a);
});
it('should return false when failing to remove an element', function () {
var a = domHelper.createElement('div');
var result = domHelper.removeElement(a);
expect(result).toBe(false);
});
});
describe('#getMainWindow', function () {
it('should return the main window', function () {
var domHelper = new DomHelper(1, 2);
expect(domHelper.getMainWindow()).toEqual(1);
});
});
describe('#getLoadWindow', function () {
it('should return the load window', function () {
var domHelper = new DomHelper(1, 2);
expect(domHelper.getLoadWindow()).toEqual(2);
});
});
});
================================================
FILE: spec/core/eventdispatcher_spec.js
================================================
describe('EventDispatcher', function () {
var EventDispatcher = webfont.EventDispatcher,
DomHelper = webfont.DomHelper,
Font = webfont.Font,
domHelper = new DomHelper(window),
element = null
eventDispatcher = null,
font = null;
beforeEach(function () {
element = domHelper.getLoadWindow().document.documentElement;
config = {
loading: jasmine.createSpy('loading'),
active: jasmine.createSpy('active'),
inactive: jasmine.createSpy('inactive'),
fontloading: jasmine.createSpy('fontloading'),
fontactive: jasmine.createSpy('fontactive'),
fontinactive: jasmine.createSpy('fontinactive'),
classes: true,
events: true
};
element.className = '';
eventDispatcher = new EventDispatcher(domHelper, config);
font = new Font('My Family', 'n4');
});
describe('#dispatchLoading', function () {
beforeEach(function () {
eventDispatcher.dispatchLoading();
});
it('should call the correct callback', function () {
expect(config.loading).toHaveBeenCalled();
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-loading');
});
});
describe('#dispatchFontLoading', function () {
beforeEach(function () {
eventDispatcher.dispatchFontLoading(font);
});
it('should call the correct callback', function () {
expect(config.fontloading).toHaveBeenCalledWith('My Family', 'n4');
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-myfamily-n4-loading');
});
});
describe('#dispatchFontInactive', function () {
beforeEach(function () {
eventDispatcher.dispatchFontInactive(font);
});
it('should call the correct callback', function () {
expect(config.fontinactive).toHaveBeenCalledWith('My Family', 'n4');
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-myfamily-n4-inactive');
});
});
describe('#dispatchFontInactive - with loading class', function () {
beforeEach(function () {
eventDispatcher.dispatchFontLoading(font);
eventDispatcher.dispatchFontInactive(font);
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-myfamily-n4-inactive');
});
});
describe('#dispatchFontInactive - with active class', function () {
beforeEach(function () {
eventDispatcher.dispatchFontActive(font);
eventDispatcher.dispatchFontInactive(font);
});
it('should not append the inactive class name', function () {
expect(element.className).toEqual('wf-myfamily-n4-active');
});
it('should still call the correct callback', function () {
expect(config.fontinactive).toHaveBeenCalledWith('My Family', 'n4');
});
});
describe('#dispatchFontActive', function () {
beforeEach(function () {
eventDispatcher.dispatchFontActive(font);
});
it('should call the correct callback', function () {
expect(config.fontactive).toHaveBeenCalledWith('My Family', 'n4');
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-myfamily-n4-active');
});
});
describe('#dispatchFontActive - with loading class', function () {
beforeEach(function () {
eventDispatcher.dispatchFontLoading(font);
eventDispatcher.dispatchFontActive(font);
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-myfamily-n4-active');
});
});
describe('#dispatchFontActive - with inactive class', function () {
beforeEach(function () {
eventDispatcher.dispatchFontInactive(font);
eventDispatcher.dispatchFontActive(font);
});
it('should set the correct class', function () {
expect(element.className).toEqual('wf-myfamily-n4-active');
});
});
describe('#dispatchInactive', function () {
beforeEach(function () {
eventDispatcher.dispatchInactive();
});
it('should call the correct callback', function () {
expect(config.inactive).toHaveBeenCalled();
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-inactive');
});
});
describe('#dispatchInactive - with loading class', function () {
beforeEach(function () {
eventDispatcher.dispatchLoading();
eventDispatcher.dispatchInactive();
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-inactive');
});
});
describe('#dispatchInactive - with active class', function () {
beforeEach(function () {
eventDispatcher.dispatchActive();
eventDispatcher.dispatchInactive();
});
it('should not set the the inactive class', function () {
expect(element.className).toEqual('wf-active');
});
it('should still call the inactive callback', function () {
expect(config.inactive).toHaveBeenCalled();
});
});
describe('#dispatchActive', function () {
beforeEach(function () {
eventDispatcher.dispatchActive();
});
it('should call the correct callback', function () {
expect(config.active).toHaveBeenCalled();
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-active');
});
});
describe('#dispatchActive - with loading class', function () {
beforeEach(function () {
eventDispatcher.dispatchLoading();
eventDispatcher.dispatchActive();
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-active');
});
});
describe('#dispatchActive - with inactive class', function () {
beforeEach(function () {
eventDispatcher.dispatchInactive();
eventDispatcher.dispatchActive();
});
it('should set the correct class name', function () {
expect(element.className).toEqual('wf-active');
});
});
describe('disable classes and events', function () {
beforeEach(function () {
config.classes = false;
config.events = false;
eventDispatcher = new EventDispatcher(domHelper, config);
eventDispatcher.dispatchInactive();
eventDispatcher.dispatchActive();
eventDispatcher.dispatchLoading();
eventDispatcher.dispatchFontInactive(font);
eventDispatcher.dispatchFontActive(font);
eventDispatcher.dispatchFontLoading(font);
});
afterEach(function () {
config.classes = true;
config.events = true;
});
it('should not fire any events', function () {
expect(config.inactive).not.toHaveBeenCalled();
expect(config.active).not.toHaveBeenCalled();
expect(config.loading).not.toHaveBeenCalled();
expect(config.fontinactive).not.toHaveBeenCalled();
expect(config.fontactive).not.toHaveBeenCalled();
expect(config.fontloading).not.toHaveBeenCalled();
});
});
describe('disable classes', function () {
beforeEach(function () {
config.classes = false;
eventDispatcher = new EventDispatcher(domHelper, config);
eventDispatcher.dispatchInactive();
eventDispatcher.dispatchActive();
eventDispatcher.dispatchLoading();
eventDispatcher.dispatchFontInactive(font);
eventDispatcher.dispatchFontActive(font);
eventDispatcher.dispatchFontLoading(font);
});
afterEach(function () {
config.classes = true;
});
it('should not fire any events', function () {
expect(element.className).toEqual('');
});
});
});
================================================
FILE: spec/core/font_spec.js
================================================
describe('Font', function () {
var Font = webfont.Font;
describe('#quote', function () {
var quote = function (font) {
return new Font(font).getCssName();
};
it('should quote names with spaces', function () {
expect(quote('My Family')).toEqual("'My Family'");
});
it('should quote names with spaces and double quotes', function () {
expect(quote('"My Family"')).toEqual("'My Family'");
});
it('should quote names with spaces and single quotes', function () {
expect(quote("'My Family'")).toEqual("'My Family'");
});
it('should quote multiple single quoted names separated with a comma', function () {
expect(quote("'family 1','family 2'")).toEqual("'family 1','family 2'");
});
it('should quote multiple single quoted names separated with a comma and space', function () {
expect(quote("'family 1', 'family 2'")).toEqual("'family 1','family 2'");
});
it('should quote family names starting with a number', function () {
expect(quote('5test')).toEqual("'5test'");
});
it('should not quote when there is no space', function () {
expect(quote('MyFamily')).toEqual('MyFamily');
});
it('should remove quotes when they are unnecesssary', function () {
expect(quote('"MyFamily"')).toEqual('MyFamily');
});
it('should not quote multiple names when there is no space', function () {
expect(quote("'family-1', 'family-2'")).toEqual('family-1,family-2');
});
});
describe('#toCssString', function () {
function toCssString(fvd) {
return new Font('My Family', fvd).toCssString();
}
it('should expand font styles correctly', function () {
expect(toCssString('n4')).toEqual("normal 400 300px 'My Family'");
expect(toCssString('i4')).toEqual("italic 400 300px 'My Family'");
expect(toCssString('o4')).toEqual("oblique 400 300px 'My Family'");
});
it('should expand weights correctly', function () {
for (var i = 1; i < 10; i += 1) {
expect(toCssString('n' + i)).toEqual("normal " + (i * 100) + " 300px 'My Family'");
}
});
});
describe('#getCssVariation', function () {
function toCss(fvd) {
return new Font('My Family', fvd).getCssVariation();
}
it('should expand font-style', function () {
expect(toCss('n4')).toEqual('font-style:normal;font-weight:400;');
expect(toCss('i4')).toEqual('font-style:italic;font-weight:400;');
expect(toCss('o4')).toEqual('font-style:oblique;font-weight:400;');
});
it('should expand weights correctly', function () {
for (var i = 1; i < 10; i += 1) {
expect(toCss('n' + i)).toEqual('font-style:normal;font-weight:' + (i * 100) + ';');
}
});
it('should not expand incorrect input', function () {
expect(toCss('')).toEqual('font-style:normal;font-weight:400;');
expect(toCss('n')).toEqual('font-style:normal;font-weight:400;');
expect(toCss('1')).toEqual('font-style:normal;font-weight:400;');
expect(toCss('n1x')).toEqual('font-style:normal;font-weight:400;');
});
});
describe('parseCssVariation', function () {
function toFvd(css) {
return Font.parseCssVariation(css);
}
it('should default to n4 when there is no description', function () {
expect(toFvd('')).toEqual('n4');
expect(toFvd(null)).toEqual('n4');
expect(toFvd(undefined)).toEqual('n4');
});
it('should compact font style', function () {
expect(toFvd('font-style: normal;')).toEqual('n4');
expect(toFvd('font-style: italic;')).toEqual('i4');
expect(toFvd('font-style: oblique;')).toEqual('o4');
});
it('should return the default value when font-style is incorrect', function () {
expect(toFvd('font-style: other;')).toEqual('n4');
});
it('should compact font weight', function () {
expect(toFvd('font-weight: normal;')).toEqual('n4');
expect(toFvd('font-weight: bold;')).toEqual('n7');
for (var i = 1; i < 10; i += 1) {
expect(toFvd('font-weight: ' + (i * 100) + ';')).toEqual('n' + i);
}
});
it('should return the default value when font-weight is incorrect', function () {
expect(toFvd('font-weight: 140;')).toEqual('n4');
expect(toFvd('font-weight: other;')).toEqual('n4');
});
it('should compact multiple properties', function () {
expect(toFvd('font-weight: bold; font-style: italic;')).toEqual('i7');
expect(toFvd('; font-weight: bold; font-style: italic;')).toEqual('i7');
expect(toFvd('font-style:italic;font-weight:bold;')).toEqual('i7');
expect(toFvd(' font-style: italic ;\n\nfont-weight: bold; ')).toEqual('i7');
});
it('should return default values for incorrect individual properties', function () {
expect(toFvd('src: url(/font.otf)')).toEqual('n4');
expect(toFvd('font-weight: 900; src: url(/font.otf);')).toEqual('n9');
expect(toFvd('font-weight: 800; font-stretch:condensed;')).toEqual('n8');
});
});
});
================================================
FILE: spec/core/fontmoduleloader_spec.js
================================================
describe('FontModuleLoader', function () {
var FontModuleLoader = webfont.FontModuleLoader;
describe('#getModules', function () {
var fontModuleLoader = null;
beforeEach(function () {
fontModuleLoader = new FontModuleLoader();
});
it('should return an empty array without modules', function () {
var modules = fontModuleLoader.getModules();
expect(modules).not.toBeNull();
expect(modules.length).toEqual(0);
});
it('should have modules', function () {
fontModuleLoader.addModuleFactory('booh', function () {
return {
scary: true
};
});
fontModuleLoader.addModuleFactory('haha', function () {
return {
funny: true
};
});
fontModuleLoader.addModuleFactory('moo', function () {
return {
cowy: true
};
});
var modules = fontModuleLoader.getModules({
booh: {},
moo: {},
nothing: {}
});
expect(modules).not.toBeNull();
expect(modules.length).toEqual(2);
var module = modules[0];
expect(module).not.toBeNull();
expect(module.scary || module.cowy).toBe(true);
var module = modules[1];
expect(module).not.toBeNull();
expect(module.scary || module.cowy).toBe(true);
});
});
});
================================================
FILE: spec/core/fontruler_spec.js
================================================
describe('FontRuler', function () {
var Font = webfont.Font,
FontRuler = webfont.FontRuler,
DomHelper = webfont.DomHelper,
Size = webfont.Size,
domHelper = null,
font = null;
beforeEach(function () {
font = new Font('sans-serif');
domHelper = new DomHelper(window);
});
it('should prevent a long test string from word wrapping', function () {
var fontRulerA = new FontRuler(domHelper, 'abc'),
fontRulerB = new FontRuler(domHelper, 'abc HelloWorld,thisshouldwrap!!!!');
fontRulerA.insert();
fontRulerB.insert();
fontRulerA.setFont(font);
fontRulerB.setFont(font);
var widthA = fontRulerA.getWidth(),
widthB = fontRulerB.getWidth();
expect(widthA).not.toEqual(widthB);
});
});
================================================
FILE: spec/core/fontwatcher_spec.js
================================================
describe('FontWatcher', function () {
var FontWatcher = webfont.FontWatcher,
FontWatchRunner = webfont.FontWatchRunner,
NativeFontWatchRunner = webfont.NativeFontWatchRunner,
Font = webfont.Font,
DomHelper = webfont.DomHelper,
Version = webfont.Version,
domHelper = new DomHelper(window),
eventDispatcher = {},
testStrings = null,
timeout = null,
font1 = null,
font2 = null,
font3 = null,
font4 = null,
activeFonts = [];
beforeEach(function () {
font1 = new Font('font1');
font2 = new Font('font2');
font3 = new Font('font3');
font4 = new Font('font4');
activeFonts = [];
testStrings = jasmine.createSpy('testStrings');
timeout = jasmine.createSpy('timeout');
eventDispatcher.dispatchLoading = jasmine.createSpy('dispatchLoading');
eventDispatcher.dispatchFontLoading = jasmine.createSpy('dispatchFontLoading');
eventDispatcher.dispatchFontActive = jasmine.createSpy('dispatchFontActive');
eventDispatcher.dispatchFontInactive = jasmine.createSpy('dispatchFontInactive');
eventDispatcher.dispatchActive = jasmine.createSpy('dispatchActive');
eventDispatcher.dispatchInactive = jasmine.createSpy('dispatchInactive');
var fakeStart = function (font, fontTestString) {
var found = false;
testStrings(this.fontTestString_);
timeout(this.timeout_);
for (var i = 0; i < activeFonts.length; i += 1) {
if (activeFonts[i].getName() === this.font_.getName()) {
found = true;
break;
}
}
if (found) {
this.activeCallback_(this.font_);
} else {
this.inactiveCallback_(this.font_);
}
};
spyOn(FontWatchRunner.prototype, 'start').andCallFake(fakeStart);
spyOn(NativeFontWatchRunner.prototype, 'start').andCallFake(fakeStart);
});
if (!!window.FontFace) {
describe('use native font loading API', function () {
beforeEach(function () {
FontWatcher.SHOULD_USE_NATIVE_LOADER = null;
});
it('works on Chrome', function () {
spyOn(FontWatcher, 'getUserAgent').andReturn('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36');
expect(FontWatcher.shouldUseNativeLoader()).toEqual(true);
});
it('is disabled on Firefox <= 42', function () {
spyOn(FontWatcher, 'getUserAgent').andReturn('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:42.0) Gecko/20100101 Firefox/42.0')
expect(FontWatcher.shouldUseNativeLoader()).toEqual(false);
});
it('is enabled on Firefox > 43', function () {
spyOn(FontWatcher, 'getUserAgent').andReturn('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:43.0) Gecko/20100101 Firefox/43.0');
expect(FontWatcher.shouldUseNativeLoader()).toEqual(true);
});
it('is disabled on Safari > 10', function () {
spyOn(FontWatcher, 'getUserAgent').andReturn('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14');
spyOn(FontWatcher, 'getVendor').andReturn('Apple');
expect(FontWatcher.shouldUseNativeLoader()).toEqual(false);
});
});
}
describe('watch zero fonts', function () {
it('should call inactive when there are no fonts to load', function () {
activeFonts = [];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([], {}, null, true);
expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
});
it('should not call inactive when there are no fonts to load, but this is not the last set', function () {
activeFonts = [];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([], {}, null, false);
expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
});
});
describe('watch one font not last', function () {
it('should not call font inactive, inactive or active', function () {
activeFonts = [font1];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1], {}, null, false);
expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchActive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
});
});
describe('watch one font active', function () {
it('should call font active and active', function () {
activeFonts = [font1];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1], {}, null, true);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
});
});
describe('watch one font inactive', function () {
it('should call inactive', function () {
activeFonts = [];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1], {}, null, true);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchFontActive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchActive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
});
});
describe('watch multiple fonts active', function () {
it('should call font active and active', function () {
activeFonts = [font1, font2, font3];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1, font2, font3], {}, null, true);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchFontInactive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
});
});
describe('watch multiple fonts inactive', function () {
it('should call inactive', function () {
activeFonts = [];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1, font2, font3], {}, null, true);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchFontActive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith(font1);
expect(eventDispatcher.dispatchActive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchInactive).toHaveBeenCalled();
});
});
describe('watch multiple fonts mixed', function () {
it('should call the correct callbacks', function () {
activeFonts = [font1, font3];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1, font2, font3], {}, null, true);
expect(eventDispatcher.dispatchFontLoading.callCount).toEqual(3);
expect(eventDispatcher.dispatchFontLoading.calls[0].args[0]).toEqual(font1);
expect(eventDispatcher.dispatchFontLoading.calls[1].args[0]).toEqual(font2);
expect(eventDispatcher.dispatchFontLoading.calls[2].args[0]).toEqual(font3);
expect(eventDispatcher.dispatchFontActive.callCount).toEqual(2);
expect(eventDispatcher.dispatchFontActive.calls[0].args[0]).toEqual(font1);
expect(eventDispatcher.dispatchFontActive.calls[1].args[0]).toEqual(font3);
expect(eventDispatcher.dispatchFontInactive.callCount).toEqual(1);
expect(eventDispatcher.dispatchFontInactive.calls[0].args[0]).toEqual(font2);
expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
});
});
describe('watch multiple fonts with descriptions', function () {
it('should call the correct callbacks', function () {
var font5 = new Font('font4', 'i7'),
font6 = new Font('font5'),
font7 = new Font('font6'),
font8 = new Font('font7', 'i4'),
font9 = new Font('font8', 'n7');
activeFonts = [font5, font6];
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font5, font6, font7, font8, font9], {}, null, true);
expect(eventDispatcher.dispatchFontLoading.callCount).toEqual(5);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font5);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font6);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font7);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font8);
expect(eventDispatcher.dispatchFontLoading).toHaveBeenCalledWith(font9);
expect(eventDispatcher.dispatchFontActive.callCount).toEqual(2);
expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith(font5);
expect(eventDispatcher.dispatchFontActive).toHaveBeenCalledWith(font6);
expect(eventDispatcher.dispatchFontInactive.callCount).toEqual(3);
expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith(font7);
expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith(font8);
expect(eventDispatcher.dispatchFontInactive).toHaveBeenCalledWith(font9);
expect(eventDispatcher.dispatchInactive).not.toHaveBeenCalled();
expect(eventDispatcher.dispatchActive).toHaveBeenCalled();
});
});
describe('watch multiple fonts with test strings', function () {
it('should use the correct tests strings', function () {
activeFonts = [font1, font2];
var defaultTestString = FontWatcher.SHOULD_USE_NATIVE_LOADER ? undefined : FontWatchRunner.DEFAULT_TEST_STRING;
var fontWatcher = new FontWatcher(domHelper, eventDispatcher);
fontWatcher.watchFonts([font1, font2, font3, font4], {
'font1': 'testString1',
'font2': null,
'font3': 'testString2',
'font4': null
}, null, true);
expect(testStrings.callCount).toEqual(4);
expect(testStrings.calls[0].args[0]).toEqual('testString1');
expect(testStrings.calls[1].args[0]).toEqual(defaultTestString);
expect(testStrings.calls[2].args[0]).toEqual('testString2');
expect(testStrings.calls[3].args[0]).toEqual(defaultTestString);
});
});
it('should pass on the timeout to FontWatchRunner', function () {
var fontWatcher = new FontWatcher(domHelper, eventDispatcher, 4000);
fontWatcher.watchFonts([font1], {}, null, true);
expect(timeout).toHaveBeenCalledWith(4000);
});
});
================================================
FILE: spec/core/fontwatchrunner_spec.js
================================================
describe('FontWatchRunner', function () {
var FontWatchRunner = webfont.FontWatchRunner,
Font = webfont.Font,
BrowserInfo = webfont.BrowserInfo,
DomHelper = webfont.DomHelper,
FontRuler = webfont.FontRuler;
var domHelper = null,
activeCallback = null,
inactiveCallback = null,
nullFont = null,
sourceSansA = null,
sourceSansB = null,
elena = null;
beforeEach(function () {
domHelper = new DomHelper(window);
activeCallback = jasmine.createSpy('activeCallback');
inactiveCallback = jasmine.createSpy('inactiveCallback');
nullFont = new Font('__webfontloader_test__');
sourceSansA = new Font('SourceSansA');
sourceSansB = new Font('SourceSansB');
elena = new Font('Elena');
});
it('should fail to load a null font', function () {
var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
domHelper, nullFont, 500, {});
runs(function () {
fontWatchRunner.start();
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(inactiveCallback).toHaveBeenCalledWith(nullFont);
});
});
it('should load font succesfully', function () {
var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
domHelper, sourceSansA, 5000),
ruler = new FontRuler(domHelper, 'abcdef'),
monospace = new Font('monospace'),
sourceSansAFallback = new Font("'SourceSansA', monospace"),
activeWidth = null,
originalWidth = null,
finalCheck = false;
runs(function () {
ruler.insert();
ruler.setFont(monospace);
originalWidth = ruler.getWidth();
ruler.setFont(sourceSansAFallback);
fontWatchRunner.start();
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(activeCallback).toHaveBeenCalledWith(sourceSansA);
activeWidth = ruler.getWidth();
expect(activeWidth).not.toEqual(originalWidth);
window.setTimeout(function () {
finalCheck = true;
}, 200);
});
waitsFor(function () {
return finalCheck;
});
runs(function () {
expect(ruler.getWidth()).not.toEqual(originalWidth);
expect(ruler.getWidth()).toEqual(activeWidth);
});
});
it('should attempt to load a non-existing font', function () {
var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
domHelper, elena, 500, {});
runs(function () {
fontWatchRunner.start();
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(inactiveCallback).toHaveBeenCalledWith(elena);
});
});
it('should load even if @font-face is inserted after watching has started', function () {
var fontWatchRunner = new FontWatchRunner(activeCallback, inactiveCallback,
domHelper, sourceSansB, 5000),
ruler = new FontRuler(domHelper, 'abcdef'),
monospace = new Font('monospace'),
sourceSansBFallback = new Font("'SourceSansB', monospace"),
activeWidth = null,
originalWidth = null,
finalCheck = false;
runs(function () {
ruler.insert();
ruler.setFont(monospace);
originalWidth = ruler.getWidth();
ruler.setFont(sourceSansBFallback);
fontWatchRunner.start();
var link = document.createElement('link');
link.rel = "stylesheet";
link.href= "fixtures/fonts/sourcesansb.css";
domHelper.insertInto('head', link);
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(activeCallback).toHaveBeenCalledWith(sourceSansB);
activeWidth = ruler.getWidth();
expect(activeWidth).not.toEqual(originalWidth);
window.setTimeout(function () {
finalCheck = true;
}, 200);
});
waitsFor(function () {
return finalCheck;
});
runs(function () {
expect(ruler.getWidth()).not.toEqual(originalWidth);
expect(ruler.getWidth()).toEqual(activeWidth);
});
});
});
================================================
FILE: spec/core/nativefontwatchrunner_spec.js
================================================
describe('NativeFontWatchRunner', function () {
var NativeFontWatchRunner = webfont.NativeFontWatchRunner,
Font = webfont.Font,
DomHelper = webfont.DomHelper,
FontRuler = webfont.FontRuler;
var domHelper = null,
activeCallback = null,
inactiveCallback = null,
nullFont = null,
sourceSansC = null,
sourceSansDup = null,
elena = null;
beforeEach(function () {
domHelper = new DomHelper(window);
activeCallback = jasmine.createSpy('activeCallback');
inactiveCallback = jasmine.createSpy('inactiveCallback');
nullFont = new Font('__webfontloader_test_3__');
sourceSansC = new Font('SourceSansC');
sourceSansDup = new Font('SourceSansDup');
elena = new Font('Elena');
});
if (window['FontFace']) {
it('should fail to load a null font', function () {
var fontWatchRunner = new NativeFontWatchRunner(activeCallback, inactiveCallback,
domHelper, nullFont, 500);
runs(function () {
fontWatchRunner.start();
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(inactiveCallback).toHaveBeenCalledWith(nullFont);
});
});
function succesfulLoadingSpec(getFontToBeLoaded, getFontNameToBeLoaded) {
var fontToBeLoaded = getFontToBeLoaded(),
fontNameToBeLoaded = getFontNameToBeLoaded(),
fontWatchRunner = new NativeFontWatchRunner(activeCallback, inactiveCallback,
domHelper, fontToBeLoaded),
ruler = new FontRuler(domHelper, 'abcdef'),
monospace = new Font('monospace'),
fallbackFont = new Font(fontNameToBeLoaded + ', monospace'),
activeWidth = null,
originalWidth = null,
finalCheck = false;
runs(function () {
ruler.insert();
ruler.setFont(monospace);
originalWidth = ruler.getWidth();
ruler.setFont(fallbackFont);
fontWatchRunner.start();
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(activeCallback).toHaveBeenCalledWith(fontToBeLoaded);
activeWidth = ruler.getWidth();
expect(activeWidth).not.toEqual(originalWidth);
window.setTimeout(function () {
finalCheck = true;
}, 200);
});
waitsFor(function () {
return finalCheck;
});
runs(function () {
expect(ruler.getWidth()).not.toEqual(originalWidth);
expect(ruler.getWidth()).toEqual(activeWidth);
});
}
it('should load font succesfully',
succesfulLoadingSpec.bind(null, function() { return sourceSansC; }, function() { return 'SourceSansC'; }));
it('should load font succesfully even if it is duplicated',
succesfulLoadingSpec.bind(null, function() { return sourceSansDup; }, function() { return 'SourceSansDup'; }));
it('should attempt to load a non-existing font', function () {
var fontWatchRunner = new NativeFontWatchRunner(activeCallback, inactiveCallback,
domHelper, elena, 500);
runs(function () {
fontWatchRunner.start();
});
waitsFor(function () {
return activeCallback.wasCalled || inactiveCallback.wasCalled;
});
runs(function () {
expect(inactiveCallback).toHaveBeenCalledWith(elena);
});
});
}
});
================================================
FILE: spec/core/size_spec.js
================================================
describe('Size', function () {
var Size = webfont.Size;
it('should return true on identical sizes', function () {
expect(new Size(10, 10).equals(new Size(10, 10))).toBe(true);
});
it('should return false when two sizes are different', function () {
expect(new Size(10, 10).equals(new Size(20, 20))).toBe(false);
expect(new Size(10, 10).equals(new Size(10, 20))).toBe(false);
});
it('should return false when one font is undefined or null', function () {
expect(new Size(10, 10).equals(undefined)).toBe(false);
expect(new Size(10, 10).equals(null)).toBe(false);
});
});
================================================
FILE: spec/core/webfont_spec.js
================================================
describe('WebFont', function () {
var WebFont = webfont.WebFont,
Font = webfont.Font;
FontWatchRunner = webfont.FontWatchRunner,
NativeFontWatchRunner = webfont.NativeFontWatchRunner,
Version = webfont.Version,
Font = webfont.Font,
FontModuleLoader = webfont.FontModuleLoader,
fontModuleLoader = null;
beforeEach(function () {
fontModuleLoader = new FontModuleLoader();
});
describe('font load with context', function () {
var font = null,
testModule = null,
fakeMainWindow = {
document: {}
};
beforeEach(function () {
font = new WebFont(fakeMainWindow);
font.addModule('test', function (conf, domHelper) {
testModule = new function () {
this.domHelper = domHelper;
};
testModule.load = function (onReady) {
onReady([]);
};
return testModule;
});
});
it('should load with the correct context', function () {
font.load({
test: {
somedata: 'in french a cow says meuh'
},
context: window
});
expect(testModule.domHelper).not.toBeNull();
expect(testModule.domHelper).not.toBeUndefined();
expect(testModule.domHelper.getMainWindow()).toEqual(fakeMainWindow);
expect(testModule.domHelper.getLoadWindow()).toEqual(window);
});
});
describe('module failed to provide families and descriptions because it did not initialize properly', function () {
var webfont = null,
testModule = null,
font = null,
inactive = jasmine.createSpy('inactive'),
active = jasmine.createSpy('active');
beforeEach(function () {
font = new Font('Font1');
jasmine.Clock.useMock();
webfont = new WebFont(window);
webfont.addModule('test', function (conf, domHelper) {
testModule = new function () {
this.conf = conf;
};
spyOn(FontWatchRunner.prototype, 'start').andCallFake(function () {
if (conf.id) {
active(font);
} else {
inactive(font);
}
});
spyOn(NativeFontWatchRunner.prototype, 'start').andCallFake(function () {
if (conf.id) {
active(font);
} else {
inactive(font);
}
});
testModule.load = function (onReady) {
if (conf.id) {
onReady([font]);
} else {
onReady([]);
}
};
return testModule;
});
});
it('should load with a project id', function () {
webfont.load({
test: {
id: 'hello world'
},
inactive: inactive,
active: active
});
jasmine.Clock.tick(1);
expect(testModule).not.toBeNull();
expect(active).toHaveBeenCalled();
});
it('should not load without a project id', function () {
webfont.load({
test: {
},
inactive: inactive,
active: active
});
jasmine.Clock.tick(1);
expect(testModule).not.toBeNull();
expect(inactive).toHaveBeenCalled();
});
});
describe('should pass both fonts and test strings to onready', function () {
var font = null,
fontTestStrings = null,
testModule = null;
beforeEach(function () {
font = new WebFont(window);
font.addModule('test', function (conf, domHelper) {
testModule = new function () {};
testModule.load = function (onReady) {
onReady([new Font('Elena')], { 'Elena': '1234567' });
};
return testModule;
});
spyOn(font, 'onModuleReady_');
});
it('should have called onModuleReady with the correct font and test string', function () {
font.load({
'test': {}
});
expect(font.onModuleReady_).toHaveBeenCalled();
expect(font.onModuleReady_.calls[0].args[2]).toEqual([new Font('Elena')]);
expect(font.onModuleReady_.calls[0].args[3]).toEqual({ 'Elena': '1234567' });
});
});
describe('module fails to load', function () {
var font = null,
testModule = null,
inactive = null,
active = null;
beforeEach(function () {
inactive = jasmine.createSpy('inactive'),
active = jasmine.createSpy('active');
font = new WebFont(window, fontModuleLoader);
font.addModule('test', function (conf, domHelper) {
testModule = new function () {};
testModule.load = function (onReady) {
onReady([]);
};
return testModule;
});
});
it('times out and calls inactive', function () {
runs(function () {
font.load({
'test': {},
inactive: inactive,
active: active
});
});
waitsFor(function () {
return active.wasCalled || inactive.wasCalled;
});
runs(function () {
expect(inactive).toHaveBeenCalled();
expect(active).not.toHaveBeenCalled();
});
});
});
describe('synchronous load event', function () {
var font = null,
testModule = null,
inactive = null,
loading = null,
active = null;
beforeEach(function () {
inactive = jasmine.createSpy('inactive'),
active = jasmine.createSpy('active');
loading = jasmine.createSpy('loading');
font = new WebFont(window, fontModuleLoader);
font.addModule('test', function (conf, domHelper) {
testModule = new function () {};
testModule.load = function (onReady) {
onReady([new Font('Elena')]);
};
return testModule;
});
});
it('fires loading event correctly', function () {
runs(function () {
font.load({
'test': {},
inactive: inactive,
active: active,
loading: loading
});
expect(loading).toHaveBeenCalled();
});
waitsFor(function () {
return active.wasCalled || inactive.wasCalled;
});
runs(function () {
expect(inactive).toHaveBeenCalled();
expect(active).not.toHaveBeenCalled();
});
});
});
});
================================================
FILE: spec/deps.js
================================================
// This file was autogenerated by calcdeps.js
goog.addDependency("../../src/closure.js", [], []);
goog.addDependency("../../src/core/cssclassname.js", ["webfont.CssClassName"], []);
goog.addDependency("../../src/core/domhelper.js", ["webfont.DomHelper"], []);
goog.addDependency("../../src/core/stylesheetwaiter.js", ["webfont.StyleSheetWaiter"], []);
goog.addDependency("../../src/core/eventdispatcher.js", ["webfont.EventDispatcher"], ["webfont.CssClassName"]);
goog.addDependency("../../src/core/font.js", ["webfont.Font"], []);
goog.addDependency("../../src/core/fontmodule.js", ["webfont.FontModule"], []);
goog.addDependency("../../src/core/fontmoduleloader.js", ["webfont.FontModuleLoader","webfont.FontModuleFactory"], []);
goog.addDependency("../../src/core/fontruler.js", ["webfont.FontRuler"], []);
goog.addDependency("../../src/core/fontwatcher.js", ["webfont.FontWatcher"], ["webfont.FontWatchRunner","webfont.NativeFontWatchRunner"]);
goog.addDependency("../../src/core/fontwatchrunner.js", ["webfont.FontWatchRunner"], ["webfont.Font","webfont.FontRuler"]);
goog.addDependency("../../src/core/initialize.js", ["webfont"], ["webfont.WebFont","webfont.modules.Typekit","webfont.modules.Fontdeck","webfont.modules.Monotype","webfont.modules.Custom","webfont.modules.google.GoogleFontApi"]);
goog.addDependency("../../src/core/nativefontwatchrunner.js", ["webfont.NativeFontWatchRunner"], ["webfont.Font"]);
goog.addDependency("../../src/core/webfont.js", ["webfont.WebFont"], ["webfont.DomHelper","webfont.EventDispatcher","webfont.FontWatcher","webfont.FontModuleLoader"]);
goog.addDependency("../../src/modules/custom.js", ["webfont.modules.Custom"], ["webfont.Font", "webfont.StyleSheetWaiter"]);
goog.addDependency("../../src/modules/fontdeck.js", ["webfont.modules.Fontdeck"], ["webfont.Font"]);
goog.addDependency("../../src/modules/google/fontapiparser.js", ["webfont.modules.google.FontApiParser"], ["webfont.Font"]);
goog.addDependency("../../src/modules/google/fontapiurlbuilder.js", ["webfont.modules.google.FontApiUrlBuilder"], []);
goog.addDependency("../../src/modules/google/googlefontapi.js", ["webfont.modules.google.GoogleFontApi"], ["webfont.modules.google.FontApiUrlBuilder","webfont.modules.google.FontApiParser","webfont.FontWatchRunner", "webfont.StyleSheetWaiter"]);
goog.addDependency("../../src/modules/monotype.js", ["webfont.modules.Monotype"], ["webfont.Font"]);
goog.addDependency("../../src/modules/typekit.js", ["webfont.modules.Typekit"], ["webfont.Font"]);
================================================
FILE: spec/fixtures/external_script.js
================================================
window.EXTERNAL_SCRIPT_LOADED = true;
================================================
FILE: spec/fixtures/external_stylesheet.css
================================================
#TEST_ELEMENT {
display: block;
position: absolute;
top: 0;
left: 0;
width: 300px;
}
================================================
FILE: spec/fixtures/fonts/LICENSE.txt
================================================
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
================================================
FILE: spec/fixtures/fonts/nullfont.css
================================================
@font-face{font-family:__webfontloader_test__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:font/truetype;base64,) format('truetype');}
================================================
FILE: spec/fixtures/fonts/nullfont1.css
================================================
@font-face{font-family:__webfontloader_test_1__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:font/truetype;base64,) format('truetype');}
================================================
FILE: spec/fixtures/fonts/nullfont2.css
================================================
@font-face{font-family:__webfontloader_test_2__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:font/truetype;base64,) format('truetype');}
================================================
FILE: spec/fixtures/fonts/nullfont3.css
================================================
@font-face{font-family:__webfontloader_test_3__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:font/truetype;base64,) format('truetype');}
================================================
FILE: spec/fixtures/fonts/sourcesansa.css
================================================
@font-face{font-family:SourceSansA;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) format('woff'),url(sourcesans.otf) format('opentype'),url(sourcesans.ttf) format('truetype'),url(sourcesans.svg#source_sans_proregular) format('svg');}
================================================
FILE: spec/fixtures/fonts/sourcesansb.css
================================================
@font-face{font-family:SourceSansB;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) format('woff'),url(sourcesans.otf) format('opentype'),url(sourcesans.ttf) format('truetype'),url(sourcesans.svg#source_sans_proregular) format('svg');}
================================================
FILE: spec/fixtures/fonts/sourcesansc.css
================================================
@font-face{font-family:SourceSansC;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) format('woff'),url(sourcesans.otf) format('opentype'),url(sourcesans.ttf) format('truetype'),url(sourcesans.svg#source_sans_proregular) format('svg');}
================================================
FILE: spec/fixtures/fonts/sourcesansd.css
================================================
@font-face{font-family:SourceSansD;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) format('woff'),url(sourcesans.otf) format('opentype'),url(sourcesans.ttf) format('truetype'),url(sourcesans.svg#source_sans_proregular) format('svg');}
================================================
FILE: spec/fixtures/fonts/sourcesansdup1.css
================================================
@font-face{font-family:SourceSansDup;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) format('woff'),url(sourcesans.otf) format('opentype'),url(sourcesans.ttf) format('truetype'),url(sourcesans.svg#source_sans_proregular) format('svg');}
================================================
FILE: spec/fixtures/fonts/sourcesansdup2.css
================================================
@font-face{font-family:SourceSansDup;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) format('woff'),url(sourcesans.otf) format('opentype'),url(sourcesans.ttf) format('truetype'),url(sourcesans.svg#source_sans_proregular) format('svg');}
================================================
FILE: spec/index.html
================================================
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Webfontloader tests</title>
<link rel="stylesheet" href="../tools/jasmine/jasmine.css">
<link rel="stylesheet" href="fixtures/fonts/nullfont.css">
<link rel="stylesheet" href="fixtures/fonts/nullfont1.css">
<link rel="stylesheet" href="fixtures/fonts/nullfont2.css">
<link rel="stylesheet" href="fixtures/fonts/nullfont3.css">
<link rel="stylesheet" href="fixtures/fonts/sourcesansa.css">
<link rel="stylesheet" href="fixtures/fonts/sourcesansc.css">
<link rel="stylesheet" href="fixtures/fonts/sourcesansdup1.css">
<link rel="stylesheet" href="fixtures/fonts/sourcesansdup2.css">
</head>
<body>
<script>
CLOSURE_NO_DEPS = true;
</script>
<script src="../tools/jasmine/jasmine.js"></script>
<script src="../tools/jasmine/jasmine-html.js"></script>
<script src="../tools/jasmine-phantomjs/terminal-reporter.js"></script>
<script src="../tools/jasmine-browserstack/jasmine-browserstack.js"></script>
<script src="../tools/compiler/base.js"></script>
<script src="../spec/deps.js"></script>
<script>
goog.require('webfont');
</script>
<script src="../spec/core/domhelper_spec.js"></script>
<script src="../spec/core/cssclassname_spec.js"></script>
<script src="../spec/core/fontmoduleloader_spec.js"></script>
<script src="../spec/core/eventdispatcher_spec.js"></script>
<script src="../spec/core/font_spec.js"></script>
<script src="../spec/core/fontruler_spec.js"></script>
<script src="../spec/core/fontwatchrunner_spec.js"></script>
<script src="../spec/core/nativefontwatchrunner_spec.js"></script>
<script src="../spec/core/fontwatcher_spec.js"></script>
<script src="../spec/core/webfont_spec.js"></script>
<script src="../spec/modules/google/fontapiparser_spec.js"></script>
<script src="../spec/modules/google/fontapiurlbuilder_spec.js"></script>
<script src="../spec/modules/google/googlefontapi_spec.js"></script>
<script src="../spec/modules/custom_spec.js"></script>
<script src="../spec/modules/fontdeck_spec.js"></script>
<script src="../spec/modules/monotype_spec.js"></script>
<script src="../spec/modules/typekit_spec.js"></script>
<script>
(function () {
var env = jasmine.getEnv();
env.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter(),
terminalReporter = new jasmine.TerminalReporter({
verbosity: 3,
color: true
}),
browserStackReporter = new jasmine.BrowserStackReporter();
if (/PhantomJS/.test(navigator.userAgent)) {
env.addReporter(terminalReporter);
}
env.addReporter(htmlReporter);
env.addReporter(browserStackReporter);
env.specFilter = function (spec) {
return htmlReporter.specFilter(spec);
};
var currentOnload = window.onload;
window.onload = function () {
if (currentOnload) {
currentOnload();
}
env.execute();
};
}());
</script>
</body>
</html>
================================================
FILE: spec/modules/custom_spec.js
================================================
describe('modules.Custom', function () {
var Custom = webfont.modules.Custom,
FontFamily = webfont.FontFamily,
Any = jasmine.Matchers.Any;
describe('insert links correctly', function () {
var fakeDomHelper = null,
load = null;
function notifySheetsLoaded() {
var argsForCall = fakeDomHelper.loadStylesheet.argsForCall;
for (var i = 0; i < argsForCall.length; i++) {
var args = argsForCall[i];
args[1]();
}
}
beforeEach(function () {
fakeDomHelper = {
loadStylesheet: jasmine.createSpy('createCssLink')
};
load = jasmine.createSpy('load');
var defaultModule = new Custom(fakeDomHelper, {
families: ['Font1', 'Font2', 'Font3'],
urls: ['https://moo', 'https://meuh'],
testStrings: {
Font3: 'hello world'
}
});
defaultModule.load(load);
});
it('should have inserted the links correctly', function () {
expect(fakeDomHelper.loadStylesheet.callCount).toEqual(2);
expect(fakeDomHelper.loadStylesheet).toHaveBeenCalledWith('https://moo', new Any(Function));
expect(fakeDomHelper.loadStylesheet).toHaveBeenCalledWith('https://meuh', new Any(Function));
});
if (webfont.DomHelper.CAN_WAIT_STYLESHEET) {
it('should not invoke callback before all CSS are loaded', function () {
expect(load.callCount).toEqual(0);
notifySheetsLoaded();
expect(load.callCount).toEqual(1);
});
}
it('should have loaded the families correctly', function () {
notifySheetsLoaded();
expect(load.callCount).toEqual(1);
expect(load.calls[0].args[0].length).toEqual(3);
expect(load.calls[0].args[0][0].getName()).toEqual('Font1');
expect(load.calls[0].args[0][1].getName()).toEqual('Font2');
expect(load.calls[0].args[0][2].getName()).toEqual('Font3');
});
it('should have set a custom test string', function () {
notifySheetsLoaded();
expect(load.callCount).toEqual(1);
expect(load.calls[0].args[1]).toEqual({ Font3: 'hello world' });
});
});
});
================================================
FILE: spec/modules/fontdeck_spec.js
================================================
describe('modules.Fontdeck', function () {
var Fontdeck = webfont.modules.Fontdeck,
Font = webfont.Font;
var configuration = {
id: '2282'
};
var apiResponse = {
"domain" : "localhost",
"cssurl" : "https://f.fontdeck.com/s/css/03BmCXiV2AHwX/Rp+OBFTfD2oFs/localhost/2282.css",
"project" : 2282,
"cssbase" : "https://f.fontdeck.com/s/css/03BmCXiV2AHwX/Rp+OBFTfD2oFs",
"fonts" : [
{
"font_family" : "'Fertigo Pro Regular', Fertigo, Constantia, Palatino, serif",
"font_size_adjust" : 0.508,
"name" : "Fertigo Pro Regular",
"style" : "normal",
"weight" : "normal",
"font_urls" : {
"eot" : "https://f.fontdeck.com/f/1/SUlFR0tid0kAA2vb11Ly/IGWDK+wV8TMAfV0J1Ej1J1GFRT1bssqrn6a.eot",
"ttf" : "https://f.fontdeck.com/f/1/SUlFR0tid0kAA2vb11Ly/IGWDK+wV8TMAfV0J1Ej1J1GFRT1bssqrn6a.ttf",
"woff" : "https://f.fontdeck.com/f/1/SUlFR0tid0kAA2vb11Ly/IGWDK+wV8TMAfV0J1Ej1J1GFRT1bssqrn6a.woff",
"svg" : "https://f.fontdeck.com/f/1/SUlFR0tid0kAA2vb11Ly/IGWDK+wV8TMAfV0J1Ej1J1GFRT1bssqrn6a.svg#104"
},
"id" : 104
},
{
"font_family" : "'Bodoni Display Bold Italic', Georgia, 'Times New Roman', Times, serif",
"font_size_adjust" : 0.45,
"name" : "Bodoni Display Bold Italic",
"style" : "italic",
"weight" : "bold",
"font_urls" : {
"eot" : "https://f.fontdeck.com/f/1/azJEbTVyc1QAA11+CAE5C93+l/bAQx1ipRo6Maba19w3Yy5ng+qVWlfj.eot",
"ttf" : "https://f.fontdeck.com/f/1/azJEbTVyc1QAA11+CAE5C93+l/bAQx1ipRo6Maba19w3Yy5ng+qVWlfj.ttf",
"woff" : "https://f.fontdeck.com/f/1/azJEbTVyc1QAA11+CAE5C93+l/bAQx1ipRo6Maba19w3Yy5ng+qVWlfj.woff",
"svg" : "https://f.fontdeck.com/f/1/azJEbTVyc1QAA11+CAE5C93+l/bAQx1ipRo6Maba19w3Yy5ng+qVWlfj.svg#2256"
},
"id" : 2256
}
]
};
var fakeDomHelper = null,
global = null;
beforeEach(function () {
global = {
location: {}
};
fakeDomHelper = {
loadScript: jasmine.createSpy('loadScript'),
getLoadWindow: jasmine.createSpy('getLoadWindow').andReturn(global),
getHostName: function () { return 'test-host-name'; }
};
});
describe('support and load life cycle', function () {
var fontdeck = null,
onReady = jasmine.createSpy('onReady');
beforeEach(function () {
fontdeck = new Fontdeck(fakeDomHelper, configuration);
fontdeck.load(onReady);
});
it('should create the script correctly', function () {
expect(fakeDomHelper.loadScript).toHaveBeenCalled();
expect(fakeDomHelper.loadScript.calls[0].args[0]).toEqual('https://f.fontdeck.com/s/css/js/test-host-name/2282.js');
});
it('should have created a global', function () {
expect(global.__webfontfontdeckmodule__).not.toBeNull();
expect(global.__webfontfontdeckmodule__['2282']).not.toBeNull();
});
it('should load correctly after calling the callback', function () {
global.__webfontfontdeckmodule__['2282'](true, apiResponse);
expect(fontdeck.fonts_).toEqual([new Font(apiResponse.fonts[0].name), new Font(apiResponse.fonts[1].name, 'i7')]);
});
});
describe('no project id', function () {
var fontdeck = null,
support = null;
beforeEach(function () {
fontdeck = new Fontdeck(fakeDomHelper, { id: null });
});
it('should not have loaded any fonts', function () {
expect(fontdeck.fonts_).toEqual([]);
});
});
});
================================================
FILE: spec/modules/google/fontapiparser_spec.js
================================================
describe('modules.google.FontApiParser', function () {
var FontApiParser = webfont.modules.google.FontApiParser,
Font = webfont.Font;
describe('parsed values are coherent', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Tangerine', 'Droid Serif:bi', 'Yanone Kaffeesatz:200,300,400,700', 'Cantarell:italic,b', 'Exo:100italic', 'Lobster:200n']);
parser.parse();
});
it('should parse fonts correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(10);
expect(fonts).toEqual([
new Font('Tangerine', 'n4'),
new Font('Droid Serif', 'i7'),
new Font('Yanone Kaffeesatz', 'n2'),
new Font('Yanone Kaffeesatz', 'n3'),
new Font('Yanone Kaffeesatz', 'n4'),
new Font('Yanone Kaffeesatz', 'n7'),
new Font('Cantarell', 'i4'),
new Font('Cantarell', 'n7'),
new Font('Exo', 'i1'),
new Font('Lobster', 'n2')
]);
});
});
describe('mix of numeric weight and style', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Nobile:700i,b,200i,r,i700']);
parser.parse();
});
it('should parse fonts correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(4);
expect(fonts).toEqual([
new Font('Nobile', 'i7'),
new Font('Nobile', 'n7'),
new Font('Nobile', 'i2'),
new Font('Nobile', 'n4')
]);
});
});
describe('typo bild instead of bold', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Nobile:bild']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Nobile', 'n4'));
});
});
describe('variations with dashes', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Nobile:semi-bold']);
parser.parse();
});
it('should parse the variation correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Nobile', 'n6'));
});
});
describe('nonsense', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Nobile:dwe,^%^%fewf,$9940@#!@#$%^&*()_+}POIBJ{}{']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Nobile', 'n4'));
});
});
describe('no weight and one subset defined', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Cantarell::greek']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Cantarell', 'n4'));
});
it('should parse pick test strings correctly', function () {
var testStrings = parser.getFontTestStrings(),
cantarell = testStrings['Cantarell'];
expect(cantarell).not.toBeNull();
expect(cantarell).toEqual(FontApiParser.INT_FONTS['greek']);
});
});
describe('no weight and multiple subsets defined', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Cantarell::cyrillic,greek,latin']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Cantarell', 'n4'));
});
it('should parse pick test strings correctly', function () {
var testStrings = parser.getFontTestStrings(),
cantarell = testStrings['Cantarell'];
expect(cantarell).not.toBeNull();
expect(cantarell).toEqual(FontApiParser.INT_FONTS['cyrillic']);
});
});
describe('weight and multiple subsets defined', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Cantarell:regular,bold:cyrillic,greek,latin']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(2);
expect(fonts).toEqual([
new Font('Cantarell', 'n4'),
new Font('Cantarell', 'n7')
]);
});
it('should parse pick test strings correctly', function () {
var testStrings = parser.getFontTestStrings(),
cantarell = testStrings['Cantarell'];
expect(cantarell).not.toBeNull();
expect(cantarell).toEqual(FontApiParser.INT_FONTS['cyrillic']);
});
});
describe('Hanuman is backward compatible', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Hanuman']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Hanuman', 'n4'));
});
it('should parse pick test strings correctly', function () {
var testStrings = parser.getFontTestStrings(),
hanuman = testStrings['Hanuman'];
expect(hanuman).not.toBeNull();
expect(hanuman).toEqual(FontApiParser.INT_FONTS['Hanuman']);
});
});
describe('Hanuman is forward compatible', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Hanuman::khmer']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(1);
expect(fonts[0]).toEqual(new Font('Hanuman', 'n4'));
});
it('should parse pick test strings correctly', function () {
var testStrings = parser.getFontTestStrings(),
hanuman = testStrings['Hanuman'];
expect(hanuman).not.toBeNull();
expect(hanuman).toEqual(FontApiParser.INT_FONTS['khmer']);
});
});
describe('plus replaced with space', function () {
var parser = null;
beforeEach(function () {
parser = new FontApiParser(['Erica+One', 'Droid+Serif::latin', 'Yanone+Kaffeesatz:400,700:latin']);
parser.parse();
});
it('should parse families correctly', function () {
var fonts = parser.getFonts();
expect(fonts.length).toEqual(4);
expect(fonts).toEqual([
new Font('Erica One', 'n4'),
new Font('Droid Serif', 'n4'),
new Font('Yanone Kaffeesatz', 'n4'),
new Font('Yanone Kaffeesatz', 'n7')
]);
});
});
});
================================================
FILE: spec/modules/google/fontapiurlbuilder_spec.js
================================================
describe('modules.google.FontApiUrlBuilder', function () {
var FontApiUrlBuilder = webfont.modules.google.FontApiUrlBuilder;
it('should throw an exception if there are no font families', function () {
var builder = new FontApiUrlBuilder('https://moo');
expect(builder.build).toThrow();
});
it('should build a proper url', function () {
var builder = new FontApiUrlBuilder('https://moo');
builder.setFontFamilies(['Font1', 'Font2']);
expect(builder.build()).toEqual('https://moo?family=Font1%7CFont2');
});
it('should build a proper url', function () {
var builder = new FontApiUrlBuilder(undefined);
builder.setFontFamilies(['Font1', 'Font2']);
expect(builder.build()).toEqual(
FontApiUrlBuilder.DEFAULT_API_URL +
'?family=Font1%7CFont2');
});
it('should build a proper url', function () {
var builder = new FontApiUrlBuilder(undefined);
builder.setFontFamilies(['Font1:bold:greek,cyrillic', 'Font2:italic', 'Font3']);
expect(builder.build()).toEqual(
FontApiUrlBuilder.DEFAULT_API_URL +
'?family=Font1:bold%7CFont2:italic%7CFont3' +
'&subset=greek,cyrillic');
});
it('should build a proper url', function () {
var builder = new FontApiUrlBuilder(undefined);
builder.setFontFamilies(['Font1:bold,italic:greek,cyrillic', 'Font2:italic', 'Font3::latin']);
expect(builder.build()).toEqual(
FontApiUrlBuilder.DEFAULT_API_URL +
'?family=Font1:bold,italic%7CFont2:italic%7CFont3' +
'&subset=greek,cyrillic,latin');
});
});
================================================
FILE: spec/modules/google/googlefontapi_spec.js
================================================
describe('modules.google.GoogleFontApi', function () {
var GoogleFontApi = webfont.modules.google.GoogleFontApi,
Any = jasmine.Matchers.Any,
Font = webfont.Font,
link = '',
insert = '',
onload = null,
fakeDomHelper = {
whenBodyExists: function (callback) {
callback();
},
loadStylesheet: function (cssLink, cb) {
link = cssLink;
onload = cb;
}
};
beforeEach(function () {
insert = '';
link = '';
onload = null;
});
function notifySheetsLoaded() {
if (onload)
onload();
};
describe('call onReady with font family loading', function () {
var googleFontApi = null,
fonts = null;
beforeEach(function () {
googleFontApi = new GoogleFontApi(fakeDomHelper, { families: ['Font1', 'Font2'] });
googleFontApi.load(function (f) {
fonts = f;
});
});
it('has inserted the link element correctly', function () {
expect(link).toEqual('https://fonts.googleapis.com/css?family=Font1%7CFont2');
});
it('has the correct families', function () {
notifySheetsLoaded();
expect(fonts).not.toBeNull();
expect(fonts.length).toEqual(2);
expect(fonts[0]).toEqual(new Font('Font1'));
expect(fonts[1]).toEqual(new Font('Font2'));
});
});
describe('call onReady with font family loading and custom API url', function () {
var googleFontApi = null;
var loaded = false;
beforeEach(function () {
loaded = false;
googleFontApi = new GoogleFontApi(fakeDomHelper, {
api: 'https://moo',
families: ['Font1', 'Font2']
});
googleFontApi.load(function () { loaded = true; });
});
it('has inserted the link element correctly', function () {
expect(link).toEqual('https://moo?family=Font1%7CFont2');
});
if (webfont.DomHelper.CAN_WAIT_STYLESHEET) {
it('does not call onReady until sheets are loaded', function () {
expect(onload).toMatch(new Any(Function));
expect(loaded).toBe(false);
notifySheetsLoaded();
expect(loaded).toBe(true);
});
}
});
describe('spaces replaced by plus', function () {
var googleFontApi = null;
beforeEach(function () {
googleFontApi = new GoogleFontApi(fakeDomHelper, { families: ['Font1 WithSpace', 'Font2 WithSpaceToo'] });
googleFontApi.load(function () {});
});
it('has inserted the link element correctly', function () {
expect(link).toEqual('https://fonts.googleapis.com/css?family=Font1+WithSpace%7CFont2+WithSpaceToo');
});
});
describe('load with variations', function () {
var googleFontApi = null;
beforeEach(function () {
googleFontApi = new GoogleFontApi(fakeDomHelper, { families: ['Font1 WithSpace:bi', 'Font2 WithSpaceToo:b,r'] });
googleFontApi.load(function () {});
});
it('has inserted the link element correctly', function () {
expect(link).toEqual('https://fonts.googleapis.com/css?family=Font1+WithSpace:bi%7CFont2+WithSpaceToo:b,r');
});
});
});
================================================
FILE: spec/modules/monotype_spec.js
================================================
describe('modules.Monotype', function () {
var Monotype = webfont.modules.Monotype,
Font = webfont.Font,
BrowserInfo = webfont.BrowserInfo,
UserAgent = webfont.UserAgent,
Version = webfont.Version;
var configuration = {
projectId: '01e2ff27-25bf-4801-a23e-73d328e6c7cc',
api: 'https://fast.fonts.net/jsapidev'
};
var fakeDomHelper = null,
global = null,
script = {},
monotype = null,
load = null,
support = null;
beforeEach(function () {
global = {};
fakeDomHelper = {
loadScript: jasmine.createSpy('loadScript').andCallFake(function (src, callback) {
script.onload = callback;
return script;
}),
getLoadWindow: jasmine.createSpy('getLoadWindow').andReturn(global)
};
support = jasmine.createSpy('support');
load = jasmine.createSpy('load');
monotype = new Monotype(fakeDomHelper, configuration);
monotype.load(load);
global[Monotype.HOOK + configuration.projectId] = function () {
return [{fontfamily: 'aachen bold'}, {fontfamily: 'kid print regular'}];
};
script.onload();
});
it('should create a script element', function () {
expect(fakeDomHelper.loadScript).toHaveBeenCalled();
expect(fakeDomHelper.loadScript.calls[0].args[0]).toEqual('https://fast.fonts.net/jsapidev/01e2ff27-25bf-4801-a23e-
gitextract_e9i9r2bx/ ├── .gitignore ├── .travis.yml ├── CHANGELOG ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin/ │ └── webfontloader-demos ├── bower.json ├── browsers.json ├── externs.js ├── lib/ │ ├── webfontloader/ │ │ ├── demo/ │ │ │ ├── public/ │ │ │ │ ├── basic.css │ │ │ │ ├── blank.html │ │ │ │ ├── custom-iframe.html │ │ │ │ ├── custom.html │ │ │ │ ├── event-css-active-multiple.html │ │ │ │ ├── event-css-active.html │ │ │ │ ├── event-css-inactive.html │ │ │ │ ├── event-css-loading.html │ │ │ │ ├── event-js-active.html │ │ │ │ ├── event-js-font-active.html │ │ │ │ ├── event-js-loading.html │ │ │ │ ├── events-variations.html │ │ │ │ ├── events.html │ │ │ │ ├── fontdeck.html │ │ │ │ ├── fontwatchrunner-default-fonts.html │ │ │ │ ├── google-css.html │ │ │ │ ├── google-iframe.html │ │ │ │ ├── google.html │ │ │ │ ├── ie-fast-js.html │ │ │ │ ├── ie-slow-js.html │ │ │ │ ├── ie-slow-link.html │ │ │ │ ├── index.html │ │ │ │ ├── monotype-iframe.html │ │ │ │ ├── monotype.html │ │ │ │ ├── typekit-iframe.html │ │ │ │ ├── typekit-variations.html │ │ │ │ └── typekit.html │ │ │ └── server.rb │ │ └── modules.rb │ └── webfontloader.rb ├── package.json ├── spec/ │ ├── core/ │ │ ├── cssclassname_spec.js │ │ ├── domhelper_spec.js │ │ ├── eventdispatcher_spec.js │ │ ├── font_spec.js │ │ ├── fontmoduleloader_spec.js │ │ ├── fontruler_spec.js │ │ ├── fontwatcher_spec.js │ │ ├── fontwatchrunner_spec.js │ │ ├── nativefontwatchrunner_spec.js │ │ ├── size_spec.js │ │ └── webfont_spec.js │ ├── deps.js │ ├── fixtures/ │ │ ├── external_script.js │ │ ├── external_stylesheet.css │ │ └── fonts/ │ │ ├── LICENSE.txt │ │ ├── nullfont.css │ │ ├── nullfont1.css │ │ ├── nullfont2.css │ │ ├── nullfont3.css │ │ ├── sourcesans.otf │ │ ├── sourcesansa.css │ │ ├── sourcesansb.css │ │ ├── sourcesansc.css │ │ ├── sourcesansd.css │ │ ├── sourcesansdup1.css │ │ └── sourcesansdup2.css │ ├── index.html │ └── modules/ │ ├── custom_spec.js │ ├── fontdeck_spec.js │ ├── google/ │ │ ├── fontapiparser_spec.js │ │ ├── fontapiurlbuilder_spec.js │ │ └── googlefontapi_spec.js │ ├── monotype_spec.js │ └── typekit_spec.js ├── src/ │ ├── closure.js │ ├── core/ │ │ ├── cssclassname.js │ │ ├── domhelper.js │ │ ├── eventdispatcher.js │ │ ├── font.js │ │ ├── fontmodule.js │ │ ├── fontmoduleloader.js │ │ ├── fontruler.js │ │ ├── fontwatcher.js │ │ ├── fontwatchrunner.js │ │ ├── initialize.js │ │ ├── nativefontwatchrunner.js │ │ ├── stylesheetwaiter.js │ │ └── webfont.js │ ├── modules/ │ │ ├── custom.js │ │ ├── fontdeck.js │ │ ├── google/ │ │ │ ├── fontapiparser.js │ │ │ ├── fontapiurlbuilder.js │ │ │ └── googlefontapi.js │ │ ├── monotype.js │ │ └── typekit.js │ └── modules.yml ├── tools/ │ ├── compiler/ │ │ ├── base.js │ │ └── compiler.jar │ ├── jasmine/ │ │ ├── MIT.LICENSE │ │ ├── jasmine-html.js │ │ ├── jasmine.css │ │ └── jasmine.js │ ├── jasmine-browserstack/ │ │ └── jasmine-browserstack.js │ └── jasmine-phantomjs/ │ ├── jasmine-phantomjs.js │ └── terminal-reporter.js ├── webfontloader.gemspec └── webfontloader.js
SYMBOL INDEX (96 symbols across 15 files)
FILE: lib/webfontloader.rb
type WebFontLoader (line 5) | module WebFontLoader
FILE: lib/webfontloader/demo/server.rb
type WebFontLoader (line 4) | module WebFontLoader
type Demo (line 5) | module Demo
class Server (line 6) | class Server < Sinatra::Base
method get_js_code (line 89) | def get_js_code
FILE: lib/webfontloader/modules.rb
type WebFontLoader (line 1) | module WebFontLoader
class Modules (line 2) | class Modules
method initialize (line 4) | def initialize(*modules)
method all_source_files (line 17) | def all_source_files
method all_test_globs (line 23) | def all_test_globs
method js_output_wrapper (line 30) | def js_output_wrapper(source, version)
method config (line 36) | def config
FILE: spec/core/domhelper_spec.js
function callback (line 289) | function callback() {
function callback (line 316) | function callback() {
function check (line 453) | function check() {
FILE: spec/core/font_spec.js
function toCssString (line 47) | function toCssString(fvd) {
function toCss (line 65) | function toCss(fvd) {
function toFvd (line 90) | function toFvd(css) {
FILE: spec/core/nativefontwatchrunner_spec.js
function succesfulLoadingSpec (line 45) | function succesfulLoadingSpec(getFontToBeLoaded, getFontNameToBeLoaded) {
FILE: spec/modules/custom_spec.js
function notifySheetsLoaded (line 10) | function notifySheetsLoaded() {
FILE: spec/modules/google/googlefontapi_spec.js
function notifySheetsLoaded (line 25) | function notifySheetsLoaded() {
FILE: src/core/domhelper.js
function mayInvokeCallback (line 286) | function mayInvokeCallback() {
function onStylesheetAvailable (line 312) | function onStylesheetAvailable(callback) {
function onMediaAvailable (line 324) | function onMediaAvailable(callback) {
FILE: src/modules/monotype.js
function checkAndLoadIfDownloaded (line 65) | function checkAndLoadIfDownloaded() {
FILE: tools/compiler/base.js
function visitNode (line 1272) | function visitNode(path) {
function tempCtor (line 2227) | function tempCtor() {}
FILE: tools/jasmine-browserstack/jasmine-browserstack.js
function stack (line 8) | function stack(err) {
function BrowserStackReporter (line 25) | function BrowserStackReporter() {
FILE: tools/jasmine/jasmine-html.js
function focusedSpecName (line 126) | function focusedSpecName() {
function createReporterDom (line 148) | function createReporterDom(version) {
function noTryCatch (line 165) | function noTryCatch() {
function searchWithCatch (line 169) | function searchWithCatch() {
function setExceptionHandling (line 188) | function setExceptionHandling() {
function showDetails (line 363) | function showDetails() {
function isUndefined (line 369) | function isUndefined(obj) {
function isDefined (line 373) | function isDefined(obj) {
function specPluralizedFor (line 377) | function specPluralizedFor(count) {
FILE: tools/jasmine/jasmine.js
function getGlobal (line 55) | function getGlobal() {
function tryIt (line 621) | function tryIt(f) {
FILE: webfontloader.js
function aa (line 1) | function aa(a,b,c){return a.call.apply(a.bind,arguments)}
function ba (line 1) | function ba(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Arra...
function p (line 1) | function p(a,b,c){p=Function.prototype.bind&&-1!=Function.prototype.bind...
function ca (line 1) | function ca(a,b){this.a=a;this.o=b||a;this.c=this.o.document}
function t (line 1) | function t(a,b,c,d){b=a.c.createElement(b);if(c)for(var e in c)c.hasOwnP...
function u (line 1) | function u(a,b,c){a=a.c.getElementsByTagName(b)[0];a||(a=document.docume...
function v (line 1) | function v(a){a.parentNode&&a.parentNode.removeChild(a)}
function w (line 2) | function w(a,b,c){b=b||[];c=c||[];for(var d=a.className.split(/\s+/),e=0...
function y (line 2) | function y(a,b){for(var c=a.className.split(/\s+/),d=0,e=c.length;d<e;d+...
function ea (line 3) | function ea(a){return a.o.location.hostname||a.a.location.hostname}
function z (line 3) | function z(a,b,c){function d(){m&&e&&f&&(m(g),m=null)}b=t(a,"link",{rel:...
function A (line 4) | function A(a,b,c,d){var e=a.c.getElementsByTagName("head")[0];if(e){var ...
function B (line 4) | function B(){this.a=0;this.c=null}
function C (line 4) | function C(a){a.a++;return function(){a.a--;D(a)}}
function E (line 4) | function E(a,b){a.c=b;D(a)}
function D (line 4) | function D(a){0==a.a&&a.c&&(a.c(),a.c=null)}
function F (line 4) | function F(a){this.a=a||"-"}
function G (line 4) | function G(a,b){this.c=a;this.f=4;this.a="n";var c=(b||"n4").match(/^([n...
function fa (line 4) | function fa(a){return H(a)+" "+(a.f+"00")+" 300px "+I(a.c)}
function I (line 4) | function I(a){var b=[];a=a.split(/,\s*/);for(var c=0;c<a.length;c++){var...
function J (line 4) | function J(a){return a.a+a.f}
function H (line 4) | function H(a){var b="normal";"o"===a.a?b="oblique":"i"===a.a&&(b="italic...
function ga (line 5) | function ga(a){var b=4,c="n",d=null;a&&((d=a.match(/(normal|oblique|ital...
function ha (line 5) | function ha(a,b){this.c=a;this.f=a.o.document.documentElement;this.h=b;t...
function ia (line 5) | function ia(a){a.g&&w(a.f,[a.a.c("wf","loading")]);K(a,"loading")}
function L (line 5) | function L(a){if(a.g){var b=y(a.f,a.a.c("wf","active")),c=[],d=[a.a.c("w...
function K (line 5) | 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 (line 5) | function ja(){this.c={}}
function ka (line 5) | function ka(a,b,c){var d=[],e;for(e in b)if(b.hasOwnProperty(e)){var f=a...
function M (line 5) | function M(a,b){this.c=a;this.f=b;this.a=t(this.c,"span",{"aria-hidden":...
function N (line 5) | function N(a){u(a.c,"body",a.a)}
function O (line 5) | function O(a){return"display:block;position:absolute;top:-9999px;left:-9...
function P (line 5) | function P(a,b,c,d,e,f){this.g=a;this.j=b;this.a=d;this.c=c;this.f=e||3E...
function f (line 5) | function f(){q()-c>=b.f?e():a.fonts.load(fa(b.a),b.h).then(function(a){1...
function Q (line 5) | function Q(a,b,c,d,e,f,g){this.v=a;this.B=b;this.c=c;this.a=d;this.s=g||...
function T (line 6) | function T(){if(null===S){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.ex...
function la (line 7) | function la(a,b,c){for(var d in R)if(R.hasOwnProperty(d)&&b===a.f[R[d]]&...
function U (line 7) | function U(a){var b=a.g.a.offsetWidth,c=a.h.a.offsetWidth,d;(d=b===a.f.s...
function ma (line 7) | function ma(a){setTimeout(p(function(){U(this)},a),50)}
function V (line 7) | function V(a,b){setTimeout(p(function(){v(this.g.a);v(this.h.a);v(this.j...
function W (line 7) | function W(a,b,c){this.c=a;this.a=b;this.f=0;this.m=this.j=!1;this.s=c}
function na (line 8) | function na(a){0==--a.f&&a.j&&(a.m?(a=a.a,a.g&&w(a.f,[a.a.c("wf","active...
function oa (line 8) | function oa(a){this.j=a;this.a=new ja;this.h=0;this.f=this.g=!0}
function qa (line 9) | function qa(a,b,c,d,e){var f=0==--a.h;(a.f||a.g)&&setTimeout(function(){...
function pa (line 10) | function pa(a,b,c){var d=[],e=c.timeout;ia(b);var d=ka(a.a,c,a.c),f=new ...
function ra (line 10) | function ra(a,b){this.c=a;this.a=b}
function b (line 11) | function b(){if(f["__mti_fntLst"+d]){var c=f["__mti_fntLst"+d](),e=[],h;...
function sa (line 12) | function sa(a,b){this.c=a;this.a=b}
function ta (line 12) | function ta(a,b){a?this.c=a:this.c=ua;this.a=[];this.f=[];this.g=b||""}
function va (line 12) | function va(a,b){for(var c=b.length,d=0;d<c;d++){var e=b[d].split(":");3...
function wa (line 13) | function wa(a){if(0==a.a.length)throw Error("No fonts to load!");if(-1!=...
function ya (line 13) | function ya(a){this.f=a;this.a=[];this.c={}}
function Da (line 16) | function Da(a){for(var b=a.f.length,c=0;c<b;c++){var d=a.f[c].split(":")...
function Ea (line 17) | function Ea(a,b){this.c=a;this.a=b}
function Ga (line 17) | function Ga(a,b){this.c=a;this.a=b}
function Ha (line 17) | function Ha(a,b){this.c=a;this.f=b;this.a=[]}
Condensed preview — 110 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (493K chars).
[
{
"path": ".gitignore",
"chars": 32,
"preview": ".bundle\n*~\ntarget\ntmp\n_site\npkg\n"
},
{
"path": ".travis.yml",
"chars": 312,
"preview": "before_install:\n - wget https://s3.amazonaws.com/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2\n - tar -xjf pha"
},
{
"path": "CHANGELOG",
"chars": 15895,
"preview": "v1.6.28 (March 27, 2017)\n\n* Clear timer timeout when promise resolves.\n\nv1.6.27 (November 29, 2016)\n\n* Disable native fo"
},
{
"path": "CONTRIBUTING.md",
"chars": 2026,
"preview": "# Contributing\n\nPlease open [an issue](https://github.com/typekit/webfontloader/issues) if you find or suspect any probl"
},
{
"path": "Gemfile",
"chars": 39,
"preview": "source 'https://rubygems.org'\n\ngemspec\n"
},
{
"path": "LICENSE",
"chars": 10173,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 17083,
"preview": "# Web Font Loader\n\nWeb Font Loader gives you added control when using linked fonts via `@font-face`. It provides a commo"
},
{
"path": "Rakefile",
"chars": 6986,
"preview": "require 'rubygems'\nrequire 'rake'\nrequire 'date'\n\n######################################################################"
},
{
"path": "bin/webfontloader-demos",
"chars": 799,
"preview": "#!/usr/bin/env ruby\n\nrequire 'rubygems'\n\n$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + \"/../lib\")\nrequire"
},
{
"path": "bower.json",
"chars": 422,
"preview": "{\n \"name\": \"webfontloader\",\n \"main\": \"webfontloader.js\",\n \"description\": \"Web Font Loader gives you added control whe"
},
{
"path": "browsers.json",
"chars": 2499,
"preview": "[\n {\n \"os_version\": \"XP\",\n \"os\": \"Windows\",\n \"browser_version\": \"12.16\",\n \"browser\": \"opera\"\n },\n {\n \""
},
{
"path": "externs.js",
"chars": 178,
"preview": "/**\n * @type {function(function():*)}\n */\nvar define;\n\n/**\n * @type {boolean?}\n */\ndefine.amd;\n\n/**\n * @type {Object}\n *"
},
{
"path": "lib/webfontloader/demo/public/basic.css",
"chars": 100,
"preview": "body {\n line-height: 1;\n font-size: 14px;\n margin: 10px;\n}\nh1 {\n font-size: 5em;\n margin: 0;\n}\n"
},
{
"path": "lib/webfontloader/demo/public/blank.html",
"chars": 171,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\">\n <title>Blank"
},
{
"path": "lib/webfontloader/demo/public/custom-iframe.html",
"chars": 1022,
"preview": "<!doctype html>\n<html>\n<head>\n <title>Custom Module</title>\n <script type=\"text/javascript\" src=\"/webfont.js\"></script"
},
{
"path": "lib/webfontloader/demo/public/custom.html",
"chars": 2616,
"preview": "<!doctype html>\n<html>\n<head>\n <title>Custom Module</title>\n <script type=\"text/javascript\" src=\"/webfont.js\"></script"
},
{
"path": "lib/webfontloader/demo/public/event-css-active-multiple.html",
"chars": 1068,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/event-css-active.html",
"chars": 867,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/event-css-inactive.html",
"chars": 887,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/event-css-loading.html",
"chars": 1366,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/event-js-active.html",
"chars": 986,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/event-js-font-active.html",
"chars": 1039,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/event-js-loading.html",
"chars": 1606,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/events-variations.html",
"chars": 4486,
"preview": "<!doctype html>\n<html>\n<head>\n <script type=\"text/javascript\" src=\"/webfont.js\"></script>\n <script type=\"text/javascri"
},
{
"path": "lib/webfontloader/demo/public/events.html",
"chars": 3143,
"preview": "<!doctype html>\n<html>\n<head>\n <script type=\"text/javascript\" src=\"/webfont.js\"></script>\n <script type=\"text/javascri"
},
{
"path": "lib/webfontloader/demo/public/fontdeck.html",
"chars": 2042,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script src=\"/webfont.js\"></"
},
{
"path": "lib/webfontloader/demo/public/fontwatchrunner-default-fonts.html",
"chars": 3287,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/google-css.html",
"chars": 602,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n\n <link href=\"/fonts/api?fami"
},
{
"path": "lib/webfontloader/demo/public/google-iframe.html",
"chars": 1026,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/google.html",
"chars": 742,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/ie-fast-js.html",
"chars": 1077,
"preview": "<!doctype html>\n<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n <title>Show me Fon"
},
{
"path": "lib/webfontloader/demo/public/ie-slow-js.html",
"chars": 1119,
"preview": "<!doctype html>\n<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n <title>Show me Fon"
},
{
"path": "lib/webfontloader/demo/public/ie-slow-link.html",
"chars": 879,
"preview": "<!doctype html>\n<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n <title>Show me Fon"
},
{
"path": "lib/webfontloader/demo/public/index.html",
"chars": 4320,
"preview": "<!doctype html>\n<html>\n<head>\n</head>\n<body>\n <h1>Web Font Loader Demos</h1>\n <p>\n Demonstrations of pure CSS and J"
},
{
"path": "lib/webfontloader/demo/public/monotype-iframe.html",
"chars": 1012,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/monotype.html",
"chars": 854,
"preview": "<!doctype html>\r\n<html>\r\n<head>\r\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\r\n <script type=\"text/javas"
},
{
"path": "lib/webfontloader/demo/public/typekit-iframe.html",
"chars": 999,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/typekit-variations.html",
"chars": 1367,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/public/typekit.html",
"chars": 919,
"preview": "<!doctype html>\n<html>\n<head>\n <link href=\"/basic.css\" rel=\"stylesheet\" type=\"text/css\">\n <script type=\"text/javascrip"
},
{
"path": "lib/webfontloader/demo/server.rb",
"chars": 3058,
"preview": "require 'sinatra/base'\nrequire 'open-uri'\n\nmodule WebFontLoader\n module Demo\n class Server < Sinatra::Base\n\n De"
},
{
"path": "lib/webfontloader/modules.rb",
"chars": 1187,
"preview": "module WebFontLoader\n class Modules\n\n def initialize(*modules)\n @project_root = WebFontLoader::ProjectRoot\n "
},
{
"path": "lib/webfontloader.rb",
"chars": 162,
"preview": "require 'yaml'\n\nrequire 'webfontloader/modules'\n\nmodule WebFontLoader\n VERSION = '1.6.28'\n\n ProjectRoot = File.expand_"
},
{
"path": "package.json",
"chars": 932,
"preview": "{\n \"name\": \"webfontloader\",\n \"version\": \"1.6.28\",\n \"description\": \"Web Font Loader gives you added control when using"
},
{
"path": "spec/core/cssclassname_spec.js",
"chars": 1316,
"preview": "describe('CssClassName', function () {\n var CssClassName = webfont.CssClassName,\n sanitizer = new CssClassName();\n"
},
{
"path": "spec/core/domhelper_spec.js",
"chars": 14855,
"preview": "describe('DomHelper', function () {\n var DomHelper = webfont.DomHelper,\n domHelper = new DomHelper(window);\n\n des"
},
{
"path": "spec/core/eventdispatcher_spec.js",
"chars": 7720,
"preview": "describe('EventDispatcher', function () {\n var EventDispatcher = webfont.EventDispatcher,\n DomHelper = webfont.Dom"
},
{
"path": "spec/core/font_spec.js",
"chars": 5062,
"preview": "describe('Font', function () {\n var Font = webfont.Font;\n\n describe('#quote', function () {\n var quote = function ("
},
{
"path": "spec/core/fontmoduleloader_spec.js",
"chars": 1351,
"preview": "describe('FontModuleLoader', function () {\n var FontModuleLoader = webfont.FontModuleLoader;\n\n describe('#getModules',"
},
{
"path": "spec/core/fontruler_spec.js",
"chars": 773,
"preview": "describe('FontRuler', function () {\n var Font = webfont.Font,\n FontRuler = webfont.FontRuler,\n DomHelper = we"
},
{
"path": "spec/core/fontwatcher_spec.js",
"chars": 11052,
"preview": "describe('FontWatcher', function () {\n var FontWatcher = webfont.FontWatcher,\n FontWatchRunner = webfont.FontWatch"
},
{
"path": "spec/core/fontwatchrunner_spec.js",
"chars": 4296,
"preview": "describe('FontWatchRunner', function () {\n var FontWatchRunner = webfont.FontWatchRunner,\n Font = webfont.Font,\n "
},
{
"path": "spec/core/nativefontwatchrunner_spec.js",
"chars": 3484,
"preview": "describe('NativeFontWatchRunner', function () {\n var NativeFontWatchRunner = webfont.NativeFontWatchRunner,\n Font "
},
{
"path": "spec/core/size_spec.js",
"chars": 606,
"preview": "describe('Size', function () {\n var Size = webfont.Size;\n\n it('should return true on identical sizes', function () {\n "
},
{
"path": "spec/core/webfont_spec.js",
"chars": 6216,
"preview": "describe('WebFont', function () {\n var WebFont = webfont.WebFont,\n Font = webfont.Font;\n FontWatchRunner = we"
},
{
"path": "spec/deps.js",
"chars": 2503,
"preview": "// This file was autogenerated by calcdeps.js\ngoog.addDependency(\"../../src/closure.js\", [], []);\ngoog.addDependency(\".."
},
{
"path": "spec/fixtures/external_script.js",
"chars": 38,
"preview": "window.EXTERNAL_SCRIPT_LOADED = true;\n"
},
{
"path": "spec/fixtures/external_stylesheet.css",
"chars": 95,
"preview": "#TEST_ELEMENT {\n display: block;\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n}\n"
},
{
"path": "spec/fixtures/fonts/LICENSE.txt",
"chars": 4622,
"preview": "Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Re"
},
{
"path": "spec/fixtures/fonts/nullfont.css",
"chars": 160,
"preview": "@font-face{font-family:__webfontloader_test__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:font"
},
{
"path": "spec/fixtures/fonts/nullfont1.css",
"chars": 162,
"preview": "@font-face{font-family:__webfontloader_test_1__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:fo"
},
{
"path": "spec/fixtures/fonts/nullfont2.css",
"chars": 162,
"preview": "@font-face{font-family:__webfontloader_test_2__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:fo"
},
{
"path": "spec/fixtures/fonts/nullfont3.css",
"chars": 162,
"preview": "@font-face{font-family:__webfontloader_test_3__;src:url(data:application/x-font-woff;base64,) format('woff'),url(data:fo"
},
{
"path": "spec/fixtures/fonts/sourcesansa.css",
"chars": 267,
"preview": "@font-face{font-family:SourceSansA;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) forma"
},
{
"path": "spec/fixtures/fonts/sourcesansb.css",
"chars": 267,
"preview": "@font-face{font-family:SourceSansB;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) forma"
},
{
"path": "spec/fixtures/fonts/sourcesansc.css",
"chars": 267,
"preview": "@font-face{font-family:SourceSansC;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) forma"
},
{
"path": "spec/fixtures/fonts/sourcesansd.css",
"chars": 267,
"preview": "@font-face{font-family:SourceSansD;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) forma"
},
{
"path": "spec/fixtures/fonts/sourcesansdup1.css",
"chars": 269,
"preview": "@font-face{font-family:SourceSansDup;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) for"
},
{
"path": "spec/fixtures/fonts/sourcesansdup2.css",
"chars": 269,
"preview": "@font-face{font-family:SourceSansDup;src:url(sourcesans.eot?#iefix) format('embedded-opentype'),url(sourcesans.woff) for"
},
{
"path": "spec/index.html",
"chars": 3222,
"preview": "<!doctype html>\n<html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Webf"
},
{
"path": "spec/modules/custom_spec.js",
"chars": 2127,
"preview": "describe('modules.Custom', function () {\n var Custom = webfont.modules.Custom,\n FontFamily = webfont.FontFamily,\n "
},
{
"path": "spec/modules/fontdeck_spec.js",
"chars": 3541,
"preview": "describe('modules.Fontdeck', function () {\n var Fontdeck = webfont.modules.Fontdeck,\n Font = webfont.Font;\n\n var "
},
{
"path": "spec/modules/google/fontapiparser_spec.js",
"chars": 6902,
"preview": "describe('modules.google.FontApiParser', function () {\n var FontApiParser = webfont.modules.google.FontApiParser,\n "
},
{
"path": "spec/modules/google/fontapiurlbuilder_spec.js",
"chars": 1548,
"preview": "describe('modules.google.FontApiUrlBuilder', function () {\n var FontApiUrlBuilder = webfont.modules.google.FontApiUrlBu"
},
{
"path": "spec/modules/google/googlefontapi_spec.js",
"chars": 3120,
"preview": "describe('modules.google.GoogleFontApi', function () {\n var GoogleFontApi = webfont.modules.google.GoogleFontApi,\n "
},
{
"path": "spec/modules/monotype_spec.js",
"chars": 1498,
"preview": "describe('modules.Monotype', function () {\n var Monotype = webfont.modules.Monotype,\n Font = webfont.Font,\n B"
},
{
"path": "spec/modules/typekit_spec.js",
"chars": 1836,
"preview": "describe('modules.Typekit', function () {\n var Typekit = webfont.modules.Typekit,\n Font = webfont.Font;\n\n var con"
},
{
"path": "src/closure.js",
"chars": 112,
"preview": "/* Web Font Loader v{{version}} - (c) Adobe Systems, Google. License: Apache 2.0 */\n(function(){{{source}}}());\n"
},
{
"path": "src/core/cssclassname.js",
"chars": 1297,
"preview": "goog.provide('webfont.CssClassName');\n\n/**\n * Handles sanitization and construction of css class names.\n * @param {strin"
},
{
"path": "src/core/domhelper.js",
"chars": 12020,
"preview": "goog.provide('webfont.DomHelper');\n\n/**\n * Handles common DOM manipulation tasks. The aim of this library is to cover\n *"
},
{
"path": "src/core/eventdispatcher.js",
"chars": 6247,
"preview": "goog.provide('webfont.EventDispatcher');\n\ngoog.require('webfont.CssClassName');\n\n/**\n * A class to dispatch events and m"
},
{
"path": "src/core/font.js",
"chars": 3046,
"preview": "goog.provide('webfont.Font');\n\n/**\n * This class is an abstraction for a single font or typeface.\n * It contains the fon"
},
{
"path": "src/core/fontmodule.js",
"chars": 339,
"preview": "goog.provide('webfont.FontModule');\n\n/**\n * @interface\n */\nwebfont.FontModule = function () {};\n\ngoog.scope(function () "
},
{
"path": "src/core/fontmoduleloader.js",
"chars": 1142,
"preview": "goog.provide('webfont.FontModuleLoader');\ngoog.provide('webfont.FontModuleFactory');\n\n/** @typedef {function(Object, web"
},
{
"path": "src/core/fontruler.js",
"chars": 1559,
"preview": "goog.provide('webfont.FontRuler');\n\n/**\n * An element that can be used to measure the metrics\n * of a given font and str"
},
{
"path": "src/core/fontwatcher.js",
"chars": 4635,
"preview": "goog.provide('webfont.FontWatcher');\n\ngoog.require('webfont.FontWatchRunner');\ngoog.require('webfont.NativeFontWatchRunn"
},
{
"path": "src/core/fontwatchrunner.js",
"chars": 7973,
"preview": "goog.provide('webfont.FontWatchRunner');\n\ngoog.require('webfont.Font');\ngoog.require('webfont.FontRuler');\n\n/**\n * @cons"
},
{
"path": "src/core/initialize.js",
"chars": 2228,
"preview": "goog.provide('webfont');\n\ngoog.require('webfont.WebFont');\n\ngoog.require('webfont.modules.Typekit');\ngoog.require('webfo"
},
{
"path": "src/core/nativefontwatchrunner.js",
"chars": 1938,
"preview": "goog.provide('webfont.NativeFontWatchRunner');\n\ngoog.require('webfont.Font');\n\ngoog.scope(function () {\n /**\n * @const"
},
{
"path": "src/core/stylesheetwaiter.js",
"chars": 1018,
"preview": "goog.provide('webfont.StyleSheetWaiter');\n\n/**\n * A utility class for handling callback from DomHelper.loadStylesheet()."
},
{
"path": "src/core/webfont.js",
"chars": 3068,
"preview": "goog.provide('webfont.WebFont');\n\ngoog.require('webfont.DomHelper');\ngoog.require('webfont.EventDispatcher');\ngoog.requi"
},
{
"path": "src/modules/custom.js",
"chars": 1618,
"preview": "goog.provide('webfont.modules.Custom');\n\ngoog.require('webfont.Font');\ngoog.require('webfont.StyleSheetWaiter');\n\n/**\n *"
},
{
"path": "src/modules/fontdeck.js",
"chars": 2048,
"preview": "goog.provide('webfont.modules.Fontdeck');\n\ngoog.require('webfont.Font');\n\n/**\n * @constructor\n * @implements {webfont.Fo"
},
{
"path": "src/modules/google/fontapiparser.js",
"chars": 4627,
"preview": "goog.provide('webfont.modules.google.FontApiParser');\n\ngoog.require('webfont.Font');\n\n/**\n * @constructor\n */\nwebfont.mo"
},
{
"path": "src/modules/google/fontapiurlbuilder.js",
"chars": 1946,
"preview": "goog.provide('webfont.modules.google.FontApiUrlBuilder');\n\n/**\n * @constructor\n */\nwebfont.modules.google.FontApiUrlBuil"
},
{
"path": "src/modules/google/googlefontapi.js",
"chars": 1693,
"preview": "goog.provide('webfont.modules.google.GoogleFontApi');\n\ngoog.require('webfont.modules.google.FontApiUrlBuilder');\ngoog.re"
},
{
"path": "src/modules/monotype.js",
"chars": 3176,
"preview": "goog.provide('webfont.modules.Monotype');\n\ngoog.require('webfont.Font');\n\n/**\nwebfont.load({\n monotype: {\n projectId"
},
{
"path": "src/modules/typekit.js",
"chars": 2034,
"preview": "goog.provide('webfont.modules.Typekit');\n\ngoog.require('webfont.Font');\n\n/**\n * @constructor\n * @implements {webfont.Fon"
},
{
"path": "src/modules.yml",
"chars": 617,
"preview": "core:\n - ../tools/compiler/base.js\n - core/domhelper.js\n - core/stylesheetwaiter.js\n - core/cssclassname.js\n - core"
},
{
"path": "tools/compiler/base.js",
"chars": 83688,
"preview": "// Copyright 2006 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0"
},
{
"path": "tools/jasmine/MIT.LICENSE",
"chars": 1061,
"preview": "Copyright (c) 2008-2011 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of th"
},
{
"path": "tools/jasmine/jasmine-html.js",
"chars": 20765,
"preview": "jasmine.HtmlReporterHelpers = {};\n\njasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {\n va"
},
{
"path": "tools/jasmine/jasmine.css",
"chars": 6537,
"preview": "body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }\n\n#HTMLReporter { font-size: 11px; font-"
},
{
"path": "tools/jasmine/jasmine.js",
"chars": 70892,
"preview": "var isCommonJS = typeof window == \"undefined\" && typeof exports == \"object\";\n\n/**\n * Top level namespace for Jasmine, a "
},
{
"path": "tools/jasmine-browserstack/jasmine-browserstack.js",
"chars": 3418,
"preview": "(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define(['jasmine'], factory);\n } el"
},
{
"path": "tools/jasmine-phantomjs/jasmine-phantomjs.js",
"chars": 548,
"preview": "var webpage = require('webpage'),\n system = require('system');\n\nif (system.args.length !== 1) {\n var page = webpage."
},
{
"path": "tools/jasmine-phantomjs/terminal-reporter.js",
"chars": 5806,
"preview": "/**\n * Taken from https://github.com/larrymyers/jasmine-reporters\n * Licensed under the MIT license.\n */\n(function() {\n "
},
{
"path": "webfontloader.gemspec",
"chars": 7651,
"preview": "## This is the rakegem gemspec template. Make sure you read and understand\n## all of the comments. Some sections require"
},
{
"path": "webfontloader.js",
"chars": 12505,
"preview": "/* Web Font Loader v1.6.28 - (c) Adobe Systems, Google. License: Apache 2.0 */(function(){function aa(a,b,c){return a.ca"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the typekit/webfontloader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 110 files (457.7 KB), approximately 120.8k tokens, and a symbol index with 96 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.