diff --git a/runtests/test/stdlib/testall/DomTestAllTest.java b/runtests/test/stdlib/testall/DomTestAllTest.java index 67eb5826707..02e51b2ca8a 100644 --- a/runtests/test/stdlib/testall/DomTestAllTest.java +++ b/runtests/test/stdlib/testall/DomTestAllTest.java @@ -7,6 +7,6 @@ import test.dom.*; */ public class DomTestAllTest { public static TestSuite suite() { - return new TestSuite(DomTest.class); + return new TestSuite(DomBuilderTest.class, DomTest.class); } } diff --git a/stdlib/ktSrc/dom/Dom.kt b/stdlib/ktSrc/dom/Dom.kt index 9087c182234..5497b8cbdc0 100644 --- a/stdlib/ktSrc/dom/Dom.kt +++ b/stdlib/ktSrc/dom/Dom.kt @@ -1,9 +1,8 @@ package std.dom +import std.* import org.w3c.dom.* -import javax.xml.parsers.DocumentBuilder -import javax.xml.parsers.DocumentBuilderFactory -import std.getOrElse + // Properties @@ -19,6 +18,7 @@ set(value) { this.setAttribute("style", value) } +// TODO can we come up with a better name; 'class' is a reserved word? var Element.cssClass : String get() = this.getAttribute("class").getOrElse("") set(value) { @@ -32,4 +32,64 @@ inline fun Node.plus(child: Node?): Node { this.appendChild(child) } return this -} \ No newline at end of file +} + + +// Builder + +/* +Creates a new element which can be configured via a function +*/ +fun Document.createElement(name: String, init: Element.()-> Unit): Element { + val elem = this.createElement(name).sure() + elem.init() + return elem +} + +/* +Creates a new element to an element which has an owner Document which can be configured via a function +*/ +fun Element.createElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element { + val elem = ownerDocument(doc).createElement(name).sure() + elem.init() + return elem +} + +/* +Returns the owner document of the element or uses the provided document +*/ +fun Element.ownerDocument(doc: Document? = null): Document { + val answer = if (doc == null) this.getOwnerDocument() else doc + if (answer == null) { + throw IllegalArgumentException("Element does not have an ownerDocument and none was provided for: ${this}") + } else { + return answer + } +} + +/* +Adds a newly created element which can be configured via a function +*/ +fun Document.addElement(name: String, init: Element.()-> Unit): Element { + val child = createElement(name, init) + this.appendChild(child) + return child +} + +/* +Adds a newly created element to an element which has an owner Document which can be configured via a function +*/ +fun Element.addElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element { + val child = createElement(name, doc, init) + this.appendChild(child) + return child +} + +/* +Adds a newly created text node to an element which either already has an owner Document or one must be provided as a parameter +*/ +fun Element.addText(text: String, doc: Document? = null): Element { + val child = ownerDocument(doc).createTextNode(text) + this.appendChild(child) + return this +} diff --git a/testlib/test/dom/DomBuilderTest.kt b/testlib/test/dom/DomBuilderTest.kt new file mode 100644 index 00000000000..647852336ea --- /dev/null +++ b/testlib/test/dom/DomBuilderTest.kt @@ -0,0 +1,27 @@ +package test.dom + +import std.* +import std.dom.* +import stdhack.test.* +import org.w3c.dom.* + +class DomBuilderTest() : TestSupport() { + + fun testBuildDocumnet() { + var doc = createDocument() + + doc.addElement("foo") { + id = "id1" + style = "bold" + cssClass = "bar" + addElement("child") { + cssClass = "another" + addElement("grandChild") { + cssClass = "tiny" + addText("Hello World!") + } + } + } + println("builder document: ${doc.toXmlString()}") + } +}