;; 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.main.data.preview (:require ["js-beautify" :as beautify] [app.common.data :as d] [app.common.data.macros :as dm] [app.common.pages.helpers :as cph] [app.common.types.shape-tree :as ctst] [app.main.data.workspace.state-helpers :as wsh] [app.main.fonts :as fonts] [app.main.refs :as refs] [app.util.code-gen :as cg] [app.util.timers :as ts] [beicon.core :as rx] [clojure.set :as set] [cuerdas.core :as str] [potok.core :as ptk])) (def style-type "css") (def markup-type "html") (def page-template " %s ") (defn format-code [code type] (cond-> code (= type "svg") (-> (str/replace "" "") (str/replace "><" ">\n<")) (or (= type "svg") (= type "html")) (beautify/html #js {"indent_size" 2}))) (defn update-preview-window [preview code width height] (when preview (if (aget preview "load") (.load preview code width height) (ts/schedule #(update-preview-window preview code width height))))) (defn shapes->fonts [shapes] (->> shapes (filter cph/text-shape?) (map (comp fonts/get-content-fonts :content)) (reduce set/union #{}))) (defn update-preview [preview shape-id] (ptk/reify ::update-preview ptk/EffectEvent (effect [_ state _] (let [objects (wsh/lookup-page-objects state) shape (get objects shape-id) all-children (->> (cph/selected-with-children objects [shape-id]) (ctst/sort-z-index objects) (keep (d/getf objects))) fonts (shapes->fonts all-children)] (->> (rx/from fonts) (rx/merge-map fonts/fetch-font-css) (rx/reduce conj []) (rx/map #(str/join "\n" %)) (rx/subs (fn [fontfaces-css] (let [style-code (dm/str fontfaces-css "\n" (-> (cg/generate-style-code objects style-type all-children) (format-code style-type))) markup-code (-> (cg/generate-markup-code objects markup-type [shape]) (format-code markup-type))] (update-preview-window preview (str/format page-template style-code markup-code) (-> shape :selrect :width) (-> shape :selrect :height)))))))))) (defn open-preview-selected [] (ptk/reify ::open-preview-selected ptk/WatchEvent (watch [_ state _] (let [shape-id (first (wsh/lookup-selected state)) closed-preview (rx/subject) preview (.open js/window "/#/frame-preview") listener-fn #(rx/push! closed-preview true)] (.addEventListener preview "beforeunload" listener-fn) (->> (rx/from-atom (refs/all-children-objects shape-id) {:emit-current-value? true}) (rx/take-until closed-preview) (rx/debounce 1000) (rx/map #(update-preview preview shape-id)))))))