diff --git a/pxtsim/runtime.ts b/pxtsim/runtime.ts index 3a95257e847..3b274aa58bd 100644 --- a/pxtsim/runtime.ts +++ b/pxtsim/runtime.ts @@ -148,7 +148,7 @@ namespace pxsim { return Promise.all(values.map(v => mapper(v))); } - export function promiseMapAllSeries(values: T[], mapper: (obj: T) => Promise): Promise { + export function promiseMapAllSeries(values: T[], mapper: (obj: T) => Promise): Promise { return promisePoolAsync(1, values, mapper); } @@ -193,7 +193,7 @@ namespace pxsim { }, ms); }); - return Promise.race([ promise, timeoutPromise ]) + return Promise.race([promise, timeoutPromise]) .then(output => { // clear any dangling timeout if (res) { @@ -311,6 +311,14 @@ namespace pxsim { }) return v; } + + export function sanitizeCssName(name: string): string { + let sanitized = name.replace(/[^a-zA-Z0-9-_]/g, '_'); + if (!/^[a-zA-Z_]/.test(sanitized)) { + sanitized = 'cls_' + sanitized; + } + return sanitized; + } } export interface Map { @@ -575,7 +583,7 @@ namespace pxsim { class EventHandler { private busy = 0; - constructor(public handler: RefAction, public flags: number) {} + constructor(public handler: RefAction, public flags: number) { } async runAsync(eventValue: EventIDType, runtime: Runtime, valueToArgs?: EventValueToActionArgs) { // The default behavior can technically be configured in codal, but we always set it to queue if busy @@ -597,9 +605,9 @@ namespace pxsim { } private async runFiberAsync(eventValue: EventIDType, runtime: Runtime, valueToArgs?: EventValueToActionArgs) { - this.busy ++; + this.busy++; await runtime.runFiberAsync(this.handler, ...(valueToArgs ? valueToArgs(eventValue) : [eventValue])); - this.busy --; + this.busy--; } } @@ -680,7 +688,7 @@ namespace pxsim { this._handlers = [new EventHandler(a, flags)]; } else { - this._addRemoveLog.push({ act: a, log: LogType.UserSet, flags}); + this._addRemoveLog.push({ act: a, log: LogType.UserSet, flags }); } } diff --git a/pxtsim/simdriver.ts b/pxtsim/simdriver.ts index 0f8710e2d0f..edd30cac22a 100644 --- a/pxtsim/simdriver.ts +++ b/pxtsim/simdriver.ts @@ -393,13 +393,15 @@ namespace pxsim { this.options.simulatorExtensions && this.options.simulatorExtensions[messageChannel]; - const startSimulatorExtension = (url: string, permanent: boolean) => { + const startSimulatorExtension = (url: string, permanent: boolean, aspectRatio: number) => { + aspectRatio = aspectRatio || this._runOptions?.aspectRatio || 1.22; let wrapper = this.createFrame(url); this.container.appendChild(wrapper); const messageFrame = wrapper.firstElementChild as HTMLIFrameElement; messageFrame.dataset[FRAME_DATA_MESSAGE_CHANNEL] = messageChannel; + messageFrame.dataset[FRAME_ASPECT_RATIO] = aspectRatio + ""; pxsim.U.addClass(wrapper, "simmsg") - pxsim.U.addClass(wrapper, "simmsg" + messageChannel) + pxsim.U.addClass(wrapper, "simmsg" + U.sanitizeCssName(messageChannel)) if (permanent) messageFrame.dataset[PERMANENT] = "true"; this.startFrame(messageFrame); @@ -417,7 +419,7 @@ namespace pxsim { url.searchParams.set("parentOrigin", encodeURIComponent(this.options.parentOrigin)); if (this.options.userLanguage) url.searchParams.set("language", encodeURIComponent(this.options.userLanguage)); - startSimulatorExtension(url.toString(), simulatorExtension.permanent); + startSimulatorExtension(url.toString(), simulatorExtension.permanent, simulatorExtension.aspectRatio); } // not running the current run, restart else if (messageFrame.dataset['runid'] != this.runId) { @@ -434,7 +436,7 @@ namespace pxsim { const url = ((useLocalHost && messageSimulator.localHostUrl) || messageSimulator.url) .replace("$PARENT_ORIGIN$", encodeURIComponent(this.options.parentOrigin || "")) .replace("$LANGUAGE$", encodeURIComponent(this.options.userLanguage)) - startSimulatorExtension(url, messageSimulator.permanent); + startSimulatorExtension(url, messageSimulator.permanent, messageSimulator.aspectRatio); } // not running the curren run, restart else if (messageFrame.dataset['runid'] != this.runId) {