|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 const { resolveURI, Require, |
|
8 unload, override, descriptor } = require('../../toolkit/loader'); |
|
9 const { ensure } = require('../system/unload'); |
|
10 const addonWindow = require('../addon/window'); |
|
11 const { PlainTextConsole } = require('sdk/console/plain-text'); |
|
12 |
|
13 let defaultGlobals = override(require('../system/globals'), { |
|
14 console: console |
|
15 }); |
|
16 |
|
17 function CustomLoader(module, globals, packaging, overrides={}) { |
|
18 let options = packaging || require("@loader/options"); |
|
19 options = override(options, { |
|
20 id: overrides.id || options.id, |
|
21 globals: override(defaultGlobals, globals || {}), |
|
22 modules: override(options.modules || {}, { |
|
23 'sdk/addon/window': addonWindow |
|
24 }) |
|
25 }); |
|
26 |
|
27 let loaderModule = options.isNative ? '../../toolkit/loader' : '../loader/cuddlefish'; |
|
28 let { Loader } = require(loaderModule); |
|
29 let loader = Loader(options); |
|
30 let wrapper = Object.create(loader, descriptor({ |
|
31 require: Require(loader, module), |
|
32 sandbox: function(id) { |
|
33 let requirement = loader.resolve(id, module.id); |
|
34 let uri = resolveURI(requirement, loader.mapping); |
|
35 return loader.sandboxes[uri]; |
|
36 }, |
|
37 unload: function(reason) { |
|
38 unload(loader, reason); |
|
39 } |
|
40 })); |
|
41 ensure(wrapper); |
|
42 return wrapper; |
|
43 }; |
|
44 exports.Loader = CustomLoader; |
|
45 |
|
46 function HookedPlainTextConsole(hook, print, innerID) { |
|
47 this.log = hook.bind(null, "log", innerID); |
|
48 this.info = hook.bind(null, "info", innerID); |
|
49 this.warn = hook.bind(null, "warn", innerID); |
|
50 this.error = hook.bind(null, "error", innerID); |
|
51 this.debug = hook.bind(null, "debug", innerID); |
|
52 this.exception = hook.bind(null, "exception", innerID); |
|
53 this.time = hook.bind(null, "time", innerID); |
|
54 this.timeEnd = hook.bind(null, "timeEnd", innerID); |
|
55 |
|
56 this.__exposedProps__ = { |
|
57 log: "rw", info: "rw", warn: "rw", error: "rw", debug: "rw", |
|
58 exception: "rw", time: "rw", timeEnd: "rw" |
|
59 }; |
|
60 } |
|
61 |
|
62 // Creates a custom loader instance whose console module is hooked in order |
|
63 // to avoid printing messages to the console, and instead, expose them in the |
|
64 // returned `messages` array attribute |
|
65 exports.LoaderWithHookedConsole = function (module, callback) { |
|
66 let messages = []; |
|
67 function hook(type, innerID, msg) { |
|
68 messages.push({ type: type, msg: msg, innerID: innerID }); |
|
69 if (callback) |
|
70 callback(type, msg, innerID); |
|
71 } |
|
72 |
|
73 return { |
|
74 loader: CustomLoader(module, { |
|
75 console: new HookedPlainTextConsole(hook, null, null) |
|
76 }, override(require("@loader/options"), { |
|
77 modules: { |
|
78 'sdk/console/plain-text': { |
|
79 PlainTextConsole: HookedPlainTextConsole.bind(null, hook) |
|
80 } |
|
81 } |
|
82 })), |
|
83 messages: messages |
|
84 }; |
|
85 } |
|
86 |
|
87 // Same than LoaderWithHookedConsole with lower level, instead we get what is |
|
88 // actually printed to the command line console |
|
89 exports.LoaderWithHookedConsole2 = function (module, callback) { |
|
90 let messages = []; |
|
91 return { |
|
92 loader: CustomLoader(module, { |
|
93 console: new PlainTextConsole(function (msg) { |
|
94 messages.push(msg); |
|
95 if (callback) |
|
96 callback(msg); |
|
97 }) |
|
98 }), |
|
99 messages: messages |
|
100 }; |
|
101 } |
|
102 |
|
103 // Creates a custom loader with a filtered console. The callback is passed every |
|
104 // console message type and message and if it returns false the message will |
|
105 // not be logged normally |
|
106 exports.LoaderWithFilteredConsole = function (module, callback) { |
|
107 function hook(type, innerID, msg) { |
|
108 if (callback && callback(type, msg, innerID) == false) |
|
109 return; |
|
110 console[type](msg); |
|
111 } |
|
112 |
|
113 return CustomLoader(module, { |
|
114 console: new HookedPlainTextConsole(hook, null, null) |
|
115 }, override(require("@loader/options"), { |
|
116 modules: { |
|
117 'sdk/console/plain-text': { |
|
118 PlainTextConsole: HookedPlainTextConsole.bind(null, hook) |
|
119 } |
|
120 } |
|
121 })); |
|
122 } |