mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-26 10:08:06 +02:00
Implement a single getInheritableProperty
utility function
This function combines the logic of two separate methods into one. The loop limit is also a good thing to have for the calls in `src/core/annotation.js`. Moreover, since this is important functionality, a set of unit tests and documentation is added.
This commit is contained in:
parent
4e5eb59a33
commit
f308d73d40
4 changed files with 189 additions and 57 deletions
|
@ -15,7 +15,8 @@
|
|||
|
||||
import {
|
||||
AnnotationBorderStyleType, AnnotationFieldFlag, AnnotationFlag,
|
||||
AnnotationType, OPS, stringToBytes, stringToPDFString, Util, warn
|
||||
AnnotationType, getInheritableProperty, OPS, stringToBytes, stringToPDFString,
|
||||
Util, warn
|
||||
} from '../shared/util';
|
||||
import { Catalog, FileSpec, ObjectLoader } from './obj';
|
||||
import { Dict, isDict, isName, isRef, isStream } from './primitives';
|
||||
|
@ -60,7 +61,7 @@ class AnnotationFactory {
|
|||
return new TextAnnotation(parameters);
|
||||
|
||||
case 'Widget':
|
||||
let fieldType = Util.getInheritableProperty(dict, 'FT');
|
||||
let fieldType = getInheritableProperty({ dict, key: 'FT', });
|
||||
fieldType = isName(fieldType) ? fieldType.name : null;
|
||||
|
||||
switch (fieldType) {
|
||||
|
@ -580,15 +581,16 @@ class WidgetAnnotation extends Annotation {
|
|||
|
||||
data.annotationType = AnnotationType.WIDGET;
|
||||
data.fieldName = this._constructFieldName(dict);
|
||||
data.fieldValue = Util.getInheritableProperty(dict, 'V',
|
||||
/* getArray = */ true);
|
||||
data.fieldValue = getInheritableProperty({ dict, key: 'V',
|
||||
getArray: true, });
|
||||
data.alternativeText = stringToPDFString(dict.get('TU') || '');
|
||||
data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || '';
|
||||
let fieldType = Util.getInheritableProperty(dict, 'FT');
|
||||
data.defaultAppearance = getInheritableProperty({ dict, key: 'DA', }) || '';
|
||||
let fieldType = getInheritableProperty({ dict, key: 'FT', });
|
||||
data.fieldType = isName(fieldType) ? fieldType.name : null;
|
||||
this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty;
|
||||
this.fieldResources = getInheritableProperty({ dict, key: 'DR', }) ||
|
||||
Dict.empty;
|
||||
|
||||
data.fieldFlags = Util.getInheritableProperty(dict, 'Ff');
|
||||
data.fieldFlags = getInheritableProperty({ dict, key: 'Ff', });
|
||||
if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) {
|
||||
data.fieldFlags = 0;
|
||||
}
|
||||
|
@ -675,18 +677,20 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|||
constructor(params) {
|
||||
super(params);
|
||||
|
||||
const dict = params.dict;
|
||||
|
||||
// The field value is always a string.
|
||||
this.data.fieldValue = stringToPDFString(this.data.fieldValue || '');
|
||||
|
||||
// Determine the alignment of text in the field.
|
||||
let alignment = Util.getInheritableProperty(params.dict, 'Q');
|
||||
let alignment = getInheritableProperty({ dict, key: 'Q', });
|
||||
if (!Number.isInteger(alignment) || alignment < 0 || alignment > 2) {
|
||||
alignment = null;
|
||||
}
|
||||
this.data.textAlignment = alignment;
|
||||
|
||||
// Determine the maximum length of text in the field.
|
||||
let maximumLength = Util.getInheritableProperty(params.dict, 'MaxLen');
|
||||
let maximumLength = getInheritableProperty({ dict, key: 'MaxLen', });
|
||||
if (!Number.isInteger(maximumLength) || maximumLength < 0) {
|
||||
maximumLength = null;
|
||||
}
|
||||
|
@ -814,7 +818,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
|
|||
// inherit the options from a parent annotation (issue 8094).
|
||||
this.data.options = [];
|
||||
|
||||
let options = Util.getInheritableProperty(params.dict, 'Opt');
|
||||
let options = getInheritableProperty({ dict: params.dict, key: 'Opt', });
|
||||
if (Array.isArray(options)) {
|
||||
let xref = params.xref;
|
||||
for (let i = 0, ii = options.length; i < ii; i++) {
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
import { Catalog, ObjectLoader, XRef } from './obj';
|
||||
import { Dict, isDict, isName, isStream } from './primitives';
|
||||
import {
|
||||
info, isArrayBuffer, isNum, isSpace, isString, MissingDataException, OPS,
|
||||
shadow, stringToBytes, stringToPDFString, Util, warn
|
||||
getInheritableProperty, info, isArrayBuffer, isNum, isSpace, isString,
|
||||
MissingDataException, OPS, shadow, stringToBytes, stringToPDFString, Util
|
||||
} from '../shared/util';
|
||||
import { NullStream, Stream, StreamsSequenceStream } from './stream';
|
||||
import { AnnotationFactory } from './annotation';
|
||||
|
@ -62,33 +62,19 @@ var Page = (function PageClosure() {
|
|||
}
|
||||
|
||||
Page.prototype = {
|
||||
getInheritedPageProp: function Page_getInheritedPageProp(key, getArray) {
|
||||
var dict = this.pageDict, valueArray = null, loopCount = 0;
|
||||
var MAX_LOOP_COUNT = 100;
|
||||
getArray = getArray || false;
|
||||
// Always walk up the entire parent chain, to be able to find
|
||||
// e.g. \Resources placed on multiple levels of the tree.
|
||||
while (dict) {
|
||||
var value = getArray ? dict.getArray(key) : dict.get(key);
|
||||
if (value !== undefined) {
|
||||
if (!valueArray) {
|
||||
valueArray = [];
|
||||
}
|
||||
valueArray.push(value);
|
||||
}
|
||||
if (++loopCount > MAX_LOOP_COUNT) {
|
||||
warn('getInheritedPageProp: maximum loop count exceeded for ' + key);
|
||||
return valueArray ? valueArray[0] : undefined;
|
||||
}
|
||||
dict = dict.get('Parent');
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getInheritableProperty(key, getArray = false) {
|
||||
let value = getInheritableProperty({ dict: this.pageDict, key, getArray,
|
||||
stopWhenFound: false, });
|
||||
if (!Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
if (!valueArray) {
|
||||
return undefined;
|
||||
if (value.length === 1 || !isDict(value[0])) {
|
||||
return value[0];
|
||||
}
|
||||
if (valueArray.length === 1 || !isDict(valueArray[0])) {
|
||||
return valueArray[0];
|
||||
}
|
||||
return Dict.merge(this.xref, valueArray);
|
||||
return Dict.merge(this.xref, value);
|
||||
},
|
||||
|
||||
get content() {
|
||||
|
@ -100,11 +86,12 @@ var Page = (function PageClosure() {
|
|||
// present, but can be empty. Some document omit it still, in this case
|
||||
// we return an empty dictionary.
|
||||
return shadow(this, 'resources',
|
||||
this.getInheritedPageProp('Resources') || Dict.empty);
|
||||
this._getInheritableProperty('Resources') || Dict.empty);
|
||||
},
|
||||
|
||||
get mediaBox() {
|
||||
var mediaBox = this.getInheritedPageProp('MediaBox', true);
|
||||
var mediaBox = this._getInheritableProperty('MediaBox',
|
||||
/* getArray = */ true);
|
||||
// Reset invalid media box to letter size.
|
||||
if (!Array.isArray(mediaBox) || mediaBox.length !== 4) {
|
||||
return shadow(this, 'mediaBox', LETTER_SIZE_MEDIABOX);
|
||||
|
@ -113,7 +100,8 @@ var Page = (function PageClosure() {
|
|||
},
|
||||
|
||||
get cropBox() {
|
||||
var cropBox = this.getInheritedPageProp('CropBox', true);
|
||||
var cropBox = this._getInheritableProperty('CropBox',
|
||||
/* getArray = */ true);
|
||||
// Reset invalid crop box to media box.
|
||||
if (!Array.isArray(cropBox) || cropBox.length !== 4) {
|
||||
return shadow(this, 'cropBox', this.mediaBox);
|
||||
|
@ -143,7 +131,7 @@ var Page = (function PageClosure() {
|
|||
},
|
||||
|
||||
get rotate() {
|
||||
var rotate = this.getInheritedPageProp('Rotate') || 0;
|
||||
var rotate = this._getInheritableProperty('Rotate') || 0;
|
||||
// Normalize rotation so it's a multiple of 90 and between 0 and 270
|
||||
if (rotate % 90 !== 0) {
|
||||
rotate = 0;
|
||||
|
@ -180,7 +168,7 @@ var Page = (function PageClosure() {
|
|||
|
||||
loadResources: function Page_loadResources(keys) {
|
||||
if (!this.resourcesPromise) {
|
||||
// TODO: add async getInheritedPageProp and remove this.
|
||||
// TODO: add async `_getInheritableProperty` and remove this.
|
||||
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
|
||||
}
|
||||
return this.resourcesPromise.then(() => {
|
||||
|
@ -316,7 +304,7 @@ var Page = (function PageClosure() {
|
|||
|
||||
get annotations() {
|
||||
var annotations = [];
|
||||
var annotationRefs = this.getInheritedPageProp('Annots') || [];
|
||||
var annotationRefs = this._getInheritableProperty('Annots') || [];
|
||||
for (var i = 0, n = annotationRefs.length; i < n; ++i) {
|
||||
var annotationRef = annotationRefs[i];
|
||||
var annotation = AnnotationFactory.create(this.xref, annotationRef,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue