diff --git a/config/config.toml b/config/config.toml
index f1f3f95..720fb46 100644
--- a/config/config.toml
+++ b/config/config.toml
@@ -1,8 +1,10 @@
-[cdn]
-bootstrap_css = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
-bootstrap_js = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
+[websocket]
+url = "127.0.0.1"
+port = 8080
-[paths]
-javascript_dir = "/internal/javascript"
+[fileserver]
+url = "127.0.0.1"
+port = 8085
-[setup]
+[fileserver_api]
+url = "http://localhost:8085/"
diff --git a/docs/src/index.md b/docs/src/index.md
index 876b196..38fdae0 100644
--- a/docs/src/index.md
+++ b/docs/src/index.md
@@ -19,11 +19,11 @@ YOUR_PACKAGE_NAME$> julia --project -e 'using Pluto; Pluto.run(notebook="PlutoBo
## Write your own code
There is some hierarchy:
-- `main` in `src/Main.jl` gets called in the beginning, so use this as julia entry point
-- functions that should be callable from js need to go into `src/Functions.jl`
-- all javascript files in `static/javascript/` are getting executed, though `static/javascript/javascript.js` is the last one, so use this as js entry point
+- `main` in `src/Main.jl` gets called in the beginning, use this as Julia entry point
+- `static/javascript/main.js` is getting executed in the beginning too, use this as JS entrypoint
+- functions that should be callable from js should to go into `src/Functions.jl`. They can be anywhere else too, but make sure they are included in `src/YOUR_PACKAGE_NAME.jl`
-There is a simple example in `src/Functions.jl`, `src/static/index.html` and `src/static/javascript/javascript.js` about calling a julia function from javascript with callbacks.
+There is a simple example in `src/Functions.jl`, `static/index.html` and `static/javascript/main.js` about calling a Julia function from JS with callbacks.
### Simple calling of a Julia function within HTML using a button and an input
@@ -48,14 +48,17 @@ Now we create an input with `id=buttonInput` for our number in `static/index.htm
```
as well as a button
```HTML
-
+
```
and a div to show our output
```HTML
Output:
```
-Since we used `calculateVeryHardStuff` in our button, we need to define it aswell. We do this in `static/javascript/javascript.js`
+Now we need to define a function that does something when we click the button. We do this in `static/javascript/main.js`
```JavaScript
+//Import callJuliaFunction. Internal JS files are on /internal/static/javascript
+import { callJuliaFunction } from "/internal/static/javascript/interface.js";
+
function calculateVeryHardStuff() {
// get our input
const input = document.getElementById("buttonInput");
@@ -87,9 +90,19 @@ function calculateVeryHardStuff() {
}
)
}
+
+//add our function as click event to the button
+document.getElementById("calculateButton").addEventListener("click", calculateVeryHardStuff);
```
And that's it, we have created a simple application using HTML and JavaScript as input and Julia for calculating!
+Importing other JS files is easily done using ES6 Modules:
+```javascript
+//imports function from static/javascript/folder/file.js
+import { function } from "./folder/file.js";
+```
+Don't forget to export functions you want to import elsewhere.
+
# PlutoBoard.jl Documentation
## PlutoBoard interface
@@ -107,22 +120,15 @@ callJuliaFunction()
## Internal functions
-### Julia internal functions
```@docs
-load_scripts_and_links()
-load_html()
-load_html_string_to_body()
+add_cell(;ws)
+remove_cell(uuid::String; ws)
+get_cells(;ws)
+
+get_html()
load_js()
open_file(path::String)
copy_with_delete(from::String, to::String)
setup()
get_package_name()
-```
-
-### JavaScript internal functions
-```@docs
-placeIframe()
-updateAllCells()
-updateCell()
-insertHTMLToBody()
```
\ No newline at end of file
diff --git a/internal/javascript/Dummy.jl b/internal/javascript/Dummy.jl
deleted file mode 100644
index abba1e4..0000000
--- a/internal/javascript/Dummy.jl
+++ /dev/null
@@ -1,79 +0,0 @@
-export callJuliaFunction, placeIframe, updateAllCells, updateCell, insertHTMLToBody
-
-"""
-```javascript
-async callJuliaFunction(
- func_name,
- { args = [], kwargs = {}, response_callback = () => { } } = {}
-) -> Promise
-```
-`kwargs` are kwargs for the Julia function to be called.
-
-Calls specified Julia function with args and callback within browser context from JavaScript.
-
-Example usage:
-```javascript
-callJuliaFunction("get_cube", {
- args: [number],
- response_callback: (
- r => {
- const outP = document.getElementById("buttonOutput");
- outP.innerHTML = `Cube of \${number}... \${Math.round(r * 100)}%`;
- }
- )
- }).then(
- r => {
- const outP = document.getElementById("buttonOutput");
- outP.innerHTML = `The cube of \${number} is \${r}`;
- }
- )
-```
-"""
-function callJuliaFunction()
-end
-
-
-"""
-```javascript
-placeIframe(targetCellID, destinationDiv)
-```
-Places an iframe of the site itself in `destinationDiv` only showing `targetCellID`.
-"""
-function placeIframe()
-end
-
-"""
-```javascript
-placeAlliFrames()
-```
-Calls `placeIframe` for every div with `cellid` attribute.
-"""
-function placeAlliFrames()
-end
-
-"""
-```javascript
-async updateAllCells()
-```
-Forcefully reevaluates all Pluto cells.
-"""
-function updateAllCells()
-end
-
-"""
-```javascript
-async updateCell(cellid)
-```
-Reevaluates Pluto cell with `cellid`.
-"""
-function updateCell()
-end
-
-"""
-```javascript
-insertHTMLToBody(html, css)
-```
-Appends html and css string below body.
-"""
-function insertHTMLToBody()
-end
diff --git a/internal/javascript/iFrame.js b/internal/javascript/iFrame.js
deleted file mode 100644
index 874adc2..0000000
--- a/internal/javascript/iFrame.js
+++ /dev/null
@@ -1,168 +0,0 @@
-//DO NOT LOAD IN IFRAME
-
-function placeIframe(targetCellID, destinationDiv) {
- const iFrameID = `cell-iframe-${targetCellID}`;
- const plutoBoardExportDivID = 'main-export';
-
- let listener = setInterval(function () {
- if (destinationDiv !== null) {
- clearInterval(listener);
-
-
- let notebook = document.querySelector('pluto-notebook');
- let notebookID = notebook.id;
-
- let div = destinationDiv;
- let iframe = document.createElement('iframe');
- iframe.id = iFrameID;
- iframe.src = `http://localhost:1234/edit?id=${notebookID}`;
-
- if (window.location === window.parent.location) {
- div.appendChild(iframe);
-
-
- //wait until iframe is loaded
- let interval = setInterval(function () {
- if (document.querySelector(`#${iFrameID}`).contentDocument) {
- clearInterval(interval);
- console.log('iframe loaded');
-
- let interval2 = setInterval(function () {
- if (document.querySelector(`#${iFrameID}`).contentDocument.querySelector(`#${plutoBoardExportDivID}`)) {
- clearInterval(interval2);
- console.log('main-export loaded');
-
- //find all style tags in iframe and remove them
- let iframeDoc = document.querySelector(`#${iFrameID}`).contentDocument;
- let styles = iframeDoc.querySelectorAll('style');
- //remove all styles without class attribute
- styles.forEach(style => {
- // if (!style.hasAttribute('class')) {
- // style.remove();
- // }
- //if stlye.innerHTML includes 'PlutoBoard.jl internal stylesheet' remove it
- if (style.innerHTML.includes('PlutoBoard.jl internal stylesheet')) {
- style.remove();
- }
-
- });
-
- //get all pluto-cell elements and hide them
- let cells = iframeDoc.querySelectorAll('pluto-cell');
- cells.forEach(cell => {
- //check if id is equal to targetCellID
- if (cell.id !== targetCellID) {
- cell.style.display = 'none';
- } else {
- cell.style.margin = '0.8vw';
- cell.style.padding = '2vw';
- }
- });
-
- //set body background to transparent
- let body = iframeDoc.querySelector('body');
- body.style.backgroundColor = 'transparent';
-
- //hide header
- let header = iframeDoc.querySelector('header');
- header.style.display = 'none';
-
- //hie footer
- let footer = iframeDoc.querySelector('footer');
- footer.style.display = 'none';
-
- //hide #main-export
- let mainExport = iframeDoc.querySelector(`#${plutoBoardExportDivID}`);
- mainExport.style.display = 'none';
-
- //hide .not-iframe
- let notIframe = iframeDoc.querySelectorAll('.not-iframe');
- notIframe.forEach(element => {
- element.style.display = 'none';
- });
-
- //hide #helpbox-wrapper
- let helpbox = iframeDoc.querySelector('#helpbox-wrapper');
- helpbox.style.display = 'none';
-
- //hide every child of body except body>div>pluto-editor>main>pluto-notebook
-
- //set main margin & padding to 0
- let main = iframeDoc.querySelector('main');
- main.style.margin = '0';
- main.style.padding = '0';
- main.style.display = 'contents';
-
- //hide preamble
- let preamble = iframeDoc.querySelector('preamble');
- preamble.style.display = 'none';
-
- //hide all add_cell buttons
- let addCellButtons = iframeDoc.querySelectorAll('.add_cell');
- addCellButtons.forEach(button => {
- button.style.display = 'none';
- });
-
- //hide .cm-gutters
- let cmGutters = iframeDoc.querySelectorAll('.cm-gutters');
- cmGutters.forEach(gutter => {
- gutter.style.display = 'none';
- });
-
- //hide all pluto-shoulders
- let shoulders = iframeDoc.querySelectorAll('pluto-shoulder');
- shoulders.forEach(shoulder => {
- shoulder.style.display = 'none';
- });
-
- //get pluto-editor parent
- let editor = iframeDoc.querySelector('pluto-editor');
- let editorParent = editor.parentElement;
- editorParent.style.minHeight = '0';
-
- //set body min height to 0
- body.style.minHeight = '0';
-
- //hide loading-bar
- let loadingBar = iframeDoc.querySelector('loading-bar');
- loadingBar.style.display = 'none';
-
-
- //pluto-notebook border radius
- let notebook = iframeDoc.querySelector('pluto-notebook');
- notebook.style.borderRadius = '4vw';
- notebook.style.width = '100vw';
- notebook.style.height = '100vh';
-
- //hide pluto-trafficlight
- let trafficLight = iframeDoc.querySelector('pluto-trafficlight');
- trafficLight.style.display = 'none';
-
- }
- }, 100);
- }
- }, 100);
- }
- }
- }, 100);
-}
-
-
-function placeAlliFrames() {
- //get all divs with class cell-div
- let cellDivs = document.querySelectorAll('.cell-div');
- cellDivs.forEach(cellDiv => {
- let cellID = cellDiv.getAttribute('cellid');
- if (cellID === null) {
- return;
- }
- placeIframe(cellID, cellDiv);
- });
-}
-
-mainExportListener = setInterval(function () {
- if ((document.querySelector('#app') !== undefined) || (document.querySelector("#main-export") !== undefined)) {
- clearInterval(mainExportListener);
- placeAlliFrames();
- }
-}, 100);
\ No newline at end of file
diff --git a/internal/javascript/internal.js b/internal/javascript/internal.js
deleted file mode 100644
index 6ba0f24..0000000
--- a/internal/javascript/internal.js
+++ /dev/null
@@ -1,218 +0,0 @@
-// DO LOAD IN IFRAME!
-
-async function updateAllCells() {
- const cells = document.querySelectorAll("pluto-cell");
- await cells[0]._internal_pluto_actions.set_and_run_multiple(Array.from(cells).map(cell => cell.id));
- window.location.reload();
-}
-
-async function updateCell(cellID) {
- const cell = document.getElementById(cellID);
- await cell._internal_pluto_actions.set_and_run_multiple([cellID]);
-}
-
-function insertHTMLToBody(html, css) {
- let body = document.querySelector('body');
- if (!body.querySelector('style')) {
- body.insertAdjacentHTML('beforeend', css);
- } else {
- body.querySelector('style').remove();
- body.insertAdjacentHTML('afterbegin', css);
- }
-
- if (!document.getElementById('main-export')) {
- body.insertAdjacentHTML('afterbegin', html);
- } else {
- document.getElementById('main-export').remove();
- body.insertAdjacentHTML('afterbegin', html);
- }
-}
-
-function openNav() {
- document.getElementById("mySidebar").style.width = "250px";
-}
-
-function closeNav() {
- document.getElementById("mySidebar").style.width = "0";
-}
-
-function resizeInitial() {
- let element = document.getElementById("pluto-nav").parentElement.parentElement;
- element.style.minHeight = "0";
-}
-
-
-
-// --------------------------------------------------- SETTINGS MODAL ---------------------------------------------------
-
-const modal = document.getElementById('default-modal');
-const openBtn = document.getElementById('open-settings-modal');
-const closeBtn = document.getElementById('close-settings-modal');
-const pageContent = document.getElementById('main-export');
-
-function openSettings() {
- modal.classList.remove('hidden');
- modal.classList.add('flex');
- pageContent.classList.add('blur-sm');
-}
-
-function closeSettings() {
- modal.classList.remove('flex');
- modal.classList.add('hidden');
- pageContent.classList.remove('blur-sm');
-}
-
-openBtn.addEventListener('click', () => {
- openSettings();
-});
-
-closeBtn.addEventListener('click', () => {
- closeSettings();
-});
-
-function findCell(cell_id) {
- //find cell with property cellid=cell_id
- const cell = document.querySelector(`div[cellid="${cell_id}"]`);
- if (cell) {
- sendToast(`Cell ${cell_id} found.`, 'success');
- closeSettings();
- cell.classList.add('border-4', 'border-red-500');
- setTimeout(() => {
- cell.classList.remove('border-4', 'border-red-500');
- }, 3000);
- } else {
- sendToast(`Cell ${cell_id} not found.`, 'error');
- }
-}
-
-
-function sendToast(message, type) {
- const toastContainer = document.getElementById('toast-container');
- let img = '';
- if (type === 'success') {
- img = `
-
- Check icon
-
`;
- } else if (type === 'error') {
- img = `
-
- Error icon
-
`;
- }
- else if (type === 'warning') {
- img = `
-
- Warning icon
-
`;
- }
-
- //generate random id for toast
- const id = Math.random().toString(36).substring(7);
- const toast = `