Split highlight annotation div into multiple divs
Fix for issue #12504. Highlight annotation may have several rectangles so we must have several divs to add mouse events handlers.
This commit is contained in:
parent
1eaf9c961b
commit
85e6c67cf3
@ -2086,6 +2086,13 @@ class PopupAnnotation extends Annotation {
|
|||||||
const rawParent = parameters.dict.getRaw("Parent");
|
const rawParent = parameters.dict.getRaw("Parent");
|
||||||
this.data.parentId = isRef(rawParent) ? rawParent.toString() : null;
|
this.data.parentId = isRef(rawParent) ? rawParent.toString() : null;
|
||||||
|
|
||||||
|
const parentRect = parentItem.getArray("Rect");
|
||||||
|
if (Array.isArray(parentRect) && parentRect.length === 4) {
|
||||||
|
this.data.parentRect = Util.normalizeRect(parentRect);
|
||||||
|
} else {
|
||||||
|
this.data.parentRect = [0, 0, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
const rt = parentItem.get("RT");
|
const rt = parentItem.get("RT");
|
||||||
if (isName(rt, AnnotationReplyType.GROUP)) {
|
if (isName(rt, AnnotationReplyType.GROUP)) {
|
||||||
// Subordinate annotations in a group should inherit
|
// Subordinate annotations in a group should inherit
|
||||||
|
@ -239,6 +239,35 @@ class AnnotationElement {
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create quadrilaterals for the quadPoints.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {boolean} ignoreBorder
|
||||||
|
* @memberof AnnotationElement
|
||||||
|
* @returns {HTMLSectionElement}
|
||||||
|
*/
|
||||||
|
_createQuadrilaterals(ignoreBorder = false) {
|
||||||
|
if (!this.data.quadPoints) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const quadrilaterals = [];
|
||||||
|
const savedRect = this.data.rect;
|
||||||
|
for (const quadPoint of this.data.quadPoints) {
|
||||||
|
const rect = [
|
||||||
|
quadPoint[2].x,
|
||||||
|
quadPoint[2].y,
|
||||||
|
quadPoint[1].x,
|
||||||
|
quadPoint[1].y,
|
||||||
|
];
|
||||||
|
this.data.rect = rect;
|
||||||
|
quadrilaterals.push(this._createContainer(ignoreBorder));
|
||||||
|
}
|
||||||
|
this.data.rect = savedRect;
|
||||||
|
return quadrilaterals;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a popup for the annotation's HTML element. This is used for
|
* Create a popup for the annotation's HTML element. This is used for
|
||||||
* annotations that do not have a Popup entry in the dictionary, but
|
* annotations that do not have a Popup entry in the dictionary, but
|
||||||
@ -789,14 +818,14 @@ class PopupAnnotationElement extends AnnotationElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selector = `[data-annotation-id="${this.data.parentId}"]`;
|
const selector = `[data-annotation-id="${this.data.parentId}"]`;
|
||||||
const parentElement = this.layer.querySelector(selector);
|
const parentElements = this.layer.querySelectorAll(selector);
|
||||||
if (!parentElement) {
|
if (parentElements.length === 0) {
|
||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
const popup = new PopupElement({
|
const popup = new PopupElement({
|
||||||
container: this.container,
|
container: this.container,
|
||||||
trigger: parentElement,
|
trigger: Array.from(parentElements),
|
||||||
color: this.data.color,
|
color: this.data.color,
|
||||||
title: this.data.title,
|
title: this.data.title,
|
||||||
modificationDate: this.data.modificationDate,
|
modificationDate: this.data.modificationDate,
|
||||||
@ -805,12 +834,18 @@ class PopupAnnotationElement extends AnnotationElement {
|
|||||||
|
|
||||||
// Position the popup next to the parent annotation's container.
|
// Position the popup next to the parent annotation's container.
|
||||||
// PDF viewers ignore a popup annotation's rectangle.
|
// PDF viewers ignore a popup annotation's rectangle.
|
||||||
const parentTop = parseFloat(parentElement.style.top),
|
const page = this.page;
|
||||||
parentLeft = parseFloat(parentElement.style.left),
|
const rect = Util.normalizeRect([
|
||||||
parentWidth = parseFloat(parentElement.style.width);
|
this.data.parentRect[0],
|
||||||
const popupLeft = parentLeft + parentWidth;
|
page.view[3] - this.data.parentRect[1] + page.view[1],
|
||||||
|
this.data.parentRect[2],
|
||||||
|
page.view[3] - this.data.parentRect[3] + page.view[1],
|
||||||
|
]);
|
||||||
|
const popupLeft =
|
||||||
|
rect[0] + this.data.parentRect[2] - this.data.parentRect[0];
|
||||||
|
const popupTop = rect[1];
|
||||||
|
|
||||||
this.container.style.transformOrigin = `${-popupLeft}px ${-parentTop}px`;
|
this.container.style.transformOrigin = `${-popupLeft}px ${-popupTop}px`;
|
||||||
this.container.style.left = `${popupLeft}px`;
|
this.container.style.left = `${popupLeft}px`;
|
||||||
|
|
||||||
this.container.appendChild(popup.render());
|
this.container.appendChild(popup.render());
|
||||||
@ -885,10 +920,16 @@ class PopupElement {
|
|||||||
const contents = this._formatContents(this.contents);
|
const contents = this._formatContents(this.contents);
|
||||||
popup.appendChild(contents);
|
popup.appendChild(contents);
|
||||||
|
|
||||||
|
if (!Array.isArray(this.trigger)) {
|
||||||
|
this.trigger = [this.trigger];
|
||||||
|
}
|
||||||
|
|
||||||
// Attach the event listeners to the trigger element.
|
// Attach the event listeners to the trigger element.
|
||||||
this.trigger.addEventListener("click", this._toggle.bind(this));
|
this.trigger.forEach(element => {
|
||||||
this.trigger.addEventListener("mouseover", this._show.bind(this, false));
|
element.addEventListener("click", this._toggle.bind(this));
|
||||||
this.trigger.addEventListener("mouseout", this._hide.bind(this, false));
|
element.addEventListener("mouseover", this._show.bind(this, false));
|
||||||
|
element.addEventListener("mouseout", this._hide.bind(this, false));
|
||||||
|
});
|
||||||
popup.addEventListener("click", this._hide.bind(this, true));
|
popup.addEventListener("click", this._hide.bind(this, true));
|
||||||
|
|
||||||
wrapper.appendChild(popup);
|
wrapper.appendChild(popup);
|
||||||
@ -1324,6 +1365,7 @@ class HighlightAnnotationElement extends AnnotationElement {
|
|||||||
parameters.data.contents
|
parameters.data.contents
|
||||||
);
|
);
|
||||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||||
|
this.quadrilaterals = this._createQuadrilaterals(/* ignoreBorder = */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1339,7 +1381,7 @@ class HighlightAnnotationElement extends AnnotationElement {
|
|||||||
if (!this.data.hasPopup) {
|
if (!this.data.hasPopup) {
|
||||||
this._createPopup(this.container, null, this.data);
|
this._createPopup(this.container, null, this.data);
|
||||||
}
|
}
|
||||||
return this.container;
|
return this.quadrilaterals || this.container;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1567,7 +1609,14 @@ class AnnotationLayer {
|
|||||||
parameters.annotationStorage || new AnnotationStorage(),
|
parameters.annotationStorage || new AnnotationStorage(),
|
||||||
});
|
});
|
||||||
if (element.isRenderable) {
|
if (element.isRenderable) {
|
||||||
parameters.div.appendChild(element.render());
|
const rendered = element.render();
|
||||||
|
if (Array.isArray(rendered)) {
|
||||||
|
for (const renderedElement of rendered) {
|
||||||
|
parameters.div.appendChild(renderedElement);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parameters.div.appendChild(rendered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1580,14 +1629,15 @@ class AnnotationLayer {
|
|||||||
* @memberof AnnotationLayer
|
* @memberof AnnotationLayer
|
||||||
*/
|
*/
|
||||||
static update(parameters) {
|
static update(parameters) {
|
||||||
|
const transform = `matrix(${parameters.viewport.transform.join(",")})`;
|
||||||
for (const data of parameters.annotations) {
|
for (const data of parameters.annotations) {
|
||||||
const element = parameters.div.querySelector(
|
const elements = parameters.div.querySelectorAll(
|
||||||
`[data-annotation-id="${data.id}"]`
|
`[data-annotation-id="${data.id}"]`
|
||||||
);
|
);
|
||||||
if (element) {
|
if (elements) {
|
||||||
element.style.transform = `matrix(${parameters.viewport.transform.join(
|
elements.forEach(element => {
|
||||||
","
|
element.style.transform = transform;
|
||||||
)})`;
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parameters.div.removeAttribute("hidden");
|
parameters.div.removeAttribute("hidden");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user