Merge pull request #9191 from timvandermeij/pushbuttons

Button widget annotations: implement support for pushbuttons
This commit is contained in:
Tim van der Meij 2017-11-27 22:31:07 +01:00 committed by GitHub
commit 3e34eb31d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 39 deletions

View File

@ -732,45 +732,70 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) && this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON); !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
if (this.data.checkBox) {
if (!isName(this.data.fieldValue)) {
return;
}
this.data.fieldValue = this.data.fieldValue.name;
}
this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) && this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON); !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
if (this.data.radioButton) { this.data.pushButton = this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
this.data.fieldValue = this.data.buttonValue = null;
// The parent field's `V` entry holds a `Name` object with the appearance if (this.data.checkBox) {
// state of whichever child field is currently in the "on" state. this._processCheckBox();
let fieldParent = params.dict.get('Parent'); } else if (this.data.radioButton) {
if (isDict(fieldParent) && fieldParent.has('V')) { this._processRadioButton(params);
let fieldParentValue = fieldParent.get('V'); } else if (this.data.pushButton) {
if (isName(fieldParentValue)) { this._processPushButton(params);
this.data.fieldValue = fieldParentValue.name; } else {
} warn('Invalid field flags for button widget annotation');
} }
}
// The button's value corresponds to its appearance state. _processCheckBox() {
let appearanceStates = params.dict.get('AP'); if (!isName(this.data.fieldValue)) {
if (!isDict(appearanceStates)) { return;
return; }
} this.data.fieldValue = this.data.fieldValue.name;
let normalAppearanceState = appearanceStates.get('N'); }
if (!isDict(normalAppearanceState)) {
return; _processRadioButton(params) {
} this.data.fieldValue = this.data.buttonValue = null;
let keys = normalAppearanceState.getKeys();
for (let i = 0, ii = keys.length; i < ii; i++) { // The parent field's `V` entry holds a `Name` object with the appearance
if (keys[i] !== 'Off') { // state of whichever child field is currently in the "on" state.
this.data.buttonValue = keys[i]; let fieldParent = params.dict.get('Parent');
break; if (isDict(fieldParent) && fieldParent.has('V')) {
} let fieldParentValue = fieldParent.get('V');
if (isName(fieldParentValue)) {
this.data.fieldValue = fieldParentValue.name;
} }
} }
// The button's value corresponds to its appearance state.
let appearanceStates = params.dict.get('AP');
if (!isDict(appearanceStates)) {
return;
}
let normalAppearanceState = appearanceStates.get('N');
if (!isDict(normalAppearanceState)) {
return;
}
let keys = normalAppearanceState.getKeys();
for (let i = 0, ii = keys.length; i < ii; i++) {
if (keys[i] !== 'Off') {
this.data.buttonValue = keys[i];
break;
}
}
}
_processPushButton(params) {
if (!params.dict.has('A')) {
warn('Push buttons without action dictionaries are not supported');
return;
}
Catalog.parseDestDictionary({
destDict: params.dict,
resultObj: this.data,
docBaseUrl: params.pdfManager.docBaseUrl,
});
} }
} }

View File

@ -61,8 +61,7 @@ class AnnotationElementFactory {
} else if (parameters.data.checkBox) { } else if (parameters.data.checkBox) {
return new CheckboxWidgetAnnotationElement(parameters); return new CheckboxWidgetAnnotationElement(parameters);
} }
warn('Unimplemented button widget annotation: pushbutton'); return new PushButtonWidgetAnnotationElement(parameters);
break;
case 'Ch': case 'Ch':
return new ChoiceWidgetAnnotationElement(parameters); return new ChoiceWidgetAnnotationElement(parameters);
} }
@ -543,6 +542,25 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
} }
} }
class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
/**
* Render the push button widget annotation's HTML element
* in the empty container.
*
* @public
* @memberof PushButtonWidgetAnnotationElement
* @returns {HTMLSectionElement}
*/
render() {
// The rendering and functionality of a push button widget annotation is
// equal to that of a link annotation, but may have more functionality, such
// as performing actions on form fields (resetting, submitting, et cetera).
let container = super.render();
container.className = 'buttonWidgetAnnotation pushButton';
return container;
}
}
class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
constructor(parameters) { constructor(parameters) {
super(parameters, parameters.renderInteractiveForms); super(parameters, parameters.renderInteractiveForms);

View File

@ -19,7 +19,8 @@
position: absolute; position: absolute;
} }
.annotationLayer .linkAnnotation > a { .annotationLayer .linkAnnotation > a,
.annotationLayer .buttonWidgetAnnotation.pushButton > a {
opacity: 0.2; opacity: 0.2;
background: #ff0; background: #ff0;
box-shadow: 0px 2px 10px #ff0; box-shadow: 0px 2px 10px #ff0;

View File

@ -0,0 +1 @@
https://web.archive.org/web/20171003035412/https://www.cs.utexas.edu/users/EWD/ewd02xx/EWD288.PDF

View File

@ -3717,6 +3717,16 @@
"type": "eq", "type": "eq",
"annotations": true "annotations": true
}, },
{ "id": "issue4872",
"file": "pdfs/issue4872.pdf",
"md5": "21c6cbc682140d6f6017bbeb45892053",
"rounds": 1,
"link": true,
"firstPage": 1,
"lastPage": 1,
"type": "eq",
"annotations": true
},
{ "id": "issue6108", { "id": "issue6108",
"file": "pdfs/issue6108.pdf", "file": "pdfs/issue6108.pdf",
"md5": "8961cb55149495989a80bf0487e0f076", "md5": "8961cb55149495989a80bf0487e0f076",

View File

@ -17,7 +17,8 @@
position: absolute; position: absolute;
} }
.annotationLayer .linkAnnotation > a { .annotationLayer .linkAnnotation > a,
.annotationLayer .buttonWidgetAnnotation.pushButton > a {
position: absolute; position: absolute;
font-size: 1em; font-size: 1em;
top: 0; top: 0;
@ -26,11 +27,16 @@
height: 100%; height: 100%;
} }
.annotationLayer .linkAnnotation > a /* -ms-a */ { .annotationLayer .linkAnnotation > a /* -ms-a */ {
background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat; background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat;
} }
.annotationLayer .linkAnnotation > a:hover { .annotationLayer .buttonWidgetAnnotation.pushButton > a /* -ms-a */ {
background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat;
}
.annotationLayer .linkAnnotation > a:hover,
.annotationLayer .buttonWidgetAnnotation.pushButton > a:hover {
opacity: 0.2; opacity: 0.2;
background: #ff0; background: #ff0;
box-shadow: 0px 2px 10px #ff0; box-shadow: 0px 2px 10px #ff0;