mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-16 20:02:20 +02:00
Photoshop-parity editor client: layers, selection/masking, brushes,
smart filters, LUT import, Quick Edit, mobile gestures, workspaces,
batch operations, and the service-worker versioning (v978->v1006).
Source: vendor/photocraft (ad1cff44) photo-editor client files, merged
onto upstream/dev (a8c147b2). Conflict resolution documented in
pr_work/A_conflicts.md; editor files taken from vendor/photocraft
(upstream's editor is an earlier snapshot of the same feature).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
2.5 KiB
Python
51 lines
2.5 KiB
Python
"""Quick Edit support for Photoshop's Type ▸ Warp ("warp the text").
|
|
|
|
The editor already had a full retained-text warp pipeline (static/js/editor/
|
|
text-layer.js `warpCanvas`, and `warp`/`warpAmount` on the text data), but the
|
|
Quick Edit client fast path never routed a warp request, so "warp the text"
|
|
fell through to "No built-in quick action matched". These tests pin the new
|
|
deterministic branch in galleryEditor.js `_executeQuickEditLocal`.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
EDITOR = (ROOT / "static" / "js" / "galleryEditor.js").read_text(encoding="utf-8")
|
|
TEXT_LAYER = (ROOT / "static" / "js" / "editor" / "text-layer.js").read_text(encoding="utf-8")
|
|
COVERAGE = (ROOT / "docs" / "QUICKEDIT_COVERAGE.md").read_text(encoding="utf-8")
|
|
|
|
|
|
def test_warp_branch_applies_style_and_amount():
|
|
assert "// --- Type ▸ Warp (deterministic) ---" in EDITOR
|
|
assert "const _warpWord = /\\bwarp(?:ed)?\\b/.test(p);" in EDITOR
|
|
assert "const _warpTextWord = /\\b(?:text|title|caption|heading|word|lettering|type)\\b/.test(p);" in EDITOR
|
|
assert "_rerenderTextLayer(_wLayer, { ..._wLayer.text, warp: style, warpAmount: _wAmount });" in EDITOR
|
|
assert "_saveState('Warp text');" in EDITOR
|
|
assert "_setAiCommandStatus(style === 'none' ? 'Removed the text warp.' : `Warped the text (${style}).`, 'done');" in EDITOR
|
|
|
|
|
|
def test_warp_maps_every_photoshop_style():
|
|
for style in ("arc", "arch", "bulge", "inflate", "squeeze", "fisheye", "wave", "rise", "twist", "flag"):
|
|
assert f"style = '{style}'" in EDITOR, style
|
|
assert "style = 'none'" in EDITOR
|
|
assert "const _wAm = p.match(/\\b(?:by|amount|to)\\s*(-?\\d{1,3})\\b/);" in EDITOR
|
|
assert "Math.max(-100, Math.min(100, Math.round(Number(_wAm[1])))) : 50" in EDITOR
|
|
|
|
|
|
def test_warp_runs_before_generic_text_edit():
|
|
warp_idx = EDITOR.index("// --- Type ▸ Warp (deterministic) ---")
|
|
text_idx = EDITOR.index("// --- Text edit (deterministic) ---")
|
|
assert warp_idx < text_idx
|
|
|
|
|
|
def test_warp_infrastructure_exists():
|
|
assert "export function warpCanvas(base, style, amount)" in TEXT_LAYER
|
|
assert "export const WARP_STYLES" in TEXT_LAYER
|
|
assert "warp: WARP_STYLES.includes(value.warp) ? value.warp : 'none'," in TEXT_LAYER
|
|
assert "warpAmount: finite(value.warpAmount, DEFAULT_TEXT_DATA.warpAmount, -100, 100)," in TEXT_LAYER
|
|
assert "function _rerenderTextLayer(layer, nextText, preserveCenter = true)" in EDITOR
|
|
|
|
|
|
def test_coverage_row_marked_ok():
|
|
assert "| Type → Warp | \"warp the text\" | `_rerenderTextLayer` (warp) | ✔ | ✔ | ✔ | OK |" in COVERAGE
|