@lynx-js/web-core
Version:
This is an internal experimental package, do not use
281 lines • 13 kB
JavaScript
/*
* Copyright 2025 The Lynx Authors. All rights reserved.
* Licensed under the Apache License Version 2.0 that can be found in the
* LICENSE file in the root directory of this source tree.
*/
import { MainThreadServerContext, StyleSheetResource } from '../wasm.js';
import { LYNX_TAG_TO_HTML_TAG_MAP, uniqueIdSymbol, lynxDefaultDisplayLinearAttribute, lynxEntryNameAttribute, } from '../../constants.js';
import { __AddConfig, __AddDataset, __AddEvent, __ElementIsEqual, __FirstElement, __GetChildren, __GetComponentID, __GetConfig, __GetDataByKey, __GetDataset, __GetElementConfig, __GetElementUniqueID, __GetEvent, __GetEvents, __GetPageElement, __GetParent, __GetTemplateParts, __InsertElementBefore, __LastElement, __MarkPartElement, __MarkTemplateElement, __NextElement, __RemoveElement, __ReplaceElement, __ReplaceElements, __SetConfig, __SetDataset, __SetEvents, __SwapElement, __UpdateComponentID, __UpdateComponentInfo, __UpdateListCallbacks, getUniqueId, } from './pureElementAPIs.js';
export function createElementAPI(mtsBinding, styleInfo, viewAttributes, config) {
const wasmContext = new MainThreadServerContext(viewAttributes, config.enableCSSSelector, config.transformVW, config.transformVH, config.transformREM);
if (styleInfo) {
const resource = new StyleSheetResource(styleInfo, undefined);
wasmContext.push_style_sheet(resource);
}
let pageElementId;
function getAttribute(element, key) {
return wasmContext.get_attribute(element[uniqueIdSymbol], key) || undefined;
}
const __SetCSSId = (elements, cssId, entryName) => {
const uniqueIds = elements.map((element) => element[uniqueIdSymbol]);
wasmContext.set_css_id(new Uint32Array(uniqueIds), cssId ?? 0, entryName);
};
const __SetClasses = (element, classname) => {
const el = element;
if (classname) {
wasmContext.set_attribute(el[uniqueIdSymbol], 'class', classname);
}
else {
wasmContext.remove_attribute(el[uniqueIdSymbol], 'class');
}
};
const __AddClass = (element, className) => {
const el = element;
wasmContext.add_class(el[uniqueIdSymbol], className);
};
return {
globalThisAPIs: {
// Pure/Throwing Methods
__GetID: ((element) => {
return getAttribute(element, 'id') ?? null;
}),
__GetTag: ((element) => {
const el = element;
const tag = wasmContext.get_tag(el[uniqueIdSymbol]) ?? '';
// Reverse-map HTML tag to Lynx tag (consistent with CSR `__GetTag` behavior)
for (const [lynxTag, htmlTag] of Object.entries(LYNX_TAG_TO_HTML_TAG_MAP)) {
if (tag === htmlTag) {
return lynxTag;
}
}
return tag;
}),
__GetAttributes: ((element) => {
const el = element;
return wasmContext.get_attributes(el[uniqueIdSymbol]);
}),
__GetAttributeByName: (element, name) => {
return getAttribute(element, name) ?? null;
},
__GetClasses: ((element) => {
const cls = getAttribute(element, 'class');
if (!cls)
return [];
return cls.split(/\s+/).filter((c) => c.length > 0);
}),
__GetParent: ((element) => {
const id = getUniqueId(element);
const parentId = wasmContext.get_parent(id);
if (parentId !== undefined) {
return { [uniqueIdSymbol]: parentId };
}
return null;
}),
__GetChildren,
__AddEvent,
__GetEvent,
__GetEvents,
__SetEvents,
__UpdateListCallbacks,
__GetConfig,
__SetConfig,
__GetElementConfig,
__GetComponentID,
__GetDataset,
__SetDataset,
__AddDataset,
__GetDataByKey,
__ElementIsEqual,
__GetElementUniqueID,
__FirstElement,
__LastElement,
__NextElement,
__RemoveElement: ((parent, child) => {
const parentId = getUniqueId(parent);
const childId = getUniqueId(child);
wasmContext.remove_child(parentId, childId);
}),
__ReplaceElement: ((newElement, oldElement) => {
const newId = getUniqueId(newElement);
const oldId = getUniqueId(oldElement);
wasmContext.replace_element(newId, oldId);
}),
__SwapElement,
__SetCSSId,
__SetClasses: config.enableCSSSelector
? __SetClasses
: ((element, classname) => {
__SetClasses(element, classname);
const el = element;
wasmContext.update_css_og_style(el[uniqueIdSymbol], getAttribute(el, lynxEntryNameAttribute));
}),
__AddClass,
__AddConfig,
__UpdateComponentInfo,
__UpdateComponentID,
__MarkTemplateElement,
__MarkPartElement,
__GetTemplateParts,
__GetPageElement,
__InsertElementBefore: ((parent, child, ref) => {
const parentId = getUniqueId(parent);
const childId = getUniqueId(child);
const refId = ref ? getUniqueId(ref) : undefined;
wasmContext.insert_before(parentId, childId, refId);
}),
__ReplaceElements: ((parent, newChildren, oldChildren) => {
const parentId = getUniqueId(parent);
const newArr = Array.isArray(newChildren) ? newChildren : [newChildren];
const newIds = new Uint32Array(newArr.map(getUniqueId));
const oldArr = oldChildren
? (Array.isArray(oldChildren) ? oldChildren : [oldChildren])
: [];
const oldIds = new Uint32Array(oldArr.map(getUniqueId));
wasmContext.replace_elements(parentId, newIds, oldIds);
}),
// Context-Dependent Methods
__CreateView: ((parentComponentUniqueId) => {
const id = wasmContext.create_element('x-view', parentComponentUniqueId);
return { [uniqueIdSymbol]: id };
}),
__CreateText: ((parentComponentUniqueId) => {
const id = wasmContext.create_element('x-text', parentComponentUniqueId);
return { [uniqueIdSymbol]: id };
}),
__CreateImage: ((parentComponentUniqueId) => {
const id = wasmContext.create_element('x-image', parentComponentUniqueId);
return { [uniqueIdSymbol]: id };
}),
__CreateRawText: ((text) => {
const id = wasmContext.create_element('raw-text');
wasmContext.set_attribute(id, 'text', text);
return { [uniqueIdSymbol]: id };
}),
__CreateScrollView: ((parentComponentUniqueId) => {
const id = wasmContext.create_element('scroll-view', parentComponentUniqueId);
return { [uniqueIdSymbol]: id };
}),
__CreateElement: ((tagName, parentComponentUniqueId) => {
const htmlTag = LYNX_TAG_TO_HTML_TAG_MAP[tagName] ?? tagName;
const id = wasmContext.create_element(htmlTag, parentComponentUniqueId);
const el = { [uniqueIdSymbol]: id };
if (!config.enableCSSSelector) {
wasmContext.set_attribute(id, 'l-uid', id.toString());
}
return el;
}),
__CreateComponent: ((parentComponentUniqueId, _componentID, _cssID, entryName, name) => {
const id = wasmContext.create_element('x-view', parentComponentUniqueId, _cssID, _componentID); // Component host
const el = { [uniqueIdSymbol]: id };
if (!config.enableCSSSelector) {
wasmContext.set_attribute(id, 'l-uid', id.toString());
}
if (entryName) {
wasmContext.set_attribute(id, 'lynx-entry-name', entryName);
}
if (name) {
wasmContext.set_attribute(id, 'name', name);
}
return el;
}),
__CreateWrapperElement: ((parentComponentUniqueId) => {
const id = wasmContext.create_element('lynx-wrapper', parentComponentUniqueId);
return { [uniqueIdSymbol]: id };
}),
__CreateList: ((parentComponentUniqueId) => {
const id = wasmContext.create_element('x-list', parentComponentUniqueId);
return { [uniqueIdSymbol]: id };
}),
__CreatePage: ((_componentID, _cssID) => {
const id = wasmContext.create_element('div', 0, _cssID, _componentID);
pageElementId = id;
const el = { [uniqueIdSymbol]: id };
if (!config.enableCSSSelector) {
wasmContext.set_attribute(id, 'l-uid', id.toString());
}
wasmContext.set_attribute(id, 'part', 'page');
if (config.defaultDisplayLinear === false) {
wasmContext.set_attribute(id, lynxDefaultDisplayLinearAttribute, 'false');
}
if (config.defaultOverflowVisible === true) {
wasmContext.set_attribute(id, 'lynx-default-overflow-visible', 'true');
}
return el;
}),
__AppendElement: ((parent, child) => {
const parentId = getUniqueId(parent);
const childId = getUniqueId(child);
wasmContext.append_child(parentId, childId);
}),
__SetAttribute: ((element, name, value) => {
const el = element;
let valStr = '';
if (value == null) {
valStr = '';
}
else {
valStr = value.toString();
}
wasmContext.set_attribute(el[uniqueIdSymbol], name, valStr);
}),
__SetInlineStyles: ((element, value) => {
const uniqueId = element[uniqueIdSymbol];
if (!value) {
wasmContext.remove_attribute(uniqueId, 'style');
}
else {
if (typeof value === 'string') {
if (!wasmContext.set_inline_styles_in_str(uniqueId, value)) {
wasmContext.set_attribute(uniqueId, 'style', value);
}
}
else if (!value) {
wasmContext.remove_attribute(uniqueId, 'style');
}
else {
const vec = [];
for (const [k, v] of Object.entries(value)) {
if (v != null) {
vec.push(k, v.toString());
}
}
wasmContext.set_inline_styles_in_key_value_vec(uniqueId, vec);
}
}
}),
__AddInlineStyle: ((element, key, value) => {
const uniqueId = element[uniqueIdSymbol];
let valStr = null;
if (value != null) {
valStr = value.toString();
}
if (typeof key === 'number') {
return wasmContext.set_inline_styles_number_key(uniqueId, key, valStr);
}
else {
return wasmContext.add_inline_style_raw_string_key(uniqueId, key.toString(), valStr);
}
}),
__ElementAnimate: () => { },
__FlushElementTree: (() => {
if (pageElementId !== undefined) {
mtsBinding.ssrResult = wasmContext.generate_html(pageElementId);
}
}),
__SetID: ((element, id) => {
wasmContext.set_attribute(element[uniqueIdSymbol], 'id', id ?? '');
}),
__InvokeUIMethod: () => {
throw new Error('Not yet Implemented');
},
__QuerySelector: () => {
throw new Error('Not yet Implemented');
},
__QuerySelectorAll: () => {
throw new Error('Not yet Implemented');
},
},
wasmContext,
};
}
//# sourceMappingURL=createElementAPI.js.map