-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | hsp+jmacro support
--   
--   HSP allows for the use of literal XML in Haskell program text. JMacro
--   allows for the use of javascript-syntax for generating javascript in
--   Haskell. This library makes it easy to embed JMacro generated
--   javascript in HSX templates.
@package hsx-jmacro
@version 7.3.7


-- | This experimental module provides a monad transformer <a>JMacroT</a>
--   and corresponding <a>XMLGenerator</a> instance which can be used to
--   directly generate javascript which builds an XML/HTML DOM.
--   
--   This is similar to the 'ToJExpr XMLToDOM' instance except that there
--   is no intermediate XML type. The <a>XMLGenerator</a> instance directly
--   generates the javascript needed to build the DOM.
--   
--   This is intellectually fun. But it is not clear how it is valuable.
--   That is why this module is marked as experimental.
module HSP.JMacroT

-- | isomorphic to IdentityT, but used for generating javascript that
--   generates XML/HTML
newtype JMacroT m a
JMacroT :: m a -> JMacroT m a
[unJMacroT] :: JMacroT m a -> m a

-- | unwrap the <a>XMLGenT</a> and <a>JMacroT</a> constructors
evalJMacroT :: XMLGenT (JMacroT m) JExpr -> m JExpr

-- | map a function over the inner monad
mapJMacroT :: (m a -> n b) -> JMacroT m a -> JMacroT n b

-- | an alias for 'JMacroT Identity'
type JMacroM = JMacroT Identity

-- | evaluate <a>JMacroM</a>
evalJMacroM :: XMLGenT JMacroM a -> a
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (HSP.JMacroT.JMacroT m)
instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (HSP.JMacroT.JMacroT m)
instance Control.Monad.RWS.Class.MonadRWS r w s m => Control.Monad.RWS.Class.MonadRWS r w s (HSP.JMacroT.JMacroT m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (HSP.JMacroT.JMacroT m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (HSP.JMacroT.JMacroT m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (HSP.JMacroT.JMacroT m)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (HSP.JMacroT.JMacroT m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (HSP.JMacroT.JMacroT m)
instance GHC.Base.Monad m => GHC.Base.Monad (HSP.JMacroT.JMacroT m)
instance GHC.Base.Alternative m => GHC.Base.Alternative (HSP.JMacroT.JMacroT m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (HSP.JMacroT.JMacroT m)
instance GHC.Base.Functor m => GHC.Base.Functor (HSP.JMacroT.JMacroT m)
instance Control.Monad.Trans.Class.MonadTrans HSP.JMacroT.JMacroT
instance Language.Javascript.JMacro.Base.ToJExpr a => Language.Javascript.JMacro.Base.ToJExpr (HSP.XMLGenerator.XMLGenT HSP.JMacroT.JMacroM a)
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.XMLGen (HSP.JMacroT.JMacroT m)
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsAttr (HSP.JMacroT.JMacroT m) (HSP.XMLGenerator.Attr Data.Text.Internal.Lazy.Text Data.Text.Internal.Lazy.Text)
instance (GHC.Base.Functor m, GHC.Base.Monad m, HSP.XMLGenerator.StringType (HSP.JMacroT.JMacroT m) ~ Data.Text.Internal.Lazy.Text) => HSP.XMLGenerator.EmbedAsChild (HSP.JMacroT.JMacroT m) GHC.Types.Char
instance (GHC.Base.Functor m, GHC.Base.Monad m, HSP.XMLGenerator.StringType (HSP.JMacroT.JMacroT m) ~ Data.Text.Internal.Lazy.Text) => HSP.XMLGenerator.EmbedAsChild (HSP.JMacroT.JMacroT m) GHC.Base.String
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsChild (HSP.JMacroT.JMacroT m) Data.Text.Internal.Text
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsChild (HSP.JMacroT.JMacroT m) Data.Text.Internal.Lazy.Text
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsChild (HSP.JMacroT.JMacroT m) ()
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsAttr (HSP.JMacroT.JMacroT m) (HSP.XMLGenerator.Attr Data.Text.Internal.Lazy.Text GHC.Types.Bool)
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsAttr (HSP.JMacroT.JMacroT m) (HSP.XMLGenerator.Attr Data.Text.Internal.Lazy.Text GHC.Types.Int)
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.AppendChild (HSP.JMacroT.JMacroT m) Language.Javascript.JMacro.Base.JExpr
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.SetAttr (HSP.JMacroT.JMacroT m) Language.Javascript.JMacro.Base.JExpr
instance (GHC.Base.Functor m, GHC.Base.Monad m, HSP.XMLGenerator.StringType (HSP.JMacroT.JMacroT m) ~ Data.Text.Internal.Lazy.Text) => HSP.XMLGenerator.XMLGenerator (HSP.JMacroT.JMacroT m)


-- | This module provides support for:
--   
--   <ol>
--   <li>embedding Javascript generated by JMacro into HSX.</li>
--   <li>turning XML generated by HSX into a DOM node in Javascript</li>
--   </ol>
--   
--   It provides the following instances:
--   
--   <pre>
--   instance (XMLGenerator m, IntegerSupply m) =&gt; EmbedAsChild m JStat
--   instance (IntegerSupply m, IsName n, EmbedAsAttr m (Attr Name String)) =&gt; EmbedAsAttr m (Attr n JStat)
--   instance ToJExpr XML
--   instance ToJExpr DOMNode
--   instance ToJExpr XMLToInnerHTML
--   instance ToJExpr XMLToDOM
--   </pre>
--   
--   In order to ensure that each embedded <a>JStat</a> block has unique
--   variable names, the monad must supply a source of unique names. This
--   is done by adding an instance of <a>IntegerSupply</a> for the monad
--   being used with <a>XMLGenerator</a>.
--   
--   For example, we can use <tt>StateT</tt> to provide an
--   <a>IntegerSupply</a> instance for <tt>ServerPartT</tt>:
--   
--   <pre>
--   instance IntegerSupply (ServerPartT (StateT Integer IO)) where
--       nextInteger = nextInteger'
--   </pre>
--   
--   Alternatively, we can exploit the IO monad to provide an
--   <a>IntegerSupply</a> instance for <tt>ServerPartT</tt>:
--   
--   <pre>
--   instance IntegerSupply (ServerPartT IO) where
--       nextInteger = fmap (fromIntegral . (`mod` 1024) . hashUnique) (liftIO newUnique)
--   </pre>
--   
--   The <tt>ToJExpr XML</tt> instance allows you to splice in XML lifted
--   out of an arbitrary monad to generate DOM nodes with JMacro
--   antiquotation:
--   
--   <pre>
--   js = do html &lt;- unXMLGenT &lt;p&gt;I'm in a Monad!&lt;/p&gt;
--           return [jmacro| document.getElementById("messages").appendChild(`(html)`); |]
--   </pre>
--   
--   The <tt>ToJExpr DOMNode</tt> instance allows you to run HSP in the
--   Identity monad to render JMacro in pure code:
--   
--   <pre>
--   html :: DOMNode
--   html = &lt;p&gt;I'm using &lt;em&gt;JavaScript&lt;/em&gt;!&lt;/p&gt;
--   js = [jmacro| var language = `(html)`.getElementsByTagName("em")[0].textContent; |]
--   </pre>
--   
--   You can see here that you get an actual DOM tree in JavaScript. This
--   is also compatible with libraries such as jQuery and YUI which are
--   able to wrap DOM nodes in their own type, for example with jQuery:
--   
--   <pre>
--   js = [jmacro| var languages = $(`(html)`).find("em").text(); |]
--   </pre>
--   
--   Or with YUI:
--   
--   <pre>
--   js = [jmacro| var languages = Y.one(`(html)`).one("em").get("text"); |]
--   </pre>
--   
--   There are two ways to turn HTML into a a DOM node in the browser. One
--   way is to render the HTML to a string, and pass the string to
--   <tt>element.innerHTML</tt>. The other way is to us the use the DOM
--   functions like <tt>createElement</tt>, <tt>setAttribute</tt>, to
--   programatically create the DOM on the client.
--   
--   In webkit-based browsers like Chrome and Safari, the DOM method
--   appears to be slightly faster. In other browsers, the
--   <tt>innerHTML</tt> method appears to be faster. The <tt>innerHTML</tt>
--   method will almost always required fewer bytes to be transmitted.
--   Additionally, if your XML/HTML contains pre-escaped content, you are
--   required to use <tt>innerHTML</tt> anyway.
--   
--   So, by default the <a>ToJExpr</a> <a>XML</a> instance uses the
--   <tt>innerHTML</tt> method. Though, that could change in the future. If
--   you care about using one method over the other you can use the
--   <tt>newtype</tt> wrappers <a>XMLToInnerHTML</a> or <a>XMLToDOM</a> to
--   select which method to use.
module HSP.JMacro

-- | This class provides a monotonically increasing supply of non-duplicate
--   <a>Integer</a> values
class IntegerSupply m
nextInteger :: IntegerSupply m => m Integer

-- | This help function allows you to easily create an <a>IntegerSupply</a>
--   instance for monads that have a <a>MonadState</a> <a>Integer</a>
--   instance.
--   
--   For example:
--   
--   <pre>
--   instance IntegerSupply (ServerPartT (StateT Integer IO)) where
--       nextInteger = nextInteger'
--   </pre>
nextInteger' :: (MonadState Integer m) => m Integer

-- | Provided for convenience since <tt>Ident</tt> is exported by both
--   <tt>HSP.Identity</tt> and <tt>JMacro</tt>. Using this you can avoid
--   the need for an extra and qualified import.
type DOMNode = HSPT XML Identity XML

-- | newtype which can be used with <a>toJExpr</a> to specify that the XML
--   should be converted to a DOM in javascript by using <tt>innerHTML</tt>
newtype XMLToInnerHTML
XMLToInnerHTML :: XML -> XMLToInnerHTML

-- | newtype which can be used with <a>toJExpr</a> to specify that the XML
--   should be converted to a DOM in javascript by using
--   <tt>createElement</tt>, <tt>appendChild</tt>, and other DOM functions.
--   
--   WARNING: <tt>CDATA FALSE</tt> values are assumed to be pre-escaped
--   HTML and will be converted to a DOM node by using <tt>innerHTML</tt>.
--   Additionally, if the call to <tt>innerHTML</tt> returns more than one
--   node, only the first node is used.
newtype XMLToDOM
XMLToDOM :: XML -> XMLToDOM
instance (HSP.XMLGenerator.XMLGenerator m, HSP.JMacro.IntegerSupply m, HSP.XMLGenerator.EmbedAsChild m Data.Text.Internal.Lazy.Text, HSP.XMLGenerator.StringType m ~ Data.Text.Internal.Lazy.Text) => HSP.XMLGenerator.EmbedAsChild m Language.Javascript.JMacro.Base.JStat
instance (HSP.JMacro.IntegerSupply m, HSP.XMLGenerator.EmbedAsAttr m (HSP.XMLGenerator.Attr n Data.Text.Internal.Lazy.Text)) => HSP.XMLGenerator.EmbedAsAttr m (HSP.XMLGenerator.Attr n Language.Javascript.JMacro.Base.JStat)
instance Language.Javascript.JMacro.Base.ToJExpr HSP.JMacro.DOMNode
instance Language.Javascript.JMacro.Base.ToJExpr HSP.JMacro.XMLToInnerHTML
instance Language.Javascript.JMacro.Base.ToJExpr HSP.JMacro.XMLToDOM
instance Language.Javascript.JMacro.Base.ToJExpr HSP.XML.XML
