steal-css
Version:
CSS plugin for StealJS
356 lines • 14.7 kB
JavaScript
/*[system-bundles-config]*/
System.bundles = {"bundles/main.css!":["folder/main.css!steal-css"]};
/*config.js*/
define('config.js', [
'require',
'exports',
'module',
'@steal'
], function (require, exports, module) {
var steal = require('@steal');
steal.config({
ext: { css: 'steal-css' },
paths: {
'bootstrap/*': 'folder/bootstrap/*',
'steal-css': '../../css.js',
'helpers': './helpers.js'
}
});
});
/*helpers*/
define('helpers', function (require, exports, module) {
exports.waitForCssRules = function (styleNode, callback) {
if (typeof callback !== 'function') {
throw new Error('No callback provided');
}
var poller = setInterval(function () {
var rulesLoaded = false;
try {
styleNode.sheet.cssRules;
rulesLoaded = true;
} catch (e) {
}
if (rulesLoaded) {
clearInterval(poller);
callback();
}
}, 10);
};
exports.poll = function poll(pred, timeout, interval) {
var pollInterval = interval || 100;
var endTime = Number(new Date()) + (timeout || 3000);
return new Promise(function (resolve, reject) {
if (pred())
return resolve();
var poller = setInterval(function () {
if (pred()) {
clearInterval(poller);
resolve();
} else if (Number(new Date()) >= endTime) {
clearInterval(poller);
reject(new Error('Timed out for ' + pred));
}
}, pollInterval);
});
};
});
/*steal-css*/
define('steal-css', [
'require',
'exports',
'module',
'@loader',
'@steal'
], function (require, exports, module) {
(function (global, require, exports, module) {
var loader = require('@loader');
var steal = require('@steal');
var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]';
var importRegEx = /@import [^uU]['"]?([^'"\)]*)['"]?/g;
var resourceRegEx = /url\(['"]?([^'"\)]*)['"]?\)/g;
var waitSeconds = loader.cssOptions && loader.cssOptions.timeout ? parseInt(loader.cssOptions.timeout, 10) : 60;
var onloadCss = function (link, cb) {
var styleSheets = getDocument().styleSheets, i = styleSheets.length;
while (i--) {
if (styleSheets[i].href === link.href) {
return cb();
}
}
setTimeout(function () {
onloadCss(link, cb);
});
};
function isIE9() {
var doc = getDocument();
return doc && !!Function('/*@cc_on return (/^9/.test(@_jscript_version) && /MSIE 9.0(?!.*IEMobile)/i.test(navigator.userAgent)); @*/')();
}
function getDocument() {
if (typeof doneSsr !== 'undefined' && doneSsr.globalDocument) {
return doneSsr.globalDocument;
}
if (typeof document !== 'undefined') {
return document;
}
throw new Error('Unable to load CSS in an environment without a document.');
}
function getHead() {
var doc = getDocument();
var head = doc.head || doc.getElementsByTagName('head')[0];
if (!head) {
var docEl = doc.documentElement || doc;
head = doc.createElement('head');
docEl.insertBefore(head, docEl.firstChild);
}
return head;
}
function CSSModule(load, loader) {
if (typeof load === 'object') {
this.load = load;
this.loader = loader;
this.address = this.load.address;
this.source = this.load.source;
} else {
this.address = load;
this.source = loader;
}
}
CSSModule.cssCount = 0;
CSSModule.ie9MaxStyleSheets = 31;
CSSModule.currentStyleSheet = null;
CSSModule.prototype = {
injectLink: function () {
if (this._loaded) {
return this._loaded;
}
if (this.linkExists()) {
this._loaded = Promise.resolve('');
return this._loaded;
}
var doc = getDocument();
var link = this.link = doc.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = this.address;
this._loaded = new Promise(function (resolve, reject) {
var timeout = setTimeout(function () {
reject('Unable to load CSS');
}, waitSeconds * 1000);
var loadCB = function (event) {
clearTimeout(timeout);
link.removeEventListener('load', loadCB);
link.removeEventListener('error', loadCB);
if (event && event.type === 'error') {
reject('Unable to load CSS');
} else {
resolve('');
}
};
if ('isApplicationInstalled' in navigator || !link.addEventListener) {
onloadCss(link, loadCB);
} else if (navigator.noUI) {
loadCB();
} else {
link.addEventListener('load', loadCB);
link.addEventListener('error', loadCB);
}
getHead().appendChild(link);
});
return this._loaded;
},
injectStyle: function () {
var doc = getDocument();
var head = getHead();
var style = this.style = doc.createElement('style');
style.type = 'text/css';
if (style.sheet) {
style.sheet.cssText = this.source;
} else if (style.styleSheet) {
style.styleSheet.cssText = this.source;
} else {
style.appendChild(doc.createTextNode(this.source));
}
head.appendChild(style);
},
ie9StyleSheetLimitHack: function () {
var doc = getDocument();
if (!CSSModule.cssCount) {
CSSModule.currentStyleSheet = doc.createStyleSheet();
}
CSSModule.cssCount += 1;
CSSModule.currentStyleSheet.cssText += this.source;
if (CSSModule.cssCount === CSSModule.ie9MaxStyleSheets) {
CSSModule.cssCount = 0;
}
},
updateURLs: function () {
var rawSource = this.source, address = this.address;
this.source = rawSource.replace(importRegEx, function (whole, part) {
if (isNode) {
return '@import url(' + part + ')';
} else {
return '@import url(' + steal.joinURIs(address, part) + ')';
}
});
if (!loader.isEnv('build')) {
this.source = this.source + '/*# sourceURL=' + address + ' */';
this.source = this.source.replace(resourceRegEx, function (whole, part) {
return 'url(' + steal.joinURIs(address, part) + ')';
});
}
return this.source;
},
getExistingNode: function () {
var doc = getDocument();
var selector = '[href=\'' + this.address + '\']';
return doc.querySelector && doc.querySelector(selector);
},
linkExists: function () {
var styleSheets = getDocument().styleSheets;
for (var i = 0; i < styleSheets.length; ++i) {
if (this.address === styleSheets[i].href) {
return true;
}
}
return false;
},
setupLiveReload: function (loader, name) {
var head = getHead();
var css = this;
if (loader.liveReloadInstalled) {
var cssReload = loader['import']('live-reload', { name: module.id });
Promise.resolve(cssReload).then(function (reload) {
loader['import'](name).then(function () {
reload.once('!dispose/' + name, function () {
css.style.__isDirty = true;
reload.once('!cycleComplete', function () {
head.removeChild(css.style);
});
});
});
});
}
}
};
if (loader.isEnv('production')) {
exports.fetch = function (load) {
var css = new CSSModule(load.address);
return css.injectLink();
};
} else {
exports.instantiate = function (load) {
var loader = this;
var css = new CSSModule(load.address, load.source);
load.source = css.updateURLs();
load.metadata.deps = [];
load.metadata.format = 'css';
load.metadata.execute = function () {
if (getDocument()) {
if (isIE9()) {
css.ie9StyleSheetLimitHack();
} else {
css.injectStyle();
}
css.setupLiveReload(loader, load.name);
}
return loader.newModule({ source: css.source });
};
};
}
exports.CSSModule = CSSModule;
exports.getDocument = getDocument;
exports.getHead = getHead;
exports.locateScheme = true;
exports.buildType = 'css';
exports.includeInBuild = true;
exports.pluginBuilder = 'steal-css/slim';
}(function () {
return this;
}(), require, exports, module));
});
/*main*/
define('main', [
'require',
'exports',
'module',
'@steal',
'helpers',
'./folder/main.css'
], function (require, exports, module) {
(function (global, require, exports, module) {
var steal = require('@steal');
var helpers = require('helpers');
require('./folder/main.css');
var testImage = function (selector) {
return new Promise(function (resolve, reject) {
var image = new Image();
image.onload = function () {
resolve();
};
image.onerror = function () {
reject(new Error('Cannot load ' + selector));
};
image.src = $(selector).css('background-image').replace(/url\("?/, '').replace(/"?\)/, '');
});
};
function waitForCssToBeApplied() {
return helpers.poll(function () {
var btn = $('.btn.btn-danger');
return btn.css('display') === 'inline-block' && btn.css('backgroundColor') === 'rgb(255, 0, 0)';
});
}
function log() {
var btn = $('.btn.btn-danger');
console.log('Button display: ', btn.css('display'));
console.log('Button backgroundColor: ', btn.css('backgroundColor'));
console.log('background-image', $('#test-element').css('background-image'));
console.log('tilde', $('#test-relative').css('background-image'));
}
if (steal.isEnv('production')) {
if (typeof window !== 'undefined' && window.assert) {
waitForCssToBeApplied().then(function () {
var btn = $('.btn.btn-danger');
assert.equal(btn.css('display'), 'inline-block', '@import "locate://"; styles applied');
assert.equal(btn.css('backgroundColor'), 'rgb(255, 0, 0)', '@import url("locate://"); styles applied');
}).then(function () {
return testImage('#test-element');
}).then(function () {
assert.ok(true, 'background-image: url(../); styles applied');
return testImage('#test-relative');
}).then(function () {
assert.ok(true, 'background-image: url(locate://); styles applied');
done();
}).catch(function (err) {
assert.ok(false, err);
done();
});
} else {
waitForCssToBeApplied().then(log);
}
} else {
helpers.waitForCssRules($('style')[0], function () {
if (typeof window !== 'undefined' && window.assert) {
waitForCssToBeApplied().then(function () {
var btn = $('.btn.btn-danger');
assert.equal(btn.css('display'), 'inline-block', '@import "locate://"; styles applied');
assert.equal(btn.css('backgroundColor'), 'rgb(255, 0, 0)', '@import url("locate://"); styles applied');
}).then(function () {
return testImage('#test-element');
}).then(function () {
assert.ok(true, 'background-image: url(../); styles applied');
return testImage('#test-relative');
}).then(function () {
assert.ok(true, 'background-image: url(locate://); styles applied');
done();
}).catch(function (err) {
assert.notOk(err, 'should not fail');
done();
});
} else {
waitForCssToBeApplied().then(log);
}
});
}
}(function () {
return this;
}(), require, exports, module));
});