Skip to content
Merged
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
59 changes: 12 additions & 47 deletions web/js/codeworld.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ import {
run,
toggleObsoleteCodeAlert,
warnIfUnsaved,
sha256digest,
saveCodeToLocalStorageAndReplaceHash,
tryLoadingCodeFromLocalStorage,
tryFetchCodeFromSourceAndStripURL,
} from './codeworld_shared.js';

import * as Alert from './utils/alert.js';
Expand Down Expand Up @@ -178,7 +180,7 @@ async function init() {
if(window.buildMode === 'codeworld')
document.querySelector("#docButton").style.display = "none";

const savedCode = localStorage.getItem(`${window.buildMode}-${window.location.hash.slice(1)}`);
const savedCode = tryLoadingCodeFromLocalStorage(window.buildMode);

if (savedCode) {
setCode(savedCode);
Expand All @@ -192,48 +194,15 @@ picture = ...
`);
}

const currentUrl = new URL(window.location);
const searchParams = currentUrl.searchParams;
const codeSrc = searchParams.get("loadSrc");
if(codeSrc) {
const fetchController = new AbortController();
sweetAlert({
title: Alert.title('Loading code'),
text: 'The code is being fetched. Please wait...',
onOpen: () => {
sweetAlert.showLoading();
sweetAlert.getCancelButton().disabled = false;
},
showConfirmButton: false,
showCancelButton: true,
showCloseButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
}).then(() => {
fetchController.abort();
});
try {
const response = await fetch(codeSrc, {
signal: fetchController.signal,
});
const code = await response.text();
setCode(code);
sweetAlert.close();
searchParams.delete("loadSrc");
window.history.replaceState(window.history.state, "", currentUrl.toString());
} catch (error) {
sweetAlert(
'Oops!',
'Could not load the code from source. Please try again.',
'error'
);
}
}
await tryFetchCodeFromSourceAndStripURL(async (code) => {
setCode(code);
await saveCodeToLocalStorageAndReplaceHash(code, window.buildMode);
});

if(window.preloadCode && window.buildMode === 'haskell'){
const codeToLoad = new DOMParser().parseFromString(window.preloadCode, 'text/html').documentElement.textContent;
setCode(codeToLoad);
await saveCodeToLocalStorageAndReplaceHash(codeToLoad, window.buildMode);
};
}

Expand Down Expand Up @@ -959,7 +928,7 @@ function stopRun() {
}
window.cancelCompile();

run('', '', '', false, null);
run(false, '', false, null);
}

function compile() {
Expand Down Expand Up @@ -1020,14 +989,10 @@ function compile() {
compilerMessage = 'Sorry! Your program couldn\'t be run right now.';
}

const codeHash = await sha256digest(src.trim());

window.program = compiledProgram;
run(codeHash,"deploy_hash",compilerMessage,false,compileGeneration);
localStorage.setItem(`${window.buildMode}-${codeHash}`, src);


run(status === 200,compilerMessage,false,compileGeneration);
sweetAlert.close();
await saveCodeToLocalStorageAndReplaceHash(src, window.buildMode);
return;
}

Expand Down
85 changes: 79 additions & 6 deletions web/js/codeworld_shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ function initializeLayoutContainer(options) {
}


function run(hash, dhash, msg, error, generation) {
function run(successful, msg, error, generation) {
window.runningGeneration = generation;
window.debugAvailable = false;
window.debugActive = false;
Expand All @@ -965,17 +965,13 @@ function run(hash, dhash, msg, error, generation) {
'*'
);

if (hash) {
window.location.hash = `#${hash}`;
}

runner.contentWindow.location.replace(`run?mode=${window.buildMode}`);
document.getElementById('runner').style.display = 'none';
document.getElementById('startRecButton').style.display = 'none';

const layoutHandler = $(LAYOUT_CONTAINER_CLASSNAME).layout();

if (hash || msg) {
if (successful || msg) {
layoutHandler.show('east');
layoutHandler.open('east');
} else {
Expand Down Expand Up @@ -1097,6 +1093,80 @@ async function sha256digest(data) {
});
}

async function saveCodeToLocalStorageAndReplaceHash(code, mode) {
const currentUrl = new URL(window.location);

try {
const codeHash = await sha256digest(code.trim());
localStorage.setItem(`${mode}-${codeHash}`, code);
currentUrl.hash = codeHash;

window.history.replaceState(window.history.state, "", currentUrl.toString());
} catch (error) {
console.error('Failed to save code to local storage:', error);
sweetAlert(
'Oops!',
'Unable to store code in local storage. Quota might have been exceeded.',
'error'
);
}
}
Comment thread
nimec01 marked this conversation as resolved.

function tryLoadingCodeFromLocalStorage(mode) {
const currentUrl = new URL(window.location);
const codeHash = currentUrl.hash.slice(1);
if(!codeHash) return;

return localStorage.getItem(`${mode}-${codeHash}`);
}

async function tryFetchCodeFromSourceAndStripURL(handler){
const currentUrl = new URL(window.location);
const searchParams = currentUrl.searchParams;

const codeSrc = searchParams.get("loadSrc");
if (!codeSrc) return;

const fetchController = new AbortController();
sweetAlert({
title: Alert.title('Loading code'),
text: 'The code is being fetched. Please wait...',
onOpen: () => {
sweetAlert.showLoading();
sweetAlert.getCancelButton().disabled = false;
},
showConfirmButton: false,
showCancelButton: true,
showCloseButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
}).then(() => {
fetchController.abort();
});
try {
const response = await fetch(codeSrc, {
signal: fetchController.signal,
});
if(response.ok) {
const code = await response.text();
searchParams.delete("loadSrc");
window.history.replaceState(window.history.state, "", currentUrl.toString());
sweetAlert.close();
await handler(code);
} else {
throw new Error(`Failed to fetch code from source: ${response.statusText}`);
}

} catch (error) {
sweetAlert(
'Oops!',
'Could not load the code from source. Please try again.',
'error'
);
}
}

export {
clearMessages,
definePanelExtension,
Expand All @@ -1114,4 +1184,7 @@ export {
toggleObsoleteCodeAlert,
warnIfUnsaved,
sha256digest,
saveCodeToLocalStorageAndReplaceHash,
tryLoadingCodeFromLocalStorage,
tryFetchCodeFromSourceAndStripURL,
};
50 changes: 25 additions & 25 deletions web/js/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
*/

import { sendHttp } from './utils/network.js';
import {
saveCodeToLocalStorageAndReplaceHash,
tryLoadingCodeFromLocalStorage,
tryFetchCodeFromSourceAndStripURL,
} from './codeworld_shared.js'
import * as Alert from './utils/alert.js';

// Tracks when the program started, and whether the program has done
// anything observable (as best we can tell). This is used to decide
Expand Down Expand Up @@ -233,41 +239,35 @@ function start() {
}

async function init() {
let paramList = location.search.slice(1).split('&');
const params = {};
for (let i = 0; i < paramList.length; i++) {
const name = decodeURIComponent(paramList[i].split('=')[0]);
const value = decodeURIComponent(paramList[i].slice(name.length + 1));
params[name] = value;
}
// params from the hash
paramList = location.hash.slice(1).split('&');
for (let i = 0; i < paramList.length; i++) {
const name = decodeURIComponent(paramList[i].split('=')[0]);
const value = decodeURIComponent(paramList[i].slice(name.length + 1));
params[name] = value;
}
await Alert.init();
const searchParams = new URLSearchParams(window.location.search);

let mode = params['mode'];
let mode = searchParams.get('mode');
if(!mode) mode = 'codeworld';

const savedCode = tryLoadingCodeFromLocalStorage(mode);
if(savedCode) {
window.preloadCode = savedCode;
}

const codeSrc = params['loadSrc'];

if(codeSrc || window.preloadCode) {
if(searchParams.has('loadSrc') || window.preloadCode) {
try {
let code = window.preloadCode;
if(!code) {
const response = await fetch(codeSrc);
code = await response.text();
if(!response.ok) {
throw new Error("Could not load source code from external location. Response code not OK.");
}
}
await tryFetchCodeFromSourceAndStripURL((fetchedCode) => {
code = fetchedCode;
});
}
Comment thread
nimec01 marked this conversation as resolved.

if(code.trim() === '')return;

Comment thread
patritzenfeld marked this conversation as resolved.
await saveCodeToLocalStorageAndReplaceHash(code, mode);

const data = new FormData();
data.append('source', code);
data.append('mode', mode);

const enablePreview = params['enablePreview'];
const enablePreview = searchParams.get('enablePreview');

if(enablePreview) data.append('enablePreview',enablePreview);

Expand Down
15 changes: 15 additions & 0 deletions web/run.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,25 @@
<script>
window.preloadCode = `/*CODE_TO_BE_LOADED_BY_DEFAULT*/`;
</script>
<link rel="stylesheet" href="css/theme-variables.css" />
<link rel="stylesheet" href="css/codeworld.css" />
<link
rel="stylesheet"
href="mirrored/cdn.materialdesignicons.com/3.6.95/css/materialdesignicons.min.css"
/>
<link
rel="stylesheet"
href="mirrored/ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css"
/>
</head>

<body></body>

<script type="module" src="js/run.js"></script>
<script type="text/javascript" src="js/debugmode.js"></script>
<script
src="mirrored/code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"
></script>
</html>