on develop help sign in
Improve updating.

Use `Unchecked` versions of functions where possible and replace `deleteBetween*` and `deleteUpTo*` functions with JS versions to avoid the need for synchronous ops (`getParentNode` and `strictEqual`)

commit39af22e1f38b8f0c4bfefd83c16c8f179704aedc authorHamish Mackenzie <Hamish.K.Mackenzie@googlemail.com> dateWed 30 Nov 2016, 10:43 (10 years ago) parentdcdd6a8
6 files changed+134−92
reflex-dom.cabal+1−2 src/Foreign/JavaScript/TH.hs+1−3 src/Reflex/Dom/Builder/Immediate.hs+104−59 src/Reflex/Dom/Internal.hs+19−19 src/Reflex/Dom/Old.hs+3−3 src/Reflex/Dom/Widget/Input.hs+6−6
reflex-dom.cabal+1−2
@@ -45,6 +45,7 @@ library
4545 directory == 1.2.*,
4646 exception-transformers == 0.4.*,
4747 ghcjs-dom >= 0.7.0.0 && < 0.8,
48+ jsaddle >=0.7.0.0 && <0.8,
4849 -- keycode-0.2 has a bug on firefox
4950 keycode >= 0.2.1 && < 0.3,
5051 lens >= 4.7 && < 5,
@@ -70,8 +71,6 @@ library
7071 hashable == 1.2.*
7172 else
7273 hs-source-dirs: src-ghc
73− build-depends:
74− jsaddle >=0.7.0.0 && <0.8
7574 if !os(windows)
7675 build-depends: unix == 2.7.*
7776
src/Foreign/JavaScript/TH.hs+1−3
@@ -281,9 +281,7 @@ instance MonadJS JSCtx_IO IO where
281281 fromJSString (JSRef_IO r) = return $ JS.fromJSString $ JS.pFromJSVal r
282282 fromJSArray (JSRef_IO r) = fmap coerce $ JS.toListIO $ coerce r
283283 fromJSUint8Array (JSRef_IO r) = fmap (JS.toByteString 0 Nothing . JS.createFromArrayBuffer) $ JSArrayBuffer.unsafeFreeze $ JS.pFromJSVal r --TODO: Assert that this is immutable
284− fromJSNumber (JSRef_IO r) = do
285− Just n <- JS.fromJSVal r
286− return n
284+ fromJSNumber (JSRef_IO r) = JS.fromJSValUnchecked r
287285 withJSBool b f = f $ JSRef_IO $ JS.toJSBool b
288286 withJSString s f = f $ JSRef_IO $ JS.pToJSVal $ JS.toJSString s
289287 withJSNumber n f = do
src/Reflex/Dom/Builder/Immediate.hs+104−59
@@ -54,7 +54,7 @@ import Data.Monoid
5454import Data.Some (Some)
5555import qualified Data.Some as Some
5656import Data.Text (Text)
57−import GHCJS.DOM.Document (Document, createDocumentFragment, createElement, createElementNS, createTextNode)
57+import GHCJS.DOM.Document (Document, createDocumentFragmentUnchecked, createElementUnchecked, createElementNSUnchecked, createTextNodeUnchecked)
5858import GHCJS.DOM.Element (getScrollTop, removeAttribute, removeAttributeNS, setAttribute, setAttributeNS)
5959import qualified GHCJS.DOM.Element as Element
6060import qualified GHCJS.DOM.Event as Event
@@ -65,9 +65,9 @@ import qualified GHCJS.DOM.HTMLInputElement as Input
6565import qualified GHCJS.DOM.HTMLSelectElement as Select
6666import qualified GHCJS.DOM.HTMLTextAreaElement as TextArea
6767import GHCJS.DOM.MouseEvent
68−import GHCJS.DOM.Node (appendChild, getOwnerDocument, getParentNode, getPreviousSibling,
69− removeChild, setNodeValue, toNode)
70−import qualified GHCJS.DOM.Node as DOM (insertBefore)
68+import GHCJS.DOM.Node (appendChild_, getOwnerDocumentUnchecked, getParentNodeUnchecked, getPreviousSiblingUnchecked,
69+ removeChild_, setNodeValue, toNode)
70+import qualified GHCJS.DOM.Node as DOM (insertBefore_)
7171import GHCJS.DOM.Types
7272 (liftJSM, askJSM, runJSM, JSM, MonadJSM(..),
7373 FocusEvent, IsElement, IsEvent, IsNode, KeyboardEvent, Node,
@@ -75,6 +75,7 @@ import GHCJS.DOM.Types
7575import qualified GHCJS.DOM.Types as DOM
7676import GHCJS.DOM.UIEvent
7777import qualified GHCJS.DOM.Window as Window
78+import Language.Javascript.JSaddle (call, eval)
7879
7980import Debug.Trace hiding (traceEvent)
8081
@@ -125,64 +126,109 @@ askEvents = ImmediateDomBuilderT $ asks _immediateDomBuilderEnv_events
125126append :: (IsNode n, MonadJSM m) => n -> ImmediateDomBuilderT t m ()
126127append n = do
127128 p <- askParent
128− _ <- liftJSM $ appendChild p $ Just n
129+ liftJSM $ appendChild_ p $ Just n
129130 return ()
130131
131132{-# INLINABLE textNodeInternal #-}
132133textNodeInternal :: (MonadJSM m, ToDOMString contents) => contents -> ImmediateDomBuilderT t m DOM.Text
133134textNodeInternal t = do
134135 doc <- askDocument
135− Just n <- liftJSM $ createTextNode doc t
136+ n <- liftJSM $ createTextNodeUnchecked doc t
136137 append n
137138 return n
138139
139140-- | s and e must both be children of the same node and s must precede e
140141{-# INLINABLE deleteBetweenInclusive #-}
141142deleteBetweenInclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
142−deleteBetweenInclusive s e = do
143− mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
144− case mCurrentParent of
145− Nothing -> return () --TODO: Is this the right behavior?
146− Just currentParent -> do
147− deleteUpToGivenParent currentParent s e
148− _ <- removeChild currentParent $ Just e
149− return ()
143+deleteBetweenInclusive s e = liftJSM $ do
144+ f <- eval ("(function(s,e){ \
145+ p = e.parentNode; \
146+ if(p !== null) { \
147+ for(;;){ \
148+ x = e.previousSibling; \
149+ p.removeChild(x); \
150+ if(s===x) break; \
151+ } \
152+ p.removeChild(e); \
153+ }})" :: Text)
154+ void $ call f f (s, e)
155+
156+-- do
157+-- mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
158+-- case mCurrentParent of
159+-- Nothing -> return () --TODO: Is this the right behavior?
160+-- Just currentParent -> do
161+-- deleteUpToGivenParent currentParent s e
162+-- removeChild_ currentParent $ Just e
163+-- return ()
150164
151165-- | s and e must both be children of the same node and s must precede e
152166deleteBetweenExclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
153−deleteBetweenExclusive s e = do
154− mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
155− case mCurrentParent of
156− Nothing -> return () --TODO: Is this the right behavior?
157− Just currentParent -> do
158− let go = do
159− Just x <- getPreviousSibling e -- This can't be Nothing because we should hit 's' first
160− _ <- removeChild currentParent $ Just x
161− liftJSM (strictEqual s x) >>= \case
162− True -> return ()
163− False -> go
164− go
165− _ <- removeChild currentParent $ Just e
166− return ()
167+deleteBetweenExclusive s e = liftJSM $ do
168+ f <- eval ("(function(s,e){ \
169+ p = e.parentNode; \
170+ if(p !== null) { \
171+ for(;;){ \
172+ x = e.previousSibling; \
173+ p.removeChild(x); \
174+ if(s===x) break; \
175+ } \
176+ p.removeChild(e); \
177+ }})" :: Text)
178+ void $ call f f (s, e)
179+
180+-- do
181+-- mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
182+-- case mCurrentParent of
183+-- Nothing -> return () --TODO: Is this the right behavior?
184+-- Just currentParent -> do
185+-- let go = do
186+-- x <- getPreviousSiblingUnchecked e -- This can't be Nothing because we should hit 's' first
187+-- removeChild_ currentParent $ Just x
188+-- liftJSM (strictEqual s x) >>= \case
189+-- True -> return ()
190+-- False -> go
191+-- go
192+-- removeChild_ currentParent $ Just e
193+-- return ()
167194
168195-- | s and e must both be children of the same node and s must precede e; s and all nodes between s and e will be removed, but e will not be removed
169196{-# INLINABLE deleteUpTo #-}
170197deleteUpTo :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
171−deleteUpTo s e = do
172− mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
173− case mCurrentParent of
174− Nothing -> return () --TODO: Is this the right behavior?
175− Just currentParent -> deleteUpToGivenParent currentParent s e
198+deleteUpTo s e = liftJSM $ do
199+ f <- eval ("(function(s,e){ \
200+ p = e.parentNode; \
201+ if(p !== null) { \
202+ for(;;) { \
203+ x = e.previousSibling; \
204+ p.removeChild(x); \
205+ if(s===x) break; \
206+ } \
207+ }})" :: Text)
208+ void $ call f f (s, e)
209+-- do
210+-- mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
211+-- case mCurrentParent of
212+-- Nothing -> return () --TODO: Is this the right behavior?
213+-- Just currentParent -> deleteUpToGivenParent currentParent s e
176214
177215{-# INLINABLE deleteUpToGivenParent #-}
178216deleteUpToGivenParent :: (MonadJSM m, IsNode parent, IsNode start, IsNode end) => parent -> start -> end -> m ()
179−deleteUpToGivenParent currentParent s e = do
180− fix $ \loop -> do
181− Just x <- getPreviousSibling e -- This can't be Nothing because we should hit 's' first
182− _ <- removeChild currentParent $ Just x
183− liftJSM (strictEqual s x) >>= \case
184− True -> return ()
185− False -> loop
217+deleteUpToGivenParent currentParent s e = liftJSM $ do
218+ f <- eval ("(function(p,s,e){ \
219+ for(;;){ \
220+ x = e.previousSibling; \
221+ p.removeChild(x); \
222+ if(s===x) break; \
223+ }})" :: Text)
224+ void $ call f f (currentParent, s, e)
225+--do
226+-- fix $ \loop -> do
227+-- x <- getPreviousSiblingUnchecked e -- This can't be Nothing because we should hit 's' first
228+-- removeChild_ currentParent $ Just x
229+-- liftJSM (strictEqual s x) >>= \case
230+-- True -> return ()
231+-- False -> loop
186232
187233type SupportsImmediateDomBuilder t m = (Reflex t, MonadJSM m, MonadJSM (Performable m), MonadHold t m, MonadFix m, PerformEvent t m, MonadReflexCreateTrigger t m, MonadRef m, Ref m ~ Ref JSM, MonadAdjust t m)
188234
@@ -232,9 +278,9 @@ makeElement :: forall er t m a. SupportsImmediateDomBuilder t m => Text -> Eleme
232278makeElement elementTag cfg child = do
233279 doc <- askDocument
234280 events <- askEvents
235− Just e <- liftJSM $ case cfg ^. namespace of
236− Nothing -> createElement doc (Just elementTag)
237− Just ens -> createElementNS doc (Just ens) (Just elementTag)
281+ e <- liftJSM $ case cfg ^. namespace of
282+ Nothing -> createElementUnchecked doc (Just elementTag)
283+ Just ens -> createElementNSUnchecked doc (Just ens) (Just elementTag)
238284 ImmediateDomBuilderT $ iforM_ (cfg ^. initialAttributes) $ \(AttributeName mAttrNamespace n) v -> case mAttrNamespace of
239285 Nothing -> lift $ setAttribute e n v
240286 Just ans -> lift $ setAttributeNS e (Just ans) n v
@@ -305,7 +351,7 @@ instance er ~ EventResult => Default (GhcjsEventSpec er) where
305351 def = GhcjsEventSpec
306352 { _ghcjsEventSpec_filters = mempty
307353 , _ghcjsEventSpec_handler = \(en, GhcjsDomEvent evt) -> do
308− Just (t :: DOM.EventTarget) <- withIsEvent en $ Event.getTarget evt --TODO: Rework this; defaultDomEventHandler shouldn't need to take this as an argument
354+ t :: DOM.EventTarget <- withIsEvent en $ Event.getTargetUnchecked evt --TODO: Rework this; defaultDomEventHandler shouldn't need to take this as an argument
309355 let e = uncheckedCastTo DOM.Element t
310356 runReaderT (defaultDomEventHandler e en) evt
311357 }
@@ -335,7 +381,7 @@ instance SupportsImmediateDomBuilder t m => DomBuilder t (ImmediateDomBuilderT t
335381 ((e, _), domElement) <- makeElement "input" (cfg ^. inputElementConfig_elementConfig) $ return ()
336382 let domInputElement = uncheckedCastTo DOM.HTMLInputElement domElement
337383 Input.setValue domInputElement $ Just (cfg ^. inputElementConfig_initialValue)
338− Just v0 <- Input.getValue domInputElement
384+ v0 <- Input.getValueUnchecked domInputElement
339385 let getMyValue = fromMaybe "" <$> Input.getValue domInputElement
340386 valueChangedByUI <- performEvent $ getMyValue <$ Reflex.select (_element_events e) (WrapArg Input)
341387 valueChangedBySetValue <- performEvent $ ffor (cfg ^. inputElementConfig_setValue) $ \v' -> do
@@ -349,11 +395,12 @@ instance SupportsImmediateDomBuilder t m => DomBuilder t (ImmediateDomBuilderT t
349395 checkedChangedByUI <- wrapDomEvent domInputElement (`on` Element.click) $ do
350396 Input.getChecked domInputElement
351397 checkedChangedBySetChecked <- performEvent $ ffor (_inputElementConfig_setChecked cfg) $ \newChecked -> do
352− oldChecked <- Input.getChecked domInputElement
353− if newChecked /= oldChecked
354− then do Input.setChecked domInputElement newChecked
398+-- oldChecked <- Input.getChecked domInputElement
399+-- if newChecked /= oldChecked
400+-- then do
401+ Input.setChecked domInputElement newChecked
355402 return $ Just newChecked
356− else return Nothing
403+-- else return Nothing
357404 c <- holdDyn (_inputElementConfig_initialChecked cfg) $ leftmost
358405 [ fmapMaybe id checkedChangedBySetChecked
359406 , checkedChangedByUI
@@ -382,7 +429,7 @@ instance SupportsImmediateDomBuilder t m => DomBuilder t (ImmediateDomBuilderT t
382429 ((e, _), domElement) <- makeElement "textarea" (cfg ^. textAreaElementConfig_elementConfig) $ return ()
383430 let domTextAreaElement = uncheckedCastTo DOM.HTMLTextAreaElement domElement
384431 TextArea.setValue domTextAreaElement $ Just (cfg ^. textAreaElementConfig_initialValue)
385− Just v0 <- TextArea.getValue domTextAreaElement
432+ v0 <- TextArea.getValueUnchecked domTextAreaElement
386433 let getMyValue = fromMaybe "" <$> TextArea.getValue domTextAreaElement
387434 valueChangedByUI <- performEvent $ getMyValue <$ Reflex.select (_element_events e) (WrapArg Input)
388435 valueChangedBySetValue <- performEvent $ ffor (cfg ^. textAreaElementConfig_setValue) $ \v' -> do
@@ -432,13 +479,13 @@ instance (Reflex t, MonadAdjust t m, MonadJSM m, MonadHold t m, PerformEvent t m
432479 initialEnv <- ImmediateDomBuilderT ask
433480 before <- textNodeInternal ("" :: Text)
434481 -- We draw 'after' in this roundabout way to avoid using MonadFix
435− Just after <- createTextNode (_immediateDomBuilderEnv_document initialEnv) ("" :: Text)
482+ after <- createTextNodeUnchecked (_immediateDomBuilderEnv_document initialEnv) ("" :: Text)
436483 let drawInitialChild = do
437484 result <- a0
438485 append after
439486 return result
440487 (result0, result') <- lift $ runWithReplace (runImmediateDomBuilderT drawInitialChild initialEnv) $ ffor a' $ \child -> do
441− Just df <- createDocumentFragment $ _immediateDomBuilderEnv_document initialEnv
488+ df <- createDocumentFragmentUnchecked $ _immediateDomBuilderEnv_document initialEnv
442489 result <- runImmediateDomBuilderT child $ initialEnv
443490 { _immediateDomBuilderEnv_parent = toNode df
444491 }
@@ -452,7 +499,7 @@ instance (Reflex t, MonadAdjust t m, MonadJSM m, MonadHold t m, PerformEvent t m
452499 drawChildInitial child = runImmediateDomBuilderT ((,,) <$> pure (error "sequenceDMapWithAdjust{ImmediateDomBuilderT}: drawChildInitial: DocumentFragment evaluated") <*> textNodeInternal ("" :: Text) <*> child) initialEnv --TODO: Don't return a DocumentFragment at all here; this will require that sequenceDMapWithAdjust accept differently-typed values for the constant and Event arguments.
453500 drawChildUpdate :: ImmediateDomBuilderT t m a -> m (DOM.DocumentFragment, DOM.Text, a)
454501 drawChildUpdate child = do
455− Just df <- createDocumentFragment $ _immediateDomBuilderEnv_document initialEnv
502+ df <- createDocumentFragmentUnchecked $ _immediateDomBuilderEnv_document initialEnv
456503 runImmediateDomBuilderT ((,,) <$> pure df <*> textNodeInternal ("" :: Text) <*> child) $ initialEnv
457504 { _immediateDomBuilderEnv_parent = toNode df
458505 }
@@ -491,8 +538,8 @@ insertImmediateAbove :: (IsNode placeholder, PerformEvent t m, MonadJSM (Perform
491538insertImmediateAbove n toInsertAbove = do
492539 events <- askEvents
493540 lift $ performEvent $ ffor toInsertAbove $ \new -> do
494− Just doc <- getOwnerDocument n
495− Just df <- createDocumentFragment doc
541+ doc <- getOwnerDocumentUnchecked n
542+ df <- createDocumentFragmentUnchecked doc
496543 result <- runImmediateDomBuilderT new $ ImmediateDomBuilderEnv
497544 { _immediateDomBuilderEnv_parent = toNode df
498545 , _immediateDomBuilderEnv_document = doc
@@ -503,10 +550,8 @@ insertImmediateAbove n toInsertAbove = do
503550
504551insertBefore :: (MonadJSM m, IsNode new, IsNode existing) => new -> existing -> m ()
505552insertBefore new existing = do
506− mp <- getParentNode existing
507− case mp of
508− Nothing -> trace "ImmediateDomBuilderT: placeholder: Warning: (getParentNode n) returned Nothing" $ return ()
509− Just p -> void $ DOM.insertBefore p (Just new) (Just existing) -- If there's no parent, that means we've been removed from the DOM; this should not happen if the we're removing ourselves from the performEvent properly
553+ p <- getParentNodeUnchecked existing
554+ DOM.insertBefore_ p (Just new) (Just existing) -- If there's no parent, that means we've been removed from the DOM; this should not happen if the we're removing ourselves from the performEvent properly
510555
511556instance PerformEvent t m => PerformEvent t (ImmediateDomBuilderT t m) where
512557 type Performable (ImmediateDomBuilderT t m) = Performable m
src/Reflex/Dom/Internal.hs+19−19
@@ -49,8 +49,8 @@ import GHCJS.DOM.Types (MonadJSM(..), JSM)
4949{-# INLINABLE mainWidget #-}
5050mainWidget :: (forall x. Widget x ()) -> JSM ()
5151mainWidget w = withJSContextSingleton $ \jsSing -> do
52− Just doc <- currentDocument
53− Just body <- getBody doc
52+ doc <- currentDocumentUnchecked
53+ body <- getBodyUnchecked doc
5454 attachWidget body jsSing w
5555 forever $ do
5656 liftIO $ threadDelay 100000
@@ -60,10 +60,10 @@ mainWidget w = withJSContextSingleton $ \jsSing -> do
6060{-# INLINABLE mainWidgetWithHead #-}
6161mainWidgetWithHead :: (forall x. Widget x ()) -> (forall x. Widget x ()) -> JSM ()
6262mainWidgetWithHead h b = withJSContextSingleton $ \jsSing -> do
63− Just doc <- currentDocument
64− Just headElement <- getHead doc
63+ doc <- currentDocumentUnchecked
64+ headElement <- getHeadUnchecked doc
6565 attachWidget headElement jsSing h
66− Just body <- getBody doc
66+ body <- getBodyUnchecked doc
6767 attachWidget body jsSing b
6868 forever $ do
6969 liftIO $ threadDelay 100000
@@ -72,10 +72,10 @@ mainWidgetWithHead h b = withJSContextSingleton $ \jsSing -> do
7272{-# INLINABLE mainWidgetWithCss #-}
7373mainWidgetWithCss :: ByteString -> (forall x. Widget x ()) -> JSM ()
7474mainWidgetWithCss css w = withJSContextSingleton $ \jsSing -> do
75− Just doc <- currentDocument
76− Just headElement <- getHead doc
75+ doc <- currentDocumentUnchecked
76+ headElement <- getHeadUnchecked doc
7777 setInnerHTML headElement . Just $ "<style>" <> T.unpack (decodeUtf8 css) <> "</style>" --TODO: Fix this
78− Just body <- getBody doc
78+ body <- getBodyUnchecked doc
7979 attachWidget body jsSing w
8080 forever $ do
8181 liftIO $ threadDelay 100000
@@ -94,9 +94,9 @@ attachWidget rootElement wv w = liftIO $ fst <$> attachWidget' rootElement wv w
9494
9595mainWidgetWithHead' :: (forall x. (a -> Widget x b, b -> Widget x a)) -> JSM ()
9696mainWidgetWithHead' widgets = withJSContextSingleton $ \jsSing -> do
97− Just doc <- currentDocument
98− Just headElement <- getHead doc
99− Just bodyElement <- getBody doc
97+ doc <- currentDocumentUnchecked
98+ headElement <- getHeadUnchecked doc
99+ bodyElement <- getBodyUnchecked doc
100100-- runWebGUI $ \webView -> withWebViewSingleton webView $ \wv ->
101101 liftIO $ fmap fst $ attachWidget'' $ \events -> do
102102 let (headWidget, bodyWidget) = widgets
@@ -107,8 +107,8 @@ mainWidgetWithHead' widgets = withJSContextSingleton $ \jsSing -> do
107107
108108unsafeReplaceElementContentsWithWidget :: DOM.IsElement e => EventChannel -> R.Event Spider () -> e -> JSContextSingleton x -> Widget x a -> PerformEventT Spider (SpiderHost Global) a
109109unsafeReplaceElementContentsWithWidget events postBuild rootElement jsSing w = (`runWithJSContextSingleton` jsSing) $ do
110− Just doc <- getOwnerDocument rootElement
111− Just df <- createDocumentFragment doc
110+ doc <- getOwnerDocumentUnchecked rootElement
111+ df <- createDocumentFragmentUnchecked doc
112112 let builderEnv = ImmediateDomBuilderEnv
113113 { _immediateDomBuilderEnv_document = doc
114114 , _immediateDomBuilderEnv_parent = toNode df
@@ -116,7 +116,7 @@ unsafeReplaceElementContentsWithWidget events postBuild rootElement jsSing w = (
116116 }
117117 result <- runImmediateDomBuilderT (runPostBuildT w postBuild) builderEnv
118118 setInnerHTML rootElement $ Just ("" :: String)
119− _ <- appendChild rootElement $ Just df
119+ _ <- appendChildUnchecked rootElement $ Just df
120120 return result
121121
122122{-# INLINABLE attachWidget' #-}
@@ -151,8 +151,8 @@ attachWidget'' w = do
151151-- | Run a reflex-dom application inside of an existing DOM element with the given ID
152152mainWidgetInElementById :: Text -> (forall x. Widget x ()) -> JSM ()
153153mainWidgetInElementById eid w = withJSContextSingleton $ \jsSing -> do
154− Just doc <- currentDocument
155− Just root <- getElementById doc eid
154+ doc <- currentDocumentUnchecked
155+ root <- getElementByIdUnchecked doc eid
156156 attachWidget root jsSing w
157157 forever $ do
158158 liftIO $ threadDelay 100000
@@ -168,9 +168,9 @@ data AppOutput t = AppOutput --TODO: Add quit event
168168
169169runApp' :: (t ~ Spider) => (forall x. AppInput t -> Widget x (AppOutput t)) -> JSM ()
170170runApp' app = withJSContextSingleton $ \jsSing -> do
171− Just doc <- currentDocument
172− Just body <- getBody doc
173− Just win <- getDefaultView doc
171+ doc <- currentDocumentUnchecked
172+ body <- getBodyUnchecked doc
173+ win <- getDefaultViewUnchecked doc
174174 rec o <- attachWidget body jsSing $ do
175175 w <- lift $ wrapWindow win $ _appOutput_windowConfig o
176176 app $ AppInput
src/Reflex/Dom/Old.hs+3−3
@@ -69,7 +69,7 @@ import Foreign.JavaScript.TH
6969import qualified GHCJS.DOM.Element as Element
7070import GHCJS.DOM.EventM (EventM)
7171import GHCJS.DOM.NamedNodeMap as NNM
72−import GHCJS.DOM.Node (getFirstChild, getNodeName, getParentNode, getPreviousSibling, removeChild)
72+import GHCJS.DOM.Node (getFirstChild, getNodeName, getParentNode, getPreviousSibling, removeChildUnchecked)
7373import GHCJS.DOM.Types
7474 (MonadJSM, strictEqual, liftJSM, JSM, IsElement, IsNode)
7575import qualified GHCJS.DOM.Types as DOM
@@ -250,7 +250,7 @@ namedNodeMapGetNames self = do
250250 l <- NNM.getLength self
251251 let locations = if l == 0 then [] else [0..l-1] -- Can't use 0..l-1 if l is 0 because l is unsigned and will wrap around
252252 fmap (Set.fromList . catMaybes) $ forM locations $ \i -> do
253− Just n <- NNM.item self i
253+ n <- NNM.itemUnchecked self i
254254 getNodeName n
255255
256256nodeClear :: IsNode self => self -> JSM ()
@@ -259,7 +259,7 @@ nodeClear n = do
259259 case mfc of
260260 Nothing -> return ()
261261 Just fc -> do
262− _ <- removeChild n $ Just fc
262+ removeChildUnchecked n $ Just fc
263263 nodeClear n
264264
265265elStopPropagationNS :: forall t m en a. (MonadWidget t m) => Maybe Text -> Text -> EventName en -> m a -> m a
src/Reflex/Dom/Widget/Input.hs+6−6
@@ -38,7 +38,7 @@ import GHCJS.DOM.EventM (on)
3838import qualified GHCJS.DOM.FileList as FileList
3939import GHCJS.DOM.HTMLInputElement (HTMLInputElement)
4040import GHCJS.DOM.HTMLTextAreaElement (HTMLTextAreaElement)
41−import GHCJS.DOM.Types (MonadJSM, File, unsafeCastTo)
41+import GHCJS.DOM.Types (MonadJSM, File, uncheckedCastTo)
4242import qualified GHCJS.DOM.Types as DOM (Element(..), EventTarget(..))
4343import Reflex.Class
4444import Reflex.Dom.Builder.Class
@@ -287,8 +287,8 @@ checkboxView dAttrs dValue = do
287287 postBuild <- getPostBuild
288288 let filters :: DMap EventName (GhcjsEventFilter CheckboxViewEventResult)
289289 filters = DMap.singleton Click $ GhcjsEventFilter $ \(GhcjsDomEvent evt) -> do
290− Just t <- Event.getTarget evt
291− b <- Input.getChecked =<< unsafeCastTo Input.HTMLInputElement t
290+ t <- Event.getTargetUnchecked evt
291+ b <- Input.getChecked $ uncheckedCastTo Input.HTMLInputElement t
292292 return $ (,) preventDefault $ return $ Just $ CheckboxViewEventResult b
293293 elementConfig :: ElementConfig CheckboxViewEventResult t m
294294 elementConfig = (def :: ElementConfig EventResult t m)
@@ -299,8 +299,8 @@ checkboxView dAttrs dValue = do
299299 , _ghcjsEventSpec_handler = \(en, GhcjsDomEvent evt) -> case en of
300300 Click -> error "impossible"
301301 _ -> do
302− Just (e :: DOM.EventTarget) <- withIsEvent en $ Event.getTarget evt
303− element <- unsafeCastTo DOM.Element e
302+ e :: DOM.EventTarget <- withIsEvent en $ Event.getTargetUnchecked evt
303+ let element = uncheckedCastTo DOM.Element e
304304 mr <- runReaderT (defaultDomEventHandler element en) evt
305305 return $ ffor mr $ \(EventResult r) -> CheckboxViewEventResult $ regularToCheckboxViewEventType en r
306306 }
@@ -340,7 +340,7 @@ fileInput config = do
340340 eRaw <- inputElement cfg
341341 let e = _inputElement_raw eRaw
342342 eChange <- wrapDomEvent e (`on` Element.change) $ do
343− Just files <- Input.getFiles e
343+ files <- Input.getFilesUnchecked e
344344 len <- FileList.getLength files
345345 mapM (fmap (fromMaybe (error "fileInput: fileList.item returned null")) . FileList.item files) [0 .. len-1]
346346 dValue <- holdDyn [] eChange