Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/nasty-lizards-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@lynx-js/web-elements": patch
"@lynx-js/web-core": patch
---

feat: add x-markdown support

Add opt-in support for the `x-markdown` element on Lynx Web, including
Markdown rendering together with its related styling, interaction, animation,
truncation, range rendering, and effect capabilities exposed through the
component API.

Update the `web-core`, `web-core-wasm`, and `web-mainthread-apis` runtime
paths to use the shared property-or-attribute setter from `web-constants`, so
custom elements such as `x-markdown` can receive structured property values
correctly instead of being forced through string-only attribute updates.

```javascript
import '@lynx-js/web-elements/XMarkdown';
```
16 changes: 10 additions & 6 deletions packages/web-platform/web-core-e2e/tests/reactlynx.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3199,12 +3199,16 @@ test.describe('reactlynx3 tests', () => {
// input/bindinput test-case start
test('basic-element-x-input-bindinput', async ({ page }, { title }) => {
await goto(page, title);
await page.locator('input').press('Enter');
await wait(200);
await page.locator('input').fill('foobar');
await wait(200);
const result = await page.locator('.result').first().innerText();
expect(result).toBe('foobar-6-6');
const input = page.locator('input');
const result = page.locator('.result').first();

// Firefox CI can be slower to finish mounting/binding handlers; wait for initial render first.
await expect(input).toBeVisible();
await expect(input).toHaveValue('bindinput');

await input.press('Enter');
await input.fill('foobar');
await expect(result).toHaveText('foobar-6-6');
});
// input/bindinput test-case start for <input>
test('basic-element-input-bindinput', async ({ page }, { title }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Copyright 2023 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 type { Rpc } from '@lynx-js/web-worker-rpc';
import { Rpc } from '@lynx-js/web-worker-rpc';
import { queryNodes } from './queryNodes.js';
import { setNativePropsEndpoint } from '../../endpoints.js';
import type { LynxViewInstance } from '../LynxViewInstance.js';
import { setElementPropertyOrAttribute } from '../utils/setElementPropertyOrAttribute.js';
import { setNativePropsEndpoint } from '../../endpoints.js';

function applyNativeProps(element: Element, nativeProps: Record<string, any>) {
for (const key in nativeProps) {
const value = nativeProps[key] as string;
const value = nativeProps[key];
if (key === 'text' && element?.tagName === 'X-TEXT') {
if (
element.firstElementChild
Expand All @@ -23,7 +24,7 @@ function applyNativeProps(element: Element, nativeProps: Record<string, any>) {
) {
(element as HTMLElement).style.setProperty(key, value);
} else {
element.setAttribute(key, value);
setElementPropertyOrAttribute(element, key, value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { wasmInstance } from '../../wasm.js';
import { setElementPropertyOrAttribute } from '../utils/setElementPropertyOrAttribute.js';

import {
AnimationOperation,
Expand Down Expand Up @@ -447,11 +448,7 @@ export function createElementAPI(
}
});
} else {
if (value == null) {
element.removeAttribute(name);
} else {
element.setAttribute(name, value.toString());
}
setElementPropertyOrAttribute(element, name, value);
Comment thread
PupilTong marked this conversation as resolved.
if (name === 'exposure-id') {
if (value != null) {
mtsBinding.markExposureRelatedElementByUniqueId(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2023 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.

export const setElementPropertyOrAttribute = (
element: Element,
key: string,
value: unknown,
) => {
if (value == null) {
element.removeAttribute(key);
return;
}

if (
key in element
&& typeof value !== 'string'
&& typeof value !== 'number'
&& typeof value !== 'boolean'
) {
(element as unknown as Record<string, unknown>)[key] = value;
} else {
element.setAttribute(key, String(value));
}
};
1 change: 1 addition & 0 deletions packages/web-platform/web-elements/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@import url("./src/elements/XSvg/x-svg.css");
@import url("./src/elements/XImage/x-image.css");
@import url("./src/elements/XInput/x-input.css");
@import url("./src/elements/XMarkdown/x-markdown.css");
Comment thread
Sherry-hue marked this conversation as resolved.
@import url("./src/elements/XOverlayNg/x-overlay-ng.css");
@import url("./src/elements/XRefreshView/x-refresh-view.css");
@import url("./src/elements/XSwiper/x-swiper.css");
Expand Down
10 changes: 10 additions & 0 deletions packages/web-platform/web-elements/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
"types": "./dist/elements/XInput/index.d.ts",
"default": "./dist/elements/XInput/index.js"
},
"./XMarkdown": {
"@lynx-js/source-field": "./src/elements/XMarkdown/index.ts",
"types": "./dist/elements/XMarkdown/index.d.ts",
"default": "./dist/elements/XMarkdown/index.js"
},
"./XOverlayNg": {
"@lynx-js/source-field": "./src/elements/XOverlayNg/index.ts",
"types": "./dist/elements/XOverlayNg/index.d.ts",
Expand Down Expand Up @@ -135,11 +140,16 @@
"test:install": "playwright install --with-deps chromium firefox webkit",
"test:update": "playwright test --ui --update-snapshots"
},
"dependencies": {
"dompurify": "^3.3.1",
"markdown-it": "^14.1.0"
},
"devDependencies": {
"@lynx-js/playwright-fixtures": "workspace:*",
"@playwright/test": "^1.58.2",
"@rsbuild/core": "catalog:rsbuild",
"@rsbuild/plugin-source-build": "1.0.4",
"@types/markdown-it": "^14.1.1",
"nyc": "^17.1.0",
"tslib": "^2.8.1"
},
Expand Down
Loading
Loading