Ctrl-Tabでのタブ切り替え時に、折りたたまれていないタブにだけフォーカスできるようにした

git-svn-id: http://www.cozmixng.org/repos/piro/treestyletab/trunk@1232 599a83e7-65a4-db11-8015-0010dcdd6dc2
This commit is contained in:
piro 2007-10-19 03:05:36 +00:00
parent efd3140667
commit d146e00622
5 changed files with 123 additions and 95 deletions

View File

@ -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>

View File

@ -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 : {
@ -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;
@ -168,36 +195,16 @@ var TreeStyleTabService = {
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 */
@ -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;
} }
]]></> ]]></>
@ -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)
@ -1010,38 +1029,33 @@ 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);
}, },

View File

@ -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);

View File

@ -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)">

View File

@ -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 "タブで開く(初期値)">