Release v2.7.0
- #467 by @bobsingor – Implemented
renderPageAnnotationsRawto batch render annotation appearance streams and updatedupdatePageAnnotationto support skipping appearance regeneration.
- #467 by @bobsingor – Added types and interfaces for annotation appearance streams (
AnnotationAppearanceMap,AnnotationAppearances,AnnotationAppearanceImage) and updatedPdfEngineinterface withrenderPageAnnotationsRaw.
- #467 by @bobsingor –
- Added support for rendering annotation appearance streams (AP) for better visual fidelity with other PDF viewers.
- Refactored annotation rendering to use a registry-based system, allowing for easier extensibility.
- Introduced
moveAnnotationAPI to update annotation positions without regenerating their appearance streams. - Added caching for rendered appearance streams.
- #467 by @bobsingor – Updated redaction tools and renderers to explicitly disable appearance stream usage, ensuring dynamic rendering for redaction marks.
- #467 by @bobsingor – Fix Vue reactivity bugs when switching documents in the schema-driven viewer.
useRegisterAnchornow acceptsMaybeRefOrGetter<string>and re-registers anchors whendocumentIdchanges.AutoMenuRenderernow passes a reactive getter touseUIStateso menu state tracks the active document.
-
#486 by @shunyy – Add Japanese (
ja) translations to the snippet viewer. Thanks to @shunyy ! -
#478 by @phreyah – Add Swedish (
sv) translations to the snippet viewer. -
#487 by @shunyy – Expose
fontFallbackconfiguration option in the snippet viewer. -
#467 by @bobsingor – Fixed color matching case insensitivity and rotation debounce logic in the annotation sidebar.
Release v2.6.2
- #475 by @bobsingor – ### Extract tight glyph bounds and font size from PDFium
readGlyphInfonow callsFPDFText_GetCharBoxalongsideFPDFText_GetLooseCharBoxto extract tight character bounds (closely surrounding the actual glyph shape) and maps them to device-space coordinates.buildRunsFromGlyphspasses tight bounds through to eachPdfGlyphSlimrecord (tightX,tightY,tightWidth,tightHeight) and stores per-runfontSizefromFPDFText_GetFontSize.
- #475 by @bobsingor – ### Tight glyph bounds and font size on run/glyph models
PdfGlyphSlimgains optionaltightX,tightY,tightWidth,tightHeightfields for tight character bounds fromFPDFText_GetCharBox(closely surrounding the actual glyph shape, as opposed to the existing loose bounds fromFPDFText_GetLooseCharBox).PdfGlyphObjectgains optionaltightOriginandtightSizefields for the same purpose at the intermediate object level.PdfRungains an optionalfontSizefield populated fromFPDFText_GetFontSize, used for font-size-aware rectangle merging during selection.
-
#475 by @bobsingor – ### Selection plugin: Chrome PDFium parity and geometry cache eviction
Double-click / triple-click selection
- Double-click selects the word around the clicked glyph, triple-click selects the full visual line, matching Chromium's
PDFiumEngine::OnMultipleClickbehaviour.
Drag threshold
- Pointer-down no longer immediately begins a drag-selection. The pointer must move beyond a configurable
minSelectionDragDistance(default 3 px) before selection starts, preventing accidental selections on simple clicks.
Tolerance-based hit-testing with tight bounds
glyphAtnow performs two-pass hit-testing adapted from PDFium'sCPDF_TextPage::GetIndexAtPos: an exact-match pass followed by a tolerance-expanded nearest-neighbour pass using Manhattan distance.- Hit-testing uses tight glyph bounds (
FPDFText_GetCharBox) instead of loose bounds (FPDFText_GetLooseCharBox), matching Chrome's behaviour and preventing cross-line selection jumping on short lines. Configurable viatoleranceFactor(default 1.5).
Font-size-aware rectangle merging
shouldMergeHorizontalRectsnow refuses to merge runs whose font sizes differ by more than 1.5x, preventing a large character (e.g. a heading "1") from merging into adjacent body-text lines.rectsWithinSlicesub-splits runs when the horizontal gap between consecutive glyphs exceeds 2.5x the average glyph width, mirroring Chrome'sCalculateTextRunInfoAtcharacter-distance heuristic.
Geometry cache eviction (LRU)
- Added
maxCachedGeometriesconfig option (default 50) to bound per-document geometry memory. Least-recently-used pages are evicted when the limit is exceeded; pages with active UI registrations are pinned and never evicted. - When an evicted page scrolls back into view and falls within an active selection, its rects are lazily recomputed and pushed to the UI.
Marquee / text-selection coordination
- Introduced
hasTextAnchorstate so the marquee handler does not activate while the text handler has a pending anchor (before the drag threshold is met).
- Double-click selects the word around the clicked glyph, triple-click selects the full visual line, matching Chromium's
Release v2.6.1
-
#473 by @bobsingor – Implement getPageTextRuns in PdfiumNative, WebWorkerEngine, and RemoteExecutor for extracting rich text runs with font, size, and color metadata. Implement renderPageRaw and renderPageRectRaw in WebWorkerEngine for returning raw ImageDataLike pixel data without encoding.
-
#463 by @bobsingor – Update readPageAnnoRect to call EPDFAnnot_GetRect instead of FPDFAnnot_GetRect, ensuring annotation rectangles are always normalized. Fixes link annotations appearing below their expected position when the PDF Rect array has inverted y-coordinates.
- #473 by @bobsingor – Add PdfFontInfo, PdfTextRun, and PdfPageTextRuns types for rich text extraction with font metadata and color info. Add renderPageRaw and renderPageRectRaw methods to PdfEngine for raw pixel output (ImageDataLike). Add getPageTextRuns to PdfEngine and IPdfiumExecutor. Add TaskSequence utility for composing sequential Task operations with abort propagation.
-
#463 by @bobsingor – Add EPDFAnnot_GetRect that wraps FPDFAnnot_GetRect with rect normalization. Upstream FPDFAnnot_GetRect does not normalize the rect read from the PDF dictionary, so when a PDF stores its Rect array with y1 > y2 the top/bottom values are inverted. This caused link annotations to be positioned incorrectly.
-
#463 by @bobsingor – Sync pdfium-src with upstream chromium/7689
- #473 by @bobsingor – Add renderPageRaw and renderPageRectRaw methods to RenderCapability and RenderScope for returning raw ImageDataLike pixel data, useful for AI/ML pipelines that need direct pixel access without Blob encoding.
-
#465 by @bobsingor – Switch toolbar close command from hardcoded pointerMode to activateDefaultMode. On mobile devices the default mode is pan mode rather than pointer mode, and activating pointer mode prevented scrolling (only allowing text selection).
-
#466 by @bobsingor – Fix toolbar UI visibility: hide the mode select dropdown when no annotation/shape/redact modes are available (previously showed a dropdown with a single item), and hide the file-actions divider when document:open and document:close items are not visible.
Release v2.6.0
- #452 by @bobsingor –
- Update PDFium engine to support saving and loading rotated annotations.
- Add support for
EPDFAnnot_SetRotate,EPDFAnnot_SetExtendedRotation, andEPDFAnnot_SetUnrotatedRect. - Implement unrotated rendering path for rotated annotations.
- #458 by @bobsingor –
- Fallback unknown font to Helvetica in
setAnnotationDefaultAppearanceso annotations with non-standard fonts can still be edited.
- Fallback unknown font to Helvetica in
- #452 by @bobsingor –
- Add rotation geometry utilities:
rotatePointAround,calculateRotatedRectAABB,inferRotationCenterFromRects. - Add
rotationandunrotatedRectproperties toPdfAnnotationObjectBase.
- Add rotation geometry utilities:
-
#459 by @bobsingor – Fix JSDoc descriptions for
colorandoverlayColoronPdfRedactAnnoObjectto match actual semantics. -
#458 by @bobsingor –
- Fix
StandardFontDescriptor.cssto use base family names only (not variant-specific like"Helvetica-Bold"). - Add
StandardFontCssPropertiesinterface andstandardFontCssProperties()for cross-platform font rendering with properfontWeight/fontStyle.
- Fix
- #452 by @bobsingor –
- Export new rotation-related PDFium functions:
EPDFAnnot_SetRotate,EPDFAnnot_GetRotate,EPDFAnnot_SetExtendedRotation, etc. - Update WASM build.
- Export new rotation-related PDFium functions:
- #458 by @bobsingor –
- Add abbreviated font name aliases (Helv, ZaDb, Cour, etc.) and missing Helvetica-Oblique mapping in
StringToStandardFont.
- Add abbreviated font name aliases (Helv, ZaDb, Cour, etc.) and missing Helvetica-Oblique mapping in
-
#447 by @bobsingor – Added
modeIdfiltering to marquee end event handler so annotation selection only triggers duringpointerMode, preventing interference with redaction marquees. Added page activity claims (annotation-selectiontopic) when selecting/deselecting annotations for scroll plugin page elevation. -
#452 by @bobsingor –
- Add support for rotating annotations.
- Add
rotationUIprop toAnnotationLayerandAnnotationContainer. - Add
isRotatableandisGroupRotatableproperties toAnnotationTool. - Add
insertUprightbehavior for stamps and free text. - Update
AnnotationLayerto support custom rotation handles via slots/components.
- #458 by @bobsingor –
- Use
standardFontCssPropertiesin FreeText components (React, Svelte, Vue) so bold/italic render correctly on all platforms.
- Use
- #447 by @bobsingor – Added topic-based page activity tracking system. New methods
claimPageActivity,releasePageActivity, andhasPageActivityon bothInteractionManagerCapabilityandInteractionManagerScope. NewonPageActivityChangeevent andPageActivityChangeEventtype. Topics are named strings (e.g. 'annotation-selection', 'selection-menu') that can be active on one page at a time per document, automatically moving when re-claimed on a different page.
-
#447 by @bobsingor – Subscribe to selection plugin's
onEmptySpaceClickevent to deselect pending redactions when the user clicks on empty page space. Restores background-click-to-deselect behavior that was lost during the marquee unification. -
#447 by @bobsingor – Unified marquee redaction with the selection plugin's marquee infrastructure. Removed standalone
createMarqueeHandler,registerMarqueeOnPage,RegisterMarqueeOnPageOptions, andMarqueeRedactCallback. Marquee redaction now subscribes to selection plugin'sonMarqueeChangeandonMarqueeEndevents and forwards them via newonRedactionMarqueeChangemethod. Enabled marquee forRedactionMode.RedactandRedactionMode.MarqueeRedactmodes viaenableForMode. Added page activity claims (redaction-selectiontopic) in legacy mode for scroll plugin page elevation.
-
#459 by @bobsingor – Fix default redaction fill color (
color) to#000000(black) and overlay text color (overlayColor) to#FFFFFF(white). -
#458 by @bobsingor –
- Use
standardFontCssPropertiesin redaction overlay components (React, Svelte, Vue) for consistent font rendering.
- Use
-
#452 by @bobsingor –
- Explicitly disable rotation for redaction tools.
- #447 by @bobsingor – Added page elevation support driven by interaction manager page activity. New
elevatedboolean onPageLayoutinterface. Scroll plugin subscribes toonPageActivityChangeand tracks elevated pages per document. Scroller components (React, Svelte, Vue) applyzIndex: 1andposition: relativeon page containers whenlayout.elevatedis true. Added optional dependency on@embedpdf/plugin-interaction-manager.
-
#447 by @bobsingor – Added
onEmptySpaceClickevent toSelectionScopeandSelectionCapability. Fires when the user clicks directly on the page background (empty space) rather than on a child element. Detection runs before mode-gating so it fires for all modes regardless of whether text or marquee selection is enabled. NewEmptySpaceClickEventandEmptySpaceClickScopeEventtype exports. -
#447 by @bobsingor – Unified text selection and marquee selection under the
enableForModeAPI. ExtendedEnableForModeOptionswithenableSelection,showSelectionRects,enableMarquee, andshowMarqueeRectsoptions. DeprecatedshowRects(useshowSelectionRects),setMarqueeEnabled, andisMarqueeEnabled(useenableForModewithenableMarquee). AddedmodeIdtoSelectionChangeEvent,BeginSelectionEvent,EndSelectionEvent,MarqueeChangeEvent,MarqueeEndEvent, and their scoped counterparts. Marquee handler now usesregisterAlwaysso any plugin can enable marquee for their mode. RemovedstopImmediatePropagationfrom text selection handler in favor ofisTextSelectingcoordination.Refactored
SelectionLayerinto a thin orchestrator that composes the newTextSelectioncomponent and existingMarqueeSelectioncomponent. Consumers no longer need to renderMarqueeSelectionseparately --SelectionLayernow includes both text and marquee selection. Added newTextSelectionexport for advanced standalone usage. AddedtextStyleandmarqueeStyleprops toSelectionLayerfor consistent CSS-standard styling (background,borderColor,borderStyle).MarqueeSelectionupdated with CSS-standard props (background,borderColor,borderStyle); oldstrokeandfillprops deprecated. NewTextSelectionStyleandMarqueeSelectionStyletype exports.
- #452 by @bobsingor –
- Update
DragResizeControllerto support rotation interactions. - Add
useInteractionHandlessupport for rotation handles. - Add rotation snapping and constraints.
- Update
- #452 by @bobsingor –
- Add rotation property control to the annotation sidebar.
- Update selection menu to handle rotated annotations.
Release v2.5.0
-
#441 by @bobsingor – Implemented per-document rotation normalization in the PDFium engine:
- Updated
PdfCache.setDocument()to accept per-documentnormalizeRotationflag - Added
normalizeRotationproperty toDocumentContextfor tracking document-level setting - Updated
PageCacheto useEPDF_LoadPageNormalizedwhen normalization is enabled - Modified page size retrieval to use
EPDF_GetPageSizeByIndexNormalizedfor normalized documents - Propagated
doc: PdfDocumentObjectparameter through 30+ coordinate transformation methods to access the normalization flag - Updated
convertDevicePointToPagePointandconvertPagePointToDevicePointto use 0° rotation when normalization is enabled
This change allows annotations, text selection, and rendering to work correctly across pages with different rotations by treating all coordinates in a consistent 0° space.
- Updated
-
#441 by @bobsingor – Added support for per-document rotation normalization:
- Added
normalizedRotation: booleanproperty toPdfDocumentObjectto track whether the document was opened with normalized rotation - Added
normalizeRotation?: booleanoption toPdfOpenDocumentBufferOptionsinterface - Added
normalizeRotation?: booleanoption toPdfOpenDocumentUrlOptionsinterface
When
normalizeRotationis enabled, all page coordinates (annotations, text, rendering) are in 0° space regardless of the page's original rotation. - Added
-
#441 by @bobsingor – Added new PDFium functions to support normalized page rotation:
EPDF_GetPageSizeByIndexNormalized: Returns page dimensions as if the page had 0° rotation (swaps width/height for 90°/270° rotated pages)EPDF_LoadPageNormalized: Loads a page with normalized rotation, treating all coordinates in 0° space
These functions enable the engine to work with page coordinates consistently regardless of original page rotation.
-
#441 by @bobsingor – Enabled rotation normalization by default for all documents opened through the document manager:
- Added
normalizeRotation: truetoopenDocumentFromUrl()method - Added
normalizeRotation: truetoopenDocumentFromBuffer()method - Added
normalizeRotation: trueto internaldoOpen()method
This ensures all documents managed by the plugin have consistent coordinate handling regardless of individual page rotations.
- Added
- #441 by @bobsingor – Fixed rotation calculation in AnnotationLayer components to properly combine page intrinsic rotation with document rotation:
- Updated React
AnnotationLayercomponent to compute effective rotation as(pageRotation + docRotation) % 4 - Updated Vue
annotation-layer.vuecomponent with the same rotation logic - Updated Svelte
AnnotationLayer.sveltecomponent with the same rotation logic
- Updated React
- #441 by @bobsingor – Fixed rotation calculation in PagePointerProvider components to properly handle rotation override and combine page intrinsic rotation with document rotation:
- Updated React
PagePointerProviderto use rotation override directly when provided, otherwise combine page and document rotation - Updated Vue
page-pointer-provider.vuewith the same rotation logic - Updated Svelte
PagePointerProvider.sveltewith the same rotation logic
- Updated React
- #441 by @bobsingor – Fixed rotation calculation in RedactionLayer components to properly combine page intrinsic rotation with document rotation:
- Updated React
RedactionLayercomponent to compute effective rotation as(pageRotation + docRotation) % 4 - Updated Vue
redaction-layer.vuecomponent with the same rotation logic - Updated Svelte
redaction-layer.sveltecomponent with the same rotation logic
- Updated React
- #441 by @bobsingor – Fixed rotation calculation in Rotate components to properly handle rotation override and combine page intrinsic rotation with document rotation:
- Updated React
Rotatecomponent to use rotation override directly when provided, otherwise combine page and document rotation - Updated Vue
rotate.vuecomponent with the same rotation logic - Updated Svelte
Rotate.sveltecomponent with the same rotation logic
- Updated React
- #441 by @bobsingor – Fixed scroll calculations to account for page intrinsic rotation:
- Updated
getSpreadPagesWithSizes()to compute effective rotation as(pageRotation + docRotation) % 4for each page - Updated
scrollToPage()to use effective rotation when calculating scroll position - Updated
getRectPositionForPage()to use effective rotation when provided rotation is undefined - Fixed
calculatePageVisibility()in base strategy to account for horizontal centering offset
- Updated
- #441 by @bobsingor – Fixed rotation calculation in SelectionLayer components to properly combine page intrinsic rotation with document rotation:
- Updated React
SelectionLayercomponent to compute effective rotation as(pageRotation + docRotation) % 4 - Updated Vue
selection-layer.vuecomponent with the same rotation logic - Updated Svelte
SelectionLayer.sveltecomponent with the same rotation logic
- Updated React
- #441 by @bobsingor – Fixed thumbnail rendering to account for page intrinsic rotation:
- Updated
rebuildLayout()to swap width/height for pages with 90° or 270° rotation when calculating thumbnail dimensions - Added
rotation: page.rotationto render options inrenderThumb()to ensure thumbnails display with correct orientation
- Updated
- #441 by @bobsingor – Fixed tile calculations to account for page intrinsic rotation:
- Updated
refreshTilesForPages()to compute effective rotation as(pageRotation + docRotation) % 4for each page - Updated
onScrollMetricsChange()to use effective rotation per page when calculating tiles
- Updated
-
#441 by @bobsingor – Fixed resize handle cursors to account for page rotation:
- Updated
diagonalCursor()function to swapns-resizeandew-resizecursors for edge handles (n, s, e, w) on odd rotation values (90° and 270°) - Reorganized cursor logic to handle edge handles separately from corner handles
Previously, edge resize handles showed incorrect cursors on rotated pages (e.g., north handle showed
ns-resizeinstead ofew-resizeon 90° rotated pages). - Updated
Release v2.4.1
-
#434 by @bobsingor – Fixed memory leak where image encoder workers were never terminated when the engine was destroyed:
- Added optional
destroy()method toImageDataConverterinterface for resource cleanup - Updated
createWorkerPoolImageConverterandcreateHybridImageConverterto attachdestroy()that terminates the encoder worker pool - Updated
PdfEngine.destroy()to callimageConverter.destroy?.()to clean up encoder workers
Previously, each viewer instance would leave 2 encoder workers running after destruction.
- Added optional
-
#434 by @bobsingor – Fixed memory leak in
EmbedPdfContainerwhere Preact components were not unmounted on disconnect:- Added
render(null, this.root)indisconnectedCallback()to properly unmount Preact components - This triggers the cleanup chain: plugin destroy, engine destroy, and worker termination
Previously, navigating between pages would leave workers running (1 PDFium + 2 encoder workers per viewer instance).
- Added
Release v2.4.0
- #426 by @bobsingor – Added redaction annotation engine methods:
- Added
applyRedaction()to apply a single REDACT annotation, removing content and flattening the overlay - Added
applyAllRedactions()to apply all REDACT annotations on a page - Added
flattenAnnotation()to flatten any annotation's appearance to page content - Added
readPdfRedactAnno()for reading REDACT annotations with all properties - Added
addRedactContent()for creating REDACT annotations with QuadPoints, colors, and overlay text - Added overlay text getter/setter methods for REDACT annotations
- Added
- #426 by @bobsingor – Added support for REDACT annotation type with full read/write capabilities:
- Added
PdfRedactAnnoObjectinterface for redact annotations with properties for overlay text, colors, and font settings - Added
PdfAnnotationColorType.OverlayColorenum value for redaction overlay color - Added
PdfRedactAnnoObjecttoPdfSupportedAnnoObjectunion type - Added new engine interface methods:
applyRedaction,applyAllRedactions,flattenAnnotation - Added corresponding methods to
IPdfiumExecutorinterface
- Added
- #426 by @bobsingor – Added PDFium functions for redaction annotation support:
- Added
EPDFAnnot_ApplyRedactionto apply a single redaction annotation - Added
EPDFAnnot_Flattento flatten an annotation's appearance to page content - Added
EPDFPage_ApplyRedactionsto apply all redactions on a page - Added
EPDFAnnot_GetOverlayTextandEPDFAnnot_SetOverlayTextfor overlay text - Added
EPDFAnnot_GetOverlayTextRepeatandEPDFAnnot_SetOverlayTextRepeatfor text repeat setting
- Added
-
#433 by @bobsingor – Reduced WASM binary size from 7.4MB to 4.5MB by removing debug symbols (-g flag) from the build.
Thanks to @Mikescops for reporting this.
- #426 by @bobsingor – Added annotation renderer registry and enhanced annotation capabilities:
- Added
purgeAnnotation()method to remove annotations from state without calling the PDF engine - Added annotation renderer registry allowing external plugins to register custom annotation renderers
- Added
useRegisterRenderers()hook andAnnotationRendererProvidercontext for renderer registration - Changed interaction properties (
isDraggable,isResizable,lockAspectRatio) to support dynamic functions based on annotation - Added
AnnotationCommandMetadatainterface for history command filtering - Added
isRedact()helper function for type-checking redact annotations - Framework exports now include
AnnotationPluginPackagewithAnnotationRendererProviderwrapper
- Added
- #429 by @bobsingor – Fixed group selection box ignoring document permissions:
- Added
canModifyAnnotationspermission check toGroupSelectionBoxcomponent across React, Vue, and Svelte - Group drag and resize operations are now properly disabled when the user lacks annotation modification permissions
- This aligns group selection behavior with individual annotation container permission checks
- Added
- #426 by @bobsingor – Added
loggerto command action context, enabling commands to log debug information through the plugin's logger instance.
- #426 by @bobsingor – Added history purging by command metadata:
- Added
purgeByMetadata()method to remove history entries matching a predicate on command metadata - Added generic
metadatafield toCommandinterface for attaching identifiable data to commands - Enables permanent operations (like redaction commits) to clean up related undo/redo history
- Added
- #426 by @bobsingor – Added annotation-based redaction mode for integrated redaction workflow:
- Added
useAnnotationModeconfig option to use REDACT annotations as pending redactions - Added unified
RedactionMode.Redactmode supporting both text selection and area marquee - Added
redactToolannotation tool for integration with annotation plugin - Added
RedactHighlightandRedactAreacomponents for rendering redact annotations - Added automatic renderer registration via framework-specific
RedactionPluginPackage - Added
source,markColor,redactionColor, andtextproperties toRedactionItemtype - Pending redactions now sync with annotation plugin state in annotation mode
- Added
enableRedact(),toggleRedact(),isRedactActive(),endRedact()methods - Removed deprecated
startRedaction()andendRedaction()methods from scope API
- Added
- #428 by @bobsingor – Added modal props feature to pass context when opening modals:
- Extended
openModal(modalId, props?)to accept optional props parameter - Added
propsfield toModalSlotStatetype - Added
modalPropstoModalRendererPropsfor all frameworks (Preact, React, Svelte, Vue) - Updated schema renderers to pass
modalPropsthrough to modal components
- Extended
-
#428 by @bobsingor – Fixed link modal context handling:
- Added
sourceprop to LinkModal to distinguish between annotation and text selection context - Updated
annotation:add-linkcommand to pass{ source: 'selection' }when opening modal - Updated
annotation:toggle-linkcommand to pass{ source: 'annotation' }when opening modal - Prevents incorrect behavior where annotation selection would override text selection when creating links
- Added
-
#426 by @bobsingor – Added redaction management features:
- Added
RedactionSidebarcomponent for viewing and managing pending redactions - Added
annotation:apply-redactioncommand to apply the selected redaction annotation - Added
redaction:redactcommand for unified redact mode (text + area) - Added
panel:toggle-redactioncommand for toggling the redaction sidebar - Added redaction panel configuration to UI schema
- Added REDACT annotation type support in annotation sidebar
- Added
redactCombinedandredactionSidebaricons - Added translations for redaction panel, overlay text, and redaction states
- Updated redaction toolbar to use unified redact mode
- Added
-
#430 by @bobsingor – Added document permission checks to redaction sidebar buttons:
- "Clear All" button is now disabled when
canModifyAnnotationsis false - "Redact All" button is now disabled when
canModifyContentsis false - Added squiggly annotation tool to annotation toolbar
- Added ink tool to annotation overflow menu and responsive breakpoints
- "Clear All" button is now disabled when
-
57a8431by @bobsingor – Fixed TabButton component causing unintended form submission when used inside forms. Addedtype="button"to prevent tab buttons from triggering form submit, which was causing the link modal to close immediately when switching to the Page tab.
- #426 by @bobsingor – Fixed AutoMount component to render utilities inside wrapper context. Utilities registered via
addUtility()now have access to context provided by wrappers (React, Vue, Svelte), enabling plugins to share context between wrappers and utilities.
Release v2.3.0
- #406 by @bobsingor – Added support for creating and updating PDF link annotations with URI and internal page targets. Implemented IRT (In Reply To) and RT (Reply Type) property handling for annotation relationships and grouping. Refactored annotation content methods to use centralized
applyBaseAnnotationPropertiesandreadBaseAnnotationPropertieshelpers, reducing code duplication. Updated text markup and ink handlers to preferstrokeColorover deprecatedcolorproperty.
- #406 by @bobsingor – Added
PdfAnnotationReplyTypeenum withReplyandGroupvalues to support annotation relationships per ISO 32000-2. AddedinReplyToIdandreplyTypeproperties toPdfAnnotationObjectBasefor annotation grouping and reply threads. ExtendedPdfLinkAnnoObjectwith styling properties:strokeColor,strokeWidth,strokeStyle, andstrokeDashArray. Deprecatedcolorin favor ofstrokeColorfor text markup and ink annotations. DeprecatedbackgroundColorin favor ofcolorfor free text annotations. Fixed documentation comments for squiggly, underline, and strikeout annotations.
- #406 by @bobsingor – Added multi-selection support with new Redux actions:
ADD_TO_SELECTION,REMOVE_FROM_SELECTION, andSET_SELECTION. TheselectedUidsarray now tracks multiple selected annotations, withselectedUidcomputed for backward compatibility. Implemented annotation grouping and ungrouping using IRT/RT properties viagroupAnnotations()andungroupAnnotations()methods. Added unified drag and resize API (startDrag,updateDrag,commitDrag,cancelDrag,startResize,updateResize,commitResize,cancelResize) that handles multi-annotation operations including attached link annotations. AddedLinkannotation component andGroupSelectionBoxcomponent for Preact, Svelte, and Vue frameworks. Updated text markup tools to usestrokeColorand suppress selection layer rects. Improved commit process withcollectPendingChanges,executeCommitBatch, and commit locking to prevent concurrent modifications.
- #406 by @bobsingor – Made
labelKeydynamic, allowing it to be a function that returns different translation keys based on state. Added dynamiciconsupport so command icons can change at runtime. Addedregistryto the dynamic evaluation context for accessing other plugins. Madeuian optional dependency instead of not listed. Added early return indetectCommandChangeswhen document is not fully loaded.
- #406 by @bobsingor – Added
stopImmediatePropagation()andisImmediatePropagationStopped()methods to pointer events via the newEmbedPdfPointerEventExtensionsinterface. This allows higher-priority handlers to prevent lower-priority handlers from activating for the same event. UpdatedmergeHandlersto respect propagation state and stop calling handlers when propagation is stopped. RefactoredEmbedPdfPointerEventas a generic type that combines native events with extensions.
- #406 by @bobsingor – Added marquee selection functionality allowing users to drag a rectangle to select multiple elements. Introduced
createMarqueeSelectionHandlerandcreateTextSelectionHandleras separate pointer event handlers that can be combined withmergeHandlers. AddedMarqueeSelectioncomponent for Preact, Svelte, and Vue. AddedEnableForModeOptionsinterface withshowRectsoption for configurable selection behavior. AddedonMarqueeChangeandonMarqueeEndevents. AddedsetMarqueeEnabledandisMarqueeEnabledmethods to the capability.
- #406 by @bobsingor – Added
LinkModalcomponent for creating and editing link annotations with URL and internal page targets. Added new icons:GroupIcon,UngroupIcon,LinkIcon,LinkOffIcon,ExternalLinkIcon, andMarqueeSelectIcon. Updated annotation sidebar to support multi-selection usinggetSelectedAnnotationsselector. Added grouping and ungrouping commands with dynamic labels and icons. Added marquee selection command. Updated UI schema and translations for new link and grouping features.
- #406 by @bobsingor – Updated PDFium WASM module with new bindings for annotation actions and reply types. Added
EPDFAnnot_SetAction,EPDFAnnot_GetReplyType, andEPDFAnnot_SetReplyTypefunctions to support link annotations and annotation grouping.
- #406 by @bobsingor – Updated to use the new
enableForModesignature with options object. Configured redaction mode to suppress selection layer rects since the redaction plugin renders its own selection visualization.
- #406 by @bobsingor – Removed
commandsfrom required dependencies. The UI plugin no longer requires the commands plugin to be registered.
Release v2.2.0
-
#389 by @bobsingor – Add document permissions support:
- Add
useDocumentPermissionshook for React, Svelte, and Vue with reactive permission state and helper methods (hasPermission,hasAllPermissions, and shorthand booleans likecanPrint,canCopyContents, etc.) - Add
UPDATE_DOCUMENT_SECURITYaction andupdateDocumentSecurityaction creator for updating document security state - Add reducer case for updating document permissions and owner unlock state
- Add permission helper methods to
BasePlugin:getDocumentPermissions,checkPermission,requirePermission - Export
useDocumentPermissionsfrom shared, svelte, and vue entry points
- Add
-
#389 by @bobsingor – Add permission override system with global and per-document configuration:
- Add
PermissionConfiginterface for configuring permission overrides withenforceDocumentPermissionsandoverridesoptions - Add
permissionsoption toPluginRegistryConfigfor global permission configuration - Add
permissionstoDocumentStatefor per-document permission overrides - Add
getEffectivePermissionandgetEffectivePermissionsselectors for layered permission resolution (per-document → global → PDF) - Add human-readable permission names (
print,modifyContents,copyContents, etc.) as alternatives to numeric flags - Update
BasePluginpermission helpers (checkPermission,requirePermission,getDocumentPermissions) to use effective permissions - Update
useDocumentPermissionshooks (React, Svelte, Vue) to return both effective and raw PDF permissions - Add
configprop toEmbedPDFcomponents for passingPluginRegistryConfig, deprecating individualloggerprop - Export
PermissionConfig,PermissionName,ALL_PERMISSION_FLAGS, and permission selectors
- Add
- #389 by @bobsingor – Add document security/encryption engine methods:
- Add
setDocumentEncryptionfor setting AES-256 encryption with user/owner passwords and permission flags - Add
removeEncryptionfor marking documents for encryption removal on save - Add
unlockOwnerPermissionsfor unlocking owner permissions on encrypted documents - Add
isEncryptedandisOwnerUnlockedquery methods - Implement security methods in
PdfEngineorchestrator,RemoteExecutor,PdfiumNative,WebWorkerEngine, andEngineRunner - Query and store
isEncrypted,isOwnerUnlocked, andpermissionswhen opening documents
- Add
- #389 by @bobsingor – Add PDF permission and security types:
- Add
isEncrypted,isOwnerUnlocked, andpermissionsproperties toPdfDocumentObject - Add
PdfPermissionFlagenum with all PDF permission flags (Print, ModifyContents, CopyContents, ModifyAnnotations, FillForms, ExtractForAccessibility, AssembleDocument, PrintHighQuality) andAllowAllcombination - Add
buildPermissionshelper function for combining permission flags - Add
PermissionDeniedErrorclass for permission check failures - Add security methods to
PdfEngineinterface:setDocumentEncryption,removeEncryption,unlockOwnerPermissions,isEncrypted,isOwnerUnlocked - Add security methods to
IPdfiumExecutorinterface
- Add
- #389 by @bobsingor – Add permission checking for annotation operations:
- Check
PdfPermissionFlag.ModifyAnnotationsbefore creating, updating, or deleting annotations - Check permission before activating annotation tools
- Check permission before creating annotations from text selection
- Update
AnnotationContainercomponents (React, Svelte, Vue) to respectcanModifyAnnotationspermission:- Disable drag/resize when permission is denied
- Hide vertex handles when permission is denied
- Guard double-click handlers based on permission
- Check
- #389 by @bobsingor – Add per-document permission overrides when opening documents:
- Add
permissionsoption toLoadDocumentUrlOptionsfor URL-based document loading - Add
permissionsoption toLoadDocumentBufferOptionsfor buffer-based document loading - Add
permissionsoption toOpenFileDialogOptionsfor file dialog document loading - Pass permission configuration to core store when documents are opened
- Add
- #389 by @bobsingor – Add permission checking for print operations:
- Check
PdfPermissionFlag.Printbefore allowing document printing - Return
PdfErrorCode.Securityerror when print permission is denied
- Check
- #389 by @bobsingor – Add permission checking for redaction operations:
- Check
PdfPermissionFlag.ModifyContentsbefore adding pending redaction items - Check permission before enabling redact selection or marquee redact modes
- Check permission before starting redaction mode
- Check permission before committing pending redactions (single or all)
- Return
PdfErrorCode.Securityerror when permission is denied for commit operations
- Check
- #389 by @bobsingor – Add overlay enable/disable functionality:
- Add
SET_OVERLAY_ENABLEDaction andsetOverlayEnabledaction creator - Add
enabledOverlaysstate toUIDocumentStatefor tracking overlay visibility - Add overlay management methods to
UIScope:enableOverlay,disableOverlay,toggleOverlay,isOverlayEnabled,getEnabledOverlays - Add
onOverlayChangedevent hook for overlay state changes - Update schema renderer to filter overlays by enabled state
- Initialize overlay enabled state from schema's
defaultEnabledproperty
- Add
-
#389 by @bobsingor – Add document security and protection features:
- Add
ProtectModalcomponent for setting document encryption with user/owner passwords and permission restrictions - Add
UnlockOwnerOverlaycomponent to notify users when viewing protected documents with restricted permissions - Add
ViewPermissionsModalcomponent for viewing and unlocking document permissions - Add
PermissionsDisplaycomponent for showing permission status - Add permission-based command disabling for annotation, redaction, print, copy, and capture commands
- Add security-related translations for English, German, Dutch, French, Spanish, and Chinese
- Add new icons:
EyeIcon,EyeOffIcon,InfoIcon,UnlockIcon - Update UI schema with protection modal, view permissions modal, and unlock owner overlay
- Add
-
#389 by @bobsingor – Add global permission configuration to snippet viewer:
- Add
permissionsoption toPDFViewerConfigfor global permission overrides - Support
enforceDocumentPermissionsto ignore PDF permissions entirely - Support
overrideswith human-readable names (print,modifyAnnotations, etc.) or numeric flags - Update command permission checks to use effective permissions via
getEffectivePermission - Pass permission configuration to
EmbedPDFvia newconfigprop
- Add
Release v2.1.2
- #369 by @bobsingor – Improved PDF content handling with the following changes:
- Shading object support: Shading patterns (gradients, mesh shadings) are now properly preserved and regenerated when modifying PDF pages. Previously, shading objects could be lost during page content updates.
- Shading redaction: Redaction now correctly removes shading objects that fall entirely within a redaction area, ensuring complete content removal.
- Graphics state preservation: Existing graphics state resources (such as soft masks, overprint modes, and other advanced properties) are now preserved with their original names during content regeneration.
-
#369 by @bobsingor – Add missing translations for redaction delete and commit commands (
redaction.deleteSelectedandredaction.commitSelected) in all supported languages (English, German, Dutch, French, Spanish). -
#381 by @bobsingor –
- Add i18n support for capture and print dialogs with translations for all supported languages
- Add
document:capturecommand to toolbar for screenshot functionality - Refactor hint-layer and capture components to use translation hooks
- Remove unused
@types/classnamesdependency
-
#378 by @bobsingor –
- Add Simplified Chinese (zh-CN) translations for all UI elements
- Add i18n support for annotation type labels in comment sidebar with translation keys and fallbacks
- Fix rimraf command to use
--globflag for compatibility with rimraf v4+