-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | representations of a web page -- -- An applicative-based, shared-data representation of a web page. @package web-rep @version 0.6.0 -- | Key generators and miscellaneous html utilities. -- -- Uses the lucid Html. module Web.Rep.Html -- | FIXME: A horrible hack to separate class id's class__ :: Text -> Attribute -- | Convert html to text toText :: Html a -> Text -- | Convert a link to a css library from text to html. -- --
-- >>> libCss "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" -- <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> --libCss :: Text -> Html () -- | Convert a link to a js library from text to html. -- --
-- >>> libJs "https://code.jquery.com/jquery-3.3.1.slim.min.js" -- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script> --libJs :: Text -> Html () -- | A monad transformer that generates HTML. Use the simpler Html -- type if you don't want to transform over some other monad. data HtmlT (m :: Type -> Type) a -- | Simple HTML builder type. Defined in terms of HtmlT. Check out -- that type for instance information. -- -- Simple use-cases will just use this type. But if you want to -- transformer over Reader or something, you can go and use HtmlT. type Html = HtmlT Identity instance Lucid.Base.ToHtml GHC.Types.Double instance Lucid.Base.ToHtml GHC.Types.Bool instance Lucid.Base.ToHtml GHC.Types.Int instance Lucid.Base.ToHtml () instance Lucid.Base.ToHtml a => Lucid.Base.ToHtml [a] -- | Common web page input elements, often with bootstrap scaffolding. module Web.Rep.Html.Input -- | something that might exist on a web page and be a front-end input to -- computations. data Input a Input :: a -> Maybe Text -> Text -> InputType -> Input a -- | underlying value [inputVal] :: Input a -> a -- | label suggestion [inputLabel] :: Input a -> Maybe Text -- | name/key/id of the Input [inputId] :: Input a -> Text -- | type of html input [inputType] :: Input a -> InputType -- | Various types of web page inputs, encapsulating practical bootstrap -- class functionality data InputType Slider :: [Attribute] -> InputType TextBox :: InputType TextBox' :: InputType TextArea :: Int -> InputType ColorPicker :: InputType ChooseFile :: InputType Dropdown :: [Text] -> InputType DropdownMultiple :: [Text] -> Char -> InputType DropdownSum :: [Text] -> InputType Datalist :: [Text] -> Text -> InputType Checkbox :: Bool -> InputType Toggle :: Bool -> Maybe Text -> InputType Button :: InputType instance GHC.Generics.Generic (Web.Rep.Html.Input.Input a) instance GHC.Show.Show a => GHC.Show.Show (Web.Rep.Html.Input.Input a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Web.Rep.Html.Input.Input a) instance GHC.Generics.Generic Web.Rep.Html.Input.InputType instance GHC.Show.Show Web.Rep.Html.Input.InputType instance GHC.Classes.Eq Web.Rep.Html.Input.InputType instance Lucid.Base.ToHtml a => Lucid.Base.ToHtml (Web.Rep.Html.Input.Input a) -- | mathjax functionality. -- -- some mathjax assets -- -- mathjax cheatsheet -- -- FIXME: Mathjax inside svg doesn't quite work, and needs to be -- structured around the foreign object construct. module Web.Rep.Mathjax -- | A Page that loads mathjax mathjaxPage :: Page -- | A Page that loads the mathjax 2.7 js library mathjax27Page :: Page -- | A Page that tries to enable mathjax inside svg (which is -- tricky). mathjaxSvgPage :: Text -> Page -- | A Page that tries to enable mathjax 2.7 inside svg. mathjax27SvgPage :: Text -> Page -- | Page rendering module Web.Rep.Render -- | Render a Page with the default configuration into Html. renderPage :: Page -> Html () -- | Render a Page into css text, js text and html. renderPageWith :: PageConfig -> Page -> (Text, Text, Html ()) -- | Render a Page into Html. renderPageHtmlWith :: PageConfig -> Page -> Html () -- | Render a Page as Text. renderPageAsText :: PageConfig -> Page -> Concerns Text -- | Render Page concerns to files. renderPageToFile :: FilePath -> PageConfig -> Page -> IO () -- | Render a page to just a Html file. renderPageHtmlToFile :: FilePath -> PageConfig -> Page -> IO () -- | Serve pages via ScottyM module Web.Rep.Server -- | serve a Page via a ScottyM servePageWith :: RoutePattern -> PageConfig -> Page -> ScottyM () -- | Some bootstrap assets and functionality. module Web.Rep.Bootstrap -- | A page containing all the bootstrap needs for a web page. bootstrapPage :: Page -- | wrap some Html with the bootstrap card class cardify :: (Html (), [Attribute]) -> Maybe Text -> (Html (), [Attribute]) -> Html () -- | wrap some html with a classed div divClass_ :: Text -> Html () -> Html () -- | create a bootstrapped accordian class accordion :: MonadState Int m => Text -> Maybe Text -> [(Text, Html ())] -> m (Html ()) -- | create a bootstrapped accordian class accordionChecked :: MonadState Int m => Text -> [(Text, Html (), Html ())] -> m (Html ()) -- | A Html object based on the bootstrap accordion card concept. accordionCard :: Bool -> [Attribute] -> Text -> Text -> Text -> Text -> Html () -> Html () -- | A bootstrap accordion card attached to a checkbox. accordionCardChecked :: Bool -> Text -> Text -> Text -> Text -> Html () -> Html () -> Html () -- | This version of accordion runs a local state for naming, and will -- cause name clashes if the prefix is not unique. accordion_ :: Text -> Maybe Text -> [(Text, Html ())] -> Html () -- | Various SharedRep instances for common html input elements. module Web.Rep.SharedReps -- | Create a sharedRep from an Input. repInput :: (Monad m, ToHtml a) => Parser a -> (a -> Text) -> Input a -> a -> SharedRep m a -- | Like repInput, but does not put a value into the HashMap on -- instantiation, consumes the value when found in the HashMap, and -- substitutes a default on lookup failure repMessage :: (Monad m, ToHtml a) => Parser a -> (a -> Text) -> Input a -> a -> a -> SharedRep m a -- | integral slider -- -- For Example, a slider between 0 and 1000 with a step of 10 and a -- default value of 300 is: -- --
-- >>> :t sliderI (Just "label") 0 1000 10 300 -- sliderI (Just "label") 0 1000 10 300 -- :: (Monad m, ToHtml a, P.Integral a, Show a) => SharedRep m a --sliderI :: (Monad m, ToHtml a, Integral a, Show a) => Maybe Text -> a -> a -> a -> a -> SharedRep m a -- | double slider -- -- For Example, a slider between 0 and 1 with a step of 0.01 and a -- default value of 0.3 is: -- --
-- >>> :t slider (Just "label") 0 1 0.01 0.3 -- slider (Just "label") 0 1 0.01 0.3 :: Monad m => SharedRep m Double --slider :: Monad m => Maybe Text -> Double -> Double -> Double -> Double -> SharedRep m Double -- | dropdown box dropdown :: (Monad m, ToHtml a) => Parser a -> (a -> Text) -> Maybe Text -> [Text] -> a -> SharedRep m a -- | dropdown box with multiple selections dropdownMultiple :: (Monad m, ToHtml a) => Parser a -> (a -> Text) -> Maybe Text -> [Text] -> [a] -> SharedRep m [a] -- | a datalist input datalist :: Monad m => Maybe Text -> [Text] -> Text -> Text -> SharedRep m Text -- | A dropdown box designed to help represent a haskell sum type. dropdownSum :: (Monad m, ToHtml a) => Parser a -> (a -> Text) -> Maybe Text -> [Text] -> a -> SharedRep m a -- | Non-typed hex color input colorPicker :: Monad m => Maybe Text -> Text -> SharedRep m Text -- | textbox classique -- --
-- >>> :t textbox (Just "label") "some text" -- textbox (Just "label") "some text" :: Monad m => SharedRep m Text --textbox :: Monad m => Maybe Text -> Text -> SharedRep m Text -- | textarea input element, specifying number of rows. textarea :: Monad m => Int -> Maybe Text -> Text -> SharedRep m Text -- | A checkbox input. checkbox :: Monad m => Maybe Text -> Bool -> SharedRep m Bool -- | a toggle button toggle :: Monad m => Maybe Text -> Bool -> SharedRep m Bool -- | a button button :: Monad m => Maybe Text -> SharedRep m Bool -- | filename input chooseFile :: Monad m => Maybe Text -> Text -> SharedRep m Text -- | Represent a Maybe using a checkbox. -- -- Hides the underlying content on Nothing maybeRep :: Monad m => Maybe Text -> Bool -> SharedRep m a -> SharedRep m (Maybe a) -- | Representation of web concerns (css, js & html). fiddle :: Monad m => Concerns Text -> SharedRep m (Concerns Text, Bool) -- | turns a SharedRep into a fiddle viaFiddle :: Monad m => SharedRep m a -> SharedRep m (Bool, Concerns Text, a) -- | A (fixed-size) list represented in html as an accordion card A major -- restriction of the library is that a SharedRepF does not have a -- Monad instance. In practice, this means that the external -- representation of lists cannot have a dynamic size. accordionList :: Monad m => Maybe Text -> Text -> Maybe Text -> (Text -> a -> SharedRep m a) -> [Text] -> [a] -> SharedRep m [a] -- | A fixed-sized list of Maybe a's listMaybeRep :: Monad m => Maybe Text -> Text -> (Text -> Maybe a -> SharedRep m (Maybe a)) -> Int -> [a] -> SharedRep m [Maybe a] -- | A SharedRep of [a]. Due to the applicative nature of the bridge, the -- size of lists has to be fixed on construction. listRep is a workaround -- for this, to enable some form of dynamic sizing. listRep :: Monad m => Maybe Text -> Text -> (Bool -> SharedRep m Bool) -> (a -> SharedRep m a) -> Int -> a -> [a] -> SharedRep m [a] -- | Parse from a textbox -- -- Uses focusout so as not to spam the reader. readTextbox :: (Monad m, Read a, Show a) => Maybe Text -> a -> SharedRep m (Either Text a) defaultListLabels :: Int -> [Text] repChoice :: Monad m => Int -> [(Text, SharedRep m a)] -> SharedRep m a subtype :: With a => a -> Text -> Text -> a -- | select test keys from a Map selectItems :: [Text] -> HashMap Text a -> [(Text, a)] -- | rep of multiple items list repItemsSelect :: Monad m => [Text] -> [Text] -> SharedRep m [Text] -- | A socket between a web page and haskell, based on the box library. module Web.Rep.Socket socketPage :: Page serveSocketBox :: SocketConfig -> Page -> Box IO Text Text -> IO () sharedServer :: SharedRep IO a -> SocketConfig -> Page -> (Html () -> [Code]) -> (Either Text a -> IO [Code]) -> IO () defaultSharedServer :: Show a => SharedRep IO a -> IO () data SocketConfig SocketConfig :: Text -> Int -> Text -> SocketConfig [host] :: SocketConfig -> Text [port] :: SocketConfig -> Int [path] :: SocketConfig -> Text defaultSocketConfig :: SocketConfig defaultSocketPage :: Page defaultInputCode :: Html () -> [Code] defaultOutputCode :: (Monad m, Show a) => Either Text a -> m [Code] data Code Replace :: Text -> Text -> Code Append :: Text -> Text -> Code Console :: Text -> Code Eval :: Text -> Code Val :: Text -> Code code :: Code -> Text instance GHC.Read.Read Web.Rep.Socket.Code instance GHC.Generics.Generic Web.Rep.Socket.Code instance GHC.Show.Show Web.Rep.Socket.Code instance GHC.Classes.Eq Web.Rep.Socket.Code -- | A haskell library for representing web pages. -- -- This library is a collection of web page abstractions, together with a -- reimagining of suavemente. -- -- I wanted to expose the server delivery mechanism, switch the streaming -- nature of the gap between a web page and a haskell server, and -- concentrate on getting a clean interface between pure haskell and the -- world that is a web page. -- -- See app/examples.hs and Examples for usage. module Web.Rep -- | Information contained in a web page can usually be considered to be -- isomorphic to a map of named values - a HashMap. This is -- especially true when considering a differential of information -- contained in a web page. Looking at a page from the outside, it often -- looks like a streaming differential of a hashmap. -- -- RepF consists of an underlying value being represented, and, given a -- hashmap state, a way to produce a representation of the underlying -- value (or error), in another domain, together with the potential to -- alter the hashmap state. data RepF r a Rep :: r -> (HashMap Text Text -> (HashMap Text Text, Either Text a)) -> RepF r a [rep] :: RepF r a -> r [make] :: RepF r a -> HashMap Text Text -> (HashMap Text Text, Either Text a) -- | the common usage, where the representation domain is Html type Rep a = RepF (Html ()) a -- | stateful result of one step, given a RepF, and a monadic -- action. Useful for testing and for initialising a page. oneRep :: (Monad m, MonadIO m) => Rep a -> (Rep a -> HashMap Text Text -> m ()) -> StateT (HashMap Text Text) m (HashMap Text Text, Either Text a) -- | Driven by the architecture of the DOM, web page components are -- compositional, and tree-like, where components are often composed of -- other components, and values are thus shared across components. -- -- This is sometimes referred to as "observable sharing". See -- data-reify as another library that reifies this (pun intended), -- and provided the initial inspiration for this implementation. -- -- unshare should only be run once, which is a terrible flaw that might -- be fixed by linear types. newtype SharedRepF m r a SharedRep :: StateT (Int, HashMap Text Text) m (RepF r a) -> SharedRepF m r a [unshare] :: SharedRepF m r a -> StateT (Int, HashMap Text Text) m (RepF r a) -- | default representation type of Html () type SharedRep m a = SharedRepF m (Html ()) a -- | Compute the initial state of a SharedRep and then run an action once -- (see tests). runOnce :: Monad m => SharedRep m a -> (Html () -> HashMap Text Text -> m ()) -> m (HashMap Text Text, Either Text a) -- | compute the initial state of a SharedRep (testing) zeroState :: Monad m => SharedRep m a -> m (Html (), (HashMap Text Text, Either Text a)) -- | Create a sharedRep register :: Monad m => (Text -> Either Text a) -> (a -> Text) -> (Text -> a -> r) -> a -> SharedRepF m r a -- | name supply for elements of a SharedRepF genName :: MonadState Int m => m Text -- | sometimes a number doesn't work properly in html (or js???), and an -- alpha prefix seems to help genNamePre :: MonadState Int m => Text -> m Text -- | Components of a web page. -- -- A web page can take many forms but still have the same underlying -- representation. For example, CSS can be linked to in a separate file, -- or can be inline within html, but still be the same css and have the -- same expected external effect. A Page represents the practical -- components of what makes up a static snapshot of a web page. data Page Page :: [Html ()] -> [Html ()] -> RepCss -> RepJs -> RepJs -> Html () -> Html () -> Page -- | css library links [libsCss] :: Page -> [Html ()] -- | javascript library links [libsJs] :: Page -> [Html ()] -- | css [cssBody] :: Page -> RepCss -- | javascript with global scope [jsGlobal] :: Page -> RepJs -- | javascript included within the onLoad function [jsOnLoad] :: Page -> RepJs -- | html within the header [htmlHeader] :: Page -> Html () -- | body html [htmlBody] :: Page -> Html () -- | Configuration options when rendering a Page. data PageConfig PageConfig :: PageConcerns -> PageStructure -> PageRender -> Concerns FilePath -> [FilePath] -> PageConfig [concerns] :: PageConfig -> PageConcerns [structure] :: PageConfig -> PageStructure [pageRender] :: PageConfig -> PageRender [filenames] :: PageConfig -> Concerns FilePath [localdirs] :: PageConfig -> [FilePath] -- | Default configuration is inline ecma and css, separate html header and -- body, minified code, with the suggested filename prefix. defaultPageConfig :: FilePath -> PageConfig -- | A web page typically is composed of some css, javascript and html. -- -- Concerns abstracts this structural feature of a web page. data Concerns a Concerns :: a -> a -> a -> Concerns a [cssConcern] :: Concerns a -> a [jsConcern] :: Concerns a -> a [htmlConcern] :: Concerns a -> a -- | The common file suffixes of the three concerns. suffixes :: Concerns FilePath -- | Create filenames for each Concern element. concernNames :: FilePath -> FilePath -> Concerns FilePath -- | Is the rendering to include all Concerns (typically in a html -- file) or be separated (tyypically into separate files and linked in -- the html file)? data PageConcerns Inline :: PageConcerns Separated :: PageConcerns -- | Various ways that a Html file can be structured. data PageStructure HeaderBody :: PageStructure Headless :: PageStructure Snippet :: PageStructure Svg :: PageStructure -- | Post-processing of page concerns data PageRender Pretty :: PageRender Minified :: PageRender NoPost :: PageRender -- | The Css context is used to collect style rules which are -- mappings from selectors to style properties. The Css type is a -- computation in the StyleM monad that just collects and doesn't -- return anything. type Css = StyleM () -- | Unifies css as either a Css or as Text. data RepCss RepCss :: Css -> RepCss RepCssText :: Text -> RepCss -- | Render Css as text. renderCss :: Css -> Text -- | Render RepCss as text. renderRepCss :: PageRender -> RepCss -> Text -- | wrapper for JSAST newtype JS JS :: JSAST -> JS [unJS] :: JS -> JSAST -- | Unifies javascript as JSStatement and script as Text. data RepJs RepJs :: JS -> RepJs RepJsText :: Text -> RepJs -- | Wrap js in standard DOM window loader. onLoad :: RepJs -> RepJs -- | Render RepJs as Text. renderRepJs :: PageRender -> RepJs -> Text -- | Convert Text to JS, throwing an error on incorrectness. parseJs :: Text -> JS -- | Render JS as Text. renderJs :: JS -> Text -- | A map from keys to values. A map cannot contain duplicate keys; each -- key can map to at most one value. data HashMap k v module Web.Rep.Examples -- | simple page example page1 :: Page -- | page with localised libraries page2 :: Page -- | simple mathjax formulae pagemj :: Page cfg2 :: PageConfig -- | One of each sharedrep input instances. data RepExamples RepExamples :: Text -> Text -> Int -> Double -> Bool -> Bool -> Int -> [Int] -> Shape -> Text -> RepExamples [repTextbox] :: RepExamples -> Text [repTextarea] :: RepExamples -> Text [repSliderI] :: RepExamples -> Int [repSlider] :: RepExamples -> Double [repCheckbox] :: RepExamples -> Bool [repToggle] :: RepExamples -> Bool [repDropdown] :: RepExamples -> Int [repDropdownMultiple] :: RepExamples -> [Int] [repShape] :: RepExamples -> Shape [repColor] :: RepExamples -> Text -- | one of each input SharedReps repExamples :: Monad m => SharedRep m RepExamples -- | For a typed dropdown example. data Shape SquareShape :: Shape CircleShape :: Shape -- | shape printer fromShape :: Shape -> Text -- | shape parser toShape :: Text -> Shape data SumTypeExample SumInt :: Int -> SumTypeExample SumOnly :: SumTypeExample SumText :: Text -> SumTypeExample repSumTypeExample :: Monad m => Int -> Text -> SumTypeExample -> SharedRep m SumTypeExample data SumType2Example SumOutside :: Int -> SumType2Example SumInside :: SumTypeExample -> SumType2Example repSumType2Example :: Monad m => Int -> Text -> SumTypeExample -> SumType2Example -> SharedRep m SumType2Example listExample :: Monad m => Int -> SharedRep m [Int] listRepExample :: Monad m => Int -> SharedRep m [Int] fiddleExample :: Concerns Text instance GHC.Generics.Generic Web.Rep.Examples.SumType2Example instance GHC.Show.Show Web.Rep.Examples.SumType2Example instance GHC.Classes.Eq Web.Rep.Examples.SumType2Example instance GHC.Generics.Generic Web.Rep.Examples.SumTypeExample instance GHC.Show.Show Web.Rep.Examples.SumTypeExample instance GHC.Classes.Eq Web.Rep.Examples.SumTypeExample instance GHC.Generics.Generic Web.Rep.Examples.RepExamples instance GHC.Classes.Eq Web.Rep.Examples.RepExamples instance GHC.Show.Show Web.Rep.Examples.RepExamples instance GHC.Generics.Generic Web.Rep.Examples.Shape instance GHC.Show.Show Web.Rep.Examples.Shape instance GHC.Classes.Eq Web.Rep.Examples.Shape