@lynx-js/web-mainthread-apis 0.9.1 → 0.10.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/CHANGELOG.md +31 -0
- package/dist/MainThreadLynx.js +13 -6
- package/dist/MainThreadRuntime.d.ts +42 -9
- package/dist/MainThreadRuntime.js +89 -33
- package/dist/elementAPI/ElementThreadElement.d.ts +18 -68
- package/dist/elementAPI/ElementThreadElement.js +1 -269
- package/dist/elementAPI/attributeAndProperty/attributeAndPropertyFunctions.d.ts +29 -23
- package/dist/elementAPI/attributeAndProperty/attributeAndPropertyFunctions.js +115 -52
- package/dist/elementAPI/domTree/domTreeFunctions.d.ts +11 -13
- package/dist/elementAPI/domTree/domTreeFunctions.js +8 -11
- package/dist/elementAPI/elementCreating/elementCreatingFunctions.d.ts +14 -21
- package/dist/elementAPI/elementCreating/elementCreatingFunctions.js +42 -21
- package/dist/elementAPI/event/eventFunctions.d.ts +16 -14
- package/dist/elementAPI/event/eventFunctions.js +130 -26
- package/dist/elementAPI/style/styleFunctions.d.ts +10 -7
- package/dist/elementAPI/style/styleFunctions.js +66 -52
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/utils/createCrossThreadEvent.d.ts +3 -0
- package/dist/utils/createCrossThreadEvent.js +44 -0
- package/dist/utils/createExposureService.d.ts +4 -0
- package/dist/utils/createExposureService.js +63 -0
- package/package.json +2 -2
- package/dist/elementAPI/attributeAndProperty/createAttributeAndPropertyFunctionsWithContext.d.ts +0 -5
- package/dist/elementAPI/attributeAndProperty/createAttributeAndPropertyFunctionsWithContext.js +0 -13
- package/dist/elementAPI/createOffscreenDocument.d.ts +0 -13
- package/dist/elementAPI/createOffscreenDocument.js +0 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @lynx-js/web-mainthread-apis
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- feat: rewrite the main thread Element PAPIs ([#343](https://github.com/lynx-family/lynx-stack/pull/343))
|
|
8
|
+
|
|
9
|
+
In this commit we've rewritten the main thread apis.
|
|
10
|
+
|
|
11
|
+
The most highlighted change is that
|
|
12
|
+
|
|
13
|
+
- Before this commit we send events directly to bts
|
|
14
|
+
- After this change, we send events to mts then send them to bts with some data combined.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- feat(web): use pure DOM API to implement Element PAPIs ([#334](https://github.com/lynx-family/lynx-stack/pull/334))
|
|
19
|
+
|
|
20
|
+
1. rewrite all element PAPIs impl. Now we use DOM.
|
|
21
|
+
2. use our new package `@lynx-js/offscreen-document` to support the new Element PAPI implementation in a worker
|
|
22
|
+
|
|
23
|
+
- fix: inline style will be removed for value number `0` ([#368](https://github.com/lynx-family/lynx-stack/pull/368))
|
|
24
|
+
|
|
25
|
+
the inline style value could be incorrectly removed for number value `0`;
|
|
26
|
+
|
|
27
|
+
For example, `flex-shrink:0` may be ignored.
|
|
28
|
+
|
|
29
|
+
- fix: publicComponentEvent args order ([#401](https://github.com/lynx-family/lynx-stack/pull/401))
|
|
30
|
+
|
|
31
|
+
- 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)]:
|
|
32
|
+
- @lynx-js/web-constants@0.10.0
|
|
33
|
+
|
|
3
34
|
## 0.9.1
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/dist/MainThreadLynx.js
CHANGED
|
@@ -9,12 +9,19 @@ export function createMainThreadLynx(config, lepusRuntime) {
|
|
|
9
9
|
},
|
|
10
10
|
__globalProps: config.globalProps,
|
|
11
11
|
requireModule(path) {
|
|
12
|
-
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
// @ts-expect-error
|
|
13
|
+
if (self.WorkerGlobalScope) {
|
|
14
|
+
const mainfestUrl = config.lepusCode[`/${path}`];
|
|
15
|
+
if (mainfestUrl)
|
|
16
|
+
path = mainfestUrl;
|
|
17
|
+
// @ts-expect-error
|
|
18
|
+
importScripts(path);
|
|
19
|
+
const entry = globalThis.module.exports;
|
|
20
|
+
return entry?.(lepusRuntime);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw new Error('importing scripts synchronously is only available for the multi-thread running mode');
|
|
24
|
+
}
|
|
18
25
|
},
|
|
19
26
|
requireModuleAsync(path, callback) {
|
|
20
27
|
const mainfestUrl = config.lepusCode[`/${path}`];
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type LynxTemplate, type PageConfig, type ProcessDataCallback, type StyleInfo, type FlushElementTreeOptions, type Cloneable, type BrowserConfig, type publishEventEndpoint, type publicComponentEventEndpoint, type reportErrorEndpoint, type onLifecycleEventEndpoint, type RpcCallType, type postExposureEndpoint } from '@lynx-js/web-constants';
|
|
2
2
|
import { type MainThreadLynx } from './MainThreadLynx.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { LynxRuntimeInfo } from './elementAPI/ElementThreadElement.js';
|
|
4
4
|
export interface MainThreadRuntimeCallbacks {
|
|
5
5
|
mainChunkReady: () => void;
|
|
6
|
-
flushElementTree:
|
|
6
|
+
flushElementTree: (options: FlushElementTreeOptions, timingFlags: string[]) => void;
|
|
7
7
|
_ReportError: RpcCallType<typeof reportErrorEndpoint>;
|
|
8
8
|
__OnLifecycleEvent: RpcCallType<typeof onLifecycleEventEndpoint>;
|
|
9
9
|
markTiming: (pipelineId: string, timingKey: string) => void;
|
|
10
|
+
publishEvent: RpcCallType<typeof publishEventEndpoint>;
|
|
11
|
+
publicComponentEvent: RpcCallType<typeof publicComponentEventEndpoint>;
|
|
12
|
+
postExposure: RpcCallType<typeof postExposureEndpoint>;
|
|
10
13
|
}
|
|
11
14
|
export interface MainThreadConfig {
|
|
12
15
|
pageConfig: PageConfig;
|
|
@@ -17,26 +20,56 @@ export interface MainThreadConfig {
|
|
|
17
20
|
lepusCode: LynxTemplate['lepusCode'];
|
|
18
21
|
browserConfig: BrowserConfig;
|
|
19
22
|
tagMap: Record<string, string>;
|
|
23
|
+
docu: Pick<Document, 'append' | 'createElement' | 'addEventListener'>;
|
|
20
24
|
}
|
|
25
|
+
export declare const elementToRuntimeInfoMap: unique symbol;
|
|
26
|
+
export declare const getElementByUniqueId: unique symbol;
|
|
27
|
+
export declare const updateCSSInJsStyle: unique symbol;
|
|
28
|
+
export declare const lynxUniqueIdToElement: unique symbol;
|
|
29
|
+
export declare const switchExposureService: unique symbol;
|
|
21
30
|
export declare class MainThreadRuntime {
|
|
22
31
|
#private;
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
config: MainThreadConfig;
|
|
33
|
+
/**
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
[lynxUniqueIdToElement]: WeakRef<HTMLElement>[];
|
|
37
|
+
/**
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
[switchExposureService]: (enable: boolean, sendEvent: boolean) => void;
|
|
41
|
+
/**
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
private _lynxUniqueIdToStyleSheet;
|
|
45
|
+
/**
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
_page?: HTMLElement;
|
|
49
|
+
/**
|
|
50
|
+
* @private the CreatePage will append it to this
|
|
51
|
+
*/
|
|
52
|
+
_rootDom: Pick<Element, 'append' | 'addEventListener'>;
|
|
25
53
|
/**
|
|
26
54
|
* @private
|
|
27
55
|
*/
|
|
28
56
|
_timingFlags: string[];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
[elementToRuntimeInfoMap]: WeakMap<HTMLElement, LynxRuntimeInfo>;
|
|
32
61
|
constructor(config: MainThreadConfig);
|
|
62
|
+
/**
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
[getElementByUniqueId](uniqueId: number): HTMLElement | undefined;
|
|
66
|
+
[updateCSSInJsStyle](uniqueId: number, newStyles: string): void;
|
|
33
67
|
/**
|
|
34
68
|
* @private
|
|
35
69
|
*/
|
|
36
70
|
__lynxGlobalBindingValues: Record<string, any>;
|
|
37
71
|
get globalThis(): this;
|
|
38
72
|
lynx: MainThreadLynx;
|
|
39
|
-
NativeModules: undefined;
|
|
40
73
|
__globalProps: unknown;
|
|
41
74
|
processData?: ProcessDataCallback;
|
|
42
75
|
renderPage: (data: unknown) => void;
|
|
@@ -1,52 +1,87 @@
|
|
|
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 {} from '@lynx-js/web-constants';
|
|
4
|
+
import { lynxUniqueIdAttribute, } from '@lynx-js/web-constants';
|
|
5
5
|
import { globalMuteableVars } from '@lynx-js/web-constants';
|
|
6
6
|
import { createMainThreadLynx } from './MainThreadLynx.js';
|
|
7
7
|
import { initializeElementCreatingFunction } from './elementAPI/elementCreating/elementCreatingFunctions.js';
|
|
8
|
-
import
|
|
8
|
+
import { createAttributeAndPropertyFunctions } from './elementAPI/attributeAndProperty/attributeAndPropertyFunctions.js';
|
|
9
9
|
import * as domTreeApis from './elementAPI/domTree/domTreeFunctions.js';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
10
|
+
import { createEventFunctions } from './elementAPI/event/eventFunctions.js';
|
|
11
|
+
import { createStyleFunctions } from './elementAPI/style/styleFunctions.js';
|
|
12
12
|
import { flattenStyleInfo, genCssContent, genCssInJsInfo, transformToWebCss, } from './utils/processStyleInfo.js';
|
|
13
|
-
import {
|
|
13
|
+
import { createExposureService } from './utils/createExposureService.js';
|
|
14
|
+
export const elementToRuntimeInfoMap = Symbol('elementToRuntimeInfoMap');
|
|
15
|
+
export const getElementByUniqueId = Symbol('getElementByUniqueId');
|
|
16
|
+
export const updateCSSInJsStyle = Symbol('updateCSSInJsStyle');
|
|
17
|
+
export const lynxUniqueIdToElement = Symbol('lynxUniqueIdToElement');
|
|
18
|
+
export const switchExposureService = Symbol('switchExposureService');
|
|
14
19
|
export class MainThreadRuntime {
|
|
15
20
|
config;
|
|
16
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
[lynxUniqueIdToElement] = [];
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
[switchExposureService];
|
|
29
|
+
/**
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
_lynxUniqueIdToStyleSheet = [];
|
|
33
|
+
/**
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
_page;
|
|
37
|
+
/**
|
|
38
|
+
* @private the CreatePage will append it to this
|
|
39
|
+
*/
|
|
40
|
+
_rootDom;
|
|
17
41
|
/**
|
|
18
42
|
* @private
|
|
19
43
|
*/
|
|
20
44
|
_timingFlags = [];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
/**
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
[elementToRuntimeInfoMap] = new WeakMap();
|
|
24
49
|
constructor(config) {
|
|
25
50
|
this.config = config;
|
|
26
51
|
this.__globalProps = config.globalProps;
|
|
27
52
|
this.lynx = createMainThreadLynx(config, this);
|
|
53
|
+
/**
|
|
54
|
+
* now create the style content
|
|
55
|
+
* 1. flatten the styleInfo
|
|
56
|
+
* 2. transform the styleInfo to web css
|
|
57
|
+
* 3. generate the css in js info
|
|
58
|
+
* 4. create the style element
|
|
59
|
+
* 5. append the style element to the root dom
|
|
60
|
+
*/
|
|
28
61
|
flattenStyleInfo(this.config.styleInfo);
|
|
29
62
|
transformToWebCss(this.config.styleInfo);
|
|
30
|
-
const
|
|
63
|
+
const cssInJsInfo = this.config.pageConfig.enableCSSSelector
|
|
31
64
|
? {}
|
|
32
65
|
: genCssInJsInfo(this.config.styleInfo);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
}
|
|
46
|
-
return false;
|
|
47
|
-
};
|
|
66
|
+
this._rootDom = this.config.docu.createElement('div');
|
|
67
|
+
const cardStyleElement = this.config.docu.createElement('style');
|
|
68
|
+
cardStyleElement.innerHTML = genCssContent(this.config.styleInfo, this.config.pageConfig);
|
|
69
|
+
this._rootDom = this.config.docu;
|
|
70
|
+
this._rootDom.append(cardStyleElement);
|
|
71
|
+
/**
|
|
72
|
+
* now create Element PAPIs
|
|
73
|
+
*/
|
|
74
|
+
Object.assign(this, createAttributeAndPropertyFunctions(this), domTreeApis, createEventFunctions(this), createStyleFunctions(this, cssInJsInfo), initializeElementCreatingFunction(this));
|
|
48
75
|
this._ReportError = this.config.callbacks._ReportError;
|
|
49
76
|
this.__OnLifecycleEvent = this.config.callbacks.__OnLifecycleEvent;
|
|
77
|
+
/**
|
|
78
|
+
* Start the exposure service
|
|
79
|
+
*/
|
|
80
|
+
this[switchExposureService] =
|
|
81
|
+
createExposureService(this).switchExposureService;
|
|
82
|
+
/**
|
|
83
|
+
* to know when the main thread is ready
|
|
84
|
+
*/
|
|
50
85
|
Object.defineProperty(this, 'renderPage', {
|
|
51
86
|
get: () => {
|
|
52
87
|
return this.#renderPage;
|
|
@@ -68,6 +103,22 @@ export class MainThreadRuntime {
|
|
|
68
103
|
});
|
|
69
104
|
}
|
|
70
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
[getElementByUniqueId](uniqueId) {
|
|
110
|
+
return this[lynxUniqueIdToElement][uniqueId]?.deref();
|
|
111
|
+
}
|
|
112
|
+
[updateCSSInJsStyle](uniqueId, newStyles) {
|
|
113
|
+
let currentElement = this._lynxUniqueIdToStyleSheet[uniqueId]?.deref();
|
|
114
|
+
if (!currentElement) {
|
|
115
|
+
currentElement = this.config.docu.createElement('style');
|
|
116
|
+
this._lynxUniqueIdToStyleSheet[uniqueId] = new WeakRef(currentElement);
|
|
117
|
+
this._rootDom.append(currentElement);
|
|
118
|
+
}
|
|
119
|
+
currentElement.innerHTML =
|
|
120
|
+
`[${lynxUniqueIdAttribute}="${uniqueId}"]{${newStyles}}`;
|
|
121
|
+
}
|
|
71
122
|
/**
|
|
72
123
|
* @private
|
|
73
124
|
*/
|
|
@@ -76,22 +127,27 @@ export class MainThreadRuntime {
|
|
|
76
127
|
return this;
|
|
77
128
|
}
|
|
78
129
|
lynx;
|
|
79
|
-
NativeModules = undefined;
|
|
80
130
|
__globalProps;
|
|
81
131
|
processData;
|
|
82
132
|
#renderPage;
|
|
83
133
|
_ReportError;
|
|
84
134
|
__OnLifecycleEvent;
|
|
85
|
-
__LoadLepusChunk
|
|
135
|
+
__LoadLepusChunk = (path) => {
|
|
136
|
+
try {
|
|
137
|
+
this.lynx.requireModule(path);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
};
|
|
86
144
|
__FlushElementTree = (_subTree, options) => {
|
|
87
|
-
const operations = this.operationsRef.operations;
|
|
88
145
|
const timingFlags = this._timingFlags;
|
|
89
|
-
this.operationsRef.operations = [];
|
|
90
146
|
this._timingFlags = [];
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.
|
|
147
|
+
if (this._page && !this._page.parentElement) {
|
|
148
|
+
this._rootDom.append(this._page);
|
|
149
|
+
}
|
|
150
|
+
this.config.callbacks.flushElementTree(options, timingFlags);
|
|
95
151
|
};
|
|
96
152
|
updatePage;
|
|
97
153
|
_updateVars;
|
|
@@ -1,71 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare enum RefCountType {
|
|
4
|
-
Element = 0
|
|
5
|
-
}
|
|
6
|
-
export declare class ElementThreadElement {
|
|
7
|
-
tag: string;
|
|
1
|
+
import type { LynxEventType, Cloneable } from '@lynx-js/web-constants';
|
|
2
|
+
export interface LynxRuntimeInfo {
|
|
8
3
|
uniqueId: number;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
static uniqueIdToElement: (WeakRef<ElementThreadElement> | undefined)[];
|
|
13
|
-
static receiveEvent(event: LynxCrossThreadEvent): void;
|
|
14
|
-
static getElementByUniqueId(uniqueId: number): ElementThreadElement | undefined;
|
|
15
|
-
type: RefCountType;
|
|
4
|
+
parentComponentUniqueId: number;
|
|
5
|
+
componentConfig: Record<string, Cloneable>;
|
|
6
|
+
lynxDataset: Record<string, Cloneable>;
|
|
16
7
|
eventHandlerMap: Record<string, {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
property: {
|
|
29
|
-
parent?: ElementThreadElement;
|
|
30
|
-
componentConfig: Record<string, unknown>;
|
|
31
|
-
dataset: Record<string, unknown>;
|
|
32
|
-
[key: string]: unknown;
|
|
33
|
-
};
|
|
34
|
-
children: ElementThreadElement[];
|
|
35
|
-
parent?: ElementThreadElement;
|
|
36
|
-
constructor(tag: string, uniqueId: number, pageConfig: PageConfig, operationsRef: {
|
|
37
|
-
operations: ElementOperation[];
|
|
38
|
-
}, styleInfo: CssInJsInfo);
|
|
39
|
-
setProperty(key: string, value: any): void;
|
|
40
|
-
setDatasetProperty(key: string, value: any): void;
|
|
41
|
-
setAttribute(key: string, value: string | null): void;
|
|
42
|
-
getAttribute<T extends keyof ElementThreadElement['attributes']>(key: T): ElementThreadElement['attributes'][T];
|
|
43
|
-
appendChild(children: ElementThreadElement[]): void;
|
|
44
|
-
removeChild(child: ElementThreadElement): ElementThreadElement;
|
|
45
|
-
replaceWithElements(newElements: ElementThreadElement[]): void;
|
|
46
|
-
swapWith(elementB: ElementThreadElement): void;
|
|
47
|
-
insertBefore(child: ElementThreadElement, ref?: ElementThreadElement | null): ElementThreadElement;
|
|
48
|
-
updateCssInJsGeneratedStyle(classStyleStr: string): void;
|
|
49
|
-
setStyleProperty(key: string, value: string | null, important?: boolean): void;
|
|
50
|
-
setEventHandler(ename: string, handler: ((ev: LynxCrossThreadEvent) => void) | string | undefined, eventType: LynxEventType): void;
|
|
51
|
-
get firstElementChild(): ElementThreadElement | undefined;
|
|
52
|
-
get lastElementChild(): ElementThreadElement | undefined;
|
|
53
|
-
get nextElementSibling(): ElementThreadElement | undefined;
|
|
54
|
-
}
|
|
55
|
-
export type ComponentAtIndexCallback = (list: ListElement, listID: number, cellIndex: number, operationID: number, enableReuseNotification: boolean) => void;
|
|
56
|
-
export type EnqueueComponentCallback = (list: ListElement, listID: number, sign: number) => void;
|
|
57
|
-
type UpdateListInfoAttributeValue = {
|
|
58
|
-
insertAction: {
|
|
59
|
-
position: number;
|
|
60
|
-
}[];
|
|
61
|
-
removeAction: {
|
|
62
|
-
position: number;
|
|
63
|
-
}[];
|
|
64
|
-
};
|
|
65
|
-
export declare class ListElement extends ElementThreadElement {
|
|
66
|
-
componentAtIndex: ComponentAtIndexCallback;
|
|
67
|
-
enqueueComponent: EnqueueComponentCallback;
|
|
68
|
-
setAttribute(key: 'update-list-info', value: UpdateListInfoAttributeValue): void;
|
|
69
|
-
setAttribute(key: Exclude<string, 'update-list-info'>, value: string | null): void;
|
|
8
|
+
capture: {
|
|
9
|
+
type: LynxEventType;
|
|
10
|
+
handler: string;
|
|
11
|
+
} | undefined;
|
|
12
|
+
bind: {
|
|
13
|
+
type: LynxEventType;
|
|
14
|
+
handler: string;
|
|
15
|
+
} | undefined;
|
|
16
|
+
}>;
|
|
17
|
+
componentAtIndex?: ComponentAtIndexCallback;
|
|
18
|
+
enqueueComponent?: EnqueueComponentCallback;
|
|
70
19
|
}
|
|
71
|
-
export
|
|
20
|
+
export type ComponentAtIndexCallback = (list: HTMLElement, listID: number, cellIndex: number, operationID: number, enableReuseNotification: boolean) => void;
|
|
21
|
+
export type EnqueueComponentCallback = (list: HTMLElement, listID: number, sign: number) => void;
|
|
@@ -1,270 +1,2 @@
|
|
|
1
|
-
|
|
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 { componentIdAttribute, cssIdAttribute, OperationType, } from '@lynx-js/web-constants';
|
|
5
|
-
function getParentIdx(element, parent) {
|
|
6
|
-
parent = parent ?? element.parent;
|
|
7
|
-
const idx = parent.children.findIndex((e) => e === element);
|
|
8
|
-
if (idx === -1) {
|
|
9
|
-
console.error(`[lynx-web]`, element, ` is not a child of`, parent);
|
|
10
|
-
throw new Error(`[lynx-web] ${element} is not a child of ${parent}`);
|
|
11
|
-
}
|
|
12
|
-
return idx;
|
|
13
|
-
}
|
|
14
|
-
export var RefCountType;
|
|
15
|
-
(function (RefCountType) {
|
|
16
|
-
RefCountType[RefCountType["Element"] = 0] = "Element";
|
|
17
|
-
})(RefCountType || (RefCountType = {}));
|
|
18
|
-
export class ElementThreadElement {
|
|
19
|
-
tag;
|
|
20
|
-
uniqueId;
|
|
21
|
-
pageConfig;
|
|
22
|
-
operationsRef;
|
|
23
|
-
styleInfo;
|
|
24
|
-
static uniqueIdToElement = [];
|
|
25
|
-
static receiveEvent(event) {
|
|
26
|
-
const currentTargetUniqueId = event.currentTarget.uniqueId;
|
|
27
|
-
const target = this.uniqueIdToElement[currentTargetUniqueId]?.deref();
|
|
28
|
-
if (target) {
|
|
29
|
-
const handler = target.eventHandlerMap[event.type]?.handler;
|
|
30
|
-
if (typeof handler === 'function') {
|
|
31
|
-
queueMicrotask(() => {
|
|
32
|
-
handler(event);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
this.uniqueIdToElement[currentTargetUniqueId] = undefined;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
static getElementByUniqueId(uniqueId) {
|
|
41
|
-
return ElementThreadElement.uniqueIdToElement[uniqueId]?.deref();
|
|
42
|
-
}
|
|
43
|
-
type = RefCountType.Element;
|
|
44
|
-
eventHandlerMap = {};
|
|
45
|
-
attributes;
|
|
46
|
-
property = {
|
|
47
|
-
componentConfig: {},
|
|
48
|
-
dataset: {},
|
|
49
|
-
};
|
|
50
|
-
children = [];
|
|
51
|
-
parent;
|
|
52
|
-
// public parentComponentUniqueId!: number;
|
|
53
|
-
constructor(tag, uniqueId, pageConfig, operationsRef, styleInfo) {
|
|
54
|
-
this.tag = tag;
|
|
55
|
-
this.uniqueId = uniqueId;
|
|
56
|
-
this.pageConfig = pageConfig;
|
|
57
|
-
this.operationsRef = operationsRef;
|
|
58
|
-
this.styleInfo = styleInfo;
|
|
59
|
-
this.attributes = {
|
|
60
|
-
style: null,
|
|
61
|
-
class: '',
|
|
62
|
-
[cssIdAttribute]: null,
|
|
63
|
-
};
|
|
64
|
-
ElementThreadElement.uniqueIdToElement[this.uniqueId] = new WeakRef(this);
|
|
65
|
-
operationsRef.operations.push({
|
|
66
|
-
type: OperationType.Create,
|
|
67
|
-
uid: uniqueId,
|
|
68
|
-
tag: tag,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
setProperty(key, value) {
|
|
72
|
-
this.property[key] = value;
|
|
73
|
-
if (key === 'dataset') {
|
|
74
|
-
this.operationsRef.operations.push({
|
|
75
|
-
uid: this.uniqueId,
|
|
76
|
-
type: OperationType.SetProperty,
|
|
77
|
-
key: key,
|
|
78
|
-
value: value,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
setDatasetProperty(key, value) {
|
|
83
|
-
this.property.dataset[key] = value;
|
|
84
|
-
this.operationsRef.operations.push({
|
|
85
|
-
uid: this.uniqueId,
|
|
86
|
-
type: OperationType.SetDatasetProperty,
|
|
87
|
-
key,
|
|
88
|
-
value,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
setAttribute(key, value) {
|
|
92
|
-
this.attributes[key] = value;
|
|
93
|
-
this.operationsRef.operations.push({
|
|
94
|
-
uid: this.uniqueId,
|
|
95
|
-
type: OperationType.SetAttribute,
|
|
96
|
-
key,
|
|
97
|
-
value,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
getAttribute(key) {
|
|
101
|
-
return this.attributes[key];
|
|
102
|
-
}
|
|
103
|
-
appendChild(children) {
|
|
104
|
-
this.children.push(...children);
|
|
105
|
-
for (const kid of children) {
|
|
106
|
-
if (kid.parent) {
|
|
107
|
-
// note that Node.appendChild() will do `move node` Implicitly.
|
|
108
|
-
const idx = getParentIdx(kid);
|
|
109
|
-
kid.parent.children.splice(idx, 1);
|
|
110
|
-
}
|
|
111
|
-
kid.parent = this;
|
|
112
|
-
}
|
|
113
|
-
this.operationsRef.operations.push({
|
|
114
|
-
uid: this.uniqueId,
|
|
115
|
-
type: OperationType.Append,
|
|
116
|
-
cid: children.map(e => e.uniqueId),
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
removeChild(child) {
|
|
120
|
-
const idx = getParentIdx(child, this);
|
|
121
|
-
this.children.splice(idx, 1);
|
|
122
|
-
child.parent = undefined;
|
|
123
|
-
this.operationsRef.operations.push({
|
|
124
|
-
type: OperationType.Remove,
|
|
125
|
-
uid: this.uniqueId,
|
|
126
|
-
cid: [child.uniqueId],
|
|
127
|
-
});
|
|
128
|
-
return child;
|
|
129
|
-
}
|
|
130
|
-
replaceWithElements(newElements) {
|
|
131
|
-
for (const kid of newElements) {
|
|
132
|
-
if (this.parent === kid) {
|
|
133
|
-
console.error(`[lynx-web] cannot replace the element`, this, `by its parent`, kid);
|
|
134
|
-
throw new Error(`[lynx-web] cannot replace `);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const parent = this.parent;
|
|
138
|
-
if (parent) {
|
|
139
|
-
const currentPosition = getParentIdx(this);
|
|
140
|
-
parent.children.splice(currentPosition, 1);
|
|
141
|
-
this.parent = undefined;
|
|
142
|
-
for (const kid of newElements) {
|
|
143
|
-
if (kid.parent) {
|
|
144
|
-
const idx = getParentIdx(kid);
|
|
145
|
-
kid.parent.children.splice(idx, 1);
|
|
146
|
-
}
|
|
147
|
-
kid.parent = parent;
|
|
148
|
-
}
|
|
149
|
-
parent.children.splice(currentPosition, 0, ...newElements);
|
|
150
|
-
this.operationsRef.operations.push({
|
|
151
|
-
type: OperationType.Replace,
|
|
152
|
-
uid: this.uniqueId,
|
|
153
|
-
nid: newElements.map(e => e.uniqueId),
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
swapWith(elementB) {
|
|
158
|
-
const parentA = this.parent;
|
|
159
|
-
const parentB = elementB.parent;
|
|
160
|
-
const idxA = getParentIdx(this);
|
|
161
|
-
const idxB = getParentIdx(elementB);
|
|
162
|
-
parentA.children[idxA] = elementB;
|
|
163
|
-
elementB.parent = parentA;
|
|
164
|
-
parentB.children[idxB] = this;
|
|
165
|
-
this.parent = parentB;
|
|
166
|
-
this.operationsRef.operations.push({
|
|
167
|
-
type: OperationType.SwapElement,
|
|
168
|
-
uid: this.uniqueId,
|
|
169
|
-
tid: elementB.uniqueId,
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
insertBefore(child, ref) {
|
|
173
|
-
if (ref) {
|
|
174
|
-
const idx = getParentIdx(ref, this);
|
|
175
|
-
this.children.splice(idx, 0, child);
|
|
176
|
-
child.parent = this;
|
|
177
|
-
this.operationsRef.operations.push({
|
|
178
|
-
type: OperationType.InsertBefore,
|
|
179
|
-
uid: this.uniqueId,
|
|
180
|
-
cid: child.uniqueId,
|
|
181
|
-
ref: ref.uniqueId,
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
this.children.push(child);
|
|
186
|
-
child.parent = this;
|
|
187
|
-
this.operationsRef.operations.push({
|
|
188
|
-
type: OperationType.Append,
|
|
189
|
-
uid: this.uniqueId,
|
|
190
|
-
cid: [child.uniqueId],
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
return child;
|
|
194
|
-
}
|
|
195
|
-
updateCssInJsGeneratedStyle(classStyleStr) {
|
|
196
|
-
this.operationsRef.operations.push({
|
|
197
|
-
type: OperationType.UpdateCssInJs,
|
|
198
|
-
uid: this.uniqueId,
|
|
199
|
-
classStyleStr,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
setStyleProperty(key, value, important) {
|
|
203
|
-
this.attributes.style = (this.attributes.style ?? '')
|
|
204
|
-
+ `${key}:${value ?? ''}${important ? '!important' : ''};`;
|
|
205
|
-
this.operationsRef.operations.push({
|
|
206
|
-
type: OperationType.SetStyleProperty,
|
|
207
|
-
uid: this.uniqueId,
|
|
208
|
-
key,
|
|
209
|
-
value,
|
|
210
|
-
im: important,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
setEventHandler(ename, handler, eventType) {
|
|
214
|
-
let hname;
|
|
215
|
-
if (handler) {
|
|
216
|
-
this.eventHandlerMap[ename] = { type: eventType, handler };
|
|
217
|
-
if (typeof handler === 'function') {
|
|
218
|
-
hname = null;
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
hname = handler;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
this.eventHandlerMap[ename] = undefined;
|
|
226
|
-
}
|
|
227
|
-
this.operationsRef.operations.push({
|
|
228
|
-
type: OperationType.RegisterEventHandler,
|
|
229
|
-
uid: this.uniqueId,
|
|
230
|
-
eventType,
|
|
231
|
-
hname,
|
|
232
|
-
ename,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
get firstElementChild() {
|
|
236
|
-
return this.children[0];
|
|
237
|
-
}
|
|
238
|
-
get lastElementChild() {
|
|
239
|
-
const childLength = this.children.length;
|
|
240
|
-
return childLength > 0 ? this.children[childLength - 1] : undefined;
|
|
241
|
-
}
|
|
242
|
-
get nextElementSibling() {
|
|
243
|
-
if (this.parent) {
|
|
244
|
-
const idx = getParentIdx(this);
|
|
245
|
-
return this.parent.children[idx + 1];
|
|
246
|
-
}
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
export class ListElement extends ElementThreadElement {
|
|
251
|
-
componentAtIndex;
|
|
252
|
-
enqueueComponent;
|
|
253
|
-
setAttribute(key, value) {
|
|
254
|
-
if (key === 'update-list-info' && value) {
|
|
255
|
-
const listInfo = value;
|
|
256
|
-
const { insertAction, removeAction } = listInfo;
|
|
257
|
-
queueMicrotask(() => {
|
|
258
|
-
for (const action of insertAction) {
|
|
259
|
-
this.componentAtIndex(this, this.uniqueId, action.position, 0, false);
|
|
260
|
-
}
|
|
261
|
-
for (const action of removeAction) {
|
|
262
|
-
this.enqueueComponent(this, this.uniqueId, action.position);
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
value = value.toString();
|
|
266
|
-
}
|
|
267
|
-
super.setAttribute(key, value);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
1
|
+
export {};
|
|
270
2
|
//# sourceMappingURL=ElementThreadElement.js.map
|