Bug 883203 On OS X, run all plugins OOP by default when in 32-bit mode (i386/x86) f=Stefanh r=IanN a+comm-beta=IanN.
a=Callek for checkin to a CLOSED TREE
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="addrbookBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="addrbooks-menupopup"
extends="chrome://global/content/bindings/popup.xml#popup">
<implementation implements="nsIAbListener">
<!-- A cache of nsIAbDirectory objects. -->
<field name="_directories">[]</field>
<!-- Represents the nsIAbDirectory attribute used as the value of the
parent menulist. Defaults to URI but can be e.g. dirPrefId -->
<field name="_value">this.getAttribute("value") || "URI"</field>
<constructor>
<![CDATA[
Components.utils.import("resource:///modules/mailServices.js");
// Init the address book cache.
const nsIAbDirectory = Components.interfaces.nsIAbDirectory;
let directories = MailServices.ab.directories;
while (directories && directories.hasMoreElements()) {
var ab = directories.getNext();
if (ab instanceof nsIAbDirectory && this._matches(ab))
this._directories.push(ab);
}
this._directories.sort(this._compare);
// Now create menuitems for all displayed directories.
var menulist = this.parentNode;
var value = this._value;
this._directories.forEach(function (ab) {
menulist.appendItem(ab.dirName, ab[value]);
});
if (this.hasAttribute("none")) {
// Create a dummy menuitem representing no selection.
this._directories.unshift(null);
menulist.insertItemAt(0, this.getAttribute("none"), "");
}
// Attempt to select the persisted or otherwise first directory.
menulist.value = menulist.value;
if (!menulist.selectedItem && this.hasChildNodes())
menulist.selectedIndex = 0;
const nsIAbListener = Components.interfaces.nsIAbListener;
// Add a listener so we can update correctly if the list should change
MailServices.ab.addAddressBookListener(this,
nsIAbListener.itemAdded |
nsIAbListener.directoryRemoved |
nsIAbListener.itemChanged);
]]>
</constructor>
<destructor>
<![CDATA[
Components.utils.import("resource:///modules/mailServices.js");
MailServices.ab.removeAddressBookListener(this);
// Empty out anything in the list.
while (this.hasChildNodes())
this.removeChild(this.lastChild);
]]>
</destructor>
<!-- nsIAbListener methods -->
<method name="onItemAdded">
<parameter name="aParentDir"/>
<parameter name="aItem"/>
<body><![CDATA[
// Are we interested in this new directory?
if (aItem instanceof Components.interfaces.nsIAbDirectory &&
!aItem.isMailList && this._matches(aItem)) {
this._directories.push(aItem);
this._directories.sort(this._compare);
// Insert the new menuitem at the position to which it was sorted.
this.parentNode.insertItemAt(this._directories.indexOf(aItem),
aItem.dirName, aItem[this._value]);
}
]]></body>
</method>
<method name="onItemRemoved">
<parameter name="aParentDir"/>
<parameter name="aItem"/>
<body><![CDATA[
if (aItem instanceof Components.interfaces.nsIAbDirectory &&
!aItem.isMailList) {
// Find the item in the list to remove
// We can't use indexOf here because we need loose equality
for (var index = this._directories.length; --index >= 0; )
if (this._directories[index] == aItem)
break;
if (index != -1)
// Are we removing the selected directory?
if (this.parentNode.selectedItem ==
this.removeChild(this.childNodes[index]))
// If so, try to select the first directory, if available.
if (this.hasChildNodes())
this.firstChild.doCommand();
else
this.parentNode.selectedItem = null;
}
]]></body>
</method>
<method name="onItemPropertyChanged">
<parameter name="aItem"/>
<parameter name="aProperty"/>
<parameter name="aOldValue"/>
<parameter name="aNewValue"/>
<body><![CDATA[
if (aItem instanceof Components.interfaces.nsIAbDirectory &&
!aItem.isMailList) {
// Find the item in the list to rename.
// We can't use indexOf here because we need loose equality
for (var oldIndex = this._directories.length; --oldIndex >= 0; )
if (this._directories[oldIndex] == aItem)
break;
if (oldIndex != -1) {
// Cache the matching item so that we can use indexOf next time.
aItem = this._directories[oldIndex];
var child = this.childNodes[oldIndex];
child.label = aItem.dirName;
this._directories.sort(this._compare);
// Reorder the menuitems if renaming changed the directory index.
var newIndex = this._directories.indexOf(aItem);
if (newIndex < oldIndex)
this.insertBefore(child, this.childNodes[newIndex]);
else if (newIndex > oldIndex)
this.insertBefore(child, this.childNodes[newIndex].nextSibling);
}
}
]]></body>
</method>
<!-- Private methods -->
<!-- Tests to see whether this directory should display in the list. -->
<method name="_matches">
<parameter name="ab"/>
<body><![CDATA[
// This condition is used for instance when creating cards
if (this.getAttribute("writable") == "true" && ab.readOnly)
return false;
// This condition is used for instance when creating mailing lists
if (this.getAttribute("supportsmaillists") == "true" &&
!ab.supportsMailingLists)
return false;
return this.getAttribute(ab.isRemote ? "localonly" : "remoteonly") != "true";
]]></body>
</method>
<!-- Used to sort directories in order -->
<method name="_compare">
<parameter name="a"/>
<parameter name="b"/>
<body><![CDATA[
// Null at the very top.
if (!a)
return -1;
if (!b)
return 1;
// Personal at the top.
const kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab";
if (a.URI == kPersonalAddressbookURI)
return -1;
if (b.URI == kPersonalAddressbookURI)
return 1;
// Collected at the bottom.
const kCollectedAddressbookURI = "moz-abmdbdirectory://history.mab";
if (a.URI == kCollectedAddressbookURI)
return 1;
if (b.URI == kCollectedAddressbookURI)
return -1;
// Sort books of the same type by name.
if (a.dirType == b.dirType)
return a.dirName.localeCompare(b.dirName);
// If one of the dirTypes is PAB and the other is something else,
// then the other will go below the one of type PAB.
const PABDirectory = 2;
if (a.dirType == PABDirectory)
return -1;
if (b.dirType == PABDirectory)
return 1;
// Sort anything else by the dir type.
return a.dirType - b.dirType;
]]></body>
</method>
</implementation>
</binding>
</bindings>