plzwrk 0.0.0.8 → 0.0.0.9
raw patch · 19 files changed
+1408/−2266 lines, 19 filesdep −neat-interpolationPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: neat-interpolation
API changes (from Hackage documentation)
- Web.Framework.Plzwrk: Browserful :: (jsval -> IO (Maybe [jsval])) -> (jsval -> IO (Maybe Bool)) -> (jsval -> IO (Maybe ByteString)) -> (jsval -> IO (Maybe Double)) -> (jsval -> IO (Maybe Int)) -> (jsval -> IO (Maybe String)) -> (jsval -> IO ()) -> RequestInit jsval -> IO jsval -> (String -> IO jsval) -> (String -> IO jsval) -> (String -> IO (Maybe jsval)) -> IO jsval -> (String -> RequestInit jsval -> IO jsval) -> (jsval -> String -> IO (Maybe jsval)) -> (jsval -> String -> IO jsval) -> (jsval -> String -> jsval -> IO jsval) -> (jsval -> String -> jsval -> jsval -> IO jsval) -> ([jsval] -> IO jsval) -> (Bool -> IO jsval) -> (ByteString -> IO jsval) -> (Double -> IO jsval) -> (Int -> IO jsval) -> (String -> IO jsval) -> IO jsval -> IO Double -> (jsval -> String -> jsval -> IO ()) -> (jsval -> IO ()) -> ((jsval -> IO ()) -> IO jsval) -> Browserful jsval
- Web.Framework.Plzwrk: [_makeHaskellCallback] :: Browserful jsval -> (jsval -> IO ()) -> IO jsval
- Web.Framework.Plzwrk: data Browserful jsval
- Web.Framework.Plzwrk.MockJSVal: MockJSFunction :: Int -> (MockJSVal -> IO ()) -> [LogEvent] -> MockJSVal
- Web.Framework.Plzwrk.Tag: _datalist :: AFSig s opq
- Web.Framework.Plzwrk.Tag: _datalist' :: Sig s opq
- Web.Framework.Plzwrk.Tag: _datalist'_ :: Sig_ s opq
- Web.Framework.Plzwrk.Tag: _datalist'__ :: Sig__ s opq
- Web.Framework.Plzwrk.Tag: _datalist_ :: AFSig_ s opq
- Web.Framework.Plzwrk.Tag: _datalist__ :: AFSig__ s opq
+ Web.Framework.Plzwrk: JSEnv :: (jsval -> IO (Maybe [jsval])) -> (jsval -> IO (Maybe Bool)) -> (jsval -> IO (Maybe ByteString)) -> (jsval -> IO (Maybe Double)) -> (jsval -> IO (Maybe Int)) -> (jsval -> IO (Maybe String)) -> (jsval -> IO ()) -> RequestInit jsval -> IO jsval -> (String -> IO jsval) -> (String -> IO jsval) -> (String -> IO (Maybe jsval)) -> IO jsval -> (String -> RequestInit jsval -> IO jsval) -> (jsval -> String -> IO (Maybe jsval)) -> (jsval -> String -> IO jsval) -> (jsval -> String -> jsval -> IO jsval) -> (jsval -> String -> jsval -> jsval -> IO jsval) -> ([jsval] -> IO jsval) -> (Bool -> IO jsval) -> (ByteString -> IO jsval) -> (Double -> IO jsval) -> (Int -> IO jsval) -> (String -> IO jsval) -> IO jsval -> IO Double -> (jsval -> String -> jsval -> IO ()) -> (jsval -> IO ()) -> ((jsval -> IO ()) -> IO jsval) -> ((jsval -> jsval -> IO ()) -> IO jsval) -> ((jsval -> jsval -> jsval -> IO ()) -> IO jsval) -> JSEnv jsval
+ Web.Framework.Plzwrk: [_makeHaskellCallback1] :: JSEnv jsval -> (jsval -> IO ()) -> IO jsval
+ Web.Framework.Plzwrk: [_makeHaskellCallback2] :: JSEnv jsval -> (jsval -> jsval -> IO ()) -> IO jsval
+ Web.Framework.Plzwrk: [_makeHaskellCallback3] :: JSEnv jsval -> (jsval -> jsval -> jsval -> IO ()) -> IO jsval
+ Web.Framework.Plzwrk: data JSEnv jsval
+ Web.Framework.Plzwrk.MockJSVal: MockJSFunction1 :: Int -> (MockJSVal -> IO ()) -> [LogEvent] -> MockJSVal
+ Web.Framework.Plzwrk.MockJSVal: MockJSFunction2 :: Int -> (MockJSVal -> MockJSVal -> IO ()) -> [LogEvent] -> MockJSVal
+ Web.Framework.Plzwrk.MockJSVal: MockJSFunction3 :: Int -> (MockJSVal -> MockJSVal -> MockJSVal -> IO ()) -> [LogEvent] -> MockJSVal
+ Web.Framework.Plzwrk.Tag: datalist :: AFSig s opq
+ Web.Framework.Plzwrk.Tag: datalist' :: Sig s opq
+ Web.Framework.Plzwrk.Tag: datalist'_ :: Sig_ s opq
+ Web.Framework.Plzwrk.Tag: datalist'__ :: Sig__ s opq
+ Web.Framework.Plzwrk.Tag: datalist_ :: AFSig_ s opq
+ Web.Framework.Plzwrk.Tag: datalist__ :: AFSig__ s opq
- Web.Framework.Plzwrk: [_freeCallback] :: Browserful jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: [_freeCallback] :: JSEnv jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: [castToArray] :: Browserful jsval -> jsval -> IO (Maybe [jsval])
+ Web.Framework.Plzwrk: [castToArray] :: JSEnv jsval -> jsval -> IO (Maybe [jsval])
- Web.Framework.Plzwrk: [castToBool] :: Browserful jsval -> jsval -> IO (Maybe Bool)
+ Web.Framework.Plzwrk: [castToBool] :: JSEnv jsval -> jsval -> IO (Maybe Bool)
- Web.Framework.Plzwrk: [castToByteString] :: Browserful jsval -> jsval -> IO (Maybe ByteString)
+ Web.Framework.Plzwrk: [castToByteString] :: JSEnv jsval -> jsval -> IO (Maybe ByteString)
- Web.Framework.Plzwrk: [castToDouble] :: Browserful jsval -> jsval -> IO (Maybe Double)
+ Web.Framework.Plzwrk: [castToDouble] :: JSEnv jsval -> jsval -> IO (Maybe Double)
- Web.Framework.Plzwrk: [castToInt] :: Browserful jsval -> jsval -> IO (Maybe Int)
+ Web.Framework.Plzwrk: [castToInt] :: JSEnv jsval -> jsval -> IO (Maybe Int)
- Web.Framework.Plzwrk: [castToString] :: Browserful jsval -> jsval -> IO (Maybe String)
+ Web.Framework.Plzwrk: [castToString] :: JSEnv jsval -> jsval -> IO (Maybe String)
- Web.Framework.Plzwrk: [consoleLog] :: Browserful jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: [consoleLog] :: JSEnv jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: [defaultRequestInit] :: Browserful jsval -> RequestInit jsval
+ Web.Framework.Plzwrk: [defaultRequestInit] :: JSEnv jsval -> RequestInit jsval
- Web.Framework.Plzwrk: [documentBody] :: Browserful jsval -> IO jsval
+ Web.Framework.Plzwrk: [documentBody] :: JSEnv jsval -> IO jsval
- Web.Framework.Plzwrk: [documentCreateElement] :: Browserful jsval -> String -> IO jsval
+ Web.Framework.Plzwrk: [documentCreateElement] :: JSEnv jsval -> String -> IO jsval
- Web.Framework.Plzwrk: [documentCreateTextNode] :: Browserful jsval -> String -> IO jsval
+ Web.Framework.Plzwrk: [documentCreateTextNode] :: JSEnv jsval -> String -> IO jsval
- Web.Framework.Plzwrk: [documentGetElementById] :: Browserful jsval -> String -> IO (Maybe jsval)
+ Web.Framework.Plzwrk: [documentGetElementById] :: JSEnv jsval -> String -> IO (Maybe jsval)
- Web.Framework.Plzwrk: [documentHead] :: Browserful jsval -> IO jsval
+ Web.Framework.Plzwrk: [documentHead] :: JSEnv jsval -> IO jsval
- Web.Framework.Plzwrk: [fetch] :: Browserful jsval -> String -> RequestInit jsval -> IO jsval
+ Web.Framework.Plzwrk: [fetch] :: JSEnv jsval -> String -> RequestInit jsval -> IO jsval
- Web.Framework.Plzwrk: [getPropertyAsOpaque] :: Browserful jsval -> jsval -> String -> IO (Maybe jsval)
+ Web.Framework.Plzwrk: [getPropertyAsOpaque] :: JSEnv jsval -> jsval -> String -> IO (Maybe jsval)
- Web.Framework.Plzwrk: [invokeOn0] :: Browserful jsval -> jsval -> String -> IO jsval
+ Web.Framework.Plzwrk: [invokeOn0] :: JSEnv jsval -> jsval -> String -> IO jsval
- Web.Framework.Plzwrk: [invokeOn1] :: Browserful jsval -> jsval -> String -> jsval -> IO jsval
+ Web.Framework.Plzwrk: [invokeOn1] :: JSEnv jsval -> jsval -> String -> jsval -> IO jsval
- Web.Framework.Plzwrk: [invokeOn2] :: Browserful jsval -> jsval -> String -> jsval -> jsval -> IO jsval
+ Web.Framework.Plzwrk: [invokeOn2] :: JSEnv jsval -> jsval -> String -> jsval -> jsval -> IO jsval
- Web.Framework.Plzwrk: [jsValFromArray] :: Browserful jsval -> [jsval] -> IO jsval
+ Web.Framework.Plzwrk: [jsValFromArray] :: JSEnv jsval -> [jsval] -> IO jsval
- Web.Framework.Plzwrk: [jsValFromBool] :: Browserful jsval -> Bool -> IO jsval
+ Web.Framework.Plzwrk: [jsValFromBool] :: JSEnv jsval -> Bool -> IO jsval
- Web.Framework.Plzwrk: [jsValFromByteString] :: Browserful jsval -> ByteString -> IO jsval
+ Web.Framework.Plzwrk: [jsValFromByteString] :: JSEnv jsval -> ByteString -> IO jsval
- Web.Framework.Plzwrk: [jsValFromDouble] :: Browserful jsval -> Double -> IO jsval
+ Web.Framework.Plzwrk: [jsValFromDouble] :: JSEnv jsval -> Double -> IO jsval
- Web.Framework.Plzwrk: [jsValFromInt] :: Browserful jsval -> Int -> IO jsval
+ Web.Framework.Plzwrk: [jsValFromInt] :: JSEnv jsval -> Int -> IO jsval
- Web.Framework.Plzwrk: [jsValFromString] :: Browserful jsval -> String -> IO jsval
+ Web.Framework.Plzwrk: [jsValFromString] :: JSEnv jsval -> String -> IO jsval
- Web.Framework.Plzwrk: [makeObject] :: Browserful jsval -> IO jsval
+ Web.Framework.Plzwrk: [makeObject] :: JSEnv jsval -> IO jsval
- Web.Framework.Plzwrk: [mathRandom] :: Browserful jsval -> IO Double
+ Web.Framework.Plzwrk: [mathRandom] :: JSEnv jsval -> IO Double
- Web.Framework.Plzwrk: [setValue] :: Browserful jsval -> jsval -> String -> jsval -> IO ()
+ Web.Framework.Plzwrk: [setValue] :: JSEnv jsval -> jsval -> String -> jsval -> IO ()
- Web.Framework.Plzwrk: consoleLogS :: Browserful jsval -> String -> IO ()
+ Web.Framework.Plzwrk: consoleLogS :: JSEnv jsval -> String -> IO ()
- Web.Framework.Plzwrk: elementSetAttribute :: Browserful jsval -> jsval -> String -> String -> IO ()
+ Web.Framework.Plzwrk: elementSetAttribute :: JSEnv jsval -> jsval -> String -> String -> IO ()
- Web.Framework.Plzwrk: elementTagName :: Browserful jsval -> jsval -> IO (Maybe String)
+ Web.Framework.Plzwrk: elementTagName :: JSEnv jsval -> jsval -> IO (Maybe String)
- Web.Framework.Plzwrk: eventPreventDefault :: Browserful jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: eventPreventDefault :: JSEnv jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: eventTargetAddEventListener :: Browserful jsval -> jsval -> String -> jsval -> IO ()
+ Web.Framework.Plzwrk: eventTargetAddEventListener :: JSEnv jsval -> jsval -> String -> jsval -> IO ()
- Web.Framework.Plzwrk: eventTargetBlur :: Browserful jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: eventTargetBlur :: JSEnv jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: eventTargetRemoveEventListener :: Browserful jsval -> jsval -> String -> jsval -> IO ()
+ Web.Framework.Plzwrk: eventTargetRemoveEventListener :: JSEnv jsval -> jsval -> String -> jsval -> IO ()
- Web.Framework.Plzwrk: eventTargetValue :: Browserful jsval -> jsval -> IO (Maybe String)
+ Web.Framework.Plzwrk: eventTargetValue :: JSEnv jsval -> jsval -> IO (Maybe String)
- Web.Framework.Plzwrk: getPropertyAsBool :: Browserful jsval -> jsval -> String -> IO (Maybe Bool)
+ Web.Framework.Plzwrk: getPropertyAsBool :: JSEnv jsval -> jsval -> String -> IO (Maybe Bool)
- Web.Framework.Plzwrk: getPropertyAsDouble :: Browserful jsval -> jsval -> String -> IO (Maybe Double)
+ Web.Framework.Plzwrk: getPropertyAsDouble :: JSEnv jsval -> jsval -> String -> IO (Maybe Double)
- Web.Framework.Plzwrk: getPropertyAsInt :: Browserful jsval -> jsval -> String -> IO (Maybe Int)
+ Web.Framework.Plzwrk: getPropertyAsInt :: JSEnv jsval -> jsval -> String -> IO (Maybe Int)
- Web.Framework.Plzwrk: getPropertyAsString :: Browserful jsval -> jsval -> String -> IO (Maybe String)
+ Web.Framework.Plzwrk: getPropertyAsString :: JSEnv jsval -> jsval -> String -> IO (Maybe String)
- Web.Framework.Plzwrk: htmlElemenetClick :: Browserful jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: htmlElemenetClick :: JSEnv jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: nodeAppendChild :: Browserful jsval -> jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: nodeAppendChild :: JSEnv jsval -> jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: nodeChildNodes :: Browserful jsval -> jsval -> IO (Maybe [jsval])
+ Web.Framework.Plzwrk: nodeChildNodes :: JSEnv jsval -> jsval -> IO (Maybe [jsval])
- Web.Framework.Plzwrk: nodeInsertBefore :: Browserful jsval -> jsval -> jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: nodeInsertBefore :: JSEnv jsval -> jsval -> jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: nodeRemoveChild :: Browserful jsval -> jsval -> jsval -> IO ()
+ Web.Framework.Plzwrk: nodeRemoveChild :: JSEnv jsval -> jsval -> jsval -> IO ()
- Web.Framework.Plzwrk: nodeTextContent :: Browserful jsval -> jsval -> IO (Maybe String)
+ Web.Framework.Plzwrk: nodeTextContent :: JSEnv jsval -> jsval -> IO (Maybe String)
- Web.Framework.Plzwrk: plzwrk :: (state -> PwNode state jsval) -> state -> Browserful jsval -> String -> IO ()
+ Web.Framework.Plzwrk: plzwrk :: (state -> PwNode state jsval) -> state -> JSEnv jsval -> String -> IO ()
- Web.Framework.Plzwrk: plzwrk' :: (state -> PwNode state jsval) -> state -> Browserful jsval -> IO ()
+ Web.Framework.Plzwrk: plzwrk' :: (state -> PwNode state jsval) -> state -> JSEnv jsval -> IO ()
- Web.Framework.Plzwrk: plzwrk'_ :: (() -> PwNode () jsval) -> Browserful jsval -> IO ()
+ Web.Framework.Plzwrk: plzwrk'_ :: (() -> PwNode () jsval) -> JSEnv jsval -> IO ()
- Web.Framework.Plzwrk: plzwrkSSR :: (state -> PwNode state jsval) -> state -> Browserful jsval -> String -> IO ()
+ Web.Framework.Plzwrk: plzwrkSSR :: (state -> PwNode state jsval) -> state -> JSEnv jsval -> String -> IO ()
- Web.Framework.Plzwrk.MockJSVal: makeMockBrowser :: IO (Browserful Int)
+ Web.Framework.Plzwrk.MockJSVal: makeMockBrowser :: IO (JSEnv Int)
- Web.Framework.Plzwrk.MockJSVal: makeMockBrowserWithContext :: IORef MockBrowserInternal -> IO (Browserful Int)
+ Web.Framework.Plzwrk.MockJSVal: makeMockBrowserWithContext :: IORef MockBrowserInternal -> IO (JSEnv Int)
Files
- ChangeLog.md +5/−0
- README.md +6/−12
- hello-world/Main.hs +0/−19
- kitchen-sink/Main.hs +0/−342
- kitchen-sink/Nouns.hs +0/−519
- plzwrk.cabal +2/−39
- src/Web/Framework/Plzwrk.hs +2/−2
- src/Web/Framework/Plzwrk/Asterius.hs +25/−7
- src/Web/Framework/Plzwrk/Base.hs +8/−8
- src/Web/Framework/Plzwrk/Browserful.hs +0/−131
- src/Web/Framework/Plzwrk/Domify.hs +513/−524
- src/Web/Framework/Plzwrk/JSEnv.hs +137/−0
- src/Web/Framework/Plzwrk/MockJSVal.hs +109/−67
- src/Web/Framework/Plzwrk/TH/HSX.hs +4/−4
- src/Web/Framework/Plzwrk/TH/QuoteHSX.hs +9/−3
- src/Web/Framework/Plzwrk/Tag.hs +496/−496
- src/Web/Framework/Plzwrk/Util.hs +55/−56
- test/DOMSpec.hs +28/−28
- test/HSXSpec.hs +9/−9
ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for plzwrk +## 0.0.0.9++- Renames `Browserful` to `JSEnv`.+- Fixes garbage collection bug for callback functions.+ ## 0.0.0.8 - Fixes a bug in the HSX parser that rejected certain valid text nodes
README.md view
@@ -24,24 +24,18 @@ See it [live](https://plzwrk-kitchen-sink.surge.sh). -## Installation - -Add `plzwrk` to the `build-depends` stanza of your `.cabal` file. - -Also, add `plzwrk-X.Y.Z.?` to the `extra-deps` list of your `stack.yaml` file if you're using stack. - ## Making a webpage -`plzwrk` uses [Asterius](https://github.com/tweag/asterius) as its backend for web development. Compiling an application using `plzwrk` is no different than compiling an application using `ahc-cabal` and `ahc-dist` as described in the [Asterius documentation](https://asterius.netlify.app) with **one caveat**. You **must** use `--constraint "plzwrk +plzwrk-enable-asterius"` when running `ahc-cabal`. +`plzwrk` uses [Asterius](https://github.com/tweag/asterius) as its backend for web development. -A minimal flow is shown below, mostly copied from the asterius documentation. It assumes that you have a cabal-buildable project in the `pwd`. Note the use of the `--constraint "plzwrk +plzwrk-enable-asterius"` flag in the `ahc-cabal` step. +A minimal flow is shown below. It assumes that you have a file called `Main.hs` in the present working directory with a function `main :: IO ()` inside of it, not unlike the Hello World above. ```bash -username@hostname:~/my-dir$ docker run --rm -it -v $(pwd):/project -w /project terrorjack/asterius -asterius@hostname:/project$ ahc-cabal v2-update -asterius@hostname:/project$ ahc-cabal new-install --constraint "plzwrk +plzwrk-enable-asterius" --installdir <inst-dir> <exec-name> -asterius@hostname:/project$ cd <inst-dir> && ahc-dist --input-exe <exec-name> --browser --bundle +username@hostname:~/my-dir$ docker run --rm -it -v $(pwd):/project -w /project meeshkan/plzwrk +asterius@hostname:/project$ ahc-link --input-hs Main.hs --browser --bundle ``` + +If you're using `ahc-cabal`, compiling an application using `plzwrk` is no different than compiling an application as described in the [Asterius documentation](https://asterius.netlify.app) with **one caveat**. You **must** use `--constraint "plzwrk +plzwrk-enable-asterius"` when running `ahc-cabal`. ## Documentation
− hello-world/Main.hs
@@ -1,19 +0,0 @@-{-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} - -import Web.Framework.Plzwrk -#if defined(PLZWRK_ENABLE_ASTERIUS) -import Web.Framework.Plzwrk.Asterius -import Web.Framework.Plzwrk.Tag (p__) -#else -import Web.Framework.Plzwrk.MockJSVal -#endif - -main :: IO () -main = do -#if defined(PLZWRK_ENABLE_ASTERIUS) - browser <- asteriusBrowser -# else - browser <- makeMockBrowser -# endif - plzwrk'_ [hsx|<p>Hello world!</p>|] browser
− kitchen-sink/Main.hs
@@ -1,342 +0,0 @@-{-# LANGUAGE CPP #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE QuasiQuotes #-} - -#if defined(PLZWRK_ENABLE_ASTERIUS) -import Asterius.Types -import Web.Framework.Plzwrk.Asterius -# else -import Web.Framework.Plzwrk.MockJSVal -# endif - -import Control.Monad -import Data.HashMap.Strict hiding ( null ) -import Data.IORef -import NeatInterpolation -import qualified Data.Set as S -import qualified Data.Text as DT -import Nouns -import Prelude hiding ( div - , span - ) -import Web.Framework.Plzwrk -import Web.Framework.Plzwrk.Tag - hiding ( main - , main_ - , main'_ - ) -import qualified Web.Framework.Plzwrk.Tag as T - ( main - , main_ - , main'_ - ) -data MyState = MyState - { _name :: String - , _abstractToConcrete :: [(String, String)] - , _myNoun :: String - } - deriving Show - --- here is where we'll show our "surprise" aphorism -surprise = - (\noun -> if (length noun == 0) - then div'_ [] - else p'__ $ concat ["Life is like", indefiniteArticle noun, noun] - ) - <$> _myNoun - --- here is where we will input a noun for our "surprise" aphorosim -writeSomethingConcrete browser = input - [("type", pT "text"), ("style", pT "box-sizing:content-box"), ("input", - pF (\e s -> do - v <- (eventTargetValue browser) e - return $ maybe s (\q -> s { _myNoun = q }) v - ) - )] - [] - -aphorismList = - (\a2c -> ul' - [("class", pT "res")] - (fmap (\(a, c) -> (li__ (concat [a, " is like", indefiniteArticle c, c]))) - a2c - ) - ) - <$> _abstractToConcrete - -addAphorismButton browser = - (\a2c -> button' - [("id", pT "incr"), ("class", pT "dim"), ("click", - pF (\e s -> do - (eventTargetBlur browser) e - (consoleLogS browser) $ "Here is the current state " <> show s - concept <- randAbstract (mathRandom browser) - comparedTo <- randConcrete (mathRandom browser) - let newS = s { _abstractToConcrete = (concept, comparedTo) : a2c } - (consoleLogS browser) $ "Here is the new state " <> show newS - return $ newS - ) - )] - [txt "More aphorisms"] - ) - <$> _abstractToConcrete - -removeAphorismButton browser = - (\a2c -> button' - [("id", pT "decr"), ("class", pT "dim"), ("click", pF - (\e s -> do - (eventTargetBlur browser) e - pure $ s { _abstractToConcrete = if null a2c then [] else tail a2c } - ) - )] - [txt "Less aphorisms"] - ) - <$> _abstractToConcrete - -loginText = - (\name -> p'_ [txt "Logged in as: ", span [("class", pT "username")] [txt name]]) - <$> _name - -main :: IO () -main = do - -#if defined(PLZWRK_ENABLE_ASTERIUS) - browser <- asteriusBrowser -# else - browser <- makeMockBrowser -# endif - -- add some css! - _head <- (documentHead browser) - _style <- (documentCreateElement browser) "style" - _css <- (documentCreateTextNode browser) (DT.unpack myCss) - (nodeAppendChild browser) _style _css - (nodeAppendChild browser) _head _style - -- and here is our main div - let mainDivF = T.main_ - [ section - [("class", pT "content")] - [ h1__ "Aphorism Machine" - , aphorismList - , br - , surprise - , div [("style", pT "width:100%;display:inline-block")] - [addAphorismButton browser, removeAphorismButton browser] - , writeSomethingConcrete browser - , loginText - ] - ] - let state = MyState "Bob" [] "" - plzwrk' mainDivF state browser - - -randFromList :: [String] -> IO Double -> IO String -randFromList l f = do - z <- f - let i = round $ (fromIntegral $ length l) * z - return $ l !! i - - -indefiniteArticle :: String -> String -indefiniteArticle x = - let hd = take 1 x - in if (hd == "a" || hd == "e" || hd == "i" || hd == "o" || hd == "u") - then " an " - else " a " - -randAbstract :: IO Double -> IO String -randAbstract = randFromList abstract - -randConcrete :: IO Double -> IO String -randConcrete = randFromList concrete - -myCss = [text| -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; -} - -html, -body { - height: 100%; -} - -body>div:first-child, -body>div:first-child>div:first-child, -body>div:first-child>div:first-child>div { - height: inherit; -} - -input { - box-sizing: border-box; - padding: 9.5px 15px; - border: 0; - text-align: center; - border-bottom: 1px solid #d8d8d8; - font-size: 14px; - transition: border-bottom-color 100ms ease-in, color 100ms ease-in; - max-width: 250px; - border-radius: 0; -} - -input:focus { - outline: none; - border-color: #000; -} - -.dim { - opacity: 1; - transition: opacity .15s ease-in; - cursor: pointer; -} -.dim:hover, -.dim:focus { - opacity: .5; - transition: opacity .15s ease-in; -} -.dim:active { - opacity: .8; - transition: opacity .15s ease-out; -} - -@media (min-width: 768px) { - input { - min-width: 300px; - max-width: 620px; - } -} - -ul { - list-style: none; - padding-left: 0; -} - -hr { - margin-top: 15px; - margin-bottom: 15px; - width: 70%; -} - -main { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - padding: 20px; - box-sizing: border-box; - flex-direction: column; -} - -.content { - text-align: center; - max-width: 100%; - -webkit-animation: fadein 2s; - -moz-animation: fadein 2s; - -ms-animation: fadein 2s; - -o-animation: fadein 2s; - animation: fadein 2s; -} - -h1 { - font-family: 'Montserrat', sans-serif; - font-weight: normal; - font-size: 32px; - text-align: center; - margin-bottom: 25px; -} - -aside { - display: flex; - justify-content: center; - align-items: center; - padding: 50px 0 40px 0; - position: absolute; - bottom: 0; - left: 0; - right: 0; -} - -aside nav { - height: 18px; - display: flex; - justify-content: center; - align-items: center; -} - -aside nav a { - font-size: 13px; - color: #b2b2b2; - text-decoration: none; - transition: color 100ms ease-in; -} - -aside nav b { - display: block; - background: #b2b2b2; - width: 1px; - height: 100%; - margin: 0 10px; -} - -.username { - font-weight: 500; -} - -p { - font-weight: 400; - font-size: 14px; - line-height: 24px; - max-width: 390px; - text-align: center; - margin: 14px auto 30px auto; -} - -button { - background-color: rgba(0, 0, 0, 0.671); - border: none; - color: white; - padding: 10px 12px; - margin: 10px; - text-align: center; - border-radius: 12px; - text-decoration: none; - display: inline-block; - font-size: 14px; - } - -@keyframes fadein { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -@-moz-keyframes fadein { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -@-webkit-keyframes fadein { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -@media (max-height: 400px) { - aside { - display: none; - } -} - |] -
− kitchen-sink/Nouns.hs
@@ -1,519 +0,0 @@-module Nouns(abstract, concrete) where - -abstract = - [ "Ability" - , "Absurdity" - , "Achievement" - , "Action" - , "Adoration" - , "Adventure" - , "Advice" - , "Agitation" - , "Agony" - , "Alacrity" - , "Amazement" - , "Anger" - , "Anguish" - , "Anxiety" - , "Apathy" - , "Arrogance" - , "Artistry" - , "Audacity" - , "Awareness" - , "Awe" - , "Beauty" - , "Being" - , "Boredom" - , "Bravery" - , "Breadth" - , "Brilliance" - , "Brutality" - , "Calm" - , "Candor" - , "Care" - , "Chaos" - , "Charisma" - , "Charity" - , "Charm" - , "Childhood" - , "Clarity" - , "Cleverness" - , "Cohesion" - , "Coldness" - , "Comfort" - , "Communication" - , "Compassion" - , "Complexity" - , "Conceit" - , "Confidence" - , "Conflict" - , "Conformity" - , "Confusion" - , "Consciousness" - , "Control" - , "Courage" - , "Cowardice" - , "Crime" - , "Culture" - , "Dawn" - , "Day" - , "Death" - , "Deceit" - , "Defeat" - , "Delight" - , "Democracy" - , "Despair" - , "Disappointment" - , "Disbelief" - , "Discord" - , "Dishonesty" - , "Dissension" - , "Ego" - , "Elation" - , "Energy" - , "Ennui" - , "Enthusiasm" - , "Envy" - , "Evening" - , "Evil" - , "Excitement" - , "Exhilaration" - , "Exuberance" - , "Failure" - , "Faith" - , "Fear" - , "Fiction" - , "Forgiveness" - , "Freedom" - , "Genius" - , "Goodness" - , "Grace" - , "Greatness" - , "Grief" - , "Growth" - , "Happiness" - , "Hate" - , "Honesty" - , "Honor" - , "Hope" - , "Hubris" - , "Humility" - , "Humor" - , "Hunger" - , "Impudence" - , "Indifference" - , "Infatuation" - , "Insanity" - , "Integrity" - , "Intelligence" - , "Irritation" - , "Jealousy" - , "Joy" - , "Jubilation" - , "Justice" - , "Justification" - , "Kindness" - , "Kingship" - , "Knack" - , "Knell" - , "Knowledge" - , "Laughter" - , "Lavishness" - , "Law" - , "Leadership" - , "Leer" - , "Legitimacy" - , "Leisure" - , "Length" - , "Liberty" - , "Lie" - , "Life" - , "Listlessness" - , "Loneliness" - , "Loss" - , "Love" - , "Loyalty" - , "Luck" - , "Luxury" - , "Malice" - , "Maliciousness" - , "Malignity" - , "Manhood" - , "Marriage" - , "Martyrdom" - , "Maturity" - , "Meekness" - , "Membership" - , "Memory" - , "Mercy" - , "Meticulousness" - , "Mien" - , "Minute" - , "Misery" - , "Modesty" - , "Modicum" - , "Moment" - , "Monotony" - , "Month" - , "Morning" - , "Mortification" - , "Motivation" - , "Movement" - , "Movement" - , "Music" - , "Myriad" - , "Nadir" - , "Naivete" - , "Nap" - , "Narcissism" - , "Nausea" - , "Need" - , "Negativity" - , "Nervousness" - , "" - , "Newness" - , "Nonconformity" - , "Normalcy" - , "Nouns" - , "Nuance" - , "Obnoxiousness" - , "Occasion" - , "Omen" - , "Openness" - , "Opinion" - , "Opportunism" - , "Opportunity" - , "Optimism" - , "Pain" - , "Panacea" - , "Parenthood" - , "Parsimony" - , "Particularity" - , "Passiveness" - , "Past" - , "Patience" - , "Patriotism" - , "Peace" - , "Peculiar" - , "Peculiarity" - , "Penchant" - , "Permanence" - , "Permission" - , "Perseverance" - , "Perusal" - , "Pessimism" - , "Philosophy" - , "Placidity" - , "Pleasure" - , "Plethora" - , "Positivity" - , "Poverty" - , "Power" - , "Precision" - , "Predilection" - , "Preeminence" - , "Pride" - , "Principle" - , "Progress" - , "Prominence" - , "Prosperity" - , "Rage" - , "Reality" - , "Reason" - , "Redemption" - , "Refreshment" - , "Refusal" - , "Refutation" - , "Relaxation" - , "Relief" - , "Religion" - , "Reminiscence" - , "Repercussion" - , "Replacement" - , "Repulsiveness" - , "Resiliency" - , "Restoration" - , "Retirement" - , "Rhythm" - , "Riches" - , "Right" - , "Romance" - , "Rumor" - , "Rumour" - , "Ruthlessness" - , "Sacrifice" - , "Sadness" - , "Sale" - , "Sanity" - , "Satisfaction" - , "Scholarship" - , "Scrupulousness" - , "Security" - , "Self" - , "Sensitivity" - , "Serendipity" - , "Serenity" - , "Service" - , "Shock" - , "Silliness" - , "Sincerity" - , "Situation" - , "Skill" - , "Slave" - , "Slavery" - , "Sleep" - , "Solace" - , "Solitude" - , "Sophistication" - , "Sorrow" - , "Sparkle" - , "Speculation" - , "Speech" - , "Speed" - , "Spitefulness" - , "Squandering" - , "Stance" - , "Stardom" - , "States" - , "States" - , "Stinginess" - , "Strength" - , "Stress" - , "Strict" - , "Strictness" - , "Strife" - , "Stupidity" - , "Submission" - , "Success" - , "Suffering" - , "Surprise" - , "Susceptibleness" - , "Sympathy" - , "Talent" - , "Tediousness" - , "Tedium" - , "Tender" - , "Testimony" - , "Thirst" - , "Thoroughness" - , "Thought" - , "Thrill" - , "Time" - , "Timidness" - , "Timing" - , "Tired" - , "Tiredness" - , "Tolerance" - , "Torment" - , "Tranquility" - , "Treachery" - , "Treatment" - , "Trend" - , "Trouble" - , "Trust" - , "Truth" - , "Turbulence" - , "Turmoil" - , "Ubiquity" - , "Ugliness" - , "Umbrage" - , "Uncertainty" - , "Uncouthness" - , "Unease" - , "Unemployment" - , "Union" - , "Uniqueness" - , "Unreality" - , "Utility" - , "Vanity" - , "Viciousness" - , "Victory" - , "Vulnerability" - , "Wariness" - , "Warmth" - , "Wary" - , "Weakness" - , "Wealth" - , "Weariness" - , "Week" - , "Width" - , "Wisdom" - , "Wit" - ] - -concrete = - [ "whisker" - , "paw" - , "mammoth" - , "spider" - , "moth" - , "bug" - , "bat" - , "vulture" - , "owl" - , "turtle" - , "worm" - , "earthworm" - , "toad" - , "porcupine" - , "armadillo" - , "rat" - , "squirrel" - , "hedgehog" - , "chipmunk" - , "gerbil" - , "hamster" - , "mouse" - , "mole" - , "anteater" - , "platypus" - , "cow" - , "oxen" - , "cattle" - , "sheep" - , "lamb" - , "ram" - , "goat" - , "kid" - , "pig" - , "hog" - , "shoat" - , "sow" - , "fox" - , "vixen" - , "lemur" - , "raccoon" - , "weasel monkey" - , "ape" - , "chimpanzee" - , "orangutan" - , "baboon" - , "pony" - , "pinto" - , "mare" - , "filly" - , "gelding" - , "bronco" - , "colt" - , "stallion" - , "donkey" - , "zebra" - , "mule" - , "camel" - , "dromedary" - , "gazelle" - , "tom" - , "bird" - , "goose" - , "duck" - , "drake" - , "gander" - , "turkey" - , "songbird" - , "lark" - , "nightingale" - , "wren" - , "eagle" - , "hawk" - , "kitten" - , "chick" - , "rooster" - , "hen" - , "crow" - , "raven" - , "cat" - , "kitten" - , "mutt" - , "wolf" - , "cub" - , "tiger" - , "lion" - , "elephant" - , "cheetah" - , "puma" - , "jackal" - , "jaguar" - , "ocelot" - , "rhinoceros" - , "alpaca" - , "antelope" - , "deer" - , "doe" - , "fawn" - , "stag" - , "kangaroo" - , "joey" - , "koala" - , "sloth" - , "wombat" - , "bear" - , "hyena" - , "crocodile" - , "snake" - , "giraffe" - , "whale" - , "shark" - , "dolphin" - , "seal" - , "bed" - , "hammock" - , "hassock" - , "mirror" - , "hutch" - , "locker" - , "painting" - , "chalice" - , "cage" - , "urn" - , "bow" - , "sword" - , "dart" - , "dagger" - , "hatchet" - , "candle" - , "mop" - , "pail" - , "pipe" - , "brush" - , "easel" - , "gun" - , "rope" - , "balloon" - , "vase" - , "typewriter" - , "stylus" - , "pencil" - , "desk" - , "backpack" - , "saddle" - , "cash machine pot" - , "plate" - , "dish" - , "fork" - , "spoon" - , "samovar" - , "monsoon" - , "hurricane" - , "typhoon" - , "rain" - , "storm" - , "hail" - , "blizzard" - , "breeze" - , "whirlwind" - , "maelstrom" - , "dust storm" - , "cloudburst" - , "tornado" - , "twister" - , "cloud" - , "flood" - , "aftershock" - , "tremor" - , "earthquake" - , "lightning avalanche" - , "eclipse" - , "meteor shower" - , "thunderbolt" - , "tsunami" - ]
plzwrk.cabal view
@@ -7,7 +7,7 @@ -- hash: 8099ceb0d406f862d89306de053aba4c75999a9e0d74ac6a502458d503e7dcc1 name: plzwrk -version: 0.0.0.8 +version: 0.0.0.9 category: Web synopsis: A front-end framework description: Please see the README on GitHub at <https://github.com/meeshkan/plzwrk#readme> @@ -41,7 +41,7 @@ other-modules: Paths_plzwrk , Web.Framework.Plzwrk.Base - , Web.Framework.Plzwrk.Browserful + , Web.Framework.Plzwrk.JSEnv , Web.Framework.Plzwrk.Domify , Web.Framework.Plzwrk.Util , Web.Framework.Plzwrk.TH.HSX @@ -68,43 +68,6 @@ -DPLZWRK_ENABLE_ASTERIUS build-depends: asterius-prelude - -executable kitchen-sink-exe - main-is: Main.hs - other-modules: - Nouns - , Paths_plzwrk - hs-source-dirs: - kitchen-sink - ghc-options: -rtsopts -with-rtsopts=-N - build-depends: - base >=4.7 && <5 - , plzwrk - , containers >= 0.6.2 && < 0.7 - , neat-interpolation >= 0.5.1 && < 0.6 - , text >= 1.2.3 && < 1.3 - , unordered-containers >= 0.2.10 && < 0.3 - - default-language: Haskell2010 - if flag(plzwrk-enable-asterius) - cpp-options: - -DPLZWRK_ENABLE_ASTERIUS - -executable hello-world-exe - main-is: Main.hs - other-modules: - Paths_plzwrk - hs-source-dirs: - hello-world - ghc-options: -rtsopts -with-rtsopts=-N - build-depends: - base >=4.7 && <5 - , plzwrk - , text >= 1.2.3 && < 1.3 - default-language: Haskell2010 - if flag(plzwrk-enable-asterius) - cpp-options: - -DPLZWRK_ENABLE_ASTERIUS test-suite plzwrk-test type: exitcode-stdio-1.0
src/Web/Framework/Plzwrk.hs view
@@ -21,7 +21,7 @@ , toHTML , PwNode(..) , PwAttribute(..) - , Browserful(..) + , JSEnv(..) -- hsx , hsx , hsx' @@ -54,7 +54,7 @@ import Prelude hiding ( div ) import Web.Framework.Plzwrk.Base -import Web.Framework.Plzwrk.Browserful +import Web.Framework.Plzwrk.JSEnv import Web.Framework.Plzwrk.Domify import Web.Framework.Plzwrk.Util import Web.Framework.Plzwrk.TH.QuoteHSX
src/Web/Framework/Plzwrk/Asterius.hs view
@@ -29,10 +29,10 @@ import Data.HashMap.Strict as HM import Data.Coerce import Foreign.Ptr -import Web.Framework.Plzwrk.Browserful +import Web.Framework.Plzwrk.JSEnv -asteriusBrowser :: IO (Browserful JSVal) -asteriusBrowser = return Browserful +asteriusBrowser :: IO (JSEnv JSVal) +asteriusBrowser = return JSEnv { castToArray = _castToArray , castToBool = _castToBool @@ -61,7 +61,9 @@ , setValue = _setValue , invokeOn1 = _invokeOn1 , invokeOn2 = _invokeOn2 - , _makeHaskellCallback = __makeHaskellCallback + , _makeHaskellCallback1 = __makeHaskellCallback1 + , _makeHaskellCallback2 = __makeHaskellCallback2 + , _makeHaskellCallback3 = __makeHaskellCallback3 , mathRandom = _mathRandom } @@ -210,11 +212,21 @@ _setValue' :: JSVal -> String -> String -> IO () _setValue' a b c = _js_setValue a (toJSString b) $ _s2v (toJSString c) -__makeHaskellCallback :: (JSVal -> IO ()) -> IO JSVal -__makeHaskellCallback a = do +__makeHaskellCallback1 :: (JSVal -> IO ()) -> IO JSVal +__makeHaskellCallback1 a = do x <- makeHaskellCallback1 a return $ getJSVal x +__makeHaskellCallback2 :: (JSVal -> JSVal -> IO ()) -> IO JSVal +__makeHaskellCallback2 a = do + x <- makeHaskellCallback2 a + return $ getJSVal x + +__makeHaskellCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -> IO JSVal +__makeHaskellCallback3 a = do + x <- makeHaskellCallback3 a + return $ getJSVal x + __freeCallback :: JSVal -> IO () __freeCallback v = freeHaskellCallback (JSFunction v) @@ -282,8 +294,14 @@ foreign import javascript "document.getElementById($1)" js_documentGetElementById :: JSString -> IO JSVal -foreign import javascript "wrapper oneshot" +foreign import javascript "wrapper" makeHaskellCallback1 :: (JSVal -> IO ()) -> IO JSFunction + +foreign import javascript "wrapper" + makeHaskellCallback2 :: (JSVal -> JSVal -> IO ()) -> IO JSFunction + +foreign import javascript "wrapper" + makeHaskellCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -> IO JSFunction # else module Web.Framework.Plzwrk.Asterius where
src/Web/Framework/Plzwrk/Base.hs view
@@ -15,9 +15,9 @@ import qualified Data.HashMap.Strict as HM import qualified Data.Set as S -cssToStyle :: (HM.HashMap String String) -> String+cssToStyle :: HM.HashMap String String -> String cssToStyle css =- (intercalate ";" $ fmap (\(x, y) -> x <> ":" <> y) (HM.toList css))+ intercalate ";" $ fmap (\(x, y) -> x <> ":" <> y) (HM.toList css) -- |PwAttribute for a DOM PwNode.@@ -62,7 +62,7 @@ data PwNode s opq = PwElement { _elt_tag :: String- , _elt_attrs :: [(String, (s -> PwAttribute s opq))]+ , _elt_attrs :: [(String, s -> PwAttribute s opq)] , _elt_children :: [s -> PwNode s opq] } | PwTextNode { _tn_text :: String } @@ -80,7 +80,7 @@ _hydrate :: s -> PwNode s opq -> HydratedPwNode s opq _hydrate s (PwElement a b c) =- HydratedPwElement a (fmap (\(x, y) -> (x, y s)) b) (fmap (\x -> hydrate s x) c)+ HydratedPwElement a (fmap (\(x, y) -> (x, y s)) b) (fmap (hydrate s) c) _hydrate s (PwTextNode t) = HydratedPwTextNode t hydrate :: s -> (s -> PwNode s opq) -> HydratedPwNode s opq@@ -98,13 +98,13 @@ _toHTML (HydratedPwElement tag attrs ch) = "<" ++ tag- ++ (if (null atts) then "" else " " ++ atts)- ++ (if (null ch)+ ++ (if null atts then "" else " " ++ atts)+ ++ (if null ch then "/>"- else ">" ++ (concat $ fmap _toHTML ch) ++ "</" ++ tag ++ ">"+ else ">" ++ concatMap _toHTML ch ++ "</" ++ tag ++ ">" ) where- atts = intercalate " " $ fmap+ atts = unwords $ fmap (\(x, y) -> x <> "=\"" <> stringifyPwAttribute y <> "\"") (filter (isText . snd) attrs) _toHTML (HydratedPwTextNode txt) = txt
− src/Web/Framework/Plzwrk/Browserful.hs
@@ -1,131 +0,0 @@-module Web.Framework.Plzwrk.Browserful - ( Browserful(..) - , RequestInit(..) - , FetchBody(..) - ) -where - -import Data.ByteString.Internal ( ByteString ) -import qualified Data.HashMap.Strict as HM - --- | A data class holding functions that operate on opaque --- JavaScript types, parameterized by @jsval@. When possible, --- the real names of browser functions like 'addEventListener' --- and 'appendChild' are used. --- --- Browserful is currently implemented as data instead of as --- a typeclass because it is unclear what type of additional --- monadic transformer around IO would be most appropriate to --- retain the state of @jsval@ objects, whereas when part of --- a dataclass, the state retention is abstracted away. - -data Browserful jsval = Browserful - { - -- | Casts a value to an array of jsvals - castToArray :: jsval -> IO (Maybe [jsval]) - - -- | Casts a value to a bool - , castToBool :: jsval -> IO (Maybe Bool) - - -- | Casts a value to a bool - , castToByteString :: jsval -> IO (Maybe ByteString) - - -- | Casts a value to a double - , castToDouble :: jsval -> IO (Maybe Double) - - -- | Casts a value to an int - , castToInt :: jsval -> IO (Maybe Int) - - -- | Casts a value to a string - , castToString :: jsval -> IO (Maybe String) - - -- | Logs an opaque JavaScript value. See [Console.log](https://developer.mozilla.org/en-US/docs/Web/API/Console/log) - , consoleLog :: jsval -> IO () - - -- | A default request init - , defaultRequestInit :: RequestInit jsval - - -- | The body of the document. See [Document.body](https://developer.mozilla.org/en-US/docs/Web/API/Document/body) - , documentBody :: IO jsval - - -- | Creates an element with a given tag. See [Document.createElement](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) - , documentCreateElement :: String -> IO jsval - - -- | Creates a text node with the given text. See [Document.createTextNode](https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode) - , documentCreateTextNode :: String -> IO jsval - - -- | Gets an element by id from a document. See [Document.getElementById](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) - , documentGetElementById :: String -> IO (Maybe jsval) - - -- | Gets the head of a document. See [Document.head](https://developer.mozilla.org/en-US/docs/Web/API/Document/head) - , documentHead :: IO jsval - - -- | Calls the browser's fetch command - , fetch :: String -> (RequestInit jsval) -> IO jsval - - -- | Gets a JavaScript property, returning @Nothing@ if the object being called is null or undefined. - , getPropertyAsOpaque :: jsval -> String -> IO (Maybe jsval) - - -- | Invokes on target a function with 0 arguments. - , invokeOn0 :: jsval -> String -> IO jsval - - -- | Invokes on target a function with 1 argument. - , invokeOn1 :: jsval -> String -> jsval -> IO jsval - - -- | Invokes on target a function with 2 arguments. - , invokeOn2 :: jsval -> String -> jsval -> jsval -> IO jsval - - -- | jsval from an array of jsvals - , jsValFromArray :: [jsval] -> IO jsval - - -- | jsval from a bool - , jsValFromBool :: Bool -> IO jsval - - -- | jsval from a byte string - , jsValFromByteString :: ByteString -> IO jsval - - -- | jsval from a double - , jsValFromDouble :: Double -> IO jsval - - -- | jsval from an int - , jsValFromInt :: Int -> IO jsval - - -- | jsval from a string - , jsValFromString :: String -> IO jsval - - -- | Creates an object - , makeObject :: IO jsval - - -- | Generate a random double between 0 and 1. See [Math.random](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) - , mathRandom :: IO Double - - -- | Sets on an object a value - , setValue :: jsval -> String -> jsval -> IO () - - -- | Frees a callback. Should only be called in advanced cases. In most usage, callbacks are freed automatically by plzwrk. - , _freeCallback :: jsval -> IO () - - -- | Makes a haskell callback. Should only be called in advanced cases. In most usage, callbacks are created automatically by plzwrk. - , _makeHaskellCallback :: (jsval -> IO ()) -> IO jsval - } - --- |The body of a fetch request or response -data FetchBody jsval = - FormDataBody (HM.HashMap String jsval) -- ^ From form data, ie @multipart/form-data@ or @application/x-www-form-urlencoded@ - | StringBody String -- ^ A string, ie @text/plain@ or @application/json@ - | BlobBody jsval -- ^ A single file - | URLSearchParamsBody (HM.HashMap String String) -- ^ Useful for @application/x-www-form-urlencoded@ - | Uint8Array ByteString - --- | Initialization parameters for a request made with fetch -data RequestInit jsval = RequestInit { - _ri_method :: Maybe String -- ^ The request method, e.g., GET, POST. The default is GET. - , _ri_headers :: Maybe (HM.HashMap String String) -- ^ Any headers you want to add to your request, contained within a Headers object or an object literal with ByteString values. - , _ri_body :: Maybe (FetchBody jsval) -- ^ Any body that you want to add to your request: this can be a Blob, BufferSource, FormData, URLSearchParams, USVString, or ReadableStream object. Note that a request using the GET or HEAD method cannot have a body. - , _ri_mode :: Maybe String -- ^ The mode you want to use for the request, e.g., cors, no-cors, same-origin, or navigate. The default is cors. - , _ri_credentials :: Maybe String -- ^ The request credentials you want to use for the request: omit, same-origin, or include. The default is same-origin. - , _ri_cache :: Maybe String -- ^ The cache mode you want to use for the request. - , _ri_redirect :: Maybe String -- ^ The redirect mode to use: follow, error, or manual. The default is follow. - , _ri_referrer :: Maybe String -- ^ A USVString specifying no-referrer, client, or a URL. The default is about:client. - , _ri_integrity :: Maybe String -- ^ Contains the subresource integrity value of the request (e.g., sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=). -}
src/Web/Framework/Plzwrk/Domify.hs view
@@ -1,524 +1,513 @@-module Web.Framework.Plzwrk.Domify- ( plzwrk- , plzwrk'- , plzwrk'_- , plzwrkSSR- , plzwrkSSR'- , plzwrkSSR'_- )-where--import Control.Applicative-import Data.List.Split-import Control.Monad-import Control.Monad.Reader-import Control.Monad.Trans-import Control.Monad.Trans.Maybe-import qualified Data.HashMap.Strict as HM-import Data.IORef-import Data.Maybe ( catMaybes )-import qualified Data.Set as S-import Web.Framework.Plzwrk.Base-import Web.Framework.Plzwrk.Browserful-import Web.Framework.Plzwrk.Util--data DomifiedAttribute jsval = DomifiedTextAttribute String | DomifiedFunctionAttribute jsval--data DomifiedPwNode jsval = DomifiedPwElement- { _dom_tag :: String- , _dom_attr :: [(String, DomifiedAttribute jsval)]- , _dom_kids :: [DomifiedPwNode jsval]- , _dom_ptr :: jsval- }- | DomifiedPwTextNode String jsval--data OldStuff state jsval = OldStuff {- _oldState :: state,- _oldDom :: Maybe (DomifiedPwNode jsval)-}------------ reader functions---freeAttrFunction :: DomifiedAttribute jsval -> ReaderT (Browserful jsval) IO ()-freeAttrFunction (DomifiedFunctionAttribute f) = do- __freeCallback <- asks _freeCallback- liftIO (void $ __freeCallback f)-freeAttrFunction _ = return ()--freeFunctions :: DomifiedPwNode jsval -> ReaderT (Browserful jsval) IO ()-freeFunctions (DomifiedPwElement _ b c _) = do- mapM_ freeAttrFunction (fmap snd b)- mapM_ freeFunctions c-freeFunctions _ = pure ()--data AttributeHack = MkAttributeHack- { _hackishStyle :: HM.HashMap String String- , _hackishClass :: S.Set String- , _hackishSimple :: HM.HashMap String String- } deriving (Eq)--getStyleFrom :: [(String, String)] -> HM.HashMap String String-getStyleFrom l = HM.unions- (fmap stylishAttributes $ filter (\(x, _) -> x == "style") l) where- stylishAttributes :: (String, String) -> HM.HashMap String String- stylishAttributes (_, y) = HM.fromList $ fmap- (\s -> let ss = splitOn ":" s in (ss !! 0, ss !! 1))- (filter (\x -> elem ':' x) (splitOn ";" y))--getClassFrom :: [(String, String)] -> S.Set String-getClassFrom l = S.unions- (fmap classyAttributes $ filter (\(x, _) -> x == "class") l) where- classyAttributes :: (String, String) -> S.Set String- classyAttributes (_, y) = S.fromList (words y)--getSimpleFrom :: [(String, String)] -> HM.HashMap String String-getSimpleFrom l = HM.unions (fmap simplyAttributes l) where- simplyAttributes :: (String, String) -> HM.HashMap String String- simplyAttributes (x, y) =- if (x /= "class" && x /= "style") then HM.singleton x y else HM.empty--attributeListToSplitAttrs :: [(String, String)] -> AttributeHack-attributeListToSplitAttrs fl =- MkAttributeHack (getStyleFrom fl) (getClassFrom fl) (getSimpleFrom fl)--isDText :: (String, DomifiedAttribute jsval) -> Maybe (String, String)-isDText (k, DomifiedTextAttribute v) = Just (k, v)-isDText _ = Nothing--isPwText :: (String, PwAttribute s jsval) -> Maybe (String, String)-isPwText (k, PwTextAttribute v) = Just (k, v)-isPwText _ = Nothing---daToF :: [(String, DomifiedAttribute jsval)] -> [(String, String)]-daToF l = catMaybes $ fmap isDText l--paToF :: [(String, PwAttribute s jsval)] -> [(String, String)]-paToF l = catMaybes $ fmap isPwText l--nodesEq- :: String- -> String- -> [(String, DomifiedAttribute jsval)]- -> [(String, PwAttribute s jsval)]- -> Bool-nodesEq t0 t1 a0 a1 =- (t0 == t1)- && ( attributeListToSplitAttrs (daToF a0)- == attributeListToSplitAttrs (paToF a1)- )--padr :: Int -> a -> [a] -> [a]-padr i v l = if (length l >= i) then l else padr i v (l ++ [v])--reconcile- :: Bool- -> IORef (OldStuff state jsval)- -> (state -> PwNode state jsval)- -> jsval- -> jsval- -> Maybe (DomifiedPwNode jsval)- -> Maybe (HydratedPwNode state jsval)- -> ReaderT- (Browserful jsval)- IO- (Maybe (DomifiedPwNode jsval))-reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just (DomifiedPwElement currentTag currentAttributes currentChildren currentNode)) (Just maybeNewNode@(HydratedPwElement maybeNewTag maybeNewAttributes maybeNewChildren))- = if (nodesEq currentTag maybeNewTag currentAttributes maybeNewAttributes)- then- (do- let maxlen = max (length maybeNewChildren) (length currentChildren)- newChildren <- sequence $ getZipList- ( (reconcile touchDOM- refToOldStuff- domCreationF- currentNode- topLevelNode- )- <$> (ZipList (padr maxlen Nothing (fmap Just currentChildren)))- <*> (ZipList (padr maxlen Nothing (fmap Just maybeNewChildren)))- )- currentAttributes <- mapM- (hydratedAttrToDomifiedAttr refToOldStuff domCreationF parentNode)- maybeNewAttributes- if touchDOM- then- (do- mapM_ (removeEventHandler currentNode) currentAttributes- mapM_ (setEventHandler currentNode) currentAttributes- )- else (pure ())- return $ Just- (DomifiedPwElement currentTag- currentAttributes- (catMaybes newChildren)- currentNode- )- )- else- (do- res <- domify touchDOM- refToOldStuff- domCreationF- parentNode- topLevelNode- (Just currentNode)- maybeNewNode- return $ Just res- )-reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just currentDomifiedString@(DomifiedPwTextNode currentString currentNode)) (Just maybeNewNode@(HydratedPwTextNode maybeNewString))- = if (currentString == maybeNewString)- then pure (Just currentDomifiedString)- else- (do- res <- domify touchDOM- refToOldStuff- domCreationF- parentNode- topLevelNode- (Just currentNode)- maybeNewNode- return $ Just res- )-reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just (DomifiedPwElement _ _ _ currentNode)) (Just maybeNewNode@(HydratedPwTextNode _))- = do- res <- domify touchDOM- refToOldStuff- domCreationF- parentNode- topLevelNode- (Just currentNode)- maybeNewNode- return $ Just res-reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just (DomifiedPwTextNode _ currentNode)) (Just maybeNewNode@(HydratedPwElement _ _ _))- = do- res <- domify touchDOM- refToOldStuff- domCreationF- parentNode- topLevelNode- (Just currentNode)- maybeNewNode- return $ Just res-reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode Nothing (Just maybeNewNode)- = do- res <- domify touchDOM- refToOldStuff- domCreationF- parentNode- topLevelNode- Nothing- maybeNewNode- return $ Just res-reconcile touchDOM refToOldStuff domCreationF parentNode _ (Just (DomifiedPwElement _ _ _ currentNode)) Nothing- = if (touchDOM)- then- (do- _nodeRemoveChild <- asks nodeRemoveChild- liftIO $ _nodeRemoveChild parentNode currentNode- return Nothing- )- else (pure Nothing)-reconcile touchDOM refToOldStuff domCreationF parentNode _ (Just (DomifiedPwTextNode _ currentNode)) Nothing- = if (touchDOM)- then- (do- _nodeRemoveChild <- asks nodeRemoveChild- liftIO $ _nodeRemoveChild parentNode currentNode- return Nothing- )- else (pure Nothing)-reconcile _ _ _ _ _ _ _ = error "Inconsistent state"--reconcileAndAdd = reconcile True--cbMaker- :: IORef (OldStuff state jsval)- -> (state -> PwNode state jsval)- -> jsval- -> (jsval -> state -> IO state)- -> Browserful jsval- -> jsval- -> IO ()-cbMaker refToOldStuff domCreationF topLevelNode eventToState env event = do- oldStuff <- readIORef refToOldStuff- let oldDom = _oldDom oldStuff- let oldState = _oldState oldStuff- newState <- eventToState event oldState- let newHydratedDom = hydrate newState domCreationF- newDom <- runReaderT- (reconcileAndAdd refToOldStuff- domCreationF- topLevelNode- topLevelNode- oldDom- (Just newHydratedDom)- )- env- maybe (pure ()) (\x -> runReaderT (freeFunctions x) env) oldDom- writeIORef refToOldStuff (OldStuff newState newDom)--eventable- :: IORef (OldStuff state jsval)- -> (state -> PwNode state jsval)- -> jsval- -> (jsval -> state -> IO state)- -> ReaderT (Browserful jsval) IO jsval-eventable refToOldStuff domCreationF topLevelNode eventToState = do- __makeHaskellCallback <- asks _makeHaskellCallback- env <- ask- liftIO $ __makeHaskellCallback- (cbMaker refToOldStuff domCreationF topLevelNode eventToState env)--hydratedAttrToDomifiedAttr- :: IORef (OldStuff state jsval)- -> (state -> PwNode state jsval)- -> jsval- -> (String, PwAttribute state jsval)- -> ReaderT (Browserful jsval) IO (String, DomifiedAttribute jsval)-hydratedAttrToDomifiedAttr refToOldStuff domCreationF topLevelNode (k, PwTextAttribute t)- = return $ (k, DomifiedTextAttribute t)-hydratedAttrToDomifiedAttr refToOldStuff domCreationF topLevelNode (k, PwFunctionAttribute f)- = do- func <- eventable refToOldStuff domCreationF topLevelNode f- return $ (k, DomifiedFunctionAttribute func)--setAtt- :: jsval- -> (String, DomifiedAttribute jsval)- -> ReaderT (Browserful jsval) IO ()-setAtt currentNode (k, DomifiedTextAttribute v) = do- _elementSetAttribute <- asks elementSetAttribute- liftIO $ _elementSetAttribute currentNode k v-setAtt currentNode kv = setEventHandler currentNode kv--handleOnlyEventListener- :: (jsval -> String -> jsval -> IO ())- -> jsval- -> (String, DomifiedAttribute jsval)- -> IO ()-handleOnlyEventListener eventListenerHandlerF currentNode (k, DomifiedFunctionAttribute v)- = eventListenerHandlerF currentNode k v-handleOnlyEventListener _ _ _ = pure ()--setEventHandler- :: jsval- -> (String, DomifiedAttribute jsval)- -> ReaderT (Browserful jsval) IO ()-setEventHandler currentNode domifiedAttribute = do- _eventTargetAddEventListener <- asks eventTargetAddEventListener- liftIO $ handleOnlyEventListener _eventTargetAddEventListener- currentNode- domifiedAttribute--removeEventHandler- :: jsval- -> (String, DomifiedAttribute jsval)- -> ReaderT (Browserful jsval) IO ()-removeEventHandler currentNode domifiedAttribute = do- _eventTargetRemoveEventListener <- asks eventTargetRemoveEventListener- liftIO $ handleOnlyEventListener _eventTargetRemoveEventListener- currentNode- domifiedAttribute--domify- :: Bool- -> IORef (OldStuff state jsval)- -> (state -> PwNode state jsval)- -> jsval- -> jsval- -> Maybe jsval- -> HydratedPwNode state jsval- -> ReaderT (Browserful jsval) IO (DomifiedPwNode jsval)-domify touchDOM refToOldStuff domCreationF parentNode topLevelNode replacing (HydratedPwElement tag attrs children)- = do- _documentCreateElement <- asks documentCreateElement- _nodeAppendChild <- asks nodeAppendChild- _nodeInsertBefore <- asks nodeInsertBefore- _nodeRemoveChild <- asks nodeRemoveChild- newNode <- liftIO $ _documentCreateElement tag- newAttributes <- mapM- (hydratedAttrToDomifiedAttr refToOldStuff domCreationF topLevelNode)- attrs- if touchDOM then (mapM_ (setAtt newNode) newAttributes) else (pure ())- newChildren <- mapM- (domify touchDOM refToOldStuff domCreationF newNode topLevelNode Nothing)- children- if touchDOM- then- (do- maybe- (liftIO $ _nodeAppendChild parentNode newNode)- (\x -> do- liftIO $ _nodeInsertBefore parentNode newNode x- liftIO $ _nodeRemoveChild parentNode x- )- replacing- )- else (pure ())- liftIO $ return (DomifiedPwElement tag newAttributes newChildren newNode)-domify touchDOM _ _ parentNode topLevelNode replacing (HydratedPwTextNode text)- = do- _documentCreateElement <- asks documentCreateElement- _nodeAppendChild <- asks nodeAppendChild- _nodeInsertBefore <- asks nodeInsertBefore- _nodeRemoveChild <- asks nodeRemoveChild- _documentCreateTextNode <- asks documentCreateTextNode- newTextNode <- liftIO $ _documentCreateTextNode text- if touchDOM- then- (do- maybe- (liftIO $ _nodeAppendChild parentNode newTextNode)- (\x -> do- liftIO $ _nodeInsertBefore parentNode newTextNode x- liftIO $ _nodeRemoveChild parentNode x- )- replacing- )- else (pure ())- liftIO $ return (DomifiedPwTextNode text newTextNode)--getChildren :: DomifiedPwNode jsval -> [DomifiedPwNode jsval]-getChildren (DomifiedPwElement _ _ x _) = x-getChildren _ = []--setEventHandlers_- :: jsval -> DomifiedPwNode jsval -> ReaderT (Browserful jsval) IO ()-setEventHandlers_ v (DomifiedPwElement _ a _ _) = mapM_ (setEventHandler v) a-setEventHandlers_ _ _ = liftIO $ pure ()--transformFromCurrentDom- :: jsval- -> [DomifiedPwNode jsval]- -> ReaderT (Browserful jsval) IO [DomifiedPwNode jsval]-transformFromCurrentDom parentNode children = do- _nodeChildNodes <- asks nodeChildNodes- _kids <- liftIO $ _nodeChildNodes parentNode- let kids = maybe [] id _kids- newChildren <- sequence $ getZipList- ( transformFromCurrentDom- <$> (ZipList kids)- <*> (ZipList $ fmap getChildren children)- )- sequence- $ getZipList (setEventHandlers_ <$> (ZipList kids) <*> (ZipList children))- return $ getZipList- ( (\cur chldrn ptr -> cur { _dom_kids = chldrn, _dom_ptr = ptr })- <$> (ZipList children)- <*> (ZipList newChildren)- <*> (ZipList kids)- )--addHandlers- :: jsval- -> DomifiedPwNode jsval- -> ReaderT (Browserful jsval) IO (DomifiedPwNode jsval)-addHandlers parentNode curDom = do- transformed <- transformFromCurrentDom parentNode [curDom]- return $ (transformed !! 0)--__plzwrk- :: Bool- -> (state -> PwNode state jsval)- -> state- -> jsval- -> Browserful jsval- -> IO (Maybe (DomifiedPwNode jsval))-__plzwrk cleanDOM domF state parentNode env = do- refToOldStuff <- newIORef (OldStuff state Nothing)- newDom <- runReaderT- (reconcile cleanDOM- refToOldStuff- domF- parentNode- parentNode- Nothing- (Just $ hydrate state domF)- )- env- writeIORef refToOldStuff (OldStuff state newDom)- if (not cleanDOM)- then- (maybe- (pure Nothing)- (\y -> do- withHandlers <- runReaderT (addHandlers parentNode y) env- writeIORef refToOldStuff (OldStuff state (Just y))- return $ Just withHandlers- )- newDom- )- else pure newDom--_plzwrk- :: Bool- -> (state -> PwNode state jsval)- -> state- -> Browserful jsval- -> String- -> IO (Maybe (DomifiedPwNode jsval))-_plzwrk cleanDOM domF state env nodeId = do- parentNode <- (documentGetElementById env) nodeId- maybe (error ("Node with id not in DOM: " <> show nodeId))- (\x -> __plzwrk cleanDOM domF state x env)- parentNode----- |The main function that makes a web app.--plzwrk- :: (state -> PwNode state jsval) -- ^ A function that takes a state and produces a DOM- -> state -- ^ An initial state- -> Browserful jsval -- ^ A browser implementation, ie Asterius or the mock browser- -> String -- ^ The id of the element into which the DOM is inserted. Note that plzwrk manages all children under this element. Touching the managed elements can break plzwrk.- -> IO () -- ^ Returns nothing--plzwrk domF state env nodeId = void $ _plzwrk True domF state env nodeId---- |A variant of plzwrk that acts on a node already rendered to the DOM,---- ie by server-side rendering. It assumes the node has been rendered---- with the same state-to-node function as well as the same state.--plzwrkSSR- :: (state -> PwNode state jsval) -- ^ A function that takes a state and produces a DOM- -> state -- ^ An initial state- -> Browserful jsval -- ^ A browser implementation, ie Asterius or the mock browser- -> String -- ^ The id of the element into which the DOM is inserted. Note that plzwrk manages all children under this element. Touching the managed elements can break plzwrk.- -> IO () -- ^ Returns nothing--plzwrkSSR domF state env nodeId = void $ _plzwrk False domF state env nodeId--_plzwrk'- :: Bool- -> (state -> PwNode state jsval)- -> state- -> Browserful jsval- -> IO (Maybe (DomifiedPwNode jsval))-_plzwrk' cleanDOM domF state env = do- parentNode <- (documentBody env)- __plzwrk cleanDOM domF state parentNode env---- |A variation of plzwrk that inserts the node as a child of the document's body.--plzwrk' :: (state -> PwNode state jsval) -> state -> Browserful jsval -> IO ()-plzwrk' domF state env = void $ _plzwrk' True domF state env---- |A variation of plzwrk that inserts the node as a child of the document's body.--plzwrkSSR'- :: (state -> PwNode state jsval) -> state -> Browserful jsval -> IO ()-plzwrkSSR' domF state env = void $ _plzwrk' False domF state env---- |A variation of plzwrk that takes no state.--plzwrk'_ :: (() -> PwNode () jsval) -> Browserful jsval -> IO ()-plzwrk'_ domF env = plzwrk' domF () env---- |A variation of plzwrkSSR that takes no state.--plzwrkSSR'_ :: (() -> PwNode () jsval) -> Browserful jsval -> IO ()-plzwrkSSR'_ domF env = plzwrkSSR' domF () env+module Web.Framework.Plzwrk.Domify + ( plzwrk + , plzwrk' + , plzwrk'_ + , plzwrkSSR + , plzwrkSSR' + , plzwrkSSR'_ + ) +where + +import Control.Applicative +import Data.List.Split +import Control.Monad +import Control.Monad.Reader +import Control.Monad.Trans +import Control.Monad.Trans.Maybe +import qualified Data.HashMap.Strict as HM +import Data.IORef +import Data.Maybe ( fromMaybe + , catMaybes + , mapMaybe + ) +import qualified Data.Set as S +import Web.Framework.Plzwrk.Base +import Web.Framework.Plzwrk.JSEnv +import Web.Framework.Plzwrk.Util + +data DomifiedAttribute jsval = DomifiedTextAttribute String | DomifiedFunctionAttribute jsval + +data DomifiedPwNode jsval = DomifiedPwElement + { _dom_tag :: String + , _dom_attr :: [(String, DomifiedAttribute jsval)] + , _dom_kids :: [DomifiedPwNode jsval] + , _dom_ptr :: jsval + } + | DomifiedPwTextNode String jsval + +data OldStuff state jsval = OldStuff { + _oldState :: state, + _oldDom :: Maybe (DomifiedPwNode jsval) +} + +---------- reader functions + + +freeAttrFunction :: DomifiedAttribute jsval -> ReaderT (JSEnv jsval) IO () +freeAttrFunction (DomifiedFunctionAttribute f) = do + __freeCallback <- asks _freeCallback + liftIO (void $ __freeCallback f) +freeAttrFunction _ = return () + +freeFunctions :: DomifiedPwNode jsval -> ReaderT (JSEnv jsval) IO () +freeFunctions (DomifiedPwElement _ b c _) = do + mapM_ freeAttrFunction (fmap snd b) + mapM_ freeFunctions c +freeFunctions _ = pure () + +data AttributeHack = MkAttributeHack + { _hackishStyle :: HM.HashMap String String + , _hackishClass :: S.Set String + , _hackishSimple :: HM.HashMap String String + } deriving (Eq) + +getStyleFrom :: [(String, String)] -> HM.HashMap String String +getStyleFrom l = HM.unions + (fmap stylishAttributes (filter (\(x, _) -> x == "style") l)) where + stylishAttributes :: (String, String) -> HM.HashMap String String + stylishAttributes (_, y) = HM.fromList $ fmap + (\s -> let ss = splitOn ":" s in (head ss, ss !! 1)) + (filter (elem ':') (splitOn ";" y)) + +getClassFrom :: [(String, String)] -> S.Set String +getClassFrom l = S.unions + (fmap classyAttributes (filter (\(x, _) -> x == "class") l)) where + classyAttributes :: (String, String) -> S.Set String + classyAttributes (_, y) = S.fromList (words y) + +getSimpleFrom :: [(String, String)] -> HM.HashMap String String +getSimpleFrom l = HM.unions (fmap simplyAttributes l) where + simplyAttributes :: (String, String) -> HM.HashMap String String + simplyAttributes (x, y) = + if x /= "class" && x /= "style" then HM.singleton x y else HM.empty + +attributeListToSplitAttrs :: [(String, String)] -> AttributeHack +attributeListToSplitAttrs fl = + MkAttributeHack (getStyleFrom fl) (getClassFrom fl) (getSimpleFrom fl) + +isDText :: (String, DomifiedAttribute jsval) -> Maybe (String, String) +isDText (k, DomifiedTextAttribute v) = Just (k, v) +isDText _ = Nothing + +isPwText :: (String, PwAttribute s jsval) -> Maybe (String, String) +isPwText (k, PwTextAttribute v) = Just (k, v) +isPwText _ = Nothing + + +daToF :: [(String, DomifiedAttribute jsval)] -> [(String, String)] +daToF = mapMaybe isDText + +paToF :: [(String, PwAttribute s jsval)] -> [(String, String)] +paToF = mapMaybe isPwText + +nodesEq + :: String + -> String + -> [(String, DomifiedAttribute jsval)] + -> [(String, PwAttribute s jsval)] + -> Bool +nodesEq t0 t1 a0 a1 = + (t0 == t1) + && ( attributeListToSplitAttrs (daToF a0) + == attributeListToSplitAttrs (paToF a1) + ) + +padr :: Int -> a -> [a] -> [a] +padr i v l = if length l >= i then l else padr i v (l ++ [v]) + +getOpaque :: DomifiedPwNode jsval -> jsval +getOpaque (DomifiedPwElement _ _ _ x) = x +getOpaque (DomifiedPwTextNode _ x ) = x + +reconcile + :: Bool + -> IORef (OldStuff state jsval) + -> (state -> PwNode state jsval) + -> jsval + -> jsval + -> Maybe (DomifiedPwNode jsval) + -> Maybe (HydratedPwNode state jsval) + -> ReaderT + (JSEnv jsval) + IO + (Maybe (DomifiedPwNode jsval)) +reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just (DomifiedPwElement currentTag currentAttributes currentChildren currentNode)) (Just maybeNewNode@(HydratedPwElement maybeNewTag maybeNewAttributes maybeNewChildren)) + = if nodesEq currentTag maybeNewTag currentAttributes maybeNewAttributes + then + (do + let maxlen = max (length maybeNewChildren) (length currentChildren) + newChildren <- sequence $ getZipList + ( reconcile touchDOM + refToOldStuff + domCreationF + currentNode + topLevelNode + <$> ZipList (padr maxlen Nothing (fmap Just currentChildren)) + <*> ZipList (padr maxlen Nothing (fmap Just maybeNewChildren)) + ) + newerAttributes <- mapM + (hydratedAttrToDomifiedAttr refToOldStuff domCreationF parentNode) + maybeNewAttributes + if touchDOM + then + (do + mapM_ (removeEventHandler currentNode) currentAttributes + mapM_ (setEventHandler currentNode) newerAttributes + ) + else pure () + return $ Just + (DomifiedPwElement currentTag + newerAttributes + (catMaybes newChildren) + currentNode + ) + ) + else + (do + res <- domify touchDOM + refToOldStuff + domCreationF + parentNode + topLevelNode + (Just currentNode) + maybeNewNode + return $ Just res + ) +reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just currentDomifiedString@(DomifiedPwTextNode currentString currentNode)) (Just maybeNewNode@(HydratedPwTextNode maybeNewString)) + = if currentString == maybeNewString + then pure (Just currentDomifiedString) + else + (do + res <- domify touchDOM + refToOldStuff + domCreationF + parentNode + topLevelNode + (Just currentNode) + maybeNewNode + return $ Just res + ) +reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just (DomifiedPwElement _ _ _ currentNode)) (Just maybeNewNode@(HydratedPwTextNode _)) + = do + res <- domify touchDOM + refToOldStuff + domCreationF + parentNode + topLevelNode + (Just currentNode) + maybeNewNode + return $ Just res +reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode (Just (DomifiedPwTextNode _ currentNode)) (Just maybeNewNode@(HydratedPwElement _ _ _)) + = do + res <- domify touchDOM + refToOldStuff + domCreationF + parentNode + topLevelNode + (Just currentNode) + maybeNewNode + return $ Just res +reconcile touchDOM refToOldStuff domCreationF parentNode topLevelNode Nothing (Just maybeNewNode) + = do + res <- domify touchDOM + refToOldStuff + domCreationF + parentNode + topLevelNode + Nothing + maybeNewNode + return $ Just res +reconcile touchDOM refToOldStuff domCreationF parentNode _ (Just domifiedPwNode) Nothing + = if touchDOM + then + (do + _nodeRemoveChild <- asks nodeRemoveChild + liftIO $ _nodeRemoveChild parentNode (getOpaque domifiedPwNode) + return Nothing + ) + else pure Nothing +reconcile _ _ _ _ _ _ _ = error "Inconsistent state" + +reconcileAndAdd = reconcile True + +cbMaker + :: IORef (OldStuff state jsval) + -> (state -> PwNode state jsval) + -> jsval + -> (jsval -> state -> IO state) + -> JSEnv jsval + -> jsval + -> IO () +cbMaker refToOldStuff domCreationF topLevelNode eventToState env event = do + oldStuff <- readIORef refToOldStuff + let oldDom = _oldDom oldStuff + let oldState = _oldState oldStuff + newState <- eventToState event oldState + let newHydratedDom = hydrate newState domCreationF + newDom <- runReaderT + (reconcileAndAdd refToOldStuff + domCreationF + topLevelNode + topLevelNode + oldDom + (Just newHydratedDom) + ) + env + maybe (pure ()) (\x -> runReaderT (freeFunctions x) env) oldDom + writeIORef refToOldStuff (OldStuff newState newDom) + +eventable + :: IORef (OldStuff state jsval) + -> (state -> PwNode state jsval) + -> jsval + -> (jsval -> state -> IO state) + -> ReaderT (JSEnv jsval) IO jsval +eventable refToOldStuff domCreationF topLevelNode eventToState = do + __makeHaskellCallback1 <- asks _makeHaskellCallback1 + env <- ask + liftIO $ __makeHaskellCallback1 + (cbMaker refToOldStuff domCreationF topLevelNode eventToState env) + +hydratedAttrToDomifiedAttr + :: IORef (OldStuff state jsval) + -> (state -> PwNode state jsval) + -> jsval + -> (String, PwAttribute state jsval) + -> ReaderT (JSEnv jsval) IO (String, DomifiedAttribute jsval) +hydratedAttrToDomifiedAttr refToOldStuff domCreationF topLevelNode (k, PwTextAttribute t) + = return (k, DomifiedTextAttribute t) +hydratedAttrToDomifiedAttr refToOldStuff domCreationF topLevelNode (k, PwFunctionAttribute f) + = do + func <- eventable refToOldStuff domCreationF topLevelNode f + return (k, DomifiedFunctionAttribute func) + +setAtt + :: jsval + -> (String, DomifiedAttribute jsval) + -> ReaderT (JSEnv jsval) IO () +setAtt currentNode (k, DomifiedTextAttribute v) = do + _elementSetAttribute <- asks elementSetAttribute + liftIO $ _elementSetAttribute currentNode k v +setAtt currentNode kv = setEventHandler currentNode kv + +handleOnlyEventListener + :: (jsval -> String -> jsval -> IO ()) + -> jsval + -> (String, DomifiedAttribute jsval) + -> IO () +handleOnlyEventListener eventListenerHandlerF currentNode (k, DomifiedFunctionAttribute v) + = eventListenerHandlerF currentNode k v +handleOnlyEventListener _ _ _ = pure () + +setEventHandler + :: jsval + -> (String, DomifiedAttribute jsval) + -> ReaderT (JSEnv jsval) IO () +setEventHandler currentNode domifiedAttribute = do + _eventTargetAddEventListener <- asks eventTargetAddEventListener + liftIO $ handleOnlyEventListener _eventTargetAddEventListener + currentNode + domifiedAttribute + +removeEventHandler + :: jsval + -> (String, DomifiedAttribute jsval) + -> ReaderT (JSEnv jsval) IO () +removeEventHandler currentNode domifiedAttribute = do + _eventTargetRemoveEventListener <- asks eventTargetRemoveEventListener + liftIO $ handleOnlyEventListener _eventTargetRemoveEventListener + currentNode + domifiedAttribute + +domify + :: Bool + -> IORef (OldStuff state jsval) + -> (state -> PwNode state jsval) + -> jsval + -> jsval + -> Maybe jsval + -> HydratedPwNode state jsval + -> ReaderT (JSEnv jsval) IO (DomifiedPwNode jsval) +domify touchDOM refToOldStuff domCreationF parentNode topLevelNode replacing (HydratedPwElement tag attrs children) + = do + _documentCreateElement <- asks documentCreateElement + _nodeAppendChild <- asks nodeAppendChild + _nodeInsertBefore <- asks nodeInsertBefore + _nodeRemoveChild <- asks nodeRemoveChild + newNode <- liftIO $ _documentCreateElement tag + newAttributes <- mapM + (hydratedAttrToDomifiedAttr refToOldStuff domCreationF topLevelNode) + attrs + if touchDOM then mapM_ (setAtt newNode) newAttributes else pure () + newChildren <- mapM + (domify touchDOM refToOldStuff domCreationF newNode topLevelNode Nothing) + children + if touchDOM + then maybe + (liftIO $ _nodeAppendChild parentNode newNode) + (\x -> do + liftIO $ _nodeInsertBefore parentNode newNode x + liftIO $ _nodeRemoveChild parentNode x + ) + replacing + else pure () + liftIO $ return (DomifiedPwElement tag newAttributes newChildren newNode) +domify touchDOM _ _ parentNode topLevelNode replacing (HydratedPwTextNode text) + = do + _documentCreateElement <- asks documentCreateElement + _nodeAppendChild <- asks nodeAppendChild + _nodeInsertBefore <- asks nodeInsertBefore + _nodeRemoveChild <- asks nodeRemoveChild + _documentCreateTextNode <- asks documentCreateTextNode + newTextNode <- liftIO $ _documentCreateTextNode text + if touchDOM + then maybe + (liftIO $ _nodeAppendChild parentNode newTextNode) + (\x -> do + liftIO $ _nodeInsertBefore parentNode newTextNode x + liftIO $ _nodeRemoveChild parentNode x + ) + replacing + else pure () + liftIO $ return (DomifiedPwTextNode text newTextNode) + +getChildren :: DomifiedPwNode jsval -> [DomifiedPwNode jsval] +getChildren (DomifiedPwElement _ _ x _) = x +getChildren _ = [] + +setEventHandlers_ + :: jsval -> DomifiedPwNode jsval -> ReaderT (JSEnv jsval) IO () +setEventHandlers_ v (DomifiedPwElement _ a _ _) = mapM_ (setEventHandler v) a +setEventHandlers_ _ _ = liftIO $ pure () + +transformFromCurrentDom + :: jsval + -> [DomifiedPwNode jsval] + -> ReaderT (JSEnv jsval) IO [DomifiedPwNode jsval] +transformFromCurrentDom parentNode children = do + _nodeChildNodes <- asks nodeChildNodes + _kids <- liftIO $ _nodeChildNodes parentNode + let kids = fromMaybe [] _kids + newChildren <- sequence $ getZipList + ( transformFromCurrentDom + <$> ZipList kids + <*> ZipList (fmap getChildren children) + ) + sequence_ + $ getZipList (setEventHandlers_ <$> ZipList kids <*> ZipList children) + return $ getZipList + ( (\cur chldrn ptr -> cur { _dom_kids = chldrn, _dom_ptr = ptr }) + <$> ZipList children + <*> ZipList newChildren + <*> ZipList kids + ) + +addHandlers + :: jsval + -> DomifiedPwNode jsval + -> ReaderT (JSEnv jsval) IO (DomifiedPwNode jsval) +addHandlers parentNode curDom = do + transformed <- transformFromCurrentDom parentNode [curDom] + return (head transformed) + +__plzwrk + :: Bool + -> (state -> PwNode state jsval) + -> state + -> jsval + -> JSEnv jsval + -> IO (Maybe (DomifiedPwNode jsval)) +__plzwrk cleanDOM domF state parentNode env = do + refToOldStuff <- newIORef (OldStuff state Nothing) + newDom <- runReaderT + (reconcile cleanDOM + refToOldStuff + domF + parentNode + parentNode + Nothing + (Just $ hydrate state domF) + ) + env + writeIORef refToOldStuff (OldStuff state newDom) + if not cleanDOM + then maybe + (pure Nothing) + (\y -> do + withHandlers <- runReaderT (addHandlers parentNode y) env + writeIORef refToOldStuff (OldStuff state (Just y)) + return $ Just withHandlers + ) + newDom + else pure newDom + +_plzwrk + :: Bool + -> (state -> PwNode state jsval) + -> state + -> JSEnv jsval + -> String + -> IO (Maybe (DomifiedPwNode jsval)) +_plzwrk cleanDOM domF state env nodeId = do + parentNode <- documentGetElementById env nodeId + maybe (error ("Node with id not in DOM: " <> show nodeId)) + (\x -> __plzwrk cleanDOM domF state x env) + parentNode + + +-- |The main function that makes a web app. + +plzwrk + :: (state -> PwNode state jsval) -- ^ A function that takes a state and produces a DOM + -> state -- ^ An initial state + -> JSEnv jsval -- ^ A browser implementation, ie Asterius or the mock browser + -> String -- ^ The id of the element into which the DOM is inserted. Note that plzwrk manages all children under this element. Touching the managed elements can break plzwrk. + -> IO () -- ^ Returns nothing + +plzwrk domF state env nodeId = void $ _plzwrk True domF state env nodeId + +-- |A variant of plzwrk that acts on a node already rendered to the DOM, + +-- ie by server-side rendering. It assumes the node has been rendered + +-- with the same state-to-node function as well as the same state. + +plzwrkSSR + :: (state -> PwNode state jsval) -- ^ A function that takes a state and produces a DOM + -> state -- ^ An initial state + -> JSEnv jsval -- ^ A browser implementation, ie Asterius or the mock browser + -> String -- ^ The id of the element into which the DOM is inserted. Note that plzwrk manages all children under this element. Touching the managed elements can break plzwrk. + -> IO () -- ^ Returns nothing + +plzwrkSSR domF state env nodeId = void $ _plzwrk False domF state env nodeId + +_plzwrk' + :: Bool + -> (state -> PwNode state jsval) + -> state + -> JSEnv jsval + -> IO (Maybe (DomifiedPwNode jsval)) +_plzwrk' cleanDOM domF state env = do + parentNode <- documentBody env + __plzwrk cleanDOM domF state parentNode env + +-- |A variation of plzwrk that inserts the node as a child of the document's body. + +plzwrk' :: (state -> PwNode state jsval) -> state -> JSEnv jsval -> IO () +plzwrk' domF state env = void $ _plzwrk' True domF state env + +-- |A variation of plzwrk that inserts the node as a child of the document's body. + +plzwrkSSR' + :: (state -> PwNode state jsval) -> state -> JSEnv jsval -> IO () +plzwrkSSR' domF state env = void $ _plzwrk' False domF state env + +-- |A variation of plzwrk that takes no state. + +plzwrk'_ :: (() -> PwNode () jsval) -> JSEnv jsval -> IO () +plzwrk'_ domF = plzwrk' domF () + +-- |A variation of plzwrkSSR that takes no state. + +plzwrkSSR'_ :: (() -> PwNode () jsval) -> JSEnv jsval -> IO () +plzwrkSSR'_ domF = plzwrkSSR' domF ()
+ src/Web/Framework/Plzwrk/JSEnv.hs view
@@ -0,0 +1,137 @@+module Web.Framework.Plzwrk.JSEnv + ( JSEnv(..) + , RequestInit(..) + , FetchBody(..) + ) +where + +import Data.ByteString.Internal ( ByteString ) +import qualified Data.HashMap.Strict as HM + +-- | A data class holding functions that operate on opaque +-- JavaScript types, parameterized by @jsval@. When possible, +-- the real names of browser functions like 'addEventListener' +-- and 'appendChild' are used. +-- +-- JSEnv is currently implemented as data instead of as +-- a typeclass because it is unclear what type of additional +-- monadic transformer around IO would be most appropriate to +-- retain the state of @jsval@ objects, whereas when part of +-- a dataclass, the state retention is abstracted away. + +data JSEnv jsval = JSEnv + { + -- | Casts a value to an array of jsvals + castToArray :: jsval -> IO (Maybe [jsval]) + + -- | Casts a value to a bool + , castToBool :: jsval -> IO (Maybe Bool) + + -- | Casts a value to a bool + , castToByteString :: jsval -> IO (Maybe ByteString) + + -- | Casts a value to a double + , castToDouble :: jsval -> IO (Maybe Double) + + -- | Casts a value to an int + , castToInt :: jsval -> IO (Maybe Int) + + -- | Casts a value to a string + , castToString :: jsval -> IO (Maybe String) + + -- | Logs an opaque JavaScript value. See [Console.log](https://developer.mozilla.org/en-US/docs/Web/API/Console/log) + , consoleLog :: jsval -> IO () + + -- | A default request init + , defaultRequestInit :: RequestInit jsval + + -- | The body of the document. See [Document.body](https://developer.mozilla.org/en-US/docs/Web/API/Document/body) + , documentBody :: IO jsval + + -- | Creates an element with a given tag. See [Document.createElement](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) + , documentCreateElement :: String -> IO jsval + + -- | Creates a text node with the given text. See [Document.createTextNode](https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode) + , documentCreateTextNode :: String -> IO jsval + + -- | Gets an element by id from a document. See [Document.getElementById](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) + , documentGetElementById :: String -> IO (Maybe jsval) + + -- | Gets the head of a document. See [Document.head](https://developer.mozilla.org/en-US/docs/Web/API/Document/head) + , documentHead :: IO jsval + + -- | Calls the browser's fetch command + , fetch :: String -> RequestInit jsval -> IO jsval + + -- | Gets a JavaScript property, returning @Nothing@ if the object being called is null or undefined. + , getPropertyAsOpaque :: jsval -> String -> IO (Maybe jsval) + + -- | Invokes on target a function with 0 arguments. + , invokeOn0 :: jsval -> String -> IO jsval + + -- | Invokes on target a function with 1 argument. + , invokeOn1 :: jsval -> String -> jsval -> IO jsval + + -- | Invokes on target a function with 2 arguments. + , invokeOn2 :: jsval -> String -> jsval -> jsval -> IO jsval + + -- | jsval from an array of jsvals + , jsValFromArray :: [jsval] -> IO jsval + + -- | jsval from a bool + , jsValFromBool :: Bool -> IO jsval + + -- | jsval from a byte string + , jsValFromByteString :: ByteString -> IO jsval + + -- | jsval from a double + , jsValFromDouble :: Double -> IO jsval + + -- | jsval from an int + , jsValFromInt :: Int -> IO jsval + + -- | jsval from a string + , jsValFromString :: String -> IO jsval + + -- | Creates an object + , makeObject :: IO jsval + + -- | Generate a random double between 0 and 1. See [Math.random](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) + , mathRandom :: IO Double + + -- | Sets on an object a value + , setValue :: jsval -> String -> jsval -> IO () + + -- | Frees a callback. Should only be called in advanced cases. In most usage, callbacks are freed automatically by plzwrk. + , _freeCallback :: jsval -> IO () + + -- | Makes a haskell callback with one argument. Should only be called in advanced cases. In most usage, callbacks are created automatically by plzwrk. + , _makeHaskellCallback1 :: (jsval -> IO ()) -> IO jsval + + -- | Makes a haskell callback with two arguments. Should only be called in advanced cases. In most usage, callbacks are created automatically by plzwrk. + , _makeHaskellCallback2 :: (jsval -> jsval -> IO ()) -> IO jsval + + -- | Makes a haskell callback with three arguments. Should only be called in advanced cases. In most usage, callbacks are created automatically by plzwrk. + , _makeHaskellCallback3 :: (jsval -> jsval -> jsval -> IO ()) -> IO jsval + } + +-- |The body of a fetch request or response +data FetchBody jsval = + FormDataBody (HM.HashMap String jsval) -- ^ From form data, ie @multipart/form-data@ or @application/x-www-form-urlencoded@ + | StringBody String -- ^ A string, ie @text/plain@ or @application/json@ + | BlobBody jsval -- ^ A single file + | URLSearchParamsBody (HM.HashMap String String) -- ^ Useful for @application/x-www-form-urlencoded@ + | Uint8Array ByteString + +-- | Initialization parameters for a request made with fetch +data RequestInit jsval = RequestInit { + _ri_method :: Maybe String -- ^ The request method, e.g., GET, POST. The default is GET. + , _ri_headers :: Maybe (HM.HashMap String String) -- ^ Any headers you want to add to your request, contained within a Headers object or an object literal with ByteString values. + , _ri_body :: Maybe (FetchBody jsval) -- ^ Any body that you want to add to your request: this can be a Blob, BufferSource, FormData, URLSearchParams, USVString, or ReadableStream object. Note that a request using the GET or HEAD method cannot have a body. + , _ri_mode :: Maybe String -- ^ The mode you want to use for the request, e.g., cors, no-cors, same-origin, or navigate. The default is cors. + , _ri_credentials :: Maybe String -- ^ The request credentials you want to use for the request: omit, same-origin, or include. The default is same-origin. + , _ri_cache :: Maybe String -- ^ The cache mode you want to use for the request. + , _ri_redirect :: Maybe String -- ^ The redirect mode to use: follow, error, or manual. The default is follow. + , _ri_referrer :: Maybe String -- ^ A USVString specifying no-referrer, client, or a URL. The default is about:client. + , _ri_integrity :: Maybe String -- ^ Contains the subresource integrity value of the request (e.g., sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=). +}
src/Web/Framework/Plzwrk/MockJSVal.hs view
@@ -1,15 +1,27 @@ {-| + Module : Web.Framework.Plzwrk.MockJSVal + Description : Mock browser for testing + Copyright : (c) Mike Solomon 2020 + License : GPL-3 + Maintainer : mike@meeshkan.com + Stability : experimental + Portability : POSIX, Windows + + This module exports a mock browser called + @defaultInternalBrowser@ used in plzwrk's tests + and that can be used in your unit tests as well. + -} module Web.Framework.Plzwrk.MockJSVal ( MockJSVal(..) @@ -28,7 +40,7 @@ import Data.List ( elemIndex ) import Prelude hiding ( lookup ) import Web.Framework.Plzwrk.Base -import Web.Framework.Plzwrk.Browserful +import Web.Framework.Plzwrk.JSEnv data LogEvent = ListenerReceived String Int | AddedAsListenerTo Int @@ -58,7 +70,9 @@ data MockJSVal = MockJSElement Int String MockAttributes [MockJSVal] [LogEvent] | MockJSTextNode Int String [LogEvent] - | MockJSFunction Int (MockJSVal -> IO ()) [LogEvent] + | MockJSFunction1 Int (MockJSVal -> IO ()) [LogEvent] + | MockJSFunction2 Int (MockJSVal -> MockJSVal -> IO ()) [LogEvent] + | MockJSFunction3 Int (MockJSVal -> MockJSVal -> MockJSVal -> IO ()) [LogEvent] | MockJSObject Int (HashMap String Int) [LogEvent] | MockJSString Int String [LogEvent] | MockJSDouble Int Double [LogEvent] @@ -81,7 +95,9 @@ <> " " <> show e show (MockJSTextNode a b c) = show a <> " " <> show b <> " " <> show c - show (MockJSFunction a _ c) = show a <> " " <> show c + show (MockJSFunction1 a _ c) = show a <> " " <> show c + show (MockJSFunction2 a _ c) = show a <> " " <> show c + show (MockJSFunction3 a _ c) = show a <> " " <> show c show (MockJSObject a b c) = show a <> " " <> show b <> " " <> show c show (MockJSString a b c) = show a <> " " <> show b <> " " <> show c show (MockJSDouble a b c) = show a <> " " <> show b <> " " <> show c @@ -94,7 +110,9 @@ _withNewLog :: MockJSVal -> [LogEvent] -> MockJSVal _withNewLog (MockJSElement a b c d _) log = MockJSElement a b c d log _withNewLog (MockJSTextNode a b _ ) log = MockJSTextNode a b log -_withNewLog (MockJSFunction a b _ ) log = MockJSFunction a b log +_withNewLog (MockJSFunction1 a b _ ) log = MockJSFunction1 a b log +_withNewLog (MockJSFunction2 a b _ ) log = MockJSFunction2 a b log +_withNewLog (MockJSFunction3 a b _ ) log = MockJSFunction3 a b log _withNewLog (MockJSObject a b _ ) log = MockJSObject a b log _withNewLog (MockJSString a b _ ) log = MockJSString a b log _withNewLog (MockJSDouble a b _ ) log = MockJSDouble a b log @@ -116,7 +134,9 @@ _ptr :: MockJSVal -> Int _ptr (MockJSElement a _ _ _ _) = a _ptr (MockJSTextNode a _ _ ) = a -_ptr (MockJSFunction a _ _ ) = a +_ptr (MockJSFunction1 a _ _ ) = a +_ptr (MockJSFunction2 a _ _ ) = a +_ptr (MockJSFunction3 a _ _ ) = a _ptr (MockJSObject a _ _ ) = a _ptr (MockJSString a _ _ ) = a _ptr (MockJSDouble a _ _ ) = a @@ -130,12 +150,12 @@ -> String -> MockJSVal -> IO (MockAttributes, [LogEvent], [LogEvent]) -_eventTargetAddEventListener (MockJSElement n _ (MockAttributes atts lstns) _ logn) evt fn@(MockJSFunction m _ logm) +_eventTargetAddEventListener (MockJSElement n _ (MockAttributes atts lstns) _ logn) evt fn@(MockJSFunction1 m _ logm) = pure - $ ( MockAttributes atts $ insert evt fn lstns - , logn <> [ListenerReceived evt m] - , logm <> [AddedAsListenerTo n] - ) + ( MockAttributes atts $ insert evt fn lstns + , logn <> [ListenerReceived evt m] + , logm <> [AddedAsListenerTo n] + ) _eventTargetAddEventListener _ _ _ = error "Can only add event listener to element" @@ -143,19 +163,17 @@ :: MockJSVal -> String -> String -> IO (MockAttributes, [LogEvent]) _elementSetAttribute (MockJSElement n _ (MockAttributes atts lstns) _ logn) nm attr = pure - $ ( MockAttributes (insert nm attr atts) lstns - , logn <> [AttributeReceived nm attr] - ) + ( MockAttributes (insert nm attr atts) lstns + , logn <> [AttributeReceived nm attr] + ) _elementSetAttribute _ _ _ = error "Can only add event listener to element" _nodeAppendChild :: MockJSVal -> MockJSVal -> IO ([MockJSVal], [LogEvent], [LogEvent]) _nodeAppendChild (MockJSElement n _ _ kids logn) kid@(MockJSElement m _ _ _ logm) - = pure - $ (kids <> [kid], logn <> [ChildReceived m], logm <> [AddedAsChildTo n]) + = pure (kids <> [kid], logn <> [ChildReceived m], logm <> [AddedAsChildTo n]) _nodeAppendChild (MockJSElement n _ _ kids logn) kid@(MockJSTextNode m _ logm) - = pure - $ (kids <> [kid], logn <> [ChildReceived m], logm <> [AddedAsChildTo n]) + = pure (kids <> [kid], logn <> [ChildReceived m], logm <> [AddedAsChildTo n]) _nodeAppendChild _ _ = error "Can only append element to element" __nodeRemoveChild @@ -168,12 +186,11 @@ -> IO ([MockJSVal], [LogEvent], [LogEvent]) __nodeRemoveChild n kids logn kid m logm = maybe (error ("Existing item " <> show m <> " not child of " <> show n)) - (\x -> - pure - $ ( take x kids <> drop (x + 1) kids - , logn <> [RemovedNode m] - , logm <> [RemovedAsNodeFrom n] - ) + (\x -> pure + ( take x kids <> drop (x + 1) kids + , logn <> [RemovedNode m] + , logm <> [RemovedAsNodeFrom n] + ) ) (elemIndex (_ptr kid) (fmap _ptr kids)) @@ -190,15 +207,14 @@ -> String -> MockJSVal -> IO (MockAttributes, [LogEvent], [LogEvent]) -_eventTargetRemoveEventListener (MockJSElement n _ (MockAttributes atts lstns) _ logn) evt fn@(MockJSFunction m _ logm) +_eventTargetRemoveEventListener (MockJSElement n _ (MockAttributes atts lstns) _ logn) evt fn@(MockJSFunction1 m _ logm) = maybe (error ("Listener " <> show m <> " not child of " <> show n)) - (\x -> - pure - $ ( MockAttributes atts $ delete evt lstns - , logn <> [RemovedListener evt m] - , logm <> [RemovedAsListenerFrom n] - ) + (\x -> pure + ( MockAttributes atts $ delete evt lstns + , logn <> [RemovedListener evt m] + , logm <> [RemovedAsListenerFrom n] + ) ) (lookup evt lstns) _eventTargetRemoveEventListener _ _ _ = @@ -222,13 +238,12 @@ ) _nodeInsertBeforeInternal n kids logn newI m logm existingI l logl = maybe (error ("Existing item " <> show l <> " not child of " <> show n)) - (\x -> - pure - $ ( take x kids <> [newI] <> drop x kids - , logn <> [InsertedChildBefore m l] - , logm <> [InsertedAsChildBefore n l] - , logl <> [ElementAddedBefore m] - ) + (\x -> pure + ( take x kids <> [newI] <> drop x kids + , logn <> [InsertedChildBefore m l] + , logm <> [InsertedAsChildBefore n l] + , logl <> [ElementAddedBefore m] + ) ) (elemIndex (_ptr existingI) (fmap _ptr kids)) @@ -262,20 +277,29 @@ _nodeChildNodes _ = error "Can only get children of element" __freeCallback :: MockJSVal -> IO [LogEvent] -__freeCallback (MockJSFunction n _ log) = pure (log <> [FreeCallback n]) +__freeCallback (MockJSFunction1 n _ log) = pure (log <> [FreeCallback n]) +__freeCallback (MockJSFunction2 n _ log) = pure (log <> [FreeCallback n]) +__freeCallback (MockJSFunction3 n _ log) = pure (log <> [FreeCallback n]) __freeCallback _ = error "Can only free function" -dummyClick :: MockJSVal -> IO () --- todo give real number +isFree :: LogEvent -> Bool +isFree (FreeCallback _) = True +isFree _ = False +hasFree :: [LogEvent] -> Bool +hasFree l = or (fmap isFree l) -dummyClick (MockJSFunction _ f _) = f $ MockMouseEvent (-1) +-- todo give real number +dummyClick :: MockJSVal -> IO () +dummyClick (MockJSFunction1 _ f logs) = do + if hasFree logs then error "Trying to call freed callback" else pure () + f $ MockMouseEvent (-1) _htmlElemenetClick :: MockJSVal -> IO () _htmlElemenetClick (MockJSElement _ _ (MockAttributes _ evts) _ _) = do let oc = lookup "click" evts - maybe (pure ()) (\x -> dummyClick x) oc + maybe (pure ()) dummyClick oc _htmlElemenetClick _ = error "Can only free function" @@ -284,6 +308,7 @@ + data MockBrowserInternal = MockBrowserInternal { unBrowser :: HashMap Int MockJSVal , unCtr :: Int @@ -294,8 +319,8 @@ look env elt = do r <- readIORef env let bz = unBrowser r - maybe (error $ "Cannot find object pointer in env: " <> (show elt)) - (\x -> return x) + maybe (error $ "Cannot find object pointer in env: " <> show elt) + return (lookup elt bz) incr :: IORef MockBrowserInternal -> IO Int @@ -338,6 +363,7 @@ return i ---------------------- + _jsValFrom :: (Int -> s -> [LogEvent] -> MockJSVal) -> IORef MockBrowserInternal @@ -358,6 +384,7 @@ ---------------------- + _'mathRandom :: IORef MockBrowserInternal -> IO Double _'mathRandom _ = pure 0.5 @@ -380,15 +407,15 @@ | s == "tagName" = do tn <- _'elementTagName env i _v <- _'jsValFromString env tn - (return . Just) $ _v + (return . Just) _v | s == "textContent" = do tc <- _'nodeTextContent env i _v <- _'jsValFromString env tc - (return . Just) $ _v + (return . Just) _v | s == "childNodes" = do cn <- _'nodeChildNodes env i - _v <-_'jsValFromArray env cn - (return . Just) $ _v + _v <- _'jsValFromArray env cn + (return . Just) _v | otherwise = error $ "This property is not implemented yet in MockJSVal: " <> s @@ -470,10 +497,9 @@ _'fetch :: IORef MockBrowserInternal -> String -> RequestInit Int -> IO Int -_'fetch env _ _ = do - _o <- _'makeObject env - return _o -- return an empty object for now +_'fetch env _ _ = _'makeObject env + _'elementTagName :: IORef MockBrowserInternal -> Int -> IO String _'elementTagName env elt = do _elt <- look env elt @@ -489,8 +515,8 @@ _elt <- look env elt _nodeTextContent _elt -_'_freeCallback :: IORef MockBrowserInternal -> Int -> IO () -_'_freeCallback env fn = do +_'freeCallback :: IORef MockBrowserInternal -> Int -> IO () +_'freeCallback env fn = do _fn <- look env fn newLog <- __freeCallback _fn wrt env fn $ _withNewLog _fn newLog @@ -502,25 +528,25 @@ idEq :: String -> MockJSVal -> Bool idEq txt (MockJSElement _ _ (MockAttributes atts _) _ _) = - Just txt == (lookup "id" atts) + Just txt == lookup "id" atts idEq _ _ = False _'documentBody :: IORef MockBrowserInternal -> IO Int _'documentBody ref = do mb <- readIORef ref let browser = unBrowser mb - pt <- maybe (error "No body.") (\x -> pure $ _ptr x) $ lookup 0 browser - return pt + maybe (error "No body.") (pure . _ptr) (lookup 0 browser) _'documentHead :: IORef MockBrowserInternal -> IO Int _'documentHead ref = pure (-1) -- need to implement in mock? + _documentGetElementByIdInternal :: MockJSVal -> String -> [Int] _documentGetElementByIdInternal jsv@(MockJSElement _ _ _ ch _) txt = - if (idEq txt jsv) + if idEq txt jsv then [_ptr jsv] - else (foldr (++) [] $ fmap (\x -> _documentGetElementByIdInternal x txt) ch) + else concatMap (`_documentGetElementByIdInternal` txt) ch _documentGetElementByIdInternal _ _ = [] _'documentGetElementById @@ -529,7 +555,7 @@ body <- _'documentBody env _body <- look env body let elts = _documentGetElementByIdInternal _body txt - return $ if (null elts) then (Nothing) else (Just $ head elts) + return $ if null elts then Nothing else Just $ head elts _'nodeInsertBefore :: IORef MockBrowserInternal -> Int -> Int -> Int -> IO () _'nodeInsertBefore env parent newItem existingItem = do @@ -542,13 +568,27 @@ wrt env newItem $ _withNewLog _newItem newLogNewItem wrt env existingItem $ _withNewLog _existingItem newLogExistingItem -_'_makeHaskellCallback :: IORef MockBrowserInternal -> (Int -> IO ()) -> IO Int -_'_makeHaskellCallback env cb = do +_'makeHaskellCallback1 :: IORef MockBrowserInternal -> (Int -> IO ()) -> IO Int +_'makeHaskellCallback1 env cb = do i <- incr env - let elt = MockJSFunction i (\x -> cb $ _ptr x) [MadeCallback i] + let elt = MockJSFunction1 i (cb . _ptr) [MadeCallback i] wrt env i elt return i +_'makeHaskellCallback2 :: IORef MockBrowserInternal -> (Int -> Int -> IO ()) -> IO Int +_'makeHaskellCallback2 env cb = do + i <- incr env + let elt = MockJSFunction2 i (\x y -> cb (_ptr x) (_ptr y)) [MadeCallback i] + wrt env i elt + return i + +_'makeHaskellCallback3 :: IORef MockBrowserInternal -> (Int -> Int -> Int -> IO ()) -> IO Int +_'makeHaskellCallback3 env cb = do + i <- incr env + let elt = MockJSFunction3 i (\x y z -> cb (_ptr x) (_ptr y) (_ptr z)) [MadeCallback i] + wrt env i elt + return i + _'makeObject :: IORef MockBrowserInternal -> IO Int _'makeObject env = do i <- incr env @@ -644,8 +684,8 @@ , _ri_integrity = Nothing } -makeMockBrowserWithContext :: IORef MockBrowserInternal -> IO (Browserful Int) -makeMockBrowserWithContext r = return Browserful +makeMockBrowserWithContext :: IORef MockBrowserInternal -> IO (JSEnv Int) +makeMockBrowserWithContext r = return JSEnv { castToArray = _'castToArray r , castToBool = _'castToBool r , castToByteString = _'castToByteString r @@ -660,7 +700,7 @@ , documentGetElementById = _'documentGetElementById r , documentHead = _'documentHead r , fetch = _'fetch r - , _freeCallback = _'_freeCallback r + , _freeCallback = _'freeCallback r , getPropertyAsOpaque = _'getPropertyAsOpaque r , jsValFromArray = _'jsValFromArray r , jsValFromBool = _'jsValFromBool r @@ -673,7 +713,9 @@ , setValue = _'setValue r , invokeOn1 = _'invokeOn1 r , invokeOn2 = _'invokeOn2 r - , _makeHaskellCallback = _'_makeHaskellCallback r + , _makeHaskellCallback1 = _'makeHaskellCallback1 r + , _makeHaskellCallback2 = _'makeHaskellCallback2 r + , _makeHaskellCallback3 = _'makeHaskellCallback3 r , mathRandom = _'mathRandom r } @@ -686,7 +728,7 @@ [CreatedElement 0] newIORef MockBrowserInternal { unBrowser = singleton 0 body, unCtr = 1 } -makeMockBrowser :: IO (Browserful Int) +makeMockBrowser :: IO (JSEnv Int) makeMockBrowser = do rf <- defaultInternalBrowser makeMockBrowserWithContext rf
src/Web/Framework/Plzwrk/TH/HSX.hs view
@@ -50,7 +50,7 @@ attr <- many attribute ws close <- try (string "/>" <|> string ">") - if (length close) == 2 + if length close == 2 then return (HSXSelfClosingTag name attr) else do elementBody <- many elementHSXBody @@ -86,12 +86,12 @@ return $ HSXHaskellTxtAttribute value makeBracketed cmd contain = do - let start = ("#" <> cmd <> "{") + let start = "#" <> cmd <> "{" let end = "}#" string start value <- manyTill anyChar (string end) ws - return $ if (contain) then start <> value <> end else value + return $ if contain then start <> value <> end else value haskellCodeAttr = do value <- makeBracketed "c" False @@ -117,7 +117,7 @@ ws char '=' ws - value <- stringAttribute <|> (try haskellCodeAttr) <|> haskellTxtAttr + value <- stringAttribute <|> try haskellCodeAttr <|> haskellTxtAttr ws return (name, value)
src/Web/Framework/Plzwrk/TH/QuoteHSX.hs view
@@ -81,7 +81,13 @@ (TH.conE (TH.mkName "PwElement")) [ TH.litE (TH.StringL tag) , TH.listE (fmap hsxAttributeToExpQ attrs)- , foldl TH.appE (TH.varE (TH.mkName "foldr")) [(TH.varE (TH.mkName "plusplus")), (TH.conE (TH.mkName "[]")), TH.listE (fmap (\x -> hsxToExpQ True True x) elts)]+ , foldl+ TH.appE+ (TH.varE (TH.mkName "foldr"))+ [ TH.varE (TH.mkName "plusplus")+ , TH.conE (TH.mkName "[]")+ , TH.listE (fmap (hsxToExpQ True True) elts)+ ] ] ) hsxToExpQ lam returnAsList (HSXSelfClosingTag tag attrs) = asList@@ -89,9 +95,9 @@ (wrapInLambda lam $ foldl TH.appE (TH.conE (TH.mkName "PwElement"))- [ (TH.litE (TH.StringL tag))+ [ TH.litE (TH.StringL tag) , TH.listE (fmap hsxAttributeToExpQ attrs)- , (TH.conE (TH.mkName "[]"))+ , TH.conE (TH.mkName "[]") ] ) hsxToExpQ lam returnAsList (HSXBody b) = asList
src/Web/Framework/Plzwrk/Tag.hs view
@@ -206,12 +206,12 @@ , _data'_ , _data__ , _data'__ -, _datalist -, _datalist' -, _datalist_ -, _datalist'_ -, _datalist__ -, _datalist'__ +, datalist +, datalist' +, datalist_ +, datalist'_ +, datalist__ +, datalist'__ , dd , dd' , dd_ @@ -772,8 +772,8 @@ import Web.Framework.Plzwrk.Base type AFSig s opq - = [(String, (s -> PwAttribute s opq))] -> [s -> PwNode s opq] -> (s -> PwNode s opq) -type Sig s opq = [(String, (s -> PwAttribute s opq))] -> [s -> PwNode s opq] -> PwNode s opq + = [(String, s -> PwAttribute s opq)] -> [s -> PwNode s opq] -> (s -> PwNode s opq) +type Sig s opq = [(String, s -> PwAttribute s opq)] -> [s -> PwNode s opq] -> PwNode s opq type AFSig_ s opq = [s -> PwNode s opq] -> (s -> PwNode s opq) type Sig_ s opq = [s -> PwNode s opq] -> PwNode s opq @@ -783,2269 +783,2269 @@ a :: AFSig s opq -a x y = (\_ -> PwElement "a" x y) +a x y _ = PwElement "a" x y a' :: Sig s opq a' = PwElement "a" a_ :: AFSig_ s opq -a_ x = (\_ -> PwElement "a" dats x) +a_ x _ = PwElement "a" dats x a'_ :: Sig_ s opq -a'_ x = PwElement "a" dats x +a'_ = PwElement "a" dats a__ :: AFSig__ s opq -a__ x = (\_ -> PwElement "a" dats [txt x]) +a__ x _ = PwElement "a" dats [txt x] a'__ :: Sig__ s opq a'__ x = PwElement "a" dats [txt x] abbr :: AFSig s opq -abbr x y = (\_ -> PwElement "abbr" x y) +abbr x y _ = PwElement "abbr" x y abbr' :: Sig s opq abbr' = PwElement "abbr" abbr_ :: AFSig_ s opq -abbr_ x = (\_ -> PwElement "abbr" dats x) +abbr_ x _ = PwElement "abbr" dats x abbr'_ :: Sig_ s opq -abbr'_ x = PwElement "abbr" dats x +abbr'_ = PwElement "abbr" dats abbr__ :: AFSig__ s opq -abbr__ x = (\_ -> PwElement "abbr" dats [txt x]) +abbr__ x _ = PwElement "abbr" dats [txt x] abbr'__ :: Sig__ s opq abbr'__ x = PwElement "abbr" dats [txt x] acronym :: AFSig s opq -acronym x y = (\_ -> PwElement "acronym" x y) +acronym x y _ = PwElement "acronym" x y acronym' :: Sig s opq acronym' = PwElement "acronym" acronym_ :: AFSig_ s opq -acronym_ x = (\_ -> PwElement "acronym" dats x) +acronym_ x _ = PwElement "acronym" dats x acronym'_ :: Sig_ s opq -acronym'_ x = PwElement "acronym" dats x +acronym'_ = PwElement "acronym" dats acronym__ :: AFSig__ s opq -acronym__ x = (\_ -> PwElement "acronym" dats [txt x]) +acronym__ x _ = PwElement "acronym" dats [txt x] acronym'__ :: Sig__ s opq acronym'__ x = PwElement "acronym" dats [txt x] address :: AFSig s opq -address x y = (\_ -> PwElement "address" x y) +address x y _ = PwElement "address" x y address' :: Sig s opq address' = PwElement "address" address_ :: AFSig_ s opq -address_ x = (\_ -> PwElement "address" dats x) +address_ x _ = PwElement "address" dats x address'_ :: Sig_ s opq -address'_ x = PwElement "address" dats x +address'_ = PwElement "address" dats address__ :: AFSig__ s opq -address__ x = (\_ -> PwElement "address" dats [txt x]) +address__ x _ = PwElement "address" dats [txt x] address'__ :: Sig__ s opq address'__ x = PwElement "address" dats [txt x] applet :: AFSig s opq -applet x y = (\_ -> PwElement "applet" x y) +applet x y _ = PwElement "applet" x y applet' :: Sig s opq applet' = PwElement "applet" applet_ :: AFSig_ s opq -applet_ x = (\_ -> PwElement "applet" dats x) +applet_ x _ = PwElement "applet" dats x applet'_ :: Sig_ s opq -applet'_ x = PwElement "applet" dats x +applet'_ = PwElement "applet" dats applet__ :: AFSig__ s opq -applet__ x = (\_ -> PwElement "applet" dats [txt x]) +applet__ x _ = PwElement "applet" dats [txt x] applet'__ :: Sig__ s opq applet'__ x = PwElement "applet" dats [txt x] area :: AFSig s opq -area x y = (\_ -> PwElement "area" x y) +area x y _ = PwElement "area" x y area' :: Sig s opq area' = PwElement "area" area_ :: AFSig_ s opq -area_ x = (\_ -> PwElement "area" dats x) +area_ x _ = PwElement "area" dats x area'_ :: Sig_ s opq -area'_ x = PwElement "area" dats x +area'_ = PwElement "area" dats area__ :: AFSig__ s opq -area__ x = (\_ -> PwElement "area" dats [txt x]) +area__ x _ = PwElement "area" dats [txt x] area'__ :: Sig__ s opq area'__ x = PwElement "area" dats [txt x] article :: AFSig s opq -article x y = (\_ -> PwElement "article" x y) +article x y _ = PwElement "article" x y article' :: Sig s opq article' = PwElement "article" article_ :: AFSig_ s opq -article_ x = (\_ -> PwElement "article" dats x) +article_ x _ = PwElement "article" dats x article'_ :: Sig_ s opq -article'_ x = PwElement "article" dats x +article'_ = PwElement "article" dats article__ :: AFSig__ s opq -article__ x = (\_ -> PwElement "article" dats [txt x]) +article__ x _ = PwElement "article" dats [txt x] article'__ :: Sig__ s opq article'__ x = PwElement "article" dats [txt x] aside :: AFSig s opq -aside x y = (\_ -> PwElement "aside" x y) +aside x y _ = PwElement "aside" x y aside' :: Sig s opq aside' = PwElement "aside" aside_ :: AFSig_ s opq -aside_ x = (\_ -> PwElement "aside" dats x) +aside_ x _ = PwElement "aside" dats x aside'_ :: Sig_ s opq -aside'_ x = PwElement "aside" dats x +aside'_ = PwElement "aside" dats aside__ :: AFSig__ s opq -aside__ x = (\_ -> PwElement "aside" dats [txt x]) +aside__ x _ = PwElement "aside" dats [txt x] aside'__ :: Sig__ s opq aside'__ x = PwElement "aside" dats [txt x] audio :: AFSig s opq -audio x y = (\_ -> PwElement "audio" x y) +audio x y _ = PwElement "audio" x y audio' :: Sig s opq audio' = PwElement "audio" audio_ :: AFSig_ s opq -audio_ x = (\_ -> PwElement "audio" dats x) +audio_ x _ = PwElement "audio" dats x audio'_ :: Sig_ s opq -audio'_ x = PwElement "audio" dats x +audio'_ = PwElement "audio" dats audio__ :: AFSig__ s opq -audio__ x = (\_ -> PwElement "audio" dats [txt x]) +audio__ x _ = PwElement "audio" dats [txt x] audio'__ :: Sig__ s opq audio'__ x = PwElement "audio" dats [txt x] b :: AFSig s opq -b x y = (\_ -> PwElement "b" x y) +b x y _ = PwElement "b" x y b' :: Sig s opq b' = PwElement "b" b_ :: AFSig_ s opq -b_ x = (\_ -> PwElement "b" dats x) +b_ x _ = PwElement "b" dats x b'_ :: Sig_ s opq -b'_ x = PwElement "b" dats x +b'_ = PwElement "b" dats b__ :: AFSig__ s opq -b__ x = (\_ -> PwElement "b" dats [txt x]) +b__ x _ = PwElement "b" dats [txt x] b'__ :: Sig__ s opq b'__ x = PwElement "b" dats [txt x] base :: AFSig s opq -base x y = (\_ -> PwElement "base" x y) +base x y _ = PwElement "base" x y base' :: Sig s opq base' = PwElement "base" base_ :: AFSig_ s opq -base_ x = (\_ -> PwElement "base" dats x) +base_ x _ = PwElement "base" dats x base'_ :: Sig_ s opq -base'_ x = PwElement "base" dats x +base'_ = PwElement "base" dats base__ :: AFSig__ s opq -base__ x = (\_ -> PwElement "base" dats [txt x]) +base__ x _ = PwElement "base" dats [txt x] base'__ :: Sig__ s opq base'__ x = PwElement "base" dats [txt x] basefont :: AFSig s opq -basefont x y = (\_ -> PwElement "basefont" x y) +basefont x y _ = PwElement "basefont" x y basefont' :: Sig s opq basefont' = PwElement "basefont" basefont_ :: AFSig_ s opq -basefont_ x = (\_ -> PwElement "basefont" dats x) +basefont_ x _ = PwElement "basefont" dats x basefont'_ :: Sig_ s opq -basefont'_ x = PwElement "basefont" dats x +basefont'_ = PwElement "basefont" dats basefont__ :: AFSig__ s opq -basefont__ x = (\_ -> PwElement "basefont" dats [txt x]) +basefont__ x _ = PwElement "basefont" dats [txt x] basefont'__ :: Sig__ s opq basefont'__ x = PwElement "basefont" dats [txt x] bdi :: AFSig s opq -bdi x y = (\_ -> PwElement "bdi" x y) +bdi x y _ = PwElement "bdi" x y bdi' :: Sig s opq bdi' = PwElement "bdi" bdi_ :: AFSig_ s opq -bdi_ x = (\_ -> PwElement "bdi" dats x) +bdi_ x _ = PwElement "bdi" dats x bdi'_ :: Sig_ s opq -bdi'_ x = PwElement "bdi" dats x +bdi'_ = PwElement "bdi" dats bdi__ :: AFSig__ s opq -bdi__ x = (\_ -> PwElement "bdi" dats [txt x]) +bdi__ x _ = PwElement "bdi" dats [txt x] bdi'__ :: Sig__ s opq bdi'__ x = PwElement "bdi" dats [txt x] bdo :: AFSig s opq -bdo x y = (\_ -> PwElement "bdo" x y) +bdo x y _ = PwElement "bdo" x y bdo' :: Sig s opq bdo' = PwElement "bdo" bdo_ :: AFSig_ s opq -bdo_ x = (\_ -> PwElement "bdo" dats x) +bdo_ x _ = PwElement "bdo" dats x bdo'_ :: Sig_ s opq -bdo'_ x = PwElement "bdo" dats x +bdo'_ = PwElement "bdo" dats bdo__ :: AFSig__ s opq -bdo__ x = (\_ -> PwElement "bdo" dats [txt x]) +bdo__ x _ = PwElement "bdo" dats [txt x] bdo'__ :: Sig__ s opq bdo'__ x = PwElement "bdo" dats [txt x] big :: AFSig s opq -big x y = (\_ -> PwElement "big" x y) +big x y _ = PwElement "big" x y big' :: Sig s opq big' = PwElement "big" big_ :: AFSig_ s opq -big_ x = (\_ -> PwElement "big" dats x) +big_ x _ = PwElement "big" dats x big'_ :: Sig_ s opq -big'_ x = PwElement "big" dats x +big'_ = PwElement "big" dats big__ :: AFSig__ s opq -big__ x = (\_ -> PwElement "big" dats [txt x]) +big__ x _ = PwElement "big" dats [txt x] big'__ :: Sig__ s opq big'__ x = PwElement "big" dats [txt x] blockquote :: AFSig s opq -blockquote x y = (\_ -> PwElement "blockquote" x y) +blockquote x y _ = PwElement "blockquote" x y blockquote' :: Sig s opq blockquote' = PwElement "blockquote" blockquote_ :: AFSig_ s opq -blockquote_ x = (\_ -> PwElement "blockquote" dats x) +blockquote_ x _ = PwElement "blockquote" dats x blockquote'_ :: Sig_ s opq -blockquote'_ x = PwElement "blockquote" dats x +blockquote'_ = PwElement "blockquote" dats blockquote__ :: AFSig__ s opq -blockquote__ x = (\_ -> PwElement "blockquote" dats [txt x]) +blockquote__ x _ = PwElement "blockquote" dats [txt x] blockquote'__ :: Sig__ s opq blockquote'__ x = PwElement "blockquote" dats [txt x] body :: AFSig s opq -body x y = (\_ -> PwElement "body" x y) +body x y _ = PwElement "body" x y body' :: Sig s opq body' = PwElement "body" body_ :: AFSig_ s opq -body_ x = (\_ -> PwElement "body" dats x) +body_ x _ = PwElement "body" dats x body'_ :: Sig_ s opq -body'_ x = PwElement "body" dats x +body'_ = PwElement "body" dats body__ :: AFSig__ s opq -body__ x = (\_ -> PwElement "body" dats [txt x]) +body__ x _ = PwElement "body" dats [txt x] body'__ :: Sig__ s opq body'__ x = PwElement "body" dats [txt x] br :: (s -> PwNode s opq) -br = (\_ -> PwElement "br" dats []) +br _ = PwElement "br" dats [] button :: AFSig s opq -button x y = (\_ -> PwElement "button" x y) +button x y _ = PwElement "button" x y button' :: Sig s opq button' = PwElement "button" button_ :: AFSig_ s opq -button_ x = (\_ -> PwElement "button" dats x) +button_ x _ = PwElement "button" dats x button'_ :: Sig_ s opq -button'_ x = PwElement "button" dats x +button'_ = PwElement "button" dats button__ :: AFSig__ s opq -button__ x = (\_ -> PwElement "button" dats [txt x]) +button__ x _ = PwElement "button" dats [txt x] button'__ :: Sig__ s opq button'__ x = PwElement "button" dats [txt x] canvas :: AFSig s opq -canvas x y = (\_ -> PwElement "canvas" x y) +canvas x y _ = PwElement "canvas" x y canvas' :: Sig s opq canvas' = PwElement "canvas" canvas_ :: AFSig_ s opq -canvas_ x = (\_ -> PwElement "canvas" dats x) +canvas_ x _ = PwElement "canvas" dats x canvas'_ :: Sig_ s opq -canvas'_ x = PwElement "canvas" dats x +canvas'_ = PwElement "canvas" dats canvas__ :: AFSig__ s opq -canvas__ x = (\_ -> PwElement "canvas" dats [txt x]) +canvas__ x _ = PwElement "canvas" dats [txt x] canvas'__ :: Sig__ s opq canvas'__ x = PwElement "canvas" dats [txt x] caption :: AFSig s opq -caption x y = (\_ -> PwElement "caption" x y) +caption x y _ = PwElement "caption" x y caption' :: Sig s opq caption' = PwElement "caption" caption_ :: AFSig_ s opq -caption_ x = (\_ -> PwElement "caption" dats x) +caption_ x _ = PwElement "caption" dats x caption'_ :: Sig_ s opq -caption'_ x = PwElement "caption" dats x +caption'_ = PwElement "caption" dats caption__ :: AFSig__ s opq -caption__ x = (\_ -> PwElement "caption" dats [txt x]) +caption__ x _ = PwElement "caption" dats [txt x] caption'__ :: Sig__ s opq caption'__ x = PwElement "caption" dats [txt x] center :: AFSig s opq -center x y = (\_ -> PwElement "center" x y) +center x y _ = PwElement "center" x y center' :: Sig s opq center' = PwElement "center" center_ :: AFSig_ s opq -center_ x = (\_ -> PwElement "center" dats x) +center_ x _ = PwElement "center" dats x center'_ :: Sig_ s opq -center'_ x = PwElement "center" dats x +center'_ = PwElement "center" dats center__ :: AFSig__ s opq -center__ x = (\_ -> PwElement "center" dats [txt x]) +center__ x _ = PwElement "center" dats [txt x] center'__ :: Sig__ s opq center'__ x = PwElement "center" dats [txt x] cite :: AFSig s opq -cite x y = (\_ -> PwElement "cite" x y) +cite x y _ = PwElement "cite" x y cite' :: Sig s opq cite' = PwElement "cite" cite_ :: AFSig_ s opq -cite_ x = (\_ -> PwElement "cite" dats x) +cite_ x _ = PwElement "cite" dats x cite'_ :: Sig_ s opq -cite'_ x = PwElement "cite" dats x +cite'_ = PwElement "cite" dats cite__ :: AFSig__ s opq -cite__ x = (\_ -> PwElement "cite" dats [txt x]) +cite__ x _ = PwElement "cite" dats [txt x] cite'__ :: Sig__ s opq cite'__ x = PwElement "cite" dats [txt x] code :: AFSig s opq -code x y = (\_ -> PwElement "code" x y) +code x y _ = PwElement "code" x y code' :: Sig s opq code' = PwElement "code" code_ :: AFSig_ s opq -code_ x = (\_ -> PwElement "code" dats x) +code_ x _ = PwElement "code" dats x code'_ :: Sig_ s opq -code'_ x = PwElement "code" dats x +code'_ = PwElement "code" dats code__ :: AFSig__ s opq -code__ x = (\_ -> PwElement "code" dats [txt x]) +code__ x _ = PwElement "code" dats [txt x] code'__ :: Sig__ s opq code'__ x = PwElement "code" dats [txt x] col :: AFSig s opq -col x y = (\_ -> PwElement "col" x y) +col x y _ = PwElement "col" x y col' :: Sig s opq col' = PwElement "col" col_ :: AFSig_ s opq -col_ x = (\_ -> PwElement "col" dats x) +col_ x _ = PwElement "col" dats x col'_ :: Sig_ s opq -col'_ x = PwElement "col" dats x +col'_ = PwElement "col" dats col__ :: AFSig__ s opq -col__ x = (\_ -> PwElement "col" dats [txt x]) +col__ x _ = PwElement "col" dats [txt x] col'__ :: Sig__ s opq col'__ x = PwElement "col" dats [txt x] colgroup :: AFSig s opq -colgroup x y = (\_ -> PwElement "colgroup" x y) +colgroup x y _ = PwElement "colgroup" x y colgroup' :: Sig s opq colgroup' = PwElement "colgroup" colgroup_ :: AFSig_ s opq -colgroup_ x = (\_ -> PwElement "colgroup" dats x) +colgroup_ x _ = PwElement "colgroup" dats x colgroup'_ :: Sig_ s opq -colgroup'_ x = PwElement "colgroup" dats x +colgroup'_ = PwElement "colgroup" dats colgroup__ :: AFSig__ s opq -colgroup__ x = (\_ -> PwElement "colgroup" dats [txt x]) +colgroup__ x _ = PwElement "colgroup" dats [txt x] colgroup'__ :: Sig__ s opq colgroup'__ x = PwElement "colgroup" dats [txt x] _data :: AFSig s opq -_data x y = (\_ -> PwElement "_data" x y) +_data x y _ = PwElement "_data" x y _data' :: Sig s opq _data' = PwElement "_data" _data_ :: AFSig_ s opq -_data_ x = (\_ -> PwElement "_data" dats x) +_data_ x _ = PwElement "_data" dats x _data'_ :: Sig_ s opq -_data'_ x = PwElement "_data" dats x +_data'_ = PwElement "_data" dats _data__ :: AFSig__ s opq -_data__ x = (\_ -> PwElement "_data" dats [txt x]) +_data__ x _ = PwElement "_data" dats [txt x] _data'__ :: Sig__ s opq _data'__ x = PwElement "_data" dats [txt x] -_datalist :: AFSig s opq -_datalist x y = (\_ -> PwElement "_datalist" x y) +datalist :: AFSig s opq +datalist x y _ = PwElement "datalist" x y -_datalist' :: Sig s opq -_datalist' = PwElement "_datalist" +datalist' :: Sig s opq +datalist' = PwElement "datalist" -_datalist_ :: AFSig_ s opq -_datalist_ x = (\_ -> PwElement "_datalist" dats x) +datalist_ :: AFSig_ s opq +datalist_ x _ = PwElement "datalist" dats x -_datalist'_ :: Sig_ s opq -_datalist'_ x = PwElement "_datalist" dats x +datalist'_ :: Sig_ s opq +datalist'_ = PwElement "datalist" dats -_datalist__ :: AFSig__ s opq -_datalist__ x = (\_ -> PwElement "_datalist" dats [txt x]) +datalist__ :: AFSig__ s opq +datalist__ x _ = PwElement "datalist" dats [txt x] -_datalist'__ :: Sig__ s opq -_datalist'__ x = PwElement "_datalist" dats [txt x] +datalist'__ :: Sig__ s opq +datalist'__ x = PwElement "datalist" dats [txt x] dd :: AFSig s opq -dd x y = (\_ -> PwElement "dd" x y) +dd x y _ = PwElement "dd" x y dd' :: Sig s opq dd' = PwElement "dd" dd_ :: AFSig_ s opq -dd_ x = (\_ -> PwElement "dd" dats x) +dd_ x _ = PwElement "dd" dats x dd'_ :: Sig_ s opq -dd'_ x = PwElement "dd" dats x +dd'_ = PwElement "dd" dats dd__ :: AFSig__ s opq -dd__ x = (\_ -> PwElement "dd" dats [txt x]) +dd__ x _ = PwElement "dd" dats [txt x] dd'__ :: Sig__ s opq dd'__ x = PwElement "dd" dats [txt x] del :: AFSig s opq -del x y = (\_ -> PwElement "del" x y) +del x y _ = PwElement "del" x y del' :: Sig s opq del' = PwElement "del" del_ :: AFSig_ s opq -del_ x = (\_ -> PwElement "del" dats x) +del_ x _ = PwElement "del" dats x del'_ :: Sig_ s opq -del'_ x = PwElement "del" dats x +del'_ = PwElement "del" dats del__ :: AFSig__ s opq -del__ x = (\_ -> PwElement "del" dats [txt x]) +del__ x _ = PwElement "del" dats [txt x] del'__ :: Sig__ s opq del'__ x = PwElement "del" dats [txt x] details :: AFSig s opq -details x y = (\_ -> PwElement "details" x y) +details x y _ = PwElement "details" x y details' :: Sig s opq details' = PwElement "details" details_ :: AFSig_ s opq -details_ x = (\_ -> PwElement "details" dats x) +details_ x _ = PwElement "details" dats x details'_ :: Sig_ s opq -details'_ x = PwElement "details" dats x +details'_ = PwElement "details" dats details__ :: AFSig__ s opq -details__ x = (\_ -> PwElement "details" dats [txt x]) +details__ x _ = PwElement "details" dats [txt x] details'__ :: Sig__ s opq details'__ x = PwElement "details" dats [txt x] dfn :: AFSig s opq -dfn x y = (\_ -> PwElement "dfn" x y) +dfn x y _ = PwElement "dfn" x y dfn' :: Sig s opq dfn' = PwElement "dfn" dfn_ :: AFSig_ s opq -dfn_ x = (\_ -> PwElement "dfn" dats x) +dfn_ x _ = PwElement "dfn" dats x dfn'_ :: Sig_ s opq -dfn'_ x = PwElement "dfn" dats x +dfn'_ = PwElement "dfn" dats dfn__ :: AFSig__ s opq -dfn__ x = (\_ -> PwElement "dfn" dats [txt x]) +dfn__ x _ = PwElement "dfn" dats [txt x] dfn'__ :: Sig__ s opq dfn'__ x = PwElement "dfn" dats [txt x] dialog :: AFSig s opq -dialog x y = (\_ -> PwElement "dialog" x y) +dialog x y _ = PwElement "dialog" x y dialog' :: Sig s opq dialog' = PwElement "dialog" dialog_ :: AFSig_ s opq -dialog_ x = (\_ -> PwElement "dialog" dats x) +dialog_ x _ = PwElement "dialog" dats x dialog'_ :: Sig_ s opq -dialog'_ x = PwElement "dialog" dats x +dialog'_ = PwElement "dialog" dats dialog__ :: AFSig__ s opq -dialog__ x = (\_ -> PwElement "dialog" dats [txt x]) +dialog__ x _ = PwElement "dialog" dats [txt x] dialog'__ :: Sig__ s opq dialog'__ x = PwElement "dialog" dats [txt x] dir :: AFSig s opq -dir x y = (\_ -> PwElement "dir" x y) +dir x y _ = PwElement "dir" x y dir' :: Sig s opq dir' = PwElement "dir" dir_ :: AFSig_ s opq -dir_ x = (\_ -> PwElement "dir" dats x) +dir_ x _ = PwElement "dir" dats x dir'_ :: Sig_ s opq -dir'_ x = PwElement "dir" dats x +dir'_ = PwElement "dir" dats dir__ :: AFSig__ s opq -dir__ x = (\_ -> PwElement "dir" dats [txt x]) +dir__ x _ = PwElement "dir" dats [txt x] dir'__ :: Sig__ s opq dir'__ x = PwElement "dir" dats [txt x] div :: AFSig s opq -div x y = (\_ -> PwElement "div" x y) +div x y _ = PwElement "div" x y div' :: Sig s opq div' = PwElement "div" div_ :: AFSig_ s opq -div_ x = (\_ -> PwElement "div" dats x) +div_ x _ = PwElement "div" dats x div'_ :: Sig_ s opq -div'_ x = PwElement "div" dats x +div'_ = PwElement "div" dats div__ :: AFSig__ s opq -div__ x = (\_ -> PwElement "div" dats [txt x]) +div__ x _ = PwElement "div" dats [txt x] div'__ :: Sig__ s opq div'__ x = PwElement "div" dats [txt x] dl :: AFSig s opq -dl x y = (\_ -> PwElement "dl" x y) +dl x y _ = PwElement "dl" x y dl' :: Sig s opq dl' = PwElement "dl" dl_ :: AFSig_ s opq -dl_ x = (\_ -> PwElement "dl" dats x) +dl_ x _ = PwElement "dl" dats x dl'_ :: Sig_ s opq -dl'_ x = PwElement "dl" dats x +dl'_ = PwElement "dl" dats dl__ :: AFSig__ s opq -dl__ x = (\_ -> PwElement "dl" dats [txt x]) +dl__ x _ = PwElement "dl" dats [txt x] dl'__ :: Sig__ s opq dl'__ x = PwElement "dl" dats [txt x] dt :: AFSig s opq -dt x y = (\_ -> PwElement "dt" x y) +dt x y _ = PwElement "dt" x y dt' :: Sig s opq dt' = PwElement "dt" dt_ :: AFSig_ s opq -dt_ x = (\_ -> PwElement "dt" dats x) +dt_ x _ = PwElement "dt" dats x dt'_ :: Sig_ s opq -dt'_ x = PwElement "dt" dats x +dt'_ = PwElement "dt" dats dt__ :: AFSig__ s opq -dt__ x = (\_ -> PwElement "dt" dats [txt x]) +dt__ x _ = PwElement "dt" dats [txt x] dt'__ :: Sig__ s opq dt'__ x = PwElement "dt" dats [txt x] em :: AFSig s opq -em x y = (\_ -> PwElement "em" x y) +em x y _ = PwElement "em" x y em' :: Sig s opq em' = PwElement "em" em_ :: AFSig_ s opq -em_ x = (\_ -> PwElement "em" dats x) +em_ x _ = PwElement "em" dats x em'_ :: Sig_ s opq -em'_ x = PwElement "em" dats x +em'_ = PwElement "em" dats em__ :: AFSig__ s opq -em__ x = (\_ -> PwElement "em" dats [txt x]) +em__ x _ = PwElement "em" dats [txt x] em'__ :: Sig__ s opq em'__ x = PwElement "em" dats [txt x] embed :: AFSig s opq -embed x y = (\_ -> PwElement "embed" x y) +embed x y _ = PwElement "embed" x y embed' :: Sig s opq embed' = PwElement "embed" embed_ :: AFSig_ s opq -embed_ x = (\_ -> PwElement "embed" dats x) +embed_ x _ = PwElement "embed" dats x embed'_ :: Sig_ s opq -embed'_ x = PwElement "embed" dats x +embed'_ = PwElement "embed" dats embed__ :: AFSig__ s opq -embed__ x = (\_ -> PwElement "embed" dats [txt x]) +embed__ x _ = PwElement "embed" dats [txt x] embed'__ :: Sig__ s opq embed'__ x = PwElement "embed" dats [txt x] fieldset :: AFSig s opq -fieldset x y = (\_ -> PwElement "fieldset" x y) +fieldset x y _ = PwElement "fieldset" x y fieldset' :: Sig s opq fieldset' = PwElement "fieldset" fieldset_ :: AFSig_ s opq -fieldset_ x = (\_ -> PwElement "fieldset" dats x) +fieldset_ x _ = PwElement "fieldset" dats x fieldset'_ :: Sig_ s opq -fieldset'_ x = PwElement "fieldset" dats x +fieldset'_ = PwElement "fieldset" dats fieldset__ :: AFSig__ s opq -fieldset__ x = (\_ -> PwElement "fieldset" dats [txt x]) +fieldset__ x _ = PwElement "fieldset" dats [txt x] fieldset'__ :: Sig__ s opq fieldset'__ x = PwElement "fieldset" dats [txt x] figcaption :: AFSig s opq -figcaption x y = (\_ -> PwElement "figcaption" x y) +figcaption x y _ = PwElement "figcaption" x y figcaption' :: Sig s opq figcaption' = PwElement "figcaption" figcaption_ :: AFSig_ s opq -figcaption_ x = (\_ -> PwElement "figcaption" dats x) +figcaption_ x _ = PwElement "figcaption" dats x figcaption'_ :: Sig_ s opq -figcaption'_ x = PwElement "figcaption" dats x +figcaption'_ = PwElement "figcaption" dats figcaption__ :: AFSig__ s opq -figcaption__ x = (\_ -> PwElement "figcaption" dats [txt x]) +figcaption__ x _ = PwElement "figcaption" dats [txt x] figcaption'__ :: Sig__ s opq figcaption'__ x = PwElement "figcaption" dats [txt x] figure :: AFSig s opq -figure x y = (\_ -> PwElement "figure" x y) +figure x y _ = PwElement "figure" x y figure' :: Sig s opq figure' = PwElement "figure" figure_ :: AFSig_ s opq -figure_ x = (\_ -> PwElement "figure" dats x) +figure_ x _ = PwElement "figure" dats x figure'_ :: Sig_ s opq -figure'_ x = PwElement "figure" dats x +figure'_ = PwElement "figure" dats figure__ :: AFSig__ s opq -figure__ x = (\_ -> PwElement "figure" dats [txt x]) +figure__ x _ = PwElement "figure" dats [txt x] figure'__ :: Sig__ s opq figure'__ x = PwElement "figure" dats [txt x] font :: AFSig s opq -font x y = (\_ -> PwElement "font" x y) +font x y _ = PwElement "font" x y font' :: Sig s opq font' = PwElement "font" font_ :: AFSig_ s opq -font_ x = (\_ -> PwElement "font" dats x) +font_ x _ = PwElement "font" dats x font'_ :: Sig_ s opq -font'_ x = PwElement "font" dats x +font'_ = PwElement "font" dats font__ :: AFSig__ s opq -font__ x = (\_ -> PwElement "font" dats [txt x]) +font__ x _ = PwElement "font" dats [txt x] font'__ :: Sig__ s opq font'__ x = PwElement "font" dats [txt x] footer :: AFSig s opq -footer x y = (\_ -> PwElement "footer" x y) +footer x y _ = PwElement "footer" x y footer' :: Sig s opq footer' = PwElement "footer" footer_ :: AFSig_ s opq -footer_ x = (\_ -> PwElement "footer" dats x) +footer_ x _ = PwElement "footer" dats x footer'_ :: Sig_ s opq -footer'_ x = PwElement "footer" dats x +footer'_ = PwElement "footer" dats footer__ :: AFSig__ s opq -footer__ x = (\_ -> PwElement "footer" dats [txt x]) +footer__ x _ = PwElement "footer" dats [txt x] footer'__ :: Sig__ s opq footer'__ x = PwElement "footer" dats [txt x] form :: AFSig s opq -form x y = (\_ -> PwElement "form" x y) +form x y _ = PwElement "form" x y form' :: Sig s opq form' = PwElement "form" form_ :: AFSig_ s opq -form_ x = (\_ -> PwElement "form" dats x) +form_ x _ = PwElement "form" dats x form'_ :: Sig_ s opq -form'_ x = PwElement "form" dats x +form'_ = PwElement "form" dats form__ :: AFSig__ s opq -form__ x = (\_ -> PwElement "form" dats [txt x]) +form__ x _ = PwElement "form" dats [txt x] form'__ :: Sig__ s opq form'__ x = PwElement "form" dats [txt x] frame :: AFSig s opq -frame x y = (\_ -> PwElement "frame" x y) +frame x y _ = PwElement "frame" x y frame' :: Sig s opq frame' = PwElement "frame" frame_ :: AFSig_ s opq -frame_ x = (\_ -> PwElement "frame" dats x) +frame_ x _ = PwElement "frame" dats x frame'_ :: Sig_ s opq -frame'_ x = PwElement "frame" dats x +frame'_ = PwElement "frame" dats frame__ :: AFSig__ s opq -frame__ x = (\_ -> PwElement "frame" dats [txt x]) +frame__ x _ = PwElement "frame" dats [txt x] frame'__ :: Sig__ s opq frame'__ x = PwElement "frame" dats [txt x] frameset :: AFSig s opq -frameset x y = (\_ -> PwElement "frameset" x y) +frameset x y _ = PwElement "frameset" x y frameset' :: Sig s opq frameset' = PwElement "frameset" frameset_ :: AFSig_ s opq -frameset_ x = (\_ -> PwElement "frameset" dats x) +frameset_ x _ = PwElement "frameset" dats x frameset'_ :: Sig_ s opq -frameset'_ x = PwElement "frameset" dats x +frameset'_ = PwElement "frameset" dats frameset__ :: AFSig__ s opq -frameset__ x = (\_ -> PwElement "frameset" dats [txt x]) +frameset__ x _ = PwElement "frameset" dats [txt x] frameset'__ :: Sig__ s opq frameset'__ x = PwElement "frameset" dats [txt x] head :: AFSig s opq -head x y = (\_ -> PwElement "head" x y) +head x y _ = PwElement "head" x y head' :: Sig s opq head' = PwElement "head" head_ :: AFSig_ s opq -head_ x = (\_ -> PwElement "head" dats x) +head_ x _ = PwElement "head" dats x head'_ :: Sig_ s opq -head'_ x = PwElement "head" dats x +head'_ = PwElement "head" dats head__ :: AFSig__ s opq -head__ x = (\_ -> PwElement "head" dats [txt x]) +head__ x _ = PwElement "head" dats [txt x] head'__ :: Sig__ s opq head'__ x = PwElement "head" dats [txt x] header :: AFSig s opq -header x y = (\_ -> PwElement "header" x y) +header x y _ = PwElement "header" x y header' :: Sig s opq header' = PwElement "header" header_ :: AFSig_ s opq -header_ x = (\_ -> PwElement "header" dats x) +header_ x _ = PwElement "header" dats x header'_ :: Sig_ s opq -header'_ x = PwElement "header" dats x +header'_ = PwElement "header" dats header__ :: AFSig__ s opq -header__ x = (\_ -> PwElement "header" dats [txt x]) +header__ x _ = PwElement "header" dats [txt x] header'__ :: Sig__ s opq header'__ x = PwElement "header" dats [txt x] hr :: (s -> PwNode s opq) -hr = (\_ -> PwElement "br" dats []) +hr _ = PwElement "br" dats [] html :: AFSig s opq -html x y = (\_ -> PwElement "html" x y) +html x y _ = PwElement "html" x y html' :: Sig s opq html' = PwElement "html" html_ :: AFSig_ s opq -html_ x = (\_ -> PwElement "html" dats x) +html_ x _ = PwElement "html" dats x html'_ :: Sig_ s opq -html'_ x = PwElement "html" dats x +html'_ = PwElement "html" dats html__ :: AFSig__ s opq -html__ x = (\_ -> PwElement "html" dats [txt x]) +html__ x _ = PwElement "html" dats [txt x] html'__ :: Sig__ s opq html'__ x = PwElement "html" dats [txt x] i :: AFSig s opq -i x y = (\_ -> PwElement "i" x y) +i x y _ = PwElement "i" x y i' :: Sig s opq i' = PwElement "i" i_ :: AFSig_ s opq -i_ x = (\_ -> PwElement "i" dats x) +i_ x _ = PwElement "i" dats x i'_ :: Sig_ s opq -i'_ x = PwElement "i" dats x +i'_ = PwElement "i" dats i__ :: AFSig__ s opq -i__ x = (\_ -> PwElement "i" dats [txt x]) +i__ x _ = PwElement "i" dats [txt x] i'__ :: Sig__ s opq i'__ x = PwElement "i" dats [txt x] iframe :: AFSig s opq -iframe x y = (\_ -> PwElement "iframe" x y) +iframe x y _ = PwElement "iframe" x y iframe' :: Sig s opq iframe' = PwElement "iframe" iframe_ :: AFSig_ s opq -iframe_ x = (\_ -> PwElement "iframe" dats x) +iframe_ x _ = PwElement "iframe" dats x iframe'_ :: Sig_ s opq -iframe'_ x = PwElement "iframe" dats x +iframe'_ = PwElement "iframe" dats iframe__ :: AFSig__ s opq -iframe__ x = (\_ -> PwElement "iframe" dats [txt x]) +iframe__ x _ = PwElement "iframe" dats [txt x] iframe'__ :: Sig__ s opq iframe'__ x = PwElement "iframe" dats [txt x] -img :: [(String, (s -> PwAttribute s opq))] -> (s -> PwNode s opq) -img x = (\_ -> PwElement "img" x []) +img :: [(String, s -> PwAttribute s opq)] -> (s -> PwNode s opq) +img x _ = PwElement "img" x [] -img' :: [(String, (s -> PwAttribute s opq))] -> PwNode s opq +img' :: [(String, s -> PwAttribute s opq)] -> PwNode s opq img' x = PwElement "img" x [] img_ :: (s -> PwNode s opq) -img_ = (\_ -> PwElement "img" dats []) +img_ _ = PwElement "img" dats [] img'_ :: PwNode s opq img'_ = PwElement "img" dats [] input :: AFSig s opq -input x y = (\_ -> PwElement "input" x y) +input x y _ = PwElement "input" x y input' :: Sig s opq input' = PwElement "input" input_ :: AFSig_ s opq -input_ x = (\_ -> PwElement "input" dats x) +input_ x _ = PwElement "input" dats x input'_ :: Sig_ s opq -input'_ x = PwElement "input" dats x +input'_ = PwElement "input" dats input__ :: AFSig__ s opq -input__ x = (\_ -> PwElement "input" dats [txt x]) +input__ x _ = PwElement "input" dats [txt x] input'__ :: Sig__ s opq input'__ x = PwElement "input" dats [txt x] ins :: AFSig s opq -ins x y = (\_ -> PwElement "ins" x y) +ins x y _ = PwElement "ins" x y ins' :: Sig s opq ins' = PwElement "ins" ins_ :: AFSig_ s opq -ins_ x = (\_ -> PwElement "ins" dats x) +ins_ x _ = PwElement "ins" dats x ins'_ :: Sig_ s opq -ins'_ x = PwElement "ins" dats x +ins'_ = PwElement "ins" dats ins__ :: AFSig__ s opq -ins__ x = (\_ -> PwElement "ins" dats [txt x]) +ins__ x _ = PwElement "ins" dats [txt x] ins'__ :: Sig__ s opq ins'__ x = PwElement "ins" dats [txt x] kbd :: AFSig s opq -kbd x y = (\_ -> PwElement "kbd" x y) +kbd x y _ = PwElement "kbd" x y kbd' :: Sig s opq kbd' = PwElement "kbd" kbd_ :: AFSig_ s opq -kbd_ x = (\_ -> PwElement "kbd" dats x) +kbd_ x _ = PwElement "kbd" dats x kbd'_ :: Sig_ s opq -kbd'_ x = PwElement "kbd" dats x +kbd'_ = PwElement "kbd" dats kbd__ :: AFSig__ s opq -kbd__ x = (\_ -> PwElement "kbd" dats [txt x]) +kbd__ x _ = PwElement "kbd" dats [txt x] kbd'__ :: Sig__ s opq kbd'__ x = PwElement "kbd" dats [txt x] label :: AFSig s opq -label x y = (\_ -> PwElement "label" x y) +label x y _ = PwElement "label" x y label' :: Sig s opq label' = PwElement "label" label_ :: AFSig_ s opq -label_ x = (\_ -> PwElement "label" dats x) +label_ x _ = PwElement "label" dats x label'_ :: Sig_ s opq -label'_ x = PwElement "label" dats x +label'_ = PwElement "label" dats label__ :: AFSig__ s opq -label__ x = (\_ -> PwElement "label" dats [txt x]) +label__ x _ = PwElement "label" dats [txt x] label'__ :: Sig__ s opq label'__ x = PwElement "label" dats [txt x] legend :: AFSig s opq -legend x y = (\_ -> PwElement "legend" x y) +legend x y _ = PwElement "legend" x y legend' :: Sig s opq legend' = PwElement "legend" legend_ :: AFSig_ s opq -legend_ x = (\_ -> PwElement "legend" dats x) +legend_ x _ = PwElement "legend" dats x legend'_ :: Sig_ s opq -legend'_ x = PwElement "legend" dats x +legend'_ = PwElement "legend" dats legend__ :: AFSig__ s opq -legend__ x = (\_ -> PwElement "legend" dats [txt x]) +legend__ x _ = PwElement "legend" dats [txt x] legend'__ :: Sig__ s opq legend'__ x = PwElement "legend" dats [txt x] li :: AFSig s opq -li x y = (\_ -> PwElement "li" x y) +li x y _ = PwElement "li" x y li' :: Sig s opq li' = PwElement "li" li_ :: AFSig_ s opq -li_ x = (\_ -> PwElement "li" dats x) +li_ x _ = PwElement "li" dats x li'_ :: Sig_ s opq -li'_ x = PwElement "li" dats x +li'_ = PwElement "li" dats li__ :: AFSig__ s opq -li__ x = (\_ -> PwElement "li" dats [txt x]) +li__ x _ = PwElement "li" dats [txt x] li'__ :: Sig__ s opq li'__ x = PwElement "li" dats [txt x] link :: AFSig s opq -link x y = (\_ -> PwElement "link" x y) +link x y _ = PwElement "link" x y link' :: Sig s opq link' = PwElement "link" link_ :: AFSig_ s opq -link_ x = (\_ -> PwElement "link" dats x) +link_ x _ = PwElement "link" dats x link'_ :: Sig_ s opq -link'_ x = PwElement "link" dats x +link'_ = PwElement "link" dats link__ :: AFSig__ s opq -link__ x = (\_ -> PwElement "link" dats [txt x]) +link__ x _ = PwElement "link" dats [txt x] link'__ :: Sig__ s opq link'__ x = PwElement "link" dats [txt x] main :: AFSig s opq -main x y = (\_ -> PwElement "main" x y) +main x y _ = PwElement "main" x y main' :: Sig s opq main' = PwElement "main" main_ :: AFSig_ s opq -main_ x = (\_ -> PwElement "main" dats x) +main_ x _ = PwElement "main" dats x main'_ :: Sig_ s opq -main'_ x = PwElement "main" dats x +main'_ = PwElement "main" dats main__ :: AFSig__ s opq -main__ x = (\_ -> PwElement "main" dats [txt x]) +main__ x _ = PwElement "main" dats [txt x] main'__ :: Sig__ s opq main'__ x = PwElement "main" dats [txt x] map :: AFSig s opq -map x y = (\_ -> PwElement "map" x y) +map x y _ = PwElement "map" x y map' :: Sig s opq map' = PwElement "map" map_ :: AFSig_ s opq -map_ x = (\_ -> PwElement "map" dats x) +map_ x _ = PwElement "map" dats x map'_ :: Sig_ s opq -map'_ x = PwElement "map" dats x +map'_ = PwElement "map" dats map__ :: AFSig__ s opq -map__ x = (\_ -> PwElement "map" dats [txt x]) +map__ x _ = PwElement "map" dats [txt x] map'__ :: Sig__ s opq map'__ x = PwElement "map" dats [txt x] mark :: AFSig s opq -mark x y = (\_ -> PwElement "mark" x y) +mark x y _ = PwElement "mark" x y mark' :: Sig s opq mark' = PwElement "mark" mark_ :: AFSig_ s opq -mark_ x = (\_ -> PwElement "mark" dats x) +mark_ x _ = PwElement "mark" dats x mark'_ :: Sig_ s opq -mark'_ x = PwElement "mark" dats x +mark'_ = PwElement "mark" dats mark__ :: AFSig__ s opq -mark__ x = (\_ -> PwElement "mark" dats [txt x]) +mark__ x _ = PwElement "mark" dats [txt x] mark'__ :: Sig__ s opq mark'__ x = PwElement "mark" dats [txt x] meta :: AFSig s opq -meta x y = (\_ -> PwElement "meta" x y) +meta x y _ = PwElement "meta" x y meta' :: Sig s opq meta' = PwElement "meta" meta_ :: AFSig_ s opq -meta_ x = (\_ -> PwElement "meta" dats x) +meta_ x _ = PwElement "meta" dats x meta'_ :: Sig_ s opq -meta'_ x = PwElement "meta" dats x +meta'_ = PwElement "meta" dats meta__ :: AFSig__ s opq -meta__ x = (\_ -> PwElement "meta" dats [txt x]) +meta__ x _ = PwElement "meta" dats [txt x] meta'__ :: Sig__ s opq meta'__ x = PwElement "meta" dats [txt x] meter :: AFSig s opq -meter x y = (\_ -> PwElement "meter" x y) +meter x y _ = PwElement "meter" x y meter' :: Sig s opq meter' = PwElement "meter" meter_ :: AFSig_ s opq -meter_ x = (\_ -> PwElement "meter" dats x) +meter_ x _ = PwElement "meter" dats x meter'_ :: Sig_ s opq -meter'_ x = PwElement "meter" dats x +meter'_ = PwElement "meter" dats meter__ :: AFSig__ s opq -meter__ x = (\_ -> PwElement "meter" dats [txt x]) +meter__ x _ = PwElement "meter" dats [txt x] meter'__ :: Sig__ s opq meter'__ x = PwElement "meter" dats [txt x] nav :: AFSig s opq -nav x y = (\_ -> PwElement "nav" x y) +nav x y _ = PwElement "nav" x y nav' :: Sig s opq nav' = PwElement "nav" nav_ :: AFSig_ s opq -nav_ x = (\_ -> PwElement "nav" dats x) +nav_ x _ = PwElement "nav" dats x nav'_ :: Sig_ s opq -nav'_ x = PwElement "nav" dats x +nav'_ = PwElement "nav" dats nav__ :: AFSig__ s opq -nav__ x = (\_ -> PwElement "nav" dats [txt x]) +nav__ x _ = PwElement "nav" dats [txt x] nav'__ :: Sig__ s opq nav'__ x = PwElement "nav" dats [txt x] noframes :: AFSig s opq -noframes x y = (\_ -> PwElement "noframes" x y) +noframes x y _ = PwElement "noframes" x y noframes' :: Sig s opq noframes' = PwElement "noframes" noframes_ :: AFSig_ s opq -noframes_ x = (\_ -> PwElement "noframes" dats x) +noframes_ x _ = PwElement "noframes" dats x noframes'_ :: Sig_ s opq -noframes'_ x = PwElement "noframes" dats x +noframes'_ = PwElement "noframes" dats noframes__ :: AFSig__ s opq -noframes__ x = (\_ -> PwElement "noframes" dats [txt x]) +noframes__ x _ = PwElement "noframes" dats [txt x] noframes'__ :: Sig__ s opq noframes'__ x = PwElement "noframes" dats [txt x] noscript :: AFSig s opq -noscript x y = (\_ -> PwElement "noscript" x y) +noscript x y _ = PwElement "noscript" x y noscript' :: Sig s opq noscript' = PwElement "noscript" noscript_ :: AFSig_ s opq -noscript_ x = (\_ -> PwElement "noscript" dats x) +noscript_ x _ = PwElement "noscript" dats x noscript'_ :: Sig_ s opq -noscript'_ x = PwElement "noscript" dats x +noscript'_ = PwElement "noscript" dats noscript__ :: AFSig__ s opq -noscript__ x = (\_ -> PwElement "noscript" dats [txt x]) +noscript__ x _ = PwElement "noscript" dats [txt x] noscript'__ :: Sig__ s opq noscript'__ x = PwElement "noscript" dats [txt x] object :: AFSig s opq -object x y = (\_ -> PwElement "object" x y) +object x y _ = PwElement "object" x y object' :: Sig s opq object' = PwElement "object" object_ :: AFSig_ s opq -object_ x = (\_ -> PwElement "object" dats x) +object_ x _ = PwElement "object" dats x object'_ :: Sig_ s opq -object'_ x = PwElement "object" dats x +object'_ = PwElement "object" dats object__ :: AFSig__ s opq -object__ x = (\_ -> PwElement "object" dats [txt x]) +object__ x _ = PwElement "object" dats [txt x] object'__ :: Sig__ s opq object'__ x = PwElement "object" dats [txt x] ol :: AFSig s opq -ol x y = (\_ -> PwElement "ol" x y) +ol x y _ = PwElement "ol" x y ol' :: Sig s opq ol' = PwElement "ol" ol_ :: AFSig_ s opq -ol_ x = (\_ -> PwElement "ol" dats x) +ol_ x _ = PwElement "ol" dats x ol'_ :: Sig_ s opq -ol'_ x = PwElement "ol" dats x +ol'_ = PwElement "ol" dats ol__ :: AFSig__ s opq -ol__ x = (\_ -> PwElement "ol" dats [txt x]) +ol__ x _ = PwElement "ol" dats [txt x] ol'__ :: Sig__ s opq ol'__ x = PwElement "ol" dats [txt x] optgroup :: AFSig s opq -optgroup x y = (\_ -> PwElement "optgroup" x y) +optgroup x y _ = PwElement "optgroup" x y optgroup' :: Sig s opq optgroup' = PwElement "optgroup" optgroup_ :: AFSig_ s opq -optgroup_ x = (\_ -> PwElement "optgroup" dats x) +optgroup_ x _ = PwElement "optgroup" dats x optgroup'_ :: Sig_ s opq -optgroup'_ x = PwElement "optgroup" dats x +optgroup'_ = PwElement "optgroup" dats optgroup__ :: AFSig__ s opq -optgroup__ x = (\_ -> PwElement "optgroup" dats [txt x]) +optgroup__ x _ = PwElement "optgroup" dats [txt x] optgroup'__ :: Sig__ s opq optgroup'__ x = PwElement "optgroup" dats [txt x] option :: AFSig s opq -option x y = (\_ -> PwElement "option" x y) +option x y _ = PwElement "option" x y option' :: Sig s opq option' = PwElement "option" option_ :: AFSig_ s opq -option_ x = (\_ -> PwElement "option" dats x) +option_ x _ = PwElement "option" dats x option'_ :: Sig_ s opq -option'_ x = PwElement "option" dats x +option'_ = PwElement "option" dats option__ :: AFSig__ s opq -option__ x = (\_ -> PwElement "option" dats [txt x]) +option__ x _ = PwElement "option" dats [txt x] option'__ :: Sig__ s opq option'__ x = PwElement "option" dats [txt x] output :: AFSig s opq -output x y = (\_ -> PwElement "output" x y) +output x y _ = PwElement "output" x y output' :: Sig s opq output' = PwElement "output" output_ :: AFSig_ s opq -output_ x = (\_ -> PwElement "output" dats x) +output_ x _ = PwElement "output" dats x output'_ :: Sig_ s opq -output'_ x = PwElement "output" dats x +output'_ = PwElement "output" dats output__ :: AFSig__ s opq -output__ x = (\_ -> PwElement "output" dats [txt x]) +output__ x _ = PwElement "output" dats [txt x] output'__ :: Sig__ s opq output'__ x = PwElement "output" dats [txt x] p :: AFSig s opq -p x y = (\_ -> PwElement "p" x y) +p x y _ = PwElement "p" x y p' :: Sig s opq p' = PwElement "p" p_ :: AFSig_ s opq -p_ x = (\_ -> PwElement "p" dats x) +p_ x _ = PwElement "p" dats x p'_ :: Sig_ s opq -p'_ x = PwElement "p" dats x +p'_ = PwElement "p" dats p__ :: AFSig__ s opq -p__ x = (\_ -> PwElement "p" dats [txt x]) +p__ x _ = PwElement "p" dats [txt x] p'__ :: Sig__ s opq p'__ x = PwElement "p" dats [txt x] param :: AFSig s opq -param x y = (\_ -> PwElement "param" x y) +param x y _ = PwElement "param" x y param' :: Sig s opq param' = PwElement "param" param_ :: AFSig_ s opq -param_ x = (\_ -> PwElement "param" dats x) +param_ x _ = PwElement "param" dats x param'_ :: Sig_ s opq -param'_ x = PwElement "param" dats x +param'_ = PwElement "param" dats param__ :: AFSig__ s opq -param__ x = (\_ -> PwElement "param" dats [txt x]) +param__ x _ = PwElement "param" dats [txt x] param'__ :: Sig__ s opq param'__ x = PwElement "param" dats [txt x] picture :: AFSig s opq -picture x y = (\_ -> PwElement "picture" x y) +picture x y _ = PwElement "picture" x y picture' :: Sig s opq picture' = PwElement "picture" picture_ :: AFSig_ s opq -picture_ x = (\_ -> PwElement "picture" dats x) +picture_ x _ = PwElement "picture" dats x picture'_ :: Sig_ s opq -picture'_ x = PwElement "picture" dats x +picture'_ = PwElement "picture" dats picture__ :: AFSig__ s opq -picture__ x = (\_ -> PwElement "picture" dats [txt x]) +picture__ x _ = PwElement "picture" dats [txt x] picture'__ :: Sig__ s opq picture'__ x = PwElement "picture" dats [txt x] pre :: AFSig s opq -pre x y = (\_ -> PwElement "pre" x y) +pre x y _ = PwElement "pre" x y pre' :: Sig s opq pre' = PwElement "pre" pre_ :: AFSig_ s opq -pre_ x = (\_ -> PwElement "pre" dats x) +pre_ x _ = PwElement "pre" dats x pre'_ :: Sig_ s opq -pre'_ x = PwElement "pre" dats x +pre'_ = PwElement "pre" dats pre__ :: AFSig__ s opq -pre__ x = (\_ -> PwElement "pre" dats [txt x]) +pre__ x _ = PwElement "pre" dats [txt x] pre'__ :: Sig__ s opq pre'__ x = PwElement "pre" dats [txt x] progress :: AFSig s opq -progress x y = (\_ -> PwElement "progress" x y) +progress x y _ = PwElement "progress" x y progress' :: Sig s opq progress' = PwElement "progress" progress_ :: AFSig_ s opq -progress_ x = (\_ -> PwElement "progress" dats x) +progress_ x _ = PwElement "progress" dats x progress'_ :: Sig_ s opq -progress'_ x = PwElement "progress" dats x +progress'_ = PwElement "progress" dats progress__ :: AFSig__ s opq -progress__ x = (\_ -> PwElement "progress" dats [txt x]) +progress__ x _ = PwElement "progress" dats [txt x] progress'__ :: Sig__ s opq progress'__ x = PwElement "progress" dats [txt x] q :: AFSig s opq -q x y = (\_ -> PwElement "q" x y) +q x y _ = PwElement "q" x y q' :: Sig s opq q' = PwElement "q" q_ :: AFSig_ s opq -q_ x = (\_ -> PwElement "q" dats x) +q_ x _ = PwElement "q" dats x q'_ :: Sig_ s opq -q'_ x = PwElement "q" dats x +q'_ = PwElement "q" dats q__ :: AFSig__ s opq -q__ x = (\_ -> PwElement "q" dats [txt x]) +q__ x _ = PwElement "q" dats [txt x] q'__ :: Sig__ s opq q'__ x = PwElement "q" dats [txt x] rp :: AFSig s opq -rp x y = (\_ -> PwElement "rp" x y) +rp x y _ = PwElement "rp" x y rp' :: Sig s opq rp' = PwElement "rp" rp_ :: AFSig_ s opq -rp_ x = (\_ -> PwElement "rp" dats x) +rp_ x _ = PwElement "rp" dats x rp'_ :: Sig_ s opq -rp'_ x = PwElement "rp" dats x +rp'_ = PwElement "rp" dats rp__ :: AFSig__ s opq -rp__ x = (\_ -> PwElement "rp" dats [txt x]) +rp__ x _ = PwElement "rp" dats [txt x] rp'__ :: Sig__ s opq rp'__ x = PwElement "rp" dats [txt x] rt :: AFSig s opq -rt x y = (\_ -> PwElement "rt" x y) +rt x y _ = PwElement "rt" x y rt' :: Sig s opq rt' = PwElement "rt" rt_ :: AFSig_ s opq -rt_ x = (\_ -> PwElement "rt" dats x) +rt_ x _ = PwElement "rt" dats x rt'_ :: Sig_ s opq -rt'_ x = PwElement "rt" dats x +rt'_ = PwElement "rt" dats rt__ :: AFSig__ s opq -rt__ x = (\_ -> PwElement "rt" dats [txt x]) +rt__ x _ = PwElement "rt" dats [txt x] rt'__ :: Sig__ s opq rt'__ x = PwElement "rt" dats [txt x] ruby :: AFSig s opq -ruby x y = (\_ -> PwElement "ruby" x y) +ruby x y _ = PwElement "ruby" x y ruby' :: Sig s opq ruby' = PwElement "ruby" ruby_ :: AFSig_ s opq -ruby_ x = (\_ -> PwElement "ruby" dats x) +ruby_ x _ = PwElement "ruby" dats x ruby'_ :: Sig_ s opq -ruby'_ x = PwElement "ruby" dats x +ruby'_ = PwElement "ruby" dats ruby__ :: AFSig__ s opq -ruby__ x = (\_ -> PwElement "ruby" dats [txt x]) +ruby__ x _ = PwElement "ruby" dats [txt x] ruby'__ :: Sig__ s opq ruby'__ x = PwElement "ruby" dats [txt x] s :: AFSig s opq -s x y = (\_ -> PwElement "s" x y) +s x y _ = PwElement "s" x y s' :: Sig s opq s' = PwElement "s" s_ :: AFSig_ s opq -s_ x = (\_ -> PwElement "s" dats x) +s_ x _ = PwElement "s" dats x s'_ :: Sig_ s opq -s'_ x = PwElement "s" dats x +s'_ = PwElement "s" dats s__ :: AFSig__ s opq -s__ x = (\_ -> PwElement "s" dats [txt x]) +s__ x _ = PwElement "s" dats [txt x] s'__ :: Sig__ s opq s'__ x = PwElement "s" dats [txt x] samp :: AFSig s opq -samp x y = (\_ -> PwElement "samp" x y) +samp x y _ = PwElement "samp" x y samp' :: Sig s opq samp' = PwElement "samp" samp_ :: AFSig_ s opq -samp_ x = (\_ -> PwElement "samp" dats x) +samp_ x _ = PwElement "samp" dats x samp'_ :: Sig_ s opq -samp'_ x = PwElement "samp" dats x +samp'_ = PwElement "samp" dats samp__ :: AFSig__ s opq -samp__ x = (\_ -> PwElement "samp" dats [txt x]) +samp__ x _ = PwElement "samp" dats [txt x] samp'__ :: Sig__ s opq samp'__ x = PwElement "samp" dats [txt x] script :: AFSig s opq -script x y = (\_ -> PwElement "script" x y) +script x y _ = PwElement "script" x y script' :: Sig s opq script' = PwElement "script" script_ :: AFSig_ s opq -script_ x = (\_ -> PwElement "script" dats x) +script_ x _ = PwElement "script" dats x script'_ :: Sig_ s opq -script'_ x = PwElement "script" dats x +script'_ = PwElement "script" dats script__ :: AFSig__ s opq -script__ x = (\_ -> PwElement "script" dats [txt x]) +script__ x _ = PwElement "script" dats [txt x] script'__ :: Sig__ s opq script'__ x = PwElement "script" dats [txt x] section :: AFSig s opq -section x y = (\_ -> PwElement "section" x y) +section x y _ = PwElement "section" x y section' :: Sig s opq section' = PwElement "section" section_ :: AFSig_ s opq -section_ x = (\_ -> PwElement "section" dats x) +section_ x _ = PwElement "section" dats x section'_ :: Sig_ s opq -section'_ x = PwElement "section" dats x +section'_ = PwElement "section" dats section__ :: AFSig__ s opq -section__ x = (\_ -> PwElement "section" dats [txt x]) +section__ x _ = PwElement "section" dats [txt x] section'__ :: Sig__ s opq section'__ x = PwElement "section" dats [txt x] select :: AFSig s opq -select x y = (\_ -> PwElement "select" x y) +select x y _ = PwElement "select" x y select' :: Sig s opq select' = PwElement "select" select_ :: AFSig_ s opq -select_ x = (\_ -> PwElement "select" dats x) +select_ x _ = PwElement "select" dats x select'_ :: Sig_ s opq -select'_ x = PwElement "select" dats x +select'_ = PwElement "select" dats select__ :: AFSig__ s opq -select__ x = (\_ -> PwElement "select" dats [txt x]) +select__ x _ = PwElement "select" dats [txt x] select'__ :: Sig__ s opq select'__ x = PwElement "select" dats [txt x] small :: AFSig s opq -small x y = (\_ -> PwElement "small" x y) +small x y _ = PwElement "small" x y small' :: Sig s opq small' = PwElement "small" small_ :: AFSig_ s opq -small_ x = (\_ -> PwElement "small" dats x) +small_ x _ = PwElement "small" dats x small'_ :: Sig_ s opq -small'_ x = PwElement "small" dats x +small'_ = PwElement "small" dats small__ :: AFSig__ s opq -small__ x = (\_ -> PwElement "small" dats [txt x]) +small__ x _ = PwElement "small" dats [txt x] small'__ :: Sig__ s opq small'__ x = PwElement "small" dats [txt x] source :: AFSig s opq -source x y = (\_ -> PwElement "source" x y) +source x y _ = PwElement "source" x y source' :: Sig s opq source' = PwElement "source" source_ :: AFSig_ s opq -source_ x = (\_ -> PwElement "source" dats x) +source_ x _ = PwElement "source" dats x source'_ :: Sig_ s opq -source'_ x = PwElement "source" dats x +source'_ = PwElement "source" dats source__ :: AFSig__ s opq -source__ x = (\_ -> PwElement "source" dats [txt x]) +source__ x _ = PwElement "source" dats [txt x] source'__ :: Sig__ s opq source'__ x = PwElement "source" dats [txt x] span :: AFSig s opq -span x y = (\_ -> PwElement "span" x y) +span x y _ = PwElement "span" x y span' :: Sig s opq span' = PwElement "span" span_ :: AFSig_ s opq -span_ x = (\_ -> PwElement "span" dats x) +span_ x _ = PwElement "span" dats x span'_ :: Sig_ s opq -span'_ x = PwElement "span" dats x +span'_ = PwElement "span" dats span__ :: AFSig__ s opq -span__ x = (\_ -> PwElement "span" dats [txt x]) +span__ x _ = PwElement "span" dats [txt x] span'__ :: Sig__ s opq span'__ x = PwElement "span" dats [txt x] strike :: AFSig s opq -strike x y = (\_ -> PwElement "strike" x y) +strike x y _ = PwElement "strike" x y strike' :: Sig s opq strike' = PwElement "strike" strike_ :: AFSig_ s opq -strike_ x = (\_ -> PwElement "strike" dats x) +strike_ x _ = PwElement "strike" dats x strike'_ :: Sig_ s opq -strike'_ x = PwElement "strike" dats x +strike'_ = PwElement "strike" dats strike__ :: AFSig__ s opq -strike__ x = (\_ -> PwElement "strike" dats [txt x]) +strike__ x _ = PwElement "strike" dats [txt x] strike'__ :: Sig__ s opq strike'__ x = PwElement "strike" dats [txt x] strong :: AFSig s opq -strong x y = (\_ -> PwElement "strong" x y) +strong x y _ = PwElement "strong" x y strong' :: Sig s opq strong' = PwElement "strong" strong_ :: AFSig_ s opq -strong_ x = (\_ -> PwElement "strong" dats x) +strong_ x _ = PwElement "strong" dats x strong'_ :: Sig_ s opq -strong'_ x = PwElement "strong" dats x +strong'_ = PwElement "strong" dats strong__ :: AFSig__ s opq -strong__ x = (\_ -> PwElement "strong" dats [txt x]) +strong__ x _ = PwElement "strong" dats [txt x] strong'__ :: Sig__ s opq strong'__ x = PwElement "strong" dats [txt x] style :: AFSig s opq -style x y = (\_ -> PwElement "style" x y) +style x y _ = PwElement "style" x y style' :: Sig s opq style' = PwElement "style" style_ :: AFSig_ s opq -style_ x = (\_ -> PwElement "style" dats x) +style_ x _ = PwElement "style" dats x style'_ :: Sig_ s opq -style'_ x = PwElement "style" dats x +style'_ = PwElement "style" dats style__ :: AFSig__ s opq -style__ x = (\_ -> PwElement "style" dats [txt x]) +style__ x _ = PwElement "style" dats [txt x] style'__ :: Sig__ s opq style'__ x = PwElement "style" dats [txt x] sub :: AFSig s opq -sub x y = (\_ -> PwElement "sub" x y) +sub x y _ = PwElement "sub" x y sub' :: Sig s opq sub' = PwElement "sub" sub_ :: AFSig_ s opq -sub_ x = (\_ -> PwElement "sub" dats x) +sub_ x _ = PwElement "sub" dats x sub'_ :: Sig_ s opq -sub'_ x = PwElement "sub" dats x +sub'_ = PwElement "sub" dats sub__ :: AFSig__ s opq -sub__ x = (\_ -> PwElement "sub" dats [txt x]) +sub__ x _ = PwElement "sub" dats [txt x] sub'__ :: Sig__ s opq sub'__ x = PwElement "sub" dats [txt x] summary :: AFSig s opq -summary x y = (\_ -> PwElement "summary" x y) +summary x y _ = PwElement "summary" x y summary' :: Sig s opq summary' = PwElement "summary" summary_ :: AFSig_ s opq -summary_ x = (\_ -> PwElement "summary" dats x) +summary_ x _ = PwElement "summary" dats x summary'_ :: Sig_ s opq -summary'_ x = PwElement "summary" dats x +summary'_ = PwElement "summary" dats summary__ :: AFSig__ s opq -summary__ x = (\_ -> PwElement "summary" dats [txt x]) +summary__ x _ = PwElement "summary" dats [txt x] summary'__ :: Sig__ s opq summary'__ x = PwElement "summary" dats [txt x] sup :: AFSig s opq -sup x y = (\_ -> PwElement "sup" x y) +sup x y _ = PwElement "sup" x y sup' :: Sig s opq sup' = PwElement "sup" sup_ :: AFSig_ s opq -sup_ x = (\_ -> PwElement "sup" dats x) +sup_ x _ = PwElement "sup" dats x sup'_ :: Sig_ s opq -sup'_ x = PwElement "sup" dats x +sup'_ = PwElement "sup" dats sup__ :: AFSig__ s opq -sup__ x = (\_ -> PwElement "sup" dats [txt x]) +sup__ x _ = PwElement "sup" dats [txt x] sup'__ :: Sig__ s opq sup'__ x = PwElement "sup" dats [txt x] svg :: AFSig s opq -svg x y = (\_ -> PwElement "svg" x y) +svg x y _ = PwElement "svg" x y svg' :: Sig s opq svg' = PwElement "svg" svg_ :: AFSig_ s opq -svg_ x = (\_ -> PwElement "svg" dats x) +svg_ x _ = PwElement "svg" dats x svg'_ :: Sig_ s opq -svg'_ x = PwElement "svg" dats x +svg'_ = PwElement "svg" dats svg__ :: AFSig__ s opq -svg__ x = (\_ -> PwElement "svg" dats [txt x]) +svg__ x _ = PwElement "svg" dats [txt x] svg'__ :: Sig__ s opq svg'__ x = PwElement "svg" dats [txt x] table :: AFSig s opq -table x y = (\_ -> PwElement "table" x y) +table x y _ = PwElement "table" x y table' :: Sig s opq table' = PwElement "table" table_ :: AFSig_ s opq -table_ x = (\_ -> PwElement "table" dats x) +table_ x _ = PwElement "table" dats x table'_ :: Sig_ s opq -table'_ x = PwElement "table" dats x +table'_ = PwElement "table" dats table__ :: AFSig__ s opq -table__ x = (\_ -> PwElement "table" dats [txt x]) +table__ x _ = PwElement "table" dats [txt x] table'__ :: Sig__ s opq table'__ x = PwElement "table" dats [txt x] tbody :: AFSig s opq -tbody x y = (\_ -> PwElement "tbody" x y) +tbody x y _ = PwElement "tbody" x y tbody' :: Sig s opq tbody' = PwElement "tbody" tbody_ :: AFSig_ s opq -tbody_ x = (\_ -> PwElement "tbody" dats x) +tbody_ x _ = PwElement "tbody" dats x tbody'_ :: Sig_ s opq -tbody'_ x = PwElement "tbody" dats x +tbody'_ = PwElement "tbody" dats tbody__ :: AFSig__ s opq -tbody__ x = (\_ -> PwElement "tbody" dats [txt x]) +tbody__ x _ = PwElement "tbody" dats [txt x] tbody'__ :: Sig__ s opq tbody'__ x = PwElement "tbody" dats [txt x] td :: AFSig s opq -td x y = (\_ -> PwElement "td" x y) +td x y _ = PwElement "td" x y td' :: Sig s opq td' = PwElement "td" td_ :: AFSig_ s opq -td_ x = (\_ -> PwElement "td" dats x) +td_ x _ = PwElement "td" dats x td'_ :: Sig_ s opq -td'_ x = PwElement "td" dats x +td'_ = PwElement "td" dats td__ :: AFSig__ s opq -td__ x = (\_ -> PwElement "td" dats [txt x]) +td__ x _ = PwElement "td" dats [txt x] td'__ :: Sig__ s opq td'__ x = PwElement "td" dats [txt x] template :: AFSig s opq -template x y = (\_ -> PwElement "template" x y) +template x y _ = PwElement "template" x y template' :: Sig s opq template' = PwElement "template" template_ :: AFSig_ s opq -template_ x = (\_ -> PwElement "template" dats x) +template_ x _ = PwElement "template" dats x template'_ :: Sig_ s opq -template'_ x = PwElement "template" dats x +template'_ = PwElement "template" dats template__ :: AFSig__ s opq -template__ x = (\_ -> PwElement "template" dats [txt x]) +template__ x _ = PwElement "template" dats [txt x] template'__ :: Sig__ s opq template'__ x = PwElement "template" dats [txt x] textarea :: AFSig s opq -textarea x y = (\_ -> PwElement "textarea" x y) +textarea x y _ = PwElement "textarea" x y textarea' :: Sig s opq textarea' = PwElement "textarea" textarea_ :: AFSig_ s opq -textarea_ x = (\_ -> PwElement "textarea" dats x) +textarea_ x _ = PwElement "textarea" dats x textarea'_ :: Sig_ s opq -textarea'_ x = PwElement "textarea" dats x +textarea'_ = PwElement "textarea" dats textarea__ :: AFSig__ s opq -textarea__ x = (\_ -> PwElement "textarea" dats [txt x]) +textarea__ x _ = PwElement "textarea" dats [txt x] textarea'__ :: Sig__ s opq textarea'__ x = PwElement "textarea" dats [txt x] tfoot :: AFSig s opq -tfoot x y = (\_ -> PwElement "tfoot" x y) +tfoot x y _ = PwElement "tfoot" x y tfoot' :: Sig s opq tfoot' = PwElement "tfoot" tfoot_ :: AFSig_ s opq -tfoot_ x = (\_ -> PwElement "tfoot" dats x) +tfoot_ x _ = PwElement "tfoot" dats x tfoot'_ :: Sig_ s opq -tfoot'_ x = PwElement "tfoot" dats x +tfoot'_ = PwElement "tfoot" dats tfoot__ :: AFSig__ s opq -tfoot__ x = (\_ -> PwElement "tfoot" dats [txt x]) +tfoot__ x _ = PwElement "tfoot" dats [txt x] tfoot'__ :: Sig__ s opq tfoot'__ x = PwElement "tfoot" dats [txt x] th :: AFSig s opq -th x y = (\_ -> PwElement "th" x y) +th x y _ = PwElement "th" x y th' :: Sig s opq th' = PwElement "th" th_ :: AFSig_ s opq -th_ x = (\_ -> PwElement "th" dats x) +th_ x _ = PwElement "th" dats x th'_ :: Sig_ s opq -th'_ x = PwElement "th" dats x +th'_ = PwElement "th" dats th__ :: AFSig__ s opq -th__ x = (\_ -> PwElement "th" dats [txt x]) +th__ x _ = PwElement "th" dats [txt x] th'__ :: Sig__ s opq th'__ x = PwElement "th" dats [txt x] thead :: AFSig s opq -thead x y = (\_ -> PwElement "thead" x y) +thead x y _ = PwElement "thead" x y thead' :: Sig s opq thead' = PwElement "thead" thead_ :: AFSig_ s opq -thead_ x = (\_ -> PwElement "thead" dats x) +thead_ x _ = PwElement "thead" dats x thead'_ :: Sig_ s opq -thead'_ x = PwElement "thead" dats x +thead'_ = PwElement "thead" dats thead__ :: AFSig__ s opq -thead__ x = (\_ -> PwElement "thead" dats [txt x]) +thead__ x _ = PwElement "thead" dats [txt x] thead'__ :: Sig__ s opq thead'__ x = PwElement "thead" dats [txt x] time :: AFSig s opq -time x y = (\_ -> PwElement "time" x y) +time x y _ = PwElement "time" x y time' :: Sig s opq time' = PwElement "time" time_ :: AFSig_ s opq -time_ x = (\_ -> PwElement "time" dats x) +time_ x _ = PwElement "time" dats x time'_ :: Sig_ s opq -time'_ x = PwElement "time" dats x +time'_ = PwElement "time" dats time__ :: AFSig__ s opq -time__ x = (\_ -> PwElement "time" dats [txt x]) +time__ x _ = PwElement "time" dats [txt x] time'__ :: Sig__ s opq time'__ x = PwElement "time" dats [txt x] title :: AFSig s opq -title x y = (\_ -> PwElement "title" x y) +title x y _ = PwElement "title" x y title' :: Sig s opq title' = PwElement "title" title_ :: AFSig_ s opq -title_ x = (\_ -> PwElement "title" dats x) +title_ x _ = PwElement "title" dats x title'_ :: Sig_ s opq -title'_ x = PwElement "title" dats x +title'_ = PwElement "title" dats title__ :: AFSig__ s opq -title__ x = (\_ -> PwElement "title" dats [txt x]) +title__ x _ = PwElement "title" dats [txt x] title'__ :: Sig__ s opq title'__ x = PwElement "title" dats [txt x] tr :: AFSig s opq -tr x y = (\_ -> PwElement "tr" x y) +tr x y _ = PwElement "tr" x y tr' :: Sig s opq tr' = PwElement "tr" tr_ :: AFSig_ s opq -tr_ x = (\_ -> PwElement "tr" dats x) +tr_ x _ = PwElement "tr" dats x tr'_ :: Sig_ s opq -tr'_ x = PwElement "tr" dats x +tr'_ = PwElement "tr" dats tr__ :: AFSig__ s opq -tr__ x = (\_ -> PwElement "tr" dats [txt x]) +tr__ x _ = PwElement "tr" dats [txt x] tr'__ :: Sig__ s opq tr'__ x = PwElement "tr" dats [txt x] track :: AFSig s opq -track x y = (\_ -> PwElement "track" x y) +track x y _ = PwElement "track" x y track' :: Sig s opq track' = PwElement "track" track_ :: AFSig_ s opq -track_ x = (\_ -> PwElement "track" dats x) +track_ x _ = PwElement "track" dats x track'_ :: Sig_ s opq -track'_ x = PwElement "track" dats x +track'_ = PwElement "track" dats track__ :: AFSig__ s opq -track__ x = (\_ -> PwElement "track" dats [txt x]) +track__ x _ = PwElement "track" dats [txt x] track'__ :: Sig__ s opq track'__ x = PwElement "track" dats [txt x] tt :: AFSig s opq -tt x y = (\_ -> PwElement "tt" x y) +tt x y _ = PwElement "tt" x y tt' :: Sig s opq tt' = PwElement "tt" tt_ :: AFSig_ s opq -tt_ x = (\_ -> PwElement "tt" dats x) +tt_ x _ = PwElement "tt" dats x tt'_ :: Sig_ s opq -tt'_ x = PwElement "tt" dats x +tt'_ = PwElement "tt" dats tt__ :: AFSig__ s opq -tt__ x = (\_ -> PwElement "tt" dats [txt x]) +tt__ x _ = PwElement "tt" dats [txt x] tt'__ :: Sig__ s opq tt'__ x = PwElement "tt" dats [txt x] u :: AFSig s opq -u x y = (\_ -> PwElement "u" x y) +u x y _ = PwElement "u" x y u' :: Sig s opq u' = PwElement "u" u_ :: AFSig_ s opq -u_ x = (\_ -> PwElement "u" dats x) +u_ x _ = PwElement "u" dats x u'_ :: Sig_ s opq -u'_ x = PwElement "u" dats x +u'_ = PwElement "u" dats u__ :: AFSig__ s opq -u__ x = (\_ -> PwElement "u" dats [txt x]) +u__ x _ = PwElement "u" dats [txt x] u'__ :: Sig__ s opq u'__ x = PwElement "u" dats [txt x] ul :: AFSig s opq -ul x y = (\_ -> PwElement "ul" x y) +ul x y _ = PwElement "ul" x y ul' :: Sig s opq ul' = PwElement "ul" ul_ :: AFSig_ s opq -ul_ x = (\_ -> PwElement "ul" dats x) +ul_ x _ = PwElement "ul" dats x ul'_ :: Sig_ s opq -ul'_ x = PwElement "ul" dats x +ul'_ = PwElement "ul" dats ul__ :: AFSig__ s opq -ul__ x = (\_ -> PwElement "ul" dats [txt x]) +ul__ x _ = PwElement "ul" dats [txt x] ul'__ :: Sig__ s opq ul'__ x = PwElement "ul" dats [txt x] var :: AFSig s opq -var x y = (\_ -> PwElement "var" x y) +var x y _ = PwElement "var" x y var' :: Sig s opq var' = PwElement "var" var_ :: AFSig_ s opq -var_ x = (\_ -> PwElement "var" dats x) +var_ x _ = PwElement "var" dats x var'_ :: Sig_ s opq -var'_ x = PwElement "var" dats x +var'_ = PwElement "var" dats var__ :: AFSig__ s opq -var__ x = (\_ -> PwElement "var" dats [txt x]) +var__ x _ = PwElement "var" dats [txt x] var'__ :: Sig__ s opq var'__ x = PwElement "var" dats [txt x] video :: AFSig s opq -video x y = (\_ -> PwElement "video" x y) +video x y _ = PwElement "video" x y video' :: Sig s opq video' = PwElement "video" video_ :: AFSig_ s opq -video_ x = (\_ -> PwElement "video" dats x) +video_ x _ = PwElement "video" dats x video'_ :: Sig_ s opq -video'_ x = PwElement "video" dats x +video'_ = PwElement "video" dats video__ :: AFSig__ s opq -video__ x = (\_ -> PwElement "video" dats [txt x]) +video__ x _ = PwElement "video" dats [txt x] video'__ :: Sig__ s opq video'__ x = PwElement "video" dats [txt x] wbr :: (s -> PwNode s opq) -wbr = (\_ -> PwElement "br" dats []) +wbr _ = PwElement "br" dats [] txt :: String -> (s -> PwNode s opq) -txt t = (\_ -> PwTextNode t) +txt t _ = PwTextNode t txt' :: String -> PwNode s opq txt' = PwTextNode h1 :: AFSig s opq -h1 x y = (\_ -> PwElement "h1" x y) +h1 x y _ = PwElement "h1" x y h1' :: Sig s opq h1' = PwElement "h1" h1_ :: AFSig_ s opq -h1_ x = (\_ -> PwElement "h1" dats x) +h1_ x _ = PwElement "h1" dats x h1'_ :: Sig_ s opq -h1'_ x = PwElement "h1" dats x +h1'_ = PwElement "h1" dats h1__ :: AFSig__ s opq -h1__ x = (\_ -> PwElement "h1" dats [txt x]) +h1__ x _ = PwElement "h1" dats [txt x] h1'__ :: Sig__ s opq h1'__ x = PwElement "h1" dats [txt x] h2 :: AFSig s opq -h2 x y = (\_ -> PwElement "h2" x y) +h2 x y _ = PwElement "h2" x y h2' :: Sig s opq h2' = PwElement "h2" h2_ :: AFSig_ s opq -h2_ x = (\_ -> PwElement "h2" dats x) +h2_ x _ = PwElement "h2" dats x h2'_ :: Sig_ s opq -h2'_ x = PwElement "h2" dats x +h2'_ = PwElement "h2" dats h2__ :: AFSig__ s opq -h2__ x = (\_ -> PwElement "h2" dats [txt x]) +h2__ x _ = PwElement "h2" dats [txt x] h2'__ :: Sig__ s opq h2'__ x = PwElement "h2" dats [txt x] h3 :: AFSig s opq -h3 x y = (\_ -> PwElement "h3" x y) +h3 x y _ = PwElement "h3" x y h3' :: Sig s opq h3' = PwElement "h3" h3_ :: AFSig_ s opq -h3_ x = (\_ -> PwElement "h3" dats x) +h3_ x _ = PwElement "h3" dats x h3'_ :: Sig_ s opq -h3'_ x = PwElement "h3" dats x +h3'_ = PwElement "h3" dats h3__ :: AFSig__ s opq -h3__ x = (\_ -> PwElement "h3" dats [txt x]) +h3__ x _ = PwElement "h3" dats [txt x] h3'__ :: Sig__ s opq h3'__ x = PwElement "h3" dats [txt x] h4 :: AFSig s opq -h4 x y = (\_ -> PwElement "h4" x y) +h4 x y _ = PwElement "h4" x y h4' :: Sig s opq h4' = PwElement "h4" h4_ :: AFSig_ s opq -h4_ x = (\_ -> PwElement "h4" dats x) +h4_ x _ = PwElement "h4" dats x h4'_ :: Sig_ s opq -h4'_ x = PwElement "h4" dats x +h4'_ = PwElement "h4" dats h4__ :: AFSig__ s opq -h4__ x = (\_ -> PwElement "h4" dats [txt x]) +h4__ x _ = PwElement "h4" dats [txt x] h4'__ :: Sig__ s opq h4'__ x = PwElement "h4" dats [txt x] h5 :: AFSig s opq -h5 x y = (\_ -> PwElement "h5" x y) +h5 x y _ = PwElement "h5" x y h5' :: Sig s opq h5' = PwElement "h5" h5_ :: AFSig_ s opq -h5_ x = (\_ -> PwElement "h5" dats x) +h5_ x _ = PwElement "h5" dats x h5'_ :: Sig_ s opq -h5'_ x = PwElement "h5" dats x +h5'_ = PwElement "h5" dats h5__ :: AFSig__ s opq -h5__ x = (\_ -> PwElement "h5" dats [txt x]) +h5__ x _ = PwElement "h5" dats [txt x] h5'__ :: Sig__ s opq h5'__ x = PwElement "h5" dats [txt x] h6 :: AFSig s opq -h6 x y = (\_ -> PwElement "h6" x y) +h6 x y _ = PwElement "h6" x y h6' :: Sig s opq h6' = PwElement "h6" h6_ :: AFSig_ s opq -h6_ x = (\_ -> PwElement "h6" dats x) +h6_ x _ = PwElement "h6" dats x h6'_ :: Sig_ s opq -h6'_ x = PwElement "h6" dats x +h6'_ = PwElement "h6" dats h6__ :: AFSig__ s opq -h6__ x = (\_ -> PwElement "h6" dats [txt x]) +h6__ x _ = PwElement "h6" dats [txt x] h6'__ :: Sig__ s opq h6'__ x = PwElement "h6" dats [txt x]
src/Web/Framework/Plzwrk/Util.hs view
@@ -29,177 +29,176 @@ , dats' , PwAttribute(..) ) -import Web.Framework.Plzwrk.Browserful +import Web.Framework.Plzwrk.JSEnv -- | Creates a text attribute wrapped in an applicative functor -pT :: String -> (s -> PwAttribute s opq) -pT t = (\_ -> PwTextAttribute t) +pT :: String -> s -> PwAttribute s opq +pT t _ = PwTextAttribute t -- | Creates a callback attribute wrapped in an applicative functor -pF :: (opq -> s -> IO s) -> (s -> PwAttribute s opq) -pF f = (\_ -> PwFunctionAttribute f) +pF :: (opq -> s -> IO s) -> s -> PwAttribute s opq +pF f _ = PwFunctionAttribute f -- |From an event, gets the target's value. eventTargetValue - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the event -> IO (Maybe String) -- ^ the target value, or nothing if it doesn't exist eventTargetValue browser e = do - opq <- (getPropertyAsOpaque browser) e "target" - maybe (pure Nothing) (\y -> (getPropertyAsString browser) y "value") opq + opq <- getPropertyAsOpaque browser e "target" + maybe (pure Nothing) (\y -> getPropertyAsString browser y "value") opq -- |From an event, takes the target and blurs it. eventTargetBlur - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the event -> IO () -- ^ returns nothing eventTargetBlur browser e = do - opq <- (getPropertyAsOpaque browser) e "target" - maybe (pure ()) (\y -> void $ (invokeOn0 browser) y "blur") opq + opq <- getPropertyAsOpaque browser e "target" + maybe (pure ()) (\y -> void $ invokeOn0 browser y "blur") opq -- |Take an event and prevent the default. eventPreventDefault - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the event -> IO () -- ^ returns nothing -eventPreventDefault browser e = do - void $ (invokeOn0 browser) e "preventDefault" +eventPreventDefault browser e = void $ invokeOn0 browser e "preventDefault" ----------- -- | Sets on an element an attribute. See [Element.setAttribute](https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute) elementSetAttribute - :: Browserful jsval -- ^ The browser + :: JSEnv jsval -- ^ The browser -> jsval -- ^ the node -> String -- ^ the attribute name -> String -- ^ the attribute -> IO () -- ^ returns nothing elementSetAttribute b e k v = do - _k <- (jsValFromString b) k - _v <- (jsValFromString b) v - void $ (invokeOn2 b) e "setAttribute" _k _v + _k <- jsValFromString b k + _v <- jsValFromString b v + void $ invokeOn2 b e "setAttribute" _k _v -- | Gets the tag name of an element. See [Element.tagName](https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName) elementTagName - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the element -> IO (Maybe String) -- ^ Returns the tag name elementTagName b v = do - _o <- (getPropertyAsOpaque b) v "tagName" - maybe (pure Nothing) (\x -> (castToString b) x) _o + _o <- getPropertyAsOpaque b v "tagName" + maybe (pure Nothing) (castToString b) _o -- | Takes a target and an event name and adds a listener. See [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) eventTargetAddEventListener - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the element -> String -- ^ the listener name. note that this should be "click" or "input", not "onclick" nor "oninput" -> jsval -- ^ the listener -> IO () -- ^ returns nothing eventTargetAddEventListener b e k v = do - _k <- (jsValFromString b) k - void $ (invokeOn2 b) e "addEventListener" _k v + _k <- jsValFromString b k + void $ invokeOn2 b e "addEventListener" _k v -- | Takes a target and an event name and removes a listener. See [EventTarget.removeEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener) eventTargetRemoveEventListener - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the element -> String -- ^ the listener name. note that this should be "click" or "input", not "onclick" nor "oninput" -> jsval -- ^ the listener -> IO () -- ^ returns nothing eventTargetRemoveEventListener b e k v = do - _k <- (jsValFromString b) k - void $ (invokeOn2 b) e "removeEventListener" _k v + _k <- jsValFromString b k + void $ invokeOn2 b e "removeEventListener" _k v -- | Gets a JavaScript property as a bool, returning @Nothing@ if the object being called is null or undefined or the property cannot be cast to a bool. getPropertyAsBool - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the object containing the property -> String -- ^ the property name -> IO (Maybe Bool) -- ^ the response if the property is a bool, else Nothing getPropertyAsBool b o k = do - _v <- (getPropertyAsOpaque b) o k - maybe (pure Nothing) (\x -> (castToBool b) x) _v + _v <- getPropertyAsOpaque b o k + maybe (pure Nothing) (castToBool b) _v -- | Gets a JavaScript property as a double, returning @Nothing@ if the object being called is null or undefined or the property cannot be cast to a double. getPropertyAsDouble - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the object containing the property -> String -- ^ the property name -> IO (Maybe Double) -- ^ the response if the property is a double, else Nothing getPropertyAsDouble b o k = do - _v <- (getPropertyAsOpaque b) o k - maybe (pure Nothing) (\x -> (castToDouble b) x) _v + _v <- getPropertyAsOpaque b o k + maybe (pure Nothing) (castToDouble b) _v -- | Gets a JavaScript property as an int, returning @Nothing@ if the object being called is null or undefined or the property cannot be cast to an int. getPropertyAsInt - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the object containing the property -> String -- ^ the property name -> IO (Maybe Int) -- ^ the response if the property is an int, else Nothing getPropertyAsInt b o k = do - _v <- (getPropertyAsOpaque b) o k - maybe (pure Nothing) (\x -> (castToInt b) x) _v + _v <- getPropertyAsOpaque b o k + maybe (pure Nothing) (castToInt b) _v -- | Gets a JavaScript property as an string, returning @Nothing@ if the object being called is null or undefined. getPropertyAsString - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the object containing the property -> String -- ^ the property name -> IO (Maybe String) -- ^ the response getPropertyAsString b o k = do - _v <- (getPropertyAsOpaque b) o k - maybe (pure Nothing) (\x -> (castToString b) x) _v + _v <- getPropertyAsOpaque b o k + maybe (pure Nothing) (castToString b) _v -- | Takes an element and clicks it. Useful for testing. See [HTMLElement.click](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click) -htmlElemenetClick :: Browserful jsval -> jsval -> IO () -htmlElemenetClick b e = void $ (invokeOn0 b) e "click" +htmlElemenetClick :: JSEnv jsval -> jsval -> IO () +htmlElemenetClick b e = void $ invokeOn0 b e "click" -- | Logs a string. See [Console.log](https://developer.mozilla.org/en-US/docs/Web/API/Console/log) -consoleLogS :: Browserful jsval -> String -> IO () +consoleLogS :: JSEnv jsval -> String -> IO () consoleLogS b s = do - _s <- (jsValFromString b) s - (consoleLog b) _s + _s <- jsValFromString b s + consoleLog b _s -- | Takes a node and appends a child. See [Node.appendChild](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) nodeAppendChild - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the node -> jsval -- ^ the child to append -> IO () -- ^ returns nothing -nodeAppendChild b e v = void $ (invokeOn1 b) e "appendChild" v +nodeAppendChild b e v = void $ invokeOn1 b e "appendChild" v -- | Get the children of a node. See [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes) nodeChildNodes - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the node -> IO (Maybe [jsval]) nodeChildNodes b v = do - _cn <- (getPropertyAsOpaque b) v "childNodes" - maybe (pure Nothing) (\x -> (castToArray b) x) _cn + _cn <- getPropertyAsOpaque b v "childNodes" + maybe (pure Nothing) (castToArray b) _cn -- | Inserts a node into an element before another node. See [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore) nodeInsertBefore - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the parent element -> jsval -- ^ the new node -> jsval -- ^ the pre-existing node -> IO () -- ^ returns nothing -nodeInsertBefore b e k v = void $ (invokeOn2 b) e "insertBefore" k v +nodeInsertBefore b e k v = void $ invokeOn2 b e "insertBefore" k v -- | Removes a child from a parent node. See [Node.removeChild](https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild) nodeRemoveChild - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the parent element -> jsval -- ^ the child to remove -> IO () -- ^ returns nothing -nodeRemoveChild b e v = void $ (invokeOn1 b) e "removeChild" v +nodeRemoveChild b e v = void $ invokeOn1 b e "removeChild" v -- | Gets the text content of a node. See [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) nodeTextContent - :: Browserful jsval -- ^ the browser + :: JSEnv jsval -- ^ the browser -> jsval -- ^ the node -> IO (Maybe String) -- ^ the text content as a string nodeTextContent b e = do - _tc <- (getPropertyAsOpaque b) e "textContent" - maybe (pure Nothing) (\x -> (castToString b) x) _tc + _tc <- getPropertyAsOpaque b e "textContent" + maybe (pure Nothing) (castToString b) _tc
test/DOMSpec.hs view
@@ -15,19 +15,19 @@ , div'_ ) -nodeChildNodesOrThrow :: Browserful jsval -> jsval -> IO [jsval] +nodeChildNodesOrThrow :: JSEnv jsval -> jsval -> IO [jsval] nodeChildNodesOrThrow b v = do - _v <- (nodeChildNodes b v) + _v <- nodeChildNodes b v maybe (error "Could not find child nodes") pure _v -nodeTextContentOrThrow :: Browserful jsval -> jsval -> IO String +nodeTextContentOrThrow :: JSEnv jsval -> jsval -> IO String nodeTextContentOrThrow b v = do - _v <- (nodeTextContent b v) + _v <- nodeTextContent b v maybe (error "Could not find text content") pure _v -elementTagNameOrThrow :: Browserful jsval -> jsval -> IO String +elementTagNameOrThrow :: JSEnv jsval -> jsval -> IO String elementTagNameOrThrow b v = do - _v <- (elementTagName b v) + _v <- elementTagName b v maybe (error "Could not find tag name") pure _v data MyState = MyState @@ -39,7 +39,7 @@ let domF = (\x y -> div'_ [ p [("style", pT "position:absolute")] - (take y $ repeat (txt (concat [x, show y]))) + (replicate y (txt (x ++ show y))) , button [("id", pT "incr"), ("class", pT "a b ccc"), ("click", pF (\_ s -> pure $ s { _ctr = y + 1 }) @@ -60,51 +60,51 @@ mock <- makeMockBrowserWithContext rf plzwrk' domF state mock parentNode <- documentBody mock - childrenLevel0 <- (nodeChildNodesOrThrow mock) parentNode + childrenLevel0 <- nodeChildNodesOrThrow mock parentNode length childrenLevel0 `shouldBe` 1 - divtag <- (elementTagNameOrThrow mock) (head childrenLevel0) + divtag <- elementTagNameOrThrow mock (head childrenLevel0) divtag `shouldBe` "div" - childrenLevel1 <- (nodeChildNodesOrThrow mock) (head childrenLevel0) + childrenLevel1 <- nodeChildNodesOrThrow mock (head childrenLevel0) length childrenLevel1 `shouldBe` 4 - ptag <- (elementTagNameOrThrow mock) (head childrenLevel1) + ptag <- elementTagNameOrThrow mock (head childrenLevel1) ptag `shouldBe` "p" - childrenLevel2 <- (nodeChildNodesOrThrow mock) (head childrenLevel1) + childrenLevel2 <- nodeChildNodesOrThrow mock (head childrenLevel1) length childrenLevel2 `shouldBe` 1 -- increment 4 times - (documentGetElementById mock) "incr" + documentGetElementById mock "incr" >>= maybe (error "Incr node does not exist") (htmlElemenetClick mock) - (documentGetElementById mock) "incr" + documentGetElementById mock "incr" >>= maybe (error "Incr node does not exist") (htmlElemenetClick mock) - (documentGetElementById mock) "incr" + documentGetElementById mock "incr" >>= maybe (error "Incr node does not exist") (htmlElemenetClick mock) - (documentGetElementById mock) "incr" + documentGetElementById mock "incr" >>= maybe (error "Incr node does not exist") (htmlElemenetClick mock) parentNode' <- documentBody mock - childrenLevel0' <- (nodeChildNodesOrThrow mock) parentNode' + childrenLevel0' <- nodeChildNodesOrThrow mock parentNode' length childrenLevel0' `shouldBe` 1 - divtag' <- (elementTagNameOrThrow mock) (head childrenLevel0') + divtag' <- elementTagNameOrThrow mock (head childrenLevel0') divtag' `shouldBe` "div" - childrenLevel1' <- (nodeChildNodesOrThrow mock) (head childrenLevel0') + childrenLevel1' <- nodeChildNodesOrThrow mock (head childrenLevel0') length childrenLevel1' `shouldBe` 4 - childrenLevel2' <- (nodeChildNodesOrThrow mock) (head childrenLevel1') + childrenLevel2' <- nodeChildNodesOrThrow mock (head childrenLevel1') length childrenLevel2' `shouldBe` 5 content' <- mapM (nodeTextContentOrThrow mock) childrenLevel2' - content' `shouldBe` (take 5 $ repeat "Mike5") - (documentGetElementById mock) "decr" + content' `shouldBe` replicate 5 "Mike5" + documentGetElementById mock "decr" >>= maybe (error "Incr node does not exist") (htmlElemenetClick mock) - (documentGetElementById mock) "decr" + documentGetElementById mock "decr" >>= maybe (error "Incr node does not exist") (htmlElemenetClick mock) parentNode'' <- documentBody mock - childrenLevel0'' <- (nodeChildNodesOrThrow mock) parentNode'' + childrenLevel0'' <- nodeChildNodesOrThrow mock parentNode'' length childrenLevel0'' `shouldBe` 1 - divtag'' <- (elementTagNameOrThrow mock) (head childrenLevel0'') + divtag'' <- elementTagNameOrThrow mock (head childrenLevel0'') divtag'' `shouldBe` "div" - childrenLevel1'' <- (nodeChildNodesOrThrow mock) (head childrenLevel0'') + childrenLevel1'' <- nodeChildNodesOrThrow mock (head childrenLevel0'') length childrenLevel1'' `shouldBe` 4 - childrenLevel2'' <- (nodeChildNodesOrThrow mock) (head childrenLevel1'') + childrenLevel2'' <- nodeChildNodesOrThrow mock (head childrenLevel1'') length childrenLevel2'' `shouldBe` 3 content'' <- mapM (nodeTextContentOrThrow mock) childrenLevel2'' - content'' `shouldBe` (take 3 $ repeat "Mike3") + content'' `shouldBe` replicate 3 "Mike3" toHTML domF state `shouldBe` "<div><p style=\"position:absolute\">Mike1</p><button id=\"incr\" class=\"a b ccc\">Increase counter</button><br/><button id=\"decr\" style=\"position:absolute;margin:10px\">Decrease counter</button></div>"
test/HSXSpec.hs view
@@ -18,7 +18,7 @@ -- we use () for an empty state _elt_tag (dom ()) `shouldBe` "p" - _tn_text (((_elt_children (dom ())) !! 0) ()) `shouldBe` "Hello world!" + _tn_text (head (_elt_children (dom ())) ()) `shouldBe` "Hello world!" it "Parses hsx with an event listener" $ do let dom = [hsx| <h1 id="foo" style="position:absolute"> @@ -42,8 +42,8 @@ </h1> |] _elt_tag (dom 3) `shouldBe` "h1" - _elt_tag (((_elt_children (dom 5)) !! 0) 3) `shouldBe` "a" - _tn_text (((_elt_children (dom 5)) !! 1) 3) `shouldBe` "hello world" + _elt_tag (head (_elt_children (dom 5)) 3) `shouldBe` "a" + _tn_text ((_elt_children (dom 5) !! 1) 3) `shouldBe` "hello world" 1 `shouldBe` 1 it "Parses hsx with a list of elements" $ do let mylink = [hsx|<a click=#c{(\_ x -> return $ x + 41)}#>Hello</a>|] @@ -54,9 +54,9 @@ </h1> |] _elt_tag (dom 3) `shouldBe` "h1" - _elt_tag (((_elt_children (dom 5)) !! 0) 3) `shouldBe` "a" - _elt_tag (((_elt_children (dom 5)) !! 6) 3) `shouldBe` "a" - _tn_text (((_elt_children (dom 5)) !! 10) 3) `shouldBe` "hello world" + _elt_tag (head (_elt_children (dom 5)) 3) `shouldBe` "a" + _elt_tag ((_elt_children (dom 5) !! 6) 3) `shouldBe` "a" + _tn_text ((_elt_children (dom 5) !! 10) 3) `shouldBe` "hello world" it "Parses hsx mixing text and not text" $ do let mylink = [hsx|<a click=#c{(\_ x -> return $ x + 41)}#>Hello</a>|] let dom = [hsx| @@ -65,8 +65,8 @@ </h1> |] _elt_tag (dom 3) `shouldBe` "h1" - _elt_tag (((_elt_children (dom 5)) !! 0) 3) `shouldBe` "div" - _elt_tag ((_elt_children (((_elt_children (dom 5)) !! 0) 3) !! 1) 5) `shouldBe` "span" + _elt_tag (head (_elt_children (dom 5)) 3) `shouldBe` "div" + _elt_tag ((_elt_children (head (_elt_children (dom 5)) 3) !! 1) 5) `shouldBe` "span" it "Parses hsx'" $ do let mylink = [hsx|<a click=#c{(\_ x -> return $ x + 41)}#>Hello</a>|] let dom = (\st -> [hsx'| @@ -75,4 +75,4 @@ </h1> |]) _elt_tag (dom 3) `shouldBe` "h1" - _elt_tag (((_elt_children (dom 5)) !! 0) 3) `shouldBe` "a" + _elt_tag (head (_elt_children (dom 5)) 3) `shouldBe` "a"