Skip to content

Instantly share code, notes, and snippets.

@espretto
Created July 1, 2015 12:13
Show Gist options
  • Save espretto/532fd2de57c17a448fc4 to your computer and use it in GitHub Desktop.
Save espretto/532fd2de57c17a448fc4 to your computer and use it in GitHub Desktop.
JavaScript: requirejs-css-loader
/**
* amd plugin for loading css specifically for components that
* have a custom tag-name. the stylesheet has to include
* the css-property `cursor` with a value different from `auto` within a css-rule
* for the tag-name.
*
* the `display: block` property might have served well this purpose since it
* has to be set just like the html5shiv does. however, then again we might
* actually want a custom tag that is `display: inline` which is the default
* so there would be no telling if the rule applied or not.
*/
define([
'jquery',
'modernizr' // exports `Modernizr` and `html5`
], function ($) {
var createElement = (html5 || document).createElement,
readyEvents = 'load error readystatechange',
readyStates = {
'undefined': true,
complete: true,
loaded: true
};
/**
* simply insert link element with the given url
*/
function getStyleSheet (url, callback) {
var linkNode = createElement('LINK');
$(linkNode)
.attr({
href: url,
rel: 'stylesheet',
type: 'text/css'
})
.on(readyEvents, function () {
var link = this;
if (readyStates[link.readyState]) {
$(link).off(readyEvents);
callback();
}
})
.appendTo('head');
}
/**
* create an element with the custom tag-name and
* poll it's css-property `content` for a value different from `none`.
*
* stop polling on timeout. no need to throw an error,
* requirejs will do so for us.
*/
function pollUntilApplied (tagName, timeLimit, callback) {
var elem = createElement(tagName),
$elem = $(elem).appendTo('body');
(function poll () {
if ($elem.css('cursor') !== 'auto') {
$elem.remove();
callback();
} else if ($.now() < timeLimit) {
setTimeout(poll, 50);
}
}());
}
/**
* main: requirejs descriptor for this plugin
*/
return {
// TODO inline css on build with useful data-attributes
load: function(name, req, onLoad, config) {
// avoid error on build
if (config.isBuild) return onLoad(null);
var // pass this down to stop polling after timeout
timeLimit = $.now() + config.waitSeconds*1e3,
url = req.toUrl(name),
// extract the tag-name parameter
parts = url.split('!'),
tagName = parts.length > 1 ? parts.pop() : false;
// rejoin the url
url = parts.join('!');
getStyleSheet(url, function () {
if (tagName) {
pollUntilApplied(tagName, timeLimit, onLoad);
} else {
onLoad();
}
});
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment