<!DOCTYPE html>
<title>CSSOM test: declaration block after setting via CSSOM</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#set-a-css-declaration-value">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
  function generateCSSDeclBlock(props) {
    let elem = document.createElement("div");
    let cssText = props.map(({name, value, priority}) => {
      let longhand = `${name}: ${value}`;
      if (priority) {
        longhand += "!" + priority;
      }
      return longhand + ";";
    }).join(" ");
    elem.setAttribute("style", cssText);
    return elem.style;
  }
  function compareByName(a, b) {
    if (a.name < b.name) return -1;
    if (a.name > b.name) return 1;
    return 0;
  }
  function checkDeclarationsAnyOrder(block, props, msg) {
    let actual = [];
    for (let name of block) {
      let value = block.getPropertyValue(name);
      let priority = block.getPropertyPriority(name);
      actual.push({name, value, priority});
    }
    actual.sort(compareByName);
    let expected = Array.from(props);
    expected.sort(compareByName);
    assert_object_equals(actual, expected, "Declaration block content should match " + msg);
  }
  function longhand(name, value, priority="") {
    return {name, value, priority};
  }
  function* shorthand(name, value, priority="") {
    for (let subprop of SUBPROPS[name]) {
      yield longhand(subprop, value, priority);
    }
  }

  const SUBPROPS = {
    "margin": ["margin-top", "margin-right", "margin-bottom", "margin-left"],
    "padding": ["padding-top", "padding-right", "padding-bottom", "padding-left"],
  };

  test(function() {
    let expectedDecls = [
      longhand("top", "1px"),
      longhand("bottom", "2px"),
      longhand("left", "3px", "important"),
      longhand("right", "4px"),
    ];
    let block = generateCSSDeclBlock(expectedDecls);
    checkDeclarationsAnyOrder(block, expectedDecls, "in initial block");

    block.setProperty("top", "5px", "important");
    expectedDecls[0] = longhand("top", "5px", "important");
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting existing property");

    block.setProperty("bottom", "2px");
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting existing property with identical value");

    block.setProperty("left", "3px");
    expectedDecls[2].priority = "";
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting existing property with different priority");

    block.setProperty("float", "none");
    expectedDecls.push(longhand("float", "none"));
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting non-existing property");
  }, "setProperty with longhand should update only the declaration being set");

  test(function() {
    let expectedDecls = [
      longhand("top", "1px"),
      longhand("bottom", "2px"),
      longhand("left", "3px", "important"),
      longhand("right", "4px"),
    ];
    let block = generateCSSDeclBlock(expectedDecls);
    checkDeclarationsAnyOrder(block, expectedDecls, "in initial block");

    block.top = "5px";
    expectedDecls[0] = longhand("top", "5px");
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting existing property");

    block.bottom = "2px";
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting existing property with identical value");

    block.left = "3px";
    expectedDecls[2].priority = "";
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting existing property with different priority");

    block.float = "none";
    expectedDecls.push(longhand("float", "none"));
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting non-existing property");
  }, "property setter should update only the declaration being set");

  test(function() {
    let expectedDecls = [
      ...shorthand("margin", "1px"),
      longhand("top", "2px"),
      ...shorthand("padding", "3px", "important"),
    ];
    let block = generateCSSDeclBlock(expectedDecls);
    checkDeclarationsAnyOrder(block, expectedDecls, "in initial block");

    block.setProperty("margin", "4px");
    for (let i = 0; i < 4; i++) {
      expectedDecls[i].value = "4px";
    }
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting an existing shorthand");

    block.setProperty("margin", "4px");
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting an existing shorthand with identical value");

    block.setProperty("padding", "3px");
    for (let i = 5; i < 9; i++) {
      expectedDecls[i].priority = "";
    }
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting an existing shorthand with different priority");

    block.setProperty("margin-bottom", "5px", "important");
    expectedDecls[2] = longhand("margin-bottom", "5px", "important");
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting a longhand in an existing shorthand");
  }, "setProperty with shorthand should update only the declarations being set");

  test(function() {
    let expectedDecls = [
      ...shorthand("margin", "1px"),
      longhand("top", "2px"),
      ...shorthand("padding", "3px", "important"),
    ];
    let block = generateCSSDeclBlock(expectedDecls);
    checkDeclarationsAnyOrder(block, expectedDecls, "in initial block");

    block.margin = "4px";
    for (let i = 0; i < 4; i++) {
      expectedDecls[i].value = "4px";
    }
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting an existing shorthand");

    block.margin = "4px";
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting an existing shorthand with identical value");

    block.padding = "3px";
    for (let i = 5; i < 9; i++) {
      expectedDecls[i].priority = "";
    }
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting an existing shorthand with different priority");

    block.marginBottom = "5px";
    expectedDecls[2] = longhand("margin-bottom", "5px");
    checkDeclarationsAnyOrder(block, expectedDecls, "after setting a longhand in an existing shorthand");
  }, "longhand property setter should update only the decoarations being set");
</script>
