{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, FlexibleInstances #-}
module Text.HTML.Form (Form(..), Input(..), OptionGroup(..), Option(..),
FileSelector(..), defaultFileData, ImageData(..), defaultImageData,
TextArea(..), defaultTextArea, parseElement, parseElement',
parseDocument, parseDocument', ensureButtons) where
import Data.Text (Text)
import qualified Data.Text as Txt
import Text.XML.Cursor
import Text.XML (Document, Name(..), Node(..))
import Data.Maybe (fromMaybe, listToMaybe, mapMaybe)
import Data.List (singleton)
import Text.Read (readMaybe)
import Data.Function (on)
import Network.URI (parseURIReference, URI, nullURI)
import Text.Regex.TDFA (Regex, defaultCompOpt, defaultExecOpt)
import Text.Regex.TDFA.Text (compile)
data Form = Form {
Form -> URI
action :: URI,
Form -> Text
enctype :: Text,
Form -> Text
method :: Text,
Form -> Bool
validate :: Bool,
Form -> Text
target :: Text,
Form -> [Text]
acceptCharset :: [Text],
Form -> Bool
autocomplete :: Bool,
Form -> Text
formName :: Text,
Form -> Text
rel :: Text,
Form -> [Input]
inputs :: [Input],
Form -> String
lang :: String
}
data Input = Input {
Input -> Text
label :: Text,
Input -> Node
description :: Node,
Input -> Text
inputType :: Text,
Input -> Text
dirname :: Text,
Input -> Text
inputName :: Text,
Input -> Text
value :: Text,
Input -> Text
inputAutocomplete :: Text,
Input -> Bool
autofocus :: Bool,
Input -> Bool
checked :: Bool,
Input -> Bool
disabled :: Bool,
Input -> Bool
readonly :: Bool,
Input -> Bool
multiple :: Bool,
Input -> Maybe URI
formAction :: Maybe URI,
Input -> Maybe Text
formEnctype :: Maybe Text,
Input -> Maybe Text
formMethod :: Maybe Text,
Input -> Bool
formValidate :: Bool,
Input -> Maybe Text
formTarget :: Maybe Text,
Input -> Text
inputMode :: Text,
Input -> [OptionGroup]
list :: [OptionGroup],
Input -> (Maybe Text, Maybe Text)
range :: (Maybe Text, Maybe Text),
Input -> Maybe Text
step :: Maybe Text,
Input -> (Maybe Int, Maybe Int)
lengthRange :: (Maybe Int, Maybe Int),
Input -> Maybe Regex
pattern :: Maybe Regex,
Input -> Bool
required :: Bool,
Input -> Text
placeholder :: Text,
Input -> Text
title :: Text,
Input -> Maybe Int
size :: Maybe Int,
Input -> FileSelector
fileData :: FileSelector,
Input -> ImageData
imageData :: ImageData,
Input -> TextArea
textArea :: TextArea
}
data OptionGroup = OptGroup {
OptionGroup -> Text
optsLabel :: Text,
OptionGroup -> Bool
optsDisabled :: Bool,
OptionGroup -> [Option]
subopts :: [Option]
}
data Option = Option {
Option -> Text
optLabel :: Text,
Option -> Text
optValue :: Text,
Option -> Bool
optSelected :: Bool,
Option -> Bool
optDisabled :: Bool
}
data FileSelector = FileSelector {
FileSelector -> [Text]
fileAccept :: [Text],
FileSelector -> Text
fileCapture :: Text
}
defaultFileData :: FileSelector
defaultFileData :: FileSelector
defaultFileData = [Text] -> Text -> FileSelector
FileSelector [] Text
""
data ImageData = ImageData {
ImageData -> Maybe Text
imgAlt :: Maybe Text,
ImageData -> (Maybe Int, Maybe Int)
imgSize :: (Maybe Int, Maybe Int),
ImageData -> Maybe URI
imgSrc :: Maybe URI
}
defaultImageData :: ImageData
defaultImageData :: ImageData
defaultImageData = Maybe Text -> (Maybe Int, Maybe Int) -> Maybe URI -> ImageData
ImageData Maybe Text
forall a. Maybe a
Nothing (Maybe Int
forall a. Maybe a
Nothing, Maybe Int
forall a. Maybe a
Nothing) Maybe URI
forall a. Maybe a
Nothing
data TextArea = TextArea {
TextArea -> Bool
autocorrect :: Bool,
TextArea -> Maybe Int
rows :: Maybe Int,
TextArea -> Maybe Bool
spellcheck :: Maybe Bool,
TextArea -> Maybe Bool
textwrap :: Maybe Bool
}
defaultTextArea :: TextArea
defaultTextArea :: TextArea
defaultTextArea = Bool -> Maybe Int -> Maybe Bool -> Maybe Bool -> TextArea
TextArea Bool
True Maybe Int
forall a. Maybe a
Nothing Maybe Bool
forall a. Maybe a
Nothing Maybe Bool
forall a. Maybe a
Nothing
attr :: Text -> Cursor -> Text -> Text
attr :: Text -> Cursor -> Text -> Text
attr Text
n Cursor
el Text
def | [Text
ret] <- Text
n Text -> Cursor -> [Text]
`laxAttribute` Cursor
el = Text
ret
| Bool
otherwise = Text
def
attr' :: Text -> Cursor -> (Text -> a) -> Text -> a
attr' :: forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
n Cursor
el Text -> a
cb Text
def = Text -> a
cb (Text -> a) -> Text -> a
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
n Cursor
el Text
def
attr'' :: Text -> Cursor -> (String -> a) -> Text -> a
attr'' :: forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
n Cursor
el String -> a
cb Text
def = Text -> Cursor -> (Text -> a) -> Text -> a
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
n Cursor
el (String -> a
cb (String -> a) -> (Text -> String) -> Text -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Txt.unpack) Text
def
hasAttr :: Name -> Cursor -> Bool
hasAttr :: Name -> Cursor -> Bool
hasAttr Name
n = Bool -> Bool
not (Bool -> Bool) -> (Cursor -> Bool) -> Cursor -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Cursor] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Cursor] -> Bool) -> (Cursor -> [Cursor]) -> Cursor -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Cursor -> [Cursor]
hasAttribute Name
n
mAttr :: Text -> Cursor -> Maybe Text
mAttr :: Text -> Cursor -> Maybe Text
mAttr Text
n = [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text)
-> (Cursor -> [Text]) -> Cursor -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Cursor -> [Text]
laxAttribute Text
n
parseElement :: Cursor -> Maybe Form
parseElement :: Cursor -> Maybe Form
parseElement = Text -> Cursor -> Maybe Form
parseElement' Text
"en"
parseElement' :: Text -> Cursor -> Maybe Form
parseElement' :: Text -> Cursor -> Maybe Form
parseElement' Text
language Cursor
el | Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"form" Cursor
el = Form -> Maybe Form
forall a. a -> Maybe a
Just Form {
action :: URI
action = Text -> Cursor -> (String -> URI) -> Text -> URI
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"action" Cursor
el (URI -> Maybe URI -> URI
forall a. a -> Maybe a -> a
fromMaybe URI
nullURI (Maybe URI -> URI) -> (String -> Maybe URI) -> String -> URI
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe URI
parseURIReference) Text
".",
enctype :: Text
enctype = Text -> Cursor -> Text -> Text
attr Text
"enctype" Cursor
el Text
"",
method :: Text
method = Text -> Cursor -> Text -> Text
attr Text
"method" Cursor
el Text
"GET",
validate :: Bool
validate = [Cursor] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Cursor] -> Bool) -> [Cursor] -> Bool
forall a b. (a -> b) -> a -> b
$ Name -> Cursor -> [Cursor]
hasAttribute Name
"novalidate" Cursor
el,
target :: Text
target = Text -> Cursor -> Text -> Text
attr Text
"target" Cursor
el Text
"_self",
acceptCharset :: [Text]
acceptCharset = Text -> Cursor -> (Text -> [Text]) -> Text -> [Text]
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"accept-charset" Cursor
el Text -> [Text]
Txt.words Text
"utf-8",
autocomplete :: Bool
autocomplete = Name -> Cursor -> Bool
hasAttr Name
"autocomplete" Cursor
el,
formName :: Text
formName = Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"",
rel :: Text
rel = Text -> Cursor -> Text -> Text
attr Text
"rel" Cursor
el Text
"",
inputs :: [Input]
inputs = (Cursor -> Maybe Input) -> [Cursor] -> [Input]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Cursor -> Maybe Input
parseInput ([Cursor] -> [Input]) -> [Cursor] -> [Input]
forall a b. (a -> b) -> a -> b
$ Cursor -> [Cursor]
queryInputs Cursor
el,
lang :: String
lang = Text -> String
Txt.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
language (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Maybe Text
forall a. [a] -> Maybe a
listToMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$
(Cursor -> Maybe Text) -> [Cursor] -> [Text]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Text -> Cursor -> Maybe Text
mAttr Text
"lang") ([Cursor] -> [Text]) -> [Cursor] -> [Text]
forall a b. (a -> b) -> a -> b
$ (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall node. Axis node -> Axis node
orSelf Cursor -> [Cursor]
forall node. Axis node
ancestor Cursor
el
}
| Bool
otherwise = Maybe Form
forall a. Maybe a
Nothing
root :: Axis
root :: Cursor -> [Cursor]
root = Cursor -> [Cursor]
forall a. a -> [a]
singleton (Cursor -> [Cursor]) -> (Cursor -> Cursor) -> Cursor -> [Cursor]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Cursor] -> Cursor
forall a. HasCallStack => [a] -> a
last ([Cursor] -> Cursor) -> (Cursor -> [Cursor]) -> Cursor -> Cursor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall node. Axis node -> Axis node
orSelf Cursor -> [Cursor]
forall node. Axis node
ancestor
laxElements :: [Text] -> Axis
laxElements :: [Text] -> Cursor -> [Cursor]
laxElements [Text]
ns = (Name -> Bool) -> Cursor -> [Cursor]
forall b. Boolean b => (Name -> b) -> Cursor -> [Cursor]
checkName (\Name
x -> [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or [
(Text -> Text -> Bool) -> (Text -> Text) -> Text -> Text -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
(==) Text -> Text
Txt.toCaseFold Text
n (Text -> Bool) -> Text -> Bool
forall a b. (a -> b) -> a -> b
$ Name -> Text
nameLocalName Name
x | Text
n <- [Text]
ns])
queryInputs :: Cursor -> [Cursor]
queryInputs :: Cursor -> [Cursor]
queryInputs Cursor
form = (Cursor -> [Cursor]
allInputs (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Cursor -> [Cursor]
inForm) Cursor
form
where
allInputs :: Cursor -> [Cursor]
allInputs = Cursor -> [Cursor]
root (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [Text] -> Cursor -> [Cursor]
laxElements [
Text
"input", Text
"textarea", Text
"button", Text
"select"]
inForm :: Cursor -> [Cursor]
inForm = (Cursor -> Bool) -> Cursor -> [Cursor]
forall b. Boolean b => (Cursor -> b) -> Cursor -> [Cursor]
check (\Cursor
x ->
Text -> Cursor -> [Text]
laxAttribute Text
"form" Cursor
x [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Cursor -> [Text]
laxAttribute Text
"id" Cursor
form Bool -> Bool -> Bool
||
Cursor -> Bool
nestedInForm Cursor
x)
nestedInForm :: Cursor -> Bool
nestedInForm Cursor
x = [Cursor] -> Maybe Cursor
forall a. [a] -> Maybe a
listToMaybe ((Cursor -> [Cursor]
forall node. Axis node
ancestor (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> Cursor -> [Cursor]
laxElement Text
"form") Cursor
x) Maybe Cursor -> Maybe Cursor -> Bool
forall a. Eq a => a -> a -> Bool
== Cursor -> Maybe Cursor
forall a. a -> Maybe a
Just Cursor
form
parseInput :: Cursor -> Maybe Input
parseInput :: Cursor -> Maybe Input
parseInput Cursor
el | Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"input" Cursor
el = Input -> Maybe Input
forall a. a -> Maybe a
Just Input {
label :: Text
label = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe
(Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"value" Cursor
el (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"alt" Cursor
el (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$
Text -> Cursor -> Text -> Text
attr Text
"type" Cursor
el Text
"text") (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ (Cursor -> Text) -> Maybe Cursor -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Text
text Maybe Cursor
label',
description :: Node
description = Node -> Maybe Node -> Node
forall a. a -> Maybe a -> a
fromMaybe (Text -> Node
mkEl (Text -> Node) -> Text -> Node
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"") (Maybe Node -> Node) -> Maybe Node -> Node
forall a b. (a -> b) -> a -> b
$ (Cursor -> Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Node
forall node. Cursor node -> node
node (Maybe Cursor -> Maybe Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> a -> b
$
Text -> Maybe Cursor
elByID (Text -> Cursor -> Text -> Text
attr Text
"aria-describedby" Cursor
el Text
"") Maybe Cursor -> Maybe Cursor -> Maybe Cursor
forall a. Maybe a -> Maybe a -> Maybe a
`orElse` Maybe Cursor
label',
inputType :: Text
inputType = Text -> Cursor -> Text -> Text
attr Text
"type" Cursor
el Text
"text",
value :: Text
value = Text -> Cursor -> Text -> Text
attr Text
"value" Cursor
el Text
"",
inputAutocomplete :: Text
inputAutocomplete = Text -> Cursor -> Text -> Text
attr Text
"autocomplete" Cursor
el Text
"on",
autofocus :: Bool
autofocus = Name -> Cursor -> Bool
hasAttr Name
"autofocus" Cursor
el,
checked :: Bool
checked = Name -> Cursor -> Bool
hasAttr Name
"checked" Cursor
el,
disabled :: Bool
disabled = Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
el Bool -> Bool -> Bool
|| Text -> Cursor -> Text -> Text
attr Text
"type" Cursor
el Text
"" Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"hidden",
readonly :: Bool
readonly = Name -> Cursor -> Bool
hasAttr Name
"readonly" Cursor
el Bool -> Bool -> Bool
|| Text -> Cursor -> Text -> Text
attr Text
"type" Cursor
el Text
"" Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"hidden",
multiple :: Bool
multiple = Name -> Cursor -> Bool
hasAttr Name
"multiple" Cursor
el,
dirname :: Text
dirname = Text -> Cursor -> Text -> Text
attr Text
"dirname" Cursor
el Text
"",
inputName :: Text
inputName = Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"",
formAction :: Maybe URI
formAction = if Name -> Cursor -> Bool
hasAttr Name
"formaction" Cursor
el
then Text -> Cursor -> (Text -> Maybe URI) -> Text -> Maybe URI
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"formaction" Cursor
el (String -> Maybe URI
parseURIReference (String -> Maybe URI) -> (Text -> String) -> Text -> Maybe URI
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Txt.unpack) Text
""
else Maybe URI
forall a. Maybe a
Nothing,
formEnctype :: Maybe Text
formEnctype = Text -> Cursor -> Maybe Text
mAttr Text
"formenctype" Cursor
el,
formMethod :: Maybe Text
formMethod = Text -> Cursor -> Maybe Text
mAttr Text
"formmethod" Cursor
el,
formValidate :: Bool
formValidate = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Name -> Cursor -> Bool
hasAttr Name
"formnovalidate" Cursor
el,
formTarget :: Maybe Text
formTarget = Text -> Cursor -> Maybe Text
mAttr Text
"formtarget" Cursor
el,
inputMode :: Text
inputMode = Text -> Cursor -> Text -> Text
attr Text
"inputmode" Cursor
el Text
"text",
list :: [OptionGroup]
list = [OptionGroup] -> Maybe [OptionGroup] -> [OptionGroup]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [OptionGroup] -> [OptionGroup])
-> Maybe [OptionGroup] -> [OptionGroup]
forall a b. (a -> b) -> a -> b
$ (Cursor -> [OptionGroup]) -> Maybe Cursor -> Maybe [OptionGroup]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> [OptionGroup]
parseOptions (Text -> Maybe Cursor
elByID (Text -> Maybe Cursor) -> Maybe Text -> Maybe Cursor
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> Cursor -> Maybe Text
mAttr Text
"list" Cursor
el),
range :: (Maybe Text, Maybe Text)
range = (Text -> Cursor -> Maybe Text
mAttr Text
"min" Cursor
el, Text -> Cursor -> Maybe Text
mAttr Text
"max" Cursor
el),
step :: Maybe Text
step = Text -> Cursor -> Maybe Text
mAttr Text
"step" Cursor
el,
lengthRange :: (Maybe Int, Maybe Int)
lengthRange = (Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"minlength" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"maxLength" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
""),
pattern :: Maybe Regex
pattern = Text -> Cursor -> (Text -> Maybe Regex) -> Text -> Maybe Regex
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"pattern" Cursor
el
(Either String Regex -> Maybe Regex
forall a b. Either a b -> Maybe b
rightToMaybe (Either String Regex -> Maybe Regex)
-> (Text -> Either String Regex) -> Text -> Maybe Regex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CompOption -> ExecOption -> Text -> Either String Regex
compile CompOption
forall regex compOpt execOpt.
RegexOptions regex compOpt execOpt =>
compOpt
defaultCompOpt ExecOption
forall regex compOpt execOpt.
RegexOptions regex compOpt execOpt =>
execOpt
defaultExecOpt) Text
".*",
required :: Bool
required = Name -> Cursor -> Bool
hasAttr Name
"required" Cursor
el,
placeholder :: Text
placeholder = Text -> Cursor -> Text -> Text
attr Text
"placeholder" Cursor
el Text
"",
title :: Text
title = Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"",
size :: Maybe Int
size = Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"size" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
fileData :: FileSelector
fileData = FileSelector {
fileAccept :: [Text]
fileAccept = Text -> Cursor -> (Text -> [Text]) -> Text -> [Text]
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"accept" Cursor
el Text -> [Text]
Txt.words Text
"*",
fileCapture :: Text
fileCapture = Text -> Cursor -> Text -> Text
attr Text
"capture" Cursor
el Text
""
},
imageData :: ImageData
imageData = ImageData {
imgAlt :: Maybe Text
imgAlt = Text -> Cursor -> Maybe Text
mAttr Text
"alt" Cursor
el,
imgSize :: (Maybe Int, Maybe Int)
imgSize = (Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"width" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"height" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
""),
imgSrc :: Maybe URI
imgSrc = Text -> Cursor -> (String -> Maybe URI) -> Text -> Maybe URI
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"src" Cursor
el (String -> Maybe URI
parseURIReference) Text
""
},
textArea :: TextArea
textArea = TextArea
defaultTextArea
}
| Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"textarea" Cursor
el = Input -> Maybe Input
forall a. a -> Maybe a
Just Input {
inputType :: Text
inputType = Text
"<textarea>",
label :: Text
label = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"") (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ (Cursor -> Text) -> Maybe Cursor -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Text
text Maybe Cursor
label',
description :: Node
description = Node -> Maybe Node -> Node
forall a. a -> Maybe a -> a
fromMaybe (Text -> Node
mkEl (Text -> Node) -> Text -> Node
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"") (Maybe Node -> Node) -> Maybe Node -> Node
forall a b. (a -> b) -> a -> b
$ (Cursor -> Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Node
forall node. Cursor node -> node
node (Maybe Cursor -> Maybe Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> a -> b
$
Text -> Maybe Cursor
elByID (Text -> Cursor -> Text -> Text
attr Text
"aria-describedby" Cursor
el Text
"") Maybe Cursor -> Maybe Cursor -> Maybe Cursor
forall a. Maybe a -> Maybe a -> Maybe a
`orElse` Maybe Cursor
label',
value :: Text
value = Cursor -> Text
text Cursor
el,
inputAutocomplete :: Text
inputAutocomplete = Text -> Cursor -> Text -> Text
attr Text
"autocomplete" Cursor
el Text
"on",
autofocus :: Bool
autofocus = Name -> Cursor -> Bool
hasAttr Name
"autofocus" Cursor
el,
size :: Maybe Int
size = Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"cols" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
dirname :: Text
dirname = Text -> Cursor -> Text -> Text
attr Text
"dirname" Cursor
el Text
"",
disabled :: Bool
disabled = Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
el,
lengthRange :: (Maybe Int, Maybe Int)
lengthRange = (Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"minLength" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"maxLength" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
""),
inputName :: Text
inputName = Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"",
placeholder :: Text
placeholder = Text -> Cursor -> Text -> Text
attr Text
"placeholder" Cursor
el Text
"",
readonly :: Bool
readonly = Name -> Cursor -> Bool
hasAttr Name
"readonly" Cursor
el,
required :: Bool
required = Name -> Cursor -> Bool
hasAttr Name
"required" Cursor
el,
title :: Text
title = Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"",
inputMode :: Text
inputMode = Text -> Cursor -> Text -> Text
attr Text
"inputMode" Cursor
el Text
"text",
textArea :: TextArea
textArea = TextArea {
autocorrect :: Bool
autocorrect = Text -> Cursor -> Text -> Text
attr Text
"autocorrect" Cursor
el Text
"on" Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"off",
rows :: Maybe Int
rows = Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"rows" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
spellcheck :: Maybe Bool
spellcheck = Text -> Cursor -> (Text -> Maybe Bool) -> Text -> Maybe Bool
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"spellcheck" Cursor
el (\Text
x -> case Text
x of
Text
"true" -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
Text
"false" -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
Text
"default" -> Maybe Bool
forall a. Maybe a
Nothing
Text
_ -> Maybe Bool
forall a. Maybe a
Nothing) Text
"default",
textwrap :: Maybe Bool
textwrap = Text -> Cursor -> (Text -> Maybe Bool) -> Text -> Maybe Bool
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"wrap" Cursor
el (\Text
x -> case Text
x of
Text
"hard" -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
Text
"soft" -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
Text
"off" -> Maybe Bool
forall a. Maybe a
Nothing
Text
_ -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False) Text
"soft"
},
checked :: Bool
checked = Bool
False,
multiple :: Bool
multiple = Bool
True,
formAction :: Maybe URI
formAction = Maybe URI
forall a. Maybe a
Nothing,
formEnctype :: Maybe Text
formEnctype = Maybe Text
forall a. Maybe a
Nothing,
formMethod :: Maybe Text
formMethod = Maybe Text
forall a. Maybe a
Nothing,
formValidate :: Bool
formValidate = Bool
False,
formTarget :: Maybe Text
formTarget = Maybe Text
forall a. Maybe a
Nothing,
list :: [OptionGroup]
list = [],
range :: (Maybe Text, Maybe Text)
range = (Maybe Text
forall a. Maybe a
Nothing, Maybe Text
forall a. Maybe a
Nothing),
step :: Maybe Text
step = Maybe Text
forall a. Maybe a
Nothing,
pattern :: Maybe Regex
pattern = Maybe Regex
forall a. Maybe a
Nothing,
fileData :: FileSelector
fileData = FileSelector
defaultFileData,
imageData :: ImageData
imageData = ImageData
defaultImageData
}
| Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"button" Cursor
el = Input -> Maybe Input
forall a. a -> Maybe a
Just Input {
label :: Text
label = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (Cursor -> Text
text Cursor
el) (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ (Cursor -> Text) -> Maybe Cursor -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Text
text Maybe Cursor
label',
description :: Node
description = Node -> Maybe Node -> Node
forall a. a -> Maybe a -> a
fromMaybe (Cursor -> Node
forall node. Cursor node -> node
node Cursor
el) (Maybe Node -> Node) -> Maybe Node -> Node
forall a b. (a -> b) -> a -> b
$ (Cursor -> Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Node
forall node. Cursor node -> node
node (Maybe Cursor -> Maybe Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> a -> b
$
Text -> Maybe Cursor
elByID (Text -> Maybe Cursor) -> Text -> Maybe Cursor
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"aria-describedby" Cursor
el Text
"",
autofocus :: Bool
autofocus = Name -> Cursor -> Bool
hasAttr Name
"autofocus" Cursor
el,
disabled :: Bool
disabled = Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
el,
formAction :: Maybe URI
formAction = if Name -> Cursor -> Bool
hasAttr Name
"formaction" Cursor
el
then Text -> Cursor -> (Text -> Maybe URI) -> Text -> Maybe URI
forall a. Text -> Cursor -> (Text -> a) -> Text -> a
attr' Text
"formaction" Cursor
el (String -> Maybe URI
parseURIReference (String -> Maybe URI) -> (Text -> String) -> Text -> Maybe URI
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Txt.unpack) Text
""
else Maybe URI
forall a. Maybe a
Nothing,
formEnctype :: Maybe Text
formEnctype = Text -> Cursor -> Maybe Text
mAttr Text
"formenctype" Cursor
el,
formMethod :: Maybe Text
formMethod = Text -> Cursor -> Maybe Text
mAttr Text
"formmethod" Cursor
el,
formValidate :: Bool
formValidate = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Name -> Cursor -> Bool
hasAttr Name
"formnovalidate" Cursor
el,
formTarget :: Maybe Text
formTarget = Text -> Cursor -> Maybe Text
mAttr Text
"formtarget" Cursor
el,
inputName :: Text
inputName = Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"",
inputType :: Text
inputType = Text -> Cursor -> Text -> Text
attr Text
"type" Cursor
el Text
"submit",
value :: Text
value = Text -> Cursor -> Text -> Text
attr Text
"value" Cursor
el Text
"",
title :: Text
title = Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"",
placeholder :: Text
placeholder = [Text] -> Text
Txt.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Text]) -> Cursor -> [Text]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Cursor -> [Text]
content) Cursor
el,
dirname :: Text
dirname = Text
"",
inputAutocomplete :: Text
inputAutocomplete = Text
"",
checked :: Bool
checked = Bool
False,
readonly :: Bool
readonly = Bool
False,
multiple :: Bool
multiple = Bool
False,
inputMode :: Text
inputMode = Text
"",
list :: [OptionGroup]
list = [],
range :: (Maybe Text, Maybe Text)
range = (Maybe Text
forall a. Maybe a
Nothing, Maybe Text
forall a. Maybe a
Nothing),
step :: Maybe Text
step = Maybe Text
forall a. Maybe a
Nothing,
lengthRange :: (Maybe Int, Maybe Int)
lengthRange = (Maybe Int
forall a. Maybe a
Nothing, Maybe Int
forall a. Maybe a
Nothing),
pattern :: Maybe Regex
pattern = Maybe Regex
forall a. Maybe a
Nothing,
required :: Bool
required = Bool
False,
size :: Maybe Int
size = Maybe Int
forall a. Maybe a
Nothing,
fileData :: FileSelector
fileData = FileSelector
defaultFileData,
imageData :: ImageData
imageData = ImageData
defaultImageData,
textArea :: TextArea
textArea = TextArea
defaultTextArea
}
| Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"select" Cursor
el = Input -> Maybe Input
forall a. a -> Maybe a
Just Input {
inputType :: Text
inputType = Text
"<select>",
label :: Text
label = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"") (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ ([Text] -> Text) -> Maybe [Text] -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Text] -> Text
Txt.concat (Maybe [Text] -> Maybe Text) -> Maybe [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$
(Cursor -> [Text]) -> Maybe Cursor -> Maybe [Text]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> [Text]
filterSelect Maybe Cursor
label',
description :: Node
description = Node -> Maybe Node -> Node
forall a. a -> Maybe a -> a
fromMaybe (Text -> Node
mkEl (Text -> Node) -> Text -> Node
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"") (Maybe Node -> Node) -> Maybe Node -> Node
forall a b. (a -> b) -> a -> b
$ (Cursor -> Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Cursor -> Node
forall node. Cursor node -> node
node (Maybe Cursor -> Maybe Node) -> Maybe Cursor -> Maybe Node
forall a b. (a -> b) -> a -> b
$
Text -> Maybe Cursor
elByID (Text -> Maybe Cursor) -> Text -> Maybe Cursor
forall a b. (a -> b) -> a -> b
$ Text -> Cursor -> Text -> Text
attr Text
"aria-describedby" Cursor
el Text
"",
inputAutocomplete :: Text
inputAutocomplete = Text -> Cursor -> Text -> Text
attr Text
"autocomplete" Cursor
el Text
"on",
autofocus :: Bool
autofocus = Name -> Cursor -> Bool
hasAttr Name
"autofocus" Cursor
el,
disabled :: Bool
disabled = Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
el,
multiple :: Bool
multiple = Name -> Cursor -> Bool
hasAttr Name
"multiple" Cursor
el,
inputName :: Text
inputName = Text -> Cursor -> Text -> Text
attr Text
"name" Cursor
el Text
"",
required :: Bool
required = Name -> Cursor -> Bool
hasAttr Name
"required" Cursor
el,
size :: Maybe Int
size = Text -> Cursor -> (String -> Maybe Int) -> Text -> Maybe Int
forall a. Text -> Cursor -> (String -> a) -> Text -> a
attr'' Text
"size" Cursor
el String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe Text
"",
list :: [OptionGroup]
list = Cursor -> [OptionGroup]
parseOptions Cursor
el,
title :: Text
title = Text -> Cursor -> Text -> Text
attr Text
"title" Cursor
el Text
"",
dirname :: Text
dirname = Text
"",
value :: Text
value = Text
"",
checked :: Bool
checked = Bool
False,
readonly :: Bool
readonly = Bool
False,
formAction :: Maybe URI
formAction = Maybe URI
forall a. Maybe a
Nothing,
formEnctype :: Maybe Text
formEnctype = Maybe Text
forall a. Maybe a
Nothing,
formMethod :: Maybe Text
formMethod = Maybe Text
forall a. Maybe a
Nothing,
formValidate :: Bool
formValidate = Bool
False,
formTarget :: Maybe Text
formTarget = Maybe Text
forall a. Maybe a
Nothing,
inputMode :: Text
inputMode = Text
"",
range :: (Maybe Text, Maybe Text)
range = (Maybe Text
forall a. Maybe a
Nothing, Maybe Text
forall a. Maybe a
Nothing),
step :: Maybe Text
step = Maybe Text
forall a. Maybe a
Nothing,
lengthRange :: (Maybe Int, Maybe Int)
lengthRange = (Maybe Int
forall a. Maybe a
Nothing, Maybe Int
forall a. Maybe a
Nothing),
pattern :: Maybe Regex
pattern = Maybe Regex
forall a. Maybe a
Nothing,
placeholder :: Text
placeholder = Text
"",
fileData :: FileSelector
fileData = FileSelector
defaultFileData,
imageData :: ImageData
imageData = ImageData
defaultImageData,
textArea :: TextArea
textArea = TextArea
defaultTextArea
}
| Bool
otherwise = Maybe Input
forall a. Maybe a
Nothing
where
elByAttr :: Name -> Text -> Maybe Cursor
elByAttr Name
k Text
v = [Cursor] -> Maybe Cursor
forall a. [a] -> Maybe a
listToMaybe ([Cursor] -> Maybe Cursor) -> [Cursor] -> Maybe Cursor
forall a b. (a -> b) -> a -> b
$ (Cursor -> [Cursor]
root (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Name -> Text -> Cursor -> [Cursor]
attributeIs Name
k Text
v) Cursor
el
elByID :: Text -> Maybe Cursor
elByID = Name -> Text -> Maybe Cursor
elByAttr Name
"id"
label' :: Maybe Cursor
label' = Name -> Text -> Maybe Cursor
elByAttr Name
"for" (Text -> Cursor -> Text -> Text
attr Text
"id" Cursor
el Text
"") Maybe Cursor -> Maybe Cursor -> Maybe Cursor
forall a. Maybe a -> Maybe a -> Maybe a
`orElse`
[Cursor] -> Maybe Cursor
forall a. [a] -> Maybe a
listToMaybe ([Cursor] -> Maybe Cursor) -> [Cursor] -> Maybe Cursor
forall a b. (a -> b) -> a -> b
$ (Cursor -> [Cursor]
forall node. Axis node
ancestor (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> Cursor -> [Cursor]
laxElement Text
"label") Cursor
el
filterSelect :: Cursor -> [Text]
filterSelect = Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Text]) -> Cursor -> [Text]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=>
(Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall b. Boolean b => (Cursor -> b) -> Cursor -> [Cursor]
checkNot ((Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall node. Axis node -> Axis node
orSelf Cursor -> [Cursor]
forall node. Axis node
ancestor (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> Cursor -> [Cursor]
laxElement Text
"select") (Cursor -> [Cursor]) -> (Cursor -> [Text]) -> Cursor -> [Text]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=>
Cursor -> [Text]
content
parseOptions :: Cursor -> [OptionGroup]
parseOptions :: Cursor -> [OptionGroup]
parseOptions Cursor
el = [Cursor -> OptionGroup
parseGroup Cursor
opt
| Cursor
opt <- (Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [Text] -> Cursor -> [Cursor]
laxElements [Text
"option", Text
"optgroup"] (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=>
(Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall b. Boolean b => (Cursor -> b) -> Cursor -> [Cursor]
checkNot (Cursor -> [Cursor]
forall node. Axis node
parent (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> Cursor -> [Cursor]
laxElement Text
"optgroup")) Cursor
el]
where
parseGroup :: Cursor -> OptionGroup
parseGroup Cursor
opt
| Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"option" Cursor
opt =
Text -> Bool -> [Option] -> OptionGroup
OptGroup Text
"" Bool
False [Cursor -> Bool -> Option
parseOption Cursor
opt Bool
False]
| Cursor
_:[Cursor]
_ <- Text -> Cursor -> [Cursor]
laxElement Text
"optgroup" Cursor
opt = OptGroup {
optsLabel :: Text
optsLabel = Text -> Cursor -> Text -> Text
attr Text
"label" Cursor
opt Text
"",
optsDisabled :: Bool
optsDisabled = Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
opt,
subopts :: [Option]
subopts = [Cursor -> Bool -> Option
parseOption Cursor
o (Bool -> Option) -> Bool -> Option
forall a b. (a -> b) -> a -> b
$ Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
opt | Cursor
o <- Cursor -> [Cursor]
forall node. Axis node
child Cursor
opt]
}
| Bool
otherwise = Text -> Bool -> [Option] -> OptionGroup
OptGroup Text
"" Bool
True []
parseOption :: Cursor -> Bool -> Option
parseOption Cursor
opt Bool
disabledOverride = Option {
optLabel :: Text
optLabel = Text -> Cursor -> Text -> Text
attr Text
"label" Cursor
opt (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Cursor -> Text
text Cursor
opt,
optValue :: Text
optValue = Text -> Cursor -> Text -> Text
attr Text
"value" Cursor
opt (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Cursor -> Text
text Cursor
opt,
optSelected :: Bool
optSelected = Name -> Cursor -> Bool
hasAttr Name
"selected" Cursor
opt,
optDisabled :: Bool
optDisabled = Name -> Cursor -> Bool
hasAttr Name
"disabled" Cursor
opt Bool -> Bool -> Bool
|| Bool
disabledOverride
}
parseDocument :: Document -> Text -> Maybe Form
parseDocument :: Document -> Text -> Maybe Form
parseDocument = Text -> Document -> Text -> Maybe Form
parseDocument' Text
"en"
parseDocument' :: Text -> Document -> Text -> Maybe Form
parseDocument' :: Text -> Document -> Text -> Maybe Form
parseDocument' Text
language Document
doc Text
n
| Just Int
n' <- String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe Int) -> String -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Text -> String
Txt.unpack Text
n, Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Cursor] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Cursor -> [Cursor]
forms Cursor
doc') =
Text -> Cursor -> Maybe Form
parseElement' Text
language (Cursor -> [Cursor]
forms Cursor
doc' [Cursor] -> Int -> Cursor
forall a. HasCallStack => [a] -> Int -> a
!! Int
n')
| Cursor
el:[Cursor]
_ <- (Cursor -> [Cursor]
forms (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Name -> Text -> Cursor -> [Cursor]
attributeIs Name
"name" Text
n) Cursor
doc' = Text -> Cursor -> Maybe Form
parseElement' Text
language Cursor
el
| Bool
otherwise = Maybe Form
forall a. Maybe a
Nothing
where
forms :: Cursor -> [Cursor]
forms = (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall node. Axis node -> Axis node
orSelf Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Cursor]) -> Cursor -> [Cursor]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> Cursor -> [Cursor]
laxElement Text
"form"
doc' :: Cursor
doc' = Document -> Cursor
fromDocument Document
doc
checkNot :: Boolean b => (Cursor -> b) -> Axis
checkNot :: forall b. Boolean b => (Cursor -> b) -> Cursor -> [Cursor]
checkNot Cursor -> b
test = (Cursor -> Bool) -> Cursor -> [Cursor]
forall b. Boolean b => (Cursor -> b) -> Cursor -> [Cursor]
check (Bool -> Bool
not (Bool -> Bool) -> (Cursor -> Bool) -> Cursor -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Bool
forall a. Boolean a => a -> Bool
bool (b -> Bool) -> (Cursor -> b) -> Cursor -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cursor -> b
test)
rightToMaybe :: Either a b -> Maybe b
rightToMaybe :: forall a b. Either a b -> Maybe b
rightToMaybe (Left a
_) = Maybe b
forall a. Maybe a
Nothing
rightToMaybe (Right b
x) = b -> Maybe b
forall a. a -> Maybe a
Just b
x
instance Eq Cursor where
Cursor
a == :: Cursor -> Cursor -> Bool
== Cursor
b = Cursor -> Node
forall node. Cursor node -> node
node Cursor
a Node -> Node -> Bool
forall a. Eq a => a -> a -> Bool
== Cursor -> Node
forall node. Cursor node -> node
node Cursor
b
orElse :: Maybe a -> Maybe a -> Maybe a
orElse :: forall a. Maybe a -> Maybe a -> Maybe a
orElse ret :: Maybe a
ret@(Just a
_) Maybe a
_ = Maybe a
ret
orElse Maybe a
_ Maybe a
ret = Maybe a
ret
infixr 0 `orElse`
text :: Cursor -> Text
text :: Cursor -> Text
text = [Text] -> Text
Txt.concat ([Text] -> Text) -> (Cursor -> [Text]) -> Cursor -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Cursor -> [Cursor]
forall node. Axis node
descendant (Cursor -> [Cursor]) -> (Cursor -> [Text]) -> Cursor -> [Text]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Cursor -> [Text]
content)
mkEl :: Text -> Node
mkEl :: Text -> Node
mkEl = Text -> Node
NodeContent
ensureButtons :: Form -> Form
ensureButtons :: Form -> Form
ensureButtons = Text -> Text -> Form -> Form
ensureButton Text
"submit" Text
"Submit" (Form -> Form) -> (Form -> Form) -> Form -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Form -> Form
ensureButton Text
"reset" Text
"Reset"
where
ensureButton :: Text -> Text -> Form -> Form
ensureButton Text
typ Text
label' Form
form
| (Input -> Bool) -> [Input] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Input
x -> Input -> Text
inputType Input
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
typ) ([Input] -> Bool) -> [Input] -> Bool
forall a b. (a -> b) -> a -> b
$ Form -> [Input]
inputs Form
form = Form
form
| Bool
otherwise = Form
form { inputs = inputs form ++ [button typ label'] }
button :: Text -> Text -> Input
button Text
typ Text
label' = Input {
label :: Text
label = Text
label',
description :: Node
description = Text -> Node
mkEl Text
"",
autofocus :: Bool
autofocus = Bool
False,
disabled :: Bool
disabled = Bool
False,
formAction :: Maybe URI
formAction = Maybe URI
forall a. Maybe a
Nothing,
formMethod :: Maybe Text
formMethod = Maybe Text
forall a. Maybe a
Nothing,
formEnctype :: Maybe Text
formEnctype = Maybe Text
forall a. Maybe a
Nothing,
formValidate :: Bool
formValidate = Bool
True,
formTarget :: Maybe Text
formTarget = Maybe Text
forall a. Maybe a
Nothing,
inputName :: Text
inputName = Text
"",
inputType :: Text
inputType = Text
typ,
value :: Text
value = Text
"",
title :: Text
title = Text
"",
placeholder :: Text
placeholder = Text
"",
dirname :: Text
dirname = Text
"",
inputAutocomplete :: Text
inputAutocomplete = Text
"",
checked :: Bool
checked = Bool
False,
readonly :: Bool
readonly = Bool
False,
multiple :: Bool
multiple = Bool
False,
inputMode :: Text
inputMode = Text
"",
list :: [OptionGroup]
list = [],
range :: (Maybe Text, Maybe Text)
range = (Maybe Text
forall a. Maybe a
Nothing, Maybe Text
forall a. Maybe a
Nothing),
step :: Maybe Text
step = Maybe Text
forall a. Maybe a
Nothing,
lengthRange :: (Maybe Int, Maybe Int)
lengthRange = (Maybe Int
forall a. Maybe a
Nothing, Maybe Int
forall a. Maybe a
Nothing),
pattern :: Maybe Regex
pattern = Maybe Regex
forall a. Maybe a
Nothing,
required :: Bool
required = Bool
False,
size :: Maybe Int
size = Maybe Int
forall a. Maybe a
Nothing,
fileData :: FileSelector
fileData = FileSelector
defaultFileData,
imageData :: ImageData
imageData = ImageData
defaultImageData,
textArea :: TextArea
textArea = TextArea
defaultTextArea
}