Skip to content

Commit 9ad69ad

Browse files
committed
Inkuire JS support
1 parent 10ff05d commit 9ad69ad

File tree

11 files changed

+59762
-24
lines changed

11 files changed

+59762
-24
lines changed

scaladoc-js/src/searchbar/Searchbar.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ class Searchbar {
44
val pages = SearchbarGlobals.pages.toList.map(PageEntry.apply)
55
val engine = SearchbarEngine(pages)
66
val parser = QueryParser()
7-
val component = SearchbarComponent(q => engine.query(parser.parse(q)))
8-
}
7+
// val component = SearchbarComponent(q => engine.query(parser.parse(q)))
8+
val inkuireEngine = InkuireJSSearchEngine()
9+
val component = SearchbarComponent(inkuireEngine.query)
10+
}

scaladoc-js/src/searchbar/SearchbarComponent.scala

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package dotty.tools.scaladoc
33
import org.scalajs.dom._
44
import org.scalajs.dom.html.Input
55

6-
class SearchbarComponent(val callback: (String) => List[PageEntry]):
6+
class SearchbarComponent(val callback: (String) => (PageEntry => Node) => Unit):
77
val resultsChunkSize = 100
88
extension (p: PageEntry)
99
def toHTML =
@@ -28,24 +28,12 @@ class SearchbarComponent(val callback: (String) => List[PageEntry]):
2828
wrapper
2929

3030
def handleNewQuery(query: String) =
31-
val result = callback(query).map(_.toHTML)
3231
resultsDiv.scrollTop = 0
3332
while (resultsDiv.hasChildNodes()) resultsDiv.removeChild(resultsDiv.lastChild)
3433
val fragment = document.createDocumentFragment()
35-
result.take(resultsChunkSize).foreach(fragment.appendChild)
36-
resultsDiv.appendChild(fragment)
37-
def loadMoreResults(result: List[raw.HTMLElement]): Unit = {
38-
resultsDiv.onscroll = (event: Event) => {
39-
if (resultsDiv.scrollHeight - resultsDiv.scrollTop == resultsDiv.clientHeight)
40-
{
41-
val fragment = document.createDocumentFragment()
42-
result.take(resultsChunkSize).foreach(fragment.appendChild)
43-
resultsDiv.appendChild(fragment)
44-
loadMoreResults(result.drop(resultsChunkSize))
45-
}
46-
}
34+
callback(query) { (p: PageEntry) =>
35+
resultsDiv.appendChild(p.toHTML)
4736
}
48-
loadMoreResults(result.drop(resultsChunkSize))
4937

5038
private val searchIcon: html.Div =
5139
val span = document.createElement("span").asInstanceOf[html.Span]
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package dotty.tools.scaladoc
2+
3+
import scala.io.Source
4+
import dotty.tools.scaladoc.PageEntry
5+
import org.scalajs.dom.webworkers.Worker
6+
import org.scalajs.dom._
7+
import scala.scalajs.js.{ JSON, Dynamic }
8+
import scala.collection.mutable.ListBuffer
9+
import scala.scalajs.js
10+
import scala.scalajs.js.timers._
11+
import org.scalajs.dom.ext.Ajax
12+
import scala.scalajs.js.URIUtils
13+
14+
import scala.concurrent.ExecutionContext.global
15+
import scala.concurrent.ExecutionContext
16+
import scala.concurrent.Future
17+
18+
case class Match(
19+
prettifiedSignature: String,
20+
functionName: String,
21+
packageLocation: String,
22+
pageLocation: String
23+
)
24+
25+
case class OutputFormat(
26+
query: String,
27+
matches: List[Match]
28+
)
29+
30+
//TODO CORS problems
31+
class InkuireDelegateSearchEngine {
32+
33+
given ec: ExecutionContext = global
34+
35+
val ec2 = "http://ec2-52-59-255-148.eu-central-1.compute.amazonaws.com:8080" //TODO configure
36+
37+
private def getURLContent(url: String): Future[String] = Ajax.get(url).map(_.responseText).fallbackTo(Future("[]"))
38+
39+
def dynamicToPageEntry(d: Dynamic): PageEntry =
40+
PageEntry(
41+
d.functionName.asInstanceOf[String],
42+
d.prettifiedSignature.asInstanceOf[String],
43+
d.pageLocation.asInstanceOf[String],
44+
d.functionName.asInstanceOf[String],
45+
List.empty
46+
)
47+
48+
def query(s: String)(callback: PageEntry => Node): Unit = {
49+
val signature = URIUtils.encodeURIComponent(s)
50+
getURLContent(ec2 + "/forSignature?signature=" + signature).map(JSON.parse(_)).foreach { (d: Dynamic) =>
51+
d.matches.asInstanceOf[js.Array[Dynamic]].map(dynamicToPageEntry).foreach(callback)
52+
}
53+
}
54+
55+
}
56+
57+
class InkuireJSSearchEngine {
58+
59+
val scriptPath = Globals.pathToRoot + "scripts/"
60+
val worker = new Worker(s"${scriptPath}inkuire-worker.js")
61+
62+
def dynamicToPageEntry(d: Dynamic): PageEntry = {
63+
PageEntry(
64+
d.functionName.asInstanceOf[String],
65+
d.prettifiedSignature.asInstanceOf[String],
66+
d.pageLocation.asInstanceOf[String],
67+
d.functionName.asInstanceOf[String],
68+
List.empty
69+
)
70+
}
71+
72+
def query(s: String)(callback: PageEntry => Node): List[PageEntry] = {
73+
worker.onmessage = _ => ()
74+
val res = ListBuffer[PageEntry]()
75+
val func = (msg: MessageEvent) => {
76+
msg.data.asInstanceOf[String] match {
77+
case "engine_ready" =>
78+
case "new_query" =>
79+
case q =>
80+
val matches = JSON.parse(q).matches
81+
val actualMatches = matches.asInstanceOf[js.Array[Dynamic]].map(dynamicToPageEntry)
82+
actualMatches.foreach(callback)
83+
}
84+
}
85+
worker.onmessage = func
86+
worker.postMessage(s)
87+
res.toList
88+
}
89+
90+
}

0 commit comments

Comments
 (0)