[Pkg-mozext-commits] [tree-style-tab] 01/03: Imported Upstream version 0.16.2015111001
Ximin Luo
infinity0 at debian.org
Fri Nov 13 16:11:46 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository tree-style-tab.
commit b01574386940bd498c576024849d74cd6264329d
Author: Ximin Luo <infinity0 at debian.org>
Date: Fri Nov 13 00:20:00 2015 +0100
Imported Upstream version 0.16.2015111001
---
META-INF/manifest.mf | 138 +++---
META-INF/mozilla.rsa | Bin 4189 -> 4189 bytes
META-INF/mozilla.sf | 4 +-
content/treestyletab/bookmarksOverlay.js | 7 +
content/treestyletab/bookmarksOverlayEditable.js | 3 +
content/treestyletab/content-utils.js | 55 +++
content/treestyletab/res/bookmarkMultipleTabs.xul | 7 +-
...kmarkMultipleTabs_bookmarkPropertiesOverlay.xul | 45 +-
content/treestyletab/res/tabsDragUtils.js | 55 ++-
content/treestyletab/treestyletab.css | 45 +-
content/treestyletab/treestyletab.js | 6 +
content/treestyletab/windowHelper.js | 546 +++++++++++----------
content/treestyletab/windowHelperHacks.js | 56 ++-
defaults/preferences/treestyletab.js | 12 +-
install.rdf | 4 +-
locale/en-US/treestyletab/treestyletab.dtd | 4 +-
modules/ReferenceCounter.js | 42 ++
modules/autoHide.js | 123 ++++-
modules/base.js | 47 +-
modules/browser.js | 484 +++++++++---------
modules/browserUIShowHideObserver.js | 134 +++--
modules/constants.js | 9 +-
modules/contentBridge.js | 21 +-
modules/fullTooltip.js | 2 +-
modules/fullscreenObserver.js | 21 +-
modules/groupTab.js | 2 +-
modules/lib/inherit.jsm | 2 +-
modules/pseudoTreeBuilder.js | 2 +-
modules/tabAttributesObserver.js | 2 +-
modules/tabbarDNDObserver.js | 150 ++++--
modules/tabpanelDNDObserver.js | 9 +-
modules/themeManager.js | 2 +-
modules/utils.js | 70 ++-
modules/window.js | 200 +++++---
skin/classic/treestyletab/Linux-base.css | 6 +
skin/classic/treestyletab/square/tab-surface.css | 4 +-
skin/classic/treestyletab/ui-base.css | 34 +-
37 files changed, 1477 insertions(+), 876 deletions(-)
diff --git a/META-INF/manifest.mf b/META-INF/manifest.mf
index 8cd9d38..2264eab 100644
--- a/META-INF/manifest.mf
+++ b/META-INF/manifest.mf
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
Name: install.rdf
Digest-Algorithms: MD5 SHA1
-MD5-Digest: XmdqNUkTM6QdwsQ5YvcjPw==
-SHA1-Digest: YAn17jTjifr/5uDzOWuTMkgbS24=
+MD5-Digest: LU9MOfmVFQKCFVg0AM159g==
+SHA1-Digest: BNsWVAkBeLoD+KiFzhm8uZhdrf0=
Name: chrome.manifest
Digest-Algorithms: MD5 SHA1
@@ -22,8 +22,8 @@ SHA1-Digest: XLM7zjvCkIi09SoAGOVOZdeQofY=
Name: content/treestyletab/bookmarksOverlay.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: a1UScbFacLdf3bGkQHgZVg==
-SHA1-Digest: akG9SMpPnjkZ2aci1msbsa34ymc=
+MD5-Digest: sLs6Xz86OV6NK6RJVHgEvA==
+SHA1-Digest: pmX3AWu0z9RzIeDgImy8NfP1UIA=
Name: content/treestyletab/bookmarksOverlay.xul
Digest-Algorithms: MD5 SHA1
@@ -37,8 +37,8 @@ SHA1-Digest: /V6d117O8c9Qgt7NoCuVRN2bOF0=
Name: content/treestyletab/bookmarksOverlayEditable.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 1OUCn+P21t3cQaO4Zjc3fw==
-SHA1-Digest: LMw7a9VHhMRD5D+gBKwYQBNQjWE=
+MD5-Digest: fz/WG9plX7+4mymO1k4eqg==
+SHA1-Digest: CBTSfQAfKiL/sT9YpY8vwW9Zml0=
Name: content/treestyletab/bookmarksOverlayEditable.xul
Digest-Algorithms: MD5 SHA1
@@ -65,6 +65,11 @@ Digest-Algorithms: MD5 SHA1
MD5-Digest: 5LerXpT+fFUV2k1YOWLOCw==
SHA1-Digest: UoiQ5kghSuZB2O1NOtmcO82G6ZY=
+Name: content/treestyletab/content-utils.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: u5TSTFqsmy3oW+pn6MvYGQ==
+SHA1-Digest: XPRa16z/xWO9CPGCemcNYgi2Lwk=
+
Name: content/treestyletab/group.xul
Digest-Algorithms: MD5 SHA1
MD5-Digest: 36AhehtnHOpGrElzTkAIzQ==
@@ -92,13 +97,13 @@ SHA1-Digest: dUnh9cVls70LC0cO+AzOTyJ+7Bc=
Name: content/treestyletab/treestyletab.css
Digest-Algorithms: MD5 SHA1
-MD5-Digest: ckNWCVVeVUwyAE8Ks4gRgA==
-SHA1-Digest: BmB3htcfoWnSKj7KE5BB7Cu9Sec=
+MD5-Digest: UIzT5sgWVHFZhuXzoCT9cQ==
+SHA1-Digest: eYWjBJvS12pO+j90U4BIpE9BDvo=
Name: content/treestyletab/treestyletab.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: ld2sTGlJa+As/xraL/CwOQ==
-SHA1-Digest: LA2MSt95ft6Mt7ufc53o/qq0oew=
+MD5-Digest: rAQdu8NF3MYvlInTA/rnZA==
+SHA1-Digest: mdGLj3IkGat9NH80/KPUwZIx3zc=
Name: content/treestyletab/treestyletab.xml
Digest-Algorithms: MD5 SHA1
@@ -112,24 +117,24 @@ SHA1-Digest: UL5BD1Q3QU5lrlyvVrvvYzxKzpM=
Name: content/treestyletab/windowHelper.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: jNbQDZNTag3AkbZ5qUfYmA==
-SHA1-Digest: C/mp3RdS4rQjkmrKZNS8X0Nly7I=
+MD5-Digest: djwD/HnGMfG+uyywHjuBnQ==
+SHA1-Digest: NIayIo0Ik7UxA9Gh2Kt/86y6tmI=
Name: content/treestyletab/windowHelperHacks.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: +s/LgIomma9/3/NXA4xK1Q==
-SHA1-Digest: rAB+c6L9HAPpCxWS5vcbvorWmNk=
+MD5-Digest: HU2bYPiXZtwNdiUbkepXhA==
+SHA1-Digest: RJmFgfQwbq0H5AO7AjH42biwkT4=
Name: content/treestyletab/res/bookmarkMultipleTabs.xul
Digest-Algorithms: MD5 SHA1
-MD5-Digest: BxexkR9ZJCUNcfDfbTeB+Q==
-SHA1-Digest: 60fRvXNQIxZszW6dVBK8RGi/StQ=
+MD5-Digest: iebNA+/X3W4H8iz0vn/JyQ==
+SHA1-Digest: SIpJbMdGhMrFhN3F1Bg6yykW/oQ=
Name: content/treestyletab/res/bookmarkMultipleTabs_bookmarkPropertiesOv
erlay.xul
Digest-Algorithms: MD5 SHA1
-MD5-Digest: hn+GVG2KuEdIcR6cd+cPVg==
-SHA1-Digest: zvKA9WdbSHU79zF+CwuH41FYeyU=
+MD5-Digest: hLKdeMp53y13zIADzK90pw==
+SHA1-Digest: egqUV8t6VkSTKSNKgj1ZC+yc3jQ=
Name: content/treestyletab/res/icon.png
Digest-Algorithms: MD5 SHA1
@@ -173,8 +178,8 @@ SHA1-Digest: WzGw9OlK27u2qgwpylJvL+GMB9k=
Name: content/treestyletab/res/tabsDragUtils.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: HiAUx9j5fAnkXeYyqQsnTQ==
-SHA1-Digest: GcN7PicYjUYq8jnq5FsdCfJXOvA=
+MD5-Digest: W9TDKDIlBGpERagCv9lS9A==
+SHA1-Digest: UDF3Oxyej6oju457n513VqAIt88=
Name: content/treestyletab/res/twisty-modern-b.png
Digest-Algorithms: MD5 SHA1
@@ -198,8 +203,8 @@ SHA1-Digest: q0mYa40sk7KoHzdmK6voR/OuGF8=
Name: defaults/preferences/treestyletab.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 9biMjtnraI40dhAz4IJYYg==
-SHA1-Digest: MkVnqunBxYKr7c8ZcQQ9B0CDcDA=
+MD5-Digest: AdO/+hHOi1b60QOLzwVY+g==
+SHA1-Digest: e+5nkclUxU2r/6DOyrc4Wp20/ww=
Name: locale/cs/treestyletab/license.txt
Digest-Algorithms: MD5 SHA1
@@ -253,8 +258,8 @@ SHA1-Digest: /vNGGzRR58QK5AOQjlorkE5GCAI=
Name: locale/en-US/treestyletab/treestyletab.dtd
Digest-Algorithms: MD5 SHA1
-MD5-Digest: ldc81dCNxvzqLjJSmCOTNg==
-SHA1-Digest: suzdF/d1DEkJBDpvaRjChgHD/Ew=
+MD5-Digest: zYzWcmQTBKdgXDyHSLHevQ==
+SHA1-Digest: H3VKEtaRrs9Jt9dPBpdZkTePgKg=
Name: locale/en-US/treestyletab/treestyletab.properties
Digest-Algorithms: MD5 SHA1
@@ -398,83 +403,88 @@ SHA1-Digest: 820CmLC9fE1O0AAZaeKrzW0ER0g=
Name: modules/autoHide.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: T9SAawe0+UOMjMQizNLHDA==
-SHA1-Digest: 8KQ0JqLSzHH1tOjz/1jwh62zwxk=
+MD5-Digest: B9zP89rDOYvQbfDt8Zzygg==
+SHA1-Digest: fEWPNjGv/wd+jegY4ae6NViute0=
Name: modules/base.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: q+mYhiRSG/v4AAbkIT4uCQ==
-SHA1-Digest: s804P4dgT5r0jnMU7tBb1JY85p8=
+MD5-Digest: SW7n5j5ulYqgVbALxDNHwg==
+SHA1-Digest: gshjveyfvCzlEasH+SJAVmhpduw=
Name: modules/browser.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 992iLJmymDwfBlCenFMYxw==
-SHA1-Digest: HNf1gNRzLl9m9aWjpv6BUf8sOFk=
+MD5-Digest: Qsm9orLKQiwwI3wFGdgR5w==
+SHA1-Digest: lFCgOlN5J5AkJiLLgtWlAJLKKdI=
Name: modules/browserUIShowHideObserver.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 8MSAEZpP7EhsHmIXnjzG7g==
-SHA1-Digest: M3SCb58qeNORSPot1UHe63vyftM=
+MD5-Digest: 1jGa2nmHU/8r438jcy8bxA==
+SHA1-Digest: 0ye5nfvkIj6pI35yGQAEL7xtJ+k=
Name: modules/constants.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 6mbfJ7B8IX8ScrJgjSBh4g==
-SHA1-Digest: LekJDB7P9PtP/J5a+8+FANZtikM=
+MD5-Digest: bXcNFYoNHgH7Ut8DERrw9w==
+SHA1-Digest: YJ98EXt4ZUC8A9NCHjbj3fOUF6M=
Name: modules/contentBridge.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: AZB2jQAnxsjypV1umhfEBw==
-SHA1-Digest: HFsqlRnRFb+hIdV7G5+MG3R0QUI=
+MD5-Digest: 8EkTrdJ8nAxYO+81/mRYig==
+SHA1-Digest: PjTvEP1WjiDk/FgiOz5XVHKr/+E=
Name: modules/fullscreenObserver.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: mf/V54u6CtD6V2RFW/WF0Q==
-SHA1-Digest: v6+507G5urrawGK8lQh8JRdrcPo=
+MD5-Digest: dA4uF/PyD4eIAjQaZ1RIIQ==
+SHA1-Digest: ENKlU1ETpeEMx47y4xvTsSltvtw=
Name: modules/fullTooltip.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: ShAuksj5Si0Sb0kEe1NwrQ==
-SHA1-Digest: 4DKc57PO/dO2V3oo0aNBOu7Dfkk=
+MD5-Digest: OTHa0q1gsOZFgz5uOQOE0Q==
+SHA1-Digest: SAU4UbMLDt9SVI9lrj/dfSoXe4k=
Name: modules/groupTab.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: GdIHZgj3aQMqHtvRhbjv1w==
-SHA1-Digest: LhC5EqN9up0tyG7mzsxUD6ZxxUA=
+MD5-Digest: NL5i97YRH+b+XpG22i8tIA==
+SHA1-Digest: qefrneMChMj4kmaCaq19QCg/BqM=
Name: modules/pseudoTreeBuilder.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 4q0nQ4CIjqaKtkWM3aHsZQ==
-SHA1-Digest: FzFEKrsUgN3ctHxnapuDMhdRXUQ=
+MD5-Digest: KsauIXOH18MRG4mEplXZfw==
+SHA1-Digest: 7EaG3t5WJWOobr8LTS9nX/ulAoI=
+
+Name: modules/ReferenceCounter.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: /+GL3pEvh8yXhOLV1KTL0g==
+SHA1-Digest: KwYUQNA0W5ensPrOgCQeR2NRGm4=
Name: modules/tabAttributesObserver.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: V2bHwKcnECwSU9tiBq6oMA==
-SHA1-Digest: s0dTBYAbHaHJl1qosnFeq09v3wE=
+MD5-Digest: ASIvZ3RBvp7ujNIxUhHjhA==
+SHA1-Digest: E3qycu7EJPrhOGIYeCcsiHlDq/A=
Name: modules/tabbarDNDObserver.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: uFs6iCDzp8ZlGMTsVMHM0Q==
-SHA1-Digest: JK+000vzvtosIaUhtvOl+yE5d2Y=
+MD5-Digest: Af1MrXXUChYdrEcE83+ljA==
+SHA1-Digest: jzjPtaYbneiJQrIL86DEi8H0qCQ=
Name: modules/tabpanelDNDObserver.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: D2vLeI9JjyTH0dxUd3YjWw==
-SHA1-Digest: Ev0jhVn62wkkjNSOO5QHtGKBWXU=
+MD5-Digest: viIk0SD+R9Tc1k0cMgf98g==
+SHA1-Digest: NGDF4zuUWe9dhiX73LMiqEKgBnk=
Name: modules/themeManager.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: AtFiQr5iJ7aRAIpw3ISe2w==
-SHA1-Digest: qxskOiLU34Yfh6Gxp/2rBD06gIQ=
+MD5-Digest: LKIpjU4H0S4zStz+u9J2FQ==
+SHA1-Digest: QRODHmwaRkX+b/zrhPVckxz7kf4=
Name: modules/utils.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: zZ/+U7Sd8RvruD0Mknpl8A==
-SHA1-Digest: sdflsWuengne5M5scHCKGQ2KIWE=
+MD5-Digest: Evsu0Jey/gxHQtysi3qW9w==
+SHA1-Digest: z+FPUT6tjjGfA52pyzkH0LPYwB0=
Name: modules/window.js
Digest-Algorithms: MD5 SHA1
-MD5-Digest: wxooRnHV0nCp3Bn7DQbN8g==
-SHA1-Digest: CiPCoI2sXL0Yt2kswj/w45/MU38=
+MD5-Digest: wYWu/aoxc/N0JO1GpDROKg==
+SHA1-Digest: 1UMTBrQ27VOYeSz+Lzk2iDFJiuQ=
Name: modules/lib/animationManager.js
Digest-Algorithms: MD5 SHA1
@@ -498,8 +508,8 @@ SHA1-Digest: 3IbYcqoRV/tpDPKB+iE5Y9iCjCo=
Name: modules/lib/inherit.jsm
Digest-Algorithms: MD5 SHA1
-MD5-Digest: SESkSedzqkncyLXHABiaog==
-SHA1-Digest: NqtEgb7S1xm1jXEOznskOfZk/Sk=
+MD5-Digest: 5KlF2H6R+m4TNbqEUCxnag==
+SHA1-Digest: YS9YH8+s/xXoCob9P2p2s2DUouQ=
Name: modules/lib/namespace.jsm
Digest-Algorithms: MD5 SHA1
@@ -573,8 +583,8 @@ SHA1-Digest: SkZhMKbeatV48RFx9AROoyuLalc=
Name: skin/classic/treestyletab/Linux-base.css
Digest-Algorithms: MD5 SHA1
-MD5-Digest: qcqsCQR2mdKUIuZFf9EEgA==
-SHA1-Digest: aQmL/lqslBMfWjHLumKMmUERwjo=
+MD5-Digest: jObYHMsAFuzN/olmy/FK4g==
+SHA1-Digest: IwwSyHMrakvDNVtGXz/itt/OdCQ=
Name: skin/classic/treestyletab/Linux-config.css
Digest-Algorithms: MD5 SHA1
@@ -603,8 +613,8 @@ SHA1-Digest: /CcGFdIzQT8ebf8twW9s6P1rRRI=
Name: skin/classic/treestyletab/ui-base.css
Digest-Algorithms: MD5 SHA1
-MD5-Digest: 5G3HB6CjHahNZTUpbtJsOQ==
-SHA1-Digest: jipVd7r7T1LUwqdguo6WxjwTdkY=
+MD5-Digest: f7hWW6ka4HhJp2x4iDlIrw==
+SHA1-Digest: SBpgkKqiRMt63i0rHc+TUMJoo1o=
Name: skin/classic/treestyletab/WINNT-base.css
Digest-Algorithms: MD5 SHA1
@@ -788,8 +798,8 @@ SHA1-Digest: CTg4j0P/755VUethbwqkLbDrXcI=
Name: skin/classic/treestyletab/square/tab-surface.css
Digest-Algorithms: MD5 SHA1
-MD5-Digest: py4qLMM7RcXH+RwIHJE/Xw==
-SHA1-Digest: Ei6AJVrIrnKAL/qew2jLvNgXjWw=
+MD5-Digest: 09Z32P8AYKbhVLtelLGY8A==
+SHA1-Digest: uJCYdd6cnRl0V0Vt+sFUFWmD4oE=
Name: skin/classic/treestyletab/square/vertigo.css
Digest-Algorithms: MD5 SHA1
diff --git a/META-INF/mozilla.rsa b/META-INF/mozilla.rsa
index 3602901..3f13926 100644
Binary files a/META-INF/mozilla.rsa and b/META-INF/mozilla.rsa differ
diff --git a/META-INF/mozilla.sf b/META-INF/mozilla.sf
index 77eea90..6f46475 100644
--- a/META-INF/mozilla.sf
+++ b/META-INF/mozilla.sf
@@ -1,4 +1,4 @@
Signature-Version: 1.0
-MD5-Digest-Manifest: b7fHst3iS1XpUeOAFDG0UA==
-SHA1-Digest-Manifest: icaPq7Iu/pZ1EMF/GPzMkCbIWFc=
+MD5-Digest-Manifest: qqshu9SyS0COjRVzsZbRkw==
+SHA1-Digest-Manifest: /jRGtjTb2V8ydEzI2MuaANhRgMg=
diff --git a/content/treestyletab/bookmarksOverlay.js b/content/treestyletab/bookmarksOverlay.js
index 1270725..91e51d0 100644
--- a/content/treestyletab/bookmarksOverlay.js
+++ b/content/treestyletab/bookmarksOverlay.js
@@ -3,6 +3,7 @@ XPCOMUtils.defineLazyModuleGetter(this,
'TreeStyleTabUtils', 'resource://treestyletab-modules/utils.js');
(function() {
+let { ReferenceCounter } = Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js', {});
let { inherit } = Components.utils.import('resource://treestyletab-modules/lib/inherit.jsm', {});
var TreeStyleTabBookmarksService = inherit(TreeStyleTabService, {
@@ -218,13 +219,17 @@ var TreeStyleTabBookmarksService = inherit(TreeStyleTabService, {
preInit : function TSTBMService_preInit()
{
window.addEventListener('load', this, false);
+ ReferenceCounter.add('window,load,TSTBMService,false');
window.addEventListener(window['piro.sakura.ne.jp'].tabsDragUtils.EVENT_TYPE_TABS_DROP, this, false);
+ ReferenceCounter.add('window,EVENT_TYPE_TABS_DROP,TSTBMService,false');
},
init : function TSTBMService_init()
{
window.removeEventListener('load', this, false);
+ ReferenceCounter.remove('window,load,TSTBMService,false');
window.addEventListener('unload', this, false);
+ ReferenceCounter.add('window,unload,TSTBMService,false');
if (!('PlacesUIUtils' in window)) return;
@@ -473,7 +478,9 @@ var TreeStyleTabBookmarksService = inherit(TreeStyleTabService, {
destroy : function TSTBMService_destroy()
{
window.removeEventListener('unload', this, false);
+ ReferenceCounter.remove('window,unload,TSTBMService,false');
window.removeEventListener(window['piro.sakura.ne.jp'].tabsDragUtils.EVENT_TYPE_TABS_DROP, this, false);
+ ReferenceCounter.remove('window,EVENT_TYPE_TABS_DROP,TSTBMService,false');
},
// observer for nsINavBookmarksService
diff --git a/content/treestyletab/bookmarksOverlayEditable.js b/content/treestyletab/bookmarksOverlayEditable.js
index 8bf57d7..c529c3f 100644
--- a/content/treestyletab/bookmarksOverlayEditable.js
+++ b/content/treestyletab/bookmarksOverlayEditable.js
@@ -3,6 +3,7 @@ XPCOMUtils.defineLazyModuleGetter(this,
'TreeStyleTabUtils', 'resource://treestyletab-modules/utils.js');
(function() {
+let { ReferenceCounter } = Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js', {});
let { inherit } = Components.utils.import('resource://treestyletab-modules/lib/inherit.jsm', {});
var TreeStyleTabBookmarksServiceEditable = inherit(TreeStyleTabBookmarksService, {
@@ -386,6 +387,7 @@ var TreeStyleTabBookmarksServiceEditable = inherit(TreeStyleTabBookmarksService,
{
case 'DOMContentLoaded':
window.removeEventListener('DOMContentLoaded', this, false);
+ ReferenceCounter.remove('window,DOMContentLoaded,TreeStyleTabBookmarksServiceEditable,false');
this.init();
break;
}
@@ -394,6 +396,7 @@ var TreeStyleTabBookmarksServiceEditable = inherit(TreeStyleTabBookmarksService,
});
window.addEventListener('DOMContentLoaded', TreeStyleTabBookmarksServiceEditable, false);
+ReferenceCounter.add('window,DOMContentLoaded,TreeStyleTabBookmarksServiceEditable,false');
window.TreeStyleTabBookmarksServiceEditable = TreeStyleTabBookmarksServiceEditable;
})();
diff --git a/content/treestyletab/content-utils.js b/content/treestyletab/content-utils.js
new file mode 100644
index 0000000..511af1d
--- /dev/null
+++ b/content/treestyletab/content-utils.js
@@ -0,0 +1,55 @@
+(function(global) {
+ var DEBUG = false;
+ function mydump(aMessage) {
+ if (DEBUG)
+ dump('treestyletab(general) content utils: '+aMessage +'\n');
+ }
+ mydump('CONTENT SCRIPT LOADED <'+global.content.location+'>');
+
+ var Cc = Components.classes;
+ var Ci = Components.interfaces;
+ var Cu = Components.utils;
+ var Cr = Components.results;
+
+ var { TreeStyleTabConstants } = Cu.import('resource://treestyletab-modules/constants.js', {});
+
+ function free() {
+ cleanup =
+ Cc = Ci = Cu = Cr =
+ TreeStyleTabConstants =
+ messageListener =
+ handleEvent =
+ mydump =
+ undefined;
+ }
+
+ var messageListener = function(aMessage) {
+ mydump('CONTENT MESSAGE LISTENED <'+(global.content && global.content.location)+'>');
+ mydump(JSON.stringify(aMessage.json));
+ switch (aMessage.json.command)
+ {
+ case TreeStyleTabConstants.COMMAND_SHUTDOWN:
+ global.removeMessageListener(TreeStyleTabConstants.MESSAGE_TYPE, messageListener);
+ global.removeEventListener('selectionchange', handleEvent, true);
+ free();
+ return;
+ }
+ };
+ global.addMessageListener(TreeStyleTabConstants.MESSAGE_TYPE, messageListener);
+
+ function handleEvent(aEvent) {
+ switch (aEvent.type)
+ {
+ case 'selectionchange':
+ if (!aEvent.target ||
+ !aEvent.target.getSelection)
+ return;
+ global.sendAsyncMessage(TreeStyleTabConstants.MESSAGE_TYPE, {
+ command : TreeStyleTabConstants.COMMAND_REPORT_SELECTION_CHANGE,
+ text : aEvent.target.getSelection().toString()
+ });
+ return;
+ }
+ }
+ global.addEventListener('selectionchange', handleEvent, true);
+})(this);
diff --git a/content/treestyletab/res/bookmarkMultipleTabs.xul b/content/treestyletab/res/bookmarkMultipleTabs.xul
index d282cf0..775791a 100644
--- a/content/treestyletab/res/bookmarkMultipleTabs.xul
+++ b/content/treestyletab/res/bookmarkMultipleTabs.xul
@@ -14,7 +14,7 @@
in JS files:
window['piro.sakura.ne.jp'].bookmarkMultipleTabs.addBookmarkFor(tabsArray, folderName);
- license: The MIT License, Copyright (c) 2009-2012 YUKI "Piro" Hiroshi
+ license: The MIT License, Copyright (c) 2009-2015 YUKI "Piro" Hiroshi
original:
http://github.com/piroor/fxaddonlib-bookmark-multiple-tabs
-->
@@ -24,7 +24,7 @@
window.addEventListener('DOMContentLoaded', function() {
window.removeEventListener('DOMContentLoaded', arguments.callee, true);
- const currentRevision = 5;
+ const currentRevision = 8;
if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
@@ -72,9 +72,6 @@ window.addEventListener('DOMContentLoaded', function() {
hiddenRows : ['description', 'location', 'loadInSidebar', 'keyword']
}, window);
}
- else if ('showMinimalAddMultiBookmarkUI' in utils) { // Firefox 3 - 8
- utils.showMinimalAddMultiBookmarkUI(tabs);
- }
else {
throw new Error('there is no method to create bookmarks from tabs!');
}
diff --git a/content/treestyletab/res/bookmarkMultipleTabs_bookmarkPropertiesOverlay.xul b/content/treestyletab/res/bookmarkMultipleTabs_bookmarkPropertiesOverlay.xul
index beb26b6..23e0488 100644
--- a/content/treestyletab/res/bookmarkMultipleTabs_bookmarkPropertiesOverlay.xul
+++ b/content/treestyletab/res/bookmarkMultipleTabs_bookmarkPropertiesOverlay.xul
@@ -14,7 +14,7 @@
in JS files:
window['piro.sakura.ne.jp'].bookmarkMultipleTabs.addBookmarkFor(tabsArray, folderName);
- license: The MIT License, Copyright (c) 2009-2012 YUKI "Piro" Hiroshi
+ license: The MIT License, Copyright (c) 2009-2015 YUKI "Piro" Hiroshi
http://github.com/piroor/fxaddonlibs/blob/master/license.txt
original:
http://github.com/piroor/fxaddonlibs/blob/master/bookmarkMultipleTabs.xul
@@ -28,23 +28,32 @@
BookmarkPropertiesPanel._determineItemInfo.toSource().indexOf('__folderNameOverride') > -1)
return;
- eval('BookmarkPropertiesPanel._determineItemInfo = '+BookmarkPropertiesPanel._determineItemInfo.toSource().replace(
- '{',
- ['{',
- 'var __folderNameOverride = null;',
- 'try {',
- ' __folderNameOverride = Components.classes["@mozilla.org/preferences;1"]',
- ' .getService(Components.interfaces.nsIPrefBranch)',
- ' .getCharPref("temp.showMinimalAddMultiBookmarkUI.folderName");',
- ' __folderNameOverride = decodeURIComponent(escape(__folderNameOverride));',
- '}',
- 'catch(e) {',
- '}'
- ].join('')
- ).replace(
- 'this._strings.getString("bookmarkAllTabsDefault")',
- '__folderNameOverride || $&'
- ));
+ // Defined at http://mxr.mozilla.org/mozilla-central/source/browser/components/places/content/bookmarkProperties.js#73
+ const ACTION_ADD = 1;
+
+ BookmarkPropertiesPanel.__treestyletab__determineItemInfo = BookmarkPropertiesPanel._determineItemInfo;
+ BookmarkPropertiesPanel._determineItemInfo = function(...aArgs) {
+ var folderNameOverride = null;
+ try {
+ folderNameOverride = Components.classes['@mozilla.org/preferences;1']
+ .getService(Components.interfaces.nsIPrefBranch)
+ .getCharPref('temp.showMinimalAddMultiBookmarkUI.folderName');
+ folderNameOverride = decodeURIComponent(escape(folderNameOverride));
+ }
+ catch(e) {
+ }
+ var retVal = this.__treestyletab__determineItemInfo.apply(this, aArgs);
+ if (folderNameOverride &&
+ this._action == ACTION_ADD) {
+ let dialogInfo = window.arguments[0];
+ if (dialogInfo.type === 'folder' &&
+ !('title' in dialogInfo) &&
+ 'URIList' in dialogInfo) {
+ this._title = folderNameOverride;
+ }
+ }
+ return retVal;
+ };
})();
]]></script>
</overlay>
diff --git a/content/treestyletab/res/tabsDragUtils.js b/content/treestyletab/res/tabsDragUtils.js
index 7debcdd..a3ea13d 100644
--- a/content/treestyletab/res/tabsDragUtils.js
+++ b/content/treestyletab/res/tabsDragUtils.js
@@ -15,7 +15,7 @@
http://github.com/piroor/fxaddonlib-tabs-drag-utils
*/
(function() {
- const currentRevision = 33;
+ const currentRevision = 35;
if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
@@ -54,12 +54,12 @@
getRestoringData: function(aTab)
{
var data = aTab.linkedBrowser.__SS_data;
- if (!data && this.RestoringTabsData) // Firefox 23-
- data = this.RestoringTabsData.get(aTab.linkedBrowser);
+ if (!data && this.TabStateCache) // Firefox 23-
+ data = this.TabStateCache.get(aTab.linkedBrowser);
return data;
},
- get TabRestoreStates() {
- return this.SessionStoreNS.TabRestoreStates;
+ get TabStateCache() {
+ return this.SessionStoreNS.TabStateCache;
},
get SessionStoreNS() {
delete this.SessionStoreNS;
@@ -159,17 +159,32 @@
{
this.updatedTabDNDObservers.push(aObserver);
- if ('_setEffectAllowedForDataTransfer' in aObserver &&
- aObserver._setEffectAllowedForDataTransfer.toSource().indexOf('tabsDragUtils') < 0) {
- let original = aObserver._setEffectAllowedForDataTransfer;
- aObserver.__TabsDragUtils_original__setEffectAllowedForDataTransfer = original;
- eval('aObserver._setEffectAllowedForDataTransfer = '+
- original.toSource().replace(
- 'dt.mozItemCount > 1',
- '$& && !window["piro.sakura.ne.jp"].tabsDragUtils.isTabsDragging(arguments[0])'
- )
- );
- aObserver.__TabsDragUtils_updated__setEffectAllowedForDataTransfer = aObserver._setEffectAllowedForDataTransfer;
+ if (typeof aObserver._setEffectAllowedForDataTransfer === 'function') { // Firefox 43 and older
+ if (aObserver._setEffectAllowedForDataTransfer.toSource().indexOf('tabsDragUtils') < 0) {
+ let original = aObserver._setEffectAllowedForDataTransfer;
+ aObserver.__TabsDragUtils_original__setEffectAllowedForDataTransfer = original;
+ eval('aObserver._setEffectAllowedForDataTransfer = '+
+ original.toSource().replace(
+ 'dt.mozItemCount > 1',
+ '$& && !window["piro.sakura.ne.jp"].tabsDragUtils.isTabsDragging(arguments[0])'
+ )
+ );
+ aObserver.__TabsDragUtils_updated__setEffectAllowedForDataTransfer = aObserver._setEffectAllowedForDataTransfer;
+ }
+ }
+ else { // Firefox 44 and later
+ if (typeof aObserver._getDropEffectForTabDrag === 'function' &&
+ aObserver._getDropEffectForTabDrag.toSource().indexOf('tabsDragUtils') < 0) {
+ let original = aObserver._getDropEffectForTabDrag;
+ aObserver.__TabsDragUtils_original__getDropEffectForTabDrag = original;
+ eval('aObserver._getDropEffectForTabDrag = '+
+ original.toSource().replace(
+ 'dt.mozItemCount > 1',
+ '$& && !window["piro.sakura.ne.jp"].tabsDragUtils.isTabsDragging(arguments[0])'
+ )
+ );
+ aObserver.__TabsDragUtils_updated__getDropEffectForTabDrag = aObserver._getDropEffectForTabDrag;
+ }
}
if ('_animateTabMove' in aObserver &&
@@ -573,6 +588,11 @@
if (!aObserver)
return;
+ if (aObserver._getDropEffectForTabDrag == aObserver.__TabsDragUtils_updated__getDropEffectForTabDrag)
+ aObserver._getDropEffectForTabDrag = aObserver.__TabsDragUtils_original__getDropEffectForTabDrag;
+ delete aObserver.__TabsDragUtils_original__getDropEffectForTabDrag;
+ delete aObserver.__TabsDragUtils_updated__getDropEffectForTabDrag;
+
if (aObserver._setEffectAllowedForDataTransfer == aObserver.__TabsDragUtils_updated__setEffectAllowedForDataTransfer)
aObserver._setEffectAllowedForDataTransfer = aObserver.__TabsDragUtils_original__setEffectAllowedForDataTransfer;
delete aObserver.__TabsDragUtils_original__setEffectAllowedForDataTransfer;
@@ -839,7 +859,8 @@
{
if (this.isTabNeedToBeRestored(aTab)) {
let data = this.getRestoringData(aTab);
- let entry = data.entries[Math.min(data.index, data.entries.length-1)];
+ let history = data.history;
+ let entry = history.entries[Math.min(history.index, history.entries.length-1)];
if (entry) return entry.url;
}
return aTab.linkedBrowser.currentURI.spec;
diff --git a/content/treestyletab/treestyletab.css b/content/treestyletab/treestyletab.css
index dc353f0..81c14f5 100644
--- a/content/treestyletab/treestyletab.css
+++ b/content/treestyletab/treestyletab.css
@@ -77,16 +77,25 @@
/* tab bar in the DOM-fullscreen mode */
-.tabbrowser-tabs[treestyletab-dom-fullscreen-activated="true"],
-.tabbrowser-strip[treestyletab-dom-fullscreen-activated="true"],
-.tabbrowser-strip[treestyletab-dom-fullscreen-activated="true"]+splitter,
-.treestyletab-tabbar-toolbar[treestyletab-dom-fullscreen-activated="true"],
-.treestyletab-tabbar-toolbar[treestyletab-dom-fullscreen-activated="true"] > *,
-tabbrowser[treestyletab-dom-fullscreen-activated-mode="true"][tabcontainer]
+:root[inDOMFullscreen="true"]
+ .tabbrowser-tabs,
+:root[inDOMFullscreen="true"]
+ .tabbrowser-strip,
+:root[inDOMFullscreen="true"]
+ .tabbrowser-strip+splitter,
+:root[inDOMFullscreen="true"]
+ .treestyletab-tabbar-toolbar,
+:root[inDOMFullscreen="true"]
+ .treestyletab-tabbar-toolbar > *,
+:root[inDOMFullscreen="true"]
+ tabbrowser[tabcontainer]
.tabbrowser-strip.treestyletab-tabbar-placeholder,
-tabbrowser[treestyletab-dom-fullscreen-activated-mode="true"][tabcontainer]
- .tabbrowser-strip.treestyletab-tabbar-placeholder+splitter {
- visibility: collapse;
+:root[inDOMFullscreen="true"]
+ tabbrowser[tabcontainer]
+ .tabbrowser-strip.treestyletab-tabbar-placeholder+splitter,
+:root[inDOMFullscreen="true"]
+ .treestyletab-tabbar-toggler {
+ visibility: collapse !important;
}
@@ -282,7 +291,7 @@ tabs.tabbrowser-tabs[treestyletab-tabbar-position="left"][treestyletab-invert-sc
* Normal selectors in default theme is stronger than :-moz-any() even if
* it includes #TabsToolbar in its subqueries.
*/
- at media all and (-moz-windows-compositor) { /* for winstripe */
+ at media all and (-moz-windows-compositor) { /* for winstripe: Windows */
#navigator-toolbox
> .treestyletab-tabbar-toolbar:not(#toolbar-menubar),
#navigator-toolbox
@@ -378,12 +387,12 @@ tabs.tabbrowser-tabs[treestyletab-tabbar-position="left"][treestyletab-invert-sc
}
.treestyletab-tabbar-toolbar,
.treestyletab-tabbar-toolbar-ready,
-/* for gnomestripe */
+/* for gnomestripe: Linux */
#TabsToolbar.treestyletab-tabbar-toolbar:not([autohide="true"]):not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
#TabsToolbar.treestyletab-tabbar-toolbar:not([autohide="true"])[tabsontop="true"]:not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
#TabsToolbar.treestyletab-tabbar-toolbar-ready:not([autohide="true"]):not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
#TabsToolbar.treestyletab-tabbar-toolbar-ready:not([autohide="true"])[tabsontop="true"]:not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
-/* for pinstripe */
+/* for pinstripe: OS X */
toolbar.treestyletab-tabbar-toolbar:not([nowindowdrag="true"]),
toolbar.treestyletab-tabbar-toolbar-ready:not([nowindowdrag="true"]),
/* Hide Caption Titlebar Plus (Smart)
@@ -595,9 +604,17 @@ toolbar.treestyletab-tabbar-toolbar-ready:not([nowindowdrag="true"]),
/* width: 24px; */
z-index: 100;
}
+*[collapsed="true"]
+ .tabbrowser-tabs[treestyletab-mode="vertical"]
+ .tabbrowser-tab[pinned],
+*[collapsed="true"]
+ .tabbrowser-tabs[treestyletab-mode="vertical"]
+ .tabbrowser-tab[pinned] * /* this is required to hide unexpectedly shown gray rect (ex. .tab-background) */,
.tabbrowser-tabs[treestyletab-mode="vertical"][treestyletab-dom-fullscreen-activated="true"]
- .tabbrowser-tab[pinned] {
- z-index: -100;
+ .tabbrowser-tab[pinned],
+.tabbrowser-tabs[treestyletab-mode="vertical"][treestyletab-dom-fullscreen-activated="true"]
+ .tabbrowser-tab[pinned] * /* this is required to hide unexpectedly shown gray rect (ex. .tab-background) */ {
+ visibility: collapse;
}
.tabbrowser-tabs[treestyletab-mode="vertical"]
diff --git a/content/treestyletab/treestyletab.js b/content/treestyletab/treestyletab.js
index cd47d71..4b63e06 100644
--- a/content/treestyletab/treestyletab.js
+++ b/content/treestyletab/treestyletab.js
@@ -1,21 +1,27 @@
(function() {
+ let { ReferenceCounter } = Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js', {});
/**
* On secondary (and later) window, SSWindowStateBusy event can be fired
* before DOMContentLoaded, on "domwindowopened".
*/
var SSWindowStateBusyListener = function TSTSSWindowStateBusyListener(aEvent) {
window.removeEventListener(aEvent.type, TSTSSWindowStateBusyListener, false);
+ ReferenceCounter.remove('window,aEvent.type,TSTSSWindowStateBusyListener,false');
window.__treestyletab__WindowStateBusy = true;
SSWindowStateBusyListener = undefined;
};
window.addEventListener('SSWindowStateBusy', SSWindowStateBusyListener, false);
+ ReferenceCounter.add('window,SSWindowStateBusy,SSWindowStateBusyListener,false');
window.addEventListener('DOMContentLoaded', function onDOMContentLoaded(aEvent) {
window.removeEventListener(aEvent.type, onDOMContentLoaded, false);
+ ReferenceCounter.remove('window,aEvent.type,onDOMContentLoaded,false');
if (SSWindowStateBusyListener) {
window.removeEventListener('SSWindowStateBusy', SSWindowStateBusyListener, false);
+ ReferenceCounter.remove('window,SSWindowStateBusy,SSWindowStateBusyListener,false');
SSWindowStateBusyListener = undefined;
}
}, false);
+ ReferenceCounter.add('window,aEvent.type,onDOMContentLoaded,false');
var ns = {};
Components.utils.import('resource://treestyletab-modules/window.js', ns);
diff --git a/content/treestyletab/windowHelper.js b/content/treestyletab/windowHelper.js
index 9ece3be..0537e3b 100644
--- a/content/treestyletab/windowHelper.js
+++ b/content/treestyletab/windowHelper.js
@@ -3,6 +3,7 @@ XPCOMUtils.defineLazyModuleGetter(this,
'TreeStyleTabUtils', 'resource://treestyletab-modules/utils.js');
var TreeStyleTabWindowHelper = {
+ runningDelayedStartup : false,
get service()
{
@@ -11,43 +12,35 @@ var TreeStyleTabWindowHelper = {
preInit : function TSTWH_preInit()
{
- TreeStyleTabUtils.doPatching(gBrowserInit._delayedStartup, 'gBrowserInit._delayedStartup', function(aName, aSource) {
- if (aSource.indexOf('!MultipleTabService.tearOffSelectedTabsFromRemote()') > -1) {
- return eval(aName+' = '+aSource.replace(
- '!MultipleTabService.tearOffSelectedTabsFromRemote()',
- '!TreeStyleTabService.tearOffSubtreeFromRemote() && $&'
- ));
- }
- else if (aSource.indexOf('gBrowser.swapBrowsersAndCloseOther') > -1) {
- return eval(aName+' = '+aSource.replace(
- /gBrowser\.swapBrowsersAndCloseOther\([^)]+\);/g,
- 'if (!TreeStyleTabService.tearOffSubtreeFromRemote()) { $& }'
- ).replace(
- // Workaround for https://github.com/piroor/treestyletab/issues/741
- // After the function is updated by TST, reassignment of a global variable raises an error like:
- // > System JS : ERROR chrome://treestyletab/content/windowHelper.js line 30 > eval:130 - TypeError: can't redefine non-configurable property 'gBidiUI'
- // If I access it as a property of the global object, the error doesn't appear.
- /([^\.])\bgBidiUI =/,
- '$1window.gBidiUI ='
- ));
+ gBrowserInit.__treestyletab___delayedStartup = gBrowserInit._delayedStartup;
+ gBrowserInit._delayedStartup = function(...args) {
+ TreeStyleTabWindowHelper.runningDelayedStartup = true;
+ var retVal = this.__treestyletab___delayedStartup.apply(this, args);
+ TreeStyleTabWindowHelper.runningDelayedStartup = false;
+ return retVal;
+ };
+
+ nsBrowserAccess.prototype.__treestyletab__openURI = nsBrowserAccess.prototype.openURI;
+ nsBrowserAccess.prototype.openURI = function(aURI, aOpener, aWhere, aContext) {
+ var where = aWhere;
+ if (where === Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
+ let isExternal = aContext === Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL;
+ let overridePref = TreeStyleTabUtils.prefs.getPref('browser.link.open_newwindow.override.external');
+ if (isExternal && overridePref !== null)
+ where = overridePref;
+ else
+ where = TreeStyleTabUtils.prefs.getPref('browser.link.open_newwindow');
}
- }, 'TreeStyleTab');
-
- TreeStyleTabUtils.doPatching(nsBrowserAccess.prototype.openURI, 'nsBrowserAccess.prototype.openURI', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- /(switch\s*\(aWhere\))/,
- 'TreeStyleTabService.onBeforeBrowserAccessOpenURI(aOpener, aWhere, aContext); $1'
- ));
- }, 'TreeStyleTab');
+ TreeStyleTabService.onBeforeBrowserAccessOpenURI(aOpener, where, aContext);
+ return this.__treestyletab__openURI.call(this, aURI, aOpener, aWhere, aContext);
+ };
- TreeStyleTabUtils.doPatching(nsBrowserAccess.prototype.openURIInFrame, 'nsBrowserAccess.prototype.openURIInFrame', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'let browser = ',
- // Use "arguments[1]" instead of "aOwner" or "aParams".
- // The argument name is changed from "aOwner" to "aParams" by https://bugzilla.mozilla.org/show_bug.cgi?id=1058116
- 'TreeStyleTabService.onBeforeBrowserAccessOpenURI(arguments[1], aWhere, aContext); $&'
- ));
- }, 'TreeStyleTab');
+ nsBrowserAccess.prototype.__treestyletab__openURIInFrame = nsBrowserAccess.prototype.openURIInFrame;
+ nsBrowserAccess.prototype.openURIInFrame = function(aURI, aParams, aWhere, aContext) {
+ if (aWhere === Ci.nsIBrowserDOMWindow.OPEN_NEWTAB)
+ TreeStyleTabService.onBeforeBrowserAccessOpenURI(aParams, aWhere, aContext);
+ return this.__treestyletab__openURIInFrame.call(this, aURI, aParams, aWhere, aContext);
+ };
if ('TabsInTitlebar' in window) {
TreeStyleTabUtils.doPatching(TabsInTitlebar._update, 'TabsInTitlebar._update', function(aName, aSource) {
@@ -58,29 +51,23 @@ var TreeStyleTabWindowHelper = {
}, 'treeStyleTab');
}
- TreeStyleTabUtils.doPatching(window.BrowserOpenTab, 'window.BrowserOpenTab', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'openUILinkIn(',
- 'gBrowser.treeStyleTab.onBeforeNewTabCommand(); $&'
- ));
- }, 'treeStyleTab');
-
- TreeStyleTabUtils.doPatching(window.undoCloseTab, 'window.undoCloseTab', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- /(\btab\s*=\s*[^\.]+\.undoCloseTab\([^;]+\);)/,
- 'gBrowser.__treestyletab__doingUndoCloseTab = true;\n' +
- '$1\n' +
- 'tab.__treestyletab__restoredByUndoCloseTab = true;\n' +
- 'setTimeout(function() { delete gBrowser.__treestyletab__doingUndoCloseTab; }, 0);'
- ));
- }, 'treestyletab');
-
- TreeStyleTabUtils.doPatching(window.XULBrowserWindow.hideChromeForLocation, 'XULBrowserWindow.hideChromeForLocation', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{ if (gBrowser.treeStyleTab.isVertical) return false;\n'
- ));
- }, 'treeStyleTab');
+ window.__treestyletab__BrowserOpenTab = window.BrowserOpenTab;
+ window.BrowserOpenTab = function(...aArgs) {
+ gBrowser.treeStyleTab.onBeforeNewTabCommand();
+ return this.__treestyletab__BrowserOpenTab.apply(this, aArgs);
+ };
+
+ window.__treestyletab__undoCloseTab = window.undoCloseTab;
+ window.undoCloseTab = function(...aArgs) {
+ gBrowser.__treestyletab__doingUndoCloseTab = true;
+ var tab = this.__treestyletab__undoCloseTab.apply(this, aArgs);
+ if (tab)
+ tab.__treestyletab__restoredByUndoCloseTab = true;
+ setTimeout(function() {
+ delete gBrowser.__treestyletab__doingUndoCloseTab;
+ }, 0);
+ return tab;
+ };
[
'window.duplicateTab.handleLinkClick',
@@ -109,6 +96,19 @@ var TreeStyleTabWindowHelper = {
{
this.overrideExtensionsBeforeBrowserInit(); // windowHelperHacks.js
this.overrideGlobalFunctions();
+
+ // Replacing of gBrowserInit._delayedStartup() with eval()
+ // breaks the variable scope of the function and break its
+ // functionality completely.
+ // Instead, I change the behavior of the method only at the
+ // startup process.
+ gBrowser.__treestyletab__swapBrowsersAndCloseOther = gBrowser.swapBrowsersAndCloseOther;
+ gBrowser.swapBrowsersAndCloseOther = function(...args) {
+ if (TreeStyleTabWindowHelper.runningDelayedStartup &&
+ TreeStyleTabService.tearOffSubtreeFromRemote())
+ return;
+ return this.__treestyletab__swapBrowsersAndCloseOther.apply(this, args);
+ };
},
onAfterBrowserInit : function TSTWH_onAfterBrowserInit()
@@ -127,93 +127,121 @@ var TreeStyleTabWindowHelper = {
)
aObserver = aObserver.tabContainer;
- TreeStyleTabUtils.doPatching(aObserver._setEffectAllowedForDataTransfer, aObserver+'._setEffectAllowedForDataTransfer', function(aName, aSource) {
- return eval('aObserver._setEffectAllowedForDataTransfer = '+aSource.replace(
- '{',
- '{ var TSTTabBrowser = this instanceof Element ? (this.tabbrowser || this) : gBrowser ; var TST = TSTTabBrowser.treeStyleTab;'
- ).replace(
- /\.screenX/g, '[TST.screenPositionProp]'
- ).replace(
- /\.width/g, '[TST.sizeProp]'
- ).replace(
- /(return (?:true|dt.effectAllowed = "copyMove");)/,
- 'if (!TST.tabbarDNDObserver.canDropTab(arguments[0])) {\n' +
- ' return dt.effectAllowed = "none";\n' +
- '}\n' +
- '$1'
- ).replace(
- 'sourceNode.parentNode == this &&',
- '$& TST.getTabFromEvent(event) == sourceNode &&'
- ));
- }, 'TST');
+ if (typeof aObserver._setEffectAllowedForDataTransfer === 'function') { // Firefox 43 and older
+ TreeStyleTabUtils.doPatching(aObserver._setEffectAllowedForDataTransfer, aObserver+'._setEffectAllowedForDataTransfer', function(aName, aSource) {
+ return eval('aObserver._setEffectAllowedForDataTransfer = '+aSource.replace(
+ '{',
+ '{ var TSTTabBrowser = this instanceof Element ? (this.tabbrowser || this) : gBrowser ; var TST = TSTTabBrowser.treeStyleTab;'
+ ).replace(
+ /\.screenX/g, '[TST.screenPositionProp]'
+ ).replace(
+ /\.width/g, '[TST.sizeProp]'
+ ).replace(
+ /(return (?:true|dt.effectAllowed = "copyMove");)/,
+ 'if (!TST.tabbarDNDObserver.canDropTab(arguments[0])) {\n' +
+ ' return dt.effectAllowed = "none";\n' +
+ '}\n' +
+ '$1'
+ ).replace(
+ 'sourceNode.parentNode == this &&',
+ '$& TST.getTabFromEvent(event) == sourceNode &&'
+ ));
+ }, 'TST');
+ }
+ else { // Firefox 44 and later
+ aObserver.__treestyletab__getDropEffectForTabDrag = aObserver._getDropEffectForTabDrag;
+ aObserver._getDropEffectForTabDrag = function(...aArgs) {
+ var effects = this.__treestyletab__getDropEffectForTabDrag.apply(this, aArgs);
+ if (effects === 'copy' || effects === 'move') {
+ let TSTTabBrowser = this instanceof Element ? (this.tabbrowser || this) : gBrowser ;
+ var TST = TSTTabBrowser.treeStyleTab
+ if (!TST.tabbarDNDObserver.canDropTab(aArgs[0]))
+ effects = 'none';
+ }
+ return effects;
+ };
+ }
},
overrideGlobalFunctions : function TSTWH_overrideGlobalFunctions()
{
this.initToolbarItems();
- TreeStyleTabUtils.doPatching(nsContextMenu.prototype.openLinkInTab, 'nsContextMenu.prototype.openLinkInTab', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{\n' +
- ' TreeStyleTabService.handleNewTabFromCurrent(this.target.ownerDocument.defaultView);'
- ));
- }, 'TreeStyleTab');
-
- TreeStyleTabUtils.doPatching(nsContextMenu.prototype.openFrameInTab, 'nsContextMenu.prototype.openFrameInTab', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{\n' +
- ' TreeStyleTabService.handleNewTabFromCurrent(this.target.ownerDocument.defaultView);'
- ));
- }, 'TreeStyleTab');
-
- var viewImageMethod = ('viewImage' in nsContextMenu.prototype) ? 'viewImage' : 'viewMedia' ;
- TreeStyleTabUtils.doPatching(nsContextMenu.prototype[viewImageMethod], 'nsContextMenu.prototype.'+viewImageMethod, function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- /(openUILink\()/g,
- 'TreeStyleTabService.onBeforeViewMedia(e, this.target.ownerDocument.defaultView); $1'
- ));
- }, 'TreeStyleTab');
-
- TreeStyleTabUtils.doPatching(nsContextMenu.prototype.viewBGImage, 'nsContextMenu.prototype.viewBGImage', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'openUILink(',
- 'TreeStyleTabService.onBeforeViewMedia(e, this.target.ownerDocument.defaultView); $&'
- ));
- }, 'TreeStyleTab');
-
- TreeStyleTabUtils.doPatching(nsContextMenu.prototype.addDictionaries, 'nsContextMenu.prototype.addDictionaries', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'openUILinkIn(',
- 'TreeStyleTabService.onBeforeOpenLink(where, this.target.ownerDocument.defaultView); $&'
- ));
- }, 'TreeStyleTab');
-
- TreeStyleTabUtils.doPatching(BrowserSearch._loadSearch, 'BrowserSearch._loadSearch', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'openLinkIn(',
- 'TreeStyleTabService.onBeforeBrowserSearch(arguments[0], useNewTab); $&'
- ));
- }, 'TreeStyleTab');
-
- TreeStyleTabUtils.doPatching(window.openLinkIn, 'window.openLinkIn', function(aName, aSource) {
- // Bug 1050447 changed this line in Fx 34 to
- // newTab = w.gBrowser.loadOneTab(
- // Bug 1108555 removed newTab assignment
- return eval(aName+' = '+aSource.replace(
- /((b|(newTab = )?w\.gB)rowser.loadOneTab\()/g,
- 'TreeStyleTabService.onBeforeOpenLinkWithTab(gBrowser.selectedTab, aFromChrome); $1'
- ));
- }, 'TreeStyleTab');
+ nsContextMenu.prototype.__treestyletab__openLinkInTab = nsContextMenu.prototype.openLinkInTab;
+ nsContextMenu.prototype.openLinkInTab = function(...aArgs) {
+ TreeStyleTabService.handleNewTabFromCurrent(this.target.ownerDocument.defaultView);
+ return this.__treestyletab__openLinkInTab.apply(this, aArgs);
+ };
+
+ nsContextMenu.prototype.__treestyletab__openFrameInTab = nsContextMenu.prototype.openFrameInTab;
+ nsContextMenu.prototype.openFrameInTab = function(...aArgs) {
+ TreeStyleTabService.handleNewTabFromCurrent(this.target.ownerDocument.defaultView);
+ return this.__treestyletab__openFrameInTab.apply(this, aArgs);
+ };
+
+ nsContextMenu.prototype.__treestyletab__viewMedia = nsContextMenu.prototype.viewMedia;
+ nsContextMenu.prototype.viewMedia = function(aEvent) {
+ TreeStyleTabService.onBeforeViewMedia(aEvent, this.target.ownerDocument.defaultView);
+ return this.__treestyletab__viewMedia.call(this, aEvent);
+ };
+
+ nsContextMenu.prototype.__treestyletab__viewBGImage = nsContextMenu.prototype.viewBGImage;
+ nsContextMenu.prototype.viewBGImage = function(aEvent) {
+ TreeStyleTabService.onBeforeViewMedia(aEvent, this.target.ownerDocument.defaultView);
+ return this.__treestyletab__viewBGImage.call(this, aEvent);
+ };
+
+ nsContextMenu.prototype.__treestyletab__addDictionaries = nsContextMenu.prototype.addDictionaries;
+ nsContextMenu.prototype.addDictionaries = function(...aArgs) {
+ var newWindowPref = TreeStyleTabUtils.prefs.getPref('browser.link.open_newwindow');
+ var where = newWindowPref === 3 ? 'tab' : 'window' ;
+ TreeStyleTabService.onBeforeOpenLink(where, this.target.ownerDocument.defaultView);
+ return this.__treestyletab__addDictionaries.apply(this, aArgs);
+ };
+
+ nsContextMenu.prototype.__treestyletab__viewPartialSource = nsContextMenu.prototype.viewPartialSource;
+ nsContextMenu.prototype.viewPartialSource = function(...aArgs) {
+ TreeStyleTabService.handleNewTabFromCurrent(this.target.ownerDocument.defaultView);
+ return this.__treestyletab__viewPartialSource.apply(this, aArgs);
+ };
+
+ nsContextMenu.prototype.__treestyletab__viewFrameSource = nsContextMenu.prototype.viewFrameSource;
+ nsContextMenu.prototype.viewFrameSource = function(...aArgs) {
+ TreeStyleTabService.handleNewTabFromCurrent(this.target.ownerDocument.defaultView);
+ return this.__treestyletab__viewFrameSource.apply(this, aArgs);
+ };
+
+ window.__treestyletab__BrowserViewSource = window.BrowserViewSource;
+ window.BrowserViewSource = function(...aArgs) {
+ TreeStyleTabService.handleNewTabFromCurrent(aArgs[0]);
+ return this.__treestyletab__BrowserViewSource.apply(this, aArgs);
+ };
+
+ BrowserSearch.__treestyletab__loadSearch = BrowserSearch._loadSearch;
+ BrowserSearch._loadSearch = function(aSearchText, aUseNewTab, aPurpose) {
+ TreeStyleTabService.onBeforeBrowserSearch(aSearchText, aUseNewTab);
+ return this.__treestyletab__loadSearch.call(this, aSearchText, aUseNewTab, aPurpose);
+ };
+
+ window.__treestyletab__openLinkIn = window.openLinkIn;
+ window.openLinkIn = function(aUrl, aWhere, aParams) {
+ TreeStyleTabService.onBeforeOpenLinkWithTab(gBrowser.selectedTab, aParams.fromChrome);
+ return this.__treestyletab__openLinkIn.call(this, aUrl, aWhere, aParams);
+ };
[
- 'window.permaTabs.utils.wrappedFunctions["window.contentAreaClick"]',
- 'window.__contentAreaClick',
- 'window.__ctxextensions__contentAreaClick',
- 'window.contentAreaClick'
- ].forEach(function(aName) {
- var func = this._getFunction(aName);
+ { owner: window.permaTabs && window.permaTabs.utils && window.permaTabs.utils.wrappedFunctions,
+ name: 'window.contentAreaClick' },
+ { owner: window,
+ name: '__contentAreaClick' },
+ { owner: window,
+ name: '__ctxextensions__contentAreaClick' },
+ { owner: window,
+ name: 'contentAreaClick' }
+ ].forEach(function(aTarget) {
+ var name = aTarget.name;
+ var owner = aTarget.owner;
+ var func = owner && owner[name];
var source = func && func.toString();
if (!func ||
!/^\(?function contentAreaClick/.test(source) ||
@@ -221,20 +249,19 @@ var TreeStyleTabWindowHelper = {
// (calls for the function is not included by Firefox default.)
!/(openNewTabWith\()/.test(source))
return;
- TreeStyleTabUtils.doPatching(func, aName, function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- /(openNewTabWith\()/g,
- 'TreeStyleTabService.onBeforeOpenNewTabByThirdParty(event.target.ownerDocument.defaultView); $1'
- ));
- }, 'TreeStyleTab');
+ let original = '__treestyletab__' + name;
+ owner[original] = owner[name];
+ owner[name] = function(aEvent, aIsPanelClick, ...aArgs) {
+ TreeStyleTabService.onBeforeOpenNewTabByThirdParty(aEvent.target.ownerDocument.defaultView);
+ return this[original].apply(this, [aEvent, aIsPanelClick].concat(aArgs));
+ };
}, this);
- TreeStyleTabUtils.doPatching(window.duplicateTabIn, 'window.duplicateTabIn', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{ gBrowser.treeStyleTab.onBeforeTabDuplicate(aTab, where, delta); '
- ));
- }, 'treeStyleTab');
+ window.__treestyletab__duplicateTabIn = window.duplicateTabIn;
+ window.duplicateTabIn = function(aTab, where, delta) {
+ gBrowser.treeStyleTab.onBeforeTabDuplicate(aTab, where, delta);
+ return window.__treestyletab__duplicateTabIn.call(this, aTab, where, delta);
+ };
[
'permaTabs.utils.wrappedFunctions["window.BrowserHomeClick"]',
@@ -252,89 +279,82 @@ var TreeStyleTabWindowHelper = {
}, 'TreeStyleTab');
}, this);
- TreeStyleTabUtils.doPatching(FeedHandler.loadFeed, 'FeedHandler.loadFeed', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'openUILink(',
- 'TreeStyleTabService.onBeforeViewMedia(event, gBrowser); $&'
- ));
- }, 'TreeStyleTab');
+ FeedHandler.__treestyletab__loadFeed = FeedHandler.loadFeed;
+ FeedHandler.loadFeed = function(aHref, aEvent) {
+ TreeStyleTabService.onBeforeViewMedia(aEvent, gBrowser);
+ return this.__treestyletab__loadFeed.call(this, aHref, aEvent);
+ };
if ('showNavToolbox' in FullScreen) { // for Firefox 40 or later
- TreeStyleTabUtils.doPatching(FullScreen.showNavToolbox, 'FullScreen.showNavToolbox', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'this._isChromeCollapsed = false;',
- 'gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_FULLSCREEN); $&'
- ));
- }, 'treeStyleTab');
- TreeStyleTabUtils.doPatching(FullScreen.hideNavToolbox, 'FullScreen.hideNavToolbox', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'this._isChromeCollapsed = true;',
- 'gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_FULLSCREEN); $&'
- ));
- }, 'treeStyleTab');
+ FullScreen.__treestyletab__showNavToolbox = FullScreen.showNavToolbox;
+ FullScreen.showNavToolbox = function(...aArgs) {
+ var beforeCollapsed = this._isChromeCollapsed;
+ var retVal = this.__treestyletab__showNavToolbox.apply(this, aArgs);
+ if (beforeCollapsed !== this._isChromeCollapsed)
+ gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_FULLSCREEN);
+ return retVal;
+ };
+
+ FullScreen.__treestyletab__hideNavToolbox = FullScreen.hideNavToolbox;
+ FullScreen.hideNavToolbox = function(...aArgs) {
+ var beforeCollapsed = this._isChromeCollapsed;
+ var retVal = this.__treestyletab__hideNavToolbox.apply(this, aArgs);
+ if (beforeCollapsed !== this._isChromeCollapsed)
+ gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_FULLSCREEN);
+ return retVal;
+ };
}
else if ('mouseoverToggle' in FullScreen) { // for Firefox 39 or older
- TreeStyleTabUtils.doPatching(FullScreen.mouseoverToggle, 'FullScreen.mouseoverToggle', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'this._isChromeCollapsed = !aShow;',
- 'gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_FULLSCREEN); $&'
- ));
- }, 'treeStyleTab');
- }
-
- TreeStyleTabUtils.doPatching(FullScreen.toggle, 'FullScreen.toggle', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- 'if (enterFS) {',
- 'gBrowser.treeStyleTab.onBeforeFullScreenToggle(enterFS); $&'
- ));
- }, 'treeStyleTab');
-
- TreeStyleTabUtils.doPatching(PrintUtils.printPreview, 'PrintUtils.printPreview', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{ TreeStyleTabService.onPrintPreviewEnter();'
- ));
- }, 'TreeStyleTab');
- TreeStyleTabUtils.doPatching(PrintUtils.exitPrintPreview, 'PrintUtils.exitPrintPreview', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{ TreeStyleTabService.onPrintPreviewExit();'
- ));
- }, 'TreeStyleTab');
-
- if ('TabsOnTop' in window) {
- TreeStyleTabUtils.doPatching(TabsOnTop.syncUI, 'TabsOnTop.syncUI', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- /(\}\)?)$/,
- 'gBrowser.treeStyleTab.onTabsOnTopSyncCommand(enabled); $&'
- ));
- }, 'treeStyleTab');
+ FullScreen.__treestyletab__mouseoverToggle = FullScreen.mouseoverToggle;
+ FullScreen.mouseoverToggle = function(...aArgs) {
+ var beforeCollapsed = this._isChromeCollapsed;
+ var retVal = this.__treestyletab__mouseoverToggle.apply(this, aArgs);
+ if (beforeCollapsed !== this._isChromeCollapsed)
+ gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_FULLSCREEN);
+ return retVal;
+ };
}
- if ('SidebarUI' in window) { // for Firefox 39 or later
- SidebarUI.__treestyletab__show = SidebarUI.show;
- SidebarUI.show = function(...aArgs) {
- return this.__treestyletab__show.apply(this, aArgs)
- .then(function(aResult) {
+ FullScreen.__treestyletab__toggle = FullScreen.toggle;
+ FullScreen.toggle = function(...aArgs) {
+ var enterFS = window.fullScreen;
+ gBrowser.treeStyleTab.onBeforeFullScreenToggle(enterFS);
+ return this.__treestyletab__toggle.apply(this, aArgs);
+ };
+
+ PrintUtils.__treestyletab__printPreview = PrintUtils.printPreview;
+ PrintUtils.printPreview = function(...aArgs) {
+ TreeStyleTabService.onPrintPreviewEnter();
+ return this.__treestyletab__printPreview.apply(this, aArgs);
+ };
+ PrintUtils.__treestyletab__exitPrintPreview = PrintUtils.exitPrintPreview;
+ PrintUtils.exitPrintPreview = function(...aArgs) {
+ TreeStyleTabService.onPrintPreviewExit();
+ return this.__treestyletab__exitPrintPreview.apply(this, aArgs);
+ };
+
+ SidebarUI.__treestyletab__show = SidebarUI.show;
+ SidebarUI.show = function(...aArgs) {
+ var opened = this.isOpen;
+ var width = this.browser.boxObject.width;
+ return this.__treestyletab__show.apply(this, aArgs)
+ .then((function(aResult) {
+ if (opened !== this.isOpen ||
+ width !== this.browser.boxObject.width)
gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_TOGGLE_SIDEBAR);
- return aResult;
- });
- };
- SidebarUI.__treestyletab__hide = SidebarUI.hide;
- SidebarUI.hide = function(...aArgs) {
- var retVal = this.__treestyletab__hide.apply(this, aArgs);
+ return aResult;
+ }).bind(this));
+ };
+ SidebarUI.__treestyletab__hide = SidebarUI.hide;
+ SidebarUI.hide = function(...aArgs) {
+ var opened = this.isOpen;
+ var width = this.browser.boxObject.width;
+ var retVal = this.__treestyletab__hide.apply(this, aArgs);
+ if (opened !== this.isOpen ||
+ width !== this.browser.boxObject.width)
gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_TOGGLE_SIDEBAR);
- return retVal;
- };
- }
- else if ('toggleSidebar' in window) { // for Firefox 38 or older
- TreeStyleTabUtils.doPatching(window.toggleSidebar, 'window.toggleSidebar', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{ gBrowser.treeStyleTab.updateFloatingTabbar(gBrowser.treeStyleTab.kTABBAR_UPDATE_BY_TOGGLE_SIDEBAR);'
- ));
- }, 'treeStyleTab');
- }
+ return retVal;
+ };
},
_splitFunctionNames : function TSTWH__splitFunctionNames(aString)
{
@@ -361,6 +381,8 @@ var TreeStyleTabWindowHelper = {
initToolbarItems : function TSTWH_initToolbarItems()
{
+ let { ReferenceCounter } = Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js', {});
+
var searchbar = document.getElementById('searchbar');
if (searchbar &&
searchbar.doSearch &&
@@ -375,35 +397,47 @@ var TreeStyleTabWindowHelper = {
}
var goButton = document.getElementById('urlbar-go-button');
- if (goButton)
+ if (goButton) {
goButton.parentNode.addEventListener('click', this.service, true);
+ ReferenceCounter.add('goButton.parentNode,click,this.service,true');
+ }
var tabbar = this.service.getTabStrip(this.service.browser);
tabbar.addEventListener('click', this.service, true);
+ ReferenceCounter.add('tabbar,click,this.service,true');
var newTabButton = document.getElementById('new-tab-button');
- const nsIDOMNode = Ci.nsIDOMNode;
+ var nsIDOMNode = Ci.nsIDOMNode;
if (newTabButton &&
- !(tabbar.compareDocumentPosition(newTabButton) & nsIDOMNode.DOCUMENT_POSITION_CONTAINED_BY))
+ !(tabbar.compareDocumentPosition(newTabButton) & nsIDOMNode.DOCUMENT_POSITION_CONTAINED_BY)) {
newTabButton.parentNode.addEventListener('click', this.service, true);
+ ReferenceCounter.add('newTabButton.parentNode,click,this.service,true');
+ }
this.service.updateAllTabsButton(gBrowser);
},
destroyToolbarItems : function TSTWH_destroyToolbarItems()
{
+ let { ReferenceCounter } = Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js', {});
+
var goButton = document.getElementById('urlbar-go-button');
- if (goButton)
- goButton.parentNode.removeEventListener('click', this, true);
+ if (goButton) {
+ goButton.parentNode.removeEventListener('click', this.service, true);
+ ReferenceCounter.remove('goButton.parentNode,click,this.service,true');
+ }
var tabbar = this.service.getTabStrip(this.service.browser);
tabbar.removeEventListener('click', this.service, true);
+ ReferenceCounter.remove('tabbar,click,this.service,true');
var newTabButton = document.getElementById('new-tab-button');
- const nsIDOMNode = Ci.nsIDOMNode;
+ var nsIDOMNode = Ci.nsIDOMNode;
if (newTabButton &&
- !(tabbar.compareDocumentPosition(newTabButton) & Ci.nsIDOMNode.DOCUMENT_POSITION_CONTAINED_BY))
+ !(tabbar.compareDocumentPosition(newTabButton) & Ci.nsIDOMNode.DOCUMENT_POSITION_CONTAINED_BY)) {
newTabButton.parentNode.removeEventListener('click', this.service, true);
+ ReferenceCounter.remove('newTabButton.parentNode,click,this.service,true');
+ }
var allTabsButton = document.getElementById('alltabs-button');
if (allTabsButton && allTabsButton.hasChildNodes())
@@ -498,27 +532,26 @@ var TreeStyleTabWindowHelper = {
));
}, 'treeStyleTab');
- TreeStyleTabUtils.doPatching(b.removeCurrentTab, 'b.removeCurrentTab', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{ if (!this.treeStyleTab.warnAboutClosingTabSubtreeOf(this.selectedTab)) return;'
- ));
- }, 'treeStyleTab');
+ b.__treestyletab__removeCurrentTab = b.removeCurrentTab;
+ b.removeCurrentTab = function(...aArgs) {
+ if (!this.treeStyleTab.warnAboutClosingTabSubtreeOf(this.selectedTab))
+ return;
+ return this.__treestyletab__removeCurrentTab.apply(this, aArgs);
+ };
},
initTabbarMethods : function TSTWH_initTabbarMethods(aTabBrowser)
{
var b = aTabBrowser;
- TreeStyleTabUtils.doPatching(b.mTabContainer.advanceSelectedTab, 'b.mTabContainer.advanceSelectedTab', function(aName, aSource) {
- return eval(aName+' = '+aSource.replace(
- '{',
- '{\n' +
- ' var treeStyleTab = TreeStyleTabService.getTabBrowserFromChild(this).treeStyleTab;\n' +
- ' if (treeStyleTab.handleAdvanceSelectedTab(arguments[0], arguments[1]))\n' +
- ' return;'
- ));
- }, 'treeStyleTab.handleAdvanceSelectedTab');
+ if (!b.mTabContainer.__treestyletab__advanceSelectedTab)
+ b.mTabContainer.__treestyletab__advanceSelectedTab = b.mTabContainer.advanceSelectedTab;
+ if (b.mTabContainer.advanceSelectedTab.toString() === b.mTabContainer.__treestyletab__advanceSelectedTab.toString())
+ b.mTabContainer.advanceSelectedTab = function(...aArgs) {
+ if (b.treeStyleTab.handleAdvanceSelectedTab(aArgs[0], aArgs[1]))
+ return;
+ return this.__treestyletab__advanceSelectedTab.apply(this, aArgs);
+ };
TreeStyleTabUtils.doPatching(b.mTabContainer._notifyBackgroundTab, 'b.mTabContainer._notifyBackgroundTab', function(aName, aSource) {
return eval(aName+' = '+aSource.replace(
@@ -556,6 +589,14 @@ var TreeStyleTabWindowHelper = {
));
}, 'TreeStyleTabService.getTabBrowserFromChild');
+ TreeStyleTabUtils.doPatching(b.tabContainer._getDragTargetTab, 'b.tabContainer._getDragTargetTab', function(aName, aSource) {
+ return eval(aName+' = '+aSource.replace(
+ /\.screenX/g, '[this.treeStyleTab.screenPositionProp]'
+ ).replace(
+ /\.width/g, '[this.treeStyleTab.sizeProp]'
+ ));
+ }, 'treeStyleTab');
+
TreeStyleTabUtils.doPatching(b.tabContainer._getDropIndex, 'b.tabContainer._getDropIndex', function(aName, aSource) {
return eval(aName+' = '+aSource.replace(
/\.screenX/g, '[this.treeStyleTab.screenPositionProp]'
@@ -573,14 +614,11 @@ var TreeStyleTabWindowHelper = {
if (!scrollbox.__treestyletab__ensureElementIsVisible) {
scrollbox.__treestyletab__ensureElementIsVisible = scrollbox.ensureElementIsVisible;
scrollbox.ensureElementIsVisible = function(...aArgs) {
- var treeStyleTab = TreeStyleTabService.getTabBrowserFromChild(this).treeStyleTab;
- if (treeStyleTab) {
- if (treeStyleTab.shouldCancelEnsureElementIsVisible())
- return;
- let shouldScrollNow = aArgs[1] === false;
- if (treeStyleTab.animationEnabled && !shouldScrollNow)
- return treeStyleTab.scrollToTab(aArgs[0]);
- }
+ if (b.treeStyleTab.shouldCancelEnsureElementIsVisible())
+ return;
+ let shouldScrollNow = aArgs[1] === false;
+ if (b.treeStyleTab.animationEnabled && !shouldScrollNow)
+ return b.treeStyleTab.scrollToTab(aArgs[0]);
this.__treestyletab__ensureElementIsVisible.apply(this, aArgs);
};
}
diff --git a/content/treestyletab/windowHelperHacks.js b/content/treestyletab/windowHelperHacks.js
index fd28c5d..ba3e709 100644
--- a/content/treestyletab/windowHelperHacks.js
+++ b/content/treestyletab/windowHelperHacks.js
@@ -318,33 +318,37 @@ TreeStyleTabWindowHelper.overrideExtensionsPreInit = function TSTWH_overrideExte
// https://addons.mozilla.org/firefox/addon/748
if (TreeStyleTabUtils.getTreePref('compatibility.Greasemonkey')) {
try {
- let hitchModule = Components.utils.import('resource://greasemonkey/util/hitch.js', {});
- let hitch = hitchModule.hitch;
- if (hitch.toSource().indexOf('TreeStyleTabService') < 0) {
- let ns = {};
- Components.utils.import('resource://greasemonkey/third-party/getChromeWinForContentWin.js', ns);
- let getChromeWinForContentWin = ns.getChromeWinForContentWin;
- hitchModule.hitch = function(aObject, aMethod) {
- if (typeof aMethod == 'function' &&
- aMethod.toSource().indexOf('function openInTab') > -1) {
- let originalOpenInTab = aMethod;
- /**
- * This function must be replaced on scripts in "chrome:" URL, like this.
- * Otherwise the original openInTab() will raise violation error.
- * Don't move this hack into JS code modules with "resource:" URL.
- */
- aMethod = function openInTab(aSafeContentWindow, aURL, aLoadInBackgtound) {
- let chrome = getChromeWinForContentWin(aSafeContentWindow);
- if (chrome && chrome.TreeStyleTabService)
- chrome.TreeStyleTabService.readyToOpenChildTabNow(aSafeContentWindow);
- return originalOpenInTab.apply(this, arguments);
- };
- }
- return hitch.apply(this, arguments);
+ if ('GM_BrowserUI' in window &&
+ typeof GM_BrowserUI.openInTab == 'function') {
+ window.messageManager.removeMessageListener('greasemonkey:open-in-tab', GM_BrowserUI.openInTab);
+ let originalOpenInTab = GM_BrowserUI.openInTab;
+ let originalTabs = [];
+ GM_BrowserUI.openInTab = function(aMessage, ...aArgs) {
+ if (originalTabs.length === 0)
+ originalTabs = Array.slice(gBrowser.tabContainer.childNodes, 0);
+ var owner = aMessage.target;
+ var retVal = originalOpenInTab.apply(this, [aMessage].concat(aArgs));
+ window.setTimeout(function() {
+ window.setTimeout(function() {
+ if (originalTabs.length === 0)
+ return;
+ var currentTabs = Array.slice(gBrowser.tabContainer.childNodes, 0);
+ var parent = gBrowser.treeStyleTab.getTabFromBrowser(owner);
+ var insertAtFirst = TreeStyleTabUtils.getTreePref('insertNewChildAt') == sv.kINSERT_FISRT;
+ var firstChild = gBrowser.treeStyleTab.getFirstChildTab(parent);
+ currentTabs.forEach(function(aTab) {
+ if (originalTabs.indexOf(aTab) >= 0)
+ return;
+ gBrowser.treeStyleTab.attachTabTo(aTab, parent, {
+ insertBefore : insertAtFirst ? firstChild : null
+ });
+ });
+ originalTabs = [];
+ }, 0);
+ }, 0);
+ return retVal;
};
- Components.utils.import('resource://greasemonkey/util.js', ns);
- if (ns.GM_util)
- ns.GM_util.hitch = hitchModule.hitch;
+ window.messageManager.addMessageListener('greasemonkey:open-in-tab', GM_BrowserUI.openInTab);
}
}
catch(e) {
diff --git a/defaults/preferences/treestyletab.js b/defaults/preferences/treestyletab.js
index 168311f..788b7e0 100644
--- a/defaults/preferences/treestyletab.js
+++ b/defaults/preferences/treestyletab.js
@@ -250,7 +250,7 @@ pref("extensions.treestyletab.maxTreeLevel.vertical", 999);
* So, even if you enlarge "maxTreeLevel" prefs, you won't see tabs with new
* indentation.
*/
-pref("extensions.treestyletab.maxTreeLevel.phisical", false);
+pref("extensions.treestyletab.maxTreeLevel.physical", false);
/**
* Indentation size for one tree level, in pixels.
@@ -703,3 +703,13 @@ pref("extensions.treestyletab.compatibility.TotalToolbar", true);
*/
pref("extensions.treestyletab.prefsVersion", 0);
+/**
+ * Flags to activate debug dumps for each module.
+ */
+pref("extensions.treestyletab.debug.all", false);
+pref("extensions.treestyletab.debug.autoHide", false);
+pref("extensions.treestyletab.debug.base", false);
+pref("extensions.treestyletab.debug.browser", false);
+pref("extensions.treestyletab.debug.browserUIShowHideObserver", false);
+pref("extensions.treestyletab.debug.contentBridge", false);
+pref("extensions.treestyletab.debug.tabbarDNDObserver", false);
diff --git a/install.rdf b/install.rdf
index d293fcd..69f92be 100644
--- a/install.rdf
+++ b/install.rdf
@@ -5,7 +5,7 @@
<RDF:Description RDF:about="urn:mozilla:install-manifest"
em:id="treestyletab at piro.sakura.ne.jp"
em:name="Tree Style Tab"
- em:version="0.15.20150902901"
+ em:version="0.16.2015111001"
em:creator="YUKI "Piro" Hiroshi"
em:description="Show tabs like a tree."
em:homepageURL="http://piro.sakura.ne.jp/xul/_treestyletab.html.en"
@@ -235,7 +235,7 @@
<em:targetApplication>
<RDF:Description em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
em:minVersion="38.0"
- em:maxVersion="44.0a1" />
+ em:maxVersion="45.0a1" />
</em:targetApplication>
</RDF:Description>
</RDF:RDF>
diff --git a/locale/en-US/treestyletab/treestyletab.dtd b/locale/en-US/treestyletab/treestyletab.dtd
index 09f93f9..6a63bc7 100644
--- a/locale/en-US/treestyletab/treestyletab.dtd
+++ b/locale/en-US/treestyletab/treestyletab.dtd
@@ -7,8 +7,8 @@
<!ENTITY config.tabs.appearance "Appearance">
<!ENTITY config.tabbar.position.caption "Tab bar position">
-<!ENTITY config.tabbar.position.left "Leftside">
-<!ENTITY config.tabbar.position.right "Rightside">
+<!ENTITY config.tabbar.position.left "Left">
+<!ENTITY config.tabbar.position.right "Right">
<!ENTITY config.tabbar.position.top "Top (Firefox default)">
<!ENTITY config.tabbar.position.bottom "Bottom">
<!ENTITY config.tabbar.invertClosebox.left "Show closebox at leftside in each tab">
diff --git a/modules/ReferenceCounter.js b/modules/ReferenceCounter.js
new file mode 100644
index 0000000..b57318c
--- /dev/null
+++ b/modules/ReferenceCounter.js
@@ -0,0 +1,42 @@
+/**
+ * How to use:
+ *
+ * 1. Insert "ReferenceCounter.add('unique key'); after "addEventListener()"
+ * 2. Insert "ReferenceCounter.remove('unique key'); after "removeEventListener()"
+ * 3. Open and close windows multiple times.
+ * 4. Go to the browser console and run the script:
+ * (function() { let { ReferenceCounter } = Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js', {}); return ReferenceCounter.report() })();
+ *
+ * Expected result for good case:
+ *
+ * Blank array is returned.
+ *
+ * Expected result for bad case:
+ *
+ * Not-removed counters are reported as the elements of the returned array.
+ */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ['ReferenceCounter'];
+
+var ReferenceCounter = {
+ _listeners: {},
+ add: function(aKey) {
+ this._listeners[aKey] = this._listeners[aKey] || 0;
+ this._listeners[aKey]++;
+ },
+ remove: function(aKey) {
+ this._listeners[aKey] = this._listeners[aKey] || 0;
+ this._listeners[aKey]--;
+ },
+ report: function() {
+ var keys = [];
+ Object.keys(this._listeners).forEach(function(aKey) {
+ if (this._listeners[aKey] <= 1)
+ return;
+ keys.push(aKey+'('+this._listeners[aKey]+')');
+ }, this);
+ return keys;
+ }
+};
diff --git a/modules/autoHide.js b/modules/autoHide.js
index 6665e8a..c6eb9e0 100644
--- a/modules/autoHide.js
+++ b/modules/autoHide.js
@@ -34,9 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['AutoHideBrowser', 'AutoHideWindow'];
-
-const DEBUG = false;
+var EXPORTED_SYMBOLS = ['AutoHideBrowser', 'AutoHideWindow'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -46,6 +44,7 @@ Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://treestyletab-modules/lib/inherit.jsm');
Cu.import('resource://treestyletab-modules/constants.js');
+Cu.import('resource://treestyletab-modules/ReferenceCounter.js');
XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
@@ -59,7 +58,7 @@ XPCOMUtils.defineLazyGetter(this, 'prefs', function() {
});
-const AutoHideConstants = Object.freeze(inherit(TreeStyleTabConstants, {
+var AutoHideConstants = Object.freeze(inherit(TreeStyleTabConstants, {
kMODE : 'treestyletab-tabbar-autohide-mode',
kMODE_DISABLED : 0,
kMODE_HIDE : 1,
@@ -355,11 +354,21 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
if (!(aReason & this.kSHOWHIDE_BY_API)) {
b.addEventListener('dragover', this, true);
+ ReferenceCounter.add('b,dragover,AHW,true');
b.addEventListener('dragleave', this, true);
+ ReferenceCounter.add('b,dragleave,AHW,true');
sv.tabStripPlaceHolder.addEventListener('mousedown', this, true);
+ ReferenceCounter.add('tabStripPlaceHolder,mousedown,AHW,true');
sv.tabStripPlaceHolder.addEventListener('mouseup', this, true);
+ ReferenceCounter.add('tabStripPlaceHolder,mouseup,AHW,true');
sv.tabStrip.addEventListener('mousedown', this, true);
- sv.tabStrip.addEventListener('mouseup', this, true);
+ ReferenceCounter.add('tabStrip,mousedown,AHW,true');
+ w.addEventListener('mouseup', this, true);
+ ReferenceCounter.add('w,mouseup,AHW,true');
+ w.addEventListener('dragend', this, true);
+ ReferenceCounter.add('w,dragend,AHW,true');
+ w.addEventListener('drop', this, true);
+ ReferenceCounter.add('w,drop,AHW,true');
if (this.shouldListenMouseMove)
this.startListenMouseMove();
if (b == w.gBrowser && sv.shouldListenKeyEventsForAutoHide)
@@ -368,7 +377,9 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
this.notifyStatusToAllTabs();
}
w.addEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
+ ReferenceCounter.add('w,kEVENT_TYPE_PRINT_PREVIEW_ENTERED,AHW,false');
w.addEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_EXITED, this, false);
+ ReferenceCounter.add('w,kEVENT_TYPE_PRINT_PREVIEW_EXITED,AHW,false');
this.updateTransparency();
@@ -394,11 +405,21 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
if (this.userActionListening) {
b.removeEventListener('dragover', this, true);
+ ReferenceCounter.remove('b,dragover,AHW,true');
b.removeEventListener('dragleave', this, true);
+ ReferenceCounter.remove('b,dragleave,AHW,true');
sv.tabStripPlaceHolder.removeEventListener('mousedown', this, true);
+ ReferenceCounter.remove('tabStripPlaceHolder,mousedown,AHW,true');
sv.tabStripPlaceHolder.removeEventListener('mouseup', this, true);
+ ReferenceCounter.remove('tabStripPlaceHolder,mouseup,AHW,true');
sv.tabStrip.removeEventListener('mousedown', this, true);
- sv.tabStrip.removeEventListener('mouseup', this, true);
+ ReferenceCounter.remove('tabStrip,mousedown,AHW,true');
+ w.removeEventListener('mouseup', this, true);
+ ReferenceCounter.remove('w,mouseup,AHW,true');
+ w.removeEventListener('dragend', this, true);
+ ReferenceCounter.remove('w,dragend,AHW,true');
+ w.removeEventListener('drop', this, true);
+ ReferenceCounter.remove('w,drop,AHW,true');
this.endListenMouseMove();
if (b == w.gBrowser)
w.TreeStyleTabService.endListenKeyEventsFor(sv.LISTEN_FOR_AUTOHIDE);
@@ -406,7 +427,9 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
this.notifyStatusToAllTabs();
}
w.removeEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
+ ReferenceCounter.remove('w,kEVENT_TYPE_PRINT_PREVIEW_ENTERED,AHW,false');
w.removeEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_EXITED, this, false);
+ ReferenceCounter.remove('w,kEVENT_TYPE_PRINT_PREVIEW_EXITED,AHW,false');
this.updateTransparency();
@@ -463,10 +486,15 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
return;
this.screen.addEventListener('mousemove', this, true);
+ ReferenceCounter.add('screen,mousemove,AHW,true');
this.treeStyleTab.tabStripPlaceHolder.addEventListener('mousemove', this, true);
+ ReferenceCounter.add('tabStripPlaceHolder,mousemove,AHW,true');
this.treeStyleTab.tabStrip.addEventListener('mousemove', this, true);
+ ReferenceCounter.add('tabStrip,mousemove,AHW,true');
this.toggler.addEventListener('mousemove', this, true);
+ ReferenceCounter.add('toggler,mousemove,AHW,true');
this.window.addEventListener('TabRemotenessChange', this, false);
+ ReferenceCounter.add('window,TabRemotenessChange,AHW,false');
this.mouseMoveListening = true;
@@ -479,10 +507,15 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
return;
this.screen.removeEventListener('mousemove', this, true);
+ ReferenceCounter.remove('screen,mousemove,AHW,true');
this.treeStyleTab.tabStripPlaceHolder.removeEventListener('mousemove', this, true);
+ ReferenceCounter.remove('tabStripPlaceHolder,mousemove,AHW,true');
this.treeStyleTab.tabStrip.removeEventListener('mousemove', this, true);
+ ReferenceCounter.remove('tabStrip,mousemove,AHW,true');
this.toggler.removeEventListener('mousemove', this, true);
+ ReferenceCounter.remove('toggler,mousemove,AHW,true');
this.window.removeEventListener('TabRemotenessChange', this, false);
+ ReferenceCounter.remove('window,TabRemotenessChange,AHW,false');
this.mouseMoveListening = false;
@@ -502,8 +535,17 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
showHideOnMouseMove : function AHB_showHideOnMouseMove(aCoordinates)
{
+ var sv = this.treeStyleTab;
+ var b = this.browser;
+ var w = this.window;
+
+ var exapndedByUnknownReason = (
+ this.expanded &&
+ !(this.showHideReason & this.kSHOWN_BY_ANY_REASON)
+ );
var position = this.getMousePosition(aCoordinates);
- if (DEBUG) {
+
+ if (utils.isDebugging('autoHide')) {
let humanReadablePosition = [];
if (position & this.MOUSE_POSITION_OUTSIDE)
humanReadablePosition.push('outside');
@@ -513,20 +555,29 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
humanReadablePosition.push('near');
if (position & this.MOUSE_POSITION_SENSITIVE)
humanReadablePosition.push('sensitive');
+ let extraInfo = [];
+ if (sv.isPopupShown())
+ extraInfo.push('popupshown');
+ if (exapndedByUnknownReason)
+ extraInfo.push('expanded-by-unknown');
+ if (this.lastMouseDownTarget)
+ extraInfo.push('mousedown');
dump('showHideOnMouseMove: ' +
'('+aCoordinates.screenX + ', ' + aCoordinates.screenY + ') => ' +
- humanReadablePosition.join(', ') + '\n');
+ humanReadablePosition.join(', ') +
+ (extraInfo.length ? ('[' + extraInfo.join(', ') + ']') : '') +
+ '\n');
}
- if (position == this.MOUSE_POSITION_UNKNOWN)
+
+ if (sv.isPopupShown() ||
+ exapndedByUnknownReason ||
+ this.lastMouseDownTarget ||
+ position == this.MOUSE_POSITION_UNKNOWN)
return;
this.cancelShowHideOnMouseMove();
this.showHideContentsAreaScreen();
- var sv = this.treeStyleTab;
- var b = this.browser;
- var w = this.window;
-
var shouldShow = position & this.MOUSE_POSITION_SENSITIVE;
if (this.expanded) { // currently shown, let's hide it.
if (shouldShow) {
@@ -839,7 +890,7 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
this.showHideReason = aReason || this.showHideReason || this.kSHOWN_BY_UNKNOWN;
}
- if (DEBUG) {
+ if (utils.isDebugging('autoHide')) {
let givenReason = this._getHumanReadableReason(aReason);
let unifiedReason = this._getHumanReadableReason(this.showHideReason);
if (this.expanded)
@@ -1091,14 +1142,16 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
if (!this.window.TreeStyleTabService.shouldApplyNewPref('tabbar.autoHide.mode'))
return;
this.browser.setAttribute(this.kMODE+'-normal', value);
- this.updateMode(value);
+ if (!this.window.fullScreen)
+ this.updateMode(value);
return;
case 'extensions.treestyletab.tabbar.autoHide.mode.fullscreen':
if (!this.window.TreeStyleTabService.shouldApplyNewPref('tabbar.autoHide.mode.fullscreen'))
return;
this.browser.setAttribute(this.kMODE+'-fullscreen', value);
- this.updateMode(value);
+ if (this.window.fullScreen)
+ this.updateMode(value);
return;
case 'extensions.treestyletab.tabbar.autoShow.mousemove':
@@ -1156,6 +1209,11 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
return this.onMouseDown(aEvent);
case 'mouseup':
+ // Note, we must handle "drop" event also to handle the end
+ // of drag-and-drop of a tab due to the bug:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=460801
+ case 'dragend':
+ case 'drop':
return this.onMouseUp(aEvent);
case 'mousemove':
@@ -1271,7 +1329,8 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
onMouseUp : function AHB_onMouseUp(aEvent)
{
var sv = this.treeStyleTab;
- if (aEvent.originalTarget &&
+ if (this.isResizing &&
+ aEvent.originalTarget &&
sv.evaluateXPath(
'ancestor-or-self::*[@class="'+sv.kSPLITTER+'"]',
aEvent.originalTarget,
@@ -1291,15 +1350,7 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
/^(scrollbar|thumb|slider|scrollbarbutton)$/i.test(this.lastMouseDownTarget || ''))
return true;
- if (
- !aEvent.shiftKey &&
- !sv.isPopupShown() &&
- (
- !this.expanded ||
- this.showHideReason & this.kSHOWN_BY_ANY_REASON
- ) &&
- !this.lastMouseDownTarget
- )
+ if (!aEvent.shiftKey)
this.showHideOnMouseMove(aEvent);
return true;
},
@@ -1421,14 +1472,23 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
this.onPrefChange('extensions.treestyletab.tabbar.autoHide.contentAreaScreen.enabled');
b.mTabContainer.addEventListener('TabOpen', this, false);
+ ReferenceCounter.add('mTabContainer,TabOpen,AHW,false');
b.mTabContainer.addEventListener('TabClose', this, false);
+ ReferenceCounter.add('mTabContainer,TabClose,AHW,false');
b.mTabContainer.addEventListener('TabMove', this, false);
+ ReferenceCounter.add('mTabContainer,TabMove,AHW,false');
b.mTabContainer.addEventListener('select', this, false);
+ ReferenceCounter.add('mTabContainer,select,AHW,false');
b.addEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGING, this, false);
+ ReferenceCounter.add('b,kEVENT_TYPE_TABBAR_POSITION_CHANGING,AHW,false');
b.addEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGED, this, false);
+ ReferenceCounter.add('b,kEVENT_TYPE_TABBAR_POSITION_CHANGED,AHW,false');
b.addEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN, this, false);
+ ReferenceCounter.add('b,kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN,AHW,false');
b.addEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_START, this, false);
+ ReferenceCounter.add('b,kEVENT_TYPE_TAB_FOCUS_SWITCHING_START,AHW,false');
b.addEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END, this, false);
+ ReferenceCounter.add('b,kEVENT_TYPE_TAB_FOCUS_SWITCHING_END,AHW,false');
},
destroy : function AHB_destroy()
@@ -1439,14 +1499,23 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
var sv = this.treeStyleTab;
var b = this.browser;
b.mTabContainer.removeEventListener('TabOpen', this, false);
+ ReferenceCounter.remove('mTabContainer,TabOpen,AHW,false');
b.mTabContainer.removeEventListener('TabClose', this, false);
+ ReferenceCounter.remove('mTabContainer,TabClose,AHW,false');
b.mTabContainer.removeEventListener('TabMove', this, false);
+ ReferenceCounter.remove('mTabContainer,TabMove,AHW,false');
b.mTabContainer.removeEventListener('select', this, false);
+ ReferenceCounter.remove('mTabContainer,select,AHW,false');
b.removeEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGING, this, false);
+ ReferenceCounter.remove('b,kEVENT_TYPE_TABBAR_POSITION_CHANGING,AHW,false');
b.removeEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGED, this, false);
+ ReferenceCounter.remove('b,kEVENT_TYPE_TABBAR_POSITION_CHANGED,AHW,false');
b.removeEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN, this, false);
+ ReferenceCounter.remove('b,kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN,AHW,false');
b.removeEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_START, this, false);
+ ReferenceCounter.remove('b,kEVENT_TYPE_TAB_FOCUS_SWITCHING_START,AHW,false');
b.removeEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END, this, false);
+ ReferenceCounter.remove('b,kEVENT_TYPE_TAB_FOCUS_SWITCHING_END,AHW,false');
delete this.treeStyleTab;
delete this.browser;
@@ -1590,6 +1659,7 @@ AutoHideWindow.prototype = inherit(AutoHideBase.prototype, {
this.waitingForWindowReady = true;
this.window.addEventListener('SSWindowStateReady', this, false);
+ ReferenceCounter.add('window,SSWindowStateReady,AHW,false');
Services.obs.addObserver(this, 'browser-delayed-startup-finished', false);
},
@@ -1600,6 +1670,7 @@ AutoHideWindow.prototype = inherit(AutoHideBase.prototype, {
this.waitingForWindowReady = false;
this.window.removeEventListener('SSWindowStateReady', this, false);
+ ReferenceCounter.remove('window,SSWindowStateReady,AHW,false');
Services.obs.removeObserver(this, 'browser-delayed-startup-finished');
},
diff --git a/modules/base.js b/modules/base.js
index 3b0e385..778b454 100644
--- a/modules/base.js
+++ b/modules/base.js
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TreeStyleTabBase'];
+var EXPORTED_SYMBOLS = ['TreeStyleTabBase'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -149,7 +149,8 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
this.overrideExtensions();
}
catch(e) {
- dump(e+'\n');
+ if (utils.isDebugging('base'))
+ dump(e+'\n');
}
},
_initialized : false,
@@ -518,14 +519,15 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
var message = 'ERROR: accessed after destruction!';
var error = new Error(message);
- dump(message+'\n'+error.stack+'\n');
+ if (utils.isDebugging('base'))
+ dump(message+'\n'+error.stack.replace(/^/gm, ' ')+'\n');
throw error;
},
defaultErrorHandler : function TSTBase_defaultErrorHandler(aError)
{
if (aError.stack)
- Cu.reportError(aError.message+'\n'+aError.stack);
+ Cu.reportError(aError.message+'\n'+aError.stack.replace(/^/gm, ' '));
else
Cu.reportError(aError);
},
@@ -949,9 +951,9 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
{
var strip = this.tabStrip;
if (!strip) {
- if (DEBUG) {
+ if (utils.isDebugging('base')) {
dump('FAILED TO SET TABSTRIP ATTRIBUTE ' + aAttr + '=' + aValue + '\n');
- dump((new Error()).stack + '\n');
+ dump((new Error()).stack.replace(/^/gm, ' ') + '\n');
}
return;
}
@@ -1508,7 +1510,9 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
refId = aInsertBefore.getAttribute(this.kID);
}
- dump('Tree Style Tab: new child tab is requested.\n'+new Error().stack+'\n');
+ if (utils.isDebugging('base'))
+ dump('Tree Style Tab: new child tab is requested.\n'+
+ new Error().stack.replace(/^/gm, ' ')+'\n');
ownerBrowser.treeStyleTab.readiedToAttachNewTab = true;
ownerBrowser.treeStyleTab.readiedToAttachMultiple = aMultiple || false ;
@@ -1644,6 +1648,11 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
return false;
var ownerBrowser = this.getTabBrowserFromChild(browser);
+
+ if (ownerBrowser.treeStyleTab.readiedToAttachNewTab && utils.isDebugging('base'))
+ dump('Tree Style Tab: new child tab is canceled.\n'+
+ new Error().stack.replace(/^/gm, ' ')+'\n');
+
ownerBrowser.treeStyleTab.readiedToAttachNewTab = false;
ownerBrowser.treeStyleTab.readiedToAttachNewTabGroup = false;
ownerBrowser.treeStyleTab.readiedToAttachMultiple = false;
@@ -1834,7 +1843,8 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
aTab.label+'\n '+
aTab.getAttribute(this.kID);
}, this).join('\n');
- dump(message+'\n');
+ if (utils.isDebugging('base'))
+ dump(message+'\n');
break;
}
@@ -1846,7 +1856,8 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
aTab.label+'\n '+
aTab.getAttribute(this.kID);
}, this).join('\n');
- dump(message+'\n');
+ if (utils.isDebugging('base'))
+ dump(message+'\n');
}
tabs.push(parentTab);
@@ -1993,7 +2004,8 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
aTab.label+'\n '+
aTab.getAttribute(this.kID);
}, this).join('\n');
- dump(message+'\n');
+ if (utils.isDebugging('base'))
+ dump(message+'\n');
continue;
}
tabs.push(tab);
@@ -2077,19 +2089,8 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
if (!aTab)
return null;
- if (this.tabsHash) { // XPath-less implementation
- let tabs = this.getDescendantTabs(aTab);
- return tabs.length ? tabs[tabs.length-1] : null ;
- }
-
- var parent = aTab.getAttribute(this.kPARENT);
- return this.evaluateXPath(
- 'following-sibling::xul:tab['+
- (parent ? '@'+this.kPARENT+'="'+parent+'"' : 'not(@'+this.kPARENT+')' )+
- '][1]/preceding-sibling::xul:tab[1][not(@'+this.kID+'="'+aTab.getAttribute(this.kID)+'")]',
- aTab,
- Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
- ).singleNodeValue;
+ let tabs = this.getDescendantTabs(aTab);
+ return tabs.length ? tabs[tabs.length-1] : null ;
},
collectRootTabs : function TSTBase_collectRootTabs(aTabs) /* PUBLIC API */
diff --git a/modules/browser.js b/modules/browser.js
index be34f07..afd0948 100644
--- a/modules/browser.js
+++ b/modules/browser.js
@@ -36,9 +36,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TreeStyleTabBrowser'];
-
-const DEBUG = false;
+var EXPORTED_SYMBOLS = ['TreeStyleTabBrowser'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -47,6 +45,7 @@ const Cu = Components.utils;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Timer.jsm');
Cu.import('resource://treestyletab-modules/lib/inherit.jsm');
+Cu.import('resource://treestyletab-modules/ReferenceCounter.js');
XPCOMUtils.defineLazyModuleGetter(this, 'Services', 'resource://gre/modules/Services.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Promise', 'resource://gre/modules/Promise.jsm');
@@ -135,7 +134,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
startProp : 'top',
endProp : 'bottom',
- maxTreeLevelPhisical : false,
+ maxTreeLevelPhysical : false,
needRestoreTree : false,
@@ -825,16 +824,26 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.initTabbar(null, this.kTABBAR_TOP, true);
w.addEventListener('resize', this, true);
+ ReferenceCounter.add('w,resize,TSTBrowser,true');
w.addEventListener('beforecustomization', this, true);
+ ReferenceCounter.add('w,beforecustomization,TSTBrowser,true');
w.addEventListener('aftercustomization', this, false);
+ ReferenceCounter.add('w,aftercustomization,TSTBrowser,false');
w.addEventListener('customizationchange', this, false);
+ ReferenceCounter.add('w,customizationchange,TSTBrowser,false');
w.addEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
+ ReferenceCounter.add('w,kEVENT_TYPE_PRINT_PREVIEW_ENTERED,TSTBrowser,false');
w.addEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_EXITED, this, false);
+ ReferenceCounter.add('w,kEVENT_TYPE_PRINT_PREVIEW_EXITED,TSTBrowser,false');
w.addEventListener('tabviewframeinitialized', this, false);
+ ReferenceCounter.add('w,tabviewframeinitialized,TSTBrowser,false');
w.addEventListener(this.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END, this, false);
+ ReferenceCounter.add('w,kEVENT_TYPE_TAB_FOCUS_SWITCHING_END,TSTBrowser,false');
w.addEventListener('SSWindowStateBusy', this, false);
+ ReferenceCounter.add('w,SSWindowStateBusy,TSTBrowser,false');
b.addEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false);
+ ReferenceCounter.add('b,nsDOMMultipleTabHandlerTabsClosing,TSTBrowser,false');
w['piro.sakura.ne.jp'].tabsDragUtils.initTabBrowser(b);
@@ -870,28 +879,6 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.fixTooNarrowTabbar();
this.fireTabbarPositionEvent(false, 'top', position); /* PUBLIC API */
-
- if (this.timers['init'])
- clearTimeout(this.timers['init']);
-
- this.timers['init'] = setTimeout((function() {
- try {
- // This command is always enabled and the TabsOnTop can be enabled
- // by <tabbrowser>.updateVisibility().
- // So we have to reset TabsOnTop state on the startup.
- var toggleTabsOnTop = d.getElementById('cmd_ToggleTabsOnTop');
- var TabsOnTop = 'TabsOnTop' in w ? w.TabsOnTop : null ;
- if (TabsOnTop && TabsOnTop.syncUI && toggleTabsOnTop && this.isVertical) {
- toggleTabsOnTop.setAttribute('disabled', true);
- if (TabsOnTop.enabled && TabsOnTop.toggle)
- TabsOnTop.toggle();
- }
- }
- catch(e) {
- this.defaultErrorHandler(e);
- }
- delete this.timers['init'];
- }).bind(this), 0);
},
_initTabbrowserExtraContents : function TSTBrowser_initTabbrowserExtraContents()
@@ -934,6 +921,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var tabContextMenu = b.tabContextMenu ||
d.getAnonymousElementByAttribute(b, 'anonid', 'tabContextMenu');
tabContextMenu.addEventListener('popupshowing', this, false);
+ ReferenceCounter.add('tabContextMenu,popupshowing,TSTBrowser,false');
if (!('MultipleTabService' in w)) {
w.setTimeout(function(aSelf, aTabBrowser, aPopup) {
let suffix = '-tabbrowser-'+(aTabBrowser.id || 'instance-'+parseInt(Math.random() * 65000));
@@ -1011,7 +999,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var w = this.window;
this._DNDObserversInitialized = false;
w.addEventListener('mouseover', this, true);
+ ReferenceCounter.add('w,mouseover,TSTBrowser,true');
w.addEventListener('dragover', this, true);
+ ReferenceCounter.add('w,dragover,TSTBrowser,true');
},
_initDNDObservers : function TSTBrowser_initDNDObservers()
@@ -1024,7 +1014,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var w = this.window;
w.removeEventListener('mouseover', this, true);
+ ReferenceCounter.remove('w,mouseover,TSTBrowser,true');
w.removeEventListener('dragover', this, true);
+ ReferenceCounter.remove('w,dragover,TSTBrowser,true');
this._DNDObserversInitialized = true;
},
@@ -1633,11 +1625,13 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
return new Promise((function(aResolve, aReject) {
var onInitialized = (function() {
this.mTabBrowser.removeEventListener(this.kEVENT_TYPE_TABBAR_INITIALIZED, onInitialized, false);
+ ReferenceCounter.remove('mTabBrowser,kEVENT_TYPE_TABBAR_INITIALIZED,onInitialized,false');
if (!aIsTemporaryChange)
delete this._temporaryPosition;
aResolve();
}).bind(this);
this.mTabBrowser.addEventListener(this.kEVENT_TYPE_TABBAR_INITIALIZED, onInitialized, false);
+ ReferenceCounter.add('mTabBrowser,kEVENT_TYPE_TABBAR_INITIALIZED,onInitialized,false');
}).bind(this));
},
@@ -1647,27 +1641,46 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var tabContainer = b.mTabContainer;
tabContainer.addEventListener('TabOpen', this, true);
+ ReferenceCounter.add('tabContainer,TabOpen,TSTBrowser,true');
tabContainer.addEventListener('TabClose', this, true);
+ ReferenceCounter.add('tabContainer,TabClose,TSTBrowser,true');
tabContainer.addEventListener('TabMove', this, true);
+ ReferenceCounter.add('tabContainer,TabMove,TSTBrowser,true');
tabContainer.addEventListener('TabShow', this, true);
+ ReferenceCounter.add('tabContainer,TabShow,TSTBrowser,true');
tabContainer.addEventListener('TabHide', this, true);
+ ReferenceCounter.add('tabContainer,TabHide,TSTBrowser,true');
tabContainer.addEventListener('SSTabRestoring', this, true);
+ ReferenceCounter.add('tabContainer,SSTabRestoring,TSTBrowser,true');
tabContainer.addEventListener('SSTabRestored', this, true);
+ ReferenceCounter.add('tabContainer,SSTabRestored,TSTBrowser,true');
tabContainer.addEventListener('TabPinned', this, true);
+ ReferenceCounter.add('tabContainer,TabPinned,TSTBrowser,true');
tabContainer.addEventListener('TabUnpinned', this, true);
+ ReferenceCounter.add('tabContainer,TabUnpinned,TSTBrowser,true');
tabContainer.addEventListener('mouseover', this, true);
+ ReferenceCounter.add('tabContainer,mouseover,TSTBrowser,true');
tabContainer.addEventListener('mouseout', this, true);
+ ReferenceCounter.add('tabContainer,mouseout,TSTBrowser,true');
tabContainer.addEventListener('dblclick', this, true);
+ ReferenceCounter.add('tabContainer,dblclick,TSTBrowser,true');
tabContainer.addEventListener('select', this, true);
+ ReferenceCounter.add('tabContainer,select,TSTBrowser,true');
tabContainer.addEventListener('scroll', this, true);
+ ReferenceCounter.add('tabContainer,scroll,TSTBrowser,true');
var strip = this.tabStrip;
strip.addEventListener('MozMouseHittest', this, true); // to block default behaviors of the tab bar
+ ReferenceCounter.add('strip,MozMouseHittest,TSTBrowser,true');
strip.addEventListener('mousedown', this, true);
+ ReferenceCounter.add('strip,mousedown,TSTBrowser,true');
strip.addEventListener('click', this, true);
+ ReferenceCounter.add('strip,click,TSTBrowser,true');
this.scrollBox.addEventListener('overflow', this, true);
+ ReferenceCounter.add('scrollBox,overflow,TSTBrowser,true');
this.scrollBox.addEventListener('underflow', this, true);
+ ReferenceCounter.add('scrollBox,underflow,TSTBrowser,true');
},
_ensureNewSplitter : function TSTBrowser__ensureNewSplitter()
@@ -1678,13 +1691,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
// We always have to re-create splitter, because its "collapse"
// behavior becomes broken by repositioning of the tab bar.
if (splitter) {
- try {
- splitter.removeEventListener('mousedown', this.windowService, false);
- splitter.removeEventListener('mouseup', this.windowService, false);
- splitter.removeEventListener('dblclick', this.windowService, false);
- }
- catch(e) {
- }
+ this._destroyOldSplitter();
let oldSplitter = splitter;
splitter = oldSplitter.cloneNode(true);
oldSplitter.parentNode.removeChild(oldSplitter);
@@ -1713,13 +1720,15 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
// So, we have to turn the actual tab bar visible manually
// when the grippy is clicked.
let tabContainer = this.mTabBrowser.tabContainer;
- grippy.addEventListener('click', function() {
+ let grippyOnClick = function() {
tabContainer.ownerDocument.defaultView.setTimeout(function() {
var visible = grippy.getAttribute('state') != 'collapsed';
if (visible != tabContainer.visible)
tabContainer.visible = visible;
}, 0);
- }, true);
+ };
+ grippy.addEventListener('click', grippy.grippyOnClick, true);
+ ReferenceCounter.add('grippy,click,grippy.grippyOnClick,true');
splitter.appendChild(grippy);
}
@@ -1729,15 +1738,39 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
splitter.setAttribute('class', splitterClass);
splitter.addEventListener('mousedown', this.windowService, false);
+ ReferenceCounter.add('splitter,mousedown,windowService,false');
splitter.addEventListener('mouseup', this.windowService, false);
+ ReferenceCounter.add('splitter,mouseup,windowService,false');
splitter.addEventListener('dblclick', this.windowService, false);
+ ReferenceCounter.add('splitter,dblclick,windowService,false');
var ref = this.mTabBrowser.mPanelContainer;
ref.parentNode.insertBefore(splitter, ref);
+ this.splitter = splitter;
return splitter;
},
+ _destroyOldSplitter : function TSTBrowser_destroyOldSplitter(aChanging, aOldPosition, aNewPosition)
+ {
+ var d = this.document;
+ var splitter = this.splitter;
+ try {
+ splitter.removeEventListener('mousedown', this.windowService, false);
+ ReferenceCounter.remove('splitter,mousedown,windowService,false');
+ splitter.removeEventListener('mouseup', this.windowService, false);
+ ReferenceCounter.remove('splitter,mouseup,windowService,false');
+ splitter.removeEventListener('dblclick', this.windowService, false);
+ ReferenceCounter.remove('splitter,dblclick,windowService,false');
+ var grippy = splitter.firstChild;
+ grippy.removeEventListener('click', grippy.grippyOnClick, true);
+ ReferenceCounter.remove('grippy,click,grippy.grippyOnClick,true');
+ delete grippy.grippyOnClick;
+ }
+ catch(e) {
+ }
+ },
+
fireTabbarPositionEvent : function TSTBrowser_fireTabbarPositionEvent(aChanging, aOldPosition, aNewPosition)
{
if (aOldPosition == aNewPosition)
@@ -1766,13 +1799,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var d = this.document;
var b = this.mTabBrowser;
var orient;
- var toggleTabsOnTop = d.getElementById('cmd_ToggleTabsOnTop');
- var TabsOnTop = 'TabsOnTop' in w ? w.TabsOnTop : null ;
if (this.isVertical) {
orient = 'vertical';
this.fixed = this.fixed; // ensure set to the current orient
- if (toggleTabsOnTop)
- toggleTabsOnTop.setAttribute('disabled', true);
}
else {
orient = 'horizontal';
@@ -1785,57 +1814,12 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
// remove ordinal for "tabs on top" https://bugzilla.mozilla.org/show_bug.cgi?id=544815
if (this.position == 'top') {
this.removeTabStripAttribute('ordinal');
- if (TabsOnTop && !this.windowService.isPopupWindow &&
- this.windowService.initialized) {
- let currentState = TabsOnTop.enabled;
- let originalState = utils.getTreePref('tabsOnTop.originalState');
- if (originalState !== null &&
- currentState != originalState &&
- this.windowService.tabsOnTopChangingByUI &&
- !this.windowService.changingTabsOnTop)
- utils.setTreePref('tabsOnTop.originalState', currentState);
- // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=555987
- // This should be done when the value of the "ordinal" attribute
- // is modified dynamically. So, we don' have to do it before
- // the browser window is completely initialized.
- TabsOnTop.enabled = !currentState;
- if (this.timers['updateTabbarState_TabsOnTop'])
- clearTimeout(this.timers['updateTabbarState_TabsOnTop']);
- this.timers['updateTabbarState_TabsOnTop'] = setTimeout((function() {
- try {
- TabsOnTop.enabled = currentState;
- }
- catch(e) {
- this.defaultErrorHandler(e);
- }
- delete this.timers['updateTabbarState_TabsOnTop'];
- }).bind(this), 0);
- }
}
}
else {
this.fixed = false; // ensure set to the current orient
this.setTabStripAttribute('height', this.maxTabbarHeight(this.tabbarHeight, b));
}
- if (toggleTabsOnTop) {
- if (this.position == 'top')
- toggleTabsOnTop.removeAttribute('disabled');
- else
- toggleTabsOnTop.setAttribute('disabled', true);
- }
- }
-
- if (TabsOnTop && !this.windowService.isPopupWindow) {
- let updateTabsOnTop = (function() {
- this.windowService.updateTabsOnTop();
- }).bind(this);
- // TabsOnTop.enabled is always "false" before the browser window is
- // completely initialized. So, we have to check it with delay only
- // on the Startup.
- if (this.initialized)
- updateTabsOnTop();
- else
- setTimeout(updateTabsOnTop, 0);
}
if (this.timers['updateTabbarState'])
@@ -1861,7 +1845,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.setTabbrowserAttribute(this.kALLOW_STACK, this.canStackTabs ? 'true' : null);
this.updateTabsZIndex(this.canStackTabs);
- if (this.maxTreeLevelPhisical)
+ if (this.maxTreeLevelPhysical)
this.promoteTooDeepLevelTabs();
this.updateAllTabsIndent();
@@ -1952,7 +1936,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
{
aReason = aReason || this.kTABBAR_UPDATE_BY_UNKNOWN_REASON;
- if (DEBUG) {
+ if (utils.isDebugging('browser')) {
let humanReadableReason =
(aReason & this.kTABBAR_UPDATE_BY_RESET ? 'reset ' : '' ) +
(aReason & this.kTABBAR_UPDATE_BY_PREF_CHANGE ? 'prefchange ' : '' ) +
@@ -2088,11 +2072,19 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
else
this.positionPinnedTabsWithDelay(null, null, aReason & this.kTABBAR_UPDATE_BY_AUTOHIDE);
- if (!collapsed && aReason & this.kTABBAR_UPDATE_BY_AUTOHIDE)
- setTimeout((function() {
- if (this.browser) // ignore calling after destroyed...
- this.scrollToTab(this.browser.selectedTab);
- }).bind(this), 0);
+ this.notifyingRenderedEvent = true;
+ var event = d.createEvent('Events');
+ event.initEvent(this.kEVENT_TYPE_TABBAR_RENDERED, true, false);
+ this.mTabBrowser.tabContainer.dispatchEvent(event);
+
+ setTimeout((function() {
+ this.notifyingRenderedEvent = false;
+
+ if (!collapsed &&
+ aReason & this.kTABBAR_UPDATE_BY_AUTOHIDE &&
+ this.browser) // ignore calling after destroyed...
+ this.scrollToTab(this.browser.selectedTab);
+ }).bind(this), 0);
},
getTabbarPlaceholderSize: function TSTBrowser_getTabbarPlaceholderSize()
{
@@ -2274,9 +2266,6 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
delete this.timers[key];
}, this);
- this.autoHide.destroy();
- delete this._autoHide;
-
this._initDNDObservers(); // ensure initialized
this.tabbarDNDObserver.destroy();
delete this._tabbarDNDObserver;
@@ -2293,6 +2282,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
delete this.tabStripPlaceHolderBoxObserver;
}
+ this._destroyOldSplitter();
+
var w = this.window;
var d = this.document;
var b = this.mTabBrowser;
@@ -2309,23 +2300,37 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this._endListenTabbarEvents();
+ this.autoHide.destroy();
+ this._autoHide = undefined; // block to be re-initialized by property accesses
+
w.removeEventListener('resize', this, true);
+ ReferenceCounter.remove('w,resize,TSTBrowser,true');
w.removeEventListener('beforecustomization', this, true);
+ ReferenceCounter.remove('w,beforecustomization,TSTBrowser,true');
w.removeEventListener('aftercustomization', this, false);
+ ReferenceCounter.remove('w,aftercustomization,TSTBrowser,false');
w.removeEventListener('customizationchange', this, false);
+ ReferenceCounter.remove('w,customizationchange,TSTBrowser,false');
w.removeEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
+ ReferenceCounter.remove('w,kEVENT_TYPE_PRINT_PREVIEW_ENTERED,TSTBrowser,false');
w.removeEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_EXITED, this, false);
+ ReferenceCounter.remove('w,kEVENT_TYPE_PRINT_PREVIEW_EXITED,TSTBrowser,false');
w.removeEventListener('tabviewframeinitialized', this, false);
+ ReferenceCounter.remove('w,tabviewframeinitialized,TSTBrowser,false');
w.removeEventListener(this.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END, this, false);
+ ReferenceCounter.remove('w,kEVENT_TYPE_TAB_FOCUS_SWITCHING_END,TSTBrowser,false');
w.removeEventListener('SSWindowStateBusy', this, false);
+ ReferenceCounter.remove('w,SSWindowStateBusy,TSTBrowser,false');
b.removeEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false);
+ ReferenceCounter.remove('b,nsDOMMultipleTabHandlerTabsClosing,TSTBrowser,false');
w['piro.sakura.ne.jp'].tabsDragUtils.destroyTabBrowser(b);
var tabContextMenu = b.tabContextMenu ||
d.getAnonymousElementByAttribute(b, 'anonid', 'tabContextMenu');
tabContextMenu.removeEventListener('popupshowing', this, false);
+ ReferenceCounter.remove('tabContextMenu,popupshowing,TSTBrowser,false');
if (this.tabbarCanvas) {
this.tabbarCanvas.parentNode.removeChild(this.tabbarCanvas);
@@ -2354,7 +2359,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
if (aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave) {
this.document.removeEventListener('mouseover', aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave, true);
+ ReferenceCounter.remove('document,mouseover,aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave,true');
this.document.removeEventListener('mouseout', aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave, true);
+ ReferenceCounter.remove('document,mouseout,aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave,true');
delete aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave;
}
@@ -2372,27 +2379,46 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var tabContainer = b.mTabContainer;
tabContainer.removeEventListener('TabOpen', this, true);
+ ReferenceCounter.remove('tabContainer,TabOpen,TSTBrowser,true');
tabContainer.removeEventListener('TabClose', this, true);
+ ReferenceCounter.remove('tabContainer,TabClose,TSTBrowser,true');
tabContainer.removeEventListener('TabMove', this, true);
+ ReferenceCounter.remove('tabContainer,TabMove,TSTBrowser,true');
tabContainer.removeEventListener('TabShow', this, true);
+ ReferenceCounter.remove('tabContainer,TabShow,TSTBrowser,true');
tabContainer.removeEventListener('TabHide', this, true);
+ ReferenceCounter.remove('tabContainer,TabHide,TSTBrowser,true');
tabContainer.removeEventListener('SSTabRestoring', this, true);
+ ReferenceCounter.remove('tabContainer,SSTabRestoring,TSTBrowser,true');
tabContainer.removeEventListener('SSTabRestored', this, true);
+ ReferenceCounter.remove('tabContainer,SSTabRestored,TSTBrowser,true');
tabContainer.removeEventListener('TabPinned', this, true);
+ ReferenceCounter.remove('tabContainer,TabPinned,TSTBrowser,true');
tabContainer.removeEventListener('TabUnpinned', this, true);
+ ReferenceCounter.remove('tabContainer,TabUnpinned,TSTBrowser,true');
tabContainer.removeEventListener('mouseover', this, true);
+ ReferenceCounter.remove('tabContainer,mouseover,TSTBrowser,true');
tabContainer.removeEventListener('mouseout', this, true);
+ ReferenceCounter.remove('tabContainer,mouseout,TSTBrowser,true');
tabContainer.removeEventListener('dblclick', this, true);
+ ReferenceCounter.remove('tabContainer,dblclick,TSTBrowser,true');
tabContainer.removeEventListener('select', this, true);
+ ReferenceCounter.remove('tabContainer,select,TSTBrowser,true');
tabContainer.removeEventListener('scroll', this, true);
+ ReferenceCounter.remove('tabContainer,scroll,TSTBrowser,true');
var strip = this.tabStrip;
strip.removeEventListener('MozMouseHittest', this, true);
+ ReferenceCounter.remove('strip,MozMouseHittest,TSTBrowser,true');
strip.removeEventListener('mousedown', this, true);
+ ReferenceCounter.remove('strip,mousedown,TSTBrowser,true');
strip.removeEventListener('click', this, true);
+ ReferenceCounter.remove('strip,click,TSTBrowser,true');
this.scrollBox.removeEventListener('overflow', this, true);
+ ReferenceCounter.remove('scrollBox,overflow,TSTBrowser,true');
this.scrollBox.removeEventListener('underflow', this, true);
+ ReferenceCounter.remove('scrollBox,underflow,TSTBrowser,true');
},
saveCurrentState : function TSTBrowser_saveCurrentState()
@@ -2428,9 +2454,11 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
return new Promise((function(aResolve, aReject) {
var onRestored = (function() {
this.mTabBrowser.removeEventListener(this.kEVENT_TYPE_TABBAR_POSITION_CHANGED, onRestored, false);
+ ReferenceCounter.remove('mTabBrowser,kEVENT_TYPE_TABBAR_POSITION_CHANGED,onRestored,false');
aResolve();
}).bind(this);
this.mTabBrowser.addEventListener(this.kEVENT_TYPE_TABBAR_POSITION_CHANGED, onRestored, false);
+ ReferenceCounter.add('mTabBrowser,kEVENT_TYPE_TABBAR_POSITION_CHANGED,onRestored,false');
}).bind(this))
.then(this.destroyTabbarPostProcess.bind(this));
}
@@ -2533,8 +2561,10 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
if (aPopup.state == 'open') {
aPopup.addEventListener('popuphidden', function onPopuphidden(aEvent) {
aPopup.removeEventListener(aEvent.type, onPopuphidden, false);
+ ReferenceCounter.remove('aPopup,popuphidden,onPopuphidden,false');
aPopup.parentNode.removeChild(aPopup);
}, false);
+ ReferenceCounter.add('aPopup,popuphidden,onPopuphidden,false');
aPopup.hidePopup();
}
else {
@@ -2702,8 +2732,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
case 'extensions.treestyletab.tabbar.narrowScrollbar':
return this.setTabbrowserAttribute(this.kNARROW_SCROLLBAR, value);
- case 'extensions.treestyletab.maxTreeLevel.phisical':
- if (this.maxTreeLevelPhisical = value)
+ case 'extensions.treestyletab.maxTreeLevel.physical':
+ if (this.maxTreeLevelPhysical = value)
this.promoteTooDeepLevelTabs();
return;
@@ -3047,6 +3077,15 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var pareintIndexInTree = hasStructure ? this.treeStructure.shift() : 0 ;
var lastRelatedTab = b._lastRelatedTab;
+ if (utils.isDebugging('browser')) {
+ dump('TSTBrowser_onTabOpen\n ' + [
+ 'readiedToAttachNewTab: '+this.readiedToAttachNewTab,
+ 'parentTab: '+this.parentTab + ' (' + this.getTabById(this.parentTab) + ')',
+ 'insertBefore: '+this.insertBefore,
+ 'treeStructure: '+this.treeStructure
+ ].join('\n ') + '\n');
+ }
+
if (this.readiedToAttachNewTab) {
if (pareintIndexInTree < 0) { // there is no parent, so this is a new parent!
this.parentTab = tab.getAttribute(this.kID);
@@ -3167,19 +3206,50 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
updateInsertionPositionInfo : function TSTBrowser_updateInsertionPositionInfo(aTab)
{
- if (!aTab.parentNode) // do nothing for closed tab!
+ if (!aTab ||
+ !aTab.parentNode) // do nothing for closed tab!
return;
var prev = this.getPreviousSiblingTab(aTab);
if (prev) {
this.setTabValue(aTab, this.kINSERT_AFTER, prev.getAttribute(this.kID));
this.setTabValue(prev, this.kINSERT_BEFORE, aTab.getAttribute(this.kID));
+ } else {
+ this.deleteTabValue(aTab, this.kINSERT_AFTER);
}
var next = this.getNextSiblingTab(aTab);
if (next) {
this.setTabValue(aTab, this.kINSERT_BEFORE, next.getAttribute(this.kID));
this.setTabValue(next, this.kINSERT_AFTER, aTab.getAttribute(this.kID));
+ } else {
+ this.deleteTabValue(aTab, this.kINSERT_BEFORE);
+ }
+ },
+
+ closeUpInsertionPositionInfoAround : function TSTBrowser_closeUpInsertionPositionInfoAround(aTab)
+ {
+ if (!aTab ||
+ !aTab.parentNode) // do nothing for closed tab!
+ return;
+
+ var prev = this.getPreviousSiblingTab(aTab);
+ var next = this.getNextSiblingTab(aTab);
+ if (prev) {
+ this.setTabValue(aTab, this.kINSERT_AFTER, prev.getAttribute(this.kID));
+
+ if (next)
+ this.setTabValue(prev, this.kINSERT_BEFORE, next.getAttribute(this.kID));
+ else
+ this.deleteTabValue(prev, this.kINSERT_BEFORE);
+ }
+ if (next) {
+ this.setTabValue(aTab, this.kINSERT_BEFORE, next.getAttribute(this.kID));
+
+ if (prev)
+ this.setTabValue(next, this.kINSERT_AFTER, prev.getAttribute(this.kID));
+ else
+ this.deleteTabValue(next, this.kINSERT_AFTER);
}
},
@@ -3197,15 +3267,13 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var closeParentBehavior = this.getCloseParentBehaviorForTab(tab);
var backupAttributes = this._collectBackupAttributes(tab);
- if (DEBUG)
+ if (utils.isDebugging('browser'))
dump('onTabClose: backupAttributes = '+JSON.stringify(backupAttributes)+'\n');
if (closeParentBehavior == this.kCLOSE_PARENT_BEHAVIOR_CLOSE_ALL_CHILDREN ||
this.isSubtreeCollapsed(tab))
this._closeChildTabs(tab);
- this._saveAndUpdateReferenceTabsInfo(tab);
-
var firstChild = this.getFirstChildTab(tab);
this.detachAllChildren(tab, {
@@ -3357,28 +3425,6 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
}).bind(this), 0);
},
- _saveAndUpdateReferenceTabsInfo : function TSTBrowser_saveAndUpdateReferenceTabsInfo(aTab)
- {
- var prev = this.getPreviousSiblingTab(aTab);
- var next = this.getNextSiblingTab(aTab);
- if (prev) {
- this.setTabValue(aTab, this.kINSERT_AFTER, prev.getAttribute(this.kID));
-
- if (next)
- this.setTabValue(prev, this.kINSERT_BEFORE, next.getAttribute(this.kID));
- else
- this.deleteTabValue(prev, this.kINSERT_BEFORE);
- }
- if (next) {
- this.setTabValue(aTab, this.kINSERT_BEFORE, next.getAttribute(this.kID));
-
- if (prev)
- this.setTabValue(next, this.kINSERT_AFTER, prev.getAttribute(this.kID));
- else
- this.deleteTabValue(next, this.kINSERT_AFTER);
- }
- },
-
_restoreTabAttributes : function TSTBrowser_restoreTabAttributes(aTab, aAttributes)
{
for (var i in aAttributes)
@@ -3473,52 +3519,29 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.moveTabSubtreeTo(tab, tab._tPos);
}
- var parentTab = this.getParentTab(tab);
- if (parentTab && !this.subTreeChildrenMovingCount) {
- this.updateChildrenArray(parentTab);
- }
-
this.updateTabsCount(tab, true);
- var prev = this.getPreviousSiblingTab(tab);
- var next = this.getNextSiblingTab(tab);
-
- if (prev) {
- this.setTabValue(prev, this.kINSERT_BEFORE, tab.getAttribute(this.kID));
- this.setTabValue(tab, this.kINSERT_AFTER, prev.getAttribute(this.kID));
- }
- else
- this.deleteTabValue(tab, this.kINSERT_AFTER);
-
- if (next) {
- this.setTabValue(next, this.kINSERT_AFTER, tab.getAttribute(this.kID));
- this.setTabValue(tab, this.kINSERT_BEFORE, next.getAttribute(this.kID));
- }
- else
- this.deleteTabValue(tab, this.kINSERT_BEFORE);
-
- var old = aEvent.detail;
- if (old > tab._tPos)
- old--;
- var tabs = this.getAllTabs(b);
- old = tabs[old];
-
- prev = this.getPreviousSiblingTab(old);
- next = this.getNextSiblingTab(old);
+ var tabsToBeUpdated = [tab];
- if (prev) {
- this.setTabValue(prev, this.kINSERT_BEFORE, old.getAttribute(this.kID));
- this.setTabValue(old, this.kINSERT_AFTER, prev.getAttribute(this.kID));
+ var parentTab = this.getParentTab(tab);
+ if (parentTab) {
+ let children = this.getChildTabs(parentTab);
+ let oldChildIndex = children.indexOf(tab);
+ if (oldChildIndex > -1) {
+ if (oldChildIndex > 0) {
+ let oldPrevTab = children[oldChildIndex - 1];
+ tabsToBeUpdated.push(oldPrevTab);
+ }
+ if (oldChildIndex < children.lenght - 1) {
+ let oldNextTab = children[oldChildIndex + 1];
+ tabsToBeUpdated.push(oldNextTab);
+ }
+ }
+ if (!this.subTreeChildrenMovingCount)
+ this.updateChildrenArray(parentTab);
}
- else
- this.deleteTabValue(old, this.kINSERT_AFTER);
- if (next) {
- this.setTabValue(next, this.kINSERT_AFTER, old.getAttribute(this.kID));
- this.setTabValue(old, this.kINSERT_BEFORE, next.getAttribute(this.kID));
- }
- else
- this.deleteTabValue(old, this.kINSERT_BEFORE);
+ tabsToBeUpdated.forEach(this.updateInsertionPositionInfo, this);
this.positionPinnedTabsWithDelay();
@@ -3560,6 +3583,11 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
delta = Math.abs(pos - oldPos);
}
+ if (utils.isDebugging('browser')) {
+ dump('attachTabFromPosition '+aTab._tPos+' / '+aOldPosition+'\n');
+ dump((new Error()).stack.replace(/^/gm, ' ')+'\n');
+ }
+
var prevTab = this.getPreviousTab(aTab);
var nextTab = this.getNextTab(aTab);
@@ -3909,7 +3937,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
handleRestoredTab : function TSTBrowser_handleRestoredTab(aTab)
{
if (aTab.__treestyletab__restoreState === undefined) {
- if (DEBUG)
+ if (utils.isDebugging('browser'))
dump('handleRestoredTab: ' + aTab._tPos + ' is already restored!\n');
return false;
}
@@ -4138,7 +4166,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
var restoringMultipleTabs = this.windowService.restoringTree;
var position = this._prepareInsertionPosition(aTab, aMayBeDuplicated);
var parent = position.parent;
- if (DEBUG)
+ if (utils.isDebugging('browser'))
dump('handleRestoredTab: found parent = ' + parent+'\n');
if (parent) {
aTab.removeAttribute(this.kPARENT);
@@ -4185,7 +4213,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
}
var ancestors = (this.getTabValue(aTab, this.kANCESTORS) || this.getTabValue(aTab, this.kPARENT)).split('|');
- if (DEBUG)
+ if (utils.isDebugging('browser'))
dump('handleRestoredTab: ancestors = ' + ancestors+'\n');
var parent = null;
for (let i in ancestors)
@@ -4208,7 +4236,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
*/
if (!parent) {
parent = aTab.getAttribute(this.kPARENT);
- if (DEBUG)
+ if (utils.isDebugging('browser'))
dump('handleRestoredTab: parent = ' + parent+'\n');
if (parent && !next)
next = this.getNextSiblingTab(aTab);
@@ -4421,6 +4449,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
let self = this;
aRestoredTab.addEventListener('SSTabRestoring', function onSSTabRestoring(aEvent) {
aRestoredTab.removeEventListener(aEvent.type, onSSTabRestoring, false);
+ ReferenceCounter.remove('aRestoredTab,SSTabRestoring,onSSTabRestoring,false');
self.askUndoCloseTabSetBehavior(aRestoredTab, indexes.length)
.then(function(aBehavior) {
if (aBehavior & self.kUNDO_CLOSE_SET)
@@ -4430,6 +4459,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
Components.utils.reportError(aError);
});
}, false);
+ ReferenceCounter.add('aRestoredTab,SSTabRestoring,onSSTabRestoring,false');
}
else if (behavior & this.kUNDO_CLOSE_SET) {
this.doRestoreClosedSet(aRestoredTab, indexes);
@@ -4947,6 +4977,11 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
}
if (isContentResize || isChromeResize) {
+ if (utils.isDebugging('browser')) {
+ dump('TSTBrowser_onResize\n');
+ dump(' isContentResize = '+isContentResize+'\n');
+ dump(' isChromeResize = '+isChromeResize+'\n');
+ }
this.updateFloatingTabbar(this.kTABBAR_UPDATE_BY_WINDOW_RESIZE);
this.updateInvertedTabContentsOrder(true);
this.mTabBrowser.mTabContainer.adjustTabstrip();
@@ -5106,52 +5141,15 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
}
},
- onTabsOnTopSyncCommand : function TSTBrowser_onTabsOnTopSyncCommand(aEnabled)
- {
- if (
- this.windowService.tabsOnTopChangingByUI ||
- !aEnabled ||
- this.position != 'top' ||
- this.fixed ||
- this.windowService.isPopupWindow
- )
- return;
- this.windowService.tabsOnTopChangingByUI = true;
- if (this.timers['onTabsOnTopSyncCommand'])
- clearTimeout(this.timers['onTabsOnTopSyncCommand']);
- this.timers['onTabsOnTopSyncCommand'] = setTimeout((function() {
- Deferred.resolve()
- .then((function() {
- this.windowService.toggleFixed(this.mTabBrowser);
- return wait(0);
- }).bind(this))
- .then((function() {
- if (this.window.TabsOnTop.enabled != aEnabled)
- this.window.TabsOnTop.enabled = aEnabled;
- }).bind(this))
- .catch(this.defaultErrorHandler.bind(this))
- .then((function() {
- this.windowService.tabsOnTopChangingByUI = false;
- delete this.timers['onTabsOnTopSyncCommand'];
- }).bind(this));
- }).bind(this), 0);
- },
-
onBeforeFullScreenToggle : function TSTBrowser_onBeforeFullScreenToggle(aEnterFS)
{
if (this.position != 'top') {
- // entering to the DOM-fullscreen (ex. YouTube Player)
- if (this.document.mozFullScreen) {
- this.setTabbrowserAttribute(this.kDOM_FULLSCREEN_ACTIVATED, true);
- }
- else {
- if (this.document.documentElement.getAttribute(this.kDOM_FULLSCREEN_ACTIVATED) != 'true') {
- if (aEnterFS)
- this.autoHide.startForFullScreen();
- else
- this.autoHide.endForFullScreen();
- }
- this.removeTabbrowserAttribute(this.kDOM_FULLSCREEN_ACTIVATED);
+ // ignore entering to the DOM-fullscreen (ex. YouTube Player)
+ if (!this.document.mozFullScreen) {
+ if (aEnterFS)
+ this.autoHide.startForFullScreen();
+ else
+ this.autoHide.endForFullScreen();
}
}
},
@@ -5292,7 +5290,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
if (aParent) {
newAncestors = [aParent].concat(this.getAncestorTabs(aParent));
- if (this.maxTreeLevelPhisical && this.maxTreeLevel > -1) {
+ if (this.maxTreeLevelPhysical && this.maxTreeLevel > -1) {
let level = parseInt(aParent.getAttribute(this.kNEST) || 0) + 1;
newAncestors.some(function(aAncestor) {
if (level <= this.maxTreeLevel)
@@ -5467,6 +5465,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
if (!parentTab)
return;
+ if (!aInfo.dontUpdateInsertionPositionInfo)
+ this.closeUpInsertionPositionInfoAround(aChild);
+
var id = aChild.getAttribute(this.kID);
this.setTabValue(
@@ -5527,6 +5528,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
if (aInfo.behavior == this.kCLOSE_PARENT_BEHAVIOR_CLOSE_ALL_CHILDREN)
aInfo.behavior = this.kCLOSE_PARENT_BEHAVIOR_PROMOTE_FIRST_CHILD;
+ aInfo.dontUpdateInsertionPositionInfo = true;
+
var b = this.mTabBrowser;
var parentTab = this.getParentTab(aTab);
@@ -5926,7 +5929,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
promoteTooDeepLevelTabs : function TSTBrowser_promoteTooDeepLevelTabs(aParent)
{
- if (this.maxTreeLevel < 0 || !this.maxTreeLevelPhisical)
+ if (this.maxTreeLevel < 0 || !this.maxTreeLevelPhysical)
return;
var tabs = aParent ? this.getDescendantTabs(aParent) : this.getAllTabs(this.mTabBrowser) ;
@@ -6258,12 +6261,16 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
if (x > rect.left && x < rect.right && y > rect.top && y < rect.bottom)
return;
self.document.removeEventListener('mouseover', aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave, true);
+ ReferenceCounter.remove('document,mouseover,aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave,true');
self.document.removeEventListener('mouseout', aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave, true);
+ ReferenceCounter.remove('document,mouseout,aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave,true');
delete aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave;
self.checkTabsIndentOverflow();
};
this.document.addEventListener('mouseover', aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave, true);
+ ReferenceCounter.add('document,mouseover,aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave,true');
this.document.addEventListener('mouseout', aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave, true);
+ ReferenceCounter.add('document,mouseout,aTab.__treestyletab__checkTabsIndentOverflowOnMouseLeave,true');
}
}
},
@@ -6873,9 +6880,12 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
Components.utils.reportError(new Error('There is no property named "_browserEpochs"!!'));
}
- dump('TSTBrowser::restoreTree\n');
- dump(' level = '+level+'\n');
- dump(' tabsToRestore = '+tabsToRestore+'\n');
+ if (utils.isDebugging('browser')) {
+ dump('TSTBrowser::restoreTree\n');
+ dump(' level = '+level+'\n');
+ dump(' tabsToRestore = '+tabsToRestore+'\n');
+ }
+
if (
level <= this.kRESTORE_TREE_LEVEL_NONE ||
tabsToRestore <= 1
@@ -6896,7 +6906,10 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
(!onlyVisible || !aTab.hidden)
);
});
- dump(' restoring member tabs = '+tabs.length+' ('+tabs.map(function(aTab) { return aTab._tPos; })+')\n');
+
+ if (utils.isDebugging('browser'))
+ dump(' restoring member tabs = '+tabs.length+' ('+tabs.map(function(aTab) { return aTab._tPos; })+')\n');
+
if (tabs.length <= 1)
return;
@@ -6994,8 +7007,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
isPopupShown : function TSTBrowser_isPopupShown(...aArgs) {
return this._callWindowServiceMethod('isPopupShown', aArgs);
},
- updateTabsOnTop : function TSTBrowser_updateTabsOnTop(...aArgs) {
- return this._callWindowServiceMethod('updateTabsOnTop', aArgs);
+ updateTabsInTitlebar : function TSTBrowser_updateTabsInTitlebar(...aArgs) {
+ return this._callWindowServiceMethod('updateTabsInTitlebar', aArgs);
},
registerTabFocusAllowance : function TSTBrowser_registerTabFocusAllowance(...aArgs) {
return this._callWindowServiceMethod('registerTabFocusAllowance', aArgs);
@@ -7010,7 +7023,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
/* show/hide tab bar */
get autoHide()
{
- if (!this._autoHide) {
+ if (!('_autoHide' in this)) {
this._autoHide = new AutoHideBrowser(this.mTabBrowser);
}
return this._autoHide;
@@ -7063,7 +7076,38 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
cancelShowHideTabbarOnMousemove : function TSTBrowser_cancelShowHideTabbarOnMousemove() { this.autoHide.cancelShowHideOnMousemove(); },
showTabbarForFeedback : function TSTBrowser_showTabbarForFeedback() { this.autoHide.showForFeedback(); },
delayedShowTabbarForFeedback : function TSTBrowser_delayedShowTabbarForFeedback() { this.autoHide.delayedShowForFeedback(); },
- cancelHideTabbarForFeedback : function TSTBrowser_cancelHideTabbarForFeedback() { this.autoHide.cancelHideForFeedback(); }
+ cancelHideTabbarForFeedback : function TSTBrowser_cancelHideTabbarForFeedback() { this.autoHide.cancelHideForFeedback(); },
+ // DEBUGGING
+ dumpTreeInformation : function() {
+ var ids = [];
+ var extraAttributes = {
+ children: this.kCHILDREN,
+ restoringChildren: this.kCHILDREN_RESTORING,
+ parent: this.kPARENT,
+ insertBefore: this.kINSERT_BEFORE,
+ insertAfter: this.kINSERT_AFTER
+ };
+ var result = this.rootTabs.map(function scanTab(aTab) {
+ var id = this.getTabValue(aTab, this.kID);
+ ids.push(id);
+ var result = { id: id };
+ Object.keys(extraAttributes).forEach(function(aKey) {
+ var value = this.getTabValue(aTab, extraAttributes[aKey]);
+ if (value)
+ result[aKey] = value;
+ }, this);
+ var children = this.getChildTabs(aTab).map(scanTab, this);
+ if (children.length > 0)
+ result.actualChildren = children;
+ return result;
+ }, this);
+ var json = JSON.stringify(result);
+ ids.forEach(function(aId, aIndex) {
+ json = json.replace(new RegExp(aId, 'g'), 'TAB-' + aIndex);
+ });
+ return JSON.parse(json);
+ }
+
});
diff --git a/modules/browserUIShowHideObserver.js b/modules/browserUIShowHideObserver.js
index df1bae0..ac5b391 100644
--- a/modules/browserUIShowHideObserver.js
+++ b/modules/browserUIShowHideObserver.js
@@ -34,16 +34,18 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['BrowserUIShowHideObserver'];
+var EXPORTED_SYMBOLS = ['BrowserUIShowHideObserver'];
-var DEBUG = false;
+Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
Components.utils.import('resource://treestyletab-modules/constants.js');
-function BrowserUIShowHideObserver(aOwner, aBox) {
+XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
+
+function BrowserUIShowHideObserver(aOwner, aBox, aOptions) {
this.owner = aOwner;
this.box = aBox;
- this.init();
+ this.init(aOptions);
}
BrowserUIShowHideObserver.prototype = {
get MutationObserver()
@@ -52,18 +54,18 @@ BrowserUIShowHideObserver.prototype = {
return w.MutationObserver || w.MozMutationObserver;
},
- init : function BrowserUIShowHideObserver_onInit()
+ init : function BrowserUIShowHideObserver_onInit(aOptions)
{
if (!this.MutationObserver)
return;
this.observer = new this.MutationObserver((function(aMutations, aObserver) {
this.onMutation(aMutations, aObserver);
}).bind(this));
- this.observer.observe(this.box, {
+ var options = {
childList : true,
attributes : true,
subtree : true,
- attributeOldValue: DEBUG,
+ attributeOldValue: utils.isDebugging('browserUIShowHideObserver'),
attributeFilter : [
'hidden',
'collapsed',
@@ -72,21 +74,36 @@ BrowserUIShowHideObserver.prototype = {
'width',
'height'
]
- });
+ };
+ if (aOptions) {
+ Object.keys(options).forEach(function(aKey) {
+ if (aKey in aOptions)
+ options[aKey] = aOptions[aKey];
+ });
+ }
+ this.observer.observe(this.box, options);
},
onMutation : function BrowserUIShowHideObserver_onMutation(aMutations, aObserver)
{
aMutations.forEach(function(aMutation) {
- switch (aMutation.type)
- {
- case 'childList':
- if (aMutation.target == this.box)
- this.owner.browser.treeStyleTab.updateFloatingTabbar(TreeStyleTabConstants.kTABBAR_UPDATE_BY_WINDOW_RESIZE);
- return;
-
- case 'attributes':
- this.onAttributeModified(aMutation, aObserver);
- return;
+ try {
+ switch (aMutation.type)
+ {
+ case 'childList':
+ if (aMutation.target == this.box) {
+ this.dumpMutation(aMutation, 'BrowserUIShowHideObserver_onMutation/childList');
+ this.owner.browser.treeStyleTab.updateFloatingTabbar(TreeStyleTabConstants.kTABBAR_UPDATE_BY_WINDOW_RESIZE);
+ }
+ return;
+
+ case 'attributes':
+ this.onAttributeModified(aMutation, aObserver);
+ return;
+ }
+ }
+ catch(error) {
+ this.dumpMutation(aMutation, 'BrowserUIShowHideObserver_onMutation(error)');
+ Components.utils.reportError(error);
}
}, this);
},
@@ -101,9 +118,31 @@ BrowserUIShowHideObserver.prototype = {
delete this.owner;
},
+ dumpMutation : function BrowserUIShowHideObserver_dumpMutation(aMutation, aDescription)
+ {
+ if (!utils.isDebugging('browserUIShowHideObserver'))
+ return;
+
+ var target = aMutation.target;
+ var ownerInformation = this.box.localName + '#' + this.box.id + '.' + this.box.className;
+ var targetInformation = target.localName + '#' + target.id + '.' + target.className;
+ var attributeInformation = '';
+ if (aMutation.attributeName)
+ attributeInformation = ' / ' +
+ aMutation.attributeName + ', ' +
+ aMutation.oldValue + ' => ' +
+ target.getAttribute(aMutation.attributeName);
+ dump(aDescription + ' ' +
+ ownerInformation + ' / ' +
+ targetInformation +
+ attributeInformation + '\n');
+ },
+
onAttributeModified : function BrowserUIShowHideObserver_onAttributeModified(aMutation, aObserver)
{
- if (this.handlingAttrChange)
+ var TST = this.owner.browser.treeStyleTab;
+ if (this.handlingAttrChange ||
+ TST.notifyingRenderedEvent)
return;
var target = aMutation.target;
@@ -111,7 +150,6 @@ BrowserUIShowHideObserver.prototype = {
if (target.__treestyletab_mutationObserver_lastState == state)
return;
- var TST = this.owner.browser.treeStyleTab;
if (
// ignore modifications of each tab
TST.getTabFromChild(target) ||
@@ -124,34 +162,58 @@ BrowserUIShowHideObserver.prototype = {
)
return;
- var toolbarVisible = !TST.ownerToolbar.collapsed;
- var tabbarVisible = this.owner.browser.tabContainer.visible;
- var placeHolderVisible = !TST.tabStripPlaceHolder.collapsed;
- var tabbarVisibilityMismatching = (
- toolbarVisible != placeHolderVisible ||
- tabbarVisible != placeHolderVisible
- );
+ var tabbar = this.owner.browser.tabContainer;
+ var placeHolder = TST.tabStripPlaceHolder;
+
+ var tabbarVisibilityMismatching = false;
+ {
+ let toolbarVisible = !TST.ownerToolbar.collapsed;
+ let tabbarVisible = tabbar.visible;
+ let placeHolderVisible = !placeHolder.collapsed;
+ tabbarVisibilityMismatching = (
+ toolbarVisible != placeHolderVisible ||
+ tabbarVisible != placeHolderVisible
+ );
+ }
+
+ var tabbarMatrixMismatching = false;
+ {
+ let tabbarBox = tabbar.boxObject;
+ let tabbarMatrix = JSON.stringify({
+ x: tabbarBox.screenX,
+ y: tabbarBox.screenY,
+ w: tabbarBox.width,
+ h: tabbarBox.height
+ });
+ let placeHolderBox = placeHolder.boxObject;
+ let placeHolderMatrix = JSON.stringify({
+ x: placeHolderBox.screenX,
+ y: placeHolderBox.screenY,
+ w: placeHolderBox.width,
+ h: placeHolderBox.height
+ });
+ tabbarMatrixMismatching = tabbarMatrix != placeHolderMatrix;
+ }
if (
// I must ignore show/hide of elements managed by TST,
// to avoid infinity loop.
- target.hasAttribute(TreeStyleTabConstants.kTAB_STRIP_ELEMENT) &&
+ TST.evaluateXPath(
+ 'ancestor-or-self::xul:*[@' + TreeStyleTabConstants.kTAB_STRIP_ELEMENT + '="true"]',
+ target,
+ Components.interfaces.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
+ ).singleNodeValue &&
// However, I have to synchronize visibility of the real
// tab bar and the placeholder's one. If they have
// different visibility, then the tab bar is shown or
// hidden by "auto hide tab bar" feature of someone
// (Pale Moon, Tab Mix Plus, etc.)
- !tabbarVisibilityMismatching
+ !tabbarVisibilityMismatching &&
+ !tabbarMatrixMismatching
)
return;
- if (DEBUG) {
- dump('BrowserUIShowHideObserver_onAttributeModified ' +
- target.localName + '#' + target.id + '.' + target.className + ', ' +
- aMutation.attributeName + ', ' +
- aMutation.oldValue + ' => ' +
- target.getAttribute(aMutation.attributeName) + '\n');
- }
+ this.dumpMutation(aMutation, 'BrowserUIShowHideObserver_onAttributeModified');
this.handlingAttrChange = true;
diff --git a/modules/constants.js b/modules/constants.js
index c1d4cbe..a3578ce 100644
--- a/modules/constants.js
+++ b/modules/constants.js
@@ -34,9 +34,9 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TreeStyleTabConstants'];
+var EXPORTED_SYMBOLS = ['TreeStyleTabConstants'];
-const TreeStyleTabConstants = Object.freeze({
+var TreeStyleTabConstants = Object.freeze({
/* attributes */
kID : 'treestyletab-id',
kCHILDREN : 'treestyletab-children',
@@ -82,7 +82,6 @@ const TreeStyleTabConstants = Object.freeze({
kFAVICONIZED : 'treestyletab-faviconized',
kBG_NOTIFY_PHASE : 'treestyletab-notifybgtab-phase',
kIGNORE_POPUP_STATE : 'treestyletab-ignore-state',
- kDOM_FULLSCREEN_ACTIVATED : 'treestyletab-dom-fullscreen-activated',
kTAB_INVERTED : 'treestyletab-tab-inverted',
kTAB_CONTENTS_INVERTED : 'treestyletab-tab-contents-inverted',
@@ -132,6 +131,7 @@ const TreeStyleTabConstants = Object.freeze({
kEVENT_TYPE_TABBAR_POSITION_CHANGED : 'nsDOMTreeStyleTabTabbarPositionChanged',
kEVENT_TYPE_TABBAR_STATE_CHANGING : 'nsDOMTreeStyleTabTabbarStateChanging',
kEVENT_TYPE_TABBAR_STATE_CHANGED : 'nsDOMTreeStyleTabTabbarStateChanged',
+ kEVENT_TYPE_TABBAR_RENDERED : 'nsDOMTreeStyleTabTabbarRendered',
kEVENT_TYPE_FOCUS_NEXT_TAB : 'nsDOMTreeStyleTabFocusNextTab',
kEVENT_TYPE_ATTACHED : 'nsDOMTreeStyleTabAttached',
kEVENT_TYPE_DETACHED : 'nsDOMTreeStyleTabParted',
@@ -218,11 +218,12 @@ const TreeStyleTabConstants = Object.freeze({
RESTORE_STATE_STRUCTURE_RESTORED : 2,
-// CONTENT_SCRIPT : 'chrome://treestyletab/content/content-utils.js',
+ CONTENT_SCRIPT : 'chrome://treestyletab/content/content-utils.js',
CONTENT_SCRIPT_AUTOHIDE : 'chrome://treestyletab/content/content-utils-autohide.js',
MESSAGE_TYPE : 'treestyletab',
COMMAND_SHUTDOWN : 'shutdown',
+ COMMAND_REPORT_SELECTION_CHANGE : 'report-selection-change',
COMMAND_REPORT_MOUSEDOWN : 'report-mousedown',
COMMAND_REPORT_MOUSEUP : 'report-mouseup',
COMMAND_REPORT_MOUSEMOVE : 'report-mousemove',
diff --git a/modules/contentBridge.js b/modules/contentBridge.js
index 8a90fd7..d7f34a4 100644
--- a/modules/contentBridge.js
+++ b/modules/contentBridge.js
@@ -33,9 +33,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['ContentBridge'];
-
-const DEBUG = false;
+var EXPORTED_SYMBOLS = ['ContentBridge'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -46,12 +44,15 @@ Cu.import('resource://treestyletab-modules/lib/inherit.jsm');
Cu.import('resource://treestyletab-modules/constants.js');
Cu.import('resource://gre/modules/Promise.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
+
function ContentBridge(aTab, aTabBrowser)
{
this.init(aTab, aTabBrowser);
}
ContentBridge.install = function CB_installScript(aWindow) {
+ aWindow.messageManager.loadFrameScript(TreeStyleTabConstants.CONTENT_SCRIPT, true);
aWindow.messageManager.loadFrameScript(TreeStyleTabConstants.CONTENT_SCRIPT_AUTOHIDE, true);
};
@@ -59,6 +60,8 @@ ContentBridge.uninstall = function CB_installScript(aWindow) {
aWindow.messageManager.broadcastAsyncMessage(TreeStyleTabConstants.MESSAGE_TYPE, {
command : TreeStyleTabConstants.COMMAND_SHUTDOWN
});
+ aWindow.messageManager.removeDelayedFrameScript(TreeStyleTabConstants.CONTENT_SCRIPT);
+ aWindow.messageManager.removeDelayedFrameScript(TreeStyleTabConstants.CONTENT_SCRIPT_AUTOHIDE);
};
ContentBridge.prototype = inherit(TreeStyleTabConstants, {
@@ -104,15 +107,21 @@ ContentBridge.prototype = inherit(TreeStyleTabConstants, {
},
handleMessage : function CB_handleMessage(aMessage)
{
-// dump('*********************handleMessage*******************\n');
-// dump('TARGET IS: '+aMessage.target.localName+'\n');
-// dump(JSON.stringify(aMessage.json)+'\n');
+ if (utils.isDebugging('contentBridge')) {
+ dump('*********************handleMessage*******************\n');
+ dump('TARGET IS: '+aMessage.target.localName+'\n');
+ dump(JSON.stringify(aMessage.json)+'\n');
+ }
if (aMessage.target != this.mTab.linkedBrowser)
return;
switch (aMessage.json.command)
{
+ case this.COMMAND_REPORT_SELECTION_CHANGE:
+ this.mTab.__treestyletab__lastContentSelectionText = aMessage.json.text;
+ return;
+
case this.COMMAND_REPORT_MOUSEDOWN:
{
let fakeEvent = this.fixupEventCoordinates(aMessage.json.event);
diff --git a/modules/fullTooltip.js b/modules/fullTooltip.js
index 7962f2f..9457d87 100644
--- a/modules/fullTooltip.js
+++ b/modules/fullTooltip.js
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['FullTooltipManager'];
+var EXPORTED_SYMBOLS = ['FullTooltipManager'];
const Cc = Components.classes;
const Ci = Components.interfaces;
diff --git a/modules/fullscreenObserver.js b/modules/fullscreenObserver.js
index 368eb87..6dcd7de 100644
--- a/modules/fullscreenObserver.js
+++ b/modules/fullscreenObserver.js
@@ -14,7 +14,7 @@
* The Original Code is the Tree Style Tab.
*
* The Initial Developer of the Original Code is YUKI "Piro" Hiroshi.
- * Portions created by the Initial Developer are Copyright (C) 2013
+ * Portions created by the Initial Developer are Copyright (C) 2013-2015
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -33,7 +33,9 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['FullscreenObserver'];
+var EXPORTED_SYMBOLS = ['FullscreenObserver'];
+
+Components.utils.import('resource://treestyletab-modules/constants.js');
Components.utils.import('resource://treestyletab-modules/utils.js');
@@ -57,10 +59,11 @@ FullscreenObserver.prototype = {
}).bind(this));
this.observer.observe(this.window.document.documentElement, {
attributes : true,
+ attributeOldValue: true,
attributeFilter : ['sizemode']
});
- this.onSizeModeChange();
+ this.window.setTimeout(this.onSizeModeChange.bind(this), 0);
},
destroy : function FullscreenObserver_destroy()
@@ -74,6 +77,12 @@ FullscreenObserver.prototype = {
onMutation : function FullscreenObserver_onMutation(aMutations, aObserver)
{
+ var anyChanged = aMutations.some(function(aMutation) {
+ var newValue = aMutation.target.getAttribute(aMutation.attributeName);
+ return aMutation.oldValue !== newValue;
+ }, this);
+ if (!anyChanged)
+ return;
this.window.setTimeout((function() {
this.onSizeModeChange();
}).bind(this), 10);
@@ -81,6 +90,12 @@ FullscreenObserver.prototype = {
onSizeModeChange : function FullscreenObserver_onSizeModeChange()
{
+ this.updateToolboxPosition();
+ if (!this.window.gBrowser.treeStyleTab.notifyingRenderedEvent)
+ this.window.gBrowser.treeStyleTab.updateFloatingTabbar(TreeStyleTabConstants.kTABBAR_UPDATE_BY_WINDOW_RESIZE);
+ },
+ updateToolboxPosition : function FullscreenObserver_onSizeModeChange()
+ {
var w = this.window;
var d = w.document;
if (d.documentElement.getAttribute('sizemode') != 'fullscreen')
diff --git a/modules/groupTab.js b/modules/groupTab.js
index c53725e..080f1b4 100644
--- a/modules/groupTab.js
+++ b/modules/groupTab.js
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['GroupTab'];
+var EXPORTED_SYMBOLS = ['GroupTab'];
const Cc = Components.classes;
const Ci = Components.interfaces;
diff --git a/modules/lib/inherit.jsm b/modules/lib/inherit.jsm
index 72ce625..cb7730e 100644
--- a/modules/lib/inherit.jsm
+++ b/modules/lib/inherit.jsm
@@ -10,7 +10,7 @@
* @url http://github.com/piroor/fxaddonlib-inherit
*/
-const EXPORTED_SYMBOLS = ['inherit'];
+var EXPORTED_SYMBOLS = ['inherit'];
function toPropertyDescriptors(aProperties) {
var descriptors = {};
diff --git a/modules/pseudoTreeBuilder.js b/modules/pseudoTreeBuilder.js
index de5ecf9..5907d54 100644
--- a/modules/pseudoTreeBuilder.js
+++ b/modules/pseudoTreeBuilder.js
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['PseudoTreeBuilder'];
+var EXPORTED_SYMBOLS = ['PseudoTreeBuilder'];
const Cc = Components.classes;
const Ci = Components.interfaces;
diff --git a/modules/tabAttributesObserver.js b/modules/tabAttributesObserver.js
index 7f81598..8a62231 100644
--- a/modules/tabAttributesObserver.js
+++ b/modules/tabAttributesObserver.js
@@ -33,7 +33,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TabAttributesObserver'];
+var EXPORTED_SYMBOLS = ['TabAttributesObserver'];
Components.utils.import('resource://treestyletab-modules/constants.js');
diff --git a/modules/tabbarDNDObserver.js b/modules/tabbarDNDObserver.js
index dfd2598..e45033e 100644
--- a/modules/tabbarDNDObserver.js
+++ b/modules/tabbarDNDObserver.js
@@ -14,7 +14,7 @@
* The Original Code is the Tree Style Tab.
*
* The Initial Developer of the Original Code is YUKI "Piro" Hiroshi.
- * Portions created by the Initial Developer are Copyright (C) 2010-2014
+ * Portions created by the Initial Developer are Copyright (C) 2010-2015
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -35,9 +35,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TabbarDNDObserver'];
-
-const DEBUG = false;
+var EXPORTED_SYMBOLS = ['TabbarDNDObserver'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -45,6 +43,7 @@ const Cu = Components.utils;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
+Cu.import('resource://treestyletab-modules/ReferenceCounter.js');
XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
@@ -188,7 +187,8 @@ try{
return info.canDrop;
}
catch(e) {
- dump('TabbarDND::canDrop\n'+e+'\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump('TabbarDND::canDrop\n'+e+'\n');
return false;
}
},
@@ -262,7 +262,8 @@ catch(e) {
getDropActionInternal : function TabbarDND_getDropActionInternal(aEvent, aSourceTab)
{
- if (DEBUG) dump('getDropActionInternal: start\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump('getDropActionInternal: start\n');
var sv = this.treeStyleTab;
var b = this.browser;
var d = this.document;
@@ -303,18 +304,21 @@ catch(e) {
var isNewTabAction = !aSourceTab || aSourceTab.ownerDocument != d;
if (!tab || tab.localName != 'tab') {
- if (DEBUG) dump(' not on a tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' not on a tab\n');
let action = isTabMoveFromOtherWindow ? sv.kACTION_STAY : (sv.kACTION_MOVE | sv.kACTION_PART) ;
if (isNewTabAction) action |= sv.kACTION_NEWTAB;
if (aEvent[sv.screenPositionProp] < sv.getTabActualScreenPosition(firstTab)) {
- if (DEBUG) dump(' above the first tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' above the first tab\n');
info.target = info.parent = info.insertBefore = firstTab;
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
info.action = action;
return info;
}
else if (aEvent[sv.screenPositionProp] > sv.getTabActualScreenPosition(tabs[lastTabIndex]) + tabs[lastTabIndex].boxObject[sv.sizeProp]) {
- if (DEBUG) dump(' below the last tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' below the last tab\n');
info.target = info.parent = tabs[lastTabIndex];
info.position = isInverted ? sv.kDROP_BEFORE : sv.kDROP_AFTER ;
info.action = action;
@@ -324,25 +328,30 @@ catch(e) {
let index = b.getNewIndex ?
b.getNewIndex(aEvent) :
b.tabContainer._getDropIndex(aEvent) ;
- if (DEBUG) dump(' on the tab '+index+'\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' on the tab '+index+'\n');
index = Math.min(index, lastTabIndex);
info.target = tab = tabs[index];
if (index == tabs[lastTabIndex]._tPos) {
if (index > 0)
info.target = tab = tabs[index - 1];
info.position = sv.kDROP_AFTER;
- if (DEBUG) dump(' => after the last tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' => after the last tab\n');
} else if (index == firstTab._tPos) {
if (index < lastTabIndex - 1)
info.target = tab = tabs[index + 1];
info.position = sv.kDROP_BEFORE;
- if (DEBUG) dump(' => before the first tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' => before the first tab\n');
}
- if (DEBUG) dump(' info.target = ' + info.target._tPos + '\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' info.target = ' + info.target._tPos + '\n');
}
}
else {
- if (DEBUG) dump(' on the tab '+tab._tPos+'\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' on the tab '+tab._tPos+'\n');
sv.ensureTabInitialized(tab);
info.target = tab;
}
@@ -378,18 +387,21 @@ catch(e) {
switch (info.position)
{
case sv.kDROP_ON:
- if (DEBUG) dump(' position = on the tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' position = on the tab\n');
var visible = sv.getNextVisibleTab(tab);
info.action = sv.kACTION_STAY | sv.kACTION_ATTACH;
info.parent = tab;
info.insertBefore = utils.getTreePref('insertNewChildAt') == sv.kINSERT_FISRT ?
(sv.getFirstChildTab(tab) || visible) :
(sv.getNextSiblingTab(tab) || sv.getNextTab(sv.getLastDescendantTab(tab) || tab));
- if (DEBUG && info.insertBefore) dump(' insertBefore = '+info.insertBefore._tPos+'\n');
+ if (utils.isDebugging('tabbarDNDObserver') && info.insertBefore)
+ dump(' insertBefore = '+info.insertBefore._tPos+'\n');
break;
case sv.kDROP_BEFORE:
- if (DEBUG) dump(' position = before the tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' position = before the tab\n');
/*
<= detach from parent, and move
[TARGET ]
@@ -425,11 +437,13 @@ catch(e) {
info.action = sv.kACTION_MOVE | (info.parent ? sv.kACTION_ATTACH : sv.kACTION_PART );
info.insertBefore = tab;
}
- if (DEBUG && info.insertBefore) dump(' insertBefore = '+info.insertBefore._tPos+'\n');
+ if (utils.isDebugging('tabbarDNDObserver') && info.insertBefore)
+ dump(' insertBefore = '+info.insertBefore._tPos+'\n');
break;
case sv.kDROP_AFTER:
- if (DEBUG) dump(' position = after the tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' position = after the tab\n');
/*
[TARGET ]
<= if the target has a parent, attach to it and and move
@@ -473,7 +487,8 @@ catch(e) {
}
}
}
- if (DEBUG && info.insertBefore) dump(' insertBefore = '+info.insertBefore._tPos+'\n');
+ if (utils.isDebugging('tabbarDNDObserver') && info.insertBefore)
+ dump(' insertBefore = '+info.insertBefore._tPos+'\n');
break;
}
@@ -484,14 +499,16 @@ catch(e) {
performDrop : function TabbarDND_performDrop(aInfo, aDraggedTab)
{
- if (DEBUG) dump('performDrop: start\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump('performDrop: start\n');
var sv = this.treeStyleTab;
var b = this.browser;
var w = this.window;
var tabsInfo = this.getDraggedTabsInfoFromOneTab(aDraggedTab, aInfo);
if (!tabsInfo.draggedTab) {
- if (DEBUG) dump(' => no dragged tab\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' => no dragged tab\n');
return false;
}
@@ -548,7 +565,8 @@ catch(e) {
sourceBrowser == targetBrowser &&
sourceService.getNextVisibleTab(draggedTabs[draggedTabs.length-1]) == aInfo.insertBefore
) {
- if (DEBUG) dump(' => no change\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump(' => no change\n');
// then, do nothing
return true;
}
@@ -951,7 +969,13 @@ try{
var info = this.getDropAction(aEvent, session);
var observer = b;
- if (b.tabContainer && b.tabContainer._setEffectAllowedForDataTransfer)
+ if (
+ b.tabContainer &&
+ (
+ b.tabContainer._getDropEffectForTabDrag || // Firefox 44 and later
+ b.tabContainer._setEffectAllowedForDataTransfer // Firefox 43 and older
+ )
+ )
observer = b.tabContainer;
// auto-switch for staying on tabs
@@ -963,7 +987,9 @@ try{
) {
let time = observer.mDragTime || observer._dragTime || 0;
let delay = observer.mDragOverDelay || observer._dragOverDelay || 0;
- let effects = observer._setEffectAllowedForDataTransfer(aEvent);
+ let effects = '_setEffectAllowedForDataTransfer' in observer ?
+ observer._setEffectAllowedForDataTransfer(aEvent) :
+ observer._getDropEffectForTabDrag(aEvent) ;
if (effects == 'link') {
let now = Date.now();
if (!time) {
@@ -978,14 +1004,20 @@ try{
}
}
+ {
+ let effects = '_setEffectAllowedForDataTransfer' in observer ?
+ observer._setEffectAllowedForDataTransfer(aEvent) :
+ observer._getDropEffectForTabDrag(aEvent) ;
+
if (
!info.canDrop ||
- observer._setEffectAllowedForDataTransfer(aEvent) == 'none'
+ effects == 'none'
) {
aEvent.dataTransfer.effectAllowed = "none";
this.clearDropPosition();
return true;
}
+ }
let indicatorTab = info.target;
if (sv.isCollapsed(info.target)) {
@@ -1021,7 +1053,8 @@ try{
return (info.position == sv.kDROP_ON || sv.position != 'top')
}
catch(e) {
- dump('TabbarDND::onDragOver\n'+e+'\n');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump('TabbarDND::onDragOver\n'+e+'\n');
}
},
@@ -1066,7 +1099,15 @@ catch(e) {
tabbar._tabDropIndicator.collapsed = true;
var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
- if (dt.dropEffect != 'link' && !draggedTab) {
+
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump('TabbarDND::onDrop\n' +
+ ' dt.dropEffect: ' + dt.dropEffect + '\n' +
+ ' draggedTab: ' + draggedTab + '\n');
+
+ if (dt.dropEffect != 'link' &&
+ dt.dropEffect != 'move' &&
+ !draggedTab) {
aEvent.stopPropagation();
return;
}
@@ -1132,6 +1173,9 @@ catch(e) {
if (aURI.indexOf(this.BOOKMARK_FOLDER) == 0) {
let newTabs = sv.getNewTabsWithOperation(function() {
var data = aURI.replace(self.BOOKMARK_FOLDER, '');
+ if (utils.isDebugging('tabbarDNDObserver'))
+ dump('TabbarDND::handleLinksOrBookmarks\n' +
+ ' bookmark folder data: ' + data + '\n');
data = JSON.parse(data);
w.PlacesUIUtils._openTabset(data.children, { type : 'drop' }, w, data.title);
}, b);
@@ -1143,8 +1187,12 @@ catch(e) {
this.performDrop(aDropActionInfo, newTabs[0]);
}
else {
- aURI = utils.getShortcutOrURI(w, aURI);
- this.performDrop(aDropActionInfo, b.loadOneTab(aURI, { inBackground: bgLoad }));
+ // TODO: The callback (for Firefox 38 and older) should be
+ // migrated to a Promise (Firefox 39 and later).
+ w.getShortcutOrURIAndPostData(aURI, (function(aData) {
+ var uri = aData.url;
+ this.performDrop(aDropActionInfo, b.loadOneTab(uri, { inBackground: bgLoad }));
+ }).bind(this));
}
}, this);
}
@@ -1158,8 +1206,10 @@ catch(e) {
aDropActionInfo.position == sv.kDROP_ON)
loadDroppedLinkToNewChildTab = sv.dropLinksOnTabBehavior() == sv.kDROPLINK_NEWTAB;
- try {
- let uri = utils.getShortcutOrURI(w, uris[0]);
+ // TODO: The callback (for Firefox 38 and older) should be
+ // migrated to a Promise (Firefox 39 and later).
+ w.getShortcutOrURIAndPostData(uris[0], (function(aData) {
+ var uri = aData.url;
if (loadDroppedLinkToNewChildTab || locked) {
this.performDrop(aDropActionInfo, b.loadOneTab(uri, { inBackground: bgLoad }));
}
@@ -1168,9 +1218,7 @@ catch(e) {
if (!bgLoad)
b.selectedTab = tab;
}
- }
- catch(e) {
- }
+ }).bind(this));
}
},
securityCheck : function TabbarDND_securityCheck(aURI, aEvent)
@@ -1248,8 +1296,12 @@ catch(e) {
{
let item = JSON.parse(aData);
if (item.type == 'text/x-moz-place-container') {
- // When a blank folder is dropped, just open a dummy tab with the folder name.
let children = item.children;
+ if (!children) {
+ children = item.children = this.retrieveBookmarksInFolder(item.id);
+ aData = JSON.stringify(item);
+ }
+ // When a blank folder is dropped, just open a dummy tab with the folder name.
if (children && children.length == 0) {
let uri = this.treeStyleTab.getGroupTabURI({ title: item.title });
return [uri];
@@ -1284,6 +1336,20 @@ catch(e) {
}
return [];
},
+ retrieveBookmarksInFolder : function TabbarDND_retrieveBookmarksInFolder(aId)
+ {
+ var PlacesUtils = this.window.PlacesUtils;
+ var folder = PlacesUtils.getFolderContents(aId, false, true).root;
+ var children = [];
+ for (let i = 0; i < folder.childCount; i++) {
+ let child = folder.getChild(i);
+ if (PlacesUtils.nodeIsURI(child)) {
+ let item = PlacesUtils.wrapNode(child, 'text/x-moz-place');
+ children.push(JSON.parse(item));
+ }
+ }
+ return children;
+ },
init : function TabbarDND_init(aTabBrowser)
{
@@ -1302,11 +1368,17 @@ catch(e) {
{
var target = this.treeStyleTab.ownerToolbar || this.treeStyleTab.tabStrip;
target.addEventListener('dragstart', this, true);
+ ReferenceCounter.add('target,dragstart,TabbarDND,true');
target.addEventListener('dragover', this, true);
+ ReferenceCounter.add('target,dragover,TabbarDND,true');
target.addEventListener('dragenter', this, false);
+ ReferenceCounter.add('target,dragenter,TabbarDND,false');
target.addEventListener('dragleave', this, false);
+ ReferenceCounter.add('target,dragleave,TabbarDND,false');
target.addEventListener('dragend', this, true);
+ ReferenceCounter.add('target,dragend,TabbarDND,true');
target.addEventListener('drop', this, true);
+ ReferenceCounter.add('target,drop,TabbarDND,true');
},
destroy : function TabbarDND_destroy()
@@ -1323,11 +1395,17 @@ catch(e) {
{
var target = this.treeStyleTab.ownerToolbar || this.treeStyleTab.tabStrip;
target.removeEventListener('dragstart', this, true);
+ ReferenceCounter.remove('target,dragstart,TabbarDND,true');
target.removeEventListener('dragover', this, true);
+ ReferenceCounter.remove('target,dragover,TabbarDND,true');
target.removeEventListener('dragenter', this, false);
+ ReferenceCounter.remove('target,dragenter,TabbarDND,false');
target.removeEventListener('dragleave', this, false);
+ ReferenceCounter.remove('target,dragleave,TabbarDND,false');
target.removeEventListener('dragend', this, true);
+ ReferenceCounter.remove('target,dragend,TabbarDND,true');
target.removeEventListener('drop', this, true);
+ ReferenceCounter.remove('target,drop,TabbarDND,true');
}
};
diff --git a/modules/tabpanelDNDObserver.js b/modules/tabpanelDNDObserver.js
index 69689c5..d2eee66 100644
--- a/modules/tabpanelDNDObserver.js
+++ b/modules/tabpanelDNDObserver.js
@@ -34,12 +34,13 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TabpanelDNDObserver'];
+var EXPORTED_SYMBOLS = ['TabpanelDNDObserver'];
const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
+Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js');
XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
@@ -145,16 +146,22 @@ TabpanelDNDObserver.prototype = {
var b = this.treeStyleTab.mTabBrowser;
b.mPanelContainer.addEventListener('dragover', this, true);
+ ReferenceCounter.add('b.mPanelContainer,dragover,this,true');
b.mPanelContainer.addEventListener('dragleave', this, true);
+ ReferenceCounter.add('b.mPanelContainer,dragleave,this,true');
b.mPanelContainer.addEventListener('drop', this, true);
+ ReferenceCounter.add('b.mPanelContainer,drop,this,true');
},
destroy : function TabpanelDND_destroy()
{
var b = this.treeStyleTab.mTabBrowser;
b.mPanelContainer.removeEventListener('dragover', this, true);
+ ReferenceCounter.remove('b.mPanelContainer,dragover,this,true');
b.mPanelContainer.removeEventListener('dragleave', this, true);
+ ReferenceCounter.remove('b.mPanelContainer,dragleave,this,true');
b.mPanelContainer.removeEventListener('drop', this, true);
+ ReferenceCounter.remove('b.mPanelContainer,drop,this,true');
delete this.treeStyleTab;
delete this.browser;
diff --git a/modules/themeManager.js b/modules/themeManager.js
index 1cc1105..26126a6 100644
--- a/modules/themeManager.js
+++ b/modules/themeManager.js
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TreeStyleTabThemeManager'];
+var EXPORTED_SYMBOLS = ['TreeStyleTabThemeManager'];
const BASE = 'chrome://treestyletab/skin/';
diff --git a/modules/utils.js b/modules/utils.js
index a3a2f7b..240602f 100644
--- a/modules/utils.js
+++ b/modules/utils.js
@@ -14,7 +14,7 @@
* The Original Code is the Tree Style Tab.
*
* The Initial Developer of the Original Code is YUKI "Piro" Hiroshi.
- * Portions created by the Initial Developer are Copyright (C) 2010-2014
+ * Portions created by the Initial Developer are Copyright (C) 2010-2015
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -36,7 +36,7 @@
"use strict";
-let EXPORTED_SYMBOLS = ['TreeStyleTabUtils'];
+var EXPORTED_SYMBOLS = ['TreeStyleTabUtils'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -61,14 +61,16 @@ XPCOMUtils.defineLazyGetter(this, 'stringBundle', function() {
XPCOMUtils.defineLazyModuleGetter(this, 'Task',
'resource://gre/modules/Task.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'Promise',
+ 'resource://gre/modules/Promise.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'TreeStyleTabConstants',
'resource://treestyletab-modules/constants.js', 'TreeStyleTabConstants');
const TST_PREF_PREFIX = 'extensions.treestyletab.';
-const TST_PREF_VERSION = 10;
+const TST_PREF_VERSION = 11;
-let TreeStyleTabUtils = {
+var TreeStyleTabUtils = {
get prefs () {
return prefs;
@@ -213,6 +215,12 @@ let TreeStyleTabUtils = {
this.setTreePref('openGroupBookmark.behavior', behavior);
}
}
+ case 10:
+ {
+ let physical = this.getTreePref('maxTreeLevel.phisical');
+ this.setTreePref('maxTreeLevel.physical', physical);
+ this.clearTreePref('maxTreeLevel.phisical');
+ }
default:
for (let i = 0, maxi = orientalPrefs.length; i < maxi; i++)
{
@@ -229,6 +237,11 @@ let TreeStyleTabUtils = {
}
this.setTreePref('prefsVersion', TST_PREF_VERSION);
},
+
+ isDebugging : function utils_isDebugging(aModule)
+ {
+ return this.getTreePref('debug.' + aModule) || this.getTreePref('debug.all');
+ },
/* string bundle */
get treeBundle () {
@@ -253,32 +266,16 @@ let TreeStyleTabUtils = {
isTabNotRestoredYet : function utils_isTabNotRestoredYet(aTab)
{
var browser = aTab.linkedBrowser;
- // Firefox 25 and later. See: https://bugzilla.mozilla.org/show_bug.cgi?id=867142
- if (this.TabRestoreStates &&
- this.TabRestoreStates.has(browser))
- return (
- this.TabRestoreStates.isNeedsRestore(browser) ||
- this.TabRestoreStates.isRestoring(browser)
- );
-
return !!browser.__SS_restoreState;
},
isTabNeedToBeRestored : function utils_isTabNeedToBeRestored(aTab)
{
var browser = aTab.linkedBrowser;
- // Firefox 25 and later. See: https://bugzilla.mozilla.org/show_bug.cgi?id=867142
- if (this.TabRestoreStates &&
- this.TabRestoreStates.has(browser))
- return this.TabRestoreStates.isNeedsRestore(browser);
-
return browser.__SS_restoreState == 1;
},
get SessionStoreInternal() {
return this.SessionStoreNS.SessionStoreInternal;
},
- get TabRestoreStates() {
- return this.SessionStoreNS.TabRestoreStates;
- },
get SessionStoreNS() {
if (!this._SessionStoreNS) {
try {
@@ -292,24 +289,6 @@ let TreeStyleTabUtils = {
return this._SessionStoreNS;
},
- getShortcutOrURI : function utils_getShortcutOrURI(aBrowserWindow, aURI)
- {
- var done = false;
- aBrowserWindow.getShortcutOrURIAndPostData(aURI, function(aData) {
- aURI = aData.url;
- done = true;
- });
-
- // this should be rewritten in asynchronous style...
- var thread = Cc['@mozilla.org/thread-manager;1'].getService().mainThread;
- while (!done)
- {
- thread.processNextEvent(true);
- }
-
- return aURI;
- },
-
doPatching : function utils_assertFunctionExists(aFunction, aName, aPatchingTask, aMatcher)
{
@@ -375,3 +354,18 @@ let TreeStyleTabUtils = {
};
prefs.addPrefListener(TreeStyleTabUtils);
+
+{
+ // Never save TST specific attributes! (because it causes many problems)
+ let { TabAttributesInternal } = Cu.import('resource:///modules/sessionstore/TabAttributes.jsm', {});
+ if (TabAttributesInternal && TabAttributesInternal._skipAttrs) {
+ Object.keys(TreeStyleTabConstants).forEach(function(aKey) {
+ if (!/^k[A-Z_]+$/.test(aKey))
+ return;
+ var name = TreeStyleTabConstants[aKey];
+ if (!/^treestyletab-/.test(String(name)))
+ return;
+ TabAttributesInternal._skipAttrs.add(name);
+ });
+ }
+}
diff --git a/modules/window.js b/modules/window.js
index 424f346..866a890 100644
--- a/modules/window.js
+++ b/modules/window.js
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ******/
-const EXPORTED_SYMBOLS = ['TreeStyleTabWindow'];
+var EXPORTED_SYMBOLS = ['TreeStyleTabWindow'];
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -43,6 +43,7 @@ const Cu = Components.utils;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Timer.jsm');
Cu.import('resource://treestyletab-modules/lib/inherit.jsm');
+Cu.import('resource://treestyletab-modules/ReferenceCounter.js');
XPCOMUtils.defineLazyGetter(this, 'window', function() {
Cu.import('resource://treestyletab-modules/lib/namespace.jsm');
@@ -80,7 +81,9 @@ function TreeStyleTabWindow(aWindow)
this.restoringCount = 0;
aWindow.addEventListener('DOMContentLoaded', this, true);
+ ReferenceCounter.add('w,DOMContentLoaded,TSTWindow,true');
aWindow.addEventListener('load', this, false);
+ ReferenceCounter.add('w,load,TSTWindow,false');
aWindow.TreeStyleTabService = this;
XPCOMUtils.defineLazyModuleGetter(aWindow, 'TreeStyleTabBrowser', 'resource://treestyletab-modules/browser.js');
@@ -188,6 +191,11 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
return this.document.getElementById('browser-bottombox');
},
+ get socialBox()
+ {
+ return this.document.getElementById('social-sidebar-box');
+ },
+
get isPopupWindow()
{
return (
@@ -280,7 +288,20 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
return false;
}
- var selection = this.window.getBrowserSelection();
+ var selection = '';
+ var contextMenuContentData = this.window.gContextMenuContentData;
+ if (contextMenuContentData && contextMenuContentData.selectionInfo) {
+ selection = contextMenuContentData.selectionInfo.text;
+ }
+ else {
+ let tab = this.window.gBrowser.selectedTab;
+ selection = tab.__treestyletab__lastContentSelectionText || '';
+ // for old Firefox without selectionchange event
+ if (selection === '' &&
+ typeof this.window.getBrowserSelection === 'function' &&
+ tab.linkedBrowser.getAttribute('remote') !== 'true')
+ selection = this.window.getBrowserSelection();
+ }
return selection.trim() == aTerm;
},
kSEARCH_RESULT_DO_NOT_ATTACH : 0,
@@ -298,7 +319,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
get autoHideWindow()
{
- if (!this._autoHideWindow) {
+ if (!('_autoHideWindow' in this)) {
this._autoHideWindow = new AutoHideWindow(this.window);
}
return this._autoHideWindow;
@@ -306,7 +327,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
get themeManager()
{
- if (!this._themeManager) {
+ if (!('_themeManager' in this)) {
this._themeManager = new TreeStyleTabThemeManager(this.window);
}
return this._themeManager;
@@ -359,10 +380,12 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
var w = this.window;
w.removeEventListener('DOMContentLoaded', this, true);
+ ReferenceCounter.remove('w,DOMContentLoaded,TSTWindow,true');
if (w.location.href.indexOf('chrome://browser/content/browser.xul') != 0)
return;
w.addEventListener('SSTabRestoring', this, true);
+ ReferenceCounter.add('w,SSTabRestoring,TSTWindow,true');
w.TreeStyleTabWindowHelper.preInit();
@@ -375,8 +398,10 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
{
var w = this.window;
w.removeEventListener('load', this, false);
+ ReferenceCounter.remove('w,load,TSTWindow,false');
w.addEventListener('unload', this, false);
+ ReferenceCounter.add('w,unload,TSTWindow,false');
if (
w.location.href.indexOf('chrome://browser/content/browser.xul') != 0 ||
@@ -391,28 +416,43 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
this.preInit();
}
w.removeEventListener('SSTabRestoring', this, true);
+ ReferenceCounter.remove('w,SSTabRestoring,TSTWindow,true');
var d = this.document;
d.addEventListener('popupshowing', this, false);
+ ReferenceCounter.add('d,popupshowing,TSTWindow,false');
d.addEventListener('popuphiding', this, true);
+ ReferenceCounter.add('d,popuphiding,TSTWindow,true');
d.addEventListener(this.kEVENT_TYPE_TAB_COLLAPSED_STATE_CHANGED, this, false);
+ ReferenceCounter.add('d,kEVENT_TYPE_TAB_COLLAPSED_STATE_CHANGED,TSTWindow,false');
d.addEventListener(this.kEVENT_TYPE_TABBAR_POSITION_CHANGED, this, false);
+ ReferenceCounter.add('d,kEVENT_TYPE_TABBAR_POSITION_CHANGED,TSTWindow,false');
d.addEventListener(this.kEVENT_TYPE_TABBAR_STATE_CHANGED, this, false);
+ ReferenceCounter.add('d,kEVENT_TYPE_TABBAR_STATE_CHANGED,TSTWindow,false');
d.addEventListener(this.kEVENT_TYPE_FOCUS_NEXT_TAB, this, false);
+ ReferenceCounter.add('d,kEVENT_TYPE_FOCUS_NEXT_TAB,TSTWindow,false');
w.addEventListener('beforecustomization', this, true);
+ ReferenceCounter.add('w,beforecustomization,TSTWindow,true');
w.addEventListener('aftercustomization', this, false);
+ ReferenceCounter.add('w,aftercustomization,TSTWindow,false');
w.messageManager.addMessageListener('SessionStore:restoreTabContentStarted', this);
this.fullscreenObserver = new FullscreenObserver(this.window);
this.initUIShowHideObserver();
+ if (!this.isMac)
+ this.initMenubarShowHideObserver();
var appcontent = d.getElementById('appcontent');
appcontent.addEventListener('SubBrowserAdded', this, false);
+ ReferenceCounter.add('appcontent,SubBrowserAdded,TSTWindow,false');
appcontent.addEventListener('SubBrowserRemoveRequest', this, false);
+ ReferenceCounter.add('appcontent,SubBrowserRemoveRequest,TSTWindow,false');
w.addEventListener('UIOperationHistoryUndo:TabbarOperations', this, false);
+ ReferenceCounter.add('w,UIOperationHistoryUndo:TabbarOperations,TSTWindow,false');
w.addEventListener('UIOperationHistoryRedo:TabbarOperations', this, false);
+ ReferenceCounter.add('w,UIOperationHistoryRedo:TabbarOperations,TSTWindow,false');
prefs.addPrefListener(this);
@@ -425,7 +465,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
w.TreeStyleTabWindowHelper.onAfterBrowserInit();
this.processRestoredTabs();
- this.updateTabsOnTop();
+ this.updateTabsInTitlebar();
this.autoHideWindow; // initialize
@@ -438,15 +478,6 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
initUninstallationListener : function TSTWindow_initUninstallationListener()
{
var restorePrefs = function() {
- if (prefs.getPref('extensions.treestyletab.tabsOnTop.originalState')) {
- prefs.clearPref('extensions.treestyletab.tabsOnTop.originalState');
- try {
- this.browser.treeStyleTab.position = 'top';
- }
- catch(e) {
- }
- this.window.TabsOnTop.enabled = true;
- }
}.bind(this);
new UninstallationListener({
id : 'treestyletab at piro.sakura.ne.jp',
@@ -489,7 +520,10 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
initUIShowHideObserver : function TSTWindow_initUIShowHideObserver()
{
- this.rootElementObserver = new BrowserUIShowHideObserver(this, this.document.documentElement);
+ this.rootElementObserver = new BrowserUIShowHideObserver(this, this.document.documentElement, {
+ childList : false,
+ subtree : false
+ });
var toolbox = this.browserToolbox;
if (toolbox)
@@ -502,6 +536,23 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
var bottomBox = this.browserBottomBox;
if (bottomBox)
this.browserBottomBoxObserver = new BrowserUIShowHideObserver(this, bottomBox);
+
+ var socialBox = this.socialBox;
+ if (socialBox)
+ this.socialBoxObserver = new BrowserUIShowHideObserver(this, socialBox);
+ },
+
+ initMenubarShowHideObserver : function TSTWindow_initMenubarShowHideObserver()
+ {
+ var w = this.window;
+ var MutationObserver = w.MutationObserver || w.MozMutationObserver;
+ this.menubarShowHideObserver = new MutationObserver((function(aMutations, aObserver) {
+ this.updateTabsInTitlebar();
+ }).bind(this));
+ this.menubarShowHideObserver.observe(w.document.getElementById('toolbar-menubar'), {
+ attributes : true,
+ attributeFilter : ['autohide']
+ });
},
destroy : function TSTWindow_destroy()
@@ -511,12 +562,15 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
this.base.inWindowDestoructionProcess = true;
try {
w.removeEventListener('unload', this, false);
+ ReferenceCounter.remove('w,unload,TSTWindow,false');
+
+ w.TreeStyleTabWindowHelper.destroyToolbarItems();
this.autoHideWindow.destroy();
- delete this._autoHideWindow;
+ this._autoHideWindow = undefined;
this.themeManager.destroy();
- delete this._themeManager;
+ this._themeManager = undefined;
this.browser.treeStyleTab.saveCurrentState();
this.destroyTabBrowser(this.browser);
@@ -526,13 +580,21 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
let d = this.document;
d.removeEventListener('popupshowing', this, false);
+ ReferenceCounter.remove('d,popupshowing,TSTWindow,false');
d.removeEventListener('popuphiding', this, true);
+ ReferenceCounter.remove('d,popuphiding,TSTWindow,true');
d.removeEventListener(this.kEVENT_TYPE_TAB_COLLAPSED_STATE_CHANGED, this, false);
+ ReferenceCounter.remove('d,kEVENT_TYPE_TAB_COLLAPSED_STATE_CHANGED,TSTWindow,false');
d.removeEventListener(this.kEVENT_TYPE_TABBAR_POSITION_CHANGED, this, false);
+ ReferenceCounter.remove('d,kEVENT_TYPE_TABBAR_POSITION_CHANGED,TSTWindow,false');
d.removeEventListener(this.kEVENT_TYPE_TABBAR_STATE_CHANGED, this, false);
+ ReferenceCounter.remove('d,kEVENT_TYPE_TABBAR_STATE_CHANGED,TSTWindow,false');
d.removeEventListener(this.kEVENT_TYPE_FOCUS_NEXT_TAB, this, false);
+ ReferenceCounter.remove('d,kEVENT_TYPE_FOCUS_NEXT_TAB,TSTWindow,false');
w.removeEventListener('beforecustomization', this, true);
+ ReferenceCounter.remove('w,beforecustomization,TSTWindow,true');
w.removeEventListener('aftercustomization', this, false);
+ ReferenceCounter.remove('w,aftercustomization,TSTWindow,false');
w.messageManager.removeMessageListener('SessionStore:restoreTabContentStarted', this);
@@ -541,9 +603,10 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
this.fullscreenObserver.destroy();
delete this.fullscreenObserver;
- this.rootElementObserver.destroy();
- delete this.rootElementObserver;
-
+ if (this.rootElementObserver) {
+ this.rootElementObserver.destroy();
+ delete this.rootElementObserver;
+ }
if (this.browserToolboxObserver) {
this.browserToolboxObserver.destroy();
delete this.browserToolboxObserver;
@@ -556,18 +619,32 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
this.browserBottomBoxObserver.destroy();
delete this.browserBottomBoxObserver;
}
+ if (this.socialBoxObserver) {
+ this.socialBoxObserver.destroy();
+ delete this.socialBoxObserver;
+ }
+
+ if (this.menubarShowHideObserver) {
+ this.menubarShowHideObserver.disconnect();
+ delete this.menubarShowHideObserver;
+ }
for (let i = 0, maxi = this._tabFocusAllowance.length; i < maxi; i++)
{
w.removeEventListener(this.kEVENT_TYPE_FOCUS_NEXT_TAB, this._tabFocusAllowance[i], false);
+ ReferenceCounter.remove('w,kEVENT_TYPE_FOCUS_NEXT_TAB,_tabFocusAllowance['+i+'],false');
}
var appcontent = d.getElementById('appcontent');
appcontent.removeEventListener('SubBrowserAdded', this, false);
+ ReferenceCounter.remove('appcontent,SubBrowserAdded,TSTWindow,false');
appcontent.removeEventListener('SubBrowserRemoveRequest', this, false);
+ ReferenceCounter.remove('appcontent,SubBrowserRemoveRequest,TSTWindow,false');
w.removeEventListener('UIOperationHistoryUndo:TabbarOperations', this, false);
+ ReferenceCounter.remove('w,UIOperationHistoryUndo:TabbarOperations,TSTWindow,false');
w.removeEventListener('UIOperationHistoryRedo:TabbarOperations', this, false);
+ ReferenceCounter.remove('w,UIOperationHistoryRedo:TabbarOperations,TSTWindow,false');
prefs.removePrefListener(this);
}
@@ -624,7 +701,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
case this.kEVENT_TYPE_TABBAR_POSITION_CHANGED:
case this.kEVENT_TYPE_TABBAR_STATE_CHANGED:
- return this.updateTabsOnTop();
+ return this.updateTabsInTitlebar();
case this.kEVENT_TYPE_FOCUS_NEXT_TAB:
return this.onFocusNextTab(aEvent);
@@ -709,9 +786,13 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
if (!this.keyEventListening) {
let w = this.window;
w.addEventListener('keydown', this, true);
+ ReferenceCounter.add('w,keydown,TSTWindow,true');
w.addEventListener('keyup', this, true);
+ ReferenceCounter.add('w,keyup,TSTWindow,true');
w.addEventListener('keypress', this, true);
+ ReferenceCounter.add('w,keypress,TSTWindow,true');
w.addEventListener('blur', this, true);
+ ReferenceCounter.add('w,blur,TSTWindow,true');
this.keyEventListening = true;
}
this.keyEventListeningFlags |= aReason;
@@ -725,9 +806,13 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
if (!this.keyEventListeningFlags && this.keyEventListening) {
let w = this.window;
w.removeEventListener('keydown', this, true);
+ ReferenceCounter.remove('w,keydown,TSTWindow,true');
w.removeEventListener('keyup', this, true);
+ ReferenceCounter.remove('w,keyup,TSTWindow,true');
w.removeEventListener('keypress', this, true);
+ ReferenceCounter.remove('w,keypress,TSTWindow,true');
w.removeEventListener('blur', this, true);
+ ReferenceCounter.remove('w,blur,TSTWindow,true');
this.keyEventListening = false;
}
},
@@ -787,9 +872,9 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
// this.accelKeyPressed = this.isAccelKeyPressed(aEvent);
this.accelKeyPressed = aEvent.ctrlKey || aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_CONTROL;
- this.window.setTimeout(function(aSelf) {
- aSelf.arrowKeyEventOnTab = null;
- }, 10, this);
+ setTimeout((function() {
+ this.arrowKeyEventOnTab = null;
+ }).bind(this), 10);
var standBy = scrollDown = scrollUp = (!aEvent.altKey && this.accelKeyPressed);
@@ -921,6 +1006,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
aEvent.currentTarget.setCapture(true);
aEvent.currentTarget.addEventListener('mousemove', this, false);
+ ReferenceCounter.add('currentTarget,mousemove,TSTWindow,false');
var b = this.getTabBrowserFromChild(aEvent.currentTarget);
var box = aEvent.currentTarget.id == 'treestyletab-tabbar-resizer-splitter' ?
@@ -944,6 +1030,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
target.releaseCapture();
target.removeEventListener('mousemove', this, false);
+ ReferenceCounter.remove('currentTarget,mousemove,TSTWindow,false');
this.tabbarResizeStartWidth = -1;
this.tabbarResizeStartHeight = -1;
@@ -1064,16 +1151,16 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
)
return;
- this.updateAeroPeekPreviewsTimer = w.setTimeout(function(aSelf) {
- aSelf.updateAeroPeekPreviewsTimer = null;
+ this.updateAeroPeekPreviewsTimer = w.setTimeout((function() {
+ this.updateAeroPeekPreviewsTimer = null;
try {
- aSelf.updateAeroPeekPreviewsInternal();
+ this.updateAeroPeekPreviewsInternal();
}
catch(e) {
dump(e+'\n');
- aSelf.updateAeroPeekPreviews();
+ this.updateAeroPeekPreviews();
}
- }, 250, this);
+ }).bind(this), 250);
},
updateAeroPeekPreviewsTimer : null,
updateAeroPeekPreviewsInternal : function TSTWindow_updateAeroPeekPreviewsInternal()
@@ -1102,54 +1189,42 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
}, this);
},
- updateTabsOnTop : function TSTWindow_updateTabsOnTop()
+ updateTabsInTitlebar : function TSTWindow_updateTabsInTitlebar()
{
if (
this.isPopupWindow ||
- this.tabsOnTopChangingByUI ||
- this.tabsOnTopChangingByTST
+ this.tabsInTitlebarChanging
)
return;
- var TabsOnTop = this.window.TabsOnTop;
+ this.tabsInTitlebarChanging = true;
+ // We have to do this with delay, because the tab bar is always on top
+ // for the toolbar customizing and returned to left or right after a delay.
+ setTimeout(this.updateTabsInTitlebarInternal.bind(this), 0);
+ },
+ updateTabsInTitlebarInternal : function TSTWindow_updateTabsInTitlebarInternal()
+ {
var TabsInTitlebar = this.window.TabsInTitlebar;
var isTopTabbar = this.browser.treeStyleTab.position == 'top';
- this.tabsOnTopChangingByTST = true;
-
try {
- if (TabsOnTop) {
- let originalState = utils.getTreePref('tabsOnTop.originalState');
- if (originalState === null) {
- let current = prefs.getDefaultPref('browser.tabs.onTop') === null ?
- TabsOnTop.enabled :
- prefs.getPref('browser.tabs.onTop') ;
- utils.setTreePref('tabsOnTop.originalState', originalState = current);
- }
-
- if (!isTopTabbar || !this.browser.treeStyleTab.fixed) {
- if (TabsOnTop.enabled)
- TabsOnTop.enabled = false;
- }
- else {
- if (TabsOnTop.enabled != originalState)
- TabsOnTop.enabled = originalState;
- utils.clearTreePref('tabsOnTop.originalState');
- }
- }
if (TabsInTitlebar) {
- let allowed = isTopTabbar && this.browser.treeStyleTab.fixed;
+ let menubar = this.window.document.getElementById('toolbar-menubar');
+ let allowed = (
+ (isTopTabbar && this.browser.treeStyleTab.fixed) ||
+ (!this.isMac && menubar.getAttribute('autohide') !== 'true')
+ );
if (
(this.window.TabsOnBottom && utils.getTreePref('compatibility.TabsOnBottom')) ||
('navbarontop' in this.window && utils.getTreePref('compatibility.NavbarOnTitlebar')) ||
('classicthemerestorerjs' in this.window && utils.getTreePref('compatibility.ClassicThemeRestorer'))
)
allowed = true;
- TabsInTitlebar.allowedBy('TreeStyleTab-tabsOnTop', allowed);
+ TabsInTitlebar.allowedBy('TreeStyleTab-tabsInTitlebar', allowed);
}
}
finally {
- this.tabsOnTopChangingByTST = false;
+ this.tabsInTitlebarChanging = false;
}
},
@@ -1163,17 +1238,17 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
).booleanValue)
return;
- this.window.setTimeout(function(aSelf) {
+ setTimeout((function() {
if ((!aPopup.boxObject.width && !aPopup.boxObject.height) ||
aPopup.boxObject.popupState == 'closed')
return;
var id = aPopup.id;
- var item = id && aSelf.document.getElementById(id) ? id : aPopup ;
- var index = aSelf._shownPopups.indexOf(item);
+ var item = id && this.document.getElementById(id) ? id : aPopup ;
+ var index = this._shownPopups.indexOf(item);
if (index < 0)
- aSelf._shownPopups.push(item);
- }, 10, this);
+ this._shownPopups.push(item);
+ }).bind(this), 10);
},
onPopupHidden : function TSTWindow_onPopupHidden(aPopup)
@@ -1688,6 +1763,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
}
};
this.window.addEventListener(this.kEVENT_TYPE_FOCUS_NEXT_TAB, listener, false);
+ ReferenceCounter.add('window,kEVENT_TYPE_FOCUS_NEXT_TAB,listener,false');
this._tabFocusAllowance.push(listener);
},
_tabFocusAllowance : [],
diff --git a/skin/classic/treestyletab/Linux-base.css b/skin/classic/treestyletab/Linux-base.css
index 31b67e7..925f386 100644
--- a/skin/classic/treestyletab/Linux-base.css
+++ b/skin/classic/treestyletab/Linux-base.css
@@ -53,3 +53,9 @@
#TabsToolbar::after {
display: none;
}
+
+/* cancel too much padding for the icon in the vertical tab bar */
+#main-window[treestyletab-mode="vertical"]
+ #alltabs-button > .toolbarbutton-icon {
+ padding: 3px 7px;
+}
diff --git a/skin/classic/treestyletab/square/tab-surface.css b/skin/classic/treestyletab/square/tab-surface.css
index b910e21..a9b3d0d 100644
--- a/skin/classic/treestyletab/square/tab-surface.css
+++ b/skin/classic/treestyletab/square/tab-surface.css
@@ -10,9 +10,9 @@
}
.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
- .tabbrowser-tab
+ .tabbrowser-tab:not([titlechanged])
:-moz-any(.tab-background:not([pinned]),
- .tab-background:not([titlechanged])[pinned]) {
+ .tab-background[pinned]) {
background-color: -moz-dialog !important;
background-image: -moz-linear-gradient(
top,
diff --git a/skin/classic/treestyletab/ui-base.css b/skin/classic/treestyletab/ui-base.css
index 7cb973b..600a32b 100644
--- a/skin/classic/treestyletab/ui-base.css
+++ b/skin/classic/treestyletab/ui-base.css
@@ -233,6 +233,22 @@ tabbrowser[treestyletab-drop-position="left"]:not([treestyletab-tabbar-position=
min-height: 22px;
}
+.treestyletab-tabbar-toolbar[treestyletab-mode="vertical"]
+ toolbarbutton:not(.tab-close-button)
+ > .toolbarbutton-icon {
+ /**
+ * This is required to block the tab bar to be shrunken.
+ * See: https://github.com/piroor/treestyletab/issues/964#issuecomment-153781248
+ */
+ max-width: none !important;
+ /**
+ * But we still have to set maximum size of the icon
+ * to shrink the size of high-res icons.
+ * See: https://github.com/piroor/treestyletab/issues/964#issuecomment-153801249
+ */
+ max-height: 16px;
+}
+
/* transaprent tab bar */
.tabbrowser-tabs[treestyletab-tabbar-autohide]
@@ -338,13 +354,22 @@ tabbrowser[treestyletab-tabbar-position="bottom"]
}
.tabbrowser-tabs[treestyletab-mode="vertical"]
- .tab-content[pinned="true"] > image {
+ .tab-content[pinned="true"] > image:not(.tab-icon-overlay) {
height: 16px;
margin: 0;
padding: 0;
width: 16px;
}
+/* overlay icon: because TST applies "min-height:2em" for tabs, overlay icons also should be rendered based on the "em" scale. */
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+ .tab-content[pinned="true"] > image.tab-icon-overlay {
+ height: 1em;
+ width: 1em;
+ margin-top: -0.7em !important;
+ -moz-margin-start: -1em !important;
+}
+
/* disable highlighting of pinned tabs whici is not faviconized */
.tabbrowser-tabs[treestyletab-mode="vertical"]
@@ -356,13 +381,6 @@ tabbrowser[treestyletab-tabbar-position="bottom"]
background-image: none;
}
-/* overlay icon */
-.tabbrowser-tabs[treestyletab-mode="vertical"]
- .tab-content[pinned="true"] > image.tab-icon-overlay {
- margin-top: -14px !important;
- -moz-margin-start: -8px !important;
-}
-
/* notification of newly opened tabs in background */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/tree-style-tab.git
More information about the Pkg-mozext-commits
mailing list