module Dom ( onInput , selectElement , selectElements , selectElementFrom , selectElementsFrom , replaceElement , appendNodes , setValue ) where import Control.Monad.Except (runExcept) as Except import Data.Array (range, catMaybes) as Array import Data.Maybe (Maybe(Nothing, Just)) import Data.Traversable (sequence) as Traversable import Effect (Effect) import Prelude import Web.DOM.Element (toParentNode, fromNode) as Element import Web.DOM.Internal.Types (Element, Node, NodeList) import Web.DOM.Node (replaceChild, parentNode, appendChild) as Node import Web.DOM.NodeList (length, item) as NodeList import Web.DOM.ParentNode (QuerySelector) import Web.DOM.ParentNode (querySelector, querySelectorAll) as DOM import Web.HTML (window) as HTML import Web.HTML.HTMLDocument as HTMLDocument import Web.HTML.HTMLInputElement (setValue, fromElement) as HTMLInputElement import Web.HTML.Window (document) as Window foreign import onInput :: Element -> (String -> Effect Unit) -> Effect Unit selectElement :: QuerySelector -> Effect (Maybe Element) selectElement query = do document <- HTML.window >>= Window.document DOM.querySelector query (HTMLDocument.toParentNode document) selectElements :: QuerySelector -> Effect (Array Element) selectElements query = do document <- HTML.window >>= Window.document nodeList <- DOM.querySelectorAll query (HTMLDocument.toParentNode document) getNodes nodeList selectElementFrom :: Element -> QuerySelector -> Effect (Maybe Element) selectElementFrom elem query = DOM.querySelector query (Element.toParentNode elem) selectElementsFrom :: Element -> QuerySelector -> Effect (Array Element) selectElementsFrom elem query = do nodeList <- DOM.querySelectorAll query (Element.toParentNode elem) getNodes nodeList getNodes :: NodeList -> Effect (Array Element) getNodes nodeList = do length <- NodeList.length nodeList Array.range 0 length # (map (\i -> (concatMaybe <<< map Element.fromNode) <$> NodeList.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 replaceElement :: Node -> Node -> Effect Unit replaceElement before after = do parent <- Node.parentNode before case parent of Just n -> do _ <- Node.replaceChild after before n pure unit Nothing -> pure unit appendNodes :: Node -> Array Node -> Effect Unit appendNodes parent nodes = nodes # map (\n -> Node.appendChild n parent) # Traversable.sequence # map (const unit) setValue :: String -> Element -> Effect Unit setValue value elem = case HTMLInputElement.fromElement elem of Just inputElem -> do HTMLInputElement.setValue value inputElem _ -> pure unit