Work in progress on embeddable CEs
This commit is contained in:
parent
a5c268cbb8
commit
0cda1b839a
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectTasksOptions" suppressed-tasks="Less" />
|
||||
</project>
|
10
app.js
10
app.js
|
@ -463,6 +463,15 @@ function shortUrlHandler(req, res, next) {
|
|||
});
|
||||
}
|
||||
|
||||
// TODO: write the info here directly instead of redirecting...
|
||||
function embeddedHandler(req, res, next) {
|
||||
res.writeHead(301, {
|
||||
Location: 'embed.html',
|
||||
'Cache-Control': 'public'
|
||||
});
|
||||
res.end();
|
||||
}
|
||||
|
||||
var clientOptionsHandler = new ClientOptionsHandler(fileSources);
|
||||
var apiHandler = new ApiHandler();
|
||||
var compileHandler = new CompileHandler();
|
||||
|
@ -515,6 +524,7 @@ findCompilers().then(function (compilers) {
|
|||
.use('/source', getSource)
|
||||
.use('/api', apiHandler.handler)
|
||||
.use('/g', shortUrlHandler)
|
||||
.use('/e', embeddedHandler)
|
||||
.post('/compile', compileHandler.handler) // used inside static/compiler.js
|
||||
.post('/diff', diffHandler); // used inside static/compiler.js
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ define(function (require) {
|
|||
}
|
||||
|
||||
function initialise() {
|
||||
if (options.embedded) return;
|
||||
$(function () {
|
||||
function create_script_element(id, url) {
|
||||
var el = document.createElement('script');
|
||||
|
|
|
@ -173,7 +173,7 @@ define(function (require) {
|
|||
Editor.prototype.maybeEmitChange = function (force) {
|
||||
var source = this.getSource();
|
||||
if (!force && source == this.lastChangeEmitted) return;
|
||||
this.lastChangeEmitted = this.getSource();
|
||||
this.lastChangeEmitted = source;
|
||||
this.eventHub.emit('editorChange', this.id, this.lastChangeEmitted);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Compiler Explorer</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="explorer.css" rel="stylesheet">
|
||||
<script data-main="main" src="ext/requirejs/require.js"></script>
|
||||
</head>
|
||||
<body class="embedded">
|
||||
|
||||
<a href="/" class="float-link link" target="_blank">
|
||||
Compiler Explorer ‐ <span class="language-name"></span>
|
||||
<span class="glyphicon glyphicon-new-window"></span><br/>
|
||||
</a>
|
||||
|
||||
<div id="root"></div>
|
||||
|
||||
<div class="gl_keep template">
|
||||
<div id="codeEditor">
|
||||
<div class="top-bar btn-toolbar hidden">
|
||||
<div class="btn-group btn-group-sm options" role="group">
|
||||
<button title="Colourise lines so one can see how the source maps to the output"
|
||||
class="btn btn-default btn-sm active" data-bind="colouriseAsm">
|
||||
<span class="glyphicon glyphicon-adjust"></span>
|
||||
</button>
|
||||
<button title="Run the compilers automatically as you type"
|
||||
class="btn btn-default btn-sm active" data-bind="compileOnChange">
|
||||
<span class="glyphicon glyphicon-play-circle"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea>// Type your code here, or load an example.</textarea>
|
||||
</div>
|
||||
|
||||
<div id="compiler">
|
||||
<div class="top-bar">
|
||||
<table>
|
||||
<tr>
|
||||
<td><select class="compiler-picker" placeholder="Select a compiler..."></select></td>
|
||||
<td><input class="options form-control" type="text" placeholder="compiler options..."
|
||||
size="256"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="btn-group btn-group-sm filters hidden" data-toggle="buttons">
|
||||
<button class="btn btn-sm" title="Compile to binary and disassemble the output"
|
||||
data-bind="binary">
|
||||
<span>11010</span>
|
||||
</button>
|
||||
<button class="btn btn-sm active nonbinary" title="Filter unused labels from the output"
|
||||
data-bind="labels">
|
||||
<span>.LX0:</span>
|
||||
</button>
|
||||
<button class="btn btn-sm active nonbinary" title="Filter all assembler directives from the output"
|
||||
data-bind="directives">
|
||||
<span>.text</span>
|
||||
</button>
|
||||
<button class="btn btn-sm active nonbinary"
|
||||
title="Remove all lines which are only comments from the output"
|
||||
data-bind="commentOnly">
|
||||
<span>//</span>
|
||||
</button>
|
||||
<button class="btn btn-sm active" title="Output disassembly in Intel syntax"
|
||||
data-bind="intel">
|
||||
<span>Intel</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea>[Waiting...]</textarea>
|
||||
<div class="bottom-bar"></div>
|
||||
</div>
|
||||
|
||||
<div id="compiler-output">
|
||||
<pre class="content"></pre>
|
||||
</div>
|
||||
|
||||
<div class="inline-msg">
|
||||
<span class="compiler"></span><span class="icon">!!</span><span class="msg"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -5,9 +5,28 @@
|
|||
@import url("ext/selectize/dist/css/selectize.bootstrap2.css");
|
||||
|
||||
.navbar {
|
||||
border-radius: 0px;
|
||||
border-radius: 0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.float-link {
|
||||
z-index: 100;
|
||||
position: absolute;
|
||||
bottom: 0.5em;
|
||||
right: 0.5em;
|
||||
display: inline-block;
|
||||
padding: 0.25em;
|
||||
font-size: x-small;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background-color: rgba(128,128,128,0.5);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.float-link:hover {
|
||||
background-color: rgba(128,128,128,0.9);
|
||||
}
|
||||
|
||||
.template {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<ul class="nav navbar-nav navbar-left">
|
||||
<li><a href="#" id="get-short-link">Short link</a></li>
|
||||
<li><a href="#" id="get-full-link">Full link</a></li>
|
||||
<li><a href="#" id="get-embed-link">Embed</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="if-github-enabled">
|
||||
|
|
|
@ -65,6 +65,36 @@ define(function (require) {
|
|||
var shortenURL = require('urlshorten-google');
|
||||
var Raven = require('raven-js');
|
||||
|
||||
function contentFromEmbedded(embeddedUrl) {
|
||||
var params = url.unrisonify(embeddedUrl);
|
||||
var filters = _.chain((params.filters || "").split(','))
|
||||
.map(function (o) {
|
||||
return [o, true];
|
||||
})
|
||||
.object()
|
||||
.value();
|
||||
return [
|
||||
{
|
||||
type: 'row',
|
||||
content: [
|
||||
editor.getComponentWith(1, params.source, filters),
|
||||
compiler.getComponentWith(1, filters, params.options, params.compiler)
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function getEmbeddedUrl(layout) {
|
||||
window.layout = layout;
|
||||
|
||||
return window.location.origin + '/e#' + url.risonify({
|
||||
filters: "",
|
||||
source: "",
|
||||
compiler: "",
|
||||
options: ""
|
||||
});
|
||||
}
|
||||
|
||||
function start() {
|
||||
analytics.initialise();
|
||||
sharing.initialise();
|
||||
|
@ -78,28 +108,44 @@ define(function (require) {
|
|||
settings: {showPopoutIcon: false},
|
||||
content: [{type: 'row', content: [editor.getComponent(1), compiler.getComponent(1)]}]
|
||||
};
|
||||
var root = $("#root");
|
||||
var config = url.deserialiseState(window.location.hash.substr(1));
|
||||
if (config) {
|
||||
// replace anything in the default config with that from the hash
|
||||
config = _.extend(defaultConfig, config);
|
||||
}
|
||||
|
||||
$(window).bind('hashchange', function () {
|
||||
// punt on hash events and just reload the page if there's a hash
|
||||
if (window.location.hash.substr(1))
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
if (!config) {
|
||||
var savedState = null;
|
||||
try {
|
||||
savedState = window.localStorage.getItem('gl');
|
||||
} catch (e) {
|
||||
// Some browsers in secure modes can throw exceptions here...
|
||||
var config;
|
||||
if (!options.embedded) {
|
||||
config = url.deserialiseState(window.location.hash.substr(1));
|
||||
if (config) {
|
||||
// replace anything in the default config with that from the hash
|
||||
config = _.extend(defaultConfig, config);
|
||||
}
|
||||
config = savedState !== null ? JSON.parse(savedState) : defaultConfig;
|
||||
|
||||
if (!config) {
|
||||
var savedState = null;
|
||||
try {
|
||||
savedState = window.localStorage.getItem('gl');
|
||||
} catch (e) {
|
||||
// Some browsers in secure modes can throw exceptions here...
|
||||
}
|
||||
config = savedState !== null ? JSON.parse(savedState) : defaultConfig;
|
||||
}
|
||||
} else {
|
||||
config = _.extend(defaultConfig,
|
||||
{
|
||||
settings: {
|
||||
showMaximiseIcon: false,
|
||||
showCloseIcon: false,
|
||||
hasHeaders: false
|
||||
},
|
||||
content: contentFromEmbedded(window.location.hash.substr(1))
|
||||
});
|
||||
}
|
||||
|
||||
var root = $("#root");
|
||||
|
||||
var layout;
|
||||
try {
|
||||
layout = new GoldenLayout(config, root);
|
||||
|
@ -110,11 +156,17 @@ define(function (require) {
|
|||
new Hub(layout, defaultSrc);
|
||||
}
|
||||
layout.on('stateChanged', function () {
|
||||
var state = JSON.stringify(layout.toConfig());
|
||||
try {
|
||||
window.localStorage.setItem('gl', state);
|
||||
} catch (e) {
|
||||
// Some browsers in secure modes may throw
|
||||
var config = layout.toConfig();
|
||||
// Only preserve state in localStorage in non-embedded mode.
|
||||
if (!options.embedded) {
|
||||
var state = JSON.stringify(config);
|
||||
try {
|
||||
window.localStorage.setItem('gl', state);
|
||||
} catch (e) {
|
||||
// Some browsers in secure modes may throw
|
||||
}
|
||||
} else {
|
||||
$('a.link').attr('href', '/#' + url.serialiseState(config));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -173,6 +225,12 @@ define(function (require) {
|
|||
initPopover($("#get-short-link"), function (done) {
|
||||
shortenURL(permalink(), done);
|
||||
});
|
||||
initPopover($("#get-embed-link"), function (done) {
|
||||
done(function () {
|
||||
return '<iframe width="800px" height="200px" src="' +
|
||||
getEmbeddedUrl(layout) + '"></iframe>';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(start);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
define(function (require) {
|
||||
"use strict";
|
||||
var $ = require('jquery');
|
||||
var options = $.ajax({type: "GET", url: 'client-options.json', async: false});
|
||||
return options.responseJSON;
|
||||
var options = $.ajax({type: "GET", url: 'client-options.json', async: false}).responseJSON;
|
||||
options.embedded = window.location.pathname === "/embed.html";
|
||||
return options;
|
||||
});
|
||||
|
|
|
@ -117,6 +117,8 @@ define(function (require) {
|
|||
|
||||
return {
|
||||
deserialiseState: deserialiseState,
|
||||
serialiseState: serialiseState
|
||||
serialiseState: serialiseState,
|
||||
unrisonify: unrisonify,
|
||||
risonify: risonify
|
||||
};
|
||||
});
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Embedding test</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
Test; here's some inline Compiler Explorer stuff:
|
||||
</div>
|
||||
<iframe width="800px" height="200px"
|
||||
src="http://lud-ldnmg01:10240/e#source:'int+main()%7B%7D',compiler:g44,options:'-O2',filters:'colouriseAsm,intel,commentOnly,directives,labels,compileOnChange'"></iframe>
|
||||
</body>
|
||||
<div>And here's some text after</div>
|
||||
</html>
|
Loading…
Reference in New Issue