@lynx-js/web-core 0.9.1 → 0.10.1
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/CHANGELOG.md +59 -0
- package/README.md +18 -2
- package/dist/apis/LynxView.d.ts +20 -14
- package/dist/apis/LynxView.js +30 -23
- package/dist/apis/inShadowRootStyles.d.ts +1 -1
- package/dist/apis/inShadowRootStyles.js +9 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/uiThread/bootWorkers.js +8 -8
- package/dist/uiThread/crossThreadHandlers/registerDispatchLynxViewEventHandler.d.ts +2 -0
- package/dist/uiThread/crossThreadHandlers/registerDispatchLynxViewEventHandler.js +15 -0
- package/dist/uiThread/crossThreadHandlers/registerFlushElementTreeHandler.d.ts +2 -11
- package/dist/uiThread/crossThreadHandlers/registerFlushElementTreeHandler.js +15 -88
- package/dist/uiThread/crossThreadHandlers/registerInvokeUIMethodHandler.js +4 -3
- package/dist/uiThread/crossThreadHandlers/registerNapiModulesCallHandler.js +5 -2
- package/dist/uiThread/startUIThread.js +13 -13
- package/package.json +6 -5
- package/dist/types/RuntimePropertyOnElement.d.ts +0 -17
- package/dist/types/RuntimePropertyOnElement.js +0 -2
- package/dist/uiThread/crossThreadHandlers/bootTimingSystem.d.ts +0 -5
- package/dist/uiThread/crossThreadHandlers/bootTimingSystem.js +0 -51
- package/dist/uiThread/crossThreadHandlers/createExposureService.d.ts +0 -2
- package/dist/uiThread/crossThreadHandlers/createExposureService.js +0 -57
- package/dist/uiThread/decodeElementOperation.d.ts +0 -12
- package/dist/uiThread/decodeElementOperation.js +0 -175
- package/dist/utils/createCrossThreadEvent.d.ts +0 -2
- package/dist/utils/createCrossThreadEvent.js +0 -43
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# @lynx-js/web-core
|
|
2
2
|
|
|
3
|
+
## 0.10.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- docs: fix documents about lynx-view's properties ([#412](https://github.com/lynx-family/lynx-stack/pull/412))
|
|
8
|
+
|
|
9
|
+
Attributes should be hyphen-name: 'init-data', 'global-props'.
|
|
10
|
+
|
|
11
|
+
now all properties has corresponding attributes.
|
|
12
|
+
|
|
13
|
+
- feat: onNapiModulesCall function add new param: `dispatchNapiModules`, napiModulesMap val add new param: `handleDispatch`. ([#414](https://github.com/lynx-family/lynx-stack/pull/414))
|
|
14
|
+
|
|
15
|
+
Now you can use them to actively communicate to napiModules (background thread) in onNapiModulesCall (ui thread).
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`1af3b60`](https://github.com/lynx-family/lynx-stack/commit/1af3b6052ab27f98bf0e4d1b0ec9f7d9e88e0afc)]:
|
|
18
|
+
- @lynx-js/web-constants@0.10.1
|
|
19
|
+
- @lynx-js/web-worker-runtime@0.10.1
|
|
20
|
+
- @lynx-js/web-worker-rpc@0.10.1
|
|
21
|
+
|
|
22
|
+
## 0.10.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- feat: rewrite the main thread Element PAPIs ([#343](https://github.com/lynx-family/lynx-stack/pull/343))
|
|
27
|
+
|
|
28
|
+
In this commit we've rewritten the main thread apis.
|
|
29
|
+
|
|
30
|
+
The most highlighted change is that
|
|
31
|
+
|
|
32
|
+
- Before this commit we send events directly to bts
|
|
33
|
+
- After this change, we send events to mts then send them to bts with some data combined.
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- refactor: timing system ([#378](https://github.com/lynx-family/lynx-stack/pull/378))
|
|
38
|
+
|
|
39
|
+
Now we moved the timing system to the background thread.
|
|
40
|
+
|
|
41
|
+
- feat: support `defaultOverflowVisible` config ([#406](https://github.com/lynx-family/lynx-stack/pull/406))
|
|
42
|
+
|
|
43
|
+
- fix(web): rsbuild will bundle 2 exactly same chunk for two same `new Worker` stmt ([#372](https://github.com/lynx-family/lynx-stack/pull/372))
|
|
44
|
+
|
|
45
|
+
the bundle size will be optimized about 28.2KB
|
|
46
|
+
|
|
47
|
+
- fix: inline style will be removed for value number `0` ([#368](https://github.com/lynx-family/lynx-stack/pull/368))
|
|
48
|
+
|
|
49
|
+
the inline style value could be incorrectly removed for number value `0`;
|
|
50
|
+
|
|
51
|
+
For example, `flex-shrink:0` may be ignored.
|
|
52
|
+
|
|
53
|
+
- feat: The onNapiModulesCall function of lynx-view provides the fourth parameter: `lynxView`, which is the actual lynx-view DOM. ([#350](https://github.com/lynx-family/lynx-stack/pull/350))
|
|
54
|
+
|
|
55
|
+
- fix: publicComponentEvent args order ([#401](https://github.com/lynx-family/lynx-stack/pull/401))
|
|
56
|
+
|
|
57
|
+
- Updated dependencies [[`3a8dabd`](https://github.com/lynx-family/lynx-stack/commit/3a8dabd877084c15db1404c912dd8a19c7a0fc59), [`a521759`](https://github.com/lynx-family/lynx-stack/commit/a5217592f5aebea4b17860e729d523ecabb5f691), [`890c6c5`](https://github.com/lynx-family/lynx-stack/commit/890c6c51470c82104abb1049681f55e5d97cf9d6)]:
|
|
58
|
+
- @lynx-js/web-worker-runtime@0.10.0
|
|
59
|
+
- @lynx-js/web-constants@0.10.0
|
|
60
|
+
- @lynx-js/web-worker-rpc@0.10.0
|
|
61
|
+
|
|
3
62
|
## 0.9.1
|
|
4
63
|
|
|
5
64
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -10,8 +10,24 @@ import '@lynx-js/web-core/index.css';
|
|
|
10
10
|
|
|
11
11
|
document.body.innerHTML = `
|
|
12
12
|
<lynx-view
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
style="height:100vh; width:100vw;"
|
|
14
|
+
url="http://localhost:3000/main/main-thread.js"
|
|
15
|
+
>
|
|
16
|
+
</lynx-view>`;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If you use Lynx elements (view, text, image, etc.), you need to import `@lynx-js/web-elements`:
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import '@lynx-js/web-core';
|
|
23
|
+
import '@lynx-js/web-core/index.css';
|
|
24
|
+
import '@lynx-js/web-elements/all';
|
|
25
|
+
import '@lynx-js/web-elements/index.css';
|
|
26
|
+
|
|
27
|
+
document.body.innerHTML = `
|
|
28
|
+
<lynx-view
|
|
29
|
+
style="height:100vh; width:100vw;"
|
|
30
|
+
url="http://localhost:3000/main/main-thread.js"
|
|
15
31
|
>
|
|
16
32
|
</lynx-view>`;
|
|
17
33
|
```
|
package/dist/apis/LynxView.d.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { type Cloneable, type NapiModulesCall, type NapiModulesMap, type NativeModulesCall, type NativeModulesMap, type UpdateDataType } from '@lynx-js/web-constants';
|
|
2
|
+
export type INapiModulesCall = (name: string, data: any, moduleName: string, lynxView: LynxView, dispatchNapiModules: (data: Cloneable) => void) => Promise<{
|
|
3
|
+
data: unknown;
|
|
4
|
+
transfer?: Transferable[];
|
|
5
|
+
}> | {
|
|
6
|
+
data: unknown;
|
|
7
|
+
transfer?: Transferable[];
|
|
8
|
+
} | undefined;
|
|
2
9
|
/**
|
|
3
10
|
* Based on our experiences, these elements are almost used in all lynx cards.
|
|
4
11
|
*/
|
|
5
12
|
/**
|
|
6
|
-
* @
|
|
7
|
-
* @
|
|
8
|
-
* @
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
11
|
-
* @
|
|
12
|
-
* @
|
|
13
|
-
* @
|
|
14
|
-
* @
|
|
15
|
-
* @
|
|
16
|
-
* @
|
|
13
|
+
* @property {string} url [required] (attribute: "url") The url of the entry of your Lynx card
|
|
14
|
+
* @property {Cloneable} globalProps [optional] (attribute: "global-props") The globalProps value of this Lynx card
|
|
15
|
+
* @property {Cloneable} initData [oprional] (attribute: "init-data") The initial data of this Lynx card
|
|
16
|
+
* @property {Record<string,string>} overrideLynxTagToHTMLTagMap [optional] use this property/attribute to override the lynx tag -> html tag map
|
|
17
|
+
* @property {NativeModulesMap} nativeModulesMap [optional] use to customize NativeModules. key is module-name, value is esm url.
|
|
18
|
+
* @property {NativeModulesCall} onNativeModulesCall [optional] the NativeModules value handler. Arguments will be cached before this property is assigned.
|
|
19
|
+
* @property {"auto" | null} height [optional] (attribute: "height") set it to "auto" for height auto-sizing
|
|
20
|
+
* @property {"auto" | null} width [optional] (attribute: "width") set it to "auto" for width auto-sizing
|
|
21
|
+
* @property {NapiModulesMap} napiModulesMap [optional] the napiModule which is called in lynx-core. key is module-name, value is esm url.
|
|
22
|
+
* @property {INapiModulesCall} onNapiModulesCall [optional] the NapiModule value handler.
|
|
23
|
+
* @property {"false" | "true" | null} injectHeadLinks [optional] @default true set it to "false" to disable injecting the <link href="" ref="stylesheet"> styles into shadowroot
|
|
17
24
|
*
|
|
18
25
|
* @event error lynx card fired an error
|
|
19
26
|
*
|
|
@@ -23,7 +30,7 @@ import { type Cloneable, type NapiModulesCall, type NapiModulesMap, type NativeM
|
|
|
23
30
|
* Note that you should declarae the size of lynx-view
|
|
24
31
|
*
|
|
25
32
|
* ```html
|
|
26
|
-
* <lynx-view url="https://path/to/main-thread.js"
|
|
33
|
+
* <lynx-view url="https://path/to/main-thread.js" raw-data="{}" global-props="{}" style="height:300px;width:300px">
|
|
27
34
|
* </lynx-view>
|
|
28
35
|
* ```
|
|
29
36
|
*
|
|
@@ -38,7 +45,6 @@ export declare class LynxView extends HTMLElement {
|
|
|
38
45
|
static lynxViewCount: number;
|
|
39
46
|
static tag: "lynx-view";
|
|
40
47
|
private static observedAttributeAsProperties;
|
|
41
|
-
private static attributeCamelCaseMap;
|
|
42
48
|
/**
|
|
43
49
|
* @private
|
|
44
50
|
*/
|
|
@@ -95,7 +101,7 @@ export declare class LynxView extends HTMLElement {
|
|
|
95
101
|
* @property
|
|
96
102
|
*/
|
|
97
103
|
get onNapiModulesCall(): NapiModulesCall | undefined;
|
|
98
|
-
set onNapiModulesCall(handler:
|
|
104
|
+
set onNapiModulesCall(handler: INapiModulesCall);
|
|
99
105
|
/**
|
|
100
106
|
* @public
|
|
101
107
|
* @method
|
package/dist/apis/LynxView.js
CHANGED
|
@@ -8,17 +8,17 @@ import { inShadowRootStyles } from './inShadowRootStyles.js';
|
|
|
8
8
|
* Based on our experiences, these elements are almost used in all lynx cards.
|
|
9
9
|
*/
|
|
10
10
|
/**
|
|
11
|
-
* @
|
|
12
|
-
* @
|
|
13
|
-
* @
|
|
14
|
-
* @
|
|
15
|
-
* @
|
|
16
|
-
* @
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
19
|
-
* @
|
|
20
|
-
* @
|
|
21
|
-
* @
|
|
11
|
+
* @property {string} url [required] (attribute: "url") The url of the entry of your Lynx card
|
|
12
|
+
* @property {Cloneable} globalProps [optional] (attribute: "global-props") The globalProps value of this Lynx card
|
|
13
|
+
* @property {Cloneable} initData [oprional] (attribute: "init-data") The initial data of this Lynx card
|
|
14
|
+
* @property {Record<string,string>} overrideLynxTagToHTMLTagMap [optional] use this property/attribute to override the lynx tag -> html tag map
|
|
15
|
+
* @property {NativeModulesMap} nativeModulesMap [optional] use to customize NativeModules. key is module-name, value is esm url.
|
|
16
|
+
* @property {NativeModulesCall} onNativeModulesCall [optional] the NativeModules value handler. Arguments will be cached before this property is assigned.
|
|
17
|
+
* @property {"auto" | null} height [optional] (attribute: "height") set it to "auto" for height auto-sizing
|
|
18
|
+
* @property {"auto" | null} width [optional] (attribute: "width") set it to "auto" for width auto-sizing
|
|
19
|
+
* @property {NapiModulesMap} napiModulesMap [optional] the napiModule which is called in lynx-core. key is module-name, value is esm url.
|
|
20
|
+
* @property {INapiModulesCall} onNapiModulesCall [optional] the NapiModule value handler.
|
|
21
|
+
* @property {"false" | "true" | null} injectHeadLinks [optional] @default true set it to "false" to disable injecting the <link href="" ref="stylesheet"> styles into shadowroot
|
|
22
22
|
*
|
|
23
23
|
* @event error lynx card fired an error
|
|
24
24
|
*
|
|
@@ -28,7 +28,7 @@ import { inShadowRootStyles } from './inShadowRootStyles.js';
|
|
|
28
28
|
* Note that you should declarae the size of lynx-view
|
|
29
29
|
*
|
|
30
30
|
* ```html
|
|
31
|
-
* <lynx-view url="https://path/to/main-thread.js"
|
|
31
|
+
* <lynx-view url="https://path/to/main-thread.js" raw-data="{}" global-props="{}" style="height:300px;width:300px">
|
|
32
32
|
* </lynx-view>
|
|
33
33
|
* ```
|
|
34
34
|
*
|
|
@@ -43,12 +43,9 @@ export class LynxView extends HTMLElement {
|
|
|
43
43
|
static tag = 'lynx-view';
|
|
44
44
|
static observedAttributeAsProperties = [
|
|
45
45
|
'url',
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'overrideLynxTagToHTMLTagMap',
|
|
49
|
-
'nativeModulesMap',
|
|
46
|
+
'global-props',
|
|
47
|
+
'init-data',
|
|
50
48
|
];
|
|
51
|
-
static attributeCamelCaseMap = Object.fromEntries(this.observedAttributeAsProperties.map((nm) => [nm.toLocaleLowerCase(), nm]));
|
|
52
49
|
/**
|
|
53
50
|
* @private
|
|
54
51
|
*/
|
|
@@ -167,7 +164,9 @@ export class LynxView extends HTMLElement {
|
|
|
167
164
|
return this.#onNapiModulesCall;
|
|
168
165
|
}
|
|
169
166
|
set onNapiModulesCall(handler) {
|
|
170
|
-
this.#onNapiModulesCall =
|
|
167
|
+
this.#onNapiModulesCall = (name, data, moduleName, dispatchNapiModules) => {
|
|
168
|
+
return handler(name, data, moduleName, this, dispatchNapiModules);
|
|
169
|
+
};
|
|
171
170
|
}
|
|
172
171
|
/**
|
|
173
172
|
* @public
|
|
@@ -212,10 +211,16 @@ export class LynxView extends HTMLElement {
|
|
|
212
211
|
*/
|
|
213
212
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
214
213
|
if (oldValue !== newValue) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
214
|
+
switch (name) {
|
|
215
|
+
case 'url':
|
|
216
|
+
this.#url = newValue;
|
|
217
|
+
break;
|
|
218
|
+
case 'global-props':
|
|
219
|
+
this.#globalProps = JSON.parse(newValue);
|
|
220
|
+
break;
|
|
221
|
+
case 'init-data':
|
|
222
|
+
this.#initData = JSON.parse(newValue);
|
|
223
|
+
break;
|
|
219
224
|
}
|
|
220
225
|
}
|
|
221
226
|
}
|
|
@@ -289,7 +294,9 @@ export class LynxView extends HTMLElement {
|
|
|
289
294
|
const styleElement = document.createElement('style');
|
|
290
295
|
this.shadowRoot.append(styleElement);
|
|
291
296
|
const styleSheet = styleElement.sheet;
|
|
292
|
-
|
|
297
|
+
for (const rule of inShadowRootStyles) {
|
|
298
|
+
styleSheet.insertRule(rule);
|
|
299
|
+
}
|
|
293
300
|
const injectHeadLinks = this.getAttribute('inject-head-links') !== 'false';
|
|
294
301
|
if (injectHeadLinks) {
|
|
295
302
|
document.head.querySelectorAll('link[rel="stylesheet"]').forEach((linkElement) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const inShadowRootStyles
|
|
1
|
+
export declare const inShadowRootStyles: string[];
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
export const inShadowRootStyles =
|
|
2
|
-
[lynx-default-display-linear="false"] * {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
1
|
+
export const inShadowRootStyles = [
|
|
2
|
+
` [lynx-default-display-linear="false"] * {
|
|
3
|
+
--lynx-display: flex;
|
|
4
|
+
--lynx-display-toggle: var(--lynx-display-flex);
|
|
5
|
+
}`,
|
|
6
|
+
`[lynx-default-overflow-visible="true"] x-view{
|
|
7
|
+
overflow: visible;
|
|
8
|
+
}`,
|
|
9
|
+
];
|
|
7
10
|
//# sourceMappingURL=inShadowRootStyles.js.map
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -19,10 +19,7 @@ export function bootWorkers() {
|
|
|
19
19
|
function createMainWorker() {
|
|
20
20
|
const channelToMainThread = new MessageChannel();
|
|
21
21
|
const channelMainThreadWithBackground = new MessageChannel();
|
|
22
|
-
const mainThreadWorker =
|
|
23
|
-
type: 'module',
|
|
24
|
-
name: `lynx-main`,
|
|
25
|
-
});
|
|
22
|
+
const mainThreadWorker = createWebWorker();
|
|
26
23
|
const mainThreadMessage = {
|
|
27
24
|
mode: 'main',
|
|
28
25
|
toUIThread: channelToMainThread.port2,
|
|
@@ -42,10 +39,7 @@ function createMainWorker() {
|
|
|
42
39
|
}
|
|
43
40
|
function createBackgroundWorker(channelMainThreadWithBackground) {
|
|
44
41
|
const channelToBackground = new MessageChannel();
|
|
45
|
-
const backgroundThreadWorker =
|
|
46
|
-
type: 'module',
|
|
47
|
-
name: `lynx-bg`,
|
|
48
|
-
});
|
|
42
|
+
const backgroundThreadWorker = createWebWorker();
|
|
49
43
|
const backgroundThreadMessage = {
|
|
50
44
|
mode: 'background',
|
|
51
45
|
toUIThread: channelToBackground.port2,
|
|
@@ -59,4 +53,10 @@ function createBackgroundWorker(channelMainThreadWithBackground) {
|
|
|
59
53
|
const backgroundRpc = new Rpc(channelToBackground.port1, 'ui-to-bg');
|
|
60
54
|
return { backgroundRpc, backgroundThreadWorker };
|
|
61
55
|
}
|
|
56
|
+
function createWebWorker() {
|
|
57
|
+
return new Worker(new URL('@lynx-js/web-worker-runtime', import.meta.url), {
|
|
58
|
+
type: 'module',
|
|
59
|
+
name: `lynx-web`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
62
|
//# sourceMappingURL=bootWorkers.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import { dispatchLynxViewEventEndpoint } from '@lynx-js/web-constants';
|
|
5
|
+
export function registerDispatchLynxViewEventHandler(rpc, shadowRoot) {
|
|
6
|
+
rpc.registerHandler(dispatchLynxViewEventEndpoint, (eventType, detail) => {
|
|
7
|
+
shadowRoot.dispatchEvent(new CustomEvent(eventType, {
|
|
8
|
+
detail,
|
|
9
|
+
bubbles: true,
|
|
10
|
+
cancelable: true,
|
|
11
|
+
composed: true,
|
|
12
|
+
}));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=registerDispatchLynxViewEventHandler.js.map
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import { type PageConfig, type flushElementTreeEndpoint } from '@lynx-js/web-constants';
|
|
2
1
|
import type { Rpc } from '@lynx-js/web-worker-rpc';
|
|
3
|
-
|
|
4
|
-
export declare function registerFlushElementTreeHandler(mainThreadRpc: Rpc, endpoint: typeof flushElementTreeEndpoint, options: {
|
|
5
|
-
pageConfig: PageConfig;
|
|
6
|
-
backgroundRpc: Rpc;
|
|
2
|
+
export declare function registerFlushElementTreeHandler(mainThreadRpc: Rpc, options: {
|
|
7
3
|
shadowRoot: ShadowRoot;
|
|
8
4
|
}, onCommit: (info: {
|
|
9
|
-
pipelineId: string | undefined;
|
|
10
|
-
timingFlags: string[];
|
|
11
5
|
isFP: boolean;
|
|
12
|
-
}) => void
|
|
13
|
-
uniqueIdToElement: WeakRef<HTMLElement & RuntimePropertyOnElement>[];
|
|
14
|
-
uniqueIdToCssInJsRule: WeakRef<CSSStyleRule>[];
|
|
15
|
-
};
|
|
6
|
+
}) => void): void;
|
|
@@ -1,97 +1,24 @@
|
|
|
1
1
|
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
2
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const rootStyleElementForCssInJs = document.createElement('style');
|
|
17
|
-
if (!pageConfig.enableCSSSelector) {
|
|
18
|
-
shadowRoot.append(rootStyleElementForCssInJs);
|
|
19
|
-
}
|
|
20
|
-
const createElementImpl = (tag) => {
|
|
21
|
-
const element = document.createElement(tag);
|
|
22
|
-
element[lynxRuntimeValue] = {
|
|
23
|
-
dataset: {},
|
|
24
|
-
eventHandler: {},
|
|
25
|
-
};
|
|
26
|
-
return element;
|
|
27
|
-
};
|
|
28
|
-
const createStyleRuleImpl = (uniqueId, initialStyle) => {
|
|
29
|
-
const commonStyleSheetText = `[${lynxUniqueIdAttribute}="${uniqueId.toString()}"]{${initialStyle}}`;
|
|
30
|
-
const idx = rootStyleElementForCssInJs.sheet.insertRule(commonStyleSheetText);
|
|
31
|
-
return rootStyleElementForCssInJs.sheet.cssRules[idx];
|
|
32
|
-
};
|
|
33
|
-
const mtsHandler = (event) => {
|
|
34
|
-
const crossThreadEvent = createCrossThreadEvent(event);
|
|
35
|
-
mainThreadRpc.invoke(postMainThreadEvent, [crossThreadEvent]);
|
|
36
|
-
};
|
|
37
|
-
const btsHandler = (event) => {
|
|
38
|
-
const crossThreadEvent = createCrossThreadEvent(event);
|
|
39
|
-
const currentTarget = event.currentTarget;
|
|
40
|
-
const parentComponentUniqueId = currentTarget.getAttribute(parentComponentUniqueIdAttribute) ?? '0';
|
|
41
|
-
const componentTargetDom = shadowRoot.querySelector(`[${lynxUniqueIdAttribute}="${parentComponentUniqueId}"]`);
|
|
42
|
-
const componentId = componentTargetDom?.getAttribute(lynxTagAttribute) !== 'page'
|
|
43
|
-
? componentTargetDom?.getAttribute(componentIdAttribute) ?? undefined
|
|
44
|
-
: undefined;
|
|
45
|
-
const hname = currentTarget[lynxRuntimeValue]
|
|
46
|
-
.eventHandler[crossThreadEvent.type].hname;
|
|
47
|
-
if (componentId) {
|
|
48
|
-
backgroundRpc.invoke(publicComponentEventEndpoint, [
|
|
49
|
-
componentId,
|
|
50
|
-
hname,
|
|
51
|
-
crossThreadEvent,
|
|
52
|
-
]);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
backgroundRpc.invoke(publishEventEndpoint, [
|
|
56
|
-
hname,
|
|
57
|
-
crossThreadEvent,
|
|
58
|
-
]);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
mainThreadRpc.registerHandler(endpoint, (operations, options, cardCss, timingFlags) => {
|
|
62
|
-
const { pipelineOptions } = options;
|
|
63
|
-
const pipelineId = pipelineOptions?.pipelineID;
|
|
64
|
-
markTimingInternal('dispatch_start', pipelineId);
|
|
65
|
-
markTimingInternal('layout_start', pipelineId);
|
|
66
|
-
markTimingInternal('ui_operation_flush_start', pipelineId);
|
|
67
|
-
const page = decodeElementOperation(operations, {
|
|
68
|
-
uniqueIdToElement,
|
|
69
|
-
uniqueIdToCssInJsRule,
|
|
70
|
-
createElementImpl,
|
|
71
|
-
createStyleRuleImpl,
|
|
72
|
-
eventHandler: {
|
|
73
|
-
mtsHandler,
|
|
74
|
-
btsHandler,
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
markTimingInternal('ui_operation_flush_end', pipelineId);
|
|
78
|
-
const isFP = !!page;
|
|
79
|
-
if (isFP) {
|
|
80
|
-
// on FP
|
|
81
|
-
const styleElement = document.createElement('style');
|
|
82
|
-
styleElement.innerHTML = cardCss;
|
|
83
|
-
shadowRoot.append(styleElement);
|
|
84
|
-
shadowRoot.append(page);
|
|
85
|
-
applyPageAttributes(page, pageConfig);
|
|
86
|
-
}
|
|
87
|
-
markTimingInternal('layout_end', pipelineId);
|
|
88
|
-
markTimingInternal('dispatch_end', pipelineId);
|
|
4
|
+
import { flushElementTreeEndpoint, postOffscreenEventEndpoint, } from '@lynx-js/web-constants';
|
|
5
|
+
import { initOffscreenDocument } from '@lynx-js/offscreen-document/main';
|
|
6
|
+
export function registerFlushElementTreeHandler(mainThreadRpc, options, onCommit) {
|
|
7
|
+
const { shadowRoot, } = options;
|
|
8
|
+
const onEvent = mainThreadRpc.createCall(postOffscreenEventEndpoint);
|
|
9
|
+
const { decodeOperation } = initOffscreenDocument({
|
|
10
|
+
shadowRoot,
|
|
11
|
+
onEvent,
|
|
12
|
+
});
|
|
13
|
+
let isFP = true;
|
|
14
|
+
mainThreadRpc.registerHandler(flushElementTreeEndpoint, (operations) => {
|
|
15
|
+
decodeOperation(operations);
|
|
89
16
|
onCommit({
|
|
90
|
-
pipelineId,
|
|
91
|
-
timingFlags,
|
|
92
17
|
isFP,
|
|
93
18
|
});
|
|
19
|
+
if (isFP) {
|
|
20
|
+
isFP = false;
|
|
21
|
+
}
|
|
94
22
|
});
|
|
95
|
-
return { uniqueIdToElement, uniqueIdToCssInJsRule };
|
|
96
23
|
}
|
|
97
24
|
//# sourceMappingURL=registerFlushElementTreeHandler.js.map
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
1
4
|
import { Rpc } from '@lynx-js/web-worker-rpc';
|
|
2
5
|
import { queryNodes } from './queryNodes.js';
|
|
3
|
-
import { ErrorCode,
|
|
6
|
+
import { ErrorCode, invokeUIMethodEndpoint } from '@lynx-js/web-constants';
|
|
4
7
|
const methodAlias = {
|
|
5
8
|
'boundingClientRect': (element) => {
|
|
6
9
|
const rect = element.getBoundingClientRect();
|
|
7
10
|
return {
|
|
8
11
|
id: element.id,
|
|
9
|
-
dataset: element[lynxRuntimeValue]
|
|
10
|
-
.dataset,
|
|
11
12
|
width: rect.width,
|
|
12
13
|
height: rect.height,
|
|
13
14
|
left: rect.left,
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { napiModulesCallEndpoint, } from '@lynx-js/web-constants';
|
|
1
|
+
import { dispatchNapiModuleEndpoint, napiModulesCallEndpoint, } from '@lynx-js/web-constants';
|
|
2
2
|
export function registerNapiModulesCallHandler(rpc, napiModulesCall) {
|
|
3
|
-
rpc.
|
|
3
|
+
const dispatchNapiModules = rpc.createCall(dispatchNapiModuleEndpoint);
|
|
4
|
+
rpc.registerHandler(napiModulesCallEndpoint, (name, data, moduleName) => {
|
|
5
|
+
return napiModulesCall(name, data, moduleName, dispatchNapiModules);
|
|
6
|
+
});
|
|
4
7
|
}
|
|
5
8
|
//# sourceMappingURL=registerNapiModulesCallHandler.js.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
2
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import { createExposureService } from './crossThreadHandlers/createExposureService.js';
|
|
5
4
|
import { registerInvokeUIMethodHandler } from './crossThreadHandlers/registerInvokeUIMethodHandler.js';
|
|
6
5
|
import { registerNativePropsHandler } from './crossThreadHandlers/registerSetNativePropsHandler.js';
|
|
7
6
|
import { registerNativeModulesCallHandler } from './crossThreadHandlers/registerNativeModulesCallHandler.js';
|
|
@@ -9,13 +8,13 @@ import { bootWorkers } from './bootWorkers.js';
|
|
|
9
8
|
import { registerReportErrorHandler } from './crossThreadHandlers/registerReportErrorHandler.js';
|
|
10
9
|
import { registerFlushElementTreeHandler } from './crossThreadHandlers/registerFlushElementTreeHandler.js';
|
|
11
10
|
import { createDispose } from './crossThreadHandlers/createDispose.js';
|
|
12
|
-
import { bootTimingSystem } from './crossThreadHandlers/bootTimingSystem.js';
|
|
13
11
|
import { registerTriggerComponentEventHandler } from './crossThreadHandlers/registerTriggerComponentEventHandler.js';
|
|
14
12
|
import { registerSelectComponentHandler } from './crossThreadHandlers/registerSelectComponentHandler.js';
|
|
15
|
-
import {
|
|
13
|
+
import { mainThreadChunkReadyEndpoint, mainThreadStartEndpoint, markTimingEndpoint, sendGlobalEventEndpoint, uiThreadFpReadyEndpoint, } from '@lynx-js/web-constants';
|
|
16
14
|
import { loadTemplate } from '../utils/loadTemplate.js';
|
|
17
15
|
import { createUpdateData } from './crossThreadHandlers/createUpdateData.js';
|
|
18
16
|
import { registerNapiModulesCallHandler } from './crossThreadHandlers/registerNapiModulesCallHandler.js';
|
|
17
|
+
import { registerDispatchLynxViewEventHandler } from './crossThreadHandlers/registerDispatchLynxViewEventHandler.js';
|
|
19
18
|
export function startUIThread(templateUrl, configs, shadowRoot, callbacks) {
|
|
20
19
|
const createLynxStartTiming = performance.now() + performance.timeOrigin;
|
|
21
20
|
const { nativeModulesMap, napiModulesMap } = configs;
|
|
@@ -23,7 +22,12 @@ export function startUIThread(templateUrl, configs, shadowRoot, callbacks) {
|
|
|
23
22
|
const sendGlobalEvent = backgroundRpc.createCall(sendGlobalEventEndpoint);
|
|
24
23
|
const uiThreadFpReady = backgroundRpc.createCall(uiThreadFpReadyEndpoint);
|
|
25
24
|
const mainThreadStart = mainThreadRpc.createCall(mainThreadStartEndpoint);
|
|
26
|
-
const
|
|
25
|
+
const markTiming = backgroundRpc.createCall(markTimingEndpoint);
|
|
26
|
+
const markTimingInternal = (timingKey, pipelineId, timeStamp) => {
|
|
27
|
+
if (!timeStamp)
|
|
28
|
+
timeStamp = performance.now() + performance.timeOrigin;
|
|
29
|
+
markTiming(timingKey, pipelineId, timeStamp);
|
|
30
|
+
};
|
|
27
31
|
markTimingInternal('create_lynx_start', undefined, createLynxStartTiming);
|
|
28
32
|
markTimingInternal('load_template_start');
|
|
29
33
|
loadTemplate(templateUrl).then((template) => {
|
|
@@ -36,24 +40,20 @@ export function startUIThread(templateUrl, configs, shadowRoot, callbacks) {
|
|
|
36
40
|
});
|
|
37
41
|
});
|
|
38
42
|
registerReportErrorHandler(mainThreadRpc, callbacks.onError);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
registerFlushElementTreeHandler(mainThreadRpc,
|
|
42
|
-
pageConfig,
|
|
43
|
-
backgroundRpc,
|
|
43
|
+
registerDispatchLynxViewEventHandler(backgroundRpc, shadowRoot);
|
|
44
|
+
mainThreadRpc.registerHandler(mainThreadChunkReadyEndpoint, () => {
|
|
45
|
+
registerFlushElementTreeHandler(mainThreadRpc, {
|
|
44
46
|
shadowRoot,
|
|
45
47
|
}, (info) => {
|
|
46
|
-
const {
|
|
48
|
+
const { isFP } = info;
|
|
47
49
|
if (isFP) {
|
|
48
50
|
registerInvokeUIMethodHandler(backgroundRpc, shadowRoot);
|
|
49
51
|
registerNativePropsHandler(backgroundRpc, shadowRoot);
|
|
50
52
|
registerTriggerComponentEventHandler(backgroundRpc, shadowRoot);
|
|
51
53
|
registerSelectComponentHandler(backgroundRpc, shadowRoot);
|
|
52
|
-
createExposureService(backgroundRpc, shadowRoot);
|
|
53
54
|
uiThreadFpReady();
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
-
}, markTimingInternal);
|
|
56
|
+
});
|
|
57
57
|
});
|
|
58
58
|
registerNativeModulesCallHandler(backgroundRpc, callbacks.nativeModulesCall);
|
|
59
59
|
registerNapiModulesCallHandler(backgroundRpc, callbacks.napiModulesCall);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynx-js/web-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "",
|
|
6
6
|
"keywords": [],
|
|
@@ -24,13 +24,14 @@
|
|
|
24
24
|
"**/*.css"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@lynx-js/
|
|
28
|
-
"@lynx-js/web-
|
|
29
|
-
"@lynx-js/web-worker-
|
|
27
|
+
"@lynx-js/offscreen-document": "0.0.0",
|
|
28
|
+
"@lynx-js/web-constants": "0.10.1",
|
|
29
|
+
"@lynx-js/web-worker-rpc": "0.10.1",
|
|
30
|
+
"@lynx-js/web-worker-runtime": "0.10.1"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@lynx-js/lynx-core": "0.1.0",
|
|
33
|
-
"@lynx-js/web-elements": "0.5.
|
|
34
|
+
"@lynx-js/web-elements": "0.5.3"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"@lynx-js/lynx-core": "0.1.0",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { LynxEventType, Cloneable } from '@lynx-js/web-constants';
|
|
2
|
-
import { lynxRuntimeValue } from '@lynx-js/web-constants';
|
|
3
|
-
type RuntimeValue = {
|
|
4
|
-
dataset: {
|
|
5
|
-
[key: string]: Cloneable;
|
|
6
|
-
};
|
|
7
|
-
eventHandler: Record<string, {
|
|
8
|
-
type: LynxEventType;
|
|
9
|
-
handler: (ev: Event) => void;
|
|
10
|
-
hname: string;
|
|
11
|
-
} | undefined>;
|
|
12
|
-
[key: string]: any;
|
|
13
|
-
};
|
|
14
|
-
export type RuntimePropertyOnElement = {
|
|
15
|
-
[lynxRuntimeValue]: RuntimeValue;
|
|
16
|
-
};
|
|
17
|
-
export {};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Rpc } from '@lynx-js/web-worker-rpc';
|
|
2
|
-
export declare function bootTimingSystem(mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, shadowRoot: ShadowRoot): {
|
|
3
|
-
markTimingInternal: (timingKey: string, pipelineId?: string, timeStamp?: number) => void;
|
|
4
|
-
sendTimingResult: (pipelineId: string | undefined, timingFlags: string[], isFp: boolean) => void;
|
|
5
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import { postTimingInfoFromBackgroundThread, postTimingInfoFromMainThread, postTimingResult, } from '@lynx-js/web-constants';
|
|
5
|
-
export function bootTimingSystem(mainThreadRpc, backgroundThreadRpc, shadowRoot) {
|
|
6
|
-
const setupTiming = {};
|
|
7
|
-
const pipelineIdToTiming = new Map();
|
|
8
|
-
let commonTimingFlags = [];
|
|
9
|
-
function markTimingInternal(timingKey, pipelineId, timeStamp) {
|
|
10
|
-
if (!timeStamp)
|
|
11
|
-
timeStamp = performance.now() + performance.timeOrigin;
|
|
12
|
-
if (!pipelineId) {
|
|
13
|
-
setupTiming[timingKey] = timeStamp;
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
if (!pipelineIdToTiming.has(pipelineId)) {
|
|
17
|
-
pipelineIdToTiming.set(pipelineId, {});
|
|
18
|
-
}
|
|
19
|
-
const timingInfo = pipelineIdToTiming.get(pipelineId);
|
|
20
|
-
timingInfo[timingKey] = timeStamp;
|
|
21
|
-
}
|
|
22
|
-
function sendTimingResult(pipelineId, timingFlags, isFp) {
|
|
23
|
-
const timingInfo = (pipelineId ? pipelineIdToTiming.get(pipelineId) : undefined) ?? {};
|
|
24
|
-
if (!pipelineId)
|
|
25
|
-
commonTimingFlags = commonTimingFlags.concat(timingFlags);
|
|
26
|
-
else
|
|
27
|
-
timingFlags = timingFlags.concat(commonTimingFlags);
|
|
28
|
-
backgroundThreadRpc.invoke(postTimingResult, [
|
|
29
|
-
pipelineId,
|
|
30
|
-
timingInfo,
|
|
31
|
-
timingFlags,
|
|
32
|
-
isFp ? setupTiming : undefined,
|
|
33
|
-
]);
|
|
34
|
-
shadowRoot.dispatchEvent(new CustomEvent('timing', {
|
|
35
|
-
detail: isFp ? setupTiming : timingInfo,
|
|
36
|
-
bubbles: true,
|
|
37
|
-
cancelable: true,
|
|
38
|
-
composed: true,
|
|
39
|
-
}));
|
|
40
|
-
if (pipelineId) {
|
|
41
|
-
pipelineIdToTiming.delete(pipelineId);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
mainThreadRpc.registerHandler(postTimingInfoFromMainThread, markTimingInternal);
|
|
45
|
-
backgroundThreadRpc.registerHandler(postTimingInfoFromBackgroundThread, markTimingInternal);
|
|
46
|
-
return {
|
|
47
|
-
markTimingInternal,
|
|
48
|
-
sendTimingResult,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=bootTimingSystem.js.map
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { lynxUniqueIdAttribute, postExposureEndpoint, switchExposureService, } from '@lynx-js/web-constants';
|
|
2
|
-
import { createCrossThreadEvent } from '../../utils/createCrossThreadEvent.js';
|
|
3
|
-
export function createExposureService(rpc, shadowRoot) {
|
|
4
|
-
let working = true;
|
|
5
|
-
let exposureCache = [];
|
|
6
|
-
let disexposureCache = [];
|
|
7
|
-
const onScreen = new Map();
|
|
8
|
-
async function exposureEventHandler(ev) {
|
|
9
|
-
const exposureEvent = createCrossThreadEvent(ev);
|
|
10
|
-
exposureEvent.detail['unique-id'] = parseFloat(ev.target.getAttribute(lynxUniqueIdAttribute));
|
|
11
|
-
const exposureID = exposureEvent.exposureID;
|
|
12
|
-
if (ev.type === 'exposure') {
|
|
13
|
-
exposureCache.push(exposureEvent);
|
|
14
|
-
onScreen.set(exposureID, exposureEvent);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
disexposureCache.push(exposureEvent);
|
|
18
|
-
onScreen.delete(exposureID);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
setInterval(() => {
|
|
22
|
-
if (exposureCache.length > 0 || disexposureCache.length > 0) {
|
|
23
|
-
const currentExposure = exposureCache;
|
|
24
|
-
const currentDisexposure = disexposureCache;
|
|
25
|
-
exposureCache = [];
|
|
26
|
-
disexposureCache = [];
|
|
27
|
-
rpc.invoke(postExposureEndpoint, [{
|
|
28
|
-
exposures: currentExposure,
|
|
29
|
-
disExposures: currentDisexposure,
|
|
30
|
-
}]);
|
|
31
|
-
}
|
|
32
|
-
}, 1000 / 20);
|
|
33
|
-
shadowRoot.addEventListener('exposure', exposureEventHandler, {
|
|
34
|
-
passive: true,
|
|
35
|
-
});
|
|
36
|
-
shadowRoot.addEventListener('disexposure', exposureEventHandler, {
|
|
37
|
-
passive: true,
|
|
38
|
-
});
|
|
39
|
-
rpc.registerHandler(switchExposureService, async (enable, sendEvent) => {
|
|
40
|
-
if (enable && !working) {
|
|
41
|
-
// send all onScreen info
|
|
42
|
-
rpc.invoke(postExposureEndpoint, [{
|
|
43
|
-
exposures: [...onScreen.values()],
|
|
44
|
-
disExposures: [],
|
|
45
|
-
}]);
|
|
46
|
-
}
|
|
47
|
-
else if (!enable && working) {
|
|
48
|
-
if (sendEvent) {
|
|
49
|
-
rpc.invoke(postExposureEndpoint, [{
|
|
50
|
-
exposures: [],
|
|
51
|
-
disExposures: [...onScreen.values()],
|
|
52
|
-
}]);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=createExposureService.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ElementOperation } from '@lynx-js/web-constants';
|
|
2
|
-
import type { RuntimePropertyOnElement } from '../types/RuntimePropertyOnElement.js';
|
|
3
|
-
export declare function decodeElementOperation<T extends HTMLElement & RuntimePropertyOnElement>(operations: ElementOperation[], options: {
|
|
4
|
-
uniqueIdToElement: (WeakRef<T> | undefined)[];
|
|
5
|
-
uniqueIdToCssInJsRule: (WeakRef<CSSStyleRule> | undefined)[];
|
|
6
|
-
createElementImpl: (tag: string) => T;
|
|
7
|
-
createStyleRuleImpl: (uniqueId: number, initialStyle: string) => CSSStyleRule;
|
|
8
|
-
eventHandler: {
|
|
9
|
-
mtsHandler: (event: Event) => void;
|
|
10
|
-
btsHandler: (event: Event) => void;
|
|
11
|
-
};
|
|
12
|
-
}): T | undefined;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import { cssIdAttribute, lynxUniqueIdAttribute, OperationType, lynxRuntimeValue, LynxEventNameToW3cByTagName, LynxEventNameToW3cCommon, W3cEventNameToLynx, __lynx_timing_flag, lynxTagAttribute, } from '@lynx-js/web-constants';
|
|
5
|
-
function getElement(uniqueId, uniqueIdToElement) {
|
|
6
|
-
const element = uniqueIdToElement[uniqueId]?.deref();
|
|
7
|
-
if (element) {
|
|
8
|
-
return element;
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
throw new Error(`[lynx-web] cannot find element with uniqueId: ${uniqueId}`);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
function createElement(tag, uniqueId, uniqueIdToElement, createElementImpl) {
|
|
15
|
-
const current = uniqueIdToElement[uniqueId]?.deref();
|
|
16
|
-
if (current) {
|
|
17
|
-
throw new Error(`[lynx-web] uniqueid is occupied: cannot create new element ${tag} with uniqueId: ${uniqueId}`);
|
|
18
|
-
}
|
|
19
|
-
const element = createElementImpl(tag);
|
|
20
|
-
element.setAttribute(lynxUniqueIdAttribute, uniqueId.toString());
|
|
21
|
-
uniqueIdToElement[uniqueId] = new WeakRef(element);
|
|
22
|
-
return element;
|
|
23
|
-
}
|
|
24
|
-
function handleHtmlEvent(event) {
|
|
25
|
-
const currentTarget = event.currentTarget;
|
|
26
|
-
if (!currentTarget)
|
|
27
|
-
return;
|
|
28
|
-
const { eventHandler, } = currentTarget[lynxRuntimeValue];
|
|
29
|
-
const lynxEventName = W3cEventNameToLynx[event.type] ?? event.type;
|
|
30
|
-
const eventHandlerInfo = eventHandler[lynxEventName];
|
|
31
|
-
if (eventHandlerInfo) {
|
|
32
|
-
const { type: eventType, handler } = eventHandlerInfo;
|
|
33
|
-
const isCatch = eventType === 'catchEvent' || eventType === 'capture-catch';
|
|
34
|
-
handler(event);
|
|
35
|
-
if (isCatch) {
|
|
36
|
-
event.stopPropagation();
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
export function decodeElementOperation(operations, options) {
|
|
41
|
-
const { uniqueIdToElement, uniqueIdToCssInJsRule, createElementImpl, createStyleRuleImpl, eventHandler, } = options;
|
|
42
|
-
let pageElement;
|
|
43
|
-
for (const op of operations) {
|
|
44
|
-
if (op.type === OperationType.Create) {
|
|
45
|
-
const element = createElement(op.tag, op.uid, uniqueIdToElement, createElementImpl);
|
|
46
|
-
if (typeof op.cssId === 'number') {
|
|
47
|
-
element.setAttribute(cssIdAttribute, op.cssId.toString());
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
const target = getElement(op.uid, uniqueIdToElement);
|
|
52
|
-
switch (op.type) {
|
|
53
|
-
case OperationType.Append:
|
|
54
|
-
{
|
|
55
|
-
const children = op.cid.map(id => getElement(id, uniqueIdToElement));
|
|
56
|
-
target.append(...children);
|
|
57
|
-
}
|
|
58
|
-
break;
|
|
59
|
-
case OperationType.InsertBefore:
|
|
60
|
-
{
|
|
61
|
-
const child = getElement(op.cid, uniqueIdToElement);
|
|
62
|
-
const ref = op.ref ? getElement(op.ref, uniqueIdToElement) : null;
|
|
63
|
-
target.insertBefore(child, ref);
|
|
64
|
-
}
|
|
65
|
-
break;
|
|
66
|
-
case OperationType.Remove:
|
|
67
|
-
{
|
|
68
|
-
for (const kidId of op.cid) {
|
|
69
|
-
const kid = getElement(kidId, uniqueIdToElement);
|
|
70
|
-
target.removeChild(kid);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
break;
|
|
74
|
-
case OperationType.Replace:
|
|
75
|
-
{
|
|
76
|
-
const newElements = op.nid.map(id => getElement(id, uniqueIdToElement));
|
|
77
|
-
target.replaceWith(...newElements);
|
|
78
|
-
}
|
|
79
|
-
break;
|
|
80
|
-
case OperationType.SetAttribute:
|
|
81
|
-
{
|
|
82
|
-
if (op.value === null) {
|
|
83
|
-
target.removeAttribute(op.key);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
target.setAttribute(op.key, op.value);
|
|
87
|
-
if (op.key === lynxTagAttribute && op.value === 'page') {
|
|
88
|
-
pageElement = target;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
break;
|
|
93
|
-
case OperationType.SwapElement:
|
|
94
|
-
{
|
|
95
|
-
const targetB = getElement(op.tid, uniqueIdToElement);
|
|
96
|
-
const temp = document.createElement('div');
|
|
97
|
-
target.replaceWith(temp);
|
|
98
|
-
targetB.replaceWith(target);
|
|
99
|
-
temp.replaceWith(targetB);
|
|
100
|
-
}
|
|
101
|
-
break;
|
|
102
|
-
case OperationType.SetProperty:
|
|
103
|
-
target[lynxRuntimeValue][op.key] = op.value;
|
|
104
|
-
if (op.key === 'dataset') {
|
|
105
|
-
if (op.value) {
|
|
106
|
-
for (const [key, value] of Object.entries(op.value)) {
|
|
107
|
-
if (value) {
|
|
108
|
-
target.setAttribute(`data-${key}`, value.toString());
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
target.removeAttribute(`data-${key}`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
target[lynxRuntimeValue]['dataset'] = {};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
break;
|
|
120
|
-
case OperationType.SetDatasetProperty:
|
|
121
|
-
target[lynxRuntimeValue].dataset[op.key] = op.value;
|
|
122
|
-
if (op.value) {
|
|
123
|
-
target.setAttribute(`data-${op.key}`, op.value.toString());
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
target.removeAttribute(`data-${op.key}`);
|
|
127
|
-
}
|
|
128
|
-
break;
|
|
129
|
-
case OperationType.RegisterEventHandler:
|
|
130
|
-
const isMtsHandler = op.hname === null;
|
|
131
|
-
const lynxEventName = op.ename.toLowerCase();
|
|
132
|
-
const htmlEventName = LynxEventNameToW3cByTagName[target.tagName]?.[lynxEventName]
|
|
133
|
-
?? LynxEventNameToW3cCommon[lynxEventName] ?? lynxEventName;
|
|
134
|
-
const currentHandlerInfo = target[lynxRuntimeValue].eventHandler[lynxEventName];
|
|
135
|
-
if (currentHandlerInfo) {
|
|
136
|
-
target.removeEventListener(htmlEventName, handleHtmlEvent);
|
|
137
|
-
}
|
|
138
|
-
const isCaptureEvent = op.eventType === 'capture-bind'
|
|
139
|
-
|| op.eventType === 'capture-catch';
|
|
140
|
-
if (op.hname === undefined) {
|
|
141
|
-
target[lynxRuntimeValue].eventHandler[lynxEventName] = undefined;
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
target.addEventListener(htmlEventName, handleHtmlEvent, {
|
|
145
|
-
passive: true,
|
|
146
|
-
capture: isCaptureEvent,
|
|
147
|
-
});
|
|
148
|
-
target[lynxRuntimeValue].eventHandler[lynxEventName] = {
|
|
149
|
-
type: op.eventType,
|
|
150
|
-
handler: isMtsHandler
|
|
151
|
-
? eventHandler.mtsHandler
|
|
152
|
-
: eventHandler.btsHandler,
|
|
153
|
-
hname: op.hname ?? '',
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
break;
|
|
157
|
-
case OperationType.SetStyleProperty:
|
|
158
|
-
target.style.setProperty(op.key, op.value, op.im ? '!important' : undefined);
|
|
159
|
-
break;
|
|
160
|
-
case OperationType.UpdateCssInJs:
|
|
161
|
-
let rule = uniqueIdToCssInJsRule[op.uid]?.deref();
|
|
162
|
-
if (rule) {
|
|
163
|
-
rule.style.cssText = op.classStyleStr;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
rule = createStyleRuleImpl(op.uid, op.classStyleStr);
|
|
167
|
-
uniqueIdToCssInJsRule[op.uid] = new WeakRef(rule);
|
|
168
|
-
}
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return pageElement;
|
|
174
|
-
}
|
|
175
|
-
//# sourceMappingURL=decodeElementOperation.js.map
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import { lynxRuntimeValue, lynxUniqueIdAttribute, W3cEventNameToLynx, } from '@lynx-js/web-constants';
|
|
5
|
-
export function createCrossThreadEvent(domEvent) {
|
|
6
|
-
const targetElement = domEvent.target;
|
|
7
|
-
const currentTargetElement = domEvent
|
|
8
|
-
.currentTarget;
|
|
9
|
-
const type = domEvent.type;
|
|
10
|
-
const params = {};
|
|
11
|
-
if (type.match(/^transition/)) {
|
|
12
|
-
Object.assign(params, {
|
|
13
|
-
'animation_type': 'keyframe-animation',
|
|
14
|
-
'animation_name': domEvent.propertyName,
|
|
15
|
-
new_animator: true, // we support the new_animator only
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
else if (type.match(/animation/)) {
|
|
19
|
-
Object.assign(params, {
|
|
20
|
-
'animation_type': 'keyframe-animation',
|
|
21
|
-
'animation_name': domEvent.animationName,
|
|
22
|
-
new_animator: true, // we support the new_animator only
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
return {
|
|
26
|
-
type: W3cEventNameToLynx[type] ?? type,
|
|
27
|
-
timestamp: domEvent.timeStamp,
|
|
28
|
-
target: {
|
|
29
|
-
id: targetElement.id,
|
|
30
|
-
dataset: targetElement[lynxRuntimeValue].dataset,
|
|
31
|
-
uniqueId: parseFloat(targetElement.getAttribute(lynxUniqueIdAttribute)),
|
|
32
|
-
},
|
|
33
|
-
currentTarget: {
|
|
34
|
-
id: currentTargetElement.id,
|
|
35
|
-
dataset: currentTargetElement[lynxRuntimeValue]?.dataset ?? {},
|
|
36
|
-
uniqueId: parseFloat(currentTargetElement.getAttribute?.(lynxUniqueIdAttribute)),
|
|
37
|
-
},
|
|
38
|
-
// @ts-expect-error
|
|
39
|
-
detail: domEvent.detail ?? {},
|
|
40
|
-
params,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=createCrossThreadEvent.js.map
|