diff --git a/README.md b/README.md
index e69de29..f24fb2a 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,27 @@
+[](https://addons.mozilla.org/firefox/addon/tab-utilities-fixed/)
+[]()
+[]()
+[]()
+
+# Tab Utilities Fixed (Deprecated)
+
+[Tab Utilities](https://addons.mozilla.org/firefox/addon/tab-utilities/)'s compatibility fixes release.
+
+The project's focused goal: Compatibility fixes for Firefox 28 (with orange 'Firefox' button or Pale Moon) to the latest Firefox Beta (tested for Windows).
+
+Issue reports and patches are welcome.
+
+## Deprecated
+This project has been deprecated due to the new browser extension standard ([WebExtensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions); [W3C](https://browserext.github.io/browserext/); [Terminology](https://wiki.mozilla.org/Add-ons/Terminology)) to Firefox 57 and difficult to maintain, it still has some bugs in the final version, such as full screen support, as well as other quirks.
+
+If you would, you can continue to report problems (but no guaranteed for repair) or recommend alternatives on the issues.
+
+### My collections on AMO site
+* [WebExtensions for tabs](https://addons.mozilla.org/firefox/collections/yfdyh000/webextensions-for-tabs/)
+* [WebExtensions](https://addons.mozilla.org/firefox/collections/yfdyh000/webextensions/)
+
+## Resources
+[newer TODO board](https://github.com/yfdyh000/tabutils/projects);
+[older TODO and notes](https://github.com/yfdyh000/tabutils/wiki/TODO).
+
+[Release versions and notes](https://github.com/yfdyh000/tabutils/releases) < may include the latest unsigned version.
diff --git a/chrome.manifest b/chrome.manifest
index a5afe7d..c42efd4 100644
--- a/chrome.manifest
+++ b/chrome.manifest
@@ -1,5 +1,6 @@
content tabutils chrome/content/
skin tabutils classic/1.0 chrome/skin/
+resource tabmixplus modules/
overlay chrome://browser/content/browser.xul chrome://tabutils/content/tabutils.xul
overlay chrome://browser/content/places/placesOverlay.xul chrome://tabutils/content/placesOverlay.xul
diff --git a/chrome/content/bookmarkProperties.xul b/chrome/content/bookmarkProperties.xul
index b0be7f0..9dc75fb 100644
--- a/chrome/content/bookmarkProperties.xul
+++ b/chrome/content/bookmarkProperties.xul
@@ -3,13 +3,16 @@
diff --git a/chrome/content/content.js b/chrome/content/content.js
new file mode 100644
index 0000000..9b305dc
--- /dev/null
+++ b/chrome/content/content.js
@@ -0,0 +1,20 @@
+// This frame script is used to assist Tab Utilities Fixed, to avoid performance degradation in e10s.
+
+var getLinksSelected = function() {
+ let links = content.document.links;
+ let selection = content.getSelection();
+ if (!links || !selection) return [];
+
+ let linkURLs = [];
+ //console.time('checkLinkSelected');
+ for (let link of links) {
+ if (selection.containsNode(link, true) && (link.offsetHeight > 0) && linkURLs.indexOf(link.href) == -1)
+ linkURLs.push(link.href);
+ }
+ //console.timeEnd('checkLinkSelected');
+ return linkURLs;
+};
+
+sendAsyncMessage("tabutils-fixed:LinksSelected", {
+ links : getLinksSelected()
+});
diff --git a/chrome/content/preferences.xul b/chrome/content/preferences.xul
index 66476c8..0e8ae78 100644
--- a/chrome/content/preferences.xul
+++ b/chrome/content/preferences.xul
@@ -5,8 +5,6 @@
%browserDTD;
-
-%tabBrowserDTD;
%tabsDTD;
@@ -21,8 +19,8 @@
-
+
@@ -575,16 +573,14 @@
-
+
+
-
-
-
-
@@ -1052,9 +1048,9 @@
var preferences = document.getElementsByTagName("preference");
for (let preference of preferences) {
str += 'pref(';
- str += preference.name.quote();
+ str += JSON.stringify(preference.name);
str += ', ';
- str += preference.type == typeof preference.value ? preference.value.quote() :
+ str += preference.type == typeof preference.value ? JSON.stringify(preference.value) :
preference.inverted ? !preference.value : preference.value;
str += ');\n';
}
@@ -1155,7 +1151,9 @@
}
function closeButtons() {
- $("tabClipWidth").disabled = ($("closeButtons").value & 0x0f) != 1;
+ var value = $("closeButtons").value;
+ $("tabClipWidth").disabled = (value != 1) && (value != 10);
+ $("c.closeButtons").disabled = value == 2;
}
function hideLoadInBackground() {
@@ -1313,8 +1311,10 @@
if(!aPane._inited)
return;
- aPane.setAttribute('lastSelected', [tabbox.selectedIndex for (tabbox of aPane.getElementsByTagName('tabbox'))].join());
+ let tabbox = aPane.getElementsByTagName('tabbox')[0];
+ if (tabbox)
+ aPane.setAttribute('lastSelected', tabbox.selectedIndex);
}
]]>
-
\ No newline at end of file
+
diff --git a/chrome/content/tabutils-mt.js b/chrome/content/tabutils-mt.js
index a13988d..92d92f7 100644
--- a/chrome/content/tabutils-mt.js
+++ b/chrome/content/tabutils-mt.js
@@ -42,8 +42,8 @@ tabutils._multirowTabs = function() {
}, false);
TU_hookCode("gBrowser.mTabContainer._getDropIndex",
- [/event.screenX.*width \/ 2/g, function(s) s + " && " + s.replace("screenX", "screenY", "g").replace("width / 2", "height")
- + " || " + s.replace("screenX", "screenY", "g").replace("width / 2", "height * 0")]
+ [/event.screenX.*width \/ 2/g, function(s) s + " && " + s.replace(/screenX/g, "screenY").replace("width / 2", "height")
+ + " || " + s.replace(/screenX/g, "screenY").replace("width / 2", "height * 0")]
);
tabutils.addEventListener(gBrowser.mTabContainer, "dragover", function(event) {
@@ -75,7 +75,7 @@ tabutils._multirowTabs = function() {
if (TU_getPref("extensions.tabutils.disableTabMoveAnimation", true)) {
TU_hookFunc(arguments.callee.caller.toString().match(/^.*{|var (ind|tabStrip|ltr).*|var pixelsToScroll[\s\S]*$/g).join("\n"),
[/.*scrollByPixels.*/, ";"],
- [/.*effects == "move"[\s\S]*?(?=var (newIndex|scrollRect|rect))/, ""]
+ [/.*effects == "move"[\s\S]*?(?=var (newIndex|scrollRect|rect))/, ""] // needs fix
).apply(this, arguments);
return;
}
@@ -95,7 +95,7 @@ tabutils._multirowTabs = function() {
}, true);
TU_hookCode("gBrowser.moveTabTo", "{", function() {
- if (["onxbldrop", "ondrop"].indexOf(arguments.callee.caller.name) > -1) {
+ if (TMP_console.isCallerInList(["onxbldrop", "ondrop"])) {
if (aTab.pinned) {
if (aIndex >= this._numPinnedTabs)
this.pinTab(aTab, false);
diff --git a/chrome/content/tabutils-st.js b/chrome/content/tabutils-st.js
index 8c66600..8d45274 100644
--- a/chrome/content/tabutils-st.js
+++ b/chrome/content/tabutils-st.js
@@ -113,6 +113,11 @@ tabutils._stackTabs = function() {
if (bTab.getAttribute("group-counter") == 1) {
bTab.setAttribute("group-collapsed", !options.expand && TU_getPref("extensions.tabutils.autoCollapseNewStack", true));
this.mTabContainer.mTabstrip.ensureElementIsVisible(bTab);
+ if (bTab.image && TU_getPref('extensions.tabutils.colorStackFromFavicon', false))
+ Services.mozIColorAnalyzer.findRepresentativeColor(makeURI(bTab.image), function(success, color) {
+ if (success)
+ this.updateStack(bTab, {color: "#" + ("000000" + color.toString(16)).slice(-6)});
+ }.bind(this));
}
//must happen after "group" is set to avoid bypassing stack, and
@@ -221,6 +226,10 @@ tabutils._stackTabs = function() {
let tabs = this.siblingTabsOf(aTab);
if (tabs.length == 0)
return;
+ if (tabs.length == 1 && TU_getPref("extensions.tabutils.autoCleanupStack", false)) {
+ gBrowser.detachTab(aTab);
+ return;
+ }
if (typeof aTab == "string") {
aTab = tabs[0];
@@ -471,7 +480,7 @@ tabutils._stackTabs = function() {
}
}
- let lastTab = this.getLastSelectedTab();
+ lastTab = this.getLastSelectedTab();
if (lastTab && lastTab.hasAttribute("group") &&
lastTab.getAttribute("group") != aTab.getAttribute("group") &&
TU_getPref("extensions.tabutils.autoCollapseStackOnBlur", false))
@@ -495,8 +504,8 @@ tabutils._stackTabs = function() {
});
TU_hookCode("gBrowser.loadTabs",
- [/(?=var tabNum)/, "var tabs = [firstTabAdded || this.mCurrentTab];"],
- [/(?=.*aReplace.*\n.*moveTabTo.*)/, "tabs.push(tab);"],
+ [/(?=(?:var|let) tabNum)/, "var tabs = [firstTabAdded || this.mCurrentTab];"],
+ [/(?=if\s*\(.*\n.*moveTabTo.*tab.*)/, "tabs.push(tab);"],
[/(?=.*!aLoadInBackground.*)/, function() {
if (tabs.length > 1 && TU_getPref("extensions.tabutils.autoStack", false))
this.stackTabs(tabs);
@@ -505,16 +514,16 @@ tabutils._stackTabs = function() {
TU_hookCode("gBrowser.mTabContainer._selectNewTab", "aNewTab.hidden", "$& || aNewTab.collapsed");
- TU_hookCode("gBrowser.createTooltip", /(tab|tn).getAttribute\("label"\)/, function(s, s1) (function() {
- $1.mOverTwisty ? $1.hasAttribute("group-collapsed") ?
+ TU_hookCode("gBrowser.createTooltip", /(?:tab\._.+)(tab|tn).getAttribute\("label"\)/, function(s, s1) (function() {
+ a1.mOverTwisty ? a1.hasAttribute("group-collapsed") ?
document.getElementById("context_collapseStack").getAttribute("label_expand") :
document.getElementById("context_collapseStack").getAttribute("label_collapse")
- : this.isCollapsedStack($1) ?
+ : this.isCollapsedStack(a1) ?
TU_getPref("extensions.tabutils.mouseHoverPopup", true) ?
event.preventDefault() :
- this.siblingTabsOf($1).map(function($1) ($1.hasAttribute("group-selected") ? "> " : "# ") + $0).join("\n") :
- $0
- }).toString().replace(/^.*{|}$/g, "").replace("$0", s, "g").replace("$1", s1, "g"));
+ this.siblingTabsOf(a1).map(function(a1) (a1.hasAttribute("group-selected") ? "> " : "# ") + a0).join("\n") :
+ a0
+ }).toString().replace(/^.*{|}$/g, "").replace(/a0/g, s).replace(/a1/g, s1));
gBrowser._setMenuitemAttributes = function _setMenuitemAttributes(aItem, aTab) {
["label", "crop", "image"].forEach(function(aProp) {
diff --git a/chrome/content/tabutils-vt.js b/chrome/content/tabutils-vt.js
index 6e370bb..e174dab 100644
--- a/chrome/content/tabutils-vt.js
+++ b/chrome/content/tabutils-vt.js
@@ -6,6 +6,8 @@ tabutils._verticalTabs = function() {
var [start, end, size] = vertical ? ["top", "bottom", "height"]
: ["left", "right", "width"];
}],
+ ["left:", "[start]:", "g"], // Bug 971630 [Fx29]
+ ["right:", "[end]:", "g"],
[".left", "[start]", "g"],
[".right", "[end]", "g"],
[".width", "[size]", "g"]
@@ -31,34 +33,48 @@ tabutils._verticalTabs = function() {
gBrowser.mTabContainer.visible = aShow;
});
- TU_hookCode("FullScreen.toggle", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
- for (let fullScrToggler of this._fullScrTogglers) {
- fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
- fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
- }
- });
-
- TU_hookCode("FullScreen.enterDomFullscreen", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
- for (let fullScrToggler of this._fullScrTogglers) {
- fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
- fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
- }
- });
+ if (tabutils.fxVersion >= 35.0) { // Bug 1071821 [Fx35]
+ // I did not find a compatible approach
+ TU_hookCode("FullScreen.toggle", /.*if.*\(\!this\._fullScrToggler\).*\n.*\n.*\n.*\n.*\}/, function() {
+ if (!this._eventLoaded) { // the equivalent to "if (!this._fullScrToggler)"
+ for (let fullScrToggler of this._fullScrTogglers) {
+ fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
+ fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
+ fullScrToggler.collapsed = false;
+ }
+ this._eventLoaded = true;
+ }
+ });
- TU_hookCode("FullScreen.cleanup", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
- for (let fullScrToggler of this._fullScrTogglers) {
- fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
- fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
- }
- });
+ } else { // Earlier than Fx35
+ TU_hookCode("FullScreen.toggle", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
+ for (let fullScrToggler of this._fullScrTogglers) {
+ fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
+ fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
+ fullScrToggler.hidden = false;
+ }
+ });
+ TU_hookCode("FullScreen.enterDomFullscreen", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
+ for (let fullScrToggler of this._fullScrTogglers) {
+ fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
+ fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
+ }
+ });
- TU_hookCode("FullScreen.mouseoverToggle", /.*collapsed = aShow.*/, function() {
+ TU_hookCode("FullScreen.cleanup", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
+ for (let fullScrToggler of this._fullScrTogglers) {
+ fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
+ fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
+ }
+ });
+ }
+ TU_hookCode("FullScreen.mouseoverToggle", /.*(collapsed|hidden) = aShow.*/, function() {
let tabBarPosition = TU_getPref("extensions.tabutils.tabBarPosition");
- this._fullScrTogglers[0].collapsed = aShow;
- this._fullScrTogglers[1].collapsed = aShow || tabBarPosition != 1;
- this._fullScrTogglers[2].collapsed = aShow || tabBarPosition != 2;
- this._fullScrTogglers[3].collapsed = aShow || tabBarPosition != 3;
- });
+ this._fullScrTogglers[0].$1 = aShow;
+ this._fullScrTogglers[1].$1 = aShow || tabBarPosition != 1;
+ this._fullScrTogglers[2].$1 = aShow || tabBarPosition != 2;
+ this._fullScrTogglers[3].$1 = aShow || tabBarPosition != 3;
+ }); // Note: mozFullScreen is Fx9+. I did not add " || document.mozFullScreen" because it seems always return to false, unknown reason.
TU_hookCode("FullScreen.showXULChrome",
['fullscreenctls.parentNode == navbar', 'document.getElementById("TabsToolbar").parentNode == gNavToolbox'],
diff --git a/chrome/content/tabutils.js b/chrome/content/tabutils.js
index 679af62..142927c 100644
--- a/chrome/content/tabutils.js
+++ b/chrome/content/tabutils.js
@@ -29,13 +29,23 @@ var tabutils = {
window.addEventListener("load", this, false);
window.addEventListener("unload", this, false);
- if (gBrowser.mTabListeners.length > 0) { // Bug 463384 [Fx5]
+ if (typeof gBrowser._tabListeners === "object") { // Bug 1238685 [Fx46]
+ let tabFilters = gBrowser._tabFilters.values().next().value;
+ let tabListener = gBrowser._tabListeners.values().next().value;
+ gBrowser.browsers[0].webProgress.removeProgressListener(tabFilters);
+ tabFilters.removeProgressListener(tabListener);
+ tabListener = gBrowser.mTabProgressListener(tabListener.mTab, tabListener.mBrowser, tabListener.mBlank);
+ tabFilters.addProgressListener(tabListener, Ci.nsIWebProgress.NOTIFY_ALL);
+ gBrowser.browsers[0].webProgress.addProgressListener(tabFilters, Ci.nsIWebProgress.NOTIFY_ALL);
+ }
+ else if (gBrowser.mTabListeners.length > 0) { // Bug 463384 [Fx5]
+ let tabFilters = gBrowser.mTabFilters[0];
let tabListener = gBrowser.mTabListeners[0];
- gBrowser.browsers[0].webProgress.removeProgressListener(gBrowser.mTabFilters[0]);
- gBrowser.mTabFilters[0].removeProgressListener(gBrowser.mTabListeners[0]);
- gBrowser.mTabListeners[0] = gBrowser.mTabProgressListener(tabListener.mTab, tabListener.mBrowser, tabListener.mBlank);
- gBrowser.mTabFilters[0].addProgressListener(gBrowser.mTabListeners[0], Ci.nsIWebProgress.NOTIFY_ALL);
- gBrowser.browsers[0].webProgress.addProgressListener(gBrowser.mTabFilters[0], Ci.nsIWebProgress.NOTIFY_ALL);
+ gBrowser.browsers[0].webProgress.removeProgressListener(tabFilters);
+ tabFilters.removeProgressListener(tabListener);
+ tabListener = gBrowser.mTabProgressListener(tabListener.mTab, tabListener.mBrowser, tabListener.mBlank);
+ tabFilters.addProgressListener(tabListener, Ci.nsIWebProgress.NOTIFY_ALL);
+ gBrowser.browsers[0].webProgress.addProgressListener(tabFilters, Ci.nsIWebProgress.NOTIFY_ALL);
}
if (!("privateBrowsingEnabled" in gPrivateBrowsingUI)) { // Bug 799001 [Fx20]
@@ -44,14 +54,21 @@ var tabutils = {
});
}
- let os = Services.appinfo.OS; //WINNT, Linux or Darwin
- let version = parseFloat(Services.appinfo.version);
- document.documentElement.setAttribute("OS", os);
+ this.fxOnOS = Services.appinfo.OS; //WINNT, Linux or Darwin
+ this.fxVersion = parseFloat(Services.appinfo.version);
+ document.documentElement.setAttribute("OS", this.FxOnOS);
document.documentElement.setAttribute("v4", true);
document.documentElement.setAttribute("v6", true);
document.documentElement.setAttribute("v14", true);
document.documentElement.setAttribute("v17", true);
- document.documentElement.setAttribute("v29", version >= 29.0);
+ document.documentElement.setAttribute("v29", this.fxVersion >= 29.0);
+ document.documentElement.setAttribute("v31", this.fxVersion >= 31.0);
+ document.documentElement.setAttribute("v45", this.fxVersion >= 45.0);
+
+ gBrowser.mTabContainer._originalAdjustTabstripFunc = gBrowser.mTabContainer.adjustTabstrip;
+ gBrowser.mTabContainer.adjustTabstrip = function adjustTabstrip() {
+ this._originalAdjustTabstripFunc();
+ }
// Function.prototype.__defineGetter__("stack", function() {
// var stack = [];
@@ -91,7 +108,7 @@ var tabutils = {
return this.removeAttribute(aTab, aAttr);
aTab.setAttribute(aAttr, aVal);
- this._ss.setTabValue(aTab, aAttr, aVal);
+ this._ss.setTabValue(aTab, aAttr, String(aVal));
},
removeAttribute: function(aTab, aAttr) {
@@ -147,7 +164,7 @@ var tabutils = {
_eventListeners: [],
addEventListener: function() {
- document.addEventListener.apply(arguments[0], Array.slice(arguments, 1));
+ arguments[0].addEventListener.apply(arguments[0], Array.slice(arguments, 1));
this._eventListeners.push(arguments);
},
@@ -170,6 +187,7 @@ window.addEventListener("DOMContentLoaded", tabutils, false);
[
["@mozilla.org/browser/sessionstore;1", "nsISessionStore", "_ss", tabutils], // Bug 898732 [Fx26]
["@mozilla.org/docshell/urifixup;1", "nsIURIFixup"], // Bug 802026 [Fx20]
+ ["@mozilla.org/places/colorAnalyzer;1", "mozIColorAnalyzer"],
["@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper"],
["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"]
].forEach(function([aContract, aInterface, aName, aObject])
@@ -304,13 +322,17 @@ tabutils._PlacesUtilsExt = function() {
tabutils._openUILinkInTab = function() {
- //主页
+ //涓婚〉
TU_hookCode("BrowserGoHome", "browser.tabs.loadBookmarksInBackground", "extensions.tabutils.loadHomepageInBackground");
- //地址栏回车键
+ //鍦板潃鏍忓洖杞﹂敭
TU_hookCode("gURLBar.handleCommand",
- [/((aTriggeringEvent)\s*&&\s*(aTriggeringEvent.altKey))(?![\s\S]*\1)/, "let (newTabPref = TU_getPref('extensions.tabutils.openUrlInTab', true)) ($1 || newTabPref) && !(($2 ? $3 : false) && newTabPref && TU_getPref('extensions.tabutils.invertAlt', true))"],
- [/(?=.*openUILinkIn.*)/, function() {
+ [/(let altEnter\s*=.+)\s*((aTriggeringEvent|event)\s*&&\s*(aTriggeringEvent\.altKey|event\.altKey))\s*&&\s*.*isTabEmpty.*;/, function() {
+ let newTabPref = TU_getPref('extensions.tabutils.openUrlInTab', true);
+ let TU_altEnter = ($2 || newTabPref) && !(($3 ? $4 : false) && newTabPref && TU_getPref('extensions.tabutils.invertAlt', true));
+ $1TU_altEnter;
+ }],
+ [/(?=.*openUILinkIn\(url\, where\, params.*)/, function() {
params.inBackground = TU_getPref('extensions.tabutils.loadUrlInBackground', false);
params.disallowInheritPrincipal = !mayInheritPrincipal;
params.event = aTriggeringEvent || {};
@@ -319,16 +341,16 @@ tabutils._openUILinkInTab = function() {
["aTriggeringEvent.preventDefault();", ""],
["aTriggeringEvent.stopPropagation();", ""]
);
- TU_hookCode("openLinkIn", /(?=let uriObj)/, "w.gURLBar.handleRevert();");
+ // TU_hookCode("openLinkIn", /(?=let uriObj)/, "w.gURLBar.handleRevert();");
- //搜索栏回车键
+ //鎼滅储鏍忓洖杞﹂敭
if (BrowserSearch.searchBar)
TU_hookCode("BrowserSearch.searchBar.handleSearchCommand",
[/(\(aEvent && aEvent.altKey\)) \^ (newTabPref)/, "($1 || $2) && !($1 && $2 && TU_getPref('extensions.tabutils.invertAlt', true)) && !isTabEmpty(gBrowser.selectedTab)"],
[/"tab"/, "TU_getPref('extensions.tabutils.loadSearchInBackground', false) ? 'background' : 'foreground'"]
);
- //右键点击书签
+ //鍙抽敭鐐瑰嚮涔︾
TU_hookCode("BookmarksEventHandler.onClick",
["aEvent.button == 2", "$& && (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey || !TU_getPref('extensions.tabutils.rightClickBookmarks', 0))"],
["aEvent.button == 1", "aEvent.button > 0"],
@@ -340,7 +362,7 @@ tabutils._openUILinkInTab = function() {
);
TU_hookCode("whereToOpenLink", "e.button == 1", "e.button > 0");
- //保持菜单打开
+ //淇濇寔鑿滃崟鎵撳紑
TU_hookCode("BookmarksEventHandler.onClick", /.*hidePopup.*/, "if (!(TU_getPref('extensions.tabutils.middleClickBookmarks', 0) & 4)) $&");
TU_hookCode("checkForMiddleClick", /.*closeMenus.*/, "if (!(TU_getPref('extensions.tabutils.middleClickBookmarks', 0) & 4)) $&");
@@ -364,7 +386,7 @@ tabutils._openUILinkInTab = function() {
tabutils._openLinkInTab = function() {
- //强制在新标签页打开所有链接
+ //寮哄埗鍦ㄦ柊鏍囩椤垫墦寮鎵鏈夐摼鎺
TU_hookCode("contentAreaClick", /if[^{}]*event.button == 0[^{}]*{([^{}]|{[^{}]*}|{([^{}]|{[^{}]*})*})*(?=})/, "$&" + (function() {
if (tabutils.gOpenLinkInTab && !href.startsWith("javascript:")) {
openNewTabWith(href, linkNode.ownerDocument, null, event, false);
@@ -378,11 +400,11 @@ tabutils._openLinkInTab = function() {
aWhere = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;
});
- //强制在后台打开所有新标签页
+ //寮哄埗鍦ㄥ悗鍙版墦寮鎵鏈夋柊鏍囩椤
TU_hookCode("gBrowser.loadOneTab", /(?=var owner)/, "bgLoad = bgLoad && !tabutils.gLoadAllInForeground || tabutils.gLoadAllInBackground;");
TU_hookCode("gBrowser.loadTabs", /(?=var owner)/, "aLoadInBackground = aLoadInBackground && !tabutils.gLoadAllInForeground || tabutils.gLoadAllInBackground;");
- //强制在新标签页打开外部链接
+ //寮哄埗鍦ㄦ柊鏍囩椤垫墦寮澶栭儴閾炬帴
TU_hookCode("contentAreaClick", /if[^{}]*event.button == 0[^{}]*{([^{}]|{[^{}]*}|{([^{}]|{[^{}]*})*})*(?=})/, "$&" + (function() {
if (/^(https?|ftp)/.test(href) && TU_getPref("extensions.tabutils.openExternalInTab", false)) {
let ourDomain = tabutils.getDomainFromURI(linkNode.ownerDocument.documentURIObject);
@@ -395,7 +417,7 @@ tabutils._openLinkInTab = function() {
}
}).toString().replace(/^.*{|}$/g, ""));
- //外来链接
+ //澶栨潵閾炬帴
TU_hookCode("nsBrowserAccess.prototype.openURI", '"browser.link.open_newwindow"', 'isExternal ? "browser.link.open_external" : $&');
// L-click
@@ -415,7 +437,7 @@ tabutils._openLinkInTab = function() {
);
TU_hookCode("openNewTabWith", "aEvent.button == 1", "aEvent.button > 0");
- //拖曳链接
+ //鎷栨洺閾炬帴
TU_hookCode("handleDroppedLink", /.*loadURI.*/, function(s) (function() {
{
switch (true) {
@@ -429,12 +451,28 @@ tabutils._openLinkInTab = function() {
}
}
}).toString().replace(/^.*{|}$/g, "").replace("$0", s));
+ // For Fx51 and earlier
+
+ // The following edition applies to bug 92737 [Fx52] changes and later.
+ TU_hookCode("handleDroppedLink", /.*urls\.push\([\s\S]*?postData.*/g, function(s) (function() {
+ {
+ switch (true) {
+ case /\.(xpi|user\.js)$/.test(data.url): // Bug 846635 [Fx25]
+ case !TU_getPref("extensions.tabutils.dragAndGo", true):
+ $0;break;
+ case event.ctrlKey != TU_getPref("extensions.tabutils.invertDrag", false):
+ BrowserSearch.loadSearch(name || link.url, true);break;
+ default:
+ openNewTabWith(data.url, null, data.postData, event, true);break; // ", event.target.ownerDocument.documentURIObject" will break for example drop an local file (file:///) to about:newtab page, blocked for security reasons.
+ }
+ }
+ }).toString().replace(/^.*{|}$/g, "").replace("$0", s));
for (let b of gBrowser.browsers) {
b.droppedLinkHandler = handleDroppedLink;
}
- //在新标签页打开链接时继承历史
+ //鍦ㄦ柊鏍囩椤垫墦寮閾炬帴鏃剁户鎵垮巻鍙
TU_hookCode("gBrowser.loadOneTab",
["{", function() {
var currentTab = this.mCurrentTab;
@@ -451,7 +489,7 @@ tabutils._openLinkInTab = function() {
);
};
-//单窗口模式
+//鍗曠獥鍙fā寮
tabutils._singleWindowMode = function() {
if (TU_getPref("extensions.tabutils.singleWindowMode", false)) {
var win = (function() {
@@ -465,7 +503,7 @@ tabutils._singleWindowMode = function() {
if (win) {
TU_hookFunc((gBrowserInit.onLoad + gBrowserInit._delayedStartup).toString().match(/^.*{|if \(uriToLoad.*{([^{}]|{[^{}]*}|{([^{}]|{[^{}]*})*})*}|}$/g).join("\n"), // Bug 756313 [Fx19]
- ["{", "var uriToLoad = window.arguments && window.arguments[0];"],
+ ["{", "var uriToLoad = {window.arguments && window.arguments[0]};"],
["gBrowser.loadTabs(specs, false, true);", "this.gBrowser.loadTabs(specs, false, false);"],
["loadOneOrMoreURIs(uriToLoad);", "this.gBrowser.loadTabs(uriToLoad.split('|'), false, false);"],
[/.*loadURI.*\n.*/, "this.gBrowser.loadOneTab(uriToLoad, window.arguments[2], window.arguments[1] && window.arguments[1].split('=')[1], window.arguments[3] || null, false, window.arguments[4] || false);"],
@@ -489,7 +527,8 @@ tabutils._singleWindowMode = function() {
};
TU_hookCode("OpenBrowserWindow", "{", function() {
- if (TU_getPref("extensions.tabutils.singleWindowMode", false))
+ if (TU_getPref("extensions.tabutils.singleWindowMode", false)
+ && typeof options != "object") // .remote for non-e10s; .private (window)
return BrowserOpenTab() || gBrowser.getLastOpenedTab();
});
@@ -514,7 +553,7 @@ tabutils._singleWindowMode = function() {
});
TU_hookCode("gBrowser.replaceTabWithWindow", "{", function() {
- if (["_onDragEnd", "onxbldragend"].indexOf(arguments.callee.caller.name) > -1 && TU_getPref("extensions.tabutils.singleWindowMode", false))
+ if (TMP_console.isCallerInList(["_onDragEnd", "onxbldragend"]) && TU_getPref("extensions.tabutils.singleWindowMode", false))
return null;
});
@@ -541,7 +580,7 @@ tabutils._singleWindowMode = function() {
tabutils._tabOpeningOptions = function() {
- //新建标签页时利用已有空白标签页
+ //鏂板缓鏍囩椤垫椂鍒╃敤宸叉湁绌虹櫧鏍囩椤
TU_hookCode("gBrowser.addTab",
[/if \(arguments.length == 2[^{}]*\) {[^{}]*}/, "$&" + (function() {
if (!isBlankPageURL(aURI)) {
@@ -552,9 +591,10 @@ tabutils._tabOpeningOptions = function() {
}
}
}).toString().replace(/^.*{|}$/g, "")],
- [/(?=return t;)/, gBrowser.addTab.toString().match(/var (uriIsBlankPage|uriIsNotAboutBlank|uriIsAboutBlank).*|let docShellsSwapped[\s\S]*(?=\n.*docShellsSwapped.*)|if \((uriIsNotAboutBlank|.*uriIsAboutBlank)\) {([^{}]|{[^{}]*})*}/g).join("\n")] // Bug 716108 [Fx16]
- );
-
+ [/(?=return t;)/, gBrowser.addTab.toString().match(
+ /var (?:uriIsBlankPage|uriIsNotAboutBlank|uriIsAboutBlank).*|let (?:options|browserParams) = \{[\s\S]*?dispatchEvent.+;|if.+!usingPreloadedContent[\s\S]*catch[^}]+?\}[^}]+?\}|let (docShellsSwapped|usingPreloadedContent)[\s\S]*(?=\n.*(docShellsSwapped|usingPreloadedContent).*)|if \((uriIsNotAboutBlank|.*uriIsAboutBlank)\) {([^{}]|{[^{}]*})*}/g
+ ).join("\n").replace(/(?:var|let) b\s*=/, "b =")]
+ ); // Bug 716108 [Fx16], Bug 1077652 [Fx37], Bug 1243707 [Fx48], etc. Grab all about preload tab, open tab, barring select tab.
gBrowser.getBlankTab = function getBlankTab() {
var reuseBlank = TU_getPref("extensions.tabutils.reuseBlank", 1);
return reuseBlank & 1 && this.isBlankTab(this.mCurrentTab) ? this.mCurrentTab :
@@ -581,7 +621,7 @@ tabutils._tabOpeningOptions = function() {
};
TU_hookCode("isBlankPageURL", 'aURL == "about:blank"', "gInitialPages.indexOf(aURL) > -1");
- //自动关闭非主动打开的空白标签页
+ //鑷姩鍏抽棴闈炰富鍔ㄦ墦寮鐨勭┖鐧芥爣绛鹃〉
TU_hookCode("gBrowser.mTabProgressListener", /(?=var location)/, function() {
if (aWebProgress.DOMWindow.document.documentURI == "about:blank"
&& aRequest.QueryInterface(nsIChannel).URI.spec != "about:blank"
@@ -594,6 +634,10 @@ tabutils._tabOpeningOptions = function() {
}
});
+ // Not understand the purpose of the module,
+ // and it has been broken since Firefox 38.
+ // https://hg.mozilla.org/releases/mozilla-aurora/diff/120b108aa176/toolkit/mozapps/downloads/DownloadLastDir.jsm [Bug 1115248]
+ /*
let tmp = {};
Cu.import("resource://gre/modules/DownloadLastDir.jsm", tmp);
@@ -621,14 +665,15 @@ tabutils._tabOpeningOptions = function() {
getFileAsync.apply(this, arguments);
};
})();
+ */
- //在当前标签页的右侧打开新标签页
- //连续打开后台标签时保持原有顺序
+ //鍦ㄥ綋鍓嶆爣绛鹃〉鐨勫彸渚ф墦寮鏂版爣绛鹃〉
+ //杩炵画鎵撳紑鍚庡彴鏍囩鏃朵繚鎸佸師鏈夐『搴
TU_hookCode("gBrowser.addTab",
- [/\S*insertRelatedAfterCurrent\S*(?=\))/, "false"],
+ [/\S*insertRelatedAfterCurrent\S*(?=\))/, "false"], // replace "getBoolPref("browser.tabs.insertRelatedAfterCurrent")"
[/(?=(return t;)(?![\s\S]*\1))/, function() {
if (t.hasAttribute("opener")) {
- function shouldStack(tab) let (args = tab.arguments) (args.aReferrerURI || args.aRelatedToCurrent && args.aURI != "about:blank");
+ function shouldStack(tab) { let args = tab.arguments; return args.aReferrerURI || args.aRelatedToCurrent && args.aURI != "about:blank"; }
let lastRelatedTab = this.mCurrentTab;
let isStack = this.isStackedTab(lastRelatedTab);
@@ -655,7 +700,7 @@ tabutils._tabOpeningOptions = function() {
if ((function() {
switch (TU_getPref("extensions.tabutils.openTabNext", 1)) {
case 1: //All
- case 2: return aRelatedToCurrent || aReferrerURI || aURI != "about:blank"; //All but New Tab
+ case 2: return aRelatedToCurrent || aReferrerURI || (aURI != "about:blank" && aURI != "about:newtab"); //All but New Tab
case 3: return aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent; //None but Links
default: return false; //None
}
@@ -674,14 +719,15 @@ tabutils._tabOpeningOptions = function() {
this.updateCurrentBrowser(true);
});
- //新建标签页
+ //鏂板缓鏍囩椤
if (BrowserOpenTab.name == "BrowserOpenTab") { //Compatibility with Speed Dial
TU_hookCode("BrowserOpenTab",
[/.*openUILinkIn\((.*)\)/, function(s, s1) s.replace(s1, (
+ s1 = s1.replace(/,\s*\{\s*relatedToCurrent\s*\}/, ""),
s1 = s1.split(","),
s1.push("{inBackground: TU_getPref('extensions.tabutils.loadNewInBackground', false)}"),
s1.push("{relatedToCurrent: TU_getPref('extensions.tabutils.openTabNext', 1) == 1}"),
- s1.join().replace("},{", ",")
+ s1.join().replace(/\}\s*,\s*\{/, ",")
))] // Bug 490225 [Fx11]
);
}
@@ -694,12 +740,12 @@ tabutils._tabOpeningOptions = function() {
return this.mTabContainer.getElementsByAttribute("linkedpanel", this.mPanelContainer.lastChild.id)[0];
};
- //复制标签页
+ //澶嶅埗鏍囩椤
TU_hookCode("gBrowser.duplicateTab",
[/return/g, "var tab ="],
["}", function() {
this.detachTab(tab, true);
- if (["_onDrop", "onxbldrop", "duplicateTabIn"].indexOf(arguments.callee.caller.name) == -1) {
+ if (TMP_console.isCallerInList(["_onDrop", "onxbldrop", "duplicateTabIn"])) {
if (TU_getPref("extensions.tabutils.openDuplicateNext", true)) {
if (this.isStackedTab(aTab))
aTab = this.lastSiblingTabOf(aTab);
@@ -712,9 +758,9 @@ tabutils._tabOpeningOptions = function() {
}]
);
- //撤销关闭标签页
- TU_hookCode("gBrowser.moveTabTo", "{", function() {
- if (arguments.callee.caller.name == "ssi_undoCloseTab"
+ //鎾ら攢鍏抽棴鏍囩椤
+ TU_hookCode("gBrowser.moveTabTo", "}", function() {
+ if (TMP_console.callerName() == "ssi_undoCloseTab"
&& !TU_getPref("extensions.tabutils.restoreOriginalPosition", true))
return;
});
@@ -722,7 +768,7 @@ tabutils._tabOpeningOptions = function() {
tabutils._tabClosingOptions = function() {
- //关闭标签页时选择左侧/右侧/第一个/最后一个标签
+ //鍏抽棴鏍囩椤垫椂閫夋嫨宸︿晶/鍙充晶/绗竴涓/鏈鍚庝竴涓爣绛
gBrowser._tabsToSelect = function _tabsToSelect(aTabs) {
if (!aTabs)
aTabs = this.visibleTabs;
@@ -800,7 +846,7 @@ tabutils._tabClosingOptions = function() {
}
};
- //关闭标签页时选择亲属标签
+ //鍏抽棴鏍囩椤垫椂閫夋嫨浜插睘鏍囩
TU_hookCode("gBrowser.onTabSelect", "}", function() {
var panelId = aTab.linkedPanel + "#";
Array.forEach(this.visibleTabs, function(aTab) {
@@ -834,27 +880,27 @@ tabutils._tabClosingOptions = function() {
|| bTab.getAttribute("opener").startsWith(aTab.linkedPanel + "#");
};
- //关闭标签页时选择上次浏览的标签
+ //鍏抽棴鏍囩椤垫椂閫夋嫨涓婃娴忚鐨勬爣绛
gBrowser.mTabContainer._tabHistory = Array.slice(gBrowser.mTabs);
TU_hookCode("gBrowser.onTabOpen", "}", function() {
var tabHistory = this.mTabContainer._tabHistory;
tabHistory.splice(1, 0, aTab);
aTab._lastAccessed = Date.now();
- tabutils._ss.setTabValue(aTab, "lastAccessed", aTab._lastAccessed);
+ tabutils._ss.setTabValue(aTab, "lastAccessed", String(aTab._lastAccessed));
});
TU_hookCode("gBrowser.onTabSelect", "}", function() {
var tabHistory = this.mTabContainer._tabHistory;
- var lastTab = tabHistory[0];
+ lastTab = tabHistory[0];
lastTab._lastAccessed = Date.now();
- tabutils._ss.setTabValue(lastTab, "lastAccessed", lastTab._lastAccessed);
+ tabutils._ss.setTabValue(lastTab, "lastAccessed", String(lastTab._lastAccessed));
var index = tabHistory.indexOf(aTab);
if (index > -1)
tabHistory.splice(index, 1);
tabHistory.unshift(aTab);
aTab._lastAccessed = Infinity;
- tabutils._ss.setTabValue(aTab, "lastAccessed", aTab._lastAccessed);
+ tabutils._ss.setTabValue(aTab, "lastAccessed", String(aTab._lastAccessed));
});
TU_hookCode("gBrowser.onTabClose", "}", function() {
@@ -871,7 +917,7 @@ tabutils._tabClosingOptions = function() {
tabHistory.splice(index, 1);
if (aTab._lastAccessed == Infinity)
- tabutils._ss.setTabValue(aTab, "lastAccessed", aTab._lastAccessed);
+ tabutils._ss.setTabValue(aTab, "lastAccessed", String(aTab._lastAccessed));
else
aTab._lastAccessed = tabutils._ss.getTabValue(aTab, "lastAccessed");
@@ -889,8 +935,8 @@ tabutils._tabClosingOptions = function() {
|| tabHistory[aDir < 0 ? tabHistory.length - 1 : 0];
};
- //Ctrl+Tab切换到上次浏览的标签
- //Ctrl+左右方向键切换到前一个/后一个标签
+ //Ctrl+Tab鍒囨崲鍒颁笂娆℃祻瑙堢殑鏍囩
+ //Ctrl+宸﹀彸鏂瑰悜閿垏鎹㈠埌鍓嶄竴涓/鍚庝竴涓爣绛
tabutils.addEventListener(window, "keydown", function(event) {
if (!event.ctrlKey || event.altKey || event.metaKey)
return;
@@ -980,7 +1026,9 @@ tabutils._tabClosingOptions = function() {
TU_hookCode("gBrowser.updateCurrentBrowser", /.*dispatchEvent[\s\S]*_tabAttrModified.*/, "$&};if (window.windowState != window.STATE_MINIMIZED) {");
//Don't close the last primary window with the las tab
- TU_hookCode("gBrowser._beginRemoveTab", "_closeWindowWithLastTab", "$& && " + (function() { //Bug 607893
+ TU_hookCode("gBrowser._beginRemoveTab",
+ /_closeWindowWithLastTab|Services\.prefs\.getBoolPref\("browser\.tabs\.closeWindowWithLastTab"\)/, // Bug 997681 [Fx31]
+ "$& && " + (function() { //Implement to Bug 607893
(TU_getPref("extensions.tabutils.closeLastWindowWithLastTab", false) || function() {
var winEnum = Services.wm.getEnumerator("navigator:browser");
while (winEnum.hasMoreElements()) {
@@ -1104,7 +1152,7 @@ tabutils._tabClosingOptions = function() {
}, false);
};
-//标记未读标签页
+//鏍囪鏈鏍囩椤
tabutils._unreadTab = function() {
gBrowser.unreadTab = function unreadTab(aTab, aForce) {
if (aForce == null)
@@ -1143,7 +1191,7 @@ tabutils._unreadTab = function() {
});
}
-//保护标签页、锁定标签页、冻结标签页
+//淇濇姢鏍囩椤点侀攣瀹氭爣绛鹃〉銆佸喕缁撴爣绛鹃〉
tabutils._protectAndLockTab = function() {
/* aRestoring = null: setAttribute + setTabValue + tagURI
* aRestoring = false: setAttribute + setTabValue
@@ -1168,7 +1216,7 @@ tabutils._protectAndLockTab = function() {
else {
aTab.setAttribute("protected", true);
if (!aRestoring)
- tabutils._ss.setTabValue(aTab, "protected", true);
+ tabutils._ss.setTabValue(aTab, "protected", String(true));
if (aRestoring == null && !gPrivateBrowsingUI.privateBrowsingEnabled && TU_getPref("extensions.tabutils.autoProtect", true)) {
PlacesUtils.tagging.tagURI(aTab.linkedBrowser.currentURI, ["protected"]);
}
@@ -1194,7 +1242,7 @@ tabutils._protectAndLockTab = function() {
else {
aTab.setAttribute("locked", true);
if (!aRestoring)
- tabutils._ss.setTabValue(aTab, "locked", true);
+ tabutils._ss.setTabValue(aTab, "locked", String(true));
if (aRestoring == null && !gPrivateBrowsingUI.privateBrowsingEnabled && TU_getPref("extensions.tabutils.autoLock", true)) {
PlacesUtils.tagging.tagURI(aTab.linkedBrowser.currentURI, ["locked"]);
}
@@ -1272,7 +1320,7 @@ tabutils._protectAndLockTab = function() {
}).toString().replace(/^.*{|}$/g, ""));
};
-//图标化标签页
+//鍥炬爣鍖栨爣绛鹃〉
tabutils._faviconizeTab = function() {
gBrowser.faviconizeTab = function faviconizeTab(aTab, aForce, aRestoring) {
if (aForce == aTab.hasAttribute("faviconized"))
@@ -1293,7 +1341,7 @@ tabutils._faviconizeTab = function() {
else {
aTab.setAttribute("faviconized", true);
if (!aRestoring)
- tabutils._ss.setTabValue(aTab, "faviconized", true);
+ tabutils._ss.setTabValue(aTab, "faviconized", String(true));
if (aRestoring == null && !gPrivateBrowsingUI.privateBrowsingEnabled && TU_getPref("extensions.tabutils.autoFaviconize", true)) {
PlacesUtils.tagging.tagURI(aTab.linkedBrowser.currentURI, ["faviconized"]);
}
@@ -1316,11 +1364,11 @@ tabutils._faviconizeTab = function() {
TU_hookCode("gBrowser.onLocationChange", "}", "this.autoFaviconizeTab(aTab, uri, tags);");
};
-//固定标签页
+//鍥哄畾鏍囩椤
tabutils._pinTab = function() {
};
-//重命名标签页
+//閲嶅懡鍚嶆爣绛鹃〉
tabutils._renameTab = function() {
gBrowser.renameTab = function renameTab(aTab, aTitle, aRestoring) {
if (aTab.getAttribute("title") == aTitle)
@@ -1373,11 +1421,11 @@ tabutils._renameTab = function() {
TU_hookCode("gBrowser.loadTabs",
["{", "var lastArg = Object(arguments[arguments.length - 1]), aTitles = TU_getPref('extensions.tabutils.titleAsBookmark', false) ? lastArg.titles : null;"],
- [/(\w+) = .*addTab.*\[(.*)\].*/g, function(s, s1, s2) (function() {
+ [/(\w+) = .*addTab.*\[(.*)\][\s\S]*?\}\);/g, function(s, s1, s2) (function() {
$0
if (aTitles && aTitles[$2])
$1.setAttribute("title", aTitles[$2]);
- }).toString().replace(/^.*{|}$/g, "").replace("$0", s).replace("$1", s1, "g").replace("$2", s2, "g")]
+ }).toString().replace(/^.*{|}$/g, "").replace("$0", s).replace(/\$1/g, s1).replace(/\$2/g, s2)]
);
};
@@ -1422,7 +1470,7 @@ tabutils._restartTab = function() {
aTab._restartTimer = null;
}
- let lastTab = this.getLastSelectedTab();
+ lastTab = this.getLastSelectedTab();
if (lastTab)
this.autoRestartTab(lastTab);
});
@@ -1436,7 +1484,7 @@ tabutils._restartTab = function() {
});
};
-//自动刷新标签页
+//鑷姩鍒锋柊鏍囩椤
tabutils._reloadEvery = function() {
gBrowser.autoReloadTab = function autoReloadTab(aTab, aForce, aRestoring, aInterval) {
if (aForce == aTab.hasAttribute("autoReload") && (!aForce || aInterval == aTab._reloadInterval))
@@ -1463,8 +1511,8 @@ tabutils._reloadEvery = function() {
aTab._reloadInterval = aInterval || aTab._reloadInterval || TU_getPref("extensions.tabutils.reloadInterval", 10);
TU_setPref("extensions.tabutils.reloadInterval", aTab._reloadInterval);
if (!aRestoring) {
- tabutils._ss.setTabValue(aTab, "autoReload", true);
- tabutils._ss.setTabValue(aTab, "reloadInterval", aTab._reloadInterval);
+ tabutils._ss.setTabValue(aTab, "autoReload", String(true));
+ tabutils._ss.setTabValue(aTab, "reloadInterval", String(aTab._reloadInterval));
}
if (aRestoring == null && !gPrivateBrowsingUI.privateBrowsingEnabled && TU_getPref("extensions.tabutils.autoEnableAutoReload", true)) {
@@ -1583,6 +1631,7 @@ tabutils._bookmarkTabs = function() {
PlacesCommandHook.bookmarkPage(aTabs[0].linkedBrowser, PlacesUtils.bookmarksMenuFolderId, true);
};
+ if (tabutils.fxVersion < 40) { // https://hg.mozilla.org/mozilla-central/diff/d84b62b367b4/browser/base/content/browser-places.js
TU_hookCode("PlacesCommandHook.bookmarkPage",
[/(?=.*(createItem|PlacesCreateBookmarkTransaction).*)/, function() {
var annos = [descAnno];
@@ -1594,7 +1643,9 @@ tabutils._bookmarkTabs = function() {
}],
[/.*(createItem|PlacesCreateBookmarkTransaction).*/, function(s) s.replace("[descAnno]", "annos")] // Bug 575955 [Fx13]
);
+ }
+ if (!("abHere2" in window)) { // Compatibility with Add Bookmark Here 虏
TU_hookCode("PlacesCommandHook.bookmarkCurrentPages",
["this.uniqueCurrentPages", (function() {
!gPrivateBrowsingUI.privateBrowsingEnabled && TU_getPref("extensions.tabutils.bookmarkAllWithHistory", true) ?
@@ -1603,6 +1654,7 @@ tabutils._bookmarkTabs = function() {
}).toString().replace(/^.*{|}$/g, "")],
["pages.length > 1", "true"]
);
+ }
//Highlight bookmarks with history
TU_hookCode("PlacesViewBase.prototype._createMenuItemForPlacesNode", /(?=return element;)/, function() {
@@ -1628,13 +1680,13 @@ tabutils._bookmarkTabs = function() {
TU_hookCode("gBrowser.loadTabs",
["{", "var lastArg = Object(arguments[arguments.length - 1]), aItemIds = lastArg.itemIds;"],
- [/(\w+) = .*addTab.*\[(.*)\].*/g, function(s, s1, s2) (function() {
+ [/(\w+) = .*addTab.*\[(.*)\][\s\S]*?\}\);/g, function(s, s1, s2) (function() {
$0
if (aItemIds && aItemIds[$2] && PlacesUtils.annotations.itemHasAnnotation(aItemIds[$2], "bookmarkProperties/tabState")) {
$1.linkedBrowser.stop();
tabutils._ss.setTabState($1, PlacesUtils.annotations.getItemAnnotation(aItemIds[$2], "bookmarkProperties/tabState"));
}
- }).toString().replace(/^.*{|}$/g, "").replace("$0", s).replace("$1", s1, "g").replace("$2", s2, "g")]
+ }).toString().replace(/^.*{|}$/g, "").replace("$0", s).replace(/\$1/g, s1).replace(/\$2/g, s2)]
);
};
@@ -1781,7 +1833,7 @@ tabutils._multiTabHandler = function() {
}, []);
};
- //关闭多个标签页
+ //鍏抽棴澶氫釜鏍囩椤
TU_hookCode("gBrowser.warnAboutClosingTabs", /\w+(?= <= 1)/, "($& = arguments[1] && 'length' in arguments[1] ? arguments[1].length : $&)"); // Bug 866880 [Fx24]
gBrowser.removeTabsBut = function removeTabsBut(aTabs, bTabs) {
aTabs = aTabs ? "length" in aTabs ? aTabs : [aTabs] : [];
@@ -1822,7 +1874,7 @@ tabutils._multiTabHandler = function() {
gBrowser.closeAllTabs = function() this.removeTabsBut(this.allTabs);
gBrowser.closeAllDuplicateTabs = function() this.removeTabsBut(this.allTabs, this.uniqueTabsOf(this.allTabs));
- //拖曳多个标签页
+ //鎷栨洺澶氫釜鏍囩椤
gBrowser.gatherTabs = function gatherTabs(aTabs, aTab, aSuppressTabMove) {
let index = 0;
if (aTab) {
@@ -1874,7 +1926,9 @@ tabutils._multiTabHandler = function() {
}
}, true);
- TU_hookCode("gBrowser.mTabContainer._setEffectAllowedForDataTransfer",
+ TU_hookCode(typeof gBrowser.mTabContainer._setEffectAllowedForDataTransfer === 'function' ?
+ "gBrowser.mTabContainer._setEffectAllowedForDataTransfer" : // Firefox 43 and older
+ "gBrowser.mTabContainer._getDropEffectForTabDrag", // Firefox 44 and later
["dt.mozItemCount > 1", "false"]
);
@@ -1901,7 +1955,7 @@ tabutils._multiTabHandler = function() {
});
TU_hookCode("gBrowser.moveTabTo", // Bug 822068 [Fx20]
- ["this.mCurrentTab._selected = false;", "let wasFocused = (document.activeElement == this.mCurrentTab);$&"],
+ ["this.mCurrentTab._selected = false;", "wasFocused = (document.activeElement == this.mCurrentTab);$&"],
["this.mCurrentTab._selected = true;", "$&;if (wasFocused) this.mCurrentTab.focus();"]
);
@@ -1980,7 +2034,7 @@ tabutils._multiTabHandler = function() {
TU_hookCode("gBrowser.swapBrowsersAndCloseOther", /(?=.*_beginRemoveTab.*)/, function() {
if ([gBrowserInit.onLoad, gBrowserInit._delayedStartup].indexOf(arguments.callee.caller) > -1 || // Bug 756313 [Fx19]
- ["onxbldrop", "_handleTabDrop"].indexOf(arguments.callee.caller.name) > -1) {
+ TMP_console.isCallerInList(["onxbldrop", "_handleTabDrop"])) {
let selectedTabs = aOtherTab._selectedTabs || remoteBrowser.contextTabsOf(aOtherTab);
if (selectedTabs.length > 1) {
this.swapBrowsersAndCloseOther(aOurTab, selectedTabs.shift());
@@ -2023,7 +2077,7 @@ tabutils._multiTabHandler = function() {
tabutils._tabClickingOptions = function() {
- //载入剪贴板URL
+ //杞藉叆鍓创鏉縐RL
gBrowser.loadURLFromClipboard = function loadURLFromClipboard(aTab) {
var url = readFromClipboard();
if (!url)
@@ -2038,16 +2092,17 @@ tabutils._tabClickingOptions = function() {
}
};
- //浏览历史菜单
- TU_hookCode("FillHistoryMenu",
- ["count <= 1", "count == 0"],
- [/(?=var webNav)/, function() {
+ //娴忚鍘嗗彶鑿滃崟
+ TU_hookCode("FillHistoryMenu", // Fillin the history menu
+ ["count <= 1", "count == 0"], // Always show the menu
+ ["gBrowser.selectedTab", "tab", "g"], // since Bug 1148505 [Fx43].
+ [FillHistoryMenu.toString().indexOf("var webNav")>0 ? /(?=var webNav)/ : /(?=let sessionHistory)/, function() { // Bug 1148505 [Fx43].
var tab = document.popupNode;
if (!tab || tab.localName != 'tab')
tab = gBrowser.selectedTab;
aParent.value = tab._tPos;
}],
- ["gBrowser.webNavigation", "tab.linkedBrowser.webNavigation"]
+ ["gBrowser.webNavigation", "tab.linkedBrowser.webNavigation"] // Is no longer valid since Bug 1148505 [Fx43].
);
TU_hookCode("gotoHistoryIndex",
["gBrowser.selectedTab", "tab", "g"],
@@ -2057,7 +2112,7 @@ tabutils._tabClickingOptions = function() {
TU_hookCode("TabContextMenu.updateContextMenu", "aPopupMenu.triggerNode", "document.popupNode", "g");
TU_hookCode("gBrowser.mTabContainer._selectNewTab", "{", function() {
- if (["onxblmousedown"].indexOf(arguments.callee.caller.name) > -1 &&
+ if (TMP_console.isCallerInList(["onxblmousedown"]) &&
!aNewTab.selected)
aNewTab.setAttribute("firstclick", true);
});
@@ -2285,7 +2340,7 @@ tabutils._tabClickingOptions = function() {
//Mouse release to select
TU_hookCode("gBrowser.mTabContainer._selectNewTab", "{", function() {
- if (["onxblmousedown"].indexOf(arguments.callee.caller.name) > -1 &&
+ if (TMP_console.isCallerInList(["onxblmousedown"]) &&
TU_getPref("extensions.tabutils.mouseReleaseSelect", true))
return;
});
@@ -2318,9 +2373,13 @@ tabutils._tabClickingOptions = function() {
}, false);
//Mouse scroll to select
- tabutils.addEventListener(gBrowser.mTabContainer, 'DOMMouseScroll', function(event) {
+ tabutils.addEventListener(gBrowser.mTabContainer, 'wheel', function(event) {
+ let isVertical = Math.abs(event.deltaY) > Math.abs(event.deltaX);
+ let delta = isVertical ? event.deltaY : event.deltaX;
+ let scrollByDelta = isVertical && this._isRTLScrollbox ? -delta : delta;
if (event.ctrlKey) {
- document.getElementById(event.detail < 0 ? "cmd_prevGroup" : "cmd_nextGroup").doCommand();
+ document.getElementById(scrollByDelta < 0 ? "cmd_prevGroup" : "cmd_nextGroup").doCommand();
+ event.preventDefault();
event.stopPropagation();
return;
}
@@ -2328,8 +2387,9 @@ tabutils._tabClickingOptions = function() {
if (event.originalTarget != this.mTabstrip._scrollButtonUp &&
event.originalTarget != this.mTabstrip._scrollButtonDown &&
TU_getPref("extensions.tabutils.mouseScrollSelect", false)) {
- let scrollDir = event.detail < 0 ^ TU_getPref("extensions.tabutils.mouseScrollSelectDir", false) ? -1 : 1;
+ let scrollDir = scrollByDelta < 0 ^ TU_getPref("extensions.tabutils.mouseScrollSelectDir", false) ? -1 : 1;
this.advanceSelectedTab(scrollDir, TU_getPref("extensions.tabutils.mouseScrollSelectWrap", false));
+ event.preventDefault();
event.stopPropagation();
}
}, true);
@@ -2373,10 +2433,14 @@ tabutils._miscFeatures = function() {
TU_hookCode("openGMarkLabelInTabs",
[/.*openUILinkIn.*/, ""],
[/(?=.*(labelArray)(?![\s\S]*\1))/, function() {
- var urls = [label.url for (label of labelArray)];
+ var urls = $1;
var loadInBackground = TU_getPref("browser.tabs.loadBookmarksInBackground");
gBrowser.loadTabs(urls, loadInBackground, false);
- }]
+ }.toString().replace("$1",
+ tabutils.fxVersion >= 30.0 ?
+ "[for (label of labelArray) label.url]" : // Bug 979865 [Fx30] support
+ "[label.url for (label of labelArray)]" // Bug 1220564 [Fx46] removed
+ )]
);
TU_hookCode("BookmarkingUI" in window ? "BookmarkingUI._updateStar" : "PlacesStarButton._updateStateInternal", /(?=.*this._itemIds.*)/, function() { //Bug 650527
@@ -2435,37 +2499,36 @@ tabutils._miscFeatures = function() {
}
};
-//浏览区右键菜单
+//娴忚鍖哄彸閿彍鍗
tabutils._mainContextMenu = function() {
- nsContextMenu.prototype.isLinkSelected = function() {
- var focusedWindow = document.commandDispatcher.focusedWindow;
- if (!focusedWindow || focusedWindow == window)
- focusedWindow = window.content;
-
- var links = focusedWindow.document.links;
- var selection = focusedWindow.getSelection();
- if (!links || !selection)
- return false;
-
- this.linkURLs = [];
- for (let link of links) {
- if (selection.containsNode(link, true) && this.linkURLs.indexOf(link.href) == -1)
- this.linkURLs.push(link.href);
- }
-
- var item = document.getElementById("context-openselectedlinksintab");
- item.setAttribute("label", item.getAttribute("label").replace(/\d*(?=])/, this.linkURLs.length));
-
- return this.linkURLs.length > 1;
+ var TUF_LinksSelected = []; // due to an call in that "listener".
+ nsContextMenu.prototype.checkLinkSelected = function() {
+ //console.time('getLinkSelected');
+ messageManager.addMessageListener("tabutils-fixed:LinksSelected", listener);
+ function listener(message) {
+ //console.dir(message);
+ let linkURLs = message.data.links;
+ TUF_LinksSelected = linkURLs;
+ let item = document.getElementById("context-openselectedlinksintab");
+ item.setAttribute("label", item.getAttribute("label").replace(/\d*(?=])/, linkURLs.length));
+ item.setAttribute("hidden", linkURLs.length > 1 ? "" : "true");
+ //console.timeEnd('getLinkSelected');
+ }
+ let browserMM = gBrowser.selectedBrowser.messageManager;
+ browserMM.loadFrameScript('chrome://tabutils/content/content.js', true);
};
nsContextMenu.prototype.openSelectedLinksInTab = function() {
- this.linkURLs.forEach(function(aURL) openNewTabWith(aURL, this.target.ownerDocument, null, null, false), this);
+ gBrowser.loadTabs(TUF_LinksSelected);
};
//TU_hookCode("nsContextMenu.prototype.initOpenItems", /.*openlinkincurrent.*/, function(s) s.replace("onPlainTextLink", "shouldShow"));
TU_hookCode("nsContextMenu.prototype.initOpenItems", "}", function() {
- this.showItem("context-openselectedlinksintab", this.isLinkSelected());
+ this.checkLinkSelected();
+ });
+ TU_hookCode("nsContextMenu.prototype.hiding", "}", function() {
+ let item = document.getElementById("context-openselectedlinksintab");
+ item.setAttribute("hidden", true);
});
};
@@ -2759,7 +2822,7 @@ tabutils._hideTabBar = function() {
TU_hookCode("gBrowser.mTabContainer.updateVisibility", "{", 'if (!TU_getPref("browser.tabs.autoHide")) return;');
};
-//撤销关闭标签页按钮
+//鎾ら攢鍏抽棴鏍囩椤垫寜閽
tabutils._undoCloseTabButton = function() {
TU_hookCode("RecentlyClosedTabsAndWindowsMenuUtils" in window ?
"RecentlyClosedTabsAndWindowsMenuUtils._undoCloseMiddleClick" : // Bug 928640 [Fx27]
@@ -2812,6 +2875,7 @@ tabutils._undoCloseTabButton = function() {
tabutils._undoCloseMiddleClick = HistoryMenu.prototype._undoCloseMiddleClick;
tabutils.populateUndoSubmenu = HistoryMenu.prototype.populateUndoSubmenu;
+ tabutils._getClosedTabCount = HistoryMenu.prototype._getClosedTabCount; // Bug 1064217 [Fx35]
TU_hookCode("tabutils.populateUndoSubmenu",
[/var undoPopup.*/, "var undoPopup = arguments[0];"],
[/.*undoMenu.*/g, ""],
@@ -2852,22 +2916,31 @@ tabutils._tabPrefObserver = {
//Close buttons
TU_hookCode("gBrowser.mTabContainer.adjustTabstrip",
- [/let tab.*/, function() {
- let tab;
- Array.some(this.tabbrowser.visibleTabs, function(aTab) {
- return !aTab.collapsed && getComputedStyle(aTab).MozBoxFlex > 0 && (tab = aTab);
- });
- }],
- ["this.mCloseButtons", "($& & 0x0f)"],
- ["this.mCloseButtons != 3", "(this.mCloseButtons & 0x0f) != 3 && !(this.mCloseButtons & 0x20)"],
- ["this._closeWindowWithLastTab", "false", "g"],
- ["}", function() {
- this.setAttribute("closeButtonOnPointedTab", (this.mCloseButtons & 0x0f) == 1 || !!(this.mCloseButtons & 0x10));
+ ["this._originalAdjustTabstripFunc();", "if (this.TU_mCloseButtons == 10) {this.mCloseButtons = this.legacy_mCloseButtons; $&}"],
+ ["}", function() {
+ if (this.TU_mCloseButtons != 10) {
+ var def = "alltabs";
+ var map = {
+ 0: "activetab",
+ 1: "alltabs",
+ 2: "hidden",
+ 16: "activepointedtab",
+ 18: "pointedtab"
+ };
+ var value = map[this.TU_mCloseButtons] || def;
+ if (value == "alltabs") {
+ let tab = this.tabbrowser.visibleTabs[this.tabbrowser._numPinnedTabs];
+ if (tab && tab.getBoundingClientRect().width <= this.mTabClipWidth) {
+ value = "hidden";
+ }
+ }
+ this.setAttribute("closebuttons", value);
+ }
}]
);
//Tab counter
- TU_hookCode("gBrowser.mTabContainer.adjustTabstrip", "}", function() {
+ TU_hookCode("gBrowser.mTabContainer.adjustTabstrip", "{", function() {
if (this.mAllTabsPopup) {
let n = gBrowser.mTabs.length - gBrowser._removingTabs.length;
let m = gBrowser.allTabs.length;
@@ -2907,7 +2980,7 @@ tabutils._tabPrefObserver = {
'.alltabs-item#Selector#'
].join(),
textSelector: [
- '.tabbrowser-tab#Selector# > * > .tab-content > .tab-text',
+ '.tabbrowser-tab#Selector# > * > .tab-content .tab-text',
'.alltabs-item#Selector#'
].join(),
bgSelector: [
@@ -2933,7 +3006,7 @@ tabutils._tabPrefObserver = {
if (!aData.startsWith("extensions.tabutils."))
return;
- let name = aData.slice(20).replace(".", "_", "g");
+ let name = aData.slice(20).replace(/\./g, "_");
if (name in this) {
this[name]();
return;
@@ -2954,9 +3027,9 @@ tabutils._tabPrefObserver = {
return;
this.cssRules[prefName] = {
- tab: tabutils.insertRule(this.tabSelector.replace('#Selector#', selector, 'g') + '{}'),
- text: tabutils.insertRule(this.textSelector.replace('#Selector#', selector, 'g') + '{}'),
- bg: tabutils.insertRule(this.bgSelector.replace('#Selector#', selector, 'g') + '{}')
+ tab: tabutils.insertRule(this.tabSelector.replace(/#Selector#/g, selector) + '{}'),
+ text: tabutils.insertRule(this.textSelector.replace(/#Selector#/g, selector) + '{}'),
+ bg: tabutils.insertRule(this.bgSelector.replace(/#Selector#/g, selector) + '{}')
};
}
@@ -3053,7 +3126,8 @@ tabutils._tabPrefObserver = {
if (!button) {
button = document.getElementById("nav-bar").appendChild(document.createElement("toolbarbutton"));
button.id = RegExp.$1;
- button.image = gBrowser.mFaviconService.defaultFavicon.spec;
+ const FaviconService = Cc["@mozilla.org/browser/favicon-service;1"]. getService(Ci.nsIFaviconService);
+ button.image = FaviconService.defaultFavicon.spec;
button.className = "toolbarbutton-1 chromeclass-toolbar-additional";
button.collapsed = !TU_getPref("extensions.tabutils.button." + RegExp.$1);
}
@@ -3187,7 +3261,8 @@ tabutils._tabPrefObserver = {
},
closeButtons: function() {
- gBrowser.mTabContainer.mCloseButtons = TU_getPref("extensions.tabutils.closeButtons");
+ gBrowser.mTabContainer.legacy_mCloseButtons = TU_getPref("browser.tabs.closeButtons");
+ gBrowser.mTabContainer.TU_mCloseButtons = TU_getPref("extensions.tabutils.closeButtons");
gBrowser.mTabContainer.adjustTabstrip();
},
@@ -3220,40 +3295,64 @@ tabutils._tabPrefObserver = {
hideOpenInTab: function() {
var hideOpenInTab = TU_getPref("extensions.tabutils.hideOpenInTab");
- document.getElementById("statusbar-openintab").collapsed = hideOpenInTab;
+ var toolbarItem = document.getElementById("statusbar-openintab");
+ //Check if toolbar item is not removed by user
+ if (toolbarItem) {
+ toolbarItem.collapsed = hideOpenInTab;
+ }
},
hideLoadInBackground: function() {
var hideLoadInBackground = TU_getPref("extensions.tabutils.hideLoadInBackground");
if (hideLoadInBackground)
TU_setPref("extensions.tabutils.loadAllInBackground", false);
- document.getElementById("statusbar-loadinbackground").collapsed = hideLoadInBackground;
+ var toolbarItem = document.getElementById("statusbar-loadinbackground");
+ //Check if toolbar item is not removed by user
+ if (toolbarItem) {
+ toolbarItem.collapsed = hideLoadInBackground;
+ }
},
hideLoadInForeground: function() {
var hideLoadInForeground = TU_getPref("extensions.tabutils.hideLoadInForeground");
if (hideLoadInForeground)
TU_setPref("extensions.tabutils.loadAllInForeground", false);
- document.getElementById("statusbar-loadinforeground").collapsed = hideLoadInForeground;
+ var toolbarItem = document.getElementById("statusbar-loadinforeground");
+ //Check if toolbar item is not removed by user
+ if (toolbarItem) {
+ toolbarItem.collapsed = hideLoadInForeground;
+ }
},
openLinkInTab: function() {
tabutils.gOpenLinkInTab = TU_getPref("extensions.tabutils.openLinkInTab");
- document.getElementById("statusbar-openintab").setAttribute("checked", tabutils.gOpenLinkInTab);
+ var toolbarItem = document.getElementById("statusbar-openintab");
+ //Check if toolbar item is not removed by user
+ if (toolbarItem) {
+ toolbarItem.setAttribute("checked", tabutils.gOpenLinkInTab);
+ }
},
loadAllInBackground: function() {
tabutils.gLoadAllInBackground = TU_getPref("extensions.tabutils.loadAllInBackground");
if (tabutils.gLoadAllInBackground)
TU_setPref("extensions.tabutils.loadAllInForeground", false);
- document.getElementById("statusbar-loadinbackground").setAttribute("checked", tabutils.gLoadAllInBackground);
+ var toolbarItem = document.getElementById("statusbar-loadinbackground");
+ //Check if toolbar item is not removed by user
+ if (toolbarItem) {
+ toolbarItem.setAttribute("checked", tabutils.gLoadAllInBackground);
+ }
},
loadAllInForeground: function() {
tabutils.gLoadAllInForeground = TU_getPref("extensions.tabutils.loadAllInForeground");
if (tabutils.gLoadAllInForeground)
TU_setPref("extensions.tabutils.loadAllInBackground", false);
- document.getElementById("statusbar-loadinforeground").setAttribute("checked", tabutils.gLoadAllInForeground);
+ var toolbarItem = document.getElementById("statusbar-loadinforeground");
+ //Check if toolbar item is not removed by user
+ if (toolbarItem) {
+ toolbarItem.setAttribute("checked", tabutils.gLoadAllInForeground);
+ }
},
loadInNewTab: function() {
diff --git a/chrome/content/tabutils.xml b/chrome/content/tabutils.xml
index 09b61a4..809e69c 100644
--- a/chrome/content/tabutils.xml
+++ b/chrome/content/tabutils.xml
@@ -5,8 +5,6 @@
%globalDTD;
%browserDTD;
-
-%tabBrowserDTD;
]>
-
+
-
+
-
-
@@ -214,7 +217,7 @@
+
+
%browserDTD;
-
-%tabBrowserDTD;
%tabutilsDTD;
]>
@@ -100,22 +100,12 @@
onpopupshowing="try {BookmarksEventHandler.onPopupShowing(event);} catch (e) {this.parentNode._placesView || new PlacesMenu(event, this.getAttribute('place'));}"
tooltip="bhTooltip" popupsinherittooltip="true"/>
-
-
-
-
-
-
-
-
-
-
-