diff options
author | Jakob Odersky <jakob@odersky.com> | 2016-11-08 00:01:24 -0800 |
---|---|---|
committer | Jakob Odersky <jakob@odersky.com> | 2016-11-08 16:52:27 -0800 |
commit | 137aac4781e3da76c7f1631999e70309ed09ce2f (patch) | |
tree | 2a04db27e324d8126390e53acff5d813a186a438 /src/main/scala/workbench/WorkbenchSplicePlugin.scala | |
parent | 71e5666ceeab0db8bb69c3bfcd2ddef5ab982029 (diff) | |
download | workbench-137aac4781e3da76c7f1631999e70309ed09ce2f.tar.gz workbench-137aac4781e3da76c7f1631999e70309ed09ce2f.tar.bz2 workbench-137aac4781e3da76c7f1631999e70309ed09ce2f.zip |
Separate splicing and refresh into separate plugins
Diffstat (limited to 'src/main/scala/workbench/WorkbenchSplicePlugin.scala')
-rw-r--r-- | src/main/scala/workbench/WorkbenchSplicePlugin.scala | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/main/scala/workbench/WorkbenchSplicePlugin.scala b/src/main/scala/workbench/WorkbenchSplicePlugin.scala new file mode 100644 index 0000000..9d68ad3 --- /dev/null +++ b/src/main/scala/workbench/WorkbenchSplicePlugin.scala @@ -0,0 +1,88 @@ +package com.lihaoyi.workbench +import scala.concurrent.ExecutionContext.Implicits.global +import sbt._ +import sbt.Keys._ +import autowire._ +import org.scalajs.sbtplugin.ScalaJSPlugin +import org.scalajs.core.tools.io._ +import org.scalajs.sbtplugin.ScalaJSPluginInternal._ +import org.scalajs.sbtplugin.Implicits._ + +object WorkbenchSplicePlugin extends AutoPlugin { + + override def requires = WorkbenchPlugin + + object autoImport { + val updatedJS = taskKey[List[String]]("Provides the addresses of the JS files that have changed") + val spliceBrowsers = taskKey[Unit]("Attempts to do a live update of the code running in the browser while maintaining state") + } + import autoImport._ + import WorkbenchBasePlugin.autoImport._ + import WorkbenchBasePlugin.server + import ScalaJSPlugin.AutoImport._ + + val spliceSettings = Seq( + updatedJS := { + var files: List[String] = Nil + ((crossTarget in Compile).value * "*.js").get.foreach { + (x: File) => + streams.value.log.info("workbench: Checking " + x.getName) + FileFunction.cached(streams.value.cacheDirectory / x.getName, FilesInfo.lastModified, FilesInfo.lastModified) { + (f: Set[File]) => + val fsPath = f.head.getAbsolutePath.drop(new File("").getAbsolutePath.length) + files = fsPath :: files + f + }(Set(x)) + } + files + }, + updatedJS := { + val paths = updatedJS.value + val url = localUrl.value + paths.map { path => + s"http://${url._1}:${url._2}$path" + } + }, + spliceBrowsers := { + val changed = updatedJS.value + // There is no point in clearing the browser if no js files have changed. + if (changed.length > 0) { + for{ + path <- changed + if !path.endsWith(".js.js") + }{ + streams.value.log.info("workbench: Splicing " + path) + val url = localUrl.value + val prefix = s"http://${url._1}:${url._2}/" + val s = munge(sbt.IO.read(new sbt.File(path.drop(prefix.length)))) + + sbt.IO.write(new sbt.File(path.drop(prefix.length) + ".js"), s.getBytes) + server.value.Wire[Api].run(path + ".js").call() + } + } + }, + spliceBrowsers <<= spliceBrowsers.triggeredBy(fastOptJS in Compile) + ) + + override def projectSettings = spliceSettings + + def munge(s0: String) = { + var s = s0 + s = s.replace("\nvar ScalaJS = ", "\nvar ScalaJS = ScalaJS || ") + s = s.replaceAll( + "\n(ScalaJS\\.c\\.[a-zA-Z_$0-9]+\\.prototype) = (.*?\n)", + """ + |$1 = $1 || {} + |(function(){ + | var newProto = $2 + | for (var attrname in newProto) { $1[attrname] = newProto[attrname]; } + |})() + |""".stripMargin + ) + for(char <- Seq("d", "c", "h", "i", "n", "m")){ + s = s.replaceAll("\n(ScalaJS\\." + char + "\\.[a-zA-Z_$0-9]+) = ", "\n$1 = $1 || ") + } + s + } + +} |