@@ -1,3 +1,4 @@
1+{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE DataKinds #-}
@@ -31,7 +32,6 @@ import Reflex.TriggerEvent.Base hiding (askEvents)
31import Reflex.TriggerEvent.Class
32import Reflex.TriggerEvent.Class
33import Control.Concurrent.Chan
34import Control.Concurrent.Chan
34−import Control.Exception (evaluate)
35import Control.Lens hiding (element, ix)
35import Control.Lens hiding (element, ix)
36import Control.Monad.Exception
36import Control.Monad.Exception
37import Control.Monad.Primitive
37import Control.Monad.Primitive
@@ -55,6 +55,7 @@ import Data.Monoid
55import Data.Some (Some)
55import Data.Some (Some)
56import qualified Data.Some as Some
56import qualified Data.Some as Some
57import Data.Text (Text)
57import Data.Text (Text)
58+import qualified Data.Text as T
58import GHCJS.DOM.Document (Document, createDocumentFragmentUnchecked, createElementUnchecked, createElementNSUnchecked, createTextNodeUnchecked)
59import GHCJS.DOM.Document (Document, createDocumentFragmentUnchecked, createElementUnchecked, createElementNSUnchecked, createTextNodeUnchecked)
59import GHCJS.DOM.Element (getScrollTop, removeAttribute, removeAttributeNS, setAttribute, setAttributeNS)
60import GHCJS.DOM.Element (getScrollTop, removeAttribute, removeAttributeNS, setAttribute, setAttributeNS)
60import qualified GHCJS.DOM.Element as Element
61import qualified GHCJS.DOM.Element as Element
@@ -81,8 +82,6 @@ import GHCJS.DOM.UIEvent
81import qualified GHCJS.DOM.Window as Window
82import qualified GHCJS.DOM.Window as Window
82import Language.Javascript.JSaddle (call, eval)
83import Language.Javascript.JSaddle (call, eval)
84−import Debug.Trace hiding (traceEvent)
86data TriggerRef t a = TriggerRef { unTriggerRef :: IORef (Maybe (EventTrigger t a)) }
85data TriggerRef t a = TriggerRef { unTriggerRef :: IORef (Maybe (EventTrigger t a)) }
88data ImmediateDomBuilderEnv t
87data ImmediateDomBuilderEnv t
@@ -146,31 +145,36 @@ textNodeInternal t = do
146{-# INLINABLE deleteBetweenInclusive #-}
145{-# INLINABLE deleteBetweenInclusive #-}
147deleteBetweenInclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
146deleteBetweenInclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
148deleteBetweenInclusive s e = liftJSM $ do
147deleteBetweenInclusive s e = liftJSM $ do
148+ f <- eval $ T.unlines
149− f <- eval ("(function(s,e){ \
149+ [ "(function(s,e){"
150− p = e.parentNode; \
150+ , " p = e.parentNode;"
151− if(p !== null) { \
151+ , " if(p !== null) {"
152− for(;;){ \
152+ , " for(;;){"
153− x = e.previousSibling; \
153+ , " x = e.previousSibling;"
154− p.removeChild(x); \
154+ , " p.removeChild(x);"
155− if(s===x) break; \
155+ , " if(s===x) break;"
157− p.removeChild(e); \
157+ , " p.removeChild(e);"
158− }})" :: Text)
158+ , " }"
159 void $ call f f (s, e)
161 void $ call f f (s, e)
161-- | s and e must both be children of the same node and s must precede e;
163-- | s and e must both be children of the same node and s must precede e;
162-- all nodes between s and e will be removed, but s and e will not be removed
164-- all nodes between s and e will be removed, but s and e will not be removed
163deleteBetweenExclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
165deleteBetweenExclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
164deleteBetweenExclusive s e = liftJSM $ do
166deleteBetweenExclusive s e = liftJSM $ do
167+ f <- eval $ T.unlines
165− f <- eval ("(function(s,e){ \
168+ [ "(function(s,e){"
166− p = e.parentNode; \
169+ , " p = e.parentNode;"
167− if(p !== null) { \
170+ , " if(p !== null) {"
168− for(;;){ \
171+ , " for(;;){"
169− x = e.previousSibling; \
172+ , " x = e.previousSibling;"
170− if(s===x) break; \
173+ , " if(s===x) break;"
171− p.removeChild(x); \
174+ , " p.removeChild(x);"
173− }})" :: Text)
176+ , " }})"
174 void $ call f f (s, e)
178 void $ call f f (s, e)
176-- | s and e must both be children of the same node and s must precede e;
180-- | s and e must both be children of the same node and s must precede e;
@@ -178,27 +182,31 @@ deleteBetweenExclusive s e = liftJSM $ do
178{-# INLINABLE deleteUpTo #-}
182{-# INLINABLE deleteUpTo #-}
179deleteUpTo :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
183deleteUpTo :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
180deleteUpTo s e = liftJSM $ do
184deleteUpTo s e = liftJSM $ do
185+ f <- eval $ T.unlines
181− f <- eval ("(function(s,e){ \
186+ [ "(function(s,e){"
182− p = e.parentNode; \
187+ , " p = e.parentNode;"
183− if(p !== null) { \
188+ , " if(p !== null) {"
184− for(;;) { \
189+ , " for(;;) {"
185− x = e.previousSibling; \
190+ , " x = e.previousSibling;"
186− p.removeChild(x); \
191+ , " p.removeChild(x);"
187− if(s===x) break; \
192+ , " if(s===x) break;"
189− }})" :: Text)
194+ , " }})"
190 void $ call f f (s, e)
196 void $ call f f (s, e)
192-- | s and all nodes between s and e will be removed, but e will not be removed
198-- | s and all nodes between s and e will be removed, but e will not be removed
193{-# INLINABLE deleteUpToGivenParent #-}
199{-# INLINABLE deleteUpToGivenParent #-}
194deleteUpToGivenParent :: (MonadJSM m, IsNode parent, IsNode start, IsNode end) => parent -> start -> end -> m ()
200deleteUpToGivenParent :: (MonadJSM m, IsNode parent, IsNode start, IsNode end) => parent -> start -> end -> m ()
195deleteUpToGivenParent currentParent s e = liftJSM $ do
201deleteUpToGivenParent currentParent s e = liftJSM $ do
202+ f <- eval $ T.unlines
196− f <- eval ("(function(p,s,e){ \
203+ [ "(function(p,s,e){"
197− for(;;){ \
204+ , " for(;;){"
198− x = e.previousSibling; \
205+ , " x = e.previousSibling;"
199− p.removeChild(x); \
206+ , " p.removeChild(x);"
200− if(s===x) break; \
207+ , " if(s===x) break;"
201− }})" :: Text)
208+ , " }})"
202 void $ call f f (currentParent, s, e)
210 void $ call f f (currentParent, s, e)
204type 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)
212type 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)
@@ -225,9 +233,8 @@ wrap e cfg = do
225 liftIO $ forM_ mv $ \v -> writeChan events [TriggerRef triggerRef :=> TriggerInvocation v (return ())]
233 liftIO $ forM_ mv $ \v -> writeChan events [TriggerRef triggerRef :=> TriggerInvocation v (return ())]
226 return $ en :=> EventFilterTriggerRef triggerRef
234 return $ en :=> EventFilterTriggerRef triggerRef
228− let h :: forall en. (EventName en, GhcjsDomEvent en) -> JSM (Maybe (er en))
236+ let h :: GhcjsEventHandler er
229− h = _ghcjsEventSpec_handler $ _rawElementConfig_eventSpec cfg -- Note: this needs to be done strictly and outside of the newFanEventWithTrigger, so that the newFanEventWithTrigger doesn't retain the entire cfg, which can cause a cyclic dependency that the GC won't be able to clean up
237+ !h = _ghcjsEventSpec_handler $ _rawElementConfig_eventSpec cfg -- Note: this needs to be done strictly and outside of the newFanEventWithTrigger, so that the newFanEventWithTrigger doesn't retain the entire cfg, which can cause a cyclic dependency that the GC won't be able to clean up
230− _ <- liftIO $ evaluate h
231 ctx <- askJSM
238 ctx <- askJSM
232 newFanEventWithTrigger $ \(WrapArg en) t ->
239 newFanEventWithTrigger $ \(WrapArg en) t ->
233 case DMap.lookup en eventTriggerRefs of
240 case DMap.lookup en eventTriggerRefs of
@@ -237,7 +244,7 @@ wrap e cfg = do
237 writeIORef r Nothing
244 writeIORef r Nothing
238 Nothing -> (`runJSM` ctx) <$> (`runJSM` ctx) (elementOnEventName en e $ do
245 Nothing -> (`runJSM` ctx) <$> (`runJSM` ctx) (elementOnEventName en e $ do
239 evt <- DOM.event
246 evt <- DOM.event
240− mv <- lift $ h (en, GhcjsDomEvent evt)
247+ mv <- lift $ unGhcjsEventHandler h (en, GhcjsDomEvent evt)
241 case mv of
248 case mv of
242 Nothing -> return ()
249 Nothing -> return ()
243 Just v -> liftIO $ do
250 Just v -> liftIO $ do
@@ -286,7 +293,7 @@ instance DomSpace GhcjsDomSpace where
286 { _ghcjsEventSpec_filters =
293 { _ghcjsEventSpec_filters =
287 let f' = Just . GhcjsEventFilter . \case
294 let f' = Just . GhcjsEventFilter . \case
288 Nothing -> \evt -> do
295 Nothing -> \evt -> do
289− mEventResult <- _ghcjsEventSpec_handler es (en, evt)
296+ mEventResult <- unGhcjsEventHandler (_ghcjsEventSpec_handler es) (en, evt)
290 return (f mEventResult, return mEventResult)
297 return (f mEventResult, return mEventResult)
291 Just (GhcjsEventFilter oldFilter) -> \evt -> do
298 Just (GhcjsEventFilter oldFilter) -> \evt -> do
292 (oldFlags, oldContinuation) <- oldFilter evt
299 (oldFlags, oldContinuation) <- oldFilter evt
@@ -304,9 +311,11 @@ data Maybe1 f a = Nothing1 | Just1 (f a)
305data GhcjsEventSpec er = GhcjsEventSpec
312data GhcjsEventSpec er = GhcjsEventSpec
306 { _ghcjsEventSpec_filters :: DMap EventName (GhcjsEventFilter er)
313 { _ghcjsEventSpec_filters :: DMap EventName (GhcjsEventFilter er)
307− , _ghcjsEventSpec_handler :: forall en. (EventName en, GhcjsDomEvent en) -> JSM (Maybe (er en))
314+ , _ghcjsEventSpec_handler :: GhcjsEventHandler er
317+newtype GhcjsEventHandler er = GhcjsEventHandler { unGhcjsEventHandler :: forall en. (EventName en, GhcjsDomEvent en) -> JSM (Maybe (er en)) }
310#ifndef USE_TEMPLATE_HASKELL
319#ifndef USE_TEMPLATE_HASKELL
311phantom2 :: (Functor f, Contravariant f) => f a -> f b
320phantom2 :: (Functor f, Contravariant f) => f a -> f b
312phantom2 = phantom
321phantom2 = phantom
@@ -316,14 +325,14 @@ ghcjsEventSpec_filters :: forall er . Lens' (GhcjsEventSpec er) (DMap EventName
316ghcjsEventSpec_filters f (GhcjsEventSpec a b) = (\a' -> GhcjsEventSpec a' b) <$> f a
325ghcjsEventSpec_filters f (GhcjsEventSpec a b) = (\a' -> GhcjsEventSpec a' b) <$> f a
317{-# INLINE ghcjsEventSpec_filters #-}
326{-# INLINE ghcjsEventSpec_filters #-}
318ghcjsEventSpec_handler :: forall er en . Getter (GhcjsEventSpec er) ((EventName en, GhcjsDomEvent en) -> JSM (Maybe (er en)))
327ghcjsEventSpec_handler :: forall er en . Getter (GhcjsEventSpec er) ((EventName en, GhcjsDomEvent en) -> JSM (Maybe (er en)))
319−ghcjsEventSpec_handler f (GhcjsEventSpec _ b) = phantom2 (f b)
328+ghcjsEventSpec_handler f (GhcjsEventSpec _ (GhcjsEventHandler b)) = phantom2 (f b)
320{-# INLINE ghcjsEventSpec_handler #-}
329{-# INLINE ghcjsEventSpec_handler #-}
323instance er ~ EventResult => Default (GhcjsEventSpec er) where
332instance er ~ EventResult => Default (GhcjsEventSpec er) where
324 def = GhcjsEventSpec
333 def = GhcjsEventSpec
325 { _ghcjsEventSpec_filters = mempty
334 { _ghcjsEventSpec_filters = mempty
326− , _ghcjsEventSpec_handler = \(en, GhcjsDomEvent evt) -> do
335+ , _ghcjsEventSpec_handler = GhcjsEventHandler $ \(en, GhcjsDomEvent evt) -> do
327 t :: DOM.EventTarget <- withIsEvent en $ Event.getTargetUnchecked evt --TODO: Rework this; defaultDomEventHandler shouldn't need to take this as an argument
336 t :: DOM.EventTarget <- withIsEvent en $ Event.getTargetUnchecked evt --TODO: Rework this; defaultDomEventHandler shouldn't need to take this as an argument
328 let e = uncheckedCastTo DOM.Element t
337 let e = uncheckedCastTo DOM.Element t
329 runReaderT (defaultDomEventHandler e en) evt
338 runReaderT (defaultDomEventHandler e en) evt