packages feed

haste-lib-0.6.0.0: src/Haste/DOM.hs

{-# LANGUAGE GADTs #-}
-- | DOM manipulation functions using 'String' for string representation.
module Haste.DOM (
    -- * Basic types and elements
    IsElem (..), Elem (..),
    document, documentBody, documentHead,

    -- * Adding and removing child elements
    appendChild, insertChildBefore,  setChildren, clearChildren, deleteChild,

    -- * Selecting child elements
    getFirstChild, getLastChild, getChildren,

    -- * Creating elements
    newElem, newTextElem,

    -- * Setting attributes on elements
    Attribute, AttrValue, AttrName (..),
    attribute, set, with, children,
    prop, style, attr, (=:),

    -- * Selecting elements
    QuerySelector, ElemID,
    elemById, elemsByQS, elemsByClass,
    withElem , withElems, withElemsQS, mapQS, mapQS_,

    -- * Properties and attributes
    PropID,
    setProp, unsetProp, getProp, setAttr, unsetAttr, getAttr, J.getValue,

    -- * Style sheets and classes
    ElemClass, getStyle, setStyle, setClass, toggleClass, hasClass,
    addStylesheet,

    -- * Triggering events
    click, focus, blur,

    -- * File elements
    J.getFileData, getFileName,
  ) where
import qualified Haste.DOM.JSString as J
import Haste.DOM.Core
import Haste.Prim (fromJSStr, toJSStr)
import Control.Monad.IO.Class

type PropID = String
type ElemID = String
type QuerySelector = String
type ElemClass = String
type AttrValue = String

-- | Create a style attribute name.
style :: String -> AttrName
style = StyleName . toJSStr

-- | Create an HTML attribute name.
attr :: String -> AttrName
attr = AttrName . toJSStr

-- | Create a DOM property name.
--   See <http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html> for more information about the difference between attributes and properties.
prop :: String -> AttrName
prop = PropName . toJSStr

-- | Create an 'Attribute'.
(=:) :: AttrName -> AttrValue -> Attribute
name =: val = attribute name (toJSStr val)

-- | Create an element.
newElem :: MonadIO m => String -> m Elem
newElem = J.newElem . toJSStr

-- | Create a text node.
newTextElem :: MonadIO m => String -> m Elem
newTextElem = J.newTextElem . toJSStr

-- | Set a property of the given element.
setProp :: (IsElem e, MonadIO m) => e -> PropID -> String -> m ()
setProp e property val = J.setProp e (toJSStr property) (toJSStr val)

-- | Unset a property of the given element. Primarily useful with boolean
--   properties.
unsetProp :: (IsElem e, MonadIO m) => e -> PropID -> m ()
unsetProp e property = J.unsetProp e (toJSStr property)

-- | Set an attribute of the given element.
setAttr :: (IsElem e, MonadIO m) => e -> PropID -> String -> m ()
setAttr e property val = J.setAttr e (toJSStr property) (toJSStr val)

-- | Unset an attribute of the given element. Primarily useful with boolean
--   attributes.
unsetAttr :: (IsElem e, MonadIO m) => e -> PropID -> m ()
unsetAttr e property = J.unsetAttr e (toJSStr property)

-- | Get a property of an element.
getProp :: (IsElem e, MonadIO m) => e -> PropID -> m String
getProp e property = J.getProp e (toJSStr property) >>= return . fromJSStr

-- | Get an attribute of an element.
getAttr :: (IsElem e, MonadIO m) => e -> PropID -> m String
getAttr e property = J.getAttr e (toJSStr property) >>= return . fromJSStr

-- | Get a CSS style property of an element.
getStyle :: (IsElem e, MonadIO m) => e -> PropID -> m String
getStyle e property = J.getStyle e (toJSStr property) >>= return . fromJSStr

-- | Set a CSS style property on an element.
setStyle :: (IsElem e, MonadIO m) => e -> PropID -> String -> m ()
setStyle e property val = J.setStyle e (toJSStr property) (toJSStr val)

-- | Get an element by its HTML ID attribute.
elemById :: MonadIO m => ElemID -> m (Maybe Elem)
elemById = J.elemById . toJSStr

-- | Get all elements of the given class.
elemsByClass :: MonadIO m => ElemClass -> m [Elem]
elemsByClass = J.elemsByClass . toJSStr

-- | Get all children elements matching a query selector.
elemsByQS :: MonadIO m => Elem -> QuerySelector -> m [Elem]
elemsByQS el = J.elemsByQS el . toJSStr

-- | Perform an IO action on an element.
withElem :: MonadIO m => ElemID -> (Elem -> m a) -> m a
withElem = J.withElem . toJSStr

-- | Perform an IO action over several elements. Throws an error if some of the
--   elements are not found.
withElems :: MonadIO m => [ElemID] -> ([Elem] -> m a) -> m a
withElems = J.withElems . map toJSStr

-- | Perform an IO action over the a list of elements matching a query
--   selector.
withElemsQS :: (IsElem e, MonadIO m)
            => e
            -> QuerySelector
            -> ([Elem] -> m a)
            -> m a
withElemsQS el = J.withElemsQS el . toJSStr

-- | Map an IO computation over the list of elements matching a query selector.
mapQS :: (IsElem e, MonadIO m)
      => e
      -> QuerySelector
      -> (Elem -> m a)
      -> m [a]
mapQS el = J.mapQS el . toJSStr

-- | Like @mapQS@ but returns no value.
mapQS_ :: (IsElem e, MonadIO m)
       => e
       -> QuerySelector
       -> (Elem -> m a)
       -> m ()
mapQS_ el = J.mapQS_ el . toJSStr

-- | Get the name of the currently selected file from a file input element.
--   Any directory information is stripped, and only the actual file name is
--   returned, as the directory information is useless (and faked) anyway.
getFileName :: (IsElem e, MonadIO m) => e -> m String
getFileName e = J.getFileName e >>= return . fromJSStr

-- | Add or remove a class from an element's class list.
setClass :: (IsElem e, MonadIO m) => e -> String -> Bool -> m ()
setClass e sel = J.setClass e (toJSStr sel)

-- | Toggle the existence of a class within an elements class list.
toggleClass :: (IsElem e, MonadIO m) => e -> String -> m ()
toggleClass e = J.toggleClass e . toJSStr

-- | Does the given element have a particular class?
hasClass :: (IsElem e, MonadIO m) => e -> String -> m Bool
hasClass e = J.hasClass e . toJSStr

-- | Append the stylesheet at the given URL to @document.head@.
addStylesheet :: MonadIO m => String -> m ()
addStylesheet = J.addStylesheet . toJSStr