1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
/* 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);
},
};
|