Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1148,8 +1148,20 @@
"description": "last focused"
},
"commandSettingLabelTabClosePinned": {
"message": "Close pinned tabs",
"description": "Close pinned tabs"
"message": "Pinned tabs behavior",
"description": "Pinned tabs behavior"
},
"commandSettingLabelTabClosePinnedNone": {
"message": "Do nothing",
"description": "Do nothing"
},
"commandSettingLabelTabClosePinnedClose": {
"message": "Close",
"description": "Close"
},
"commandSettingLabelTabClosePinnedDiscard": {
"message": "Discard",
"description": "Discard"
},
"commandSettingLabelRestoreCurrentWindow": {
"message": "Current window only",
Expand Down Expand Up @@ -1345,8 +1357,8 @@
"description": "Determines which tab should be focused next."
},
"commandSettingDescriptionTabClosePinned": {
"message": "Determines if pinned tabs can be closed or not.",
"description": "Determines if pinned tabs can be closed or not."
"message": "Determines how the close gesture handles pinned tabs: do nothing (ignore), close (remove tab), or discard (unload content but keep tab).",
"description": "Determines how the close gesture handles pinned tabs: do nothing (ignore), close (remove tab), or discard (unload content but keep tab)."
},
"commandSettingDescriptionRestoreCurrentWindow": {
"message": "Determines if only tabs which belong to the current window should be restored.",
Expand Down
20 changes: 16 additions & 4 deletions src/_locales/ja_JP/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1132,8 +1132,20 @@
"description": "last focused"
},
"commandSettingLabelTabClosePinned": {
"message": "ピン留めされたタブを閉じる",
"description": "Close pinned tabs"
"message": "ピン留めタブの動作",
"description": "Pinned tabs behavior"
},
"commandSettingLabelTabClosePinnedNone": {
"message": "何もしない",
"description": "Do nothing"
},
"commandSettingLabelTabClosePinnedClose": {
"message": "閉じる",
"description": "Close"
},
"commandSettingLabelTabClosePinnedDiscard": {
"message": "アンロード",
"description": "Discard"
},
"commandSettingLabelRestoreCurrentWindow": {
"message": "現在のウィンドウのみ",
Expand Down Expand Up @@ -1328,8 +1340,8 @@
"description": "Determines which tab should be focused next."
},
"commandSettingDescriptionTabClosePinned": {
"message": "ピン留めされたタブを閉じるかどうかを指定します。",
"description": "Determines if pinned tabs can be closed or not."
"message": "閉じるジェスチャーがピン留めタブをどう処理するか:何もしない(無視)、閉じる(タブを削除)、またはアンロード(コンテンツをアンロードしてタブを保持)",
"description": "Determines how the close gesture handles pinned tabs: do nothing (ignore), close (remove tab), or discard (unload content but keep tab)."
},
"commandSettingDescriptionRestoreCurrentWindow": {
"message": "タブの復元を現在のウィンドウのみにするかどうかを指定します。",
Expand Down
20 changes: 16 additions & 4 deletions src/_locales/ko_KR/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1132,8 +1132,20 @@
"description": "last focused"
},
"commandSettingLabelTabClosePinned": {
"message": "고정 탭 닫기",
"description": "Close pinned tabs"
"message": "고정 탭 동작",
"description": "Pinned tabs behavior"
},
"commandSettingLabelTabClosePinnedNone": {
"message": "아무것도 안 함",
"description": "Do nothing"
},
"commandSettingLabelTabClosePinnedClose": {
"message": "닫기",
"description": "Close"
},
"commandSettingLabelTabClosePinnedDiscard": {
"message": "언로드",
"description": "Discard"
},
"commandSettingLabelRestoreCurrentWindow": {
"message": "현재 창만",
Expand Down Expand Up @@ -1328,8 +1340,8 @@
"description": "Determines which tab should be focused next."
},
"commandSettingDescriptionTabClosePinned": {
"message": "고정된 탭의 닫기 여부를 정의합니다.",
"description": "Determines if pinned tabs can be closed or not."
"message": "닫기 제스처가 고정 탭을 처리하는 방법: 아무것도 안 함(무시), 닫기(탭 제거), 또는 언로드(내용을 언로드하지만 탭 유지)",
"description": "Determines how the close gesture handles pinned tabs: do nothing (ignore), close (remove tab), or discard (unload content but keep tab)."
},
"commandSettingDescriptionRestoreCurrentWindow": {
"message": "현재 창에 속한 탭만 복원할지 여부를 결정합니다.",
Expand Down
20 changes: 16 additions & 4 deletions src/_locales/zh_CN/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1132,8 +1132,20 @@
"description": "last focused"
},
"commandSettingLabelTabClosePinned": {
"message": "关闭固定的标签页",
"description": "Close pinned tabs"
"message": "固定标签页的处理方式",
"description": "Pinned tabs behavior"
},
"commandSettingLabelTabClosePinnedNone": {
"message": "不操作",
"description": "Do nothing"
},
"commandSettingLabelTabClosePinnedClose": {
"message": "关闭",
"description": "Close"
},
"commandSettingLabelTabClosePinnedDiscard": {
"message": "卸载",
"description": "Discard"
},
"commandSettingLabelRestoreCurrentWindow": {
"message": "仅当前窗口",
Expand Down Expand Up @@ -1328,8 +1340,8 @@
"description": "Determines which tab should be focused next."
},
"commandSettingDescriptionTabClosePinned": {
"message": "决定是否关闭固定的标签页。",
"description": "Determines if pinned tabs can be closed or not."
"message": "决定关闭手势对固定标签页的处理方式:不操作(忽略)、关闭(移除标签页)、或卸载(清空内容但保留标签页)",
"description": "Determines how the close gesture handles pinned tabs: do nothing (ignore), close (remove tab), or discard (unload content but keep tab)."
},
"commandSettingDescriptionRestoreCurrentWindow": {
"message": "决定是否只恢复属于当前窗口的标签页。",
Expand Down
20 changes: 16 additions & 4 deletions src/_locales/zh_TW/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1132,8 +1132,20 @@
"description": "last focused"
},
"commandSettingLabelTabClosePinned": {
"message": "關閉釘選的分頁",
"description": "Close pinned tabs"
"message": "釘選分頁的處理方式",
"description": "Pinned tabs behavior"
},
"commandSettingLabelTabClosePinnedNone": {
"message": "不操作",
"description": "Do nothing"
},
"commandSettingLabelTabClosePinnedClose": {
"message": "關閉",
"description": "Close"
},
"commandSettingLabelTabClosePinnedDiscard": {
"message": "卸載",
"description": "Discard"
},
"commandSettingLabelRestoreCurrentWindow": {
"message": "僅目前的視窗",
Expand Down Expand Up @@ -1328,8 +1340,8 @@
"description": "Determines which tab should be focused next."
},
"commandSettingDescriptionTabClosePinned": {
"message": "決定被釘選的分頁是否能被關閉",
"description": "Determines if pinned tabs can be closed or not."
"message": "決定關閉手勢對釘選分頁的處理方式:不操作(忽略)、關閉(移除分頁)、或卸載(清空內容但保留分頁)",
"description": "Determines how the close gesture handles pinned tabs: do nothing (ignore), close (remove tab), or discard (unload content but keep tab)."
},
"commandSettingDescriptionRestoreCurrentWindow": {
"message": "決定是否僅還原屬於目前視窗的分頁",
Expand Down
67 changes: 65 additions & 2 deletions src/core/commands.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,71 @@ export async function NewTab (sender, data) {


export async function CloseTab (sender, data) {
// remove tab if not pinned or remove-pinned-tabs option is enabled
if (this.getSetting("closePinned") || !sender.tab.pinned) {
let closePinnedBehavior = this.getSetting("closePinned");

// Handle backward compatibility: convert boolean to string
if (typeof closePinnedBehavior === "boolean") {
closePinnedBehavior = closePinnedBehavior ? "close" : "none";
}

// If tab is pinned and behavior is "none", do nothing
if (sender.tab.pinned && closePinnedBehavior === "none") {
return;
}

// If tab is pinned and behavior is "discard"
if (sender.tab.pinned && closePinnedBehavior === "discard") {
try {
const tabs = await browser.tabs.query({
windowId: sender.tab.windowId,
active: false,
hidden: false
});

// if there are other tabs to focus
if (tabs.length > 0) {
let nextTab = null;
const nextFocusSetting = this.getSetting("nextFocus");

switch (nextFocusSetting) {
case "default":
case "next":
// get closest tab to the right (if not found it will return the closest tab to the left)
nextTab = tabs.reduce((acc, cur) =>
(acc.index <= sender.tab.index && cur.index > acc.index) || (cur.index > sender.tab.index && cur.index < acc.index) ? cur : acc
);
break;

case "previous":
// get closest tab to the left (if not found it will return the closest tab to the right)
nextTab = tabs.reduce((acc, cur) =>
(acc.index >= sender.tab.index && cur.index < acc.index) || (cur.index < sender.tab.index && cur.index > acc.index) ? cur : acc
);
break;

case "recent":
// get the previous tab
nextTab = tabs.reduce((acc, cur) => acc.lastAccessed > cur.lastAccessed ? acc : cur);
break;
}

if (nextTab) {
await browser.tabs.update(nextTab.id, { active: true });
// Discard the tab after switching focus (cannot discard active tab)
await browser.tabs.discard(sender.tab.id);
return true;
}
}

return false;
} catch (error) {
console.error("Error discarding pinned tab:", error);
return false;
}
}

// remove tab if not pinned or remove-pinned-tabs option is "close"
if (closePinnedBehavior === "close" || !sender.tab.pinned) {
const tabs = await browser.tabs.query({
windowId: sender.tab.windowId,
active: false,
Expand Down
2 changes: 1 addition & 1 deletion src/resources/json/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"command": "CloseTab",
"settings": {
"nextFocus": "default",
"closePinned": true
"closePinned": "close"
},
"group": "tabs"
},
Expand Down
8 changes: 7 additions & 1 deletion src/views/options/fragments/command-setting-templates.inc
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,14 @@

<template data-commands="CloseTab">
<span data-i18n="commandSettingLabelTabClosePinned" class="cb-setting-name"></span>
<input name="closePinned" class="toggle-button" type="checkbox">
<p data-i18n="commandSettingDescriptionTabClosePinned" class="cb-setting-description"></p>
<div class="select-wrapper">
<select name="closePinned" class="select-field">
<option value="none" data-i18n="commandSettingLabelTabClosePinnedNone"></option>
<option value="close" data-i18n="commandSettingLabelTabClosePinnedClose"></option>
<option value="discard" data-i18n="commandSettingLabelTabClosePinnedDiscard"></option>
</select>
</div>
</template>

<template data-commands="RestoreTab">
Expand Down