mirror of
https://github.com/penpot/penpot.git
synced 2026-09-24 04:46:14 +00:00
This makes RTL texts in auto-width to grow towards their left side in the text editor v3. AI-assisted-by: claude-opus-5
132 lines
5.9 KiB
Clojure
132 lines
5.9 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
|
|
|
(ns frontend-tests.data.wasm-text-test
|
|
"Growth anchor of auto-grow wasm text shapes (see `resize-wasm-text-modifiers`).
|
|
Tests stub the wasm bridge and assert on the shape the modifiers produce."
|
|
(:require
|
|
[app.common.geom.shapes :as gsh]
|
|
[app.common.types.modifiers :as ctm]
|
|
[app.common.types.shape :as cts]
|
|
[app.main.data.workspace.wasm-text :as dwwt]
|
|
[cljs.test :as t :include-macros true]))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; Helpers
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(defn- make-content
|
|
"Text content whose paragraphs carry the given `:text-direction` values."
|
|
[& directions]
|
|
{:type "root"
|
|
:children [{:type "paragraph-set"
|
|
:children (vec (for [direction directions]
|
|
{:type "paragraph"
|
|
:text-direction direction
|
|
:children [{:text "hello"}]}))}]})
|
|
|
|
(defn- make-text-shape
|
|
[& {:keys [x y width height grow-type rotation]
|
|
:or {x 100 y 50 width 60 height 20 grow-type :auto-width}}]
|
|
(let [shape (-> (cts/setup-shape {:type :text
|
|
:x x
|
|
:y y
|
|
:width width
|
|
:height height})
|
|
(assoc :grow-type grow-type))]
|
|
(if (some? rotation)
|
|
(gsh/transform-shape
|
|
shape
|
|
(ctm/rotation-modifiers shape (gsh/shape->center shape) rotation))
|
|
shape)))
|
|
|
|
(defn- resized
|
|
"Shape that results from `resize-wasm-text-modifiers` when the renderer
|
|
measures `new-size`."
|
|
[shape content new-size]
|
|
;; The stub needs the real fn's arities: a variadic `fn` has no `arity$2`
|
|
;; dispatch, so the 2-arity call site blows up.
|
|
(with-redefs [dwwt/get-wasm-text-new-size (fn ([_] new-size) ([_ _] new-size))]
|
|
(let [modifiers (dwwt/resize-wasm-text-modifiers shape content)]
|
|
(gsh/transform-shape shape (get-in modifiers [(:id shape) :modifiers])))))
|
|
|
|
(defn- close? [a b]
|
|
(< (abs (- a b)) 0.01))
|
|
|
|
;; ---------------------------------------------------------------------------
|
|
;; Growth anchor
|
|
;; ---------------------------------------------------------------------------
|
|
|
|
(t/deftest rtl-auto-width-keeps-its-right-edge-when-growing
|
|
(t/testing "an rtl auto-width shape extends leftward: the right and top edges
|
|
stay put and x moves left"
|
|
(let [shape (make-text-shape)
|
|
content (make-content "rtl")
|
|
before (:selrect shape)
|
|
after (:selrect (resized shape content {:width 120 :height 20}))]
|
|
(t/is (close? (+ (:x after) (:width after))
|
|
(+ (:x before) (:width before)))
|
|
"right edge preserved")
|
|
(t/is (close? (:y after) (:y before)) "top edge preserved")
|
|
(t/is (close? (:x after) 40) "x moved left by the growth")
|
|
(t/is (close? (:width after) 120)))))
|
|
|
|
(t/deftest rtl-auto-width-keeps-its-right-edge-when-shrinking
|
|
(t/testing "deleting text shrinks the box from the left, right edge preserved"
|
|
(let [shape (make-text-shape)
|
|
content (make-content "rtl")
|
|
before (:selrect shape)
|
|
after (:selrect (resized shape content {:width 30 :height 20}))]
|
|
(t/is (close? (+ (:x after) (:width after))
|
|
(+ (:x before) (:width before)))
|
|
"right edge preserved")
|
|
(t/is (close? (:x after) 130) "x moved right as the box narrowed"))))
|
|
|
|
(t/deftest ltr-auto-width-keeps-its-left-edge
|
|
(t/testing "ltr content is untouched: the left edge stays anchored"
|
|
(let [shape (make-text-shape)
|
|
content (make-content "ltr")
|
|
after (:selrect (resized shape content {:width 120 :height 20}))]
|
|
(t/is (close? (:x after) 100) "left edge preserved")
|
|
(t/is (close? (:width after) 120)))))
|
|
|
|
(t/deftest mixed-direction-auto-width-keeps-its-left-edge
|
|
(t/testing "a box with one rtl and one ltr paragraph keeps the previous
|
|
left-anchored growth"
|
|
(let [shape (make-text-shape)
|
|
content (make-content "rtl" "ltr")
|
|
after (:selrect (resized shape content {:width 120 :height 20}))]
|
|
(t/is (close? (:x after) 100) "left edge preserved"))))
|
|
|
|
(t/deftest rtl-auto-height-keeps-its-left-edge
|
|
(t/testing "auto-height only ever changes height, so the anchor is irrelevant
|
|
and x must not move"
|
|
(let [shape (make-text-shape :grow-type :auto-height)
|
|
content (make-content "rtl")
|
|
after (:selrect (resized shape content {:width 60 :height 80}))]
|
|
(t/is (close? (:x after) 100) "x preserved")
|
|
(t/is (close? (:width after) 60) "width preserved")
|
|
(t/is (close? (:height after) 80) "height grew"))))
|
|
|
|
(t/deftest rotated-rtl-auto-width-grows-along-its-own-axis
|
|
(t/testing "a rotated rtl shape keeps its own top-right corner, not the
|
|
axis-aligned one"
|
|
(let [shape (make-text-shape :rotation 30)
|
|
content (make-content "rtl")
|
|
before (:points shape)
|
|
after (:points (resized shape content {:width 120 :height 20}))]
|
|
;; points are [top-left top-right bottom-right bottom-left]
|
|
(t/is (close? (:x (second after)) (:x (second before)))
|
|
"top-right x preserved")
|
|
(t/is (close? (:y (second after)) (:y (second before)))
|
|
"top-right y preserved"))))
|
|
|
|
(t/deftest no-modifiers-when-the-renderer-has-no-size
|
|
(t/testing "a nil measurement (shape absent from wasm state) skips the resize"
|
|
(let [shape (make-text-shape)]
|
|
(with-redefs [dwwt/get-wasm-text-new-size (fn ([_] nil) ([_ _] nil))]
|
|
(t/is (nil? (dwwt/resize-wasm-text-modifiers shape (make-content "rtl"))))))))
|