Skip to content

Commit

Permalink
#4547 - Cannot create long-distance relation in PDF editor
Browse files Browse the repository at this point in the history
- Added support for context menu in PDF editor
  • Loading branch information
reckart committed Feb 22, 2024
1 parent bd7881a commit 17fbeba
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ export class PdfAnnotationEditor implements AnnotationEditor {
this.ajax = ajax
this.root = element

element.addEventListener('annotationSelected', ev => this.onAnnotationSelected(ev))
element.addEventListener('createSpanAnnotation', ev => this.onCreateSpanAnnotation(ev))
element.addEventListener('createRelationAnnotation', ev => this.onCreateRelationAnnotation(ev))
element.addEventListener('doubleClickAnnotation', ev => this.onDoubleClickAnnotation(ev))
// Prevent right-click from triggering a selection event
this.root.addEventListener('mousedown', e => this.cancelRightClick(e), { capture: true })
this.root.addEventListener('mouseup', e => this.cancelRightClick(e), { capture: true })
this.root.addEventListener('mouseclick', e => this.cancelRightClick(e), { capture: true })

this.root.addEventListener('annotationSelected', ev => this.onAnnotationSelected(ev))
this.root.addEventListener('createSpanAnnotation', ev => this.onCreateSpanAnnotation(ev))
this.root.addEventListener('createRelationAnnotation', ev => this.onCreateRelationAnnotation(ev))
this.root.addEventListener('doubleClickAnnotation', ev => this.onDoubleClickAnnotation(ev))
this.root.addEventListener('openContextMenu', ev => this.onOpenContextMenu(ev))
}

async init (): Promise<void> {
Expand All @@ -47,6 +53,27 @@ export class PdfAnnotationEditor implements AnnotationEditor {
scrollTo(args)
}

private cancelRightClick (e: Event): void {
if (e instanceof MouseEvent) {
if (e.button === 2) {
console.log("cancelled")
e.preventDefault()
e.stopPropagation()
}
}
}

onOpenContextMenu (ev: Event) {
if (ev instanceof CustomEvent) {
const ann = ev.detail.ann as AbstractAnnotation
const oev = ev.detail.originalEvent

if (!(oev instanceof MouseEvent) || !(oev.target instanceof Node)) return

if (ann.vid) this.ajax.openContextMenu(ann.vid, oev)
}
}

onAnnotationSelected (ev: Event) {
if (ev instanceof CustomEvent) {
const ann = ev.detail as AbstractAnnotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default abstract class AbstractAnnotation extends EventEmitter {
}

/**
* Handle a click event.
* Handle a left-click event.
*/
handleSingleClickEvent (e: Event) {
if (this.element) {
Expand All @@ -110,6 +110,23 @@ export default abstract class AbstractAnnotation extends EventEmitter {
}
}

/**
* Handle a right-click event.
*/
handleRightClickEvent (e: Event) {
if (this.element && e instanceof MouseEvent) {
// If the user shift-right-clicks, open the normal browser context menu. This is useful
// e.g. during debugging / developing
if (e.shiftKey) return

e.preventDefault()

const event = document.createEvent('CustomEvent')
event.initCustomEvent('openContextMenu', true, true, { ann: this, originalEvent: e})
this.element.dispatchEvent(event)
}
}

/**
* Handle a hoverIn event.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default class RelationAnnotation extends AbstractAnnotation {

// Need to bind these event handler methods
this.handleSingleClickEvent = this.handleSingleClickEvent.bind(this)
this.handleRightClickEvent = this.handleRightClickEvent.bind(this)
this.handleHoverInEvent = this.handleHoverInEvent.bind(this)
this.handleHoverOutEvent = this.handleHoverOutEvent.bind(this)

Expand Down Expand Up @@ -220,18 +221,21 @@ export default class RelationAnnotation extends AbstractAnnotation {
super.enableViewMode()

if (!this.readOnly) {
this.element?.querySelectorAll('path').forEach(e =>
e.addEventListener('click', this.handleSingleClickEvent))
}
this.element?.querySelectorAll('path').forEach(e => {
e.addEventListener('click', this.handleSingleClickEvent)
e.addEventListener('contextmenu', this.handleRightClickEvent)
})}
}

/**
* Disable view mode.
*/
disableViewMode () {
super.disableViewMode()
this.element?.querySelectorAll('path').forEach(e =>
e.removeEventListener('click', this.handleSingleClickEvent))
this.element?.querySelectorAll('path').forEach(e => {
e.removeEventListener('click', this.handleSingleClickEvent)
e.removeEventListener('contextmenu', this.handleRightClickEvent)
})
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class SpanAnnotation extends AbstractAnnotation {

// Need to bind these event handler methods
this.handleClickEvent = this.handleClickEvent.bind(this)
this.handleRightClickEvent = this.handleRightClickEvent.bind(this)
this.handleHoverInEvent = this.handleHoverInEvent.bind(this)
this.handleHoverOutEvent = this.handleHoverOutEvent.bind(this)

Expand Down Expand Up @@ -117,6 +118,7 @@ export default class SpanAnnotation extends AbstractAnnotation {
this.element?.querySelectorAll('.anno-knob').forEach(e => {
e.addEventListener('mousedown', this.preventFocusChange)
e.addEventListener('click', this.handleClickEvent)
e.addEventListener('contextmenu', this.handleRightClickEvent)
})
}

Expand Down Expand Up @@ -162,6 +164,7 @@ export default class SpanAnnotation extends AbstractAnnotation {
super.disableViewMode()
this.element?.querySelectorAll('.anno-knob').forEach(e => {
e.removeEventListener('click', this.handleClickEvent)
e.removeEventListener('contextmenu', this.handleRightClickEvent)
e.removeEventListener('mousedown', this.preventFocusChange)
})
}
Expand Down

0 comments on commit 17fbeba

Please sign in to comment.