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.
10 ////////////////////////////////////////////////////////////////////////////////
11 uses("resource://gre/modules/devtools/gcli.jsm");
13 let {oneShotTimer
, intervalTimer
} = require("utils/timer");
16 ////////////////////////////////////////////////////////////////////////////////
17 let editList
= {lmod
:-1};
21 function getEditList () {
22 let cur
= scacheAPI
.getScriptsForEdit();
23 if (cur
.lmod
!= editList
.lmod
) {
24 editList
= {lmod
:cur
.lmod
, list
:cur
.list
};
25 editNames
= new Array();
26 for (let xnfo
of editList
.list
) editNames
.push({name
:xnfo
.name
, value
:xnfo
.path
});
32 ////////////////////////////////////////////////////////////////////////////////
33 let pkgList
= {lmod
:-1};
37 function getPkgList () {
38 let cur
= pkgman
.getPackageList();
39 //conlog("getPkgList: pkgList.lmod=", pkgList.lmod, "; cur.lmod=", cur.lmod);
40 if (cur
.lmod
!= pkgList
.lmod
) {
41 pkgList
= {lmod
:cur
.lmod
, list
:cur
.list
};
42 pkgNames
= new Array();
43 for (let pi
of pkgList
.list
) pkgNames
.push({name
:pi
.name
, value
:pi
});
49 ////////////////////////////////////////////////////////////////////////////////
50 function addjsext (fn
) {
51 if (!/\.js$/.test(fn
)) fn
+= ".js";
56 ////////////////////////////////////////////////////////////////////////////////
57 function openEditor (fname
, chromeWin
, newfile
) {
58 let fl
= Cc
["@mozilla.org/file/local;1"].createInstance(Ci
.nsIFile
);
59 fl
.followLinks
= true;
60 fl
.initWithPath(fname
);
63 if (fl
.isDirectory()) return;
64 lmtime
= fl
.lastModifiedTime
;
70 text
= fileReadText(fl
);
74 logError("can't read file: "+fname
);
78 "// ==UserScript==\n"+
83 "// @run-at document-end\n"+
88 "// ==/UserScript==\n\n";
90 let spw
= chromeWin
.Scratchpad
.ScratchpadManager
.openScratchpad({
95 // TODO: how can i observe file changes without timer?
96 let wasChange
= false;
97 let checkFC = function () {
98 let fl
= Cc
["@mozilla.org/file/local;1"].createInstance(Ci
.nsIFile
);
99 fl
.followLinks
= true;
100 fl
.initWithPath(fname
);
101 if (fl
.exists() && !fl
.isDirectory() && lmtime
!= fl
.lastModifiedTime
) {
102 lmtime
= fl
.lastModifiedTime
;
107 let tm
= intervalTimer(function () {
108 if (checkFC()) { scacheAPI
.reset(); wasChange
= true; }
110 // kill timer on closing
111 spw
.addEventListener("close", function sploaded() {
112 spw
.removeEventListener("close", sploaded
, false);
115 if (wasChange
|| checkFC()) {
117 scacheAPI
.validate();
118 latestUC
= scacheAPI
.getUC();
124 ////////////////////////////////////////////////////////////////////////////////
125 let gcliCommandSpecs
= [
128 description
: "GuerillaJS control",
132 name
: "guerilla about",
133 description
: "show various info",
137 description
: "info to show",
138 type
: { name
: "selection", data
: ["readme", "credits", "thanks", "licenses"] },
139 defaultValue
: "readme",
142 exec: function (args
, context
) {
143 let bro
= context
.environment
.chromeWindow
.gBrowser
;
146 case "credits": list
= "CREDITS.txt"; break;
147 case "thanks": list
= "THANKS.txt"; break;
148 case "licenses": list
= ["LICENSE.bsd.txt", "LICENSE.mit.txt", "LICENSE.mpl.txt", "LICENSE.wtfpl.txt"]; break;
149 default: list
= "README.txt"; break;
151 if (typeof(list
) == "string") {
152 bro
.selectedTab
= bro
.addTab(gsdoxURL
+list
);
154 for (let name
of list
) bro
.selectedTab
= bro
.addTab(gsdoxURL
+name
);
160 name
: "guerilla reset",
161 description
: "reset all internal caches",
162 exec: function (args
, context
) {
163 //conlog("clearing guerilla caches...");
169 name
: "guerilla debug",
170 description
: "switch debug mode on/off",
174 description
: "action to perform",
175 type
: { name
: "selection", data
: ["show", "tan", "ona", "toggle"] },
176 defaultValue
: "show",
179 returnValue
: "string",
180 exec: function (args
, context
) {
182 case "tan": guerillaOptions
.debugMode
= true; break;
183 case "ona": guerillaOptions
.debugMode
= false; break;
184 case "toggle": guerillaOptions
.debugMode
= !guerillaOptions
.debugMode
; break;
186 return "guerilla debug mode is "+(guerillaOptions
.debugMode
? "on" : "off");
191 name
: "guerilla log",
192 description
: "switch logging on/off",
196 description
: "action to perform",
197 type
: { name
: "selection", data
: ["show", "tan", "ona", "toggle"] },
198 defaultValue
: "show",
201 returnValue
: "string",
202 exec: function (args
, context
) {
204 case "tan": guerillaOptions
.logEnabled
= true; break;
205 case "ona": guerillaOptions
.logEnabled
= false; break;
206 case "toggle": guerillaOptions
.logEnabled
= !guerillaOptions
.logEnabled
; break;
208 return "guerilla logging is "+(guerillaOptions
.logEnabled
? "on" : "off");
213 name
: "guerilla state",
214 description
: "switch guerilla state",
218 description
: "action to perform",
219 type
: { name
: "selection", data
: ["show", "active", "inactive", "toggle"] },
220 defaultValue
: "show",
223 returnValue
: "string",
224 exec: function (args
, context
) {
226 case "active": guerillaOptions
.active
= true; break;
227 case "inactive": guerillaOptions
.active
= false; break;
228 case "toggle": guerillaOptions
.active
= !guerillaOptions
.active
; break;
230 return "guerilla is "+(guerillaOptions
.active
? "" : "in")+"active";
235 name
: "guerilla activate",
236 description
: "activate guerilla",
237 returnValue
: "string",
238 exec: function (args
, context
) {
239 guerillaOptions
.active
= true;
240 return "guerilla is active";
245 name
: "guerilla deactivate",
246 description
: "deactivate guerilla",
247 returnValue
: "string",
248 exec: function (args
, context
) {
249 guerillaOptions
.active
= false;
250 return "guerilla is inactive";
255 name
: "guerilla new",
256 description
: "create new userscript",
260 description
: "new script name",
264 exec: function (args
, context
) {
265 let fname
= args
.filename
;
266 let mt
= fname
.match(/^\/?libs\/([^\/]+)$/);
267 if (mt
) fname
= mt
[1];
268 if (fname
.length
== 0 || fname
.indexOf("/") >= 0) return;
269 fname
= addjsext(fname
);
273 dir
= getUserLibDir();
276 //if (args.filename.length == 0 || args.filename.indexOf("/") >= 0) { alert("invalid file name: "+args.filename); return; }
277 dir
= getUserJSDir();
280 conlog("trying to edit '"+dir
.path
+"'");
281 openEditor(dir
.path
, context
.environment
.chromeDocument
.defaultView
, true);
286 name
: "guerilla edit",
287 description
: "edit guerilla script",
288 //returnValue: "string",
292 description
: "script name to edit",
296 lookup: function (context
) getEditList(),
300 exec: function (args
, context
) {
301 if (args
.filename
) openEditor(args
.filename
, context
.environment
.chromeDocument
.defaultView
);
306 name
: "guerilla package",
307 description
: "GuerillaJS package control",
310 name
: "guerilla package abort",
311 description
: "abort all operations",
312 exec: function (args
, context
) { pkgman
.cancel(); },
315 name
: "guerilla package list",
316 description
: "list installed packages",
317 returnValue
: "string",
326 exec: function (args
, context
) {
327 let mask
= args
.mask
||"*";
328 let re
= wild2re(mask
);
329 let res
= "=== package list ===";
331 for (let pi
of pkgDB
.getActivePackages()) {
332 if (re
.test(pi
.name
)) {
334 if (pi
.version
) res
+= "\t"+pi
.version
;
338 //return (count ? res : "no packages found");
339 //TODO: special output
340 logError(count
? res
: "no packages found");
341 return "find result in error console";
345 name
: "guerilla package update",
346 description
: "update package(s)",
355 exec: function (args
, context
) {
356 if (!args
.mask
) return;
357 let mask
= args
.mask
||"*";
358 let re
= wild2re(mask
);
359 for (let pi
of pkgDB
.getActivePackages()) {
360 if (re
.test(pi
.name
)) {
362 pkgman
.update(pi
.name
);
364 logError("ERROR: ", e
.message
);
371 name
: "guerilla package install",
372 description
: "install package",
376 description
: "package name",
381 description
: "package install url",
385 exec: function (args
, context
) {
386 if (!args
.name
|| !args
.url
) return;
388 pkgman
.install(args
.name
, args
.url
);
390 logError("ERROR: ", e
.message
);
395 name
: "guerilla package remove",
396 description
: "remove package",
400 description
: "package name",
404 lookup: function (context
) getPkgList(),
408 exec: function (args
, context
) {
409 //if (!args.name.name) return;
411 pkgman
.remove(args
.name
.name
);
413 logError("ERROR: ", e
.message
);
419 name
: "guerilla wtf",
424 description
: "file name",
429 exec: function (args
, context
) {
430 if (!args
.filename
) return;
432 let h
= calcFileSha512(args
.filename
);
433 logError("h="+h
+"; "+args
.filename
);
435 logError("ERROR: ", e
.message
);
442 ////////////////////////////////////////////////////////////////////////////////
443 registerStartupHook("gcli", function () {
444 for (let f
= 0; f
< gcliCommandSpecs
.length
; ++f
) {
445 if (gcliCommandSpecs
[f
].name
) gcli
.addCommand(gcliCommandSpecs
[f
]);
450 registerShutdownHook("gcli", function () {
451 for (let f
= 0; f
< gcliCommandSpecs
.length
; ++f
) {
452 if (gcliCommandSpecs
[f
].name
) gcli
.removeCommand(gcliCommandSpecs
[f
]);