JS bookmarklet

2009-03-13

This is a Javscript bookmarklet. This shell really helps in trying to debug runtime values.

I did not write this! Source: http://www.squarefree.com/shell/

(This is a very long line! Create a new bookmark and paste this as the target url. Will not work for explorer but great in firefox.)
Code: (JS shell 1.4)

javascript:with(window.open("","_blank","width="+screen.width*.6+",left="+screen.width*.35+",height="+screen.height*.9+",resizable,scrollbars=yes")){document.write("\n\n\n\n\nJavaScript%20Shell%201.4\n\n\nvar%20\nhistList%20=%20[\"\"],%20\nhistPos%20=%200,%20\n_scope%20=%20{},%20\n_win,%20//%20a%20top-level%20context\nquestion,\n_in,\n_out,\ntooManyMatches%20=%20null,\nlastError%20=%20null;\n\nfunction%20refocus()\n{\n%20%20_in.blur();%20//%20Needed%20for%20Mozilla%20to%20scroll%20correctly.\n%20%20_in.focus();\n}\n\nfunction%20init()\n{\n%20%20_in%20=%20document.getElementById(\"input\");\n%20%20_out%20=%20document.getElementById(\"output\");\n\n%20%20_win%20=%20window;\n\n%20%20if%20(opener%20&&%20!opener.closed)\n%20%20{\n%20%20%20%20println(\"Using%20bookmarklet%20version%20of%20shell:%20commands%20will%20run%20in%20opener's%20context.\",%20\"message\");\n%20%20%20%20_win%20=%20opener;\n%20%20}\n\n%20%20initTarget();\n\n%20%20recalculateInputHeight();\n%20%20refocus();\n}\n\nfunction%20initTarget()\n{\n%20%20_win.Shell%20=%20window;\n%20%20_win.print%20=%20shellCommands.print;\n}\n\n\n//%20Unless%20the%20user%20is%20selected%20something,%20refocus%20the%20textbox.\n//%20(requested%20by%20caillon,%20brendan,%20asa)\nfunction%20keepFocusInTextbox(e)%20\n{\n%20%20var%20g%20=%20e.srcElement%20?%20e.srcElement%20:%20e.target;%20//%20IE%20vs.%20standard\n%20%20\n%20%20while%20(!g.tagName)\n%20%20%20%20g%20=%20g.parentNode;\n%20%20var%20t%20=%20g.tagName.toUpperCase();\n%20%20if%20(t==\"A\"%20||%20t==\"INPUT\")\n%20%20%20%20return;\n%20%20%20%20\n%20%20if%20(window.getSelection)%20{\n%20%20%20%20//%20Mozilla\n%20%20%20%20if%20(String(window.getSelection()))\n%20%20%20%20%20%20return;\n%20%20}\n%20%20else%20if%20(document.getSelection)%20{\n%20%20%20%20//%20Opera?%20Netscape%204?\n%20%20%20%20if%20(document.getSelection())\n%20%20%20%20%20%20return;\n%20%20}\n%20%20else%20{\n%20%20%20%20//%20IE\n%20%20%20%20if%20(%20document.selection.createRange().text%20)\n%20%20%20%20%20%20return;\n%20%20}\n%20%20\n%20%20refocus();\n}\n\nfunction%20inputKeydown(e)%20{\n%20%20//%20Use%20onkeydown%20because%20IE%20doesn't%20support%20onkeypress%20for%20arrow%20keys\n\n%20%20//alert(e.keyCode%20+%20\"%20^%20\"%20+%20e.keycode);\n\n%20%20if%20(e.shiftKey%20&&%20e.keyCode%20==%2013)%20{%20//%20shift-enter\n%20%20%20%20//%20don't%20do%20anything;%20allow%20the%20shift-enter%20to%20insert%20a%20line%20break%20as%20normal\n%20%20}%20else%20if%20(e.keyCode%20==%2013)%20{%20//%20enter\n%20%20%20%20//%20execute%20the%20input%20on%20enter\n%20%20%20%20try%20{%20go();%20}%20catch(er)%20{%20alert(er);%20};\n%20%20%20%20setTimeout(function()%20{%20_in.value%20=%20\"\";%20},%200);%20//%20can't%20preventDefault%20on%20input,%20so%20clear%20it%20later\n%20%20}%20else%20if%20(e.keyCode%20==%2038)%20{%20//%20up\n%20%20%20%20//%20go%20up%20in%20history%20if%20at%20top%20or%20ctrl-up\n%20%20%20%20if%20(e.ctrlKey%20||%20caretInFirstLine(_in))\n%20%20%20%20%20%20hist(true);\n%20%20}%20else%20if%20(e.keyCode%20==%2040)%20{%20//%20down\n%20%20%20%20//%20go%20down%20in%20history%20if%20at%20end%20or%20ctrl-down\n%20%20%20%20if%20(e.ctrlKey%20||%20caretInLastLine(_in))\n%20%20%20%20%20%20hist(false);\n%20%20}%20else%20if%20(e.keyCode%20==%209)%20{%20//%20tab\n%20%20%20%20tabcomplete();\n%20%20%20%20setTimeout(function()%20{%20refocus();%20},%200);%20//%20refocus%20because%20tab%20was%20hit\n%20%20}%20else%20{%20}\n\n%20%20setTimeout(recalculateInputHeight,%200);\n%20%20\n%20%20//return%20true;\n};\n\nfunction%20caretInFirstLine(textbox)\n{\n%20%20//%20IE%20doesn't%20support%20selectionStart/selectionEnd\n%20%20if%20(textbox.selectionStart%20==%20undefined)\n%20%20%20%20return%20true;\n\n%20%20var%20firstLineBreak%20=%20textbox.value.indexOf(\"\\n\");\n%20%20\n%20%20return%20((firstLineBreak%20==%20-1)%20||%20(textbox.selectionStart%20<=%20firstLineBreak));\n}\n\nfunction%20caretInLastLine(textbox)\n{\n%20%20//%20IE%20doesn't%20support%20selectionStart/selectionEnd\n%20%20if%20(textbox.selectionEnd%20==%20undefined)\n%20%20%20%20return%20true;\n\n%20%20var%20lastLineBreak%20=%20textbox.value.lastIndexOf(\"\\n\");\n%20%20\n%20%20return%20(textbox.selectionEnd%20>%20lastLineBreak);\n}\n\nfunction%20recalculateInputHeight()\n{\n%20%20var%20rows%20=%20_in.value.split(/\\n/).length\n%20%20%20%20+%201%20//%20prevent%20scrollbar%20flickering%20in%20Mozilla\n%20%20%20%20+%20(window.opera%20?%201%20:%200);%20//%20leave%20room%20for%20scrollbar%20in%20Opera\n%20%20\n%20%20if%20(_in.rows%20!=%20rows)%20//%20without%20this%20check,%20it%20is%20impossible%20to%20select%20text%20in%20Opera%207.60%20or%20Opera%208.0.\n%20%20%20%20_in.rows%20=%20rows;\n}\n\nfunction%20println(s,%20type)\n{\n%20%20if((s=String(s)))\n%20%20{\n%20%20%20%20var%20newdiv%20=%20document.createElement(\"div\");\n%20%20%20%20newdiv.appendChild(document.createTextNode(s));\n%20%20%20%20newdiv.className%20=%20type;\n%20%20%20%20_out.appendChild(newdiv);\n%20%20%20%20return%20newdiv;\n%20%20}\n}\n\nfunction%20printWithRunin(h,%20s,%20type)\n{\n%20%20var%20div%20=%20println(s,%20type);\n%20%20var%20head%20=%20document.createElement(\"strong\");\n%20%20head.appendChild(document.createTextNode(h%20+%20\":%20\"));\n%20%20div.insertBefore(head,%20div.firstChild);\n}\n\n\nvar%20shellCommands%20=%20\n{\nload%20:%20function%20load(url)\n{\n%20%20var%20s%20=%20_win.document.createElement(\"script\");\n%20%20s.type%20=%20\"text/javascript\";\n%20%20s.src%20=%20url;\n%20%20_win.document.getElementsByTagName(\"head\")[0].appendChild(s);\n%20%20println(\"Loading%20\"%20+%20url%20+%20\"...\",%20\"message\");\n},\n\nclear%20:%20function%20clear()\n{\n%20%20var%20CHILDREN_TO_PRESERVE%20=%203;\n%20%20while%20(_out.childNodes[CHILDREN_TO_PRESERVE])%20\n%20%20%20%20_out.removeChild(_out.childNodes[CHILDREN_TO_PRESERVE]);\n},\n\nprint%20:%20function%20print(s)%20{%20println(s,%20\"print\");%20},\n\n//%20the%20normal%20function,%20\"print\",%20shouldn't%20return%20a%20value\n//%20(suggested%20by%20brendan;%20later%20noticed%20it%20was%20a%20problem%20when%20showing%20others)\npr%20:%20function%20pr(s)%20\n{%20\n%20%20shellCommands.print(s);%20//%20need%20to%20specify%20shellCommands%20so%20it%20doesn't%20try%20window.print()!\n%20%20return%20s;\n},\n\nprops%20:%20function%20props(e,%20onePerLine)\n{\n%20%20if%20(e%20===%20null)%20{\n%20%20%20%20println(\"props%20called%20with%20null%20argument\",%20\"error\");\n%20%20%20%20return;\n%20%20}\n\n%20%20if%20(e%20===%20undefined)%20{\n%20%20%20%20println(\"props%20called%20with%20undefined%20argument\",%20\"error\");\n%20%20%20%20return;\n%20%20}\n\n%20%20var%20ns%20=%20[\"Methods\",%20\"Fields\",%20\"Unreachables\"];\n%20%20var%20as%20=%20[[],%20[],%20[]];%20//%20array%20of%20(empty)%20arrays%20of%20arrays!\n%20%20var%20p,%20j,%20i;%20//%20loop%20variables,%20several%20used%20multiple%20times\n\n%20%20var%20protoLevels%20=%200;\n\n%20%20for%20(p%20=%20e;%20p;%20p%20=%20p.__proto__)\n%20%20{\n%20%20%20%20for%20(i=0;%20i%20thing%20typed%20is%20now%20in%20\"limbo\"\n%20%20//%20(last%20item%20in%20histList)%20and%20should%20be%20reachable%20by%20pressing%20\n%20%20//%20down%20again.\n\n%20%20var%20L%20=%20histList.length;\n\n%20%20if%20(L%20==%201)\n%20%20%20%20return;\n\n%20%20if%20(up)\n%20%20{\n%20%20%20%20if%20(histPos%20==%20L-1)\n%20%20%20%20{\n%20%20%20%20%20%20//%20Save%20this%20entry%20in%20case%20the%20user%20hits%20the%20down%20key.\n%20%20%20%20%20%20histList[histPos]%20=%20_in.value;\n%20%20%20%20}\n\n%20%20%20%20if%20(histPos%20>%200)\n%20%20%20%20{\n%20%20%20%20%20%20histPos--;\n%20%20%20%20%20%20//%20Use%20a%20timeout%20to%20prevent%20up%20from%20moving%20cursor%20within%20new%20text\n%20%20%20%20%20%20//%20Set%20to%20nothing%20first%20for%20the%20same%20reason\n%20%20%20%20%20%20setTimeout(\n%20%20%20%20%20%20%20%20function()%20{\n%20%20%20%20%20%20%20%20%20%20_in.value%20=%20'';%20\n%20%20%20%20%20%20%20%20%20%20_in.value%20=%20histList[histPos];\n%20%20%20%20%20%20%20%20%20%20var%20caretPos%20=%20_in.value.length;\n%20%20%20%20%20%20%20%20%20%20if%20(_in.setSelectionRange)%20\n%20%20%20%20%20%20%20%20%20%20%20%20_in.setSelectionRange(caretPos,%20caretPos);\n%20%20%20%20%20%20%20%20},\n%20%20%20%20%20%20%20%200\n%20%20%20%20%20%20);\n%20%20%20%20}\n%20%20}%20\n%20%20else%20//%20down\n%20%20{\n%20%20%20%20if%20(histPos%20<%20L-1)\n%20%20%20%20{\n%20%20%20%20%20%20histPos++;\n%20%20%20%20%20%20_in.value%20=%20histList[histPos];\n%20%20%20%20}\n%20%20%20%20else%20if%20(histPos%20==%20L-1)\n%20%20%20%20{\n%20%20%20%20%20%20//%20Already%20on%20the%20current%20entry:%20clear%20but%20save\n%20%20%20%20%20%20if%20(_in.value)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20histList[histPos]%20=%20_in.value;\n%20%20%20%20%20%20%20%20++histPos;\n%20%20%20%20%20%20%20%20_in.value%20=%20\"\";\n%20%20%20%20%20%20}\n%20%20%20%20}\n%20%20}\n}\n\nfunction%20tabcomplete()\n{\n%20%20/*\n%20%20%20*%20Working%20backwards%20from%20s[from],%20find%20the%20spot\n%20%20%20*%20where%20this%20expression%20starts.%20%20It%20will%20scan\n%20%20%20*%20until%20it%20hits%20a%20mismatched%20(%20or%20a%20space,\n%20%20%20*%20but%20it%20skips%20over%20quoted%20strings.\n%20%20%20*%20If%20stopAtDot%20is%20true,%20stop%20at%20a%20'.'\n%20%20%20*/\n%20%20function%20findbeginning(s,%20from,%20stopAtDot)\n%20%20{\n%20%20%20%20/*\n%20%20%20%20%20*%20%20Complicated%20function.\n%20%20%20%20%20*\n%20%20%20%20%20*%20%20Return%20true%20if%20s[i]%20==%20q%20BUT%20ONLY%20IF\n%20%20%20%20%20*%20%20s[i-1]%20is%20not%20a%20backslash.\n%20%20%20%20%20*/\n%20%20%20%20function%20equalButNotEscaped(s,i,q)\n%20%20%20%20{\n%20%20%20%20%20%20if(s.charAt(i)%20!=%20q)%20//%20not%20equal%20go%20no%20further\n%20%20%20%20%20%20%20%20return%20false;\n\n%20%20%20%20%20%20if(i==0)%20//%20beginning%20of%20string\n%20%20%20%20%20%20%20%20return%20true;\n\n%20%20%20%20%20%20if(s.charAt(i-1)%20==%20'\\\\')%20//%20escaped?\n%20%20%20%20%20%20%20%20return%20false;\n\n%20%20%20%20%20%20return%20true;\n%20%20%20%20}\n\n%20%20%20%20var%20nparens%20=%200;\n%20%20%20%20var%20i;\n%20%20%20%20for(i=from;%20i>=0;%20i--)\n%20%20%20%20{\n%20%20%20%20%20%20if(s.charAt(i)%20==%20'%20')\n%20%20%20%20%20%20%20%20break;\n\n%20%20%20%20%20%20if(stopAtDot%20&&%20s.charAt(i)%20==%20'.')\n%20%20%20%20%20%20%20%20break;\n%20%20%20%20%20%20%20%20\n%20%20%20%20%20%20if(s.charAt(i)%20==%20')')\n%20%20%20%20%20%20%20%20nparens++;\n%20%20%20%20%20%20else%20if(s.charAt(i)%20==%20'(')\n%20%20%20%20%20%20%20%20nparens--;\n\n%20%20%20%20%20%20if(nparens%20<%200)\n%20%20%20%20%20%20%20%20break;\n\n%20%20%20%20%20%20//%20skip%20quoted%20strings\n%20%20%20%20%20%20if(s.charAt(i)%20==%20'\\''%20||%20s.charAt(i)%20==%20'\\\"')\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20//dump(\"skipping%20quoted%20chars:%20\");\n%20%20%20%20%20%20%20%20var%20quot%20=%20s.charAt(i);\n%20%20%20%20%20%20%20%20i--;\n%20%20%20%20%20%20%20%20while(i%20>=%200%20&&%20!equalButNotEscaped(s,i,quot))%20{\n%20%20%20%20%20%20%20%20%20%20//dump(s.charAt(i));\n%20%20%20%20%20%20%20%20%20%20i--;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20//dump(\"\\n\");\n%20%20%20%20%20%20}\n%20%20%20%20}\n%20%20%20%20return%20i;\n%20%20}\n\n%20%20//%20XXX%20should%20be%20used%20more%20consistently%20(instead%20of%20using%20selectionStart/selectionEnd%20throughout%20code)\n%20%20//%20XXX%20doesn't%20work%20in%20IE,%20even%20though%20it%20contains%20IE-specific%20code\n%20%20function%20getcaretpos(inp)\n%20%20{\n%20%20%20%20if(inp.selectionEnd%20!=%20null)\n%20%20%20%20%20%20return%20inp.selectionEnd;\n%20%20%20%20%20%20\n%20%20%20%20if(inp.createTextRange)\n%20%20%20%20{\n%20%20%20%20%20%20var%20docrange%20=%20_win.Shell.document.selection.createRange();\n%20%20%20%20%20%20var%20inprange%20=%20inp.createTextRange();\n%20%20%20%20%20%20if%20(inprange.setEndPoint)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20inprange.setEndPoint('EndToStart',%20docrange);\n%20%20%20%20%20%20%20%20return%20inprange.text.length;\n%20%20%20%20%20%20}\n%20%20%20%20}\n\n%20%20%20%20return%20inp.value.length;%20//%20sucks,%20punt\n%20%20}\n\n%20%20function%20setselectionto(inp,pos)\n%20%20{\n%20%20%20%20if(inp.selectionStart)%20{\n%20%20%20%20%20%20inp.selectionStart%20=%20inp.selectionEnd%20=%20pos;\n%20%20%20%20}\n%20%20%20%20else%20if(inp.createTextRange)%20{\n%20%20%20%20%20%20var%20docrange%20=%20_win.Shell.document.selection.createRange();\n%20%20%20%20%20%20var%20inprange%20=%20inp.createTextRange();\n%20%20%20%20%20%20inprange.move('character',pos);\n%20%20%20%20%20%20inprange.select();\n%20%20%20%20}\n%20%20%20%20else%20{%20//%20err...\n%20%20%20%20/*\n%20%20%20%20%20%20inp.select();\n%20%20%20%20%20%20if(_win.Shell.document.getSelection())\n%20%20%20%20%20%20%20%20_win.Shell.document.getSelection()%20=%20\"\";\n%20%20%20%20%20%20%20%20*/\n%20%20%20%20}\n%20%20}\n%20%20%20%20//%20get%20position%20of%20cursor%20within%20the%20input%20box\n%20%20%20%20var%20caret%20=%20getcaretpos(_in);\n\n%20%20%20%20if(caret)%20{\n%20%20%20%20%20%20//dump(\"----\\n\");\n%20%20%20%20%20%20var%20dotpos,%20spacepos,%20complete,%20obj;\n%20%20%20%20%20%20//dump(\"caret%20pos:%20\"%20+%20caret%20+%20\"\\n\");\n%20%20%20%20%20%20//%20see%20if%20there's%20a%20dot%20before%20here\n%20%20%20%20%20%20dotpos%20=%20findbeginning(_in.value,%20caret-1,%20true);\n%20%20%20%20%20%20//dump(\"dot%20pos:%20\"%20+%20dotpos%20+%20\"\\n\");\n%20%20%20%20%20%20if(dotpos%20==%20-1%20||%20_in.value.charAt(dotpos)%20!=%20'.')%20{\n%20%20%20%20%20%20%20%20dotpos%20=%20caret;\n//dump(\"changed%20dot%20pos:%20\"%20+%20dotpos%20+%20\"\\n\");\n%20%20%20%20%20%20}\n\n%20%20%20%20%20%20//%20look%20backwards%20for%20a%20non-variable-name%20character\n%20%20%20%20%20%20spacepos%20=%20findbeginning(_in.value,%20dotpos-1,%20false);\n%20%20%20%20%20%20//dump(\"space%20pos:%20\"%20+%20spacepos%20+%20\"\\n\");\n%20%20%20%20%20%20//%20get%20the%20object%20we're%20trying%20to%20complete%20on\n%20%20%20%20%20%20if(spacepos%20==%20dotpos%20||%20spacepos+1%20==%20dotpos%20||%20dotpos%20==%20caret)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20//%20try%20completing%20function%20args\n%20%20%20%20%20%20%20%20if(_in.value.charAt(dotpos)%20==%20'('%20||\n%20(_in.value.charAt(spacepos)%20==%20'('%20&&%20(spacepos+1)%20==%20dotpos))\n%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20var%20fn,fname;\n%20%20var%20from%20=%20(_in.value.charAt(dotpos)%20==%20'(')%20?%20dotpos%20:%20spacepos;\n%20%20%20%20%20%20%20%20%20%20spacepos%20=%20findbeginning(_in.value,%20from-1,%20false);\n\n%20%20%20%20%20%20%20%20%20%20fname%20=%20_in.value.substr(spacepos+1,from-(spacepos+1));\n%20%20//dump(\"fname:%20\"%20+%20fname%20+%20\"\\n\");\n%20%20%20%20%20%20%20%20%20%20try%20{\n%20%20%20%20%20%20%20%20%20%20%20%20with(_win.Shell._scope)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20with(_win)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20with(Shell.shellCommands)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fn%20=%20eval(fname);\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20catch(er)%20{\n%20%20%20%20%20%20%20%20%20%20%20%20//dump('fn%20is%20not%20a%20valid%20object\\n');\n%20%20%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20if(fn%20==%20undefined)%20{\n%20%20%20%20%20%20%20%20%20%20%20%20%20//dump('fn%20is%20undefined');\n%20%20%20%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20if(fn%20instanceof%20Function)\n%20%20%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20%20%20//%20Print%20function%20definition,%20including%20argument%20names,%20but%20not%20function%20body\n%20%20%20%20%20%20%20%20%20%20%20%20if(!fn.toString().match(/function%20.+?\\(\\)%20+\\{\\n%20+\\[native%20code\\]\\n\\}/))\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20println(fn.toString().match(/function%20.+?\\(.*?\\)/),%20\"tabcomplete\");\n%20%20%20%20%20%20%20%20%20%20}\n\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20else\n%20%20%20%20%20%20%20%20%20%20obj%20=%20_win;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20var%20objname%20=%20_in.value.substr(spacepos+1,dotpos-(spacepos+1));\n%20%20%20%20%20%20%20%20//dump(\"objname:%20|\"%20+%20objname%20+%20\"|\\n\");\n%20%20%20%20%20%20%20%20try%20{\n%20%20%20%20%20%20%20%20%20%20with(_win.Shell._scope)\n%20%20%20%20%20%20%20%20%20%20%20%20with(_win)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20obj%20=%20eval(objname);\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20catch(er)%20{\n%20%20%20%20%20%20%20%20%20%20printError(er);%20\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20if(obj%20==%20undefined)%20{\n%20%20%20%20%20%20%20%20%20%20//%20sometimes%20this%20is%20tabcomplete's%20fault,%20so%20don't%20print%20it%20:(\n%20%20%20%20%20%20%20%20%20%20//%20e.g.%20completing%20from%20\"print(document.getElements\"\n%20%20%20%20%20%20%20%20%20%20//%20println(\"Can't%20complete%20from%20null%20or%20undefined%20expression%20\"%20+%20objname,%20\"error\");\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20}\n%20%20%20%20%20%20//dump(\"obj:%20\"%20+%20obj%20+%20\"\\n\");\n%20%20%20%20%20%20//%20get%20the%20thing%20we're%20trying%20to%20complete\n%20%20%20%20%20%20if(dotpos%20==%20caret)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20if(spacepos+1%20==%20dotpos%20||%20spacepos%20==%20dotpos)\n%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20//%20nothing%20to%20complete\n%20%20%20%20%20%20%20%20%20%20//dump(\"nothing%20to%20complete\\n\");\n%20%20%20%20%20%20%20%20%20%20return;\n%20%20%20%20%20%20%20%20}\n\n%20%20%20%20%20%20%20%20complete%20=%20_in.value.substr(spacepos+1,dotpos-(spacepos+1));\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20complete%20=%20_in.value.substr(dotpos+1,caret-(dotpos+1));\n%20%20%20%20%20%20}\n%20%20%20%20%20%20//dump(\"complete:%20\"%20+%20complete%20+%20\"\\n\");\n%20%20%20%20%20%20//%20ok,%20now%20look%20at%20all%20the%20props/methods%20of%20this%20obj\n%20%20%20%20%20%20//%20and%20find%20ones%20starting%20with%20'complete'\n%20%20%20%20%20%20var%20matches%20=%20[];\n%20%20%20%20%20%20var%20bestmatch%20=%20null;\n%20%20%20%20%20%20for(var%20a%20in%20obj)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20//a%20=%20a.toString();\n%20%20%20%20%20%20%20%20//XXX:%20making%20it%20lowercase%20could%20help%20some%20cases,\n%20%20%20%20%20%20%20%20//%20but%20screws%20up%20my%20general%20logic.\n%20%20%20%20%20%20%20%20if(a.substr(0,complete.length)%20==%20complete)%20{\n%20%20%20%20%20%20%20%20%20%20matches.push(a);\n%20%20%20%20%20%20%20%20%20%20////dump(\"match:%20\"%20+%20a%20+%20\"\\n\");\n%20%20%20%20%20%20%20%20%20%20//%20if%20no%20best%20match,%20this%20is%20the%20best%20match\n%20%20%20%20%20%20%20%20%20%20if(bestmatch%20==%20null)\n%20%20%20%20%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20%20%20%20%20bestmatch%20=%20a;\n%20%20%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20%20%20%20%20//%20the%20best%20match%20is%20the%20longest%20common%20string\n%20%20%20%20%20%20%20%20%20%20%20%20function%20min(a,b){%20return%20((a%201%20&&%20(tooManyMatches%20==%20objAndComplete%20||%20matches.length%20<=%2010))%20{\n\n%20%20%20%20%20%20%20%20printWithRunin(\"Matches:%20\",%20matches.join(',%20'),%20\"tabcomplete\");\n%20%20%20%20%20%20%20%20tooManyMatches%20=%20null;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20if(matches.length%20>%2010)\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20println(matches.length%20+%20\"%20matches.%20%20Press%20tab%20again%20to%20see%20them%20all\",%20\"tabcomplete\");\n%20%20%20%20%20%20%20%20tooManyMatches%20=%20objAndComplete;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20tooManyMatches%20=%20null;\n%20%20%20%20%20%20}\n%20%20%20%20%20%20if(bestmatch%20!=%20\"\")\n%20%20%20%20%20%20{\n%20%20%20%20%20%20%20%20var%20sstart;\n%20%20%20%20%20%20%20%20if(dotpos%20==%20caret)%20{\n%20%20%20%20%20%20%20%20%20%20sstart%20=%20spacepos+1;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20else%20{\n%20%20%20%20%20%20%20%20%20%20sstart%20=%20dotpos+1;\n%20%20%20%20%20%20%20%20}\n%20%20%20%20%20%20%20%20_in.value%20=%20_in.value.substr(0,%20sstart)\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20+%20bestmatch\n%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20+%20_in.value.substr(caret);\n%20%20%20%20%20%20%20%20setselectionto(_in,caret%20+%20(bestmatch.length%20-%20complete.length));\n%20%20%20%20%20%20}\n%20%20%20%20}\n}\n\nfunction%20printQuestion(q)\n{\n%20%20println(q,%20\"input\");\n}\n\nfunction%20printAnswer(a)\n{\n%20%20if%20(a%20!==%20undefined)%20{\n%20%20%20%20println(a,%20\"normalOutput\");\n%20%20%20%20shellCommands.ans%20=%20a;\n%20%20}\n}\n\nfunction%20printError(er)\n{%20\n%20%20var%20lineNumberString;\n\n%20%20lastError%20=%20er;%20//%20for%20debugging%20the%20shell\n%20%20if%20(er.name)\n%20%20{\n%20%20%20%20//%20lineNumberString%20should%20not%20be%20\"\",%20to%20avoid%20a%20very%20wacky%20bug%20in%20IE%206.\n%20%20%20%20lineNumberString%20=%20(er.lineNumber%20!=%20undefined)%20?%20(\"%20on%20line%20\"%20+%20er.lineNumber%20+%20\":%20\")%20:%20\":%20\";\n%20%20%20%20println(er.name%20+%20lineNumberString%20+%20er.message,%20\"error\");%20//%20Because%20IE%20doesn't%20have%20error.toString.\n%20%20}\n%20%20else\n%20%20%20%20println(er,%20\"error\");%20//%20Because%20security%20errors%20in%20Moz%20/only/%20have%20toString.\n}\n\nfunction%20go(s)\n{\n%20%20_in.value%20=%20question%20=%20s%20?%20s%20:%20_in.value;\n\n%20%20if%20(question%20==%20\"\")\n%20%20%20%20return;\n\n%20%20histList[histList.length-1]%20=%20question;\n%20%20histList[histList.length]%20=%20\"\";\n%20%20histPos%20=%20histList.length%20-%201;\n%20%20\n%20%20//%20Unfortunately,%20this%20has%20to%20happen%20*before*%20the%20JavaScript%20is%20run,%20so%20that%20\n%20%20//%20print()%20output%20will%20go%20in%20the%20right%20place.\n%20%20_in.value='';\n%20%20recalculateInputHeight();\n%20%20printQuestion(question);\n\n%20%20if%20(_win.closed)%20{\n%20%20%20%20printError(\"Target%20window%20has%20been%20closed.\");\n%20%20%20%20return;\n%20%20}\n%20%20\n%20%20try%20{%20(\"Shell\"%20in%20_win)%20}\n%20%20catch(er)%20{\n%20%20%20%20printError(\"The%20JavaScript%20Shell%20cannot%20access%20variables%20in%20the%20target%20window.%20%20The%20most%20likely%20reason%20is%20that%20the%20target%20window%20now%20has%20a%20different%20page%20loaded%20and%20that%20page%20has%20a%20different%20hostname%20than%20the%20original%20page.\");\n%20%20%20%20return;\n%20%20}\n\n%20%20if%20(!(\"Shell\"%20in%20_win))\n%20%20%20%20initTarget();%20//%20silent\n\n%20%20//%20Evaluate%20Shell.question%20using%20_win's%20eval%20(this%20is%20why%20eval%20isn't%20in%20the%20|with|,%20IIRC).\n%20%20_win.location.href%20=%20\"javascript:try{%20Shell.printAnswer(eval('with(Shell._scope)%20with(Shell.shellCommands)%20{'%20+%20Shell.question%20+%20String.fromCharCode(10)%20+%20'}'));%20}%20catch(er)%20{%20Shell.printError(er);%20};%20setTimeout(Shell.refocus,%200);%20void%200\";\n}\n\n\n\n\n\n\n\n\nbody%20{%20background:%20white;%20color:%20black;%20}\n\n#output%20{%20white-space:%20pre;%20white-space:%20-moz-pre-wrap;%20}%20/*%20Preserve%20line%20breaks,%20but%20wrap%20too%20if%20browser%20supports%20it%20*/\nh3%20{%20margin-top:%200;%20margin-bottom:%200em;%20}\nh3%20+%20div%20{%20margin:%200;%20}\n\nform%20{%20margin:%200;%20padding:%200;%20}\n#input%20{%20width:%20100%25;%20border:%20none;%20padding:%200;%20overflow:%20auto;%20}\n\n.input%20{%20color:%20blue;%20background:%20white;%20font:%20inherit;%20font-weight:%20bold;%20margin-top:%20.5em;%20/*%20background:%20#E6E6FF;%20*/%20}\n.normalOutput%20{%20color:%20black;%20background:%20white;%20}\n.print%20{%20color:%20brown;%20background:%20white;%20}\n.error%20{%20color:%20red;%20background:%20white;%20}\n.propList%20{%20color:%20green;%20background:%20white;%20}\n.message%20{%20color:%20green;%20background:%20white;%20}\n.tabcomplete%20{%20color:%20purple;%20background:%20white;%20}\n\n\n\n\n\n

JavaScript%20Shell%201.4

Features:%20autocompletion%20of%20property%20names%20with%20Tab,%20multiline%20input%20with%20Shift+Enter,%20input%20history%20with%20(Ctrl+)%20Up/Down,%20Math,%20help
Values%20and%20functions:%20ans,%20print(string),%20props(object),%20blink(node),%20clear(),%20load(scriptURL),%20scope(object)
\n\n
\n\n\n\n");document.close();}void%200