Skip to content

Instantly share code, notes, and snippets.

@baamenabar
Forked from frontendbeast/sm-annotated.html
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baamenabar/614720635f10b5921f32 to your computer and use it in GitHub Desktop.
Save baamenabar/614720635f10b5921f32 to your computer and use it in GitHub Desktop.
/**
* 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