@@ -15,6 +15,7 @@ module Reflex.Dom.Internal where
1515
1616import Prelude hiding (concat, mapM, mapM_, sequence, sequence_)
1717
18+import qualified Reflex as R
1819import Reflex.Dom.Builder.Immediate
1920import Reflex.Dom.Class
2021import Reflex.Dom.Internal.Foreign
@@ -74,23 +75,49 @@ type Widget x = PostBuildT Spider (ImmediateDomBuilderT Spider (WithWebView x (P
7475attachWidget :: DOM.IsElement e => e -> WebViewSingleton x -> Widget x a -> IO a
7576attachWidget rootElement wv w = fst <$> attachWidget' rootElement wv w
7677
77−{-# INLINABLE attachWidget' #-}
78−attachWidget' :: DOM.IsElement e => e -> WebViewSingleton x -> Widget x a -> IO (a, FireCommand Spider (SpiderHost Global))
79−attachWidget' rootElement wv w = do
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)
88+
89+unsafeReplaceElementContentsWithWidget :: DOM.IsElement e => EventChannel -> R.Event Spider () -> e -> WebViewSingleton x -> Widget x a -> PerformEventT Spider (SpiderHost Global) a
90+unsafeReplaceElementContentsWithWidget events postBuild rootElement wv w = do
8091 Just doc <- getOwnerDocument rootElement
8192 Just df <- createDocumentFragment doc
93+ let builderEnv = ImmediateDomBuilderEnv
94+ { _immediateDomBuilderEnv_document = doc
95+ , _immediateDomBuilderEnv_parent = toNode df
96+ , _immediateDomBuilderEnv_events = events
97+ }
98+ result <- runWithWebView (runImmediateDomBuilderT (runPostBuildT w postBuild) builderEnv) wv
99+ setInnerHTML rootElement $ Just ("" :: String)
100+ _ <- appendChild rootElement $ Just df
101+ return result
102+
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)
109+
110+type EventChannel = Chan [DSum (TriggerRef Spider) TriggerInvocation]
111+
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
82115 events <- newChan
83116 (result, fc@(FireCommand fire)) <- runSpiderHost $ do
84− (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
85− let builderEnv = ImmediateDomBuilderEnv
86− { _immediateDomBuilderEnv_document = doc
87− , _immediateDomBuilderEnv_parent = toNode df
88− , _immediateDomBuilderEnv_events = events
89− }
90− results@(_, FireCommand fire) <- hostPerformEventT $ runWithWebView (runImmediateDomBuilderT (runPostBuildT w postBuild) builderEnv) wv
117+ ((result, postBuildTriggerRef), fc@(FireCommand fire)) <- hostPerformEventT $ w events
91118 mPostBuildTrigger <- readRef postBuildTriggerRef
92119 forM_ mPostBuildTrigger $ \postBuildTrigger -> fire [postBuildTrigger :=> Identity ()] $ return ()
93− return results
120+ return (result, fc)
94121 void $ forkIO $ forever $ do
95122 ers <- readChan events
96123 _ <- postGUISync $ runSpiderHost $ do
@@ -100,8 +127,6 @@ attachWidget' rootElement wv w = do
100127 _ <- fire (catMaybes mes) $ return ()
101128 liftIO $ forM_ ers $ \(_ :=> TriggerInvocation _ cb) -> cb
102129 return ()
103− setInnerHTML rootElement $ Just (""::String)
104− _ <- appendChild rootElement $ Just df
105130 return (result, fc)
106131
107132-- | Run a reflex-dom application inside of an existing DOM element with the given ID