mirror of
https://github.com/penpot/penpot.git
synced 2026-05-25 09:53:44 +00:00
125 lines
4.1 KiB
Clojure
125 lines
4.1 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.text.content.to-dom
|
|
(:require
|
|
[app.common.data :as d]
|
|
[app.common.text :as txt]
|
|
[app.util.dom :as dom]
|
|
[app.util.text.content.styles :as styles]))
|
|
|
|
(defn set-dataset
|
|
[element data]
|
|
(doseq [[data-name data-value] data]
|
|
(dom/set-data! element (name data-name) data-value)))
|
|
|
|
(defn set-styles
|
|
[element styles]
|
|
(doseq [[style-name style-value] styles]
|
|
(if (contains? styles/mapping style-name)
|
|
(let [[style-encode] (get styles/mapping style-name)
|
|
style-encoded-value (style-encode style-value)]
|
|
(dom/set-style! element (styles/get-style-name-as-css-variable style-name) style-encoded-value))
|
|
(dom/set-style! element (styles/get-style-name style-name) (styles/normalize-style-value style-name style-value)))))
|
|
|
|
(defn create-element
|
|
([tag]
|
|
(create-element tag nil nil))
|
|
([tag attrs]
|
|
(create-element tag attrs nil))
|
|
([tag attrs children]
|
|
(let [element (dom/create-element tag)]
|
|
;; set attributes to the element if necessary.
|
|
(doseq [[attr-name attr-value] attrs]
|
|
(case attr-name
|
|
:data (set-dataset element attr-value)
|
|
:style (set-styles element attr-value)
|
|
(dom/set-attribute! element (name attr-name) attr-value)))
|
|
|
|
;; add childs to the element if necessary.
|
|
(doseq [child children]
|
|
(dom/append-child! element child))
|
|
|
|
;; we need to return the DOM element
|
|
element)))
|
|
|
|
(defn get-styles-from-attrs
|
|
[node attrs]
|
|
(let [styles (reduce (fn [acc key] (assoc acc key (get node key))) {} attrs)
|
|
fills
|
|
(cond
|
|
;; DEPRECATED: still here for backward compatibility with
|
|
;; old penpot files that still has a single color.
|
|
(or (some? (:fill-color node))
|
|
(some? (:fill-opacity node))
|
|
(some? (:fill-color-gradient node)))
|
|
[(d/without-nils (select-keys node [:fill-color :fill-opacity :fill-color-gradient
|
|
:fill-color-ref-id :fill-color-ref-file]))]
|
|
|
|
(nil? (:fills node))
|
|
[{:fill-color "#000000" :fill-opacity 1}]
|
|
|
|
:else
|
|
(:fills node))]
|
|
(assoc styles :fills fills)))
|
|
|
|
(defn get-paragraph-styles
|
|
[paragraph]
|
|
(let [styles (get-styles-from-attrs paragraph (d/concat-set txt/paragraph-attrs txt/text-node-attrs))
|
|
;; If the text is not empty we must the paragraph font size to 0,
|
|
;; it affects to the height calculation the browser does
|
|
font-size (if (some #(not= "" (:text %)) (:children paragraph))
|
|
"0"
|
|
(:font-size styles (:font-size txt/default-text-attrs)))]
|
|
(cond-> styles
|
|
;; Every paragraph must have line-height to be correctly rendered
|
|
(nil? (:line-height styles)) (assoc :line-height (:line-height txt/default-text-attrs))
|
|
true (assoc :font-size font-size))))
|
|
|
|
(defn get-root-styles
|
|
[root]
|
|
(get-styles-from-attrs root txt/root-attrs))
|
|
|
|
(defn get-inline-styles
|
|
[inline paragraph]
|
|
(let [node (if (= "" (:text inline)) paragraph inline)
|
|
styles (get-styles-from-attrs node txt/text-node-attrs)]
|
|
(dissoc styles :line-height)))
|
|
|
|
(defn get-inline-children
|
|
[inline]
|
|
[(if (= "" (:text inline))
|
|
(dom/create-element "br")
|
|
(dom/create-text (:text inline)))])
|
|
|
|
(defn create-inline
|
|
[inline paragraph]
|
|
(create-element
|
|
"span"
|
|
{:id (:key inline)
|
|
:data {:itype "inline"}
|
|
:style (get-inline-styles inline paragraph)}
|
|
(get-inline-children inline)))
|
|
|
|
(defn create-paragraph
|
|
[paragraph]
|
|
(create-element
|
|
"div"
|
|
{:id (:key paragraph)
|
|
:data {:itype "paragraph"}
|
|
:style (get-paragraph-styles paragraph)}
|
|
(mapv #(create-inline % paragraph) (:children paragraph))))
|
|
|
|
(defn create-root
|
|
[root]
|
|
(let [root-styles (get-root-styles root)]
|
|
(create-element
|
|
"div"
|
|
{:id (:key root)
|
|
:data {:itype "root"}
|
|
:style root-styles}
|
|
(mapv create-paragraph (get-in root [:children 0 :children])))))
|