;; 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.from-dom (:require [app.common.data :as d] [app.common.types.text :as txt] [app.util.dom :as dom] [app.util.text.content.styles :as styles])) (defn is-text-node [node] (= (.-nodeType node) js/Node.TEXT_NODE)) (defn is-element [node tag] (and (= (.-nodeType node) js/Node.ELEMENT_NODE) (= (.-nodeName node) (.toUpperCase tag)))) (defn is-line-break [node] (is-element node "br")) (defn is-text-span-child [node] (or (is-line-break node) (is-text-node node))) (defn get-text-span-text [element] (when-not (is-text-span-child (.-firstChild element)) (throw (js/TypeError. "Invalid text span child"))) (if (is-line-break (.-firstChild element)) "" (.-textContent element))) (defn get-attrs-from-styles [element attrs defaults] (let [attrs (or attrs []) value-empty? (fn [v] (or (nil? v) (and (string? v) (empty? v)) (and (coll? v) (empty? v))))] (reduce (fn [acc key] (let [style (.-style element) value (if (contains? styles/mapping key) (let [style-name (styles/get-style-name-as-css-variable key) [_ style-decode] (get styles/mapping key)] (style-decode (.getPropertyValue style style-name))) (let [style-name (styles/get-style-name key)] (styles/normalize-attr-value key (.getPropertyValue style style-name))))] (assoc acc key (if (value-empty? value) (get defaults key) value)))) {} attrs))) (defn get-text-span-styles [element] (get-attrs-from-styles element txt/text-node-attrs (txt/get-default-text-attrs))) (defn get-paragraph-styles [element] (let [styles (get-attrs-from-styles element (d/concat-set txt/paragraph-attrs txt/text-node-attrs) (d/merge txt/default-paragraph-attrs txt/default-text-attrs)) ;; Recover real font-size from data attribute, which to_dom/get-paragraph-styles may have ;; changed to "0" ("0" trick to avoid it interfering with height calculation in the browser). saved-font-size (dom/get-data element "saved-font-size")] (cond-> styles (some? saved-font-size) (assoc :font-size saved-font-size)))) (defn get-root-styles [element] (get-attrs-from-styles element txt/root-attrs txt/default-root-attrs)) (defn create-text-span [element] (let [text (get-text-span-text element)] (d/merge {:text text :key (.-id element)} (get-text-span-styles element)))) (defn create-paragraph [element] (d/merge {:type "paragraph" :key (.-id element) :children (mapv create-text-span (.-children element))} (get-paragraph-styles element))) (defn create-root [element] (let [root-styles (get-root-styles element)] (d/merge {:type "root" :key (.-id element) :children [{:type "paragraph-set" :children (mapv create-paragraph (.-children element))}]} root-styles)))