diff --git a/CHANGES.md b/CHANGES.md index d58a99268..219efc70e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -28,6 +28,17 @@ - To @andrewzhurov for many code contributions on this release. +## 1.15.1-beta + +### :bug: Bugs fixed + +- Fix shadows doesn't work on nested artboards [Taiga #3886](https://tree.taiga.io/project/penpot/issue/3886) +- Fix problems with double-click and selection [Taiga #4005](https://tree.taiga.io/project/penpot/issue/4005) +- Fix mismatch between editor and displayed text in workspace [Taiga #3975](https://tree.taiga.io/project/penpot/issue/3975) +- Fix validation error on text position [Taiga #4010](https://tree.taiga.io/project/penpot/issue/4010) +- Fix objects jitter while scrolling [Github #2167](https://github.com/penpot/penpot/issues/2167) +>>>>>>> origin/staging + ## 1.15.0-beta ### :boom: Breaking changes & Deprecations diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 8f4102c01..e3174d6d7 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -151,23 +151,18 @@ "Check if `parent-candidate` is parent of `shape-id`" [objects shape-id parent-candidate] - (loop [current (get objects parent-candidate) - done #{} - pending (:shapes current)] - + (loop [current-id shape-id] (cond - (contains? done (:id current)) - (recur (get objects (first pending)) - done - (rest pending)) + (= current-id parent-candidate) + true - (empty? pending) false - (and current (contains? (set (:shapes current)) shape-id)) true + (or (nil? current-id) + (= current-id uuid/zero) + (= current-id (get-in objects [current-id :parent-id]))) + false :else - (recur (get objects (first pending)) - (conj done (:id current)) - (concat (rest pending) (:shapes current)))))) + (recur (get-in objects [current-id :parent-id]))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; COMPONENTS HELPERS diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs index 4191926df..1e072a0f2 100644 --- a/frontend/src/app/main/ui/viewer.cljs +++ b/frontend/src/app/main/ui/viewer.cljs @@ -32,7 +32,9 @@ [app.main.ui.viewer.share-link] [app.main.ui.viewer.thumbnails :refer [thumbnails-panel]] [app.util.dom :as dom] + [app.util.dom.normalize-wheel :as nw] [app.util.i18n :as i18n :refer [tr]] + [app.util.keyboard :as kbd] [app.util.webapi :as wapi] [cuerdas.core :as str] [goog.events :as events] @@ -307,7 +309,28 @@ on-scroll (mf/use-fn (fn [event] - (reset! scroll (dom/get-target-scroll event))))] + (reset! scroll (dom/get-target-scroll event)))) + + on-wheel + (mf/use-fn + (fn [event] + (let [event (.getBrowserEvent ^js event) + norm-event ^js (nw/normalize-wheel event) + mod? (kbd/mod? event) + shift? (kbd/shift? event) + delta (.-pixelY norm-event) + viewer-section (mf/ref-val viewer-section-ref) + scroll-pos (if shift? + (dom/get-h-scroll-pos viewer-section) + (dom/get-scroll-pos viewer-section)) + new-scroll-pos (+ scroll-pos delta)] + (when-not mod? + (do + (dom/prevent-default event) + (dom/stop-propagation event) + (if shift? + (dom/set-h-scroll-pos! viewer-section new-scroll-pos) + (dom/set-scroll-pos! viewer-section new-scroll-pos)))))))] (hooks/use-shortcuts ::viewer sc/shortcuts) (when (nil? page) @@ -327,10 +350,12 @@ (mf/with-effect [] (dom/set-html-theme-color clr/gray-50 "dark") (let [key1 (events/listen js/window "click" on-click) - key2 (events/listen (mf/ref-val viewer-section-ref) "scroll" on-scroll)] + key2 (events/listen (mf/ref-val viewer-section-ref) "scroll" on-scroll #js {"passive" true}) + key3 (events/listen (mf/ref-val viewer-section-ref) "wheel" on-wheel #js {"passive" false})] (fn [] (events/unlistenByKey key1) - (events/unlistenByKey key2)))) + (events/unlistenByKey key2) + (events/unlistenByKey key3)))) (mf/use-layout-effect (fn [] @@ -441,16 +466,14 @@ :fullscreen fullscreen?)} [:div.viewer-content - [:& header/header - {:project project - :index index - :file file - :page page - :frame frame - :permissions permissions - :zoom zoom - :section section}] - + [:& header/header {:project project + :index index + :file file + :page page + :frame frame + :permissions permissions + :zoom zoom + :section section}] [:div.thumbnail-close {:on-click #(st/emit! dv/close-thumbnails-panel) :class (dom/classnames :invisible (not (:show-thumbnails local false)))}] [:& thumbnails-panel {:frames frames diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index 420eaaa44..2cacfc13d 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -40,7 +40,7 @@ childs (mf/deref childs-ref)] [:& (mf/provider embed/context) {:value true} - [:& shape-container {:shape shape :ref ref :disable-shadows? true} + [:& shape-container {:shape shape :ref ref :disable-shadows? (cph/root-frame? shape)} [:& frame-shape {:shape shape :childs childs} ]]])))) (defn check-props diff --git a/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs b/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs index 052a8f7d6..1417c5d5b 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/editor.cljs @@ -268,8 +268,7 @@ text-modifier (mf/deref text-modifier-ref) - bounding-box - (gsht/position-data-bounding-box text-modifier) + bounding-box (gsht/position-data-bounding-box (or text-modifier shape)) x (min (:x bounding-box) (:x shape)) y (min (:y bounding-box) (:y shape)) @@ -280,15 +279,15 @@ :transform (dm/str (gsh/transform-matrix shape))} [:defs [:clipPath {:id clip-id} - [:rect {:x (or x (:x shape)) - :y (or y (:y shape)) - :width (or width (:width shape)) - :height (or height (:height shape)) + [:rect {:x x + :y y + :width width + :height height :fill "red"}]]] - [:foreignObject {:x (:x shape) :y (:y shape) :width width :height height} + [:foreignObject {:x x :y y :width width :height height} [:div {:style {:position "absolute" :left 0 - :top 0 + :top (- (:y shape) y) :pointer-events "all"}} [:& text-shape-edit-html {:shape shape :key (str (:id shape))}]]]])) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 4b0565674..0c6c6a4ca 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -195,13 +195,17 @@ [:div.viewport [:div.viewport-overlays {:ref overlays-ref} - [:div {:style {:pointer-events "none" :opacity 0}} - [:& stvh/viewport-texts - {:key (dm/str "texts-" page-id) - :page-id page-id - :objects objects - :modifiers modifiers - :edition edition}]] + ;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap + ;; inside a foreign object "dummy" so this awkward behaviour is take into account + [:svg {:style {:top 0 :left 0 :position "fixed" :width "100%" :height "100%" :opacity 0}} + [:foreignObject {:x 0 :y 0 :width "100%" :height "100%"} + [:div {:style {:pointer-events "none"}} + [:& stvh/viewport-texts + {:key (dm/str "texts-" page-id) + :page-id page-id + :objects objects + :modifiers modifiers + :edition edition}]]]] (when show-comments? [:& comments/comments-layer {:vbox vbox diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs index c7e8b1eb4..88ce201be 100644 --- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs @@ -21,8 +21,8 @@ [app.main.ui.workspace.viewport.utils :as utils] [app.util.dom :as dom] [app.util.dom.dnd :as dnd] + [app.util.dom.normalize-wheel :as nw] [app.util.keyboard :as kbd] - [app.util.normalize-wheel :as nw] [app.util.object :as obj] [app.util.timers :as timers] [beicon.core :as rx] @@ -194,7 +194,7 @@ :else (let [;; We only get inside childrens of the hovering shape hover-ids (->> @hover-ids (filter (partial cph/is-child? objects id))) - selected (get objects (if (> (count hover-ids) 1) (second hover-ids) (first hover-ids)))] + selected (get objects (first hover-ids))] (when (some? selected) (reset! hover selected) (st/emit! (dw/select-shape (:id selected))))))))))))) diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index bd5bb883e..1737917dc 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -330,10 +330,10 @@ (defn bounding-rect->rect [rect] (when (some? rect) - {:x (or (.-left rect) (:left rect)) - :y (or (.-top rect) (:top rect)) - :width (or (.-width rect) (:width rect)) - :height (or (.-height rect) (:height rect))})) + {:x (or (.-left rect) (:left rect) 0) + :y (or (.-top rect) (:top rect) 0) + :width (or (.-width rect) (:width rect) 1) + :height (or (.-height rect) (:height rect) 1)})) (defn get-window-size [] @@ -482,11 +482,21 @@ (when (some? element) (.-scrollTop element))) +(defn get-h-scroll-pos + [^js element] + (when (some? element) + (.-scrollLeft element))) + (defn set-scroll-pos! [^js element scroll] (when (some? element) (obj/set! element "scrollTop" scroll))) +(defn set-h-scroll-pos! + [^js element scroll] + (when (some? element) + (obj/set! element "scrollLeft" scroll))) + (defn scroll-into-view! ([^js element] (scroll-into-view! element false)) diff --git a/frontend/src/app/util/dom/normalize_wheel.js b/frontend/src/app/util/dom/normalize_wheel.js index fc221e54c..69efb2bc1 100644 --- a/frontend/src/app/util/dom/normalize_wheel.js +++ b/frontend/src/app/util/dom/normalize_wheel.js @@ -15,15 +15,10 @@ 'use strict'; -goog.provide("app.util.normalize_wheel"); +goog.provide("app.util.dom.normalize_wheel"); goog.scope(function() { - const self = app.util.normalize_wheel; - - // const UserAgent_DEPRECATED = require('UserAgent_DEPRECATED'); - - // const isEventSupported = require('isEventSupported'); - + const self = app.util.dom.normalize_wheel; // Reasonable defaults const PIXEL_STEP = 10; @@ -174,6 +169,5 @@ goog.scope(function() { self.normalize_wheel = normalizeWheel; - }); diff --git a/frontend/src/app/util/text_svg_position.cljs b/frontend/src/app/util/text_svg_position.cljs index f73655a19..6957d64fd 100644 --- a/frontend/src/app/util/text_svg_position.cljs +++ b/frontend/src/app/util/text_svg_position.cljs @@ -19,13 +19,14 @@ [parent-node direction text-node] (letfn [(parse-entry [^js entry] - {:node (.-node entry) - :position (dom/bounding-rect->rect (.-position entry)) - :text (.-text entry) - :direction direction})] + (when (some? (.-position entry)) + {:node (.-node entry) + :position (dom/bounding-rect->rect (.-position entry)) + :text (.-text entry) + :direction direction}))] (into [] - (map parse-entry) + (keep parse-entry) (tpd/parse-text-nodes parent-node text-node)))) (def load-promises (atom {}))