/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /** One of the goals of JsAccount is to be able to incrementally extend a base implementation, possibly adding a new interface. This code demonstrates a mailnews URL extended for a hypthetical account type "foo". */ const { JSAccountUtils } = ChromeUtils.import( "resource:///modules/jsaccount/JSAccountUtils.jsm" ); const { JaBaseUrl, JaBaseUrlProperties } = ChromeUtils.import( "resource:///modules/jsaccount/JaBaseUrl.jsm" ); const ATTACHMENT_QUERY = "part=1."; var FooUrlProperties = { // Extend the base properties. __proto__: JaBaseUrlProperties, contractID: "@mozilla.org/jsaccount/testjafoourl;1", classID: Components.ID("{73F98539-A59F-4F6F-9A72-D83A08646C23}"), // Add an additional interface only needed by this custom class. extraInterfaces: [Ci.msgIFooUrl], }; // Constructor var xpcomFactory = JSAccountUtils.jaFactory(FooUrlProperties, FooUrl); // Main class. function FooUrl(aDelegator, aBaseInterfaces) { // Superclass constructor JaBaseUrl.call(this, aDelegator, aBaseInterfaces); // I'm not sure why I have to call this again, as it is called in the // base constructor, but without it this method will not find the // interfaces beyond nsISupports. aBaseInterfaces.forEach(iface => this.cppBase instanceof iface); // instance variables this._urlType = -1; // unknown; this._itemId = null; this._hidden = "IAmHidden"; } // Extend the base class methods. FooUrl.prototype = { // Typical boilerplate to include in all implementations. // Extended the JS URL object. __proto__: JaBaseUrl.prototype, // Delegate these methods to CPP. _JsPrototypeToDelegate: true, // InterfaceRequestor override, needed if extraInterfaces. getInterface(iid) { for (let iface of FooUrlProperties.extraInterfaces) { if (iid.equals(iface)) { return this; } } return this.delegator.QueryInterface(iid); }, // msgIFooUrl implementation // Foo id for item. // attribute AString itemId; get itemId() { return this._itemId; }, set itemId(aVal) { this._itemId = aVal; }, // Does this url refer to an attachment? // readonly attribute boolean isAttachment; get isAttachment() { // We look to see if the URL has an attachment query let query = this.QueryInterface(Ci.nsIURL).query; return query && query.includes(ATTACHMENT_QUERY); }, };