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,