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

use offline asseteditor.html from mkc cache #187

Merged
merged 3 commits into from
Mar 7, 2025
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@
"dependencies": {
"@types/path-browserify": "^1.0.0",
"@vscode/extension-telemetry": "^0.7.5",
"makecode-browser": "^1.3.1",
"makecode-core": "^1.7.0",
"makecode-browser": "^1.3.2",
"makecode-core": "^1.7.1",
"path-browserify": "^1.0.1"
}
}
9 changes: 9 additions & 0 deletions resources/assetMessaging.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

window.addEventListener("message", function (m) {
if (m.data._fromVscode) {
if (m.data.type === "fetch-html") {
frame.srcdoc = m.data.srcDoc;
return;
}

frame.contentWindow.postMessage(m.data, "*");

if (m.data.type === "open") {
Expand All @@ -20,5 +25,9 @@
});
document.addEventListener("DOMContentLoaded", function (event) {
frame = document.getElementById("asset-editor-frame");

vscode.postMessage({
type: "fetch-html"
});
});
}())
9 changes: 7 additions & 2 deletions resources/assetframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@

<body>
<div id="asset-editor-container">
<iframe id="asset-editor-frame" style="position:absolute;top:0;left:0;width:100%;height:100%;" src="@ASSETURL@" allowfullscreen="allowfullscreen"
sandbox="allow-popups allow-forms allow-scripts allow-same-origin" frameborder="0">
<iframe
id="asset-editor-frame"
style="position:absolute;top:0;left:0;width:100%;height:100%;"
allowfullscreen="allowfullscreen"
sandbox="allow-popups allow-forms allow-scripts allow-same-origin"
frameborder="0"
>
</iframe>
</div>
</body>
Expand Down
26 changes: 19 additions & 7 deletions src/web/assetEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { activeWorkspace, findFilesAsync, readFileAsync, writeFileAsync } from "./host";
import { syncJResAsync } from "./jres";
import { readTextFileAsync, throttle } from "./util";
import { getAssetEditorHtmlAsync } from "./makecodeOperations";

let extensionContext: vscode.ExtensionContext;
// const assetUrl = "http://localhost:3232/asseteditor.html";
Expand Down Expand Up @@ -70,6 +71,7 @@

protected panel: vscode.WebviewPanel;
protected editing: AssetEditorState | undefined;
protected assetEditorHtml: string | undefined;
protected disposables: vscode.Disposable[];
protected pendingMessages: {[index: string]: (res: any) => void} = {};
protected nextId = 0;
Expand Down Expand Up @@ -137,6 +139,12 @@
}

switch (message.type) {
case "fetch-html":
this.postMessageCore({
type: "fetch-html",
srcDoc: this.assetEditorHtml
});
break;
case "event":
this.handleSimulatorEventAsync(message);
break;
Expand All @@ -158,22 +166,28 @@
}

sendMessageAsync(message: any) {
message._fromVscode = true;
message.id = this.nextId++;

return new Promise<any>(resolve => {
this.pendingMessages[message.id] = resolve;
this.panel.webview.postMessage(message);
this.postMessageCore(message);
});
}

addDisposable(d: vscode.Disposable) {
this.disposables.push(d);
}

protected postMessageCore(message: any) {
message._fromVscode = true;
this.panel.webview.postMessage(message);
}

protected async initWebviewHtmlAsync() {
this.panel.webview.html = "";
const simulatorHTML = await getAssetEditorHtmlAsync(this.panel.webview);

this.assetEditorHtml = await getAssetEditorHtmlAsync(activeWorkspace());;
const simulatorHTML = await getAssetEditorLoaderHtmlAsync(this.panel.webview);
this.panel.webview.html = simulatorHTML;
}

Expand Down Expand Up @@ -220,16 +234,14 @@
}


async function getAssetEditorHtmlAsync(webview: vscode.Webview) {
async function getAssetEditorLoaderHtmlAsync(webview: vscode.Webview) {
const uri = vscode.Uri.joinPath(extensionContext.extensionUri, "resources", "assetframe.html");
const contents = await readTextFileAsync(uri);

const pathURL = (s: string) =>
webview.asWebviewUri(vscode.Uri.joinPath(extensionContext.extensionUri, "resources", s)).toString();

return contents
.replace(/@RES@\/([\w\-\.]+)/g, (f, fn) => pathURL(fn))
.replace("@ASSETURL@", assetUrl);
return contents.replace(/@RES@\/([\w\-\.]+)/g, (f, fn) => pathURL(fn));
}

async function readProjectJResAsync() {
Expand Down Expand Up @@ -272,7 +284,7 @@
async function readProjectPaletteAsync() {
const config = await readFileAsync("./pxt.json", "utf8");
const parsed = JSON.parse(config);
if (parsed.palette) return parsed.palette as string[];

Check warning on line 287 in src/web/assetEditor.ts

View workflow job for this annotation

GitHub Actions / buildpr

Expected { after 'if' condition
}

async function saveFilesAsync(files: {[index: string]: string}) {
Expand Down
119 changes: 59 additions & 60 deletions src/web/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function createVsCodeHost(): Host {
existsAsync: async (p) => existsAsync(rmFolderPrefix(p)),
unlinkAsync: async (p) => unlinkAsync(rmFolderPrefix(p)),
cwdAsync: async () => getFolderName(),
symlinkAsync: async () => {},
symlinkAsync: async () => { },
listFilesAsync: async (d, f) => listFilesAsync(rmFolderPrefix(d), f),
requestAsync: httpRequestCoreAsync,
createLanguageServiceAsync: async (editor) => new BrowserLanguageService(editor),
Expand All @@ -24,7 +24,8 @@ export function createVsCodeHost(): Host {
throw new Error(`Exit with status ${code}`);
},
bufferToString: buffer => new TextDecoder().decode(buffer),
stringToBuffer
stringToBuffer,
base64EncodeBufferAsync
};
}

Expand Down Expand Up @@ -104,78 +105,65 @@ async function listFilesAsync(directory: string, filename: string) {
});
}

export function httpRequestCoreAsync(options: HttpRequestOptions) {
return new Promise<HttpResponse>((resolve, reject) => {
let client: XMLHttpRequest;
let resolved = false;
export async function httpRequestCoreAsync(options: HttpRequestOptions) {
const headers = options.headers || {};
const data = options.data;
const method = options.method || (data == null ? "GET" : "POST");

let buf: null | Uint8Array | string;

if (data == null) {
buf = null;
} else if (data instanceof Uint8Array) {
buf = data;
} else if (typeof data === "object") {
buf = JSON.stringify(data);
headers["content-type"] = "application/json; charset=utf8";
} else if (typeof data === "string") {
buf = data;
} else {
throw new Error("bad data");
}

let headers = options.headers || {};
const requestHeaders = new Headers();
Object.keys(headers).forEach(k => {
requestHeaders.set(k, headers[k]);
});

client = new XMLHttpRequest();
client.onreadystatechange = () => {
if (resolved) {return;} // Safari/iOS likes to call this thing more than once
const resp = await fetch(options.url, {
method,
headers: requestHeaders,
body: buf
});

if (client.readyState === 4) {
resolved = true;
let res: HttpResponse = {
statusCode: client.status,
headers: {},
buffer: (client as any).responseBody || client.response,
text: client.responseText,
};
const body = await resp.arrayBuffer();

if (typeof res.buffer === "string") {
res.buffer = new TextEncoder().encode(res.buffer);
}
const allHeaders = client.getAllResponseHeaders();
allHeaders.split(/\r?\n/).forEach(l => {
let m = /^\s*([^:]+): (.*)/.exec(l);
if (m) {
res.headers[m[1].toLowerCase()] = m[2];
}
});
resolve(res);
}
};
let text: string | undefined;

let data = options.data;
let method = options.method || (data == null ? "GET" : "POST");

let buf: any;

if (data == null) {
buf = null;
} else if (data instanceof Uint8Array) {
buf = data;
} else if (typeof data === "object") {
buf = JSON.stringify(data);
headers["content-type"] = "application/json; charset=utf8";
} else if (typeof data === "string") {
buf = data;
} else {
throw new Error("bad data");
}
try {
text = new TextDecoder().decode(body);
}
catch (e) {
// binary data
}

client.open(method, options.url);
const res: HttpResponse = {
statusCode: resp.status,
headers: {},
buffer: new Uint8Array(body),
text,
};

Object.keys(headers).forEach(k => {
client.setRequestHeader(k, headers[k]);
});
resp.headers.forEach((value, key) => res.headers[key.toLowerCase()] = value);

if (buf == null) {
client.send();
}
else {
client.send(buf);
}
});
return res;
}

function resolvePath(path: string) {
return vscode.Uri.joinPath(activeWorkspace().uri, path);
}

export function stringToBuffer(str: string, encoding?: string){
export function stringToBuffer(str: string, encoding?: string) {
let contents: string;
if (encoding === "base64") {
try {
Expand Down Expand Up @@ -237,4 +225,15 @@ export async function findFilesAsync(extension: string, root: vscode.Uri, matchW
}

return result;
}

function base64EncodeBufferAsync(buffer: Uint8Array | ArrayBuffer): Promise<string> {
return new Promise<string>(resolve => {
const reader = new FileReader();
reader.onload = () => {
const url = reader.result as string;
resolve(url.slice(url.indexOf(',') + 1));
};
reader.readAsDataURL(new Blob([buffer]));
});
}
4 changes: 4 additions & 0 deletions src/web/makecodeOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export function getSimHtmlAsync(folder: vscode.WorkspaceFolder, cancellationToke
return enqueueOperationAsync(folder, () => cmd.getSimHTML({}), cancellationToken);
}

export function getAssetEditorHtmlAsync(folder: vscode.WorkspaceFolder, cancellationToken?: vscode.CancellationToken) {
return enqueueOperationAsync(folder, () => cmd.getAssetEditorHTML({}), cancellationToken);
}

/**
* The mkc CLI uses global state, so we need to perform operations in a queue just in case the
* user is doing things in multiple workspaces at once
Expand Down
Loading
Loading