hematite 0.1.13 → 0.1.14

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5428a81a66f2c162d5db506a782443ab49ec31a2a2b67a02dec1cab941828768
4
- data.tar.gz: 4a54bb491b61987364791315c6b4024b6fc019a3ba42f5488f43fb7f9c9ff704
3
+ metadata.gz: e7d0e540229aa59560164e505b1f9c56bfc06410483f121f0f37de4b35f14648
4
+ data.tar.gz: e134ec448a27e0e1ab0b6c6fb058a71248d9a59c182956a6b873834c150eb120
5
5
  SHA512:
6
- metadata.gz: '08188e55d1fc0e2f342a186ac1cc57c0226fe7b138cdb5e2f622716b29f4a5cf41768220f9dafb3971d2081dfef5cbee1cb8f485cd6e041589b6a3472a63204f'
7
- data.tar.gz: 1ddbfb8aa3b14052e0befc9e5dc6b59f1486705dc5f82033337a08a085368e27b6b1a51601db7e26b9578af0fafe74c0b3951a0e3fcda496ff5de23b35ad4b88
6
+ metadata.gz: f0629528aa7d95d26b68b488a2b5110625471856310273f74db557a8b543db35ccb072af00ffed6195d61e7eef1ed50ac755f55b034fe4c6fa41c22c7e0d35df
7
+ data.tar.gz: 31c8354bfa13a6ce9fb8531835c367214a6419d20ddb5246092271f2caf81fded7e0aba03db2e52e0166b40500d1bb2a4b0f4d31856feb94375c840f095b4f79
data/_sass/_nav.scss CHANGED
@@ -124,7 +124,6 @@ nav.sidebar {
124
124
  transform: scale(0, 1) translate(-30px, 0);
125
125
 
126
126
  color: var(--primary-text-color);
127
- background-color: var(--primary-background-color);
128
127
  box-shadow: 0 0 2px var(--shadow-color-light);
129
128
  padding: $navbar-padding;
130
129
 
@@ -138,6 +137,15 @@ nav.sidebar {
138
137
  transform-origin: left;
139
138
  transition: opacity 0.5s ease, transform 0.5s ease, width 0.5s ease;
140
139
 
140
+ // Work around a rendering bug in Safari — apply the background color to both
141
+ // the results pane and the container.
142
+ //
143
+ // Without this, Safari may display elements of pinned-pages in the same
144
+ // location as the search results.
145
+ &, .search-results {
146
+ background-color: var(--primary-background-color);
147
+ }
148
+
141
149
 
142
150
  // Container with search box and button
143
151
  > .search-container {
@@ -25,6 +25,7 @@ h1, h2, h3 {
25
25
  }
26
26
 
27
27
  body.mdSourceView {
28
+ padding-top: 50px;
28
29
  background: white;
29
30
  color: black;
30
31
  }
@@ -0,0 +1,37 @@
1
+
2
+ import { assertEq } from "./assertions.mjs";
3
+
4
+ let htmlReplacements = [
5
+ [ /[&]/g, '&' ],
6
+ [ /[<]/g, '&lt;' ],
7
+ [ /[>]/g, '&gt;' ],
8
+ ];
9
+
10
+ var EscapeHelper = {
11
+ escapeHTML(text) {
12
+ for (const item of htmlReplacements) {
13
+ text = text.replace(item[0], item[1]);
14
+ }
15
+
16
+ return text;
17
+ },
18
+ // Escape for usage within a regex expression
19
+ escapeRegex(text) {
20
+ return text.replace(/([\*\(\).\[\]\{\}\^\$\-\=\;\:\'\"\\])/g, '\\$1'); //'
21
+ },
22
+ // Escape text for usage within a replacement pattern
23
+ // E.g. "foobar".replaceAll("foo", text);
24
+ escapeReplacePattern(text) {
25
+ return text.replace(/\$/g, '$$$$');
26
+ }
27
+ };
28
+
29
+ assertEq("Test escape <", EscapeHelper.escapeHTML('<'), '&lt;');
30
+ assertEq("Test escape multiple <", EscapeHelper.escapeHTML('<a></a>'), '&lt;a&gt;&lt;/a&gt;');
31
+ assertEq("Test escape >", EscapeHelper.escapeHTML('>'), '&gt;');
32
+ assertEq("Test escape identity", EscapeHelper.escapeHTML('Hello, world.'), 'Hello, world.');
33
+ assertEq("Test regex escape simple", EscapeHelper.escapeRegex(".*"), "\\.\\*");
34
+ assertEq("Test regex more complicated escape", EscapeHelper.escapeRegex("This, is a test... :)"), "This, is a test\\.\\.\\. \\:\\)");
35
+ assertEq("Test replace pattern escape", EscapeHelper.escapeReplacePattern("0$ and 24 cents"), "0$$ and 24 cents");
36
+
37
+ export default EscapeHelper;
@@ -37,6 +37,12 @@ function createTagLinks(page) {
37
37
  let label = document.querySelector("#post_tags > #tag_header_lbl");
38
38
  label.innerText = stringLookup(`tags`);
39
39
 
40
+ // Don't show the tag container if there aren't any tags
41
+ if (!page.tags || page.tags.length == 0) {
42
+ container.style.display = "none";
43
+ return;
44
+ }
45
+
40
46
  for (const tag of page.tags) {
41
47
  let tagElem = document.createElement("a");
42
48
  tagElem.style.display = "inline-block";
@@ -47,11 +53,6 @@ function createTagLinks(page) {
47
53
 
48
54
  container.appendChild(tagElem);
49
55
  }
50
-
51
- // Don't show the tag container if there aren't any tags
52
- if (page.tags.length == 0) {
53
- container.style.display = "none";
54
- }
55
56
  }
56
57
 
57
58
  function fillDate(page) {
data/assets/js/search.mjs CHANGED
@@ -7,6 +7,7 @@ import { expandContainingDropdowns } from "./dropdownExpander.mjs";
7
7
  import AnimationUtil from "./AnimationUtil.mjs";
8
8
  import AsyncUtil from "./AsyncUtil.mjs";
9
9
  import UrlHelper from "./UrlHelper.mjs";
10
+ import EscapeHelper from "./EscapeHelper.mjs";
10
11
 
11
12
  const PAGE_DATA_URL = `{{ "/assets/search_data.json" | relative_url }}`;
12
13
  const MATCHING_TITLE_PRIORITY_INCREMENT = 15;
@@ -177,6 +178,7 @@ class Searcher {
177
178
  results.push({
178
179
  index,
179
180
  context,
181
+ matchIndex: matchLoc,
180
182
  pageData,
181
183
  });
182
184
 
@@ -305,17 +307,35 @@ function handleSearch(searcher) {
305
307
 
306
308
  searchResults.replaceChildren(descriptionElem);
307
309
 
310
+ // Adds HTML to bold/italicize all results in [context].
311
+ // [context] is HTML-escaped before adding to the result.
312
+ const boldResults = (context) => {
313
+ let result = "";
314
+ let queryRegex = new RegExp(`(${EscapeHelper.escapeRegex(query)})`, `ig`);
315
+ let contextHTML = "";
316
+ let lastIdx = 0;
317
+ for (const match of context.matchAll(queryRegex)) {
318
+ result += EscapeHelper.escapeHTML(context.substring(lastIdx, match.index));
319
+ result += "<b><i>" + EscapeHelper.escapeHTML(match[0]) + "</i></b>";
320
+ lastIdx = match.index + match[0].length;
321
+ }
322
+ result += EscapeHelper.escapeHTML(context.substring(lastIdx));
323
+
324
+ return result;
325
+ };
326
+
308
327
  for (const result of results) {
309
328
  let link = document.createElement("a");
310
- let context = document.createElement("div");
311
- context.classList.add('context');
329
+ let contextElem = document.createElement("div");
330
+ contextElem.classList.add('context');
312
331
 
313
332
  link.innerText = result.pageData.title ?? stringLookup(`untitled`);
314
333
  link.href =
315
334
  result.pageData.url + `?query=${escape(query)},index=${result.index}`;
316
- context.innerText = result.context;
317
335
 
318
- link.appendChild(context);
336
+ contextElem.innerHTML = boldResults(result.context);
337
+
338
+ link.appendChild(contextElem);
319
339
  searchResults.appendChild(link);
320
340
  }
321
341
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hematite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henry Heino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-29 00:00:00.000000000 Z
11
+ date: 2022-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -75,6 +75,7 @@ files:
75
75
  - assets/js/AnimationUtil.mjs
76
76
  - assets/js/AsyncUtil.mjs
77
77
  - assets/js/DateUtil.mjs
78
+ - assets/js/EscapeHelper.mjs
78
79
  - assets/js/PageAlert.mjs
79
80
  - assets/js/Settings.mjs
80
81
  - assets/js/UrlHelper.mjs