@@ -653,9 +653,8 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
653 -- Watch for user interaction and trigger event accordingly
653 -- Watch for user interaction and trigger event accordingly
654 requestDomAction_ $ (liftJSM getValue >>= liftIO . triggerChangeByUI) <$ Reflex.select (_element_events e) (WrapArg Input)
654 requestDomAction_ $ (liftJSM getValue >>= liftIO . triggerChangeByUI) <$ Reflex.select (_element_events e) (WrapArg Input)
656− case _inputElementConfig_setValue cfg of
656+ for_ (_inputElementConfig_setValue cfg) $ \eSetValue ->
658− Just eSetValue -> requestDomAction_ $ ffor eSetValue $ \v' -> do
657+ requestDomAction_ $ ffor eSetValue $ \v' -> do
659 Input.setValue domInputElement v'
658 Input.setValue domInputElement v'
660 v <- getValue -- We get the value after setting it in case the browser has mucked with it somehow
659 v <- getValue -- We get the value after setting it in case the browser has mucked with it somehow
661 liftIO $ triggerChangeBySetValue v
660 liftIO $ triggerChangeBySetValue v
@@ -691,7 +690,7 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
691 checked <- holdUniqDyn checked'
690 checked <- holdUniqDyn checked'
693 let initialFocus = False -- Assume it isn't focused, but we update the actual focus state at switchover
692 let initialFocus = False -- Assume it isn't focused, but we update the actual focus state at switchover
694− hasFocus <- holdDyn initialFocus focusChange
693+ hasFocus <- holdUniqDyn =<< holdDyn initialFocus focusChange
696 v <- holdDyn v0 $ leftmost
695 v <- holdDyn v0 $ leftmost
697 [ valueChangedBySetValue
696 [ valueChangedBySetValue
@@ -712,30 +711,59 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
714 {-# INLINABLE textAreaElement #-}
713 {-# INLINABLE textAreaElement #-}
715− textAreaElement cfg = do --TODO
714+ textAreaElement cfg = do
716− ((e, _), _domElement') <- makeElement "textarea" (cfg ^. textAreaElementConfig_elementConfig) $ return ()
715+ ((e, _), domElementRef) <- makeElement "textarea" (cfg ^. textAreaElementConfig_elementConfig) $ return ()
717− let domElement = undefined :: DOM.HTMLTextAreaElement
716+
718− let domTextAreaElement = uncheckedCastTo DOM.HTMLTextAreaElement domElement
717+ (valueChangedByUI, triggerChangeByUI) <- newTriggerEvent
719− TextArea.setValue domTextAreaElement $ cfg ^. textAreaElementConfig_initialValue
718+ (valueChangedBySetValue, triggerChangeBySetValue) <- newTriggerEvent
720− v0 <- TextArea.getValue domTextAreaElement
719+
721− let getMyValue = TextArea.getValue domTextAreaElement
720+ (focusChange, triggerFocusChange) <- newTriggerEvent
722− valueChangedByUI <- requestDomAction $ liftJSM getMyValue <$ Reflex.select (_element_events e) (WrapArg Input)
721+
724+ -- Expected initial value from config
725+ let v0 = _textAreaElementConfig_initialValue cfg
727+ addHydrationStep $ do
728+ domElement <- liftIO $ readIORef domElementRef
729+ let domTextAreaElement = uncheckedCastTo DOM.HTMLTextAreaElement domElement
730+ getValue = TextArea.getValue domTextAreaElement
732+ -- The browser might have messed with the value, or the user could have
733+ -- altered it before activation, so we set it if it isn't what we expect
734+ liftJSM getValue >>= \v0' -> do
735+ when (v0' /= v0) $ liftIO $ triggerChangeByUI v0'
737+ -- Watch for user interaction and trigger event accordingly
738+ requestDomAction_ $ (liftJSM getValue >>= liftIO . triggerChangeByUI) <$ Reflex.select (_element_events e) (WrapArg Input)
723− valueChangedBySetValue <- case _textAreaElementConfig_setValue cfg of
740+ for_ (_textAreaElementConfig_setValue cfg) $ \eSetValue ->
724− Nothing -> return never
725− Just eSetValue -> requestDomAction $ ffor eSetValue $ \v' -> do
741+ requestDomAction_ $ ffor eSetValue $ \v' -> do
726− TextArea.setValue domTextAreaElement v'
742+ TextArea.setValue domTextAreaElement v'
727− getMyValue -- We get the value after setting it in case the browser has mucked with it somehow
743+ v <- getValue -- We get the value after setting it in case the browser has mucked with it somehow
744+ liftIO $ triggerChangeBySetValue v
746+ let focusChange' = leftmost
747+ [ False <$ Reflex.select (_element_events e) (WrapArg Blur)
748+ , True <$ Reflex.select (_element_events e) (WrapArg Focus)
750+ liftIO . triggerFocusChange =<< Node.isSameNode (toNode domElement) . fmap toNode =<< Document.getActiveElement doc
751+ requestDomAction_ $ liftIO . triggerFocusChange <$> focusChange'
753+ let initialFocus = False -- Assume it isn't focused, but we update the actual focus state at switchover
754+ hasFocus <- holdUniqDyn =<< holdDyn initialFocus focusChange
728 v <- holdDyn v0 $ leftmost
756 v <- holdDyn v0 $ leftmost
729 [ valueChangedBySetValue
757 [ valueChangedBySetValue
730 , valueChangedByUI
758 , valueChangedByUI
732− hasFocus <- mkHasFocus e
760+
733 return $ TextAreaElement
761 return $ TextAreaElement
734 { _textAreaElement_value = v
762 { _textAreaElement_value = v
735 , _textAreaElement_input = valueChangedByUI
763 , _textAreaElement_input = valueChangedByUI
736 , _textAreaElement_hasFocus = hasFocus
764 , _textAreaElement_hasFocus = hasFocus
737 , _textAreaElement_element = e
765 , _textAreaElement_element = e
738− , _textAreaElement_raw = domTextAreaElement
766+ , _textAreaElement_raw = undefined -- TODO domTextAreaElement
741 {-# INLINABLE selectElement #-}
769 {-# INLINABLE selectElement #-}