diff options
Diffstat (limited to 'src/scaladoc/scala/tools/nsc/doc/html/page')
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/DeprecatedIndex.scala | 58 | ||||
-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.scala | 138 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala | 120 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala | 56 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala | 61 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala | 2 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala | 59 |
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"><</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"></i> + <i id="search-icon" class="material-icons"></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"></i> + <span class='input'> + <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> + { 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"></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"></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 @@ -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 } – { 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("&", "&").replace("<", "<").replace(">", ">") - // 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" ) |