Merge pull request #4552 from dferer/annotations-refresh

Prevent the annotationLayer from being recreated when the page is redrawn
This commit is contained in:
Yury Delendik 2014-04-16 08:09:53 -05:00
commit 7069753d64
2 changed files with 87 additions and 54 deletions

View File

@ -129,6 +129,7 @@ var Annotation = (function AnnotationClosure() {
this.appearance = getDefaultAppearance(dict); this.appearance = getDefaultAppearance(dict);
data.hasAppearance = !!this.appearance; data.hasAppearance = !!this.appearance;
data.id = params.ref.num;
} }
Annotation.prototype = { Annotation.prototype = {

View File

@ -68,7 +68,7 @@ var PageView = function pageView(container, id, scale,
} }
}; };
this.reset = function pageViewReset() { this.reset = function pageViewReset(keepAnnotations) {
if (this.renderTask) { if (this.renderTask) {
this.renderTask.cancel(); this.renderTask.cancel();
} }
@ -81,14 +81,23 @@ var PageView = function pageView(container, id, scale,
var childNodes = div.childNodes; var childNodes = div.childNodes;
for (var i = div.childNodes.length - 1; i >= 0; i--) { for (var i = div.childNodes.length - 1; i >= 0; i--) {
var node = childNodes[i]; var node = childNodes[i];
if (this.zoomLayer && this.zoomLayer === node) { if ((this.zoomLayer && this.zoomLayer === node) ||
(keepAnnotations && this.annotationLayer === node)) {
continue; continue;
} }
div.removeChild(node); div.removeChild(node);
} }
div.removeAttribute('data-loaded'); div.removeAttribute('data-loaded');
this.annotationLayer = null; if (keepAnnotations) {
if (this.annotationLayer) {
// Hide annotationLayer until all elements are resized
// so they are not displayed on the already-resized page
this.annotationLayer.setAttribute('hidden', 'true');
}
} else {
this.annotationLayer = null;
}
delete this.canvas; delete this.canvas;
@ -120,7 +129,7 @@ var PageView = function pageView(container, id, scale,
if (this.zoomLayer) { if (this.zoomLayer) {
this.cssTransform(this.zoomLayer.firstChild); this.cssTransform(this.zoomLayer.firstChild);
} }
this.reset(); this.reset(true);
}; };
this.cssTransform = function pageCssTransform(canvas) { this.cssTransform = function pageCssTransform(canvas) {
@ -269,60 +278,73 @@ var PageView = function pageView(container, id, scale,
} }
pdfPage.getAnnotations().then(function(annotationsData) { pdfPage.getAnnotations().then(function(annotationsData) {
if (self.annotationLayer) {
// If an annotationLayer already exists, delete it to avoid creating
// duplicate annotations when rapidly re-zooming the document.
pageDiv.removeChild(self.annotationLayer);
self.annotationLayer = null;
}
viewport = viewport.clone({ dontFlip: true }); viewport = viewport.clone({ dontFlip: true });
for (var i = 0; i < annotationsData.length; i++) { var transform = viewport.transform;
var data = annotationsData[i]; var transformStr = 'matrix(' + transform.join(',') + ')';
var annotation = PDFJS.Annotation.fromData(data); var data, element, i, ii;
if (!annotation || !annotation.hasHtml()) {
continue;
}
var element = annotation.getHtmlElement(pdfPage.commonObjs); if (self.annotationLayer) {
mozL10n.translate(element); // If an annotationLayer already exists, refresh its children's
// transformation matrices
data = annotation.getData(); for (i = 0, ii = annotationsData.length; i < ii; i++) {
var rect = data.rect; data = annotationsData[i];
var view = pdfPage.view; element = self.annotationLayer.querySelector(
rect = PDFJS.Util.normalizeRect([ '[data-annotation-id="' + data.id + '"]');
rect[0], if (element) {
view[3] - rect[1] + view[1], CustomStyle.setProp('transform', element, transformStr);
rect[2],
view[3] - rect[3] + view[1]
]);
element.style.left = rect[0] + 'px';
element.style.top = rect[1] + 'px';
element.style.position = 'absolute';
var transform = viewport.transform;
var transformStr = 'matrix(' + transform.join(',') + ')';
CustomStyle.setProp('transform', element, transformStr);
var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
CustomStyle.setProp('transformOrigin', element, transformOriginStr);
if (data.subtype === 'Link' && !data.url) {
var link = element.getElementsByTagName('a')[0];
if (link) {
if (data.action) {
bindNamedAction(link, data.action);
} else {
bindLink(link, ('dest' in data) ? data.dest : null);
}
} }
} }
// See this.reset()
self.annotationLayer.removeAttribute('hidden');
} else {
for (i = 0, ii = annotationsData.length; i < ii; i++) {
data = annotationsData[i];
var annotation = PDFJS.Annotation.fromData(data);
if (!annotation || !annotation.hasHtml()) {
continue;
}
if (!self.annotationLayer) { element = annotation.getHtmlElement(pdfPage.commonObjs);
var annotationLayerDiv = document.createElement('div'); element.setAttribute('data-annotation-id', data.id);
annotationLayerDiv.className = 'annotationLayer'; mozL10n.translate(element);
pageDiv.appendChild(annotationLayerDiv);
self.annotationLayer = annotationLayerDiv; data = annotation.getData();
var rect = data.rect;
var view = pdfPage.view;
rect = PDFJS.Util.normalizeRect([
rect[0],
view[3] - rect[1] + view[1],
rect[2],
view[3] - rect[3] + view[1]
]);
element.style.left = rect[0] + 'px';
element.style.top = rect[1] + 'px';
element.style.position = 'absolute';
CustomStyle.setProp('transform', element, transformStr);
var transformOriginStr = -rect[0] + 'px ' + -rect[1] + 'px';
CustomStyle.setProp('transformOrigin', element, transformOriginStr);
if (data.subtype === 'Link' && !data.url) {
var link = element.getElementsByTagName('a')[0];
if (link) {
if (data.action) {
bindNamedAction(link, data.action);
} else {
bindLink(link, ('dest' in data) ? data.dest : null);
}
}
}
if (!self.annotationLayer) {
var annotationLayerDiv = document.createElement('div');
annotationLayerDiv.className = 'annotationLayer';
pageDiv.appendChild(annotationLayerDiv);
self.annotationLayer = annotationLayerDiv;
}
self.annotationLayer.appendChild(element);
} }
self.annotationLayer.appendChild(element);
} }
}); });
} }
@ -458,7 +480,12 @@ var PageView = function pageView(container, id, scale,
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
canvas.id = 'page' + this.id; canvas.id = 'page' + this.id;
canvasWrapper.appendChild(canvas); canvasWrapper.appendChild(canvas);
div.appendChild(canvasWrapper); if (this.annotationLayer) {
// annotationLayer needs to stay on top
div.insertBefore(canvasWrapper, this.annotationLayer);
} else {
div.appendChild(canvasWrapper);
}
this.canvas = canvas; this.canvas = canvas;
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
@ -486,7 +513,12 @@ var PageView = function pageView(container, id, scale,
textLayerDiv.className = 'textLayer'; textLayerDiv.className = 'textLayer';
textLayerDiv.style.width = canvas.style.width; textLayerDiv.style.width = canvas.style.width;
textLayerDiv.style.height = canvas.style.height; textLayerDiv.style.height = canvas.style.height;
div.appendChild(textLayerDiv); if (this.annotationLayer) {
// annotationLayer needs to stay on top
div.insertBefore(textLayerDiv, this.annotationLayer);
} else {
div.appendChild(textLayerDiv);
}
} }
var textLayer = this.textLayer = var textLayer = this.textLayer =
textLayerDiv ? new TextLayerBuilder({ textLayerDiv ? new TextLayerBuilder({