Helpers, Hooks & Constants
This guide covers the utility modules (helpers/), Vue composables (hooks/), and registries (constants/) that support the UI layer.
Helpers — src/helpers/
| File | Purpose |
|---|---|
device.js | Device/browser detection (detailed below). |
hotkeysManager.js | Minimal keyboard-shortcut manager: register(combo, handler), unregister(combo), initialize(), destroy(). Not yet wired into the app. |
loadDocument.js | Convenience wrapper around core.loadDocument(src, options, docNum) that wires the engine's progress callback to useDocument.setLoadingProgress. Usable helper (the live loading path in DocumentContainer.vue calls core.loadDocument directly). |
initDocument.js | Live bootstrap: new ComPDFKitViewer(options) from lib/webview.min.js, then core.setDocumentViewer(1, documentViewer). |
setupI18n.js | i18next initialization reference (declares Languages[] catalog + languageRules). |
getHashParameters.js | Parses window.location.hash into a key/value object (typed boolean coercion). |
getPopupPosition.js | Computes screen coordinates for annotation popups. |
loadScript.js | loadScript(src, warning) — Promise wrapper injecting <script> into <head>. Also exports loadConfig(initOptions) (the iframe↔parent config handshake). |
renderStampPreview.js | Floating .stamp-preview div that follows the mouse showing a stamp image. |
utils.js | uploadFile(extension), hslToRgb, convertColor, areColorsSimilar(c1, c2, threshold=10). |
annotationPermissions.js | canCopyAnnotations({ isReadOnly, isUserAdmin, currentAuthor, annotations }). |
device.js
Exports booleans/functions computed once at module load from navigator.userAgent and window.innerWidth:
- Layout breakpoints:
isDesktop()(> 900),isTabletOrMobile()(<= 900),isMobile/isMobileSize()(< 640). - OS:
isMac,isWindows,isIOS(incl. iOS 13 MacIntel+touch),isAndroid,isHarmonyOSMobile,isiPad. - Mobile aggregate:
isMobileDevice(iOS || Android || HarmonyOS || webOS/BlackBerry/IEMobile/Opera Mini) andisMobileDeviceFunc(). - Browsers:
isChrome,isSafari,isChromeOniOS,isFirefoxOniOS,isFirefox,isIEEdge,isIEEdgeChromium,isIE11,isIE,isIEEdgeLegacy.
device.js is pulled in by ~27 components/stores; isMobileDevice / isiPad drive the mobile guards in setActiveToolMode / setToolbarGroup.
getPopupPosition.js
getAnnotationPopupPositionBasedOn(rect, pageNumber, popup, documentViewerKey=1, position='right') → { left, top }. Pipeline: convert page-space rect corners to window coords via core.pageToWindow; read popup.getBoundingClientRect(); clamp left (center or right-aligned, BOUNDARY_PADDING=4) and top (prefer below the annotation at annotBottom + ANNOTATION_PADDING, fall back to above, then to the side with more space).
Hooks — src/hooks/
| File | Status | Purpose |
|---|---|---|
useSearch.js | Functional, self-contained | Returns reactive search state (searchQuery, searchResults, currentIndex, searching, currentResult) plus search(), setActiveResult(), clear() methods that delegate to core.search / core.setActiveSearchResult / core.clearSearchResults. Does not touch the global document store, so it does not conflict with the store-driven search panel. |
useOnAnnotationPopupOpen.js | Functional, no consumers | Returns a { selectedAnnotation } ref; registers annotationSelected / annotationDeselected and removes them via onScopeDispose, so listeners are cleaned up when the owning scope disposes. |
Both hooks are currently orphaned (no consumers found by grep). They are safe to use as-is; alternatively prefer the store-based approach for search.
Constants — src/constants/
dataElements.js
A centralized UPPER_SNAKE_CASE → camelCase/kebab-case map of every dataElement identifier — the single source of truth for the store's activeElements / disabledElements / activeElementsTab / headers keys. Sections: toolbar/header buttons, annotation tools, popup actions, crop popup, redaction, form tools, measurement tools, content editor, compare, document actions, panels, dialogs, disable-only chrome, and tab constants (ThumbnailsButton, OutlinesButton, AnnotationButton, LayersButton, SignatureButton, SearchButton, General, Appearance, Preference, Standard, Dynamic, Custom, Keyboard, Trackpad, …).
toolNames.js
Three exports:
ToolNames—UPPER_SNAKE → camelCasemap of every tool name (View, Annotation, Form, Measurement, Content editor, Signature, Security).DataElementToToolName— reverse map fromDataElements.*_BUTTONtoToolNames.*.map—{ [toolName]: { tool, toolName? } }lookup used bydocument.js#setToolState.register(tool)— adds a custom tool tomap.
panel.js
panelNames—{ pageModePanel, stampPanel }(lazy-rendered panels).noLazyPanelNames—{ stylePanel, leftPanel, rightPanel, linkPanel, colorSeparationPanel, contentEditorPanel, redactionPanel }(eager-rendered panels).
API helpers — src/api_helpers/
| File | Purpose |
|---|---|
createEncapsulatedStore.js | Wraps a Pinia store to expose only dispatch(action)(args) and getState(key) (deep-cloned). Used by popup APIs, getPassword, getPanels. |
createPopupAPI.js | Builds the UI.Popup interface (add / update / getItems) for a given popup data-element. |