mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 10:38:13 -05:00
Merge pull request #3673 from penpot/alotor-codegen-fixes
🐛 Fix some cases for the html preview
This commit is contained in:
commit
22d7ab9590
8 changed files with 191 additions and 71 deletions
|
@ -48,11 +48,11 @@
|
|||
(beautify/html #js {"indent_size" 2})))
|
||||
|
||||
(defn update-preview-window
|
||||
[preview code]
|
||||
[preview code width height]
|
||||
(when preview
|
||||
(if (aget preview "load")
|
||||
(.load preview code)
|
||||
(ts/schedule #(update-preview-window preview code)))))
|
||||
(.load preview code width height)
|
||||
(ts/schedule #(update-preview-window preview code width height)))))
|
||||
|
||||
(defn shapes->fonts
|
||||
[shapes]
|
||||
|
@ -92,7 +92,11 @@
|
|||
(-> (cg/generate-markup-code objects markup-type [shape])
|
||||
(format-code markup-type))]
|
||||
|
||||
(update-preview-window preview (str/format page-template style-code markup-code))))))))))
|
||||
(update-preview-window
|
||||
preview
|
||||
(str/format page-template style-code markup-code)
|
||||
(-> shape :selrect :width)
|
||||
(-> shape :selrect :height))))))))))
|
||||
|
||||
(defn open-preview-selected
|
||||
[]
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.exports :as de]
|
||||
[app.main.data.preview :as dp]
|
||||
[app.main.data.shortcuts :as ds]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.colors :as mdc]
|
||||
|
@ -539,8 +540,12 @@
|
|||
:bool-exclude {:tooltip (ds/meta (ds/alt "E"))
|
||||
:command (ds/c-mod "alt+e")
|
||||
:subsections [:shape]
|
||||
:fn #(emit-when-no-readonly (dw/create-bool :exclude))}}
|
||||
)
|
||||
:fn #(emit-when-no-readonly (dw/create-bool :exclude))}
|
||||
|
||||
;; PREVIEW
|
||||
:preview-frame {:tooltip (ds/meta (ds/alt ds/enter))
|
||||
:command (ds/c-mod "alt+enter")
|
||||
:fn #(emit-when-no-readonly (dp/open-preview-selected))}})
|
||||
|
||||
(def opacity-shortcuts
|
||||
(into {} (->>
|
||||
|
|
|
@ -24,11 +24,13 @@
|
|||
|
||||
handle-load
|
||||
(mf/use-callback
|
||||
(fn [data]
|
||||
(fn [data width height]
|
||||
(prn "handle-load" data)
|
||||
(reset! last-data* data)
|
||||
(let [iframe-dom (mf/ref-val iframe-ref)]
|
||||
(when iframe-dom
|
||||
(-> iframe-dom (aset "width" width))
|
||||
(-> iframe-dom (aset "height" height))
|
||||
(-> iframe-dom .-contentWindow .-document .open)
|
||||
(-> iframe-dom .-contentWindow .-document (.write data))
|
||||
(-> iframe-dom .-contentWindow .-document .close)))))
|
||||
|
@ -65,11 +67,5 @@
|
|||
[:iframe {:ref load-ref
|
||||
:frameborder "0"
|
||||
:scrolling "no"
|
||||
:style {:width (str (* 100 (if (> zoom 1)
|
||||
(* 1 zoom)
|
||||
(/ 1 zoom))) "%")
|
||||
:height (str (* 100 (if (> zoom 1)
|
||||
(* 1 zoom)
|
||||
(/ 1 zoom))) "%")
|
||||
:transform-origin "left top"
|
||||
:style {:transform-origin "top center"
|
||||
:transform (str "scale(" zoom ")")}}]]]))
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
|
||||
(ns app.util.code-gen.common
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn shape->selector
|
||||
|
@ -23,3 +27,36 @@
|
|||
selector (if (str/starts-with? selector "-") (subs selector 1) selector)]
|
||||
selector)
|
||||
""))
|
||||
|
||||
(defn svg-markup?
|
||||
"Function to determine whether a shape is rendered in HTML+CSS or is rendered
|
||||
through a SVG"
|
||||
[shape]
|
||||
(or
|
||||
;; path and path-like shapes
|
||||
(cph/path-shape? shape)
|
||||
(cph/bool-shape? shape)
|
||||
|
||||
;; imported SVG images
|
||||
(cph/svg-raw-shape? shape)
|
||||
(some? (:svg-attrs shape))
|
||||
|
||||
;; CSS masks are not enough we need to delegate to SVG
|
||||
(cph/mask-shape? shape)
|
||||
|
||||
;; Texts with shadows or strokes we render in SVG
|
||||
(and (cph/text-shape? shape)
|
||||
(or (d/not-empty? (:shadow shape))
|
||||
(d/not-empty? (:strokes shape))))
|
||||
|
||||
;; When a shape has several strokes or the stroke is not a "border"
|
||||
(or (> (count (:strokes shape)) 1)
|
||||
(and (= (count (:strokes shape)) 1)
|
||||
(not= (-> shape :strokes first :stroke-alignment) :inner)))))
|
||||
|
||||
(defn has-wrapper?
|
||||
[objects shape]
|
||||
;; Layout children with a transform should be wrapped
|
||||
(and (ctl/any-layout-immediate-child? objects shape)
|
||||
(not (gmt/unit? (:transform shape)))))
|
||||
|
||||
|
|
|
@ -18,32 +18,6 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn svg-markup?
|
||||
"Function to determine whether a shape is rendered in HTML+CSS or is rendered
|
||||
through a SVG"
|
||||
[shape]
|
||||
(or
|
||||
;; path and path-like shapes
|
||||
(cph/path-shape? shape)
|
||||
(cph/bool-shape? shape)
|
||||
|
||||
;; imported SVG images
|
||||
(cph/svg-raw-shape? shape)
|
||||
(some? (:svg-attrs shape))
|
||||
|
||||
;; CSS masks are not enough we need to delegate to SVG
|
||||
(cph/mask-shape? shape)
|
||||
|
||||
;; Texts with shadows or strokes we render in SVG
|
||||
(and (cph/text-shape? shape)
|
||||
(or (d/not-empty? (:shadow shape))
|
||||
(d/not-empty? (:strokes shape))))
|
||||
|
||||
;; When a shape has several strokes or the stroke is not a "border"
|
||||
(or (> (count (:strokes shape)) 1)
|
||||
(and (= (count (:strokes shape)) 1)
|
||||
(not= (-> shape :strokes first :stroke-alignment) :inner)))))
|
||||
|
||||
(defn generate-html
|
||||
([objects shape]
|
||||
(generate-html objects shape 0))
|
||||
|
@ -54,7 +28,7 @@
|
|||
|
||||
shape-html
|
||||
(cond
|
||||
(svg-markup? shape)
|
||||
(cgc/svg-markup? shape)
|
||||
(let [svg-markup (generate-svg objects shape)]
|
||||
(dm/fmt "%<div class=\"%\">\n%\n%</div>"
|
||||
indent
|
||||
|
@ -98,7 +72,15 @@
|
|||
(maybe-reverse)
|
||||
(map #(generate-html objects (get objects %) (inc level)))
|
||||
(str/join "\n"))
|
||||
indent))]
|
||||
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
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.ui.shapes.text.styles :as sts]
|
||||
[app.util.code-gen.common :as cgc]
|
||||
[app.util.code-gen.style-css-formats :refer [format-value]]
|
||||
|
@ -50,6 +53,19 @@ svg {
|
|||
|
||||
")
|
||||
|
||||
(def shape-wrapper-css-properties
|
||||
#{:flex-shrink
|
||||
:margin
|
||||
:max-height
|
||||
:min-height
|
||||
:max-width
|
||||
:min-width
|
||||
:align-self
|
||||
:justify-self
|
||||
:grid-column
|
||||
:grid-row
|
||||
:z-index})
|
||||
|
||||
(def shape-css-properties
|
||||
[:position
|
||||
:left
|
||||
|
@ -82,6 +98,7 @@ svg {
|
|||
;; Flex related properties
|
||||
:flex-direction
|
||||
:flex-wrap
|
||||
:flex
|
||||
|
||||
;; Grid related properties
|
||||
:grid-template-rows
|
||||
|
@ -118,6 +135,24 @@ svg {
|
|||
(when-let [value (get-value property shape objects)]
|
||||
[property value]))
|
||||
|
||||
(defn shape->wrapper-css-properties
|
||||
[shape objects]
|
||||
(when (and (ctl/any-layout-immediate-child? objects shape)
|
||||
(not (gmt/unit? (:transform shape))))
|
||||
(let [{:keys [width height]} (gsh/shapes->rect [shape])]
|
||||
(cond-> [[:position "relative"]
|
||||
[:width width]
|
||||
[:height height]]
|
||||
(ctl/flex-layout-immediate-child? objects shape)
|
||||
(conj [:flex-shrink 0])))))
|
||||
|
||||
(defn shape->wrapper-child-css-properties
|
||||
[shape objects]
|
||||
(when (and (ctl/any-layout-immediate-child? objects shape) (not (gmt/unit? (:transform shape))))
|
||||
[[:position "absolute"]
|
||||
[:left "50%"]
|
||||
[:top "50%"]]))
|
||||
|
||||
(defn shape->css-properties
|
||||
"Given a shape extract the CSS properties in the format of list [property value]"
|
||||
[shape objects properties]
|
||||
|
@ -143,9 +178,10 @@ svg {
|
|||
(defn format-css-properties
|
||||
"Format a list of [property value] into a list of css properties in the format 'property: value;'"
|
||||
[properties options]
|
||||
(->> properties
|
||||
(map #(dm/str " " (format-css-property % options)))
|
||||
(str/join "\n")))
|
||||
(when properties
|
||||
(->> properties
|
||||
(map #(dm/str " " (format-css-property % options)))
|
||||
(str/join "\n"))))
|
||||
|
||||
(defn get-shape-properties-css
|
||||
([objects shape properties]
|
||||
|
@ -199,13 +235,40 @@ svg {
|
|||
(get-shape-css-selector shape objects nil))
|
||||
|
||||
([shape objects options]
|
||||
(let [properties (-> shape
|
||||
(shape->css-properties objects shape-css-properties)
|
||||
(format-css-properties options))
|
||||
selector (cgc/shape->selector shape)]
|
||||
(str/join "\n" [(str/fmt "/* %s */" (:name shape))
|
||||
(let [selector (cgc/shape->selector shape)
|
||||
|
||||
wrapper? (cgc/has-wrapper? objects shape)
|
||||
|
||||
css-properties
|
||||
(if wrapper?
|
||||
(filter (complement shape-wrapper-css-properties) shape-css-properties)
|
||||
shape-css-properties)
|
||||
|
||||
properties
|
||||
(-> shape
|
||||
(shape->css-properties objects css-properties)
|
||||
(format-css-properties options))
|
||||
|
||||
wrapper-properties
|
||||
(when wrapper?
|
||||
(-> (d/concat-vec
|
||||
(shape->css-properties shape objects shape-wrapper-css-properties)
|
||||
(shape->wrapper-css-properties shape objects))
|
||||
(format-css-properties options)))
|
||||
|
||||
wrapper-child-properties
|
||||
(when wrapper?
|
||||
(-> shape
|
||||
(shape->wrapper-child-css-properties objects)
|
||||
(format-css-properties options)))]
|
||||
|
||||
(str/join
|
||||
"\n"
|
||||
(filter some? [(str/fmt "/* %s */" (:name shape))
|
||||
(when wrapper? (str/fmt ".%s-wrapper {\n%s\n}" selector wrapper-properties))
|
||||
(when wrapper? (str/fmt ".%s-wrapper > * {\n%s\n}" selector wrapper-child-properties))
|
||||
(str/fmt ".%s {\n%s\n}" selector properties)
|
||||
(when (cph/text-shape? shape) (generate-text-css shape))]))))
|
||||
(when (cph/text-shape? shape) (generate-text-css shape))])))))
|
||||
|
||||
(defn get-css-property
|
||||
([objects shape property]
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
:margin :size-array
|
||||
:grid-template-rows :tracks
|
||||
:grid-template-columns :tracks
|
||||
:transform :matrix
|
||||
})
|
||||
|
||||
(defmulti format-value
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
|
||||
(ns app.util.code-gen.style-css-values
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.util.code-gen.markup-html :refer [svg-markup?]]))
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.util.code-gen.common :as cgc]))
|
||||
|
||||
(defn fill->color
|
||||
[{:keys [fill-color fill-opacity fill-color-gradient]}]
|
||||
|
@ -30,7 +32,7 @@
|
|||
(not (ctl/layout-absolute? shape))
|
||||
(or (cph/group-like-shape? shape)
|
||||
(cph/frame-shape? shape)
|
||||
(svg-markup? shape)))
|
||||
(cgc/svg-markup? shape)))
|
||||
(cph/root-frame? shape))
|
||||
:relative
|
||||
|
||||
|
@ -66,14 +68,37 @@
|
|||
[_ shape objects]
|
||||
(get-shape-position shape objects :y))
|
||||
|
||||
(defmethod get-value :flex
|
||||
[_ shape objects]
|
||||
(let [parent (cph/get-parent objects (:id shape))]
|
||||
(when (and (ctl/flex-layout-immediate-child? objects shape)
|
||||
(or (and (contains? #{:row :reverse-row} (:layout-flex-dir parent))
|
||||
(= :fill (:layout-item-h-sizing shape)))
|
||||
(and (contains? #{:column :column-row} (:layout-flex-dir parent))
|
||||
(= :fill (:layout-item-v-sizing shape)))))
|
||||
1)))
|
||||
|
||||
(defn get-shape-size
|
||||
[shape objects type]
|
||||
(let [sizing (if (= type :width)
|
||||
(let [parent (cph/get-parent objects (:id shape))
|
||||
sizing (if (= type :width)
|
||||
(:layout-item-h-sizing shape)
|
||||
(:layout-item-v-sizing shape))]
|
||||
(cond
|
||||
(or (and (ctl/any-layout? shape) (= sizing :auto) (not (svg-markup? shape)))
|
||||
(and (ctl/any-layout-immediate-child? objects shape) (= sizing :fill)))
|
||||
(and (ctl/flex-layout-immediate-child? objects shape)
|
||||
(or (and (= type :height)
|
||||
(contains? #{:row :reverse-row} (:layout-flex-dir parent))
|
||||
(= :fill (:layout-item-v-sizing shape)))
|
||||
(and (= type :width)
|
||||
(contains? #{:column :column-row} (:layout-flex-dir parent))
|
||||
(= :fill (:layout-item-h-sizing shape)))))
|
||||
:fill
|
||||
|
||||
(and (ctl/flex-layout-immediate-child? objects shape) (= sizing :fill))
|
||||
nil
|
||||
|
||||
(or (and (ctl/any-layout? shape) (= sizing :auto) (not (cgc/svg-markup? shape)))
|
||||
(and (ctl/grid-layout-immediate-child? objects shape) (= sizing :fill)))
|
||||
sizing
|
||||
|
||||
(some? (:selrect shape))
|
||||
|
@ -92,21 +117,25 @@
|
|||
|
||||
(defmethod get-value :transform
|
||||
[_ shape objects]
|
||||
(when-not (svg-markup? shape)
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
|
||||
transform
|
||||
(gmt/multiply (:transform shape (gmt/matrix))
|
||||
(:transform-inverse parent (gmt/matrix)))]
|
||||
(when-not (gmt/unit? transform)
|
||||
transform))))
|
||||
(:transform-inverse parent (gmt/matrix)))
|
||||
|
||||
transform-str (when-not (gmt/unit? transform) (fmt/format-matrix transform))]
|
||||
|
||||
(if (cgc/has-wrapper? objects shape)
|
||||
(dm/str "translate(-50%, -50%) " (d/nilv transform-str ""))
|
||||
transform-str))))
|
||||
|
||||
(defmethod get-value :background
|
||||
[_ {:keys [fills] :as shape} _]
|
||||
(let [single-fill? (= (count fills) 1)
|
||||
ffill (first fills)
|
||||
gradient? (some? (:fill-color-gradient ffill))]
|
||||
(when (and (not (svg-markup? shape)) (not (cph/group-shape? shape)) single-fill? gradient?)
|
||||
(when (and (not (cgc/svg-markup? shape)) (not (cph/group-shape? shape)) single-fill? gradient?)
|
||||
(fill->color ffill))))
|
||||
|
||||
(defmethod get-value :background-color
|
||||
|
@ -114,12 +143,12 @@
|
|||
(let [single-fill? (= (count fills) 1)
|
||||
ffill (first fills)
|
||||
gradient? (some? (:fill-color-gradient ffill))]
|
||||
(when (and (not (svg-markup? shape)) (not (cph/group-shape? shape)) single-fill? (not gradient?))
|
||||
(when (and (not (cgc/svg-markup? shape)) (not (cph/group-shape? shape)) single-fill? (not gradient?))
|
||||
(fill->color ffill))))
|
||||
|
||||
(defmethod get-value :background-image
|
||||
[_ {:keys [fills] :as shape} _]
|
||||
(when (and (not (svg-markup? shape)) (not (cph/group-shape? shape)) (> (count fills) 1))
|
||||
(when (and (not (cgc/svg-markup? shape)) (not (cph/group-shape? shape)) (> (count fills) 1))
|
||||
(->> fills
|
||||
(map fill->color))))
|
||||
|
||||
|
@ -138,7 +167,7 @@
|
|||
|
||||
(defmethod get-value :border
|
||||
[_ shape _]
|
||||
(when-not (svg-markup? shape)
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(get-stroke-data (first (:strokes shape)))))
|
||||
|
||||
(defmethod get-value :border-radius
|
||||
|
@ -155,12 +184,12 @@
|
|||
|
||||
(defmethod get-value :box-shadow
|
||||
[_ shape _]
|
||||
(when-not (svg-markup? shape)
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(:shadow shape)))
|
||||
|
||||
(defmethod get-value :filter
|
||||
[_ shape _]
|
||||
(when-not (svg-markup? shape)
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(get-in shape [:blur :value])))
|
||||
|
||||
(defmethod get-value :display
|
||||
|
@ -258,8 +287,15 @@
|
|||
(defmethod get-value :flex-shrink
|
||||
[_ shape objects]
|
||||
(when (and (ctl/flex-layout-immediate-child? objects shape)
|
||||
(not= :fill (:layout-item-h-sizing shape))
|
||||
(not= :fill (:layout-item-v-sizing shape))
|
||||
|
||||
(not (and (contains? #{:row :reverse-row} (:layout-flex-dir shape))
|
||||
(= :fill (:layout-item-h-sizing shape))))
|
||||
|
||||
(not (and (contains? #{:column :column-row} (:layout-flex-dir shape))
|
||||
(= :fill (:layout-item-v-sizing shape))))
|
||||
|
||||
;;(not= :fill (:layout-item-h-sizing shape))
|
||||
;;(not= :fill (:layout-item-v-sizing shape))
|
||||
(not= :auto (:layout-item-h-sizing shape))
|
||||
(not= :auto (:layout-item-v-sizing shape)))
|
||||
0))
|
||||
|
@ -336,5 +372,3 @@
|
|||
(defmethod get-value :default
|
||||
[property shape _]
|
||||
(get shape property))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue