├── README.md
├── chrome.manifest
├── chrome
├── content
│ ├── bookmarkProperties.xul
│ ├── content.js
│ ├── placesOverlay.xul
│ ├── preferences.xul
│ ├── tabs.xul
│ ├── tabutils-mt.js
│ ├── tabutils-pt.js
│ ├── tabutils-st.js
│ ├── tabutils-vt.js
│ ├── tabutils.js
│ ├── tabutils.xml
│ ├── tabutils.xul
│ ├── tulib.js
│ ├── unknownContentType.xul
│ └── utilityOverlay.js
├── locale
│ ├── de
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── en-US
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── es-ES
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── it
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── ja-JP
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── pl
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── pt-BR
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── ru
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ ├── zh-CN
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
│ └── zh-TW
│ │ ├── preferences.dtd
│ │ ├── tabutils.dtd
│ │ └── tabutils.properties
└── skin
│ ├── Secure-Glyph.png
│ ├── Secure24.png
│ ├── autoreload.png
│ ├── preferences.css
│ ├── preferences.png
│ ├── tabutils.css
│ ├── tabutils.png
│ ├── tabutils_fx14.css
│ ├── tabutils_fx29.css
│ ├── tabutils_fx31.css
│ ├── tabutils_fx4.css
│ ├── tabutils_fx45.css
│ ├── tabutils_fx6.css
│ ├── tabutils_linux.css
│ ├── tabutils_mac.css
│ ├── toolbar.png
│ └── toolbar_Fx4.png
├── defaults
└── preferences
│ └── prefs.js
├── install.rdf
└── modules
├── Services.jsm
└── log.jsm
/README.md:
--------------------------------------------------------------------------------
1 | [](https://addons.mozilla.org/firefox/addon/tab-utilities-fixed/)
2 | []()
3 | []()
4 | []()
5 |
6 | # Tab Utilities Fixed (Deprecated)
7 |
8 | [Tab Utilities](https://addons.mozilla.org/firefox/addon/tab-utilities/)'s compatibility fixes release.
9 |
10 | 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).
11 |
12 | Issue reports and patches are welcome.
13 |
14 | ## Deprecated
15 | 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.
16 |
17 | If you would, you can continue to report problems (but no guaranteed for repair) or recommend alternatives on the issues.
18 |
19 | ### My collections on AMO site
20 | * [WebExtensions for tabs](https://addons.mozilla.org/firefox/collections/yfdyh000/webextensions-for-tabs/)
21 | * [WebExtensions](https://addons.mozilla.org/firefox/collections/yfdyh000/webextensions/)
22 |
23 | ## Resources
24 | [newer TODO board](https://github.com/yfdyh000/tabutils/projects);
25 | [older TODO and notes](https://github.com/yfdyh000/tabutils/wiki/TODO).
26 |
27 | [Release versions and notes](https://github.com/yfdyh000/tabutils/releases) < may include the latest unsigned version.
28 |
--------------------------------------------------------------------------------
/chrome.manifest:
--------------------------------------------------------------------------------
1 | content tabutils chrome/content/
2 | skin tabutils classic/1.0 chrome/skin/
3 | resource tabmixplus modules/
4 |
5 | overlay chrome://browser/content/browser.xul chrome://tabutils/content/tabutils.xul
6 | overlay chrome://browser/content/places/placesOverlay.xul chrome://tabutils/content/placesOverlay.xul
7 | overlay chrome://ybookmarks/content/ybsidebar.xul chrome://tabutils/content/placesOverlay.xul
8 | overlay chrome://bookmarktags/content/tagBrowserSidebar.xul chrome://tabutils/content/placesOverlay.xul
9 | overlay chrome://browser/content/places/bookmarkProperties.xul chrome://tabutils/content/bookmarkProperties.xul
10 | overlay chrome://browser/content/places/bookmarkProperties2.xul chrome://tabutils/content/bookmarkProperties.xul
11 | overlay chrome://mozapps/content/downloads/unknownContentType.xul chrome://tabutils/content/unknownContentType.xul
12 | overlay chrome://browser/content/preferences/tabs.xul chrome://tabutils/content/tabs.xul
13 | style chrome://global/content/customizeToolbar.xul chrome://tabutils/skin/tabutils.css
14 |
15 | locale tabutils en-US chrome/locale/en-US/
16 | locale tabutils zh-CN chrome/locale/zh-CN/
17 | locale tabutils zh-TW chrome/locale/zh-TW/
18 | locale tabutils pl chrome/locale/pl/
19 | locale tabutils pt-BR chrome/locale/pt-BR/
20 | locale tabutils de chrome/locale/de/
21 | locale tabutils es-ES chrome/locale/es-ES/
22 | locale tabutils ru chrome/locale/ru/
23 | locale tabutils ja-JP chrome/locale/ja-JP/
24 | locale tabutils it chrome/locale/it/
25 |
--------------------------------------------------------------------------------
/chrome/content/bookmarkProperties.xul:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/chrome/content/content.js:
--------------------------------------------------------------------------------
1 | // This frame script is used to assist Tab Utilities Fixed, to avoid performance degradation in e10s.
2 |
3 | var getLinksSelected = function() {
4 | let links = content.document.links;
5 | let selection = content.getSelection();
6 | if (!links || !selection) return [];
7 |
8 | let linkURLs = [];
9 | //console.time('checkLinkSelected');
10 | for (let link of links) {
11 | if (selection.containsNode(link, true) && (link.offsetHeight > 0) && linkURLs.indexOf(link.href) == -1)
12 | linkURLs.push(link.href);
13 | }
14 | //console.timeEnd('checkLinkSelected');
15 | return linkURLs;
16 | };
17 |
18 | sendAsyncMessage("tabutils-fixed:LinksSelected", {
19 | links : getLinksSelected()
20 | });
21 |
--------------------------------------------------------------------------------
/chrome/content/placesOverlay.xul:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/chrome/content/tabs.xul:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | %tabutilsDTD;
6 | ]>
7 |
8 |
9 |
10 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/chrome/content/tabutils-mt.js:
--------------------------------------------------------------------------------
1 | //Multi-row tabs
2 | tabutils._multirowTabs = function() {
3 | gBrowser.mTabContainer.enterBlockMode = function enterBlockMode() {
4 | if (this.orient == "horizontal" && this.getAttribute("overflow") == "true" && this.getAttribute("showAllTabs") == "true") {
5 | this.mTabstrip._lineHeight = this.mTabstrip.boxObject.height;
6 | this.setAttribute("multirow", true);
7 | this._revertTabSizing();
8 |
9 | let evt = document.createEvent("UIEvent");
10 | evt.initUIEvent("underflow", true, false, window, 1);
11 | this.mTabstrip._scrollbox.dispatchEvent(evt);
12 | }
13 | };
14 |
15 | gBrowser.mTabContainer.exitBlockMode = function exitBlockMode() {
16 | if (!this.hasAttribute("multirow"))
17 | return;
18 |
19 | if (this.orient == "horizontal" &&
20 | this.getAttribute("showAllTabs") == "true" &&
21 | (this.getAttribute("overflow") == "true" || this.mTabstrip.boxObject.height / this.mTabstrip._lineHeight > 1.35))
22 | return;
23 |
24 | this.removeAttribute("multirow");
25 | this.stylePinnedTabs();
26 | };
27 |
28 | tabutils.addEventListener(gBrowser.mTabContainer, "overflow", function(event) {
29 | this.enterBlockMode();
30 | }, false);
31 |
32 | tabutils.addEventListener(gBrowser.mTabContainer, "TabClose", function(event) {
33 | setTimeout(function() {
34 | this.exitBlockMode();
35 | }.bind(this), 250);
36 | }, false);
37 |
38 | tabutils.addEventListener(window, "resize", function(event) {
39 | gBrowser.mTabContainer.exitBlockMode();
40 | if (window.fullScreen && FullScreen._isChromeCollapsed)
41 | gNavToolbox.style.marginTop = -gNavToolbox.getBoundingClientRect().height + "px";
42 | }, false);
43 |
44 | TU_hookCode("gBrowser.mTabContainer._getDropIndex",
45 | [/event.screenX.*width \/ 2/g, function(s) s + " && " + s.replace(/screenX/g, "screenY").replace("width / 2", "height")
46 | + " || " + s.replace(/screenX/g, "screenY").replace("width / 2", "height * 0")]
47 | );
48 |
49 | tabutils.addEventListener(gBrowser.mTabContainer, "dragover", function(event) {
50 | var ind = this._tabDropIndicator.parentNode;
51 | if (!this.hasAttribute("multirow")) {
52 | ind.style.position = "";
53 | return;
54 | }
55 | ind.style.position = "fixed";
56 | ind.style.zIndex = 100;
57 |
58 | var newIndex = this._getDropIndex(event);
59 | var tab = this.childNodes[newIndex < this.childNodes.length ? newIndex : newIndex - 1];
60 | var ltr = getComputedStyle(this).direction == "ltr";
61 | var [start, end] = ltr ? ["left", "right"] : ["right", "left"];
62 | var startPos = this.getBoundingClientRect()[start];
63 | if (tab.boxObject.screenY > event.screenY && newIndex > 0) {
64 | tab = this.childNodes[newIndex - 1];
65 | startPos += tab.getBoundingClientRect()[end] - this.mTabstrip._scrollbox.getBoundingClientRect()[start];
66 | }
67 | ind.style[start] = startPos - ind.clientWidth / 2 * (ltr ? 1 : -1) + "px";
68 |
69 | ind.style.top = tab.getBoundingClientRect().top + "px";
70 | ind.style.lineHeight = tab.getBoundingClientRect().height + "px";
71 | ind.firstChild.style.verticalAlign = "bottom";
72 | }, true);
73 |
74 | TU_hookCode("gBrowser.mTabContainer._animateTabMove", "{", function() {
75 | if (TU_getPref("extensions.tabutils.disableTabMoveAnimation", true)) {
76 | TU_hookFunc(arguments.callee.caller.toString().match(/^.*{|var (ind|tabStrip|ltr).*|var pixelsToScroll[\s\S]*$/g).join("\n"),
77 | [/.*scrollByPixels.*/, ";"],
78 | [/.*effects == "move"[\s\S]*?(?=var (newIndex|scrollRect|rect))/, ""] // needs fix
79 | ).apply(this, arguments);
80 | return;
81 | }
82 | });
83 |
84 | tabutils.addEventListener(gBrowser.mTabContainer, "drop", function(event) {
85 | if (!TU_getPref("extensions.tabutils.disableTabMoveAnimation", true))
86 | return;
87 |
88 | let dt = event.dataTransfer;
89 | let dropEffect = dt.dropEffect;
90 | let draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
91 |
92 | if (dropEffect == "move" && draggedTab && draggedTab.parentNode == this) {
93 | draggedTab._dragData.animDropIndex = this._getDropIndex(event);
94 | }
95 | }, true);
96 |
97 | TU_hookCode("gBrowser.moveTabTo", "{", function() {
98 | if (TMP_console.isCallerInList(["onxbldrop", "ondrop"])) {
99 | if (aTab.pinned) {
100 | if (aIndex >= this._numPinnedTabs)
101 | this.pinTab(aTab, false);
102 | } else {
103 | if (aIndex < this._numPinnedTabs)
104 | this.pinTab(aTab, true);
105 | }
106 | }
107 | });
108 |
109 | tabutils.addEventListener(gBrowser.mTabContainer, "dragexit", function(event) {
110 | this._tabDropIndicator.collapsed = true;
111 | }, true);
112 |
113 | tabutils.addEventListener(gBrowser.mTabContainer, "dragend", function(event) {
114 | this._tabDropIndicator.collapsed = true;
115 | }, true);
116 |
117 | tabutils._tabPrefObserver.showAllTabs = function() {
118 | let showAllTabs = TU_getPref("extensions.tabutils.showAllTabs");
119 | if (showAllTabs) {
120 | gBrowser.mTabContainer.setAttribute("showAllTabs", true);
121 | gBrowser.mTabContainer.enterBlockMode();
122 | }
123 | else {
124 | gBrowser.mTabContainer.removeAttribute("showAllTabs");
125 | gBrowser.mTabContainer.exitBlockMode();
126 | }
127 | };
128 | };
129 |
--------------------------------------------------------------------------------
/chrome/content/tabutils-pt.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/content/tabutils-pt.js
--------------------------------------------------------------------------------
/chrome/content/tabutils-vt.js:
--------------------------------------------------------------------------------
1 | //Vertical tabs
2 | tabutils._verticalTabs = function() {
3 | TU_hookCode("gBrowser.mTabContainer._notifyBackgroundTab",
4 | [/(?=var scrollRect)/, function() {
5 | var vertical = this.orient == "vertical";
6 | var [start, end, size] = vertical ? ["top", "bottom", "height"]
7 | : ["left", "right", "width"];
8 | }],
9 | ["left:", "[start]:", "g"], // Bug 971630 [Fx29]
10 | ["right:", "[end]:", "g"],
11 | [".left", "[start]", "g"],
12 | [".right", "[end]", "g"],
13 | [".width", "[size]", "g"]
14 | );
15 |
16 | TU_hookCode("gBrowser.mTabContainer._getDropIndex",
17 | ["{", function() {
18 | var vertical = this.orient == "vertical";
19 | var [position, size] = vertical ? ["screenY", "height"]
20 | : ["screenX", "width"];
21 | }],
22 | [/getComputedStyle.*direction == "ltr"/, "$& || vertical"],
23 | [".screenX", "[position]", "g"],
24 | [".width", "[size]", "g"]
25 | );
26 |
27 | TU_hookCode("gBrowser.addTab", '!Services.prefs.getBoolPref("browser.tabs.animate")', 'this.mTabContainer.orient == "vertical" || $&');
28 | TU_hookCode("gBrowser.removeTab", '!Services.prefs.getBoolPref("browser.tabs.animate")', 'this.mTabContainer.orient == "vertical" || $&');
29 |
30 | // Hide tabs toolbar in Full Screen mode
31 | TU_hookCode("FullScreen.mouseoverToggle", /(?=.*gNavToolbox.*)/, function() {
32 | if (document.getElementById("TabsToolbar").parentNode != gNavToolbox)
33 | gBrowser.mTabContainer.visible = aShow;
34 | });
35 |
36 | if (tabutils.fxVersion >= 35.0) { // Bug 1071821 [Fx35]
37 | // I did not find a compatible approach
38 | TU_hookCode("FullScreen.toggle", /.*if.*\(\!this\._fullScrToggler\).*\n.*\n.*\n.*\n.*\}/, function() {
39 | if (!this._eventLoaded) { // the equivalent to "if (!this._fullScrToggler)"
40 | for (let fullScrToggler of this._fullScrTogglers) {
41 | fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
42 | fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
43 | fullScrToggler.collapsed = false;
44 | }
45 | this._eventLoaded = true;
46 | }
47 | });
48 |
49 | } else { // Earlier than Fx35
50 | TU_hookCode("FullScreen.toggle", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
51 | for (let fullScrToggler of this._fullScrTogglers) {
52 | fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
53 | fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
54 | fullScrToggler.hidden = false;
55 | }
56 | });
57 | TU_hookCode("FullScreen.enterDomFullscreen", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
58 | for (let fullScrToggler of this._fullScrTogglers) {
59 | fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
60 | fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
61 | }
62 | });
63 |
64 | TU_hookCode("FullScreen.cleanup", /.*_expandCallback.*\n.*_expandCallback.*/, function() {
65 | for (let fullScrToggler of this._fullScrTogglers) {
66 | fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
67 | fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
68 | }
69 | });
70 | }
71 | TU_hookCode("FullScreen.mouseoverToggle", /.*(collapsed|hidden) = aShow.*/, function() {
72 | let tabBarPosition = TU_getPref("extensions.tabutils.tabBarPosition");
73 | this._fullScrTogglers[0].$1 = aShow;
74 | this._fullScrTogglers[1].$1 = aShow || tabBarPosition != 1;
75 | this._fullScrTogglers[2].$1 = aShow || tabBarPosition != 2;
76 | this._fullScrTogglers[3].$1 = aShow || tabBarPosition != 3;
77 | }); // Note: mozFullScreen is Fx9+. I did not add " || document.mozFullScreen" because it seems always return to false, unknown reason.
78 |
79 | TU_hookCode("FullScreen.showXULChrome",
80 | ['fullscreenctls.parentNode == navbar', 'document.getElementById("TabsToolbar").parentNode == gNavToolbox'],
81 | ['fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar', 'fullscreenctls.parentNode != navbar']
82 | );
83 |
84 | XPCOMUtils.defineLazyGetter(FullScreen, "_fullScrTogglers", function() [
85 | document.getElementById("fullscr-toggler"),
86 | document.getElementById("fullscr-toggler-bottom"),
87 | document.getElementById("fullscr-toggler-left"),
88 | document.getElementById("fullscr-toggler-right")
89 | ]);
90 |
91 | // Hide tabs toolbar in Print Preview mode
92 | TU_hookCode("PrintPreviewListener._hideChrome", "}", function() {
93 | this._chromeState.tabsToolbarOpen = gBrowser.mTabContainer.visible;
94 | gBrowser.mTabContainer.visible = false;
95 | });
96 |
97 | TU_hookCode("PrintPreviewListener._showChrome", "}", function() {
98 | if (this._chromeState.tabsToolbarOpen)
99 | gBrowser.mTabContainer.visible = true;
100 | });
101 |
102 | tabutils._tabPrefObserver.tabBarPosition = function() {
103 | let tabsToolbar = document.getElementById("TabsToolbar");
104 | let appcontent = document.getElementById("appcontent");
105 | let bottombox = document.getElementById("browser-bottombox");
106 |
107 | switch (TU_getPref("extensions.tabutils.tabBarPosition")) {
108 | case 1: //Bottom
109 | if (tabsToolbar.parentNode != bottombox) {
110 | gBrowser.mTabContainer.mTabstrip._stopSmoothScroll();
111 | bottombox.insertBefore(tabsToolbar, bottombox.firstChild);
112 | tabsToolbar.orient = gBrowser.mTabContainer.orient = gBrowser.mTabContainer.mTabstrip.orient = "horizontal";
113 | TabsInTitlebar.allowedBy("tabbarposition", false);
114 | }
115 | break;
116 | case 2: //Left
117 | if (tabsToolbar.nextSibling != appcontent) {
118 | gBrowser.mTabContainer.mTabstrip._stopSmoothScroll();
119 | appcontent.parentNode.insertBefore(tabsToolbar, appcontent);
120 | tabsToolbar.orient = gBrowser.mTabContainer.orient = gBrowser.mTabContainer.mTabstrip.orient = "vertical";
121 | TabsInTitlebar.allowedBy("tabbarposition", false);
122 | gBrowser.mTabContainer.removeAttribute("overflow");
123 | }
124 | break;
125 | case 3: //Right
126 | if (tabsToolbar.previousSibling != appcontent) {
127 | gBrowser.mTabContainer.mTabstrip._stopSmoothScroll();
128 | appcontent.parentNode.insertBefore(tabsToolbar, appcontent.nextSibling);
129 | tabsToolbar.orient = gBrowser.mTabContainer.orient = gBrowser.mTabContainer.mTabstrip.orient = "vertical";
130 | TabsInTitlebar.allowedBy("tabbarposition", false);
131 | gBrowser.mTabContainer.removeAttribute("overflow");
132 | }
133 | break;
134 | case 0: //Top
135 | default:
136 | if (tabsToolbar.parentNode != gNavToolbox) {
137 | gBrowser.mTabContainer.mTabstrip._stopSmoothScroll();
138 | if ("TabsOnTop" in window) // Bug 755593 [Fx28]
139 | gNavToolbox.appendChild(tabsToolbar);
140 | else
141 | gNavToolbox.insertBefore(tabsToolbar, document.getElementById("nav-bar"));
142 | tabsToolbar.orient = gBrowser.mTabContainer.orient = gBrowser.mTabContainer.mTabstrip.orient = "horizontal";
143 | TabsInTitlebar.allowedBy("tabbarposition", true);
144 | }
145 | break;
146 | }
147 |
148 | this.closeButtons();
149 | };
150 | };
151 |
--------------------------------------------------------------------------------
/chrome/content/tabutils.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | %globalDTD;
6 |
7 | %browserDTD;
8 | ]>
9 |
10 |
14 |
15 |
16 |
17 |
24 |
25 |
26 |
29 |
30 |
31 |
38 |
42 |
43 |
44 |
45 |
54 |
56 |
60 |
61 |
62 |
64 |
73 |
74 |
75 |
76 |
77 |
128 |
129 |
130 |
131 | document.getElementById("PinnedTabsBarItems")
132 |
133 |
134 |
135 |
136 |
139 |
140 |
141 |
142 |
143 |
147 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
170 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
187 |
188 |
191 |
192 |
195 |
196 |
202 |
203 |
209 |
210 |
211 |
212 |
213 |
214 | handleDroppedLink
215 |
216 |
217 |
218 |
219 |
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------
/chrome/content/tulib.js:
--------------------------------------------------------------------------------
1 | var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
2 |
3 | XPCOMUtils.defineLazyModuleGetter(this, "TabmixSvc",
4 | "resource://tabmixplus/Services.jsm");
5 | var TMP_console = TabmixSvc.console;
6 |
7 | function TU_hookCode(aStr) {
8 | try {
9 | var namespaces = aStr.split(".");
10 |
11 | try {
12 | var object = this;
13 | while (namespaces.length > 1) {
14 | object = object[namespaces.shift()];
15 | }
16 | }
17 | catch (e) {
18 | throw TypeError(aStr + " is not a function");
19 | }
20 |
21 | var method = namespaces.pop();
22 | if (typeof object[method] != "function")
23 | throw TypeError(aStr + " is not a function");
24 |
25 | return object[method] = TU_hookFunc.apply(this, Array.concat(object[method], Array.slice(arguments, 1)));
26 | }
27 | catch (e) {
28 | Components.utils.reportError("Failed to hook " + aStr + "\n---\n"+(new Error()).stack);
29 | }
30 | }
31 |
32 | function TU_hookSetter(aStr) {
33 | try {
34 | var namespaces = aStr.split(".");
35 |
36 | try {
37 | var object = this;
38 | while (namespaces.length > 1) {
39 | object = object[namespaces.shift()];
40 | }
41 | }
42 | catch (e) {
43 | throw TypeError(aStr + " has no setter");
44 | }
45 |
46 | var property = namespaces.pop();
47 | var orgSetter = object.__lookupSetter__(property);
48 | if (!orgSetter)
49 | throw TypeError(aStr + " has no setter");
50 |
51 | var mySetter = TU_hookFunc.apply(this, Array.concat(orgSetter, Array.slice(arguments, 1)));
52 | object.__defineGetter__(property, object.__lookupGetter__(property));
53 | object.__defineSetter__(property, mySetter);
54 |
55 | return mySetter;
56 | }
57 | catch (e) {
58 | Components.utils.reportError("Failed to hook " + aStr + "\n---\n"+(new Error()).stack);
59 | }
60 | }
61 |
62 | function TU_hookFunc(aFunc) {
63 | var myCode = aFunc.toString();
64 | var orgCode, newCode, flags;
65 |
66 | for (var i = 1; i < arguments.length;) {
67 | if (arguments[i].constructor.name == "Array")
68 | [orgCode, newCode, flags] = arguments[i++];
69 | else
70 | [orgCode, newCode, flags] = [arguments[i++], arguments[i++], arguments[i++]];
71 |
72 | if (typeof newCode == "function" && newCode.length == 0)
73 | newCode = newCode.toString().replace(/^.*{|}$/g, "");
74 |
75 | switch (orgCode) {
76 | case "{": [orgCode, newCode] = [/{/, "$&\n" + newCode];break;
77 | case "}": [orgCode, newCode] = [/}$/, newCode + "\n$&"];break;
78 | }
79 |
80 | if (typeof orgCode == "string")
81 | orgCode = RegExp(orgCode.replace(/[{[(\\^|$.?*+/)\]}]/g, "\\$&"), flags || "");
82 |
83 | myCode = myCode.replace(orgCode, newCode);
84 | }
85 |
86 | // Cu.reportError(myCode);
87 | // myCode = myCode.replace(/(^.*\n?{)([\s\S]*)(}$)/, function(s, s1, s2, s3) (function() {
88 | // $1
89 | // try {
90 | //// switch (arguments.callee.name) {
91 | //// case "set_selectedTab":
92 | //// Cu.reportError(arguments.callee.caller.name + '*' + arguments.callee.name + '*' + (val && val._tPos));break;
93 | //// case "BrowserOpenTab":
94 | //// Cu.reportError(arguments.callee.caller.name + '*' + arguments.callee.name );break;
95 | //// }
96 | // $2
97 | // } catch (e) {
98 | // Cu.reportError([arguments.callee.name ,e]);
99 | // Cu.reportError(arguments.callee.stack);
100 | // Cu.reportError(arguments.callee);
101 | // }
102 | // $3
103 | // }).toString().replace(/^.*{|}$/g, "").replace("$1", s1).replace("$2", s2).replace("$3", s3));
104 |
105 | return eval("(" + myCode + ")");
106 | }
107 |
108 | function TU_getPref(aPrefName, aDefault) {
109 | switch (Services.prefs.getPrefType(aPrefName)) {
110 | case Services.prefs.PREF_BOOL: return Services.prefs.getBoolPref(aPrefName);
111 | case Services.prefs.PREF_INT: return Services.prefs.getIntPref(aPrefName);
112 | case Services.prefs.PREF_STRING: return Services.prefs.getComplexValue(aPrefName, Components.interfaces.nsISupportsString).data;
113 | default:
114 | switch (typeof aDefault) {
115 | case "boolean": Services.prefs.setBoolPref(aPrefName, aDefault);break;
116 | case "number": Services.prefs.setIntPref(aPrefName, aDefault);break;
117 | case "string": Services.prefs.setCharPref(aPrefName, aDefault);break;
118 | }
119 | return aDefault;
120 | }
121 | }
122 |
123 | function TU_setPref(aPrefName, aValue) {
124 | switch (Services.prefs.getPrefType(aPrefName)) {
125 | case Services.prefs.PREF_BOOL: Services.prefs.setBoolPref(aPrefName, aValue);break;
126 | case Services.prefs.PREF_INT: Services.prefs.setIntPref(aPrefName, aValue);break;
127 | case Services.prefs.PREF_STRING: Services.prefs.setCharPref(aPrefName, aValue);break;
128 | default:
129 | switch (typeof aValue) {
130 | case "boolean": Services.prefs.setBoolPref(aPrefName, aValue);break;
131 | case "number": Services.prefs.setIntPref(aPrefName, aValue);break;
132 | case "string": Services.prefs.setCharPref(aPrefName, aValue);break;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/chrome/content/unknownContentType.xul:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
--------------------------------------------------------------------------------
/chrome/content/utilityOverlay.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/content/utilityOverlay.js
--------------------------------------------------------------------------------
/chrome/locale/de/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/de/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/de/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Lesezeichen/Chronik/Adressen/Suchergebnisse in neuen Tabs öffnen und weitere Funktionen für das Surfen mit Tabs.
2 |
--------------------------------------------------------------------------------
/chrome/locale/en-US/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/chrome/locale/en-US/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/en-US/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Open Bookmarks/History/URL/Search in new tabs, and more utilities for tabbed browsing.
2 |
--------------------------------------------------------------------------------
/chrome/locale/es-ES/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/es-ES/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/es-ES/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Abra marcadores, historial, direcciones y búsquedas en nuevas pestañas, entre muchas otras utilidades para la navegación con pestañas.
2 |
--------------------------------------------------------------------------------
/chrome/locale/it/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/it/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/it/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Nuove funzioni per le Schede sull'apertura di Segnalibri, Cronologie e Nuove Pagine.
2 |
--------------------------------------------------------------------------------
/chrome/locale/ja-JP/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/ja-JP/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/ja-JP/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=ブックマーク/履歴/URL/検索を新しいタブで開き、タブブラウジングに有用な機能を追加します。
2 |
--------------------------------------------------------------------------------
/chrome/locale/pl/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/pl/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/pl/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Otwiera elementy z zakładek/historii/adresów URL/paska szukania w nowych kartach oraz inne narzędzia dla przeglądania w kartach.
2 |
--------------------------------------------------------------------------------
/chrome/locale/pt-BR/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/pt-BR/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/pt-BR/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Abre em novas abas o favoritos/histórico/endereços/busca, e mais utilidades para uma navegação com abas.
2 |
--------------------------------------------------------------------------------
/chrome/locale/ru/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/chrome/locale/ru/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/ru/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=Расширенное управление вкладками и многое другое.
2 |
--------------------------------------------------------------------------------
/chrome/locale/zh-CN/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/zh-CN/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/zh-CN/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=在新标签页打开书签、历史、地址、搜索,以及更多增强标签式浏览的实用功能。
2 |
--------------------------------------------------------------------------------
/chrome/locale/zh-TW/preferences.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/chrome/locale/zh-TW/tabutils.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chrome/locale/zh-TW/tabutils.properties:
--------------------------------------------------------------------------------
1 | extensions.tabutilsfixed@addon.cn.description=於新分頁開啟書籤、歷史記錄、網址、搜尋,以及更多增強分頁瀏覽的實用功能。
2 |
--------------------------------------------------------------------------------
/chrome/skin/Secure-Glyph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/Secure-Glyph.png
--------------------------------------------------------------------------------
/chrome/skin/Secure24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/Secure24.png
--------------------------------------------------------------------------------
/chrome/skin/autoreload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/autoreload.png
--------------------------------------------------------------------------------
/chrome/skin/preferences.css:
--------------------------------------------------------------------------------
1 | radio[pane] {
2 | list-style-image: url("chrome://tabutils/skin/preferences.png");
3 | }
4 |
5 | radio[pane=pane1] {
6 | -moz-image-region: rect(0px, 32px, 32px, 0px);
7 | }
8 |
9 | radio[pane=pane2] {
10 | -moz-image-region: rect(0px, 64px, 32px, 32px);
11 | }
12 |
13 | radio[pane=pane3] {
14 | -moz-image-region: rect(0px, 96px, 32px, 64px);
15 | }
16 |
17 | radio[pane=pane4] {
18 | -moz-image-region: rect(0px, 128px, 32px, 96px);
19 | }
20 |
21 | checkbox:not([label]) > .checkbox-label-box {
22 | display: none;
23 | }
24 |
25 | menuseparator:first-child,
26 | menuseparator:last-child {
27 | display: none;
28 | }
29 |
--------------------------------------------------------------------------------
/chrome/skin/preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/preferences.png
--------------------------------------------------------------------------------
/chrome/skin/tabutils.css:
--------------------------------------------------------------------------------
1 | .tabbrowser-arrowscrollbox {
2 | -moz-binding: url(chrome://tabutils/content/tabutils.xml#arrowscrollbox);
3 | }
4 |
5 | menupopup > [collapsed="true"],
6 | menuseparator:first-child,
7 | menuseparator:last-child {
8 | display: none;
9 | }
10 |
11 | /* Close Tab buttons */
12 | .tabbrowser-tabs[closebuttons="pointedtab"] > .tabbrowser-tab:hover .tab-close-button,
13 | .tabbrowser-tabs[closebuttons="activepointedtab"] > .tabbrowser-tab:hover .tab-close-button,
14 | .tabbrowser-tabs[closebuttons="activetab"] > .tabbrowser-tab[selected] .tab-close-button,
15 | .tabbrowser-tabs[closebuttons="activepointedtab"] > .tabbrowser-tab[selected] .tab-close-button,
16 | .tabbrowser-tabs[closebuttons="alltabs"] > .tabbrowser-tab .tab-close-button {
17 | display: -moz-box;
18 | }
19 |
20 | .tabbrowser-tabs[closebuttons="pointedtab"] > .tabbrowser-tab:not(:hover) .tab-close-button,
21 | .tabbrowser-tabs[closebuttons="activetab"] > .tabbrowser-tab:not([selected]) .tab-close-button,
22 | .tabbrowser-tabs[closebuttons="activepointedtab"] > .tabbrowser-tab:not(:hover):not([selected]) .tab-close-button,
23 | .tabbrowser-tabs[closebuttons="hidden"] > .tabbrowser-tab .tab-close-button {
24 | display: none;
25 | }
26 |
27 | /* All Tabs button */
28 | .tabs-alltabs-button[showTabCounter="true"] {
29 | visibility: visible !important; /* Fx12 */
30 | width: auto !important;
31 | -moz-box-orient: horizontal;
32 | }
33 |
34 | .tabs-alltabs-button[showTabCounter="true"] > .toolbarbutton-text {
35 | display: -moz-box;
36 | }
37 |
38 | .tabs-alltabs-button:not([showTabCounter="true"]) > .toolbarbutton-text,
39 | .tabs-alltabs-button[showTabCounter="true"] > .toolbarbutton-icon,
40 | .tabs-alltabs-button[showTabCounter="true"] > .toolbarbutton-menu-dropmarker {
41 | display: none;
42 | }
43 |
44 | /* Extra spaces */
45 | .tabbrowser-tabs[showLeftSpace="true"] .tabbrowser-arrowscrollbox {
46 | -moz-padding-start: 15px;
47 | }
48 |
49 | .tabbrowser-tabs[showRightSpace="true"] .tabbrowser-arrowscrollbox {
50 | -moz-padding-end: 15px;
51 | }
52 |
53 | /* Tab Width */
54 | .tabbrowser-tabs[tabfittitle="true"] > .tabbrowser-tab {
55 | width: auto !important;
56 | -moz-box-flex: 0 !important;
57 | }
58 |
59 | /* Tab Highlighting */
60 | .tabbrowser-tab[locked] .tab-throbber:not([busy]),
61 | .tabbrowser-tab[locked] .tab-throbber:not([busy]) + .tab-icon-image,
62 | .tabbrowser-tab[protected] .tab-close-button,
63 | .tabbrowser-tab[autoReload] .tab-close-button {
64 | display: -moz-box !important;
65 | }
66 |
67 | .tabbrowser-tab[protected] .tab-close-button,
68 | .tabbrowser-tab[autoReload]:not(:hover) .tab-close-button {
69 | visibility: visible !important;
70 | }
71 |
72 | .tabbrowser-tab[locked] .tab-throbber:not([busy]) {
73 | -moz-margin-end: -8px !important;
74 | }
75 |
76 | .tabbrowser-tab[locked] .tab-throbber:not([busy]) + .tab-icon-image {
77 | -moz-margin-start: -8px !important;
78 | position: relative;
79 | z-index: -1;
80 | }
81 |
82 | .tabbrowser-tab[locked] .tab-throbber:not([busy]),
83 | .tabbrowser-tab[protected] .tab-close-button {
84 | list-style-image: url("chrome://tabutils/skin/Secure24.png") !important;
85 | -moz-image-region: auto !important;
86 | }
87 |
88 | /* Tab Highlighting */
89 | .tabbrowser-tab[autoReload]:not(:hover) .tab-close-button {
90 | list-style-image: url("chrome://tabutils/skin/autoreload.png") !important;
91 | -moz-image-region: auto !important;
92 | }
93 |
94 | /* Pinned Tab */
95 | .tabbrowser-tabs[orient="vertical"] > .tabbrowser-tab[pinned],
96 | .tabbrowser-tabs[autoFaviconizePinned="true"] > .tabbrowser-tab[pinned],
97 | .tabbrowser-tab[faviconized] {
98 | min-width: -moz-min-content !important;
99 | }
100 |
101 | .tabbrowser-tab[faviconized],
102 | .tabbrowser-tab[pinned] {
103 | width: -moz-min-content !important;
104 | -moz-box-flex: 0 !important;
105 | }
106 |
107 | [orient="horizontal"] > .tabbrowser-tab[faviconized] .tab-text:not(.tab-badge),
108 | .tabbrowser-tab[faviconized]:not([protected]):not([autoReload]) .tab-close-button,
109 | .tabbrowser-tab[pinned]:not([protected]):not([autoReload]) .tab-close-button {
110 | display: none !important;
111 | }
112 |
113 | .tabbrowser-tab[faviconized][autoReload]:hover .tab-close-button,
114 | .tabbrowser-tab[pinned][autoReload]:hover .tab-close-button {
115 | visibility: hidden;
116 | }
117 |
118 | #main-window toolbarbutton.tabbrowser-tab[faviconized] {
119 | -moz-box-align: center;
120 | opacity: 0.5;
121 | }
122 |
123 | #main-window .tabbrowser-tab[pinned] {
124 | position: fixed !important;
125 | -moz-box-sizing: border-box;
126 | }
127 |
128 | #main-window .tabbrowser-tab[pinned] > * {
129 | vertical-align: middle;
130 | position: relative;
131 | }
132 |
133 | #PinnedTabsBar:empty {
134 | -moz-padding-end: 0;
135 | -moz-padding-start: 0;
136 | }
137 |
138 | .tabbrowser-tabs[multirow]:not([showPhantom="true"]) #PinnedTabsBar,
139 | .tabbrowser-tabs[multirow] #PinnedTabsBar:empty:not([style*="border"]),
140 | .tabbrowser-tabs[multirow] #PinnedTabsBarItems:empty:not([style*="border"]),
141 | .tabbrowser-tabs[orient="vertical"] #PinnedTabsBar:empty:not([style*="border"]),
142 | .tabbrowser-tabs[orient="vertical"] #PinnedTabsBarItems:empty:not([style*="border"]) {
143 | visibility: collapse;
144 | }
145 |
146 | .tabbrowser-tabs[multirow][showPhantom="true"][haspinned] #PinnedTabsBar,
147 | .tabbrowser-tabs[multirow][showPhantom="true"][haspinned] #PinnedTabsBarItems,
148 | .tabbrowser-tabs[orient="vertical"][showPhantom="true"][haspinned] #PinnedTabsBar,
149 | .tabbrowser-tabs[orient="vertical"][showPhantom="true"][haspinned] #PinnedTabsBarItems {
150 | border-bottom-width: 0px !important;
151 | padding-bottom: 0px !important;
152 | margin-bottom: 0px !important;
153 | }
154 |
155 | .tabbrowser-tabs[multirow][showPhantom="true"][haspinned] .tabbrowser-arrowscrollbox > scrollbox,
156 | .tabbrowser-tabs[orient="vertical"][showPhantom="true"][haspinned] .tabbrowser-arrowscrollbox > scrollbox {
157 | border-top-width: 0px !important;
158 | padding-top: 0px !important;
159 | margin-top: 0px !important;
160 | }
161 |
162 | #main-window .tabbrowser-tabs[multirow]:not([showPhantom="true"]) > .tabbrowser-tab[pinned] {
163 | position: static !important;
164 | margin-top: 0px !important;
165 | }
166 |
167 | /* Multi-row Tabs */
168 | .tabbrowser-tabs[multirow] .tabbrowser-arrowscrollbox,
169 | .tabbrowser-tabs[multirow] .tabbrowser-arrowscrollbox > scrollbox,
170 | .tabbrowser-tabs[multirow] .tabbrowser-arrowscrollbox > scrollbox > box {
171 | display: inline-block;
172 | }
173 |
174 | #TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
175 | .tabbrowser-tabs[multirow] .tabbrowser-tab[collapsed="true"],
176 | .tabbrowser-tabs[multirow] .tabbrowser-arrowscrollbox > .scrollbutton-up,
177 | .tabbrowser-tabs[multirow] .tabbrowser-arrowscrollbox > .scrollbutton-down {
178 | display: none;
179 | }
180 |
181 | .tabbrowser-tabs[multirow] .tabbrowser-tab,
182 | .tabbrowser-tabs[multirow] .tabbrowser-arrowscrollbox > * {
183 | vertical-align: top;
184 | }
185 |
186 | /* Bookmarks with history */
187 | .bookmark-item[history] {
188 | color: blue;
189 | }
190 |
191 | /* Toolbar buttons */
192 | #button_tuOptions {
193 | list-style-image: url("chrome://tabutils/skin/tabutils.png");
194 | }
195 |
196 | #closetab-button {
197 | list-style-image: url("chrome://global/skin/icons/close.png");
198 | -moz-image-region: rect(0px, 14px, 14px, 0px);
199 | }
200 |
201 | #undoclosetab-button {
202 | list-style-image: url("chrome://tabutils/skin/toolbar_Fx4.png");
203 | }
204 |
205 | #undoclosetab-button[disabled="true"] {
206 | }
207 |
208 | #button_tuOptions .toolbarbutton-icon {
209 | width: 22px;
210 | height: 20px;
211 | margin: 2px 1px;
212 | }
213 |
214 | #closetab-button .toolbarbutton-icon,
215 | #undoclosetab-button .toolbarbutton-icon {
216 | width: 20px;
217 | height: 20px;
218 | margin: 2px;
219 | }
220 |
221 | toolbar[iconsize="small"] #button_tuOptions .toolbarbutton-icon,
222 | toolbar[iconsize="small"] #closetab-button .toolbarbutton-icon,
223 | toolbar[iconsize="small"] #undoclosetab-button .toolbarbutton-icon {
224 | width: 16px;
225 | height: 16px;
226 | margin: 0px;
227 | }
228 |
229 | /* Statusbar buttons */
230 | #status-bar[mode="icons"] > #statusbar-openintab > .statusbarpanel-text,
231 | #status-bar[mode="icons"] > #statusbar-loadinbackground > .statusbarpanel-text,
232 | #status-bar[mode="icons"] > #statusbar-loadinforeground > .statusbarpanel-text {
233 | display: none;
234 | }
235 |
236 | #status-bar[mode="text"] > #statusbar-openintab > .statusbarpanel-icon,
237 | #status-bar[mode="text"] > #statusbar-loadinbackground > .statusbarpanel-icon,
238 | #status-bar[mode="text"] > #statusbar-loadinforeground > .statusbarpanel-icon {
239 | display: none;
240 | }
241 |
242 | #statusbar-openintab,
243 | #statusbar-loadinbackground,
244 | #statusbar-loadinforeground {
245 | list-style-image: url("resource:///chrome/browser/skin/classic/browser/classic/browser/Toolbar-small.png");
246 | font-weight: bold;
247 | color: green;
248 | }
249 |
250 | #statusbar-openintab[checked="false"],
251 | #statusbar-loadinbackground[checked="false"],
252 | #statusbar-loadinforeground[checked="false"] {
253 | color: grey;
254 | }
255 |
256 | #statusbar-openintab {
257 | -moz-image-region: rect(0px, 160px, 16px, 144px);
258 | }
259 |
260 | #statusbar-loadinbackground {
261 | -moz-image-region: rect(0px, 16px, 16px, 0px);
262 | }
263 |
264 | #statusbar-loadinforeground {
265 | -moz-image-region: rect(0px, 32px, 16px, 16px);
266 | }
267 |
268 | #statusbar-openintab[checked="false"] {
269 | -moz-image-region: rect(32px, 48px, 48px, 32px);
270 | }
271 |
272 | #statusbar-loadinbackground[checked="false"] {
273 | -moz-image-region: rect(32px, 16px, 48px, 0px);
274 | }
275 |
276 | #statusbar-loadinforeground[checked="false"] {
277 | -moz-image-region: rect(32px, 32px, 48px, 16px);
278 | }
279 |
280 | /* Full Screen UI */
281 | #fullscr-toggler-bottom {
282 | height: 1px;
283 | background: black;
284 | }
285 |
286 | #fullscr-toggler-left,
287 | #fullscr-toggler-right {
288 | width: 1px;
289 | background: black;
290 | }
291 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/tabutils.png
--------------------------------------------------------------------------------
/chrome/skin/tabutils_fx14.css:
--------------------------------------------------------------------------------
1 | /* Toolbar buttons */
2 | window[v14="true"]:not([OS="Linux"]) #navigator-toolbox[iconsize=large][mode=icons] > #nav-bar #button_tuOptions .toolbarbutton-icon,
3 | window[v14="true"]:not([OS="Linux"]) #navigator-toolbox[iconsize=large][mode=icons] > #nav-bar #closetab-button .toolbarbutton-icon {
4 | width: 32px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_fx29.css:
--------------------------------------------------------------------------------
1 | /* Toolbar buttons */
2 | window[v29="true"]:not([OS="Linux"]) #nav-bar #button_tuOptions .toolbarbutton-icon,
3 | window[v29="true"]:not([OS="Linux"]) #nav-bar #closetab-button .toolbarbutton-icon {
4 | width: 32px;
5 | height: 24px;
6 | }
7 |
8 | /* Statusbar buttons */
9 | window[v29="true"] #statusbar-openintab {
10 | -moz-image-region: rect(0px, 360px, 18px, 342px);
11 | }
12 | window[v29="true"] #statusbar-loadinbackground {
13 | -moz-image-region: rect(0px, 54px, 18px, 36px);
14 | }
15 | window[v29="true"] #statusbar-loadinforeground {
16 | -moz-image-region: rect(0px, 72px, 18px, 54px);
17 | }
18 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_fx31.css:
--------------------------------------------------------------------------------
1 | /* Phantom Tabs */
2 | window[v31="true"] .tabbrowser-tab[pinned] .tab-background:not([fadein]),
3 | window[v31="true"] .tabbrowser-tab[pinned] .tab-close-button:not([fadein]),
4 | window[v31="true"] .tabbrowser-tab[pinned] .tab-label:not([fadein]) {
5 | visibility: visible;
6 | }
7 | window[v31="true"] .tabbrowser-tab[pinned] .tab-icon-image:not([fadein]) {
8 | display: -moz-box;
9 | }
10 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_fx4.css:
--------------------------------------------------------------------------------
1 | window[v4="true"] .tab-content {
2 | -moz-binding: url(chrome://tabutils/content/tabutils.xml#tab-content);
3 | }
4 |
5 | window[v4="true"] .tab-twisty {
6 | -moz-binding: url(chrome://tabutils/content/tabutils.xml#tab-twisty);
7 | }
8 |
9 | window[v4="true"] .tab-content > .tab-counter {
10 | -moz-binding: none !important; /* Compa. with Informational Tab */
11 | }
12 |
13 | window[v4="true"] browser {
14 | -moz-binding: url(chrome://tabutils/content/tabutils.xml#browser);
15 | }
16 |
17 | /* Tabs toolbar */
18 | #TabsToolbar[orient="vertical"],
19 | #browser-bottombox > #TabsToolbar {
20 | -moz-box-ordinal-group: 1;
21 | }
22 |
23 | .tabbrowser-arrowscrollbox[orient="vertical"] > .arrowscrollbox-scrollbox {
24 | overflow: auto;
25 | }
26 |
27 | .tabbrowser-arrowscrollbox[orient="vertical"] > .scrollbutton-up,
28 | .tabbrowser-arrowscrollbox[orient="vertical"] > .scrollbutton-down,
29 | .tabbrowser-tabs[orient="vertical"] > hbox > .tab-drop-indicator {
30 | display: none;
31 | }
32 |
33 | #TabsToolbar[orient="vertical"] :-moz-any(toolbaritem, toolbarpaletteitem) > * {
34 | -moz-box-flex: 1;
35 | }
36 |
37 | #TabsToolbar[orient="vertical"] toolbarseparator {
38 | -moz-appearance: none;
39 | border-width: 3px 2px;
40 | -moz-border-top-colors : transparent transparent ThreeDShadow;
41 | -moz-border-bottom-colors : transparent transparent ThreeDHighlight;
42 | }
43 |
44 | #TabsToolbar[orient="vertical"] > toolbarspacer {
45 | height: 15px;
46 | }
47 |
48 | #TabsToolbar[orient="vertical"] > toolbarpaletteitem {
49 | margin-top: -2px;
50 | margin-bottom: -2px;
51 | border-top: 2px solid transparent;
52 | border-bottom: 2px solid transparent;
53 | }
54 |
55 | #TabsToolbar[orient="vertical"] > toolbarpaletteitem > toolbarspacer {
56 | height: 11px;
57 | }
58 |
59 | #TabsToolbar[orient="vertical"] > toolbarpaletteitem[dragover="left"] {
60 | border-left-color: transparent;
61 | border-top-color: #000000;
62 | }
63 |
64 | #TabsToolbar[orient="vertical"] > toolbarpaletteitem[dragover="right"] {
65 | border-right-color: transparent;
66 | border-bottom-color: #000000;
67 | }
68 |
69 | /* Tab Stacking */
70 | .tabbrowser-tabs[orient="horizontal"]:not([colorStack="true"]) > .tabbrowser-tab:-moz-any(:not([group]):not([pinned]), [group-selected])
71 | ~ .tabbrowser-tab[group-selected]:not([group-counter="1"])[group-collapsed],
72 | .tabbrowser-tabs[orient="horizontal"]:not([colorStack="true"]) > .tabbrowser-tab:-moz-any(:not([group]):not([pinned]), [group-selected])
73 | ~ .tabbrowser-tab[group-first]:not([group-last]):not([group-collapsed]),
74 | .tabbrowser-tabs[orient="horizontal"]:not([colorStack="true"]) > .tabbrowser-tab[group-last]:not([group-first])
75 | + .tabbrowser-tab:-moz-any(:not([group]), [group-counter="1"]),
76 | .tabbrowser-tabs[orient="vertical"] > .tabbrowser-tab[group]:not([group-first]):not([group-collapsed]) {
77 | -moz-margin-start: 9px;
78 | }
79 |
80 | .tabbrowser-tab[group-selected]:not([group-counter="1"])[group-collapsed] .tab-twisty {
81 | list-style-image: url("jar:resource://app/omni.jar!/chrome/toolkit/skin/classic/global/tree/twisty-clsd.png");
82 | }
83 |
84 | .tabbrowser-tab[group-first]:not([group-last]):not([group-collapsed]) .tab-twisty {
85 | list-style-image: url("jar:resource://app/omni.jar!/chrome/toolkit/skin/classic/global/tree/twisty-open.png");
86 | }
87 |
88 | .tabbrowser-tabs[orient="vertical"]:not([treestyletab-mode]) > .tabbrowser-tab:-moz-any(:not([group]):not([pinned]), [group-counter="1"]) .tab-twisty {
89 | width: 9px;
90 | }
91 |
92 | .tab-counter {
93 | display: none;
94 | }
95 |
96 | .tabbrowser-tab[group-selected]:not([group-counter="1"])[group-collapsed] .tab-counter {
97 | display: -moz-box !important;
98 | }
99 |
100 | .tabbrowser-tab[dragover="center"] {
101 | outline: 2px solid -moz-dialogtext !important;
102 | outline-offset: -2px !important;
103 | -moz-outline-radius: 4px !important;
104 | }
105 |
106 | /*
107 | .tabbrowser-tab[dragover="left"] {
108 | -moz-border-left-colors: -moz-dialogtext -moz-dialogtext transparent !important;
109 | }
110 |
111 | .tabbrowser-tab[dragover="right"] {
112 | -moz-border-right-colors: -moz-dialogtext -moz-dialogtext transparent !important;
113 | }
114 |
115 | .tabbrowser-tab[dragover="top"] {
116 | -moz-border-top-colors: -moz-dialogtext -moz-dialogtext transparent !important;
117 | }
118 |
119 | .tabbrowser-tab[dragover="bottom"] {
120 | -moz-border-bottom-colors: -moz-dialogtext -moz-dialogtext transparent !important;
121 | }*/
122 |
123 | /* Tab Width */
124 | window[v4="true"] .tabbrowser-tabs > .tabbrowser-tab:not([pinned]):not([fadein]) {
125 | max-width: 0.1px !important;
126 | min-width: 0.1px !important;
127 | }
128 |
129 | window[v4="true"] .tabbrowser-tabs[dontanimate="true"] > .tabbrowser-tab {
130 | -moz-transition: none !important;
131 | }
132 |
133 | window[v4="true"] .tabbrowser-tab[protected] .tab-close-button > .toolbarbutton-icon {
134 | width: 16px;
135 | height: 16px;
136 | }
137 |
138 | window[v4="true"] .tabbrowser-tab[pinned][unread][rotate="true"] .tab-icon-image {
139 | -moz-transform: rotate(360deg);
140 | }
141 |
142 | window[v4="true"] .tabbrowser-tab[pinned][unread] .tab-icon-image {
143 | -moz-transition: -moz-transform .4s linear;
144 | }
145 |
146 | /* Pinned Tabs */
147 | window[v4="true"] .tabbrowser-tabs[style*="-moz-margin-start"],
148 | window[v4="true"] .tabbrowser-tab[style*="-moz-margin-start"] {
149 | -moz-margin-start: 0px !important;
150 | }
151 |
152 | window[v4="true"] .tabbrowser-tabs[style*="margin-top"] {
153 | margin-top: 0px !important;
154 | }
155 |
156 | window[v4="true"] .tabbrowser-tab[style*="margin-left"] {
157 | margin-left: 0px !important;
158 | }
159 |
160 | window[v4="true"] #PinnedTabsBarDropIndicator {
161 | list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
162 | }
163 |
164 | window[v4="true"] .tabbrowser-tab[pinned]:not([faviconized]) .tab-label {
165 | width: auto;
166 | }
167 |
168 | /* Toolbar buttons */
169 | window[v4="true"] #closetab-button {
170 | list-style-image: url("jar:resource://app/omni.jar!/chrome/toolkit/skin/classic/global/icons/close.png");
171 | -moz-image-region: rect(0px, 16px, 16px, 0px);
172 | }
173 |
174 | window[v4="true"]:not([OS="Linux"]) #button_tuOptions .toolbarbutton-icon,
175 | window[v4="true"]:not([OS="Linux"]) #closetab-button .toolbarbutton-icon {
176 | width: 16px;
177 | height: 16px;
178 | }
179 |
180 | window[v4="true"]:not([OS="Linux"]) #undoclosetab-button .toolbarbutton-icon {
181 | width: auto;
182 | height: auto;
183 | }
184 |
185 | /* Statusbar buttons */
186 | window[v4="true"] #statusbar-openintab,
187 | window[v4="true"] #statusbar-loadinbackground,
188 | window[v4="true"] #statusbar-loadinforeground {
189 | list-style-image: url("jar:resource://app/omni.jar!/chrome/browser/skin/classic/browser/Toolbar.png");
190 | }
191 |
192 | window[v4="true"]:not([OS="Linux"]) #statusbar-openintab[checked="false"],
193 | window[v4="true"]:not([OS="Linux"]) #statusbar-loadinbackground[checked="false"],
194 | window[v4="true"]:not([OS="Linux"]) #statusbar-loadinforeground[checked="false"] {
195 | opacity: 0.5;
196 | }
197 |
198 | window[v4="true"] #statusbar-openintab {
199 | -moz-image-region: rect(0px, 180px, 18px, 162px);
200 | }
201 |
202 | window[v4="true"] #statusbar-loadinbackground {
203 | -moz-image-region: rect(0px, 18px, 18px, 0px);
204 | }
205 |
206 | window[v4="true"] #statusbar-loadinforeground {
207 | -moz-image-region: rect(0px, 36px, 18px, 18px);
208 | }
209 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_fx45.css:
--------------------------------------------------------------------------------
1 | /* Tab Stacking */
2 | window[v45="true"] .tabbrowser-tab[group-selected]:not([group-counter="1"])[group-collapsed] .tab-twisty {
3 | list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd");
4 | }
5 |
6 | window[v45="true"] .tabbrowser-tab[group-first]:not([group-last]):not([group-collapsed]) .tab-twisty {
7 | list-style-image: url("chrome://global/skin/tree/twisty.svg#open");
8 | }
9 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_fx6.css:
--------------------------------------------------------------------------------
1 | /* Tab Stacking */
2 | window[v6="true"] .tabbrowser-tab[group-selected]:not([group-counter="1"])[group-collapsed] .tab-twisty {
3 | list-style-image: url("chrome://global/skin/tree/twisty-clsd.png");
4 | }
5 |
6 | window[v6="true"] .tabbrowser-tab[group-first]:not([group-last]):not([group-collapsed]) .tab-twisty {
7 | list-style-image: url("chrome://global/skin/tree/twisty-open.png");
8 | }
9 |
10 | /* Toolbar buttons */
11 | window[v6="true"] #closetab-button {
12 | list-style-image: url("chrome://global/skin/icons/close.png");
13 | }
14 |
15 | /* Statusbar buttons */
16 | window[v6="true"] #statusbar-openintab,
17 | window[v6="true"] #statusbar-loadinbackground,
18 | window[v6="true"] #statusbar-loadinforeground {
19 | list-style-image: url("resource:///chrome/browser/skin/classic/browser/Toolbar.png");
20 | }
21 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_linux.css:
--------------------------------------------------------------------------------
1 | /* Toolbar buttons */
2 | window[OS="Linux"] #closetab-button {
3 | list-style-image: url("moz-icon://stock/gtk-close?size=toolbar");
4 | -moz-image-region: auto;
5 | }
6 |
7 | window[OS="Linux"] #closetab-button[disabled="true"] {
8 | list-style-image: url("moz-icon://stock/gtk-close?size=toolbar&state=disabled");
9 | }
10 |
11 | window[OS="Linux"] toolbar[iconsize="small"] #closetab-button {
12 | list-style-image: url("moz-icon://stock/gtk-close?size=menu");
13 | }
14 |
15 | window[OS="Linux"] toolbar[iconsize="small"] #closetab-button[disabled="true"] {
16 | list-style-image: url("moz-icon://stock/gtk-close?size=menu&state=disabled");
17 | }
18 |
19 | window[OS="Linux"] #undoclosetab-button {
20 | list-style-image: url("moz-icon://stock/gtk-undelete?size=toolbar");
21 | -moz-image-region: auto;
22 | }
23 |
24 | window[OS="Linux"] #undoclosetab-button[disabled="true"] {
25 | list-style-image: url("moz-icon://stock/gtk-undelete?size=toolbar&state=disabled");
26 | }
27 |
28 | window[OS="Linux"] toolbar[iconsize="small"] #undoclosetab-button {
29 | list-style-image: url("moz-icon://stock/gtk-undelete?size=menu");
30 | }
31 |
32 | window[OS="Linux"] toolbar[iconsize="small"] #undoclosetab-button[disabled="true"] {
33 | list-style-image: url("moz-icon://stock/gtk-undelete?size=menu&state=disabled");
34 | }
35 |
36 | window[OS="Linux"] #closetab-button .toolbarbutton-icon,
37 | window[OS="Linux"] #undoclosetab-button .toolbarbutton-icon {
38 | width: auto;
39 | height: auto;
40 | margin: 0px;
41 | }
42 |
43 | /* Status bar buttons */
44 | window[OS="Linux"] #statusbar-openintab {
45 | list-style-image: url("moz-icon://stock/gtk-add?size=menu");
46 | -moz-image-region: auto;
47 | }
48 |
49 | window[OS="Linux"] #statusbar-openintab[checked="false"] {
50 | list-style-image: url("moz-icon://stock/gtk-add?size=menu&state=disabled");
51 | }
52 |
53 | window[OS="Linux"] #statusbar-loadinbackground {
54 | list-style-image: url("moz-icon://stock/gtk-go-back?size=menu");
55 | -moz-image-region: auto;
56 | }
57 |
58 | window[OS="Linux"] #statusbar-loadinbackground[checked="false"] {
59 | list-style-image: url("moz-icon://stock/gtk-go-back?size=menu&state=disabled");
60 | }
61 |
62 | window[OS="Linux"] #statusbar-loadinforeground {
63 | list-style-image: url("moz-icon://stock/gtk-go-forward?size=menu");
64 | -moz-image-region: auto;
65 | }
66 |
67 | window[OS="Linux"] #statusbar-loadinforeground[checked="false"] {
68 | list-style-image: url("moz-icon://stock/gtk-go-forward?size=menu&state=disabled");
69 | }
70 |
--------------------------------------------------------------------------------
/chrome/skin/tabutils_mac.css:
--------------------------------------------------------------------------------
1 | /* Tab Stacking */
2 | window[OS="Darwin"][v4="true"] .tabbrowser-tab[group-selected]:not([group-counter="1"])[group-collapsed] .tab-twisty {
3 | -moz-appearance: treetwisty;
4 | -moz-padding-end: 2px;
5 | }
6 |
7 | window[OS="Darwin"][v4="true"] .tabbrowser-tab[group-first]:not([group-last]):not([group-collapsed]) .tab-twisty {
8 | -moz-appearance: treetwistyopen;
9 | }
10 |
11 | window[OS="Darwin"][v4="true"] .tabbrowser-tabs[orient="vertical"]:not([treestyletab-mode]) > .tabbrowser-tab:-moz-any(:not([group]):not([pinned]), [group-counter="1"]) .tab-twisty {
12 | width: 21px;
13 | }
14 |
15 | window[OS="Darwin"][v4="true"] .tabbrowser-tabs[orient="vertical"] > .tabbrowser-tab[group]:not([group-first]):not([group-collapsed]) {
16 | -moz-margin-start: 21px;
17 | }
18 |
19 | /* Status bar buttons */
20 | window[OS="Darwin"][v4="true"] #statusbar-openintab {
21 | -moz-image-region: rect(0px, 220px, 20px, 200px);
22 | }
23 |
24 | window[OS="Darwin"][v4="true"] #statusbar-loadinbackground {
25 | -moz-image-region: rect(0px, 40px, 20px, 20px);
26 | }
27 |
28 | window[OS="Darwin"][v4="true"] #statusbar-loadinforeground {
29 | -moz-image-region: rect(0px, 60px, 20px, 40px);
30 | }
31 |
--------------------------------------------------------------------------------
/chrome/skin/toolbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/toolbar.png
--------------------------------------------------------------------------------
/chrome/skin/toolbar_Fx4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfdyh000/tabutils/c1a9f054aae6b50dba1d084d55befaebb11edbbf/chrome/skin/toolbar_Fx4.png
--------------------------------------------------------------------------------
/install.rdf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tabutilsfixed@addon.cn
5 | 2
6 | Tab Utilities Fixed
7 | 1.5.2017.08.17
8 | YFdyh000
9 | ithinc (Former author)
10 | Phil Tsarik
11 | Kamui-Solo
12 | Leszek(teo)Życzkowski
13 | Emanuele Alimonda
14 | Cye3s (zh-CN)
15 | Jose Sun, kingsmile (zh-TW)
16 | Leszek(teo)Życzkowski (pl)
17 | Edgard Dias Magalhaes (pt-BR)
18 | erglo, o.roth (ReinekeFux) von BabelZilla.org (de)
19 | Carlos Mella (es-ES)
20 | ynetbot (ru)
21 | matsumoto (ja-JP)
22 | Klezzon (it)
23 | Open Bookmarks/History/URL/Search in new tabs, and more utilities for tabbed browsing.
24 | https://addons.mozilla.org/firefox/addon/tab-utilities-fixed/
25 | chrome://tabutils/skin/tabutils.png
26 | chrome://tabutils/content/preferences.xul
27 |
28 |
29 | {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
30 | 17.0
31 | 39.*
32 |
33 |
34 | false
35 | true
36 |
37 |
--------------------------------------------------------------------------------
/modules/Services.jsm:
--------------------------------------------------------------------------------
1 | "use strict";
2 | // License: The file copied from Tab Mix Plus 0.4.1.6pre.141229a1 (MPL 2.0)
3 |
4 | var EXPORTED_SYMBOLS = ["TabmixSvc"];
5 |
6 | const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
7 |
8 | Cu.import("resource://gre/modules/XPCOMUtils.jsm");
9 | Cu.import("resource://gre/modules/Services.jsm");
10 |
11 | let _versions = {};
12 | function isVersion(aVersionNo) {
13 | if (TabmixSvc.isPaleMoonID) {
14 | let paleMoonVer = arguments.length > 1 ? arguments[1] : -1;
15 | if (aVersionNo > 240 && paleMoonVer == -1)
16 | return false;
17 | aVersionNo = paleMoonVer;
18 | }
19 |
20 | if (typeof _versions[aVersionNo] == "boolean")
21 | return _versions[aVersionNo];
22 |
23 | let v = Services.appinfo.version;
24 | return _versions[aVersionNo] = Services.vc.compare(v, aVersionNo/10 + ".0a1") >= 0;
25 | }
26 |
27 | let TabmixSvc = {
28 | debugMode: function() {
29 | return this.prefBranch.prefHasUserValue("enableDebug") &&
30 | this.prefBranch.getBoolPref("enableDebug");
31 | },
32 |
33 | version: function() {
34 | return isVersion.apply(null, arguments);
35 | },
36 |
37 | getString: function(aStringKey) {
38 | try {
39 | return this._strings.GetStringFromName(aStringKey);
40 | } catch (e) {
41 | dump("*** Failed to get string " + aStringKey + " in bundle: tabmix.properties\n");
42 | throw e;
43 | }
44 | },
45 |
46 | getFormattedString: function(aStringKey, aStringsArray) {
47 | try {
48 | return this._strings.formatStringFromName(aStringKey, aStringsArray, aStringsArray.length);
49 | } catch (e) {
50 | dump("*** Failed to format string " + aStringKey + " in bundle: tabmix.properties\n");
51 | throw e;
52 | }
53 | },
54 |
55 | getSMString: function(aStringKey) {
56 | try {
57 | return this.SMstrings.GetStringFromName(aStringKey);
58 | } catch (e) {
59 | dump("*** Failed to get string " + aStringKey + " in bundle: session-manager.properties\n");
60 | throw e;
61 | }
62 | },
63 |
64 | setLabel: function(property) {
65 | var label, key;
66 | if (property.indexOf("sm.") == 0) {
67 | label = this.getSMString(property + ".label");
68 | key = this.getSMString(property + ".accesskey");
69 | }
70 | else {
71 | label = this.getString(property + ".label");
72 | key = this.getString(property + ".accesskey");
73 | }
74 | var accessKeyIndex = label.toLowerCase().indexOf(key.toLowerCase());
75 | if (accessKeyIndex > -1)
76 | label = label.substr(0, accessKeyIndex) + "&" + label.substr(accessKeyIndex);
77 | return label;
78 | },
79 |
80 | topWin: function() {
81 | return Services.wm.getMostRecentWindow("navigator:browser");
82 | },
83 |
84 | get direct2dDisabled() {
85 | delete this.direct2dDisabled;
86 | try {
87 | // this pref exist only in windows
88 | return this.direct2dDisabled = Services.prefs.getBoolPref("gfx.direct2d.disabled");
89 | } catch(ex) {}
90 | return this.direct2dDisabled = false;
91 | },
92 |
93 | /**
94 | * call a callback for all currently opened browser windows
95 | * (might miss the most recent one)
96 | * @param aFunc
97 | * Callback each window is passed to
98 | */
99 | forEachBrowserWindow: function(aFunc) {
100 | let windowsEnum = Services.wm.getEnumerator("navigator:browser");
101 | while (windowsEnum.hasMoreElements()) {
102 | let window = windowsEnum.getNext();
103 | if (!window.closed) {
104 | aFunc.call(null, window);
105 | }
106 | }
107 | },
108 |
109 | // some extensions override native JSON so we use nsIJSON
110 | JSON: {
111 | nsIJSON: null,
112 | parse: function TMP_parse(str) {
113 | try {
114 | return JSON.parse(str);
115 | } catch(ex) {
116 | try {
117 | return "decode" in this.nsIJSON ? this.nsIJSON.decode(str) : null;
118 | } catch(ex) {return null}
119 | }
120 | },
121 | stringify: function TMP_stringify(obj) {
122 | try {
123 | return JSON.stringify(obj);
124 | } catch(ex) {
125 | try {
126 | return "encode" in this.nsIJSON ? this.nsIJSON.encode(obj) : null;
127 | } catch(ex) {return null}
128 | }
129 | }
130 | },
131 |
132 | syncHandlers: new WeakMap(),
133 |
134 | windowStartup: {
135 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
136 | Ci.nsISupportsWeakReference]),
137 | _initialized: false,
138 | init: function(aWindow) {
139 | // windowStartup must only be called once for each window
140 | if ("firstWindowInSession" in aWindow.Tabmix)
141 | return;
142 | aWindow.Tabmix.firstWindowInSession = !this._initialized;
143 | if (this._initialized)
144 | return;
145 | this._initialized = true;
146 |
147 | try {
148 | // replace old Settings.
149 | // we must call this before any other tabmix function
150 | aWindow.gTMPprefObserver.updateSettings();
151 | } catch (ex) {TabmixSvc.console.assert(ex);}
152 |
153 | Services.obs.addObserver(this, "browser-delayed-startup-finished", true);
154 | Services.obs.addObserver(this, "quit-application", true);
155 |
156 | if (isVersion(190))
157 | Cu.import("resource://tabmixplus/DownloadLastDir.jsm");
158 |
159 | Cu.import("resource://tabmixplus/Places.jsm");
160 | TabmixPlacesUtils.init(aWindow);
161 |
162 | TabmixSvc.tabStylePrefs = {};
163 | let tmp = {};
164 | Cu.import("resource://tabmixplus/DynamicRules.jsm", tmp);
165 | tmp.DynamicRules.init(aWindow);
166 | },
167 |
168 | observe: function(aSubject, aTopic, aData) {
169 | switch (aTopic) {
170 | case "quit-application":
171 | TabmixPlacesUtils.onQuitApplication();
172 | for (let id of Object.keys(TabmixSvc.console._timers)) {
173 | let timer = TabmixSvc.console._timers[id];
174 | timer.cancel();
175 | }
176 | break;
177 | case "browser-delayed-startup-finished":
178 | try {
179 | aSubject.Tabmix.initialization.run("delayedStartup");
180 | } catch (ex) {TabmixSvc.console.assert(ex);}
181 | break;
182 | }
183 | }
184 | },
185 |
186 | saveTabAttributes: function(tab, attrib) {
187 | TabStateCache.saveTabAttributes(tab, attrib);
188 | },
189 |
190 | get ss() {
191 | delete this.ss;
192 | if (isVersion(250, 250)) {
193 | let tmp = {}
194 | Cu.import("resource:///modules/sessionstore/SessionStore.jsm", tmp);
195 | return this.ss = tmp.SessionStore;
196 | }
197 | return this.ss = Cc["@mozilla.org/browser/sessionstore;1"].
198 | getService(Ci.nsISessionStore);
199 | },
200 |
201 | sm: {
202 | lastSessionPath: null,
203 | persistTabAttributeSet: false,
204 | status: "",
205 | crashed: false,
206 | get sanitized() {
207 | delete this.sanitized;
208 | return this.sanitized = TabmixSvc.prefBranch.prefHasUserValue("sessions.sanitized");
209 | },
210 | set sanitized(val) {
211 | delete this.sanitized;
212 | return this.sanitized = val;
213 | },
214 | private: true,
215 | settingPreference: false,
216 | },
217 |
218 | blockedClickingOptions: []
219 | }
220 |
221 | XPCOMUtils.defineLazyGetter(TabmixSvc.JSON, "nsIJSON", function() {
222 | return Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
223 | });
224 |
225 | // check if australis tab shape is implemented
226 | XPCOMUtils.defineLazyGetter(TabmixSvc, "australis", function() {
227 | return this.topWin().document.getElementById("tab-curve-clip-path-start") ?
228 | true : false;
229 | });
230 |
231 | XPCOMUtils.defineLazyGetter(TabmixSvc, "prefs", function() {
232 | let svc = isVersion(230) ? "resource://gre/modules/Preferences.jsm" :
233 | "resource://services-common/preferences.js";
234 | let tmp = {}
235 | Cu.import(svc, tmp);
236 | return new tmp.Preferences("");
237 | });
238 |
239 | // Tabmix preference branch
240 | XPCOMUtils.defineLazyGetter(TabmixSvc, "prefBranch", function () {return Services.prefs.getBranch("extensions.tabmix.")});
241 | // string bundle
242 | XPCOMUtils.defineLazyGetter(TabmixSvc, "_strings", function () {
243 | let properties = "chrome://tabmixplus/locale/tabmix.properties";
244 | return Services.strings.createBundle(properties);
245 | });
246 | XPCOMUtils.defineLazyGetter(TabmixSvc, "SMstrings", function () {
247 | let properties = "chrome://tabmixplus/locale/session-manager.properties";
248 | return Services.strings.createBundle(properties);
249 | });
250 |
251 | XPCOMUtils.defineLazyGetter(TabmixSvc, "isMac", function () {
252 | return Services.appinfo.OS == "Darwin";
253 | });
254 |
255 | XPCOMUtils.defineLazyGetter(TabmixSvc, "isLinux", function () {
256 | return Services.appinfo.OS == "Linux";
257 | });
258 |
259 | XPCOMUtils.defineLazyGetter(TabmixSvc, "isPaleMoon", function () {
260 | return Services.appinfo.name == "Pale Moon";
261 | });
262 |
263 | XPCOMUtils.defineLazyGetter(TabmixSvc, "isPaleMoonID", function () {
264 | return Services.appinfo.ID == "{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}";
265 | });
266 |
267 | /**
268 | * bug 1051017 - Firefox 34 - change
269 | * browser.contentWindow -> browser.contentWindowAsCPOW
270 | * browser.contentDocument -> browser.contentDocumentAsCPOW
271 | * window.content -> window.gBrowser.selectedBrowser.contentWindowAsCPOW
272 | **/
273 | XPCOMUtils.defineLazyGetter(TabmixSvc, "contentWindowAsCPOW", function () {
274 | return isVersion(340) ? "contentWindowAsCPOW" : "contentWindow";
275 | });
276 |
277 | XPCOMUtils.defineLazyGetter(TabmixSvc, "contentDocumentAsCPOW", function () {
278 | return isVersion(340) ? "contentDocumentAsCPOW" : "contentDocument";
279 | });
280 |
281 | XPCOMUtils.defineLazyModuleGetter(TabmixSvc, "FileUtils",
282 | "resource://gre/modules/FileUtils.jsm");
283 |
284 | XPCOMUtils.defineLazyModuleGetter(TabmixSvc, "console",
285 | "resource://tabmixplus/log.jsm");
286 |
287 | let TabStateCache = {
288 | get _update() {
289 | delete this._update;
290 | return this._update = isVersion(260) ? "updateField" : "update";
291 | },
292 |
293 | get TabStateCache() {
294 | delete this.TabStateCache;
295 | if (isVersion(270))
296 | Cu.import("resource:///modules/sessionstore/TabStateCache.jsm", this);
297 | else
298 | this.TabStateCache = Cu.getGlobalForObject(TabmixSvc.ss).TabStateCache;
299 | return this.TabStateCache;
300 | },
301 |
302 | saveTabAttributes: function(tab, attrib) {
303 | if (!isVersion(250))
304 | return;
305 |
306 | let attribs = attrib.split(",");
307 | function update(attributes) {
308 | attribs.forEach(function(key) {
309 | if (tab.hasAttribute(key))
310 | attributes[key] = tab.getAttribute(key);
311 | else if (key in attributes)
312 | delete attributes[key];
313 | })
314 | }
315 |
316 | let browser = tab.linkedBrowser;
317 | if (browser.__SS_data) {
318 | if (!browser.__SS_data.attributes)
319 | browser.__SS_data.attributes = {};
320 | update(browser.__SS_data.attributes);
321 | }
322 |
323 | // Bug 905049 fixed by Bug 960903 - Broadcast session history
324 | if (isVersion(290))
325 | return;
326 |
327 | let tabHasCache = isVersion(270) ? this.TabStateCache.has(browser) :
328 | this.TabStateCache._data.has(browser);
329 | if (tabHasCache) {
330 | let attributes = this.TabStateCache.get(browser).attributes || {};
331 | update(attributes);
332 | this.TabStateCache[this._update](browser, "attributes", attributes);
333 | }
334 | }
335 | }
336 |
--------------------------------------------------------------------------------
/modules/log.jsm:
--------------------------------------------------------------------------------
1 | "use strict";
2 | // License: The file copied from Tab Mix Plus 0.4.1.6pre.141229a1 (MPL 2.0)
3 |
4 | var EXPORTED_SYMBOLS = ["console"];
5 |
6 | const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
7 |
8 | Cu.import("resource://gre/modules/Services.jsm");
9 | Cu.import("resource://tabmixplus/Services.jsm");
10 |
11 | let gNextID = 1;
12 |
13 | let console = {
14 | getObject: function(aWindow, aMethod) {
15 | let msg = "";
16 | if (!aWindow)
17 | msg += "aWindow is undefined";
18 | if (typeof aMethod != "string")
19 | msg += (msg ? "\n" : "") + "aMethod need to be a string";
20 | if (msg) {
21 | this.assert(msg);
22 | return {toString: function() msg};
23 | }
24 | var rootID, methodsList = aMethod.split(".");
25 | if (methodsList[0] == "window")
26 | methodsList.shift();
27 | else if (methodsList[0] == "document") {
28 | methodsList.shift();
29 | rootID = methodsList.shift().replace(/getElementById\(|\)|'|"/g , "");
30 | }
31 | try {
32 | var obj = aWindow;
33 | if (rootID)
34 | obj = obj.document.getElementById(rootID);
35 | methodsList.forEach(function(aFn) {
36 | obj = obj[aFn];
37 | });
38 | } catch (ex) { }
39 | return obj || {toString: function() "undefined"};
40 | },
41 |
42 | _timers: {},
43 | show: function(aMethod, aDelay, aWindow) {
44 | try {
45 | if (typeof(aDelay) == "undefined")
46 | aDelay = 500;
47 |
48 | let logMethod = function _logMethod() {
49 | let result = "", isObj = typeof aMethod == "object";
50 | if (typeof aMethod != "function") {
51 | result = isObj ? aMethod.obj[aMethod.name] :
52 | this.getObject(aWindow, aMethod);
53 | result = " = " + result.toString()
54 | }
55 | this.clog((isObj ? aMethod.fullName : aMethod) + result);
56 | }.bind(this);
57 |
58 | if (aDelay >= 0) {
59 | let timerID = gNextID++;
60 | let timer = Object.create(Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer));
61 | timer.clear = function() {
62 | if (timerID in this._timers)
63 | delete this._timers[timerID];
64 | timer.cancel();
65 | }.bind(this);
66 | if (aWindow) {
67 | aWindow.addEventListener("unload", function unload() {
68 | timer.clear();
69 | }, false);
70 | }
71 | timer.initWithCallback({
72 | notify: function notify() {
73 | timer.clear();
74 | logMethod();
75 | }
76 | }, aDelay, Ci.nsITimer.TYPE_ONE_SHOT);
77 |
78 | this._timers[timerID] = timer;
79 | }
80 | else
81 | logMethod();
82 |
83 | } catch (ex) {this.assert(ex, "Error we can't show " + aMethod + " in Tabmix.show");}
84 | },
85 |
86 | clog: function(aMessage) {
87 | Services.console.logStringMessage("TabMix :\n" + aMessage);
88 | },
89 |
90 | log: function TMP_console_log(aMessage, aShowCaller, offset) {
91 | offset = !offset ? 0 : 1;
92 | let names = this._getNames(aShowCaller ? 2 + offset : 1 + offset);
93 | let callerName = names[offset+0];
94 | let callerCallerName = aShowCaller && names[offset+1] ? " (caller was " + names[offset+1] + ")" : "";
95 | Services.console.logStringMessage("TabMix " + callerName + callerCallerName + " :\n" + aMessage);
96 | },
97 |
98 | // get functions names from Error().stack
99 | // excluding any internal caller (name start with TMP_console_)
100 | _getNames: function(aCount, stack) {
101 | stack = this._getStackExcludingInternal(stack);
102 | if (!aCount)
103 | aCount = 1;
104 | else if (aCount < 0)
105 | aCount = stack.length;
106 | let names = [];
107 | for (let i = 0, l = Math.min(aCount, stack.length); i < l; i++)
108 | names.push(this._name(stack[i]));
109 |
110 | return names;
111 | },
112 |
113 | // get the name of the function that is in the nth place in Error().stack
114 | // excluding any internal caller in the count
115 | getCallerNameByIndex: function(aIndex) {
116 | let fn = this._getStackExcludingInternal()[aIndex];
117 | if (fn)
118 | return this._name(fn);
119 | return null;
120 | },
121 |
122 | _getStackExcludingInternal: function(stack) {
123 | if (!stack)
124 | stack = Error().stack.split("\n").slice(2);
125 | else
126 | stack = stack.split("\n");
127 | // cut internal callers
128 | let re = /TMP_console_.*/;
129 | while (stack.length && stack[0].match(re))
130 | stack.splice(0, 1);
131 | return stack;
132 | },
133 |
134 | _char: "@",
135 | _name: function(fn) {
136 | let name = fn.substr(0, fn.indexOf(this._char))
137 | if (fn && !name) {
138 | // get file name and line number
139 | let lastIndexOf = fn.lastIndexOf("/");
140 | name = lastIndexOf > -1 ? fn.substr(lastIndexOf+1) : "?";
141 | }
142 | return name;
143 | },
144 |
145 | /*
146 | _nameFromComponentsStack: function(Cs) {
147 | return Cs.name ||
148 | Cs.filename.substr(Cs.filename.lastIndexOf("/") + 1) + ":" + Cs.lineNumber;
149 | },
150 |
151 | callerName: function() {
152 | try {
153 | var name = this._nameFromComponentsStack(Components.stack.caller.caller);
154 | } catch (ex) { }
155 | return name || "";
156 | },
157 | */
158 |
159 | callerName: function TMP_console_callerName() {
160 | return this.getCallerNameByIndex(1);
161 | },
162 |
163 | // return true if the caller name of the calling function is in the
164 | // arguments list
165 | isCallerInList: function TMP_console_isCallerInList() {
166 | if (!arguments.length) {
167 | this.assert("no arguments in Tabmix.isCallerInList");
168 | return false;
169 | }
170 |
171 | try {
172 | let callerName = this.getCallerNameByIndex(1);
173 | if (!callerName)
174 | return false;
175 | if (typeof arguments[0] == "object")
176 | return arguments[0].indexOf(callerName) > -1;
177 |
178 | let args = Array.prototype.slice.call(arguments);
179 | return args.indexOf(callerName) > -1;
180 |
181 | } catch (ex) {
182 | this.assert(ex, "Error we can't check for caller name");
183 | }
184 | return false;
185 | },
186 |
187 | /*
188 | options = {
189 | msg: msg
190 | log: true / false; default true
191 | function: true / false default false
192 | deep: true / false default false
193 | offset; for internal use only true / false default false
194 | }
195 | */
196 | obj: function TMP_console_obj(aObj, aMessage, aDisallowLog, level) {
197 | var offset = typeof level == "string" ? " " : "";
198 | aMessage = aMessage ? offset + aMessage + "\n" : "";
199 | var objS = aObj ? offset + aObj.toString() : offset + "aObj is " + typeof(aObj);
200 | objS += ":\n"
201 |
202 | for (let prop in aObj) {
203 | try {
204 | let val = aObj[prop];
205 | let type = typeof val;
206 | if (type == "string")
207 | val = "\'" + val + "\'";
208 | if (type == "function" && typeof level == "string") {
209 | val = val.toString();
210 | let code = val.toString().indexOf("native code") > -1 ?
211 | "[native code]" : "[code]"
212 | val = val.substr(0, val.indexOf("(")) + "() { " + code + " }";
213 | }
214 | objS += offset + prop + "[" + type + "]" + " = " + val + "\n";
215 | if (type == "object" && val != null && level && typeof level == "boolean")
216 | objS += this.obj(val, "", true, "deep") + "\n";
217 | } catch (ex) {
218 | objS += offset + prop + " = " + "[!!error retrieving property]" + "\n";
219 | }
220 | }
221 | if (aDisallowLog)
222 | objS = aMessage + "======================\n" + objS;
223 | else
224 | this.log(aMessage + "=============== Object Properties ===============\n" + objS, true);
225 | return objS;
226 | },
227 |
228 | // RegExp to remove path/to/profile/extensions from filename
229 | get _pathRegExp() {
230 | delete this._pathRegExp;
231 | let folder = TabmixSvc.FileUtils.getDir("ProfD", ["extensions"]);
232 | let path = folder.path.replace("\\", "/", "g") + "/";
233 | return this._pathRegExp = new RegExp("jar:|file:///|" + path, "g");
234 | },
235 |
236 | _formatStack: function(stack) {
237 | let lines = [], _char = this._char, re = this._pathRegExp;
238 | stack.forEach(function(line) {
239 | let atIndex = line.indexOf("@");
240 | let columnIndex = line.lastIndexOf(":");
241 | let fileName = line.slice(atIndex + 1, columnIndex).split(" -> ").pop();
242 | if (fileName) {
243 | let lineNumber = parseInt(line.slice(columnIndex + 1));
244 | let colNumber;
245 | if (fileName.replace("://", "///").indexOf(":") > -1) {
246 | colNumber = lineNumber;
247 | columnIndex = fileName.lastIndexOf(":");
248 | lineNumber = parseInt(fileName.slice(columnIndex + 1));
249 | fileName = fileName.slice(0, columnIndex);
250 | }
251 | fileName = decodeURI(fileName).replace(re, "");
252 | let atIndex = line.indexOf(_char);
253 | let name = line.slice(0, atIndex).split("(").shift();
254 | let formated = ' File "' + fileName + '", line ' + lineNumber;
255 | if (colNumber)
256 | formated += ', col ' + colNumber;
257 | if (name)
258 | formated += ', in ' + name.replace("/<", "");
259 | lines.push(formated);
260 | }
261 | });
262 |
263 | return lines.join("\n");
264 | },
265 |
266 | assert: function TMP_console_assert(aError, aMsg) {
267 | if (!aError || typeof aError.stack != "string") {
268 | this.trace((aMsg || "") + "\n" + (aError || ""), 2);
269 | return;
270 | }
271 |
272 | let names = this._getNames(1, aError.stack);
273 | let errAt = " at " + names[0];
274 | let location = aError.location ? "\n" + aError.location : "";
275 | let assertionText = "Tabmix Plus ERROR" + errAt + ":\n" + (aMsg ? aMsg + "\n" : "") + aError.message + location;
276 | let stackText = "\nStack Trace: \n" + this._formatStack(aError.stack.split("\n"));
277 | Services.console.logStringMessage(assertionText + stackText);
278 | },
279 |
280 | trace: function TMP_console_trace(aMsg) {
281 | let stack = this._formatStack(this._getStackExcludingInternal());
282 | Services.console.logStringMessage("Tabmix Trace: " + (aMsg || "") + '\n' + stack);
283 | }
284 | }
285 |
--------------------------------------------------------------------------------