diff --git a/src/extensions/default/Git/src/Main.js b/src/extensions/default/Git/src/Main.js
index 3b50a63ed7..1d05933d6d 100644
--- a/src/extensions/default/Git/src/Main.js
+++ b/src/extensions/default/Git/src/Main.js
@@ -344,27 +344,35 @@ define(function (require, exports) {
var _toggleMenuEntriesState = false,
_divider1 = null,
- _divider2 = null;
+ _divider2 = null,
+ _divider3 = null;
function toggleMenuEntries(bool) {
if (bool === _toggleMenuEntriesState) {
return;
}
var projectCmenu = Menus.getContextMenu(Menus.ContextMenuIds.PROJECT_MENU);
var workingCmenu = Menus.getContextMenu(Menus.ContextMenuIds.WORKING_SET_CONTEXT_MENU);
+ var tabbarCmenu = Menus.getContextMenu("tabbar-context-menu");
if (bool) {
_divider1 = projectCmenu.addMenuDivider();
_divider2 = workingCmenu.addMenuDivider();
+ _divider3 = tabbarCmenu.addMenuDivider();
projectCmenu.addMenuItem(CMD_ADD_TO_IGNORE);
workingCmenu.addMenuItem(CMD_ADD_TO_IGNORE);
+ tabbarCmenu.addMenuItem(CMD_ADD_TO_IGNORE);
projectCmenu.addMenuItem(CMD_REMOVE_FROM_IGNORE);
workingCmenu.addMenuItem(CMD_REMOVE_FROM_IGNORE);
+ tabbarCmenu.addMenuItem(CMD_REMOVE_FROM_IGNORE);
} else {
projectCmenu.removeMenuDivider(_divider1.id);
workingCmenu.removeMenuDivider(_divider2.id);
+ tabbarCmenu.removeMenuDivider(_divider3.id);
projectCmenu.removeMenuItem(CMD_ADD_TO_IGNORE);
workingCmenu.removeMenuItem(CMD_ADD_TO_IGNORE);
+ tabbarCmenu.removeMenuItem(CMD_ADD_TO_IGNORE);
projectCmenu.removeMenuItem(CMD_REMOVE_FROM_IGNORE);
workingCmenu.removeMenuItem(CMD_REMOVE_FROM_IGNORE);
+ tabbarCmenu.removeMenuItem(CMD_REMOVE_FROM_IGNORE);
}
_toggleMenuEntriesState = bool;
}
diff --git a/src/extensions/default/Git/src/ProjectTreeMarks.js b/src/extensions/default/Git/src/ProjectTreeMarks.js
index 966d4d5686..faeb6e1e23 100644
--- a/src/extensions/default/Git/src/ProjectTreeMarks.js
+++ b/src/extensions/default/Git/src/ProjectTreeMarks.js
@@ -201,4 +201,8 @@ define(function (require) {
detachEvents();
});
+ return {
+ isIgnored: isIgnored
+ };
+
});
diff --git a/src/extensions/default/Git/src/TabBarIntegration.js b/src/extensions/default/Git/src/TabBarIntegration.js
index 24453f3166..0336cf6a87 100644
--- a/src/extensions/default/Git/src/TabBarIntegration.js
+++ b/src/extensions/default/Git/src/TabBarIntegration.js
@@ -3,6 +3,7 @@ define(function (require) {
const Events = require("src/Events");
const Git = require("src/git/Git");
const Preferences = require("src/Preferences");
+ const ProjectTreeMarks = require("src/ProjectTreeMarks");
// the cache of file statuses by path
let fileStatusCache = {};
@@ -55,6 +56,19 @@ define(function (require) {
);
}
+ /**
+ * whether the file is gitignored or not
+ *
+ * @param {string} fullPath - the file path
+ * @returns {boolean} - if the file is gitignored it returns true otherwise false
+ */
+ function isIgnored(fullPath) {
+ if (!ProjectTreeMarks || !ProjectTreeMarks.isIgnored) {
+ return false;
+ }
+ return ProjectTreeMarks.isIgnored(fullPath);
+ }
+
// Update file status cache when Git status results are received
EventEmitter.on(Events.GIT_STATUS_RESULTS, function (files) {
@@ -85,6 +99,7 @@ define(function (require) {
return {
getFileStatus: getFileStatus,
isModified: isModified,
- isUntracked: isUntracked
+ isUntracked: isUntracked,
+ isIgnored: isIgnored
};
});
diff --git a/src/extensionsIntegrated/TabBar/main.js b/src/extensionsIntegrated/TabBar/main.js
index bf5d0c4c27..fd6ae9975e 100644
--- a/src/extensionsIntegrated/TabBar/main.js
+++ b/src/extensionsIntegrated/TabBar/main.js
@@ -150,9 +150,14 @@ define(function (require, exports, module) {
const TabBarIntegration = window.phoenixGitEvents.TabBarIntegration;
// find the Git status
- // if untracked we add the git-new class and U char
- // if modified we add the git-modified class and M char
- if (TabBarIntegration.isUntracked(entry.path)) {
+ // Check ignored FIRST (takes precedence over other statuses)
+ // if ignored we add the git-ignored class
+ // if untracked we add the git-new class
+ // if modified we add the git-modified class
+ if (TabBarIntegration.isIgnored(entry.path)) {
+ gitStatus = "Ignored";
+ gitStatusClass = "git-ignored";
+ } else if (TabBarIntegration.isUntracked(entry.path)) {
gitStatus = "Untracked";
gitStatusClass = "git-new";
} else if (TabBarIntegration.isModified(entry.path)) {
@@ -553,7 +558,7 @@ define(function (require, exports, module) {
const paneId = isSecondPane ? "second-pane" : "first-pane";
// show the context menu at mouse position
- MoreOptions.showMoreOptionsContextMenu(paneId, event.pageX, event.pageY, filePath);
+ MoreOptions.showMoreOptionsContextMenu(paneId, filePath, event.pageX, event.pageY);
});
}
@@ -768,6 +773,7 @@ define(function (require, exports, module) {
// handle when a single tab gets clicked
handleTabClick();
+ MoreOptions.init();
Overflow.init();
DragDrop.init($("#phoenix-tab-bar"), $("#phoenix-tab-bar-2"));
diff --git a/src/extensionsIntegrated/TabBar/more-options.js b/src/extensionsIntegrated/TabBar/more-options.js
index d8bbd41d91..b6df56139a 100644
--- a/src/extensionsIntegrated/TabBar/more-options.js
+++ b/src/extensionsIntegrated/TabBar/more-options.js
@@ -23,308 +23,143 @@
* The more options context menu is shown when a tab is right-clicked
*/
define(function (require, exports, module) {
- const DropdownButton = require("widgets/DropdownButton");
- const Strings = require("strings");
const CommandManager = require("command/CommandManager");
const Commands = require("command/Commands");
const FileSystem = require("filesystem/FileSystem");
+ const Menus = require("command/Menus");
+ const Strings = require("strings");
const Global = require("./global");
- // List of items to show in the context menu
- // Strings defined in `src/nls/root/strings.js`
- const items = [
- Strings.CLOSE_TAB,
- Strings.CLOSE_TABS_TO_THE_LEFT,
- Strings.CLOSE_TABS_TO_THE_RIGHT,
- Strings.CLOSE_SAVED_TABS,
- Strings.CLOSE_ALL_TABS,
- "---",
- Strings.CMD_FILE_RENAME,
- Strings.CMD_FILE_DELETE,
- Strings.CMD_SHOW_IN_TREE,
- "---",
- Strings.REOPEN_CLOSED_FILE
- ];
-
- /**
- * "CLOSE TAB"
- * this function handles the closing of the tab that was right-clicked
- *
- * @param {String} filePath - path of the file to close
- * @param {String} paneId - the id of the pane in which the file is present
- */
- function handleCloseTab(filePath, paneId) {
- if (filePath) {
- // Get the file object using FileSystem
- const fileObj = FileSystem.getFileForPath(filePath);
-
- // Execute close command with file object and pane ID
- CommandManager.execute(Commands.FILE_CLOSE, { file: fileObj, paneId: paneId });
- }
+ // these are Tab bar specific commands for the context menu
+ // not added in the Commands.js as Tab bar is not a core module but an extension
+ // read init function
+ const TABBAR_CLOSE_TABS_LEFT = "tabbar.closeTabsLeft";
+ const TABBAR_CLOSE_TABS_RIGHT = "tabbar.closeTabsRight";
+ const TABBAR_CLOSE_SAVED_TABS = "tabbar.closeSavedTabs";
+ const TABBAR_CLOSE_ALL = "tabbar.closeAllTabs";
+
+ // stores the context of the right-clicked tab (which file, which pane)
+ // this is set inside the showMoreOptionsContextMenu. read that func for more details
+ let _currentTabContext = { filePath: null, paneId: null };
+
+ // gets the working set (list of open files) for the given pane
+ function _getWorkingSet(paneId) {
+ return paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet;
}
- /**
- * "CLOSE ALL TABS"
- * This will close all tabs in the specified pane
- *
- * @param {String} paneId - the id of the pane ["first-pane", "second-pane"]
- */
- function handleCloseAllTabs(paneId) {
- if (!paneId) {
- return;
- }
-
- let workingSet;
- workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet;
- if (!workingSet || workingSet.length === 0) {
- return;
- }
-
- // close each file in the pane, start from the rightmost [to avoid index shifts]
- for (let i = workingSet.length - 1; i >= 0; i--) {
- const fileObj = FileSystem.getFileForPath(workingSet[i].path);
+ // closes files from right to left to avoid index shifts during iteration
+ function _closeFiles(files, paneId) {
+ for (let i = files.length - 1; i >= 0; i--) {
+ const fileObj = FileSystem.getFileForPath(files[i].path);
CommandManager.execute(Commands.FILE_CLOSE, { file: fileObj, paneId: paneId });
}
}
- /**
- * "CLOSE SAVED TABS"
- * This will close all tabs that are not dirty in the specified pane
- *
- * @param {String} paneId - the id of the pane ["first-pane", "second-pane"]
- */
- function handleCloseSavedTabs(paneId) {
- if (!paneId) {
- return;
- }
-
- let workingSet;
- workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet;
- if (!workingSet || workingSet.length === 0) {
- return;
- }
-
- // get all those entries that are not dirty
- const unmodifiedEntries = workingSet.filter((entry) => !entry.isDirty);
-
- // close each non-dirty file in the pane
- for (let i = unmodifiedEntries.length - 1; i >= 0; i--) {
- const fileObj = FileSystem.getFileForPath(unmodifiedEntries[i].path);
- CommandManager.execute(Commands.FILE_CLOSE, { file: fileObj, paneId: paneId });
- }
- }
-
- /**
- * "CLOSE TABS TO THE LEFT"
- * This function is responsible for closing all tabs to the left of the right-clicked tab
- *
- * @param {String} filePath - path of the file that was right-clicked
- * @param {String} paneId - the id of the pane in which the file is present
- */
- function handleCloseTabsToTheLeft(filePath, paneId) {
- if (!filePath) {
- return;
- }
-
- let workingSet;
- workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet;
- if (!workingSet) {
- return;
- }
-
- // find the index of the current file in the working set
- const currentIndex = workingSet.findIndex((entry) => entry.path === filePath);
-
- if (currentIndex > 0) {
- // we only proceed if there are tabs to the left
- // get all files to the left of the current file
- const filesToClose = workingSet.slice(0, currentIndex);
-
- // Close each file, starting from the rightmost [to avoid index shifts]
- for (let i = filesToClose.length - 1; i >= 0; i--) {
- const fileObj = FileSystem.getFileForPath(filesToClose[i].path);
- CommandManager.execute(Commands.FILE_CLOSE, { file: fileObj, paneId: paneId });
- }
+ // executes a command with the right-clicked tab's file as the target
+ function _executeWithFileContext(commandId, options = {}) {
+ if (_currentTabContext.filePath) {
+ // we need to get the file object from the file path, as the commandManager expects the file object
+ const fileObj = FileSystem.getFileForPath(_currentTabContext.filePath);
+ CommandManager.execute(commandId, { file: fileObj, ...options });
}
}
- /**
- * "CLOSE TABS TO THE RIGHT"
- * This function is responsible for closing all tabs to the right of the right-clicked tab
- *
- * @param {String} filePath - path of the file that was right-clicked
- * @param {String} paneId - the id of the pane in which the file is present
- */
- function handleCloseTabsToTheRight(filePath, paneId) {
- if (!filePath) {
- return;
- }
-
- let workingSet;
- workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet;
- if (!workingSet) {
- return;
- }
-
- // get the index of the current file in the working set
- const currentIndex = workingSet.findIndex((entry) => entry.path === filePath);
- // only proceed if there are tabs to the right
- if (currentIndex !== -1 && currentIndex < workingSet.length - 1) {
- // get all files to the right of the current file
- const filesToClose = workingSet.slice(currentIndex + 1);
-
- for (let i = filesToClose.length - 1; i >= 0; i--) {
- const fileObj = FileSystem.getFileForPath(filesToClose[i].path);
- CommandManager.execute(Commands.FILE_CLOSE, { file: fileObj, paneId: paneId });
- }
+ // **Close All Tabs**
+ // closes all tabs in the pane where the tab was right-clicked
+ function handleCloseAllTabs() {
+ const workingSet = _getWorkingSet(_currentTabContext.paneId);
+ if (workingSet && workingSet.length !== 0) {
+ // close everything in the pane
+ _closeFiles(workingSet, _currentTabContext.paneId);
}
}
- /**
- * "REOPEN CLOSED FILE"
- * This just calls the reopen closed file command. everthing else is handled there
- * TODO: disable the command if there are no closed files, look into the file menu
- */
- function reopenClosedFile() {
- CommandManager.execute(Commands.FILE_REOPEN_CLOSED);
- }
-
- /**
- * "RENAME FILE"
- * This function handles the renaming of the file that was right-clicked
- *
- * @param {String} filePath - path of the file to rename
- */
- function handleFileRename(filePath) {
- if (filePath) {
- // First ensure the sidebar is visible so users can see the rename action
- CommandManager.execute(Commands.SHOW_SIDEBAR);
-
- // Get the file object using FileSystem
- const fileObj = FileSystem.getFileForPath(filePath);
-
- // Execute the rename command with the file object
- CommandManager.execute(Commands.FILE_RENAME, { file: fileObj });
+ // **Close Saved Tabs**
+ // closes all saved tabs (not dirty) in the pane
+ function handleCloseSavedTabs() {
+ const workingSet = _getWorkingSet(_currentTabContext.paneId);
+ if (workingSet && workingSet.length !== 0) {
+ // filter out dirty tabs, only close the saved ones
+ const savedTabs = workingSet.filter(entry => !entry.isDirty);
+ _closeFiles(savedTabs, _currentTabContext.paneId);
}
}
- /**
- * "DELETE FILE"
- * This function handles the deletion of the file that was right-clicked
- *
- * @param {String} filePath - path of the file to delete
- */
- function handleFileDelete(filePath) {
- if (filePath) {
- // Get the file object using FileSystem
- const fileObj = FileSystem.getFileForPath(filePath);
+ // **Close Tabs to the Left**
+ // closes all tabs to the left of the right-clicked tab
+ function handleCloseTabsToTheLeft() {
+ const workingSet = _getWorkingSet(_currentTabContext.paneId);
+ if (!workingSet) { return; }
- // Execute the delete command with the file object
- CommandManager.execute(Commands.FILE_DELETE, { file: fileObj });
+ // find where the right-clicked tab is in the list
+ const currentIndex = workingSet.findIndex(entry => entry.path === _currentTabContext.filePath);
+ if (currentIndex > 0) {
+ // slice from start to currentIndex (not including currentIndex)
+ _closeFiles(workingSet.slice(0, currentIndex), _currentTabContext.paneId);
}
}
- /**
- * "SHOW IN FILE TREE"
- * This function handles showing the file in the file tree
- *
- * @param {String} filePath - path of the file to show in file tree
- */
- function handleShowInFileTree(filePath) {
- if (filePath) {
- // First ensure the sidebar is visible so users can see the file in the tree
- CommandManager.execute(Commands.SHOW_SIDEBAR);
-
- // Get the file object using FileSystem
- const fileObj = FileSystem.getFileForPath(filePath);
+ // **Close Tabs to the Right**
+ // closes all tabs to the right of the right-clicked tab
+ function handleCloseTabsToTheRight() {
+ const workingSet = _getWorkingSet(_currentTabContext.paneId);
+ if (!workingSet) { return; }
- // Execute the show in tree command with the file object
- CommandManager.execute(Commands.NAVIGATE_SHOW_IN_FILE_TREE, { file: fileObj });
+ // find where the right-clicked tab is in the list
+ const currentIndex = workingSet.findIndex(entry => entry.path === _currentTabContext.filePath);
+ if (currentIndex !== -1 && currentIndex < workingSet.length - 1) {
+ // slice from currentIndex+1 to end
+ _closeFiles(workingSet.slice(currentIndex + 1), _currentTabContext.paneId);
}
}
/**
- * This function is called when a tab is right-clicked
- * This will show the more options context menu
- *
+ * this function is called from Tabbar/main.js when a tab is right clicked
+ * it is responsible to show the context menu and also set the currentTabContext
* @param {String} paneId - the id of the pane ["first-pane", "second-pane"]
+ * @param {String} filePath - the path of the file that was right-clicked
* @param {Number} x - the x coordinate for positioning the menu
* @param {Number} y - the y coordinate for positioning the menu
- * @param {String} filePath - [optional] the path of the file that was right-clicked
*/
- function showMoreOptionsContextMenu(paneId, x, y, filePath) {
- const dropdown = new DropdownButton.DropdownButton("", items);
-
- // Append to document body for absolute positioning
- $("body").append(dropdown.$button);
-
- // Position the dropdown at the mouse coordinates
- dropdown.$button.css({
- position: "absolute",
- left: x + "px",
- top: y + "px",
- zIndex: 1000
- });
+ function showMoreOptionsContextMenu(paneId, filePath, x, y) {
+ _currentTabContext.filePath = filePath;
+ _currentTabContext.paneId = paneId;
- // Add a custom class to override the max-height, not sure why a scroll bar was coming but this did the trick
- dropdown.dropdownExtraClasses = "tabbar-context-menu";
-
- dropdown.showDropdown();
-
- $(".tabbar-context-menu").css("max-height", "300px");
-
- // handle the option selection
- dropdown.on("select", function (e, item) {
- _handleSelection(item, filePath, paneId);
- });
-
- // Remove the button after the dropdown is hidden
- dropdown.$button.css({
- display: "none"
- });
+ const contextMenu = Menus.getContextMenu("tabbar-context-menu");
+ const event = $.Event("contextmenu", { pageX: x, pageY: y });
+ contextMenu.open(event);
}
+
/**
- * Handles the selection of an option in the more options context menu
- *
- * @param {String} item - the item being selected
- * @param {String} filePath - the path of the file that was right-clicked
- * @param {String} paneId - the id of the pane ["first-pane", "second-pane"]
+ * this is the main function, it gets called only once on load from TabBar/main.js
+ * this registers the context menu and add the menu items inside it
*/
- function _handleSelection(item, filePath, paneId) {
- switch (item) {
- case Strings.CLOSE_TAB:
- handleCloseTab(filePath, paneId);
- break;
- case Strings.CLOSE_TABS_TO_THE_LEFT:
- handleCloseTabsToTheLeft(filePath, paneId);
- break;
- case Strings.CLOSE_TABS_TO_THE_RIGHT:
- handleCloseTabsToTheRight(filePath, paneId);
- break;
- case Strings.CLOSE_ALL_TABS:
- handleCloseAllTabs(paneId);
- break;
- case Strings.CLOSE_SAVED_TABS:
- handleCloseSavedTabs(paneId);
- break;
- case Strings.CMD_FILE_RENAME:
- handleFileRename(filePath);
- break;
- case Strings.CMD_FILE_DELETE:
- handleFileDelete(filePath);
- break;
- case Strings.CMD_SHOW_IN_TREE:
- handleShowInFileTree(filePath);
- break;
- case Strings.REOPEN_CLOSED_FILE:
- reopenClosedFile();
- break;
- }
+ function init() {
+ // these are the tab bar specific commands
+ CommandManager.register(Strings.CLOSE_TABS_TO_THE_LEFT, TABBAR_CLOSE_TABS_LEFT, handleCloseTabsToTheLeft);
+ CommandManager.register(Strings.CLOSE_TABS_TO_THE_RIGHT, TABBAR_CLOSE_TABS_RIGHT, handleCloseTabsToTheRight);
+ CommandManager.register(Strings.CLOSE_SAVED_TABS, TABBAR_CLOSE_SAVED_TABS, handleCloseSavedTabs);
+ CommandManager.register(Strings.CLOSE_ALL_TABS, TABBAR_CLOSE_ALL, handleCloseAllTabs);
+
+ // these commands already exist for working files, just reusing them
+ const menu = Menus.registerContextMenu("tabbar-context-menu");
+ menu.addMenuItem(Commands.FILE_CLOSE);
+ menu.addMenuItem(TABBAR_CLOSE_TABS_LEFT);
+ menu.addMenuItem(TABBAR_CLOSE_TABS_RIGHT);
+ menu.addMenuItem(TABBAR_CLOSE_SAVED_TABS);
+ menu.addMenuItem(TABBAR_CLOSE_ALL);
+ menu.addMenuDivider();
+ menu.addMenuItem(Commands.FILE_RENAME);
+ menu.addMenuItem(Commands.FILE_DELETE);
+ menu.addMenuItem(Commands.NAVIGATE_SHOW_IN_FILE_TREE);
+ menu.addMenuDivider();
+ menu.addMenuItem(Commands.FILE_REOPEN_CLOSED);
}
module.exports = {
- showMoreOptionsContextMenu
+ showMoreOptionsContextMenu,
+ init
};
});
diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js
index 986e42901d..ed03f8e14b 100644
--- a/src/nls/root/strings.js
+++ b/src/nls/root/strings.js
@@ -469,12 +469,10 @@ define({
"STATUSBAR_TASKS_RESTART": "Restart",
// Tab bar Strings
- "CLOSE_TAB": "Close Tab",
"CLOSE_TABS_TO_THE_RIGHT": "Close Tabs to the Right",
"CLOSE_TABS_TO_THE_LEFT": "Close Tabs to the Left",
"CLOSE_ALL_TABS": "Close All Tabs",
"CLOSE_SAVED_TABS": "Close Saved Tabs",
- "REOPEN_CLOSED_FILE": "Reopen Closed File",
// CodeInspection: errors/warnings
"ERRORS_NO_FILE": "No File Open",
@@ -1664,7 +1662,7 @@ define({
"CUSTOM_SNIPPETS_SAVE": "Save",
"CUSTOM_SNIPPETS_NO_DESCRIPTION": "No description",
"CUSTOM_SNIPPETS_NO_MATCHES": "No snippets match \"{0}\"",
- "CUSTOM_SNIPPETS_LEARN_MORE": "Add your own code hints to speed up coding - Learn More",
+ "CUSTOM_SNIPPETS_LEARN_MORE": "Add your own code hints to speed up coding - Learn More",
"CUSTOM_SNIPPETS_DUPLICATE_ERROR": "A snippet with abbreviation \"{0}\" already exists.",
"CUSTOM_SNIPPETS_SPACE_ERROR": "Space is not accepted as a valid abbreviation character.",
"CUSTOM_SNIPPETS_ABBR_LENGTH_ERROR": "Abbreviation cannot be more than 30 characters.",
diff --git a/src/styles/Extn-TabBar.less b/src/styles/Extn-TabBar.less
index 912425a9f7..59655a39fd 100644
--- a/src/styles/Extn-TabBar.less
+++ b/src/styles/Extn-TabBar.less
@@ -256,19 +256,19 @@
.tab.placeholder .tab-name {
font-style: italic;
- color: #888;
+ color: #999;
}
.dark .tab.placeholder .tab-name {
- color: #888;
+ color: #999;
}
.tab.placeholder.active .tab-name {
- color: #666;
+ color: #777;
}
.dark .tab.placeholder.active .tab-name {
- color: #aaa;
+ color: #bbb;
}
.tab.placeholder::after {
@@ -460,3 +460,21 @@
.dark .tab.git-new > .tab-icon:before {
color: #91CC41;
}
+
+.tab.git-ignored .tab-name {
+ color: #868888 !important;
+ font-style: italic;
+}
+
+.tab.git-ignored .tab-dirname {
+ color: #868888 !important;
+ font-style: italic;
+}
+
+.dark .tab.git-ignored .tab-name {
+ color: #868888 !important;
+}
+
+.dark .tab.git-ignored .tab-dirname {
+ color: #868888 !important;
+}
diff --git a/test/spec/Extn-Tabbar-integ-test.js b/test/spec/Extn-Tabbar-integ-test.js
index 9292bce749..1293801e96 100644
--- a/test/spec/Extn-Tabbar-integ-test.js
+++ b/test/spec/Extn-Tabbar-integ-test.js
@@ -1837,7 +1837,7 @@ define(function (require, exports, module) {
* @returns {jQuery} - The context menu element
*/
function getContextMenu() {
- return $(".tabbar-context-menu");
+ return $("#tabbar-context-menu");
}
it("should open context menu when right-clicking on a tab", async function () {
@@ -1846,22 +1846,22 @@ define(function (require, exports, module) {
expect($tab.length).toBe(1);
// Simulate a right-click (contextmenu) event on the tab
- $tab.trigger("contextmenu", {
+ const event = $.Event("contextmenu", {
pageX: 100,
pageY: 100
});
+ $tab.trigger(event);
// Wait for the context menu to appear
await awaitsFor(
function () {
- return getContextMenu().length > 0;
+ return getContextMenu().hasClass("open");
},
"Context menu to appear"
);
- // Verify the context menu is visible
- expect(getContextMenu().length).toBe(1);
- expect(getContextMenu().is(":visible")).toBe(true);
+ // Verify the context menu is open
+ expect(getContextMenu().hasClass("open")).toBe(true);
// Clean up - close the context menu by clicking elsewhere
$("body").click();
@@ -1869,36 +1869,47 @@ define(function (require, exports, module) {
// Wait for the context menu to disappear
await awaitsFor(
function () {
- return getContextMenu().length === 0;
+ return !getContextMenu().hasClass("open");
},
"Context menu to disappear"
);
});
- it("should close the tab when selecting 'Close Tab' from context menu", async function () {
+ it("should close the tab when selecting 'Close' from context menu", async function () {
// Get the tab element
const $tab = getTab(testFilePath);
// Right-click on the tab to open context menu
- $tab.trigger("contextmenu", {
+ // First trigger mousedown to make the tab active
+ const mousedownEvent = $.Event("mousedown", {
+ button: 2,
pageX: 100,
pageY: 100
});
+ $tab.trigger(mousedownEvent);
+
+ // Then trigger contextmenu to open the menu
+ const contextmenuEvent = $.Event("contextmenu", {
+ pageX: 100,
+ pageY: 100
+ });
+ $tab.trigger(contextmenuEvent);
// Wait for context menu to appear
await awaitsFor(
function () {
- return getContextMenu().length > 0;
+ return getContextMenu().hasClass("open");
},
"Context menu to appear"
);
- // Find and click the "Close Tab" option
+ // Find and click the "Close" option
const $closeTabOption = getContextMenu()
- .find("a.stylesheet-link")
+ .find(".menu-name")
.filter(function () {
- return $(this).text().trim() === Strings.CLOSE_TAB;
- });
+ return $(this).text().trim() === Strings.CMD_FILE_CLOSE;
+ })
+ .closest("li");
expect($closeTabOption.length).toBe(1);
$closeTabOption.click();
@@ -1946,25 +1957,34 @@ define(function (require, exports, module) {
const $tab = getTab(testFilePath);
// Right-click on the first tab to open context menu
- $tab.trigger("contextmenu", {
+ const mousedownEvent = $.Event("mousedown", {
+ button: 2,
pageX: 100,
pageY: 100
});
+ $tab.trigger(mousedownEvent);
+
+ const contextmenuEvent = $.Event("contextmenu", {
+ pageX: 100,
+ pageY: 100
+ });
+ $tab.trigger(contextmenuEvent);
// Wait for context menu to appear
await awaitsFor(
function () {
- return getContextMenu().length > 0;
+ return getContextMenu().hasClass("open");
},
"Context menu to appear"
);
- // Find and click the "Close tabs to the right" option
+ // Find and click the "Close Tabs to the Right" option
const $closeTabsToRightOption = getContextMenu()
- .find("a.stylesheet-link")
+ .find(".menu-name")
.filter(function () {
return $(this).text().trim() === Strings.CLOSE_TABS_TO_THE_RIGHT;
- });
+ })
+ .closest("li");
expect($closeTabsToRightOption.length).toBe(1);
$closeTabsToRightOption.click();
@@ -2018,25 +2038,34 @@ define(function (require, exports, module) {
const $tab = getTab(testFilePath3);
// Right-click on the third tab to open context menu
- $tab.trigger("contextmenu", {
+ const mousedownEvent = $.Event("mousedown", {
+ button: 2,
pageX: 100,
pageY: 100
});
+ $tab.trigger(mousedownEvent);
+
+ const contextmenuEvent = $.Event("contextmenu", {
+ pageX: 100,
+ pageY: 100
+ });
+ $tab.trigger(contextmenuEvent);
// Wait for context menu to appear
await awaitsFor(
function () {
- return getContextMenu().length > 0;
+ return getContextMenu().hasClass("open");
},
"Context menu to appear"
);
- // Find and click the "Close tabs to the left" option
+ // Find and click the "Close Tabs to the Left" option
const $closeTabsToLeftOption = getContextMenu()
- .find("a.stylesheet-link")
+ .find(".menu-name")
.filter(function () {
return $(this).text().trim() === Strings.CLOSE_TABS_TO_THE_LEFT;
- });
+ })
+ .closest("li");
expect($closeTabsToLeftOption.length).toBe(1);
$closeTabsToLeftOption.click();
@@ -2105,25 +2134,34 @@ define(function (require, exports, module) {
const $tab = getTab(testFilePath);
// Right-click on the tab to open context menu
- $tab.trigger("contextmenu", {
+ const mousedownEvent = $.Event("mousedown", {
+ button: 2,
+ pageX: 100,
+ pageY: 100
+ });
+ $tab.trigger(mousedownEvent);
+
+ const contextmenuEvent = $.Event("contextmenu", {
pageX: 100,
pageY: 100
});
+ $tab.trigger(contextmenuEvent);
// Wait for context menu to appear
await awaitsFor(
function () {
- return getContextMenu().length > 0;
+ return getContextMenu().hasClass("open");
},
"Context menu to appear"
);
- // Find and click the "Close saved tabs" option
+ // Find and click the "Close Saved Tabs" option
const $closeSavedTabsOption = getContextMenu()
- .find("a.stylesheet-link")
+ .find(".menu-name")
.filter(function () {
return $(this).text().trim() === Strings.CLOSE_SAVED_TABS;
- });
+ })
+ .closest("li");
expect($closeSavedTabsOption.length).toBe(1);
$closeSavedTabsOption.click();
@@ -2184,25 +2222,34 @@ define(function (require, exports, module) {
const $tab = getTab(testFilePath);
// Right-click on the tab to open context menu
- $tab.trigger("contextmenu", {
+ const mousedownEvent = $.Event("mousedown", {
+ button: 2,
+ pageX: 100,
+ pageY: 100
+ });
+ $tab.trigger(mousedownEvent);
+
+ const contextmenuEvent = $.Event("contextmenu", {
pageX: 100,
pageY: 100
});
+ $tab.trigger(contextmenuEvent);
// Wait for context menu to appear
await awaitsFor(
function () {
- return getContextMenu().length > 0;
+ return getContextMenu().hasClass("open");
},
"Context menu to appear"
);
- // Find and click the "Close all tabs" option
+ // Find and click the "Close All Tabs" option
const $closeAllTabsOption = getContextMenu()
- .find("a.stylesheet-link")
+ .find(".menu-name")
.filter(function () {
return $(this).text().trim() === Strings.CLOSE_ALL_TABS;
- });
+ })
+ .closest("li");
expect($closeAllTabsOption.length).toBe(1);
$closeAllTabsOption.click();