updateElement method
void
updateElement(
- String tag,
- String? id,
- String? classes,
- Map<
String, String> ? styles, - Map<
String, String> ? attributes, - Map<
String, EventCallback> ? events,
override
Implementation
@override
void updateElement(String tag, String? id, String? classes, Map<String, String>? styles,
Map<String, String>? attributes, Map<String, EventCallback>? events) {
late Set<String> attributesToRemove;
late html.Element elem;
var namespace = xmlns[tag];
if ((namespace, parent?.node) case (== null, html.Element pnode)) {
namespace = pnode.namespaceUri;
}
diff:
if (node == null) {
var toHydrate = parent!.toHydrate;
if (toHydrate.isNotEmpty) {
for (var e in toHydrate) {
if (e is html.Element && e.tagName.toLowerCase() == tag) {
if (kVerboseMode) {
print("Hydrate html node: $e");
}
elem = node = e;
attributesToRemove = elem.attributes.keys.toSet();
toHydrate.remove(e);
Iterable<Node> nodes = e.nodes;
if (kDebugMode) {
nodes = nodes.where((node) => node is! html.Text || (node.text ?? '').trim().isNotEmpty);
}
this.toHydrate = nodes.toList();
break diff;
}
}
}
elem = node = _createElement(tag, namespace);
attributesToRemove = {};
if (kVerboseMode) {
print("Create html node: $elem");
}
} else {
if (node is! html.Element || (node as html.Element).tagName.toLowerCase() != tag) {
elem = _createElement(tag, namespace);
var old = node;
node!.replaceWith(elem);
node = elem;
if (old != null && old.childNodes.isNotEmpty) {
var oldChildren = [...old.childNodes];
for (var child in oldChildren) {
elem.append(child);
}
}
attributesToRemove = {};
if (kVerboseMode) {
print("Replace html node: $elem for $old");
}
} else {
elem = node as html.Element;
attributesToRemove = elem.attributes.keys.toSet();
}
}
elem.clearOrSetAttribute('id', id);
elem.clearOrSetAttribute('class', classes == null || classes.isEmpty ? null : classes);
elem.clearOrSetAttribute('style',
styles == null || styles.isEmpty ? null : styles.entries.map((e) => '${e.key}: ${e.value}').join('; '));
if (attributes != null && attributes.isNotEmpty) {
for (var attr in attributes.entries) {
if (attr.key == 'value' && elem is InputElement && elem.value != attr.value) {
if (kVerboseMode) {
print("Set input value: ${attr.value}");
}
elem.value = attr.value;
continue;
}
elem.clearOrSetAttribute(attr.key, attr.value);
}
}
attributesToRemove.removeAll(['id', 'class', 'style', ...?attributes?.keys]);
if (attributesToRemove.isNotEmpty) {
for (final name in attributesToRemove) {
elem.removeAttribute(name);
if (kVerboseMode) {
print("Remove attribute: $name");
}
}
}
if (events != null && events.isNotEmpty) {
final prevEventTypes = this.events?.keys.toSet();
this.events ??= <String, EventBinding>{};
final dataEvents = this.events!;
events.forEach((type, fn) {
prevEventTypes?.remove(type);
final currentBinding = dataEvents[type];
if (currentBinding != null) {
currentBinding.fn = fn;
} else {
dataEvents[type] = EventBinding(elem, type, fn);
}
});
prevEventTypes?.forEach((type) {
dataEvents.remove(type)?.clear();
});
} else {
clearEvents();
}
}