shared-utils.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. /*!
  2. * better-scroll / shared-utils
  3. * (c) 2016-2021 ustbhuangyi
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  8. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  9. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SharedUtils = {}));
  10. }(this, (function (exports) { 'use strict';
  11. function warn(msg) {
  12. console.error("[BScroll warn]: " + msg);
  13. }
  14. function assert(condition, msg) {
  15. if (!condition) {
  16. throw new Error('[BScroll] ' + msg);
  17. }
  18. }
  19. /*! *****************************************************************************
  20. Copyright (c) Microsoft Corporation.
  21. Permission to use, copy, modify, and/or distribute this software for any
  22. purpose with or without fee is hereby granted.
  23. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  24. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  25. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  26. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  27. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  28. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  29. PERFORMANCE OF THIS SOFTWARE.
  30. ***************************************************************************** */
  31. var __assign = function() {
  32. __assign = Object.assign || function __assign(t) {
  33. for (var s, i = 1, n = arguments.length; i < n; i++) {
  34. s = arguments[i];
  35. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  36. }
  37. return t;
  38. };
  39. return __assign.apply(this, arguments);
  40. };
  41. function __spreadArrays() {
  42. for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  43. for (var r = Array(s), k = 0, i = 0; i < il; i++)
  44. for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
  45. r[k] = a[j];
  46. return r;
  47. }
  48. // ssr support
  49. var inBrowser = typeof window !== 'undefined';
  50. var ua = inBrowser && navigator.userAgent.toLowerCase();
  51. var isWeChatDevTools = !!(ua && /wechatdevtools/.test(ua));
  52. var isAndroid = ua && ua.indexOf('android') > 0;
  53. /* istanbul ignore next */
  54. var isIOSBadVersion = (function () {
  55. if (typeof ua === 'string') {
  56. var regex = /os (\d\d?_\d(_\d)?)/;
  57. var matches = regex.exec(ua);
  58. if (!matches)
  59. return false;
  60. var parts = matches[1].split('_').map(function (item) {
  61. return parseInt(item, 10);
  62. });
  63. // ios version >= 13.4 issue 982
  64. return !!(parts[0] === 13 && parts[1] >= 4);
  65. }
  66. return false;
  67. })();
  68. /* istanbul ignore next */
  69. exports.supportsPassive = false;
  70. /* istanbul ignore next */
  71. if (inBrowser) {
  72. var EventName = 'test-passive';
  73. try {
  74. var opts = {};
  75. Object.defineProperty(opts, 'passive', {
  76. get: function () {
  77. exports.supportsPassive = true;
  78. },
  79. }); // https://github.com/facebook/flow/issues/285
  80. window.addEventListener(EventName, function () { }, opts);
  81. }
  82. catch (e) { }
  83. }
  84. function getNow() {
  85. return window.performance &&
  86. window.performance.now &&
  87. window.performance.timing
  88. ? window.performance.now() + window.performance.timing.navigationStart
  89. : +new Date();
  90. }
  91. var extend = function (target, source) {
  92. for (var key in source) {
  93. target[key] = source[key];
  94. }
  95. return target;
  96. };
  97. function isUndef(v) {
  98. return v === undefined || v === null;
  99. }
  100. function getDistance(x, y) {
  101. return Math.sqrt(x * x + y * y);
  102. }
  103. function between(x, min, max) {
  104. if (x < min) {
  105. return min;
  106. }
  107. if (x > max) {
  108. return max;
  109. }
  110. return x;
  111. }
  112. function findIndex(ary, fn) {
  113. if (ary.findIndex) {
  114. return ary.findIndex(fn);
  115. }
  116. var index = -1;
  117. ary.some(function (item, i, ary) {
  118. var ret = fn(item, i, ary);
  119. if (ret) {
  120. index = i;
  121. return ret;
  122. }
  123. });
  124. return index;
  125. }
  126. var elementStyle = (inBrowser &&
  127. document.createElement('div').style);
  128. var vendor = (function () {
  129. /* istanbul ignore if */
  130. if (!inBrowser) {
  131. return false;
  132. }
  133. var transformNames = [
  134. {
  135. key: 'standard',
  136. value: 'transform',
  137. },
  138. {
  139. key: 'webkit',
  140. value: 'webkitTransform',
  141. },
  142. {
  143. key: 'Moz',
  144. value: 'MozTransform',
  145. },
  146. {
  147. key: 'O',
  148. value: 'OTransform',
  149. },
  150. {
  151. key: 'ms',
  152. value: 'msTransform',
  153. },
  154. ];
  155. for (var _i = 0, transformNames_1 = transformNames; _i < transformNames_1.length; _i++) {
  156. var obj = transformNames_1[_i];
  157. if (elementStyle[obj.value] !== undefined) {
  158. return obj.key;
  159. }
  160. }
  161. /* istanbul ignore next */
  162. return false;
  163. })();
  164. /* istanbul ignore next */
  165. function prefixStyle(style) {
  166. if (vendor === false) {
  167. return style;
  168. }
  169. if (vendor === 'standard') {
  170. if (style === 'transitionEnd') {
  171. return 'transitionend';
  172. }
  173. return style;
  174. }
  175. return vendor + style.charAt(0).toUpperCase() + style.substr(1);
  176. }
  177. function getElement(el) {
  178. return (typeof el === 'string'
  179. ? document.querySelector(el)
  180. : el);
  181. }
  182. function addEvent(el, type, fn, capture) {
  183. var useCapture = exports.supportsPassive
  184. ? {
  185. passive: false,
  186. capture: !!capture,
  187. }
  188. : !!capture;
  189. el.addEventListener(type, fn, useCapture);
  190. }
  191. function removeEvent(el, type, fn, capture) {
  192. el.removeEventListener(type, fn, {
  193. capture: !!capture,
  194. });
  195. }
  196. function offset(el) {
  197. var left = 0;
  198. var top = 0;
  199. while (el) {
  200. left -= el.offsetLeft;
  201. top -= el.offsetTop;
  202. el = el.offsetParent;
  203. }
  204. return {
  205. left: left,
  206. top: top,
  207. };
  208. }
  209. function offsetToBody(el) {
  210. var rect = el.getBoundingClientRect();
  211. return {
  212. left: -(rect.left + window.pageXOffset),
  213. top: -(rect.top + window.pageYOffset),
  214. };
  215. }
  216. var cssVendor = vendor && vendor !== 'standard' ? '-' + vendor.toLowerCase() + '-' : '';
  217. var transform = prefixStyle('transform');
  218. var transition = prefixStyle('transition');
  219. var hasPerspective = inBrowser && prefixStyle('perspective') in elementStyle;
  220. // fix issue #361
  221. var hasTouch = inBrowser && ('ontouchstart' in window || isWeChatDevTools);
  222. var hasTransition = inBrowser && transition in elementStyle;
  223. var style = {
  224. transform: transform,
  225. transition: transition,
  226. transitionTimingFunction: prefixStyle('transitionTimingFunction'),
  227. transitionDuration: prefixStyle('transitionDuration'),
  228. transitionDelay: prefixStyle('transitionDelay'),
  229. transformOrigin: prefixStyle('transformOrigin'),
  230. transitionEnd: prefixStyle('transitionEnd'),
  231. transitionProperty: prefixStyle('transitionProperty'),
  232. };
  233. var eventTypeMap = {
  234. touchstart: 1,
  235. touchmove: 1,
  236. touchend: 1,
  237. touchcancel: 1,
  238. mousedown: 2,
  239. mousemove: 2,
  240. mouseup: 2,
  241. };
  242. function getRect(el) {
  243. /* istanbul ignore if */
  244. if (el instanceof window.SVGElement) {
  245. var rect = el.getBoundingClientRect();
  246. return {
  247. top: rect.top,
  248. left: rect.left,
  249. width: rect.width,
  250. height: rect.height,
  251. };
  252. }
  253. else {
  254. return {
  255. top: el.offsetTop,
  256. left: el.offsetLeft,
  257. width: el.offsetWidth,
  258. height: el.offsetHeight,
  259. };
  260. }
  261. }
  262. function preventDefaultExceptionFn(el, exceptions) {
  263. for (var i in exceptions) {
  264. if (exceptions[i].test(el[i])) {
  265. return true;
  266. }
  267. }
  268. return false;
  269. }
  270. var tagExceptionFn = preventDefaultExceptionFn;
  271. function tap(e, eventName) {
  272. var ev = document.createEvent('Event');
  273. ev.initEvent(eventName, true, true);
  274. ev.pageX = e.pageX;
  275. ev.pageY = e.pageY;
  276. e.target.dispatchEvent(ev);
  277. }
  278. function click(e, event) {
  279. if (event === void 0) { event = 'click'; }
  280. var eventSource;
  281. if (e.type === 'mouseup') {
  282. eventSource = e;
  283. }
  284. else if (e.type === 'touchend' || e.type === 'touchcancel') {
  285. eventSource = e.changedTouches[0];
  286. }
  287. var posSrc = {};
  288. if (eventSource) {
  289. posSrc.screenX = eventSource.screenX || 0;
  290. posSrc.screenY = eventSource.screenY || 0;
  291. posSrc.clientX = eventSource.clientX || 0;
  292. posSrc.clientY = eventSource.clientY || 0;
  293. }
  294. var ev;
  295. var bubbles = true;
  296. var cancelable = true;
  297. var ctrlKey = e.ctrlKey, shiftKey = e.shiftKey, altKey = e.altKey, metaKey = e.metaKey;
  298. var pressedKeysMap = {
  299. ctrlKey: ctrlKey,
  300. shiftKey: shiftKey,
  301. altKey: altKey,
  302. metaKey: metaKey,
  303. };
  304. if (typeof MouseEvent !== 'undefined') {
  305. try {
  306. ev = new MouseEvent(event, extend(__assign({ bubbles: bubbles,
  307. cancelable: cancelable }, pressedKeysMap), posSrc));
  308. }
  309. catch (e) {
  310. /* istanbul ignore next */
  311. createEvent();
  312. }
  313. }
  314. else {
  315. createEvent();
  316. }
  317. function createEvent() {
  318. ev = document.createEvent('Event');
  319. ev.initEvent(event, bubbles, cancelable);
  320. extend(ev, posSrc);
  321. }
  322. // forwardedTouchEvent set to true in case of the conflict with fastclick
  323. ev.forwardedTouchEvent = true;
  324. ev._constructed = true;
  325. e.target.dispatchEvent(ev);
  326. }
  327. function dblclick(e) {
  328. click(e, 'dblclick');
  329. }
  330. function prepend(el, target) {
  331. var firstChild = target.firstChild;
  332. if (firstChild) {
  333. before(el, firstChild);
  334. }
  335. else {
  336. target.appendChild(el);
  337. }
  338. }
  339. function before(el, target) {
  340. var parentNode = target.parentNode;
  341. parentNode.insertBefore(el, target);
  342. }
  343. function removeChild(el, child) {
  344. el.removeChild(child);
  345. }
  346. function hasClass(el, className) {
  347. var reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
  348. return reg.test(el.className);
  349. }
  350. function addClass(el, className) {
  351. if (hasClass(el, className)) {
  352. return;
  353. }
  354. var newClass = el.className.split(' ');
  355. newClass.push(className);
  356. el.className = newClass.join(' ');
  357. }
  358. function removeClass(el, className) {
  359. if (!hasClass(el, className)) {
  360. return;
  361. }
  362. var reg = new RegExp('(^|\\s)' + className + '(\\s|$)', 'g');
  363. el.className = el.className.replace(reg, ' ');
  364. }
  365. function HTMLCollectionToArray(el) {
  366. return Array.prototype.slice.call(el, 0);
  367. }
  368. function getClientSize(el) {
  369. return {
  370. width: el.clientWidth,
  371. height: el.clientHeight,
  372. };
  373. }
  374. var ease = {
  375. // easeOutQuint
  376. swipe: {
  377. style: 'cubic-bezier(0.23, 1, 0.32, 1)',
  378. fn: function (t) {
  379. return 1 + --t * t * t * t * t;
  380. }
  381. },
  382. // easeOutQuard
  383. swipeBounce: {
  384. style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
  385. fn: function (t) {
  386. return t * (2 - t);
  387. }
  388. },
  389. // easeOutQuart
  390. bounce: {
  391. style: 'cubic-bezier(0.165, 0.84, 0.44, 1)',
  392. fn: function (t) {
  393. return 1 - --t * t * t * t;
  394. }
  395. }
  396. };
  397. var DEFAULT_INTERVAL = 1000 / 60;
  398. var windowCompat = inBrowser && window;
  399. /* istanbul ignore next */
  400. function noop$1() { }
  401. var requestAnimationFrame = (function () {
  402. /* istanbul ignore if */
  403. if (!inBrowser) {
  404. return noop$1;
  405. }
  406. return (windowCompat.requestAnimationFrame ||
  407. windowCompat.webkitRequestAnimationFrame ||
  408. windowCompat.mozRequestAnimationFrame ||
  409. windowCompat.oRequestAnimationFrame ||
  410. // if all else fails, use setTimeout
  411. function (callback) {
  412. return window.setTimeout(callback, callback.interval || DEFAULT_INTERVAL); // make interval as precise as possible.
  413. });
  414. })();
  415. var cancelAnimationFrame = (function () {
  416. /* istanbul ignore if */
  417. if (!inBrowser) {
  418. return noop$1;
  419. }
  420. return (windowCompat.cancelAnimationFrame ||
  421. windowCompat.webkitCancelAnimationFrame ||
  422. windowCompat.mozCancelAnimationFrame ||
  423. windowCompat.oCancelAnimationFrame ||
  424. function (id) {
  425. window.clearTimeout(id);
  426. });
  427. })();
  428. /* istanbul ignore next */
  429. var noop = function (val) { };
  430. var sharedPropertyDefinition = {
  431. enumerable: true,
  432. configurable: true,
  433. get: noop,
  434. set: noop,
  435. };
  436. var getProperty = function (obj, key) {
  437. var keys = key.split('.');
  438. for (var i = 0; i < keys.length - 1; i++) {
  439. obj = obj[keys[i]];
  440. if (typeof obj !== 'object' || !obj)
  441. return;
  442. }
  443. var lastKey = keys.pop();
  444. if (typeof obj[lastKey] === 'function') {
  445. return function () {
  446. return obj[lastKey].apply(obj, arguments);
  447. };
  448. }
  449. else {
  450. return obj[lastKey];
  451. }
  452. };
  453. var setProperty = function (obj, key, value) {
  454. var keys = key.split('.');
  455. var temp;
  456. for (var i = 0; i < keys.length - 1; i++) {
  457. temp = keys[i];
  458. if (!obj[temp])
  459. obj[temp] = {};
  460. obj = obj[temp];
  461. }
  462. obj[keys.pop()] = value;
  463. };
  464. function propertiesProxy(target, sourceKey, key) {
  465. sharedPropertyDefinition.get = function proxyGetter() {
  466. return getProperty(this, sourceKey);
  467. };
  468. sharedPropertyDefinition.set = function proxySetter(val) {
  469. setProperty(this, sourceKey, val);
  470. };
  471. Object.defineProperty(target, key, sharedPropertyDefinition);
  472. }
  473. var EventEmitter = /** @class */ (function () {
  474. function EventEmitter(names) {
  475. this.events = {};
  476. this.eventTypes = {};
  477. this.registerType(names);
  478. }
  479. EventEmitter.prototype.on = function (type, fn, context) {
  480. if (context === void 0) { context = this; }
  481. this.hasType(type);
  482. if (!this.events[type]) {
  483. this.events[type] = [];
  484. }
  485. this.events[type].push([fn, context]);
  486. return this;
  487. };
  488. EventEmitter.prototype.once = function (type, fn, context) {
  489. var _this = this;
  490. if (context === void 0) { context = this; }
  491. this.hasType(type);
  492. var magic = function () {
  493. var args = [];
  494. for (var _i = 0; _i < arguments.length; _i++) {
  495. args[_i] = arguments[_i];
  496. }
  497. _this.off(type, magic);
  498. var ret = fn.apply(context, args);
  499. if (ret === true) {
  500. return ret;
  501. }
  502. };
  503. magic.fn = fn;
  504. this.on(type, magic);
  505. return this;
  506. };
  507. EventEmitter.prototype.off = function (type, fn) {
  508. if (!type && !fn) {
  509. this.events = {};
  510. return this;
  511. }
  512. if (type) {
  513. this.hasType(type);
  514. if (!fn) {
  515. this.events[type] = [];
  516. return this;
  517. }
  518. var events = this.events[type];
  519. if (!events) {
  520. return this;
  521. }
  522. var count = events.length;
  523. while (count--) {
  524. if (events[count][0] === fn ||
  525. (events[count][0] && events[count][0].fn === fn)) {
  526. events.splice(count, 1);
  527. }
  528. }
  529. return this;
  530. }
  531. };
  532. EventEmitter.prototype.trigger = function (type) {
  533. var args = [];
  534. for (var _i = 1; _i < arguments.length; _i++) {
  535. args[_i - 1] = arguments[_i];
  536. }
  537. this.hasType(type);
  538. var events = this.events[type];
  539. if (!events) {
  540. return;
  541. }
  542. var len = events.length;
  543. var eventsCopy = __spreadArrays(events);
  544. var ret;
  545. for (var i = 0; i < len; i++) {
  546. var event_1 = eventsCopy[i];
  547. var fn = event_1[0], context = event_1[1];
  548. if (fn) {
  549. ret = fn.apply(context, args);
  550. if (ret === true) {
  551. return ret;
  552. }
  553. }
  554. }
  555. };
  556. EventEmitter.prototype.registerType = function (names) {
  557. var _this = this;
  558. names.forEach(function (type) {
  559. _this.eventTypes[type] = type;
  560. });
  561. };
  562. EventEmitter.prototype.destroy = function () {
  563. this.events = {};
  564. this.eventTypes = {};
  565. };
  566. EventEmitter.prototype.hasType = function (type) {
  567. var types = this.eventTypes;
  568. var isType = types[type] === type;
  569. if (!isType) {
  570. warn("EventEmitter has used unknown event type: \"" + type + "\", should be oneof [" +
  571. ("" + Object.keys(types).map(function (_) { return JSON.stringify(_); })) +
  572. "]");
  573. }
  574. };
  575. return EventEmitter;
  576. }());
  577. var EventRegister = /** @class */ (function () {
  578. function EventRegister(wrapper, events) {
  579. this.wrapper = wrapper;
  580. this.events = events;
  581. this.addDOMEvents();
  582. }
  583. EventRegister.prototype.destroy = function () {
  584. this.removeDOMEvents();
  585. this.events = [];
  586. };
  587. EventRegister.prototype.addDOMEvents = function () {
  588. this.handleDOMEvents(addEvent);
  589. };
  590. EventRegister.prototype.removeDOMEvents = function () {
  591. this.handleDOMEvents(removeEvent);
  592. };
  593. EventRegister.prototype.handleDOMEvents = function (eventOperation) {
  594. var _this = this;
  595. var wrapper = this.wrapper;
  596. this.events.forEach(function (event) {
  597. eventOperation(wrapper, event.name, _this, !!event.capture);
  598. });
  599. };
  600. EventRegister.prototype.handleEvent = function (e) {
  601. var eventType = e.type;
  602. this.events.some(function (event) {
  603. if (event.name === eventType) {
  604. event.handler(e);
  605. return true;
  606. }
  607. return false;
  608. });
  609. };
  610. return EventRegister;
  611. }());
  612. exports.EventEmitter = EventEmitter;
  613. exports.EventRegister = EventRegister;
  614. exports.HTMLCollectionToArray = HTMLCollectionToArray;
  615. exports.addClass = addClass;
  616. exports.addEvent = addEvent;
  617. exports.assert = assert;
  618. exports.before = before;
  619. exports.between = between;
  620. exports.cancelAnimationFrame = cancelAnimationFrame;
  621. exports.click = click;
  622. exports.cssVendor = cssVendor;
  623. exports.dblclick = dblclick;
  624. exports.ease = ease;
  625. exports.eventTypeMap = eventTypeMap;
  626. exports.extend = extend;
  627. exports.findIndex = findIndex;
  628. exports.getClientSize = getClientSize;
  629. exports.getDistance = getDistance;
  630. exports.getElement = getElement;
  631. exports.getNow = getNow;
  632. exports.getRect = getRect;
  633. exports.hasClass = hasClass;
  634. exports.hasPerspective = hasPerspective;
  635. exports.hasTouch = hasTouch;
  636. exports.hasTransition = hasTransition;
  637. exports.inBrowser = inBrowser;
  638. exports.isAndroid = isAndroid;
  639. exports.isIOSBadVersion = isIOSBadVersion;
  640. exports.isUndef = isUndef;
  641. exports.isWeChatDevTools = isWeChatDevTools;
  642. exports.offset = offset;
  643. exports.offsetToBody = offsetToBody;
  644. exports.prepend = prepend;
  645. exports.preventDefaultExceptionFn = preventDefaultExceptionFn;
  646. exports.propertiesProxy = propertiesProxy;
  647. exports.removeChild = removeChild;
  648. exports.removeClass = removeClass;
  649. exports.removeEvent = removeEvent;
  650. exports.requestAnimationFrame = requestAnimationFrame;
  651. exports.style = style;
  652. exports.tagExceptionFn = tagExceptionFn;
  653. exports.tap = tap;
  654. exports.ua = ua;
  655. exports.warn = warn;
  656. Object.defineProperty(exports, '__esModule', { value: true });
  657. })));