@widget-js/core 0.0.6 → 0.0.8
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/cjs/api/ElectronApi.js +73 -53
- package/dist/cjs/api/Keys.js +11 -0
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/model/BroadcastEvent.js +12 -0
- package/dist/cjs/model/SocialInfo.js +10 -0
- package/dist/cjs/model/Widget.js +60 -29
- package/dist/cjs/model/WidgetData.js +16 -0
- package/dist/cjs/model/WidgetParams.js +143 -0
- package/dist/cjs/repository/WidgetDataRepository.js +88 -0
- package/dist/cjs/router/encoding.js +144 -0
- package/dist/cjs/router/query.js +107 -0
- package/dist/esm/api/ElectronApi.js +73 -54
- package/dist/esm/api/Keys.js +7 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/model/BroadcastEvent.js +8 -0
- package/dist/esm/model/SocialInfo.js +6 -0
- package/dist/esm/model/Widget.js +60 -30
- package/dist/esm/model/WidgetData.js +12 -0
- package/dist/esm/model/WidgetParams.js +139 -0
- package/dist/esm/repository/WidgetDataRepository.js +81 -0
- package/dist/esm/router/encoding.js +135 -0
- package/dist/esm/router/query.js +101 -0
- package/dist/types/api/ElectronApi.d.ts +8 -0
- package/dist/types/api/Keys.d.ts +7 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/model/BroadcastEvent.d.ts +7 -0
- package/dist/types/model/SocialInfo.d.ts +6 -0
- package/dist/types/model/Widget.d.ts +47 -5
- package/dist/types/model/WidgetData.d.ts +35 -0
- package/dist/types/model/WidgetParams.d.ts +63 -0
- package/dist/types/repository/WidgetDataRepository.d.ts +27 -0
- package/dist/types/router/encoding.d.ts +62 -0
- package/dist/types/router/query.d.ts +62 -0
- package/dist/umd/index.js +2 -1
- package/dist/umd/index.js.LICENSE.txt +6 -0
- package/package.json +7 -4
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组件参数,如宽,高,id,语言等环境参数
|
|
3
|
+
*/
|
|
4
|
+
import { parseQuery } from "../router/query";
|
|
5
|
+
export class WidgetParams {
|
|
6
|
+
/**
|
|
7
|
+
* 将组件参数转为url参数
|
|
8
|
+
* @param object
|
|
9
|
+
* @return URLSearchParams w_w=2&w_h=2&w_id=21&w_width=156&w_height=156
|
|
10
|
+
*/
|
|
11
|
+
toUrlParams() {
|
|
12
|
+
const urlParams = new URLSearchParams();
|
|
13
|
+
const ownPropertyNames = Object.getOwnPropertyNames(this);
|
|
14
|
+
for (let ownPropertyName of ownPropertyNames) {
|
|
15
|
+
const key = ownPropertyName;
|
|
16
|
+
const value = this[key];
|
|
17
|
+
if (value) {
|
|
18
|
+
urlParams.append(WidgetParams.PARAM_PREFIX + ownPropertyName, value.toString());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return urlParams;
|
|
22
|
+
}
|
|
23
|
+
getPersistKey() {
|
|
24
|
+
return `${this.name}-${this.id}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 从当前地址解析组件参数:
|
|
28
|
+
* http://localhost:8080/#/widget/config/labor_progress?w_w=2&w_h=2&w_width=156&w_height=156
|
|
29
|
+
* =>
|
|
30
|
+
* {w:2,h:2,id:21,width:156,height:156}
|
|
31
|
+
*/
|
|
32
|
+
static fromCurrentLocation() {
|
|
33
|
+
const href = window.location.href;
|
|
34
|
+
let queryString = href.split("?")[1];
|
|
35
|
+
return this.fromObject(parseQuery(queryString));
|
|
36
|
+
}
|
|
37
|
+
static setValue(widgetEnv, key, value) {
|
|
38
|
+
const keyWithoutPrefix = key.replace(this.PARAM_PREFIX, "");
|
|
39
|
+
if (keyWithoutPrefix == WidgetParams.PARAM_ID) {
|
|
40
|
+
widgetEnv.id = value;
|
|
41
|
+
}
|
|
42
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_X) {
|
|
43
|
+
widgetEnv.x = parseInt(value);
|
|
44
|
+
}
|
|
45
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_Y) {
|
|
46
|
+
widgetEnv.y = parseInt(value);
|
|
47
|
+
}
|
|
48
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_H) {
|
|
49
|
+
widgetEnv.h = parseInt(value);
|
|
50
|
+
}
|
|
51
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_W) {
|
|
52
|
+
widgetEnv.w = parseInt(value);
|
|
53
|
+
}
|
|
54
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_LANG) {
|
|
55
|
+
widgetEnv.lang = value;
|
|
56
|
+
}
|
|
57
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_THEME) {
|
|
58
|
+
widgetEnv.theme = value;
|
|
59
|
+
}
|
|
60
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_MODE) {
|
|
61
|
+
widgetEnv.mode = parseInt(value);
|
|
62
|
+
}
|
|
63
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_RADIUS) {
|
|
64
|
+
widgetEnv.radius = parseInt(value);
|
|
65
|
+
}
|
|
66
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_WIDTH) {
|
|
67
|
+
widgetEnv.width = parseInt(value);
|
|
68
|
+
}
|
|
69
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_HEIGHT) {
|
|
70
|
+
widgetEnv.height = parseInt(value);
|
|
71
|
+
}
|
|
72
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_NAME) {
|
|
73
|
+
widgetEnv.name = value;
|
|
74
|
+
}
|
|
75
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_TITLE) {
|
|
76
|
+
widgetEnv.title = value;
|
|
77
|
+
}
|
|
78
|
+
else if (keyWithoutPrefix == WidgetParams.PARAM_PREVIEW) {
|
|
79
|
+
widgetEnv.preview = (value === 'true');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 从对象键值对中初始化组件参数
|
|
84
|
+
* {w_w:2,w_h:2,w_id:21,w_width:156,w_height:156}=>
|
|
85
|
+
* {w:2,h:2,id:21,width:156,height:156}
|
|
86
|
+
* @param object
|
|
87
|
+
*/
|
|
88
|
+
static fromObject(object) {
|
|
89
|
+
const widgetEnv = new WidgetParams();
|
|
90
|
+
const ownPropertyNames = Object.getOwnPropertyNames(object);
|
|
91
|
+
for (let ownPropertyName of ownPropertyNames) {
|
|
92
|
+
const key = ownPropertyName;
|
|
93
|
+
const value = object[key];
|
|
94
|
+
this.setValue(widgetEnv, key, value);
|
|
95
|
+
}
|
|
96
|
+
return widgetEnv;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
WidgetParams.PARAM_PREFIX = "w_";
|
|
100
|
+
WidgetParams.PARAM_ID = "id";
|
|
101
|
+
WidgetParams.PARAM_W = "w";
|
|
102
|
+
WidgetParams.PARAM_H = "h";
|
|
103
|
+
WidgetParams.PARAM_WIDTH = "width";
|
|
104
|
+
WidgetParams.PARAM_HEIGHT = "height";
|
|
105
|
+
WidgetParams.PARAM_X = "x";
|
|
106
|
+
WidgetParams.PARAM_Y = "y";
|
|
107
|
+
WidgetParams.PARAM_LANG = "lang";
|
|
108
|
+
WidgetParams.PARAM_THEME = "theme";
|
|
109
|
+
WidgetParams.PARAM_MODE = "mode";
|
|
110
|
+
WidgetParams.PARAM_RADIUS = "radius";
|
|
111
|
+
WidgetParams.PARAM_NAME = "name";
|
|
112
|
+
WidgetParams.PARAM_TITLE = "title";
|
|
113
|
+
WidgetParams.PARAM_PREVIEW = "preview";
|
|
114
|
+
WidgetParams.PARAMS = [
|
|
115
|
+
WidgetParams.PARAM_ID,
|
|
116
|
+
WidgetParams.PARAM_W,
|
|
117
|
+
WidgetParams.PARAM_H,
|
|
118
|
+
WidgetParams.PARAM_X,
|
|
119
|
+
WidgetParams.PARAM_Y,
|
|
120
|
+
WidgetParams.PARAM_LANG,
|
|
121
|
+
WidgetParams.PARAM_THEME,
|
|
122
|
+
WidgetParams.PARAM_MODE,
|
|
123
|
+
WidgetParams.PARAM_WIDTH,
|
|
124
|
+
WidgetParams.PARAM_HEIGHT,
|
|
125
|
+
WidgetParams.PARAM_NAME,
|
|
126
|
+
WidgetParams.PARAM_TITLE,
|
|
127
|
+
WidgetParams.PARAM_PREVIEW,
|
|
128
|
+
];
|
|
129
|
+
export var ThemeMode;
|
|
130
|
+
(function (ThemeMode) {
|
|
131
|
+
ThemeMode["AUTO"] = "auto";
|
|
132
|
+
ThemeMode["LIGHT"] = "LIGHT";
|
|
133
|
+
ThemeMode["DARK"] = "DARK";
|
|
134
|
+
})(ThemeMode || (ThemeMode = {}));
|
|
135
|
+
export var WidgetHostMode;
|
|
136
|
+
(function (WidgetHostMode) {
|
|
137
|
+
WidgetHostMode[WidgetHostMode["DEFAULT"] = 0] = "DEFAULT";
|
|
138
|
+
WidgetHostMode[WidgetHostMode["OVERLAP"] = 1] = "OVERLAP";
|
|
139
|
+
})(WidgetHostMode || (WidgetHostMode = {}));
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import localforage from "localforage";
|
|
11
|
+
import { BroadcastEvent } from "../model/BroadcastEvent";
|
|
12
|
+
import { ElectronApi } from "../api/ElectronApi";
|
|
13
|
+
export class WidgetDataRepository {
|
|
14
|
+
/**
|
|
15
|
+
* 保存组件数据
|
|
16
|
+
* @param data
|
|
17
|
+
*/
|
|
18
|
+
static save(data) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
let store = this.getStore(data.name);
|
|
21
|
+
const result = yield store.setItem(this.getKey(data.name, data.id), JSON.stringify(data));
|
|
22
|
+
const broadcastEvent = new BroadcastEvent(BroadcastEvent.TYPE_WIDGET_UPDATED, "", data);
|
|
23
|
+
yield ElectronApi.sendBroadcastEvent(broadcastEvent);
|
|
24
|
+
return result;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 获取组件 LocalForage 存储实例
|
|
29
|
+
* @param name
|
|
30
|
+
*/
|
|
31
|
+
static getStore(name) {
|
|
32
|
+
if (this.stores.has(name)) {
|
|
33
|
+
return this.stores.get(name);
|
|
34
|
+
}
|
|
35
|
+
const store = localforage.createInstance({ name: name });
|
|
36
|
+
this.stores.set(name, store);
|
|
37
|
+
return store;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 通过组件名保存组件信息,通常用于存储可以在同类组件中共用的数据
|
|
41
|
+
* @param name
|
|
42
|
+
* @param json
|
|
43
|
+
*/
|
|
44
|
+
static saveByName(name, json) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
let store = this.getStore(name);
|
|
47
|
+
const result = yield store.setItem(name, json);
|
|
48
|
+
const broadcastEvent = new BroadcastEvent(BroadcastEvent.TYPE_WIDGET_UPDATED, "", { name, json });
|
|
49
|
+
yield ElectronApi.sendBroadcastEvent(broadcastEvent);
|
|
50
|
+
return result;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
static findWithName(name, type) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
let store = this.getStore(name);
|
|
56
|
+
let result = yield store.getItem(name);
|
|
57
|
+
if (result) {
|
|
58
|
+
const widgetData = new type(name);
|
|
59
|
+
widgetData.parseJSON(JSON.parse(result));
|
|
60
|
+
return widgetData;
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
static find(name, id, type) {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
let store = this.getStore(name);
|
|
68
|
+
let result = yield store.getItem(this.getKey(name, id));
|
|
69
|
+
if (result) {
|
|
70
|
+
const widgetData = new type(name, id);
|
|
71
|
+
widgetData.parseJSON(JSON.parse(result));
|
|
72
|
+
return widgetData;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
static getKey(name, id) {
|
|
78
|
+
return `${name}@${id}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
WidgetDataRepository.stores = new Map();
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encoding Rules ␣ = Space Path: ␣ " < > # ? { } Query: ␣ " < > # & = Hash: ␣ "
|
|
3
|
+
* < > `
|
|
4
|
+
*
|
|
5
|
+
* On top of that, the RFC3986 (https://tools.ietf.org/html/rfc3986#section-2.2)
|
|
6
|
+
* defines some extra characters to be encoded. Most browsers do not encode them
|
|
7
|
+
* in encodeURI https://github.com/whatwg/url/issues/369, so it may be safer to
|
|
8
|
+
* also encode `!'()*`. Leaving un-encoded only ASCII alphanumeric(`a-zA-Z0-9`)
|
|
9
|
+
* plus `-._~`. This extra safety should be applied to query by patching the
|
|
10
|
+
* string returned by encodeURIComponent encodeURI also encodes `[\]^`. `\`
|
|
11
|
+
* should be encoded to avoid ambiguity. Browsers (IE, FF, C) transform a `\`
|
|
12
|
+
* into a `/` if directly typed in. The _backtick_ (`````) should also be
|
|
13
|
+
* encoded everywhere because some browsers like FF encode it when directly
|
|
14
|
+
* written while others don't. Safari and IE don't encode ``"<>{}``` in hash.
|
|
15
|
+
*/
|
|
16
|
+
// const EXTRA_RESERVED_RE = /[!'()*]/g
|
|
17
|
+
// const encodeReservedReplacer = (c: string) => '%' + c.charCodeAt(0).toString(16)
|
|
18
|
+
const HASH_RE = /#/g; // %23
|
|
19
|
+
const AMPERSAND_RE = /&/g; // %26
|
|
20
|
+
const SLASH_RE = /\//g; // %2F
|
|
21
|
+
const EQUAL_RE = /=/g; // %3D
|
|
22
|
+
const IM_RE = /\?/g; // %3F
|
|
23
|
+
export const PLUS_RE = /\+/g; // %2B
|
|
24
|
+
/**
|
|
25
|
+
* NOTE: It's not clear to me if we should encode the + symbol in queries, it
|
|
26
|
+
* seems to be less flexible than not doing so and I can't find out the legacy
|
|
27
|
+
* systems requiring this for regular requests like text/html. In the standard,
|
|
28
|
+
* the encoding of the plus character is only mentioned for
|
|
29
|
+
* application/x-www-form-urlencoded
|
|
30
|
+
* (https://url.spec.whatwg.org/#urlencoded-parsing) and most browsers seems lo
|
|
31
|
+
* leave the plus character as is in queries. To be more flexible, we allow the
|
|
32
|
+
* plus character on the query, but it can also be manually encoded by the user.
|
|
33
|
+
*
|
|
34
|
+
* Resources:
|
|
35
|
+
* - https://url.spec.whatwg.org/#urlencoded-parsing
|
|
36
|
+
* - https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20
|
|
37
|
+
*/
|
|
38
|
+
const ENC_BRACKET_OPEN_RE = /%5B/g; // [
|
|
39
|
+
const ENC_BRACKET_CLOSE_RE = /%5D/g; // ]
|
|
40
|
+
const ENC_CARET_RE = /%5E/g; // ^
|
|
41
|
+
const ENC_BACKTICK_RE = /%60/g; // `
|
|
42
|
+
const ENC_CURLY_OPEN_RE = /%7B/g; // {
|
|
43
|
+
const ENC_PIPE_RE = /%7C/g; // |
|
|
44
|
+
const ENC_CURLY_CLOSE_RE = /%7D/g; // }
|
|
45
|
+
const ENC_SPACE_RE = /%20/g; // }
|
|
46
|
+
/**
|
|
47
|
+
* Encode characters that need to be encoded on the path, search and hash
|
|
48
|
+
* sections of the URL.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
* @param text - string to encode
|
|
52
|
+
* @returns encoded string
|
|
53
|
+
*/
|
|
54
|
+
function commonEncode(text) {
|
|
55
|
+
return encodeURI('' + text)
|
|
56
|
+
.replace(ENC_PIPE_RE, '|')
|
|
57
|
+
.replace(ENC_BRACKET_OPEN_RE, '[')
|
|
58
|
+
.replace(ENC_BRACKET_CLOSE_RE, ']');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Encode characters that need to be encoded on the hash section of the URL.
|
|
62
|
+
*
|
|
63
|
+
* @param text - string to encode
|
|
64
|
+
* @returns encoded string
|
|
65
|
+
*/
|
|
66
|
+
export function encodeHash(text) {
|
|
67
|
+
return commonEncode(text)
|
|
68
|
+
.replace(ENC_CURLY_OPEN_RE, '{')
|
|
69
|
+
.replace(ENC_CURLY_CLOSE_RE, '}')
|
|
70
|
+
.replace(ENC_CARET_RE, '^');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Encode characters that need to be encoded query values on the query
|
|
74
|
+
* section of the URL.
|
|
75
|
+
*
|
|
76
|
+
* @param text - string to encode
|
|
77
|
+
* @returns encoded string
|
|
78
|
+
*/
|
|
79
|
+
export function encodeQueryValue(text) {
|
|
80
|
+
return (commonEncode(text)
|
|
81
|
+
// Encode the space as +, encode the + to differentiate it from the space
|
|
82
|
+
.replace(PLUS_RE, '%2B')
|
|
83
|
+
.replace(ENC_SPACE_RE, '+')
|
|
84
|
+
.replace(HASH_RE, '%23')
|
|
85
|
+
.replace(AMPERSAND_RE, '%26')
|
|
86
|
+
.replace(ENC_BACKTICK_RE, '`')
|
|
87
|
+
.replace(ENC_CURLY_OPEN_RE, '{')
|
|
88
|
+
.replace(ENC_CURLY_CLOSE_RE, '}')
|
|
89
|
+
.replace(ENC_CARET_RE, '^'));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Like `encodeQueryValue` but also encodes the `=` character.
|
|
93
|
+
*
|
|
94
|
+
* @param text - string to encode
|
|
95
|
+
*/
|
|
96
|
+
export function encodeQueryKey(text) {
|
|
97
|
+
return encodeQueryValue(text).replace(EQUAL_RE, '%3D');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Encode characters that need to be encoded on the path section of the URL.
|
|
101
|
+
*
|
|
102
|
+
* @param text - string to encode
|
|
103
|
+
* @returns encoded string
|
|
104
|
+
*/
|
|
105
|
+
export function encodePath(text) {
|
|
106
|
+
return commonEncode(text).replace(HASH_RE, '%23').replace(IM_RE, '%3F');
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Encode characters that need to be encoded on the path section of the URL as a
|
|
110
|
+
* param. This function encodes everything {@link encodePath} does plus the
|
|
111
|
+
* slash (`/`) character. If `text` is `null` or `undefined`, returns an empty
|
|
112
|
+
* string instead.
|
|
113
|
+
*
|
|
114
|
+
* @param text - string to encode
|
|
115
|
+
* @returns encoded string
|
|
116
|
+
*/
|
|
117
|
+
export function encodeParam(text) {
|
|
118
|
+
return text == null ? '' : encodePath(text).replace(SLASH_RE, '%2F');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Decode text using `decodeURIComponent`. Returns the original text if it
|
|
122
|
+
* fails.
|
|
123
|
+
*
|
|
124
|
+
* @param text - string to decode
|
|
125
|
+
* @returns decoded string
|
|
126
|
+
*/
|
|
127
|
+
export function decode(text) {
|
|
128
|
+
try {
|
|
129
|
+
return decodeURIComponent('' + text);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
// __DEV__ && warn(`Error decoding "${text}". Using original value`)
|
|
133
|
+
}
|
|
134
|
+
return '' + text;
|
|
135
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { decode, encodeQueryKey, encodeQueryValue, PLUS_RE } from './encoding';
|
|
2
|
+
const isArray = Array.isArray;
|
|
3
|
+
/**
|
|
4
|
+
* Transforms a queryString into a {@link LocationQuery} object. Accept both, a
|
|
5
|
+
* version with the leading `?` and without Should work as URLSearchParams
|
|
6
|
+
* @internal
|
|
7
|
+
*
|
|
8
|
+
* @param search - search string to parse
|
|
9
|
+
* @returns a query object
|
|
10
|
+
*/
|
|
11
|
+
export function parseQuery(search) {
|
|
12
|
+
const query = {};
|
|
13
|
+
// avoid creating an object with an empty key and empty value
|
|
14
|
+
// because of split('&')
|
|
15
|
+
if (search === '' || search === '?')
|
|
16
|
+
return query;
|
|
17
|
+
const hasLeadingIM = search[0] === '?';
|
|
18
|
+
const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');
|
|
19
|
+
for (let i = 0; i < searchParams.length; ++i) {
|
|
20
|
+
// pre decode the + into space
|
|
21
|
+
const searchParam = searchParams[i].replace(PLUS_RE, ' ');
|
|
22
|
+
// allow the = character
|
|
23
|
+
const eqPos = searchParam.indexOf('=');
|
|
24
|
+
const key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
|
|
25
|
+
const value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
|
|
26
|
+
if (key in query) {
|
|
27
|
+
// an extra variable for ts types
|
|
28
|
+
let currentValue = query[key];
|
|
29
|
+
if (!isArray(currentValue)) {
|
|
30
|
+
currentValue = query[key] = [currentValue];
|
|
31
|
+
}
|
|
32
|
+
// we force the modification
|
|
33
|
+
;
|
|
34
|
+
currentValue.push(value);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
query[key] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return query;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Stringifies a {@link LocationQueryRaw} object. Like `URLSearchParams`, it
|
|
44
|
+
* doesn't prepend a `?`
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*
|
|
48
|
+
* @param query - query object to stringify
|
|
49
|
+
* @returns string version of the query without the leading `?`
|
|
50
|
+
*/
|
|
51
|
+
export function stringifyQuery(query) {
|
|
52
|
+
let search = '';
|
|
53
|
+
for (let key in query) {
|
|
54
|
+
const value = query[key];
|
|
55
|
+
key = encodeQueryKey(key);
|
|
56
|
+
if (value == null) {
|
|
57
|
+
// only null adds the value
|
|
58
|
+
if (value !== undefined) {
|
|
59
|
+
search += (search.length ? '&' : '') + key;
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
// keep null values
|
|
64
|
+
const values = isArray(value)
|
|
65
|
+
? value.map(v => v && encodeQueryValue(v))
|
|
66
|
+
: [value && encodeQueryValue(value)];
|
|
67
|
+
values.forEach(value => {
|
|
68
|
+
// skip undefined values in arrays as if they were not present
|
|
69
|
+
// smaller code than using filter
|
|
70
|
+
if (value !== undefined) {
|
|
71
|
+
// only append & with non-empty search
|
|
72
|
+
search += (search.length ? '&' : '') + key;
|
|
73
|
+
if (value != null)
|
|
74
|
+
search += '=' + value;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return search;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Transforms a {@link LocationQueryRaw} into a {@link LocationQuery} by casting
|
|
82
|
+
* numbers into strings, removing keys with an undefined value and replacing
|
|
83
|
+
* undefined with null in arrays
|
|
84
|
+
*
|
|
85
|
+
* @param query - query object to normalize
|
|
86
|
+
* @returns a normalized query object
|
|
87
|
+
*/
|
|
88
|
+
export function normalizeQuery(query) {
|
|
89
|
+
const normalizedQuery = {};
|
|
90
|
+
for (const key in query) {
|
|
91
|
+
const value = query[key];
|
|
92
|
+
if (value !== undefined) {
|
|
93
|
+
normalizedQuery[key] = isArray(value)
|
|
94
|
+
? value.map(v => (v == null ? null : '' + v))
|
|
95
|
+
: value == null
|
|
96
|
+
? value
|
|
97
|
+
: '' + value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return normalizedQuery;
|
|
101
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { Widget } from "../model/Widget";
|
|
2
|
+
import { BroadcastEvent } from "../model/BroadcastEvent";
|
|
2
3
|
export declare class ElectronApi {
|
|
3
4
|
static openAddWidgetWindow(): void;
|
|
4
5
|
static registerWidgets(widgets: Widget[]): Promise<void>;
|
|
6
|
+
static setConfig(key: string, value: string | number | boolean): Promise<void>;
|
|
7
|
+
static sendBroadcastEvent(event: BroadcastEvent): Promise<void>;
|
|
8
|
+
static registerBroadcast(callback: (event: BroadcastEvent) => void): Promise<void>;
|
|
9
|
+
static unregisterBroadcast(): Promise<void>;
|
|
10
|
+
static addIpcListener(key: String, f: Function): Promise<void>;
|
|
11
|
+
static removeIpcListener(key: String): Promise<void>;
|
|
12
|
+
static getConfig(key: string, defaultValue: string | number | boolean): Promise<any>;
|
|
5
13
|
static hasElectronApi(): boolean;
|
|
6
14
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare class Keys {
|
|
2
|
+
static readonly CONFIG_LAUNCH_AT_STARTUP = "LAUNCH_AT_STARTUP";
|
|
3
|
+
static readonly CONFIG_WIDGET_SHADOW = "WIDGET_SHADOW";
|
|
4
|
+
static readonly CHANNEL_MAIN = "WeiZ5kaKijae";
|
|
5
|
+
static readonly EVENT_WIDGET_UPDATED = "WIDGET_SHADOW";
|
|
6
|
+
static readonly BROADCAST_EVENT = "sendBroadcastEvent";
|
|
7
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export * from "./model/Widget";
|
|
2
|
+
export * from "./model/BroadcastEvent";
|
|
3
|
+
export * from "./model/WidgetData";
|
|
4
|
+
export * from "./model/WidgetParams";
|
|
2
5
|
export * from "./api/ElectronApi";
|
|
6
|
+
export * from "./api/Keys";
|
|
7
|
+
export * from "./repository/WidgetDataRepository";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type SocialInfoType = "qq" | "wechat" | "qq-group" | "discord" | "telegram" | "tiktok" | "douyin" | "youtube" | "instagram" | "twitter" | "facebook" | "kuaishou" | "bilibili" | "github" | "email" | "gitee" | "homepage";
|
|
2
|
+
export declare class SocialInfo {
|
|
3
|
+
name: SocialInfoType;
|
|
4
|
+
content: string;
|
|
5
|
+
constructor(name: SocialInfoType, url: string);
|
|
6
|
+
}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
type WidgetOptions = {
|
|
2
|
+
name: string;
|
|
3
|
+
title: Map<string, string>;
|
|
4
|
+
description: Map<string, string>;
|
|
5
|
+
keywords: WidgetKeyword[];
|
|
6
|
+
lang: string;
|
|
7
|
+
w: number;
|
|
8
|
+
h: number;
|
|
9
|
+
maxW?: number;
|
|
10
|
+
maxH?: number;
|
|
11
|
+
minW?: number;
|
|
12
|
+
minH?: number;
|
|
13
|
+
url: string;
|
|
14
|
+
configUrl?: string;
|
|
15
|
+
extraUrl?: Map<string, string>;
|
|
16
|
+
};
|
|
1
17
|
export declare class Widget {
|
|
2
18
|
readonly name: string;
|
|
3
19
|
/**
|
|
@@ -8,7 +24,7 @@ export declare class Widget {
|
|
|
8
24
|
/**
|
|
9
25
|
* 组件介绍
|
|
10
26
|
*/
|
|
11
|
-
readonly
|
|
27
|
+
readonly description: Map<string, string>;
|
|
12
28
|
readonly keywords: WidgetKeyword[];
|
|
13
29
|
/**
|
|
14
30
|
* 组件默认语言
|
|
@@ -22,8 +38,11 @@ export declare class Widget {
|
|
|
22
38
|
readonly minH: number;
|
|
23
39
|
readonly url: string;
|
|
24
40
|
readonly configUrl?: string | null;
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
/**
|
|
42
|
+
* 组件其他页面的url在这注册
|
|
43
|
+
*/
|
|
44
|
+
readonly extraUrl: Map<string, string>;
|
|
45
|
+
constructor(options: WidgetOptions);
|
|
27
46
|
/**
|
|
28
47
|
* 获取组件标题
|
|
29
48
|
* @param lang 语言环境,不传则获取默认语言
|
|
@@ -33,8 +52,30 @@ export declare class Widget {
|
|
|
33
52
|
* 获取组件标描述
|
|
34
53
|
* @param lang 语言环境,不传则获取默认标题
|
|
35
54
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
getDescription(lang?: string): string | undefined;
|
|
56
|
+
toJSON(): {
|
|
57
|
+
name: string;
|
|
58
|
+
title: {
|
|
59
|
+
[k: string]: string;
|
|
60
|
+
};
|
|
61
|
+
description: {
|
|
62
|
+
[k: string]: string;
|
|
63
|
+
};
|
|
64
|
+
keywords: WidgetKeyword[];
|
|
65
|
+
lang: string;
|
|
66
|
+
w: number;
|
|
67
|
+
h: number;
|
|
68
|
+
maxW: number;
|
|
69
|
+
maxH: number;
|
|
70
|
+
minW: number;
|
|
71
|
+
minH: number;
|
|
72
|
+
url: string;
|
|
73
|
+
configUrl: string | null | undefined;
|
|
74
|
+
extraUrl: {
|
|
75
|
+
[k: string]: string;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
static parse(json: string): Widget;
|
|
38
79
|
}
|
|
39
80
|
export declare enum WidgetKeyword {
|
|
40
81
|
RECOMMEND = "recommend",
|
|
@@ -48,3 +89,4 @@ export declare enum WidgetKeyword {
|
|
|
48
89
|
INFO = "info",
|
|
49
90
|
DASHBOARD = "dashboard"
|
|
50
91
|
}
|
|
92
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组件配置数据,用于存储组件自定义页面所设置的数据
|
|
3
|
+
*/
|
|
4
|
+
export declare class WidgetData {
|
|
5
|
+
/**
|
|
6
|
+
* 组件id
|
|
7
|
+
*/
|
|
8
|
+
id?: string;
|
|
9
|
+
/**
|
|
10
|
+
* 组件名
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
/**
|
|
14
|
+
* 背景颜色
|
|
15
|
+
*/
|
|
16
|
+
backgroundColor?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 文字颜色
|
|
19
|
+
*/
|
|
20
|
+
color?: string;
|
|
21
|
+
/**
|
|
22
|
+
* 字体大小
|
|
23
|
+
*/
|
|
24
|
+
fontSize?: number;
|
|
25
|
+
/**
|
|
26
|
+
* 字体
|
|
27
|
+
*/
|
|
28
|
+
fontFamily?: string;
|
|
29
|
+
/**
|
|
30
|
+
* 圆角半径
|
|
31
|
+
*/
|
|
32
|
+
borderRadius?: number;
|
|
33
|
+
constructor(name: string, id?: string);
|
|
34
|
+
parseJSON(json: {}): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare class WidgetParams {
|
|
2
|
+
static readonly PARAM_PREFIX = "w_";
|
|
3
|
+
static readonly PARAM_ID = "id";
|
|
4
|
+
static readonly PARAM_W = "w";
|
|
5
|
+
static readonly PARAM_H = "h";
|
|
6
|
+
static readonly PARAM_WIDTH = "width";
|
|
7
|
+
static readonly PARAM_HEIGHT = "height";
|
|
8
|
+
static readonly PARAM_X = "x";
|
|
9
|
+
static readonly PARAM_Y = "y";
|
|
10
|
+
static readonly PARAM_LANG = "lang";
|
|
11
|
+
static readonly PARAM_THEME = "theme";
|
|
12
|
+
static readonly PARAM_MODE = "mode";
|
|
13
|
+
static readonly PARAM_RADIUS = "radius";
|
|
14
|
+
static readonly PARAM_NAME = "name";
|
|
15
|
+
static readonly PARAM_TITLE = "title";
|
|
16
|
+
static readonly PARAM_PREVIEW = "preview";
|
|
17
|
+
static readonly PARAMS: string[];
|
|
18
|
+
id?: string;
|
|
19
|
+
w?: number;
|
|
20
|
+
width?: number;
|
|
21
|
+
height?: number;
|
|
22
|
+
h?: number;
|
|
23
|
+
x?: number;
|
|
24
|
+
y?: number;
|
|
25
|
+
preview?: boolean;
|
|
26
|
+
lang?: string;
|
|
27
|
+
theme?: ThemeMode;
|
|
28
|
+
mode?: WidgetHostMode;
|
|
29
|
+
radius?: number;
|
|
30
|
+
name?: string;
|
|
31
|
+
title?: string;
|
|
32
|
+
/**
|
|
33
|
+
* 将组件参数转为url参数
|
|
34
|
+
* @param object
|
|
35
|
+
* @return URLSearchParams w_w=2&w_h=2&w_id=21&w_width=156&w_height=156
|
|
36
|
+
*/
|
|
37
|
+
toUrlParams(): URLSearchParams;
|
|
38
|
+
getPersistKey(): string;
|
|
39
|
+
/**
|
|
40
|
+
* 从当前地址解析组件参数:
|
|
41
|
+
* http://localhost:8080/#/widget/config/labor_progress?w_w=2&w_h=2&w_width=156&w_height=156
|
|
42
|
+
* =>
|
|
43
|
+
* {w:2,h:2,id:21,width:156,height:156}
|
|
44
|
+
*/
|
|
45
|
+
static fromCurrentLocation(): WidgetParams;
|
|
46
|
+
private static setValue;
|
|
47
|
+
/**
|
|
48
|
+
* 从对象键值对中初始化组件参数
|
|
49
|
+
* {w_w:2,w_h:2,w_id:21,w_width:156,w_height:156}=>
|
|
50
|
+
* {w:2,h:2,id:21,width:156,height:156}
|
|
51
|
+
* @param object
|
|
52
|
+
*/
|
|
53
|
+
static fromObject(object: any): WidgetParams;
|
|
54
|
+
}
|
|
55
|
+
export declare enum ThemeMode {
|
|
56
|
+
AUTO = "auto",
|
|
57
|
+
LIGHT = "LIGHT",
|
|
58
|
+
DARK = "DARK"
|
|
59
|
+
}
|
|
60
|
+
export declare enum WidgetHostMode {
|
|
61
|
+
DEFAULT = 0,
|
|
62
|
+
OVERLAP = 1
|
|
63
|
+
}
|