/* eslint-disable max-len */
import { TW_DATA_TAG, tw_focus, tw_hide, tw_toggleCssClass } from "./util.js";
/**
* Bookmarks manager
*/
class BookmarkLayer {
constructor(
app,
showBookmarksOnOpen = false,
preserveBookmarksState = true,
bookmarksFullyExpanded = false
) {
this._app = app;
this._isBookmarksOpened = false;
this._isResizeEventAdded = false;
this._bindEvents();
/**
* All bookmarks items.
*/
this.allBookmarks = [];
/**
* If *true*, on first open bookmarks it will show bookmarks fully expaned.
* In next openings, if it will be expanded or collapsed depends on the property value
* of *preserveBookmarksState*.
*
* Default false.
* */
this.bookmarksFullyExpanded = bookmarksFullyExpanded || false;
/** If *false*, on every open bookmarks it will show bookmarks
* fully expaned or collapsed based on the property value
* of *bookmarksFullyExpanded*.
*
* Default: *true*
* */
this.preserveBookmarksState = preserveBookmarksState === false || true;
/** If *true* it will automatically open bookmarks when the document
* is loaded. If the document doesn't have bookmarks nothing will happen.
*
* Default: *false*
* */
this.showBookmarksOnOpen = showBookmarksOnOpen || false;
}
// #region private functions
get _bookmarksDiv() {
return this._app.isMobile
? this._app.elements.tw2018elem_bookmarksDivMobile
: this._app.elements.tw2018elem_bookmarksDivDesktop;
}
_bindEvents() {
const me = this;
this._app.elements.tw2018elem_bookmarkBtn.addEventListener(
"click",
function (event) {
if (!event.defaultPrevented) {
me._toggle();
}
}
);
this._app.elements.tw2018elem_bookmarkPopupClose.addEventListener(
"click",
function (event) {
me._toggle();
event.preventDefault();
}
);
}
_showMobile(val) {
this._app.elements.tw2018elem_bookmarkPopupOverlay.style.display = val
? "flex"
: "none";
}
_showDesktop(val) {
this._app.elements.tw2018elem_bookmarksDivDesktop.style.display = val
? "inline-block"
: "none";
if (!val) {
this._app.elements.tw2018elem_viewerContainer.style.left = "0";
} else {
const bookmarkWidth =
this._app.elements.tw2018elem_bookmarksDivDesktop.getBoundingClientRect()
.width;
this._app.elements.tw2018elem_viewerContainer.style.left =
bookmarkWidth + "px";
}
this._app.setElementsSize();
}
_addBookmark(bookmark, parentDiv) {
const outlineItem = document.createElement("div");
outlineItem.classList.add("tw2018css_outlineItem");
outlineItem.setAttribute(TW_DATA_TAG, "");
const a = document.createElement("a");
a.setAttribute("href", "#");
a.innerText = bookmark.title;
a.setAttribute("bookmarkId", this.allBookmarks.length);
this.allBookmarks.push(bookmark.dest);
const me = this;
a.onclick = function (event) {
const id = parseInt(this.getAttribute("bookmarkId"));
me._app.linkService.navigateTo(me.allBookmarks[id]);
event.preventDefault();
if (me._app.isMobile) {
me._toggle();
}
return false;
};
if (bookmark.items.length > 0) {
const toggleDiv = document.createElement("div");
toggleDiv.classList.add("tw2018css_outlineItemToggler");
toggleDiv.setAttribute(TW_DATA_TAG, "");
if (!this.bookmarksFullyExpanded) {
toggleDiv.classList.add("tw2018css_outlineItemsHidden");
}
toggleDiv.onclick = function () {
me._toggleBookmark(this);
};
outlineItem.appendChild(toggleDiv);
outlineItem.appendChild(a);
const outlineItems = document.createElement("div");
outlineItems.classList.add("tw2018css_outlineItems");
outlineItems.setAttribute(TW_DATA_TAG, "");
outlineItem.appendChild(outlineItems);
for (let i = 0; i < bookmark.items.length; i++) {
me._addBookmark(bookmark.items[i], outlineItems);
}
} else {
outlineItem.classList.add("tw2018css_simple");
outlineItem.setAttribute(TW_DATA_TAG, "");
outlineItem.appendChild(a);
}
parentDiv.appendChild(outlineItem);
}
_toggleBookmarks() {
if (!this._bookmarksDiv) {
return;
}
const itemTogglers = this._bookmarksDiv.getElementsByClassName(
"tw2018css_outlineItemToggler"
);
for (let i = 0; i < itemTogglers.length; i++) {
this._toggleBookmark(itemTogglers[i]);
}
}
_resizeBookmarksDivFrame() {
const bookmarkWidth = this._bookmarksDiv.getBoundingClientRect().width;
this._app.elements.tw2018elem_viewerContainer.style.left =
bookmarkWidth + "px";
this._app.elements.tw2018elem_viewerContainer.style.width =
this._app.elements.tw2018elem_mainContainer.getBoundingClientRect()
.width -
2 -
bookmarkWidth +
"px";
this._app.setElementsSize();
}
_addIFrameResizeHandlerIfNeeded() {
if (!this._app.isMobile) {
if (!this._isResizeEventAdded) {
const me = this;
if (this._app.elements.tw2018elem_bookmarksDivFrame.contentWindow) {
this._app.elements.tw2018elem_bookmarksDivFrame.contentWindow.addEventListener(
"resize",
me._resizeBookmarksDivFrame.bind(me)
);
} else {
// TODO check for IE11 -> multiple instances of app
window.frames.tw2018elem_bookmarksDivFrame.addEventListener(
"resize",
me._resizeBookmarksDivFrame.bind(me)
);
}
me._isResizeEventAdded = true;
}
}
}
_expandAll() {
if (!this._bookmarksDiv) {
return;
}
const itemTogglers = this._bookmarksDiv.getElementsByClassName(
"tw2018css_outlineItemToggler"
);
for (let i = 0; i < itemTogglers.length; i++) {
this._expandBookmarkItem(itemTogglers[i]);
}
}
_expandBookmarkItem(div) {
div.classList.remove("tw2018css_outlineItemsHidden");
}
_closeBookmarkItem(div) {
div.classList.add("tw2018css_outlineItemsHidden");
div.setAttribute(TW_DATA_TAG, "");
}
_toggleBookmark(div) {
if (div.classList.contains("tw2018css_outlineItemsHidden")) {
this._expandBookmarkItem(div);
} else {
this._closeBookmarkItem(div);
}
}
_toggle() {
this.show(!this._isBookmarksOpened);
if (this._app.isMobile) {
tw_toggleCssClass(
this._app.elements.tw2018elem_bookmarkPopupOverlay,
"tw2018elem_bookmarkPopupOverlayVisible"
);
}
}
// #endregion
// #region public functions
/** Based on *val* parameter shows or hides bookmarks. */
show(val) {
if (!this._app.pdfDocument) {
val = false;
}
if (this.allBookmarks.length === 0) {
val = false;
}
/*
if (this._isBookmarksOpened === val) {
return;
}
*/
this._isBookmarksOpened = val;
if (!val) {
this._showMobile(val);
this._showDesktop(val);
} else {
if (!this.preserveBookmarksState) {
if (this.bookmarksFullyExpanded) {
this._expandAll();
}
}
if (this._app.isMobile) {
this._showMobile(val);
this._showDesktop(false);
} else {
this._showDesktop(val);
this._showMobile(false);
}
}
tw_focus(this._app.elements.tw2018elem_bookmarkBtn, val);
}
/**
* Resets bookmarks and its GUI elements.
*/
reset() {
this.allBookmarks = [];
this._isBookmarksCompletelyOpen = false;
this._isBookmarksOpened = false;
if (!this._app.isMobile) {
this._bookmarksDiv.innerHTML =
"<iframe class='tw2018elem_bookmarksDivFrame' data-tw2018-pdf-viewer='' allowtransparency='true'></iframe>";
this._app.elements.tw2018elem_bookmarksDivFrame =
this._bookmarksDiv.children[0];
}
}
/**
* Read all bookmarks (if they exist) from the PDF document and fill its value in related GUI elements.
*/
loadBookmarks() {
this.allBookmarks = [];
this._addIFrameResizeHandlerIfNeeded();
const me = this;
me._app.viewer.pdfDoc.getOutline().then(function (destinations) {
if (
!destinations ||
destinations.length === 0 ||
destinations.length === 1
) {
me._app.elements.tw2018elem_bookmarkBtn.disabled = true;
tw_focus(me._app.elements.tw2018elem_bookmarkBtn, false);
if (!me._app.isMobile) {
tw_hide(me._bookmarksDiv);
} else {
tw_hide(me._app.elements.tw2018elem_bookmarkPopupOverlay);
}
me._app.elements.tw2018elem_viewerContainer.style.left = "0";
} else {
me._app.elements.tw2018elem_bookmarkBtn.disabled = false;
for (let i = 0; i < destinations.length; i++) {
me._addBookmark(
destinations[i],
me._app.elements.tw2018elem_bookmarksDivMobile
);
}
for (let i = 0; i < destinations.length; i++) {
me._addBookmark(
destinations[i],
me._app.elements.tw2018elem_bookmarksDivDesktop
);
}
// me.isBookmarksCompletelyOpen = me.showBookmarksCompletelyOnOpen;
me._isBookmarksOpened = me.showBookmarksOnOpen;
me.show(me._isBookmarksOpened);
}
});
}
}
// #endregion
export { BookmarkLayer };