Caret/js/tab.js

163 lines
No EOL
4.6 KiB
JavaScript

define([
"command",
"storage/file",
"util/manos",
"settings!ace"
], function(command, File, M, Settings) {
var EditSession = ace.require("ace/edit_session").EditSession;
var Tab = function(contents, file) {
contents = contents || "";
EditSession.call(this, contents, "ace/mode/text");
if (contents) {
this.setValue(contents);
}
if (file) {
this.setFile(file);
} else {
this.fileName = "untitled.txt";
}
this.modified = false;
this.setUndoManager(new ace.UndoManager());
var self = this;
this.on("change", function() {
if (self.modified) return;
self.modified = true;
command.fire("session:render");
});
this.animationClass = "enter";
};
//hopefully this never screws up unaugmented Ace sessions.
Tab.prototype = EditSession.prototype;
Tab.prototype.setFile = function(file) {
this.file = file;
this.fileName = file.entry.name;
this.modifiedAt = new Date();
}
Tab.prototype.save = function(as, c) {
if (typeof as == "function") {
c = as;
as = false;
}
var content = this.getValue();
var self = this;
var deferred = M.deferred();
var whenOpen = function() {
self.file.write(content).then(function() {
self.modifiedAt = new Date();
self.modified = false;
command.fire("session:render");
deferred.done();
}, deferred.fail.bind(deferred));
};
if (!self.file || as) {
var file = new File();
file.open("save")
.then(function() {
self.file = file;
self.fileName = file.entry.name;
delete self.syntaxMode;
}, function(err) {
dialog(err);
deferred.fail();
})
.then(whenOpen);
} else {
whenOpen();
}
if (c) M.pton(deferred, c);
return deferred.promise();
};
Tab.prototype.drop = function() {
//let listeners know, like the project manager
this._emit("close");
if (!this.file || !chrome.fileSystem.retainEntry) return;
var id = this.file.retain();
if (!id) return;
chrome.storage.local.get("retained", function(data) {
if (!data.retained) return;
var filtered = data.retained.filter(function(item) { return item != id });
chrome.storage.local.set({ retained: filtered });
});
};
Tab.prototype.render = function(index) {
var element = document.createElement("a");
element.setAttribute("draggable", true);
element.setAttribute("command", "session:raise-tab");
element.setAttribute("argument", index);
element.setAttribute("title", this.fileName);
element.setAttribute("href", "tabs/" + index);
element.className = "tab";
if (this.animationClass) {
element.addClass(this.animationClass);
}
this.animationClass = "";
element.innerHTML = this.fileName + (this.modified ? " •" : "");
var close = document.createElement("a");
close.innerHTML = "×";
close.className = "close";
close.setAttribute("command", "session:close-tab");
close.setAttribute("argument", index);
element.append(close);
return element;
}
Tab.prototype.detectSyntax = function(userConfig) {
//settings are async
var self = this;
Settings.pull("user").then(function(data) {
var userConfig = data.user;
self.setUseSoftTabs(!userConfig.useTabs);
self.setTabSize(userConfig.indentation || 2);
self.setUseWrapMode(userConfig.wordWrap);
self.setWrapLimit(userConfig.wrapLimit || null);
self.setNewLineMode(userConfig.lineEnding || "auto");
self.setUseWorker(userConfig.useWorker);
});
//syntax, however, is sync
var syntaxValue = "plain_text";
if (this.syntaxMode) {
syntaxValue = this.syntaxMode;
} else if (this.file) {
if (this.file.virtual) {
//settings files are special
syntaxValue = "javascript";
this.setMode("ace/mode/javascript");
} else if (this.file.entry) {
var found = false;
var extension = this.file.entry.name.split(".").pop();
//this won't ever change, safe to get each time
var aceConfig = Settings.get("ace");
for (var i = 0; i < aceConfig.modes.length; i++) {
var mode = aceConfig.modes[i];
if (mode.extensions.indexOf(extension) > -1) {
this.setMode("ace/mode/" + mode.name);
syntaxValue = mode.name;
break;
}
}
}
this.syntaxMode = syntaxValue;
}
this.setMode("ace/mode/" + syntaxValue);
return syntaxValue;
}
return Tab;
});