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
7 changes: 7 additions & 0 deletions .changeset/fix-rpx-unit-inline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@lynx-js/web-core": patch
---

fix: tokenizing inline style values correctly to support rpx and ppx unit conversion

This fixes an issue where the `transform_inline_style_key_value_vec` API bypassed the CSS tokenizer, preventing dimension units like `rpx` or `ppx` from being successfully transformed into `calc` strings when specified via inline styles.
5 changes: 5 additions & 0 deletions .changeset/transform-ppx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/web-core": patch
---

feat: add `ppx` unit support for CSS, transforming to `calc(... * var(--ppx-unit))` directly.
24 changes: 24 additions & 0 deletions packages/web-platform/web-core-e2e/tests/reactlynx.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,30 @@ test.describe('reactlynx3 tests', () => {
await expect(target).toHaveCSS('width', '10px');
});

test('basic-rpx-unit-js-value', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
const lynxView = await page.locator('lynx-view');
await lynxView.evaluate((node) => {
node.style.width = '50px';
});
const target = await page.locator('#target');
await expect(target).toHaveCSS('height', '10px'); // 20cqw, 50 / 100 * 20 = 10px
await expect(target).toHaveCSS('width', '10px');
});

test('basic-ppx-unit', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
const lynxView = await page.locator('lynx-view');
await lynxView.evaluate((node) => {
node.style.width = '50px';
});
const target = await page.locator('#target');
await expect(target).toHaveCSS('height', '10px'); // 20cqw, 50 / 100 * 20 = 10px
await expect(target).toHaveCSS('width', '10px');
});

test('basic-vw-vh-unit', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { root } from '@lynx-js/react';

function App() {
return (
<view
id='target'
style={{
height: '20ppx',
width: '20ppx',
background: 'pink',
}}
/>
);
}

root.render(<App></App>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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 { root } from '@lynx-js/react';

function App() {
return (
<view
id='target'
style={{
height: `${10 + 10}rpx`,
width: '20rpx',
background: 'pink',
}}
/>
);
}

root.render(<App></App>);
6 changes: 3 additions & 3 deletions packages/web-platform/web-core/binary/client/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ export function encode_legacy_json_generated_raw_style_info(raw_style_info: RawS

export function get_font_face_content(buffer: Uint8Array): string;

export function get_inline_styles_in_key_value_vec(dom: HTMLElement, k_v_vec: string[], transform_vw: boolean, transform_vh: boolean): void;

export function get_style_content(buffer: Uint8Array): string;

export function set_inline_styles_in_key_value_vec(dom: HTMLElement, k_v_vec: string[], transform_vw: boolean, transform_vh: boolean): void;

export function set_inline_styles_in_str(dom: HTMLElement, styles: string, transform_vw: boolean, transform_vh: boolean): boolean;

export function set_inline_styles_number_key(dom: HTMLElement, key: number, value?: string | null): void;
Expand All @@ -195,7 +195,6 @@ export interface InitOutput {
readonly decode_style_info: (a: any, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
readonly encode_legacy_json_generated_raw_style_info: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
readonly get_font_face_content: (a: any) => [number, number, number, number];
readonly get_inline_styles_in_key_value_vec: (a: any, b: number, c: number, d: number, e: number) => void;
readonly get_style_content: (a: any) => [number, number, number, number];
readonly mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
readonly mainthreadwasmcontext_add_dataset: (a: number, b: number, c: any, d: any) => [number, number];
Expand Down Expand Up @@ -232,6 +231,7 @@ export interface InitOutput {
readonly ruleprelude_new: () => number;
readonly ruleprelude_push_selector: (a: number, b: number) => void;
readonly selector_push_one_selector_section: (a: number, b: number, c: number, d: number, e: number) => [number, number];
readonly set_inline_styles_in_key_value_vec: (a: any, b: number, c: number, d: number, e: number) => void;
readonly set_inline_styles_in_str: (a: any, b: number, c: number, d: number, e: number) => number;
readonly set_inline_styles_number_key: (a: any, b: number, c: number, d: number) => void;
readonly stylesheetresource_new: (a: any, b: any) => [number, number, number];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export const add_inline_style_raw_string_key: (a: any, b: number, c: number, d:
export const decode_style_info: (a: any, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
export const encode_legacy_json_generated_raw_style_info: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
export const get_font_face_content: (a: any) => [number, number, number, number];
export const get_inline_styles_in_key_value_vec: (a: any, b: number, c: number, d: number, e: number) => void;
export const get_style_content: (a: any) => [number, number, number, number];
export const mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
export const mainthreadwasmcontext_add_dataset: (a: number, b: number, c: any, d: any) => [number, number];
Expand Down Expand Up @@ -55,6 +54,7 @@ export const rule_set_prelude: (a: number, b: number) => void;
export const ruleprelude_new: () => number;
export const ruleprelude_push_selector: (a: number, b: number) => void;
export const selector_push_one_selector_section: (a: number, b: number, c: number, d: number, e: number) => [number, number];
export const set_inline_styles_in_key_value_vec: (a: any, b: number, c: number, d: number, e: number) => void;
export const set_inline_styles_in_str: (a: any, b: number, c: number, d: number, e: number) => number;
export const set_inline_styles_number_key: (a: any, b: number, c: number, d: number) => void;
export const stylesheetresource_new: (a: any, b: any) => [number, number, number];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ export function encode_legacy_json_generated_raw_style_info(raw_style_info: RawS

export function get_font_face_content(buffer: Uint8Array): string;

export function get_inline_styles_in_key_value_vec(dom: HTMLElement, k_v_vec: string[], transform_vw: boolean, transform_vh: boolean): void;

export function get_style_content(buffer: Uint8Array): string;

export function set_inline_styles_in_key_value_vec(dom: HTMLElement, k_v_vec: string[], transform_vw: boolean, transform_vh: boolean): void;

export function set_inline_styles_in_str(dom: HTMLElement, styles: string, transform_vw: boolean, transform_vh: boolean): boolean;

export function set_inline_styles_number_key(dom: HTMLElement, key: number, value?: string | null): void;
Expand All @@ -195,7 +195,6 @@ export interface InitOutput {
readonly decode_style_info: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly encode_legacy_json_generated_raw_style_info: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly get_font_face_content: (a: number, b: number) => void;
readonly get_inline_styles_in_key_value_vec: (a: number, b: number, c: number, d: number, e: number) => void;
readonly get_style_content: (a: number, b: number) => void;
readonly mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
readonly mainthreadwasmcontext_add_dataset: (a: number, b: number, c: number, d: number, e: number) => void;
Expand Down Expand Up @@ -232,6 +231,7 @@ export interface InitOutput {
readonly ruleprelude_new: () => number;
readonly ruleprelude_push_selector: (a: number, b: number) => void;
readonly selector_push_one_selector_section: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
readonly set_inline_styles_in_key_value_vec: (a: number, b: number, c: number, d: number, e: number) => void;
readonly set_inline_styles_in_str: (a: number, b: number, c: number, d: number, e: number) => number;
readonly set_inline_styles_number_key: (a: number, b: number, c: number, d: number) => void;
readonly stylesheetresource_new: (a: number, b: number, c: number) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export const add_inline_style_raw_string_key: (a: number, b: number, c: number,
export const decode_style_info: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
export const encode_legacy_json_generated_raw_style_info: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
export const get_font_face_content: (a: number, b: number) => void;
export const get_inline_styles_in_key_value_vec: (a: number, b: number, c: number, d: number, e: number) => void;
export const get_style_content: (a: number, b: number) => void;
export const mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
export const mainthreadwasmcontext_add_dataset: (a: number, b: number, c: number, d: number, e: number) => void;
Expand Down Expand Up @@ -55,6 +54,7 @@ export const rule_set_prelude: (a: number, b: number) => void;
export const ruleprelude_new: () => number;
export const ruleprelude_push_selector: (a: number, b: number) => void;
export const selector_push_one_selector_section: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
export const set_inline_styles_in_key_value_vec: (a: number, b: number, c: number, d: number, e: number) => void;
export const set_inline_styles_in_str: (a: number, b: number, c: number, d: number, e: number) => number;
export const set_inline_styles_number_key: (a: number, b: number, c: number, d: number) => void;
export const stylesheetresource_new: (a: number, b: number, c: number) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/web-platform/web-core/binary/server/server.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export class MainThreadServerContext {
generate_html(element_id: number): string;
get_attribute(element_id: number, key: string): string | undefined;
get_attributes(element_id: number): object;
get_inline_styles_in_key_value_vec(element_id: number, k_v_vec: string[]): void;
get_page_css(): string;
get_parent(child_id: number): number | undefined;
get_tag(element_id: number): string | undefined;
Expand All @@ -24,6 +23,7 @@ export class MainThreadServerContext {
replace_elements(parent_id: number, new_children_ids: Uint32Array, old_children_ids: Uint32Array): void;
set_attribute(element_id: number, key: string, value: string): void;
set_css_id(elements_unique_id: Uint32Array, css_id: number, entry_name?: string | null): void;
set_inline_styles_in_key_value_vec(element_id: number, k_v_vec: string[]): void;
set_inline_styles_in_str(element_id: number, styles: string): boolean;
set_inline_styles_number_key(element_id: number, key: number, value?: string | null): void;
update_css_og_style(unique_id: number, entry_name?: string | null): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const mainthreadservercontext_create_element: (a: number, b: number, c: n
export const mainthreadservercontext_generate_html: (a: number, b: number) => [number, number];
export const mainthreadservercontext_get_attribute: (a: number, b: number, c: number, d: number) => [number, number];
export const mainthreadservercontext_get_attributes: (a: number, b: number) => [number, number, number];
export const mainthreadservercontext_get_inline_styles_in_key_value_vec: (a: number, b: number, c: number, d: number) => void;
export const mainthreadservercontext_get_page_css: (a: number) => [number, number];
export const mainthreadservercontext_get_parent: (a: number, b: number) => number;
export const mainthreadservercontext_get_tag: (a: number, b: number) => [number, number];
Expand All @@ -32,6 +31,7 @@ export const mainthreadservercontext_replace_element: (a: number, b: number, c:
export const mainthreadservercontext_replace_elements: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
export const mainthreadservercontext_set_attribute: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
export const mainthreadservercontext_set_css_id: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number];
export const mainthreadservercontext_set_inline_styles_in_key_value_vec: (a: number, b: number, c: number, d: number) => void;
export const mainthreadservercontext_set_inline_styles_in_str: (a: number, b: number, c: number, d: number) => number;
export const mainthreadservercontext_set_inline_styles_number_key: (a: number, b: number, c: number, d: number, e: number) => void;
export const mainthreadservercontext_update_css_og_style: (a: number, b: number, c: number, d: number) => [number, number];
Expand Down
7 changes: 7 additions & 0 deletions packages/web-platform/web-core/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ lynx-view {
container-name: lynx-view;
container-type: inline-size;
--rpx-unit: 1cqw;
--ppx-unit: 1cqw;
--vw-unit: 1vw;
--vh-unit: 1vh;
}
Expand All @@ -34,6 +35,7 @@ lynx-view::part(page) {
height: 100%;
width: 100%;
--rpx-unit: inherit;
--ppx-unit: inherit;
--vw-unit: inherit;
--vh-unit: inherit;
}
Expand All @@ -43,6 +45,11 @@ lynx-view::part(page) {
inherits: true;
}

@property --ppx-unit {
syntax: "<length>";
inherits: true;
}

@property --vw-unit {
syntax: "<length>";
inherits: true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub fn set_inline_styles_in_str(
}

#[wasm_bindgen]
pub fn get_inline_styles_in_key_value_vec(
pub fn set_inline_styles_in_key_value_vec(
dom: &web_sys::HtmlElement,
k_v_vec: Vec<String>,
transform_vw: bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl MainThreadServerContext {
true
}

pub fn get_inline_styles_in_key_value_vec(&mut self, element_id: usize, k_v_vec: Vec<String>) {
pub fn set_inline_styles_in_key_value_vec(&mut self, element_id: usize, k_v_vec: Vec<String>) {
let transformed_style_str = transform_inline_style_key_value_vec(
k_v_vec,
&crate::style_transformer::token_transformer::TransformerConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ pub(crate) fn transform_inline_style_key_value_vec(
key = value;
} else {
let name = hyphenate_style_name(&key);
transformer.on_declaration_parsed(name.into(), value, false);
use crate::css_tokenizer::tokenize::Parser;
transformer.on_token(crate::css_tokenizer::token_types::IDENT_TOKEN, &name);
transformer.on_token(crate::css_tokenizer::token_types::COLON_TOKEN, ":");
crate::css_tokenizer::tokenize::tokenize(&value, transformer);
transformer.on_token(crate::css_tokenizer::token_types::SEMICOLON_TOKEN, ";");
}
}

Expand Down Expand Up @@ -273,4 +277,13 @@ mod tests {
let result = transform_inline_style_string(source, &TransformerConfig::default());
assert_eq!(result, "--align-self-row:start;--align-self-column:start;");
}

#[test]
fn rpx_unit_in_key_value_vec() {
let result = transform_inline_style_key_value_vec(
vec!["height".to_string(), "100rpx".to_string()],
&TransformerConfig::default(),
);
assert_eq!(result, "height:calc(100 * var(--rpx-unit));");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,38 @@ pub(crate) fn transform_one_token<'a>(
) -> (u8, Cow<'a, str>) {
match token_type {
DIMENSION_TOKEN => {
if token_value.len() > 3 && token_value.to_ascii_lowercase().ends_with("rpx") {
let value = &token_value[..token_value.len() - 3];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--rpx-unit))")),
);
let len = token_value.len();
if len > 3 {
let suffix = &token_value[len - 3..];
if suffix.eq_ignore_ascii_case("rpx") {
let value = &token_value[..len - 3];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--rpx-unit))")),
);
} else if suffix.eq_ignore_ascii_case("ppx") {
let value = &token_value[..len - 3];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--ppx-unit))")),
);
}
}
if config.transform_vw
&& token_value.len() > 2
&& token_value.to_ascii_lowercase().ends_with("vw")
{
let value = &token_value[..token_value.len() - 2];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--vw-unit))")),
);
}
if config.transform_vh
&& token_value.len() > 2
&& token_value.to_ascii_lowercase().ends_with("vh")
{
let value = &token_value[..token_value.len() - 2];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--vh-unit))")),
);
if len > 2 {
let suffix = &token_value[len - 2..];
if config.transform_vw && suffix.eq_ignore_ascii_case("vw") {
let value = &token_value[..len - 2];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--vw-unit))")),
);
} else if config.transform_vh && suffix.eq_ignore_ascii_case("vh") {
let value = &token_value[..len - 2];
return (
token_type,
Cow::Owned(format!("calc({value} * var(--vh-unit))")),
);
}
}
(token_type, Cow::Borrowed(token_value))
}
Expand Down Expand Up @@ -86,6 +92,18 @@ mod tests {
assert_eq!(tv, "calc(100 * var(--rpx-unit))");
}

#[test]
fn test_transform_ppx() {
let (_, tv) = transform_one_token(DIMENSION_TOKEN, "100ppx", &TransformerConfig::default());
assert_eq!(tv, "calc(100 * var(--ppx-unit))");
}

#[test]
fn test_transform_ppx_case_insensitive() {
let (_, tv) = transform_one_token(DIMENSION_TOKEN, "100PPX", &TransformerConfig::default());
assert_eq!(tv, "calc(100 * var(--ppx-unit))");
}

#[test]
fn test_transform_vw() {
let (_, tv) = transform_one_token(
Expand Down
1 change: 1 addition & 0 deletions packages/web-platform/web-core/test_transformer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use std::borrow::Cow;
Loading
Loading