2013-12-04 17:24:04 +00:00
|
|
|
define([
|
|
|
|
"command",
|
2013-12-23 18:27:51 +00:00
|
|
|
"storage/file",
|
2014-01-21 02:03:18 +00:00
|
|
|
"util/manos",
|
2014-03-05 16:52:48 +00:00
|
|
|
"settings!ace,user",
|
2014-01-22 03:01:00 +00:00
|
|
|
"util/template!templates/tab.html"
|
|
|
|
], function(command, File, M, Settings, inflate) {
|
2014-02-27 06:34:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Tabs are just augmented versions of regular Ace sessions. We add properties
|
|
|
|
to track the attached file, detect syntax, render the tab UI, and fire events
|
|
|
|
when the tab is removed.
|
|
|
|
|
|
|
|
*/
|
2013-10-07 06:03:14 +00:00
|
|
|
|
|
|
|
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;
|
2013-10-07 06:21:04 +00:00
|
|
|
command.fire("session:render");
|
2013-10-07 06:03:14 +00:00
|
|
|
});
|
|
|
|
|
2013-10-17 00:06:32 +00:00
|
|
|
this.animationClass = "enter";
|
|
|
|
|
2013-10-07 06:03:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//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;
|
|
|
|
}
|
2014-03-05 16:52:48 +00:00
|
|
|
|
|
|
|
//strip final whitespace, if enabled
|
|
|
|
if (Settings.get("user").trimTrailingWhitespace) {
|
|
|
|
command.fire("ace:trim-whitespace");
|
|
|
|
}
|
|
|
|
|
2013-10-07 06:03:14 +00:00
|
|
|
var content = this.getValue();
|
|
|
|
var self = this;
|
2013-12-23 19:20:04 +00:00
|
|
|
var deferred = M.deferred();
|
2013-10-07 06:03:14 +00:00
|
|
|
|
2013-12-23 19:20:04 +00:00
|
|
|
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;
|
2014-01-23 16:38:20 +00:00
|
|
|
self.detectSyntax();
|
2013-12-23 19:20:04 +00:00
|
|
|
}, function(err) {
|
|
|
|
dialog(err);
|
|
|
|
deferred.fail();
|
|
|
|
})
|
|
|
|
.then(whenOpen);
|
2014-01-21 02:03:18 +00:00
|
|
|
} else {
|
|
|
|
whenOpen();
|
2013-12-23 19:20:04 +00:00
|
|
|
}
|
2013-12-23 18:27:51 +00:00
|
|
|
|
2013-12-23 19:20:04 +00:00
|
|
|
if (c) M.pton(deferred, c);
|
|
|
|
return deferred.promise();
|
2013-10-07 06:03:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Tab.prototype.drop = function() {
|
2013-11-03 01:30:37 +00:00
|
|
|
//let listeners know, like the project manager
|
|
|
|
this._emit("close");
|
2013-10-07 06:03:14 +00:00
|
|
|
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 });
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-01-21 02:03:18 +00:00
|
|
|
Tab.prototype.render = function(index) {
|
2014-01-22 03:01:00 +00:00
|
|
|
var element = inflate.get("templates/tab.html", {
|
|
|
|
index: index,
|
|
|
|
fileName: this.fileName,
|
|
|
|
modified: this.modified,
|
|
|
|
animation: this.animationClass
|
|
|
|
});
|
2014-01-21 02:03:18 +00:00
|
|
|
this.animationClass = "";
|
|
|
|
return element;
|
|
|
|
}
|
|
|
|
|
|
|
|
Tab.prototype.detectSyntax = function(userConfig) {
|
2014-01-21 06:10:06 +00:00
|
|
|
//settings are async
|
2014-01-21 07:19:25 +00:00
|
|
|
var self = this;
|
2014-01-21 06:10:06 +00:00
|
|
|
Settings.pull("user").then(function(data) {
|
|
|
|
var userConfig = data.user;
|
2014-01-21 07:19:25 +00:00
|
|
|
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);
|
2014-01-21 06:10:06 +00:00
|
|
|
});
|
|
|
|
//syntax, however, is sync
|
2014-02-22 06:37:13 +00:00
|
|
|
var syntaxValue = this.syntaxMode || "plain_text";
|
2014-02-22 06:49:40 +00:00
|
|
|
if (this.file) {
|
2014-01-21 02:03:18 +00:00
|
|
|
if (this.file.virtual) {
|
|
|
|
//settings files are special
|
|
|
|
syntaxValue = "javascript";
|
|
|
|
this.setMode("ace/mode/javascript");
|
|
|
|
} else if (this.file.entry) {
|
|
|
|
var extension = this.file.entry.name.split(".").pop();
|
2014-01-21 06:10:06 +00:00
|
|
|
//this won't ever change, safe to get each time
|
|
|
|
var aceConfig = Settings.get("ace");
|
2014-01-21 02:03:18 +00:00
|
|
|
for (var i = 0; i < aceConfig.modes.length; i++) {
|
|
|
|
var mode = aceConfig.modes[i];
|
|
|
|
if (mode.extensions.indexOf(extension) > -1) {
|
|
|
|
syntaxValue = mode.name;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-02-22 06:37:13 +00:00
|
|
|
this.setMode("ace/mode/" + syntaxValue);
|
2014-02-22 06:27:36 +00:00
|
|
|
this.syntaxMode = syntaxValue;
|
2014-01-21 02:03:18 +00:00
|
|
|
return syntaxValue;
|
|
|
|
}
|
|
|
|
|
2013-10-07 06:03:14 +00:00
|
|
|
return Tab;
|
|
|
|
|
|
|
|
});
|