Skip to content

[BUG] Repeat polyfill() runs grow the inline style attributes #461

Description

@jamesnw

Repeat polyfill() runs grow the inline style attributes, because we keep adding them. That isn't caused by this PR, but we've now amplified it since we're matching against more declarations.

I think we could fix this by removing stale attributes that we've added on a previous run before we re-shift on a subsequent run. Something like this in cascade.ts (I haven't tested this):

diff --git a/src/cascade.ts b/src/cascade.ts
--- a/src/cascade.ts
+++ b/src/cascade.ts
@@ -132,12 +132,31 @@ export function registerShiftedProperties(
   }
 }
 
+/**
+ * Remove every declaration of `property` from `block`.
+ *
+ * Used before appending a generated declaration, so that re-processing a block
+ * we already wrote doesn't accumulate a duplicate each time. Inline styles are
+ * re-parsed from the `style` attribute a previous run wrote back, so this is
+ * the difference between an idempotent run and one that grows the attribute
+ * without bound. Removing rather than skipping keeps last-wins order when a
+ * block declares the same property twice.
+ */
+function dropExistingDeclarations(block: Block, property: string) {
+  block.children.forEach((child, item) => {
+    if (isDeclaration(child) && child.property === property) {
+      block.children.remove(item);
+    }
+  });
+}
+
 /**
  * Shift property declarations for properties that are not yet natively
  * supported into custom properties.
  */
 function shiftUnsupportedProperties(node: CssNode, block?: Block) {
   if (isDeclaration(node) && SHIFTED_PROPERTIES[node.property] && block) {
+    dropExistingDeclarations(block, SHIFTED_PROPERTIES[node.property]);
     block.children.appendData({
       ...node,
       property: SHIFTED_PROPERTIES[node.property],
@@ -162,6 +181,7 @@ function expandInsetShorthands(node: CssNode, block?: Block) {
 
   const appendProperty = (property: string, value?: CssNode) => {
     if (!value) return;
+    dropExistingDeclarations(block, property);
     block.children.appendData({
       ...node,
       property,

Or @jpzwarte and @jamesnw if you think this deserves its own issue and PR, that's fine too!

Originally posted by @jgerigmeyer in #448 (review)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions