Skip to content

Commit 61f6521

Browse files
author
DavidQ
committed
Add two-click text placement wire edit toolbar and clear Paint on right click - PR_26133_073-text-placement-edit-toolbar-and-right-click-paint-clear
1 parent 23f6bd4 commit 61f6521

6 files changed

Lines changed: 245 additions & 39 deletions

File tree

docs/dev/reports/playwright_v8_coverage_report.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Playwright V8 Coverage Report
22

3-
PR: PR_26133_072-drawing-hint-enter-complete-and-text-restore
3+
PR: PR_26133_073-text-placement-edit-toolbar-and-right-click-paint-clear
44

55
Source: docs/dev/reports/playwright_v8_coverage_report.txt generated by the latest npm run test:workspace-v2 run.
66

@@ -21,10 +21,11 @@ Source: docs/dev/reports/playwright_v8_coverage_report.txt generated by the late
2121

2222
## Changed Runtime JS Files Covered
2323

24-
- (95%) tools/object-vector-studio-v2/js/ToolStarterApp.js - executed lines 6432/6432; executed functions 651/682
24+
- (83%) tools/object-vector-studio-v2/js/bootstrap.js - executed lines 109/109; executed functions 5/6
25+
- (96%) tools/object-vector-studio-v2/js/ToolStarterApp.js - executed lines 6594/6594; executed functions 669/700
2526

2627
## Changed JS Files Considered
2728

29+
- (83%) tools/object-vector-studio-v2/js/bootstrap.js - changed runtime JS file with browser V8 coverage
30+
- (96%) tools/object-vector-studio-v2/js/ToolStarterApp.js - changed runtime JS file with browser V8 coverage
2831
- (0%) tests/playwright/tools/WorkspaceManagerV2.spec.mjs - Playwright test file, not collected as browser runtime coverage
29-
- (95%) tools/object-vector-studio-v2/js/ToolStarterApp.js - changed runtime JS file with browser V8 coverage
30-
- (0%) tools/object-vector-studio-v2/styles/toolStarter.css - CSS file, not collected by browser JavaScript V8 coverage

docs/dev/reports/playwright_workspace_v2_results.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
# Playwright Workspace V2 Results
22

3-
PR: PR_26133_072-drawing-hint-enter-complete-and-text-restore
3+
PR: PR_26133_073-text-placement-edit-toolbar-and-right-click-paint-clear
44

55
## Validation
66

77
- PASS: npm run test:workspace-v2
88
- Result: 54 passed
9-
- Runtime: 5.3m
9+
- Runtime: 5.1m
1010
- Browser project: playwright
1111
- Workers: 1
1212

1313
## Targeted Checks Covered
1414

15-
- Drawing hint keeps "Double-click / Enter to complete" and renders as a fixed-size HTML overlay outside SVG canvas scaling.
16-
- Hint follows the pointer with offset and keeps pointer-events disabled.
17-
- Hint size remains stable at 100%, 300%, and 50% zoom states.
18-
- Polygon and Polyline Enter completion remain covered through drawing helpers.
19-
- Polygon double-click completion is explicitly verified.
20-
- Text preview uses restored normal SVG text style attributes while avoiding dashed preview artifacts for wide stroke width.
15+
- Text tool uses first click, live preview, and second click commit for schema-valid text placement.
16+
- Text preview and committed text preserve active stroke color, stroke opacity, stroke width, and transparent fill.
17+
- Object Preview toolbar enables Undo, Copy, and Paste when valid; Paste uses copied shape data; Undo/Redo restore shape count.
18+
- Right-click on a shape applies transparent Paint/fill only to the clicked shape and suppresses the browser context menu.
19+
- Stroke-mode right-click no longer clears stroke.
2120

2221
## Console/Runtime Errors
2322

tests/playwright/tools/WorkspaceManagerV2.spec.mjs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,18 +2953,15 @@ test.describe("Workspace Manager V2 bootstrap", () => {
29532953
});
29542954
await page.locator("#objectVectorStudioV2StrokeModeButton").click();
29552955
await rightClickPreviewShape(1);
2956-
await expect(page.locator("#statusLog")).toHaveValue(/OK Applied transparent stroke to shape row 1 by right-click\./);
2957-
await expect(page.locator("#objectVectorStudioV2JsonDetails")).toContainText('"stroke": "#00000000"');
2958-
const shapeOneStyleAfterTransparentStroke = await page.evaluate(() => ({
2956+
await expect(page.locator("#statusLog")).toHaveValue(/OK Applied transparent fill to shape row 1 by right-click\./);
2957+
await expect(page.locator("#objectVectorStudioV2JsonDetails")).not.toContainText('"stroke": "#00000000"');
2958+
const shapeOneStyleAfterSecondRightClick = await page.evaluate(() => ({
29592959
contextMenuPrevented: window.__objectVectorStudioV2ContextMenuPrevented,
29602960
style: { ...window.__objectVectorStudioV2App.selectedShape().style }
29612961
}));
2962-
expect(shapeOneStyleAfterTransparentStroke).toEqual({
2962+
expect(shapeOneStyleAfterSecondRightClick).toEqual({
29632963
contextMenuPrevented: true,
2964-
style: {
2965-
...shapeOneStyleAfterTransparentFill.style,
2966-
stroke: "#00000000"
2967-
}
2964+
style: shapeOneStyleAfterTransparentFill.style
29682965
});
29692966
await expect(page.locator("#objectVectorStudioV2FillOpacity")).toHaveValue("128");
29702967
await expect(page.locator("#objectVectorStudioV2StrokeOpacity")).toHaveValue("166");
@@ -2973,7 +2970,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
29732970
await page.keyboard.press("I");
29742971
await expect(page.locator('[data-shape-tool="picker"]')).toHaveAttribute("aria-pressed", "true");
29752972
await clickPreviewShape(1);
2976-
await expect(page.locator("#statusLog")).toHaveValue(/OK Picker sampled shape row 1: fill #00000000, stroke #00000000, fill opacity 0\.502, stroke opacity 0\.651, stroke width 2\./);
2973+
await expect(page.locator("#statusLog")).toHaveValue(/OK Picker sampled shape row 1: fill #00000000, stroke #6fd3ff, fill opacity 0\.502, stroke opacity 0\.651, stroke width 2\./);
29772974
const pickerState = await page.evaluate(() => {
29782975
const app = window.__objectVectorStudioV2App;
29792976
return {
@@ -2995,7 +2992,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
29952992
paletteTarget: "stroke",
29962993
selectedFillColor: "#00000000",
29972994
selectedFillOpacity: 0.502,
2998-
selectedStrokeColor: "#00000000",
2995+
selectedStrokeColor: "#6fd3ff",
29992996
selectedStrokeOpacity: 0.651,
30002997
shapeStyle: shapeOneStyleBeforePicker,
30012998
strokeInput: "166",
@@ -3661,7 +3658,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
36613658
await drawObjectVectorShape(page, "circle", [{ x: 20, y: -20 }, { x: 45, y: -20 }]);
36623659
await drawObjectVectorShape(page, "ellipse", [{ x: 60, y: -30 }, { x: 95, y: -5 }]);
36633660
await drawObjectVectorShape(page, "triangle", [{ x: -30, y: 50 }, { x: 10, y: 80 }]);
3664-
await drawObjectVectorShape(page, "text", [{ x: 50, y: 50 }]);
3661+
await drawObjectVectorShape(page, "text", [{ x: 50, y: 50 }, { x: 60, y: 62 }]);
36653662
const strokeOnlyCreatedShapes = await page.evaluate(() => {
36663663
const createdTools = ["rectangle", "square", "circle", "ellipse", "triangle", "text"];
36673664
return window.__objectVectorStudioV2App.selectedObject().shapes
@@ -3726,6 +3723,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
37263723
const textPreview = await page.locator("#objectVectorStudioV2RenderSurface text.object-vector-studio-v2__drawing-preview").evaluate((preview) => ({
37273724
dash: preview.style.strokeDasharray,
37283725
fill: preview.getAttribute("fill"),
3726+
fontSize: Number(preview.getAttribute("font-size")),
37293727
stroke: preview.getAttribute("stroke"),
37303728
strokeWidth: Number(preview.getAttribute("stroke-width")),
37313729
text: preview.textContent.trim(),
@@ -3734,19 +3732,49 @@ test.describe("Workspace Manager V2 bootstrap", () => {
37343732
expect(textPreview).toEqual({
37353733
dash: "none",
37363734
fill: "#00000000",
3735+
fontSize: 60,
37373736
stroke: "#6fd3ff",
37383737
strokeWidth: 20,
37393738
text: "Text",
37403739
tool: "text"
37413740
});
37423741
await clickObjectVectorLogicalPoint(page, 76, 66);
3743-
const committedTextStyle = await page.evaluate(() => ({ ...window.__objectVectorStudioV2App.selectedShape().style }));
3744-
expect(committedTextStyle).toMatchObject({
3742+
const committedText = await page.evaluate(() => ({
3743+
geometry: { ...window.__objectVectorStudioV2App.selectedShape().geometry },
3744+
shapeCount: window.__objectVectorStudioV2App.selectedObject().shapes.length,
3745+
style: { ...window.__objectVectorStudioV2App.selectedShape().style }
3746+
}));
3747+
expect(committedText.geometry).toEqual({ fontSize: 6, text: "Text", x: 70, y: 66 });
3748+
expect(committedText.style).toMatchObject({
37453749
fill: "#00000000",
37463750
stroke: "#6fd3ff",
37473751
strokeOpacity: 1,
37483752
strokeWidth: 20
37493753
});
3754+
const previewToolbarAfterText = await page.evaluate(() => Array.from(document.querySelectorAll(".object-vector-studio-v2__preview-edit-toolbar button")).map((button) => ({
3755+
disabled: button.disabled,
3756+
label: button.textContent.trim()
3757+
})));
3758+
expect(previewToolbarAfterText).toEqual([
3759+
{ disabled: false, label: "Undo" },
3760+
{ disabled: true, label: "Redo" },
3761+
{ disabled: false, label: "Copy" },
3762+
{ disabled: true, label: "Paste" }
3763+
]);
3764+
await page.locator("#objectVectorStudioV2PreviewCopyButton").click();
3765+
await expect(page.locator("#statusLog")).toHaveValue(/OK Copied shape row \d+ to Object Preview clipboard\./);
3766+
await expect(page.locator("#objectVectorStudioV2PreviewPasteButton")).toBeEnabled();
3767+
await page.locator("#objectVectorStudioV2PreviewPasteButton").click();
3768+
await expect(page.locator("#statusLog")).toHaveValue(/OK Pasted copied shape into Drawing Flow\./);
3769+
await expect.poll(async () => page.evaluate(() => window.__objectVectorStudioV2App.selectedObject().shapes.length)).toBe(committedText.shapeCount + 1);
3770+
await expect(page.locator("#objectVectorStudioV2PreviewUndoButton")).toBeEnabled();
3771+
await page.locator("#objectVectorStudioV2PreviewUndoButton").click();
3772+
await expect(page.locator("#statusLog")).toHaveValue(/OK Undo applied to Object Preview edits\./);
3773+
await expect.poll(async () => page.evaluate(() => window.__objectVectorStudioV2App.selectedObject().shapes.length)).toBe(committedText.shapeCount);
3774+
await expect(page.locator("#objectVectorStudioV2PreviewRedoButton")).toBeEnabled();
3775+
await page.locator("#objectVectorStudioV2PreviewRedoButton").click();
3776+
await expect(page.locator("#statusLog")).toHaveValue(/OK Redo applied to Object Preview edits\./);
3777+
await expect.poll(async () => page.evaluate(() => window.__objectVectorStudioV2App.selectedObject().shapes.length)).toBe(committedText.shapeCount + 1);
37503778

37513779
const shapeCountBeforeDoubleClick = await page.evaluate(() => window.__objectVectorStudioV2App.selectedObject().shapes.length);
37523780
await page.locator('[data-shape-tool="polygon"]').click();

tools/object-vector-studio-v2/index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ <h2 class="tools-platform-frame__eyebrow">First-Class Tools Surface V2</h2>
126126
<div id="objectVectorStudioV2ObjectPreviewFooter" class="object-vector-studio-v2__preview-footer">Object ID: none</div>
127127
<hr class="object-vector-studio-v2__separator">
128128
<div class="object-vector-studio-v2__preview-edit-toolbar" aria-label="Object preview edit actions">
129-
<button id="objectVectorStudioV2PreviewUndoButton" type="button" disabled title="Undo is not wired for Object Preview edits yet" aria-label="Undo">Undo</button>
130-
<button id="objectVectorStudioV2PreviewRedoButton" type="button" disabled title="Redo is not wired for Object Preview edits yet" aria-label="Redo">Redo</button>
131-
<button id="objectVectorStudioV2PreviewCopyButton" type="button" disabled title="Copy is not wired for Object Preview edits yet" aria-label="Copy">Copy</button>
132-
<button id="objectVectorStudioV2PreviewPasteButton" type="button" disabled title="Paste is not wired for Object Preview edits yet" aria-label="Paste">Paste</button>
129+
<button id="objectVectorStudioV2PreviewUndoButton" type="button" disabled title="Undo the last Object Preview edit" aria-label="Undo">Undo</button>
130+
<button id="objectVectorStudioV2PreviewRedoButton" type="button" disabled title="Redo the last undone Object Preview edit" aria-label="Redo">Redo</button>
131+
<button id="objectVectorStudioV2PreviewCopyButton" type="button" disabled title="Copy the selected shape" aria-label="Copy">Copy</button>
132+
<button id="objectVectorStudioV2PreviewPasteButton" type="button" disabled title="Paste the copied shape into the selected object" aria-label="Paste">Paste</button>
133133
</div>
134134
<hr class="object-vector-studio-v2__separator">
135135
<div class="object-vector-studio-v2__animation-controls" aria-label="Animation controls">

0 commit comments

Comments
 (0)