define(['dojo/json', 'build/fs', 'build/fileUtils', 'build/transforms/writeAmd', '../build'],
|
function(json, fs, fileUtils, writeAmd, buildModule){
|
var targetStylesheet;
|
return {
|
start:function(
|
mid,
|
referenceModule,
|
bc
|
){
|
// mid may contain a pragma (e.g. "!strip"); remove
|
mid = mid.split("!")[0];
|
var cssPlugin = bc.amdResources["xstyle/css"],
|
stylesheetInfo = bc.getSrcModuleInfo(mid, referenceModule, true),
|
cssResource = bc.resources[stylesheetInfo.url],
|
xstyleModuleInfo = bc.getSrcModuleInfo("xstyle/core/parser", referenceModule, true),
|
xstyleText = fs.readFileSync(xstyleModuleInfo.url + '.js', "utf8"),
|
xstyleProcess = buildModule(xstyleText);
|
|
function processStylesheetLayers(){
|
// build all the target stylesheets from the layers
|
if(!bc.processedStylesheets){
|
bc.processedStylesheets = true;
|
for(var i in bc.layers){
|
var layer = bc.layers[i];
|
targetStylesheet = layer.targetStylesheet;
|
if(targetStylesheet){
|
// we want to calculate the target stylesheet relative to the layer
|
var layerModule = layer.name && bc.getSrcModuleInfo(layer.name);
|
var moduleInfo = bc.getSrcModuleInfo(targetStylesheet, layerModule, true);
|
var targetStylesheetModule = bc.resources[moduleInfo.url];
|
var targetDestStylesheetModule = bc.getDestModuleInfo(targetStylesheet, null, true);
|
var targetStylesheetUrl = bc.currentTargetStylesheetUrl = moduleInfo.url;
|
var targetDestStylesheetUrl = targetDestStylesheetModule.url;
|
// initialize the target stylesheet
|
var targetStylesheetContents = '';
|
try{
|
if(targetStylesheetModule){
|
targetStylesheetContents = processCss(targetStylesheetModule).standardCss;
|
}else{
|
targetStylesheetModule = moduleInfo;
|
}
|
var moduleSet = writeAmd.computeLayerContents({mid:'stylesheet-process' + i}, layer.include, layer.exclude);
|
var targetResource;
|
for (var i in moduleSet) {
|
var module = moduleSet[i];
|
if(module.getCss){
|
if(module.mid == targetStylesheetModule.mid) {
|
// probably not necessary to assign this anymore
|
targetResource = module;
|
// if it is the target stylesheet, the contents are already included
|
}else{
|
targetStylesheetContents += module.getCss();
|
}
|
}
|
}
|
if(targetResource){
|
var loadIndicator = '#' + targetResource.module.mid.replace(/\//g,'-').replace(/\..*/,'')
|
+ '-loaded{display:none}';
|
targetStylesheetContents += loadIndicator;
|
targetResource.module.originalCss = targetResource.module.text;
|
targetResource.isTargetStylesheet = true;
|
}
|
targetStylesheetModule.isTargetStylesheet = true;
|
targetStylesheetModule.originalCss = targetStylesheetModule.text;
|
targetStylesheetModule.text = targetStylesheetContents;
|
|
var url = targetDestStylesheetUrl.replace(/\/x$/,'');
|
|
fileUtils.ensureDirectoryByFilename(url);
|
fs.writeFileSync(url, targetStylesheetContents);
|
}catch(e){
|
console.error('error creating css layer', e.stack || e);
|
}
|
bc.currentTargetStylesheetUrl = targetStylesheetUrl = null;
|
}
|
}
|
}
|
}
|
if(targetStylesheet){
|
}else{
|
// there is no targe stylesheet, so
|
// we will be directly inlining the stylesheet in the layer, so we need the createStyleSheet module
|
var createStyleSheetModule = bc.getSrcModuleInfo('xstyle/core/load-css', referenceModule);
|
}
|
// read the stylesheet so we can process
|
//var text= fs.readFileSync(stylesheetInfo.src, "utf8");
|
|
if (!cssPlugin){
|
throw new Error("text! plugin missing");
|
}
|
if (!cssResource){
|
throw new Error("text resource (" + stylesheetInfo.url + ") missing");
|
}
|
|
var result = [cssPlugin];
|
if(createStyleSheetModule){
|
// if we are inlining the stylesheet, we need the functionality to insert a stylesheet from text
|
result.push(bc.amdResources['xstyle/core/load-css']);
|
}
|
if(bc.internStrings && !bc.internSkip(stylesheetInfo.mid, referenceModule)){
|
// or inline it
|
result.push({
|
module:cssResource,
|
pid:stylesheetInfo.pid,
|
mid:stylesheetInfo.mid,
|
deps:[],
|
getText:function(){
|
var processed = this.processed = processCss(this.module, true);//stylesheetInfo.url, // inline resources too
|
return processed.xstyleCss ?
|
json.stringify({
|
cssText: processed.standardCss,
|
xCss: processed.xstyleCss
|
}) :
|
json.stringify(processed.standardCss +"");
|
},
|
getCss: function(){
|
this.cssRetrieved = true;
|
return processCss(this.module).standardCss;//, targetStylesheetUrl);
|
},
|
internStrings: function(){
|
processStylesheetLayers();
|
if(this.isTargetStylesheet){
|
// a target stylesheet, this should go through the xstyle loader
|
// to ensure it is actually loaded
|
return ['', '0'];
|
}
|
if(this.cssRetrieved){
|
// the CSS has been written to a stylesheet, we intern an indicator that
|
// it has already been loaded
|
return ['url:' + this.mid, '{}'];
|
}
|
// it hasn't been written to a target stylesheet, so it needs to actually be inlined
|
return ['url:' + this.mid, this.getText()];
|
}
|
});
|
}
|
function processCss(module, inlineAllResource){
|
var text = module.originalCss || module.getText ? module.getText() : module.text;
|
if(text===undefined){
|
// the module likely did not go through the read transform; therefore, just read it manually
|
text= fs.readFileSync(module.src, "utf8");
|
}
|
try{
|
var processed = xstyleProcess(text, bc.currentTargetStylesheetUrl || module.src, module.src, inlineAllResource);
|
//for(var i = 0; i < processed.requiredModules.length; i++){
|
// TODO: at some point, we may add an option to include the modules that
|
// are required by the stylesheet, but at least by default these should
|
// probably be async lazy loaded
|
//}
|
}catch(e){
|
console.error('Error processing CSS', e.stack || e);
|
processed = {standardCss: text};
|
}
|
return processed;
|
}
|
return result;
|
}
|
};
|
});
|