選択範囲のリンクを子タブとして開く機能を追加
git-svn-id: http://www.cozmixng.org/repos/piro/treestyletab/trunk@1284 599a83e7-65a4-db11-8015-0010dcdd6dc2
This commit is contained in:
parent
9a8fe69208
commit
1542562437
@ -25,6 +25,9 @@
|
|||||||
<preference id="extensions.treestyletab.tabbar.invertUI"
|
<preference id="extensions.treestyletab.tabbar.invertUI"
|
||||||
name="extensions.treestyletab.tabbar.invertUI"
|
name="extensions.treestyletab.tabbar.invertUI"
|
||||||
type="bool"/>
|
type="bool"/>
|
||||||
|
<preference id="extensions.treestyletab.show.openSelectionLinks"
|
||||||
|
name="extensions.treestyletab.show.openSelectionLinks"
|
||||||
|
type="bool"/>
|
||||||
</preferences>
|
</preferences>
|
||||||
|
|
||||||
<checkbox id="extensions.treestyletab.tabbar.scroll.smooth-check"
|
<checkbox id="extensions.treestyletab.tabbar.scroll.smooth-check"
|
||||||
@ -64,6 +67,9 @@
|
|||||||
src="chrome://treestyletab/content/res/style-mixed.png"/>
|
src="chrome://treestyletab/content/res/style-mixed.png"/>
|
||||||
</radiogroup>
|
</radiogroup>
|
||||||
</groupbox>
|
</groupbox>
|
||||||
|
<checkbox id="extensions.treestyletab.show.openSelectionLinks-check"
|
||||||
|
preference="extensions.treestyletab.show.openSelectionLinks"
|
||||||
|
label="&config.show.openSelectionLinks;"/>
|
||||||
</prefpane>
|
</prefpane>
|
||||||
|
|
||||||
<prefpane id="prefpane-tab" label="&config.tabs.tab;"
|
<prefpane id="prefpane-tab" label="&config.tabs.tab;"
|
||||||
|
@ -84,6 +84,14 @@ var TreeStyleTabService = {
|
|||||||
},
|
},
|
||||||
_ObserverService : null,
|
_ObserverService : null,
|
||||||
|
|
||||||
|
get IOService() {
|
||||||
|
if (!this._IOService) {
|
||||||
|
this._IOService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
|
||||||
|
}
|
||||||
|
return this._IOService;
|
||||||
|
},
|
||||||
|
_IOService : null,
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
|
|
||||||
readyToOpenChildTab : function(aFrameOrTabBrowser, aMultiple)
|
readyToOpenChildTab : function(aFrameOrTabBrowser, aMultiple)
|
||||||
@ -300,6 +308,21 @@ var TreeStyleTabService = {
|
|||||||
return aTabs;
|
return aTabs;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
makeURIFromSpec : function(aURI)
|
||||||
|
{
|
||||||
|
var newURI;
|
||||||
|
aURI = aURI || '';
|
||||||
|
if (aURI && String(aURI).indexOf('file:') == 0) {
|
||||||
|
var fileHandler = this.IOService.getProtocolHandler('file').QueryInterface(Components.interfaces.nsIFileProtocolHandler);
|
||||||
|
var tempLocalFile = fileHandler.getFileFromURLSpec(aURI);
|
||||||
|
newURI = this.IOService.newFileURI(tempLocalFile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newURI = this.IOService.newURI(aURI, null, null);
|
||||||
|
}
|
||||||
|
return newURI;
|
||||||
|
},
|
||||||
|
|
||||||
/* Initializing */
|
/* Initializing */
|
||||||
|
|
||||||
init : function()
|
init : function()
|
||||||
@ -308,6 +331,8 @@ var TreeStyleTabService = {
|
|||||||
|
|
||||||
window.removeEventListener('load', this, false);
|
window.removeEventListener('load', this, false);
|
||||||
|
|
||||||
|
document.getElementById('contentAreaContextMenu').addEventListener('popupshowing', this, false);
|
||||||
|
|
||||||
if (this.getPref('extensions.treestyletab.inSubbrowsers.enabled')) {
|
if (this.getPref('extensions.treestyletab.inSubbrowsers.enabled')) {
|
||||||
var appcontent = document.getElementById('appcontent');
|
var appcontent = document.getElementById('appcontent');
|
||||||
appcontent.addEventListener('SubBrowserAdded', this, false);
|
appcontent.addEventListener('SubBrowserAdded', this, false);
|
||||||
@ -832,6 +857,8 @@ catch(e) {
|
|||||||
|
|
||||||
window.removeEventListener('unload', this, false);
|
window.removeEventListener('unload', this, false);
|
||||||
|
|
||||||
|
document.getElementById('contentAreaContextMenu').removeEventListener('popupshowing', this, false);
|
||||||
|
|
||||||
if (this.getPref('extensions.treestyletab.inSubbrowsers.enabled')) {
|
if (this.getPref('extensions.treestyletab.inSubbrowsers.enabled')) {
|
||||||
var appcontent = document.getElementById('appcontent');
|
var appcontent = document.getElementById('appcontent');
|
||||||
appcontent.removeEventListener('SubBrowserAdded', this, false);
|
appcontent.removeEventListener('SubBrowserAdded', this, false);
|
||||||
@ -949,7 +976,8 @@ catch(e) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case 'popupshowing':
|
case 'popupshowing':
|
||||||
// this.showHideMenuItems(aEvent.target);
|
if (aEvent.target != aEvent.currentTarget) return;
|
||||||
|
this.initContextMenu();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'SubBrowserAdded':
|
case 'SubBrowserAdded':
|
||||||
@ -1198,6 +1226,20 @@ catch(e) {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
initContextMenu : function()
|
||||||
|
{
|
||||||
|
var item = document.getElementById('context-treestyletab-openSelectionLinks');
|
||||||
|
var sep = document.getElementById('context-treestyletab-openSelectionLinks-separator');
|
||||||
|
if (this.getPref('extensions.treestyletab.show.openSelectionLinks') && this.getSelectionLinks().length) {
|
||||||
|
item.removeAttribute('hidden');
|
||||||
|
sep.removeAttribute('hidden');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.setAttribute('hidden', true);
|
||||||
|
sep.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/* Tab Utilities */
|
/* Tab Utilities */
|
||||||
|
|
||||||
getTabValue : function(aTab, aKey)
|
getTabValue : function(aTab, aKey)
|
||||||
@ -2178,6 +2220,119 @@ catch(e) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openSelectionLinks : function()
|
||||||
|
{
|
||||||
|
var links = this.getSelectionLinks();
|
||||||
|
if (!links.length) return;
|
||||||
|
|
||||||
|
var b = this.browser;
|
||||||
|
var targetWindow = document.commandDispatcher.focusedWindow;
|
||||||
|
if (!targetWindow || targetWindow.top == window)
|
||||||
|
targetWindow = b.contentWindow;
|
||||||
|
|
||||||
|
var referrer = this.makeURIFromSpec(targetWindow.location.href);
|
||||||
|
|
||||||
|
this.readyToOpenChildTab(targetWindow, true);
|
||||||
|
var self = this;
|
||||||
|
links.forEach(function(aItem, aIndex) {
|
||||||
|
var tab = b.addTab(aItem.uri, referrer);
|
||||||
|
if (aIndex == 0 && !self.getPref('browser.tabs.loadInBackground'))
|
||||||
|
b.selectedTab = tab;
|
||||||
|
});
|
||||||
|
this.stopToOpenChildTab(targetWindow);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelectionLinks : function()
|
||||||
|
{
|
||||||
|
var links = [];
|
||||||
|
|
||||||
|
var targetWindow = document.commandDispatcher.focusedWindow;
|
||||||
|
if (!targetWindow || targetWindow.top == window)
|
||||||
|
targetWindow = this.browser.contentWindow;
|
||||||
|
|
||||||
|
var selection = targetWindow.getSelection();
|
||||||
|
if (!selection || !selection.rangeCount)
|
||||||
|
return links;
|
||||||
|
|
||||||
|
const count = selection.rangeCount;
|
||||||
|
var range,
|
||||||
|
node,
|
||||||
|
link,
|
||||||
|
uri,
|
||||||
|
nodeRange = targetWindow.document.createRange();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
range = selection.getRangeAt(0);
|
||||||
|
node = range.startContainer;
|
||||||
|
|
||||||
|
traceTree:
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
nodeRange.selectNode(node);
|
||||||
|
|
||||||
|
// 「ノードの終端が、選択範囲の先端より後にあるかどうか」をチェック。
|
||||||
|
// 後にあるならば、そのノードは選択範囲内にあると考えられる。
|
||||||
|
if (nodeRange.compareBoundaryPoints(Range.START_TO_END, range) > -1) {
|
||||||
|
// 「ノードの先端が、選択範囲の終端より後にあるかどうか」をチェック。
|
||||||
|
// 後にあるならば、そのノードは選択範囲外にあると考えられる。
|
||||||
|
if (nodeRange.compareBoundaryPoints(Range.END_TO_START, range) > 0) {
|
||||||
|
// 「リンクテキストが実際には選択されていないリンク」については除外する
|
||||||
|
if (
|
||||||
|
links.length &&
|
||||||
|
range.startContainer.nodeType != Node.ELEMENT_NODE &&
|
||||||
|
range.startOffset == range.startContainer.nodeValue.length &&
|
||||||
|
links[0].node == this.getParentLink(range.startContainer)
|
||||||
|
)
|
||||||
|
links.splice(0, 1);
|
||||||
|
|
||||||
|
if (
|
||||||
|
links.length &&
|
||||||
|
range.endContainer.nodeType != Node.ELEMENT_NODE &&
|
||||||
|
range.endOffset == 0 &&
|
||||||
|
links[links.length-1].node == this.getParentLink(range.endContainer)
|
||||||
|
)
|
||||||
|
links.splice(links.length-1, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (link = this.getParentLink(node)) {
|
||||||
|
try {
|
||||||
|
uri = link.href;
|
||||||
|
if (uri && uri.indexOf('mailto:') < 0)
|
||||||
|
links.push({ node : link, uri : uri });
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.hasChildNodes() && !link) {
|
||||||
|
node = node.firstChild;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (!node.nextSibling)
|
||||||
|
{
|
||||||
|
node = node.parentNode;
|
||||||
|
if (!node) break traceTree;
|
||||||
|
}
|
||||||
|
node = node.nextSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeRange.detach();
|
||||||
|
|
||||||
|
return links;
|
||||||
|
},
|
||||||
|
|
||||||
|
getParentLink : function(aNode)
|
||||||
|
{
|
||||||
|
var node = aNode;
|
||||||
|
while (!node.href && node.parentNode)
|
||||||
|
node = node.parentNode;
|
||||||
|
|
||||||
|
return node.href ? node : null ;
|
||||||
|
},
|
||||||
|
|
||||||
/* Pref Listener */
|
/* Pref Listener */
|
||||||
|
|
||||||
domain : 'extensions.treestyletab',
|
domain : 'extensions.treestyletab',
|
||||||
|
@ -10,6 +10,16 @@
|
|||||||
<script src="hacks.js" type="application/x-javascript"/>
|
<script src="hacks.js" type="application/x-javascript"/>
|
||||||
|
|
||||||
|
|
||||||
|
<popup id="contentAreaContextMenu">
|
||||||
|
<menuseparator id="context-treestyletab-openSelectionLinks-separator"
|
||||||
|
insertafter="context-sep-open"/>
|
||||||
|
<menuitem id="context-treestyletab-openSelectionLinks"
|
||||||
|
insertafter="context-sep-open"
|
||||||
|
label="&context.openSelectionLinks.label;"
|
||||||
|
accesskey="&context.openSelectionLinks.accesskey;"
|
||||||
|
oncommand="TreeStyleTabService.openSelectionLinks();"/>
|
||||||
|
</popup>
|
||||||
|
|
||||||
<menupopup id="multipletab-selection-menu">
|
<menupopup id="multipletab-selection-menu">
|
||||||
<menuitem id="multipletab-selection-item-removeTabSubTree"
|
<menuitem id="multipletab-selection-item-removeTabSubTree"
|
||||||
insertafter="multipletab-selection-removeTabs"
|
insertafter="multipletab-selection-removeTabs"
|
||||||
|
@ -6,6 +6,8 @@ pref("extensions.treestyletab.tabbar.scroll.timeout", 250);
|
|||||||
pref("extensions.treestyletab.tabbar.style", "mixed");
|
pref("extensions.treestyletab.tabbar.style", "mixed");
|
||||||
pref("extensions.treestyletab.levelMargin", 12);
|
pref("extensions.treestyletab.levelMargin", 12);
|
||||||
|
|
||||||
|
pref("extensions.treestyletab.show.openSelectionLinks", true);
|
||||||
|
|
||||||
pref("extensions.treestyletab.openGroupBookmarkAsTabSubTree", true);
|
pref("extensions.treestyletab.openGroupBookmarkAsTabSubTree", true);
|
||||||
pref("extensions.treestyletab.loadDroppedLinkToNewChildTab", false);
|
pref("extensions.treestyletab.loadDroppedLinkToNewChildTab", false);
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
<!ENTITY config.tabbar.style.vertigo "Vertigo">
|
<!ENTITY config.tabbar.style.vertigo "Vertigo">
|
||||||
<!ENTITY config.tabbar.style.mixed "Mixed">
|
<!ENTITY config.tabbar.style.mixed "Mixed">
|
||||||
|
|
||||||
|
<!ENTITY config.show.openSelectionLinks "Add "Open Selection Links in Tabs" to the context menu">
|
||||||
|
|
||||||
|
|
||||||
<!ENTITY config.tabs.tab "Tab Operations">
|
<!ENTITY config.tabs.tab "Tab Operations">
|
||||||
|
|
||||||
@ -51,6 +53,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!ENTITY context.openSelectionLinks.label "Open Selection Links in Tabs">
|
||||||
|
<!ENTITY context.openSelectionLinks.accesskey "l">
|
||||||
|
|
||||||
<!ENTITY selection.removeTabSubTree.label "Close Selected Sub Trees">
|
<!ENTITY selection.removeTabSubTree.label "Close Selected Sub Trees">
|
||||||
<!ENTITY selection.removeTabSubTree.accesskey "s">
|
<!ENTITY selection.removeTabSubTree.accesskey "s">
|
||||||
<!ENTITY context.removeTabSubTree.label "Close this Sub Tree">
|
<!ENTITY context.removeTabSubTree.label "Close this Sub Tree">
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
<!ENTITY config.tabbar.style.vertigo "Vertigo">
|
<!ENTITY config.tabbar.style.vertigo "Vertigo">
|
||||||
<!ENTITY config.tabbar.style.mixed "Mixed">
|
<!ENTITY config.tabbar.style.mixed "Mixed">
|
||||||
|
|
||||||
|
<!ENTITY config.show.openSelectionLinks "コンテキストメニューに「選択したリンクをすべてタブで開く」を加える">
|
||||||
|
|
||||||
|
|
||||||
<!ENTITY config.tabs.tab "タブの開き方">
|
<!ENTITY config.tabs.tab "タブの開き方">
|
||||||
|
|
||||||
@ -50,6 +52,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!ENTITY context.openSelectionLinks.label "選択したリンクをすべてタブで開く">
|
||||||
|
<!ENTITY context.openSelectionLinks.accesskey "l">
|
||||||
|
|
||||||
<!ENTITY selection.removeTabSubTree.label "すべてのサブツリーを閉じる">
|
<!ENTITY selection.removeTabSubTree.label "すべてのサブツリーを閉じる">
|
||||||
<!ENTITY selection.removeTabSubTree.accesskey "s">
|
<!ENTITY selection.removeTabSubTree.accesskey "s">
|
||||||
<!ENTITY context.removeTabSubTree.label "このサブツリーを閉じる">
|
<!ENTITY context.removeTabSubTree.label "このサブツリーを閉じる">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user