Move binarySearchFirstItem
back to the web/
-folder (PR 15237 follow-up)
This was moved into the `src/display/`-folder in PR 15110, for the initial editor-a11y patch. However, with the changes in PR 15237 we're again only using `binarySearchFirstItem` in the `web/`-folder and it thus seem reasonable to move it back there. The primary reason for moving it back is that `binarySearchFirstItem` is currently exposed in the public API, and we always want to avoid that unless it's either PDF-related functionality or code that simply must be shared between the `src/`- and `web/`-folders. In this case, `binarySearchFirstItem` is a general helper function that doesn't really satisfy either of those alternatives.
This commit is contained in:
parent
2b66ed5fef
commit
0024165f1f
@ -611,38 +611,6 @@ function getColorValues(colors) {
|
|||||||
span.remove();
|
span.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Use binary search to find the index of the first item in a given array which
|
|
||||||
* passes a given condition. The items are expected to be sorted in the sense
|
|
||||||
* that if the condition is true for one item in the array, then it is also true
|
|
||||||
* for all following items.
|
|
||||||
*
|
|
||||||
* @returns {number} Index of the first array element to pass the test,
|
|
||||||
* or |items.length| if no such element exists.
|
|
||||||
*/
|
|
||||||
function binarySearchFirstItem(items, condition, start = 0) {
|
|
||||||
let minIndex = start;
|
|
||||||
let maxIndex = items.length - 1;
|
|
||||||
|
|
||||||
if (maxIndex < 0 || !condition(items[maxIndex])) {
|
|
||||||
return items.length;
|
|
||||||
}
|
|
||||||
if (condition(items[minIndex])) {
|
|
||||||
return minIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (minIndex < maxIndex) {
|
|
||||||
const currentIndex = (minIndex + maxIndex) >> 1;
|
|
||||||
const currentItem = items[currentIndex];
|
|
||||||
if (condition(currentItem)) {
|
|
||||||
maxIndex = currentIndex;
|
|
||||||
} else {
|
|
||||||
minIndex = currentIndex + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return minIndex; /* === maxIndex */
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentTransform(ctx) {
|
function getCurrentTransform(ctx) {
|
||||||
const { a, b, c, d, e, f } = ctx.getTransform();
|
const { a, b, c, d, e, f } = ctx.getTransform();
|
||||||
return [a, b, c, d, e, f];
|
return [a, b, c, d, e, f];
|
||||||
@ -655,7 +623,6 @@ function getCurrentTransformInverse(ctx) {
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
AnnotationPrefix,
|
AnnotationPrefix,
|
||||||
binarySearchFirstItem,
|
|
||||||
deprecated,
|
deprecated,
|
||||||
DOMCanvasFactory,
|
DOMCanvasFactory,
|
||||||
DOMCMapReaderFactory,
|
DOMCMapReaderFactory,
|
||||||
|
20
src/pdf.js
20
src/pdf.js
@ -41,7 +41,15 @@ import {
|
|||||||
VerbosityLevel,
|
VerbosityLevel,
|
||||||
} from "./shared/util.js";
|
} from "./shared/util.js";
|
||||||
import {
|
import {
|
||||||
binarySearchFirstItem,
|
build,
|
||||||
|
getDocument,
|
||||||
|
LoopbackPort,
|
||||||
|
PDFDataRangeTransport,
|
||||||
|
PDFWorker,
|
||||||
|
setPDFNetworkStreamFactory,
|
||||||
|
version,
|
||||||
|
} from "./display/api.js";
|
||||||
|
import {
|
||||||
getFilenameFromUrl,
|
getFilenameFromUrl,
|
||||||
getPdfFilenameFromUrl,
|
getPdfFilenameFromUrl,
|
||||||
getXfaPageViewport,
|
getXfaPageViewport,
|
||||||
@ -52,15 +60,6 @@ import {
|
|||||||
PixelsPerInch,
|
PixelsPerInch,
|
||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
} from "./display/display_utils.js";
|
} from "./display/display_utils.js";
|
||||||
import {
|
|
||||||
build,
|
|
||||||
getDocument,
|
|
||||||
LoopbackPort,
|
|
||||||
PDFDataRangeTransport,
|
|
||||||
PDFWorker,
|
|
||||||
setPDFNetworkStreamFactory,
|
|
||||||
version,
|
|
||||||
} from "./display/api.js";
|
|
||||||
import { AnnotationEditorLayer } from "./display/editor/annotation_editor_layer.js";
|
import { AnnotationEditorLayer } from "./display/editor/annotation_editor_layer.js";
|
||||||
import { AnnotationEditorUIManager } from "./display/editor/tools.js";
|
import { AnnotationEditorUIManager } from "./display/editor/tools.js";
|
||||||
import { AnnotationLayer } from "./display/annotation_layer.js";
|
import { AnnotationLayer } from "./display/annotation_layer.js";
|
||||||
@ -117,7 +116,6 @@ export {
|
|||||||
AnnotationEditorUIManager,
|
AnnotationEditorUIManager,
|
||||||
AnnotationLayer,
|
AnnotationLayer,
|
||||||
AnnotationMode,
|
AnnotationMode,
|
||||||
binarySearchFirstItem,
|
|
||||||
build,
|
build,
|
||||||
CMapCompressionType,
|
CMapCompressionType,
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
binarySearchFirstItem,
|
|
||||||
DOMCanvasFactory,
|
DOMCanvasFactory,
|
||||||
DOMSVGFactory,
|
DOMSVGFactory,
|
||||||
getFilenameFromUrl,
|
getFilenameFromUrl,
|
||||||
@ -26,39 +25,6 @@ import { bytesToString } from "../../src/shared/util.js";
|
|||||||
import { isNodeJS } from "../../src/shared/is_node.js";
|
import { isNodeJS } from "../../src/shared/is_node.js";
|
||||||
|
|
||||||
describe("display_utils", function () {
|
describe("display_utils", function () {
|
||||||
describe("binary search", function () {
|
|
||||||
function isTrue(boolean) {
|
|
||||||
return boolean;
|
|
||||||
}
|
|
||||||
function isGreater3(number) {
|
|
||||||
return number > 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
it("empty array", function () {
|
|
||||||
expect(binarySearchFirstItem([], isTrue)).toEqual(0);
|
|
||||||
});
|
|
||||||
it("single boolean entry", function () {
|
|
||||||
expect(binarySearchFirstItem([false], isTrue)).toEqual(1);
|
|
||||||
expect(binarySearchFirstItem([true], isTrue)).toEqual(0);
|
|
||||||
});
|
|
||||||
it("three boolean entries", function () {
|
|
||||||
expect(binarySearchFirstItem([true, true, true], isTrue)).toEqual(0);
|
|
||||||
expect(binarySearchFirstItem([false, true, true], isTrue)).toEqual(1);
|
|
||||||
expect(binarySearchFirstItem([false, false, true], isTrue)).toEqual(2);
|
|
||||||
expect(binarySearchFirstItem([false, false, false], isTrue)).toEqual(3);
|
|
||||||
});
|
|
||||||
it("three numeric entries", function () {
|
|
||||||
expect(binarySearchFirstItem([0, 1, 2], isGreater3)).toEqual(3);
|
|
||||||
expect(binarySearchFirstItem([2, 3, 4], isGreater3)).toEqual(2);
|
|
||||||
expect(binarySearchFirstItem([4, 5, 6], isGreater3)).toEqual(0);
|
|
||||||
});
|
|
||||||
it("three numeric entries and a start index", function () {
|
|
||||||
expect(binarySearchFirstItem([0, 1, 2, 3, 4], isGreater3, 2)).toEqual(4);
|
|
||||||
expect(binarySearchFirstItem([2, 3, 4], isGreater3, 2)).toEqual(2);
|
|
||||||
expect(binarySearchFirstItem([4, 5, 6], isGreater3, 1)).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("DOMCanvasFactory", function () {
|
describe("DOMCanvasFactory", function () {
|
||||||
let canvasFactory;
|
let canvasFactory;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
backtrackBeforeAllVisibleElements,
|
backtrackBeforeAllVisibleElements,
|
||||||
|
binarySearchFirstItem,
|
||||||
getPageSizeInches,
|
getPageSizeInches,
|
||||||
getVisibleElements,
|
getVisibleElements,
|
||||||
isPortraitOrientation,
|
isPortraitOrientation,
|
||||||
@ -24,6 +25,39 @@ import {
|
|||||||
} from "../../web/ui_utils.js";
|
} from "../../web/ui_utils.js";
|
||||||
|
|
||||||
describe("ui_utils", function () {
|
describe("ui_utils", function () {
|
||||||
|
describe("binary search", function () {
|
||||||
|
function isTrue(boolean) {
|
||||||
|
return boolean;
|
||||||
|
}
|
||||||
|
function isGreater3(number) {
|
||||||
|
return number > 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
it("empty array", function () {
|
||||||
|
expect(binarySearchFirstItem([], isTrue)).toEqual(0);
|
||||||
|
});
|
||||||
|
it("single boolean entry", function () {
|
||||||
|
expect(binarySearchFirstItem([false], isTrue)).toEqual(1);
|
||||||
|
expect(binarySearchFirstItem([true], isTrue)).toEqual(0);
|
||||||
|
});
|
||||||
|
it("three boolean entries", function () {
|
||||||
|
expect(binarySearchFirstItem([true, true, true], isTrue)).toEqual(0);
|
||||||
|
expect(binarySearchFirstItem([false, true, true], isTrue)).toEqual(1);
|
||||||
|
expect(binarySearchFirstItem([false, false, true], isTrue)).toEqual(2);
|
||||||
|
expect(binarySearchFirstItem([false, false, false], isTrue)).toEqual(3);
|
||||||
|
});
|
||||||
|
it("three numeric entries", function () {
|
||||||
|
expect(binarySearchFirstItem([0, 1, 2], isGreater3)).toEqual(3);
|
||||||
|
expect(binarySearchFirstItem([2, 3, 4], isGreater3)).toEqual(2);
|
||||||
|
expect(binarySearchFirstItem([4, 5, 6], isGreater3)).toEqual(0);
|
||||||
|
});
|
||||||
|
it("three numeric entries and a start index", function () {
|
||||||
|
expect(binarySearchFirstItem([0, 1, 2, 3, 4], isGreater3, 2)).toEqual(4);
|
||||||
|
expect(binarySearchFirstItem([2, 3, 4], isGreater3, 2)).toEqual(2);
|
||||||
|
expect(binarySearchFirstItem([4, 5, 6], isGreater3, 1)).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("isValidRotation", function () {
|
describe("isValidRotation", function () {
|
||||||
it("should reject non-integer angles", function () {
|
it("should reject non-integer angles", function () {
|
||||||
expect(isValidRotation()).toEqual(false);
|
expect(isValidRotation()).toEqual(false);
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
/** @typedef {import("./event_utils").EventBus} EventBus */
|
/** @typedef {import("./event_utils").EventBus} EventBus */
|
||||||
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
|
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
|
||||||
|
|
||||||
import { binarySearchFirstItem, createPromiseCapability } from "pdfjs-lib";
|
import { binarySearchFirstItem, scrollIntoView } from "./ui_utils.js";
|
||||||
|
import { createPromiseCapability } from "pdfjs-lib";
|
||||||
import { getCharacterType } from "./pdf_find_utils.js";
|
import { getCharacterType } from "./pdf_find_utils.js";
|
||||||
import { scrollIntoView } from "./ui_utils.js";
|
|
||||||
|
|
||||||
const FindState = {
|
const FindState = {
|
||||||
FOUND: 0,
|
FOUND: 0,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { binarySearchFirstItem } from "pdfjs-lib";
|
import { binarySearchFirstItem } from "./ui_utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class aims to provide some methods:
|
* This class aims to provide some methods:
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { binarySearchFirstItem } from "pdfjs-lib";
|
|
||||||
|
|
||||||
const DEFAULT_SCALE_VALUE = "auto";
|
const DEFAULT_SCALE_VALUE = "auto";
|
||||||
const DEFAULT_SCALE = 1.0;
|
const DEFAULT_SCALE = 1.0;
|
||||||
const DEFAULT_SCALE_DELTA = 1.1;
|
const DEFAULT_SCALE_DELTA = 1.1;
|
||||||
@ -226,6 +224,38 @@ function removeNullCharacters(str, replaceInvisible = false) {
|
|||||||
return str.replace(NullCharactersRegExp, "");
|
return str.replace(NullCharactersRegExp, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use binary search to find the index of the first item in a given array which
|
||||||
|
* passes a given condition. The items are expected to be sorted in the sense
|
||||||
|
* that if the condition is true for one item in the array, then it is also true
|
||||||
|
* for all following items.
|
||||||
|
*
|
||||||
|
* @returns {number} Index of the first array element to pass the test,
|
||||||
|
* or |items.length| if no such element exists.
|
||||||
|
*/
|
||||||
|
function binarySearchFirstItem(items, condition, start = 0) {
|
||||||
|
let minIndex = start;
|
||||||
|
let maxIndex = items.length - 1;
|
||||||
|
|
||||||
|
if (maxIndex < 0 || !condition(items[maxIndex])) {
|
||||||
|
return items.length;
|
||||||
|
}
|
||||||
|
if (condition(items[minIndex])) {
|
||||||
|
return minIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (minIndex < maxIndex) {
|
||||||
|
const currentIndex = (minIndex + maxIndex) >> 1;
|
||||||
|
const currentItem = items[currentIndex];
|
||||||
|
if (condition(currentItem)) {
|
||||||
|
maxIndex = currentIndex;
|
||||||
|
} else {
|
||||||
|
minIndex = currentIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minIndex; /* === maxIndex */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Approximates float number as a fraction using Farey sequence (max order
|
* Approximates float number as a fraction using Farey sequence (max order
|
||||||
* of 8).
|
* of 8).
|
||||||
@ -813,6 +843,7 @@ export {
|
|||||||
approximateFraction,
|
approximateFraction,
|
||||||
AutoPrintRegExp,
|
AutoPrintRegExp,
|
||||||
backtrackBeforeAllVisibleElements, // only exported for testing
|
backtrackBeforeAllVisibleElements, // only exported for testing
|
||||||
|
binarySearchFirstItem,
|
||||||
DEFAULT_SCALE,
|
DEFAULT_SCALE,
|
||||||
DEFAULT_SCALE_DELTA,
|
DEFAULT_SCALE_DELTA,
|
||||||
DEFAULT_SCALE_VALUE,
|
DEFAULT_SCALE_VALUE,
|
||||||
|
Loading…
Reference in New Issue
Block a user