Created
July 1, 2015 12:13
-
-
Save espretto/532fd2de57c17a448fc4 to your computer and use it in GitHub Desktop.
JavaScript: requirejs-css-loader
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
/** | |
* 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