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 require("utils/utils");
14 let {oneShotTimer
, intervalTimer
} = require("utils/timer");
17 ////////////////////////////////////////////////////////////////////////////////
18 let editList
= {lmod
:-1};
22 function getEditList () {
23 let cur
= scacheAPI
.getScriptsForEdit();
24 if (cur
.lmod
!= editList
.lmod
) {
25 editList
= {lmod
:cur
.lmod
, list
:cur
.list
};
26 editNames
= new Array();
27 for (let xnfo
of editList
.list
) editNames
.push({name
:xnfo
.name
, value
:xnfo
.path
});
33 ////////////////////////////////////////////////////////////////////////////////
34 let pkgList
= {lmod
:-1};
38 function getPkgList () {
39 let cur
= pkgman
.getPackageList();
40 //conlog("getPkgList: pkgList.lmod=", pkgList.lmod, "; cur.lmod=", cur.lmod);
41 if (cur
.lmod
!= pkgList
.lmod
) {
42 pkgList
= {lmod
:cur
.lmod
, list
:cur
.list
};
43 pkgNames
= new Array();
44 for (let pi
of pkgList
.list
) pkgNames
.push({name
:pi
.name
, value
:pi
});
50 ////////////////////////////////////////////////////////////////////////////////
51 function addjsext (fn
) {
52 if (!/\.js$/.test(fn
)) fn
+= ".js";
57 ////////////////////////////////////////////////////////////////////////////////
58 function openEditor (fname
, chromeWin
, newfile
) {
59 let fl
= Cc
["@mozilla.org/file/local;1"].createInstance(Ci
.nsIFile
);
60 fl
.followLinks
= true;
61 fl
.initWithPath(fname
);
64 if (fl
.isDirectory()) return;
65 lmtime
= fl
.lastModifiedTime
;
71 text
= fileReadText(fl
);
75 logError("can't read file: "+fname
);
79 "// ==UserScript==\n"+
84 "// @run-at document-end\n"+
89 "// ==/UserScript==\n\n";
91 let spw
= chromeWin
.Scratchpad
.ScratchpadManager
.openScratchpad({
96 // TODO: how can i observe file changes without timer?
97 let wasChange
= false;
98 let checkFC = function () {
99 let fl
= Cc
["@mozilla.org/file/local;1"].createInstance(Ci
.nsIFile
);
100 fl
.followLinks
= true;
101 fl
.initWithPath(fname
);
102 if (fl
.exists() && !fl
.isDirectory() && lmtime
!= fl
.lastModifiedTime
) {
103 lmtime
= fl
.lastModifiedTime
;
108 let tm
= intervalTimer(function () {
109 if (checkFC()) { scacheAPI
.reset(); wasChange
= true; }
111 // kill timer on closing
112 spw
.addEventListener("close", function sploaded() {
113 spw
.removeEventListener("close", sploaded
, false);
116 if (wasChange
|| checkFC()) {
118 scacheAPI
.validate();
119 latestUC
= scacheAPI
.getUC();
125 ////////////////////////////////////////////////////////////////////////////////
126 let gcliCommandSpecs
= [
129 description
: "GuerillaJS control",
133 name
: "guerilla about",
134 description
: "show various info",
138 description
: "info to show",
139 type
: { name
: "selection", data
: ["readme", "credits", "thanks", "licenses"] },
140 defaultValue
: "readme",
143 exec: function (args
, context
) {
144 let bro
= context
.environment
.chromeWindow
.gBrowser
;
147 case "credits": list
= "CREDITS.txt"; break;
148 case "thanks": list
= "THANKS.txt"; break;
149 case "licenses": list
= ["LICENSE.bsd.txt", "LICENSE.mit.txt", "LICENSE.mpl.txt", "LICENSE.wtfpl.txt"]; break;
150 default: list
= "README.txt"; break;
152 if (typeof(list
) == "string") {
153 bro
.selectedTab
= bro
.addTab(gsdoxUrl
+list
);
155 for (let name
of list
) bro
.selectedTab
= bro
.addTab(gsdoxUrl
+name
);
161 name
: "guerilla reset",
162 description
: "reset all internal caches",
163 exec: function (args
, context
) {
164 //conlog("clearing guerilla caches...");
170 name
: "guerilla debug",
171 description
: "switch debug mode on/off",
175 description
: "action to perform",
176 type
: { name
: "selection", data
: ["show", "tan", "ona", "toggle"] },
177 defaultValue
: "show",
180 returnValue
: "string",
181 exec: function (args
, context
) {
183 case "tan": addonOptions
.debugMode
= true; break;
184 case "ona": addonOptions
.debugMode
= false; break;
185 case "toggle": addonOptions
.debugMode
= !addonOptions
.debugMode
; break;
187 return "guerilla debug mode is "+(addonOptions
.debugMode
? "on" : "off");
192 name
: "guerilla log",
193 description
: "switch logging on/off",
197 description
: "action to perform",
198 type
: { name
: "selection", data
: ["show", "tan", "ona", "toggle"] },
199 defaultValue
: "show",
202 returnValue
: "string",
203 exec: function (args
, context
) {
205 case "tan": addonOptions
.logEnabled
= true; break;
206 case "ona": addonOptions
.logEnabled
= false; break;
207 case "toggle": addonOptions
.logEnabled
= !addonOptions
.logEnabled
; break;
209 return "guerilla logging is "+(addonOptions
.logEnabled
? "on" : "off");
214 name
: "guerilla state",
215 description
: "switch guerilla state",
219 description
: "action to perform",
220 type
: { name
: "selection", data
: ["show", "active", "inactive", "toggle"] },
221 defaultValue
: "show",
224 returnValue
: "string",
225 exec: function (args
, context
) {
227 case "active": addonOptions
.active
= true; break;
228 case "inactive": addonOptions
.active
= false; break;
229 case "toggle": addonOptions
.active
= !addonOptions
.active
; break;
231 return "guerilla is "+(addonOptions
.active
? "" : "in")+"active";
236 name
: "guerilla activate",
237 description
: "activate guerilla",
238 returnValue
: "string",
239 exec: function (args
, context
) {
240 addonOptions
.active
= true;
241 return "guerilla is active";
246 name
: "guerilla deactivate",
247 description
: "deactivate guerilla",
248 returnValue
: "string",
249 exec: function (args
, context
) {
250 addonOptions
.active
= false;
251 return "guerilla is inactive";
256 name
: "guerilla new",
257 description
: "create new userscript",
261 description
: "new script name",
265 exec: function (args
, context
) {
266 let fname
= args
.filename
;
267 let mt
= fname
.match(/^\/?libs\/([^\/]+)$/);
268 if (mt
) fname
= mt
[1];
269 if (fname
.length
== 0 || fname
.indexOf("/") >= 0) return;
270 fname
= addjsext(fname
);
274 dir
= getUserLibDir();
277 //if (args.filename.length == 0 || args.filename.indexOf("/") >= 0) { alert("invalid file name: "+args.filename); return; }
278 dir
= getUserJSDir();
281 conlog("trying to edit '"+dir
.path
+"'");
282 openEditor(dir
.path
, context
.environment
.chromeDocument
.defaultView
, true);
287 name
: "guerilla edit",
288 description
: "edit guerilla script",
289 //returnValue: "string",
293 description
: "script name to edit",
297 lookup: function (context
) getEditList(),
301 exec: function (args
, context
) {
302 if (args
.filename
) openEditor(args
.filename
, context
.environment
.chromeDocument
.defaultView
);
307 name
: "guerilla package",
308 description
: "GuerillaJS package control",
311 name
: "guerilla package abort",
312 description
: "abort all operations",
313 exec: function (args
, context
) { pkgman
.cancel(); },
316 name
: "guerilla package list",
317 description
: "list installed packages",
318 returnValue
: "string",
327 exec: function (args
, context
) {
328 let mask
= args
.mask
||"*";
329 let re
= wild2re(mask
);
330 let res
= "=== package list ===";
332 for (let pi
of pkgDB
.getActivePackages()) {
333 if (re
.test(pi
.name
)) {
335 if (pi
.version
) res
+= "\t"+pi
.version
;
339 //return (count ? res : "no packages found");
340 //TODO: special output
341 logError(count
? res
: "no packages found");
342 return "find result in error console";
346 name
: "guerilla package update",
347 description
: "update package(s)",
356 exec: function (args
, context
) {
357 if (!args
.mask
) return;
358 let mask
= args
.mask
||"*";
359 let re
= wild2re(mask
);
360 for (let pi
of pkgDB
.getActivePackages()) {
361 if (re
.test(pi
.name
)) {
363 pkgman
.update(pi
.name
);
365 logError("ERROR: ", e
.message
);
372 name
: "guerilla package install",
373 description
: "install package",
377 description
: "package name",
382 description
: "package install url",
386 exec: function (args
, context
) {
387 if (!args
.name
|| !args
.url
) return;
389 pkgman
.install(args
.name
, args
.url
);
391 logError("ERROR: ", e
.message
);
396 name
: "guerilla package remove",
397 description
: "remove package",
401 description
: "package name",
405 lookup: function (context
) getPkgList(),
409 exec: function (args
, context
) {
410 //if (!args.name.name) return;
412 pkgman
.remove(args
.name
.name
);
414 logError("ERROR: ", e
.message
);
420 name
: "guerilla wtf",
425 description
: "file name",
430 exec: function (args
, context
) {
431 if (!args
.filename
) return;
433 let h
= calcFileSha512(args
.filename
);
434 logError("h="+h
+"; "+args
.filename
);
436 logError("ERROR: ", e
.message
);
443 ////////////////////////////////////////////////////////////////////////////////
444 registerStartupHook("gcli", function () {
445 for (let cmd
of gcliCommandSpecs
) {
446 if (cmd
&& typeof(cmd
) === "object" && cmd
.name
) gcli
.addCommand(cmd
);
451 registerShutdownHook("gcli", function () {
452 for (let cmd
of gcliCommandSpecs
) {
453 if (cmd
&& typeof(cmd
) === "object" && cmd
.name
) gcli
.removeCommand(cmd
);