|
@@ -0,0 +1,944 @@
|
|
|
+import EventHandler from './EventHandler';
|
|
|
+import annotationStore from "./annotation_store";
|
|
|
+
|
|
|
+/**
|
|
|
+ * Represents an object that manages the Annotations that appear on a Document's pages when displayed in a DocumentViewer.
|
|
|
+ * @memberof Core
|
|
|
+ */
|
|
|
+class AnnotationManager extends EventHandler {
|
|
|
+ /**
|
|
|
+ * Creates a new instance of AnnotationManager.
|
|
|
+ * @extends Core.EventHandler
|
|
|
+ * @param {Core.DocumentViewer} docViewer
|
|
|
+ */
|
|
|
+ constructor(docViewer) {
|
|
|
+ super();
|
|
|
+ this.docViewer = docViewer;
|
|
|
+ this.annotations = null;
|
|
|
+
|
|
|
+ this.addEventListener('annotationChange', this.handleAnnotationChange.bind(this));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The different action types for the annotationChanged event.
|
|
|
+ * @property {string} ADD - When the annotationChanged event triggered due to adding annotations
|
|
|
+ * @property {string} DELETE - When the annotationChanged event triggered due to deleting annotations
|
|
|
+ * @property {string} MODIFY - When the annotationChanged event triggered due to modifying annotations
|
|
|
+ */
|
|
|
+ static get AnnotationChangedActions() {
|
|
|
+ return {
|
|
|
+ ADD: 'ADD',
|
|
|
+ DELETE: 'DELETE',
|
|
|
+ MODIFY: 'MODIFY'
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @property {string} ANNOTATION_SELECTED - [Core.AnnotationManager.annotationSelected]{@link Core.AnnotationManager#event:annotationSelected}
|
|
|
+ * @property {string} ANNOTATION_DESELECTED - [Core.AnnotationManager.annotationDeselected]{@link Core.AnnotationManager#event:annotationDeselected}
|
|
|
+ * @property {string} ANNOTATION_DOUBLE_CLICKED - [Core.AnnotationManager.annotationDoubleClicked]{@link Core.AnnotationManager#event:annotationDoubleClicked}
|
|
|
+ * @property {string} ANNOTATION_CHANGED - [Core.AnnotationManager.annotationChanged]{@link Core.AnnotationManager#event:annotationChanged}
|
|
|
+ * @property {string} ANNOTATION_NUMBERING_UPDATED - [Core.AnnotationManager.annotationNumberingUpdated]{@link Core.AnnotationManager#event:annotationNumberingUpdated}
|
|
|
+ * @property {string} UPDATE_ANNOTATION_PERMISSION - [Core.AnnotationManager.updateAnnotationPermission]{@link Core.AnnotationManager#event:updateAnnotationPermission}
|
|
|
+ * @property {string} ANNOTATIONS_DRAWN - [Core.AnnotationManager.annotationsDrawn]{@link Core.AnnotationManager#event:annotationsDrawn}
|
|
|
+ * @property {string} ANNOTATION_HIDDEN - [Core.AnnotationManager.annotationHidden]{@link Core.AnnotationManager#event:annotationHidden}
|
|
|
+ * @property {string} SET_NOTE_TEXT - [Core.AnnotationManager.setNoteText]{@link Core.AnnotationManager#event:setNoteText}
|
|
|
+ * @property {string} ADD_REPLY - [Core.AnnotationManager.addReply]{@link Core.AnnotationManager#event:addReply}
|
|
|
+ * @property {string} DELETE_REPLY - [Core.AnnotationManager.deleteReply]{@link Core.AnnotationManager#event:deleteReply}
|
|
|
+ * @property {string} FIELD_CHANGED - [Core.AnnotationManager.fieldChanged]{@link Core.AnnotationManager#event:fieldChanged}
|
|
|
+ * @property {string} FILE_ATTACHMENT_DATA_AVAILABLE - [Core.AnnotationManager.fileAttachmentDataAvailable]{@link Core.AnnotationManager#event:fileAttachmentDataAvailable}
|
|
|
+ */
|
|
|
+ static get Events() {
|
|
|
+ return {
|
|
|
+ ANNOTATION_SELECTED: 'ANNOTATION_SELECTED',
|
|
|
+ ANNOTATION_DESELECTED: 'ANNOTATION_DESELECTED',
|
|
|
+ ANNOTATION_DOUBLE_CLICKED: 'ANNOTATION_DOUBLE_CLICKED',
|
|
|
+ ANNOTATION_CHANGED: 'ANNOTATION_CHANGED',
|
|
|
+ ANNOTATION_NUMBERING_UPDATED: 'ANNOTATION_NUMBERING_UPDATED',
|
|
|
+ UPDATE_ANNOTATION_PERMISSION: 'UPDATE_ANNOTATION_PERMISSION',
|
|
|
+ ANNOTATIONS_DRAWN: 'ANNOTATIONS_DRAWN',
|
|
|
+ ANNOTATION_HIDDEN: 'ANNOTATION_HIDDEN',
|
|
|
+ SET_NOTE_TEXT: 'SET_NOTE_TEXT',
|
|
|
+ ADD_REPLY: 'ADD_REPLY',
|
|
|
+ DELETE_REPLY: 'DELETE_REPLY',
|
|
|
+ FIELD_CHANGED: 'FIELD_CHANGED',
|
|
|
+ FILE_ATTACHMENT_DATA_AVAILABLE: 'FILE_ATTACHMENT_DATA_AVAILABLE'
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Represents the types of rotations available to perform on an annotation.
|
|
|
+ * @property {string} SNAP_ROTATION - Rotate an annotation in discrete steps, such as 45 or 90 degrees
|
|
|
+ * @property {string} FREEFORM_ROTATION - Rotate an annotation continuously
|
|
|
+ */
|
|
|
+ static get RotationTypes() {
|
|
|
+ return {
|
|
|
+ SNAP_ROTATION: 'SNAP_ROTATION',
|
|
|
+ FREEFORM_ROTATION: 'FREEFORM_ROTATION'
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Represents the types of tabbing orders available to set on widgets in the document.
|
|
|
+ * @property {string} STRUCTURE - Order widgets according to the order found in the internal structure. This is default
|
|
|
+ * @property {string} ROW - Order widgets in terms of rows
|
|
|
+ * @property {string} COLUMN - Order widgets in terms of columns
|
|
|
+ */
|
|
|
+ static get TabbingOrders() {
|
|
|
+ return {
|
|
|
+ STRUCTURE: 'STRUCTURE',
|
|
|
+ ROW: 'ROW',
|
|
|
+ COLUMN: 'COLUMN'
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ async handleAnnotationChange(data) {
|
|
|
+ let annotation = data.annotation
|
|
|
+ this.annotationHistory.push(annotation)
|
|
|
+ const formTypes = ['textfield', 'checkbox', 'radiobutton', 'listbox', 'combobox', 'pushbutton', 'signatureFields']
|
|
|
+ const markupTypes = ['highlight', 'underline', 'strikeout', 'squiggly']
|
|
|
+ if (data.type === 'add') {
|
|
|
+ if (!Array.isArray(annotation)) {
|
|
|
+ annotation = [annotation]
|
|
|
+ }
|
|
|
+ const length = annotation.length
|
|
|
+ for (let i = 0; i < length; i++) {
|
|
|
+ if (Number(annotation[i].pageIndex) + 1 > this.pagesCount) continue
|
|
|
+ if (formTypes.includes(annotation[i].type)) {
|
|
|
+ annotation[i].operate = "add-form"
|
|
|
+ } else {
|
|
|
+ annotation[i].operate = "add-annot"
|
|
|
+ annotation[i].author = this.annotator
|
|
|
+ }
|
|
|
+
|
|
|
+ if (markupTypes.includes(annotation[i].type)) {
|
|
|
+ const quadPoints = []
|
|
|
+ if (!annotation[i].quadPoints[0].PointX && !annotation[i].quadPoints[0].PointY) {
|
|
|
+ for (let j = 0; j < annotation[i].quadPoints.length; j++) {
|
|
|
+ const quadPoint = annotation[i].quadPoints[j]
|
|
|
+ const left = quadPoint.left
|
|
|
+ const top = quadPoint.top
|
|
|
+ const right = quadPoint.right
|
|
|
+ const bottom = quadPoint.bottom
|
|
|
+
|
|
|
+ quadPoints.push({
|
|
|
+ PointX: left,
|
|
|
+ PointY: top,
|
|
|
+ })
|
|
|
+ quadPoints.push({
|
|
|
+ PointX: right,
|
|
|
+ PointY: top,
|
|
|
+ })
|
|
|
+ quadPoints.push({
|
|
|
+ PointX: left,
|
|
|
+ PointY: bottom,
|
|
|
+ })
|
|
|
+ quadPoints.push({
|
|
|
+ PointX: right,
|
|
|
+ PointY: bottom,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ annotation[i].quadPoints = quadPoints
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await this.handleAnnotations(annotation[i])
|
|
|
+ if (result && result.code) return false
|
|
|
+ if (this.docViewer.pdfViewer) {
|
|
|
+ this.docViewer.pdfViewer.renderAnnotation(annotation[i], !!data.show)
|
|
|
+ }
|
|
|
+ annotation[i].targetPage = annotation[i].pageIndex * 1 + 1
|
|
|
+ let currentAnnotation = JSON.parse(JSON.stringify(annotation[i]))
|
|
|
+ if (currentAnnotation.inklist) {
|
|
|
+ currentAnnotation = this.handleInk(currentAnnotation)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const annotations = this.annotations[annotation.pageIndex]
|
|
|
+ if (!annotations) return
|
|
|
+ const index = findIndex(annotation.name, annotations)
|
|
|
+ if (data.type === 'delete') {
|
|
|
+ const annot = annotations[index]
|
|
|
+ let result = null
|
|
|
+ if (annot.replies?.length) {
|
|
|
+ result = await this.messageHandler.sendWithPromise('RemoveFromPageIncludeReplyAnnot', {
|
|
|
+ pagePtr: annot.pagePtr,
|
|
|
+ annotPtr: annotation.annotPtr
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ result = await this.messageHandler.sendWithPromise('RemoveAnnot', {
|
|
|
+ annotPtr: annotation.annotPtr
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result && result.code) {
|
|
|
+ console.log(result.message)
|
|
|
+ alert(result.message)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ annotations.splice(index, 1)
|
|
|
+ if (!annotations.length) {
|
|
|
+ delete this.annotations[annotation.pageIndex]
|
|
|
+ }
|
|
|
+ } else if (data.type === 'empty') {
|
|
|
+ annotations.splice(index, 1)
|
|
|
+ if (!annotations.length) {
|
|
|
+ delete this.annotations[annotation.pageIndex]
|
|
|
+ }
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ annotation.doc = this.doc
|
|
|
+ const result = await this.messageHandler.sendWithPromise('EditAnnotation', { annotation })
|
|
|
+
|
|
|
+ if (result && result.code) {
|
|
|
+ console.log(result.message)
|
|
|
+ alert(result.message)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const rawAnnotation = annotations[index]
|
|
|
+ annotations[index] = {
|
|
|
+ ...rawAnnotation,
|
|
|
+ ...annotation
|
|
|
+ }
|
|
|
+ }
|
|
|
+ annotation.targetPage = annotation.pageIndex + 1
|
|
|
+
|
|
|
+ let currentAnnotation = annotation
|
|
|
+ if (currentAnnotation.inklist) {
|
|
|
+ currentAnnotation = this.handleInk(currentAnnotation)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.annotationChanged(this.annotations);
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ async handleAnnotations(annotation, init = false) {
|
|
|
+ if (!this.annotations) {
|
|
|
+ this.annotations = {}
|
|
|
+ }
|
|
|
+ if (init) {
|
|
|
+ this.initAddAnnotations(annotation)
|
|
|
+ } else {
|
|
|
+ if (Number(annotation.pageIndex) + 1 > this.pagesCount) return
|
|
|
+ this.pushAnnotations(annotation)
|
|
|
+ if ('destPage' in annotation) {
|
|
|
+ annotation.doc = this.doc
|
|
|
+ annotation.pageHeight = this.pagesPtr[annotation.pageIndex].height
|
|
|
+ }
|
|
|
+ const pagePtr = this.pagesPtr[annotation.pageIndex].pagePtr
|
|
|
+ const result = await this.messageHandler.sendWithPromise('CreateAnnotation', {
|
|
|
+ doc: this.doc,
|
|
|
+ pagePtr,
|
|
|
+ annotation
|
|
|
+ })
|
|
|
+
|
|
|
+ if (result && result.code) {
|
|
|
+ console.log(result.message)
|
|
|
+ alert(result.message)
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ const { annotPtr } = result
|
|
|
+
|
|
|
+ annotation.pagePtr = pagePtr
|
|
|
+ annotation.annotPtr = annotPtr
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pushAnnotations(annotation) {
|
|
|
+ const pageIndex = annotation.pageIndex
|
|
|
+ const annotations = this.annotations
|
|
|
+ if (!annotations[pageIndex]) {
|
|
|
+ annotations[pageIndex] = []
|
|
|
+ this.docViewer.pdfViewer._pages[pageIndex].annotations = annotations[pageIndex]
|
|
|
+ }
|
|
|
+ if (!annotationStore.annotationsAll) {
|
|
|
+ annotationStore.annotationsAll = annotations
|
|
|
+ }
|
|
|
+ annotations[pageIndex].push(annotation)
|
|
|
+ }
|
|
|
+
|
|
|
+ initAddAnnotations(annotation) {
|
|
|
+ const pageIndex = annotation.pageIndex
|
|
|
+ const annotations = this.annotations
|
|
|
+ if (!annotations[pageIndex]) {
|
|
|
+ annotations[pageIndex] = []
|
|
|
+ }
|
|
|
+ if (typeof annotation.index !== 'undefined') {
|
|
|
+ annotations[pageIndex][annotation.index] = annotation
|
|
|
+ } else {
|
|
|
+ annotations[pageIndex].push(annotation)
|
|
|
+ }
|
|
|
+ if (!annotationStore.annotationsAll) {
|
|
|
+ annotationStore.annotationsAll = annotations
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理回复注释
|
|
|
+ async handleReplyAnnotation(data) {
|
|
|
+ const { type, annotation, reply, reviewAnnotState, markedAnnotState } = data
|
|
|
+ const { pagePtr, annotPtr } = annotation
|
|
|
+
|
|
|
+ const annot = this.annotations[annotation.pageIndex].find(item => item?.name === annotation.name)
|
|
|
+ if (!annot) return
|
|
|
+
|
|
|
+ if (type === 'add') {
|
|
|
+ if (reply) { // 添加回复
|
|
|
+ reply.name = uuidv4()
|
|
|
+ await this.messageHandler.sendWithPromise('CreateReplyAnnotation', {
|
|
|
+ pagePtr,
|
|
|
+ annotPtr,
|
|
|
+ reply
|
|
|
+ })
|
|
|
+ const { replies, markedAnnotState, reviewAnnotState } = await this.messageHandler.sendWithPromise('GetReplyAnnotation', {
|
|
|
+ pagePtr,
|
|
|
+ annotPtr
|
|
|
+ })
|
|
|
+ if (replies.length) {
|
|
|
+ replies.forEach(reply => reply.name = uuidv4())
|
|
|
+ annot.replies = replies
|
|
|
+ }
|
|
|
+ if (reviewAnnotState) annot.reviewAnnotState = reviewAnnotState
|
|
|
+ if (markedAnnotState) annot.markedAnnotState = markedAnnotState
|
|
|
+ }
|
|
|
+
|
|
|
+ if (reviewAnnotState || markedAnnotState) { // 添加有状态回复(首次设置注释状态)
|
|
|
+ const newState = await this.messageHandler.sendWithPromise('CreateReplyStateAnnotation', {
|
|
|
+ pagePtr,
|
|
|
+ annotPtr,
|
|
|
+ state: reviewAnnotState || markedAnnotState
|
|
|
+ })
|
|
|
+ if (markedAnnotState) annot.markedAnnotState = newState
|
|
|
+ else annot.reviewAnnotState = newState
|
|
|
+ }
|
|
|
+
|
|
|
+ this.addReply(annotation, reply);
|
|
|
+
|
|
|
+ } else if (type === 'delete') {
|
|
|
+ await this.messageHandler.sendWithPromise('RemoveAnnot', {
|
|
|
+ annotPtr: reply.annotPtr
|
|
|
+ })
|
|
|
+ annot.replies = annot.replies.filter(item => item.name !== reply.name)
|
|
|
+ annot.replies.forEach(item => {
|
|
|
+ if (item.index > reply.index) {
|
|
|
+ item.index--
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.deleteReply(reply, annot);
|
|
|
+
|
|
|
+ } else if (type === 'edit') {
|
|
|
+ if (markedAnnotState || reviewAnnotState) { // 修改注释状态
|
|
|
+ const newState = await this.messageHandler.sendWithPromise('SetState', {
|
|
|
+ reviewAnnotState,
|
|
|
+ markedAnnotState
|
|
|
+ })
|
|
|
+ if (markedAnnotState) {
|
|
|
+ annot.markedAnnotState = newState
|
|
|
+ }
|
|
|
+ if (reviewAnnotState) {
|
|
|
+ annot.reviewAnnotState = newState
|
|
|
+ }
|
|
|
+ } else { // 修改回复内容
|
|
|
+ this.messageHandler.sendWithPromise('EditReplyAnnotation', {
|
|
|
+ reply
|
|
|
+ })
|
|
|
+ const index = annot.replies.findIndex(obj => obj.name === reply.name)
|
|
|
+ const replyItem = annot.replies[index]
|
|
|
+ annot.replies[index] = {
|
|
|
+ ...replyItem,
|
|
|
+ ...reply
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.annotationChanged(this.annotations);
|
|
|
+ }
|
|
|
+
|
|
|
+ async exportXfdf(download = false) {
|
|
|
+ let xfdfString = ''
|
|
|
+ const result = await this.messageHandler.sendWithPromise('XFDFExportAnnotations', {
|
|
|
+ doc: this.doc
|
|
|
+ })
|
|
|
+
|
|
|
+ if (result && result.code) {
|
|
|
+ console.log(result.message)
|
|
|
+ alert(result.message)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ xfdfString = result.Content
|
|
|
+
|
|
|
+ if (download) {
|
|
|
+ const name = this._docName.replace(/\.pdf$/, '.xfdf')
|
|
|
+ const blob = new Blob([xfdfString], { type: 'application/xml' })
|
|
|
+ saveAs(blob, name)
|
|
|
+ return true
|
|
|
+ } else {
|
|
|
+ return xfdfString
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async importAnnotations(data) {
|
|
|
+ const source = await new Promise((resolve) => {
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = (event) => {
|
|
|
+ const contents = event.target.result
|
|
|
+ resolve(contents)
|
|
|
+ };
|
|
|
+
|
|
|
+ if (this.webviewerServer) {
|
|
|
+ reader.readAsText(data);
|
|
|
+ } else {
|
|
|
+ reader.readAsArrayBuffer(data);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const xfdfBuffer = new Uint8Array(source)
|
|
|
+ const result = await this.messageHandler.sendWithPromise('XFDFImportAnnotations', {
|
|
|
+ doc: this.doc,
|
|
|
+ xfdfBuffer
|
|
|
+ })
|
|
|
+
|
|
|
+ if (result && result.code) {
|
|
|
+ console.log(result.message)
|
|
|
+ alert(result.message)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ this.emptyAnnotations()
|
|
|
+ this.reRenderAnnotations()
|
|
|
+ // for (let i = 0; i < len; i++) {
|
|
|
+ // const item = annotationsXml[i]
|
|
|
+ // const data = {
|
|
|
+ // annotationType: 3,
|
|
|
+ // fontSize: 10,
|
|
|
+ // value: item.obj_attr.content,
|
|
|
+ // rotation: 0,
|
|
|
+ // position: item.obj_attr.position,
|
|
|
+ // type: 'custom'
|
|
|
+ // }
|
|
|
+ // this.pdfViewer._pages[annotationsXml[i].obj_attr.page].pdfAnnotationLayer.deserialize(data)
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ emptyAnnotations() {
|
|
|
+ const annotations = this.annotations
|
|
|
+ if (this.annotations) {
|
|
|
+ for (let pageIndex in annotations) {
|
|
|
+ this.docViewer.pdfViewer._pages[pageIndex].emptyAnnotations()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async reRenderAnnotations() {
|
|
|
+ this.annotations = null
|
|
|
+ const annotations = []
|
|
|
+ const pagesPtr = this.pagesPtr
|
|
|
+
|
|
|
+ for (let pageIndex = 0; pageIndex < pagesPtr.length; pageIndex++) {
|
|
|
+ const pagePtr = pagesPtr[pageIndex]
|
|
|
+ const data = await this.messageHandler.sendWithPromise('InitAnnot', {
|
|
|
+ pageIndex,
|
|
|
+ pagePtr: pagePtr.pagePtr
|
|
|
+ })
|
|
|
+ for (let annotCountNum = 0; annotCountNum < data.annotCount; annotCountNum++) {
|
|
|
+ const annotation = data.annotations[annotCountNum]
|
|
|
+ const typeInt = annotation.type
|
|
|
+ const type = AnnotationTypeString[typeInt]
|
|
|
+ annotation.pageIndex = pageIndex
|
|
|
+ annotation.type = type
|
|
|
+ let attr = null
|
|
|
+ if (type === 'widget') {
|
|
|
+ attr = await this.messageHandler.sendWithPromise('GetWidgetAnnotation', {
|
|
|
+ doc: this.doc,
|
|
|
+ annotPtr: annotation.annotPtr,
|
|
|
+ pagePtr: annotation.pagePtr,
|
|
|
+ typeInt
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ attr = await this.messageHandler.sendWithPromise('GetAnnotation', {
|
|
|
+ doc: this.doc,
|
|
|
+ annotPtr: annotation.annotPtr,
|
|
|
+ pagePtr: annotation.pagePtr,
|
|
|
+ typeInt,
|
|
|
+ scale: this.scale
|
|
|
+ })
|
|
|
+ if (attr && attr.replies && attr.replies.length) attr.replies.forEach(reply => reply.name = uuidv4())
|
|
|
+ }
|
|
|
+ Object.assign(annotation, attr)
|
|
|
+ annotations.push(annotation)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let index = 0; index < annotations.length; index++) {
|
|
|
+ if (!this.annotations) {
|
|
|
+ this.annotations = {}
|
|
|
+ }
|
|
|
+ this.pushAnnotations(annotations[index])
|
|
|
+
|
|
|
+ this.docViewer.pdfViewer.renderAnnotation(annotations[index])
|
|
|
+ }
|
|
|
+ this.annotationChanged(this.annotations);
|
|
|
+ }
|
|
|
+
|
|
|
+ handleInk(annotation) {
|
|
|
+ let rawAnnotation = JSON.parse(JSON.stringify(annotation))
|
|
|
+ let inklist = ''
|
|
|
+ let inkArray = []
|
|
|
+ if (Array.isArray(rawAnnotation.inklist)) {
|
|
|
+ inkArray = rawAnnotation.inklist
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ inkArray.push(rawAnnotation.inklist)
|
|
|
+ }
|
|
|
+ for (let i = 0; i < inkArray.length; i++) {
|
|
|
+ inklist = inklist + inkArray[i].replaceAll(';', ',') + '//'
|
|
|
+ }
|
|
|
+ rawAnnotation.inklist = inklist// rawAnnotation.inklist.replaceAll(';', ',') + '//'
|
|
|
+ return rawAnnotation
|
|
|
+ }
|
|
|
+
|
|
|
+ initAnnotations(annotations, render = false) {
|
|
|
+ for (let index = 0; index < annotations.length; index++) {
|
|
|
+ const result = this.handleAnnotations(annotations[index], true)
|
|
|
+ if (result && result.code) return false
|
|
|
+ render && this.docViewer.pdfViewer.renderAnnotation(annotations[index])
|
|
|
+ }
|
|
|
+ this.annotationChanged(this.annotations);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Adds the specified annotation to the managed list of annotations.
|
|
|
+ * @param {Core.Annotations.Annotation|Array.<Core.Annotations.Annotation>} annotation - An array of annotations.
|
|
|
+ * @param {object} [options] - An object that can contain the following optional parameters.
|
|
|
+ * @param {boolean} [options.imported=false] - Whether the annotations were imported from another source or not
|
|
|
+ * @param {boolean} [options.isUndoRedo=false] - Whether the annotation change was caused by undo/redo or not
|
|
|
+ * @param {boolean} [options.autoFocus=false] - Whether the annotation's text input should be automatically focused if applicable. Relevant to FreeText and Callout annotations.
|
|
|
+ * @param {string} [options.source] - What type of action cause this event (i.e. "redactionApplied")
|
|
|
+ */
|
|
|
+ addAnnotation(annotation, options) {
|
|
|
+ if (!Array.isArray(annotation)) {
|
|
|
+ annotation = [annotation];
|
|
|
+ }
|
|
|
+ this.addAnnotations(annotation);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Adds the specified annotations to the managed list of annotations.
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annotations - An array of annotations.
|
|
|
+ * @param {object} [options] - An object that can contain the following optional parameters.
|
|
|
+ * @param {boolean} [options.imported=false] - Whether the annotations were imported from another source or not
|
|
|
+ * @param {boolean} [options.isUndoRedo=false] - Whether the annotation change was caused by undo/redo or not
|
|
|
+ * @param {boolean} [options.autoFocus=false] - Whether the annotation's text input should be automatically focused if applicable. Relevant to FreeText and Callout annotations.
|
|
|
+ * @param {string} [options.source] - What type of action cause this event (i.e. "redactionApplied")
|
|
|
+ */
|
|
|
+ addAnnotations(annotations, options) {
|
|
|
+ annotations.forEach(item => {
|
|
|
+ this.handleAnnotationChange({ type: 'add', annotation: item })
|
|
|
+ })
|
|
|
+ for (let i = 0; i < annotations.length; i++) {
|
|
|
+ this.annotations.push(annotations[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Whether or not the current user can modify the annotation.
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation to check permissions on.
|
|
|
+ * @returns {boolean} Whether the annotation can be modified or not.
|
|
|
+ */
|
|
|
+ canModify(annotation) {
|
|
|
+ return !annotation.ReadOnly;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Whether or not the current user can modify the annotation's contents.
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation to check permissions on.
|
|
|
+ * @returns {boolean} Whether the annotation's contents can be modified or not.
|
|
|
+ */
|
|
|
+ canModifyContents(annotation) {
|
|
|
+ return !annotation.ReadOnly;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates an annotation that replies to the passed in annotation. Annotation replies are sticky note annotations.
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation to add a reply to
|
|
|
+ * @param {string} initialText - The initialText for the annotation, defaults to the empty string
|
|
|
+ * @returns {Core.Annotations.StickyAnnotation} The created annotation reply
|
|
|
+ */
|
|
|
+ createAnnotationReply(annotation, initialText = '') {
|
|
|
+ const reply = {
|
|
|
+ operate: 'add-annot',
|
|
|
+ type: 'reply',
|
|
|
+ author: this.docViewer.annotator.value,
|
|
|
+ title: this.docViewer.annotator.value,
|
|
|
+ contents: initialText,
|
|
|
+ date: new Date(),
|
|
|
+ pageIndex: selectedAnnot.value.pageIndex,
|
|
|
+ index: selectedAnnot.value.replies?.length || 0
|
|
|
+ }
|
|
|
+ this.handleReplyAnnotation({
|
|
|
+ type: 'add',
|
|
|
+ annotation: [annotation],
|
|
|
+ reply: [reply]
|
|
|
+ })
|
|
|
+ return reply;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Deletes the specified annotation in the managed list of annotations. If an annotation is successfully deleted, the annotationChanged event will be fired with a "delete" action.
|
|
|
+ * @param {Core.Annotations.Annotation|Array.<Core.Annotations.Annotation>} annotation - An instance of Annotation.
|
|
|
+ * @param {object} [options] - An object that can contain the following optional parameters.
|
|
|
+ * @param {boolean} [options.imported=false] - Whether the annotations were imported from another source or not
|
|
|
+ * @param {boolean} [options.isUndoRedo=false] - Whether the annotation change was caused by undo/redo or not
|
|
|
+ * @param {boolean} [options.autoFocus=false] - Whether the annotation's text input should be automatically focused if applicable. Relevant to FreeText and Callout annotations.
|
|
|
+ * @param {string} [options.source] - What type of action cause this event (i.e. "redactionApplied")
|
|
|
+ */
|
|
|
+ deleteAnnotation(annotation, options) {
|
|
|
+ if (!Array.isArray(annotation)) {
|
|
|
+ annotation = [annotation];
|
|
|
+ }
|
|
|
+ this.deleteAnnotations(annotation);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Deletes the specified annotations in the managed list of annotations. If an annotation is successfully deleted, the annotationChanged event will be fired with a "delete" action.
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annotations - An array of annotations.
|
|
|
+ * @param {object} [options] - An object that can contain the following optional parameters.
|
|
|
+ * @param {boolean} [options.imported=false] - Whether the annotations were imported from another source or not
|
|
|
+ * @param {boolean} [options.isUndoRedo=false] - Whether the annotation change was caused by undo/redo or not
|
|
|
+ * @param {boolean} [options.autoFocus=false] - Whether the annotation's text input should be automatically focused if applicable. Relevant to FreeText and Callout annotations.
|
|
|
+ * @param {string} [options.source] - What type of action cause this event (i.e. "redactionApplied")
|
|
|
+ */
|
|
|
+ deleteAnnotations(annotations, options) {
|
|
|
+ const annotationList = this.annotations
|
|
|
+ annotations.forEach(annotation => {
|
|
|
+ const index = annotationList.findIndex(item => item.Id === annotation.Id);
|
|
|
+ if (index > -1) {
|
|
|
+ const annotPtr = annotationList[index].annotPtr
|
|
|
+ Module._RemoveAnnot(annotPtr)
|
|
|
+ annotationList.splice(index, 1)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Exports all annotations as an XFDF (XML) string
|
|
|
+ * @param {object} [options] - Options for the export. Set options.widgets or options.links or options.fields to false to disable exporting of them.
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} [options.annotList] - An array of annotations to only export the XFDF for those particular annotations.
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} [options.annotationList] - An array of annotations to only export the XFDF for those particular annotations.
|
|
|
+ * @param {boolean} [options.widgets] - Whether to export widget information
|
|
|
+ * @param {boolean} [options.links] - Whether to export links information
|
|
|
+ * @param {boolean} [options.fields] - Whether to export fields information
|
|
|
+ * @param {boolean} [options.useDisplayAuthor] - Whether to export annotations with the Display Author name from annotationManager.getDisplayAuthor()
|
|
|
+ * @param {boolean} [options.generateInlineAppearances] - Whether to generate custom appearance strings for annotations that have an appearance generated on export (e.g. freetext). Default: true
|
|
|
+ * @returns {Promise.<string>} Returns a promise that resolves with the XFDF (XML) annotations as a string
|
|
|
+ */
|
|
|
+ exportAnnotations(options) {
|
|
|
+ return this.exportXfdf();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Gets an annotation object by the annotation's ID.
|
|
|
+ * @param {*} id - The ID of the annotation.
|
|
|
+ * @param {*} annotationList - Optionally pass your own array of annotations to search in
|
|
|
+ */
|
|
|
+ getAnnotationById(id, annotationList) {
|
|
|
+ if (annotationList && annotationList.length) return annotationList.find(annotation => annotation.Id === id);
|
|
|
+ return this.annotations.find(annotation => annotation.Id === id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Gets the list of all annotations managed by the AnnotationManager.
|
|
|
+ * @returns {Array.<Core.Annotations.Annotation>} An array of Annotations.
|
|
|
+ */
|
|
|
+ getAnnotationsList() {
|
|
|
+ return this.annotations;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the user name of the current user.
|
|
|
+ * @returns {string} The user name of the current user.
|
|
|
+ */
|
|
|
+ getCurrentUser() {
|
|
|
+ return this.docViewer.annotator;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Annotations may set the author to a unique id which isn't suitable for display in the UI. this function gets the author name of the annotation that should be displayed.
|
|
|
+ * @param {string} annotationUserId - Annotation userId
|
|
|
+ * @returns {string} The display author name
|
|
|
+ */
|
|
|
+ getDisplayAuthor(annotationUserId) {
|
|
|
+ const annotation = this.annotations.find(annotation => annotation.Id === annotationUserId);
|
|
|
+ if (annotation) return annotation.author;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Hides the specified annotation.
|
|
|
+ * @param {Core.Annotations.Annotation} annot - The annotation to hide
|
|
|
+ */
|
|
|
+ hideAnnotation(annot) {
|
|
|
+ if (!Array.isArray(annot)) {
|
|
|
+ annot = [annot];
|
|
|
+ }
|
|
|
+ this.hideAnnotations(annot);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Hides all of the annotations in the list
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annots - Array of annotations to hide
|
|
|
+ */
|
|
|
+ hideAnnotations(annots) {
|
|
|
+ for (let i = 0; i < annots.length; i++) {
|
|
|
+ annots[i].hidden = true;
|
|
|
+ }
|
|
|
+ this.annotationHidden(annots, true)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Loads XFDF annotations into the viewer
|
|
|
+ * @param {string} xfdfString - The XFDF annotations as a string
|
|
|
+ * @param {object} [options] - The options for importing
|
|
|
+ * @param {number} [options.batchSize] - The number of annotations to import in each batch (default 100)
|
|
|
+ * @param {number} [options.batchDelay] - The amount of time in milliseconds to delay between importing each batch (default 0)
|
|
|
+ * @param {Core.Annotations.Annotation|Array.<Core.Annotations.Annotation>} [options.batchSize] - The type of existing annotations that will be removed before import starts (default [])
|
|
|
+ * @returns {Promise.<any>} Returns a promise that resolves with the annotations have been imported
|
|
|
+ */
|
|
|
+ importAnnotations(xfdfString, options) {
|
|
|
+ this.importAnnotations(xfdfString);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Redraws the specified annotation. Note that the entire annotation canvas for the page will be redrawn.
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation to be redrawn.
|
|
|
+ */
|
|
|
+ redrawAnnotation(annotation) {
|
|
|
+ this.docViewer.pdfViewer.renderAnnotation(annotation)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the styles for the annotation
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - an annotation of which the styles will be changed.
|
|
|
+ * @param {object|function} newStyles - if an object is used, it should contain properties of the new styles. If a function is used, the current styles will be passed as its argument and the function should return an object which contains properties of the new styles. Example of valid properties: StrokeColor, TextColor, FillColor, FontSize, Opacity, StrokeThickness, Precision, Scale, OverlayText, Style and Dashes.
|
|
|
+ */
|
|
|
+ async setAnnotationStyles(annotation, newStyles) {
|
|
|
+ const annotations = this.annotations[annotation.pageIndex]
|
|
|
+ if (!annotations) return
|
|
|
+ const index = findIndex(annotation.name, annotations)
|
|
|
+
|
|
|
+ annotation.doc = this.doc
|
|
|
+ Object.keys(newStyles).forEach(key => {
|
|
|
+ if (key in annotation) annotation[key] = newStyles[key];
|
|
|
+ });
|
|
|
+ const result = await this.messageHandler.sendWithPromise('EditAnnotation', { annotation })
|
|
|
+
|
|
|
+ if (result && result.code) {
|
|
|
+ console.log(result.message)
|
|
|
+ alert(result.message)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const rawAnnotation = annotations[index]
|
|
|
+ annotations[index] = {
|
|
|
+ ...rawAnnotation,
|
|
|
+ ...annotation
|
|
|
+ }
|
|
|
+ annotation.targetPage = annotation.pageIndex + 1
|
|
|
+
|
|
|
+ let currentAnnotation = annotation
|
|
|
+ if (currentAnnotation.inklist) {
|
|
|
+ currentAnnotation = this.handleInk(currentAnnotation)
|
|
|
+ }
|
|
|
+
|
|
|
+ this.annotationChanged(this.annotations);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Shows the annotation
|
|
|
+ * @param {Core.Annotations.Annotation} annot - The annotation to show
|
|
|
+ */
|
|
|
+ showAnnotation(annot) {
|
|
|
+ if (!Array.isArray(annot)) {
|
|
|
+ annot = [annot];
|
|
|
+ }
|
|
|
+ this.showAnnotations(annot);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Shows all of the annotations in the list
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annots - Array of annotations to show
|
|
|
+ */
|
|
|
+ showAnnotations(annots) {
|
|
|
+ for (var i = 0; i < annots.length; i++) {
|
|
|
+ annots[i].hidden = false;
|
|
|
+ }
|
|
|
+ this.annotationHidden(annots, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Redraws the annotations on the same page as the specified annotation if the annotation has been added.
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - An instance of Annotation.
|
|
|
+ */
|
|
|
+ updateAnnotation(annotation) {
|
|
|
+ this.redrawAnnotation(annotation);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Updates the annotation state. This is done by creating an annotation that replies to the passed in annotation.
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation to add a reply to
|
|
|
+ * @param {string} state - Annotations may have an author-specific state associated with them. Valid states are for Review stateModel: Accepted, Rejected, Cancelled, Completed, None. Default is None. Valid states are for Marked stateModel: Marked and Unmarked. Default is Unmarked.
|
|
|
+ * @param {string} stateModel - Gets or sets the stateModel of the annotation. stateModel has two statemodels: Marked, Review. Default is Review.
|
|
|
+ * @param {string} message - Message to be set when the state is updated.
|
|
|
+ * @returns {Core.Annotations.StickyAnnotation} The created annotation reply
|
|
|
+ */
|
|
|
+ updateAnnotationState(annotation, state, stateModel, message) {
|
|
|
+ let data
|
|
|
+
|
|
|
+ if (stateModel === 'Review') {
|
|
|
+ if (annotation.reviewAnnotState) {
|
|
|
+ data = {
|
|
|
+ type: 'edit',
|
|
|
+ annotation,
|
|
|
+ reviewAnnotState: annotation.reviewAnnotState.annotPtr ? {
|
|
|
+ annotPtr: annotation.reviewAnnotState.annotPtr,
|
|
|
+ state
|
|
|
+ } : state
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ data = {
|
|
|
+ type: 'add',
|
|
|
+ annotation,
|
|
|
+ reviewAnnotState: state
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (stateModel === 'Marked') {
|
|
|
+ if (annotation.markedAnnotState) {
|
|
|
+ data = {
|
|
|
+ type: 'edit',
|
|
|
+ annotation,
|
|
|
+ markedAnnotState: annotation.markedAnnotState.annotPtr ? {
|
|
|
+ annotPtr: annotation.markedAnnotState.annotPtr,
|
|
|
+ state: annotation.markedAnnotState.state === 'MARKED' ? 'UNMARKED' : 'MARKED'
|
|
|
+ } : (annotation.markedAnnotState === 'MARKED' ? 'UNMARKED' : 'MARKED')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ data = {
|
|
|
+ type: 'add',
|
|
|
+ annotation,
|
|
|
+ markedAnnotState: state
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ data && this.handleReplyAnnotation(data)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered when a reply has been added to an annotation
|
|
|
+ * @event Core.AnnotationManager#addReply
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation that was added
|
|
|
+ * @param {Core.Annotations.Annotation} parent - The annotation that is the direct parent of the first annotation
|
|
|
+ * @param {Core.Annotations.Annotation} root - The annotation that is the root parent of the first annotation (may be the same as parent)
|
|
|
+ */
|
|
|
+ addReply(annotation, reply) {
|
|
|
+ this.trigger('addReply', {
|
|
|
+ annotation: reply,
|
|
|
+ parent: annotation,
|
|
|
+ root: annotation
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered when an annotation or annotations have been changed (added, deleted, modified). Attach like annotManager.addEventListener('annotationChanged', callback)
|
|
|
+ * @event Core.AnnotationManager#annotationChanged
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annotations - The annotations that were changed
|
|
|
+ * @param {string} action - The action that occurred (add, delete, modify)
|
|
|
+ * @param {Core.AnnotationManager.AnnotationChangedInfoObject} info - An object containing extra information about the annotationChanged event
|
|
|
+ */
|
|
|
+ annotationChanged(annotations, action, info) {
|
|
|
+ this.trigger('annotationChanged', {
|
|
|
+ annotations,
|
|
|
+ action,
|
|
|
+ info
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered after annotations have been deselected.
|
|
|
+ * @event Core.AnnotationManager#annotationDeselected
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annotationList - List of annotations that have been deselected.
|
|
|
+ */
|
|
|
+ annotationDeselected(annotations) {
|
|
|
+ this.trigger('annotationDeselected', annotations);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered after an annotation has been double clicked
|
|
|
+ * @event Core.AnnotationManager#annotationDoubleClicked
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation that has been double clicked
|
|
|
+ */
|
|
|
+ annotationDoubleClicked(annotation) {
|
|
|
+ this.trigger('annotationDoubleClicked', annotation);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered after annotations have been hidden/shown.
|
|
|
+ * @event Core.AnnotationManager#annotationHidden
|
|
|
+ * @param {Array.<Core.Annotations.Annotation>} annotationList - List of annotations that were hidden or shown
|
|
|
+ * @param {boolean} hidden - Whether the annotations have been hidden or shown
|
|
|
+ */
|
|
|
+ annotationHidden(annotationList, hidden) {
|
|
|
+ this.trigger('annotationHidden', {
|
|
|
+ annotationList,
|
|
|
+ hidden
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered after annotations have been drawn for a page
|
|
|
+ * @event Core.AnnotationManager#annotationsDrawn
|
|
|
+ * @param {object} pageNumber - The page number of all the annotations that were just drawn
|
|
|
+ */
|
|
|
+ annotationsDrawn() {}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Triggered when a reply has been deleted from an annotation
|
|
|
+ * @event Core.AnnotationManager#deleteReply
|
|
|
+ * @param {Core.Annotations.Annotation} annotation - The annotation that was deleted
|
|
|
+ * @param {Core.Annotations.Annotation} root - The annotation that is the root parent of the first annotation
|
|
|
+ */
|
|
|
+ deleteReply(reply, annotation) {
|
|
|
+ this.trigger('deleteReply', {
|
|
|
+ annotation: reply,
|
|
|
+ root: annotation
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @typedef {object} Core.AnnotationManager.AnnotationChangedInfoObject
|
|
|
+ * @property {boolean} imported - A boolean that will be true if the annotation change is the result of importing annotations using importAnnotations, importAnnotationCommand or if the imported parameter is set to true when calling addAnnotations or deleteAnnotations
|
|
|
+ * @property {boolean} isUndoRedo - A boolean that will be true if the annotation change is the result of an undo or redo action
|
|
|
+ * @property {string} source - An optional string that indicates what type of action caused this event (i.e. "redactionApplied") Core.AnnotationManager.AnnotationChangedSources
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * Sources for what triggered the annotationChanged event
|
|
|
+ * @typedef {string} Core.AnnotationManager.AnnotationChangedSources
|
|
|
+ * @property {string} MOVE - Source for when the annotation was moved
|
|
|
+ * @property {string} RESIZE - Source for when the annotation was resized
|
|
|
+ * @property {string} ROTATE - Source for when the annotation was rotated
|
|
|
+ * @property {string} TEXT_CHANGED - Source for when the annotation's text was changed (FreeText)
|
|
|
+ * @property {string} NOTE_CHANGED - Source for when the annotation's note was changed
|
|
|
+ * @property {string} DRAGGING_ACROSS_PAGES - Source for when the annotation was dragged across pages
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @ignore
|
|
|
+ * @memberof Core.AnnotationManager
|
|
|
+ */
|
|
|
+class Alignment {}
|
|
|
+
|
|
|
+export { AnnotationManager };
|