Skip to content

Instantly share code, notes, and snippets.

@StanAngeloff
Created July 1, 2010 10:13
Show Gist options
  • Save StanAngeloff/459802 to your computer and use it in GitHub Desktop.
Save StanAngeloff/459802 to your computer and use it in GitHub Desktop.
(function() {
/*****************************************************************************
* *
* EDIT CONSTANTS BELOW TO MATCH YOUR MACHINE SETUP *
* *
* Cygwin 1.7 and Ruby must be installed first (install using setup-1.7.exe) *
* Unix machines DO NOT need Cygwin. Instead use /usr/bin as CYGWIN_PATH *
* *
* To install Sass, follow instructions here first: *
* http://www.cygwin.com/ml/cygwin/2007-05/msg00439.html *
* Start Cygwin and run: *
* > gem install haml *
* *
* To install CoffeeScript: *
* > git clone git://github.com/jashkenas/coffee-script.git *
* *
* `java` executable is recommended to be on `PATH`, however you can specify *
* a full path below. *
* *
* Remember to escape \ as \\ on Windows. *
* *
****************************************************************************/
// Download from http://www.java.com/en/download/manual.jsp
const JAVA_PATH = 'C:\\Program Files (x86)\\Java\\jre6\\bin\\javaw.exe';
// Download from http://yuilibrary.com/downloads/#yuicompressor
const YUI_PATH = 'D:\\Workspace\\assets\\3rdparty\\yuicompressor-2.4.2.jar';
// Download from http://closure-compiler.googlecode.com/files/compiler-latest.zip
const CLOSURE_COMPILER_PATH = 'D:\\Workspace\\assets\\3rdparty\\compiler.jar';
// Download from http://cygwin.com/setup-1.7.exe
const CYGWIN_PATH = 'C:\\bin\\cygwin\\';
// Download from http://github.com/jashkenas/coffee-script/
const COFFEE_SCRIPT_PATH = 'D:\\Workspace\\public\\coffee-script\\';
// Configure mappings between file extension and compiler (optionally, chain of compilers)
const COMPILER_MAP = {
'.uncompressed.css': ['yui-css', '.css'],
'.unprocessed.css': ['yui-css', '.css'],
'.uncompressed.js': ['closure-compiler-js', '.js'],
'.unprocessed.js': ['closure-compiler-js', '.js'],
'.jssrc': ['closure-compiler-js', '.js'],
'.sass': ['sass', '.css'],
'.scss': ['sass', '.css'],
'.coffee': ['coffee', '.js']
};
// Configure overrides per project
const PROJECT_MAP = {
'myBP online': { 'sass.style': 'compressed' },
'National Box Office': { 'sass.style': 'compressed' },
'HTML Toolkit': { 'coffee.noWrap': false }
}
/** DON'T EDIT PAST THIS LINE ***********************************************/
const Cc = Components.classes;
const Ci = Components.interfaces;
var loaderService = Cc['@mozilla.org/moz/jssubscript-loader;1'].getService(Ci.mozIJSSubScriptLoader);
var Compiler = {};
Compiler.require = function(scriptName, scriptPath) {
loaderService.loadSubScript('file:///' + scriptPath + scriptName);
};
Compiler.Coffee = function(inputContents, options) {
Compiler.require('lib/helpers.js', COFFEE_SCRIPT_PATH);
Compiler.require('lib/rewriter.js', COFFEE_SCRIPT_PATH);
Compiler.require('lib/lexer.js', COFFEE_SCRIPT_PATH);
Compiler.require('lib/parser.js', COFFEE_SCRIPT_PATH);
Compiler.require('lib/scope.js', COFFEE_SCRIPT_PATH);
Compiler.require('lib/nodes.js', COFFEE_SCRIPT_PATH);
Compiler.require('lib/coffee-script.js', COFFEE_SCRIPT_PATH);
compileOptions = {};
compileOptions.no_wrap = (options && 'coffee.noWrap' in options ? options['coffee.noWrap'] : true);
return CoffeeScript.compile(inputContents, compileOptions);
};
const supportedCompilers = {
'yui-css': ['"' + JAVA_PATH + '" -jar "' + YUI_PATH + '" --charset utf-8 -v --type=css -o "{outpath}" "{inpath}"'],
'yui-js': ['"' + JAVA_PATH + '" -jar "' + YUI_PATH + '" --charset utf-8 -v --type=js -o "{outpath}" "{inpath}"'],
'closure-compiler-js': ['"' + JAVA_PATH + '" -jar "' + CLOSURE_COMPILER_PATH + '" --js "{inpath}" --js_output_file "{outpath}"'],
'sass': ['"' + CYGWIN_PATH + 'bin\\sass" --trace --style={$sass.style|extended} "{infile}" > "{outfile}"',
'PATH=' + CYGWIN_PATH + 'bin;' + CYGWIN_PATH + 'lib\nCYGWIN=nodosfilewarning'],
'coffee': [Compiler.Coffee]
};
if (typeof (extensions) === 'undefined')
window.extensions = {};
if (typeof (window.extensions.compileObserver) === 'undefined')
window.extensions.compileObserver = null;
window.extensions.compileInputBaseName = null;
const INDEX_COMMAND_LINE = 0;
const INDEX_ENVIRONMENT = 1;
const INDEX_COMPILER = 0;
const INDEX_FILE_EXTENSION = 1;
var observerService = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
function ProcessObserver(command, process, callback) {
this._command = command;
this._process = process;
this._callback = (callback || function() {});
observerService.addObserver(this, 'run_terminated', false);
try {
this._process.wait(0);
this.cleanUp();
} catch (exception) {};
};
ProcessObserver.prototype.observe = function(child, topic, command) {
if ('run_terminated' === topic &&
this._command === command) {
this.cleanUp();
this._process = null;
}
};
ProcessObserver.prototype.cleanUp = function() {
if (this._command) {
observerService.removeObserver(this, 'run_terminated');
this._command = null;
}
if (this._process) {
var processExitCode = this._process.wait(-1),
processOutput = (this._process.getStdout() || this._process.getStderr());
this._callback(processExitCode, processOutput, this._process);
this._process = null;
}
};
ProcessObserver.prototype.kill = function() {
if (this._command) {
observerService.removeObserver(this, 'run_terminated');
this._command = null;
}
if (this._process) {
this._process.kill(-1);
this._process = null;
}
};
Compiler.run = function(inputFilePath, inputBaseName, inputDirectoryPath) {
for (var knownExtension in COMPILER_MAP)
if (COMPILER_MAP.hasOwnProperty(knownExtension) &&
inputFilePath.indexOf(knownExtension) === inputFilePath.length - knownExtension.length) {
var outputFilePath = inputFilePath.substr(0, inputFilePath.length - knownExtension.length) + COMPILER_MAP[knownExtension][INDEX_FILE_EXTENSION],
outputBaseName = inputBaseName.substr(0, inputBaseName.length - knownExtension.length) + COMPILER_MAP[knownExtension][INDEX_FILE_EXTENSION],
compilerName = COMPILER_MAP[knownExtension][INDEX_COMPILER],
commandLine = supportedCompilers[compilerName][INDEX_COMMAND_LINE],
commandEnvironment = supportedCompilers[compilerName][INDEX_ENVIRONMENT],
projectBaseName = (ko.projects.manager.currentProject ? ko.projects.manager.currentProject.name.split('.').shift() : 'undefined');
if ('string' === typeof (commandLine)) {
commandLine = commandLine.replace('{inpath}', inputFilePath, 'g')
.replace('{infile}', inputBaseName, 'g')
.replace('{outpath}', outputFilePath, 'g')
.replace('{outfile}', outputBaseName, 'g');
try {
commandLine = commandLine.replace(/\{\$([\w\.]+)\|(\w+)\}/g, function(group, constantName, defaultValue) {
if (projectBaseName in PROJECT_MAP)
if (constantName in PROJECT_MAP[projectBaseName])
return PROJECT_MAP[projectBaseName][constantName];
return defaultValue;
});
} catch (e) { /* ignore */ }
}
StatusBar_AddMessage("Compiling '" + inputBaseName + "' to '" + outputBaseName + "' using '" + compilerName + "'...", 'run_command', 12500, false);
try {
if ('function' === typeof (commandLine)) {
var inputFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile),
inputFileStream = null,
inputStreamReader = null,
inputContents = null,
outputFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile),
outputFileStream = null,
outputStreamWriter = null,
outputContents = null;
inputFile.initWithPath(inputFilePath);
outputFile.initWithPath(outputFilePath);
try {
inputFileStream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream);
inputFileStream.init(inputFile, 0x01 /* PR_RDONLY */, 0, 0);
inputStreamReader = Cc['@mozilla.org/scriptableinputstream;1'].createInstance(Ci.nsIScriptableInputStream);
inputStreamReader.init(inputFileStream);
inputContents = inputStreamReader.read(inputFile.fileSize);
outputContents = commandLine(inputContents, PROJECT_MAP[projectBaseName]);
outputFileStream = Cc['@mozilla.org/network/file-output-stream;1'].createInstance(Ci.nsIFileOutputStream);
outputFileStream.init(outputFile, 0x02 /* PR_WRONLY */ | 0x08 /* PR_CREATE_FILE */ | 0x20 /* PR_TRUNCATE */, 0, 0);
outputFileStream.write(outputContents, outputContents.length);
StatusBar_AddMessage("Done compiling '" + inputBaseName + "' to '" + outputBaseName + "'.", 'run_command', 1500, false);
} finally {
if (outputFileStream !== null)
outputFileStream.close();
if (inputStreamReader !== null)
inputStreamReader.close();
if (inputFileStream !== null)
inputFileStream.close();
}
} else {
var runSvc = Cc['@activestate.com/koRunService;1'].getService(Ci.koIRunService);
if (window.extensions.compileObserver)
window.extensions.compileObserver.kill();
var process = runSvc.RunAndNotify(commandLine, inputDirectoryPath, commandEnvironment, null);
window.extensions.compileObserver = new ProcessObserver(commandLine, process, function(processExitCode, processOutput) {
if (processExitCode === 0) {
var continueChain = false;
for (knownExtension in COMPILER_MAP)
if (COMPILER_MAP.hasOwnProperty(knownExtension) &&
outputFilePath.indexOf(knownExtension) === outputFilePath.length - knownExtension.length) {
if ( ! window.extensions.compileInputBaseName)
window.extensions.compileInputBaseName = inputBaseName;
Compiler.run(outputFilePath, outputBaseName, inputDirectoryPath);
continueChain = true;
}
if ( ! continueChain)
StatusBar_AddMessage("Done compiling '" + (window.extensions.compileInputBaseName ? window.extensions.compileInputBaseName : inputBaseName) + "' to '" + outputBaseName + "'.", 'run_command', 1500, false);
} else {
StatusBar_AddMessage("Error compiling '" + inputBaseName + "' using '" + compilerName + "'.", 'run_command', 2500, true);
ko.dialogs.alert("Error compiling '" + inputBaseName + "' [" + processExitCode + "] using '" + compilerName + "'.",
"Output:\n"
+ processOutput
+ "\n________________________\n\n"
+ "Command line:\n" + commandLine);
}
});
}
} catch (exception) {
var lastErrorSvc = Cc['@activestate.com/koLastErrorService;1'].getService(Ci.koILastErrorService);
var errorMessage = lastErrorSvc.getLastErrorMessage();
if ( ! errorMessage)
errorMessage = exception;
ko.dialogs.alert('Whoops! Compile encountered an exception:', errorMessage);
throw exception;
}
}
};
if (ko.views.manager &&
ko.views.manager.currentView &&
ko.views.manager.currentView.getAttribute('type') === 'editor' &&
ko.views.manager.currentView.document) {
var view = ko.views.manager.currentView,
document = view.document,
inputFilePath, inputBaseName, inputDirectoryPath;
Compiler.run(
inputFilePath = document.file.path,
inputBaseName = document.file.baseName,
inputDirectoryPath = inputFilePath.substr(0, inputFilePath.length - inputBaseName.length));
view.setFocus();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment