diff --git a/src/charlotte.ts b/src/charlotte.ts index 1d2d791..0aefd7a 100644 --- a/src/charlotte.ts +++ b/src/charlotte.ts @@ -1,5 +1,5 @@ export { version } from '../package.json'; -export { inject } from './injector/inject'; +export { injectVM, injectBlockly } from './injector/inject'; export { settings } from './util/settings'; import openFrontend from './frontend'; export { diff --git a/src/global.d.ts b/src/global.d.ts index b9853fd..cf330c2 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,6 +1,7 @@ /* eslint-disable multiline-comment-style */ /* eslint-disable @typescript-eslint/triple-slash-reference */ /// +/// /// /// /// @@ -20,6 +21,7 @@ declare interface Window { env: string; } >; + format?: formatMessage; openFrontend(): void; }; Scratch?: Context; diff --git a/src/index.ts b/src/index.ts index 58ceb27..345fe91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,15 @@ -import { trap, inject } from './injector/inject'; +import { trap, injectVM, injectBlockly } from './injector/inject'; import { log } from './util/log'; const open = window.open; // @ts-expect-error defined in webpack define plugin log(`eureka-loader ${__EUREKA_VERSION__}`); // Try injecting chibi into the page. const [vm, blockly] = await trap(open); -if (!!vm) { +if (vm) { // Alright we got the virtual machine, start the injection. window.eureka.vm = vm; - inject(vm, blockly); + injectVM(vm); + injectBlockly(blockly); } else { // This is not a Scratch page, stop injecting. log(`Cannot find vm in this page, stop injecting.`); diff --git a/src/injector/inject.ts b/src/injector/inject.ts index 470ad68..93a3340 100644 --- a/src/injector/inject.ts +++ b/src/injector/inject.ts @@ -169,14 +169,7 @@ export function trap (open: typeof window.open): Promise<[EurekaCompatibleVM | n return [null, null]; }); } - -/** - * Inject into the original virtual machine. - * @param vm {EurekaCompatibleVM} Original virtual machine instance. - */ -export function inject (vm: EurekaCompatibleVM, blockly: any) { - const loader = (window.eureka.loader = new EurekaLoader(vm)); - const originalLoadFunc = vm.extensionManager.loadExtensionURL; +function setupFormat (vm: EurekaCompatibleVM) { const getLocale = vm.getLocale; const format = formatMessage.namespace(); format.setup({ @@ -185,6 +178,18 @@ export function inject (vm: EurekaCompatibleVM, blockly: any) { generateId: (defaultMessage: string) => `${defaultMessage}`, translations: l10n }); + window.eureka.format = format; + return format; +} + +/** + * Inject into the original virtual machine. + * @param vm {EurekaCompatibleVM} Original virtual machine instance. + */ +export function injectVM (vm: EurekaCompatibleVM) { + const loader = (window.eureka.loader = new EurekaLoader(vm)); + const originalLoadFunc = vm.extensionManager.loadExtensionURL; + const format = setupFormat(vm); vm.extensionManager.loadExtensionURL = async function (extensionURL: string, ...args: []) { if (extensionURL in window.eureka.registeredExtension) { const { url, env } = window.eureka.registeredExtension[extensionURL]; @@ -453,7 +458,13 @@ export function inject (vm: EurekaCompatibleVM, blockly: any) { return originalGetOrderFunc.call(this, extensions, ...args); }; } +} +export function injectBlockly (blockly: any) { + const format = window.eureka.format; + if (!format) { + return error('You should inject VM first'); + } if (typeof blockly === 'object') { window.eureka.blockly = blockly; const originalAddCreateButton_ = blockly.Procedures.addCreateButton_; @@ -472,7 +483,7 @@ export function inject (vm: EurekaCompatibleVM, blockly: any) { warn('Cannot find real blockly instance, try alternative method...'); const originalProcedureCallback = window.Blockly?.getMainWorkspace()?.toolboxCategoryCallbacks_?.PROCEDURE; - if (!originalProcedureCallback) { + if (typeof originalProcedureCallback !== 'function') { error('alternative method failed, stop injecting'); return; } @@ -493,6 +504,7 @@ export function inject (vm: EurekaCompatibleVM, blockly: any) { workspace.toolboxRefreshEnabled_ = true; } } + function injectToolbox ( xmlList: HTMLElement[], workspace: EurekaCompatibleWorkspace,