static: add optional save shortcut support to playground
If enabled (via the "enableShortcuts" option), Ctrl+S/Cmd+S now saves/shares the playground snippet and initiates a download. Credit to Alexander Kucherenko (see golang.org/cl/35950). Updates golang/go#15378. Change-Id: I8a2d733c25e4c95787fbe1f5ac00fa1befbb4693 Reviewed-on: https://go-review.googlesource.com/36486 Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
parent
1977f1cf7d
commit
69cfa78961
|
|
@ -169,8 +169,9 @@ function PlaygroundOutput(el) {
|
||||||
cl = write.Kind;
|
cl = write.Kind;
|
||||||
|
|
||||||
var m = write.Body;
|
var m = write.Body;
|
||||||
if (write.Kind == 'end')
|
if (write.Kind == 'end') {
|
||||||
m = '\nProgram exited' + (m?(': '+m):'.');
|
m = '\nProgram exited' + (m?(': '+m):'.');
|
||||||
|
}
|
||||||
|
|
||||||
if (m.indexOf('IMAGE:') === 0) {
|
if (m.indexOf('IMAGE:') === 0) {
|
||||||
// TODO(adg): buffer all writes before creating image
|
// TODO(adg): buffer all writes before creating image
|
||||||
|
|
@ -235,6 +236,7 @@ function PlaygroundOutput(el) {
|
||||||
// toysEl - toys select element (optional)
|
// toysEl - toys select element (optional)
|
||||||
// enableHistory - enable using HTML5 history API (optional)
|
// enableHistory - enable using HTML5 history API (optional)
|
||||||
// transport - playground transport to use (default is HTTPTransport)
|
// transport - playground transport to use (default is HTTPTransport)
|
||||||
|
// enableShortcuts - whether to enable shortcuts (Ctrl+S/Cmd+S to save) (default is false)
|
||||||
function playground(opts) {
|
function playground(opts) {
|
||||||
var code = $(opts.codeEl);
|
var code = $(opts.codeEl);
|
||||||
var transport = opts['transport'] || new HTTPTransport();
|
var transport = opts['transport'] || new HTTPTransport();
|
||||||
|
|
@ -274,7 +276,25 @@ function PlaygroundOutput(el) {
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(cbro): e is a jQuery event, not a DOM event.
|
||||||
|
function handleSaveShortcut(e) {
|
||||||
|
if (e.isDefaultPrevented()) return false;
|
||||||
|
if (!e.metaKey && !e.ctrlKey) return false;
|
||||||
|
if (e.key != "S" && e.key != "s") return false;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Share and save
|
||||||
|
share(function(url) {
|
||||||
|
window.location.href = url + ".go?download=true";
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function keyHandler(e) {
|
function keyHandler(e) {
|
||||||
|
if (opts.enableShortcuts && handleSaveShortcut(e)) return;
|
||||||
|
|
||||||
if (e.keyCode == 9 && !e.ctrlKey) { // tab (but not ctrl-tab)
|
if (e.keyCode == 9 && !e.ctrlKey) { // tab (but not ctrl-tab)
|
||||||
insertTabs(1);
|
insertTabs(1);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -369,18 +389,15 @@ function PlaygroundOutput(el) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(opts.runEl).click(run);
|
var shareURL; // jQuery element to show the shared URL.
|
||||||
$(opts.fmtEl).click(fmt);
|
var sharing = false; // true if there is a pending request.
|
||||||
|
var shareCallbacks = [];
|
||||||
|
function share(opt_callback) {
|
||||||
|
if (opt_callback) shareCallbacks.push(opt_callback);
|
||||||
|
|
||||||
if (opts.shareEl !== null && (opts.shareURLEl !== null || opts.shareRedirect !== null)) {
|
|
||||||
var shareURL;
|
|
||||||
if (opts.shareURLEl) {
|
|
||||||
shareURL = $(opts.shareURLEl).hide();
|
|
||||||
}
|
|
||||||
var sharing = false;
|
|
||||||
$(opts.shareEl).click(function() {
|
|
||||||
if (sharing) return;
|
if (sharing) return;
|
||||||
sharing = true;
|
sharing = true;
|
||||||
|
|
||||||
var sharingData = body();
|
var sharingData = body();
|
||||||
$.ajax("/share", {
|
$.ajax("/share", {
|
||||||
processData: false,
|
processData: false,
|
||||||
|
|
@ -395,9 +412,15 @@ function PlaygroundOutput(el) {
|
||||||
if (opts.shareRedirect) {
|
if (opts.shareRedirect) {
|
||||||
window.location = opts.shareRedirect + xhr.responseText;
|
window.location = opts.shareRedirect + xhr.responseText;
|
||||||
}
|
}
|
||||||
if (shareURL) {
|
|
||||||
var path = "/p/" + xhr.responseText;
|
var path = "/p/" + xhr.responseText;
|
||||||
var url = origin(window.location) + path;
|
var url = origin(window.location) + path;
|
||||||
|
|
||||||
|
for (var i = 0; i < shareCallbacks.length; i++) {
|
||||||
|
shareCallbacks[i](url);
|
||||||
|
}
|
||||||
|
shareCallbacks = [];
|
||||||
|
|
||||||
|
if (shareURL) {
|
||||||
shareURL.show().val(url).focus().select();
|
shareURL.show().val(url).focus().select();
|
||||||
|
|
||||||
if (rewriteHistory) {
|
if (rewriteHistory) {
|
||||||
|
|
@ -408,7 +431,16 @@ function PlaygroundOutput(el) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
$(opts.runEl).click(run);
|
||||||
|
$(opts.fmtEl).click(fmt);
|
||||||
|
|
||||||
|
if (opts.shareEl !== null && (opts.shareURLEl !== null || opts.shareRedirect !== null)) {
|
||||||
|
if (opts.shareURLEl) {
|
||||||
|
shareURL = $(opts.shareURLEl).hide();
|
||||||
|
}
|
||||||
|
$(opts.shareEl).click(share);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.toysEl !== null) {
|
if (opts.toysEl !== null) {
|
||||||
|
|
|
||||||
|
|
@ -2379,8 +2379,9 @@ function PlaygroundOutput(el) {
|
||||||
cl = write.Kind;
|
cl = write.Kind;
|
||||||
|
|
||||||
var m = write.Body;
|
var m = write.Body;
|
||||||
if (write.Kind == 'end')
|
if (write.Kind == 'end') {
|
||||||
m = '\nProgram exited' + (m?(': '+m):'.');
|
m = '\nProgram exited' + (m?(': '+m):'.');
|
||||||
|
}
|
||||||
|
|
||||||
if (m.indexOf('IMAGE:') === 0) {
|
if (m.indexOf('IMAGE:') === 0) {
|
||||||
// TODO(adg): buffer all writes before creating image
|
// TODO(adg): buffer all writes before creating image
|
||||||
|
|
@ -2445,6 +2446,7 @@ function PlaygroundOutput(el) {
|
||||||
// toysEl - toys select element (optional)
|
// toysEl - toys select element (optional)
|
||||||
// enableHistory - enable using HTML5 history API (optional)
|
// enableHistory - enable using HTML5 history API (optional)
|
||||||
// transport - playground transport to use (default is HTTPTransport)
|
// transport - playground transport to use (default is HTTPTransport)
|
||||||
|
// enableShortcuts - whether to enable shortcuts (Ctrl+S/Cmd+S to save) (default is false)
|
||||||
function playground(opts) {
|
function playground(opts) {
|
||||||
var code = $(opts.codeEl);
|
var code = $(opts.codeEl);
|
||||||
var transport = opts['transport'] || new HTTPTransport();
|
var transport = opts['transport'] || new HTTPTransport();
|
||||||
|
|
@ -2484,7 +2486,25 @@ function PlaygroundOutput(el) {
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(cbro): e is a jQuery event, not a DOM event.
|
||||||
|
function handleSaveShortcut(e) {
|
||||||
|
if (e.isDefaultPrevented()) return false;
|
||||||
|
if (!e.metaKey && !e.ctrlKey) return false;
|
||||||
|
if (e.key != "S" && e.key != "s") return false;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Share and save
|
||||||
|
share(function(url) {
|
||||||
|
window.location.href = url + ".go?download=true";
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function keyHandler(e) {
|
function keyHandler(e) {
|
||||||
|
if (opts.enableShortcuts && handleSaveShortcut(e)) return;
|
||||||
|
|
||||||
if (e.keyCode == 9 && !e.ctrlKey) { // tab (but not ctrl-tab)
|
if (e.keyCode == 9 && !e.ctrlKey) { // tab (but not ctrl-tab)
|
||||||
insertTabs(1);
|
insertTabs(1);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -2579,18 +2599,15 @@ function PlaygroundOutput(el) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(opts.runEl).click(run);
|
var shareURL; // jQuery element to show the shared URL.
|
||||||
$(opts.fmtEl).click(fmt);
|
var sharing = false; // true if there is a pending request.
|
||||||
|
var shareCallbacks = [];
|
||||||
|
function share(opt_callback) {
|
||||||
|
if (opt_callback) shareCallbacks.push(opt_callback);
|
||||||
|
|
||||||
if (opts.shareEl !== null && (opts.shareURLEl !== null || opts.shareRedirect !== null)) {
|
|
||||||
var shareURL;
|
|
||||||
if (opts.shareURLEl) {
|
|
||||||
shareURL = $(opts.shareURLEl).hide();
|
|
||||||
}
|
|
||||||
var sharing = false;
|
|
||||||
$(opts.shareEl).click(function() {
|
|
||||||
if (sharing) return;
|
if (sharing) return;
|
||||||
sharing = true;
|
sharing = true;
|
||||||
|
|
||||||
var sharingData = body();
|
var sharingData = body();
|
||||||
$.ajax("/share", {
|
$.ajax("/share", {
|
||||||
processData: false,
|
processData: false,
|
||||||
|
|
@ -2605,9 +2622,15 @@ function PlaygroundOutput(el) {
|
||||||
if (opts.shareRedirect) {
|
if (opts.shareRedirect) {
|
||||||
window.location = opts.shareRedirect + xhr.responseText;
|
window.location = opts.shareRedirect + xhr.responseText;
|
||||||
}
|
}
|
||||||
if (shareURL) {
|
|
||||||
var path = "/p/" + xhr.responseText;
|
var path = "/p/" + xhr.responseText;
|
||||||
var url = origin(window.location) + path;
|
var url = origin(window.location) + path;
|
||||||
|
|
||||||
|
for (var i = 0; i < shareCallbacks.length; i++) {
|
||||||
|
shareCallbacks[i](url);
|
||||||
|
}
|
||||||
|
shareCallbacks = [];
|
||||||
|
|
||||||
|
if (shareURL) {
|
||||||
shareURL.show().val(url).focus().select();
|
shareURL.show().val(url).focus().select();
|
||||||
|
|
||||||
if (rewriteHistory) {
|
if (rewriteHistory) {
|
||||||
|
|
@ -2618,7 +2641,16 @@ function PlaygroundOutput(el) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
$(opts.runEl).click(run);
|
||||||
|
$(opts.fmtEl).click(fmt);
|
||||||
|
|
||||||
|
if (opts.shareEl !== null && (opts.shareURLEl !== null || opts.shareRedirect !== null)) {
|
||||||
|
if (opts.shareURLEl) {
|
||||||
|
shareURL = $(opts.shareURLEl).hide();
|
||||||
|
}
|
||||||
|
$(opts.shareEl).click(share);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.toysEl !== null) {
|
if (opts.toysEl !== null) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue