Merge pull request #8868 from Snuffleupagus/save-rotation
Store the rotation in the `ViewHistory`/`PDFHistory` (issue 5927)
This commit is contained in:
commit
e6d05be41a
@ -14,8 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
binarySearchFirstItem, EventBus, getPDFFileNameFromURL, waitOnEventOrTimeout,
|
binarySearchFirstItem, EventBus, getPDFFileNameFromURL, isValidRotation,
|
||||||
WaitOnType
|
waitOnEventOrTimeout, WaitOnType
|
||||||
} from '../../web/ui_utils';
|
} from '../../web/ui_utils';
|
||||||
import { createObjectURL, isNodeJS } from '../../src/shared/util';
|
import { createObjectURL, isNodeJS } from '../../src/shared/util';
|
||||||
|
|
||||||
@ -261,6 +261,29 @@ describe('ui_utils', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isValidRotation', function() {
|
||||||
|
it('should reject non-integer angles', function() {
|
||||||
|
expect(isValidRotation()).toEqual(false);
|
||||||
|
expect(isValidRotation(null)).toEqual(false);
|
||||||
|
expect(isValidRotation(NaN)).toEqual(false);
|
||||||
|
expect(isValidRotation([90])).toEqual(false);
|
||||||
|
expect(isValidRotation('90')).toEqual(false);
|
||||||
|
expect(isValidRotation(90.5)).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject non-multiple of 90 degree angles', function() {
|
||||||
|
expect(isValidRotation(45)).toEqual(false);
|
||||||
|
expect(isValidRotation(-123)).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept valid angles', function() {
|
||||||
|
expect(isValidRotation(0)).toEqual(true);
|
||||||
|
expect(isValidRotation(90)).toEqual(true);
|
||||||
|
expect(isValidRotation(-270)).toEqual(true);
|
||||||
|
expect(isValidRotation(540)).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('waitOnEventOrTimeout', function() {
|
describe('waitOnEventOrTimeout', function() {
|
||||||
let eventBus;
|
let eventBus;
|
||||||
|
|
||||||
|
53
web/app.js
53
web/app.js
@ -15,9 +15,9 @@
|
|||||||
/* globals PDFBug, Stats */
|
/* globals PDFBug, Stats */
|
||||||
|
|
||||||
import {
|
import {
|
||||||
animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, MAX_SCALE,
|
animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, isValidRotation,
|
||||||
MIN_SCALE, noContextMenuHandler, normalizeWheelEventDelta, parseQueryString,
|
MAX_SCALE, MIN_SCALE, noContextMenuHandler, normalizeWheelEventDelta,
|
||||||
ProgressBar, RendererType
|
parseQueryString, ProgressBar, RendererType
|
||||||
} from './ui_utils';
|
} from './ui_utils';
|
||||||
import {
|
import {
|
||||||
build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException,
|
build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException,
|
||||||
@ -935,6 +935,8 @@ let PDFViewerApplication = {
|
|||||||
|
|
||||||
if (this.pdfHistory.initialBookmark) {
|
if (this.pdfHistory.initialBookmark) {
|
||||||
this.initialBookmark = this.pdfHistory.initialBookmark;
|
this.initialBookmark = this.pdfHistory.initialBookmark;
|
||||||
|
|
||||||
|
this.initialRotation = this.pdfHistory.initialRotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,6 +950,7 @@ let PDFViewerApplication = {
|
|||||||
zoom: DEFAULT_SCALE_VALUE,
|
zoom: DEFAULT_SCALE_VALUE,
|
||||||
scrollLeft: '0',
|
scrollLeft: '0',
|
||||||
scrollTop: '0',
|
scrollTop: '0',
|
||||||
|
rotation: null,
|
||||||
sidebarView: SidebarView.NONE,
|
sidebarView: SidebarView.NONE,
|
||||||
}).catch(() => { /* Unable to read from storage; ignoring errors. */ });
|
}).catch(() => { /* Unable to read from storage; ignoring errors. */ });
|
||||||
|
|
||||||
@ -956,12 +959,14 @@ let PDFViewerApplication = {
|
|||||||
// Initialize the default values, from user preferences.
|
// Initialize the default values, from user preferences.
|
||||||
let hash = this.viewerPrefs['defaultZoomValue'] ?
|
let hash = this.viewerPrefs['defaultZoomValue'] ?
|
||||||
('zoom=' + this.viewerPrefs['defaultZoomValue']) : null;
|
('zoom=' + this.viewerPrefs['defaultZoomValue']) : null;
|
||||||
|
let rotation = null;
|
||||||
let sidebarView = this.viewerPrefs['sidebarViewOnLoad'];
|
let sidebarView = this.viewerPrefs['sidebarViewOnLoad'];
|
||||||
|
|
||||||
if (values.exists && this.viewerPrefs['showPreviousViewOnLoad']) {
|
if (values.exists && this.viewerPrefs['showPreviousViewOnLoad']) {
|
||||||
hash = 'page=' + values.page +
|
hash = 'page=' + values.page +
|
||||||
'&zoom=' + (this.viewerPrefs['defaultZoomValue'] || values.zoom) +
|
'&zoom=' + (this.viewerPrefs['defaultZoomValue'] || values.zoom) +
|
||||||
',' + values.scrollLeft + ',' + values.scrollTop;
|
',' + values.scrollLeft + ',' + values.scrollTop;
|
||||||
|
rotation = parseInt(values.rotation, 10);
|
||||||
sidebarView = sidebarView || (values.sidebarView | 0);
|
sidebarView = sidebarView || (values.sidebarView | 0);
|
||||||
}
|
}
|
||||||
if (pageMode && !this.viewerPrefs['disablePageMode']) {
|
if (pageMode && !this.viewerPrefs['disablePageMode']) {
|
||||||
@ -970,13 +975,14 @@ let PDFViewerApplication = {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
hash,
|
hash,
|
||||||
|
rotation,
|
||||||
sidebarView,
|
sidebarView,
|
||||||
};
|
};
|
||||||
}).then(({ hash, sidebarView, }) => {
|
}).then(({ hash, rotation, sidebarView, }) => {
|
||||||
initialParams.bookmark = this.initialBookmark;
|
initialParams.bookmark = this.initialBookmark;
|
||||||
initialParams.hash = hash;
|
initialParams.hash = hash;
|
||||||
|
|
||||||
this.setInitialView(hash, { sidebarView, });
|
this.setInitialView(hash, { rotation, sidebarView, });
|
||||||
|
|
||||||
// Make all navigation keys work on document load,
|
// Make all navigation keys work on document load,
|
||||||
// unless the viewer is embedded in a web page.
|
// unless the viewer is embedded in a web page.
|
||||||
@ -1131,14 +1137,24 @@ let PDFViewerApplication = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setInitialView(storedHash, { sidebarView, } = {}) {
|
setInitialView(storedHash, { rotation, sidebarView, } = {}) {
|
||||||
|
let setRotation = (angle) => {
|
||||||
|
if (isValidRotation(angle)) {
|
||||||
|
this.pdfViewer.pagesRotation = angle;
|
||||||
|
}
|
||||||
|
};
|
||||||
this.isInitialViewSet = true;
|
this.isInitialViewSet = true;
|
||||||
this.pdfSidebar.setInitialView(sidebarView);
|
this.pdfSidebar.setInitialView(sidebarView);
|
||||||
|
|
||||||
if (this.initialBookmark) {
|
if (this.initialBookmark) {
|
||||||
|
setRotation(this.initialRotation);
|
||||||
|
delete this.initialRotation;
|
||||||
|
|
||||||
this.pdfLinkService.setHash(this.initialBookmark);
|
this.pdfLinkService.setHash(this.initialBookmark);
|
||||||
this.initialBookmark = null;
|
this.initialBookmark = null;
|
||||||
} else if (storedHash) {
|
} else if (storedHash) {
|
||||||
|
setRotation(rotation);
|
||||||
|
|
||||||
this.pdfLinkService.setHash(storedHash);
|
this.pdfLinkService.setHash(storedHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1232,16 +1248,10 @@ let PDFViewerApplication = {
|
|||||||
if (!this.pdfDocument) {
|
if (!this.pdfDocument) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let { pdfViewer, pdfThumbnailViewer, } = this;
|
let newRotation = (this.pdfViewer.pagesRotation + 360 + delta) % 360;
|
||||||
let pageNumber = pdfViewer.currentPageNumber;
|
this.pdfViewer.pagesRotation = newRotation;
|
||||||
let newRotation = (pdfViewer.pagesRotation + 360 + delta) % 360;
|
// Note that the thumbnail viewer is updated, and rendering is triggered,
|
||||||
|
// in the 'rotationchanging' event handler.
|
||||||
pdfViewer.pagesRotation = newRotation;
|
|
||||||
pdfThumbnailViewer.pagesRotation = newRotation;
|
|
||||||
|
|
||||||
this.forceRendering();
|
|
||||||
// Ensure that the active page doesn't change during rotation.
|
|
||||||
pdfViewer.currentPageNumber = pageNumber;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
requestPresentationMode() {
|
requestPresentationMode() {
|
||||||
@ -1266,6 +1276,7 @@ let PDFViewerApplication = {
|
|||||||
eventBus.on('updateviewarea', webViewerUpdateViewarea);
|
eventBus.on('updateviewarea', webViewerUpdateViewarea);
|
||||||
eventBus.on('pagechanging', webViewerPageChanging);
|
eventBus.on('pagechanging', webViewerPageChanging);
|
||||||
eventBus.on('scalechanging', webViewerScaleChanging);
|
eventBus.on('scalechanging', webViewerScaleChanging);
|
||||||
|
eventBus.on('rotationchanging', webViewerRotationChanging);
|
||||||
eventBus.on('sidebarviewchanged', webViewerSidebarViewChanged);
|
eventBus.on('sidebarviewchanged', webViewerSidebarViewChanged);
|
||||||
eventBus.on('pagemode', webViewerPageMode);
|
eventBus.on('pagemode', webViewerPageMode);
|
||||||
eventBus.on('namedaction', webViewerNamedAction);
|
eventBus.on('namedaction', webViewerNamedAction);
|
||||||
@ -1343,6 +1354,7 @@ let PDFViewerApplication = {
|
|||||||
eventBus.off('updateviewarea', webViewerUpdateViewarea);
|
eventBus.off('updateviewarea', webViewerUpdateViewarea);
|
||||||
eventBus.off('pagechanging', webViewerPageChanging);
|
eventBus.off('pagechanging', webViewerPageChanging);
|
||||||
eventBus.off('scalechanging', webViewerScaleChanging);
|
eventBus.off('scalechanging', webViewerScaleChanging);
|
||||||
|
eventBus.off('rotationchanging', webViewerRotationChanging);
|
||||||
eventBus.off('sidebarviewchanged', webViewerSidebarViewChanged);
|
eventBus.off('sidebarviewchanged', webViewerSidebarViewChanged);
|
||||||
eventBus.off('pagemode', webViewerPageMode);
|
eventBus.off('pagemode', webViewerPageMode);
|
||||||
eventBus.off('namedaction', webViewerNamedAction);
|
eventBus.off('namedaction', webViewerNamedAction);
|
||||||
@ -1769,6 +1781,7 @@ function webViewerUpdateViewarea(evt) {
|
|||||||
'zoom': location.scale,
|
'zoom': location.scale,
|
||||||
'scrollLeft': location.left,
|
'scrollLeft': location.left,
|
||||||
'scrollTop': location.top,
|
'scrollTop': location.top,
|
||||||
|
'rotation': location.rotation,
|
||||||
}).catch(function() { /* unable to write to storage */ });
|
}).catch(function() { /* unable to write to storage */ });
|
||||||
}
|
}
|
||||||
let href =
|
let href =
|
||||||
@ -1926,6 +1939,14 @@ function webViewerScaleChanging(evt) {
|
|||||||
PDFViewerApplication.pdfViewer.update();
|
PDFViewerApplication.pdfViewer.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function webViewerRotationChanging(evt) {
|
||||||
|
PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;
|
||||||
|
|
||||||
|
PDFViewerApplication.forceRendering();
|
||||||
|
// Ensure that the active page doesn't change during rotation.
|
||||||
|
PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
function webViewerPageChanging(evt) {
|
function webViewerPageChanging(evt) {
|
||||||
let page = evt.pageNumber;
|
let page = evt.pageNumber;
|
||||||
|
|
||||||
|
@ -30,6 +30,16 @@ class IPDFLinkService {
|
|||||||
*/
|
*/
|
||||||
set page(value) {}
|
set page(value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get rotation() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
set rotation(value) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dest - The PDF destination object.
|
* @param dest - The PDF destination object.
|
||||||
*/
|
*/
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { cloneObj, parseQueryString, waitOnEventOrTimeout } from './ui_utils';
|
import {
|
||||||
|
cloneObj, isValidRotation, parseQueryString, waitOnEventOrTimeout
|
||||||
|
} from './ui_utils';
|
||||||
import { getGlobalEventBus } from './dom_events';
|
import { getGlobalEventBus } from './dom_events';
|
||||||
|
|
||||||
// Heuristic value used when force-resetting `this._blockHashChange`.
|
// Heuristic value used when force-resetting `this._blockHashChange`.
|
||||||
@ -49,7 +51,7 @@ function parseCurrentHash(linkService) {
|
|||||||
if (!(Number.isInteger(page) && page > 0 && page <= linkService.pagesCount)) {
|
if (!(Number.isInteger(page) && page > 0 && page <= linkService.pagesCount)) {
|
||||||
page = null;
|
page = null;
|
||||||
}
|
}
|
||||||
return { hash, page, };
|
return { hash, page, rotation: linkService.rotation, };
|
||||||
}
|
}
|
||||||
|
|
||||||
class PDFHistory {
|
class PDFHistory {
|
||||||
@ -62,6 +64,7 @@ class PDFHistory {
|
|||||||
|
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
this.initialBookmark = null;
|
this.initialBookmark = null;
|
||||||
|
this.initialRotation = null;
|
||||||
|
|
||||||
this._boundEvents = Object.create(null);
|
this._boundEvents = Object.create(null);
|
||||||
this._isViewerInPresentationMode = false;
|
this._isViewerInPresentationMode = false;
|
||||||
@ -99,6 +102,7 @@ class PDFHistory {
|
|||||||
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
this.initialBookmark = null;
|
this.initialBookmark = null;
|
||||||
|
this.initialRotation = null;
|
||||||
|
|
||||||
this._popStateInProgress = false;
|
this._popStateInProgress = false;
|
||||||
this._blockHashChange = 0;
|
this._blockHashChange = 0;
|
||||||
@ -110,7 +114,7 @@ class PDFHistory {
|
|||||||
this._position = null;
|
this._position = null;
|
||||||
|
|
||||||
if (!this._isValidState(state) || resetHistory) {
|
if (!this._isValidState(state) || resetHistory) {
|
||||||
let { hash, page, } = parseCurrentHash(this.linkService);
|
let { hash, page, rotation, } = parseCurrentHash(this.linkService);
|
||||||
|
|
||||||
if (!hash || reInitialized || resetHistory) {
|
if (!hash || reInitialized || resetHistory) {
|
||||||
// Ensure that the browser history is reset on PDF document load.
|
// Ensure that the browser history is reset on PDF document load.
|
||||||
@ -119,7 +123,8 @@ class PDFHistory {
|
|||||||
}
|
}
|
||||||
// Ensure that the browser history is initialized correctly when
|
// Ensure that the browser history is initialized correctly when
|
||||||
// the document hash is present on PDF document load.
|
// the document hash is present on PDF document load.
|
||||||
this._pushOrReplaceState({ hash, page, }, /* forceReplace = */ true);
|
this._pushOrReplaceState({ hash, page, rotation, },
|
||||||
|
/* forceReplace = */ true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +133,10 @@ class PDFHistory {
|
|||||||
let destination = state.destination;
|
let destination = state.destination;
|
||||||
this._updateInternalState(destination, state.uid,
|
this._updateInternalState(destination, state.uid,
|
||||||
/* removeTemporary = */ true);
|
/* removeTemporary = */ true);
|
||||||
|
|
||||||
|
if (destination.rotation !== undefined) {
|
||||||
|
this.initialRotation = destination.rotation;
|
||||||
|
}
|
||||||
if (destination.dest) {
|
if (destination.dest) {
|
||||||
this.initialBookmark = JSON.stringify(destination.dest);
|
this.initialBookmark = JSON.stringify(destination.dest);
|
||||||
|
|
||||||
@ -188,6 +197,7 @@ class PDFHistory {
|
|||||||
dest: explicitDest,
|
dest: explicitDest,
|
||||||
hash,
|
hash,
|
||||||
page: pageNumber,
|
page: pageNumber,
|
||||||
|
rotation: this.linkService.rotation,
|
||||||
}, forceReplace);
|
}, forceReplace);
|
||||||
|
|
||||||
if (!this._popStateInProgress) {
|
if (!this._popStateInProgress) {
|
||||||
@ -402,6 +412,7 @@ class PDFHistory {
|
|||||||
`page=${location.pageNumber}` : location.pdfOpenParams.substring(1),
|
`page=${location.pageNumber}` : location.pdfOpenParams.substring(1),
|
||||||
page: this.linkService.page,
|
page: this.linkService.page,
|
||||||
first: location.pageNumber,
|
first: location.pageNumber,
|
||||||
|
rotation: location.rotation,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this._popStateInProgress) {
|
if (this._popStateInProgress) {
|
||||||
@ -459,8 +470,9 @@ class PDFHistory {
|
|||||||
// This case corresponds to the user changing the hash of the document.
|
// This case corresponds to the user changing the hash of the document.
|
||||||
this._currentUid = this._uid;
|
this._currentUid = this._uid;
|
||||||
|
|
||||||
let { hash, page, } = parseCurrentHash(this.linkService);
|
let { hash, page, rotation, } = parseCurrentHash(this.linkService);
|
||||||
this._pushOrReplaceState({ hash, page, }, /* forceReplace */ true);
|
this._pushOrReplaceState({ hash, page, rotation, },
|
||||||
|
/* forceReplace = */ true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this._isValidState(state)) {
|
if (!this._isValidState(state)) {
|
||||||
@ -497,6 +509,10 @@ class PDFHistory {
|
|||||||
let destination = state.destination;
|
let destination = state.destination;
|
||||||
this._updateInternalState(destination, state.uid,
|
this._updateInternalState(destination, state.uid,
|
||||||
/* removeTemporary = */ true);
|
/* removeTemporary = */ true);
|
||||||
|
|
||||||
|
if (isValidRotation(destination.rotation)) {
|
||||||
|
this.linkService.rotation = destination.rotation;
|
||||||
|
}
|
||||||
if (destination.dest) {
|
if (destination.dest) {
|
||||||
this.linkService.navigateTo(destination.dest);
|
this.linkService.navigateTo(destination.dest);
|
||||||
} else if (destination.hash) {
|
} else if (destination.hash) {
|
||||||
|
@ -75,6 +75,20 @@ class PDFLinkService {
|
|||||||
this.pdfViewer.currentPageNumber = value;
|
this.pdfViewer.currentPageNumber = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get rotation() {
|
||||||
|
return this.pdfViewer.pagesRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
set rotation(value) {
|
||||||
|
this.pdfViewer.pagesRotation = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string|Array} dest - The named, or explicit, PDF destination.
|
* @param {string|Array} dest - The named, or explicit, PDF destination.
|
||||||
*/
|
*/
|
||||||
@ -413,6 +427,16 @@ class SimpleLinkService {
|
|||||||
* @param {number} value
|
* @param {number} value
|
||||||
*/
|
*/
|
||||||
set page(value) {}
|
set page(value) {}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get rotation() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
set rotation(value) {}
|
||||||
/**
|
/**
|
||||||
* @param dest - The PDF destination object.
|
* @param dest - The PDF destination object.
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getVisibleElements, NullL10n, scrollIntoView, watchScroll
|
getVisibleElements, isValidRotation, NullL10n, scrollIntoView, watchScroll
|
||||||
} from './ui_utils';
|
} from './ui_utils';
|
||||||
import { PDFThumbnailView } from './pdf_thumbnail_view';
|
import { PDFThumbnailView } from './pdf_thumbnail_view';
|
||||||
|
|
||||||
@ -95,12 +95,15 @@ class PDFThumbnailViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set pagesRotation(rotation) {
|
set pagesRotation(rotation) {
|
||||||
if (!(typeof rotation === 'number' && rotation % 90 === 0)) {
|
if (!isValidRotation(rotation)) {
|
||||||
throw new Error('Invalid thumbnails rotation angle.');
|
throw new Error('Invalid thumbnails rotation angle.');
|
||||||
}
|
}
|
||||||
if (!this.pdfDocument) {
|
if (!this.pdfDocument) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this._pagesRotation === rotation) {
|
||||||
|
return; // The rotation didn't change.
|
||||||
|
}
|
||||||
this._pagesRotation = rotation;
|
this._pagesRotation = rotation;
|
||||||
|
|
||||||
for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {
|
for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
import { createPromiseCapability, PDFJS } from 'pdfjs-lib';
|
import { createPromiseCapability, PDFJS } from 'pdfjs-lib';
|
||||||
import {
|
import {
|
||||||
CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, getVisibleElements,
|
CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, getVisibleElements,
|
||||||
MAX_AUTO_SCALE, NullL10n, RendererType, SCROLLBAR_PADDING, scrollIntoView,
|
isValidRotation, MAX_AUTO_SCALE, NullL10n, RendererType, SCROLLBAR_PADDING,
|
||||||
UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll
|
scrollIntoView, UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll
|
||||||
} from './ui_utils';
|
} from './ui_utils';
|
||||||
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
|
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
|
||||||
import { AnnotationLayerBuilder } from './annotation_layer_builder';
|
import { AnnotationLayerBuilder } from './annotation_layer_builder';
|
||||||
@ -271,20 +271,34 @@ class PDFViewer {
|
|||||||
* @param {number} rotation - The rotation of the pages (0, 90, 180, 270).
|
* @param {number} rotation - The rotation of the pages (0, 90, 180, 270).
|
||||||
*/
|
*/
|
||||||
set pagesRotation(rotation) {
|
set pagesRotation(rotation) {
|
||||||
if (!(typeof rotation === 'number' && rotation % 90 === 0)) {
|
if (!isValidRotation(rotation)) {
|
||||||
throw new Error('Invalid pages rotation angle.');
|
throw new Error('Invalid pages rotation angle.');
|
||||||
}
|
}
|
||||||
if (!this.pdfDocument) {
|
if (!this.pdfDocument) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this._pagesRotation === rotation) {
|
||||||
|
return; // The rotation didn't change.
|
||||||
|
}
|
||||||
this._pagesRotation = rotation;
|
this._pagesRotation = rotation;
|
||||||
|
|
||||||
|
let pageNumber = this._currentPageNumber;
|
||||||
|
|
||||||
for (let i = 0, ii = this._pages.length; i < ii; i++) {
|
for (let i = 0, ii = this._pages.length; i < ii; i++) {
|
||||||
let pageView = this._pages[i];
|
let pageView = this._pages[i];
|
||||||
pageView.update(pageView.scale, rotation);
|
pageView.update(pageView.scale, rotation);
|
||||||
}
|
}
|
||||||
|
// Prevent errors in case the rotation changes *before* the scale has been
|
||||||
|
// set to a non-default value.
|
||||||
|
if (this._currentScaleValue) {
|
||||||
|
this._setScale(this._currentScaleValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
this._setScale(this._currentScaleValue, true);
|
this.eventBus.dispatch('rotationchanging', {
|
||||||
|
source: this,
|
||||||
|
pagesRotation: rotation,
|
||||||
|
pageNumber,
|
||||||
|
});
|
||||||
|
|
||||||
if (this.defaultRenderingQueue) {
|
if (this.defaultRenderingQueue) {
|
||||||
this.update();
|
this.update();
|
||||||
@ -718,6 +732,7 @@ class PDFViewer {
|
|||||||
scale: normalizedScaleValue,
|
scale: normalizedScaleValue,
|
||||||
top: intTop,
|
top: intTop,
|
||||||
left: intLeft,
|
left: intLeft,
|
||||||
|
rotation: this._pagesRotation,
|
||||||
pdfOpenParams,
|
pdfOpenParams,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -443,6 +443,10 @@ function normalizeWheelEventDelta(evt) {
|
|||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidRotation(angle) {
|
||||||
|
return Number.isInteger(angle) && angle % 90 === 0;
|
||||||
|
}
|
||||||
|
|
||||||
function cloneObj(obj) {
|
function cloneObj(obj) {
|
||||||
let result = Object.create(null);
|
let result = Object.create(null);
|
||||||
for (let i in obj) {
|
for (let i in obj) {
|
||||||
@ -655,6 +659,7 @@ export {
|
|||||||
MAX_AUTO_SCALE,
|
MAX_AUTO_SCALE,
|
||||||
SCROLLBAR_PADDING,
|
SCROLLBAR_PADDING,
|
||||||
VERTICAL_PADDING,
|
VERTICAL_PADDING,
|
||||||
|
isValidRotation,
|
||||||
cloneObj,
|
cloneObj,
|
||||||
RendererType,
|
RendererType,
|
||||||
mozL10n,
|
mozL10n,
|
||||||
|
Loading…
Reference in New Issue
Block a user