UNPKG

vscroll

Version:
260 lines 9.57 kB
import { __extends, __read, __spreadArray } from "tslib"; import { BaseProcessFactory, CommonProcess, AdapterProcess, ProcessStatus } from './misc/index'; import { Direction } from '../inputs/index'; var PreFetch = /** @class */ (function (_super) { __extends(PreFetch, _super); function PreFetch() { return _super !== null && _super.apply(this, arguments) || this; } PreFetch.run = function (scroller) { var workflow = scroller.workflow, buffer = scroller.buffer, state = scroller.state; var fetch = state.fetch, cycle = state.cycle; fetch.minIndex = buffer.minIndex; // set first and last indexes of items to fetch PreFetch.setPositionsAndIndexes(scroller); // skip indexes that are in buffer PreFetch.skipBufferedItems(scroller); if (scroller.settings.infinite) { // fill indexes to include buffer if no clip PreFetch.checkBufferGaps(scroller); } // add indexes if there are too few items to fetch (clip padding) PreFetch.checkFetchPackSize(scroller); // set fetch direction PreFetch.setFetchDirection(scroller); workflow.call({ process: PreFetch.process, status: PreFetch.getStatus(scroller), payload: { process: cycle.initiator } }); }; PreFetch.setPositionsAndIndexes = function (scroller) { PreFetch.setPositions(scroller); PreFetch.setFirstIndex(scroller); PreFetch.setLastIndex(scroller); scroller.logger.fetch(); }; PreFetch.setPositions = function (scroller) { var state = scroller.state, viewport = scroller.viewport; var positions = state.fetch.positions; var paddingDelta = viewport.getBufferPadding(); positions.before = viewport.scrollPosition; positions.startDelta = PreFetch.getStartDelta(scroller); positions.relative = positions.before - positions.startDelta; positions.start = positions.relative - paddingDelta; positions.end = positions.relative + viewport.getSize() + paddingDelta; }; PreFetch.getStartDelta = function (scroller) { // calculate size before start index var buffer = scroller.buffer, viewport = scroller.viewport; var offset = viewport.offset; var startDelta = 0; if (offset) { startDelta += offset; } if (!buffer.defaultSize) { return startDelta; } for (var index = buffer.finiteAbsMinIndex; index < buffer.startIndex; index++) { startDelta += buffer.getSizeByIndex(index); } scroller.logger.log(function () { return __spreadArray([ "start delta is ".concat(startDelta) ], __read((offset ? [" (+".concat(offset, " offset)")] : [])), false); }); return startDelta; }; PreFetch.setFirstIndex = function (scroller) { var state = scroller.state, buffer = scroller.buffer; var _a = state.fetch, positions = _a.positions, first = _a.first; var start = positions.start; var firstIndex = buffer.startIndex; var firstIndexPosition = 0; if (state.cycle.innerLoop.isInitial) { scroller.logger.log('skipping fetch backward direction [initial loop]'); } else if (!buffer.defaultSize) { scroller.logger.log('skipping fetch backward direction [no item size]'); } else { var position = firstIndexPosition; var index = firstIndex; while (true) { if (start >= 0) { var size = buffer.getSizeByIndex(index); var diff = position + size - start; if (diff > 0) { firstIndex = index; firstIndexPosition = position; break; } position += size; index++; if (index < buffer.absMinIndex) { break; } } if (start < 0) { index--; if (index < buffer.absMinIndex) { break; } position -= buffer.getSizeByIndex(index); var diff = position - start; firstIndex = index; firstIndexPosition = position; if (diff <= 0) { break; } } } } first.index = first.indexBuffer = Math.max(firstIndex, buffer.absMinIndex); first.position = firstIndexPosition; }; PreFetch.setLastIndex = function (scroller) { var state = scroller.state, buffer = scroller.buffer, settings = scroller.settings; var fetch = state.fetch, cycle = state.cycle; var firstVisible = fetch.firstVisible, positions = fetch.positions, first = fetch.first, last = fetch.last; var relative = positions.relative, end = positions.end; var lastIndex; if (!buffer.defaultSize) { // just to fetch forward bufferSize items if neither averageItemSize nor itemSize are present lastIndex = buffer.startIndex + settings.bufferSize - 1; scroller.logger.log('forcing fetch forward direction [no item size]'); } else { var index = first.indexBuffer; var position = first.position; lastIndex = index; while (true) { lastIndex = index; var size = buffer.getSizeByIndex(index); position += size; if (isNaN(firstVisible.index) && position > relative) { firstVisible.index = index; if (!cycle.innerLoop.isInitial) { firstVisible.delta = position - size - relative; } } if (position >= end) { break; } if (index++ > buffer.absMaxIndex) { break; } } } last.index = last.indexBuffer = Math.min(lastIndex, buffer.absMaxIndex); }; PreFetch.skipBufferedItems = function (scroller) { var buffer = scroller.buffer; if (!buffer.size) { return; } var fetch = scroller.state.fetch; var firstIndex = fetch.first.index; var lastIndex = fetch.last.index; var packs = [[]]; var p = 0; for (var i = firstIndex; i <= lastIndex; i++) { if (!buffer.get(i)) { packs[p].push(i); } else if (packs[p].length) { packs[++p] = []; } } var pack = packs[0]; if (packs[0].length && packs[1] && packs[1].length) { fetch.hasAnotherPack = true; // todo: need to look for biggest pack in visible area // todo: or think about merging two requests in a single Fetch process if (packs[1].length >= packs[0].length) { pack = packs[1]; } } fetch.first.index = Math.max(pack[0], buffer.absMinIndex); fetch.last.index = Math.min(pack[pack.length - 1], buffer.absMaxIndex); if (fetch.first.index !== firstIndex || fetch.last.index !== lastIndex) { scroller.logger.fetch('after Buffer flushing'); } }; PreFetch.checkBufferGaps = function (scroller) { var buffer = scroller.buffer, state = scroller.state; var fetch = state.fetch; if (!buffer.size) { return; } var fetchFirst = fetch.first.index; var bufferLast = buffer.lastIndex; if (fetchFirst > bufferLast) { fetch.first.index = fetch.first.indexBuffer = bufferLast + 1; } var bufferFirst = buffer.firstIndex; var fetchLast = fetch.last.index; if (fetchLast < bufferFirst) { fetch.last.index = fetch.last.indexBuffer = bufferFirst - 1; } if (fetch.first.index !== fetchFirst || fetch.last.index !== fetchLast) { scroller.logger.fetch('after Buffer filling (no clip case)'); } }; PreFetch.checkFetchPackSize = function (scroller) { var buffer = scroller.buffer, state = scroller.state; var fetch = state.fetch; if (!fetch.shouldFetch) { return; } var firstIndex = fetch.first.index; var lastIndex = fetch.last.index; var diff = scroller.settings.bufferSize - (lastIndex - firstIndex + 1); if (diff <= 0) { return; } if (!buffer.size || lastIndex > buffer.items[0].$index) { // forward var newLastIndex = Math.min(lastIndex + diff, buffer.absMaxIndex); if (newLastIndex > lastIndex) { fetch.last.index = fetch.last.indexBuffer = newLastIndex; } } else { var newFirstIndex = Math.max(firstIndex - diff, buffer.absMinIndex); if (newFirstIndex < firstIndex) { fetch.first.index = fetch.first.indexBuffer = newFirstIndex; } } if (fetch.first.index !== firstIndex || fetch.last.index !== lastIndex) { scroller.logger.fetch('after bufferSize adjustment'); PreFetch.skipBufferedItems(scroller); } }; PreFetch.setFetchDirection = function (scroller) { var buffer = scroller.buffer, state = scroller.state; var fetch = state.fetch; if (fetch.last.index) { var direction_1 = Direction.forward; if (buffer.size) { direction_1 = fetch.last.index < buffer.items[0].$index ? Direction.backward : Direction.forward; } fetch.direction = direction_1; scroller.logger.log(function () { return "fetch direction is \"".concat(direction_1, "\""); }); } }; PreFetch.getStatus = function (scroller) { var _a = scroller.state, cycle = _a.cycle, fetch = _a.fetch; if (cycle.initiator === AdapterProcess.clip) { scroller.logger.log(function () { return "going to skip fetch due to \"".concat(AdapterProcess.clip, "\" process"); }); return ProcessStatus.next; } if (fetch.shouldFetch) { scroller.logger.log(function () { return "going to fetch ".concat(fetch.count, " items started from index ").concat(fetch.index); }); return ProcessStatus.next; } return ProcessStatus.done; }; return PreFetch; }(BaseProcessFactory(CommonProcess.preFetch))); export default PreFetch; //# sourceMappingURL=preFetch.js.map