yeet
This commit is contained in:
23
node_modules/fontfaceobserver/LICENSE
generated
vendored
Normal file
23
node_modules/fontfaceobserver/LICENSE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Copyright (c) 2014 - Bram Stein
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
165
node_modules/fontfaceobserver/README.md
generated
vendored
Normal file
165
node_modules/fontfaceobserver/README.md
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
# Font Face Observer [](https://travis-ci.org/bramstein/fontfaceobserver)
|
||||
|
||||
Font Face Observer is a small `@font-face` loader and monitor (3.5KB minified and 1.3KB gzipped) compatible with any webfont service. It will monitor when a webfont is loaded and notify you. It does not limit you in any way in where, when, or how you load your webfonts. Unlike the [Web Font Loader](https://github.com/typekit/webfontloader) Font Face Observer uses scroll events to detect font loads efficiently and with minimum overhead.
|
||||
|
||||
## How to use
|
||||
|
||||
Include your `@font-face` rules as usual. Fonts can be supplied by either a font service such as [Google Fonts](http://www.google.com/fonts), [Typekit](http://typekit.com), and [Webtype](http://webtype.com) or be self-hosted. You can set up monitoring for a single font family at a time:
|
||||
|
||||
```js
|
||||
var font = new FontFaceObserver('My Family', {
|
||||
weight: 400
|
||||
});
|
||||
|
||||
font.load().then(function () {
|
||||
console.log('Font is available');
|
||||
}, function () {
|
||||
console.log('Font is not available');
|
||||
});
|
||||
```
|
||||
|
||||
The `FontFaceObserver` constructor takes two arguments: the font-family name (required) and an object describing the variation (optional). The object can contain `weight`, `style`, and `stretch` properties. If a property is not present it will default to `normal`. To start loading the font, call the `load` method. It'll immediately return a new Promise that resolves when the font is loaded and rejected when the font fails to load.
|
||||
|
||||
If your font doesn't contain at least the latin "BESbwy" characters you must pass a custom test string to the `load` method.
|
||||
|
||||
```js
|
||||
var font = new FontFaceObserver('My Family');
|
||||
|
||||
font.load('中国').then(function () {
|
||||
console.log('Font is available');
|
||||
}, function () {
|
||||
console.log('Font is not available');
|
||||
});
|
||||
```
|
||||
|
||||
The default timeout for giving up on font loading is 3 seconds. You can increase or decrease this by passing a number of milliseconds as the second parameter to the `load` method.
|
||||
|
||||
```js
|
||||
var font = new FontFaceObserver('My Family');
|
||||
|
||||
font.load(null, 5000).then(function () {
|
||||
console.log('Font is available');
|
||||
}, function () {
|
||||
console.log('Font is not available after waiting 5 seconds');
|
||||
});
|
||||
```
|
||||
|
||||
Multiple fonts can be loaded by creating a `FontFaceObserver` instance for each.
|
||||
|
||||
```js
|
||||
var fontA = new FontFaceObserver('Family A');
|
||||
var fontB = new FontFaceObserver('Family B');
|
||||
|
||||
fontA.load().then(function () {
|
||||
console.log('Family A is available');
|
||||
});
|
||||
|
||||
fontB.load().then(function () {
|
||||
console.log('Family B is available');
|
||||
});
|
||||
```
|
||||
|
||||
You may also load both at the same time, rather than loading each individually.
|
||||
|
||||
```js
|
||||
var fontA = new FontFaceObserver('Family A');
|
||||
var fontB = new FontFaceObserver('Family B');
|
||||
|
||||
Promise.all([fontA.load(), fontB.load()]).then(function () {
|
||||
console.log('Family A & B have loaded');
|
||||
});
|
||||
```
|
||||
|
||||
If you are working with a large number of fonts, you may decide to create `FontFaceObserver` instances dynamically:
|
||||
|
||||
```js
|
||||
// An example collection of font data with additional metadata,
|
||||
// in this case “color.”
|
||||
var exampleFontData = {
|
||||
'Family A': { weight: 400, color: 'red' },
|
||||
'Family B': { weight: 400, color: 'orange' },
|
||||
'Family C': { weight: 900, color: 'yellow' },
|
||||
// Etc.
|
||||
};
|
||||
|
||||
var observers = [];
|
||||
|
||||
// Make one observer for each font,
|
||||
// by iterating over the data we already have
|
||||
Object.keys(exampleFontData).forEach(function(family) {
|
||||
var data = exampleFontData[family];
|
||||
var obs = new FontFaceObserver(family, data);
|
||||
observers.push(obs.load());
|
||||
});
|
||||
|
||||
Promise.all(observers)
|
||||
.then(function(fonts) {
|
||||
fonts.forEach(function(font) {
|
||||
console.log(font.family + ' ' + font.weight + ' ' + 'loaded');
|
||||
|
||||
// Map the result of the Promise back to our existing data,
|
||||
// to get the other properties we need.
|
||||
console.log(exampleFontData[font.family].color);
|
||||
});
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.warn('Some critical font are not available:', err);
|
||||
});
|
||||
```
|
||||
|
||||
The following example emulates FOUT with Font Face Observer for `My Family`.
|
||||
|
||||
```js
|
||||
var font = new FontFaceObserver('My Family');
|
||||
|
||||
font.load().then(function () {
|
||||
document.documentElement.className += " fonts-loaded";
|
||||
});
|
||||
```
|
||||
|
||||
```css
|
||||
.fonts-loaded {
|
||||
body {
|
||||
font-family: My Family, sans-serif;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
If you're using npm you can install Font Face Observer as a dependency:
|
||||
|
||||
```shell
|
||||
$ npm install fontfaceobserver
|
||||
```
|
||||
|
||||
You can then require `fontfaceobserver` as a CommonJS (Browserify) module:
|
||||
|
||||
```js
|
||||
var FontFaceObserver = require('fontfaceobserver');
|
||||
|
||||
var font = new FontFaceObserver('My Family');
|
||||
|
||||
font.load().then(function () {
|
||||
console.log('My Family has loaded');
|
||||
});
|
||||
```
|
||||
|
||||
If you're not using npm, grab `fontfaceobserver.js` or `fontfaceobserver.standalone.js` (see below) and include it in your project. It'll export a global `FontFaceObserver` that you can use to create new instances.
|
||||
|
||||
Font Face Observer uses Promises in its API, so for [browsers that do not support promises](http://caniuse.com/#search=promise) you'll need to include a polyfill. If you use your own Promise polyfill you just need to include `fontfaceobserver.standalone.js` in your project. If you do not have an existing Promise polyfill you should use `fontfaceobserver.js` which includes a small Promise polyfill. Using the Promise polyfill adds roughly 1.4KB (500 bytes gzipped) to the file size.
|
||||
|
||||
## Browser support
|
||||
|
||||
FontFaceObserver has been tested and works on the following browsers:
|
||||
|
||||
* Chrome (desktop & Android)
|
||||
* Firefox
|
||||
* Opera
|
||||
* Safari (desktop & iOS)
|
||||
* IE8+
|
||||
* Android WebKit
|
||||
|
||||
## License
|
||||
|
||||
Font Face Observer is licensed under the BSD License. Copyright 2014-2017 Bram Stein. All rights reserved.
|
15
node_modules/fontfaceobserver/externs.js
generated
vendored
Normal file
15
node_modules/fontfaceobserver/externs.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} family
|
||||
* @param {Object} descriptors
|
||||
*/
|
||||
var FontFaceObserver = function (family, descriptors) {};
|
||||
|
||||
/**
|
||||
* @param {string=} opt_text
|
||||
* @param {number=} opt_timeout
|
||||
*
|
||||
* @return {Promise.<FontFaceObserver>}
|
||||
*/
|
||||
FontFaceObserver.prototype.load = function (opt_text, opt_timeout) {};
|
12
node_modules/fontfaceobserver/fontfaceobserver.js
generated
vendored
Normal file
12
node_modules/fontfaceobserver/fontfaceobserver.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/* Font Face Observer v2.1.0 - © Bram Stein. License: BSD-3-Clause */(function(){'use strict';var f,g=[];function l(a){g.push(a);1==g.length&&f()}function m(){for(;g.length;)g[0](),g.shift()}f=function(){setTimeout(m)};function n(a){this.a=p;this.b=void 0;this.f=[];var b=this;try{a(function(a){q(b,a)},function(a){r(b,a)})}catch(c){r(b,c)}}var p=2;function t(a){return new n(function(b,c){c(a)})}function u(a){return new n(function(b){b(a)})}function q(a,b){if(a.a==p){if(b==a)throw new TypeError;var c=!1;try{var d=b&&b.then;if(null!=b&&"object"==typeof b&&"function"==typeof d){d.call(b,function(b){c||q(a,b);c=!0},function(b){c||r(a,b);c=!0});return}}catch(e){c||r(a,e);return}a.a=0;a.b=b;v(a)}}
|
||||
function r(a,b){if(a.a==p){if(b==a)throw new TypeError;a.a=1;a.b=b;v(a)}}function v(a){l(function(){if(a.a!=p)for(;a.f.length;){var b=a.f.shift(),c=b[0],d=b[1],e=b[2],b=b[3];try{0==a.a?"function"==typeof c?e(c.call(void 0,a.b)):e(a.b):1==a.a&&("function"==typeof d?e(d.call(void 0,a.b)):b(a.b))}catch(h){b(h)}}})}n.prototype.g=function(a){return this.c(void 0,a)};n.prototype.c=function(a,b){var c=this;return new n(function(d,e){c.f.push([a,b,d,e]);v(c)})};
|
||||
function w(a){return new n(function(b,c){function d(c){return function(d){h[c]=d;e+=1;e==a.length&&b(h)}}var e=0,h=[];0==a.length&&b(h);for(var k=0;k<a.length;k+=1)u(a[k]).c(d(k),c)})}function x(a){return new n(function(b,c){for(var d=0;d<a.length;d+=1)u(a[d]).c(b,c)})};window.Promise||(window.Promise=n,window.Promise.resolve=u,window.Promise.reject=t,window.Promise.race=x,window.Promise.all=w,window.Promise.prototype.then=n.prototype.c,window.Promise.prototype["catch"]=n.prototype.g);}());
|
||||
|
||||
(function(){function l(a,b){document.addEventListener?a.addEventListener("scroll",b,!1):a.attachEvent("scroll",b)}function m(a){document.body?a():document.addEventListener?document.addEventListener("DOMContentLoaded",function c(){document.removeEventListener("DOMContentLoaded",c);a()}):document.attachEvent("onreadystatechange",function k(){if("interactive"==document.readyState||"complete"==document.readyState)document.detachEvent("onreadystatechange",k),a()})};function t(a){this.a=document.createElement("div");this.a.setAttribute("aria-hidden","true");this.a.appendChild(document.createTextNode(a));this.b=document.createElement("span");this.c=document.createElement("span");this.h=document.createElement("span");this.f=document.createElement("span");this.g=-1;this.b.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.c.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";
|
||||
this.f.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.h.style.cssText="display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;";this.b.appendChild(this.h);this.c.appendChild(this.f);this.a.appendChild(this.b);this.a.appendChild(this.c)}
|
||||
function u(a,b){a.a.style.cssText="max-width:none;min-width:20px;min-height:20px;display:inline-block;overflow:hidden;position:absolute;width:auto;margin:0;padding:0;top:-999px;white-space:nowrap;font-synthesis:none;font:"+b+";"}function z(a){var b=a.a.offsetWidth,c=b+100;a.f.style.width=c+"px";a.c.scrollLeft=c;a.b.scrollLeft=a.b.scrollWidth+100;return a.g!==b?(a.g=b,!0):!1}function A(a,b){function c(){var a=k;z(a)&&a.a.parentNode&&b(a.g)}var k=a;l(a.b,c);l(a.c,c);z(a)};function B(a,b){var c=b||{};this.family=a;this.style=c.style||"normal";this.weight=c.weight||"normal";this.stretch=c.stretch||"normal"}var C=null,D=null,E=null,F=null;function G(){if(null===D)if(J()&&/Apple/.test(window.navigator.vendor)){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))(?:\.([0-9]+))/.exec(window.navigator.userAgent);D=!!a&&603>parseInt(a[1],10)}else D=!1;return D}function J(){null===F&&(F=!!document.fonts);return F}
|
||||
function K(){if(null===E){var a=document.createElement("div");try{a.style.font="condensed 100px sans-serif"}catch(b){}E=""!==a.style.font}return E}function L(a,b){return[a.style,a.weight,K()?a.stretch:"","100px",b].join(" ")}
|
||||
B.prototype.load=function(a,b){var c=this,k=a||"BESbswy",r=0,n=b||3E3,H=(new Date).getTime();return new Promise(function(a,b){if(J()&&!G()){var M=new Promise(function(a,b){function e(){(new Date).getTime()-H>=n?b(Error(""+n+"ms timeout exceeded")):document.fonts.load(L(c,'"'+c.family+'"'),k).then(function(c){1<=c.length?a():setTimeout(e,25)},b)}e()}),N=new Promise(function(a,c){r=setTimeout(function(){c(Error(""+n+"ms timeout exceeded"))},n)});Promise.race([N,M]).then(function(){clearTimeout(r);a(c)},
|
||||
b)}else m(function(){function v(){var b;if(b=-1!=f&&-1!=g||-1!=f&&-1!=h||-1!=g&&-1!=h)(b=f!=g&&f!=h&&g!=h)||(null===C&&(b=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),C=!!b&&(536>parseInt(b[1],10)||536===parseInt(b[1],10)&&11>=parseInt(b[2],10))),b=C&&(f==w&&g==w&&h==w||f==x&&g==x&&h==x||f==y&&g==y&&h==y)),b=!b;b&&(d.parentNode&&d.parentNode.removeChild(d),clearTimeout(r),a(c))}function I(){if((new Date).getTime()-H>=n)d.parentNode&&d.parentNode.removeChild(d),b(Error(""+
|
||||
n+"ms timeout exceeded"));else{var a=document.hidden;if(!0===a||void 0===a)f=e.a.offsetWidth,g=p.a.offsetWidth,h=q.a.offsetWidth,v();r=setTimeout(I,50)}}var e=new t(k),p=new t(k),q=new t(k),f=-1,g=-1,h=-1,w=-1,x=-1,y=-1,d=document.createElement("div");d.dir="ltr";u(e,L(c,"sans-serif"));u(p,L(c,"serif"));u(q,L(c,"monospace"));d.appendChild(e.a);d.appendChild(p.a);d.appendChild(q.a);document.body.appendChild(d);w=e.a.offsetWidth;x=p.a.offsetWidth;y=q.a.offsetWidth;I();A(e,function(a){f=a;v()});u(e,
|
||||
L(c,'"'+c.family+'",sans-serif'));A(p,function(a){g=a;v()});u(p,L(c,'"'+c.family+'",serif'));A(q,function(a){h=a;v()});u(q,L(c,'"'+c.family+'",monospace'))})})};"object"===typeof module?module.exports=B:(window.FontFaceObserver=B,window.FontFaceObserver.prototype.load=B.prototype.load);}());
|
8
node_modules/fontfaceobserver/fontfaceobserver.standalone.js
generated
vendored
Normal file
8
node_modules/fontfaceobserver/fontfaceobserver.standalone.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/* Font Face Observer v2.1.0 - © Bram Stein. License: BSD-3-Clause */(function(){function l(a,b){document.addEventListener?a.addEventListener("scroll",b,!1):a.attachEvent("scroll",b)}function m(a){document.body?a():document.addEventListener?document.addEventListener("DOMContentLoaded",function c(){document.removeEventListener("DOMContentLoaded",c);a()}):document.attachEvent("onreadystatechange",function k(){if("interactive"==document.readyState||"complete"==document.readyState)document.detachEvent("onreadystatechange",k),a()})};function t(a){this.a=document.createElement("div");this.a.setAttribute("aria-hidden","true");this.a.appendChild(document.createTextNode(a));this.b=document.createElement("span");this.c=document.createElement("span");this.h=document.createElement("span");this.f=document.createElement("span");this.g=-1;this.b.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.c.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";
|
||||
this.f.style.cssText="max-width:none;display:inline-block;position:absolute;height:100%;width:100%;overflow:scroll;font-size:16px;";this.h.style.cssText="display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;";this.b.appendChild(this.h);this.c.appendChild(this.f);this.a.appendChild(this.b);this.a.appendChild(this.c)}
|
||||
function u(a,b){a.a.style.cssText="max-width:none;min-width:20px;min-height:20px;display:inline-block;overflow:hidden;position:absolute;width:auto;margin:0;padding:0;top:-999px;white-space:nowrap;font-synthesis:none;font:"+b+";"}function z(a){var b=a.a.offsetWidth,c=b+100;a.f.style.width=c+"px";a.c.scrollLeft=c;a.b.scrollLeft=a.b.scrollWidth+100;return a.g!==b?(a.g=b,!0):!1}function A(a,b){function c(){var a=k;z(a)&&a.a.parentNode&&b(a.g)}var k=a;l(a.b,c);l(a.c,c);z(a)};function B(a,b){var c=b||{};this.family=a;this.style=c.style||"normal";this.weight=c.weight||"normal";this.stretch=c.stretch||"normal"}var C=null,D=null,E=null,F=null;function G(){if(null===D)if(J()&&/Apple/.test(window.navigator.vendor)){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))(?:\.([0-9]+))/.exec(window.navigator.userAgent);D=!!a&&603>parseInt(a[1],10)}else D=!1;return D}function J(){null===F&&(F=!!document.fonts);return F}
|
||||
function K(){if(null===E){var a=document.createElement("div");try{a.style.font="condensed 100px sans-serif"}catch(b){}E=""!==a.style.font}return E}function L(a,b){return[a.style,a.weight,K()?a.stretch:"","100px",b].join(" ")}
|
||||
B.prototype.load=function(a,b){var c=this,k=a||"BESbswy",r=0,n=b||3E3,H=(new Date).getTime();return new Promise(function(a,b){if(J()&&!G()){var M=new Promise(function(a,b){function e(){(new Date).getTime()-H>=n?b(Error(""+n+"ms timeout exceeded")):document.fonts.load(L(c,'"'+c.family+'"'),k).then(function(c){1<=c.length?a():setTimeout(e,25)},b)}e()}),N=new Promise(function(a,c){r=setTimeout(function(){c(Error(""+n+"ms timeout exceeded"))},n)});Promise.race([N,M]).then(function(){clearTimeout(r);a(c)},
|
||||
b)}else m(function(){function v(){var b;if(b=-1!=f&&-1!=g||-1!=f&&-1!=h||-1!=g&&-1!=h)(b=f!=g&&f!=h&&g!=h)||(null===C&&(b=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),C=!!b&&(536>parseInt(b[1],10)||536===parseInt(b[1],10)&&11>=parseInt(b[2],10))),b=C&&(f==w&&g==w&&h==w||f==x&&g==x&&h==x||f==y&&g==y&&h==y)),b=!b;b&&(d.parentNode&&d.parentNode.removeChild(d),clearTimeout(r),a(c))}function I(){if((new Date).getTime()-H>=n)d.parentNode&&d.parentNode.removeChild(d),b(Error(""+
|
||||
n+"ms timeout exceeded"));else{var a=document.hidden;if(!0===a||void 0===a)f=e.a.offsetWidth,g=p.a.offsetWidth,h=q.a.offsetWidth,v();r=setTimeout(I,50)}}var e=new t(k),p=new t(k),q=new t(k),f=-1,g=-1,h=-1,w=-1,x=-1,y=-1,d=document.createElement("div");d.dir="ltr";u(e,L(c,"sans-serif"));u(p,L(c,"serif"));u(q,L(c,"monospace"));d.appendChild(e.a);d.appendChild(p.a);d.appendChild(q.a);document.body.appendChild(d);w=e.a.offsetWidth;x=p.a.offsetWidth;y=q.a.offsetWidth;I();A(e,function(a){f=a;v()});u(e,
|
||||
L(c,'"'+c.family+'",sans-serif'));A(p,function(a){g=a;v()});u(p,L(c,'"'+c.family+'",serif'));A(q,function(a){h=a;v()});u(q,L(c,'"'+c.family+'",monospace'))})})};"object"===typeof module?module.exports=B:(window.FontFaceObserver=B,window.FontFaceObserver.prototype.load=B.prototype.load);}());
|
57
node_modules/fontfaceobserver/package.json
generated
vendored
Normal file
57
node_modules/fontfaceobserver/package.json
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "fontfaceobserver",
|
||||
"version": "2.1.0",
|
||||
"description": "Detect if web fonts are available",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/bramstein/fontfaceobserver.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/bramstein/fontfaceobserver/issues"
|
||||
},
|
||||
"homepage": "https://fontfaceobserver.com/",
|
||||
"main": "fontfaceobserver.standalone.js",
|
||||
"keywords": [
|
||||
"fontloader",
|
||||
"fonts",
|
||||
"font",
|
||||
"font-face",
|
||||
"web font",
|
||||
"font load",
|
||||
"font events"
|
||||
],
|
||||
"files": [
|
||||
"fontfaceobserver.js",
|
||||
"fontfaceobserver.standalone.js",
|
||||
"src/*.js",
|
||||
"externs.js"
|
||||
],
|
||||
"author": "Bram Stein <b.l.stein@gmail.com> (http://www.bramstein.com/)",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"closure-dom": "=0.2.6",
|
||||
"extend": "^3.0.0",
|
||||
"google-closure-compiler": "=20161024.0.0",
|
||||
"grunt": "^1.0.3",
|
||||
"grunt-contrib-clean": "^1.0.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-jshint": "^1.0.0",
|
||||
"grunt-exec": "~1.0.0",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-phantomjs-core": "^2.0.0",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
"promis": "=1.1.4",
|
||||
"sinon": "^1.17.4",
|
||||
"unexpected": "^10.14.2"
|
||||
},
|
||||
"scripts": {
|
||||
"preversion": "npm test",
|
||||
"version": "grunt dist && git add fontfaceobserver.js && git add fontfaceobserver.standalone.js",
|
||||
"postversion": "git push && git push --tags && rm -rf build && npm publish",
|
||||
"test": "grunt test"
|
||||
}
|
||||
}
|
10
node_modules/fontfaceobserver/src/descriptors.js
generated
vendored
Normal file
10
node_modules/fontfaceobserver/src/descriptors.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
goog.provide('fontface.Descriptors');
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* style: (string|undefined),
|
||||
* weight: (string|undefined),
|
||||
* stretch: (string|undefined)
|
||||
* }}
|
||||
*/
|
||||
fontface.Descriptors;
|
348
node_modules/fontfaceobserver/src/observer.js
generated
vendored
Normal file
348
node_modules/fontfaceobserver/src/observer.js
generated
vendored
Normal file
@ -0,0 +1,348 @@
|
||||
goog.provide('fontface.Observer');
|
||||
|
||||
goog.require('fontface.Ruler');
|
||||
goog.require('dom');
|
||||
|
||||
goog.scope(function () {
|
||||
var Ruler = fontface.Ruler;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} family
|
||||
* @param {fontface.Descriptors=} opt_descriptors
|
||||
*/
|
||||
fontface.Observer = function (family, opt_descriptors) {
|
||||
var descriptors = opt_descriptors || {};
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this['family'] = family;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this['style'] = descriptors.style || 'normal';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this['weight'] = descriptors.weight || 'normal';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this['stretch'] = descriptors.stretch || 'normal';
|
||||
};
|
||||
|
||||
var Observer = fontface.Observer;
|
||||
|
||||
/**
|
||||
* @type {null|boolean}
|
||||
*/
|
||||
Observer.HAS_WEBKIT_FALLBACK_BUG = null;
|
||||
|
||||
/**
|
||||
* @type {null|boolean}
|
||||
*/
|
||||
Observer.HAS_SAFARI_10_BUG = null;
|
||||
|
||||
/**
|
||||
* @type {null|boolean}
|
||||
*/
|
||||
Observer.SUPPORTS_STRETCH = null;
|
||||
|
||||
/**
|
||||
* @type {null|boolean}
|
||||
*/
|
||||
Observer.SUPPORTS_NATIVE_FONT_LOADING = null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
Observer.DEFAULT_TIMEOUT = 3000;
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Observer.getUserAgent = function () {
|
||||
return window.navigator.userAgent;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
Observer.getNavigatorVendor = function () {
|
||||
return window.navigator.vendor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this browser is WebKit and it has the fallback bug
|
||||
* which is present in WebKit 536.11 and earlier.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
Observer.hasWebKitFallbackBug = function () {
|
||||
if (Observer.HAS_WEBKIT_FALLBACK_BUG === null) {
|
||||
var match = /AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(Observer.getUserAgent());
|
||||
|
||||
Observer.HAS_WEBKIT_FALLBACK_BUG = !!match &&
|
||||
(parseInt(match[1], 10) < 536 ||
|
||||
(parseInt(match[1], 10) === 536 &&
|
||||
parseInt(match[2], 10) <= 11));
|
||||
}
|
||||
return Observer.HAS_WEBKIT_FALLBACK_BUG;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the browser has the Safari 10 bugs. The
|
||||
* native font load API in Safari 10 has two bugs that cause
|
||||
* the document.fonts.load and FontFace.prototype.load methods
|
||||
* to return promises that don't reliably get settled.
|
||||
*
|
||||
* The bugs are described in more detail here:
|
||||
* - https://bugs.webkit.org/show_bug.cgi?id=165037
|
||||
* - https://bugs.webkit.org/show_bug.cgi?id=164902
|
||||
*
|
||||
* If the browser is made by Apple, and has native font
|
||||
* loading support, it is potentially affected. But the API
|
||||
* was fixed around AppleWebKit version 603, so any newer
|
||||
* versions that that does not contain the bug.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
Observer.hasSafari10Bug = function () {
|
||||
if (Observer.HAS_SAFARI_10_BUG === null) {
|
||||
if (Observer.supportsNativeFontLoading() && /Apple/.test(Observer.getNavigatorVendor())) {
|
||||
var match = /AppleWebKit\/([0-9]+)(?:\.([0-9]+))(?:\.([0-9]+))/.exec(Observer.getUserAgent());
|
||||
|
||||
Observer.HAS_SAFARI_10_BUG = !!match && parseInt(match[1], 10) < 603;
|
||||
} else {
|
||||
Observer.HAS_SAFARI_10_BUG = false;
|
||||
}
|
||||
}
|
||||
return Observer.HAS_SAFARI_10_BUG;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the browser supports the native font loading
|
||||
* API.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
Observer.supportsNativeFontLoading = function () {
|
||||
if (Observer.SUPPORTS_NATIVE_FONT_LOADING === null) {
|
||||
Observer.SUPPORTS_NATIVE_FONT_LOADING = !!document['fonts'];
|
||||
}
|
||||
return Observer.SUPPORTS_NATIVE_FONT_LOADING;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the browser supports font-style in the font
|
||||
* short-hand syntax.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
Observer.supportStretch = function () {
|
||||
if (Observer.SUPPORTS_STRETCH === null) {
|
||||
var div = dom.createElement('div');
|
||||
|
||||
try {
|
||||
div.style.font = 'condensed 100px sans-serif';
|
||||
} catch (e) {}
|
||||
Observer.SUPPORTS_STRETCH = (div.style.font !== '');
|
||||
}
|
||||
|
||||
return Observer.SUPPORTS_STRETCH;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* @param {string} family
|
||||
* @return {string}
|
||||
*/
|
||||
Observer.prototype.getStyle = function (family) {
|
||||
return [this['style'], this['weight'], Observer.supportStretch() ? this['stretch'] : '', '100px', family].join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current time in milliseconds
|
||||
*
|
||||
* @return {number}
|
||||
*/
|
||||
Observer.prototype.getTime = function () {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string=} text Optional test string to use for detecting if a font is available.
|
||||
* @param {number=} timeout Optional timeout for giving up on font load detection and rejecting the promise (defaults to 3 seconds).
|
||||
* @return {Promise.<fontface.Observer>}
|
||||
*/
|
||||
Observer.prototype.load = function (text, timeout) {
|
||||
var that = this;
|
||||
var testString = text || 'BESbswy';
|
||||
var timeoutId = 0;
|
||||
var timeoutValue = timeout || Observer.DEFAULT_TIMEOUT;
|
||||
var start = that.getTime();
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (Observer.supportsNativeFontLoading() && !Observer.hasSafari10Bug()) {
|
||||
var loader = new Promise(function (resolve, reject) {
|
||||
var check = function () {
|
||||
var now = that.getTime();
|
||||
|
||||
if (now - start >= timeoutValue) {
|
||||
reject(new Error('' + timeoutValue + 'ms timeout exceeded'));
|
||||
} else {
|
||||
document.fonts.load(that.getStyle('"' + that['family'] + '"'), testString).then(function (fonts) {
|
||||
if (fonts.length >= 1) {
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(check, 25);
|
||||
}
|
||||
}, reject);
|
||||
}
|
||||
};
|
||||
check();
|
||||
});
|
||||
|
||||
var timer = new Promise(function (resolve, reject) {
|
||||
timeoutId = setTimeout(
|
||||
function() { reject(new Error('' + timeoutValue + 'ms timeout exceeded')); },
|
||||
timeoutValue
|
||||
);
|
||||
});
|
||||
|
||||
Promise.race([timer, loader]).then(function () {
|
||||
clearTimeout(timeoutId);
|
||||
resolve(that);
|
||||
}, reject);
|
||||
} else {
|
||||
dom.waitForBody(function () {
|
||||
var rulerA = new Ruler(testString);
|
||||
var rulerB = new Ruler(testString);
|
||||
var rulerC = new Ruler(testString);
|
||||
|
||||
var widthA = -1;
|
||||
var widthB = -1;
|
||||
var widthC = -1;
|
||||
|
||||
var fallbackWidthA = -1;
|
||||
var fallbackWidthB = -1;
|
||||
var fallbackWidthC = -1;
|
||||
|
||||
var container = dom.createElement('div');
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function removeContainer() {
|
||||
if (container.parentNode !== null) {
|
||||
dom.remove(container.parentNode, container);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* If metric compatible fonts are detected, one of the widths will be -1. This is
|
||||
* because a metric compatible font won't trigger a scroll event. We work around
|
||||
* this by considering a font loaded if at least two of the widths are the same.
|
||||
* Because we have three widths, this still prevents false positives.
|
||||
*
|
||||
* Cases:
|
||||
* 1) Font loads: both a, b and c are called and have the same value.
|
||||
* 2) Font fails to load: resize callback is never called and timeout happens.
|
||||
* 3) WebKit bug: both a, b and c are called and have the same value, but the
|
||||
* values are equal to one of the last resort fonts, we ignore this and
|
||||
* continue waiting until we get new values (or a timeout).
|
||||
*/
|
||||
function check() {
|
||||
if ((widthA != -1 && widthB != -1) || (widthA != -1 && widthC != -1) || (widthB != -1 && widthC != -1)) {
|
||||
if (widthA == widthB || widthA == widthC || widthB == widthC) {
|
||||
// All values are the same, so the browser has most likely loaded the web font
|
||||
|
||||
if (Observer.hasWebKitFallbackBug()) {
|
||||
// Except if the browser has the WebKit fallback bug, in which case we check to see if all
|
||||
// values are set to one of the last resort fonts.
|
||||
|
||||
if (((widthA == fallbackWidthA && widthB == fallbackWidthA && widthC == fallbackWidthA) ||
|
||||
(widthA == fallbackWidthB && widthB == fallbackWidthB && widthC == fallbackWidthB) ||
|
||||
(widthA == fallbackWidthC && widthB == fallbackWidthC && widthC == fallbackWidthC))) {
|
||||
// The width we got matches some of the known last resort fonts, so let's assume we're dealing with the last resort font.
|
||||
return;
|
||||
}
|
||||
}
|
||||
removeContainer();
|
||||
clearTimeout(timeoutId);
|
||||
resolve(that);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This ensures the scroll direction is correct.
|
||||
container.dir = 'ltr';
|
||||
|
||||
rulerA.setFont(that.getStyle('sans-serif'));
|
||||
rulerB.setFont(that.getStyle('serif'));
|
||||
rulerC.setFont(that.getStyle('monospace'));
|
||||
|
||||
dom.append(container, rulerA.getElement());
|
||||
dom.append(container, rulerB.getElement());
|
||||
dom.append(container, rulerC.getElement());
|
||||
|
||||
dom.append(document.body, container);
|
||||
|
||||
fallbackWidthA = rulerA.getWidth();
|
||||
fallbackWidthB = rulerB.getWidth();
|
||||
fallbackWidthC = rulerC.getWidth();
|
||||
|
||||
function checkForTimeout() {
|
||||
var now = that.getTime();
|
||||
|
||||
if (now - start >= timeoutValue) {
|
||||
removeContainer();
|
||||
reject(new Error('' + timeoutValue + 'ms timeout exceeded'));
|
||||
} else {
|
||||
var hidden = document['hidden'];
|
||||
if (hidden === true || hidden === undefined) {
|
||||
widthA = rulerA.getWidth();
|
||||
widthB = rulerB.getWidth();
|
||||
widthC = rulerC.getWidth();
|
||||
check();
|
||||
}
|
||||
timeoutId = setTimeout(checkForTimeout, 50);
|
||||
}
|
||||
}
|
||||
|
||||
checkForTimeout();
|
||||
|
||||
|
||||
rulerA.onResize(function (width) {
|
||||
widthA = width;
|
||||
check();
|
||||
});
|
||||
|
||||
rulerA.setFont(that.getStyle('"' + that['family'] + '",sans-serif'));
|
||||
|
||||
rulerB.onResize(function (width) {
|
||||
widthB = width;
|
||||
check();
|
||||
});
|
||||
|
||||
rulerB.setFont(that.getStyle('"' + that['family'] + '",serif'));
|
||||
|
||||
rulerC.onResize(function (width) {
|
||||
widthC = width;
|
||||
check();
|
||||
});
|
||||
|
||||
rulerC.setFont(that.getStyle('"' + that['family'] + '",monospace'));
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
130
node_modules/fontfaceobserver/src/ruler.js
generated
vendored
Normal file
130
node_modules/fontfaceobserver/src/ruler.js
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
goog.provide('fontface.Ruler');
|
||||
|
||||
goog.require('dom');
|
||||
|
||||
goog.scope(function () {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} text
|
||||
*/
|
||||
fontface.Ruler = function (text) {
|
||||
var style = 'max-width:none;' +
|
||||
'display:inline-block;' +
|
||||
'position:absolute;' +
|
||||
'height:100%;' +
|
||||
'width:100%;' +
|
||||
'overflow:scroll;' +
|
||||
'font-size:16px;';
|
||||
|
||||
this.element = dom.createElement('div');
|
||||
this.element.setAttribute('aria-hidden', 'true');
|
||||
|
||||
dom.append(this.element, dom.createText(text));
|
||||
|
||||
this.collapsible = dom.createElement('span');
|
||||
this.expandable = dom.createElement('span');
|
||||
this.collapsibleInner = dom.createElement('span');
|
||||
this.expandableInner = dom.createElement('span');
|
||||
|
||||
this.lastOffsetWidth = -1;
|
||||
|
||||
dom.style(this.collapsible, style);
|
||||
dom.style(this.expandable, style);
|
||||
dom.style(this.expandableInner, style);
|
||||
dom.style(this.collapsibleInner, 'display:inline-block;width:200%;height:200%;font-size:16px;max-width:none;');
|
||||
|
||||
dom.append(this.collapsible, this.collapsibleInner);
|
||||
dom.append(this.expandable, this.expandableInner);
|
||||
|
||||
dom.append(this.element, this.collapsible);
|
||||
dom.append(this.element, this.expandable);
|
||||
};
|
||||
|
||||
var Ruler = fontface.Ruler;
|
||||
|
||||
/**
|
||||
* @return {Element}
|
||||
*/
|
||||
Ruler.prototype.getElement = function () {
|
||||
return this.element;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} font
|
||||
*/
|
||||
Ruler.prototype.setFont = function (font) {
|
||||
dom.style(this.element, 'max-width:none;' +
|
||||
'min-width:20px;' +
|
||||
'min-height:20px;' +
|
||||
'display:inline-block;' +
|
||||
'overflow:hidden;' +
|
||||
'position:absolute;' +
|
||||
'width:auto;' +
|
||||
'margin:0;' +
|
||||
'padding:0;' +
|
||||
'top:-999px;' +
|
||||
'white-space:nowrap;' +
|
||||
'font-synthesis:none;' +
|
||||
'font:' + font + ';');
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
Ruler.prototype.getWidth = function () {
|
||||
return this.element.offsetWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} width
|
||||
*/
|
||||
Ruler.prototype.setWidth = function (width) {
|
||||
this.element.style.width = width + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
Ruler.prototype.reset = function () {
|
||||
var offsetWidth = this.getWidth(),
|
||||
width = offsetWidth + 100;
|
||||
|
||||
this.expandableInner.style.width = width + 'px';
|
||||
this.expandable.scrollLeft = width;
|
||||
this.collapsible.scrollLeft = this.collapsible.scrollWidth + 100;
|
||||
|
||||
if (this.lastOffsetWidth !== offsetWidth) {
|
||||
this.lastOffsetWidth = offsetWidth;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {function(number)} callback
|
||||
*/
|
||||
Ruler.prototype.onScroll = function (callback) {
|
||||
if (this.reset() && this.element.parentNode !== null) {
|
||||
callback(this.lastOffsetWidth);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function(number)} callback
|
||||
*/
|
||||
Ruler.prototype.onResize = function (callback) {
|
||||
var that = this;
|
||||
|
||||
function onScroll() {
|
||||
that.onScroll(callback);
|
||||
}
|
||||
|
||||
dom.addListener(this.collapsible, 'scroll', onScroll);
|
||||
dom.addListener(this.expandable, 'scroll', onScroll);
|
||||
this.reset();
|
||||
};
|
||||
});
|
Reference in New Issue
Block a user