2014-02-23 22:21:11 +00:00
|
|
|
define([
|
|
|
|
"command",
|
|
|
|
"sessions/state",
|
2014-02-23 23:48:51 +00:00
|
|
|
"sessions/addRemove",
|
|
|
|
"ui/contextMenus",
|
|
|
|
"util/manos",
|
2014-02-23 22:21:11 +00:00
|
|
|
"util/dom2"
|
2014-02-23 23:48:51 +00:00
|
|
|
], function(command, state, addRemove, contextMenus, M) {
|
2014-02-27 02:56:05 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
This module returns a function that will bind for event delegation to the
|
|
|
|
tab container. Most of it is support for drag/drop.
|
|
|
|
*/
|
2014-02-23 22:21:11 +00:00
|
|
|
|
|
|
|
var enableTabDragDrop = function() {
|
|
|
|
var tabContainer = document.find(".tabs");
|
|
|
|
var draggedTab = null;
|
2014-02-27 02:56:05 +00:00
|
|
|
|
2014-02-23 22:21:11 +00:00
|
|
|
tabContainer.on("dragstart", function(e) {
|
|
|
|
if (!e.target.matches(".tab")) return;
|
2014-02-23 23:17:05 +00:00
|
|
|
e.target.style.opacity = 0;
|
2014-02-23 22:21:11 +00:00
|
|
|
setTimeout(function() {
|
|
|
|
e.target.addClass("dragging");
|
|
|
|
}, 50);
|
|
|
|
e.dataTransfer.setDragImage(e.target, 0, 0);
|
|
|
|
e.dataTransfer.effectAllowed = "move";
|
|
|
|
e.dataTransfer.clearData("text/plain");
|
|
|
|
e.dataTransfer.clearData("text/uri-list");
|
|
|
|
e.dataTransfer.setData("application/x-tab-id", e.target.getAttribute("tab-id"));
|
|
|
|
draggedTab = e.target;
|
|
|
|
draggedTab.ondragend = function() {
|
|
|
|
draggedTab = null;
|
|
|
|
e.target.style.opacity = null;
|
|
|
|
e.target.removeClass("dragging");
|
|
|
|
};
|
|
|
|
});
|
2014-02-27 02:56:05 +00:00
|
|
|
|
2014-02-23 22:21:11 +00:00
|
|
|
tabContainer.on("dragover", function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
e.dropEffect = "move";
|
2014-02-23 22:56:48 +00:00
|
|
|
var tab = e.target.findUp(".tab:not(.hovering)");
|
2014-05-05 04:53:50 +00:00
|
|
|
if (tab || e.target == tabContainer) {
|
|
|
|
var old = tabContainer.find(".hovering");
|
|
|
|
if (old) old.removeClass("hovering");
|
|
|
|
if (tab) tab.addClass("hovering");
|
2014-02-23 22:56:48 +00:00
|
|
|
}
|
|
|
|
});
|
2014-02-27 02:56:05 +00:00
|
|
|
|
2014-05-05 04:53:50 +00:00
|
|
|
//cancel hover appearance when leaving the tab bar
|
|
|
|
tabContainer.on("drag", function(e) {
|
|
|
|
var tabCoords = tabContainer.getBoundingClientRect();
|
|
|
|
if (
|
|
|
|
e.clientX > tabCoords.left &&
|
|
|
|
e.clientX < tabCoords.left + tabCoords.width &&
|
|
|
|
e.clientY > tabCoords.top &&
|
|
|
|
e.clientY < tabCoords.top + tabCoords.top
|
|
|
|
) return;
|
2014-02-23 22:56:48 +00:00
|
|
|
var hovered = tabContainer.find(".hovering");
|
|
|
|
if (hovered) hovered.removeClass("hovering");
|
2014-02-23 22:21:11 +00:00
|
|
|
});
|
2014-02-27 02:56:05 +00:00
|
|
|
|
2014-02-23 22:21:11 +00:00
|
|
|
tabContainer.on("drop", function(e) {
|
|
|
|
if (!draggedTab) return;
|
|
|
|
e.stopPropagation();
|
|
|
|
var location = "before"; //how to position the new tab
|
|
|
|
var target; //closest tab to drop event
|
|
|
|
if (e.target == tabContainer) {
|
|
|
|
//if dropped on the bar, find the nearest tab to go after
|
|
|
|
var elements = tabContainer.findAll(".tab");
|
|
|
|
location = "after";
|
|
|
|
elements.forEach(function(el) {
|
|
|
|
if (el.offsetLeft < e.offsetX) {
|
|
|
|
target = el;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
//otherwise, find the actual tab element
|
|
|
|
target = e.target.findUp(".tab");
|
|
|
|
}
|
|
|
|
var fromIndex = e.dataTransfer.getData("application/x-tab-id") * 1;
|
|
|
|
var toIndex = target.getAttribute("tab-id") * 1;
|
|
|
|
var from = state.tabs[fromIndex];
|
|
|
|
var to = state.tabs[toIndex];
|
|
|
|
if (from != to) {
|
|
|
|
var reordered = [];
|
|
|
|
state.tabs.forEach(function(t) {
|
|
|
|
if (t == from) return;
|
|
|
|
if (t == to && location == "before") {
|
|
|
|
reordered.push(from);
|
|
|
|
}
|
|
|
|
reordered.push(t);
|
|
|
|
if (t == to && location == "after") {
|
|
|
|
reordered.push(from);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
state.tabs = reordered;
|
|
|
|
}
|
|
|
|
command.fire("session:render");
|
|
|
|
});
|
2014-02-27 02:56:05 +00:00
|
|
|
|
2014-02-23 22:21:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
var enableTabMiddleClick = function() {
|
|
|
|
var tabContainer = document.find(".tabs");
|
|
|
|
tabContainer.on("click", function(e) {
|
2014-04-10 23:48:01 +00:00
|
|
|
if (!e.target.matches(".label")) return;
|
2014-02-23 22:21:11 +00:00
|
|
|
if (e.button != 1) return;
|
|
|
|
e.preventDefault();
|
2014-04-10 23:48:01 +00:00
|
|
|
command.fire("session:close-tab", e.target.getAttribute("argument"));
|
2014-02-23 22:21:11 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-02-23 23:48:51 +00:00
|
|
|
var closeTabsRight = function(tabID) {
|
|
|
|
tabID = tabID || state.tabs.indexOf(editor.getSession());
|
|
|
|
var toClose = [];
|
|
|
|
for (var i = state.tabs.length - 1; i > tabID; i--) {
|
|
|
|
toClose.push(i);
|
|
|
|
}
|
|
|
|
M.serial(toClose, addRemove.remove);
|
|
|
|
};
|
|
|
|
|
2014-03-24 15:18:25 +00:00
|
|
|
var enableDblClickNewTab = function() {
|
|
|
|
var tabContainer = document.find(".tabs");
|
2014-05-05 04:53:50 +00:00
|
|
|
tabContainer.on("dblclick", function(e) {
|
2014-03-24 15:18:25 +00:00
|
|
|
e.preventDefault();
|
|
|
|
if (e.button == 0)
|
|
|
|
command.fire("session:new-file");
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-02-23 23:48:51 +00:00
|
|
|
command.on("session:close-to-right", closeTabsRight);
|
|
|
|
|
|
|
|
contextMenus.register("Close", "closeTab", "tabs/:id", function(args) {
|
|
|
|
command.fire("session:close-tab", args.id);
|
|
|
|
});
|
|
|
|
contextMenus.register("Close tabs to the right", "closeTabsRight", "tabs/:id", function(args) {
|
|
|
|
closeTabsRight(args.id);
|
|
|
|
});
|
|
|
|
|
2014-02-23 22:21:11 +00:00
|
|
|
return function() {
|
|
|
|
enableTabDragDrop();
|
|
|
|
enableTabMiddleClick();
|
2014-03-24 15:18:25 +00:00
|
|
|
enableDblClickNewTab();
|
2014-02-23 22:21:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
});
|