From cb6a65e26333804969b34debd1a7850a3fcb557b Mon Sep 17 00:00:00 2001 From: James Strachan Date: Thu, 24 May 2012 11:49:21 +0100 Subject: [PATCH] refactored the KoolApp JavaFX browser so its generic and reusable; using a + +when opening in the HTML in the KoolApp JavaFX browser (running the org.koolapp.javafx.namespace class as a Java main() function) + + java org.koolapp.javafx.namespace file://foo.html + +The browser will startup, load the HTML and then when it sees the text/kotlin script it will invoke your function; once the document has loaded (and the kotlin.browser.document property is updated). + +The same Kotlin code should then work if the code is compiled to JavaScript. The only change is required is that the script tag with text/kotlin needs to be replaced with the actual JavaScript file; this could be done dynamically on the server or as part of your build process. diff --git a/koolapp-javafx/pom.xml b/koolapp-javafx/pom.xml index 56dcd59..e87e1c1 100644 --- a/koolapp-javafx/pom.xml +++ b/koolapp-javafx/pom.xml @@ -72,7 +72,9 @@ test - + + + diff --git a/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/Main.kt b/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/Main.kt new file mode 100644 index 0000000..c8deece --- /dev/null +++ b/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/Main.kt @@ -0,0 +1,12 @@ +package org.koolapp.javafx + +import javafx.application.Application + +/** + * A command line application which starts the JavaFX browser and boots up + * the application defined by the first URL parameter. + */ +fun main(args: Array): Unit { + println("Starting KoolApp browser: http://koolapp.org/ - pleasae keep kool!") + Application.launch(javaClass(), args.makeString(" ")) +} \ No newline at end of file diff --git a/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/WebApplication.kt b/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/WebApplication.kt index 46848c4..0b8cb43 100644 --- a/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/WebApplication.kt +++ b/koolapp-javafx/src/main/kotlin/org/koolapp/javafx/WebApplication.kt @@ -4,6 +4,7 @@ import java.io.File import javafx.application.Application import javafx.beans.value.ChangeListener import javafx.beans.value.ObservableValue +import javafx.concurrent.Worker.State import javafx.event.ActionEvent import javafx.event.EventHandler import javafx.geometry.HPos @@ -17,8 +18,9 @@ import javafx.scene.layout.Priority import javafx.scene.web.WebEngine import javafx.scene.web.WebView import javafx.stage.Stage +import kotlin.browser.* +import kotlin.dom.* import org.w3c.dom.Document -import javafx.concurrent.Worker.State /** * An [[Application]] which uses a [[WebView]] and [[WebEngine]] @@ -27,10 +29,10 @@ public open class WebApplication(): Application() { private var _engine: WebEngine? = null var engine: WebEngine - get() = _engine!! - set(value) { - _engine = value - } + get() = _engine!! + set(value) { + _engine = value + } var prefWidth = 800.0 var prefHeight = 600.0 @@ -42,9 +44,9 @@ public open class WebApplication(): Application() { val changeListener = object : ChangeListener { public override fun changed(observable: ObservableValue?, oldValue: State?, newValue: State?) { if (newValue != null && newValue == State.SUCCEEDED) { - val document = engine.getDocument() - if (document != null) { - block(document) + val doc = engine.getDocument() + if (doc != null) { + block(doc) } if (fireOnce) { engine.getLoadWorker()?.stateProperty()?.removeListener(this) @@ -63,6 +65,11 @@ public open class WebApplication(): Application() { view.setPrefSize(prefWidth, prefHeight) view.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); + ready { + // lets register the global DOM instance + document = it + loadKotlinScripts(it) + } val initialLocation = loadInitial() val locationField = TextField(initialLocation) @@ -120,7 +127,17 @@ public open class WebApplication(): Application() { * so it can be populated into the address bar */ protected open fun loadInitial(): String { - return load("http://koolapp.org/") + val parameters = getParameters()!! + val unnamed = parameters.getUnnamed()!! + val raw = parameters.getRaw()!! + val url = if (unnamed.notEmpty()) { + unnamed.first()!! + } else if (raw.notEmpty()) { + raw.first()!! + } else { + "http://koolapp.org/" + } + return load(url) } /** @@ -139,5 +156,43 @@ public open class WebApplication(): Application() { } return url } + + /** + * Attempts to find any <script> tags for the type *text/kotlin* and invokes the methods + */ + protected fun loadKotlinScripts(document: Document): Unit { + val scriptTags = document["script"] + for (scriptTag in scriptTags) { + val t = scriptTag.attribute("type") + if (t == "text/kotlin") { + val text = scriptTag.text.trim() + val lines = text.split("\n") + for (line in lines) { + val initCall = line.trim().trimTrailing("()") + if (initCall.notEmpty()) { + val idx = initCall.lastIndexOf('.') + if (idx <= 0) { + println("Warning cannot invoke initCall which is not on a class $initCall") + } else { + try { + val className = initCall.substring(0, idx) + val methodName = initCall.substring(idx + 1) + val klass = loadClass(className) + val method = klass.getMethod(methodName)!! + method.invoke(null) + } catch (e: Exception) { + println("Failed to invoke startup method: " + initCall + ". Reason: " + e) + e.printStackTrace() + } + } + } + } + } + } + } + + protected fun loadClass(className: String): Class { + return Class.forName(className) as Class + } } diff --git a/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/Main.kt b/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/Main.kt deleted file mode 100644 index 5f824e8..0000000 --- a/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/Main.kt +++ /dev/null @@ -1,8 +0,0 @@ -package test.koolapp.javafx - -import javafx.application.Application - -fun main(args: Array): Unit { - println("Hello world!") - Application.launch(javaClass) -} \ No newline at end of file diff --git a/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/SampleWebApp.kt b/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/SampleWebApp.kt index 2dd188e..f4bd58c 100644 --- a/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/SampleWebApp.kt +++ b/koolapp-javafx/src/test/kotlin/test/koolapp/javafx/SampleWebApp.kt @@ -6,9 +6,13 @@ import test.koolapp.myapp.myApp public class SampleWebApp(): WebApplication() { override fun loadInitial(): String { + /* + This is another way of registering an application on a page instead of using the

Sample

+

This example HTML was loaded from a local file!

+ +

Should have generated stuff above...

+ \ No newline at end of file