on develop help sign in
Merge remote-tracking branch 'origin/prerender' into develop
8826615Ryan Trinkle
reflex-dom-core/default.nix+3−3
@@ -1,5 +1,5 @@
1{ mkDerivation, ghc, aeson, base, bifunctors, bimap, blaze-builder
1{ mkDerivation, ghc, aeson, base, bifunctors, bimap, blaze-builder
2−, bytestring, containers, contravariant, data-default
2+, bytestring, constraints, containers, contravariant, data-default
3, dependent-map, dependent-sum, dependent-sum-template, directory
3, dependent-map, dependent-sum, dependent-sum-template, directory
4, exception-transformers, ghcjs-dom, hlint, jsaddle, keycode, lens
4, exception-transformers, ghcjs-dom, hlint, jsaddle, keycode, lens
5, monad-control, mtl, primitive, random, ref-tf, reflex, semigroups
5, monad-control, mtl, primitive, random, ref-tf, reflex, semigroups
@@ -16,8 +16,8 @@ in mkDerivation (addGcTestDepends {
16 version = "0.4";
16 version = "0.4";
17 src = ./.;
17 src = ./.;
18 libraryHaskellDepends = [
18 libraryHaskellDepends = [
19− aeson base bifunctors bimap blaze-builder bytestring containers
19+ aeson base bifunctors bimap blaze-builder bytestring constraints
20− contravariant data-default dependent-map dependent-sum
20+ containers contravariant data-default dependent-map dependent-sum
21 dependent-sum-template directory exception-transformers ghcjs-dom
21 dependent-sum-template directory exception-transformers ghcjs-dom
22 jsaddle keycode lens monad-control mtl primitive random ref-tf
22 jsaddle keycode lens monad-control mtl primitive random ref-tf
23 reflex semigroups stm template-haskell text these time transformers
23 reflex semigroups stm template-haskell text these time transformers
reflex-dom-core/reflex-dom-core.cabal+2
@@ -43,6 +43,7 @@ library
43 blaze-builder,
43 blaze-builder,
44 bytestring == 0.10.*,
44 bytestring == 0.10.*,
45 containers == 0.5.*,
45 containers == 0.5.*,
46+ constraints == 0.9.*,
46 contravariant >= 1.4 && < 1.5,
47 contravariant >= 1.4 && < 1.5,
47 data-default >= 0.5 && < 0.8,
48 data-default >= 0.5 && < 0.8,
48 dependent-map == 0.2.*,
49 dependent-map == 0.2.*,
@@ -94,6 +95,7 @@ library
94 Reflex.Dom.Location
95 Reflex.Dom.Location
95 Reflex.Dom.Main
96 Reflex.Dom.Main
96 Reflex.Dom.Old
97 Reflex.Dom.Old
98+ Reflex.Dom.Prerender
97 Reflex.Dom.Time
99 Reflex.Dom.Time
98 Reflex.Dom.WebSocket
100 Reflex.Dom.WebSocket
99 Reflex.Dom.Widget
101 Reflex.Dom.Widget
reflex-dom-core/src/Foreign/JavaScript/Orphans.hs+12−6
@@ -16,13 +16,19 @@ import Reflex.Requester.Base (RequesterT)
16import Reflex.TriggerEvent.Base
16import Reflex.TriggerEvent.Base
17import Reflex.Query.Base (QueryT)
17import Reflex.Query.Base (QueryT)
18
18
19−instance (MonadJSM m, ReflexHost t) => MonadJSM (PostBuildT t m)
19+instance (MonadJSM m, ReflexHost t) => MonadJSM (PostBuildT t m) where
20+ liftJSM' = lift . liftJSM'
20instance (MonadJSM (HostFrame t), ReflexHost t) => MonadJSM (PerformEventT t m) where
21instance (MonadJSM (HostFrame t), ReflexHost t) => MonadJSM (PerformEventT t m) where
21 liftJSM' = PerformEventT . lift . liftJSM'
22 liftJSM' = PerformEventT . lift . liftJSM'
22−instance MonadJSM m => MonadJSM (DynamicWriterT t w m)
23+instance MonadJSM m => MonadJSM (DynamicWriterT t w m) where
24+ liftJSM' = lift . liftJSM'
23−instance MonadJSM m => MonadJSM (EventWriterT t w m)
25+instance MonadJSM m => MonadJSM (EventWriterT t w m) where
26+ liftJSM' = lift . liftJSM'
24−instance MonadJSM m => MonadJSM (RequesterT t request response m)
27+instance MonadJSM m => MonadJSM (RequesterT t request response m) where
28+ liftJSM' = lift . liftJSM'
25−instance MonadJSM m => MonadJSM (TriggerEventT t m)
29+instance MonadJSM m => MonadJSM (TriggerEventT t m) where
30+ liftJSM' = lift . liftJSM'
26−instance MonadJSM m => MonadJSM (QueryT t q m)
31+instance MonadJSM m => MonadJSM (QueryT t q m) where
32+ liftJSM' = lift . liftJSM'
27
33
28#endif
34#endif
reflex-dom-core/src/Reflex/Dom/Builder/Class.hs+3
@@ -7,6 +7,9 @@
7{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE FunctionalDependencies #-}
8{-# LANGUAGE FunctionalDependencies #-}
9{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10+#if !MIN_VERSION_base(4,9,0)
11+{-# LANGUAGE ImpredicativeTypes #-}
12+#endif
10{-# LANGUAGE LambdaCase #-}
13{-# LANGUAGE LambdaCase #-}
11{-# LANGUAGE MultiParamTypeClasses #-}
14{-# LANGUAGE MultiParamTypeClasses #-}
12{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
reflex-dom-core/src/Reflex/Dom/Builder/Immediate.hs+4
@@ -760,7 +760,11 @@ instance (Reflex t, MonadAdjust t m, MonadJSM m, MonadHold t m, MonadFix m, Prim
760 mapM_ (\(k :=> v) -> void $ placeFragment k v) $ DMap.toDescList p -- We need to go in reverse order here, to make sure the placeholders are in the right spot at the right time
760 mapM_ (\(k :=> v) -> void $ placeFragment k v) $ DMap.toDescList p -- We need to go in reverse order here, to make sure the placeholders are in the right spot at the right time
761 liftIO $ writeIORef placeholders $! phsAfter
761 liftIO $ writeIORef placeholders $! phsAfter
762
762
763+#if MIN_VERSION_base(4,9,0)
763data ChildReadyState k
764data ChildReadyState k
765+#else
766+data ChildReadyState (k :: * -> *)
767+#endif
764 = ChildReadyState_Ready
768 = ChildReadyState_Ready
765 | ChildReadyState_Unready !(Maybe (Some k))
769 | ChildReadyState_Unready !(Maybe (Some k))
766 deriving (Show, Read, Eq, Ord)
770 deriving (Show, Read, Eq, Ord)
reflex-dom-core/src/Reflex/Dom/Builder/InputDisabled.hs+9
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1{-# LANGUAGE FlexibleInstances #-}
2{-# LANGUAGE FlexibleInstances #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
@@ -15,6 +16,9 @@ import Control.Monad.Trans.Control
15import Data.Coerce
16import Data.Coerce
16import qualified Data.Map as Map
17import qualified Data.Map as Map
17import Foreign.JavaScript.TH
18import Foreign.JavaScript.TH
19+#ifndef ghcjs_HOST_OS
20+import GHCJS.DOM.Types (MonadJSM (..))
21+#endif
18import Reflex
22import Reflex
19import Reflex.Dom.Builder.Class
23import Reflex.Dom.Builder.Class
20import Reflex.Dom.Builder.Immediate (HasDocument (..))
24import Reflex.Dom.Builder.Immediate (HasDocument (..))
@@ -26,6 +30,11 @@ import Reflex.Host.Class
26-- "select" as their tag will NOT be disabled.
30-- "select" as their tag will NOT be disabled.
27newtype InputDisabledT m a = InputDisabledT { runInputDisabledT :: m a } deriving (Functor, Applicative, Monad, MonadAtomicRef, MonadFix, MonadIO)
31newtype InputDisabledT m a = InputDisabledT { runInputDisabledT :: m a } deriving (Functor, Applicative, Monad, MonadAtomicRef, MonadFix, MonadIO)
28
32
33+#ifndef ghcjs_HOST_OS
34+instance MonadJSM m => MonadJSM (InputDisabledT m) where
35+ liftJSM' = InputDisabledT . liftJSM'
36+#endif
37+
29deriving instance MonadSample t m => MonadSample t (InputDisabledT m)
38deriving instance MonadSample t m => MonadSample t (InputDisabledT m)
30deriving instance MonadHold t m => MonadHold t (InputDisabledT m)
39deriving instance MonadHold t m => MonadHold t (InputDisabledT m)
31
40
reflex-dom-core/src/Reflex/Dom/Core.hs+1
@@ -9,6 +9,7 @@ import Reflex.Dom.Class as X
9import Reflex.Dom.Location as X
9import Reflex.Dom.Location as X
10import Reflex.Dom.Main as X
10import Reflex.Dom.Main as X
11import Reflex.Dom.Old as X
11import Reflex.Dom.Old as X
12+import Reflex.Dom.Prerender as X
12import Reflex.Dom.Time as X
13import Reflex.Dom.Time as X
13import Reflex.Dom.WebSocket as X
14import Reflex.Dom.WebSocket as X
14import Reflex.Dom.Widget as X
15import Reflex.Dom.Widget as X
reflex-dom-core/src/Reflex/Dom/Prerender.hsnew file+82
@@ -0,0 +1,82 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+{-# LANGUAGE EmptyDataDecls #-}
3+{-# LANGUAGE FlexibleContexts #-}
4+{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FunctionalDependencies #-}
6+{-# LANGUAGE MultiParamTypeClasses #-}
7+{-# LANGUAGE Rank2Types #-}
8+{-# LANGUAGE ScopedTypeVariables #-}
9+{-# LANGUAGE TypeFamilies #-}
10+{-# LANGUAGE TypeSynonymInstances #-}
11+{-# LANGUAGE UndecidableInstances #-}
12+module Reflex.Dom.Prerender
13+ ( Prerender (..)
14+ , prerender
15+ ) where
16+
17+import Control.Monad.Reader
18+import Data.Constraint
19+import Foreign.JavaScript.TH
20+import GHCJS.DOM.Types (MonadJSM)
21+import Reflex
22+import Reflex.Dom.Builder.InputDisabled
23+import Reflex.Dom.Builder.Immediate
24+import Reflex.Dom.Builder.Static
25+import Reflex.Host.Class
26+
27+type PrerenderClientConstraint js m =
28+ ( HasJS js m
29+ , HasJS js (Performable m)
30+ , MonadJSM m
31+ , MonadJSM (Performable m)
32+ , HasJSContext m
33+ , HasJSContext (Performable m)
34+ , MonadFix m
35+ , MonadFix (Performable m)
36+ )
37+
38+class Prerender js m | m -> js where
39+ prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m))
40+
41+-- | Draw one widget when prerendering (e.g. server-side) and another when the
42+-- widget is fully instantiated. In a given execution of this function, there
43+-- will be exactly one invocation of exactly one of the arguments.
44+prerender :: forall js m a. Prerender js m => m a -> (PrerenderClientConstraint js m => m a) -> m a
45+prerender server client = case prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)) of
46+ Nothing -> server
47+ Just Dict -> client
48+
49+instance ( HasJS js m
50+ , HasJS js (Performable m)
51+ , HasJSContext m
52+ , HasJSContext (Performable m)
53+ , MonadJSM m
54+ , MonadJSM (Performable m)
55+ , MonadFix m
56+ , MonadFix (Performable m)
57+ , ReflexHost t
58+ ) => Prerender js (ImmediateDomBuilderT t m) where
59+ prerenderClientDict = Just Dict
60+
61+data NoJavaScript -- This type should never have a HasJS instance
62+
63+instance js ~ NoJavaScript => Prerender js (StaticDomBuilderT t m) where
64+ prerenderClientDict = Nothing
65+
66+instance (Prerender js m, ReflexHost t) => Prerender js (PostBuildT t m) where
67+ prerenderClientDict = fmap (\Dict -> Dict) (prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)))
68+
69+instance Prerender js m => Prerender js (DynamicWriterT t w m) where
70+ prerenderClientDict = fmap (\Dict -> Dict) (prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)))
71+
72+instance Prerender js m => Prerender js (ReaderT w m) where
73+ prerenderClientDict = fmap (\Dict -> Dict) (prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)))
74+
75+instance Prerender js m => Prerender js (RequesterT t request response m) where
76+ prerenderClientDict = fmap (\Dict -> Dict) (prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)))
77+
78+instance Prerender js m => Prerender js (QueryT t q m) where
79+ prerenderClientDict = fmap (\Dict -> Dict) (prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)))
80+
81+instance Prerender js m => Prerender js (InputDisabledT m) where
82+ prerenderClientDict = fmap (\Dict -> Dict) (prerenderClientDict :: Maybe (Dict (PrerenderClientConstraint js m)))