diff options
-rw-r--r-- | package.scala | 18 | ||||
-rw-r--r-- | readme.md | 7 | ||||
-rw-r--r-- | workbench_template.ts | 24 |
3 files changed, 33 insertions, 16 deletions
diff --git a/package.scala b/package.scala index 0e0e7be..2e42673 100644 --- a/package.scala +++ b/package.scala @@ -27,7 +27,7 @@ package object workbench extends sbt.Plugin { val localUrl = settingKey[(String, Int)]("localUrl") val server = settingKey[ActorRef]("local websocket server") val fileName = settingKey[String]("name of the generated javascript file") - val bootstrapSnippet = settingKey[String]("piece of javascript to make things happen") + val bootSnippet = settingKey[String]("piece of javascript to make things happen") implicit val system = ActorSystem( "SystemLol", config = ConfigFactory.load(ActorSystem.getClass.getClassLoader), @@ -47,7 +47,7 @@ package object workbench extends sbt.Plugin { localUrl := ("localhost", 12345), fileName := "workbench.js", server := { - implicit val server = system.actorOf(Props(new SocketServer(bootstrapSnippet.value))) + implicit val server = system.actorOf(Props(new SocketServer())) val host = localUrl.value io.IO(Sockets) ! Http.Bind(server, host._1, host._2) server @@ -76,14 +76,18 @@ package object workbench extends sbt.Plugin { println("Checking " + x.getName) FileFunction.cached(streams.value.cacheDirectory / x.getName, FilesInfo.lastModified, FilesInfo.lastModified){ (f: Set[File]) => println("Refreshing " + x.getName) - server.value send Json.arr("run", f.head.getAbsolutePath, bootstrapSnippet.value) + server.value send Json.arr("run", f.head.getAbsolutePath, bootSnippet.value) f }(Set(x)) } }, generateClient := { - FileFunction.cached(streams.value.cacheDirectory / "workbench"/ "workbench.js", FilesInfo.full, FilesInfo.full){ (f: Set[File]) => - val transformed = IO.read(f.head).replace("<host>", localUrl.value._1).replace("<port>", localUrl.value._2.toString) + FileFunction.cached(streams.value.cacheDirectory / "workbench"/ "workbench.js", FilesInfo.full, FilesInfo.exists){ (f: Set[File]) => + val transformed = + IO.read(f.head) + .replace("<host>", localUrl.value._1) + .replace("<port>", localUrl.value._2.toString) + .replace("<bootSnippet>", bootSnippet.value) val outputFile = (crossTarget in Compile).value / fileName.value IO.write(outputFile, transformed) Set(outputFile) @@ -91,7 +95,7 @@ package object workbench extends sbt.Plugin { } ) - class SocketServer(bootstrapSnippet: String) extends Actor{ + class SocketServer() extends Actor{ val sockets: mutable.Set[ActorRef] = mutable.Set.empty def receive = { case x: Tcp.Connected => sender ! Tcp.Register(self) // normal Http server init @@ -111,7 +115,7 @@ package object workbench extends sbt.Plugin { case Sockets.Upgraded => sockets.add(sender) println("Browser Open n=" + sockets.size) - self send Json.arr("eval", bootstrapSnippet) + self send Json.arr("boot") case f @ Frame(fin, rsv, Text, maskingKey, data) => sockets.foreach(_ ! f.copy(maskingKey=None)) @@ -24,7 +24,7 @@ packageJS in Compile := { } ``` -- Define your `bootstrapSnippet`, which is a piece of javascript to be run to start your application, e.g. `bootstrapSnippet := "ScalaJS.modules.example_ScalaJSExample().main();"`. scala-js-workbench requires this so it can use it to re-start your application later on its own. You do not also need to include this on the page itself, as scala-js-workbench will execute this snippet when the browser first connects. +- Define your `bootSnippet`, which is a piece of javascript to be run to start your application, e.g. `bootSnippet := "ScalaJS.modules.example_ScalaJSExample().main();"`. scala-js-workbench requires this so it can use it to re-start your application later on its own. You do not also need to include this on the page itself, as scala-js-workbench will execute this snippet when the browser first connects. Now you have a choice of what you want to do when the code compiles: @@ -42,7 +42,8 @@ This will attempt to perform an update without refreshing the page every time `p - Returning the state of `document.body` to the initial state before any javascript was run - Stripping all event listeners from things within body -- Clearing all repeated timeouts and intervals. +- Clearing all repeated timeouts and intervals +- Running the `bootSnippet` again `updateBrowsers` is a best-effort cleanup, and does not do things like: @@ -52,6 +53,8 @@ This will attempt to perform an update without refreshing the page every time `p Nonetheless, for the bulk of javascript libraries these limitations are acceptable. As long as you're not doing anything too crazy, `updateBrowsers` but should suffice for most applications. +You can force the clean-up-and-reboot to happen from the browser via the shortcut Ctrl-Alt-Shift-Enter if you simply wish to reset the browser to a clean state. + ------- With that done, when you open a HTML page containing `workbench.js`, if you have sbt running and scala-js-workbench enabled, it should connect over websockets and start forwarding our SBT log to the browser javascript console. You can now run the `refreshBrowsers` and `updateBrowsers` commands to tell it to refresh itself, and if you set up the `triggeredBy` rule as shown above, it should refresh/update itself automatically at the end of every `packageJS` cycle. diff --git a/workbench_template.ts b/workbench_template.ts index 729b498..7e49bab 100644 --- a/workbench_template.ts +++ b/workbench_template.ts @@ -1,9 +1,23 @@ var socket = (function(){ var open = false var shadowBody = null + var bootSnippet = "<bootSnippet>" window.onload = function(){ shadowBody = document.body.cloneNode() } + window.addEventListener("keydown", function (event) { + if(event.keyCode==13 && event.ctrlKey && event.altKey && event.shiftKey) { + clear() + eval(bootSnippet) + } + }) + function clear(){ + document.body = shadowBody.cloneNode() + for(var i = 0; i < 99999; i++){ + clearTimeout(i) + clearInterval(i) + } + } var start = function(){ socket = new WebSocket("ws://<host>:<port>/") @@ -19,11 +33,7 @@ var socket = (function(){ location.reload() } if (data[0] == "clear"){ - document.body = shadowBody.cloneNode() - for(var i = 0; i < 99999; i++){ - clearTimeout(i) - clearInterval(i) - } + clear() } if (data[0] == "run"){ var tag = document.createElement("script") @@ -38,8 +48,8 @@ var socket = (function(){ } document.head.appendChild(tag) } - if (data[0] == "eval"){ - eval(data[1]) + if (data[0] == "boot"){ + eval(bootSnippet) } if (data[0] == "print") console[data[1]](data[2]) } |