2008-07-16 08:41:38 -07:00
<?xml version="1.0"?>
2008-12-15 08:44:27 -08:00
< !DOCTYPE bindings [
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
]>
2008-07-16 08:41:38 -07:00
<bindings
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id= "autocomplete-aligned" extends= "chrome://global/content/bindings/autocomplete.xml#autocomplete" >
<implementation >
<method name= "openPopup" >
<body > < ![CDATA[
this.popup.openAutocompletePopup(this, document.getElementById("toolbar-main"));
]]></body>
</method>
<method name= "closePopup" >
<body > < ![CDATA[
// do nothing
]]></body>
</method>
<method name= "reallyClosePopup" >
<body > < ![CDATA[
this.mConsumeRollupEvent = false;
this.popup.closePopup();
]]></body>
</method>
</implementation>
</binding>
2009-02-24 22:20:45 -08:00
2008-12-09 10:38:31 -08:00
<binding id= "popup_autocomplete" >
<content hidden= "true" >
<xul:vbox class= "autocomplete-box" flex= "1" >
<xul:vbox class= "autocomplete-items" anonid= "autocomplete-items" flex= "1000" >
<xul:label />
<xul:label />
<xul:label />
<xul:label />
<xul:label />
<xul:label />
<xul:label />
</xul:vbox>
<children />
</xul:vbox>
</content>
<implementation implements= "nsIAutoCompletePopup, nsIDOMEventListener" >
<constructor > < ![CDATA[
window.addEventListener("click", this, true);
window.addEventListener("blur", this, true);
]]></constructor>
<!-- nsIAutocompleteInput -->
<property name= "overrideValue"
readonly="true"
onget="return null;"/>
<field name= "_input" />
<property name= "input"
readonly="true"
onget="return this._input;"/>
<field name= "_selectedIndex" > -1</field>
<field name= "_selectedItem" />
<property name= "selectedIndex"
onget="return this._selectedIndex;">
<setter > < ![CDATA[
// Ignore invalid indices
if (val < -1 | |
val > this._matchCount - 1)
return val;
if (this._selectedItem)
this._styleItem(this._selectedItem, false);
// highlight the selected item
let item = this._items.childNodes.item(val);
if (item) {
this._selectedItem = item;
this._styleItem(this._selectedItem, true);
}
2009-02-24 22:20:45 -08:00
2008-12-09 10:38:31 -08:00
return this._selectedIndex = val;
]]></setter>
</property>
<field name= "_popupOpen" > false</field>
<property name= "popupOpen"
readonly="true"
onget="return this._popupOpen;"/>
<method name= "openAutocompletePopup" >
<parameter name= "aInput" />
<parameter name= "aElement" />
<body > < ![CDATA[
if (this._popupOpen)
return;
this._input = aInput;
this.hidden = false;
this._popupOpen = true;
this.invalidate();
]]></body>
</method>
<method name= "closePopup" >
<body > < ![CDATA[
if (!this._popupOpen)
return;
this.selectedIndex = -1;
this.input.controller.stopSearch();
this.hidden = true;
this._popupOpen = false;
]]></body>
</method>
<method name= "invalidate" >
<body > < ![CDATA[
// Don't bother doing work if we're not even open
if (!this.popupOpen)
return;
let controller = this.input.controller;
let searchString = controller.searchString;
let matchCount = this._matchCount;
let children = this._items.childNodes.length;
for (let i = 0; i < children ; + + i ) {
let label = this._items.childNodes[i];
label._index = i;
// Check whether there's an entry to fill
if (i > matchCount - 1) {
// Just clear out the old item
label.setAttribute("class", "");
label.setAttribute("value", "");
continue;
}
let url = controller.getValueAt(i);
let title = controller.getCommentAt(i);
let type = controller.getStyleAt(i);
let image = controller.getImageAt(i);
let typeClass = "ac-result-type-" + type;
label.setAttribute("class", "autocomplete-item " + typeClass);
label.setAttribute("value", title || url);
}
]]></body>
</method>
<method name= "selectBy" >
<parameter name= "aReverse" />
<parameter name= "aPage" />
<body > < ![CDATA[
let newIndex;
let lastIndex = this._matchCount - 1;
if (this._selectedIndex == -1)
newIndex = aReverse ? lastIndex : 0;
else
newIndex = this._selectedIndex + (aReverse ? -1 : 1);
// Deal with rollover
if (newIndex > lastIndex)
newIndex = 0;
else if (newIndex < 0 )
newIndex = lastIndex;
this.selectedIndex = newIndex;
]]></body>
</method>
2009-02-24 22:20:45 -08:00
2008-12-09 10:38:31 -08:00
<!-- Helpers -->
<field name= "_items" >
document.getAnonymousElementByAttribute(this,
"anonid", "autocomplete-items");
</field>
<property name= "_matchCount"
readonly="true">
<getter > < ![CDATA[
return Math.min(this.input.controller.matchCount, this._items.childNodes.length);
]]></getter>
</property>
<!-- Handles click/blur events on the window while the popup is open. -->
<method name= "handleEvent" >
<parameter name= "aEvent" />
<body > < ![CDATA[
this.closePopup();
]]></body>
</method>
2009-02-24 22:20:45 -08:00
2008-12-09 10:38:31 -08:00
<method name= "_styleItem" >
<parameter name= "aItem" />
<parameter name= "aAddStyle" />
<body > < ![CDATA[
if (aAddStyle)
aItem.className = "autocomplete-item-selected";
else
aItem.className = "autocomplete-item";
]]></body>
</method>
</implementation>
<handlers >
<handler event= "click" >
< ![CDATA[
let originalTarget = event.originalTarget;
if (event.button == 0 & &
originalTarget.localName == "label") {
this._selectedIndex = originalTarget._index;
this.input.controller.handleEnter(true);
} else
this.closePopup();
]]>
</handler>
</handlers>
</binding>
2008-07-16 08:41:38 -07:00
2009-02-24 22:20:45 -08:00
<binding id= "place-base" >
<content />
2008-12-15 08:44:27 -08:00
<implementation >
2009-02-24 22:20:45 -08:00
<constructor >
< ![CDATA[
2009-02-24 22:20:45 -08:00
let itemId = this.getAttribute("itemid");
if (itemId)
this.init(itemId);
2009-02-24 22:20:45 -08:00
]]>
</constructor>
2009-02-24 22:20:45 -08:00
<field name= "_itemId" > null</field>
2009-02-24 22:20:45 -08:00
<field name= "_uri" />
2009-02-24 22:20:45 -08:00
<field name= "_control" > null</field>
2009-02-24 22:20:45 -08:00
<field name= "_isEditing" > false</field>
2008-12-15 08:44:27 -08:00
<field name= "_nameField" >
document.getAnonymousElementByAttribute(this, "anonid", "name");
</field>
<field name= "_uriField" >
document.getAnonymousElementByAttribute(this, "anonid", "uri");
</field>
<field name= "_tagsField" >
document.getAnonymousElementByAttribute(this, "anonid", "tags");
</field>
2009-02-24 22:20:45 -08:00
<property name= "itemId" onget= "return this._itemId" />
<property name= "type" onget= "return this.getAttribute('type');" />
2009-02-24 22:20:45 -08:00
2008-12-15 08:44:27 -08:00
<property name= "name" onget= "return this._nameField.value"
onset="this._nameField.value = val; return val;"/>
2009-02-24 22:20:45 -08:00
<property name= "spec" onget= "return this._uriField.value"
onset="this._uriField.value = val; return val;"/>
2008-12-15 08:44:27 -08:00
<property name= "tags" onget= "return this._tagsField.value"
onset="this._tagsField.value = val; return val;"/>
<property name= "tagsAsArray" readonly= "true" >
<getter >
< ![CDATA[
// we don't require the leading space (after each comma)
var tags = this.tags.split(",");
for (var i = 0; i < tags.length ; i + + ) {
// remove trailing and leading spaces
tags[i] = tags[i].trim();
// remove empty entries from the array.
if (tags[i] == "") {
tags.splice(i, 1);
i--;
}
}
return tags;
]]>
</getter>
</property>
2009-02-24 22:20:45 -08:00
<property name= "isEditing" readonly= "true" onget= "return this._isEditing;" />
<property name= "control" readonly= "true" >
<getter >
< ![CDATA[
2009-02-24 22:20:45 -08:00
if (this._control)
return this._control;
2009-02-24 22:20:45 -08:00
let parent = this.parentNode;
while (parent) {
2009-02-24 22:20:45 -08:00
if (parent.localName == "placelist") {
this._control = parent;
return this._control;
}
2009-02-24 22:20:45 -08:00
parent = parent.parentNode;
}
return null;
]]>
</getter>
</property>
<method name= "init" >
2009-02-24 22:20:45 -08:00
<parameter name= "aItemId" />
2009-02-24 22:20:45 -08:00
<body >
< ![CDATA[
2009-02-24 22:20:45 -08:00
this._itemId = aItemId;
if (!this._itemId)
return;
2009-02-24 22:20:45 -08:00
this.name = PlacesUtils.bookmarks.getItemTitle(this._itemId);
try {
this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
} catch (e) {}
if (this._uri) {
2009-02-24 22:20:45 -08:00
this.spec = this._uri.spec;
2009-02-24 22:20:45 -08:00
let fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
let icon = document.getAnonymousElementByAttribute(this, "anonid", "favicon");
icon.src = fis.getFaviconImageForPage(this._uri).spec;
}
]]>
</body>
</method>
2008-12-15 08:44:27 -08:00
<method name= "startEditing" >
<body >
< ![CDATA[
2009-02-24 22:20:45 -08:00
if (this._itemId == -1)
2008-12-15 08:44:27 -08:00
return;
2009-02-24 22:20:45 -08:00
this._isEditing = true;
if (this.control)
this.control.activeItem = this;
2008-12-15 08:44:27 -08:00
2009-02-24 22:20:45 -08:00
this.updateFields();
if (this._uri) {
var currentTags = PlacesUtils.tagging.getTagsForURI(this._uri, {});
this.tags = currentTags.join(", ");
}
2008-12-15 08:44:27 -08:00
this._nameField.focus();
]]>
</body>
</method>
<method name= "stopEditing" >
<parameter name= "shouldSave" />
<body >
< ![CDATA[
if (shouldSave)
this.save();
2009-02-24 22:20:45 -08:00
this._isEditing = false;
if (this.control)
this.control.activeItem = null;
this.updateFields();
2008-12-15 08:44:27 -08:00
let event = document.createEvent("Events");
event.initEvent("close", true, false);
this.dispatchEvent(event);
]]>
</body>
</method>
<method name= "save" >
<body >
< ![CDATA[
// Update the name
2009-02-24 22:20:45 -08:00
PlacesUtils.bookmarks.setItemTitle(this._itemId, this.name);
2008-12-15 08:44:27 -08:00
// Update the tags
2009-02-24 22:20:45 -08:00
if (this._uri) {
var currentTags = PlacesUtils.tagging.getTagsForURI(this._uri, {});
var tags = this.tagsAsArray;
if (tags.length > 0 || currentTags.length > 0) {
var tagsToRemove = [];
var tagsToAdd = [];
var i;
for (i = 0; i < currentTags.length ; i + + ) {
if (tags.indexOf(currentTags[i]) == -1)
tagsToRemove.push(currentTags[i]);
}
for (i = 0; i < tags.length ; i + + ) {
if (currentTags.indexOf(tags[i]) == -1)
tagsToAdd.push(tags[i]);
}
if (tagsToAdd.length > 0)
PlacesUtils.tagging.tagURI(this._uri, tagsToAdd);
if (tagsToRemove.length > 0)
PlacesUtils.tagging.untagURI(this._uri, tagsToRemove);
2008-12-15 08:44:27 -08:00
}
2009-02-24 22:20:45 -08:00
// If the URI was updated change it in the bookmark
2009-02-24 22:20:45 -08:00
if (this._uri.spec != this.spec) {
2009-02-24 22:20:45 -08:00
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
2009-02-24 22:20:45 -08:00
uri = ios.newURI(this.spec, null, null);
2008-12-15 08:44:27 -08:00
2009-02-24 22:20:45 -08:00
PlacesUtils.bookmarks.changeBookmarkURI(this._itemId, this._uri);
}
2008-12-15 08:44:27 -08:00
}
]]>
</body>
</method>
<method name= "remove" >
<body >
< ![CDATA[
2009-02-24 22:20:45 -08:00
PlacesUtils.bookmarks.removeItem(this._itemId);
2008-12-15 08:44:27 -08:00
// If this was the last bookmark (excluding tag-items and livemark
// children, see getMostRecentBookmarkForURI) for the bookmark's url,
// remove the url from tag containers as well.
2009-02-24 22:20:45 -08:00
if (this._uri) {
if (PlacesUtils.getMostRecentBookmarkForURI(this._uri) == -1) {
var tags = PlacesUtils.tagging.getTagsForURI(this._uri, {});
PlacesUtils.tagging.untagURI(this._uri, tags);
}
2008-12-15 08:44:27 -08:00
}
2009-02-24 22:20:45 -08:00
this.stopEditing(false);
if (this.control)
this.control.removeItem(this);
2008-12-15 08:44:27 -08:00
let event = document.createEvent("Events");
2009-02-24 22:20:45 -08:00
event.initEvent("BookmarkRemove", true, false);
2008-12-15 08:44:27 -08:00
this.dispatchEvent(event);
2009-02-24 22:20:45 -08:00
]]>
</body>
</method>
2009-02-24 22:20:45 -08:00
<method name= "move" >
2009-02-24 22:20:45 -08:00
<body >
< ![CDATA[
if (this.control)
this.control.activeItem = this;
let control = this.control || this;
2009-02-24 22:20:45 -08:00
let code = control.getAttribute("onmove");
2009-02-24 22:20:45 -08:00
if (code) {
let func = new Function(code);
func.call(control);
}
]]>
</body>
</method>
<method name= "updateFields" >
<body >
< ![CDATA[
// implemented by sub classes
]]>
</body>
</method>
</implementation>
</binding>
2008-12-15 08:44:27 -08:00
2009-02-24 22:20:45 -08:00
<binding id= "place-item" extends= "chrome://browser/content/bindings.xml#place-base" >
<content align= "start" >
<xul:image anonid= "favicon" class= "bookmark-item-image" />
<xul:grid flex= "1" >
<xul:columns >
<xul:column flex= "1" />
<xul:column />
</xul:columns>
<xul:rows >
<xul:row align= "center" >
<xul:textbox anonid= "name" readonly= "true" xbl:inherits= "value=name" />
2009-02-24 22:20:45 -08:00
<xul:hbox align= "center" anonid= "edit-controls" class= "bookmark-manage-controls" >
<xul:image anonid= "close-button" class= "close-button"
onmousedown="document.getBindingParent(this).remove()"/>
2009-02-24 22:20:45 -08:00
<xul:button anonid= "folder-button" label= "&editBookmarkMove.label;"
2009-02-24 22:20:45 -08:00
oncommand="document.getBindingParent(this).move()"/>
2009-02-24 22:20:45 -08:00
<xul:button anonid= "edit-button" label= "&editBookmarkEdit.label;"
oncommand="document.getBindingParent(this).startEditing()"/>
<xul:button anonid= "done-button" label= "&editBookmarkDone.label;" hidden= "true"
oncommand="document.getBindingParent(this).stopEditing(true)"/>
</xul:hbox>
</xul:row>
<xul:row anonid= "uri-row" align= "center" hidden= "true" >
<xul:textbox anonid= "uri" xbl:inherits= "value=uri" />
</xul:row>
<xul:row anonid= "tags-row" align= "center" hidden= "true" >
<xul:textbox anonid= "tags" xbl:inherits= "value=tags" emptytext= "&editBookmarkTags.label;" />
</xul:row>
</xul:rows>
</xul:grid>
</content>
<implementation >
<method name= "updateFields" >
<body >
< ![CDATA[
this._nameField.readOnly = !this._isEditing;
document.getAnonymousElementByAttribute(this, "anonid", "edit-button").hidden = this._isEditing;
document.getAnonymousElementByAttribute(this, "anonid", "done-button").hidden = !this._isEditing;
document.getAnonymousElementByAttribute(this, "anonid", "uri-row").hidden = !this._isEditing;
document.getAnonymousElementByAttribute(this, "anonid", "tags-row").hidden = !this._isEditing;
]]>
</body>
</method>
</implementation>
</binding>
<binding id= "place-folder" extends= "chrome://browser/content/bindings.xml#place-base" >
<content align= "center" >
<xul:image anonid= "favicon" class= "bookmark-folder-image" />
<xul:grid flex= "1" >
<xul:columns >
<xul:column flex= "1" />
<xul:column />
</xul:columns>
<xul:rows >
<xul:row align= "center" >
<xul:textbox anonid= "name" readonly= "true" xbl:inherits= "value=name" />
2009-02-24 22:20:45 -08:00
<xul:hbox align= "center" anonid= "edit-controls" class= "bookmark-manage-controls" >
<xul:image anonid= "close-button" class= "close-button"
onmousedown="document.getBindingParent(this).remove()"/>
2009-02-24 22:20:45 -08:00
<xul:button anonid= "folder-button" label= "&editBookmarkMove.label;"
2009-02-24 22:20:45 -08:00
oncommand="document.getBindingParent(this).move()"/>
2009-02-24 22:20:45 -08:00
<xul:button anonid= "edit-button" label= "&editBookmarkEdit.label;"
oncommand="document.getBindingParent(this).startEditing()"/>
<xul:button anonid= "done-button" label= "&editBookmarkDone.label;" hidden= "true"
oncommand="document.getBindingParent(this).stopEditing(true)"/>
</xul:hbox>
</xul:row>
</xul:rows>
</xul:grid>
</content>
<implementation >
<method name= "updateFields" >
<body >
< ![CDATA[
this._nameField.readOnly = !this._isEditing;
document.getAnonymousElementByAttribute(this, "anonid", "edit-button").hidden = this._isEditing;
document.getAnonymousElementByAttribute(this, "anonid", "done-button").hidden = !this._isEditing;
2008-12-15 08:44:27 -08:00
]]>
</body>
</method>
</implementation>
</binding>
2009-02-24 22:20:45 -08:00
<binding id= "place-label" extends= "chrome://browser/content/bindings.xml#place-base" >
<content align= "center" >
<xul:spacer xbl:inherits= "width=indent" />
<xul:image anonid= "favicon" class= "bookmark-folder-image" />
<xul:label anonid= "name" crop= "end" flex= "1" />
</content>
</binding>
<binding id= "place-list" >
<content orient= "vertical" flex= "1" >
<xul:vbox anonid= "parent-items" class= "place-list-parents" >
</xul:vbox>
<xul:richlistbox anonid= "child-items" class= "place-list-children" flex= "1" />
</content>
<implementation >
<constructor >
< ![CDATA[
this._type = this.getAttribute("type");
this._mode = this.getAttribute("mode");
let bs = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
this._bundle = bs.createBundle("chrome://browser/locale/browser.properties");
]]>
</constructor>
<field name= "_bundle" > null</field>
<field name= "_type" />
<field name= "_mode" />
<field name= "_activeItem" > null</field>
<field name= "_ignoreEditing" > false</field>
<field name= "_manageUI" > false</field>
<field name= "_parents" >
document.getAnonymousElementByAttribute(this, "anonid", "parent-items");
</field>
<field name= "_children" >
document.getAnonymousElementByAttribute(this, "anonid", "child-items");
</field>
2009-02-27 11:44:35 -08:00
<property name= "scrollBoxObject" readonly= "true" onget= "return this._children.scrollBoxObject;" />
2009-02-24 22:20:45 -08:00
<property name= "activeItem" >
<getter >
< ![CDATA[
return this._activeItem;
]]>
</getter>
<setter >
< ![CDATA[
if (!this._ignoreEditing) {
if (this._activeItem & & this._activeItem.isEditing) {
this._ignoreEditing = true;
this._activeItem.stopEditing(false);
this._ignoreEditing = false;
}
this._activeItem = val;
}
return val;
]]>
</setter>
</property>
<property name= "manageUI" >
<getter >
< ![CDATA[
return this._manageUI;
]]>
</getter>
<setter >
< ![CDATA[
if (this._manageUI != val) {
this._manageUI = val;
if (this._manageUI) {
this.setAttribute("ui", "manage");
}
else {
if (this._activeItem)
this._activeItem.stopEditing();
this.removeAttribute("ui");
}
}
return val;
]]>
</setter>
</property>
<method name= "_getChildren" >
<parameter name= "aFolder" />
<body >
< ![CDATA[
let items = [];
let options = PlacesUtils.history.getNewQueryOptions();
options.queryType = (this._type == "bookmarks" ? options.QUERY_TYPE_BOOKMARKS : options.QUERY_TYPE_HISTORY);
let query = PlacesUtils.history.getNewQuery();
if (aFolder)
query.setFolders([aFolder], 1);
let result = PlacesUtils.history.executeQuery(query, options);
let rootNode = result.root;
rootNode.containerOpen = true;
let cc = rootNode.childCount;
for (var i=0; i<cc ; + + i ) {
var node = rootNode.getChild(i);
if (this._mode == "folders" & & node.type == node.RESULT_TYPE_FOLDER) {
items.push(node);
}
else if (this._mode == "") {
items.push(node);
}
}
rootNode.containerOpen = false;
return items;
]]>
</body>
</method>
<method name= "openFolder" >
<parameter name= "aRootFolder" />
<body >
< ![CDATA[
aRootFolder = aRootFolder || PlacesUtils.bookmarks.bookmarksMenuFolder;
this._activeItem = null;
let parents = this._parents;
while (parents.firstChild)
parents.removeChild(parents.firstChild);
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var self = this;
let folderId = aRootFolder;
do {
let parent = document.createElementNS(XULNS, "placelabel");
parent.setAttribute("class", "bookmark-folder");
parent.setAttribute("itemid", folderId);
parent.setAttribute("indent", 0);
parents.insertBefore(parent, parents.firstChild);
// XXX Fix me - use <handler > ?
parent.addEventListener("click", function(e) { self.openFolder(e.target.itemId); }, false);
folderId = PlacesUtils.bookmarks.getFolderIdForItem(folderId);
} while (folderId != PlacesUtils.bookmarks.placesRoot)
let children = this._children;
while (children.firstChild)
children.removeChild(children.firstChild);
let childItems = this._getChildren(aRootFolder);
for (let i=0; i<childItems.length ; i + + ) {
let node = childItems[i];
this.appendItem(node.itemId, node.type);
}
// Add the "<new f o l d e r > " item
let newFolder = document.createElementNS(XULNS, "button");
newFolder.setAttribute("class", "bookmark-folder-new");
newFolder.setAttribute("label", this._bundle.GetStringFromName("editBookmarkAddFolder"));
children.appendChild(newFolder);
// XXX Fix me - use <handler > ?
newFolder.addEventListener("click", function(e) { self.addFolder(); }, false);
]]>
</body>
</method>
<method name= "addFolder" >
<body >
< ![CDATA[
let parents = this._parents;
let parent = parents.lastChild;
if ("itemId" in parent) {
let children = this._children;
let newId = PlacesUtils.bookmarks.createFolder(parent.itemId, this._bundle.GetStringFromName("editBookmarkNewFolder"), PlacesUtils.bookmarks.DEFAULT_INDEX);
let child = this.appendItem(newId, Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER, children.lastChild);
child.startEditing();
}
]]>
</body>
</method>
<method name= "appendItem" >
<parameter name= "aItemId" />
<parameter name= "aType" />
<parameter name= "aBefore" />
<body >
< ![CDATA[
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let child = document.createElementNS(XULNS, "placeitem");
child.setAttribute("itemid", aItemId);
child.setAttribute("class", "bookmark-item");
if (aType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER)
child.setAttribute("type", "folder");
this._children.insertBefore(child, aBefore);
// XXX make a <handler > for the mousedown
var self = this;
child.addEventListener("mouseup", function(e) { self._fireOpen(e, child); }, false);
return child;
]]>
</body>
</method>
<method name= "removeItem" >
<parameter name= "aItem" />
<body >
< ![CDATA[
this._children.removeChild(aItem);
]]>
</body>
</method>
<method name= "_fireOpen" >
<parameter name= "aEvent" />
<parameter name= "aItem" />
<body >
< ![CDATA[
if (aEvent.target.isEditing || aEvent.originalTarget.localName == "button")
return;
if (aItem.type == "folder") {
this.openFolder(aItem.itemId);
}
else {
// Force the item to be active
this._activeItem = aItem;
// This is a callback used to forward information to some
// external code [we fire an event & a pseudo attribute event]
let event = document.createEvent("Events");
event.initEvent("BookmarkOpen", true, false);
this.dispatchEvent(event);
let func = new Function("event", this.getAttribute("onopen"));
func.call(this, event);
}
]]>
</body>
</method>
</implementation>
</binding>
<binding id= "place-tree" >
<content orient= "vertical" flex= "1" >
<xul:richlistbox anonid= "items" class= "place-tree-items" flex= "1" />
</content>
<implementation >
<constructor >
< ![CDATA[
this._type = this.getAttribute("type");
this._mode = this.getAttribute("mode");
]]>
</constructor>
<field name= "_type" />
<field name= "_mode" />
<field name= "_items" >
document.getAnonymousElementByAttribute(this, "anonid", "items");
</field>
2009-02-27 11:44:35 -08:00
<property name= "scrollBoxObject" readonly= "true" onget= "return this._items.scrollBoxObject;" />
2009-02-24 22:20:45 -08:00
<property name= "selectedItem" readonly= "true" >
<getter >
< ![CDATA[
return this._items.selectedItem;
]]>
</getter>
</property>
<method name= "_getChildren" >
<parameter name= "aFolder" />
<body >
< ![CDATA[
let items = [];
let options = PlacesUtils.history.getNewQueryOptions();
options.queryType = (this._type == "bookmarks" ? options.QUERY_TYPE_BOOKMARKS : options.QUERY_TYPE_HISTORY);
let query = PlacesUtils.history.getNewQuery();
if (aFolder)
query.setFolders([aFolder], 1);
let result = PlacesUtils.history.executeQuery(query, options);
let rootNode = result.root;
rootNode.containerOpen = true;
let cc = rootNode.childCount;
for (var i=0; i<cc ; + + i ) {
var node = rootNode.getChild(i);
if (this._mode == "folders" & & node.type == node.RESULT_TYPE_FOLDER) {
items.push(node);
}
else if (this._mode == "") {
items.push(node);
}
}
rootNode.containerOpen = false;
return items;
]]>
</body>
</method>
<method name= "openFolder" >
<parameter name= "aRootFolder" />
<parameter name= "aLevel" />
<body >
< ![CDATA[
aRootFolder = aRootFolder || PlacesUtils.bookmarks.bookmarksMenuFolder;
aLevel = aLevel || 0;
let items = this._items;
if (!aLevel) {
while (items.firstChild)
items.removeChild(items.firstChild);
2009-02-24 22:20:45 -08:00
this.appendItem(aRootFolder, Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER, aLevel);
aLevel += 24;
2009-02-24 22:20:45 -08:00
}
let childItems = this._getChildren(aRootFolder);
for (let i=0; i<childItems.length ; i + + ) {
let node = childItems[i];
let child = this.appendItem(node.itemId, node.type, aLevel);
this.openFolder(node.itemId, aLevel + 24);
}
]]>
</body>
</method>
<method name= "appendItem" >
<parameter name= "aItemId" />
<parameter name= "aType" />
<parameter name= "aLevel" />
<body >
< ![CDATA[
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let child = document.createElementNS(XULNS, "placelabel");
child.setAttribute("type", "folder");
child.setAttribute("itemid", aItemId);
child.setAttribute("indent", aLevel);
this._items.appendChild(child);
// XXX make a <handler > for the mouseup
var self = this;
2009-02-24 22:20:45 -08:00
child.addEventListener("mouseup", function(e) { self._fireSelect(e, child); }, false);
2009-02-24 22:20:45 -08:00
return child;
]]>
</body>
</method>
2009-02-24 22:20:45 -08:00
<method name= "_fireSelect" >
2009-02-24 22:20:45 -08:00
<parameter name= "aEvent" />
<parameter name= "aItem" />
<body >
< ![CDATA[
// Force the item to be selected
this._items.selectedItem = aItem;
2009-02-24 22:20:45 -08:00
// the richlistbox will fire an onselect event, which will bubble to
// the placetree onselect handler. We don't need to explicitly fire
// anything here.
2009-02-24 22:20:45 -08:00
]]>
</body>
</method>
</implementation>
</binding>
2008-07-16 08:41:38 -07:00
</bindings>