-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | ReactJS binding using Glazier and Pipes.Fluid -- -- ReactJS binding using Glazier and Pipes.Fluid, which is more -- functional and composable than Elm/Flux. @package glazier-react @version 0.6.0.0 -- | Contains commons utilities when defining your own widget module Glazier.React.ReactDOM -- | Using a React Element (first arg) give React rendering control over a -- DOM element (second arg). This should only be called for the topmost -- component. render :: JSVal -> JSVal -> IO () module Glazier.React.Model -- | Lens to the callbacks and interactions with React class HasPlan c pln | c -> pln plan :: HasPlan c pln => Lens' c pln -- | Lens to the pure model for state and rendering. class HasModel c mdl | c -> mdl model :: HasModel c mdl => Lens' c mdl -- | Convert to the pure serializable model for saving and restoring class ToOutline c o | c -> o outline :: ToOutline c o => c -> o -- | A record of Model and Plan data Scene mdl pln Scene :: mdl -> pln -> Scene mdl pln [_model] :: Scene mdl pln -> mdl [_plan] :: Scene mdl pln -> pln class HasScene c mdl pln | c -> mdl pln scene :: HasScene c mdl pln => Lens' c (Scene mdl pln) -- | All scenes should be disposable to make it easier for cleanup of -- callbacks. -- | A Scene can be converted to Outline by using the Model -- | Frame is a Mvar of Scene. React rendering callback uses this MVar for -- rendering. type Frame mdl pln = MVar (Scene mdl pln) class HasFrame c mdl pln | c -> mdl pln frame :: HasFrame c mdl pln => Lens' c (Frame mdl pln) -- | A record of Scene and Frame. data Gizmo mdl pln Gizmo :: Scene mdl pln -> Frame mdl pln -> Gizmo mdl pln [_scene] :: Gizmo mdl pln -> Scene mdl pln [_frame] :: Gizmo mdl pln -> Frame mdl pln -- | Undecidableinstances! But this is safe because Scene is definitely -- smaller than Gizmo class (HasScene c mdl pln, HasFrame c mdl pln) => HasGizmo c mdl pln | c -> mdl pln gizmo :: HasGizmo c mdl pln => Lens' c (Gizmo mdl pln) -- | A Gizmo can be converted to Outline by using the Model instance GHC.Generics.Generic (Glazier.React.Model.Gizmo mdl pln) instance GHC.Generics.Generic (Glazier.React.Model.Scene mdl pln) instance Glazier.React.Model.HasScene (Glazier.React.Model.Scene mdl pln) mdl pln instance (Control.Disposable.Disposing pln, Control.Disposable.Disposing mdl) => Control.Disposable.Disposing (Glazier.React.Model.Scene mdl pln) instance Glazier.React.Model.HasPlan (Glazier.React.Model.Scene mdl pln) pln instance Glazier.React.Model.HasModel (Glazier.React.Model.Scene mdl pln) mdl instance Glazier.React.Model.ToOutline mdl ol => Glazier.React.Model.ToOutline (Glazier.React.Model.Scene mdl pln) ol instance Glazier.React.Model.HasFrame (Glazier.React.Model.Frame mdl pln) mdl pln instance Control.Disposable.Disposing (Glazier.React.Model.Scene mdl pln) => Control.Disposable.Disposing (Glazier.React.Model.Gizmo mdl pln) instance Glazier.React.Model.HasGizmo (Glazier.React.Model.Gizmo mdl pln) mdl pln instance Glazier.React.Model.HasFrame (Glazier.React.Model.Gizmo mdl pln) mdl pln instance Glazier.React.Model.HasScene (Glazier.React.Model.Gizmo mdl pln) mdl pln instance Glazier.React.Model.HasPlan (Glazier.React.Model.Gizmo mdl pln) pln instance Glazier.React.Model.HasModel (Glazier.React.Model.Gizmo mdl pln) mdl instance Glazier.React.Model.ToOutline mdl o => Glazier.React.Model.ToOutline (Glazier.React.Model.Gizmo mdl pln) o -- | This module based on ReactFluxPropertiesAndEvents.hs. module Glazier.React.Event -- | The object that dispatched the event. -- https://developer.mozilla.org/en-US/docs/Web/API/Event/target data DOMEventTarget -- | The native event -- https://developer.mozilla.org/en-US/docs/Web/API/Event data DOMEvent -- | Every event in React is a synthetic event, a cross-browser wrapper -- around the native event. SyntheticEvent must only be used in -- the first part of eventHandler. data SyntheticEvent -- | Using the NFData idea from ReactFluxPropertiesAndEvents.hs -- React re-uses SyntheticEvent from a pool, which means it may no longer -- be valid if we lazily parse it. However, we still want lazy parsing so -- we don't parse unnecessary fields. Additionally, we don't want to -- block during the event handling.The reason this is a problem is -- because Javascript is single threaded, but Haskell is lazy. Therefore -- GHCJS threads are a strange mixture of synchronous and asynchronous -- threads, where a synchronous thread might be converted to an -- asynchronous thread if a "black hole" is encountered. See -- https://github.com/ghcjs/ghcjs-base/blob/master/GHCJS/Concurrent.hs -- This safe interface requires two input functions: 1. a function to -- reduce SyntheticEvent to a NFData. The mkEventCallback will ensure -- that the NFData is forced which will ensure all the required fields -- from Synthetic event has been parsed. This function must not block. 2. -- a second function that uses the NFData. This function is allowed to -- block. mkEventHandler results in a function that you can safely pass -- into syncCallback1 with ContinueAsync. eventHandler :: NFData a => (evt -> a) -> (a -> b) -> (evt -> b) -- | a monadic version of eventHandler The monad's effects must not block! eventHandlerM :: (Monad m, NFData a) => (evt -> m a) -> (a -> m b) -> (evt -> m b) -- | Every SyntheticEvent can be parsed to an Event. -- Event must only be used in the first part of -- eventHandler. data Event Event :: Bool -> Bool -> DOMEventTarget -> Bool -> Int -> Bool -> DOMEvent -> DOMEventTarget -> Int -> JSString -> Event preventDefault :: SyntheticEvent -> IO () isDefaultPrevented :: SyntheticEvent -> Bool stopPropagation :: SyntheticEvent -> IO () isPropagationStopped :: SyntheticEvent -> Bool -- | We can lie about this not being in IO because within the strict part -- of eventHandlerM the SyntheticEvent is effectively immutable. parseEvent :: SyntheticEvent -> Event -- | Mouse and Drag/Drop events MouseEvent must only be used in the -- first part of eventHandler. -- https://facebook.github.io/react/docs/events.html#mouse-events -- https://developer.mozilla.org/en-US/docs/Web/Events Event names -- (eventType) onClick (click) onContextMenu (contextmenu) onDoubleClick -- (dblclick) onDrag (drag) onDragEnd (dragend) onDragEnter (dragenter) -- onDragExit (dragexit) onDragLeave (dragleave) onDragOver (dragover) -- onDragStart (dragstart) onDrop (drop) onMouseDown (mousedown) -- onMouseEnter (mouseenter) onMouseLeave (mouseleave) onMouseMove -- (mousemove) onMouseOut (mouseout) onMouseOver (mouseover) onMouseUp -- (mouseup) data MouseEvent MouseEvent :: Bool -> Int -> Int -> Int -> Int -> Bool -> (JSString -> Bool) -> Bool -> Int -> Int -> DOMEventTarget -> Int -> Int -> Bool -> MouseEvent -- | We can lie about this not being in IO because within the strict part -- of eventHandlerM the SyntheticEvent is effectively immutable. parseMouseEvent :: SyntheticEvent -> Maybe MouseEvent -- | Keyboard events KeyboardEvent must only be used in the first -- part of eventHandler. -- https://facebook.github.io/react/docs/events.html#keyboard-events -- Event names (eventType) onKeyDown (keydown) onKeyPress (keypress) -- onKeyUp (keyyp) data KeyboardEvent KeyboardEvent :: Bool -> Int -> Bool -> (JSString -> Bool) -> JSString -> Int -> JSString -> Int -> Bool -> Bool -> Bool -> Int -> KeyboardEvent -- | We can lie about this not being in IO because within the strict part -- of eventHandlerM the SyntheticEvent is effectively immutable. parseKeyboardEvent :: SyntheticEvent -> Maybe KeyboardEvent instance GHCJS.Internal.Types.IsJSVal Glazier.React.Event.DOMEventTarget instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Event.DOMEventTarget instance JavaScript.Extras.Cast.ToJS Glazier.React.Event.DOMEventTarget instance JavaScript.Extras.Cast.FromJS Glazier.React.Event.DOMEventTarget instance GHCJS.Internal.Types.IsJSVal Glazier.React.Event.DOMEvent instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Event.DOMEvent instance JavaScript.Extras.Cast.ToJS Glazier.React.Event.DOMEvent instance JavaScript.Extras.Cast.FromJS Glazier.React.Event.DOMEvent instance GHCJS.Internal.Types.IsJSVal Glazier.React.Event.SyntheticEvent instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Event.SyntheticEvent instance JavaScript.Extras.Cast.ToJS Glazier.React.Event.SyntheticEvent instance JavaScript.Extras.Cast.FromJS Glazier.React.Event.SyntheticEvent -- | HtmlT inspired monad for creating ReactElements module Glazier.React.Element data ReactElement -- | Unfortunately, ReactJS did not export an easy way to check if -- something is a ReactElement, although they do so in the internal code -- with REACT_ELEMENT_TYPE. This function allow coercing a ReactElement -- from a JSVal and is named unsafe as a reminder that the coersion is -- unchecked. This function is required when receiving ReactElement from -- javascript (eg in a callback) or to interface with foreign React -- Elements. unsafeCoerceElement :: JSVal -> ReactElement -- | Create a react element (with children) from a HashMap of properties mkBranchElement :: JSVar -> [Property] -> [ReactElement] -> IO ReactElement -- | Create a react element (with no children) from a HashMap of properties mkLeafElement :: JSVar -> [Property] -> IO ReactElement -- | Not an IO action because JSString is immutable textElement :: JSString -> ReactElement -- | React only allows a single top most element. Provide a handly function -- to wrap a list of ReactElements inside a div if required. If -- there is only one element in the list, then nothing is changed. mkCombinedElements :: [ReactElement] -> IO ReactElement instance GHCJS.Internal.Types.IsJSVal Glazier.React.Element.ReactElement instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Element.ReactElement instance JavaScript.Extras.Cast.ToJS Glazier.React.Element.ReactElement -- | HtmlT inspired monad for creating ReactElements module Glazier.React.Markup data ReactMarkup ElementMarkup :: ReactElement -> ReactMarkup TextMarkup :: JSString -> ReactMarkup BranchMarkup :: BranchParam -> ReactMarkup LeafMarkup :: LeafParam -> ReactMarkup -- | The parameters required to create a branch ReactElement with children data BranchParam BranchParam :: JSVar -> [Property] -> (DList ReactMarkup) -> BranchParam -- | The parameters required to create a leaf ReactElement (no children) data LeafParam LeafParam :: JSVar -> [Property] -> LeafParam -- | Create ReactElements from a AtomMarkup fromMarkup :: ReactMarkup -> IO (ReactElement) -- | Monadic generator of ReactActom. It is a CPS-style WriterT (ie a -- StateT) to build up a function build up a computations to generate a -- '[AtomMarkup]'. You can use runStateT with an initial state of -- mempty. newtype ReactMlT m a ReactMlT :: StateT (DList ReactMarkup) m a -> ReactMlT m a [runReactMlT] :: ReactMlT m a -> StateT (DList ReactMarkup) m a type ReactMl = ReactMlT Identity -- | To use an exisitng ReactElement fromElement :: Applicative m => ReactElement -> ReactMlT m () -- | Convert the ReactMlt to [R.ReactElement] toElements :: MonadIO io => ReactMlT io () -> io [ReactElement] -- | Render the ReactMlt under a Glazier window markedWindow :: MonadIO io => WindowT s (ReactMlT io) () -> WindowT s io [ReactElement] -- | Fully render the ReactMlt into a [R.ReactElement] markedElements :: MonadIO io => WindowT s (ReactMlT io) () -> s -> io [ReactElement] -- | Fully render the ReactMlt into a R.ReactElement markedElement :: MonadIO io => WindowT s (ReactMlT io) () -> s -> io ReactElement -- | For text content txt :: Applicative m => JSString -> ReactMlT m () -- | For the contentless elements: eg br_ lf :: Applicative m => JSVar -> [Property] -> ReactMlT m () -- | For the contentful elements: eg div_ bh :: Functor m => JSVar -> [Property] -> ReactMlT m a -> ReactMlT m a instance Control.Monad.Morph.MFunctor Glazier.React.Markup.ReactMlT instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Glazier.React.Markup.ReactMlT m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Glazier.React.Markup.ReactMlT m) instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Glazier.React.Markup.ReactMlT m) instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Glazier.React.Markup.ReactMlT m) instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Glazier.React.Markup.ReactMlT m) instance GHC.Base.Functor m => GHC.Base.Functor (Glazier.React.Markup.ReactMlT m) instance GHC.Base.Monad m => GHC.Base.Applicative (Glazier.React.Markup.ReactMlT m) instance GHC.Base.Monad m => GHC.Base.Monad (Glazier.React.Markup.ReactMlT m) instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Data.DList.DList Glazier.React.Markup.ReactMarkup) (Glazier.React.Markup.ReactMlT m) instance (Data.Semigroup.Semigroup a, GHC.Base.Monad m) => Data.Semigroup.Semigroup (Glazier.React.Markup.ReactMlT m a) instance (GHC.Base.Monoid a, GHC.Base.Monad m) => GHC.Base.Monoid (Glazier.React.Markup.ReactMlT m a) module Glazier.React.Component -- | A newtype wrapper to give a noop disposable instance to React -- components This allows generic deriving of model Adaptors. data ReactComponent mkComponent :: IO ReactComponent instance Control.Disposable.Disposing Glazier.React.Component.ReactComponent instance GHCJS.Internal.Types.IsJSVal Glazier.React.Component.ReactComponent instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Component.ReactComponent instance JavaScript.Extras.Cast.ToJS Glazier.React.Component.ReactComponent module Glazier.React.Maker -- | DSL for IO effects required during making widget models and callbacks -- Maker remembers the action type to allow mapAction for -- changing the action type by parent widgets. The model type does not -- need to be changed, so it is hidden in the GADT existential. data Maker act nxt [MkHandler] :: (JSVal -> MaybeT IO [act]) -> (Callback (JSVal -> IO ()) -> nxt) -> Maker act nxt [MkEmptyFrame] :: (Frame mdl pln -> nxt) -> Maker act nxt [MkRenderer] :: Frame mdl pln -> (JSVal -> WindowT (Scene mdl pln) ReactMl ()) -> (Callback (JSVal -> IO JSVal) -> nxt) -> Maker act nxt [PutFrame] :: Frame mdl pln -> Scene mdl pln -> nxt -> Maker act nxt [GetComponent] :: (ReactComponent -> nxt) -> Maker act nxt [MkKey] :: (JSString -> nxt) -> Maker act nxt mkKey :: forall m_anSQ act_anCA. MonadFree (Maker act_anCA) m_anSQ => m_anSQ JSString getComponent :: forall m_anSN act_anCA. MonadFree (Maker act_anCA) m_anSN => m_anSN ReactComponent putFrame :: forall (mdl_XnCY :: Type) (pln_XnD0 :: Type) m_anSJ act_anCA. MonadFree (Maker act_anCA) m_anSJ => Frame mdl_XnCY pln_XnD0 -> Scene mdl_XnCY pln_XnD0 -> m_anSJ () mkRenderer :: forall (mdl_XnCU :: Type) (pln_XnCW :: Type) m_anSE act_anCA. MonadFree (Maker act_anCA) m_anSE => Frame mdl_XnCU pln_XnCW -> (JSVal -> WindowT (Scene mdl_XnCU pln_XnCW) ReactMl ()) -> m_anSE (Callback (JSVal -> IO JSVal)) mkEmptyFrame :: forall (mdl_XnCQ :: Type) (pln_XnCS :: Type) m_anSB act_anCA. MonadFree (Maker act_anCA) m_anSB => m_anSB (Frame mdl_XnCQ pln_XnCS) mkHandler :: forall m_anSx act_anCA. MonadFree (Maker act_anCA) m_anSx => (JSVal -> MaybeT IO [act_anCA]) -> m_anSx (Callback (JSVal -> IO ())) -- | Allows changing the action type of Maker withAction :: (act -> act') -> Maker act a -> Maker act' a hoistWithAction :: (act -> act') -> F (Maker act) a -> F (Maker act') a instance GHC.Base.Functor (Glazier.React.Maker.Maker act) module Glazier.React.Widget type SceneOf w = Scene (ModelOf w) (PlanOf w) type FrameOf w = Frame (ModelOf w) (PlanOf w) type GizmoOf w = Gizmo (ModelOf w) (PlanOf w) type WindowOf w = WindowT (SceneOf w) (ReactMlT Identity) () type GadgetOf w = GadgetT (ActionOf w) (GizmoOf w) Identity (DList (CommandOf w)) -- | tag used to choose Schema that contains Gizmos data WithGizmo -- | tag used to choose Schema that contains Outlines data WithOutline -- | You can't use type family as a type variable for a data type. The -- workaround is to use a tag to choose between different type family -- functions. ModelType takes a tag to choose between Gizmo or Outline. -- This enables creating a data type that can specialize to -- using the tag. -- | Record of functions for a widget. Contains everything you need to make -- the model, render, and run the event processing. This is a GADT to -- enforce the Disposing and ToOutline constraints at the time of -- creating the Widget record. data Widget c a o m p [Widget] :: (Disposing m, Disposing p, ToOutline m o) => (o -> F (Maker a) m) -> (Frame m p -> F (Maker a) p) -> WindowT (Scene m p) (ReactMlT Identity) () -> GadgetT a (Gizmo m p) Identity (DList c) -> Widget c a o m p -- | This typeclass is convenient as it carries the 'Disposing Model' and -- 'Disposing Plan' constraints and allows treating 'Widget c a m p' as a -- type w class (Disposing (ModelOf w), Disposing (PlanOf w), ToOutline (ModelOf w) (OutlineOf w)) => IsWidget w -- | Make a Model from an Outline mkModel :: IsWidget w => w -> OutlineOf w -> F (Maker (ActionOf w)) (ModelOf w) -- | Given an empty frame, make the Plan that uses the frame for rendering mkPlan :: IsWidget w => w -> Frame (ModelOf w) (PlanOf w) -> F (Maker (ActionOf w)) (PlanOf w) -- | Rendering function that uses the Scene of Model and Plan window :: IsWidget w => w -> WindowT (Scene (ModelOf w) (PlanOf w)) (ReactMlT Identity) () -- | Update function that processes Action to update the Frame and Scene gadget :: IsWidget w => w -> GadgetT (ActionOf w) (Gizmo (ModelOf w) (PlanOf w)) Identity (DList (CommandOf w)) -- | Make the required Frame and Plan for a Model mkGizmo :: IsWidget w => w -> ModelOf w -> F (Maker (ActionOf w)) (Gizmo (ModelOf w) (PlanOf w)) -- | Make the required Frame and Plan from an Outline mkGizmo' :: IsWidget w => w -> OutlineOf w -> F (Maker (ActionOf w)) (Gizmo (ModelOf w) (PlanOf w)) instance (Control.Disposable.Disposing m, Control.Disposable.Disposing p, Glazier.React.Model.ToOutline m o) => Glazier.React.Widget.IsWidget (Glazier.React.Widget.Widget c a o m p) module Glazier.React.Maker.Run -- | This is called synchronously by React to render the DOM. This must not -- block! onRender :: MVar s -> (JSVal -> WindowT s (ReactMlT IO) ()) -> JSVal -> IO JSVal mkActionCallback :: Output act -> (JSVal -> MaybeT IO [act]) -> IO (Callback (JSVal -> IO ())) run :: MVar Int -> ReactComponent -> Output act -> Maker act (IO a) -> IO a -- | Common functions used by command interpreters module Glazier.React.Command.Run componentSetState :: HasGizmo giz mdl pln => giz -> [Property] -> JSVal -> IO () module Glazier.React.Command -- | Just change the state to something different so the React -- pureComponent will call render() renderCmd :: Monad m => (sm -> -- [JE.Property] -> J.JSVal -> cmd) -> G.GadgetT act sm m cmd -- The resulting command should be interpreted using -- componentSetState basicRenderCmd :: MonadState sm m => Lens' sm Int -> Getter sm JSVal -> (sm -> [Property] -> JSVal -> cmd) -> m cmd