@@ -2,11 +2,13 @@ package dotty.tools.scaladoc
2
2
3
3
import org .scalajs .dom ._
4
4
import org .scalajs .dom .html .Input
5
+ import scala .scalajs .js .timers ._
6
+ import scala .concurrent .duration ._
5
7
6
- class SearchbarComponent (val callback : ( String ) => List [ PageEntry ] ):
8
+ class SearchbarComponent (engine : SearchbarEngine , inkuireEngine : InkuireJSSearchEngine , parser : QueryParser ):
7
9
val resultsChunkSize = 100
8
10
extension (p : PageEntry )
9
- def toHTML =
11
+ def toHTML ( inkuire : Boolean = false ) =
10
12
val wrapper = document.createElement(" div" ).asInstanceOf [html.Div ]
11
13
wrapper.classList.add(" scaladoc-searchbar-result" )
12
14
wrapper.classList.add(" monospace" )
@@ -16,7 +18,7 @@ class SearchbarComponent(val callback: (String) => List[PageEntry]):
16
18
icon.classList.add(p.kind.take(2 ))
17
19
18
20
val resultA = document.createElement(" a" ).asInstanceOf [html.Anchor ]
19
- resultA.href = Globals .pathToRoot + p.location
21
+ resultA.href = if inkuire then p.location else Globals .pathToRoot + p.location
20
22
resultA.text = s " ${p.fullName}"
21
23
22
24
val location = document.createElement(" span" )
@@ -32,26 +34,67 @@ class SearchbarComponent(val callback: (String) => List[PageEntry]):
32
34
})
33
35
wrapper
34
36
35
- def handleNewQuery ( query : String ) =
36
- val result = callback( query).map(_.toHTML)
37
+ def handleNewFluffQuery ( matchers : List [ Matchers ] ) =
38
+ val result = engine. query(matchers ).map(_.toHTML(inkuire = false ) )
37
39
resultsDiv.scrollTop = 0
38
40
while (resultsDiv.hasChildNodes()) resultsDiv.removeChild(resultsDiv.lastChild)
39
41
val fragment = document.createDocumentFragment()
40
42
result.take(resultsChunkSize).foreach(fragment.appendChild)
41
43
resultsDiv.appendChild(fragment)
42
44
def loadMoreResults (result : List [raw.HTMLElement ]): Unit = {
43
45
resultsDiv.onscroll = (event : Event ) => {
44
- if (resultsDiv.scrollHeight - resultsDiv.scrollTop == resultsDiv.clientHeight)
45
- {
46
- val fragment = document.createDocumentFragment()
47
- result.take(resultsChunkSize).foreach(fragment.appendChild)
48
- resultsDiv.appendChild(fragment)
49
- loadMoreResults(result.drop(resultsChunkSize))
50
- }
46
+ if (resultsDiv.scrollHeight - resultsDiv.scrollTop == resultsDiv.clientHeight) {
47
+ val fragment = document.createDocumentFragment()
48
+ result.take(resultsChunkSize).foreach(fragment.appendChild)
49
+ resultsDiv.appendChild(fragment)
50
+ loadMoreResults(result.drop(resultsChunkSize))
51
+ }
51
52
}
52
53
}
53
54
loadMoreResults(result.drop(resultsChunkSize))
54
55
56
+ extension (s : String )
57
+ def toHTMLError =
58
+ val wrapper = document.createElement(" div" ).asInstanceOf [html.Div ]
59
+ wrapper.classList.add(" scaladoc-searchbar-result" )
60
+ wrapper.classList.add(" monospace" )
61
+
62
+ val errorSpan = document.createElement(" span" ).asInstanceOf [html.Span ]
63
+ errorSpan.classList.add(" search-error" )
64
+ errorSpan.textContent = s
65
+
66
+ wrapper.appendChild(errorSpan)
67
+ wrapper
68
+
69
+ var timeoutHandle : SetTimeoutHandle = null
70
+ def handleNewQuery (query : String ) =
71
+ clearTimeout(timeoutHandle)
72
+ resultsDiv.scrollTop = 0
73
+ resultsDiv.onscroll = (event : Event ) => { }
74
+ while (resultsDiv.hasChildNodes()) resultsDiv.removeChild(resultsDiv.lastChild)
75
+ val fragment = document.createDocumentFragment()
76
+ parser.parse(query) match {
77
+ case EngineMatchersQuery (matchers) =>
78
+ handleNewFluffQuery(matchers)
79
+ case BySignature (signature) =>
80
+ timeoutHandle = setTimeout(1 .second) {
81
+ val properResultsDiv = document.createElement(" div" ).asInstanceOf [html.Div ]
82
+ resultsDiv.appendChild(properResultsDiv)
83
+ val loading = document.createElement(" div" ).asInstanceOf [html.Div ]
84
+ loading.classList.add(" loading-wrapper" )
85
+ val animation = document.createElement(" div" ).asInstanceOf [html.Div ]
86
+ animation.classList.add(" loading" )
87
+ loading.appendChild(animation)
88
+ properResultsDiv.appendChild(loading)
89
+ inkuireEngine.query(query) { (p : PageEntry ) =>
90
+ properResultsDiv.appendChild(p.toHTML(inkuire = true ))
91
+ } { (s : String ) =>
92
+ animation.classList.remove(" loading" )
93
+ properResultsDiv.appendChild(s.toHTMLError)
94
+ }
95
+ }
96
+ }
97
+
55
98
private val searchIcon : html.Div =
56
99
val span = document.createElement(" span" ).asInstanceOf [html.Span ]
57
100
span.innerHTML = """ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><path d="M19.64 18.36l-6.24-6.24a7.52 7.52 0 10-1.28 1.28l6.24 6.24zM7.5 13.4a5.9 5.9 0 115.9-5.9 5.91 5.91 0 01-5.9 5.9z"></path></svg>"""
0 commit comments