projectEndings / staticSearch

A codebase to support a pure JSON search engine requiring no backend for any XHTML5 document collection
https://endings.uvic.ca/staticSearch/docs/index.html
Mozilla Public License 2.0
46 stars 21 forks source link

Need better programmer documentation #294

Open martindholmes opened 2 months ago

martindholmes commented 2 months ago

As more sophisticated project teams are adopting staticSearch, it's clear that we need to do a better job of providing documentation for programmers who need to override and customize behaviour. The JS is well-documented inline using JSDoc standards, so it's mostly just a question of compiling that; the XSLT is also well-documented using xd:doc etc., but we'd rather not have a dependency on the commercial Oxygen compiler for this, so we may need to write our own tool.

martindholmes commented 2 months ago

I tested compiling the JS documentation with JSDoc, and the results were not good. This was using the Ubuntu deb package, which appears to be at version 2.4; the npm package is at 4.02, so there's obviously been a lot of work done since then. We'll also need to create a config file for it.

martindholmes commented 2 months ago

Running the npm version I was able to get half-decent output, but there are some documentation features that it doesn't seem to be finding or using successfully, so I'll work on figuring out better ways to document those.

martindholmes commented 1 month ago

After more experimentation, I'm beginning to think we'll have to write our own doc-generation process. It will probably end up being much more practical than trying to bludgeon one of the existing compilers into doing what we want it to.

joeytakeda commented 1 month ago

When we chatted about this last week, we started looking at jsdoc2md (https://github.com/jsdoc2md/jsdoc-to-markdown?tab=readme-ov-file)

Just gave it a shot with the main StaticSearch JS: jsdoc2md --files js/StaticSearch.js and the output looks pretty good to me, which I put inside a details below (though I'm not sure off the top of my head why it's duplicating the documentation?).

Sample Output for StaticSearch.js ## Classes
StaticSearch
StaticSearch
## StaticSearch **Kind**: global class * [StaticSearch](#StaticSearch) * [new StaticSearch()](#new_StaticSearch_new) * [new StaticSearch()](#new_StaticSearch_new) * _instance_ * [.normalizedQuery](#StaticSearch+normalizedQuery) : Array.<string> * [.stopwords](#StaticSearch+stopwords) : Array * _inner_ * [~setupFeatFilter(filterId, filterName)](#StaticSearch..setupFeatFilter) ⇒ boolean * [~parseUrlQueryString(popping)](#StaticSearch..parseUrlQueryString) ⇒ boolean * [~openAncestorElements(startingElements)](#StaticSearch..openAncestorElements) ⇒ boolean * [~doSearch(popping)](#StaticSearch..doSearch) ⇒ boolean * [~setupSearchingDiv()](#StaticSearch..setupSearchingDiv) * [~setQueryString()](#StaticSearch..setQueryString) ⇒ boolean * [~parseSearchQuery()](#StaticSearch..parseSearchQuery) ⇒ boolean * [~addSearchItem(strInput, isPhrasal)](#StaticSearch..addSearchItem) ⇒ boolean * [~clearSearchForm()](#StaticSearch..clearSearchForm) ⇒ boolean * [~processFilters()](#StaticSearch..processFilters) ⇒ boolean * [~getDocUrisForFilters()](#StaticSearch..getDocUrisForFilters) ⇒ XSet * [~writeSearchReport()](#StaticSearch..writeSearchReport) ⇒ boolean * [~getTermsByType(termType)](#StaticSearch..getTermsByType) ⇒ Array.<number> * [~populateIndexes()](#StaticSearch..populateIndexes) * [~stemFound(data)](#StaticSearch..stemFound) * [~clearResultsDiv()](#StaticSearch..clearResultsDiv) ⇒ boolean * [~reportNoResults(trySimplerSearch)](#StaticSearch..reportNoResults) ⇒ boolean * [~reportTooManyResults()](#StaticSearch..reportTooManyResults) ⇒ boolean * [~processResults()](#StaticSearch..processResults) ⇒ boolean * [~processPhrases()](#StaticSearch..processResults..processPhrases) ⇒ * [~processMustNotContains()](#StaticSearch..processResults..processMustNotContains) ⇒ * [~processMustContains(indexes, runAsFilter)](#StaticSearch..processResults..processMustContains) ⇒ * [~processMayContains(addAllFound)](#StaticSearch..processResults..processMayContains) ⇒ * [~paginateResults()](#StaticSearch..paginateResults) ⇒ boolean * [~showAllResults()](#StaticSearch..showAllResults) ⇒ boolean * [~showMoreResults()](#StaticSearch..showMoreResults) ⇒ boolean * [~phraseToRegex(str)](#StaticSearch..phraseToRegex) ⇒ RegExp \| null * [~wildcardToRegex(strToken)](#StaticSearch..wildcardToRegex) ⇒ RegExp \| null ### new StaticSearch() This is the class that handles parsing the user's input, through typed queries in the search box and selections in search filters. It expects to find the following HTML items in the HTML of the search page which includes it (expressed as CSS selectors): input#ssQuery[type='text'] (the main search box) button#ssDoSearch (button for invoking search) div#ssSearching (div containing message to show search is under way) div#ssResults (div in which to output the results) input[type='checkbox'].staticSearch_desc (optional; checkbox lists for filtering based on text labels) input[type='text'].staticSearch_date (optional; textboxes for date filters) input[type='number'].staticSearch_num (optional; inputs for numerical filters) input[type='checkbox'].staticSearch_bool (optional: checkboxes for boolean filters) input[type='text'].staticSearch_text (NOT YET IMPLEMENTED: type-in search filter boxes) The first is mandatory, although the user is not required to use it; they may choose simply to retrieve filtered lists of documents. The second is mandatory, although the user may also invoke search by pressing return while the text box has focus. The third is mandatory, because there must be somewhere to show the results of a search. The rest are optional, but if present, they will be incorporated. ### new StaticSearch() The constructor has no paramaters since it reads everything it requires from the host HTML page. ### staticSearch.normalizedQuery : Array.<string> **Kind**: instance property of [StaticSearch](#StaticSearch) ### staticSearch.stopwords : Array this.stopwords **Kind**: instance property of [StaticSearch](#StaticSearch) ### StaticSearch~setupFeatFilter(filterId, filterName) ⇒ boolean this function runs when the json for a specific feature filter is retrieved; it enables the control and assigns functionality events to it. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if a filter is found and set up, else false. | Param | Type | Description | | --- | --- | --- | | filterId | string | the id of the filter to set up. | | filterName | string | the string name of the filter. | ### StaticSearch~parseUrlQueryString(popping) ⇒ boolean this function is run after the class is instantiated to check whether there is a search string in the browser URL. If so, it parses it out and runs the query. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if a search is initiated otherwise false. | Param | Type | Description | | --- | --- | --- | | popping | boolean | specifies whether this parse has been triggered by window.onpopstate (meaning the user is moving through the browser history) | ### StaticSearch~openAncestorElements(startingElements) ⇒ boolean **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if any change is made, otherwise false. | Param | Type | Description | | --- | --- | --- | | startingElements | Array | The array of elements from which to search up the tree for ancestors which need to be opened. For each element, any ancestor details element is opened so that the starting control is not hidden. | ### StaticSearch~doSearch(popping) ⇒ boolean this function initiates the search process, taking it as far as creating the promises for retrieval of JSON files. After that, the resolution of the promises carries the process on. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if a search is initiated otherwise false. | Param | Type | Description | | --- | --- | --- | | popping | boolean | specifies whether this parse has been triggered by window.onpopstate (meaning the user is moving through the browser history) | ### StaticSearch~setupSearchingDiv() this function sets up the "Searching..." popup message, by adding a class to the document body that makes the ssSearching div appear; it then sets polls to see whether StaticSearch.isSearching has been set back to false and, if so, removes the class **Kind**: inner method of [StaticSearch](#StaticSearch) ### StaticSearch~setQueryString() ⇒ boolean this function is run once a search is initiated, and it takes the search parameters and creates a browser URL search string, then pushes this into the History object so that all searches are bookmarkable. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, otherwise false. ### StaticSearch~parseSearchQuery() ⇒ boolean this retrieves the content of the text search box and parses it into an array of term items ready for analysis against retrieved results. Even if no search terms are found, it returns true so that filter-only searches may proceed. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if no errors occur, otherwise false. ### StaticSearch~addSearchItem(strInput, isPhrasal) ⇒ boolean this is passed a single component from the search box parser by parseSearchQuery. It constructs a single item from it, and adds that to this.terms. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if terms found, otherwise false. | Param | Type | Description | | --- | --- | --- | | strInput | string | a string of text. | | isPhrasal | boolean | whether or not this is a phrasal search. This may be true even for a single word, if it is to be searched unstemmed. | ### StaticSearch~clearSearchForm() ⇒ boolean this function removes all previously-selected filter control settings, and empties the search query box. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true on success, false on failure. ### StaticSearch~processFilters() ⇒ boolean this function calls StaticSearch~getDocUrisForFilters(), and if the function succeeds, it sets the docsMatchingFilters to the returned XSet and returns true, otherwise it clears the current set of filters (THINK: IS THIS CORRECT BEHAVIOUR?) and returns false. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true on success, false on failure. ### StaticSearch~getDocUrisForFilters() ⇒ XSet this function gets the set of currently-configured filters by analyzing the form elements, then returns a set (in the form of an XSet object) of all the document ids that qualify according to the filters. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: XSet - an XSet object (which might be empty) with an added boolean property filtersActive which specifies whether filters have been configured by the user. ### StaticSearch~writeSearchReport() ⇒ boolean This outputs a human-readable explanation of the search that's being done, to clarify for users what they've chosen to look for. Note that the output div is hidden by default. NOTE: This does not yet include filter information. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if the process succeeds, otherwise false. ### StaticSearch~getTermsByType(termType) ⇒ Array.<number> This method returns an array of indexes in the StaticSearch.terms array, being the terms which match the supplied term type (PHRASE, MUST_CONTAIN etc.). **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: Array.<number> - An array of zero or more integers. | Param | Type | Description | | --- | --- | --- | | termType | number | One of PHRASE, MUST_CONTAIN, MUST_NOT_CONTAIN, MAY_CONTAIN. | ### StaticSearch~populateIndexes() The task of this function is basically to ensure that the various indexes (search terms and facet filters) are ready to handle a search, in that attempts have been made to retrieve all JSON files relating to the current search. The index is deemed ready when either a) all the JSON files for required stems and filters have been retrieved and their contents merged into the required structures, or b) a retrieval has failed, so an empty placeholder has been inserted to signify that there is no such dataset. The function works with fetch and promises, and its final .then() calls the processResults function. **Kind**: inner method of [StaticSearch](#StaticSearch) ### StaticSearch~stemFound(data) Before a request for a JSON file is initially made, an empty index is stored, indexed under the stem which is being searched, so that whether or not we successfully retrieve data, we won't have to try again in a subsequent search in the same session. Then, when a request for a JSON file for a specific stem results in a JSON file with data, we overwrite the data in the index, indexed under the stem. Sometimes the data coming in may be an instance of an empty index, if the retrieval code knows it got nothing. **Kind**: inner method of [StaticSearch](#StaticSearch) | Param | Type | Description | | --- | --- | --- | | data | Object | the data structure retrieved for the stem. | ### StaticSearch~clearResultsDiv() ⇒ boolean This clears out and sets up the results div, ready for reporting of results. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. ### StaticSearch~reportNoResults(trySimplerSearch) ⇒ boolean Reports that no results have been found. Also optionally configures and runs a simpler version of the current search, with phrases tokenized, etc. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. | Param | Type | Description | | --- | --- | --- | | trySimplerSearch | boolean | a flag to determine whether this search should be simplified and automatically run again. | ### StaticSearch~reportTooManyResults() ⇒ boolean Reports, both in the results and the console, that the number of results found exceed the configured limit (StaticSearch.resultsLimit) and cannot be displayed. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not ### StaticSearch~processResults() ⇒ boolean When we are satisfied that all relevant search data has been retrieved and added to the index, this function is called to process the search and show any results found. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if there are results to show; false if not. * [~processResults()](#StaticSearch..processResults) ⇒ boolean * [~processPhrases()](#StaticSearch..processResults..processPhrases) ⇒ * [~processMustNotContains()](#StaticSearch..processResults..processMustNotContains) ⇒ * [~processMustContains(indexes, runAsFilter)](#StaticSearch..processResults..processMustContains) ⇒ * [~processMayContains(addAllFound)](#StaticSearch..processResults..processMayContains) ⇒ #### processResults~processPhrases() ⇒ Embedded function to retrieve the results from phrasal searches. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. #### processResults~processMustNotContains() ⇒ Embedded function to remove from the result set all documents which contain terms which have been designated as excluded. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. #### processResults~processMustContains(indexes, runAsFilter) ⇒ Embedded function to retrieve all documents containing terms designated as required. This function works in two ways; if running after a phrasal search has been done, it simply acts as a filter on the document set already retrieved; if running as the initial retrieval mechanism (where there are no phrasal searches), it populates the result set itself. It's doubly complicated because it must also eliminate from the existing result set any document that doesn't contain a term. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. | Param | Type | Description | | --- | --- | --- | | indexes | Array.<number> | a list of indexes into the terms array. This needs to be a parameter because the function is calls itself recursively with a reduced array. | | runAsFilter | boolean | controls which mode the process runs in. | #### processResults~processMayContains(addAllFound) ⇒ Embedded function to process may_contain search terms. This function runs in two modes: if it's being called after prior imperative search terms have been processed, then it adds no new documents to the set, just enhances their scores. But if there are no imperative search terms, then all documents found are added to the set. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. | Param | Type | Description | | --- | --- | --- | | addAllFound | boolean | controls which mode the process runs in. | ### StaticSearch~paginateResults() ⇒ boolean This method adds pagination controls to the results and adds a number of properties to the StaticSearch object to handle pagination. It first checks whether or not it needs to add anything to the page, and, if it does, then adds the Show More / Show All buttons to the bottom of the results div and adds some functionality to the buttons. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if necessary; false if unnecessary ### StaticSearch~showAllResults() ⇒ boolean Method to show all of the results (i.e. removing the hidden item's class that instructs all of its siblings to hide) and hide the pagination widget. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. ### StaticSearch~showMoreResults() ⇒ boolean Method to show more results based off of the current page and the number of results to show. If we're on the last page, then the "Show More" is simply a proxy for showAll; otherwise, it shifts the hidden class from the last item to the next one in the sequence. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. ### StaticSearch~phraseToRegex(str) ⇒ RegExp \| null This method takes a phrase and converts it into the regular expression that will be matched against contexts. This function first escapes all characters to prevent from unintentional regular expression, then expands all apostrophes (i.e. treating U+0027, U+2018, U+2019, U+201B as equivalent) and all quotation marks. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: RegExp \| null - a regular expression, or null if one can't be constructed | Param | Type | Description | | --- | --- | --- | | str | string | a string of text | ### StaticSearch~wildcardToRegex(strToken) ⇒ RegExp \| null This method is provided with a single token as input. The token should contain wildcard characters (asterisk, question mark and square brackets). The function converts this to a JS regular expression. For example: th*n[gk]? would become /^th.*[gk].$/. The regex is created with leading and trailing pipe characters, because the string of words against which it will be matched uses these as delimiters, and it has a capturing group for the content between the pipes. Because of the use of the pipe delimiter, a negative character class [^\\|] (i.e. 'not a pipe') is used in place of a dot. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: RegExp \| null - a regular expression; or null if one cannot be constructed. | Param | Type | Description | | --- | --- | --- | | strToken | string | a string of text with no spaces. | ## StaticSearch **Kind**: global class * [StaticSearch](#StaticSearch) * [new StaticSearch()](#new_StaticSearch_new) * [new StaticSearch()](#new_StaticSearch_new) * _instance_ * [.normalizedQuery](#StaticSearch+normalizedQuery) : Array.<string> * [.stopwords](#StaticSearch+stopwords) : Array * _inner_ * [~setupFeatFilter(filterId, filterName)](#StaticSearch..setupFeatFilter) ⇒ boolean * [~parseUrlQueryString(popping)](#StaticSearch..parseUrlQueryString) ⇒ boolean * [~openAncestorElements(startingElements)](#StaticSearch..openAncestorElements) ⇒ boolean * [~doSearch(popping)](#StaticSearch..doSearch) ⇒ boolean * [~setupSearchingDiv()](#StaticSearch..setupSearchingDiv) * [~setQueryString()](#StaticSearch..setQueryString) ⇒ boolean * [~parseSearchQuery()](#StaticSearch..parseSearchQuery) ⇒ boolean * [~addSearchItem(strInput, isPhrasal)](#StaticSearch..addSearchItem) ⇒ boolean * [~clearSearchForm()](#StaticSearch..clearSearchForm) ⇒ boolean * [~processFilters()](#StaticSearch..processFilters) ⇒ boolean * [~getDocUrisForFilters()](#StaticSearch..getDocUrisForFilters) ⇒ XSet * [~writeSearchReport()](#StaticSearch..writeSearchReport) ⇒ boolean * [~getTermsByType(termType)](#StaticSearch..getTermsByType) ⇒ Array.<number> * [~populateIndexes()](#StaticSearch..populateIndexes) * [~stemFound(data)](#StaticSearch..stemFound) * [~clearResultsDiv()](#StaticSearch..clearResultsDiv) ⇒ boolean * [~reportNoResults(trySimplerSearch)](#StaticSearch..reportNoResults) ⇒ boolean * [~reportTooManyResults()](#StaticSearch..reportTooManyResults) ⇒ boolean * [~processResults()](#StaticSearch..processResults) ⇒ boolean * [~processPhrases()](#StaticSearch..processResults..processPhrases) ⇒ * [~processMustNotContains()](#StaticSearch..processResults..processMustNotContains) ⇒ * [~processMustContains(indexes, runAsFilter)](#StaticSearch..processResults..processMustContains) ⇒ * [~processMayContains(addAllFound)](#StaticSearch..processResults..processMayContains) ⇒ * [~paginateResults()](#StaticSearch..paginateResults) ⇒ boolean * [~showAllResults()](#StaticSearch..showAllResults) ⇒ boolean * [~showMoreResults()](#StaticSearch..showMoreResults) ⇒ boolean * [~phraseToRegex(str)](#StaticSearch..phraseToRegex) ⇒ RegExp \| null * [~wildcardToRegex(strToken)](#StaticSearch..wildcardToRegex) ⇒ RegExp \| null ### new StaticSearch() This is the class that handles parsing the user's input, through typed queries in the search box and selections in search filters. It expects to find the following HTML items in the HTML of the search page which includes it (expressed as CSS selectors): input#ssQuery[type='text'] (the main search box) button#ssDoSearch (button for invoking search) div#ssSearching (div containing message to show search is under way) div#ssResults (div in which to output the results) input[type='checkbox'].staticSearch_desc (optional; checkbox lists for filtering based on text labels) input[type='text'].staticSearch_date (optional; textboxes for date filters) input[type='number'].staticSearch_num (optional; inputs for numerical filters) input[type='checkbox'].staticSearch_bool (optional: checkboxes for boolean filters) input[type='text'].staticSearch_text (NOT YET IMPLEMENTED: type-in search filter boxes) The first is mandatory, although the user is not required to use it; they may choose simply to retrieve filtered lists of documents. The second is mandatory, although the user may also invoke search by pressing return while the text box has focus. The third is mandatory, because there must be somewhere to show the results of a search. The rest are optional, but if present, they will be incorporated. ### new StaticSearch() The constructor has no paramaters since it reads everything it requires from the host HTML page. ### staticSearch.normalizedQuery : Array.<string> **Kind**: instance property of [StaticSearch](#StaticSearch) ### staticSearch.stopwords : Array this.stopwords **Kind**: instance property of [StaticSearch](#StaticSearch) ### StaticSearch~setupFeatFilter(filterId, filterName) ⇒ boolean this function runs when the json for a specific feature filter is retrieved; it enables the control and assigns functionality events to it. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if a filter is found and set up, else false. | Param | Type | Description | | --- | --- | --- | | filterId | string | the id of the filter to set up. | | filterName | string | the string name of the filter. | ### StaticSearch~parseUrlQueryString(popping) ⇒ boolean this function is run after the class is instantiated to check whether there is a search string in the browser URL. If so, it parses it out and runs the query. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if a search is initiated otherwise false. | Param | Type | Description | | --- | --- | --- | | popping | boolean | specifies whether this parse has been triggered by window.onpopstate (meaning the user is moving through the browser history) | ### StaticSearch~openAncestorElements(startingElements) ⇒ boolean **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if any change is made, otherwise false. | Param | Type | Description | | --- | --- | --- | | startingElements | Array | The array of elements from which to search up the tree for ancestors which need to be opened. For each element, any ancestor details element is opened so that the starting control is not hidden. | ### StaticSearch~doSearch(popping) ⇒ boolean this function initiates the search process, taking it as far as creating the promises for retrieval of JSON files. After that, the resolution of the promises carries the process on. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if a search is initiated otherwise false. | Param | Type | Description | | --- | --- | --- | | popping | boolean | specifies whether this parse has been triggered by window.onpopstate (meaning the user is moving through the browser history) | ### StaticSearch~setupSearchingDiv() this function sets up the "Searching..." popup message, by adding a class to the document body that makes the ssSearching div appear; it then sets polls to see whether StaticSearch.isSearching has been set back to false and, if so, removes the class **Kind**: inner method of [StaticSearch](#StaticSearch) ### StaticSearch~setQueryString() ⇒ boolean this function is run once a search is initiated, and it takes the search parameters and creates a browser URL search string, then pushes this into the History object so that all searches are bookmarkable. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, otherwise false. ### StaticSearch~parseSearchQuery() ⇒ boolean this retrieves the content of the text search box and parses it into an array of term items ready for analysis against retrieved results. Even if no search terms are found, it returns true so that filter-only searches may proceed. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if no errors occur, otherwise false. ### StaticSearch~addSearchItem(strInput, isPhrasal) ⇒ boolean this is passed a single component from the search box parser by parseSearchQuery. It constructs a single item from it, and adds that to this.terms. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if terms found, otherwise false. | Param | Type | Description | | --- | --- | --- | | strInput | string | a string of text. | | isPhrasal | boolean | whether or not this is a phrasal search. This may be true even for a single word, if it is to be searched unstemmed. | ### StaticSearch~clearSearchForm() ⇒ boolean this function removes all previously-selected filter control settings, and empties the search query box. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true on success, false on failure. ### StaticSearch~processFilters() ⇒ boolean this function calls StaticSearch~getDocUrisForFilters(), and if the function succeeds, it sets the docsMatchingFilters to the returned XSet and returns true, otherwise it clears the current set of filters (THINK: IS THIS CORRECT BEHAVIOUR?) and returns false. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true on success, false on failure. ### StaticSearch~getDocUrisForFilters() ⇒ XSet this function gets the set of currently-configured filters by analyzing the form elements, then returns a set (in the form of an XSet object) of all the document ids that qualify according to the filters. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: XSet - an XSet object (which might be empty) with an added boolean property filtersActive which specifies whether filters have been configured by the user. ### StaticSearch~writeSearchReport() ⇒ boolean This outputs a human-readable explanation of the search that's being done, to clarify for users what they've chosen to look for. Note that the output div is hidden by default. NOTE: This does not yet include filter information. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if the process succeeds, otherwise false. ### StaticSearch~getTermsByType(termType) ⇒ Array.<number> This method returns an array of indexes in the StaticSearch.terms array, being the terms which match the supplied term type (PHRASE, MUST_CONTAIN etc.). **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: Array.<number> - An array of zero or more integers. | Param | Type | Description | | --- | --- | --- | | termType | number | One of PHRASE, MUST_CONTAIN, MUST_NOT_CONTAIN, MAY_CONTAIN. | ### StaticSearch~populateIndexes() The task of this function is basically to ensure that the various indexes (search terms and facet filters) are ready to handle a search, in that attempts have been made to retrieve all JSON files relating to the current search. The index is deemed ready when either a) all the JSON files for required stems and filters have been retrieved and their contents merged into the required structures, or b) a retrieval has failed, so an empty placeholder has been inserted to signify that there is no such dataset. The function works with fetch and promises, and its final .then() calls the processResults function. **Kind**: inner method of [StaticSearch](#StaticSearch) ### StaticSearch~stemFound(data) Before a request for a JSON file is initially made, an empty index is stored, indexed under the stem which is being searched, so that whether or not we successfully retrieve data, we won't have to try again in a subsequent search in the same session. Then, when a request for a JSON file for a specific stem results in a JSON file with data, we overwrite the data in the index, indexed under the stem. Sometimes the data coming in may be an instance of an empty index, if the retrieval code knows it got nothing. **Kind**: inner method of [StaticSearch](#StaticSearch) | Param | Type | Description | | --- | --- | --- | | data | Object | the data structure retrieved for the stem. | ### StaticSearch~clearResultsDiv() ⇒ boolean This clears out and sets up the results div, ready for reporting of results. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. ### StaticSearch~reportNoResults(trySimplerSearch) ⇒ boolean Reports that no results have been found. Also optionally configures and runs a simpler version of the current search, with phrases tokenized, etc. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. | Param | Type | Description | | --- | --- | --- | | trySimplerSearch | boolean | a flag to determine whether this search should be simplified and automatically run again. | ### StaticSearch~reportTooManyResults() ⇒ boolean Reports, both in the results and the console, that the number of results found exceed the configured limit (StaticSearch.resultsLimit) and cannot be displayed. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not ### StaticSearch~processResults() ⇒ boolean When we are satisfied that all relevant search data has been retrieved and added to the index, this function is called to process the search and show any results found. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if there are results to show; false if not. * [~processResults()](#StaticSearch..processResults) ⇒ boolean * [~processPhrases()](#StaticSearch..processResults..processPhrases) ⇒ * [~processMustNotContains()](#StaticSearch..processResults..processMustNotContains) ⇒ * [~processMustContains(indexes, runAsFilter)](#StaticSearch..processResults..processMustContains) ⇒ * [~processMayContains(addAllFound)](#StaticSearch..processResults..processMayContains) ⇒ #### processResults~processPhrases() ⇒ Embedded function to retrieve the results from phrasal searches. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. #### processResults~processMustNotContains() ⇒ Embedded function to remove from the result set all documents which contain terms which have been designated as excluded. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. #### processResults~processMustContains(indexes, runAsFilter) ⇒ Embedded function to retrieve all documents containing terms designated as required. This function works in two ways; if running after a phrasal search has been done, it simply acts as a filter on the document set already retrieved; if running as the initial retrieval mechanism (where there are no phrasal searches), it populates the result set itself. It's doubly complicated because it must also eliminate from the existing result set any document that doesn't contain a term. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. | Param | Type | Description | | --- | --- | --- | | indexes | Array.<number> | a list of indexes into the terms array. This needs to be a parameter because the function is calls itself recursively with a reduced array. | | runAsFilter | boolean | controls which mode the process runs in. | #### processResults~processMayContains(addAllFound) ⇒ Embedded function to process may_contain search terms. This function runs in two modes: if it's being called after prior imperative search terms have been processed, then it adds no new documents to the set, just enhances their scores. But if there are no imperative search terms, then all documents found are added to the set. **Kind**: inner method of [processResults](#StaticSearch..processResults) **Returns**: true if succeeds, false if not. | Param | Type | Description | | --- | --- | --- | | addAllFound | boolean | controls which mode the process runs in. | ### StaticSearch~paginateResults() ⇒ boolean This method adds pagination controls to the results and adds a number of properties to the StaticSearch object to handle pagination. It first checks whether or not it needs to add anything to the page, and, if it does, then adds the Show More / Show All buttons to the bottom of the results div and adds some functionality to the buttons. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if necessary; false if unnecessary ### StaticSearch~showAllResults() ⇒ boolean Method to show all of the results (i.e. removing the hidden item's class that instructs all of its siblings to hide) and hide the pagination widget. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. ### StaticSearch~showMoreResults() ⇒ boolean Method to show more results based off of the current page and the number of results to show. If we're on the last page, then the "Show More" is simply a proxy for showAll; otherwise, it shifts the hidden class from the last item to the next one in the sequence. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: boolean - true if successful, false if not. ### StaticSearch~phraseToRegex(str) ⇒ RegExp \| null This method takes a phrase and converts it into the regular expression that will be matched against contexts. This function first escapes all characters to prevent from unintentional regular expression, then expands all apostrophes (i.e. treating U+0027, U+2018, U+2019, U+201B as equivalent) and all quotation marks. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: RegExp \| null - a regular expression, or null if one can't be constructed | Param | Type | Description | | --- | --- | --- | | str | string | a string of text | ### StaticSearch~wildcardToRegex(strToken) ⇒ RegExp \| null This method is provided with a single token as input. The token should contain wildcard characters (asterisk, question mark and square brackets). The function converts this to a JS regular expression. For example: th*n[gk]? would become /^th.*[gk].$/. The regex is created with leading and trailing pipe characters, because the string of words against which it will be matched uses these as delimiters, and it has a capturing group for the content between the pipes. Because of the use of the pipe delimiter, a negative character class [^\\|] (i.e. 'not a pipe') is used in place of a dot. **Kind**: inner method of [StaticSearch](#StaticSearch) **Returns**: RegExp \| null - a regular expression; or null if one cannot be constructed. | Param | Type | Description | | --- | --- | --- | | strToken | string | a string of text with no spaces. |