Skip to content

Commit 49b5145

Browse files
committed
[Annotation] Use the clip-path property when an annotation has some quad points
This way it'll avoid to split a div in multiple divs having the same id (which is supposed to be unique).
1 parent 071e6bc commit 49b5145

File tree

2 files changed

+45
-79
lines changed

2 files changed

+45
-79
lines changed

src/display/annotation_layer.js

+34-75
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import {
2222
AnnotationBorderStyleType,
2323
AnnotationType,
24-
assert,
2524
FeatureTest,
2625
LINE_FACTOR,
2726
shadow,
@@ -181,7 +180,7 @@ class AnnotationElement {
181180
this.container = this._createContainer(ignoreBorder);
182181
}
183182
if (createQuadrilaterals) {
184-
this.quadrilaterals = this._createQuadrilaterals(ignoreBorder);
183+
this._createQuadrilaterals();
185184
}
186185
}
187186

@@ -416,26 +415,41 @@ class AnnotationElement {
416415
* @private
417416
* @param {boolean} ignoreBorder
418417
* @memberof AnnotationElement
419-
* @returns {Array<HTMLElement>} An array of section elements.
420418
*/
421-
_createQuadrilaterals(ignoreBorder = false) {
422-
if (!this.data.quadPoints) {
423-
return null;
419+
_createQuadrilaterals() {
420+
const { quadPoints } = this.data;
421+
if (!quadPoints || quadPoints.length === 1) {
422+
return;
424423
}
425424

426-
const quadrilaterals = [];
427-
const savedRect = this.data.rect;
428-
for (const quadPoint of this.data.quadPoints) {
429-
this.data.rect = [
430-
quadPoint[2].x,
431-
quadPoint[2].y,
432-
quadPoint[1].x,
433-
quadPoint[1].y,
434-
];
435-
quadrilaterals.push(this._createContainer(ignoreBorder));
425+
const { svgFactory } = this;
426+
const svg = svgFactory.createElement("svg");
427+
svg.classList.add("quadrilateralsContainer");
428+
429+
svg.setAttribute("width", 0);
430+
svg.setAttribute("height", 0);
431+
const defs = svgFactory.createElement("defs");
432+
svg.append(defs);
433+
const clipPath = svgFactory.createElement("clipPath");
434+
const id = `clippath_${this.data.id}`;
435+
clipPath.setAttribute("id", id);
436+
clipPath.setAttribute("clipPathUnits", "objectBoundingBox");
437+
defs.append(clipPath);
438+
439+
const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect;
440+
const width = rectTrX - rectBlX;
441+
const height = rectTrY - rectBlY;
442+
for (const [, { x: trX, y: trY }, { x: blX, y: blY }] of quadPoints) {
443+
const rect = svgFactory.createElement("rect");
444+
rect.setAttribute("x", `${(blX - rectBlX) / width}`);
445+
rect.setAttribute("y", `${(rectTrY - trY) / height}`);
446+
rect.setAttribute("width", `${(trX - blX) / width}`);
447+
rect.setAttribute("height", `${(trY - blY) / height}`);
448+
clipPath.append(rect);
436449
}
437-
this.data.rect = savedRect;
438-
return quadrilaterals;
450+
451+
this.container.append(svg);
452+
this.container.style.clipPath = `url(#${id})`;
439453
}
440454

441455
/**
@@ -449,18 +463,8 @@ class AnnotationElement {
449463
* @memberof AnnotationElement
450464
*/
451465
_createPopup(trigger, data) {
452-
let container = this.container;
453-
if (this.quadrilaterals) {
454-
trigger ||= this.quadrilaterals;
455-
container = this.quadrilaterals[0];
456-
}
457-
458-
// If no trigger element is specified, create it.
459-
if (!trigger) {
460-
trigger = document.createElement("div");
461-
trigger.classList.add("popupTriggerArea");
462-
container.append(trigger);
463-
}
466+
const container = this.container;
467+
trigger ||= this.container;
464468

465469
const popupElement = new PopupElement({
466470
container,
@@ -480,25 +484,6 @@ class AnnotationElement {
480484
container.append(popup);
481485
}
482486

483-
/**
484-
* Render the quadrilaterals of the annotation.
485-
*
486-
* @private
487-
* @param {string} className
488-
* @memberof AnnotationElement
489-
* @returns {Array<HTMLElement>} An array of section elements.
490-
*/
491-
_renderQuadrilaterals(className) {
492-
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
493-
assert(this.quadrilaterals, "Missing quadrilaterals during rendering");
494-
}
495-
496-
for (const quadrilateral of this.quadrilaterals) {
497-
quadrilateral.classList.add(className);
498-
}
499-
return this.quadrilaterals;
500-
}
501-
502487
/**
503488
* Render the annotation's HTML element(s).
504489
*
@@ -613,16 +598,6 @@ class LinkAnnotationElement extends AnnotationElement {
613598
}
614599
}
615600

616-
if (this.quadrilaterals) {
617-
return this._renderQuadrilaterals("linkAnnotation").map(
618-
(quadrilateral, index) => {
619-
const linkElement = index === 0 ? link : link.cloneNode();
620-
quadrilateral.append(linkElement);
621-
return quadrilateral;
622-
}
623-
);
624-
}
625-
626601
this.container.classList.add("linkAnnotation");
627602
if (isBound) {
628603
this.container.append(link);
@@ -2396,10 +2371,6 @@ class HighlightAnnotationElement extends AnnotationElement {
23962371
this._createPopup(null, this.data);
23972372
}
23982373

2399-
if (this.quadrilaterals) {
2400-
return this._renderQuadrilaterals("highlightAnnotation");
2401-
}
2402-
24032374
this.container.classList.add("highlightAnnotation");
24042375
return this.container;
24052376
}
@@ -2425,10 +2396,6 @@ class UnderlineAnnotationElement extends AnnotationElement {
24252396
this._createPopup(null, this.data);
24262397
}
24272398

2428-
if (this.quadrilaterals) {
2429-
return this._renderQuadrilaterals("underlineAnnotation");
2430-
}
2431-
24322399
this.container.classList.add("underlineAnnotation");
24332400
return this.container;
24342401
}
@@ -2454,10 +2421,6 @@ class SquigglyAnnotationElement extends AnnotationElement {
24542421
this._createPopup(null, this.data);
24552422
}
24562423

2457-
if (this.quadrilaterals) {
2458-
return this._renderQuadrilaterals("squigglyAnnotation");
2459-
}
2460-
24612424
this.container.classList.add("squigglyAnnotation");
24622425
return this.container;
24632426
}
@@ -2483,10 +2446,6 @@ class StrikeOutAnnotationElement extends AnnotationElement {
24832446
this._createPopup(null, this.data);
24842447
}
24852448

2486-
if (this.quadrilaterals) {
2487-
return this._renderQuadrilaterals("strikeoutAnnotation");
2488-
}
2489-
24902449
this.container.classList.add("strikeoutAnnotation");
24912450
return this.container;
24922451
}

web/annotation_layer_builder.css

+11-4
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,9 @@
239239
appearance: none;
240240
}
241241

242-
.annotationLayer .popupTriggerArea {
242+
.annotationLayer .fileAttachmentAnnotation .popupTriggerArea {
243243
height: 100%;
244244
width: 100%;
245-
}
246-
247-
.annotationLayer .fileAttachmentAnnotation .popupTriggerArea {
248245
position: absolute;
249246
}
250247

@@ -335,3 +332,13 @@
335332
width: 100%;
336333
display: inline-block;
337334
}
335+
336+
.annotationLayer svg.quadrilateralsContainer {
337+
contain: strict;
338+
width: 0;
339+
height: 0;
340+
position: absolute;
341+
top: 0;
342+
left: 0;
343+
z-index: -1;
344+
}

0 commit comments

Comments
 (0)