mirror of
https://github.com/penpot/penpot.git
synced 2026-05-07 17:18:35 +00:00
Step toward issue #9260 (incremental migration of legacy UI components to the modern `*`-suffixed syntax, removing the per-render JS-to-Clojure props conversion overhead). Twin namespaces with parallel structure: each defines six components that drive a recursive text rendering pass over the editor's content tree (root -> paragraph-set -> paragraph -> node -> text). Both files were uniformly legacy: every component carried `::mf/wrap-props false` and read its props with `(obj/get props "key")`. None had `::mf/register`, `unchecked-get` or `obj/merge!`, so they qualify as clean Case-A migrations. frontend/src/app/main/ui/shapes/text/fo_text.cljs (6 components) ---------------------------------------------------------------- - `render-text` -> `render-text*` - `render-root` -> `render-root*` - `render-paragraph-set` -> `render-paragraph-set*` - `render-paragraph` -> `render-paragraph*` - `render-node` -> `render-node*` (forward-props case, see below) - `text-shape` -> `text-shape*` (`::mf/forward-ref` preserved) The four leaf components switch from `[props]` + per-key `(obj/get props "key")` to standard destructuring. `text-shape` already used destructuring under `::mf/props :obj`; that legacy metadata is dropped because the modern `*` form handles props automatically. Its single `::mf/forward-ref true` is kept per the prompt's "preserve forward-ref" rule. `render-node` is the recursive driver. It needs to forward all of its incoming props to the matched paragraph-* / text component and then to a child `render-node*` after overriding `:node`, `:index` and `:key`. The migrated form uses `::mf/props :obj` together with `{:keys [node] :as props}` to keep the JS-object props symbol available, and `(mf/spread-props props {…})` replaces the previous `obj/clone` + `obj/set!` chain. `app.util.object` is no longer required by this namespace and the `(:require ... [app.util.object :as obj] ...)` line is removed. frontend/src/app/main/ui/shapes/text/html_text.cljs (6 components) ----------------------------------------------------------------- Identical six-component shape as `fo_text.cljs`, plus a `code?` flag threaded through every component to switch the rendering path between regular shapes and code-style shapes. - `render-text` -> `render-text*` - `render-root` -> `render-root*` - `render-paragraph-set` -> `render-paragraph-set*` - `render-paragraph` -> `render-paragraph*` - `render-node` -> `render-node*` (same forward-props treatment as above, plus `is-code` in the spread) - `text-shape` -> `text-shape*` (`::mf/forward-ref` preserved) The `code?` boolean prop is renamed to `is-code` per the migration prompt's "?-suffixed boolean -> `is-` prefix" rule. The rename is applied at every read site (5 components) and at the `text-shape*` internal call to `render-node*`, so the prop is consistent inside the namespace. `app.util.object` is no longer required by this namespace either and the corresponding `:require` line is dropped. External call sites (3 files, 4 sites) -------------------------------------- - `frontend/src/app/main/ui/shapes/text.cljs` - the legacy text-shape wrapper (intentionally kept legacy in this PR because it dispatches to `svg/text-shape`, which is still being touched by the in-flight PR #9016) now calls `[:> fo/text-shape* props]`. The `props` symbol is the wrapper's incoming JS-object; modern destructured components accept JS-object props at the call site via `[:>` so this works unchanged. - `frontend/src/app/util/code_gen/markup_html.cljs` - `(mf/element text/text-shape #js {:shape shape :code? true})` becomes `(mf/element text/text-shape* #js {:shape shape :is-code true})` (component renamed and the `code?` JS key updated to match the renamed prop). - `frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs` - `[:& html/text-shape {…}]` -> `[:> html/text-shape* {…}]`. Behavior preserved verbatim --------------------------- Same render output, same forward-ref forwarding semantics, same recursive children-by-index keying, same default `:dir "auto"` on `render-paragraph*`. The visible-prop changes are only the `code?` -> `is-code` rename, all driven from this namespace and its single caller in `markup_html.cljs`. Github #9260 Signed-off-by: FairyPigDev <luislee3108@gmail.com>
95 lines
3.6 KiB
Clojure
95 lines
3.6 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 INC
|
|
|
|
(ns app.util.code-gen.markup-html
|
|
(:require
|
|
["react-dom/server" :as rds]
|
|
[app.common.data :as d]
|
|
[app.common.data.macros :as dm]
|
|
[app.common.files.helpers :as cfh]
|
|
[app.common.types.shape.layout :as ctl]
|
|
[app.config :as cfg]
|
|
[app.main.ui.shapes.text.html-text :as text]
|
|
[app.util.code-gen.common :as cgc]
|
|
[app.util.code-gen.markup-svg :refer [generate-svg]]
|
|
[cuerdas.core :as str]
|
|
[rumext.v2 :as mf]))
|
|
|
|
(defn generate-html
|
|
([objects shape]
|
|
(generate-html objects shape 0))
|
|
|
|
([objects shape level]
|
|
(when (and (some? shape) (some? (:selrect shape)))
|
|
(let [indent (str/repeat " " level)
|
|
|
|
shape-html
|
|
(cond
|
|
(cgc/svg-markup? shape)
|
|
(let [svg-markup (generate-svg objects shape)]
|
|
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
|
indent
|
|
(dm/str "shape " (d/name (:type shape)) " "
|
|
(cgc/shape->selector shape))
|
|
svg-markup
|
|
indent))
|
|
|
|
(cfh/text-shape? shape)
|
|
(let [text-shape-html (rds/renderToStaticMarkup (mf/element text/text-shape* #js {:shape shape :is-code true}))
|
|
text-shape-html (str/replace text-shape-html #"style\s*=\s*[\"'][^\"']*[\"']" "")]
|
|
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
|
indent
|
|
(dm/str "shape " (d/name (:type shape)) " "
|
|
(cgc/shape->selector shape))
|
|
text-shape-html
|
|
indent))
|
|
|
|
(cfh/image-shape? shape)
|
|
(let [data (or (:metadata shape) (:fill-image shape))
|
|
image-url (cfg/resolve-file-media data)]
|
|
(dm/fmt "%<img src=\"%\" class=\"%\">\n%</img>"
|
|
indent
|
|
image-url
|
|
(dm/str "shape " (d/name (:type shape)) " "
|
|
(cgc/shape->selector shape))
|
|
indent))
|
|
|
|
(empty? (:shapes shape))
|
|
(dm/fmt "%<div class=\"%\">\n%</div>"
|
|
indent
|
|
(dm/str "shape " (d/name (:type shape)) " "
|
|
(cgc/shape->selector shape))
|
|
indent)
|
|
|
|
:else
|
|
(let [children (->> shape :shapes (map #(get objects %)))
|
|
reverse? (ctl/any-layout? shape)
|
|
;; The order for layout elements is the reverse of SVG order
|
|
children (cond-> children reverse? reverse)]
|
|
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
|
indent
|
|
(dm/str (d/name (:type shape)) " "
|
|
(cgc/shape->selector shape))
|
|
(->> children
|
|
(map #(generate-html objects % (inc level)))
|
|
(str/join "\n"))
|
|
indent)))
|
|
|
|
shape-html
|
|
(if (cgc/has-wrapper? objects shape)
|
|
(dm/fmt "<div class=\"%\">%</div>"
|
|
(dm/str (cgc/shape->selector shape) "-wrapper")
|
|
shape-html)
|
|
|
|
shape-html)]
|
|
(dm/fmt "%<!-- % -->\n%" indent (dm/str (d/name (:type shape)) ": " (:name shape)) shape-html)))))
|
|
|
|
(defn generate-markup
|
|
[objects shapes]
|
|
(->> shapes
|
|
(keep #(generate-html objects %))
|
|
(str/join "\n")))
|