UNPKG

curl-amd

Version:

curl.js is small, fast, extensible module loader that handles AMD, CommonJS Modules/1.1, CSS, HTML/text, and legacy scripts.

151 lines (122 loc) 3.48 kB
/** MIT License (c) copyright 2010-2013 B Cavalier & J Hann */ /** * curl style! plugin */ define([], function () { var nonRelUrlRe, findUrlRx, undef, doc, head; if (typeof window != 'undefined') { doc = window.document; head = doc.head || doc.getElementsByTagName('head')[0]; } // tests for absolute urls and root-relative urls nonRelUrlRe = /^\/|^[^:]*:\/\//; // Note: this will fail if there are parentheses in the url findUrlRx = /url\s*\(['"]?([^'"\)]*)['"]?\)/g; function translateUrls (cssText, baseUrl) { return cssText.replace(findUrlRx, function (all, url) { return 'url("' + translateUrl(url, baseUrl) + '")'; }); } function translateUrl (url, parentPath) { // if this is a relative url if (!nonRelUrlRe.test(url)) { // append path onto it url = parentPath + url; } return url; } /***** style element functions *****/ var currentStyle, callbacks = []; function createStyle (cssText, callback, errback) { try { clearTimeout(createStyle.debouncer); if (createStyle.accum) { createStyle.accum.push(cssText); } else { createStyle.accum = [cssText]; currentStyle = doc.createStyleSheet ? doc.createStyleSheet() : head.appendChild(doc.createElement('style')); } callbacks.push({ callback: callback, errback: errback, sheet: currentStyle }); createStyle.debouncer = setTimeout(function () { var style, allCssText, err; try { style = currentStyle; currentStyle = undef; allCssText = createStyle.accum.join('\n'); createStyle.accum = undef; // for safari which chokes on @charset "UTF-8"; // TODO: see if Safari 5.x and up still complain allCssText = allCssText.replace(/.+charset[^;]+;/g, ''); // IE 6-8 won't accept the W3C method for inserting css text 'cssText' in style ? style.cssText = allCssText : style.appendChild(doc.createTextNode(allCssText)); } catch (ex) { err = ex; // just notify most recent errback. no need to spam errback(ex); } if (!err) waitForDocumentComplete(notify); }, 0); } catch (ex) { errback(ex); } } function notify () { var list = callbacks; callbacks = []; for (var i = 0, len = list.length; i < len; i++) { list[i].callback(list[i].sheet); } } /** * Keep checking for the document readyState to be "complete" since * Chrome doesn't apply the styles to the document until that time. * If we return before readyState == 'complete', Chrome may not have * applied the styles, yet. * Chrome only. * @private * @param cb */ function waitForDocumentComplete (cb) { // this isn't exactly the same as domReady (when dom can be // manipulated). it's later (when styles are applied). // chrome needs this (and opera?) function complete () { if (isDocumentComplete()) { cb(); } else { setTimeout(complete, 10); } } complete(); } /** * Returns true if the documents' readyState == 'complete' or the * document doesn't implement readyState. * Chrome only. * @private * @return {Boolean} */ function isDocumentComplete () { return !doc.readyState || doc.readyState == 'complete'; } createStyle.load = function (absId, req, loaded, config) { // get css text req([absId], function (cssText) { // TODO: translate urls? createStyle(cssText, loaded, loaded.error); }); }; createStyle.translateUrls = translateUrls; return createStyle; });