emissions-api-sdk 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +135 -6
  2. package/dist/Constants.js +1 -1
  3. package/dist/api/Factor.js +53 -1
  4. package/dist/api/TypeRecommender.js +48 -0
  5. package/dist/coverage/clover.xml +17 -14
  6. package/dist/coverage/coverage-final.json +4 -4
  7. package/dist/coverage/lcov-report/index.html +7 -7
  8. package/dist/coverage/lcov-report/src/Client.ts.html +1 -1
  9. package/dist/coverage/lcov-report/src/Constants.ts.html +2 -2
  10. package/dist/coverage/lcov-report/src/api/Calculation.ts.html +1 -1
  11. package/dist/coverage/lcov-report/src/api/EconomicActivity.ts.html +1 -1
  12. package/dist/coverage/lcov-report/src/api/Factor.ts.html +159 -3
  13. package/dist/coverage/lcov-report/src/api/FactorSets.ts.html +1 -1
  14. package/dist/coverage/lcov-report/src/api/Fugitive.ts.html +1 -1
  15. package/dist/coverage/lcov-report/src/api/Location.ts.html +1 -1
  16. package/dist/coverage/lcov-report/src/api/Metadata.ts.html +1 -1
  17. package/dist/coverage/lcov-report/src/api/Mobile.ts.html +1 -1
  18. package/dist/coverage/lcov-report/src/api/RealEstate.ts.html +1 -1
  19. package/dist/coverage/lcov-report/src/api/Stationary.ts.html +1 -1
  20. package/dist/coverage/lcov-report/src/api/TransportationAndDistribution.ts.html +1 -1
  21. package/dist/coverage/lcov-report/src/api/TypeRecommender.ts.html +146 -2
  22. package/dist/coverage/lcov-report/src/api/Usage.ts.html +1 -1
  23. package/dist/coverage/lcov-report/src/api/index.html +1 -1
  24. package/dist/coverage/lcov-report/src/index.html +1 -1
  25. package/dist/coverage/lcov-report/src/request.ts.html +1 -1
  26. package/dist/coverage/lcov-report/src/utils.ts.html +1 -1
  27. package/dist/coverage/lcov-report/test/index.html +1 -1
  28. package/dist/coverage/lcov-report/test/mocks/CommonRequest.ts.html +1 -1
  29. package/dist/coverage/lcov-report/test/mocks/FactorRequest.ts.html +1 -1
  30. package/dist/coverage/lcov-report/test/mocks/GenericCalculationRequest.ts.html +1 -1
  31. package/dist/coverage/lcov-report/test/mocks/LocationRequest.ts.html +1 -1
  32. package/dist/coverage/lcov-report/test/mocks/SearchRequest.ts.html +148 -4
  33. package/dist/coverage/lcov-report/test/mocks/index.html +5 -5
  34. package/dist/coverage/lcov-report/test/testUtils.ts.html +1 -1
  35. package/dist/coverage/lcov.info +16 -13
  36. package/dist/types/Constants.d.ts +1 -1
  37. package/dist/types/api/Factor.d.ts +53 -1
  38. package/dist/types/api/TypeRecommender.d.ts +48 -0
  39. package/dist/types/interfaces/common.d.ts +8 -0
  40. package/docs/_static/base-stemmer.js +476 -0
  41. package/docs/_static/basic.css +0 -8
  42. package/docs/_static/doctools.js +6 -5
  43. package/docs/_static/english-stemmer.js +1066 -0
  44. package/docs/_static/language_data.js +7 -186
  45. package/docs/_static/pygments.css +164 -146
  46. package/docs/_static/searchtools.js +121 -60
  47. package/docs/_static/sphinx_highlight.js +36 -31
  48. package/docs/_static/styles/furo.css +1 -1
  49. package/docs/_static/styles/furo.css.map +1 -1
  50. package/docs/authentication.html +21 -30
  51. package/docs/client.html +21 -30
  52. package/docs/genindex.html +21 -30
  53. package/docs/getting_started.html +21 -30
  54. package/docs/index.html +21 -30
  55. package/docs/reference.html +63 -72
  56. package/docs/sdk.html +21 -30
  57. package/docs/search.html +21 -30
  58. package/docs/searchindex.js +1 -1
  59. package/docs/troubleshooting.html +21 -30
  60. package/package.json +1 -1
  61. package/src/Constants.ts +1 -1
  62. package/src/api/Factor.ts +53 -1
  63. package/src/api/TypeRecommender.ts +48 -0
  64. package/src/interfaces/common.ts +12 -0
  65. package/test/mocks/SearchRequest.ts +48 -0
@@ -41,11 +41,12 @@ if (typeof Scorer === "undefined") {
41
41
  }
42
42
 
43
43
  // Global search result kind enum, used by themes to style search results.
44
+ // prettier-ignore
44
45
  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"; }
46
+ static get index() { return "index"; }
47
+ static get object() { return "object"; }
48
+ static get text() { return "text"; }
49
+ static get title() { return "title"; }
49
50
  }
50
51
 
51
52
  const _removeChildren = (element) => {
@@ -58,6 +59,15 @@ const _removeChildren = (element) => {
58
59
  const _escapeRegExp = (string) =>
59
60
  string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
60
61
 
62
+ const _escapeHTML = (text) => {
63
+ return text
64
+ .replaceAll("&", "&")
65
+ .replaceAll("<", "&lt;")
66
+ .replaceAll(">", "&gt;")
67
+ .replaceAll('"', "&quot;")
68
+ .replaceAll("'", "&apos;");
69
+ };
70
+
61
71
  const _displayItem = (item, searchTerms, highlightTerms) => {
62
72
  const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
63
73
  const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
@@ -90,25 +100,30 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
90
100
  let linkEl = listItem.appendChild(document.createElement("a"));
91
101
  linkEl.href = linkUrl + anchor;
92
102
  linkEl.dataset.score = score;
93
- linkEl.innerHTML = title;
103
+ linkEl.innerHTML = _escapeHTML(title);
94
104
  if (descr) {
95
105
  listItem.appendChild(document.createElement("span")).innerHTML =
96
- " (" + descr + ")";
106
+ ` (${_escapeHTML(descr)})`;
97
107
  // highlight search terms in the description
98
- if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
99
- highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
100
- }
101
- else if (showSearchSummary)
108
+ if (SPHINX_HIGHLIGHT_ENABLED)
109
+ // SPHINX_HIGHLIGHT_ENABLED is set in sphinx_highlight.js
110
+ highlightTerms.forEach((term) =>
111
+ _highlightText(listItem, term, "highlighted"),
112
+ );
113
+ } else if (showSearchSummary)
102
114
  fetch(requestUrl)
103
115
  .then((responseData) => responseData.text())
104
116
  .then((data) => {
105
117
  if (data)
106
118
  listItem.appendChild(
107
- Search.makeSearchSummary(data, searchTerms, anchor)
119
+ Search.makeSearchSummary(data, searchTerms, anchor),
108
120
  );
109
121
  // highlight search terms in the summary
110
- if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
111
- highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
122
+ if (SPHINX_HIGHLIGHT_ENABLED)
123
+ // SPHINX_HIGHLIGHT_ENABLED is set in sphinx_highlight.js
124
+ highlightTerms.forEach((term) =>
125
+ _highlightText(listItem, term, "highlighted"),
126
+ );
112
127
  });
113
128
  Search.output.appendChild(listItem);
114
129
  };
@@ -117,14 +132,14 @@ const _finishSearch = (resultCount) => {
117
132
  Search.title.innerText = _("Search Results");
118
133
  if (!resultCount)
119
134
  Search.status.innerText = Documentation.gettext(
120
- "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
135
+ "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.",
121
136
  );
122
137
  else
123
138
  Search.status.innerText = Documentation.ngettext(
124
139
  "Search finished, found one page matching the search query.",
125
140
  "Search finished, found ${resultCount} pages matching the search query.",
126
141
  resultCount,
127
- ).replace('${resultCount}', resultCount);
142
+ ).replace("${resultCount}", resultCount);
128
143
  };
129
144
  const _displayNextItem = (
130
145
  results,
@@ -138,7 +153,7 @@ const _displayNextItem = (
138
153
  _displayItem(results.pop(), searchTerms, highlightTerms);
139
154
  setTimeout(
140
155
  () => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
141
- 5
156
+ 5,
142
157
  );
143
158
  }
144
159
  // search finished, update title and status message
@@ -170,9 +185,10 @@ const _orderResultsByScoreThenName = (a, b) => {
170
185
  * This is the same as ``\W+`` in Python, preserving the surrogate pair area.
171
186
  */
172
187
  if (typeof splitQuery === "undefined") {
173
- var splitQuery = (query) => query
188
+ var splitQuery = (query) =>
189
+ query
174
190
  .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
175
- .filter(term => term) // remove remaining empty strings
191
+ .filter((term) => term); // remove remaining empty strings
176
192
  }
177
193
 
178
194
  /**
@@ -184,16 +200,23 @@ const Search = {
184
200
  _pulse_status: -1,
185
201
 
186
202
  htmlToText: (htmlString, anchor) => {
187
- const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
203
+ const htmlElement = new DOMParser().parseFromString(
204
+ htmlString,
205
+ "text/html",
206
+ );
188
207
  for (const removalQuery of [".headerlink", "script", "style"]) {
189
- htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() });
208
+ htmlElement.querySelectorAll(removalQuery).forEach((el) => {
209
+ el.remove();
210
+ });
190
211
  }
191
212
  if (anchor) {
192
- const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`);
213
+ const anchorContent = htmlElement.querySelector(
214
+ `[role="main"] ${anchor}`,
215
+ );
193
216
  if (anchorContent) return anchorContent.textContent;
194
217
 
195
218
  console.warn(
196
- `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.`
219
+ `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.`,
197
220
  );
198
221
  }
199
222
 
@@ -202,7 +225,7 @@ const Search = {
202
225
  if (docContent) return docContent.textContent;
203
226
 
204
227
  console.warn(
205
- "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template."
228
+ "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template.",
206
229
  );
207
230
  return "";
208
231
  },
@@ -287,12 +310,8 @@ const Search = {
287
310
  const queryTermLower = queryTerm.toLowerCase();
288
311
 
289
312
  // maybe skip this "word"
290
- // stopwords array is from language_data.js
291
- if (
292
- stopwords.indexOf(queryTermLower) !== -1 ||
293
- queryTerm.match(/^\d+$/)
294
- )
295
- return;
313
+ // stopwords set is from language_data.js
314
+ if (stopwords.has(queryTermLower) || queryTerm.match(/^\d+$/)) return;
296
315
 
297
316
  // stem the word
298
317
  let word = stemmer.stemWord(queryTermLower);
@@ -304,8 +323,12 @@ const Search = {
304
323
  }
305
324
  });
306
325
 
307
- if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
308
- localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
326
+ if (SPHINX_HIGHLIGHT_ENABLED) {
327
+ // SPHINX_HIGHLIGHT_ENABLED is set in sphinx_highlight.js
328
+ localStorage.setItem(
329
+ "sphinx_highlight_terms",
330
+ [...highlightTerms].join(" "),
331
+ );
309
332
  }
310
333
 
311
334
  // console.debug("SEARCH: searching for:");
@@ -318,7 +341,13 @@ const Search = {
318
341
  /**
319
342
  * execute search (requires search index to be loaded)
320
343
  */
321
- _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => {
344
+ _performSearch: (
345
+ query,
346
+ searchTerms,
347
+ excludedTerms,
348
+ highlightTerms,
349
+ objectTerms,
350
+ ) => {
322
351
  const filenames = Search._index.filenames;
323
352
  const docNames = Search._index.docnames;
324
353
  const titles = Search._index.titles;
@@ -334,10 +363,15 @@ const Search = {
334
363
 
335
364
  const queryLower = query.toLowerCase().trim();
336
365
  for (const [title, foundTitles] of Object.entries(allTitles)) {
337
- if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) {
366
+ if (
367
+ title.toLowerCase().trim().includes(queryLower)
368
+ && queryLower.length >= title.length / 2
369
+ ) {
338
370
  for (const [file, id] of foundTitles) {
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
371
+ const score = Math.round(
372
+ (Scorer.title * queryLower.length) / title.length,
373
+ );
374
+ const boost = titles[file] === title ? 1 : 0; // add a boost for document titles
341
375
  normalResults.push([
342
376
  docNames[file],
343
377
  titles[file] !== title ? `${titles[file]} > ${title}` : title,
@@ -353,9 +387,9 @@ const Search = {
353
387
 
354
388
  // search for explicit entries in index directives
355
389
  for (const [entry, foundEntries] of Object.entries(indexEntries)) {
356
- if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
390
+ if (entry.includes(queryLower) && queryLower.length >= entry.length / 2) {
357
391
  for (const [file, id, isMain] of foundEntries) {
358
- const score = Math.round(100 * queryLower.length / entry.length);
392
+ const score = Math.round((100 * queryLower.length) / entry.length);
359
393
  const result = [
360
394
  docNames[file],
361
395
  titles[file],
@@ -376,11 +410,13 @@ const Search = {
376
410
 
377
411
  // lookup as object
378
412
  objectTerms.forEach((term) =>
379
- normalResults.push(...Search.performObjectSearch(term, objectTerms))
413
+ normalResults.push(...Search.performObjectSearch(term, objectTerms)),
380
414
  );
381
415
 
382
416
  // lookup as search terms in fulltext
383
- normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms));
417
+ normalResults.push(
418
+ ...Search.performTermsSearch(searchTerms, excludedTerms),
419
+ );
384
420
 
385
421
  // let the scorer override scores with a custom scoring function
386
422
  if (Scorer.score) {
@@ -401,7 +437,11 @@ const Search = {
401
437
  // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
402
438
  let seen = new Set();
403
439
  results = results.reverse().reduce((acc, result) => {
404
- let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
440
+ let resultStr = result
441
+ .slice(0, 4)
442
+ .concat([result[5]])
443
+ .map((v) => String(v))
444
+ .join(",");
405
445
  if (!seen.has(resultStr)) {
406
446
  acc.push(result);
407
447
  seen.add(resultStr);
@@ -413,8 +453,20 @@ const Search = {
413
453
  },
414
454
 
415
455
  query: (query) => {
416
- const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query);
417
- const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms);
456
+ const [
457
+ searchQuery,
458
+ searchTerms,
459
+ excludedTerms,
460
+ highlightTerms,
461
+ objectTerms,
462
+ ] = Search._parseQuery(query);
463
+ const results = Search._performSearch(
464
+ searchQuery,
465
+ searchTerms,
466
+ excludedTerms,
467
+ highlightTerms,
468
+ objectTerms,
469
+ );
418
470
 
419
471
  // for debugging
420
472
  //Search.lastresults = results.slice(); // a copy
@@ -437,7 +489,7 @@ const Search = {
437
489
  const results = [];
438
490
 
439
491
  const objectSearchCallback = (prefix, match) => {
440
- const name = match[4]
492
+ const name = match[4];
441
493
  const fullname = (prefix ? prefix + "." : "") + name;
442
494
  const fullnameLower = fullname.toLowerCase();
443
495
  if (fullnameLower.indexOf(object) < 0) return;
@@ -489,9 +541,7 @@ const Search = {
489
541
  ]);
490
542
  };
491
543
  Object.keys(objects).forEach((prefix) =>
492
- objects[prefix].forEach((array) =>
493
- objectSearchCallback(prefix, array)
494
- )
544
+ objects[prefix].forEach((array) => objectSearchCallback(prefix, array)),
495
545
  );
496
546
  return results;
497
547
  },
@@ -513,9 +563,17 @@ const Search = {
513
563
  // perform the search on the required terms
514
564
  searchTerms.forEach((word) => {
515
565
  const files = [];
566
+ // find documents, if any, containing the query word in their text/title term indices
567
+ // use Object.hasOwnProperty to avoid mismatching against prototype properties
516
568
  const arr = [
517
- { files: terms[word], score: Scorer.term },
518
- { files: titleTerms[word], score: Scorer.title },
569
+ {
570
+ files: terms.hasOwnProperty(word) ? terms[word] : undefined,
571
+ score: Scorer.term,
572
+ },
573
+ {
574
+ files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined,
575
+ score: Scorer.title,
576
+ },
519
577
  ];
520
578
  // add support for partial matches
521
579
  if (word.length > 2) {
@@ -547,15 +605,17 @@ const Search = {
547
605
 
548
606
  // set score for the word in each file
549
607
  recordFiles.forEach((file) => {
550
- if (!scoreMap.has(file)) scoreMap.set(file, {});
551
- scoreMap.get(file)[word] = record.score;
608
+ if (!scoreMap.has(file)) scoreMap.set(file, new Map());
609
+ const fileScores = scoreMap.get(file);
610
+ fileScores.set(word, record.score);
552
611
  });
553
612
  });
554
613
 
555
614
  // create the mapping
556
615
  files.forEach((file) => {
557
616
  if (!fileMap.has(file)) fileMap.set(file, [word]);
558
- else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word);
617
+ else if (fileMap.get(file).indexOf(word) === -1)
618
+ fileMap.get(file).push(word);
559
619
  });
560
620
  });
561
621
 
@@ -566,11 +626,11 @@ const Search = {
566
626
 
567
627
  // as search terms with length < 3 are discarded
568
628
  const filteredTermCount = [...searchTerms].filter(
569
- (term) => term.length > 2
629
+ (term) => term.length > 2,
570
630
  ).length;
571
631
  if (
572
- wordList.length !== searchTerms.size &&
573
- wordList.length !== filteredTermCount
632
+ wordList.length !== searchTerms.size
633
+ && wordList.length !== filteredTermCount
574
634
  )
575
635
  continue;
576
636
 
@@ -578,16 +638,16 @@ const Search = {
578
638
  if (
579
639
  [...excludedTerms].some(
580
640
  (term) =>
581
- terms[term] === file ||
582
- titleTerms[term] === file ||
583
- (terms[term] || []).includes(file) ||
584
- (titleTerms[term] || []).includes(file)
641
+ terms[term] === file
642
+ || titleTerms[term] === file
643
+ || (terms[term] || []).includes(file)
644
+ || (titleTerms[term] || []).includes(file),
585
645
  )
586
646
  )
587
647
  break;
588
648
 
589
649
  // select one (max) score for the file.
590
- const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
650
+ const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w)));
591
651
  // add result to the result list
592
652
  results.push([
593
653
  docNames[file],
@@ -623,7 +683,8 @@ const Search = {
623
683
 
624
684
  let summary = document.createElement("p");
625
685
  summary.classList.add("context");
626
- summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
686
+ summary.textContent =
687
+ top + text.substr(startWithContext, 240).trim() + tail;
627
688
 
628
689
  return summary;
629
690
  },
@@ -1,7 +1,7 @@
1
1
  /* Highlighting utilities for Sphinx HTML documentation. */
2
2
  "use strict";
3
3
 
4
- const SPHINX_HIGHLIGHT_ENABLED = true
4
+ const SPHINX_HIGHLIGHT_ENABLED = true;
5
5
 
6
6
  /**
7
7
  * highlight a given string on a node by wrapping it in
@@ -13,9 +13,9 @@ const _highlight = (node, addItems, text, className) => {
13
13
  const parent = node.parentNode;
14
14
  const pos = val.toLowerCase().indexOf(text);
15
15
  if (
16
- pos >= 0 &&
17
- !parent.classList.contains(className) &&
18
- !parent.classList.contains("nohighlight")
16
+ pos >= 0
17
+ && !parent.classList.contains(className)
18
+ && !parent.classList.contains("nohighlight")
19
19
  ) {
20
20
  let span;
21
21
 
@@ -30,13 +30,7 @@ const _highlight = (node, addItems, text, className) => {
30
30
 
31
31
  span.appendChild(document.createTextNode(val.substr(pos, text.length)));
32
32
  const rest = document.createTextNode(val.substr(pos + text.length));
33
- parent.insertBefore(
34
- span,
35
- parent.insertBefore(
36
- rest,
37
- node.nextSibling
38
- )
39
- );
33
+ parent.insertBefore(span, parent.insertBefore(rest, node.nextSibling));
40
34
  node.nodeValue = val.substr(0, pos);
41
35
  /* There may be more occurrences of search term in this node. So call this
42
36
  * function recursively on the remaining fragment.
@@ -46,7 +40,7 @@ const _highlight = (node, addItems, text, className) => {
46
40
  if (isInSVG) {
47
41
  const rect = document.createElementNS(
48
42
  "http://www.w3.org/2000/svg",
49
- "rect"
43
+ "rect",
50
44
  );
51
45
  const bbox = parent.getBBox();
52
46
  rect.x.baseVal.value = bbox.x;
@@ -65,7 +59,7 @@ const _highlightText = (thisNode, text, className) => {
65
59
  let addItems = [];
66
60
  _highlight(thisNode, addItems, text, className);
67
61
  addItems.forEach((obj) =>
68
- obj.parent.insertAdjacentElement("beforebegin", obj.target)
62
+ obj.parent.insertAdjacentElement("beforebegin", obj.target),
69
63
  );
70
64
  };
71
65
 
@@ -73,25 +67,31 @@ const _highlightText = (thisNode, text, className) => {
73
67
  * Small JavaScript module for the documentation.
74
68
  */
75
69
  const SphinxHighlight = {
76
-
77
70
  /**
78
71
  * highlight the search words provided in localstorage in the text
79
72
  */
80
73
  highlightSearchWords: () => {
81
- if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
74
+ if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
82
75
 
83
76
  // get and clear terms from localstorage
84
77
  const url = new URL(window.location);
85
78
  const highlight =
86
- localStorage.getItem("sphinx_highlight_terms")
87
- || url.searchParams.get("highlight")
88
- || "";
89
- localStorage.removeItem("sphinx_highlight_terms")
90
- url.searchParams.delete("highlight");
91
- window.history.replaceState({}, "", url);
79
+ localStorage.getItem("sphinx_highlight_terms")
80
+ || url.searchParams.get("highlight")
81
+ || "";
82
+ localStorage.removeItem("sphinx_highlight_terms");
83
+ // Update history only if '?highlight' is present; otherwise it
84
+ // clears text fragments (not set in window.location by the browser)
85
+ if (url.searchParams.has("highlight")) {
86
+ url.searchParams.delete("highlight");
87
+ window.history.replaceState({}, "", url);
88
+ }
92
89
 
93
90
  // get individual terms from highlight string
94
- const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
91
+ const terms = highlight
92
+ .toLowerCase()
93
+ .split(/\s+/)
94
+ .filter((x) => x);
95
95
  if (terms.length === 0) return; // nothing to do
96
96
 
97
97
  // There should never be more than one element matching "div.body"
@@ -107,11 +107,11 @@ const SphinxHighlight = {
107
107
  document
108
108
  .createRange()
109
109
  .createContextualFragment(
110
- '<p class="highlight-link">' +
111
- '<a href="javascript:SphinxHighlight.hideSearchWords()">' +
112
- _("Hide Search Matches") +
113
- "</a></p>"
114
- )
110
+ '<p class="highlight-link">'
111
+ + '<a href="javascript:SphinxHighlight.hideSearchWords()">'
112
+ + _("Hide Search Matches")
113
+ + "</a></p>",
114
+ ),
115
115
  );
116
116
  },
117
117
 
@@ -125,7 +125,7 @@ const SphinxHighlight = {
125
125
  document
126
126
  .querySelectorAll("span.highlighted")
127
127
  .forEach((el) => el.classList.remove("highlighted"));
128
- localStorage.removeItem("sphinx_highlight_terms")
128
+ localStorage.removeItem("sphinx_highlight_terms");
129
129
  },
130
130
 
131
131
  initEscapeListener: () => {
@@ -134,10 +134,15 @@ const SphinxHighlight = {
134
134
 
135
135
  document.addEventListener("keydown", (event) => {
136
136
  // bail for input elements
137
- if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
137
+ if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName))
138
+ return;
138
139
  // bail with special keys
139
- if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
140
- if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
140
+ if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
141
+ return;
142
+ if (
143
+ DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
144
+ && event.key === "Escape"
145
+ ) {
141
146
  SphinxHighlight.hideSearchWords();
142
147
  event.preventDefault();
143
148
  }