diff options
Diffstat (limited to 'src/scaladoc')
32 files changed, 691 insertions, 1522 deletions
diff --git a/src/scaladoc/scala/tools/ant/Scaladoc.scala b/src/scaladoc/scala/tools/ant/Scaladoc.scala index b38aadd328..63d3b4ce27 100644 --- a/src/scaladoc/scala/tools/ant/Scaladoc.scala +++ b/src/scaladoc/scala/tools/ant/Scaladoc.scala @@ -14,8 +14,8 @@ import org.apache.tools.ant.Project import org.apache.tools.ant.types.{Path, Reference} import org.apache.tools.ant.util.{FileUtils, GlobPatternMapper} +import scala.tools.nsc.ScalaDocReporter import scala.tools.nsc.doc.Settings -import scala.tools.nsc.reporters.ConsoleReporter /** An Ant task to document Scala code. * @@ -666,7 +666,7 @@ class Scaladoc extends ScalaMatchingTask { /** Performs the compilation. */ override def execute() = { val (docSettings, sourceFiles) = initialize - val reporter = new ConsoleReporter(docSettings) + val reporter = new ScalaDocReporter(docSettings) try { val docProcessor = new scala.tools.nsc.doc.DocFactory(reporter, docSettings) docProcessor.document(sourceFiles.map (_.toString)) diff --git a/src/scaladoc/scala/tools/nsc/ScalaDoc.scala b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala index bd00c27f7b..e266f7beea 100644 --- a/src/scaladoc/scala/tools/nsc/ScalaDoc.scala +++ b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala @@ -8,7 +8,8 @@ package scala.tools.nsc import scala.tools.nsc.doc.DocFactory import scala.tools.nsc.reporters.ConsoleReporter -import scala.reflect.internal.util.FakePos +import scala.reflect.internal.Reporter +import scala.reflect.internal.util.{ FakePos, NoPosition, Position } /** The main class for scaladoc, a front-end for the Scala compiler * that generates documentation from source files. @@ -38,23 +39,43 @@ class ScalaDoc { reporter.echo(command.usageMsg) else try { new DocFactory(reporter, docSettings) document command.files } - catch { - case ex @ FatalError(msg) => - if (docSettings.debug.value) ex.printStackTrace() - reporter.error(null, "fatal error: " + msg) - } - finally reporter.printSummary() + catch { + case ex @ FatalError(msg) => + if (docSettings.debug.value) ex.printStackTrace() + reporter.error(null, "fatal error: " + msg) + } + finally reporter.printSummary() !reporter.reallyHasErrors } } +/** The Scaladoc reporter adds summary messages to the `ConsoleReporter` + * + * Use the `summaryX` methods to add unique summarizing message to the end of + * the run. + */ class ScalaDocReporter(settings: Settings) extends ConsoleReporter(settings) { + import scala.collection.mutable.LinkedHashMap // need to do sometimes lie so that the Global instance doesn't // trash all the symbols just because there was an error override def hasErrors = false def reallyHasErrors = super.hasErrors + + private[this] val delayedMessages: LinkedHashMap[(Position, String), () => Unit] = + LinkedHashMap.empty + + /** Eliminates messages if both `pos` and `msg` are equal to existing element */ + def addDelayedMessage(pos: Position, msg: String, print: () => Unit): Unit = + delayedMessages += ((pos, msg) -> print) + + def printDelayedMessages(): Unit = delayedMessages.values.foreach(_.apply()) + + override def printSummary(): Unit = { + printDelayedMessages() + super.printSummary() + } } object ScalaDoc extends ScalaDoc { @@ -70,4 +91,20 @@ object ScalaDoc extends ScalaDoc { def main(args: Array[String]): Unit = sys exit { if (process(args)) 0 else 1 } + + implicit class SummaryReporter(val rep: Reporter) extends AnyVal { + /** Adds print lambda to ScalaDocReporter, executes it on other reporter */ + private[this] def summaryMessage(pos: Position, msg: String, print: () => Unit): Unit = rep match { + case r: ScalaDocReporter => r.addDelayedMessage(pos, msg, print) + case _ => print() + } + + def summaryEcho(pos: Position, msg: String): Unit = summaryMessage(pos, msg, () => rep.echo(pos, msg)) + def summaryError(pos: Position, msg: String): Unit = summaryMessage(pos, msg, () => rep.error(pos, msg)) + def summaryWarning(pos: Position, msg: String): Unit = summaryMessage(pos, msg, () => rep.warning(pos, msg)) + + def summaryEcho(msg: String): Unit = summaryEcho(NoPosition, msg) + def summaryError(msg: String): Unit = summaryError(NoPosition, msg) + def summaryWarning(msg: String): Unit = summaryWarning(NoPosition, msg) + } } diff --git a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala index 47ddfb8aa9..8c646be9c6 100644 --- a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala @@ -6,8 +6,8 @@ package scala.tools.nsc package doc -import scala.util.control.ControlThrowable import reporters.Reporter +import scala.util.control.ControlThrowable import scala.reflect.internal.util.BatchSourceFile /** A documentation processor controls the process of generating Scala @@ -105,17 +105,24 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor def generate() = { import doclet._ val docletClass = Class.forName(settings.docgenerator.value) // default is html.Doclet - val docletInstance = docletClass.newInstance().asInstanceOf[Generator] + val docletInstance = + docletClass + .getConstructors + .find { constr => + constr.getParameterTypes.length == 1 && + constr.getParameterTypes.apply(0) == classOf[scala.reflect.internal.Reporter] + } + .map(_.newInstance(reporter)) + .getOrElse{ + reporter.warning(null, "Doclets should be created with the Reporter constructor, otherwise logging reporters will not be shared by the creating parent") + docletClass.newInstance() + } + .asInstanceOf[Generator] docletInstance match { case universer: Universer => val universe = makeUniverse(Left(files)) getOrElse { throw NoCompilerRunException } universer setUniverse universe - - docletInstance match { - case indexer: Indexer => indexer setIndex model.IndexModelFactory.makeIndex(universe) - case _ => () - } case _ => () } docletInstance.generate() diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index 8a341a92d5..59380dd782 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -14,6 +14,9 @@ import scala.language.postfixOps * @param printMsg A function that prints the string, without any extra boilerplate of error */ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) extends scala.tools.nsc.Settings(error) { + // TODO 2.13 Remove + private def removalIn213 = "This flag is scheduled for removal in 2.13. If you have a case where you need this flag then please report a bug." + /** A setting that defines in which format the documentation is output. ''Note:'' this setting is currently always * `html`. */ val docformat = ChoiceSetting ( @@ -45,7 +48,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) val docfooter = StringSetting ( "-doc-footer", "footer", - "A footer on every Scaladoc page, by default the EPFL/Typesafe copyright notice. Can be overridden with a custom footer.", + "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", "" ) @@ -199,10 +202,11 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) "" ) + // TODO 2.13 Remove val docExpandAllTypes = BooleanSetting ( "-expand-all-types", "Expand all type aliases and abstract types into full template pages. (locally this can be done with the @template annotation)" - ) + ) withDeprecationMessage(removalIn213) val docGroups = BooleanSetting ( "-groups", diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala index 707d0c469f..d3b4bf8ff5 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -47,7 +47,8 @@ trait CommentFactoryBase { this: MemberLookupBase => groupDesc0: Map[String,Body] = Map.empty, groupNames0: Map[String,Body] = Map.empty, groupPrio0: Map[String,Body] = Map.empty, - hideImplicitConversions0: List[Body] = List.empty + hideImplicitConversions0: List[Body] = List.empty, + shortDescription0: List[Body] = List.empty ): Comment = new Comment { val body = body0 getOrElse Body(Seq.empty) val authors = authors0 @@ -90,9 +91,13 @@ trait CommentFactoryBase { this: MemberLookupBase => } } + override val shortDescription: Option[Text] = shortDescription0.lastOption collect { + case Body(List(Paragraph(Chain(List(Summary(Text(e))))))) if !e.trim.contains("\n") => Text(e) + } + override val hideImplicitConversions: List[String] = hideImplicitConversions0 flatMap { - case Body(List(Paragraph(Chain(List(Summary(Text(e))))))) if (!e.trim.contains("\n")) => List(e) + case Body(List(Paragraph(Chain(List(Summary(Text(e))))))) if !e.trim.contains("\n") => List(e) case _ => List() } } @@ -290,7 +295,7 @@ trait CommentFactoryBase { this: MemberLookupBase => } case line :: ls if (lastTagKey.isDefined) => { - val newtags = if (!line.isEmpty) { + val newtags = if (!line.isEmpty || inCodeBlock) { val key = lastTagKey.get val value = ((tags get key): @unchecked) match { @@ -397,7 +402,8 @@ trait CommentFactoryBase { this: MemberLookupBase => groupDesc0 = allSymsOneTag(SimpleTagKey("groupdesc")), groupNames0 = allSymsOneTag(SimpleTagKey("groupname")), groupPrio0 = allSymsOneTag(SimpleTagKey("groupprio")), - hideImplicitConversions0 = allTags(SimpleTagKey("hideImplicitConversion")) + hideImplicitConversions0 = allTags(SimpleTagKey("hideImplicitConversion")), + shortDescription0 = allTags(SimpleTagKey("shortDescription")) ) for ((key, _) <- bodyTags) diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala index 81f8c3ec06..5d0b6782bc 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala @@ -47,9 +47,10 @@ abstract class Comment { Chain(List(inline) ++ stack.reverse) } - /** A shorter version of the body. Usually, this is the first sentence of the body. */ + /** A shorter version of the body. Either from `@shortDescription` or the + * first sentence of the body. */ def short: Inline = { - body.summary match { + shortDescription orElse body.summary match { case Some(s) => closeHtmlTags(s) case _ => @@ -62,7 +63,7 @@ abstract class Comment { /** A list of other resources to see, including links to other entities or * to external documentation. The empty list is used when no other resource - * is mentionned. */ + * is mentioned. */ def see: List[Body] /** A description of the result of the entity. Typically, this provides additional @@ -126,6 +127,9 @@ abstract class Comment { /** A list of implicit conversions to hide */ def hideImplicitConversions: List[String] + /** A short description used in the entity-view and search results */ + def shortDescription: Option[Text] + override def toString = body.toString + "\n" + (authors map ("@author " + _.toString)).mkString("\n") + diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala index 42b56aa927..b4ede6d358 100644 --- a/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala @@ -9,7 +9,6 @@ import scala.collection._ * to configure what data is actually available to the generator: * - A `Universer` provides a `Universe` data structure representing the interfaces and comments of the documented * program. - * - An `Indexer` provides precalculated indexing information about a universe. * To implement this class only requires defining method `generateImpl`. */ abstract class Generator { diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala deleted file mode 100644 index 12fee69cca..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala +++ /dev/null @@ -1,21 +0,0 @@ -package scala.tools.nsc -package doc -package doclet - -/** A `Generator` may implement the `Indexer` trait to gain access to pre-calculated indexing information */ -trait Indexer extends Generator with Universer { - - protected var indexField: Index = null - - def index: Index = indexField - - def setIndex(i: Index) { - assert(indexField == null) - indexField = i - } - - checks += { () => - indexField != null - } - -} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala index cad7cf3298..73a854e995 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala @@ -7,14 +7,19 @@ package scala.tools.nsc package doc package html +import scala.reflect.internal.Reporter import doclet._ /** The default doclet used by the scaladoc command line tool * when no user-provided doclet is provided. */ -class Doclet extends Generator with Universer with Indexer { +class Doclet(reporter: Reporter) extends Generator with Universer { - def generateImpl() { - new html.HtmlFactory(universe, index, new ScalaDocReporter(universe.settings)).generate() - } + @deprecated("Doclets should be created with the Reporter constructor. Otherwise logging reporters will not be shared by the creating parent", "2.12.0") + def this() = this(null) + def generateImpl() = + new html.HtmlFactory( + universe, + if (reporter != null) reporter else new ScalaDocReporter(universe.settings) + ).generate() } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala index 65c540d4c5..62620057cb 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala @@ -12,11 +12,12 @@ import java.io.{ File => JFile } import io.{ Streamable, Directory } import scala.collection._ import page.diagram._ +import scala.reflect.internal.Reporter /** A class that can generate Scaladoc sites to some fixed root folder. * @author David Bernard * @author Gilles Dubochet */ -class HtmlFactory(val universe: doc.Universe, index: doc.Index, val reporter: ScalaDocReporter) { +class HtmlFactory(val universe: doc.Universe, val reporter: Reporter) { import page.{IndexScript, EntityPage} /** The character encoding to be used for generated Scaladoc sites. @@ -33,7 +34,7 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index, val reporter: Sc "class_comp.svg", "object_comp.svg", "trait_comp.svg", - "permalink.svg", + "object_comp_trait.svg", "abstract_type.svg", "lato-v11-latin-100.eot", "lato-v11-latin-100.ttf", @@ -100,16 +101,10 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index, val reporter: Sc libResources foreach (s => copyResource("lib/" + s)) - IndexScript(universe, index) writeFor this + IndexScript(universe) writeFor this - if (index.hasDeprecatedMembers) - new page.DeprecatedIndex(universe, index, reporter) writeFor this try { writeTemplates(_ writeFor this) - - for (letter <- index.firstLetterIndex) { - new html.page.ReferenceIndex(letter._1, index, universe, reporter) writeFor this - } } finally { DiagramStats.printStats(universe.settings) universe.dotRunner.cleanup() diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala index 0eb90d8942..6ad51f4f7e 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala @@ -13,6 +13,7 @@ import base._ import base.comment._ import model._ +import scala.reflect.internal.Reporter import scala.xml.NodeSeq import scala.xml.Elem import scala.xml.dtd.DocType @@ -27,7 +28,7 @@ abstract class HtmlPage extends Page { thisPage => protected def title: String /** ScalaDoc reporter for error handling */ - protected def reporter: ScalaDocReporter + protected def docletReporter: Reporter /** The page description */ protected def description: String = @@ -216,41 +217,16 @@ abstract class HtmlPage extends Page { thisPage => val Trait, Class, Type, Object, Package = Value } - /** Returns the _big image name and the alt attribute - * corresponding to the DocTemplate Entity (upper left icon) */ - def docEntityKindToBigImage(ety: DocTemplateEntity) = { - def entityToImage(e: DocTemplateEntity) = - if (e.isTrait) Image.Trait - else if (e.isClass) Image.Class - else if (e.isAbstractType || e.isAliasType) Image.Type - else if (e.isObject) Image.Object - else if (e.isPackage) Image.Package - else { - // FIXME: an entity *should* fall into one of the above categories, - // but AnyRef is somehow not - Image.Class - } - - val image = entityToImage(ety) - val companionImage = ety.companion filter { - e => e.visibility.isPublic && ! e.inSource.isEmpty - } map { entityToImage } - - (image, companionImage) match { - case (from, Some(to)) => - ((from + "_to_" + to + "_big.png").toLowerCase, from + "/" + to) - case (from, None) => - ((from + "_big.png").toLowerCase, from.toString) - } - } - def permalink(template: Entity, isSelf: Boolean = true): Elem = <span class="permalink"> - <a href={ memberToUrl(template, isSelf) } title="Permalink" target="_top"> - <img src={ relativeLinkTo(List("permalink.svg", "lib")) } alt="Permalink" /> + <a href={ memberToUrl(template, isSelf) } title="Permalink"> + <i class="material-icons"></i> </a> </span> + def docEntityImageClass(tpl: DocTemplateEntity): String = + tpl.kind + tpl.companion.fold("")("-companion-" + _.kind) + def docEntityKindToCompanionTitle(ety: DocTemplateEntity, baseString: String = "See companion") = ety.companion match{ case Some(companion) => @@ -263,7 +239,7 @@ abstract class HtmlPage extends Page { thisPage => case None => baseString } - def companionAndPackage(tpl: DocTemplateEntity): Elem = + def companionAndPackage(tpl: DocTemplateEntity): NodeSeq = <span class="morelinks">{ tpl.companion match { case Some(companionTpl) => @@ -272,15 +248,9 @@ abstract class HtmlPage extends Page { thisPage => else if (companionTpl.isTrait) s"trait ${companionTpl.name}" else s"class ${companionTpl.name}" <div> - Related Docs: - <a href={relativeLinkTo(tpl.companion.get)} title={docEntityKindToCompanionTitle(tpl)}>{objClassTrait}</a> - <span class="divider">|</span> - {templateToHtml(tpl.inTemplate, s"package ${tpl.inTemplate.name}")} - </div> - case None => - <div>Related Doc: - {templateToHtml(tpl.inTemplate, s"package ${tpl.inTemplate.name}")} + Companion <a href={relativeLinkTo(companionTpl)} title={docEntityKindToCompanionTitle(tpl)}>{objClassTrait}</a> </div> + case None => NodeSeq.Empty } }</span> diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala index 875d7919c2..c720c4939f 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala @@ -102,6 +102,11 @@ abstract class Page { relativize(thisPage.path.reverse, destPath.reverse).mkString("/") } + def hasCompanion(mbr: TemplateEntity): Boolean = mbr match { + case dtpl: DocTemplateEntity => dtpl.companion.isDefined + case _ => false + } + protected def inlineToStr(inl: comment.Inline): String = inl match { case comment.Chain(items) => items flatMap (inlineToStr(_)) mkString "" case comment.Italic(in) => inlineToStr(in) diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala deleted file mode 100644 index e8cb58c732..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - */ - -package scala -package tools -package nsc -package doc -package html -package page - -import doc.model._ - -class DeprecatedIndex(universe: Universe, index: doc.Index, rep: ScalaDocReporter) extends HtmlPage { - - def reporter = rep - - def path = List("deprecated-list.html") - - def title = { - val s = universe.settings - ( if (!s.doctitle.isDefault) s.doctitle.value else "" ) + - ( if (!s.docversion.isDefault) (" " + s.docversion.value) else "" ) - } - - def headers = - <xml:group> - <link href={ relativeLinkTo(List("ref-index.css", "lib")) } media="screen" type="text/css" rel="stylesheet"/> - <script type="text/javascript" src={ relativeLinkTo{List("jquery.js", "lib")} }></script> - </xml:group> - - - private def entry(name: String, methods: Iterable[MemberEntity]) = { - val occurrences = methods.filter(_.deprecation.isDefined).map(method => - templateToHtml(method.inDefinitionTemplates.head) - ).toList.distinct - - <div class="entry"> - <div class="name">{ name }</div> - <div class="occurrences">{ - for (owner <- occurrences) yield owner ++ scala.xml.Text(" ") - }</div> - </div> - } - - def deprecatedEntries = { - val available = ('_' +: ('a' to 'z')).flatMap(index.firstLetterIndex.get) - - for (group <- available; - value <- group if value._2.find(_.deprecation.isDefined).isDefined) - yield value - } - - def body = - <body>{ - for(value <- deprecatedEntries) yield - entry(value._1, value._2.view) - }</body> - -} 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..9dd2c2184d 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala @@ -13,6 +13,7 @@ package page import base._ import base.comment._ +import scala.reflect.internal.Reporter import scala.collection.mutable import scala.xml.{NodeSeq, Text, UnprefixedAttribute} import scala.language.postfixOps @@ -22,10 +23,12 @@ import model.diagram._ import diagram._ trait EntityPage extends HtmlPage { + import ScalaDoc.SummaryReporter + def universe: doc.Universe def generator: DiagramGenerator def tpl: DocTemplateEntity - def reporter: ScalaDocReporter + def docletReporter: Reporter override val path = templateToPath(tpl) @@ -71,9 +74,80 @@ 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 = + if (mbr.isObject && hasCompanion(mbr)) + NodeSeq.Empty + else + <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 || x.isObject)) + .sortBy(_.name) + .map(entityToUl(_, (if (tpl.isPackage) 0 else -1) + rootToParentLis.length)) + val currSubLis = tpl.templates + .filter(_.isPackage) + .sortBy(_.name) + .map(memberToHtml(_, tpl, indentation = rootToParentLis.length + 1)) + + if (subsToTpl.isEmpty && !tpl.isPackage) // current Entity is not a package, show packages before entity listing + rootToParentLis ++ subsToTplLis ++ subsAfterTplLis ++ currSubLis ++ currEntityLis + else + rootToParentLis ++ subsToTplLis ++ currSubLis ++ currEntityLis ++ subsAfterTplLis + } + </ul> + </div> + </div> + <div id="content"> + { content } + </div> </div> </div> </body> @@ -87,8 +161,7 @@ trait EntityPage extends HtmlPage { val version = universe.settings.docversion.value if (version.length > "XX.XX.XX-XXX".length) { - reporter.warning(null, - s"doc-version ($version) is too long to be displayed in the webview") + docletReporter.summaryWarning(s"doc-version ($version) was too long to be displayed in the webview, and will be left out. The max length is: XX.XX.XX-XXX") "" } else version } @@ -105,7 +178,7 @@ trait EntityPage extends HtmlPage { </div> val valueMembers = - tpl.methods ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted + tpl.methods ++ tpl.values ++ tpl.templates.filter(x => x.isObject) sorted val (absValueMembers, nonAbsValueMembers) = valueMembers partition (_.isAbstract) @@ -145,53 +218,53 @@ trait EntityPage extends HtmlPage { <body class={ tpl.kind + (if (tpl.isType) " type" else " value") }> <div id="definition"> { - val (src, alt) = docEntityKindToBigImage(tpl) - - val identifier = alt.toString.substring(0,2).toLowerCase + val imageClass = docEntityImageClass(tpl) tpl.companion match { case Some(companion) if (companion.visibility.isPublic && companion.inSource != None) => - <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><div class={s"big-circle companion $identifier"}>{ identifier.substring(0,1) }</div></a> + <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><div class={s"big-circle $imageClass"}>{ imageClass.substring(0,1) }</div></a> case _ => - <div class={ "big-circle " + alt.toString.toLowerCase }>{ identifier.substring(0,1) }</div> - }} + <div class={s"big-circle $imageClass"}>{ imageClass.substring(0,1) }</div> + } + } { owner } - <h1>{ displayName }</h1>{ - if (tpl.isPackage) NodeSeq.Empty else <h3>{companionAndPackage(tpl)}</h3> - }{ permalink(tpl) } - { signature(tpl, isSelf = true) } + <h1>{ displayName }{ permalink(tpl) }</h1> + { if (tpl.isPackage) NodeSeq.Empty else <h3>{companionAndPackage(tpl)}</h3> } </div> + { signature(tpl, isSelf = true) } + { memberToCommentHtml(tpl, tpl.inTemplate, isSelf = true) } + { if (valueMembers.filterNot(_.kind == "package").isEmpty) NodeSeq.Empty else <div id="mbrsel"> <div class='toggle'></div> <div id='memberfilter'> <i class="material-icons arrow"></i> <span class='input'> - <input id='mbrsel-input' placeholder='Filter members' type='text' accesskey='/'/> + <input id='mbrsel-input' placeholder='Filter all members' type='text' accesskey='/'/> </span> <i class="clear material-icons"></i> </div> - <div id='filterby'> - <div id="order"> - <span class="filtertype">Ordering</span> - <ol> - { - if (!universe.settings.docGroups.value || (tpl.members.map(_.group).distinct.length == 1)) - NodeSeq.Empty - else - <li class="group out"><span>Grouped</span></li> - } - <li class="alpha in"><span>Alphabetic</span></li> - { - if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) - NodeSeq.Empty - else - <li class="inherit out"><span>By Inheritance</span></li> - } - </ol> - </div> + <div id='filterby'> + <div id="order"> + <span class="filtertype">Ordering</span> + <ol> + { + if (!universe.settings.docGroups.value || (tpl.members.map(_.group).distinct.length == 1)) + NodeSeq.Empty + else + <li class="group out"><span>Grouped</span></li> + } + <li class="alpha in"><span>Alphabetic</span></li> + { + if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) + NodeSeq.Empty + else + <li class="inherit out"><span>By Inheritance</span></li> + } + </ol> + </div> { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else { if (!tpl.linearizationTemplates.isEmpty) @@ -235,6 +308,7 @@ trait EntityPage extends HtmlPage { } </div> </div> + } <div id="template"> <div id="allMembers"> @@ -262,7 +336,12 @@ 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 + .map(memberToHtml(_, tpl)) + } + </ol> </div> } @@ -329,14 +408,19 @@ trait EntityPage extends HtmlPage { { if (Set("epfl", "EPFL").contains(tpl.universe.settings.docfooter.value)) - <div id="footer">Scala programming documentation. Copyright (c) 2003-2016 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://typesafe.com" target="_top">Typesafe</a>.</div> + <div id="footer">Scala programming documentation. Copyright (c) 2003-2016 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://www.lightbend.com" target="_top">Lightbend</a>.</div> else <div id="footer"> { tpl.universe.settings.docfooter.value } </div> } </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 +430,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 }> @@ -504,7 +589,7 @@ trait EntityPage extends HtmlPage { <br/> ++ scala.xml.Text("To access this member you can use a ") ++ <a href="http://stackoverflow.com/questions/2087250/what-is-the-purpose-of-type-ascription-in-scala" target="_blank">type ascription</a> ++ scala.xml.Text(":") ++ - <br/> ++ <div class="cmt"><pre>{"(" + Template.lowerFirstLetter(tpl.name) + ": " + conv.targetType.name + ")." + mbr.name + params }</pre></div> + <br/> ++ <div class="cmt"><pre>{"(" + EntityPage.lowerFirstLetter(tpl.name) + ": " + conv.targetType.name + ")." + mbr.name + params }</pre></div> } val shadowingWarning: NodeSeq = @@ -695,7 +780,6 @@ trait EntityPage extends HtmlPage { case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.linearizationTemplates.nonEmpty => <div class="toggleContainer block"> <span class="toggle"> - <i class="material-icons"></i> Linear Supertypes </span> <div class="superTypes hiddenContent">{ @@ -718,7 +802,6 @@ trait EntityPage extends HtmlPage { if (subs.nonEmpty) <div class="toggleContainer block"> <span class="toggle"> - <i class="material-icons"></i> Known Subclasses </span> <div class="subClasses hiddenContent">{ @@ -738,7 +821,6 @@ trait EntityPage extends HtmlPage { if (diagramSvg != NodeSeq.Empty) { <div class="toggleContainer block diagram-container" id={ id + "-container"}> <span class="toggle diagram-link"> - <i class="material-icons"></i> { description } </span> <div class="diagram" id={ id }>{ diagramSvg }</div> @@ -794,7 +876,6 @@ trait EntityPage extends HtmlPage { def inside(hasLinks: Boolean, nameLink: String = ""): NodeSeq = <xml:group> <span class="modifier_kind"> - <i class="material-icons unfold-arrow"></i> <span class="modifier">{ mbr.flags.map(flag => inlineToHtml(flag.text) ++ scala.xml.Text(" ")) }</span> <span class="kind">{ kindToString(mbr) }</span> </span> @@ -828,7 +909,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 { @@ -890,7 +973,7 @@ trait EntityPage extends HtmlPage { else NodeSeq.Empty case alt: MemberEntity with AliasType => - <span class="result"> = { typeToHtml(alt.alias, hasLinks) }</span> + <span class="result alias"> = { typeToHtml(alt.alias, hasLinks) }</span> case tpl: MemberTemplateEntity if !tpl.parentTypes.isEmpty => <span class="result"> extends { typeToHtml(tpl.parentTypes.map(_._2), hasLinks) }</span> @@ -1043,11 +1126,15 @@ object EntityPage { uni: doc.Universe, gen: DiagramGenerator, docTpl: DocTemplateEntity, - rep: ScalaDocReporter + rep: Reporter ): EntityPage = new EntityPage { def universe = uni def generator = gen def tpl = docTpl - def reporter = rep + def docletReporter = rep } + + /* Vlad: Lesson learned the hard way: don't put any stateful code that references the model here, + * it won't be garbage collected and you'll end up filling the heap with garbage */ + def lowerFirstLetter(s: String) = if (s.length >= 1) s.substring(0,1).toLowerCase() + s.substring(1) else s } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala deleted file mode 100644 index 8204f413fd..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala +++ /dev/null @@ -1,75 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author David Bernard, Manohar Jonnalagedda, Felix Mulder - */ - -package scala.tools.nsc -package doc -package html -package page - -import model._ -import scala.collection._ -import scala.xml._ - -class Index(universe: doc.Universe, val index: doc.Index, rep: ScalaDocReporter) extends HtmlPage { - - def reporter = rep - - def path = List("index.html") - - def title = "" - - val headers = - <xml:group> - <link href={ relativeLinkTo{List("index.css", "lib")} } media="screen" type="text/css" rel="stylesheet"/> - <script type="text/javascript" src={ relativeLinkTo{List("jquery.js", "lib")} }></script> - <script type="text/javascript" src={ relativeLinkTo{List("index.js", "lib")} }></script> - <script type="text/javascript" src="index.js"></script> - <script type="text/javascript" src={ relativeLinkTo{List("scheduler.js", "lib")} }></script> - </xml:group> - - val body = - <body> - { search } - <div id="search-results"> - <div id="results-content"> - <div id="entity-results"></div> - <div id="member-results"></div> - </div> - </div> - <div id="content" style="-webkit-overflow-scrolling: touch;"> - <iframe id="template" name="template" src={ relativeLinkTo{List("package.html")} }/> - </div> - </body> - - def search = - <div id="search"> - <span id="doc-title"> - {universe.settings.doctitle.value} - <span id="doc-version"> - { - val version = universe.settings.docversion.value - - if (version.length > "XX.XX.XX-XXX".length) { - reporter.warning(null, - s"doc-version ($version) is too long to be displayed in the webview") - "" - } else version - } - </span> - </span> - <span class="close-results"><span class="left"><</span> Back</span> - <div id="textfilter"> - <span class="input"> - <input autocapitalize="none" placeholder="Search" id="index-input" type="text" accesskey="/"/> - <span class="clear">✖</span> - </span> - </div> - </div> - - def packageQualifiedName(ety: DocTemplateEntity): String = - if (ety.inTemplate.isPackage) ety.name - else (packageQualifiedName(ety.inTemplate) + "." + ety.name) - -} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala index 2c38036bb6..6b24c0f568 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala @@ -12,7 +12,7 @@ import scala.tools.nsc.doc.model.{Package, DocTemplateEntity} import scala.tools.nsc.doc.html.{Page, HtmlFactory} import scala.util.parsing.json.{JSONObject, JSONArray, JSONType} -class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { +class IndexScript(universe: doc.Universe) extends Page { import model._ import scala.tools.nsc.doc.base.comment.Text import scala.collection.immutable.Map @@ -30,17 +30,26 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { case (pack, templates) => { val merged = mergeByQualifiedName(templates) - val ary = merged.keys.toList.sortBy(_.toLowerCase).map(key => { + val ary = merged.keys.toList.sortBy(_.toLowerCase).map { key => + /** One pair is generated for the class/trait and one for the + * companion object, both will have the same {"name": key} + * + * As such, we need to distinguish between the members that are + * generated by the object, and the members generated by the + * class/trait instance. Otherwise one of the member objects will be + * overwritten. + */ val pairs = merged(key).flatMap { t: DocTemplateEntity => + val kind = kindToString(t) Seq( - kindToString(t) -> relativeLinkTo(t), - "kind" -> kindToString(t), - "members" -> membersToJSON(t.members.filter(!_.isShadowedOrAmbiguousImplicit)), + kind -> relativeLinkTo(t), + "kind" -> kind, + s"members_$kind" -> membersToJSON(t.members.filter(!_.isShadowedOrAmbiguousImplicit), t), "shortDescription" -> shortDesc(t)) } JSONObject(Map(pairs : _*) + ("name" -> key)) - }) + } pack.qualifiedName -> JSONArray(ary) } @@ -83,10 +92,10 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { } /** Returns the json representation of the supplied members */ - def membersToJSON(entities: List[MemberEntity]): JSONType = - JSONArray(entities map memberToJSON) + def membersToJSON(entities: List[MemberEntity], parent: DocTemplateEntity): JSONType = + JSONArray(entities map (memberToJSON(_, parent))) - private def memberToJSON(mbr: MemberEntity): JSONObject = { + private def memberToJSON(mbr: MemberEntity, parent: DocTemplateEntity): JSONObject = { /** This function takes a member and gets eventual parameters and the * return type. For example, the definition: * {{{ def get(key: A): Option[B] }}} @@ -100,6 +109,7 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { } .mkString("(", ")(", "): " + d.resultType.name) case v: Val => ": " + v.resultType.name + case _ => "" } /** This function takes a member entity and return all modifiers in a @@ -119,15 +129,15 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { */ def jsonObject(m: MemberEntity): JSONObject = JSONObject(Map( - "label" -> m.definitionName.replaceAll(".*#", ""), // member name + "label" -> "[^\\.]*\\.([^#]+#)?".r.replaceAllIn(m.definitionName, ""), // member name "member" -> m.definitionName.replaceFirst("#", "."), // full member name "tail" -> memberTail(m), - "kind" -> memberKindToString(m), // modifiers i.e. "abstract def" - "link" -> memberToUrl(m))) // permalink to the member + "kind" -> memberKindToString(m), // modifiers i.e. "abstract def" + "link" -> memberToUrl(m))) // permalink to the member mbr match { - case d: Def => jsonObject(d) - case v: Val => jsonObject(v) + case x @ (_: Def | _: Val | _: Object | _: AliasType) => jsonObject(x) + case e @ (_: Class | _: Trait) if parent.isRootPackage || !parent.isPackage => jsonObject(e) case m: MemberEntity => JSONObject(Map("member" -> m.definitionName, "error" -> "unsupported entity")) } @@ -140,6 +150,5 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { } object IndexScript { - def apply(universe: doc.Universe, index: doc.Index) = - new IndexScript(universe, index) + def apply(universe: doc.Universe) = new IndexScript(universe) } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala deleted file mode 100644 index 6780f17a8c..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala +++ /dev/null @@ -1,63 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author Pedro Furlanetto - */ - -package scala -package tools -package nsc -package doc -package html -package page - -import doc.model._ - -class ReferenceIndex(letter: Char, index: doc.Index, universe: Universe, rep: ScalaDocReporter) extends HtmlPage { - - def reporter = rep - - def path = List("index-"+letter+".html", "index") - - def title = { - val s = universe.settings - ( if (!s.doctitle.isDefault) s.doctitle.value else "" ) + - ( if (!s.docversion.isDefault) (" " + s.docversion.value) else "" ) - } - - def headers = - <xml:group> - <link href={ relativeLinkTo(List("ref-index.css", "lib")) } media="screen" type="text/css" rel="stylesheet"/> - <script type="text/javascript" src={ relativeLinkTo{List("jquery.js", "lib")} }></script> - </xml:group> - - - private def entry(name: String, methods: Iterable[MemberEntity]) = { - val occurrences = methods.map(method => { - val html = templateToHtml(method.inDefinitionTemplates.head) - if (method.deprecation.isDefined) { - <strike>{ html }</strike> - } else { - html - } - }).toList.distinct - - <div class="entry"> - <div class="name">{ - if (methods.find { ! _.deprecation.isDefined } != None) - name - else - <strike>{ name }</strike> - }</div> - <div class="occurrences">{ - for (owner <- occurrences) yield owner ++ scala.xml.Text(" ") - }</div> - </div> - } - - def body = - <body>{ - for(groups <- index.firstLetterIndex(letter)) yield - entry(groups._1, groups._2.view) - }</body> - -} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala deleted file mode 100644 index f5e909cf90..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala +++ /dev/null @@ -1,987 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author David Bernard, Manohar Jonnalagedda - */ - -package scala -package tools -package nsc -package doc -package html -package page - -import base._ -import base.comment._ - -import scala.collection.mutable -import scala.xml.{NodeSeq, Text, UnprefixedAttribute} -import scala.language.postfixOps - -import model._ -import model.diagram._ -import diagram._ - -class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemplateEntity, rep: ScalaDocReporter) extends HtmlPage { - - def reporter = rep - - val path = templateToPath(tpl) - - def title = { - val s = universe.settings - ( if (!s.doctitle.isDefault) s.doctitle.value + " " else "" ) + - ( if (!s.docversion.isDefault) s.docversion.value else "" ) + - ( if ((!s.doctitle.isDefault || !s.docversion.isDefault) && tpl.qualifiedName != "_root_") " - " + tpl.qualifiedName else "" ) - } - - val headers = - <xml:group> - <link href={ relativeLinkTo{List("template.css", "lib")} } media="screen" type="text/css" rel="stylesheet"/> - <link href={ relativeLinkTo{List("diagrams.css", "lib")} } media="screen" type="text/css" rel="stylesheet" id="diagrams-css" /> - <script type="text/javascript" src={ relativeLinkTo{List("jquery.js", "lib")} } id="jquery-js"></script> - <script type="text/javascript" src={ relativeLinkTo{List("jquery.panzoom.min.js", "lib")} }></script> - <script type="text/javascript" src={ relativeLinkTo{List("jquery.mousewheel.min.js", "lib")} }></script> - <script type="text/javascript" src={ relativeLinkTo{List("template.js", "lib")} }></script> - <script type="text/javascript" src={ relativeLinkTo{List("tools.tooltip.js", "lib")} }></script> - { if (universe.settings.docDiagrams.value) { - <script type="text/javascript" src={ relativeLinkTo{List("modernizr.custom.js", "lib")} }></script> - <script type="text/javascript" src={ relativeLinkTo{List("diagrams.js", "lib")} } id="diagrams-js"></script> - } else NodeSeq.Empty } - <script type="text/javascript"> - if(top === self) {{ - var url = '{ val p = templateToPath(tpl); "../" * (p.size - 1) + "index.html" }'; - var hash = '{ val p = templateToPath(tpl); (p.tail.reverse ::: List(p.head.replace(".html", ""))).mkString(".") }'; - var anchor = window.location.hash; - var anchor_opt = ''; - if (anchor.length { scala.xml.Unparsed(">=") /* unless we use Unparsed, it gets escaped and crashes the script */ } 1) - anchor_opt = '@' + anchor.substring(1); - window.location.href = url + '#' + hash + anchor_opt; - }} - </script> - </xml:group> - - val valueMembers = - tpl.methods ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted - - val (absValueMembers, nonAbsValueMembers) = - valueMembers partition (_.isAbstract) - - val (deprValueMembers, nonDeprValueMembers) = - nonAbsValueMembers partition (_.deprecation.isDefined) - - val (concValueMembers, shadowedImplicitMembers) = - nonDeprValueMembers partition (!_.isShadowedOrAmbiguousImplicit) - - val typeMembers = - tpl.abstractTypes ++ tpl.aliasTypes ++ tpl.templates.filter(x => x.isTrait || x.isClass) sorted (implicitly[Ordering[MemberEntity]]) - - val constructors = (tpl match { - case cls: Class => (cls.constructors: List[MemberEntity]).sorted - case _ => Nil - }) - - /* for body, there is a special case for AnyRef, otherwise AnyRef appears - * like a package/object this problem should be fixed, this implementation - * is just a patch. */ - val body = { - val templateName = if (tpl.isRootPackage) "root package" else tpl.name - val displayName = tpl.companion match { - case Some(companion) if (companion.visibility.isPublic && companion.inSource != None) => - <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}>{ templateName }</a> - case _ => - templateName - } - val owner = { - if (tpl.isRootPackage || tpl.inTemplate.isRootPackage) - NodeSeq.Empty - else - <p id="owner">{ templatesToHtml(tpl.inTemplate.toRoot.reverse.tail, scala.xml.Text(".")) }</p> - } - - <body class={ tpl.kind + (if (tpl.isType) " type" else " value") }> - <div id="definition"> - { - val (src, alt) = docEntityKindToBigImage(tpl) - - val identifier = alt.toString.substring(0,2).toLowerCase - - tpl.companion match { - case Some(companion) if (companion.visibility.isPublic && companion.inSource != None) => - <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> - }{ permalink(tpl) } - { signature(tpl, isSelf = true) } - </div> - - { memberToCommentHtml(tpl, tpl.inTemplate, isSelf = true) } - - <div id="mbrsel"> - <div class='toggle'></div> - <div id='textfilter'><span class='input'><input id='mbrsel-input' placeholder='Filter members' type='text' accesskey='/'/></span><span class='clear'>✖</span></div> - <div id='filterby'> - { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty && (!universe.settings.docGroups.value || (tpl.members.map(_.group).distinct.length == 1))) - NodeSeq.Empty - else - <div id="order"> - <span class="filtertype">Ordering</span> - <ol> - { - if (!universe.settings.docGroups.value || (tpl.members.map(_.group).distinct.length == 1)) - NodeSeq.Empty - else - <li class="group out"><span>Grouped</span></li> - } - <li class="alpha in"><span>Alphabetic</span></li> - { - if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) - NodeSeq.Empty - else - <li class="inherit out"><span>By Inheritance</span></li> - } - </ol> - </div> - } - { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else - { - if (!tpl.linearizationTemplates.isEmpty) - <div class="ancestors"> - <span class="filtertype">Inherited<br/> - </span> - <ol id="linearization"> - { (tpl :: tpl.linearizationTemplates).map(wte => <li class="in" name={ wte.qualifiedName }><span>{ wte.name }</span></li>) } - </ol> - </div> - else NodeSeq.Empty - } ++ { - if (!tpl.conversions.isEmpty) - <div class="ancestors"> - <span class="filtertype">Implicitly<br/> - </span> - <ol id="implicits"> { - tpl.conversions.map { conv => - val name = conv.conversionQualifiedName - val hide = universe.settings.hiddenImplicits(name) - <li class="in" name={ name } data-hidden={ hide.toString }><span>{ "by " + conv.conversionShortName }</span></li> - } - } - </ol> - </div> - else NodeSeq.Empty - } ++ - <div class="ancestors"> - <span class="filtertype"></span> - <ol> - <li class="hideall out"><span>Hide All</span></li> - <li class="showall in"><span>Show All</span></li> - </ol> - </div> - } - { - <div id="visbl"> - <span class="filtertype">Visibility</span> - <ol><li class="public in"><span>Public</span></li><li class="all out"><span>All</span></li></ol> - </div> - } - </div> - </div> - - <div id="template"> - <div id="allMembers"> - { if (constructors.isEmpty) NodeSeq.Empty else - <div id="constructors" class="members"> - <h3>Instance Constructors</h3> - <ol>{ constructors map (memberToHtml(_, tpl)) }</ol> - </div> - } - - { if (typeMembers.isEmpty) NodeSeq.Empty else - <div id="types" class="types members"> - <h3>Type Members</h3> - <ol>{ typeMembers map (memberToHtml(_, tpl)) }</ol> - </div> - } - - { if (absValueMembers.isEmpty) NodeSeq.Empty else - <div class="values members"> - <h3>Abstract Value Members</h3> - <ol>{ absValueMembers map (memberToHtml(_, tpl)) }</ol> - </div> - } - - { 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> - </div> - } - - { if (shadowedImplicitMembers.isEmpty) NodeSeq.Empty else - <div class="values members"> - <h3>Shadowed Implicit Value Members</h3> - <ol>{ shadowedImplicitMembers map (memberToHtml(_, tpl)) }</ol> - </div> - } - - { if (deprValueMembers.isEmpty) NodeSeq.Empty else - <div class="values members"> - <h3>Deprecated Value Members</h3> - <ol>{ deprValueMembers map (memberToHtml(_, tpl)) }</ol> - </div> - } - </div> - - <div id="inheritedMembers"> - { - // linearization - NodeSeq fromSeq (for ((superTpl, superType) <- (tpl.linearizationTemplates zip tpl.linearizationTypes)) yield - <div class="parent" name={ superTpl.qualifiedName }> - <h3>Inherited from { - typeToHtmlWithStupidTypes(tpl, superTpl, superType) - }</h3> - </div> - ) - } - { - // implicitly inherited - NodeSeq fromSeq (for (conversion <- (tpl.conversions)) yield - <div class="conversion" name={ conversion.conversionQualifiedName }> - <h3>Inherited by implicit conversion { conversion.conversionShortName } from - { typeToHtml(tpl.resultType, hasLinks = true) } to { typeToHtml(conversion.targetType, hasLinks = true) } - </h3> - </div> - ) - } - </div> - - <div id="groupedMembers"> - { - val allGroups = tpl.members.map(_.group).distinct - val orderedGroups = allGroups.map(group => (tpl.groupPriority(group), group)).sorted.map(_._2) - // linearization - NodeSeq fromSeq (for (group <- orderedGroups) yield - <div class="group" name={ group }> - <h3>{ tpl.groupName(group) }</h3> - { - tpl.groupDescription(group) match { - case Some(body) => <div class="comment cmt">{ bodyToHtml(body) }</div> - case _ => NodeSeq.Empty - } - } - </div> - ) - } - </div> - - </div> - - <div id="tooltip" ></div> - - { - if (Set("epfl", "EPFL").contains(tpl.universe.settings.docfooter.value)) - <div id="footer">Scala programming documentation. Copyright (c) 2003-2016 <a href="http://www.epfl.ch" target="_top">EPFL</a>, with contributions from <a href="http://typesafe.com" target="_top">Typesafe</a>.</div> - else - <div id="footer"> { tpl.universe.settings.docfooter.value } </div> - } - </body> - } - - def memberToHtml(mbr: MemberEntity, inTpl: DocTemplateEntity): NodeSeq = { - // Sometimes it's same, do we need signatureCompat still? - val sig = if (mbr.signature == mbr.signatureCompat) { - <a id={ mbr.signature }/> - } else { - <a id={ mbr.signature }/><a id={ mbr.signatureCompat }/> - } - - val memberComment = memberToCommentHtml(mbr, inTpl, isSelf = false) - <li name={ mbr.definitionName } visbl={ if (mbr.visibility.isProtected) "prt" else "pub" } - data-isabs={ mbr.isAbstract.toString } - fullComment={ if(memberComment.filter(_.label=="div").isEmpty) "no" else "yes" } - group={ mbr.group }> - { sig } - { signature(mbr, isSelf = false) } - { memberComment } - </li> - } - - def memberToCommentHtml(mbr: MemberEntity, inTpl: DocTemplateEntity, isSelf: Boolean): NodeSeq = { - mbr match { - case dte: DocTemplateEntity if isSelf => - // comment of class itself - <xml:group> - <div id="comment" class="fullcommenttop">{ memberToCommentBodyHtml(mbr, inTpl, isSelf = true) }</div> - </xml:group> - case _ => - // comment of non-class member or non-documentented inner class - val commentBody = memberToCommentBodyHtml(mbr, inTpl, isSelf = false) - if (commentBody.isEmpty) - NodeSeq.Empty - else { - val shortComment = memberToShortCommentHtml(mbr, isSelf) - val longComment = memberToUseCaseCommentHtml(mbr, isSelf) ++ memberToCommentBodyHtml(mbr, inTpl, isSelf) - - val includedLongComment = if (shortComment.text.trim == longComment.text.trim) - NodeSeq.Empty - else - <div class="fullcomment">{ longComment }</div> - - shortComment ++ includedLongComment - } - } - } - - def memberToUseCaseCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq = { - mbr match { - case nte: NonTemplateMemberEntity if nte.isUseCase => - inlineToHtml(comment.Text("[use case] ")) - case _ => NodeSeq.Empty - } - } - - def memberToShortCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq = - mbr.comment.fold(NodeSeq.Empty) { comment => - <p class="shortcomment cmt">{ memberToUseCaseCommentHtml(mbr, isSelf) }{ inlineToHtml(comment.short) }</p> - } - - def memberToInlineCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq = - <p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p> - - def memberToCommentBodyHtml(mbr: MemberEntity, inTpl: DocTemplateEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = { - val s = universe.settings - - val memberComment = - if (mbr.comment.isEmpty) NodeSeq.Empty - else <div class="comment cmt">{ commentToHtml(mbr.comment) }</div> - - val authorComment = - if (! s.docAuthor || mbr.comment.isEmpty || - mbr.comment.isDefined && mbr.comment.get.authors.isEmpty) NodeSeq.Empty - else <div class="comment cmt"> - {if (mbr.comment.get.authors.size > 1) <h6>Authors:</h6> else <h6>Author:</h6>} - { mbr.comment.get.authors map bodyToHtml} - </div> - - val paramComments = { - val prs: List[ParameterEntity] = mbr match { - case cls: Class => cls.typeParams ::: cls.valueParams.flatten - case trt: Trait => trt.typeParams - case dfe: Def => dfe.typeParams ::: dfe.valueParams.flatten - case ctr: Constructor => ctr.valueParams.flatten - case _ => Nil - } - - def paramCommentToHtml(prs: List[ParameterEntity], comment: Comment): NodeSeq = prs match { - - case (tp: TypeParam) :: rest => - val paramEntry: NodeSeq = { - <dt class="tparam">{ tp.name }</dt><dd class="cmt">{ bodyToHtml(comment.typeParams(tp.name)) }</dd> - } - paramEntry ++ paramCommentToHtml(rest, comment) - - case (vp: ValueParam) :: rest => - val paramEntry: NodeSeq = { - <dt class="param">{ vp.name }</dt><dd class="cmt">{ bodyToHtml(comment.valueParams(vp.name)) }</dd> - } - paramEntry ++ paramCommentToHtml(rest, comment) - - case _ => - NodeSeq.Empty - } - - mbr.comment.fold(NodeSeq.Empty) { comment => - val cmtedPrs = prs filter { - case tp: TypeParam => comment.typeParams isDefinedAt tp.name - case vp: ValueParam => comment.valueParams isDefinedAt vp.name - } - if (cmtedPrs.isEmpty && comment.result.isEmpty) NodeSeq.Empty - else { - <dl class="paramcmts block">{ - paramCommentToHtml(cmtedPrs, comment) ++ ( - comment.result match { - case None => NodeSeq.Empty - case Some(cmt) => - <dt>returns</dt><dd class="cmt">{ bodyToHtml(cmt) }</dd> - }) - }</dl> - } - } - } - - val implicitInformation = mbr.byConversion match { - case Some(conv) => - <dt class="implicit">Implicit information</dt> ++ - { - val targetType = typeToHtml(conv.targetType, hasLinks = true) - val conversionMethod = conv.convertorMethod match { - case Left(member) => Text(member.name) - case Right(name) => Text(name) - } - - // strip off the package object endings, they make things harder to follow - val conversionOwnerQualifiedNane = conv.convertorOwner.qualifiedName.stripSuffix(".package") - val conversionOwner = templateToHtml(conv.convertorOwner, conversionOwnerQualifiedNane) - - val constraintText = conv.constraints match { - case Nil => - NodeSeq.Empty - case List(constraint) => - scala.xml.Text("This conversion will take place only if ") ++ constraintToHtml(constraint) ++ scala.xml.Text(".") - case List(constraint1, constraint2) => - scala.xml.Text("This conversion will take place only if ") ++ constraintToHtml(constraint1) ++ - scala.xml.Text(" and at the same time ") ++ constraintToHtml(constraint2) ++ scala.xml.Text(".") - case constraints => - <br/> ++ "This conversion will take place only if all of the following constraints are met:" ++ <br/> ++ { - var index = 0 - constraints map { constraint => scala.xml.Text({ index += 1; index } + ". ") ++ constraintToHtml(constraint) ++ <br/> } - } - } - - <dd> - This member is added by an implicit conversion from { typeToHtml(inTpl.resultType, hasLinks = true) } to - { targetType } performed by method { conversionMethod } in { conversionOwner }. - { constraintText } - </dd> - } ++ { - if (mbr.isShadowedOrAmbiguousImplicit) { - // These are the members that are shadowing or ambiguating the current implicit - // see ImplicitMemberShadowing trait for more information - val shadowingSuggestion = { - val params = mbr match { - case d: Def => d.valueParams map (_ map (_ name) mkString("(", ", ", ")")) mkString - case _ => "" // no parameters - } - <br/> ++ scala.xml.Text("To access this member you can use a ") ++ - <a href="http://stackoverflow.com/questions/2087250/what-is-the-purpose-of-type-ascription-in-scala" - target="_blank">type ascription</a> ++ scala.xml.Text(":") ++ - <br/> ++ <div class="cmt"><pre>{"(" + Template.lowerFirstLetter(tpl.name) + ": " + conv.targetType.name + ")." + mbr.name + params }</pre></div> - } - - val shadowingWarning: NodeSeq = - if (mbr.isShadowedImplicit) - scala.xml.Text("This implicitly inherited member is shadowed by one or more members in this " + - "class.") ++ shadowingSuggestion - else if (mbr.isAmbiguousImplicit) - scala.xml.Text("This implicitly inherited member is ambiguous. One or more implicitly " + - "inherited members have similar signatures, so calling this member may produce an ambiguous " + - "implicit conversion compiler error.") ++ shadowingSuggestion - else NodeSeq.Empty - - <dt class="implicit">Shadowing</dt> ++ - <dd>{ shadowingWarning }</dd> - - } else NodeSeq.Empty - } - case _ => - NodeSeq.Empty - } - - // --- start attributes block vals - val attributes: NodeSeq = { - val fvs: List[comment.Paragraph] = visibility(mbr).toList - if (fvs.isEmpty || isReduced) NodeSeq.Empty - else { - <dt>Attributes</dt> - <dd>{ fvs map { fv => { inlineToHtml(fv.text) ++ scala.xml.Text(" ") } } }</dd> - } - } - - val definitionClasses: NodeSeq = { - val inDefTpls = mbr.inDefinitionTemplates - if ((inDefTpls.tail.isEmpty && (inDefTpls.head == inTpl)) || isReduced) NodeSeq.Empty - else { - <dt>Definition Classes</dt> - <dd>{ templatesToHtml(inDefTpls, scala.xml.Text(" → ")) }</dd> - } - } - - val fullSignature: NodeSeq = { - mbr match { - case nte: NonTemplateMemberEntity if nte.isUseCase => - <div class="full-signature-block toggleContainer"> - <span class="toggle">Full Signature</span> - <div class="hiddenContent full-signature-usecase">{ signature(nte.useCaseOf.get,isSelf = true) }</div> - </div> - case _ => NodeSeq.Empty - } - } - - val selfType: NodeSeq = mbr match { - case dtpl: DocTemplateEntity if (isSelf && !dtpl.selfType.isEmpty && !isReduced) => - <dt>Self Type</dt> - <dd>{ typeToHtml(dtpl.selfType.get, hasLinks = true) }</dd> - case _ => NodeSeq.Empty - } - - val annotations: NodeSeq = { - // A list of annotations which don't show their arguments, e. g. because they are shown separately. - val annotationsWithHiddenArguments = List("deprecated", "Deprecated", "migration") - - def showArguments(annotation: Annotation) = - !(annotationsWithHiddenArguments.contains(annotation.qualifiedName)) - - if (!mbr.annotations.isEmpty) { - <dt>Annotations</dt> - <dd>{ - mbr.annotations.map { annot => - <xml:group> - <span class="name">@{ templateToHtml(annot.annotationClass) }</span>{ - if (showArguments(annot)) argumentsToHtml(annot.arguments) else NodeSeq.Empty - } - </xml:group> - } - } - </dd> - } else NodeSeq.Empty - } - - val sourceLink: NodeSeq = mbr match { - case dtpl: DocTemplateEntity if (isSelf && dtpl.sourceUrl.isDefined && dtpl.inSource.isDefined && !isReduced) => - val (absFile, _) = dtpl.inSource.get - <dt>Source</dt> - <dd>{ <a href={ dtpl.sourceUrl.get.toString } target="_blank">{ Text(absFile.file.getName) }</a> }</dd> - case _ => NodeSeq.Empty - } - - val deprecation: NodeSeq = - mbr.deprecation match { - case Some(deprecation) if !isReduced => - <dt>Deprecated</dt> - <dd class="cmt">{ bodyToHtml(deprecation) }</dd> - case _ => NodeSeq.Empty - } - - val migration: NodeSeq = - mbr.migration match { - case Some(migration) if !isReduced => - <dt>Migration</dt> - <dd class="cmt">{ bodyToHtml(migration) }</dd> - case _ => NodeSeq.Empty - } - - val mainComment: NodeSeq = mbr.comment match { - case Some(comment) if (! isReduced) => - def orEmpty[T](it: Iterable[T])(gen: =>NodeSeq): NodeSeq = - if (it.isEmpty) NodeSeq.Empty else gen - - val example = - orEmpty(comment.example) { - <div class="block">Example{ if (comment.example.length > 1) "s" else ""}: - <ol>{ - val exampleXml: List[NodeSeq] = for (ex <- comment.example) yield - <li class="cmt">{ bodyToHtml(ex) }</li> - exampleXml.reduceLeft(_ ++ Text(", ") ++ _) - }</ol> - </div> - } - - val version: NodeSeq = - orEmpty(comment.version) { - <dt>Version</dt> - <dd>{ for(body <- comment.version.toList) yield bodyToHtml(body) }</dd> - } - - val sinceVersion: NodeSeq = - orEmpty(comment.since) { - <dt>Since</dt> - <dd>{ for(body <- comment.since.toList) yield bodyToHtml(body) }</dd> - } - - val note: NodeSeq = - orEmpty(comment.note) { - <dt>Note</dt> - <dd>{ - val noteXml: List[NodeSeq] = for(note <- comment.note ) yield <span class="cmt">{bodyToHtml(note)}</span> - noteXml.reduceLeft(_ ++ Text(", ") ++ _) - }</dd> - } - - val seeAlso: NodeSeq = - orEmpty(comment.see) { - <dt>See also</dt> - <dd>{ - val seeXml: List[NodeSeq] = for(see <- comment.see ) yield <span class="cmt">{bodyToHtml(see)}</span> - seeXml.reduceLeft(_ ++ _) - }</dd> - } - - val exceptions: NodeSeq = - orEmpty(comment.throws) { - <dt>Exceptions thrown</dt> - <dd>{ - val exceptionsXml: List[NodeSeq] = - for((name, body) <- comment.throws.toList.sortBy(_._1) ) yield - <span class="cmt">{bodyToHtml(body)}</span> - exceptionsXml.reduceLeft(_ ++ Text("") ++ _) - }</dd> - } - - val todo: NodeSeq = - orEmpty(comment.todo) { - <dt>To do</dt> - <dd>{ - val todoXml: List[NodeSeq] = (for(todo <- comment.todo ) yield <span class="cmt">{bodyToHtml(todo)}</span> ) - todoXml.reduceLeft(_ ++ _) - }</dd> - } - - example ++ version ++ sinceVersion ++ exceptions ++ todo ++ note ++ seeAlso - - case _ => NodeSeq.Empty - } - // end attributes block vals --- - - val attributesInfo = implicitInformation ++ attributes ++ definitionClasses ++ fullSignature ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment - val attributesBlock = - if (attributesInfo.isEmpty) - NodeSeq.Empty - else - <dl class="attributes block"> { attributesInfo }</dl> - - val linearization = mbr match { - case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.linearizationTemplates.nonEmpty => - <div class="toggleContainer block"> - <span class="toggle">Linear Supertypes</span> - <div class="superTypes hiddenContent">{ - typesToHtml(dtpl.linearizationTypes, hasLinks = true, sep = scala.xml.Text(", ")) - }</div> - </div> - case _ => NodeSeq.Empty - } - - val subclasses = mbr match { - case dtpl: DocTemplateEntity if isSelf && !isReduced => - val subs = mutable.HashSet.empty[DocTemplateEntity] - def transitive(dtpl: DocTemplateEntity) { - for (sub <- dtpl.directSubClasses if !(subs contains sub)) { - subs add sub - transitive(sub) - } - } - transitive(dtpl) - if (subs.nonEmpty) - <div class="toggleContainer block"> - <span class="toggle">Known Subclasses</span> - <div class="subClasses hiddenContent">{ - templatesToHtml(subs.toList.sorted(Entity.EntityOrdering), scala.xml.Text(", ")) - }</div> - </div> - else NodeSeq.Empty - case _ => NodeSeq.Empty - } - - def createDiagram(f: DocTemplateEntity => Option[Diagram], description: String, id: String): NodeSeq = - if (s.docDiagrams.value) mbr match { - case dtpl: DocTemplateEntity if isSelf && !isReduced => - val diagram = f(dtpl) - if (diagram.isDefined) { - val diagramSvg = generator.generate(diagram.get, tpl, this) - if (diagramSvg != NodeSeq.Empty) { - <div class="toggleContainer block diagram-container" id={ id + "-container"}> - <span class="toggle diagram-link">{ description }</span> - <div class="diagram" id={ id }>{ diagramSvg }</div> - <div id="diagram-controls" class="hiddenContent"> - <button id="diagram-zoom-out" class="diagram-btn"><i class="material-icons"></i></button> - <button id="diagram-zoom-in" class="diagram-btn"><i class="material-icons"></i></button> - <button title="Toggle full-screen" id="diagram-fs" class="diagram-btn to-full"><i class="material-icons"></i></button> - </div> - </div> - } else NodeSeq.Empty - } else NodeSeq.Empty - case _ => NodeSeq.Empty - } else NodeSeq.Empty // diagrams not generated - - val typeHierarchy = createDiagram(_.inheritanceDiagram, "Type Hierarchy", "inheritance-diagram") - val contentHierarchy = createDiagram(_.contentDiagram, "Content Hierarchy", "content-diagram") - - memberComment ++ authorComment ++ paramComments ++ attributesBlock ++ linearization ++ subclasses ++ typeHierarchy ++ contentHierarchy - } - - def boundsToHtml(hi: Option[TypeEntity], lo: Option[TypeEntity], hasLinks: Boolean): NodeSeq = { - def bound0(bnd: Option[TypeEntity], pre: String): NodeSeq = bnd match { - case None => NodeSeq.Empty - case Some(tpe) => scala.xml.Text(pre) ++ typeToHtml(tpe, hasLinks) - } - bound0(lo, " >: ") ++ bound0(hi, " <: ") - } - - def visibility(mbr: MemberEntity): Option[comment.Paragraph] = { - import comment._ - import comment.{ Text => CText } - mbr.visibility match { - case PrivateInInstance() => - Some(Paragraph(CText("private[this]"))) - case PrivateInTemplate(owner) if (owner == mbr.inTemplate) => - Some(Paragraph(CText("private"))) - case PrivateInTemplate(owner) => - Some(Paragraph(Chain(List(CText("private["), EntityLink(comment.Text(owner.qualifiedName), LinkToTpl(owner)), CText("]"))))) - case ProtectedInInstance() => - Some(Paragraph(CText("protected[this]"))) - case ProtectedInTemplate(owner) if (owner == mbr.inTemplate) => - Some(Paragraph(CText("protected"))) - case ProtectedInTemplate(owner) => - Some(Paragraph(Chain(List(CText("protected["), EntityLink(comment.Text(owner.qualifiedName), LinkToTpl(owner)), CText("]"))))) - case Public() => - None - } - } - - /** name, tparams, params, result */ - def signature(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = { - - def inside(hasLinks: Boolean, nameLink: String = ""): NodeSeq = - <xml:group> - <span class="modifier_kind"> - <span class="modifier">{ mbr.flags.map(flag => inlineToHtml(flag.text) ++ scala.xml.Text(" ")) }</span> - <span class="kind">{ kindToString(mbr) }</span> - </span> - <span class="symbol"> - { - val nameClass = - if (mbr.isImplicitlyInherited) - if (mbr.isShadowedOrAmbiguousImplicit) - "implicit shadowed" - else - "implicit" - else - "name" - - val nameHtml = { - val value = if (mbr.isConstructor) tpl.name else mbr.name - val span = if (mbr.deprecation.isDefined) - <span class={ nameClass + " deprecated"} title={"Deprecated: "+bodyToStr(mbr.deprecation.get)}>{ value }</span> - else - <span class={ nameClass }>{ value }</span> - val encoded = scala.reflect.NameTransformer.encode(value) - if (encoded != value) { - span % new UnprefixedAttribute("title", - "gt4s: " + encoded + - span.attribute("title").map( - node => ". " + node - ).getOrElse(""), - scala.xml.Null) - } else { - span - } - } - if (!nameLink.isEmpty) - <a href={nameLink}>{nameHtml}</a> - else nameHtml - }{ - def tparamsToHtml(mbr: Any): NodeSeq = mbr match { - case hk: HigherKinded => - val tpss = hk.typeParams - if (tpss.isEmpty) NodeSeq.Empty else { - def tparam0(tp: TypeParam): NodeSeq = - <span name={ tp.name }>{ tp.variance + tp.name }{ tparamsToHtml(tp) }{ boundsToHtml(tp.hi, tp.lo, hasLinks)}</span> - def tparams0(tpss: List[TypeParam]): NodeSeq = (tpss: @unchecked) match { - case tp :: Nil => tparam0(tp) - case tp :: tps => tparam0(tp) ++ Text(", ") ++ tparams0(tps) - } - <span class="tparams">[{ tparams0(tpss) }]</span> - } - case _ => NodeSeq.Empty - } - tparamsToHtml(mbr) - }{ - if (isReduced) NodeSeq.Empty else { - def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = { - def param0(vl: ValueParam): NodeSeq = - // notice the }{ in the next lines, they are necessary to avoid an undesired whitespace in output - <span name={ vl.name }>{ - Text(vl.name) - }{ Text(": ") ++ typeToHtml(vl.resultType, hasLinks) }{ - vl.defaultValue match { - case Some(v) => Text(" = ") ++ treeToHtml(v) - case None => NodeSeq.Empty - } - }</span> - - def params0(vlss: List[ValueParam]): NodeSeq = vlss match { - case Nil => NodeSeq.Empty - case vl :: Nil => param0(vl) - case vl :: vls => param0(vl) ++ Text(", ") ++ params0(vls) - } - def implicitCheck(vlss: List[ValueParam]): NodeSeq = vlss match { - case vl :: vls => if(vl.isImplicit) { <span class="implicit">implicit </span> } else Text("") - case _ => Text("") - } - vlsss map { vlss => <span class="params">({implicitCheck(vlss) ++ params0(vlss) })</span> } - } - mbr match { - case cls: Class => paramsToHtml(cls.valueParams) - case ctr: Constructor => paramsToHtml(ctr.valueParams) - case dfe: Def => paramsToHtml(dfe.valueParams) - case _ => NodeSeq.Empty - } - } - }{ if (isReduced) NodeSeq.Empty else { - mbr match { - case tme: MemberEntity if (tme.isDef || tme.isVal || tme.isLazyVal || tme.isVar) => - <span class="result">: { typeToHtml(tme.resultType, hasLinks) }</span> - - case abt: MemberEntity with AbstractType => - val b2s = boundsToHtml(abt.hi, abt.lo, hasLinks) - if (b2s != NodeSeq.Empty) - <span class="result">{ b2s }</span> - else NodeSeq.Empty - - case alt: MemberEntity with AliasType => - <span class="result"> = { typeToHtml(alt.alias, hasLinks) }</span> - - case tpl: MemberTemplateEntity if !tpl.parentTypes.isEmpty => - <span class="result"> extends { typeToHtml(tpl.parentTypes.map(_._2), hasLinks) }</span> - - case _ => NodeSeq.Empty - } - }} - </span> - </xml:group> - mbr match { - case dte: DocTemplateEntity if !isSelf => - <h4 class="signature">{ inside(hasLinks = true, nameLink = relativeLinkTo(dte)) }</h4> ++ permalink(dte, isSelf) - case _ if isSelf => - <h4 id="signature" class="signature">{ inside(hasLinks = true) }</h4> - case _ => - <h4 class="signature">{ inside(hasLinks = true) }</h4> ++ permalink(mbr) - } - - } - - /** */ - def treeToHtml(tree: TreeEntity): NodeSeq = { - - /** Makes text good looking in the html page : newlines and basic indentation, - * You must change this function if you want to improve pretty printing of default Values - */ - def codeStringToXml(text: String): NodeSeq = { - var goodLookingXml: NodeSeq = NodeSeq.Empty - var indent = 0 - for (c <- text) c match { - case '{' => indent+=1 - goodLookingXml ++= Text("{") - case '}' => indent-=1 - goodLookingXml ++= Text("}") - case '\n' => - goodLookingXml++= <br/> ++ indentation - case _ => goodLookingXml ++= Text(c.toString) - } - def indentation:NodeSeq = { - var indentXml = NodeSeq.Empty - for (x <- 1 to indent) indentXml ++= Text(" ") - indentXml - } - goodLookingXml - } - - var index = 0 - val str = tree.expression - val length = str.length - var myXml: NodeSeq = NodeSeq.Empty - for ((from, (member, to)) <- tree.refEntity.toSeq) { - if (index < from) { - myXml ++= codeStringToXml(str.substring(index,from)) - index = from - } - if (index == from) { - member match { - case mbr: DocTemplateEntity => - val link = relativeLinkTo(mbr) - myXml ++= <span class="name"><a href={link}>{str.substring(from, to)}</a></span> - case mbr: MemberEntity => - val anchor = "#" + mbr.signature - val link = relativeLinkTo(mbr.inTemplate) - myXml ++= <span class="name"><a href={link ++ anchor}>{str.substring(from, to)}</a></span> - } - index = to - } - } - - if (index <= length-1) - myXml ++= codeStringToXml(str.substring(index, length )) - - if (length < 36) - <span class="symbol">{ myXml }</span> - else - <span class="defval" name={ myXml }>{ "..." }</span> - } - - private def argumentsToHtml(argss: List[ValueArgument]): NodeSeq = { - def argumentsToHtml0(argss: List[ValueArgument]): NodeSeq = argss match { - case Nil => NodeSeq.Empty - case arg :: Nil => argumentToHtml(arg) - case arg :: args => argumentToHtml(arg) ++ scala.xml.Text(", ") ++ argumentsToHtml0(args) - } - <span class="args">({ argumentsToHtml0(argss) })</span> - } - - private def argumentToHtml(arg: ValueArgument): NodeSeq = { - <span> - { - arg.parameter match { - case Some(param) => Text(param.name + " = ") - case None => NodeSeq.Empty - } - } - { treeToHtml(arg.value) } - </span> - } - - private def bodyToStr(body: comment.Body): String = - body.blocks flatMap (blockToStr(_)) mkString "" - - private def blockToStr(block: comment.Block): String = block match { - case comment.Paragraph(in) => inlineToStr(in) - case _ => block.toString - } - - private def typeToHtmlWithStupidTypes(tpl: TemplateEntity, superTpl: TemplateEntity, superType: TypeEntity): NodeSeq = - if (tpl.universe.settings.useStupidTypes.value) - superTpl match { - case dtpl: DocTemplateEntity => - val sig = signature(dtpl, isSelf = false, isReduced = true) \ "_" - sig - case tpl: TemplateEntity => - Text(tpl.name) - } - else - typeToHtml(superType, hasLinks = true) - - private def constraintToHtml(constraint: Constraint): NodeSeq = constraint match { - case ktcc: KnownTypeClassConstraint => - scala.xml.Text(ktcc.typeExplanation(ktcc.typeParamName) + " (" + ktcc.typeParamName + ": ") ++ - templateToHtml(ktcc.typeClassEntity) ++ scala.xml.Text(")") - case tcc: TypeClassConstraint => - scala.xml.Text(tcc.typeParamName + " is ") ++ - <a href="http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-scala" target="_blank"> - context-bounded</a> ++ scala.xml.Text(" by " + tcc.typeClassEntity.qualifiedName + " (" + tcc.typeParamName + ": ") ++ - templateToHtml(tcc.typeClassEntity) ++ scala.xml.Text(")") - case impl: ImplicitInScopeConstraint => - scala.xml.Text("an implicit value of type ") ++ typeToHtml(impl.implicitType, hasLinks = true) ++ scala.xml.Text(" is in scope") - case eq: EqualTypeParamConstraint => - scala.xml.Text(eq.typeParamName + " is " + eq.rhs.name + " (" + eq.typeParamName + " =:= ") ++ - typeToHtml(eq.rhs, hasLinks = true) ++ scala.xml.Text(")") - case bt: BoundedTypeParamConstraint => - scala.xml.Text(bt.typeParamName + " is a superclass of " + bt.lowerBound.name + " and a subclass of " + - bt.upperBound.name + " (" + bt.typeParamName + " >: ") ++ - typeToHtml(bt.lowerBound, hasLinks = true) ++ scala.xml.Text(" <: ") ++ - typeToHtml(bt.upperBound, hasLinks = true) ++ scala.xml.Text(")") - case lb: LowerBoundedTypeParamConstraint => - scala.xml.Text(lb.typeParamName + " is a superclass of " + lb.lowerBound.name + " (" + lb.typeParamName + " >: ") ++ - typeToHtml(lb.lowerBound, hasLinks = true) ++ scala.xml.Text(")") - case ub: UpperBoundedTypeParamConstraint => - scala.xml.Text(ub.typeParamName + " is a subclass of " + ub.upperBound.name + " (" + ub.typeParamName + " <: ") ++ - typeToHtml(ub.upperBound, hasLinks = true) ++ scala.xml.Text(")") - } -} - -object Template { - /* Vlad: Lesson learned the hard way: don't put any stateful code that references the model here, - * it won't be garbage collected and you'll end up filling the heap with garbage */ - - def lowerFirstLetter(s: String) = if (s.length >= 1) s.substring(0,1).toLowerCase() + s.substring(1) else s -} diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css index 8c20810784..08add0efa1 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css @@ -33,6 +33,10 @@ display: none; } +.diagram-container > span.toggle { + z-index: 9; +} + .diagram { overflow: hidden; padding-top:15px; @@ -73,7 +77,7 @@ z-index: 2; } -#inheritance-diagram-container.full-screen { +.diagram-container.full-screen { position: fixed !important; margin: 0; border-radius: 0; @@ -85,11 +89,11 @@ z-index: 10000; } -#inheritance-diagram-container.full-screen > span.toggle { +.diagram-container.full-screen > span.toggle { display: none; } -#inheritance-diagram-container.full-screen > div.diagram { +.diagram-container.full-screen > div.diagram { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js index 5d139c1080..b13732760a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js @@ -60,8 +60,8 @@ $(document).ready(function() diagrams.initHighlighting(); $("button#diagram-fs").click(function() { - $("#inheritance-diagram-container").toggleClass("full-screen"); - $("#inheritance-diagram-container > div.diagram").css({ + $(".diagram-container").toggleClass("full-screen"); + $(".diagram-container > div.diagram").css({ height: $("svg").height() + "pt" }); @@ -155,7 +155,7 @@ diagrams.initHighlighting = function() */ diagrams.resize = function() { // available width - var availableWidth = $("body").width() - 100; + var availableWidth = $(".diagram-container").width(); $(".diagram-container").each(function() { // unregister click event on whole div @@ -163,7 +163,7 @@ diagrams.resize = function() { var diagramWidth = $(".diagram", this).data("width"); var diagramHeight = $(".diagram", this).data("height"); - if(diagramWidth > availableWidth) { + if (diagramWidth > availableWidth) { // resize diagram var height = diagramHeight / diagramWidth * availableWidth; $(".diagram svg", this).width(availableWidth); @@ -204,7 +204,7 @@ diagrams.toggle = function(container, dontAnimate) $("#diagram-controls", container).show(); - $("#inheritance-diagram-container").on('mousewheel.focal', function(e) { + $(".diagram-container").on('mousewheel.focal', function(e) { e.preventDefault(); var delta = e.delta || e.originalEvent.wheelDelta; var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0; 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..d805ccc1ac 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,12 +404,136 @@ 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; + overflow-y: hidden; max-width: 1140px; - margin: 5em auto 0; + margin: 4em auto 0; +} + +div#content-container > div#subpackage-spacer { + float: right; + height: 100%; + margin: 1.1rem 0.5rem 0 0.5em; + font-size: 0.8em; + min-width: 8rem; +} + +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-entities { + margin: 0.3rem 0; +} + +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.current-entities > *:nth-child(1), +div#packages > ul > li.current-entities > *:nth-child(2) { + float: left; + display: inline; + height: 1rem; + width: 1rem; + margin: 1px 0 0 0; + cursor: pointer; +} + +div#packages > ul > li > a.class { + background: url("class.svg") no-repeat center; + background-size: 0.9rem; +} + +div#packages > ul > li > a.trait { + background: url("trait.svg") no-repeat center; + background-size: 0.9rem; +} + +div#packages > ul > li > a.object { + background: url("object.svg") no-repeat center; + background-size: 0.9rem; +} + +div#packages > ul > li > a.abstract.type { + background: url("abstract_type.svg") no-repeat center; + background-size: 0.9rem; +} + +div#packages > ul > li > a { + text-decoration: none !important; + margin-left: 1px; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; + font-size: 0.9em; +} + +/* 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 { @@ -554,7 +678,7 @@ div#results-content > div#member-results > ul.entities > li > ul.members > li > div#results-content > div#entity-results > ul.entities > li > ul.members > li > span.kind, div#results-content > div#entity-results > ul.entities > li > ul.members > li > span.tail { margin-right: 0.6em; - font-family: "Source Code Pro"; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; } div#results-content > div#member-results > ul.entities > li > ul.members > li > span.kind { @@ -564,7 +688,7 @@ div#results-content > div#member-results > ul.entities > li > ul.members > li > div#results-content > div#member-results > ul.entities > li > ul.members > li > a.label, div#results-content > div#entity-results > ul.entities > li > ul.members > li > a.label { color: #2C3D9B; - font-family: "Source Code Pro"; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; } /** Scrollpane settings needed for jquery.scrollpane.min.js */ @@ -710,6 +834,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..1a2e62b314 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 @@ -21,6 +21,20 @@ var Index = {}; } })(Index); +/** Find query string from URL */ +var QueryString = function(key) { + if (QueryString.map === undefined) { // only calc once + QueryString.map = {}; + var keyVals = window.location.search.split("?").pop().split("&"); + keyVals.forEach(function(elem) { + var pair = elem.split("="); + if (pair.length == 2) QueryString.map[pair[0]] = pair[1]; + }); + } + + return QueryString.map[key]; +}; + $(document).ready(function() { // Clicking #doc-title returns the user to the root package $("#doc-title").click(function() { document.location = toRoot + "index.html" }); @@ -33,15 +47,17 @@ $(document).ready(function() { configureTextFilter(); - $("#index-input").on("focus", function(e) { - $("#textfilter > .input > .clear").show(); - }); - - $("#index-input").on("blur", function() { - setTimeout(function() { + $("#index-input").on("input", function(e) { + if($(this).val().length > 0) + $("#textfilter > .input > .clear").show(); + else $("#textfilter > .input > .clear").hide(); - }, 10); }); + + if (QueryString("search") !== undefined) { + $("#index-input").val(QueryString("search")); + searchAll(); + } }); /* Handles all key presses while scrolling around with keyboard shortcuts in search results */ @@ -98,7 +114,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 +148,7 @@ function handleKeyNavigation() { var $old = items.next(); $old.addClass("selected"); + scroller.scrollDown($old); $(window).bind("keydown", function(e) { switch ( e.keyCode ) { @@ -228,6 +245,8 @@ function configureTextFilter() { $("div#search-results").hide(); $("#search > span.close-results").hide(); $("#search > span#doc-title").show(); + + $(this).hide(); }); }); @@ -412,7 +431,12 @@ function handleSearchedPackage(res, regExp) { */ function searchEntity(entity, ul, regExp) { return new Promise(function(resolve, reject) { - var matchingMembers = $.grep(entity.members, function(member, i) { + var allMembers = + (entity.members_trait || []) + .concat(entity.members_class || []) + .concat(entity.members_object || []) + + var matchingMembers = $.grep(allMembers, function(member, i) { return regExp.test(member.label); }); @@ -482,7 +506,7 @@ function listItem(entity, regExp) { } else { var spacer = document.createElement("div"); spacer.className = "icon spacer"; - li.appendChild(spacer); + li.insertBefore(spacer, iconElem); } var ul = document.createElement("ul"); @@ -510,6 +534,11 @@ function searchAll() { return; } + // Replace ?search=X with current search string if not hosted locally on Chrome + try { + window.history.replaceState({}, "", "?search=" + searchStr); + } catch(e) {} + $("div#results-content > span.search-text").remove(); var memberResults = document.getElementById("member-results"); diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_comp_trait.svg b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_comp_trait.svg new file mode 100644 index 0000000000..56eccd03ba --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_comp_trait.svg @@ -0,0 +1,57 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="72px" height="72px" viewBox="0 0 72 72" version="1.1"> + <defs> + <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-1"> + <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/> + <feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"/> + <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.14 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"/> + <feMerge> + <feMergeNode in="shadowMatrixOuter1"/> + <feMergeNode in="SourceGraphic"/> + </feMerge> + </filter> + <circle id="path-2" cx="32" cy="32" r="32"/> + <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-4"> + <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/> + <feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"/> + <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.14 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"/> + <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetInner1"/> + <feGaussianBlur stdDeviation="0" in="shadowOffsetInner1" result="shadowBlurInner1"/> + <feComposite in="shadowBlurInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"/> + <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.14 0" in="shadowInnerInner1" type="matrix" result="shadowMatrixInner1"/> + <feOffset dx="0" dy="-1" in="SourceAlpha" result="shadowOffsetInner2"/> + <feGaussianBlur stdDeviation="0" in="shadowOffsetInner2" result="shadowBlurInner2"/> + <feComposite in="shadowBlurInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"/> + <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.14 0" in="shadowInnerInner2" type="matrix" result="shadowMatrixInner2"/> + <feMerge> + <feMergeNode in="shadowMatrixOuter1"/> + <feMergeNode in="SourceGraphic"/> + <feMergeNode in="shadowMatrixInner1"/> + <feMergeNode in="shadowMatrixInner2"/> + </feMerge> + </filter> + <path id="path-5" d="M32 61C49.673112 61 64 48.0162577 64 32 64 15.9837423 49.673112 3 32 3 14.326888 3 0 15.9837423 0 32 0 48.0162577 14.326888 61 32 61Z"/> + </defs> + <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Artboard-1" transform="translate(-298.000000, -91.000000)"> + <g id="BG" transform="translate(302.000000, 91.000000)"> + <g id="Icon"> + <mask id="mask-3" fill="white"> + <use xlink:href="#path-2"/> + </mask> + <use id="Mask" fill="#19AACF" filter="url(#filter-1)" xlink:href="#path-2"/> + <rect id="Rectangle-2" opacity="0.3" fill="#000000" mask="url(#mask-3)" x="-8" y="33" width="80" height="31"/> + <mask id="mask-6" fill="white"> + <use xlink:href="#path-5"/> + </mask> + <use id="Mask" fill="#2C6C8D" filter="url(#filter-4)" xlink:href="#path-5"/> + <text id="t" mask="url(#mask-6)" font-family="Open Sans, Helvetica Neueu, Sans-serif" font-size="40" font-weight="normal" fill="#FFFFFF"> + <tspan x="17" y="47"> + O + </tspan> + </text> + <rect id="Rectangle-2" opacity="0.190065299" fill="#000000" mask="url(#mask-6)" x="-8" y="2" width="80" height="31"/> + </g> + </g> + </g> + </g> +</svg> diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.svg b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.svg deleted file mode 100644 index a11d568d94..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" fill="#ffffff" height="24" viewBox="0 0 24 24"><path d="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z" /></svg> diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js index 750c9099fd..52fb1770ee 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js @@ -5,7 +5,7 @@ function Scheduler() { var scheduler = this; var resolution = 0; this.timeout = undefined; - this.queues = new Array(0); // an array of work pacakges indexed by index in the labels table. + this.queues = new Array(0); // an array of work packages indexed by index in the labels table. this.labels = new Array(0); // an indexed array of labels indexed by priority. This should be short. this.label = function(name, priority) { 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..f222749dd2 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 @@ -40,7 +40,7 @@ body { text-align: center; color: #858484; bottom: 0; - height: 20px; + min-height: 20px; margin: 0 1em 0.5em; } @@ -53,10 +53,6 @@ body { text-decoration: none; } -body.trait div#definition { - background-color: #2e6d82; -} - #types ol li > p { margin-top: 5px; } @@ -71,8 +67,7 @@ body.trait div#definition { padding: 5px 0; padding: 0; margin: 0.5em; - border-radius: 0.2em; - box-shadow: 0 0 10px rgba(0,0,0,0.2); + min-height: 4.72em; } #definition > a > img { @@ -86,7 +81,8 @@ body.trait div#definition { } #definition > h1 { - color: white; + float: left; + color: #103a51; display: inline-block; overflow: hidden; margin-top: 10px; @@ -94,19 +90,28 @@ body.trait div#definition { } #definition h1 > a { - color: #fff !important; + color: #103a51 !important; text-decoration: none !important; } +#template ol > li > span.permalink > a > i { + transform: rotate(-45deg); +} + #definition #owner { - color: #ffffff; + color: #103a51; padding-top: 1.3em; font-size: 0.8em; overflow: hidden; } +#definition > h3 { + margin-top: 0.85em; + padding: 0; +} + #definition #owner > a { - color: #ffffff; + color: #103a51; } #definition #owner > a:hover { @@ -114,14 +119,13 @@ body.trait div#definition { } #signature { - background-color:#c2d2dc; + background-color: #c2d2dc; min-height: 18px; font-size: 0.9em; padding: 8px; - width: 100%; color: #103a51; - border-bottom-left-radius: 0.2em; - border-bottom-right-radius: 0.2em; + border-radius: 0.2em; + margin: 0 0.5rem; } #signature > span.modifier_kind { @@ -133,6 +137,10 @@ body.trait div#definition { padding-left: 0; } +span.symbol > a { + display: inline-block; +} + #signature > span.symbol { text-align: left; display: inline; @@ -147,7 +155,7 @@ body.trait div#definition { .toggleContainer .toggle { position: relative; color: #103a51; - margin-left: 2.3em; + margin-left: 0.3em; cursor: pointer; -webkit-touch-callout: none; -webkit-user-select: none; @@ -192,18 +200,6 @@ body.trait div#definition { opacity: 1; } -.value #definition { - background-color: #103A51; /* blue */ -} - -.type #definition { - background-color: rgba(49, 101, 85, 1); /* green */ -} - -.abstract.type #definition { - background-color: #447A90; -} - .big-circle { box-sizing: content-box; height: 5.7em; @@ -220,18 +216,22 @@ body.trait div#definition { background: url("class.svg") no-repeat center; } -.big-circle.cl.companion { +.big-circle.class-companion-object { background: url("class_comp.svg") no-repeat center; } -.big-circle.ob.companion { +.big-circle.object-companion-class { background: url("object_comp.svg") no-repeat center; } -.big-circle.tr.companion { +.big-circle.trait-companion-object { background: url("trait_comp.svg") no-repeat center; } +.big-circle.object-companion-trait { + background: url("object_comp_trait.svg") no-repeat center; +} + .big-circle.object { background: url("object.svg") no-repeat center; } @@ -250,12 +250,14 @@ body.abstract.type div.big-circle { #template { margin: 0.9em 0.75em 0.75em; - border-radius: 0.2em; - background-color: #fff; - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.1); - box-shadow: 0 0 10px rgba(0,0,0,0.1); padding-bottom: 0.5em; - overflow: hidden; +} + +#template h3 { + color: #103a51; + height: 2em; + padding: 1em 1em 2em; + font-size: 1.2em; } #order { @@ -263,7 +265,7 @@ body.abstract.type div.big-circle { } h3 { - color: white; + color: #103a51; padding: 5px 10px; font-size: 1em; font-weight: bold; @@ -288,21 +290,10 @@ dl.attributes > dd { min-height: 15px; } -#template .values > h3 { - color: #2C475C; - height: 2em; - padding: 1em 1em 2em; - font-size: 1.2em; -} - .values ol li:last-child { margin-bottom: 5px; } -#template .types > h3 { - height: 18px; -} - #constructors > h3 { height: 2em; padding: 1em 1em 2em; @@ -333,30 +324,38 @@ dl.attributes > dd { /* Member cells */ div.members > ol { - background-color: white; list-style: none; - padding: 0 10px; } div.members > ol > li { display: table; width: 100%; position: relative; - background-color: #e1e7ed; + background-color: #fff; border-radius: 0.2em; color: #103a51; padding: 5px 0 5px; margin-bottom: 0.4em; - min-height: 2.8em; + min-height: 3.7em; + border-left: 0.25em solid white; + -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.1); + box-shadow: 0 0 10px rgba(0,0,0,0.1); + transition: 0.1s; } div.members > ol >li.selected, div.members > ol > li:hover { - background-color: #c2d2dc; + background-color: #dae7f0; + border-left-color: #dae7f0; +} + +div.members > ol >li[fullComment=yes].selected, +div.members > ol > li[fullComment=yes]:hover { + cursor: pointer; + border-left: 0.25em solid #72D0EB; } div.members > ol > li:last-child { - border: 0; padding: 5px 0 5px; } @@ -372,7 +371,7 @@ div.members > ol > li:last-child { } .signature { - font-family: "Source Code Pro"; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; font-size: 0.8rem; line-height: 18px; clear: both; @@ -380,7 +379,7 @@ div.members > ol > li:last-child { } .modifier_kind { - font-family: "Source Code Pro"; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; font-size: 0.8rem; padding-right: 0.5em; text-align: right; @@ -390,7 +389,7 @@ div.members > ol > li:last-child { } .symbol { - font-family: "Source Code Pro"; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; } a > .symbol > .name { @@ -418,6 +417,16 @@ span.symbol > span.name { font-weight: bold; } +#types > ol > li > span.symbol > span.result { + display: none; +} + +#types > ol > li > span.symbol > span.result.alias, +#types > ol > li:hover > span.symbol > span.result, +#types > ol > li.open > span.symbol > span.result { + display: inline; +} + .symbol > .implicit { display: inline-block; font-weight: bold; @@ -463,7 +472,7 @@ i.unfold-arrow { #template .values .name { font-weight: 600; - color: darkblue; + color: #315479; } #template .types .name { @@ -506,31 +515,35 @@ div#definition > h4#signature > span.modifier_kind > i.unfold-arrow, #definition .morelinks { text-align: right; - position: absolute; - top: 2.95em; - right: 1em; - width: 450px; - font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; } #definition .morelinks a { - color: #EBEBEB; + color: #103a51; } #template .members li .permalink { position: absolute; - top: 5px; - right: 5px; + left: 0.25em; + top: 0.95em; } #definition .permalink { - position: absolute; - top: 10px; - right: 15px; + display: none; + color: black; } #definition .permalink a { - color: #EBEBEB; + color: #103a51; + transform: rotate(-45deg); +} + +#definition > h1 > span > a > i { + font-size: 1.4rem; +} + +#template ol > li > span.permalink > a > i { + color: #fff; } #template .members li .permalink, @@ -584,7 +597,7 @@ div#definition > h4#signature > span.modifier_kind > i.unfold-arrow, background-color: #fff; margin: 5px 0; display: block; - font-family: "Source Code Pro"; + font-family: "Source Code Pro", "Monaco", "Ubuntu Mono Regular", "Lucida Console", monospace; border-radius: 0.2em; overflow-x: auto; } @@ -719,6 +732,7 @@ div.fullcomment .block { } div.fullcommenttop .block { + position: relative; padding: 1em; margin: 0.5em 0; border-radius: 0.2em; @@ -727,6 +741,16 @@ div.fullcommenttop .block { box-shadow: 0 0 10px rgba(0,0,0,0.1); } +div.fullcommenttop .toggleContainer { + border-left: 0 solid #72D0EB; + transition: 0.1s; + cursor: pointer; +} + +div.fullcommenttop .toggleContainer:hover { + border-left: 0.25em solid #72D0EB; +} + div#comment, div#mbrsel, div#template, @@ -839,12 +863,9 @@ div.fullcomment dl.paramcmts > dd { margin: 0.8em; border-radius: 0.2em; background-color: #364550; - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.1); - box-shadow: 0 0 10px rgba(0,0,0,0.1); + -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2); + box-shadow: 0 0 10px rgba(0,0,0,0.2); position: relative; - margin-bottom: -1em; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } #mbrsel > div.toggle { @@ -877,6 +898,12 @@ div.fullcomment dl.paramcmts > dd { left: 0; top: 0; color: #fff; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } #mbrsel > div.toggle.open > i { @@ -1025,7 +1052,7 @@ div.fullcomment dl.paramcmts > dd { /* Media query rules for smaller viewport */ @media only screen /* Large screen with a small window */ -and (max-width: 560px) +and (max-width: 650px) , screen /* HiDPI device like Nexus 5 */ and (max-device-width: 360px) @@ -1058,16 +1085,23 @@ and (-webkit-device-pixel-ratio: 2) height: 6em; } + #definition > h1 { + font-size: 1em; + margin-right: 0.3em; + } + + #definition > h3 { + float: left; + margin: 0.3em 0; + } + + #definition > #owner { + padding-top: 2.6em; + } + #definition .morelinks { text-align: left; - left: 7.2em; font-size: 0.8em; - top: auto; - bottom: 0.5em; - } - - #signature { - top: 6.7em; } .big-circle { 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..64177a7723 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 @@ -4,10 +4,10 @@ var $panzoom = undefined; $(document).ready(function() { // Add zoom functionality to type inheritance diagram - $panzoom = $("#inheritance-diagram").panzoom({ + $panzoom = $(".diagram-container > .diagram").panzoom({ increment: 0.1, minScale: 1, - maxScale: 3, + maxScale: 7, transition: true, duration: 200, contain: 'invert', @@ -16,15 +16,10 @@ $(document).ready(function() { $zoomOut: $('#diagram-zoom-out'), }); - $("#template > div > div > ol > li > span > a").click(function(e) { - var href = $(this).attr("href"); - if (href.indexOf("#") != -1) { - e.preventDefault(); - location.hash = href.split("#").pop(); - $("#template > div > div > ol > li").removeClass("selected"); - var parent = $(this).parent().parent().addClass("selected"); - $("#content-container").animate({scrollTop: $("#content-container").scrollTop() + $(this).offset().top - $("#search").height() - 22}, 500); - } + 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 = { @@ -58,21 +53,22 @@ $(document).ready(function() { function exposeMember(jqElem) { var jqElemParent = jqElem.parent(), parentName = jqElemParent.attr("name"), - linearizationName = /^([^#]*)(#.*)?$/gi.exec(parentName)[1]; + ancestorName = /^([^#]*)(#.*)?$/gi.exec(parentName)[1]; // switch visibility filter if necessary if (jqElemParent.attr("visbl") == "prt") { toggleVisibilityFilter(controls.visibility.all, controls.visibility.publicOnly); } - // toggle appropriate linearization buttons - if (linearizationName) { - $("#linearization li.out[name='" + linearizationName + "']").removeClass("out").addClass("in"); + // toggle appropriate ancestor filter buttons + if (ancestorName) { + $("#filterby li.out[name='" + ancestorName + "']").removeClass("out").addClass("in"); } filter(); jqElemParent.addClass("selected"); - $("#content-container").animate({scrollTop: jqElemParent.offset().top - $("#search").height() - 5 }, 1000); + commentToggleFct(jqElemParent); + $("#content-scroll-container").animate({scrollTop: $("#content-scroll-container").scrollTop() + jqElemParent.offset().top - $("#search").height() - 23 }, 1000); } var isHiddenClass = function (name) { @@ -140,10 +136,10 @@ $(document).ready(function() { }); $("#memberfilter > .clear").click(function() { $("#memberfilter input").attr("value", ""); + $(this).hide(); filter(); }); $(document).keydown(function(event) { - if (event.keyCode == 9) { // tab $("#index-input", window.parent.document).focus(); input.attr("value", ""); @@ -155,8 +151,7 @@ $(document).ready(function() { if ($(this).hasClass("in")) { $(this).removeClass("in"); $(this).addClass("out"); - } - else if ($(this).hasClass("out")) { + } else if ($(this).hasClass("out")) { $(this).removeClass("out"); $(this).addClass("in"); } @@ -167,8 +162,7 @@ $(document).ready(function() { if ($(this).hasClass("in")) { $(this).removeClass("in"); $(this).addClass("out"); - } - else if ($(this).hasClass("out")) { + } else if ($(this).hasClass("out")) { $(this).removeClass("out"); $(this).addClass("in"); } @@ -208,19 +202,16 @@ $(document).ready(function() { filter(); }); $("#order > ol > li.alpha").click(function() { - if ($(this).hasClass("out")) { + if ($(this).hasClass("out")) orderAlpha(); - } }) $("#order > ol > li.inherit").click(function() { - if ($(this).hasClass("out")) { + if ($(this).hasClass("out")) orderInherit(); - } }); $("#order > ol > li.group").click(function() { - if ($(this).hasClass("out")) { + if ($(this).hasClass("out")) orderGroup(); - } }); $("#groupedMembers").hide(); @@ -237,14 +228,14 @@ $(document).ready(function() { }); /* Add toggle arrows */ - //var docAllSigs = $("#template li").has(".fullcomment").find(".signature"); - // trying to speed things up a little bit - var docAllSigs = $("#template li[fullComment=yes] .modifier_kind"); - - function commentToggleFct(signature){ - var parent = signature.parent(); - var shortComment = $(".shortcomment", parent); - var fullComment = $(".fullcomment", parent); + $("#template li[fullComment=yes] .modifier_kind").addClass("closed"); + + function commentToggleFct(element){ + $("#template li.selected").removeClass("selected"); + element.toggleClass("open"); + var signature = element.find(".modifier_kind") + var shortComment = element.find(".shortcomment"); + var fullComment = element.find(".fullcomment"); var vis = $(":visible", fullComment); signature.toggleClass("closed").toggleClass("opened"); if (vis.length > 0) { @@ -266,15 +257,15 @@ $(document).ready(function() { } } }; - docAllSigs.addClass("closed"); - docAllSigs.click(function() { + + $("#template li[fullComment=yes]").click(function() { commentToggleFct($(this)); }); /* Linear super types and known subclasses */ function toggleShowContentFct(e){ e.toggleClass("open"); - var content = $(".hiddenContent", e.parent().get(0)); + var content = $(".hiddenContent", e); if(content.is(':visible')) { if (!isMobile()) content.slideUp(100); else content.hide(); @@ -284,12 +275,14 @@ $(document).ready(function() { } }; - $(".toggle:not(.diagram-link)").click(function() { + $(".toggleContainer:not(.diagram-container):not(.full-signature-block)").click(function() { toggleShowContentFct($(this)); }); - // Set parent window title - windowTitle(); + $(".toggleContainer.full-signature-block").click(function() { + toggleShowContentFct($(this)); + return false; + }); if ($("#order > ol > li.group").length == 1) { orderGroup(); }; @@ -299,22 +292,34 @@ $(document).ready(function() { return $(memberSelector); } - // highlight and jump to selected member + // highlight and jump to selected member if an anchor is provided if (window.location.hash) { var jqElem = findElementByHash(window.location.hash); - if (jqElem.length > 0) { + if (jqElem.length > 0) exposeMember(jqElem); - } } - $("#mbrsel-input").on("focus", function() { - $("#memberfilter > .clear").show(); + $("#template span.permalink").click(function(e) { + e.preventDefault(); + var href = $("a", this).attr("href"); + if (href.indexOf("#") != -1) { + var hash = href.split("#").pop() + try { + window.history.pushState({}, "", "#" + hash) + } catch (e) { + // fallback for file:// URLs, has worse scrolling behavior + location.hash = hash; + } + exposeMember(findElementByHash(hash)) + } + return false; }); - $("#mbrsel-input").on("blur", function() { - setTimeout(function() { + $("#mbrsel-input").on("input", function() { + if ($(this).val().length > 0) + $("#memberfilter > .clear").show(); + else $("#memberfilter > .clear").hide(); - }, 10); }); }); @@ -537,15 +542,6 @@ function filter() { return false; }; -function windowTitle() { - try { - parent.document.title=document.title; - } catch(e) { - // Chrome doesn't allow settings the parent's title when - // used on the local file system. - } -}; - /** Check if user agent is associated with a known mobile browser */ function isMobile() { return /Android|webOS|Mobi|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); diff --git a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala index 524f94443d..757f13f79a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala @@ -455,7 +455,7 @@ trait ValueParam extends ParameterEntity { /** The type of this value parameter. */ def resultType: TypeEntity - /** The devault value of this value parameter, if it has been defined. */ + /** The default value of this value parameter, if it has been defined. */ def defaultValue: Option[TreeEntity] /** Whether this value parameter is implicit. */ diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index bccb65aa5f..928cb34d30 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -51,7 +51,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { lazy val dotRunner = new DotRunner(settings) } _modelFinished = true - // complete the links between model entities, everthing that couldn't have been done before + // complete the links between model entities, everything that couldn't have been done before universe.rootPackage.completeModel() Some(universe) filter (_.rootPackage != null) diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 830d902b68..e67a717257 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -236,7 +236,7 @@ trait ModelFactoryImplicitSupport { try { // TODO: Not sure if `owner = sym.owner` is the right thing to do -- seems similar to what scalac should be doing val silentContext = context.make(owner = sym.owner).makeSilent(reportAmbiguousErrors = false) - val search = inferImplicit(EmptyTree, tpe, false, false, silentContext, false) + val search = inferImplicitByTypeSilent(tpe, silentContext) available = Some(search.tree != EmptyTree) } catch { case _: TypeError => diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala index 3b7eb4e947..464cacc99a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala @@ -163,7 +163,7 @@ trait DiagramDirectiveParser { case Nil => defaultFilter - // compute the exact filters. By including the annotation, the diagram is autmatically added + // compute the exact filters. By including the annotation, the diagram is automatically added case _ => tFilter -= System.currentTimeMillis var hideDiagram0: Boolean = false diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala index 86900f26c9..bbcb18353a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala @@ -63,7 +63,7 @@ trait DiagramFactory extends DiagramDirectiveParser { case d: TemplateImpl if !classExcluded(d) => NormalNode(makeType(d.sym.tpe, tpl), Some(d))() }.sortBy(_.tpl.get.name)(implicitly[Ordering[String]].reverse) - // outgoing implicit coversions + // outgoing implicit conversions lazy val outgoingImplicitNodes = tpl.outgoingImplicitlyConvertedClasses.map { case (outgoingTpl, outgoingType, conv) => ImplicitNode(outgoingType, Some(outgoingTpl))(implicitTooltip(from=tpl, to=tpl, conv=conv)) |