Ctrl-Tabでのタブ切り替え時に、折りたたまれていないタブにだけフォーカスできるようにした
git-svn-id: http://www.cozmixng.org/repos/piro/treestyletab/trunk@1232 599a83e7-65a4-db11-8015-0010dcdd6dc2
This commit is contained in:
parent
efd3140667
commit
d146e00622
@ -21,6 +21,9 @@
|
|||||||
name="extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab"
|
name="extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab"
|
||||||
type="bool"
|
type="bool"
|
||||||
inverted="true"/>
|
inverted="true"/>
|
||||||
|
<preference id="extensions.treestyletab.focusMode"
|
||||||
|
name="extensions.treestyletab.focusMode"
|
||||||
|
type="int"/>
|
||||||
<preference id="browser.link.open_newwindow"
|
<preference id="browser.link.open_newwindow"
|
||||||
name="browser.link.open_newwindow"
|
name="browser.link.open_newwindow"
|
||||||
type="int"/>
|
type="int"/>
|
||||||
@ -38,6 +41,11 @@
|
|||||||
<checkbox id="extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab-check"
|
<checkbox id="extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab-check"
|
||||||
preference="extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab"
|
preference="extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab"
|
||||||
label="&config.adoptChildrenToGrandParentOnRemoveTab;"/>
|
label="&config.adoptChildrenToGrandParentOnRemoveTab;"/>
|
||||||
|
<checkbox id="extensions.treestyletab.focusMode-check"
|
||||||
|
preference="extensions.treestyletab.focusMode"
|
||||||
|
label="&config.focusMode;"
|
||||||
|
onsyncfrompreference="return document.getElementById('extensions.treestyletab.focusMode').value == 0;"
|
||||||
|
onsynctopreference="return document.getElementById('extensions.treestyletab.focusMode-check').checked ? 0 : 1 ;"/>
|
||||||
<groupbox>
|
<groupbox>
|
||||||
<caption label="&config.open_newwindow.caption;"/>
|
<caption label="&config.open_newwindow.caption;"/>
|
||||||
<vbox>
|
<vbox>
|
||||||
|
@ -11,6 +11,9 @@ var TreeStyleTabService = {
|
|||||||
kTWISTY : 'treestyletab-tab-tree-twisty',
|
kTWISTY : 'treestyletab-tab-tree-twisty',
|
||||||
kTWISTY_CONTAINER : 'treestyletab-tab-tree-twisty-container',
|
kTWISTY_CONTAINER : 'treestyletab-tab-tree-twisty-container',
|
||||||
|
|
||||||
|
kFOCUS_ALL : 0,
|
||||||
|
kFOCUS_VISIBLE : 1,
|
||||||
|
|
||||||
levelMargin : 12,
|
levelMargin : 12,
|
||||||
|
|
||||||
NSResolver : {
|
NSResolver : {
|
||||||
@ -40,7 +43,7 @@ var TreeStyleTabService = {
|
|||||||
_SessionStore : null,
|
_SessionStore : null,
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
|
|
||||||
isEventFiredOnTabIcon : function(aEvent)
|
isEventFiredOnTabIcon : function(aEvent)
|
||||||
{
|
{
|
||||||
var tab = this.getTabFromEvent(aEvent);
|
var tab = this.getTabFromEvent(aEvent);
|
||||||
@ -72,6 +75,30 @@ var TreeStyleTabService = {
|
|||||||
return 'SplitBrowser' ? SplitBrowser.activeBrowser : gBrowser ;
|
return 'SplitBrowser' ? SplitBrowser.activeBrowser : gBrowser ;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
evaluateXPath : function(aExpression, aContext, aType)
|
||||||
|
{
|
||||||
|
if (!aType) aType = XPathResult.ORDERED_NODE_SNAPSHOT_TYPE;
|
||||||
|
try {
|
||||||
|
var xpathResult = document.evaluate(
|
||||||
|
aExpression,
|
||||||
|
aContext,
|
||||||
|
this.NSResolver,
|
||||||
|
aType,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return {
|
||||||
|
singleNodeValue : null,
|
||||||
|
snapshotLength : 0,
|
||||||
|
snapshotItem : function() {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return xpathResult;
|
||||||
|
},
|
||||||
|
|
||||||
getArrayFromXPathResult : function(aXPathResult)
|
getArrayFromXPathResult : function(aXPathResult)
|
||||||
{
|
{
|
||||||
var max = aXPathResult.snapshotLength;
|
var max = aXPathResult.snapshotLength;
|
||||||
@ -165,43 +192,23 @@ var TreeStyleTabService = {
|
|||||||
separator.setAttribute('hidden', true);
|
separator.setAttribute('hidden', true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getSeparators : function(aPopup)
|
getSeparators : function(aPopup)
|
||||||
{
|
{
|
||||||
try {
|
return this.evaluateXPath('descendant::xul:menuseparator', aPopup);
|
||||||
var xpathResult = document.evaluate(
|
|
||||||
'descendant::xul:menuseparator',
|
|
||||||
aPopup,
|
|
||||||
this.NSResolver,
|
|
||||||
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
return { snapshotLength : 0 };
|
|
||||||
}
|
|
||||||
return xpathResult;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getObsoleteSeparator : function(aPopup)
|
getObsoleteSeparator : function(aPopup)
|
||||||
{
|
{
|
||||||
try {
|
return this.evaluateXPath(
|
||||||
var xpathResult = document.evaluate(
|
'descendant::xul:menuseparator[not(@hidden)][not(following-sibling::*[not(@hidden)]) or not(preceding-sibling::*[not(@hidden)]) or local-name(following-sibling::*[not(@hidden)]) = "menuseparator"]',
|
||||||
'descendant::xul:menuseparator[not(@hidden)][not(following-sibling::*[not(@hidden)]) or not(preceding-sibling::*[not(@hidden)]) or local-name(following-sibling::*[not(@hidden)]) = "menuseparator"]',
|
aPopup,
|
||||||
aPopup,
|
XPathResult.FIRST_ORDERED_NODE_TYPE
|
||||||
this.NSResolver,
|
).singleNodeValue;
|
||||||
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return xpathResult.singleNodeValue;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Initializing */
|
/* Initializing */
|
||||||
|
|
||||||
init : function()
|
init : function()
|
||||||
{
|
{
|
||||||
if (!('gBrowser' in window)) return;
|
if (!('gBrowser' in window)) return;
|
||||||
@ -238,7 +245,7 @@ var TreeStyleTabService = {
|
|||||||
|
|
||||||
this.initTabBrowser(gBrowser);
|
this.initTabBrowser(gBrowser);
|
||||||
},
|
},
|
||||||
|
|
||||||
initTabBrowser : function(aTabBrowser)
|
initTabBrowser : function(aTabBrowser)
|
||||||
{
|
{
|
||||||
aTabBrowser.mTabContainer.addEventListener('TreeStyleTab:TabOpen', this, true);
|
aTabBrowser.mTabContainer.addEventListener('TreeStyleTab:TabOpen', this, true);
|
||||||
@ -255,8 +262,36 @@ var TreeStyleTabService = {
|
|||||||
/\{/,
|
/\{/,
|
||||||
<><![CDATA[
|
<><![CDATA[
|
||||||
{
|
{
|
||||||
if (aNewTab.__treestyletab__preventSelect) {
|
if (arguments[0].__treestyletab__preventSelect) {
|
||||||
aNewTab.__treestyletab__preventSelect = false;
|
arguments[0].__treestyletab__preventSelect = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
]]></>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
eval('aTabBrowser.mTabContainer.advanceSelectedTab = '+
|
||||||
|
aTabBrowser.mTabContainer.advanceSelectedTab.toSource().replace(
|
||||||
|
/\{/,
|
||||||
|
<><![CDATA[
|
||||||
|
{
|
||||||
|
if (TreeStyleTabService.getPref('extensions.treestyletab.focusMode') == 1) {
|
||||||
|
var xpathResult = TreeStyleTabService.evaluateXPath(
|
||||||
|
(arguments[0] < 0 ? 'preceding-sibling' : 'following-sibling' )+
|
||||||
|
'::xul:tab[not(@'+TreeStyleTabService.kCOLLAPSED+'="true")]',
|
||||||
|
this.selectedItem
|
||||||
|
);
|
||||||
|
var nextTab = xpathResult.snapshotItem(arguments[0] < 0 ? xpathResult.snapshotLength-1 : 0 );
|
||||||
|
if (!nextTab && arguments[1]) {
|
||||||
|
var xpathResult = TreeStyleTabService.evaluateXPath(
|
||||||
|
'child::xul:tab[not(@'+TreeStyleTabService.kCOLLAPSED+'="true")]',
|
||||||
|
this
|
||||||
|
);
|
||||||
|
nextTab = xpathResult.snapshotItem(arguments[0] < 0 ? xpathResult.snapshotLength-1 : 0 );
|
||||||
|
}
|
||||||
|
if (nextTab && nextTab != this.selectedItem) {
|
||||||
|
this.selectNewTab(nextTab, arguments[0], arguments[1]);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
]]></>
|
]]></>
|
||||||
@ -313,7 +348,7 @@ var TreeStyleTabService = {
|
|||||||
delete tabs;
|
delete tabs;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initTab : function(aTab, aTabBrowser)
|
initTab : function(aTab, aTabBrowser)
|
||||||
{
|
{
|
||||||
var id = 'tab-<'+Date.now()+'-'+parseInt(Math.random() * 65000)+'>';
|
var id = 'tab-<'+Date.now()+'-'+parseInt(Math.random() * 65000)+'>';
|
||||||
@ -391,7 +426,7 @@ var TreeStyleTabService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/* Event Handling */
|
/* Event Handling */
|
||||||
|
|
||||||
handleEvent : function(aEvent)
|
handleEvent : function(aEvent)
|
||||||
{
|
{
|
||||||
switch (aEvent.type)
|
switch (aEvent.type)
|
||||||
@ -641,9 +676,9 @@ var TreeStyleTabService = {
|
|||||||
this.collapseExpandTreesIntelligentlyFor(tab);
|
this.collapseExpandTreesIntelligentlyFor(tab);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Tab Utilities */
|
/* Tab Utilities */
|
||||||
|
|
||||||
getTabValue : function(aTab, aKey)
|
getTabValue : function(aTab, aKey)
|
||||||
{
|
{
|
||||||
var value = null;
|
var value = null;
|
||||||
@ -682,37 +717,21 @@ var TreeStyleTabService = {
|
|||||||
|
|
||||||
getTabById : function(aId, aTabBrowser)
|
getTabById : function(aId, aTabBrowser)
|
||||||
{
|
{
|
||||||
try {
|
return this.evaluateXPath(
|
||||||
var xpathResult = document.evaluate(
|
'descendant::xul:tab[@'+this.kID+' = "'+aId+'"]',
|
||||||
'descendant::xul:tab[@'+this.kID+' = "'+aId+'"]',
|
aTabBrowser.mTabContainer,
|
||||||
aTabBrowser.mTabContainer,
|
XPathResult.FIRST_ORDERED_NODE_TYPE
|
||||||
this.NSResolver,
|
).singleNodeValue;
|
||||||
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return xpathResult.singleNodeValue;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getParentTabOf : function(aTab)
|
getParentTabOf : function(aTab)
|
||||||
{
|
{
|
||||||
var id = aTab.getAttribute(this.kID);
|
var id = aTab.getAttribute(this.kID);
|
||||||
try {
|
return this.evaluateXPath(
|
||||||
var xpathResult = document.evaluate(
|
'parent::*/child::xul:tab[contains(@'+this.kCHILDREN+', "'+id+'")]',
|
||||||
'parent::*/child::xul:tab[contains(@'+this.kCHILDREN+', "'+id+'")]',
|
aTab,
|
||||||
aTab,
|
XPathResult.FIRST_ORDERED_NODE_TYPE
|
||||||
this.NSResolver,
|
).singleNodeValue;
|
||||||
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return xpathResult.singleNodeValue;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getNextSiblingTabOf : function(aTab)
|
getNextSiblingTabOf : function(aTab)
|
||||||
@ -832,7 +851,7 @@ var TreeStyleTabService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/* Commands */
|
/* Commands */
|
||||||
|
|
||||||
adoptTabTo : function(aChild, aParent, aInfo)
|
adoptTabTo : function(aChild, aParent, aInfo)
|
||||||
{
|
{
|
||||||
if (!aChild || !aParent) return;
|
if (!aChild || !aParent) return;
|
||||||
@ -1010,43 +1029,38 @@ var TreeStyleTabService = {
|
|||||||
expandedParentTabs.push(parentTab.getAttribute(this.kID));
|
expandedParentTabs.push(parentTab.getAttribute(this.kID));
|
||||||
}
|
}
|
||||||
expandedParentTabs = expandedParentTabs.join('|');
|
expandedParentTabs = expandedParentTabs.join('|');
|
||||||
try {
|
|
||||||
var xpathResult = document.evaluate(
|
|
||||||
'child::xul:tab[@'+this.kCHILDREN+' and not(@'+this.kCOLLAPSED+'="true") and not(@'+this.kSUBTREE_COLLAPSED+'="true") and not(contains("'+expandedParentTabs+'", @'+this.kID+'))]',
|
|
||||||
b.mTabContainer,
|
|
||||||
this.NSResolver,
|
|
||||||
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
var collapseTab;
|
|
||||||
var dontCollapse;
|
|
||||||
for (var i = 0, maxi = xpathResult.snapshotLength; i < maxi; i++)
|
|
||||||
{
|
|
||||||
dontCollapse = false;
|
|
||||||
collapseTab = xpathResult.snapshotItem(i);
|
|
||||||
|
|
||||||
parentTab = this.getParentTabOf(collapseTab);
|
var xpathResult = this.evaluateXPath(
|
||||||
if (parentTab) {
|
'child::xul:tab[@'+this.kCHILDREN+' and not(@'+this.kCOLLAPSED+'="true") and not(@'+this.kSUBTREE_COLLAPSED+'="true") and not(contains("'+expandedParentTabs+'", @'+this.kID+'))]',
|
||||||
dontCollapse = true;
|
b.mTabContainer
|
||||||
do {
|
);
|
||||||
if (parentTab != parent) continue;
|
var collapseTab;
|
||||||
dontCollapse = false;
|
var dontCollapse;
|
||||||
break;
|
for (var i = 0, maxi = xpathResult.snapshotLength; i < maxi; i++)
|
||||||
}
|
{
|
||||||
while (parentTab = this.getParentTabOf(parentTab));
|
dontCollapse = false;
|
||||||
|
collapseTab = xpathResult.snapshotItem(i);
|
||||||
|
|
||||||
|
parentTab = this.getParentTabOf(collapseTab);
|
||||||
|
if (parentTab) {
|
||||||
|
dontCollapse = true;
|
||||||
|
do {
|
||||||
|
if (parentTab != parent) continue;
|
||||||
|
dontCollapse = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
while (parentTab = this.getParentTabOf(parentTab));
|
||||||
if (!dontCollapse)
|
|
||||||
this.collapseExpandTabSubTree(collapseTab, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dontCollapse)
|
||||||
|
this.collapseExpandTabSubTree(collapseTab, true);
|
||||||
}
|
}
|
||||||
catch(e) {
|
|
||||||
}
|
|
||||||
this.collapseExpandTabSubTree(aTab, false);
|
this.collapseExpandTabSubTree(aTab, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Pref Listener */
|
/* Pref Listener */
|
||||||
|
|
||||||
domain : 'extensions.treestyletab',
|
domain : 'extensions.treestyletab',
|
||||||
|
|
||||||
observe : function(aSubject, aTopic, aPrefName)
|
observe : function(aSubject, aTopic, aPrefName)
|
||||||
@ -1065,7 +1079,7 @@ var TreeStyleTabService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/* Save/Load Prefs */
|
/* Save/Load Prefs */
|
||||||
|
|
||||||
get Prefs()
|
get Prefs()
|
||||||
{
|
{
|
||||||
if (!this._Prefs) {
|
if (!this._Prefs) {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
pref("extensions.treestyletab.autoCollapseExpandSubTreeOnSelect", true);
|
pref("extensions.treestyletab.autoCollapseExpandSubTreeOnSelect", true);
|
||||||
pref("extensions.treestyletab.autoExpandSubTreeOnAppendChild", true);
|
pref("extensions.treestyletab.autoExpandSubTreeOnAppendChild", true);
|
||||||
pref("extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab", true);
|
pref("extensions.treestyletab.adoptChildrenToGrandParentOnRemoveTab", true);
|
||||||
|
// 0 = default, 1 = only visible tabs
|
||||||
|
pref("extensions.treestyletab.focusMode", 1);
|
||||||
|
|
||||||
pref("browser.link.open_newwindow.restriction", 0);
|
pref("browser.link.open_newwindow.restriction", 0);
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
<!ENTITY config.adoptChildrenToGrandParentOnRemoveTab "Liberate child tabs from the tree when the parent tab is closed">
|
<!ENTITY config.adoptChildrenToGrandParentOnRemoveTab "Liberate child tabs from the tree when the parent tab is closed">
|
||||||
|
|
||||||
|
<!ENTITY config.focusMode "Focus to the next/previous tab even if it is invisible, by Control(Command)-Tab">
|
||||||
|
|
||||||
<!ENTITY config.open_newwindow.caption "New window opened from links in webpages unexpectedly">
|
<!ENTITY config.open_newwindow.caption "New window opened from links in webpages unexpectedly">
|
||||||
<!ENTITY config.open_newwindow.window "Open as Window">
|
<!ENTITY config.open_newwindow.window "Open as Window">
|
||||||
<!ENTITY config.open_newwindow.tab "Open as Tab (default)">
|
<!ENTITY config.open_newwindow.tab "Open as Tab (default)">
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
<!ENTITY config.adoptChildrenToGrandParentOnRemoveTab "親のタブを閉じたら子孫のタブをツリーから解放する">
|
<!ENTITY config.adoptChildrenToGrandParentOnRemoveTab "親のタブを閉じたら子孫のタブをツリーから解放する">
|
||||||
|
|
||||||
|
<!ENTITY config.focusMode "Control(Command)-Tabでタブを切り替える時、折りたたまれたタブにもフォーカスする">
|
||||||
|
|
||||||
<!ENTITY config.open_newwindow.caption "Webページのリンクから勝手に開かれたウィンドウの制御">
|
<!ENTITY config.open_newwindow.caption "Webページのリンクから勝手に開かれたウィンドウの制御">
|
||||||
<!ENTITY config.open_newwindow.window "ウィンドウで開く">
|
<!ENTITY config.open_newwindow.window "ウィンドウで開く">
|
||||||
<!ENTITY config.open_newwindow.tab "タブで開く(初期値)">
|
<!ENTITY config.open_newwindow.tab "タブで開く(初期値)">
|
||||||
|
Loading…
Reference in New Issue
Block a user