Alters Find in Article to escape regex characters by default

This commit is contained in:
Brian Sanders 2020-05-13 05:29:09 -04:00
parent 737f4bfdf5
commit 98e0434077
2 changed files with 26 additions and 26 deletions

View File

@ -684,6 +684,7 @@ private extension WebViewController {
private struct FindInArticleOptions: Codable { private struct FindInArticleOptions: Codable {
var text: String var text: String
var caseSensitive = false var caseSensitive = false
var regex = false
} }

View File

@ -161,8 +161,9 @@ function makeHighlightRect({left, top, width, height}, offsetTop=0, offsetLeft=0
return overlay; return overlay;
} }
function clearHighlightRects(container=document.getElementById('nnw:highlightContainer')) { function clearHighlightRects() {
while (container.firstChild) container.firstChild.remove(); let container = document.getElementById('nnw:highlightContainer')
if (container) container.remove();
} }
function highlightRects(rects, clearOldRects=true, makeHighlightRect=makeHighlightRect) { function highlightRects(rects, clearOldRects=true, makeHighlightRect=makeHighlightRect) {
@ -171,14 +172,12 @@ function highlightRects(rects, clearOldRects=true, makeHighlightRect=makeHighlig
article.style.position = 'relative'; article.style.position = 'relative';
if (container) { if (container && clearOldRects)
if (clearOldRects) container.remove();
clearHighlightRects(container);
} else {
container = document.createElement('div'); container = document.createElement('div');
container.id = 'nnw:highlightContainer'; container.id = 'nnw:highlightContainer';
article.appendChild(container); article.appendChild(container);
}
const {top, left} = article.getBoundingClientRect(); const {top, left} = article.getBoundingClientRect();
return Array.from(rects, rect => return Array.from(rects, rect =>
@ -369,20 +368,6 @@ function scrollToRect({top, height}, node, pad=0) {
scrollParent(node).scrollBy({ top: scrollBy }); scrollParent(node).scrollBy({ top: scrollBy });
} }
function findNext() {
const result = f.next();
const bounds = textBounds(f.node, f.offset, f.offsetEnd);
highlightRects(bounds)
}
function getFinderCount(finder) {
let count = 0;
while (finder.next())
++count;
finder.reset();
return count;
}
function withEncodedArg(fn) { function withEncodedArg(fn) {
return function(encodedData, ...rest) { return function(encodedData, ...rest) {
const data = encodedData && JSON.parse(atob(encodedData)); const data = encodedData && JSON.parse(atob(encodedData));
@ -390,9 +375,17 @@ function withEncodedArg(fn) {
} }
} }
function escapeRegex(s) {
return s.replace(/[.?*+^$\\()[\]{}]/g, '\\$&');
}
class FindState { class FindState {
constructor(options) { constructor(options) {
const { text, caseSensitive } = options; let { text, caseSensitive, regex } = options;
if (!regex)
text = escapeRegex(text);
const finder = new Finder(new RegExp(text, caseSensitive ? 'g' : 'ig')); const finder = new Finder(new RegExp(text, caseSensitive ? 'g' : 'ig'));
this.results = Array.from(finder); this.results = Array.from(finder);
this.index = -1; this.index = -1;
@ -429,7 +422,13 @@ const ExcludeKeys = new Set(['top', 'right', 'bottom', 'left']);
updateFind = withEncodedArg(options => { updateFind = withEncodedArg(options => {
// TODO Start at the current result position // TODO Start at the current result position
// TODO Introduce slight delay, cap the number of results, and report results asynchronously // TODO Introduce slight delay, cap the number of results, and report results asynchronously
try {
CurrentFindState = new FindState(options); CurrentFindState = new FindState(options);
} catch (err) {
clearHighlightRects();
throw err;
}
CurrentFindState.selectNext() || clearHighlightRects(); CurrentFindState.selectNext() || clearHighlightRects();
return btoa(JSON.stringify(CurrentFindState, (k, v) => (ExcludeKeys.has(k) ? undefined : v))); return btoa(JSON.stringify(CurrentFindState, (k, v) => (ExcludeKeys.has(k) ? undefined : v)));
}); });