Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaladoc: Integrate Scastie into Scaladoc #13258

Merged
merged 6 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1417,7 +1417,7 @@ object Build {
"scaladoc testcases",
"scaladoc/output/testcases",
"master",
Seq("-usejavacp")
Seq("-usejavacp", "-snippet-compiler:scaladoc-testcases/docs=compile", "-siteroot", "scaladoc-testcases/docs")
)
}.value,

Expand Down
5 changes: 5 additions & 0 deletions project/scripts/cmdScaladocTests
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ DOTTY_NONBOOTSTRAPPED_VERSION=$(eval $DOTTY_NONBOOTSTRAPPED_VERSION_COMMAND | ta
DOTTY_BOOTSTRAPPED_VERSION_COMMAND="$SBT \"eval println(Build.dottyVersion)\""
DOTTY_BOOTSTRAPPED_VERSION=$(eval $DOTTY_BOOTSTRAPPED_VERSION_COMMAND | tail -n 2 | head -n 1)

GITHUB_REPOSITORY="lampepfl/dotty"
GITHUB_SHA="3.0.0"

"$SBT" "scaladoc/generateTestcasesDocumentation" > "$tmp" 2>&1 || echo "generated testcases project with sbt"
dist/target/pack/bin/scaladoc \
-d "$OUT1" \
Expand All @@ -31,6 +34,8 @@ dist/target/pack/bin/scaladoc \
-Ygenerate-inkuire \
"-skip-by-id:scala.runtime.stdLibPatches" \
"-skip-by-id:scala.runtime.MatchCase" \
"-snippet-compiler:scaladoc-testcases/docs=compile" \
-siteroot scaladoc-testcases/docs \
-project-footer "Copyright (c) 2002-2021, LAMP/EPFL" \
-author -groups -revision master -project-version "${DOTTY_BOOTSTRAPPED_VERSION}" \
out/bootstrap/scaladoc-testcases/scala-"${DOTTY_NONBOOTSTRAPPED_VERSION}"/classes > "$tmp" 2>&1 || echo "generated testcases project with scripts"
Expand Down
115 changes: 96 additions & 19 deletions scaladoc-js/resources/code-snippets.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
--slider-diameter: calc(var(--slider-height) - 4px);
}

.snippet-showhide p {
.buttons p {
margin-left: 4px;
margin-bottom: 0;
margin-top: 0;
Expand Down Expand Up @@ -160,8 +160,8 @@ input:checked + .slider:before {
}


.snippet .buttons>:not(:last-child) {
border-left: 2px solid var(--inactive-bg);
.snippet .buttons>:not(:first-child) {
border-right: 2px solid var(--inactive-bg);
}

.snippet .buttons>* {
Expand Down Expand Up @@ -194,28 +194,110 @@ input:checked + .slider:before {
display: none;
}

@media(max-width: 576px) {
.snippet-showhide {
--slider-width: 32px;
--slider-height: 16px;
}
.snippet .scastie.embedded {
width: 100%;
}

.snippet .scastie.embedded .content {
height: unset;
}

.snippet .scastie.embedded .editor-container {
height: unset;
}

.snippet .scastie.embedded .editor-container .code {
height: unset;
}

.snippet .scastie.embedded .editor-container .editor-wrapper {
height: unset;
}

.snippet .scastie .CodeMirror, .snippet .scastie .CodeMirror-scroll {
height:unset;
}

.snippet .scastie.embedded .app.light .editor-container .code .CodeMirror-scroll {
height:unset;
min-height: 50px;
}

.snippet .scastie .app.light .editor-container .console-container .console {
height: unset;
}

.snippet .scastie .app.light .CodeMirror-gutters {
background-color: var(--code-bg) !important;
border-color: var(--code-bg) !important;
}

.snippet .scastie .app.light .CodeMirror {
color: var(--code-fg);
background-color: var(--code-bg);
}


.snippet .scastie .app.light .output-console pre {
color: white;
background-color: rgb(0, 43, 54);
}

.snippet .scastie .app.light .editor-container .handler {
background-color: var(--code-bg);
}

.snippet .scastie .console-container {
margin-left: 30px;
}

.snippet .scastie .app.light .main-panel {
background-color: unset;
}

.snippet .scastie .cm-s-solarized.cm-s-light .CodeMirror-widget .fold,
.snippet .scastie .cm-s-solarized.cm-s-light .CodeMirror-linewidget .compilation-info,
.snippet .scastie .cm-s-solarized.cm-s-light .CodeMirror-linewidget .runtime-error,
.snippet .scastie .cm-s-solarized.cm-s-light .CodeMirror-linewidget .line,
.snippet .scastie .cm-s-solarized.cm-s-light .CodeMirror-linewidget .inline {
background-color: var(--code-bg);
}

.snippet .scastie .ansi-color-yellow {
color: #b58900;
}

.snippet .scastie .ansi-color-magenta {
color: var(--red500);
}

.snippet .fa-warning:before, .fa-exclamation-triangle:before {
color: #b58900;
}

@media(max-width: 836px) {
.snippet .buttons {
--icon-size: 16px;
font-size: 16px;
--icon-size: 16px;
font-size: 0px;
}

.snippet .buttons p {
--icon-size: 16px;
font-size: 0px;
}
}

@media(max-width: 360px) {
@media(max-width: 576px) {
.snippet-showhide {
--slider-width: 32px;
--slider-height: 16px;
}
}

.snippet .buttons {
--icon-size: 16px;
font-size: 0px;
@media(max-width: 360px) {
.snippet-showhide {
--slider-width: 32px;
--slider-height: 16px;
}
}

Expand All @@ -224,9 +306,4 @@ input:checked + .slider:before {
--slider-width: 24px;
--slider-height: 10px;
}

.snippet .buttons {
--icon-size: 16px;
font-size: 0px;
}
}
116 changes: 103 additions & 13 deletions scaladoc-js/src/code-snippets/CodeSnippets.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package dotty.tools.scaladoc

import scala.scalajs.js
import org.scalajs.dom._
import org.scalajs.dom.ext._

import CodeSnippetsGlobals._

class CodeSnippets:
lazy val scastieConfig = getScastieConfiguration

private def getScastieConfiguration: js.Dynamic =
js.Dynamic.literal(
sbtConfig = scastieConfiguration,
targetType = "scala3"
)

private def getButtonsSection(snippet: html.Element): Option[html.Div] = snippet.querySelector("div.buttons") match {
case div: html.Div => Some(div)
Expand All @@ -12,7 +22,7 @@ class CodeSnippets:

def enrichSnippets() = document.querySelectorAll("div.snippet").foreach {
case snippet: html.Element =>
snippet.addEventListener("click", e => e.stopPropagation())
snippet.addEventListener("click", (e: MouseEvent) => e.asInstanceOf[js.Dynamic].fromSnippet = true)
snippetAnchor(snippet)
handleHideableCode(snippet)
handleImportedCode(snippet)
Expand Down Expand Up @@ -106,23 +116,103 @@ class CodeSnippets:
div
}
def runButton = {
val div = document.createElement("div")
val button = document.createElement("button").asInstanceOf[html.Button]
val icon = document.createElement("i")
icon.classList.add("fas")
icon.classList.add("fa-play")
button.appendChild(icon)
button.classList.add("run-button")
button.addEventListener("click", _ => {}) // TODO: Run button #13065
button.disabled = true
div.appendChild(button)
val div = document.createElement("div").asInstanceOf[html.Div]
val runButton = document.createElement("button").asInstanceOf[html.Button]
val runIcon = document.createElement("i")
runIcon.classList.add("fas")
runIcon.classList.add("fa-play")
runButton.classList.add("run-button")
runButton.appendChild(runIcon)

runButton.addEventListener("click", _ =>
if !runButton.hasAttribute("opened") then {
scastie.Embedded(snippet.querySelector("pre"), scastieConfig)
runButton.setAttribute("opened", "opened")
}
snippet.querySelector(".scastie .embedded-menu") match {
case btn: html.Element =>
btn.style = "display:none;"
case _ =>
}
snippet.querySelector(".scastie .embedded-menu .run-button") match {
case btn: html.Element => btn.click()
case _ =>
}
snippet.querySelector(".buttons .exit-button") match {
case btn: html.Element => btn.parentElement.style = ""
case _ =>
}
snippet.querySelector(".buttons .to-scastie-button") match {
case btn: html.Element => btn.parentElement.style = ""
case _ =>
}
)

div.appendChild(runButton)
div
}
def exitButton = {
val div = document.createElement("div").asInstanceOf[html.Div]
val exitButton = document.createElement("button").asInstanceOf[html.Element]
val exitIcon = document.createElement("i")
exitIcon.classList.toggle("fas")
exitIcon.classList.toggle("fa-times")
exitButton.classList.add("exit-button")
div.style = "display:none;"
exitButton.appendChild(exitIcon)

exitButton.addEventListener("click", _ =>
snippet.querySelector("pre") match {
case p: html.Element => p.style = ""
case _ =>
}
snippet.querySelector(".scastie.embedded") match {
case s: html.Element => snippet.removeChild(s)
case _ =>
}
snippet.querySelector(".buttons .run-button") match {
case btn: html.Element => btn.removeAttribute("opened")
case _ =>
}
snippet.querySelector(".buttons .to-scastie-button") match {
case btn: html.Element => btn.parentElement.style = "display:none;"
case _ =>
}
div.style = "display:none;"
)

div.appendChild(exitButton)
div
}
def toScastieButton = {
val div = document.createElement("div").asInstanceOf[html.Div]
val toScastieButton = document.createElement("button").asInstanceOf[html.Element]
val toScastieIcon = document.createElement("i").asInstanceOf[html.Image]

toScastieIcon.classList.add("fas")
toScastieIcon.classList.add("fa-external-link-alt")
toScastieButton.classList.add("to-scastie-button")
div.style = "display:none;"
toScastieButton.appendChild(toScastieIcon)

toScastieButton.addEventListener("click", _ =>
snippet.querySelector(".embedded-menu li.logo") match {
case toScastie: html.Element => toScastie.click()
case _ =>
}
)

div.appendChild(toScastieButton)
div
}
val buttonsSection = getButtonsSection(snippet)
buttonsSection.foreach(s =>
s.appendChild(copyButton)
// Temporarily disabled
// s.appendChild(runButton)
if !snippet.hasAttribute("hasContext") then {
s.appendChild(toScastieButton)
s.appendChild(runButton)
s.appendChild(exitButton)
}
)
}

Expand Down
11 changes: 11 additions & 0 deletions scaladoc-js/src/code-snippets/CodeSnippetsGlobals.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dotty.tools.scaladoc

import scala.scalajs.js
import scala.scalajs.js.annotation.JSGlobalScope

@js.native
@JSGlobalScope
object CodeSnippetsGlobals extends js.Object {
val scastie: Scastie = js.native
val scastieConfiguration: String = js.native
}
9 changes: 9 additions & 0 deletions scaladoc-js/src/code-snippets/Scastie.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dotty.tools.scaladoc

import scala.scalajs.js
import org.scalajs.dom._

@js.native
trait Scastie extends js.Object:
def Embedded(selector: String | Node, config: js.Dynamic): Unit = js.native
def Embedded(selector: String | Node): Unit = js.native
12 changes: 8 additions & 4 deletions scaladoc-testcases/docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@

---

```scala sc:compile
2 + List(0)
```scala
val someVariable: Int = 2
```

```scala sc:compile
new snippetCompiler.Snippet0 { }
```scala sc:fail
trait RenderingContext
class Renderer(using RenderingContext)
val renderer: Renderer = Renderer()
```



2 changes: 1 addition & 1 deletion scaladoc/resources/dotty_res/scripts/ux.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ window.addEventListener("DOMContentLoaded", () => {
if (elements) {
for (i = 0; i < elements.length; i++) {
elements[i].onclick = function(e) {
if(!$(e.target).is("a"))
if(!$(e.target).is("a") && e.fromSnippet !== true)
this.classList.toggle("expand")
}
}
Expand Down
Loading