onSetAttributesAsText method
void
onSetAttributesAsText(
- int? id,
- Map<String, dynamic> params
)
Implementation
void onSetAttributesAsText(int? id, Map<String, dynamic> params) {
if (DebugFlags.enableDevToolsLogs) {
devToolsLogger.finer('[DevTools] DOM.setAttributesAsText nodeId=${params['nodeId']}');
}
int? nodeId = params['nodeId'];
String? text = params['text'];
String? name = params['name'];
final ctx = dbgContext;
if (nodeId == null || ctx == null) {
sendToFrontend(id, null);
return;
}
final targetId = ctx.getTargetIdByNodeId(nodeId);
Node? node;
if (targetId != null) {
node = ctx.getBindingObject(Pointer.fromAddress(targetId)) as Node?;
}
if (node is Element && text != null) {
final el = node as Element;
if (name != null && name.isNotEmpty) {
// Update single attribute case
if (text.isEmpty) {
el.removeAttribute(name);
} else {
el.setAttribute(name, text);
}
} else {
// Replace attributes from text string
el.attributes.clear();
// Match name="value" or name='value', allow hyphens/colons in attribute name
final pair = RegExp(r"""([^\s=]+)\s*=\s*("([^"]*)"|'([^']*)')""");
for (final m in pair.allMatches(text)) {
final attrName = m.group(1);
final dv = m.group(3); // double-quoted value
final sv = m.group(4); // single-quoted value
final attrValue = dv ?? sv ?? '';
if (attrName != null) {
el.setAttribute(attrName, attrValue);
}
}
// Also handle boolean attributes present without =value
// by scanning leftover tokens that look like names
final consumed = pair.allMatches(text).map((m) => m.group(0)!).join(' ');
final remainder = text.replaceAll(consumed, ' ').trim();
if (remainder.isNotEmpty) {
// Split by whitespace and set empty string for each token not containing '='
for (final token in remainder.split(RegExp(r'\s+'))) {
if (token.isEmpty) continue;
if (!token.contains('=')) {
el.setAttribute(token, '');
}
}
}
}
}
sendToFrontend(id, null);
}