@progress/telerik-jquery-report-viewer
Version:
Progress® Telerik® Report Viewer for jQuery
536 lines (531 loc) • 20.2 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var utils = require('./utils.js');
var Scroll = {
controller: {},
$placeholder: null,
$pageContainer: null,
pageContainer: null,
$pageWrapper: null,
pageWrapper: null,
viewMode: null,
loadedPage: {},
scrollInProgress: false,
enabled: false,
pageCount: 0,
additionalTopOffset: 130,
pageDistance: 20,
oldScrollTopPosition: 0,
skeletonTemplate: '<div class="trv-report-page trv-skeleton-page trv-skeleton-{0}" style="{1}" data-page="{0}"><div class="trv-skeleton-wrapper" style="{2}"></div></div>',
/**
* Initialize the scroll object
* Takes two parameters
* - placeholder - PageArea dom element
* - options - PageArea options
*/
init: function init(placeholder, options) {
var that = this;
that.$placeholder = $("[data-selector='" + options.viewerSelector + "']").find(placeholder);
that.$pageContainer = this.$placeholder.find(".trv-page-container");
that.pageContainer = this.$pageContainer[0];
that.$pageWrapper = this.$placeholder.find(".trv-page-wrapper");
that.pageWrapper = this.$pageWrapper[0];
that.controller = options.controller;
that.viewMode = null;
that.loadedPage = {};
that.scrollInProgress = false;
that.enabled = false;
that.pageCount = 0;
that.controller.scaleChanged(function(e, args) {
if (that.enabled) {
setTimeout(function() {
that._loadMorePages();
that._keepCurrentPageInToView();
}, 100);
}
}).loadedReportChange(function(event) {
if (that.enabled) {
that.disable();
if (event.type !== "loadedReportChange") {
setTimeout(function() {
that.controller.getPageData(1).then(function(newPage) {
that.renderPage(newPage);
});
});
}
}
}).viewModeChanged(function(args) {
if (that.enabled) {
that.disable();
}
}).interactiveActionExecuting(function(e, args) {
var actionType = args.action.Type;
if (that.enabled && (actionType === "sorting" || actionType === "toggleVisibility")) {
that.disable();
}
}).updatePageDimensionsReady(function(event, args) {
if (that.enabled && that._currentPageNumber() > 0) {
that._keepCurrentPageInToView();
}
}).pageCountChange(function(event, args) {
if (that.enabled && that.pageCount !== args) {
if (that._currentPageNumber() > 0 && !that.scrollInProgress) {
that._loadMorePages();
}
if (args > 1) {
that._initEvents();
}
that.pageCount = args;
}
});
},
/**
* Returns true, when Telerik Report Viewer pageMode is set to CONTINUOUS_SCROLL or it is unset
*/
isEnabled: function isEnabled() {
return this.enabled;
},
disable: function disable() {
this.$pageWrapper.empty();
this.enabled = false;
this.loadedPage = {};
this.pageCount = 0;
this.$placeholder.removeClass("scrollable");
this._unbind();
},
enable: function() {
this.enabled = true;
this.$placeholder.addClass("scrollable");
this._initEvents();
},
/**
* Handle the page rendering called from the PageArea
* Takes one parameter
* page - the page object
*/
renderPage: function renderPage(page) {
var that = this;
var pageViewMode = that.controller.getViewMode();
var renderedPage = that.$placeholder.find('[data-page="' + page.pageNumber + '"]');
if (!that.enabled) {
that.enabled = true;
that.$placeholder.addClass("scrollable");
if (pageViewMode !== that.viewMode || !renderedPage.length) {
that._updatePageArea(page);
} else {
that._render(page, true);
this.$pageContainer.scrollTop(3);
that._setCurrentPage(page.pageNumber);
}
that.viewMode = that.controller.getViewMode();
that._loadMorePages();
} else {
if (pageViewMode !== that.viewMode || !renderedPage.length) {
that._updatePageArea(page);
} else {
that._navigateToPage(page, renderedPage);
}
that.viewMode = that.controller.getViewMode();
}
},
/**
* Trigger scrolling animation to the specific element.
*/
navigateToElement: function navigateToElement(offsetTop, pageNumber) {
var that = this;
that.scrollInProgress = true;
if (that._isSkeletonScreen(null, pageNumber)) {
that.controller.getPageData(pageNumber).then(function(newPage) {
that._render(newPage, false);
that.$pageContainer.animate({ scrollTop: offsetTop }, 500, function() {
that._setCurrentPage(pageNumber);
setTimeout(function() {
that.scrollInProgress = false;
}, 100);
});
});
} else {
that.$pageContainer.animate({ scrollTop: offsetTop }, 500, function() {
that._setCurrentPage(pageNumber);
setTimeout(function() {
that.scrollInProgress = false;
}, 100);
});
}
},
_setCurrentPage: function _setCurrentPage(pageNumber) {
var that = this;
if (pageNumber !== that._currentPageNumber()) {
that.controller.setCurrentPageNumber(pageNumber);
}
if (that.controller.getPageCount() > 1) {
that.$placeholder.find(".k-state-default").removeClass("k-state-default");
that.$placeholder.find('[data-page="' + pageNumber + '"]').addClass("k-state-default");
}
that._loadNextPreviousPage(pageNumber);
},
_updatePageArea: function _updatePageArea(page) {
var that = this;
var scrollTo = 0;
var pageNumber = page.pageNumber;
that.scrollInProgress = true;
if (pageNumber > 1) {
that._generateSkeletonScreens(pageNumber);
}
that._render(page, false);
that._setCurrentPage(page.pageNumber);
setTimeout(function() {
scrollTo = pageNumber > 1 ? that.$placeholder.find('[data-page="' + pageNumber + '"]').position().top : 0;
that.$pageContainer.animate({ scrollTop: scrollTo }, 0, function() {
that.scrollInProgress = false;
});
}, 100);
},
_navigateToPage: function _navigateToPage(page, renderedPage) {
var that = this;
that.scrollInProgress = true;
var scrollTo = renderedPage.position().top;
var pages = that.$placeholder.find(".trv-report-page");
var pageNumber = page.pageNumber;
$(pages[0]).height();
if (that._isSkeletonScreen(renderedPage, pageNumber)) {
that.controller.getPageData(pageNumber).then(function(newPage) {
that._render(newPage, false);
that.$pageContainer.animate({ scrollTop: scrollTo }, 500, function() {
setTimeout(function() {
that._setCurrentPage(newPage.pageNumber);
that.scrollInProgress = false;
});
});
});
} else {
that._updatePageContent(page, renderedPage);
that.$pageContainer.animate({ scrollTop: scrollTo }, 500, function() {
setTimeout(function() {
that._setCurrentPage(page.pageNumber);
that.scrollInProgress = false;
});
});
}
},
_updatePageContent: function _updatePageContent(page, renderedPage) {
this._updatePageStyle(page);
var pageNumber = page.pageNumber;
var wrapper = $($.parseHTML(page.pageContent));
var $pageContent = wrapper.find("div.sheet");
var $page = this.$placeholder.find('[data-page="' + pageNumber + '"]');
$pageContent.css("margin", 0);
$page.append($pageContent).append($('<div class="trv-page-overlay"></div>'));
renderedPage.replaceWith($page);
this.controller.scrollPageReady({ page, target: $page });
},
_currentPageNumber: function _currentPageNumber() {
return this.controller.getCurrentPageNumber();
},
_isSkeletonScreen: function _isSkeletonScreen(page, pageNumber) {
if (!page) {
page = this.$placeholder.find('[data-page="' + pageNumber + '"]');
}
return page.hasClass("trv-skeleton-" + pageNumber);
},
_addSkeletonScreen: function _addSkeletonScreen(pageNumber, position) {
var that = this;
var pageStyleNumber = position ? parseInt(pageNumber + 1) : parseInt(pageNumber - 1);
var pageStyleBaseDom = that.$placeholder.find('[data-page="' + pageStyleNumber + '"]');
var pageStyle = pageStyleBaseDom.attr("style");
var contentStyle = pageStyleBaseDom.find("sheet").attr("style");
var skeletonEl = utils.stringFormat(that.skeletonTemplate, [pageNumber, pageStyle, contentStyle]);
if (position) {
that.$pageWrapper.prepend(skeletonEl);
} else {
that.$pageWrapper.append(skeletonEl);
}
},
_generateSkeletonScreens: function _generateSkeletonScreens(upToPageNumber) {
var that = this;
var skeletonEl = "";
var pageStyleBaseDom = this.$placeholder.find('[data-page="1"]');
var pageStyle = pageStyleBaseDom.attr("style");
var contentStyle = pageStyleBaseDom.find("sheet").attr("style");
var lastPage = that.$placeholder.find(".trv-report-page").last().attr("data-page");
var index = lastPage ? parseInt(lastPage) + 1 : 1;
for (index; index < upToPageNumber; index++) {
skeletonEl = skeletonEl + utils.stringFormat(that.skeletonTemplate, [index, pageStyle, contentStyle]);
}
that.$pageWrapper.append($(skeletonEl));
},
_loadMorePages: function _loadMorePages() {
var that = this;
var pageCount = that.controller.getPageCount();
var isViewPortBiggerThanPageHeight = that.$pageContainer.innerHeight() > that.$pageWrapper.innerHeight();
if (pageCount > 1) {
if (isViewPortBiggerThanPageHeight) {
that.scrollInProgress = true;
var lastPage = parseInt(that.$placeholder.find(".trv-report-page").last().attr("data-page"));
var nextPage = lastPage + 1;
if (nextPage <= pageCount) {
that.controller.getPageData(nextPage).then(function(newPage) {
that._render(newPage, false);
that._loadMorePages();
that.scrollInProgress = false;
});
}
} else {
that._loadVisiblePages();
that.scrollInProgress = false;
}
}
},
_loadVisiblePages: function _loadVisiblePages() {
var that = this;
var pages = that.$placeholder.find(".trv-report-page");
Array.from(pages).forEach((value) => {
var pageItem = $(value);
var pageNumber = parseInt(pageItem.attr("data-page"));
if (that._scrolledInToView(pageItem) && that._isSkeletonScreen(pageItem, pageNumber)) {
that.controller.getPageData(pageNumber).then((newPage) => {
that._render(newPage, false);
});
}
});
},
_scrolledInToView: function _scrolledInToView(elem) {
var pageCoords = elem[0].getBoundingClientRect();
var parentCoords = elem.closest(".trv-pages-area")[0].getBoundingClientRect();
var parentTop = parentCoords.top;
var parentBottom = parentCoords.top + parentCoords.height;
var pageTop = pageCoords.top;
var pageBottom = pageTop + elem.outerHeight(true);
var additionalTopOffset = this.additionalTopOffset + parentTop;
var topVisible = pageTop > 0 && pageTop < parentBottom;
var bottomVisible = pageBottom < parentBottom && pageBottom > additionalTopOffset;
return topVisible || bottomVisible;
},
_render: function _render(page, empty) {
var that = this;
var pageNumber = page.pageNumber;
var pageItem = that.$placeholder.find('[data-page="' + pageNumber + '"]');
if (!empty && pageItem && pageItem.length && !that._isSkeletonScreen(pageItem, pageNumber)) {
return;
}
that.loadedPage[pageNumber] = page;
that._updatePageStyle(page);
var wrapper = $($.parseHTML(page.pageContent));
var $pageContent = wrapper.find("div.sheet");
var $page = $('<div class="trv-report-page" data-page="' + pageNumber + '"></div>');
$pageContent.css("margin", 0);
$page.append($pageContent).append($('<div class="trv-page-overlay"></div>'));
if (empty) {
that.$pageWrapper.empty();
}
that.$pageWrapper.removeData().data("pageNumber", pageNumber);
var $skeletonPage = that.$placeholder.find(".trv-skeleton-" + pageNumber);
if ($skeletonPage.length) {
$skeletonPage.replaceWith($page);
} else {
that.$pageWrapper.append($page);
}
that.controller.scrollPageReady({ page, target: $page });
},
_updatePageStyle: function _updatePageStyle(page) {
var that = this;
var lastLoadedPage = that.loadedPage[that._lastLoadedPage()] || page;
var styleId = "trv-" + that.controller.clientId() + "-styles";
var pageStyles;
$("#" + styleId).remove();
pageStyles = $("<style id=" + styleId + "></style>");
pageStyles.append(lastLoadedPage.pageStyles);
pageStyles.appendTo("head");
},
_lastLoadedPage: function _lastLoadedPage() {
var that = this;
var lastKey;
for (var key in that.loadedPage) {
if (that.loadedPage.hasOwnProperty(key)) {
lastKey = key;
}
}
return lastKey;
},
_loadNextPreviousPage: function _loadNextPreviousPage(pageNumber) {
var that = this;
var nextPage;
var previousPage;
var nextItem;
var previousItem;
if (pageNumber < that.controller.getPageCount()) {
nextPage = pageNumber + 1;
nextItem = that.$placeholder.find('[data-page="' + nextPage + '"]');
}
if (pageNumber > 1) {
previousPage = pageNumber - 1;
previousItem = that.$placeholder.find('[data-page="' + previousPage + '"]');
}
if (previousItem && previousItem.length && that._isSkeletonScreen(previousItem, previousPage)) {
that.controller.getPageData(previousPage).then(function(newPage) {
that._render(newPage, false);
});
}
if (nextItem && nextItem.length && that._isSkeletonScreen(nextItem, nextPage)) {
that.controller.getPageData(nextPage).then(function(newPage) {
that._render(newPage, false);
});
}
},
_clickPage: function _clickPage(pageDom) {
var that = this;
var currentPage = that._currentPageNumber();
var pageNumber = parseInt(pageDom.attr("data-page"));
if (currentPage !== pageNumber) {
if (that._isSkeletonScreen(pageDom, pageNumber)) {
that.controller.getPageData(pageNumber).then(function(newPage) {
that._render(newPage, false, true);
that._setCurrentPage(newPage.pageNumber);
});
} else {
that._setCurrentPage(pageNumber);
}
}
},
_initEvents: function _initEvents() {
var that = this;
that.$pageContainer.off("click", ".trv-report-page").on("click", ".trv-report-page", function(e) {
that._clickPage($(e.currentTarget));
});
that.$pageContainer.scroll(function() {
var pages = that.$placeholder.find(".trv-report-page");
var scrollPosition = parseInt((that.$pageContainer.scrollTop() + that.$pageContainer.innerHeight()).toFixed(0));
if (!that.scrollInProgress && that.oldScrollTopPosition !== scrollPosition) {
if (that.oldScrollTopPosition > scrollPosition) {
that._scrollUp(pages);
} else {
that._scrollDown(pages, scrollPosition);
}
}
that.oldScrollTopPosition = scrollPosition;
});
that.$pageContainer.scroll(function() {
var pages = that.$placeholder.find(".trv-report-page");
var scrollPosition = parseInt((that.$pageContainer.scrollTop() + that.$pageContainer.innerHeight()).toFixed(0));
if (!that.scrollInProgress && pages.length && that.oldScrollTopPosition !== scrollPosition) {
that._advanceCurrentPage(pages);
}
});
},
_unbind: function() {
var that = this;
that.$pageContainer.off("click", ".trv-report-page");
that.$pageContainer.off("scroll");
},
_advanceCurrentPage: function _advanceCurrentPage(pages) {
var that = this;
var newCurrentPage = that._findNewCurrentPage(pages);
var pageNumber;
var currentPageNumber = that._currentPageNumber();
var currentPageIsInToView = that._scrolledInToView(that.$placeholder.find('[data-page="' + currentPageNumber + '"]'));
if (newCurrentPage !== -1) {
newCurrentPage = $(newCurrentPage);
pageNumber = parseInt(newCurrentPage.attr("data-page"));
if (currentPageNumber !== pageNumber && !currentPageIsInToView) {
if (that._isSkeletonScreen(newCurrentPage, pageNumber)) {
that.controller.getPageData(pageNumber).then(function(newPage) {
that._render(newPage, false, true);
that._setCurrentPage(newPage.pageNumber);
});
} else {
that._setCurrentPage(pageNumber);
}
}
} else {
console.log("Page not found - ", newCurrentPage);
}
},
// Binary search
_findNewCurrentPage: function _findNewCurrentPage(pages) {
var that = this;
var middleIndex = Math.floor(pages.length / 2);
var result = that._findPageInViewPort(middleIndex, pages);
if (pages.length === 1) {
return pages[0];
}
if (result === 0) {
return pages[middleIndex];
} else if (result < 0 && pages.length > 1) {
return that._findNewCurrentPage(pages.splice(middleIndex, Number.MAX_VALUE));
} else if (result > 0 && pages.length > 1) {
return that._findNewCurrentPage(pages.splice(0, middleIndex));
}
return -1;
},
_findPageInViewPort: function _findPageInViewPort(index, pages) {
var pageItem = this.$placeholder.find(pages[index]);
var pageCoords = pageItem[0].getBoundingClientRect();
var parentCoords = pageItem.closest(".trv-pages-area")[0].getBoundingClientRect();
var parentTop = parentCoords.top;
parentCoords.top + parentCoords.height;
var pageTop = pageCoords.top;
var pageBottom = pageTop + pageItem.outerHeight(true);
var additionalTopOffset = this.additionalTopOffset + parentTop;
var isCurentPage = pageTop <= additionalTopOffset && additionalTopOffset < pageBottom;
if (isCurentPage) {
return 0;
}
if (pageBottom < additionalTopOffset) {
return -1;
}
return 1;
},
_scrollDown: function _scrollDown(pages, scrollPosition) {
var that = this;
if (scrollPosition >= that.pageContainer.scrollHeight - 5) {
var lastPage = parseInt($(pages[pages.length - 1]).attr("data-page"));
var nextPage = lastPage + 1;
if (that._currentPageNumber() < nextPage && nextPage <= that.controller.getPageCount()) {
that._addSkeletonScreen(nextPage, false);
that.controller.getPageData(nextPage).then(function(newPage) {
that._render(newPage, false);
});
}
} else {
that._advanceCurrentPage(pages);
that._loadVisiblePages();
}
},
_scrollUp: function _scrollUp(pages) {
var that = this;
if (that.$pageContainer.scrollTop() === 0) {
var firstPage = $(pages[0]);
var pageNumber = parseInt(firstPage.attr("data-page"));
var previousPage = pageNumber - 1;
if (that._currentPageNumber() > previousPage && previousPage >= 1) {
that._addSkeletonScreen(previousPage, true);
that.controller.getPageData(previousPage).then(function(newPage) {
that._render(newPage, false);
that.$pageContainer.scrollTop(3);
});
}
} else {
that._advanceCurrentPage(pages);
that._loadVisiblePages();
}
},
_keepCurrentPageInToView: function _keepCurrentPageInToView() {
var that = this;
var currentPage = that.$placeholder.find('[data-page="' + that._currentPageNumber() + '"]');
var currentPagePosition = currentPage.position().top;
var currentPageHeight = currentPage.innerHeight();
var pageContainerHeight = that.$pageContainer.innerHeight();
var emptyView;
that.scrollInProgress = true;
if (currentPageHeight < pageContainerHeight) {
emptyView = (pageContainerHeight - currentPageHeight) / 2;
currentPagePosition = parseInt(currentPagePosition - emptyView);
}
that.$pageContainer.animate({ scrollTop: currentPagePosition }, 0, function() {
setTimeout(function() {
that.scrollInProgress = false;
}, 100);
});
}
};
exports.Scroll = Scroll;
;