Skip to content
Open
19 changes: 18 additions & 1 deletion Debug/addons/tabplus/options.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<div class="panel" style="display: block;">
<div class="panel" style="display: block;">
<label>View</label>
<br>
<label><input type="checkbox" id="Icon">Icon</label><br>
<input type="checkbox" id="Drive"><label for="Drive" id="_Drive">Drive</label><br>
<label><input type="checkbox" id="Close">Close Tab</label><br>
<label><input type="checkbox" id="CloseAll">Close all tabs</label><br>
<label><input type="checkbox" id="!NoLock">Lock</label><br>
<label><input type="checkbox" id="Protected">@wmploc.dll,-1714[Protected]</label><br>
<label><input type="checkbox" id="New">New Tab</label><br>
Expand Down Expand Up @@ -78,6 +79,22 @@
<input type="text" name="IconProtect" onchange="SetImage();" class="full">
</td>
</tr>
<tr>
<td class="full" style="vertical-align: bottom">
<label>New tab</label>
</td>
<td style="white-space: nowrap">
<button onclick="ShowIcon(document.F.NewTab, 'List');">Select</button>
</td>
<td style="white-space: nowrap">
<button onclick="RefX('NewTab');">Browse...</button>
</td>
</tr>
<tr>
<td class="full" colspan="3">
<input type="text" name="NewTab" onchange="SetImage();" class="full">
</td>
</tr>
</table>
</div>
<div class="panel" style="display: block;">
Expand Down
62 changes: 55 additions & 7 deletions Debug/addons/tabplus/script.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Addon_Id = "tabplus";
const Addon_Id = "tabplus";
let item = GetAddonElement(Addon_Id);
if (!item.getAttribute("Set")) {
item.setAttribute("Icon", 1);
Expand All @@ -23,6 +23,19 @@ if (window.Addon == 1) {
tids: [],
nSelected: [],

IsWin10OrLater: async function () {
let appVer, res, osVer;
appVer = await navigator.appVersion.split(';');
if (appVer[2]) {
res = /^\s*Windows NT\s+(\d+\.\d+)/i.exec(appVer[2]);
if (res && res[1] && parseFloat(res[1]) >= 10) {
return 1;
}
}

return 0;
},

Arrange: async function (Id, bWait) {
delete Addons.TabPlus.tids[Id];
const o = document.getElementById("tabplus_" + Id);
Expand All @@ -36,6 +49,9 @@ if (window.Addon == 1) {
if (o.lastChild && Addons.TabPlus.opt.New) {
o.removeChild(o.lastChild);
}
if (o.lastChild && Addons.TabPlus.opt.CloseAll) {
o.removeChild(o.lastChild);
}
let nDisp = o.getElementsByTagName("li").length;
while (nDisp > nCount) {
o.removeChild(o.lastChild);
Expand All @@ -60,7 +76,15 @@ if (window.Addon == 1) {
if (Addons.TabPlus.opt.Align > 1 && Addons.TabPlus.opt.Width) {
s.push(' style="text-align: center; width: 100%"');
}
s.push('>+</li>');
s.push('>', Addons.TabPlus.ImgNewTab, '</li>');
o.insertAdjacentHTML("beforeend", s.join(""));
}
if (Addons.TabPlus.opt.CloseAll) {
let s = ['<li class="tab3" onclick="Addons.TabPlus.CloseAll(', Id, ');return false"'];
if (Addons.TabPlus.opt.Align > 1 && Addons.TabPlus.opt.Width) {
s.push(' style="text-align: center; width: 100%"');
}
s.push('>', Addons.TabPlus.ImgCloseAll, '</li>');
o.insertAdjacentHTML("beforeend", s.join(""));
}
Addons.TabPlus.SetActiveColor(Id);
Expand Down Expand Up @@ -109,6 +133,15 @@ if (window.Addon == 1) {
}
},

CloseAll: async function (Id) {
const TC = await te.Ctrl(CTRL_TC, Id);
if (TC) {
for (var i = TC.Count; i--;) {
TC[i].Close();
}
}
},

Style: async function (TC, i, bRedraw, wait) {
let r = await Promise.all([TC[i], TC.Id]);
const FV = r[0];
Expand Down Expand Up @@ -511,6 +544,11 @@ if (window.Addon == 1) {

$.importScript("addons\\" + Addon_Id + "\\sync.js");

let newTabImage = "font:Segoe UI Emoji,0x271a";
if (Addons.TabPlus.IsWin10OrLater()) {
newTabImage = "font:Segoe UI Symbol,0xe109";
}

AddEvent("PanelCreated", async function (Ctrl, Id) {
const s = ['<ul id="tabplus_', Id, '" class="tab0" oncontextmenu="Addons.TabPlus.Popup(event,', Id, ');return false"'];
s.push(' ondblclick="Addons.TabPlus.DblClick(event,', Id, ');return false" onmousewheel="Addons.TabPlus.Wheel(event,', Id, ')" onresize="Resize();"');
Expand Down Expand Up @@ -581,7 +619,7 @@ if (window.Addon == 1) {
await Addons.TabPlus.Style(TC, i, true)
o = document.getElementById("tabplus_" + Id);
if (o) {
if (await TC.Count + (Addons.TabPlus.opt.New ? 1 : 0) != o.getElementsByTagName("li").length) {
if (await TC.Count + (Addons.TabPlus.opt.New ? 1 : 0) + (Addons.TabPlus.opt.CloseAll ? 1 : 0) != o.getElementsByTagName("li").length) {
o = null;
}
}
Expand Down Expand Up @@ -626,18 +664,28 @@ if (window.Addon == 1) {
onmouseout: "MouseOut()",
src: Addons.TabPlus.opt.IconClose || "font:Marlett,0x72"
}, r0),
GetImgTag({
draggable: "false",
"class": "button",
title: await GetText("Close all tabs"),
src: Addons.TabPlus.opt.IconClose || "font:Marlett,0x72"
}, r0),
GetImgTag({
draggable: "false",
src: Addons.TabPlus.opt.IconProtect || GetWinIcon(0xa00, "font:Segoe MDL2 Assets,0xea18", 0x602, "font:Segoe UI Emoji,0x26c9", 0, "font:Webdings,0x64")
}, r0),
GetImgTag({
draggable: "false",
"class": "button",
title: await GetText("New tab"),
src: Addons.TabPlus.opt.NewTab || newTabImage
}, r0)];
if (Addons.TabPlus.opt.New) {
r.push(GetText("New tab"));
}
Promise.all(r).then(function (r) {
Addons.TabPlus.ImgLock2 = r.shift();
Addons.TabPlus.ImgClose = r.shift();
Addons.TabPlus.ImgCloseAll = r.shift();
Addons.TabPlus.ImgProtect = r.shift();
Addons.TabPlus.str.NewTab = r.shift();
Addons.TabPlus.ImgNewTab = r.shift();
});
delete item;
} else {
Expand Down
9 changes: 5 additions & 4 deletions Debug/script/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ button {

.button, .button1 {
display: inline-block; *display: inline; *zoom: 1;
padding: 1px 1px;
padding: 3px;
text-decoration: none;
cursor: default;
outline: 0;
Expand All @@ -73,15 +73,15 @@ button {
cursor: default;
background-color: #e3e3e3;
border: 1px solid #a0a0a0;
padding: 0;
padding: 2px;
outline: 0;
white-space: nowrap;
vertical-align: middle;
}

.menu {
display: inline-block; *display: inline; *zoom: 1;
margin: 1px 5px;
margin: 3px 5px;
text-decoration: none;
color: #000;
cursor: default;
Expand All @@ -96,7 +96,7 @@ button {
color: #000;
background-color: #e3e3e3;
border: 1px solid #a0a0a0;
padding: 0 4px;
padding: 2px 4px;
margin: 0;
}

Expand Down Expand Up @@ -157,6 +157,7 @@ button {
list-style: none;
margin: 0;
padding: 0 1px;
line-height: 1.5em;
cursor: default;
position: relative;
}
Expand Down
19 changes: 17 additions & 2 deletions Debug/script/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ TabIndex = -1;
g_x = { Menu: null, Addons: null };
g_Chg = { Menus: false, Addons: false, Tab: false, Tree: false, View: false, Data: null };
g_arMenuTypes = ["Default", "Context", "Background", "Tabs", "Tree", "File", "Edit", "View", "Favorites", "Tools", "Help", "Systray", "System", "Alias"];
g_arFields = ["Name", "Path", "Type", "Icon", "Height"];
g_MenuType = "";
g_Id = "";
g_dlgAddons = null;
Expand Down Expand Up @@ -898,7 +899,7 @@ async function LoadMenus(nSelected) {
}
}

async function LoadX(mode, fn, form) {
async function LoadX(mode, fn, form, arExtFields) {
if (!g_x[mode]) {
if (!form) {
form = document.F;
Expand Down Expand Up @@ -956,7 +957,21 @@ async function LoadX(mode, fn, form) {
g_x[mode].length = i;
while (--i >= 0) {
const item = items[i];
SetData(g_x[mode][i], [item.getAttribute("Name"), item.text || item.textContent, item.getAttribute("Type"), item.getAttribute("Icon"), item.getAttribute("Height")]);
const values = [];
for (let index = 0; index < g_arFields.length; index++) {
if (index != 1) {
values.push(item.getAttribute(g_arFields[index]));
} else {
values.push(item.text || item.textContent);
}
}
if (arExtFields) {
for (let index = 0; index < arExtFields.length; index++) {
values.push(item.getAttribute(arExtFields[index]));
}
}

SetData(g_x[mode][i], values);
}
}
EnableSelectTag(g_x[mode]);
Expand Down
61 changes: 39 additions & 22 deletions Debug/script/sync1.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Tablacus Explorer
//Tablacus Explorer

te.ClearEvents();
te.About = AboutTE(2);
Expand Down Expand Up @@ -1288,6 +1288,27 @@ AddEvent("Refresh", function (Ctrl, pt) {
}
});

InsertFavoriteItem = function (xml, menus, item, FolderItem, s) {
if (s) {
item.setAttribute("Name", s.replace(/\\/g, "/"));
item.setAttribute("Filter", "");
let path = api.GetDisplayNameOf(FolderItem, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING | SHGDN_FORPARSINGEX);
if ("string" === typeof path) {
path = FolderItem.Path;
}
if (!FolderItem.Enum && fso.FileExists(path)) {
path = PathQuoteSpaces(path);
item.setAttribute("Type", "Exec");
} else {
item.setAttribute("Type", "Open");
}
item.text = path;
menus[0].appendChild(item);
SaveXmlEx("menus.xml", xml);
FavoriteChanged();
}
}

AddFavorite = function (FolderItem) {
const xml = te.Data.xmlMenus;
const menus = xml.getElementsByTagName("Favorites");
Expand All @@ -1302,26 +1323,14 @@ AddFavorite = function (FolderItem) {
if (!FolderItem) {
return;
}
InputDialog("Add Favorite", GetFolderItemName(FolderItem), function (s) {
if (s) {
item.setAttribute("Name", s.replace(/\\/g, "/"));
item.setAttribute("Filter", "");
let path = api.GetDisplayNameOf(FolderItem, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING | SHGDN_FORPARSINGEX);
if ("string" === typeof path) {
path = FolderItem.Path;
}
if (!FolderItem.Enum && fso.FileExists(path)) {
path = PathQuoteSpaces(path);
item.setAttribute("Type", "Exec");
} else {
item.setAttribute("Type", "Open");
}
item.text = path;
menus[0].appendChild(item);
SaveXmlEx("menus.xml", xml);
FavoriteChanged();
}
});

if (0) {
InputDialog("Add Favorite", GetFolderItemName(FolderItem), function (s) {
InsertFavoriteItem(xml, menus, item, FolderItem, s);
});
} else {
InsertFavoriteItem(xml, menus, item, FolderItem, GetFolderItemName(FolderItem));
}
}
}

Expand Down Expand Up @@ -1564,7 +1573,15 @@ AddEvent("Close", function (Ctrl) {
break;
case CTRL_SB:
case CTRL_EB:
return CanClose(Ctrl) || api.ILIsEqual(Ctrl, "about:blank") && Ctrl.Parent.Count < 2 ? S_FALSE : CloseView(Ctrl);
// When the user closes the last tab, navigate to "This PC".
let retValue = CanClose(Ctrl);
if (retValue == S_OK && Ctrl.Parent.Count <= 1) {
retValue = (api.ILIsEqual(Ctrl, ssfDRIVES) || api.ILIsEqual(Ctrl, "about:blank")) ? S_FALSE : S_OK;
if (!api.ILIsEqual(Ctrl, ssfDRIVES)) {
Ctrl.Navigate(ssfDRIVES, SBSP_NEWBROWSER);
}
}
return retValue;
case CTRL_TC:
SetDisplay("Panel_" + Ctrl.Id, "none");
break;
Expand Down