Skip to content

Commit 1b32edf

Browse files
committed
Integrate Scastie into Scaladoc.
1 parent 31292be commit 1b32edf

30 files changed

+14356
-23
lines changed

project/Build.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ object Build {
13931393
"scaladoc testcases",
13941394
"scaladoc/output/testcases",
13951395
"master",
1396-
Seq("-usejavacp")
1396+
Seq("-usejavacp", "-snippet-compiler:scaladoc-testcases/docs=compile", "-siteroot", "scaladoc-testcases/docs")
13971397
)
13981398
}.value,
13991399

scaladoc-js/resources/scaladoc-searchbar.css

+93
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,99 @@ input:checked + .slider:before {
288288
display: none;
289289
}
290290

291+
.snippet .scastie.embedded {
292+
width: 100%;
293+
}
294+
295+
.snippet .scastie.embedded .content {
296+
height: unset;
297+
}
298+
299+
.snippet .scastie.embedded .editor-container {
300+
height: unset;
301+
}
302+
303+
.snippet .scastie.embedded .editor-container .code {
304+
height: unset;
305+
}
306+
307+
.snippet .scastie.embedded .editor-container .editor-wrapper {
308+
padding-top: 48px;
309+
height: unset;
310+
}
311+
312+
.snippet .scastie .CodeMirror, .snippet .scastie .CodeMirror-scroll {
313+
height:unset;
314+
}
315+
316+
.snippet .scastie.embedded .editor-container .code .CodeMirror-scroll {
317+
height:unset !important;
318+
min-height: 50px !important;
319+
}
320+
321+
.snippet .scastie .editor-container .console-container .console {
322+
height: unset !important;
323+
}
324+
325+
.snippet .scastie .CodeMirror-gutters {
326+
background-color: var(--code-bg) !important;
327+
}
328+
329+
.snippet .scastie .CodeMirror {
330+
color: var(--code-fg) !important;
331+
background-color: var(--code-bg) !important;
332+
}
333+
334+
.snippet .scastie .embedded-menu > * {
335+
background-color: transparent !important;
336+
color: var(--active-fg) !important;
337+
width: 64px;
338+
font-size: 1em;
339+
padding: 8px;
340+
position: unset;
341+
}
342+
343+
.snippet .scastie .embedded-menu li:hover {
344+
background-color: var(--active-bg) !important;
345+
}
346+
347+
.snippet .scastie .embedded-menu {
348+
margin: 15px;
349+
display: block;
350+
}
351+
352+
.snippet .scastie .embedded-menu > li {
353+
display: unset;
354+
border: unset;
355+
transition-duration: 0.4s;
356+
}
357+
358+
:root.theme-dark .snippet .scastie .embedded-menu > .logo img {
359+
filter: unset;
360+
}
361+
:root .snippet .scastie .embedded-menu > .logo img {
362+
filter: invert(100%) hue-rotate(180deg);
363+
}
364+
365+
366+
.snippet .scastie .output-console pre {
367+
color: white;
368+
background-color: rgb(0, 43, 54);
369+
}
370+
371+
.snippet .scastie .app.light .editor-container .handler {
372+
background-color: var(--code-bg) !important;
373+
}
374+
375+
.snippet .scastie .console-container {
376+
margin-left: 30px;
377+
}
378+
379+
.snippet .scastie .main-panel {
380+
background-color: unset !important;
381+
}
382+
383+
291384
@media(max-width: 576px) {
292385
.snippet-showhide {
293386
--slider-width: 32px;

scaladoc-js/src/code-snippets/CodeSnippets.scala

+31-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package dotty.tools.scaladoc
22

3+
import scala.scalajs.js
34
import org.scalajs.dom._
45
import org.scalajs.dom.ext._
56

7+
import CodeSnippetsGlobals._
8+
69
class CodeSnippets:
710

811
private def getButtonsSection(snippet: html.Element): Option[html.Div] = snippet.querySelector("div.buttons") match {
@@ -12,7 +15,7 @@ class CodeSnippets:
1215

1316
def enrichSnippets() = document.querySelectorAll("div.snippet").foreach {
1417
case snippet: html.Element =>
15-
snippet.addEventListener("click", e => e.stopPropagation())
18+
snippet.addEventListener("click", (e: MouseEvent) => e.asInstanceOf[js.Dynamic].fromSnippet = true)
1619
snippetAnchor(snippet)
1720
handleHideableCode(snippet)
1821
handleImportedCode(snippet)
@@ -109,20 +112,41 @@ class CodeSnippets:
109112
val div = document.createElement("div")
110113
val button = document.createElement("button").asInstanceOf[html.Button]
111114
val icon = document.createElement("i")
112-
icon.classList.add("fas")
113-
icon.classList.add("fa-play")
115+
def initialState() = {
116+
icon.classList.add("fas")
117+
icon.classList.add("fa-play")
118+
button.setAttribute("state", "run")
119+
}
120+
def toggleState() = {
121+
icon.classList.toggle("fa-play")
122+
icon.classList.toggle("fa-times")
123+
if button.getAttribute("state") == "run" then button.setAttribute("state", "exit")
124+
else button.setAttribute("state", "run")
125+
}
126+
initialState()
114127
button.appendChild(icon)
115128
button.classList.add("run-button")
116-
button.addEventListener("click", _ => {}) // TODO: Run button #13065
117-
button.disabled = true
129+
button.addEventListener("click", _ =>
130+
if button.getAttribute("state") == "run" then
131+
scastie.Embedded(snippet.querySelector("pre"))
132+
else
133+
snippet.querySelector("pre") match {
134+
case p: html.Element => p.style = ""
135+
case _ =>
136+
}
137+
snippet.querySelector(".scastie.embedded") match {
138+
case s: html.Element => snippet.removeChild(s)
139+
case _ =>
140+
}
141+
toggleState()
142+
)
118143
div.appendChild(button)
119144
div
120145
}
121146
val buttonsSection = getButtonsSection(snippet)
122147
buttonsSection.foreach(s =>
123148
s.appendChild(copyButton)
124-
// Temporarily disabled
125-
// s.appendChild(runButton)
149+
if !snippet.hasAttribute("hasContext") then s.appendChild(runButton)
126150
)
127151
}
128152

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dotty.tools.scaladoc
2+
3+
import scala.scalajs.js
4+
import scala.scalajs.js.annotation.JSGlobalScope
5+
6+
@js.native
7+
@JSGlobalScope
8+
object CodeSnippetsGlobals extends js.Object {
9+
val scastie: Scastie = js.native
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package dotty.tools.scaladoc
2+
3+
import scala.scalajs.js
4+
import org.scalajs.dom._
5+
6+
@js.native
7+
trait Scastie extends js.Object:
8+
def Embedded(selector: String | Node, config: js.Dynamic): Unit = js.native
9+
def Embedded(selector: String | Node): Unit = js.native

scaladoc-testcases/docs/docs/index.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33

44
---
55

6-
```scala sc:compile
7-
2 + List(0)
6+
```scala
7+
val someVariable: Int = 2
88
```
99

10-
```scala sc:compile
11-
new snippetCompiler.Snippet0 { }
10+
```scala sc:fail
11+
trait RenderingContext
12+
class Renderer(using RenderingContext)
13+
val renderer: Renderer = Renderer()
1214
```
1315

16+
17+

scaladoc/resources/dotty_res/scripts/ux.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ window.addEventListener("DOMContentLoaded", () => {
1010
if (elements) {
1111
for (i = 0; i < elements.length; i++) {
1212
elements[i].onclick = function(e) {
13-
if(!$(e.target).is("a"))
13+
if(!$(e.target).is("a") && e.fromSnippet !== true)
1414
this.classList.toggle("expand")
1515
}
1616
}

0 commit comments

Comments
 (0)