diff --git a/src/DOM/HTML/HTMLElement.js b/src/DOM/HTML/HTMLElement.js index 6fffb89..f5aa96f 100644 --- a/src/DOM/HTML/HTMLElement.js +++ b/src/DOM/HTML/HTMLElement.js @@ -68,6 +68,12 @@ exports.setClassName = function (className) { }; }; +exports.classList = function (element) { + return function () { + return element.classList; + }; +}; + // ---------------------------------------------------------------------------- exports.hidden = function (elt) { diff --git a/src/DOM/HTML/HTMLElement.purs b/src/DOM/HTML/HTMLElement.purs index 950a6c9..bb35fcc 100644 --- a/src/DOM/HTML/HTMLElement.purs +++ b/src/DOM/HTML/HTMLElement.purs @@ -7,6 +7,7 @@ module DOM.HTML.HTMLElement , setDir , className , setClassName + , classList , hidden , setHidden , tabIndex @@ -30,12 +31,13 @@ module DOM.HTML.HTMLElement ) where import Prelude + import Control.Monad.Eff (Eff) -import Data.Nullable (Nullable, toMaybe) -import Data.Maybe (Maybe) import DOM (DOM) import DOM.HTML.Types (HTMLElement) -import DOM.Node.Types (Element) +import DOM.Node.Types (DOMTokenList, Element) +import Data.Maybe (Maybe) +import Data.Nullable (Nullable, toMaybe) foreign import title :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) String foreign import setTitle :: forall eff. String -> HTMLElement -> Eff (dom :: DOM | eff) Unit @@ -49,6 +51,8 @@ foreign import setDir :: forall eff. String -> HTMLElement -> Eff (dom :: DOM | foreign import className :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) String foreign import setClassName :: forall eff. String -> HTMLElement -> Eff (dom :: DOM | eff) Unit +foreign import classList :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) DOMTokenList + foreign import hidden :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) Boolean foreign import setHidden :: forall eff. Boolean -> HTMLElement -> Eff (dom :: DOM | eff) Unit diff --git a/src/DOM/Node/DOMTokenList.js b/src/DOM/Node/DOMTokenList.js new file mode 100644 index 0000000..a8fe4fb --- /dev/null +++ b/src/DOM/Node/DOMTokenList.js @@ -0,0 +1,51 @@ +"use strict"; + +exports.add = function(list) { + return function(token) { + return function() { + return list.add(token); + }; + }; +}; + +exports.remove = function(list) { + return function(token) { + return function() { + return list.remove(token); + }; + }; +}; + +exports.contains = function(list) { + return function(token) { + return function() { + return list.contains(token); + }; + }; +}; + +exports.toggle = function(list) { + return function(token) { + return function() { + return list.toggle(token); + }; + }; +}; + +exports.toggleForce = function(list) { + return function(token) { + return function(force) { + return function() { + return list.toggle(token, force); + }; + }; + }; +}; + +exports._item = function(list) { + return function(index) { + return function() { + return list.item(index); + }; + }; +}; diff --git a/src/DOM/Node/DOMTokenList.purs b/src/DOM/Node/DOMTokenList.purs new file mode 100644 index 0000000..0d49ad5 --- /dev/null +++ b/src/DOM/Node/DOMTokenList.purs @@ -0,0 +1,31 @@ +module DOM.Node.ClassList + ( add + , contains + , item + , remove + , toggle + , toggleForce + ) where + +import Prelude + +import Control.Monad.Eff (Eff) +import DOM (DOM) +import DOM.Node.Types (DOMTokenList) +import Data.Maybe (Maybe) +import Data.Nullable (Nullable, toMaybe) + +foreign import add :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Unit + +foreign import remove :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Unit + +foreign import contains :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Boolean + +foreign import toggle :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Boolean + +foreign import toggleForce :: forall eff. DOMTokenList -> String -> Boolean -> Eff (dom :: DOM | eff) Boolean + +foreign import _item :: forall eff. DOMTokenList -> Int -> Eff (dom :: DOM | eff) (Nullable String) + +item :: forall eff. DOMTokenList -> Int -> Eff (dom :: DOM | eff) (Maybe String) +item index = map toMaybe <<< _item index diff --git a/test/DOM/Node/DomTokenList.purs b/test/DOM/Node/DomTokenList.purs new file mode 100644 index 0000000..88b1885 --- /dev/null +++ b/test/DOM/Node/DomTokenList.purs @@ -0,0 +1,155 @@ +module Test.DOM.Node.DOMTokenList where + +import Prelude + +import Control.Monad.Aff.Console (CONSOLE) +import Control.Monad.Eff.Class (liftEff) +import Control.Monad.Free (Free) +import DOM (DOM) +import DOM.HTML (window) +import DOM.HTML.Document (body) +import DOM.HTML.HTMLElement (classList, className, setClassName) +import DOM.HTML.Types (WINDOW) +import DOM.HTML.Window (document) +import DOM.Node.ClassList (add, contains, remove, toggle, toggleForce, item) as CL +import Data.Maybe (Maybe(..), fromMaybe) +import Test.Unit (TestF, describe, it) +import Test.Unit.Assert (shouldEqual) + +domTokenListTests :: forall eff. Free (TestF (dom :: DOM, console :: CONSOLE, + window :: WINDOW | eff)) Unit +domTokenListTests = do + describe "DOMTokenList of classList" do + it "contains a token" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + CL.contains list "a" + Nothing -> pure false + + result `shouldEqual` true + + it "adds a token" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + -- clear class names, first + _ <- setClassName "" body'' + list <- classList body'' + _ <- CL.add list "a" + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a" + + it "removes a token" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + _ <- CL.remove list "b" + resultA <- CL.contains list "a" + resultB <- CL.contains list "b" + resultC <- CL.contains list "c" + -- Only "b" should be removed + pure $ resultA && not resultB && resultC + Nothing -> pure false + + result `shouldEqual` true + + it "toggles a token by removing its value" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + _ <- CL.toggle list "c" + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a b" + + it "toggles a token by adding its value" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b" body'' + list <- classList body'' + _ <- CL.toggle list "c" + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a b c" + + it "toggles a token by forcing to add its value" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b" body'' + list <- classList body'' + _ <- CL.toggleForce list "c" true + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a b c" + + it "toggles a token by forcing to add (but not to remove) its value" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + _ <- CL.toggleForce list "c" true + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a b c" + + it "toggles a token by forcing to remove its value" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + _ <- CL.toggleForce list "c" false + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a b" + + it "toggles a token by forcing to remove (but not to add) its value" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b" body'' + list <- classList body'' + _ <- CL.toggleForce list "c" false + className body'' + Nothing -> pure "failed" + + result `shouldEqual` "a b" + + it "returns an item if available" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + CL.item list 2 + Nothing -> pure Nothing + + (fromMaybe "not found" result) `shouldEqual` "c" + + it "returns not an item if it's not available" do + body' <- liftEff $ window >>= document >>= body + result <- case body' of + Just body'' -> liftEff do + _ <- setClassName "a b c" body'' + list <- classList body'' + CL.item list 5 + Nothing -> pure Nothing + + (fromMaybe "not found" result) `shouldEqual` "not found" diff --git a/test/Main.purs b/test/Main.purs index 697b80d..13c0c44 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -1,26 +1,22 @@ module Test.Main where import Prelude (($), discard) +import Control.Monad.Aff (launchAff, Canceler) +import Control.Monad.Aff.AVar (AVAR) +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.Class (liftEff) +import Control.Monad.Eff.Console (CONSOLE) +import Control.Monad.Eff.Exception (EXCEPTION) import DOM (DOM) import DOM.HTML.Types (WINDOW) import Data.Enum (fromEnum) import ExitCodes (ExitCode(Success)) import PhantomJS.Phantom (exit, PHANTOMJS) -import Control.Monad.Aff (Aff, launchAff, Canceler) -import Control.Monad.Eff.Class (liftEff) as EffClass -import Control.Monad.Aff.AVar (AVAR) -import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Console (CONSOLE) -import Control.Monad.Eff.Exception (EXCEPTION) +import Test.DOM.HTML.Window (domHtmlWindowTests) +import Test.DOM.Node.DOMTokenList (domTokenListTests) import Test.Unit (describe, it) import Test.Unit.Assert (assert) import Test.Unit.Output.Simple (runTest) -import Test.DOM.HTML.Window (domHtmlWindowTests) - - -liftEff :: forall eff a. Eff (phantomjs :: PHANTOMJS | eff) a -> Aff (phantomjs :: PHANTOMJS | eff) a -liftEff = EffClass.liftEff - main :: forall eff @@ -28,6 +24,7 @@ main (Canceler (console :: CONSOLE, avar :: AVAR, dom :: DOM, window :: WINDOW, phantomjs :: PHANTOMJS | eff)) main = launchAff $ runTest do domHtmlWindowTests + domTokenListTests describe "exit" $ do it "should exit" $ do