summaryrefslogtreecommitdiff
path: root/src/scaladoc/scala/tools/nsc/doc/html/page
diff options
context:
space:
mode:
Diffstat (limited to 'src/scaladoc/scala/tools/nsc/doc/html/page')
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala58
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala (renamed from src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala)414
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala138
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala120
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala56
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala61
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala59
8 files changed, 464 insertions, 444 deletions
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 f257153bd7..0000000000
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala
+++ /dev/null
@@ -1,58 +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) extends HtmlPage {
-
- 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/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala
index 08d3508a78..7232892d52 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala
@@ -1,6 +1,6 @@
/* NSC -- new Scala compiler
- * Copyright 2007-2013 LAMP/EPFL
- * @author David Bernard, Manohar Jonnalagedda
+ * Copyright 2007-2016 LAMP/EPFL
+ * @author David Bernard, Manohar Jonnalagedda, Felix Mulder
*/
package scala
@@ -13,36 +13,43 @@ package page
import base._
import base.comment._
-import model._
-import model.diagram._
-import scala.xml.{Elem, NodeSeq, Text, UnprefixedAttribute}
+import scala.reflect.internal.Reporter
+import scala.collection.mutable
+import scala.xml.{NodeSeq, Text, UnprefixedAttribute}
import scala.language.postfixOps
-import scala.collection.mutable. { Set, HashSet }
import model._
import model.diagram._
import diagram._
-class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemplateEntity) extends HtmlPage {
+trait EntityPage extends HtmlPage {
+ import ScalaDoc.SummaryReporter
+
+ def universe: doc.Universe
+ def generator: DiagramGenerator
+ def tpl: DocTemplateEntity
+ def docletReporter: Reporter
- val path =
- templateToPath(tpl)
+ override val path = templateToPath(tpl)
def title = {
val s = universe.settings
-
- tpl.name +
- ( if (!s.doctitle.isDefault) " - " + s.doctitle.value else "" ) +
- ( if (!s.docversion.isDefault) (" " + s.docversion.value) else "" ) +
- " - " + tpl.qualifiedName
+ ( 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 =
+ def headers =
<xml:group>
+ <link href={ relativeLinkTo{List("index.css", "lib")} } media="screen" type="text/css" rel="stylesheet"/>
<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-ui.js", "lib")} }></script>
+ <script type="text/javascript" src={ relativeLinkTo{List("jquery.js", "lib")} }></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("index.js", "lib")} }></script>
+ <script type="text/javascript" src={ relativeLinkTo{List("index.js")} }></script>
+ <script type="text/javascript" src={ relativeLinkTo{List("scheduler.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) {
@@ -50,20 +57,116 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<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>
+ /* this variable can be used by the JS to determine the path to the root document */
+ var toRoot = '{ val p = templateToPath(tpl); "../" * (p.size - 1) }';
+ </script>
</xml:group>
+ def body =
+ <body>
+ { search }
+ <div id="search-results">
+ <div id="search-progress">
+ <div id="progress-fill"></div>
+ </div>
+ <div id="results-content">
+ <div id="entity-results"></div>
+ <div id="member-results"></div>
+ </div>
+ </div>
+ <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 => Page.inlineToStr(com.short))}></a>
+ }
+ case _ => <span class="separator"></span>
+ }
+ }
+ <a class={mbr.kind} href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => Page.inlineToStr(com.short))}></a>
+ <a href={relativeLinkTo(mbr)} title={mbr.comment.fold("")(com => Page.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>
+
+ def search =
+ <div id="search">
+ <span id="doc-title">{universe.settings.doctitle.value}<span id="doc-version">{universe.settings.docversion.value}</span></span>
+ <span class="close-results"><span class="left">&lt;</span> Back</span>
+ <div id="textfilter">
+ <span class="input">
+ <input autocapitalize="none" placeholder="Search" id="index-input" type="text" accesskey="/"/>
+ <i class="clear material-icons">&#xE14C;</i>
+ <i id="search-icon" class="material-icons">&#xE8B6;</i>
+ </span>
+ </div>
+ </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)
@@ -85,7 +188,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
/* 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 content = {
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) =>
@@ -100,92 +203,100 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<p id="owner">{ templatesToHtml(tpl.inTemplate.toRoot.reverse.tail, scala.xml.Text(".")) }</p>
}
- <body class={ if (tpl.isType) "type" else "value" }>
+ <body class={ tpl.kind + (if (tpl.isType) " type" else " value") }>
<div id="definition">
{
- val (src, alt) = docEntityKindToBigImage(tpl)
+ val imageClass = docEntityImageClass(tpl)
tpl.companion match {
case Some(companion) if (companion.visibility.isPublic && companion.inSource != None) =>
- <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><img alt={alt} src={ relativeLinkTo(List(src, "lib")) }/></a>
+ <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><div class={s"big-circle $imageClass"}>{ imageClass.substring(0,1) }</div></a>
case _ =>
- <img alt={alt} src={ relativeLinkTo(List(src, "lib")) }/>
- }}
+ <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) }
+ <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 id='textfilter'><span class='pre'/><span class='input'><input id='mbrsel-input' type='text' accesskey='/'/></span><span class='post'/></div>
- { 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>
+ <div class='toggle'></div>
+ <div id='memberfilter'>
+ <i class="material-icons arrow">&#xE037;</i>
+ <span class='input'>
+ <input id='mbrsel-input' placeholder='Filter all members' type='text' accesskey='/'/>
+ </span>
+ <i class="clear material-icons">&#xE14C;</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>
+ { 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>
- {
- 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>
- }
+ <li class="hideall out"><span>Hide All</span></li>
+ <li class="showall in"><span>Show All</span></li>
</ol>
</div>
- }
- { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else
+ }
{
- if (!tpl.linearizationTemplates.isEmpty)
- <div id="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 id="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 id="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 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">
@@ -204,28 +315,33 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
}
{ if (absValueMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>Abstract Value Members</h3>
<ol>{ absValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}
{ if (concValueMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <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>
}
{ if (shadowedImplicitMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>Shadowed Implicit Value Members</h3>
<ol>{ shadowedImplicitMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}
{ if (deprValueMembers.isEmpty) NodeSeq.Empty else
- <div id="values" class="values members">
+ <div class="values members">
<h3>Deprecated Value Members</h3>
<ol>{ deprValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
@@ -284,19 +400,29 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
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 }/>
+ } 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" }
+ 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 }>
- <a id={ mbr.signature }/>
- <a id={ mbr.signatureCompat }/>
+ { sig }
{ signature(mbr, isSelf = false) }
{ memberComment }
</li>
@@ -407,7 +533,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
val implicitInformation = mbr.byConversion match {
case Some(conv) =>
- <dt class="implicit">Implicit information</dt> ++
+ <dt class="implicit">Implicit</dt> ++
{
val targetType = typeToHtml(conv.targetType, hasLinks = true)
val conversionMethod = conv.convertorMethod match {
@@ -451,7 +577,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<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 =
@@ -496,7 +622,10 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
mbr match {
case nte: NonTemplateMemberEntity if nte.isUseCase =>
<div class="full-signature-block toggleContainer">
- <span class="toggle">Full Signature</span>
+ <span class="toggle">
+ <i class="material-icons">&#xE037;</i>
+ Full Signature
+ </span>
<div class="hiddenContent full-signature-usecase">{ signature(nte.useCaseOf.get,isSelf = true) }</div>
</div>
case _ => NodeSeq.Empty
@@ -618,7 +747,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<dt>To do</dt>
<dd>{
val todoXml: List[NodeSeq] = (for(todo <- comment.todo ) yield <span class="cmt">{bodyToHtml(todo)}</span> )
- todoXml.reduceLeft(_ ++ Text(", ") ++ _)
+ todoXml.reduceLeft(_ ++ _)
}</dd>
}
@@ -638,7 +767,9 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
val linearization = mbr match {
case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.linearizationTemplates.nonEmpty =>
<div class="toggleContainer block">
- <span class="toggle">Linear Supertypes</span>
+ <span class="toggle">
+ Linear Supertypes
+ </span>
<div class="superTypes hiddenContent">{
typesToHtml(dtpl.linearizationTypes, hasLinks = true, sep = scala.xml.Text(", "))
}</div>
@@ -648,7 +779,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
val subclasses = mbr match {
case dtpl: DocTemplateEntity if isSelf && !isReduced =>
- val subs: Set[DocTemplateEntity] = HashSet.empty
+ val subs = mutable.HashSet.empty[DocTemplateEntity]
def transitive(dtpl: DocTemplateEntity) {
for (sub <- dtpl.directSubClasses if !(subs contains sub)) {
subs add sub
@@ -658,9 +789,11 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
transitive(dtpl)
if (subs.nonEmpty)
<div class="toggleContainer block">
- <span class="toggle">Known Subclasses</span>
+ <span class="toggle">
+ Known Subclasses
+ </span>
<div class="subClasses hiddenContent">{
- templatesToHtml(subs.toList.sortBy(_.name), scala.xml.Text(", "))
+ templatesToHtml(subs.toList.sorted(Entity.EntityOrdering), scala.xml.Text(", "))
}</div>
</div>
else NodeSeq.Empty
@@ -675,10 +808,15 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
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>
+ <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">&#xE15B;</i></button>
+ <button id="diagram-zoom-in" class="diagram-btn"><i class="material-icons">&#xE145;</i></button>
+ <button title="Toggle full-screen" id="diagram-fs" class="diagram-btn to-full"><i class="material-icons">&#xE5D0;</i></button>
+ </div>
</div>
} else NodeSeq.Empty
} else NodeSeq.Empty
@@ -759,7 +897,9 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
}
}
if (!nameLink.isEmpty)
- <a href={nameLink}>{nameHtml}</a>
+ <a title={mbr.comment.fold("")(c => Page.inlineToStr(c.short))} href={nameLink}>
+ {nameHtml}
+ </a>
else nameHtml
}{
def tparamsToHtml(mbr: Any): NodeSeq = mbr match {
@@ -821,7 +961,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
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>
@@ -833,11 +973,11 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
</xml:group>
mbr match {
case dte: DocTemplateEntity if !isSelf =>
- <h4 class="signature">{ inside(hasLinks = true, nameLink = relativeLinkTo(dte)) }</h4> ++ permalink(dte, isSelf)
+ permalink(dte, isSelf) ++ { inside(hasLinks = true, nameLink = relativeLinkTo(dte)) }
case _ if isSelf =>
<h4 id="signature" class="signature">{ inside(hasLinks = true) }</h4>
case _ =>
- <h4 class="signature">{ inside(hasLinks = true) }</h4> ++ permalink(mbr)
+ permalink(mbr) ++ { inside(hasLinks = true) }
}
}
@@ -925,21 +1065,10 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
body.blocks flatMap (blockToStr(_)) mkString ""
private def blockToStr(block: comment.Block): String = block match {
- case comment.Paragraph(in) => inlineToStr(in)
+ case comment.Paragraph(in) => Page.inlineToStr(in)
case _ => block.toString
}
- private def inlineToStr(inl: comment.Inline): String = inl match {
- case comment.Chain(items) => items flatMap (inlineToStr(_)) mkString ""
- case comment.Italic(in) => inlineToStr(in)
- case comment.Bold(in) => inlineToStr(in)
- case comment.Underline(in) => inlineToStr(in)
- case comment.Monospace(in) => inlineToStr(in)
- case comment.Text(text) => text
- case comment.Summary(in) => inlineToStr(in)
- case _ => inl.toString
- }
-
private def typeToHtmlWithStupidTypes(tpl: TemplateEntity, superTpl: TemplateEntity, superType: TypeEntity): NodeSeq =
if (tpl.universe.settings.useStupidTypes.value)
superTpl match {
@@ -980,9 +1109,20 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
}
}
-object Template {
+object EntityPage {
+ def apply(
+ uni: doc.Universe,
+ gen: DiagramGenerator,
+ docTpl: DocTemplateEntity,
+ rep: Reporter
+ ): EntityPage = new EntityPage {
+ def universe = uni
+ def generator = gen
+ def tpl = docTpl
+ 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 6bfe480e33..0000000000
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala
+++ /dev/null
@@ -1,138 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2007-2013 LAMP/EPFL
- * @author David Bernard, Manohar Jonnalagedda
- */
-
-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) extends HtmlPage {
-
- def path = List("index.html")
-
- def title = {
- val s = universe.settings
- ( if (!s.doctitle.isDefault) s.doctitle.value else "" ) +
- ( if (!s.docversion.isDefault) (" " + s.docversion.value) else "" )
- }
-
- 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("jquery-ui.js", "lib")} }></script>
- <script type="text/javascript" src={ relativeLinkTo{List("jquery.layout.js", "lib")} }></script>
- <script type="text/javascript" src={ relativeLinkTo{List("index.js", "lib")} }></script>
- <script type="text/javascript" src={ relativeLinkTo{List("scheduler.js", "lib")} }></script>
- </xml:group>
-
- val body =
- <body>
- <div id="library">
- <img class='class icon' alt='class icon' src={ relativeLinkTo{List("class.png", "lib")} }/>
- <img class='trait icon' alt='trait icon' src={ relativeLinkTo{List("trait.png", "lib")} }/>
- <img class='object icon' alt='trait icon' src={ relativeLinkTo{List("object.png", "lib")} }/>
- <img class='package icon' alt='trait icon' src={ relativeLinkTo{List("package.png", "lib")} }/>
- </div>
- { browser }
- <div id="content" class="ui-layout-center">
- <iframe id="template" name="template" src={ relativeLinkTo{List("package.html")} }/>
- </div>
- </body>
-
- def letters: NodeSeq =
- '_' +: ('a' to 'z') map {
- char => {
- val label = if (char == '_') '#' else char.toUpper
-
- index.firstLetterIndex.get(char) match {
- case Some(_) =>
- <a target="template" href={ "index/index-" + char + ".html" }>{
- label
- }</a>
- case None => <span>{ label }</span>
- }
- }
- }
-
- def deprecated: NodeSeq = if (index.hasDeprecatedMembers)
- <a target="template" href="deprecated-list.html">deprecated</a>
- else
- <span>deprecated</span>
-
- def browser =
- <div id="browser" class="ui-layout-west">
- <div class="ui-west-center">
- <div id="filter">
- <div id="textfilter"></div>
- <div id="letters">{ letters } &#8211; { deprecated }</div>
- </div>
- <div class="pack" id="tpl">{
- def packageElem(pack: model.Package): NodeSeq = {
- <xml:group>
- { if (!pack.isRootPackage)
- <a class="tplshow" href={ relativeLinkTo(pack) } target="template">{ pack.qualifiedName }</a>
- else NodeSeq.Empty
- }
- <ol class="templates">{
- val tpls: Map[String, Seq[DocTemplateEntity]] =
- (pack.templates collect {
- case t: DocTemplateEntity if !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName) => t
- }) groupBy (_.name)
-
- val placeholderSeq: NodeSeq = <div class="placeholder"></div>
-
- def createLink(entity: DocTemplateEntity, includePlaceholder: Boolean, includeText: Boolean) = {
- val entityType = kindToString(entity)
- val linkContent = (
- { if (includePlaceholder) placeholderSeq else NodeSeq.Empty }
- ++
- { if (includeText) <span class="tplLink">{ Text(packageQualifiedName(entity)) }</span> else NodeSeq.Empty }
- )
- <a class="tplshow" href={ relativeLinkTo(entity) } target="template"><span class={ entityType }>({ Text(entityType) })</span>{ linkContent }</a>
- }
-
- for (tn <- tpls.keySet.toSeq sortBy (_.toLowerCase)) yield {
- val entities = tpls(tn)
- val row = (entities find (e => e.isPackage || e.isObject), entities find (e => e.isTrait || e.isClass))
-
- val itemContents = row match {
- case (Some(obj), None) => createLink(obj, includePlaceholder = true, includeText = true)
-
- case (maybeObj, Some(template)) =>
- val firstLink = maybeObj match {
- case Some(obj) => createLink(obj, includePlaceholder = false, includeText = false)
- case None => placeholderSeq
- }
-
- firstLink ++ createLink(template, includePlaceholder = false, includeText = true)
-
- case _ => // FIXME: this default case should not be necessary. For some reason AnyRef is not a package, object, trait, or class
- val entry = entities.head
- placeholderSeq ++ createLink(entry, includePlaceholder = false, includeText = true)
- }
-
- <li title={ entities.head.qualifiedName }>{ itemContents }</li>
- }
- }</ol>
- <ol class="packages"> {
- for (sp <- pack.packages sortBy (_.name.toLowerCase)) yield
- <li class="pack" title={ sp.qualifiedName }>{ packageElem(sp) }</li>
- }</ol>
- </xml:group>
- }
- packageElem(universe.rootPackage)
- }</div></div><script src="index.js"></script>
- </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 e3c94505ab..28304e76c7 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala
@@ -1,21 +1,26 @@
/* NSC -- new Scala compiler
- * Copyright 2007-2013 LAMP/EPFL
- * @author David Bernard, Manohar Jonnalagedda
+ * Copyright 2007-2016 LAMP/EPFL
+ * @author David Bernard, Manohar Jonnalagedda, Felix Mulder
*/
-package scala.tools.nsc.doc.html.page
+package scala.tools.nsc.doc
+package html
+package page
import scala.tools.nsc.doc
import scala.tools.nsc.doc.model.{Package, DocTemplateEntity}
import scala.tools.nsc.doc.html.{Page, HtmlFactory}
-import scala.util.parsing.json.{JSONObject, JSONArray}
-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
+
def path = List("index.js")
override def writeFor(site: HtmlFactory) {
writeFile(site) {
- _.write("Index.PACKAGES = " + packages.toString() + ";")
+ _.write(s"Index.PACKAGES = $packages;")
}
}
@@ -24,33 +29,46 @@ 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 pairs = merged(key).map(
- t => kindToString(t) -> relativeLinkTo(t)
- ) :+ ("name" -> key)
+ val ary = merged.keys.toVector.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(
+ kind -> relativeLinkTo(t),
+ "kind" -> kind,
+ s"members_$kind" -> membersToJSON(t.members.toVector.filter(!_.isShadowedOrAmbiguousImplicit), t),
+ "shortDescription" -> shortDesc(t))
+ }
- JSONObject(scala.collection.immutable.Map(pairs : _*))
- })
+ JSONObject(Map(pairs : _*) + ("name" -> key))
+ }
pack.qualifiedName -> JSONArray(ary)
}
}).toSeq
- JSONObject(scala.collection.immutable.Map(pairs : _*))
+ JSONObject(Map(pairs : _*))
}
- def mergeByQualifiedName(source: List[DocTemplateEntity]) = {
- var result = Map[String, List[DocTemplateEntity]]()
+ private def mergeByQualifiedName(source: List[DocTemplateEntity]): collection.mutable.Map[String, List[DocTemplateEntity]] = {
+ val result = collection.mutable.Map[String, List[DocTemplateEntity]]()
for (t <- source) {
val k = t.qualifiedName
- result += k -> (result.getOrElse(k, List()) :+ t)
+ result += k -> (result.getOrElse(k, Nil) :+ t)
}
result
}
- def allPackages = {
+ def allPackages: List[Package] = {
def f(parent: Package): List[Package] = {
parent.packages.flatMap(
p => f(p) :+ p
@@ -59,11 +77,77 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page {
f(universe.rootPackage).sortBy(_.toString)
}
- def allPackagesWithTemplates = {
+ def allPackagesWithTemplates: Map[Package, List[DocTemplateEntity]] = {
Map(allPackages.map((key) => {
key -> key.templates.collect {
case t: DocTemplateEntity if !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName) => t
}
}) : _*)
}
+
+ /** Gets the short description i.e. the first sentence of the docstring */
+ def shortDesc(mbr: MemberEntity): String = mbr.comment.fold("") { c =>
+ Page.inlineToStr(c.short).replaceAll("\n", "")
+ }
+
+ /** Returns the json representation of the supplied members */
+ def membersToJSON(entities: Vector[MemberEntity], parent: DocTemplateEntity): JSONArray =
+ JSONArray(entities.map(memberToJSON(_, parent)))
+
+ 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] }}}
+ * Gets turned into: "(key: A): Option[B]"
+ */
+ def memberTail: MemberEntity => String = {
+ case d: Def => d
+ .valueParams //List[List[ValueParam]]
+ .map { params =>
+ params.map(p => p.name + ": " + p.resultType.name).mkString(", ")
+ }
+ .mkString("(", ")(", "): " + d.resultType.name)
+ case v: Val => ": " + v.resultType.name
+ case _ => ""
+ }
+
+ /** This function takes a member entity and return all modifiers in a
+ * string, example:
+ * {{{ lazy val scalaProps: java.util.Properties }}}
+ * Gets turned into: "lazy val"
+ */
+ def memberKindToString(mbr: MemberEntity): String = {
+ val kind = mbr.flags.map(_.text.asInstanceOf[Text].text).mkString(" ")
+ val space = if (kind == "") "" else " "
+
+ kind + space + kindToString(mbr)
+ }
+
+ /** This function turns a member entity into a JSON object that the index.js
+ * script can use to render search results
+ */
+ def jsonObject(m: MemberEntity): JSONObject =
+ JSONObject(Map(
+ "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
+
+ mbr match {
+ 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"))
+ }
+ }
+
+ def memberToUrl(mbr: MemberEntity): String = {
+ val path = templateToPath(mbr.inTemplate).reverse.mkString("/")
+ s"$path#${mbr.signature}"
+ }
+}
+
+object IndexScript {
+ def apply(universe: doc.Universe) = new IndexScript(universe)
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala
new file mode 100644
index 0000000000..5f6cb7e799
--- /dev/null
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala
@@ -0,0 +1,56 @@
+package scala.tools.nsc.doc.html.page
+
+import JSONFormat.format
+
+private[page] object JSONFormat {
+
+ def format(x: Any): String = x match {
+ case s: String => s"""\"${quoteString(s)}\""""
+ case jo: JSONObject => jo.toString
+ case ja: JSONArray => ja.toString
+ case other => throw new UnsupportedOperationException(s"Value $other of class ${other.getClass} cannot be formatted.")
+ }
+
+ /** This function can be used to properly quote Strings for JSON output. */
+ def quoteString(s: String): String = {
+ val len: Int = s.length
+ val buf = new StringBuilder(len + len/4)
+ var i: Int = 0
+ while (i < len) {
+ s.apply(i) match {
+ case '"' => buf ++= "\\\""
+ case '\\' => buf ++= "\\\\"
+ case '/' => buf ++= "\\/"
+ case '\b' => buf ++= "\\b"
+ case '\f' => buf ++= "\\f"
+ case '\n' => buf ++= "\\n"
+ case '\r' => buf ++= "\\r"
+ case '\t' => buf ++= "\\t"
+ /* We'll unicode escape any control characters. These include:
+ * 0x00 -> 0x1f : ASCII Control (C0 Control Codes)
+ * 0x7f : ASCII DELETE
+ * 0x80 -> 0x9f : C1 Control Codes
+ *
+ * Per RFC4627, section 2.5, we're not technically required to
+ * encode the C1 codes, but we do to be safe.
+ */
+ case c if ((c >= '\u0000' && c <= '\u001f') || (c >= '\u007f' && c <= '\u009f')) =>
+ val cint = c.toInt
+ buf ++= f"\\u$cint%04x"
+ case c => buf += c
+ }
+ i += 1
+ }
+ buf.toString()
+ }
+}
+
+/** Represents a JSON Object (map). */
+private[page] case class JSONObject(obj: Map[String,Any]) {
+ override def toString = obj.map({ case (k,v) => format(k) + " : " + format(v) }).mkString("{", ", ", "}")
+}
+
+/** Represents a JSON Array (vector). */
+private[page] case class JSONArray(vector: Vector[Any]) {
+ override def toString = vector.map(format).mkString("[", ", ", "]")
+}
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 84ee82f994..0000000000
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala
+++ /dev/null
@@ -1,61 +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) extends HtmlPage {
-
- 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/diagram/DiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala
index cf65de4151..829bba3f32 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala
@@ -23,5 +23,5 @@ trait DiagramGenerator {
* @param p The page the diagram will be embedded in (needed for link generation)
* @return The HTML to be embedded in the Scaladoc page
*/
- def generate(d: Diagram, t: DocTemplateEntity, p: HtmlPage):NodeSeq
+ def generate(d: Diagram, t: DocTemplateEntity, p: HtmlPage): NodeSeq
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
index 320a8e23b2..99af2f627f 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
@@ -10,7 +10,7 @@ package html
package page
package diagram
-import scala.xml.{NodeSeq, XML, PrefixedAttribute, Elem, MetaData, Null, UnprefixedAttribute}
+import scala.xml.{NodeSeq, PrefixedAttribute, Elem, Null, UnprefixedAttribute}
import scala.collection.immutable._
import model._
import model.diagram._
@@ -211,7 +211,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
// escape HTML characters in node names
def escape(name: String) = name.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
- // assemble node attribues in a map
+ // assemble node attributes in a map
val attr = scala.collection.mutable.Map[String, String]()
// link
@@ -246,15 +246,12 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
// HTML label
var name = escape(node.name)
- var img = ""
- if(node.isTraitNode)
- img = "trait_diagram.png"
- else if(node.isClassNode)
- img = "class_diagram.png"
- else if(node.isObjectNode)
- img = "object_diagram.png"
- else if(node.isTypeNode)
- img = "type_diagram.png"
+ var img =
+ if(node.isTraitNode) "trait_diagram.png"
+ else if(node.isClassNode) "class_diagram.png"
+ else if(node.isObjectNode) "object_diagram.png"
+ else if(node.isTypeNode) "type_diagram.png"
+ else ""
if(!img.equals("")) {
img = "<TD><IMG SCALE=\"TRUE\" SRC=\"" + settings.outdir.value + "/lib/" + img + "\" /></TD>"
@@ -364,7 +361,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
// add an id and class attribute to the SVG element
case Elem(prefix, "svg", attribs, scope, child @ _*) => {
val klass = if (isInheritanceDiagram) "class-diagram" else "package-diagram"
- Elem(prefix, "svg", attribs, scope, child map(x => transform(x)) : _*) %
+ Elem(prefix, "svg", attribs, scope, true, child map(x => transform(x)) : _*) %
new UnprefixedAttribute("id", "graph" + counter, Null) %
new UnprefixedAttribute("class", klass, Null)
}
@@ -378,7 +375,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
// assign id and class attributes to edges and nodes:
// the id attribute generated by dot has the format: "{class}|{id}"
case g @ Elem(prefix, "g", attribs, scope, children @ _*) if (List("edge", "node").contains((g \ "@class").toString)) => {
- var res = new Elem(prefix, "g", attribs, scope, (children map(x => transform(x))): _*)
+ var res = new Elem(prefix, "g", attribs, scope, true, (children map(x => transform(x))): _*)
val dotId = (g \ "@id").toString
if (dotId.count(_ == '|') == 1) {
val Array(klass, id) = dotId.toString.split("\\|")
@@ -395,11 +392,11 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
val imageNode = <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href={ ("./lib/" + kind + "_diagram.png") } width="16px" height="16px" preserveAspectRatio="xMinYMin meet" x={ xposition.get.toString } y={ yposition.get.toString }/>
val anchorNode = (g \ "a") match {
case Seq(Elem(prefix, "a", attribs, scope, children @ _*)) =>
- transform(new Elem(prefix, "a", attribs, scope, (children ++ imageNode): _*))
+ transform(new Elem(prefix, "a", attribs, scope, true, (children ++ imageNode): _*))
case _ =>
g \ "a"
}
- res = new Elem(prefix, "g", attribs, scope, anchorNode: _*)
+ res = new Elem(prefix, "g", attribs, scope, true, anchorNode: _*)
DiagramStats.addFixedImage()
}
}
@@ -413,7 +410,7 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
scala.xml.Text("")
// apply recursively
case Elem(prefix, label, attribs, scope, child @ _*) =>
- Elem(prefix, label, attribs, scope, child map(x => transform(x)) : _*)
+ Elem(prefix, label, attribs, scope, true, child map(x => transform(x)) : _*)
case x => x
}
@@ -439,22 +436,22 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
)
private val nodeAttributes = Map(
- "shape" -> "rectangle",
- "style" -> "filled",
+ "shape" -> "rect",
+ "style" -> "filled,rounded",
"penwidth" -> "1",
"margin" -> "0.08,0.01",
"width" -> "0.0",
"height" -> "0.0",
- "fontname" -> "Arial",
- "fontsize" -> "10.00"
+ "fontname" -> "Source Code Pro",
+ "fontsize" -> "8.00"
)
private val edgeAttributes = Map(
"color" -> "#d4d4d4",
- "arrowsize" -> "0.5",
+ "arrowsize" -> "0.7",
"fontcolor" -> "#aaaaaa",
- "fontsize" -> "10.00",
- "fontname" -> "Arial"
+ "fontsize" -> "9.00",
+ "fontname" -> "Source Code Pro"
)
private val defaultStyle = Map(
@@ -477,26 +474,26 @@ class DotDiagramGenerator(settings: doc.Settings, dotRunner: DotRunner) extends
)
private val traitStyle = Map(
- "color" -> "#37657D",
- "fillcolor" -> "#498AAD",
+ "color" -> "#2E6D82",
+ "fillcolor" -> "#2E6D82",
"fontcolor" -> "#ffffff"
)
private val classStyle = Map(
- "color" -> "#115F3B",
- "fillcolor" -> "#0A955B",
+ "color" -> "#418565",
+ "fillcolor" -> "#418565",
"fontcolor" -> "#ffffff"
)
private val objectStyle = Map(
- "color" -> "#102966",
- "fillcolor" -> "#3556a7",
+ "color" -> "#103A51",
+ "fillcolor" -> "#103A51",
"fontcolor" -> "#ffffff"
)
private val typeStyle = Map(
- "color" -> "#115F3B",
- "fillcolor" -> "#0A955B",
+ "color" -> "#2E6D82",
+ "fillcolor" -> "#2E6D82",
"fontcolor" -> "#ffffff"
)