зеркало из https://github.com/mozilla/gecko-dev.git
Checking in add bookmark UI modifications, cf. bug 322989
This commit is contained in:
Родитель
3d4b1b7933
Коммит
ff3df4b86e
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче