Isolate RNG drafts and fix image editor lifecycle
Some checks failed
Deploy Sokko G / deploy (push) Failing after 2s
Some checks failed
Deploy Sokko G / deploy (push) Failing after 2s
This commit is contained in:
parent
7c0b72f914
commit
b470a34b2a
7 changed files with 297 additions and 50 deletions
85
e2e/fixtures/editor-lifecycle-probe.js
Normal file
85
e2e/fixtures/editor-lifecycle-probe.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
// Rôle : monte les éditeurs réels sous StrictMode et contrôle les décodages concurrents.
|
||||
/* global URL */
|
||||
import { createElement, StrictMode, useLayoutEffect, useState } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { flushSync } from "react-dom";
|
||||
import { ImageViewer } from "../../website/src/components/ImageViewer.jsx";
|
||||
import { ToolboxCoverEditor } from "../../website/src/features/toolboxes/ToolboxCoverEditor.jsx";
|
||||
import { RngSimulatorModule } from "../../website/src/features/toolboxes/modules/RngSimulatorModule.jsx";
|
||||
import { normalizeRngSimulatorData } from "../../website/src/features/toolboxes/storage/toolboxStorage.js";
|
||||
|
||||
export function mountEditorProbe(element, kind, initialProps) {
|
||||
const root = createRoot(element);
|
||||
const snapshots = [];
|
||||
const saves = [];
|
||||
let updateProps;
|
||||
const components = { viewer: ImageViewer, cover: ToolboxCoverEditor, rng: RngSimulatorModule };
|
||||
function Probe() {
|
||||
const [props, setProps] = useState(initialProps);
|
||||
updateProps = setProps;
|
||||
useLayoutEffect(() => {
|
||||
snapshots.push(Array.from(element.querySelectorAll("input"), (input) => input.value));
|
||||
});
|
||||
const context = {
|
||||
getModuleData: () => props.data,
|
||||
normalizeRngSimulatorData,
|
||||
setModuleData: (_toolbox, _module, data) => {
|
||||
saves.push(data);
|
||||
setProps((current) => ({ ...current, data }));
|
||||
},
|
||||
uid: () => "new-rate"
|
||||
};
|
||||
return createElement(components[kind], {
|
||||
toolboxId: "probe", moduleId: "rng", context,
|
||||
onClose: () => {}, onSave: (value) => saves.push(value),
|
||||
setEditing: (editing) => setProps((current) => ({ ...current, editing })),
|
||||
...props
|
||||
});
|
||||
}
|
||||
flushSync(() => root.render(createElement(StrictMode, null, createElement(Probe))));
|
||||
return {
|
||||
snapshots, saves,
|
||||
update(patch) {
|
||||
snapshots.length = 0;
|
||||
flushSync(() => updateProps((props) => ({ ...props, ...patch })));
|
||||
},
|
||||
unmount: () => flushSync(() => root.unmount())
|
||||
};
|
||||
}
|
||||
|
||||
export function controlImageDecoding() {
|
||||
const originalDecode = globalThis.createImageBitmap;
|
||||
const originalCreate = URL.createObjectURL;
|
||||
const originalRevoke = URL.revokeObjectURL;
|
||||
const pending = [];
|
||||
const created = [];
|
||||
const revoked = [];
|
||||
const closed = [];
|
||||
globalThis.createImageBitmap = (file) => new Promise((resolve, reject) => {
|
||||
pending.push({ file, resolve, reject });
|
||||
});
|
||||
URL.createObjectURL = (file) => {
|
||||
const url = originalCreate(file);
|
||||
created.push(url);
|
||||
return url;
|
||||
};
|
||||
URL.revokeObjectURL = (url) => {
|
||||
revoked.push(url);
|
||||
originalRevoke(url);
|
||||
};
|
||||
return {
|
||||
pending, created, revoked, closed,
|
||||
async resolve(index) {
|
||||
const bitmap = await originalDecode(pending[index].file);
|
||||
const close = bitmap.close.bind(bitmap);
|
||||
bitmap.close = () => { closed.push(index); close(); };
|
||||
pending[index].resolve(bitmap);
|
||||
},
|
||||
reject: (index) => pending[index].reject(new Error("decode failed")),
|
||||
restore() {
|
||||
globalThis.createImageBitmap = originalDecode;
|
||||
URL.createObjectURL = originalCreate;
|
||||
URL.revokeObjectURL = originalRevoke;
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue