/
search.js
141 lines (119 loc) · 3.86 KB
/
search.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
(function () {
const SEARCH_ID = 'search';
const ENABLE_SEARCH_ID = 'enable_search';
const REGEX_MODE_ID = 'regex_mode';
const COUNT_ID = 'count';
const LIST_ID = 'list';
let list = null;
let filteredList = null;
const logPerformance = (work, startTime, endTime) => {
const duration = (endTime - startTime).toFixed(2);
console.log(`${work} took ${duration} ms`);
};
const getSearchEl = () => document.getElementById(SEARCH_ID);
const getEnableSearchEl = () => document.getElementById(ENABLE_SEARCH_ID);
const getRegexModeEl = () => document.getElementById(REGEX_MODE_ID);
const getCountEl = () => document.getElementById(COUNT_ID);
const getListEl = () => document.getElementById(LIST_ID);
const disableSearchEl = placeholder => {
getSearchEl().disabled = true;
getSearchEl().placeholder = placeholder;
};
const enableSearchEl = () => {
getSearchEl().disabled = false;
getSearchEl().placeholder =
'Case-insensitive search by title, content, or publish date';
};
const disableRegexModeEl = () => {
getRegexModeEl().disabled = true;
};
const enableRegexModeEl = () => {
getRegexModeEl().disabled = false;
};
const fetchJsonIndex = () => {
const startTime = performance.now();
disableSearchEl('Loading ...');
const url = `${window.location.origin}/index.json`;
fetch(url)
.then(response => response.json())
.then(data => {
list = data.blog;
filteredList = data.blog;
enableSearchEl();
logPerformance('fetchJsonIndex', startTime, performance.now());
})
.catch(error =>
console.error(`Failed to fetch JSON index: ${error.message}`)
);
};
const filterList = regexMode => {
const regexQuery = new RegExp(getSearchEl().value, 'i');
const query = getSearchEl().value.toUpperCase();
filteredList = list.filter(item => {
const title = item.Title.toUpperCase();
const content = item.PlainContent.toUpperCase();
const publishDate = item.PublishDateFormatted.toUpperCase();
if (regexMode) {
return (
regexQuery.test(title) ||
regexQuery.test(content) ||
regexQuery.test(publishDate)
);
} else {
return (
title.includes(query) ||
content.includes(query) ||
publishDate.includes(query)
);
}
});
};
const renderCount = () => {
const count = `Count: ${filteredList.length}`;
getCountEl().textContent = count;
};
const renderList = () => {
const newList = document.createElement('ul');
newList.id = LIST_ID;
filteredList.forEach(item => {
const li = document.createElement('li');
const publishDate = document.createElement('span');
publishDate.textContent = item.PublishDateFormatted;
const titleLink = document.createElement('a');
titleLink.href = item.RelPermalink;
titleLink.textContent = item.Title;
li.appendChild(publishDate);
li.appendChild(document.createTextNode(' '));
li.appendChild(titleLink);
newList.appendChild(li);
});
const oldList = getListEl();
oldList.replaceWith(newList);
};
const handleSearchEvent = () => {
const regexMode = getRegexModeEl().checked;
filterList(regexMode);
renderCount();
renderList();
};
const handleEnableSearchEvent = () => {
if (getEnableSearchEl().checked) {
fetchJsonIndex();
enableRegexModeEl();
} else {
disableSearchEl('Disabled ...');
disableRegexModeEl();
}
};
const addEventListeners = () => {
getEnableSearchEl().addEventListener('change', handleEnableSearchEvent);
getSearchEl().addEventListener('keyup', handleSearchEvent);
getRegexModeEl().addEventListener('change', handleSearchEvent);
};
const main = () => {
if (getSearchEl()) {
addEventListeners();
}
};
main();
})();