@whitesev/pops 2.5.3 → 2.5.5

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.
@@ -30,7 +30,7 @@ export interface PopsRightClickMenuDataDetails {
30
30
  * + false 不关闭菜单
31
31
  *
32
32
  */
33
- callback?: (clickEvent: PointerEvent, contextMenuEvent: PointerEvent, liElement: HTMLLIElement, menuListenerRootNode: HTMLElement) => boolean | void | Promise<boolean | void>;
33
+ callback?: (clickEvent: PointerEvent, contextMenuEvent: PointerEvent, liElement: HTMLLIElement, menuListenerRootNode: NonNullable<PopsRightClickMenuDetails["target"]>) => boolean | void | Promise<boolean | void>;
34
34
  /**
35
35
  * 子项配置
36
36
  */
@@ -47,8 +47,14 @@ export interface PopsRightClickMenuDetails extends Pick<PopsCommonConfig, "useSh
47
47
  target?: HTMLElement | Window | EventTarget | Node;
48
48
  /**
49
49
  * 目标的子元素选择器,默认为空
50
+ * @default null
50
51
  */
51
52
  targetSelector?: string | null;
53
+ /**
54
+ * 位置
55
+ * @default "fixed"
56
+ */
57
+ position?: "absolute" | "fixed";
52
58
  /**
53
59
  * 右键菜单数据
54
60
  */
@@ -87,4 +93,14 @@ export interface PopsRightClickMenuDetails extends Pick<PopsCommonConfig, "useSh
87
93
  * @default false
88
94
  */
89
95
  preventDefault?: boolean;
96
+ /**
97
+ * 限制x位置在当前视窗内
98
+ * @default true
99
+ */
100
+ limitPositionXInView?: boolean;
101
+ /**
102
+ * 限制y位置在当前视窗内
103
+ * @default true
104
+ */
105
+ limitPositionYInView?: boolean;
90
106
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whitesev/pops",
3
- "version": "2.5.3",
3
+ "version": "2.5.5",
4
4
  "description": "弹窗库",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/WhiteSevs/TamperMonkeyScript/tree/master/lib/pops#readme",
@@ -41,28 +41,28 @@
41
41
  "license": "MIT",
42
42
  "dependencies": {
43
43
  "any-touch": "^2.2.0",
44
- "worker-timers": "^8.0.23"
44
+ "worker-timers": "^8.0.25"
45
45
  },
46
46
  "devDependencies": {
47
- "@eslint/js": "^9.36.0",
48
- "@rollup/plugin-commonjs": "^28.0.6",
47
+ "@eslint/js": "^9.37.0",
48
+ "@rollup/plugin-commonjs": "^28.0.8",
49
49
  "@rollup/plugin-json": "^6.1.0",
50
- "@rollup/plugin-node-resolve": "^16.0.1",
50
+ "@rollup/plugin-node-resolve": "^16.0.3",
51
51
  "@rollup/plugin-terser": "^0.4.4",
52
52
  "@rollup/plugin-typescript": "12.1.4",
53
- "browserslist": "^4.26.2",
54
- "caniuse-lite": "^1.0.30001743",
55
- "eslint": "^9.36.0",
53
+ "browserslist": "^4.26.3",
54
+ "caniuse-lite": "^1.0.30001751",
55
+ "eslint": "^9.37.0",
56
56
  "eslint-config-prettier": "^10.1.8",
57
57
  "eslint-plugin-compat": "^6.0.2",
58
58
  "eslint-plugin-prettier": "^5.5.4",
59
59
  "globals": "^16.4.0",
60
- "rollup": "^4.45.0",
60
+ "rollup": "^4.52.4",
61
61
  "rollup-plugin-clear": "^2.0.7",
62
- "rollup-plugin-import-css": "^4.0.1",
62
+ "rollup-plugin-import-css": "^4.0.2",
63
63
  "tslib": "^2.8.1",
64
- "typescript": "^5.8.3",
65
- "typescript-eslint": "^8.44.0"
64
+ "typescript": "^5.9.3",
65
+ "typescript-eslint": "^8.46.1"
66
66
  },
67
67
  "scripts": {
68
68
  "lint": "eslint .",
@@ -490,42 +490,7 @@ export const PopsPanelConfig = (): DeepRequired<PopsPanelDetails> => {
490
490
  },
491
491
  },
492
492
  ],
493
- bottomContentConfig: [
494
- {
495
- text: "Github",
496
- position: "left",
497
- className: "user-home",
498
- attributes: {
499
- "data-url": "https://github.com/whitesevs",
500
- },
501
- props: {
502
- "data-test": 1,
503
- },
504
- disableHoverCSS: false,
505
- clickCallback() {
506
- const userHomeUrl = (this.attributes as { [key: string]: any })["data-url"];
507
- console.log("打开个人主页:" + userHomeUrl);
508
- window.open(userHomeUrl, "_blank");
509
- },
510
- afterRender(config) {
511
- console.log(config);
512
- },
513
- },
514
- {
515
- text: "0.0.1",
516
- position: "right",
517
- className: "script-version",
518
- attributes: {},
519
- props: {},
520
- disableHoverCSS: true,
521
- clickCallback() {
522
- console.log("当前版本:" + this.text);
523
- },
524
- afterRender(config) {
525
- console.log(config);
526
- },
527
- },
528
- ],
493
+ bottomContentConfig: [],
529
494
  btn: {
530
495
  close: {
531
496
  enable: true,
@@ -19,8 +19,18 @@ export const PopsPanel = {
19
19
  let config: Required<PopsPanelDetails> = PopsPanelConfig();
20
20
  config = popsUtils.assign(config, GlobalConfig.getGlobalConfig());
21
21
  config = popsUtils.assign(config, details);
22
- if (details && Array.isArray(details.content)) {
23
- config.content = details.content;
22
+ if (details) {
23
+ if (Array.isArray(details.content)) {
24
+ // 存在内容配置
25
+ config.content = details.content;
26
+ }
27
+ if (Array.isArray(details.bottomContentConfig)) {
28
+ // 存在底部配置
29
+ config.bottomContentConfig = details.bottomContentConfig;
30
+ } else {
31
+ // 不存在底部配置 清空默认的
32
+ config.bottomContentConfig = [];
33
+ }
24
34
  }
25
35
  config = PopsHandler.handleOnly(popsType, config);
26
36
 
@@ -5,6 +5,7 @@ export const rightClickMenuConfig = (): DeepRequired<PopsRightClickMenuDetails>
5
5
  return {
6
6
  target: document.documentElement,
7
7
  targetSelector: null,
8
+ position: "fixed",
8
9
  data: [
9
10
  {
10
11
  icon: PopsIcon.getIcon("search")!,
@@ -94,5 +95,7 @@ export const rightClickMenuConfig = (): DeepRequired<PopsRightClickMenuDetails>
94
95
  preventDefault: true,
95
96
  style: null,
96
97
  beforeAppendToPageCallBack() {},
98
+ limitPositionXInView: true,
99
+ limitPositionYInView: true,
97
100
  };
98
101
  };
@@ -30,6 +30,9 @@
30
30
  -webkit-backdrop-filter: var(--pops-right-context-backdrop-filter);
31
31
  backdrop-filter: var(--pops-right-context-backdrop-filter);
32
32
  }
33
+ .pops-rightClickMenu[data-position="absolute"] {
34
+ position: absolute;
35
+ }
33
36
  /* scale动画 */
34
37
  .pops-rightClickMenu-anim-scale {
35
38
  transition:
@@ -47,7 +47,7 @@ export const PopsRightClickMenu = {
47
47
  ]);
48
48
 
49
49
  if (config.style != null) {
50
- const cssNode = popsDOMUtils.createElement(
50
+ const $css = popsDOMUtils.createElement(
51
51
  "style",
52
52
  {
53
53
  innerHTML: config.style,
@@ -56,7 +56,7 @@ export const PopsRightClickMenu = {
56
56
  type: "text/css",
57
57
  }
58
58
  );
59
- $shadowRoot.appendChild(cssNode);
59
+ $shadowRoot.appendChild($css);
60
60
  }
61
61
 
62
62
  const PopsContextMenu = {
@@ -132,7 +132,7 @@ export const PopsRightClickMenu = {
132
132
  * @param event
133
133
  * @param selectorTarget
134
134
  */
135
- contextMenuEvent(event: PointerEvent, selectorTarget: HTMLElement) {
135
+ contextMenuEvent(event: PointerEvent, selectorTarget: NonNullable<PopsRightClickMenuDetails["target"]>) {
136
136
  if (config.preventDefault) {
137
137
  popsDOMUtils.preventEvent(event);
138
138
  }
@@ -140,6 +140,7 @@ export const PopsRightClickMenu = {
140
140
  if (PopsContextMenu.rootElement) {
141
141
  PopsContextMenu.closeAllMenu(PopsContextMenu.rootElement);
142
142
  }
143
+ selectorTarget = selectorTarget ?? config.target;
143
144
  const rootElement = PopsContextMenu.showMenu(event, config.data, selectorTarget);
144
145
  PopsContextMenu.rootElement = rootElement;
145
146
  if (config.only) {
@@ -186,7 +187,6 @@ export const PopsRightClickMenu = {
186
187
  });
187
188
  $menu.remove();
188
189
  };
189
- popsDOMUtils.containsClassName;
190
190
  if (popsDOMUtils.containsClassName($menu, `pops-${popsType}-anim-show`)) {
191
191
  /* 有动画 */
192
192
  popsDOMUtils.on($menu, popsDOMUtils.getTransitionEndNameList(), transitionEndEvent, {
@@ -233,10 +233,16 @@ export const PopsRightClickMenu = {
233
233
  * @param isChildren 是否是rightClickMenu的某一项的子菜单
234
234
  */
235
235
  createMenuContainerElement(isChildren: boolean) {
236
- const $menu = popsDOMUtils.createElement("div", {
237
- className: `pops-${popsType}`,
238
- innerHTML: /*html*/ `<ul class="pops-${popsType}-wrapper"></ul>`,
239
- });
236
+ const $menu = popsDOMUtils.createElement(
237
+ "div",
238
+ {
239
+ className: `pops-${popsType}`,
240
+ innerHTML: /*html*/ `<ul class="pops-${popsType}-wrapper"></ul>`,
241
+ },
242
+ {
243
+ "data-position": config.position,
244
+ }
245
+ );
240
246
  const zIndex = this.getMenuZIndex();
241
247
  if (zIndex > 10000) {
242
248
  $menu.style.zIndex = zIndex.toString();
@@ -287,8 +293,13 @@ export const PopsRightClickMenu = {
287
293
  * 限制的间隙距离
288
294
  */
289
295
  const limitDistance = 1;
290
- const maxPageLeftOffset = popsDOMUtils.width(globalThis) - limitDistance;
291
- const maxPageTopOffset = popsDOMUtils.height(globalThis) - limitDistance;
296
+ let maxPageLeftOffset = popsDOMUtils.width(globalThis) - limitDistance;
297
+ let maxPageTopOffset = popsDOMUtils.height(globalThis) - limitDistance;
298
+ if (config.position === "absolute") {
299
+ // 添加滚动距离
300
+ maxPageLeftOffset += globalThis.scrollX;
301
+ maxPageTopOffset += globalThis.scrollY;
302
+ }
292
303
  /* left最大偏移 */
293
304
  const maxLeftOffset = maxPageLeftOffset - menuElementWidth;
294
305
  /* top最大偏移 */
@@ -299,8 +310,10 @@ export const PopsRightClickMenu = {
299
310
  let currentLeftOffset = mousePosition.x;
300
311
  let currentTopOffset = mousePosition.y;
301
312
  currentLeftOffset = currentLeftOffset < 0 ? 0 : currentLeftOffset;
313
+ currentTopOffset = currentTopOffset < 0 ? 0 : currentTopOffset;
314
+
302
315
  // 不允许超出left最大值
303
- if (currentLeftOffset + chileMenuLeftOrRightDistance >= maxLeftOffset) {
316
+ if (config.limitPositionXInView && currentLeftOffset + chileMenuLeftOrRightDistance >= maxLeftOffset) {
304
317
  // 超过,那么子菜单将会在放在左边
305
318
  // 偏移计算方式就是父菜单的右偏移+父菜单的宽度
306
319
  if (parentInfo) {
@@ -326,8 +339,7 @@ export const PopsRightClickMenu = {
326
339
  Reflect.deleteProperty(result, "right");
327
340
  }
328
341
  // 不允许超出top最大值
329
- currentTopOffset = currentTopOffset < 0 ? 0 : currentTopOffset;
330
- if (currentTopOffset + childMenuTopOrBottomDistance >= maxTopOffset) {
342
+ if (config.limitPositionYInView && currentTopOffset + childMenuTopOrBottomDistance >= maxTopOffset) {
331
343
  // 超过,那么子菜单将会在放在上面
332
344
  if (parentInfo) {
333
345
  // 以项的top偏移为基准
@@ -347,6 +359,7 @@ export const PopsRightClickMenu = {
347
359
  Reflect.deleteProperty(result, "top");
348
360
  } else {
349
361
  currentTopOffset = currentTopOffset + childMenuTopOrBottomDistance;
362
+ // 底部偏移
350
363
  result.top = currentTopOffset;
351
364
  Reflect.deleteProperty(result, "bottom");
352
365
  }
@@ -358,7 +371,11 @@ export const PopsRightClickMenu = {
358
371
  * @param _config_
359
372
  * @param menuListenerRootNode 右键菜单监听的元素
360
373
  */
361
- showMenu(menuEvent: PointerEvent, _config_: PopsRightClickMenuDataDetails[], menuListenerRootNode: HTMLElement) {
374
+ showMenu(
375
+ menuEvent: PointerEvent,
376
+ _config_: PopsRightClickMenuDataDetails[],
377
+ menuListenerRootNode: NonNullable<PopsRightClickMenuDetails["target"]>
378
+ ) {
362
379
  const menuElement = this.createMenuContainerElement(false);
363
380
  Reflect.set(menuElement, "__menuData__", {
364
381
  child: [],
@@ -395,7 +412,7 @@ export const PopsRightClickMenu = {
395
412
  _config_: PopsRightClickMenuDataDetails[],
396
413
  rootElement: HTMLDivElement,
397
414
  targetLiElement: HTMLLIElement,
398
- menuListenerRootNode: HTMLElement
415
+ menuListenerRootNode: NonNullable<PopsRightClickMenuDetails["target"]>
399
416
  ) {
400
417
  const menuElement = this.createMenuContainerElement(true);
401
418
  Reflect.set(menuElement, "__menuData__", {
@@ -467,7 +484,7 @@ export const PopsRightClickMenu = {
467
484
  rootElement: HTMLDivElement,
468
485
  menuElement: HTMLDivElement,
469
486
  _config_: PopsRightClickMenuDataDetails[],
470
- menuListenerRootNode: HTMLElement
487
+ menuListenerRootNode: NonNullable<PopsRightClickMenuDetails["target"]>
471
488
  ) {
472
489
  const menuEventTarget = menuEvent.target;
473
490
  const menuULElement = menuElement.querySelector<HTMLUListElement>("ul")!;
@@ -592,11 +609,26 @@ export const PopsRightClickMenu = {
592
609
  PopsContextMenu.addWindowCheckClickListener();
593
610
  return {
594
611
  guid: guid,
595
- config: config,
596
- removeWindowCheckClickListener: PopsContextMenu.removeWindowCheckClickListener,
612
+ config: config as DeepRequired<PopsRightClickMenuDetails>,
597
613
  addWindowCheckClickListener: PopsContextMenu.addWindowCheckClickListener,
598
- removeContextMenuEvent: PopsContextMenu.removeContextMenuEvent,
614
+ removeWindowCheckClickListener: PopsContextMenu.removeWindowCheckClickListener,
599
615
  addContextMenuEvent: PopsContextMenu.addContextMenuEvent,
616
+ removeContextMenuEvent: PopsContextMenu.removeContextMenuEvent,
617
+ /**
618
+ * 移除初始化时的添加的监听事件
619
+ */
620
+ removeInitEventListener: {
621
+ contextMenu() {
622
+ PopsContextMenu.removeContextMenuEvent(config.target as Window, config.targetSelector!);
623
+ },
624
+ windowClick() {
625
+ PopsContextMenu.removeWindowCheckClickListener();
626
+ },
627
+ },
628
+ /**
629
+ * 操作弹出菜单的对象
630
+ */
631
+ PopsContextMenu: PopsContextMenu,
600
632
  };
601
633
  },
602
634
  };
@@ -35,7 +35,7 @@ export interface PopsRightClickMenuDataDetails {
35
35
  clickEvent: PointerEvent,
36
36
  contextMenuEvent: PointerEvent,
37
37
  liElement: HTMLLIElement,
38
- menuListenerRootNode: HTMLElement
38
+ menuListenerRootNode: NonNullable<PopsRightClickMenuDetails["target"]>
39
39
  ) => boolean | void | Promise<boolean | void>;
40
40
  /**
41
41
  * 子项配置
@@ -55,8 +55,14 @@ export interface PopsRightClickMenuDetails
55
55
  target?: HTMLElement | Window | EventTarget | Node;
56
56
  /**
57
57
  * 目标的子元素选择器,默认为空
58
+ * @default null
58
59
  */
59
60
  targetSelector?: string | null;
61
+ /**
62
+ * 位置
63
+ * @default "fixed"
64
+ */
65
+ position?: "absolute" | "fixed";
60
66
  /**
61
67
  * 右键菜单数据
62
68
  */
@@ -95,4 +101,14 @@ export interface PopsRightClickMenuDetails
95
101
  * @default false
96
102
  */
97
103
  preventDefault?: boolean;
104
+ /**
105
+ * 限制x位置在当前视窗内
106
+ * @default true
107
+ */
108
+ limitPositionXInView?: boolean;
109
+ /**
110
+ * 限制y位置在当前视窗内
111
+ * @default true
112
+ */
113
+ limitPositionYInView?: boolean;
98
114
  }