PDF bookmarks ​
Because PDFViewCtrl and UIExtension differ in layering, bookmark APIs are split into two parts, each exposed through a service instance:
BookmarkDataService: Bookmark data service at the PDFViewCtrl layer. When your app is built on PDFViewCtrl only, extend bookmarks using APIs from this service.
BookmarkUIService: UIExtension-layer APIs built on
BookmarkDataService. They wrap part of the data service for UI view/data sync and undo/redo support.
NOTE
See Customize bookmark UI to customize bookmark UI components.
Code examples:
Example 1 ​
This example uses BookmarkDataService to fetch and log first-level bookmarks:
html
<html>
<label>Select a PDF file with bookmarks:
<input type="file" id="file">
</label>
<hr style="width: 100%;">
<div id="pdf-viewer"></div>
</html>
<script>
const libPath = window.top.location.origin + '/lib';
const ePDFViewer = document.getElementById('pdf-viewer');
const pdfViewer = new PDFViewCtrl.PDFViewer({
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
},
customs: {
ScrollWrap: PDFViewCtrl.DivScrollWrap.create(ePDFViewer)
}
});
pdfViewer.init(ePDFViewer);
document.getElementById('file').onchange = function (e) {
if (!this.value) {
return;
}
pdfViewer.openPDFByFile(e.target.files[0]);
this.value = '';
};
pdfViewer.eventEmitter.on(PDFViewCtrl.ViewerEvents.openFileSuccess, () => {
const bookmarkDataService = pdfViewer.getBookmarkDataService();
bookmarkDataService.getFirstLevelBookmarks().then(firstLevelBookmarks => {
console.log(firstLevelBookmarks);
});
})
</script>
<style>
body {
display: flex;
flex-direction: column;
}
#pdf-viewer {
width: 100%;
flex: 1;
overflow: auto;
}
</style>json
{
"iframeOptions": {
"style": "height: 500px"
}
}Example 2 ​
This example uses BookmarkUIService to create and delete bookmarks:
html
<html>
<div id="pdf-ui"></div>
<template id="custom-toolbar-template">
<div class="custom-toolbar" @var.toolbar="$component">
<xbutton @on.click="toolbar.addBookmark()">Create</xbutton>
<xbutton @on.click="toolbar.deleteSelectedBookmark()">Delete</xbutton>
</div>
</template>
</html>
<style>
html {
overflow: hidden;
}
body {
height: 100vh;
}
#pdf-ui {
position: relative;
top: 50px;
}
.custom-toolbar {
display: flex;
gap: 10px;
border-bottom: 1px solid #f0f0f0;
padding: 5px 0;
}
</style>
<script>
const customBookmarkContextmenuTemplate = document.getElementById('custom-toolbar-template').innerHTML;
class CustomBookmarkToolbarComponent extends UIExtension.SeniorComponentFactory.createSuperClass({
template: customBookmarkContextmenuTemplate
}) {
static getName() {
return 'custom-bookmark-toolbar';
}
addBookmark() {
const service = this.getPDFUI().getBookmarkUIService();
const text = prompt("Create new bookmark", "Untitled");
service.addBookmark({
title: text,
relationship: PDF.bookmark.BookmarkRelationship.LAST_CHILD
})
}
deleteSelectedBookmark() {
const service = this.getPDFUI().getBookmarkUIService();
const bookmarkId = service.getCurrentActiveBookmarkId();
if (bookmarkId === undefined) {
alert('You did not select a bookmark');
return;
}
const confirmed = confirm('Are you sure you want to delete this bookmark? ')
if (confirmed) {
service.deleteBookmark(bookmarkId)
}
}
}
const customModule = UIExtension.modular.module('custom', []);
customModule.registerComponent(CustomBookmarkToolbarComponent);
const CustomAppearance = UIExtension.appearances.adaptive.extend({
getDefaultFragments() {
return [{
target: 'sidebar-bookmark-v2',
action: UIExtension.UIConsts.FRAGMENT_ACTION.PREPEND,
template: `<custom:custom-bookmark-toolbar></custom:custom-bookmark-toolbar>`
}];
}
});
const libPath = window.top.location.origin + '/lib';
const pdfui = new UIExtension.PDFUI({
viewerOptions: {
libPath: libPath,
jr: {
licenseSN: licenseSN,
licenseKey: licenseKey
}
},
renderTo: '#pdf-ui',
appearance: CustomAppearance,
addons: []
});
</script>json
{
"iframeOptions": {
"style": "height: 500px"
}
}