Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiments with single-page setup to keep Effekt cache #74

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@
<body>
{% endif %}

<main id="content">
{{ content }}
</main>


<script src="{{site.url}}{{site.baseurl}}/highlight/highlight.pack.js"></script>
Expand Down
12 changes: 0 additions & 12 deletions src/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,6 @@ function activateMenuNesting() {
const handleMenuNesting = (e) => {
e.preventDefault();
toggleParent(e.currentTarget, "open");
const elementType = e.currentTarget.tagName.toLowerCase();
if (elementType === "a") {
const linkElement = e.currentTarget;
const linkElementParent = linkElement.parentNode;
const destination = linkElement.href;
if (
destination !== window.location.href &&
!linkElementParent.classList.contains("active")
) {
window.location.href = destination;
}
}
};
if (menuParents) {
[...menuParents].map(elem => {
Expand Down
25 changes: 15 additions & 10 deletions src/ide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ import * as effekt from "./effekt-language";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import type { Diagnostic, DiagnosticSeverity, Position } from "vscode-languageserver-types"

// initialize:
// load all code[module=...] elements and write them to the IDE
document.querySelectorAll("code[module]").forEach( (code: HTMLElement) => {
let module = code.getAttribute("module")
let filename = module + ".effekt"
let content = code.getAttribute("prelude") + code.getAttribute("content") + code.getAttribute("postlude")
effekt.write(filename, content)
})

export interface IViewModel extends monaco.editor.ITextModel {
getFullText(): string
modelPosition(pos: Position): Position
viewPosition(pos: Position): Position
}

// initialize:
// load all code[module=...] elements and write them to the IDE
export function loadModules() {
document.querySelectorAll("code[module]").forEach( (code: HTMLElement) => {
let module = code.getAttribute("module")
let filename = module + ".effekt"
let content = code.getAttribute("prelude") + code.getAttribute("content") + code.getAttribute("postlude")
effekt.write(filename, content)
})
}

export function createModel(filename: string, contents: string, hiddenPrelude: string, hiddenPostlude: string): IViewModel {
let model = monaco.editor.createModel(contents.trim(), "effekt", monaco.Uri.file(filename))
let model = monaco.editor.getModel(monaco.Uri.file(filename));
if (model) model.setValue(contents.trim())
else model = monaco.editor.createModel(contents.trim(), "effekt", monaco.Uri.file(filename))

let pre = hiddenPrelude || ""
let post = hiddenPostlude || ""
let lineOffset = (hiddenPrelude.match(/\n/g) || '').length
Expand Down
84 changes: 77 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ async function enableEditing(code: HTMLElement, run: HTMLElement, coreOut: HTMLE

let IDE = await import(/* webpackMode: "lazy", webpackChunkName: "ide" */ "./ide")
let editor = await import(/* webpackMode: "lazy", webpackChunkName: "editor" */ "./editor")
IDE.loadModules();

parent.classList.remove("editor-loading")
parent.classList.add("editor")
Expand Down Expand Up @@ -264,17 +265,13 @@ function parseOptions(str: string): CodeOptions {
}
}




window.addEventListener("DOMContentLoaded", () => {

function initDOM() {
processCode()

// let codes = document.querySelectorAll("code")
// monacoEditor(codes[codes.length - 1])
hljs.configure({
languages: ['effekt', 'bash']
languages: ['effekt', 'bash']
});

// highlight inline code
Expand All @@ -286,4 +283,77 @@ window.addEventListener("DOMContentLoaded", () => {
})

docs.init()
})
}

const globalHistory = [{ url: window.location.href, scrollPosition: 0 }];
let currentHistoryIndex = 0;

function loadPage(url, addToHistory = true) {
fetch(url)
.then((response) => response.text())
.then((html) => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const newContent = doc.querySelector("main#content");
document.querySelector("main#content").innerHTML = newContent.innerHTML;

initDOM();
addLinkListeners();

document.title = doc.querySelector("head > title").innerHTML;

if (addToHistory) {
globalHistory.splice(currentHistoryIndex + 1);
globalHistory.push({ url, scrollPosition: 0 });
currentHistoryIndex = globalHistory.length - 1;
window.history.pushState({ index: currentHistoryIndex }, "", url);
setTimeout(() => { // wait until content is rendered
window.scrollTo({ top: 0 })
}, 0);
} else {
setTimeout(() => { // wait until content is rendered
window.scrollTo({ top: globalHistory[currentHistoryIndex].scrollPosition });
}, 0);
}
console.log("Current history:", globalHistory, "Current index:", currentHistoryIndex);
})
.catch((err) => console.error("Failed to load page", err));
}

function addLinkListeners() {
const links = document.querySelectorAll(".sidebar-nav a, a.next-page, a.previous-page");

links.forEach((link) => {
link.addEventListener("click", (e) => {
e.preventDefault();
loadPage(link.getAttribute("href"));
});
});
}

function navigateHistory(step) {
globalHistory[currentHistoryIndex].scrollPosition = window.pageYOffset;
const newIndex = currentHistoryIndex + step;
if (newIndex >= 0 && newIndex < globalHistory.length) {
currentHistoryIndex = newIndex;
loadPage(globalHistory[currentHistoryIndex].url, false);
}
}

window.addEventListener("DOMContentLoaded", () => {
addLinkListeners();
initDOM();

window.addEventListener('popstate', (event) => {
if (event.state && typeof event.state.index !== 'undefined') {
const step = event.state.index - currentHistoryIndex;
navigateHistory(step);
}
});

window.addEventListener('beforeunload', () => {
globalHistory[currentHistoryIndex].scrollPosition = window.pageYOffset;
});
});

window.history.pushState({ index: 0 }, "", window.location.href);