added first cut of the DOM events API (its not all compiling to JS yet though due to Class<T> not being supported)

This commit is contained in:
James Strachan
2012-07-24 11:10:50 +01:00
parent a3cbd37e5f
commit b25c27bfed
10 changed files with 249 additions and 21 deletions
+1 -5
View File
@@ -19,11 +19,7 @@
<entry name="?*.kt" />
<entry name="?*.template" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
<annotationProcessing enabled="false" useClasspath="true" />
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_STRING" value="-target 1.6" />
+2
View File
@@ -1,6 +1,8 @@
package org.w3c.dom
//
// NOTE THIS FILE IS AUTO-GENERATED by the GeneratedJavaScriptStubs.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
+85
View File
@@ -0,0 +1,85 @@
package org.w3c.dom.events
import org.w3c.dom.*
import org.w3c.dom.views.*
//
// NOTE THIS FILE IS AUTO-GENERATED by the GeneratedJavaScriptStubs.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
import js.noImpl
// Contains stub APIs for the W3C DOM API so we can delegate to the platform DOM instead
native public trait DocumentEvent {
public fun createEvent(arg1: String?): Event = js.noImpl
}
native public trait Event {
public val `type`: String
public val bubbles: Boolean
public val cancelable: Boolean
public val currentTarget: EventTarget
public val eventPhase: Short
public val target: EventTarget
public val timeStamp: Long
public fun stopPropagation(): Unit = js.noImpl
public fun preventDefault(): Unit = js.noImpl
public fun initEvent(arg1: String?, arg2: Boolean, arg3: Boolean): Unit = js.noImpl
public class object {
public val CAPTURING_PHASE: Short = 1
public val AT_TARGET: Short = 2
public val BUBBLING_PHASE: Short = 3
}
}
native public trait EventListener {
public fun handleEvent(arg1: Event): Unit = js.noImpl
}
native public trait EventTarget {
public fun dispatchEvent(arg1: Event): Boolean = js.noImpl
public fun addEventListener(arg1: String?, arg2: EventListener, arg3: Boolean): Unit = js.noImpl
public fun removeEventListener(arg1: String?, arg2: EventListener, arg3: Boolean): Unit = js.noImpl
}
native public trait MouseEvent: UIEvent {
public val altKey: Boolean
public val button: Short
public val clientX: Int
public val clientY: Int
public val ctrlKey: Boolean
public val metaKey: Boolean
public val relatedTarget: EventTarget
public val screenX: Int
public val screenY: Int
public val shiftKey: Boolean
public fun initMouseEvent(arg1: String?, arg2: Boolean, arg3: Boolean, arg4: AbstractView, arg5: Int, arg6: Int, arg7: Int, arg8: Int, arg9: Int, arg10: Boolean, arg11: Boolean, arg12: Boolean, arg13: Boolean, arg14: Short, arg15: EventTarget): Unit = js.noImpl
}
native public trait MutationEvent: Event {
public val attrChange: Short
public val attrName: String
public val newValue: String
public val prevValue: String
public val relatedNode: Node
public fun initMutationEvent(arg1: String?, arg2: Boolean, arg3: Boolean, arg4: Node, arg5: String?, arg6: String?, arg7: String?, arg8: Short): Unit = js.noImpl
public class object {
public val MODIFICATION: Short = 1
public val ADDITION: Short = 2
public val REMOVAL: Short = 3
}
}
native public trait UIEvent: Event {
public val detail: Int
public val view: AbstractView
public fun initUIEvent(arg1: String?, arg2: Boolean, arg3: Boolean, arg4: AbstractView, arg5: Int): Unit = js.noImpl
}
+7
View File
@@ -0,0 +1,7 @@
package org.w3c.dom.views
import js.noImpl
native public trait AbstractView {
}
@@ -0,0 +1,50 @@
package kotlin.dom
import org.w3c.dom.Document
import org.w3c.dom.Node
import org.w3c.dom.events.*
import java.io.Closeable
fun <T: Event> eventHandler(eventType: Class<T>, handler: (T) -> Unit): EventListener {
return object : EventListener {
public override fun handleEvent(e: Event?) {
if (e != null && eventType.isInstance(e)) {
handler(e as T)
}
}
}
}
/**
* Registers a handler on the named event
*/
public fun Node?.on(name: String, capture: Boolean, handler: (Event) -> Unit): Closeable? {
return on(name, capture, javaClass<Event>(), handler)
}
public fun <T: Event> Node?.on(name: String, capture: Boolean, eventType: Class<T>, handler: (T) -> Unit): Closeable? {
return if (this is EventTarget) {
val target: EventTarget = this
val listener = eventHandler(eventType, handler)
target.addEventListener(name, listener, capture)
object: Closeable {
public override fun close() {
target.removeEventListener(name, listener, capture)
}
public override fun toString(): String? = "CloseableEventListener($target, $name)"
}
} else {
null
}
}
public fun Node?.onClick(capture: Boolean = false, handler: (MouseEvent) -> Unit): Closeable? {
return on("click", capture, javaClass<MouseEvent>(), handler)
}
public fun Node?.onDoubleClick(capture: Boolean = false, handler: (MouseEvent) -> Unit): Closeable? {
return on("dblclick", capture, javaClass<MouseEvent>(), handler)
}
@@ -0,0 +1,58 @@
package kotlin.dom
import org.w3c.dom.Node
import org.w3c.dom.events.*
// JavaScript style properties for JVM : TODO could auto-generate these
val Event.bubbles: Boolean
get() = getBubbles()
val Event.cancelable: Boolean
get() = getCancelable()
val Event.getCurrentTarget: EventTarget?
get() = getCurrentTarget()
val Event.eventPhase: Short
get() = getEventPhase()
val Event.target: EventTarget?
get() = getTarget()
val Event.timeStamp: Long
get() = getTimeStamp()
// TODO we can't use 'type' as the property name in Kotlin so we should fix it in JS
val Event.eventType: String
get() = getType()!!
val MouseEvent.altKey: Boolean
get() = getAltKey()
val MouseEvent.button: Short
get() = getButton()
val MouseEvent.clientX: Int
get() = getClientX()
val MouseEvent.clientY: Int
get() = getClientY()
val MouseEvent.ctrlKey: Boolean
get() = getCtrlKey()
val MouseEvent.metaKey: Boolean
get() = getMetaKey()
val MouseEvent.relatedTarget: EventTarget?
get() = getRelatedTarget()
val MouseEvent.screenX: Int
get() = getScreenX()
val MouseEvent.screenY: Int
get() = getScreenY()
val MouseEvent.shiftKey: Boolean
get() = getShiftKey()
+2 -1
View File
@@ -1,5 +1,5 @@
/**
* JVM specific API implementations using JAXB and so forth which would not be used when compiling to JS
* JVM specific API implementations using JAXP and so forth which would not be used when compiling to JS
*/
package kotlin.dom
@@ -19,6 +19,7 @@ import javax.xml.transform.stream.StreamResult
import org.w3c.dom.*
import org.xml.sax.InputSource
// JavaScript style properties - TODO could auto-generate these
val Node.nodeName: String
get() = getNodeName() ?: ""
@@ -8,16 +8,55 @@ import java.lang.reflect.Modifier
import java.util.ArrayList
import java.util.TreeMap
import org.w3c.dom.*
import org.w3c.dom.events.*
import java.util.List
/**
* This tool generates JavaScript stubs for classes available in the JDK which are already available in the browser environment
* such as the W3C DOM
*/
fun generateDomAPI(file: File): Unit {
val packageName = "org.w3c.dom"
val imports = ""
val classes: List<Class<*>> = arrayList(javaClass<Attr>(), javaClass<CDATASection>(),
javaClass<CharacterData>(), javaClass<Comment>(),
javaClass<Document>(), javaClass<DocumentFragment>(), javaClass<DocumentType>(),
javaClass<DOMConfiguration>(),
javaClass<DOMError>(), javaClass<DOMErrorHandler>(),
javaClass<DOMImplementation>(), javaClass<DOMImplementationList>(),
javaClass<DOMLocator>(),
javaClass<DOMStringList>(),
javaClass<Element>(),
javaClass<Entity>(), javaClass<EntityReference>(),
javaClass<NameList>(), javaClass<NamedNodeMap>(), javaClass<Node>(), javaClass<NodeList>(),
javaClass<Notation>(), javaClass<ProcessingInstruction>(),
javaClass<Text>(), javaClass<TypeInfo>(),
javaClass<UserDataHandler>())
writeClassesFile(file, packageName, imports, classes)
}
fun generateDomEventsAPI(file: File): Unit {
val packageName = "org.w3c.dom.events"
val imports = "import org.w3c.dom.*\nimport org.w3c.dom.views.*\n"
val classes: List<Class<*>> = arrayList(javaClass<DocumentEvent>(), javaClass<Event>(),
javaClass<EventListener>(), javaClass<EventTarget>(),
javaClass<MouseEvent>(), javaClass<MutationEvent>(),
javaClass<UIEvent>())
writeClassesFile(file, packageName, imports, classes)
}
private fun writeClassesFile(file: File, packageName: String, imports: String, classes: List<Class<*>>): Unit {
write(file) {
println("""
package org.w3c.dom
package $packageName
$imports
//
// NOTE THIS FILE IS AUTO-GENERATED by the GeneratedJavaScriptStubs.kt
@@ -30,20 +69,6 @@ import js.noImpl
""")
val classes = arrayList(javaClass<Attr>(), javaClass<CDATASection>(),
javaClass<CharacterData>(), javaClass<Comment>(),
javaClass<Document>(), javaClass<DocumentFragment>(), javaClass<DocumentType>(),
javaClass<DOMConfiguration>(),
javaClass<DOMError>(), javaClass<DOMErrorHandler>(),
javaClass<DOMImplementation>(), javaClass<DOMImplementationList>(),
javaClass<DOMLocator>(),
javaClass<DOMStringList>(),
javaClass<Element>(),
javaClass<Entity>(), javaClass<EntityReference>(),
javaClass<NameList>(), javaClass<NamedNodeMap>(), javaClass<Node>(), javaClass<NodeList>(),
javaClass<Notation>(), javaClass<ProcessingInstruction>(),
javaClass<Text>(), javaClass<TypeInfo>(),
javaClass<UserDataHandler>())
fun simpleTypeName(klass: Class<out Any?>?): String {
val answer = klass?.getSimpleName()?.capitalize() ?: "Unit"
@@ -69,6 +69,7 @@ fun main(args: Array<String>) {
val jsCoreDir = File(srcDir, "../../../../js/js.libraries/src/core")
require(jsCoreDir.exists())
generateDomAPI(File(jsCoreDir, "dom.kt"))
generateDomEventsAPI(File(jsCoreDir, "domEvents.kt"))
val otherArrayNames = arrayList("Boolean", "Byte", "Char", "Short", "Int", "Long", "Float", "Double")
@@ -44,6 +44,9 @@
<fileset dir="${basedir}/../../stdlib/src/kotlin/dom">
<include name="**/*.kt"/>
<exclude name="**/*JVM.kt"/>
<!-- TODO get compiling ASAP when we can use Class<T> in JavaScript -->
<exclude name="**/DomEvents.kt"/>
</fileset>
<fileset dir="${basedir}/../../stdlib/src/kotlin/support">
<include name="**/*.kt"/>