0
Fork 0
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:
Aitor Moreno 2023-09-27 13:54:11 +02:00 committed by GitHub
commit 22d7ab9590
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 191 additions and 71 deletions

View file

@ -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
[]

View file

@ -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 {} (->>

View file

@ -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 ")")}}]]]))

View file

@ -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)))))

View file

@ -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

View file

@ -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]

View file

@ -33,7 +33,6 @@
:margin :size-array
:grid-template-rows :tracks
:grid-template-columns :tracks
:transform :matrix
})
(defmulti format-value

View file

@ -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))