diff --git a/extensions/chromium/options/migration.js b/extensions/chromium/options/migration.js index ca547850c4214..d2d8720d4eb9c 100644 --- a/extensions/chromium/options/migration.js +++ b/extensions/chromium/options/migration.js @@ -81,6 +81,9 @@ limitations under the License. 'disableTextLayer', 'enhanceTextSelection', 'textLayerMode', + 'showPreviousViewOnLoad', + 'disablePageMode', + 'viewOnLoad', ], function(items) { // Migration code for https://github.com/mozilla/pdf.js/pull/7635. if (typeof items.enableHandToolOnLoad === 'boolean') { @@ -113,6 +116,20 @@ limitations under the License. storageSync.remove(['disableTextLayer', 'enhanceTextSelection']); } } + // Migration code for https://github.com/mozilla/pdf.js/pull/10502. + if (typeof items.showPreviousViewOnLoad === 'boolean') { + if (!items.showPreviousViewOnLoad) { + storageSync.set({ + viewOnLoad: 1, + }, function() { + if (!chrome.runtime.lastError) { + storageSync.remove(['showPreviousViewOnLoad', 'disablePageMode']); + } + }); + } else { + storageSync.remove(['showPreviousViewOnLoad', 'disablePageMode']); + } + } }); } })(); diff --git a/extensions/chromium/options/options.html b/extensions/chromium/options/options.html index 412e80bb1a11c..57ddae7b14305 100644 --- a/extensions/chromium/options/options.html +++ b/extensions/chromium/options/options.html @@ -43,6 +43,19 @@ + + + + + + Default + Show previous position + Show initial position + + + + + @@ -71,6 +84,7 @@ + Default Do not show sidebar Show thumbnails in sidebar Show document outline in sidebar @@ -125,6 +139,7 @@ + Default Vertical scrolling Horizontal scrolling Wrapped scrolling @@ -138,6 +153,7 @@ + Default No spreads Odd spreads Even spreads diff --git a/extensions/chromium/preferences_schema.json b/extensions/chromium/preferences_schema.json index eb264dee26999..2ce2a53ba4080 100644 --- a/extensions/chromium/preferences_schema.json +++ b/extensions/chromium/preferences_schema.json @@ -2,11 +2,20 @@ "type": "object", "properties": { "showPreviousViewOnLoad": { - "title": "Show previous position of PDF upon load", - "description": "Whether to view PDF documents in the last page and position upon opening the viewer.", + "description": "DEPRECATED. Set viewOnLoad to 1 to disable showing the last page/position on load.", "type": "boolean", "default": true }, + "viewOnLoad": { + "title": "View position on load", + "description": "The position in the document upon load.\n -1 = Default (uses OpenAction if available, otherwise equal to `viewOnLoad = 0`).\n 0 = The last viewed page/position.\n 1 = The initial page/position.", + "enum": [ + -1, + 0, + 1 + ], + "default": 0 + }, "defaultZoomValue": { "title": "Default zoom level", "description": "Default zoom level of the viewer. Accepted values: 'auto', 'page-actual', 'page-width', 'page-height', 'page-fit', or a zoom level in percents.", @@ -16,15 +25,16 @@ }, "sidebarViewOnLoad": { "title": "Sidebar state on load", - "description": "Controls the state of the sidebar upon load.\n 0 = do not show sidebar.\n 1 = show thumbnails in sidebar.\n 2 = show document outline in sidebar.\n 3 = Show attachments in sidebar.", + "description": "Controls the state of the sidebar upon load.\n -1 = Default (uses PageMode if available, otherwise the last position if available/enabled).\n 0 = Do not show sidebar.\n 1 = Show thumbnails in sidebar.\n 2 = Show document outline in sidebar.\n 3 = Show attachments in sidebar.", "type": "integer", "enum": [ + -1, 0, 1, 2, 3 ], - "default": 0 + "default": -1 }, "enableHandToolOnLoad": { "description": "DEPRECATED. Set cursorToolOnLoad to 1 to enable the hand tool by default.", @@ -117,15 +127,12 @@ ], "default": 0 }, - "disableOpenActionDestination": { - "type": "boolean", - "default": true - }, "disablePageLabels": { "type": "boolean", "default": false }, "disablePageMode": { + "description": "DEPRECATED.", "type": "boolean", "default": false }, @@ -159,25 +166,27 @@ }, "scrollModeOnLoad": { "title": "Scroll mode on load", - "description": "Controls how the viewer scrolls upon load.\n 0 = Vertical scrolling.\n 1 = Horizontal scrolling.\n 2 = Wrapped scrolling.", + "description": "Controls how the viewer scrolls upon load.\n -1 = Default (uses the last position if available/enabled).\n 0 = Vertical scrolling.\n 1 = Horizontal scrolling.\n 2 = Wrapped scrolling.", "type": "integer", "enum": [ + -1, 0, 1, 2 ], - "default": 0 + "default": -1 }, "spreadModeOnLoad": { "title": "Spread mode on load", - "description": "Whether the viewer should join pages into spreads upon load.\n 0 = No spreads.\n 1 = Odd spreads.\n 2 = Even spreads.", + "description": "Whether the viewer should join pages into spreads upon load.\n -1 = Default (uses the last position if available/enabled).\n 0 = No spreads.\n 1 = Odd spreads.\n 2 = Even spreads.", "type": "integer", "enum": [ + -1, 0, 1, 2 ], - "default": 0 + "default": -1 } } } diff --git a/web/app.js b/web/app.js index 0d09e67ef7536..5c87ee0d257a5 100644 --- a/web/app.js +++ b/web/app.js @@ -16,9 +16,10 @@ import { animationStarted, DEFAULT_SCALE_VALUE, getGlobalEventBus, - getPDFFileNameFromURL, isValidRotation, MAX_SCALE, MIN_SCALE, - noContextMenuHandler, normalizeWheelEventDelta, parseQueryString, - PresentationModeState, ProgressBar, RendererType, TextLayerMode + getPDFFileNameFromURL, isValidRotation, isValidScrollMode, isValidSpreadMode, + MAX_SCALE, MIN_SCALE, noContextMenuHandler, normalizeWheelEventDelta, + parseQueryString, PresentationModeState, ProgressBar, RendererType, + ScrollMode, SpreadMode, TextLayerMode } from './ui_utils'; import { build, createObjectURL, getDocument, getFilenameFromUrl, GlobalWorkerOptions, @@ -52,6 +53,12 @@ const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; // ms const FORCE_PAGES_LOADED_TIMEOUT = 10000; // ms const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000; // ms +const ViewOnLoad = { + UNKNOWN: -1, + PREVIOUS: 0, // Default value. + INITIAL: 1, +}; + const DefaultExternalServices = { updateFindControlState(data) {}, updateFindMatchesCount(data) {}, @@ -900,46 +907,29 @@ let PDFViewerApplication = { firstPagePromise.then((pdfPage) => { this.loadingBar.setWidth(this.appConfig.viewerContainer); - if (!AppOptions.get('disableHistory') && !this.isViewerEmbedded) { - // The browsing history is only enabled when the viewer is standalone, - // i.e. not when it is embedded in a web page. - this.pdfHistory.initialize({ - fingerprint: pdfDocument.fingerprint, - resetHistory: !AppOptions.get('showPreviousViewOnLoad'), - updateUrl: AppOptions.get('historyUpdateUrl'), - }); - - if (this.pdfHistory.initialBookmark) { - this.initialBookmark = this.pdfHistory.initialBookmark; - - this.initialRotation = this.pdfHistory.initialRotation; - } - } - - let storePromise = store.getMultiple({ + const storePromise = store.getMultiple({ page: null, zoom: DEFAULT_SCALE_VALUE, scrollLeft: '0', scrollTop: '0', rotation: null, - sidebarView: SidebarView.NONE, - scrollMode: null, - spreadMode: null, + sidebarView: SidebarView.UNKNOWN, + scrollMode: ScrollMode.UNKNOWN, + spreadMode: SpreadMode.UNKNOWN, }).catch(() => { /* Unable to read from storage; ignoring errors. */ }); Promise.all([ storePromise, pageModePromise, openActionDestPromise, ]).then(async ([values = {}, pageMode, openActionDest]) => { - if (openActionDest && !this.initialBookmark && - !AppOptions.get('disableOpenActionDestination')) { - // Always let the browser history/document hash take precedence. - this.initialBookmark = JSON.stringify(openActionDest); - // TODO: Re-factor the `PDFHistory` initialization to remove this hack - // that's currently necessary to prevent weird initial history state. - this.pdfHistory.push({ explicitDest: openActionDest, - pageNumber: null, }); - } + const viewOnLoad = AppOptions.get('viewOnLoad'); + + this._initializePdfHistory({ + fingerprint: pdfDocument.fingerprint, + viewOnLoad, + initialDest: openActionDest, + }); const initialBookmark = this.initialBookmark; + // Initialize the default values, from user preferences. const zoom = AppOptions.get('defaultZoomValue'); let hash = zoom ? `zoom=${zoom}` : null; @@ -949,18 +939,25 @@ let PDFViewerApplication = { let scrollMode = AppOptions.get('scrollModeOnLoad'); let spreadMode = AppOptions.get('spreadModeOnLoad'); - if (values.page && AppOptions.get('showPreviousViewOnLoad')) { - hash = 'page=' + values.page + '&zoom=' + (zoom || values.zoom) + - ',' + values.scrollLeft + ',' + values.scrollTop; + if (values.page && viewOnLoad !== ViewOnLoad.INITIAL) { + hash = `page=${values.page}&zoom=${zoom || values.zoom},` + + `${values.scrollLeft},${values.scrollTop}`; rotation = parseInt(values.rotation, 10); - sidebarView = sidebarView || (values.sidebarView | 0); - scrollMode = scrollMode || (values.scrollMode | 0); - spreadMode = spreadMode || (values.spreadMode | 0); + // Always let user preferences take precedence over the view history. + if (sidebarView === SidebarView.UNKNOWN) { + sidebarView = (values.sidebarView | 0); + } + if (scrollMode === ScrollMode.UNKNOWN) { + scrollMode = (values.scrollMode | 0); + } + if (spreadMode === SpreadMode.UNKNOWN) { + spreadMode = (values.spreadMode | 0); + } } - if (pageMode && !AppOptions.get('disablePageMode')) { - // Always let the user preference/history take precedence. - sidebarView = sidebarView || apiPageModeToSidebarView(pageMode); + // Always let the user preference/view history take precedence. + if (pageMode && sidebarView === SidebarView.UNKNOWN) { + sidebarView = apiPageModeToSidebarView(pageMode); } this.setInitialView(hash, { @@ -1147,30 +1144,57 @@ let PDFViewerApplication = { }); }, + /** + * @private + */ + _initializePdfHistory({ fingerprint, viewOnLoad, initialDest = null, }) { + if (AppOptions.get('disableHistory') || this.isViewerEmbedded) { + // The browsing history is only enabled when the viewer is standalone, + // i.e. not when it is embedded in a web page. + return; + } + this.pdfHistory.initialize({ + fingerprint, + resetHistory: viewOnLoad === ViewOnLoad.INITIAL, + updateUrl: AppOptions.get('historyUpdateUrl'), + }); + + if (this.pdfHistory.initialBookmark) { + this.initialBookmark = this.pdfHistory.initialBookmark; + + this.initialRotation = this.pdfHistory.initialRotation; + } + + // Always let the browser history/document hash take precedence. + if (initialDest && !this.initialBookmark && + viewOnLoad === ViewOnLoad.UNKNOWN) { + this.initialBookmark = JSON.stringify(initialDest); + // TODO: Re-factor the `PDFHistory` initialization to remove this hack + // that's currently necessary to prevent weird initial history state. + this.pdfHistory.push({ explicitDest: initialDest, pageNumber: null, }); + } + }, + setInitialView(storedHash, { rotation, sidebarView, scrollMode, spreadMode, } = {}) { - let setRotation = (angle) => { + const setRotation = (angle) => { if (isValidRotation(angle)) { this.pdfViewer.pagesRotation = angle; } }; - let setViewerModes = (scroll, spread) => { - if (Number.isInteger(scroll)) { + const setViewerModes = (scroll, spread) => { + if (isValidScrollMode(scroll)) { this.pdfViewer.scrollMode = scroll; } - if (Number.isInteger(spread)) { + if (isValidSpreadMode(spread)) { this.pdfViewer.spreadMode = spread; } }; - - // Putting these before isInitialViewSet = true prevents these values from - // being stored in the document history (and overriding any future changes - // made to the corresponding global preferences), just this once. - setViewerModes(scrollMode, spreadMode); - this.isInitialViewSet = true; this.pdfSidebar.setInitialView(sidebarView); + setViewerModes(scrollMode, spreadMode); + if (this.initialBookmark) { setRotation(this.initialRotation); delete this.initialRotation; diff --git a/web/app_options.js b/web/app_options.js index 7e98646231238..12686d38b7acc 100644 --- a/web/app_options.js +++ b/web/app_options.js @@ -48,21 +48,11 @@ const defaultOptions = { value: false, kind: OptionKind.VIEWER, }, - disableOpenActionDestination: { - /** @type {boolean} */ - value: true, - kind: OptionKind.VIEWER, - }, disablePageLabels: { /** @type {boolean} */ value: false, kind: OptionKind.VIEWER, }, - disablePageMode: { - /** @type {boolean} */ - value: false, - kind: OptionKind.VIEWER, - }, /** * The `disablePreferences` is, conditionally, defined below. */ @@ -106,7 +96,8 @@ const defaultOptions = { */ maxCanvasPixels: { /** @type {number} */ - value: viewerCompatibilityParams.maxCanvasPixels || 16777216, + value: 16777216, + compatibility: viewerCompatibilityParams.maxCanvasPixels, kind: OptionKind.VIEWER, }, pdfBugEnabled: { @@ -124,24 +115,19 @@ const defaultOptions = { value: false, kind: OptionKind.VIEWER, }, - showPreviousViewOnLoad: { - /** @type {boolean} */ - value: true, - kind: OptionKind.VIEWER, - }, sidebarViewOnLoad: { /** @type {number} */ - value: 0, + value: -1, kind: OptionKind.VIEWER, }, scrollModeOnLoad: { /** @type {number} */ - value: 0, + value: -1, kind: OptionKind.VIEWER, }, spreadModeOnLoad: { /** @type {number} */ - value: 0, + value: -1, kind: OptionKind.VIEWER, }, textLayerMode: { @@ -154,6 +140,11 @@ const defaultOptions = { value: false, kind: OptionKind.VIEWER, }, + viewOnLoad: { + /** @type {boolean} */ + value: 0, + kind: OptionKind.VIEWER, + }, cMapPacked: { /** @type {boolean} */ @@ -173,7 +164,8 @@ const defaultOptions = { }, disableCreateObjectURL: { /** @type {boolean} */ - value: apiCompatibilityParams.disableCreateObjectURL || false, + value: false, + compatibility: apiCompatibilityParams.disableCreateObjectURL, kind: OptionKind.API, }, disableFontFace: { @@ -251,22 +243,27 @@ class AppOptions { } static get(name) { - let defaultOption = defaultOptions[name], userOption = userOptions[name]; + const userOption = userOptions[name]; if (userOption !== undefined) { return userOption; } - return (defaultOption !== undefined ? defaultOption.value : undefined); + const defaultOption = defaultOptions[name]; + if (defaultOption !== undefined) { + return (defaultOption.compatibility || defaultOption.value); + } + return undefined; } static getAll(kind = null) { - let options = Object.create(null); - for (let name in defaultOptions) { - let defaultOption = defaultOptions[name], userOption = userOptions[name]; - if (kind && defaultOption.kind !== kind) { + const options = Object.create(null); + for (const name in defaultOptions) { + const defaultOption = defaultOptions[name]; + if (kind && kind !== defaultOption.kind) { continue; } - options[name] = (userOption !== undefined ? - userOption : defaultOption.value); + const userOption = userOptions[name]; + options[name] = (userOption !== undefined ? userOption : + (defaultOption.compatibility || defaultOption.value)); } return options; } diff --git a/web/base_viewer.js b/web/base_viewer.js index 416602dca8deb..45578ac850cc2 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -15,10 +15,11 @@ import { CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, getGlobalEventBus, - getVisibleElements, isPortraitOrientation, isValidRotation, MAX_AUTO_SCALE, - moveToEndOfArray, NullL10n, PresentationModeState, RendererType, - SCROLLBAR_PADDING, scrollIntoView, TextLayerMode, UNKNOWN_SCALE, - VERTICAL_PADDING, watchScroll + getVisibleElements, isPortraitOrientation, isValidRotation, isValidScrollMode, + isValidSpreadMode, MAX_AUTO_SCALE, moveToEndOfArray, NullL10n, + PresentationModeState, RendererType, SCROLLBAR_PADDING, scrollIntoView, + ScrollMode, SpreadMode, TextLayerMode, UNKNOWN_SCALE, VERTICAL_PADDING, + watchScroll } from './ui_utils'; import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue'; import { AnnotationLayerBuilder } from './annotation_layer_builder'; @@ -29,18 +30,6 @@ import { TextLayerBuilder } from './text_layer_builder'; const DEFAULT_CACHE_SIZE = 10; -const ScrollMode = { - VERTICAL: 0, // The default value. - HORIZONTAL: 1, - WRAPPED: 2, -}; - -const SpreadMode = { - NONE: 0, // The default value. - ODD: 1, - EVEN: 2, -}; - /** * @typedef {Object} PDFViewerOptions * @property {HTMLDivElement} container - The container for the viewer element. @@ -1084,7 +1073,7 @@ class BaseViewer { if (this._scrollMode === mode) { return; // The Scroll mode didn't change. } - if (!Number.isInteger(mode) || !Object.values(ScrollMode).includes(mode)) { + if (!isValidScrollMode(mode)) { throw new Error(`Invalid scroll mode: ${mode}`); } this._scrollMode = mode; @@ -1130,7 +1119,7 @@ class BaseViewer { if (this._spreadMode === mode) { return; // The Spread mode didn't change. } - if (!Number.isInteger(mode) || !Object.values(SpreadMode).includes(mode)) { + if (!isValidSpreadMode(mode)) { throw new Error(`Invalid spread mode: ${mode}`); } this._spreadMode = mode; @@ -1177,6 +1166,4 @@ class BaseViewer { export { BaseViewer, - ScrollMode, - SpreadMode, }; diff --git a/web/chromecom.js b/web/chromecom.js index 48eecb6ccc35e..88c8f525921fe 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -341,6 +341,8 @@ class ChromePreferences extends BasePreferences { enableHandToolOnLoad: false, disableTextLayer: false, enhanceTextSelection: false, + showPreviousViewOnLoad: true, + disablePageMode: false, }, this.defaults); chrome.storage.managed.get(defaultManagedPrefs, function(items) { @@ -370,6 +372,13 @@ class ChromePreferences extends BasePreferences { delete items.disableTextLayer; delete items.enhanceTextSelection; + // Migration code for https://github.com/mozilla/pdf.js/pull/10502. + if (!items.showPreviousViewOnLoad && !items.viewOnLoad) { + items.viewOnLoad = 1; + } + delete items.showPreviousViewOnLoad; + delete items.disablePageMode; + getPreferences(items); }); } else { diff --git a/web/default_preferences.json b/web/default_preferences.json index 702b5d5a970d2..22a115b44a754 100644 --- a/web/default_preferences.json +++ b/web/default_preferences.json @@ -1,7 +1,7 @@ { - "showPreviousViewOnLoad": true, + "viewOnLoad": 0, "defaultZoomValue": "", - "sidebarViewOnLoad": 0, + "sidebarViewOnLoad": -1, "cursorToolOnLoad": 0, "enableWebGL": false, "eventBusDispatchToDOM": false, @@ -16,10 +16,8 @@ "renderer": "canvas", "renderInteractiveForms": false, "enablePrintAutoRotate": false, - "disableOpenActionDestination": true, - "disablePageMode": false, "disablePageLabels": false, "historyUpdateUrl": false, - "scrollModeOnLoad": 0, - "spreadModeOnLoad": 0 + "scrollModeOnLoad": -1, + "spreadModeOnLoad": -1 } diff --git a/web/pdf_sidebar.js b/web/pdf_sidebar.js index 27a77ad59b11b..80c5b31449d1a 100644 --- a/web/pdf_sidebar.js +++ b/web/pdf_sidebar.js @@ -19,10 +19,12 @@ import { RenderingStates } from './pdf_rendering_queue'; const UI_NOTIFICATION_CLASS = 'pdfSidebarNotification'; const SidebarView = { + UNKNOWN: -1, NONE: 0, - THUMBS: 1, + THUMBS: 1, // Default value. OUTLINE: 2, ATTACHMENTS: 3, + LAYERS: 4, }; /** @@ -130,18 +132,15 @@ class PDFSidebar { } this.isInitialViewSet = true; - if (this.isOpen && view === SidebarView.NONE) { + // If the user has already manually opened the sidebar, immediately closing + // it would be bad UX; also ignore the "unknown" sidebar view value. + if (view === SidebarView.NONE || view === SidebarView.UNKNOWN) { this._dispatchEvent(); - // If the user has already manually opened the sidebar, - // immediately closing it would be bad UX. return; } - let isViewPreserved = (view === this.visibleView); - this.switchView(view, /* forceOpen */ true); - - if (isViewPreserved) { - // Prevent dispatching two back-to-back `sidebarviewchanged` events, - // since `this.switchView` dispatched the event if the view changed. + // Prevent dispatching two back-to-back `sidebarviewchanged` events, + // since `this._switchView` dispatched the event if the view changed. + if (!this._switchView(view, /* forceOpen */ true)) { this._dispatchEvent(); } } @@ -153,14 +152,24 @@ class PDFSidebar { * The default value is `false`. */ switchView(view, forceOpen = false) { - if (view === SidebarView.NONE) { - this.close(); - return; - } - let isViewChanged = (view !== this.active); + this._switchView(view, forceOpen); + } + + /** + * @returns {boolean} Indicating if `this._dispatchEvent` was called. + * @private + */ + _switchView(view, forceOpen = false) { + const isViewChanged = (view !== this.active); let shouldForceRendering = false; switch (view) { + case SidebarView.NONE: + if (this.isOpen) { + this.close(); + return true; // Closing will trigger rendering and dispatch the event. + } + return false; case SidebarView.THUMBS: this.thumbnailButton.classList.add('toggled'); this.outlineButton.classList.remove('toggled'); @@ -177,7 +186,7 @@ class PDFSidebar { break; case SidebarView.OUTLINE: if (this.outlineButton.disabled) { - return; + return false; } this.thumbnailButton.classList.remove('toggled'); this.outlineButton.classList.add('toggled'); @@ -189,7 +198,7 @@ class PDFSidebar { break; case SidebarView.ATTACHMENTS: if (this.attachmentsButton.disabled) { - return; + return false; } this.thumbnailButton.classList.remove('toggled'); this.outlineButton.classList.remove('toggled'); @@ -200,9 +209,8 @@ class PDFSidebar { this.attachmentsView.classList.remove('hidden'); break; default: - console.error('PDFSidebar_switchView: "' + view + - '" is an unsupported value.'); - return; + console.error(`PDFSidebar._switchView: "${view}" is not a valid view.`); + return false; } // Update the active view *after* it has been validated above, // in order to prevent setting it to an invalid state. @@ -210,7 +218,7 @@ class PDFSidebar { if (forceOpen && !this.isOpen) { this.open(); - return; // NOTE: Opening will trigger rendering, and dispatch the event. + return true; // Opening will trigger rendering and dispatch the event. } if (shouldForceRendering) { this._forceRendering(); @@ -219,6 +227,7 @@ class PDFSidebar { this._dispatchEvent(); } this._hideUINotification(this.active); + return isViewChanged; } open() { diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js index b9f6f6701d9fd..4c4c679e75901 100644 --- a/web/secondary_toolbar.js +++ b/web/secondary_toolbar.js @@ -13,10 +13,9 @@ * limitations under the License. */ -import { ScrollMode, SpreadMode } from './base_viewer'; +import { SCROLLBAR_PADDING, ScrollMode, SpreadMode } from './ui_utils'; import { CursorTool } from './pdf_cursor_tools'; import { PDFSinglePageViewer } from './pdf_single_page_viewer'; -import { SCROLLBAR_PADDING } from './ui_utils'; /** * @typedef {Object} SecondaryToolbarOptions diff --git a/web/ui_utils.js b/web/ui_utils.js index f2d9bb05811a1..e1235759ae5ba 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -41,6 +41,20 @@ const TextLayerMode = { ENABLE_ENHANCE: 2, }; +const ScrollMode = { + UNKNOWN: -1, + VERTICAL: 0, // Default value. + HORIZONTAL: 1, + WRAPPED: 2, +}; + +const SpreadMode = { + UNKNOWN: -1, + NONE: 0, // Default value. + ODD: 1, + EVEN: 2, +}; + // Replaces {{arguments}} with their values. function formatL10nValue(text, args) { if (!args) { @@ -602,6 +616,16 @@ function isValidRotation(angle) { return Number.isInteger(angle) && angle % 90 === 0; } +function isValidScrollMode(mode) { + return (Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && + mode !== ScrollMode.UNKNOWN); +} + +function isValidSpreadMode(mode) { + return (Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && + mode !== SpreadMode.UNKNOWN); +} + function isPortraitOrientation(size) { return size.width <= size.height; } @@ -863,10 +887,14 @@ export { SCROLLBAR_PADDING, VERTICAL_PADDING, isValidRotation, + isValidScrollMode, + isValidSpreadMode, isPortraitOrientation, PresentationModeState, RendererType, TextLayerMode, + ScrollMode, + SpreadMode, NullL10n, EventBus, getGlobalEventBus,