UNPKG

@whitesev/pops

Version:

弹窗库

901 lines (872 loc) 659 kB
define((function () { 'use strict'; const SymbolEvents = Symbol("events_" + (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)); const PopsCoreEnv = { document: document, window: window, globalThis: globalThis, self: self, }; const PopsCore = { get document() { return PopsCoreEnv.document; }, get window() { return PopsCoreEnv.window; }, get globalThis() { return PopsCoreEnv.globalThis; }, get self() { return PopsCoreEnv.self; }, }; const OriginPrototype = { Object: { defineProperty: Object.defineProperty, }, }; const createCache = (lastNumberWeakMap) => { return (collection, nextNumber) => { lastNumberWeakMap.set(collection, nextNumber); return nextNumber; }; }; /* * The value of the constant Number.MAX_SAFE_INTEGER equals (2 ** 53 - 1) but it * is fairly new. */ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER === undefined ? 9007199254740991 : Number.MAX_SAFE_INTEGER; const TWO_TO_THE_POWER_OF_TWENTY_NINE = 536870912; const TWO_TO_THE_POWER_OF_THIRTY = TWO_TO_THE_POWER_OF_TWENTY_NINE * 2; const createGenerateUniqueNumber = (cache, lastNumberWeakMap) => { return (collection) => { const lastNumber = lastNumberWeakMap.get(collection); /* * Let's try the cheapest algorithm first. It might fail to produce a new * number, but it is so cheap that it is okay to take the risk. Just * increase the last number by one or reset it to 0 if we reached the upper * bound of SMIs (which stands for small integers). When the last number is * unknown it is assumed that the collection contains zero based consecutive * numbers. */ let nextNumber = lastNumber === undefined ? collection.size : lastNumber < TWO_TO_THE_POWER_OF_THIRTY ? lastNumber + 1 : 0; if (!collection.has(nextNumber)) { return cache(collection, nextNumber); } /* * If there are less than half of 2 ** 30 numbers stored in the collection, * the chance to generate a new random number in the range from 0 to 2 ** 30 * is at least 50%. It's benifitial to use only SMIs because they perform * much better in any environment based on V8. */ if (collection.size < TWO_TO_THE_POWER_OF_TWENTY_NINE) { while (collection.has(nextNumber)) { nextNumber = Math.floor(Math.random() * TWO_TO_THE_POWER_OF_THIRTY); } return cache(collection, nextNumber); } // Quickly check if there is a theoretical chance to generate a new number. if (collection.size > MAX_SAFE_INTEGER) { throw new Error('Congratulations, you created a collection of unique numbers which uses all available integers!'); } // Otherwise use the full scale of safely usable integers. while (collection.has(nextNumber)) { nextNumber = Math.floor(Math.random() * MAX_SAFE_INTEGER); } return cache(collection, nextNumber); }; }; const LAST_NUMBER_WEAK_MAP = new WeakMap(); const cache = createCache(LAST_NUMBER_WEAK_MAP); const generateUniqueNumber = createGenerateUniqueNumber(cache, LAST_NUMBER_WEAK_MAP); const isMessagePort = (sender) => { return typeof sender.start === 'function'; }; const PORT_MAP = new WeakMap(); const extendBrokerImplementation = (partialBrokerImplementation) => ({ ...partialBrokerImplementation, connect: ({ call }) => { return async () => { const { port1, port2 } = new MessageChannel(); const portId = await call('connect', { port: port1 }, [port1]); PORT_MAP.set(port2, portId); return port2; }; }, disconnect: ({ call }) => { return async (port) => { const portId = PORT_MAP.get(port); if (portId === undefined) { throw new Error('The given port is not connected.'); } await call('disconnect', { portId }); }; }, isSupported: ({ call }) => { return () => call('isSupported'); } }); const ONGOING_REQUESTS = new WeakMap(); const createOrGetOngoingRequests = (sender) => { if (ONGOING_REQUESTS.has(sender)) { // @todo TypeScript needs to be convinced that has() works as expected. return ONGOING_REQUESTS.get(sender); } const ongoingRequests = new Map(); ONGOING_REQUESTS.set(sender, ongoingRequests); return ongoingRequests; }; const createBroker = (brokerImplementation) => { const fullBrokerImplementation = extendBrokerImplementation(brokerImplementation); return (sender) => { const ongoingRequests = createOrGetOngoingRequests(sender); sender.addEventListener('message', (({ data: message }) => { const { id } = message; if (id !== null && ongoingRequests.has(id)) { const { reject, resolve } = ongoingRequests.get(id); ongoingRequests.delete(id); if (message.error === undefined) { resolve(message.result); } else { reject(new Error(message.error.message)); } } })); if (isMessagePort(sender)) { sender.start(); } const call = (method, params = null, transferables = []) => { return new Promise((resolve, reject) => { const id = generateUniqueNumber(ongoingRequests); ongoingRequests.set(id, { reject, resolve }); if (params === null) { sender.postMessage({ id, method }, transferables); } else { sender.postMessage({ id, method, params }, transferables); } }); }; const notify = (method, params, transferables = []) => { sender.postMessage({ id: null, method, params }, transferables); }; let functions = {}; for (const [key, handler] of Object.entries(fullBrokerImplementation)) { functions = { ...functions, [key]: handler({ call, notify }) }; } return { ...functions }; }; }; // Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. const scheduledIntervalsState = new Map([[0, null]]); // tslint:disable-line no-empty const scheduledTimeoutsState = new Map([[0, null]]); // tslint:disable-line no-empty const wrap = createBroker({ clearInterval: ({ call }) => { return (timerId) => { if (typeof scheduledIntervalsState.get(timerId) === 'symbol') { scheduledIntervalsState.set(timerId, null); call('clear', { timerId, timerType: 'interval' }).then(() => { scheduledIntervalsState.delete(timerId); }); } }; }, clearTimeout: ({ call }) => { return (timerId) => { if (typeof scheduledTimeoutsState.get(timerId) === 'symbol') { scheduledTimeoutsState.set(timerId, null); call('clear', { timerId, timerType: 'timeout' }).then(() => { scheduledTimeoutsState.delete(timerId); }); } }; }, setInterval: ({ call }) => { return (func, delay = 0, ...args) => { const symbol = Symbol(); const timerId = generateUniqueNumber(scheduledIntervalsState); scheduledIntervalsState.set(timerId, symbol); const schedule = () => call('set', { delay, now: performance.timeOrigin + performance.now(), timerId, timerType: 'interval' }).then(() => { const state = scheduledIntervalsState.get(timerId); if (state === undefined) { throw new Error('The timer is in an undefined state.'); } if (state === symbol) { func(...args); // Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). if (scheduledIntervalsState.get(timerId) === symbol) { schedule(); } } }); schedule(); return timerId; }; }, setTimeout: ({ call }) => { return (func, delay = 0, ...args) => { const symbol = Symbol(); const timerId = generateUniqueNumber(scheduledTimeoutsState); scheduledTimeoutsState.set(timerId, symbol); call('set', { delay, now: performance.timeOrigin + performance.now(), timerId, timerType: 'timeout' }).then(() => { const state = scheduledTimeoutsState.get(timerId); if (state === undefined) { throw new Error('The timer is in an undefined state.'); } if (state === symbol) { // A timeout can be savely deleted because it is only called once. scheduledTimeoutsState.delete(timerId); func(...args); } }); return timerId; }; } }); const load = (url) => { const worker = new Worker(url); return wrap(worker); }; const createLoadOrReturnBroker = (loadBroker, worker) => { let broker = null; return () => { if (broker !== null) { return broker; } const blob = new Blob([worker], { type: 'application/javascript; charset=utf-8' }); const url = URL.createObjectURL(blob); broker = loadBroker(url); // Bug #1: Edge up until v18 didn't like the URL to be revoked directly. setTimeout(() => URL.revokeObjectURL(url)); return broker; }; }; // This is the minified and stringified code of the worker-timers-worker package. const worker = `(()=>{var e={455:function(e,t){!function(e){"use strict";var t=function(e){return function(t){var r=e(t);return t.add(r),r}},r=function(e){return function(t,r){return e.set(t,r),r}},n=void 0===Number.MAX_SAFE_INTEGER?9007199254740991:Number.MAX_SAFE_INTEGER,o=536870912,s=2*o,a=function(e,t){return function(r){var a=t.get(r),i=void 0===a?r.size:a<s?a+1:0;if(!r.has(i))return e(r,i);if(r.size<o){for(;r.has(i);)i=Math.floor(Math.random()*s);return e(r,i)}if(r.size>n)throw new Error("Congratulations, you created a collection of unique numbers which uses all available integers!");for(;r.has(i);)i=Math.floor(Math.random()*n);return e(r,i)}},i=new WeakMap,u=r(i),c=a(u,i),d=t(c);e.addUniqueNumber=d,e.generateUniqueNumber=c}(t)}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var s=t[n]={exports:{}};return e[n].call(s.exports,s,s.exports,r),s.exports}(()=>{"use strict";const e=-32603,t=-32602,n=-32601,o=(e,t)=>Object.assign(new Error(e),{status:t}),s=t=>o('The handler of the method called "'.concat(t,'" returned an unexpected result.'),e),a=(t,r)=>async({data:{id:a,method:i,params:u}})=>{const c=r[i];try{if(void 0===c)throw(e=>o('The requested method called "'.concat(e,'" is not supported.'),n))(i);const r=void 0===u?c():c(u);if(void 0===r)throw(t=>o('The handler of the method called "'.concat(t,'" returned no required result.'),e))(i);const d=r instanceof Promise?await r:r;if(null===a){if(void 0!==d.result)throw s(i)}else{if(void 0===d.result)throw s(i);const{result:e,transferables:r=[]}=d;t.postMessage({id:a,result:e},r)}}catch(e){const{message:r,status:n=-32603}=e;t.postMessage({error:{code:n,message:r},id:a})}};var i=r(455);const u=new Map,c=(e,r,n)=>({...r,connect:({port:t})=>{t.start();const n=e(t,r),o=(0,i.generateUniqueNumber)(u);return u.set(o,(()=>{n(),t.close(),u.delete(o)})),{result:o}},disconnect:({portId:e})=>{const r=u.get(e);if(void 0===r)throw(e=>o('The specified parameter called "portId" with the given value "'.concat(e,'" does not identify a port connected to this worker.'),t))(e);return r(),{result:null}},isSupported:async()=>{if(await new Promise((e=>{const t=new ArrayBuffer(0),{port1:r,port2:n}=new MessageChannel;r.onmessage=({data:t})=>e(null!==t),n.postMessage(t,[t])}))){const e=n();return{result:e instanceof Promise?await e:e}}return{result:!1}}}),d=(e,t,r=()=>!0)=>{const n=c(d,t,r),o=a(e,n);return e.addEventListener("message",o),()=>e.removeEventListener("message",o)},l=e=>t=>{const r=e.get(t);if(void 0===r)return Promise.resolve(!1);const[n,o]=r;return clearTimeout(n),e.delete(t),o(!1),Promise.resolve(!0)},f=(e,t,r)=>(n,o,s)=>{const{expected:a,remainingDelay:i}=e(n,o);return new Promise((e=>{t.set(s,[setTimeout(r,i,a,t,e,s),e])}))},m=(e,t)=>{const r=performance.now(),n=e+t-r-performance.timeOrigin;return{expected:r+n,remainingDelay:n}},p=(e,t,r,n)=>{const o=e-performance.now();o>0?t.set(n,[setTimeout(p,o,e,t,r,n),r]):(t.delete(n),r(!0))},h=new Map,v=l(h),w=new Map,g=l(w),M=f(m,h,p),y=f(m,w,p);d(self,{clear:async({timerId:e,timerType:t})=>({result:await("interval"===t?v(e):g(e))}),set:async({delay:e,now:t,timerId:r,timerType:n})=>({result:await("interval"===n?M:y)(e,t,r)})})})()})();`; // tslint:disable-line:max-line-length const loadOrReturnBroker = createLoadOrReturnBroker(load, worker); const clearInterval$1 = (timerId) => loadOrReturnBroker().clearInterval(timerId); const clearTimeout$1 = (timerId) => loadOrReturnBroker().clearTimeout(timerId); const setInterval$1 = (...args) => loadOrReturnBroker().setInterval(...args); const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args); let t$1 = class t{constructor(){this.__map={};}beforeEach(t){this.__interceptor=t;}on(t,i){const s=Array.isArray(t)?t:[t];for(const t of s){this.__map[t]=this.__map[t]||[];const s=this.__map[t];s&&s.push(i);}return this}emit(t,i,s){ void 0!==this.__interceptor?this.__interceptor(t,(()=>{this.__emit(t,i),s&&s();})):(this.__emit(t,i),s&&s());}__emit(t,i){const s=this.__map[t];if(Array.isArray(s)&&(null==s?void 0:s.length))for(const _ of s)_(i,t);this.event=i;}off(t,i){const s=this.__map[t];if(void 0!==s)if(void 0===i)delete this.__map[t];else {const t=s.findIndex((t=>t===i));s.splice(t,1);}}destroy(){this.__map={};}}; const n$1="clientX",e$2="clientY",t=16,c$3="start",o$1="move",s$1="cancel",u$3="end",a$2="left",i$3="right",r$4="up",d$1="down",m$2={4:"start",5:"move",1:"end",3:"cancel"};function v$1(n){return m$2[n]}function b(n,e,t){const c={1:{0:{move:4},4:{move:5,end:1,cancel:3},5:{move:5,end:1,cancel:3}},0:{4:{move:2,end:1,cancel:3},5:{start:2,move:2,end:1,cancel:3}}}[Number(n)][e];return void 0!==c&&c[t]||0}function g$1(n){[1,3,2].includes(n.state)&&(n.state=0);}function h$3(n){return [5,1,3].includes(n)}function j(n){if(n.disabled)return n.state=0,true}function O(n,e){return Object.assign(Object.assign(Object.assign({},n),e),{state:0,disabled:false})}function p$3(n){return Math.round(100*n)/100} function r$3(){let t,o,i,r,a=0;return function(u){if(t=o,void 0!==u){a=Number.MAX_SAFE_INTEGER>a?++a:1;const h=function(t,o){const{phase:i,points:r,changedPoints:a,nativeEvent:u}=t,h=r.length,p=c$3===i,g=u$3===i&&0===h||s$1===i,l=Date.now(),{x:d,y:m}=c$2(r)||c$2(a),{currentTarget:v}=u;return Object.assign(t,{id:o,x:d,y:m,timestamp:l,isStart:p,isEnd:g,pointLength:h,currentTarget:v,getOffset(t=v){const e=t.getBoundingClientRect();return {x:d-Math.round(e.left),y:m-Math.round(e.top)}}})}(u,a);o=h;const{isStart:p,pointLength:g}=h;return p&&(i=h,t=void 0,r=1<g?h:void 0),Object.assign(Object.assign({},h),{prevInput:t,startMultiInput:r,startInput:i})}}}function c$2(t){const{length:e}=t;if(0<e){if(1===e){const{clientX:e,clientY:n}=t[0];return {x:Math.round(e),y:Math.round(n)}}const n=t.reduce(((t,e)=>(t.x+=e[n$1],t.y+=e[e$2],t)),{x:0,y:0});return {x:Math.round(n.x/e),y:Math.round(n.y/e)}}}function a$1(t,e,n,s){const o={};for(const t in n)["target","currentTarget","type"].includes(t)||(o[t]=n[t]);let i;return document.createEvent?(i=document.createEvent("HTMLEvents"),i.initEvent(t,null==s?void 0:s.bubbles,null==s?void 0:s.cancelable)):i=new Event(t,s),Object.assign(i,o,{match:()=>n.targets&&0<n.targets.length&&n.targets.every((t=>i.currentTarget.contains(t)))}),e.dispatchEvent(i)}function u$2(t,e){const{preventDefault:n}=e;return s=n,"[object Function]"===Object.prototype.toString.call(s)?n(t):!!n;var s;}const h$2=["touchstart","touchmove","touchend","touchcancel","mousedown"],p$2=["mousemove","mouseup"];const g={domEvents:{bubbles:true,cancelable:true},preventDefault:t=>{if(t.target&&"tagName"in t.target){const{tagName:e}=t.target;return !/^(?:INPUT|TEXTAREA|BUTTON|SELECT)$/.test(e)}return false}};let l$1 = class l extends t$1{constructor(t,e){super(),this.v="2.1.3",this.__computeFunctionList=[],this.__computeFunctionCreatorList=[],this.__pluginContexts=[],this.__isIgnoreMouse=false,this.el=t,this.c={},this.__options=Object.assign(Object.assign({},g),e);const n=function(t){const e=r$3();return function(n){const s=[],o=[];Array.from(n.touches).forEach((({clientX:e,clientY:n,target:i})=>{(null==t?void 0:t.contains(i))&&(s.push(i),o.push({clientX:e,clientY:n,target:i}));}));const i=Array.from(n.changedTouches).map((({clientX:t,clientY:e,target:n})=>({clientX:t,clientY:e,target:n})));return e({phase:n.type.replace("touch",""),changedPoints:i,points:o,nativeEvent:n,target:n.target,targets:s})}}(this.el),s=function(){let t,e=false,n=null;const s=r$3();return function(o){const{clientX:i,clientY:r,type:c,button:a,target:u}=o;let h,p=[{clientX:i,clientY:r,target:u}];if("mousedown"===c&&0===a)n=u,e=true,h="start";else {if(!e)return;"mousemove"===c?h="move":"mouseup"===c&&(p=[],h="end",e=false);}const g=t||[{clientX:i,clientY:r,target:u}];if(t=[{clientX:i,clientY:r,target:u}],void 0!==h)return s({phase:h,changedPoints:g,points:p,target:n,targets:[n],nativeEvent:o})}}();if(this.__inputCreatorMap={touchstart:n,touchmove:n,touchend:n,touchcancel:n,mousedown:s,mousemove:s,mouseup:s},this.on("at:after",(t=>{const{target:e,__type:n}=t,{domEvents:s}=this.__options;s&&void 0!==this.el&&e&&(a$1(n,e,t,s),a$1("at:after",e,t,s));})),void 0!==t){t.style.webkitTapHighlightColor="rgba(0,0,0,0)";let e=false;try{const t={};Object.defineProperty(t,"passive",{get(){e=!0;}}),window.addEventListener("_",(()=>{}),t);}catch(t){}this.on("u",function(t,e,n){return h$2.forEach((s=>{t.addEventListener(s,e,n);})),p$2.forEach((t=>{window.addEventListener(t,e,n);})),()=>{h$2.forEach((n=>{t.removeEventListener(n,e);})),p$2.forEach((t=>{window.removeEventListener(t,e);}));}}(t,this.catchEvent.bind(this),false===this.__options.preventDefault&&e?{passive:true}:{passive:false}));}}use(t,e){this.__pluginContexts.push(t(this,e));}catchEvent(t){const e=this.__inputCreatorMap[t.type](t);if(void 0!==e){const n=()=>t.stopPropagation(),s=()=>t.stopImmediatePropagation(),o=()=>t.preventDefault();if(u$2(t,this.__options))o();else if("touchstart"===t.type?this.__isIgnoreMouse=true:"touchmove"===t.type&&(this.__isIgnoreMouse=false),this.__isIgnoreMouse&&t.type.startsWith("mouse"))return void("mouseup"===t.type&&(this.__isIgnoreMouse=false));this.emit("input",e),this.emit2(`at:${e.phase}`,e,{});const i={};this.__computeFunctionList.forEach((t=>{const n=t(e,i);if(void 0!==n)for(const t in n)i[t]=n[t];})),this.emit("computed",Object.assign(Object.assign(Object.assign({},e),i),{stopPropagation:n,stopImmediatePropagation:s,preventDefault:o}));}}compute(t,e){for(const e of t)this.__computeFunctionCreatorList.includes(e)||(this.__computeFunctionCreatorList.push(e),this.__computeFunctionList.push(e()));this.on("computed",e);}beforeEach(t){super.beforeEach(((e,n)=>{var s;(null===(s=this.c)||void 0===s?void 0:s.name)?t(e,n):n();}));}get(t){return this.__pluginContexts.find((e=>t===e.name))}set(t){this.__options=Object.assign(Object.assign({},this.__options),t);}emit2(t,e,n){this.c=n,this.emit(t,Object.assign(Object.assign({},e),{type:t}),(()=>{this.emit("at:after",Object.assign(Object.assign({},e),{name:t,__type:t}));}));}destroy(){this.emit("u"),super.destroy();}}; var x=r=>Math.sqrt(r.x*r.x+r.y*r.y),y=(r,a)=>r.x*a.x+r.y*a.y,e$1=(r,a)=>{var t=x(r)*x(a);if(0===t)return 0;var h=y(r,a)/t;return h>1&&(h=1),Math.acos(h)},n=(r,a)=>r.x*a.y-a.x*r.y,o=r=>r/Math.PI*180,s=(r,a)=>{var t=e$1(r,a);return n(r,a)>0&&(t*=-1),o(t)},u$1=(x,y)=>{if(0!==x||0!==y)return Math.abs(x)>=Math.abs(y)?0<x?i$3:a$2:0<y?d$1:r$4}; function p$1(){let n=0,e=0;return function(o,r){const{prevVecotr:i,startVecotr:a,activeVecotr:c}=r;return c&&(e=Math.round(s(c,i)),n=Math.round(s(c,a))),{angle:n,deltaAngle:e}}}function d(){return function(t){const{prevInput:e}=t;let o$1=0,r=0,i=0;if(void 0!==e&&(o$1=t.x-e.x,r=t.y-e.y,0!==o$1||0!==r)){const t=Math.sqrt(Math.pow(o$1,2)+Math.pow(r,2));i=Math.round(o(Math.acos(Math.abs(o$1)/t)));}return {deltaX:o$1,deltaY:r,deltaXYAngle:i}}}function h$1(){let t,n=0,u=0,s=0,p=0,d=0;return function(h){const{phase:l,startInput:f}=h;return c$3===l?(n=0,u=0,s=0,p=0,d=0):o$1===l&&(n=Math.round(h.points[0][n$1]-f.points[0][n$1]),u=Math.round(h.points[0][e$2]-f.points[0][e$2]),s=Math.abs(n),p=Math.abs(u),d=Math.round(x({x:s,y:p})),t=u$1(n,u)),{displacementX:n,displacementY:u,distanceX:s,distanceY:p,distance:d,overallDirection:t}}}function l(){let t=1;return function(n,o){let r=1;const{prevVecotr:i,startVecotr:a,activeVecotr:c}=o;return c&&(r=p$3(x(c)/x(i)),t=p$3(x(c)/x(a))),{scale:t,deltaScale:r}}}function f(){let t$1,n,e=0,r=0,i=0,a=0;return function(c){if(void 0!==c){n=n||c.startInput;const u=c.timestamp-n.timestamp;if(t<u){const s=c.x-n.x,p=c.y-n.y;i=Math.round(s/u*100)/100,a=Math.round(p/u*100)/100,e=Math.abs(i),r=Math.abs(a),t$1=u$1(s,p),n=c;}}return {velocityX:e,velocityY:r,speedX:i,speedY:a,direction:t$1}}}function M(){let t=0;return function(n){const{phase:e}=n;return c$3===e&&(t=n.pointLength),{maxPointLength:t}}}function v(t){return {x:t.points[1][n$1]-t.points[0][n$1],y:t.points[1][e$2]-t.points[0][e$2]}}function m$1(){let t,n,e;return function(o){const{prevInput:r,startMultiInput:i}=o;return void 0!==i&&void 0!==r&&o.id!==i.id&&1<r.pointLength&&1<o.pointLength?(t=v(i),n=v(r),e=v(o)):e=void 0,{startVecotr:t,prevVecotr:n,activeVecotr:e}}} const m={name:"tap",pointLength:1,tapTimes:1,waitNextTapTime:300,maxDistance:2,maxDistanceFromPrevTap:9,maxPressTime:250};function r$2(r,s){const c=O(m,s);let p,u,x$1,T=0;function f(){T=0,p=void 0,u=void 0;}return r.compute([h$1,M],(t=>{if(j(c))return;const{phase:i,x:o,y:m}=t;u$3===i&&(c.state=0,!function(){const{startInput:e,pointLength:n,timestamp:a}=t,i=a-e.timestamp,{distance:o,maxPointLength:m}=t;return m===c.pointLength&&0===n&&c.maxDistance>=o&&c.maxPressTime>i}()?(f(),c.state=2):(clearTimeout(x$1),function(t,e){if(void 0!==p){const n=x({x:t.x-p.x,y:t.y-p.y});return p=t,e.maxDistanceFromPrevTap>=n}return p=t,true}({x:o,y:m},c)&&function(t){const e=performance.now();if(void 0===u)return u=e,true;{const n=e-u;return u=e,n<t}}(c.waitNextTapTime)?T++:T=1,0==T%c.tapTimes?(c.state=1,r.emit2(c.name,t,c),f()):x$1=setTimeout((()=>{c.state=2,f();}),c.waitNextTapTime)));})),c} const p={name:"pan",threshold:10,pointLength:1};function u(u,d$1){const f$1=O(p,d$1);return u.compute([f,h$1,d],(t=>{if(g$1(f$1),j(f$1))return;const c=function(){const{pointLength:e,distance:n}=t;return f$1.pointLength===e&&f$1.threshold<=n}();if(f$1.state=b(c,f$1.state,t.phase),c||h$3(f$1.state)){const{name:e}=f$1;u.emit2(e,t,f$1),u.emit2(e+v$1(f$1.state),t,f$1),![u$3,s$1].includes(t.phase)&&t.direction&&u.emit2(e+t.direction,t,f$1);}})),f$1} const c$1={name:"swipe",threshold:10,velocity:.3,pointLength:1};function a(a,r){const s=O(c$1,r);return a.compute([h$1,f,M],(t=>{if(s.state=0,!s.disabled&&function(){if(u$3!==t.phase)return false;const{velocityX:o,velocityY:n,distance:i,maxPointLength:c}=t;return c===s.pointLength&&0===t.points.length&&s.threshold<i&&s.velocity<Math.max(o,n)}()){const{name:e}=s;s.state=1,a.emit2(e,t,s),a.emit2(e+t.direction,t,s);}})),s} const r$1={name:"press",pointLength:1,maxDistance:9,minPressTime:251};function c(c,u){const p=O(r$1,u);let f=0;return c.compute([h$1],(t=>{if(j(p))return;const{phase:o,startInput:r,pointLength:u}=t;if(c$3===o&&p.pointLength===u)g$1(p),clearTimeout(f),f=setTimeout((()=>{p.state=1,c.emit2(p.name,t,p);}),p.minPressTime);else if(u$3===o&&1===p.state)c.emit2(`${p.name}${r$4}`,t,p);else if(1!==p.state){const e=t.timestamp-r.timestamp;(!function(){const{distance:e}=t;return e&&p.maxDistance>e}()||p.minPressTime>e&&[u$3,s$1].includes(o))&&(clearTimeout(f),p.state=2);}})),p} const i$2={name:"pinch",threshold:0,pointLength:2};function r(r,m){const p=O(i$2,m);return r.compute([m$1,l],(t=>{if(g$1(p),j(p))return;const c=function(){const{pointLength:e,scale:n,deltaScale:o,phase:a}=t;return p.pointLength===e&&p.threshold<Math.abs(n-1)}();p.state=b(c,p.state,t.phase);const{name:h}=p;if(c||h$3(p.state)){r.emit2(h,t,p);const{deltaScale:e}=t;1!==e&&r.emit2(h+(1<e?"in":"out"),t,p);}const i=v$1(p.state);i&&r.emit2(h+i,t,p);})),p} const h={name:"rotate",threshold:0,pointLength:2};function i$1(i,m){const u=O(h,m);return i.compute([m$1,p$1],(t=>{if(j(u))return;g$1(u);const r=function(){const{pointLength:e,angle:n}=t;return u.pointLength===e&&u.threshold<Math.abs(n)}();u.state=b(r,u.state,t.phase);const{name:c}=u;(r||h$3(u.state))&&i.emit2(c,t,u);const h=v$1(u.state);h&&i.emit2(c+h,t,u);})),u} function e(e){e.use(r$2,{name:"doubletap",tapTimes:2});const a=e.get("doubletap");let o;return e.beforeEach(((t,e)=>{"tap"===t?(clearTimeout(o),o=setTimeout((()=>{[0,2].includes(a.state)&&e();}),300)):e();})),a} class i extends l$1{constructor(t,u$1){super(t,u$1),this.use(r$2),this.use(u),this.use(a),this.use(c),this.use(r),this.use(i$1);}}i.STATE_POSSIBLE=0,i.STATE_START=4,i.STATE_MOVE=5,i.STATE_END=1,i.STATE_CANCELLED=3,i.STATE_FAILED=2,i.STATE_RECOGNIZED=1,i.tap=r$2,i.pan=u,i.swipe=a,i.press=c,i.rotate=i$1,i.pinch=r,i.doubletap=e; class PopsUtils { /** * 判断是否是window,例如window、self、globalThis * @param target */ isWin(target) { if (typeof target !== "object") { return false; } if (target instanceof Node) { return false; } if (target === globalThis) { return true; } if (target === window) { return true; } if (target === self) { return true; } if (target === PopsCore.globalThis) { return true; } if (target === PopsCore.window) { return true; } if (target === PopsCore.self) { return true; } if (typeof unsafeWindow !== "undefined" && target === unsafeWindow) { return true; } if (target?.Math?.toString() !== "[object Math]") { return false; } return true; } isDOM(target) { return target instanceof Node; } /** * 删除对象上的属性 * @param target * @param propName */ delete(target, propName) { if (typeof Reflect === "object" && Reflect.deleteProperty) { Reflect.deleteProperty(target, propName); } else { delete target[propName]; } } assign(target = {}, source = {}, isAdd = false) { let UtilsContext = this; if (source == null) { return target; } if (target == null) { target = {}; } if (Array.isArray(source)) { let canTraverse = source.filter((item) => { return typeof item === "object"; }); if (!canTraverse.length) { return source; } } if (isAdd) { for (const sourceKeyName in source) { const targetKeyName = sourceKeyName; let targetValue = target[targetKeyName]; let sourceValue = source[sourceKeyName]; if (typeof sourceValue === "object" && sourceValue != null && sourceKeyName in target && !UtilsContext.isDOM(sourceValue)) { /* 源端的值是object类型,且不是元素节点 */ target[sourceKeyName] = UtilsContext.assign(targetValue, sourceValue, isAdd); continue; } target[sourceKeyName] = sourceValue; } } else { for (const targetKeyName in target) { if (targetKeyName in source) { // @ts-ignore let targetValue = target[targetKeyName]; // @ts-ignore let sourceValue = source[targetKeyName]; if (typeof sourceValue === "object" && sourceValue != null && !UtilsContext.isDOM(sourceValue) && Object.keys(sourceValue).length) { /* 源端的值是object类型,且不是元素节点 */ // @ts-ignore target[targetKeyName] = UtilsContext.assign(targetValue, sourceValue, isAdd); continue; } /* 直接赋值 */ // @ts-ignore target[targetKeyName] = sourceValue; } } } return target; } /** * 生成uuid */ getRandomGUID() { if (typeof PopsCore.globalThis?.crypto?.randomUUID === "function") { return PopsCore.globalThis.crypto.randomUUID(); } else { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (charStr) { var randomValue = (Math.random() * 16) | 0, randomCharValue = charStr === "x" ? randomValue : (randomValue & 0x3) | 0x8; return randomCharValue.toString(16); }); } } contains(context, target) { if (arguments.length === 1) { // 只判断该页面是否存在该元素 return this.contains(PopsCore.document.body || PopsCore.document.documentElement, arguments[0]); } else { if (target == null) { return false; } if (typeof target[Symbol.iterator] === "function") { // 可遍历的数组 let flag = true; for (const targetNode of target) { if (!context.contains(targetNode)) { flag = false; break; } } return flag; } else { return context.contains(target); } } } formatTime(text = new Date(), formatType = "yyyy-MM-dd HH:mm:ss") { let time = text == null ? new Date() : new Date(text); /** * 校验时间补0 * @param timeNum * @returns */ function checkTime(timeNum) { if (timeNum < 10) return "0" + timeNum; return timeNum; } /** * 时间制修改 24小时制转12小时制 * @param hourNum 小时 * @returns */ function timeSystemChange(hourNum) { return hourNum > 12 ? hourNum - 12 : hourNum; } let timeRegexp = { yyyy: time.getFullYear(), /* 年 */ MM: checkTime(time.getMonth() + 1), /* 月 */ dd: checkTime(time.getDate()), /* 日 */ HH: checkTime(time.getHours()), /* 时 (24小时制) */ hh: checkTime(timeSystemChange(time.getHours())), /* 时 (12小时制) */ mm: checkTime(time.getMinutes()), /* 分 */ ss: checkTime(time.getSeconds()), /* 秒 */ }; Object.keys(timeRegexp).forEach(function (key) { let replaecRegexp = new RegExp(key, "g"); formatType = formatType.replace(replaecRegexp, timeRegexp[key]); }); return formatType; } formatByteToSize(byteSize, addType = true) { byteSize = parseInt(byteSize.toString()); if (isNaN(byteSize)) { throw new TypeError("Utils.formatByteToSize 参数 byteSize 格式不正确"); } let result = 0; let resultType = "KB"; let sizeData = {}; sizeData.B = 1; sizeData.KB = 1024; sizeData.MB = sizeData.KB * sizeData.KB; sizeData.GB = sizeData.MB * sizeData.KB; sizeData.TB = sizeData.GB * sizeData.KB; sizeData.PB = sizeData.TB * sizeData.KB; sizeData.EB = sizeData.PB * sizeData.KB; sizeData.ZB = sizeData.EB * sizeData.KB; sizeData.YB = sizeData.ZB * sizeData.KB; sizeData.BB = sizeData.YB * sizeData.KB; sizeData.NB = sizeData.BB * sizeData.KB; sizeData.DB = sizeData.NB * sizeData.KB; for (let key in sizeData) { result = byteSize / sizeData[key]; resultType = key; if (sizeData.KB >= result) { break; } } result = result.toFixed(2); result = addType ? result + resultType.toString() : parseFloat(result.toString()); return result; } AnyTouch = () => { return i; }; /** * 通过navigator.userAgent判断是否是手机访问 * @param userAgent */ isPhone(userAgent = PopsCore.globalThis.navigator.userAgent) { return Boolean(/(iPhone|iPad|iPod|iOS|Android)/i.test(userAgent)); } /** * 自动使用 Worker 执行 setTimeout */ setTimeout(callback, timeout = 0) { try { return setTimeout$1(callback, timeout); } catch (error) { return globalThis.setTimeout(callback, timeout); } } /** * 配合 .setTimeout 使用 */ clearTimeout(timeId) { try { if (timeId != null) { clearTimeout$1(timeId); } } catch (error) { } finally { globalThis.clearTimeout(timeId); } } /** * 自动使用 Worker 执行 setInterval */ setInterval(callback, timeout = 0) { try { return setInterval$1(callback, timeout); } catch (error) { return globalThis.setInterval(callback, timeout); } } /** * 配合 .setInterval 使用 */ clearInterval(timeId) { try { if (timeId != null) { clearInterval$1(timeId); } } catch (error) { } finally { globalThis.clearInterval(timeId); } } } const popsUtils = new PopsUtils(); const PopsSafeUtils = { /** * 获取安全的html */ getSafeHTML(text) { // @ts-ignore if (globalThis.trustedTypes) { // @ts-ignore const policy = globalThis.trustedTypes.createPolicy("safe-innerHTML", { createHTML: (html) => html, }); return policy.createHTML(text); } else { return text; } }, /** * 设置安全的html */ setSafeHTML($el, text) { // 创建 TrustedHTML 策略(需 CSP 允许) $el.innerHTML = this.getSafeHTML(text); }, }; class PopsDOMUtilsEvent { on(element, eventType, selector, callback, option) { /** * 获取option配置 * @param args * @param startIndex * @param option */ function getOption(args, startIndex, option) { let currentParam = args[startIndex]; if (typeof currentParam === "boolean") { option.capture = currentParam; if (typeof args[startIndex + 1] === "boolean") { option.once = args[startIndex + 1]; } if (typeof args[startIndex + 2] === "boolean") { option.passive = args[startIndex + 2]; } } else if (typeof currentParam === "object" && ("capture" in currentParam || "once" in currentParam || "passive" in currentParam || "isComposedPath" in currentParam)) { option.capture = currentParam.capture; option.once = currentParam.once; option.passive = currentParam.passive; option.isComposedPath = currentParam.isComposedPath; } return option; } let DOMUtilsContext = this; let args = arguments; if (typeof element === "string") { element = DOMUtilsContext.selectorAll(element); } if (element == null) { return; } let elementList = []; if (element instanceof NodeList || Array.isArray(element)) { element = element; elementList = [...element]; } else { elementList.push(element); } // 事件名 let eventTypeList = []; if (Array.isArray(eventType)) { eventTypeList = eventTypeList.concat(eventType.filter((eventTypeItem) => typeof eventTypeItem === "string" && eventTypeItem.toString() !== "")); } else if (typeof eventType === "string") { eventTypeList = eventTypeList.concat(eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== "")); } // 子元素选择器 let selectorList = []; if (Array.isArray(selector)) { selectorList = selectorList.concat(selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== "")); } else if (typeof selector === "string") { selectorList.push(selector); } // 事件回调 let listenerCallBack = callback; // 事件配置 let listenerOption = { capture: false, once: false, passive: false, isComposedPath: false, }; if (typeof selector === "function") { // 这是为没有selector的情况 // 那么它就是callback listenerCallBack = selector; listenerOption = getOption(args, 3, listenerOption); } else { // 这是存在selector的情况 listenerOption = getOption(args, 4, listenerOption); } /** * 如果是once,那么删除该监听和元素上的事件和监听 */ function checkOptionOnceToRemoveEventListener() { if (listenerOption.once) { DOMUtilsContext.off(element, eventType, selector, callback, option); } } elementList.forEach((elementItem) => { /** * 事件回调 * @param event */ function domUtilsEventCallBack(event) { if (selectorList.length) { /* 存在子元素选择器 */ // 这时候的this和target都是子元素选择器的元素 let eventTarget = listenerOption.isComposedPath ? event.composedPath()[0] : event.target; let totalParent = elementItem; if (popsUtils.isWin(totalParent)) { if (totalParent === PopsCore.document) { totalParent = PopsCore.document.documentElement; } } let findValue = selectorList.find((selectorItem) => { // 判断目标元素是否匹配选择器 if (DOMUtilsContext.matches(eventTarget, selectorItem)) { /* 当前目标可以被selector所匹配到 */ return true; } /* 在上层与主元素之间寻找可以被selector所匹配到的 */ let $closestMatches = DOMUtilsContext.closest(eventTarget, selectorItem); if ($closestMatches && totalParent?.contains($closestMatches)) { eventTarget = $closestMatches; return true; } return false; }); if (findValue) { // 这里尝试使用defineProperty修改event的target值 try { OriginPrototype.Object.defineProperty(event, "target", { get() { return eventTarget; }, }); } catch (error) { } listenerCallBack.call(eventTarget, event, eventTarget); checkOptionOnceToRemoveEventListener(); } } else { // 这时候的this指向监听的元素 listenerCallBack.call(elementItem, event); checkOptionOnceToRemoveEventListener(); } } /* 遍历事件名设置元素事件 */ eventTypeList.forEach((eventName) => { elementItem.addEventListener(eventName, domUtilsEventCallBack, listenerOption); /* 获取对象上的事件 */ let elementEvents = Reflect.get(elementItem, SymbolEvents) || {}; /* 初始化对象上的xx事件 */ elementEvents[eventName] = elementEvents[eventName] || []; elementEvents[eventName].push({ selector: selectorList, option: listenerOption, callback: domUtilsEventCallBack, originCallBack: listenerCallBack, }); /* 覆盖事件 */ Reflect.set(elementItem, SymbolEvents, elementEvents); }); }); } off(element, eventType, selector, callback, option, filter) { /** * 获取option配置 * @param args1 * @param startIndex * @param option */ function getOption(args1, startIndex, option) { let currentParam = args1[startIndex]; if (typeof currentParam === "boolean") { option.capture = currentParam; } else if (typeof currentParam === "object" && "capture" in currentParam) { option.capture = currentParam.capture; } return option; } let DOMUtilsContext = this; let args = arguments; if (typeof element === "string") { element = DOMUtilsContext.selectorAll(element); } if (element == null) { return; } let elementList = []; if (element instanceof NodeList || Array.isArray(element)) { element = element; elementList = [...element]; } else { elementList.push(element); } let eventTypeList = []; if (Array.isArray(eventType)) { eventTypeList = eventTypeList.concat(eventType.filter((eventTypeItem) => typeof eventTypeItem === "string" && eventTypeItem.toString() !== "")); } else if (typeof eventType === "string") { eventTypeList = eventTypeList.concat(eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== "")); } // 子元素选择器 let selectorList = []; if (Array.isArray(selector)) { selectorList = selectorList.concat(selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== "")); } else if (typeof selector === "string") { selectorList.push(selector); } /** * 事件的回调函数 */ let listenerCallBack = callback; /** * 事件的配置 */ let listenerOption = { capture: false, }; if (typeof selector === "function") { // 这是为没有selector的情况 // 那么它就是callback listenerCallBack = selector; listenerOption = getOption(args, 3, listenerOption); } else { // 这是存在selector的情况 listenerOption = getOption(args, 4, listenerOption); } // 是否移除所有事件 let isRemoveAll = false; if (args.length === 2) { // 目标函数、事件名 isRemoveAll = true; } else if ((args.length === 3 && typeof args[2] === "string") || Array.isArray(args[2])) { // 目标函数、事件名、子元素选择器 isRemoveAll = true; } elementList.forEach((elementItem) => { /* 获取对象上的事件 */ let elementEvents = Reflect.get(elementItem, SymbolEvents) || {}; eventTypeList.forEach((eventName) => { let handlers = elementEvents[eventName] || []; if (typeof filter === "function") { handlers = handlers.filter(filter); } for (let index = 0; index < handlers.length; index++) { let handler = handlers[index]; let flag = true; if (flag && listenerCallBack && handler.originCallBack !== listenerCallBack) { // callback不同 flag = false; } if (flag && selectorList.length && Array.isArray(handler.selector)) { if (JSON.stringify(handler.selector) !== JSON.stringify(selectorList)) { // 子元素选择器不同 flag = false; } } if (flag && listenerOption.capture !== handler.option.capture) { // 事件的配置项不同 flag = false; } if (flag || isRemoveAll) { elementItem.removeEventListener(eventName, handler.callback, handler.option); handlers.splice(index--, 1); } } if (handlers.length === 0) { /* 如果没有任意的handler,那么删除该属性 */ popsUtils.delete(elementEvents, eventType); } }); Reflect.set(elementItem, SymbolEvents, elementEvents); }); } /** * 取消绑定所有的事件 * @param element 需要取消绑定的元素|元素数组 *