@@ -4,6 +4,7 @@ const MAX_SUBSTRING_LIMIT = 100;
44const ANIMATION_TIME = 200 ;
55const FETCH_RESULTS_DELAY = 250 ;
66const CLEAR_RESULTS_DELAY = 300 ;
7+ const RTD_SEARCH_PARAMETER = "rtd_search" ;
78
89/**
910 * Debounce the function.
@@ -42,7 +43,7 @@ const debounce = (func, wait) => {
4243
4344/**
4445 * Wrapper around underscorejs's template function.
45- *
46+ *
4647 * This is to make it work with new and old versions.
4748 */
4849const render_template = ( template , data ) => {
@@ -55,69 +56,21 @@ const render_template = (template, data) => {
5556 return result ;
5657} ;
5758
58- /**
59- * Take an object as parameter and convert it to
60- * url params string.
61- *
62- * Eg. if ``obj = { 'a': 1, 'b': 2, 'c': ['hello', 'world'] }``, then it will return
63- * the string ``a=1&b=2&c=hello,world``
64- *
65- * @param {Object } obj the object to be converted
66- * @return {String|Array } object in url params form
67- */
68- const convertObjToUrlParams = obj => {
69- let params = Object . keys ( obj ) . map ( function ( key ) {
70- if ( _is_string ( key ) ) {
71- const s = key + "=" + encodeURI ( obj [ key ] ) ;
72- return s ;
73- }
74- } ) ;
75-
76- // removing empty strings from the 'params' array
77- let final_params = [ ] ;
78- for ( let i = 0 ; i < params . length ; ++ i ) {
79- if ( _is_string ( params [ i ] ) ) {
80- final_params . push ( params [ i ] ) ;
81- }
82- }
83- if ( final_params . length === 1 ) {
84- return final_params [ 0 ] ;
85- } else {
86- let final_url_params = final_params . join ( "&" ) ;
87- return final_url_params ;
88- }
89- } ;
90-
9159
9260/**
9361 * Adds/removes "rtd_search" url parameter to the url.
9462 */
9563const updateUrl = ( ) => {
96- let origin = window . location . origin ;
97- let path = window . location . pathname ;
98- let url_params = $ . getQueryParameters ( ) ;
99- let hash = window . location . hash ;
64+ let parsed_url = new URL ( window . location . href ) ;
10065 let search_query = getSearchTerm ( ) ;
101- // search_query should not be an empty string
66+ // search_query should not be an empty string.
10267 if ( search_query . length > 0 ) {
103- url_params . rtd_search = search_query ;
68+ parsed_url . searchParams . set ( RTD_SEARCH_PARAMETER , search_query ) ;
10469 } else {
105- delete url_params . rtd_search ;
70+ parsed_url . searchParams . delete ( RTD_SEARCH_PARAMETER ) ;
10671 }
107-
108- let window_location_search = convertObjToUrlParams ( url_params ) + hash ;
109-
110- // this happens during the tests,
111- // when window.location.origin is "null" in Firefox
112- // then correct URL is contained by window.location.pathname
113- // which starts with "file://"
114- let url = path + "?" + window_location_search ;
115- if ( origin . substring ( 0 , 4 ) === "http" ) {
116- url = origin + url ;
117- }
118-
119- // update url
120- window . history . pushState ( { } , null , url ) ;
72+ // Update url.
73+ window . history . pushState ( { } , null , parsed_url . toString ( ) ) ;
12174} ;
12275
12376
@@ -172,18 +125,6 @@ const _is_string = str => {
172125 }
173126} ;
174127
175- /**
176- * Checks if data type is a non-empty array
177- * @param {* } data data whose type is to be checked
178- * @return {Boolean } returns true if data is non-empty array, else returns false
179- */
180- const _is_array = arr => {
181- if ( Array . isArray ( arr ) && arr . length > 0 ) {
182- return true ;
183- } else {
184- return false ;
185- }
186- } ;
187128
188129/**
189130 * Generate and return html structure
@@ -538,11 +479,12 @@ const getErrorDiv = err_msg => {
538479 * and appends the results to <div class="search__outer"> node,
539480 * which is already created when the page was loaded.
540481 *
541- * @param {String } search_url url on which request will be sent
542- * @param {String } projectName name (slug) of the project
482+ * @param {String } api_endpoint: API endpoint
483+ * @param {Object } parameters: search parameters
484+ * @param {String } projectName: name (slug) of the project
543485 * @return {Function } debounced function with debounce time of 500ms
544486 */
545- const fetchAndGenerateResults = ( search_url , projectName ) => {
487+ const fetchAndGenerateResults = ( api_endpoint , parameters , projectName ) => {
546488 let search_outer = document . querySelector ( ".search__outer" ) ;
547489
548490 // Removes all results (if there is any),
@@ -553,52 +495,48 @@ const fetchAndGenerateResults = (search_url, projectName) => {
553495 search_loding . innerHTML = "<strong>Searching ....</strong>" ;
554496 search_outer . appendChild ( search_loding ) ;
555497
556- let ajaxFunc = ( ) => {
498+ let fetchFunc = ( ) => {
557499 // Update URL just before fetching the results
558500 updateUrl ( ) ;
559501 updateSearchBar ( ) ;
560502
561- $ . ajax ( {
562- url : search_url ,
563- crossDomain : true ,
564- xhrFields : {
565- withCredentials : true
566- } ,
567- complete : ( resp , status_code ) => {
568- if (
569- status_code === "success" ||
570- typeof resp . responseJSON !== "undefined"
571- ) {
572- if ( resp . responseJSON . results . length > 0 ) {
573- let search_result_box = generateSuggestionsList (
574- resp . responseJSON ,
575- projectName
576- ) ;
577- removeResults ( ) ;
578- search_outer . appendChild ( search_result_box ) ;
579-
580- // remove active classes from all suggestions
581- // if the mouse hovers, otherwise styles from
582- // :hover and .active will clash.
583- search_outer . addEventListener ( "mouseenter" , e => {
584- removeAllActive ( ) ;
585- } ) ;
586- } else {
587- removeResults ( ) ;
588- let err_div = getErrorDiv ( "No results found" ) ;
589- search_outer . appendChild ( err_div ) ;
590- }
591- }
592- } ,
593- error : ( resp , status_code , error ) => {
503+ const url = api_endpoint + "?" + new URLSearchParams ( parameters ) . toString ( ) ;
504+
505+ fetch ( url , { method : "GET" } )
506+ . then ( response => {
507+ if ( ! response . ok ) {
508+ throw new Error ( ) ;
509+ }
510+ return response . json ( ) ;
511+ } )
512+ . then ( data => {
513+ if ( data . results . length > 0 ) {
514+ let search_result_box = generateSuggestionsList (
515+ data ,
516+ projectName
517+ ) ;
518+ removeResults ( ) ;
519+ search_outer . appendChild ( search_result_box ) ;
520+
521+ // remove active classes from all suggestions
522+ // if the mouse hovers, otherwise styles from
523+ // :hover and .active will clash.
524+ search_outer . addEventListener ( "mouseenter" , e => {
525+ removeAllActive ( ) ;
526+ } ) ;
527+ } else {
594528 removeResults ( ) ;
595- let err_div = getErrorDiv ( "There was an error. Please try again. " ) ;
529+ let err_div = getErrorDiv ( "No results found " ) ;
596530 search_outer . appendChild ( err_div ) ;
597531 }
532+ } )
533+ . catch ( error => {
534+ removeResults ( ) ;
535+ let err_div = getErrorDiv ( "There was an error. Please try again." ) ;
536+ search_outer . appendChild ( err_div ) ;
598537 } ) ;
599538 } ;
600- ajaxFunc = debounce ( ajaxFunc , FETCH_RESULTS_DELAY ) ;
601- return ajaxFunc ;
539+ return debounce ( fetchFunc , FETCH_RESULTS_DELAY ) ;
602540} ;
603541
604542/**
@@ -696,7 +634,6 @@ window.addEventListener("DOMContentLoaded", () => {
696634 if ( window . hasOwnProperty ( "READTHEDOCS_DATA" ) ) {
697635 const project = READTHEDOCS_DATA . project ;
698636 const version = READTHEDOCS_DATA . version ;
699- const language = READTHEDOCS_DATA . language || "en" ;
700637 const api_host = READTHEDOCS_DATA . proxied_api_host || '/_' ;
701638
702639 let initialHtml = generateAndReturnInitialHtml ( ) ;
@@ -720,25 +657,18 @@ window.addEventListener("DOMContentLoaded", () => {
720657
721658 search_outer_input . addEventListener ( "input" , e => {
722659 let search_query = getSearchTerm ( ) ;
723-
724- let search_params = {
725- q : search_query ,
726- project : project ,
727- version : version ,
728- language : language ,
729- } ;
730-
731- const search_url =
732- api_host +
733- "/api/v2/search/?" +
734- convertObjToUrlParams ( search_params ) ;
735-
736660 if ( search_query . length > 0 ) {
737661 if ( current_request !== null ) {
738662 // cancel previous ajax request.
739663 current_request . cancel ( ) ;
740664 }
741- current_request = fetchAndGenerateResults ( search_url , project ) ;
665+ const search_endpoint = api_host + "/api/v2/search/" ;
666+ const search_params = {
667+ q : search_query ,
668+ project : project ,
669+ version : version ,
670+ } ;
671+ current_request = fetchAndGenerateResults ( search_endpoint , search_params , project ) ;
742672 current_request ( ) ;
743673 } else {
744674 // if the last request returns the results,
@@ -825,9 +755,9 @@ window.addEventListener("DOMContentLoaded", () => {
825755 // if "rtd_search" is present in URL parameters,
826756 // then open the search modal and show the results
827757 // for the value of "rtd_search"
828- let url_params = $ . getQueryParameters ( ) ;
829- if ( _is_array ( url_params . rtd_search ) ) {
830- let query = decodeURIComponent ( url_params . rtd_search ) ;
758+ const url_params = new URLSearchParams ( document . location . search ) ;
759+ const query = url_params . get ( RTD_SEARCH_PARAMETER ) ;
760+ if ( query !== null ) {
831761 showSearchModal ( query ) ;
832762 search_outer_input . value = query ;
833763
0 commit comments