-- 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.3.0 -- | Key generators and miscellaneous html utilities. -- -- Uses the lucid Html. module Web.Page.Html -- | FIXME: A horrible hack to separate class id's class__ :: Text -> Attribute -- | Convert html to text toText :: Html a -> Text -- | name supply for html elements 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 -- | 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 () -- | convert from #xxxxxx to PixelRGB8 fromHex :: Parser PixelRGB8 -- | convert from PixelRGB8 to #xxxxxx toHex :: PixelRGB8 -> Text -- | 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 Codec.Picture.Types.PixelRGB8 instance Lucid.Base.ToHtml () -- | Common web page input elements, often with bootstrap scaffolding. module Web.Page.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 TextArea :: Int -> InputType ColorPicker :: InputType ChooseFile :: InputType Dropdown :: [Text] -> InputType DropdownSum :: [Text] -> InputType Datalist :: [Text] -> Text -> InputType Checkbox :: Bool -> InputType Toggle :: Bool -> Maybe Text -> InputType Button :: InputType instance GHC.Generics.Generic (Web.Page.Html.Input.Input a) instance GHC.Show.Show a => GHC.Show.Show (Web.Page.Html.Input.Input a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Web.Page.Html.Input.Input a) instance GHC.Generics.Generic Web.Page.Html.Input.InputType instance GHC.Show.Show Web.Page.Html.Input.InputType instance GHC.Classes.Eq Web.Page.Html.Input.InputType instance Lucid.Base.ToHtml a => Lucid.Base.ToHtml (Web.Page.Html.Input.Input a) -- | Page rendering module Web.Page.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.Page.Server -- | serve a Page via a ScottyM servePageWith :: RoutePattern -> PageConfig -> Page -> ScottyM () -- | 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.Page.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 -- | A streaming bridge between a web page and haskell. module Web.Page.Bridge -- | componentry to kick off a javascript-bridge enabled page bridgePage :: Page -- | append to a container and run any embedded scripts append :: Engine -> Text -> Text -> IO () -- | replace a container and run any embedded scripts replace :: Engine -> Text -> Text -> IO () -- | The javascript bridge continuation. bridge :: Engine -> Cont_ IO Value -- | send css, js and html over the bridge sendConcerns :: Engine -> Text -> Concerns Text -> IO () -- | An Engine is a handle to a specific JavaScript engine data Engine -- | This accepts WebSocket requests, calls the callback with an -- Engine that can be used to access JavaScript. start :: (Engine -> IO ()) -> Application -> Application -- | The WAI application. -- -- Note that, since WAI 3.0, this type is structured in continuation -- passing style to allow for proper safe resource handling. This was -- handled in the past via other means (e.g., ResourceT). As a -- demonstration: -- --
-- app :: Application -- app req respond = bracket_ -- (putStrLn "Allocating scarce resource") -- (putStrLn "Cleaning up") -- (respond $ responseLBS status200 [] "Hello World") --type Application = Request -> Response -> IO ResponseReceived -> IO ResponseReceived -- | consume an Element using a Committer and a Value continuation valueConsume :: s -> (Element -> s -> s) -> Cont IO (Committer IO (Either Text s)) -> Cont_ IO Value -> IO s -- | consume shared values using a step function, a continuation committer, -- and a Value continuation. sharedConsume :: (s -> (s, Either Text b)) -> s -> (Element -> s -> s) -> Cont IO (Committer IO (Either Text (s, Either Text b))) -> Cont_ IO Value -> IO s -- | process a list of Values runList :: Monad m => SharedRep m a -> [Value] -> m [Either Text (HashMap Text Text, Either Text a)] -- | run a SharedRep using an initial state, a step function that consumes -- the shared model, and a value continuation runOnEvent :: SharedRep IO a -> (Rep a -> StateT (Int, HashMap Text Text) IO ()) -> (Either Text (HashMap Text Text, Either Text a) -> IO ()) -> Cont_ IO Value -> IO (HashMap Text Text) -- | create Wai Middleware for a SharedRepF providing an initialiser -- and action on events midShared :: () => SharedRep IO a -> (Engine -> Rep a -> StateT (HashMap Text Text) IO ()) -> (Engine -> Either Text (HashMap Text Text, Either Text a) -> IO ()) -> Application -> Application -- | Some bootstrap assets and functionality. module Web.Page.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.Page.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, 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 -- | 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 -- | color input colorPicker :: Monad m => Maybe Text -> PixelRGB8 -> SharedRep m PixelRGB8 -- | 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] defaultListLabels :: Int -> [Text] -- | 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.Page -- | 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. newtype SharedRepF m r a SharedRep :: StateT (Int, HashMap Text Text) m (RepF r a) -> SharedRepF m r a [unrep] :: 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 -- | A key-value Text pair as the realistic datatype that zips across the -- interface between a page and haskell. data Element Element :: Text -> Text -> Element [element] :: Element -> Text [value] :: Element -> Text -- | 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)) -- | 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 ()] -> PageCss -> PageJs -> PageJs -> Html () -> Html () -> Page -- | css library links [libsCss] :: Page -> [Html ()] -- | javascript library links [libsJs] :: Page -> [Html ()] -- | css [cssBody] :: Page -> PageCss -- | javascript with global scope [jsGlobal] :: Page -> PageJs -- | javascript included within the onLoad function [jsOnLoad] :: Page -> PageJs -- | 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 PageCss PageCss :: Css -> PageCss PageCssText :: Text -> PageCss -- | Render Css as text. renderCss :: Css -> Text -- | Render PageCss as text. renderPageCss :: PageRender -> PageCss -> Text -- | wrapper for JSAST newtype JS JS :: JSAST -> JS [unJS] :: JS -> JSAST -- | Unifies javascript as JSStatement and script as Text. data PageJs PageJs :: JS -> PageJs PageJsText :: Text -> PageJs -- | Wrap js in standard DOM window loader. onLoad :: PageJs -> PageJs -- | Render PageJs as Text. renderPageJs :: PageRender -> PageJs -> Text -- | Convert Text to JS, throwing an error on incorrectness. parseJs :: Text -> JS -- | Render JS as Text. renderJs :: JS -> Text -- | A JSON value represented as a Haskell value. data Value Object :: !Object -> Value Array :: !Array -> Value String :: !Text -> Value Number :: !Scientific -> Value Bool :: !Bool -> Value Null :: Value -- | A specialised variant of bracket with just a computation to run -- afterward. finally :: () => IO a -> IO b -> IO a -- | Classic pixel type storing 8bit red, green and blue (RGB) information. -- Values are stored in the following order: -- --
-- >>> void Nothing -- Nothing -- -- >>> void (Just 3) -- Just () ---- -- Replace the contents of an Either Int -- Int with unit, resulting in an Either -- Int '()': -- --
-- >>> void (Left 8675309) -- Left 8675309 -- -- >>> void (Right 8675309) -- Right () ---- -- Replace every element of a list with unit: -- --
-- >>> void [1,2,3] -- [(),(),()] ---- -- Replace the second element of a pair with unit: -- --
-- >>> void (1,2) -- (1,()) ---- -- Discard the result of an IO action: -- --
-- >>> mapM print [1,2] -- 1 -- 2 -- [(),()] -- -- >>> void $ mapM print [1,2] -- 1 -- 2 --void :: Functor f => f a -> f () -- | Evaluate each action in the structure from left to right, and ignore -- the results. For a version that doesn't ignore the results see -- sequenceA. sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f () -- | A space efficient, packed, unboxed Unicode text type. data Text -- | O(n) Convert a String into a Text. Subject to -- fusion. Performs replacement on invalid scalar values. pack :: String -> Text -- | O(n) Convert a Text into a String. Subject to -- fusion. unpack :: Text -> String -- | Case analysis for the Bool type. bool x y p -- evaluates to x when p is False, and evaluates -- to y when p is True. -- -- This is equivalent to if p then y else x; that is, one can -- think of it as an if-then-else construct with its arguments reordered. -- --
-- >>> bool "foo" "bar" True -- "bar" -- -- >>> bool "foo" "bar" False -- "foo" ---- -- Confirm that bool x y p and if p then y else -- x are equivalent: -- --
-- >>> let p = True; x = "bar"; y = "foo" -- -- >>> bool x y p == if p then y else x -- True -- -- >>> let p = False -- -- >>> bool x y p == if p then y else x -- True --bool :: () => a -> a -> Bool -> a module Web.Page.Examples -- | simple page example page1 :: Page -- | page with localised libraries page2 :: Page -- | simple mathjax formulae pagemj :: Page -- | simple mathjax formulae inside an svg text element pagemjsvg :: Page cfg2 :: PageConfig -- | One of each sharedrep input instances. data RepExamples RepExamples :: Text -> Text -> Int -> Double -> Bool -> Bool -> Int -> Shape -> PixelRGB8 -> RepExamples [repTextbox] :: RepExamples -> Text [repTextarea] :: RepExamples -> Text [repSliderI] :: RepExamples -> Int [repSlider] :: RepExamples -> Double [repCheckbox] :: RepExamples -> Bool [repToggle] :: RepExamples -> Bool [repDropdown] :: RepExamples -> Int [repShape] :: RepExamples -> Shape [repColor] :: RepExamples -> PixelRGB8 -- | 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.Page.Examples.SumType2Example instance GHC.Show.Show Web.Page.Examples.SumType2Example instance GHC.Classes.Eq Web.Page.Examples.SumType2Example instance GHC.Generics.Generic Web.Page.Examples.SumTypeExample instance GHC.Show.Show Web.Page.Examples.SumTypeExample instance GHC.Classes.Eq Web.Page.Examples.SumTypeExample instance GHC.Generics.Generic Web.Page.Examples.RepExamples instance GHC.Classes.Eq Web.Page.Examples.RepExamples instance GHC.Show.Show Web.Page.Examples.RepExamples instance GHC.Generics.Generic Web.Page.Examples.Shape instance GHC.Show.Show Web.Page.Examples.Shape instance GHC.Classes.Eq Web.Page.Examples.Shape