Permalink
Browse files

Merge pull request #1278 from SergioCrisostomo/cssAssets

add onLoad callback for cross-origin CSS assets
  • Loading branch information...
anutron committed Jul 29, 2014
2 parents 6d07f3a + e5f81bf commit d0d5712cb918948cd18ae4672f51f1556a0b47ed
Showing with 74 additions and 34 deletions.
  1. +2 −0 Docs/Utilities/Assets.md
  2. +1 −0 Gruntfile.js
  3. +29 −11 Source/Utilities/Assets.js
  4. +42 −23 Specs/Utilities/Assets.js
View
@@ -52,6 +52,8 @@ Injects a css file in the page.
1. source - (*string*) The path of the CSS file.
2. properties - (*object*) Some additional attributes you might want to add to the link Element; this is the same as the second argument you might pass to including the Element constructor. For instance you might specify a title attribute or perhaps an id.
- onLoad - (*function*) A function that will be invoked when the CSS is loaded.
- timeout - (*number*, defaults to 3000 ms) The maximum amount of milliseconds to wait for onLoad callback to be called.
- document - (*object*, defaults to `document`) The document which the link element should be injected in.
View
@@ -82,6 +82,7 @@ module.exports = function(grunt) {
options: {
captureTimeout: 60000 * 2,
browserNoActivityTimeout: 20000,
singleRun: true,
frameworks: ['jasmine', 'sinon'],
files: [
View
@@ -50,22 +50,40 @@ var Asset = {
css: function(source, properties){
if (!properties) properties = {};
var load = properties.onload || properties.onLoad,
doc = properties.document || document,
timeout = properties.timeout || 3000;
['onload', 'onLoad', 'document'].each(function(prop){
delete properties[prop];
});
var link = new Element('link', {
type: 'text/css',
rel: 'stylesheet',
media: 'screen',
type: 'text/css',
href: source
});
var load = properties.onload || properties.onLoad,
doc = properties.document || document;
delete properties.onload;
delete properties.onLoad;
delete properties.document;
}).setProperties(properties).inject(doc.head);
if (load) link.addEvent('load', load);
return link.set(properties).inject(doc.head);
if (load){
// based on article at http://www.yearofmoo.com/2011/03/cross-browser-stylesheet-preloading.html
var loaded = false, retries = 0;
var check = function(){
var stylesheets = document.styleSheets;
for (var i = 0; i < stylesheets.length; i++){
var file = stylesheets[i];
var owner = file.ownerNode ? file.ownerNode : file.owningElement;
if (owner && owner == link){
loaded = true;
return load.call(link);
}
}
retries++;
if (!loaded && retries < timeout / 50) return setTimeout(check, 50);
}
setTimeout(check, 0);
}
return link;
},
image: function(source, properties){
View
@@ -20,7 +20,7 @@ describe('Assets', function(){
}
});
waits(500);
waits(800);
runs(function(){
expect(myScript.get('tag')).toEqual('script');
@@ -31,35 +31,59 @@ describe('Assets', function(){
});
});
});
describe('Assets.css', function(){
it('should load a css file and fire the load event', function(){
var load = jasmine.createSpy('load');
function addCSS(source, load){
new Element('div', {
id: 'moologo'
}).inject($(document.body));
var myCSS = Asset.css('base/Tests/Specs/assets/Assets.css.test.css', {
return myCSS = Asset.css(source, {
id: 'myStyle',
title: 'myStyle',
onload: function(){
onLoad: function(){
load(this);
}
});
}
afterEach(function(){
$('myStyle').destroy();
$('moologo').destroy();
});
waits(500);
it('should load a external css file and run load callback', function(){
var load = jasmine.createSpy('load');
var url = 'https://rawgit.com/mootools/mootools-more/master/Tests/Specs/assets/Assets.css.test.css';
var myCSS = addCSS(url, load);
var myCSS = addCSS(url, load);
waits(3000);
runs(function(){
expect(myCSS.get('tag')).toEqual('link');
expect(myCSS.id).toEqual('myStyle');
// Current implementation of assets uses the load event which only works in IE/Opera
// expect(load).toHaveBeenCalledWith(myCSS);
myCSS.destroy();
expect(load).toHaveBeenCalledWith(myCSS);
load = myCSS = null;
});
});
it('should load a local css file and run load callback', function(){
var load = jasmine.createSpy('load');
var url = 'base/Tests/Specs/assets/Assets.css.test.css';
var myCSS = addCSS(url, load);
waits(2000);
runs(function(){
var border = $('moologo').getStyle('border');
expect(load).toHaveBeenCalledWith(myCSS);
expect(myCSS.get('tag')).toEqual('link');
expect(myCSS.id).toEqual('myStyle');
expect(border.contains('4px solid')).toBeTruthy();
load = myCSS = null;
});
});
});
describe('Assets.image', function(){
@@ -74,7 +98,7 @@ describe('Assets', function(){
onload: load
});
waits(500);
waits(800);
runs(function(){
expect(myImage.get('tag')).toEqual('img');
@@ -97,7 +121,7 @@ describe('Assets', function(){
onerror: error
});
waits(500);
waits(800);
runs(function(){
expect(load).not.toHaveBeenCalled();
@@ -122,7 +146,7 @@ describe('Assets', function(){
onload: loaded
});
waits(500);
waits(800);
runs(function(){
expect(loadedagain).toHaveBeenCalled();
@@ -141,16 +165,14 @@ describe('Assets', function(){
onerror: error
});
waits(500);
waits(800);
runs(function(){
expect(load).not.toHaveBeenCalled();
expect(error).toHaveBeenCalledWith(myImage);
myImage.destroy();
});
});
});
describe('Assets.images', function(){
@@ -170,7 +192,7 @@ describe('Assets', function(){
onError: error
});
waits(500);
waits(800);
runs(function(){
expect(complete).toHaveBeenCalled();
@@ -196,16 +218,13 @@ describe('Assets', function(){
onError: error
});
waits(500);
waits(800);
runs(function(){
expect(complete).toHaveBeenCalled();
expect(progress.callCount).toEqual(1);
expect(error.callCount).toEqual(2);
});
});
});
});

0 comments on commit d0d5712

Please sign in to comment.