Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CFI related improvements #395

Merged
merged 34 commits into from
Jul 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9967855
Clean up, remove outdated code, and make things more clear
Mar 22, 2017
229d9c0
implemented iterative binary search for CFIs, without using carretFro…
HugApps Mar 29, 2017
d2c6aa4
added changes to splitting for binary search to improve performance
HugApps Mar 29, 2017
a00ff75
added a new way to split the node Range before binary searching
HugApps Mar 30, 2017
c155f4d
implementing new splitting algorithm based on rect heights
HugApps Mar 30, 2017
5159d9d
further improvments to splitting by using max height per line to cac…
HugApps Mar 31, 2017
d8fa712
editing , removing some console.logs
HugApps Mar 31, 2017
5479397
Added fix to handle video elements as CFI
HugApps Apr 3, 2017
94a2318
added buffer during split to further decrease run time
HugApps Apr 4, 2017
16b0de3
Remove video element workaround
Apr 4, 2017
00bb763
Code clean up, normalize code style
Apr 4, 2017
d6900b9
Fix calculating the visibility percentage of a partially visible rect…
Apr 5, 2017
e118608
Add debug output for new getVisibleTextRangeOffsets implementation
Apr 5, 2017
bc0bbcc
Refactor DEBUG flag
Apr 5, 2017
c8baaa9
removing parseFloat
HugApps Apr 5, 2017
da3383b
Add debug info capturing for cfi nav logic hot spot
Apr 5, 2017
72aecb4
Updated to TreeWalker logic, fixed scroll view
cappadeini Apr 24, 2017
eb112c4
Blacklist check, temp fix
May 30, 2017
e6fb9f1
Improve TreeWalker logic
May 30, 2017
4dc2e98
Fix ScrollView get first/last visible CFI by calculating the right vi…
May 31, 2017
3e3d021
Fix incorrect logic in frame dimensions getter for fxl scaler workaround
May 31, 2017
a2d6322
Sanity check for normalizeRectangle
May 31, 2017
d9747b4
Fix logic issue when checking rect visibility
Jun 16, 2016
b16b7bf
Refactor CFI nav logic to allow processing "range" CFIs with a single…
May 31, 2017
5dc51d2
Introduce new function getNearestCfiFromElement
May 31, 2017
9c2ff0b
Implement new API calls for getStartCfi and getEndCfi
May 4, 2016
229891f
Use proper axis when checking if a rect is visible in VWM (vertical w…
Jun 1, 2017
5996872
Fix related to #384, ensure page indices are properly restored on pag…
Jun 1, 2017
e04446a
Clarify that the page index values returned by the CFI nav are actual…
Jun 1, 2017
035d810
Fixed a problem with CfiNavigationLogic#getPageIndexDeltaForElement w…
barbender Jun 22, 2017
bed61d0
Fix internal CFI nav logic function
Jun 23, 2017
5b615a0
Clean up
Jul 10, 2017
0966445
Fix #386 by using parentNode instead of parentElement
Jul 10, 2017
fd9086f
Generate text offset first/last visible CFIs using a collapsed range …
Jul 11, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,485 changes: 1,265 additions & 1,220 deletions js/views/cfi_navigation_logic.js

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions js/views/fixed_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,27 @@ var FixedView = function(options, reader){
});
};

this.getStartCfi = function () {
return getDisplayingViews()[0].getStartCfi();
};

this.getEndCfi = function () {
return getDisplayingViews()[0].getEndCfi();
};

this.getNearestCfiFromElement = function(element) {
var views = getDisplayingViews();

for (var i = 0, count = views.length; i < count; i++) {

var view = views[i];
if (view.getLoadedContentFrames()[0].$iframe[0].contentDocument === element.ownerDocument) {
return view.getNearestCfiFromElement(element);
}
}

};

};
return FixedView;
});
26 changes: 22 additions & 4 deletions js/views/one_page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -974,17 +974,24 @@ var OnePageView = function (options, classes, enableBookStyleOverrides, reader)
}

function getFrameDimensions() {
if (reader.needsFixedLayoutScalerWorkAround()) {
var parentEl = _$el.parent()[0];
return {
width: parentEl.clientWidth,
height: parentEl.clientHeight
};
}
return {
width: _$el.parent()[0].clientWidth,
height: _$el.parent()[0].clientHeight
width: _meta_size.width,
height: _meta_size.height
};
}

this.getNavigator = function () {
return new CfiNavigationLogic({
$iframe: _$iframe,
frameDimensions: getFrameDimensions,
visibleContentOffsets: getVisibleContentOffsets,
frameDimensionsGetter: getFrameDimensions,
visibleContentOffsetsGetter: getVisibleContentOffsets,
classBlacklist: ["cfi-marker", "mo-cfi-highlight", "resize-sensor", "resize-sensor-expand", "resize-sensor-shrink", "resize-sensor-inner"],
elementBlacklist: [],
idBlacklist: ["MathJax_Message", "MathJax_SVG_Hidden"]
Expand Down Expand Up @@ -1117,6 +1124,17 @@ var OnePageView = function (options, classes, enableBookStyleOverrides, reader)
return self.getNavigator().getElementFromPoint(x, y);
};

this.getStartCfi = function () {
return createBookmarkFromCfi(self.getNavigator().getStartCfi());
};

this.getEndCfi = function () {
return createBookmarkFromCfi(self.getNavigator().getEndCfi());
};

this.getNearestCfiFromElement = function(element) {
return createBookmarkFromCfi(self.getNavigator().getNearestCfiFromElement(element));
};
};

OnePageView.Events = {
Expand Down
36 changes: 36 additions & 0 deletions js/views/reader_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -1628,6 +1628,29 @@ var ReaderView = function (options) {
}
return undefined;
};

/**
* Get CFI of the first element from the base of the document
* @returns {ReadiumSDK.Models.BookmarkData}
*/
this.getStartCfi = function() {
if (_currentView) {
return _currentView.getStartCfi();
}
return undefined;
};

/**
* Get CFI of the last element from the base of the document
* @returns {ReadiumSDK.Models.BookmarkData}
*/
this.getEndCfi = function() {
if (_currentView) {
return _currentView.getEndCfi();
}
return undefined;
};

/**
*
* @param {string} rangeCfi
Expand Down Expand Up @@ -1733,6 +1756,19 @@ var ReaderView = function (options) {
}
return undefined;
};

/**
* Useful for getting a CFI that's as close as possible to an invisible (not rendered, zero client rects) element
* @param {HTMLElement} element
* @returns {*}
*/
this.getNearestCfiFromElement = function(element) {
if (_currentView) {
return _currentView.getNearestCfiFromElement(element);
}
return undefined;
};

};

/**
Expand Down
83 changes: 57 additions & 26 deletions js/views/reflowable_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ var ReflowableView = function(options, reader){
columnMinWidth: 400,
spreadCount : 0,
currentSpreadIndex : 0,
currentPageIndex: 0,
columnWidth : undefined,
pageOffset : 0,
columnCount: 0
Expand Down Expand Up @@ -176,6 +177,27 @@ var ReflowableView = function(options, reader){
};
}

function getPageOffset() {
if (_paginationInfo.rightToLeft && !_paginationInfo.isVerticalWritingMode) {
return -_paginationInfo.pageOffset;
}
return _paginationInfo.pageOffset;
}

function getPaginationOffsets() {
var offset = getPageOffset();
if (_paginationInfo.isVerticalWritingMode) {
return {
top: offset,
left: 0
};
}
return {
top: 0,
left: offset
};
}

function renderIframe() {
if (_$contentFrame) {
//destroy old contentFrame
Expand All @@ -198,8 +220,9 @@ var ReflowableView = function(options, reader){

_navigationLogic = new CfiNavigationLogic({
$iframe: _$iframe,
frameDimensions: getFrameDimensions,
frameDimensionsGetter: getFrameDimensions,
paginationInfo: _paginationInfo,
paginationOffsetsGetter: getPaginationOffsets,
classBlacklist: _cfiClassBlacklist,
elementBlacklist: _cfiElementBlacklist,
idBlacklist: _cfiIdBlacklist
Expand All @@ -221,6 +244,7 @@ var ReflowableView = function(options, reader){

_paginationInfo.pageOffset = 0;
_paginationInfo.currentSpreadIndex = 0;
_paginationInfo.currentPageIndex = 0;
_currentSpineItem = spineItem;

// TODO: this is a dirty hack!!
Expand Down Expand Up @@ -412,18 +436,18 @@ var ReflowableView = function(options, reader){

}

this.openPageInternal = function(pageRequest) {
function _openPageInternal(pageRequest) {

if(_isWaitingFrameRender) {
_deferredPageRequest = pageRequest;
return;
return false;
}

// if no spine item specified we are talking about current spine item
if(pageRequest.spineItem && pageRequest.spineItem != _currentSpineItem) {
_deferredPageRequest = pageRequest;
loadSpineItem(pageRequest.spineItem);
return;
return true;
}

var pageIndex = undefined;
Expand All @@ -433,21 +457,17 @@ var ReflowableView = function(options, reader){
pageIndex = pageRequest.spineItemPageIndex;
}
else if(pageRequest.elementId) {
pageIndex = _navigationLogic.getPageForElementId(pageRequest.elementId);

if (pageIndex < 0) pageIndex = 0;
pageIndex = _paginationInfo.currentPageIndex + _navigationLogic.getPageIndexDeltaForElementId(pageRequest.elementId);
}
else if(pageRequest.firstVisibleCfi && pageRequest.lastVisibleCfi) {
var firstPageIndex;
var lastPageIndex;
try
{
firstPageIndex = _navigationLogic.getPageForElementCfi(pageRequest.firstVisibleCfi,
firstPageIndex = _navigationLogic.getPageIndexDeltaForCfi(pageRequest.firstVisibleCfi,
_cfiClassBlacklist,
_cfiElementBlacklist,
_cfiIdBlacklist);

if (firstPageIndex < 0) firstPageIndex = 0;
}
catch (e)
{
Expand All @@ -456,30 +476,26 @@ var ReflowableView = function(options, reader){
}
try
{
lastPageIndex = _navigationLogic.getPageForElementCfi(pageRequest.lastVisibleCfi,
lastPageIndex = _navigationLogic.getPageIndexDeltaForCfi(pageRequest.lastVisibleCfi,
_cfiClassBlacklist,
_cfiElementBlacklist,
_cfiIdBlacklist);

if (lastPageIndex < 0) lastPageIndex = 0;
}
catch (e)
{
lastPageIndex = 0;
console.error(e);
}
// Go to the page in the middle of the two elements
pageIndex = Math.round((firstPageIndex + lastPageIndex) / 2);
pageIndex = _paginationInfo.currentPageIndex + Math.round((firstPageIndex + lastPageIndex) / 2);
}
else if(pageRequest.elementCfi) {
try
{
pageIndex = _navigationLogic.getPageForElementCfi(pageRequest.elementCfi,
pageIndex = _paginationInfo.currentPageIndex + _navigationLogic.getPageIndexDeltaForCfi(pageRequest.elementCfi,
_cfiClassBlacklist,
_cfiElementBlacklist,
_cfiIdBlacklist);

if (pageIndex < 0) pageIndex = 0;
}
catch (e)
{
Expand All @@ -498,18 +514,20 @@ var ReflowableView = function(options, reader){
pageIndex = 0;
}

if(pageIndex >= 0 && pageIndex < _paginationInfo.columnCount) {
_paginationInfo.currentSpreadIndex = Math.floor(pageIndex / _paginationInfo.visibleColumnCount) ;
onPaginationChanged(pageRequest.initiator, pageRequest.spineItem, pageRequest.elementId);
}
else {
if (pageIndex < 0 || pageIndex > _paginationInfo.columnCount) {
console.log('Illegal pageIndex value: ', pageIndex, 'column count is ', _paginationInfo.columnCount);
pageIndex = pageIndex < 0 ? 0 : _paginationInfo.columnCount;
}
};

_paginationInfo.currentPageIndex = pageIndex;
_paginationInfo.currentSpreadIndex = Math.floor(pageIndex / _paginationInfo.visibleColumnCount) ;
onPaginationChanged(pageRequest.initiator, pageRequest.spineItem, pageRequest.elementId);
return true;
}

this.openPage = function(pageRequest) {
// Go to request page, it will save the new position in onPaginationChanged
this.openPageInternal(pageRequest);
_openPageInternal(pageRequest);
// Save it for when pagination is updated
_lastPageRequest = pageRequest;
};
Expand All @@ -533,7 +551,7 @@ var ReflowableView = function(options, reader){

this.restoreCurrentPosition = function() {
if (_lastPageRequest) {
this.openPageInternal(_lastPageRequest);
_openPageInternal(_lastPageRequest);
}
};

Expand Down Expand Up @@ -578,7 +596,7 @@ var ReflowableView = function(options, reader){
}

function onPaginationChanged_(initiator, paginationRequest_spineItem, paginationRequest_elementId) {

_paginationInfo.currentPageIndex = _paginationInfo.currentSpreadIndex * _paginationInfo.visibleColumnCount;
_paginationInfo.pageOffset = (_paginationInfo.columnWidth + _paginationInfo.columnGap) * _paginationInfo.visibleColumnCount * _paginationInfo.currentSpreadIndex;

redraw();
Expand Down Expand Up @@ -839,6 +857,7 @@ var ReflowableView = function(options, reader){
if (_lastPageRequest) {
// Make sure we stay on the same page after the content or the viewport
// has been resized
_paginationInfo.currentPageIndex = 0; // current page index is not stable, reset it
self.restoreCurrentPosition();
} else {
onPaginationChanged(self); // => redraw() => showBook(), so the trick below is not needed
Expand Down Expand Up @@ -1150,6 +1169,14 @@ var ReflowableView = function(options, reader){
return createBookmarkFromCfi(_navigationLogic.getLastVisibleCfi());
};

this.getStartCfi = function () {
return createBookmarkFromCfi(_navigationLogic.getStartCfi());
};

this.getEndCfi = function () {
return createBookmarkFromCfi(_navigationLogic.getEndCfi());
};

this.getDomRangeFromRangeCfi = function (rangeCfi, rangeCfi2, inclusive) {
if (rangeCfi2 && rangeCfi.idref !== rangeCfi2.idref) {
console.error("getDomRangeFromRangeCfi: both CFIs must be scoped under the same spineitem idref");
Expand Down Expand Up @@ -1177,6 +1204,10 @@ var ReflowableView = function(options, reader){
this.getElementFromPoint = function(x, y) {
return _navigationLogic.getElementFromPoint(x,y);
};

this.getNearestCfiFromElement = function(element) {
return createBookmarkFromCfi(_navigationLogic.getNearestCfiFromElement(element));
};
};
return ReflowableView;
});
Loading