Control "muted" status of descendant tabs if the tab has a subtree and they are collapsed

This commit is contained in:
YUKI Hiroshi 2015-11-19 20:20:15 +09:00
parent 38928625a9
commit 92e03c52a9
2 changed files with 75 additions and 29 deletions

View File

@ -638,6 +638,20 @@ var TreeStyleTabWindowHelper = {
}, 'treeStyleTab'); }, 'treeStyleTab');
} }
},
initTabMethods : function TSTWH_initTabMethods(aTab, aTabBrowser)
{
if (aTab.__treestyletab__toggleMuteAudio &&
aTab.__treestyletab__toggleMuteAudio.toString() != aTab.toggleMuteAudio.toString())
return;
aTab.__treestyletab__toggleMuteAudio = aTab.toggleMuteAudio;
aTab.toggleMuteAudio = function(...aArgs) {
if (aTabBrowser.treeStyleTab.handleTabToggleMuteAudio(aTab))
return;
return aTab.__treestyletab__toggleMuteAudio.apply(this, aArgs);
};
} }
}; };

View File

@ -842,12 +842,10 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
w.addEventListener('SSWindowStateBusy', this, false); w.addEventListener('SSWindowStateBusy', this, false);
ReferenceCounter.add('w,SSWindowStateBusy,TSTBrowser,false'); ReferenceCounter.add('w,SSWindowStateBusy,TSTBrowser,false');
/* Currently we don't have to handle these events because the actual status is tracked by TabAttrModified events for the "soundplaying" attribute. However, in the future we possibly need to track the status from these raw events...
b.addEventListener('DOMAudioPlaybackStarted', this, false); b.addEventListener('DOMAudioPlaybackStarted', this, false);
ReferenceCounter.add('b,DOMAudioPlaybackStarted,TSTBrowser,false'); ReferenceCounter.add('b,DOMAudioPlaybackStarted,TSTBrowser,false');
b.addEventListener('DOMAudioPlaybackStopped', this, false); b.addEventListener('DOMAudioPlaybackStopped', this, false);
ReferenceCounter.add('b,DOMAudioPlaybackStopped,TSTBrowser,false'); ReferenceCounter.add('b,DOMAudioPlaybackStopped,TSTBrowser,false');
*/
b.addEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false); b.addEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false);
ReferenceCounter.add('b,nsDOMMultipleTabHandlerTabsClosing,TSTBrowser,false'); ReferenceCounter.add('b,nsDOMMultipleTabHandlerTabsClosing,TSTBrowser,false');
@ -1075,6 +1073,7 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.initTabAttributes(aTab); this.initTabAttributes(aTab);
this.initTabContents(aTab); this.initTabContents(aTab);
this.window.TreeStyleTabWindowHelper.initTabMethods(aTab, this.mTabBrowser);
if (!aTab.hasAttribute(this.kNEST)) if (!aTab.hasAttribute(this.kNEST))
aTab.setAttribute(this.kNEST, 0); aTab.setAttribute(this.kNEST, 0);
@ -2261,7 +2260,10 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.initTabAttributes(tab); this.initTabAttributes(tab);
this.initTabContents(tab); this.initTabContents(tab);
if (aSouldUpdateAsParent) if (aSouldUpdateAsParent)
this.updateTabAsParent(tab, true); this.updateTabAsParent(tab, {
dontUpdateAncestor : true
});
this.window.TreeStyleTabWindowHelper.initTabMethods(tab, this.mTabBrowser);
} }
}, },
@ -2335,12 +2337,10 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
w.removeEventListener('SSWindowStateBusy', this, false); w.removeEventListener('SSWindowStateBusy', this, false);
ReferenceCounter.remove('w,SSWindowStateBusy,TSTBrowser,false'); ReferenceCounter.remove('w,SSWindowStateBusy,TSTBrowser,false');
/*
b.removeEventListener('DOMAudioPlaybackStarted', this, false); b.removeEventListener('DOMAudioPlaybackStarted', this, false);
ReferenceCounter.remove('b,DOMAudioPlaybackStarted,TSTBrowser,false'); ReferenceCounter.remove('b,DOMAudioPlaybackStarted,TSTBrowser,false');
b.removeEventListener('DOMAudioPlaybackStopped', this, false); b.removeEventListener('DOMAudioPlaybackStopped', this, false);
ReferenceCounter.remove('b,DOMAudioPlaybackStopped,TSTBrowser,false'); ReferenceCounter.remove('b,DOMAudioPlaybackStopped,TSTBrowser,false');
*/
b.removeEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false); b.removeEventListener('nsDOMMultipleTabHandlerTabsClosing', this, false);
ReferenceCounter.remove('b,nsDOMMultipleTabHandlerTabsClosing,TSTBrowser,false'); ReferenceCounter.remove('b,nsDOMMultipleTabHandlerTabsClosing,TSTBrowser,false');
@ -2909,7 +2909,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.setTabValue(tab, this.kREALLY_SOUND_PLAYING, true); this.setTabValue(tab, this.kREALLY_SOUND_PLAYING, true);
else else
this.deleteTabValue(tab, this.kREALLY_SOUND_PLAYING); this.deleteTabValue(tab, this.kREALLY_SOUND_PLAYING);
this.updateTabAsParent(tab); this.updateTabAsParent(tab, {
dontUpdateCount : true
});
return; return;
case 'muted': case 'muted':
@ -2917,7 +2919,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.setTabValue(tab, this.kREALLY_MUTED, true); this.setTabValue(tab, this.kREALLY_MUTED, true);
else else
this.deleteTabValue(tab, this.kREALLY_MUTED); this.deleteTabValue(tab, this.kREALLY_MUTED);
this.updateTabAsParent(tab); this.updateTabAsParent(tab, {
dontUpdateCount : true
});
return; return;
} }
}, this); }, this);
@ -3039,12 +3043,13 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
return this.needRestoreTree = true; return this.needRestoreTree = true;
/*
case 'DOMAudioPlaybackStarted': case 'DOMAudioPlaybackStarted':
{ {
let tab = this.getTabFromBrowser(aEvent.originalTarget); let tab = this.getTabFromBrowser(aEvent.originalTarget);
this.setTabValue(tab, this.kREALLY_SOUND_PLAYING, true); this.setTabValue(tab, this.kREALLY_SOUND_PLAYING, true);
this.updateTabAsParent(tab); this.updateTabAsParent(tab, {
dontUpdateCount : true
});
} }
return; return;
@ -3052,10 +3057,11 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
{ {
let tab = this.getTabFromBrowser(aEvent.originalTarget); let tab = this.getTabFromBrowser(aEvent.originalTarget);
this.deleteTabValue(tab, this.kREALLY_SOUND_PLAYING); this.deleteTabValue(tab, this.kREALLY_SOUND_PLAYING);
this.updateTabAsParent(tab); this.updateTabAsParent(tab, {
dontUpdateCount : true
});
} }
return; return;
*/
case 'nsDOMMultipleTabHandlerTabsClosing': case 'nsDOMMultipleTabHandlerTabsClosing':
@ -3570,6 +3576,8 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
// twisty vanished after the tab is moved!! // twisty vanished after the tab is moved!!
this.initTabContents(tab); this.initTabContents(tab);
this.window.TreeStyleTabWindowHelper.initTabMethods(tab, b);
// On Firefox 29, 30 and laters, reopened (restored) tab can be // On Firefox 29, 30 and laters, reopened (restored) tab can be
// placed in wrong place, because "TabMove" event fires before // placed in wrong place, because "TabMove" event fires before
// "SSTabRestoring" event and "kINSERT_BEFORE" information is // "SSTabRestoring" event and "kINSERT_BEFORE" information is
@ -4335,6 +4343,19 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
this.mTabBrowser.moveTabTo(aTab, newPos); this.mTabBrowser.moveTabTo(aTab, newPos);
}, },
handleTabToggleMuteAudio : function TSTBrowser_handleTabToggleMuteAudio(aTab)
{
if (this.isCollapsed(aTab) || this.isSubtreeCollapsed(aTab)) {
let children = this.getChildTabs(aTab);
let parentStatus = aTab.getAttribute('muted');
children.forEach(function(aChild) {
if (aChild.getAttribute('muted') == parentStatus)
aChild.toggleMuteAudio();
}, this);
}
return this.getTabValue(aTab, this.kREALLY_SOUND_PLAYING) != 'true';
},
correctChildTabsOrderWithDelay : function TSTBrowser_correctChildTabsOrderWithDelay(aTab) correctChildTabsOrderWithDelay : function TSTBrowser_correctChildTabsOrderWithDelay(aTab)
{ {
if (aTab.correctChildTabsOrderWithDelayTimer) if (aTab.correctChildTabsOrderWithDelayTimer)
@ -4559,7 +4580,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
onTabRestored : function TSTBrowser_onTabRestored(aEvent) onTabRestored : function TSTBrowser_onTabRestored(aEvent)
{ {
this.updateTabAsParent(aEvent.originalTarget, true); this.updateTabAsParent(aEvent.originalTarget, {
dontUpdateCount : true
});
delete aEvent.originalTarget.__treestyletab__restoredByUndoCloseTab; delete aEvent.originalTarget.__treestyletab__restoredByUndoCloseTab;
}, },
@ -5968,47 +5991,54 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
} }
}, },
updateTabAsParent : function TSTBrowser_updateTabAsParent(aTab, aDontUpdateAncestor) updateTabAsParent : function TSTBrowser_updateTabAsParent(aTab, aOptions)
{ {
if (!aTab || if (!aTab ||
!aTab.parentNode) // do nothing for closed tab! !aTab.parentNode) // do nothing for closed tab!
return; return;
var descendants = this.getDescendantTabs(aTab); aOptions = aOptions || {};
this.updateTabsCount(aTab, descendants);
this.updateTabSoundIndicator(aTab, descendants);
if (!aDontUpdateAncestor) { if (!aOptions.dontUpdateCount)
this.updateTabsCount(aTab);
this.updateTabSoundIndicator(aTab);
if (!aOptions.dontUpdateAncestor) {
let parent = this.getParentTab(aTab); let parent = this.getParentTab(aTab);
if (parent) if (parent)
this.updateTabAsParent(parent); this.updateTabAsParent(parent, aOptions);
} }
}, },
updateTabsCount : function TSTBrowser_updateTabsCount(aTab, aDescendants) updateTabsCount : function TSTBrowser_updateTabsCount(aTab)
{ {
var descendants = this.getDescendantTabs(aTab);
var count = this.document.getAnonymousElementByAttribute(aTab, 'class', this.kCOUNTER); var count = this.document.getAnonymousElementByAttribute(aTab, 'class', this.kCOUNTER);
if (count) { if (count) {
let value = aDescendants.length; let value = descendants.length;
if (this.counterRole == this.kCOUNTER_ROLE_ALL_TABS) if (this.counterRole == this.kCOUNTER_ROLE_ALL_TABS)
value += 1; value += 1;
count.setAttribute('value', value); count.setAttribute('value', value);
} }
}, },
updateTabSoundIndicator : function TSTBrowser_updateTabSoundIndicator(aTab, aDescendants) updateTabSoundIndicator : function TSTBrowser_updateTabSoundIndicator(aTab)
{ {
var hasSoundPlayingDescendant = aDescendants.some(function(aDescendant) { var children = this.getChildTabs(aTab);
return this.getTabValue(aDescendant, this.kREALLY_SOUND_PLAYING) == 'true';
var hasSoundPlayingChild = children.some(function(aChild) {
return aChild.getAttribute('soundplaying') == 'true';
}, this); }, this);
if (hasSoundPlayingDescendant || var reallySoundPlaying = this.getTabValue(aTab, this.kREALLY_SOUND_PLAYING) == 'true';
this.getTabValue(aTab, this.kREALLY_SOUND_PLAYING) == 'true') if (hasSoundPlayingChild ||
reallySoundPlaying)
aTab.setAttribute('soundplaying', true); aTab.setAttribute('soundplaying', true);
else else
aTab.removeAttribute('soundplaying'); aTab.removeAttribute('soundplaying');
var allDescendantsMuted = aDescendants.length > 0 && aDescendants.every(function(aDescendant) { var allChildrenMuted = children.length > 0 && children.every(function(aChild) {
return this.getTabValue(aDescendant, this.kREALLY_MUTED) == 'true'; return aChild.getAttribute('muted') == 'true';
}, this); }, this);
if (allDescendantsMuted || if ((allChildrenMuted && !reallySoundPlaying) ||
this.getTabValue(aTab, this.kREALLY_MUTED) == 'true') this.getTabValue(aTab, this.kREALLY_MUTED) == 'true')
aTab.setAttribute('muted', true); aTab.setAttribute('muted', true);
else else
@ -6021,7 +6051,9 @@ TreeStyleTabBrowser.prototype = inherit(TreeStyleTabWindow.prototype, {
for (let i = 0, maxi = tabs.length; i < maxi; i++) for (let i = 0, maxi = tabs.length; i < maxi; i++)
{ {
let tab = tabs[i]; let tab = tabs[i];
this.updateTabAsParent(tab, true); this.updateTabAsParent(tab, {
dontUpdateAncestor : true
});
} }
}, },