ph-utils 0.8.3 → 0.9.0
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/README.md +7 -7
- package/lib/array.js +3 -2
- package/lib/date.js +1 -3
- package/lib/index.d.ts +30 -12
- package/lib/index.js +2 -16
- package/lib/storage.d.ts +4 -4
- package/lib/storage.js +4 -4
- package/lib/theme.d.ts +42 -0
- package/lib/theme.js +136 -0
- package/package.json +5 -1
- package/lib/clipboard.d.ts +0 -11
- package/lib/clipboard.js +0 -101
package/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
## ph-utils
|
2
|
-
|
3
|
-
整理了 js 前后端开发(web + nodejs)时常用的一些工具;[详细文档](https://gitee.com/towardly/ph/wikis/Home?sort_id=4035190)
|
4
|
-
|
5
|
-
### 包含如下工具文件
|
6
|
-
|
7
|
-
`index` 基础工具类、`date` 跟日期相关的工具类、`file` 文件操作相关工具类[**服务端**]、`server` 服务端工具类、`validator` 数据验证、`dom` 浏览器节点操作相关[**前端**]、`web` 一些只适用于前端相关的工具、`color` 颜色相关工具
|
1
|
+
## ph-utils
|
2
|
+
|
3
|
+
整理了 js 前后端开发(web + nodejs)时常用的一些工具;[详细文档](https://gitee.com/towardly/ph/wikis/Home?sort_id=4035190)
|
4
|
+
|
5
|
+
### 包含如下工具文件
|
6
|
+
|
7
|
+
`index` 基础工具类、`date` 跟日期相关的工具类、`file` 文件操作相关工具类[**服务端**]、`server` 服务端工具类、`validator` 数据验证、`dom` 浏览器节点操作相关[**前端**]、`web` 一些只适用于前端相关的工具、`color` 颜色相关工具
|
package/lib/array.js
CHANGED
@@ -6,9 +6,10 @@
|
|
6
6
|
* @returns
|
7
7
|
*/
|
8
8
|
export function order(arr, order = "asc", orderKey = null) {
|
9
|
-
const collator = new Intl.Collator();
|
9
|
+
const collator = new Intl.Collator(undefined, { numeric: true });
|
10
10
|
return arr.sort((a, b) => {
|
11
|
-
let aValue = a
|
11
|
+
let aValue = a;
|
12
|
+
let bValue = b;
|
12
13
|
if (typeof a === "object" && orderKey != null) {
|
13
14
|
// @ts-ignore
|
14
15
|
aValue = a[orderKey];
|
package/lib/date.js
CHANGED
@@ -116,8 +116,6 @@ export function format(date, pattern = "yyyy-mm-dd HH:MM:ss") {
|
|
116
116
|
export function parse(date) {
|
117
117
|
if (date == null)
|
118
118
|
return new Date();
|
119
|
-
if (date instanceof Date)
|
120
|
-
return date;
|
121
119
|
if (typeof date === "string" && !/Z$/i.test(date)) {
|
122
120
|
const d = date.match(REGEX_PARSE);
|
123
121
|
if (d) {
|
@@ -127,7 +125,7 @@ export function parse(date) {
|
|
127
125
|
if (typeof date === "number") {
|
128
126
|
return new Date(date <= 9999999999 ? date * 1000 : date);
|
129
127
|
}
|
130
|
-
return new Date();
|
128
|
+
return new Date(date);
|
131
129
|
}
|
132
130
|
/**
|
133
131
|
* 设置日期的开始或者结束的点
|
package/lib/index.d.ts
CHANGED
@@ -29,37 +29,55 @@ export declare function isNumeric(str: string, numericParam?: {
|
|
29
29
|
*/
|
30
30
|
export declare function isBoolean(str: string): boolean;
|
31
31
|
/** 生成随机数的选项 */
|
32
|
-
interface
|
32
|
+
interface RandomStringOption {
|
33
33
|
/** 生成指定长度的随机字符串 */
|
34
|
-
length
|
34
|
+
length: number;
|
35
35
|
/** 是否包含英文字母, 默认为: true */
|
36
36
|
hasLetter?: boolean;
|
37
37
|
/** 生成纯数字的随机数时, 首位是否允许为 0, 默认为: true */
|
38
38
|
firstIsZero?: boolean;
|
39
|
+
}
|
40
|
+
interface RangeRandomOption {
|
39
41
|
/** 配合 max 生成 [min~max] 之间的随机数 */
|
40
|
-
min
|
42
|
+
min: number;
|
41
43
|
/** 配合 min 生成 [min~max] 之间的随机数 */
|
42
|
-
max
|
44
|
+
max: number;
|
43
45
|
/** 生成的随机数,是否包含 max, 默认: false */
|
44
46
|
hasEnd?: boolean;
|
45
47
|
/** 生成的随机数是否是整数, 默认: true */
|
46
48
|
isInteger?: boolean;
|
47
49
|
}
|
48
50
|
/**
|
49
|
-
*
|
50
|
-
*
|
51
|
-
*
|
52
|
-
* @param opts 生成随机数的配置
|
51
|
+
* 生成指定长度的随机数
|
52
|
+
*
|
53
|
+
* @param len - 生成的随机数长度
|
53
54
|
*
|
54
55
|
* @example <caption>1. 生成指定长度的随机字符串</caption>
|
55
56
|
* random(1); // 长度为 1 的随机字符串
|
57
|
+
*/
|
58
|
+
export declare function random(len: number): string;
|
59
|
+
/**
|
60
|
+
* 生成介于 [min, max] 之间的随机数
|
56
61
|
*
|
57
|
-
* @
|
58
|
-
*
|
62
|
+
* @param option 配置项
|
63
|
+
* @param option.min 生成介于 [min, max] 之间的随机数
|
64
|
+
* @param option.max 生成介于 [min, max] 之间的随机数
|
65
|
+
* @param option.hasEnd 生成的随机数,是否包含 max, 默认: false
|
66
|
+
* @param option.isInteger 生成的随机数是否是整数, 默认: true
|
67
|
+
*/
|
68
|
+
export declare function random(option: RangeRandomOption): number;
|
69
|
+
/**
|
70
|
+
* 生成指定长度随机数
|
59
71
|
*
|
60
|
-
* @
|
72
|
+
* @param option 配置项
|
73
|
+
* @param option.length 生成的随机数长度
|
74
|
+
* @param option.hasLetter 是否包含英文字母, 默认为: true
|
75
|
+
* @param option.firstIsZero 生成纯数字的随机数时, 首位是否允许为 0, 默认为: true
|
76
|
+
*
|
77
|
+
* @example <caption>2. 生成纯数字且首位不能为0长度为1的随机字符</caption>
|
78
|
+
* random({ length: 1, hasLetter: false, firstIsZero: false })
|
61
79
|
*/
|
62
|
-
export declare function random(
|
80
|
+
export declare function random(option: RandomStringOption): string;
|
63
81
|
/**
|
64
82
|
* 带有错误名称标记的错误类型
|
65
83
|
*/
|
package/lib/index.js
CHANGED
@@ -53,20 +53,6 @@ export function isNumeric(str, numericParam) {
|
|
53
53
|
export function isBoolean(str) {
|
54
54
|
return ["true", "false"].indexOf(str) >= 0;
|
55
55
|
}
|
56
|
-
/**
|
57
|
-
* 生成随机数
|
58
|
-
* 1. 生成指定长度的随机数
|
59
|
-
* 2. 生成介于 [min, max] 之间的随机数
|
60
|
-
* @param opts 生成随机数的配置
|
61
|
-
*
|
62
|
-
* @example <caption>1. 生成指定长度的随机字符串</caption>
|
63
|
-
* random(1); // 长度为 1 的随机字符串
|
64
|
-
*
|
65
|
-
* @example <caption>2. 生成纯数字且不能为0长度为1的随机字符</caption>
|
66
|
-
* random({ length: 1, hasLetter: false, firstIsZero: false })
|
67
|
-
*
|
68
|
-
* @returns
|
69
|
-
*/
|
70
56
|
export function random(opts) {
|
71
57
|
if (typeof opts === "object" && opts.min != null && opts.max != null) {
|
72
58
|
const randomNum = Math.random();
|
@@ -79,13 +65,13 @@ export function random(opts) {
|
|
79
65
|
if (typeof opts === "object" && opts.length == null) {
|
80
66
|
throw new Error("random_length_cannot_null");
|
81
67
|
}
|
82
|
-
|
68
|
+
let len = typeof opts === "object" ? opts.length : opts;
|
83
69
|
/* 生成指定长度的随机数 */
|
84
70
|
let chars = RANDOM_CHARS;
|
85
71
|
if (typeof opts === "object" && opts.hasLetter === false) {
|
86
72
|
chars = NUMBER_RANDOM_CHARTS;
|
87
73
|
}
|
88
|
-
const resRandom = Array.from({ length: len }, () => chars.charAt(random({ min: 0, max:
|
74
|
+
const resRandom = Array.from({ length: len }, () => chars.charAt(random({ min: 0, max: chars.length - 1, hasEnd: true }))).join("");
|
89
75
|
if (typeof opts === "object" &&
|
90
76
|
opts.firstIsZero === false &&
|
91
77
|
resRandom.indexOf("0") === 0) {
|
package/lib/storage.d.ts
CHANGED
@@ -11,8 +11,8 @@ interface StorageSetOption {
|
|
11
11
|
* 存储值到 Storage 中
|
12
12
|
* @param key 设置的 key
|
13
13
|
* @param value 设置的值
|
14
|
-
* @param storage session 或 local
|
15
|
-
* @param expire 数据有效期, 单位秒, 默认: -1 - 永久存储
|
14
|
+
* @param [option.storage] session 或 local, 默认: session
|
15
|
+
* @param [option.expire] 数据有效期, 单位秒, 默认: -1 - 永久存储
|
16
16
|
*/
|
17
17
|
export declare function set(key: string, value: any, option?: StorageSetOption): void;
|
18
18
|
/**
|
@@ -37,8 +37,8 @@ interface StorageQueryOption {
|
|
37
37
|
* 从 Storage 中取出数据
|
38
38
|
* @param key 保存时的 key
|
39
39
|
* @param defaultValue 没有数据时的默认值
|
40
|
-
* @param delete 是否在取出后,删除数据,默认:false - 取出后删除数据
|
41
|
-
* @param storage 使用的 Storage ,可以是 localStorage、sessionStorage
|
40
|
+
* @param [option.delete] 是否在取出后,删除数据,默认:false - 取出后删除数据
|
41
|
+
* @param [option.storage] 使用的 Storage ,可以是 localStorage、sessionStorage, 默认: localStorage、sessionStorage
|
42
42
|
* @returns Storage 中 key 对应的数据
|
43
43
|
*/
|
44
44
|
export declare function get<T>(key: string, defaultValue?: T, option?: StorageQueryOption): T;
|
package/lib/storage.js
CHANGED
@@ -5,8 +5,8 @@ function getStorage(storage = "session") {
|
|
5
5
|
* 存储值到 Storage 中
|
6
6
|
* @param key 设置的 key
|
7
7
|
* @param value 设置的值
|
8
|
-
* @param storage session 或 local
|
9
|
-
* @param expire 数据有效期, 单位秒, 默认: -1 - 永久存储
|
8
|
+
* @param [option.storage] session 或 local, 默认: session
|
9
|
+
* @param [option.expire] 数据有效期, 单位秒, 默认: -1 - 永久存储
|
10
10
|
*/
|
11
11
|
export function set(key, value, option) {
|
12
12
|
const opts = {
|
@@ -40,8 +40,8 @@ export function remove(key, storage) {
|
|
40
40
|
* 从 Storage 中取出数据
|
41
41
|
* @param key 保存时的 key
|
42
42
|
* @param defaultValue 没有数据时的默认值
|
43
|
-
* @param delete 是否在取出后,删除数据,默认:false - 取出后删除数据
|
44
|
-
* @param storage 使用的 Storage ,可以是 localStorage、sessionStorage
|
43
|
+
* @param [option.delete] 是否在取出后,删除数据,默认:false - 取出后删除数据
|
44
|
+
* @param [option.storage] 使用的 Storage ,可以是 localStorage、sessionStorage, 默认: localStorage、sessionStorage
|
45
45
|
* @returns Storage 中 key 对应的数据
|
46
46
|
*/
|
47
47
|
export function get(key, defaultValue, option) {
|
package/lib/theme.d.ts
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
/** 获取当前系统的主题 */
|
2
|
+
export declare function getSystemTheme(): "dark" | "light";
|
3
|
+
/**
|
4
|
+
* 初始化主题, 让网页能够适应系统主题, 同时根据缓存的主题切换主题
|
5
|
+
* @returns 当前应用的主题
|
6
|
+
*/
|
7
|
+
export declare function initTheme(): Promise<"dark" | "light">;
|
8
|
+
/**
|
9
|
+
* 切换主题, 通常用于预览
|
10
|
+
* @param theme 切换的主题
|
11
|
+
* @returns 切换后的主题
|
12
|
+
*/
|
13
|
+
export declare function toggleTheme(theme?: "light" | "dark" | "auto"): Promise<"dark" | "light">;
|
14
|
+
/** 获取当前主题 */
|
15
|
+
export declare function getTheme(): string;
|
16
|
+
/**
|
17
|
+
* 应用主题
|
18
|
+
* @param theme 待应用的主题
|
19
|
+
* @param cache 是否缓存应用的主题, 让应用下一次启动的时候, 可以应用主题, 默认: true
|
20
|
+
* @returns 应用的主题
|
21
|
+
*/
|
22
|
+
export declare function applyTheme(theme?: "light" | "dark" | "auto", cache?: boolean): Promise<"dark" | "light">;
|
23
|
+
/** 获取当前主题色 */
|
24
|
+
export declare function getColorTheme(defaultValue?: string): string | undefined;
|
25
|
+
/**
|
26
|
+
* 初始化主题色, 让网页能够适应系统主题色, 同时根据缓存的主题色切换主题色
|
27
|
+
* @returns 当前应用的主题色
|
28
|
+
*/
|
29
|
+
export declare function initColorTheme(): Promise<string> | null;
|
30
|
+
/**
|
31
|
+
* 切换主题色, 通常用于预览
|
32
|
+
* @param color 待切换的主题色
|
33
|
+
* @returns 切换后的主题色
|
34
|
+
*/
|
35
|
+
export declare function toggleColorTheme(color: string): Promise<string>;
|
36
|
+
/**
|
37
|
+
* 应用主题色
|
38
|
+
* @param color 主题色
|
39
|
+
* @param cache 是否缓存主题色, 让应用下一次启动的时候, 可以应用主题色, 默认: true
|
40
|
+
* @returns 切换后的主题色
|
41
|
+
*/
|
42
|
+
export declare function applyColorTheme(color: string, cache?: boolean): Promise<string>;
|
package/lib/theme.js
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
import { adjust } from "./color.js";
|
2
|
+
/** 获取当前系统的主题 */
|
3
|
+
export function getSystemTheme() {
|
4
|
+
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
5
|
+
return "dark";
|
6
|
+
}
|
7
|
+
return "light";
|
8
|
+
}
|
9
|
+
/**
|
10
|
+
* 初始化主题, 让网页能够适应系统主题, 同时根据缓存的主题切换主题
|
11
|
+
* @returns 当前应用的主题
|
12
|
+
*/
|
13
|
+
export async function initTheme() {
|
14
|
+
// 让网页能够适应系统主题
|
15
|
+
let $themeStyle = document.getElementById("theme-style");
|
16
|
+
if ($themeStyle == null) {
|
17
|
+
$themeStyle = document.createElement("style");
|
18
|
+
$themeStyle.id = "theme-style";
|
19
|
+
$themeStyle.innerHTML = `
|
20
|
+
:root{color-scheme:light dark;}
|
21
|
+
html.light{color-scheme: light;}
|
22
|
+
html.dark {color-scheme: dark;}
|
23
|
+
`;
|
24
|
+
document.head.appendChild($themeStyle);
|
25
|
+
}
|
26
|
+
// 获取已经应用的主题设置
|
27
|
+
const cacheTheme = localStorage.getItem("web-theme-appearance");
|
28
|
+
return toggleTheme(cacheTheme);
|
29
|
+
}
|
30
|
+
/**
|
31
|
+
* 切换主题, 通常用于预览
|
32
|
+
* @param theme 切换的主题
|
33
|
+
* @returns 切换后的主题
|
34
|
+
*/
|
35
|
+
export async function toggleTheme(theme) {
|
36
|
+
if (theme !== "light" && theme !== "dark") {
|
37
|
+
theme = getSystemTheme();
|
38
|
+
}
|
39
|
+
const classList = document.documentElement.classList;
|
40
|
+
if (theme === "light") {
|
41
|
+
classList.add("light");
|
42
|
+
classList.remove("dark");
|
43
|
+
}
|
44
|
+
else if (theme === "dark") {
|
45
|
+
classList.add("dark");
|
46
|
+
classList.remove("light");
|
47
|
+
}
|
48
|
+
return theme;
|
49
|
+
}
|
50
|
+
/** 获取当前主题 */
|
51
|
+
export function getTheme() {
|
52
|
+
// 1. 从根节点获取
|
53
|
+
let theme = document.documentElement.className.match(/light|dark/);
|
54
|
+
if (theme != null) {
|
55
|
+
theme = theme[0];
|
56
|
+
}
|
57
|
+
if (theme == null) {
|
58
|
+
theme = localStorage.getItem("web-theme-appearance");
|
59
|
+
}
|
60
|
+
if (theme == null) {
|
61
|
+
theme = getSystemTheme();
|
62
|
+
}
|
63
|
+
return theme;
|
64
|
+
}
|
65
|
+
/**
|
66
|
+
* 应用主题
|
67
|
+
* @param theme 待应用的主题
|
68
|
+
* @param cache 是否缓存应用的主题, 让应用下一次启动的时候, 可以应用主题, 默认: true
|
69
|
+
* @returns 应用的主题
|
70
|
+
*/
|
71
|
+
export async function applyTheme(theme, cache = true) {
|
72
|
+
if (cache === true) {
|
73
|
+
localStorage.setItem("web-theme-appearance", theme == null ? "auto" : theme);
|
74
|
+
}
|
75
|
+
return toggleTheme(theme);
|
76
|
+
}
|
77
|
+
/** 获取当前主题色 */
|
78
|
+
export function getColorTheme(defaultValue) {
|
79
|
+
const root = document.documentElement;
|
80
|
+
const match = root.className.match(/color-([0-9a-fA-F]{6})/);
|
81
|
+
if (match == null) {
|
82
|
+
// 获取 --nt-primary-color 的值
|
83
|
+
let color = getComputedStyle(root).getPropertyValue("--nt-primary-color");
|
84
|
+
if (color === "") {
|
85
|
+
color = localStorage.getItem("web-theme-color");
|
86
|
+
}
|
87
|
+
return color ? color : defaultValue;
|
88
|
+
}
|
89
|
+
return `#${match[1]}`;
|
90
|
+
}
|
91
|
+
/**
|
92
|
+
* 初始化主题色, 让网页能够适应系统主题色, 同时根据缓存的主题色切换主题色
|
93
|
+
* @returns 当前应用的主题色
|
94
|
+
*/
|
95
|
+
export function initColorTheme() {
|
96
|
+
// 获取缓存主题色
|
97
|
+
const color = localStorage.getItem("web-theme-color");
|
98
|
+
if (color != null) {
|
99
|
+
return toggleColorTheme(color);
|
100
|
+
}
|
101
|
+
return color;
|
102
|
+
}
|
103
|
+
/**
|
104
|
+
* 切换主题色, 通常用于预览
|
105
|
+
* @param color 待切换的主题色
|
106
|
+
* @returns 切换后的主题色
|
107
|
+
*/
|
108
|
+
export async function toggleColorTheme(color) {
|
109
|
+
const vars = [
|
110
|
+
`--nt-primary-color: ${color};`,
|
111
|
+
`--nt-primary-color-dark1: ${adjust(color, 1, false)};`,
|
112
|
+
];
|
113
|
+
for (let i = 1; i <= 5; i++) {
|
114
|
+
vars.push(`--nt-primary-color-light${i}: ${adjust(color, i)};`);
|
115
|
+
}
|
116
|
+
let $style = document.getElementById("color-theme-style");
|
117
|
+
if ($style == null) {
|
118
|
+
$style = document.createElement("style");
|
119
|
+
$style.id = "color-theme-style";
|
120
|
+
document.head.appendChild($style);
|
121
|
+
}
|
122
|
+
$style.innerHTML = `:root{${vars.join("")}}`;
|
123
|
+
return color;
|
124
|
+
}
|
125
|
+
/**
|
126
|
+
* 应用主题色
|
127
|
+
* @param color 主题色
|
128
|
+
* @param cache 是否缓存主题色, 让应用下一次启动的时候, 可以应用主题色, 默认: true
|
129
|
+
* @returns 切换后的主题色
|
130
|
+
*/
|
131
|
+
export function applyColorTheme(color, cache = true) {
|
132
|
+
if (cache === true) {
|
133
|
+
localStorage.setItem("web-theme-color", color.substring(1));
|
134
|
+
}
|
135
|
+
return toggleColorTheme(color);
|
136
|
+
}
|
package/package.json
CHANGED
@@ -58,9 +58,13 @@
|
|
58
58
|
"types": "./lib/array.d.ts",
|
59
59
|
"import": "./lib/array.js"
|
60
60
|
},
|
61
|
+
"./theme": {
|
62
|
+
"types": "./lib/theme.d.ts",
|
63
|
+
"import": "./lib/theme.js"
|
64
|
+
},
|
61
65
|
"./*": "./lib/*"
|
62
66
|
},
|
63
|
-
"version": "0.
|
67
|
+
"version": "0.9.0",
|
64
68
|
"type": "module",
|
65
69
|
"repository": {
|
66
70
|
"type": "git",
|
package/lib/clipboard.d.ts
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* 复制数据, 可以从多种类型的数据
|
3
|
-
* 1. 直接复制文本: await copy("待复制的文本")
|
4
|
-
* 2. 复制节点上的 data-copy-text:
|
5
|
-
* <button data-copy-text="这是待复制的文本">复制</button>
|
6
|
-
* await copy(e.target) // or await copy("#a") or await copy(document.querySelector('#a'))
|
7
|
-
* 3. 直接复制节点本身数据: await copy('#a')
|
8
|
-
* @param {string | HTMLElement} source 复制源, 从中解析待复制的数据
|
9
|
-
* @returns {Promise<boolean>} 是否复制成功
|
10
|
-
*/
|
11
|
-
export declare function copy(source: string | HTMLElement): Promise<boolean>;
|
package/lib/clipboard.js
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* 创建一个临时节点缓存待复制数据
|
3
|
-
* @param {String} value - 待复制文本
|
4
|
-
* @return {HTMLElement}
|
5
|
-
*/
|
6
|
-
function createFakeElement(value) {
|
7
|
-
const fakeElement = document.createElement("textarea");
|
8
|
-
fakeElement.style.border = "0";
|
9
|
-
fakeElement.style.padding = "0";
|
10
|
-
fakeElement.style.margin = "0";
|
11
|
-
fakeElement.style.position = "absolute";
|
12
|
-
fakeElement.style.left = "-9999px";
|
13
|
-
fakeElement.style.top = "-9999";
|
14
|
-
fakeElement.setAttribute("readonly", "");
|
15
|
-
fakeElement.value = value;
|
16
|
-
return fakeElement;
|
17
|
-
}
|
18
|
-
/** 通过执行 execCommand 来执行复制 */
|
19
|
-
function copyFromCommand(text) {
|
20
|
-
// 添加节点
|
21
|
-
const fakeEl = createFakeElement(text);
|
22
|
-
document.body.append(fakeEl);
|
23
|
-
fakeEl.focus();
|
24
|
-
fakeEl.select();
|
25
|
-
// 执行复制
|
26
|
-
const res = document.execCommand("copy");
|
27
|
-
fakeEl.remove(); // 删除节点
|
28
|
-
return Promise.resolve(res);
|
29
|
-
}
|
30
|
-
/** 使用 navigator.clipboard 复制 */
|
31
|
-
function copyFromClipboard(text) {
|
32
|
-
const theClipboard = navigator.clipboard;
|
33
|
-
if (theClipboard != null) {
|
34
|
-
return theClipboard
|
35
|
-
.writeText(text)
|
36
|
-
.then(() => {
|
37
|
-
Promise.resolve(true);
|
38
|
-
})
|
39
|
-
.catch(() => Promise.resolve(false));
|
40
|
-
}
|
41
|
-
return Promise.resolve(false);
|
42
|
-
}
|
43
|
-
/** 解析待复制的文本 */
|
44
|
-
function parseCopyText(source) {
|
45
|
-
let copyText = null; // 待复制文本
|
46
|
-
let sourceEl = null;
|
47
|
-
// 获取待复制数据
|
48
|
-
if (typeof source === "string") {
|
49
|
-
// 从节点拿数据
|
50
|
-
if (source.startsWith("#") || source.startsWith(".")) {
|
51
|
-
sourceEl = document.querySelector(source);
|
52
|
-
if (sourceEl == null) {
|
53
|
-
copyText = source;
|
54
|
-
}
|
55
|
-
}
|
56
|
-
else {
|
57
|
-
copyText = source;
|
58
|
-
}
|
59
|
-
}
|
60
|
-
if (source instanceof HTMLElement) {
|
61
|
-
sourceEl = source;
|
62
|
-
}
|
63
|
-
// 从节点获取待复制数据
|
64
|
-
if (sourceEl != null) {
|
65
|
-
if (sourceEl.hasAttribute("data-copy-text")) {
|
66
|
-
copyText = sourceEl.getAttribute("data-copy-text");
|
67
|
-
}
|
68
|
-
else {
|
69
|
-
const tagName = sourceEl.tagName;
|
70
|
-
if (tagName === "INPUT" || tagName === "TEXTAREA") {
|
71
|
-
copyText = sourceEl.value;
|
72
|
-
}
|
73
|
-
else {
|
74
|
-
copyText = sourceEl.textContent;
|
75
|
-
}
|
76
|
-
}
|
77
|
-
}
|
78
|
-
return copyText;
|
79
|
-
}
|
80
|
-
/**
|
81
|
-
* 复制数据, 可以从多种类型的数据
|
82
|
-
* 1. 直接复制文本: await copy("待复制的文本")
|
83
|
-
* 2. 复制节点上的 data-copy-text:
|
84
|
-
* <button data-copy-text="这是待复制的文本">复制</button>
|
85
|
-
* await copy(e.target) // or await copy("#a") or await copy(document.querySelector('#a'))
|
86
|
-
* 3. 直接复制节点本身数据: await copy('#a')
|
87
|
-
* @param {string | HTMLElement} source 复制源, 从中解析待复制的数据
|
88
|
-
* @returns {Promise<boolean>} 是否复制成功
|
89
|
-
*/
|
90
|
-
export async function copy(source) {
|
91
|
-
// 待复制文本
|
92
|
-
const copyText = parseCopyText(source);
|
93
|
-
if (copyText == null) {
|
94
|
-
return Promise.resolve(false);
|
95
|
-
}
|
96
|
-
const v = await copyFromClipboard(copyText);
|
97
|
-
if (v === false) {
|
98
|
-
return copyFromCommand(copyText);
|
99
|
-
}
|
100
|
-
return Promise.resolve(true);
|
101
|
-
}
|