diff --git a/scaladoc-js/resources/scaladoc-searchbar.css b/scaladoc-js/resources/scaladoc-searchbar.css
index 035adbee6555..7f708b338fe8 100644
--- a/scaladoc-js/resources/scaladoc-searchbar.css
+++ b/scaladoc-js/resources/scaladoc-searchbar.css
@@ -100,5 +100,32 @@
.pull-right {
float: right;
- margin-left: auto
+ margin-left: auto;
+}
+
+.snippet-comment-button {
+ position: absolute;
+ left: 50%;
+ width: 24px;
+ height: 24px;
+}
+
+.show-snippet-comments-button {
+ -ms-transform: translate(calc(-50% + 5em), -50%);
+ transform: translate(calc(-50% + 5em), -50%);
+ background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Ccircle cx='12' cy='12' r='12' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M19 11.0053L19 13.1085H12.9873L12.988 19H10.8714L10.8721 13.1085L5 13.1085L5 11.0053L10.8721 11.0053V5L12.9865 5.00074L12.988 11.0045L19 11.0053Z' fill='%2327282C' fill-opacity='0.75'/%3E %3C/svg%3E");
+}
+
+.show-snippet-comments-button:hover {
+ background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Ccircle cx='12' cy='12' r='12' fill='light grey'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M19 11.0053L19 13.1085H12.9873L12.988 19H10.8714L10.8721 13.1085L5 13.1085L5 11.0053L10.8721 11.0053V5L12.9865 5.00074L12.988 11.0045L19 11.0053Z' fill='%2327282C' fill-opacity='0.75'/%3E %3C/svg%3E");
+}
+
+.hide-snippet-comments-button {
+ -ms-transform: translate(calc(-50% + 5em), -50%) rotate(45deg);
+ transform: translate(calc(-50% + 5em), -50%) rotate(45deg);
+ background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Ccircle cx='12' cy='12' r='12' fill='white'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M19 11.0053L19 13.1085H12.9873L12.988 19H10.8714L10.8721 13.1085L5 13.1085L5 11.0053L10.8721 11.0053V5L12.9865 5.00074L12.988 11.0045L19 11.0053Z' fill='%2327282C' fill-opacity='0.75'/%3E %3C/svg%3E");
+}
+
+.hide-snippet-comments-button:hover {
+ background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E %3Ccircle cx='12' cy='12' r='12' fill='light grey'/%3E %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M19 11.0053L19 13.1085H12.9873L12.988 19H10.8714L10.8721 13.1085L5 13.1085L5 11.0053L10.8721 11.0053V5L12.9865 5.00074L12.988 11.0045L19 11.0053Z' fill='%2327282C' fill-opacity='0.75'/%3E %3C/svg%3E");
}
diff --git a/scaladoc-js/src/Main.scala b/scaladoc-js/src/Main.scala
index 7b32aed9a1ea..c31ad58568fa 100644
--- a/scaladoc-js/src/Main.scala
+++ b/scaladoc-js/src/Main.scala
@@ -3,4 +3,5 @@ package dotty.tools.scaladoc
object Main extends App {
Searchbar()
SocialLinks()
+ CodeSnippets()
}
diff --git a/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala
new file mode 100644
index 000000000000..b6ed3d476887
--- /dev/null
+++ b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala
@@ -0,0 +1,43 @@
+package dotty.tools.scaladoc
+
+import org.scalajs.dom._
+import org.scalajs.dom.ext._
+
+class CodeSnippets:
+ val replacePatternsAndResults: Seq[(String, String)] = Seq(
+ """(\/\/{{\n)((.|\n)*?)(\/\/}}\n)""" -> """$2""", // wrap content of block directives
+ """(\/\/.*?)(\n|\$)""" -> """$1$2""", // wrap single line comment
+ """(\/\*)((.|\n)*?)(\*\/)""" -> """$0""", // wrap multi line comment
+ )
+
+ document.querySelectorAll("code").foreach {
+ case e: html.Element => e.innerHTML = replacePatternsAndResults.foldLeft(e.innerHTML) {
+ case (acc, (pattern, result)) =>
+ acc.replaceAll(pattern, result)
+ }
+ }
+
+ def toggleHide(e: html.Element | html.Document) = e.querySelectorAll("code span.hideable").foreach {
+ case e: html.Element if e.style.getPropertyValue("display").isEmpty => e.style.setProperty("display", "none")
+ case e: html.Element => e.style.removeProperty("display")
+ }
+
+ toggleHide(document)
+
+ document.querySelectorAll("pre").foreach {
+ case e: html.Element if e.querySelectorAll("code span.hideable").nonEmpty =>
+ val a = document.createElement("a")
+ a.addEventListener("click", { (_: MouseEvent) =>
+ if(a.classList.contains("hide-snippet-comments-button")) {
+ a.classList.add("show-snippet-comments-button")
+ a.classList.remove("hide-snippet-comments-button")
+ } else {
+ a.classList.add("hide-snippet-comments-button")
+ a.classList.remove("show-snippet-comments-button")
+ }
+ toggleHide(e)
+ })
+ a.classList.add("snippet-comment-button")
+ a.classList.add("show-snippet-comments-button")
+ e.insertBefore(a, e.firstChild)
+ }
diff --git a/scaladoc-testcases/src/tests/snippetComments.scala b/scaladoc-testcases/src/tests/snippetComments.scala
new file mode 100644
index 000000000000..39b15648103e
--- /dev/null
+++ b/scaladoc-testcases/src/tests/snippetComments.scala
@@ -0,0 +1,31 @@
+package tests.snippetComments
+
+
+/**
+ * This is my codeblock
+ *
+ * ```
+ * //{{
+ * import xd
+ * import xd2
+ * //}}
+ *
+ *
+ * val x = 1 // This is my valid comment
+ *
+ * /*
+ * multi line comment
+ * */
+ * val reallyFLongDeclaration = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
+ * val y = 2 // comment in the same line
+ * // comment in new line
+ * val z = 3
+ *
+ * //{{
+ * val hideMe = 7
+ * //}}
+ * ```
+ *
+ * The end of my codeblock
+ */
+class A
diff --git a/scaladoc/resources/dotty_res/styles/scalastyle.css b/scaladoc/resources/dotty_res/styles/scalastyle.css
index 948a377c9397..5c6580601308 100644
--- a/scaladoc/resources/dotty_res/styles/scalastyle.css
+++ b/scaladoc/resources/dotty_res/styles/scalastyle.css
@@ -5,7 +5,9 @@
--border-light: #DADFE6;
--border-medium: #abc;
+ --body-bg: #f0f3f6;
--code-bg: #F4F5FA;
+ --documentable-bg: #FFFFFF;
--symbol-fg: #333;
--link-fg: #00607D;
--link-hover-fg: #00A0D0;
@@ -45,6 +47,7 @@ body {
padding: 0;
font-family: "Lato", sans-serif;
font-size: 16px;
+ background-color: var(--body-bg);
}
/* Page layout */
@@ -75,7 +78,12 @@ h1, h2, h3 {
font-family: var(--title-font);
color: var(--title-fg);
}
-pre, code, .monospace, .hljs {
+.monospace {
+ font-family: var(--mono-font);
+ background: var(--documentable-bg);
+ font-variant-ligatures: none;
+}
+pre, code, .hljs {
font-family: var(--mono-font);
background: var(--code-bg);
font-variant-ligatures: none;
@@ -84,12 +92,16 @@ code {
font-size: .8em;
padding: 0 .3em;
}
+pre {
+ overflow-x: auto;
+ scrollbar-width: thin;
+}
pre code, pre code.hljs {
font-size: 1em;
padding: 0;
}
pre, .symbol.monospace {
- padding: 10px 8px 10px 12px;
+ padding: 12px 8px 10px 12px;
font-weight: 500;
font-size: 12px;
}
@@ -468,12 +480,18 @@ footer .pull-right {
padding-right: 0.5em;
min-width: 10em;
max-width: 10em;
+ width: 10em;
overflow: hidden;
direction: rtl;
white-space: nowrap;
text-indent: 0em;
}
+.documentableElement .docs {
+ width: 100%;
+ table-layout: fixed;
+}
+
.documentableElement .modifiers .other-modifiers {
color: gray;
}
@@ -514,8 +532,8 @@ footer .pull-right {
padding: 5px 4px 5px 4px;
font-weight: 500;
font-size: 12px;
- background: var(--code-bg);
- border: 0.25em solid white;
+ background: var(--documentable-bg);
+ border: 0.25em solid var(--body-bg);
}
.documentableElement>div {
@@ -524,12 +542,11 @@ footer .pull-right {
.expand.documentableElement>div {
display: block;
- padding-left: 3em;
}
.expand.documentableElement>div.header {
display: block;
- padding-left: 7.5em;
+ padding-left: 4.5em;
text-indent: -4.5em;
}