Fixes for numerous bookmarks bugs, e.g. 68496, 50276, 68395, 68537, 68545,

68985, various hangs, crashes, glitches etc. 68545, 68985, 68395 r=jag;
Implement new bookmarks sidebar panel. a=hyatt


git-svn-id: svn://10.0.0.236/trunk@89270 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
ben%netscape.com 2001-03-11 07:32:24 +00:00
parent d3ba25399c
commit bf0bb164b4
17 changed files with 443 additions and 210 deletions

View File

@ -51,7 +51,7 @@
</RDF:Description>
<RDF:Description about="urn:sidebar:panel:bookmarks">
<NC:title>&sidebar.panel.client-bookmarks;</NC:title>
<NC:content>chrome://communicator/content/bookmarks/bm-panel.xul</NC:content>
<NC:content>chrome://communicator/content/bookmarks/bookmarksPanel.xul</NC:content>
</RDF:Description>
<RDF:Description about="urn:sidebar:panel:history">
<NC:title>&sidebar.panel.client-history;</NC:title>

View File

@ -109,13 +109,12 @@
<menuitem id="context-bookmarkpage"
value="&bookmarkPageCmd.label;"
accesskey="&bookmarkPageCmd.accesskey;"
oncommand="addBookmark(window._content.location.href,
window._content.document.title);"/>
oncommand="BookmarksUtils.addBookmarkToWindow(window._content);"/>
<menuitem id="context-bookmarklink"
value="&bookmarkLinkCmd.label;"
accesskey="&bookmarkLinkCmd.accesskey;"
oncommand="addBookmark(contextMenu.linkURL(),
contextMenu.linkText());"/>
oncommand="BookmarksUtils.addBookmark(contextMenu.linkURL(),
contextMenu.linkText());"/>
<menuseparator id="context-sep-bookmark"/>
<!-- Save ==================================== -->
<menuitem id="context-savepage"

View File

@ -121,19 +121,3 @@
return null;
}
function addBookmark(url,title)
{
if (!title)
title = url;
var focusedWindow = document.commandDispatcher.focusedWindow;
if (focusedWindow == window)
focusedWindow = _content;
var docCharset = focusedWindow.document.characterSet;
var bmks = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
.getService(Components.interfaces.nsIBookmarksService);
bmks.AddBookmark(url, title, bmks.BOOKMARK_DEFAULT_TYPE, docCharset);
}

View File

@ -48,8 +48,6 @@ function Startup()
if (window.arguments[4] == "selectFolder") {
document.getElementById("bookmarknamegrid").setAttribute("hidden", "true");
toggleCreateIn();
document.getElementById("createinlabel").setAttribute("collapsed", "true");
document.getElementById("createinbuttonbox").setAttribute("hidden", "true");
document.getElementById("dontaskagain").setAttribute("hidden", "true");
document.getElementById("createinseparator").setAttribute("hidden", "true");
sizeToContent();
@ -61,11 +59,8 @@ function Startup()
gFld_Name.value = window.arguments[0] || "";
gFld_URL.value = window.arguments[1] || "";
gBookmarkCharset = window.arguments [3] || null;
if (window.arguments[2]) {
if (window.arguments[2])
gCreateInFolder = window.arguments[2];
document.getElementById("createin").setAttribute("hidden", "true");
document.getElementById("folderbox").setAttribute("hidden", "true");
}
}
}
@ -74,34 +69,6 @@ function Startup()
gFld_Name.focus();
}
function toggleCreateIn()
{
var folderbox = document.getElementById("folderbox");
var createInButton = document.getElementById("createin");
var dontaskagain = document.getElementById("dontaskagain");
var oldID, newID;
if (folderbox.getAttribute("hidden") == "true") {
createInButton.value = createInButton.getAttribute("value2");
folderbox.removeAttribute("hidden");
dontaskagain.removeAttribute("hidden");
oldID = "buttonsparent";
newID = "openParent";
}
else {
createInButton.value = createInButton.getAttribute("value1");
folderbox.setAttribute("hidden", "true");
dontaskagain.setAttribute("hidden", "true");
oldID = "openParent";
newID = "buttonsparent";
}
var oldParent = document.getElementById(oldID);
var newParent = document.getElementById(newID);
var buttons = oldParent.firstChild.cloneNode(true);
oldParent.removeChild(oldParent.firstChild);
newParent.appendChild(buttons);
sizeToContent();
}
function onLocationInput ()
{
var ok = document.getElementById("ok");
@ -127,6 +94,7 @@ function onOK()
catch (e) {
// No "NC:NewBookmarkFolder" exists, just append to the root.
rFolder = kRDF.GetResource("NC:BookmarksRoot", true);
kRDFC.Init(kBMDS, rFolder);
}
if (!gFld_URL.value) return;
@ -163,8 +131,10 @@ function onTreeSelect ()
{
if (gFolderTree.selectedItems.length < 1)
gCreateInFolder = "NC:NewBookmarkFolder";
var selectedItem = gFolderTree.selectedItems[0];
gCreateInFolder = selectedItem.id;
else {
var selectedItem = gFolderTree.selectedItems[0];
gCreateInFolder = selectedItem.id;
}
}
var gBookmarksShell = null;
@ -195,5 +165,3 @@ function useDefaultFolder ()
}

View File

@ -82,19 +82,7 @@
<separator id="createinseparator"/>
<box id="createinbuttonbox">
<button id="createin" class="disclosure-triangle" value="&button.createin.label;"
accesskey="&button.createin.accesskey;"
value1="&button.createin.label;"
value2="&button.createin2.label;"
oncommand="toggleCreateIn();"/>
<spring flex="1"/>
<box id="buttonsparent">
<box id="okCancelButtonsRight"/>
</box>
</box>
<box id="folderbox" orient="vertical" hidden="true" flex="1">
<box id="folderbox" orient="vertical" flex="1">
<separator/>
<grid flex="1">
<columns>
@ -144,15 +132,16 @@
</grid>
<separator/>
</box>
<!-- XXX - todo - remove all the create-in code -->
<box valign="bottom">
<box autostretch="never">
<checkbox id="dontaskagain" hidden="true"
<checkbox id="dontaskagain"
value="&alwayscreateinfolder.label;"
accesskey="&alwayscreateinfolder.accesskey;"/>
</box>
<spring flex="1"/>
<box id="openParent" orient="vertical"/>
<box id="okCancelButtonsRight"/>
</box>
</window>

View File

@ -131,6 +131,10 @@ BookmarksWindowTree.prototype = {
/////////////////////////////////////////////////////////////////////////////
// Number of clicks to activate a bookmark.
openClickCount: 2,
/////////////////////////////////////////////////////////////////////////////
// Open Bookmark in new window
openNewWindow: true,
/////////////////////////////////////////////////////////////////////////////
// Selection change (clicks, key navigation) in the tree update the statusbar

View File

@ -27,7 +27,7 @@
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarks.css" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarksWindow.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
@ -68,31 +68,7 @@
<script src="chrome://global/content/nsTransferable.js"></script>
<script src="chrome://communicator/content/bookmarks/bookmarksDD.js"></script>
<commands id="commands">
<commandset id="CommandUpdate_Bookmarks"
commandupdater="true"
events="focus,tree-select"
oncommandupdate="BookmarksTree.prototype.controller.onCommandUpdate()">
</commandset>
<commandset id="selectEditMenuItems"/>
<commandset id="globalEditMenuItems"/>
<commandset id="bookmarksItems">
<command id="cmd_open" oncommand="goDoCommand('cmd_open');"/>
<command id="cmd_openfolder" oncommand="goDoCommand('cmd_openfolder');"/>
<command id="cmd_newfolder" oncommand="goDoCommand('cmd_newfolder');"/>
<command id="cmd_newbookmark" oncommand="goDoCommand('cmd_newbookmark');"/>
<command id="cmd_newseparator" oncommand="goDoCommand('cmd_newseparator');"/>
<command id="cmd_find" oncommand="goDoCommand('cmd_find');"/>
<command id="cmd_setnewbookmarkfolder" oncommand="goDoCommand('cmd_setnewbookmarkfolder');"/>
<command id="cmd_setpersonaltoolbarfolder" oncommand="goDoCommand('cmd_setpersonaltoolbarfolder');"/>
<command id="cmd_setnewsearchfolder" oncommand="goDoCommand('cmd_setnewsearchfolder');"/>
<command id="cmd_properties" oncommand="goDoCommand('cmd_properties');"/>
<command id="cmd_rename" oncommand="goDoCommand('cmd_rename');"/>
<command id="cmd_openfolderinnewwindow" oncommand="goDoCommand('cmd_openfolderinnewwindow');"/>
<command id="cmd_import" oncommand="goDoCommand('cmd_import');"/>
<command id="cmd_export" oncommand="goDoCommand('cmd_export');"/>
</commandset>
</commands>
<commands id="commands"/>
<broadcasterset id="broadcasterset">
<!-- File Menu -->
@ -102,11 +78,6 @@
<broadcaster id="cmd_quit"/>
<!-- Edit Menu -->
<broadcaster id="cmd_undo"/>
<broadcaster id="cmd_cut"/>
<broadcaster id="cmd_copy"/>
<broadcaster id="cmd_paste"/>
<broadcaster id="cmd_delete"/>
<broadcaster id="cmd_selectAll"/>
<broadcaster id="cmd_preferences"/>
</broadcasterset>
@ -262,7 +233,7 @@
</toolbar>
</toolbox>
<tree id="bookmarksTree" ref="NC:NavCenter" context="bmContext"
<tree id="bookmarksTree" class="bookmarks-window-tree" context="bmContext" ref="NC:NavCenter"
datasources="rdf:bookmarks rdf:files rdf:httpindex rdf:localsearch rdf:internetsearch"
multiple="true" flags="dont-test-empty"
ondragover="nsDragAndDrop.dragOver(event, bookmarksDNDObserver);"
@ -299,7 +270,7 @@
rdf:type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
loading="rdf:http://home.netscape.com/NC-rdf#loading">
<treerow>
<treecell class="treecell-bookmark treecell-indent treecell-editable"
<treecell class="treecell-indent treecell-editable"
editable="true" value="rdf:http://home.netscape.com/NC-rdf#Name"
src="rdf:http://home.netscape.com/NC-rdf#Icon"
web:status="rdf:http://home.netscape.com/WEB-rdf#status"
@ -407,9 +378,9 @@
</treehead>
<treechildren flex="1" id="treechildren-bookmarks"
onclick="if (gBookmarksShell) gBookmarksShell.open(event);"/>
onclick="gBookmarksShell.treeOpen(event);"/>
</tree>
<statusbar id="status-bar">
<statusbarpanel class="statusbarpanel-icononly" id="offline-status"/>
<statusbarpanel id="statusbar-text" flex="1"/>

View File

@ -24,6 +24,18 @@
var NC_NS = "http://home.netscape.com/NC-rdf#";
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
var gSpringLoadTracker = {
timeout: 0,
element: null,
open: function (aRDFNode)
{
if (this.element)
this.element.setAttribute("open", "true");
clearTimeout(this.timeout);
}
};
var bookmarksDNDObserver = {
_RDF: null,
get RDF ()
@ -61,6 +73,8 @@ var bookmarksDNDObserver = {
if (bookmarksTree.getAttribute("sortActive") == "true")
throw Components.results.NS_OK;
dump("*** pass\n");
var selItems = null;
if (bookmarksTree.selectedItems.length <= 0)
selItems = [aEvent.target.parentNode.parentNode];
@ -104,8 +118,42 @@ var bookmarksDNDObserver = {
if (rowGroup)
rowGroup.setAttribute("dd-triggerrepaint" +
(bookmarksTree.getAttribute("sortActive") == "true" ? "sorted" : ""), 0);
},
var rdfNode = gBookmarksShell.findRDFNode(aEvent.target, true);
var rdfParent = rdfNode.parentNode.parentNode;
if (rdfParent && rdfParent.getAttribute("container") == "true") {
var rDragOverContainer = this.RDF.GetResource(NODE_ID(rdfParent));
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
const kRDFCUtilsContractID = "@mozilla.org/rdf/container-utils;1";
const kRDFCUtilsIID = Components.interfaces.nsIRDFContainerUtils;
const kRDFCUtils = Components.classes[kRDFCUtilsContractID].getService(kRDFCUtilsIID);
var isContainer = kRDFCUtils.IsContainer(kBMDS, rDragOverContainer);
if (!isContainer) {
// This ain't a container. Don't allow drops, and bail before doing anything
// else.
aDragSession.canDrop = false;
return;
}
}
// Springloaded folders.
/* XXX - not yet.
if (rdfNode && rdfNode.getAttribute("container") == "true" &&
rdfNode.getAttribute("open") != "true") {
if (!gSpringLoadTracker.element || gSpringLoadTracker.element.id != rdfNode.id) {
// XXX - this is not good enough. We need to keep track of nesting and close up
// folders after the user has dragged out of them otherwise we end up with
// everything open and a big mess!
if (gSpringLoadTracker.timeout)
clearTimeout(gSpringLoadTracker.timeout);
gSpringLoadTracker.element = rdfNode;
gSpringLoadTracker.timeout = setTimeout("gSpringLoadTracker.open()", 100);
}
}
*/
},
_flavourSet: null,
getSupportedFlavours: function ()
{
@ -188,6 +236,7 @@ var bookmarksDNDObserver = {
bo.beginBatch();
}
*/
for (i = 0; i < numObjects; ++i) {
var flavourData = aXferData.dataList[i].first;
@ -214,11 +263,19 @@ var bookmarksDNDObserver = {
var rSource = this.getResource(sourceID);
var rParent = parentID ? this.getResource(parentID) : null;
const kRDFCUtilsContractID = "@mozilla.org/rdf/container-utils;1";
const kRDFCUtilsIID = Components.interfaces.nsIRDFContainerUtils;
const kRDFCUtils = Components.classes[kRDFCUtilsContractID].getService(kRDFCUtilsIID);
var isContainer = kRDFCUtils.IsContainer(kBMDS, rContainer);
// Prevent dropping node on itself, before or after itself, on its parent
// container, or a weird situation when an open container is dropped into
// itself (which results in data loss!).
// Also prevent dropping into a folder that isn't actually a container
// (and is thus probably a pseudo-container from an aggregated datasource,
// see bug 68656 fir details).
if (rSource == rTarget || (dropAction == "on" && rContainer == rParent) ||
rContainer == rSource)
rContainer == rSource || !isContainer)
continue;
// XXX if any of the following fails, the nodes are gone for good!

View File

@ -321,10 +321,10 @@ BookmarksUIElement.prototype = {
break;
case "newseparator":
nfseln = this.getBestItem ();
var parentNode = this.findRDFNode(aSelectedItem, false);
args = [{ property: NC_NS + "parent",
resource: NODE_ID(parentNode) }];
BookmarksUtils.doBookmarksCommand(NODE_ID(aSelectedItem),
var parentNode = this.findRDFNode(nfseln, false);
var args = [{ property: NC_NS + "parent",
resource: NODE_ID(parentNode) }];
BookmarksUtils.doBookmarksCommand(NODE_ID(nfseln),
NC_NS_CMD + "newseparator", args);
break;
case "import":
@ -490,6 +490,19 @@ BookmarksUIElement.prototype = {
this.endBatch();
},
/////////////////////////////////////////////////////////////////////////////
// For the given selection, determines the element that should form the
// container to paste items into.
resolvePasteFolder: function (aSelection)
{
const lastSelected = aSelection[aSelection.length-1];
if (lastSelected.getAttribute("container") == "true" &&
lastSelected.getAttribute("open") == "true" &&
aSelection.length == 1)
return lastSelected;
return this.findRDFNode(lastSelected, false);
},
canPaste: function ()
{
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
@ -513,6 +526,7 @@ BookmarksUIElement.prototype = {
deleteSelection: function (aSelection)
{
dump("*** deleteSelection\n");
const kRDFCContractID = "@mozilla.org/rdf/container;1";
const kRDFCIID = Components.interfaces.nsIRDFContainer;
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
@ -521,8 +535,6 @@ BookmarksUIElement.prototype = {
var count = 0;
var selectionLength = aSelection.length;
if ("beginBatch" in this && selectionLength > 1)
this.beginBatch();
while (aSelection.length && aSelection[count]) {
const currParent = this.findRDFNode(aSelection[count], false);
const kSelectionURI = NODE_ID(aSelection[count]);
@ -541,10 +553,17 @@ BookmarksUIElement.prototype = {
ksRDFC.Init(kBMDS, krParent);
nextElement = this.getNextElement(aSelection[count]);
ksRDFC.RemoveElement(krNode, true);
try {
// XXX - UGH. Template builder is NOT removing the element from the
// tree, and so selection remains non-zero in length and we go into
// an infinite loop here. Tear the node out of the document.
var parent = aSelection[count].parentNode;
parent.removeChild(aSelection[count]);
}
catch (e) {
}
}
if ("beginBatch" in this && selectionLength > 1)
this.endBatch();
this.selectElement(nextElement);
},
@ -571,25 +590,19 @@ BookmarksUIElement.prototype = {
openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", urlValue);
},
open: function (aEvent)
open: function (aEvent, aRDFNode)
{
if (!this.isValidOpenEvent(aEvent))
return;
var rdfNode = this.findRDFNode(aEvent.target, true);
if (rdfNode.getAttribute("container") == "true")
return;
var urlValue = LITERAL(this.db, rdfNode, NC_NS + "URL");
var urlValue = LITERAL(this.db, aRDFNode, NC_NS + "URL");
// Ignore "NC:" and empty urls.
if (urlValue.substring(0,3) == "NC:" || !urlValue) return;
if (aEvent.altKey)
this.showPropertiesForNode (rdfNode);
else
this.showPropertiesForNode (aRDFNode);
else if (this.openNewWindow)
openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", urlValue);
else
openTopWin (urlValue);
aEvent.preventBubble();
},
@ -757,7 +770,16 @@ var BookmarksUtils = {
var url = aWindow.location.href;
var title = aWindow.document.title || url;
var docCharset = aWindow.document.characterSet;
this.addBookmark(url, title, docCharset);
},
addBookmark: function (aURL, aTitle, aCharset)
{
if (aCharset === undefined) {
var fw = document.commandDispatcher.focusedWindow;
aCharset = fw.document.characterSet;
}
const kPrefContractID = "@mozilla.org/preferences;1";
const kPrefIID = Components.interfaces.nsIPref;
const kPrefSvc = Components.classes[kPrefContractID].getService(kPrefIID);
@ -768,25 +790,18 @@ var BookmarksUtils = {
catch (e) {
}
// XXX - 0.8 hack - prevent dialog from appearing on Mac, as there are
// crashes in optimized builds.
if (navigator.platform.toLowerCase().indexOf("mac") != -1) {
showDialog = false;
}
if (showDialog)
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,dialog=no,resizable=no", title, url, null, docCharset);
"centerscreen,chrome,dialog=no,resizable=no", aTitle, aURL, null, aCharset);
else {
// User has elected to override the file dialog and always file bookmarks
// into the default bookmark folder.
const kBMSvcContractID = "@mozilla.org/browser/bookmarks-service;1";
const kBMSvcIID = Components.interfaces.nsIBookmarksService;
const kBMSvc = Components.classes[kBMSvcContractID].getService(kBMSvcIID);
kBMSvc.AddBookmark(url, title, kBMSvcIID.BOOKMARK_DEFAULT_TYPE, docCharset);
kBMSvc.AddBookmark(aURL, aTitle, kBMSvcIID.BOOKMARK_DEFAULT_TYPE, aCharset);
}
}
};
/* XXX Template problems

View File

@ -36,9 +36,44 @@
<popupset id="popupset">
<popup id="bmContext"
oncreate="if (gBookmarksShell) gBookmarksShell.createContextMenu(event);"/>
oncreate="gBookmarksShell.createContextMenu(event);"/>
</popupset>
<commands id="commands">
<commandset id="bookmarksItems">
<command id="cmd_open" oncommand="goDoCommand('cmd_open');"/>
<command id="cmd_openfolder" oncommand="goDoCommand('cmd_openfolder');"/>
<command id="cmd_newfolder" oncommand="goDoCommand('cmd_newfolder');"/>
<command id="cmd_newbookmark" oncommand="goDoCommand('cmd_newbookmark');"/>
<command id="cmd_newseparator" oncommand="goDoCommand('cmd_newseparator');"/>
<command id="cmd_find" oncommand="goDoCommand('cmd_find');"/>
<command id="cmd_setnewbookmarkfolder" oncommand="goDoCommand('cmd_setnewbookmarkfolder');"/>
<command id="cmd_setpersonaltoolbarfolder" oncommand="goDoCommand('cmd_setpersonaltoolbarfolder');"/>
<command id="cmd_setnewsearchfolder" oncommand="goDoCommand('cmd_setnewsearchfolder');"/>
<command id="cmd_properties" oncommand="goDoCommand('cmd_properties');"/>
<command id="cmd_rename" oncommand="goDoCommand('cmd_rename');"/>
<command id="cmd_openfolderinnewwindow" oncommand="goDoCommand('cmd_openfolderinnewwindow');"/>
<command id="cmd_import" oncommand="goDoCommand('cmd_import');"/>
<command id="cmd_export" oncommand="goDoCommand('cmd_export');"/>
</commandset>
<commandset id="CommandUpdate_Bookmarks"
commandupdater="true"
events="focus,tree-select"
oncommandupdate="BookmarksTree.prototype.controller.onCommandUpdate()">
</commandset>
<commandset id="selectEditMenuItems"/>
<commandset id="globalEditMenuItems"/>
<commandset id="bookmarksItems"/>
</commands>
<broadcasterset id="broadcasterset">
<broadcaster id="cmd_cut"/>
<broadcaster id="cmd_copy"/>
<broadcaster id="cmd_paste"/>
<broadcaster id="cmd_delete"/>
<broadcaster id="cmd_selectAll"/>
</broadcasterset>
</overlay>

View File

@ -0,0 +1,82 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@netscape.com> (Original Author)
*/
////////////////////////////////////////////////////////////////////////////////
// Get the two bookmarks utility libraries running, attach controllers, focus
// tree widget, etc.
function Startup()
{
// Create the Bookmarks Shell
var bookmarksTree = document.getElementById("bookmarksTree");
gBookmarksShell = new BookmarksPanelTree (bookmarksTree.database);
// Set up the tree controller
bookmarksTree.controllers.appendController(gBookmarksShell.controller);
// Update to the last sort.
RefreshSort();
bookmarksTree.focus();
}
////////////////////////////////////////////////////////////////////////////////
// Class representing the bookmarks panel's tree. This subclasses BookmarksTree,
// which contains methods generic to any tree-like bookmarks UI representation.
// This class contains data specific to the tree in this panel, e.g. number of
// clicks required to load a bookmark, which differs from other bookmarks tree
// implementations (such as window).
function BookmarksPanelTree (aCompositeDataSource)
{
// 'db' is used by the base class.
this.db = aCompositeDataSource;
this.id = "bookmarksTree";
}
BookmarksPanelTree.prototype = {
__proto__: BookmarksTree.prototype,
/////////////////////////////////////////////////////////////////////////////
// Number of clicks to activate a bookmark.
openClickCount: 1,
/////////////////////////////////////////////////////////////////////////////
// Open Bookmark in most recent window
openNewWindow: false,
addBookmark: function ()
{
// This looks evil, you'd think we'd want to find the most recent NAVIGATOR
// window and add a bookmark to the page loaded in that, but that's not the
// case. In mail/news, we want to bookmark the current mail message and in
// editor we want to bookmark the current document.
BookmarksUtils.addBookmarkToWindow(top._content);
},
manageBookmarks: function ()
{
openDialog("chrome://communicator/content/bookmarks/bookmarks.xul", "", "chrome,dialog=no,resizable=yes");
}
};

View File

@ -0,0 +1,139 @@
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is mozilla.org code.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com> (Original Author, v2.0)
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarksWindow.css" type="text/css"?>
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/bookmarks.dtd">
<window id="bookmarksPanel" orient="vertical"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Startup();">
<!-- Generic Utilities -->
<script type="text/javascript" src="chrome://global/content/nsTreeUtils.js"></script>
<!-- XXX - would like to cut this dependency out -->
<script type="text/javascript" src="chrome://global/content/strres.js"></script>
<script type="text/javascript" src="chrome://global/content/nsJSComponentManager.js"></script>
<!-- Bookmarks Shell -->
<script type="text/javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"></script>
<script type="text/javascript" src="chrome://communicator/content/bookmarks/bookmarksTree.js"></script>
<script type="text/javascript" src="chrome://communicator/content/bookmarks/bookmarksPanel.js"></script>
<!-- Drag and Drop -->
<script src="chrome://global/content/nsJSComponentManager.js"></script>
<script src="chrome://global/content/nsJSSupportsUtils.js"></script>
<script src="chrome://global/content/nsDragAndDrop.js"></script>
<script src="chrome://global/content/nsTransferable.js"></script>
<script type="text/javascript" src="chrome://communicator/content/bookmarks/bookmarksDD.js"></script>
<!-- context menu, tooltips, etc -->
<popupset id="popupset"/>
<!-- bookmarks string bundle -->
<stringbundleset id="stringbundleset"/>
<!-- bookmarks & edit commands -->
<commands id="commands"/>
<broadcasterset id="broadcasterset"/>
<box id="panel-bar" class="toolbar">
<button class="button-toolbar" value="&command.addBookmark.label;"
oncommand="gBookmarksShell.addBookmark();"/>
<button class="button-toolbar" value="&command.manageBookmarks.label;"
oncommand="gBookmarksShell.manageBookmarks();"/>
</box>
<tree id="bookmarksTree" context="bmContext" ref="NC:BookmarksRoot"
datasources="rdf:bookmarks rdf:files rdf:httpindex rdf:localsearch rdf:internetsearch"
flags="dont-test-empty"
ondragover="nsDragAndDrop.dragOver(event, bookmarksDNDObserver);"
ondraggesture="nsDragAndDrop.startDrag(event, bookmarksDNDObserver);"
ondragdrop="nsDragAndDrop.drop(event, bookmarksDNDObserver);"
onclick="gBookmarksShell.treeClicked(event);"
style="height:0px" flex="1">
<template>
<rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
<treechildren>
<treeitem uri="rdf:*"
rdf:type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type">
<treerow>
<treecell autostretch="never"><treeindentation/>
<separator class="groove" flex="1"/></treecell>
</treerow>
</treeitem>
</treechildren>
</rule>
<rule>
<treechildren>
<treeitem uri="rdf:*" persist="open" class="bookmark-item"
web:status="rdf:http://home.netscape.com/WEB-rdf#status"
rdf:type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
loading="rdf:http://home.netscape.com/NC-rdf#loading">
<treerow>
<treecell class="treecell-indent treecell-editable"
editable="true" value="rdf:http://home.netscape.com/NC-rdf#Name"
src="rdf:http://home.netscape.com/NC-rdf#Icon"
web:status="rdf:http://home.netscape.com/WEB-rdf#status"
rdf:type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
loading="rdf:http://home.netscape.com/NC-rdf#loading" />
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecolgroup id="theColumns">
<treecol id="Name"
sortSeparators="true" width="4*" flex="4"
persist="hidden width sortActive sortDirection"
resource="http://home.netscape.com/NC-rdf#Name"/>
</treecolgroup>
<treehead>
<treerow id="headRow">
<treecell class="treecell-header sortDirectionIndicator treecell-header-sidebarpanel"
value="&tree.header.name.label;"
onclick="return TriStateColumnSort('Name');"
observes="Name" />
</treerow>
</treehead>
<treechildren flex="1" id="treechildren-bookmarks"
onclick="gBookmarksShell.treeOpen(event);"/>
</tree>
</window>

View File

@ -56,7 +56,8 @@ BookmarksTree.prototype = {
var xulElement = document.createElementNS(kXULNS, "menuitem");
xulElement.setAttribute("command", aCommandName);
xulElement.setAttribute("observes", "cmd_" + aCommandName.substring(NC_NS_CMD.length));
var node = xulElement.getAttribute('observes');
switch (aCommandName) {
case NC_NS_CMD + "open":
xulElement.setAttribute("value", aDisplayName);
@ -82,19 +83,6 @@ BookmarksTree.prototype = {
return xulElement;
},
/////////////////////////////////////////////////////////////////////////////
// For the given selection, determines the element that should form the
// container to paste items into.
resolvePasteFolder: function (aSelection)
{
const lastSelected = aSelection[aSelection.length-1];
if (lastSelected.getAttribute("container") == "true" &&
lastSelected.getAttribute("open") == "true" &&
aSelection.length == 1)
return lastSelected;
return this.findRDFNode(lastSelected, false);
},
// Command implementation
commands: {
openFolder: function (aSelectedItem)
@ -146,9 +134,9 @@ BookmarksTree.prototype = {
var aShell = aParams[0];
var selItemURI = NODE_ID(aParams[1]);
aShell.propertySet(selItemURI, aParams[2], aParams[3]);
gBookmarksShell.tree.focus();
gBookmarksShell.selectFolderItem(NODE_ID(gBookmarksShell.findRDFNode(aParams[1], false)),
selItemURI, false);
gBookmarksShell.tree.focus();
gSelectionTracker.clickCount = 0;
},
@ -171,6 +159,8 @@ BookmarksTree.prototype = {
if (!shell.validateNameAndTopic(name, aTopic, relativeNode, dummyItem))
return;
dummyItem.parentNode.removeChild(dummyItem);
// If we're attempting to create a folder as a subfolder of an open folder,
// we need to set the parentFolder to be relativeNode, which will be the
// parent of the new folder, rather than the parent of the relativeNode,
@ -193,6 +183,7 @@ BookmarksTree.prototype = {
var newFolderItem = document.getElementById(newFolderRDFObserver._newFolderURI);
gBookmarksShell.tree.focus();
gBookmarksShell.tree.selectItem(newFolderItem);
gSelectionTracker.clickCount = 0;
},
///////////////////////////////////////////////////////////////////////////
@ -256,6 +247,8 @@ BookmarksTree.prototype = {
else
aSelectedItem.parentNode.appendChild(dummyItem);
}
var index = gBookmarksShell.tree.getIndexOfItem(dummyItem);
gBookmarksShell.tree.ensureIndexIsVisible(index);
}
else {
if (aSelectedItem.nextSibling)
@ -397,8 +390,10 @@ BookmarksTree.prototype = {
// editable cells.
treeClicked: function (aEvent)
{
if (this.tree.selectedItems.length > 1 || aEvent.detail > 1 || aEvent.button != 0)
if (this.tree.selectedItems.length > 1 || aEvent.detail > 1 || aEvent.button != 0) {
gSelectionTracker.clickCount = 0;
return;
}
if (gSelectionTracker.currentItem == this.tree.currentItem &&
gSelectionTracker.currentCell == aEvent.target)
++gSelectionTracker.clickCount;
@ -407,25 +402,44 @@ BookmarksTree.prototype = {
gSelectionTracker.currentItem = this.tree.currentItem;
gSelectionTracker.currentCell = aEvent.target;
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" &&
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" &&
gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Folder")
return;
var row = gSelectionTracker.currentItem.firstChild;
for (var i = 0; i < row.childNodes.length; ++i) {
if (row.childNodes[i] == gSelectionTracker.currentCell) {
// Don't allow inline-edit of cells other than name for folders.
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" && i)
return;
// Don't allow editing of the root folder name
if (gSelectionTracker.currentItem.id == "NC:BookmarksRoot")
return;
if (gSelectionTracker.clickCount == 1)
gBookmarksShell.commands.editCell(this.tree.currentItem, i);
break;
if (row) {
for (var i = 0; i < row.childNodes.length; ++i) {
if (row.childNodes[i] == gSelectionTracker.currentCell) {
// Don't allow inline-edit of cells other than name for folders.
// XXX - so so skeezy. Change this to look for NC:Name or some such.
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" && i)
return;
// Don't allow editing of the root folder name
if (gSelectionTracker.currentItem.id == "NC:BookmarksRoot")
return;
if (gSelectionTracker.clickCount == 1 && this.openClickCount > 1)
gBookmarksShell.commands.editCell(this.tree.currentItem, i);
break;
}
}
}
},
treeOpen: function (aEvent)
{
if (!this.isValidOpenEvent(aEvent))
return;
var rdfNode = this.findRDFNode(aEvent.target, true);
if (rdfNode.getAttribute("container") == "true") {
if (this.openClickCount == 1)
rdfNode.setAttribute("open", rdfNode.getAttribute("open") != "true");
gSelectionTracker.clickCount = 0;
return;
}
this.open(aEvent, rdfNode);
},
/////////////////////////////////////////////////////////////////////////////
// Tree key events. This handles when to go into inline-edit mode for editable
@ -441,12 +455,8 @@ BookmarksTree.prototype = {
else if (aEvent.keyCode == 113)
goDoCommand("cmd_rename");
else if (aEvent.keyCode == 13 &&
this.tree.currentItem.firstChild.getAttribute("inline-edit") != "true") {
if (aEvent.altKey)
goDoCommand("cmd_properties");
else
goDoCommand("cmd_open");
}
this.tree.currentItem.firstChild.getAttribute("inline-edit") != "true")
goDoCommand(aEvent.altKey ? "cmd_properties" : "cmd_open");
},
selectFolderItem: function (aFolderURI, aItemURI, aAdditiveFlag)
@ -600,7 +610,7 @@ BookmarksTree.prototype = {
"cmd_paste", "cmd_cut", "cmd_delete",
"cmd_setpersonaltoolbarfolder", "cmd_setnewbookmarkfolder",
"cmd_setnewsearchfolder"];
for (var i = 0; i < commands.length; ++i)
for (var i = 0; i < commands.length; ++i)
goUpdateCommand(commands[i]);
}
}

View File

@ -19,21 +19,21 @@
comm.jar:
content/communicator/bookmarks/addBookmark.xul
content/communicator/bookmarks/addBookmark.js
+ content/communicator/bookmarks/addBookmark.js
content/communicator/bookmarks/bm-find.js
content/communicator/bookmarks/bm-find.xul
content/communicator/bookmarks/bm-panel.js
content/communicator/bookmarks/bm-panel.xul
content/communicator/bookmarks/bm-props.js
content/communicator/bookmarks/bm-props.xul
content/communicator/bookmarks/bookmarksDD.js
content/communicator/bookmarks/bookmarks.xul
+ content/communicator/bookmarks/bookmarksDD.js
+ content/communicator/bookmarks/bookmarks.xul
content/communicator/bookmarks/bookmarks.js
content/communicator/bookmarks/bookmarks-temp.js
content/communicator/bookmarks/bookmarksDD-temp.js
content/communicator/bookmarks/bookmarksTree.js
+ content/communicator/bookmarks/bookmarksTree.js
content/communicator/bookmarks/bookmarksOverlay.xul
content/communicator/bookmarks/bookmarksOverlay.js
+ content/communicator/bookmarks/bookmarksOverlay.js
+ content/communicator/bookmarks/bookmarksPanel.xul
+ content/communicator/bookmarks/bookmarksPanel.js
content/communicator/bookmarks/pref-bookmarks.xul
en-US.jar:

View File

@ -41,6 +41,9 @@
<!ENTITY command.delete.label "Delete">
<!ENTITY command.fileBookmark.label "File Bookmark">
<!ENTITY command.fileBookmark.accesskey "l">
<!ENTITY command.addBookmark.label "Add...">
<!ENTITY command.manageBookmarks.label "Manage">
<!ENTITY menuitem.view.command.toolbar.label "Toolbar">
<!ENTITY menuitem.view.command.toolbar.accesskey "t">

View File

@ -23,28 +23,5 @@ DEPTH=..\..\..\..
DIRS= locale
CHROME_DIR = .
CHROME_CONTENT_DIR = packages\core\communicator\content\bookmarks
CHROME_L10N_DIR = locales\en-US\communicator\locale\bookmarks
CHROME_CONTENT = \
.\bm-find.js \
.\bm-find.xul \
.\bm-panel.js \
.\bm-panel.xul \
.\bm-props.js \
.\bm-props.xul \
.\bookmarks.js \
.\bookmarksDD.js \
.\bookmarks.xul \
$(NULL)
CHROME_L10N = \
.\locale\en-US\bm-find.dtd \
.\locale\en-US\bm-props.dtd \
.\locale\en-US\bookmarks.dtd \
.\locale\en-US\bookmark.properties \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@ -45,7 +45,7 @@
</rdf:Description>
<rdf:Description about="urn:sidebar:panel:bookmarks">
<nc:title>&sidebar.bookmarks.label;</nc:title>
<nc:content>chrome://communicator/content/bookmarks/bm-panel.xul</nc:content>
<nc:content>chrome://communicator/content/bookmarks/bookmarksPanel.xul</nc:content>
</rdf:Description>
<rdf:Description about="urn:sidebar:panel:history">
<nc:title>&sidebar.history.label;</nc:title>