Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9088029

Browse filesBrowse files
committed
first tutorial
1 parent 86759ff commit 9088029
Copy full SHA for 9088029

File tree

Expand file treeCollapse file tree

3 files changed

+191
-2
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+191
-2
lines changed

‎helloworld.html

Copy file name to clipboard
+186Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="chrome=1">
6+
<title>Josh.js by sdether</title>
7+
<link rel="stylesheet" href="stylesheets/styles.css">
8+
<link rel="stylesheet" href="stylesheets/pygment_trac.css">
9+
<script src="javascripts/respond.js"></script>
10+
<!--[if lt IE 9]>
11+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
12+
<![endif]-->
13+
<!--[if lt IE 8]>
14+
<link rel="stylesheet" href="stylesheets/ie.css">
15+
<![endif]-->
16+
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
17+
<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro' rel='stylesheet' type='text/css'>
18+
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
19+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
20+
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
21+
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
22+
<script>Josh = {Debug: true };</script>
23+
<script src="javascripts/killring.js"></script>
24+
<script src="javascripts/history.js"></script>
25+
<script src="javascripts/readline.js"></script>
26+
<script src="javascripts/shell.js"></script>
27+
<script src="javascripts/pathhandler.js"></script>
28+
<style type="text/css">
29+
#shell-panel {
30+
height: 200px;
31+
width: 100%;
32+
background-color: #002f05;
33+
color: #00fe00;
34+
padding: 20px 20px 20px 20px;
35+
font-family: 'Source Code Pro';
36+
overflow: scroll;
37+
overflow-x: hidden;
38+
overflow-y: scroll;
39+
border: 1px dashed #E6EBE0;
40+
}</style>
41+
<script>
42+
$(document).ready(function() {
43+
var history = new Josh.History({ key: 'josh.helloworld'});
44+
var shell = Josh.Shell({history: history});
45+
var promptCounter = 0;
46+
shell.onNewPrompt(function(callback) {
47+
promptCounter++;
48+
callback("[" + promptCounter + "] $");
49+
});
50+
shell.setCommandHandler("hello", {
51+
exec: function(cmd, args, callback) {
52+
var arg = args[0] || '';
53+
var response = "who is this " + arg + " you are talking to?";
54+
if(arg === 'josh') {
55+
response = 'pleased to meet you.';
56+
} else if(arg === 'world') {
57+
response = 'world says hi.'
58+
} else if(!arg) {
59+
response = 'who are you saying hello to?';
60+
}
61+
callback(response);
62+
},
63+
completion: function(cmd, arg, line, callback) {
64+
callback(shell.bestMatch(arg, ['world', 'josh']))
65+
}
66+
});
67+
shell.activate();
68+
});</script>
69+
</head>
70+
<body>
71+
<div id="header">
72+
<nav>
73+
<li><a href="index.html">Back to the Documentation</a></li>
74+
</nav>
75+
</div>
76+
<div class="wrapper">
77+
78+
<section>
79+
<h1>Hello World Shell</h1>
80+
81+
<p>This tutorial shows how easy it is to create the below shell window with a custom prompt and a new command
82+
<code>hello</code>.</p>
83+
84+
<p>
85+
86+
<div id="shell-panel">
87+
<div>Type <code>help</code> or hit <code>TAB</code> for a list of commands.</div>
88+
<div id="shell-view"></div>
89+
</div>
90+
</p>
91+
<h2>Creating the Shell</h2>
92+
93+
<p>The
94+
<code>Josh.Shell</code> uses local storage to store a history of the commands that you have typed. By default this is keyed with
95+
<em>josh.history</em>. That history is available to all instances of the shell on your site. For this tutorial, we want to make sure we have our own copy, so we don't get commands from other tutorials and examples, so we need to create a history object with its own key:
96+
</p>
97+
<pre>var history = new Josh.History({ key: 'helloworld.history'});</pre>
98+
<p>Now we can create a Shell instance with that history:</p>
99+
<pre>var shell = Josh.Shell({history: history});</pre>
100+
<p>Now the shell exists but has not yet been activated.</p>
101+
102+
<p><em>Note on how the shell attaches to its UI elements:</em> By default
103+
<code>Josh.Shell</code> expects to find a <code>div#shell-panel</code> that contains a
104+
<code>div#shell-view</code>. The former is the physical container providing the dimensions of the shell, while the latter is a div the shell will continue to append to and scroll to mimic a screen. If you want to use other div IDs (because you have multiple shells on one page), you can provide
105+
<code>shell-panel-id</code> and <code>shell-view-id</code> in the constructor.</p>
106+
107+
<h2>Rendering the prompt</h2>
108+
109+
<p>The default prompt for Josh is
110+
<strong>jsh$</strong>. Let's create a prompt instead that keeps track of how many times it has been shown:
111+
</p>
112+
<pre>var promptCounter = 0;
113+
shell.onNewPrompt(function(callback) {
114+
promptCounter++;
115+
callback("[" + promptCounter + "] $ ");
116+
});</pre>
117+
<p>
118+
<code>onNewPrompt</code> is called every time Josh needs to re-render the prompt. This happens usually a command is executed, but can also happen on tab completion, when a list of possible completions is shown.
119+
<code>onNewPrompt</code> expects a function that accepts a callback as its only argument. Josh will not continue until the callback has been called with an html string to display. This allows the prompt to rendered as part of an asynchronous action. For our example, we just increment the promptCounter and send back a simple string with the counter.
120+
</p>
121+
122+
<h2>Adding a new command</h2>
123+
124+
<p>Josh implements just three commands out of the box:</p>
125+
<ul>
126+
<li><code>help</code> - show a list of known commands</li>
127+
<li><code>history</code> - show the commands previously entered</li>
128+
<li><code>clear</code> - clear the console (i.e. remove all children from <code>div#shell-view</code></li>
129+
</ul>
130+
<p>Let's add a new command called hello with tab completion:</p>
131+
<pre>shell.setCommandHandler("hello", {
132+
exec: function(cmd, args, callback) {
133+
var arg = args[0] || '';
134+
var response = "who is this " + arg + " you are talking to?";
135+
if(arg === 'josh') {
136+
response = 'pleased to meet you.';
137+
} else if(arg === 'world') {
138+
response = 'world says hi.'
139+
} else if(!arg) {
140+
response = 'who are you saying hello to?';
141+
}
142+
callback(response);
143+
},
144+
completion: function(cmd, arg, line, callback) {
145+
callback(shell.bestMatch(arg, ['world', 'josh']))
146+
}
147+
});</pre>
148+
<p>To add a command, simply call <code>shell.setCommandHandler</code> and provide it at least an
149+
<code>exec</code> handler, and optionally a <code> completion</code> handler.</p>
150+
151+
<p>
152+
<code>exec</code> expects a function that takes the name of the called command, an array of whitespace separated arguments to the command and a callback that MUST be called with an html string to output to the console. For our toy command we implement a command named
153+
<code>hello</code> which understands arguments <em>josh</em> and
154+
<em>world</em> and has alternate outputs for no arguments and unknown arguments.</p>
155+
156+
<p>
157+
<code>completion</code> expects a function that takes the current command, the current argument being completed, the complete line (since the cursor may not be at the tail) and a callback that MUST be called either with a completion data structure. The format of this data structure is:
158+
</p>
159+
<pre>{
160+
completion: {string to append to current argument},
161+
suggestions: [{array of possible completions},...]
162+
}</pre>
163+
<p>Here are some expected completions:</p>
164+
<ul>
165+
<li><code>hello &lt;TAB&gt;</code> => <code>{completion:null,suggestions:['world', 'josh']}</code></li>
166+
<li><code>hello wo&lt;TAB&gt;</code> => <code>{completion:'rld',suggestions:['world']}</code></li>
167+
<li><code>hello x&lt;TAB&gt;</code> => <code>{completion:'',suggestions:[]}</code></li>
168+
</ul>
169+
<p>To simplify this process of finding the partial strings and possible completions, Shell offers a method
170+
<code>bestMatch</code> which expects as input the partial to match (our arg to the completion handler) and a list of all possible completions and it will narrow down what to append to the partial and what suggestions to show.
171+
</p>
172+
173+
<h2>Turning it on</h2>
174+
175+
<p>Now that we've added our custom behavior to
176+
<code>Josh.Shell</code>, all we have to do is activate the shell to render the prompt and start capturing all keystrokes via readline (i.e. if you want the shell to only capture keys while the shell has focus, it is up to you to write focus and blur code to activate and deactivate the shell.)
177+
</p>
178+
<pre>shell.activate();</pre>
179+
<p>And that's all there is to getting a custom Bash-like shell in your web page.</p>
180+
</section>
181+
</div>
182+
<!--[if !IE]>
183+
<script>fixScale(document);</script><![endif]-->
184+
185+
</body>
186+
</html>

‎index.html

Copy file name to clipboardExpand all lines: index.html
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,14 @@ <h1>josh.js 0.2</h1>
9999
</li>
100100
</ul>
101101

102-
<h2>Demo</h2>
102+
<h2>Live Demo</h2>
103103

104104
<p id="demo"><em>Hit the <span style="color: #ffcc00; font-weight: bold; font-size: 1.2em">~</span> key to show a demo console ( <a href="docs/example.html">Annotated source of demo</a>)</em></p>
105105

106+
<h2>Tutorials</h2>
107+
<ul>
108+
<li><a href="helloworld.html">Hello world</a> - put a console on a web page and add a new custom command with completion</li>
109+
</ul>
106110
<h2>License</h2>
107111

108112
<p>josh.js is licensed under the Apache 2.0 License</p>

‎stylesheets/styles.css

Copy file name to clipboardExpand all lines: stylesheets/styles.css
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,6 @@ dt {
712712
max-width: 650px;
713713
margin: 0 auto;
714714
padding: 0 10px;
715-
background: blue;
716715
margin: 6px auto;
717716
}
718717
#header nav li {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.