[Pkg-mozext-commits] [SCM] Show tabs like a tree branch, upstream, updated. upstream/0.12.2011061701-1-g9f8ba91

Andrea Veri av at src.gnome.org
Mon Dec 5 19:05:43 UTC 2011


The following commit has been merged in the upstream branch:
commit 9f8ba91df1ff414432441ff7d411ed80df60a779
Author: Andrea Veri <av at src.gnome.org>
Date:   Mon Dec 5 20:06:14 2011 +0100

    Imported Upstream Release 0.12.2011110101.

diff --git a/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js b/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js
index d9a1ce0..a5ba95a 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js
@@ -211,139 +211,110 @@ var TreeStyleTabBookmarksService = {
 			catch(e) { // Firefox 3.6 or older
 				ns = window;
 			}
+			var sv = this;
 			with (ns) {
 
-			eval('PlacesUIUtils._openTabset = '+
-				PlacesUIUtils._openTabset.toSource().replace(
-					/(function[^\(]*\([^\)]+)(\))/,
-					'$1, aFolderTitle$2'
-				).replace(
-					'{',
-					'{ var TSTTreeStructure = null, TSTPreviousTabs, TSTOpenGroupBookmarkBehavior;'
-				).replace(
-					'var urls = [];',
-					'$& var ids = [];'
-				).replace(
-					'urls.push(item.uri);',
-					'$& ids.push(item.id);'
-				).replace(
-					/(browserWindow\.(?:getBrowser\(\)|gBrowser)\.loadTabs\([^;]+\);)/,
-					<![CDATA[
-						if (
-							where.indexOf('tab') == 0 ||
-							aEvent.target.id == 'placesContext_openContainer:tabs' ||
-							aEvent.target.id == 'placesContext_openLinks:tabs' ||
-							aEvent.target == aEvent.target.parentNode._endOptOpenAllInTabs ||
-							aEvent.target.getAttribute('openInTabs') == 'true'
-							) {
-							let sv = browserWindow.TreeStyleTabBookmarksService;
-							TSTOpenGroupBookmarkBehavior = sv.openGroupBookmarkBehavior();
-							if (TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_SUBTREE) {
-								let treeStructure = TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_DONT_RESTORE_TREE_STRUCTURE ?
-											null :
-											sv.getTreeStructureFromItems(ids) ;
-								if (
-									treeStructure &&
-									TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_USE_DUMMY
-									) {
-									let parentCount = 0;
-									let childCount = 0;
-									for (let i in treeStructure) {
-										if (treeStructure[i] == -1)
-											parentCount++;
-										else
-											childCount++;
-									}
-									if (
-										parentCount > 1 &&
-										(
-											TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_USE_DUMMY_FORCE ||
-											// when there is any orphan, then all of parents and orphans should be grouped under a dummy tab.
-											childCount < parentCount
-										)
-										) {
-										ids.unshift(-1);
-										treeStructure = sv.getTreeStructureFromItems(ids, 0);
-										urls.unshift(sv.getGroupTabURI(aFolderTitle));
-									}
-								}
+			let (method = (sv.getTreePref('compatibility.TabUtilities') && PlacesUIUtils.TU__openTabset) ?
+							'TU__openTabset' :
+							'_openTabset') {
+				eval('PlacesUIUtils.'+method+' = '+
+					PlacesUIUtils[method].toSource().replace(
+						/(function[^\(]*\([^\)]+)(\))/,
+						'$1, aFolderTitle$2'
+					).replace(
+						'{',
+						'{ var TSTTreeStructure = null, TSTPreviousTabs, TSTOpenGroupBookmarkBehavior;'
+					).replace(
+						'var urls = [];',
+						'$& var ids = [];'
+					).replace(
+						'urls.push(item.uri);',
+						'$& ids.push(item.id);'
+					).replace(
+						/(browserWindow\.(?:getBrowser\(\)|gBrowser)\.loadTabs\([^;]+\);)/,
+						<![CDATA[
+							var TSTResult = browserWindow.TreeStyleTabBookmarksService.handleTabsOpenProcess(where, aEvent, browserWindow, ids, urls, typeof replaceCurrentTab == 'undefined' ? undefined : replaceCurrentTab, aFolderTitle);
+							TSTTreeStructure = TSTResult.treeStructure;
+							TSTPreviousTabs = TSTResult.previousTabs;
+							TSTOpenGroupBookmarkBehavior = TSTResult.behavior;
+							if (typeof replaceCurrentTab != 'undefined')
+								replaceCurrentTab = TSTResult.replaceCurrentTab;
+							$1
+							]]>
+					).replace(
+						/(\}\)?)$/,
+						<![CDATA[
+							if (TSTTreeStructure && TSTPreviousTabs) {
+								let tabs = browserWindow.TreeStyleTabBookmarksService.getNewTabsFromPreviousTabsInfo(browserWindow.gBrowser, TSTPreviousTabs)
+								browserWindow.TreeStyleTabService.applyTreeStructureToTabs(tabs, TSTTreeStructure, TSTOpenGroupBookmarkBehavior & browserWindow.TreeStyleTabBookmarksService.kGROUP_BOOKMARK_EXPAND_ALL_TREE);
+							}
+						$1]]>
+					)
+				);
+				if (sv.getTreePref('compatibility.TabUtilities') && method.indexOf('TU_') > -1)
+					window[method] = PlacesUIUtils[method];
+			}
 
-								if (sv.getTreePref('compatibility.TMP') &&
-									'TMP_Places' in browserWindow &&
-									'openGroup' in browserWindow.TMP_Places) {
-									TSTTreeStructure = treeStructure;
-									TSTPreviousTabs = browserWindow.TreeStyleTabBookmarksService.getTabsInfo(browserWindow.gBrowser);
+			let (method = (sv.getTreePref('compatibility.TabUtilities') && PlacesUIUtils.TU_openContainerNodeInTabs) ?
+							'TU_openContainerNodeInTabs' :
+							'openContainerNodeInTabs') {
+				eval('PlacesUIUtils.'+method+' = '+
+					PlacesUIUtils[method].toSource().replace(
+						/(this\._openTabset\([^\)]+)(\))/,
+						<![CDATA[
+							let (w = '_getTopBrowserWin' in this ?
+										this._getTopBrowserWin() :
+									'_getCurrentActiveWin' in this ?
+										this._getCurrentActiveWin() :
+										window) {
+								let nodes = w.TreeStyleTabBookmarksService.getItemIdsForContainerNode(aNode);
+								for (let i in nodes) {
+									urlsToOpen[i].id = nodes[i];
 								}
-								else {
-									sv.readyToOpenNewTabGroup(null, treeStructure, TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_EXPAND_ALL_TREE);
-								}
-								replaceCurrentTab = false;
-							}
-							else {
-								replaceCurrentTab = !!(TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_REPLACE);
 							}
-						}
-						$1
+							$1, aNode.title$2
 						]]>
-				).replace(
-					/(\}\)?)$/,
-					<![CDATA[
-						if (TSTTreeStructure && TSTPreviousTabs) {
-							let tabs = browserWindow.TreeStyleTabBookmarksService.getNewTabsFromPreviousTabsInfo(browserWindow.gBrowser, TSTPreviousTabs)
-							browserWindow.TreeStyleTabService.applyTreeStructureToTabs(tabs, TSTTreeStructure, TSTOpenGroupBookmarkBehavior & browserWindow.TreeStyleTabBookmarksService.kGROUP_BOOKMARK_EXPAND_ALL_TREE);
-						}
-					$1]]>
-				)
-			);
+					)
+				);
+				if (sv.getTreePref('compatibility.TabUtilities') && method.indexOf('TU_') > -1)
+					window[method] = PlacesUIUtils[method];
+			}
 
-			eval('PlacesUIUtils.openContainerNodeInTabs = '+
-				PlacesUIUtils.openContainerNodeInTabs.toSource().replace(
-					/(this\._openTabset\([^\)]+)(\))/,
-					<![CDATA[
-						let (w = '_getTopBrowserWin' in this ?
-									this._getTopBrowserWin() :
-								'_getCurrentActiveWin' in this ?
-									this._getCurrentActiveWin() :
-									window) {
-							let nodes = w.TreeStyleTabBookmarksService.getItemIdsForContainerNode(aNode);
-							for (let i in nodes) {
-								urlsToOpen[i].id = nodes[i];
+			let (method = (sv.getTreePref('compatibility.TabUtilities') && PlacesUIUtils.TU_openURINodesInTabs) ?
+							'TU_openURINodesInTabs' :
+							'openURINodesInTabs') {
+				eval('PlacesUIUtils.'+method+' = '+
+					PlacesUIUtils[method].toSource().replace(
+						'{',
+						<![CDATA[{
+							var TSTBS;
+							let (w = '_getTopBrowserWin' in this ?
+										this._getTopBrowserWin() :
+									'_getCurrentActiveWin' in this ?
+										this._getCurrentActiveWin() :
+										window) {
+								TSTBS = w.TreeStyleTabBookmarksService;
 							}
-						}
-						$1, aNode.title$2
-					]]>
-				)
-			);
-
-			eval('PlacesUIUtils.openURINodesInTabs = '+
-				PlacesUIUtils.openURINodesInTabs.toSource().replace(
-					'{',
-					<![CDATA[{
-						var TSTBS;
-						let (w = '_getTopBrowserWin' in this ?
-									this._getTopBrowserWin() :
-								'_getCurrentActiveWin' in this ?
-									this._getCurrentActiveWin() :
-									window) {
-							TSTBS = w.TreeStyleTabBookmarksService;
-						}
-					]]>.toString()
-				).replace(
-					'uri: aNodes[i].uri,',
-					'id: aNodes[i].itemId, $&'
-				).replace(
-					/(this\._openTabset\([^\)]+)(\))/,
-					<![CDATA[$1,
-						TSTBS.treeBundle
-							.getFormattedString(
-								PlacesUtils.nodeIsBookmark(aNodes[0]) ?
-									'openSelectedPlaces.bookmarks' :
-									'openSelectedPlaces.history',
-								[aNodes[0].title, aNodes.length]
-							)
-					$2]]>
-				)
-			);
+						]]>.toString()
+					).replace(
+						'uri: aNodes[i].uri,',
+						'id: aNodes[i].itemId, $&'
+					).replace(
+						/(this\._openTabset\([^\)]+)(\))/,
+						<![CDATA[$1,
+							TSTBS.treeBundle
+								.getFormattedString(
+									PlacesUtils.nodeIsBookmark(aNodes[0]) ?
+										'openSelectedPlaces.bookmarks' :
+										'openSelectedPlaces.history',
+									[aNodes[0].title, aNodes.length]
+								)
+						$2]]>
+					)
+				);
+				if (sv.getTreePref('compatibility.TabUtilities') && method.indexOf('TU_') > -1)
+					window[method] = PlacesUIUtils[method];
+			}
 
 			PlacesUIUtils.__treestyletab__done = true;
 
@@ -381,6 +352,77 @@ var TreeStyleTabBookmarksService = {
 			);
 		}
 	},
+	handleTabsOpenProcess : function TSTBMService_handleTabsOpenProcess(aWhere, aEvent, aBrowserWindow, aIDs, aURLs, aReplaceCurrentTab, aFolderTitle)
+	{
+		var result = {
+				behavior          : undefined,
+				treeStructure     : undefined,
+				previousTabs      : undefined,
+				replaceCurrentTab : undefined
+			};
+		if (
+			aWhere.indexOf('tab') != 0 &&
+			aEvent.target.id != 'placesContext_openContainer:tabs' &&
+			aEvent.target.id != 'placesContext_openLinks:tabs' &&
+			aEvent.target != aEvent.target.parentNode._endOptOpenAllInTabs &&
+			aEvent.target.getAttribute('openInTabs') != 'true'
+			)
+			return result;
+
+		var sv = aBrowserWindow.TreeStyleTabBookmarksService;
+		result.behavior = sv.openGroupBookmarkBehavior();
+		if (result.behavior & sv.kGROUP_BOOKMARK_SUBTREE) {
+			let treeStructure = result.behavior & sv.kGROUP_BOOKMARK_DONT_RESTORE_TREE_STRUCTURE ?
+						null :
+						sv.getTreeStructureFromItems(aIDs) ;
+			if (
+				treeStructure &&
+				result.behavior & sv.kGROUP_BOOKMARK_USE_DUMMY
+				) {
+				let parentCount = 0;
+				let childCount = 0;
+				for (let i in treeStructure) {
+					if (treeStructure[i] == -1)
+						parentCount++;
+					else
+						childCount++;
+				}
+				if (
+					parentCount > 1 &&
+					(
+						result.behavior & sv.kGROUP_BOOKMARK_USE_DUMMY_FORCE ||
+						// when there is any orphan, then all of parents and orphans should be grouped under a dummy tab.
+						childCount < parentCount
+					)
+					) {
+					aIDs.unshift(-1);
+					treeStructure = sv.getTreeStructureFromItems(aIDs, 0);
+					aURLs.unshift(sv.getGroupTabURI(aFolderTitle));
+				}
+			}
+
+			if (sv.getTreePref('compatibility.TMP') &&
+				'TMP_Places' in aBrowserWindow &&
+				'openGroup' in aBrowserWindow.TMP_Places) {
+				result.treeStructure = treeStructure;
+				result.previousTabs = aBrowserWindow.TreeStyleTabBookmarksService.getTabsInfo(aBrowserWindow.gBrowser);
+			}
+			else {
+				sv.readyToOpenNewTabGroup(null, treeStructure, result.behavior & sv.kGROUP_BOOKMARK_EXPAND_ALL_TREE);
+			}
+			// replaceCurrentTab works only on Firefox 7 or earlier
+			// See: https://bugzilla.mozilla.org/show_bug.cgi?id=440093
+			if (typeof aReplaceCurrentTab !== 'undefined')
+				result.replaceCurrentTab = false;
+		}
+		else {
+			if (typeof aReplaceCurrentTab !== 'undefined')
+				result.replaceCurrentTab = !!(result.behavior & sv.kGROUP_BOOKMARK_REPLACE);
+		}
+		return result;
+	},
+
+
 
 	destroy : function TSTBMService_destroy()
 	{
diff --git a/chrome/treestyletab.jar!/content/treestyletab/config.js b/chrome/treestyletab.jar!/content/treestyletab/config.js
index a97a939..f4a055a 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/config.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/config.js
@@ -168,6 +168,16 @@ function initTabPane()
 		newTabPref.removeAttribute('hidden');
 	else
 		newTabPref.setAttribute('hidden', true);
+
+	var bookmarkGroupReplacePref = document.getElementById('openGroupBookmark.replace');
+	if (comparator.compare(XULAppInfo.version, '7.0') > 0) {
+		if (bookmarkGroupReplacePref.selected)
+			document.getElementById('openGroupBookmark.subtree').selected = true;
+		bookmarkGroupReplacePref.setAttribute('hidden', true);
+	}
+	else {
+		bookmarkGroupReplacePref.removeAttribute('hidden');
+	}
 }
 
 function onSyncGroupBookmarkUIToPref()
diff --git a/chrome/treestyletab.jar!/content/treestyletab/config.xul b/chrome/treestyletab.jar!/content/treestyletab/config.xul
index 1b8358f..f764145 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/config.xul
+++ b/chrome/treestyletab.jar!/content/treestyletab/config.xul
@@ -446,7 +446,7 @@
 				onsyncfrompreference="return onSyncGroupBookmarkPrefToUI();"
 				preference="extensions.treestyletab.openGroupBookmark.behavior">
 				<radio value="0" collapsed="true"/>
-				<radio value="1" label="&config.openGroupBookmark.subtree;"/>
+				<radio id="openGroupBookmark.subtree" value="1" label="&config.openGroupBookmark.subtree;"/>
 				<hbox>
 					<spacer style="width:1em;"/>
 					<vbox>
@@ -471,7 +471,8 @@
 					</vbox>
 				</hbox>
 				<radio value="2" label="&config.openGroupBookmark.flat;"/>
-				<radio value="4" label="&config.openGroupBookmark.replace;"/>
+				<radio id="openGroupBookmark.replace"
+					value="4" label="&config.openGroupBookmark.replace;"/>
 			</radiogroup>
 			</vbox>
 		</deck>
diff --git a/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.css b/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.css
index d526cbc..08b03b3 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.css
+++ b/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.css
@@ -14,51 +14,66 @@
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
-:root[tabFx2Compatible="13"]
+:root[tabFx2Compatible="15"]
   .tabbrowser-tab {
 	-moz-binding: url(tabFx2Compatible.xml#tabbrowser-tab-3) !important;
 }
 
-:root[tabFx2Compatible="13"][tabFx2Compatible-flags~="separate-tabContextMenu"]
+:root[tabFx2Compatible="15"][tabFx2Compatible-flags~="separate-tabContextMenu"]
   .tabbrowser-tab {
 	-moz-binding: url(tabFx2Compatible.xml#tabbrowser-tab-4) !important;
 }
 
-:root[tabFx2Compatible="13"]:not([tabFx2Compatible-flags~="png-throbber"])[tabFx2Compatible-flags~="fx3"]
+:root[tabFx2Compatible="15"]:not([tabFx2Compatible-flags~="png-throbber"])[tabFx2Compatible-flags~="fx3"]
   .tab-icon-image[busy] {
 	list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif") !important;
 	opacity: 0.6;
 }
 
-:root[tabFx2Compatible="13"][tabFx2Compatible-flags~="png-throbber"][tabFx2Compatible-flags~="fx3"]
+:root[tabFx2Compatible="15"][tabFx2Compatible-flags~="png-throbber"][tabFx2Compatible-flags~="fx3"]
   .tab-icon-image[busy] {
 	list-style-image: url("chrome://global/skin/icons/loading_16.png") !important;
 }
 
-:root[tabFx2Compatible="13"][tabFx2Compatible-flags~="mac"][tabFx2Compatible-flags~="png-throbber"]
+:root[tabFx2Compatible="15"][tabFx2Compatible-flags~="mac"][tabFx2Compatible-flags~="png-throbber"]
   .tab-icon-image {
 	list-style-image: url("chrome://global/skin/tree/item.png");
 }
+:root[tabFx2Compatible="15"][tabFx2Compatible-flags~="blank-favicon"]
+  .tab-icon-image {
+	list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
 
-:root[tabFx2Compatible="13"][tabFx2Compatible-flags~="mac"]
+:root[tabFx2Compatible="15"][tabFx2Compatible-flags~="mac"]
   .tabbrowser-tab:not(:hover) .tab-icon-image:not([selected="true"]) {
 	opacity: 0.6;
 }
 
-:root[tabFx2Compatible="13"]
+:root[tabFx2Compatible="15"]
   .tabbrowser-tab:focus > .tab-image-middle {
 	outline: 1px dotted;
 }
 /* we must split declarations for old Gecko */
-:root[tabFx2Compatible="13"]
+:root[tabFx2Compatible="15"]
   .tabbrowser-tab:-moz-focusring > .tab-stack {
 	outline: 1px dotted;
 }
 
 
-:root[tabFx2Compatible="13"]
+:root[tabFx2Compatible="15"]
   .tab-image-left[pinned="true"],
-:root[tabFx2Compatible="13"]
+:root[tabFx2Compatible="15"]
   .tab-image-right[pinned="true"] {
 	display: none !important;
 }
+
+/* Tab Utilities */
+:root[tabFx2Compatible="15"]
+  .tabbrowser-tabs[highlightLocked][highlightSelected][highlightUnread]
+  > .tabbrowser-tab .tab-icon > .tab-icon-image ~ *,
+:root[tabFx2Compatible="15"]
+  .tabbrowser-tabs[highlightlocked][highlightselected][highlightunread]
+  > .tabbrowser-tab .tab-icon > .tab-icon-image ~ * {
+	background: none !important;
+}
+
diff --git a/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.xul b/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.xul
index 2845e10..b8477e5 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.xul
+++ b/chrome/treestyletab.jar!/content/treestyletab/res/tabFx2Compatible.xul
@@ -19,7 +19,7 @@
 window.addEventListener('DOMContentLoaded', function() {
 	window.removeEventListener('DOMContentLoaded', arguments.callee, true);
 
-	const currentRevision = 13;
+	const currentRevision = 15;
 
 	var b = document.getElementById('content');
 	if (!b || b.localName != 'tabbrowser') return;
@@ -79,6 +79,8 @@ window.addEventListener('DOMContentLoaded', function() {
 				flags.push('png-throbber');
 			if (Comparator.compare(XULAppInfo.version, '4.0b1') >= 0)
 				flags.push('separate-tabContextMenu');
+			if (Comparator.compare(XULAppInfo.version, '7.0') > 0)
+				flags.push('blank-favicon');
 			else
 				flags.push('fx3');
 			root.setAttribute('tabFx2Compatible-flags', flags.join(' '));
diff --git a/chrome/treestyletab.jar!/content/treestyletab/res/tabsDragUtils.js b/chrome/treestyletab.jar!/content/treestyletab/res/tabsDragUtils.js
index 3e1bbaf..128e142 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/res/tabsDragUtils.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/res/tabsDragUtils.js
@@ -13,7 +13,7 @@
    http://github.com/piroor/fxaddonlibs/blob/master/tabsDragUtils.js
 */
 (function() {
-	const currentRevision = 16;
+	const currentRevision = 17;
 
 	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
 
@@ -30,6 +30,7 @@
 
 	const Cc = Components.classes;
 	const Ci = Components.interfaces;
+	const TAB_DROP_TYPE = 'application/x-moz-tabbrowser-tab';
 
 	var tabsDragUtils = {
 		revision : currentRevision,
diff --git a/chrome/treestyletab.jar!/content/treestyletab/treestyletab.css b/chrome/treestyletab.jar!/content/treestyletab/treestyletab.css
index aed52c4..0ff4a00 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/treestyletab.css
+++ b/chrome/treestyletab.jar!/content/treestyletab/treestyletab.css
@@ -99,14 +99,14 @@ tabbrowser[treestyletab-tabbar-autohide-mode="1"][treestyletab-tabbar-autohide="
 }
 
 /* put resizer under tabs, and raise up tabs */
-.treestyletab-tabbar-toolbar[treestyletab-mode="vertical"][treestyletab-tabbar-autohide][treestyletab-tabbar-autohide-state="expanded"]
+.treestyletab-tabbar-toolbar[treestyletab-mode="vertical"][treestyletab-tabbar-autohide]
   > *,
-.treestyletab-toolbar-inner-box[treestyletab-tabbar-autohide][treestyletab-tabbar-autohide-state="expanded"]:not([treestyletab-tabbar-fixed="true"])
+.treestyletab-toolbar-inner-box[treestyletab-tabbar-autohide]:not([treestyletab-tabbar-fixed="true"])
   > * {
 	position: relative;
 	z-index: 2;
 }
-.treestyletab-tabbar-toolbar[treestyletab-mode="vertical"][treestyletab-tabbar-autohide][treestyletab-tabbar-autohide-state="expanded"]
+.treestyletab-tabbar-toolbar[treestyletab-mode="vertical"][treestyletab-tabbar-autohide]
   #treestyletab-tabbar-resizer-box {
 	position: absolute;
 	bottom: 0;
@@ -446,13 +446,19 @@ toolbar.treestyletab-tabbar-toolbar-ready:not([nowindowdrag="true"]),
 
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab[pinned="true"] {
-	height: 24px;
+	/* height: 24px; */
 	line-height: 0;
 	position: fixed !important;
-	width: 24px;
+	/* width: 24px; */
 	z-index: 100;
 }
 
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab[pinned="true"]:not(.treestyletab-faviconized)
+  .tab-label[pinned] {
+	width: auto;
+}
+
 /* print preview */
 .tabbrowser-strip[treestyletab-tabbar-fixed="true"]+splitter,
 .tabbrowser-strip[treestyletab-print-preview="true"],
@@ -507,3 +513,4 @@ image.tab-icon {
 :root:not([treestyletab-tabbar-fixed="true"]) #ctStack {
 	display: none;
 }
+
diff --git a/chrome/treestyletab.jar!/content/treestyletab/windowHelper.js b/chrome/treestyletab.jar!/content/treestyletab/windowHelper.js
index 7e8909b..29438f8 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/windowHelper.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/windowHelper.js
@@ -187,17 +187,26 @@ var TreeStyleTabWindowHelper = {
 			'loadSearch' in BrowserSearch) {
 			eval('BrowserSearch.loadSearch = '+
 				BrowserSearch.loadSearch.toSource().replace(
+					// for old Firefox 4 and olders
 					'if (useNewTab) {',
 					<![CDATA[$&
 						if (TreeStyleTabService.shouldOpenSearchResultAsChild(arguments[0]))
 							TreeStyleTabService.readyToOpenChildTab();
 					]]>
+				).replace(
+					// for Firefox 5 and later
+					'openLinkIn(',
+					<![CDATA[
+						if (useNewTab && TreeStyleTabService.shouldOpenSearchResultAsChild(arguments[0]))
+							TreeStyleTabService.readyToOpenChildTab();
+					$&]]>
 				)
 			);
 		}
 
 		this._splitFunctionNames(<![CDATA[
 			window.duplicateTab.handleLinkClick
+			window.duplicatethistab.handleLinkClick
 			window.__treestyletab__highlander__origHandleLinkClick
 			window.__splitbrowser__handleLinkClick
 			window.__ctxextensions__handleLinkClick
@@ -258,6 +267,9 @@ var TreeStyleTabWindowHelper = {
 			window.duplicateTab.gotoHistoryIndex
 			window.duplicateTab.BrowserBack
 			window.duplicateTab.BrowserForward
+			window.duplicatethistab.gotoHistoryIndex
+			window.duplicatethistab.BrowserBack
+			window.duplicatethistab.BrowserForward
 			window.__rewindforward__BrowserForward
 			window.__rewindforward__BrowserBack
 			window.gotoHistoryIndex
diff --git a/chrome/treestyletab.jar!/content/treestyletab/windowHelperHacks.js b/chrome/treestyletab.jar!/content/treestyletab/windowHelperHacks.js
index 6ca5adf..117fea0 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/windowHelperHacks.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/windowHelperHacks.js
@@ -539,12 +539,18 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 				{
 					switch (aEvent.type)
 					{
+						case 'TabOpen':
 						case 'TreeStyleTabAttached':
 						case 'TreeStyleTabParted':
 							var child = aEvent.originalTarget;
 							var parent = aEvent.parentTab;
 							if (child && parent) {
-								colorfulTabs.setColor(child, TreeStyleTabService.SessionStore.getTabValue(parent, 'tabClr'));
+								let color = TreeStyleTabService.SessionStore.getTabValue(parent, 'tabClr');
+								if (/^\d+,\d+,\d+$/.test(color))
+									color = 'rgb('+color+')';
+								window.setTimeout(function() {
+									colorfulTabs.setColor(child, color);
+								}, 0);
 							}
 							else if (child) {
 								TreeStyleTabService.SessionStore.setTabValue(child, 'tabClr', '');
@@ -556,6 +562,7 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 							break;
 
 						case 'unload':
+							document.removeEventListener('TabOpen', this, false);
 							document.removeEventListener('TreeStyleTabAttached', this, false);
 							document.removeEventListener('TreeStyleTabParted', this, false);
 							document.removeEventListener('unload', this, false);
@@ -569,6 +576,7 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 				'.display = ""'
 			)
 		);
+		document.addEventListener('TabOpen', listener, false);
 		document.addEventListener('TreeStyleTabAttached', listener, false);
 		document.addEventListener('TreeStyleTabParted', listener, false);
 		document.addEventListener('unload', listener, false);
@@ -667,15 +675,57 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 
 	// Greasemonkey
 	// https://addons.mozilla.org/firefox/addon/748
-	if ('GM_BrowserUI' in window &&
-		'openInTab' in GM_BrowserUI &&
-		sv.getTreePref('compatibility.Greasemonkey')) {
-		eval('GM_BrowserUI.openInTab = '+
-			GM_BrowserUI.openInTab.toSource().replace(
-				/(if\s*\(this\.isMyWindow\([^\)]+\)\)\s*\{\s*)(this\.tabBrowser)/,
-				'$1 TreeStyleTabService.readyToOpenChildTab($2); $2'
-			)
-		);
+	if (sv.getTreePref('compatibility.Greasemonkey')) {
+		try {
+			let hitchModule = Components.utils.import('resource://greasemonkey/util/hitch.js', {});
+			let hitch = hitchModule.hitch;
+			if (hitch.toSource().indexOf('TreeStyleTabService') < 0) {
+				hitchModule.hitch = function(aObject, aMethod) {
+					if (typeof aMethod == 'function' &&
+						aMethod.toSource().indexOf('function openInTab') > -1) {
+						let originalOpenInTab = aMethod;
+						/**
+						 * This function must be replaced on scripts in "chrome:" URL, like this.
+						 * Otherwise the original openInTab() will raise violation error.
+						 * Don't move this hack into JS code modules with "resource:" URL.
+						 */
+						aMethod = function openInTab(aSafeContentWindow, aChromeWindow, aURL, aLoadInBackgtound) {
+							if (aChromeWindow.TreeStyleTabService)
+								aChromeWindow.TreeStyleTabService.readyToOpenChildTabNow(aSafeContentWindow);
+							return originalOpenInTab.apply(this, arguments);
+						};
+					}
+					return hitch.apply(this, arguments);
+				};
+			}
+		}
+		catch(e) {
+			dump(e+'\n');
+
+			// hacks for old versions
+			if ('GM_BrowserUI' in window && 'openInTab' in GM_BrowserUI) {
+				eval('GM_BrowserUI.openInTab = '+
+					GM_BrowserUI.openInTab.toSource().replace(
+						/(if\s*\(this\.isMyWindow\([^\)]+\)\)\s*\{\s*)(this\.tabBrowser)/,
+						'$1 TreeStyleTabService.readyToOpenChildTab($2); $2'
+					)
+				);
+			}
+			else if ('@greasemonkey.mozdev.org/greasemonkey-service;1' in Components.classes) {
+				let service = Components.classes['@greasemonkey.mozdev.org/greasemonkey-service;1'].getService().wrappedJSObject;
+				if (service && service.__proto__._openInTab) {
+					let _openInTab = service.__proto__._openInTab;
+					if (_openInTab.toSource().indexOf('TreeStyleTabService') < 0) {
+						service.__proto__._openInTab = function() {
+							let contentWindow = arguments[0];
+							let chromeWindow = arguments[1];
+							chromeWindow.TreeStyleTabService.readyToOpenChildTabNow(contentWindow);
+							return _openInTab.apply(this, arguments);
+						};
+					}
+				}
+			}
+		}
 	}
 
 	// SBM Counter
@@ -706,15 +756,25 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 	// https://addons.mozilla.org/firefox/addon/4336
 	// Snap Links Plus
 	// http://snaplinks.mozdev.org/
-	if ('executeAction' in window &&
-		'openTabs' in window &&
-		sv.getTreePref('compatibility.SnapLinks')) {
-		eval('window.openTabs = '+
-			window.openTabs.toSource().replace(
-				/((sContent|gBrowser|getBrowser\(\))\.addTab)/,
-				'TreeStyleTabService.readyToOpenChildTab($2); $1'
-			)
-		);
+	if (sv.getTreePref('compatibility.SnapLinks')) {
+		if ('executeAction' in window &&
+			'openTabs' in window) {
+			eval('window.openTabs = '+
+				window.openTabs.toSource().replace(
+					/((sContent|gBrowser|getBrowser\(\))\.addTab)/,
+					'TreeStyleTabService.readyToOpenChildTab($2); $1'
+				)
+			);
+		}
+		if ('SnapLinks' in window &&
+			'OpenTabs' in SnapLinks) {
+			eval('SnapLinks.OpenTabs = '+
+				SnapLinks.OpenTabs.toSource().replace(
+					/((sContent|gBrowser|getBrowser\(\))\.addTab)/,
+					'TreeStyleTabService.readyToOpenChildTab($2); $1'
+				)
+			);
+		}
 	}
 
 	// Mouseless Browsing
@@ -1085,6 +1145,32 @@ TreeStyleTabWindowHelper.overrideExtensionsAfterBrowserInit = function TSTWH_ove
 		}
 	}
 
+	// InstaClick
+	// https://addons.mozilla.org/firefox/addon/instaclick/
+	if ('instaclick' in window &&
+		'contentAreaClick2' in window.instaclick &&
+		sv.getTreePref('compatibility.InstaClick')) {
+		eval('instaclick.contentAreaClick2 = '+
+			instaclick.contentAreaClick2.toSource().replace(
+				'gBrowser.loadOneTab(',
+				'TreeStyleTabService.readyToOpenChildTab(); $&'
+			)
+		);
+	}
+
+	// Duplicate This Tab
+	// https://addons.mozilla.org/firefox/addon/duplicate-this-tab/
+	if ('duplicatethistab' in window &&
+		'openLinkWithHistory' in window.duplicatethistab &&
+		sv.getTreePref('compatibility.DuplicateThisTab')) {
+		eval('duplicatethistab.openLinkWithHistory = '+
+			duplicatethistab.openLinkWithHistory.toSource().replace(
+				'var newTab = ',
+				'TreeStyleTabService.readyToOpenChildTab(); $&'
+			)
+		);
+	}
+
 	window.setTimeout(function(aSelf) {
 		aSelf.overrideExtensionsDelayed();
 	}, 0, this);
diff --git a/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/license.txt b/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/license.txt
index 3512ccb..ed97cf4 100755
--- a/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/license.txt
+++ b/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/license.txt
@@ -19,6 +19,7 @@ the Initial Developer. All Rights Reserved.
 
 Contributor(s): HkYtrewq <hkytrewq at gmail.com>
                 Tsprajna <oceant.adsl at msa.hinet.net>
+                bootleq <bootleq 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
diff --git a/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.dtd b/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.dtd
index 6dd4763..3370cd3 100755
--- a/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.dtd
+++ b/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.dtd
@@ -1,4 +1,4 @@
-<!ENTITY config.title        "樹狀分頁設定">
+<!ENTITY config.title        "Tree Style Tab 設定">
 
 <!ENTITY config.scale.min "小">
 <!ENTITY config.scale.max "大">
@@ -7,166 +7,154 @@
 <!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.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      "Narrow scrollbar">
+<!ENTITY config.tabbar.invertTab            "左右掉換分頁縮進方向">
+<!ENTITY config.tabbar.invertTabContents    "左右掉換分頁內容">
+<!ENTITY config.tabbar.narrowScrollbar      "較窄的側邊欄">
 <!ENTITY config.enableSubtreeIndent         "縮進分頁">
-<!ENTITY config.maxTreeLevel.before "until">
-<!ENTITY config.maxTreeLevel.after  "level(s)">
+<!ENTITY config.maxTreeLevel.before "(最多">
+<!ENTITY config.maxTreeLevel.after  "層)">
 <!ENTITY config.allowSubtreeCollapseExpand  "允許摺疊 / 展開樹狀子目錄">
 <!ENTITY config.tabbar.hideAlltabsButton    "顯示「列出所有分頁」按鈕">
 
 
-<!ENTITY config.tabs.style "Style">
+<!ENTITY config.tabs.style "樣式">
 
-<!ENTITY config.tabbar.style.caption "分頁工具列的外觀">
-<!ENTITY config.tabbar.style.plain   "ç°¡æ½”">
+<!ENTITY config.tabbar.style.caption "分頁工具列樣式">
+<!ENTITY config.tabbar.style.plain   "Plain">
 <!ENTITY config.tabbar.style.flat    "Flat">
-<!ENTITY config.tabbar.style.mixed   "混合">
+<!ENTITY config.tabbar.style.mixed   "Mixed">
 <!ENTITY config.tabbar.style.vertigo "Vertigo">
-<!ENTITY config.tabbar.style.metal   "金屬">
+<!ENTITY config.tabbar.style.metal   "Metal">
 <!ENTITY config.tabbar.style.sidebar "Sidebar">
-<!ENTITY config.tabbar.style.none    "預設 (由主題自行指定)">
+<!ENTITY config.tabbar.style.none    "無(由佈景主題指定)">
 
 <!ENTITY config.twisty.style.caption "摺疊 / 展開的圖示">
 <!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.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.show.tabContextMenu.caption "新增以下項目到分頁的右鍵選單">
 
 
-<!ENTITY config.tabs.tab "New Tabs">
-<!--ENTITY config.tabs.tab "分頁操作"-->
+<!ENTITY config.tabs.tab "新分頁">
 
-<!ENTITY config.autoAttach.newTabCommand.label_before "Open new blank tab as">
-<!ENTITY config.autoAttach.newTabCommand.independent "an independent tab">
-<!ENTITY config.autoAttach.newTabCommand.child       "a child of the current tab">
-<!ENTITY config.autoAttach.newTabCommand.sibling     "a sibling of the current tab">
-<!ENTITY config.autoAttach.newTabCommand.nextSibling "the next sibling of the current tab">
-<!ENTITY config.autoAttach.newTabCommand.label_after "">
+<!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 "For middle click on the "New Tab" button, open new blank tab as">
-<!ENTITY config.autoAttach.newTabButton.independent "an independent tab">
-<!ENTITY config.autoAttach.newTabButton.child       "a child of the current tab">
-<!ENTITY config.autoAttach.newTabButton.sibling     "a sibling of the current tab">
-<!ENTITY config.autoAttach.newTabButton.nextSibling "the next sibling of the current tab">
+<!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 "For middle click on the "Reload" button, duplicate the tab as">
-<!ENTITY config.autoAttach.duplicateTabCommand.independent "an independent tab">
-<!ENTITY config.autoAttach.duplicateTabCommand.child       "a child of the source tab">
-<!ENTITY config.autoAttach.duplicateTabCommand.sibling     "a sibling of the source tab">
-<!ENTITY config.autoAttach.duplicateTabCommand.nextSibling "the next sibling of the source tab">
+<!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 "For middle click on the "Go" button, open new tab as">
-<!ENTITY config.autoAttach.goButton.independent "an independent tab">
-<!ENTITY config.autoAttach.goButton.child       "a child of the current tab">
-<!ENTITY config.autoAttach.goButton.sibling     "a sibling of the current tab">
-<!ENTITY config.autoAttach.goButton.nextSibling "the next sibling of the current tab">
+<!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.caption   "按書籤資料夾的「全部開啟」時"-->
+<!ENTITY config.openGroupBookmark.caption     "按書籤資料夾的「全部用分頁開啟」時">
 <!ENTITY config.openGroupBookmark.ask         "每次都問我">
-<!ENTITY config.openGroupBookmark.subtree     "用一個子樹開啟(推薦)">
-<!ENTITY config.openGroupBookmark.subtree.type.before  "">
-<!ENTITY config.openGroupBookmark.subtree.type.restore "Restore">
-<!ENTITY config.openGroupBookmark.subtree.type.flat    "Ignore">
-<!ENTITY config.openGroupBookmark.subtree.type.after   "tree structure of tabs saved to bookmarks">
-<!ENTITY config.openGroupBookmark.flat        "用分開的分頁開啟(Firefox 預設)">
+<!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.replace     "將目前瀏覽的分頁取代為書籤的內容">
-<!ENTITY config.openGroupBookmark.underParent "將各分頁開啟於一虛分頁之下以便分組">
+<!ENTITY config.openGroupBookmark.underParent "開啟於一個分組用的父分頁下">
 
-<!ENTITY config.dropLinksOnTab.caption "Dropped link, URL, bookmark or file to existing tab">
-<!ENTITY config.dropLinksOnTab.ask     "Always ask me how to load it">
-<!ENTITY config.dropLinksOnTab.load    "Load in the tab (Firefox default)">
-<!ENTITY config.dropLinksOnTab.newTab  "Open as a new child tab">
-<!--
-<!ENTITY config.dropLinksOnTab.caption "拖曳鏈結或 URL 到現有的分頁時">
-<!ENTITY config.dropLinksOnTab.ask     "每次都問我">
-<!ENTITY config.dropLinksOnTab.load    "在拖曳目的地分頁載入鏈結(Firefox 預設)">
-<!ENTITY config.dropLinksOnTab.newTab  "用拖曳目的地分頁之下的新子分頁開啟鏈結">
--->
+<!ENTITY config.dropLinksOnTab.caption "拖曳鏈結、URL 或書籤到現存分頁時">
+<!ENTITY config.dropLinksOnTab.ask     "每次都問我怎麼載入">
+<!ENTITY config.dropLinksOnTab.load    "在該分頁載入鏈結(Firefox 預設)">
+<!ENTITY config.dropLinksOnTab.newTab  "開啟為新的子分頁">
 
 
 <!ENTITY config.tabs.autohide "自動隱藏">
 
-<!ENTITY config.autoHide.mode.normal.caption     "for Normal Window Mode">
-<!ENTITY config.autoHide.mode.fullscreen.caption "for Full Screen Mode">
+<!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.autoShow.caption "在以下情況自動顯示分頁工具列">
+<!ENTITY config.autoShow.mousemove "滑鼠指標接近分頁工具列邊緣">
+<!ENTITY config.autoHide.area.before "感應區:距離分頁工具列">
 <!ENTITY config.autoHide.area.after "個像素的範圍">
-<!--
-<!ENTITY config.autoShow.mousemove.mode2 "滑鼠指標指在分頁工具列邊緣">
-<!ENTITY config.autoHide.area.before.mode2 "感應區:">
-<!ENTITY config.autoHide.area.after.mode2 "像素(距分頁工具列內緣)">
--->
 <!ENTITY config.autoHide.delay.before "延遲:">
 <!ENTITY config.autoHide.delay.after "毫秒">
-<!ENTITY config.autoShow.accelKeyDown "按下 Ctrl一段時間後">
+<!ENTITY config.autoShow.accelKeyDown "按下 Ctrl 一段時間後">
 <!ENTITY config.autoShow.accelKeyDown.delay.before "">
 <!ENTITY config.autoShow.accelKeyDown.delay.after  "毫秒以上才顯示">
-<!ENTITY config.autoShow.tabSwitch   "用 Ctrl+Tab 切換分頁時">
+<!ENTITY config.autoShow.tabSwitch   "用 Ctrl-Tab 切換分頁時">
 <!ENTITY config.autoShow.feedback    "開新分頁或關閉分頁時">
 <!ENTITY config.autoShow.feedback.delay.before "">
-<!ENTITY config.autoShow.feedback.delay.after  "毫秒後就自動隱藏">
+<!ENTITY config.autoShow.feedback.delay.after  "毫秒後自動隱藏">
 
 
 <!ENTITY config.tabs.tree "樹狀結構">
 
-<!--ENTITY config.autoCollapseExpandSubtreeOnSelect "當開新分頁或切換分頁時,自動摺疊無關的子樹"-->
-<!ENTITY config.autoCollapseExpandSubtreeOnSelect "切換分頁時,自動展開該子樹並摺疊無關者">
-<!ENTITY config.autoCollapseExpandSubtreeOnSelect.onCurrentTabRemove "不包括因關閉當前分頁而造成的切換">
+<!ENTITY config.autoCollapseExpandSubtreeOnSelect "切換分頁時,自動展開該子樹,並摺疊無關的分頁">
+<!ENTITY config.autoCollapseExpandSubtreeOnSelect.onCurrentTabRemove "不包括關閉當前分頁造成的切換">
+
+<!ENTITY config.focusMode "用 Ctrl-Tab 切換分頁時,已摺疊的分頁也可切換">
+
 <!ENTITY config.collapseExpandSubtree.dblclick "按兩下分頁開關子樹">
 <!ENTITY config.autoExpandSubtreeOnAppendChild "當新增分頁到子樹時,自動展開子樹">
 
-<!ENTITY config.closeParentBehavior.caption "當關閉親分頁時">
+<!ENTITY config.closeParentBehavior.caption "關閉父分頁時">
 <!ENTITY config.closeParentBehavior.close   "一併關閉所屬子分頁">
-<!ENTITY config.closeParentBehavior.promoteFirst "提升第一子分頁到親分頁所在位階">
-<!ENTITY config.closeParentBehavior.promoteAll   "所有子分頁都提升到親分頁所在位階">
+<!ENTITY config.closeParentBehavior.promoteFirst "提升第一個子分頁到父分頁所在階層">
+<!ENTITY config.closeParentBehavior.promoteAll   "所有子分頁都提升到父分頁所在階層">
 <!ENTITY config.closeParentBehavior.detach  "從該樹釋放所屬子分頁">
-<!ENTITY config.closeRootBehavior.promoteFirst   "若親分頁上無親分頁,則提升第一子分頁成為親分頁">
+<!ENTITY config.closeRootBehavior.promoteFirst   "只有關閉最頂層的父分頁時,才提升第一子分頁為父分頁">
 
-<!ENTITY config.focusMode "用 Ctrl+Tab 切換分頁時,即使是摺疊了的分頁也切換">
 
 <!ENTITY config.insertNewChildAt.caption "開啟新子分頁的位置">
-<!ENTITY config.insertNewChildAt.first "插入到子樹的開端">
-<!ENTITY config.insertNewChildAt.last "新增到子樹的末端">
+<!ENTITY config.insertNewChildAt.first "子樹的前端">
+<!ENTITY config.insertNewChildAt.last "子樹的末端">
 
-<!ENTITY config.undoCloseTabSet.caption  "When a member of a tree is restored by "Undo Close Tab"">
-<!ENTITY config.undoCloseTabSet.ask      "Ask me always">
-<!ENTITY config.undoCloseTabSet.set      "Restore whole of the tree">
-<!ENTITY config.undoCloseTabSet.separate "Restore only one tab (Firefox default)">
+<!ENTITY config.undoCloseTabSet.caption  "「Undo Close Tab」復原樹狀結構分頁時">
+<!ENTITY config.undoCloseTabSet.ask      "每次都問我">
+<!ENTITY config.undoCloseTabSet.set      "復原整個樹結構">
+<!ENTITY config.undoCloseTabSet.separate "只復原一個分頁(Firefox 預設)">
 
 
 <!ENTITY config.tabs.advanced "進階">
 
 <!ENTITY config.animation.enabled "啟用動畫效果">
 
-<!ENTITY config.tooltip.includeChildren        "於頁籤提示方塊中顯示該樹的內容">
+<!ENTITY config.tooltip.includeChildren        "於分頁提示方塊中顯示樹的內容">
 
-<!ENTITY config.bookmarkDroppedTabs.caption "Action for drag and drop of a parent tab to the bookmarks tree">
-<!ENTITY config.bookmarkDroppedTabs.ask     "Ask me always">
-<!ENTITY config.bookmarkDroppedTabs.all     "Bookmark all tabs in the tree">
-<!ENTITY config.bookmarkDroppedTabs.parent  "Bookmark only the dragged one tab">
+<!ENTITY config.bookmarkDroppedTabs.caption "拖曳父分頁到書籤時">
+<!ENTITY config.bookmarkDroppedTabs.ask     "每次都問我">
+<!ENTITY config.bookmarkDroppedTabs.all     "將樹中的所有分頁加入書籤">
+<!ENTITY config.bookmarkDroppedTabs.parent  "只將拖曳的分頁加入書籤">
 
 
 
@@ -183,17 +171,17 @@
 <!ENTITY context.removeTabSubtree.accesskey "s">
 <!ENTITY context.removeDescendantTabs.label     "關閉所有子分頁">
 <!ENTITY context.removeDescendantTabs.accesskey "d">
-<!ENTITY context.removeAllTabsBut.label         "Close Other Tabs except this Tree">
+<!ENTITY context.removeAllTabsBut.label         "關閉除了此樹以外的所有分頁">
 <!ENTITY context.removeAllTabsBut.accesskey     "a">
-<!ENTITY context.collapseAllSubtree.label     "摺疊全部樹狀目錄">
+<!ENTITY context.collapseAllSubtree.label     "摺疊全部樹目錄">
 <!ENTITY context.collapseAllSubtree.accesskey "c">
-<!ENTITY context.expandAllSubtree.label     "展開全部樹狀目錄">
+<!ENTITY context.expandAllSubtree.label     "展開全部樹目錄">
 <!ENTITY context.expandAllSubtree.accesskey "e">
 <!ENTITY context.toggleAutoHide.label     "自動隱藏分頁工具列">
 <!ENTITY context.toggleAutoHide.accesskey "h">
-<!ENTITY context.toggleFixed.label            "固定分頁工具列的位置/寬高">
-<!ENTITY context.toggleFixed.label.horizontal "固定分頁工具列的位置/高度">
-<!ENTITY context.toggleFixed.label.vertical   "固定分頁工具列的位置/寬度">
+<!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">
diff --git a/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.properties b/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.properties
index 26a290c..fef6a63 100755
--- a/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.properties
+++ b/chrome/treestyletab.jar!/locale/zh-TW/treestyletab/treestyletab.properties
@@ -5,45 +5,45 @@ tooltip.expandSubtree.labeled=展開此樹:\n%S
 tooltip.closeTree=關閉此樹
 tooltip.item.label=%2$S* %1$S
 
-dropLinkOnTab.title=要如何開啟拖曳的鏈結?
-dropLinkOnTab.text=有一個鏈結被拖曳到現有的分頁了.「樹狀分頁」可將此鏈結以新增子分頁開啟. 您打算怎樣處理?
-dropLinkOnTab.never=不要再問我, 以後都照此例辦理
-dropLinkOnTab.loadInTheTab=就此分頁載入 (Firefox預設)
-dropLinkOnTab.openNewChildTab=新增子分頁開啟
-
-openGroupBookmarkBehavior.title=要如何開啟複數書籤?
-openGroupBookmarkBehavior.text=即將以複數分頁開啟這些書籤. 您打算怎樣處理?
-openGroupBookmarkBehavior.never=不要再問我, 以後都照此例辦理
+dropLinkOnTab.title=如何開啟拖曳的鏈結?
+dropLinkOnTab.text=有一個鏈結被拖曳到目前分頁。Tree Style Tab 可將此鏈結開啟為新的子分頁,您打算怎麼處理?
+dropLinkOnTab.never=不要再問我,以後都照此辦理
+dropLinkOnTab.loadInTheTab=直接在此分頁載入(Firefox 預設)
+dropLinkOnTab.openNewChildTab=開啟為子分頁
+
+openGroupBookmarkBehavior.title=如何開啟複數書籤?
+openGroupBookmarkBehavior.text=即將以複數分頁開啟這些書籤,您打算怎樣處理?
+openGroupBookmarkBehavior.never=不要再問我,以後都照此辦理
 openGroupBookmarkBehavior.subTree=以新樹開啟
-openGroupBookmarkBehavior.separate=各用一新分頁開啟 (Firefox預設)
-openGroupBookmarkBehavior.replace=取代目前瀏覽的分頁
+openGroupBookmarkBehavior.separate=各用一新分頁開啟(Firefox 預設)
+openGroupBookmarkBehavior.replace=取代目前分頁
 
-bookmarkDroppedTabs.title=How to bookmark a tree of tabs?
-bookmarkDroppedTabs.text=The dragged tab has children. How to bookmark them?
-bookmarkDroppedTabs.never=Never ask me again
-bookmarkDroppedTabs.bookmarkAll=Bookmark All Tabs in the tree
-bookmarkDroppedTabs.bookmarkOnlyParent=Bookmark the Parent Tab Only.
+bookmarkDroppedTabs.title=如何將樹加入書籤?
+bookmarkDroppedTabs.text=拖曳的分頁含有子分頁,要如何加入書籤?
+bookmarkDroppedTabs.never=不要再問我,以後都照此辦理
+bookmarkDroppedTabs.bookmarkAll=將所有分頁加為書籤
+bookmarkDroppedTabs.bookmarkOnlyParent=只加入父分頁
 
-undoCloseTabSetBehavior.label=Do you want following %S tab(s) to be restored along?
-undoCloseTabSetBehavior.never=Never ask me again
-undoCloseTabSetBehavior.set=Restore tabs
-undoCloseTabSetBehavior.separate=No thank you
+undoCloseTabSetBehavior.label=您要一併復原以下 %S 個同時關閉的分頁嗎?
+undoCloseTabSetBehavior.never=不要再問我,以後都照此辦理
+undoCloseTabSetBehavior.set=全部復原
+undoCloseTabSetBehavior.separate=不,謝謝
 
-openSelectedPlaces.bookmarks=始於書籤 %2$S, 亦含括"%1$S"
-openSelectedPlaces.history=始於歷史項 %2$S, 亦含括"%1$S"
+openSelectedPlaces.bookmarks=始於包含 %1$S 的 %2$S 個書籤
+openSelectedPlaces.history=始於包含 %1$S 的 %2$S 個歷史項目
 
-bookmarkProperty.parent.label=親分頁:
-bookmarkProperty.parent.blank.label=(無題)
+bookmarkProperty.parent.label=父分頁:
+bookmarkProperty.parent.blank.label=(無)
 bookmarkProperty.parent.current.label=[ %S ]
 
-undo_changeTabbarPosition_label=Change the position of the tab bar
+undo_changeTabbarPosition_label=變更分頁工具列的位置
 
-toolbarCustomizing_tabbar_horizontal=This toolbar becomes a tab bar.
-toolbarCustomizing_tabbar_vertical=This toolbar becomes a vertical tab bar.
+toolbarCustomizing_tabbar_horizontal=將這個工具列變為分頁工具列。
+toolbarCustomizing_tabbar_vertical=將這個工具列變為垂直的分頁工具列。
 
 
-compatibility_STM_warning_title=Super Tab Mode collides with Tree Style Tab
-compatibility_STM_warning_text=New tabs opened from links (or others) don't become child of the current tab, because the position of new tabs is controlled by Super Tab Mode. Which feature do you want to be enabled?\n(*You can change those settings manually by the configuration dialog of Super Tab Mode.)
-compatibility_STM_warning_use_TST=Make tabs children of the current tab
-compatibility_STM_warning_use_STM=Put tabs to the position specified by Super Tab Mode
-compatibility_STM_warning_never=Don't show this dialo anymore.
+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=不要再問我
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/metal/base.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/metal/base.css
index 7196074..f5899a0 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/metal/base.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/metal/base.css
@@ -128,7 +128,11 @@ tabbrowser[treestyletab-tabbar-position="right"]
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab
   .tab-icon
-  .tab-icon-image {
+  .tab-icon-image,
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab
+  .tab-icon
+  .tab-throbber {
 	width: 16px !important;
 	height: 16px !important;
 	margin: 0 0 0 6px !important;
@@ -136,7 +140,11 @@ tabbrowser[treestyletab-tabbar-position="right"]
 .tabbrowser-tabs[treestyletab-tab-contents-inverted="true"]
   .tabbrowser-tab
   .tab-icon
-  .tab-icon-image {
+  .tab-icon-image,
+.tabbrowser-tabs[treestyletab-tab-contents-inverted="true"]
+  .tabbrowser-tab
+  .tab-icon
+  .tab-throbber {
 	margin: 0 6px 0 0 !important;
 }
 
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/base.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/base.css
index 839fd4b..3ca991c 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/base.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/base.css
@@ -14,6 +14,11 @@
 	background: transparent !important;
 	background-color: #d4dde5 !important;
 }
+/* autohide */
+.treestyletab-tabbar-toolbar[treestyletab-tabbar-autohide][treestyletab-mode="vertical"]
+  #treestyletab-tabbar-resizer-box {
+	background: rgba(212, 221, 229, 0.75);
+}
 
 /* Don't display unnecessary clutter */
 .tabbrowser-tabs[treestyletab-mode="vertical"]
@@ -125,7 +130,10 @@ tabbrowser[treestyletab-mode="vertical"]
 /* Always display the favicon at 100% opacity */
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab:not(:hover):not([selected="true"])
-  .tab-icon-image {
+  .tab-icon-image,
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab:not(:hover):not([selected="true"])
+  .tab-throbber {
 	opacity: 1.0 !important;
 }
 
@@ -404,6 +412,7 @@ tabbrowser[treestyletab-mode="vertical"]
 	border: 0 none !important;
 }
 
+
 /* for Multiple Tab Handler */
 .tabbrowser-tabs[treestyletab-mode="vertical"]
   .tabbrowser-tab:not(:hover):not([selected="true"])[multipletab-ready-to-close="true"]
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-3.6.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-3.6.css
index bb51281..3673965 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-3.6.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-3.6.css
@@ -13,6 +13,12 @@
   .tabbrowser-strip:not([treestyletab-style~="aero"])[treestyletab-mode="vertical"] {
 	background-color: #e8e8e8 !important;
 }
+/* autohide */
+#main-window:not([active="true"])
+  .treestyletab-tabbar-toolbar[treestyletab-tabbar-autohide]:not([treestyletab-style~="aero"])[treestyletab-mode="vertical"]
+  #treestyletab-tabbar-resizer-box {
+	background: rgba(232, 232, 232, 0.75);
+}
 
 /* Use the splitter to display the border of .tabbrowser-strip */
 #main-window:not([active="true"])
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-4.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-4.css
index eececda..dad6763 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-4.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/sidebar/inactive-4.css
@@ -15,6 +15,12 @@
   .tabbrowser-strip:not([treestyletab-style~="aero"])[treestyletab-mode="vertical"] {
 	background-color: #e8e8e8 !important;
 }
+/* autohide */
+#main-window:-moz-window-inactive
+  .treestyletab-tabbar-toolbar[treestyletab-tabbar-autohide]:not([treestyletab-style~="aero"])[treestyletab-mode="vertical"]
+  #treestyletab-tabbar-resizer-box {
+	background: rgba(232, 232, 232, 0.75);
+}
 
 /* Use the splitter to display the border of .tabbrowser-strip */
 #main-window:-moz-window-inactive
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/square/base.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/square/base.css
index 1f2ceab..a07ce39 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/square/base.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/square/base.css
@@ -141,7 +141,9 @@
 }
 
 .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
-  .tab-icon-image {
+  .tab-icon-image,
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  .tab-throbber {
 	margin-left: 0;
 }
 
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/square/vertigo.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/square/vertigo.css
index 444a2c9..27661f5 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/square/vertigo.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/square/vertigo.css
@@ -1,6 +1,17 @@
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
-.tabbrowser-tabs:not([treestyletab-tabbar-position="top"]) {
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"]),
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  .tabbrowser-tab:not([pinned]),
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  .tabbrowser-tab:not([pinned]):not([selected="true"]),
+.tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  :-moz-any(.tabbrowser-tab[pinned]:not([titlechanged]),
+            .tabbrowser-tab[pinned]:not([titlechanged]):not([selected="true"])),
+:root[tabFx2Compatible-flags~="mac"]
+  .tabbrowser-tabs:not([treestyletab-tabbar-position="top"])
+  :-moz-any(.tabbrowser-tab[pinned],
+            .tabbrowser-tab[pinned][titlechanged]) {
 	background: transparent !important;
 }
 
@@ -73,3 +84,10 @@
 	-moz-border-left-colors: #d1e2fe #d1e2fe !important;
 	-moz-border-right-colors: #d1e2fe #d1e2fe !important;
 }
+
+/* autohide */
+.treestyletab-tabbar-toolbar[treestyletab-tabbar-autohide][treestyletab-mode="vertical"]
+  #treestyletab-tabbar-resizer-box {
+	background: ThreeDFace;
+	opacity: 0.75;
+}
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/twisty/twisty.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/twisty/twisty.css
index 5d0a38a..f81816f 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/twisty/twisty.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/twisty/twisty.css
@@ -1,6 +1,10 @@
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
-.tabbrowser-tab:not([pinned="true"])
+.tabbrowser-tabs[treestyletab-mode="vertical"]
+  .tabbrowser-tab:not([pinned="true"])
+  .treestyletab-twisty-container,
+.tabbrowser-tabs[treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .treestyletab-twisty-container {
 	margin: 0 3px 0 -3px;
 	-moz-box-pack: start;
@@ -8,62 +12,83 @@
 	-moz-box-flex: 1;
 }
 
-.tabbrowser-tabs[treestyletab-tab-contents-inverted="true"]
+.tabbrowser-tabs[treestyletab-mode="vertical"][treestyletab-tab-contents-inverted="true"]
   .tabbrowser-tab:not([pinned="true"])
+  .treestyletab-twisty-container,
+.tabbrowser-tabs[treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .treestyletab-twisty-container {
 	margin: 0 -3px 0 3px;
 }
-.tabbrowser-tabs[treestyletab-twisty-style^="modern"]
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="vertical"]
   .tabbrowser-tab:not([pinned="true"])
   .treestyletab-twisty-container,
-.tabbrowser-tabs[treestyletab-twisty-style^="osx"]
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="vertical"]
   .tabbrowser-tab:not([pinned="true"])
+  .treestyletab-twisty-container,
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
+  .treestyletab-twisty-container,
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .treestyletab-twisty-container {
 	position: relative;
 	margin: 0 14px 0 -14px;
 }
-.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-tab-contents-inverted="true"]
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="vertical"][treestyletab-tab-contents-inverted="true"]
   .tabbrowser-tab:not([pinned="true"])
   .treestyletab-twisty-container,
-.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-tab-contents-inverted="true"]
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="vertical"][treestyletab-tab-contents-inverted="true"]
   .tabbrowser-tab:not([pinned="true"])
+  .treestyletab-twisty-container,
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
+  .treestyletab-twisty-container,
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .treestyletab-twisty-container {
 	margin: 0 -14px 0 14px;
 }
 
 
-.tabbrowser-tabs[treestyletab-twisty-style="retro"][treestyletab-mode="horizontal"]
-  .tabbrowser-tab:not([pinned="true"])
+.tabbrowser-tabs[treestyletab-twisty-style="retro"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .treestyletab-twisty-container {
 	position: relative;
 	margin: 0 16px 0 -16px;
 }
 
 .tabbrowser-tabs[treestyletab-twisty-style="retro"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
-  .tabbrowser-tab[treestyletab-children]:not([pinned="true"])
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .tab-icon {
 	margin-left: 16px;
 }
-.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-allow-subtree-collapse="true"][treestyletab-mode="horizontal"]
-  .tabbrowser-tab:not([pinned="true"])
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .tab-icon,
-.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-allow-subtree-collapse="true"][treestyletab-mode="horizontal"]
-  .tabbrowser-tab:not([pinned="true"])
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .tab-icon {
 	margin-left: 12px;
 }
-.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-allow-subtree-collapse="true"]:not([treestyletab-tab-contents-inverted="true"])
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="vertical"][treestyletab-allow-subtree-collapse="true"]:not([treestyletab-tab-contents-inverted="true"])
   .tabbrowser-tab:not([pinned="true"])
   .tab-icon,
-.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-allow-subtree-collapse="true"]:not([treestyletab-tab-contents-inverted="true"])
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="vertical"][treestyletab-allow-subtree-collapse="true"]:not([treestyletab-tab-contents-inverted="true"])
   .tabbrowser-tab:not([pinned="true"])
+  .tab-icon,
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
+  .tab-icon,
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="horizontal"][treestyletab-allow-subtree-collapse="true"]
+  .tabbrowser-tab[treestyletab-allow-subtree-collapse="true"][treestyletab-children]:not([pinned="true"])
   .tab-icon {
 	margin-left: 9px;
 }
-.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
+.tabbrowser-tabs[treestyletab-twisty-style^="modern"][treestyletab-mode="vertical"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
   .tabbrowser-tab:not([pinned="true"])
   .tab-icon,
-.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
+.tabbrowser-tabs[treestyletab-twisty-style^="osx"][treestyletab-mode="vertical"][treestyletab-allow-subtree-collapse="true"][treestyletab-tab-contents-inverted="true"]
   .tabbrowser-tab:not([pinned="true"])
   .tab-icon {
 	margin-right: 9px;
diff --git a/chrome/treestyletab.jar!/skin/classic/treestyletab/ui.css b/chrome/treestyletab.jar!/skin/classic/treestyletab/ui.css
index 7910604..db5d3b6 100755
--- a/chrome/treestyletab.jar!/skin/classic/treestyletab/ui.css
+++ b/chrome/treestyletab.jar!/skin/classic/treestyletab/ui.css
@@ -198,6 +198,15 @@
   .tab-icon-image,
 .tabbrowser-tabs[treestyletab-tabbar-position="top"]
   .tabbrowser-tab[treestyletab-drop-position="self"]
+  .tab-throbber,
+.tabbrowser-tabs:not([treestyletab-style])
+  .tabbrowser-tab[treestyletab-drop-position="before"]
+  .tab-throbber,
+.tabbrowser-tabs:not([treestyletab-style])
+  .tabbrowser-tab[treestyletab-drop-position="after"]
+  .tab-throbber,
+.tabbrowser-tabs[treestyletab-tabbar-position="top"]
+  .tabbrowser-tab[treestyletab-drop-position="self"]
   .tab-extra-status,
 .tabbrowser-tabs:not([treestyletab-style])
   .tabbrowser-tab[treestyletab-drop-position="before"]
diff --git a/defaults/preferences/treestyletab.js b/defaults/preferences/treestyletab.js
index aaedc13..aedf81f 100755
--- a/defaults/preferences/treestyletab.js
+++ b/defaults/preferences/treestyletab.js
@@ -557,6 +557,13 @@ pref("extensions.multipletab.show.multipletab-selection-item-createSubtree", tru
 pref("extensions.treestyletab.createSubtree.underParent", true);
 
 /**
+ * Size of pinned tabs in the vertical tab bar.
+ * "width" can accept a special value "-1" which means "expand to the width of the tab bar".
+ */
+pref("extensions.treestyletab.pinnedTab.width", 24);
+pref("extensions.treestyletab.pinnedTab.height", 24);
+
+/**
  * Compatibility hack flags for other addons. They can be disabled by each
  * addon, when the addon become working with TST without dirty hacks.
  * In other words, add-on authros can disable TST's dirty hack if it is
@@ -569,6 +576,7 @@ pref("extensions.treestyletab.compatibility.ColorfulTabs", true);
 pref("extensions.treestyletab.compatibility.DomainTab", true);
 pref("extensions.treestyletab.compatibility.DragDeGo", true);
 pref("extensions.treestyletab.compatibility.DragNDropToolbars", true);
+pref("extensions.treestyletab.compatibility.DuplicateThisTab", true);
 pref("extensions.treestyletab.compatibility.FirefoxSync", true);
 pref("extensions.treestyletab.compatibility.FireGestures", true);
 pref("extensions.treestyletab.compatibility.FLST", true);
@@ -578,6 +586,7 @@ pref("extensions.treestyletab.compatibility.GoogleToolbar.Sidewiki", true);
 pref("extensions.treestyletab.compatibility.Greasemonkey", true);
 pref("extensions.treestyletab.compatibility.Highlander", true);
 pref("extensions.treestyletab.compatibility.IETabPlus", true);
+pref("extensions.treestyletab.compatibility.InstaClick", true);
 pref("extensions.treestyletab.compatibility.LastTab", true);
 pref("extensions.treestyletab.compatibility.Linky", true);
 pref("extensions.treestyletab.compatibility.Locationbar2", true);
diff --git a/install.rdf b/install.rdf
index 2cde331..031dbd1 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.12.2011061701"
+                   em:version="0.12.2011110101"
                    em:creator="SHIMODA Hiroshi"
                    em:description="Show tabs like a tree."
                    em:homepageURL="http://piro.sakura.ne.jp/xul/_treestyletab.html.en"
@@ -91,7 +91,7 @@
     <em:localized>
       <RDF:Description em:locale="zh-TW"
                        em:name="Tree Style Tab"
-                       em:description="以樹狀目錄形式顯示分頁"
+                       em:description="樹狀分頁顯示。"
                        em:homepageURL="http://piro.sakura.ne.jp/xul/_treestyletab.html.en"
                        em:creator="SHIMODA Hiroshi">
           <em:contributor>Zusukar (auto-shrink mode)</em:contributor>
@@ -99,6 +99,7 @@
           <em:contributor>Philipp von Weitershausen (Sidebar style)</em:contributor>
           <em:translator>HkYtrewq (zh-TW locale)</em:translator>
           <em:translator>Tsprajna (zh-TW locale)</em:translator>
+          <em:translator>bootleq (zh-TW locale)</em:translator>
       </RDF:Description>
     </em:localized>
     <em:localized>
@@ -166,7 +167,7 @@
     <em:targetApplication>
       <RDF:Description em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
                        em:minVersion="3.6"
-                       em:maxVersion="7.0a1" />
+                       em:maxVersion="10.0a1" />
     </em:targetApplication>
   </RDF:Description>
 </RDF:RDF>
diff --git a/modules/autoHide.js b/modules/autoHide.js
index 21e7d9e..29c13f8 100755
--- a/modules/autoHide.js
+++ b/modules/autoHide.js
@@ -312,43 +312,20 @@ AutoHideBrowser.prototype = {
  
 	showHideOnMousemove : function AHB_showHideOnMousemove(aEvent) 
 	{
-		var w = this.window;
-		if ('gestureInProgress' in w && w.gestureInProgress)
+		var position = this.getMousePosition(aEvent);
+		if (position == this.MOUSE_POSITION_UNKNOWN)
 			return;
 
 		this.cancelShowHideOnMousemove();
 
-		var sv  = this.treeStyleTab;
-		var b   = this.browser;
-		var pos = sv.position;
-		var box = b.mCurrentBrowser.boxObject;
-
-		if (sv.isFloating && this.expanded) { // Firefox 4.0-
-			box = {
-				screenX : box.screenX + (pos == 'left' ? this.XOffset : 0 ),
-				screenY : box.screenY,
-				width   : box.width - this.XOffset,
-				height  : box.height
-			};
-		}
-
-		var sensitiveArea = this.sensitiveArea;
-		/* For resizing of shrunken tab bar and clicking closeboxes,
-		   we have to shrink sensitive area a little. */
-		if (this.shrunken) sensitiveArea -= 20;
+		var sv = this.treeStyleTab;
+		var b  = this.browser;
+		var w  = this.window;
 
-		var shouldKeepShown = (
-				pos == 'left' ?
-					(aEvent.screenX <= box.screenX + sensitiveArea) :
-				pos == 'right' ?
-					(aEvent.screenX >= box.screenX + box.width - sensitiveArea) :
-				pos == 'bottom' ?
-					(aEvent.screenY >= box.screenY + box.height - sensitiveArea) :
-					(aEvent.screenY <= box.screenY + sensitiveArea)
-			);
+		var shouldShow = position & this.MOUSE_POSITION_SENSITIVE;
 		if (this.expanded) {
 			if (
-				shouldKeepShown &&
+				shouldShow &&
 				this.showHideReason & this.kKEEP_SHOWN_ON_MOUSEOVER &&
 				sv.getTreePref('tabbar.autoShow.keepShownOnMouseover')
 				) {
@@ -357,7 +334,7 @@ AutoHideBrowser.prototype = {
 				this.cancelHideForFeedback();
 			}
 			else if (
-				!shouldKeepShown &&
+				!shouldShow &&
 				sv.getTreePref('tabbar.autoShow.mousemove')
 				) {
 				this.showHideOnMousemoveTimer = w.setTimeout(
@@ -371,15 +348,7 @@ AutoHideBrowser.prototype = {
 				);
 			}
 		}
-		else if (
-				pos == 'left' ?
-					(aEvent.screenX <= box.screenX + sensitiveArea) :
-				pos == 'right' ?
-					(aEvent.screenX >= box.screenX + box.width - sensitiveArea) :
-				pos == 'bottom' ?
-					(aEvent.screenY >= box.screenY + box.height - sensitiveArea) :
-					(aEvent.screenY <= box.screenY + sensitiveArea)
-			) {
+		else if (shouldShow) {
 			this.showHideOnMousemoveTimer = w.setTimeout(
 				function(aSelf) {
 					aSelf.cancelDelayedShowForShortcut();
@@ -392,11 +361,62 @@ AutoHideBrowser.prototype = {
 		}
 
 		b = null;
-		pos = null
-		box = null;
-		sensitiveArea = null;
-		shouldKeepShown = null;
 	},
+	getMousePosition : function AHB_getMousePosition(aEvent) 
+	{
+		var w = this.window;
+		if ('gestureInProgress' in w && w.gestureInProgress)
+			return this.MOUSE_POSITION_UNKNOWN;
+
+		var sv  = this.treeStyleTab;
+		var b   = this.browser;
+		var pos = sv.position;
+		var box = b.mCurrentBrowser.boxObject;
+
+		if (sv.isFloating && this.expanded) { // Firefox 4.0-
+			box = {
+				screenX : box.screenX + (pos == 'left' ? this.XOffset : 0 ),
+				screenY : box.screenY,
+				width   : box.width - this.XOffset,
+				height  : box.height
+			};
+		}
+
+		var sensitiveArea = this.sensitiveArea;
+		/* For resizing of shrunken tab bar and clicking closeboxes,
+
+		   we have to shrink sensitive area a little. */
+		if (this.shrunken) sensitiveArea -= 20;
+
+		if (
+			pos == 'left' ?
+				(aEvent.screenX <= box.screenX) :
+			pos == 'right' ?
+				(aEvent.screenX >= box.screenX + box.width) :
+			pos == 'bottom' ?
+				(aEvent.screenY >= box.screenY + box.height) :
+				(aEvent.screenY <= box.screenY)
+			)
+			return this.MOUSE_POSITION_INSIDE;
+
+		if (
+			pos == 'left' ?
+				(aEvent.screenX <= box.screenX + sensitiveArea) :
+			pos == 'right' ?
+				(aEvent.screenX >= box.screenX + box.width - sensitiveArea) :
+			pos == 'bottom' ?
+				(aEvent.screenY >= box.screenY + box.height - sensitiveArea) :
+				(aEvent.screenY <= box.screenY + sensitiveArea)
+			)
+			return this.MOUSE_POSITION_NEAR;
+
+		return this.MOUSE_POSITION_OUTSIDE;
+	},
+	MOUSE_POSITION_UNKNOWN : 0,
+	MOUSE_POSITION_OUTSIDE : (1 << 0),
+	MOUSE_POSITION_INSIDE  : (1 << 1),
+	MOUSE_POSITION_NEAR    : (1 << 2),
+	MOUSE_POSITION_SENSITIVE : (1 << 1) | (1 << 2),
  
 	cancelShowHideOnMousemove : function AHB_cancelShowHideOnMousemove() 
 	{
@@ -1267,6 +1287,10 @@ AutoHideBrowser.prototype = {
 		if (this.expanded)
 			return;
 
+		var position = this.getMousePosition(aEvent);
+		if (!(position & this.MOUSE_POSITION_SENSITIVE))
+			return;
+
 		var draggedTabs = this.window['piro.sakura.ne.jp'].tabsDragUtils.getSelectedTabs(aEvent);
 		if (
 			draggedTabs.length ||
@@ -1289,6 +1313,10 @@ AutoHideBrowser.prototype = {
 		if (this._autoHideOnDragLeaveTimer)
 			this.window.clearTimeout(this._autoHideOnDragLeaveTimer);
 
+		var position = this.getMousePosition(aEvent);
+		if (position & this.MOUSE_POSITION_SENSITIVE)
+			return;
+
 		this._autoHideOnDragLeaveTimer = this.window.setTimeout(function(aSelf) {
 			delete aSelf._autoHideOnDragLeaveTimer;
 			aSelf.hide(aSelf.kSHOWN_BY_MOUSEMOVE);
@@ -1505,9 +1533,13 @@ AutoHideWindow.prototype = {
 		}
 		var w = this.window;
 		w.setTimeout(function() {
-			if (w.windowState != Ci.nsIDOMChromeWindow.STATE_NORMAL) return;
+			if (w.windowState != Ci.nsIDOMChromeWindow.STATE_NORMAL)
+				return;
 			var count = 0;
 			var resizeTimer = w.setInterval(function(){
+				if (w.windowState != Ci.nsIDOMChromeWindow.STATE_NORMAL)
+					return w.clearInterval(resizeTimer);
+
 				if (++count > 100 || w.innerHeight > 0) {
 					w.clearInterval(resizeTimer);
 					w.resizeBy(-1,-1);
diff --git a/modules/browser.js b/modules/browser.js
index 898e711..323aad2 100755
--- a/modules/browser.js
+++ b/modules/browser.js
@@ -387,47 +387,68 @@ TreeStyleTabBrowser.prototype = {
 		var maxWidth = tabbarPlaceHolderWidth || tabbarWidth;
 
 		var count  = this.pinnedTabsCount;
-		var width  = aWidth || this.PINNED_TAB_DEFAULT_WIDTH;
-		var height = aHeight || this.PINNED_TAB_DEFAULT_HEIGHT;
+		var width  = Math.min(maxWidth, aWidth || this.window.TreeStyleTabService.pinnedTabWidth);
+		if (width < 0)
+			width = maxWidth;
+		else
+			width = Math.max(this.MIN_PINNED_TAB_WIDTH, width);
+		var height = Math.max(this.MIN_PINNED_TAB_HEIGHT, aHeight || this.window.TreeStyleTabService.pinnedTabHeight);
 		var maxCol = Math.floor(maxWidth / width);
 		var maxRow = Math.ceil(count / maxCol);
 		var col    = 0;
 		var row    = 0;
 
-		var inverted = this.position == 'left' && b.getAttribute(this.kINVERT_SCROLLBAR) == 'true';
+		var faviconized = width <= this.MIN_PINNED_TAB_WIDTH;
+		var baseX = this.tabStrip.boxObject.screenX - this.document.documentElement.boxObject.screenX;
+
+		/**
+		 * Hacks for Firefox 9 or olders.
+		 * In a box with "direction: rtr", we have to position tabs
+		 * by margin-right, because the basic position becomes
+		 * "top-right" instead of "top-left".
+		 */
+		var needToInvertDirection = !this.isGecko10OrLater && this.position == 'left' && b.getAttribute(this.kINVERT_SCROLLBAR) == 'true';
 		var remainder = maxWidth - (maxCol * width);
-		var shrunkenOffset = ((inverted || this.position == 'right') && tabbarPlaceHolderWidth) ?
+		var shrunkenOffset = ((needToInvertDirection || this.position == 'right') && tabbarPlaceHolderWidth) ?
 								tabbarWidth - tabbarPlaceHolderWidth :
 								0 ;
 
+		var removeFaviconizedClassPattern = new RegExp('\\s+'+this.kFAVICONIZED, 'g');
+
 		tabbar.style.MozMarginStart = '';
 		tabbar.style.setProperty('margin-top', (height * maxRow)+'px', 'important');
 		for (let i = 0; i < count; i++)
 		{
-			let style = tabbar.childNodes[i].style;
+			let item = tabbar.childNodes[i];
+
+			let style = item.style;
 			style.MozMarginStart = '';
 
 			let transitionStyleBackup = style.transition || style.MozTransition || '';
 			if (aJustNow)
 				style.MozTransition = style.transition = 'none';
 
-			if (inverted) {
-				/**
-				 * In a box with "direction: rtr", we have to position tabs
-				 * by margin-right, because the basic position becomes
-				 * "top-right" instead of "top-left".
-				 */
+			let className = item.className.replace(removeFaviconizedClassPattern, '');
+			if (faviconized)
+				className += ' '+this.kFAVICONIZED;
+			if (className != item.className)
+				item.className = className;
+
+			style.width = width+'px';
+			if (needToInvertDirection) {
 				let margin = (width * (maxCol - col - 1)) + remainder + shrunkenOffset;
 				style.setProperty('margin-right', margin+'px', 'important');
-				style.marginLeft = '';
+				style.marginLeft = style.left = style.right = '';
 			}
 			else {
 				style.setProperty('margin-left', ((width * col) + shrunkenOffset)+'px', 'important');
+				style.left = baseX+'px';
+				style.right = 'auto';
 				style.marginRight = '';
 			}
 
 			style.setProperty('margin-top', (- height * (maxRow - row))+'px', 'important');
-			style.top = style.right = style.bottom = style.left = '';
+			style.top = style.bottom = '';
 
 			if (aJustNow)
 				this.Deferred.next(function() { // "transition" must be cleared after the reflow.
@@ -462,8 +483,6 @@ TreeStyleTabBrowser.prototype = {
 			aSelf._positionPinnedTabsWithDelayTimerArgs = null;
 		}, 0, this);
 	},
-	PINNED_TAB_DEFAULT_WIDTH : 24,
-	PINNED_TAB_DEFAULT_HEIGHT : 24,
  
 	resetPinnedTabs : function TSTBrowser_resetPinnedTabs() 
 	{
@@ -473,7 +492,8 @@ TreeStyleTabBrowser.prototype = {
 		for (var i = 0, count = this.pinnedTabsCount; i < count; i++)
 		{
 			let style = tabbar.childNodes[i].style;
-			style.MozMarginStart = style.marginLeft = style.marginRight = style.marginTop = '';
+			style.width = style.left = style.right =
+				style.MozMarginStart = style.marginLeft = style.marginRight = style.marginTop = '';
 		}
 	},
  
@@ -589,6 +609,7 @@ TreeStyleTabBrowser.prototype = {
 		w.addEventListener('customizationchange', this, false);
 		w.addEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
 		w.addEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_EXITED,  this, false);
+		w.addEventListener('tabviewhidden', this, true);
 
 		b.addEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false);
 
@@ -1753,6 +1774,7 @@ TreeStyleTabBrowser.prototype = {
 		w.removeEventListener('customizationchange', this, false);
 		w.removeEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
 		w.removeEventListener(this.kEVENT_TYPE_PRINT_PREVIEW_EXITED,  this, false);
+		w.removeEventListener('tabviewhidden', this, true);
 
 		b.removeEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false);
 
@@ -2175,6 +2197,10 @@ TreeStyleTabBrowser.prototype = {
 			case 'extensions.treestyletab.tabbar.autoHide.mode.fullscreen':
 				return this.autoHide; // ensure initialized
 
+			case 'extensions.treestyletab.pinnedTab.width':
+			case 'extensions.treestyletab.pinnedTab.height':
+				return this.positionPinnedTabsWithDelay();
+
 			default:
 				return;
 		}
@@ -2418,6 +2444,13 @@ TreeStyleTabBrowser.prototype = {
 			case 'customizationchange':
 				return this.updateCustomizedTabsToolbar();
 
+			case 'tabviewhidden':
+				this.tabViewHiding = true;
+				this._addedCountClearTimer = this.window.setTimeout(function(aSelf) {
+					aSelf.tabViewHiding = false;
+				}, 0, this);
+				return;
+
 
 			case this.kEVENT_TYPE_PRINT_PREVIEW_ENTERED:
 				return this.onTreeStyleTabPrintPreviewEntered(aEvent);
@@ -2433,7 +2466,28 @@ TreeStyleTabBrowser.prototype = {
 	},
 	lastScrollX : -1,
 	lastScrollY : -1,
+	tabViewHiding : false,
 	
+	restoreLastScrollPosition : function TSTBrowser_restoreLastScrollPosition()
+	{
+		if (this.lastScrollX < 0 || this.lastScrollY < 0) return;
+		var lastX = this.lastScrollX;
+		var lastY = this.lastScrollY;
+		this.clearLastScrollPosition();
+		if (!this.smoothScrollTask &&
+			!this.scrollBox._smoothScrollTimer) { // don't restore scroll position if another scroll is already running.
+			let x = {}, y = {};
+			let scrollBoxObject = this.scrollBoxObject;
+			scrollBoxObject.getPosition(x, y);
+			if (x.value != lastX || y.value != lastY)
+				scrollBoxObject.scrollTo(lastX, lastY);
+		}
+	},
+	clearLastScrollPosition : function TSTBrowser_clearLastScrollPosition()
+	{
+		this.lastScrollX = -1;
+		this.lastScrollY = -1;
+	},
 	updateLastScrollPosition : function TSTBrowser_updateLastScrollPosition() 
 	{
 		if (!this.isVertical) return;
@@ -2457,6 +2511,7 @@ TreeStyleTabBrowser.prototype = {
 
 		var hasStructure = this.treeStructure && this.treeStructure.length;
 		var pareintIndexInTree = hasStructure ? this.treeStructure.shift() : 0 ;
+		var lastRelatedTab = b._lastRelatedTab;
 
 		if (this.readiedToAttachNewTab) {
 			if (pareintIndexInTree < 0) { // there is no parent, so this is a new parent!
@@ -2485,7 +2540,7 @@ TreeStyleTabBrowser.prototype = {
 			else if (
 				parent &&
 				this.getTreePref('insertNewChildAt') == this.kINSERT_FISRT &&
-				(this.multipleCount == 0 || this._addedCountInThisLoop == 0)
+				(this.multipleCount <= 0 || this._addedCountInThisLoop <= 0)
 				) {
 				/* •¡”‚ÌŽqƒ^ƒu‚ðˆê‹C‚ÉŠJ‚­ê‡AÅ‰‚ÉŠJ‚¢‚½ƒ^ƒu‚¾‚¯‚ð
 				   Žqƒ^ƒu‚̍ŏ‰‚̈ʒu‚É‘}“ü‚µA‘±‚­ƒ^ƒu‚́uÅ‰‚ÌŠJ‚¢‚½ƒ^ƒuv‚Æ
@@ -2553,6 +2608,16 @@ TreeStyleTabBrowser.prototype = {
 		if (tabs.length == 2)
 			this.updateInvertedTabContentsOrder(tabs);
 
+		/**
+		 * gBrowser.adthis._changeTabbarPosition(position);
+		 dTab() resets gBrowser._lastRelatedTab.owner
+		 * when a new background tab is opened from the current tab,
+		 * but it will fail with TST because gBrowser.moveTab() (called
+		 * by TST) clears gBrowser._lastRelatedTab.
+		 * So, we have to restore gBrowser._lastRelatedTab manually.
+		 */
+		b._lastRelatedTab = lastRelatedTab;
+
 		return true;
 	},
 	_addedCountInThisLoop : 0,
@@ -2603,6 +2668,9 @@ TreeStyleTabBrowser.prototype = {
 			}
 		}
 
+		var toBeClosedSibling = !this.hasChildTabs(tab) ?
+								this._reserveCloseNeedlessGroupTabSibling(tab) : null ;
+
 		var firstChild     = this.getFirstChildTab(tab);
 		var parentTab      = this.getParentTab(tab);
 		var nextFocusedTab = null;
@@ -2698,6 +2766,8 @@ TreeStyleTabBrowser.prototype = {
 		}
 
 		if (b.selectedTab == tab) {
+			if (nextFocusedTab && nextFocusedTab == toBeClosedSibling)
+				nextFocusedTab = this.getFirstChildTab(nextFocusedTab);
 			if (
 				nextFocusedTab &&
 				!nextFocusedTab.hidden
@@ -2734,6 +2804,31 @@ TreeStyleTabBrowser.prototype = {
 		if (collapsed)
 			this.startRendering();
 	},
+	_reserveCloseNeedlessGroupTabSibling : function TSTBrowser_reserveCloseNeedlessGroupTabSibling(aTab)
+	{
+		if (!aTab)
+			return null;
+
+		var parent = this.getParentTab(aTab);
+		var siblings = this.getSiblingTabs(aTab);
+		var groupTabs = siblings.filter(function(aTab) {
+				return this.isGroupTab(aTab);
+			}, this);
+		var groupTab = (
+				groupTabs.length == 1 &&
+				siblings.length == 1 &&
+				this.hasChildTabs(groupTabs[0])
+				) ? groupTabs[0] : null ;
+
+		if (groupTab) {
+			this.window.setTimeout(function(aSelf, aGroupTab) {
+				aSelf.getTabBrowserFromChild(aGroupTab).removeTab(aGroupTab, { animate : true });
+			}, 0, this, groupTab);
+			return groupTab;
+		}
+
+		return null;
+	},
 	getNextFocusedTab : function TSTBrowser_getNextFocusedTab(aTab)
 	{
 		return this.getNextSiblingTab(aTab) ||
@@ -2770,6 +2865,7 @@ TreeStyleTabBrowser.prototype = {
 	{
 		var tab = aEvent.originalTarget;
 		var b   = this.mTabBrowser;
+		tab.__treestyletab__previousPosition = aEvent.detail;
 
 		// When the tab was moved before TabOpen event is fired, we have to update manually.
 		var newlyOpened = !this.isTabInitialized(tab) && this.onTabAdded(null, tab);
@@ -2946,19 +3042,25 @@ TreeStyleTabBrowser.prototype = {
 	// for TabView (Panorama aka Tab Candy)
 	onTabVisibilityChanged : function TSTBrowser_onTabVisibilityChanged(aEvent) 
 	{
-		this.updateInvertedTabContentsOrder(aEvent.originalTarget);
+		var tab = aEvent.originalTarget;
+		if (this.tabViewHiding) {
+			this.updateInvertedTabContentsOrder(aEvent.originalTarget);
 
-		if (this.tabVisibilityChangedTimer) {
-			this.window.clearTimeout(this.tabVisibilityChangedTimer);
-			this.tabVisibilityChangedTimer = null;
+			if (this.tabVisibilityChangedTimer) {
+				this.window.clearTimeout(this.tabVisibilityChangedTimer);
+				this.tabVisibilityChangedTimer = null;
+			}
+			this.tabVisibilityChangedTabs.push(tab);
+			this.tabVisibilityChangedTimer = this.window.setTimeout(function(aSelf) {
+				aSelf.tabVisibilityChangedTimer = null;
+				var tabs = aSelf.tabVisibilityChangedTabs;
+				aSelf.tabVisibilityChangedTabs = [];
+				aSelf.updateTreeByTabVisibility(tabs);
+			}, 0, this);
+		}
+		else if (aEvent.type == 'TabHide') {
+			this.subtreeFollowParentAcrossTabGroups(tab);
 		}
-		this.tabVisibilityChangedTabs.push(aEvent.originalTarget);
-		this.tabVisibilityChangedTimer = this.window.setTimeout(function(aSelf) {
-			aSelf.tabVisibilityChangedTimer = null;
-			var tabs = aSelf.tabVisibilityChangedTabs;
-			aSelf.tabVisibilityChangedTabs = [];
-			aSelf.updateTreeByTabVisibility(tabs);
-		}, 0, this);
 	},
 	tabVisibilityChangedTimer : null,
 	updateTreeByTabVisibility : function TSTBrowser_updateTreeByTabVisibility(aChangedTabs)
@@ -3032,6 +3134,32 @@ TreeStyleTabBrowser.prototype = {
 		}
 		this.internallyTabMovingCount--;
 	},
+	tabViewTreeIsMoving : false,
+	subtreeFollowParentAcrossTabGroups : function TSTBrowser_subtreeFollowParentAcrossTabGroups(aParent)
+	{
+		if (this.tabViewTreeIsMoving) return;
+		let item = aParent._tabViewTabItem;
+		if (!item) return;
+		let group = item.parent;
+		if (!group) return;
+
+		this.tabViewTreeIsMoving = true;
+		this.internallyTabMovingCount++;
+		let w = this.window;
+		let b = this.mTabBrowser;
+		let lastCount = this.getAllTabs(b).snapshotLength - 1;
+		w.setTimeout(function(aSelf) {
+			aSelf.partTab(aParent);
+			b.moveTabTo(aParent, lastCount);
+			let descendantTabs = aSelf.getDescendantTabs(aParent);
+			descendantTabs.forEach(function(aTab) {
+				w.TabView.moveTabTo(aTab, group.id);
+				b.moveTabTo(aTab, lastCount);
+			});
+			aSelf.internallyTabMovingCount--;
+			aSelf.tabViewTreeIsMoving = false;
+		}, 0, this);
+	},
  
 	onTabRestoring : function TSTBrowser_onTabRestoring(aEvent) 
 	{
@@ -3440,25 +3568,46 @@ TreeStyleTabBrowser.prototype = {
 	{
 		var parentTab = this.getParentTab(aTab);
 
-		if (!parentTab)
-			this.collapseExpandSubtree(aTab, false);
+		/**
+		 * Children of the newly pinned tab are possibly
+		 * moved to the top of the tab bar, by TabMove event
+		 * from the newly pinned tab. So, we have to
+		 * reposition unexpectedly moved children.
+		 */
+		if (!parentTab) {
+			/**
+			 * Universal but dangerous logic. "__treestyletab__previousPosition"
+			 * can be broken by multiple movings.
+			 */
+			let b = this.browser;
+			this.internallyTabMovingCount++;
+			this.getDescendantTabs(aTab).reverse().forEach(function(aChildTab) {
+				if (aChildTab.__treestyletab__previousPosition > aChildTab._tPos)
+					b.moveTabTo(aChildTab, aChildTab.__treestyletab__previousPosition);
+			}, this);
+			this.internallyTabMovingCount--;
+		}
+		else {
+			/**
+			 * Safer logic. This cannot be available for "root" tabs because
+			 * their children (already moved) have no way to know the anchor
+			 * position (the next sibling of the pinned tab itself).
+			 */
+			let b = this.browser;
+			this.internallyTabMovingCount++;
+			this.getChildTabs(aTab).reverse().forEach(function(aChildTab) {
+				if (aChildTab._tPos < parentTab._tPos)
+					b.moveTabTo(aChildTab, parentTab._tPos);
+			}, this);
+			this.internallyTabMovingCount--;
+		}
 
-		this.getChildTabs(aTab).reverse().forEach(
-			parentTab ?
-				function(aChildTab) {
-					this.attachTabTo(aChildTab, parentTab, {
-						dontExpand : true,
-						/**
-						 * Children of the newly pinned tab are possibly
-						 * moved to the top of the tab bar, by TabMove event
-						 * from the newly pinned tab. So, we have to
-						 * reposition unexpectedly moved children.
-						 */
-						dontMove   : aChildTab._tPos > parentTab._tPos
-					});
-				} :
-				this.partTab,
-		this);
+		this.partAllChildren(aTab, {
+			behavior : this.getCloseParentBehaviorForTab(
+				aTab,
+				this.kCLOSE_PARENT_BEHAVIOR_PROMOTE_FIRST_CHILD
+			)
+		});
 		this.partTab(aTab);
 
 		this.collapseExpandTab(aTab, false);
@@ -3706,18 +3855,8 @@ TreeStyleTabBrowser.prototype = {
  
 	onScroll : function TSTBrowser_onScroll(aEvent) 
 	{
-		if (this.lastScrollX < 0 || this.lastScrollY < 0) return;
 		// restore scroll position when a tab is closed.
-		if (!this.smoothScrollTask &&
-			!this.scrollBox._smoothScrollTimer) { // don't restore scroll position if another scroll is already running.
-			let x = {}, y = {};
-			let scrollBoxObject = this.scrollBoxObject;
-			scrollBoxObject.getPosition(x, y);
-			if (x.value != this.lastScrollX || y.value != this.lastScrollY)
-				scrollBoxObject.scrollTo(this.lastScrollX, this.lastScrollY);
-		}
-		this.lastScrollX = -1;
-		this.lastScrollY = -1;
+		this.restoreLastScrollPosition();
 	},
  
 	onTabbarOverflow : function TSTBrowser_onTabbarOverflow(aEvent) 
@@ -3832,6 +3971,7 @@ TreeStyleTabBrowser.prototype = {
 				aEvent.currentTarget,
 				Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
 			).singleNodeValue;
+			if (!item) return;
 			items[aID] = item;
 			if (this.getTreePref('show.'+aID))
 				item.removeAttribute('hidden');
@@ -3857,56 +3997,66 @@ TreeStyleTabBrowser.prototype = {
 		// collapse/expand all
 		sep = this.evaluateXPath(
 			'descendant::xul:menuseparator[starts-with(@id, "'+this.kMENUITEM_COLLAPSEEXPAND_SEPARATOR+'")]',
-
 			aEvent.currentTarget,
 			Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
 		).singleNodeValue;
 		let collapseItem = items[this.kMENUITEM_COLLAPSE];
-		let expanndItem = items[this.kMENUITEM_EXPAND];
+		let expandItem = items[this.kMENUITEM_EXPAND];
 		if (this.canCollapseSubtree(b) &&
 			this.evaluateXPath(
 				'child::xul:tab[@'+this.kCHILDREN+']',
 				b.mTabContainer
 			).snapshotLength) {
-			if (this.evaluateXPath(
-					'child::xul:tab[@'+this.kCHILDREN+' and not(@'+this.kSUBTREE_COLLAPSED+'="true")]',
-					b.mTabContainer
-				).snapshotLength)
-				collapseItem.removeAttribute('disabled');
-			else
-				collapseItem.setAttribute('disabled', true);
+			if (collapseItem) {
+				if (this.evaluateXPath(
+						'child::xul:tab[@'+this.kCHILDREN+' and not(@'+this.kSUBTREE_COLLAPSED+'="true")]',
+						b.mTabContainer
+					).snapshotLength)
+					collapseItem.removeAttribute('disabled');
+				else
+					collapseItem.setAttribute('disabled', true);
+			}
 
-			if (this.evaluateXPath(
-					'child::xul:tab[@'+this.kCHILDREN+' and @'+this.kSUBTREE_COLLAPSED+'="true"]',
-					b.mTabContainer
-				).snapshotLength)
-				expanndItem.removeAttribute('disabled');
-			else
-				expanndItem.setAttribute('disabled', true);
+			if (expandItem) {
+				if (this.evaluateXPath(
+						'child::xul:tab[@'+this.kCHILDREN+' and @'+this.kSUBTREE_COLLAPSED+'="true"]',
+						b.mTabContainer
+					).snapshotLength)
+					expandItem.removeAttribute('disabled');
+				else
+					expandItem.setAttribute('disabled', true);
+			}
 		}
 		else {
-			collapseItem.setAttribute('hidden', true);
-			expanndItem.setAttribute('hidden', true);
-		}
-		if (collapseItem.getAttribute('hidden') == 'true' &&
-			expanndItem.getAttribute('hidden') == 'true') {
-			sep.setAttribute('hidden', true);
+			if (collapseItem) collapseItem.setAttribute('hidden', true);
+			if (expandItem) expandItem.setAttribute('hidden', true);
 		}
-		else {
-			sep.removeAttribute('hidden');
+		if (sep) {
+			if (
+				(!collapseItem || collapseItem.getAttribute('hidden') == 'true') &&
+				(!expandItem || expandItem.getAttribute('hidden') == 'true')
+				) {
+				sep.setAttribute('hidden', true);
+			}
+			else {
+				sep.removeAttribute('hidden');
+			}
 		}
 
 		// close all tabs but this tree
 		let removeAllTabsBut = items[this.kMENUITEM_REMOVEALLTABSBUT];
-		let rootTabs = this.visibleRootTabs;
-		if (rootTabs.length == 1 && rootTabs[0] == b.mContextTab)
-			removeAllTabsBut.setAttribute('disabled', true);
-		else
-			removeAllTabsBut.removeAttribute('disabled');
+		if (removeAllTabsBut) {
+			let rootTabs = this.visibleRootTabs;
+			if (rootTabs.length == 1 && rootTabs[0] == b.mContextTab)
+				removeAllTabsBut.setAttribute('disabled', true);
+			else
+				removeAllTabsBut.removeAttribute('disabled');
+		}
 
 		// auto hide
 		let autohide = items[this.kMENUITEM_AUTOHIDE];
-		this.autoHide.updateMenuItem(autohide);
+		if (autohide)
+			this.autoHide.updateMenuItem(autohide);
 
 		// fix
 		let fixedPref;
@@ -3920,23 +4070,29 @@ TreeStyleTabBrowser.prototype = {
 			fixedLabel = 'label-horizontal';
 		}
 		let fixed = items[this.kMENUITEM_FIXED];
-		fixed.setAttribute('label', fixed.getAttribute(fixedLabel));
-		if (fixedPref)
-			fixed.setAttribute('checked', true);
-		else
-			fixed.removeAttribute('checked');
+		if (fixed) {
+			fixed.setAttribute('label', fixed.getAttribute(fixedLabel));
+			if (fixedPref)
+				fixed.setAttribute('checked', true);
+			else
+				fixed.removeAttribute('checked');
+		}
 
 		sep = this.evaluateXPath(
 			'descendant::xul:menuseparator[starts-with(@id, "'+this.kMENUITEM_AUTOHIDE_SEPARATOR+'")]',
 			aEvent.currentTarget,
 			Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
 		).singleNodeValue;
-		if (autohide.getAttribute('hidden') != 'true' ||
-			fixed.getAttribute('hidden') != 'true') {
-			sep.removeAttribute('hidden');
-		}
-		else {
-			sep.setAttribute('hidden', true);
+		if (sep) {
+			if (
+				(autohide && autohide.getAttribute('hidden') != 'true') ||
+				(fixed && fixed.getAttribute('hidden') != 'true')
+				) {
+				sep.removeAttribute('hidden');
+			}
+			else {
+				sep.setAttribute('hidden', true);
+			}
 		}
 	},
   
@@ -4027,7 +4183,11 @@ TreeStyleTabBrowser.prototype = {
 	},
 	set treeViewEnabled(aValue)
 	{
-		this._treeViewEnabled = !!aValue;
+		var newValue = !!aValue;
+		if (newValue == this._treeViewEnabled)
+			return aValue;
+
+		this._treeViewEnabled = newValue;
 		if (this._treeViewEnabled) {
 			if (this._lastAllowSubtreeCollapseExpand)
 				this.allowSubtreeCollapseExpand = true;
@@ -4286,11 +4446,20 @@ TreeStyleTabBrowser.prototype = {
 		if (aInfo.behavior == this.kCLOSE_PARENT_BEHAVIOR_CLOSE_ALL_CHILDREN)
 			aInfo.behavior = this.kCLOSE_PARENT_BEHAVIOR_PROMOTE_FIRST_CHILD;
 
-		var dontUpdateIndent = aInfo.dontUpdateIndent;
-
 		var b = this.mTabBrowser;
 		var parentTab = this.getParentTab(aTab);
 		var children = this.getChildTabs(aTab);
+
+		if (
+			this.isGroupTab(aTab) &&
+			this.getTabsArray(b).filter(function(aTab) {
+				return !b._removingTabs || b._removingTabs.indexOf(aTab) < 0;
+			}).length == children.length
+			) {
+			aInfo.behavior = this.kCLOSE_PARENT_BEHAVIOR_PROMOTE_ALL_CHILDREN;
+			aInfo.dontUpdateIndent = false;
+		}
+
 		var insertBefore = null;
 		if (aInfo.behavior == this.kCLOSE_PARENT_BEHAVIOR_DETACH_ALL_CHILDREN &&
 			!this.getTreePref('closeParentBehavior.moveDetachedTabsToBottom')) {
diff --git a/modules/utils.js b/modules/utils.js
index c65859e..58321ce 100755
--- a/modules/utils.js
+++ b/modules/utils.js
@@ -130,6 +130,7 @@ var TreeStyleTabUtils = {
 	kANIMATION_ENABLED  : 'treestyletab-animation-enabled',
 	kINVERT_SCROLLBAR   : 'treestyletab-invert-scrollbar',
 	kNARROW_SCROLLBAR   : 'treestyletab-narrow-scrollbar',
+	kFAVICONIZED        : 'treestyletab-faviconized',
 
 	kTAB_INVERTED          : 'treestyletab-tab-inverted',
 	kTAB_CONTENTS_INVERTED : 'treestyletab-tab-contents-inverted',
@@ -317,10 +318,19 @@ var TreeStyleTabUtils = {
 	},
 	_Comparator : null,
  
-	get isGecko2() 
+	get isGecko10OrLater() 
+	{
+		return this.Comparator.compare(this.XULAppInfo.version, '10.0a') > 0;
+	},
+ 
+	get isGecko2OrLater() 
 	{
 		return this.Comparator.compare(this.XULAppInfo.version, '4.0b5') > 0;
 	},
+	get isGecko2() // for backward compatibility
+	{
+		return this.isGecko2OrLater
+	},
  
 	get treeBundle() { 
 		return stringBundle.get('chrome://treestyletab/locale/treestyletab.properties');
@@ -366,6 +376,13 @@ var TreeStyleTabUtils = {
 		catch(e) {
 			dump(e+'\n');
 		}
+
+		try {
+			this.overrideExtensions();
+		}
+		catch(e) {
+			dump(e+'\n');
+		}
 // rap('utils/init end');
 	},
 	_initialized : false,
@@ -392,6 +409,10 @@ var TreeStyleTabUtils = {
 		this.AeroPeek = ns.AeroPeek;
 	},
  
+	overrideExtensions : function TSTUtils_overrideExtensions() 
+	{
+	},
+ 
 	updateNarrowScrollbarStyle : function TSTUtils_updateNarrowScrollbarStyle() 
 	{
 		const SSS = Cc['@mozilla.org/content/style-sheet-service;1']
@@ -493,7 +514,9 @@ var TreeStyleTabUtils = {
 		while (targets.hasMoreElements())
 		{
 			let target = targets.getNext()
-							.QueryInterface(Ci.nsIDOMWindowInternal);
+							.QueryInterface(Ci.nsIDOMWindow);
+			if ('nsIDOMWindowInternal' in Ci) // for Firefox 7 or olders
+				target = target.QueryInterface(Ci.nsIDOMWindowInternal);
 			windows.push(target);
 		}
 
@@ -1975,6 +1998,16 @@ var TreeStyleTabUtils = {
 		).singleNodeValue;
 	},
  
+	getSiblingTabs : function TSTUtils_getSiblingTabs(aTab) /* PUBLIC API */
+	{
+		var parent = this.getParentTab(aTab);
+
+		var siblings = parent && parent.parentNode ? this.getChildTabs(parent) : this.visibleRootTabs ;
+		return siblings.filter(function(aSiblingTab) {
+			return aSiblingTab != aTab;
+		});
+	},
+ 
 	getChildTabs : function TSTUtils_getChildTabs(aTab, aAllTabsArray) /* PUBLIC API */ 
 	{
 		var tabs = [];
diff --git a/modules/window.js b/modules/window.js
index 6c21be2..85a3cf1 100755
--- a/modules/window.js
+++ b/modules/window.js
@@ -225,6 +225,8 @@ TreeStyleTabWindow.prototype = {
  
 	shouldOpenSearchResultAsChild : function TSTWindow_shouldOpenSearchResultAsChild(aTerm) 
 	{
+		aTerm = aTerm.replace(/^\s+|\s+$/g, '');
+
 		var mode = this.getTreePref('autoAttach.searchResult');
 		if (mode == this.kSEARCH_RESULT_ATTACH_ALWAYS) {
 			return true;
@@ -241,7 +243,7 @@ TreeStyleTabWindow.prototype = {
 			if (!aWindow || !(aWindow instanceof Ci.nsIDOMWindow))
 				return false;
 			var selection = aWindow.getSelection();
-			if (selection && selection.toString() == aTerm)
+			if (selection && selection.toString().replace(/^\s+|\s+$/g, '') == aTerm)
 				return true;
 			return aWindow.frames ? Array.slice(aWindow.frames).some(arguments.callee) : false ;
 		})(w);
@@ -460,7 +462,9 @@ TreeStyleTabWindow.prototype = {
 		// Init autohide service only if it have to be activated.
 		if (this.isAutoHide)
 			this.onPrefChange('extensions.treestyletab.tabbar.autoHide.mode');
+
 		this.onPrefChange('extensions.treestyletab.autoCollapseExpandSubtreeOnSelect.whileFocusMovingByShortcut');
+		this.onPrefChange('extensions.treestyletab.pinnedTab.width');
 // rap('window/init end');
 	},
 	initialized : false,
@@ -1557,6 +1561,31 @@ TreeStyleTabWindow.prototype = {
 		event.initEvent(this.kEVENT_TYPE_PRINT_PREVIEW_EXITED.replace(/^nsDOM/, ''), true, false);
 		d.documentElement.dispatchEvent(event);
 	},
+ 
+	updatePinnedTabsSize : function TSTWindow_updatePinnedTabsSize()
+	{
+		if (this.pinnedTabsSizeStyle) {
+			this.pinnedTabsSizeStyle.parentNode.removeChild(this.pinnedTabsSizeStyle);
+			this.pinnedTabsSizeStyle = null;
+		}
+
+		var style = ['.tabbrowser-tabs[treestyletab-mode="vertical"] .tabbrowser-tab[pinned="true"] {'];
+		style.push('height: '+Math.max(this.MIN_PINNED_TAB_HEIGHT, this.pinnedTabHeight)+'px;');
+		style.push('}');
+
+		var d = this.document;
+		var pi = d.createProcessingInstruction(
+					'xml-stylesheet',
+					'type="text/css" href="data:text/css,'+encodeURIComponent(style.join(''))+'"'
+				);
+		d.insertBefore(pi, d.documentElement);
+		this.pinnedTabsSizeStyle = pi;
+	},
+	MIN_PINNED_TAB_WIDTH : 24,
+	MIN_PINNED_TAB_HEIGHT : 24,
+	pinnedTabWidth : 24,
+	pinnedTabHeight : 24,
+	pinnedTabsSizeStyle : null,
   
 	observe : function TSTWindow_observe(aSubject, aTopic, aData) 
 	{
@@ -1607,6 +1636,16 @@ TreeStyleTabWindow.prototype = {
 					this.endListenKeyEventsFor(this.LISTEN_FOR_AUTOEXPAND_BY_FOCUSCHANGE);
 				break;
 
+			case 'extensions.treestyletab.pinnedTab.width':
+				this.pinnedTabWidth = value;
+				this.updatePinnedTabsSize();
+				return;
+
+			case 'extensions.treestyletab.pinnedTab.height':
+				this.pinnedTabHeight = value;
+				this.updatePinnedTabsSize();
+				return;
+
 			default:
 				break;
 		}

-- 
Show tabs like a tree



More information about the Pkg-mozext-commits mailing list