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);
data.hasAppearance = !!this.appearance;
data.id = params.ref.num;
}
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) {
this.renderTask.cancel();
}
@ -81,14 +81,23 @@ var PageView = function pageView(container, id, scale,
var childNodes = div.childNodes;
for (var i = div.childNodes.length - 1; i >= 0; i--) {
var node = childNodes[i];
if (this.zoomLayer && this.zoomLayer === node) {
if ((this.zoomLayer && this.zoomLayer === node) ||
(keepAnnotations && this.annotationLayer === node)) {
continue;
}
div.removeChild(node);
}
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;
@ -120,7 +129,7 @@ var PageView = function pageView(container, id, scale,
if (this.zoomLayer) {
this.cssTransform(this.zoomLayer.firstChild);
}
this.reset();
this.reset(true);
};
this.cssTransform = function pageCssTransform(canvas) {
@ -269,60 +278,73 @@ var PageView = function pageView(container, id, scale,
}
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 });
for (var i = 0; i < annotationsData.length; i++) {
var data = annotationsData[i];
var annotation = PDFJS.Annotation.fromData(data);
if (!annotation || !annotation.hasHtml()) {
continue;
}
var transform = viewport.transform;
var transformStr = 'matrix(' + transform.join(',') + ')';
var data, element, i, ii;
var element = annotation.getHtmlElement(pdfPage.commonObjs);
mozL10n.translate(element);
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';
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);
}
if (self.annotationLayer) {
// If an annotationLayer already exists, refresh its children's
// transformation matrices
for (i = 0, ii = annotationsData.length; i < ii; i++) {
data = annotationsData[i];
element = self.annotationLayer.querySelector(
'[data-annotation-id="' + data.id + '"]');
if (element) {
CustomStyle.setProp('transform', element, transformStr);
}
}
// 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) {
var annotationLayerDiv = document.createElement('div');
annotationLayerDiv.className = 'annotationLayer';
pageDiv.appendChild(annotationLayerDiv);
self.annotationLayer = annotationLayerDiv;
element = annotation.getHtmlElement(pdfPage.commonObjs);
element.setAttribute('data-annotation-id', data.id);
mozL10n.translate(element);
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');
canvas.id = 'page' + this.id;
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;
var ctx = canvas.getContext('2d');
@ -486,7 +513,12 @@ var PageView = function pageView(container, id, scale,
textLayerDiv.className = 'textLayer';
textLayerDiv.style.width = canvas.style.width;
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 =
textLayerDiv ? new TextLayerBuilder({