11/*
2- * searchtools.js
3- * ~~~~~~~~~~~~~~~~
4- *
52 * Sphinx JavaScript utilities for the full-text search.
6- *
7- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
8- * :license: BSD, see LICENSE for details.
9- *
103 */
114"use strict" ;
125
@@ -20,7 +13,7 @@ if (typeof Scorer === "undefined") {
2013 // and returns the new score.
2114 /*
2215 score: result => {
23- const [docname, title, anchor, descr, score, filename] = result
16+ const [docname, title, anchor, descr, score, filename, kind ] = result
2417 return score
2518 },
2619 */
@@ -47,6 +40,14 @@ if (typeof Scorer === "undefined") {
4740 } ;
4841}
4942
43+ // Global search result kind enum, used by themes to style search results.
44+ class SearchResultKind {
45+ static get index ( ) { return "index" ; }
46+ static get object ( ) { return "object" ; }
47+ static get text ( ) { return "text" ; }
48+ static get title ( ) { return "title" ; }
49+ }
50+
5051const _removeChildren = ( element ) => {
5152 while ( element && element . lastChild ) element . removeChild ( element . lastChild ) ;
5253} ;
@@ -64,9 +65,13 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
6465 const showSearchSummary = DOCUMENTATION_OPTIONS . SHOW_SEARCH_SUMMARY ;
6566 const contentRoot = document . documentElement . dataset . content_root ;
6667
67- const [ docName , title , anchor , descr , score , _filename ] = item ;
68+ const [ docName , title , anchor , descr , score , _filename , kind ] = item ;
6869
6970 let listItem = document . createElement ( "li" ) ;
71+ // Add a class representing the item's type:
72+ // can be used by a theme's CSS selector for styling
73+ // See SearchResultKind for the class names.
74+ listItem . classList . add ( `kind-${ kind } ` ) ;
7075 let requestUrl ;
7176 let linkUrl ;
7277 if ( docBuilder === "dirhtml" ) {
@@ -115,8 +120,10 @@ const _finishSearch = (resultCount) => {
115120 "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
116121 ) ;
117122 else
118- Search . status . innerText = _ (
119- "Search finished, found ${resultCount} page(s) matching the search query."
123+ Search . status . innerText = Documentation . ngettext (
124+ "Search finished, found one page matching the search query." ,
125+ "Search finished, found ${resultCount} pages matching the search query." ,
126+ resultCount ,
120127 ) . replace ( '${resultCount}' , resultCount ) ;
121128} ;
122129const _displayNextItem = (
@@ -138,7 +145,7 @@ const _displayNextItem = (
138145 else _finishSearch ( resultCount ) ;
139146} ;
140147// Helper function used by query() to order search results.
141- // Each input is an array of [docname, title, anchor, descr, score, filename].
148+ // Each input is an array of [docname, title, anchor, descr, score, filename, kind ].
142149// Order the results by score (in opposite order of appearance, since the
143150// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
144151const _orderResultsByScoreThenName = ( a , b ) => {
@@ -178,7 +185,7 @@ const Search = {
178185
179186 htmlToText : ( htmlString , anchor ) => {
180187 const htmlElement = new DOMParser ( ) . parseFromString ( htmlString , 'text/html' ) ;
181- for ( const removalQuery of [ ".headerlinks " , "script" , "style" ] ) {
188+ for ( const removalQuery of [ ".headerlink " , "script" , "style" ] ) {
182189 htmlElement . querySelectorAll ( removalQuery ) . forEach ( ( el ) => { el . remove ( ) } ) ;
183190 }
184191 if ( anchor ) {
@@ -248,6 +255,7 @@ const Search = {
248255 searchSummary . classList . add ( "search-summary" ) ;
249256 searchSummary . innerText = "" ;
250257 const searchList = document . createElement ( "ul" ) ;
258+ searchList . setAttribute ( "role" , "list" ) ;
251259 searchList . classList . add ( "search" ) ;
252260
253261 const out = document . getElementById ( "search-results" ) ;
@@ -318,7 +326,7 @@ const Search = {
318326 const indexEntries = Search . _index . indexentries ;
319327
320328 // Collect multiple result groups to be sorted separately and then ordered.
321- // Each is an array of [docname, title, anchor, descr, score, filename].
329+ // Each is an array of [docname, title, anchor, descr, score, filename, kind ].
322330 const normalResults = [ ] ;
323331 const nonMainIndexResults = [ ] ;
324332
@@ -328,14 +336,16 @@ const Search = {
328336 for ( const [ title , foundTitles ] of Object . entries ( allTitles ) ) {
329337 if ( title . toLowerCase ( ) . trim ( ) . includes ( queryLower ) && ( queryLower . length >= title . length / 2 ) ) {
330338 for ( const [ file , id ] of foundTitles ) {
331- let score = Math . round ( 100 * queryLower . length / title . length )
339+ const score = Math . round ( Scorer . title * queryLower . length / title . length ) ;
340+ const boost = titles [ file ] === title ? 1 : 0 ; // add a boost for document titles
332341 normalResults . push ( [
333342 docNames [ file ] ,
334343 titles [ file ] !== title ? `${ titles [ file ] } > ${ title } ` : title ,
335344 id !== null ? "#" + id : "" ,
336345 null ,
337- score ,
346+ score + boost ,
338347 filenames [ file ] ,
348+ SearchResultKind . title ,
339349 ] ) ;
340350 }
341351 }
@@ -353,6 +363,7 @@ const Search = {
353363 null ,
354364 score ,
355365 filenames [ file ] ,
366+ SearchResultKind . index ,
356367 ] ;
357368 if ( isMain ) {
358369 normalResults . push ( result ) ;
@@ -474,6 +485,7 @@ const Search = {
474485 descr ,
475486 score ,
476487 filenames [ match [ 0 ] ] ,
488+ SearchResultKind . object ,
477489 ] ) ;
478490 } ;
479491 Object . keys ( objects ) . forEach ( ( prefix ) =>
@@ -584,6 +596,7 @@ const Search = {
584596 null ,
585597 score ,
586598 filenames [ file ] ,
599+ SearchResultKind . text ,
587600 ] ) ;
588601 }
589602 return results ;
0 commit comments