diff options
author | Vlad Ureche <vlad.ureche@epfl.ch> | 2016-02-26 21:54:00 +0100 |
---|---|---|
committer | Vlad Ureche <vlad.ureche@epfl.ch> | 2016-02-26 21:54:00 +0100 |
commit | 239d76f21520b17c1a1866e7d2b518f6952d84b1 (patch) | |
tree | 861096fa71cc4b5037c42f94390177f5f1328d48 | |
parent | e891bb60f721465bfe497b16f5ef440de0a7d5e5 (diff) | |
parent | 89cd6a308ed39b0b0af24773ce5d68e3f16efe03 (diff) | |
download | scala-239d76f21520b17c1a1866e7d2b518f6952d84b1.tar.gz scala-239d76f21520b17c1a1866e7d2b518f6952d84b1.tar.bz2 scala-239d76f21520b17c1a1866e7d2b518f6952d84b1.zip |
Merge pull request #4983 from felixmulder/topic/scaladoc-package-view
Add package view to scaladoc
6 files changed, 221 insertions, 16 deletions
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 { <div id="member-results"></div> </div> </div> - <div id="content-container" style="-webkit-overflow-scrolling: touch;"> - <div id="content"> - { content } + <div id="content-scroll-container" style="-webkit-overflow-scrolling: touch;"> + <div id="content-container" style="-webkit-overflow-scrolling: touch;"> + <div id="subpackage-spacer"> + <div id="packages"> + <h1>Packages</h1> + <ul> + { + def entityToUl(mbr: TemplateEntity with MemberEntity, indentation: Int): NodeSeq = + <li class={"current-entities indented" + indentation}> + { + mbr match { + case dtpl: DocTemplateEntity => + dtpl.companion.fold(<span class="separator"></span>) { c: DocTemplateEntity => + <a class="object" href={relativeLinkTo(c)} title={c.comment.fold("")(com => inlineToStr(com.short))}></a> + } + case _ => <span class="separator"></span> + } + } + <a class={mbr.kind} href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => inlineToStr(com.short))}></a> + <a href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => inlineToStr(com.short))}> + {mbr.name} + </a> + </li> + + // 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 + } + </ul> + </div> + </div> + <div id="content"> + { content } + </div> </div> </div> </body> @@ -146,7 +211,6 @@ trait EntityPage extends HtmlPage { <div id="definition"> { val (src, alt) = docEntityKindToBigImage(tpl) - val identifier = alt.toString.substring(0,2).toLowerCase tpl.companion match { @@ -154,7 +218,8 @@ trait EntityPage extends HtmlPage { <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><div class={s"big-circle companion $identifier"}>{ identifier.substring(0,1) }</div></a> case _ => <div class={ "big-circle " + alt.toString.toLowerCase }>{ identifier.substring(0,1) }</div> - }} + } + } { owner } <h1>{ displayName }</h1>{ if (tpl.isPackage) NodeSeq.Empty else <h3>{companionAndPackage(tpl)}</h3> @@ -262,7 +327,13 @@ trait EntityPage extends HtmlPage { { if (concValueMembers.isEmpty) NodeSeq.Empty else <div class="values members"> <h3>{ if (absValueMembers.isEmpty) "Value Members" else "Concrete Value Members" }</h3> - <ol>{ concValueMembers map (memberToHtml(_, tpl)) }</ol> + <ol> + { + concValueMembers + .filter(_.kind != "package") + .map(memberToHtml(_, tpl)) + } + </ol> </div> } @@ -336,7 +407,12 @@ trait EntityPage extends HtmlPage { </body> } - 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) { <a id={ mbr.signature }/> @@ -346,6 +422,7 @@ trait EntityPage extends HtmlPage { val memberComment = memberToCommentHtml(mbr, inTpl, isSelf = false) <li name={ mbr.definitionName } visbl={ if (mbr.visibility.isProtected) "prt" else "pub" } + class={ s"indented$indentation " + (if (mbr eq inTpl) "current" else "") } data-isabs={ mbr.isAbstract.toString } fullComment={ if(memberComment.filter(_.label=="div").isEmpty) "no" else "yes" } group={ mbr.group }> @@ -828,7 +905,9 @@ trait EntityPage extends HtmlPage { } } if (!nameLink.isEmpty) - <a href={nameLink}>{nameHtml}</a> + <a title={mbr.comment.fold("")(c => inlineToStr(c.short))} href={nameLink}> + {nameHtml} + </a> 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"), diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala index daa7de8545..3fe5ef3baf 100644 --- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala +++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala @@ -797,11 +797,6 @@ object Test extends Properties("HtmlFactory") { case _ => false } - property("SI-8144: Members' permalink - package") = check("some/index.html") { node => - ("type link" |: node.assertTypeLink("../some/index.html")) && - ("member: some.pack" |: node.assertValuesLink("some.pack", "../some/index.html#pack")) - } - property("SI-8144: Members' permalink - inner package") = check("some/pack/index.html") { node => ("type link" |: node.assertTypeLink("../../some/pack/index.html")) && ("member: SomeType (object)" |: node.assertValuesLink("some.pack.SomeType", "../../some/pack/index.html#SomeType")) && |