Simple restructuring PageView into PDFPageView

This commit is contained in:
Yury Delendik 2014-09-27 13:03:28 -05:00
parent 863d583ae1
commit f68678086d
4 changed files with 585 additions and 556 deletions

View File

@ -197,8 +197,6 @@ var PDFFindController = (function PDFFindControllerClosure() {
}, },
updatePage: function PDFFindController_updatePage(index) { updatePage: function PDFFindController_updatePage(index) {
var page = this.pdfViewer.getPageView(index);
if (this.selected.pageIdx === index) { if (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 textLayer. Once the textLayer is // rendering the page, which adds the textLayer. Once the textLayer is
@ -206,6 +204,7 @@ var PDFFindController = (function PDFFindControllerClosure() {
this.pdfViewer.scrollPageIntoView(index + 1); this.pdfViewer.scrollPageIntoView(index + 1);
} }
var page = this.pdfViewer.getPageView(index);
if (page.textLayer) { if (page.textLayer) {
page.textLayer.updateMatches(); page.textLayer.updateMatches();
} }

View File

@ -20,22 +20,38 @@
'use strict'; 'use strict';
/** /**
* @constructor * @typedef {Object} PDFPageViewOptions
* @param {HTMLDivElement} container - The viewer element. * @property {HTMLDivElement} container - The viewer element.
* @param {number} id - The page unique ID (normally its number). * @property {number} id - The page unique ID (normally its number).
* @param {number} scale - The page scale display. * @property {number} scale - The page scale display.
* @param {PageViewport} defaultViewport - The page viewport. * @property {PageViewport} defaultViewport - The page viewport.
* @param {IPDFLinkService} linkService - The navigation/linking service. * @property {IPDFLinkService} linkService - The navigation/linking service.
* @param {PDFRenderingQueue} renderingQueue - The rendering queue object. * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
* @param {Cache} cache - The page cache. * @property {Cache} cache - The page cache.
* @param {PDFPageSource} pageSource * @property {PDFPageSource} pageSource
* @param {PDFViewer} viewer * @property {PDFViewer} viewer
* */
/**
* @class
* @implements {IRenderableView} * @implements {IRenderableView}
*/ */
var PageView = function pageView(container, id, scale, defaultViewport, var PDFPageView = (function PDFPageViewClosure() {
linkService, renderingQueue, cache, /**
pageSource, viewer) { * @constructs PDFPageView
* @param {PDFPageViewOptions} options
*/
function PDFPageView(options) {
var container = options.container;
var id = options.id;
var scale = options.scale;
var defaultViewport = options.defaultViewport;
var linkService = options.linkService;
var renderingQueue = options.renderingQueue;
var cache = options.cache;
var pageSource = options.pageSource;
var viewer = options.viewer;
this.id = id; this.id = id;
this.renderingId = 'page' + id; this.renderingId = 'page' + id;
@ -63,39 +79,45 @@ var PageView = function pageView(container, id, scale, defaultViewport,
var anchor = document.createElement('a'); var anchor = document.createElement('a');
anchor.name = '' + this.id; anchor.name = '' + this.id;
var div = this.el = document.createElement('div'); var div = document.createElement('div');
div.id = 'pageContainer' + this.id; div.id = 'pageContainer' + this.id;
div.className = 'page'; div.className = 'page';
div.style.width = Math.floor(this.viewport.width) + 'px'; div.style.width = Math.floor(this.viewport.width) + 'px';
div.style.height = Math.floor(this.viewport.height) + 'px'; div.style.height = Math.floor(this.viewport.height) + 'px';
this.el = div; // TODO replace 'el' property usage
this.div = div;
container.appendChild(anchor); container.appendChild(anchor);
container.appendChild(div); container.appendChild(div);
}
this.setPdfPage = function pageViewSetPdfPage(pdfPage) { PDFPageView.prototype = {
setPdfPage: function PDFPageView_setPdfPage(pdfPage) {
this.pdfPage = pdfPage; this.pdfPage = pdfPage;
this.pdfPageRotate = pdfPage.rotate; this.pdfPageRotate = pdfPage.rotate;
var totalRotation = (this.rotation + this.pdfPageRotate) % 360; var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS, totalRotation); this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS,
totalRotation);
this.stats = pdfPage.stats; this.stats = pdfPage.stats;
this.reset(); this.reset();
}; },
this.destroy = function pageViewDestroy() { destroy: function PDFPageView_destroy() {
this.zoomLayer = null; this.zoomLayer = null;
this.reset(); this.reset();
if (this.pdfPage) { if (this.pdfPage) {
this.pdfPage.destroy(); this.pdfPage.destroy();
} }
}; },
this.reset = function pageViewReset(keepAnnotations) { reset: function PDFPageView_reset(keepAnnotations) {
if (this.renderTask) { if (this.renderTask) {
this.renderTask.cancel(); this.renderTask.cancel();
} }
this.resume = null; this.resume = null;
this.renderingState = RenderingStates.INITIAL; this.renderingState = RenderingStates.INITIAL;
var div = this.div;
div.style.width = Math.floor(this.viewport.width) + 'px'; div.style.width = Math.floor(this.viewport.width) + 'px';
div.style.height = Math.floor(this.viewport.height) + 'px'; div.style.height = Math.floor(this.viewport.height) + 'px';
@ -131,9 +153,9 @@ var PageView = function pageView(container, id, scale, defaultViewport,
this.loadingIconDiv = document.createElement('div'); this.loadingIconDiv = document.createElement('div');
this.loadingIconDiv.className = 'loadingIcon'; this.loadingIconDiv.className = 'loadingIcon';
div.appendChild(this.loadingIconDiv); div.appendChild(this.loadingIconDiv);
}; },
this.update = function pageViewUpdate(scale, rotation) { update: function PDFPageView_update(scale, rotation) {
this.scale = scale || this.scale; this.scale = scale || this.scale;
if (typeof rotation !== 'undefined') { if (typeof rotation !== 'undefined') {
@ -172,17 +194,18 @@ var PageView = function pageView(container, id, scale, defaultViewport,
this.cssTransform(this.zoomLayer.firstChild); this.cssTransform(this.zoomLayer.firstChild);
} }
this.reset(true); this.reset(true);
}; },
this.cssTransform = function pageCssTransform(canvas, redrawAnnotations) { cssTransform: function PDFPageView_transform(canvas, redrawAnnotations) {
// Scale canvas, canvas wrapper, and page container. // Scale canvas, canvas wrapper, and page container.
var width = this.viewport.width; var width = this.viewport.width;
var height = this.viewport.height; var height = this.viewport.height;
var div = this.div;
canvas.style.width = canvas.parentNode.style.width = div.style.width = canvas.style.width = canvas.parentNode.style.width = div.style.width =
Math.floor(width) + 'px'; Math.floor(width) + 'px';
canvas.style.height = canvas.parentNode.style.height = div.style.height = canvas.style.height = canvas.parentNode.style.height = div.style.height =
Math.floor(height) + 'px'; Math.floor(height) + 'px';
// The canvas may have been originally rotated, so rotate relative to that. // The canvas may have been originally rotated, rotate relative to that.
var relativeRotation = this.viewport.rotation - canvas._viewport.rotation; var relativeRotation = this.viewport.rotation - canvas._viewport.rotation;
var absRotation = Math.abs(relativeRotation); var absRotation = Math.abs(relativeRotation);
var scaleX = 1, scaleY = 1; var scaleX = 1, scaleY = 1;
@ -238,28 +261,19 @@ var PageView = function pageView(container, id, scale, defaultViewport,
} }
if (redrawAnnotations && this.annotationLayer) { if (redrawAnnotations && this.annotationLayer) {
setupAnnotations(div, this.pdfPage, this.viewport); this.setupAnnotations();
} }
}; },
Object.defineProperty(this, 'width', { get width() {
get: function PageView_getWidth() {
return this.viewport.width; return this.viewport.width;
}, },
enumerable: true
});
Object.defineProperty(this, 'height', { get height() {
get: function PageView_getHeight() {
return this.viewport.height; return this.viewport.height;
}, },
enumerable: true
});
var self = this;
function setupAnnotations(pageDiv, pdfPage, viewport) {
setupAnnotations: function PDFPageView_setupAnnotations() {
function bindLink(link, dest) { function bindLink(link, dest) {
link.href = linkService.getDestinationHash(dest); link.href = linkService.getDestinationHash(dest);
link.onclick = function pageViewSetupLinksOnclick() { link.onclick = function pageViewSetupLinksOnclick() {
@ -282,6 +296,12 @@ var PageView = function pageView(container, id, scale, defaultViewport,
link.className = 'internalLink'; link.className = 'internalLink';
} }
var linkService = this.linkService;
var pageDiv = this.div;
var pdfPage = this.pdfPage;
var viewport = this.viewport;
var self = this;
pdfPage.getAnnotations().then(function(annotationsData) { pdfPage.getAnnotations().then(function(annotationsData) {
viewport = viewport.clone({ dontFlip: true }); viewport = viewport.clone({ dontFlip: true });
var transform = viewport.transform; var transform = viewport.transform;
@ -351,13 +371,13 @@ var PageView = function pageView(container, id, scale, defaultViewport,
} }
} }
}); });
} },
this.getPagePoint = function pageViewGetPagePoint(x, y) { getPagePoint: function PDFPageView_getPagePoint(x, y) {
return this.viewport.convertToPdfPoint(x, y); return this.viewport.convertToPdfPoint(x, y);
}; },
this.draw = function pageviewDraw(callback) { draw: function PDFPageView_draw(callback) {
var pdfPage = this.pdfPage; var pdfPage = this.pdfPage;
if (this.pagePdfPromise) { if (this.pagePdfPromise) {
@ -381,6 +401,7 @@ var PageView = function pageView(container, id, scale, defaultViewport,
this.renderingState = RenderingStates.RUNNING; this.renderingState = RenderingStates.RUNNING;
var viewport = this.viewport; var viewport = this.viewport;
var div = this.div;
// Wrap the canvas so if it has a css transform for highdpi the overflow // Wrap the canvas so if it has a css transform for highdpi the overflow
// will be hidden in FF. // will be hidden in FF.
var canvasWrapper = document.createElement('div'); var canvasWrapper = document.createElement('div');
@ -445,7 +466,8 @@ var PageView = function pageView(container, id, scale, defaultViewport,
div.appendChild(textLayerDiv); div.appendChild(textLayerDiv);
} }
textLayer = this.viewer.createTextLayerBuilder(textLayerDiv, this.id - 1, textLayer = this.viewer.createTextLayerBuilder(textLayerDiv,
this.id - 1,
this.viewport); this.viewport);
} }
this.textLayer = textLayer; this.textLayer = textLayer;
@ -461,9 +483,9 @@ var PageView = function pageView(container, id, scale, defaultViewport,
var self = this; var self = this;
function pageViewDrawCallback(error) { function pageViewDrawCallback(error) {
// The renderTask may have been replaced by a new one, so only remove the // The renderTask may have been replaced by a new one, so only remove
// reference to the renderTask if it matches the one that is triggering // the reference to the renderTask if it matches the one that is
// this callback. // triggering this callback.
if (renderTask === self.renderTask) { if (renderTask === self.renderTask) {
self.renderTask = null; self.renderTask = null;
} }
@ -534,20 +556,20 @@ var PageView = function pageView(container, id, scale, defaultViewport,
} }
); );
setupAnnotations(div, pdfPage, this.viewport); this.setupAnnotations();
div.setAttribute('data-loaded', true); div.setAttribute('data-loaded', true);
// Add the page to the cache at the start of drawing. That way it can be // Add the page to the cache at the start of drawing. That way it can be
// evicted from the cache and destroyed even if we pause its rendering. // evicted from the cache and destroyed even if we pause its rendering.
cache.push(this); this.cache.push(this);
}; },
this.beforePrint = function pageViewBeforePrint() { beforePrint: function PDFPageView_beforePrint() {
var pdfPage = this.pdfPage; var pdfPage = this.pdfPage;
var viewport = pdfPage.getViewport(1); var viewport = pdfPage.getViewport(1);
// Use the same hack we use for high dpi displays for printing to get better // Use the same hack we use for high dpi displays for printing to get
// output until bug 811002 is fixed in FF. // better output until bug 811002 is fixed in FF.
var PRINT_OUTPUT_SCALE = 2; var PRINT_OUTPUT_SCALE = 2;
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
canvas.width = Math.floor(viewport.width) * PRINT_OUTPUT_SCALE; canvas.width = Math.floor(viewport.width) * PRINT_OUTPUT_SCALE;
@ -595,9 +617,9 @@ var PageView = function pageView(container, id, scale, defaultViewport,
} }
}); });
}; };
}; },
this.updateStats = function pageViewUpdateStats() { updateStats: function PDFPageView_updateStats() {
if (!this.stats) { if (!this.stats) {
return; return;
} }
@ -606,5 +628,8 @@ var PageView = function pageView(container, id, scale, defaultViewport,
var stats = this.stats; var stats = this.stats;
Stats.add(this.id, stats); Stats.add(this.id, stats);
} }
},
}; };
};
return PDFPageView;
})();

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*globals watchScroll, Cache, DEFAULT_CACHE_SIZE, PageView, UNKNOWN_SCALE, /*globals watchScroll, Cache, DEFAULT_CACHE_SIZE, PDFPageView, UNKNOWN_SCALE,
SCROLLBAR_PADDING, VERTICAL_PADDING, MAX_AUTO_SCALE, CSS_UNITS, SCROLLBAR_PADDING, VERTICAL_PADDING, MAX_AUTO_SCALE, CSS_UNITS,
DEFAULT_SCALE, scrollIntoView, getVisibleElements, RenderingStates, DEFAULT_SCALE, scrollIntoView, getVisibleElements, RenderingStates,
PDFJS, Promise, TextLayerBuilder, PDFRenderingQueue */ PDFJS, Promise, TextLayerBuilder, PDFRenderingQueue */
@ -236,10 +236,17 @@ var PDFViewer = (function pdfViewer() {
var viewport = pdfPage.getViewport(scale * CSS_UNITS); var viewport = pdfPage.getViewport(scale * CSS_UNITS);
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
var pageSource = new PDFPageSource(pdfDocument, pageNum); var pageSource = new PDFPageSource(pdfDocument, pageNum);
var pageView = new PageView(this.viewer, pageNum, scale, var pageView = new PDFPageView({
viewport.clone(), this.linkService, container: this.viewer,
this.renderingQueue, this.cache, id: pageNum,
pageSource, this); scale: scale,
defaultViewport: viewport.clone(),
linkService: this.linkService,
renderingQueue: this.renderingQueue,
cache: this.cache,
pageSource: pageSource,
viewer: this
});
bindOnAfterDraw(pageView); bindOnAfterDraw(pageView);
this.pages.push(pageView); this.pages.push(pageView);
} }
@ -398,7 +405,6 @@ var PDFViewer = (function pdfViewer() {
scrollPageIntoView: function PDFViewer_scrollPageIntoView(pageNumber, scrollPageIntoView: function PDFViewer_scrollPageIntoView(pageNumber,
dest) { dest) {
var pageView = this.pages[pageNumber - 1]; var pageView = this.pages[pageNumber - 1];
var pageViewDiv = pageView.el;
if (this.presentationModeState === if (this.presentationModeState ===
PresentationModeState.FULLSCREEN) { PresentationModeState.FULLSCREEN) {
@ -412,7 +418,7 @@ var PDFViewer = (function pdfViewer() {
this._setScale(this.currentScaleValue, true); this._setScale(this.currentScaleValue, true);
} }
if (!dest) { if (!dest) {
scrollIntoView(pageViewDiv); scrollIntoView(pageView.div);
return; return;
} }
@ -475,7 +481,7 @@ var PDFViewer = (function pdfViewer() {
} }
if (scale === 'page-fit' && !dest[4]) { if (scale === 'page-fit' && !dest[4]) {
scrollIntoView(pageViewDiv); scrollIntoView(pageView.div);
return; return;
} }
@ -486,7 +492,7 @@ var PDFViewer = (function pdfViewer() {
var left = Math.min(boundingRect[0][0], boundingRect[1][0]); var left = Math.min(boundingRect[0][0], boundingRect[1][0]);
var top = Math.min(boundingRect[0][1], boundingRect[1][1]); var top = Math.min(boundingRect[0][1], boundingRect[1][1]);
scrollIntoView(pageViewDiv, { left: left, top: top }); scrollIntoView(pageView.div, { left: left, top: top });
}, },
_updateLocation: function (firstPage) { _updateLocation: function (firstPage) {

View File

@ -16,7 +16,7 @@
*/ */
/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, ProgressBar, /* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, ProgressBar,
DownloadManager, getFileName, scrollIntoView, getPDFFileNameFromURL, DownloadManager, getFileName, scrollIntoView, getPDFFileNameFromURL,
PDFHistory, Preferences, SidebarView, ViewHistory, PageView, PDFHistory, Preferences, SidebarView, ViewHistory,
PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar, PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar,
PasswordPrompt, PresentationMode, HandTool, Promise, PasswordPrompt, PresentationMode, HandTool, Promise,
DocumentProperties, DocumentOutlineView, DocumentAttachmentsView, DocumentProperties, DocumentOutlineView, DocumentAttachmentsView,
@ -1353,7 +1353,6 @@ var PDFViewerApplication = {
rotatePages: function pdfViewRotatePages(delta) { rotatePages: function pdfViewRotatePages(delta) {
var pageNumber = this.page; var pageNumber = this.page;
this.pageRotation = (this.pageRotation + 360 + delta) % 360; this.pageRotation = (this.pageRotation + 360 + delta) % 360;
this.pdfViewer.pagesRotation = this.pageRotation; this.pdfViewer.pagesRotation = this.pageRotation;
this.pdfThumbnailViewer.pagesRotation = this.pageRotation; this.pdfThumbnailViewer.pagesRotation = this.pageRotation;