@lynx-js/web-mainthread-apis 0.14.2 → 0.15.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 CHANGED
@@ -1,5 +1,37 @@
1
1
  # @lynx-js/web-mainthread-apis
2
2
 
3
+ ## 0.15.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`e59138b`](https://github.com/lynx-family/lynx-stack/commit/e59138b3c2285ce83a2927ee046671b9015acdfd)]:
8
+ - @lynx-js/web-style-transformer@0.3.3
9
+ - @lynx-js/web-constants@0.15.1
10
+
11
+ ## 0.15.0
12
+
13
+ ### Minor Changes
14
+
15
+ - refactor: move exposure system to web-core ([#1254](https://github.com/lynx-family/lynx-stack/pull/1254))
16
+
17
+ **THIS IS A BREAKING CHANGE**
18
+
19
+ **You'll need to upgrade your @lynx-js/web-elements to >= 0.8.0**
20
+
21
+ For SSR and better performance, we moved the lynx's exposure system from web-element to web-core.
22
+
23
+ Before this commit, we create Intersection observers by creating HTMLElements.
24
+
25
+ After this commit, we will create such Intersection observers after dom stabled.
26
+
27
+ Also, the setInterval for exposure has been removed, now we use an on time lazy timer for such features.
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies [[`16f402f`](https://github.com/lynx-family/lynx-stack/commit/16f402f557ba12ec34a35a1b9b00115bf576c20f), [`60095d7`](https://github.com/lynx-family/lynx-stack/commit/60095d741ae969e76a8faeb669a0fbe7e6e81f7c), [`224c653`](https://github.com/lynx-family/lynx-stack/commit/224c653f370d807281fa0a9ffbb4f4dd5c9d308e)]:
32
+ - @lynx-js/web-style-transformer@0.3.2
33
+ - @lynx-js/web-constants@0.15.0
34
+
3
35
  ## 0.14.2
4
36
 
5
37
  ### Patch Changes
@@ -1,7 +1,7 @@
1
1
  import { type LynxTemplate, type PageConfig, type StyleInfo, type FlushElementTreeOptions, type Cloneable, type BrowserConfig, type publishEventEndpoint, type publicComponentEventEndpoint, type reportErrorEndpoint, type RpcCallType, type LynxContextEventTarget, type LynxJSModule, type MainThreadGlobalThis, type WebFiberElementImpl, type I18nResourceTranslationOptions } from '@lynx-js/web-constants';
2
2
  export interface MainThreadRuntimeCallbacks {
3
3
  mainChunkReady: () => void;
4
- flushElementTree: (options: FlushElementTreeOptions, timingFlags: string[]) => void;
4
+ flushElementTree: (options: FlushElementTreeOptions, timingFlags: string[], exposureChangedElements: WebFiberElementImpl[]) => void;
5
5
  _ReportError: RpcCallType<typeof reportErrorEndpoint>;
6
6
  __OnLifecycleEvent: (lifeCycleEvent: Cloneable) => void;
7
7
  markTiming: (pipelineId: string, timingKey: string) => void;
@@ -4,10 +4,22 @@
4
4
  import { lynxUniqueIdAttribute, systemInfo, parentComponentUniqueIdAttribute, componentIdAttribute, LynxEventNameToW3cByTagName, LynxEventNameToW3cCommon, lynxTagAttribute, W3cEventNameToLynx, cssIdAttribute, lynxDefaultDisplayLinearAttribute, __lynx_timing_flag, lynxDisposedAttribute, } from '@lynx-js/web-constants';
5
5
  import { globalMuteableVars } from '@lynx-js/web-constants';
6
6
  import { createMainThreadLynx } from './createMainThreadLynx.js';
7
- import { flattenStyleInfo, genCssContent, genCssInJsInfo, transformToWebCss, } from './utils/processStyleInfo.js';
7
+ import { flattenStyleInfo, genCssContent, genCssOGInfo, transformToWebCss, } from './utils/processStyleInfo.js';
8
8
  import { __AddClass, __AddConfig, __AddDataset, __AddInlineStyle, __AppendElement, __ElementIsEqual, __FirstElement, __GetAttributes, __GetChildren, __GetClasses, __GetComponentID, __GetDataByKey, __GetDataset, __GetElementConfig, __GetElementUniqueID, __GetID, __GetParent, __GetTag, __InsertElementBefore, __LastElement, __NextElement, __RemoveElement, __ReplaceElement, __ReplaceElements, __SetClasses, __SetConfig, __SetCSSId, __SetDataset, __SetID, __SetInlineStyles, __UpdateComponentID, } from './pureElementPAPIs.js';
9
9
  import { createCrossThreadEvent } from './utils/createCrossThreadEvent.js';
10
- import { decodeCssInJs } from './utils/decodeCssInJs.js';
10
+ import { decodeCssOG } from './utils/decodeCssOG.js';
11
+ const exposureRelatedAttributes = new Set([
12
+ 'exposure-id',
13
+ 'exposure-area',
14
+ 'exposure-screen-margin-top',
15
+ 'exposure-screen-margin-right',
16
+ 'exposure-screen-margin-bottom',
17
+ 'exposure-screen-margin-left',
18
+ 'exposure-ui-margin-top',
19
+ 'exposure-ui-margin-right',
20
+ 'exposure-ui-margin-bottom',
21
+ 'exposure-ui-margin-left',
22
+ ]);
11
23
  export function createMainThreadGlobalThis(config) {
12
24
  let pageElement;
13
25
  let uniqueIdInc = 1;
@@ -22,6 +34,7 @@ export function createMainThreadGlobalThis(config) {
22
34
  */
23
35
  const varsUpdateHandlers = [];
24
36
  const lynxGlobalBindingValues = {};
37
+ const exposureChangedElements = new Set();
25
38
  /**
26
39
  * now create the style content
27
40
  * 1. flatten the styleInfo
@@ -32,15 +45,15 @@ export function createMainThreadGlobalThis(config) {
32
45
  */
33
46
  flattenStyleInfo(styleInfo, pageConfig.enableCSSSelector);
34
47
  transformToWebCss(styleInfo);
35
- const cssInJsInfo = pageConfig.enableCSSSelector
48
+ const cssOGInfo = pageConfig.enableCSSSelector
36
49
  ? {}
37
- : genCssInJsInfo(styleInfo);
50
+ : genCssOGInfo(styleInfo);
38
51
  const cardStyleElement = callbacks.createElement('style');
39
52
  cardStyleElement.innerHTML = genCssContent(styleInfo, pageConfig);
40
53
  // @ts-expect-error
41
54
  rootDom.append(cardStyleElement);
42
55
  const cardStyleElementSheet = cardStyleElement.sheet;
43
- const updateCSSInJsStyle = (uniqueId, newStyles) => {
56
+ const updateCssOGStyle = (uniqueId, newStyles) => {
44
57
  if (lynxUniqueIdToStyleRulesIndex[uniqueId] !== undefined) {
45
58
  const rule = cardStyleElementSheet
46
59
  .cssRules[lynxUniqueIdToStyleRulesIndex[uniqueId]];
@@ -121,6 +134,12 @@ export function createMainThreadGlobalThis(config) {
121
134
  element.removeEventListener(eventName, currentRegisteredHandler, {
122
135
  capture: isCapture,
123
136
  });
137
+ // remove the exposure id if the exposure-id is a placeholder value
138
+ const isExposure = eventName === 'uiappear'
139
+ || eventName === 'uidisappear';
140
+ if (isExposure && element.getAttribute('exposure-id') === '-1') {
141
+ mtsGlobalThis.__SetAttribute(element, 'exposure-id', null);
142
+ }
124
143
  }
125
144
  }
126
145
  else {
@@ -133,6 +152,12 @@ export function createMainThreadGlobalThis(config) {
133
152
  element.addEventListener(htmlEventName, currentRegisteredHandler, {
134
153
  capture: isCapture,
135
154
  });
155
+ // add exposure id if no exposure-id is set
156
+ const isExposure = eventName === 'uiappear'
157
+ || eventName === 'uidisappear';
158
+ if (isExposure && element.getAttribute('exposure-id') === null) {
159
+ mtsGlobalThis.__SetAttribute(element, 'exposure-id', '-1');
160
+ }
136
161
  }
137
162
  }
138
163
  if (newEventHandler) {
@@ -276,6 +301,10 @@ export function createMainThreadGlobalThis(config) {
276
301
  if (key === __lynx_timing_flag && value) {
277
302
  timingFlags.push(value);
278
303
  }
304
+ if (exposureRelatedAttributes.has(key)) {
305
+ // if the attribute is related to exposure, we need to mark the element as changed
306
+ exposureChangedElements.add(element);
307
+ }
279
308
  }
280
309
  };
281
310
  const __UpdateListCallbacks = (element, componentAtIndex, enqueueComponent) => {
@@ -306,13 +335,13 @@ export function createMainThreadGlobalThis(config) {
306
335
  const newClassName = ((element.getAttribute('class') ?? '') + ' ' + className)
307
336
  .trim();
308
337
  element.setAttribute('class', newClassName);
309
- const newStyleStr = decodeCssInJs(newClassName, cssInJsInfo, element.getAttribute(cssIdAttribute));
310
- updateCSSInJsStyle(Number(element.getAttribute(lynxUniqueIdAttribute)), newStyleStr);
338
+ const newStyleStr = decodeCssOG(newClassName, cssOGInfo, element.getAttribute(cssIdAttribute));
339
+ updateCssOGStyle(Number(element.getAttribute(lynxUniqueIdAttribute)), newStyleStr);
311
340
  };
312
341
  const __SetClassesForCSSOG = (element, classNames) => {
313
342
  __SetClasses(element, classNames);
314
- const newStyleStr = decodeCssInJs(classNames ?? '', cssInJsInfo, element.getAttribute(cssIdAttribute));
315
- updateCSSInJsStyle(Number(element.getAttribute(lynxUniqueIdAttribute)), newStyleStr ?? '');
343
+ const newStyleStr = decodeCssOG(classNames ?? '', cssOGInfo, element.getAttribute(cssIdAttribute));
344
+ updateCssOGStyle(Number(element.getAttribute(lynxUniqueIdAttribute)), newStyleStr ?? '');
316
345
  };
317
346
  const __LoadLepusChunk = (path) => {
318
347
  const lepusModule = lepusCode[`${path}`];
@@ -333,7 +362,9 @@ export function createMainThreadGlobalThis(config) {
333
362
  // @ts-expect-error
334
363
  rootDom.append(pageElement);
335
364
  }
336
- callbacks.flushElementTree(options, timingFlagsCopied);
365
+ const exposureChangedElementsArray = Array.from(exposureChangedElements);
366
+ exposureChangedElements.clear();
367
+ callbacks.flushElementTree(options, timingFlagsCopied, exposureChangedElementsArray);
337
368
  };
338
369
  const __GetTemplateParts = () => {
339
370
  return undefined;
@@ -1,4 +1,4 @@
1
1
  import { type Rpc, type StartMainThreadContextConfig, type RpcCallType, type reportErrorEndpoint, type MainThreadGlobalThis, type I18nResourceTranslationOptions, type InitI18nResources, type I18nResources } from '@lynx-js/web-constants';
2
- export declare function prepareMainThreadAPIs(backgroundThreadRpc: Rpc, rootDom: Document | ShadowRoot, createElement: Document['createElement'], commitDocument: () => Promise<void> | void, markTimingInternal: (timingKey: string, pipelineId?: string) => void, flushMarkTimingInternal: () => void, reportError: RpcCallType<typeof reportErrorEndpoint>, triggerI18nResourceFallback: (options: I18nResourceTranslationOptions) => void, initialI18nResources: (data: InitI18nResources) => I18nResources): {
2
+ export declare function prepareMainThreadAPIs(backgroundThreadRpc: Rpc, rootDom: Document | ShadowRoot, createElement: Document['createElement'], commitDocument: (exposureChangedElements: HTMLElement[]) => Promise<void> | void, markTimingInternal: (timingKey: string, pipelineId?: string) => void, flushMarkTimingInternal: () => void, reportError: RpcCallType<typeof reportErrorEndpoint>, triggerI18nResourceFallback: (options: I18nResourceTranslationOptions) => void, initialI18nResources: (data: InitI18nResources) => I18nResources): {
3
3
  startMainThread: (config: StartMainThreadContextConfig) => Promise<MainThreadGlobalThis>;
4
4
  };
@@ -6,6 +6,8 @@ import { registerCallLepusMethodHandler } from './crossThreadHandlers/registerCa
6
6
  import { registerGetCustomSectionHandler } from './crossThreadHandlers/registerGetCustomSectionHandler.js';
7
7
  import { createMainThreadGlobalThis } from './createMainThreadGlobalThis.js';
8
8
  import { createExposureService } from './utils/createExposureService.js';
9
+ import { initTokenizer } from './utils/tokenizer.js';
10
+ const initTokenizerPromise = initTokenizer();
9
11
  const moduleCache = {};
10
12
  export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElement, commitDocument, markTimingInternal, flushMarkTimingInternal, reportError, triggerI18nResourceFallback, initialI18nResources) {
11
13
  const postTimingFlags = backgroundThreadRpc.createCall(postTimingFlagsEndpoint);
@@ -20,6 +22,7 @@ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElemen
20
22
  const { globalProps, template, browserConfig, nativeModulesMap, napiModulesMap, tagMap, initI18nResources, } = config;
21
23
  const { styleInfo, pageConfig, customSections, cardType, lepusCode } = template;
22
24
  markTimingInternal('decode_start');
25
+ await initTokenizerPromise;
23
26
  const lepusCodeEntries = await Promise.all(Object.entries(lepusCode).map(async ([name, url]) => {
24
27
  const cachedModule = moduleCache[url];
25
28
  if (cachedModule) {
@@ -78,7 +81,7 @@ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElemen
78
81
  mtsGlobalThis.renderPage(initData);
79
82
  mtsGlobalThis.__FlushElementTree(undefined, {});
80
83
  },
81
- flushElementTree: async (options, timingFlags) => {
84
+ flushElementTree: async (options, timingFlags, exposureChangedElements) => {
82
85
  const pipelineId = options?.pipelineOptions?.pipelineID;
83
86
  markTimingInternal('dispatch_start', pipelineId);
84
87
  if (isFp) {
@@ -90,7 +93,7 @@ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElemen
90
93
  }
91
94
  markTimingInternal('layout_start', pipelineId);
92
95
  markTimingInternal('ui_operation_flush_start', pipelineId);
93
- await commitDocument();
96
+ await commitDocument(exposureChangedElements);
94
97
  markTimingInternal('ui_operation_flush_end', pipelineId);
95
98
  markTimingInternal('layout_end', pipelineId);
96
99
  markTimingInternal('dispatch_end', pipelineId);
@@ -128,13 +128,16 @@ export const __AddClass = /*#__PURE__*/ (element, className) => {
128
128
  export const __SetInlineStyles = /*#__PURE__*/ (element, value) => {
129
129
  if (!value)
130
130
  return;
131
- const { transformedStyle } = typeof value === 'string'
132
- ? transformInlineStyleString(value)
133
- : transformParsedStyles(Object.entries(value).map(([k, value]) => [
131
+ if (typeof value === 'string') {
132
+ element.setAttribute('style', transformInlineStyleString(value));
133
+ }
134
+ else {
135
+ const { transformedStyle } = transformParsedStyles(Object.entries(value).map(([k, value]) => [
134
136
  hyphenateStyleName(k),
135
137
  value,
136
138
  ]));
137
- const transformedStyleStr = transformedStyle.map(([property, value]) => `${property}:${value};`).join('');
138
- element.setAttribute('style', transformedStyleStr);
139
+ const transformedStyleStr = transformedStyle.map(([property, value]) => `${property}:${value};`).join('');
140
+ element.setAttribute('style', transformedStyleStr);
141
+ }
139
142
  };
140
143
  //# sourceMappingURL=pureElementPAPIs.js.map
@@ -1,8 +1 @@
1
- export declare function transformInlineStyleString(str: string): {
2
- childStyle: [string, string][];
3
- transformedStyle: [string, string][];
4
- };
5
- export declare function transformParsedStyles(hyphenatedStyleObject: [property: string, value: string][]): {
6
- childStyle: [string, string][];
7
- transformedStyle: [string, string][];
8
- };
1
+ export { transformInlineStyleString, transformParsedStyles, } from '../utils/tokenizer.js';
@@ -1,42 +1,5 @@
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
- // @ts-expect-error
5
- import * as tokenizer from 'css-tree/tokenizer';
6
- import { transformLynxStyles } from '@lynx-js/web-style-transformer';
7
- function parseStyleStringToObject(str) {
8
- const hyphenNameStyles = [];
9
- let beforeColonToken = true;
10
- let propertyStart = 0;
11
- let propertyEnd = 0;
12
- let valueStart = 0;
13
- let valueEnd = 0;
14
- tokenizer.tokenize(str + ';', (type, start, end) => {
15
- if (type === tokenizer.Semicolon || tokenizer.EOF) {
16
- valueEnd = start;
17
- const trimmedProperty = str.substring(propertyStart, propertyEnd).trim();
18
- const trimmedValue = str.substring(valueStart, valueEnd).trim();
19
- if (!beforeColonToken && trimmedValue && trimmedProperty) {
20
- hyphenNameStyles.push([
21
- trimmedProperty,
22
- trimmedValue,
23
- ]);
24
- }
25
- beforeColonToken = true;
26
- propertyStart = end;
27
- }
28
- else if (type === tokenizer.Colon && beforeColonToken) {
29
- beforeColonToken = false;
30
- valueStart = end;
31
- propertyEnd = start;
32
- }
33
- });
34
- return hyphenNameStyles;
35
- }
36
- export function transformInlineStyleString(str) {
37
- return transformParsedStyles(parseStyleStringToObject(str));
38
- }
39
- export function transformParsedStyles(hyphenatedStyleObject) {
40
- return transformLynxStyles(hyphenatedStyleObject);
41
- }
4
+ export { transformInlineStyleString, transformParsedStyles, } from '../utils/tokenizer.js';
42
5
  //# sourceMappingURL=transformInlineStyle.js.map
@@ -7,6 +7,7 @@ export function createExposureService(rootDom, postExposure) {
7
7
  let working = true;
8
8
  let exposureCache = [];
9
9
  let disexposureCache = [];
10
+ let delayCallback = null;
10
11
  const onScreen = new Map();
11
12
  function exposureEventHandler(ev) {
12
13
  const exposureEvent = createCrossThreadEvent(ev, ev.type);
@@ -20,19 +21,22 @@ export function createExposureService(rootDom, postExposure) {
20
21
  disexposureCache.push(exposureEvent);
21
22
  onScreen.delete(exposureID);
22
23
  }
23
- }
24
- setInterval(() => {
25
- if (exposureCache.length > 0 || disexposureCache.length > 0) {
26
- const currentExposure = exposureCache;
27
- const currentDisexposure = disexposureCache;
28
- exposureCache = [];
29
- disexposureCache = [];
30
- postExposure({
31
- exposures: currentExposure,
32
- disExposures: currentDisexposure,
33
- });
24
+ if (!delayCallback) {
25
+ delayCallback = setTimeout(() => {
26
+ if (exposureCache.length > 0 || disexposureCache.length > 0) {
27
+ const currentExposure = exposureCache;
28
+ const currentDisexposure = disexposureCache;
29
+ exposureCache = [];
30
+ disexposureCache = [];
31
+ postExposure({
32
+ exposures: currentExposure,
33
+ disExposures: currentDisexposure,
34
+ });
35
+ }
36
+ delayCallback = null;
37
+ }, 1000 / 20);
34
38
  }
35
- }, 1000 / 20);
39
+ }
36
40
  rootDom.addEventListener('exposure', exposureEventHandler, {
37
41
  passive: true,
38
42
  });
@@ -0,0 +1,8 @@
1
+ import type { CssOGInfo } from '@lynx-js/web-constants';
2
+ /**
3
+ * @param classes
4
+ * @param styleInfo it should be flattened, which means there is no imports field in the styleInfo
5
+ * @param cssId
6
+ * @returns
7
+ */
8
+ export declare function decodeCssOG(classes: string, styleInfo: CssOGInfo, cssId: string | null): string;
@@ -4,7 +4,7 @@
4
4
  * @param cssId
5
5
  * @returns
6
6
  */
7
- export function decodeCssInJs(classes, styleInfo, cssId) {
7
+ export function decodeCssOG(classes, styleInfo, cssId) {
8
8
  const classList = classes.split(' ').filter(e => e);
9
9
  let declarations = [];
10
10
  const currentStyleInfo = styleInfo[cssId ?? '0'];
@@ -20,4 +20,4 @@ export function decodeCssInJs(classes, styleInfo, cssId) {
20
20
  }
21
21
  return declarations.map(([property, value]) => `${property}:${value};`).join('');
22
22
  }
23
- //# sourceMappingURL=decodeCssInJs.js.map
23
+ //# sourceMappingURL=decodeCssOG.js.map
@@ -1,4 +1,4 @@
1
- import { type StyleInfo, type CssInJsInfo, type PageConfig } from '@lynx-js/web-constants';
1
+ import { type StyleInfo, type CssOGInfo, type PageConfig } from '@lynx-js/web-constants';
2
2
  export declare function flattenStyleInfo(styleInfo: StyleInfo, enableCSSSelector: boolean): void;
3
3
  /**
4
4
  * apply the lynx css -> web css transformation
@@ -11,4 +11,4 @@ export declare function genCssContent(styleInfo: StyleInfo, pageConfig: PageConf
11
11
  /**
12
12
  * generate the css-in-js data
13
13
  */
14
- export declare function genCssInJsInfo(styleInfo: StyleInfo): CssInJsInfo;
14
+ export declare function genCssOGInfo(styleInfo: StyleInfo): CssOGInfo;
@@ -2,7 +2,7 @@
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
4
  import { cssIdAttribute, lynxTagAttribute, } from '@lynx-js/web-constants';
5
- import { transformLynxStyles } from '@lynx-js/web-style-transformer';
5
+ import { transformParsedStyles } from './tokenizer.js';
6
6
  export function flattenStyleInfo(styleInfo, enableCSSSelector) {
7
7
  function flattenOneStyleInfo(cssId) {
8
8
  const oneInfo = styleInfo[cssId];
@@ -16,7 +16,7 @@ export function flattenStyleInfo(styleInfo, enableCSSSelector) {
16
16
  oneInfo.rules.push(...(enableCSSSelector
17
17
  ? flatInfo.rules
18
18
  // when enableCSSSelector is false, need to make a shallow copy of rules.sel
19
- // otherwise updating `oneCssInfo.sel` in `genCssInJsInfo()` will affect other imported cssInfo
19
+ // otherwise updating `oneCssInfo.sel` in `genCssOGInfo()` will affect other imported cssInfo
20
20
  : flatInfo.rules.map(i => ({ ...i }))));
21
21
  }
22
22
  }
@@ -35,7 +35,7 @@ export function transformToWebCss(styleInfo) {
35
35
  for (const cssInfos of Object.values(styleInfo)) {
36
36
  for (const rule of cssInfos.rules) {
37
37
  const { sel: selectors, decl: declarations } = rule;
38
- const { transformedStyle, childStyle } = transformLynxStyles(declarations);
38
+ const { transformedStyle, childStyle } = transformParsedStyles(declarations);
39
39
  rule.decl = transformedStyle;
40
40
  if (childStyle.length > 0) {
41
41
  cssInfos.rules.push({
@@ -87,9 +87,9 @@ export function genCssContent(styleInfo, pageConfig) {
87
87
  /**
88
88
  * generate the css-in-js data
89
89
  */
90
- export function genCssInJsInfo(styleInfo) {
90
+ export function genCssOGInfo(styleInfo) {
91
91
  return Object.fromEntries(Object.entries(styleInfo).map(([cssId, cssInfos]) => {
92
- const oneCssInJsInfo = {};
92
+ const oneCssOGInfo = {};
93
93
  cssInfos.rules = cssInfos.rules.filter(oneCssInfo => {
94
94
  oneCssInfo.sel = oneCssInfo.sel.filter(selectorList => {
95
95
  const [classSelectors, pseudoClassSelectors, pseudoElementSelectors, combinator,] = selectorList;
@@ -100,12 +100,12 @@ export function genCssInJsInfo(styleInfo) {
100
100
  && pseudoElementSelectors.length === 0
101
101
  && combinator.length === 0) {
102
102
  const selectorName = classSelectors[0].substring(1);
103
- const currentDeclarations = oneCssInJsInfo[selectorName];
103
+ const currentDeclarations = oneCssOGInfo[selectorName];
104
104
  if (currentDeclarations) {
105
105
  currentDeclarations.push(...oneCssInfo.decl);
106
106
  }
107
107
  else {
108
- oneCssInJsInfo[selectorName] = oneCssInfo.decl;
108
+ oneCssOGInfo[selectorName] = oneCssInfo.decl;
109
109
  }
110
110
  return false; // remove this selector from style info
111
111
  }
@@ -113,7 +113,7 @@ export function genCssInJsInfo(styleInfo) {
113
113
  });
114
114
  return oneCssInfo.sel.length > 0;
115
115
  });
116
- return [cssId, oneCssInJsInfo];
116
+ return [cssId, oneCssOGInfo];
117
117
  }));
118
118
  }
119
119
  //# sourceMappingURL=processStyleInfo.js.map
@@ -0,0 +1,6 @@
1
+ export declare const initTokenizer: () => Promise<void>;
2
+ export declare function transformInlineStyleString(str: string): string;
3
+ export declare function transformParsedStyles(styles: [string, string][]): {
4
+ childStyle: [string, string][];
5
+ transformedStyle: [string, string][];
6
+ };
@@ -0,0 +1,78 @@
1
+ // @ts-ignore the wasm module built later than the ts code
2
+ import init from '@lynx-js/web-style-transformer';
3
+ let wasm;
4
+ let HEAPU16;
5
+ var ENVIRONMENT_IS_NODE = typeof process == 'object'
6
+ && typeof process.versions == 'object'
7
+ && typeof process.versions.node == 'string';
8
+ export const initTokenizer = async () => {
9
+ // initialize wasm module in node.js environment
10
+ if (ENVIRONMENT_IS_NODE) {
11
+ const path = await import(/* webpackIgnore:true */ 'node:path');
12
+ const fs = await import(/* webpackIgnore:true */ 'node:fs/promises');
13
+ const wasmModuleBuffer = await fs.readFile(path.join(import.meta.dirname, '..', '..', 'node_modules', '@lynx-js', 'web-style-transformer', 'dist', 'index_bg.wasm'));
14
+ wasm = await init(wasmModuleBuffer);
15
+ }
16
+ else {
17
+ wasm = await init();
18
+ }
19
+ };
20
+ const stringToUTF16 = (str) => {
21
+ const len = str.length;
22
+ const ptr = wasm.malloc(len << 1);
23
+ if (!HEAPU16 || HEAPU16.byteLength == 0) {
24
+ HEAPU16 = new Uint16Array(wasm.memory.buffer);
25
+ }
26
+ for (let i = 0; i < len; i++) {
27
+ HEAPU16[(ptr >> 1) + i] = str.charCodeAt(i);
28
+ }
29
+ return { ptr, len };
30
+ };
31
+ export function transformInlineStyleString(str) {
32
+ const { ptr, len } = stringToUTF16(str);
33
+ try {
34
+ const transformedStyle = wasm.transform_raw_u16_inline_style_ptr(ptr, len)
35
+ ?? str;
36
+ wasm.free(ptr, len << 1);
37
+ return transformedStyle;
38
+ }
39
+ catch (e) {
40
+ wasm.free(ptr, len << 1);
41
+ throw e;
42
+ }
43
+ }
44
+ export function transformParsedStyles(styles) {
45
+ let childStyle = [];
46
+ let transformedStyle = [];
47
+ for (const [property, value] of styles) {
48
+ const { ptr: propertyPtr, len: propertyLen } = stringToUTF16(property);
49
+ const { ptr: valuePtr, len: valueLen } = stringToUTF16(value);
50
+ try {
51
+ const transformedResult = wasm
52
+ .transform_raw_u16_inline_style_ptr_parsed(propertyPtr, propertyLen, valuePtr, valueLen);
53
+ wasm.free(propertyPtr, propertyLen << 1);
54
+ wasm.free(valuePtr, valueLen << 1);
55
+ if (transformedResult) {
56
+ const [transformedStyleForCurrent, childStyleForCurrent] = transformedResult;
57
+ transformedStyle = transformedStyle.concat(transformedStyleForCurrent);
58
+ if (childStyleForCurrent) {
59
+ childStyle = childStyle.concat(childStyleForCurrent);
60
+ }
61
+ }
62
+ else {
63
+ // If the transformation fails, we keep the original style
64
+ transformedStyle.push([property, value]);
65
+ }
66
+ }
67
+ catch (e) {
68
+ wasm.free(propertyPtr, propertyLen << 1);
69
+ wasm.free(valuePtr, valueLen << 1);
70
+ throw e;
71
+ }
72
+ }
73
+ return {
74
+ childStyle,
75
+ transformedStyle,
76
+ };
77
+ }
78
+ //# sourceMappingURL=tokenizer.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-mainthread-apis",
3
- "version": "0.14.2",
3
+ "version": "0.15.1",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "keywords": [],
@@ -15,6 +15,7 @@
15
15
  "typings": "dist/index.d.ts",
16
16
  "files": [
17
17
  "dist",
18
+ "binary",
18
19
  "!dist/**/*.js.map",
19
20
  "LICENSE.txt",
20
21
  "Notice.txt",
@@ -23,9 +24,8 @@
23
24
  "**/*.css"
24
25
  ],
25
26
  "dependencies": {
26
- "css-tree": "^3.1.0",
27
27
  "hyphenate-style-name": "^1.1.0",
28
- "@lynx-js/web-constants": "0.14.2",
29
- "@lynx-js/web-style-transformer": "0.3.1"
28
+ "@lynx-js/web-constants": "0.15.1",
29
+ "@lynx-js/web-style-transformer": "0.3.3"
30
30
  }
31
31
  }
@@ -1,8 +0,0 @@
1
- import type { CssInJsInfo } from '@lynx-js/web-constants';
2
- /**
3
- * @param classes
4
- * @param styleInfo it should be flattened, which means there is no imports field in the styleInfo
5
- * @param cssId
6
- * @returns
7
- */
8
- export declare function decodeCssInJs(classes: string, styleInfo: CssInJsInfo, cssId: string | null): string;