removed one error message
[k8imago.git] / code / modules / utils.js
blob2603226b5917d3be0b1eda8a6d49a3bdd50484bf
1 /* coded by Ketmar // Invisible Vector (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://www.wtfpl.net/txt/copying/ for more details.
9 */
10 // utility functions
11 let EXPORTED_SYMBOLS = [
12 "MODULE_PATH",
14 "getDomWindowForChannel",
15 "getBrowserForDomWindow",
16 "createInputStreamFromString",
17 "url2uri",
18 "cssEscape",
19 "oneShotTimer",
20 "intervalTimer",
22 "setupGBrowser",
23 "registerWindowHook",
24 "imagoCallWindowHook",
26 "getRulesIFile",
27 "getFileTextContents"
30 const {utils:Cu, classes:Cc, interfaces:Ci, results:Cr} = Components;
33 //////////////////////////////////////////////////////////////////////////////
34 const MODULE_PATH = "chrome://k8-imago-code/content/modules/";
37 //////////////////////////////////////////////////////////////////////////////
38 let gBrowser = null;
41 function setupGBrowser (gb) {
42 gBrowser = gb;
46 //////////////////////////////////////////////////////////////////////////////
47 // window hooks
48 // string name (key)
49 // array hooks (value)
50 let winhooks = {};
52 function registerWindowHook (name, cb) {
53 if (typeof(name) !== "string" || !name) throw new Error("string hook name expected");
54 if (typeof(cb) !== "function") throw new Error("function hook callback expected");
55 if (name !== "load" && name !== "unload") throw new Error("invalid window hook: '"+name+"'");
56 let arr = winhooks[name];
57 if (arr === undefined) {
58 arr = [];
59 winhooks[name] = arr;
61 for (let h of arr) if (h === cb) return;
62 arr.push(cb);
66 function imagoCallWindowHook (name, win) {
67 //win.setTimeout(function() conlog("****", Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).name), 3000); // "Pale Moon"
68 if (typeof(name) !== "string" || !name) return;
69 let arr = winhooks[name];
70 if (arr !== undefined) {
71 for (let h of arr) {
72 try {
73 h(win, name);
74 } catch (e) {
75 Component.utils.reportError(e);
82 //////////////////////////////////////////////////////////////////////////////
83 const iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
86 //////////////////////////////////////////////////////////////////////////////
87 // null or dom window
88 function getDomWindowForChannel (chan) {
89 try {
90 let notifyCBs = null;
91 if (chan.notificationCallbacks) {
92 notifyCBs = chan.notificationCallbacks;
93 } else if (chan.loadGroup) {
94 notifyCBs = chan.loadGroup.notifyCBs;
96 return (notifyCBs ? notifyCBs.getInterface(Ci.nsIDOMWindow) : null);
97 } catch (e) {
98 //userChrome.logError(e);
99 return null;
104 function getBrowserForDomWindow (dw) {
105 if (!dw) return null;
106 if (!gBrowser) return null;
107 if (typeof(gBrowser.getBrowserForDocument) !== "function") return null;
108 return gBrowser.getBrowserForDocument(dw.top.document);
112 //////////////////////////////////////////////////////////////////////////////
113 function createInputStreamFromString (data) {
114 if (typeof(data) !== "string") data = "";
115 let ost = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
116 let sst = Cc["@mozilla.org/storagestream;1"].createInstance(Ci.nsIStorageStream);
117 sst.init(8192, data.length, null); // default allocator
118 ost.setOutputStream(sst.getOutputStream(0));
119 ost.writeBytes(data, data.length);
120 return sst.newInputStream(0);
124 //////////////////////////////////////////////////////////////////////////////
125 function url2uri (url) {
126 return iosvc.newURI(url, null, null);
130 function cssEscape (s) s.replace(/([\]\[(){}"'`#.\/\\])/g, "\\$1"); //"
133 //////////////////////////////////////////////////////////////////////////////
134 // returns timer object
135 function createTimer (aCallback, aDelay, oneshot) {
136 // create the timer object
137 let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
138 // The timer object may be garbage collected before it fires, so we need to
139 // keep a reference to it alive (https://bugzil.la/647998).
140 // However, simply creating a closure over the timer object without using it
141 // may not be enough, as the timer might get optimized out of the closure
142 // scope (https://bugzil.la/640629#c9). To work around this, the timer object
143 // is explicitly stored as a property of the observer.
144 let fired = false;
145 var observer = {
146 observe: function () {
147 fired = true;
148 // just-in-case check
149 if (observer.timer && oneshot) delete observer.timer;
150 aCallback();
152 timer: timer,
154 timer.init(observer, aDelay, (oneshot ? Ci.nsITimer.TYPE_ONE_SHOT : Ci.nsITimer.TYPE_REPEATING_SLACK));
155 return {
156 get active () !fired,
157 get callback () aCallback,
158 get oneShot () !!oneShot,
159 get interval () aDelay,
160 cancel: function () {
161 if (observer.timer) {
162 observer.timer.cancel();
163 delete observer.timer;
169 function oneShotTimer (aCallback, aDelay) createTimer(aCallback, aDelay, true);
170 function intervalTimer (aCallback, aDelay) createTimer(aCallback, aDelay, false);
173 //////////////////////////////////////////////////////////////////////////////
174 function getRulesIFile () {
175 let pd = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
176 pd.append("k8imago");
177 pd.append("rules.rc");
178 return pd;
182 //////////////////////////////////////////////////////////////////////////////
183 function getFileTextContents (file) {
184 let encoding = "UTF-8";
185 function toUnicode (text) {
186 if (typeof(text) === "string") {
187 if (text.length == 0) return "";
188 } else if (text instanceof ArrayBuffer) {
189 if (text.byteLength == 0) return "";
190 text = new Uint8Array(text);
191 return new TextDecoder(encoding).decode(text);
192 } else if ((text instanceof Uint8Array) || (text instanceof Int8Array)) {
193 if (text.length == 0) return "";
194 return new TextDecoder(encoding).decode(text);
195 } else {
196 return "";
198 let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
199 converter.charset = encoding;
200 let res = converter.ConvertToUnicode(text);
201 if (res.length >= 3 && res.substr(0, 3) == "\u00EF\u00BB\u00BF") res = res.substr(3); // fuck BOM
202 return res;
205 //debuglog("file=[", file.path, "]");
206 // read file
207 let inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
208 inputStream.init(file, -1, -1, null);
209 let scInputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
210 scInputStream.init(inputStream);
211 let output = scInputStream.read(-1);
212 scInputStream.close();
213 inputStream.close();
214 return toUnicode(output, encoding);