packages feed

react-flux 0.9.3 → 0.9.4

raw patch · 12 files changed

+186/−134 lines, 12 files

Files

ChangeLog.md view
@@ -1,3 +1,11 @@+# 0.9.4++* Fix to build with latest ghcjs-base (requires at least aaa4d59117f37d1b9c60a154a9128b3bcc6301cd)+  of ghcjs-base), so you may need to recompile ghcjs and ghcjs-base.+* Add a function 'property' to create a property from any JSRef, not just Aeson values.+* Add a function 'elementProperty' to create a property from a ReactElementM, useful for+  interacting with foreign React classes.+ # 0.9.3  * Don't require web-routes dependency if not building the routing example
example/routing/Router.hs view
@@ -37,7 +37,7 @@  foreign import javascript unsafe   "window.onhashchange = function() {$1(location.hash.toString());}"-  js_attachtLocationHashCb :: (Callback (JSRef JSString -> IO ())) -> IO ()+  js_attachtLocationHashCb :: (Callback (JSRef -> IO ())) -> IO ()  foreign import javascript unsafe   "window.location.hash = $1"
react-flux.cabal view
@@ -1,5 +1,5 @@ name:                react-flux-version:             0.9.3+version:             0.9.4 synopsis:            A binding to React based on the Flux application architecture for GHCJS category:            Web homepage:            https://bitbucket.org/wuzzeb/react-flux
src/React/Flux/Addons/Bootstrap.hs view
@@ -15,8 +15,8 @@ -- | A bootstrap <http://react-bootstrap.github.io/components.html component>.  For example, -- -- >bootstrap_ "Alert" [ "bsStyle" $= "danger"---                     , callback "onDismiss" (const $ dispatch CloseAlert)---                     ] $+-- >                   , callback "onDismiss" (const $ dispatch CloseAlert)+-- >                   ] $ -- >    p_ "Hello, World!" bootstrap_ :: String            -- ^ The component name.   Uses @window['ReactBootstrap'][name]@ to find the class, so@@ -33,7 +33,7 @@  foreign import javascript unsafe     "window['ReactBootstrap'][$1]"-    js_ReactBootstrap :: JSString -> JSRef ()+    js_ReactBootstrap :: JSString -> JSRef  #else 
src/React/Flux/Addons/React.hs view
@@ -57,7 +57,7 @@  foreign import javascript unsafe     "React['addons']['CSSTransitionGroup']"-    js_CSSTransitionGroup :: JSRef ()+    js_CSSTransitionGroup :: JSRef  #else cssTransitionGroup _ x = x
src/React/Flux/Export.hs view
@@ -1,5 +1,5 @@--- | Replace this with Export from improved-base branch of ghcjs-base once--- the improved-base branch becomes the default+-- | At some point this should be replaced by GHCJS.Foreign.Export, but GHCJS.Foreign.Export+-- currently causes a bug in the Todo example application to appear. module React.Flux.Export where  #ifdef __GHCJS__@@ -9,7 +9,7 @@  import GHCJS.Types -newtype Export a = Export (JSRef ())+newtype Export a = Export JSRef  foreign import javascript unsafe     "hsreact$export($1)"
src/React/Flux/Internal.hs view
@@ -8,6 +8,7 @@   , ReactElementRef(..)   , HandlerArg(..)   , PropertyOrHandler(..)+  , property   , ReactElement(..)   , ReactElementM(..)   , elemText@@ -21,36 +22,42 @@  import           Data.String (IsString(..)) import           Data.Aeson-import           Data.Aeson.Types (Pair) import           Data.Typeable (Typeable) import           Control.Monad.Writer import           Control.Monad.Identity (Identity(..))  #ifdef __GHCJS__-import qualified Data.Text as T import           Unsafe.Coerce import qualified Data.JSString as JSS import qualified JavaScript.Array as JSA import           GHCJS.Foreign.Callback import qualified JavaScript.Object as JSO-import           GHCJS.Types (JSRef, castRef, JSString)-import           GHCJS.Marshal (toJSRef_aeson, ToJSRef(..), fromJSRef)+import           GHCJS.Types (JSRef, JSString, IsJSRef, jsref)+import           GHCJS.Marshal (ToJSRef(..), fromJSRef) import           React.Flux.Export #else+import Data.Text (Text) type Callback a = ()-type JSRef a = ()+type JSRef = ()+class ToJSRef a+instance ToJSRef Value+instance ToJSRef Text+class IsJSRef a #endif  -- type JSObject a = JSO.Object a  -- | This type is for the return value of @React.createClass@-newtype ReactViewRef props = ReactViewRef { reactViewRef :: JSRef () }+newtype ReactViewRef props = ReactViewRef { reactViewRef :: JSRef }+instance IsJSRef (ReactViewRef props)  -- | This type is for the return value of @React.createElement@-newtype ReactElementRef = ReactElementRef { reactElementRef :: JSRef () }+newtype ReactElementRef = ReactElementRef { reactElementRef :: JSRef }+instance IsJSRef ReactElementRef  -- | The first parameter of an event handler registered with React.-newtype HandlerArg = HandlerArg (JSRef ())+newtype HandlerArg = HandlerArg JSRef+instance IsJSRef HandlerArg  instance Show HandlerArg where     show _ = "HandlerArg"@@ -60,7 +67,14 @@ -- The combination of all properties and event handlers are used to create the javascript object -- passed as the second argument to @React.createElement@. data PropertyOrHandler handler =-   Property Pair+   forall ref. ToJSRef ref => Property+      { propertyName :: String+      , propertyVal :: ref+      }+ | ElementProperty+      { elementPropertyName :: String+      , elementValue :: ReactElementM handler ()+      }  | EventHandler       { evtHandlerName :: String       , evtHandler :: HandlerArg -> handler@@ -71,20 +85,26 @@       }  instance Functor PropertyOrHandler where-    fmap _ (Property p) = Property p+    fmap _ (Property name val) = Property name val+    fmap f (ElementProperty name (ReactElementM mkElem)) =+        ElementProperty name $ ReactElementM $ mapWriter (\((),e) -> ((), fmap f e)) mkElem     fmap f (EventHandler name h) = EventHandler name (f . h)     fmap f (CallbackProperty name g) = CallbackProperty name (f . g) +-- | Create a property from anything that can be converted to a JSRef+property :: ToJSRef val => String -> val -> PropertyOrHandler handler+property = Property+ -- | Keys in React can either be strings or integers class ReactViewKey key where-    toKeyRef :: key -> IO (JSRef ())+    toKeyRef :: key -> IO JSRef  #if __GHCJS__ instance ReactViewKey String where     toKeyRef = return . unsafeCoerce . toJSString  instance ReactViewKey Int where-    toKeyRef i = castRef <$> toJSRef i+    toKeyRef i = toJSRef i #else instance ReactViewKey String where     toKeyRef = const $ return ()@@ -202,27 +222,81 @@ -- | Execute a ReactElementM to create a javascript React element and a list of callbacks attached -- to nodes within the element.  These callbacks will need to be released with 'releaseCallback' -- once the class is re-rendered.-mkReactElement :: (eventHandler -> IO ())+mkReactElement :: forall eventHandler.+                  (eventHandler -> IO ())                -> IO [ReactElementRef] -- ^ this.props.children                -> ReactElementM eventHandler ()-               -> IO (ReactElementRef, [Callback (JSRef () -> IO ())])+               -> IO (ReactElementRef, [Callback (JSRef -> IO ())])  #ifdef __GHCJS__ -mkReactElement runHandler getPropsChildren eM = runWriterT $ do-    let e = execWriter $ runReactElementM eM-        e' = case e of-                Content txt -> ForeignElement (Left "span") [] (Content txt)-                _ -> e-    refs <- createElement getPropsChildren $ fmap runHandler e'-    case refs of-        [] -> lift $ js_ReactCreateElementNoChildren "div"-        [x] -> return x-        xs -> lift $ do-            emptyObj <- JSO.create-            let arr = JSA.fromList $ map reactElementRef xs-            js_ReactCreateElementName "div" emptyObj arr+mkReactElement runHandler getPropsChildren = runWriterT . mToElem+    where+        -- Run the ReactElementM monad to create a ReactElementRef.+        mToElem :: ReactElementM eventHandler () -> MkReactElementM ReactElementRef+        mToElem eM = do+            let e = execWriter $ runReactElementM eM+                e' = case e of+                        Content txt -> ForeignElement (Left "span") [] (Content txt)+                        _ -> e+            refs <- createElement e'+            case refs of+                [] -> lift $ js_ReactCreateElementNoChildren "div"+                [x] -> return x+                xs -> lift $ do+                    emptyObj <- JSO.create+                    let arr = JSA.fromList $ map reactElementRef xs+                    js_ReactCreateElementName "div" emptyObj arr +        -- add the property or handler to the javascript object+        addPropOrHandlerToObj :: JSO.Object -> PropertyOrHandler eventHandler -> MkReactElementM ()+        addPropOrHandlerToObj obj (Property n val) = lift $ do+            vRef <- toJSRef val+            JSO.setProp (toJSString n) vRef obj+        addPropOrHandlerToObj obj (ElementProperty name rM) = do+            ReactElementRef ref <- mToElem rM+            lift $ JSO.setProp (toJSString name) ref obj+        addPropOrHandlerToObj obj (EventHandler str handler) = do+            -- this will be released by the render function of the class (jsbits/class.js)+            cb <- lift $ syncCallback1 ContinueAsync $ \evtRef ->+                runHandler $ handler $ HandlerArg evtRef+            tell [cb]+            lift $ JSO.setProp (toJSString str) (jsref cb) obj+        addPropOrHandlerToObj obj (CallbackProperty str handler) = do+            cb <- lift $ syncCallback1 ContinueAsync $ \argref -> do+                v <- fromJSRef argref+                runHandler $ handler $ maybe (error "Unable to decode callback value") id v+            tell [cb]+            lift $ JSO.setProp (toJSString str) (jsref cb) obj++        -- call React.createElement+        createElement :: ReactElement eventHandler -> MkReactElementM [ReactElementRef]+        createElement EmptyElement = return []+        createElement (Append x y) = (++) <$> createElement x <*> createElement y+        createElement (Content s) = return [js_ReactCreateContent s]+        createElement ChildrenPassedToView = lift getPropsChildren+        createElement (f@(ForeignElement{})) = do+            obj <- lift $ JSO.create+            mapM_ (addPropOrHandlerToObj obj) $ fProps f+            childNodes <- createElement $ fChild f+            let childArr = JSA.fromList $ map reactElementRef childNodes+            e <- lift $ case fName f of+                Left s -> js_ReactCreateElementName (toJSString s) obj childArr+                Right ref -> js_ReactCreateForeignElement ref obj childArr+            return [e]+        createElement (ViewElement { ceClass = rc, ceProps = props, ceKey = mkey, ceChild = child }) = do+            childNodes <- createElement child+            propsE <- lift $ export props -- this will be released inside the lifetime events for the class (jsbits/class.js)+            let arr = JSA.fromList $ map reactElementRef childNodes+            e <- lift $ case mkey of+                Just key -> do+                    keyRef <- toKeyRef key+                    js_ReactCreateKeyedElement rc keyRef propsE arr+                Nothing -> js_ReactCreateClass rc propsE arr+            return [e]++type MkReactElementM a = WriterT [Callback (JSRef -> IO ())] IO a+ foreign import javascript unsafe     "React['createElement']($1)"     js_ReactCreateElementNoChildren :: JSString -> IO ReactElementRef@@ -241,62 +315,18 @@  foreign import javascript unsafe     "React['createElement']($1, {key: $2, hs:$3}, $4)"-    js_ReactCreateKeyedElement :: ReactViewRef a -> JSRef key -> Export props -> JSA.JSArray -> IO ReactElementRef+    js_ReactCreateKeyedElement :: ReactViewRef a -> JSRef -> Export props -> JSA.JSArray -> IO ReactElementRef  js_ReactCreateContent :: String -> ReactElementRef js_ReactCreateContent = ReactElementRef . unsafeCoerce . toJSString -addPropOrHandlerToObj :: JSO.Object -> PropertyOrHandler (IO ()) -> WriterT [Callback (JSRef () -> IO ())] IO ()-addPropOrHandlerToObj obj (Property (n, v)) = lift $ do-    vRef <- toJSRef_aeson v-    JSO.setProp (toJSString $ T.unpack n) vRef obj-addPropOrHandlerToObj obj (EventHandler str handler) = do-    -- this will be released by the render function of the class (jsbits/class.js)-    cb <- lift $ syncCallback1 ContinueAsync $ \evtRef ->-        handler $ HandlerArg evtRef-    tell [cb]-    cbRef <- lift $ toJSRef cb-    lift $ JSO.setProp (toJSString str) cbRef obj-addPropOrHandlerToObj obj (CallbackProperty str handler) = do-    cb <- lift $ syncCallback1 ContinueAsync $ \argref -> do-        v <- fromJSRef $ castRef argref-        handler $ maybe (error "Unable to decode callback value") id v-    tell [cb]-    cbRef <- lift $ toJSRef cb-    lift $ JSO.setProp (toJSString str) cbRef obj--createElement :: IO [ReactElementRef] -> ReactElement (IO ()) -> WriterT [Callback (JSRef () -> IO ())] IO [ReactElementRef]-createElement _ EmptyElement = return []-createElement c (Append x y) = (++) <$> createElement c x <*> createElement c y-createElement _ (Content s) = return [js_ReactCreateContent s]-createElement c ChildrenPassedToView = lift c-createElement c (f@(ForeignElement{})) = do-    obj <- lift $ JSO.create-    mapM_ (addPropOrHandlerToObj obj) $ fProps f-    childNodes <- createElement c $ fChild f-    let childArr = JSA.fromList $ map reactElementRef childNodes-    e <- lift $ case fName f of-        Left s -> js_ReactCreateElementName (toJSString s) obj childArr-        Right ref -> js_ReactCreateForeignElement ref obj childArr-    return [e]-createElement c (ViewElement { ceClass = rc, ceProps = props, ceKey = mkey, ceChild = child }) = do-    childNodes <- createElement c child-    propsE <- lift $ export props -- this will be released inside the lifetime events for the class (jsbits/class.js)-    let arr = JSA.fromList $ map reactElementRef childNodes-    e <- lift $ case mkey of-        Just key -> do-            keyRef <- toKeyRef key-            js_ReactCreateKeyedElement rc keyRef propsE arr-        Nothing -> js_ReactCreateClass rc propsE arr-    return [e]- toJSString :: String -> JSString toJSString = JSS.pack  #else+mkReactElement _ _ _ = return (ReactElementRef (), [])+ toJSString :: String -> String toJSString = id--mkReactElement _ _ _ = return (ReactElementRef (), [])  #endif
src/React/Flux/Lifecycle.hs view
@@ -50,12 +50,11 @@  import GHCJS.Foreign (jsNull) import GHCJS.Foreign.Callback-import GHCJS.Marshal (ToJSRef(..))-import GHCJS.Types (JSRef, castRef)+import GHCJS.Types (JSRef, jsref)  #endif -type HTMLElement = JSRef ()+type HTMLElement = JSRef  -- | Actions to access the current properties and state. data LPropsAndState props state = LPropsAndState@@ -136,7 +135,7 @@         f (dom this) (setStateFn this)      willRecvPropsCb <- mkLCallback2 (lComponentWillReceiveProps cfg) $ \f this newPropsE -> do-        newProps <- parseExport $ Export $ castRef newPropsE+        newProps <- parseExport $ Export newPropsE         f (dom this) (setStateFn this) newProps      willUpdateCb <- mkLCallback2 (lComponentWillUpdate cfg) $ \f this argRef -> do@@ -166,7 +165,7 @@ mkLCallback1 :: (Typeable props, Typeable state)              => Maybe (LPropsAndState props state -> f)              -> (f -> ReactThis state props -> IO ())-             -> IO (JSRef (Callback (JSRef () -> IO ())))+             -> IO JSRef mkLCallback1 Nothing _ = return jsNull mkLCallback1 (Just f) c = do   cb <- syncCallback1 ThrowWouldBlock $ \thisRef -> do@@ -175,12 +174,12 @@                             , lGetState = js_ReactGetState this >>= parseExport                             }     c (f ps) this-  toJSRef cb+  return $ jsref cb  mkLCallback2 :: (Typeable props, Typeable state)              => Maybe (LPropsAndState props state -> f)-             -> (f -> ReactThis state props -> JSRef a -> IO ())-             -> IO (JSRef (Callback (JSRef () -> JSRef a -> IO ())))+             -> (f -> ReactThis state props -> JSRef -> IO ())+             -> IO JSRef mkLCallback2 Nothing _ = return jsNull mkLCallback2 (Just f) c = do   cb <- syncCallback2 ThrowWouldBlock $ \thisRef argRef -> do@@ -189,7 +188,7 @@                             , lGetState = js_ReactGetState this >>= parseExport                             }     c (f ps) this argRef-  toJSRef cb+  return $ jsref cb  #else 
src/React/Flux/PropertiesAndEvents.hs view
@@ -5,6 +5,8 @@     PropertyOrHandler   , (@=)   , ($=)+  , property+  , elementProperty   , callback    -- * Events@@ -87,30 +89,38 @@ #ifdef __GHCJS__ import           Data.Maybe (fromMaybe) -import qualified Data.JSString as JSS import           GHCJS.Foreign (fromJSBool) import           GHCJS.Marshal (FromJSRef(..))-import           GHCJS.Types (JSRef, nullRef, JSString)+import           GHCJS.Types (JSRef, nullRef, JSString, IsJSRef) import           JavaScript.Array as JSA  #else-type JSRef a = ()+type JSRef = () type JSString = String type JSArray = () class FromJSRef a+class IsJSRef a nullRef :: () nullRef = () #endif +-- TOOD: change these to take a String next time we bump the major version+ -- | Create a property. (@=) :: A.ToJSON a => T.Text -> a -> PropertyOrHandler handler-n @= a = Property (n, A.toJSON a)+n @= a = Property (T.unpack n) (A.toJSON a)  -- | Create a text-valued property.  This is here to avoid problems when OverloadedStrings extension -- is enabled ($=) :: T.Text -> T.Text -> PropertyOrHandler handler-n $= a = Property (n, A.toJSON a)+n $= a = Property (T.unpack n) a +-- | Some third-party React classes allow passing React elements as properties.  This function+-- will first run the given 'ReactElementM' to obtain an element or elements, and then use that+-- element as the value for a property with the given key.+elementProperty :: String -> ReactElementM handler () -> PropertyOrHandler handler+elementProperty = ElementProperty+ -- | Create a callback property.  This is primarily intended for foreign React classes which expect -- callbacks to be passed to them as properties.  For events on DOM elements, you should instead use -- the handlers below.@@ -123,7 +133,8 @@  -- | A reference to the object that dispatched the event. -- <https://developer.mozilla.org/en-US/docs/Web/API/Event/target>-newtype EventTarget = EventTarget (JSRef ())+newtype EventTarget = EventTarget JSRef+instance IsJSRef EventTarget  instance Show (EventTarget) where     show _ = "EventTarget"@@ -226,11 +237,11 @@  foreign import javascript unsafe     "$1['preventDefault']();"-    js_preventDefault :: JSRef () -> IO ()+    js_preventDefault :: JSRef -> IO ()  foreign import javascript unsafe     "$1['stopPropagation']();"-    js_stopProp :: JSRef () -> IO ()+    js_stopProp :: JSRef -> IO ()  #else @@ -476,7 +487,7 @@     show (TouchEvent t1 t2 t3 _ t4 t5 t6 t7)         = show (t1, t2, t3, t4, t5, t6, t7) -parseTouch :: JSRef a -> Touch+parseTouch :: JSRef -> Touch parseTouch o = Touch     { touchIdentifier = o .: "identifier"     , touchTarget = EventTarget $ js_getProp o "target"@@ -488,7 +499,7 @@     , touchPageY = o .: "pageY"     } -parseTouchList :: JSRef a -> JSString -> [Touch]+parseTouchList :: JSRef -> JSString -> [Touch] parseTouchList obj key = unsafePerformIO $ do     let arr = js_getArrayProp obj key         len = arrayLength arr@@ -569,49 +580,49 @@  foreign import javascript unsafe     "$1[$2]"-    js_getProp :: JSRef a -> JSString -> JSRef b+    js_getProp :: JSRef -> JSString -> JSRef  foreign import javascript unsafe     "$1[$2]"-    js_getArrayProp :: JSRef a -> JSString -> JSA.JSArray+    js_getArrayProp :: JSRef -> JSString -> JSA.JSArray  -- | Access a property from an object.  Since event objects are immutable, we can use -- unsafePerformIO without worry.-(.:) :: FromJSRef b => JSRef a -> JSString -> b+(.:) :: FromJSRef b => JSRef -> JSString -> b obj .: key = fromMaybe (error "Unable to decode event target") $ unsafePerformIO $     fromJSRef $ js_getProp obj key  foreign import javascript unsafe     "$1['getModifierState']($2)"-    js_GetModifierState :: JSRef () -> JSString -> JSRef Bool+    js_GetModifierState :: JSRef -> JSString -> JSRef -getModifierState :: JSRef () -> String -> Bool+getModifierState :: JSRef -> String -> Bool getModifierState ref = fromJSBool . js_GetModifierState ref . toJSString  arrayLength :: JSArray -> Int arrayLength = JSA.length -arrayIndex :: Int -> JSArray -> JSRef a+arrayIndex :: Int -> JSArray -> JSRef arrayIndex = JSA.index  #else -js_getProp :: a -> String -> JSRef b+js_getProp :: a -> String -> JSRef js_getProp _ _ = () -js_getArrayProp :: a -> String -> JSRef b+js_getArrayProp :: a -> String -> JSRef js_getArrayProp _ _ = () -(.:) :: JSRef () -> String -> b+(.:) :: JSRef -> String -> b _ .: _ = undefined -getModifierState :: JSRef () -> String -> Bool+getModifierState :: JSRef -> String -> Bool getModifierState _ _ = False  arrayLength :: JSArray -> Int arrayLength _ = 0 -arrayIndex :: Int -> JSArray -> JSRef ()+arrayIndex :: Int -> JSArray -> JSRef arrayIndex _ _ = ()  #endif
src/React/Flux/Store.hs view
@@ -16,14 +16,16 @@ import System.IO.Unsafe (unsafePerformIO)  #ifdef __GHCJS__-import GHCJS.Types (JSRef, isNull)+import GHCJS.Types (JSRef, isNull, IsJSRef) import React.Flux.Export (Export, export) #else-type JSRef a = ()+type JSRef = ()+class IsJSRef a #endif  -- | This type is used to represent the foreign javascript object part of the store.-newtype ReactStoreRef storeData = ReactStoreRef (JSRef ())+newtype ReactStoreRef storeData = ReactStoreRef JSRef+instance IsJSRef (ReactStoreRef storeData)  -- | A store contains application state, receives actions from the dispatcher, and notifies -- component views to re-render themselves.  You can have multiple stores; it should be the case
src/React/Flux/Views.hs view
@@ -13,11 +13,11 @@ import React.Flux.Export import JavaScript.Array import GHCJS.Foreign.Callback-import GHCJS.Types (JSRef, castRef, JSString)+import GHCJS.Types (JSRef, JSString, IsJSRef, jsref) import GHCJS.Marshal (ToJSRef(..))  #else-type JSRef a = ()+type JSRef = () #endif  @@ -273,7 +273,8 @@  #ifdef __GHCJS__ -newtype ReactThis state props = ReactThis (JSRef ())+newtype ReactThis state props = ReactThis JSRef+instance IsJSRef (ReactThis state props)  foreign import javascript unsafe     "$1['state'].hs"@@ -293,30 +294,31 @@  foreign import javascript unsafe     "React['findDOMNode']($1)"-    js_ReactFindDOMNode :: ReactThis state props -> IO (JSRef a)+    js_ReactFindDOMNode :: ReactThis state props -> IO JSRef  foreign import javascript unsafe     "React['findDOMNode']($1['refs'][$2])"-    js_ReactGetRef :: ReactThis state props -> JSString -> IO (JSRef a)+    js_ReactGetRef :: ReactThis state props -> JSString -> IO JSRef -newtype RenderCbArg = RenderCbArg (JSRef ())+newtype RenderCbArg = RenderCbArg JSRef+instance IsJSRef RenderCbArg  foreign import javascript unsafe     "$1.newCallbacks = $2; $1.elem = $3;"-    js_RenderCbSetResults :: RenderCbArg -> JSRef [Callback (JSRef () -> IO ())] -> ReactElementRef -> IO ()+    js_RenderCbSetResults :: RenderCbArg -> JSRef -> ReactElementRef -> IO ()  foreign import javascript unsafe     "hsreact$mk_ctrl_view($1, $2, $3)"     js_createControllerView :: JSString                             -> ReactStoreRef storeData-                            -> Callback (JSRef () -> JSRef () -> IO ())+                            -> Callback (JSRef -> JSRef -> IO ())                             -> IO (ReactViewRef props)  -- | Create a view with no state. foreign import javascript unsafe     "hsreact$mk_view($1, $2)"     js_createView :: JSString-                  -> Callback (JSRef () -> JSRef () -> IO ())+                  -> Callback (JSRef -> JSRef -> IO ())                   -> IO (ReactViewRef props)  -- | Create a view which tracks its own state.  Similar releasing needs to happen for callbacks and@@ -325,19 +327,19 @@     "hsreact$mk_stateful_view($1, $2, $3)"     js_createStatefulView :: JSString                           -> Export state-                          -> Callback (JSRef () -> JSRef () -> IO ())+                          -> Callback (JSRef -> JSRef -> IO ())                           -> IO (ReactViewRef props)  foreign import javascript unsafe     "hsreact$mk_lifecycle_view($1, $2, $3, $4, $5, $6, $7, $8, $9)"-    js_makeLifecycleView :: JSString -> Export state -> Callback (JSRef () -> JSRef () -> IO ())-                         -> JSRef a -> JSRef b -> JSRef c -> JSRef d -> JSRef e -> JSRef f -> IO (ReactViewRef props)+    js_makeLifecycleView :: JSString -> Export state -> Callback (JSRef -> JSRef -> IO ())+                         -> JSRef -> JSRef -> JSRef -> JSRef -> JSRef -> JSRef -> IO (ReactViewRef props)  mkRenderCallback :: Typeable props                  => (ReactThis state props -> IO state) -- ^ parse state                  -> (ReactThis state props -> eventHandler -> IO ()) -- ^ execute event args                  -> (state -> props -> IO (ReactElementM eventHandler ())) -- ^ renderer-                 -> IO (Callback (JSRef () -> JSRef () -> IO ()))+                 -> IO (Callback (JSRef -> JSRef -> IO ())) mkRenderCallback parseState runHandler render = syncCallback2 ContinueAsync $ \thisRef argRef -> do     let this = ReactThis thisRef         arg = RenderCbArg argRef@@ -351,7 +353,7 @@      (element, evtCallbacks) <- mkReactElement (runHandler this) getPropsChildren node -    evtCallbacksRef <- toJSRef evtCallbacks+    evtCallbacksRef <- toJSRef $ map jsref evtCallbacks     js_RenderCbSetResults arg evtCallbacksRef element  parseExport :: Typeable a => Export a -> IO a@@ -397,7 +399,7 @@ -- -- >foreign import javascript unsafe -- >    "window['Select']"--- >    js_ReactSelectClass :: JSRef ()+-- >    js_ReactSelectClass :: JSRef -- > -- >reactSelect_ :: [PropertyOrHandler eventHandler] -> ReactElementM eventHandler () -- >reactSelect_ props = foreignClass js_ReactSelectClass props mempty@@ -422,7 +424,7 @@ -- >                   ] -- >    , onSelectChange dispatchSomething -- >    ]-foreignClass :: JSRef cl -- ^ The javascript reference to the class+foreignClass :: JSRef -- ^ The javascript reference to the class              -> [PropertyOrHandler eventHandler] -- ^ properties and handlers to pass when creating an instance of this class.              -> ReactElementM eventHandler a -- ^ The child element or elements              -> ReactElementM eventHandler a@@ -431,7 +433,7 @@  foreignClass name attrs (ReactElementM child) =     let (a, childEl) = runWriter child-     in elementToM a $ ForeignElement (Right $ ReactViewRef $ castRef name) attrs childEl+     in elementToM a $ ForeignElement (Right $ ReactViewRef name) attrs childEl  #else foreignClass _ _ x = x
test/client/TestClient.hs view
@@ -134,7 +134,7 @@  foreign import javascript unsafe     "$1.id"-    js_domGetId :: JSRef a -> IO (JSRef String)+    js_domGetId :: JSRef -> IO JSRef  logDOM :: LDOM -> IO () logDOM dom = do