infinity.esm.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*!
  2. * better-scroll / infinity
  3. * (c) 2016-2021 ustbhuangyi
  4. * Released under the MIT License.
  5. */
  6. function warn(msg) {
  7. console.error("[BScroll warn]: " + msg);
  8. }
  9. /*! *****************************************************************************
  10. Copyright (c) Microsoft Corporation.
  11. Permission to use, copy, modify, and/or distribute this software for any
  12. purpose with or without fee is hereby granted.
  13. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  14. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  15. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  16. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  17. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  18. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  19. PERFORMANCE OF THIS SOFTWARE.
  20. ***************************************************************************** */
  21. var __assign = function() {
  22. __assign = Object.assign || function __assign(t) {
  23. for (var s, i = 1, n = arguments.length; i < n; i++) {
  24. s = arguments[i];
  25. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  26. }
  27. return t;
  28. };
  29. return __assign.apply(this, arguments);
  30. };
  31. function __awaiter(thisArg, _arguments, P, generator) {
  32. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  33. return new (P || (P = Promise))(function (resolve, reject) {
  34. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  35. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  36. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  37. step((generator = generator.apply(thisArg, _arguments || [])).next());
  38. });
  39. }
  40. function __generator(thisArg, body) {
  41. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  42. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  43. function verb(n) { return function (v) { return step([n, v]); }; }
  44. function step(op) {
  45. if (f) throw new TypeError("Generator is already executing.");
  46. while (_) try {
  47. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  48. if (y = 0, t) op = [op[0] & 2, t.value];
  49. switch (op[0]) {
  50. case 0: case 1: t = op; break;
  51. case 4: _.label++; return { value: op[1], done: false };
  52. case 5: _.label++; y = op[1]; op = [0]; continue;
  53. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  54. default:
  55. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  56. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  57. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  58. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  59. if (t[2]) _.ops.pop();
  60. _.trys.pop(); continue;
  61. }
  62. op = body.call(thisArg, _);
  63. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  64. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  65. }
  66. }
  67. // ssr support
  68. var inBrowser = typeof window !== 'undefined';
  69. var ua = inBrowser && navigator.userAgent.toLowerCase();
  70. !!(ua && /wechatdevtools/.test(ua));
  71. ua && ua.indexOf('android') > 0;
  72. /* istanbul ignore next */
  73. ((function () {
  74. if (typeof ua === 'string') {
  75. var regex = /os (\d\d?_\d(_\d)?)/;
  76. var matches = regex.exec(ua);
  77. if (!matches)
  78. return false;
  79. var parts = matches[1].split('_').map(function (item) {
  80. return parseInt(item, 10);
  81. });
  82. // ios version >= 13.4 issue 982
  83. return !!(parts[0] === 13 && parts[1] >= 4);
  84. }
  85. return false;
  86. }))();
  87. /* istanbul ignore next */
  88. var supportsPassive = false;
  89. /* istanbul ignore next */
  90. if (inBrowser) {
  91. var EventName = 'test-passive';
  92. try {
  93. var opts = {};
  94. Object.defineProperty(opts, 'passive', {
  95. get: function () {
  96. supportsPassive = true;
  97. },
  98. }); // https://github.com/facebook/flow/issues/285
  99. window.addEventListener(EventName, function () { }, opts);
  100. }
  101. catch (e) { }
  102. }
  103. var elementStyle = (inBrowser &&
  104. document.createElement('div').style);
  105. var vendor = (function () {
  106. /* istanbul ignore if */
  107. if (!inBrowser) {
  108. return false;
  109. }
  110. var transformNames = [
  111. {
  112. key: 'standard',
  113. value: 'transform',
  114. },
  115. {
  116. key: 'webkit',
  117. value: 'webkitTransform',
  118. },
  119. {
  120. key: 'Moz',
  121. value: 'MozTransform',
  122. },
  123. {
  124. key: 'O',
  125. value: 'OTransform',
  126. },
  127. {
  128. key: 'ms',
  129. value: 'msTransform',
  130. },
  131. ];
  132. for (var _i = 0, transformNames_1 = transformNames; _i < transformNames_1.length; _i++) {
  133. var obj = transformNames_1[_i];
  134. if (elementStyle[obj.value] !== undefined) {
  135. return obj.key;
  136. }
  137. }
  138. /* istanbul ignore next */
  139. return false;
  140. })();
  141. /* istanbul ignore next */
  142. function prefixStyle(style) {
  143. if (vendor === false) {
  144. return style;
  145. }
  146. if (vendor === 'standard') {
  147. if (style === 'transitionEnd') {
  148. return 'transitionend';
  149. }
  150. return style;
  151. }
  152. return vendor + style.charAt(0).toUpperCase() + style.substr(1);
  153. }
  154. var cssVendor = vendor && vendor !== 'standard' ? '-' + vendor.toLowerCase() + '-' : '';
  155. var transform = prefixStyle('transform');
  156. var transition = prefixStyle('transition');
  157. inBrowser && prefixStyle('perspective') in elementStyle;
  158. var style = {
  159. transform: transform,
  160. transition: transition,
  161. transitionTimingFunction: prefixStyle('transitionTimingFunction'),
  162. transitionDuration: prefixStyle('transitionDuration'),
  163. transitionDelay: prefixStyle('transitionDelay'),
  164. transformOrigin: prefixStyle('transformOrigin'),
  165. transitionEnd: prefixStyle('transitionEnd'),
  166. transitionProperty: prefixStyle('transitionProperty'),
  167. };
  168. var PRE_NUM = 10;
  169. var POST_NUM = 30;
  170. var IndexCalculator = /** @class */ (function () {
  171. function IndexCalculator(wrapperHeight, tombstoneHeight) {
  172. this.wrapperHeight = wrapperHeight;
  173. this.tombstoneHeight = tombstoneHeight;
  174. this.lastDirection = 1 /* DOWN */;
  175. this.lastPos = 0;
  176. }
  177. IndexCalculator.prototype.calculate = function (pos, list) {
  178. var offset = pos - this.lastPos;
  179. this.lastPos = pos;
  180. var direction = this.getDirection(offset);
  181. // important! start index is much more important than end index.
  182. var start = this.calculateIndex(0, pos, list);
  183. var end = this.calculateIndex(start, pos + this.wrapperHeight, list);
  184. if (direction === 1 /* DOWN */) {
  185. start -= PRE_NUM;
  186. end += POST_NUM;
  187. }
  188. else {
  189. start -= POST_NUM;
  190. end += PRE_NUM;
  191. }
  192. if (start < 0) {
  193. start = 0;
  194. }
  195. return {
  196. start: start,
  197. end: end,
  198. };
  199. };
  200. IndexCalculator.prototype.getDirection = function (offset) {
  201. var direction;
  202. if (offset > 0) {
  203. direction = 1 /* DOWN */;
  204. }
  205. else if (offset < 0) {
  206. direction = 0 /* UP */;
  207. }
  208. else {
  209. return this.lastDirection;
  210. }
  211. this.lastDirection = direction;
  212. return direction;
  213. };
  214. IndexCalculator.prototype.calculateIndex = function (start, offset, list) {
  215. if (offset <= 0) {
  216. return start;
  217. }
  218. var i = start;
  219. var startPos = list[i] && list[i].pos !== -1 ? list[i].pos : 0;
  220. var lastPos = startPos;
  221. var tombstone = 0;
  222. while (i < list.length && list[i].pos < offset) {
  223. lastPos = list[i].pos;
  224. i++;
  225. }
  226. if (i === list.length) {
  227. tombstone = Math.floor((offset - lastPos) / this.tombstoneHeight);
  228. }
  229. i += tombstone;
  230. return i;
  231. };
  232. IndexCalculator.prototype.resetState = function () {
  233. this.lastDirection = 1 /* DOWN */;
  234. this.lastPos = 0;
  235. };
  236. return IndexCalculator;
  237. }());
  238. var ListItem = /** @class */ (function () {
  239. function ListItem() {
  240. this.data = null;
  241. this.dom = null;
  242. this.tombstone = null;
  243. this.width = 0;
  244. this.height = 0;
  245. this.pos = 0;
  246. }
  247. return ListItem;
  248. }());
  249. var DataManager = /** @class */ (function () {
  250. function DataManager(list, fetchFn, onFetchFinish) {
  251. this.fetchFn = fetchFn;
  252. this.onFetchFinish = onFetchFinish;
  253. this.loadedNum = 0;
  254. this.fetching = false;
  255. this.hasMore = true;
  256. this.list = list || [];
  257. }
  258. DataManager.prototype.update = function (end) {
  259. return __awaiter(this, void 0, void 0, function () {
  260. var len;
  261. return __generator(this, function (_a) {
  262. if (!this.hasMore) {
  263. end = Math.min(end, this.list.length);
  264. }
  265. // add data placeholder
  266. if (end > this.list.length) {
  267. len = end - this.list.length;
  268. this.addEmptyData(len);
  269. }
  270. // tslint:disable-next-line: no-floating-promises
  271. return [2 /*return*/, this.checkToFetch(end)];
  272. });
  273. });
  274. };
  275. DataManager.prototype.add = function (data) {
  276. for (var i = 0; i < data.length; i++) {
  277. if (!this.list[this.loadedNum]) {
  278. this.list[this.loadedNum] = { data: data[i] };
  279. }
  280. else {
  281. this.list[this.loadedNum] = __assign(__assign({}, this.list[this.loadedNum]), { data: data[i] });
  282. }
  283. this.loadedNum++;
  284. }
  285. return this.list;
  286. };
  287. DataManager.prototype.addEmptyData = function (len) {
  288. for (var i = 0; i < len; i++) {
  289. this.list.push(new ListItem());
  290. }
  291. return this.list;
  292. };
  293. DataManager.prototype.fetch = function (len) {
  294. return __awaiter(this, void 0, void 0, function () {
  295. var data;
  296. return __generator(this, function (_a) {
  297. switch (_a.label) {
  298. case 0:
  299. if (this.fetching) {
  300. return [2 /*return*/, []];
  301. }
  302. this.fetching = true;
  303. return [4 /*yield*/, this.fetchFn(len)];
  304. case 1:
  305. data = _a.sent();
  306. this.fetching = false;
  307. return [2 /*return*/, data];
  308. }
  309. });
  310. });
  311. };
  312. DataManager.prototype.checkToFetch = function (end) {
  313. return __awaiter(this, void 0, void 0, function () {
  314. var min, newData, currentEnd;
  315. return __generator(this, function (_a) {
  316. switch (_a.label) {
  317. case 0:
  318. if (!this.hasMore) {
  319. return [2 /*return*/];
  320. }
  321. if (end <= this.loadedNum) {
  322. return [2 /*return*/];
  323. }
  324. min = end - this.loadedNum;
  325. return [4 /*yield*/, this.fetch(min)];
  326. case 1:
  327. newData = _a.sent();
  328. if (newData instanceof Array && newData.length) {
  329. this.add(newData);
  330. currentEnd = this.onFetchFinish(this.list, true);
  331. return [2 /*return*/, this.checkToFetch(currentEnd)];
  332. }
  333. else if (typeof newData === 'boolean' && newData === false) {
  334. this.hasMore = false;
  335. this.list.splice(this.loadedNum);
  336. this.onFetchFinish(this.list, false);
  337. }
  338. return [2 /*return*/];
  339. }
  340. });
  341. });
  342. };
  343. DataManager.prototype.getList = function () {
  344. return this.list;
  345. };
  346. DataManager.prototype.resetState = function () {
  347. this.loadedNum = 0;
  348. this.fetching = false;
  349. this.hasMore = true;
  350. this.list = [];
  351. };
  352. return DataManager;
  353. }());
  354. var Tombstone = /** @class */ (function () {
  355. function Tombstone(create) {
  356. this.create = create;
  357. this.cached = [];
  358. this.width = 0;
  359. this.height = 0;
  360. this.initialed = false;
  361. this.getSize();
  362. }
  363. Tombstone.isTombstone = function (el) {
  364. if (el && el.classList) {
  365. return el.classList.contains('tombstone');
  366. }
  367. return false;
  368. };
  369. Tombstone.prototype.getSize = function () {
  370. if (!this.initialed) {
  371. var tombstone = this.create();
  372. tombstone.style.position = 'absolute';
  373. document.body.appendChild(tombstone);
  374. tombstone.style.display = '';
  375. this.height = tombstone.offsetHeight;
  376. this.width = tombstone.offsetWidth;
  377. document.body.removeChild(tombstone);
  378. this.cached.push(tombstone);
  379. }
  380. };
  381. Tombstone.prototype.getOne = function () {
  382. var tombstone = this.cached.pop();
  383. if (tombstone) {
  384. var tombstoneStyle = tombstone.style;
  385. tombstoneStyle.display = '';
  386. tombstoneStyle.opacity = '1';
  387. tombstoneStyle[style.transform] = '';
  388. tombstoneStyle[style.transition] = '';
  389. return tombstone;
  390. }
  391. return this.create();
  392. };
  393. Tombstone.prototype.recycle = function (tombstones) {
  394. for (var _i = 0, tombstones_1 = tombstones; _i < tombstones_1.length; _i++) {
  395. var tombstone = tombstones_1[_i];
  396. tombstone.style.display = 'none';
  397. this.cached.push(tombstone);
  398. }
  399. return this.cached;
  400. };
  401. Tombstone.prototype.recycleOne = function (tombstone) {
  402. this.cached.push(tombstone);
  403. return this.cached;
  404. };
  405. return Tombstone;
  406. }());
  407. var ANIMATION_DURATION_MS = 200;
  408. var DomManager = /** @class */ (function () {
  409. function DomManager(content, renderFn, tombstone) {
  410. this.renderFn = renderFn;
  411. this.tombstone = tombstone;
  412. this.unusedDom = [];
  413. this.timers = [];
  414. this.setContent(content);
  415. }
  416. DomManager.prototype.update = function (list, start, end) {
  417. if (start >= list.length) {
  418. start = list.length - 1;
  419. }
  420. if (end > list.length) {
  421. end = list.length;
  422. }
  423. this.collectUnusedDom(list, start, end);
  424. this.createDom(list, start, end);
  425. this.cacheHeight(list, start, end);
  426. var _a = this.positionDom(list, start, end), startPos = _a.startPos, startDelta = _a.startDelta, endPos = _a.endPos;
  427. return {
  428. start: start,
  429. startPos: startPos,
  430. startDelta: startDelta,
  431. end: end,
  432. endPos: endPos,
  433. };
  434. };
  435. DomManager.prototype.collectUnusedDom = function (list, start, end) {
  436. // TODO optimise
  437. for (var i = 0; i < list.length; i++) {
  438. if (i === start) {
  439. i = end - 1;
  440. continue;
  441. }
  442. if (list[i].dom) {
  443. var dom = list[i].dom;
  444. if (Tombstone.isTombstone(dom)) {
  445. this.tombstone.recycleOne(dom);
  446. dom.style.display = 'none';
  447. }
  448. else {
  449. this.unusedDom.push(dom);
  450. }
  451. list[i].dom = null;
  452. }
  453. }
  454. return list;
  455. };
  456. DomManager.prototype.createDom = function (list, start, end) {
  457. for (var i = start; i < end; i++) {
  458. var dom = list[i].dom;
  459. var data = list[i].data;
  460. if (dom) {
  461. if (Tombstone.isTombstone(dom) && data) {
  462. list[i].tombstone = dom;
  463. list[i].dom = null;
  464. }
  465. else {
  466. continue;
  467. }
  468. }
  469. dom = data
  470. ? this.renderFn(data, this.unusedDom.pop())
  471. : this.tombstone.getOne();
  472. dom.style.position = 'absolute';
  473. list[i].dom = dom;
  474. list[i].pos = -1;
  475. this.content.appendChild(dom);
  476. }
  477. };
  478. DomManager.prototype.cacheHeight = function (list, start, end) {
  479. for (var i = start; i < end; i++) {
  480. if (list[i].data && !list[i].height) {
  481. list[i].height = list[i].dom.offsetHeight;
  482. }
  483. }
  484. };
  485. DomManager.prototype.positionDom = function (list, start, end) {
  486. var _this = this;
  487. var tombstoneEles = [];
  488. var _a = this.getStartPos(list, start, end), startPos = _a.start, startDelta = _a.delta;
  489. var pos = startPos;
  490. for (var i = start; i < end; i++) {
  491. var tombstone = list[i].tombstone;
  492. if (tombstone) {
  493. var tombstoneStyle = tombstone.style;
  494. tombstoneStyle[style.transition] = cssVendor + "transform " + ANIMATION_DURATION_MS + "ms, opacity " + ANIMATION_DURATION_MS + "ms";
  495. tombstoneStyle[style.transform] = "translateY(" + pos + "px)";
  496. tombstoneStyle.opacity = '0';
  497. list[i].tombstone = null;
  498. tombstoneEles.push(tombstone);
  499. }
  500. if (list[i].dom && list[i].pos !== pos) {
  501. list[i].dom.style[style.transform] = "translateY(" + pos + "px)";
  502. list[i].pos = pos;
  503. }
  504. pos += list[i].height || this.tombstone.height;
  505. }
  506. var timerId = window.setTimeout(function () {
  507. _this.tombstone.recycle(tombstoneEles);
  508. }, ANIMATION_DURATION_MS);
  509. this.timers.push(timerId);
  510. return {
  511. startPos: startPos,
  512. startDelta: startDelta,
  513. endPos: pos,
  514. };
  515. };
  516. DomManager.prototype.getStartPos = function (list, start, end) {
  517. if (list[start] && list[start].pos !== -1) {
  518. return {
  519. start: list[start].pos,
  520. delta: 0,
  521. };
  522. }
  523. // TODO optimise
  524. var pos = list[0].pos === -1 ? 0 : list[0].pos;
  525. for (var i_1 = 0; i_1 < start; i_1++) {
  526. pos += list[i_1].height || this.tombstone.height;
  527. }
  528. var originPos = pos;
  529. var i;
  530. for (i = start; i < end; i++) {
  531. if (!Tombstone.isTombstone(list[i].dom) && list[i].pos !== -1) {
  532. pos = list[i].pos;
  533. break;
  534. }
  535. }
  536. var x = i;
  537. if (x < end) {
  538. while (x > start) {
  539. pos -= list[x - 1].height;
  540. x--;
  541. }
  542. }
  543. var delta = originPos - pos;
  544. return {
  545. start: pos,
  546. delta: delta,
  547. };
  548. };
  549. DomManager.prototype.removeTombstone = function () {
  550. var tombstones = this.content.querySelectorAll('.tombstone');
  551. for (var i = tombstones.length - 1; i >= 0; i--) {
  552. this.content.removeChild(tombstones[i]);
  553. }
  554. };
  555. DomManager.prototype.setContent = function (content) {
  556. if (content !== this.content) {
  557. this.content = content;
  558. }
  559. };
  560. DomManager.prototype.destroy = function () {
  561. this.removeTombstone();
  562. this.timers.forEach(function (id) {
  563. clearTimeout(id);
  564. });
  565. };
  566. DomManager.prototype.resetState = function () {
  567. this.destroy();
  568. this.timers = [];
  569. this.unusedDom = [];
  570. };
  571. return DomManager;
  572. }());
  573. var EXTRA_SCROLL_Y = -2000;
  574. var InfinityScroll = /** @class */ (function () {
  575. function InfinityScroll(scroll) {
  576. this.scroll = scroll;
  577. this.start = 0;
  578. this.end = 0;
  579. this.init();
  580. }
  581. InfinityScroll.prototype.init = function () {
  582. var _this = this;
  583. this.handleOptions();
  584. var _a = this.options, fetchFn = _a.fetch, renderFn = _a.render, createTombstoneFn = _a.createTombstone;
  585. this.tombstone = new Tombstone(createTombstoneFn);
  586. this.indexCalculator = new IndexCalculator(this.scroll.scroller.scrollBehaviorY.wrapperSize, this.tombstone.height);
  587. this.domManager = new DomManager(this.scroll.scroller.content, renderFn, this.tombstone);
  588. this.dataManager = new DataManager([], fetchFn, this.onFetchFinish.bind(this));
  589. this.scroll.on(this.scroll.eventTypes.destroy, this.destroy, this);
  590. this.scroll.on(this.scroll.eventTypes.scroll, this.update, this);
  591. this.scroll.on(this.scroll.eventTypes.contentChanged, function (content) {
  592. _this.domManager.setContent(content);
  593. _this.indexCalculator.resetState();
  594. _this.domManager.resetState();
  595. _this.dataManager.resetState();
  596. _this.update({ y: 0 });
  597. });
  598. var scrollBehaviorY = this.scroll.scroller.scrollBehaviorY;
  599. scrollBehaviorY.hooks.on(scrollBehaviorY.hooks.eventTypes.computeBoundary, this.modifyBoundary, this);
  600. this.update({ y: 0 });
  601. };
  602. InfinityScroll.prototype.modifyBoundary = function (boundary) {
  603. // manually set position to allow scroll
  604. boundary.maxScrollPos = EXTRA_SCROLL_Y;
  605. };
  606. InfinityScroll.prototype.handleOptions = function () {
  607. // narrow down type to an object
  608. var infinityOptions = this.scroll.options.infinity;
  609. if (infinityOptions) {
  610. if (typeof infinityOptions.fetch !== 'function') {
  611. warn('Infinity plugin need fetch Function to new data.');
  612. }
  613. if (typeof infinityOptions.render !== 'function') {
  614. warn('Infinity plugin need render Function to render each item.');
  615. }
  616. if (typeof infinityOptions.render !== 'function') {
  617. warn('Infinity plugin need createTombstone Function to create tombstone.');
  618. }
  619. this.options = infinityOptions;
  620. }
  621. this.scroll.options.probeType = 3 /* Realtime */;
  622. };
  623. InfinityScroll.prototype.update = function (pos) {
  624. var position = Math.round(-pos.y);
  625. // important! calculate start/end index to render
  626. var _a = this.indexCalculator.calculate(position, this.dataManager.getList()), start = _a.start, end = _a.end;
  627. this.start = start;
  628. this.end = end;
  629. // tslint:disable-next-line: no-floating-promises
  630. this.dataManager.update(end);
  631. this.updateDom(this.dataManager.getList());
  632. };
  633. InfinityScroll.prototype.onFetchFinish = function (list, hasMore) {
  634. var end = this.updateDom(list).end;
  635. if (!hasMore) {
  636. this.domManager.removeTombstone();
  637. this.scroll.scroller.animater.stop();
  638. this.scroll.resetPosition();
  639. }
  640. // tslint:disable-next-line: no-floating-promises
  641. return end;
  642. };
  643. InfinityScroll.prototype.updateDom = function (list) {
  644. var _a = this.domManager.update(list, this.start, this.end), end = _a.end, startPos = _a.startPos, endPos = _a.endPos, startDelta = _a.startDelta;
  645. if (startDelta) {
  646. this.scroll.minScrollY = startDelta;
  647. }
  648. if (endPos > this.scroll.maxScrollY) {
  649. this.scroll.maxScrollY = -(endPos - this.scroll.scroller.scrollBehaviorY.wrapperSize);
  650. }
  651. return {
  652. end: end,
  653. startPos: startPos,
  654. endPos: endPos,
  655. };
  656. };
  657. InfinityScroll.prototype.destroy = function () {
  658. var _a = this.scroll.scroller, content = _a.content, scrollBehaviorY = _a.scrollBehaviorY;
  659. while (content.firstChild) {
  660. content.removeChild(content.firstChild);
  661. }
  662. this.domManager.destroy();
  663. this.scroll.off('scroll', this.update);
  664. this.scroll.off('destroy', this.destroy);
  665. scrollBehaviorY.hooks.off(scrollBehaviorY.hooks.eventTypes.computeBoundary);
  666. };
  667. InfinityScroll.pluginName = 'infinity';
  668. return InfinityScroll;
  669. }());
  670. export default InfinityScroll;