Fassung 1.5.0: die Vorschau wird zur Arbeitsflaeche
Abgleich mit dem Flatsome UX Builder (docs/FLATSOME-ABGLEICH.md): die Gestaltung ist Flatsome voraus, die Luecken liegen beim Elementkatalog und bei der Bedienung. Umuts Entscheidung: Bedienung zuerst, Shop-Elemente ausgelassen. Erste Haelfte der Bedienung: - Werkzeugleiste am Element in der Vorschau. Sie nennt das Element, auf das sie wirkt - die Seitenleiste hat dieselben fuenf Aktionen, und zwei gleichnamige Bedienelemente auf einem Bildschirm sind fuer eine Sprachausgabe nicht unterscheidbar. Beide Wege rufen dieselben Funktionen auf. - Auswahl- und Ueberfahrrahmen mit Beschriftung. - Einfuegepunkte an Ober- und Unterkante: das naechste Element landet dort statt am Ende. - Ziehen aus dem Werkzeugkasten in die Vorschau, mit Ablegemarke zwischen den Elementen und Rahmen um einen aufnehmenden Behaelter. Der Strukturbaum zieht in dieselbe Flaeche. Die Ebene liegt ueber dem Rahmen, nicht darin: die Vorschau wird bei jeder Aenderung ersetzt, eingezeichnete Bedienelemente waeren weg und stuenden in der Auszeichnung, die die Vorschau wahrheitsgetreu zeigen soll. Leiste und Pluszeichen werden gegenskaliert und bleiben in der Mobilvorschau fingergross. Im Modell neu: insertBlockAt, moveBlockTo, dropList. Dabei behoben: die Ebene war aria-hidden und enthielt fokussierbare Schaltflaechen; canContain zerbrach an einem fehlenden Block beim Ziehen aus dem Werkzeugkasten; beim Verschieben ans Listenende wurde der Index begrenzt, bevor die Entnahme verrechnet war. Geprueft: npm test 22/22, phpunit 434/434, npm run test:editor vollstaendig mit neuem Abschnitt und ohne axe-Verstoss. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
af5a2cef86
commit
22e4ada830
10 files changed
+841
-27
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { EditorHistory, createBlock, locate, insertBlock, duplicateBlock, moveBlock, upgradeDocument, effectiveDesign, setDesign, insertPreset, insertRow, blockPath, insertMedia, setEffect, isPluginBlock, blockLabel, blockIcon, canContain, isContainer, setStyle, effectiveStyle, hoverStyle, resetStyleDevice, clearStyle, copyStyle, SCHEMA_VERSION } from '../public/assets/editor-model.js';
|
||||
import { EditorHistory, createBlock, locate, insertBlock, insertBlockAt, moveBlockTo, dropList, duplicateBlock, moveBlock, upgradeDocument, effectiveDesign, setDesign, insertPreset, insertRow, blockPath, insertMedia, setEffect, isPluginBlock, blockLabel, blockIcon, canContain, isContainer, setStyle, effectiveStyle, hoverStyle, resetStyleDevice, clearStyle, copyStyle, SCHEMA_VERSION } from '../public/assets/editor-model.js';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { designCss } from '../scripts/build-design.mjs';
|
||||
|
||||
@@ -364,3 +364,64 @@ test('a current document still accepts new blocks, and every block type can be i
|
||||
assert.throws(() => upgradeDocument({ schemaVersion: 99, blocks: [] }, 6), /Unbekanntes Dokumentschema/);
|
||||
assert.throws(() => upgradeDocument({ schemaVersion: 5, blocks: [] }, SCHEMA_VERSION + 1), /Unbekanntes Dokumentschema/);
|
||||
});
|
||||
|
||||
// --- Punktgenaues Einfuegen und Verschieben -------------------------------------------------
|
||||
// Die Grundlage fuer das Ablegen in der Vorschau: dort zaehlt die Stelle, nicht die Auswahl.
|
||||
|
||||
test('a drop lands at the exact position, also at the very end of a list', () => {
|
||||
const document = fixture();
|
||||
const section = locate(document.blocks, 's1').block;
|
||||
insertBlockAt(document, 'text', 's1', 0);
|
||||
assert.deepEqual(section.children.map(block => block.type), ['text', 'heading', 'text']);
|
||||
insertBlockAt(document, 'button', 's1', section.children.length);
|
||||
assert.equal(section.children.at(-1).type, 'button');
|
||||
// Ein Index jenseits des Endes haengt an, statt zu scheitern.
|
||||
assert.ok(insertBlockAt(document, 'button', 's1', 99));
|
||||
assert.equal(section.children.length, 5);
|
||||
});
|
||||
|
||||
test('moving to an exact position settles the shift before it clamps', () => {
|
||||
const order = document => document.blocks[0].children.map(block => block.id);
|
||||
const document = fixture();
|
||||
insertBlockAt(document, 'button', 's1', 2);
|
||||
const ids = order(document);
|
||||
// Nach hinten: die Entnahme verschiebt jede spaetere Stelle um eins.
|
||||
assert.equal(moveBlockTo(document, ids[0], 's1', 2), true);
|
||||
assert.deepEqual(order(document), [ids[1], ids[0], ids[2]]);
|
||||
// Ganz ans Ende. Ohne die richtige Reihenfolge von Verrechnen und Begrenzen landete der
|
||||
// Block hier eine Stelle zu frueh.
|
||||
assert.equal(moveBlockTo(document, ids[1], 's1', 3), true);
|
||||
assert.deepEqual(order(document), [ids[0], ids[2], ids[1]]);
|
||||
// Nach vorne: dort wird nichts verrechnet.
|
||||
assert.equal(moveBlockTo(document, ids[1], 's1', 0), true);
|
||||
assert.deepEqual(order(document), [ids[1], ids[0], ids[2]]);
|
||||
});
|
||||
|
||||
test('a drop never detaches a branch and never breaks a container rule', () => {
|
||||
const document = fixture();
|
||||
upgradeDocument(document, SCHEMA_VERSION);
|
||||
// Eine Sektion in ihr eigenes Kind: das wuerde den Ast abtrennen.
|
||||
assert.equal(moveBlockTo(document, 's1', 'h1', 0), false);
|
||||
assert.equal(moveBlockTo(document, 's1', 's1', 0), false);
|
||||
assert.equal(document.blocks.length, 2);
|
||||
// Eine Galerie nimmt nur Bilder.
|
||||
const galleryId = insertBlock(document, 'gallery', null);
|
||||
assert.equal(moveBlockTo(document, 'h1', galleryId, 0), false);
|
||||
assert.equal(locate(document.blocks, 'h1').parent.id, 's1');
|
||||
assert.equal(insertBlockAt(document, 'text', galleryId, 0), null);
|
||||
assert.ok(insertBlockAt(document, 'image', galleryId, 0));
|
||||
});
|
||||
|
||||
test('the top level takes everything the validator takes there, and nothing else', () => {
|
||||
const document = fixture();
|
||||
upgradeDocument(document, SCHEMA_VERSION);
|
||||
// Ein Akkordeon-Eintrag und ein Tab gehoeren in ihre Gruppe - der Validator lehnt sie sonst ab.
|
||||
assert.equal(dropList(document, null, { type: 'accordionitem' }), null);
|
||||
assert.equal(dropList(document, null, { type: 'tabitem' }), null);
|
||||
// Alles andere darf dort stehen, genau wie ueber die Schaltflaechen.
|
||||
for (const type of ['section', 'heading', 'image', 'text']) {
|
||||
assert.equal(dropList(document, null, { type }), document.blocks, type);
|
||||
}
|
||||
// Beim Ziehen aus dem Werkzeugkasten gibt es den Block noch nicht.
|
||||
assert.doesNotThrow(() => dropList(document, 's1', null));
|
||||
});
|
||||
Reference in new issue
Block a user