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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/* 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/. */
"use strict";
const {Cc,Ci,Cm,Cr,Cu} = require("chrome");
var jsm = {};
Cu.import("resource://gre/modules/XPCOMUtils.jsm", jsm);
var utils = exports.utils = jsm.XPCOMUtils;
Cm.QueryInterface(Ci.nsIComponentRegistrar);
var factories = [];
function Factory(options) {
memory.track(this);
this.wrappedJSObject = this;
this.create = options.create;
this.uuid = options.uuid;
this.name = options.name;
this.contractID = options.contractID;
Cm.registerFactory(this.uuid,
this.name,
this.contractID,
this);
var self = this;
factories.push(this);
}
Factory.prototype = {
createInstance: function(outer, iid) {
try {
if (outer)
throw Cr.NS_ERROR_NO_AGGREGATION;
return (new this.create()).QueryInterface(iid);
} catch (e) {
console.exception(e);
if (e instanceof Ci.nsIException)
throw e;
else
throw Cr.NS_ERROR_FAILURE;
}
},
unregister: function() {
var index = factories.indexOf(this);
if (index == -1)
throw new Error("factory already unregistered");
var self = this;
factories.splice(index, 1);
Cm.unregisterFactory(this.uuid, this);
},
QueryInterface: utils.generateQI([Ci.nsIFactory])
};
var makeUuid = exports.makeUuid = function makeUuid() {
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
var uuid = uuidGenerator.generateUUID();
return uuid;
};
var autoRegister = exports.autoRegister = function autoRegister(path) {
// TODO: This assumes that the url points to a directory
// that contains subdirectories corresponding to OS/ABI and then
// further subdirectories corresponding to Gecko platform version.
// we should probably either behave intelligently here or allow
// the caller to pass-in more options if e.g. there aren't
// Gecko-specific binaries for a component (which will be the case
// if only frozen interfaces are used).
var runtime = require("./runtime");
var osDirName = runtime.OS + "_" + runtime.XPCOMABI;
var platformVersion = require("./xul-app").platformVersion.substring(0, 5);
var file = Cc['@mozilla.org/file/local;1']
.createInstance(Ci.nsILocalFile);
file.initWithPath(path);
file.append(osDirName);
file.append(platformVersion);
if (!(file.exists() && file.isDirectory()))
throw new Error("component not available for OS/ABI " +
osDirName + " and platform " + platformVersion);
Cm.QueryInterface(Ci.nsIComponentRegistrar);
Cm.autoRegister(file);
};
var register = exports.register = function register(options) {
options = {__proto__: options};
if (!options.uuid)
options.uuid = makeUuid();
return new Factory(options);
};
var getClass = exports.getClass = function getClass(contractID, iid) {
if (!iid)
iid = Ci.nsISupports;
return Cm.getClassObjectByContractID(contractID, iid);
};
require("./unload").when(
function() {
var copy = factories.slice();
copy.reverse();
copy.forEach(function(factory) { factory.unregister(); });
});
|