Permalink
Browse files

First commit

  • Loading branch information...
0 parents commit 12f7e955c8ddae18b251d11db6b01743fa71a085 Mike Mattozzi committed Feb 15, 2011
Showing with 338 additions and 0 deletions.
  1. +4 −0 README.md
  2. +58 −0 SimpleStream.js
  3. +121 −0 index.html
  4. +16 −0 jquery-1.5.min.js
  5. +11 −0 package.json
  6. +5 −0 webrepl-test.js
  7. +123 −0 webrepl.js
@@ -0,0 +1,4 @@
+var webrepl = require('./webrepl');
+webrepl.start(8080).context.foo = { 'bar' : 1 };
+
+Enjoy using a repl via your browser!
@@ -0,0 +1,58 @@
+var util = require('util');
+var events = require('events');
+
+function SimpleStream() {
+ this.messages = [];
+ events.EventEmitter.call(this);
+}
+
+util.inherits(SimpleStream, events.EventEmitter);
+
+SimpleStream.prototype.readable = true;
+
+SimpleStream.prototype.setEncoding = function(encoding) {
+ console.log("unexpected set encoding");
+};
+
+SimpleStream.prototype.pause = function() {
+ console.log("unexpected pause");
+};
+
+SimpleStream.prototype.resume = function() {
+};
+
+SimpleStream.prototype.destroy = function() {
+ console.log("unexpected destroy");
+};
+
+SimpleStream.prototype.destroySoon = function() {
+ console.log("unexpected destroySoon");
+};
+
+SimpleStream.prototype.destroy = function(destination) {
+ console.log("unexpected pipe");
+};
+
+SimpleStream.prototype.writable = true;
+
+SimpleStream.prototype.write = function(string, encoding) {
+ console.log("unexpected write string");
+};
+
+SimpleStream.prototype.write = function(data) {
+ this.messages.push(data);
+};
+
+SimpleStream.prototype.end = function() {
+ console.log("unexpected end");
+};
+
+SimpleStream.prototype.end = function(string, encoding) {
+ console.log("unexpected end string");
+};
+
+SimpleStream.prototype.end = function(buffer) {
+ console.log("unexpected end buffer");
+};
+
+module.exports = SimpleStream;
@@ -0,0 +1,121 @@
+<html>
+ <head>
+ <style>
+ body {
+ background-color: #EBE8E0;
+ margin-top: 0px;
+ }
+
+ input#in {
+ width:92%;
+ margin-left: 4%;
+ font-size:30px;
+ font-family:Verdana;
+ color:#0B5C7B;
+ border: 2px solid white;
+ box-shadow: 5px 5px 5px #888;
+ -moz-box-shadow: 5px 5px 5px #888;
+ -webkit-box-shadow: 5px 5px 5px #888;
+ background-color:white;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ outline: 0 none;
+ }
+
+ #out {
+ font-size:18px;
+ font-family:Verdana;
+ color:#0B5C7B;
+ }
+
+ div#main-container {
+ background-color:white;
+ margin-top:30px;
+ margin-left:4%;
+ padding: 2% 2% 2% 2%;
+ border-top-left-radius: 15px;
+ border-top-right-radius: 15px;
+ border-bottom-left-radius: 15px;
+ border-bottom-right-radius: 15px;
+ width:88%;
+ }
+
+ div#header {
+ font-size:18px;
+ font-family:Verdana;
+ color:#0B5C7B;
+ background-color:white;
+ margin-top:0px;
+ margin-left:4%;
+ margin-bottom: 12px;
+ padding-left: 2%;
+ padding-right: 2%;
+ padding-top: 4px;
+ padding-bottom: 8px;
+ border-bottom-left-radius: 15px;
+ border-bottom-right-radius: 15px;
+ width:88%;
+ }
+
+ div.replOut {
+ color: green;
+ }
+
+ div.replIn {
+ color: #0B5C7B;
+ }
+
+ div.replErr {
+ color: red;
+ }
+
+ </style>
+ <script src="jquery-1.5.min.js" type="text/javascript"></script>
+
+ <script type="text/javascript">
+
+ var blurbHidden = false;
+
+ $(document).ready(function() {
+ $('#in').keypress(function(event) {
+ if (event.which == '13') {
+ event.preventDefault();
+ commandEntered();
+ }
+ });
+
+ $.get('info', function(data) {
+ $('#header').prepend($("<div>[" + data.pid + '] ' + data.name + "</div>"));
+ }, 'json');
+ });
+
+ function commandEntered() {
+ if (! blurbHidden) {
+ $('#blurb').hide();
+ blurbHidden = true;
+ }
+ var command = $('#in').val();
+ $('#out').prepend($("<div class='replIn'>" + command + "</div>"));
+ $.post('repl', command, function(data) {
+ $('#in').val('');
+ $.get('repl', function(resData) {
+ var type = 'replOut';
+ if (resData.match(/.*Error:/)) {
+ type = 'replErr';
+ }
+ $('#out').prepend($("<div class='" + type + "'>" + resData + "</div>"));
+ });
+ }, "text");
+ }
+
+ </script>
+ </head>
+ <body>
+ <div id="header"></div>
+ <input id="in" type="text" />
+ <div id="main-container">
+ <div id="out"><div id="blurb">web-repl: Type commands in the above box to execute in this javascript process.</div></div>
+ </div>
+ </body>
+</html>

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,11 @@
+{
+ "name" : "webrepl",
+ "version" : "0.1.0",
+ "description" : "Serve a repl for a node process via a web console",
+ "author" : "Mike Mattozzi <mike.mattozzi@gmail.com>",
+ "main" : "./webrepl.js",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/mmattozzi/webrepl.js.git"
+ }
+}
@@ -0,0 +1,5 @@
+var webrepl = require('./webrepl');
+
+var foo = { 'bar': 1, 'two': 'dos', 'today': new Date() };
+
+webrepl.start(8080).context.foo = foo;
@@ -0,0 +1,123 @@
+var SimpleStream = require('./SimpleStream');
+var repl = require('repl');
+var http = require('http');
+var fs = require('fs');
+var util = require('util');
+
+var ReplHttpServer = function ReplHttpServer(prompt, stream, replServer) {
+ this.running = false;
+ this.prompt = prompt;
+ this.stream = stream;
+ this.replServer = replServer;
+};
+
+ReplHttpServer.prototype.start = function(port, hostname, stream, replServer) {
+ var self = this;
+ self.server = http.createServer(function(req, res) { self.route(req, res); });
+ self.server.listen(port, hostname);
+ return self;
+};
+
+ReplHttpServer.prototype.route = function(req, res) {
+ var stream = this.stream;
+
+ var match = null;
+ if (req.url.match(/^\/repl/)) {
+ if (req.method === 'GET') {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ var resBody = '';
+ while (stream.messages.length > 0) {
+ var msg = stream.messages.shift();
+ if (! msg.match("^" + this.prompt)) {
+ resBody += msg;
+ }
+ }
+ res.end(resBody);
+ } else if (req.method === 'POST') {
+ var allData = "";
+ req.on('data', function(data) {
+ allData += data;
+ });
+ req.on('end', function() {
+ if (stream.emit('data', allData)) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ res.end();
+ } else {
+ res.writeHead(500, {'Content-Type': 'text/plain'});
+ res.end();
+ }
+ });
+ }
+ } else if ((match = req.url.match(/^\/context\/(.*)/))) {
+ var obj = eval('this.replServer.context.' + match[1]);
+ if (obj) {
+ res.writeHead(200, {'Content-Type': 'application/json'});
+ res.end(JSON.stringify(obj));
+ } else {
+ res.writeHeader(404);
+ res.end();
+ }
+ } else if (req.url.match(/^\/info/)) {
+ var name = (process.argv.length > 1 ? process.argv[1] : process.argv[0]);
+ var info = { 'pid': process.pid, 'name': name };
+ res.writeHead(200, {'Content-Type': 'application/json'});
+ res.end(JSON.stringify(info));
+ } else {
+ match = req.url.match(/\/(.*)/);
+ if (match) {
+ var file = match[1];
+ if (file === '') { file = 'index.html'; }
+ this.serveFile(file, res);
+ }
+ }
+};
+
+ReplHttpServer.prototype.serveFile = function(file, response) {
+ function contentType(file) {
+ if (file.match(/.js$/)) {
+ return "application/x-javascript";
+ } else if (file.match(/.html$/)) {
+ return "text/html";
+ }
+ return "text/plain";
+ }
+
+ fs.stat(file, function(err, stat) {
+ if (err) {
+ response.writeHead(404, {"Content-Type": "text/plain"});
+ response.write("Cannot find file: " + file);
+ response.end();
+ return;
+ }
+
+ fs.readFile(file, "binary", function (err, data) {
+ if (err) {
+ response.writeHead(500, {"Content-Type": contentType(file) });
+ response.write("Error opening file " + file + ": " + err);
+ } else {
+ response.writeHead(200, { 'Content-Type': contentType(file), 'Content-Length': data.length });
+ response.write(data, "binary");
+ }
+ response.end();
+ });
+ });
+};
+
+/**
+ * Starts a repl served via a web console.
+ * @param {Integer} port Port to serve web console
+ * @param {String} hostname Bind address of web console (optional)
+ * @return Return the REPLServer. Context can be set on this variable.
+ */
+var start = function(port, hostname) {
+ var stream = new SimpleStream();
+ var prompt = 'node> ';
+ var rs = new repl.REPLServer(prompt, stream);
+ var replHttpServer = new ReplHttpServer(prompt, stream, rs);
+ replHttpServer.start(port, hostname);
+ return rs;
+};
+
+var exports = { 'start' : start };
+
+module.exports = exports;

0 comments on commit 12f7e95

Please sign in to comment.