Merge pull request #7775 from timvandermeij/widget-annotation-name

Widget annotation: implement field name according to the specification
This commit is contained in:
Tim van der Meij 2016-11-02 22:43:17 +01:00 committed by GitHub
commit 9f8d67475e
3 changed files with 110 additions and 33 deletions

View File

@ -91,7 +91,7 @@ function setupForm(div, content, viewport) {
// select box is not supported
}
input.className = 'inputControl';
input.name = item.fullName;
input.name = item.fieldName;
input.title = item.alternativeText;
assignFontStyle(input, item);
bindInputItem(input, item);

View File

@ -621,6 +621,7 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() {
var data = this.data;
data.annotationType = AnnotationType.WIDGET;
data.fieldName = this._constructFieldName(dict);
data.fieldValue = Util.getInheritableProperty(dict, 'V',
/* getArray = */ true);
data.alternativeText = stringToPDFString(dict.get('TU') || '');
@ -640,41 +641,49 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() {
if (data.fieldType === 'Sig') {
this.setFlags(AnnotationFlag.HIDDEN);
}
// Building the full field name by collecting the field and
// its ancestors 'T' data and joining them using '.'.
var fieldName = [];
var namedItem = dict;
var ref = params.ref;
while (namedItem) {
var parent = namedItem.get('Parent');
var parentRef = namedItem.getRaw('Parent');
var name = namedItem.get('T');
if (name) {
fieldName.unshift(stringToPDFString(name));
} else if (parent && ref) {
// The field name is absent, that means more than one field
// with the same name may exist. Replacing the empty name
// with the '`' plus index in the parent's 'Kids' array.
// This is not in the PDF spec but necessary to id the
// the input controls.
var kids = parent.get('Kids');
var j, jj;
for (j = 0, jj = kids.length; j < jj; j++) {
var kidRef = kids[j];
if (kidRef.num === ref.num && kidRef.gen === ref.gen) {
break;
}
}
fieldName.unshift('`' + j);
}
namedItem = parent;
ref = parentRef;
}
data.fullName = fieldName.join('.');
}
Util.inherit(WidgetAnnotation, Annotation, {
/**
* Construct the (fully qualified) field name from the (partial) field
* names of the field and its ancestors.
*
* @private
* @memberof WidgetAnnotation
* @param {Dict} dict - Complete widget annotation dictionary
* @return {string}
*/
_constructFieldName: function WidgetAnnotation_constructFieldName(dict) {
// Both the `Parent` and `T` fields are optional. While at least one of
// them should be provided, bad PDF generators may fail to do so.
if (!dict.has('T') && !dict.has('Parent')) {
warn('Unknown field name, falling back to empty field name.');
return '';
}
// If no parent exists, the partial and fully qualified names are equal.
if (!dict.has('Parent')) {
return stringToPDFString(dict.get('T'));
}
// Form the fully qualified field name by appending the partial name to
// the parent's fully qualified name, separated by a period.
var fieldName = [];
if (dict.has('T')) {
fieldName.unshift(stringToPDFString(dict.get('T')));
}
var loopDict = dict;
while (loopDict.has('Parent')) {
loopDict = loopDict.get('Parent');
if (loopDict.has('T')) {
fieldName.unshift(stringToPDFString(loopDict.get('T')));
}
}
return fieldName.join('.');
},
/**
* Check if a provided field flag is set.
*

View File

@ -616,6 +616,74 @@ describe('Annotation layer', function() {
});
});
describe('WidgetAnnotation', function() {
var widgetDict;
beforeEach(function (done) {
widgetDict = new Dict();
widgetDict.set('Type', Name.get('Annot'));
widgetDict.set('Subtype', Name.get('Widget'));
done();
});
afterEach(function () {
widgetDict = null;
});
it('should handle unknown field names', function() {
var widgetRef = new Ref(20, 0);
var xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
var widgetAnnotation = annotationFactory.create(xref, widgetRef,
pdfManagerMock);
var data = widgetAnnotation.data;
expect(data.annotationType).toEqual(AnnotationType.WIDGET);
expect(data.fieldName).toEqual('');
});
it('should construct the field name when there are no ancestors',
function() {
widgetDict.set('T', 'foo');
var widgetRef = new Ref(21, 0);
var xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
var widgetAnnotation = annotationFactory.create(xref, widgetRef,
pdfManagerMock);
var data = widgetAnnotation.data;
expect(data.annotationType).toEqual(AnnotationType.WIDGET);
expect(data.fieldName).toEqual('foo');
});
it('should construct the field name when there are ancestors', function() {
var firstParent = new Dict();
firstParent.set('T', 'foo');
var secondParent = new Dict();
secondParent.set('Parent', firstParent);
secondParent.set('T', 'bar');
widgetDict.set('Parent', secondParent);
widgetDict.set('T', 'baz');
var widgetRef = new Ref(22, 0);
var xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
var widgetAnnotation = annotationFactory.create(xref, widgetRef,
pdfManagerMock);
var data = widgetAnnotation.data;
expect(data.annotationType).toEqual(AnnotationType.WIDGET);
expect(data.fieldName).toEqual('foo.bar.baz');
});
});
describe('TextWidgetAnnotation', function() {
var textWidgetDict;