[Pkg-mozext-commits] [tree-style-tab] 01/05: New upstream version 0.19.2017061601

Ximin Luo infinity0 at debian.org
Wed Jul 12 13:54:12 UTC 2017


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 8c4a20b097320551330d01611ec71aed8776c912
Author: Ximin Luo <infinity0 at debian.org>
Date:   Wed Jul 12 15:32:57 2017 +0200

    New upstream version 0.19.2017061601
---
 META-INF/manifest.mf                              |  228 +--
 META-INF/mozilla.rsa                              |  Bin 4188 -> 4188 bytes
 META-INF/mozilla.sf                               |    4 +-
 content/treestyletab/bookmarksOverlay.js          |    2 +-
 content/treestyletab/config.js                    |    2 +-
 content/treestyletab/config.xul                   |   29 +-
 content/treestyletab/content-utils-autohide.js    |    2 +-
 content/treestyletab/content-utils.js             |    7 +-
 content/treestyletab/hide-embed.css               |    5 -
 content/treestyletab/license.txt                  |    2 +-
 content/treestyletab/res/bookmarkMultipleTabs.js  |    6 +-
 content/treestyletab/res/tabsDragUtils.js         | 2023 ++++++++++-----------
 content/treestyletab/treestyletab.css             |    4 +
 content/treestyletab/windowHelper.js              |   23 +-
 content/treestyletab/windowHelperHacks.js         |   26 +-
 defaults/preferences/treestyletab.js              |   12 +-
 install.rdf                                       |   25 +-
 locale/cs/treestyletab/treestyletab.dtd           |    2 +
 locale/da-DK/treestyletab/treestyletab.dtd        |    2 +
 locale/de-DE/treestyletab/treestyletab.dtd        |    2 +
 locale/en-US/treestyletab/license.txt             |    2 +-
 locale/en-US/treestyletab/treestyletab.dtd        |    2 +
 locale/es-ES/treestyletab/treestyletab.dtd        |    2 +
 locale/fr-FR/treestyletab/treestyletab.dtd        |    2 +
 locale/{ja => gr-EL}/treestyletab/license.txt     |   69 +-
 locale/gr-EL/treestyletab/treestyletab.dtd        |  194 ++
 locale/gr-EL/treestyletab/treestyletab.properties |   59 +
 locale/it-IT/treestyletab/treestyletab.dtd        |    2 +
 locale/ja/treestyletab/license.txt                |    2 +-
 locale/ja/treestyletab/treestyletab.dtd           |    2 +
 locale/pl/treestyletab/treestyletab.dtd           |    2 +
 locale/ru/treestyletab/treestyletab.dtd           |    2 +
 locale/sv-SE/treestyletab/treestyletab.dtd        |    2 +
 locale/zh-CN/treestyletab/treestyletab.dtd        |    2 +
 locale/zh-TW/treestyletab/treestyletab.dtd        |    2 +
 modules/autoHide.js                               |   79 +-
 modules/base.js                                   |   31 +-
 modules/bookmark.js                               |   16 +-
 modules/browser.js                                |  283 ++-
 modules/browserUIShowHideObserver.js              |    4 +-
 modules/constants.js                              |    5 +-
 modules/contentBridge.js                          |   41 +-
 modules/fullTooltip.js                            |    4 +-
 modules/fullscreenObserver.js                     |    4 +-
 modules/lib/visuallyselectedTabs.jsm              |  137 +-
 modules/tabContentsObserver.js                    |   42 +-
 modules/tabbarDNDObserver.js                      |   64 +-
 modules/tabpanelDNDObserver.js                    |   88 +-
 modules/utils.js                                  |   23 +-
 modules/window.js                                 |   11 +-
 skin/classic/treestyletab/base-colors.css         |    4 +-
 skin/classic/treestyletab/license.txt             |    2 +-
 skin/classic/treestyletab/metal/base.css          |   11 +-
 skin/classic/treestyletab/metal/tab.css           |   68 +-
 skin/classic/treestyletab/sidebar/license.txt     |    2 +-
 skin/classic/treestyletab/sidebar/sidebar.css     |   21 +-
 skin/classic/treestyletab/square/base.css         |   44 +-
 skin/classic/treestyletab/square/tab-surface.css  |   10 +-
 skin/classic/treestyletab/ui-base.css             |   39 +-
 59 files changed, 2187 insertions(+), 1598 deletions(-)

diff --git a/META-INF/manifest.mf b/META-INF/manifest.mf
index 109187a..54b3c59 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: ok8SN3a3+o+SV5m68kg7oQ==
-SHA1-Digest: FKVqeq5SnvwIO/DRm1FtoCeqqmU=
+MD5-Digest: pm+Yei2qnUyWGMyJhprrRA==
+SHA1-Digest: etoKYWewzVWti5h160DF2R0Ej64=
 
 Name: chrome.manifest
 Digest-Algorithms: MD5 SHA1
@@ -27,8 +27,8 @@ SHA1-Digest: 5rm9f/2UOjYdrD9HD83HZ6rCc40=
 
 Name: content/treestyletab/bookmarksOverlay.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: d7ZAlBLrFBIWE0PZjUstlA==
-SHA1-Digest: dARACbwsGkeTYBFOwDEvzxheFic=
+MD5-Digest: dGbeIhU7n0WubrKqoPWjUA==
+SHA1-Digest: cNlE/B04I3h9co0wNNnMZAFns2c=
 
 Name: content/treestyletab/bookmarksOverlay.xul
 Digest-Algorithms: MD5 SHA1
@@ -57,38 +57,33 @@ SHA1-Digest: ougZFbteusnzVn8djm/xTObCf4Y=
 
 Name: content/treestyletab/config.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: AIdzEUui9m2g7S0U3tOC/Q==
-SHA1-Digest: jTTbgmSo0DamoouORrZaWoX6XWA=
+MD5-Digest: PFY74O4+dACw82W3SXLYOg==
+SHA1-Digest: d82ADUcjWjw8nYuzMPEds3AZxcM=
 
 Name: content/treestyletab/config.xul
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: oWFtj0roEP0prwGgmIbHNQ==
-SHA1-Digest: b9JTBbMbqyEb/TEap1A4V6xMBB8=
+MD5-Digest: 1Ae8zO9zlOnmwerBtxvGWA==
+SHA1-Digest: 7nwlSl7lxdqqttF6HKorLMeZwzo=
 
 Name: content/treestyletab/content-utils-autohide.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 5LerXpT+fFUV2k1YOWLOCw==
-SHA1-Digest: UoiQ5kghSuZB2O1NOtmcO82G6ZY=
+MD5-Digest: zHmJeLmAgXOIHBAQwkCaPA==
+SHA1-Digest: Cvcr0kUfrdcQAyTlBERv4GkFpQY=
 
 Name: content/treestyletab/content-utils.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: QsnrA2FapptFOR6lxTG6yA==
-SHA1-Digest: uS/wFjUiBFLwXTj03xZpzEmzCV8=
+MD5-Digest: AUZamPQrommIIycYq0T0Hg==
+SHA1-Digest: lVsZ0t6gjC9Zn2Y+91cHhps/0OU=
 
 Name: content/treestyletab/group.xul
 Digest-Algorithms: MD5 SHA1
 MD5-Digest: 36AhehtnHOpGrElzTkAIzQ==
 SHA1-Digest: rrjIlOUkUzJsucg+fWIEE+E87n8=
 
-Name: content/treestyletab/hide-embed.css
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: sm1uHHT3GIl7tIYUz8oS5A==
-SHA1-Digest: dVIKETt9CnpIKynmf5iCpf1jDNo=
-
 Name: content/treestyletab/license.txt
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: X5GHdwU0794vTcmyBMKgLA==
-SHA1-Digest: cpaNFJaakJy4ZMTl+Bku6h5c2Nc=
+MD5-Digest: LKtJYTXkH7wM6n0G9Zrf/A==
+SHA1-Digest: gqYGSL+oWwmNaf/w6UF/76tkxJk=
 
 Name: content/treestyletab/multipletabConfigOverlay.xul
 Digest-Algorithms: MD5 SHA1
@@ -102,8 +97,8 @@ SHA1-Digest: r/2Em0TL908f3HKMxB4LqMo/JnQ=
 
 Name: content/treestyletab/treestyletab.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: kJNUcWGpesn1BVrEpRSz6A==
-SHA1-Digest: uacaL+A7qoPJhjFZVXyybrXupu4=
+MD5-Digest: iQFjUJEE3BKly1p71sZ0Ow==
+SHA1-Digest: YyeDoDXNzpNnaa4fzRdysjIn49Y=
 
 Name: content/treestyletab/treestyletab.js
 Digest-Algorithms: MD5 SHA1
@@ -122,18 +117,18 @@ SHA1-Digest: I/ZVyT55v0dNRAoDesMfh/5q9G4=
 
 Name: content/treestyletab/windowHelper.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 5V69QScN5zOJVSvNBNoPKg==
-SHA1-Digest: C47Z/BWUPKkWuGqEVpfUQjVvilw=
+MD5-Digest: 6AyOP+yTzkP7DkFH57dB+w==
+SHA1-Digest: YUbSCnh6h8m5kiJgV277RQlIJ0M=
 
 Name: content/treestyletab/windowHelperHacks.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: it6TPw+aG1fNl6Ppg/58Ig==
-SHA1-Digest: hN8zBmRgPsbjIRku6jLkTdlK8zM=
+MD5-Digest: /3XZX48W1MurtW5Y0fKAXQ==
+SHA1-Digest: d/ZV3e15BQg+QdX9kxZD7q/C/QU=
 
 Name: content/treestyletab/res/bookmarkMultipleTabs.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: swRizGupOdq3NY2Qdi4kGw==
-SHA1-Digest: TmXCzi9HL1KMdtAEY8VpOXNBUcc=
+MD5-Digest: 8XN0Iz35pZHlkZXPTShZvQ==
+SHA1-Digest: 0sLiwVNiwKRASA1p8BmqJLTC8tA=
 
 Name: content/treestyletab/res/icon.png
 Digest-Algorithms: MD5 SHA1
@@ -177,8 +172,8 @@ SHA1-Digest: WzGw9OlK27u2qgwpylJvL+GMB9k=
 
 Name: content/treestyletab/res/tabsDragUtils.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: W2igRSPnTXnMMvsxDSDjlQ==
-SHA1-Digest: l0GL2VhzNq3RKUypfcY3DQrZDdA=
+MD5-Digest: kvB6+SHaD4TCrV72wnLP0A==
+SHA1-Digest: u9srN3Y4BYslaz3AcGUMgnSJADQ=
 
 Name: content/treestyletab/res/twisty-modern-b.png
 Digest-Algorithms: MD5 SHA1
@@ -202,8 +197,8 @@ SHA1-Digest: q0mYa40sk7KoHzdmK6voR/OuGF8=
 
 Name: defaults/preferences/treestyletab.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: wWpQz22fx2VYycBX2FkjAg==
-SHA1-Digest: edDNUr2rBkF8gZkCIHO/2iTZSyw=
+MD5-Digest: YSG5XinxWxzIkcK3MJGuLw==
+SHA1-Digest: BDxjtxqydMshrHgiypby5U5ToWs=
 
 Name: locale/cs/treestyletab/license.txt
 Digest-Algorithms: MD5 SHA1
@@ -212,8 +207,8 @@ SHA1-Digest: AmPIaBSAXJtd03ZD/LGrxu3FN3Y=
 
 Name: locale/cs/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: /mX/xFzRkHcwITPow9LgCg==
-SHA1-Digest: WMnWhoa7Igq6/CETJrTdmoqwkl4=
+MD5-Digest: SGPN+mIPWUEkp9dYq+H2YA==
+SHA1-Digest: p/z/2LihdHgpgWNxiYg2slZrY/A=
 
 Name: locale/cs/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -227,8 +222,8 @@ SHA1-Digest: vjay7k00E2Dhmo0XsTlEeFTRPXI=
 
 Name: locale/da-DK/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: DF/qlqkW+LPOm+xiDtj1tQ==
-SHA1-Digest: COub0FsdcpxqVbVNC7KiWcB4JX8=
+MD5-Digest: aB5lT2NPhsuA8C0aRDVFxg==
+SHA1-Digest: xRbp6Jx7w9a2Q8HAZY1h3fF/L+s=
 
 Name: locale/da-DK/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -242,8 +237,8 @@ SHA1-Digest: JdQfP7XjmROHYlyQEMxiYImBB38=
 
 Name: locale/de-DE/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: WccbaoYXPT5hemDgkG02Zw==
-SHA1-Digest: QJZ9Z7S+QkW7fn9PKyR37RQDhec=
+MD5-Digest: mhpAMTbZgTSfBgUZGFDVzg==
+SHA1-Digest: WeQyJo8ttgBwSOo0mHYX79qV8UI=
 
 Name: locale/de-DE/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -252,13 +247,13 @@ SHA1-Digest: +NBZ9kqAfyhgr7+ZdLZzTHldqtc=
 
 Name: locale/en-US/treestyletab/license.txt
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: mBjJFiEbKENaR38v2Zi3nw==
-SHA1-Digest: /vNGGzRR58QK5AOQjlorkE5GCAI=
+MD5-Digest: c/WYsoPxUcvIGOg+puy8zA==
+SHA1-Digest: VtAh99U52etalcEjrnYVw6pDxCI=
 
 Name: locale/en-US/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: ASou9ZtsPEgWVQMF2IRQrA==
-SHA1-Digest: 4cR3aYnrXvcG7hwpf0cA1Q+xfNc=
+MD5-Digest: CLy//rQYCUznSCjAE0pRag==
+SHA1-Digest: Uxm9xHjoLRkhGza3dnn3OJHnPnw=
 
 Name: locale/en-US/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -272,8 +267,8 @@ SHA1-Digest: OeORv30Cbr8ylQKVbM0O9Y5n+4Y=
 
 Name: locale/es-ES/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 1ISa3rQP4wr/vUx/rgXTeA==
-SHA1-Digest: BaaGstEvjiFHlWS3XOPTROUY0BY=
+MD5-Digest: u/uaPhrBjdV4mYlh2YAHKA==
+SHA1-Digest: E84F7ZwdMDojNxjssnShLIn9uBs=
 
 Name: locale/es-ES/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -287,14 +282,29 @@ SHA1-Digest: eSqlFr5OnT5gIpY1PF7f/E3bHas=
 
 Name: locale/fr-FR/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: MmU2dKfXeLH4MAtJ6fi3dg==
-SHA1-Digest: X6nsnz03rOIR03C0Enh2cHkPgGI=
+MD5-Digest: AJuzFKSUShx6GKv6ZcBTDA==
+SHA1-Digest: fIrjRhoSJvMnWidbM/Gjvh6JNMs=
 
 Name: locale/fr-FR/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
 MD5-Digest: ++Hzis+f+8VGKcUaMXVgyQ==
 SHA1-Digest: GjhFe1p1otrIRII5bMCDGAI+ATM=
 
+Name: locale/gr-EL/treestyletab/license.txt
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: VW7LssOtZslFqlpzeuPLTg==
+SHA1-Digest: sZNjCvNq0L/pyqlYoVExWi+ZETs=
+
+Name: locale/gr-EL/treestyletab/treestyletab.dtd
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: TWzfGZGQPA/UNYNDWw/VSw==
+SHA1-Digest: mJesJwLRrOgQjhKvNH/knwPYDl0=
+
+Name: locale/gr-EL/treestyletab/treestyletab.properties
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: X69UUjBkijZQQP2vZoNZJg==
+SHA1-Digest: pAEtKGQEg5zBkZbvcQ5xjATQmyk=
+
 Name: locale/it-IT/treestyletab/license.txt
 Digest-Algorithms: MD5 SHA1
 MD5-Digest: fzikcfeUYYGLBHSPKxs+ZQ==
@@ -302,8 +312,8 @@ SHA1-Digest: DqBJQrV8f3tss7fKSnCdeXNIxYs=
 
 Name: locale/it-IT/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: R8I9lkof+2i7nzfRcCfSRg==
-SHA1-Digest: yvs8t+u6XPVP1d778dAZL3JB6wE=
+MD5-Digest: Y1W8CX+/YwBJirWGxkVSzg==
+SHA1-Digest: iBeaWegQzQYM7Jv4ZP8mIWwKCRc=
 
 Name: locale/it-IT/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -312,13 +322,13 @@ SHA1-Digest: KSVrFtHQQ1VuVt1A6Ic0ebJu6g0=
 
 Name: locale/ja/treestyletab/license.txt
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: mBjJFiEbKENaR38v2Zi3nw==
-SHA1-Digest: /vNGGzRR58QK5AOQjlorkE5GCAI=
+MD5-Digest: c/WYsoPxUcvIGOg+puy8zA==
+SHA1-Digest: VtAh99U52etalcEjrnYVw6pDxCI=
 
 Name: locale/ja/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: jlz78yuKfyWP0RqbsJQoLw==
-SHA1-Digest: lFUmY8dsbbw9c1AaRThB5ykK1PI=
+MD5-Digest: mCxhN7+e9df1JXm5YPk+eQ==
+SHA1-Digest: 1nXVSxxi15SMZcvdRa1FaFg1MmE=
 
 Name: locale/ja/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -332,8 +342,8 @@ SHA1-Digest: JwRGjnhAsrasY46ktL+EtP3fxDI=
 
 Name: locale/pl/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 05JWMIjA1YJEJ8QnOPDMzg==
-SHA1-Digest: 112CqdOybA+tAyb1vWPhBsl5g8o=
+MD5-Digest: CZB5rvoXUGidweD1O4WnDw==
+SHA1-Digest: lD8rLONf7RCVDl9vfV7+DJgsgH4=
 
 Name: locale/pl/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -347,8 +357,8 @@ SHA1-Digest: Ewz5/CWtInQDfBCQoje+iGZbjEE=
 
 Name: locale/ru/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: aGUwY4SQARaxSP5aW8m5Zg==
-SHA1-Digest: kvaRTT8I2w1ed/qOmNwoiriEmz4=
+MD5-Digest: fmtz4TC8/e3aNOTtOsZ0pg==
+SHA1-Digest: Ak5QkLr0AC3anqtmYfdt14j1Z84=
 
 Name: locale/ru/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -362,8 +372,8 @@ SHA1-Digest: Zfn4AKRpBe4E44Sg1HIuoxFmif0=
 
 Name: locale/sv-SE/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: zfQPbROEGag5+VsSQWE9Mg==
-SHA1-Digest: uYkQNqCRb/RGZhwvqKmFRbDOSU0=
+MD5-Digest: xgHYVBA0o66MW8owNmmS6g==
+SHA1-Digest: zjiRXvuGwJTtmeXoI0VEHBKvUN4=
 
 Name: locale/sv-SE/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -377,8 +387,8 @@ SHA1-Digest: CxdX2iIT5cw2WR+1eMh9AA78n+U=
 
 Name: locale/zh-CN/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 9tCPNHJbg5S+2yxxbT86YA==
-SHA1-Digest: Zp3pDIoHeenUkT6SAlxb1I6GKU0=
+MD5-Digest: cg0PJ45qzXV0JOenV+dt1A==
+SHA1-Digest: 6pBFYgulvF4L2GCIRkbX76s0XyA=
 
 Name: locale/zh-CN/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -392,8 +402,8 @@ SHA1-Digest: XVqJMKhADCM73LtM7OFthNdECYo=
 
 Name: locale/zh-TW/treestyletab/treestyletab.dtd
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: ZFU8RjBxpI5mULkjIgGmmg==
-SHA1-Digest: BVst1wseNpdYpEJg1GHaawsRzR4=
+MD5-Digest: /BKmCDFXGXi3eV6Pp1qP+A==
+SHA1-Digest: c3ZwouiA4bEXtqCoTtBjc3Rc3ig=
 
 Name: locale/zh-TW/treestyletab/treestyletab.properties
 Digest-Algorithms: MD5 SHA1
@@ -402,48 +412,48 @@ SHA1-Digest: IjvrITYIupuo8dctlLwODAQN0BA=
 
 Name: modules/autoHide.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: VidzELRdPedzq49PM6oItA==
-SHA1-Digest: +/qy0uitgU5SPYj2Srgo0JhYVS4=
+MD5-Digest: rQcnT08lMJmRNLv+n59OWA==
+SHA1-Digest: Pfnmto9TimBYDSR7XJQgcSKX9Uc=
 
 Name: modules/base.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: NY09SYs8FgmLYUMeKNS7Sw==
-SHA1-Digest: JcRExlbc6cV3n5oO997KTDWmDW8=
+MD5-Digest: r2rXbDMix62LcaeCDyjPIg==
+SHA1-Digest: tOOgBRYHSEuhrdS7d3qtwARgs1c=
 
 Name: modules/bookmark.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: cMDEMd+g9AJgYNPfrkNRcw==
-SHA1-Digest: TrQsPd9SmcWiBJYkoSYNVTI7ozQ=
+MD5-Digest: EBZk78Mr/GLOa5OHi7pCkw==
+SHA1-Digest: ypaUVLviHJ/rbpCU85Db6+FMv8I=
 
 Name: modules/browser.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: PE9e1osB7awEdhSNvDD79w==
-SHA1-Digest: NSWCx6j3JpSNJ+QLzwXk5b1dwmA=
+MD5-Digest: NRqaHSSuVubXs4qHSpNSyQ==
+SHA1-Digest: r2X1g3qW+R1GLGJFOtpYD+6I/aY=
 
 Name: modules/browserUIShowHideObserver.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: dNk/UnlE0F8L4dJZICP6Nw==
-SHA1-Digest: D84Jbg20wtUqqgG4pWCgF9ZdVaw=
+MD5-Digest: bAS9zmrRzU1+UeGniocAug==
+SHA1-Digest: VnPrxjkloHHtwjsBKY05je/aR3M=
 
 Name: modules/constants.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: payijolyNJwx0JZmOWKjrA==
-SHA1-Digest: W/IH3sanSLwefhuwDu9mbL4uSlY=
+MD5-Digest: dLp1PIsRBAFdMf9gH4SfUg==
+SHA1-Digest: Q8j66uhbexuKZU8lRU3DZ5Hb5j4=
 
 Name: modules/contentBridge.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: ehtVEsZbRr6L1MVVUWVmvQ==
-SHA1-Digest: mA6dCavjo4R/7g9zpynkywxjUIY=
+MD5-Digest: Ub1Yv4IaG0rytsu40nzomA==
+SHA1-Digest: C6G2mqGEPD2yRJtNii+wEK6HPRA=
 
 Name: modules/fullscreenObserver.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: TKVwSD0v1bAX/oWKo8OerA==
-SHA1-Digest: cc6D7hos4bGfa5ReVduq0YkLnWI=
+MD5-Digest: JcuMJIL/gU4nV5iw57B2Rw==
+SHA1-Digest: GzeWNuXjs/QaMG9RIn77+9csKhU=
 
 Name: modules/fullTooltip.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: xVYm0qhioUh6O3YiHx26SA==
-SHA1-Digest: a+Z05xMoNkBVAvfMkJegFF6kqLM=
+MD5-Digest: nm9WkNVJzZ2s3sRAh/Xq2w==
+SHA1-Digest: RPkFo7rJ+DXyxsFF/cG6fwlz1WI=
 
 Name: modules/getHashString.js
 Digest-Algorithms: MD5 SHA1
@@ -472,18 +482,18 @@ SHA1-Digest: a4KpeD2z5f3xYaa//UQGtAA5+j0=
 
 Name: modules/tabbarDNDObserver.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: ePbqeE1Xe4Ajr7pr4WUtLA==
-SHA1-Digest: VQWhk6o3Tigb7hcuUn0Z2gvOxn0=
+MD5-Digest: TpWTDxP3FCaK2Li16KZdgQ==
+SHA1-Digest: a/JsjeBWG3PET6HoXOG5VDprNWo=
 
 Name: modules/tabContentsObserver.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: Mx8Cw+iPLWSjkNjv10xCXg==
-SHA1-Digest: XZJFvYTu9pPIFV+zY9hH2IJsTKM=
+MD5-Digest: qe9tWs3cVPBUdlHTgYGBmg==
+SHA1-Digest: 0GVhJL6QCyuaSHQaEWohmXlpPKE=
 
 Name: modules/tabpanelDNDObserver.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: viIk0SD+R9Tc1k0cMgf98g==
-SHA1-Digest: NGDF4zuUWe9dhiX73LMiqEKgBnk=
+MD5-Digest: xt+OCkhuRWFkJWqtYiNMrg==
+SHA1-Digest: 2yAKPTGgE5HyHRCmjkfc1krjO88=
 
 Name: modules/themeManager.js
 Digest-Algorithms: MD5 SHA1
@@ -492,13 +502,13 @@ SHA1-Digest: lOTZlS8mhjdv/2i2EG9Md07Pv04=
 
 Name: modules/utils.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 5ngRS8P2lMHI/5rpiR3Gbg==
-SHA1-Digest: yrWQTBgmfdFT3cSY8nOFNAadyo0=
+MD5-Digest: avFtTqvF5ObZtijxiW6lfg==
+SHA1-Digest: dzmTXIhBpZQ8tXgZvE0FkQyMSZo=
 
 Name: modules/window.js
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 9Kff0V+6uCIzpuUZaC7YWA==
-SHA1-Digest: k8Zk3rINL4KJj8CvKVl7G7BCTkY=
+MD5-Digest: apimRkYTEdPXg51ICAM2KQ==
+SHA1-Digest: 16TOTjFS4XyW05JPn677Kt3GVnI=
 
 Name: modules/lib/animationManager.js
 Digest-Algorithms: MD5 SHA1
@@ -547,13 +557,13 @@ SHA1-Digest: hClSyDJ2d9GMHdEuxFZjDybYBG4=
 
 Name: modules/lib/visuallyselectedTabs.jsm
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: iwd/kfZCQaJsjIkO/emj/A==
-SHA1-Digest: 8xOI2kAUhlzs7UzFQRh5ibWEhDQ=
+MD5-Digest: DTQuFccOuehA+TXdQ60CHg==
+SHA1-Digest: pqFLbh0sXGqtivaGirrJPjKdFCE=
 
 Name: skin/classic/treestyletab/base-colors.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: SjrszT+A7vBprStrxmTJ8Q==
-SHA1-Digest: R3y7LGy9olYjQJ53N4N492LTNog=
+MD5-Digest: H2HMme2+COFgc9kytMqu8A==
+SHA1-Digest: OoJ73ar4CTP/bWgach3ddAIu/PM=
 
 Name: skin/classic/treestyletab/base.css
 Digest-Algorithms: MD5 SHA1
@@ -597,8 +607,8 @@ SHA1-Digest: PSBTYQzFMTkunW+ORGpKAXaena8=
 
 Name: skin/classic/treestyletab/license.txt
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: Tc+NDhBc7EP4cr5OqQGQyQ==
-SHA1-Digest: TLhlpxf44EXADPU56xRsRroxdo4=
+MD5-Digest: c/WYsoPxUcvIGOg+puy8zA==
+SHA1-Digest: VtAh99U52etalcEjrnYVw6pDxCI=
 
 Name: skin/classic/treestyletab/Linux-base.css
 Digest-Algorithms: MD5 SHA1
@@ -632,8 +642,8 @@ SHA1-Digest: /CcGFdIzQT8ebf8twW9s6P1rRRI=
 
 Name: skin/classic/treestyletab/ui-base.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 1xmdG4x6c5gzfd06X8W05w==
-SHA1-Digest: 37cdHXqzb070RqjKqcqaCu56lio=
+MD5-Digest: 6vSIobYZmB4C2qH1rxIeIg==
+SHA1-Digest: xBdcaEeo//lmOhyNCPBCYWzv9ig=
 
 Name: skin/classic/treestyletab/WINNT-base.css
 Digest-Algorithms: MD5 SHA1
@@ -652,8 +662,8 @@ SHA1-Digest: V/bHzXC5rqlG5ibTq+FRKJ42G8Q=
 
 Name: skin/classic/treestyletab/metal/base.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: VSkSLXcxYmzkFqHNeXvlBA==
-SHA1-Digest: zlNvl7EAnEaBsDgcPEp55c0QoZI=
+MD5-Digest: b06yHliwY1umcUpkYpBp+w==
+SHA1-Digest: Lx3HUxba6pEQiUrvz7wnzdWuopk=
 
 Name: skin/classic/treestyletab/metal/Darwin.css
 Digest-Algorithms: MD5 SHA1
@@ -727,8 +737,8 @@ SHA1-Digest: u2GHUKdU+s+jbRmxFO5motzr4+0=
 
 Name: skin/classic/treestyletab/metal/tab.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: 69xmnTZqMZnraOpMHOLg6A==
-SHA1-Digest: vL0wimEoqQ73hnEe532ADXF2WFs=
+MD5-Digest: Nm5hQLmGjqx2N79zAkWPEA==
+SHA1-Digest: v9cB41Wwqj6ta85aQXuo4lEsgQs=
 
 Name: skin/classic/treestyletab/sidebar/aero.css
 Digest-Algorithms: MD5 SHA1
@@ -752,18 +762,18 @@ SHA1-Digest: 3ySucjnqrJTu7fWRs6EehENF6mk=
 
 Name: skin/classic/treestyletab/sidebar/license.txt
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: v9Eq0lPqaRSdBuATG2+oxg==
-SHA1-Digest: VNJPj9nckqPyRb2Ff3HWiGPQE58=
+MD5-Digest: 6cPOIxQHi8OpKcOgEJ5csQ==
+SHA1-Digest: 3m1QqrFY+pAv2hBsP+RzTreAfk8=
 
 Name: skin/classic/treestyletab/sidebar/sidebar.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: g+EE5ZihUvm1aCVLFb9fng==
-SHA1-Digest: LbEU6Zc8S7yiMgwIQhFCEEb/3oo=
+MD5-Digest: HcSiMHPmmsqs9KBq+z542w==
+SHA1-Digest: b+hcW/ms0rLZw7I1fIqFhxkNHLg=
 
 Name: skin/classic/treestyletab/square/base.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: ppeu5ZCdvWUDuUWajaN1Ig==
-SHA1-Digest: 0oiB6fmuq/ZPS+r37TpxPnXdcRI=
+MD5-Digest: MUtEHxlN1FcRBqt66ryKvQ==
+SHA1-Digest: kzteCDVniq8lSwKuXWUY+88Bv7I=
 
 Name: skin/classic/treestyletab/square/Darwin.css
 Digest-Algorithms: MD5 SHA1
@@ -817,8 +827,8 @@ SHA1-Digest: CTg4j0P/755VUethbwqkLbDrXcI=
 
 Name: skin/classic/treestyletab/square/tab-surface.css
 Digest-Algorithms: MD5 SHA1
-MD5-Digest: Z45sYxcnpMfZ0LsF3MP5Aw==
-SHA1-Digest: f0O5oT3oEzWSTr2hkBtuW5olTMY=
+MD5-Digest: HqzdIXD/FQc22FTZTCiFqg==
+SHA1-Digest: hjZuQ+52dONpgsjPcMzwqSCJfiE=
 
 Name: skin/classic/treestyletab/square/vertigo.css
 Digest-Algorithms: MD5 SHA1
diff --git a/META-INF/mozilla.rsa b/META-INF/mozilla.rsa
index 652d76f..565f2e7 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 99222e0..8fdad47 100644
--- a/META-INF/mozilla.sf
+++ b/META-INF/mozilla.sf
@@ -1,4 +1,4 @@
 Signature-Version: 1.0
-MD5-Digest-Manifest: Ix40zU3MtJOexcl79CmDWg==
-SHA1-Digest-Manifest: PyiHX5XkupIsPIdAzTfX20IYorU=
+MD5-Digest-Manifest: XPTKS/2vUh6zcZ51fBLG5A==
+SHA1-Digest-Manifest: fk5+Lu2Jjmw/jI2T46FBTfcx18g=
 
diff --git a/content/treestyletab/bookmarksOverlay.js b/content/treestyletab/bookmarksOverlay.js
index c110075..38d7f54 100644
--- a/content/treestyletab/bookmarksOverlay.js
+++ b/content/treestyletab/bookmarksOverlay.js
@@ -68,7 +68,7 @@ var TreeStyleTabBookmarksUIService = inherit(TreeStyleTabService, {
 		if (
 			groups.length == 1 &&
 			this.bookmarkDroppedTabsBehavior() != this.kBOOKMARK_DROPPED_TABS_ALL &&
-			!Array.some(tabs, function(aTab) {
+			![...aTabs].some(function(aTab) {
 				return aTab.getAttribute('multiselected') == 'true';
 			})
 			) {
diff --git a/content/treestyletab/config.js b/content/treestyletab/config.js
index 7fbbefe..d9158c7 100644
--- a/content/treestyletab/config.js
+++ b/content/treestyletab/config.js
@@ -67,7 +67,7 @@ function initAppearancePane()
 			document.getElementById('extensions.treestyletab.tabbar.style-arrowscrollbox'),
 			document.getElementById('extensions.treestyletab.twisty.style-arrowscrollbox')
 		];
-	Array.slice(boxes[0].childNodes).concat(Array.slice(boxes[1].childNodes)).forEach(function(aItem) {
+	[...boxes[0].childNodes].concat([...boxes[1].childNodes]).forEach(function(aItem) {
 		let start       = 0;
 		let delta       = 200;
 		let radian      = 90 * Math.PI / 180;
diff --git a/content/treestyletab/config.xul b/content/treestyletab/config.xul
index 78ced9d..631eef5 100644
--- a/content/treestyletab/config.xul
+++ b/content/treestyletab/config.xul
@@ -522,9 +522,12 @@
 		<preference id="extensions.treestyletab.tabbar.autoHide.area"
 			name="extensions.treestyletab.tabbar.autoHide.area"
 			type="int"/>
-		<preference id="extensions.treestyletab.tabbar.autoHide.delay"
-			name="extensions.treestyletab.tabbar.autoHide.delay"
+		<preference id="extensions.treestyletab.tabbar.autoHide.delay.show"
+			name="extensions.treestyletab.tabbar.autoHide.delay.show"
 			type="int"/>
+		<preference id="extensions.treestyletab.tabbar.autoShow.click"
+			name="extensions.treestyletab.tabbar.autoShow.click"
+			type="bool"/>
 		<preference id="extensions.treestyletab.tabbar.autoShow.accelKeyDown"
 			name="extensions.treestyletab.tabbar.autoShow.accelKeyDown"
 			type="bool"/>
@@ -577,9 +580,9 @@
 					extensions.treestyletab.tabbar.autoHide.area-before
 					extensions.treestyletab.tabbar.autoHide.area-textbox
 					extensions.treestyletab.tabbar.autoHide.area-after
-					extensions.treestyletab.tabbar.autoHide.delay-before
-					extensions.treestyletab.tabbar.autoHide.delay-textbox
-					extensions.treestyletab.tabbar.autoHide.delay-after
+					extensions.treestyletab.tabbar.autoHide.delay.show-before
+					extensions.treestyletab.tabbar.autoHide.delay.show-textbox
+					extensions.treestyletab.tabbar.autoHide.delay.show-after
 				"/>
 			<hbox align="center">
 				<spacer style="width:1em;"/>
@@ -596,17 +599,20 @@
 			</hbox>
 			<hbox align="center">
 				<spacer style="width:1em;"/>
-				<label id="extensions.treestyletab.tabbar.autoHide.delay-before"
+				<label id="extensions.treestyletab.tabbar.autoHide.delay.show-before"
 					value="&config.autoHide.delay.before;"
-					control="extensions.treestyletab.tabbar.autoHide.delay-textbox"/>
-				<textbox id="extensions.treestyletab.tabbar.autoHide.delay-textbox"
-					preference="extensions.treestyletab.tabbar.autoHide.delay"
+					control="extensions.treestyletab.tabbar.autoHide.delay.show-textbox"/>
+				<textbox id="extensions.treestyletab.tabbar.autoHide.delay.show-textbox"
+					preference="extensions.treestyletab.tabbar.autoHide.delay.show"
 					type="number"
 					min="0" increment="1" style="width:4em;"/>
-				<label id="extensions.treestyletab.tabbar.autoHide.delay-after"
+				<label id="extensions.treestyletab.tabbar.autoHide.delay.show-after"
 					value="&config.autoHide.delay.after;"
-					control="extensions.treestyletab.tabbar.autoHide.delay-textbox"/>
+					control="extensions.treestyletab.tabbar.autoHide.delay.show-textbox"/>
 			</hbox>
+			<checkbox id="extensions.treestyletab.tabbar.autoShow.click-check"
+				preference="extensions.treestyletab.tabbar.autoShow.click"
+				label="&config.autoShow.click;"/>
 			<checkbox id="extensions.treestyletab.tabbar.autoShow.accelKeyDown-check"
 				preference="extensions.treestyletab.tabbar.autoShow.accelKeyDown"
 				label="&config.autoShow.accelKeyDown;"
@@ -744,6 +750,7 @@
 		<radiogroup id="extensions.treestyletab.insertNewChildAt-radiogroup"
 			preference="extensions.treestyletab.insertNewChildAt"
 			orient="vertical">
+			<radio value="-1" label="&config.insertNewChildAt.noControl;"/>
 			<radio value="0" label="&config.insertNewChildAt.first;"/>
 			<radio value="1" label="&config.insertNewChildAt.last;"/>
 		</radiogroup>
diff --git a/content/treestyletab/content-utils-autohide.js b/content/treestyletab/content-utils-autohide.js
index af4ed48..88dffbd 100644
--- a/content/treestyletab/content-utils-autohide.js
+++ b/content/treestyletab/content-utils-autohide.js
@@ -32,7 +32,7 @@
 			aFrame &&
 			(
 				aFrame.document.querySelector('embed, object') ||
-				Array.some(aFrame.frames, hasPluginArea)
+				Array.prototype.some.call(aFrame.frames, hasPluginArea)
 			)
 		);
 	}
diff --git a/content/treestyletab/content-utils.js b/content/treestyletab/content-utils.js
index 1efa6d3..d5e969e 100644
--- a/content/treestyletab/content-utils.js
+++ b/content/treestyletab/content-utils.js
@@ -93,10 +93,11 @@
 		collectLocations : function(aFrame, aLocations) {
 			aLocations = aLocations || {};
 			aLocations[aFrame.location.href] = true;
-			Array.forEach(aFrame.document.getElementsByTagName('base'), function(aBase) {
+			for (let aBase of aFrame.document.getElementsByTagName('base'))
+			{
 				aLocations[aBase.href] = true;
-			}, this);
-			Array.forEach(aFrame.frames, function(aSubFrame) {
+			}
+			Array.prototype.forEach.call(aFrame.frames, function(aSubFrame) {
 				this.collectLocations(aSubFrame, aLocations);
 			}, this);
 			return Object.keys(aLocations);
diff --git a/content/treestyletab/hide-embed.css b/content/treestyletab/hide-embed.css
deleted file mode 100644
index 6dce1c7..0000000
--- a/content/treestyletab/hide-embed.css
+++ /dev/null
@@ -1,5 +0,0 @@
- at namespace url("http://www.w3.org/1999/xhtml");
-
-body > embed[name="plugin"] {
-	visibility: hidden !important;
-}
diff --git a/content/treestyletab/license.txt b/content/treestyletab/license.txt
index 7c22cef..a6c6d12 100644
--- a/content/treestyletab/license.txt
+++ b/content/treestyletab/license.txt
@@ -14,7 +14,7 @@ License.
 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) 2007-2016
+Portions created by the Initial Developer are Copyright (C) 2007-2017
 the Initial Developer. All Rights Reserved.
 
 Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
diff --git a/content/treestyletab/res/bookmarkMultipleTabs.js b/content/treestyletab/res/bookmarkMultipleTabs.js
index b9cd288..be93b3c 100644
--- a/content/treestyletab/res/bookmarkMultipleTabs.js
+++ b/content/treestyletab/res/bookmarkMultipleTabs.js
@@ -16,7 +16,7 @@
  *   http://github.com/piroor/fxaddonlib-bookmark-multiple-tabs
  */
 (function() {
-	const currentRevision = 8;
+	const currentRevision = 9;
 
 	if (!('BookmarkPropertiesPanel' in window)) {
 		window.addEventListener('DOMContentLoaded', function() {
@@ -56,7 +56,7 @@
 					if ('PlacesUIUtils' in window || 'PlacesUtils' in window) { // Firefox 3 or later
 						try {
 							var utils = 'PlacesUIUtils' in window ? PlacesUIUtils : PlacesUtils ;
-							var tabs = Array.slice(aTabs).map(this.addBookmarkTabsFilter);
+							var tabs = [...aTabs].map(this.addBookmarkTabsFilter);
 							if (aFolderName)
 								this.Prefs.setCharPref('temp.showMinimalAddMultiBookmarkUI.folderName', unescape(encodeURIComponent(aFolderName)));
 							if ('showBookmarkDialog' in utils) { // Firefox 9 or later
@@ -82,7 +82,7 @@
 					}
 
 					var currentTabInfo;
-					var tabsInfo = Array.slice(aTabs).map(function(aTab) {
+					var tabsInfo = [...aTabs].map(function(aTab) {
 							var webNav = aTab.linkedBrowser.webNavigation;
 							var url    = webNav.currentURI.spec;
 							var name   = '';
diff --git a/content/treestyletab/res/tabsDragUtils.js b/content/treestyletab/res/tabsDragUtils.js
index df17e19..1e80978 100644
--- a/content/treestyletab/res/tabsDragUtils.js
+++ b/content/treestyletab/res/tabsDragUtils.js
@@ -1,1046 +1,977 @@
-/*
- Multiple Tabs Drag and Drop Utilities for Firefox 45 or later
-
- Usage:
-   window['piro.sakura.ne.jp'].tabsDragUtils.initTabBrowser(gBrowser);
-
-   // in dragstart event listener
-   window['piro.sakura.ne.jp'].tabsDragUtils.startTabsDrag(aEvent, aArrayOfTabs, {
-     shrinkOthers : true // shrink other dragged tabs while dragging
-   });
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- original:
-   http://github.com/piroor/fxaddonlib-tabs-drag-utils
-*/
-(function() {
-	const currentRevision = 42;
-
-	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
-
-	var loadedRevision = 'tabsDragUtils' in window['piro.sakura.ne.jp'] ?
-			window['piro.sakura.ne.jp'].tabsDragUtils.revision :
-			0 ;
-	if (loadedRevision && loadedRevision >= currentRevision) {
-		return;
-	}
-
-	if (loadedRevision &&
-		'destroy' in window['piro.sakura.ne.jp'].tabsDragUtils)
-		window['piro.sakura.ne.jp'].tabsDragUtils.destroy();
-
-	const Cc = Components.classes;
-	const Ci = Components.interfaces;
-	const TAB_DROP_TYPE = 'application/x-moz-tabbrowser-tab';
-
-	var tabsDragUtils = {
-		revision : currentRevision,
-
-		// "nsDOM" prefix is required!
-		// https://developer.mozilla.org/en/Creating_Custom_Events_That_Can_Pass_Data
-		EVENT_TYPE_TABS_DROP : 'nsDOMMultipleTabsDrop',
-
-		isTabNeedToBeRestored: function(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;
-		},
-		getRestoringData: function(aTab)
-		{
-			var data = aTab.linkedBrowser.__SS_data;
-			if (!data && this.TabStateCache) // Firefox 23-
-				data = this.TabStateCache.get(aTab.linkedBrowser);
-			return data;
-		},
-		get TabStateCache() {
-			return this.SessionStoreNS.TabStateCache;
-		},
-		get SessionStoreNS() {
-			delete this.SessionStoreNS;
-			try {
-				// resource://app/modules/sessionstore/SessionStore.jsm ?
-				this.SessionStoreNS = Components.utils.import('resource:///modules/sessionstore/SessionStore.jsm', {});
-			}
-			catch(e) {
-				this.SessionStoreNS = {};
-			}
-			return this.SessionStoreNS;
-		},
-
-		init : function TDU_init()
-		{
-			window.addEventListener('load', this, false);
-		},
-		_delayedInit : function TDU_delayedInit()
-		{
-			window.removeEventListener('load', this, false);
-			delete this._delayedInit;
-
-			if (
-				'PlacesControllerDragHelper' in window &&
-				'onDrop' in PlacesControllerDragHelper &&
-				!PlacesControllerDragHelper.__TabsDragUtils_original__onDrop
-				) {
-				let original = PlacesControllerDragHelper.onDrop;
-				PlacesControllerDragHelper.__TabsDragUtils_original__onDrop = original;
-				if (PlacesControllerDragHelper.onDrop.isAsyncFunction) {
-					PlacesControllerDragHelper.onDrop = Task.async(function(insertionPoint, dt) {
-						dt = new window["piro.sakura.ne.jp"].tabsDragUtils.DOMDataTransferProxy(dt, insertionPoint);
-						// for Tree Style Tab (save tree structure to bookmarks)
-						if (dt &&
-							'_tabs' in dt &&
-							'TreeStyleTabBookmarksService' in window)
-							TreeStyleTabBookmarksService.beginAddBookmarksFromTabs(dt._tabs);
-						yield PlacesControllerDragHelper.__TabsDragUtils_original__onDrop.call(this, insertionPoint, dt)
-								.then(function(aResult) {
-									if (dt &&
-										'_tabs' in dt &&
-										'TreeStyleTabBookmarksService' in window)
-										TreeStyleTabBookmarksService.endAddBookmarksFromTabs(dt._tabs);
-								});
-					});
-				}
-				PlacesControllerDragHelper.__TabsDragUtils_updated__onDrop = PlacesControllerDragHelper.onDrop;
-			}
-
-			if ('TMP_tabDNDObserver' in window) // for Tab Mix Plus
-				this.initTabDNDObserver(TMP_tabDNDObserver);
-			else if ('TabDNDObserver' in window)	// for old Tab Mix Plus
-				this.initTabDNDObserver(TabDNDObserver);
-		},
-		destroy : function TDU_destroy()
-		{
-			if (this._delayedInit)
-				window.removeEventListener('load', this, false);
-
-			if (PlacesControllerDragHelper.onDrop == PlacesControllerDragHelper.__TabsDragUtils_updated__onDrop)
-				PlacesControllerDragHelper.onDrop = PlacesControllerDragHelper.__TabsDragUtils_original__onDrop;
-			delete PlacesControllerDragHelper.__TabsDragUtils_original__onDrop;
-			delete PlacesControllerDragHelper.__TabsDragUtils_updated__onDrop;
-
-			this.updatedTabDNDObservers.slice(0).forEach(this.destroyTabDNDObserver, this);
-		},
-
-		initTabBrowser : function TDU_initTabBrowser(aTabBrowser)
-		{
-			this.initTabDNDObserver(aTabBrowser.tabContainer);
-		},
-		destroyTabBrowser : function TDU_destroyTabBrowser(aTabBrowser)
-		{
-			this.destroyTabDNDObserver(aTabBrowser.tabContainer);
-		},
-
-		updatedTabDNDObservers : [],
-		initTabDNDObserver : function TDU_initTabDNDObserver(aObserver)
-		{
-			this.updatedTabDNDObservers.push(aObserver);
-
-			if (typeof aObserver._getDropEffectForTabDrag === 'function' &&
-				!aObserver.__tabsDragUtils__getDropEffectForTabDrag) {
-				aObserver.__tabsDragUtils_original__getDropEffectForTabDrag = aObserver._getDropEffectForTabDrag;
-				aObserver._getDropEffectForTabDrag = function(event) {
-/**
- * Original:
- *  base version: Nightly 51.0a1
- *  date        : 2016-09-04
- *  source      : https://dxr.mozilla.org/mozilla-central/rev/1789229965bfc5e7b08dfcf1c054c366abe1267a/browser/base/content/tabbrowser.xml#5545
- */
-//=====================================================================
-          var dt = event.dataTransfer;
-          // Disallow dropping multiple items
-//          if (dt.mozItemCount > 1)
-          if (dt.mozItemCount > 1 && !window['piro.sakura.ne.jp'].tabsDragUtils.isTabsDragging(event))
-            return "none";
-
-          var types = dt.mozTypesAt(0);
-          // tabs are always added as the first type
-          if (types[0] == TAB_DROP_TYPE) {
-            let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-            if (sourceNode instanceof XULElement &&
-                sourceNode.localName == "tab" &&
-                sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
-                sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
-                sourceNode.ownerDocument.defaultView.gBrowser.tabContainer == sourceNode.parentNode) {
-              // Do not allow transfering a private tab to a non-private window
-              // and vice versa.
-              if (PrivateBrowsingUtils.isWindowPrivate(window) !=
-                  PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerDocument.defaultView))
-                return "none";
-
-              if (window.gMultiProcessBrowser !=
-                  sourceNode.ownerDocument.defaultView.gMultiProcessBrowser)
-                return "none";
-
-              return dt.dropEffect == "copy" ? "copy" : "move";
-            }
-          }
-
-          if (browserDragAndDrop.canDropLink(event)) {
-            return "link";
-          }
-          return "none";
-//=====================================================================
-				};
-				aObserver.__TabsDragUtils_updated__getDropEffectForTabDrag = aObserver._getDropEffectForTabDrag;
-			}
-
-			if ('_animateTabMove' in aObserver &&
-				!aObserver.__TabsDragUtils_original__animateTabMove) {
-				let original = aObserver._animateTabMove;
-				aObserver.__TabsDragUtils_original__animateTabMove = original;
-				aObserver._animateTabMove = function _animateTabMove(event, aOptions) {
-/**
- * Original:
- *  base version: Nightly 51.0a1
- *  date        : 2016-09-04
- *  source      : https://dxr.mozilla.org/mozilla-central/rev/1789229965bfc5e7b08dfcf1c054c366abe1267a/browser/base/content/tabbrowser.xml#5303
- */
-//=====================================================================
-var TDUContext = window["piro.sakura.ne.jp"].tabsDragUtils.setupContext(event, aOptions);
-          let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
-draggedTab = TDUContext.draggedTab;
-
-          if (this.getAttribute("movingtab") != "true") {
-            this.setAttribute("movingtab", "true");
-            this.selectedItem = draggedTab;
-          }
-
-          if (!("animLastScreenX" in draggedTab._dragData)) {
-//            draggedTab._dragData.animLastScreenX = draggedTab._dragData.screenX;
-            draggedTab._dragData.animLastScreenX = draggedTab._dragData[TDUContext.position];
-          }
-
-TDUContext.utils.setupDraggedTabs(TDUContext);
-
-//          let screenX = event.screenX;
-          let screenX = event[TDUContext.position];
-          if (screenX == draggedTab._dragData.animLastScreenX)
-            return;
-
-          let draggingRight = screenX > draggedTab._dragData.animLastScreenX;
-          draggedTab._dragData.animLastScreenX = screenX;
-
-TDUContext.utils.updateDraggedTabs(TDUContext);
-
-          let rtl = (window.getComputedStyle(this).direction == "rtl");
-          let pinned = draggedTab.pinned;
-          let numPinned = this.tabbrowser._numPinnedTabs;
-          let tabs = this.tabbrowser.visibleTabs
-                                    .slice(pinned ? 0 : numPinned,
-                                           pinned ? numPinned : undefined);
-          if (rtl)
-            tabs.reverse();
-//          let tabWidth = draggedTab.getBoundingClientRect().width;
-          let tabWidth = draggedTab.getBoundingClientRect()[TDUContext.size];
-
-          // Move the dragged tab based on the mouse position.
-
-tabs = TDUContext.utils.collectAnimateTabs(tabs, TDUContext);
-
-          let leftTab = tabs[0];
-          let rightTab = tabs[tabs.length - 1];
-//          let tabScreenX = draggedTab.boxObject.screenX;
-          let tabScreenX = draggedTab.boxObject[TDUContext.position];
-//          let translateX = screenX - draggedTab._dragData.screenX;
-          let translateX = screenX - draggedTab._dragData[TDUContext.position];
-          if (!pinned) {
-//            translateX += this.mTabstrip.scrollPosition - draggedTab._dragData.scrollX;
-            translateX += this.mTabstrip.scrollPosition - draggedTab._dragData[TDUContext.scroll];
-          }
-//          let leftBound = leftTab.boxObject.screenX - tabScreenX;
-          let leftBound = leftTab.boxObject[TDUContext.position] - tabScreenX;
-//          let rightBound = (rightTab.boxObject.screenX + rightTab.boxObject.width) -
-//                           (tabScreenX + tabWidth);
-          let rightBound = (rightTab.boxObject[TDUContext.position] + rightTab.boxObject[TDUContext.size]) -
-                           (tabScreenX + tabWidth);
-
-leftBound = TDUContext.utils.updateLeftBound(leftBound, TDUContext);
-rightBound = TDUContext.utils.updateRightBound(rightBound, TDUContext);
-
-          translateX = Math.max(translateX, leftBound);
-          translateX = Math.min(translateX, rightBound);
-//          draggedTab.style.transform = "translateX(" + translateX + "px)";
-          draggedTab.style.transform = TDUContext.translator + "(" + translateX + "px)";
-
-          // Determine what tab we're dragging over.
-          // * Point of reference is the center of the dragged tab. If that
-          //   point touches a background tab, the dragged tab would take that
-          //   tab's position when dropped.
-          // * We're doing a binary search in order to reduce the amount of
-          //   tabs we need to check.
-
-TDUContext.tabScreenPosition = tabScreenX;
-TDUContext.translateDelta = translateX;
-TDUContext.utils.updateDraggedTabsTransform(TDUContext);
-tabs = TDUContext.utils.extractNotDraggedTabs(tabs, TDUContext);
-
-          let tabCenter = tabScreenX + translateX + tabWidth / 2;
-          let newIndex = -1;
-          let oldIndex = "animDropIndex" in draggedTab._dragData ?
-                         draggedTab._dragData.animDropIndex : draggedTab._tPos;
-          let low = 0;
-          let high = tabs.length - 1;
-          while (low <= high) {
-            let mid = Math.floor((low + high) / 2);
-            if (tabs[mid] == draggedTab &&
-                ++mid > high)
-              break;
-            let boxObject = tabs[mid].boxObject;
-//            let screenX = boxObject.screenX + getTabShift(tabs[mid], oldIndex);
-            let screenX = boxObject[TDUContext.position] + getTabShift(tabs[mid], oldIndex);
-//            if (screenX > tabCenter) {
-if (screenX > TDUContext.lastTabCenter) {
-              high = mid - 1;
-//            } else if (screenX + boxObject.width < tabCenter) {
-            } else if (screenX + boxObject[TDUContext.size] < tabCenter) {
-              low = mid + 1;
-            } else {
-              newIndex = tabs[mid]._tPos;
-
-TDUContext.tabCenter = tabCenter;
-TDUContext.dropTargetTabScreenPosition = screenX;
-TDUContext.utils.updateDontMove(boxObject, TDUContext);
-
-              break;
-            }
-          }
-
-if (TDUContext.utils.checkDontMove(TDUContext)) return;
-
-          if (newIndex >= oldIndex)
-            newIndex++;
-          if (newIndex < 0 || newIndex == oldIndex)
-            return;
-
-TDUContext.utils.updateDropIndex(newIndex, TDUContext);
-
-          draggedTab._dragData.animDropIndex = newIndex;
-
-          // Shift background tabs to leave a gap where the dragged tab
-          // would currently be dropped.
-
-          for (let tab of tabs) {
-            if (tab != draggedTab) {
-              let shift = getTabShift(tab, newIndex);
-//              tab.style.transform = shift ? "translateX(" + shift + "px)" : "";
-              tab.style.transform = shift ? TDUContext.translator + "(" + shift + "px)" : "";
-            }
-          }
-
-          function getTabShift(tab, dropIndex) {
-            if (tab._tPos < draggedTab._tPos && tab._tPos >= dropIndex)
-              return rtl ? -TDUContext.tabsSize : TDUContext.tabsSize;
-//              return rtl ? -tabWidth : tabWidth;
-            if (tab._tPos > draggedTab._tPos && tab._tPos < dropIndex)
-              return rtl ? TDUContext.tabsSize : -TDUContext.tabsSize;
-//              return rtl ? tabWidth : -tabWidth;
-            return 0;
-          }
-
-TDUContext.destroy();
-//=====================================================================
-				};
-				aObserver.__TabsDragUtils_updated__animateTabMove = aObserver._animateTabMove;
-			}
-		},
-		setupContext : function TDU_initTabBrowser(aEvent, aOptions)
-		{
-			var context = {};
-
-			context.draggedTabs = this.getDraggedTabs(aEvent);
-//			var originalDraggedTab = aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
-			var firstDraggedTab = context.draggedTabs[0];
-			context.draggedTab = /* originalDraggedTab ||*/ firstDraggedTab;
-
-			if (typeof aOptions == 'boolean') aOptions = { canDropOnSelf: aOptions };
-			context.options = aOptions || {};
-			context.options.canDropOnSelf = (
-				context.options.canDropOnSelf ||
-				(
-					'TreeStyleTabService' in window &&
-					!context.draggedTab.pinned
-				)
-			);
-
-			var tabbar = this.getTabbarFromEvent(aEvent);
-			var tabbarIsVertical = this.isVertical(tabbar);
-			var isVertical = 'isVertical' in context.options ?
-								context.options.isVertical :
-								tabbarIsVertical ;
-			context.position = isVertical ? 'screenY' : 'screenX' ;
-			context.rowPosition = tabbarIsVertical ? 'screenY' : 'screenX' ;
-			context.size = isVertical ? 'height' : 'width' ;
-			context.rowSize = tabbarIsVertical ? 'height' : 'width' ;
-			context.scroll = isVertical ? 'scrollY' : 'scrollX';
-			context.translator = isVertical ? 'translateY' : 'translateX' ;
-			context.currentPositionCoordinate = aEvent[context.position];
-			context.currentRowPositionCoordinate = aEvent[context.rowPosition];
-
-			var b = this.getTabBrowserFromChild(tabbar);
-			var firstNormalTab = b.visibleTabs[b._numPinnedTabs];
-			context.pinned = context.draggedTab.pinned;
-			context.onPinnedArea = context.currentRowPositionCoordinate < firstNormalTab.boxObject[context.rowPosition];
-			context.tabbarIsVertical = tabbarIsVertical;
-			context.multirowTabs = context.pinned &&
-									context.onPinnedArea &&
-									tabbarIsVertical &&
-									!isVertical;
-
-			context.tabSize = context.draggedTab.getBoundingClientRect()[context.size];
-			context.tabCenterOffset = context.tabSize * (context.options.canDropOnSelf ? 0.25 : 0.5 );
-
-
-			context.utils = this;
-			context.destroy = function() {
-				Object.keys(context).forEach(function(key) {
-					delete context[key];
-				});
-			};
-
-			return context;
-		},
-		setupDraggedTabs : function TDU_setupDraggedTabs(context)
-		{
-			context.tabsSize = 0;
-			context.draggedTabs.forEach(function(draggedTab) {
-				let style = window.getComputedStyle(draggedTab, null);
-				if (style.visibility != 'collapse' && style.display != 'none')
-					context.tabsSize += draggedTab.boxObject[context.size];
-
-				if (!draggedTab._dragData)
-					draggedTab._dragData = {};
-				this.fixDragData(draggedTab._dragData);
-
-				if (!('animLastScreenX' in draggedTab._dragData))
-					draggedTab._dragData.animLastScreenX = draggedTab._dragData[context.position];
-				if (!('previousPosition' in draggedTab._dragData))
-					draggedTab._dragData.previousPosition = context.currentPositionCoordinate;
-			}, this);
-		},
-		fixDragData : function TDU_fixDragData(aData)
-		{
-			if (!('screenY' in aData))
-				aData.screenY = aData.offsetY + window.screenY;
-			if (!('scrollY' in aData))
-				aData.scrollY = aData.scrollX;
-		},
-		updateDraggedTabs : function TDU_updateDraggedTabs(context)
-		{
-			context.draggedTabs.forEach(function(draggedTab, aIndex) {
-				if (draggedTab._dragData.canShrink && aIndex > 0) {
-					let style = draggedTab.style;
-					if (!draggedTab.__tabsDragUtils__backupStyle) {
-						let backup = {
-							overflow : {
-								value    : style.getPropertyValue('overflow'),
-								priority : style.getPropertyPriority('overflow')
-							}
-						};
-						backup['max-'+context.rowSize] = {
-							value    : style.getPropertyValue('max-'+context.rowSize),
-							priority : style.getPropertyPriority('max-'+context.rowSize)
-						};
-						backup['min-'+context.rowSize] = {
-							value    : style.getPropertyValue('min-'+context.rowSize),
-							priority : style.getPropertyPriority('min-'+context.rowSize)
-						};
-						draggedTab.__tabsDragUtils__backupStyle = backup;
-					}
-					let size = draggedTab.boxObject[context.rowSize] * 0.1;
-					style.setProperty('max-'+context.rowSize, size + 'px', 'important');
-					style.setProperty('min-'+context.rowSize, size + 'px', 'important');
-					style.setProperty('overflow', 'hidden', 'important');
-				}
-				draggedTab._dragData.animLastScreenX = context.currentPositionCoordinate;
-			}, this);
-		},
-		collectAnimateTabs : function TDU_collectAnimateTabs(tabs, context)
-		{
-			context.animateTabs = context.allAnimateTabs = tabs;
-			if (!context.multirowTabs)
-				return tabs;
-
-			// With Tree Style Tabs, pinned tabs are shown with multiple rows.
-			// We should animate only tabs in the same row.
-			return context.animateTabs = tabs.filter(function(aTab) {
-				var box = aTab.boxObject;
-				var min = box[context.rowPosition];
-				var max = min + box[context.rowSize];
-				var onSameRow = context.currentRowPositionCoordinate >= min &&
-								context.currentRowPositionCoordinate <= max;
-				if (onSameRow) {
-					return true;
-				}
-				else {
-					aTab.style.transform = ''; // reset old animation
-					return false;
-				}
-			});
-		},
-		updateLeftBound : function TDU_updateLeftBound(leftBound, context)
-		{
-			if (context.options.canDropOnSelf)
-				leftBound -= context.tabCenterOffset;
-			return leftBound;
-		},
-		updateRightBound : function TDU_updateRightBound(rightBound, context)
-		{
-			rightBound -= context.tabsSize - context.tabSize;
-			if (context.options.canDropOnSelf)
-				rightBound += context.tabCenterOffset;
-			return rightBound;
-		},
-		updateDraggedTabsTransform : function TDU_updateDraggedTabsTransform(context)
-		{
-			var transform = context.draggedTab.style.transform;
-
-			var tabs = context.draggedTabs;
-			if (context.multirowTabs) { // for multirow pinned tabs
-				let translateX = /translateX\(([-0-9\.]+)(?:px)?\)/.test(transform) && RegExp.$1 || 0;
-				translateX = parseFloat(translateX);
-				let translateY = /translateY\(([-0-9\.]+)(?:px)?\)/.test(transform) && RegExp.$1 || 0;
-				translateY = parseFloat(translateY);
-
-				let rowDelta = context.animateTabs[0].boxObject[context.rowPosition] - context.draggedTab.boxObject[context.rowPosition];
-				if (context.rowPosition == 'screenY')
-					translateY += rowDelta;
-				else
-					translateX += rowDelta;
-
-				transform = 'translate(' + translateX + 'px, ' + translateY + 'px)';
-			}
-			else {
-				tabs = tabs.slice(1);
-			}
-
-			tabs.forEach(function(tab) {
-				tab.style.transform = transform;
-			}, this);
-			context.dontMove = false;
-			context.lastTabCenter = Math.round(context.tabScreenPosition + context.translateDelta + context.tabsSize - context.tabSize / 2);
-		},
-		updateDontMove : function TDU_updateDontMove(boxObject, context)
-		{
-			context.dontMove = (
-				context.options.canDropOnSelf &&
-				(
-					(context.draggedTab._dragData.previousPosition > context.currentPositionCoordinate &&
-					 context.dropTargetTabScreenPosition + context.tabCenterOffset < context.tabCenter) ||
-					(context.draggedTab._dragData.previousPosition < context.currentPositionCoordinate &&
-					 context.dropTargetTabScreenPosition + boxObject[context.size] - context.tabCenterOffset > context.lastTabCenter)
-				)
-			);
-		},
-		checkDontMove : function TDU_checkDontMove(context)
-		{
-			context.draggedTabs.forEach(function(draggedTab) {
-				draggedTab._dragData.previousPosition = context.currentPositionCoordinate;
-			});
-			return context.dontMove;
-		},
-		extractNotDraggedTabs : function TDU_extractNotDraggedTabs(tabs, context)
-		{
-			return tabs.filter(function(tab) {
-				return context.draggedTabs.indexOf(tab) < 0
-			});
-		},
-		updateDropIndex : function TDU_updateDropIndex(newIndex, context)
-		{
-			context.draggedTabs.forEach(function(draggedTab) {
-				draggedTab._dragData.animDropIndex = newIndex;
-			});
-		},
-
-		destroyTabDNDObserver : function TDU_destroyTabDNDObserver(aObserver)
-		{
-			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;
-			delete aObserver.__TabsDragUtils_updated__setEffectAllowedForDataTransfer;
-
-			if (aObserver._animateTabMove == aObserver.__TabsDragUtils_updated__animateTabMove)
-				aObserver._animateTabMove = aObserver.__TabsDragUtils_original__animateTabMove;
-			delete aObserver.__TabsDragUtils_original__animateTabMove;
-			delete aObserver.__TabsDragUtils_updated__animateTabMove;
-
-			let index = this.updatedTabDNDObservers.indexOf(aObserver);
-			if (index > -1)
-				this.updatedTabDNDObservers = this.updatedTabDNDObservers.splice(index, 1);
-		},
-
-		startTabsDrag : function TDU_startTabsDrag(aEvent, aTabs, aOptions)
-		{
-			aOptions = aOptions || {};
-
-			var draggedTab = this.getTabFromEvent(aEvent);
-			var tabs = aTabs || [];
-			var index = tabs.indexOf(draggedTab);
-			if (index < 0)
-				return;
-
-			var dt = aEvent.dataTransfer;
-			dt.setDragImage(this.createDragFeedbackImage(tabs), 0, 0);
-
-			tabs.splice(index, 1);
-			tabs.unshift(draggedTab);
-
-			tabs.forEach(function(aTab, aIndex) {
-				dt.mozSetDataAt(TAB_DROP_TYPE, aTab, aIndex);
-				dt.mozSetDataAt('text/x-moz-text-internal', this.getCurrentURIOfTab(aTab), aIndex);
-			}, this);
-
-			// On Firefox 3.6 or older versions on Windows, drag feedback
-			// image isn't shown if there are multiple drag data...
-			if (tabs.length <= 1 ||
-				'mozSourceNode' in dt ||
-				navigator.platform.toLowerCase().indexOf('win') < 0)
-				dt.mozCursor = 'default';
-
-			if (this.canAnimateDraggedTabs(aEvent)) {
-				let tabbar = this.getTabbarFromEvent(aEvent);
-				let tabbarOffsetX = this.getClientX(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
-				let tabbarOffsetY = this.getClientY(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
-				let isVertical = this.isVertical(tabbar.mTabstrip);
-				tabs.forEach(function(aTab) {
-					var tabOffsetX = this.getClientX(aTab) - tabbarOffsetX;
-					var tabOffsetY = this.getClientY(aTab) - tabbarOffsetY;
-					aTab._dragData = {
-						offsetX: aEvent.screenX - window.screenX - tabOffsetX,
-						offsetY: aEvent.screenY - window.screenY - tabOffsetY,
-						scrollX: isVertical ? 0 : tabbar.mTabstrip.scrollPosition ,
-						scrollY: isVertical ? tabbar.mTabstrip.scrollPosition : 0 ,
-						screenX: aEvent.screenX,
-						screenY: aEvent.screenY,
-						canShrink : aOptions.shrinkOthers || false
-					};
-				}, this);
-			}
-
-			aEvent.stopPropagation();
-
-			if (aOptions.shrinkOthers) {
-				document.addEventListener('dragend', this, true);
-				document.addEventListener('drop', this, true);
-				document.addEventListener('overflow', this, true);
-				document.addEventListener('underflow', this, true);
-			}
-		},
-		isVertical : function TDS_isVertical(aElement)
-		{
-			let style = window.getComputedStyle(aElement, null);
-			return (aElement.orient || style.MozOrient || style.orient) == 'vertical';
-		},
-		getClientX : function TDS_getClientX(aElement)
-		{
-			return aElement.getBoundingClientRect().left;
-		},
-		getClientY : function TDS_getClientY(aElement)
-		{
-			return aElement.getBoundingClientRect().top;
-		},
-		createDragFeedbackImage : function TDU_createDragFeedbackImage(aTabs)
-		{
-			var previews = aTabs.map(function(aTab) {
-					try {
-						return tabPreviews.capture(aTab, false);
-					}
-					catch(e) {
-						return null;
-					}
-				}, this)
-				.filter(function(aPreview) {
-					return aPreview;
-				});
-			var offset = 16;
-
-			var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
-			canvas.width = previews[0].width + (offset * aTabs.length);
-			canvas.height = previews[0].height + (offset * aTabs.length);
-
-			var ctx = canvas.getContext('2d');
-			ctx.save();
-			try {
-				ctx.clearRect(0, 0, canvas.width, canvas.height);
-				previews.forEach(function(aPreview, aIndex) {
-					ctx.drawImage(aPreview, 0, 0);
-					ctx.translate(offset, offset);
-					ctx.globalAlpha = 1 / (aIndex+1);
-				}, this);
-			}
-			catch(e) {
-			}
-			ctx.restore();
-
-			return canvas;
-		},
-		getTabFromEvent : function TDU_getTabFromEvent(aEvent, aReallyOnTab) 
-		{
-			var tab = (aEvent.originalTarget || aEvent.target).ownerDocument.evaluate(
-					'ancestor-or-self::*[local-name()="tab"]',
-					aEvent.originalTarget || aEvent.target,
-					null,
-					XPathResult.FIRST_ORDERED_NODE_TYPE,
-					null
-				).singleNodeValue;
-			if (tab || aReallyOnTab)
-				return tab;
-
-			var b = this.getTabBrowserFromChild(aEvent.originalTarget);
-			if (b &&
-				'treeStyleTab' in b &&
-				'getTabFromTabbarEvent' in b.treeStyleTab) { // Tree Style Tab
-				return b.treeStyleTab.getTabFromTabbarEvent(aEvent);
-			}
-			return null;
-		},
-		getTabbarFromEvent : function TDU_getTabbarFromEvent(aEvent) 
-		{
-			return (aEvent.originalTarget || aEvent.target).ownerDocument.evaluate(
-					'ancestor-or-self::*[local-name()="tabs"]',
-					aEvent.originalTarget || aEvent.target,
-					null,
-					XPathResult.FIRST_ORDERED_NODE_TYPE,
-					null
-				).singleNodeValue;
-		},
-		getTabBrowserFromChild : function TDU_getTabBrowserFromChild(aTabBrowserChild) 
-		{
-			if (!aTabBrowserChild)
-				return null;
-
-			if (aTabBrowserChild.localName == 'tabbrowser') // itself
-				return aTabBrowserChild;
-
-			if (aTabBrowserChild.tabbrowser) // tabs
-				return aTabBrowserChild.tabbrowser;
-
-			if (aTabBrowserChild.localName == 'toolbar') // tabs toolbar
-				return aTabBrowserChild.getElementsByTagName('tabs')[0].tabbrowser;
-
-			var b = aTabBrowserChild.ownerDocument.evaluate(
-					'ancestor-or-self::*[local-name()="tabbrowser"] | '+
-					'ancestor-or-self::*[local-name()="tabs" and @tabbrowser] |'+
-					'ancestor::*[local-name()="toolbar"]/descendant::*[local-name()="tabs" and @tabbrowser]',
-					aTabBrowserChild,
-					null,
-					XPathResult.FIRST_ORDERED_NODE_TYPE,
-					null
-				).singleNodeValue;
-			return (b && b.tabbrowser) || b;
-		},
-		canAnimateDraggedTabs: function TDU_canAnimateDraggedTabs(aEvent)
-		{
-			var tabbar = this.getTabbarFromEvent(aEvent);
-			return tabbar && '_animateTabMove' in tabbar;
-		},
-
-		processTabsDragging: function TDU_processTabsDragging(aEvent, aOptions)
-		{
-			if (this.canAnimateDraggedTabs(aEvent)) {
-				let tabbar = this.getTabbarFromEvent(aEvent);
-				let draggedTab = aEvent.dataTransfer && aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
-				if (!draggedTab || draggedTab.ownerDocument != tabbar.ownerDocument) return false;
-
-				if (!tabbar.hasAttribute('movingtab'))
-					tabbar.setAttribute('movingtab', 'true');
-				tabbar._animateTabMove(aEvent, aOptions);
-				return true;
-			}
-			return false;
-		},
-
-		clearDraggingStyles : function TDU_clearDraggingStyles(aEvent)
-		{
-			var tabbar = this.getTabbarFromEvent(aEvent);
-			Array.forEach(tabbar.childNodes, function(aTab) {
-				let backup = aTab.__tabsDragUtils__backupStyle;
-				if (!backup)
-					return;
-
-				let style = aTab.style;
-				Object.keys(backup).forEach(function(aKey) {
-					style.setProperty(aKey, backup[aKey].value, backup[aKey].priority);
-				});
-				delete aTab.__tabsDragUtils__backupStyle;
-			}, this);
-		},
-
-		isTabsDragging : function TDU_isTabsDragging(aEvent) 
-		{
-			if (!aEvent)
-				return false;
-			var dt = aEvent.dataTransfer;
-			if (dt.mozItemCount < 1)
-				return false;
-			for (let i = 0, maxi = dt.mozItemCount; i < maxi; i++)
-			{
-				if (!dt.mozTypesAt(i).contains(TAB_DROP_TYPE))
-					return false;
-			}
-			return true;
-		},
-
-		getSelectedTabs : function TDU_getSelectedTabs(aEventOrTabOrTabBrowser)
-		{
-			var event = aEventOrTabOrTabBrowser instanceof Event ? aEventOrTabOrTabBrowser : null ;
-			var b = this.getTabBrowserFromChild(event ? event.target : aEventOrTabOrTabBrowser );
-			if (!b)
-				return [];
-
-			var w = b.ownerDocument.defaultView;
-			var tab = (aEventOrTabOrTabBrowser instanceof Element &&
-						aEventOrTabOrTabBrowser.localName == 'tab') ?
-						aEventOrTabOrTabBrowser :
-						(event && this.getTabFromEvent(event)) ;
-
-			var selectedTabs;
-			var isMultipleDrag = (
-					( // Firefox itself (https://bugzilla.mozilla.org/show_bug.cgi?id=566510)
-						'visibleTabs' in b &&
-						(selectedTabs = b.visibleTabs.filter(function(aTab) {
-							return aTab.getAttribute('multiselected') == 'true';
-						})) &&
-						selectedTabs.length
-					) ||
-					( // Tab Utilities
-						'selectedTabs' in b &&
-						(selectedTabs = b.selectedTabs) &&
-						selectedTabs.length
-					) ||
-					( // Multiple Tab Handler
-						tab &&
-						'MultipleTabService' in w &&
-						w.MultipleTabService.isSelected(tab) &&
-						w.MultipleTabService.allowMoveMultipleTabs &&
-						(selectedTabs = w.MultipleTabService.getSelectedTabs(b)) &&
-						selectedTabs.length
-					) ||
-					( // based on HTML5 drag events
-						this.isTabsDragging(event) &&
-						(selectedTabs = this.getDraggedTabs(event)) &&
-						selectedTabs.length
-					)
-				);
-			return isMultipleDrag ? selectedTabs :
-					tab ? [tab] :
-					[] ;
-		},
-
-		getDraggedTabs : function TDU_getDraggedTabs(aEventOrDataTransfer)
-		{
-			var dt = aEventOrDataTransfer.dataTransfer || aEventOrDataTransfer;
-			var tabs = [];
-			if (dt.mozItemCount < 1 ||
-				!dt.mozTypesAt(0).contains(TAB_DROP_TYPE))
-				return tabs;
-
-			for (let i = 0, maxi = dt.mozItemCount; i < maxi; i++)
-			{
-				tabs.push(dt.mozGetDataAt(TAB_DROP_TYPE, i));
-			}
-			return tabs.sort(function(aA, aB) { return aA._tPos - aB._tPos; });
-		},
- 
-	 	getCurrentURIOfTab : function TDU_getCurrentURIOfTab(aTab) 
-		{
-			if (this.isTabNeedToBeRestored(aTab)) {
-				let data = this.getRestoringData(aTab);
-				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;
-		},
-
-		// for drop on bookmarks tree
-		willBeInsertedBeforeExistingNode : function TDU_willBeInsertedBeforeExistingNode(aInsertionPoint) 
-		{
-			// drop on folder in the bookmarks menu
-			if (aInsertionPoint.dropNearItemId === void(0))
-				return false;
-
-			// drop on folder in the places organizer
-			if (aInsertionPoint._index < 0 && aInsertionPoint.dropNearItemId < 0)
-				return false;
-
-			return true;
-		},
-
-		handleEvent : function TDU_handleEvent(aEvent) 
-		{
-			switch (aEvent.type)
-			{
-				case 'load':
-					return this._delayedInit();
-
-				case 'dragend':
-				case 'drop':
-					document.removeEventListener('dragend', this, true);
-					document.removeEventListener('drop', this, true);
-					document.removeEventListener('overflow', this, true);
-					document.removeEventListener('underflow', this, true);
-					return this.clearDraggingStyles(aEvent);
-
-				case 'overflow':
-				case 'underflow':
-					if (aEvent.target.localName == 'tab') {
-						// this must be canceled to prevent the "+" button in the tab bar turns its mode.
-						aEvent.stopPropagation();
-					}
-					return;
-			}
-		},
-
-		_fireTabsDropEvent : function TDU_fireTabsDropEvent(aTabs) 
-		{
-			var event = new CustomEvent(this.EVENT_TYPE_TABS_DROP, {
-					bubbles    : true,
-					cancelable : true,
-					detail     : {
-						tabs : aTabs
-					}
-				});
-			return this._dropTarget.dispatchEvent(event);
-		},
-		get _dropTarget()
-		{
-			return ('PlacesControllerDragHelper' in window ?
-						PlacesControllerDragHelper.currentDropTarge :
-						null ) || document;
-		}
-	};
-
-
-	function DOMDataTransferProxy(aDataTransfer, aInsertionPoint) 
-	{
-		// Don't proxy it because it is not a drag of tabs.
-		if (!aDataTransfer.mozTypesAt(0).contains(TAB_DROP_TYPE))
-			return aDataTransfer;
-
-		var tabs = tabsDragUtils.getDraggedTabs(aDataTransfer);
-
-		// Don't proxy it because there is no selection.
-		if (tabs.length < 2)
-			return aDataTransfer;
-
-		this._source = aDataTransfer;
-		this._tabs = tabs;
-
-		if (!tabsDragUtils._fireTabsDropEvent(tabs))
-			this._tabs = [tabs[0]];
-
-		if (tabsDragUtils.willBeInsertedBeforeExistingNode(aInsertionPoint))
-			this._tabs.reverse();
-	}
-
-	DOMDataTransferProxy.prototype = {
-		
-		_apply : function DOMDTProxy__apply(aMethod, aArguments) 
-		{
-			return this._source[aMethod].apply(this._source, aArguments);
-		},
-	 
-		// nsIDOMDataTransfer 
-		get dropEffect() { return this._source.dropEffect; },
-		set dropEffect(aValue) { return this._source.dropEffect = aValue; },
-		get effectAllowed() { return this._source.effectAllowed; },
-		set effectAllowed(aValue) { return this._source.effectAllowed = aValue; },
-		get files() { return this._source.files; },
-		get types() { return this._source.types; },
-		clearData : function DOMDTProxy_clearData() { return this._apply('clearData', arguments); },
-		setData : function DOMDTProxy_setData() { return this._apply('setData', arguments); },
-		getData : function DOMDTProxy_getData() { return this._apply('getData', arguments); },
-		setDragImage : function DOMDTProxy_setDragImage() { return this._apply('setDragImage', arguments); },
-		addElement : function DOMDTProxy_addElement() { return this._apply('addElement', arguments); },
-	 
-		// nsIDOMNSDataTransfer 
-		get mozItemCount()
-		{
-			return this._tabs.length;
-		},
-
-		get mozCursor() { return this._source.mozCursor; },
-		set mozCursor(aValue) { return this._source.mozCursor = aValue; },
-
-		mozTypesAt : function DOMDTProxy_mozTypesAt(aIndex)
-		{
-			if (aIndex >= this._tabs.length)
-				return new StringList([]);
-
-			// return this._apply('mozTypesAt', [0]);
-			// I return "text/x-moz-url" as a first type, to override behavior for "to-be-restored" tabs.
-			return new StringList(['text/x-moz-url', TAB_DROP_TYPE, 'text/x-moz-text-internal']);
-		},
-
-		mozClearDataAt : function DOMDTProxy_mozClearDataAt()
-		{
-			this._tabs = [];
-			return this._apply('mozClearDataAt', [0]);
-		},
-
-		mozSetDataAt : function DOMDTProxy_mozSetDataAt(aFormat, aData, aIndex)
-		{
-			this._tabs = [];
-			return this._apply('mozSetDataAt', [aFormat, aData, 0]);
-		},
-
-		mozGetDataAt : function DOMDTProxy_mozGetDataAt(aFormat, aIndex)
-		{
-			if (aIndex >= this._tabs.length)
-				return null;
-
-			var tab = this._tabs[aIndex];
-			switch (aFormat)
-			{
-				case TAB_DROP_TYPE:
-					return tab;
-
-				case 'text/x-moz-url':
-					return (tabsDragUtils.getCurrentURIOfTab(tab) ||
-							'about:blank') + '\n' + tab.label;
-
-				case 'text/x-moz-text-internal':
-					return tabsDragUtils.getCurrentURIOfTab(tab) ||
-							'about:blank';
-			}
-
-			return this._apply('mozGetDataAt', [aFormat, 0]);
-		},
-
-		get mozUserCancelled() { return this._source.mozUserCancelled; }
-	};
-
-	function StringList(aTypes) 
-	{
-		return Object.create(aTypes, {
-			item : { value : function(aIndex) {
-				return this[aIndex];
-			} },
-			contains : { value : function(aType) {
-				return this.indexOf(aType) > -1;
-			} }
-		});
-	}
-
-	tabsDragUtils.DOMDataTransferProxy = DOMDataTransferProxy;
-	tabsDragUtils.StringList = StringList;
-
-	window['piro.sakura.ne.jp'].tabsDragUtils = tabsDragUtils;
-	tabsDragUtils.init();
-})();
+/*
+ Multiple Tabs Drag and Drop Utilities for Firefox 52 or later
+
+ Usage:
+   window['piro.sakura.ne.jp'].tabsDragUtils.initTabBrowser(gBrowser);
+
+   // in dragstart event listener
+   window['piro.sakura.ne.jp'].tabsDragUtils.startTabsDrag(aEvent, aArrayOfTabs);
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ original:
+   http://github.com/piroor/fxaddonlib-tabs-drag-utils
+*/
+(function() {
+	const currentRevision = 45;
+
+	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
+
+	var loadedRevision = 'tabsDragUtils' in window['piro.sakura.ne.jp'] ?
+			window['piro.sakura.ne.jp'].tabsDragUtils.revision :
+			0 ;
+	if (loadedRevision && loadedRevision >= currentRevision) {
+		return;
+	}
+
+	if (loadedRevision &&
+		'destroy' in window['piro.sakura.ne.jp'].tabsDragUtils)
+		window['piro.sakura.ne.jp'].tabsDragUtils.destroy();
+
+	const Cc = Components.classes;
+	const Ci = Components.interfaces;
+	const TAB_DROP_TYPE = 'application/x-moz-tabbrowser-tab';
+
+	var tabsDragUtils = {
+		revision : currentRevision,
+
+		// "nsDOM" prefix is required!
+		// https://developer.mozilla.org/en/Creating_Custom_Events_That_Can_Pass_Data
+		EVENT_TYPE_TABS_DROP : 'nsDOMMultipleTabsDrop',
+
+		isTabNeedToBeRestored: function(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;
+		},
+		getRestoringData: function(aTab)
+		{
+			var data = aTab.linkedBrowser.__SS_data;
+			if (!data && this.TabStateCache) // Firefox 23-
+				data = this.TabStateCache.get(aTab.linkedBrowser);
+			return data;
+		},
+		get TabStateCache() {
+			return this.SessionStoreNS.TabStateCache;
+		},
+		get SessionStoreNS() {
+			delete this.SessionStoreNS;
+			try {
+				// resource://app/modules/sessionstore/SessionStore.jsm ?
+				this.SessionStoreNS = Components.utils.import('resource:///modules/sessionstore/SessionStore.jsm', {});
+			}
+			catch(e) {
+				this.SessionStoreNS = {};
+			}
+			return this.SessionStoreNS;
+		},
+
+		init : function TDU_init()
+		{
+			window.addEventListener('load', this, false);
+		},
+		_delayedInit : function TDU_delayedInit()
+		{
+			window.removeEventListener('load', this, false);
+			delete this._delayedInit;
+
+			if (
+				'PlacesControllerDragHelper' in window &&
+				'onDrop' in PlacesControllerDragHelper &&
+				!PlacesControllerDragHelper.__TabsDragUtils_original__onDrop
+				) {
+				let original = PlacesControllerDragHelper.onDrop;
+				PlacesControllerDragHelper.__TabsDragUtils_original__onDrop = original;
+				if (PlacesControllerDragHelper.onDrop.isAsyncFunction) {
+					PlacesControllerDragHelper.onDrop = Task.async(function(insertionPoint, dt) {
+						dt = new window["piro.sakura.ne.jp"].tabsDragUtils.DOMDataTransferProxy(dt, insertionPoint);
+						// for Tree Style Tab (save tree structure to bookmarks)
+						if (dt &&
+							'_tabs' in dt &&
+							'TreeStyleTabBookmarksService' in window)
+							TreeStyleTabBookmarksService.beginAddBookmarksFromTabs(dt._tabs);
+						yield PlacesControllerDragHelper.__TabsDragUtils_original__onDrop.call(this, insertionPoint, dt)
+								.then(function(aResult) {
+									if (dt &&
+										'_tabs' in dt &&
+										'TreeStyleTabBookmarksService' in window)
+										TreeStyleTabBookmarksService.endAddBookmarksFromTabs(dt._tabs);
+								});
+					});
+				}
+				PlacesControllerDragHelper.__TabsDragUtils_updated__onDrop = PlacesControllerDragHelper.onDrop;
+			}
+
+			if ('TMP_tabDNDObserver' in window) // for Tab Mix Plus
+				this.initTabDNDObserver(TMP_tabDNDObserver);
+			else if ('TabDNDObserver' in window)	// for old Tab Mix Plus
+				this.initTabDNDObserver(TabDNDObserver);
+		},
+		destroy : function TDU_destroy()
+		{
+			if (this._delayedInit)
+				window.removeEventListener('load', this, false);
+
+			if (PlacesControllerDragHelper.onDrop == PlacesControllerDragHelper.__TabsDragUtils_updated__onDrop)
+				PlacesControllerDragHelper.onDrop = PlacesControllerDragHelper.__TabsDragUtils_original__onDrop;
+			delete PlacesControllerDragHelper.__TabsDragUtils_original__onDrop;
+			delete PlacesControllerDragHelper.__TabsDragUtils_updated__onDrop;
+
+			this.updatedTabDNDObservers.slice(0).forEach(this.destroyTabDNDObserver, this);
+		},
+
+		initTabBrowser : function TDU_initTabBrowser(aTabBrowser)
+		{
+			this.initTabDNDObserver(aTabBrowser.tabContainer);
+		},
+		destroyTabBrowser : function TDU_destroyTabBrowser(aTabBrowser)
+		{
+			this.destroyTabDNDObserver(aTabBrowser.tabContainer);
+		},
+
+		updatedTabDNDObservers : [],
+		initTabDNDObserver : function TDU_initTabDNDObserver(aObserver)
+		{
+			this.updatedTabDNDObservers.push(aObserver);
+
+			if (typeof aObserver._getDropEffectForTabDrag === 'function' &&
+				!aObserver.__tabsDragUtils__getDropEffectForTabDrag) {
+				aObserver.__tabsDragUtils_original__getDropEffectForTabDrag = aObserver._getDropEffectForTabDrag;
+				aObserver._getDropEffectForTabDrag = function(event) {
+/**
+ * Original:
+ *  base version: Nightly 55.0a1
+ *  date        : 2017-05-08
+ *  source      : https://dxr.mozilla.org/mozilla-central/rev/17d8a1e278a9c54a6fdda9d390abce4077e55b20/browser/base/content/tabbrowser.xml#6410
+ */
+//=====================================================================
+          var dt = event.dataTransfer;
+//          if (dt.mozItemCount == 1) {
+          if (dt.mozItemCount == 1 || window['piro.sakura.ne.jp'].tabsDragUtils.isTabsDragging(event)) {
+            var types = dt.mozTypesAt(0);
+            // tabs are always added as the first type
+            if (types[0] == TAB_DROP_TYPE) {
+              let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
+              if (sourceNode instanceof XULElement &&
+                  sourceNode.localName == "tab" &&
+                  sourceNode.ownerGlobal instanceof ChromeWindow &&
+                  sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
+                  sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.parentNode) {
+                // Do not allow transfering a private tab to a non-private window
+                // and vice versa.
+                if (PrivateBrowsingUtils.isWindowPrivate(window) !=
+                    PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerGlobal))
+                  return "none";
+
+                if (window.gMultiProcessBrowser !=
+                    sourceNode.ownerGlobal.gMultiProcessBrowser)
+                  return "none";
+
+                return dt.dropEffect == "copy" ? "copy" : "move";
+              }
+            }
+          }
+
+          if (browserDragAndDrop.canDropLink(event)) {
+            return "link";
+          }
+          return "none";
+//=====================================================================
+				};
+				aObserver.__TabsDragUtils_updated__getDropEffectForTabDrag = aObserver._getDropEffectForTabDrag;
+			}
+
+			if ('_animateTabMove' in aObserver &&
+				!aObserver.__TabsDragUtils_original__animateTabMove) {
+				let original = aObserver._animateTabMove;
+				aObserver.__TabsDragUtils_original__animateTabMove = original;
+				aObserver._animateTabMove = function _animateTabMove(event, aOptions) {
+/**
+ * Original:
+ *  base version: Nightly 55.0a1
+ *  date        : 2017-05-08
+ *  source      : https://dxr.mozilla.org/mozilla-central/rev/17d8a1e278a9c54a6fdda9d390abce4077e55b20/browser/base/content/tabbrowser.xml#6171
+ */
+//=====================================================================
+var TDUContext = window["piro.sakura.ne.jp"].tabsDragUtils.setupContext(event, aOptions);
+          let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
+draggedTab = TDUContext.draggedTab;
+
+          if (this.getAttribute("movingtab") != "true") {
+            this.setAttribute("movingtab", "true");
+            this.selectedItem = draggedTab;
+          }
+
+          if (!("animLastScreenX" in draggedTab._dragData)) {
+//            draggedTab._dragData.animLastScreenX = draggedTab._dragData.screenX;
+            draggedTab._dragData.animLastScreenX = draggedTab._dragData[TDUContext.position];
+          }
+
+TDUContext.utils.setupDraggedTabs(TDUContext);
+
+//          let screenX = event.screenX;
+          let screenX = event[TDUContext.position];
+          if (screenX == draggedTab._dragData.animLastScreenX)
+            return;
+
+          draggedTab._dragData.animLastScreenX = screenX;
+
+TDUContext.utils.updateDraggedTabs(TDUContext);
+
+          let rtl = (window.getComputedStyle(this).direction == "rtl");
+          let pinned = draggedTab.pinned;
+          let numPinned = this.tabbrowser._numPinnedTabs;
+          let tabs = this.tabbrowser.visibleTabs
+                                    .slice(pinned ? 0 : numPinned,
+                                           pinned ? numPinned : undefined);
+          if (rtl)
+            tabs.reverse();
+//          let tabWidth = draggedTab.getBoundingClientRect().width;
+          let tabWidth = draggedTab.getBoundingClientRect()[TDUContext.size];
+
+          // Move the dragged tab based on the mouse position.
+
+tabs = TDUContext.utils.collectAnimateTabs(tabs, TDUContext);
+
+          let leftTab = tabs[0];
+          let rightTab = tabs[tabs.length - 1];
+//          let tabScreenX = draggedTab.boxObject.screenX;
+          let tabScreenX = draggedTab.boxObject[TDUContext.position];
+//          let translateX = screenX - draggedTab._dragData.screenX;
+          let translateX = screenX - draggedTab._dragData[TDUContext.position];
+          if (!pinned) {
+//            translateX += this.mTabstrip.scrollPosition - draggedTab._dragData.scrollX;
+            translateX += this.mTabstrip.scrollPosition - draggedTab._dragData[TDUContext.scroll];
+          }
+//          let leftBound = leftTab.boxObject.screenX - tabScreenX;
+          let leftBound = leftTab.boxObject[TDUContext.position] - tabScreenX;
+//          let rightBound = (rightTab.boxObject.screenX + rightTab.boxObject.width) -
+//                           (tabScreenX + tabWidth);
+          let rightBound = (rightTab.boxObject[TDUContext.position] + rightTab.boxObject[TDUContext.size]) -
+                           (tabScreenX + tabWidth);
+
+leftBound = TDUContext.utils.updateLeftBound(leftBound, TDUContext);
+rightBound = TDUContext.utils.updateRightBound(rightBound, TDUContext);
+
+          translateX = Math.max(translateX, leftBound);
+          translateX = Math.min(translateX, rightBound);
+//          draggedTab.style.transform = "translateX(" + translateX + "px)";
+          draggedTab.style.transform = TDUContext.translator + "(" + translateX + "px)";
+
+          // Determine what tab we're dragging over.
+          // * Point of reference is the center of the dragged tab. If that
+          //   point touches a background tab, the dragged tab would take that
+          //   tab's position when dropped.
+          // * We're doing a binary search in order to reduce the amount of
+          //   tabs we need to check.
+
+TDUContext.tabScreenPosition = tabScreenX;
+TDUContext.translateDelta = translateX;
+TDUContext.utils.updateDraggedTabsTransform(TDUContext);
+tabs = TDUContext.utils.extractNotDraggedTabs(tabs, TDUContext);
+
+          let tabCenter = tabScreenX + translateX + tabWidth / 2;
+          let newIndex = -1;
+          let oldIndex = "animDropIndex" in draggedTab._dragData ?
+                         draggedTab._dragData.animDropIndex : draggedTab._tPos;
+          let low = 0;
+          let high = tabs.length - 1;
+          while (low <= high) {
+            let mid = Math.floor((low + high) / 2);
+            if (tabs[mid] == draggedTab &&
+                ++mid > high)
+              break;
+            let boxObject = tabs[mid].boxObject;
+//            let screenX = boxObject.screenX + getTabShift(tabs[mid], oldIndex);
+            let screenX = boxObject[TDUContext.position] + getTabShift(tabs[mid], oldIndex);
+//            if (screenX > tabCenter) {
+if (screenX > TDUContext.lastTabCenter) {
+              high = mid - 1;
+//            } else if (screenX + boxObject.width < tabCenter) {
+            } else if (screenX + boxObject[TDUContext.size] < tabCenter) {
+              low = mid + 1;
+            } else {
+              newIndex = tabs[mid]._tPos;
+
+TDUContext.tabCenter = tabCenter;
+TDUContext.dropTargetTabScreenPosition = screenX;
+TDUContext.utils.updateDontMove(boxObject, TDUContext);
+
+              break;
+            }
+          }
+
+if (TDUContext.utils.checkDontMove(TDUContext)) return;
+
+          if (newIndex >= oldIndex)
+            newIndex++;
+          if (newIndex < 0 || newIndex == oldIndex)
+            return;
+
+TDUContext.utils.updateDropIndex(newIndex, TDUContext);
+
+          draggedTab._dragData.animDropIndex = newIndex;
+
+          // Shift background tabs to leave a gap where the dragged tab
+          // would currently be dropped.
+
+          for (let tab of tabs) {
+            if (tab != draggedTab) {
+              let shift = getTabShift(tab, newIndex);
+//              tab.style.transform = shift ? "translateX(" + shift + "px)" : "";
+              tab.style.transform = shift ? TDUContext.translator + "(" + shift + "px)" : "";
+            }
+          }
+
+          function getTabShift(tab, dropIndex) {
+            if (tab._tPos < draggedTab._tPos && tab._tPos >= dropIndex)
+              return rtl ? -TDUContext.tabsSize : TDUContext.tabsSize;
+//              return rtl ? -tabWidth : tabWidth;
+            if (tab._tPos > draggedTab._tPos && tab._tPos < dropIndex)
+              return rtl ? TDUContext.tabsSize : -TDUContext.tabsSize;
+//              return rtl ? tabWidth : -tabWidth;
+            return 0;
+          }
+
+TDUContext.destroy();
+//=====================================================================
+				};
+				aObserver.__TabsDragUtils_updated__animateTabMove = aObserver._animateTabMove;
+			}
+		},
+		setupContext : function TDU_initTabBrowser(aEvent, aOptions)
+		{
+			var context = {};
+
+			context.draggedTabs = this.getDraggedTabs(aEvent);
+//			var originalDraggedTab = aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
+			var firstDraggedTab = context.draggedTabs[0];
+			context.draggedTab = /* originalDraggedTab ||*/ firstDraggedTab;
+
+			if (typeof aOptions == 'boolean') aOptions = { canDropOnSelf: aOptions };
+			context.options = aOptions || {};
+			context.options.canDropOnSelf = (
+				context.options.canDropOnSelf ||
+				(
+					'TreeStyleTabService' in window &&
+					!context.draggedTab.pinned
+				)
+			);
+
+			var tabbar = this.getTabbarFromEvent(aEvent);
+			var tabbarIsVertical = this.isVertical(tabbar);
+			var isVertical = 'isVertical' in context.options ?
+								context.options.isVertical :
+								tabbarIsVertical ;
+			context.position = isVertical ? 'screenY' : 'screenX' ;
+			context.rowPosition = tabbarIsVertical ? 'screenY' : 'screenX' ;
+			context.size = isVertical ? 'height' : 'width' ;
+			context.rowSize = tabbarIsVertical ? 'height' : 'width' ;
+			context.scroll = isVertical ? 'scrollY' : 'scrollX';
+			context.translator = isVertical ? 'translateY' : 'translateX' ;
+			context.currentPositionCoordinate = aEvent[context.position];
+			context.currentRowPositionCoordinate = aEvent[context.rowPosition];
+
+			var b = this.getTabBrowserFromChild(tabbar);
+			var firstNormalTab = b.visibleTabs[b._numPinnedTabs];
+			context.pinned = context.draggedTab.pinned;
+			context.onPinnedArea = context.currentRowPositionCoordinate < firstNormalTab.boxObject[context.rowPosition];
+			context.tabbarIsVertical = tabbarIsVertical;
+			context.multirowTabs = context.pinned &&
+									context.onPinnedArea &&
+									tabbarIsVertical &&
+									!isVertical;
+
+			context.tabSize = context.draggedTab.getBoundingClientRect()[context.size];
+			context.tabCenterOffset = context.tabSize * (context.options.canDropOnSelf ? 0.25 : 0.5 );
+
+
+			context.utils = this;
+			context.destroy = function() {
+				Object.keys(context).forEach(function(key) {
+					delete context[key];
+				});
+			};
+
+			return context;
+		},
+		setupDraggedTabs : function TDU_setupDraggedTabs(context)
+		{
+			context.tabsSize = 0;
+			context.draggedTabs.forEach(function(draggedTab) {
+				let style = window.getComputedStyle(draggedTab, null);
+				if (style.visibility != 'collapse' && style.display != 'none')
+					context.tabsSize += draggedTab.boxObject[context.size];
+
+				if (!draggedTab._dragData)
+					draggedTab._dragData = {};
+				this.fixDragData(draggedTab._dragData);
+
+				if (!('animLastScreenX' in draggedTab._dragData))
+					draggedTab._dragData.animLastScreenX = draggedTab._dragData[context.position];
+				if (!('previousPosition' in draggedTab._dragData))
+					draggedTab._dragData.previousPosition = context.currentPositionCoordinate;
+			}, this);
+		},
+		fixDragData : function TDU_fixDragData(aData)
+		{
+			if (!('screenY' in aData))
+				aData.screenY = aData.offsetY + window.screenY;
+			if (!('scrollY' in aData))
+				aData.scrollY = aData.scrollX;
+		},
+		updateDraggedTabs : function TDU_updateDraggedTabs(context)
+		{
+			context.draggedTabs.forEach(function(draggedTab, aIndex) {
+				draggedTab._dragData.animLastScreenX = context.currentPositionCoordinate;
+			}, this);
+		},
+		collectAnimateTabs : function TDU_collectAnimateTabs(tabs, context)
+		{
+			context.animateTabs = context.allAnimateTabs = tabs;
+			if (!context.multirowTabs)
+				return tabs;
+
+			// With Tree Style Tabs, pinned tabs are shown with multiple rows.
+			// We should animate only tabs in the same row.
+			return context.animateTabs = tabs.filter(function(aTab) {
+				var box = aTab.boxObject;
+				var min = box[context.rowPosition];
+				var max = min + box[context.rowSize];
+				var onSameRow = context.currentRowPositionCoordinate >= min &&
+								context.currentRowPositionCoordinate <= max;
+				if (onSameRow) {
+					return true;
+				}
+				else {
+					aTab.style.transform = ''; // reset old animation
+					return false;
+				}
+			});
+		},
+		updateLeftBound : function TDU_updateLeftBound(leftBound, context)
+		{
+			if (context.options.canDropOnSelf)
+				leftBound -= context.tabCenterOffset;
+			return leftBound;
+		},
+		updateRightBound : function TDU_updateRightBound(rightBound, context)
+		{
+			rightBound -= context.tabsSize - context.tabSize;
+			if (context.options.canDropOnSelf)
+				rightBound += context.tabCenterOffset;
+			return rightBound;
+		},
+		updateDraggedTabsTransform : function TDU_updateDraggedTabsTransform(context)
+		{
+			var transform = context.draggedTab.style.transform;
+
+			var tabs = context.draggedTabs;
+			if (context.multirowTabs) { // for multirow pinned tabs
+				let translateX = /translateX\(([-0-9\.]+)(?:px)?\)/.test(transform) && RegExp.$1 || 0;
+				translateX = parseFloat(translateX);
+				let translateY = /translateY\(([-0-9\.]+)(?:px)?\)/.test(transform) && RegExp.$1 || 0;
+				translateY = parseFloat(translateY);
+
+				let rowDelta = context.animateTabs[0].boxObject[context.rowPosition] - context.draggedTab.boxObject[context.rowPosition];
+				if (context.rowPosition == 'screenY')
+					translateY += rowDelta;
+				else
+					translateX += rowDelta;
+
+				transform = 'translate(' + translateX + 'px, ' + translateY + 'px)';
+			}
+			else {
+				tabs = tabs.slice(1);
+			}
+
+			tabs.forEach(function(tab) {
+				tab.style.transform = transform;
+			}, this);
+			context.dontMove = false;
+			context.lastTabCenter = Math.round(context.tabScreenPosition + context.translateDelta + context.tabsSize - context.tabSize / 2);
+		},
+		updateDontMove : function TDU_updateDontMove(boxObject, context)
+		{
+			context.dontMove = (
+				context.options.canDropOnSelf &&
+				(
+					(context.draggedTab._dragData.previousPosition > context.currentPositionCoordinate &&
+					 context.dropTargetTabScreenPosition + context.tabCenterOffset < context.tabCenter) ||
+					(context.draggedTab._dragData.previousPosition < context.currentPositionCoordinate &&
+					 context.dropTargetTabScreenPosition + boxObject[context.size] - context.tabCenterOffset > context.lastTabCenter)
+				)
+			);
+		},
+		checkDontMove : function TDU_checkDontMove(context)
+		{
+			context.draggedTabs.forEach(function(draggedTab) {
+				draggedTab._dragData.previousPosition = context.currentPositionCoordinate;
+			});
+			return context.dontMove;
+		},
+		extractNotDraggedTabs : function TDU_extractNotDraggedTabs(tabs, context)
+		{
+			return tabs.filter(function(tab) {
+				return context.draggedTabs.indexOf(tab) < 0
+			});
+		},
+		updateDropIndex : function TDU_updateDropIndex(newIndex, context)
+		{
+			context.draggedTabs.forEach(function(draggedTab) {
+				draggedTab._dragData.animDropIndex = newIndex;
+			});
+		},
+
+		destroyTabDNDObserver : function TDU_destroyTabDNDObserver(aObserver)
+		{
+			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;
+			delete aObserver.__TabsDragUtils_updated__setEffectAllowedForDataTransfer;
+
+			if (aObserver._animateTabMove == aObserver.__TabsDragUtils_updated__animateTabMove)
+				aObserver._animateTabMove = aObserver.__TabsDragUtils_original__animateTabMove;
+			delete aObserver.__TabsDragUtils_original__animateTabMove;
+			delete aObserver.__TabsDragUtils_updated__animateTabMove;
+
+			let index = this.updatedTabDNDObservers.indexOf(aObserver);
+			if (index > -1)
+				this.updatedTabDNDObservers = this.updatedTabDNDObservers.splice(index, 1);
+		},
+
+		startTabsDrag : function TDU_startTabsDrag(aEvent, aTabs, aOptions)
+		{
+			aOptions = aOptions || {};
+
+			var draggedTab = this.getTabFromEvent(aEvent);
+			var tabs = aTabs || [];
+			var index = tabs.indexOf(draggedTab);
+			if (index < 0)
+				return;
+
+			var dt = aEvent.dataTransfer;
+			dt.setDragImage(this.createDragFeedbackImage(tabs), 0, 0);
+
+			tabs.splice(index, 1);
+			tabs.unshift(draggedTab);
+
+			tabs.forEach(function(aTab, aIndex) {
+				dt.mozSetDataAt(TAB_DROP_TYPE, aTab, aIndex);
+				dt.mozSetDataAt('text/x-moz-text-internal', this.getCurrentURIOfTab(aTab), aIndex);
+			}, this);
+
+			// On Firefox 3.6 or older versions on Windows, drag feedback
+			// image isn't shown if there are multiple drag data...
+			if (tabs.length <= 1 ||
+				'mozSourceNode' in dt ||
+				navigator.platform.toLowerCase().indexOf('win') < 0)
+				dt.mozCursor = 'default';
+
+			if (this.canAnimateDraggedTabs(aEvent)) {
+				let tabbar = this.getTabbarFromEvent(aEvent);
+				let tabbarOffsetX = this.getClientX(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
+				let tabbarOffsetY = this.getClientY(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
+				let isVertical = this.isVertical(tabbar.mTabstrip);
+				tabs.forEach(function(aTab) {
+					var tabOffsetX = this.getClientX(aTab) - tabbarOffsetX;
+					var tabOffsetY = this.getClientY(aTab) - tabbarOffsetY;
+					aTab._dragData = {
+						offsetX: aEvent.screenX - window.screenX - tabOffsetX,
+						offsetY: aEvent.screenY - window.screenY - tabOffsetY,
+						scrollX: isVertical ? 0 : tabbar.mTabstrip.scrollPosition ,
+						scrollY: isVertical ? tabbar.mTabstrip.scrollPosition : 0 ,
+						screenX: aEvent.screenX,
+						screenY: aEvent.screenY
+					};
+				}, this);
+			}
+
+			aEvent.stopPropagation();
+		},
+		isVertical : function TDS_isVertical(aElement)
+		{
+			let style = window.getComputedStyle(aElement, null);
+			return (aElement.orient || style.MozOrient || style.orient) == 'vertical';
+		},
+		getClientX : function TDS_getClientX(aElement)
+		{
+			return aElement.getBoundingClientRect().left;
+		},
+		getClientY : function TDS_getClientY(aElement)
+		{
+			return aElement.getBoundingClientRect().top;
+		},
+		createDragFeedbackImage : function TDU_createDragFeedbackImage(aTabs)
+		{
+			var previews = aTabs.map(function(aTab) {
+					try {
+						return tabPreviews.capture(aTab, false);
+					}
+					catch(e) {
+						return null;
+					}
+				}, this)
+				.filter(function(aPreview) {
+					return aPreview;
+				});
+			var offset = 16;
+
+			var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
+			canvas.width = previews[0].width + (offset * aTabs.length);
+			canvas.height = previews[0].height + (offset * aTabs.length);
+
+			var ctx = canvas.getContext('2d');
+			ctx.save();
+			try {
+				ctx.clearRect(0, 0, canvas.width, canvas.height);
+				previews.forEach(function(aPreview, aIndex) {
+					ctx.drawImage(aPreview, 0, 0);
+					ctx.translate(offset, offset);
+					ctx.globalAlpha = 1 / (aIndex+1);
+				}, this);
+			}
+			catch(e) {
+			}
+			ctx.restore();
+
+			return canvas;
+		},
+		getTabFromEvent : function TDU_getTabFromEvent(aEvent, aReallyOnTab) 
+		{
+			var tab = (aEvent.originalTarget || aEvent.target).ownerDocument.evaluate(
+					'ancestor-or-self::*[local-name()="tab"]',
+					aEvent.originalTarget || aEvent.target,
+					null,
+					XPathResult.FIRST_ORDERED_NODE_TYPE,
+					null
+				).singleNodeValue;
+			if (tab || aReallyOnTab)
+				return tab;
+
+			var b = this.getTabBrowserFromChild(aEvent.originalTarget);
+			if (b &&
+				'treeStyleTab' in b &&
+				'getTabFromTabbarEvent' in b.treeStyleTab) { // Tree Style Tab
+				return b.treeStyleTab.getTabFromTabbarEvent(aEvent);
+			}
+			return null;
+		},
+		getTabbarFromEvent : function TDU_getTabbarFromEvent(aEvent) 
+		{
+			return (aEvent.originalTarget || aEvent.target).ownerDocument.evaluate(
+					'ancestor-or-self::*[local-name()="tabs"]',
+					aEvent.originalTarget || aEvent.target,
+					null,
+					XPathResult.FIRST_ORDERED_NODE_TYPE,
+					null
+				).singleNodeValue;
+		},
+		getTabBrowserFromChild : function TDU_getTabBrowserFromChild(aTabBrowserChild) 
+		{
+			if (!aTabBrowserChild)
+				return null;
+
+			if (aTabBrowserChild.localName == 'tabbrowser') // itself
+				return aTabBrowserChild;
+
+			if (aTabBrowserChild.tabbrowser) // tabs
+				return aTabBrowserChild.tabbrowser;
+
+			if (aTabBrowserChild.localName == 'toolbar') // tabs toolbar
+				return aTabBrowserChild.getElementsByTagName('tabs')[0].tabbrowser;
+
+			var b = aTabBrowserChild.ownerDocument.evaluate(
+					'ancestor-or-self::*[local-name()="tabbrowser"] | '+
+					'ancestor-or-self::*[local-name()="tabs" and @tabbrowser] |'+
+					'ancestor::*[local-name()="toolbar"]/descendant::*[local-name()="tabs" and @tabbrowser]',
+					aTabBrowserChild,
+					null,
+					XPathResult.FIRST_ORDERED_NODE_TYPE,
+					null
+				).singleNodeValue;
+			return (b && b.tabbrowser) || b;
+		},
+		canAnimateDraggedTabs: function TDU_canAnimateDraggedTabs(aEvent)
+		{
+			var tabbar = this.getTabbarFromEvent(aEvent);
+			return tabbar && '_animateTabMove' in tabbar;
+		},
+
+		processTabsDragging: function TDU_processTabsDragging(aEvent, aOptions)
+		{
+			if (this.canAnimateDraggedTabs(aEvent)) {
+				let tabbar = this.getTabbarFromEvent(aEvent);
+				let draggedTab = aEvent.dataTransfer && aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
+				if (!draggedTab || draggedTab.ownerDocument != tabbar.ownerDocument) return false;
+
+				if (!tabbar.hasAttribute('movingtab'))
+					tabbar.setAttribute('movingtab', 'true');
+				tabbar._animateTabMove(aEvent, aOptions);
+				return true;
+			}
+			return false;
+		},
+
+		isTabsDragging : function TDU_isTabsDragging(aEvent) 
+		{
+			if (!aEvent)
+				return false;
+			var dt = aEvent.dataTransfer;
+			if (dt.mozItemCount < 1)
+				return false;
+			for (let i = 0, maxi = dt.mozItemCount; i < maxi; i++)
+			{
+				if (!dt.mozTypesAt(i).contains(TAB_DROP_TYPE))
+					return false;
+			}
+			return true;
+		},
+
+		getSelectedTabs : function TDU_getSelectedTabs(aEventOrTabOrTabBrowser)
+		{
+			var event = aEventOrTabOrTabBrowser instanceof Event ? aEventOrTabOrTabBrowser : null ;
+			var b = this.getTabBrowserFromChild(event ? event.target : aEventOrTabOrTabBrowser );
+			if (!b)
+				return [];
+
+			var w = b.ownerDocument.defaultView;
+			var tab = (aEventOrTabOrTabBrowser instanceof Element &&
+						aEventOrTabOrTabBrowser.localName == 'tab') ?
+						aEventOrTabOrTabBrowser :
+						(event && this.getTabFromEvent(event)) ;
+
+			var selectedTabs;
+			var isMultipleDrag = (
+					( // Firefox itself (https://bugzilla.mozilla.org/show_bug.cgi?id=566510)
+						'visibleTabs' in b &&
+						(selectedTabs = b.visibleTabs.filter(function(aTab) {
+							return aTab.getAttribute('multiselected') == 'true';
+						})) &&
+						selectedTabs.length
+					) ||
+					( // Tab Utilities
+						'selectedTabs' in b &&
+						(selectedTabs = b.selectedTabs) &&
+						selectedTabs.length
+					) ||
+					( // Multiple Tab Handler
+						tab &&
+						'MultipleTabService' in w &&
+						w.MultipleTabService.isSelected(tab) &&
+						w.MultipleTabService.allowMoveMultipleTabs &&
+						(selectedTabs = w.MultipleTabService.getSelectedTabs(b)) &&
+						selectedTabs.length
+					) ||
+					( // based on HTML5 drag events
+						this.isTabsDragging(event) &&
+						(selectedTabs = this.getDraggedTabs(event)) &&
+						selectedTabs.length
+					)
+				);
+			return isMultipleDrag ? selectedTabs :
+					tab ? [tab] :
+					[] ;
+		},
+
+		getDraggedTabs : function TDU_getDraggedTabs(aEventOrDataTransfer)
+		{
+			var dt = aEventOrDataTransfer.dataTransfer || aEventOrDataTransfer;
+			var tabs = [];
+			if (dt.mozItemCount < 1 ||
+				!dt.mozTypesAt(0).contains(TAB_DROP_TYPE))
+				return tabs;
+
+			for (let i = 0, maxi = dt.mozItemCount; i < maxi; i++)
+			{
+				tabs.push(dt.mozGetDataAt(TAB_DROP_TYPE, i));
+			}
+			return tabs.sort(function(aA, aB) { return aA._tPos - aB._tPos; });
+		},
+ 
+	 	getCurrentURIOfTab : function TDU_getCurrentURIOfTab(aTab) 
+		{
+			if (this.isTabNeedToBeRestored(aTab)) {
+				let data = this.getRestoringData(aTab);
+				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;
+		},
+
+		// for drop on bookmarks tree
+		willBeInsertedBeforeExistingNode : function TDU_willBeInsertedBeforeExistingNode(aInsertionPoint) 
+		{
+			// drop on folder in the bookmarks menu
+			if (aInsertionPoint.dropNearItemId === void(0))
+				return false;
+
+			// drop on folder in the places organizer
+			if (aInsertionPoint._index < 0 && aInsertionPoint.dropNearItemId < 0)
+				return false;
+
+			return true;
+		},
+
+		handleEvent : function TDU_handleEvent(aEvent) 
+		{
+			switch (aEvent.type)
+			{
+				case 'load':
+					return this._delayedInit();
+			}
+		},
+
+		_fireTabsDropEvent : function TDU_fireTabsDropEvent(aTabs) 
+		{
+			var event = new CustomEvent(this.EVENT_TYPE_TABS_DROP, {
+					bubbles    : true,
+					cancelable : true,
+					detail     : {
+						tabs : aTabs
+					}
+				});
+			return this._dropTarget.dispatchEvent(event);
+		},
+		get _dropTarget()
+		{
+			return ('PlacesControllerDragHelper' in window ?
+						PlacesControllerDragHelper.currentDropTarge :
+						null ) || document;
+		}
+	};
+
+
+	function DOMDataTransferProxy(aDataTransfer, aInsertionPoint) 
+	{
+		// Don't proxy it because it is not a drag of tabs.
+		if (!aDataTransfer.mozTypesAt(0).contains(TAB_DROP_TYPE))
+			return aDataTransfer;
+
+		var tabs = tabsDragUtils.getDraggedTabs(aDataTransfer);
+
+		// Don't proxy it because there is no selection.
+		if (tabs.length < 2)
+			return aDataTransfer;
+
+		this._source = aDataTransfer;
+		this._tabs = tabs;
+
+		if (!tabsDragUtils._fireTabsDropEvent(tabs))
+			this._tabs = [tabs[0]];
+
+		if (tabsDragUtils.willBeInsertedBeforeExistingNode(aInsertionPoint))
+			this._tabs.reverse();
+	}
+
+	DOMDataTransferProxy.prototype = {
+		
+		_apply : function DOMDTProxy__apply(aMethod, aArguments) 
+		{
+			return this._source[aMethod].apply(this._source, aArguments);
+		},
+	 
+		// nsIDOMDataTransfer 
+		get dropEffect() { return this._source.dropEffect; },
+		set dropEffect(aValue) { return this._source.dropEffect = aValue; },
+		get effectAllowed() { return this._source.effectAllowed; },
+		set effectAllowed(aValue) { return this._source.effectAllowed = aValue; },
+		get files() { return this._source.files; },
+		get types() { return this._source.types; },
+		clearData : function DOMDTProxy_clearData() { return this._apply('clearData', arguments); },
+		setData : function DOMDTProxy_setData() { return this._apply('setData', arguments); },
+		getData : function DOMDTProxy_getData() { return this._apply('getData', arguments); },
+		setDragImage : function DOMDTProxy_setDragImage() { return this._apply('setDragImage', arguments); },
+		addElement : function DOMDTProxy_addElement() { return this._apply('addElement', arguments); },
+	 
+		// nsIDOMNSDataTransfer 
+		get mozItemCount()
+		{
+			return this._tabs.length;
+		},
+
+		get mozCursor() { return this._source.mozCursor; },
+		set mozCursor(aValue) { return this._source.mozCursor = aValue; },
+
+		mozTypesAt : function DOMDTProxy_mozTypesAt(aIndex)
+		{
+			if (aIndex >= this._tabs.length)
+				return new StringList([]);
+
+			// return this._apply('mozTypesAt', [0]);
+			// I return "text/x-moz-url" as a first type, to override behavior for "to-be-restored" tabs.
+			return new StringList(['text/x-moz-url', TAB_DROP_TYPE, 'text/x-moz-text-internal']);
+		},
+
+		mozClearDataAt : function DOMDTProxy_mozClearDataAt()
+		{
+			this._tabs = [];
+			return this._apply('mozClearDataAt', [0]);
+		},
+
+		mozSetDataAt : function DOMDTProxy_mozSetDataAt(aFormat, aData, aIndex)
+		{
+			this._tabs = [];
+			return this._apply('mozSetDataAt', [aFormat, aData, 0]);
+		},
+
+		mozGetDataAt : function DOMDTProxy_mozGetDataAt(aFormat, aIndex)
+		{
+			if (aIndex >= this._tabs.length)
+				return null;
+
+			var tab = this._tabs[aIndex];
+			switch (aFormat)
+			{
+				case TAB_DROP_TYPE:
+					return tab;
+
+				case 'text/x-moz-url':
+					return (tabsDragUtils.getCurrentURIOfTab(tab) ||
+							'about:blank') + '\n' + tab.label;
+
+				case 'text/x-moz-text-internal':
+					return tabsDragUtils.getCurrentURIOfTab(tab) ||
+							'about:blank';
+			}
+
+			return this._apply('mozGetDataAt', [aFormat, 0]);
+		},
+
+		get mozUserCancelled() { return this._source.mozUserCancelled; }
+	};
+
+	function StringList(aTypes) 
+	{
+		return Object.create(aTypes, {
+			item : { value : function(aIndex) {
+				return this[aIndex];
+			} },
+			contains : { value : function(aType) {
+				return this.indexOf(aType) > -1;
+			} }
+		});
+	}
+
+	tabsDragUtils.DOMDataTransferProxy = DOMDataTransferProxy;
+	tabsDragUtils.StringList = StringList;
+
+	window['piro.sakura.ne.jp'].tabsDragUtils = tabsDragUtils;
+	tabsDragUtils.init();
+})();
diff --git a/content/treestyletab/treestyletab.css b/content/treestyletab/treestyletab.css
index c27e369..de38f4b 100644
--- a/content/treestyletab/treestyletab.css
+++ b/content/treestyletab/treestyletab.css
@@ -103,6 +103,10 @@
 	visibility: collapse !important;
 }
 
+.treestyletab-tabbar-toggler {
+  opacity: 0.01;
+  position: relative;
+}
 
 /* auto hide tab bar */
 
diff --git a/content/treestyletab/windowHelper.js b/content/treestyletab/windowHelper.js
index cbfa14c..23060f5 100644
--- a/content/treestyletab/windowHelper.js
+++ b/content/treestyletab/windowHelper.js
@@ -36,10 +36,10 @@ var TreeStyleTabWindowHelper = {
 		};
 
 		nsBrowserAccess.prototype.__treestyletab__openURIInFrame = nsBrowserAccess.prototype.openURIInFrame;
-		nsBrowserAccess.prototype.openURIInFrame = function(aURI, aParams, aWhere, aContext) {
+		nsBrowserAccess.prototype.openURIInFrame = function(aURI, aParams, aWhere, aContext, ...aArgs) {
 			if (aWhere === Ci.nsIBrowserDOMWindow.OPEN_NEWTAB)
 				TreeStyleTabService.onBeforeBrowserAccessOpenURI(aParams, aWhere, aContext);
-			return nsBrowserAccess.prototype.__treestyletab__openURIInFrame.call(this, aURI, aParams, aWhere, aContext);
+			return nsBrowserAccess.prototype.__treestyletab__openURIInFrame.call(this, aURI, aParams, aWhere, aContext, ...aArgs);
 		};
 
 		if ('TabsInTitlebar' in window) {
@@ -459,7 +459,15 @@ var TreeStyleTabWindowHelper = {
 		};
 
 		b.__treestyletab__loadTabs = b.loadTabs;
-		b.loadTabs = function(aURIs, aLoadInBackground, aReplace, ...aArgs) {
+		b.loadTabs = function(aURIs, ...aArgs) {
+			var aLoadInBackground = aArgs[1];
+			var aReplace = aArgs[2];
+			if (typeof aLoadInBackground == 'object' && 
+				aLoadInBackground) {
+				aReplace = aLoadInBackground.replace;
+				aLoadInBackground = aLoadInBackground.inBackground;
+			}
+
 			if (!TreeStyleTabWindowHelper.runningDelayedStartup) { // don't open home tabs as a tree!
 				if (aReplace)
 					this.treeStyleTab.readyToOpenChildTab(this.selectedTab, true);
@@ -472,7 +480,7 @@ var TreeStyleTabWindowHelper = {
 			var firstTabAdded;
 			try {
 				tabs = this.treeStyleTab.doAndGetNewTabs((function() {
-						result = this.__treestyletab__loadTabs.call(this, aURIs, aLoadInBackground, aReplace, ...aArgs);
+						result = this.__treestyletab__loadTabs(aURIs, ...aArgs);
 					}).bind(this));
 				firstTabAdded = tabs[0];
 			}
@@ -686,10 +694,11 @@ var TreeStyleTabWindowHelper = {
 						return;
 
 					var tabbarBox = tabContainer.mTabstrip.scrollBoxObject;
-					Array.forEach(this.childNodes, function(aItem) {
+					for (let aItem of this.childNodes)
+					{
 						let tab = aItem.tab;
 						if (!tab) // not tab item
-							return;
+							continue;
 
 						let tabBox = tab.boxObject;
 						if (tabBox[treeStyleTab.screenPositionProp] >= tabbarBox[treeStyleTab.screenPositionProp] &&
@@ -697,7 +706,7 @@ var TreeStyleTabWindowHelper = {
 							aItem.setAttribute('tabIsVisible', true);
 						else
 							aItem.removeAttribute('tabIsVisible');
-					}, this);
+					}
 				};
 		}
 	
diff --git a/content/treestyletab/windowHelperHacks.js b/content/treestyletab/windowHelperHacks.js
index 13b6413..5ba0582 100644
--- a/content/treestyletab/windowHelperHacks.js
+++ b/content/treestyletab/windowHelperHacks.js
@@ -41,14 +41,14 @@ TreeStyleTabWindowHelper.overrideExtensionsPreInit = function TSTWH_overrideExte
 				let originalTabs = [];
 				GM_BrowserUI.openInTab = function(aMessage, ...aArgs) {
 					if (originalTabs.length === 0)
-						originalTabs = Array.slice(gBrowser.tabContainer.childNodes, 0);
+						originalTabs = [...gBrowser.tabContainer.childNodes];
 					var owner = aMessage.target;
 					var retVal = originalOpenInTab.call(this, aMessage, ...aArgs);
 					window.setTimeout(function() {
 						window.setTimeout(function() {
 							if (originalTabs.length === 0)
 								return;
-							var currentTabs = Array.slice(gBrowser.tabContainer.childNodes, 0);
+							var currentTabs = [...gBrowser.tabContainer.childNodes];
 							var parent = gBrowser.treeStyleTab.getTabFromBrowser(owner);
 							var insertAtFirst = TreeStyleTabUtils.getTreePref('insertNewChildAt') == sv.kINSERT_FISRT;
 							var firstChild = gBrowser.treeStyleTab.getFirstChildTab(parent);
@@ -541,9 +541,20 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 		}
 	}
 
-	window.setTimeout(function(aSelf) {
-		aSelf.overrideExtensionsDelayed();
-	}, 0, this);
+	window.setTimeout((function() {
+		this.overrideExtensionsDelayed();
+		if (typeof gBrowser._insertBrowser != 'function') {
+			this.overrideExtensionsAfterBrowserInserted();
+		}
+	}).bind(this), 0);
+
+	if (typeof gBrowser._insertBrowser == 'function') {
+		let onTabBrowserInserted = (function() {
+			window.removeEventListener('TabBrowserInserted', onTabBrowserInserted, false);
+			this.overrideExtensionsAfterBrowserInserted();
+		}).bind(this);
+		window.addEventListener('TabBrowserInserted', onTabBrowserInserted, false);
+	}
 };
 
 
@@ -665,7 +676,10 @@ TreeStyleTabWindowHelper.overrideExtensionsDelayed = function TSTWH_overrideExte
 		document.addEventListener(sv.kEVENT_TYPE_FOCUS_NEXT_TAB, listener, false);
 		document.addEventListener('unload', listener, false);
 	}
+};
+
 
+TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInserted = function TSTWH_overrideExtensionsAfterBrowserInserted() {
 	// Firefox Sync (Weave)
 	// http://www.mozilla.com/en-US/firefox/sync/
 	if (
@@ -677,6 +691,8 @@ TreeStyleTabWindowHelper.overrideExtensionsDelayed = function TSTWH_overrideExte
 		) {
 		let ns = {};
 		try { // 1.4
+			// This touches to tab.messageManager.
+			// To prevent warnings from the bug 1345098, we need to call this after TabBrowserInserted event.
 			Components.utils.import('resource://services-sync/service.js', ns);
 		}
 		catch(e) { // 1.3
diff --git a/defaults/preferences/treestyletab.js b/defaults/preferences/treestyletab.js
index 27a0e3e..e6cca38 100644
--- a/defaults/preferences/treestyletab.js
+++ b/defaults/preferences/treestyletab.js
@@ -143,6 +143,8 @@ pref("extensions.treestyletab.tabbar.autoShow.feedback.moved", true);
 pref("extensions.treestyletab.tabbar.autoShow.feedback.selected", true);
 pref("extensions.treestyletab.tabbar.autoShow.feedback.titleChanged", true);
 pref("extensions.treestyletab.tabbar.autoShow.feedback.delay", 3000);
+pref("extensions.treestyletab.tabbar.autoShow.click", false);
+pref("extensions.treestyletab.tabbar.autoHide.mousemoveAfterClick", true);
 /**
  * Size of the placeholder for "hidden tab bar".
  * When "tabbar.autoHide.mode"==1, the tab bar will be hidden completely.
@@ -299,6 +301,8 @@ pref("extensions.treestyletab.platform.Darwin.indent.property.top", "margin-bott
  * (dropping a tab onto an existing tab, new child tab from link, etc.)
  *  0 = Insert as the first child.
  *  1 = Insert as the last child.
+ *  -1 = No control. You should use this option if you want to use any other
+ *       addon which controls new tab positions.
  */
 pref("extensions.treestyletab.insertNewChildAt", 1);
 
@@ -537,12 +541,6 @@ pref("extensions.treestyletab.autoAttach.goButton", 1);
 pref("extensions.treestyletab.autoAttach.fromCurrent", 1);
 
 /**
- * If true, TST controls position of a newly opened tab by self.
- * You should turn this false if you want to use any other addon which controls new tab positions.
- */
-pref("extensions.treestyletab.controlNewTabPosition", true);
-
-/**
  * Focus targets for Ctrl-Tab/Ctrl-Shift-Tab.
  *  0 = Focus to both visible and collapsed tabs. (If a collapsed tab is
  *      focused, the tree will be expanded by another pref "autoExpandSubtreeOnCollapsedChildFocused".
@@ -738,4 +736,6 @@ pref("extensions.treestyletab.debug.contentBridge", false);
 pref("extensions.treestyletab.debug.fullscreenObserver", false);
 pref("extensions.treestyletab.debug.fullTooltip", false);
 pref("extensions.treestyletab.debug.tabbarDNDObserver", false);
+pref("extensions.treestyletab.debug.tabContentsObserver", false);
+pref("extensions.treestyletab.debug.tabpanelDNDObserver", false);
 pref("extensions.treestyletab.debug.window", false);
diff --git a/install.rdf b/install.rdf
index 69e959d..bf16581 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.18.2016111701"
+                   em:version="0.19.2017061601"
                    em:creator="YUKI "Piro" Hiroshi"
                    em:description="Show tabs like a tree."
                    em:homepageURL="http://piro.sakura.ne.jp/xul/_treestyletab.html.en"
@@ -270,12 +270,31 @@
             <em:translator>Vlastimil Ovčáčík (cs)</em:translator>
         </RDF:Description>
     </em:localized>
+    <em:localized>
+      <RDF:Description em:locale="gr-EL"
+                         em:name="Tree Style Tab"
+                         em:description="Show tabs like a tree."
+                         em:homepageURL="http://piro.sakura.ne.jp/xul/_treestyletab.html.en"
+                         em:creator="YUKI "Piro" Hiroshi">
+            <em:contributor>Zusukar (auto-shrink mode)</em:contributor>
+            <em:contributor>Alice0775 (compatibility problem)</em:contributor>
+            <em:contributor>Philipp von Weitershausen (Sidebar style)</em:contributor>
+            <em:contributor>wanabe (some bug fixes)</em:contributor>
+            <em:contributor>Tetsuharu OHZEKI (code cleanup)</em:contributor>
+            <em:contributor>mnoorenberghe (Firefox 36 support)</em:contributor>
+            <em:contributor>Xidorn Quan (Firefox 40+ support)</em:contributor>
+            <em:contributor>J. Ryan Stinnett (bug fix around tearing off of multiple tabs)</em:contributor>
+            <em:contributor>lv7777</em:contributor>
+            <em:contributor>Andrew Shu (better styling of tabs with the "Metal" skin on macOS)</em:contributor>
+            <em:translator>Vangelis Skarmoutsos (gr-EL)</em:translator>
+        </RDF:Description>
+    </em:localized>
 
 
     <em:targetApplication>
       <RDF:Description em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
-                       em:minVersion="45.0"
-                       em:maxVersion="52.0a1" />
+                       em:minVersion="52.0"
+                       em:maxVersion="56.0a1" />
     </em:targetApplication>
   </RDF:Description>
 </RDF:RDF>
diff --git a/locale/cs/treestyletab/treestyletab.dtd b/locale/cs/treestyletab/treestyletab.dtd
index b33e9d2..0f85679 100644
--- a/locale/cs/treestyletab/treestyletab.dtd
+++ b/locale/cs/treestyletab/treestyletab.dtd
@@ -108,6 +108,7 @@
 <!ENTITY config.autoHide.area.after "pixelů od okraje okna nebo lišty panelů">
 <!ENTITY config.autoHide.delay.before "Zpoždění:">
 <!ENTITY config.autoHide.delay.after "ms">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Klávesa Ctrl je stisknuta po určitou dobu">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Zobrazit lištu po">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "ms">
@@ -137,6 +138,7 @@
 <!ENTITY config.focusMode "Přepnout na následující/předchozí panel pomocí Ctrl-Tab i přesto, že není vidět">
 
 <!ENTITY config.insertNewChildAt.caption "Umístění nového potomka">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Vložit ho na začátek stromu jako prvního potomka">
 <!ENTITY config.insertNewChildAt.last "Připojit ho za posledním potomkem ve stromě">
 
diff --git a/locale/da-DK/treestyletab/treestyletab.dtd b/locale/da-DK/treestyletab/treestyletab.dtd
index f9404d7..29d7b20 100644
--- a/locale/da-DK/treestyletab/treestyletab.dtd
+++ b/locale/da-DK/treestyletab/treestyletab.dtd
@@ -122,6 +122,7 @@
 <!ENTITY config.autoHide.area.after "pixel fra vindueskant eller fanebjælke">
 <!ENTITY config.autoHide.delay.before "Forsinkelse:">
 <!ENTITY config.autoHide.delay.after "msec.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Ved tryk på Ctrl tasten">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Vis efter">
 <!ENTITY config.autoShow.accelKeyDown.delay.after "msec.">
@@ -151,6 +152,7 @@
 <!ENTITY config.focusMode "Flyt fokus til næste/forrige fane, selv om den ikke er synlig, med Ctrl-Tab">
 
 <!ENTITY config.insertNewChildAt.caption "Placering af nye underfaner">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Indsæt øverst som første underfane">
 <!ENTITY config.insertNewChildAt.last "Indsæt i træets bund">
 
diff --git a/locale/de-DE/treestyletab/treestyletab.dtd b/locale/de-DE/treestyletab/treestyletab.dtd
index 5451484..726c079 100644
--- a/locale/de-DE/treestyletab/treestyletab.dtd
+++ b/locale/de-DE/treestyletab/treestyletab.dtd
@@ -108,6 +108,7 @@
 <!ENTITY config.autoHide.area.after                "Pixel rund um die Fenster- oder Tableistenkante">
 <!ENTITY config.autoHide.delay.before              "Verzögerung:">
 <!ENTITY config.autoHide.delay.after               "Millisekunden">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown              "Wenn die Strg-Taste eine Zeit lang gedrückt wird">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Nach">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "Millisekunden anzeigen">
@@ -136,6 +137,7 @@
 <!ENTITY config.focusMode "Bei Strg+Tab auch zu nicht sichtbaren Tabs wechseln">
 
 <!ENTITY config.insertNewChildAt.caption "Einfügeposition neuer untergeordneter Tabs">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first   "Als ersten Tab einfügen">
 <!ENTITY config.insertNewChildAt.last    "Als letzten Tab anfügen">
 
diff --git a/locale/en-US/treestyletab/license.txt b/locale/en-US/treestyletab/license.txt
index 9dc284f..2d16cc7 100644
--- a/locale/en-US/treestyletab/license.txt
+++ b/locale/en-US/treestyletab/license.txt
@@ -14,7 +14,7 @@ License.
 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) 2007-2014
+Portions created by the Initial Developer are Copyright (C) 2007-2017
 the Initial Developer. All Rights Reserved.
 
 Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
diff --git a/locale/en-US/treestyletab/treestyletab.dtd b/locale/en-US/treestyletab/treestyletab.dtd
index 3e4e1a8..ece88b4 100644
--- a/locale/en-US/treestyletab/treestyletab.dtd
+++ b/locale/en-US/treestyletab/treestyletab.dtd
@@ -108,6 +108,7 @@
 <!ENTITY config.autoHide.area.after "pixels from edges of window or tab bar">
 <!ENTITY config.autoHide.delay.before "Delay:">
 <!ENTITY config.autoHide.delay.after "msec.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Control key is pressed a while">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Show after">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "msec.">
@@ -136,6 +137,7 @@
 <!ENTITY config.focusMode "Focus to the next/previous tab even if it is invisible, by Control-Tab">
 
 <!ENTITY config.insertNewChildAt.caption "Insertion position of new child tabs">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Insert to the top of the tree, as the first child">
 <!ENTITY config.insertNewChildAt.last "Append to the last of the tree">
 
diff --git a/locale/es-ES/treestyletab/treestyletab.dtd b/locale/es-ES/treestyletab/treestyletab.dtd
index f4894c9..c4aa126 100644
--- a/locale/es-ES/treestyletab/treestyletab.dtd
+++ b/locale/es-ES/treestyletab/treestyletab.dtd
@@ -117,6 +117,7 @@
 <!ENTITY config.autoHide.area.after "píxeles del borde de la ventana / barra de pestañas">
 <!ENTITY config.autoHide.delay.before "Retraso:">
 <!ENTITY config.autoHide.delay.after "mseg.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Mientras la tecla Control es presionada por un instante">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Mostrar después">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "mseg.">
@@ -148,6 +149,7 @@
 <!ENTITY config.focusMode "Seleccionar la próxima/anterior pestaña aunque no este visible, cuando se presiona Control-Tab">
 
 <!ENTITY config.insertNewChildAt.caption "Posición de inserción de nuevas pestañas hijas">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Insertar arriba del todo en el árbol">
 <!ENTITY config.insertNewChildAt.last "Insertar abajo del todo en el árbol">
 
diff --git a/locale/fr-FR/treestyletab/treestyletab.dtd b/locale/fr-FR/treestyletab/treestyletab.dtd
index a52e8ad..a509e91 100644
--- a/locale/fr-FR/treestyletab/treestyletab.dtd
+++ b/locale/fr-FR/treestyletab/treestyletab.dtd
@@ -109,6 +109,7 @@
 <!ENTITY config.autoHide.area.after "pixels des bords de la fenêtre / du panneau des onglets">
 <!ENTITY config.autoHide.delay.before "Délai :">
 <!ENTITY config.autoHide.delay.after "msec.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "La touche Control est appuyée pendant un moment">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Afficher après">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "msec.">
@@ -138,6 +139,7 @@
 <!ENTITY config.focusMode "Activer l'onglet suivant/précédent même s'il n'est pas visible par Control-Tab">
 
 <!ENTITY config.insertNewChildAt.caption "Endroit d'insertion des nouveaux onglets enfants">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Insérer au sommet de l'arborescence, en tant que premier enfant">
 <!ENTITY config.insertNewChildAt.last "Ajouter après le dernier de l'arborescence">
 
diff --git a/locale/ja/treestyletab/license.txt b/locale/gr-EL/treestyletab/license.txt
similarity index 97%
copy from locale/ja/treestyletab/license.txt
copy to locale/gr-EL/treestyletab/license.txt
index 9dc284f..2aeac80 100644
--- a/locale/ja/treestyletab/license.txt
+++ b/locale/gr-EL/treestyletab/license.txt
@@ -1,34 +1,35 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of these files are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use these files except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-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) 2007-2014
-the Initial Developer. All Rights Reserved.
-
-Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
-
-Alternatively, the contents of these files may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of these files only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of these files under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of these files under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
+
+***** BEGIN LICENSE BLOCK *****
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+The contents of these files are subject to the Mozilla Public License Version
+1.1 (the "License"); you may not use these files except in compliance with
+the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+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) 2007-2014
+the Initial Developer. All Rights Reserved.
+
+Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
+
+Alternatively, the contents of these files may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of these files only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of these files under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of these files under
+the terms of any one of the MPL, the GPL or the LGPL.
+
+***** END LICENSE BLOCK *****
diff --git a/locale/gr-EL/treestyletab/treestyletab.dtd b/locale/gr-EL/treestyletab/treestyletab.dtd
new file mode 100644
index 0000000..b4555ff
--- /dev/null
+++ b/locale/gr-EL/treestyletab/treestyletab.dtd
@@ -0,0 +1,194 @@
+<!ENTITY config.title        "Διαμόρφωση Tree Style Tab">
+
+<!ENTITY config.scale.min "min">
+<!ENTITY config.scale.max "max">
+
+
+<!ENTITY config.tabs.appearance "Εμφάνιση">
+
+<!ENTITY config.tabbar.position.caption "Θέση λωρίδας καρτέλων">
+<!ENTITY config.tabbar.position.left    "Αριστερά">
+<!ENTITY config.tabbar.position.right   "Δεξιά">
+<!ENTITY config.tabbar.position.top     "Επάνω (προκαθορισμένο του Firefox)">
+<!ENTITY config.tabbar.position.bottom  "Κάτω">
+<!ENTITY config.tabbar.invertClosebox.left  "Εμφάνιση συμβόλου κλεισίματος στην αριστερή πλευρά κάθε καρτέλας">
+<!ENTITY config.tabbar.invertClosebox.right "Εμφάνιση συμβόλου κλεισίματος στην δεξιά πλευρά κάθε καρτέλας">
+<!ENTITY config.tabbar.invertTab            "Αναστροφή εμφάνισης καρτέλων">
+<!ENTITY config.tabbar.invertTabContents    "Αναστροφή περιεχομένων καρτέλων">
+<!ENTITY config.tabbar.narrowScrollbar      "Στενή γραμμή κύλισης">
+<!ENTITY config.enableSubtreeIndent "Χρήση εσοχών στις καρτέλες">
+<!ENTITY config.maxTreeLevel.before "μέχρι">
+<!ENTITY config.maxTreeLevel.after  "επίπεδο(α)">
+<!ENTITY config.tabbarSize.before-horizontal ":">
+<!ENTITY config.tabbarSize.after-horizontal  "px ύψος">
+<!ENTITY config.tabbarSize.before-vertical   ":">
+<!ENTITY config.tabbarSize.after-vertical    "px πλάτος">
+
+
+<!ENTITY config.tabs.style "Στυλ">
+
+<!ENTITY config.tabbar.style.caption "Στυλ της λωρίδας καρτέλων">
+<!ENTITY config.tabbar.style.plain   "Απλό">
+<!ENTITY config.tabbar.style.flat    "Επίπεδο">
+<!ENTITY config.tabbar.style.mixed   "Ανάμικτο">
+<!ENTITY config.tabbar.style.vertigo "Vertigo">
+<!ENTITY config.tabbar.style.metal   "Μεταλικό">
+<!ENTITY config.tabbar.style.sidebar "Sidebar">
+<!ENTITY config.tabbar.style.none    "Προκαθορισμένο (καθορίζεται από το Θέμα)">
+
+<!ENTITY config.twisty.style.caption "Tree twisties">
+<!ENTITY config.twisty.style.auto    "Αυτόματο">
+<!ENTITY config.twisty.style.none    "Κανένα">
+<!ENTITY config.twisty.style.retro   "Ρετρό">
+<!ENTITY config.twisty.style.modern.black "Μαύρο μοντέρνο">
+<!ENTITY config.twisty.style.modern.white "Λευκό μοντέρνο">
+<!ENTITY config.twisty.style.osx     "OS X">
+
+
+<!ENTITY config.tabs.menu "Μενού">
+
+<!ENTITY config.show.tabContextMenu.caption "Προσθήκη των ακόλουθων αντικειμένων στο συναφές μενού στις καρτέλες">
+
+<!ENTITY config.tabs.tab "Νέες καρτέλες">
+
+<!ENTITY config.autoAttach.newTabCommand.label_before "Άνοιγμα νέας κενής καρτέλας ως">
+<!ENTITY config.autoAttach.newTabCommand.independent "ανεξάρτητη καρτέλα">
+<!ENTITY config.autoAttach.newTabCommand.child       "παιδί της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.newTabCommand.sibling     "αδερφική της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.newTabCommand.nextSibling "η επόμενη αδερφική της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.newTabCommand.label_after "">
+
+<!ENTITY config.autoAttach.newTabButton.label_before "Για μεσσαίο κλικ στο κουμπί "Νέα καρτέλα", άνοιγμα νέας κενής καρτέλας ως">
+<!ENTITY config.autoAttach.newTabButton.independent "ανεξάρτητη καρτέλα">
+<!ENTITY config.autoAttach.newTabButton.child       "παιδί της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.newTabButton.sibling     "αδερφική της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.newTabButton.nextSibling "η επόμενη αδερφική της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.newTabButton.label_after "">
+
+<!ENTITY config.autoAttach.duplicateTabCommand.label_before "Για μεσσαίο κλικ στο κουμπί "Επαναφόρτωση", αντέγραψε την καρτέλα ως">
+<!ENTITY config.autoAttach.duplicateTabCommand.independent "ανεξάρτητη καρτέλα">
+<!ENTITY config.autoAttach.duplicateTabCommand.child       "παιδί της αρχικής καρτέλας">
+<!ENTITY config.autoAttach.duplicateTabCommand.sibling     "αδερφική της αρχικής καρτέλας">
+<!ENTITY config.autoAttach.duplicateTabCommand.nextSibling "η επόμενη αδερφική της αρχικής καρτέλας">
+<!ENTITY config.autoAttach.duplicateTabCommand.label_after "">
+
+<!ENTITY config.autoAttach.goButton.label_before "Για μεσσαίο κλικ στο κουμπί "Πάμε", άνοιγμα νέας καρτέλας ως">
+<!ENTITY config.autoAttach.goButton.independent "ανεξάρτητη καρτέλα">
+<!ENTITY config.autoAttach.goButton.child       "παιδί της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.goButton.sibling     "αδερφική της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.goButton.nextSibling "η επόμενη αδερφική της τρέχουσας καρτέλας">
+<!ENTITY config.autoAttach.goButton.label_after "">
+
+<!ENTITY config.openGroupBookmark.caption     "Συμπεριφορά του "Άνοιγμα όλων σε καρτέλες" για φακέλους σελιδοδείκτη">
+<!ENTITY config.openGroupBookmark.ask         "Πάντα ερώτηση πως να ανοίξουν οι σελιδοδείκτες">
+<!ENTITY config.openGroupBookmark.subtree     "Άνοιγμα ως δέντρο (συνιστάται)">
+<!ENTITY config.openGroupBookmark.subtree.type.before  "">
+<!ENTITY config.openGroupBookmark.subtree.type.restore "Επαναφορά">
+<!ENTITY config.openGroupBookmark.subtree.type.flat    "Αγνόηση">
+<!ENTITY config.openGroupBookmark.subtree.type.after   "η δενδρική δομή των καρτέλων αποθηκεύτηκε στους σελιδοδείκτες">
+<!ENTITY config.openGroupBookmark.flat        "Άνοιγμα ως ξεχωριστές καρτέλες (προκαθορισμένο του Firefox)">
+<!ENTITY config.openGroupBookmark.underParent "Τοποθέτηση των καρτέλων κάτω από μία ψεύτικη καρτέλα για ομαδοποίηση">
+
+<!ENTITY config.dropLinksOnTab.caption "Αφημένος σύνδεσμος, URL, σεδιλοδείκτης ή αρχείο σε υπάρχουσα καρτέλα">
+<!ENTITY config.dropLinksOnTab.ask     "Πάντα ερώτηση πως να φορτωθεί">
+<!ENTITY config.dropLinksOnTab.load    "Φόρτωση στην καρτέλα (προκαθορισμένο του Firefox)">
+<!ENTITY config.dropLinksOnTab.newTab  "Άνοιγμα ως νέα καρτέλα-παιδί">
+
+
+<!ENTITY config.tabs.autohide "Auto hide">
+
+<!ENTITY config.autoHide.mode.normal.caption     "για κανονική κατάσταση παραθύρων">
+<!ENTITY config.autoHide.mode.fullscreen.caption "για κατάταση σε πλήρη οθόνη">
+<!ENTITY config.autoHide.mode.0 "Εμφάνιση λωρίδας καρτέλων πάντα">
+<!ENTITY config.autoHide.mode.1 "Αυτόματη απόκρυψη λωρίδας καρτέλων">
+<!ENTITY config.autoHide.mode.2 "Αυτόματη συρρίκνωση λωρίδας καρτέλων">
+<!ENTITY config.autoShow.caption "Αυτόματη εμφάνιση λωρίδας καρτέλων όταν">
+<!ENTITY config.autoShow.mousemove "ο δείκτης του ποντικιού είναι κοντά στις άκρες του παραθύρου ή της λωρίδας καρτέλων">
+<!ENTITY config.autoHide.area.before "Ευαίσθητη περιοχή:">
+<!ENTITY config.autoHide.area.after "pixel από τις άκρες του παραθύρου ή της λωρίδας καρτέλων">
+<!ENTITY config.autoHide.delay.before "Καθυστέρηση:">
+<!ENTITY config.autoHide.delay.after "msec.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
+<!ENTITY config.autoShow.accelKeyDown "Το πλήκτρο control πατήθηκε για λίγο">
+<!ENTITY config.autoShow.accelKeyDown.delay.before "Εμφάνιση μετά">
+<!ENTITY config.autoShow.accelKeyDown.delay.after  "msec.">
+<!ENTITY config.autoShow.tabSwitch   "Control-Tab για εναλλαγή καρτέλων">
+<!ENTITY config.autoShow.feedback    "Κάτι συνέβη στις καρτέλες (νέα καρτέλα, κλεισμένη καρτέλα, αλλαγή εστίασης, αλλαγή τίτλου)">
+<!ENTITY config.autoShow.feedback.delay.before "Απόκρυψη μετά">
+<!ENTITY config.autoShow.feedback.delay.after  "msec.">
+
+
+<!ENTITY config.tabs.tree "Tree">
+
+<!ENTITY config.autoCollapseExpandSubtreeOnAttach "Όταν εμφανίζεται νέο δέντρο, αυτόματη σύμπτυξη των άλλων">
+<!ENTITY config.autoCollapseExpandSubtreeOnSelect "Όταν μια καρτέλα δέχεται εστίαση, αυτόματη ανάπτυξη του δέντρου της και σύμπτυξη των άλλων">
+<!ENTITY config.autoCollapseExpandSubtreeOnSelect.onCurrentTabRemove "Exclude focus moving caused by current tab closing">
+<!ENTITY config.collapseExpandSubtree.dblclick "Διπλό κλικ σε καρτέλα για σύμπτυξη/ανάπτυξη δέντρου">
+<!ENTITY config.autoExpandSubtreeOnAppendChild "Αυτόματη ανάπτυξη δέντρου όταν εισάγονται καρτέλες στο δέντρο">
+
+<!ENTITY config.closeParentBehavior.caption      "Όταν κλείνει γονική καρτέλα">
+<!ENTITY config.closeParentBehavior.close        "Κλείσιμο καρτέλων-παιδιών επίσης">
+<!ENTITY config.closeParentBehavior.promoteFirst "Προαγωγή της πρώτης καρτέλας-παιδιού ως νέο γονιό">
+<!ENTITY config.closeParentBehavior.promoteAll   "Προαγωγή όλων των καρτέλων-παιδιών ως επίπεδο της κλεισμένης γονικής καρτέλας">
+<!ENTITY config.closeParentBehavior.detach       "Απελευθέρωση των καρτέλων-παιδιών από το δέντρο">
+<!ENTITY config.closeParentBehavior.replaceWithGroupTab "Αντικατάσταση του κλεισμένου γονέα με ψεύτικη καρτέλα και διατήρηση του δέντρου">
+<!ENTITY config.closeRootBehavior.promoteFirst   "Προαγωγή της πρώτης καρτέλας-παιδιού ως νέου γονέα, αν ο κλεισμένος γονέας δεν έχει γονέα">
+
+<!ENTITY config.focusMode "Εστίαση στην επόμενη/προηγούμενη καρτέλα ακόμη κι αν είναι αόρατη, με Control-Tab">
+
+<!ENTITY config.insertNewChildAt.caption "Θέση εισαγωγής νέων καρτέλων-παιδιών">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
+<!ENTITY config.insertNewChildAt.first "Εισαγωγή στην κορυφή του δέντρου, ως το πρώτο παιδί">
+<!ENTITY config.insertNewChildAt.last "Προσθήκη στο τέλος του δέντρου">
+
+<!ENTITY config.undoCloseTabSet.caption  "Όταν ένα μέλος του δέντρου επαναφέρεται με "Αναίρεση κλεισίματος καρτέλας"">
+<!ENTITY config.undoCloseTabSet.ask      "Ερώτηση πάντα">
+<!ENTITY config.undoCloseTabSet.set      "Επαναφορά ολόκληρου του δέντρου">
+<!ENTITY config.undoCloseTabSet.separate "Επαναφορά μόνο μίας καρτέλας (προκαθορισμένο του Firefox)">
+
+
+
+<!ENTITY config.tabs.advanced "Για προχωρημένους">
+
+<!ENTITY config.tooltip.includeChildren        "Εμφάνιση περιεχομένων δέντρου στις συμβουλές των καρτέλων">
+
+<!ENTITY config.bookmarkDroppedTabs.caption "Δράση για σύρε-άσε μιας γονικής καρτέλας στο δέντρο σελιδοδεικτών">
+<!ENTITY config.bookmarkDroppedTabs.ask     "Πάντα ερώτηση">
+<!ENTITY config.bookmarkDroppedTabs.all     "Προσθήκη σελιδοδείκτη για όλες τις καρτέλες στο δέντρο">
+<!ENTITY config.bookmarkDroppedTabs.parent  "Προσθήκη σελιδοδείκτη μόνο για την συρώμενη καρτέλα">
+
+
+
+
+
+<!ENTITY selection.createSubtree.label          "Μάζεμα σε νέο δέντρο">
+<!ENTITY selection.createSubtree.accesskey      "g">
+
+<!ENTITY selection.removeTabSubtree.label       "Κλείσιμο επιλεγμένων δέντρων">
+<!ENTITY selection.removeTabSubtree.accesskey   "s">
+<!ENTITY context.reloadTabSubtree.label         "Επαναφόρτωση αυτού του δέντρου">
+<!ENTITY context.reloadTabSubtree.accesskey     "r">
+<!ENTITY context.reloadDescendantTabs.label     "Επαναφόρτωση παιδιών">
+<!ENTITY context.reloadDescendantTabs.accesskey "r">
+<!ENTITY context.removeTabSubtree.label         "Κλείσιμο αυτού του δέντρου">
+<!ENTITY context.removeTabSubtree.accesskey     "s">
+<!ENTITY context.removeDescendantTabs.label     "Κλείσιμο παιδιών">
+<!ENTITY context.removeDescendantTabs.accesskey "d">
+<!ENTITY context.removeAllTabsBut.label         "Κλείσιμο άλλων καρτέλων εκτός αυτού του δέντρου">
+<!ENTITY context.removeAllTabsBut.accesskey     "a">
+<!ENTITY context.collapseAllSubtree.label       "Σύμπτυξη όλων των δέντρων">
+<!ENTITY context.collapseAllSubtree.accesskey   "c">
+<!ENTITY context.expandAllSubtree.label         "Ανάπτυξη όλων των δέντρων">
+<!ENTITY context.expandAllSubtree.accesskey     "e">
+<!ENTITY context.toggleAutoHide.label.hide      "Αυτόματη απόκρυψη λωρίδας καρτέλων">
+<!ENTITY context.toggleAutoHide.label.shrink    "Αυτόματη συρίκνωση λωρίδας καρτέλων">
+<!ENTITY context.toggleAutoHide.accesskey       "h">
+<!ENTITY context.toggleFixed.label              "Σταθερή θέση και πλάτος/ύψος της λωρίδας καρτέλων">
+<!ENTITY context.toggleFixed.label.horizontal   "Σταθερή θέση και ύψος της λωρίδας καρτέλων">
+<!ENTITY context.toggleFixed.label.vertical     "Σταθερή θέση και πλάτος της λωρίδας καρτέλων">
+<!ENTITY context.toggleFixed.accesskey          "f">
+<!ENTITY context.bookmarkTabSubtree.label       "Προσθήκη σελιδοδείκτη για αυτό το δέντρο...">
+<!ENTITY context.bookmarkTabSubtree.accesskey   "t">
+
+<!ENTITY group.default "Νέα ομάδα">
+<!ENTITY group.temporary "Προσωρινή ομάδα">
diff --git a/locale/gr-EL/treestyletab/treestyletab.properties b/locale/gr-EL/treestyletab/treestyletab.properties
new file mode 100644
index 0000000..c78ed6b
--- /dev/null
+++ b/locale/gr-EL/treestyletab/treestyletab.properties
@@ -0,0 +1,59 @@
+tooltip.collapseSubtree=Σύμπτυξη δέντρου
+tooltip.collapseSubtree.labeled=Σύμπτυξη δέντρου:\n%S
+tooltip.expandSubtree=Ανάπτυξη δέντρου
+tooltip.expandSubtree.labeled=Ανάπτυξη δέντρου:\n%S
+tooltip.closeTree=Κλείσιμο αυτού του δέντρου
+tooltip.closeTree.labeled=Κλείσιμο αυτού του δέντρου:\n%S
+tooltip.item.label=%2$S* %1$S
+tooltip.more=...και %1$S ακόμη καρτέλα(ες)
+
+dropLinkOnTab.title=Πώς να ανοίγει ένας αφημένος σύνδεσμος;
+dropLinkOnTab.text=Ένας σύνδεσμος αφέθηκε στην υπάρχουσα καρτέλα. Το Tree Style Tab μπορεί να ανοίξει τον σύνδεσμο ως μια νέα καρτέλα-παιδί. Πως να γίνει η μεταχείριση του συνδέσμου;
+dropLinkOnTab.never=Ποτέ μην ρωτάς, και κάνε την ίδια λειτουργία εφεξής
+dropLinkOnTab.loadInTheTab=Φόρτωση στην καρτέλα (Firefox default)
+dropLinkOnTab.openNewChildTab=Άνοιγμα ως νέας καρτέλας-παιδί
+
+openGroupBookmarkBehavior.title=Πώς να ανοίγουν πολλαπλοί σελιδοδείκτες;
+openGroupBookmarkBehavior.text=Τώρα πολλαπλές καρτέλες θα ανοίγουν από τους σελιδοδείκτες. Πώς να ανοίγουν;
+openGroupBookmarkBehavior.never=Ποτέ μην ρωτάς, και κάνε την ίδια λειτουργία εφεξής
+openGroupBookmarkBehavior.subTree=Άνοιγμα ως νέου δέντρου
+openGroupBookmarkBehavior.separate=Άνοιγμα ως ξεχωριστών καρτέλων (Firefox default)
+openGroupBookmarkBehavior.replace=Αντικατάσταση της τρέχουσας καρτέλας
+
+bookmarkDroppedTabs.title=Πώς να προστίθεται στους σελιδοδείκτες ένα δέντρο από καρτέλες;
+bookmarkDroppedTabs.text=Η συρόμενη καρτέλα έχει παιδιά. Πώς θα τα προσθέσω στους σελιδοδείκτες;
+bookmarkDroppedTabs.never=Μην με ρωτήσεις ξανά
+bookmarkDroppedTabs.bookmarkAll=Προσθήκη στους σελιδοδείκτες όλων των καρτέλων του δέντρου
+bookmarkDroppedTabs.bookmarkOnlyParent=Προσθήκη στους σελιδοδείκτες μόνο της γονικής καρτέλας.
+
+undoCloseTabSetBehavior.label=Αυτή η καρτέλα έκλεισε μαζί μα άλλες %S καρτέλες στο δέντρο. Θέλετε να ανακτηθούν μαζί και αυτές;
+undoCloseTabSetBehavior.restoreOnce=Ανάκτηση καρτέλων
+undoCloseTabSetBehavior.restoreForever=Πάντα ανάκτηση καρτέλων
+undoCloseTabSetBehavior.ignoreForever=Ποτέ να μην εμφανίζεται αυτή η ειδοποίηση
+
+openSelectedPlaces.bookmarks=από %2$S σελιδοδείκτες, περιέχουν "%1$S"
+openSelectedPlaces.history=από %2$S καταχωρήσεις ιστορικού, συμπεριλαμβανομένου "%1$S"
+
+bookmarkProperty.parent.label=Γονική καρτέλα:
+bookmarkProperty.parent.blank.label=(τίποτα)
+bookmarkProperty.parent.current.label=[ %S ]
+
+undo_changeTabbarPosition_label=Αλλαγή της θέσης της λωρίδας καρτέλων
+
+toolbarCustomizing_tabbar_horizontal=Αυτή η γραμμή εργαλείων γίνεται μια λωρίδα καρτέλων.
+toolbarCustomizing_tabbar_vertical=Αυτή η γραμμή εργαλείων γίνεται μια κάθετη λωρίδα καρτέλων.
+
+
+compatibility_STM_warning_title=Super Tab Mode συγκρούεται με το Tree Style Tab
+compatibility_STM_warning_text=Νέες καρτέλες που ανοίγουν από συνδέσμους (ή άλλες) δεν γίνονται παιδιά της τρέχουσας καρτέλας, γιατί η θέση των νέων καρτέλων ελέγχεται από Super Tab Mode. Ποιό χαρακτηριστικό θέλετε να ενεργοποιηθεί;\n(*Μπορείτε να αλλάξετε αυτές τις ρυθμίσεις χειροκίνητα απ τον διάλογο διαμόρφωσης του Super Tab Mode.)
+compatibility_STM_warning_use_TST=Κάνε τις καρτέλες παιδιά της τρέχουσας καρτέλας
+compatibility_STM_warning_use_STM=Βάλε τις καρτέλες στην θέση που καθορίσεται από το Super Tab Mode
+compatibility_STM_warning_never=Μην εμφανίσεις αυτό τον διάλογο ξανά.
+
+
+closeTabsToTheEnd_vertical_label=Κλείσιμο καρτέλων στο κάτω μέρος
+closeTabsToTheEnd_vertical_accesskey=b
+
+
+migration.treeNeverRevoked.title=Τα χαρακτηριστικά δέντρου του Tree Style Tab είναι τώρα ενεργοποιημένα υποχρεωτικά!
+migration.treeNeverRevoked.text=Σημείωση: Μερικές προτιμήσεις για απενεργοποίηση χαρακτηριστικών του δέντρου τώρα μόνιμα εξαφανίστηκαν από το Tree Style Tab. Αν απλά θέλετε μια κατακόρυφη λωρίδα καρτέλων χωρίς χαρακτηριστικά δέντρου, τότε παρακαλώ μεταβείτε σε κάποιο εναλλακτικό πρόσθετο π.χ. "Vertical Tabs", "Side Tabs", ή άλλα.
diff --git a/locale/it-IT/treestyletab/treestyletab.dtd b/locale/it-IT/treestyletab/treestyletab.dtd
index 73e24b6..ad70581 100644
--- a/locale/it-IT/treestyletab/treestyletab.dtd
+++ b/locale/it-IT/treestyletab/treestyletab.dtd
@@ -117,6 +117,7 @@
 <!ENTITY config.autoHide.area.after "distanza dai bordi della finestra / barra delle schede (in pixel)">
 <!ENTITY config.autoHide.delay.before "Ritardo:">
 <!ENTITY config.autoHide.delay.after "msec.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Viene tenuto premuto il tasto Control">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Visualizza dopo">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "msec.">
@@ -148,6 +149,7 @@
 <!ENTITY config.focusMode "Attiva la scheda successiva/precedente, anche se è nascosta, con Control-Tab">
 
 <!ENTITY config.insertNewChildAt.caption "Posizione di inserimento di nuove sottoschede">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Inserisci all'inizio del sottoalbero, come prima sottoscheda">
 <!ENTITY config.insertNewChildAt.last "Accoda all'ultimo sottoalbero">
 
diff --git a/locale/ja/treestyletab/license.txt b/locale/ja/treestyletab/license.txt
index 9dc284f..2d16cc7 100644
--- a/locale/ja/treestyletab/license.txt
+++ b/locale/ja/treestyletab/license.txt
@@ -14,7 +14,7 @@ License.
 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) 2007-2014
+Portions created by the Initial Developer are Copyright (C) 2007-2017
 the Initial Developer. All Rights Reserved.
 
 Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
diff --git a/locale/ja/treestyletab/treestyletab.dtd b/locale/ja/treestyletab/treestyletab.dtd
index a4bca36..8315a62 100644
--- a/locale/ja/treestyletab/treestyletab.dtd
+++ b/locale/ja/treestyletab/treestyletab.dtd
@@ -109,6 +109,7 @@
 <!ENTITY config.autoHide.area.after "ピクセルの範囲">
 <!ENTITY config.autoHide.delay.before "遅延:">
 <!ENTITY config.autoHide.delay.after "ミリ秒">
+<!ENTITY config.autoShow.click "タブバーでのクリック">
 <!ENTITY config.autoShow.accelKeyDown "Controlキーを長押しした時">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "ミリ秒以上で反応">
@@ -138,6 +139,7 @@
 <!ENTITY config.closeRootBehavior.promoteFirst   "最上位の親タブを閉じた時だけは、最初の子タブを新しい親にする">
 
 <!ENTITY config.insertNewChildAt.caption "新しい子タブを開く位置">
+<!ENTITY config.insertNewChildAt.noControl "制御しない(Firefoxや他のアドオンの判断に任せる)">
 <!ENTITY config.insertNewChildAt.first "ツリーの最初の位置に挿入する">
 <!ENTITY config.insertNewChildAt.last "ツリーの末尾に追加する">
 
diff --git a/locale/pl/treestyletab/treestyletab.dtd b/locale/pl/treestyletab/treestyletab.dtd
index 7fba5cc..863ee23 100644
--- a/locale/pl/treestyletab/treestyletab.dtd
+++ b/locale/pl/treestyletab/treestyletab.dtd
@@ -117,6 +117,7 @@
 <!ENTITY config.autoHide.area.after "pikseli od krawędzi okna / paska kart">
 <!ENTITY config.autoHide.delay.before "Opóźnienie:">
 <!ENTITY config.autoHide.delay.after "ms">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Naciśnięciu i przytrzymaniu klawisza [Ctrl]">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Opóźnienie:">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "ms">
@@ -146,6 +147,7 @@
 <!ENTITY config.focusMode "Skrót [Ctrl+Tab] uaktywnia następną/poprzednią kartę nawet jeśli jest niewidoczna">
 
 <!ENTITY config.insertNewChildAt.caption "Położenie wstawianych nowych potomnych kart">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Wstawiaj jako pierwszą potomną na górze drzewa">
 <!ENTITY config.insertNewChildAt.last "Wstawiaj na końcu drzewa">
 
diff --git a/locale/ru/treestyletab/treestyletab.dtd b/locale/ru/treestyletab/treestyletab.dtd
index 8d671d5..e02fcad 100755
--- a/locale/ru/treestyletab/treestyletab.dtd
+++ b/locale/ru/treestyletab/treestyletab.dtd
@@ -115,6 +115,7 @@
 <!ENTITY config.autoHide.area.after "пикселей от края окна или панели вкладок">
 <!ENTITY config.autoHide.delay.before "Задержка:">
 <!ENTITY config.autoHide.delay.after "мсек.">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "При удерживании клавиши Ctrl">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Показывать после">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "мсек.">
@@ -144,6 +145,7 @@
 <!ENTITY config.focusMode "Переходить по Ctrl+Tab на следующую/предыдущую вкладку даже если она скрыта">
 
 <!ENTITY config.insertNewChildAt.caption "Позиция добавления новых дочерних вкладок">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Добавлять в начало дерева">
 <!ENTITY config.insertNewChildAt.last "Добавлять в конец дерева">
 
diff --git a/locale/sv-SE/treestyletab/treestyletab.dtd b/locale/sv-SE/treestyletab/treestyletab.dtd
index f14928f..78bf2e2 100644
--- a/locale/sv-SE/treestyletab/treestyletab.dtd
+++ b/locale/sv-SE/treestyletab/treestyletab.dtd
@@ -121,6 +121,7 @@
 <!ENTITY config.autoHide.area.after "pixlar från kanten av fönstret eller flikfältet">
 <!ENTITY config.autoHide.delay.before "Fördröjning:">
 <!ENTITY config.autoHide.delay.after "ms">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "Ctrl-tangenten hålls nere">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "Visa efter">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "ms">
@@ -150,6 +151,7 @@
 <!ENTITY config.focusMode "Fokusera på nästa/föregående flik även om den är osynlig, m.h.a. Ctrl+Tabb">
 
 <!ENTITY config.insertNewChildAt.caption "Infogningsposition för ny underordnad flik">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "Infoga överst i trädet, som den första underordnade fliken">
 <!ENTITY config.insertNewChildAt.last "Lägg den sist i trädet">
 
diff --git a/locale/zh-CN/treestyletab/treestyletab.dtd b/locale/zh-CN/treestyletab/treestyletab.dtd
index 0020efa..235ef85 100644
--- a/locale/zh-CN/treestyletab/treestyletab.dtd
+++ b/locale/zh-CN/treestyletab/treestyletab.dtd
@@ -121,6 +121,7 @@
 <!ENTITY config.autoHide.area.after "像素(距离窗口边缘)">
 <!ENTITY config.autoHide.delay.before "延迟:">
 <!ENTITY config.autoHide.delay.after "毫秒">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "按下Ctrl键之后">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "等待">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "毫秒再显示">
@@ -150,6 +151,7 @@
 <!ENTITY config.focusMode "通过“Ctrl-Tab”切换标签时可切换到折叠起来的标签上。">
 
 <!ENTITY config.insertNewChildAt.caption "新子标签的位置">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "插入到子树顶部,成为首个子标签">
 <!ENTITY config.insertNewChildAt.last "添加到子树的最后">
 
diff --git a/locale/zh-TW/treestyletab/treestyletab.dtd b/locale/zh-TW/treestyletab/treestyletab.dtd
index 05727c7..51f2927 100644
--- a/locale/zh-TW/treestyletab/treestyletab.dtd
+++ b/locale/zh-TW/treestyletab/treestyletab.dtd
@@ -109,6 +109,7 @@
 <!ENTITY config.autoHide.area.after "個像素的範圍">
 <!ENTITY config.autoHide.delay.before "延遲:">
 <!ENTITY config.autoHide.delay.after "毫秒">
+<!ENTITY config.autoShow.click "Click on the tab bar">
 <!ENTITY config.autoShow.accelKeyDown "按下 Ctrl 一段時間後">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "毫秒以上才顯示">
@@ -140,6 +141,7 @@
 
 
 <!ENTITY config.insertNewChildAt.caption "開啟新子分頁的位置">
+<!ENTITY config.insertNewChildAt.noControl "No control (respect the decision by Firefox or other tab addons)">
 <!ENTITY config.insertNewChildAt.first "子樹的前端">
 <!ENTITY config.insertNewChildAt.last "子樹的末端">
 
diff --git a/modules/autoHide.js b/modules/autoHide.js
index 59709ee..b047523 100644
--- a/modules/autoHide.js
+++ b/modules/autoHide.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-2016
+ * Portions created by the Initial Developer are Copyright (C) 2010-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -60,10 +60,10 @@ XPCOMUtils.defineLazyGetter(this, 'prefs', function() {
 });
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['autoHide'].concat(aArgs));
+	utils.log('autoHide', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['autoHide'].concat(aArgs));
+	utils.logWithStackTrace('autoHide', ...aArgs);
 }
 
 var AutoHideConstants = Object.freeze(inherit(TreeStyleTabConstants, {
@@ -83,8 +83,9 @@ var AutoHideConstants = Object.freeze(inherit(TreeStyleTabConstants, {
 	kSHOWN_BY_SHORTCUT  : 1 << 0,
 	kSHOWN_BY_MOUSEMOVE : 1 << 1,
 	kSHOWN_BY_FEEDBACK  : 1 << 2,
+	kSHOWN_BY_CLICK     : 1 << 9,
 	kSHOWN_AUTOMATICALLY : (1 << 0) | (1 << 1),
-	kSHOWN_BY_ANY_REASON : (1 << 0) | (1 << 1) | (1 << 2),
+	kSHOWN_BY_ANY_REASON : (1 << 0) | (1 << 1) | (1 << 2) | (1 << 9),
 	kSHOWHIDE_BY_START  : 1 << 3,
 	kSHOWHIDE_BY_END    : 1 << 4,
 	kSHOWHIDE_BY_POSITION_CHANGE : 1 << 5,
@@ -203,7 +204,7 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
  
 	get toggler()
 	{
-		return this.document.getAnonymousElementByAttribute(this.browser, 'class', this.treeStyleTab.kTABBAR_TOGGLER);
+		return this.treeStyleTab.toggler;
 	},
 	
 	updateMode : function AHB_updateMode(aNewMode) 
@@ -385,6 +386,10 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 			ReferenceCounter.add('tabStripPlaceHolder,mousedown,AHW,true');
 			sv.tabStripPlaceHolder.addEventListener('mouseup', this, true);
 			ReferenceCounter.add('tabStripPlaceHolder,mouseup,AHW,true');
+			this.toggler.addEventListener('mousedown', this, true);
+			ReferenceCounter.add('toggler,mousedown,AHW,true');
+			this.toggler.addEventListener('mouseup', this, true);
+			ReferenceCounter.add('toggler,mouseup,AHW,true');
 			sv.tabStrip.addEventListener('mousedown', this, true);
 			ReferenceCounter.add('tabStrip,mousedown,AHW,true');
 			w.addEventListener('mouseup', this, true);
@@ -438,6 +443,10 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 			ReferenceCounter.remove('tabStripPlaceHolder,mousedown,AHW,true');
 			sv.tabStripPlaceHolder.removeEventListener('mouseup', this, true);
 			ReferenceCounter.remove('tabStripPlaceHolder,mouseup,AHW,true');
+			this.toggler.removeEventListener('mousedown', this, true);
+			ReferenceCounter.remove('toggler,mousedown,AHW,true');
+			this.toggler.removeEventListener('mouseup', this, true);
+			ReferenceCounter.remove('toggler,mouseup,AHW,true');
 			sv.tabStrip.removeEventListener('mousedown', this, true);
 			ReferenceCounter.remove('tabStrip,mousedown,AHW,true');
 			w.removeEventListener('mouseup', this, true);
@@ -550,8 +559,22 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
  
 	get shouldListenMouseMove() 
 	{
+		return this.shouldShowByMouseMove || this.shouldHideByMouseMove;
+	},
+	get shouldShowByMouseMove() 
+	{
 		return utils.getTreePref('tabbar.autoShow.mousemove');
 	},
+	get shouldHideByMouseMove() 
+	{
+		return (
+			utils.getTreePref('tabbar.autoShow.mousemove') ||
+			(
+				utils.getTreePref('tabbar.autoShow.click') &&
+				utils.getTreePref('tabbar.autoHide.mousemoveAfterClick')
+			)
+		);
+	},
  
 	get shouldListenKeyEventsForAutoHide()
 	{
@@ -606,24 +629,30 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 		var shouldShow = position & this.MOUSE_POSITION_SENSITIVE;
 		var delayToShow = utils.getTreePref('tabbar.autoHide.delay.show');
 		if (this.expanded) { // currently shown, let's hide it.
-			if (shouldShow) {
+			if (
+				shouldShow &&
+				this.shouldShowByMouseMove
+				) {
 				this.show(this.kSHOWN_BY_MOUSEMOVE);
 				this.cancelDelayedShowForShortcut();
 			}
 			else if (
 				!shouldShow &&
-				utils.getTreePref('tabbar.autoShow.mousemove')
+				this.shouldHideByMouseMove
 				) {
 				let delayToHide = utils.getTreePref('tabbar.autoHide.delay.hide');
 				if (delayToHide < 0)
 					delayToHide = delayToShow;
 				this.showHideOnMouseMoveTimer = w.setTimeout((function() {
 					this.cancelDelayedShowForShortcut();
-					this.hide(this.kSHOWN_BY_MOUSEMOVE);
+					this.hide(this.kSHOWN_BY_MOUSEMOVE) || this.hide(this.kSHOWN_BY_CLICK);
 				}).bind(this), delayToHide);
 			}
 		}
-		else if (shouldShow) { // currently shown, let's show it.
+		else if (
+			shouldShow &&
+			this.shouldShowByMouseMove
+			) { // currently shown, let's show it.
 			this.showHideOnMouseMoveTimer = w.setTimeout((function() {
 				this.cancelDelayedShowForShortcut();
 				this.show(this.kSHOWN_BY_MOUSEMOVE);
@@ -1010,7 +1039,7 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 	{
 		if (!this.enabled) {
 			this.start(aReason | this.kSHOWHIDE_BY_API);
-			return;
+			return true;
 		}
 
 		if (aReason) {
@@ -1020,10 +1049,12 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 				this.showHideReason ^= aReason;
 
 			if (this.showHideReason & this.kSHOWN_BY_ANY_REASON)
-				return;
+				return false;
 		}
 		if (this.expanded)
 			this.showHideInternal(aReason);
+
+		return true;
 	},
  
 	onShowing : function AHB_onShowing() 
@@ -1177,6 +1208,7 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 			case 'extensions.treestyletab.tabbar.autoShow.mousemove':
 			case 'extensions.treestyletab.tabbar.autoShow.accelKeyDown':
 			case 'extensions.treestyletab.tabbar.autoShow.feedback':
+			case 'extensions.treestyletab.tabbar.autoShow.click':
 				if (this.enabled && this.shouldListenMouseMove)
 					this.startListenMouseMove();
 				else
@@ -1191,7 +1223,15 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 				this.togglerSize = value;
 				{
 					let toggler = this.toggler;
-					toggler.style.minWidth = toggler.style.minHeight = value+'px';
+					let style = toggler.style;
+					style.minWidth = style.minHeight = value+'px';
+					style.marginLeft = style.marginRight = style.marginTop = style.marginBottom = 0;
+					switch (this.treeStyleTab.position)
+					{
+						case 'left': style.marginRight = '-'+value+'px'; break;
+						case 'right': style.marginLeft = '-'+value+'px'; break;
+						default: style.marginTop = '-'+value+'px'; break;
+					}
 					if (this.togglerSize <= 0)
 						toggler.setAttribute('collapsed', true);
 					else
@@ -1356,8 +1396,21 @@ AutoHideBrowser.prototype = inherit(AutoHideBase.prototype, {
 				aEvent.originalTarget.ownerDocument != this.document ||
 				!sv.getTabBrowserFromChild(aEvent.originalTarget)
 			)
-			)
+			) {
 			this.hide(this.kHIDDEN_BY_CLICK);
+		}
+		else if (
+			utils.getTreePref('tabbar.autoShow.click') &&
+			this.enabled &&
+			!this.expanded &&
+			aEvent.originalTarget &&
+			(
+				sv.getTabBrowserFromChild(aEvent.originalTarget) ||
+				aEvent.originalTarget == this.toggler
+			)
+			) {
+			this.show(this.kSHOWN_BY_CLICK);
+		}
 		this.lastMouseDownTarget = (
 			aEvent.originalTargetLocalName ||
 			(aEvent.originalTarget && aEvent.originalTarget.localName) ||
diff --git a/modules/base.js b/modules/base.js
index 0f50f59..8ad6acb 100644
--- a/modules/base.js
+++ b/modules/base.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-2016
+ * Portions created by the Initial Developer are Copyright (C) 2010-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -79,10 +79,10 @@ else {
 }
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['base'].concat(aArgs));
+	utils.log('base', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['base'].concat(aArgs));
+	utils.logWithStackTrace('base', ...aArgs);
 }
  
 var TreeStyleTabBase = inherit(TreeStyleTabConstants, { 
@@ -98,7 +98,12 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 	smoothScrollEnabled  : true,
 	smoothScrollDuration : 150,
 
-	animationEnabled : true,
+	get animationEnabled() {
+		var enabled = prefs.getPref('toolkit.cosmeticAnimations.enabled');
+		if (enabled === null)
+			enabled = prefs.getPref('browser.tabs.animate'); // Firefox 54 and olders
+		return enabled;
+	},
 	indentDuration   : 200,
 	collapseDuration : 150,
 
@@ -138,7 +143,6 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 		this.onPrefChange('extensions.treestyletab.tabbar.scroll.smooth');
 		this.onPrefChange('extensions.treestyletab.tabbar.scroll.duration');
 		this.onPrefChange('extensions.treestyletab.tabbar.scrollToNewTab.mode');
-		this.onPrefChange('browser.tabs.animate');
 		this.onPrefChange('extensions.treestyletab.animation.indent.duration');
 		this.onPrefChange('extensions.treestyletab.animation.collapse.duration');
 		this.onPrefChange('extensions.treestyletab.twisty.expandSensitiveArea');
@@ -942,7 +946,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 	gatherSubtreeMemberTabs : function TSTBase_gatherSubtreeMemberTabs(aTabOrTabs, aOnlyChildren) 
 	{
 		var tabs = aTabOrTabs;
-		if (!(tabs instanceof Array)) {
+		if (!Array.isArray(tabs)) {
 			tabs = [aTabOrTabs];
 		}
 
@@ -1059,7 +1063,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 	{
 		var b = this.getTabBrowserFromChild(aTabBrowserChild || this.browser);
 		this.assertBeforeDestruction(b && b.mTabContainer);
-		return Array.slice(b.mTabContainer.querySelectorAll('tab'));
+		return [...b.mTabContainer.querySelectorAll('tab')];
 	},
  
 	/**
@@ -1070,7 +1074,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 	{
 		var b = this.getTabBrowserFromChild(aTabBrowserChild || this.browser);
 		this.assertBeforeDestruction(b && b.mTabContainer);
-		return Array.slice(b.mTabContainer.querySelectorAll('tab:not([hidden="true"])'));
+		return [...b.mTabContainer.querySelectorAll('tab:not([hidden="true"])')];
 	},
  
 	getAllTabsArray : function TSTBase_getAllTabsArray(aTabBrowserChild) /* for backward compatibility */ 
@@ -1226,7 +1230,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 		var b = this.getTabBrowserFromChild(aTabBrowserChild || this.browser);
 		if (!this.canCollapseSubtree(b))
 			return this.getTabs(b);
-		return Array.slice(b.mTabContainer.querySelectorAll('tab:not(['+this.kCOLLAPSED+'="true"]):not([hidden="true"])'));
+		return [...b.mTabContainer.querySelectorAll('tab:not(['+this.kCOLLAPSED+'="true"]):not([hidden="true"])')];
 	},
  
 	getVisibleTabsArray : function TSTBase_getVisibleTabsArray(aTabBrowserChild) /* for backward compatibility */ 
@@ -1425,7 +1429,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 			 */
 			return this.readyToOpenChildTab(parentTab, false, {
 				insertBefore : nextTab,
-				insertAfter  : tab
+				insertAfter  : this.getLastDescendantTab(tab) || tab
 			});
 		}
 		else {
@@ -1601,7 +1605,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
  
 	get rootTabs() /* PUBLIC API */ 
 	{
-		return Array.slice(this.browser.mTabContainer.querySelectorAll('tab:not(['+this.kNEST+']), tab['+this.kNEST+'=""], tab['+this.kNEST+'="0"]'));
+		return [...this.browser.mTabContainer.querySelectorAll('tab:not(['+this.kNEST+']), tab['+this.kNEST+'=""], tab['+this.kNEST+'="0"]')];
 	},
  
 	get allRootTabs() /* PUBLIC API */ 
@@ -1958,7 +1962,7 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
  
 	collectRootTabs : function TSTBase_collectRootTabs(aTabs) /* PUBLIC API */ 
 	{
-		aTabs = Array.slice(aTabs);
+		aTabs = [...aTabs];
 		return aTabs.filter(function(aTab) {
 			var parent = this.getParentTab(aTab);
 			return !parent || aTabs.indexOf(parent) < 0;
@@ -2229,7 +2233,6 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 	
 	domains : [ 
 		'extensions.treestyletab.',
-		'browser.tabs.animate',
 		'extensions.stm.tabBarMultiRows' // Super Tab Mode
 	],
  
@@ -2292,8 +2295,6 @@ var TreeStyleTabBase = inherit(TreeStyleTabConstants, {
 			case 'extensions.treestyletab.tabbar.scrollToNewTab.mode':
 				return this.scrollToNewTabMode = value;
 
-			case 'browser.tabs.animate':
-				return this.animationEnabled = value;
 			case 'extensions.treestyletab.animation.indent.duration':
 				return this.indentDuration = value;
 			case 'extensions.treestyletab.animation.collapse.duration':
diff --git a/modules/bookmark.js b/modules/bookmark.js
index 9af3cc3..6ea2890 100644
--- a/modules/bookmark.js
+++ b/modules/bookmark.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) 2016
+ * Portions created by the Initial Developer are Copyright (C) 2016-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -50,10 +50,10 @@ Cu.import('resource://treestyletab-modules/constants.js');
 XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['bookmark'].concat(aArgs));
+	utils.log('bookmark', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['bookmark'].concat(aArgs));
+	utils.logWithStackTrace('bookmark', ...aArgs);
 }
 
 var TreeStyleTabBookmarksService = inherit(TreeStyleTabConstants, {
@@ -189,7 +189,7 @@ var TreeStyleTabBookmarksService = inherit(TreeStyleTabConstants, {
 		}
 		this.endAddBookmarksFromTabs();
 	},
-	bookmarkTabSubTree : function() { return this.bookmarkTabSubtree.apply(this, arguments); }, // obsolete, for backward compatibility
+	bookmarkTabSubTree : function(...aArgs) { return this.bookmarkTabSubtree(...aArgs); }, // obsolete, for backward compatibility
 
 	getParentItem : function TSTBMService_getParentItem(aId) 
 	{
@@ -459,7 +459,7 @@ PlacesUIUtils._openTabset = function(aItemsToOpen, aEvent, aWindow, ...aArgs) {
 
 PlacesUtils.__treestyletab__getURLsForContainerNode = PlacesUtils.getURLsForContainerNode;
 PlacesUtils.getURLsForContainerNode = function(aNode, ...aArgs) {
-	var uris = this.__treestyletab__getURLsForContainerNode.apply(this, [aNode].concat(aArgs));
+	var uris = this.__treestyletab__getURLsForContainerNode(aNode, ...aArgs);
 	var nodes = TreeStyleTabBookmarksService.getItemIdsForContainerNode(aNode);
 	for (let i in nodes) {
 		uris[i].id = nodes[i];
@@ -471,7 +471,7 @@ PlacesUIUtils.__treestyletab__openContainerNodeInTabs = PlacesUIUtils.openContai
 PlacesUIUtils.openContainerNodeInTabs = function(aNode, ...aArgs) {
 	this.__treestyletab__folderName = aNode.title;
 	try {
-		return this.__treestyletab__openContainerNodeInTabs.apply(this, [aNode].concat(aArgs));
+		return this.__treestyletab__openContainerNodeInTabs(aNode, ...aArgs);
 	}
 	finally {
 		delete this.__treestyletab__folderName;
@@ -488,7 +488,7 @@ PlacesUIUtils.openURINodesInTabs = function(aNodes, ...aArgs) {
 				'openSelectedPlaces.history',
 			[aNodes[0].title, aNodes.length]
 		);
-		return this.__treestyletab__openURINodesInTabs.apply(this, [aNodes].concat(aArgs));
+		return this.__treestyletab__openURINodesInTabs(aNodes, ...aArgs);
 	}
 	finally {
 		delete this.__treestyletab__openTabset_rawNodes;
@@ -503,5 +503,5 @@ PlacesUIUtils.openNodeWithEvent = function(aNode, aEvent, aView, ...aArgs) {
 		window = PlacesUIUtils._getTopBrowserWin();
 	if (window && window.gBrowser)
 		window.gBrowser.treeStyleTab.readyToOpenOrphanTabNow();
-	return PlacesUIUtils.__treestyletab__openNodeWithEvent.apply(this, [aNode, aEvent, aView].concat(aArgs));
+	return PlacesUIUtils.__treestyletab__openNodeWithEvent(aNode, aEvent, aView, ...aArgs);
 };
diff --git a/modules/browser.js b/modules/browser.js
index 20438d3..8fc9b2a 100644
--- a/modules/browser.js
+++ b/modules/browser.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) 2011-2016
+ * Portions created by the Initial Developer are Copyright (C) 2011-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -89,10 +89,10 @@ function wait(aMilliSeconds) {
 }
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['browser'].concat(aArgs));
+	utils.log('browser', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['browser'].concat(aArgs));
+	utils.logWithStackTrace('browser', ...aArgs);
 }
 
 Cu.import('resource://treestyletab-modules/window.js');
@@ -163,6 +163,33 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	maxTreeLevelPhysical : false,
 
 	needRestoreTree : false,
+
+	// Descriptors to cache "last owner" information for tabs.
+	// See the definition of TreeStyleTabBrowser.prototype.onTabOpen()
+	tabbrowserLastRelateTabHookDescriptor : {
+		get : function() {
+			return this.__treestyletab__lastRelateTab;
+		},
+		set : function(aNewRelateTab) {
+			if (aNewRelateTab)
+				aNewRelateTab.__treestyletab__lastOwner = this.selectedTab.getAttribute(TreeStyleTabBrowser.prototype.kID);
+			return this.__treestyletab__lastRelateTab = aNewRelateTab;
+		},
+		enumerable : true,
+		configurable : true
+	},
+	tabOwnerHookDescriptor : {
+		get : function() {
+			return this.__treestyletab__owner;
+		},
+		set : function(aNewOwner) {
+			if (aNewOwner)
+				this.__treestyletab__lastOwner = aNewOwner.getAttribute(TreeStyleTabBrowser.prototype.kID);
+			return this.__treestyletab__owner = aNewOwner;
+		},
+		enumerable : true,
+		configurable : true
+	},
  
 /* elements */ 
 	
@@ -210,6 +237,13 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 				d.getAnonymousElementByAttribute(this.mTabBrowser, 'id', 'tabkit-splitter'); // Tab Kit
 	},
  
+	get toggler() 
+	{
+		var d = this.document;
+		var b = this.mTabBrowser;
+		return d.getAnonymousElementByAttribute(b, 'class', this.kTABBAR_TOGGLER);
+	},
+ 
 	get tabStripPlaceHolder() 
 	{
 		return this._tabStripPlaceHolder;
@@ -218,6 +252,28 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	{
 		return (this._tabStripPlaceHolder = value);
 	},
+
+	get notificationBoxContainers()
+	{
+		var d = this.document;
+		return [
+			this.browser,
+			d.getElementById('global-notificationbox'),
+			d.getElementById('high-priority-global-notificationbox')
+		].map(function(aNode) {
+			if (aNode) {
+				return {
+					node : aNode,
+					id   : 'notificationBoxContainers(#' + aNode.id + ')'
+				};
+			}
+			else {
+				return null;
+			}
+		}).filter(function(aItem) {
+			return aItem;
+		});
+	},
   
 /* properties */ 
 	
@@ -487,11 +543,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	getTabLabel : function TSTBrowser_getTabLabel(aTab) 
 	{
 		var d = this.document;
-		var label = d.getAnonymousElementByAttribute(aTab, 'class', 'tab-text-stack') || // Mac OS X
-					( // Tab Mix Plus
-						utils.getTreePref('compatibility.TMP') &&
-						d.getAnonymousElementByAttribute(aTab, 'class', 'tab-text-container')
-					) ||
+		var label = d.getAnonymousElementByAttribute(aTab, 'class', 'tab-label-container') || // Firefox 53 and later (and Tab Mix Plus)
+					d.getAnonymousElementByAttribute(aTab, 'class', 'tab-text-stack') || // Mac OS X
 					d.getAnonymousElementByAttribute(aTab, 'class', 'tab-text tab-label');
 		return label;
 	},
@@ -591,7 +644,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		if (!this.windowService.preInitialized || !aTab)
 			return false;
 
-		if (aTab.getAttribute('pinned') == 'true')
+		if (aTab.pinned)
 			return true;
 
 		var tabBox = this.getFutureBoxObject(aTab);
@@ -629,6 +682,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
  
 	positionPinnedTabs : function TSTBrowser_positionPinnedTabs(aWidth, aHeight, aJustNow) 
 	{
+		log('TSTBrowser:positionPinnedTabs');
 		var b = this.mTabBrowser;
 		var tabbar = b.tabContainer;
 		if (
@@ -696,6 +750,13 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			style.setProperty('margin-top', (- height * (maxRow - row))+'px', 'important');
 			style.top = style.bottom = '';
 
+			log('  tab ' + item._tPos, {
+				col : col,
+				width : width,
+				height : height,
+				shrunkenOffset : shrunkenOffset
+			});
+
 			if (aJustNow) {
 				let key = 'positionPinnedTabs_tab_'+parseInt(Math.random() * 65000);
 				// "transition" must be cleared after the reflow.
@@ -714,6 +775,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			if (col >= maxCol) {
 				col = 0;
 				row++;
+				log('  new row');
 			}
 		}
 	},
@@ -821,6 +883,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		 * before DOMContentLoad, on "domwindowopened".
 		 */
 		this.needRestoreTree = w.__treestyletab__WindowStateBusy || false;
+		this.isWindowBusy = w.__treestyletab__WindowStateBusy || false;
 		delete w.__treestyletab__WindowStateBusy;
 
 		this._initTabbrowserExtraContents();
@@ -832,6 +895,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		this.setTabbrowserAttribute(this.kFIXED+'-vertical', utils.getTreePref('tabbar.fixed.vertical') ? 'true' : null, b);
 		this.setTabStripAttribute(this.kTAB_STRIP_ELEMENT, true);
 
+		Object.defineProperty(b, '_lastRelatedTab', this.tabbrowserLastRelateTabHookDescriptor);
+
 		/**
 		 * <tabbrowser> has its custom background color for itself, but it
 		 * prevents to make transparent background of the vertical tab bar.
@@ -875,6 +940,18 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		ReferenceCounter.add('w,kEVENT_TYPE_TAB_FOCUS_SWITCHING_END,TSTBrowser,false');
 		w.addEventListener('SSWindowStateBusy', this, false);
 		ReferenceCounter.add('w,SSWindowStateBusy,TSTBrowser,false');
+		w.addEventListener('SSWindowStateReady', this, false);
+		ReferenceCounter.add('w,SSWindowStateReady,TSTBrowser,false');
+
+		for (let container of this.notificationBoxContainers)
+		{
+			container.node.addEventListener('transitionend', this, false);
+			ReferenceCounter.add(container.id + ',transitionend,TSTBrowser,false');
+			container.node.addEventListener('transitioncancel', this, false);
+			ReferenceCounter.add(container.id + ',transitioncancel,TSTBrowser,false');
+			container.node.addEventListener('transitionrun', this, false);
+			ReferenceCounter.add(container.id + ',transitionrun,TSTBrowser,false');
+		}
 
 		b.addEventListener('DOMAudioPlaybackStarted', this, false);
 		ReferenceCounter.add('b,DOMAudioPlaybackStarted,TSTBrowser,false');
@@ -911,6 +988,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		this.onPrefChange('extensions.treestyletab.tabbar.autoShow.mousemove');
 		this.onPrefChange('extensions.treestyletab.tabbar.invertScrollbar');
 		this.onPrefChange('extensions.treestyletab.tabbar.narrowScrollbar');
+		this.onPrefChange('toolkit.cosmeticAnimations.enabled');
 		this.onPrefChange('browser.tabs.animate');
 
 		Services.obs.addObserver(this, this.kTOPIC_INDENT_MODIFIED, false);
@@ -935,7 +1013,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		var d = this.document;
 		var b = this.mTabBrowser;
 
-		var toggler = d.getAnonymousElementByAttribute(b, 'class', this.kTABBAR_TOGGLER);
+		var toggler = this.toggler;
 		if (!toggler) {
 			toggler = d.createElement('spacer');
 			toggler.setAttribute(this.kTAB_STRIP_ELEMENT, true);
@@ -1125,7 +1203,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		aTab.__treestyletab__internallyTabMovingCount = 0;
 
 		if (utils.isTabNotRestoredYet(aTab))
-			aTab.linkedBrowser.__treestyletab__toBeRestored = true;
+			aTab.__treestyletab__toBeRestored = true;
 
 		this.initTabAttributes(aTab);
 		this.initTabContents(aTab);
@@ -1290,7 +1368,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		if (this.window.getComputedStyle(aContainer, '').getPropertyValue('-moz-box-orient') == 'vertical')
 			return;
 
-		var nodes = Array.slice(this.document.getAnonymousNodes(aContainer) || aContainer.childNodes);
+		var nodes = [...(this.document.getAnonymousNodes(aContainer) || aContainer.childNodes)];
 
 		// reset order at first!
 		for (let i = 0, maxi = nodes.length; i < maxi; i++)
@@ -1395,7 +1473,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 						(aTarget instanceof this.window.Element) ?
 							[aTarget] :
 						(typeof aTarget == 'object' && 'length' in aTarget) ?
-							Array.slice(aTarget) :
+							[...aTarget] :
 							this.getAllTabs(b);
 				for (let i = 0, maxi = tabs.length; i < maxi; i++)
 				{
@@ -1439,7 +1517,6 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		var strip = this.tabStrip;
 		var placeHolder = this.tabStripPlaceHolder || strip;
 		var splitter = this._ensureNewSplitter();
-		var toggler = d.getAnonymousElementByAttribute(b, 'class', this.kTABBAR_TOGGLER);
 
 		// Tab Mix Plus
 		var scrollFrame, newTabBox, tabBarMode;
@@ -1483,7 +1560,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			b.mTabBox.orient = splitter.orient = 'horizontal';
 			strip.orient =
 				placeHolder.orient =
-				toggler.orient =
+				this.toggler.orient =
 				b.mTabContainer.orient =
 				b.mTabContainer.mTabstrip.orient =
 				b.mTabContainer.mTabstrip.parentNode.orient = 'vertical';
@@ -1574,7 +1651,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			b.mTabBox.orient = splitter.orient = 'vertical';
 			strip.orient =
 				placeHolder.orient =
-				toggler.orient =
+				this.toggler.orient =
 				b.mTabContainer.orient =
 				b.mTabContainer.mTabstrip.orient =
 				b.mTabContainer.mTabstrip.parentNode.orient = 'horizontal';
@@ -1671,7 +1748,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		this.timers['initTabbar'] = setTimeout((function() {
 			try {
-				delayedPostProcess(this, b, splitter, toggler);
+				delayedPostProcess(this, b, splitter, this.toggler);
 				this.updateTabbarOverflow();
 				this.updateAllTabsButton(b);
 				this.updateAllTabsAsParent();
@@ -2443,6 +2520,18 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		ReferenceCounter.remove('w,kEVENT_TYPE_TAB_FOCUS_SWITCHING_END,TSTBrowser,false');
 		w.removeEventListener('SSWindowStateBusy', this, false);
 		ReferenceCounter.remove('w,SSWindowStateBusy,TSTBrowser,false');
+		w.removeEventListener('SSWindowStateReady', this, false);
+		ReferenceCounter.remove('w,SSWindowStateReady,TSTBrowser,false');
+
+		for (let container of this.notificationBoxContainers)
+		{
+			container.node.removeEventListener('transitionend', this, false);
+			ReferenceCounter.remove(container.id + ',transitionend,TSTBrowser,false');
+			container.node.removeEventListener('transitioncancel', this, false);
+			ReferenceCounter.remove(container.id + ',transitioncancel,TSTBrowser,false');
+			container.node.removeEventListener('transitionrun', this, false);
+			ReferenceCounter.remove(container.id + ',transitionrun,TSTBrowser,false');
+		}
 
 		b.removeEventListener('DOMAudioPlaybackStarted', this, false);
 		ReferenceCounter.remove('b,DOMAudioPlaybackStarted,TSTBrowser,false');
@@ -2632,7 +2721,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	{
 		this.ownerToolbar.classList.add(this.kTABBAR_TOOLBAR);
 		this.ownerToolbar.classList.remove(this.kTABBAR_TOOLBAR_READY);
-		Array.slice(this.document.querySelectorAll('.'+this.kTABBAR_TOOLBAR_READY_POPUP))
+		[...this.document.querySelectorAll('.'+this.kTABBAR_TOOLBAR_READY_POPUP)]
 			.forEach(this.safeRemovePopup, this);
 
 		var position = this._lastTabbarPositionBeforeDestroyed || this.position;
@@ -2707,7 +2796,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		'extensions.treestyletab.',
 		'browser.tabs.closeButtons',
 		'browser.tabs.closeWindowWithLastTab',
-		'browser.tabs.animate'
+		'toolkit.cosmeticAnimations.enabled',
+		'browser.tabs.animate' // Firefox 54 and olders
 	],
  
 	observe : function TSTBrowser_observe(aSubject, aTopic, aData) 
@@ -2842,10 +2932,12 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 				return;
 
 			case 'extensions.treestyletab.tabbar.autoShow.mousemove':
+			case 'extensions.treestyletab.tabbar.autoShow.click':
 				{
-					let toggler = this.document.getAnonymousElementByAttribute(b, 'class', this.kTABBAR_TOGGLER);
+					let toggler = this.toggler;
 					if (toggler) {
-						if (value)
+						if (utils.getTreePref('tabbar.autoShow.mousemove') ||
+							utils.getTreePref('tabbar.autoShow.click'))
 							toggler.removeAttribute('hidden');
 						else
 							toggler.setAttribute('hidden', true);
@@ -2872,11 +2964,10 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 					this.promoteTooDeepLevelTabs();
 				return;
 
+			case 'toolkit.cosmeticAnimations.enabled':
 			case 'browser.tabs.animate':
 				this.setTabbrowserAttribute(this.kANIMATION_ENABLED,
-					prefs.getPref('browser.tabs.animate') !== false
-						? 'true' : null
-				);
+					this.animationEnabled ? 'true' : null);
 				return;
 
 			case 'browser.tabs.closeButtons':
@@ -3150,7 +3241,12 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 
 			case 'SSWindowStateBusy':
-				return this.needRestoreTree = true;
+				this.isWindowBusy = true;
+				this.needRestoreTree = true;
+				return;
+			case 'SSWindowStateReady':
+				this.isWindowBusy = false;
+				return;
 
 
 			case 'DOMAudioPlaybackStarted':
@@ -3173,6 +3269,13 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 				}
 				return;
 
+			case 'transitionend':
+			case 'transitioncancel':
+			case 'transitionrun':
+				if (aEvent.originalTarget.localName == 'notification')
+					this.updateFloatingTabbar(this.kTABBAR_UPDATE_BY_WINDOW_RESIZE);
+				return;
+
 
 			case 'nsDOMMultipleTabHandlerTabsClosing':
 				if (!this.onTabsClosing(aEvent))
@@ -3260,7 +3363,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		var pareintIndexInTree = hasStructure ? this.treeStructure.shift() : 0 ;
 		var lastRelatedTab = b._lastRelatedTab;
 
-		log('onTabOpen\n  ' + [
+		log('onTabOpen at ' + tab._tPos + '\n  ' + [
 		  'readiedToAttachNewTab: '+this.readiedToAttachNewTab,
 		  'parentTab: '+this.parentTab + ' (' + this.getTabById(this.parentTab) + ')',
 		  'insertBefore: '+this.insertBefore,
@@ -3270,13 +3373,21 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		if (utils.getTreePref('autoAttach') &&
 			typeof this.readiedToAttachNewTab !== 'boolean') {
+			// The "owner" may be updated after TabOpen multiple times.
+			// We need to hook tab.owner to get last available owner.
+			if (tab.owner)
+				tab.__treestyletab__lastOwner = tab.owner.getAttribute(this.kID);
+			if (!('__treestyletab__owner' in tab))
+				Object.defineProperty(tab, 'owner', this.tabOwnerHookDescriptor);
 			this.window.setTimeout((function() {
-				if (!tab.owner || tab != b._lastRelatedTab)
+				var owner = this.getTabById(tab.__treestyletab__lastOwner);
+				delete tab.__treestyletab__lastOwner; // it is not needed anymore!
+				if (!owner)
 					return;
 				log('onTabOpen: new child tab opened by browser.tabs.insertRelatedAfterCurrent=true');
-				var nextTab = this.findNextTabForNewChild(tab, tab.owner);
+				var nextTab = this.findNextTabForNewChild(tab, owner);
 				log('  next tab: '+(nextTab && nextTab._tPos));
-				this.attachTabTo(tab, tab.owner, {
+				this.attachTabTo(tab, owner, {
 					insertBefore: nextTab
 				});
 			}).bind(this), 0);
@@ -3294,7 +3405,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			}
 			if (parent) {
 				this.attachTabTo(tab, parent, {
-					dontExpand : this.shouldExpandAllTree
+					dontExpand : this.shouldExpandAllTree,
+					dontMove   : utils.getTreePref('insertNewChildAt') == this.kINSERT_NO_CONTROL
 				});
 			}
 
@@ -3326,7 +3438,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 				if (refTab = this.getFirstChildTab(parent))
 					this.insertBefore = refTab.getAttribute(this.kID);
 			}
-			else {
+			else if (utils.getTreePref('insertNewChildAt') == this.kINSERT_LAST) {
 				refTab = this.findNextTabForNewChild(tab, parent);
 				if (refTab)
 					nextIndex = refTab._tPos;
@@ -3557,7 +3669,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		this.destroyTab(tab);
 
-		if (tab.getAttribute('pinned') == 'true')
+		if (tab.pinned)
 			this.positionPinnedTabsWithDelay();
 
 		if (this.canStackTabs)
@@ -3724,11 +3836,16 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	{
 		var tab = aEvent.originalTarget;
 		var b   = this.mTabBrowser;
+		if (this.isWindowBusy) {
+			log('onTabMove: do nothing because now we are restoring a window');
+			return;
+		}
 
 		var prevPosition = aEvent.detail;
+		var positionControlled = utils.getTreePref('insertNewChildAt') != this.kINSERT_NO_CONTROL;
 		if (tab.__treestyletab__isOpening &&
 			!this.isTabInternallyMoving(tab) &&
-			utils.getTreePref('controlNewTabPosition')) {
+			positionControlled) {
 			log('onTabMove for new child tab: move back '+tab._tPos+' => '+prevPosition);
 			tab.__treestyletab__internallyTabMovingCount++;
 			b.moveTabTo(tab, prevPosition);
@@ -3827,7 +3944,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			)
 			return;
 
-		if (!restored)
+		if (!restored &&
+			!positionControlled &&
+			!this.isTabInternallyMoving(tab))
 			this.attachTabFromPosition(tab, aEvent.detail);
 
 		this.rearrangeTabViewItems(tab);
@@ -3837,6 +3956,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	{
 		log('attachTabFromPosition '+aOldPosition+' => '+aTab._tPos);
 		var parent = this.getParentTab(aTab);
+		log('  parent: '+(parent&&(parent._tPos+'('+parent.linkedBrowser.currentURI.spec+')') || 'null'));
 
 		if (aOldPosition === void(0))
 			aOldPosition = aTab._tPos;
@@ -3878,12 +3998,18 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		var newParent;
 
-		if (!prevTab) {
+		if (parent &&
+			prevTab &&
+			[prevTab].concat(this.getAncestorTabs(prevTab)).indexOf(parent) > -1) {
+			log(' => no need to fix case');
+			newParent = parent;
+		}
+		else if (!prevTab) {
 			log(' => moved to topmost position');
 			newParent = null;
 		}
 		else if (!nextTab) {
-			log(' => movedmoved to last position');
+			log(' => moved to last position');
 			newParent = (delta > 1) ? prevParent : parent ;
 		}
 		else if (prevParent == nextParent) {
@@ -4039,7 +4165,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		var allTabs = this.getAllTabs(this.mTabBrowser);
 		var normalTabs = allTabs.filter(function(aTab) {
-							return !aTab.hasAttribute('pinned');
+							return !aTab.pinned;
 						});
 		aChangedTabs = aChangedTabs || normalTabs;
 
@@ -4151,8 +4277,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	onRestoreTabContentStarted : function TSTBrowser_onRestoreTabContentStarted(aTab)
 	{
 		// don't override "false" value (means "already restored")!
-		if (typeof aTab.linkedBrowser.__treestyletab__toBeRestored == 'undefined')
-			aTab.linkedBrowser.__treestyletab__toBeRestored = true;
+		if (typeof aTab.__treestyletab__toBeRestored == 'undefined')
+			aTab.__treestyletab__toBeRestored = true;
 	},
  
 	onTabRestoring : function TSTBrowser_onTabRestoring(aEvent) 
@@ -4162,7 +4288,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		var tab = aEvent.originalTarget;
 		log('onTabRestoring ', tab._tPos);
 
-		tab.linkedBrowser.__treestyletab__toBeRestored = false;
+		tab.__treestyletab__toBeRestored = false;
 		var restored = this.handleRestoredTab(tab);
 
 		/**
@@ -4761,7 +4887,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	
 	doRestoreClosedSet : function TSTBrowser_doRestoreClosedSet(aRestoredTab, aIndexes) 
 	{
-		if (!this.window.PlacesUIUtils._confirmOpenInTabs(aIndexes.length))
+		if (!this.window.PlacesUIUtils.confirmOpenInTabs(aIndexes.length, this.window))
 			return;
 
 		this._restoringClosedSet = true;
@@ -4791,6 +4917,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			dontUpdateCount : true
 		});
 		delete tab.__treestyletab__restoredByUndoCloseTab;
+		this.updateFloatingTabbar(this.kTABBAR_UPDATE_BY_RESET);
 	},
  
 	onTabPinned : function TSTBrowser_onTabPinned(aTab) 
@@ -5166,7 +5293,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		var color;
 		var userContextId = aTab.getAttribute('usercontextid');
 		if (userContextId) {
-			let identity = ContextualIdentityService.getIdentityFromId(userContextId);
+			let identity = ContextualIdentityService.getPublicIdentityFromId ?
+							ContextualIdentityService.getPublicIdentityFromId(userContextId) : // Firefox 54 and later
+							ContextualIdentityService.getIdentityFromId(userContextId) ; // Firefox 53 or older
 			color = identity ? identity.color : null ;
 		}
 		if (color) {
@@ -5262,10 +5391,14 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
  
 	onTabbarOverflow : function TSTBrowser_onTabbarOverflow(aEvent) 
 	{
+		if (this.getTabFromEvent(aEvent))
+			return;
+
 		var tabs = this.mTabBrowser.mTabContainer;
 		var horizontal = tabs.orient == 'horizontal';
 		if (horizontal)
 			return;
+
 		aEvent.stopPropagation();
 		this.positionPinnedTabsWithDelay();
 		if (aEvent.detail == 1) {
@@ -5664,8 +5797,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			!aParent ||
 			aChild == aParent ||
 			(currentParent = this.getParentTab(aChild)) == aParent ||
-			aChild.getAttribute('pinned') == 'true' ||
-			aParent.getAttribute('pinned') == 'true'
+			aChild.pinned ||
+			aParent.pinned
 			) {
 			log('attachTabTo: already attached');
 			this.fireAttachedEvent(aChild, aParent);
@@ -6080,7 +6213,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		this.stopTabIndentAnimation(aTab);
 
-		if (aTab.hasAttribute('pinned'))
+		if (aTab.pinned)
 			return;
 
 		if (!this.enableSubtreeIndent)
@@ -6187,12 +6320,12 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 		if (!tabbarSize) // don't update indent for collapsed tab bar
 			return;
 
-		var tabs = Array.slice(b.mTabContainer.querySelectorAll(
+		var tabs = [...b.mTabContainer.querySelectorAll(
 				'tab['+this.kNEST+']:not(['+this.kNEST+'="0"]):not(['+this.kNEST+'=""])'+
 					':not(['+this.kCOLLAPSED+'="true"])'+
 					':not([hidden="true"])'+
 					':not([collapsed="true"])'
-			));
+			)];
 		if (!tabs.length)
 			return;
 
@@ -6754,6 +6887,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	},
 	updateTabCollapsed : function TSTBrowser_updateTabCollapsed(aTab, aCollapsed, aJustNow, aCallbackToRunOnStartAnimation)
 	{
+		log('TSTBrowser::updateTabCollapsed for ' + aTab._tPos);
 		if (!aTab.parentNode) // do nothing for closed tab!
 			return;
 
@@ -6807,6 +6941,12 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 				startMargin = this.kSTACKED_TAB_MARGIN;
 			}
 		}
+		log('  animation params: ', {
+			startMargin  : startMargin,
+			endMargin    : endMargin,
+			startOpacity : startOpacity,
+			endOpacity   : endOpacity
+		});
 
 		if (
 			!this.animationEnabled ||
@@ -6815,6 +6955,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 //			!this.isVertical ||
 //			!this.canCollapseSubtree(this.getParentTab(aTab))
 			) {
+			log(' => skip animation');
 			if (aCollapsed)
 				aTab.setAttribute(this.kCOLLAPSED_DONE, true);
 			else
@@ -6824,9 +6965,15 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			// Pinned tabs are positioned by "margin-top", so
 			// we must not reset the property for pinned tabs.
 			// (However, we still must update "opacity".)
-			let pinned = aTab.getAttribute('pinned') == 'true';
+			let pinned = aTab.pinned;
 			let canExpand = !pinned || this.collapseCSSProp != 'margin-top';
 
+			log(' skipped animation params: ', {
+				pinned    : pinned,
+				canExpand : canExpand,
+				endMargin : endMargin
+			});
+
 			if (canExpand)
 				aTab.style.setProperty(this.collapseCSSProp, endMargin ? '-'+endMargin+'px' : '', 'important');
 
@@ -6880,6 +7027,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 				}
 			}
 			if (aTime >= aDuration || stopAnimation) {
+				log(' => finish animation for '+aTab._tPos);
 				delete aTab.__treestyletab__updateTabCollapsedTask;
 				if (aCollapsed)
 					aTab.setAttribute(self.kCOLLAPSED_DONE, true);
@@ -7007,6 +7155,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	
 	scrollTo : function TSTBrowser_scrollTo(aEndX, aEndY, aTargetElement) 
 	{
+		log('scrollTo ' + aEndX + ', ' + aEndY);
 		if (this.timers['cancelPerformingAutoScroll'])
 			return;
 
@@ -7025,6 +7174,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 	
 	smoothScrollTo : function TSTBrowser_smoothScrollTo(aEndX, aEndY, aDuration, aTargetElement) 
 	{
+		log('smoothScrollTo ' + aEndX + ', ' + aEndY);
 		this.cancelPerformingAutoScroll(true);
 
 		var b = this.mTabBrowser;
@@ -7038,11 +7188,22 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 
 		// Use Firefox's native smooth scroll if possible
 		// because it can be accelerated.
-		if (typeof this.scrollBox._smoothScrollByPixels == 'function') {
+		if (
+			typeof this.scrollBox._smoothScrollByPixels == 'function' &&
+			( // We need to use it only when the tab is completely expanded...
+				!aTargetElement ||
+				(
+					!this.getXOffsetOfTab(aTargetElement) &&
+					!this.getYOffsetOfTab(aTargetElement)
+				)
+			)
+			) {
+			log('  => native smooth scroll');
 			let amountToScroll = this.isVertical ? deltaY : deltaX ;
 			return this.scrollBox._smoothScrollByPixels(amountToScroll, aTargetElement);
 		}
 		// Otherwise fallback to TST's custom one.
+		log('  => TST\'s smooth scroll');
 
 		var arrowscrollbox = scrollBoxObject.element.parentNode;
 		if (
@@ -7149,13 +7310,18 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
   
 	scrollToTab : function TSTBrowser_scrollToTab(aTab, aOnlyWhenCurrentTabIsInViewport) 
 	{
-		if (!this.canScrollToTab(aTab))
+		log('scrollToTab to ' + (aTab && aTab._tPos));
+		if (!this.canScrollToTab(aTab)) {
+			log('  => unscrollable');
 			return;
+		}
 
 		this.cancelPerformingAutoScroll(true);
 
-		if (this.isTabInViewport(aTab))
+		if (this.isTabInViewport(aTab)) {
+			log('  => already visible');
 			return;
+		}
 
 		var b = this.mTabBrowser;
 
@@ -7356,16 +7522,23 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
 			// If the previous state is "undetermined" ("undefined")
 			// and now it has became certain, then we should save the state
 			// for now and the next time..
-			if (typeof aTab.linkedBrowser.__treestyletab__toBeRestored == 'undefined' &&
+			if (typeof aTab.__treestyletab__toBeRestored == 'undefined' &&
 				utils.isTabNotRestoredYet(aTab))
-				aTab.linkedBrowser.__treestyletab__toBeRestored = true;
+				aTab.__treestyletab__toBeRestored = true;
 			return (
-				aTab.linkedBrowser.__treestyletab__toBeRestored &&
+				aTab.__treestyletab__toBeRestored &&
 				(!onlyVisible || !aTab.hidden)
 			);
 		});
 
-		log('  restoring member tabs = '+tabs.length+' ('+tabs.map(function(aTab) { return aTab._tPos; })+')');
+		log('  restoring member tabs = '+tabs.length,
+			tabs.map(function(aTab) {
+				return {
+					pos    : aTab._tPos,
+					pinned : aTab.pinned
+				};
+			})
+		);
 
 		if (tabs.length <= 1)
 			return;
diff --git a/modules/browserUIShowHideObserver.js b/modules/browserUIShowHideObserver.js
index 9932f82..29c6e3d 100644
--- a/modules/browserUIShowHideObserver.js
+++ b/modules/browserUIShowHideObserver.js
@@ -43,10 +43,10 @@ Components.utils.import('resource://treestyletab-modules/constants.js');
 XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['browserUIShowHideObserver'].concat(aArgs));
+	utils.log('browserUIShowHideObserver', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['browserUIShowHideObserver'].concat(aArgs));
+	utils.logWithStackTrace('browserUIShowHideObserver', ...aArgs);
 }
 
 function BrowserUIShowHideObserver(aOwner, aBox, aOptions) {
diff --git a/modules/constants.js b/modules/constants.js
index 3b8945e..915e17b 100644
--- a/modules/constants.js
+++ b/modules/constants.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-2016
+ * Portions created by the Initial Developer are Copyright (C) 2010-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -95,6 +95,7 @@ var TreeStyleTabConstants = Object.freeze({
 
 	kDROP_POSITION      : 'treestyletab-drop-position',
 	kDRAG_TYPE_TABBAR   : 'application/x-moz-treestyletab-tabbrowser-tabbar',
+	kDRAG_TYPE_TABBAR_NODE : 'application/x-moz-treestyletab-tabbrowser-tabbar-node',
 	kDROP_POSITION_UNKNOWN : 'unknown',
 	kTABBAR_MOVE_FORCE  : 'force',
 	kTABBAR_MOVE_NORMAL : 'normal',
@@ -117,6 +118,7 @@ var TreeStyleTabConstants = Object.freeze({
 	kTABBAR_TOOLBAR             : 'treestyletab-tabbar-toolbar',
 	kTABBAR_TOOLBAR_READY       : 'treestyletab-tabbar-toolbar-ready',
 	kTABBAR_TOOLBAR_READY_POPUP : 'treestyletab-tabbar-toolbar-ready-popup',
+	kTABBAR_DROP_AREA           : 'treestyletab-tabbar-drop-area',
 
 /* event types, topics */
 	kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN : 'nsDOMTreeStyleTabFocusSwitchingKeyDown',
@@ -176,6 +178,7 @@ var TreeStyleTabConstants = Object.freeze({
 	kTABBAR_REGULAR    : (1 << 0) | (1 << 2),
 	kTABBAR_INVERTED   : (1 << 3) | (1 << 4),
 
+	kINSERT_NO_CONTROL : -1,
 	kINSERT_FISRT : 0,
 	kINSERT_LAST  : 1,
 
diff --git a/modules/contentBridge.js b/modules/contentBridge.js
index 1b63305..fa5d8c3 100644
--- a/modules/contentBridge.js
+++ b/modules/contentBridge.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) 2014-2016
+ * Portions created by the Initial Developer are Copyright (C) 2014-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -47,10 +47,10 @@ Cu.import('resource://gre/modules/Promise.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['contentBridge'].concat(aArgs));
+	utils.log('contentBridge', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['contentBridge'].concat(aArgs));
+	utils.logWithStackTrace('contentBridge', ...aArgs);
 }
 
 function ContentBridge(aTab, aTabBrowser) 
@@ -81,10 +81,13 @@ ContentBridge.prototype = inherit(TreeStyleTabConstants, {
 		this.mTabBrowser = aTabBrowser;
 		this.handleMessage = this.handleMessage.bind(this);
 		this.checkPluginAreaExistenceResolvers = {};
+		this.commandQueue = [];
 
 		var manager = this.mTab.ownerDocument.defaultView.messageManager;
 		manager.addMessageListener(this.MESSAGE_TYPE, this.handleMessage);
 		manager.addMessageListener('Browser:WindowCreated', this.handleMessage);
+
+		this.mTab.addEventListener('TabBrowserInserted', this, false);
 	},
 	destroy : function CB_destroy()
 	{
@@ -92,17 +95,32 @@ ContentBridge.prototype = inherit(TreeStyleTabConstants, {
 		manager.removeMessageListener(this.MESSAGE_TYPE, this.handleMessage);
 		manager.removeMessageListener('Browser:WindowCreated', this.handleMessage);
 
+		this.mTab.removeEventListener('TabBrowserInserted', this, false);
+
 		delete this.mTab;
 		delete this.mTabBrowser;
 		delete this.checkPluginAreaExistenceResolvers;
 	},
 	sendAsyncCommand : function CB_sendAsyncCommand(aCommandType, aCommandParams)
 	{
-		var manager = this.mTab.linkedBrowser.messageManager;
-		manager.sendAsyncMessage(this.MESSAGE_TYPE, {
-			command : aCommandType,
-			params  : aCommandParams || {}
+		this.commandQueue.push({
+			type   : aCommandType,
+			params : aCommandParams
 		});
+		if (this.mTab.linkedPanel) // already  initialized
+			this.processQueuedAsyncCommands();
+	},
+	processQueuedAsyncCommands : function CB_processQueuedAsyncCommands()
+	{
+		var manager = this.mTab.linkedBrowser.messageManager;
+		for (let command of this.commandQueue)
+		{
+			manager.sendAsyncMessage(this.MESSAGE_TYPE, {
+				command : command.type,
+				params  : command.params || {}
+			});
+		}
+		this.commandQueue = [];
 	},
 	checkPluginAreaExistence : function CB_checkPluginAreaExistence()
 	{
@@ -191,6 +209,15 @@ ContentBridge.prototype = inherit(TreeStyleTabConstants, {
 			aCoordinates.screenY = fixedCoordinates.y;
 		}
 		return aCoordinates;
+	},
+
+	handleEvent : function CB_handleEvent(aEvent)
+	{
+		switch (aEvent.type)
+		{
+			case 'TabBrowserInserted':
+				return this.processQueuedAsyncCommands();
+		}
 	}
 }, Object); 
  
diff --git a/modules/fullTooltip.js b/modules/fullTooltip.js
index 0fe7fe9..46ada2e 100644
--- a/modules/fullTooltip.js
+++ b/modules/fullTooltip.js
@@ -51,10 +51,10 @@ XPCOMUtils.defineLazyServiceGetter(this, 'ScreenManager',
   '@mozilla.org/gfx/screenmanager;1', 'nsIScreenManager');
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['fullTooltip'].concat(aArgs));
+	utils.log('fullTooltip', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['fullTooltip'].concat(aArgs));
+	utils.logWithStackTrace('fullTooltip', ...aArgs);
 }
 
 function FullTooltipManager(aOwner)
diff --git a/modules/fullscreenObserver.js b/modules/fullscreenObserver.js
index 54210dc..df1b26f 100644
--- a/modules/fullscreenObserver.js
+++ b/modules/fullscreenObserver.js
@@ -40,10 +40,10 @@ Components.utils.import('resource://treestyletab-modules/constants.js');
 Components.utils.import('resource://treestyletab-modules/utils.js');
 
 function log(...aArgs) {
-	TreeStyleTabUtils.log.apply(TreeStyleTabUtils, ['fullscreenObserver'].concat(aArgs));
+	TreeStyleTabUtils.log('fullscreenObserver', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	TreeStyleTabUtils.logWithStackTrace.apply(TreeStyleTabUtils, ['fullscreenObserver'].concat(aArgs));
+	TreeStyleTabUtils.logWithStackTrace('fullscreenObserver', ...aArgs);
 }
 
 function FullscreenObserver(aWindow) {
diff --git a/modules/lib/visuallyselectedTabs.jsm b/modules/lib/visuallyselectedTabs.jsm
index c636fc2..3ea5d5a 100644
--- a/modules/lib/visuallyselectedTabs.jsm
+++ b/modules/lib/visuallyselectedTabs.jsm
@@ -1,67 +1,70 @@
-/*
- Backporting "visuallyselected" for Firefox 31-40
-
- See also:
-   http://www.hackermusings.com/2015/06/electrolysis-a-tale-of-tab-switching-and-themes/
-
- Usage:
-   Components.utils.import(".../path/to/visuallyselectedTabs.jsm");
-   visuallyselectedTabs(gBrowser);
-
- license: The MIT License, Copyright (c) 2015 YUKI "Piro" Hiroshi
- original:
-   http://github.com/piroor/fxaddonlib-visuallyselected-tabs
-*/
-
-var EXPORTED_SYMBOLS = ['visuallyselectedTabs'];
-
-Components.utils.import('resource://gre/modules/Services.jsm');
-
-function setVisuallySelected(aNode, aSelected) {
-  if (!aNode || typeof aNode.setAttribute != 'function')
-    return;
-
-  if (aSelected)
-    aNode.setAttribute('visuallyselected', true);
-  else
-    aNode.removeAttribute('visuallyselected');
-
-  Array.forEach(aNode.childNodes, function(aChild) {
-    setVisuallySelected(aChild, aSelected);
-  });
-
-  var anonymousChildren = aNode.ownerDocument.getAnonymousNodes(aNode);
-  if (anonymousChildren && anonymousChildren.length > 0)
-    Array.forEach(anonymousChildren, function(aAnonymousChild) {
-      setVisuallySelected(aAnonymousChild, aSelected);
-    });
-}
-
-function visuallyselectedTabs(aTabBrowser) {
-  if (!aTabBrowser ||
-      aTabBrowser.localName != 'tabbrowser' ||
-      aTabBrowser.__visuallyselectedTabsInstalled ||
-      Services.vc.compare(Services.appinfo.platformVersion, '41.0a1') >= 0)
-    return;
-
-  aTabBrowser.__visuallyselectedTabsInstalled = true;
-
-  function onTabSelect(aEvent) {
-    var prevTab = aEvent.detail && aEvent.detail.previousTab;
-    if (prevTab)
-      setVisuallySelected(prevTab, false);
-
-    setVisuallySelected(aEvent.originalTarget, true);
-  }
-
-  var tabsContainer = aTabBrowser.tabContainer;
-  tabsContainer.addEventListener('TabSelect', onTabSelect, false);
-
-  setVisuallySelected(aTabBrowser.selectedTab, true);
-
-  var document = aTabBrowser.ownerDocument;
-  document.addEventListener('unload', function onUnload(aEvent) {
-    document.removeEventListener('unload', onUnload, false);
-    tabsContainer.removeEventListener('TabSelect', onTabSelect, false);
-  }, false);
-}
+/*
+ Backporting "visuallyselected" for Firefox 31-40
+
+ See also:
+   http://www.hackermusings.com/2015/06/electrolysis-a-tale-of-tab-switching-and-themes/
+
+ Usage:
+   Components.utils.import(".../path/to/visuallyselectedTabs.jsm");
+   visuallyselectedTabs(gBrowser);
+
+ license: The MIT License, Copyright (c) 2015-2016 YUKI "Piro" Hiroshi
+ original:
+   http://github.com/piroor/fxaddonlib-visuallyselected-tabs
+*/
+
+var EXPORTED_SYMBOLS = ['visuallyselectedTabs'];
+
+Components.utils.import('resource://gre/modules/Services.jsm');
+
+function setVisuallySelected(aNode, aSelected) {
+  if (!aNode || typeof aNode.setAttribute != 'function')
+    return;
+
+  if (aSelected)
+    aNode.setAttribute('visuallyselected', true);
+  else
+    aNode.removeAttribute('visuallyselected');
+
+  for (let aChild of aNode.childNodes)
+  {
+    setVisuallySelected(aChild, aSelected);
+  }
+
+  var anonymousChildren = aNode.ownerDocument.getAnonymousNodes(aNode);
+  if (anonymousChildren && anonymousChildren.length > 0) {
+    for (let aAnonymousChild of anonymousChildren)
+    {
+      setVisuallySelected(aAnonymousChild, aSelected);
+    }
+  }
+}
+
+function visuallyselectedTabs(aTabBrowser) {
+  if (!aTabBrowser ||
+      aTabBrowser.localName != 'tabbrowser' ||
+      aTabBrowser.__visuallyselectedTabsInstalled ||
+      Services.vc.compare(Services.appinfo.platformVersion, '41.0a1') >= 0)
+    return;
+
+  aTabBrowser.__visuallyselectedTabsInstalled = true;
+
+  function onTabSelect(aEvent) {
+    var prevTab = aEvent.detail && aEvent.detail.previousTab;
+    if (prevTab)
+      setVisuallySelected(prevTab, false);
+
+    setVisuallySelected(aEvent.originalTarget, true);
+  }
+
+  var tabsContainer = aTabBrowser.tabContainer;
+  tabsContainer.addEventListener('TabSelect', onTabSelect, false);
+
+  setVisuallySelected(aTabBrowser.selectedTab, true);
+
+  var document = aTabBrowser.ownerDocument;
+  document.addEventListener('unload', function onUnload(aEvent) {
+    document.removeEventListener('unload', onUnload, false);
+    tabsContainer.removeEventListener('TabSelect', onTabSelect, false);
+  }, false);
+}
diff --git a/modules/tabContentsObserver.js b/modules/tabContentsObserver.js
index 8592f91..550fa9e 100644
--- a/modules/tabContentsObserver.js
+++ b/modules/tabContentsObserver.js
@@ -42,10 +42,10 @@ Components.utils.import('resource://treestyletab-modules/constants.js');
 XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['tabContentsObserver'].concat(aArgs));
+	utils.log('tabContentsObserver', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['tabContentsObserver'].concat(aArgs));
+	utils.logWithStackTrace('tabContentsObserver', ...aArgs);
 }
 
 function TabContentsObserver(aOwner, aBox, aOptions) {
@@ -120,6 +120,23 @@ TabContentsObserver.prototype = {
 		if (!tab)
 			return;
 
+		// ignore changes in <xul:label/>
+		if (
+			[...aMutation.addedNodes].every(function(aNode) {
+				return (
+					aNode.nodeType == aNode.TEXT_NODE &&
+					aNode.parentNode.localName == 'label'
+				);
+			}) ||
+			(
+				target.localName == 'label' &&
+				[...aMutation.removedNodes].every(function(aNode) {
+					return aNode.nodeType == aNode.TEXT_NODE;
+				})
+			)
+			)
+			return;
+
 		log('onTabContentsModified on the tab '+tab._tPos);
 
 		this.handlingChange = true;
@@ -130,5 +147,26 @@ TabContentsObserver.prototype = {
 		w.setTimeout((function() {
 			this.handlingChange = false;
 		}).bind(this), 10);
+	},
+
+	logMutation : function TabContentsObserver_logMutation(aMutation, aDescription)
+	{
+		if (!utils.isDebugging('tabContentsObserver'))
+			return;
+
+		var target = aMutation.target;
+		var ownerInformation = this.box.localName + '#' + this.box.id + '.' + this.box.className;
+		var targetInformation = target ? target.localName + '#' + target.id + '.' + target.className : '(null)' ;
+		var addedInformation = '';
+		if (aMutation.addedNodes.length)
+			 addedInformation = ' added[' + [...aMutation.addedNodes] + ']';
+		var removedInformation = '';
+		if (aMutation.removedNodes.length)
+			 removedInformation = ' added[' + [...aMutation.removedNodes] + ']';
+		log(aDescription + ' ' +
+			ownerInformation + ' / ' +
+			targetInformation +
+			addedInformation +
+			removedInformation);
 	}
 };
diff --git a/modules/tabbarDNDObserver.js b/modules/tabbarDNDObserver.js
index 7a6ab9e..bf77eb5 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-2016
+ * Portions created by the Initial Developer are Copyright (C) 2010-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -64,10 +64,10 @@ const SecMan = Cc['@mozilla.org/scriptsecuritymanager;1']
 				.getService(Ci.nsIScriptSecurityManager);
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['tabbarDNDObserver'].concat(aArgs));
+	utils.log('tabbarDNDObserver', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['tabbarDNDObserver'].concat(aArgs));
+	utils.logWithStackTrace('tabbarDNDObserver', ...aArgs);
 }
 
 function TabbarDNDObserver(aTabBrowser) 
@@ -79,16 +79,12 @@ TabbarDNDObserver.prototype = {
 	
 	readyToStartTabbarDrag : function TabbarDND_readyToStartTabbarDrag() 
 	{
-		var sheet = utils.makeURIFromSpec('chrome://treestyletab/content/hide-embed.css');
-		if (!SSS.sheetRegistered(sheet, SSS.AGENT_SHEET))
-			SSS.loadAndRegisterSheet(sheet, SSS.AGENT_SHEET);
+		this.treeStyleTab.panelDNDObserver.startWaitDrop();
 	},
  
 	readyToEndTabbarDrag : function TabbarDND_readyToEndTabbarDrag() 
 	{
-		var sheet = utils.makeURIFromSpec('chrome://treestyletab/content/hide-embed.css');
-		if (SSS.sheetRegistered(sheet, SSS.AGENT_SHEET))
-			SSS.unregisterSheet(sheet, SSS.AGENT_SHEET);
+		this.treeStyleTab.panelDNDObserver.endWaitDrop();
 	},
  
 	canDragTabbar : function TabbarDND_canDragTabbar(aEvent) 
@@ -767,15 +763,18 @@ catch(e) {
 		var tabsInfo = this.getDraggedTabsInfoFromOneTab(aTab, actionInfo);
 		if (
 			tabsInfo.draggedTabs.length <= 1 ||
-			Array.some(tabsInfo.draggedTabs, function(aTab) {
+			[...tabsInfo.draggedTabs].some(function(aTab) {
 				return aTab.getAttribute('multiselected') == 'true'; // if multiselected, it should be handled by other addons (like Multiple Tab Handler)
 			})
 			)
 			return;
 
-		w['piro.sakura.ne.jp'].tabsDragUtils.startTabsDrag(aEvent, tabsInfo.draggedTabs, {
-			shrinkOthers : utils.getTreePref('shrinkOtherDraggedTabs')
-		});
+		if (!sv.isCollapsed(aTab) &&
+			utils.getTreePref('shrinkOtherDraggedTabs')) {
+			sv.collapseExpandSubtree(aTab, true);
+			aTab.__treestyletab__toBeEpandedAfterDrop = true;
+		}
+		w['piro.sakura.ne.jp'].tabsDragUtils.startTabsDrag(aEvent, tabsInfo.draggedTabs);
 	},
  
 	onTabbarDragStart : function TabbarDND_onTabbarDragStart(aEvent) 
@@ -789,6 +788,11 @@ catch(e) {
 				sv.kTABBAR_MOVE_NORMAL,
 			0
 		);
+		dt.mozSetDataAt(
+			sv.kDRAG_TYPE_TABBAR_NODE,
+			sv.browser.mTabContainer,
+			0
+		);
 		dt.mozCursor = 'move';
 //		var tabbar = sv.browser.mTabContainer;
 //		var box = tabbar.boxObject;
@@ -822,7 +826,7 @@ catch(e) {
 		w.clearTimeout(this.mAutoExpandTimer);
 		w.clearTimeout(this.mAutoExpandTimerNext);
 
-		var sourceNode = dt.getData(sv.kDRAG_TYPE_TABBAR+'-node');
+		var sourceNode = dt.getData(sv.kDRAG_TYPE_TABBAR_NODE);
 		if (aEvent.target == sourceNode)
 			return;
 
@@ -931,6 +935,10 @@ catch(e) {
 			return;
 
 		var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
+		if (draggedTab.__treestyletab__toBeEpandedAfterDrop) {
+			delete draggedTab.__treestyletab__toBeEpandedAfterDrop;
+			sv.collapseExpandSubtree(draggedTab, false);
+		}
 		if (this.isDraggingAllCurrentTabs(draggedTab))
 			return;
 
@@ -1002,10 +1010,7 @@ try{
 		var observer = b;
 		if (
 			b.tabContainer &&
-			(
-				b.tabContainer._getDropEffectForTabDrag || // Firefox 44 and later
-				b.tabContainer._setEffectAllowedForDataTransfer // Firefox 43 and older
-			)
+			b.tabContainer._getDropEffectForTabDrag
 			)
 			observer = b.tabContainer;
 
@@ -1141,37 +1146,42 @@ catch(e) {
 			return;
 		}
 
+		if (!draggedTab) {
+			this.handleLinksOrBookmarks(aEvent, dropActionInfo);
+			return;
+		}
+
 		var sourceBrowser = sv.getTabBrowserFromChild(draggedTab);
-		if (draggedTab && sourceBrowser != b)
+		if (sourceBrowser != b)
 			sourceBrowser.treeStyleTab.tabbarDNDObserver.clearDropPosition(true);
 
-		if (draggedTab && this.performDrop(dropActionInfo, draggedTab)) {
+		if (draggedTab.__treestyletab__toBeEpandedAfterDrop) {
+			delete draggedTab.__treestyletab__toBeEpandedAfterDrop;
+			sourceBrowser.treeStyleTab.collapseExpandSubtree(draggedTab, false);
+		}
+
+		if (this.performDrop(dropActionInfo, draggedTab)) {
 			aEvent.stopPropagation();
 			return;
 		}
 
 		// duplicating of tabs
 		if (
-			draggedTab &&
 			(
 				dt.dropEffect == 'copy' ||
 				sourceBrowser != b
 			) &&
 			dropActionInfo.position == sv.kDROP_ON
 			) {
-			var beforeTabs = Array.slice(b.mTabContainer.childNodes);
+			let beforeTabs = [...b.mTabContainer.childNodes];
 			w.setTimeout(function() {
-				var newTabs = Array.slice(b.mTabContainer.childNodes).filter(function(aTab) {
+				var newTabs = [...b.mTabContainer.childNodes].filter(function(aTab) {
 						return beforeTabs.indexOf(aTab) < 0;
 					});
 				if (newTabs.length)
 					sv.attachTabTo(newTabs[0], dropActionInfo.target);
 			}, 0);
-			return;
 		}
-
-		if (!draggedTab)
-			this.handleLinksOrBookmarks(aEvent, dropActionInfo);
 	},
 	handleLinksOrBookmarks : function TabbarDND_handleLinksOrBookmarks(aEvent, aDropActionInfo)
 	{
diff --git a/modules/tabpanelDNDObserver.js b/modules/tabpanelDNDObserver.js
index d2eee66..e063c61 100644
--- a/modules/tabpanelDNDObserver.js
+++ b/modules/tabpanelDNDObserver.js
@@ -44,6 +44,13 @@ Components.utils.import('resource://treestyletab-modules/ReferenceCounter.js');
 
 XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
 
+function log(...aArgs) {
+	utils.log('tabpanelDNDObserver', ...aArgs);
+}
+function logWithStackTrace(...aArgs) {
+	utils.logWithStackTrace('tabpanelDNDObserver', ...aArgs);
+}
+
 
 function TabpanelDNDObserver(aTabBrowser) 
 {
@@ -78,13 +85,12 @@ TabpanelDNDObserver.prototype = {
  
 	canDrop : function TabpanelDND_canDrop(aEvent) 
 	{
-		var session = this.treeStyleTab.currentDragSession;
-		return !!(
-				session &&
-				session.isDataFlavorSupported(this.treeStyleTab.kDRAG_TYPE_TABBAR) &&
-				session.sourceNode &&
-				session.sourceNode.ownerDocument == this.document
-			);
+		var tabbar = aEvent.dataTransfer.mozGetDataAt(this.treeStyleTab.kDRAG_TYPE_TABBAR_NODE, 0);
+		log('canDrop: ', {
+			tabbar       : tabbar,
+			sameDocument : this.document == (tabbar && tabbar.ownerDocument)
+		});
+		return !!(tabbar && tabbar.ownerDocument == this.document);
 	},
  
 	handleEvent : function TabpanelDND_handleEvent(aEvent) 
@@ -119,7 +125,11 @@ TabpanelDNDObserver.prototype = {
  
 	onDrop : function TabpanelDND_onDrop(aEvent) 
 	{
-		if (!this.canDrop(aEvent)) return;
+		var canDrop = this.canDrop(aEvent);
+		this.endWaitDrop();
+		if (!canDrop)
+			return;
+
 		var sv = this.treeStyleTab;
 		var dt = aEvent.dataTransfer;
 		var position = this.getDropPosition(aEvent);
@@ -143,30 +153,60 @@ TabpanelDNDObserver.prototype = {
 		this.document     = aTabBrowser.ownerDocument;
 		this.window       = this.document.defaultView;
 		this.treeStyleTab = aTabBrowser.treeStyleTab;
-
-		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');
-
+		this.endWaitDrop();
 		delete this.treeStyleTab;
 		delete this.browser;
 		delete this.document;
 		delete this.window;
+	},
+
+	startWaitDrop : function TabpanelDND_startWaitDrop()
+	{
+		log('startWaitDrop');
+		if (this.waitingDrop)
+			return;
+
+		this.area = this.document.createElement('box');
+		this.area.setAttribute('class', this.treeStyleTab.kTABBAR_DROP_AREA);
+		this.document.documentElement.appendChild(this.area);
+		var style = this.area.style;
+		var box = this.browser.mPanelContainer.boxObject;
+		style.left = box.x + 'px';
+		style.top = box.y + 'px';
+		style.width = box.width + 'px';
+		style.height = box.height + 'px';
+
+		this.area.addEventListener('dragover',  this, true);
+		ReferenceCounter.add('this.area,dragover,this,true');
+		this.area.addEventListener('dragleave', this, true);
+		ReferenceCounter.add('this.area,dragleave,this,true');
+		this.area.addEventListener('drop',      this, true);
+		ReferenceCounter.add('this.area,drop,this,true');
+
+		this.waitingDrop = true;
+	},
+
+	endWaitDrop : function TabpanelDND_endWaitDrop()
+	{
+		log('endWaitDrop');
+		if (!this.waitingDrop)
+			return;
+
+		this.area.removeEventListener('dragover',  this, true);
+		ReferenceCounter.remove('this.area,dragover,this,true');
+		this.area.removeEventListener('dragleave', this, true);
+		ReferenceCounter.remove('this.area,dragleave,this,true');
+		this.area.removeEventListener('drop',      this, true);
+		ReferenceCounter.remove('this.area,drop,this,true');
+
+		this.area.parentNode.removeChild(this.area);
+		delete this.area;
+
+		this.waitingDrop = false;
 	}
  
 }; 
diff --git a/modules/utils.js b/modules/utils.js
index af093c6..5a920be 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-2016
+ * Portions created by the Initial Developer are Copyright (C) 2010-2017
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
@@ -69,8 +69,7 @@ XPCOMUtils.defineLazyModuleGetter(this, 'TreeStyleTabConstants',
   'resource://treestyletab-modules/constants.js', 'TreeStyleTabConstants');
 
 const TST_PREF_PREFIX = 'extensions.treestyletab.';
-const TST_PREF_VERSION = 14;
-
+const TST_PREF_VERSION = 15;
 
 var TreeStyleTabUtils = {
 
@@ -260,6 +259,13 @@ var TreeStyleTabUtils = {
 					if (delay !== null)
 						this.setTreePref('tabbar.autoHide.delay.show', delay);
 				}
+			case 14:
+				{
+					if (this.getTreePref('controlNewTabPosition') !== null) {
+						this.setTreePref('insertNewChildAt', TreeStyleTabConstants.kINSERT_NO_CONTROL);
+						this.clearTreePref('controlNewTabPosition');
+					}
+				}
 			default:
 				for (let i = 0, maxi = orientalPrefs.length; i < maxi; i++)
 				{
@@ -380,12 +386,12 @@ var TreeStyleTabUtils = {
 	isTabNotRestoredYet : function utils_isTabNotRestoredYet(aTab)
 	{
 		var browser = aTab.linkedBrowser;
-		return !!browser.__SS_restoreState;
+		return !!aTab.__SS_lazyData || !!browser.__SS_restoreState;
 	},
 	isTabNeedToBeRestored : function utils_isTabNeedToBeRestored(aTab)
 	{
 		var browser = aTab.linkedBrowser;
-		return browser.__SS_restoreState == 1;
+		return !!aTab.__SS_lazyData || browser.__SS_restoreState == 1;
 	},
 	get SessionStoreInternal() {
 		return this.SessionStoreNS.SessionStoreInternal;
@@ -806,4 +812,11 @@ prefs.addPrefListener(TreeStyleTabUtils);
 		aWindow.gBrowser.treeStyleTab.onBeforeTabDuplicate(aWindow, aTab, aDelta);
 		return this.__treestyletab__duplicateTab.call(this, aWindow, aTab, aDelta);
 	};
+
+	let { TabListView } = Cu.import('resource:///modules/syncedtabs/TabListView.js', {});
+	TabListView.prototype.__treestyletab__onOpenSelected = TabListView.prototype.onOpenSelected;
+	TabListView.prototype.onOpenSelected = function(...aArgs) {
+		this._window.top.gBrowser.treeStyleTab.readyToOpenOrphanTabNow();
+		return this.__treestyletab__onOpenSelected(...aArgs);
+	};
 }
diff --git a/modules/window.js b/modules/window.js
index 784f919..5281475 100644
--- a/modules/window.js
+++ b/modules/window.js
@@ -75,10 +75,10 @@ XPCOMUtils.defineLazyServiceGetter(this, 'SessionStore',
   '@mozilla.org/browser/sessionstore;1', 'nsISessionStore');
 
 function log(...aArgs) {
-	utils.log.apply(utils, ['window'].concat(aArgs));
+	utils.log('window', ...aArgs);
 }
 function logWithStackTrace(...aArgs) {
-	utils.logWithStackTrace.apply(utils, ['window'].concat(aArgs));
+	utils.logWithStackTrace('window', ...aArgs);
 }
 
 function TreeStyleTabWindow(aWindow)
@@ -528,10 +528,11 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
 		if (!utils.getTreePref('enableSubtreeIndent.allTabsPopup'))
 			return;
 
-		Array.forEach(aEvent.originalTarget.childNodes, function(aItem) {
+		for (let aItem of aEvent.originalTarget.childNodes)
+		{
 			if (aItem.classList.contains('alltabs-item') && 'tab' in aItem)
 				aItem.style.marginLeft = aItem.tab.getAttribute(this.kNEST) + 'em';
-		}, this);
+		}
 	},
  
 	initUIShowHideObserver : function TSTWindow_initUIShowHideObserver() 
@@ -2002,7 +2003,7 @@ TreeStyleTabWindow.prototype = inherit(TreeStyleTabBase, {
 
 		var count = 0;
 		this.browser.visibleTabs.some(function(aTab) {
-			if (aTab.linkedBrowser.__treestyletab__toBeRestored)
+			if (aTab.__treestyletab__toBeRestored)
 				count++;
 			return count > 1;
 		});
diff --git a/skin/classic/treestyletab/base-colors.css b/skin/classic/treestyletab/base-colors.css
index c2d071e..de113d3 100644
--- a/skin/classic/treestyletab/base-colors.css
+++ b/skin/classic/treestyletab/base-colors.css
@@ -44,7 +44,9 @@
 	--tst-tab-dropmarker: -moz-dialogtext;
 }
 
-:root[devtoolstheme="dark"][treestyletab-devedition="true"] {
+:root[devtoolstheme="dark"][treestyletab-devedition="true"],
+/* "Compact Dark" theme on Firefox 53 and later */
+:root[style*="resource:///chrome/browser/content/browser/defaultthemes/compact.header.png"][lwthemetextcolor="bright"] {
 	--tst-tab-surface: #39424D;
 	--tst-tab-text: white;
 	--tst-tab-border: #5f6670;
diff --git a/skin/classic/treestyletab/license.txt b/skin/classic/treestyletab/license.txt
index 023b08a..2d16cc7 100644
--- a/skin/classic/treestyletab/license.txt
+++ b/skin/classic/treestyletab/license.txt
@@ -14,7 +14,7 @@ License.
 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) 2007-2016
+Portions created by the Initial Developer are Copyright (C) 2007-2017
 the Initial Developer. All Rights Reserved.
 
 Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex at gmail.com>
diff --git a/skin/classic/treestyletab/metal/base.css b/skin/classic/treestyletab/metal/base.css
index f58315e..343e34f 100644
--- a/skin/classic/treestyletab/metal/base.css
+++ b/skin/classic/treestyletab/metal/base.css
@@ -194,11 +194,20 @@ tabbrowser[treestyletab-tabbar-position="right"]
 
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab
-  .tab-text {
+  .tab-text,
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab
+  .tab-label-container {
 	margin: 0 !important;
 	padding: 3px 4px 4px !important;
 	text-align: center !important;
 }
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab
+  .tab-label-container
+  .tab-text {
+	padding: 0 !important;
+}
 
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab
diff --git a/skin/classic/treestyletab/metal/tab.css b/skin/classic/treestyletab/metal/tab.css
index 91a1db6..05afaf0 100644
--- a/skin/classic/treestyletab/metal/tab.css
+++ b/skin/classic/treestyletab/metal/tab.css
@@ -69,18 +69,11 @@
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"]):not([pinned]),
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"])[pinned]:not([titlechanged]),
             .tab-background-end:not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
             .tab-content:not([pinned])[selected="true"],
             .tab-content[pinned]:not([titlechanged])[selected="true"],
             .tab-background-start[selected="true"],
             .tab-background-middle[selected="true"],
-            .tab-background-end[selected="true"],
-            /* Firefox 50 and older */
-            .tab-content:not([pinned])[visuallyselected="true"],
-            .tab-content[pinned]:not([titlechanged])[visuallyselected="true"],
-            .tab-background-start[visuallyselected="true"],
-            .tab-background-middle[visuallyselected="true"],
-            .tab-background-end[visuallyselected="true"]) {
+            .tab-background-end[selected="true"]) {
 	border: 0 none !important;
 	background: transparent !important;
 }
@@ -88,14 +81,9 @@
   :-moz-any(.tab-background-start:not([selected="true"]):not([visuallyselected="true"]),
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"]),
             .tab-background-end:not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
             .tab-background-start[selected="true"],
             .tab-background-middle[selected="true"],
-            .tab-background-end[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background-start[visuallyselected="true"],
-            .tab-background-middle[visuallyselected="true"],
-            .tab-background-end[visuallyselected="true"]) {
+            .tab-background-end[selected="true"]) {
 	mask: none !important;
 }
 /* highlighted pinned tabs */
@@ -202,16 +190,10 @@
   .tab-content[pinned]:not([titlechanged]),
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected]:not(:hover)
-  :-moz-any(/* Firefox 51 and later */
-            .tab-content[pinned][selected],
-            /* Firefox 50 and older */
-            .tab-content[pinned][visuallyselected]),
+  .tab-content[pinned][selected],
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected]:hover
-  :-moz-any(/* Firefox 51 and later */
-            .tab-content[pinned][selected],
-            /* Firefox 50 and older */
-            .tab-content[pinned][visuallyselected]) {
+  .tab-content[pinned][selected] {
 	background: none !important;
 }
 
@@ -254,16 +236,10 @@
   .tab-content[pinned],
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:not(:hover)
-  :-moz-any(/* Firefox 51 and later */
-            .tab-content[pinned][selected="true"],
-            /* Firefox 50 and older */
-            .tab-content[pinned][visuallyselected="true"]),
+  .tab-content[pinned][selected="true"],
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:hover
-  :-moz-any(/* Firefox 51 and later */
-            .tab-content[pinned][selected="true"],
-            /* Firefox 50 and older */
-            .tab-content[pinned][visuallyselected="true"]) {
+  .tab-content[pinned][selected="true"] {
 	line-height: 1 !important;
 	border: 1px solid #666666 !important;
 	border-radius: 4px !important;
@@ -278,31 +254,19 @@
   .tab-content[pinned]:not([titlechanged]),
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:not(:hover)
-  .tab-content[selected="true"][pinned], /* Firefox 51 and later */
-.tabbrowser-tabs[treestyletab-mode="vertical"]
-  .tabbrowser-tab[visuallyselected="true"]:not(:hover)
-  .tab-content[visuallyselected="true"][pinned], /* Firefox 50 and older */
-.tabbrowser-tabs[treestyletab-mode="vertical"]
-  .tabbrowser-tab[visuallyselected="true"]:hover
-  .tab-content[selected="true"][pinned], /* Firefox 51 and later */
+  .tab-content[selected="true"][pinned],
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:hover
-  .tab-content[visuallyselected="true"][pinned] /* Firefox 50 and older */ {
+  .tab-content[selected="true"][pinned] {
 	background: #9d9d9d !important;
 }
 
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:not(:hover)
-  .tab-content[selected="true"][pinned], /* Firefox 51 and later */
-.tabbrowser-tabs[treestyletab-mode="vertical"]
-  .tabbrowser-tab[visuallyselected="true"]:not(:hover)
-  .tab-content[visuallyselected="true"][pinned], /* Firefox 50 and older */
-.tabbrowser-tabs[treestyletab-mode="vertical"]
-  .tabbrowser-tab[visuallyselected="true"]:hover
-  .tab-content[selected="true"][pinned], /* Firefox 51 and later */
+  .tab-content[selected="true"][pinned],
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:hover
-  .tab-content[visuallyselected="true"][pinned] /* Firefox 50 and older */ {
+  .tab-content[selected="true"][pinned] {
 	background-color: #b3b2b3 !important;
 }
 
@@ -368,19 +332,11 @@
 :root:-moz-window-inactive
   .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]
-  .tab-content[pinned][selected="true"], /* Firefox 51 and later */
-:root:-moz-window-inactive
-  .tabbrowser-tabs[treestyletab-mode="vertical"]
-  .tabbrowser-tab[visuallyselected="true"]
-  .tab-content[pinned][visuallyselected="true"], /* Firefox 50 and older */
-:root:-moz-window-inactive
-  .tabbrowser-tabs[treestyletab-mode="vertical"]
-  .tabbrowser-tab[visuallyselected="true"]:hover
-  .tab-content[pinned][selected="true"], /* Firefox 51 and later */
+  .tab-content[pinned][selected="true"],
 :root:-moz-window-inactive
   .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[visuallyselected="true"]:hover
-  .tab-content[pinned][visuallyselected="true"] /* Firefox 50 and older */ {
+  .tab-content[pinned][selected="true"] {
 	background: #e4e4e4 !important;
 }
 
diff --git a/skin/classic/treestyletab/sidebar/license.txt b/skin/classic/treestyletab/sidebar/license.txt
index 38b94a5..7d3b8c4 100644
--- a/skin/classic/treestyletab/sidebar/license.txt
+++ b/skin/classic/treestyletab/sidebar/license.txt
@@ -14,7 +14,7 @@ License.
 The Original Code is the SidebarStyleTab.
 
 The Initial Developer of the Original Code is YUKI "Piro" Hiroshi.
-Portions created by the Initial Developer are Copyright (C) 2010-2012
+Portions created by the Initial Developer are Copyright (C) 2010-2017
 the Initial Developer. All Rights Reserved.
 
 Contributor(s): Philipp von Weitershausen <philipp at weitershausen.de>
diff --git a/skin/classic/treestyletab/sidebar/sidebar.css b/skin/classic/treestyletab/sidebar/sidebar.css
index b9fe92b..fbc8299 100644
--- a/skin/classic/treestyletab/sidebar/sidebar.css
+++ b/skin/classic/treestyletab/sidebar/sidebar.css
@@ -407,10 +407,7 @@ tabbrowser[treestyletab-mode="vertical"]
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   :-moz-any(.tab-content:not([selected="true"]):not([visuallyselected="true"]):not([pinned]),
             .tab-content:not([selected="true"]):not([visuallyselected="true"])[pinned]:not([titlechanged]),
-            /* Firefox 51 and later */
-            .tab-content[selected="true"],
-            /* Firefox 50 and older */
-            .tab-content[visuallyselected="true"]) {
+            .tab-content[selected="true"]) {
 	border: 0 none !important;
 	background: transparent !important;
 }
@@ -418,14 +415,9 @@ tabbrowser[treestyletab-mode="vertical"]
   :-moz-any(.tab-background-start:not([selected="true"]):not([visuallyselected="true"]),
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"]),
             .tab-background-end:not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
             .tab-background-start[selected="true"],
             .tab-background-middle[selected="true"],
-            .tab-background-end[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background-start[visuallyselected="true"],
-            .tab-background-middle[visuallyselected="true"],
-            .tab-background-end[visuallyselected="true"]) {
+            .tab-background-end[selected="true"]) {
 	mask: none !important;
 }
 .tabbrowser-tabs[treestyletab-mode="vertical"]
@@ -433,14 +425,9 @@ tabbrowser[treestyletab-mode="vertical"]
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"]):not([pinned]),
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"])[pinned]:not([titlechanged]),
             .tab-background-end:not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
             .tab-background-start[selected="true"],
             .tab-background-middle[selected="true"],
-            .tab-background-end[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background-start[visuallyselected="true"],
-            .tab-background-middle[visuallyselected="true"],
-            .tab-background-end[visuallyselected="true"]) {
+            .tab-background-end[selected="true"]) {
 	background: transparent !important;
 }
 .tabbrowser-tabs[treestyletab-mode="vertical"]
@@ -498,4 +485,4 @@ tabbrowser[treestyletab-mode="vertical"]
   .tabbrowser-tab:not(:hover):not([visuallyselected="true"])[multipletab-ready-to-close="true"]
   .tab-close-button {
 	visibility: visible !important;
-}
\ No newline at end of file
+}
diff --git a/skin/classic/treestyletab/square/base.css b/skin/classic/treestyletab/square/base.css
index c22ab34..2a2ca89 100644
--- a/skin/classic/treestyletab/square/base.css
+++ b/skin/classic/treestyletab/square/base.css
@@ -15,7 +15,9 @@
 	--tst-tabbar-bg: darkgray;
 }
 
-:root[devtoolstheme="dark"][treestyletab-devedition="true"] {
+:root[devtoolstheme="dark"][treestyletab-devedition="true"],
+/* "Compact Dark" theme on Firefox 53 and later */
+:root[style*="resource:///chrome/browser/content/browser/defaultthemes/compact.header.png"][lwthemetextcolor="bright"] {
 	--tst-tab-highlighted-base: ThreeDHighlight;
 	--tst-tab-highlighted-highlight: Highlight;
 	--tst-tab-side-border: #39424D;
@@ -182,10 +184,7 @@
 /* for Mac OS X */
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   :-moz-any(.tab-content:not([pinned="true"]):not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
-            .tab-content:not([pinned="true"])[selected="true"],
-            /* Firefox 50 and older */
-            .tab-content:not([pinned="true"])[visuallyselected="true"]) {
+            .tab-content:not([pinned="true"])[selected="true"]) {
 	border: 0 none !important;
 	background: transparent !important;
 }
@@ -193,14 +192,9 @@
   :-moz-any(.tab-background-start:not([selected="true"]):not([visuallyselected="true"]),
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"]),
             .tab-background-end:not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
             .tab-background-start[selected="true"],
             .tab-background-middle[selected="true"],
-            .tab-background-end[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background-start[visuallyselected="true"],
-            .tab-background-middle[visuallyselected="true"],
-            .tab-background-end[visuallyselected="true"]) {
+            .tab-background-end[selected="true"]) {
 	mask: none !important;
 }
 .tabbrowser-tabs[treestyletab-mode="vertical"]
@@ -208,14 +202,9 @@
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"]):not([pinned]),
             .tab-background-middle:not([selected="true"]):not([visuallyselected="true"])[pinned]:not([titlechanged]),
             .tab-background-end:not([selected="true"]):not([visuallyselected="true"]),
-            /* Firefox 51 and later */
             .tab-background-start[selected="true"],
             .tab-background-middle[selected="true"],
-            .tab-background-end[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background-start[visuallyselected="true"],
-            .tab-background-middle[visuallyselected="true"],
-            .tab-background-end[visuallyselected="true"]) {
+            .tab-background-end[selected="true"]) {
 	background: transparent !important;
 }
 .tabbrowser-tabs[treestyletab-mode="vertical"]
@@ -245,7 +234,13 @@
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
   .tabbrowser-tab[visuallyselected="true"] {
 	margin: 0 !important;
-	-moz-border-top-colors: var(--tst-tab-surface-hover) transparent !important;
+	-moz-border-top-colors: var(--tst-tab-surface-selected) transparent !important;
+	-moz-border-bottom-colors: var(--tst-tab-border) transparent !important;
+}
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  .tabbrowser-tab[visuallyselected="true"]:hover {
+	margin: 0 !important;
+	-moz-border-top-colors: var(--tst-tab-surface-selected-hover) transparent !important;
 	-moz-border-bottom-colors: var(--tst-tab-border) transparent !important;
 }
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
@@ -256,7 +251,13 @@
   .tabbrowser-tab:not([pinned])[visuallyselected="true"],
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
   .tabbrowser-tab[pinned][visuallyselected="true"] {
-	background-color: var(--tst-tab-surface-hover) !important;
+	background-color: var(--tst-tab-surface-selected) !important;
+}
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  .tabbrowser-tab:not([pinned])[visuallyselected="true"]:hover,
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  .tabbrowser-tab[pinned][visuallyselected="true"]:hover {
+	background-color: var(--tst-tab-surface-selected-hover) !important;
 }
 
 
@@ -318,10 +319,7 @@
   .tabbrowser-tab:not([visuallyselected="true"]):not([pinned]),
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
   .tabbrowser-tab
-  :-moz-any(/* Firefox 51 and later */
-            .tab-content[selected="true"]:not([pinned]),
-            /* Firefox 50 and older */
-            .tab-content[visuallyselected="true"]:not([pinned])),
+  .tab-content[selected="true"]:not([pinned]),
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
   .tabbrowser-tab
   .tab-content:not([selected="true"]):not([visuallyselected="true"]):not([pinned]) {
diff --git a/skin/classic/treestyletab/square/tab-surface.css b/skin/classic/treestyletab/square/tab-surface.css
index ba8075e..bdd6a04 100644
--- a/skin/classic/treestyletab/square/tab-surface.css
+++ b/skin/classic/treestyletab/square/tab-surface.css
@@ -23,10 +23,7 @@
 
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
   .tabbrowser-tab[visuallyselected="true"]
-  :-moz-any(/* Firefox 51 and later */
-            .tab-background[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background[visuallyselected="true"]) {
+  .tab-background[selected="true"] {
 	background-color: var(--tst-tab-surface-selected) !important;
 	background-image: -moz-linear-gradient(
 	                    top,
@@ -52,10 +49,7 @@
 
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
   .tabbrowser-tab:hover
-  :-moz-any(/* Firefox 51 and later */
-            .tab-background[selected="true"],
-            /* Firefox 50 and older */
-            .tab-background[visuallyselected="true"]) {
+  .tab-background[selected="true"] {
 	background-color: var(--tst-tab-surface-selected-hover) !important;
 	background-image: -moz-linear-gradient(
 	                    top,
diff --git a/skin/classic/treestyletab/ui-base.css b/skin/classic/treestyletab/ui-base.css
index ace694c..40b482b 100644
--- a/skin/classic/treestyletab/ui-base.css
+++ b/skin/classic/treestyletab/ui-base.css
@@ -205,6 +205,15 @@ tabbrowser[treestyletab-drop-position="left"]:not([treestyletab-tabbar-position=
 }
 
 
+.treestyletab-tabbar-drop-area {
+	-moz-appearance: none;
+	background: rgba(0, 0, 0, 0.01);
+	border: none;
+	box-shadow: none;
+	position: fixed;
+}
+
+
 
 /* vertical tab bar */
 
@@ -279,21 +288,8 @@ tabbrowser[treestyletab-drop-position="left"]:not([treestyletab-tabbar-position=
 
 /* auto hide */
 
-tabbrowser[treestyletab-tabbar-position="left"]
-  .treestyletab-tabbar-toggler {
-	border-right: 1px solid;
-	border-right-color: var(--tst-tab-border);
-}
-tabbrowser[treestyletab-tabbar-position="right"]
-  .treestyletab-tabbar-toggler {
-	border-left: 1px solid;
-	border-left-color: var(--tst-tab-border);
-}
-tabbrowser[treestyletab-tabbar-position="bottom"]
-  .treestyletab-tabbar-toggler {
-	border-top: 1px solid;
-	border-top-color: var(--tst-tab-border);
-}
+tabbrowser:not([treestyletab-tabbar-position="top"])
+  .treestyletab-tabbar-toggler,
 .treestyletab-tabbar-toolbar[treestyletab-tabbar-autohide]
   #treestyletab-tabbar-resizer-box {
 	background: rgba(0, 0, 0, 0.25);
@@ -391,6 +387,19 @@ tabbrowser[treestyletab-tabbar-position="bottom"]
 }
 
 
+/* expand tab label container to avoid cropped label
+   See: https://github.com/piroor/treestyletab/issues/1228 */
+
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab:not([pinned])
+  .tab-label-container {
+	margin-top: -0.25em;
+	margin-bottom: -0.25em;
+	padding-bottom: 0.25em;
+	padding-top: 0.25em;
+}
+
+
 /* notification of newly opened tabs in background */
 
 .tabbrowser-tabs[treestyletab-mode="vertical"]

-- 
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