diff --git a/src/core/annotation.js b/src/core/annotation.js index 830a31418..8fd3605be 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -47,18 +47,18 @@ class AnnotationFactory { * @private */ static _create(xref, ref, pdfManager, idFactory) { - let dict = xref.fetchIfRef(ref); + const dict = xref.fetchIfRef(ref); if (!isDict(dict)) { return undefined; } - let id = isRef(ref) ? ref.toString() : `annot_${idFactory.createObjId()}`; + const id = isRef(ref) ? ref.toString() : `annot_${idFactory.createObjId()}`; // Determine the annotation's subtype. let subtype = dict.get('Subtype'); subtype = isName(subtype) ? subtype.name : null; // Return the right annotation object based on the subtype and field type. - let parameters = { + const parameters = { xref, dict, subtype, @@ -181,20 +181,16 @@ function getQuadPoints(dict, rect) { function getTransformMatrix(rect, bbox, matrix) { // 12.5.5: Algorithm: Appearance streams - let bounds = Util.getAxialAlignedBoundingBox(bbox, matrix); - let minX = bounds[0]; - let minY = bounds[1]; - let maxX = bounds[2]; - let maxY = bounds[3]; - + const [minX, minY, maxX, maxY] = + Util.getAxialAlignedBoundingBox(bbox, matrix); if (minX === maxX || minY === maxY) { // From real-life file, bbox was [0, 0, 0, 0]. In this case, // just apply the transform for rect return [1, 0, 0, 1, rect[0], rect[1]]; } - let xRatio = (rect[2] - rect[0]) / (maxX - minX); - let yRatio = (rect[3] - rect[1]) / (maxY - minY); + const xRatio = (rect[2] - rect[0]) / (maxX - minX); + const yRatio = (rect[3] - rect[1]) / (maxY - minY); return [ xRatio, 0, @@ -355,7 +351,7 @@ class Annotation { * 4 (CMYK) elements */ setColor(color) { - let rgbColor = new Uint8ClampedArray(3); + const rgbColor = new Uint8ClampedArray(3); if (!Array.isArray(color)) { this.color = rgbColor; return; @@ -405,8 +401,8 @@ class Annotation { return; } if (borderStyle.has('BS')) { - let dict = borderStyle.get('BS'); - let dictType = dict.get('Type'); + const dict = borderStyle.get('BS'); + const dictType = dict.get('Type'); if (!dictType || isName(dictType, 'Border')) { this.borderStyle.setWidth(dict.get('W'), this.rectangle); @@ -414,7 +410,7 @@ class Annotation { this.borderStyle.setDashArray(dict.getArray('D')); } } else if (borderStyle.has('Border')) { - let array = borderStyle.getArray('Border'); + const array = borderStyle.getArray('Border'); if (Array.isArray(array) && array.length >= 3) { this.borderStyle.setHorizontalCornerRadius(array[0]); this.borderStyle.setVerticalCornerRadius(array[1]); @@ -444,13 +440,13 @@ class Annotation { setAppearance(dict) { this.appearance = null; - let appearanceStates = dict.get('AP'); + const appearanceStates = dict.get('AP'); if (!isDict(appearanceStates)) { return; } // In case the normal appearance is a stream, then it is used directly. - let normalAppearanceState = appearanceStates.get('N'); + const normalAppearanceState = appearanceStates.get('N'); if (isStream(normalAppearanceState)) { this.appearance = normalAppearanceState; return; @@ -461,7 +457,7 @@ class Annotation { // In case the normal appearance is a dictionary, the `AS` entry provides // the key of the stream in this dictionary. - let as = dict.get('AS'); + const as = dict.get('AS'); if (!isName(as) || !normalAppearanceState.has(as.name)) { return; } @@ -473,8 +469,8 @@ class Annotation { if (!resources) { return undefined; } - let objectLoader = new ObjectLoader(resources, keys, resources.xref); + const objectLoader = new ObjectLoader(resources, keys, resources.xref); return objectLoader.load().then(function() { return resources; }); @@ -486,24 +482,22 @@ class Annotation { return Promise.resolve(new OperatorList()); } - let data = this.data; - let appearanceDict = this.appearance.dict; - let resourcesPromise = this.loadResources([ + const data = this.data; + const appearanceDict = this.appearance.dict; + const resourcesPromise = this.loadResources([ 'ExtGState', 'ColorSpace', 'Pattern', 'Shading', 'XObject', 'Font', - // ProcSet - // Properties ]); - let bbox = appearanceDict.getArray('BBox') || [0, 0, 1, 1]; - let matrix = appearanceDict.getArray('Matrix') || [1, 0, 0, 1, 0, 0]; - let transform = getTransformMatrix(data.rect, bbox, matrix); + const bbox = appearanceDict.getArray('BBox') || [0, 0, 1, 1]; + const matrix = appearanceDict.getArray('Matrix') || [1, 0, 0, 1, 0, 0]; + const transform = getTransformMatrix(data.rect, bbox, matrix); return resourcesPromise.then((resources) => { - let opList = new OperatorList(); + const opList = new OperatorList(); opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]); return evaluator.getOperatorList({ stream: this.appearance, @@ -624,9 +618,8 @@ class AnnotationBorderStyle { // shall be numbers that are nonnegative and not all equal to zero. let isValid = true; let allZeros = true; - for (let i = 0, len = dashArray.length; i < len; i++) { - let element = dashArray[i]; - let validNumber = (+element >= 0); + for (const element of dashArray) { + const validNumber = (+element >= 0); if (!validNumber) { isValid = false; break; @@ -750,8 +743,8 @@ class WidgetAnnotation extends Annotation { constructor(params) { super(params); - let dict = params.dict; - let data = this.data; + const dict = params.dict; + const data = this.data; data.annotationType = AnnotationType.WIDGET; data.fieldName = this._constructFieldName(dict); @@ -759,7 +752,7 @@ class WidgetAnnotation extends Annotation { getArray: true, }); data.alternativeText = stringToPDFString(dict.get('TU') || ''); data.defaultAppearance = getInheritableProperty({ dict, key: 'DA', }) || ''; - let fieldType = getInheritableProperty({ dict, key: 'FT', }); + const fieldType = getInheritableProperty({ dict, key: 'FT', }); data.fieldType = isName(fieldType) ? fieldType.name : null; this.fieldResources = getInheritableProperty({ dict, key: 'DR', }) || Dict.empty; @@ -804,7 +797,7 @@ class WidgetAnnotation extends Annotation { // Form the fully qualified field name by appending the partial name to // the parent's fully qualified name, separated by a period. - let fieldName = []; + const fieldName = []; if (dict.has('T')) { fieldName.unshift(stringToPDFString(dict.get('T'))); } @@ -887,7 +880,7 @@ class TextWidgetAnnotation extends WidgetAnnotation { return super.getOperatorList(evaluator, task, renderForms); } - let operatorList = new OperatorList(); + const operatorList = new OperatorList(); // Even if there is an appearance stream, ignore it. This is the // behaviour used by Adobe Reader. @@ -895,7 +888,7 @@ class TextWidgetAnnotation extends WidgetAnnotation { return Promise.resolve(operatorList); } - let stream = new Stream(stringToBytes(this.data.defaultAppearance)); + const stream = new Stream(stringToBytes(this.data.defaultAppearance)); return evaluator.getOperatorList({ stream, task, @@ -958,27 +951,26 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { // The parent field's `V` entry holds a `Name` object with the appearance // state of whichever child field is currently in the "on" state. - let fieldParent = params.dict.get('Parent'); + const fieldParent = params.dict.get('Parent'); if (isDict(fieldParent) && fieldParent.has('V')) { - let fieldParentValue = fieldParent.get('V'); + const 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'); + const appearanceStates = params.dict.get('AP'); if (!isDict(appearanceStates)) { return; } - let normalAppearanceState = appearanceStates.get('N'); + const 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]; + for (const key of normalAppearanceState.getKeys()) { + if (key !== 'Off') { + this.data.buttonValue = key; break; } } @@ -1013,9 +1005,9 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { // inherit the options from a parent annotation (issue 8094). this.data.options = []; - let options = getInheritableProperty({ dict: params.dict, key: 'Opt', }); + const options = getInheritableProperty({ dict: params.dict, key: 'Opt', }); if (Array.isArray(options)) { - let xref = params.xref; + const xref = params.xref; for (let i = 0, ii = options.length; i < ii; i++) { let option = xref.fetchIfRef(options[i]); let isOptionArray = Array.isArray(option); @@ -1094,16 +1086,15 @@ class PopupAnnotation extends Annotation { this.data.annotationType = AnnotationType.POPUP; - let dict = parameters.dict; - let parentItem = dict.get('Parent'); + let parentItem = parameters.dict.get('Parent'); if (!parentItem) { warn('Popup annotation has a missing or invalid parent annotation.'); return; } - let parentSubtype = parentItem.get('Subtype'); + const parentSubtype = parentItem.get('Subtype'); this.data.parentType = isName(parentSubtype) ? parentSubtype.name : null; - const rawParent = dict.getRaw('Parent'); + const rawParent = parameters.dict.getRaw('Parent'); this.data.parentId = isRef(rawParent) ? rawParent.toString() : null; const rt = parentItem.get('RT'); @@ -1132,7 +1123,7 @@ class PopupAnnotation extends Annotation { // that is most likely a bug. Fallback to inherit the flags from the parent // annotation (this is consistent with the behaviour in Adobe Reader). if (!this.viewable) { - let parentFlags = parentItem.get('F'); + const parentFlags = parentItem.get('F'); if (this._isViewable(parentFlags)) { this.setFlags(parentFlags); } @@ -1157,8 +1148,8 @@ class LineAnnotation extends MarkupAnnotation { this.data.annotationType = AnnotationType.LINE; - let dict = parameters.dict; - this.data.lineCoordinates = Util.normalizeRect(dict.getArray('L')); + this.data.lineCoordinates = + Util.normalizeRect(parameters.dict.getArray('L')); } } @@ -1187,9 +1178,7 @@ class PolylineAnnotation extends MarkupAnnotation { // The vertices array is an array of numbers representing the alternating // horizontal and vertical coordinates, respectively, of each vertex. // Convert this to an array of objects with x and y coordinates. - let dict = parameters.dict; - let rawVertices = dict.getArray('Vertices'); - + const rawVertices = parameters.dict.getArray('Vertices'); this.data.vertices = []; for (let i = 0, ii = rawVertices.length; i < ii; i += 2) { this.data.vertices.push({ @@ -1223,10 +1212,8 @@ class InkAnnotation extends MarkupAnnotation { this.data.annotationType = AnnotationType.INK; - let dict = parameters.dict; const xref = parameters.xref; - - let originalInkLists = dict.getArray('InkList'); + const originalInkLists = parameters.dict.getArray('InkList'); this.data.inkLists = []; for (let i = 0, ii = originalInkLists.length; i < ii; ++i) { // The raw ink lists array contains arrays of numbers representing @@ -1308,7 +1295,7 @@ class FileAttachmentAnnotation extends MarkupAnnotation { constructor(parameters) { super(parameters); - let file = new FileSpec(parameters.dict.get('FS'), parameters.xref); + const file = new FileSpec(parameters.dict.get('FS'), parameters.xref); this.data.annotationType = AnnotationType.FILEATTACHMENT; this.data.file = file.serializable; diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index f2260fae6..83cdd4baa 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* eslint no-var: error */ import { addLinkAttributes, DOMSVGFactory, getFilenameFromUrl, LinkTarget, @@ -42,7 +43,7 @@ class AnnotationElementFactory { * @returns {AnnotationElement} */ static create(parameters) { - let subtype = parameters.data.annotationType; + const subtype = parameters.data.annotationType; switch (subtype) { case AnnotationType.LINK: @@ -52,7 +53,7 @@ class AnnotationElementFactory { return new TextAnnotationElement(parameters); case AnnotationType.WIDGET: - let fieldType = parameters.data.fieldType; + const fieldType = parameters.data.fieldType; switch (fieldType) { case 'Tx': @@ -147,8 +148,8 @@ class AnnotationElement { * @returns {HTMLSectionElement} */ _createContainer(ignoreBorder = false) { - let data = this.data, page = this.page, viewport = this.viewport; - let container = document.createElement('section'); + const data = this.data, page = this.page, viewport = this.viewport; + const container = document.createElement('section'); let width = data.rect[2] - data.rect[0]; let height = data.rect[3] - data.rect[1]; @@ -156,18 +157,18 @@ class AnnotationElement { // Do *not* modify `data.rect`, since that will corrupt the annotation // position on subsequent calls to `_createContainer` (see issue 6804). - let rect = Util.normalizeRect([ + const rect = Util.normalizeRect([ data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1] ]); - container.style.transform = 'matrix(' + viewport.transform.join(',') + ')'; - container.style.transformOrigin = -rect[0] + 'px ' + -rect[1] + 'px'; + container.style.transform = `matrix(${viewport.transform.join(',')})`; + container.style.transformOrigin = `-${rect[0]}px -${rect[1]}px`; if (!ignoreBorder && data.borderStyle.width > 0) { - container.style.borderWidth = data.borderStyle.width + 'px'; + container.style.borderWidth = `${data.borderStyle.width}px`; if (data.borderStyle.style !== AnnotationBorderStyleType.UNDERLINE) { // Underline styles only have a bottom border, so we do not need // to adjust for all borders. This yields a similar result as @@ -176,10 +177,10 @@ class AnnotationElement { height = height - 2 * data.borderStyle.width; } - let horizontalRadius = data.borderStyle.horizontalCornerRadius; - let verticalRadius = data.borderStyle.verticalCornerRadius; + const horizontalRadius = data.borderStyle.horizontalCornerRadius; + const verticalRadius = data.borderStyle.verticalCornerRadius; if (horizontalRadius > 0 || verticalRadius > 0) { - let radius = horizontalRadius + 'px / ' + verticalRadius + 'px'; + const radius = `${horizontalRadius}px / ${verticalRadius}px`; container.style.borderRadius = radius; } @@ -218,12 +219,10 @@ class AnnotationElement { } } - container.style.left = rect[0] + 'px'; - container.style.top = rect[1] + 'px'; - - container.style.width = width + 'px'; - container.style.height = height + 'px'; - + container.style.left = `${rect[0]}px`; + container.style.top = `${rect[1]}px`; + container.style.width = `${width}px`; + container.style.height = `${height}px`; return container; } @@ -247,7 +246,7 @@ class AnnotationElement { container.appendChild(trigger); } - let popupElement = new PopupElement({ + const popupElement = new PopupElement({ container, trigger, color: data.color, @@ -256,7 +255,7 @@ class AnnotationElement { contents: data.contents, hideWrapper: true, }); - let popup = popupElement.render(); + const popup = popupElement.render(); // Position the popup next to the annotation's container. popup.style.left = container.style.width; @@ -277,8 +276,8 @@ class AnnotationElement { class LinkAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.url || parameters.data.dest || - parameters.data.action); + const isRenderable = !!(parameters.data.url || parameters.data.dest || + parameters.data.action); super(parameters, isRenderable); } @@ -292,8 +291,8 @@ class LinkAnnotationElement extends AnnotationElement { render() { this.container.className = 'linkAnnotation'; - let { data, linkService, } = this; - let link = document.createElement('a'); + const { data, linkService, } = this; + const link = document.createElement('a'); addLinkAttributes(link, { url: data.url, @@ -356,8 +355,8 @@ class LinkAnnotationElement extends AnnotationElement { class TextAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable); } @@ -371,7 +370,7 @@ class TextAnnotationElement extends AnnotationElement { render() { this.container.className = 'textAnnotation'; - let image = document.createElement('img'); + const image = document.createElement('img'); image.style.height = this.container.style.height; image.style.width = this.container.style.width; image.src = this.imageResourcesPath + 'annotation-' + @@ -405,7 +404,7 @@ class WidgetAnnotationElement extends AnnotationElement { class TextWidgetAnnotationElement extends WidgetAnnotationElement { constructor(parameters) { - let isRenderable = parameters.renderInteractiveForms || + const isRenderable = parameters.renderInteractiveForms || (!parameters.data.hasAppearance && !!parameters.data.fieldValue); super(parameters, isRenderable); } @@ -443,11 +442,11 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { } if (this.data.comb) { - let fieldWidth = this.data.rect[2] - this.data.rect[0]; - let combWidth = fieldWidth / this.data.maxLen; + const fieldWidth = this.data.rect[2] - this.data.rect[0]; + const combWidth = fieldWidth / this.data.maxLen; element.classList.add('comb'); - element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)'; + element.style.letterSpacing = `calc(${combWidth}px - 1ch)`; } } else { element = document.createElement('div'); @@ -481,8 +480,8 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { */ _setTextStyle(element, font) { // TODO: This duplicates some of the logic in CanvasGraphics.setFont(). - let style = element.style; - style.fontSize = this.data.fontSize + 'px'; + const style = element.style; + style.fontSize = `${this.data.fontSize}px`; style.direction = (this.data.fontDirection < 0 ? 'rtl' : 'ltr'); if (!font) { @@ -495,8 +494,8 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { style.fontStyle = (font.italic ? 'italic' : 'normal'); // Use a reasonable default font if the font doesn't specify a fallback. - let fontFamily = font.loadedName ? '"' + font.loadedName + '", ' : ''; - let fallbackName = font.fallbackName || 'Helvetica, sans-serif'; + const fontFamily = font.loadedName ? `"${font.loadedName}", ` : ''; + const fallbackName = font.fallbackName || 'Helvetica, sans-serif'; style.fontFamily = fontFamily + fallbackName; } } @@ -517,7 +516,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { render() { this.container.className = 'buttonWidgetAnnotation checkBox'; - let element = document.createElement('input'); + const element = document.createElement('input'); element.disabled = this.data.readOnly; element.type = 'checkbox'; if (this.data.fieldValue && this.data.fieldValue !== 'Off') { @@ -545,7 +544,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { render() { this.container.className = 'buttonWidgetAnnotation radioButton'; - let element = document.createElement('input'); + const element = document.createElement('input'); element.disabled = this.data.readOnly; element.type = 'radio'; element.name = this.data.fieldName; @@ -571,7 +570,7 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { // 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(); + const container = super.render(); container.className = 'buttonWidgetAnnotation pushButton'; return container; } @@ -593,30 +592,25 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { render() { this.container.className = 'choiceWidgetAnnotation'; - let selectElement = document.createElement('select'); + const selectElement = document.createElement('select'); selectElement.disabled = this.data.readOnly; if (!this.data.combo) { // List boxes have a size and (optionally) multiple selection. selectElement.size = this.data.options.length; - if (this.data.multiSelect) { selectElement.multiple = true; } } // Insert the options into the choice field. - for (let i = 0, ii = this.data.options.length; i < ii; i++) { - let option = this.data.options[i]; - - let optionElement = document.createElement('option'); + for (const option of this.data.options) { + const optionElement = document.createElement('option'); optionElement.textContent = option.displayValue; optionElement.value = option.exportValue; - if (this.data.fieldValue.includes(option.displayValue)) { optionElement.setAttribute('selected', true); } - selectElement.appendChild(optionElement); } @@ -627,7 +621,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { class PopupAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.title || parameters.data.contents); super(parameters, isRenderable); } @@ -656,13 +650,13 @@ class PopupAnnotationElement extends AnnotationElement { return this.container; } - let selector = '[data-annotation-id="' + this.data.parentId + '"]'; - let parentElement = this.layer.querySelector(selector); + const selector = `[data-annotation-id="${this.data.parentId}"]`; + const parentElement = this.layer.querySelector(selector); if (!parentElement) { return this.container; } - let popup = new PopupElement({ + const popup = new PopupElement({ container: this.container, trigger: parentElement, color: this.data.color, @@ -673,11 +667,11 @@ class PopupAnnotationElement extends AnnotationElement { // Position the popup next to the parent annotation's container. // PDF viewers ignore a popup annotation's rectangle. - let parentLeft = parseFloat(parentElement.style.left); - let parentWidth = parseFloat(parentElement.style.width); + const parentLeft = parseFloat(parentElement.style.left); + const parentWidth = parseFloat(parentElement.style.width); this.container.style.transformOrigin = - -(parentLeft + parentWidth) + 'px -' + parentElement.style.top; - this.container.style.left = (parentLeft + parentWidth) + 'px'; + `-${parentLeft + parentWidth}px -${parentElement.style.top}`; + this.container.style.left = `${parentLeft + parentWidth}px`; this.container.appendChild(popup.render()); return this.container; @@ -707,7 +701,7 @@ class PopupElement { render() { const BACKGROUND_ENLIGHT = 0.7; - let wrapper = document.createElement('div'); + const wrapper = document.createElement('div'); wrapper.className = 'popupWrapper'; // For Popup annotations we hide the entire section because it contains @@ -717,19 +711,19 @@ class PopupElement { this.hideElement = (this.hideWrapper ? wrapper : this.container); this.hideElement.setAttribute('hidden', true); - let popup = document.createElement('div'); + const popup = document.createElement('div'); popup.className = 'popup'; - let color = this.color; + const color = this.color; if (color) { // Enlighten the color. - let r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0]; - let g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1]; - let b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2]; + const r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0]; + const g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1]; + const b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2]; popup.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0); } - let title = document.createElement('h1'); + const title = document.createElement('h1'); title.textContent = this.title; popup.appendChild(title); @@ -748,7 +742,7 @@ class PopupElement { popup.appendChild(modificationDate); } - let contents = this._formatContents(this.contents); + const contents = this._formatContents(this.contents); popup.appendChild(contents); // Attach the event listeners to the trigger element. @@ -770,10 +764,10 @@ class PopupElement { * @returns {HTMLParagraphElement} */ _formatContents(contents) { - let p = document.createElement('p'); - let lines = contents.split(/(?:\r\n?|\n)/); + const p = document.createElement('p'); + const lines = contents.split(/(?:\r\n?|\n)/); for (let i = 0, ii = lines.length; i < ii; ++i) { - let line = lines[i]; + const line = lines[i]; p.appendChild(document.createTextNode(line)); if (i < (ii - 1)) { p.appendChild(document.createElement('br')); @@ -857,8 +851,8 @@ class FreeTextAnnotationElement extends AnnotationElement { class LineAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -875,14 +869,14 @@ class LineAnnotationElement extends AnnotationElement { // Create an invisible line with the same starting and ending coordinates // that acts as the trigger for the popup. Only the line itself should // trigger the popup, not the entire container. - let data = this.data; - let width = data.rect[2] - data.rect[0]; - let height = data.rect[3] - data.rect[1]; - let svg = this.svgFactory.create(width, height); + const data = this.data; + const width = data.rect[2] - data.rect[0]; + const height = data.rect[3] - data.rect[1]; + const svg = this.svgFactory.create(width, height); // PDF coordinates are calculated from a bottom left origin, so transform // the line coordinates to a top left origin for the SVG element. - let line = this.svgFactory.createElement('svg:line'); + const line = this.svgFactory.createElement('svg:line'); line.setAttribute('x1', data.rect[2] - data.lineCoordinates[0]); line.setAttribute('y1', data.rect[3] - data.lineCoordinates[1]); line.setAttribute('x2', data.rect[2] - data.lineCoordinates[2]); @@ -903,8 +897,8 @@ class LineAnnotationElement extends AnnotationElement { class SquareAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -921,16 +915,16 @@ class SquareAnnotationElement extends AnnotationElement { // Create an invisible square with the same rectangle that acts as the // trigger for the popup. Only the square itself should trigger the // popup, not the entire container. - let data = this.data; - let width = data.rect[2] - data.rect[0]; - let height = data.rect[3] - data.rect[1]; - let svg = this.svgFactory.create(width, height); + const data = this.data; + const width = data.rect[2] - data.rect[0]; + const height = data.rect[3] - data.rect[1]; + const svg = this.svgFactory.create(width, height); // The browser draws half of the borders inside the square and half of // the borders outside the square by default. This behavior cannot be // changed programmatically, so correct for that here. - let borderWidth = data.borderStyle.width; - let square = this.svgFactory.createElement('svg:rect'); + const borderWidth = data.borderStyle.width; + const square = this.svgFactory.createElement('svg:rect'); square.setAttribute('x', borderWidth / 2); square.setAttribute('y', borderWidth / 2); square.setAttribute('width', width - borderWidth); @@ -952,8 +946,8 @@ class SquareAnnotationElement extends AnnotationElement { class CircleAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -970,16 +964,16 @@ class CircleAnnotationElement extends AnnotationElement { // Create an invisible circle with the same ellipse that acts as the // trigger for the popup. Only the circle itself should trigger the // popup, not the entire container. - let data = this.data; - let width = data.rect[2] - data.rect[0]; - let height = data.rect[3] - data.rect[1]; - let svg = this.svgFactory.create(width, height); + const data = this.data; + const width = data.rect[2] - data.rect[0]; + const height = data.rect[3] - data.rect[1]; + const svg = this.svgFactory.create(width, height); // The browser draws half of the borders inside the circle and half of // the borders outside the circle by default. This behavior cannot be // changed programmatically, so correct for that here. - let borderWidth = data.borderStyle.width; - let circle = this.svgFactory.createElement('svg:ellipse'); + const borderWidth = data.borderStyle.width; + const circle = this.svgFactory.createElement('svg:ellipse'); circle.setAttribute('cx', width / 2); circle.setAttribute('cy', height / 2); circle.setAttribute('rx', (width / 2) - (borderWidth / 2)); @@ -1001,8 +995,8 @@ class CircleAnnotationElement extends AnnotationElement { class PolylineAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); this.containerClassName = 'polylineAnnotation'; @@ -1022,28 +1016,26 @@ class PolylineAnnotationElement extends AnnotationElement { // Create an invisible polyline with the same points that acts as the // trigger for the popup. Only the polyline itself should trigger the // popup, not the entire container. - let data = this.data; - let width = data.rect[2] - data.rect[0]; - let height = data.rect[3] - data.rect[1]; - let svg = this.svgFactory.create(width, height); + const data = this.data; + const width = data.rect[2] - data.rect[0]; + const height = data.rect[3] - data.rect[1]; + const svg = this.svgFactory.create(width, height); // Convert the vertices array to a single points string that the SVG // polyline element expects ("x1,y1 x2,y2 ..."). PDF coordinates are // calculated from a bottom left origin, so transform the polyline // coordinates to a top left origin for the SVG element. - let vertices = data.vertices; let points = []; - for (let i = 0, ii = vertices.length; i < ii; i++) { - let x = vertices[i].x - data.rect[0]; - let y = data.rect[3] - vertices[i].y; + for (const coordinate of data.vertices) { + const x = coordinate.x - data.rect[0]; + const y = data.rect[3] - coordinate.y; points.push(x + ',' + y); } points = points.join(' '); - let borderWidth = data.borderStyle.width; - let polyline = this.svgFactory.createElement(this.svgElementName); + const polyline = this.svgFactory.createElement(this.svgElementName); polyline.setAttribute('points', points); - polyline.setAttribute('stroke-width', borderWidth); + polyline.setAttribute('stroke-width', data.borderStyle.width); polyline.setAttribute('stroke', 'transparent'); polyline.setAttribute('fill', 'none'); @@ -1094,8 +1086,8 @@ class CaretAnnotationElement extends AnnotationElement { class InkAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); this.containerClassName = 'inkAnnotation'; @@ -1117,32 +1109,27 @@ class InkAnnotationElement extends AnnotationElement { // Create an invisible polyline with the same points that acts as the // trigger for the popup. - let data = this.data; - let width = data.rect[2] - data.rect[0]; - let height = data.rect[3] - data.rect[1]; - let svg = this.svgFactory.create(width, height); - - let inkLists = data.inkLists; - for (let i = 0, ii = inkLists.length; i < ii; i++) { - let inkList = inkLists[i]; - let points = []; + const data = this.data; + const width = data.rect[2] - data.rect[0]; + const height = data.rect[3] - data.rect[1]; + const svg = this.svgFactory.create(width, height); + for (const inkList of data.inkLists) { // Convert the ink list to a single points string that the SVG // polyline element expects ("x1,y1 x2,y2 ..."). PDF coordinates are // calculated from a bottom left origin, so transform the polyline // coordinates to a top left origin for the SVG element. - for (let j = 0, jj = inkList.length; j < jj; j++) { - let x = inkList[j].x - data.rect[0]; - let y = data.rect[3] - inkList[j].y; - points.push(x + ',' + y); + let points = []; + for (const coordinate of inkList) { + const x = coordinate.x - data.rect[0]; + const y = data.rect[3] - coordinate.y; + points.push(`${x},${y}`); } - points = points.join(' '); - let borderWidth = data.borderStyle.width; - let polyline = this.svgFactory.createElement(this.svgElementName); + const polyline = this.svgFactory.createElement(this.svgElementName); polyline.setAttribute('points', points); - polyline.setAttribute('stroke-width', borderWidth); + polyline.setAttribute('stroke-width', data.borderStyle.width); polyline.setAttribute('stroke', 'transparent'); polyline.setAttribute('fill', 'none'); @@ -1154,15 +1141,14 @@ class InkAnnotationElement extends AnnotationElement { } this.container.append(svg); - return this.container; } } class HighlightAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -1185,8 +1171,8 @@ class HighlightAnnotationElement extends AnnotationElement { class UnderlineAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -1209,8 +1195,8 @@ class UnderlineAnnotationElement extends AnnotationElement { class SquigglyAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -1233,8 +1219,8 @@ class SquigglyAnnotationElement extends AnnotationElement { class StrikeOutAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -1257,8 +1243,8 @@ class StrikeOutAnnotationElement extends AnnotationElement { class StampAnnotationElement extends AnnotationElement { constructor(parameters) { - let isRenderable = !!(parameters.data.hasPopup || - parameters.data.title || parameters.data.contents); + const isRenderable = !!(parameters.data.hasPopup || + parameters.data.title || parameters.data.contents); super(parameters, isRenderable, /* ignoreBorder = */ true); } @@ -1308,7 +1294,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement { render() { this.container.className = 'fileAttachmentAnnotation'; - let trigger = document.createElement('div'); + const trigger = document.createElement('div'); trigger.style.height = this.container.style.height; trigger.style.width = this.container.style.width; trigger.addEventListener('dblclick', this._download.bind(this)); @@ -1358,12 +1344,11 @@ class AnnotationLayer { * @memberof AnnotationLayer */ static render(parameters) { - for (let i = 0, ii = parameters.annotations.length; i < ii; i++) { - let data = parameters.annotations[i]; + for (const data of parameters.annotations) { if (!data) { continue; } - let element = AnnotationElementFactory.create({ + const element = AnnotationElementFactory.create({ data, layer: parameters.div, page: parameters.page, @@ -1388,13 +1373,12 @@ class AnnotationLayer { * @memberof AnnotationLayer */ static update(parameters) { - for (let i = 0, ii = parameters.annotations.length; i < ii; i++) { - let data = parameters.annotations[i]; - let element = parameters.div.querySelector( - '[data-annotation-id="' + data.id + '"]'); + for (const data of parameters.annotations) { + const element = parameters.div.querySelector( + `[data-annotation-id="${data.id}"]`); if (element) { element.style.transform = - 'matrix(' + parameters.viewport.transform.join(',') + ')'; + `matrix(${parameters.viewport.transform.join(',')})`; } } parameters.div.removeAttribute('hidden');