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 +4 -4
- data/_sass/_nav.scss +9 -1
- data/assets/html/remark_presentation_frame.html +1 -0
- data/assets/js/EscapeHelper.mjs +37 -0
- data/assets/js/layout/post.mjs +6 -5
- data/assets/js/search.mjs +24 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7d0e540229aa59560164e505b1f9c56bfc06410483f121f0f37de4b35f14648
|
4
|
+
data.tar.gz: e134ec448a27e0e1ab0b6c6fb058a71248d9a59c182956a6b873834c150eb120
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 {
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
import { assertEq } from "./assertions.mjs";
|
3
|
+
|
4
|
+
let htmlReplacements = [
|
5
|
+
[ /[&]/g, '&' ],
|
6
|
+
[ /[<]/g, '<' ],
|
7
|
+
[ /[>]/g, '>' ],
|
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('<'), '<');
|
30
|
+
assertEq("Test escape multiple <", EscapeHelper.escapeHTML('<a></a>'), '<a></a>');
|
31
|
+
assertEq("Test escape >", EscapeHelper.escapeHTML('>'), '>');
|
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;
|
data/assets/js/layout/post.mjs
CHANGED
@@ -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
|
311
|
-
|
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
|
-
|
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.
|
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-
|
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
|