Convert all "private" methods in PDFFindController into proper ones

Given that none of these methods are/were ever intended to be called manually, we can now enforce this with modern class-features.
This commit is contained in:
Jonas Jenwald 2022-03-19 12:26:03 +01:00
parent cc1bca6268
commit 61a52e8043

View File

@ -260,7 +260,7 @@ class PDFFindController {
this._linkService = linkService; this._linkService = linkService;
this._eventBus = eventBus; this._eventBus = eventBus;
this._reset(); this.#reset();
eventBus._on("find", this.#onFind.bind(this)); eventBus._on("find", this.#onFind.bind(this));
eventBus._on("findbarclose", this.#onFindBarClose.bind(this)); eventBus._on("findbarclose", this.#onFindBarClose.bind(this));
} }
@ -293,7 +293,7 @@ class PDFFindController {
*/ */
setDocument(pdfDocument) { setDocument(pdfDocument) {
if (this._pdfDocument) { if (this._pdfDocument) {
this._reset(); this.#reset();
} }
if (!pdfDocument) { if (!pdfDocument) {
return; return;
@ -309,12 +309,12 @@ class PDFFindController {
const pdfDocument = this._pdfDocument; const pdfDocument = this._pdfDocument;
const { type } = state; const { type } = state;
if (this._state === null || this._shouldDirtyMatch(state)) { if (this._state === null || this.#shouldDirtyMatch(state)) {
this._dirtyMatch = true; this._dirtyMatch = true;
} }
this._state = state; this._state = state;
if (type !== "highlightallchange") { if (type !== "highlightallchange") {
this._updateUIState(FindState.PENDING); this.#updateUIState(FindState.PENDING);
} }
this._firstPageCapability.promise.then(() => { this._firstPageCapability.promise.then(() => {
@ -326,7 +326,7 @@ class PDFFindController {
) { ) {
return; return;
} }
this._extractText(); this.#extractText();
const findbarClosed = !this._highlightMatches; const findbarClosed = !this._highlightMatches;
const pendingTimeout = !!this._findTimeout; const pendingTimeout = !!this._findTimeout;
@ -339,32 +339,32 @@ class PDFFindController {
// Trigger the find action with a small delay to avoid starting the // Trigger the find action with a small delay to avoid starting the
// search when the user is still typing (saving resources). // search when the user is still typing (saving resources).
this._findTimeout = setTimeout(() => { this._findTimeout = setTimeout(() => {
this._nextMatch(); this.#nextMatch();
this._findTimeout = null; this._findTimeout = null;
}, FIND_TIMEOUT); }, FIND_TIMEOUT);
} else if (this._dirtyMatch) { } else if (this._dirtyMatch) {
// Immediately trigger searching for non-'find' operations, when the // Immediately trigger searching for non-'find' operations, when the
// current state needs to be reset and matches re-calculated. // current state needs to be reset and matches re-calculated.
this._nextMatch(); this.#nextMatch();
} else if (type === "again") { } else if (type === "again") {
this._nextMatch(); this.#nextMatch();
// When the findbar was previously closed, and `highlightAll` is set, // When the findbar was previously closed, and `highlightAll` is set,
// ensure that the matches on all active pages are highlighted again. // ensure that the matches on all active pages are highlighted again.
if (findbarClosed && this._state.highlightAll) { if (findbarClosed && this._state.highlightAll) {
this._updateAllPages(); this.#updateAllPages();
} }
} else if (type === "highlightallchange") { } else if (type === "highlightallchange") {
// If there was a pending search operation, synchronously trigger a new // If there was a pending search operation, synchronously trigger a new
// search *first* to ensure that the correct matches are highlighted. // search *first* to ensure that the correct matches are highlighted.
if (pendingTimeout) { if (pendingTimeout) {
this._nextMatch(); this.#nextMatch();
} else { } else {
this._highlightMatches = true; this._highlightMatches = true;
} }
this._updateAllPages(); // Update the highlighting on all active pages. this.#updateAllPages(); // Update the highlighting on all active pages.
} else { } else {
this._nextMatch(); this.#nextMatch();
} }
}); });
} }
@ -391,7 +391,7 @@ class PDFFindController {
scrollIntoView(element, spot, /* scrollMatches = */ true); scrollIntoView(element, spot, /* scrollMatches = */ true);
} }
_reset() { #reset() {
this._highlightMatches = false; this._highlightMatches = false;
this._scrollMatches = false; this._scrollMatches = false;
this._pdfDocument = null; this._pdfDocument = null;
@ -427,7 +427,7 @@ class PDFFindController {
/** /**
* @type {string} The (current) normalized search query. * @type {string} The (current) normalized search query.
*/ */
get _query() { get #query() {
if (this._state.query !== this._rawQuery) { if (this._state.query !== this._rawQuery) {
this._rawQuery = this._state.query; this._rawQuery = this._state.query;
[this._normalizedQuery] = normalize(this._state.query); [this._normalizedQuery] = normalize(this._state.query);
@ -435,7 +435,7 @@ class PDFFindController {
return this._normalizedQuery; return this._normalizedQuery;
} }
_shouldDirtyMatch(state) { #shouldDirtyMatch(state) {
// When the search query changes, regardless of the actual search command // When the search query changes, regardless of the actual search command
// used, always re-calculate matches to avoid errors (fixes bug 1030622). // used, always re-calculate matches to avoid errors (fixes bug 1030622).
if (state.query !== this._state.query) { if (state.query !== this._state.query) {
@ -472,7 +472,7 @@ class PDFFindController {
* Determine if the search query constitutes a "whole word", by comparing the * Determine if the search query constitutes a "whole word", by comparing the
* first/last character type with the preceding/following character type. * first/last character type with the preceding/following character type.
*/ */
_isEntireWord(content, startIdx, length) { #isEntireWord(content, startIdx, length) {
let match = content let match = content
.slice(0, startIdx) .slice(0, startIdx)
.match(NOT_DIACRITIC_FROM_END_REG_EXP); .match(NOT_DIACRITIC_FROM_END_REG_EXP);
@ -498,7 +498,7 @@ class PDFFindController {
return true; return true;
} }
_calculateRegExpMatch(query, entireWord, pageIndex, pageContent) { #calculateRegExpMatch(query, entireWord, pageIndex, pageContent) {
const matches = [], const matches = [],
matchesLength = []; matchesLength = [];
@ -507,7 +507,7 @@ class PDFFindController {
while ((match = query.exec(pageContent)) !== null) { while ((match = query.exec(pageContent)) !== null) {
if ( if (
entireWord && entireWord &&
!this._isEntireWord(pageContent, match.index, match[0].length) !this.#isEntireWord(pageContent, match.index, match[0].length)
) { ) {
continue; continue;
} }
@ -527,7 +527,7 @@ class PDFFindController {
this._pageMatchesLength[pageIndex] = matchesLength; this._pageMatchesLength[pageIndex] = matchesLength;
} }
_convertToRegExpString(query, hasDiacritics) { #convertToRegExpString(query, hasDiacritics) {
const { matchDiacritics } = this._state; const { matchDiacritics } = this._state;
let isUnicode = false; let isUnicode = false;
query = query.replace( query = query.replace(
@ -593,8 +593,8 @@ class PDFFindController {
return [isUnicode, query]; return [isUnicode, query];
} }
_calculateMatch(pageIndex) { #calculateMatch(pageIndex) {
let query = this._query; let query = this.#query;
if (query.length === 0) { if (query.length === 0) {
// Do nothing: the matches should be wiped out already. // Do nothing: the matches should be wiped out already.
return; return;
@ -606,7 +606,7 @@ class PDFFindController {
let isUnicode = false; let isUnicode = false;
if (phraseSearch) { if (phraseSearch) {
[isUnicode, query] = this._convertToRegExpString(query, hasDiacritics); [isUnicode, query] = this.#convertToRegExpString(query, hasDiacritics);
} else { } else {
// Words are sorted in reverse order to be sure that "foobar" is matched // Words are sorted in reverse order to be sure that "foobar" is matched
// before "foo" in case the query is "foobar foo". // before "foo" in case the query is "foobar foo".
@ -616,7 +616,7 @@ class PDFFindController {
.sort() .sort()
.reverse() .reverse()
.map(q => { .map(q => {
const [isUnicodePart, queryPart] = this._convertToRegExpString( const [isUnicodePart, queryPart] = this.#convertToRegExpString(
q, q,
hasDiacritics hasDiacritics
); );
@ -630,27 +630,27 @@ class PDFFindController {
const flags = `g${isUnicode ? "u" : ""}${caseSensitive ? "" : "i"}`; const flags = `g${isUnicode ? "u" : ""}${caseSensitive ? "" : "i"}`;
query = new RegExp(query, flags); query = new RegExp(query, flags);
this._calculateRegExpMatch(query, entireWord, pageIndex, pageContent); this.#calculateRegExpMatch(query, entireWord, pageIndex, pageContent);
// When `highlightAll` is set, ensure that the matches on previously // When `highlightAll` is set, ensure that the matches on previously
// rendered (and still active) pages are correctly highlighted. // rendered (and still active) pages are correctly highlighted.
if (this._state.highlightAll) { if (this._state.highlightAll) {
this._updatePage(pageIndex); this.#updatePage(pageIndex);
} }
if (this._resumePageIdx === pageIndex) { if (this._resumePageIdx === pageIndex) {
this._resumePageIdx = null; this._resumePageIdx = null;
this._nextPageMatch(); this.#nextPageMatch();
} }
// Update the match count. // Update the match count.
const pageMatchesCount = this._pageMatches[pageIndex].length; const pageMatchesCount = this._pageMatches[pageIndex].length;
if (pageMatchesCount > 0) { if (pageMatchesCount > 0) {
this._matchesCountTotal += pageMatchesCount; this._matchesCountTotal += pageMatchesCount;
this._updateUIResultsCount(); this.#updateUIResultsCount();
} }
} }
_extractText() { #extractText() {
// Perform text extraction once if this method is called multiple times. // Perform text extraction once if this method is called multiple times.
if (this._extractTextPromises.length > 0) { if (this._extractTextPromises.length > 0) {
return; return;
@ -702,7 +702,7 @@ class PDFFindController {
} }
} }
_updatePage(index) { #updatePage(index) {
if (this._scrollMatches && this._selected.pageIdx === index) { if (this._scrollMatches && this._selected.pageIdx === index) {
// If the page is selected, scroll the page into view, which triggers // If the page is selected, scroll the page into view, which triggers
// rendering the page, which adds the text layer. Once the text layer // rendering the page, which adds the text layer. Once the text layer
@ -716,14 +716,14 @@ class PDFFindController {
}); });
} }
_updateAllPages() { #updateAllPages() {
this._eventBus.dispatch("updatetextlayermatches", { this._eventBus.dispatch("updatetextlayermatches", {
source: this, source: this,
pageIndex: -1, pageIndex: -1,
}); });
} }
_nextMatch() { #nextMatch() {
const previous = this._state.findPrevious; const previous = this._state.findPrevious;
const currentPageIndex = this._linkService.page - 1; const currentPageIndex = this._linkService.page - 1;
const numPages = this._linkService.pagesCount; const numPages = this._linkService.pagesCount;
@ -742,7 +742,7 @@ class PDFFindController {
this._pageMatchesLength.length = 0; this._pageMatchesLength.length = 0;
this._matchesCountTotal = 0; this._matchesCountTotal = 0;
this._updateAllPages(); // Wipe out any previously highlighted matches. this.#updateAllPages(); // Wipe out any previously highlighted matches.
for (let i = 0; i < numPages; i++) { for (let i = 0; i < numPages; i++) {
// Start finding the matches as soon as the text is extracted. // Start finding the matches as soon as the text is extracted.
@ -752,14 +752,14 @@ class PDFFindController {
this._pendingFindMatches.add(i); this._pendingFindMatches.add(i);
this._extractTextPromises[i].then(() => { this._extractTextPromises[i].then(() => {
this._pendingFindMatches.delete(i); this._pendingFindMatches.delete(i);
this._calculateMatch(i); this.#calculateMatch(i);
}); });
} }
} }
// If there's no query there's no point in searching. // If there's no query there's no point in searching.
if (this._query === "") { if (this.#query === "") {
this._updateUIState(FindState.FOUND); this.#updateUIState(FindState.FOUND);
return; return;
} }
// If we're waiting on a page, we return since we can't do anything else. // If we're waiting on a page, we return since we can't do anything else.
@ -781,18 +781,18 @@ class PDFFindController {
// The simple case; we just have advance the matchIdx to select // The simple case; we just have advance the matchIdx to select
// the next match on the page. // the next match on the page.
offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1; offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1;
this._updateMatch(/* found = */ true); this.#updateMatch(/* found = */ true);
return; return;
} }
// We went beyond the current page's matches, so we advance to // We went beyond the current page's matches, so we advance to
// the next page. // the next page.
this._advanceOffsetPage(previous); this.#advanceOffsetPage(previous);
} }
// Start searching through the page. // Start searching through the page.
this._nextPageMatch(); this.#nextPageMatch();
} }
_matchesReady(matches) { #matchesReady(matches) {
const offset = this._offset; const offset = this._offset;
const numMatches = matches.length; const numMatches = matches.length;
const previous = this._state.findPrevious; const previous = this._state.findPrevious;
@ -800,16 +800,16 @@ class PDFFindController {
if (numMatches) { if (numMatches) {
// There were matches for the page, so initialize `matchIdx`. // There were matches for the page, so initialize `matchIdx`.
offset.matchIdx = previous ? numMatches - 1 : 0; offset.matchIdx = previous ? numMatches - 1 : 0;
this._updateMatch(/* found = */ true); this.#updateMatch(/* found = */ true);
return true; return true;
} }
// No matches, so attempt to search the next page. // No matches, so attempt to search the next page.
this._advanceOffsetPage(previous); this.#advanceOffsetPage(previous);
if (offset.wrapped) { if (offset.wrapped) {
offset.matchIdx = null; offset.matchIdx = null;
if (this._pagesToSearch < 0) { if (this._pagesToSearch < 0) {
// No point in wrapping again, there were no matches. // No point in wrapping again, there were no matches.
this._updateMatch(/* found = */ false); this.#updateMatch(/* found = */ false);
// While matches were not found, searching for a page // While matches were not found, searching for a page
// with matches should nevertheless halt. // with matches should nevertheless halt.
return true; return true;
@ -819,7 +819,7 @@ class PDFFindController {
return false; return false;
} }
_nextPageMatch() { #nextPageMatch() {
if (this._resumePageIdx !== null) { if (this._resumePageIdx !== null) {
console.error("There can only be one pending page."); console.error("There can only be one pending page.");
} }
@ -834,10 +834,10 @@ class PDFFindController {
this._resumePageIdx = pageIdx; this._resumePageIdx = pageIdx;
break; break;
} }
} while (!this._matchesReady(matches)); } while (!this.#matchesReady(matches));
} }
_advanceOffsetPage(previous) { #advanceOffsetPage(previous) {
const offset = this._offset; const offset = this._offset;
const numPages = this._linkService.pagesCount; const numPages = this._linkService.pagesCount;
offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1; offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1;
@ -851,7 +851,7 @@ class PDFFindController {
} }
} }
_updateMatch(found = false) { #updateMatch(found = false) {
let state = FindState.NOT_FOUND; let state = FindState.NOT_FOUND;
const wrapped = this._offset.wrapped; const wrapped = this._offset.wrapped;
this._offset.wrapped = false; this._offset.wrapped = false;
@ -864,16 +864,16 @@ class PDFFindController {
// Update the currently selected page to wipe out any selected matches. // Update the currently selected page to wipe out any selected matches.
if (previousPage !== -1 && previousPage !== this._selected.pageIdx) { if (previousPage !== -1 && previousPage !== this._selected.pageIdx) {
this._updatePage(previousPage); this.#updatePage(previousPage);
} }
} }
this._updateUIState(state, this._state.findPrevious); this.#updateUIState(state, this._state.findPrevious);
if (this._selected.pageIdx !== -1) { if (this._selected.pageIdx !== -1) {
// Ensure that the match will be scrolled into view. // Ensure that the match will be scrolled into view.
this._scrollMatches = true; this._scrollMatches = true;
this._updatePage(this._selected.pageIdx); this.#updatePage(this._selected.pageIdx);
} }
} }
@ -904,14 +904,14 @@ class PDFFindController {
this._dirtyMatch = true; this._dirtyMatch = true;
} }
// Avoid the UI being in a pending state when the findbar is re-opened. // Avoid the UI being in a pending state when the findbar is re-opened.
this._updateUIState(FindState.FOUND); this.#updateUIState(FindState.FOUND);
this._highlightMatches = false; this._highlightMatches = false;
this._updateAllPages(); // Wipe out any previously highlighted matches. this.#updateAllPages(); // Wipe out any previously highlighted matches.
}); });
} }
_requestMatchesCount() { #requestMatchesCount() {
const { pageIdx, matchIdx } = this._selected; const { pageIdx, matchIdx } = this._selected;
let current = 0, let current = 0,
total = this._matchesCountTotal; total = this._matchesCountTotal;
@ -930,19 +930,19 @@ class PDFFindController {
return { current, total }; return { current, total };
} }
_updateUIResultsCount() { #updateUIResultsCount() {
this._eventBus.dispatch("updatefindmatchescount", { this._eventBus.dispatch("updatefindmatchescount", {
source: this, source: this,
matchesCount: this._requestMatchesCount(), matchesCount: this.#requestMatchesCount(),
}); });
} }
_updateUIState(state, previous = false) { #updateUIState(state, previous = false) {
this._eventBus.dispatch("updatefindcontrolstate", { this._eventBus.dispatch("updatefindcontrolstate", {
source: this, source: this,
state, state,
previous, previous,
matchesCount: this._requestMatchesCount(), matchesCount: this.#requestMatchesCount(),
rawQuery: this._state?.query ?? null, rawQuery: this._state?.query ?? null,
}); });
} }