From 89cd6a308ed39b0b0af24773ce5d68e3f16efe03 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 19 Feb 2016 17:18:27 +0100 Subject: Add package view to scaladoc The package view shows the current package's: - siblings - children packages - path to root package - child entities (objects, traits, abstract types and classes) --- .../scala/tools/nsc/doc/html/page/Entity.scala | 95 ++++++++++++++-- .../tools/nsc/doc/html/resource/lib/index.css | 124 ++++++++++++++++++++- .../scala/tools/nsc/doc/html/resource/lib/index.js | 3 +- .../tools/nsc/doc/html/resource/lib/template.css | 4 + .../tools/nsc/doc/html/resource/lib/template.js | 6 + 5 files changed, 221 insertions(+), 11 deletions(-) (limited to 'src/scaladoc') diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala index 969e19c770..861dccc5dd 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala @@ -71,9 +71,74 @@ trait EntityPage extends HtmlPage {
-
-
- { content } +
+
+
+
+

Packages

+
    + { + def entityToUl(mbr: TemplateEntity with MemberEntity, indentation: Int): NodeSeq = +
  • + { + mbr match { + case dtpl: DocTemplateEntity => + dtpl.companion.fold() { c: DocTemplateEntity => + inlineToStr(com.short))}> + } + case _ => + } + } + inlineToStr(com.short))}> + inlineToStr(com.short))}> + {mbr.name} + +
  • + + // Get path from root + val rootToParentLis = tpl.toRoot + .tail + .reverse + .zipWithIndex + .map { case (pack, ind) => + memberToHtml(pack, tpl, indentation = ind, isParent = (pack eq tpl.toRoot.tail.head)) + } + + val parent = tpl.toRoot match { + case _ :: parent :: _ if !parent.isRootPackage => Some(parent) + case _ => None + } + + val parentSub = parent.fold(Seq[TemplateEntity with MemberEntity](tpl)) { p => + p.templates.filter(_.isPackage).sortBy(_.name) + } + + // If current entity is a package, take its containing entities - otherwise take parent's containing entities + val currentPackageTpls = + if (tpl.isPackage) tpl.templates + else parent.fold(Seq.empty[TemplateEntity with MemberEntity])(p => p.templates) + + val (subsToTpl, subsAfterTpl) = parentSub.partition(_.name <= tpl.name) + + val subsToTplLis = subsToTpl.map(memberToHtml(_, tpl, indentation = rootToParentLis.length)) + val subsAfterTplLis = subsAfterTpl.map(memberToHtml(_, tpl, indentation = rootToParentLis.length)) + val currEntityLis = currentPackageTpls + .filter(x => !x.isPackage && (x.isTrait || x.isClass || x.isAbstractType)) + .sortBy(_.name) + .map(entityToUl(_, rootToParentLis.length + 1)) + val currSubLis = tpl.templates + .filter(_.isPackage) + .sortBy(_.name) + .map(memberToHtml(_, tpl, indentation = rootToParentLis.length + 1)) + + rootToParentLis ++ subsToTplLis ++ currEntityLis ++ currSubLis ++ subsAfterTplLis + } +
+
+
+
+ { content } +
@@ -146,7 +211,6 @@ trait EntityPage extends HtmlPage {
{ val (src, alt) = docEntityKindToBigImage(tpl) - val identifier = alt.toString.substring(0,2).toLowerCase tpl.companion match { @@ -154,7 +218,8 @@ trait EntityPage extends HtmlPage {
{ identifier.substring(0,1) }
case _ =>
{ identifier.substring(0,1) }
- }} + } + } { owner }

{ displayName }

{ if (tpl.isPackage) NodeSeq.Empty else

{companionAndPackage(tpl)}

@@ -262,7 +327,13 @@ trait EntityPage extends HtmlPage { { if (concValueMembers.isEmpty) NodeSeq.Empty else

{ if (absValueMembers.isEmpty) "Value Members" else "Concrete Value Members" }

-
    { concValueMembers map (memberToHtml(_, tpl)) }
+
    + { + concValueMembers + .filter(_.kind != "package") + .map(memberToHtml(_, tpl)) + } +
} @@ -336,7 +407,12 @@ trait EntityPage extends HtmlPage { } - def memberToHtml(mbr: MemberEntity, inTpl: DocTemplateEntity): NodeSeq = { + def memberToHtml( + mbr: MemberEntity, + inTpl: DocTemplateEntity, + isParent: Boolean = false, + indentation: Int = 0 + ): NodeSeq = { // Sometimes it's same, do we need signatureCompat still? val sig = if (mbr.signature == mbr.signatureCompat) { @@ -346,6 +422,7 @@ trait EntityPage extends HtmlPage { val memberComment = memberToCommentHtml(mbr, inTpl, isSelf = false)
  • @@ -828,7 +905,9 @@ trait EntityPage extends HtmlPage { } } if (!nameLink.isEmpty) - {nameHtml} + inlineToStr(c.short))} href={nameLink}> + {nameHtml} + else nameHtml }{ def tparamsToHtml(mbr: Any): NodeSeq = mbr match { diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css index ea1c358149..cb11df3011 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css @@ -393,7 +393,7 @@ div#search-progress > div#progress-fill { color: #bbb; } -div#content-container { +div#content-scroll-container { position: absolute; top: 0; right: 0; @@ -404,14 +404,130 @@ div#content-container { overflow-y: auto; } +div#content-container { + max-width: 1140px; + margin: 0 auto; +} + div#content-container > div#content { -webkit-overflow-scrolling: touch; display: block; overflow-y: auto; - max-width: 1140px; margin: 5em auto 0; } +div#content-container > div#subpackage-spacer { + float: right; + height: 100%; + margin: 0.5rem 0.5rem 0 0.5em; + font-size: 0.8em; +} + +div#packages > h1 { + color: #103a51; +} + +div#packages > ul { + list-style-type: none; +} + +div#packages > ul > li { + position: relative; + margin: 0.5rem 0; + width: 100%; + border-radius: 0.2em; + min-height: 1.5em; + padding-left: 2em; +} + +div#packages > ul > li.current:hover { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + cursor: pointer; +} + +div#packages > ul > li > *:nth-child(1), +div#packages > ul > li > *:nth-child(2) { + float: left; + display: inline; + height: 1em; + width: 1em; + margin: 2px 0 0; + cursor: pointer; +} + +div#packages > ul > li > a.class { + background: url("class.svg") no-repeat center; + background-size: 0.9em; +} + +div#packages > ul > li > a.trait { + background: url("trait.svg") no-repeat center; + background-size: 0.9em; +} + +div#packages > ul > li > a.object { + background: url("object.svg") no-repeat center; + background-size: 0.9em; +} + +div#packages > ul > li > a.abstract.type { + background: url("abstract_type.svg") no-repeat center; + background-size: 0.9em; +} + +div#packages > ul > li > a { + text-decoration: none !important; + margin-left: 0.1em; +} + +/* Indentation levels for packages */ +div#packages > ul > li.indented0 { padding-left: 0em; } +div#packages > ul > li.indented1 { padding-left: 1em; } +div#packages > ul > li.indented2 { padding-left: 2em; } +div#packages > ul > li.indented3 { padding-left: 3em; } +div#packages > ul > li.indented4 { padding-left: 4em; } +div#packages > ul > li.indented5 { padding-left: 5em; } +div#packages > ul > li.indented6 { padding-left: 6em; } +div#packages > ul > li.indented7 { padding-left: 7em; } +div#packages > ul > li.indented8 { padding-left: 8em; } +div#packages > ul > li.indented9 { padding-left: 9em; } +div#packages > ul > li.indented10 { padding-left: 10em; } +div#packages > ul > li.current.indented0 { padding-left: -0.5em } +div#packages > ul > li.current.indented1 { padding-left: 0.5em } +div#packages > ul > li.current.indented2 { padding-left: 1.5em } +div#packages > ul > li.current.indented3 { padding-left: 2.5em } +div#packages > ul > li.current.indented4 { padding-left: 3.5em } +div#packages > ul > li.current.indented5 { padding-left: 4.5em } +div#packages > ul > li.current.indented6 { padding-left: 5.5em } +div#packages > ul > li.current.indented7 { padding-left: 6.5em } +div#packages > ul > li.current.indented8 { padding-left: 7.5em } +div#packages > ul > li.current.indented9 { padding-left: 8.5em } +div#packages > ul > li.current.indented10 { padding-left: 9.5em } + +div#packages > ul > li.current > span.symbol { + border-left: 0.25em solid #72D0EB; + padding-left: 0.25em; +} + +div#packages > ul > li > span.symbol > a { + text-decoration: none; +} + +div#packages > ul > li > span.symbol > span.name { + font-weight: normal; +} + +div#packages > ul > li .fullcomment, +div#packages > ul > li .modifier_kind, +div#packages > ul > li .permalink, +div#packages > ul > li .shortcomment { + display: none; +} + div#search-results { color: #103a51; position: absolute; @@ -710,6 +826,10 @@ only screen /* iPhone 6 */ and (max-device-width: 667px) and (-webkit-device-pixel-ratio: 2) { + div#content-container > div#subpackage-spacer { + display: none; + } + div#content-container > div#content { margin: 3.3em auto 0; } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js index caa6406bc5..494ad91cc8 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js @@ -98,7 +98,7 @@ function handleKeyNavigation() { scroller.scrollDown = function($elem) { var yPos = $elem.offset().top; // offset relative to viewport - if ($container.height() < yPos) { + if ($container.height() < yPos || (yPos - $("#search").height()) < 0) { $container.animate({ scrollTop: $container.scrollTop() + yPos - $("#search").height() - 10 }, 200); @@ -132,6 +132,7 @@ function handleKeyNavigation() { var $old = items.next(); $old.addClass("selected"); + scroller.scrollDown($old); $(window).bind("keydown", function(e) { switch ( e.keyCode ) { diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css index 2265f8f045..1827868171 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css @@ -133,6 +133,10 @@ body.trait div#definition { padding-left: 0; } +span.symbol > a { + display: inline-block; +} + #signature > span.symbol { text-align: left; display: inline; diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js index b0719b1ed5..ebffe81490 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js @@ -27,6 +27,12 @@ $(document).ready(function() { } }); + var oldWidth = $("div#subpackage-spacer").width() + 1 + "px"; + $("div#packages > ul > li.current").click(function() { + $("div#subpackage-spacer").css({ "width": oldWidth }); + $("li.current-entities").toggle(); + }); + var controls = { visibility: { publicOnly: $("#visbl").find("> ol > li.public"), -- cgit v1.2.3