PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/desktop/dojotoolkit/desktop/widget/Console.js

https://github.com/mmx31/lucid
JavaScript | 329 lines | 299 code | 0 blank | 30 comment | 104 complexity | 4a3703b24e10cb31d207dab6496efdba MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, MIT
  1. dojo.require("dijit._Widget");
  2. dojo.require("dijit._Templated");
  3. dojo.require("dijit._Container");
  4. dojo.provide("desktop.widget.Console");
  5. dojo.requireLocalization("desktop.widget", "console");
  6. dojo.declare("desktop.widget.Console", [dijit._Widget, dijit._Templated, dijit._Contained], {
  7. // summary:
  8. // A console widget that you can embed in an app
  9. //
  10. // example:
  11. // create a new console alias:
  12. // | myConsole.aliases.foo = function(params){
  13. // | if(params == "bar") this.domNode.innerHTML += "baz!";
  14. // | else this.domNode.innerHTML += "bar!";
  15. // | }
  16. templateString: "<div class=\"console\" dojoAttachEvent=\"onkeypress:_onKeyPress\" tabindex=\"-1\"></div>",
  17. // path: String
  18. // The full path that the console is at (can be set at creation, but cannot be changed after)
  19. path: "file://",
  20. // stdin: String
  21. // contains the text inputted to the console
  22. stdin: "",
  23. // stdout: String
  24. // contains the text outputted to the console
  25. stdout: "",
  26. // histList: array
  27. // The command history
  28. histList: [],
  29. // histSlot: Integer
  30. // internal variable used for history browsing
  31. histSlot: -1,
  32. // appAttached: bool
  33. // is an app attached to the console?
  34. appAttached: false,
  35. // aliases: Object
  36. // A JSON object with command aliases. You can add a method to this and it will be a command
  37. // Each command is passed a 'params' string which is anything that comes after the command.
  38. // Your command must parse the arguments it's passed.
  39. aliases: {
  40. clear: function(params)
  41. {
  42. this.stdout = "";
  43. this.detach();
  44. },
  45. logout: function(params)
  46. {
  47. desktop.core.logout();
  48. this.detach();
  49. },
  50. echo: function(params)
  51. {
  52. this.write(params+"\n");
  53. this.detach();
  54. },
  55. reload: function(params)
  56. {
  57. desktop.reload = true;
  58. window.onbeforeunload = null;
  59. window.location = window.location;
  60. this.detach();
  61. },
  62. help: function(params)
  63. {
  64. var n = dojo.i18n.getLocalization("desktop.widget", "console");
  65. var text = n.helpHeader;
  66. dojo.forEach(["reload", "echo", "ls", "cd", "pwd", "cat", "mkdir", "rm", "rmdir", "ps", "kill", "clear", "logout"], function(a){
  67. var s = a;
  68. if(a == "ls"
  69. || a == "mkdir"
  70. || a == "rmdir"
  71. || a == "cd") s += " ["+n.dir+"]";
  72. if(a == "cat"
  73. || a == "rm") s += " ["+n.file+"]";
  74. if(a == "kill") s += " ["+n.instance+"]";
  75. if(a == "echo") s += " ["+n.text+"]";
  76. s += ("- "+n[a+"Help"] || "Oh noes, I forgot what this does");
  77. text += s+"\n";
  78. }, this);
  79. this.write(text);
  80. this.detach();
  81. },
  82. ps: function(params)
  83. {
  84. var text = " PID TTY CMD\n";
  85. object = desktop.app.getInstances();
  86. dojo.forEach(object, dojo.hitch(this, function(proc){
  87. if (typeof(proc) != "object"){ }
  88. else {
  89. if(proc.status != "killed"){
  90. text += " "+proc.instance+" pts/0 "+proc.sysname+"\n";
  91. }
  92. }
  93. }));
  94. this.write(text);
  95. this.detach();
  96. },
  97. kill: function(params)
  98. {
  99. var n = dojo.i18n.getLocalization("desktop.widget", "console");
  100. if(params == ""){ this.write("kill: "+n.usage+": kill ["+n.instance+"]\n"); }
  101. else {
  102. if(desktop.app.kill(params) == 1){ this.write("kill: "+n.procKilled+"\n"); }
  103. else { this.write("kill: "+n.procKillFail+"\n"); }
  104. }
  105. this.detach();
  106. },
  107. cd: function(params)
  108. {
  109. if (params.charAt(0) != "/"){
  110. if (params != ""){
  111. params = (this.path.charAt(this.path.length-1) == "/" ? "" : "/") + params;
  112. this.path = this.fixPath(this.path+params);
  113. }
  114. else {
  115. this.path = this.fixPath("file://");
  116. }
  117. }
  118. else
  119. this.path = this.fixPath(params || "/");
  120. this.detach();
  121. //TODO: check to see if the directory even exists
  122. },
  123. ls: function(params)
  124. {
  125. var n = dojo.i18n.getLocalization("desktop.widget", "console");
  126. if(params == "") params = this.path;
  127. desktop.filesystem.listDirectory(params, dojo.hitch(this, function(array){
  128. var i = 0;
  129. var out = "";
  130. while(i < array.length){
  131. if(array[i].type == "text/directory"){
  132. out += "["+n.dir+"] "+array[i].name + "\n";
  133. }
  134. else {
  135. out += array[i].name + "\n";
  136. }
  137. i++;
  138. }
  139. this.write(out);
  140. this.detach();
  141. }));
  142. },
  143. mkdir: function(params)
  144. {
  145. var n = dojo.i18n.getLocalization("desktop.widget", "console");
  146. if(params == ""){
  147. this.write("mkdir: "+n.needDirName+"\n");
  148. }
  149. else {
  150. desktop.filesystem.createDirectory(this.path + "/" + params);
  151. }
  152. this.detach();
  153. },
  154. rm: function(params)
  155. {
  156. var n = dojo.i18n.getLocalization("desktop.widget", "console");
  157. if(params == ""){
  158. this.write("rm: "+n.needFileName+"\n");
  159. }
  160. else {
  161. desktop.filesystem.remove(this.path + "/" + params);
  162. }
  163. this.detach();
  164. },
  165. cat: function(params)
  166. {
  167. var n = dojo.i18n.getLocalization("desktop.widget", "console");
  168. if(params == ""){
  169. this.write("cat: "+n.needFileName+"\n");
  170. this.detach();
  171. }
  172. else {
  173. desktop.filesystem.readFileContents(this.path + "/" + params, dojo.hitch(this, function(content){
  174. this.write(content+"\n");
  175. this.detach();
  176. }));
  177. }
  178. },
  179. pwd: function(params){
  180. this.write(this.formatPath(this.path)+"\n");
  181. this.detach();
  182. }
  183. },
  184. postCreate: function(){
  185. this.drawScreen();
  186. },
  187. _onKeyPress: function(e)
  188. {
  189. e.preventDefault();
  190. // summary:
  191. // Event handler
  192. // Processes key presses, such as the up and down arrows for browsing history
  193. if(e.ctrlKey && e.keyChar == "c"){
  194. if(typeof this.appAttached == "number")
  195. desktop.app.kill(this.appAttached);
  196. }
  197. else if(e.keyCode == dojo.keys.UP_ARROW)
  198. {
  199. var length = this.histList.length;
  200. length = length-(length == 0 ? 0 : 1);
  201. if(this.histSlot >= length) return;
  202. this.histSlot++;
  203. this.stdin = this.histList[length-this.histSlot];
  204. this.drawScreen();
  205. }
  206. else if(e.keyCode == dojo.keys.DOWN_ARROW)
  207. {
  208. if(this.histSlot <= -1) return;
  209. this.histSlot--;
  210. if(this.histSlot <= -1){
  211. this.stdin="";
  212. this.histSlot = -1;
  213. }
  214. else {
  215. var length = this.histList.length;
  216. this.stdin = this.histList[(length-(length == 0 ? 0 : 1))-this.histSlot]
  217. }
  218. this.drawScreen();
  219. }
  220. else if(e.keyCode == dojo.keys.ENTER){
  221. this.inputLine(true);
  222. this.histList.push(this.stdin);
  223. this.execute(this.stdin);
  224. }
  225. else if(e.keyCode == dojo.keys.BACKSPACE){
  226. this.stdin = this.stdin.substring(0, this.stdin.length-1);
  227. this.drawScreen();
  228. }
  229. else {
  230. this.stdin += e.keyChar;
  231. this.drawScreen();
  232. }
  233. },
  234. inputLine: function(write){
  235. var lines = this.stdin.split("\n");
  236. var text = ":"+this.formatPath(this.path)+"$ "+lines[lines.length-1]+"\n";
  237. if(write) this.write(text);
  238. return text;
  239. },
  240. write: function(text){
  241. this.stdout += text;
  242. this.drawScreen();
  243. },
  244. drawScreen: function(){
  245. var text = this.stdout;
  246. var doScroll = this.domNode.scrollHeight - this.domNode.offsetHeight == this.domNode.scrollTop;
  247. if(this.appAttached === false) text += this.inputLine();
  248. desktop.textContent(this.domNode, "");
  249. dojo.forEach(text.split("\n"), function(val, i){
  250. var row = document.createElement("div");
  251. desktop.textContent(row, val);
  252. this.domNode.appendChild(row);
  253. }, this)
  254. if(doScroll){
  255. this.domNode.scrollTop = this.domNode.scrollHeight;
  256. }
  257. },
  258. fixPath: function(path){
  259. if(path.charAt(0) == "~") path = "/"+path.substring(1);
  260. if(path.charAt(0) == "/") path = "file:/"+path;
  261. path = path.split("://");
  262. while(path[1].indexOf("//") != -1)
  263. path[1] = path[1].replace("//", "/");
  264. if(path[1].indexOf("..") != -1){
  265. var parts = ("/"+path[1]).split("/");
  266. for(var i in parts){
  267. if(parts[i] != "..") continue;
  268. if(!parts[i-1]) parts.splice(i, 1);
  269. parts.splice(i-1, 2);
  270. }
  271. path[1] = parts.join("/");
  272. }
  273. path = path.join("://");
  274. return path;
  275. },
  276. formatPath: function(path){
  277. if(path.indexOf("file://" == 0)){
  278. path = "/"+path.substring(("file://").length);
  279. }
  280. if(path == "/") path = "~";
  281. return path;
  282. },
  283. execute: function(value){
  284. this.appAttached = true;
  285. this.histSlot = -1;
  286. this.write("\n");
  287. this.stdin = "";
  288. if(value == "") return this.detach();
  289. var cmd = (value.split(" "))[0];
  290. var params = value.substring(cmd.length+1, value.length);
  291. if(typeof this.aliases[cmd] == "function"){
  292. this.aliases[cmd].apply(this, [params]);
  293. }
  294. else {
  295. if(!this.execApp(cmd, params))
  296. this.execJs(value);
  297. }
  298. },
  299. execApp: function(cmd, params){
  300. for(var i in desktop.app.appList){
  301. var app = desktop.app.appList[i];
  302. if(app.sysname.toLowerCase() != cmd.toLowerCase()) continue;
  303. var args = {};
  304. //parse params
  305. dojo.forEach(params.split("--"), function(text){
  306. var parsedArg = dojo.trim(text).split("=");
  307. if(parsedArg[0])
  308. args[parsedArg[0]] = parsedArg[1] || true;
  309. });
  310. var pid = this.appAttached = desktop.app.launch(app.sysname, args);
  311. dojo.connect(desktop.app.instances[pid], "kill", this, "detach");
  312. return true;
  313. }
  314. return false;
  315. },
  316. execJs: function(value){
  317. try {
  318. this.write(eval(value)+"\n");
  319. }
  320. catch(e){
  321. this.write(e.message+"\n");
  322. }
  323. this.detach();
  324. },
  325. detach: function(){
  326. this.appAttached = false;
  327. this.drawScreen();
  328. }
  329. });