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:
mozilla.mano@sent.com 2007-09-02 12:03:24 -07:00
Родитель 03256148c3
Коммит f961e849ee
4 изменённых файлов: 139 добавлений и 141 удалений

Просмотреть файл

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