kopia lustrzana https://github.com/c9/core
365 wiersze
14 KiB
JavaScript
365 wiersze
14 KiB
JavaScript
|
define(function(require, exports, module) {
|
||
|
main.consumes = [
|
||
|
"editors", "Editor", "ui", "scm", "layout", "settings",
|
||
|
"threewaymerge", "menus", "Menu", "MenuItem", "Divider", "ace"
|
||
|
];
|
||
|
main.provides = ["diff.split"];
|
||
|
return main;
|
||
|
|
||
|
function main(options, imports, register) {
|
||
|
var settings = imports.settings;
|
||
|
var editors = imports.editors;
|
||
|
var Editor = imports.Editor;
|
||
|
var scm = imports.scm;
|
||
|
var layout = imports.layout;
|
||
|
var MenuItem = imports.MenuItem;
|
||
|
var Divider = imports.Divider;
|
||
|
var merge = imports.threewaymerge;
|
||
|
var Menu = imports.Menu;
|
||
|
var ace = imports.ace;
|
||
|
var ui = imports.ui;
|
||
|
|
||
|
var dirname = require("path").dirname;
|
||
|
var basename = require("path").basename;
|
||
|
var DiffView = require("./diff/twoway").DiffView;
|
||
|
|
||
|
/***** Initialization *****/
|
||
|
|
||
|
var extensions = [];
|
||
|
|
||
|
// :(
|
||
|
var BGCOLOR = {
|
||
|
"flat-light": "#F1F1F1",
|
||
|
"flat-dark": "#3D3D3D",
|
||
|
"light": "#D3D3D3",
|
||
|
"light-gray": "#D3D3D3",
|
||
|
"dark": "#3D3D3D",
|
||
|
"dark-gray": "#3D3D3D"
|
||
|
};
|
||
|
|
||
|
var menuAce;
|
||
|
var menuGutter;
|
||
|
|
||
|
var handle = editors.register("diff.split", "Compare", DiffViewer, extensions);
|
||
|
|
||
|
function createMenu() {
|
||
|
menuAce = new Menu({
|
||
|
id: "menu",
|
||
|
items: [
|
||
|
new MenuItem({ position: 10, command: "cut", caption: "Cut" }, handle),
|
||
|
new MenuItem({ position: 20, command: "copy", caption: "Copy" }, handle),
|
||
|
new MenuItem({ position: 30, command: "paste", caption: "Paste" }, handle),
|
||
|
new Divider({ position: 40 }, handle),
|
||
|
new MenuItem({ position: 50, command: "selectall", caption: "Select All" }, handle),
|
||
|
new Divider({ position: 60 }, handle)
|
||
|
]
|
||
|
}, handle);
|
||
|
|
||
|
menuGutter = new Menu({
|
||
|
id: "menu-gutter",
|
||
|
items: [
|
||
|
]
|
||
|
}, handle);
|
||
|
}
|
||
|
|
||
|
function DiffViewer() {
|
||
|
// TODO it is too difficult to hook into initialization flow of ace plugin
|
||
|
// so we have to copy paste bunch of code here :(
|
||
|
// var Baseclass = editors.findEditor("ace");
|
||
|
// var plugin = new Baseclass(true, []);
|
||
|
var plugin = new Editor(true, []);
|
||
|
var emit = plugin.getEmitter();
|
||
|
|
||
|
var currentSession;
|
||
|
var diffview;
|
||
|
var lastAce;
|
||
|
var lblLeft, lblRight, btnNext, btnPrev, btnFold, container;
|
||
|
var toolbar;
|
||
|
|
||
|
plugin.on("draw", function(e) {
|
||
|
var tab = e.tab;
|
||
|
|
||
|
lblLeft = new ui.label({ flex: 1 });
|
||
|
lblRight = new ui.label({ flex: 1, class: "right" });
|
||
|
btnNext = new ui.button({
|
||
|
caption: ">",
|
||
|
height: 24,
|
||
|
skin: "c9-toolbarbutton-glossy",
|
||
|
onclick: function() {
|
||
|
diffview.gotoNext(1);
|
||
|
}
|
||
|
});
|
||
|
btnPrev = new ui.button({
|
||
|
caption: "<",
|
||
|
height: 24,
|
||
|
skin: "c9-toolbarbutton-glossy",
|
||
|
onclick: function() {
|
||
|
diffview.gotoNext(-1);
|
||
|
}
|
||
|
});
|
||
|
btnFold = new ui.button({
|
||
|
caption: "Fold",
|
||
|
height: 24,
|
||
|
skin: "c9-toolbarbutton-glossy",
|
||
|
onclick: function() {
|
||
|
if (diffview.orig.session.$foldData.length)
|
||
|
diffview.orig.session.unfold();
|
||
|
else
|
||
|
diffview.foldUnchanged();
|
||
|
}
|
||
|
});
|
||
|
container = new ui.bar({ flex: 1, class: "ace_diff-container" });
|
||
|
|
||
|
tab.appendChild(new ui.vsplitbox({
|
||
|
anchors: "0 0 0 0",
|
||
|
childNodes: [
|
||
|
toolbar = new ui.hbox({
|
||
|
class: "difftoolbar",
|
||
|
height: 36,
|
||
|
align: "center",
|
||
|
edge: "0 5 0 3",
|
||
|
padding: 3,
|
||
|
childNodes: [
|
||
|
lblLeft,
|
||
|
new ui.hbox({
|
||
|
padding: 3,
|
||
|
edge: 3,
|
||
|
margin: "0 7 0 7",
|
||
|
align: "center",
|
||
|
class: "buttons",
|
||
|
childNodes: [ btnPrev, btnFold, btnNext ]
|
||
|
}),
|
||
|
lblRight
|
||
|
]
|
||
|
}),
|
||
|
container
|
||
|
]
|
||
|
}));
|
||
|
|
||
|
diffview = new DiffView(container.$ext, {});
|
||
|
|
||
|
// temporary workaround for apf focus bugs
|
||
|
// only blur is needed sinse the rest is handled by tabManager
|
||
|
// todo remove this when there is proper focus manager
|
||
|
tab.$blur = function(e) {
|
||
|
var ace = plugin.ace; // can be null when called for destroyed tab
|
||
|
if (!ace || !e || !e.toElement || e.toElement.tagName == "menu")
|
||
|
return;
|
||
|
if (!ace.isFocused())
|
||
|
ace.renderer.visualizeBlur();
|
||
|
else
|
||
|
ace.textInput.blur();
|
||
|
};
|
||
|
|
||
|
function focusApf() {
|
||
|
var page = apf.findHost(diffview.container.parentElement.parentElement);
|
||
|
if (apf.activeElement != page)
|
||
|
page.focus();
|
||
|
}
|
||
|
function updateLastAce(e, ace) { lastAce = ace; }
|
||
|
|
||
|
diffview.edit.on("focus", focusApf);
|
||
|
diffview.orig.on("focus", focusApf);
|
||
|
diffview.edit.keyBinding.setDefaultHandler(null);
|
||
|
diffview.orig.keyBinding.setDefaultHandler(null);
|
||
|
|
||
|
diffview.edit.on("focus", updateLastAce);
|
||
|
diffview.orig.on("focus", updateLastAce);
|
||
|
|
||
|
lastAce = diffview.edit;
|
||
|
|
||
|
// createProgressIndicator(e.htmlNode);
|
||
|
|
||
|
tab.on("contextmenu", function(e) {
|
||
|
if (!menuAce) createMenu();
|
||
|
|
||
|
var target = e.htmlEvent.target;
|
||
|
var gutter = plugin.diffview.gutterEl;
|
||
|
|
||
|
// Set Gutter Context Menu
|
||
|
if (ui.isChildOf(gutter, target, true)) {
|
||
|
menuGutter.show(e.x, e.y);
|
||
|
}
|
||
|
// Set main Ace Context Menu
|
||
|
else {
|
||
|
menuAce.show(e.x, e.y);
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
});
|
||
|
|
||
|
/***** Method *****/
|
||
|
|
||
|
function getLabelValue(path) {
|
||
|
var hash;
|
||
|
|
||
|
if (path.indexOf(":") > -1) {
|
||
|
hash = path.split(":");
|
||
|
path = hash[1], hash = hash[0];
|
||
|
}
|
||
|
|
||
|
var dirpath = dirname(path);
|
||
|
return (hash ? "<span class='hash'>" + hash + "</span>" : "")
|
||
|
+ basename(dirpath) + "/" + basename(path)
|
||
|
+ "<span class='dirname'> - " + dirname(dirpath) + "</span>";
|
||
|
}
|
||
|
|
||
|
function loadSession(session) {
|
||
|
if (session.diffSession) {
|
||
|
diffview.setSession(session.diffSession);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
diffview.setSession(session.diffSession = {
|
||
|
orig: diffview.createSession(),
|
||
|
edit: diffview.createSession(),
|
||
|
chunks: []
|
||
|
});
|
||
|
|
||
|
var diff = session.diff || {};
|
||
|
if (typeof diff.patch == "string") {
|
||
|
diffview.setValueFromFullPatch(diff.patch);
|
||
|
} else {
|
||
|
diffview.orig.session.setValue(diff.orig || "");
|
||
|
diffview.edit.session.setValue(diff.edit || "");
|
||
|
}
|
||
|
diffview.orig.setReadOnly(true);
|
||
|
diffview.edit.setReadOnly(true);
|
||
|
|
||
|
var syntax = ace.getSyntaxForPath(session.newPath);
|
||
|
if (syntax && syntax.indexOf("/") == -1) syntax = "ace/mode/" + syntax;
|
||
|
if (syntax) {
|
||
|
diffview.orig.session.setMode(syntax);
|
||
|
diffview.edit.session.setMode(syntax);
|
||
|
}
|
||
|
diffview.orig.renderer.once("afterRender", function() {
|
||
|
if (diffview.session == session.diffSession) {
|
||
|
if (!diffview.chunks.length)
|
||
|
diffview.computeDiff();
|
||
|
diffview.foldUnchanged();
|
||
|
diffview.gotoNext(1);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/***** Lifecycle *****/
|
||
|
|
||
|
plugin.on("load", function() {
|
||
|
});
|
||
|
|
||
|
plugin.on("documentLoad", function(e) {
|
||
|
var doc = e.doc;
|
||
|
var session = e.doc.getSession();
|
||
|
|
||
|
if (e.state.oldPath)
|
||
|
session.oldPath = e.state.oldPath;
|
||
|
if (e.state.newPath)
|
||
|
session.newPath = e.state.newPath;
|
||
|
|
||
|
doc.title = "Compare Files...";
|
||
|
|
||
|
diffview.c9session = session;
|
||
|
diffview.orig.session.c9session = session;
|
||
|
diffview.edit.session.c9session = session;
|
||
|
|
||
|
function setTheme(e) {
|
||
|
var tab = doc.tab;
|
||
|
if (e.theme && BGCOLOR[e.theme]) {
|
||
|
var isDark = e.theme == "dark";
|
||
|
|
||
|
toolbar.$ext.style.backgroundColor =
|
||
|
tab.backgroundColor = BGCOLOR[e.theme];
|
||
|
|
||
|
if (isDark) tab.classList.add("dark");
|
||
|
else tab.classList.remove("dark");
|
||
|
}
|
||
|
diffview.setTheme(settings.get("user/ace/@theme"));
|
||
|
}
|
||
|
|
||
|
layout.on("themeChange", setTheme, doc);
|
||
|
settings.on("user/ace/@theme", setTheme, doc);
|
||
|
setTheme({ theme: settings.get("user/general/@skin") });
|
||
|
|
||
|
});
|
||
|
plugin.on("documentActivate", function(e) {
|
||
|
var session = currentSession = e.doc.getSession();
|
||
|
|
||
|
if (!session.newPath) return;
|
||
|
|
||
|
var newFilename = (session.newPath + "").split("/").pop();
|
||
|
e.doc.title = "Compare " + newFilename;
|
||
|
|
||
|
lblLeft.setAttribute("caption", getLabelValue(session.oldPath));
|
||
|
lblRight.setAttribute("caption", getLabelValue(session.newPath));
|
||
|
|
||
|
if (session.diff)
|
||
|
return loadSession(session);
|
||
|
|
||
|
var newPath = session.newPath
|
||
|
.replace(/MODIFIED:/, "")
|
||
|
.replace(/STAGED:/, ":");
|
||
|
var oldPath = session.oldPath
|
||
|
.replace(/PREVIOUS:/, ":");
|
||
|
|
||
|
session.request = scm.loadDiff({
|
||
|
oldPath: oldPath,
|
||
|
newPath: newPath
|
||
|
}, function(err, diff) {
|
||
|
if (err)
|
||
|
diff;
|
||
|
|
||
|
if (session.request == diff.request) {
|
||
|
session.diff = diff;
|
||
|
loadSession(session);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
});
|
||
|
plugin.on("documentUnload", function(e) {
|
||
|
// var session = e.doc.getSession();
|
||
|
});
|
||
|
plugin.on("getState", function(e) {
|
||
|
var session = e.doc.getSession();
|
||
|
e.state.oldPath = session.oldPath;
|
||
|
e.state.newPath = session.newPath;
|
||
|
});
|
||
|
plugin.on("setState", function(e) {
|
||
|
var session = e.doc.getSession();
|
||
|
session.oldPath = e.state.oldPath;
|
||
|
session.newPath = e.state.newPath;
|
||
|
});
|
||
|
plugin.on("clear", function() {
|
||
|
});
|
||
|
plugin.on("focus", function() {
|
||
|
});
|
||
|
plugin.on("enable", function() {
|
||
|
});
|
||
|
plugin.on("disable", function() {
|
||
|
});
|
||
|
plugin.on("unload", function() {
|
||
|
});
|
||
|
plugin.on("resize", function(e) {
|
||
|
diffview && diffview.resize(e);
|
||
|
});
|
||
|
|
||
|
/***** Register and define API *****/
|
||
|
|
||
|
/**
|
||
|
* Read Only Image Editor
|
||
|
**/
|
||
|
plugin.freezePublicAPI({
|
||
|
get diffview() { return diffview; },
|
||
|
get ace () { return lastAce; }
|
||
|
});
|
||
|
|
||
|
plugin.load(null, "ace.repl");
|
||
|
|
||
|
return plugin;
|
||
|
}
|
||
|
|
||
|
register(null, {
|
||
|
"diff.split": handle
|
||
|
});
|
||
|
}
|
||
|
});
|