Skip to content

Commit

Permalink
Merge pull request #552 from antfu/feat/ide-iframe
Browse files Browse the repository at this point in the history
Use iframe for ide output
  • Loading branch information
LingDong- authored Jan 17, 2020
2 parents bcf71c8 + fbf2b74 commit cc2481d
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 91 deletions.
61 changes: 61 additions & 0 deletions src/execute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
var { num2hanzi, bool2hanzi } = require("./hanzi2num");

function isLangSupportedForEval(lang) {
if (lang !== "js")
throw new Error(
`Executing for target language "${lang}" is not supported in current environment`
);
return true;
}

function hanzinize(value) {
if (typeof value == "number") {
return num2hanzi(value);
} else if (typeof value == "boolean") {
return bool2hanzi(value);
} else if (Array.isArray(value)) {
return value.map(i => hanzinize(i)).join("。");
} else {
return value;
}
}

function outputHanziWrapper(log, outputHanzi) {
return function output(...args) {
log(...args.map(i => (outputHanzi ? hanzinize(i) : i)));
};
}

function evalCompiled(compiledCode, options = {}) {
const {
outputHanzi = true,
scoped = false,
lang = "js",
output = console.log
} = options;

isLangSupportedForEval(lang);

let code = compiledCode;

(() => {
const _console_log = console.log;
console.log = outputHanziWrapper(output, outputHanzi);
try {
if (!scoped && "window" in this) {
window.eval(code);
} else {
eval(code);
}
} catch (e) {
throw e;
} finally {
console.log = _console_log;
}
})();
}

module.exports = {
isLangSupportedForEval,
evalCompiled
};
56 changes: 1 addition & 55 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var compilers = require("./compiler/compilers");
var { typecheck, printSignature } = require("./typecheck");
var { expandMacros, extractMacros } = require("./macro.js");
var { defaultImportReader } = require("./reader");
var { evalCompiled, isLangSupportedForEval } = require("./execute");

const defaultTrustedHosts = [
"https://raw.githubusercontent.com/LingDong-/wenyan-lang/master"
Expand Down Expand Up @@ -811,61 +812,6 @@ function compile(arg1, arg2, arg3) {
return targ;
}

function isLangSupportedForEval(lang) {
if (lang !== "js")
throw new Error(
`Executing for target language "${lang}" is not supported in current environment`
);
return true;
}

function hanzinize(value) {
if (typeof value == "number") {
return num2hanzi(value);
} else if (typeof value == "boolean") {
return bool2hanzi(value);
} else if (Array.isArray(value)) {
return value.map(i => hanzinize(i)).join("。");
} else {
return value;
}
}

function outputHanziWrapper(log, outputHanzi) {
return function output(...args) {
log(...args.map(i => (outputHanzi ? hanzinize(i) : i)));
};
}

function evalCompiled(compiledCode, options = {}) {
const {
outputHanzi = true,
scoped = false,
lang = "js",
output = console.log
} = options;

isLangSupportedForEval(lang);

let code = compiledCode;

(() => {
const _console_log = console.log;
console.log = outputHanziWrapper(output, outputHanzi);
try {
if (!scoped && "window" in this) {
window.eval(code);
} else {
eval(code);
}
} catch (e) {
throw e;
} finally {
console.log = _console_log;
}
})();
}

function execute(source, options = {}) {
const { lang = "js" } = options;
isLangSupportedForEval(lang);
Expand Down
17 changes: 11 additions & 6 deletions static/assets/css/ide.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ body {

#in,
#js,
#out,
#out-iframe,
#explorer {
width: 100%;
height: calc(100% - 37px);
Expand Down Expand Up @@ -62,7 +62,16 @@ body {
padding-right: 10px;
}

#out {
#out-iframe {
border: none;
position: fixed;
margin: 0px;
background: white;
overflow: auto;
font-family: monospace;
}

#out-render {
position: absolute;
padding: 10px;
margin: 0px;
Expand All @@ -72,12 +81,8 @@ body {
right: 0;
background: white;
overflow: auto;
font-family: monospace;
width: auto;
height: auto;
word-break: normal !important;
word-wrap: normal !important;
white-space: pre !important;
}

#hand-v,
Expand Down
67 changes: 43 additions & 24 deletions static/assets/js/ide.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const exlistExamples = document.getElementById("explorer-list-examples");
const exlistPackages = document.getElementById("explorer-list-packages");
const explorerPackages = document.getElementById("explorer-packages");

const outdiv = document.getElementById("out");
const outIframe = document.getElementById("out-iframe");
const outRender = document.getElementById("out-render");
const deleteBtn = document.getElementById("delete-current");
const fileNameSpan = document.getElementById("current-file-name");
const downloadRenderBtn = document.getElementById("download-render");
Expand Down Expand Up @@ -197,6 +198,7 @@ function setView() {
var W = window.innerWidth;
var H = window.innerHeight;
var hw = 9;
var barHeight = 36;

dex.style.left = "0px";
dex.style.top = "0px";
Expand All @@ -218,6 +220,11 @@ function setView() {
dou.style.width = W - handex + "px";
dou.style.height = H - handh + "px";

outIframe.style.left = handex + "px";
outIframe.style.top = handh + barHeight + "px";
outIframe.style.width = W - handex + "px";
outIframe.style.height = H - handh - barHeight + "px";

dhex.style.left = handex - hw / 2 + "px";
dhex.style.top = "0px";
dhex.style.width = hw + "px";
Expand Down Expand Up @@ -490,7 +497,9 @@ function loadPackages() {
}

function resetOutput() {
outdiv.innerText = "";
outIframe.contentWindow.location.reload();
outIframe.classList.toggle("hidden", false);
outRender.classList.toggle("hidden", true);
downloadRenderBtn.classList.toggle("hidden", true);
renderedSVGs = [];
}
Expand All @@ -499,68 +508,76 @@ function compile() {
resetOutput();
var log = "";
try {
const errorLog = "";
var code = Wenyan.compile(editorCM.getValue(), {
lang: "js",
romanizeIdentifiers: state.config.romanizeIdentifiers,
resetVarCnt: true,
errorCallback: (...args) => (outdiv.innerText += args.join(" ") + "\n"),
errorCallback: (...args) => (errorLog += args.join(" ") + "\n"),
importContext: getImportContext(),
importCache: cache,
logCallback: x => {
log += x + "\n";
},
strict: true
});
if (errorLog) {
send({ text: errorLog });
return;
}
var sig = log
.split("=== [PASS 2.5] TYPECHECK ===\n")[1]
.split("=== [PASS 3] COMPILER ===")[0];
outdiv.innerText = sig;
send({ text: sig });
var showcode = state.config.hideImported ? hideImportedModules(code) : code;
jsCM.setValue(js_beautify(showcode));
} catch (e) {
outdiv.innerText = e.toString();
send({ text: e.toString() });
console.error(e);
}
}

function send(data) {
outIframe.onload = () => {
outIframe.contentWindow.postMessage(data);
};
}

function run() {
resetOutput();
Wenyan.evalCompiled(jsCM.getValue(), {
outputHanzi: state.config.outputHanzi,
output: (...args) => {
outdiv.innerText += args.join(" ") + "\n";
send({
code: jsCM.getValue(),
options: {
outputHanzi: state.config.outputHanzi
}
});
}

function crun() {
resetOutput();
try {
let errorOutput = "";
var code = Wenyan.compile(editorCM.getValue(), {
lang: "js",
romanizeIdentifiers: state.config.romanizeIdentifiers,
resetVarCnt: true,
errorCallback: (...args) => (outdiv.innerText += args.join(" ") + "\n"),
errorCallback: (...args) =>
(errorOutput.innerText += args.join(" ") + "\n"),
importContext: getImportContext(),
importCache: cache
});
var showcode = state.config.hideImported ? hideImportedModules(code) : code;

jsCM.setValue(js_beautify(showcode));

try {
Wenyan.evalCompiled(code, {
outputHanzi: state.config.outputHanzi,
output: (...args) => {
outdiv.innerText += args.join(" ") + "\n";
}
});
} catch (e) {
outdiv.innerText = e.toString();
console.error(e);
}
send({
code,
options: {
outputHanzi: state.config.outputHanzi
}
});
} catch (e) {
outdiv.innerText = e.toString();
send({ text: e.toString() });
jsCM.setValue("");
console.error(e);
}
Expand All @@ -581,14 +598,16 @@ function updateDark() {
}

function render() {
outdiv.innerText = "";
outRender.innerText = "";
renderedSVGs = Render.render(
currentFile.alias || currentFile.name,
currentFile.code
);
for (const svg of renderedSVGs) {
outdiv.innerHTML += svg + "<br>";
outRender.innerHTML += svg + "<br>";
}
outIframe.classList.toggle("hidden", true);
outRender.classList.toggle("hidden", false);
downloadRenderBtn.classList.toggle("hidden", false);
}

Expand Down
3 changes: 2 additions & 1 deletion static/ide.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@
</button>
</div>
</div>
<pre id="out"></pre>
<iframe src='/ide_executer.html' id="out-iframe"></iframe>
<pre id="out-render"></pre>
</div>

<div id="help-panel" class="panel hidden">
Expand Down
30 changes: 30 additions & 0 deletions static/ide_executer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<head>
<script src="./dist/execute.js"></script>
</head>
<body>
<pre id="out"></pre>
<script>
const outdiv = document.getElementById('out')

window.addEventListener('message', (e) => {
console.log(e.data)
const { text, code, options } = e.data

if (text)
outdiv.innerText = text

if (code){
outdiv.innerText = ""
try {
Wenyan.evalCompiled(code, {
...options,
output: (...args) => outdiv.innerText += args.join(" ") + "\n"
});
} catch (e) {
outdiv.innerText = e.toString();
console.error(e);
}
}
}, false);
</script>
</body>
13 changes: 8 additions & 5 deletions webpack.site.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ const makeConfig = (entry, filename, entryName) => {
return config
}

const core = makeConfig('./src/parser.js', 'dist/core.js', 'Wenyan')
const examples = makeConfig('./tools/examples.js', 'dist/examples.js', 'Examples')
const highlighter = makeConfig('./src/highlight.js', 'dist/highlight.js', 'Highlighter')
const render = makeConfig('./src/render.js', 'dist/render.js', 'Render')

module.exports = [core, examples, highlighter, render]

module.exports = [
makeConfig('./src/parser.js', 'dist/core.js', 'Wenyan'),
makeConfig('./src/execute.js', 'dist/execute.js', 'Wenyan'),
makeConfig('./tools/examples.js', 'dist/examples.js', 'Examples'),
makeConfig('./src/highlight.js', 'dist/highlight.js', 'Highlighter'),
makeConfig('./src/render.js', 'dist/render.js', 'Render'),
]

0 comments on commit cc2481d

Please sign in to comment.