JS fix stdlib API to conform to new DOM3
This commit is contained in:
committed by
Sergey Mashkov
parent
374dcd56f2
commit
4bc91ba652
@@ -42,122 +42,4 @@ private class HTMLCollectionListView(val collection: HTMLCollection) : AbstractL
|
|||||||
|
|
||||||
public fun HTMLCollection.asList(): List<HTMLElement> = HTMLCollectionListView(this)
|
public fun HTMLCollection.asList(): List<HTMLElement> = HTMLCollectionListView(this)
|
||||||
|
|
||||||
private class NodeListAsList(val delegate: NodeList) : AbstractList<Node>() {
|
public fun HTMLCollection?.toElementList() : List<Element> = this?.asList() ?: emptyList()
|
||||||
override fun size(): Int = delegate.length
|
|
||||||
|
|
||||||
override fun get(index: Int): Node =
|
|
||||||
if (index in 0..size() - 1) delegate.get(index)!!
|
|
||||||
else throw IndexOutOfBoundsException("index $index is not in range [0 .. ${size() - 1})")
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun NodeList.asList() : List<Node> = NodeListAsList(this)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds CSS class to element. Has no effect if all specified classes are already in class attribute of the element
|
|
||||||
*/
|
|
||||||
public fun Element.addClass(vararg cssClasses: String): Boolean {
|
|
||||||
val missingClasses = cssClasses.filterNot { hasClass(it) }
|
|
||||||
if (missingClasses.isNotEmpty()) {
|
|
||||||
className = StringBuilder {
|
|
||||||
append(className)
|
|
||||||
missingClasses.joinTo(this, " ", " ")
|
|
||||||
}.toString()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all [cssClasses] from element. Has no effect if all specified classes are missing in class attribute of the element
|
|
||||||
*/
|
|
||||||
public fun Element.removeClass(vararg cssClasses: String): Boolean {
|
|
||||||
if (cssClasses.any { hasClass(it) }) {
|
|
||||||
val toBeRemoved = cssClasses.toSet()
|
|
||||||
className = className.splitWithRegex("\\s+").filter { it !in toBeRemoved }.joinToString(" ")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds [cssClasses] to element if []condition] is true or removes it otherwise.
|
|
||||||
* Has no effect if class attribute already has corresponding content
|
|
||||||
*/
|
|
||||||
public fun Element.addOrRemoveClassWhen(condition : Boolean, vararg cssClasses : String) {
|
|
||||||
if (condition) {
|
|
||||||
addClass(*cssClasses)
|
|
||||||
} else {
|
|
||||||
removeClass(*cssClasses)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds [trueClassName] class to element if [condition] is true and removes [falseClassName].
|
|
||||||
* If [condition] is false then [trueClassName] will be removed and [falseClassName] will be added.
|
|
||||||
* Has no effect if class attribute already has corresponding content
|
|
||||||
*/
|
|
||||||
public fun Element.swapClassWhen(condition: Boolean, trueClassName: String, falseClassName: String) {
|
|
||||||
if (condition) {
|
|
||||||
addClass(trueClassName)
|
|
||||||
removeClass(falseClassName)
|
|
||||||
} else {
|
|
||||||
removeClass(trueClassName)
|
|
||||||
addClass(falseClassName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If [condition] is true then [attributeName] with value [attributeValue] will be added to the element, otherwise attribute with
|
|
||||||
* name [attributeName] will be removed
|
|
||||||
*/
|
|
||||||
public fun Element.addOrRemoveAttributeWhen(condition : Boolean, attributeName : String, attributeValue : String = attributeName) {
|
|
||||||
if (condition) {
|
|
||||||
setAttribute(attributeName, attributeValue)
|
|
||||||
} else {
|
|
||||||
removeAttribute(attributeName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
|
||||||
public fun Element.hasClass(cssClass: String): Boolean {
|
|
||||||
val c = this.className
|
|
||||||
return c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all child nodes
|
|
||||||
*/
|
|
||||||
public fun Node.clear() {
|
|
||||||
while (hasChildNodes()) {
|
|
||||||
removeChild(firstChild!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes this node from parent node. Does nothing if no parent node
|
|
||||||
*/
|
|
||||||
public fun Node.removeFromParent() {
|
|
||||||
parentNode?.removeChild(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* it is *true* when [Node.nodeType] is TEXT_NODE or CDATA_SECTION_NODE
|
|
||||||
*/
|
|
||||||
public val Node.isText : Boolean
|
|
||||||
get() = nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates text node and append it to the element
|
|
||||||
*/
|
|
||||||
public fun Element.appendText(text : String, doc : Document = this.ownerDocument!!) {
|
|
||||||
appendChild(doc.createTextNode(text))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends the node to the specified parent element
|
|
||||||
*/
|
|
||||||
public fun Node.appendTo(parent : Element) {
|
|
||||||
parent.appendChild(this)
|
|
||||||
}
|
|
||||||
@@ -188,40 +188,22 @@ public native trait HTMLOptionsCollection {
|
|||||||
|
|
||||||
deprecated("Use org.w3c.dom instead")
|
deprecated("Use org.w3c.dom instead")
|
||||||
public native trait HTMLDocument : Document {
|
public native trait HTMLDocument : Document {
|
||||||
public native var title: String
|
|
||||||
public native val referrer: String
|
|
||||||
public native val domain: String
|
|
||||||
public native val URL: String
|
|
||||||
public native var body: HTMLElement
|
|
||||||
public native val images: HTMLCollection
|
|
||||||
public native val applets: HTMLCollection
|
|
||||||
public native val links: HTMLCollection
|
|
||||||
public native val forms: HTMLCollection
|
|
||||||
public native val anchors: HTMLCollection
|
|
||||||
public native var cookie: HTMLCollection
|
|
||||||
public native fun open(): Unit
|
public native fun open(): Unit
|
||||||
public native fun close(): Unit
|
|
||||||
public native fun write(text: String): Unit
|
public native fun write(text: String): Unit
|
||||||
public native fun writeln(text: String): Unit
|
public native fun writeln(text: String): Unit
|
||||||
public native fun getElementsByName(elementName: String): NodeList
|
|
||||||
public native var compatMode: String
|
|
||||||
public native var onload: () -> Unit
|
|
||||||
public native var onunload: () -> Unit
|
public native var onunload: () -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated("Use org.w3c.dom instead")
|
deprecated("Use org.w3c.dom instead")
|
||||||
public native trait HTMLElement : Element {
|
public native trait HTMLElement : Element {
|
||||||
public native var id: String
|
|
||||||
public native var title: String
|
public native var title: String
|
||||||
public native var lang: String
|
public native var lang: String
|
||||||
public native var dir: String
|
public native var dir: String
|
||||||
public native var className: String
|
|
||||||
public native var style: CSSStyleDeclaration
|
public native var style: CSSStyleDeclaration
|
||||||
public native var clientWidth: Double
|
public native var clientWidth: Double
|
||||||
public native var clientHeight: Double
|
public native var clientHeight: Double
|
||||||
public native var clientTop: Double
|
public native var clientTop: Double
|
||||||
public native var clientLeft: Double
|
public native var clientLeft: Double
|
||||||
public native var innerHTML: String
|
|
||||||
public native var offsetWidth: Double
|
public native var offsetWidth: Double
|
||||||
public native var offsetHeight: Double
|
public native var offsetHeight: Double
|
||||||
public native var offsetTop: Double
|
public native var offsetTop: Double
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
package kotlin.js.dom.html5
|
package kotlin.js.dom.html5
|
||||||
|
|
||||||
native
|
native
|
||||||
public val localStorage: org.w3c.dom3.Storage = noImpl
|
public val localStorage: org.w3c.dom.Storage = noImpl
|
||||||
|
|
||||||
native
|
native
|
||||||
public val sessionStorage: org.w3c.dom3.Storage = noImpl
|
public val sessionStorage: org.w3c.dom.Storage = noImpl
|
||||||
|
|
||||||
native
|
native
|
||||||
deprecated("Use org.w3c.dom")
|
deprecated("Use org.w3c.dom")
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ import org.w3c.dom.Document
|
|||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
|
|
||||||
deprecated("use org.w3c.dom instead: create document directly via constructor Document() or use document.implementation.createDocument")
|
deprecated("use org.w3c.dom instead: create document directly via constructor Document() or use document.implementation.createDocument")
|
||||||
public fun createDocument(): Document {
|
public fun createDocument(): Document = Document()
|
||||||
return kotlin.js.dom.html.document.implementation.createDocument(null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
deprecated("use org.w3c.dom instead")
|
deprecated("use org.w3c.dom instead")
|
||||||
native public val Node.outerHTML: String get() = noImpl
|
native public val Node.outerHTML: String get() = noImpl
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ import java.lang.IndexOutOfBoundsException
|
|||||||
|
|
||||||
deprecated("use textContent directly instead")
|
deprecated("use textContent directly instead")
|
||||||
public var Node.text: String
|
public var Node.text: String
|
||||||
get() {
|
get() = textContent ?: ""
|
||||||
return textContent
|
|
||||||
}
|
|
||||||
set(value) {
|
set(value) {
|
||||||
textContent = value
|
textContent = value
|
||||||
}
|
}
|
||||||
@@ -52,7 +50,6 @@ public var Element.id: String
|
|||||||
get() = this.getAttribute("id") ?: ""
|
get() = this.getAttribute("id") ?: ""
|
||||||
set(value) {
|
set(value) {
|
||||||
this.setAttribute("id", value)
|
this.setAttribute("id", value)
|
||||||
this.setIdAttribute("id", true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var Element.style: String
|
public var Element.style: String
|
||||||
@@ -68,10 +65,7 @@ public var Element.classes: String
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
||||||
public fun Element.hasClass(cssClass: String): Boolean {
|
public fun Element.hasClass(cssClass: String): Boolean = classes.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
||||||
val c = this.classes
|
|
||||||
return c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns the children of the element as a list */
|
/** Returns the children of the element as a list */
|
||||||
@@ -118,15 +112,9 @@ public fun Document?.elements(namespaceUri: String, localName: String): List<Ele
|
|||||||
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun NodeList?.toList(): List<Node> {
|
public fun NodeList?.asList() : List<Node> = if (this == null) emptyList() else NodeListAsList(this)
|
||||||
return if (this == null) {
|
deprecated("use asList instead")
|
||||||
// TODO the following is easier to convert to JS
|
public fun NodeList?.toList(): List<Node> = asList()
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NodeListAsList(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun NodeList?.toElementList(): List<Element> {
|
public fun NodeList?.toElementList(): List<Element> {
|
||||||
return if (this == null) {
|
return if (this == null) {
|
||||||
@@ -184,48 +172,95 @@ public fun Element.get(selector: String): List<Element> {
|
|||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
|
|
||||||
/** TODO this approach generates compiler errors...
|
|
||||||
|
|
||||||
fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
/**
|
||||||
val set = this.classSet
|
* Adds CSS class to element. Has no effect if all specified classes are already in class attribute of the element
|
||||||
var answer = false
|
*/
|
||||||
for (cs in cssClasses) {
|
public fun Element.addClass(vararg cssClasses: String): Boolean {
|
||||||
if (set.add(cs)) {
|
val missingClasses = cssClasses.filterNot { hasClass(it) }
|
||||||
answer = true
|
if (missingClasses.isNotEmpty()) {
|
||||||
}
|
classes = StringBuilder {
|
||||||
|
append(classes)
|
||||||
|
missingClasses.joinTo(this, " ", " ")
|
||||||
|
}.toString()
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (answer) {
|
|
||||||
this.classSet = classSet
|
return false
|
||||||
}
|
|
||||||
return answer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
/**
|
||||||
val set = this.classSet
|
* Removes all [cssClasses] from element. Has no effect if all specified classes are missing in class attribute of the element
|
||||||
var answer = false
|
*/
|
||||||
for (cs in cssClasses) {
|
public fun Element.removeClass(vararg cssClasses: String): Boolean {
|
||||||
if (set.remove(cs)) {
|
if (cssClasses.any { hasClass(it) }) {
|
||||||
answer = true
|
val toBeRemoved = cssClasses.toSet()
|
||||||
}
|
classes = classes.split("\\s+").filter { it !in toBeRemoved }.joinToString(" ")
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (answer) {
|
|
||||||
this.classSet = classSet
|
return false
|
||||||
}
|
|
||||||
return answer
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
private class NodeListAsList(private val nodeList: NodeList) : AbstractList<Node>() {
|
/**
|
||||||
override fun get(index: Int): Node {
|
* Adds [cssClasses] to element if []condition] is true or removes it otherwise.
|
||||||
val node = nodeList.item(index)
|
* Has no effect if class attribute already has corresponding content
|
||||||
if (node == null) {
|
*/
|
||||||
throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index)
|
public fun Element.addOrRemoveClassWhen(condition : Boolean, vararg cssClasses : String) {
|
||||||
} else {
|
if (condition) {
|
||||||
return node
|
addClass(*cssClasses)
|
||||||
}
|
} else {
|
||||||
|
removeClass(*cssClasses)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun size(): Int = nodeList.length
|
/**
|
||||||
|
* Adds [trueClassName] class to element if [condition] is true and removes [falseClassName].
|
||||||
|
* If [condition] is false then [trueClassName] will be removed and [falseClassName] will be added.
|
||||||
|
* Has no effect if class attribute already has corresponding content
|
||||||
|
*/
|
||||||
|
public fun Element.swapClassWhen(condition: Boolean, trueClassName: String, falseClassName: String) {
|
||||||
|
if (condition) {
|
||||||
|
addClass(trueClassName)
|
||||||
|
removeClass(falseClassName)
|
||||||
|
} else {
|
||||||
|
removeClass(trueClassName)
|
||||||
|
addClass(falseClassName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If [condition] is true then [attributeName] with value [attributeValue] will be added to the element, otherwise attribute with
|
||||||
|
* name [attributeName] will be removed
|
||||||
|
*/
|
||||||
|
public fun Element.addOrRemoveAttributeWhen(condition : Boolean, attributeName : String, attributeValue : String = attributeName) {
|
||||||
|
if (condition) {
|
||||||
|
setAttribute(attributeName, attributeValue)
|
||||||
|
} else {
|
||||||
|
removeAttribute(attributeName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes all the children from this node */
|
||||||
|
public fun Node.clear() {
|
||||||
|
while (hasChildNodes()) {
|
||||||
|
removeChild(firstChild!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes this node from parent node. Does nothing if no parent node
|
||||||
|
*/
|
||||||
|
public fun Node.removeFromParent() {
|
||||||
|
parentNode?.removeChild(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NodeListAsList(val delegate: NodeList) : AbstractList<Node>() {
|
||||||
|
override fun size(): Int = delegate.length
|
||||||
|
|
||||||
|
override fun get(index: Int): Node =
|
||||||
|
if (index in 0..size() - 1) delegate.item(index)!!
|
||||||
|
else throw IndexOutOfBoundsException("index $index is not in range [0 .. ${size() - 1})")
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ElementListAsList(private val nodeList: NodeList) : AbstractList<Element>() {
|
private class ElementListAsList(private val nodeList: NodeList) : AbstractList<Element>() {
|
||||||
@@ -244,18 +279,6 @@ private class ElementListAsList(private val nodeList: NodeList) : AbstractList<E
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes all the children from this node */
|
|
||||||
public fun Node.clear(): Unit {
|
|
||||||
while (true) {
|
|
||||||
val child = firstChild
|
|
||||||
if (child == null) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
removeChild(child)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns an [[Iterator]] over the next siblings of this node */
|
/** Returns an [[Iterator]] over the next siblings of this node */
|
||||||
public fun Node.nextSiblings(): Iterable<Node> = NextSiblings(this)
|
public fun Node.nextSiblings(): Iterable<Node> = NextSiblings(this)
|
||||||
|
|
||||||
@@ -291,10 +314,15 @@ private class PreviousSiblings(private var node: Node) : Iterable<Node> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if this node is a Text node or a CDATA node */
|
/** Returns true if this node is a Text node or a CDATA node */
|
||||||
public fun Node.isText(): Boolean {
|
deprecated("use property isText instead")
|
||||||
val nt = nodeType
|
public fun Node.isText() : Boolean = nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
|
||||||
return nt == Node.TEXT_NODE || nt == Node.CDATA_SECTION_NODE
|
|
||||||
}
|
/**
|
||||||
|
* it is *true* when [Node.nodeType] is TEXT_NODE or CDATA_SECTION_NODE
|
||||||
|
*/
|
||||||
|
public val Node.isText : Boolean
|
||||||
|
get() = nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
|
||||||
|
|
||||||
|
|
||||||
/** Returns the attribute value or empty string if its not present */
|
/** Returns the attribute value or empty string if its not present */
|
||||||
public fun Element.attribute(name: String): String {
|
public fun Element.attribute(name: String): String {
|
||||||
@@ -411,3 +439,17 @@ public fun Element.addText(text: String?, doc: Document? = null): Element {
|
|||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates text node and append it to the element
|
||||||
|
*/
|
||||||
|
public fun Element.appendText(text : String, doc : Document = this.ownerDocument!!) {
|
||||||
|
appendChild(doc.createTextNode(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the node to the specified parent element
|
||||||
|
*/
|
||||||
|
public fun Node.appendTo(parent : Element) {
|
||||||
|
parent.appendChild(this)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user