Skip to content

Commit 18c84fc

Browse files
authored
Merge pull request #10795 from romanowski/scala3doc/member-grouping
Add support from member groupping and render html more directly
2 parents b3486ac + 5ee1c7e commit 18c84fc

35 files changed

+685
-1222
lines changed

project/Build.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,13 @@ object Build {
15271527
def generateDocumentation(targets: String, name: String, outDir: String, ref: String, params: String = "") = Def.taskDyn {
15281528
val projectVersion = version.value
15291529
IO.createDirectory(file(outDir))
1530-
val sourcesAndRevision = s"-source-links github://lampepfl/dotty -revision $ref -project-version $projectVersion"
1530+
val managedSources =
1531+
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "scala-library-src"
1532+
val projectRoot = (ThisBuild/baseDirectory).value.toPath
1533+
val stdLibRoot = projectRoot.relativize(managedSources.toPath.normalize())
1534+
val scalaSourceLink =
1535+
s"$stdLibRoot=github://scala/scala/v${stdlibVersion(Bootstrapped)}#src/library"
1536+
val sourcesAndRevision = s"-source-links $scalaSourceLink,github://lampepfl/dotty -revision $ref -project-version $projectVersion"
15311537
val cmd = s""" -d $outDir -project "$name" $sourcesAndRevision $params $targets"""
15321538
run.in(Compile).toTask(cmd)
15331539
}

scala3doc/resources/dotty_res/scripts/components/DocumentableList.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ class DocumentableList extends Component {
99
super(props);
1010

1111
this.refs = {
12-
tabs: findRefs(".section-tab[data-togglable]", findRef(".tabbedcontent")),
13-
sections: findRefs("div[data-togglable]", findRef(".tabbedcontent")),
12+
tabs: findRefs(".names .tab[data-togglable]", findRef(".membersList")).concat(
13+
findRefs(".contents h2[data-togglable]", findRef(".membersList"))
14+
),
15+
sections: findRefs(".contents .tab[data-togglable]", findRef(".membersList")),
1416
};
1517

1618
this.state = {
@@ -24,14 +26,12 @@ class DocumentableList extends Component {
2426
ref.dataset.visibility = isVisible
2527
}
2628

27-
toggleDisplayStyles(condition, ref, onVisibleStyle) {
28-
ref.style.display = condition ? onVisibleStyle : 'none'
29+
toggleDisplayStyles(condition, ref) {
30+
ref.style.display = condition ? null : 'none'
2931
}
3032

3133
render({ filter }) {
3234
this.state.list.sectionsRefs.map(sectionRef => {
33-
const tabRef = this.state.list.getTabRefFromSectionRef(sectionRef);
34-
3535
const isTabVisible = this.state.list
3636
.getSectionListRefs(sectionRef)
3737
.filter((listRef) => {
@@ -41,23 +41,26 @@ class DocumentableList extends Component {
4141
.filter(elementData => {
4242
const isElementVisible = this.state.list.isElementVisible(elementData, filter);
4343

44-
this.toggleDisplayStyles(isElementVisible, elementData.ref, "table");
44+
this.toggleDisplayStyles(isElementVisible, elementData.ref);
4545
this.toggleElementDatasetVisibility(isElementVisible, elementData.ref);
4646

4747
return isElementVisible;
4848
}).length;
4949

50-
this.toggleDisplayStyles(isListVisible, listRef, "block");
50+
this.toggleDisplayStyles(isListVisible, listRef);
5151

5252
return isListVisible;
5353
}).length;
5454

55-
this.toggleDisplayStyles(isTabVisible, tabRef, "inline-block");
55+
const outerThis = this
56+
this.state.list.getTabRefFromSectionRef(sectionRef).forEach(function(tabRef){
57+
outerThis.toggleDisplayStyles(isTabVisible, tabRef);
58+
})
5659
});
5760
}
5861
}
5962

60-
class List {
63+
class List {
6164
/**
6265
* @param tabsRef { Element[] }
6366
* @param sectionRefs { Element[] }
@@ -78,15 +81,15 @@ class List {
7881
/**
7982
* @param name { string }
8083
*/
81-
filterTab(name) {
84+
filterTab(name) {
8285
return name !== "Linear supertypes" && name !== "Known subtypes" && name !== "Type hierarchy"
8386
}
8487

8588
/**
8689
* @param sectionRef { Element }
8790
*/
8891
getTabRefFromSectionRef(sectionRef) {
89-
return this.tabsRefs.find(
92+
return this.tabsRefs.filter(
9093
(tabRef) => this._getTogglable(tabRef) === this._getTogglable(sectionRef)
9194
);
9295
}
@@ -124,8 +127,8 @@ class List {
124127
* @param filter { Filter }
125128
*/
126129
isElementVisible(elementData, filter) {
127-
return !areFiltersFromElementSelected()
128-
? false
130+
return !areFiltersFromElementSelected()
131+
? false
129132
: includesInputValue()
130133

131134
function includesInputValue() {
@@ -141,7 +144,7 @@ class List {
141144
.filter(([key]) => !!filter.filters[getFilterKey(key)])
142145

143146
/** @type { Dataset } */
144-
const defaultFiltersForMembersWithoutDataAttribute =
147+
const defaultFiltersForMembersWithoutDataAttribute =
145148
defaultFilters.reduce((acc, [key, value]) => {
146149
const filterKey = getFilterKey(key)
147150
const shouldAddDefaultFilter = !dataset.some(([k]) => k === filterKey)
@@ -156,7 +159,7 @@ class List {
156159
return defaultFilter ? [k, `${v},${defaultFilter[1]}`] : [k, v]
157160
})
158161

159-
const datasetWithDefaultFilters = [
162+
const datasetWithDefaultFilters = [
160163
...defaultFiltersForMembersWithoutDataAttribute,
161164
...datasetWithAppendedDefaultFilters
162165
]

scala3doc/resources/dotty_res/scripts/components/Filter.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class Filter {
147147
const newFilters = this._elementsRefs.reduce((filtersObject, elementRef) => {
148148
this._getDatasetWithKeywordData(elementRef.dataset).forEach(([key, value]) =>
149149
this._splitByComma(value).forEach((val) => {
150-
filtersObject[key] = filtersObject[key]
150+
filtersObject[key] = filtersObject[key]
151151
? { ...filtersObject[key], [val]: filtersObject[key][val] ?? new FilterItem() }
152152
: { [val]: new FilterItem() }
153153
})
@@ -161,21 +161,21 @@ class Filter {
161161
/**
162162
* @private
163163
* @param {Filters} newFilters
164-
* @returns {Filters}
164+
* @returns {Filters}
165165
*/
166166
_attachDefaultFilters(newFilters) {
167167
return Object.entries(Filter.defaultFilters).reduce((acc, [key, defaultFilter]) => {
168168
const filterKey = getFilterKey(key)
169169
const shouldAddDefaultKeywordFilter = this._elementsRefs.some(ref => !!ref.dataset[filterKey])
170-
171-
return shouldAddDefaultKeywordFilter
172-
? {
173-
...acc,
174-
[filterKey]: {
175-
...acc[filterKey],
176-
[defaultFilter]: new FilterItem()
177-
}
178-
}
170+
171+
return shouldAddDefaultKeywordFilter
172+
? {
173+
...acc,
174+
[filterKey]: {
175+
...acc[filterKey],
176+
[defaultFilter]: new FilterItem()
177+
}
178+
}
179179
: acc
180180
}, newFilters)
181181
}
Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +0,0 @@
1-
$("#inheritance-diagram").ready(function() {
2-
if ($("svg#graph").children().length == 0) {
3-
var dotNode = document.querySelector("#dot")
4-
if (dotNode){
5-
var svg = d3.select("#graph");
6-
var inner = svg.append("g");
7-
8-
// Set up zoom support
9-
var zoom = d3.zoom()
10-
.on("zoom", function({transform}) {
11-
inner.attr("transform", transform);
12-
});
13-
svg.call(zoom);
14-
15-
var render = new dagreD3.render();
16-
var g = graphlibDot.read(dotNode.text);
17-
g.graph().rankDir = 'BT';
18-
g.nodes().forEach(function (v) {
19-
g.setNode(v, {
20-
labelType: "html",
21-
label: g.node(v).label,
22-
style: g.node(v).style
23-
});
24-
});
25-
g.edges().forEach(function(v) {
26-
g.setEdge(v, {
27-
arrowhead: "vee"
28-
});
29-
});
30-
render(inner, g);
31-
}
32-
}
33-
})

scala3doc/resources/dotty_res/scripts/ux.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ window.addEventListener("DOMContentLoaded", () => {
1919
$(this).parent().toggleClass("expanded")
2020
});
2121

22+
$('.names .tab').on('click', function(){
23+
parent = $(this).parents(".tabs").first()
24+
shown = $(this).hasClass('selected')
25+
single = parent.hasClass("single")
26+
27+
if (single) parent.find(".tab.selected").removeClass('selected')
28+
29+
id = $(this).attr('data-togglable')
30+
myTab = parent.find("[data-togglable='" + id + "'].tab")
31+
if (!shown) { myTab.addClass('selected') }
32+
if (shown && !single) myTab.removeClass('selected')
33+
34+
if(!shown && $(this).find(".showGraph")){
35+
showGraph()
36+
$(this).find(".showGraph").removeClass("showGraph")
37+
}
38+
})
2239

2340
if (location.hash) {
2441
var selected = document.getElementById(location.hash.substring(1));
@@ -37,3 +54,37 @@ window.addEventListener("DOMContentLoaded", () => {
3754
hljs.registerAliases(["dotty", "scala3"], "scala");
3855
hljs.initHighlighting();
3956
});
57+
58+
function showGraph() {
59+
if ($("svg#graph").children().length == 0) {
60+
var dotNode = document.querySelector("#dot")
61+
if (dotNode){
62+
var svg = d3.select("#graph");
63+
var inner = svg.append("g");
64+
65+
// Set up zoom support
66+
var zoom = d3.zoom()
67+
.on("zoom", function({transform}) {
68+
inner.attr("transform", transform);
69+
});
70+
svg.call(zoom);
71+
72+
var render = new dagreD3.render();
73+
var g = graphlibDot.read(dotNode.text);
74+
g.graph().rankDir = 'BT';
75+
g.nodes().forEach(function (v) {
76+
g.setNode(v, {
77+
labelType: "html",
78+
label: g.node(v).label,
79+
style: g.node(v).style
80+
});
81+
});
82+
g.edges().forEach(function(v) {
83+
g.setEdge(v, {
84+
arrowhead: "vee"
85+
});
86+
});
87+
render(inner, g);
88+
}
89+
}
90+
}

scala3doc/resources/dotty_res/styles/scalastyle.css

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ footer .pull-right {
461461
}
462462

463463

464-
.modifiers {
464+
.documentableElement .modifiers {
465465
display: table-cell;
466466
padding-right: 0.5em;
467467
min-width: 10em;
@@ -472,23 +472,27 @@ footer .pull-right {
472472
text-indent: 0em;
473473
}
474474

475-
.modifiers .other-modifiers {
475+
.documentableElement .modifiers .other-modifiers {
476476
color: gray;
477477
}
478478

479+
.kind {
480+
margin-left: 0.5em;
481+
}
482+
479483
.other-modifiers a, .other-modifiers a:visited, .other-modifiers span[data-unresolved-link] {
480484
color: var(--link-sig-fd);
481485
}
482486

483-
.expand .modifiers {
487+
.documentableElement.expand .modifiers {
484488
display: inline-table;
485489
min-width: 7em;
486490
}
487491

488-
.signature {
492+
.documentableElement .signature {
489493
color: gray;
490494
display: table-cell;
491-
padding-left: 0.5em;
495+
white-space: pre-wrap;
492496
}
493497

494498
.signature a, .signature a:visited, .signature span[data-unresolved-link] {
@@ -551,12 +555,12 @@ footer .pull-right {
551555
.expand.documentableElement {
552556
border-left: 0.25em solid var(--leftbar-bg);
553557
}
554-
.annotations {
558+
.documentableElement .annotations {
555559
color: gray;
556560
display: none;
557561
}
558562

559-
.expand .annotations {
563+
.documentableElement.expand .annotations {
560564
display: inline-block;
561565
}
562566

@@ -575,6 +579,39 @@ footer .pull-right {
575579
margin: .5em 0 0 0;
576580
}
577581

582+
.tabs .names .tab {
583+
border: none;
584+
outline: none;
585+
background: transparent;
586+
padding: 0 6px 4px 6px;
587+
margin: 1rem 1rem 0 0;
588+
border-bottom: 1px solid grey;
589+
cursor: pointer;
590+
}
591+
592+
.tabs .names .tab.selected {
593+
color: unset;
594+
font-weight: bold;
595+
border-bottom: 2px solid var(--active-tab-color);
596+
}
597+
598+
.tabs .names {
599+
margin-bottom: 20px;
600+
}
601+
602+
.tabs .contents .tab{
603+
display: none;
604+
}
605+
606+
.tabs .contents .tab.selected {
607+
display: block;
608+
}
609+
610+
.diagram-class {
611+
width: 100%;
612+
max-height: 400px;
613+
}
614+
578615
/* Large Screens */
579616
@media(min-width: 1100px) {
580617
:root {

scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
6262
.overrideExtension(dokkaBase.getModulesAndPackagesDocumentation)
6363
)
6464

65-
val ourSignatureProvider = extend(
66-
_.extensionPoint(dokkaBase.getSignatureProvider)
67-
.fromRecipe{ case ctx @ given DokkaContext =>
68-
new ScalaSignatureProvider(ctx.single(dokkaBase.getCommentsToContentConverter))
69-
}.overrideExtension(dokkaBase.getKotlinSignatureProvider)
70-
)
71-
7265
val scalaResourceInstaller = extend(
7366
_.extensionPoint(dokkaBase.getHtmlPreprocessors)
7467
.fromRecipe{ case ctx @ given DokkaContext => new ScalaResourceInstaller }

scala3doc/src/dotty/dokka/IO.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.io.*;
44
import java.nio.file.*;
55
import java.nio.file.attribute.BasicFileAttributes;
6+
import java.util.function.Consumer;
7+
import java.nio.charset.Charset;
68

79
/** This code is mostly using public snippets and tries to mimic sbt-io api. */
810
public class IO {
@@ -25,4 +27,20 @@ public FileVisitResult visitFile(
2527
}
2628
});
2729
}
30+
31+
public static void foreachFileIn(Path dir, Consumer<Path> op) throws IOException {
32+
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
33+
@Override
34+
public FileVisitResult visitFile(
35+
Path file, BasicFileAttributes attrs)
36+
throws IOException {
37+
op.accept(file);
38+
return FileVisitResult.CONTINUE;
39+
}
40+
});
41+
}
42+
43+
public static String read(Path path) throws IOException {
44+
return new String(Files.readAllBytes(path), Charset.defaultCharset());
45+
}
2846
}

0 commit comments

Comments
 (0)