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
3 changes: 3 additions & 0 deletions debug-symbols/0.24.25+2/android-debug-symbols.7z
Git LFS file not shown
3 changes: 3 additions & 0 deletions debug-symbols/0.24.25+2/ios-debug-symbols.7z
Git LFS file not shown
3 changes: 3 additions & 0 deletions debug-symbols/0.24.25+2/linux-debug-symbols.7z
Git LFS file not shown
3 changes: 3 additions & 0 deletions debug-symbols/0.24.25+2/macos-debug-symbols.7z
Git LFS file not shown
3 changes: 3 additions & 0 deletions debug-symbols/0.24.25+2/windows-debug-symbols.7z
Git LFS file not shown
74 changes: 74 additions & 0 deletions integration_tests/lib/custom_elements/flutter_tooltips.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:webf/dom.dart' as dom;
import 'package:webf/rendering.dart';
import 'package:webf/webf.dart';

class FlutterToolTipsElement extends WidgetElement {
FlutterToolTipsElement(super.context);

@override
WebFWidgetElementState createState() => FlutterToolTipsElementState(this);
}

class FlutterToolTipsElementState extends WebFWidgetElementState {
FlutterToolTipsElementState(super.widgetElement);

FlutterToolTipsElement get tooltipsElement =>
widgetElement as FlutterToolTipsElement;

@override
Widget build(BuildContext context) {
dom.Element? firstElementChild;
for (final dom.Node node in tooltipsElement.childNodes) {
if (node is dom.Element) {
firstElementChild = node;
break;
}
}

return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
widgetElement.dispatchEvent(Event('click', bubbles: true));
},
child: firstElementChild != null
? WebFWidgetElementChild(child: firstElementChild.toWidget())
: const SizedBox.shrink(),
);
}
}

class WebFTestAutoSizeTextElement extends WidgetElement {
WebFTestAutoSizeTextElement(super.context);

@override
WebFWidgetElementState createState() => WebFTestAutoSizeTextElementState(this);
}

class WebFTestAutoSizeTextElementState extends WebFWidgetElementState {
WebFTestAutoSizeTextElementState(super.widgetElement);

WebFTestAutoSizeTextElement get autoSizeTextElement =>
widgetElement as WebFTestAutoSizeTextElement;

@override
Widget build(BuildContext context) {
final String text = autoSizeTextElement.getAttribute('text') ?? '';
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Text(
text,
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
textScaler: const TextScaler.linear(1.0),
style: const TextStyle(
color: Colors.white,
fontSize: 24,
height: 1,
),
);
},
);
}
}
3 changes: 3 additions & 0 deletions integration_tests/lib/custom_elements/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'flutter_cupertino_portal_modal_popup.dart';
import 'flutter_portal_popup_item.dart';
import 'flutter_bottom_sheet.dart';
import 'flutter_ifc_host.dart';
import 'flutter_tooltips.dart';

void defineWebFCustomElements() {
WebF.defineCustomElement('flutter-button',
Expand Down Expand Up @@ -65,4 +66,6 @@ void defineWebFCustomElements() {
WebF.defineCustomElement('flutter-max-height-container', (context) => FlutterMaxHeightContainerElement(context));
WebF.defineCustomElement('flutter-fixed-height-slot', (context) => FlutterFixedHeightSlotElement(context));
WebF.defineCustomElement('flutter-ifc-host', (context) => FlutterIFCHostElement(context));
WebF.defineCustomElement('flutter-tooltips', (context) => FlutterToolTipsElement(context));
WebF.defineCustomElement('webf-test-auto-size-text', (context) => WebFTestAutoSizeTextElement(context));
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions integration_tests/specs/rendering/widget_tooltips_child_paint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
describe('Widget tooltips child paint', () => {
it('tooltip child widget text still paints after nested widget text update in flex layout', async () => {
document.documentElement.style.margin = '0';
document.body.style.margin = '0';
document.body.style.padding = '0';
document.body.style.backgroundColor = '#000';

const root = document.createElement('div');
root.setAttribute(
'style',
[
'display:flex',
'width:240px',
'padding:12px',
'background:#000',
].join(';'),
);

const column = document.createElement('div');
column.setAttribute(
'style',
[
'display:flex',
'flex-direction:column',
'min-width:0',
'flex:1',
].join(';'),
);

const row = document.createElement('div');
row.setAttribute(
'style',
[
'display:flex',
'width:100%',
'align-items:center',
].join(';'),
);

const tips = document.createElement('flutter-tooltips');
tips.id = 'tips';
tips.setAttribute('style', 'display:block; width:100%;');

const amount = document.createElement('webf-test-auto-size-text');
amount.id = 'amount';
amount.setAttribute('text', '1,200.686 USDT');

tips.appendChild(amount);
row.appendChild(tips);
column.appendChild(row);
root.appendChild(column);
document.body.appendChild(root);

await waitForOnScreen(root);
await nextFrames(4);

await snapshot();

amount.setAttribute('text', '9,999.999 USDT');
await nextFrames(4);
await sleep(0.2);

await snapshot();
});
});
8 changes: 8 additions & 0 deletions webf/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.24.25+2

### Bug Fixes

- **Rendering/Widget/Flex**: preserve hosted Flutter widget text painting after nested updates
in flex layouts by preventing percentage-width widget children from collapsing to a transient
zero-width layout during relayout.

## 0.24.25+1

### Bug Fixes
Expand Down
4 changes: 2 additions & 2 deletions webf/ios/webf.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ Pod::Spec.new do |s|
'LLVM_LTO' => 'YES', # Enable Link Time Optimization for release builds
'GCC_OPTIMIZATION_LEVEL' => 's', # Enable optimization for size
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) ' +
'APP_REV=\\"e9eee7148\\" ' +
'APP_VERSION=\\"0.24.25+1\\" ' +
'APP_REV=\\"218bfc723\\" ' +
'APP_VERSION=\\"0.24.25+2\\" ' +
'CONFIG_VERSION=\\"2025-04-26\\" ' +
'WEBF_QUICK_JS_ENGINE=1 ' +
'FLUTTER_BACKEND=1 ' +
Expand Down
26 changes: 24 additions & 2 deletions webf/lib/src/rendering/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,30 @@ class RenderWidget extends RenderBoxModel
if (renderStyle.width.type != CSSLengthType.AUTO) {
final double? logicalContentWidth = renderStyle.contentBoxLogicalWidth;
if (logicalContentWidth != null && logicalContentWidth.isFinite) {
final double clampedWidth = logicalContentWidth.clamp(
contentConstraints!.minWidth, contentConstraints!.maxWidth);
double minWidth = childConstraints.minWidth;
double maxWidth = childConstraints.maxWidth;

// Percentage-width widget subtrees can briefly inherit a zero max-width
// from flex adjustment even though their used content width has already
// resolved from the containing block. Preserve that resolved width here
// instead of collapsing the hosted Flutter child to 0px.
if (renderStyle.width.type == CSSLengthType.PERCENTAGE &&
maxWidth == 0 &&
logicalContentWidth > 0) {
maxWidth = logicalContentWidth;
if (minWidth > maxWidth) {
minWidth = maxWidth;
}
childConstraints = BoxConstraints(
minWidth: minWidth,
maxWidth: maxWidth,
minHeight: childConstraints.minHeight,
maxHeight: childConstraints.maxHeight,
);
}

final double clampedWidth =
logicalContentWidth.clamp(minWidth, maxWidth).toDouble();
childConstraints = childConstraints.tighten(width: clampedWidth);
}
}
Expand Down
2 changes: 1 addition & 1 deletion webf/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: webf
description: W3C standards-compliant web rendering engine based on Flutter, allowing web applications to run natively on Flutter.
version: 0.24.25+1
version: 0.24.25+2
homepage: https://openwebf.com
license: GPL-3.0-only
environment:
Expand Down
Loading
Loading