on develop help sign in
Merge pull request #364 from reflex-frp/ts-hydration-attr

Export hydration attributes

commit4e4d49aea393ba9505accfef4eece749d2b2539d authorElliot Cameron <3noch@users.noreply.github.com> dateWed 1 Apr 2020, 16:35 (7 years ago) parent55a24020dc8d80
3 files changed+28−10
reflex-dom-core/ChangeLog.md+4 reflex-dom-core/src/Reflex/Dom/Builder/Hydratable.hs+4−4 reflex-dom-core/src/Reflex/Dom/Builder/Immediate.hs+20−6
reflex-dom-core/ChangeLog.md+4
@@ -19,6 +19,10 @@
1919
2020* Fix bug in hydration when dealing with unexpected HTML ([#361](https://github.com/reflex-frp/reflex-dom/pull/361)).
2121
22+* Export attributes used for controlling hydration at the element level
23+ * "data-ssr" is now available as `Reflex.Dom.Builder.Immediate.hydratableAttribute`
24+ * "data-hydration-skip" is now available as `Reflex.Dom.Builder.Immediate.skipHydrationAttribute`
25+
2226## 0.5.3
2327
2428* Deprecate a number of old inflexible widget helpers in `Reflex.Dom.Widget.Basic`:
reflex-dom-core/src/Reflex/Dom/Builder/Hydratable.hs+4−4
@@ -21,10 +21,10 @@ import GHCJS.DOM.Types (MonadJSM (..))
2121#endif
2222import Reflex
2323import Reflex.Dom.Builder.Class
24−import Reflex.Dom.Builder.Immediate (HasDocument (..))
24+import Reflex.Dom.Builder.Immediate (HasDocument (..), hydratableAttribute)
2525import Reflex.Host.Class
2626
27−-- | A DomBuilder transformer that adds "data-ssr" to all elements such that the
27+-- | A DomBuilder transformer that adds an attribute to all elements such that the
2828-- hydration builder knows which bits of DOM were added by us, and which were
2929-- added by external scripts.
3030newtype HydratableT m a = HydratableT { runHydratableT :: m a } deriving (Functor, Applicative, Monad, MonadAtomicRef, MonadFix, MonadIO)
@@ -62,8 +62,8 @@ instance PrimMonad m => PrimMonad (HydratableT m) where
6262
6363makeHydratable :: Reflex t => ElementConfig er t m -> ElementConfig er t m
6464makeHydratable cfg = cfg
65− { _elementConfig_initialAttributes = Map.insert "data-ssr" "" $ _elementConfig_initialAttributes cfg
66− , _elementConfig_modifyAttributes = fmap (Map.delete "data-ssr") <$> _elementConfig_modifyAttributes cfg
65+ { _elementConfig_initialAttributes = Map.insert hydratableAttribute "" $ _elementConfig_initialAttributes cfg
66+ , _elementConfig_modifyAttributes = fmap (Map.delete hydratableAttribute) <$> _elementConfig_modifyAttributes cfg
6767 }
6868
6969instance PostBuild t m => PostBuild t (HydratableT m) where
reflex-dom-core/src/Reflex/Dom/Builder/Immediate.hs+20−6
@@ -107,6 +107,9 @@ module Reflex.Dom.Builder.Immediate
107107 , WindowConfig (..)
108108 , Window (..)
109109 , wrapWindow
110+ -- * Attributes for controlling hydration
111+ , hydratableAttribute
112+ , skipHydrationAttribute
110113 -- * Internal
111114 , traverseDMapWithKeyWithAdjust'
112115 , hoistTraverseWithKeyWithAdjust
@@ -137,6 +140,7 @@ import Data.IntMap.Strict (IntMap)
137140import Data.Maybe
138141import Data.Monoid ((<>))
139142import Data.Some (Some(..))
143+import Data.String (IsString)
140144import Data.Text (Text)
141145import Foreign.JavaScript.Internal.Utils
142146import Foreign.JavaScript.TH
@@ -743,6 +747,14 @@ elementInternal elementTag cfg child = getHydrationMode >>= \case
743747 -> HydrationDomBuilderT HydrationDomSpace DomTimeline HydrationM (Element er HydrationDomSpace DomTimeline, a)
744748 #-}
745749
750+-- | An attribute which causes hydration to skip over an element completely.
751+skipHydrationAttribute :: IsString s => s
752+skipHydrationAttribute = "data-hydration-skip"
753+
754+-- | An attribute which signals that an element should be hydrated.
755+hydratableAttribute :: IsString s => s
756+hydratableAttribute = "data-ssr"
757+
746758{-# INLINE hydrateElement #-}
747759hydrateElement
748760 :: forall er t m a. (MonadJSM m, Reflex t, MonadReflexCreateTrigger t m, MonadFix m)
@@ -764,13 +776,15 @@ hydrateElement elementTag cfg child = do
764776 }
765777 result <- HydrationDomBuilderT $ lift $ runReaderT (unHydrationDomBuilderT child) env'
766778 wrapResult <- liftIO newEmptyMVar
767− let skipAttr = "data-hydration-skip" :: DOM.JSString
768− ssrAttr = "data-ssr" :: DOM.JSString
779+ let -- Determine if we should skip an element. We currently skip elements for
780+ -- two reasons:
781+ -- 1) it was not produced by a static builder which supports hydration
782+ -- 2) it is explicitly marked to be skipped
769783 shouldSkip :: DOM.Element -> HydrationRunnerT t m Bool
770784 shouldSkip e = do
771− skip <- hasAttribute e skipAttr
772− ssr <- hasAttribute e ssrAttr
773− pure $ skip || not ssr
785+ skip <- hasAttribute e (skipHydrationAttribute :: DOM.JSString)
786+ hydratable <- hasAttribute e (hydratableAttribute :: DOM.JSString)
787+ pure $ skip || not hydratable
774788 childDom <- liftIO $ readIORef childDelayedRef
775789 let rawCfg = extractRawElementConfig cfg
776790 doc <- askDocument
@@ -786,7 +800,7 @@ hydrateElement elementTag cfg child = do
786800 Just node -> DOM.castTo DOM.Element node >>= \case
787801 Nothing -> go (Just node) -- this node is not an element, skip
788802 Just e -> shouldSkip e >>= \case
789− True -> go (Just node) -- this element is explicitly marked for being skipped by hydration
803+ True -> go (Just node) -- this element should be skipped by hydration
790804 False -> do
791805 t <- Element.getTagName e
792806 -- TODO: check attributes?