[Pkg-mozext-commits] [SCM] Show tabs like a tree branch, master, updated. debian/0.12.2011061701-1-6-gb1f1e04

Ximin Luo infinity0 at gmx.com
Sun Oct 9 11:56:17 UTC 2011


The following commit has been merged in the master branch:
commit 32eb63186d89e0116d59013db332489015ebb324
Author: Ximin Luo <infinity0 at gmx.com>
Date:   Sun Oct 9 12:54:36 2011 +0100

    Imported Upstream version 0.12.2011082901

diff --git a/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js b/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js
index d9a1ce0..901f5a8 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/bookmarksOverlay.js
@@ -277,10 +277,14 @@ var TreeStyleTabBookmarksService = {
 								else {
 									sv.readyToOpenNewTabGroup(null, treeStructure, TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_EXPAND_ALL_TREE);
 								}
-								replaceCurrentTab = false;
+								// replaceCurrentTab works only on Firefox 7 or earlier
+								// See: https://bugzilla.mozilla.org/show_bug.cgi?id=440093
+								if (typeof replaceCurrentTab !== 'undefined')
+									replaceCurrentTab = false;
 							}
 							else {
-								replaceCurrentTab = !!(TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_REPLACE);
+								if (typeof replaceCurrentTab !== 'undefined')
+									replaceCurrentTab = !!(TSTOpenGroupBookmarkBehavior & sv.kGROUP_BOOKMARK_REPLACE);
 							}
 						}
 						$1
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..19d1496 100755
--- a/chrome/treestyletab.jar!/content/treestyletab/windowHelperHacks.js
+++ b/chrome/treestyletab.jar!/content/treestyletab/windowHelperHacks.js
@@ -667,15 +667,29 @@ 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')) {
+		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) {
+				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 +720,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 +1109,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!/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/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..509e22d 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.2011082901"
                    em:creator="SHIMODA Hiroshi"
                    em:description="Show tabs like a tree."
                    em:homepageURL="http://piro.sakura.ne.jp/xul/_treestyletab.html.en"
@@ -166,7 +166,7 @@
     <em:targetApplication>
       <RDF:Description em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
                        em:minVersion="3.6"
-                       em:maxVersion="7.0a1" />
+                       em:maxVersion="7.*" />
     </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..c1b4413 100755
--- a/modules/browser.js
+++ b/modules/browser.js
@@ -387,30 +387,47 @@ 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 faviconized = width <= this.MIN_PINNED_TAB_WIDTH;
+
 		var inverted = this.position == 'left' && b.getAttribute(this.kINVERT_SCROLLBAR) == 'true';
 		var remainder = maxWidth - (maxCol * width);
 		var shrunkenOffset = ((inverted || 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';
 
+			let className = item.className.replace(removeFaviconizedClassPattern, '');
+			if (faviconized)
+				className += ' '+this.kFAVICONIZED;
+			if (className != item.className)
+				item.className = className;
+
+			style.width = width+'px';
 			if (inverted) {
 				/**
 				 * In a box with "direction: rtr", we have to position tabs
@@ -462,8 +479,6 @@ TreeStyleTabBrowser.prototype = {
 			aSelf._positionPinnedTabsWithDelayTimerArgs = null;
 		}, 0, this);
 	},
-	PINNED_TAB_DEFAULT_WIDTH : 24,
-	PINNED_TAB_DEFAULT_HEIGHT : 24,
  
 	resetPinnedTabs : function TSTBrowser_resetPinnedTabs() 
 	{
@@ -473,7 +488,7 @@ 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.MozMarginStart = style.marginLeft = style.marginRight = style.marginTop = '';
 		}
 	},
  
@@ -2175,6 +2190,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;
 		}
@@ -2434,6 +2453,26 @@ TreeStyleTabBrowser.prototype = {
 	lastScrollX : -1,
 	lastScrollY : -1,
 	
+	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 +2496,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!
@@ -2553,6 +2593,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 +2653,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 +2751,8 @@ TreeStyleTabBrowser.prototype = {
 		}
 
 		if (b.selectedTab == tab) {
+			if (nextFocusedTab && nextFocusedTab == toBeClosedSibling)
+				nextFocusedTab = this.getFirstChildTab(nextFocusedTab);
 			if (
 				nextFocusedTab &&
 				!nextFocusedTab.hidden
@@ -2734,6 +2789,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) ||
@@ -3706,18 +3786,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 +3902,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 +3928,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 +4001,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);
+			}
 		}
 	},
   
@@ -4286,11 +4373,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..e2b9494 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',
@@ -493,7 +494,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 +1978,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