2013-09-01 18:09:09 +00:00
|
|
|
define([
|
|
|
|
"editor",
|
|
|
|
"dialog",
|
|
|
|
"command",
|
|
|
|
"file",
|
2013-09-04 19:45:51 +00:00
|
|
|
"settings!ace,user",
|
|
|
|
"aceBindings"
|
2013-09-01 18:09:09 +00:00
|
|
|
],
|
2013-09-03 15:47:59 +00:00
|
|
|
function(editor, dialog, command, File, Settings) {
|
2013-08-21 00:35:25 +00:00
|
|
|
|
|
|
|
var tabs = [];
|
2013-08-22 06:35:14 +00:00
|
|
|
var Session = ace.require("ace/edit_session").EditSession;
|
2013-09-03 15:47:59 +00:00
|
|
|
var cfg = Settings.get("ace");
|
2013-09-04 15:53:11 +00:00
|
|
|
var userConfig = Settings.get("user");
|
2013-09-04 22:01:32 +00:00
|
|
|
|
|
|
|
var augmentTab = function(session, file) {
|
|
|
|
|
|
|
|
if (file) {
|
|
|
|
session.file = file;
|
|
|
|
session.fileName = file.entry.name;
|
|
|
|
} else {
|
|
|
|
session.fileName = "untitled.txt";
|
|
|
|
}
|
2013-09-04 23:36:33 +00:00
|
|
|
|
|
|
|
setTabSyntax(session);
|
2013-09-04 22:01:32 +00:00
|
|
|
|
|
|
|
if (session.isTab) {
|
|
|
|
session.retain();
|
|
|
|
session.setUnmodified();
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
session.isTab = true;
|
|
|
|
|
2013-09-05 14:45:22 +00:00
|
|
|
session.setUndoManager(new ace.UndoManager());
|
|
|
|
|
2013-09-04 22:01:32 +00:00
|
|
|
session.save = function(as) {
|
|
|
|
if (this.modified || as) {
|
|
|
|
var content = this.getValue();
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
var whenOpen = function() {
|
|
|
|
self.file.write(content);
|
|
|
|
self.setUnmodified();
|
|
|
|
renderTabs();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.file) {
|
|
|
|
var file = this.file = new File();
|
|
|
|
return file.open("save", function() {
|
|
|
|
self.fileName = file.entry.name;
|
|
|
|
self.retain();
|
|
|
|
whenOpen();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
whenOpen();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
session.raise = function() {
|
|
|
|
editor.setSession(session);
|
2013-09-05 01:36:27 +00:00
|
|
|
syntax.value = session.syntaxMode || "plain_text";
|
2013-09-04 22:01:32 +00:00
|
|
|
renderTabs();
|
|
|
|
editor.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
session.retain = function() {
|
|
|
|
if (!this.file || !chrome.fileSystem.retainEntry) return;
|
|
|
|
var id = this.file.retain();
|
|
|
|
if (!id) return;
|
|
|
|
chrome.storage.local.get("retained", function(data) {
|
|
|
|
data.retained = data.retained || [];
|
|
|
|
if (data.retained.indexOf(id) == -1) {
|
|
|
|
data.retained.push(id);
|
|
|
|
chrome.storage.local.set({ retained: data.retained });
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
session.retain();
|
|
|
|
|
|
|
|
session.drop = function() {
|
|
|
|
if (!this.file || !chrome.fileSystem.retainEntry) return;
|
|
|
|
var id = this.file.retain();
|
|
|
|
if (!id) return;
|
|
|
|
chrome.storage.local.get("retained", function(data) {
|
|
|
|
var filtered = data.retained.filter(function(item) { return item != id });
|
|
|
|
chrome.storage.local.set({ retained: filtered });
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
session.setUnmodified = function() {
|
|
|
|
var self = this;
|
|
|
|
this.modified = false;
|
|
|
|
this.once("change", function() {
|
|
|
|
self.modified = true;
|
|
|
|
renderTabs();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
session.setUnmodified();
|
|
|
|
|
|
|
|
};
|
2013-08-21 00:35:25 +00:00
|
|
|
|
|
|
|
var renderTabs = function() {
|
2013-09-01 18:09:09 +00:00
|
|
|
var tabContainer = document.find(".tabs");
|
2013-08-21 00:35:25 +00:00
|
|
|
var contents = "";
|
2013-08-22 06:35:14 +00:00
|
|
|
var current = editor.getSession();
|
|
|
|
tabContainer.innerHTML = "";
|
2013-08-21 00:35:25 +00:00
|
|
|
tabs.forEach(function(tab, index) {
|
2013-08-22 06:35:14 +00:00
|
|
|
var span = document.createElement("span");
|
|
|
|
span.setAttribute("command", "session:raise-tab");
|
|
|
|
span.setAttribute("argument", index);
|
|
|
|
if (tab === current) {
|
|
|
|
span.className = "active";
|
|
|
|
}
|
|
|
|
span.innerHTML = tab.fileName + (tab.modified ? " *" : "");
|
|
|
|
var close = document.createElement("a");
|
|
|
|
close.innerHTML = "×";
|
|
|
|
close.className = "close";
|
|
|
|
close.setAttribute("command", "session:close-tab");
|
|
|
|
close.setAttribute("argument", index);
|
|
|
|
span.append(close);
|
|
|
|
tabContainer.append(span);
|
2013-08-21 00:35:25 +00:00
|
|
|
});
|
2013-09-04 22:01:32 +00:00
|
|
|
};
|
2013-08-21 00:35:25 +00:00
|
|
|
|
2013-09-01 04:21:21 +00:00
|
|
|
var setTabSyntax = function(tab) {
|
2013-09-04 15:53:11 +00:00
|
|
|
tab.setTabSize(userConfig.indentation || 2);
|
|
|
|
tab.setUseWrapMode(userConfig.wordWrap);
|
2013-09-05 01:36:27 +00:00
|
|
|
var syntaxValue = "plain_text";
|
2013-09-01 04:21:21 +00:00
|
|
|
if (tab.file) {
|
2013-09-04 19:26:09 +00:00
|
|
|
var found = false;
|
2013-09-01 04:21:21 +00:00
|
|
|
var extension = tab.file.entry.name.split(".").pop();
|
2013-09-01 04:33:18 +00:00
|
|
|
for (var i = 0; i < cfg.modes.length; i++) {
|
|
|
|
var mode = cfg.modes[i];
|
|
|
|
if (mode.extensions.indexOf(extension) > -1) {
|
|
|
|
tab.setMode("ace/mode/" + mode.name);
|
2013-09-05 01:36:27 +00:00
|
|
|
syntaxValue = mode.name;
|
2013-09-01 04:33:18 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-09-01 04:21:21 +00:00
|
|
|
}
|
2013-09-05 01:36:27 +00:00
|
|
|
syntax.value = syntaxValue;
|
|
|
|
tab.syntaxMode = syntaxValue;
|
2013-09-01 04:21:21 +00:00
|
|
|
};
|
|
|
|
|
2013-08-21 00:47:07 +00:00
|
|
|
var addTab = function(contents, file) {
|
2013-08-22 06:35:14 +00:00
|
|
|
contents = contents || "";
|
|
|
|
var current = editor.getSession();
|
|
|
|
var session;
|
2013-08-31 20:41:51 +00:00
|
|
|
//reuse tab if opening a file into an empty tab
|
|
|
|
if (file && !current.file && !current.modified) {
|
2013-08-22 06:35:14 +00:00
|
|
|
session = current;
|
|
|
|
session.setValue(contents);
|
|
|
|
} else {
|
|
|
|
session = new Session(contents);
|
|
|
|
tabs.push(session);
|
|
|
|
}
|
2013-09-04 22:01:32 +00:00
|
|
|
augmentTab(session, file);
|
|
|
|
session.raise();
|
2013-09-10 23:26:36 +00:00
|
|
|
return session;
|
2013-08-21 00:35:25 +00:00
|
|
|
};
|
|
|
|
|
2013-08-21 00:47:07 +00:00
|
|
|
var removeTab = function(index) {
|
2013-08-31 20:23:41 +00:00
|
|
|
if (!index) {
|
|
|
|
index = tabs.indexOf(editor.getSession());
|
|
|
|
}
|
2013-09-01 19:23:13 +00:00
|
|
|
var tab = tabs[index];
|
|
|
|
|
|
|
|
var continuation = function() {
|
2013-09-04 22:01:32 +00:00
|
|
|
tab.drop();
|
2013-09-01 19:23:13 +00:00
|
|
|
tabs = tabs.filter(function(tab, i) {
|
|
|
|
if (i == index) {
|
|
|
|
//tab.save();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2013-09-04 22:01:32 +00:00
|
|
|
});
|
2013-09-01 19:23:13 +00:00
|
|
|
if (tabs.length == 0) {
|
|
|
|
return addTab();
|
2013-08-22 06:35:14 +00:00
|
|
|
}
|
2013-09-01 19:23:13 +00:00
|
|
|
var next = index - 1;
|
|
|
|
if (next < 0) {
|
|
|
|
next = 0;
|
|
|
|
}
|
|
|
|
raiseTab(next);
|
2013-08-22 06:35:14 +00:00
|
|
|
}
|
2013-09-01 19:23:13 +00:00
|
|
|
|
|
|
|
if (tab.modified) {
|
|
|
|
dialog(
|
2013-09-01 19:41:39 +00:00
|
|
|
tab.fileName + " has been modified. Do you want to save changes?",
|
2013-09-01 19:23:13 +00:00
|
|
|
[{label: "Save", value: true}, {label: "Don't save", value: false}],
|
|
|
|
function(confirm) {
|
|
|
|
if (confirm) {
|
|
|
|
tab.save();
|
|
|
|
}
|
|
|
|
continuation();
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
continuation();
|
2013-09-01 18:36:56 +00:00
|
|
|
}
|
2013-08-21 00:47:07 +00:00
|
|
|
};
|
|
|
|
|
2013-08-21 00:35:25 +00:00
|
|
|
var raiseTab = function(index) {
|
|
|
|
var tab = tabs[index];
|
2013-09-04 22:01:32 +00:00
|
|
|
tab.raise();
|
2013-08-21 00:47:07 +00:00
|
|
|
};
|
2013-08-21 00:35:25 +00:00
|
|
|
|
2013-09-01 04:21:21 +00:00
|
|
|
var switchTab = function(shift) {
|
|
|
|
shift = shift || 1;
|
|
|
|
var current = editor.getSession();
|
|
|
|
var currentIndex = tabs.indexOf(current);
|
|
|
|
var shifted = (currentIndex + shift) % tabs.length;
|
2013-09-05 15:11:19 +00:00
|
|
|
if (shifted < 0) {
|
|
|
|
shifted = tabs.length + shifted;
|
|
|
|
}
|
2013-09-01 04:21:21 +00:00
|
|
|
raiseTab(shifted);
|
|
|
|
}
|
|
|
|
|
2013-08-21 00:35:25 +00:00
|
|
|
var openFile = function() {
|
|
|
|
var f = new File();
|
|
|
|
f.open(function(file) {
|
|
|
|
f.read(function(err, data) {
|
2013-08-22 06:35:14 +00:00
|
|
|
addTab(data, file);
|
2013-08-21 00:35:25 +00:00
|
|
|
});
|
|
|
|
});
|
2013-09-01 04:21:21 +00:00
|
|
|
};
|
2013-08-21 00:35:25 +00:00
|
|
|
|
2013-09-05 01:36:27 +00:00
|
|
|
var openFromLaunchData = function() {
|
|
|
|
if (window.launchData) {
|
|
|
|
window.launchData.items.forEach(function(file) {
|
|
|
|
var f = new File();
|
|
|
|
f.entry = file.entry;
|
|
|
|
f.read(function(err, contents) {
|
|
|
|
addTab(contents, f);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-02 01:26:22 +00:00
|
|
|
var syntax = document.find(".syntax");
|
2013-08-22 06:35:14 +00:00
|
|
|
|
2013-09-02 01:26:22 +00:00
|
|
|
var init = function() {
|
|
|
|
cfg.modes.forEach(function(mode) {
|
|
|
|
var option = document.createElement("option");
|
|
|
|
option.innerHTML = mode.label;
|
|
|
|
option.value = mode.name;
|
|
|
|
syntax.append(option);
|
|
|
|
});
|
|
|
|
addTab("");
|
2013-09-05 01:36:27 +00:00
|
|
|
openFromLaunchData();
|
2013-09-04 22:01:32 +00:00
|
|
|
chrome.storage.local.get("retained", function(data) {
|
2013-09-05 01:36:27 +00:00
|
|
|
var failures = [];
|
2013-09-04 22:01:32 +00:00
|
|
|
if (data.retained && data.retained.length) {
|
|
|
|
data.retained.forEach(function(id) {
|
|
|
|
var file = new File();
|
2013-09-05 01:36:27 +00:00
|
|
|
file.restore(id, function(err, f) {
|
|
|
|
if (err) {
|
|
|
|
//add failures to be removed asynchronously
|
|
|
|
failures.push(id);
|
|
|
|
return;
|
|
|
|
}
|
2013-09-04 22:01:32 +00:00
|
|
|
file.read(function(err, contents) {
|
|
|
|
addTab(contents, file);
|
|
|
|
});
|
2013-09-05 01:36:27 +00:00
|
|
|
return id;
|
2013-09-04 22:01:32 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
reset();
|
2013-09-05 01:36:27 +00:00
|
|
|
//after a reasonable delay, filter failures out of retention
|
|
|
|
setTimeout(function() {
|
|
|
|
chrome.storage.local.get("retained", function(data) {
|
|
|
|
chrome.storage.local.set({
|
|
|
|
retained: data.retained.filter(function(d) { return failures.indexOf(d) == -1 })
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, 500);
|
2013-09-04 22:01:32 +00:00
|
|
|
});
|
2013-09-02 01:26:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
var reset = function() {
|
2013-09-03 15:47:59 +00:00
|
|
|
cfg = Settings.get("ace");
|
2013-09-04 19:26:09 +00:00
|
|
|
userConfig = Settings.get("user");
|
2013-09-02 01:26:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
command.on("init:startup", init);
|
|
|
|
command.on("init:restart", reset);
|
|
|
|
|
|
|
|
command.on("session:syntax", function(mode) {
|
|
|
|
editor.getSession().setMode("ace/mode/" + mode);
|
2013-09-05 15:28:40 +00:00
|
|
|
editor.focus();
|
2013-09-02 01:26:22 +00:00
|
|
|
});
|
2013-08-22 06:35:14 +00:00
|
|
|
|
|
|
|
command.on("session:new-file", function() { addTab() });
|
2013-08-21 00:35:25 +00:00
|
|
|
command.on("session:open-file", openFile);
|
|
|
|
command.on("session:raise-tab", raiseTab);
|
2013-08-22 06:35:14 +00:00
|
|
|
command.on("session:save-file", function() { editor.getSession().save() });
|
|
|
|
command.on("session:save-file-as", function() { editor.getSession().save(true) });
|
|
|
|
command.on("session:close-tab", removeTab);
|
2013-09-01 04:21:21 +00:00
|
|
|
command.on("session:change-tab", switchTab);
|
2013-08-20 00:53:03 +00:00
|
|
|
|
2013-09-03 15:47:59 +00:00
|
|
|
command.on("session:open-settings-file", function(name) {
|
|
|
|
Settings.load(name, function() {
|
2013-09-10 23:26:36 +00:00
|
|
|
var data = Settings.getAsString(name);
|
2013-09-03 15:47:59 +00:00
|
|
|
var file = Settings.getAsFile(name);
|
2013-09-10 23:26:36 +00:00
|
|
|
addTab(data, file).setUseWorker(false);
|
2013-09-03 15:47:59 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-09-05 01:36:27 +00:00
|
|
|
command.on("session:open-launch", openFromLaunchData);
|
|
|
|
|
2013-09-03 15:47:59 +00:00
|
|
|
return {
|
|
|
|
addFile: addTab
|
|
|
|
}
|
|
|
|
|
2013-08-20 00:53:03 +00:00
|
|
|
});
|