Don't print hidden annotatons (bug 1815196)
and handle correctly the NoView and NoPrint flags when they're changed from JS.
This commit is contained in:
parent
0e6d141edf
commit
71960bea64
@ -628,8 +628,11 @@ class Annotation {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_isPrintable(flags) {
|
_isPrintable(flags) {
|
||||||
|
// In Acrobat, hidden flag cancels the print one
|
||||||
|
// (see annotation_hidden_print.pdf).
|
||||||
return (
|
return (
|
||||||
this._hasFlag(flags, AnnotationFlag.PRINT) &&
|
this._hasFlag(flags, AnnotationFlag.PRINT) &&
|
||||||
|
!this._hasFlag(flags, AnnotationFlag.HIDDEN) &&
|
||||||
!this._hasFlag(flags, AnnotationFlag.INVISIBLE)
|
!this._hasFlag(flags, AnnotationFlag.INVISIBLE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -642,11 +645,13 @@ class Annotation {
|
|||||||
* @public
|
* @public
|
||||||
* @memberof Annotation
|
* @memberof Annotation
|
||||||
* @param {AnnotationStorage} [annotationStorage] - Storage for annotation
|
* @param {AnnotationStorage} [annotationStorage] - Storage for annotation
|
||||||
|
* @param {boolean} [_renderForms] - if true widgets are rendered thanks to
|
||||||
|
* the annotation layer.
|
||||||
*/
|
*/
|
||||||
mustBeViewed(annotationStorage) {
|
mustBeViewed(annotationStorage, _renderForms) {
|
||||||
const hidden = annotationStorage?.get(this.data.id)?.hidden;
|
const noView = annotationStorage?.get(this.data.id)?.noView;
|
||||||
if (hidden !== undefined) {
|
if (noView !== undefined) {
|
||||||
return !hidden;
|
return !noView;
|
||||||
}
|
}
|
||||||
return this.viewable && !this._hasFlag(this.flags, AnnotationFlag.HIDDEN);
|
return this.viewable && !this._hasFlag(this.flags, AnnotationFlag.HIDDEN);
|
||||||
}
|
}
|
||||||
@ -661,9 +666,9 @@ class Annotation {
|
|||||||
* @param {AnnotationStorage} [annotationStorage] - Storage for annotation
|
* @param {AnnotationStorage} [annotationStorage] - Storage for annotation
|
||||||
*/
|
*/
|
||||||
mustBePrinted(annotationStorage) {
|
mustBePrinted(annotationStorage) {
|
||||||
const print = annotationStorage?.get(this.data.id)?.print;
|
const noPrint = annotationStorage?.get(this.data.id)?.noPrint;
|
||||||
if (print !== undefined) {
|
if (noPrint !== undefined) {
|
||||||
return print;
|
return !noPrint;
|
||||||
}
|
}
|
||||||
return this.printable;
|
return this.printable;
|
||||||
}
|
}
|
||||||
@ -1700,7 +1705,9 @@ class WidgetAnnotation extends Annotation {
|
|||||||
|
|
||||||
data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
|
data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
|
||||||
data.required = this.hasFieldFlag(AnnotationFieldFlag.REQUIRED);
|
data.required = this.hasFieldFlag(AnnotationFieldFlag.REQUIRED);
|
||||||
data.hidden = this._hasFlag(data.annotationFlags, AnnotationFlag.HIDDEN);
|
data.hidden =
|
||||||
|
this._hasFlag(data.annotationFlags, AnnotationFlag.HIDDEN) ||
|
||||||
|
this._hasFlag(data.annotationFlags, AnnotationFlag.NOVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1739,6 +1746,26 @@ class WidgetAnnotation extends Annotation {
|
|||||||
return !!(this.data.fieldFlags & flag);
|
return !!(this.data.fieldFlags & flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
_isViewable(flags) {
|
||||||
|
// We don't take into account the `NOVIEW` or `HIDDEN` flags here,
|
||||||
|
// since the visibility can be changed by js code, hence in case
|
||||||
|
// it's made viewable, we should render it (with visibility set to
|
||||||
|
// hidden).
|
||||||
|
return !this._hasFlag(flags, AnnotationFlag.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
mustBeViewed(annotationStorage, renderForms) {
|
||||||
|
if (renderForms) {
|
||||||
|
return this.viewable;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
super.mustBeViewed(annotationStorage, renderForms) &&
|
||||||
|
!this._hasFlag(this.flags, AnnotationFlag.NOVIEW)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
getRotationMatrix(annotationStorage) {
|
getRotationMatrix(annotationStorage) {
|
||||||
let rotation = annotationStorage?.get(this.data.id)?.rotation;
|
let rotation = annotationStorage?.get(this.data.id)?.rotation;
|
||||||
if (rotation === undefined) {
|
if (rotation === undefined) {
|
||||||
|
@ -556,7 +556,8 @@ class Page {
|
|||||||
for (const annotation of annotations) {
|
for (const annotation of annotations) {
|
||||||
if (
|
if (
|
||||||
intentAny ||
|
intentAny ||
|
||||||
(intentDisplay && annotation.mustBeViewed(annotationStorage)) ||
|
(intentDisplay &&
|
||||||
|
annotation.mustBeViewed(annotationStorage, renderForms)) ||
|
||||||
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
||||||
) {
|
) {
|
||||||
opListPromises.push(
|
opListPromises.push(
|
||||||
|
@ -342,24 +342,27 @@ class AnnotationElement {
|
|||||||
|
|
||||||
return shadow(this, "_commonActions", {
|
return shadow(this, "_commonActions", {
|
||||||
display: event => {
|
display: event => {
|
||||||
const hidden = event.detail.display % 2 === 1;
|
const { display } = event.detail;
|
||||||
|
// See scripting/constants.js for the values of `Display`.
|
||||||
|
// 0 = visible, 1 = hidden, 2 = noPrint and 3 = noView.
|
||||||
|
const hidden = display % 2 === 1;
|
||||||
this.container.style.visibility = hidden ? "hidden" : "visible";
|
this.container.style.visibility = hidden ? "hidden" : "visible";
|
||||||
this.annotationStorage.setValue(this.data.id, {
|
this.annotationStorage.setValue(this.data.id, {
|
||||||
hidden,
|
noView: hidden,
|
||||||
print: event.detail.display === 0 || event.detail.display === 3,
|
noPrint: display === 1 || display === 2,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
print: event => {
|
print: event => {
|
||||||
this.annotationStorage.setValue(this.data.id, {
|
this.annotationStorage.setValue(this.data.id, {
|
||||||
print: event.detail.print,
|
noPrint: !event.detail.print,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hidden: event => {
|
hidden: event => {
|
||||||
this.container.style.visibility = event.detail.hidden
|
const { hidden } = event.detail;
|
||||||
? "hidden"
|
this.container.style.visibility = hidden ? "hidden" : "visible";
|
||||||
: "visible";
|
|
||||||
this.annotationStorage.setValue(this.data.id, {
|
this.annotationStorage.setValue(this.data.id, {
|
||||||
hidden: event.detail.hidden,
|
noPrint: hidden,
|
||||||
|
noView: hidden,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
focus: event => {
|
focus: event => {
|
||||||
|
@ -2042,4 +2042,60 @@ describe("Interaction", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("in annotation_hidden_noview.pdf", () => {
|
||||||
|
let pages;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
pages = await loadAndWait(
|
||||||
|
"annotation_hidden_noview.pdf",
|
||||||
|
getSelector("11R")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await closePages(pages);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must check that invisible fields are made visible", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
await page.waitForFunction(
|
||||||
|
"window.PDFViewerApplication.scriptingReady === true"
|
||||||
|
);
|
||||||
|
|
||||||
|
let visibility = await page.$eval(
|
||||||
|
getSelector("7R"),
|
||||||
|
el => getComputedStyle(el).visibility
|
||||||
|
);
|
||||||
|
expect(visibility).withContext(`In ${browserName}`).toEqual("hidden");
|
||||||
|
|
||||||
|
visibility = await page.$eval(
|
||||||
|
getSelector("8R"),
|
||||||
|
el => getComputedStyle(el).visibility
|
||||||
|
);
|
||||||
|
expect(visibility).withContext(`In ${browserName}`).toEqual("hidden");
|
||||||
|
|
||||||
|
await page.click(getSelector("11R"));
|
||||||
|
await page.waitForTimeout(10);
|
||||||
|
|
||||||
|
visibility = await page.$eval(
|
||||||
|
getSelector("7R"),
|
||||||
|
el => getComputedStyle(el).visibility
|
||||||
|
);
|
||||||
|
expect(visibility)
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual("visible");
|
||||||
|
|
||||||
|
visibility = await page.$eval(
|
||||||
|
getSelector("8R"),
|
||||||
|
el => getComputedStyle(el).visibility
|
||||||
|
);
|
||||||
|
expect(visibility)
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual("visible");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
3
test/pdfs/.gitignore
vendored
3
test/pdfs/.gitignore
vendored
@ -606,3 +606,6 @@
|
|||||||
!issue16633.pdf
|
!issue16633.pdf
|
||||||
!bug1844576.pdf
|
!bug1844576.pdf
|
||||||
!bug1844583.pdf
|
!bug1844583.pdf
|
||||||
|
!annotation_hidden_print.pdf
|
||||||
|
!annotation_hidden_noview.pdf
|
||||||
|
!widget_hidden_print.pdf
|
||||||
|
BIN
test/pdfs/annotation_hidden_noview.pdf
Normal file
BIN
test/pdfs/annotation_hidden_noview.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/annotation_hidden_print.pdf
Normal file
BIN
test/pdfs/annotation_hidden_print.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/widget_hidden_print.pdf
Normal file
BIN
test/pdfs/widget_hidden_print.pdf
Normal file
Binary file not shown.
@ -3420,7 +3420,7 @@
|
|||||||
"print": true,
|
"print": true,
|
||||||
"annotationStorage": {
|
"annotationStorage": {
|
||||||
"427R": {
|
"427R": {
|
||||||
"hidden": false,
|
"noPrint": false,
|
||||||
"value": "hello world"
|
"value": "hello world"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8054,5 +8054,21 @@
|
|||||||
"rotation": 0
|
"rotation": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "widget_hidden_print",
|
||||||
|
"file": "pdfs/widget_hidden_print.pdf",
|
||||||
|
"md5": "0b8d5a8e8c7c7598232a79044c312cbb",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq",
|
||||||
|
"print": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "annotation_hidden_print",
|
||||||
|
"file": "pdfs/annotation_hidden_print.pdf",
|
||||||
|
"md5": "5cfa86df9b080feeb4aa320ad68d6cbd",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq",
|
||||||
|
"print": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user