always restore all tree

This commit is contained in:
Piro / SHIMODA Hiroshi 2011-12-13 03:54:43 +09:00
parent b8fd343863
commit 8d981a7d13
4 changed files with 129 additions and 103 deletions

View File

@ -559,15 +559,6 @@ pref("extensions.treestyletab.undoCloseTabSet.behavior", 3);
*/ */
pref("extensions.treestyletab.repositionStatusPanel", true); pref("extensions.treestyletab.repositionStatusPanel", true);
/**
* "Fast restore" of tree structure on the startup. Recommended value is "1".
* 0 = Restore all trees based on SSTabRestoring.
* 1 = Restore trees in the current group (Panorama) before SSTabRestoring.
* Others (tabs in background groups) are restored based on SSTabRestoring.
* 2 = Restore all trees including background groups before SSTabRestoring.
*/
pref("extensions.treestyletab.fastRestoreTree.level", 1);
/** /**
* TST overrides some internal prefs of Firefox itself, because they can * TST overrides some internal prefs of Firefox itself, because they can
* conflict with TST features. They will be rolled back when TST is uninstalled. * conflict with TST features. They will be rolled back when TST is uninstalled.

View File

@ -783,6 +783,10 @@ TreeStyleTabBrowser.prototype = {
aTab.setAttribute(this.kALLOW_COLLAPSE, true); aTab.setAttribute(this.kALLOW_COLLAPSE, true);
let self = this; let self = this;
this.Deferred.next(function() { this.Deferred.next(function() {
// changed by someone!
if (self.getAttribute(self.kID) != id)
return;
if (!self.getTabValue(aTab, self.kID)) { if (!self.getTabValue(aTab, self.kID)) {
self.setTabValue(aTab, self.kID, id); self.setTabValue(aTab, self.kID, id);
if (!(id in self.tabsHash)) if (!(id in self.tabsHash))
@ -2280,27 +2284,46 @@ TreeStyleTabBrowser.prototype = {
if (!this.window.__SS_tabsToRestore || this.window.__SS_tabsToRestore <= 1) if (!this.window.__SS_tabsToRestore || this.window.__SS_tabsToRestore <= 1)
return; return;
var level = this.getTreePref('fastRestoreTree.level');
if (level <= this.kFAST_RESTORE_NONE)
return;
var restoreOnlyCurrentGroup = level < this.kFAST_RESTORE_ALL;
var tabs = this.getAllTabsArray(this.mTabBrowser); var tabs = this.getAllTabsArray(this.mTabBrowser);
tabs.reverse().filter(function(aTab) { tabs = tabs.filter(function(aTab) {
var id = this.getTabValue(aTab, this.kID); var id = this.getTabValue(aTab, this.kID);
if ( if (
!id || // tabs opened by externals applications !id || // tabs opened by externals applications
(restoreOnlyCurrentGroup && aTab.hidden) // tabs in background groups !aTab.linkedBrowser.__SS_restoreState
) )
return false; return false;
var alreadyRestored = id == aTab.getAttribute(this.kID); var currentId = aTab.getAttribute(this.kID);
var restored = id == currentId;
if (!restored) {
delete this.tabsHash[id];
aTab.setAttribute(this.kID, id); aTab.setAttribute(this.kID, id);
this.tabsHash[id] = aTab; this.tabsHash[id] = aTab;
}
var subTreeCollapsed = this.getTabValue(aTab, this.kSUBTREE_COLLAPSED) == 'true'; aTab.__treestyletab__structureRestored = true;
var children = this.getTabValue(aTab, this.kCHILDREN);
aTab.removeAttribute(this.kPARENT);
aTab.removeAttribute(this.kCHILDREN);
aTab.removeAttribute(this.kSUBTREE_COLLAPSED);
aTab.removeAttribute(this.kCOLLAPSED);
aTab.removeAttribute(this.kNEST);
this.updateTabCollapsed(aTab, false, true);
return true;
}, this);
this.updateAllTabsIndent(true);
tabs.reverse()
.filter(this.restoreOneTab, this)
.forEach(this.updateInsertionPositionInfo, this);
},
restoreOneTab : function TSTBrowser_restoreOneTab(aTab)
{
let subTreeCollapsed = this.getTabValue(aTab, this.kSUBTREE_COLLAPSED) == 'true';
let children = this.getTabValue(aTab, this.kCHILDREN);
this.deleteTabValue(aTab, this.kCHILDREN);
if (children) { if (children) {
subTreeCollapsed = this._restoreSubtreeCollapsedState(aTab, subTreeCollapsed); subTreeCollapsed = this._restoreSubtreeCollapsedState(aTab, subTreeCollapsed);
children.split('|').forEach(function(aChild) { children.split('|').forEach(function(aChild) {
@ -2316,12 +2339,7 @@ TreeStyleTabBrowser.prototype = {
}, this); }, this);
this.collapseExpandSubtree(aTab, subTreeCollapsed, true); this.collapseExpandSubtree(aTab, subTreeCollapsed, true);
} }
if (!alreadyRestored)
aTab.__treestyletab__structureRestored = true;
return true return true
}, this).forEach(this.updateInsertionPositionInfo, this);
}, },
/* DOM Event Handling */ /* DOM Event Handling */
@ -3193,7 +3211,7 @@ TreeStyleTabBrowser.prototype = {
onTabRestoring : function TSTBrowser_onTabRestoring(aEvent) onTabRestoring : function TSTBrowser_onTabRestoring(aEvent)
{ {
this.restoreStructure(aEvent.originalTarget); this.handleRestoredTab(aEvent.originalTarget);
/** /**
* Updating of the counter which is used to know how many tabs were * Updating of the counter which is used to know how many tabs were
@ -3239,7 +3257,7 @@ TreeStyleTabBrowser.prototype = {
RESTORED_TREE_COLLAPSED_STATE_LAST_STATE : -1, RESTORED_TREE_COLLAPSED_STATE_LAST_STATE : -1,
RESTORED_TREE_COLLAPSED_STATE_COLLAPSED : 0, RESTORED_TREE_COLLAPSED_STATE_COLLAPSED : 0,
RESTORED_TREE_COLLAPSED_STATE_EXPANDED : 1, RESTORED_TREE_COLLAPSED_STATE_EXPANDED : 1,
restoreStructure : function TSTBrowser_restoreStructure(aTab) handleRestoredTab : function TSTBrowser_handleRestoredTab(aTab)
{ {
var [id, mayBeDuplicated] = this._restoreTabId(aTab); var [id, mayBeDuplicated] = this._restoreTabId(aTab);
@ -3263,8 +3281,12 @@ TreeStyleTabBrowser.prototype = {
var closeSetId = !structureRestored && this._getCloseSetId(aTab, mayBeDuplicated); var closeSetId = !structureRestored && this._getCloseSetId(aTab, mayBeDuplicated);
var currentId = aTab.getAttribute(this.kID);
if (id != currentId) {
delete this.tabsHash[currentId];
this.setTabValue(aTab, this.kID, id); this.setTabValue(aTab, this.kID, id);
this.tabsHash[id] = aTab; this.tabsHash[id] = aTab;
}
if (structureRestored) { if (structureRestored) {
/** /**
@ -3274,7 +3296,6 @@ TreeStyleTabBrowser.prototype = {
* values. * values.
*/ */
[ [
this.kPARENT,
this.kINSERT_BEFORE, this.kINSERT_BEFORE,
this.kINSERT_AFTER this.kINSERT_AFTER
].forEach(function(aKey) { ].forEach(function(aKey) {
@ -3283,21 +3304,24 @@ TreeStyleTabBrowser.prototype = {
this.setTabValue(aTab, aKey, tab); this.setTabValue(aTab, aKey, tab);
}, this); }, this);
let children = this.getTabValue(aTab, this.kCHILDREN); let parentId = this.getTabValue(aTab, this.kPARENT);
if (children.split('|').every(function(aChild) { let parentTab = this.getTabById(parentId);
return this.getTabById(aChild); if (parentTab && parentTab._tPos < aTab._tPos)
}, this)) this.setTabValue(aTab, this.kPARENT, parentId);
this.setTabValue(aTab, this.kCHILDREN, children); else
this.deleteTabValue(aTab, this.kPARENT);
[ let ancestors = [aTab].concat(this.getAncestorTabs(aTab));
this.kSUBTREE_COLLAPSED, let children = this.getTabValue(aTab, this.kCHILDREN);
this.kCOLLAPSED, children = children.split('|').filter(function(aChild) {
this.kCOLLAPSED_DONE let tab = this.getTabById(aChild);
].forEach(function(aKey) { return ancestors.indexOf(tab) < 0;
var storedValue = this.getTabValue(aTab, aKey);
if (storedValue)
this.setTabValue(aTab, aKey, storedValue);
}, this); }, this);
this.setTabValue(aTab, this.kCHILDREN, children.join('|'));
let subtreeCollapsed = this.getTabValue(aTab, this.kSUBTREE_COLLAPSED);
if (subtreeCollapsed != aTab.getAttribute(this.kSUBTREE_COLLAPSED))
this.collapseExpandSubtree(aTab, subtreeCollapsed == 'true', true);
} }
else { else {
if (closeSetId) if (closeSetId)
@ -4374,15 +4398,13 @@ TreeStyleTabBrowser.prototype = {
return; return;
} }
currentParent = aParent; // avoid recursive tree
do { var ancestors = [aParent].concat(this.getAncestorTabs(aChild));
if (currentParent != aChild) continue; if (ancestors.indexOf(aChild) > -1)
// this.fireAttachedEvent(aChild, aParent);
return; return;
}
while (currentParent = this.getParentTab(currentParent));
shouldInheritIndent = ( currentParent = ancestors[ancestors.length-1];
var shouldInheritIndent = (
!currentParent || !currentParent ||
(currentParent.getAttribute(this.kNEST) == aParent.getAttribute(this.kNEST)) (currentParent.getAttribute(this.kNEST) == aParent.getAttribute(this.kNEST))
); );
@ -5288,9 +5310,9 @@ TreeStyleTabBrowser.prototype = {
// !this.canCollapseSubtree(this.getParentTab(aTab)) // !this.canCollapseSubtree(this.getParentTab(aTab))
) { ) {
if (aCollapsed) if (aCollapsed)
this.setTabValue(aTab, this.kCOLLAPSED_DONE, true); aTab.setAttribute(this.kCOLLAPSED_DONE, true);
else else
this.deleteTabValue(aTab, this.kCOLLAPSED_DONE); aTab.removeAttribute(this.kCOLLAPSED_DONE);
aTab.removeAttribute(this.kCOLLAPSING_PHASE); aTab.removeAttribute(this.kCOLLAPSING_PHASE);
if (CSSTransitionEnabled) { if (CSSTransitionEnabled) {
@ -5315,7 +5337,7 @@ TreeStyleTabBrowser.prototype = {
if (!aCollapsed) { if (!aCollapsed) {
aTab.setAttribute(offsetAttr, maxMargin); aTab.setAttribute(offsetAttr, maxMargin);
this.deleteTabValue(aTab, this.kCOLLAPSED_DONE); aTab.removeAttribute(this.kCOLLAPSED_DONE);
} }
var radian = 90 * Math.PI / 180; var radian = 90 * Math.PI / 180;
@ -5342,7 +5364,7 @@ TreeStyleTabBrowser.prototype = {
} }
if (aTime >= aDuration || stopAnimation) { if (aTime >= aDuration || stopAnimation) {
delete aTab.__treestyletab__updateTabCollapsedTask; delete aTab.__treestyletab__updateTabCollapsedTask;
if (aCollapsed) self.setTabValue(aTab, self.kCOLLAPSED_DONE, true); if (aCollapsed) aTab.setAttribute(self.kCOLLAPSED_DONE, true);
if (!CSSTransitionEnabled) { if (!CSSTransitionEnabled) {
aTab.style.removeProperty(self.collapseCSSProp); aTab.style.removeProperty(self.collapseCSSProp);
aTab.style.removeProperty('opacity'); aTab.style.removeProperty('opacity');

View File

@ -243,10 +243,6 @@ var TreeStyleTabUtils = {
kCLOSE_PARENT_BEHAVIOR_SIMPLY_DETACH_ALL_CHILDREN : 4, kCLOSE_PARENT_BEHAVIOR_SIMPLY_DETACH_ALL_CHILDREN : 4,
kCLOSE_PARENT_BEHAVIOR_CLOSE_ALL_CHILDREN : 2, // onTabRemoved only kCLOSE_PARENT_BEHAVIOR_CLOSE_ALL_CHILDREN : 2, // onTabRemoved only
kFAST_RESTORE_NONE : 0,
kFAST_RESTORE_CURRENT_GROUP : 1,
kFAST_RESTORE_ALL : 2,
MAX_TABBAR_SIZE_RATIO : 0.8, MAX_TABBAR_SIZE_RATIO : 0.8,
DEFAULT_SHRUNKEN_WIDTH_RATIO : 0.67, DEFAULT_SHRUNKEN_WIDTH_RATIO : 0.67,
@ -1908,27 +1904,53 @@ var TreeStyleTabUtils = {
{ {
if (!aTab) return null; if (!aTab) return null;
var parent;
if (this.tabsHash) { // XPath-less implementation if (this.tabsHash) { // XPath-less implementation
let parent = this.getTabById(aTab.getAttribute(this.kPARENT)); parent = this.getTabById(aTab.getAttribute(this.kPARENT));
return (parent && parent != aTab) ? parent : null ;
} }
else {
return this.evaluateXPath( parent = this.evaluateXPath(
'preceding-sibling::xul:tab[@'+this.kID+'="'+aTab.getAttribute(this.kPARENT)+'"][1]', 'preceding-sibling::xul:tab[@'+this.kID+'="'+aTab.getAttribute(this.kPARENT)+'"][1]',
aTab, aTab,
Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
).singleNodeValue; ).singleNodeValue;
}
return (parent && parent != aTab) ? parent : null ;
}, },
getAncestorTabs : function TSTUtils_getAncestorTabs(aTab) /* PUBLIC API */ getAncestorTabs : function TSTUtils_getAncestorTabs(aTab) /* PUBLIC API */
{ {
var tabs = []; var tabs = [aTab];
var parentTab = aTab; var parentTab = aTab;
while (parentTab = this.getParentTab(parentTab)) while (parentTab = this.getParentTab(parentTab))
{ {
tabs.push(parentTab); if (tabs.indexOf(parentTab) > -1) {
let message = 'recursive tree detected!\n'+
tabs.concat([parentTab])
.reverse().map(function(aTab) {
return ' '+aTab._tPos+' : '+
aTab.label+'\n '+
aTab.getAttribute(this.kID);
}, this).join('\n');
dump(message+'\n');
break;
} }
return tabs;
if (aTab._tPos < parentTab._tPos) {
let message = 'broken tree detected!\n'+
tabs.concat([parentTab])
.reverse().map(function(aTab) {
return ' '+aTab._tPos+' : '+
aTab.label+'\n '+
aTab.getAttribute(this.kID);
}, this).join('\n');
dump(message+'\n');
}
tabs.push(parentTab);
aTab = parentTab;
}
return tabs.slice(1);
}, },
getRootTab : function TSTUtils_getRootTab(aTab) /* PUBLIC API */ getRootTab : function TSTUtils_getRootTab(aTab) /* PUBLIC API */
@ -1936,13 +1958,8 @@ var TreeStyleTabUtils = {
if (!aTab) return null; if (!aTab) return null;
if (this.tabsHash) { // XPath-less implementation if (this.tabsHash) { // XPath-less implementation
let parent = aTab; let ancestors = this.getAncestorTabs(aTab);
let root = aTab; return ancestors.length ? ancestors[ancestors.length-1] : aTab ;
while (parent = this.getParentTab(parent))
{
root = parent;
}
return root;
} }
return this.evaluateXPath( return this.evaluateXPath(
@ -2162,15 +2179,11 @@ var TreeStyleTabUtils = {
if (this.tabsHash) { // XPath-less implementation if (this.tabsHash) { // XPath-less implementation
let parent = this.getParentTab(aTab); let parent = this.getParentTab(aTab);
if (!aParent || !parent || aParent != parent) { if (!aParent || !parent || aParent != parent) {
parent = aTab; let ancestors = this.getAncestorTabs(aTab);
while (parent && parent != aParent) let index = ancestors.indexOf(aParent);
{ if (index < 1)
aTab = parent;
parent = this.getParentTab(parent);
}
if (parent != aParent)
return -1; return -1;
aParent = parent; aTab = ancestors[index-1];
} }
if (aParent) { if (aParent) {

View File

@ -1199,7 +1199,7 @@ TreeStyleTabWindow.prototype = {
this._restoringTabs.forEach(function(aTab) { this._restoringTabs.forEach(function(aTab) {
try { try {
var b = this.getTabBrowserFromChild(aTab); var b = this.getTabBrowserFromChild(aTab);
if (b) b.treeStyleTab.restoreStructure(aTab, true); if (b) b.treeStyleTab.handleRestoredTab(aTab);
} }
catch(e) { catch(e) {
} }