From 80a907708e970c9871d17184cfd8b022913e3bd6 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 29 Apr 2016 22:49:10 +0200 Subject: Move member rendering back to client (for event listeners) --- dottydoc/js/src/DottyDoc.scala | 9 +- dottydoc/js/src/EntityIndex.scala | 6 ++ dottydoc/js/src/html/EntityLayout.scala | 28 ++++++ dottydoc/js/src/html/Member.scala | 75 ++++++++++++++ .../src/dotty/tools/dottydoc/html/CustomTags.scala | 2 +- .../dotty/tools/dottydoc/html/EntityLayout.scala | 110 --------------------- .../jvm/src/dotty/tools/dottydoc/html/Html.scala | 96 ++++++++++++++++-- .../jvm/src/dotty/tools/dottydoc/html/Member.scala | 75 -------------- .../dotty/tools/dottydoc/util/IndexWriters.scala | 6 +- dottydoc/jvm/test/WhitelistedStdLib.scala | 21 ++++ 10 files changed, 225 insertions(+), 203 deletions(-) create mode 100644 dottydoc/js/src/html/EntityLayout.scala create mode 100644 dottydoc/js/src/html/Member.scala delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala delete mode 100644 dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala create mode 100644 dottydoc/jvm/test/WhitelistedStdLib.scala diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala index 9fdf007dc..b9ad1d891 100644 --- a/dottydoc/js/src/DottyDoc.scala +++ b/dottydoc/js/src/DottyDoc.scala @@ -7,16 +7,13 @@ import js.JSApp import js.annotation.{ JSExport, JSName } import org.scalajs.dom import model.Entities._ -import scala.concurrent.Future -import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue +import html.EntityLayout @JSExport object DottyDocJS { @JSExport def main(target: dom.html.Div) = { + global.document.title = "Dotty " + EntityIndex.currentEntity.path.mkString(".") + target.appendChild(EntityLayout(EntityIndex.currentEntity).html.render) hljs.initHighlightingOnLoad() - - println("Started parsing...") - Future(EntityIndex.packages.keys).map(println) - println("after fututre") } } diff --git a/dottydoc/js/src/EntityIndex.scala b/dottydoc/js/src/EntityIndex.scala index e8e27dc88..69bda283f 100644 --- a/dottydoc/js/src/EntityIndex.scala +++ b/dottydoc/js/src/EntityIndex.scala @@ -21,8 +21,14 @@ object EntityIndex { None .getOrElse(Map.empty) + val currentEntity: Entity = Unpickle[Entity] + .fromString(js.JSON.stringify(Unparsed.currentEntity)) + .toOption + .get + /** Unparsed index stores the pickled AST generated by the dottydoc tool */ @js.native @JSName("UnparsedIndex") private object Unparsed extends js.Object { def packages: js.Object = js.native + def currentEntity: js.Object = js.native } } diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala new file mode 100644 index 000000000..51fd000b7 --- /dev/null +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -0,0 +1,28 @@ +package dotty.tools.dottydoc +package js +package html + +import scalatags.JsDom.all._ +import org.scalajs.dom +import org.scalajs.dom.html.{Anchor, Div} +import model.Entities._ + +case class EntityLayout(entity: Entity) extends MemberLayout { + def html = div( + cls := "page-content", + div(raw(entity.comment.fold("")(_.body))), + entity match { + case e: Entity with Members => + Seq( + h5("Members"), + div( + cls := "mld-grid", + e.members + .collect { case x: Entity with Modifiers if !x.isPrivate => x} + .flatMap(member(_, entity)) + ) + ) + case _ => () + } + ) +} diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala new file mode 100644 index 000000000..065626a1c --- /dev/null +++ b/dottydoc/js/src/html/Member.scala @@ -0,0 +1,75 @@ +package dotty.tools.dottydoc +package js +package html + +import scalatags.JsDom.all._ +import scalatags.JsDom.TypedTag +import org.scalajs.dom +import org.scalajs.dom.html.{Anchor, Div} + +trait MemberLayout { + import model.Entities._ + + def member(m: Entity, parent: Entity) = { + def toggleBetween(short: Div, and: Div): Unit = + if (and.style.display == "none") { + and.style.display = "block" + short.style.display = "none" + } else { + and.style.display = "none" + short.style.display = "block" + } + + m match { + case m: Entity with Modifiers => + val shortComment = div( + cls := "mdl-cell mdl-cell--12-col summary-comment", + raw(m.comment.fold("")(_.short)) + ).render + + val fullComment = div( + cls := "mdl-cell mdl-cell--12-col full-comment", + style := "display: none;", + raw(m.comment.fold("")(_.body)) + ).render + + + val hasLongerFullComment = m.comment.fold(false) { c => + c.short.length + 5 < c.body.length + } + + val divs = div( + cls := + s""" + mdl-cell mdl-cell--12-col member + ${if (hasLongerFullComment) "member-fullcomment" else ""} + """, + onclick := { () => toggleBetween(shortComment, and = fullComment) }, + div( + cls := "mdl-cell mdl-cell--12-col", + span(cls := "member-name", m.modifiers.mkString(" ") + " " + m.kind + " " + m.name), + returnValue(m, parent) + ), + shortComment, + fullComment + ) + Seq(divs) + case x => Seq(h1("ERROR: " + x.name)) + } + } + + def returnValue(m: Entity with Modifiers, parent: Entity) = { + // shortens: "Option.this.A" => "A" + def shorten(s: String): String = s.split('.').toList match { + case x :: Nil => x + case x :: xs if x == parent.name => xs.last + case xs => s + } + + m match { + case v: Val => span(cls := "return-value", ": " + shorten(v.returnValue)) + case d: Def => span(cls := "return-value", ": " + shorten(d.returnValue)) + case _ => span() + } + } +} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala index 766740c4a..ed462f21b 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/CustomTags.scala @@ -7,6 +7,6 @@ import scalatags.generic.Util import org.scalajs.dom object CustomTags { - lazy val main = "main".tag lazy val nav = "nav".tag + lazy val main = "main".tag } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala deleted file mode 100644 index e256919da..000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityLayout.scala +++ /dev/null @@ -1,110 +0,0 @@ -package dotty.tools.dottydoc -package html - -import scalatags.Text.all._ -import org.scalajs.dom -import org.scalajs.dom.html.{Anchor, Div} -import model.Entities._ - -case class EntityLayout(entity: Entity, packages: Map[String, Package]) { - import CustomTags._ - import MemberLayout._ - - def html = div( - cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", - div( - cls := "mdl-layout__drawer", - span( - cls := "mdl-layout-title subtitle", - entity.path.dropRight(1).mkString(".") - ), - span( - cls := "mdl-layout-title", - entity match { - case p: Package => p.name.split("\\.").last - case e => e.name - } - ), - nav( - cls := "related mdl-navigation", - companion, - a(cls := "mdl-navigation__link", href := "#", "Source") - ), - span( - cls := "mdl-layout-title", - id := "docs-title", - "Docs" - ), - searchView, - packageView - ), - main( - cls := "mdl-layout__content", - div( - cls := "page-content", - div(raw(entity.comment.fold("")(_.body))), - entity match { - case e: Entity with Members => - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { case x: Entity with Modifiers if !x.isPrivate => x} - .flatMap(member(_, entity)) - ) - ) - case _ => () - } - ) - ) - ) - - def searchView = div( - cls := "search-container", - div( - cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", - input(cls := "mdl-textfield__input", `type` := "text", id := "search"), - label(cls := "mdl-textfield__label", `for` := "search", "Search") - ) - ) - - private def relativePath(to: Entity) = - util.Traversing.relativePath(entity, to) - - private def filteredName(str: String) = - str.replaceAll("\\$colon", ":") - - def packageView = nav( - cls := "mdl-navigation packages", - { - val keys: Seq[String] = packages.keys.toSeq.sorted - keys.flatMap { k => - val pack = packages(k) - val children = - pack.children.sortBy(_.name).filterNot(_.kind == "package").map { c => - a(cls := "mdl-navigation__link entity", href := relativePath(c), filteredName(c.name)) - } - - if (children.length > 0) - a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children - else Nil - } - } - ) - - def companion = { - val pack = entity.path.dropRight(1).mkString(".") - packages.get(pack) - .flatMap { p => - p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) - } - .map { c => - a( - cls := "mdl-navigation__link", - href := c.path.last + ".html", - "Companion " + c.kind - ) - }.getOrElse(span()) - } -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala index 7dc27ca86..aef86ffd8 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Html.scala @@ -2,23 +2,22 @@ package dotty.tools.dottydoc package html import scalatags.Text.all._ +import model.Entities._ -object Html { +case class EntityPage(entity: Entity, packages: Map[String, Package]) { import prickle._ - import model.Entities._ + import CustomTags._ private def relPath(to: String, from: Entity) = "../" * from.path.length + to - def entityHtml(entity: Entity, packages: Map[String, Package]) = "" + html( + def render = "" + html( head( meta(charset := "utf-8"), meta(name := "viewport", content := "width=device-width, initial-scale=1, shrink-to-fit=no"), meta("http-equiv".attr := "x-ua-compatible", content := "ie=edge"), - //title("Dotty - " + ent.path.mkString(".")), - script(`type` := "text/javascript", src := relPath("static/material.min.js", entity)), script(`type` := "text/javascript", src := relPath("static/highlight.pack.js", entity)), script(`type` := "text/javascript", src := relPath("index.js", entity)), @@ -31,13 +30,94 @@ object Html { body( div( id := "main-container", - EntityLayout(entity, packages).html + div( + cls := "mdl-layout mdl-js-layout mdl-layout--fixed-drawer", + div( + cls := "mdl-layout__drawer", + span( + cls := "mdl-layout-title subtitle", + entity.path.dropRight(1).mkString(".") + ), + span( + cls := "mdl-layout-title", + entity match { + case p: Package => p.name.split("\\.").last + case e => e.name + } + ), + nav( + cls := "related mdl-navigation", + companion, + a(cls := "mdl-navigation__link", href := "#", "Source") + ), + span( + cls := "mdl-layout-title", + id := "docs-title", + "Docs" + ), + searchView, + packageView + ), + main( + id := "entity-container", + cls := "mdl-layout__content" + ) + ) ) ), script( - raw(s"""|dotty.tools.dottydoc.js.DottyDocJS() - | .main(document.getElementById("main-container")); + raw(s"""|UnparsedIndex.currentEntity = ${Pickle.intoString(entity)}; + |dotty.tools.dottydoc.js.DottyDocJS() + | .main(document.getElementById("entity-container")); """.stripMargin) ) ) + + private def filteredName(str: String) = + str.replaceAll("\\$colon", ":") + + private def relativePath(to: Entity) = + util.Traversing.relativePath(entity, to) + + def packageView = nav( + cls := "mdl-navigation packages", + { + val keys: Seq[String] = packages.keys.toSeq.sorted + keys.flatMap { k => + val pack = packages(k) + val children = + pack.children.sortBy(_.name).filterNot(_.kind == "package").map { c => + a(cls := "mdl-navigation__link entity", href := relativePath(c), filteredName(c.name)) + } + + if (children.length > 0) + a(cls := "mdl-navigation__link package", href := relativePath(pack), filteredName(k)) :: children + else Nil + } + } + ) + + def companion = { + val pack = entity.path.dropRight(1).mkString(".") + packages.get(pack) + .flatMap { p => + p.children.find(e => e.name == entity.name && e.path.last != entity.path.last) + } + .map { c => + a( + cls := "mdl-navigation__link", + href := c.path.last + ".html", + "Companion " + c.kind + ) + }.getOrElse(span()) + } + + def searchView = div( + cls := "search-container", + div( + cls := "mdl-textfield mdl-js-textfield mdl-textfield--floating-label", + input(cls := "mdl-textfield__input", `type` := "text", id := "search"), + label(cls := "mdl-textfield__label", `for` := "search", "Search") + ) + ) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala deleted file mode 100644 index d04c76017..000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/Member.scala +++ /dev/null @@ -1,75 +0,0 @@ -package dotty.tools.dottydoc -package html - -import scalatags.Text.all._ -import scalatags.Text.TypedTag -import org.scalajs.dom -import org.scalajs.dom.html.{Anchor, Div} - -object MemberLayout { - import model.Entities._ - import CustomTags._ - - def member(m: Entity, parent: Entity) = { - def toggleBetween(short: Div, and: Div): Unit = - if (and.style.display == "none") { - and.style.display = "block" - short.style.display = "none" - } else { - and.style.display = "none" - short.style.display = "block" - } - - m match { - case m: Entity with Modifiers => - val shortComment = div( - cls := "mdl-cell mdl-cell--12-col summary-comment", - raw(m.comment.fold("")(_.short)) - ) - - val fullComment = div( - cls := "mdl-cell mdl-cell--12-col full-comment", - style := "display: none;", - raw(m.comment.fold("")(_.body)) - ) - - - val hasLongerFullComment = m.comment.fold(false) { c => - c.short.length + 5 < c.body.length - } - - val divs = div( - cls := - s""" - mdl-cell mdl-cell--12-col member - ${if (hasLongerFullComment) "member-fullcomment" else ""} - """, - //onclick := { () => toggleBetween(shortComment, and = fullComment) }, //FIXME! - div( - cls := "mdl-cell mdl-cell--12-col", - span(cls := "member-name", m.modifiers.mkString(" ") + " " + m.kind + " " + m.name), - returnValue(m, parent) - ), - shortComment, - fullComment - ) - Seq(divs) - case x => Seq(h1("ERROR: " + x.name)) - } - } - - def returnValue(m: Entity with Modifiers, parent: Entity) = { - // shortens: "Option.this.A" => "A" - def shorten(s: String): String = s.split('.').toList match { - case x :: Nil => x - case x :: xs if x == parent.name => xs.last - case xs => s - } - - m match { - case v: Val => span(cls := "return-value", ": " + shorten(v.returnValue)) - case d: Def => span(cls := "return-value", ": " + shorten(d.returnValue)) - case _ => span() - } - } -} diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala index 6bd6a6e9f..8ec62a7d4 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/IndexWriters.scala @@ -4,13 +4,13 @@ package util object IndexWriters { import prickle._ import model.Entities._ - import html.Html._ + import html.EntityPage def writeJs(packs: Map[String, Package], outPath: String): Unit = { for (pack <- packs.values) { println(s"""Writing '${pack.path.mkString(".")}'""") writeFile( - entityHtml(pack, packs), + EntityPage(pack, packs).render, outPath + pack.path.dropRight(1).mkString("/", "/", "/"), s"${pack.name.split("\\.").last}.html") //s"index.html") @@ -21,7 +21,7 @@ object IndexWriters { } { println(s"""Writing '${child.path.mkString(".")}'""") writeFile( - entityHtml(child, packs), + EntityPage(child, packs).render, outPath + child.path.dropRight(1).mkString("/", "/", "/"), child.path.last + ".html") } diff --git a/dottydoc/jvm/test/WhitelistedStdLib.scala b/dottydoc/jvm/test/WhitelistedStdLib.scala new file mode 100644 index 000000000..8ba8f2b89 --- /dev/null +++ b/dottydoc/jvm/test/WhitelistedStdLib.scala @@ -0,0 +1,21 @@ +package dotty.tools +package dottydoc + +import scala.io.Source + +object WhitelistedStdLib extends DottyDoc { + override def main(args: Array[String]) = { + val whitelist = "../../test/dotc/scala-collections.whitelist" + val stdlibFiles = Source.fromFile(whitelist, "UTF8") + .getLines() + .map(_.trim) // allow identation + .filter(!_.startsWith("#")) // allow comment lines prefixed by # + .map(_.takeWhile(_ != '#').trim) // allow comments in the end of line + .filter(_.nonEmpty) + .filterNot(_.endsWith("package.scala")) + .map("../." + _) + .toArray + + super.main("-language:Scala2" +: stdlibFiles) + } +} -- cgit v1.2.3