From e6f95d547f676079eca2e6192c21adc036ecfa15 Mon Sep 17 00:00:00 2001 From: Andrzej Ratajczak Date: Fri, 19 Mar 2021 12:25:47 +0100 Subject: [PATCH 1/3] Start work on handling hide directives in code snippets --- scaladoc-js/src/Main.scala | 1 + .../code-snippets/CodeSnippets.scala | 17 ++++++++++++++ .../src/tests/methodsAndConstructors.scala | 22 +++++++++++++++++++ .../tasty/comments/MemberLookup.scala | 5 ++++- 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala 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..1a15edca5631 --- /dev/null +++ b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala @@ -0,0 +1,17 @@ +package dotty.tools.scaladoc + +import org.scalajs.dom._ +import org.scalajs.dom.ext._ + +class CodeSnippets: + val replacePatternsAndResults = Seq( + // ("", ""), // hide block directives + ("""(\/\/.*)(\n|\$)""", ""), // single line comment + // ("", ""), // multi line comment + ) + + document.querySelectorAll("code").foreach { + case e: html.Element => e.innerHTML = replacePatternsAndResults.foldLeft(e.innerHTML) { + case (acc, (pattern, result)) => acc.replaceAll(pattern, """$1""") + } + } diff --git a/scaladoc-testcases/src/tests/methodsAndConstructors.scala b/scaladoc-testcases/src/tests/methodsAndConstructors.scala index d0f3386730bc..1bd88d5d7609 100644 --- a/scaladoc-testcases/src/tests/methodsAndConstructors.scala +++ b/scaladoc-testcases/src/tests/methodsAndConstructors.scala @@ -1,5 +1,27 @@ package tests.methodsAndConstructors + +/** + * This is my codeblock + * + * ``` + * //{{ + * import xd + * import xd2 + * //}} + * + * + * val x = 1 // This is my valid comment + * + * /* + * Is this my comment? + * */ + * + * val y = 2 + * ``` + * + * The end of my codeblock + */ class A class B extends A class C diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala index dff2d6a33589..c17531a5e895 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala @@ -148,7 +148,10 @@ trait MemberLookup { } if owner.isPackageDef then - findMatch(hackMembersOf(owner)) + findMatch(hackMembersOf(owner).flatMap { + s => + (if s.name.endsWith("package$") then hackMembersOf(s) else Iterator.empty) ++ Iterator(s) + }) else owner.tree match { case tree: ClassDef => From 1dd064d5537b0fe89ecca70dbb6829905e8f482a Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Fri, 19 Mar 2021 18:19:05 +0100 Subject: [PATCH 2/3] Hide irrelevant code snippet fragments in scaladoc --- scaladoc-js/resources/scaladoc-searchbar.css | 7 ++++- .../code-snippets/CodeSnippets.scala | 30 +++++++++++++++--- .../src/tests/methodsAndConstructors.scala | 22 ------------- .../src/tests/snippetComments.scala | 31 +++++++++++++++++++ .../tasty/comments/MemberLookup.scala | 5 +-- 5 files changed, 63 insertions(+), 32 deletions(-) create mode 100644 scaladoc-testcases/src/tests/snippetComments.scala diff --git a/scaladoc-js/resources/scaladoc-searchbar.css b/scaladoc-js/resources/scaladoc-searchbar.css index 035adbee6555..a99e02cd805e 100644 --- a/scaladoc-js/resources/scaladoc-searchbar.css +++ b/scaladoc-js/resources/scaladoc-searchbar.css @@ -100,5 +100,10 @@ .pull-right { float: right; - margin-left: auto + margin-left: auto; +} + +.hide-snippet-comments-button { + position: absolute; + left: 90%; } diff --git a/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala index 1a15edca5631..8beff5ec3a46 100644 --- a/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala +++ b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala @@ -4,14 +4,34 @@ import org.scalajs.dom._ import org.scalajs.dom.ext._ class CodeSnippets: - val replacePatternsAndResults = Seq( - // ("", ""), // hide block directives - ("""(\/\/.*)(\n|\$)""", ""), // single line comment - // ("", ""), // multi line comment + 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, """$1""") + 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 => + val a = document.createElement("a") + a.textContent = "Show" + a.addEventListener("click", { (_: MouseEvent) => + a.textContent = if a.textContent == "Show" then "Hide" else "Show" + toggleHide(e) + }) + a.classList.add("hide-snippet-comments-button") + e.insertBefore(a, e.firstChild) + } diff --git a/scaladoc-testcases/src/tests/methodsAndConstructors.scala b/scaladoc-testcases/src/tests/methodsAndConstructors.scala index 1bd88d5d7609..d0f3386730bc 100644 --- a/scaladoc-testcases/src/tests/methodsAndConstructors.scala +++ b/scaladoc-testcases/src/tests/methodsAndConstructors.scala @@ -1,27 +1,5 @@ package tests.methodsAndConstructors - -/** - * This is my codeblock - * - * ``` - * //{{ - * import xd - * import xd2 - * //}} - * - * - * val x = 1 // This is my valid comment - * - * /* - * Is this my comment? - * */ - * - * val y = 2 - * ``` - * - * The end of my codeblock - */ class A class B extends A class C diff --git a/scaladoc-testcases/src/tests/snippetComments.scala b/scaladoc-testcases/src/tests/snippetComments.scala new file mode 100644 index 000000000000..c7c229c7d0a2 --- /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 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/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala index c17531a5e895..dff2d6a33589 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/MemberLookup.scala @@ -148,10 +148,7 @@ trait MemberLookup { } if owner.isPackageDef then - findMatch(hackMembersOf(owner).flatMap { - s => - (if s.name.endsWith("package$") then hackMembersOf(s) else Iterator.empty) ++ Iterator(s) - }) + findMatch(hackMembersOf(owner)) else owner.tree match { case tree: ClassDef => From fc99877a42b7f18cf6a721bc0905ead5fbe63cc0 Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Tue, 23 Mar 2021 16:21:08 +0100 Subject: [PATCH 3/3] Apply review suggestions from PR #11822 --- scaladoc-js/resources/scaladoc-searchbar.css | 26 +++++++++++++++-- .../code-snippets/CodeSnippets.scala | 14 ++++++--- .../src/tests/snippetComments.scala | 2 +- .../resources/dotty_res/styles/scalastyle.css | 29 +++++++++++++++---- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/scaladoc-js/resources/scaladoc-searchbar.css b/scaladoc-js/resources/scaladoc-searchbar.css index a99e02cd805e..7f708b338fe8 100644 --- a/scaladoc-js/resources/scaladoc-searchbar.css +++ b/scaladoc-js/resources/scaladoc-searchbar.css @@ -103,7 +103,29 @@ margin-left: auto; } -.hide-snippet-comments-button { +.snippet-comment-button { position: absolute; - left: 90%; + 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/searchbar/code-snippets/CodeSnippets.scala b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala index 8beff5ec3a46..b6ed3d476887 100644 --- a/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala +++ b/scaladoc-js/src/searchbar/code-snippets/CodeSnippets.scala @@ -25,13 +25,19 @@ class CodeSnippets: toggleHide(document) document.querySelectorAll("pre").foreach { - case e: html.Element => + case e: html.Element if e.querySelectorAll("code span.hideable").nonEmpty => val a = document.createElement("a") - a.textContent = "Show" a.addEventListener("click", { (_: MouseEvent) => - a.textContent = if a.textContent == "Show" then "Hide" else "Show" + 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("hide-snippet-comments-button") + 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 index c7c229c7d0a2..39b15648103e 100644 --- a/scaladoc-testcases/src/tests/snippetComments.scala +++ b/scaladoc-testcases/src/tests/snippetComments.scala @@ -16,7 +16,7 @@ package tests.snippetComments * /* * multi line comment * */ - * + * val reallyFLongDeclaration = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" * val y = 2 // comment in the same line * // comment in new line * val z = 3 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; }