Skip to content

Commit

Permalink
Merge pull request #1336 from openkraken/fix/err_of_textNode_attachTo…
Browse files Browse the repository at this point in the history
…_WidgetElement

Fix err of textNode attach to WidgetElement.
  • Loading branch information
answershuto committed Apr 26, 2022
2 parents 6891473 + d8ee1fb commit 94c404a
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 15 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions integration_tests/specs/dom/elements/custom-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ describe('custom widget element', () => {
await snapshot();
});

it('text node should be child of flutter container and append before container append to body', async () => {
const container = document.createElement('flutter-container');
const text = document.createTextNode('text');
container.appendChild(text);
document.body.appendChild(container);
await snapshot();
});

it('element should be child of flutter container', async () => {
const container = document.createElement('flutter-container');
const element = document.createElement('div');
Expand Down Expand Up @@ -75,6 +83,7 @@ describe('custom widget element', () => {

const element = document.createElement('div');
element.style.backgroundColor = 'red';
element.style.textAlign = 'center';
element.appendChild(document.createTextNode('div element'));
container.appendChild(element);

Expand Down
15 changes: 7 additions & 8 deletions kraken/lib/src/dom/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'package:kraken/css.dart';
import 'package:kraken/dom.dart';
import 'package:kraken/foundation.dart';
import 'package:kraken/rendering.dart';
import 'package:kraken/widget.dart';

final RegExp _splitRegExp = RegExp(r'\s+');
const String _ONE_SPACE = ' ';
Expand Down Expand Up @@ -723,7 +722,7 @@ abstract class Element
// Attach renderObject of current node to parent
@override
void attachTo(Node parent, {RenderBox? after}) {
_applyStyle(style);
applyStyle(style);

if (parentElement?.renderStyle.display == CSSDisplay.sliver) {
// Sliver should not create renderer here, but need to trigger
Expand All @@ -735,7 +734,7 @@ abstract class Element

if (renderer != null) {
// If element attach WidgetElement, render object should be attach to render tree when mount.
if (parent is! WidgetElement) {
if (parent.renderObjectManagerType == RenderObjectManagerType.KRAKEN_NODE) {
RenderBoxModel.attachRenderBox(parent.renderer!, renderer!, after: after);
}

Expand Down Expand Up @@ -797,7 +796,7 @@ abstract class Element
RenderLayoutBox? renderLayoutBox = _renderLayoutBox;
if (isRendererAttached) {
// Only append child renderer when which is not attached.
if (!child.isRendererAttached && renderLayoutBox != null && this is! WidgetElement) {
if (!child.isRendererAttached && renderLayoutBox != null && renderObjectManagerType == RenderObjectManagerType.KRAKEN_NODE) {
RenderBox? after;
RenderLayoutBox? scrollingContentBox = renderLayoutBox.renderScrollingContent;
if (scrollingContentBox != null) {
Expand Down Expand Up @@ -969,8 +968,8 @@ abstract class Element
_updateRenderBoxModel();
// Attach renderBoxModel to parent if change from `display: none` to other values.
if (!isRendererAttached && parentElement != null && parentElement!.isRendererAttached) {
// If element attach WidgetElement, render obeject should be attach to render tree when mount.
if (parentNode is! WidgetElement) {
// If element attach WidgetElement, render object should be attach to render tree when mount.
if (parentElement!.renderObjectManagerType == RenderObjectManagerType.KRAKEN_NODE) {
RenderBoxModel _renderBoxModel = renderBoxModel!;
// Find the renderBox of its containing block.
RenderBox? containingBlockRenderBox = getContainingBlockRenderBox();
Expand Down Expand Up @@ -1399,7 +1398,7 @@ abstract class Element
style.setProperty(property, value, true);
}

void _applyStyle(CSSStyleDeclaration style) {
void applyStyle(CSSStyleDeclaration style) {
// Apply default style.
_applyDefaultStyle(style);
// Init display from style directly cause renderStyle is not flushed yet.
Expand All @@ -1414,7 +1413,7 @@ abstract class Element
if (renderBoxModel != null && classList.isNotEmpty) {
// Diff style.
CSSStyleDeclaration newStyle = CSSStyleDeclaration();
_applyStyle(newStyle);
applyStyle(newStyle);
Map<String, String?> diffs = style.diff(newStyle);
if (diffs.isNotEmpty) {
// Update render style.
Expand Down
10 changes: 8 additions & 2 deletions kraken/lib/src/dom/node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ enum NodeType {
DOCUMENT_FRAGMENT_NODE,
}

enum RenderObjectManagerType {
FLUTTER_ELEMENT,
KRAKEN_NODE
}

/// [RenderObjectNode] provide the renderObject related abstract life cycle for
/// [Node] or [Element]s, which wrap [RenderObject]s, which provide the actual
/// rendering of the application.
Expand Down Expand Up @@ -161,7 +166,6 @@ abstract class Node extends EventTarget implements RenderObjectNode, LifecycleCa
void willAttachRenderer() {}

@override
@mustCallSuper
void didAttachRenderer() {
// The node attach may affect the whitespace of the nextSibling and previousSibling text node so prev and next node require layout.
if (renderer is RenderBoxModel) {
Expand All @@ -170,7 +174,6 @@ abstract class Node extends EventTarget implements RenderObjectNode, LifecycleCa
}

@override
@mustCallSuper
void willDetachRenderer() {
// The node detach may affect the whitespace of the nextSibling and previousSibling text node so prev and next node require layout.
if (renderer is RenderBoxModel) {
Expand Down Expand Up @@ -306,6 +309,9 @@ abstract class Node extends EventTarget implements RenderObjectNode, LifecycleCa

@override
EventTarget? get parentEventTarget => parentNode;

// Whether Kraken Node need to manage render object.
RenderObjectManagerType get renderObjectManagerType => RenderObjectManagerType.KRAKEN_NODE;
}

/// https://dom.spec.whatwg.org/#dom-node-nodetype
Expand Down
6 changes: 4 additions & 2 deletions kraken/lib/src/dom/text_node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ class TextNode extends Node {

createRenderer();

if (parent.renderBoxModel is RenderLayoutBox) {
// If element attach WidgetElement, render object should be attach to render tree when mount.
if (parent.renderObjectManagerType == RenderObjectManagerType.KRAKEN_NODE && parent.renderBoxModel is RenderLayoutBox) {
RenderLayoutBox parentRenderLayoutBox = parent.renderBoxModel as RenderLayoutBox;
parentRenderLayoutBox = parentRenderLayoutBox.renderScrollingContent ?? parentRenderLayoutBox;
parentRenderLayoutBox.insert(_renderTextBox!, after: after);
_applyTextStyle();
}

_applyTextStyle();
}

// Detach renderObject of current node from parent
Expand Down
8 changes: 7 additions & 1 deletion kraken/lib/src/widget/element_to_widget_adaptor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ class KrakenElementToFlutterElementAdaptor extends RenderObjectElement {
widget._krakenNode.ensureChildAttached();

if (widget._krakenNode is dom.Element) {
(widget._krakenNode as dom.Element).style.flushPendingProperties();
dom.Element element = (widget._krakenNode as dom.Element);
element.applyStyle(element.style);

if (element.renderer != null) {
// Flush pending style before child attached.
element.style.flushPendingProperties();
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions kraken/lib/src/widget/widget_to_element_adaptor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,18 @@ abstract class WidgetElement extends dom.Element {

Widget build(BuildContext context, Map<String, dynamic> properties, List<Widget> children);

// The render object is inserted by Flutter framework when element is WidgetElement.
@override
dom.RenderObjectManagerType get renderObjectManagerType => dom.RenderObjectManagerType.FLUTTER_ELEMENT;

@override
void didDetachRenderer() {
super.didDetachRenderer();
}

@override
void didAttachRenderer() {
super.didAttachRenderer();

// Children of WidgetElement should insert render object by Flutter Framework.
_attachWidget(_widget);
}

Expand Down

0 comments on commit 94c404a

Please sign in to comment.