Attributes without values breaks the parser
yatesco opened this issue · 3 comments
Hi,
I've noticed that the parser doesn't like <button readonly>
but <button readonly="">
is fine. The error is: htmlElement.setAttribute(lowerName, emptyValue ? EMPTY.STR : value);
in the following listing:
// node_modules/diffhtml/dist/es/node/patch.js
var { keys } = Object;
var blocklist = /* @__PURE__ */ new Set();
var allowlist = /* @__PURE__ */ new Set();
var setAttribute = (vTree, domNode, name, value) => {
const isObject = typeof value === "object" && value;
const isFunction = typeof value === "function";
const isSymbol = typeof value === "symbol";
const isEvent = name.indexOf("on") === 0;
const anyNode = domNode;
const lowerName = isEvent ? name.toLowerCase() : name;
const blocklistName = "s-" + vTree.nodeName + "-" + lowerName;
const htmlElement = domNode;
if (allowlist.has(blocklistName)) {
anyNode[lowerName] = value;
} else if (!blocklist.has(blocklistName)) {
try {
anyNode[lowerName] = value;
allowlist.add(blocklistName);
} catch {
blocklist.add(blocklistName);
}
}
if (!isObject && !isFunction && !isSymbol) {
const emptyValue = value === null || value === void 0 || value === true;
htmlElement.setAttribute(lowerName, emptyValue ? EMPTY.STR : value); <!-- HERE -->
} else if (isObject && lowerName === "style") {
const valueKeys = keys(value);
for (let i = 0; i < valueKeys.length; i++) {
htmlElement.style[valueKeys[i]] = value[valueKeys[i]];
}
}
};
...
Unfortunately, this is from the bundled source code so I can't find the exact reference - I hope that's sufficient?
NOTE: it tends to fail on a descendant of a node with a valueless attribute, so in this case the child that failed was a grandchild of the element with a valueless attribute.
This bug report is all a bit messy - apologies - I'm on a time critical project ATM - I can return later (next week) with a reproducible project if that would help?
Sorry :( the old parser was based off node-fast-html-parser, and as such inherited some issues. I have this fixed in the new parser, but still playing whack-a-mole with existing tests. It's getting very close!
No problem at all @tbranyen :-).
One critical bug/feature I use is the fact that it doesn't overwrite input fields if the page has newer data:
- now: input field = "abc"
- now+1 request latest from server
- now+2: input field = "abcdef"
- now+3 response from server, containing "input field=abc"
- now+4 merge complete
Crucially, the input field contains "abcdef" not the "abc" from the server. I rely on this, so can we please keep this behaviour (albeit behind a config option maybe?"