c9-core/plugins/c9.ide.editors/editors.js

288 wiersze
9.7 KiB
JavaScript

define(function(require, module, exports) {
main.consumes = [
"Plugin", "menus", "ui", "settings"
];
main.provides = ["editors"];
return main;
function main(options, imports, register) {
var ui = imports.ui;
var Plugin = imports.Plugin;
var menus = imports.menus;
var settings = imports.settings;
var extname = require("path").extname;
var basename = require("path").basename;
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var emit = plugin.getEmitter();
var fileExtensions = {};
var editors = {};
var defaultEditor;
var group;
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
plugin.addElement(group = new ui.group());
menus.addItemByPath("View/Editors/", new ui.menu({
"onprop.visible": function(e) {
if (!e.value)
return;
emit("menuShow", { menu: this });
}
}), 100, plugin);
menus.addItemByPath("View/~", new ui.divider(), 200, plugin);
}
function findEditor(type, editor) {
if (type)
editor = editors[type];
// if (!editor) {
// util.alert(
// "No editor is registered",
// "Could not find an editor to display content!",
// "There is something wrong with the configuration of \
// your IDE. No editor plugin is found.");
// return;
// }
return editor;
}
function editorSupportsFile(type, path) {
var extensions = findEditor(type).fileExtensions;
var ext = extname(path).substr(1).toLowerCase();
var filename = basename(path).toLowerCase();
return ~extensions.indexOf(path)
|| ~extensions.indexOf(filename)
|| ~extensions.indexOf(ext) ? true : false;
}
function findEditorByFilename(fn) {
var ext = extname(fn).substr(1).toLowerCase();
var filename = basename(fn).toLowerCase();
// Check custom user settings first for preferred editor
var customEditor = settings.get("user/tabs/editorTypes/@" + ext);
if (customEditor) return customEditor;
var editor = fileExtensions[fn] && fileExtensions[fn][0]
|| fileExtensions[filename] && fileExtensions[filename][0]
|| fileExtensions[ext] && fileExtensions[ext][0]
|| defaultEditor;
return findEditor(null, editor);
}
/***** Methods *****/
function registerPlugin(type, caption, editor, extensions) {
editors[type] = editor;
var handle = new Plugin("Ajax.org", []);
handle[type] = editor;
handle[caption] = caption;
editor.type = type;
editor.fileExtensions = extensions;
if (extensions.length) {
//Add a menu item to the list of editors
menus.addItemByPath("View/Editors/" + caption,
new ui.item({
type: "radio",
value: type,
group: group,
onclick: function() {
emit("menuClick", { value: this.value });
}
}), 40000, handle);
}
extensions.forEach(function(ext) {
// force lower-case, to account for other LowerCase checks below
ext = ext.toLowerCase();
(fileExtensions[ext] || (fileExtensions[ext] = [])).unshift(editor);
});
if (editor.type == options.defaultEditor)
defaultEditor = editor;
emit("register", { editor: editor });
handle.on("load", function() {
if (!editors[type])
registerPlugin(type, caption, editor, extensions);
});
handle.on("unload", function() {
unregisterPlugin(type, editor, extensions);
});
return handle;
}
function unregisterPlugin(type, editor, extensions) {
delete editors[type];
extensions.forEach(function(fe) {
if (!fileExtensions[fe]) return;
var idx = fileExtensions[fe].indexOf(editor);
fileExtensions[fe].splice(idx, 1);
if (!fileExtensions[fe].length)
delete fileExtensions[fe];
});
if (defaultEditor == editor)
defaultEditor = null;
emit("unregister", { editor: editor });
}
function createEditor(type, callback) {
if (!type) type = "default";
var cancelled = false;
function create() {
if (cancelled) return;
var constr = editors[type];
var editor = constr ? new constr() : false;
editor.type = type;
callback(null, editor);
emit("create", { editor: editor });
}
if (editors[type]) create();
else {
plugin.on("register", function wait(e) {
if (e.editor.type == type) {
plugin.off("register", wait);
// Delay creation to make sure handle is created
setTimeout(create);
}
});
return function cancel() { cancelled = true; };
}
}
/***** Lifecycle *****/
plugin.on("load", function() {
load();
});
plugin.on("enable", function() {
});
plugin.on("disable", function() {
});
plugin.on("unload", function() {
loaded = false;
defaultEditor = null;
group = null;
});
/***** Register and define API *****/
/**
* Editor Manager for Cloud9. Editors are automatically registered
* here when using the {@link Editor} base class. Use this class to
* instantiate an editor instance for use outside of the normal tabs.
* If you want to open a tab with an editor to edit file content use
* {@link tabManager#method-open}.
*
* @singleton
**/
plugin.freezePublicAPI({
/**
* The editor that is used when no editor is registered for the
* file extension in question.
*
* See {@link editors#findEditorByFilename}
* See {@link tabManager#method-open}
*
* @property {String} defaultEditor
*/
get defaultEditor() { return options.defaultEditor; },
/**
* Array of file extensions supported by the registered editors
* @property {String[]} fileExtensions
*/
get fileExtensions() { return fileExtensions; },
_events: [
/**
* @event register Fires when an editor registers
* @param {Object} e
* @param {Editor} e.editor The editor that is registered
* @readonly
*/
"register",
/**
* @event unregister Fires when an editor unregisters
* @param {Object} e
* @param {Editor} e.editor The editor that is unregistered
* @readonly
*/
"unregister"
],
/**
* Registers an editor constructor to be available for certain
* file types
* @param {Function} editor the editor constructor
* @param {String[]} fileExtensions the file extensions this editor supports
*/
register: registerPlugin,
/**
* Unregisters an editor constructor for certain file types
* @param {Function} editor the editor constructor
*/
unregister: unregisterPlugin,
/**
* Retrieves an editor constructor class based on it's type
* @param {String} type The type of the editor to retrieve
* @return {Function}
*/
findEditor: findEditor,
/**
* Retrieves an editor constructor class based on a filename (or path)
* @param {String} filename the filename that determines the editor to find
* @return {Function}
*/
findEditorByFilename: findEditorByFilename,
/**
*
*/
editorSupportsFile: editorSupportsFile,
/**
* Create an editor instance based on it's type
* @param {String} type The type of the editor to create
* @return {Editor}
*/
createEditor: createEditor
});
register(null, {
editors: plugin
});
}
});