Skip to content
This repository was archived by the owner on Oct 4, 2020. It is now read-only.

Commit 2bea9c7

Browse files
authored
Merge pull request #106 from sectore/feature/classlist-domtokenlist
Add `classList` + functions of `DOMTokenList`
2 parents 62c4599 + d2bfd6f commit 2bea9c7

File tree

6 files changed

+259
-15
lines changed

6 files changed

+259
-15
lines changed

src/DOM/HTML/HTMLElement.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ exports.setClassName = function (className) {
6868
};
6969
};
7070

71+
exports.classList = function (element) {
72+
return function () {
73+
return element.classList;
74+
};
75+
};
76+
7177
// ----------------------------------------------------------------------------
7278

7379
exports.hidden = function (elt) {

src/DOM/HTML/HTMLElement.purs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module DOM.HTML.HTMLElement
77
, setDir
88
, className
99
, setClassName
10+
, classList
1011
, hidden
1112
, setHidden
1213
, tabIndex
@@ -30,12 +31,13 @@ module DOM.HTML.HTMLElement
3031
) where
3132

3233
import Prelude
34+
3335
import Control.Monad.Eff (Eff)
34-
import Data.Nullable (Nullable, toMaybe)
35-
import Data.Maybe (Maybe)
3636
import DOM (DOM)
3737
import DOM.HTML.Types (HTMLElement)
38-
import DOM.Node.Types (Element)
38+
import DOM.Node.Types (DOMTokenList, Element)
39+
import Data.Maybe (Maybe)
40+
import Data.Nullable (Nullable, toMaybe)
3941

4042
foreign import title :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) String
4143
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 |
4951
foreign import className :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) String
5052
foreign import setClassName :: forall eff. String -> HTMLElement -> Eff (dom :: DOM | eff) Unit
5153

54+
foreign import classList :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) DOMTokenList
55+
5256
foreign import hidden :: forall eff. HTMLElement -> Eff (dom :: DOM | eff) Boolean
5357
foreign import setHidden :: forall eff. Boolean -> HTMLElement -> Eff (dom :: DOM | eff) Unit
5458

src/DOM/Node/DOMTokenList.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"use strict";
2+
3+
exports.add = function(list) {
4+
return function(token) {
5+
return function() {
6+
return list.add(token);
7+
};
8+
};
9+
};
10+
11+
exports.remove = function(list) {
12+
return function(token) {
13+
return function() {
14+
return list.remove(token);
15+
};
16+
};
17+
};
18+
19+
exports.contains = function(list) {
20+
return function(token) {
21+
return function() {
22+
return list.contains(token);
23+
};
24+
};
25+
};
26+
27+
exports.toggle = function(list) {
28+
return function(token) {
29+
return function() {
30+
return list.toggle(token);
31+
};
32+
};
33+
};
34+
35+
exports.toggleForce = function(list) {
36+
return function(token) {
37+
return function(force) {
38+
return function() {
39+
return list.toggle(token, force);
40+
};
41+
};
42+
};
43+
};
44+
45+
exports._item = function(list) {
46+
return function(index) {
47+
return function() {
48+
return list.item(index);
49+
};
50+
};
51+
};

src/DOM/Node/DOMTokenList.purs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module DOM.Node.ClassList
2+
( add
3+
, contains
4+
, item
5+
, remove
6+
, toggle
7+
, toggleForce
8+
) where
9+
10+
import Prelude
11+
12+
import Control.Monad.Eff (Eff)
13+
import DOM (DOM)
14+
import DOM.Node.Types (DOMTokenList)
15+
import Data.Maybe (Maybe)
16+
import Data.Nullable (Nullable, toMaybe)
17+
18+
foreign import add :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Unit
19+
20+
foreign import remove :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Unit
21+
22+
foreign import contains :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Boolean
23+
24+
foreign import toggle :: forall eff. DOMTokenList -> String -> Eff (dom :: DOM | eff) Boolean
25+
26+
foreign import toggleForce :: forall eff. DOMTokenList -> String -> Boolean -> Eff (dom :: DOM | eff) Boolean
27+
28+
foreign import _item :: forall eff. DOMTokenList -> Int -> Eff (dom :: DOM | eff) (Nullable String)
29+
30+
item :: forall eff. DOMTokenList -> Int -> Eff (dom :: DOM | eff) (Maybe String)
31+
item index = map toMaybe <<< _item index

test/DOM/Node/DomTokenList.purs

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
module Test.DOM.Node.DOMTokenList where
2+
3+
import Prelude
4+
5+
import Control.Monad.Aff.Console (CONSOLE)
6+
import Control.Monad.Eff.Class (liftEff)
7+
import Control.Monad.Free (Free)
8+
import DOM (DOM)
9+
import DOM.HTML (window)
10+
import DOM.HTML.Document (body)
11+
import DOM.HTML.HTMLElement (classList, className, setClassName)
12+
import DOM.HTML.Types (WINDOW)
13+
import DOM.HTML.Window (document)
14+
import DOM.Node.ClassList (add, contains, remove, toggle, toggleForce, item) as CL
15+
import Data.Maybe (Maybe(..), fromMaybe)
16+
import Test.Unit (TestF, describe, it)
17+
import Test.Unit.Assert (shouldEqual)
18+
19+
domTokenListTests :: forall eff. Free (TestF (dom :: DOM, console :: CONSOLE,
20+
window :: WINDOW | eff)) Unit
21+
domTokenListTests = do
22+
describe "DOMTokenList of classList" do
23+
it "contains a token" do
24+
body' <- liftEff $ window >>= document >>= body
25+
result <- case body' of
26+
Just body'' -> liftEff do
27+
_ <- setClassName "a b c" body''
28+
list <- classList body''
29+
CL.contains list "a"
30+
Nothing -> pure false
31+
32+
result `shouldEqual` true
33+
34+
it "adds a token" do
35+
body' <- liftEff $ window >>= document >>= body
36+
result <- case body' of
37+
Just body'' -> liftEff do
38+
-- clear class names, first
39+
_ <- setClassName "" body''
40+
list <- classList body''
41+
_ <- CL.add list "a"
42+
className body''
43+
Nothing -> pure "failed"
44+
45+
result `shouldEqual` "a"
46+
47+
it "removes a token" do
48+
body' <- liftEff $ window >>= document >>= body
49+
result <- case body' of
50+
Just body'' -> liftEff do
51+
_ <- setClassName "a b c" body''
52+
list <- classList body''
53+
_ <- CL.remove list "b"
54+
resultA <- CL.contains list "a"
55+
resultB <- CL.contains list "b"
56+
resultC <- CL.contains list "c"
57+
-- Only "b" should be removed
58+
pure $ resultA && not resultB && resultC
59+
Nothing -> pure false
60+
61+
result `shouldEqual` true
62+
63+
it "toggles a token by removing its value" do
64+
body' <- liftEff $ window >>= document >>= body
65+
result <- case body' of
66+
Just body'' -> liftEff do
67+
_ <- setClassName "a b c" body''
68+
list <- classList body''
69+
_ <- CL.toggle list "c"
70+
className body''
71+
Nothing -> pure "failed"
72+
73+
result `shouldEqual` "a b"
74+
75+
it "toggles a token by adding its value" do
76+
body' <- liftEff $ window >>= document >>= body
77+
result <- case body' of
78+
Just body'' -> liftEff do
79+
_ <- setClassName "a b" body''
80+
list <- classList body''
81+
_ <- CL.toggle list "c"
82+
className body''
83+
Nothing -> pure "failed"
84+
85+
result `shouldEqual` "a b c"
86+
87+
it "toggles a token by forcing to add its value" do
88+
body' <- liftEff $ window >>= document >>= body
89+
result <- case body' of
90+
Just body'' -> liftEff do
91+
_ <- setClassName "a b" body''
92+
list <- classList body''
93+
_ <- CL.toggleForce list "c" true
94+
className body''
95+
Nothing -> pure "failed"
96+
97+
result `shouldEqual` "a b c"
98+
99+
it "toggles a token by forcing to add (but not to remove) its value" do
100+
body' <- liftEff $ window >>= document >>= body
101+
result <- case body' of
102+
Just body'' -> liftEff do
103+
_ <- setClassName "a b c" body''
104+
list <- classList body''
105+
_ <- CL.toggleForce list "c" true
106+
className body''
107+
Nothing -> pure "failed"
108+
109+
result `shouldEqual` "a b c"
110+
111+
it "toggles a token by forcing to remove its value" do
112+
body' <- liftEff $ window >>= document >>= body
113+
result <- case body' of
114+
Just body'' -> liftEff do
115+
_ <- setClassName "a b c" body''
116+
list <- classList body''
117+
_ <- CL.toggleForce list "c" false
118+
className body''
119+
Nothing -> pure "failed"
120+
121+
result `shouldEqual` "a b"
122+
123+
it "toggles a token by forcing to remove (but not to add) its value" do
124+
body' <- liftEff $ window >>= document >>= body
125+
result <- case body' of
126+
Just body'' -> liftEff do
127+
_ <- setClassName "a b" body''
128+
list <- classList body''
129+
_ <- CL.toggleForce list "c" false
130+
className body''
131+
Nothing -> pure "failed"
132+
133+
result `shouldEqual` "a b"
134+
135+
it "returns an item if available" do
136+
body' <- liftEff $ window >>= document >>= body
137+
result <- case body' of
138+
Just body'' -> liftEff do
139+
_ <- setClassName "a b c" body''
140+
list <- classList body''
141+
CL.item list 2
142+
Nothing -> pure Nothing
143+
144+
(fromMaybe "not found" result) `shouldEqual` "c"
145+
146+
it "returns not an item if it's not available" do
147+
body' <- liftEff $ window >>= document >>= body
148+
result <- case body' of
149+
Just body'' -> liftEff do
150+
_ <- setClassName "a b c" body''
151+
list <- classList body''
152+
CL.item list 5
153+
Nothing -> pure Nothing
154+
155+
(fromMaybe "not found" result) `shouldEqual` "not found"

test/Main.purs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,30 @@
11
module Test.Main where
22

33
import Prelude (($), discard)
4+
import Control.Monad.Aff (launchAff, Canceler)
5+
import Control.Monad.Aff.AVar (AVAR)
6+
import Control.Monad.Eff (Eff)
7+
import Control.Monad.Eff.Class (liftEff)
8+
import Control.Monad.Eff.Console (CONSOLE)
9+
import Control.Monad.Eff.Exception (EXCEPTION)
410
import DOM (DOM)
511
import DOM.HTML.Types (WINDOW)
612
import Data.Enum (fromEnum)
713
import ExitCodes (ExitCode(Success))
814
import PhantomJS.Phantom (exit, PHANTOMJS)
9-
import Control.Monad.Aff (Aff, launchAff, Canceler)
10-
import Control.Monad.Eff.Class (liftEff) as EffClass
11-
import Control.Monad.Aff.AVar (AVAR)
12-
import Control.Monad.Eff (Eff)
13-
import Control.Monad.Eff.Console (CONSOLE)
14-
import Control.Monad.Eff.Exception (EXCEPTION)
15+
import Test.DOM.HTML.Window (domHtmlWindowTests)
16+
import Test.DOM.Node.DOMTokenList (domTokenListTests)
1517
import Test.Unit (describe, it)
1618
import Test.Unit.Assert (assert)
1719
import Test.Unit.Output.Simple (runTest)
18-
import Test.DOM.HTML.Window (domHtmlWindowTests)
19-
20-
21-
liftEff :: forall eff a. Eff (phantomjs :: PHANTOMJS | eff) a -> Aff (phantomjs :: PHANTOMJS | eff) a
22-
liftEff = EffClass.liftEff
23-
2420

2521
main
2622
:: forall eff
2723
. Eff (exception :: EXCEPTION, console :: CONSOLE, avar :: AVAR, dom :: DOM, window :: WINDOW, phantomjs :: PHANTOMJS | eff)
2824
(Canceler (console :: CONSOLE, avar :: AVAR, dom :: DOM, window :: WINDOW, phantomjs :: PHANTOMJS | eff))
2925
main = launchAff $ runTest do
3026
domHtmlWindowTests
27+
domTokenListTests
3128

3229
describe "exit" $ do
3330
it "should exit" $ do

0 commit comments

Comments
 (0)