Checking in add bookmark UI modifications, cf. bug 322989

This commit is contained in:
joe%retrovirus.com 2006-02-08 16:52:16 +00:00
Родитель 3d4b1b7933
Коммит ff3df4b86e
5 изменённых файлов: 623 добавлений и 92 удалений

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

@ -7,6 +7,86 @@ menupopup[type="places"] {
-moz-binding: url("chrome://browser/content/places/menu.xml#places-menupopup");
}
#places-info-popup {
position: fixed;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
background-color: yellow;
}
#edit-urlbar {
left: 5px;
top: 5px;
margin: 0px;
-moz-box-flex: 1;
}
#edit-urlbox {
position: fixed;
}
#places-info-options {
position: fixed;
font-size: 9pt;
}
#places-info-grid {
}
.tag{
padding: 2px;
margin: 0px;
cursor: pointer;
}
.tag[selected="true"] {
background-color: red;
}
.tag[isparent="true"] {
font-weight: bold;
}
.tag:hover {
background-color: orange;
}
#places-link {
color: blue;
text-decoration: underline;
cursor: pointer;
}
.l0 {
margin-left: 0px;
}
.l1 {
margin-left: 10px;
}
.l2 {
margin-left: 20px;
}
.l3 {
margin-left: 30px;
}
.l4 {
margin-left: 40px;
}
.l5 {
margin-left: 50px;
}
.l6 {
margin-left: 60px;
}
#bookmarksBarShowPlaces {
list-style-image: url("chrome://browser/skin/places/places-icon.png");
}

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

@ -36,112 +36,478 @@
* ***** END LICENSE BLOCK ***** */
var PlacesBrowserShim = {
_bms: null,
_lms: null,
_history: null,
};
_bms: null, // Bookmark Service
_lms: null, // Livemark Service
_hist: null, // History Service
_ios: null, // IO Service, useful for making nsIURI objects
_currentURI: null, // URI of the bookmark being modified
_strings: null, // Localization string bundle
MAX_INDENT_DEPTH: 6, // maximum indentation level of "tag" display
PlacesBrowserShim.init = function PBS_init() {
var addBookmarkCmd = document.getElementById("Browser:AddBookmarkAs");
addBookmarkCmd.setAttribute("oncommand", "PlacesBrowserShim.addBookmark()");
init: function PBS_init() {
var addBookmarkCmd = document.getElementById("Browser:AddBookmarkAs");
addBookmarkCmd.setAttribute("oncommand", "PlacesBrowserShim.addBookmark()");
this._bms =
Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
this._bms =
Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
this._lms =
Cc["@mozilla.org/browser/livemark-service;1"].
getService(Ci.nsILivemarkService);
this._hist =
Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
this._lms =
Cc["@mozilla.org/browser/livemark-service;1"].
getService(Ci.nsILivemarkService);
// Override the old addLivemark function
BookmarksUtils.addLivemark = function(a,b,c,d) {PlacesBrowserShim.addLivemark(a,b,c,d);};
var newMenuPopup = document.getElementById("bookmarksMenuPopup");
var query = this._hist.getNewQuery();
query.setFolders([this._bms.bookmarksRoot], 1);
var options = this._hist.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
options.expandQueries = true;
var result = this._hist.executeQuery(query, options);
newMenuPopup._result = result;
newMenuPopup._resultNode = result.root;
this._hist =
Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
window.controllers.appendController(PlacesController);
PlacesController.topWindow = window;
PlacesController.tm = PlacesTransactionManager;
};
this._ios =
Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
PlacesBrowserShim.addBookmark = function PBS_addBookmark() {
var selectedBrowser = getBrowser().selectedBrowser;
this._bookmarkURI(this._bms.bookmarksRoot, selectedBrowser.currentURI,
selectedBrowser.contentTitle);
};
this._strings = document.getElementById("placeBundle");
PlacesBrowserShim._bookmarkURI =
function PBS__bookmarkURI(folder, uri, title) {
this._bms.insertItem(folder, uri, -1);
this._bms.setItemTitle(uri, title);
};
// Override the old addLivemark function
BookmarksUtils.addLivemark = function(a,b,c,d) {PlacesBrowserShim.addLivemark(a,b,c,d);};
PlacesBrowserShim.showHistory = function PBS_showHistory() {
loadURI("chrome://browser/content/places/places.xul?history", null, null);
};
var newMenuPopup = document.getElementById("bookmarksMenuPopup");
var query = this._hist.getNewQuery();
query.setFolders([this._bms.bookmarksRoot], 1);
var options = this._hist.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
options.expandQueries = true;
var result = this._hist.executeQuery(query, options);
newMenuPopup._result = result;
newMenuPopup._resultNode = result.root;
PlacesBrowserShim.showBookmarks = function PBS_showBookmarks() {
loadURI("chrome://browser/content/places/places.xul?bookmarks", null, null);
};
this._registerEventHandlers();
PlacesBrowserShim.addLivemark = function PBS_addLivemark(aURL, aFeedURL, aTitle, aDescription) {
window.controllers.appendController(PlacesController);
PlacesController.topWindow = window;
PlacesController.tm = PlacesTransactionManager;
},
addBookmark: function PBS_addBookmark() {
var selectedBrowser = getBrowser().selectedBrowser;
this._bookmarkURI(this._bms.bookmarksRoot, selectedBrowser.currentURI,
selectedBrowser.contentTitle);
},
_bookmarkURI: function PBS__bookmarkURI(folder, uri, title) {
this._bms.insertItem(folder, uri, -1);
this._bms.setItemTitle(uri, title);
},
showHistory: function PBS_showHistory() {
loadURI("chrome://browser/content/places/places.xul?history", null, null);
},
showBookmarks: function PBS_showBookmarks() {
loadURI("chrome://browser/content/places/places.xul?bookmarks", null, null);
},
addLivemark: function PBS_addLivemark(url, feedURL, title, description) {
// TODO -- put in nice confirmation dialog.
var ios =
Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
this._lms.createLivemark(this._bms.toolbarRoot,
aTitle,
ios.newURI(aURL, null, null),
ios.newURI(aFeedURL, null, null),
-1);
this._lms.createLivemark(this._bms.toolbarRoot,
title,
this._makeURI(url),
this._makeURI(feedURL),
-1);
},
/**
* Makes an nsIURI object from a string containing a URI.
*/
_makeURI: function PBS__makeURI(urlString) {
return this._ios.newURI(urlString, null, null);
},
/**
* Gets the URI that the visible browser tab is rendering.
*
* @returns a string containing the URI currently being shown
*/
_getCurrentLocation: function PBS__getCurrentLocation() {
return getBrowser().selectedBrowser.webNavigation.currentURI;
},
/**
* This method updates the state of navigation buttons (i.e. bookmark, feeds)
* which depend on the location and contents of the current page.
*/
_updateControlStates: function PBS__updateControlStates() {
var feedButton = document.getElementById("places-subscribe");
var bookmarkButton = document.getElementById("places-bookmark");
if (this._bms.isBookmarked(this._getCurrentLocation())) {
bookmarkButton.label = this._strings.getString("locationStatusBookmarked");
} else {
bookmarkButton.label = this._strings.getString("locationStatusNotBookmarked");
}
if (gBrowser.selectedBrowser.feeds) {
feedButton.removeAttribute("disabled");
} else {
feedButton.setAttribute("disabled", "true");
}
},
/**
* Register the event handlers that Places needs to update its state.
*/
_registerEventHandlers: function PBS_registerEventHandlers() {
var self = this;
function onPageShow(e){
self.onPageShow(e);
}
getBrowser().addEventListener("pageshow", onPageShow, true);
function onTabSwitch(e) {
self.onTabSwitch(e);
}
getBrowser().mTabBox.addEventListener("select", onTabSwitch, true);
},
/**
* This method should be called when the location currently being
* rendered by a browser changes (loading new page or forward/back).
*/
onPageShow: function PBS_onPageShow(e) {
if (e.target && e.target.nodeName == "#document") {
this._updateControlStates();
}
},
/**
* This method should be called when the user switches active tabs.
*/
onTabSwitch: function PBS_onTabSwitch(e) {
if (e.target == null || e.target.localName != "tabs")
return;
this._updateControlStates();
},
/**
* This method should be called when the bookmark button is clicked.
*/
onBookmarkButtonClick: function PBS_onBookmarkButtonClick() {
var urlbar = document.getElementById("urlbar");
this._currentURI = this._makeURI(urlbar.value);
if (this._bms.isBookmarked(this._currentURI)) {
this.showBookmarkProperties();
} else {
this._bms.insertItem(this._bms.bookmarksRoot, this._currentURI, -1);
this._updateControlStates();
}
},
showBookmarkProperties: function PBS_showBookmarkProperties() {
var popup = document.getElementById("places-info-popup");
var win = document.getElementById("main-window");
var urlbar = document.getElementById("urlbar");
var nurl = document.getElementById("edit-urlbar");
var nurlbox = document.getElementById("edit-urlbox");
var titlebox = document.getElementById("edit-titlebox");
nurl.value = urlbar.value;
nurl.label = urlbar.value;
nurl.size = urlbar.size;
nurlbox.style.left = urlbar.boxObject.x + "px";
nurlbox.style.top = urlbar.boxObject.y + "px";
nurl.height = urlbar.boxObject.height;
nurl.style.width = urlbar.boxObject.width + "px";
var title = this._bms.getItemTitle(this._makeURI(urlbar.value));
titlebox.value = title;
var query = this._hist.getNewQuery();
query.setFolders([this._bms.placesRoot], 1);
var options = this._hist.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
options.excludeItems = true;
this._result = this._hist.executeQuery(query, options);
var tagArea = document.getElementById("tagbox");
while (tagArea.hasChildNodes()) {
tagArea.removeChild(tagArea.firstChild);
}
var elementDict = {};
var root = this._result.root; // Note that root is always a container.
root.containerOpen = true;
this._populateTags(root, 0, tagArea, elementDict);
root.containerOpen = false;
var categories = this._bms.getBookmarkFolders(this._makeURI(urlbar.value), {});
this._updateFolderTextbox(this._makeURI(urlbar.value));
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");
}
popup.hidden = false;
popup.style.left = "" + (nurlbox.boxObject.x - 5) + "px";
popup.style.top = "" + (nurlbox.boxObject.y - 5) + "px";
popup.style.width = "" + (nurlbox.boxObject.width + (5 * 2)) + "px";
var pio = document.getElementById("places-info-options");
pio.style.top = nurlbox.boxObject.y + nurlbox.boxObject.height + 5 + "px";
pio.style.width = nurlbox.boxObject.width + "px";
pio.style.left = nurlbox.boxObject.x + "px";
var pig = document.getElementById("places-info-grid");
pig.style.width = nurlbox.boxObject.width + "px";
popup.style.height = (pio.boxObject.y + pio.boxObject.height - popup.boxObject.y + 5) + "px";
},
/**
* This method is called to exit the Bookmark Properties panel.
*
* @param aSaveChanges boolean, should be true if changes performed while
* the panel was active should be saved
*/
hideBookmarkProperties:
function PBS_hideBookmarkProperties(saveChanges) {
if (saveChanges) {
var titlebox = document.getElementById("edit-titlebox");
this._bms.setItemTitle(this._currentURI, titlebox.value);
}
var popup = document.getElementById("places-info-popup");
this._updateControlStates();
popup.hidden = true;
},
/**
* This method deletes the bookmark corresponding to the URI stored
* in _currentURI. _currentURI represents the URI that the Bookmark
* Properties panel is currently viewing/editing. Therefore, this method
* is only relevant in when the Bookmark Properties panel is active.
*/
deleteBookmark: function PBS_deleteBookmark() {
if (!this._currentURI)
return;
var folders = this._bms.getBookmarkFolders(this._currentURI, {});
if (folders.length == 0)
return;
this._bms.beginUpdateBatch();
for (var i = 0; i < folders.length; i++) {
this._bms.removeItem(folders[i], this._currentURI);
}
this._bms.endUpdateBatch();
},
/**
* This method sets the contents of the "Folders" textbox in the
* Bookmark Properties panel.
*
* @param aURI an nsIURI object representing the current bookmark's URI
*/
_updateFolderTextbox: function PBS__updateFolderTextbox(uri) {
var folderTextbox = document.getElementById("places-folder-list");
folderTextbox.value = this._getFolderNameListForURI(uri);
},
/**
* This method gets the list of folders that contain the current bookmark.
*
* @param aURI a nsIURI object representing the URI of the current bookmark
*
* @returns a comma-separated list of folder names in string form
*/
_getFolderNameListForURI: function PBS__getFolderNameListForURI(uri) {
var folders = this._bms.getBookmarkFolders(uri, {});
var results = [];
for (var i = 0; i < folders.length; i++) {
results.push(this._bms.getFolderTitle(folders[i]));
}
return results.join(", ");
},
/**
* Recursively populates the tag-like set of clickable folders.
*
* @param aContainer a reference to an nsINavHistoryContainerResultNode
* (whose) containerOpen property is set to true) representing
* the roote of the bookmark folder tree
* @param aDepth the current iteration depth -- pass this 0 at the top level.
* This only affects the visual indentation level of the tag display.
* @param aParentElement a vbox element into which the tags will be populated
* @param aElementDict a dictionary mapping folder IDs to element references
* to be populated in this method
*
* @returns none
*/
_populateTags:
function PBS__populateTags (container, depth, parentElement, elementDict) {
if (!container.containerOpen) {
throw new Error("The containerOpen property of the container parameter should be set to true before calling populateTags(), and then set to false again afterwards.");
}
var row = null;
for (var i = 0; i < container.childCount; i++) {
var childNode = container.getChild(i);
if (childNode.type != childNode.RESULT_TYPE_FOLDER)
continue;
var childFolder =
childNode.QueryInterface(Ci.nsINavHistoryFolderResultNode);
childFolder.containerOpen = true;
// If we can't alter it, no use showing it as an option.
if (childFolder.childrenReadOnly) {
childFolder.containerOpen = false;
continue;
}
if (childFolder.hasChildren) {
row = document.createElement("hbox");
row.setAttribute("class", "l" + depth);
var tag = this._createTagElement(childFolder, false);
elementDict[childFolder.folderId] = tag;
tag.setAttribute("isparent", "true");
row.appendChild(tag);
parentElement.appendChild(row);
row = null;
var nextDepth = depth + 1;
// We're limiting max indentation level here.
if (nextDepth > this.MAX_INDENT_DEPTH)
nextDepth = this.MAX_INDENT_DEPTH;
this._populateTags(childFolder, nextDepth, parentElement, elementDict);
} else {
if (row == null) {
row = document.createElement("description");
row.setAttribute("class", "l" + depth);
parentElement.appendChild(row);
} else {
// we now know that there must"ve been a tag before us on the same row
var separator = document.createElement("label");
separator.setAttribute("value", eval("\"\\u2022\"")); // bullet
separator.setAttribute("class", "tag-separator");
row.appendChild(separator);
}
var tag = this._createTagElement(childFolder, false);
elementDict[childFolder.folderId] = tag;
row.appendChild(tag);
}
childFolder.containerOpen = false;
}
},
/**
* This method creates a XUL element to represent a given Bookmark
* folder node.
*
* @param aNode an nsINavHistoryFolderResultNode object
* @param aIsSelected boolean, true if the given folder is currently selected
*
* @return a new XUL element corresponding to aNode
*/
_createTagElement: function PBS_createTagElement(node, isSelected) {
var tag = document.createElement("label");
tag.setAttribute("value", node.title);
tag.setAttribute("folderid", node.folderId);
tag.setAttribute("selected", "" + isSelected);
var self = this;
function onClick(e) {
self.tagClicked(e);
}
tag.addEventListener("command", onClick, false);
// We need the click event handler until we change the element from labels
// to something like checkboxes.
tag.addEventListener("click", onClick, false);
tag.setAttribute("class", "tag");
return tag;
},
/**
* This method should be called when a tag element generated by
* _createTagElement is clicked by the user.
*/
tagClicked: function PBS_tagClicked(event) {
var tagElement = event.target;
var folderId = parseInt(tagElement.getAttribute("folderid"));
if (tagElement.getAttribute("selected") == "true") {
this._bms.removeItem(folderId, this._currentURI);
tagElement.setAttribute("selected", "false");
} else {
this._bms.insertItem(folderId, this._currentURI, -1);
tagElement.setAttribute("selected", "true");
}
this._updateFolderTextbox(this._currentURI);
},
};
/**
* This is a custom implementation of nsITransactionManager. We do not chain
* or aggregate the default implementation because the order in which
* transactions are performed and undone is important to the user experience.
* There are two classes of transactions - those done by the browser window
* that contains this transaction manager, and those done by the embedded
* Places page. All transactions done in either part of the UI are recorded
* This is a custom implementation of nsITransactionManager. We do not chain
* or aggregate the default implementation because the order in which
* transactions are performed and undone is important to the user experience.
* There are two classes of transactions - those done by the browser window
* that contains this transaction manager, and those done by the embedded
* Places page. All transactions done in either part of the UI are recorded
* here, but ones performed by actions taken in the Places page affect the
* Undo/Redo menu items and keybindings in the browser window only when the
* Places page is the active tab. This is to prevent the user from accidentally
* undoing/redoing their changes while the Places page is not selected, and the
* user not noticing.
*
* user not noticing.
*
* When the Places page is navigated away from, the undo items registered for
* it are destroyed and the ability to undo those actions ceases.
* it are destroyed and the ability to undo those actions ceases.
*/
var PlacesTransactionManager = {
_undoItems: [],
_redoItems: [],
hidePageTransactions: true,
_getNextVisibleIndex: function PTM__getNextVisibleItem(list) {
if (!this.hidePageTransactions)
return list.length - 1;
for (var i = list.length - 1; i >= 0; --i) {
if (!list[i].pageTransaction)
return i;
}
return -1;
},
updateCommands: function PTM__updateCommands() {
CommandUpdater.updateCommand("cmd_undo");
CommandUpdater.updateCommand("cmd_redo");
@ -153,7 +519,7 @@ var PlacesTransactionManager = {
this._redoItems = [];
this.updateCommands();
},
undoTransaction: function PTM_undoTransaction() {
var index = this._getNextVisibleIndex(this._undoItems);
ASSERT(index >= 0, "Invalid Transaction index");
@ -168,31 +534,31 @@ var PlacesTransactionManager = {
ASSERT(index >= 0, "Invalid Transaction index");
var transaction = this._redoItems.splice(index, 1)[0];
transaction.redoTransaction();
this._undoItems.push(transaction);
this._undoItems.push(transaction);
this.updateCommands();
},
clear: function PTM_clear() {
this._undoItems = [];
this._redoItems = [];
this.updateCommands();
},
beginBatch: function PTM_beginBatch() {
},
endBatch: function PTM_endBatch() {
},
get numberOfUndoItems() {
return this.getUndoList().numItems;
},
get numberOfRedoItems() {
return this.getRedoList().numItems;
},
maxTransactionCount: -1,
peekUndoStack: function PTM_peekUndoStack() {
var index = this._getNextVisibleIndex(this._undoItems);
ASSERT(index >= 0, "Invalid Transaction index");
@ -203,11 +569,11 @@ var PlacesTransactionManager = {
ASSERT(index >= 0, "Invalid Transaction index");
return this._redoItems[index];
},
_filterList: function PTM__filterList(list) {
if (!this.hidePageTransactions)
return list;
var transactions = [];
for (var i = 0; i < list.length; ++i) {
if (!list[i].pageTransaction)
@ -215,15 +581,15 @@ var PlacesTransactionManager = {
}
return transactions;
},
getUndoList: function PTM_getUndoList() {
return new TransactionList(this._filterList(this._undoItems));
},
getRedoList: function PTM_getRedoList() {
return new TransactionList(this._filterList(this._redoItems));
},
_listeners: [],
_listeners: [],
AddListener: function PTM_AddListener(listener) {
this._listeners.push(listener);
},
@ -249,23 +615,23 @@ TransactionList.prototype = {
get numItems() {
return this._transactions.length;
},
itemIsBatch: function TL_itemIsBatch(index) {
return false;
},
getItem: function TL_getItem(index) {
return this._transactions[i];
},
getNumChildrenForItem: function TL_getNumChildrenForItem(index) {
return 0;
},
getChildListForItem: function TL_getChildListForItem(index) {
return null;
},
QueryInterface: function TL_QueryInterface(iid) {
if (iid.equals(Ci.nsITransactionList) ||
iid.equals(Ci.nsISupports))

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

@ -5,7 +5,8 @@
<!DOCTYPE overlay SYSTEM "chrome://browser/locale/places/places.dtd">
<overlay id="placesBrowserShim"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<script type="application/x-javascript"
src="chrome://browser/content/places/controller.js"/>
@ -37,9 +38,66 @@
<toolbox id="navigator-toolbox">
<toolbar id="bookmarksToolbar"
defaultset="bookmarksBarShowPlaces,bookmarksBarContainer"
toolbarname="Places Toolbar"
toolbarname="&places.toolbar.label;"
customizable="true"/>
</toolbox>
<toolbaritem id="urlbar-container">
<button id="places-bookmark" label="&location.status.not_bookmarked;" oncommand="PlacesBrowserShim.onBookmarkButtonClick();" align="start"/>
<button id="places-subscribe" label="&feed.subscribe.label;" tooltiptext="&feed.subscribe.tooltip;"/>
</toolbaritem>
<window id="main-window">
<stack id="places-info-popup" hidden="true">
<hbox id="edit-urlbox" flex="1">
<textbox id="edit-urlbar" flex="1" size="10" tooltiptext="&bookmark.property.location;"/>
</hbox>
<vbox id="places-info-options">
<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.folders;"/>
</hbox>
</vbox>
<textbox id="places-folder-list" value="" disabled="true"/>
</row>
<row>
<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">
<label id="places-link" value="&cmd.show_bookmarks.label;" onclick="PlacesBrowserShim.hideBookmarkProperties(true); PlacesBrowserShim.showBookmarks();"/>
<spacer flex="1"/>
<button label="&cmd.delete_bookmark.label;" oncommand="PlacesBrowserShim.deleteBookmark(); PlacesBrowserShim.hideBookmarkProperties(false);" align="end"/>
<button label="&cmd.hide_bookmark_properties.label;" oncommand="PlacesBrowserShim.hideBookmarkProperties(true)"/>
</hbox>
</vbox>
</row>
</rows>
</grid>
</vbox>
</stack>
</window>
</overlay>

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

@ -1,5 +1,7 @@
<!ENTITY places.title
"Places">
<!ENTITY places.toolbar.label
"Places Toolbar">
<!ENTITY cmd.find.label
"Find in Bookmarks/History...">
<!ENTITY cmd.find.accesskey
@ -198,3 +200,25 @@
"Maximum results: ">
<!ENTITY cmd.find.key
"f">
<!ENTITY feed.subscribe.label
"Feed">
<!ENTITY feed.subscribe.tooltip
"Subscribe">
<!ENTITY location.status.not_bookmarked
"Star (Off)">
<!ENTITY location.status.bookmarked
"Star (On)">
<!ENTITY bookmark.property.title
"Title">
<!ENTITY bookmark.property.folders
"Folders">
<!ENTITY bookmark.property.folder_list
"Folder List">
<!ENTITY bookmark.property.location
"Bookmark Location">
<!ENTITY cmd.show_bookmarks.label
"See all bookmarks">
<!ENTITY cmd.delete_bookmark.label
"Delete Bookmark">
<!ENTITY cmd.hide_bookmark_properties.label
"Done">

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

@ -35,3 +35,6 @@ searchDefault=Search
lessCriteria.label=-
moreCriteria.label=+
locationStatusNotBookmarked=Star (Off)
locationStatusBookmarked=Star (On)