зеркало из https://github.com/mozilla/gecko-dev.git
Bug 387749 - add an item detail pane to the organizer. r=dietrich (r=gavin for editable-menulist changes). a=mconnor.
This commit is contained in:
Родитель
0cccc74b01
Коммит
cad73793e2
|
@ -139,7 +139,8 @@ var PlacesCommandHook = {
|
|||
this.panel.openPopup(aAnchorElement, aPosition, -1, -1);
|
||||
|
||||
gEditItemOverlay.initPanel(aItemId,
|
||||
{ hiddenRows: ["description", "location"] });
|
||||
{ hiddenRows: ["description", "location",
|
||||
"loadInSidebar"] });
|
||||
setTimeout(function() {
|
||||
var namePicker = document.getElementById("editBMPanel_namePicker");
|
||||
namePicker.focus();
|
||||
|
|
|
@ -54,8 +54,8 @@ var gEditItemOverlay = {
|
|||
_uri: null,
|
||||
_itemId: -1,
|
||||
_itemType: -1,
|
||||
_readOnly: false,
|
||||
_microsummaries: null,
|
||||
_doneCallback: null,
|
||||
_hiddenRows: [],
|
||||
_observersAdded: false,
|
||||
|
||||
|
@ -76,46 +76,83 @@ var gEditItemOverlay = {
|
|||
|
||||
_showHideRows: function EIO__showHideRows() {
|
||||
var isBookmark = this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK;
|
||||
this._element("nameRow").hidden = this._hiddenRows.indexOf("name") != -1;
|
||||
this._element("folderRow").hidden =
|
||||
|
||||
this._element("nameRow").collapsed = this._hiddenRows.indexOf("name") != -1;
|
||||
this._element("folderRow").collapsed =
|
||||
this._hiddenRows.indexOf("folderPicker") != -1;
|
||||
this._element("tagsRow").hidden =
|
||||
this._hiddenRows.indexOf("tags") != -1 || !isBookmark;
|
||||
this._element("descriptionRow").hidden =
|
||||
this._hiddenRows.indexOf("description") != -1;
|
||||
this._element("locationRow").hidden =
|
||||
this._hiddenRows.indexOf("location") != -1 || !isBookmark;
|
||||
this._element("tagsRow").collapsed = !isBookmark ||
|
||||
this._hiddenRows.indexOf("tags") != -1;
|
||||
this._element("descriptionRow").collapsed =
|
||||
this._hiddenRows.indexOf("description") != -1 ||
|
||||
this._readOnly;
|
||||
this._element("keywordRow").collapsed = !isBookmark || this._readOnly ||
|
||||
this._hiddenRows.indexOf("keyword") != -1;
|
||||
this._element("locationRow").collapsed = !isBookmark ||
|
||||
this._hiddenRows.indexOf("location") != -1;
|
||||
this._element("loadInSidebarCheckbox").collapsed = !isBookmark ||
|
||||
this._readOnly || this._hiddenRows.indexOf("loadInSidebar") != -1;
|
||||
this._element("feedLocationRow").collapsed = !this._isLivemark ||
|
||||
this._hiddenRows.indexOf("feedLocation") != -1;
|
||||
this._element("siteLocationRow").collapsed = !this._isLivemark ||
|
||||
this._hiddenRows.indexOf("siteLocation") != -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the panel
|
||||
*/
|
||||
initPanel: function EIO_initPanel(aItemId, aInfo) {
|
||||
const bms = PlacesUtils.bookmarks;
|
||||
|
||||
this._folderMenuList = this._element("folderMenuList");
|
||||
this._folderTree = this._element("folderTree");
|
||||
this._itemId = aItemId;
|
||||
this._itemType = PlacesUtils.bookmarks.getItemType(this._itemId);
|
||||
this._itemType = bms.getItemType(this._itemId);
|
||||
this._determineInfo(aInfo);
|
||||
|
||||
var container = bms.getFolderIdForItem(this._itemId);
|
||||
if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
|
||||
this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
|
||||
// tags field
|
||||
this._element("tagsField").value =
|
||||
PlacesUtils.tagging.getTagsForURI(this._uri).join(", ");
|
||||
this._uri = bms.getBookmarkURI(this._itemId);
|
||||
this._isLivemark = false;
|
||||
if (PlacesUtils.livemarks.isLivemark(container))
|
||||
this._readOnly = true;
|
||||
else
|
||||
this._readOnly = false;
|
||||
|
||||
this._element("locationField").value = this._uri.spec;
|
||||
this._initTextField("locationField", this._uri.spec);
|
||||
this._initTextField("tagsField",
|
||||
PlacesUtils.tagging
|
||||
.getTagsForURI(this._uri).join(", "),
|
||||
false);
|
||||
this._initTextField("keywordField",
|
||||
bms.getKeywordForBookmark(this._itemId));
|
||||
|
||||
// Load In Sidebar checkbox
|
||||
this._element("loadInSidebarCheckbox").checked =
|
||||
PlacesUtils.annotations.itemHasAnnotation(this._itemId,
|
||||
LOAD_IN_SIDEBAR_ANNO);
|
||||
}
|
||||
else {
|
||||
this._readOnly = false;
|
||||
this._isLivemark = PlacesUtils.livemarks.isLivemark(this._itemId);
|
||||
if (this._isLivemark) {
|
||||
var feedURI = PlacesUtils.livemarks.getFeedURI(this._itemId);
|
||||
var siteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
|
||||
this._initTextField("feedLocationField", feedURI.spec);
|
||||
this._initTextField("siteLocationField", siteURI ? siteURI.spec : "");
|
||||
}
|
||||
this._uri = null;
|
||||
}
|
||||
|
||||
// folder picker
|
||||
this._initFolderMenuList();
|
||||
this._initFolderMenuList(container);
|
||||
|
||||
// name picker
|
||||
this._initNamePicker();
|
||||
|
||||
// description field
|
||||
this._element("descriptionField").value =
|
||||
PlacesUtils.getItemDescription(this._itemId);
|
||||
|
||||
this._initTextField("descriptionField",
|
||||
PlacesUtils.getItemDescription(this._itemId));
|
||||
|
||||
this._showHideRows();
|
||||
|
||||
// observe changes
|
||||
|
@ -126,6 +163,20 @@ var gEditItemOverlay = {
|
|||
}
|
||||
},
|
||||
|
||||
_initTextField: function(aTextFieldId, aValue, aReadOnly) {
|
||||
var field = this._element(aTextFieldId);
|
||||
field.readOnly = aReadOnly !== undefined ? aReadOnly : this._readOnly;
|
||||
|
||||
if (field.value != aValue) {
|
||||
field.value = aValue;
|
||||
|
||||
// clear the undo stack
|
||||
var editor = field.editor;
|
||||
if (editor)
|
||||
editor.transactionManager.clear();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends a menu-item representing a bookmarks folder to a menu-popup.
|
||||
* @param aMenupopup
|
||||
|
@ -148,16 +199,15 @@ var gEditItemOverlay = {
|
|||
return folderMenuItem;
|
||||
},
|
||||
|
||||
_initFolderMenuList: function EIO__initFolderMenuList() {
|
||||
_initFolderMenuList: function EIO__initFolderMenuList(aSelectedFolder) {
|
||||
// clean up first
|
||||
var menupopup = this._folderMenuList.menupopup;
|
||||
while (menupopup.childNodes.length > 4)
|
||||
menupopup.removeChild(menupopup.lastChild);
|
||||
|
||||
var container = PlacesUtils.bookmarks.getFolderIdForItem(this._itemId);
|
||||
|
||||
// only show "All Bookmarks" if the url isn't bookmarked somewhere else
|
||||
this._element("unfiledRootItem").hidden = container != PlacesUtils.unfiledRootId;
|
||||
this._element("unfiledRootItem").hidden =
|
||||
aSelectedFolder != PlacesUtils.unfiledRootId;
|
||||
|
||||
// List of recently used folders:
|
||||
var annos = PlacesUtils.annotations;
|
||||
|
@ -189,11 +239,12 @@ var gEditItemOverlay = {
|
|||
this._appendFolderItemToMenupopup(menupopup, folders[i].folderId);
|
||||
}
|
||||
|
||||
var defaultItem = this._getFolderMenuItem(container, true);
|
||||
var defaultItem = this._getFolderMenuItem(aSelectedFolder, true);
|
||||
this._folderMenuList.selectedItem = defaultItem;
|
||||
|
||||
// Hide the folders-separator if no folder is annotated as recently-used
|
||||
this._element("foldersSeparator").hidden = (menupopup.childNodes.length <= 4);
|
||||
this._folderMenuList.disabled = this._readOnly;
|
||||
},
|
||||
|
||||
QueryInterface: function EIO_QueryInterface(aIID) {
|
||||
|
@ -265,7 +316,8 @@ var gEditItemOverlay = {
|
|||
|
||||
var itemToSelect = userEnteredNameField;
|
||||
try {
|
||||
if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK)
|
||||
if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK &&
|
||||
!this._readOnly)
|
||||
this._microsummaries = this._mss.getMicrosummaries(this._uri, -1);
|
||||
}
|
||||
catch(ex) {
|
||||
|
@ -303,6 +355,12 @@ var gEditItemOverlay = {
|
|||
namePicker.selectedItem = itemToSelect;
|
||||
|
||||
namePicker.setAttribute("droppable", droppable);
|
||||
namePicker.readOnly = this._readOnly;
|
||||
|
||||
// clear the undo stack
|
||||
var editor = namePicker.editor;
|
||||
if (editor)
|
||||
editor.transactionManager.clear();
|
||||
},
|
||||
|
||||
// nsIMicrosummaryObserver
|
||||
|
@ -455,6 +513,52 @@ var gEditItemOverlay = {
|
|||
}
|
||||
},
|
||||
|
||||
onKeywordFieldBlur: function EIO_onKeywordFieldBlur() {
|
||||
var keyword = this._element("keywordField").value;
|
||||
if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) {
|
||||
var txn = PlacesUtils.ptm.editBookmarkKeyword(this._itemId, keyword);
|
||||
PlacesUtils.ptm.commitTransaction(txn);
|
||||
}
|
||||
},
|
||||
|
||||
onFeedLocationFieldBlur: function EIO_onFeedLocationFieldBlur() {
|
||||
// XXXmano: uri fixup
|
||||
var uri;
|
||||
try {
|
||||
uri = IO.newURI(this._element("feedLocationField").value);
|
||||
}
|
||||
catch(ex) { return; }
|
||||
|
||||
var currentFeedURI = PlacesUtils.livemarks.getFeedURI(this._itemId);
|
||||
if (!currentFeedURI.equals(uri)) {
|
||||
var txn = PlacesUtils.ptm.editLivemarkFeedURI(this._itemId, uri);
|
||||
PlacesUtils.ptm.commitTransaction(txn);
|
||||
}
|
||||
},
|
||||
|
||||
onSiteLocationFieldBlur: function EIO_onSiteLocationFieldBlur() {
|
||||
// XXXmano: uri fixup
|
||||
var uri = null;
|
||||
try {
|
||||
uri = IO.newURI(this._element("siteLocationField").value);
|
||||
}
|
||||
catch(ex) { }
|
||||
|
||||
var currentSiteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
|
||||
if (!uri || !currentSiteURI.equals(uri)) {
|
||||
var txn = PlacesUtils.ptm.editLivemarkSiteURI(this._itemId, uri);
|
||||
PlacesUtils.ptm.commitTransaction(txn);
|
||||
}
|
||||
},
|
||||
|
||||
onLoadInSidebarCheckboxCommand:
|
||||
function EIO_onLoadInSidebarCheckboxCommand() {
|
||||
var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
|
||||
var txn = PlacesUtils.ptm.setLoadInSidebar(this._itemId,
|
||||
loadInSidebarChecked);
|
||||
PlacesUtils.ptm.commitTransaction(txn);
|
||||
},
|
||||
|
||||
toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() {
|
||||
var expander = this._element("foldersExpander");
|
||||
if (!this._folderTree.collapsed) {
|
||||
|
@ -670,26 +774,53 @@ var gEditItemOverlay = {
|
|||
|
||||
var userEnteredNameField = this._element("userEnteredName");
|
||||
if (userEnteredNameField.value != aValue) {
|
||||
userEnteredNameField.value = aValue;
|
||||
userEnteredNameField.value = aValue;
|
||||
var namePicker = this._element("namePicker");
|
||||
if (namePicker.selectedItem == userEnteredNameField)
|
||||
if (namePicker.selectedItem == userEnteredNameField) {
|
||||
namePicker.label = aValue;
|
||||
|
||||
// clear undo stack
|
||||
namePicker.editor.transactionManager.clear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "uri":
|
||||
var locationField = this._element("locationField");
|
||||
if (locationField.value != aValue) {
|
||||
locationField.value = aValue;
|
||||
this._uri = IO.newURI(aValue);
|
||||
this._initTextField("locationField", this._uri.spec);
|
||||
this._initNamePicker(); // for microsummaries
|
||||
this._element("tagsField").value =
|
||||
PlacesUtils.tagging.getTagsForURI(this._uri).join(", ");
|
||||
this._initTextField("tagsField",
|
||||
PlacesUtils.tagging
|
||||
.getTagsForURI(this._uri).join(", "),
|
||||
false);
|
||||
this._rebuildTagsSelectorList();
|
||||
}
|
||||
break;
|
||||
case "keyword":
|
||||
this._initTextField("keywordField",
|
||||
PlacesUtils.bookmarks
|
||||
.getKeywordForBookmark(this._itemId));
|
||||
break;
|
||||
case DESCRIPTION_ANNO:
|
||||
this._element("descriptionField").value =
|
||||
PlacesUtils.annotations.getItemDescription(this._itemId);
|
||||
this._initTextField("descriptionField",
|
||||
PlacesUtils.getItemDescription(this._itemId));
|
||||
break;
|
||||
case LOAD_IN_SIDEBAR_ANNO:
|
||||
this._element("loadInSidebarCheckbox").checked =
|
||||
PlacesUtils.annotations.itemHasAnnotation(this._itemId,
|
||||
LOAD_IN_SIDEBAR_ANNO);
|
||||
break;
|
||||
case LMANNO_FEEDURI:
|
||||
var feedURISpec = PlacesUtils.livemarks.getFeedURI(this._itemId).spec;
|
||||
this._initTextField("feedLocationField", feedURISpec);
|
||||
break;
|
||||
case LMANNO_SITEURI:
|
||||
var siteURISpec = "";
|
||||
var siteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
|
||||
if (siteURI)
|
||||
siteURISpec = siteURI.spec;
|
||||
this._initTextField("siteLocationField", siteURISpec);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
src="chrome://browser/content/places/editBookmarkOverlay.js"/>
|
||||
|
||||
<vbox id="editBookmarkPanelContent">
|
||||
<broadcaster id="paneElementsBroadcaster"/>
|
||||
|
||||
<grid id="editBookmarkPanelGrid" flex="1">
|
||||
<columns>
|
||||
<column/>
|
||||
|
@ -57,14 +59,16 @@
|
|||
<rows>
|
||||
<row align="center" id="editBMPanel_nameRow">
|
||||
<label value="&editBookmarkOverlay.name.label;"
|
||||
contorl="editBMPanel_namePicker"/>
|
||||
control="editBMPanel_namePicker"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<menulist id="editBMPanel_namePicker"
|
||||
flex="1"
|
||||
editable="true"
|
||||
droppable="false"
|
||||
oninput="gEditItemOverlay.onNamePickerInput();"
|
||||
onblur="gEditItemOverlay.onNamePickerChange();"
|
||||
oncommand="gEditItemOverlay.onNamePickerChange();">
|
||||
oncommand="gEditItemOverlay.onNamePickerChange();"
|
||||
observes="paneElementsBroadcaster">
|
||||
<menupopup>
|
||||
<menuitem id="editBMPanel_userEnteredName"/>
|
||||
<menuitem disabled="true">
|
||||
|
@ -77,17 +81,39 @@
|
|||
|
||||
<row align="center" id="editBMPanel_locationRow">
|
||||
<label value="&editBookmarkOverlay.location.label;"
|
||||
contorl="editBMPanel_locationField"/>
|
||||
control="editBMPanel_locationField"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_locationField"
|
||||
onblur="gEditItemOverlay.onLocationFieldBlur();"/>
|
||||
onblur="gEditItemOverlay.onLocationFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
<row align="center" id="editBMPanel_feedLocationRow">
|
||||
<label value="&editBookmarkOverlay.feedLocation.label;"
|
||||
control="editBMPanel_feedLocationField"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_feedLocationField"
|
||||
onblur="gEditItemOverlay.onFeedLocationFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
<row align="center" id="editBMPanel_siteLocationRow">
|
||||
<label value="&editBookmarkOverlay.siteLocation.label;"
|
||||
control="editBMPanel_siteLocationField"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_siteLocationField"
|
||||
onblur="gEditItemOverlay.onSiteLocationFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
<row align="center" id="editBMPanel_folderRow">
|
||||
<label value="&editBookmarkOverlay.folder.label;"
|
||||
control="editBMPanel_folderMenuList"/>
|
||||
control="editBMPanel_folderMenuList"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<menulist id="editBMPanel_folderMenuList"
|
||||
class="folder-icon"
|
||||
oncommand="gEditItemOverlay.onFolderMenuListCommand();">
|
||||
oncommand="gEditItemOverlay.onFolderMenuListCommand();"
|
||||
observes="paneElementsBroadcaster">
|
||||
<menupopup>
|
||||
<!-- Static item for special folders -->
|
||||
<menuitem id="editBMPanel_unfiledRootItem"
|
||||
|
@ -107,7 +133,8 @@
|
|||
tooltiptext="&editBookmarkOverlay.foldersExpanderDown.tooltip;"
|
||||
tooltiptextdown="&editBookmarkOverlay.foldersExpanderDown.tooltip;"
|
||||
tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
|
||||
oncommand="gEditItemOverlay.toggleFolderTreeVisibility();"/>
|
||||
oncommand="gEditItemOverlay.toggleFolderTreeVisibility();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
<tree id="editBMPanel_folderTree"
|
||||
|
@ -118,7 +145,8 @@
|
|||
onselect="gEditItemOverlay.onFolderTreeSelect();"
|
||||
showRoot="true"
|
||||
place="place:folder=2&group=3&excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1"
|
||||
hidecolumnpicker="true">
|
||||
hidecolumnpicker="true"
|
||||
observes="paneElementsBroadcaster">
|
||||
<treecols>
|
||||
<treecol anonid="title" flex="1" primary="true" hideheader="true"/>
|
||||
</treecols>
|
||||
|
@ -127,25 +155,46 @@
|
|||
|
||||
<row align="center" id="editBMPanel_tagsRow">
|
||||
<label value="&editBookmarkOverlay.tags.label;"
|
||||
control="tagsField"/>
|
||||
control="tagsField"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_tagsField"
|
||||
onblur="gEditItemOverlay.onTagsFieldBlur();"/>
|
||||
onblur="gEditItemOverlay.onTagsFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<button id="editBMPanel_tagsSelectorExpander"
|
||||
class="expander-down"
|
||||
tooltiptext="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
|
||||
tooltiptextdown="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
|
||||
tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
|
||||
oncommand="gEditItemOverlay.toggleTagsSelector();"/>
|
||||
oncommand="gEditItemOverlay.toggleTagsSelector();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
<listbox id="editBMPanel_tagsSelector" height="150" collapsed="true"/>
|
||||
<listbox id="editBMPanel_tagsSelector"
|
||||
height="150" collapsed="true"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
|
||||
<row id="editBMPanel_descriptionRow" align="center">
|
||||
<row id="editBMPanel_keywordRow">
|
||||
<label value="&editBookmarkOverlay.keyword.label;"
|
||||
control="editBMPanel_keywordField"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_keywordField"
|
||||
onblur="gEditItemOverlay.onKeywordFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
<row id="editBMPanel_descriptionRow">
|
||||
<label value="&editBookmarkOverlay.description.label;"
|
||||
control="editBMPanel_descriptionField"/>
|
||||
control="editBMPanel_descriptionField"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_descriptionField"
|
||||
onblur="gEditItemOverlay.onDescriptionFieldBlur();"/>
|
||||
multiline="true"
|
||||
onblur="gEditItemOverlay.onDescriptionFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
<checkbox id="editBMPanel_loadInSidebarCheckbox"
|
||||
label="&editBookmarkOverlay.loadInSidebar.label;"
|
||||
oncommand="gEditItemOverlay.onLoadInSidebarCheckboxCommand();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</rows>
|
||||
</grid>
|
||||
</vbox>
|
||||
|
|
|
@ -27,3 +27,10 @@ button.commandButton {
|
|||
display: -moz-box;
|
||||
}
|
||||
|
||||
/* Edit Item Panel */
|
||||
|
||||
#infoScrollbox[minimal="true"] #editBMPanel_descriptionRow,
|
||||
#infoScrollbox[minimal="true"] #editBMPanel_loadInSidebarCheckbox,
|
||||
#infoScrollbox[minimal="true"] #editBMPanel_keywordRow {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
|
|
@ -10,4 +10,3 @@ hbox[type="places"] {
|
|||
menupopup[type="places"] {
|
||||
-moz-binding: url("chrome://browser/content/places/menu.xml#places-menupopup");
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
/**
|
||||
* Selects a place URI in the places list.
|
||||
* This function is global so it can be easily accessed by openers.
|
||||
* Selects a place URI in the places list.
|
||||
* This function is global so it can be easily accessed by openers.
|
||||
* @param placeURI
|
||||
* A place: URI string to select
|
||||
*/
|
||||
|
@ -59,7 +59,7 @@ var PlacesOrganizer = {
|
|||
// in the places tree binding's constructor
|
||||
setTimeout(function() { self._init(); }, 0);
|
||||
},
|
||||
|
||||
|
||||
_init: function PO__init() {
|
||||
this._places = document.getElementById("placesList");
|
||||
this._content = document.getElementById("placeContent");
|
||||
|
@ -106,6 +106,7 @@ var PlacesOrganizer = {
|
|||
this._backHistory.unshift(this.location);
|
||||
|
||||
this._content.place = this._location = aLocation;
|
||||
this.onContentTreeSelect();
|
||||
|
||||
// update navigation commands
|
||||
if (this._backHistory.length == 0)
|
||||
|
@ -138,7 +139,7 @@ var PlacesOrganizer = {
|
|||
HEADER_TYPE_ADVANCED_SEARCH: 3,
|
||||
|
||||
/**
|
||||
* Updates the text shown in the heading banner above the content view.
|
||||
* Updates the text shown in the heading banner above the content view.
|
||||
* @param type
|
||||
* The type of information being shown - normal (built-in history or
|
||||
* other query, bookmark folder), search results from the toolbar
|
||||
|
@ -155,7 +156,7 @@ var PlacesOrganizer = {
|
|||
|
||||
var contentTitle = document.getElementById("contentTitle");
|
||||
contentTitle.setAttribute("value", text);
|
||||
|
||||
|
||||
// Hide the advanced search controls when the user hasn't searched
|
||||
var searchModifiers = document.getElementById("searchModifiers");
|
||||
searchModifiers.hidden = type == this.HEADER_TYPE_SHOWING;
|
||||
|
@ -182,23 +183,22 @@ var PlacesOrganizer = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Loads the place URI entered in the debug
|
||||
* Loads the place URI entered in the debug
|
||||
*/
|
||||
loadPlaceURI: function PO_loadPlaceURI() {
|
||||
|
||||
// clear forward history
|
||||
this._forwardHistory.splice(0);
|
||||
|
||||
var placeURI = document.getElementById("placeURI");
|
||||
|
||||
var queriesRef = { }, optionsRef = { };
|
||||
PlacesUtils.history.queryStringToQueries(placeURI.value,
|
||||
PlacesUtils.history.queryStringToQueries(placeURI.value,
|
||||
queriesRef, { }, optionsRef);
|
||||
|
||||
|
||||
// for debug panel
|
||||
var autoFilterResults = document.getElementById("autoFilterResults");
|
||||
if (autoFilterResults.checked) {
|
||||
var options =
|
||||
var options =
|
||||
OptionsFilter.filter(queriesRef.value, optionsRef.value, null);
|
||||
}
|
||||
else
|
||||
|
@ -208,7 +208,7 @@ var PlacesOrganizer = {
|
|||
PlacesUtils.history.queriesToQueryString(queriesRef.value,
|
||||
queriesRef.value.length,
|
||||
options);
|
||||
|
||||
|
||||
placeURI.value = this.location;
|
||||
|
||||
this.setHeaderText(this.HEADER_TYPE_SHOWING, "Debug results for: " + placeURI.value);
|
||||
|
@ -227,7 +227,7 @@ var PlacesOrganizer = {
|
|||
var options = queryNode.queryOptions;
|
||||
var loadedURI = document.getElementById("loadedURI");
|
||||
loadedURI.value =
|
||||
PlacesUtils.history.queriesToQueryString(queries, queries.length,
|
||||
PlacesUtils.history.queriesToQueryString(queries, queries.length,
|
||||
options);
|
||||
},
|
||||
|
||||
|
@ -254,7 +254,7 @@ var PlacesOrganizer = {
|
|||
|
||||
// update location
|
||||
this.location = PlacesUtils.history.queriesToQueryString(queries, queries.length, options);
|
||||
|
||||
|
||||
// Make sure the query builder is hidden.
|
||||
PlacesQueryBuilder.hide();
|
||||
if (resetSearchBox) {
|
||||
|
@ -277,9 +277,9 @@ var PlacesOrganizer = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Handle clicks on the tree. If the user middle clicks on a URL, load that
|
||||
* URL according to rules. Single clicks or modified clicks do not result in
|
||||
* any special action, since they're related to selection.
|
||||
* Handle clicks on the tree. If the user middle clicks on a URL, load that
|
||||
* URL according to rules. Single clicks or modified clicks do not result in
|
||||
* any special action, since they're related to selection.
|
||||
* @param aEvent
|
||||
* The mouse event.
|
||||
*/
|
||||
|
@ -287,7 +287,7 @@ var PlacesOrganizer = {
|
|||
var currentView = aEvent.currentTarget;
|
||||
var controller = currentView.controller;
|
||||
|
||||
// If the user clicked on a tree column header, update the sorting
|
||||
// If the user clicked on a tree column header, update the sorting
|
||||
// preferences to reflect their choices.
|
||||
// XXXmano: should be done in tree.xml
|
||||
if (aEvent.target.localName == "treecol") {
|
||||
|
@ -298,9 +298,9 @@ var PlacesOrganizer = {
|
|||
if (PlacesUtils.nodeIsURI(currentView.selectedNode))
|
||||
controller.openSelectedNodeWithEvent(aEvent);
|
||||
else if (PlacesUtils.nodeIsContainer(currentView.selectedNode)) {
|
||||
// The command execution function will take care of seeing the
|
||||
// selection is a folder/container and loading its contents in
|
||||
// tabs for us.
|
||||
// The command execution function will take care of seeing the
|
||||
// selection is a folder/container and loading its contents in
|
||||
// tabs for us.
|
||||
controller.openLinksInTabs();
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ var PlacesOrganizer = {
|
|||
getCurrentOptions: function PO_getCurrentOptions() {
|
||||
return asQuery(this._content.getResult().root).queryOptions;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Show the migration wizard for importing from a file.
|
||||
*/
|
||||
|
@ -379,9 +379,9 @@ var PlacesOrganizer = {
|
|||
|
||||
// get bookmarks backup dir
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
getService(Ci.nsIProperties);
|
||||
var bookmarksBackupDir = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
bookmarksBackupDir.append("bookmarkbackups");
|
||||
bookmarksBackupDir.append("bookmarkbackups");
|
||||
if (!bookmarksBackupDir.exists())
|
||||
return; // no backup files
|
||||
|
||||
|
@ -424,22 +424,22 @@ var PlacesOrganizer = {
|
|||
*/
|
||||
onRestoreMenuItemClick: function PO_onRestoreMenuItemClick(aMenuItem) {
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
getService(Ci.nsIProperties);
|
||||
var bookmarksFile = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
bookmarksFile.append("bookmarkbackups");
|
||||
bookmarksFile.append("bookmarkbackups");
|
||||
bookmarksFile.append(aMenuItem.getAttribute("value"));
|
||||
if (!bookmarksFile.exists())
|
||||
return;
|
||||
|
||||
var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
getService(Ci.nsIPromptService);
|
||||
if (!prompts.confirm(null,
|
||||
PlacesUtils.getString("bookmarksRestoreAlertTitle"),
|
||||
PlacesUtils.getString("bookmarksRestoreAlert")))
|
||||
return;
|
||||
|
||||
var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
ieSvc.importHTMLFromFile(bookmarksFile, true);
|
||||
},
|
||||
|
||||
|
@ -451,9 +451,9 @@ var PlacesOrganizer = {
|
|||
fp.init(window, PlacesUtils.getString("bookmarksBackupTitle"),
|
||||
Ci.nsIFilePicker.modeSave);
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||
|
||||
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
getService(Ci.nsIProperties);
|
||||
var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
|
||||
fp.displayDirectory = backupsDir;
|
||||
|
||||
|
@ -462,10 +462,10 @@ var PlacesOrganizer = {
|
|||
var date = (new Date).toLocaleFormat("%Y-%m-%d");
|
||||
fp.defaultString = PlacesUtils.getFormattedString("bookmarksBackupFilename",
|
||||
[date]);
|
||||
|
||||
|
||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
||||
var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
ieSvc.exportHTMLToFile(fp.file);
|
||||
}
|
||||
},
|
||||
|
@ -476,50 +476,181 @@ var PlacesOrganizer = {
|
|||
*/
|
||||
restoreFromFile: function PO_restoreFromFile() {
|
||||
var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
getService(Ci.nsIPromptService);
|
||||
if (!prompts.confirm(null, PlacesUtils.getString("bookmarksRestoreAlertTitle"),
|
||||
PlacesUtils.getString("bookmarksRestoreAlert")))
|
||||
return;
|
||||
|
||||
|
||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, PlacesUtils.getString("bookmarksRestoreTitle"),
|
||||
Ci.nsIFilePicker.modeOpen);
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||
|
||||
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
getService(Ci.nsIProperties);
|
||||
var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
|
||||
fp.displayDirectory = backupsDir;
|
||||
|
||||
|
||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
||||
var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
ieSvc.importHTMLFromFile(fp.file, true);
|
||||
}
|
||||
},
|
||||
|
||||
_paneDisabled: false,
|
||||
_setDetailsFieldsDisabledState:
|
||||
function PO__setDetailsFieldsDisabledState(aDisabled) {
|
||||
if (aDisabled) {
|
||||
document.getElementById("paneElementsBroadcaster")
|
||||
.setAttribute("disabled", "true");
|
||||
}
|
||||
else {
|
||||
document.getElementById("paneElementsBroadcaster")
|
||||
.removeAttribute("disabled");
|
||||
}
|
||||
},
|
||||
|
||||
_detectAndSetDetailsPaneMinimalState:
|
||||
function PO__detectAndSetDetailsPaneMinimalState(aNode) {
|
||||
/**
|
||||
* The details of simple folder-items (as opposed to livemarks) or the
|
||||
* of livemark-children are not likely to fill the scrollbox anyway,
|
||||
* thus we remove the "More/Less" button and show all details.
|
||||
*
|
||||
* the wasminimal attribute here is used to persist the "more/less"
|
||||
* state in a bookmark->folder->bookmark scenario.
|
||||
*/
|
||||
var infoScrollbox = document.getElementById("infoScrollbox");
|
||||
var scrollboxExpander = document.getElementById("infoScrollboxExpander");
|
||||
if ((PlacesUtils.nodeIsFolder(aNode) &&
|
||||
!PlacesUtils.nodeIsLivemarkContainer(aNode)) ||
|
||||
PlacesUtils.nodeIsLivemarkItem(aNode)) {
|
||||
if (infoScrollbox.getAttribute("minimal") == "true")
|
||||
infoScrollbox.setAttribute("wasminimal", "true");
|
||||
infoScrollbox.removeAttribute("minimal");
|
||||
scrollboxExpander.hidden = true;
|
||||
}
|
||||
else {
|
||||
if (infoScrollbox.getAttribute("wasminimal") == "true")
|
||||
infoScrollbox.setAttribute("minimal", "true");
|
||||
infoScrollbox.removeAttribute("wasminimal");
|
||||
scrollboxExpander.hidden = false;
|
||||
}
|
||||
},
|
||||
|
||||
updateThumbnailProportions: function PO_updateThumbnailProportions() {
|
||||
var previewBox = document.getElementById("previewBox");
|
||||
var canvas = document.getElementById("itemThumbnail");
|
||||
var height = previewBox.boxObject.height;
|
||||
var width = height * (screen.width / screen.height);
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
},
|
||||
|
||||
onContentTreeSelect: function PO_onContentTreeSelect() {
|
||||
// If a textbox within a panel is focused, force-blur it so its contents
|
||||
// are saved
|
||||
if (gEditItemOverlay.itemId != -1) {
|
||||
var focusedElement = document.commandDispatcher.focusedElement;
|
||||
if (focusedElement instanceof HTMLInputElement &&
|
||||
/^editBMPanel.*/.test(focusedElement.parentNode.parentNode.id))
|
||||
focusedElement.blur();
|
||||
}
|
||||
|
||||
var contentTree = document.getElementById("placeContent");
|
||||
var deck = document.getElementById("infoDeck");
|
||||
this.updateStatusBarForView(contentTree);
|
||||
if (contentTree.hasSingleSelection) {
|
||||
var selectedNode = contentTree.selectedNode;
|
||||
if (selectedNode.itemId != -1 &&
|
||||
!PlacesUtils.nodeIsSeparator(selectedNode)) {
|
||||
gEditItemOverlay.initPanel(selectedNode.itemId,
|
||||
{ hiddenRows: ["folderPicker"] });
|
||||
deck.selectedIndex = 1;
|
||||
return;
|
||||
var detailsDeck = document.getElementById("detailsDeck");
|
||||
if (contentTree.hasSelection) {
|
||||
detailsDeck.selectedIndex = 1;
|
||||
if (contentTree.hasSingleSelection) {
|
||||
var selectedNode = contentTree.selectedNode;
|
||||
if (selectedNode.itemId != -1 &&
|
||||
!PlacesUtils.nodeIsSeparator(selectedNode)) {
|
||||
if (this._paneDisabled) {
|
||||
this._setDetailsFieldsDisabledState(false);
|
||||
this._paneDisabled = false;
|
||||
}
|
||||
|
||||
gEditItemOverlay.initPanel(selectedNode.itemId,
|
||||
{ hiddenRows: ["folderPicker"] });
|
||||
|
||||
this._detectAndSetDetailsPaneMinimalState(selectedNode);
|
||||
this.updateThumbnailProportions();
|
||||
this._updateThumbnail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
gEditItemOverlay.uninitPanel();
|
||||
deck.selectedIndex = 0;
|
||||
else {
|
||||
detailsDeck.selectedIndex = 0;
|
||||
var selectItemDesc = document.getElementById("selectItemDescription");
|
||||
var itemsCountLabel = document.getElementById("itemsCountText");
|
||||
var rowCount = this._content.treeBoxObject.view.rowCount;
|
||||
if (rowCount == 0) {
|
||||
selectItemDesc.hidden = true;
|
||||
itemsCountLabel.value = PlacesUtils.getString("detailsPane.noItems");
|
||||
}
|
||||
else {
|
||||
selectItemDesc.hidden = false;
|
||||
if (rowCount == 1)
|
||||
itemsCountLabel.value = PlacesUtils.getString("detailsPane.oneItem");
|
||||
else {
|
||||
itemsCountLabel.value =
|
||||
PlacesUtils.getFormattedString("detailsPane.multipleItems",
|
||||
[rowCount]);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateThumbnailProportions();
|
||||
this._updateThumbnail();
|
||||
}
|
||||
|
||||
// Nothing to do if the pane was already disabled
|
||||
if (!this._paneDisabled) {
|
||||
gEditItemOverlay.uninitPanel();
|
||||
this._setDetailsFieldsDisabledState(true);
|
||||
this._paneDisabled = true;
|
||||
}
|
||||
},
|
||||
|
||||
_updateThumbnail: function PO__updateThumbnail() {
|
||||
var bo = document.getElementById("previewBox").boxObject;
|
||||
var width = bo.width;
|
||||
var height = bo.height;
|
||||
|
||||
var canvas = document.getElementById("itemThumbnail");
|
||||
var ctx = canvas.getContext('2d');
|
||||
var notAvailableText = canvas.getAttribute("notavailabletext");
|
||||
ctx.save();
|
||||
ctx.fillStyle = "-moz-Dialog";
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.translate(width/2, height/2);
|
||||
|
||||
ctx.fillStyle = "GrayText";
|
||||
ctx.mozTextStyle = "12pt sans serif";
|
||||
var len = ctx.mozMeasureText(notAvailableText);
|
||||
ctx.translate(-len/2,0);
|
||||
ctx.mozDrawText(notAvailableText);
|
||||
ctx.restore();
|
||||
},
|
||||
|
||||
toggleAdditionalInfoFields: function PO_toggleAdditionalInfoFields() {
|
||||
var infoScrollbox = document.getElementById("infoScrollbox");
|
||||
var scrollboxExpander = document.getElementById("infoScrollboxExpander");
|
||||
if (infoScrollbox.getAttribute("minimal") == "true") {
|
||||
infoScrollbox.removeAttribute("minimal");
|
||||
scrollboxExpander.label = scrollboxExpander.getAttribute("lesslabel");
|
||||
}
|
||||
else {
|
||||
infoScrollbox.setAttribute("minimal", "true");
|
||||
scrollboxExpander.label = scrollboxExpander.getAttribute("morelabel");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Save the current search (or advanced query) to the bookmarks root.
|
||||
*/
|
||||
saveSearch: function PP_saveSearch() {
|
||||
saveSearch: function PO_saveSearch() {
|
||||
// Get the place: uri for the query.
|
||||
// If the advanced query builder is showing, use that.
|
||||
var queries = [];
|
||||
|
@ -553,7 +684,7 @@ var PlacesOrganizer = {
|
|||
var defaultText = PlacesUtils.getString("saveSearch.defaultText");
|
||||
|
||||
var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
getService(Ci.nsIPromptService);
|
||||
var check = {value: false};
|
||||
var input = {value: defaultText};
|
||||
var save = prompts.prompt(null, title, inputLabel, input, null, check);
|
||||
|
@ -562,14 +693,17 @@ var PlacesOrganizer = {
|
|||
if (!save || input.value == "")
|
||||
return;
|
||||
|
||||
// Add the place: uri as a bookmark under the places root.
|
||||
var txn = PlacesUtils.ptm.createItem(placeURI, PlacesUtils.bookmarks.bookmarksRoot, PlacesUtils.bookmarks.DEFAULT_INDEX, input.value);
|
||||
// Add the place: uri as a bookmark under the bookmarks root.
|
||||
var txn = PlacesUtils.ptm.createItem(placeURI,
|
||||
PlacesUtils.bookmarksRootId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
input.value);
|
||||
PlacesUtils.ptm.commitTransaction(txn);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A set of utilities relating to search within Bookmarks and History.
|
||||
* A set of utilities relating to search within Bookmarks and History.
|
||||
*/
|
||||
var PlacesSearchBox = {
|
||||
|
||||
|
@ -583,14 +717,14 @@ var PlacesSearchBox = {
|
|||
/**
|
||||
* Run a search for the specified text, over the collection specified by
|
||||
* the dropdown arrow. The default is all bookmarks, but can be
|
||||
* localized to the active collection.
|
||||
* localized to the active collection.
|
||||
* @param filterString
|
||||
* The text to search for.
|
||||
* The text to search for.
|
||||
*/
|
||||
search: function PSB_search(filterString) {
|
||||
// for non-"bookmarks" collections,
|
||||
// for non-"bookmarks" collections,
|
||||
// do not search for "" since it will match all history. Assume if the user
|
||||
// deleted everything that they want to type something else and don't
|
||||
// deleted everything that they want to type something else and don't
|
||||
// update the view.
|
||||
if (PlacesSearchBox.filterCollection != "bookmarks" &&
|
||||
(filterString == "" || this.searchFilter.hasAttribute("empty")))
|
||||
|
@ -618,7 +752,7 @@ var PlacesSearchBox = {
|
|||
PO.setHeaderText(PO.HEADER_TYPE_SEARCH, filterString);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
this.searchFilter.setAttribute("filtered", "true");
|
||||
},
|
||||
|
||||
|
@ -645,7 +779,7 @@ var PlacesSearchBox = {
|
|||
*/
|
||||
updateCollectionTitle: function PSB_updateCollectionTitle(title) {
|
||||
if (title) {
|
||||
this.searchFilter.grayText =
|
||||
this.searchFilter.grayText =
|
||||
PlacesUtils.getFormattedString("searchCurrentDefault", [title]);
|
||||
}
|
||||
else
|
||||
|
@ -685,17 +819,17 @@ var PlacesSearchBox = {
|
|||
this.searchFilter.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the gray text in the search bar as the Places View loads.
|
||||
/**
|
||||
* Set up the gray text in the search bar as the Places View loads.
|
||||
*/
|
||||
init: function PSB_init() {
|
||||
var searchFilter = this.searchFilter;
|
||||
searchFilter.grayText = PlacesUtils.getString("searchByDefault");
|
||||
searchFilter.reset();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Gets or sets the text shown in the Places Search Box
|
||||
* Gets or sets the text shown in the Places Search Box
|
||||
*/
|
||||
get value() {
|
||||
return this.searchFilter.value;
|
||||
|
@ -716,8 +850,8 @@ var PlacesQueryBuilder = {
|
|||
_numRows: 0,
|
||||
|
||||
/**
|
||||
* The maximum number of terms that can be added.
|
||||
* XXXben - this should be generated dynamically based on the contents of a
|
||||
* The maximum number of terms that can be added.
|
||||
* XXXben - this should be generated dynamically based on the contents of a
|
||||
* list of terms searchable through this widget, rather than being
|
||||
* a hard coded number.
|
||||
*/
|
||||
|
@ -765,7 +899,7 @@ var PlacesQueryBuilder = {
|
|||
"visited": this._locationSearch,
|
||||
"location": null
|
||||
};
|
||||
|
||||
|
||||
this._queryBuilders = {
|
||||
"keyword": this.setKeywordQuery,
|
||||
"visited": this.setVisitedQuery,
|
||||
|
@ -787,7 +921,7 @@ var PlacesQueryBuilder = {
|
|||
var titleDeck = document.getElementById("titleDeck");
|
||||
titleDeck.setAttribute("selectedIndex", 0);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Shows the query builder
|
||||
*/
|
||||
|
@ -797,7 +931,7 @@ var PlacesQueryBuilder = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Includes the rowId in the id attribute of an element in a row newly
|
||||
* Includes the rowId in the id attribute of an element in a row newly
|
||||
* created from the template row.
|
||||
* @param element
|
||||
* The element whose id attribute needs to be updated.
|
||||
|
@ -832,7 +966,7 @@ var PlacesQueryBuilder = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Adds a row to the view, prefilled with the next query subject. If the
|
||||
* Adds a row to the view, prefilled with the next query subject. If the
|
||||
* query builder is not visible, it will be shown.
|
||||
*/
|
||||
addRow: function PQB_addRow() {
|
||||
|
@ -848,7 +982,7 @@ var PlacesQueryBuilder = {
|
|||
|
||||
// Determine what the search type is based on the last visible row. If this
|
||||
// is the first row, the type is "keyword search". Otherwise, it's the next
|
||||
// in the sequence after the one defined by the previous visible row's
|
||||
// in the sequence after the one defined by the previous visible row's
|
||||
// Subject selector, as defined in _nextSearch.
|
||||
var searchType = this._keywordSearch;
|
||||
var lastMenu = document.getElementById("advancedSearch" +
|
||||
|
@ -857,15 +991,15 @@ var PlacesQueryBuilder = {
|
|||
if (this._numRows > 0 && lastMenu && lastMenu.selectedItem) {
|
||||
searchType = this._nextSearch[lastMenu.selectedItem.value];
|
||||
}
|
||||
// There is no "next" search type. We are here in error.
|
||||
// There is no "next" search type. We are here in error.
|
||||
if (!searchType)
|
||||
return;
|
||||
// We don't insert into the document until _after_ the searchType is
|
||||
// We don't insert into the document until _after_ the searchType is
|
||||
// determined, since this will interfere with the computation.
|
||||
gridRows.appendChild(newRow);
|
||||
this._setRowId(newRow, ++this._numRows);
|
||||
|
||||
// Ensure the Advanced Search container is visible, if this is the first
|
||||
// Ensure the Advanced Search container is visible, if this is the first
|
||||
// row being added.
|
||||
var advancedSearch = document.getElementById("advancedSearch");
|
||||
if (advancedSearch.collapsed) {
|
||||
|
@ -874,10 +1008,10 @@ var PlacesQueryBuilder = {
|
|||
// Update the header.
|
||||
const asType = PlacesOrganizer.HEADER_TYPE_ADVANCED_SEARCH;
|
||||
PlacesOrganizer.setHeaderText(asType, "");
|
||||
|
||||
// Pre-fill the search terms field with the value from the one on the
|
||||
|
||||
// Pre-fill the search terms field with the value from the one on the
|
||||
// toolbar.
|
||||
// For some reason, setting.value here synchronously does not appear to
|
||||
// For some reason, setting.value here synchronously does not appear to
|
||||
// work.
|
||||
var searchTermsField = document.getElementById("advancedSearch1Textbox");
|
||||
if (searchTermsField)
|
||||
|
@ -888,7 +1022,7 @@ var PlacesQueryBuilder = {
|
|||
// the toolbar.
|
||||
this.addRow();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.showSearch(this._numRows, searchType);
|
||||
this._updateUIForRowChange();
|
||||
|
@ -930,7 +1064,7 @@ var PlacesQueryBuilder = {
|
|||
// there are.
|
||||
var d0 = null;
|
||||
var d1 = null;
|
||||
// If there are an even number of elements in the date array, try to
|
||||
// If there are an even number of elements in the date array, try to
|
||||
// parse it as a range of two dates.
|
||||
if ((dateArr.length & 1) == 0) {
|
||||
var mid = dateArr.length / 2;
|
||||
|
@ -971,11 +1105,11 @@ var PlacesQueryBuilder = {
|
|||
var calendar = document.getElementById("advancedSearch" + row + "Calendar");
|
||||
var begin = calendar.beginrange;
|
||||
var end = calendar.endrange;
|
||||
|
||||
|
||||
// If the calendar doesn't have a begin/end, don't change the textbox.
|
||||
if (begin == null || end == null)
|
||||
return true;
|
||||
|
||||
|
||||
// If the begin and end are the same day, only fill that into the textbox.
|
||||
var textbox = document.getElementById("advancedSearch" + row + "TimePicker");
|
||||
var beginDate = begin.getDate();
|
||||
|
@ -1007,10 +1141,10 @@ var PlacesQueryBuilder = {
|
|||
endDate);
|
||||
textbox.value = beginStr + " - " + endStr;
|
||||
}
|
||||
|
||||
|
||||
// Update the search.
|
||||
this.doSearch();
|
||||
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -1058,7 +1192,7 @@ var PlacesQueryBuilder = {
|
|||
element.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.doSearch();
|
||||
},
|
||||
|
||||
|
@ -1073,17 +1207,15 @@ var PlacesQueryBuilder = {
|
|||
}
|
||||
else {
|
||||
query.uriIsPrefix = (type == "startswith");
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
var spec = document.getElementById(prefix + "Textbox").value;
|
||||
try {
|
||||
query.uri = ios.newURI(spec, null, null);
|
||||
query.uri = IO.newURI(spec);
|
||||
}
|
||||
catch (e) {
|
||||
// Invalid input can cause newURI to barf, that's OK, tack "http://"
|
||||
// Invalid input can cause newURI to barf, that's OK, tack "http://"
|
||||
// onto the front and try again to see if the user omitted it
|
||||
try {
|
||||
query.uri = ios.newURI("http://" + spec, null, null);
|
||||
query.uri = IO.newURI("http://" + spec);
|
||||
}
|
||||
catch (e) {
|
||||
// OK, they have entered something which can never match. This should
|
||||
|
@ -1143,7 +1275,7 @@ var PlacesQueryBuilder = {
|
|||
for (var i = 1; updated < this._numRows; ++i) {
|
||||
var prefix = "advancedSearch" + i;
|
||||
|
||||
// The user can remove rows from the middle and start of the list, not
|
||||
// The user can remove rows from the middle and start of the list, not
|
||||
// just from the end, so we need to make sure that this row actually
|
||||
// exists before attempting to construct a query for it.
|
||||
var querySubjectElement = document.getElementById(prefix + "Subject");
|
||||
|
@ -1155,30 +1287,30 @@ var PlacesQueryBuilder = {
|
|||
query = this.queries[0];
|
||||
else
|
||||
query = PlacesUtils.history.getNewQuery();
|
||||
|
||||
|
||||
var querySubject = querySubjectElement.value;
|
||||
this._queryBuilders[querySubject](query, prefix);
|
||||
|
||||
|
||||
if (queryType == "or")
|
||||
this.queries.push(query);
|
||||
|
||||
|
||||
++updated;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make sure we're getting uri results, not visits
|
||||
this.options = PlacesOrganizer.getCurrentOptions();
|
||||
this.options.resultType = options.RESULT_TYPE_URI;
|
||||
|
||||
// XXXben - find some public way of doing this!
|
||||
PlacesOrganizer._content.load(queries,
|
||||
PlacesOrganizer._content.load(queries,
|
||||
OptionsFilter.filter(queries, options, null));
|
||||
PlacesOrganizer.updateLoadedURI();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Population and commands for the View Menu.
|
||||
* Population and commands for the View Menu.
|
||||
*/
|
||||
var ViewMenu = {
|
||||
/**
|
||||
|
@ -1186,36 +1318,36 @@ var ViewMenu = {
|
|||
* @param popup
|
||||
* The popup that contains the previously generated content.
|
||||
* @param startID
|
||||
* The id attribute of an element that is the start of the
|
||||
* The id attribute of an element that is the start of the
|
||||
* dynamically generated region - remove elements after this
|
||||
* item only.
|
||||
* item only.
|
||||
* Must be contained by popup. Can be null (in which case the
|
||||
* contents of popup are removed).
|
||||
* contents of popup are removed).
|
||||
* @param endID
|
||||
* The id attribute of an element that is the end of the
|
||||
* dynamically generated region - remove elements up to this
|
||||
* item only.
|
||||
* Must be contained by popup. Can be null (in which case all
|
||||
* items until the end of the popup will be removed). Ignored
|
||||
* if startID is null.
|
||||
* @returns The element for the caller to insert new items before,
|
||||
* if startID is null.
|
||||
* @returns The element for the caller to insert new items before,
|
||||
* null if the caller should just append to the popup.
|
||||
*/
|
||||
_clean: function VM__clean(popup, startID, endID) {
|
||||
if (endID)
|
||||
if (endID)
|
||||
NS_ASSERT(startID, "meaningless to have valid endID and null startID");
|
||||
if (startID) {
|
||||
var startElement = document.getElementById(startID);
|
||||
NS_ASSERT(startElement.parentNode ==
|
||||
NS_ASSERT(startElement.parentNode ==
|
||||
popup, "startElement is not in popup");
|
||||
NS_ASSERT(startElement,
|
||||
NS_ASSERT(startElement,
|
||||
"startID does not correspond to an existing element");
|
||||
var endElement = null;
|
||||
if (endID) {
|
||||
endElement = document.getElementById(endID);
|
||||
NS_ASSERT(endElement.parentNode == popup,
|
||||
NS_ASSERT(endElement.parentNode == popup,
|
||||
"endElement is not in popup");
|
||||
NS_ASSERT(endElement,
|
||||
NS_ASSERT(endElement,
|
||||
"endID does not correspond to an existing element");
|
||||
}
|
||||
while (startElement.nextSibling != endElement)
|
||||
|
@ -1224,7 +1356,7 @@ var ViewMenu = {
|
|||
}
|
||||
else {
|
||||
while(popup.hasChildNodes())
|
||||
popup.removeChild(popup.firstChild);
|
||||
popup.removeChild(popup.firstChild);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
@ -1238,8 +1370,8 @@ var ViewMenu = {
|
|||
* @param endID
|
||||
* see _clean
|
||||
* @param type
|
||||
* the type of the menuitem, e.g. "radio" or "checkbox".
|
||||
* Can be null (no-type).
|
||||
* the type of the menuitem, e.g. "radio" or "checkbox".
|
||||
* Can be null (no-type).
|
||||
* Checkboxes are checked if the column is visible.
|
||||
* @param propertyPrefix
|
||||
* If propertyPrefix is non-null:
|
||||
|
@ -1251,11 +1383,11 @@ var ViewMenu = {
|
|||
* no accesskey is assigned.
|
||||
*/
|
||||
fillWithColumns: function VM_fillWithColumns(event, startID, endID, type, propertyPrefix) {
|
||||
var popup = event.target;
|
||||
var popup = event.target;
|
||||
var pivot = this._clean(popup, startID, endID);
|
||||
|
||||
// If no column is "sort-active", the "Unsorted" item needs to be checked,
|
||||
// so track whether or not we find a column that is sort-active.
|
||||
// If no column is "sort-active", the "Unsorted" item needs to be checked,
|
||||
// so track whether or not we find a column that is sort-active.
|
||||
var isSorted = false;
|
||||
var content = document.getElementById("placeContent");
|
||||
var columns = content.columns;
|
||||
|
@ -1278,7 +1410,7 @@ var ViewMenu = {
|
|||
if (type == "radio") {
|
||||
menuitem.setAttribute("type", "radio");
|
||||
menuitem.setAttribute("name", "columns");
|
||||
// This column is the sort key. Its item is checked.
|
||||
// This column is the sort key. Its item is checked.
|
||||
if (column.getAttribute("sortDirection") != "") {
|
||||
menuitem.setAttribute("checked", "true");
|
||||
isSorted = true;
|
||||
|
@ -1289,18 +1421,18 @@ var ViewMenu = {
|
|||
// Cannot uncheck the primary column.
|
||||
if (column.getAttribute("primary") == "true")
|
||||
menuitem.setAttribute("disabled", "true");
|
||||
// Items for visible columns are checked.
|
||||
// Items for visible columns are checked.
|
||||
if (!column.hidden)
|
||||
menuitem.setAttribute("checked", "true");
|
||||
}
|
||||
if (pivot)
|
||||
popup.insertBefore(menuitem, pivot);
|
||||
else
|
||||
popup.appendChild(menuitem);
|
||||
popup.appendChild(menuitem);
|
||||
}
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set up the content of the view menu.
|
||||
*/
|
||||
|
@ -1310,7 +1442,7 @@ var ViewMenu = {
|
|||
var sortColumn = this._getSortColumn();
|
||||
var viewSortAscending = document.getElementById("viewSortAscending");
|
||||
var viewSortDescending = document.getElementById("viewSortDescending");
|
||||
// We need to remove an existing checked attribute because the unsorted
|
||||
// We need to remove an existing checked attribute because the unsorted
|
||||
// menu item is not rebuilt every time we open the menu like the others.
|
||||
var viewUnsorted = document.getElementById("viewUnsorted");
|
||||
if (!sortColumn) {
|
||||
|
@ -1329,7 +1461,7 @@ var ViewMenu = {
|
|||
viewUnsorted.removeAttribute("checked");
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Shows/Hides a tree column.
|
||||
* @param element
|
||||
|
@ -1339,13 +1471,13 @@ var ViewMenu = {
|
|||
const PREFIX = "menucol_";
|
||||
var columnID = element.id.substr(PREFIX.length, element.id.length);
|
||||
var column = document.getElementById(columnID);
|
||||
NS_ASSERT(column,
|
||||
NS_ASSERT(column,
|
||||
"menu item for column that doesn't exist?! id = " + element.id);
|
||||
|
||||
var splitter = column.nextSibling;
|
||||
if (splitter && splitter.localName != "splitter")
|
||||
splitter = null;
|
||||
|
||||
|
||||
if (element.getAttribute("checked") == "true") {
|
||||
column.removeAttribute("hidden");
|
||||
if (splitter)
|
||||
|
@ -1355,12 +1487,12 @@ var ViewMenu = {
|
|||
column.setAttribute("hidden", "true");
|
||||
if (splitter)
|
||||
splitter.setAttribute("hidden", "true");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the last column that was sorted.
|
||||
* @returns the currently sorted column, null if there is no sorted column.
|
||||
* Gets the last column that was sorted.
|
||||
* @returns the currently sorted column, null if there is no sorted column.
|
||||
*/
|
||||
_getSortColumn: function VM__getSortColumn() {
|
||||
var content = document.getElementById("placeContent");
|
||||
|
@ -1380,7 +1512,7 @@ var ViewMenu = {
|
|||
* The ID of the colum that is the sort key. Can be null - the
|
||||
* current sort column id or "title" will be used.
|
||||
* @param aDirection
|
||||
* The direction to sort - "ascending" or "descending".
|
||||
* The direction to sort - "ascending" or "descending".
|
||||
* Can be null - the last direction or descending will be used.
|
||||
*
|
||||
* If both aColumnID and aDirection are null, the view will be unsorted.
|
||||
|
@ -1416,7 +1548,7 @@ var ViewMenu = {
|
|||
case "date":
|
||||
sortingMode = aDirection == "descending" ?
|
||||
NHQO.SORT_BY_DATE_DESCENDING : NHQO.SORT_BY_DATE_ASCENDING;
|
||||
break;
|
||||
break;
|
||||
case "visitCount":
|
||||
sortingMode = aDirection == "descending" ?
|
||||
NHQO.SORT_BY_VISITCOUNT_DESCENDING : NHQO.SORT_BY_VISITCOUNT_ASCENDING;
|
||||
|
@ -1448,12 +1580,12 @@ var ViewMenu = {
|
|||
};
|
||||
|
||||
/**
|
||||
* A "Configuration" set for a class of history query results. Some results
|
||||
* A "Configuration" set for a class of history query results. Some results
|
||||
* will require that the grouping UI be labeled differently from the standard
|
||||
* so this object is provided to allow those results to configure the UI when
|
||||
* they are displayed.
|
||||
* @param substr
|
||||
* A prefix substring of an annotation that the result's query
|
||||
* A prefix substring of an annotation that the result's query
|
||||
* matches.
|
||||
* @param onLabel
|
||||
* The label for the "Grouping On" command
|
||||
|
@ -1468,10 +1600,10 @@ var ViewMenu = {
|
|||
* @param offOncommand
|
||||
* The "oncommand" attribute of the "Grouping Off" command
|
||||
* @param disabled
|
||||
* Whether or not grouping is disabled for results that match this
|
||||
* Whether or not grouping is disabled for results that match this
|
||||
* config.
|
||||
*/
|
||||
function GroupingConfig(substr, onLabel, onAccesskey, offLabel, offAccesskey,
|
||||
function GroupingConfig(substr, onLabel, onAccesskey, offLabel, offAccesskey,
|
||||
onOncommand, offOncommand, disabled) {
|
||||
this.substr = substr;
|
||||
this.onLabel = onLabel;
|
||||
|
@ -1484,24 +1616,24 @@ function GroupingConfig(substr, onLabel, onAccesskey, offLabel, offAccesskey,
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles Grouping within the Content View, and the commands that support it.
|
||||
* Handles Grouping within the Content View, and the commands that support it.
|
||||
*/
|
||||
var Groupers = {
|
||||
defaultGrouper: null,
|
||||
annotationGroupers: [],
|
||||
|
||||
/**
|
||||
* Initializes groupings for various view types.
|
||||
* Initializes groupings for various view types.
|
||||
*/
|
||||
init: function G_init() {
|
||||
this.defaultGrouper =
|
||||
this.defaultGrouper =
|
||||
new GroupingConfig(null, PlacesUtils.getString("defaultGroupOnLabel"),
|
||||
PlacesUtils.getString("defaultGroupOnAccesskey"),
|
||||
PlacesUtils.getString("defaultGroupOffLabel"),
|
||||
PlacesUtils.getString("defaultGroupOffAccesskey"),
|
||||
"Groupers.groupBySite()",
|
||||
"Groupers.groupByPage()", false);
|
||||
var subscriptionConfig =
|
||||
var subscriptionConfig =
|
||||
new GroupingConfig("livemark/", PlacesUtils.getString("livemarkGroupOnLabel"),
|
||||
PlacesUtils.getString("livemarkGroupOnAccesskey"),
|
||||
PlacesUtils.getString("livemarkGroupOffLabel"),
|
||||
|
@ -1512,10 +1644,10 @@ var Groupers = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Get the most appropriate GroupingConfig for the set of queries that are
|
||||
* Get the most appropriate GroupingConfig for the set of queries that are
|
||||
* about to be executed.
|
||||
* @param queries
|
||||
* An array of queries that are about to be executed.
|
||||
* An array of queries that are about to be executed.
|
||||
* @param handler
|
||||
* Optionally specify which handler to use to filter the options.
|
||||
* If null, the default handler for the queries will be used.
|
||||
|
@ -1524,7 +1656,7 @@ var Groupers = {
|
|||
if (!handler)
|
||||
handler = OptionsFilter.getHandler(queries);
|
||||
|
||||
// If the queries will generate a bookmarks folder, there is no "grouper
|
||||
// If the queries will generate a bookmarks folder, there is no "grouper
|
||||
// config" since all of the grouping UI should be hidden (there is only one
|
||||
// grouping mode - group by folder).
|
||||
if (handler == OptionsFilter.bookmarksHandler)
|
||||
|
@ -1542,16 +1674,16 @@ var Groupers = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Updates the grouping broadcasters for the given result.
|
||||
* Updates the grouping broadcasters for the given result.
|
||||
* @param queries
|
||||
* An array of queries that are going to be executed.
|
||||
* @param options
|
||||
* The options that are being used to generate the forthcoming
|
||||
* The options that are being used to generate the forthcoming
|
||||
* result.
|
||||
* @param handler
|
||||
* Optionally specify which handler to use to filter the options.
|
||||
* If null, the default handler for the queries will be used.
|
||||
* @param
|
||||
* @param
|
||||
*/
|
||||
updateGroupingUI: function G_updateGroupingUI(queries, options, handler) {
|
||||
var separator = document.getElementById("placesBC_grouping:separator");
|
||||
|
@ -1560,9 +1692,9 @@ var Groupers = {
|
|||
separator.removeAttribute("hidden");
|
||||
groupOff.removeAttribute("hidden");
|
||||
groupOn.removeAttribute("hidden");
|
||||
|
||||
// Walk the list of registered annotationGroupers, determining what are
|
||||
// available and notifying the broadcaster
|
||||
|
||||
// Walk the list of registered annotationGroupers, determining what are
|
||||
// available and notifying the broadcaster
|
||||
var config = this._getConfig(queries, handler);
|
||||
if (!config) {
|
||||
// Generic Bookmarks Folder or custom container that disables grouping.
|
||||
|
@ -1577,8 +1709,8 @@ var Groupers = {
|
|||
groupOff.setAttribute("label", config.offLabel);
|
||||
groupOff.setAttribute("accesskey", config.offAccesskey);
|
||||
groupOff.setAttribute("oncommand", config.offOncommand);
|
||||
// Update the checked state of the UI:
|
||||
// Grouping UI is "enabled" if there is at least one set of grouping
|
||||
// Update the checked state of the UI:
|
||||
// Grouping UI is "enabled" if there is at least one set of grouping
|
||||
// options.
|
||||
var groupingsCountRef = { };
|
||||
options.getGroupingMode(groupingsCountRef);
|
||||
|
@ -1587,12 +1719,12 @@ var Groupers = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Update the visual state of UI that controls grouping.
|
||||
* Update the visual state of UI that controls grouping.
|
||||
*/
|
||||
_updateBroadcasters: function G__updateGroupingBroadcasters(on) {
|
||||
var groupingOn = document.getElementById("placesBC_grouping:on");
|
||||
var groupingOff = document.getElementById("placesBC_grouping:off");
|
||||
if (on) {
|
||||
if (on) {
|
||||
groupingOn.setAttribute("checked", "true");
|
||||
groupingOff.removeAttribute("checked");
|
||||
}
|
||||
|
@ -1603,7 +1735,7 @@ var Groupers = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Shows visited pages grouped by site.
|
||||
* Shows visited pages grouped by site.
|
||||
*/
|
||||
groupBySite: function G_groupBySite() {
|
||||
var query = asQuery(PlacesOrganizer._content.getResult().root);
|
||||
|
@ -1620,7 +1752,7 @@ var Groupers = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Shows visited pages without grouping.
|
||||
* Shows visited pages without grouping.
|
||||
*/
|
||||
groupByPage: function G_groupByPage() {
|
||||
var query = asQuery(PlacesOrganizer._content.getResult().root);
|
||||
|
@ -1636,7 +1768,7 @@ var Groupers = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Shows all subscribed feeds (Live Bookmarks) grouped under their parent
|
||||
* Shows all subscribed feeds (Live Bookmarks) grouped under their parent
|
||||
* feed.
|
||||
*/
|
||||
groupByFeed: function G_groupByFeed() {
|
||||
|
@ -1668,4 +1800,3 @@ var Groupers = {
|
|||
OptionsFilter.update(content.getResult());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
<?xml-stylesheet href="chrome://global/skin/"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
|
||||
|
||||
<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
|
||||
#else
|
||||
|
@ -64,6 +66,7 @@
|
|||
title="&places.organizer.title;"
|
||||
windowtype="Places:Organizer"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
onload="PlacesOrganizer.init();"
|
||||
onunload="PlacesOrganizer.destroy();"
|
||||
width="700" height="500" screenX="10" screenY="10"
|
||||
|
@ -71,6 +74,8 @@
|
|||
|
||||
<script type="application/x-javascript"
|
||||
src="chrome://browser/content/places/places.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/utilityOverlay.js"/>
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include ../../../base/content/browserMountPoints.inc
|
||||
|
@ -240,22 +245,13 @@
|
|||
accesskey="&selectAllCmd.accesskey;"/>
|
||||
|
||||
<menuseparator id="orgMoveSeparator"/>
|
||||
|
||||
|
||||
<menuitem id="orgDelete"
|
||||
command="cmd_delete"
|
||||
label="&deleteCmd.label;"
|
||||
key="key_delete"
|
||||
accesskey="&deleteCmd.accesskey;"/>
|
||||
<menuitem id="orgRename"
|
||||
command="placesCmd_rename"
|
||||
label="&cmd.rename.label;"
|
||||
accesskey="&cmd.rename.accesskey;"/>
|
||||
<menuitem id="orgProperties"
|
||||
command="placesCmd_show:info"
|
||||
label="&cmd.properties.label;"
|
||||
key="placesKey_show:info"
|
||||
accesskey="&cmd.properties.accesskey;"/>
|
||||
|
||||
|
||||
<menuseparator id="orgCloseSeparator"/>
|
||||
|
||||
<menuitem id="orgClose"
|
||||
|
@ -270,6 +266,7 @@
|
|||
label="&views.label;"
|
||||
accesskey="&view.accesskey;">
|
||||
<menupopup id="viewMenuPopup">
|
||||
<!--
|
||||
<menuitem id="viewDetails"
|
||||
type="radio"
|
||||
#ifdef MACOSX
|
||||
|
@ -282,18 +279,19 @@
|
|||
|
||||
<menuseparator id="addonsSeparator"/>
|
||||
|
||||
<!--
|
||||
<menuitem id="viewAddons"
|
||||
command=""
|
||||
label="&view.addons.label;"
|
||||
accesskey="&view.addons.label;"/>
|
||||
<menuseparator id="sortingSeparator"/>
|
||||
-->
|
||||
-->
|
||||
|
||||
<menu id="viewColumns"
|
||||
label="&view.columns.label;" accesskey="&view.columns.accesskey;">
|
||||
<menupopup onpopupshowing="ViewMenu.fillWithColumns(event, null, null, 'checkbox', null);"
|
||||
oncommand="ViewMenu.showHideColumn(event.target); event.stopPropagation();"/>
|
||||
</menu>
|
||||
|
||||
<menu id="viewSort" label="&view.sort.label;"
|
||||
accesskey="&view.sort.accesskey;">
|
||||
<menupopup onpopupshowing="ViewMenu.populateSortMenu(event);"
|
||||
|
@ -310,14 +308,14 @@
|
|||
oncommand="ViewMenu.setSortColumn(null, 'descending'); event.stopPropagation();"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<!--
|
||||
<!--
|
||||
<menuseparator id="groupingSeparator" observes="placesBC_grouping:separator"/>
|
||||
|
||||
<menuitem id="viewGroupNone" type="radio" name="group"
|
||||
observes="placesBC_grouping:off"/>
|
||||
<menuitem id="viewGroupGroup" type="radio" name="group"
|
||||
observes="placesBC_grouping:on"/>
|
||||
-->
|
||||
-->
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
|
||||
|
@ -408,41 +406,75 @@
|
|||
command="OrganizerCommand_search:moreCriteria"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
#include advancedSearch.inc
|
||||
<tree id="placeContent" class="placesTree" context="placesContext"
|
||||
flex="1" type="places"
|
||||
ondblclick="this.controller.openSelectedNodeWithEvent(event);"
|
||||
onclick="PlacesOrganizer.onTreeClick(event);">
|
||||
<treecols id="placeContentColumns">
|
||||
<treecol label="&col.name.label;" id="title" flex="5" primary="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.tags.label;" id="tags" flex="2"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.url.label;" id="url" flex="5"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.lastvisit.label;" id="date" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.visitcount.label;" id="visitCount" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.keyword.label;" id="keyword" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.description.label;" id="description" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.dateadded.label;" id="dateAdded" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.lastmodified.label;" id="lastModified" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
</treecols>
|
||||
<treechildren id="placeContentChildren" view="placeContent" flex="1"/>
|
||||
</tree>
|
||||
#include advancedSearch.inc
|
||||
<vbox flex="1">
|
||||
<tree id="placeContent" class="placesTree" context="placesContext"
|
||||
flex="1" type="places"
|
||||
ondblclick="this.controller.openSelectedNodeWithEvent(event);"
|
||||
onclick="PlacesOrganizer.onTreeClick(event);"
|
||||
onselect="PlacesOrganizer.onContentTreeSelect();">
|
||||
<treecols id="placeContentColumns">
|
||||
<treecol label="&col.name.label;" id="title" flex="5" primary="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.tags.label;" id="tags" flex="2"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.url.label;" id="url" flex="5"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.lastvisit.label;" id="date" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.visitcount.label;" id="visitCount" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.keyword.label;" id="keyword" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.description.label;" id="description" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.dateadded.label;" id="dateAdded" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.lastmodified.label;" id="lastModified" flex="1" hidden="true"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
</treecols>
|
||||
<treechildren id="placeContentChildren" view="placeContent" flex="1"/>
|
||||
</tree>
|
||||
<splitter id="contentSplitter" collapse="after" persist="state">
|
||||
<grippy/>
|
||||
</splitter>
|
||||
<hbox persist="height" id="infoPane">
|
||||
<hbox id="previewBox" style="min-width: 60px; -moz-border-end: 1px solid GrayText;">
|
||||
<html:canvas id="itemThumbnail" notavailabletext="&detailsPane.noPreviewAvailable.label;"/>
|
||||
</hbox>
|
||||
<deck flex="1" id="detailsDeck">
|
||||
<vbox align="center">
|
||||
<spacer flex="3"/>
|
||||
<label id="itemsCountText"/>
|
||||
<spacer flex="1"/>
|
||||
<description id="selectItemDescription">
|
||||
&detailsPane.selectAnItemText.description;
|
||||
</description>
|
||||
<spacer flex="3"/>
|
||||
</vbox>
|
||||
<scrollbox id="infoScrollbox" minimal="true" orient="vertical" flex="1" style='overflow: auto;'>
|
||||
<vbox id="editBookmarkPanelContent"/>
|
||||
<hbox>
|
||||
<button type="image" id="infoScrollboxExpander"
|
||||
lesslabel="&detailsPane.less.label;"
|
||||
morelabel="&detailsPane.more.label;"
|
||||
label="&detailsPane.more.label;"
|
||||
oncommand="PlacesOrganizer.toggleAdditionalInfoFields();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
</scrollbox>
|
||||
</deck>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox id="debugPanel" hidden="true">
|
||||
<grid>
|
||||
<columns>
|
||||
|
|
|
@ -52,6 +52,7 @@ const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
|||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
const POST_DATA_ANNO = "URIProperties/POSTData";
|
||||
const LMANNO_FEEDURI = "livemark/feedURI";
|
||||
const LMANNO_SITEURI = "livemark/siteURI";
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// On Mac OSX, the transferable system converts "\r\n" to "\n\n", where we
|
||||
|
@ -408,7 +409,7 @@ var PlacesUtils = {
|
|||
*/
|
||||
nodeIsLivemarkContainer: function PU_nodeIsLivemarkContainer(aNode) {
|
||||
return this.nodeIsFolder(aNode) &&
|
||||
this.annotations.itemHasAnnotation(aNode.itemId, LMANNO_FEEDURI);
|
||||
this.livemarks.isLivemark(aNode.itemId);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -457,7 +458,7 @@ var PlacesUtils = {
|
|||
},
|
||||
|
||||
/**
|
||||
* String-wraps a NavHistoryResultNode according to the rules of the specified
|
||||
* String-wraps a result node according to the rules of the specified
|
||||
* content type.
|
||||
* @param aNode
|
||||
* The Result node to wrap (serialize)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<!ENTITY editBookmarkOverlay.name.label "Name:">
|
||||
<!ENTITY editBookmarkOverlay.location.label "Location:">
|
||||
<!ENTITY editBookmarkOverlay.feedLocation.label "Feed Location:">
|
||||
<!ENTITY editBookmarkOverlay.siteLocation.label "Site Location:">
|
||||
<!ENTITY editBookmarkOverlay.liveTitlesSeparator.label "Live Titles">
|
||||
<!ENTITY editBookmarkOverlay.folder.label "Folder:">
|
||||
<!ENTITY editBookmarkOverlay.allBookmarksFolderItem.label "All Bookmarks">
|
||||
|
@ -9,4 +11,6 @@
|
|||
<!ENTITY editBookmarkOverlay.expanderUp.tooltip "Hide">
|
||||
<!ENTITY editBookmarkOverlay.tags.label "Tags:">
|
||||
<!ENTITY editBookmarkOverlay.description.label "Description:">
|
||||
<!ENTITY editBookmarkOverlay.keyword.label "Keyword:">
|
||||
<!ENTITY editBookmarkOverlay.tagsExpanderDown.tooltip "Show all tags">
|
||||
<!ENTITY editBookmarkOverlay.loadInSidebar.label "Load this bookmark in the sidebar">
|
||||
|
|
|
@ -191,3 +191,12 @@
|
|||
<!ENTITY forwardCmd.label "Forward">
|
||||
<!ENTITY forwardCmd.accesskey "F">
|
||||
<!ENTITY forwardButton.tooltip "Go forward">
|
||||
|
||||
<!ENTITY detailsPane.more.label
|
||||
"More">
|
||||
<!ENTITY detailsPane.less.label
|
||||
"Less">
|
||||
<!ENTITY detailsPane.noPreviewAvailable.label
|
||||
"Preview">
|
||||
<!ENTITY detailsPane.selectAnItemText.description
|
||||
"Select an item to view and edit its properties">
|
||||
|
|
|
@ -93,3 +93,7 @@ EnterExport=Export Bookmarks File
|
|||
saveSearch.title=Save Search
|
||||
saveSearch.inputLabel=Name:
|
||||
saveSearch.defaultText=New Query
|
||||
|
||||
detailsPane.noItems=No items
|
||||
detailsPane.oneItem=One item
|
||||
detailsPane.multipleItems=%S items
|
||||
|
|
|
@ -49,6 +49,8 @@ classic.jar:
|
|||
skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
|
||||
skin/classic/browser/places/starPage.png (places/starPage.png)
|
||||
skin/classic/browser/places/pageStarred.png (places/pageStarred.png)
|
||||
skin/classic/browser/places/twisty-open.gif (places/twisty-open.gif)
|
||||
skin/classic/browser/places/twisty-closed.gif (places/twisty-closed.gif)
|
||||
skin/classic/browser/places/tag.png (places/tag.png)
|
||||
skin/classic/browser/places/organizer-toolbar.png (bookmarks/Bookmarks-toolbar.png)
|
||||
skin/classic/browser/places/expander-closed-active.png (bookmarks/expander-closed-active.png)
|
||||
|
|
|
@ -112,17 +112,28 @@
|
|||
*/
|
||||
-moz-appearance: textfield;
|
||||
cursor: text;
|
||||
margin: 2px 4px;
|
||||
border: 2px solid;
|
||||
-moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
|
||||
-moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
|
||||
-moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
|
||||
-moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
|
||||
padding: 2px 2px 3px 4px;
|
||||
margin: 4px 4px;
|
||||
border: 3px solid;
|
||||
-moz-border-top-colors: transparent #888888 #000000;
|
||||
-moz-border-right-colors: transparent #FFFFFF #000000;
|
||||
-moz-border-bottom-colors: transparent #FFFFFF #000000;
|
||||
-moz-border-left-colors: transparent #888888 #000000;
|
||||
-moz-border-radius-topright: 2px;
|
||||
-moz-border-radius-bottomleft: 2px;
|
||||
padding: 0;
|
||||
background-color: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
|
||||
#editBMPanel_namePicker[droppable="false"][disabled="true"] > .menulist-editable-box {
|
||||
cursor: default;
|
||||
-moz-border-top-colors: transparent ThreeDShadow -moz-Dialog;
|
||||
-moz-border-right-colors: transparent ThreeDShadow -moz-Dialog;
|
||||
-moz-border-bottom-colors: transparent ThreeDShadow -moz-Dialog;
|
||||
-moz-border-left-colors: transparent ThreeDShadow -moz-Dialog;
|
||||
color: GrayText;
|
||||
}
|
||||
|
||||
#editBMPanel_namePicker[droppable="false"] > .menulist-editable-box > html|*.textbox-input {
|
||||
margin: 0px !important;
|
||||
border: none !important;
|
||||
|
|
|
@ -272,3 +272,24 @@ treechildren::-moz-tree-twisty(title, separator) {
|
|||
min-width:0em;
|
||||
}
|
||||
|
||||
/**
|
||||
* info pane
|
||||
*/
|
||||
|
||||
/* More/Less button */
|
||||
#infoScrollboxExpander {
|
||||
list-style-image: url("chrome://browser/skin/places/twisty-open.gif");
|
||||
-moz-appearance: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-width: 0;
|
||||
}
|
||||
|
||||
#infoScrollbox[minimal="true"] #infoScrollboxExpander {
|
||||
list-style-image: url("chrome://browser/skin/places/twisty-closed.gif");
|
||||
}
|
||||
|
||||
#itemsCountText,
|
||||
#selectItemDescription {
|
||||
color: GrayText;
|
||||
}
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 372 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 372 B |
|
@ -358,7 +358,7 @@
|
|||
|
||||
<binding id="menulist-editable" extends="chrome://global/content/bindings/menulist.xml#menulist">
|
||||
<content sizetopopup="pref">
|
||||
<xul:hbox class="menulist-editable-box textbox-input-box" xbl:inherits="context" flex="1">
|
||||
<xul:hbox class="menulist-editable-box textbox-input-box" xbl:inherits="context,disabled,readonly" flex="1">
|
||||
<html:input class="menulist-editable-input" flex="1" anonid="input" allowevents="true"
|
||||
xbl:inherits="value=label,value,disabled,tabindex,readonly"/>
|
||||
</xul:hbox>
|
||||
|
@ -493,6 +493,11 @@
|
|||
]]></getter>
|
||||
</property>
|
||||
|
||||
<property name="readOnly" onset="this.inputField.readOnly = val;
|
||||
if (val) this.setAttribute('readonly', 'true');
|
||||
else this.removeAttribute('readonly'); return val;"
|
||||
onget="return this.inputField.readOnly;"/>
|
||||
|
||||
<method name="select">
|
||||
<body>
|
||||
this.inputField.select();
|
||||
|
|
Загрузка…
Ссылка в новой задаче