mirror of
https://github.com/penpot/penpot.git
synced 2026-09-10 20:59:12 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8b457a1d3 |
No files matched your search
@@ -192,30 +192,50 @@
|
||||
#{:font-family :font-size :font-style :font-weight
|
||||
:direction :text-direction :text-decoration :text-transform :key})
|
||||
|
||||
(defn- remove-nil-style-attrs
|
||||
"Strip nil-valued non-nilable style attrs from every node in a content tree.
|
||||
Repairs content already corrupted with e.g. nil :font-family/:font-weight/
|
||||
:font-style (from an unloaded font) so it can pass the backend schema again."
|
||||
(defn- repair-nodes
|
||||
"Walk a content tree once, repairing every node so it can pass the backend
|
||||
`validate-shape` schema: nil-valued non-nilable style attrs are stripped
|
||||
(e.g. nil :font-family/:font-weight/:font-style from an unloaded font) and a
|
||||
level with no children is seeded with the default paragraph/span."
|
||||
[content]
|
||||
(txt/transform-nodes
|
||||
(fn [node]
|
||||
(reduce (fn [node k]
|
||||
(if (and (contains? node k) (nil? (get node k)))
|
||||
(dissoc node k)
|
||||
node))
|
||||
node
|
||||
non-nilable-style-attrs))
|
||||
content))
|
||||
(let [;; Seeding only makes sense inside a root tree: a bare node handed over
|
||||
;; as content is not ours to complete.
|
||||
seed? (= "root" (:type content))
|
||||
default-para (delay (-> (tc/v2-default-text-content) :children first :children first))]
|
||||
(txt/transform-nodes
|
||||
(fn [node]
|
||||
(let [node (reduce (fn [node k]
|
||||
(if (and (contains? node k) (nil? (get node k)))
|
||||
(dissoc node k)
|
||||
node))
|
||||
node
|
||||
non-nilable-style-attrs)]
|
||||
(if seed?
|
||||
(case (:type node)
|
||||
"paragraph-set"
|
||||
(cond-> node
|
||||
(empty? (:children node))
|
||||
(assoc :children [@default-para]))
|
||||
|
||||
"paragraph"
|
||||
(cond-> node
|
||||
(empty? (:children node))
|
||||
(assoc :children (:children @default-para)))
|
||||
|
||||
node)
|
||||
node)))
|
||||
content)))
|
||||
|
||||
(defn ensure-valid-text-content
|
||||
"Repair structurally incomplete text :content to a canonical
|
||||
root -> paragraph-set -> paragraph -> span tree. Returns the
|
||||
content unchanged when it is already well-formed.
|
||||
|
||||
A `nil` content, a root with no :children, or a root with an empty
|
||||
:children vector all fail the backend `validate-shape` schema
|
||||
(children must contain at least one paragraph-set). This helper
|
||||
is the defensive normalizer used by content-commit paths.
|
||||
A `nil` content, a root with no :children, a paragraph-set with no
|
||||
paragraphs, or a paragraph with no spans all fail the backend
|
||||
`validate-shape` schema (every level requires at least one child).
|
||||
This helper is the defensive normalizer used by content-commit paths;
|
||||
it mirrors the `0025-repair-empty-text-content` migration.
|
||||
|
||||
It also scrubs nil-valued non-nilable style attrs (e.g. nil
|
||||
:font-family/:font-weight/:font-style left over from an unloaded font),
|
||||
@@ -227,7 +247,7 @@
|
||||
(empty? (:children content))))
|
||||
(let [base (tc/v2-default-text-content)]
|
||||
(d/txt-merge base (select-keys content txt/root-attrs)))
|
||||
(remove-nil-style-attrs content)))
|
||||
(repair-nodes content)))
|
||||
|
||||
(defn- v2-content-has-text?
|
||||
[content]
|
||||
|
||||
@@ -1278,22 +1278,18 @@
|
||||
|
||||
(if (< index total)
|
||||
(let [paragraph (nth paragraphs index)
|
||||
spans (get paragraph :children)]
|
||||
(if (empty? (seq spans))
|
||||
(recur (inc index)
|
||||
emoji?
|
||||
langs)
|
||||
spans (or (seq (get paragraph :children))
|
||||
[(assoc (select-keys paragraph txt/text-node-attrs) :text "")])
|
||||
text (apply str (map :text spans))
|
||||
emoji? (if emoji? emoji? (t/contains-emoji? text))
|
||||
langs (t/collect-used-languages langs text)]
|
||||
|
||||
(let [text (apply str (map :text spans))
|
||||
emoji? (if emoji? emoji? (t/contains-emoji? text))
|
||||
langs (t/collect-used-languages langs text)]
|
||||
;; FIXME: this should probably be somewhere else
|
||||
(when fallback-fonts-only? (t/write-shape-text spans paragraph text))
|
||||
|
||||
;; FIXME: this should probably be somewhere else
|
||||
(when fallback-fonts-only? (t/write-shape-text spans paragraph text))
|
||||
|
||||
(recur (inc index)
|
||||
emoji?
|
||||
langs))))
|
||||
(recur (inc index)
|
||||
emoji?
|
||||
langs))
|
||||
|
||||
(let [updated-fonts
|
||||
(-> #{}
|
||||
|
||||
@@ -550,32 +550,37 @@
|
||||
exported-texts vector of vectors [[\"span1\" \"span2\"] [\"p2s1\"]]
|
||||
content existing Penpot content map (root -> paragraph-set -> …)"
|
||||
[content exported-texts]
|
||||
(let [para-set (first (get content :children))
|
||||
orig-paras (get para-set :children)
|
||||
num-orig (count orig-paras)
|
||||
last-orig-para (when (seq orig-paras) (last orig-paras))
|
||||
template-span (when last-orig-para
|
||||
(-> last-orig-para :children last))
|
||||
new-paras
|
||||
(mapv (fn [para-idx exported-span-texts]
|
||||
(let [orig-para (if (< para-idx num-orig)
|
||||
(nth orig-paras para-idx)
|
||||
(dissoc last-orig-para :children))
|
||||
orig-spans (get orig-para :children)
|
||||
num-orig-spans (count orig-spans)
|
||||
last-orig-span (when (seq orig-spans) (last orig-spans))]
|
||||
(assoc orig-para :children
|
||||
(mapv (fn [span-idx new-text]
|
||||
(let [orig-span (if (< span-idx num-orig-spans)
|
||||
(nth orig-spans span-idx)
|
||||
(or last-orig-span template-span))]
|
||||
(assoc orig-span :text new-text)))
|
||||
(range (count exported-span-texts))
|
||||
exported-span-texts))))
|
||||
(range (count exported-texts))
|
||||
exported-texts)
|
||||
new-para-set (assoc para-set :children new-paras)]
|
||||
(assoc content :children [new-para-set])))
|
||||
(if (empty? exported-texts)
|
||||
content
|
||||
(let [para-set (first (get content :children))
|
||||
orig-paras (get para-set :children)
|
||||
num-orig (count orig-paras)
|
||||
last-orig-para (when (seq orig-paras) (last orig-paras))
|
||||
template-span (when last-orig-para
|
||||
(-> last-orig-para :children last))
|
||||
exported-texts (mapv (fn [span-texts]
|
||||
(if (empty? span-texts) [""] span-texts))
|
||||
exported-texts)
|
||||
new-paras
|
||||
(mapv (fn [para-idx exported-span-texts]
|
||||
(let [orig-para (if (< para-idx num-orig)
|
||||
(nth orig-paras para-idx)
|
||||
(dissoc last-orig-para :children))
|
||||
orig-spans (get orig-para :children)
|
||||
num-orig-spans (count orig-spans)
|
||||
last-orig-span (when (seq orig-spans) (last orig-spans))]
|
||||
(assoc orig-para :children
|
||||
(mapv (fn [span-idx new-text]
|
||||
(let [orig-span (if (< span-idx num-orig-spans)
|
||||
(nth orig-spans span-idx)
|
||||
(or last-orig-span template-span))]
|
||||
(assoc orig-span :text new-text)))
|
||||
(range (count exported-span-texts))
|
||||
exported-span-texts))))
|
||||
(range (count exported-texts))
|
||||
exported-texts)
|
||||
new-para-set (assoc para-set :children new-paras)]
|
||||
(assoc content :children [new-para-set]))))
|
||||
|
||||
(defn- default-empty-text-content
|
||||
"Build a default, empty text content tree used as a merge template.
|
||||
@@ -687,7 +692,7 @@
|
||||
paragraphs (:children paragraph-set)
|
||||
|
||||
new-paragraphs
|
||||
(when (not collapsed?)
|
||||
(when (and (not collapsed?) (seq paragraphs))
|
||||
(mapv (fn [idx para]
|
||||
(cond
|
||||
;; paragraph outside the range of paragraphs.
|
||||
|
||||
Reference in new issue
Block a user