use nicer name for the css classes property, added classSet for contains/iteration support and an addClass/removeClass method to Element along with better tests of CSS class support
This commit is contained in:
+71
-4
@@ -65,22 +65,89 @@ set(value) {
|
||||
this.setAttribute("style", value)
|
||||
}
|
||||
|
||||
// TODO can we come up with a better name; 'class' is a reserved word?
|
||||
var Element.cssClass : String
|
||||
var Element.classes : String
|
||||
get() = this.getAttribute("class")?: ""
|
||||
set(value) {
|
||||
this.setAttribute("class", value)
|
||||
}
|
||||
|
||||
var Element.classSet : Set<String>
|
||||
get() {
|
||||
val answer = LinkedHashSet<String>()
|
||||
val array = this.classes.split("""\s""")
|
||||
for (s in array) {
|
||||
if (s != null && s.size > 0) {
|
||||
answer.add(s)
|
||||
}
|
||||
}
|
||||
return answer
|
||||
}
|
||||
set(value) {
|
||||
this.classes = value.join(" ")
|
||||
}
|
||||
|
||||
|
||||
// Helper methods
|
||||
|
||||
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
||||
fun Element.hasClass(cssClass: String): Boolean {
|
||||
val c = this.cssClass
|
||||
val c = this.classes
|
||||
return if (c != null)
|
||||
c.matches("""(^|\s+)$cssClass($|\s+)""")
|
||||
c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
||||
else false
|
||||
}
|
||||
|
||||
/** Adds the given CSS class to this element's 'class' attribute */
|
||||
fun Element.addClass(cssClass: String): Boolean {
|
||||
val classSet = this.classSet
|
||||
val answer = classSet.add(cssClass)
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Removes the given CSS class to this element's 'class' attribute */
|
||||
fun Element.removeClass(cssClass: String): Boolean {
|
||||
val classSet = this.classSet
|
||||
val answer = classSet.remove(cssClass)
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** TODO this approach generates compiler errors...
|
||||
|
||||
fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
||||
val set = this.classSet
|
||||
var answer = false
|
||||
for (cs in cssClasses) {
|
||||
if (set.add(cs)) {
|
||||
answer = true
|
||||
}
|
||||
}
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
||||
val set = this.classSet
|
||||
var answer = false
|
||||
for (cs in cssClasses) {
|
||||
if (set.remove(cs)) {
|
||||
answer = true
|
||||
}
|
||||
}
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
*/
|
||||
|
||||
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
||||
fun Document?.get(selector: String): List<Element> {
|
||||
val root = this?.getDocumentElement()
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.w3c.dom.*
|
||||
|
||||
class DomBuilderTest() : TestSupport() {
|
||||
|
||||
|
||||
fun testBuildDocument() {
|
||||
var doc = createDocument()
|
||||
|
||||
@@ -18,13 +19,20 @@ class DomBuilderTest() : TestSupport() {
|
||||
doc.addElement("foo") {
|
||||
id = "id1"
|
||||
style = "bold"
|
||||
cssClass = "bar"
|
||||
classes = "bar"
|
||||
addElement("child") {
|
||||
id = "id2"
|
||||
cssClass = "another"
|
||||
classes = "another"
|
||||
addElement("grandChild") {
|
||||
id = "id3"
|
||||
cssClass = "tiny"
|
||||
classes = " bar tiny"
|
||||
addText("Hello World!")
|
||||
// TODO support neater syntax sugar for adding text?
|
||||
// += "Hello World!"
|
||||
}
|
||||
addElement("grandChild2") {
|
||||
id = "id3"
|
||||
classes = "tiny thing bar "
|
||||
addText("Hello World!")
|
||||
// TODO support neater syntax sugar for adding text?
|
||||
// += "Hello World!"
|
||||
@@ -37,8 +45,8 @@ class DomBuilderTest() : TestSupport() {
|
||||
// test css selections on document
|
||||
assertEquals(0, doc[".doesNotExist"].size())
|
||||
assertEquals(1, doc[".another"].size())
|
||||
assertEquals(1, doc[".tiny"].size())
|
||||
assertEquals(1, doc[".bar"].size())
|
||||
assertEquals(3, doc[".bar"].size())
|
||||
assertEquals(2, doc[".tiny"].size())
|
||||
|
||||
// element tag selections
|
||||
assertEquals(0, doc["doesNotExist"].size())
|
||||
@@ -60,8 +68,8 @@ class DomBuilderTest() : TestSupport() {
|
||||
// test css selections on element
|
||||
assertEquals(0, root[".doesNotExist"].size())
|
||||
assertEquals(1, root[".another"].size())
|
||||
assertEquals(1, root[".tiny"].size())
|
||||
assertEquals(0, root[".bar"].size())
|
||||
assertEquals(2, root[".bar"].size())
|
||||
assertEquals(2, root[".tiny"].size())
|
||||
|
||||
// element tag selections
|
||||
assertEquals(0, root["doesNotExist"].size())
|
||||
@@ -77,12 +85,32 @@ class DomBuilderTest() : TestSupport() {
|
||||
fail("No root!")
|
||||
}
|
||||
|
||||
|
||||
val grandChild = doc["grandChild"].first
|
||||
if (grandChild != null) {
|
||||
println("got element ${grandChild.toXmlString()} with text '${grandChild.text}`")
|
||||
assertEquals("Hello World!", grandChild.text)
|
||||
assertEquals("tiny", grandChild.attribute("class") ?: "")
|
||||
assertEquals(" bar tiny", grandChild.attribute("class") ?: "")
|
||||
|
||||
// test the classSet
|
||||
val classSet = grandChild.classSet
|
||||
|
||||
assertTrue(classSet.contains("bar"))
|
||||
assertTrue(classSet.contains("tiny"))
|
||||
assertTrue(classSet.size == 2 )
|
||||
assertFalse(classSet.contains("doesNotExist"))
|
||||
|
||||
// lets add a new class and some existing classes
|
||||
grandChild.addClass("bar")
|
||||
grandChild.addClass("newThingy")
|
||||
assertEquals("bar tiny newThingy", grandChild.classes)
|
||||
|
||||
// remove
|
||||
grandChild.removeClass("bar")
|
||||
assertEquals("tiny newThingy", grandChild.classes)
|
||||
|
||||
grandChild.removeClass("tiny")
|
||||
assertEquals("newThingy", grandChild.classes)
|
||||
|
||||
} else {
|
||||
fail("Not an Element $grandChild")
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class DomTest() : TestSupport() {
|
||||
assertCssClass(e, "")
|
||||
|
||||
// now lets update the cssClass property
|
||||
e.cssClass = "foo"
|
||||
e.classes = "foo"
|
||||
assertCssClass(e, "foo")
|
||||
|
||||
// now using the attribute directly
|
||||
@@ -28,7 +28,7 @@ class DomTest() : TestSupport() {
|
||||
|
||||
|
||||
fun assertCssClass(e: Element, value: String?): Unit {
|
||||
val cl = e.cssClass
|
||||
val cl = e.classes
|
||||
val cl2 = e.getAttribute("class")
|
||||
println("element ${e.toXmlString()} has cssClass `${cl}` class attr `${cl2}`")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user