зеркало из https://github.com/mozilla/pjs.git
Bug 175124 - improve open in tabs behaviour (see comment 26), this also enables 'Open All in Tabs' for host nodes in the history sidebar (bug 369919) and for saved searches (queries), patch by mconnor and me.
This commit is contained in:
Родитель
03256148c3
Коммит
f961e849ee
|
@ -387,10 +387,10 @@ var BookmarksEventHandler = {
|
|||
var view = PlacesUtils.getViewForNode(target);
|
||||
if (PlacesUtils.nodeIsFolder(view.selectedNode)) {
|
||||
// Don't open the root folder in tabs when the empty area on the toolbar
|
||||
// is middle-clicked or when a non-bookmark item in a bookmarks menupopup
|
||||
// middle-clicked.
|
||||
// is middle-clicked or when a non-bookmark item except for Open in Tabs)
|
||||
// in a bookmarks menupopup is middle-clicked.
|
||||
if (!view.controller.rootNodeIsSelected())
|
||||
view.controller.openLinksInTabs();
|
||||
view.controller.openSelectionInTabs(aEvent);
|
||||
}
|
||||
else
|
||||
this.onCommand(aEvent);
|
||||
|
@ -430,12 +430,10 @@ var BookmarksEventHandler = {
|
|||
// load all the menuitems in tabs.
|
||||
|
||||
var target = aEvent.originalTarget;
|
||||
if (target.hasAttribute("openInTabs"))
|
||||
PlacesUtils.getViewForNode(target).controller.openLinksInTabs();
|
||||
else if (target.hasAttribute("siteURI"))
|
||||
if (target.hasAttribute("siteURI"))
|
||||
openUILink(target.getAttribute("siteURI"), aEvent);
|
||||
// If this is a normal bookmark, just load the bookmark's URI.
|
||||
else
|
||||
else if (!target.hasAttribute("openInTabs"))
|
||||
PlacesUtils.getViewForNode(target)
|
||||
.controller
|
||||
.openSelectedNodeWithEvent(aEvent);
|
||||
|
@ -498,6 +496,9 @@ var BookmarksEventHandler = {
|
|||
if (hasMultipleEntries) {
|
||||
var openInTabs = document.createElement("menuitem");
|
||||
openInTabs.setAttribute("openInTabs", "true");
|
||||
openInTabs.setAttribute("onclick", "checkForMiddleClick(this, event)");
|
||||
openInTabs.setAttribute("oncommand",
|
||||
"PlacesUtils.openContainerNodeInTabs(this.parentNode.getResultNode(), event);");
|
||||
openInTabs.setAttribute("label",
|
||||
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
|
||||
target.appendChild(openInTabs);
|
||||
|
|
|
@ -119,34 +119,6 @@ PlacesController.prototype = {
|
|||
case "placesCmd_open:window":
|
||||
case "placesCmd_open:tab":
|
||||
return this._view.selectedURINode;
|
||||
case "placesCmd_open:tabs":
|
||||
// We can open multiple links if the current selection is either:
|
||||
// a) a single folder which contains at least one link
|
||||
// b) multiple links
|
||||
var node = this._view.selectedNode;
|
||||
if (!node)
|
||||
return false;
|
||||
|
||||
if (this._view.hasSingleSelection && PlacesUtils.nodeIsFolder(node)) {
|
||||
var contents = PlacesUtils.getFolderContents(node.itemId, false, false).root;
|
||||
for (var i = 0; i < contents.childCount; ++i) {
|
||||
var child = contents.getChild(i);
|
||||
if (PlacesUtils.nodeIsURI(child))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var oneLinkIsSelected = false;
|
||||
var nodes = this._view.getSelectionNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (PlacesUtils.nodeIsURI(nodes[i])) {
|
||||
if (oneLinkIsSelected)
|
||||
return true;
|
||||
oneLinkIsSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case "placesCmd_new:folder":
|
||||
case "placesCmd_new:livemark":
|
||||
return this._canInsert() &&
|
||||
|
@ -275,9 +247,6 @@ PlacesController.prototype = {
|
|||
case "placesCmd_open:tab":
|
||||
this.openSelectedNodeIn("tab");
|
||||
break;
|
||||
case "placesCmd_open:tabs":
|
||||
this.openLinksInTabs();
|
||||
break;
|
||||
case "placesCmd_new:folder":
|
||||
this.newItem("folder");
|
||||
break;
|
||||
|
@ -670,6 +639,21 @@ PlacesController.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
// Set Open Folder/Links In Tabs items enabled state if they're visible
|
||||
if (anyVisible) {
|
||||
var openContainerInTabsItem = document.getElementById("placesContext_openContainer:tabs");
|
||||
if (!openContainerInTabsItem.hidden) {
|
||||
openContainerInTabsItem.disabled =
|
||||
PlacesUtils.getURLsForContainerNode(this._view.selectedNode)
|
||||
.length == 0;
|
||||
}
|
||||
else {
|
||||
// see selectiontype rule in the overlay
|
||||
var openLinksInTabsItem = document.getElementById("placesContext_openLinks:tabs");
|
||||
openLinksInTabsItem.disabled = openLinksInTabsItem.hidden;
|
||||
}
|
||||
}
|
||||
|
||||
return anyVisible;
|
||||
},
|
||||
|
||||
|
@ -829,103 +813,13 @@ PlacesController.prototype = {
|
|||
|
||||
/**
|
||||
* Opens the links in the selected folder, or the selected links in new tabs.
|
||||
* XXXben this needs to handle the case when there are no open browser windows
|
||||
* XXXben this function is really long, should be split apart. The codepaths
|
||||
* seem different between load folder in tabs and load selection in
|
||||
* tabs, too.
|
||||
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=331908
|
||||
*/
|
||||
openLinksInTabs: function PC_openLinksInTabs() {
|
||||
openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
|
||||
var node = this._view.selectedNode;
|
||||
if (this._view.hasSingleSelection && PlacesUtils.nodeIsFolder(node)) {
|
||||
// Check prefs to see whether to open over existing tabs.
|
||||
var doReplace = getBoolPref("browser.tabs.loadFolderAndReplace");
|
||||
var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground");
|
||||
// Get the start index to open tabs at
|
||||
|
||||
// XXX todo: no-browser-window-case
|
||||
var browserWindow = getTopWin();
|
||||
var browser = browserWindow.getBrowser();
|
||||
var tabPanels = browser.browsers;
|
||||
var tabCount = tabPanels.length;
|
||||
var firstIndex;
|
||||
// If browser.tabs.loadFolderAndReplace pref is set, load over all the
|
||||
// tabs starting with the first one.
|
||||
if (doReplace)
|
||||
firstIndex = 0;
|
||||
// If the pref is not set, only load over the blank tabs at the end, if any.
|
||||
else {
|
||||
for (firstIndex = tabCount - 1; firstIndex >= 0; --firstIndex) {
|
||||
var br = browser.browsers[firstIndex];
|
||||
if (br.currentURI.spec != "about:blank" ||
|
||||
br.webProgress.isLoadingDocument)
|
||||
break;
|
||||
}
|
||||
++firstIndex;
|
||||
}
|
||||
|
||||
// Open each uri in the folder in a tab.
|
||||
var index = firstIndex;
|
||||
var urlsToOpen = [];
|
||||
var contents = PlacesUtils.getFolderContents(node.itemId, false, false).root;
|
||||
for (var i = 0; i < contents.childCount; ++i) {
|
||||
var child = contents.getChild(i);
|
||||
if (PlacesUtils.nodeIsURI(child))
|
||||
urlsToOpen.push(child.uri);
|
||||
}
|
||||
|
||||
if (!this._confirmOpenTabs(urlsToOpen.length))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < urlsToOpen.length; ++i) {
|
||||
if (index < tabCount)
|
||||
tabPanels[index].loadURI(urlsToOpen[i]);
|
||||
// Otherwise, create a new tab to load the uri into.
|
||||
else
|
||||
browser.addTab(urlsToOpen[i]);
|
||||
++index;
|
||||
}
|
||||
|
||||
// If no bookmarks were loaded, just bail.
|
||||
if (index == firstIndex)
|
||||
return;
|
||||
|
||||
// focus the first tab if prefs say to
|
||||
if (!loadInBackground || doReplace) {
|
||||
// Select the first tab in the group.
|
||||
// Set newly selected tab after quick timeout, otherwise hideous focus problems
|
||||
// can occur because new presshell is not ready to handle events
|
||||
function selectNewForegroundTab(browser, tab) {
|
||||
browser.selectedTab = tab;
|
||||
}
|
||||
var tabs = browser.mTabContainer.childNodes;
|
||||
setTimeout(selectNewForegroundTab, 0, browser, tabs[firstIndex]);
|
||||
}
|
||||
|
||||
// Close any remaining open tabs that are left over.
|
||||
// (Always skipped when we append tabs)
|
||||
for (var i = tabCount - 1; i >= index; --i)
|
||||
browser.removeTab(tabs[i]);
|
||||
|
||||
// and focus the content
|
||||
browserWindow.content.focus();
|
||||
}
|
||||
else {
|
||||
var urlsToOpen = [];
|
||||
var nodes = this._view.getSelectionNodes();
|
||||
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (PlacesUtils.nodeIsURI(nodes[i]))
|
||||
urlsToOpen.push(nodes[i].uri);
|
||||
}
|
||||
|
||||
if (!this._confirmOpenTabs(urlsToOpen.length))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < urlsToOpen.length; ++i) {
|
||||
getTopWin().openNewTabWith(urlsToOpen[i], null, null);
|
||||
}
|
||||
}
|
||||
if (this._view.hasSingleSelection && PlacesUtils.nodeIsContainer(node))
|
||||
PlacesUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent);
|
||||
else
|
||||
PlacesUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1488,7 +1382,6 @@ function goUpdatePlacesCommands() {
|
|||
goUpdateCommand("placesCmd_open");
|
||||
goUpdateCommand("placesCmd_open:window");
|
||||
goUpdateCommand("placesCmd_open:tab");
|
||||
goUpdateCommand("placesCmd_open:tabs");
|
||||
goUpdateCommand("placesCmd_new:folder");
|
||||
goUpdateCommand("placesCmd_new:bookmark");
|
||||
goUpdateCommand("placesCmd_new:livemark");
|
||||
|
|
|
@ -71,8 +71,7 @@
|
|||
oncommand="goDoCommand('placesCmd_open:window');"/>
|
||||
<command id="placesCmd_open:tab"
|
||||
oncommand="goDoCommand('placesCmd_open:tab');"/>
|
||||
<command id="placesCmd_open:tabs"
|
||||
oncommand="goDoCommand('placesCmd_open:tabs');"/>
|
||||
|
||||
<command id="placesCmd_new:bookmark"
|
||||
oncommand="goDoCommand('placesCmd_new:bookmark');"/>
|
||||
<command id="placesCmd_new:livemark"
|
||||
|
@ -121,14 +120,18 @@
|
|||
accesskey="&cmd.open_tab.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="link"/>
|
||||
<menuitem id="placesContext_openFolder:tabs"
|
||||
command="placesCmd_open:tabs"
|
||||
<menuitem id="placesContext_openContainer:tabs"
|
||||
oncommand="var view = PlacesUtils.getViewForNode(document.popupNode);
|
||||
view.controller.openSelectionInTabs(event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
label="&cmd.open_all_in_tabs.label;"
|
||||
accesskey="&cmd.open_all_in_tabs.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="folder"/>
|
||||
selection="folder|host|query"/>
|
||||
<menuitem id="placesContext_openLinks:tabs"
|
||||
command="placesCmd_open:tabs"
|
||||
oncommand="var view = PlacesUtils.getViewForNode(document.popupNode);
|
||||
view.controller.openSelectionInTabs(event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
label="&cmd.open_all_in_tabs.label;"
|
||||
accesskey="&cmd.open_all_in_tabs.accesskey;"
|
||||
selectiontype="multiple"
|
||||
|
|
|
@ -1235,7 +1235,7 @@ var PlacesUtils = {
|
|||
* a DOM node
|
||||
* @return the closet ancestor places view if exists, null otherwsie.
|
||||
*/
|
||||
getViewForNode: function(aNode) {
|
||||
getViewForNode: function PU_getViewForNode(aNode) {
|
||||
var node = aNode;
|
||||
while (node) {
|
||||
// XXXmano: Use QueryInterface(nsIPlacesView) once we implement it...
|
||||
|
@ -1511,6 +1511,107 @@ var PlacesUtils = {
|
|||
return bk;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
getURLsForContainerNode: function PU_getURLsForContainerNode(aNode) {
|
||||
let urls = [];
|
||||
if (this.nodeIsFolder(aNode) && asQuery(aNode).queryOptions.excludeItems) {
|
||||
// grab manually
|
||||
let contents = this.getFolderContents(node.itemId, false, false).root;
|
||||
for (let i = 0; i < contents.childCount; ++i) {
|
||||
let child = contents.getChild(i);
|
||||
if (this.nodeIsURI(child))
|
||||
urls.push(node.uri);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let wasOpen = aNode.containerOpen;
|
||||
if (!wasOpen)
|
||||
aNode.containerOpen = true;
|
||||
for (let i = 0; i < aNode.childCount; ++i) {
|
||||
let child = aNode.getChild(i);
|
||||
if (this.nodeIsURI(child))
|
||||
urls.push(child.uri);
|
||||
}
|
||||
aNode.containerOpen = wasOpen;
|
||||
}
|
||||
|
||||
return urls;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gives the user a chance to cancel loading lots of tabs at once
|
||||
*/
|
||||
_confirmOpenInTabs: function PU__confirmOpenInTabs(numTabsToOpen) {
|
||||
var pref = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
const kWarnOnOpenPref = "browser.tabs.warnOnOpen";
|
||||
var reallyOpen = true;
|
||||
if (pref.getBoolPref(kWarnOnOpenPref)) {
|
||||
if (numTabsToOpen >= pref.getIntPref("browser.tabs.maxOpenBeforeWarn")) {
|
||||
var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
|
||||
// default to true: if it were false, we wouldn't get this far
|
||||
var warnOnOpen = { value: true };
|
||||
|
||||
var messageKey = "tabs.openWarningMultipleBranded";
|
||||
var openKey = "tabs.openButtonMultiple";
|
||||
const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties";
|
||||
var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Ci.nsIStringBundleService).
|
||||
createBundle(BRANDING_BUNDLE_URI).
|
||||
GetStringFromName("brandShortName");
|
||||
|
||||
var buttonPressed = promptService.confirmEx(window,
|
||||
this.getString("tabs.openWarningTitle"),
|
||||
this.getFormattedString(messageKey, [numTabsToOpen, brandShortName]),
|
||||
(promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0)
|
||||
+ (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
|
||||
this.getString(openKey), null, null,
|
||||
this.getFormattedString("tabs.openWarningPromptMeBranded",
|
||||
[brandShortName]), warnOnOpen);
|
||||
|
||||
reallyOpen = (buttonPressed == 0);
|
||||
// don't set the pref unless they press OK and it's false
|
||||
if (reallyOpen && !warnOnOpen.value)
|
||||
pref.setBoolPref(kWarnOnOpenPref, false);
|
||||
}
|
||||
}
|
||||
return reallyOpen;
|
||||
},
|
||||
|
||||
_openTabset: function PU__openTabset(aURLs, aEvent) {
|
||||
var browserWindow = getTopWin();
|
||||
var where = browserWindow ?
|
||||
whereToOpenLink(aEvent, false, true) : "window";
|
||||
if (where == "window") {
|
||||
window.openDialog(getBrowserURL(), "_blank",
|
||||
"chrome,all,dialog=no", aURLs.join("|"));
|
||||
return;
|
||||
}
|
||||
|
||||
var loadInBackground = where == "tabshifted" ? true : false;
|
||||
var replaceCurrentTab = where == "tab" ? false : true;
|
||||
browserWindow.getBrowser().loadTabs(aURLs, loadInBackground,
|
||||
replaceCurrentTab);
|
||||
},
|
||||
|
||||
openContainerNodeInTabs: function PU_openContainerInTabs(aNode, aEvent) {
|
||||
var urlsToOpen = this.getURLsForContainerNode(aNode);
|
||||
if (!this._confirmOpenInTabs(urlsToOpen.length))
|
||||
return;
|
||||
this._openTabset(urlsToOpen, aEvent);
|
||||
},
|
||||
|
||||
openURINodesInTabs: function PU_openURINodesInTabs(aNodes, aEvent) {
|
||||
var urlsToOpen = [];
|
||||
for (var i=0; i < aNodes.length; i++) {
|
||||
if (this.nodeIsURI(aNodes[i]))
|
||||
urlsToOpen.push(aNodes[i].uri);
|
||||
}
|
||||
this._openTabset(urlsToOpen, aEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче