|
| 1 | +(ns day8.reagent.impl.component |
| 2 | + (:require |
| 3 | + [goog.object :as gobj] |
| 4 | + [clojure.string :as string] |
| 5 | + [re-frame.trace :as trace :include-macros true] |
| 6 | + [re-frame.interop :as interop] |
| 7 | + [reagent.impl.component :as component] |
| 8 | + [reagent.impl.batching :as batch] |
| 9 | + [reagent.impl.util :as util] |
| 10 | + [reagent.ratom :as ratom] |
| 11 | + [reagent.debug :refer-macros [dev? warn error warn-unless assert-callable]])) |
| 12 | + |
| 13 | +(def operation-name (memoize (fn [c] (last (string/split (component/component-name c) #" > "))))) |
| 14 | + |
| 15 | +;; Monkey patched reagent.impl.component/wrap-funs to hook into render |
| 16 | +(defn wrap-funs [fmap compiler] |
| 17 | + (when (dev?) |
| 18 | + (let [renders (select-keys fmap [:render :reagentRender]) |
| 19 | + render-fun (-> renders vals first)] |
| 20 | + (assert (not (:componentFunction fmap)) ":component-function is no longer supported, use :reagent-render instead.") |
| 21 | + (assert (pos? (count renders)) "Missing reagent-render") |
| 22 | + (assert (== 1 (count renders)) "Too many render functions supplied") |
| 23 | + (assert-callable render-fun))) |
| 24 | + (let [render-fun (or (:reagentRender fmap) |
| 25 | + (:render fmap)) |
| 26 | + legacy-render (nil? (:reagentRender fmap)) |
| 27 | + name (or (:displayName fmap) |
| 28 | + (util/fun-name render-fun) |
| 29 | + (str (gensym "reagent"))) |
| 30 | + fmap (reduce-kv (fn [m k v] |
| 31 | + (assoc m k (component/get-wrapper k v))) |
| 32 | + {} fmap)] |
| 33 | + (assoc fmap |
| 34 | + :displayName name |
| 35 | + :cljsLegacyRender legacy-render |
| 36 | + :reagentRender render-fun |
| 37 | + :render (fn render [] |
| 38 | + (this-as c |
| 39 | + (trace/with-trace |
| 40 | + {:op-type :render |
| 41 | + :tags (if-let [component-name (component/component-name c)] |
| 42 | + {:component-name component-name} |
| 43 | + {}) |
| 44 | + :operation (operation-name c)}) |
| 45 | + (if util/*non-reactive* |
| 46 | + (component/do-render c compiler) |
| 47 | + (let [^clj rat (gobj/get c "cljsRatom") |
| 48 | + _ (batch/mark-rendered c) |
| 49 | + res (if (nil? rat) |
| 50 | + (ratom/run-in-reaction #(component/do-render c compiler) c "cljsRatom" |
| 51 | + batch/queue-render component/rat-opts) |
| 52 | + (._run rat false)) |
| 53 | + cljs-ratom (gobj/get c "cljsRatom")] |
| 54 | + (trace/merge-trace! |
| 55 | + {:tags {:reaction (interop/reagent-id cljs-ratom) |
| 56 | + :input-signals (when cljs-ratom |
| 57 | + (map interop/reagent-id (gobj/get cljs-ratom "watching" :none)))}}) |
| 58 | + res))))))) |
| 59 | + |
| 60 | +(defn patch-wrap-funs |
| 61 | + [] |
| 62 | + (set! reagent.impl.component/wrap-funs wrap-funs)) |
| 63 | + |
| 64 | +(defonce original-custom-wrapper reagent.impl.component/custom-wrapper) |
| 65 | + |
| 66 | +(defn custom-wrapper |
| 67 | + [key f] |
| 68 | + (case key |
| 69 | + :componentWillUnmount |
| 70 | + (fn componentWillUnmount [] |
| 71 | + (this-as c |
| 72 | + (trace/with-trace |
| 73 | + {:op-type key |
| 74 | + :operation (last (string/split (component/component-name c) #" > ")) |
| 75 | + :tags {:component-name (component/component-name c) |
| 76 | + :reaction (interop/reagent-id (gobj/get c "cljsRatom"))}}) |
| 77 | + (.call (original-custom-wrapper key f) c c))) |
| 78 | + (original-custom-wrapper key f))) |
| 79 | + |
| 80 | +(defn patch-custom-wrapper |
| 81 | + [] |
| 82 | + (set! reagent.impl.component/custom-wrapper custom-wrapper)) |
0 commit comments