@@ -15,6 +15,7 @@ module Reflex.Dom.Internal where
16import Prelude hiding (concat, mapM, mapM_, sequence, sequence_)
16import Prelude hiding (concat, mapM, mapM_, sequence, sequence_)
18+import qualified Reflex as R
18import Reflex.Dom.Builder.Immediate
19import Reflex.Dom.Builder.Immediate
19import Reflex.Dom.Class
20import Reflex.Dom.Class
20import Reflex.Dom.Internal.Foreign
21import Reflex.Dom.Internal.Foreign
@@ -74,23 +75,49 @@ type Widget x = PostBuildT Spider (ImmediateDomBuilderT Spider (WithWebView x (P
74attachWidget :: DOM.IsElement e => e -> WebViewSingleton x -> Widget x a -> IO a
75attachWidget :: DOM.IsElement e => e -> WebViewSingleton x -> Widget x a -> IO a
75attachWidget rootElement wv w = fst <$> attachWidget' rootElement wv w
76attachWidget rootElement wv w = fst <$> attachWidget' rootElement wv w
77−{-# INLINABLE attachWidget' #-}
78+mainWidgetWithHead' :: (forall x. (a -> Widget x b, b -> Widget x a)) -> IO ()
79+mainWidgetWithHead' widgets = runWebGUI $ \webView -> withWebViewSingleton webView $ \wv -> fmap fst $ attachWidget'' $ \events -> do
80+ let (headWidget, bodyWidget) = widgets
81+ Just doc <- liftIO $ fmap DOM.castToHTMLDocument <$> webViewGetDomDocument webView
82+ Just headElement <- getHead doc
83+ Just bodyElement <- getBody doc
84+ (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
85+ rec b <- unsafeReplaceElementContentsWithWidget events postBuild headElement wv $ headWidget a
86+ a <- unsafeReplaceElementContentsWithWidget events postBuild bodyElement wv $ bodyWidget b
87+ return ((), postBuildTriggerRef)
78−attachWidget' :: DOM.IsElement e => e -> WebViewSingleton x -> Widget x a -> IO (a, FireCommand Spider (SpiderHost Global))
89+unsafeReplaceElementContentsWithWidget :: DOM.IsElement e => EventChannel -> R.Event Spider () -> e -> WebViewSingleton x -> Widget x a -> PerformEventT Spider (SpiderHost Global) a
79−attachWidget' rootElement wv w = do
90+unsafeReplaceElementContentsWithWidget events postBuild rootElement wv w = do
80 Just doc <- getOwnerDocument rootElement
91 Just doc <- getOwnerDocument rootElement
81 Just df <- createDocumentFragment doc
92 Just df <- createDocumentFragment doc
93+ let builderEnv = ImmediateDomBuilderEnv
94+ { _immediateDomBuilderEnv_document = doc
95+ , _immediateDomBuilderEnv_parent = toNode df
96+ , _immediateDomBuilderEnv_events = events
98+ result <- runWithWebView (runImmediateDomBuilderT (runPostBuildT w postBuild) builderEnv) wv
99+ setInnerHTML rootElement $ Just ("" :: String)
100+ _ <- appendChild rootElement $ Just df
103+{-# INLINABLE attachWidget' #-}
104+attachWidget' :: DOM.IsElement e => e -> WebViewSingleton x -> Widget x a -> IO (a, FireCommand Spider (SpiderHost Global))
105+attachWidget' rootElement wv w = attachWidget'' $ \events -> do
106+ (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
107+ result <- unsafeReplaceElementContentsWithWidget events postBuild rootElement wv w
108+ return (result, postBuildTriggerRef)
110+type EventChannel = Chan [DSum (TriggerRef Spider) TriggerInvocation]
112+{-# INLINABLE attachWidget'' #-}
113+attachWidget'' :: (EventChannel -> PerformEventT Spider (SpiderHost Global) (a, IORef (Maybe (EventTrigger Spider ())))) -> IO (a, FireCommand Spider (SpiderHost Global))
114+attachWidget'' w = do
82 events <- newChan
115 events <- newChan
83 (result, fc@(FireCommand fire)) <- runSpiderHost $ do
116 (result, fc@(FireCommand fire)) <- runSpiderHost $ do
84− (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
117+ ((result, postBuildTriggerRef), fc@(FireCommand fire)) <- hostPerformEventT $ w events
85− let builderEnv = ImmediateDomBuilderEnv
86− { _immediateDomBuilderEnv_document = doc
87− , _immediateDomBuilderEnv_parent = toNode df
88− , _immediateDomBuilderEnv_events = events
90− results@(_, FireCommand fire) <- hostPerformEventT $ runWithWebView (runImmediateDomBuilderT (runPostBuildT w postBuild) builderEnv) wv
91 mPostBuildTrigger <- readRef postBuildTriggerRef
118 mPostBuildTrigger <- readRef postBuildTriggerRef
92 forM_ mPostBuildTrigger $ \postBuildTrigger -> fire [postBuildTrigger :=> Identity ()] $ return ()
119 forM_ mPostBuildTrigger $ \postBuildTrigger -> fire [postBuildTrigger :=> Identity ()] $ return ()
93− return results
120+ return (result, fc)
94 void $ forkIO $ forever $ do
121 void $ forkIO $ forever $ do
95 ers <- readChan events
122 ers <- readChan events
96 _ <- postGUISync $ runSpiderHost $ do
123 _ <- postGUISync $ runSpiderHost $ do
@@ -100,8 +127,6 @@ attachWidget' rootElement wv w = do
100 _ <- fire (catMaybes mes) $ return ()
127 _ <- fire (catMaybes mes) $ return ()
101 liftIO $ forM_ ers $ \(_ :=> TriggerInvocation _ cb) -> cb
128 liftIO $ forM_ ers $ \(_ :=> TriggerInvocation _ cb) -> cb
102 return ()
129 return ()
103− setInnerHTML rootElement $ Just (""::String)
104− _ <- appendChild rootElement $ Just df
105 return (result, fc)
130 return (result, fc)
107-- | Run a reflex-dom application inside of an existing DOM element with the given ID
132-- | Run a reflex-dom application inside of an existing DOM element with the given ID