module Halogen.HTML.Core (module Halogen.HTML.Core, module Web.HTML.Common, Namespace (..), ElemName (..)) where

import DOM.HTML.Indexed
import Data.MediaType
import HPrelude
import Halogen.Query.Input
import Halogen.VDom.DOM.Prop
import Halogen.VDom.Types as VDom
import Web.DOM.Element
import Web.Event.Event
import Web.HTML.Common

newtype HTML w i = HTML {forall w i. HTML w i -> VDom [Prop (Input i)] w
unHTML :: VDom [Prop (Input i)] w}

unHTML :: HTML w i -> VDom [Prop (Input i)] w
unHTML :: forall w i. HTML w i -> VDom [Prop (Input i)] w
unHTML = HTML w i -> VDom [Prop (Input i)] w
forall a b. Coercible a b => a -> b
coerce

instance Bifunctor HTML where
  bimap :: forall a b c d. (a -> b) -> (c -> d) -> HTML a c -> HTML b d
bimap a -> b
f c -> d
g (HTML VDom [Prop (Input c)] a
vdom) = VDom [Prop (Input d)] b -> HTML b d
forall w i. VDom [Prop (Input i)] w -> HTML w i
HTML (VDom [Prop (Input d)] b -> HTML b d)
-> VDom [Prop (Input d)] b -> HTML b d
forall a b. (a -> b) -> a -> b
$ ([Prop (Input c)] -> [Prop (Input d)])
-> (a -> b) -> VDom [Prop (Input c)] a -> VDom [Prop (Input d)] b
forall a b c d. (a -> b) -> (c -> d) -> VDom a c -> VDom b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((Prop (Input c) -> Prop (Input d))
-> [Prop (Input c)] -> [Prop (Input d)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Input c -> Input d) -> Prop (Input c) -> Prop (Input d)
forall a b. (a -> b) -> Prop a -> Prop b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((c -> d) -> Input c -> Input d
forall a b. (a -> b) -> Input a -> Input b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> d
g))) a -> b
f VDom [Prop (Input c)] a
vdom

instance Functor (HTML w) where
  fmap :: forall a b. (a -> b) -> HTML w a -> HTML w b
fmap = (a -> b) -> HTML w a -> HTML w b
forall b c a. (b -> c) -> HTML a b -> HTML a c
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second

renderWidget :: (i -> j) -> (w -> HTML x j) -> HTML w i -> HTML x j
renderWidget :: forall i j w x. (i -> j) -> (w -> HTML x j) -> HTML w i -> HTML x j
renderWidget i -> j
f w -> HTML x j
g (HTML VDom [Prop (Input i)] w
vdom) =
  VDom [Prop (Input j)] x -> HTML x j
forall w i. VDom [Prop (Input i)] w -> HTML w i
HTML (([Prop (Input i)] -> [Prop (Input j)])
-> (w -> VDom [Prop (Input j)] x)
-> VDom [Prop (Input i)] w
-> VDom [Prop (Input j)] x
forall a a' w w'.
(a -> a') -> (w -> VDom a' w') -> VDom a w -> VDom a' w'
VDom.renderWidget ((Prop (Input i) -> Prop (Input j))
-> [Prop (Input i)] -> [Prop (Input j)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((Input i -> Input j) -> Prop (Input i) -> Prop (Input j)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((i -> j) -> Input i -> Input j
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map i -> j
f))) ((.unHTML) (HTML x j -> VDom [Prop (Input j)] x)
-> (w -> HTML x j) -> w -> VDom [Prop (Input j)] x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> HTML x j
g) VDom [Prop (Input i)] w
vdom)

widget :: p -> HTML p q
widget :: forall p q. p -> HTML p q
widget = VDom [Prop (Input q)] p -> HTML p q
forall w i. VDom [Prop (Input i)] w -> HTML w i
HTML (VDom [Prop (Input q)] p -> HTML p q)
-> (p -> VDom [Prop (Input q)] p) -> p -> HTML p q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> VDom [Prop (Input q)] p
forall a w. w -> VDom a w
VDom.Widget

-- | Constructs a text node `HTML` value.
text :: Text -> HTML w i
text :: forall w i. Text -> HTML w i
text = VDom [Prop (Input i)] w -> HTML w i
forall w i. VDom [Prop (Input i)] w -> HTML w i
HTML (VDom [Prop (Input i)] w -> HTML w i)
-> (Text -> VDom [Prop (Input i)] w) -> Text -> HTML w i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> VDom [Prop (Input i)] w
forall a w. Text -> VDom a w
VDom.Text

-- | A smart constructor for HTML elements.
element :: forall w i. Maybe VDom.Namespace -> VDom.ElemName -> [Prop i] -> [HTML w i] -> HTML w i
element :: forall w i.
Maybe Namespace -> ElemName -> [Prop i] -> [HTML w i] -> HTML w i
element Maybe Namespace
ns ElemName
en [Prop i]
props [HTML w i]
htmls = VDom [Prop (Input i)] w -> HTML w i
forall w i. VDom [Prop (Input i)] w -> HTML w i
HTML (VDom [Prop (Input i)] w -> HTML w i)
-> VDom [Prop (Input i)] w -> HTML w i
forall a b. (a -> b) -> a -> b
$ Maybe Namespace
-> ElemName
-> [Prop (Input i)]
-> [VDom [Prop (Input i)] w]
-> VDom [Prop (Input i)] w
forall a w.
Maybe Namespace -> ElemName -> a -> [VDom a w] -> VDom a w
VDom.Elem Maybe Namespace
ns ElemName
en ((Prop i -> Prop (Input i)) -> [Prop i] -> [Prop (Input i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((i -> Input i) -> Prop i -> Prop (Input i)
forall a b. (a -> b) -> Prop a -> Prop b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap i -> Input i
forall msg. msg -> Input msg
Action) [Prop i]
props) ((HTML w i -> VDom [Prop (Input i)] w)
-> [HTML w i] -> [VDom [Prop (Input i)] w]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (.unHTML) [HTML w i]
htmls)

-- | A smart constructor for HTML elements with keyed children.
keyed :: forall w i. Maybe VDom.Namespace -> VDom.ElemName -> [Prop i] -> [(Text, HTML w i)] -> HTML w i
keyed :: forall w i.
Maybe Namespace
-> ElemName -> [Prop i] -> [(Text, HTML w i)] -> HTML w i
keyed Maybe Namespace
ns ElemName
name [Prop i]
props [(Text, HTML w i)]
children = VDom [Prop (Input i)] w -> HTML w i
forall w i. VDom [Prop (Input i)] w -> HTML w i
HTML (VDom [Prop (Input i)] w -> HTML w i)
-> VDom [Prop (Input i)] w -> HTML w i
forall a b. (a -> b) -> a -> b
$ Maybe Namespace
-> ElemName
-> [Prop (Input i)]
-> [(Text, VDom [Prop (Input i)] w)]
-> VDom [Prop (Input i)] w
forall a w.
Maybe Namespace -> ElemName -> a -> [(Text, VDom a w)] -> VDom a w
VDom.Keyed Maybe Namespace
ns ElemName
name ((Prop i -> Prop (Input i)) -> [Prop i] -> [Prop (Input i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((i -> Input i) -> Prop i -> Prop (Input i)
forall a b. (a -> b) -> Prop a -> Prop b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap i -> Input i
forall msg. msg -> Input msg
Action) [Prop i]
props) (((Text, HTML w i) -> (Text, VDom [Prop (Input i)] w))
-> [(Text, HTML w i)] -> [(Text, VDom [Prop (Input i)] w)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((HTML w i -> VDom [Prop (Input i)] w)
-> (Text, HTML w i) -> (Text, VDom [Prop (Input i)] w)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second HTML w i -> VDom [Prop (Input i)] w
forall w i. HTML w i -> VDom [Prop (Input i)] w
unHTML) [(Text, HTML w i)]
children)

-- | Create a HTML property.
prop :: forall value i. (IsProp value) => PropName value -> value -> Prop i
prop :: forall value i. IsProp value => PropName value -> value -> Prop i
prop PropName value
name = PropName value -> PropValue value -> Prop i
forall msg val. PropName val -> PropValue val -> Prop msg
Property PropName value
name (PropValue value -> Prop i)
-> (value -> PropValue value) -> value -> Prop i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. value -> PropValue value
forall a. IsProp a => a -> PropValue a
toPropValue

-- | Create a HTML attribute.
attr :: Maybe VDom.Namespace -> AttrName -> Text -> Prop i
attr :: forall i. Maybe Namespace -> AttrName -> Text -> Prop i
attr = Maybe Namespace -> AttrName -> Text -> Prop i
forall i. Maybe Namespace -> AttrName -> Text -> Prop i
Attribute

-- | Create an event handler.
handler :: EventType -> (Event -> Maybe i) -> Prop i
handler :: forall i. EventType -> (Event -> Maybe i) -> Prop i
handler = EventType -> (Event -> Maybe i) -> Prop i
forall i. EventType -> (Event -> Maybe i) -> Prop i
Handler

ref :: forall i. (Maybe Element -> Maybe i) -> Prop i
ref :: forall i. (Maybe Element -> Maybe i) -> Prop i
ref Maybe Element -> Maybe i
f =
  (ElemRef Element -> Maybe i) -> Prop i
forall msg. (ElemRef Element -> Maybe msg) -> Prop msg
Ref
    ((ElemRef Element -> Maybe i) -> Prop i)
-> (ElemRef Element -> Maybe i) -> Prop i
forall a b. (a -> b) -> a -> b
$ Maybe Element -> Maybe i
f
    (Maybe Element -> Maybe i)
-> (ElemRef Element -> Maybe Element) -> ElemRef Element -> Maybe i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
      Created Element
x -> Element -> Maybe Element
forall a. a -> Maybe a
Just Element
x
      Removed Element
_ -> Maybe Element
forall a. Maybe a
Nothing

class IsProp a where
  toPropValue :: a -> PropValue a

instance {-# OVERLAPPABLE #-} (Integral a) => IsProp a where toPropValue :: a -> PropValue a
toPropValue = a -> PropValue a
forall a. Integral a => a -> PropValue a
IntProp

instance {-# OVERLAPPING #-} IsProp Text where toPropValue :: Text -> PropValue Text
toPropValue = Text -> PropValue Text
TxtProp

instance {-# OVERLAPPING #-} IsProp Double where toPropValue :: Double -> PropValue Double
toPropValue = Double -> PropValue Double
NumProp

instance {-# OVERLAPPING #-} IsProp Bool where toPropValue :: Bool -> PropValue Bool
toPropValue = Bool -> PropValue Bool
BoolProp

instance IsProp MediaType where
  toPropValue :: MediaType -> PropValue MediaType
toPropValue = (MediaType -> Text) -> MediaType -> PropValue MediaType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp MediaType -> Text
forall a b. Coercible a b => a -> b
coerce

instance IsProp ButtonType where
  toPropValue :: ButtonType -> PropValue ButtonType
toPropValue = (ButtonType -> Text) -> ButtonType -> PropValue ButtonType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp ButtonType -> Text
renderButtonType

instance IsProp CrossOriginValue where
  toPropValue :: CrossOriginValue -> PropValue CrossOriginValue
toPropValue = (CrossOriginValue -> Text)
-> CrossOriginValue -> PropValue CrossOriginValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp CrossOriginValue -> Text
renderCrossOriginValue

instance IsProp DirValue where
  toPropValue :: DirValue -> PropValue DirValue
toPropValue = (DirValue -> Text) -> DirValue -> PropValue DirValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp DirValue -> Text
renderDirValue

instance IsProp FormMethod where
  toPropValue :: FormMethod -> PropValue FormMethod
toPropValue = (FormMethod -> Text) -> FormMethod -> PropValue FormMethod
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp FormMethod -> Text
renderFormMethod

instance IsProp InputType where
  toPropValue :: InputType -> PropValue InputType
toPropValue = (InputType -> Text) -> InputType -> PropValue InputType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp InputType -> Text
renderInputType

instance IsProp KindValue where
  toPropValue :: KindValue -> PropValue KindValue
toPropValue = (KindValue -> Text) -> KindValue -> PropValue KindValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp KindValue -> Text
renderKindValue

instance IsProp MenuitemType where
  toPropValue :: MenuitemType -> PropValue MenuitemType
toPropValue = (MenuitemType -> Text) -> MenuitemType -> PropValue MenuitemType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp MenuitemType -> Text
renderMenuitemType

instance IsProp MenuType where
  toPropValue :: MenuType -> PropValue MenuType
toPropValue = (MenuType -> Text) -> MenuType -> PropValue MenuType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp MenuType -> Text
renderMenuType

instance IsProp AutocompleteType where
  toPropValue :: AutocompleteType -> PropValue AutocompleteType
toPropValue = (AutocompleteType -> Text)
-> AutocompleteType -> PropValue AutocompleteType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp AutocompleteType -> Text
renderAutocompleteType

instance IsProp OrderedListType where
  toPropValue :: OrderedListType -> PropValue OrderedListType
toPropValue = (OrderedListType -> Text)
-> OrderedListType -> PropValue OrderedListType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp OrderedListType -> Text
renderOrderedListType

instance IsProp PreloadValue where
  toPropValue :: PreloadValue -> PropValue PreloadValue
toPropValue = (PreloadValue -> Text) -> PreloadValue -> PropValue PreloadValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp PreloadValue -> Text
renderPreloadValue

instance IsProp ScopeValue where
  toPropValue :: ScopeValue -> PropValue ScopeValue
toPropValue = (ScopeValue -> Text) -> ScopeValue -> PropValue ScopeValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp ScopeValue -> Text
renderScopeValue

instance IsProp StepValue where
  toPropValue :: StepValue -> PropValue StepValue
toPropValue = (StepValue -> Text) -> StepValue -> PropValue StepValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp StepValue -> Text
renderStepValue

instance IsProp WrapValue where
  toPropValue :: WrapValue -> PropValue WrapValue
toPropValue = (WrapValue -> Text) -> WrapValue -> PropValue WrapValue
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp WrapValue -> Text
renderWrapValue

instance IsProp InputAcceptType where
  toPropValue :: InputAcceptType -> PropValue InputAcceptType
toPropValue = (InputAcceptType -> Text)
-> InputAcceptType -> PropValue InputAcceptType
forall val. (val -> Text) -> val -> PropValue val
ViaTxtProp InputAcceptType -> Text
renderInputAcceptType