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