update method
void
update(
- String? id,
- String? classes,
- Map<
String, String> ? styles, - Map<
String, String> ? attributes, - Map<
String, EventCallback> ? events,
override
Implementation
@override
void update(
String? id,
String? classes,
Map<String, String>? styles,
Map<String, String>? attributes,
Map<String, EventCallback>? events,
) {
final Set<String> originalAttributes = {
for (var i = 0; i < node.attributes.length; i++) node.attributes.item(i)!.name,
};
node.clearOrSetAttribute('id', id);
node.clearOrSetAttribute('class', classes == null || classes.isEmpty ? null : classes);
node.clearOrSetAttribute(
'style',
styles == null || styles.isEmpty ? null : styles.entries.map((e) => '${e.key}: ${e.value}').join('; '),
);
if (attributes != null && attributes.isNotEmpty) {
for (final MapEntry(key: attrName, value: attrValue) in attributes.entries) {
if (attrName == 'value') {
if (node.isHtmlSelectElement) {
final nodeAsSelectElement = node as web.HTMLSelectElement;
if (nodeAsSelectElement.value != attrValue) {
if (kVerboseMode) {
print('Set select value: $attrValue');
}
nodeAsSelectElement.value = attrValue;
}
continue;
}
if (node.isHtmlInputElement) {
final nodeAsInputElement = node as web.HTMLInputElement;
if (nodeAsInputElement.value != attrValue) {
if (kVerboseMode) {
print('Set input value: $attrValue');
}
nodeAsInputElement.value = attrValue;
}
continue;
}
} else if (attrName == 'checked') {
if (node.isHtmlInputElement) {
final nodeAsInputElement = node as web.HTMLInputElement;
if (nodeAsInputElement.type case 'checkbox' || 'radio') {
final shouldBeChecked = attrValue == 'true';
if (nodeAsInputElement.checked != shouldBeChecked) {
if (kVerboseMode) {
print('Set input checked: $shouldBeChecked');
}
nodeAsInputElement.checked = shouldBeChecked;
if (!shouldBeChecked && node.hasAttribute('checked')) {
// Remove the attribute if unchecked to avoid HTML5 validation issues.
nodeAsInputElement.removeAttribute('checked');
}
}
continue;
}
}
} else if (attrName == 'indeterminate') {
if (node.isHtmlInputElement) {
final nodeAsInputElement = node as web.HTMLInputElement;
if (nodeAsInputElement.type == 'checkbox') {
final shouldBeIndeterminate = attrValue == 'true';
if (nodeAsInputElement.indeterminate != shouldBeIndeterminate) {
if (kVerboseMode) {
print('Set input indeterminate: $shouldBeIndeterminate');
}
nodeAsInputElement.indeterminate = shouldBeIndeterminate;
if (!shouldBeIndeterminate && node.hasAttribute('indeterminate')) {
// Remove the attribute if unchecked to avoid HTML5 validation issues.
nodeAsInputElement.removeAttribute('indeterminate');
}
}
continue;
}
}
}
node.clearOrSetAttribute(attrName, attrValue);
}
}
final attributesToRemove = originalAttributes.difference({'id', 'class', 'style', ...?attributes?.keys});
for (final name in attributesToRemove) {
node.removeAttribute(name);
if (kVerboseMode) {
print('Removed attribute: $name');
}
}
if (events != null && events.isNotEmpty) {
final dataEvents = this.events ??= <String, EventBinding>{};
final prevEventTypes = dataEvents.keys.toSet();
events.forEach((type, fn) {
prevEventTypes.remove(type);
final currentBinding = dataEvents[type];
if (currentBinding != null) {
currentBinding.fn = fn;
} else {
dataEvents[type] = EventBinding(node, type, fn);
}
});
for (final type in prevEventTypes) {
dataEvents.remove(type)?.clear();
}
} else {
if (this.events case final existingEvents?) {
for (final binding in existingEvents.values) {
binding.clear();
}
this.events = null;
}
}
}