Events
The ComPDFKit engine uses a custom EventBus for cross-module communication. The UI layer listens to engine events to keep its state in sync and exposes addEvent / removeEvent so integrators can react to the same events.
The EventBus
The engine's EventBus is exposed through the core bridge:
instance.Core.eventBus(); // the engine's event bus
instance.Core.addEvent(name, handler);
instance.Core.removeEvent(name, handler);eventBus.js in the bridge is a thin accessor — it returns core.getDocumentViewer().eventBus, exposing the engine's own bus. It holds no state of its own.
Common engine events
| Event | Fires when |
|---|---|
annotationSelected / annotationDeselected | An annotation is selected / deselected. |
annotationChanged | Annotations are added/modified/deleted. |
toolChanged | The active tool changes. |
toolModeChanged | The tool mode changes. |
scalechanging | The zoom scale changes. |
pagerendered | A page finishes rendering. |
documentloaded | The document finishes loading. |
onPagesUpdated | Pages are updated (syncs outlines, page count, current page, scale, scroll/spread mode). |
openAnnotationReply | An annotation reply thread is opened. |
updateAnnotationPermission | Annotation permissions change. |
contentEditHistoryChanged / historyChanged | Content-edit / general history changes (drives undo/redo flags). |
changeRightPanelBtnDisabled | Right-panel button disabled state changes. |
presentationmodechanged | Presentation mode toggles. |
How the UI listens
Components register listeners in their setup/mount lifecycle. For example, DocumentContainer.vue registers updateAnnotationPermission, toolModeChanged, toolChanged, annotationSelected/annotationDeselected, openAnnotationReply, onPagesUpdated, annotationChanged, and documentloaded during initViewer().
The createHeaderItemsListener (in components/HeaderItems/HeaderItemsListener.js) watches activeTool and selectedAnnotation to recompute the four property-panel button disabled flags and subscribes to annotationSelected, annotationDeselected, changeRightPanelBtnDisabled, and presentationmodechanged.
useHistoryListener bridges contentEditHistoryChanged / historyChanged into useDocument.setCanUndo / setCanRedo.
Lifecycle note:
helpers/hooks/useOnAnnotationPopupOpen.jsregistersannotationSelected/annotationDeselectedand removes them viaonScopeDispose, so listeners are cleaned up when the owning scope (component setup oreffectScope) disposes. When registering listeners yourself throughcore.addEvent, mirror this by removing them inonUnmounted(oronScopeDispose) to avoid leaks.
Examples
Listen for document load
instance.Core.addEvent('documentloaded', () => {
console.log('Document loaded');
});Listen for annotation changes
const handler = (annotations, type) => {
console.log('annotations', type, annotations);
};
instance.Core.addEvent('annotationChanged', handler);
// later
instance.Core.removeEvent('annotationChanged', handler);Listen for tool changes
instance.Core.addEvent('toolChanged', (toolName) => {
console.log('Active tool:', toolName);
});The viewer-loaded handshake
Beyond engine events, the iframe↔parent handshake uses postMessage:
- The iframe posts
{ type: 'viewerLoaded', docId }towindow.parentwhen the UI is ready (App/index.vueonMounted). webviewer.jslistens for it, capturesiframe.contentWindow.instance, fires areadyCustomEvent on the host element, and posts{ type: 'viewerLoaded', options }back into the iframe.
Integrators can listen for the ready event on the host element, or simply await ComPDFKitViewer.init(...) which resolves with instance once ready.
Related
- Architecture — the bootstrap flow and EventBus role.
- Core Bridge —
eventBus,addEvent,removeEvent. - Helpers, Hooks & Constants —
useOnAnnotationPopupOpen.