mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Update formatting for wasm notebook
This commit is contained in:
10 files changed
+309
-302
No files matched your search
@@ -1,42 +1,43 @@
|
||||
/* CSS */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Turret+Road:wght@700&display=swap');
|
||||
|
||||
h1 { font-family: 'Sen', 'sans-serif'; }
|
||||
|
||||
h2 , h3, h4, button {
|
||||
font-family: 'Turret Road', cursive;
|
||||
padding-top: 1.25rem;
|
||||
}
|
||||
@import url('https://fonts.googleapis.com/css2?family=Turret+Road:wght@700&display=swap');
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
font-family: 'Sen', 'sans-serif';
|
||||
}
|
||||
|
||||
h2, h3, h4, button {
|
||||
font-family: 'Turret Road', cursive;
|
||||
padding-top: 1.25rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
border: 1px solid black;
|
||||
width: 300px;
|
||||
height: 25px;
|
||||
padding: 5px;
|
||||
font-size: 1.2rem;
|
||||
font-family: 'Turret Road', cursive;
|
||||
border: 1px solid black;
|
||||
width: 300px;
|
||||
height: 25px;
|
||||
padding: 5px;
|
||||
font-size: 1.2rem;
|
||||
font-family: 'Turret Road', cursive;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0px;
|
||||
border-bottom: 1px solid black;
|
||||
width: 50%;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
border: 0px;
|
||||
border-bottom: 1px solid black;
|
||||
width: 50%;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: black;
|
||||
color: white;
|
||||
border: 0px;
|
||||
font-size: 1.2rem;
|
||||
height: 30px;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
border: 0px;
|
||||
font-size: 1.2rem;
|
||||
height: 30px;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@@ -2,44 +2,39 @@
|
||||
|
||||
// Javascript code go here
|
||||
|
||||
function create_ui() {
|
||||
function create_ui() {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'text';
|
||||
input.id = 'input-1';
|
||||
document.getElementById('rp-notebook').appendChild(input);
|
||||
|
||||
const input = document.createElement("input");
|
||||
input.type = "text";
|
||||
input.id = "input-1";
|
||||
document.getElementById("rp-notebook").appendChild(input);
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.id = 'btn-caclulate';
|
||||
btn.innerHTML = 'click me';
|
||||
btn.addEventListener('click', calculate, false);
|
||||
document.getElementById('rp-notebook').appendChild(btn);
|
||||
|
||||
const btn = document.createElement("button");
|
||||
btn.type = "button";
|
||||
btn.id = "btn-caclulate";
|
||||
btn.innerHTML = "click me";
|
||||
btn.addEventListener('click', calculate, false);
|
||||
document.getElementById("rp-notebook").appendChild(btn);
|
||||
const div = document.createElement('div');
|
||||
div.id = 'result';
|
||||
div.classList.add('result');
|
||||
document.getElementById('rp-notebook').appendChild(div);
|
||||
}
|
||||
|
||||
const div = document.createElement("div");
|
||||
div.id = "result";
|
||||
div.classList.add("result");
|
||||
document.getElementById("rp-notebook").appendChild(div);
|
||||
|
||||
}
|
||||
function calculate() {
|
||||
let target = document.getElementById('result');
|
||||
target.innerHTML = '';
|
||||
|
||||
function calculate() {
|
||||
|
||||
let target = document.getElementById("result");
|
||||
target.innerHTML = "";
|
||||
|
||||
let code = 'runModel()';
|
||||
|
||||
let input = document.getElementById("input-1").value;
|
||||
|
||||
let params = { "data": input };
|
||||
|
||||
|
||||
rp.pyExec(code, {
|
||||
stdout: (output) => {
|
||||
target.innerHTML += output;
|
||||
},
|
||||
vars: params
|
||||
});
|
||||
|
||||
}
|
||||
let code = 'runModel()';
|
||||
|
||||
let input = document.getElementById('input-1').value;
|
||||
|
||||
let params = { data: input };
|
||||
|
||||
rp.pyExec(code, {
|
||||
stdout: (output) => {
|
||||
target.innerHTML += output;
|
||||
},
|
||||
vars: params,
|
||||
});
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
# RustPython Notebook: python, javascript, css, markdown and math
|
||||
|
||||
|
||||
Python in the browser is fun. Python and Javascript working together is double the fun 😜. Markdown and math are good for communicating ideas 🤔 (especially scientific ones). Adding css to the mix, makes everything look pretty ✨.
|
||||
Python in the browser is fun. Python and Javascript working together is double
|
||||
the fun 😜. Markdown and math are good for communicating ideas 🤔 (especially
|
||||
scientific ones). Adding css to the mix, makes everything look pretty ✨.
|
||||
|
||||
---
|
||||
|
||||
@@ -34,9 +36,9 @@ create_ui();
|
||||
# Python code
|
||||
|
||||
def runModel():
|
||||
input = js_vars['data']
|
||||
print ("<br>")
|
||||
print("A little javascript birdie told the python snake your lucky number 🙊")
|
||||
print ("Now the everyone knows that it is: " + str(input))
|
||||
input = js_vars['data']
|
||||
print ("<br>")
|
||||
print("A little javascript birdie told the python snake your lucky number 🙊")
|
||||
print ("Now the everyone knows that it is: " + str(input))
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
# RustPython Notebook: python, javascript, css, markdown and math
|
||||
|
||||
Python in the browser is fun 🤘. Python and Javascript working together is double the fun 😜. Markdown and math are good for communicating ideas 💡(especially scientific ones 🧠). Adding css to the mix, makes everything look pretty ✨.
|
||||
Python in the browser is fun 🤘. Python and Javascript working together is double
|
||||
the fun 😜. Markdown and math are good for communicating ideas 💡(especially
|
||||
scientific ones 🧠). Adding css to the mix, makes everything look pretty ✨.
|
||||
|
||||
# Main
|
||||
|
||||
@@ -13,7 +15,8 @@ In the notebook, you can write markdown, math, javascript and python.
|
||||
H(t) \xrightarrow{write} \Big[A(t+1),\ H(t+1)\Big]
|
||||
|
||||
%%md
|
||||
It even highlights properly. You can multi-task with split view mode and create python documents as you need to. In main, use `%%` then:
|
||||
It even highlights properly. You can multi-task with split view mode and create
|
||||
python documents as you need to. In main, use `%%` then:
|
||||
- `%%md` for markdown
|
||||
- `%%py` for python
|
||||
- `%%js` for javascript
|
||||
@@ -40,10 +43,10 @@ Here is a run down of what is happening with this demo. The notebook:
|
||||
# Python code
|
||||
|
||||
def runModel():
|
||||
input = js_vars['data']
|
||||
print ("<br>")
|
||||
print("A little javascript birdie told the python snake your lucky number 🙊")
|
||||
print ("Now the everyone knows that it is: " + str(input))
|
||||
input = js_vars['data']
|
||||
print ("<br>")
|
||||
print("A little javascript birdie told the python snake your lucky number 🙊")
|
||||
print ("Now the everyone knows that it is: " + str(input))
|
||||
|
||||
%%md
|
||||
## Calculator
|
||||
@@ -86,12 +89,12 @@ function calculate() {
|
||||
let params = { "data": input };
|
||||
|
||||
|
||||
rp.pyExec(code, {
|
||||
stdout: (output) => {
|
||||
target.innerHTML += output;
|
||||
},
|
||||
vars: params
|
||||
});
|
||||
rp.pyExec(code, {
|
||||
stdout: (output) => {
|
||||
target.innerHTML += output;
|
||||
},
|
||||
vars: params
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -102,12 +105,7 @@ create_ui();
|
||||
# Python code
|
||||
|
||||
def runModel():
|
||||
input = js_vars['data']
|
||||
print ("<br>")
|
||||
print("A little javascript birdie told the python snake your lucky number 🙊")
|
||||
print ("Now the everyone knows that it is: " + str(input))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
input = js_vars['data']
|
||||
print ("<br>")
|
||||
print("A little javascript birdie told the python snake your lucky number 🙊")
|
||||
print ("Now the everyone knows that it is: " + str(input))
|
||||
@@ -19,7 +19,8 @@ In the notebook, you can write markdown, math and python. use %% then:
|
||||
- math-inline for an inline math block
|
||||
|
||||
|
||||
I **can** bold things and _italicize_ them. You got the gist, this is standard markdown syntax that you can [google](google.com).
|
||||
I **can** bold things and _italicize_ them. You got the gist, this is standard
|
||||
markdown syntax that you can [google](google.com).
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+17
-15
@@ -48,44 +48,46 @@ CodeMirror.defineMode('notebook', function (config, _parserConfig) {
|
||||
|
||||
CodeMirror.defineMIME('text/x-notebook', 'notebook');
|
||||
|
||||
|
||||
function selectBuffer(editor, buffers, name) {
|
||||
var buf = buffers[name];
|
||||
if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true});
|
||||
if (buf.getEditor()) buf = buf.linkedDoc({ sharedHist: true });
|
||||
var old = editor.swapDoc(buf);
|
||||
var linked = old.iterLinkedDocs(function(doc) {linked = doc;});
|
||||
var linked = old.iterLinkedDocs(function (doc) {
|
||||
linked = doc;
|
||||
});
|
||||
if (linked) {
|
||||
// Make sure the document in buffers is the one the other view is looking at
|
||||
for (var name in buffers) if (buffers[name] == old) buffers[name] = linked;
|
||||
old.unlinkDoc(linked);
|
||||
// Make sure the document in buffers is the one the other view is looking at
|
||||
for (var name in buffers)
|
||||
if (buffers[name] == old) buffers[name] = linked;
|
||||
old.unlinkDoc(linked);
|
||||
}
|
||||
editor.focus();
|
||||
// console.log(editor.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
function openBuffer(buffers, name, text, mode , buffersDropDown , buffersList) {
|
||||
function openBuffer(buffers, name, text, mode, buffersDropDown, buffersList) {
|
||||
buffers[name] = CodeMirror.Doc(text, mode);
|
||||
let opt = document.createElement("option");
|
||||
let opt = document.createElement('option');
|
||||
opt.appendChild(document.createTextNode(name));
|
||||
buffersDropDown.appendChild(opt);
|
||||
|
||||
let li = document.createElement("li");
|
||||
let li = document.createElement('li');
|
||||
li.appendChild(document.createTextNode(name));
|
||||
li.dataset.language = name;
|
||||
buffersList.appendChild(li);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function newBuf(buffers, buffersDropDown, buffersList, primaryEditor) {
|
||||
let name = prompt("Name your tab", "*scratch*");
|
||||
let name = prompt('Name your tab', '*scratch*');
|
||||
if (name == null) return;
|
||||
if (buffers.hasOwnProperty(name)) {
|
||||
alert("There's already a buffer by that name.");
|
||||
return;
|
||||
}
|
||||
openBuffer(buffers, name, "", "python", buffersDropDown, buffersList);
|
||||
openBuffer(buffers, name, '', 'python', buffersDropDown, buffersList);
|
||||
selectBuffer(primaryEditor, buffers, name);
|
||||
let sel = buffersDropDown;
|
||||
sel.value = name;
|
||||
}
|
||||
|
||||
export { selectBuffer , openBuffer , newBuf }
|
||||
export { selectBuffer, openBuffer, newBuf };
|
||||
+169
-159
@@ -1,5 +1,5 @@
|
||||
import './style.css';
|
||||
// Code Mirror
|
||||
// Code Mirror
|
||||
// https://github.com/codemirror/codemirror
|
||||
import CodeMirror from 'codemirror';
|
||||
import 'codemirror/mode/python/python';
|
||||
@@ -11,45 +11,38 @@ import 'codemirror/addon/comment/comment';
|
||||
import 'codemirror/lib/codemirror.css';
|
||||
import 'codemirror/theme/ayu-mirage.css';
|
||||
|
||||
import {
|
||||
selectBuffer,
|
||||
openBuffer,
|
||||
newBuf
|
||||
} from './editor';
|
||||
import { selectBuffer, openBuffer, newBuf } from './editor';
|
||||
|
||||
import { genericFetch } from './tools'
|
||||
import { genericFetch } from './tools';
|
||||
|
||||
// parsing: copied from the iodide project
|
||||
// https://github.com/iodide-project/iodide/blob/master/src/editor/iomd-tools/iomd-parser.js
|
||||
import {
|
||||
iomdParser
|
||||
} from './parse';
|
||||
import { iomdParser } from './parse';
|
||||
|
||||
// processing: execute/render editor's content
|
||||
import {
|
||||
runPython,
|
||||
runJS,
|
||||
runPython,
|
||||
runJS,
|
||||
addCSS,
|
||||
checkCssStatus,
|
||||
renderMarkdown,
|
||||
renderMath
|
||||
renderMarkdown,
|
||||
renderMath,
|
||||
} from './process';
|
||||
|
||||
let rp;
|
||||
|
||||
// A dependency graph that contains any wasm must be imported asynchronously.
|
||||
import ('rustpython')
|
||||
.then((rustpy) => {
|
||||
rp = rustpy;
|
||||
// so people can play around with it
|
||||
window.rp = rustpy;
|
||||
onReady();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('Error importing `rustpython`:', e);
|
||||
document.getElementById('error')
|
||||
.textContent = e;
|
||||
});
|
||||
import('rustpython')
|
||||
.then((rustpy) => {
|
||||
rp = rustpy;
|
||||
// so people can play around with it
|
||||
window.rp = rustpy;
|
||||
onReady();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('Error importing `rustpython`:', e);
|
||||
document.getElementById('error').textContent = e;
|
||||
});
|
||||
|
||||
const error = document.getElementById('error');
|
||||
const notebook = document.getElementById('rp-notebook');
|
||||
@@ -64,15 +57,18 @@ const notebook = document.getElementById('rp-notebook');
|
||||
// all new documents are python docs
|
||||
// adapted/inspired from https://codemirror.net/demo/buffers.html
|
||||
const primaryEditor = CodeMirror(document.getElementById('primary-editor'), {
|
||||
theme: 'ayu-mirage',
|
||||
lineNumbers: true,
|
||||
theme: 'ayu-mirage',
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
});
|
||||
|
||||
const secondaryEditor = CodeMirror(document.getElementById('secondary-editor'), {
|
||||
lineNumbers: true,
|
||||
lineWrapping: true
|
||||
});
|
||||
const secondaryEditor = CodeMirror(
|
||||
document.getElementById('secondary-editor'),
|
||||
{
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
}
|
||||
);
|
||||
|
||||
const buffers = {};
|
||||
|
||||
@@ -85,37 +81,61 @@ const buffersDropDown = document.getElementById('buffers-selection');
|
||||
// By default open 3 buffers, main, tab1 and css
|
||||
// TODO: add a JS option
|
||||
// Params for OpenBuffer (buffers object, name of buffer to create, default content, type, link in UI 1, link in UI 2)
|
||||
openBuffer(buffers, 'main',
|
||||
'# python code or code blocks that start with %%py, %%md %%math.', 'notebook',
|
||||
buffersDropDown, buffersList);
|
||||
|
||||
openBuffer(buffers, 'python', '# Python code', 'python',
|
||||
buffersDropDown, buffersList);
|
||||
|
||||
openBuffer(buffers, 'js', '// Javascript code go here', 'javascript',
|
||||
buffersDropDown, buffersList);
|
||||
openBuffer(
|
||||
buffers,
|
||||
'main',
|
||||
'# python code or code blocks that start with %%py, %%md %%math.',
|
||||
'notebook',
|
||||
buffersDropDown,
|
||||
buffersList
|
||||
);
|
||||
|
||||
openBuffer(
|
||||
buffers,
|
||||
'python',
|
||||
'# Python code',
|
||||
'python',
|
||||
buffersDropDown,
|
||||
buffersList
|
||||
);
|
||||
|
||||
openBuffer(
|
||||
buffers,
|
||||
'js',
|
||||
'// Javascript code go here',
|
||||
'javascript',
|
||||
buffersDropDown,
|
||||
buffersList
|
||||
);
|
||||
|
||||
openBuffer(
|
||||
buffers,
|
||||
'css',
|
||||
'/* CSS goes here */',
|
||||
'css',
|
||||
buffersDropDown,
|
||||
buffersList
|
||||
);
|
||||
|
||||
openBuffer(buffers, 'css', '/* CSS goes here */', 'css', buffersDropDown,
|
||||
buffersList);
|
||||
|
||||
// select main buffer by default and set the main tab to active
|
||||
selectBuffer(primaryEditor, buffers, 'main');
|
||||
selectBuffer(secondaryEditor, buffers, 'main');
|
||||
document.querySelector('ul#buffers-list li:first-child').classList.add('active');
|
||||
document
|
||||
.querySelector('ul#buffers-list li:first-child')
|
||||
.classList.add('active');
|
||||
|
||||
function onReady() {
|
||||
/* By default the notebook has the keyword "loading"
|
||||
/* By default the notebook has the keyword "loading"
|
||||
once python and doc is ready:
|
||||
create an empty div and set the id to 'rp_loaded'
|
||||
so that the test knows that we're ready */
|
||||
const readyElement = document.createElement('div');
|
||||
readyElement.id = 'rp_loaded';
|
||||
document.head.appendChild(readyElement);
|
||||
// set the notebook to empty
|
||||
notebook.innerHTML = '';
|
||||
const readyElement = document.createElement('div');
|
||||
readyElement.id = 'rp_loaded';
|
||||
document.head.appendChild(readyElement);
|
||||
// set the notebook to empty
|
||||
notebook.innerHTML = '';
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('run-btn').addEventListener('click', readEditors);
|
||||
|
||||
// on click of run
|
||||
@@ -123,18 +143,18 @@ document.getElementById('run-btn').addEventListener('click', readEditors);
|
||||
// 2. get and run content of all tabs (including dynamically added ones)
|
||||
// 3. run main tab.
|
||||
function readEditors() {
|
||||
// Clean the console and errors
|
||||
notebook.innerHTML = '';
|
||||
error.textContent = '';
|
||||
|
||||
// Clean the console and errors
|
||||
notebook.innerHTML = '';
|
||||
error.textContent = '';
|
||||
|
||||
// get the content of the css editor
|
||||
// and add the css to the head
|
||||
// use dataset.status for a flag to know when to update
|
||||
let cssCode = buffers['css'].getValue();
|
||||
let cssStatus = checkCssStatus();
|
||||
switch (cssStatus) {
|
||||
switch (cssStatus) {
|
||||
case 'none':
|
||||
addCSS(cssCode);
|
||||
addCSS(cssCode);
|
||||
break;
|
||||
case 'modified':
|
||||
// remove the old style then add the new one
|
||||
@@ -143,151 +163,141 @@ function readEditors() {
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//
|
||||
let jsCode = buffers['js'].getValue();
|
||||
runJS(jsCode);
|
||||
}
|
||||
|
||||
//
|
||||
let jsCode = buffers['js'].getValue();
|
||||
runJS(jsCode);
|
||||
|
||||
// get all the buffers, except css, js and main
|
||||
// css is auto executed at the start
|
||||
// main is parsed then executed at the end
|
||||
// main can have md, math and python function calls
|
||||
let {
|
||||
css,
|
||||
main,
|
||||
js,
|
||||
...pythonBuffers
|
||||
} = buffers;
|
||||
|
||||
for (const [name] of Object.entries(pythonBuffers)) {
|
||||
let pythonCode = buffers[name].getValue();
|
||||
runPython(pythonCode, notebook, error);
|
||||
// css is auto executed at the start
|
||||
// main is parsed then executed at the end
|
||||
// main can have md, math and python function calls
|
||||
let { css, main, js, ...pythonBuffers } = buffers;
|
||||
|
||||
for (const [name] of Object.entries(pythonBuffers)) {
|
||||
let pythonCode = buffers[name].getValue();
|
||||
runPython(pythonCode, notebook, error);
|
||||
}
|
||||
|
||||
|
||||
parseCodeFromMainEditor();
|
||||
|
||||
}
|
||||
|
||||
// Parses what is the code editor
|
||||
// either runs python or renders math or markdown
|
||||
function parseCodeFromMainEditor() {
|
||||
|
||||
// TODO: fix how javascript is injected and executed
|
||||
// Read javascript code from the jsEditor
|
||||
// Inject JS into DOM, so that functions can be called from python
|
||||
// let js_code = buffers["js"].getValue();
|
||||
// runJS(js_code);
|
||||
// Read javascript code from the jsEditor
|
||||
// Inject JS into DOM, so that functions can be called from python
|
||||
// let js_code = buffers["js"].getValue();
|
||||
// runJS(js_code);
|
||||
|
||||
// gets code from main editor
|
||||
let mainCode = buffers['main'].getValue();
|
||||
/*
|
||||
let mainCode = buffers['main'].getValue();
|
||||
/*
|
||||
Split code into chunks.
|
||||
Uses %%keyword or %% keyword as separator
|
||||
Returned object has:
|
||||
- chunkContent, chunkType, chunkId,
|
||||
- evalFlags, startLine, endLine
|
||||
*/
|
||||
let parsedCode = iomdParser(mainCode);
|
||||
parsedCode.forEach(async (chunk) => {
|
||||
// For each type of chunk, do somthing
|
||||
// so far have py for python, md for markdown and math for math ;p
|
||||
let content = chunk.chunkContent;
|
||||
switch (chunk.chunkType) {
|
||||
// by default assume this is python code
|
||||
// so users don't have to type py manually
|
||||
case '':
|
||||
case 'py':
|
||||
runPython(content, notebook, error);
|
||||
break;
|
||||
// TODO: fix how js is injected and ran
|
||||
case 'js':
|
||||
runJS(content);
|
||||
break;
|
||||
case 'md':
|
||||
notebook.innerHTML += renderMarkdown(content);
|
||||
break;
|
||||
case 'math':
|
||||
notebook.innerHTML += renderMath(content);
|
||||
break;
|
||||
default:
|
||||
// do nothing when we see an unknown chunk for now
|
||||
}
|
||||
});
|
||||
let parsedCode = iomdParser(mainCode);
|
||||
parsedCode.forEach(async (chunk) => {
|
||||
// For each type of chunk, do somthing
|
||||
// so far have py for python, md for markdown and math for math ;p
|
||||
let content = chunk.chunkContent;
|
||||
switch (chunk.chunkType) {
|
||||
// by default assume this is python code
|
||||
// so users don't have to type py manually
|
||||
case '':
|
||||
case 'py':
|
||||
runPython(content, notebook, error);
|
||||
break;
|
||||
// TODO: fix how js is injected and ran
|
||||
case 'js':
|
||||
runJS(content);
|
||||
break;
|
||||
case 'md':
|
||||
notebook.innerHTML += renderMarkdown(content);
|
||||
break;
|
||||
case 'math':
|
||||
notebook.innerHTML += renderMath(content);
|
||||
break;
|
||||
default:
|
||||
// do nothing when we see an unknown chunk for now
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updatePopup(type, message) {
|
||||
document.getElementById('popup').dataset.type = type ;
|
||||
document.getElementById('popup').dataset.type = type;
|
||||
document.getElementById('popup-header').textContent = message;
|
||||
}
|
||||
|
||||
// import button
|
||||
// show a url input + fetch button
|
||||
// takes a url where there is raw code
|
||||
document.getElementById('popup-import').addEventListener('click', async function () {
|
||||
let url = document.getElementById('popup-url').value;
|
||||
let type = document.getElementById('popup').dataset.type;
|
||||
let code = await genericFetch(url, type);
|
||||
primaryEditor.setValue(code);
|
||||
});
|
||||
document
|
||||
.getElementById('popup-import')
|
||||
.addEventListener('click', async function () {
|
||||
let url = document.getElementById('popup-url').value;
|
||||
let type = document.getElementById('popup').dataset.type;
|
||||
let code = await genericFetch(url, type);
|
||||
primaryEditor.setValue(code);
|
||||
});
|
||||
|
||||
document.getElementById('import-code').addEventListener('click' , function() {
|
||||
document.getElementById('import-code').addEventListener('click', function () {
|
||||
updatePopup('python', 'URL (raw text format)');
|
||||
});
|
||||
|
||||
// click on an item in the list
|
||||
CodeMirror.on(buffersList, 'click', function(e) {
|
||||
selectBuffer(primaryEditor, buffers, e.target.dataset.language);
|
||||
CodeMirror.on(buffersList, 'click', function (e) {
|
||||
selectBuffer(primaryEditor, buffers, e.target.dataset.language);
|
||||
});
|
||||
|
||||
// select an item in the dropdown
|
||||
CodeMirror.on(buffersDropDown, 'change', function() {
|
||||
selectBuffer(secondaryEditor, buffers, buffersDropDown.options[
|
||||
buffersDropDown.selectedIndex].value);
|
||||
CodeMirror.on(buffersDropDown, 'change', function () {
|
||||
selectBuffer(
|
||||
secondaryEditor,
|
||||
buffers,
|
||||
buffersDropDown.options[buffersDropDown.selectedIndex].value
|
||||
);
|
||||
});
|
||||
|
||||
// when css code editor changes
|
||||
// update data attribute flag to modified
|
||||
CodeMirror.on(buffers['css'], 'change', function() {
|
||||
CodeMirror.on(buffers['css'], 'change', function () {
|
||||
let style = document.getElementsByTagName('style')[0];
|
||||
if (style) {
|
||||
style.dataset.status = 'modified';
|
||||
style.dataset.status = 'modified';
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('buffers-list').addEventListener('click' , function(event) {
|
||||
let elem = document.querySelector('.active');
|
||||
if (elem) {
|
||||
elem.classList.remove('active');
|
||||
}
|
||||
event.target.classList.add('active');
|
||||
document
|
||||
.getElementById('buffers-list')
|
||||
.addEventListener('click', function (event) {
|
||||
let elem = document.querySelector('.active');
|
||||
if (elem) {
|
||||
elem.classList.remove('active');
|
||||
}
|
||||
event.target.classList.add('active');
|
||||
});
|
||||
|
||||
// new tab, new buffer
|
||||
document.getElementById('new-tab').addEventListener('click', function () {
|
||||
newBuf(buffers, buffersDropDown, buffersList, primaryEditor);
|
||||
});
|
||||
|
||||
// new tab, new buffer
|
||||
document.getElementById('new-tab')
|
||||
.addEventListener('click', function() {
|
||||
newBuf(buffers, buffersDropDown, buffersList, primaryEditor);
|
||||
});
|
||||
|
||||
// TODO: those three addEventListener can be re-written into one thing probably
|
||||
document.getElementById('split-view')
|
||||
.addEventListener('click', function() {
|
||||
document.getElementById('primary-editor')
|
||||
.classList.remove('d-none');
|
||||
document.getElementById('secondary-editor')
|
||||
.classList.remove('d-none');
|
||||
});
|
||||
document.getElementById('reader-view')
|
||||
.addEventListener('click', function() {
|
||||
document.getElementById('primary-editor')
|
||||
.classList.add('d-none');
|
||||
document.getElementById('secondary-editor')
|
||||
.classList.add('d-none');
|
||||
});
|
||||
document.getElementById('default-view')
|
||||
.addEventListener('click', function() {
|
||||
document.getElementById('primary-editor')
|
||||
.classList.remove('d-none');
|
||||
document.getElementById('secondary-editor')
|
||||
.classList.add('d-none');
|
||||
});
|
||||
document.getElementById('split-view').addEventListener('click', function () {
|
||||
document.getElementById('primary-editor').classList.remove('d-none');
|
||||
document.getElementById('secondary-editor').classList.remove('d-none');
|
||||
});
|
||||
document.getElementById('reader-view').addEventListener('click', function () {
|
||||
document.getElementById('primary-editor').classList.add('d-none');
|
||||
document.getElementById('secondary-editor').classList.add('d-none');
|
||||
});
|
||||
document.getElementById('default-view').addEventListener('click', function () {
|
||||
document.getElementById('primary-editor').classList.remove('d-none');
|
||||
document.getElementById('secondary-editor').classList.add('d-none');
|
||||
});
|
||||
@@ -30,7 +30,7 @@ function runPython(code, target, error) {
|
||||
rp.pyExec(code, {
|
||||
stdout: (output) => {
|
||||
target.innerHTML += output;
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
if (err instanceof WebAssembly.RuntimeError) {
|
||||
@@ -40,19 +40,19 @@ function runPython(code, target, error) {
|
||||
}
|
||||
}
|
||||
|
||||
function addCSS(code) {
|
||||
function addCSS(code) {
|
||||
let style = document.createElement('style');
|
||||
style.type = 'text/css';
|
||||
style.innerHTML = code;
|
||||
// add a data attribute to check if css already loaded
|
||||
style.dataset.status = "loaded";
|
||||
style.dataset.status = 'loaded';
|
||||
document.getElementsByTagName('head')[0].appendChild(style);
|
||||
}
|
||||
|
||||
function checkCssStatus() {
|
||||
let style = document.getElementsByTagName('style')[0];
|
||||
if (!style) {
|
||||
return "none";
|
||||
return 'none';
|
||||
} else {
|
||||
return style.dataset.status;
|
||||
}
|
||||
@@ -66,12 +66,12 @@ function runJS(code) {
|
||||
script.src = url;
|
||||
doc.appendChild(script);
|
||||
try {
|
||||
URL.revokeObjectURL(url);
|
||||
doc.removeChild(script);
|
||||
URL.revokeObjectURL(url);
|
||||
doc.removeChild(script);
|
||||
} catch (e) {
|
||||
// ignore if body is changed and script is detached
|
||||
console.log(e);
|
||||
// ignore if body is changed and script is detached
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
export { runPython, runJS, renderMarkdown, renderMath, addCSS, checkCssStatus }
|
||||
}
|
||||
|
||||
export { runPython, runJS, renderMarkdown, renderMath, addCSS, checkCssStatus };
|
||||
@@ -59,7 +59,6 @@ h6 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.item-center {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
@@ -112,7 +111,7 @@ ul.list-inline li {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.active {
|
||||
.active {
|
||||
background-color: #1f2430;
|
||||
color: #fff;
|
||||
}
|
||||
@@ -138,7 +137,7 @@ ul.list-inline li {
|
||||
height: calc(90vh - 60px);
|
||||
}
|
||||
|
||||
.CodeMirror , .CodeMirror-wrap {
|
||||
.CodeMirror, .CodeMirror-wrap {
|
||||
height: 100% !important;
|
||||
}
|
||||
#rp-notebook {
|
||||
@@ -196,7 +195,6 @@ input[type='url'] {
|
||||
border-left: 1px solid rgb(221, 221, 221);
|
||||
}
|
||||
|
||||
|
||||
/* css popup */
|
||||
.overlay {
|
||||
position: fixed;
|
||||
|
||||
+21
-21
@@ -1,24 +1,24 @@
|
||||
export const getResponseTypeFromFetchType = fetchEntry => {
|
||||
if (fetchEntry === "python") return "text";
|
||||
if (fetchEntry === "javascript") return "text";
|
||||
if (fetchEntry === "css") return "text";
|
||||
if (fetchEntry === "js") return "blob";
|
||||
if (fetchEntry === "plugin") return "text";
|
||||
if (fetchEntry === "bytes") return "arrayBuffer";
|
||||
export const getResponseTypeFromFetchType = (fetchEntry) => {
|
||||
if (fetchEntry === 'python') return 'text';
|
||||
if (fetchEntry === 'javascript') return 'text';
|
||||
if (fetchEntry === 'css') return 'text';
|
||||
if (fetchEntry === 'js') return 'blob';
|
||||
if (fetchEntry === 'plugin') return 'text';
|
||||
if (fetchEntry === 'bytes') return 'arrayBuffer';
|
||||
return fetchEntry;
|
||||
};
|
||||
|
||||
export function genericFetch(path, fetchType) {
|
||||
};
|
||||
|
||||
export function genericFetch(path, fetchType) {
|
||||
const responseType = getResponseTypeFromFetchType(fetchType);
|
||||
return fetch(path)
|
||||
.then(r => {
|
||||
if (!r.ok) throw new Error(`${r.status} ${r.statusText} (${path})`);
|
||||
return r[responseType]();
|
||||
})
|
||||
.then(r => {
|
||||
if (fetchType === "bytes") {
|
||||
return new Uint8Array(r);
|
||||
}
|
||||
return r;
|
||||
});
|
||||
}
|
||||
.then((r) => {
|
||||
if (!r.ok) throw new Error(`${r.status} ${r.statusText} (${path})`);
|
||||
return r[responseType]();
|
||||
})
|
||||
.then((r) => {
|
||||
if (fetchType === 'bytes') {
|
||||
return new Uint8Array(r);
|
||||
}
|
||||
return r;
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user