Skip to content

Commit 0054bb8

Browse files
committed
cleanup
1 parent eccc98b commit 0054bb8

File tree

7 files changed

+163
-85
lines changed

7 files changed

+163
-85
lines changed

demo/kitchen-sink/doclist.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,8 @@ function loadDoc(name, callback) {
169169
});
170170
}
171171

172-
// callback is called with the error message from PUT (if any)
173172
function saveDoc(name, callback) {
174-
var doc = fileCache[name];
173+
var doc = fileCache[name] || name;
175174
if (!doc || !doc.session)
176175
return callback("Unknown document: " + name);
177176

@@ -182,9 +181,24 @@ function saveDoc(name, callback) {
182181
else if (parts[0] == "ace")
183182
path = "lib/" + path;
184183

185-
net.request('PUT', path, doc.session.getValue(), callback);
184+
upload(path, doc.session.getValue(), callback);
186185
}
187186

187+
function upload(url, data, callback) {
188+
url = net.qualifyURL(url);
189+
if (!/https?:/.test(url))
190+
return callback(new Error("Unsupported url scheme"));
191+
var xhr = new XMLHttpRequest();
192+
xhr.open("PUT", url, true);
193+
xhr.onreadystatechange = function () {
194+
if (xhr.readyState === 4) {
195+
callback(!/^2../.test(xhr.status));
196+
}
197+
};
198+
xhr.send(data);
199+
};
200+
201+
188202
module.exports = {
189203
fileCache: fileCache,
190204
docs: sort(prepareDocList(docs)),

lib/ace/lib/net.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,17 @@ define(function(require, exports, module) {
99
"use strict";
1010
var dom = require("./dom");
1111

12-
exports.request = function (verb, url, data, callback) {
12+
exports.get = function (url, callback) {
1313
var xhr = new XMLHttpRequest();
14-
xhr.open(verb, url, true);
14+
xhr.open('GET', url, true);
1515
xhr.onreadystatechange = function () {
1616
//Do not explicitly handle errors, those should be
1717
//visible via console output in the browser.
1818
if (xhr.readyState === 4) {
1919
callback(xhr.responseText);
2020
}
2121
};
22-
xhr.send(data);
23-
};
24-
25-
exports.get = function (url, callback) {
26-
this.request('GET', url, null, callback);
22+
xhr.send(null);
2723
};
2824

2925
exports.loadScript = function(path, callback) {

lib/ace/mode/abap_highlight_rules.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ var AbapHighlightRules = function() {
126126
{token : "string", regex : "`", next : "start"},
127127
{defaultToken : "string"}
128128
]
129-
}
129+
};
130130
};
131131
oop.inherits(AbapHighlightRules, TextHighlightRules);
132132

static.js

+90-27
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,100 @@ var http = require("http")
1010

1111
// compatibility with node 0.6
1212
if (!fs.exists)
13-
fs.exists = path.exists;
14-
15-
http.createServer(function(request, response) {
16-
17-
var uri = url.parse(request.url).pathname
18-
, filename = path.join(process.cwd(), uri);
19-
20-
fs.exists(filename, function(exists) {
21-
if(!exists) {
22-
response.writeHead(404, {"Content-Type": "text/plain"});
23-
response.write("404 Not Found\n");
24-
response.end();
25-
return;
13+
fs.exists = path.exists;
14+
15+
var allowSave = process.argv.indexOf("--allow-save") != -1;
16+
17+
http.createServer(function(req, res) {
18+
var uri = url.parse(req.url).pathname
19+
, filename = path.join(process.cwd(), uri);
20+
21+
if (req.method == "PUT") {
22+
if (!allowSave)
23+
return error(res, 404, "Saving not allowed pass --allow-save to enable");
24+
save(req, res, filename);
2625
}
2726

28-
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
27+
fs.exists(filename, function(exists) {
28+
if (!exists)
29+
return error(res, 404, "404 Not Found\n");
30+
31+
if (fs.statSync(filename).isDirectory()) {
32+
var files = fs.readdirSync(filename);
33+
res.writeHead(200, {"Content-Type": "text/html"});
34+
35+
files.push(".", "..");
36+
var html = files.map(function(name) {
37+
var href = uri + "/" + name;
38+
href = href.replace(/[\/\\]+/g, "/").replace(/\/$/g, "");
39+
if (fs.statSync(filename + "/" + name + "/").isDirectory())
40+
href += "/";
41+
return "<a href='" + href + "'>" + name + "</a><br>";
42+
});
2943

30-
fs.readFile(filename, "binary", function(err, file) {
31-
if(err) {
32-
response.writeHead(500, {"Content-Type": "text/plain"});
33-
response.write(err + "\n");
34-
response.end();
35-
return;
36-
}
44+
res._hasBody && res.write(html.join(""));
45+
res.end();
46+
return;
47+
}
3748

38-
var contentType = mime.lookup(filename) || "text/plain";
39-
response.writeHead(200, {"Content-Type": contentType});
40-
response.write(file, "binary");
41-
response.end();
49+
fs.readFile(filename, "binary", function(err, file) {
50+
if (err) {
51+
res.writeHead(500, { "Content-Type": "text/plain" });
52+
res.write(err + "\n");
53+
res.end();
54+
return;
55+
}
56+
57+
var contentType = mime.lookup(filename) || "text/plain";
58+
res.writeHead(200, { "Content-Type": contentType });
59+
res.write(file, "binary");
60+
res.end();
61+
});
4262
});
43-
});
4463
}).listen(port, ip);
4564

46-
console.log("http://localhost:" + port);
65+
function error(res, status, message, error) {
66+
console.error(error || message);
67+
res.writeHead(status, { "Content-Type": "text/plain" });
68+
res.write(message);
69+
res.end();
70+
}
71+
72+
function save(req, res, filePath) {
73+
var data = "";
74+
req.on("data", function(chunk) {
75+
data += chunk;
76+
});
77+
req.on("error", function() {
78+
error(res, 404, "Could't save file");
79+
});
80+
req.on("end", function() {
81+
try {
82+
fs.writeFileSync(filePath, data);
83+
}
84+
catch (e) {
85+
return error(res, 404, "Could't save file", e);
86+
}
87+
res.statusCode = 200;
88+
res.end("OK");
89+
});
90+
}
91+
92+
function getLocalIps() {
93+
var os = require("os");
94+
95+
var interfaces = os.networkInterfaces ? os.networkInterfaces() : {};
96+
var addresses = [];
97+
for (var k in interfaces) {
98+
for (var k2 in interfaces[k]) {
99+
var address = interfaces[k][k2];
100+
if (address.family === "IPv4" && !address.internal) {
101+
addresses.push(address.address);
102+
}
103+
}
104+
}
105+
return addresses;
106+
}
107+
108+
console.log("http://" + (ip == "0.0.0.0" ? getLocalIps()[0] : ip) + ":" + port);
109+

static.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,13 @@ def command():
263263
puttable = set(path.abspath(p) for p in
264264
options.puttable.replace(","," ").split())
265265
if puttable and host not in ('127.0.0.1', 'localhost'):
266-
sys.exit("Permitting PUT access for non-localhost connections is unwise.")
266+
print("Permitting PUT access for non-localhost connections may be unwise.")
267267

268268
options.rootdir = path.abspath(options.rootdir)
269269

270270
for p in puttable:
271-
if not p.startswith(options.rootdir):
272-
sys.exit("puttable path '%s' not under root '%s'" % (p, options.rootdir))
271+
if not p.startswith(options.rootdir):
272+
sys.exit("puttable path '%s' not under root '%s'" % (p, options.rootdir))
273273

274274
# cut off root prefix from puttable paths
275275
puttable = set(p[len(options.rootdir):] for p in puttable)
@@ -283,13 +283,12 @@ def command():
283283
print "Serving %s to http://%s:%d" % (options.rootdir, host, port)
284284
if puttable:
285285
print("The following paths (relative to server root) may be "+
286-
"OVERWRITTEN via HTTP PUT.\n"+
287-
"I HOPE EVERY USER ON THIS SYSTEM IS TRUSTED!")
286+
"OVERWRITTEN via HTTP PUT.")
288287
for p in puttable:
289288
print p
290289
make_server(host, port, app).serve_forever()
291290
except KeyboardInterrupt, ki:
292-
print "Cio, baby!"
291+
print "Ciao, baby!"
293292
except:
294293
sys.exit("Problem initializing server: %s" % sys.exc_info()[1])
295294

tool/mode_creator.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
<select id="modeEl" size="1"></select>
6060
<input type="button" value="&#10227;" title="sync" id="syncToMode"></select>
6161
<span id="tablist"></span>
62-
<input type="button" value="Save" id="uploadToServer1"></select>
62+
<input type="button" value="Save" id="saveButton1"></select>
6363
<span class="separator-h"></span>
6464
<label for="autorunEl">live preview</label>
6565
<input type="checkbox" label="autorun" id="autorunEl" checked>
@@ -71,7 +71,7 @@
7171
<label for="themeEl">Theme</label>
7272
<select id="themeEl" size="1" value="textmate"></select>
7373
<span class="separator-h"></span>
74-
<input type="button" value="Save" id="uploadToServer2"></select>
74+
<input type="button" value="Save" id="saveButton2"></select>
7575
<label for="doc">Document</label>
7676
<select id="doc" size="1"></select>
7777
</div>

tool/mode_creator.js

+45-39
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,16 @@ util.bindDropdown("doc", function(value) {
5353
doclist.loadDoc(value, function(session) {
5454
if (session) {
5555
editor2.setSession(session);
56-
uploadEl2.disabled = session.getUndoManager().isClean();
56+
session.getUndoManager().markClean();
57+
updateSaveButtonState(null, editor2);
5758
}
5859
});
5960
});
6061

6162
var modeEl = document.getElementById("modeEl");
6263
util.fillDropdown(modeEl, modelist.modes);
6364
var modeSessions = {};
64-
var savedLeadingComments = "";
65+
6566
util.bindDropdown(modeEl, function(value) {
6667
if (modeSessions[value]) {
6768
editor1.setSession(modeSessions[value]);
@@ -70,17 +71,18 @@ util.bindDropdown(modeEl, function(value) {
7071
}
7172
var hp = "./lib/ace/mode/" + value + "_highlight_rules.js";
7273
net.get(hp, function(text) {
73-
uploadEl1.disabled = true;
74-
savedLeadingComments = text;
75-
text = util.stripLeadingComments(text);
76-
savedLeadingComments = savedLeadingComments.substr(0, savedLeadingComments.length - text.length);
77-
7874
var session = new EditSession(text);
7975
session.setUndoManager(new UndoManager());
76+
8077
modeSessions[value] = session;
81-
session.setMode("ace/mode/javascript");
78+
session.setMode("ace/mode/javascript", function() {
79+
if (session.getLine(0).match(/^\s*\//))
80+
session.toggleFoldWidget(0); // fold licence comment
81+
});
8282

8383
editor1.setSession(modeSessions[value]);
84+
session.getUndoManager().markClean();
85+
updateSaveButtonState(null, editor1);
8486
schedule();
8587
});
8688
});
@@ -91,43 +93,47 @@ document.getElementById("syncToMode").onclick = function() {
9193
run();
9294
};
9395

94-
var uploadEl1 = document.getElementById("uploadToServer1");
95-
var uploadEl2 = document.getElementById("uploadToServer2");
96-
uploadEl1.onclick = function() {
97-
var text = savedLeadingComments + editor1.getValue();
98-
var url = "./lib/ace/mode/" + modeEl.value + "_highlight_rules.js";
99-
net.request('PUT', url, text, function(text) {
100-
handle_put_result(text, editor1, uploadEl1);
96+
editor1.saveButton = document.getElementById("saveButton1");
97+
editor2.saveButton = document.getElementById("saveButton2");
98+
editor1.saveButton.editor = editor1;
99+
editor2.saveButton.editor = editor2;
100+
101+
editor1.saveButton.onclick = function() {
102+
doclist.saveDoc({
103+
path: "./lib/ace/mode/" + modeEl.value + "_highlight_rules.js",
104+
session: editor1.session
105+
}, function(err) {
106+
handleSaveResult(err, editor1);
101107
});
102108
};
103-
editor1.commands.bindKey("Ctrl-S", uploadEl1.onclick);
104-
uploadEl2.onclick = function() {
105-
doclist.saveDoc(docEl.value, function(text) {
106-
handle_put_result(text, editor2, uploadEl2);
109+
editor1.commands.bindKey({
110+
win: "Ctrl-S", mac: "Cmd-s"
111+
}, editor1.saveButton.onclick);
112+
editor2.saveButton.onclick = function() {
113+
doclist.saveDoc(docEl.value, function(err) {
114+
handleSaveResult(err, editor2);
107115
});
108116
};
109-
editor2.commands.bindKey("Ctrl-S", uploadEl2.onclick);
110-
editor1.on('change', function() {
111-
uploadEl1.disabled = false;
112-
});
113-
editor2.on('change', function() {
114-
uploadEl2.disabled = false;
115-
});
117+
editor2.commands.bindKey({
118+
win: "Ctrl-S", mac: "Cmd-s"
119+
}, editor2.saveButton.onclick);
120+
function updateSaveButtonState(e, editor){
121+
editor.saveButton.disabled = editor.session.getUndoManager().isClean();
122+
}
123+
editor1.on("input", updateSaveButtonState);
124+
editor2.on("input", updateSaveButtonState);
116125

117-
function handle_put_result(text, editor, buttonEl) {
118-
text = text.trim();
119-
if (text.length == 0) {
120-
buttonEl.disabled = true;
121-
editor.getSession().getUndoManager().markClean();
122-
} else {
123-
if (text.indexOf("405") == 0) {
124-
log("Write access to this file is disabled.\n"+
125-
"To enable saving your changes to disk, clone the Ace repository"+
126-
"\nand run the included static.py web server with the option\n"+
127-
"--puttable='lib/ace/mode/*_highlight_rules.js,demo/kitchen-sink/docs/*'");
128-
} else
129-
log(text);
126+
function handleSaveResult(err, editor) {
127+
if (err) {
128+
return log(
129+
"Write access to this file is disabled.\n"+
130+
"To enable saving your changes to disk, clone the Ace repository\n"+
131+
"and run the included web server with the --allow-write option\n"+
132+
"`node static.js --allow-write` or `static.py --puttable=*`"
133+
);
130134
}
135+
editor.session.getUndoManager().markClean();
136+
updateSaveButtonState(null, editor);
131137
}
132138

133139
document.getElementById("perfTest").onclick = function() {

0 commit comments

Comments
 (0)