Text widget annotations: implement comb support
This commit is contained in:
parent
c0e82dbc38
commit
6100ab4b18
@ -715,6 +715,11 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
|
|||||||
// Process field flags for the display layer.
|
// Process field flags for the display layer.
|
||||||
this.data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
|
this.data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
|
||||||
this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);
|
this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);
|
||||||
|
this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) &&
|
||||||
|
!this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) &&
|
||||||
|
!this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) &&
|
||||||
|
!this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) &&
|
||||||
|
this.data.maxLen !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Util.inherit(TextWidgetAnnotation, WidgetAnnotation, {
|
Util.inherit(TextWidgetAnnotation, WidgetAnnotation, {
|
||||||
|
@ -461,6 +461,14 @@ var TextWidgetAnnotationElement = (
|
|||||||
if (this.data.maxLen !== null) {
|
if (this.data.maxLen !== null) {
|
||||||
element.maxLength = this.data.maxLen;
|
element.maxLength = this.data.maxLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.data.comb) {
|
||||||
|
var fieldWidth = this.data.rect[2] - this.data.rect[0];
|
||||||
|
var combWidth = fieldWidth / this.data.maxLen;
|
||||||
|
|
||||||
|
element.classList.add('comb');
|
||||||
|
element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
element = document.createElement('div');
|
element = document.createElement('div');
|
||||||
element.textContent = this.data.fieldValue;
|
element.textContent = this.data.fieldValue;
|
||||||
|
@ -67,6 +67,12 @@
|
|||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.annotationLayer .textWidgetAnnotation input.comb {
|
||||||
|
font-family: monospace;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.annotationLayer .popupAnnotation {
|
.annotationLayer .popupAnnotation {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -3197,14 +3197,14 @@
|
|||||||
},
|
},
|
||||||
{ "id": "annotation-text-widget-annotations",
|
{ "id": "annotation-text-widget-annotations",
|
||||||
"file": "pdfs/annotation-text-widget.pdf",
|
"file": "pdfs/annotation-text-widget.pdf",
|
||||||
"md5": "cc9672539ad5b837152a9c6961e5f106",
|
"md5": "b7b8923a12998fca8603fae53f73f19b",
|
||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq",
|
"type": "eq",
|
||||||
"annotations": true
|
"annotations": true
|
||||||
},
|
},
|
||||||
{ "id": "annotation-text-widget-forms",
|
{ "id": "annotation-text-widget-forms",
|
||||||
"file": "pdfs/annotation-text-widget.pdf",
|
"file": "pdfs/annotation-text-widget.pdf",
|
||||||
"md5": "cc9672539ad5b837152a9c6961e5f106",
|
"md5": "b7b8923a12998fca8603fae53f73f19b",
|
||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq",
|
"type": "eq",
|
||||||
"forms": true
|
"forms": true
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* globals expect, it, describe, Dict, Name, Annotation, AnnotationBorderStyle,
|
/* globals expect, it, describe, Dict, Name, Annotation, AnnotationBorderStyle,
|
||||||
AnnotationBorderStyleType, AnnotationType, AnnotationFlag, PDFJS,
|
AnnotationBorderStyleType, AnnotationType, AnnotationFlag, PDFJS,
|
||||||
beforeEach, afterEach, stringToBytes, AnnotationFactory, Ref, isRef,
|
beforeEach, afterEach, stringToBytes, AnnotationFactory, Ref, isRef,
|
||||||
beforeAll, afterAll */
|
beforeAll, afterAll, AnnotationFieldFlag */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -481,6 +481,7 @@ describe('Annotation layer', function() {
|
|||||||
expect(textWidgetAnnotation.data.maxLen).toEqual(null);
|
expect(textWidgetAnnotation.data.maxLen).toEqual(null);
|
||||||
expect(textWidgetAnnotation.data.readOnly).toEqual(false);
|
expect(textWidgetAnnotation.data.readOnly).toEqual(false);
|
||||||
expect(textWidgetAnnotation.data.multiLine).toEqual(false);
|
expect(textWidgetAnnotation.data.multiLine).toEqual(false);
|
||||||
|
expect(textWidgetAnnotation.data.comb).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not set invalid text alignment, maximum length and flags',
|
it('should not set invalid text alignment, maximum length and flags',
|
||||||
@ -499,13 +500,18 @@ describe('Annotation layer', function() {
|
|||||||
expect(textWidgetAnnotation.data.maxLen).toEqual(null);
|
expect(textWidgetAnnotation.data.maxLen).toEqual(null);
|
||||||
expect(textWidgetAnnotation.data.readOnly).toEqual(false);
|
expect(textWidgetAnnotation.data.readOnly).toEqual(false);
|
||||||
expect(textWidgetAnnotation.data.multiLine).toEqual(false);
|
expect(textWidgetAnnotation.data.multiLine).toEqual(false);
|
||||||
|
expect(textWidgetAnnotation.data.comb).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set valid text alignment, maximum length and flags',
|
it('should set valid text alignment, maximum length and flags',
|
||||||
function() {
|
function() {
|
||||||
|
var flags = 0;
|
||||||
|
flags |= 1 << (AnnotationFieldFlag.READONLY - 1);
|
||||||
|
flags |= 1 << (AnnotationFieldFlag.MULTILINE - 1);
|
||||||
|
|
||||||
textWidgetDict.set('Q', 1);
|
textWidgetDict.set('Q', 1);
|
||||||
textWidgetDict.set('MaxLen', 20);
|
textWidgetDict.set('MaxLen', 20);
|
||||||
textWidgetDict.set('Ff', 4097);
|
textWidgetDict.set('Ff', flags);
|
||||||
|
|
||||||
var textWidgetRef = new Ref(84, 0);
|
var textWidgetRef = new Ref(84, 0);
|
||||||
var xref = new XRefMock([
|
var xref = new XRefMock([
|
||||||
@ -518,6 +524,74 @@ describe('Annotation layer', function() {
|
|||||||
expect(textWidgetAnnotation.data.readOnly).toEqual(true);
|
expect(textWidgetAnnotation.data.readOnly).toEqual(true);
|
||||||
expect(textWidgetAnnotation.data.multiLine).toEqual(true);
|
expect(textWidgetAnnotation.data.multiLine).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should reject comb fields without a maximum length', function() {
|
||||||
|
var flags = 0;
|
||||||
|
flags |= 1 << (AnnotationFieldFlag.COMB - 1);
|
||||||
|
|
||||||
|
textWidgetDict.set('Ff', flags);
|
||||||
|
|
||||||
|
var textWidgetRef = new Ref(46, 0);
|
||||||
|
var xref = new XRefMock([
|
||||||
|
{ ref: textWidgetRef, data: textWidgetDict, }
|
||||||
|
]);
|
||||||
|
|
||||||
|
var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef);
|
||||||
|
expect(textWidgetAnnotation.data.comb).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept comb fields with a maximum length', function() {
|
||||||
|
var flags = 0;
|
||||||
|
flags |= 1 << (AnnotationFieldFlag.COMB - 1);
|
||||||
|
|
||||||
|
textWidgetDict.set('MaxLen', 20);
|
||||||
|
textWidgetDict.set('Ff', flags);
|
||||||
|
|
||||||
|
var textWidgetRef = new Ref(46, 0);
|
||||||
|
var xref = new XRefMock([
|
||||||
|
{ ref: textWidgetRef, data: textWidgetDict, }
|
||||||
|
]);
|
||||||
|
|
||||||
|
var textWidgetAnnotation = annotationFactory.create(xref, textWidgetRef);
|
||||||
|
expect(textWidgetAnnotation.data.comb).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only accept comb fields when the flags are valid', function() {
|
||||||
|
var invalidFieldFlags = [
|
||||||
|
AnnotationFieldFlag.MULTILINE,
|
||||||
|
AnnotationFieldFlag.PASSWORD,
|
||||||
|
AnnotationFieldFlag.FILESELECT
|
||||||
|
];
|
||||||
|
|
||||||
|
// The field may not use combs until all invalid flags are unset.
|
||||||
|
for (var i = 0, ii = invalidFieldFlags.length; i <= ii; i++) {
|
||||||
|
var flags = 0;
|
||||||
|
flags |= 1 << (AnnotationFieldFlag.COMB - 1);
|
||||||
|
|
||||||
|
for (var j = 0, jj = invalidFieldFlags.length; j < jj; j++) {
|
||||||
|
flags |= 1 << (invalidFieldFlags[j] - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
textWidgetDict.set('MaxLen', 20);
|
||||||
|
textWidgetDict.set('Ff', flags);
|
||||||
|
|
||||||
|
var textWidgetRef = new Ref(93, 0);
|
||||||
|
var xref = new XRefMock([
|
||||||
|
{ ref: textWidgetRef, data: textWidgetDict, }
|
||||||
|
]);
|
||||||
|
|
||||||
|
var textWidgetAnnotation = annotationFactory.create(xref,
|
||||||
|
textWidgetRef);
|
||||||
|
|
||||||
|
var valid = (invalidFieldFlags.length === 0);
|
||||||
|
expect(textWidgetAnnotation.data.comb).toEqual(valid);
|
||||||
|
|
||||||
|
// Remove the last invalid flag for the next iteration.
|
||||||
|
if (!valid) {
|
||||||
|
invalidFieldFlags.splice(-1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('FileAttachmentAnnotation', function() {
|
describe('FileAttachmentAnnotation', function() {
|
||||||
|
@ -77,6 +77,22 @@
|
|||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.annotationLayer .textWidgetAnnotation input.comb {
|
||||||
|
font-family: monospace;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotationLayer .textWidgetAnnotation input.comb:focus {
|
||||||
|
/*
|
||||||
|
* Letter spacing is placed on the right side of each character. Hence, the
|
||||||
|
* letter spacing of the last character may be placed outside the visible
|
||||||
|
* area, causing horizontal scrolling. We avoid this by extending the width
|
||||||
|
* when the element has focus and revert this when it loses focus.
|
||||||
|
*/
|
||||||
|
width: 115%;
|
||||||
|
}
|
||||||
|
|
||||||
.annotationLayer .popupWrapper {
|
.annotationLayer .popupWrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 20em;
|
width: 20em;
|
||||||
|
Loading…
Reference in New Issue
Block a user