Report abuse

(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                                                      *
 *                                                                           *
 * java executable is recommended to be on PATH, however you can specify     *
 * a full path below.                                                        *
 *                                                                           *
 * Remember to escape \ as \\                                                *
 *                                                                           *
 ****************************************************************************/

// Download from http://www.java.com/en/download/manual.jsp
const JAVA_PATH             = 'java';

// 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\\';

/** DON'T EDIT PAST THIS LINE ***********************************************/

var supportedCompilers = { 'yui-css':             [JAVA_PATH + ' -jar "' + YUI_PATH + '" --charset utf-8 -v --type=css -o "{1}" "{0}"'],
						   'yui-js':              [JAVA_PATH + ' -jar "' + YUI_PATH + '" --charset utf-8 -v --type=js -o "{1}" "{0}"'],

						   'closure-compiler-js': [JAVA_PATH + ' -jar "' + CLOSURE_COMPILER_PATH + '" --js "{0}" --js_output_file "{1}"'],

						   'sass':                ['"' + CYGWIN_PATH + 'bin\\sass" --trace --style=compressed "{0}" "{1}"',
												   'PATH=' + CYGWIN_PATH + 'bin;' + CYGWIN_PATH + 'lib\nNODOSFILEWARNING=1'] };

var knownTypes = { '.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'] };

const Cc = Components.classes;
const Ci = Components.interfaces;

if (typeof (extensions) === 'undefined')
	window.extensions = {};

if (typeof (window.extensions.compileObserver) === 'undefined')
	window.extensions.compileObserver = null;

const INDEX_COMMAND_LINE = 0;
const INDEX_ENVIRONMENT = 1;

const INDEX_COMPILER = 0;
const INDEX_FILE_EXTENSION = 1;

var observerSvc = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);

function ProcessObserver(command, process, callback) {

	this._command = command;
	this._process = process;

	this._callback = (callback || function() {});

	observerSvc.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) {

		observerSvc.removeObserver(this, 'run_terminated');
		this._command = null;
	}

	if (this._process) {

		var processExitCode = 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) {

		observerSvc.removeObserver(this, 'run_terminated');
		this._command = null;
	}

	if (this._process) {

		this._process.kill(-1);
		this._process = null;
	}
};

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 = document.file.path,
		inputBaseName = document.file.baseName,
		inputDirectoryPath = inputFilePath.substr(0, inputFilePath.length - inputBaseName.length);

	for (var knownExtension in knownTypes)
		if (knownTypes.hasOwnProperty(knownExtension) &&
			inputFilePath.indexOf(knownExtension) === inputFilePath.length - knownExtension.length) {

			var outputFilePath = inputFilePath.substr(0, inputFilePath.length - knownExtension.length) + knownTypes[knownExtension][INDEX_FILE_EXTENSION],
				outputBaseName = inputBaseName.substr(0, inputBaseName.length - knownExtension.length) + knownTypes[knownExtension][INDEX_FILE_EXTENSION],

				compilerName = knownTypes[knownExtension][INDEX_COMPILER],

				commandLine = supportedCompilers[compilerName][INDEX_COMMAND_LINE],
				commandEnvironment = supportedCompilers[compilerName][INDEX_ENVIRONMENT];

			commandLine = commandLine.replace('{0}', inputFilePath, 'g')
									 .replace('{1}', outputFilePath, 'g');

			StatusBar_AddMessage("Compiling '" + inputBaseName + "' using '" + compilerName + "'...", 'run_command', 12500, false);

			var runSvc = Cc['@activestate.com/koRunService;1'].getService(Ci.koIRunService);

			try {

				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)
						StatusBar_AddMessage("Done compiling '" + inputBaseName + "' to '" + outputBaseName + "'.", 'run_command', 1500, false);
					else
						ko.dialogs.alert("Error compiling '" + inputBaseName + "' [" + processExitCode + "] using '" + compilerName + "'.",
										 "Output:\n"
									   + processOutput
									   + "\n________________________\n\n"
									   + "Command line:\n" + commandLine);
				});

				view.setFocus();

			} 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;
			}
		}
}

})();