@@ -141,7 +141,7 @@ import Data.Text (Text)
141import Foreign.JavaScript.Internal.Utils
141import Foreign.JavaScript.Internal.Utils
142import Foreign.JavaScript.TH
142import Foreign.JavaScript.TH
143import GHCJS.DOM.Document (Document, createDocumentFragment, createElement, createElementNS, createTextNode, createComment)
143import GHCJS.DOM.Document (Document, createDocumentFragment, createElement, createElementNS, createTextNode, createComment)
144−import GHCJS.DOM.Element (getScrollTop, removeAttribute, removeAttributeNS, setAttribute, setAttributeNS, hasAttribute, hasAttributeNS)
144+import GHCJS.DOM.Element (getScrollTop, removeAttribute, removeAttributeNS, setAttribute, setAttributeNS, hasAttribute)
145import GHCJS.DOM.EventM (EventM, event, on)
145import GHCJS.DOM.EventM (EventM, event, on)
146import GHCJS.DOM.KeyboardEvent as KeyboardEvent
146import GHCJS.DOM.KeyboardEvent as KeyboardEvent
147import GHCJS.DOM.MouseEvent
147import GHCJS.DOM.MouseEvent
@@ -192,6 +192,7 @@ import qualified GHCJS.DOM.TouchEvent as TouchEvent
192import qualified GHCJS.DOM.TouchList as TouchList
192import qualified GHCJS.DOM.TouchList as TouchList
193import qualified GHCJS.DOM.Types as DOM
193import qualified GHCJS.DOM.Types as DOM
194import qualified GHCJS.DOM.Window as Window
194import qualified GHCJS.DOM.Window as Window
195+import qualified GHCJS.DOM.WheelEvent as WheelEvent
195import qualified Reflex.Patch.DMap as PatchDMap
196import qualified Reflex.Patch.DMap as PatchDMap
196import qualified Reflex.Patch.DMapWithMove as PatchDMapWithMove
197import qualified Reflex.Patch.DMapWithMove as PatchDMapWithMove
197import qualified Reflex.Patch.MapWithMove as PatchMapWithMove
198import qualified Reflex.Patch.MapWithMove as PatchMapWithMove
@@ -318,8 +319,7 @@ addHydrationStepWithSetup :: (Adjustable t m, MonadIO m) => m a -> (a -> Hydrati
318addHydrationStepWithSetup setup f = getHydrationMode >>= \case
319addHydrationStepWithSetup setup f = getHydrationMode >>= \case
319 HydrationMode_Immediate -> pure ()
320 HydrationMode_Immediate -> pure ()
320 HydrationMode_Hydrating -> do
321 HydrationMode_Hydrating -> do
321− switchover <- HydrationDomBuilderT $ asks _hydrationDomBuilderEnv_switchover
322+ s <- lift setup
322− (s, _) <- lift $ runWithReplace setup $ return () <$ switchover
323 addHydrationStep (f s)
323 addHydrationStep (f s)
325-- | Add a hydration step
325-- | Add a hydration step
@@ -767,15 +767,10 @@ hydrateElement elementTag cfg child = do
767 let skipAttr = "data-hydration-skip" :: DOM.JSString
767 let skipAttr = "data-hydration-skip" :: DOM.JSString
768 ssrAttr = "data-ssr" :: DOM.JSString
768 ssrAttr = "data-ssr" :: DOM.JSString
769 shouldSkip :: DOM.Element -> HydrationRunnerT t m Bool
769 shouldSkip :: DOM.Element -> HydrationRunnerT t m Bool
770− shouldSkip e = case cfg ^. namespace of
770+ shouldSkip e = do
772− skip <- hasAttribute e skipAttr
771+ skip <- hasAttribute e skipAttr
773− ssr <- hasAttribute e ssrAttr
772+ ssr <- hasAttribute e ssrAttr
774− pure $ skip || not ssr
776− skip <- hasAttributeNS e (Just ns) skipAttr
777− ssr <- hasAttributeNS e (Just ns) ssrAttr
778− pure $ skip || not ssr
773+ pure $ skip || not ssr
779 childDom <- liftIO $ readIORef childDelayedRef
774 childDom <- liftIO $ readIORef childDelayedRef
780 let rawCfg = extractRawElementConfig cfg
775 let rawCfg = extractRawElementConfig cfg
781 doc <- askDocument
776 doc <- askDocument
@@ -1277,8 +1272,8 @@ hydrateComment doc t mSetContents = do
1277skipToAndReplaceComment
1272skipToAndReplaceComment
1278 :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m, RawDocument (DomBuilderSpace (HydrationDomBuilderT s t m)) ~ Document)
1273 :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m, RawDocument (DomBuilderSpace (HydrationDomBuilderT s t m)) ~ Document)
1280− -> IORef Text
1275+ -> IORef (Maybe Text)
1281− -> HydrationDomBuilderT s t m (HydrationRunnerT t m (), IORef DOM.Text, IORef Text)
1276+ -> HydrationDomBuilderT s t m (HydrationRunnerT t m (), IORef DOM.Text, IORef (Maybe Text))
1282skipToAndReplaceComment prefix key0Ref = getHydrationMode >>= \case
1277skipToAndReplaceComment prefix key0Ref = getHydrationMode >>= \case
1283 HydrationMode_Immediate -> do
1278 HydrationMode_Immediate -> do
1284 -- If we're in immediate mode, we don't try to replace an existing comment,
1279 -- If we're in immediate mode, we don't try to replace an existing comment,
@@ -1286,43 +1281,50 @@ skipToAndReplaceComment prefix key0Ref = getHydrationMode >>= \case
1286 t <- textNodeImmediate $ TextNodeConfig ("" :: Text) Nothing
1281 t <- textNodeImmediate $ TextNodeConfig ("" :: Text) Nothing
1287 append $ toNode t
1282 append $ toNode t
1288 textNodeRef <- liftIO $ newIORef t
1283 textNodeRef <- liftIO $ newIORef t
1289− keyRef <- liftIO $ newIORef ""
1284+ keyRef <- liftIO $ newIORef Nothing
1290 pure (pure (), textNodeRef, keyRef)
1285 pure (pure (), textNodeRef, keyRef)
1291 HydrationMode_Hydrating -> do
1286 HydrationMode_Hydrating -> do
1292 doc <- askDocument
1287 doc <- askDocument
1293 textNodeRef <- liftIO $ newIORef $ error "textNodeRef not yet initialized"
1288 textNodeRef <- liftIO $ newIORef $ error "textNodeRef not yet initialized"
1294 keyRef <- liftIO $ newIORef $ error "keyRef not yet initialized"
1289 keyRef <- liftIO $ newIORef $ error "keyRef not yet initialized"
1292+ tn <- createTextNode doc ("" :: Text)
1293+ insertAfterPreviousNode tn
1294+ HydrationRunnerT $ modify' $ \s -> s { _hydrationState_failed = True }
1295− let go key0 mLastNode = do
1296+ go (Just key0) mLastNode = do
1296− parent <- askParent
1297+ parent <- askParent
1297− node <- maybe (Node.getFirstChildUnchecked parent) Node.getNextSiblingUnchecked mLastNode
1298+ maybe (Node.getFirstChild parent) Node.getNextSibling mLastNode >>= \case
1299+ Nothing -> go Nothing Nothing
1298− DOM.castTo DOM.Comment node >>= \case
1300+ Just node -> DOM.castTo DOM.Comment node >>= \case
1299 Just comment -> do
1301 Just comment -> do
1300− commentText <- Node.getTextContentUnchecked comment
1302+ commentText <- fromMaybe (error "Cannot get text content of comment node") <$> Node.getTextContent comment
1301− case T.stripPrefix (prefix <> key0) commentText of
1303+ case T.stripPrefix (prefix <> key0) commentText of -- 'key0' may be @""@ in which case we're just finding the actual key; TODO: Don't be clever.
1302 Just key -> do
1304 Just key -> do
1303 -- Replace the comment with an (invisible) text node
1305 -- Replace the comment with an (invisible) text node
1304 tn <- createTextNode doc ("" :: Text)
1306 tn <- createTextNode doc ("" :: Text)
1305 Node.replaceChild_ parent tn comment
1307 Node.replaceChild_ parent tn comment
1306− pure (tn, key)
1308+ pure (tn, Just key)
1307 Nothing -> do
1309 Nothing -> do
1308− go key0 (Just node)
1310+ go (Just key0) (Just node)
1309 Nothing -> do
1311 Nothing -> do
1310− go key0 (Just node)
1312+ go (Just key0) (Just node)
1311− switchComment = do
1313+ switchComment = do
1312− key0 <- liftIO $ readIORef key0Ref
1314+ key0 <- liftIO $ readIORef key0Ref
1313− (tn, key) <- go key0 =<< getPreviousNode
1315+ (tn, key) <- go key0 =<< getPreviousNode
1314− setPreviousNode $ Just $ toNode tn
1316+ setPreviousNode $ Just $ toNode tn
1315− liftIO $ do
1317+ liftIO $ do
1316− writeIORef textNodeRef tn
1318+ writeIORef textNodeRef tn
1317− writeIORef keyRef key
1319+ writeIORef keyRef key
1318 pure (switchComment, textNodeRef, keyRef)
1320 pure (switchComment, textNodeRef, keyRef)
1320{-# INLINABLE skipToReplaceStart #-}
1322{-# INLINABLE skipToReplaceStart #-}
1321−skipToReplaceStart :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m, RawDocument (DomBuilderSpace (HydrationDomBuilderT s t m)) ~ Document) => HydrationDomBuilderT s t m (HydrationRunnerT t m (), IORef DOM.Text, IORef Text)
1323+skipToReplaceStart :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m, RawDocument (DomBuilderSpace (HydrationDomBuilderT s t m)) ~ Document) => HydrationDomBuilderT s t m (HydrationRunnerT t m (), IORef DOM.Text, IORef (Maybe Text))
1322−skipToReplaceStart = skipToAndReplaceComment "replace-start" =<< liftIO (newIORef "")
1324+skipToReplaceStart = skipToAndReplaceComment "replace-start" =<< liftIO (newIORef $ Just "") -- TODO: Don't rely on clever usage @""@ to make this work.
1324{-# INLINABLE skipToReplaceEnd #-}
1326{-# INLINABLE skipToReplaceEnd #-}
1325−skipToReplaceEnd :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m, RawDocument (DomBuilderSpace (HydrationDomBuilderT s t m)) ~ Document) => IORef Text -> HydrationDomBuilderT s t m (HydrationRunnerT t m (), IORef DOM.Text)
1327+skipToReplaceEnd :: (MonadJSM m, Reflex t, MonadFix m, Adjustable t m, MonadHold t m, RawDocument (DomBuilderSpace (HydrationDomBuilderT s t m)) ~ Document) => IORef (Maybe Text) -> HydrationDomBuilderT s t m (HydrationRunnerT t m (), IORef DOM.Text)
1326skipToReplaceEnd key = fmap (\(m,e,_) -> (m,e)) $ skipToAndReplaceComment "replace-end" key
1328skipToReplaceEnd key = fmap (\(m,e,_) -> (m,e)) $ skipToAndReplaceComment "replace-end" key
1328instance SupportsHydrationDomBuilder t m => NotReady t (HydrationDomBuilderT s t m) where
1330instance SupportsHydrationDomBuilder t m => NotReady t (HydrationDomBuilderT s t m) where
@@ -2248,7 +2250,7 @@ defaultDomEventHandler e evt = fmap (Just . EventResult) $ case evt of
2248 Touchend -> getTouchEvent
2250 Touchend -> getTouchEvent
2249 Touchcancel -> getTouchEvent
2251 Touchcancel -> getTouchEvent
2250 Mousewheel -> return ()
2252 Mousewheel -> return ()
2251− Wheel -> return ()
2253+ Wheel -> getWheelEvent
2253{-# INLINABLE defaultDomWindowEventHandler #-}
2255{-# INLINABLE defaultDomWindowEventHandler #-}
2254defaultDomWindowEventHandler :: DOM.Window -> EventName en -> EventM DOM.Window (EventType en) (Maybe (EventResult en))
2256defaultDomWindowEventHandler :: DOM.Window -> EventName en -> EventM DOM.Window (EventType en) (Maybe (EventResult en))
@@ -2298,7 +2300,7 @@ defaultDomWindowEventHandler w evt = fmap (Just . EventResult) $ case evt of
2298 Touchend -> getTouchEvent
2300 Touchend -> getTouchEvent
2299 Touchcancel -> getTouchEvent
2301 Touchcancel -> getTouchEvent
2300 Mousewheel -> return ()
2302 Mousewheel -> return ()
2301− Wheel -> return ()
2303+ Wheel -> getWheelEvent
2303{-# INLINABLE withIsEvent #-}
2305{-# INLINABLE withIsEvent #-}
2304withIsEvent :: EventName en -> (IsEvent (EventType en) => r) -> r
2306withIsEvent :: EventName en -> (IsEvent (EventType en) => r) -> r
@@ -2607,6 +2609,26 @@ getTouchEvent = do
2607 , _touchEventResult_touches = touches
2609 , _touchEventResult_touches = touches
2612+{-# INLINABLE getWheelEvent #-}
2613+getWheelEvent :: EventM e WheelEvent WheelEventResult
2616+ dx :: Double <- WheelEvent.getDeltaX e
2617+ dy :: Double <- WheelEvent.getDeltaY e
2618+ dz :: Double <- WheelEvent.getDeltaZ e
2619+ deltaMode :: Word <- WheelEvent.getDeltaMode e
2620+ return $ WheelEventResult
2621+ { _wheelEventResult_deltaX = dx
2622+ , _wheelEventResult_deltaY = dy
2623+ , _wheelEventResult_deltaZ = dz
2624+ , _wheelEventResult_deltaMode = case deltaMode of
2628+ -- See https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode
2629+ _ -> error "getWheelEvent: impossible encoding"
2610instance MonadSample t m => MonadSample t (HydrationDomBuilderT s t m) where
2632instance MonadSample t m => MonadSample t (HydrationDomBuilderT s t m) where
2611 {-# INLINABLE sample #-}
2633 {-# INLINABLE sample #-}
2612 sample = lift . sample
2634 sample = lift . sample