Changes to bookmark properties dialog:

* Customized bookmark properties dialog for add vs. edit cases
* Added support for changing URI of bookmark (annotations not carried over yet)
* Add support for viewing properties of history entries
* Changed from tag-style control to folder tree for folder selection,
  yielding layout and accessibility improvements
* Switched to using standard dialog buttons

bug=329272
r=annie.sullivan@gmail.com
sr=bugs@bengoodger.com
This commit is contained in:
joe%retrovirus.com 2006-03-10 17:36:41 +00:00
Родитель c94402a6e6
Коммит a1baed1ab6
9 изменённых файлов: 378 добавлений и 132 удалений

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

@ -6314,12 +6314,8 @@ var PlacesCommandHook = {
* Adds a bookmark to the page loaded in the current tab.
*/
bookmarkCurrentPage: function PCH_bookmarkCurrentPage() {
// TODO: add dialog for filing/confirmation
var selectedBrowser = getBrowser().selectedBrowser;
var uri = selectedBrowser.currentURI;
var bms = PlacesController.bookmarks;
bms.insertItem(bms.bookmarksRoot, uri, -1);
bms.setItemTitle(uri, selectedBrowser.contentTitle);
PlacesController.showAddBookmarkUI(selectedBrowser.currentURI);
},
/**
@ -6409,13 +6405,7 @@ var PlacesCommandHook = {
*/
onBookmarkButtonClick: function PCH_onBookmarkButtonClick() {
var currentURI = getBrowser().selectedBrowser.webNavigation.currentURI;
var bms = PlacesController.bookmarks;
if (bms.isBookmarked(currentURI)) {
PlacesController.showBookmarkProperties(currentURI);
} else {
bms.insertItem(bms.bookmarksRoot, currentURI, -1);
this.updateTagButton();
}
PlacesController.showAddBookmarkUI(currentURI);
}
};

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

@ -39,6 +39,16 @@
var BookmarkPropertiesPanel = {
/** UI Text Strings */
__strings: null,
get _strings() {
if (!this.__strings) {
this.__strings = document.getElementById("stringBundle");
}
return this.__strings;
},
/**
* The Bookmarks Service.
*/
@ -78,7 +88,6 @@ var BookmarkPropertiesPanel = {
return this.__ios;
},
_bookmarkURI: null,
_bookmarkTitle: "",
_dialogWindow: null,
@ -86,15 +95,138 @@ var BookmarkPropertiesPanel = {
_controller: null,
MAX_INDENT_DEPTH: 6, // maximum indentation level of "tag" display
EDIT_BOOKMARK_VARIANT: 0,
ADD_BOOKMARK_VARIANT: 1,
EDIT_HISTORY_VARIANT: 2,
/**
* The variant identifier for the current instance of the dialog.
* The possibilities are enumerated by the constants above.
*/
_variant: null,
_isVariant: function BPP__isVariant(variant) {
return this._variant == variant;
},
/**
* Returns true if the URI title is editable in this dialog variant.
*/
_isTitleEditable: function BPP__isTitleEditable() {
switch(this._variant) {
case this.EDIT_HISTORY_VARIANT: return false;
default: return true;
}
},
/**
* Returns true if the URI is editable in this variant of the dialog.
*/
_isURIEditable: function BPP__isURIEditable() {
switch(this._variant) {
case this.EDIT_HISTORY_VARIANT: return false;
default: return true;
}
},
/**
* Returns true if the the shortcut field is visible in this
* variant of the dialog.
*/
_isShortcutVisible: function BPP__isShortcutVisible() {
switch(this._variant) {
case this.EDIT_HISTORY_VARIANT: return false;
default: return true;
}
},
/**
* Returns true if bookmark deletion is possible from the current
* variant of the dialog.
*/
_isDeletePossible: function BPP__isDeletePossible() {
switch(this._variant) {
case this.EDIT_HISTORY_VARIANT: return false;
case this.ADD_BOOKMARK_VARIANT: return false;
default: return true;
}
},
/**
* Returns true if the URI's folder is editable in this variant
* of the dialog.
*/
_isFolderEditable: function BPP__isFolderVisible() {
switch(this._variant) {
case this.ADD_BOOKMARK_VARIANT: return true;
default: return false;
}
},
/**
* This method returns the correct label for the dialog's "accept"
* button based on the variant of the dialog.
*/
_getAcceptLabel: function BPP__getAcceptLabel() {
switch(this._variant) {
case this.ADD_BOOKMARK_VARIANT:
return this._strings.getString("dialogAcceptLabelAdd");
default: return this._strings.getString("dialogAcceptLabelEdit");
}
},
/**
* This method returns the correct title for the current variant
* of this dialog.
*/
_getDialogTitle: function BPP__getDialogTitle() {
switch(this._variant) {
case this.ADD_BOOKMARK_VARIANT:
return this._strings.getString("dialogTitleAdd");
case this.EDIT_HISTORY_VARIANT:
return this._strings.getString("dialogTitleHistoryEdit");
default:
return this._strings.getString("dialogTitleBookmarkEdit");
}
},
/**
* This method can be run on a URI parameter to ensure that it didn't
* receive a string instead of an nsIURI object.
*/
_assertURINotString: function PC__assertURINotString(value) {
_assertURINotString: function BPP__assertURINotString(value) {
ASSERT((typeof(value) == "object") && !(value instanceof String),
"This method should be passed a URI as a nsIURI object, not as a string.");
},
/**
* Determines the correct variant of the dialog to display depending
* on which action is passed in and whether or not the URI passed in
* is already bookmarked or not.
*
* @param uri the URI to display the properties for
* @param action -- "add" if this is being triggered from an "add bookmark"
* UI action; or "edit" if this is being triggered from
* a "properties" UI action
*
* @returns one of the *_VARIANT constants
*/
_determineVariant: function BPP__determineVariant(uri, action) {
if (action == "add") {
if (this._bms.isBookmarked(uri)) {
return this.EDIT_BOOKMARK_VARIANT;
} else {
return this.ADD_BOOKMARK_VARIANT;
}
} else { /* Assume "edit" */
if (this._bms.isBookmarked(uri)) {
return this.EDIT_BOOKMARK_VARIANT;
} else {
return this.EDIT_HISTORY_VARIANT;
}
}
},
/**
* This method should be called by the onload of the Bookmark Properties
* dialog to initialize the state of the panel.
@ -105,14 +237,22 @@ var BookmarkPropertiesPanel = {
* @param controller a PlacesController object for interacting with the
* Places system
*/
init: function BPP_init(dialogWindow, bookmarkURI, controller) {
init: function BPP_init(dialogWindow, bookmarkURI, controller, action) {
this._assertURINotString(bookmarkURI);
this._variant = this._determineVariant(bookmarkURI, action);
this._bookmarkURI = bookmarkURI;
this._bookmarkTitle = this._bms.getItemTitle(this._bookmarkURI);
this._dialogWindow = dialogWindow;
this._controller = controller;
this.folderTree = this._dialogWindow.document.getElementById("folder-tree");
this.folderTree.controllers.appendController(this._controller);
this.folderTree.init(new ViewConfig([TYPE_X_MOZ_PLACE_CONTAINER],
ViewConfig.GENERIC_DROP_TYPES,
true, false, 4, true));
this.folderTree.loadFolder(this._bms.placesRoot);
this._initAssignableFolderResult();
this._populateProperties();
this._updateSize();
@ -142,8 +282,15 @@ var BookmarkPropertiesPanel = {
var title = this._bookmarkTitle;
var document = this._dialogWindow.document;
// hide standard dialog button, lest it throw off size calculation later
this._dialogWindow.document.documentElement.getButton("accept").hidden=true;
this._dialogWindow.title = this._getDialogTitle();
this._dialogWindow.document.documentElement.getButton("accept").label =
this._getAcceptLabel();
if (!this._isDeletePossible()) {
this._dialogWindow.document.documentElement.getButton("extra1").hidden =
"true";
}
var nurl = document.getElementById("edit-urlbar");
@ -152,35 +299,57 @@ var BookmarkPropertiesPanel = {
nurl.value = location.spec;
titlebox.value = title;
var shortcutbox =
this._dialogWindow.document.getElementById("edit-shortcutbox");
shortcutbox.value = this._bms.getKeywordForURI(this._bookmarkURI);
if (!this._isTitleEditable())
titlebox.setAttribute("disabled", "true");
var tagArea = document.getElementById("tagbox");
if (!this._isURIEditable())
nurl.setAttribute("disabled", "true");
while (tagArea.hasChildNodes()) {
tagArea.removeChild(tagArea.firstChild);
if (this._isShortcutVisible()) {
var shortcutbox =
this._dialogWindow.document.getElementById("edit-shortcutbox");
shortcutbox.value = this._bms.getKeywordForURI(this._bookmarkURI);
} else {
var shortcutRow =
this._dialogWindow.document.getElementById("shortcut-row");
shortcutRow.setAttribute("hidden", "true");
}
var elementDict = {};
if (this._isFolderEditable()) {
var root = this._assignableFolderResult.root; //Root is always a container.
root.containerOpen = true;
this._populateTags(root, 0, tagArea, elementDict);
root.containerOpen = false;
var tagArea = document.getElementById("tagbox");
var categories = this._bms.getBookmarkFolders(location, {});
while (tagArea.hasChildNodes()) {
tagArea.removeChild(tagArea.firstChild);
}
this._updateFolderTextbox(location);
var elementDict = {};
var length = 0;
for (key in elementDict) {
length++;
}
var root = this._assignableFolderResult.root; //Root is always a container.
root.containerOpen = true;
this._populateTags(root, 0, tagArea, elementDict);
root.containerOpen = false;
for (var i=0; i < categories.length; i++) {
var elm = elementDict[categories[i]];
var categories = this._bms.getBookmarkFolders(location, {});
this._updateFolderTextbox(location);
var length = 0;
for (key in elementDict) {
length++;
}
for (var i=0; i < categories.length; i++) {
var elm = elementDict[categories[i]];
elm.setAttribute("selected", "true");
}
} else {
var folderDispRow =
this._dialogWindow.document.getElementById("folder-disp-row");
folderDispRow.setAttribute("hidden", "true");
var folderRow =
this._dialogWindow.document.getElementById("folder-row");
folderRow.setAttribute("hidden", "true");
}
},
@ -341,16 +510,9 @@ var BookmarkPropertiesPanel = {
* Size the dialog to fit its contents.
*/
_updateSize: function BPP__updateSize() {
var childDoc = this._dialogWindow.document;
var tagbox = childDoc.getElementById("tagbox");
tagbox.style.overflow="auto";
var pio = childDoc.getElementById("places-info-options");
var pig = childDoc.getElementById("places-info-grid");
var newHeight = pio.boxObject.y + pio.boxObject.height + 5;
this._dialogWindow.resizeTo(this._dialogWindow.innerWidth, newHeight);
var width = this._dialogWindow.innerWidth;
this._dialogWindow.sizeToContent();
this._dialogWindow.resizeTo(width, this._dialogWindow.innerHeight);
},
/**
@ -394,6 +556,24 @@ var BookmarkPropertiesPanel = {
* was open.
*/
_saveChanges: function PBD_saveChanges() {
var urlbox = this._dialogWindow.document.getElementById("edit-urlbar");
var newURI = this._uri(urlbox.value);
if (this._isFolderEditable()) {
var selected = this.folderTree.getSelectionNodes();
for (var i = 0; i < selected.length; i++) {
var node = selected[i];
if (node.type == node.RESULT_TYPE_FOLDER) {
var folder = node.QueryInterface(Ci.nsINavHistoryFolderResultNode);
if (!folder.childrenReadOnly) {
this._bms.insertItem(folder.folderId, newURI, -1);
}
}
}
}
var titlebox = this._dialogWindow.document.getElementById("edit-titlebox");
this._bms.setItemTitle(this._bookmarkURI, titlebox.value);
@ -401,11 +581,10 @@ var BookmarkPropertiesPanel = {
this._dialogWindow.document.getElementById("edit-shortcutbox");
this._bms.setKeywordForURI(this._bookmarkURI, shortcutbox.value);
var urlbox = this._dialogWindow.document.getElementById("edit-urlbar");
if (urlbox.value != this._bookmarkURI.spec) {
/* this._controller.changeBookmarkURI(this._bookmarkURI,
this._uri(urlbox.value));*/
LOG("TODO: delete existing bookmark, create new one with same folder & location.");
if (this._isVariant(this.EDIT_BOOKMARK_VARIANT) &&
(newURI.spec != this._bookmarkURI.spec)) {
this._controller.changeBookmarkURI(this._bookmarkURI,
this._uri(urlbox.value));
}
},
@ -414,5 +593,5 @@ var BookmarkPropertiesPanel = {
*/
_hideBookmarkProperties: function BPP__hideBookmarkProperties() {
this._dialogWindow.close();
},
}
}

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

@ -2,81 +2,108 @@
<?xml-stylesheet href="chrome://global/skin/"?>
<?xml-stylesheet href="chrome://browser/skin/places/bookmarkProperties.css"?>
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
<!DOCTYPE window
SYSTEM "chrome://browser/locale/places/bookmarkProperties.dtd">
<!DOCTYPE window [
<!ENTITY % propertiesDTD SYSTEM "chrome://browser/locale/places/bookmarkProperties.dtd">
%propertiesDTD;
<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
%placesDTD;
]>
<dialog id="bookmarkproperties" title="&bookmark.property.panel.title;"
buttons="accept"
buttons="accept, cancel, extra1"
buttonlabelextra1="&cmd.delete_bookmark.label;"
ondialogaccept="BookmarkPropertiesPanel.dialogDone();"
ondialogextra1="BookmarkPropertiesPanel.dialogDeleteBookmark();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="BookmarkPropertiesPanel.init(window, window.arguments[0], window.arguments[1]);">
onload="BookmarkPropertiesPanel.init(window, window.arguments[0], window.arguments[1], window.arguments[2]);">
<stringbundleset id="stringbundleset">
<stringbundle id="stringBundle"
src="chrome://browser/locale/places/bookmarkProperties.properties"/>
</stringbundleset>
<script type="application/x-javascript"
src="chrome://browser/content/places/bookmarkProperties.js"/>
<vbox id="places-info-options" flex="1">
<grid id="places-info-grid" flex="1">
<columns>
<column flex="1" align="end" />
<column flex="100" align="start" />
</columns>
<rows>
<row>
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.title;" align="middle"/>
</hbox>
</vbox>
<textbox id="edit-titlebox" value=""/>
</row>
<row>
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.location;" align="middle"/>
</hbox>
</vbox>
<textbox id="edit-urlbar" size="10"/>
</row>
<row>
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.shortcut;" align="middle"/>
</hbox>
</vbox>
<textbox id="edit-shortcutbox" value=""/>
</row>
<row>
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.folders;"/>
</hbox>
</vbox>
<textbox id="places-folder-list" value="" disabled="true"/>
</row>
<row flex="1">
<vbox align="end">
<hbox align="start" flex="1">
<label value="&bookmark.property.folder_list;"/>
</hbox>
</vbox>
<vbox id="tagbox">
</vbox>
</row>
<row>
<vbox></vbox>
<vbox><hbox align="end">
<button label="&cmd.delete_bookmark.label;"
oncommand="BookmarkPropertiesPanel.dialogDeleteBookmark();"
align="end"/>
<spacer flex="1"/>
<button label="&cmd.hide_bookmark_properties.label;"
oncommand="BookmarkPropertiesPanel.dialogDone();"/>
</hbox>
</vbox>
</row>
</rows>
</grid>
<grid id="places-info-grid" flex="1">
<columns>
<column flex="1" align="end" />
<column flex="100" align="start" />
</columns>
<rows>
<row>
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.title;" align="middle"/>
</hbox>
</vbox>
<textbox id="edit-titlebox" value=""/>
</row>
<row>
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.location;" align="middle"/>
</hbox>
</vbox>
<textbox id="edit-urlbar" size="10"/>
</row>
<row id="shortcut-row">
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.shortcut;" align="middle"/>
</hbox>
</vbox>
<textbox id="edit-shortcutbox" value=""/>
</row>
<row id="folder-disp-row" hidden="true">
<vbox align="end">
<hbox align="center" flex="1">
<label value="&bookmark.property.folders;"/>
</hbox>
</vbox>
<textbox id="places-folder-list" value="" disabled="true"/>
</row>
<row id="folder-row" flex="1" style="min-height: 100px;">
<vbox align="end">
<hbox align="start" flex="1">
<label value="&bookmark.property.parents;"/>
</hbox>
</vbox>
<vbox>
<tree id="folder-tree"
class="placesTree"
flex="1"
type="places"
hidecolumnpicker="true"
seltype="multiple">
<treecols>
<treecol id="title"
flex="1"
primary="true"
hideheader="true"/>
</treecols>
<treechildren id="placesListChildren"
view="placesList"
flex="1"/>
</tree>
</vbox>
</row>
<row flex="1" hidden="true">
<vbox align="end">
<hbox align="start" flex="1">
<label value="&bookmark.property.folder_list;"/>
</hbox>
</vbox>
<vbox id="tagbox">
</vbox>
</row>
</rows>
</grid>
</vbox>
</dialog>

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

@ -312,6 +312,19 @@ var PlacesController = {
return this._livemarks;
},
/**
* The Annotations Service.
*/
_annotations: null,
get annotations() {
if (!this._annotations) {
this._annotations =
Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
}
return this._annotations;
},
/** UI Text Strings */
__strings: null,
@ -817,24 +830,38 @@ var PlacesController = {
ASSERT((typeof(value) == "object") && !(value instanceof String),
"This method should be passed a URI as a nsIURI object, not as a string.");
},
/**
* Show an "Add Bookmark" dialog for the specified URI.
*
* @param uri an nsIURI object for which the "add bookmark" dialog is
* to be shown.
*/
showAddBookmarkUI: function PC_showAddBookmarkUI(uri) {
this._showBookmarkDialog(uri, "add");
},
/**
* Opens the bookmark properties panel for a given bookmarked URI.
* Opens the bookmark properties panel for a given URI.
*
* @param bookmarkURI
* A nsIURI object representing a bookmarked URI
* @param uri an nsIURI object for which the properties are to be shown
*/
showBookmarkProperties: function PC_showBookmarkProperties(bookmarkURI) {
this._assertURINotString(bookmarkURI);
ASSERT(this.bookmarks.isBookmarked(bookmarkURI),
"showBookmarkProperties() was called on a URI that hadn't been bookmarked: " + bookmarkURI.spec);
if (!this.bookmarks.isBookmarked(bookmarkURI))
return;
showBookmarkProperties: function PC_showBookmarkProperties(uri) {
this._showBookmarkDialog(uri, "edit");
},
/**
* Shows the bookmark dialog corresponding to the specified user action.
*
* @param uri the URI to show the dialog for
* @param action "add" or "edit", see _determineVariant in
* bookmarkProperties.js
*/
_showBookmarkDialog: function PC__showBookmarkDialog(uri, action) {
this._assertURINotString(uri);
window.openDialog("chrome://browser/content/places/bookmarkProperties.xul",
"", "width=600,height=400,chrome,dependent,modal,resizable",
bookmarkURI, this);
uri, this, action);
},
/**
@ -843,8 +870,6 @@ var PlacesController = {
* URI with the new URI in each applicable folder, then copies the
* metadata from the old URI to the new URI.
*/
/* NOTE(jhughes): don't use yet; UI doesn't update correctly 2006-03-04
see bug 329524 */
changeBookmarkURI: function PC_changeBookmarkProperties(oldURI, newURI) {
this._assertURINotString(oldURI);
this._assertURINotString(newURI);
@ -862,6 +887,12 @@ var PlacesController = {
this.bookmarks.getItemTitle(oldURI));
this.bookmarks.setKeywordForURI(newURI,
this.bookmarks.getKeywordForURI(oldURI));
LOG("TODO: move annotations over\n");
/*
this.annotations.copyAnnotations(oldURI, newURI, true);
this.annotations.removePageAnnotations(oldURI);
*/
this.bookmarks.endUpdateBatch();
},

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

@ -10,7 +10,12 @@
"Folders">
<!ENTITY bookmark.property.folder_list
"Folder List">
<!ENTITY bookmark.property.parents
"Visible In">
<!ENTITY cmd.delete_bookmark.label
"Delete Bookmark">
<!ENTITY cmd.hide_bookmark_properties.label
"Done">
<!ENTITY cmd.accept.edit
"Save Changes">
<!ENTITY cmd.accept.add
"Add Bookmark">

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

@ -0,0 +1,5 @@
dialogAcceptLabelAdd=Add Bookmark
dialogAcceptLabelEdit=Save Changes
dialogTitleAdd=Add Bookmark
dialogTitleBookmarkEdit=Bookmark Properties
dialogTitleHistoryEdit=Viewed Page Properties

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

@ -25,6 +25,7 @@
#ifdef MOZ_PLACES
locale/browser/places/places.dtd (%chrome/browser/places/places.dtd)
locale/browser/places/bookmarkProperties.dtd (%chrome/browser/places/bookmarkProperties.dtd)
locale/browser/places/bookmarkProperties.properties (%chrome/browser/places/bookmarkProperties.properties)
locale/browser/places/places.properties (%chrome/browser/places/places.properties)
locale/browser/places/default_places.html (%chrome/browser/places/default_places.html)
#else

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

@ -1,3 +1,7 @@
#folder-tree {
margin: 4px;
}
.tag{
padding: 2px;
margin: 0px;

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

@ -1,3 +1,7 @@
#folder-tree {
margin: 4px;
}
.tag{
padding: 2px;
margin: 0px;