Skip to content

Instantly share code, notes, and snippets.

@iwyg
Created April 9, 2011 13:55
Show Gist options
  • Save iwyg/911409 to your computer and use it in GitHub Desktop.
Save iwyg/911409 to your computer and use it in GitHub Desktop.
Fetches all css stylesheets and extracts all image urls. Comes in handy when you want to preload your css asstets. See implementation for usage instructions.
/**
* ===================================================================================
* @name CssImageCollect
* @version 1
* @description a javascript css-image preloader
* @author Thomas Appel, mail(at)thomas-appel(dot)com
*
* released under the MIT licence
* copyright © 2011 Thomas Appel, thomas-appel.com
*
* changelog:
* ===================================================================================
* -
* ===================================================================================
*
* options:
* ===================================================================================
* turbo : bool // well, as it says.
* preload : bool // you can disable preloading and just return an image array
*
* examples:
* ===================================================================================
* see implementation.js
* ===================================================================================
*/
(function( global ){
/*
if ( !global.document.styleSheets ) {
return false;
}
*/
if ( !Object.create ) {
Object.prototype.create = function( o ) {
var F = function(){};
F.prototype = o;
return new F();
};
}
var CssImageCollect = (function(){
var that, sheets = [];
function objectExtend( o, ref ) {
var i;
for ( i in ref ) {
// no additional methods and properties may be passed to the original Object
if ( o.hasOwnProperty(i) && ref.hasOwnProperty(i) ) {
o[i] = ref[i];
}
}
}
/*
* NOTE ON $MSIE
* ===================================================================================
* MSIE messes up the DOM css href property output of imported stylesheets.
* it includes styles correctly though, but here we have to "create" the real path,
* assuming the parent stylesheet's path is correct as it was direclty pulled from the
* first level document.styleSheet-Object, and thus should be a valid path.
* ===================================================================================
*/
function arrayObj ( input ) {
var cssPath = input.owningElement && input.owningElement.href ?
input.owningElement.href :
input.href,
this_url = cssPath ? cssPath.replace(/[^\/]+\.(css.*)/,'') : null,
obj = {
sheet:input,
href:this_url
};
return obj;
}
function getSheets ( input, arr, i, arg ) {
var self = this,
this_rules,
is_msie = input[0] ? input[0].rules : null,
this_sheets,
this_sheets_rules,
this_import_rules;
while ( i-- ) {
this_rules = input[i].cssRules || input[i].rules;
if (!!this_rules){
!!input[i].href && arr.push( arrayObj( input[i] ) );
this_import_rules = this_rules;
getSheets.call( this,this_import_rules,arr, this._max( this_import_rules.length ) );
this_sheets = null;
}
try {
this_sheets = input[i].styleSheet || input[i].imports;
if ( !!this_sheets ){
this_sheets_rules = this_sheets.cssRules || this_sheets;
// dont push if is MSIE
!is_msie && arr.push( arrayObj( this_sheets ) );
getSheets.call( this, this_sheets_rules, arr, this._max( this_sheets_rules.length ) );
}
}
catch(e){
window.console && console.warn(e);
}
}
return arr;
}
function imPath( im, rules, i ){
if (! !!im[0].match(/^(http|https|ftp|file|):\/\/.*?/)){ // external URL
im = rules[i].href + im[0];
} else {
im = im[0];
}
return im;
}
function uniqueArray( ar ) {
var sorter, out, len, i, j;
if( ar.length && typeof ar!=='string') {
sorter = {};out = [];
len = ar.length;
j=len;
for(i=0;i<j;i++) {
if( !sorter[ar[i]+typeof ar[i]] ) {
out.push(ar[i]);
sorter[ar[i]+typeof ar[i]] = true;
}
}
}
return out || ar;
}
that = Object.create( {
indexSheets : function() {
return getSheets.apply( this, [ global.document.styleSheets, sheets, global.document.styleSheets.length ] );
},
getSheets : function() {
return sheets;
},
getCssImageURLs : function( raw ) {
var im,cssText,
i, j, regex = /[^\"\(\)]+\.(gif|jpg|jpeg|png|svg|bmp)/g,
images=[],
rules = sheets,
style_rules;
/*
* ===================================================================================
* actually we don't have to care about relative paths
* we just need the rel path, e.g. webkit, etc. prints out the complete path;
* so, if the complete path matches the out location, shorten it
* ===================================================================================
*/
i = rules.length;
while (i--){
style_rules = rules[i].sheet.cssRules ? rules[i].sheet.cssRules :rules[i].sheet.rules; //msie fallback, note: also safari can handle the 'rules' property
j = style_rules.length;
while (j--){
cssText = style_rules[j].cssText ? style_rules[j].cssText :style_rules[j].style.cssText;
if (cssText.match(/base64/)){continue;}
im = cssText.match( regex );
if (im) {
im = imPath( im, rules, i );
images.push( im );
im = null;
}
}
}
return raw ? images : uniqueArray( images );
},
_max : function( len ){
return this.settings.turbo ? Math.min( len , 20 ) : len;
}
});
return function ( options ) {
var self = that, arr = [],
temp_src;
that.settings = {
turbo : false
}
// extend settings with user options
objectExtend( that.settings, options );
that.indexSheets();
return that;
}
}());
if ( !global.TA ) {
global.TA = {};
}
if ( !global.TA.UTILS ) {
global.TA.UTILS = {};
}
global.TA.UTILS.CssImageCollect = CssImageCollect;
}( this ));
/**
* CssImageCollect can be called with an optional configuration literal
* which takes one property called 'turbo'
* Set 'turbo' to true, if you want CssImageCollect to search
* only the first 20 rules of each stylesheet for @import rules
*/
var cssAssets = TA.UTILS.CssImageCollect({
turbo:true
});
/**
* returns all image paths found in stylesheets as an javascript array
* set argument to true, if you don't want to return a unified array
*/
cssAssets.getCssImageURLs( true );
/**
* returns all css stylesheet objects in an javascript array
*/
cssAssets.getSheets( );
/**
* re-indexes all stylesheets
*/
cssAssets.indexSheets( );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment