Skip to content

Commit 04037cd

Browse files
committed
Add support for fiddles using Scala.js 1.x.
This adds a new column `scalajs_version` in the `Fiddle` table. The correct value for existing values should be `0.6`.
1 parent 17c5dc8 commit 04037cd

File tree

13 files changed

+100
-36
lines changed

13 files changed

+100
-36
lines changed

client/src/main/scala/scalafiddle/client/CompilerHandler.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package scalafiddle.client
22

3+
import java.nio.charset.StandardCharsets
4+
35
import autowire._
46
import diode._
57
import org.scalajs.dom
68
import org.scalajs.dom.ext.Ajax
79
import upickle.default._
810

911
import scala.scalajs.js
10-
import scala.scalajs.niocharset.StandardCharsets
1112
import scala.concurrent.ExecutionContext.Implicits.global
1213
import scalafiddle.shared.{Api, FiddleVersions}
1314

client/src/main/scala/scalafiddle/client/FiddleHandler.scala

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ case class DeselectLibrary(lib: Library) extends Action
1515

1616
case class SelectScalaVersion(version: String) extends Action
1717

18+
case class SelectScalaJSVersion(version: String) extends Action
19+
1820
case class UpdateInfo(name: String, description: String) extends Action
1921

2022
case class UpdateSource(source: String) extends Action
@@ -43,6 +45,9 @@ class FiddleHandler[M](modelRW: ModelRW[M, FiddleData], fidRW: ModelRW[M, Option
4345
case SelectScalaVersion(version) =>
4446
updated(value.copy(scalaVersion = version))
4547

48+
case SelectScalaJSVersion(version) =>
49+
updated(value.copy(scalaJSVersion = version))
50+
4651
case UpdateInfo(name, description) =>
4752
updated(value.copy(name = name, description = description))
4853

client/src/main/scala/scalafiddle/client/Utils.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ object SHA1 extends js.Object {
7676
@js.native
7777
@JSGlobal("ScalaFiddleConfig")
7878
object ScalaFiddleConfig extends js.Object {
79-
val compilerURL: String = js.native
80-
val helpURL: String = js.native
81-
val scalaVersions: js.Array[String] = js.native
79+
val compilerURL: String = js.native
80+
val helpURL: String = js.native
81+
val scalaVersions: js.Array[String] = js.native
82+
val scalaJSVersions: js.Array[String] = js.native
8283
}
8384

8485
@js.native

client/src/main/scala/scalafiddle/client/component/FiddleEditor.scala

+14-9
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,11 @@ object FiddleEditor {
176176
.flatMap(version => Seq[TagMod](fLink(f)(version)(version.toString), span(" | ")))
177177
.init
178178

179-
def config[B: Ordering](name: String,
180-
renderer: CellRenderer[FiddleVersions],
181-
order: FiddleVersions => B) =
179+
def config[B: Ordering](
180+
name: String,
181+
renderer: CellRenderer[FiddleVersions],
182+
order: FiddleVersions => B
183+
) =
182184
ColumnConfig[FiddleVersions](name, renderer)(DefaultOrdering[FiddleVersions, B](order))
183185

184186
val configs = List(
@@ -290,12 +292,13 @@ object FiddleEditor {
290292
source
291293
}
292294

293-
def addDeps(source: String, deps: Seq[Library], scalaVersion: String): String = {
295+
def addDeps(source: String, deps: Seq[Library], scalaVersion: String, scalaJSVersion: String): String = {
294296
val extraDeps = deps.flatMap(_.extraDeps)
295297
val allDeps = extraDeps ++ deps.map(Library.stringify)
296298
source + "\n" +
297299
allDeps.map(dep => s"// $$FiddleDependency $dep\n").mkString +
298-
s"// $$ScalaVersion $scalaVersion\n"
300+
s"// $$ScalaVersion $scalaVersion\n" +
301+
s"// $$ScalaJSVersion $scalaJSVersion\n"
299302
}
300303

301304
def buildFullSource: CallbackTo[String] = {
@@ -304,7 +307,8 @@ object FiddleEditor {
304307
state <- $.state
305308
} yield {
306309
val source = reconstructSource(state)
307-
addDeps(source, props.data().libraries, props.data().scalaVersion)
310+
val data = props.data()
311+
addDeps(source, data.libraries, data.scalaVersion, data.scalaJSVersion)
308312
}
309313
}
310314

@@ -472,10 +476,11 @@ object FiddleEditor {
472476
} >>
473477
props.dispatch(UpdateLoginInfo) >>
474478
updateFiddle(props.data()) >>
475-
Callback.when(props.fiddleId.isDefined)(
479+
Callback.when(props.fiddleId.isDefined) {
480+
val data = props.data()
476481
props
477-
.dispatch(compile(addDeps(props.data().sourceCode, props.data().libraries, props.data().scalaVersion), FastOpt))
478-
)
482+
.dispatch(compile(addDeps(data.sourceCode, data.libraries, data.scalaVersion, data.scalaJSVersion), FastOpt))
483+
}
479484
}
480485

481486
val fiddleStart = """\s*// \$FiddleStart\s*$""".r

client/src/main/scala/scalafiddle/client/component/Sidebar.scala

+26
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ object Sidebar {
3737
val availableVersions = fd.available
3838
.filterNot(lib => fd.libraries.exists(_.name == lib.name))
3939
.filter(lib => lib.scalaVersions.contains(fd.scalaVersion))
40+
.filter(lib => lib.scalaJSVersions.contains(fd.scalaJSVersion))
4041

4142
// hide alternative versions, if requested
4243
val available =
@@ -140,6 +141,31 @@ object Sidebar {
140141
}
141142
)
142143
)
144+
),
145+
div(cls := "ui grid")(
146+
div(cls := "eight wide column")(
147+
h4("Scala.js version")
148+
),
149+
div(cls := "eight wide column right aligned")(
150+
div(cls := "grouped fields")(
151+
ScalaFiddleConfig.scalaJSVersions.toTagMod { version =>
152+
div(cls := "field")(
153+
div(cls := "ui radio checkbox")(
154+
input.radio(
155+
name := "scalajsversion",
156+
value := version,
157+
checked := props.data().scalaJSVersion == version,
158+
onChange ==> { (e: ReactEventFromInput) =>
159+
val newVersion = e.currentTarget.value
160+
props.dispatch(SelectScalaJSVersion(newVersion))
161+
}
162+
),
163+
label(version + ".x")
164+
)
165+
)
166+
}
167+
)
168+
)
143169
)
144170
)
145171
),

server/src/main/resources/application.conf

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ scalafiddle {
5757
scalaVersions = ["2.11", "2.12"]
5858
defaultScalaVersion = "2.12"
5959

60+
scalaJSVersions = ["0.6", "1"]
61+
defaultScalaJSVersion = "0.6"
62+
6063
refreshLibraries = 300
6164
refreshLibraries = ${?SCALAFIDDLE_REFRESH_LIBRARIES}
6265

server/src/main/scala/controllers/Application.scala

+21-9
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class Application @Inject() (
4747
val scalafiddleUrl = new URL(config.get[String]("scalafiddle.scalafiddleURL"))
4848
val compilerUrl = config.get[String]("scalafiddle.compilerURL")
4949
val scalaVersions = config.get[Seq[String]]("scalafiddle.scalaVersions")
50+
val scalaJSVersions = config.get[Seq[String]]("scalafiddle.scalaJSVersions")
5051

5152
Kamon.start()
5253

@@ -133,6 +134,7 @@ class Application @Inject() (
133134
val allLibs = fd.libraries.flatMap(lib => Library.stringify(lib) +: lib.extraDeps)
134135
sourceCode.append(allLibs.map(lib => s"// $$FiddleDependency $lib").mkString("\n", "\n", "\n"))
135136
sourceCode.append(s"// $$ScalaVersion ${fd.scalaVersion}\n")
137+
sourceCode.append(s"// $$ScalaJSVersion ${fd.scalaJSVersion}\n")
136138
nameOpt.foreach(name => sourceCode.append(s"// $$FiddleName $name\n"))
137139

138140
Ok(sourceCode.toString).withHeaders(CACHE_CONTROL -> "max-age=7200")
@@ -317,7 +319,7 @@ class Application @Inject() (
317319

318320
private def loadFiddle(id: String, version: Int, sourceOpt: Option[String] = None): Future[Try[FiddleData]] = {
319321
if (id == "") {
320-
val (source, libs, scalaVersion) = parseFiddle(sourceOpt.fold(defaultSource)(identity))
322+
val (source, libs, scalaVersion, scalaJSVersion) = parseFiddle(sourceOpt.fold(defaultSource)(identity))
321323
Future.successful(
322324
Success(
323325
FiddleData(
@@ -329,6 +331,9 @@ class Application @Inject() (
329331
scalaVersion
330332
.flatMap(v => scalaVersions.find(_ == v))
331333
.getOrElse(config.get[String]("scalafiddle.defaultScalaVersion")),
334+
scalaJSVersion
335+
.flatMap(v => scalaJSVersions.find(_ == v))
336+
.getOrElse(config.get[String]("scalafiddle.defaultScalaJSVersion")),
332337
None,
333338
System.currentTimeMillis()
334339
)
@@ -346,6 +351,7 @@ class Application @Inject() (
346351
f.libraries.flatMap(librarian.findLibrary),
347352
librarian.libraries,
348353
f.scalaVersion,
354+
f.scalaJSVersion,
349355
None,
350356
f.created
351357
)
@@ -363,6 +369,7 @@ class Application @Inject() (
363369
f.libraries.flatMap(librarian.findLibrary),
364370
librarian.libraries,
365371
f.scalaVersion,
372+
f.scalaJSVersion,
366373
Some(user),
367374
f.created
368375
)
@@ -376,6 +383,7 @@ class Application @Inject() (
376383
f.libraries.flatMap(librarian.findLibrary),
377384
librarian.libraries,
378385
f.scalaVersion,
386+
f.scalaJSVersion,
379387
None,
380388
f.created
381389
)
@@ -387,16 +395,20 @@ class Application @Inject() (
387395
}
388396
}
389397

390-
private def parseFiddle(source: String): (String, Seq[Library], Option[String]) = {
391-
val dependencyRE = """ *// \$FiddleDependency +(.+)""".r
392-
val versionRE = """ *// \$ScalaVersion +([0-9]+\.[0-9]+)""".r
393-
val lines = source.split("\n")
398+
private def parseFiddle(source: String): (String, Seq[Library], Option[String], Option[String]) = {
399+
val dependencyRE = """ *// \$FiddleDependency +(.+)""".r
400+
val scalaVersionRE = """ *// \$ScalaVersion +([0-9]+\.[0-9]+)""".r
401+
val scalaJSVersionRE = """ *// \$ScalaJSVersion +([0-9]+(?:\.[0-9]+)?)""".r
402+
val lines = source.split("\n")
394403
val (libLines, codeLines) = lines.partition { line =>
395-
dependencyRE.findFirstIn(line).isDefined || versionRE.findFirstIn(line).isDefined
404+
dependencyRE.findFirstIn(line).isDefined ||
405+
scalaVersionRE.findFirstIn(line).isDefined ||
406+
scalaVersionRE.findFirstIn(line).isDefined
396407
}
397-
val libs = libLines.flatMap(line => dependencyRE.findFirstMatchIn(line).flatMap(d => librarian.findLibrary(d.group(1))))
398-
val version = libLines.flatMap(line => versionRE.findFirstMatchIn(line).map(_.group(1))).headOption
399-
(codeLines.mkString("\n"), libs, version)
408+
val libs = libLines.flatMap(line => dependencyRE.findFirstMatchIn(line).flatMap(d => librarian.findLibrary(d.group(1))))
409+
val scalaVersion = libLines.flatMap(line => scalaVersionRE.findFirstMatchIn(line).map(_.group(1))).headOption
410+
val scalaJSVersion = libLines.flatMap(line => scalaJSVersionRE.findFirstMatchIn(line).map(_.group(1))).headOption
411+
(codeLines.mkString("\n"), libs, scalaVersion, scalaJSVersion)
400412
}
401413

402414
private def decodeSource(b64: String): Option[String] = {

server/src/main/scala/scalafiddle/server/Librarian.scala

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Librarian(libSource: () => BufferedSource) {
1212
case class LibraryVersion(
1313
version: String,
1414
scalaVersions: Seq[String],
15+
scalaJSVersions: Seq[String],
1516
extraDeps: Seq[String],
1617
organization: Option[String],
1718
artifact: Option[String],
@@ -25,6 +26,7 @@ class Librarian(libSource: () => BufferedSource) {
2526
LibraryVersion(
2627
readJs[String](values("version")),
2728
readJs[Seq[String]](values("scalaVersions")),
29+
values.get("scalaJSVersions").map(readJs[Seq[String]]).getOrElse(Seq("0.6")),
2830
readJs[Seq[String]](values.getOrElse("extraDeps", Js.Arr())),
2931
values.get("organization").map(readJs[String]),
3032
values.get("artifact").map(readJs[String]),
@@ -80,6 +82,7 @@ class Librarian(libSource: () => BufferedSource) {
8082
versionDef.version,
8183
lib.compileTimeOnly,
8284
versionDef.scalaVersions,
85+
versionDef.scalaJSVersions,
8386
versionDef.extraDeps,
8487
f"$idx%02d:${group.group}",
8588
createDocURL(versionDef.doc.getOrElse(lib.doc)),

server/src/main/scala/scalafiddle/server/Persistence.scala

+3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class Persistence @Inject() (config: Configuration) extends Actor with ActorLogg
8787
fiddle.sourceCode,
8888
fiddle.libraries.map(Library.stringify).toList,
8989
fiddle.scalaVersion,
90+
fiddle.scalaJSVersion,
9091
user
9192
)
9293
runAndReply(dal.insertFiddle(newFiddle))(r => Success(FiddleId(id, 0))) pipeTo sender()
@@ -101,6 +102,7 @@ class Persistence @Inject() (config: Configuration) extends Actor with ActorLogg
101102
fiddle.sourceCode,
102103
fiddle.libraries.map(Library.stringify).toList,
103104
fiddle.scalaVersion,
105+
fiddle.scalaJSVersion,
104106
user,
105107
Some(s"$id/$version")
106108
)
@@ -142,6 +144,7 @@ class Persistence @Inject() (config: Configuration) extends Actor with ActorLogg
142144
fiddle.sourceCode,
143145
fiddle.libraries.map(Library.stringify).toList,
144146
fiddle.scalaVersion,
147+
fiddle.scalaJSVersion,
145148
latest.user,
146149
Some(s"${latest.id}/${latest.version}")
147150
)

server/src/main/scala/scalafiddle/server/dao/FiddleDAO.scala

+15-13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ case class Fiddle(
88
sourceCode: String,
99
libraries: List[String],
1010
scalaVersion: String,
11+
scalaJSVersion: String,
1112
user: String,
1213
parent: Option[String] = None,
1314
created: Long = System.currentTimeMillis(),
@@ -24,21 +25,22 @@ trait FiddleDAO { self: DriverComponent =>
2425
)
2526

2627
class Fiddles(tag: Tag) extends Table[Fiddle](tag, "fiddle") {
27-
def id = column[String]("id")
28-
def version = column[Int]("version")
29-
def name = column[String]("name")
30-
def description = column[String]("description")
31-
def sourceCode = column[String]("sourcecode")
32-
def libraries = column[List[String]]("libraries")
33-
def scalaVersion = column[String]("scala_version")
34-
def user = column[String]("user")
35-
def parent = column[Option[String]]("parent")
36-
def created = column[Long]("created")
37-
def removed = column[Boolean]("removed")
38-
def pk = primaryKey("pk_fiddle", (id, version))
28+
def id = column[String]("id")
29+
def version = column[Int]("version")
30+
def name = column[String]("name")
31+
def description = column[String]("description")
32+
def sourceCode = column[String]("sourcecode")
33+
def libraries = column[List[String]]("libraries")
34+
def scalaVersion = column[String]("scala_version")
35+
def scalaJSVersion = column[String]("scalajs_version")
36+
def user = column[String]("user")
37+
def parent = column[Option[String]]("parent")
38+
def created = column[Long]("created")
39+
def removed = column[Boolean]("removed")
40+
def pk = primaryKey("pk_fiddle", (id, version))
3941

4042
def * =
41-
(id, version, name, description, sourceCode, libraries, scalaVersion, user, parent, created, removed) <> (Fiddle.tupled, Fiddle.unapply)
43+
(id, version, name, description, sourceCode, libraries, scalaVersion, scalaJSVersion, user, parent, created, removed) <> (Fiddle.tupled, Fiddle.unapply)
4244
}
4345

4446
val fiddles = TableQuery[Fiddles]

server/src/main/twirl/views/index.scala.html

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
cfg.compilerURL = "@config.get[String]("scalafiddle.compilerURL")";
4444
cfg.helpURL = "@config.get[String]("scalafiddle.helpURL")";
4545
cfg.scalaVersions = @Html(config.get[Seq[String]]("scalafiddle.scalaVersions").mkString("[\"","\",\"","\"]"));
46+
cfg.scalaJSVersions = @Html(config.get[Seq[String]]("scalafiddle.scalaJSVersions").mkString("[\"","\",\"","\"]"));
4647
window.ScalaFiddleConfig = cfg;
4748
window.ScalaFiddleData = @Html(fiddleData);
4849
</script>

server/src/main/twirl/views/resultframe.scala.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
loads.then(function() {
5757
try {
5858
eval(msg.data.code);
59-
eval("var sf = ScalaFiddle;if(typeof sf === 'function') { if(typeof sf().main === 'function') sf().main() } else if(typeof sf.main === 'function') sf.main();");
59+
eval("if(typeof ScalaFiddle !== 'undefined') { var sf = ScalaFiddle;if(typeof sf === 'function') { if(typeof sf().main === 'function') sf().main() } else if(typeof sf.main === 'function') sf.main(); }");
6060
} catch(ex) {
6161
result.insertAdjacentHTML('beforeend', '<pre class="error">ERROR: ' + ex.message + '\n' + ex.stack + '</pre>')
6262
} finally {

shared/src/main/scala/scalafiddle/shared/FiddleData.scala

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ case class Library(
1111
version: String,
1212
compileTimeOnly: Boolean,
1313
scalaVersions: Seq[String],
14+
scalaJSVersions: Seq[String],
1415
extraDeps: Seq[String],
1516
group: String,
1617
docUrl: String,
@@ -32,6 +33,7 @@ case class FiddleData(
3233
libraries: Seq[Library],
3334
available: Seq[Library],
3435
scalaVersion: String,
36+
scalaJSVersion: String,
3537
author: Option[UserInfo],
3638
modified: Long
3739
)

0 commit comments

Comments
 (0)