aboutsummaryrefslogtreecommitdiff
path: root/js/src/Dom.purs
blob: 426c390b9dab046ae27a5ec07f8bf6e9bf92769a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
module Dom
  ( onInput
  , selectElement
  , selectElements
  , selectElementFrom
  , selectElementsFrom
  , replaceElement
  , appendNodes
  , setValue
  ) where

import Control.Monad.Eff (Eff)
import Control.Monad.Except (runExcept) as Except
import Data.Array (range, catMaybes) as Array
import Data.Either (Either(Right))
import Data.Foreign (toForeign) as Foreign
import Data.Maybe (Maybe(Nothing, Just))
import Data.Traversable (sequence) as Traversable
import Prelude

import DOM (DOM)
import DOM.HTML (window) as DOM
import DOM.HTML.HTMLInputElement (setValue) as HTMLInputElement
import DOM.HTML.Types (htmlDocumentToParentNode, readHTMLInputElement) as DOM
import DOM.HTML.Window (document) as DOM
import DOM.Node.Node (replaceChild, parentNode, appendChild) as DOM
import DOM.Node.NodeList (length, item) as DOM
import DOM.Node.ParentNode (QuerySelector)
import DOM.Node.ParentNode (querySelector, querySelectorAll) as DOM
import DOM.Node.Types (Element, Node, NodeList)
import DOM.Node.Types (elementToParentNode, readElement) as DOM

foreign import onInput :: forall e. Element -> (String -> Eff (dom :: DOM | e) Unit) -> Eff (dom :: DOM | e) Unit

selectElement :: forall e. QuerySelector -> Eff (dom :: DOM | e) (Maybe Element)
selectElement query = do
  document <- DOM.window >>= DOM.document
  DOM.querySelector query (DOM.htmlDocumentToParentNode document)

selectElements :: forall e. QuerySelector -> Eff (dom :: DOM | e) (Array Element)
selectElements query = do
  document <- DOM.window >>= DOM.document
  nodeList <- DOM.querySelectorAll query (DOM.htmlDocumentToParentNode document)
  getNodes nodeList

selectElementFrom :: forall e. Element -> QuerySelector -> Eff (dom :: DOM | e) (Maybe Element)
selectElementFrom elem query =
  DOM.querySelector query (DOM.elementToParentNode elem)

selectElementsFrom :: forall e. Element -> QuerySelector -> Eff (dom :: DOM | e) (Array Element)
selectElementsFrom elem query = do
  nodeList <- DOM.querySelectorAll query (DOM.elementToParentNode elem)
  getNodes nodeList

getNodes :: forall e. NodeList -> Eff (dom :: DOM | e) (Array Element)
getNodes nodeList = do
  length <- DOM.length nodeList
  Array.range 0 length
    # (map (\i -> (concatMaybe <<< map nodeToElement) <$> DOM.item i nodeList))
    # Traversable.sequence
    # map Array.catMaybes

concatMaybe :: forall a. Maybe (Maybe a) -> Maybe a
concatMaybe mma =
  case mma of
    Just x -> x
    Nothing -> Nothing

nodeToElement :: Node -> Maybe Element
nodeToElement node =
  case Except.runExcept $ DOM.readElement (Foreign.toForeign node) of
    Right element -> Just element
    _ -> Nothing

replaceElement :: forall e. Node -> Node -> Eff (dom :: DOM | e) Unit
replaceElement before after = do
  parent <- DOM.parentNode before
  case parent of
    Just n -> do
      _ <- DOM.replaceChild after before n
      pure unit
    Nothing ->
      pure unit

appendNodes :: forall e. Node -> Array Node -> Eff (dom :: DOM | e) Unit
appendNodes parent nodes =
  nodes
    # map (\n -> DOM.appendChild n parent)
    # Traversable.sequence
    # map (const unit)

setValue :: forall e. String -> Element -> Eff (dom :: DOM | e) Unit
setValue value elem =
  case Except.runExcept $ DOM.readHTMLInputElement (Foreign.toForeign elem) of
    Right inputElem -> do
      HTMLInputElement.setValue value inputElem
    _ ->
      pure unit