aboutsummaryrefslogtreecommitdiff
path: root/dottydoc
diff options
context:
space:
mode:
Diffstat (limited to 'dottydoc')
-rw-r--r--dottydoc/js/src/DottyDoc.scala2
-rw-r--r--dottydoc/js/src/Search.scala115
-rw-r--r--dottydoc/js/src/html/EntityLayout.scala2
-rw-r--r--dottydoc/js/src/html/Member.scala4
-rw-r--r--dottydoc/js/src/model/entities.scala50
-rw-r--r--dottydoc/jvm/resources/index.css49
-rw-r--r--dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala4
-rw-r--r--dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala11
-rw-r--r--dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala1
9 files changed, 181 insertions, 57 deletions
diff --git a/dottydoc/js/src/DottyDoc.scala b/dottydoc/js/src/DottyDoc.scala
index 5773e6a19..d33648e49 100644
--- a/dottydoc/js/src/DottyDoc.scala
+++ b/dottydoc/js/src/DottyDoc.scala
@@ -18,7 +18,7 @@ import html.EntityLayout
hljs.initHighlightingOnLoad()
val searchInput = document.getElementById("search").asInstanceOf[dom.html.Input]
- searchInput.onkeyup = Search(searchInput)
+ searchInput.onkeyup = new Search(searchInput).search()
}
}
diff --git a/dottydoc/js/src/Search.scala b/dottydoc/js/src/Search.scala
index 0683c5d95..6625e3c78 100644
--- a/dottydoc/js/src/Search.scala
+++ b/dottydoc/js/src/Search.scala
@@ -2,33 +2,120 @@ package dotty.tools.dottydoc
package js
import scala.scalajs.{ js => sjs }
-import sjs.timers._
-import org.scalajs.dom
+import sjs.timers.setTimeout
+import scalatags.JsDom.all._
+import org.scalajs.dom.html.{ Input, Div }
+import org.scalajs.dom.{ document, Event }
+import scala.concurrent.ExecutionContext.Implicits.global
+import scala.concurrent.Future
-object Search {
+import js.model._
+import js.model.ops._
+
+class Search(val input: Input) {
private var isSearching = false
- def apply(input: dom.html.Input) = considerSearch(input)
+ private val mainDiv = document
+ .getElementById("entity-container")
+ .asInstanceOf[Div]
+ private val resultsDiv = document
+ .getElementById("search-results")
+ .asInstanceOf[Div]
+
+ /** Search result ADTs */
+ private case class PackageResults(matching: Stream[Package], nonMatching: Stream[Package])
+ private object PackageResults {
+ def empty = PackageResults(Stream.empty, Stream.empty)
+ }
- def considerSearch(input: dom.html.Input): dom.Event => Unit = { e =>
- val query = input.value
+ /** Entry point into search, will consider whether to start searching or not,
+ * then call `performSearch`
+ */
+ def search(): Event => Unit = { e =>
+ val query = input.value.trim
if (query.length > 2) setTimeout(200) {
if (!isSearching) {
isSearching = true
- performSearch(query)
+ performSearch(query.toLowerCase).map { _ => isSearching = false }
}
}
+ else if (query.length == 0)
+ hideSearchDiv()
}
- def performSearch(query: String): Unit = {
- println(s"searching for $query...")
+ private def performSearch(query: String): Future[Unit] =
+ for (PackageResults(matching, nonMatching) <- searchPackages(query)) yield {
+ // Clear old results, add new result categories add close button
+ resultsDiv.innerHTML = ""
+ val toplevelRes = div(id := "toplevel-results").render
+ val methodRes = div(id := "method-results").render
+ val closeButton = button(
+ id := "close-button",
+ onclick := { _: Event =>
+ resetInput()
+ hideSearchDiv()
+ },
+ cls := "mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored",
+ i(cls := "material-icons", "clear")
+ ).render
+
+ resultsDiv.appendChild(toplevelRes)
+ resultsDiv.appendChild(methodRes)
+ resultsDiv.appendChild(closeButton)
+
+ // Add all matching toplevel entities
+ matching
+ .toStream
+ .sortBy(_.name)
+ .map(createPackageCard)
+ .foreach(toplevelRes.appendChild)
+
+ // Hide entity and show results instead
+ showSearchDiv()
+ }
+
+ private def searchPackages(query: String): Future[PackageResults] = Future {
+ EntityIndex.packages.values.foldLeft(PackageResults.empty) { (acc, p) =>
+ val matchingMembers = p.members.collect {
+ case x if (x.name.toLowerCase.contains(query) && x.kind != "package") => x
+ }
+
+ println("We found all matching members maybe")
+ sjs.Dynamic.global.console.log(p)
- val matchingPackages = EntityIndex.packages.values.collect {
- case x if x.name.startsWith(query) => x
+ if (p.name.toLowerCase.contains(query) || matchingMembers.nonEmpty)
+ acc.copy(matching = p.withMembers(matchingMembers) #:: acc.matching)
+ else acc
}
+ }
+
+ private def createPackageCard(pack: Package): Div = div(
+ cls := "mdl-card mdl-shadow--2dp package-result",
+ div(cls := "mdl-card__title", h2(cls := "mdl-card__title-text", pack.name)),
+ ul(pack.members.map(createEntityLi).toList)
+ ).render
+
+ private def createEntityLi(e: Entity) = li(
+ a(
+ href := toRoot + e.path.mkString("", "/", ".html"),
+ e.kind + " " + e.name
+ )
+ )
+
+ private def toRoot = "../" * (EntityIndex.currentEntity.path.length - 1)
+
+ private def resetInput() = {
+ input.value = ""
+ input.parentElement.className = input.parentElement.className.replaceAll("is-dirty", "")
+ }
+
+ private def showSearchDiv() = {
+ mainDiv.style.display = "none"
+ resultsDiv.style.display = "block"
+ }
- println("Found matching packages: ")
- matchingPackages.map(_.name).foreach(println)
- isSearching = false
+ private def hideSearchDiv() = {
+ resultsDiv.style.display = "none"
+ mainDiv.style.display = "block"
}
}
diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala
index fcb0cd5e0..9a1076a16 100644
--- a/dottydoc/js/src/html/EntityLayout.scala
+++ b/dottydoc/js/src/html/EntityLayout.scala
@@ -5,7 +5,7 @@ package html
import scalatags.JsDom.all._
import org.scalajs.dom
import org.scalajs.dom.html.{Anchor, Div}
-import model._
+import dotty.tools.dottydoc.model._
case class EntityLayout(entity: Entity) extends MemberLayout {
def html = div(
diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala
index ff16631c5..c4989e762 100644
--- a/dottydoc/js/src/html/Member.scala
+++ b/dottydoc/js/src/html/Member.scala
@@ -8,8 +8,8 @@ import org.scalajs.dom
import org.scalajs.dom.html.{Anchor, Div}
trait MemberLayout {
- import model._
- import comment._
+ import dotty.tools.dottydoc.model._
+ import dotty.tools.dottydoc.model.comment._
def member(m: Entity, parent: Entity) = {
def toggleBetween(short: Div, and: Div): Unit =
diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala
index 2710a5392..4a4984a34 100644
--- a/dottydoc/js/src/model/entities.scala
+++ b/dottydoc/js/src/model/entities.scala
@@ -4,6 +4,7 @@ package js
package model
import scala.scalajs.{ js => sjs }
+import sjs.annotation.ScalaJSDefined
/** This file defines the interface for which to interact with the searchable
* index. To use the normal operations available on the traits on the JVM:
@@ -17,47 +18,47 @@ import scala.scalajs.{ js => sjs }
* interface, this is simply due to the fact that they're not necessary for
* search - YET. They could be added, for instance `comment` is missing.
*/
-@sjs.native
-trait Entity extends sjs.Any {
- val kind: String = sjs.native
+@ScalaJSDefined
+trait Entity extends sjs.Object {
+ val kind: String
- val name: String = sjs.native
+ val name: String
- val path: sjs.Array[String] = sjs.native
+ val path: sjs.Array[String]
}
-@sjs.native
-trait Members extends sjs.Any {
- val members: sjs.Array[Entity] = sjs.native
+@ScalaJSDefined
+trait Members extends sjs.Object {
+ val members: sjs.Array[Entity]
}
-@sjs.native
-trait Modifiers extends sjs.Any {
- val modifiers: sjs.Array[String] = sjs.native
+@ScalaJSDefined
+trait Modifiers extends sjs.Object {
+ val modifiers: sjs.Array[String]
}
-@sjs.native
+@ScalaJSDefined
trait Package extends Entity with Members
-@sjs.native
+@ScalaJSDefined
trait Class extends Entity with Members with Modifiers
-@sjs.native
-trait CaseClass extends Entity with Members with Modifiers
+@ScalaJSDefined
+trait CaseClass extends Class
-@sjs.native
-trait Object extends Class with Modifiers
+@ScalaJSDefined
+trait Object extends Class
-@sjs.native
+@ScalaJSDefined
trait Trait extends Class
-@sjs.native
+@ScalaJSDefined
trait Def extends Entity with Modifiers
-@sjs.native
+@ScalaJSDefined
trait Val extends Def
-@sjs.native
+@ScalaJSDefined
trait Var extends Def
object ops {
@@ -70,5 +71,12 @@ object ops {
case x if EntitiesWithMembers contains x.kind =>
x.asInstanceOf[Entity with Members]
}
+
+ def withMembers(mbrs: sjs.Array[Entity]): Package = new Package {
+ val kind = p.kind
+ val name = p.name
+ val path = p.path
+ val members = mbrs
+ }
}
}
diff --git a/dottydoc/jvm/resources/index.css b/dottydoc/jvm/resources/index.css
index 2be323ae7..c7292a1a4 100644
--- a/dottydoc/jvm/resources/index.css
+++ b/dottydoc/jvm/resources/index.css
@@ -1,21 +1,10 @@
-main > div.page-content {
- padding: 30px 60px;
-}
-
+/* Sidebar ------------------------------------------------------------------ */
span.subtitle {
font-size: 12px;
line-height: 0 !important;
padding-top: 32px;
}
-div.member {
- min-height: 70px;
-}
-
-div.member.member-fullcomment:hover {
- cursor: pointer;
-}
-
ul.packages {
padding-top: 0 !important;
}
@@ -106,6 +95,11 @@ span#docs-title {
padding-top: 2em;
}
+/* Entity ------------------------------------------------------------------- */
+main > div.page-content {
+ padding: 30px 60px;
+}
+
span.member-name, span.return-value {
font-family: "Roboto","Helvetica","Arial",sans-serif;
font-weight: 400;
@@ -114,3 +108,34 @@ span.member-name, span.return-value {
letter-spacing: .04em;
line-height: 24px;
}
+
+div.member {
+ min-height: 70px;
+}
+
+div.member.member-fullcomment:hover {
+ cursor: pointer;
+}
+
+/* Search results ----------------------------------------------------------- */
+main#search-results {
+ display: none;
+}
+
+/*
+main#search-results > div#toplevel-results {
+ float: left;
+ width: 50%;
+}
+*/
+
+main#search-results > div#toplevel-results > div.mdl-card.package-result {
+ margin: 20px auto;
+ width: 80%;
+}
+
+main#search-results > button#close-button {
+ position: fixed;
+ top: 1em;
+ right: 1em;
+}
diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala
index 84630f214..8496a11b8 100644
--- a/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala
+++ b/dottydoc/jvm/src/dotty/tools/dottydoc/html/EntityPage.scala
@@ -70,6 +70,10 @@ case class EntityPage(entity: Entity, packages: Map[String, Package]) {
main(
id := "entity-container",
cls := "mdl-layout__content"
+ ),
+ main(
+ id := "search-results",
+ cls := "mdl-layout__content"
)
)
)
diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala
index ba1438c7a..fef880351 100644
--- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala
+++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala
@@ -33,10 +33,6 @@ object json extends DefaultJsonProtocol {
}
implicit object EntityJsonFormat extends RootJsonFormat[Entity] {
- private def addKind(json: JsValue, kind: String): JsValue = json match {
- case json: JsObject => JsObject(json.fields + ("kind" -> JsString(kind)))
- case other => other
- }
def write(e: Entity) = e match {
case e: PackageImpl => addKind(e.toJson, "package")
@@ -51,10 +47,15 @@ object json extends DefaultJsonProtocol {
}
implicit object PackageFormat extends RootJsonFormat[Package] {
- def write(obj: Package) = obj match { case obj: PackageImpl => obj.toJson }
+ def write(obj: Package) = obj match { case obj: PackageImpl => addKind(obj.toJson, "package") }
def read(json: JsValue) = ??? // The json serialization is supposed to be one way
}
+ private def addKind(json: JsValue, kind: String): JsValue = json match {
+ case json: JsObject => JsObject(json.fields + ("kind" -> JsString(kind)))
+ case other => other
+ }
+
implicit val valFormat: JsonFormat[ValImpl] = lazyFormat(jsonFormat(ValImpl, "name", "modifiers", "path", "returnValue", "comment"))
implicit val defFormat: JsonFormat[DefImpl] = lazyFormat(jsonFormat(DefImpl, "name", "modifiers", "path", "returnValue", "comment"))
implicit val objFormat: JsonFormat[ObjectImpl] = lazyFormat(jsonFormat(ObjectImpl, "name", "members", "modifiers", "path", "comment"))
diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala
index b036a2d3a..7febb520c 100644
--- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala
+++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/OutputWriter.scala
@@ -31,7 +31,6 @@ class OutputWriter {
}
// Write full index to outPath
- //val pickled = Pickle.intoString(packs)
val pickled = packs.toJson
val js = "UnparsedIndex = {}; UnparsedIndex.packages = " + pickled + ";"
println("Writing index.js...")