diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 255d1d12ecc5c..0c2c5febb1c61 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -611,38 +611,6 @@ function getColorValues(colors) { 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) { const { a, b, c, d, e, f } = ctx.getTransform(); return [a, b, c, d, e, f]; @@ -655,7 +623,6 @@ function getCurrentTransformInverse(ctx) { export { AnnotationPrefix, - binarySearchFirstItem, deprecated, DOMCanvasFactory, DOMCMapReaderFactory, diff --git a/src/pdf.js b/src/pdf.js index 4350684562a7c..8a55278126b26 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -41,7 +41,15 @@ import { VerbosityLevel, } from "./shared/util.js"; import { - binarySearchFirstItem, + build, + getDocument, + LoopbackPort, + PDFDataRangeTransport, + PDFWorker, + setPDFNetworkStreamFactory, + version, +} from "./display/api.js"; +import { getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, @@ -52,15 +60,6 @@ import { PixelsPerInch, RenderingCancelledException, } 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 { AnnotationEditorUIManager } from "./display/editor/tools.js"; import { AnnotationLayer } from "./display/annotation_layer.js"; @@ -117,7 +116,6 @@ export { AnnotationEditorUIManager, AnnotationLayer, AnnotationMode, - binarySearchFirstItem, build, CMapCompressionType, createPromiseCapability, diff --git a/test/unit/display_utils_spec.js b/test/unit/display_utils_spec.js index 56488e628f33a..55ebe6e7d5d14 100644 --- a/test/unit/display_utils_spec.js +++ b/test/unit/display_utils_spec.js @@ -14,7 +14,6 @@ */ import { - binarySearchFirstItem, DOMCanvasFactory, DOMSVGFactory, getFilenameFromUrl, @@ -26,39 +25,6 @@ import { bytesToString } from "../../src/shared/util.js"; import { isNodeJS } from "../../src/shared/is_node.js"; 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 () { let canvasFactory; diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index 23a825349c235..7040081750b0b 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -15,6 +15,7 @@ import { backtrackBeforeAllVisibleElements, + binarySearchFirstItem, getPageSizeInches, getVisibleElements, isPortraitOrientation, @@ -24,6 +25,39 @@ import { } from "../../web/ui_utils.js"; 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 () { it("should reject non-integer angles", function () { expect(isValidRotation()).toEqual(false); diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index d7c31e096d090..cfadec222daab 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -17,9 +17,9 @@ /** @typedef {import("./event_utils").EventBus} EventBus */ /** @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 { scrollIntoView } from "./ui_utils.js"; const FindState = { FOUND: 0, diff --git a/web/text_accessibility.js b/web/text_accessibility.js index 142c894b3133a..19741c4bf37cb 100644 --- a/web/text_accessibility.js +++ b/web/text_accessibility.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { binarySearchFirstItem } from "pdfjs-lib"; +import { binarySearchFirstItem } from "./ui_utils.js"; /** * This class aims to provide some methods: diff --git a/web/ui_utils.js b/web/ui_utils.js index d9673a4dddb3d..8f3256bde23dc 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -13,8 +13,6 @@ * limitations under the License. */ -import { binarySearchFirstItem } from "pdfjs-lib"; - const DEFAULT_SCALE_VALUE = "auto"; const DEFAULT_SCALE = 1.0; const DEFAULT_SCALE_DELTA = 1.1; @@ -226,6 +224,38 @@ function removeNullCharacters(str, replaceInvisible = false) { 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 * of 8). @@ -813,6 +843,7 @@ export { approximateFraction, AutoPrintRegExp, backtrackBeforeAllVisibleElements, // only exported for testing + binarySearchFirstItem, DEFAULT_SCALE, DEFAULT_SCALE_DELTA, DEFAULT_SCALE_VALUE,