@whitesev/pops 4.2.0 → 4.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.pops = factory());
5
5
  })(this, (function () { 'use strict';
6
6
 
7
- const version = "4.2.0";
7
+ const version = "4.2.2";
8
8
 
9
9
  const GlobalConfig = {
10
10
  config: {},
@@ -248,6 +248,24 @@
248
248
  },
249
249
  };
250
250
 
251
+ /**
252
+ * 通用的CSS类名
253
+ */
254
+ const PopsCommonCSSClassName = {
255
+ flexCenter: "pops-flex-items-center",
256
+ flexYCenter: "pops-flex-y-center",
257
+ flexXCenter: "pops-flex-x-center",
258
+ hide: "pops-hide",
259
+ hideImportant: "pops-hide-important",
260
+ noBorder: "pops-no-border",
261
+ noBorderImportant: "pops-no-border-important",
262
+ userSelectNone: "pops-user-select-none",
263
+ lineHeightCenter: "pops-line-height-center",
264
+ widthFill: "pops-width-fill",
265
+ textIsDisabled: "pops-text-is-disabled",
266
+ textIsDisabledImportant: "pops-text-is-disabled-important",
267
+ };
268
+
251
269
  const OriginPrototype = {
252
270
  Object: {
253
271
  defineProperty: Object.defineProperty,
@@ -297,6 +315,30 @@
297
315
  },
298
316
  };
299
317
 
318
+ const PopsSafeUtils = {
319
+ /**
320
+ * 获取安全的html
321
+ */
322
+ getSafeHTML(text) {
323
+ if (window.trustedTypes) {
324
+ const policy = window.trustedTypes.createPolicy("safe-innerHTML", {
325
+ createHTML: (html) => html,
326
+ });
327
+ return policy.createHTML(text);
328
+ }
329
+ else {
330
+ return text;
331
+ }
332
+ },
333
+ /**
334
+ * 设置安全的html
335
+ */
336
+ setSafeHTML($el, text) {
337
+ // 创建 TrustedHTML 策略(需 CSP 允许)
338
+ $el.innerHTML = this.getSafeHTML(text);
339
+ },
340
+ };
341
+
300
342
  const n$1="clientX",e$2="clientY",t$1=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}
301
343
 
302
344
  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$2=(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};
@@ -766,48 +808,6 @@
766
808
  }
767
809
  const popsUtils = new PopsUtils();
768
810
 
769
- const PopsSafeUtils = {
770
- /**
771
- * 获取安全的html
772
- */
773
- getSafeHTML(text) {
774
- if (window.trustedTypes) {
775
- const policy = window.trustedTypes.createPolicy("safe-innerHTML", {
776
- createHTML: (html) => html,
777
- });
778
- return policy.createHTML(text);
779
- }
780
- else {
781
- return text;
782
- }
783
- },
784
- /**
785
- * 设置安全的html
786
- */
787
- setSafeHTML($el, text) {
788
- // 创建 TrustedHTML 策略(需 CSP 允许)
789
- $el.innerHTML = this.getSafeHTML(text);
790
- },
791
- };
792
-
793
- /**
794
- * 通用的CSS类名
795
- */
796
- const PopsCommonCSSClassName = {
797
- flexCenter: "pops-flex-items-center",
798
- flexYCenter: "pops-flex-y-center",
799
- flexXCenter: "pops-flex-x-center",
800
- hide: "pops-hide",
801
- hideImportant: "pops-hide-important",
802
- noBorder: "pops-no-border",
803
- noBorderImportant: "pops-no-border-important",
804
- userSelectNone: "pops-user-select-none",
805
- lineHeightCenter: "pops-line-height-center",
806
- widthFill: "pops-width-fill",
807
- textIsDisabled: "pops-text-is-disabled",
808
- textIsDisabledImportant: "pops-text-is-disabled-important",
809
- };
810
-
811
811
  /**
812
812
  * 存储在元素属性上的事件名
813
813
  */
@@ -820,7 +820,7 @@
820
820
  * @param startIndex
821
821
  * @param option
822
822
  */
823
- function getOption(args, startIndex, option) {
823
+ const getOption = function (args, startIndex, option) {
824
824
  const currentParam = args[startIndex];
825
825
  if (typeof currentParam === "boolean") {
826
826
  option.capture = currentParam;
@@ -842,7 +842,7 @@
842
842
  option.isComposedPath = currentParam.isComposedPath;
843
843
  }
844
844
  return option;
845
- }
845
+ };
846
846
  const that = this;
847
847
  // eslint-disable-next-line prefer-rest-params
848
848
  const args = arguments;
@@ -857,8 +857,7 @@
857
857
  }
858
858
  let $elList = [];
859
859
  if (element instanceof NodeList || Array.isArray(element)) {
860
- element = element;
861
- $elList = [...element];
860
+ $elList = $elList.concat(Array.from(element));
862
861
  }
863
862
  else {
864
863
  $elList.push(element);
@@ -866,15 +865,15 @@
866
865
  // 事件名
867
866
  let eventTypeList = [];
868
867
  if (Array.isArray(eventType)) {
869
- eventTypeList = eventTypeList.concat(eventType.filter((eventTypeItem) => typeof eventTypeItem === "string" && eventTypeItem.toString() !== ""));
868
+ eventTypeList = eventTypeList.concat(eventType.filter((it) => typeof it === "string" && it.toString() !== ""));
870
869
  }
871
870
  else if (typeof eventType === "string") {
872
- eventTypeList = eventTypeList.concat(eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== ""));
871
+ eventTypeList = eventTypeList.concat(eventType.split(" ").filter((it) => it !== ""));
873
872
  }
874
873
  // 子元素选择器
875
874
  let selectorList = [];
876
875
  if (Array.isArray(selector)) {
877
- selectorList = selectorList.concat(selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== ""));
876
+ selectorList = selectorList.concat(selector.filter((it) => typeof it === "string" && it.toString() !== ""));
878
877
  }
879
878
  else if (typeof selector === "string") {
880
879
  selectorList.push(selector);
@@ -898,83 +897,105 @@
898
897
  // 这是存在selector的情况
899
898
  listenerOption = getOption(args, 4, listenerOption);
900
899
  }
901
- /**
902
- * 如果是once,那么删除该监听和元素上的事件和监听
903
- */
904
- function checkOptionOnceToRemoveEventListener() {
905
- if (listenerOption.once) {
906
- that.off(element, eventType, selector, callback, option);
907
- }
908
- }
909
- $elList.forEach((elementItem) => {
910
- /**
911
- * 事件回调
912
- * @param event
913
- */
914
- function domUtilsEventCallBack(event) {
915
- if (selectorList.length) {
916
- // 存在子元素选择器
917
- // 这时候的this和target都是子元素选择器的元素
918
- let eventTarget = listenerOption.isComposedPath
919
- ? event.composedPath()[0]
920
- : event.target;
921
- let totalParent = elementItem;
922
- if (popsUtils.isWin(totalParent)) {
923
- if (totalParent === PopsCore.document) {
924
- totalParent = PopsCore.document.documentElement;
925
- }
926
- }
927
- const findValue = selectorList.find((selectorItem) => {
928
- // 判断目标元素是否匹配选择器
929
- if (that.matches(eventTarget, selectorItem)) {
930
- // 当前目标可以被selector所匹配到
931
- return true;
932
- }
933
- // 在上层与主元素之间寻找可以被selector所匹配到的
934
- const $closestMatches = that.closest(eventTarget, selectorItem);
935
- if ($closestMatches && totalParent?.contains($closestMatches)) {
936
- eventTarget = $closestMatches;
937
- return true;
938
- }
939
- return false;
940
- });
941
- if (findValue) {
942
- // 这里尝试使用defineProperty修改event的target值
943
- try {
944
- OriginPrototype.Object.defineProperty(event, "target", {
945
- get() {
946
- return eventTarget;
947
- },
948
- });
900
+ $elList.forEach(($elItem) => {
901
+ // 遍历事件名设置元素事件
902
+ eventTypeList.forEach((eventName) => {
903
+ /**
904
+ * 如果是option.once,那么删除该监听和元素上的事件和监听
905
+ */
906
+ const checkOptionOnceToRemoveEventListener = () => {
907
+ if (listenerOption.once) {
908
+ this.off($elItem, eventName, selector, callback, option);
909
+ }
910
+ };
911
+ /**
912
+ * 事件回调
913
+ * @param event
914
+ */
915
+ const handlerCallBack = function (event) {
916
+ let call_this = void 0;
917
+ let call_event = void 0;
918
+ let call_$selector = void 0;
919
+ let execCallback = false;
920
+ if (selectorList.length) {
921
+ // 存在子元素选择器
922
+ // 这时候的this和target都是子元素选择器的元素
923
+ let $target;
924
+ if (listenerOption.isComposedPath) {
925
+ // 可能为空
926
+ const composedPath = event.composedPath();
927
+ if (!composedPath.length && event.target) {
928
+ composedPath.push(event.target);
929
+ }
930
+ $target = composedPath[0];
949
931
  }
950
- catch {
951
- // 忽略
932
+ else {
933
+ $target = event.target;
934
+ }
935
+ let $parent = $elItem;
936
+ if (popsUtils.isWin($parent)) {
937
+ // window和document共用一个对象
938
+ // 这样就能处理子元素选择器无法匹配的问题
939
+ $parent = PopsCore.document.documentElement;
940
+ }
941
+ const findValue = selectorList.find((selectors) => {
942
+ // 判断目标元素是否匹配选择器
943
+ if (that.matches($target, selectors)) {
944
+ // 当前目标可以被selector所匹配到
945
+ return true;
946
+ }
947
+ // 在上层与主元素之间寻找可以被selector所匹配到的
948
+ const $closestMatches = that.closest($target, selectors);
949
+ if ($closestMatches && $parent?.contains?.($closestMatches)) {
950
+ $target = $closestMatches;
951
+ return true;
952
+ }
953
+ return false;
954
+ });
955
+ if (findValue) {
956
+ // 这里尝试使用defineProperty修改event的target值
957
+ try {
958
+ OriginPrototype.Object.defineProperty(event, "target", {
959
+ get() {
960
+ return $target;
961
+ },
962
+ });
963
+ // oxlint-disable-next-line no-empty
964
+ }
965
+ catch { }
966
+ execCallback = true;
967
+ call_this = $target;
968
+ call_event = event;
969
+ call_$selector = $target;
952
970
  }
953
- listenerCallBack.call(eventTarget, event, eventTarget);
971
+ }
972
+ else {
973
+ execCallback = true;
974
+ call_this = $elItem;
975
+ call_event = event;
976
+ }
977
+ if (execCallback) {
978
+ const result = listenerCallBack.call(call_this, call_event, call_$selector);
954
979
  checkOptionOnceToRemoveEventListener();
980
+ if (typeof result === "boolean" && !result) {
981
+ return false;
982
+ }
955
983
  }
956
- }
957
- else {
958
- // 这时候的this指向监听的元素
959
- listenerCallBack.call(elementItem, event);
960
- checkOptionOnceToRemoveEventListener();
961
- }
962
- }
963
- // 遍历事件名设置元素事件
964
- eventTypeList.forEach((eventName) => {
965
- elementItem.addEventListener(eventName, domUtilsEventCallBack, listenerOption);
984
+ };
985
+ // add listener
986
+ $elItem.addEventListener(eventName, handlerCallBack, listenerOption);
966
987
  // 获取对象上的事件
967
- const elementEvents = Reflect.get(elementItem, SymbolEvents) || {};
988
+ const elementEvents = Reflect.get($elItem, SymbolEvents) || {};
968
989
  // 初始化对象上的xx事件
969
990
  elementEvents[eventName] = elementEvents[eventName] || [];
970
991
  elementEvents[eventName].push({
971
992
  selector: selectorList,
972
993
  option: listenerOption,
973
- callback: domUtilsEventCallBack,
974
- originCallBack: listenerCallBack,
994
+ handlerCallBack: handlerCallBack,
995
+ callback: listenerCallBack,
975
996
  });
976
997
  // 覆盖事件
977
- Reflect.set(elementItem, SymbolEvents, elementEvents);
998
+ Reflect.set($elItem, SymbolEvents, elementEvents);
978
999
  });
979
1000
  });
980
1001
  return {
@@ -987,11 +1008,11 @@
987
1008
  },
988
1009
  /**
989
1010
  * 主动触发事件
990
- * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
991
- * @param useDispatchToEmit 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了selectorTarget的没有值
1011
+ * @param extraDetails 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
1012
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了`$selector`的没有值
992
1013
  */
993
- emit: (details, useDispatchToEmit) => {
994
- that.emit($elList, eventTypeList, details, useDispatchToEmit);
1014
+ emit: (extraDetails, useDispatchToTriggerEvent) => {
1015
+ that.emit($elList, eventTypeList, extraDetails, useDispatchToTriggerEvent);
995
1016
  },
996
1017
  };
997
1018
  }
@@ -1002,7 +1023,7 @@
1002
1023
  * @param startIndex
1003
1024
  * @param option
1004
1025
  */
1005
- function getOption(args1, startIndex, option) {
1026
+ const getOption = function (args1, startIndex, option) {
1006
1027
  const currentParam = args1[startIndex];
1007
1028
  if (typeof currentParam === "boolean") {
1008
1029
  option.capture = currentParam;
@@ -1011,12 +1032,12 @@
1011
1032
  option.capture = currentParam.capture;
1012
1033
  }
1013
1034
  return option;
1014
- }
1015
- const DOMUtilsContext = this;
1035
+ };
1036
+ const that = this;
1016
1037
  // eslint-disable-next-line prefer-rest-params
1017
1038
  const args = arguments;
1018
1039
  if (typeof element === "string") {
1019
- element = DOMUtilsContext.selectorAll(element);
1040
+ element = that.selectorAll(element);
1020
1041
  }
1021
1042
  if (element == null) {
1022
1043
  return;
@@ -1024,22 +1045,22 @@
1024
1045
  let $elList = [];
1025
1046
  if (element instanceof NodeList || Array.isArray(element)) {
1026
1047
  element = element;
1027
- $elList = $elList.concat(element);
1048
+ $elList = $elList.concat(Array.from(element));
1028
1049
  }
1029
1050
  else {
1030
1051
  $elList.push(element);
1031
1052
  }
1032
1053
  let eventTypeList = [];
1033
1054
  if (Array.isArray(eventType)) {
1034
- eventTypeList = eventTypeList.concat(eventType.filter((eventTypeItem) => typeof eventTypeItem === "string" && eventTypeItem.toString() !== ""));
1055
+ eventTypeList = eventTypeList.concat(eventType.filter((it) => typeof it === "string" && it.toString() !== ""));
1035
1056
  }
1036
1057
  else if (typeof eventType === "string") {
1037
- eventTypeList = eventTypeList.concat(eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== ""));
1058
+ eventTypeList = eventTypeList.concat(eventType.split(" ").filter((it) => it !== ""));
1038
1059
  }
1039
1060
  // 子元素选择器
1040
1061
  let selectorList = [];
1041
1062
  if (Array.isArray(selector)) {
1042
- selectorList = selectorList.concat(selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== ""));
1063
+ selectorList = selectorList.concat(selector.filter((it) => typeof it === "string" && it.toString() !== ""));
1043
1064
  }
1044
1065
  else if (typeof selector === "string") {
1045
1066
  selectorList.push(selector);
@@ -1068,36 +1089,39 @@
1068
1089
  // 目标函数、事件名、回调函数、事件配置、过滤函数
1069
1090
  filter = option;
1070
1091
  }
1071
- $elList.forEach((elementItem) => {
1092
+ $elList.forEach(($elItem) => {
1072
1093
  // 获取对象上的事件
1073
- const elementEvents = Reflect.get(elementItem, SymbolEvents) || {};
1094
+ const elementEvents = Reflect.get($elItem, SymbolEvents) || {};
1074
1095
  eventTypeList.forEach((eventName) => {
1075
1096
  const handlers = elementEvents[eventName] || [];
1076
- const filterHandler = typeof filter === "function" ? handlers.filter(filter) : handlers;
1077
- for (let index = 0; index < filterHandler.length; index++) {
1078
- const handler = filterHandler[index];
1097
+ // 过滤出需要删除的事件
1098
+ const handlersFiltered = typeof filter === "function" ? handlers.filter(filter) : handlers;
1099
+ for (let index = 0; index < handlersFiltered.length; index++) {
1100
+ const handler = handlersFiltered[index];
1101
+ // 过滤出的事件再根据下面的条件进行判断处理移除
1102
+ // 1. callback内存地址必须相同
1103
+ // 2. selector必须相同
1104
+ // 3. option.capture必须相同
1079
1105
  let flag = true;
1080
- if (flag && listenerCallBack && handler.originCallBack !== listenerCallBack) {
1081
- // callback不同
1106
+ if (flag && listenerCallBack && handler.callback !== listenerCallBack) {
1082
1107
  flag = false;
1083
1108
  }
1084
1109
  if (flag && selectorList.length && Array.isArray(handler.selector)) {
1085
1110
  if (JSON.stringify(handler.selector) !== JSON.stringify(selectorList)) {
1086
- // 子元素选择器不同
1087
1111
  flag = false;
1088
1112
  }
1089
1113
  }
1090
1114
  if (flag &&
1091
1115
  typeof handler.option.capture === "boolean" &&
1092
1116
  listenerOption.capture !== handler.option.capture) {
1093
- // 事件的配置项不同
1094
1117
  flag = false;
1095
1118
  }
1096
1119
  if (flag) {
1097
- elementItem.removeEventListener(eventName, handler.callback, handler.option);
1098
- const findIndex = handlers.findIndex((item) => item === handler);
1099
- if (findIndex !== -1) {
1100
- handlers.splice(findIndex, 1);
1120
+ $elItem.removeEventListener(eventName, handler.handlerCallBack, handler.option);
1121
+ for (let i = handlers.length - 1; i >= 0; i--) {
1122
+ if (handlers[i] === handler) {
1123
+ handlers.splice(i, 1);
1124
+ }
1101
1125
  }
1102
1126
  }
1103
1127
  }
@@ -1106,7 +1130,7 @@
1106
1130
  popsUtils.delete(elementEvents, eventType);
1107
1131
  }
1108
1132
  });
1109
- Reflect.set(elementItem, SymbolEvents, elementEvents);
1133
+ Reflect.set($elItem, SymbolEvents, elementEvents);
1110
1134
  });
1111
1135
  }
1112
1136
  /**
@@ -1490,11 +1514,11 @@
1490
1514
  * 阻止事件的默认行为发生,并阻止事件传播
1491
1515
  */
1492
1516
  const stopEvent = (event, onlyStopPropagation) => {
1517
+ // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
1518
+ event?.stopPropagation();
1519
+ // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
1520
+ event?.stopImmediatePropagation();
1493
1521
  if (typeof onlyStopPropagation === "boolean" && onlyStopPropagation) {
1494
- // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
1495
- event?.stopPropagation();
1496
- // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
1497
- event?.stopImmediatePropagation();
1498
1522
  return;
1499
1523
  }
1500
1524
  // 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL,或者在输入框内输入文字