-
-
Save baamenabar/614720635f10b5921f32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Localstorage for webfonts | |
* WIP | |
* | |
* This file should me minified/uglified and injected directly on the head. | |
* also absolute path to the static server should be used for the css files that get ajaxed. | |
*/ | |
(function () { | |
'use strict'; | |
// once cached, the css file is stored on the client forever unless | |
// the URL below is changed. Any change will invalidate the cache | |
modifier += withSecondaryFont ? '.secondary' : ''; | |
// We should add absolute path to static server. | |
var pathFallback = '/fonts/primary' + modifier + '.fallback.css'; | |
var pathWoff = '/fonts/primary' + modifier + '.woff.css'; | |
var pathWoff2 = '/fonts/primary' + modifier + '.woff2.css?v=2'; | |
var css_href = pathWoff; | |
// a simple event handler wrapper | |
function on(el, ev, callback) { | |
if (el.addEventListener) { | |
el.addEventListener(ev, callback, false); | |
} else if (el.attachEvent) { | |
el.attachEvent('on' + ev, callback); | |
} | |
} | |
function off (el, ev, callback) { | |
if(el.removeEventListener) { | |
el.removeEventListener(ev, callback); | |
} else if (el.detachEvent) { | |
el.detachEvent(''); | |
} | |
} | |
// if we have the fonts in localStorage or if we've cached them using the native browser cache | |
if ((window.localStorage && localStorage.font_css_cache) || document.cookie.indexOf('font_css_cache') > -1){ | |
// just use the cached version | |
//console.log('apparently we have a cashed font'); | |
injectFontsStylesheet(); | |
} else { | |
//console.log('we will wait for a load event'); | |
// otherwise, don't block the loading of the page; wait until it's done. | |
on(window, 'load', injectFontsStylesheet); | |
on(window, 'DOMContentLoaded', function() { | |
injectFontsStylesheet(); | |
off(window, 'load', injectFontsStylesheet); | |
}); | |
} | |
// Injecting a reference to the most basic file. | |
function injectPlainLinkedStylesheet () { | |
var stylesheet = document.createElement('link'); | |
css_href = pathFallback; | |
stylesheet.href = css_href; | |
stylesheet.rel = 'stylesheet'; | |
stylesheet.type = 'text/css'; | |
document.getElementsByTagName('head')[0].appendChild(stylesheet); | |
// just use the native browser cache | |
// this requires a good expires header on the server | |
document.cookie = 'font_css_cache'; | |
} | |
// quick way to determine whether a css file has been cached locally | |
function fileIsCached(href) { | |
return window.localStorage && localStorage.font_css_cache && (localStorage.font_css_cache_file === href); | |
} | |
// time to get the actual css file | |
function injectFontsStylesheet() { | |
// if this is an older browser | |
if (!window.localStorage || !window.XMLHttpRequest) { | |
injectPlainLinkedStylesheet(); | |
// if this isn't an old browser | |
} else { | |
//console.log('new browser, starting to inject'); | |
// use the cached version if we already have it | |
var supportsWoff2 = (function(){ | |
if( !( "FontFace" in window ) ) { | |
return false; | |
} | |
var f = new window.FontFace( 't', 'url( "data:application/font-woff2," ) format( "woff2" )', {} ); | |
f.load().catch(function() {}); | |
return f.status == 'loading'; | |
})(); | |
// if we have woff2 support load the woff2 file | |
if (supportsWoff2) { | |
//console.log('we DO support woff2'); | |
css_href = pathWoff2; | |
} | |
if (fileIsCached(css_href)) { | |
//console.log('we have valid cashed version'); | |
injectRawStyle(localStorage.font_css_cache); | |
// otherwise, load it with ajax | |
} else { | |
//console.log('we do not have a cashed css @ff'); | |
// check if we have support for woff2 :@see https://github.com/filamentgroup/woff2-feature-test | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', css_href, true); | |
// cater for IE8 which does not support addEventListener or attachEvent on XMLHttpRequest | |
xhr.onreadystatechange = function () { | |
if(xhr.readyState === 4){ | |
if (xhr.status === 200) { | |
//console.log('we have an answr from xhr'); | |
// once we have the content, quickly inject the css rules | |
injectRawStyle(xhr.responseText); | |
// and cache the text content for further use | |
// notice that this overwrites anything that might have already been previously cached | |
localStorage.font_css_cache = xhr.responseText; | |
localStorage.font_css_cache_file = css_href; | |
// if for whatever reason we get an error | |
} else { | |
injectPlainLinkedStylesheet(); | |
} | |
} | |
}; | |
xhr.addEventListener('error', injectPlainLinkedStylesheet, false); | |
xhr.addEventListener('abort', injectPlainLinkedStylesheet, false); | |
xhr.send(); | |
} | |
} | |
} | |
// this is the simple utitily that injects the cached or loaded css text | |
function injectRawStyle(text) { | |
//console.log('injecting raw style') | |
var style = document.createElement('style'); | |
// cater for IE8 which doesn't support style.innerHTML | |
style.setAttribute('type', 'text/css'); | |
// add the style element to the DOM before adding styles to it or IE8 will crash | |
document.getElementsByTagName('head')[0].appendChild(style); | |
if (style.styleSheet) { | |
style.styleSheet.cssText = text; | |
} else { | |
style.innerHTML = text; | |
} | |
// add the class so the new fonts get applied | |
//console.log('inserted on the head'); | |
} | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment