<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/modify-css-property.css">
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function makeNarrow() {
    document.getElementById("x").style.width = "50px";
}

function makeWide() {
    document.getElementById("x").style.width = "200px";
}

function test() {
    let nodeStyles = null;
    let suite = InspectorTest.createAsyncSuite("ModifyCSSProperty");

    suite.addTestCase({
        name: "Update value when CSSStyleDeclaration is not locked",
        test(resolve, reject) {
            let getMatchedStyleDeclaration = () => {
                for (let rule of nodeStyles.matchedRules) {
                    if (rule.selectorText === ".rule-b")
                        return rule.style;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getMatchedStyleDeclaration();
                for (let property of styleDeclaration.enabledProperties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getMatchedStyleDeclaration();
            styleDeclaration.locked = false;

            styleDeclaration.singleFireEventListener(WI.CSSStyleDeclaration.Event.PropertiesChanged, function(event) {
                let fontProperty = getProperty("font-size");
                let relativeRange = fontProperty.styleSheetTextRange.relativeTo(fontProperty.ownerStyle.styleSheetTextRange.startLine, fontProperty.ownerStyle.styleSheetTextRange.startOffset);
                relativeRange.resolveOffsets(fontProperty.ownerStyle.text);
                let propertyText = fontProperty.ownerStyle.text.slice(relativeRange.startOffset, relativeRange.endOffset);
                InspectorTest.expectEqual(propertyText, "font-size: 10px;", `styleSheetTextRange should correspond to "font-size: 10px;"`);
                resolve();
            });

            getProperty("font-size").rawValue = "11px";
            getProperty("font-size").rawValue = "10px";

            InspectorTest.expectEqual(getProperty("font-size").rawValue, "10px", `"font-size" property value should update immediately.`);

            InspectorTest.expectEqual(styleDeclaration.text, `\n    font-size: 10px;\n    color: antiquewhite;\n`, `Style declaration text should update immediately.`);
        }
    });

    suite.addTestCase({
        name: "Update value when CSSStyleDeclaration is locked",
        test(resolve, reject) {
            let getMatchedStyleDeclaration = () => {
                for (let rule of nodeStyles.matchedRules) {
                    if (rule.selectorText === ".rule-a")
                        return rule.style;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getMatchedStyleDeclaration();
                for (let property of styleDeclaration.enabledProperties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getMatchedStyleDeclaration();
            styleDeclaration.locked = true;
            getProperty("font-size").rawValue = "15px";
            getProperty("font-size").rawValue = "16px";

            InspectorTest.expectEqual(getProperty("font-size").rawValue, "16px", `"font-size" property value should update immediately.`);

            InspectorTest.expectEqual(styleDeclaration.text, `
    font-size: 16px;
    color: #333;
    margin-left: 0;
    margin-top: 1em;
`, `Style declaration text should update immediately.`);

            styleDeclaration.locked = false;

            resolve();
        }
    });

    suite.addTestCase({
        name: "ModifyCSSProperty.PropertiesChangedEvent",
        test(resolve, reject) {
            let getInlineStyleDeclaration = () => {
                for (let styleDeclaration of nodeStyles.orderedStyles) {
                    if (styleDeclaration.type === styleDeclaration.constructor.Type.Inline)
                        return styleDeclaration;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getInlineStyleDeclaration();
                for (let property of styleDeclaration.properties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getInlineStyleDeclaration();

            styleDeclaration.awaitEvent(WI.CSSStyleDeclaration.Event.PropertiesChanged).then((event) => {
                InspectorTest.expectThat(!styleDeclaration.locked, `Style declaration is unlocked.`);
                InspectorTest.expectEqual(getProperty("width").rawValue, "200px", `"width" property value should update to "200px".`);
                InspectorTest.expectEqual(styleDeclaration.text, `width: 200px;`, `Inline style declaration text should update when not locked.`);
                resolve();
            });

            styleDeclaration.locked = true;
            // WI.CSSStyleDeclaration.Event.PropertiesChanged event should not fire when the style declaration is locked.
            InspectorTest.evaluateInPage(`makeNarrow()`);

            styleDeclaration.locked = false;
            InspectorTest.evaluateInPage(`makeWide()`);
        }
    });

    suite.addTestCase({
        name: "Update inline style value when CSSStyleDeclaration locked and not locked",
        test(resolve, reject) {
            let getInlineStyleDeclaration = () => {
                for (let styleDeclaration of nodeStyles.orderedStyles) {
                    if (styleDeclaration.type === styleDeclaration.constructor.Type.Inline)
                        return styleDeclaration;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getInlineStyleDeclaration();
                for (let property of styleDeclaration.enabledProperties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getInlineStyleDeclaration();

            WI.CSSStyleDeclaration.awaitEvent(WI.CSSStyleDeclaration.Event.PropertiesChanged).then((event) => {
                InspectorTest.expectThat(!styleDeclaration.locked, `Style declaration is unlocked.`);
                InspectorTest.expectEqual(getProperty("width").rawValue, "128px", `"width" property value should update to "128px".`);
                InspectorTest.expectEqual(styleDeclaration.text, `width: 128px;`, `Inline style declaration text should update when not locked.`);
                resolve();
            });

            styleDeclaration.locked = true;
            getProperty("width").rawValue = "64px";
            InspectorTest.expectEqual(styleDeclaration.text, `width: 64px;`, `Style declaration text should update immediately.`);

            // WI.CSSStyleDeclaration.Event.PropertiesChanged event should not fire when the style declaration is locked.
            InspectorTest.evaluateInPage(`makeNarrow()`);

            styleDeclaration.locked = false;
            getProperty("width").rawValue = "128px";
            InspectorTest.expectEqual(styleDeclaration.text, `width: 128px;`, `Style declaration text should update immediately.`);

            InspectorTest.evaluateInPage(`makeWide()`);
        }
    });

    suite.addTestCase({
        name: "ModifyCSSProperty.ConsequentValueChanges",
        test(resolve, reject) {
            let getInlineStyleDeclaration = () => {
                for (let styleDeclaration of nodeStyles.orderedStyles) {
                    if (styleDeclaration.type === styleDeclaration.constructor.Type.Inline)
                        return styleDeclaration;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getInlineStyleDeclaration();
                for (let property of styleDeclaration.properties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getInlineStyleDeclaration();
            styleDeclaration.locked = false;

            for (let i = 0; i <= 20; ++i)
                getProperty("width").rawValue = i + "px";

            InspectorTest.expectEqual(styleDeclaration.text, `width: 20px;`, `Style declaration text should contain most recent value.`);

            resolve();
        }
    });

    suite.addTestCase({
        name: "ModifyCSSProperty.CommentOutAndUncommentPropertyWithNewlines",
        test(resolve, reject) {
            let getMatchedStyleDeclaration = () => {
                for (let rule of nodeStyles.matchedRules) {
                    if (rule.selectorText === ".rule-c")
                        return rule.style;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getMatchedStyleDeclaration();
                for (let property of styleDeclaration.properties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getMatchedStyleDeclaration();
            styleDeclaration.locked = true;

            InspectorTest.expectThat(!getProperty("padding-right").enabled, `Commented out property should be disabled.`);

            let disabled = false;
            getProperty("padding-right").commentOut(disabled);

            let expectedStyleText = `\n    /* padding-left: 2em; */\n    padding-right: 0px;\n`;
            InspectorTest.expectEqual(styleDeclaration.text, expectedStyleText, `Style declaration text should update immediately with uncommented property.`);

            InspectorTest.expectThat(getProperty("padding-right").enabled, `Uncommented property should be enabled.`);

            disabled = true;
            getProperty("padding-right").commentOut(disabled);

            expectedStyleText = `\n    /* padding-left: 2em; */\n    /* padding-right: 0px; */\n`;
            InspectorTest.expectEqual(styleDeclaration.text, expectedStyleText, `Style declaration text should update immediately with commented out property.`);

            InspectorTest.expectThat(!getProperty("padding-right").enabled, `Commented out property should be disabled.`);

            resolve();
        }
    });

    suite.addTestCase({
        name: "ModifyCSSProperty.CommentOutAndUncommentPropertyWithoutNewlines",
        test(resolve, reject) {
            let getMatchedStyleDeclaration = () => {
                for (let rule of nodeStyles.matchedRules) {
                    if (rule.selectorText === ".rule-d")
                        return rule.style;
                }
                InspectorTest.fail("No declaration found.");
                resolve();
            };

            let getProperty = (propertyName) => {
                let styleDeclaration = getMatchedStyleDeclaration();
                for (let property of styleDeclaration.properties) {
                    if (property.name === propertyName)
                        return property;
                }
                InspectorTest.fail("No property found.");
                resolve();
            };

            let styleDeclaration = getMatchedStyleDeclaration();
            styleDeclaration.locked = true;

            InspectorTest.expectThat(!getProperty("font-size").enabled, `Commented out property should be disabled.`);

            let disabled = false;
            getProperty("font-size").commentOut(disabled);

            let expectedStyleText = `\n    font-size: 13px;\n    /* border: 2px solid brown; */\n`;
            InspectorTest.expectEqual(styleDeclaration.text, expectedStyleText, `Style declaration text should update immediately with uncommented property.`);

            InspectorTest.expectThat(getProperty("font-size").enabled, `Uncommented property should be enabled.`);
            InspectorTest.expectThat(!getProperty("border").enabled, `Commented out property should be disabled.`);

            disabled = false;
            getProperty("border").commentOut(disabled);

            expectedStyleText = `\n    font-size: 13px;\n    border: 2px solid brown\n`;
            InspectorTest.expectEqual(styleDeclaration.text, expectedStyleText, `Style declaration text should update immediately with commented out property.`);

            InspectorTest.expectThat(getProperty("border").enabled, `Uncommented property should be enabled.`);

            resolve();
        }
    });

    suite.addTestCase({
        name: "ModifyCSSProperty.ReplacePropertyName",
        async test() {
            let getMatchedStyleDeclaration = () => {
                for (let rule of nodeStyles.matchedRules) {
                    if (rule.selectorText === ".rule-e")
                        return rule.style;
                }
                throw "No declaration found.";
            };
            let getProperty = (propertyName) => {
                let styleDeclaration = getMatchedStyleDeclaration();
                for (let property of styleDeclaration.properties) {
                    if (property.name === propertyName)
                        return property;
                }
                throw "No property found.";
            };
            let styleDeclaration = getMatchedStyleDeclaration();

            let cssProperty = getProperty("color");
            cssProperty.name = "";
            InspectorTest.expectEqual(styleDeclaration.text, "", "Style declaration text should be empty.");

            cssProperty.name = "border-color";
            InspectorTest.expectEqual(styleDeclaration.text, `\n    border-color: darkseagreen;\n`, "Style declaration text should have new property name.");
        }
    });

    function addTestCase({name, description, selector, authoredRulesHandler})
    {
        suite.addTestCase({
            name,
            description,
            async test() {
                let documentNode = await WI.domManager.requestDocument();
                let nodeId = await documentNode.querySelector(selector);
                let domNode = WI.domManager.nodeForId(nodeId);
                InspectorTest.assert(domNode, `Should find DOM Node for selector '#item'.`);

                let domNodeStyles = WI.cssManager.stylesForNode(domNode);
                InspectorTest.assert(domNodeStyles, `Should find CSS Styles for DOM Node.`);
                await domNodeStyles.refresh();

                let flatInheritedRules = domNodeStyles.inheritedRules.flatMap((inheritedRuleInfo) => inheritedRuleInfo.matchedRules);

                let authoredRules = [...domNodeStyles.matchedRules, ...flatInheritedRules].filter((rule) => rule.type === WI.CSSStyleSheet.Type.Author);
                await authoredRulesHandler(authoredRules, domNodeStyles);
            },
        });
    }

    function findRuleStyleInRules(rules, {selector, nestingRootSelector}) {
        for (let rule of rules) {
            if (rule.selectorText !== selector)
                continue;

            if (!nestingRootSelector)
                return rule.style;

            for (let grouping of rule.groupings) {
                if (grouping.type !== WI.CSSGrouping.Type.StyleRule)
                    continue;

                if (grouping.text !== nestingRootSelector)
                    continue;

                return rule.style;
            }
        }
        InspectorTest.fail(`No rule found with selector "${selector}" nested under selector "${nestingRootSelector}".`);
    }

    function getColorProperty(styleDeclaration) {
        for (let property of styleDeclaration.properties) {
            if (property.name === "color")
                return property;
        }
        InspectorTest.fail("No color property found in style declaration.");
    }

    addTestCase({
        name: "ModifyCSSProperty.EnsureNestedRulesEditingDoesNotTrampleInnerRules",
        description: "",
        selector: ".rule-f",
        async authoredRulesHandler(authoredRules, domNodeStyles) {
            let outerRuleStyle = findRuleStyleInRules(authoredRules, { selector: ".rule-f" });
            InspectorTest.expectEqual(outerRuleStyle.text, "\n    color: red;\n\n    @media(min-width: 0px) {\n        &.explicit-nested-rule { \n            color: blue;\n        }\n\n        color: green;\n    }\n", "Outer style declaration text should contain the expected `color` property.");
            let outerRuleStyleChangedPromise = domNodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
            getColorProperty(outerRuleStyle).rawValue = "magenta";
            await outerRuleStyleChangedPromise;
            InspectorTest.expectEqual(outerRuleStyle.text, "\n    color: magenta;\n\n    @media(min-width: 0px) {\n        &.explicit-nested-rule { \n            color: blue;\n        }\n\n        color: green;\n    }\n\n", "Outer style declaration text should contain the new `color` value.");

            let innerImplicitRuleStyle = findRuleStyleInRules(authoredRules, { selector: "&", nestingRootSelector: ".rule-f" });
            InspectorTest.expectEqual(innerImplicitRuleStyle.text, "\n        &.explicit-nested-rule { \n            color: blue;\n        }\n\n        color: green;\n    ", "Inner implicit style declaration text should contain the expected `color` property.");
            let innerImplicitRuleStyleChangedPromise = domNodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
            getColorProperty(innerImplicitRuleStyle).rawValue = "yellow";
            await innerImplicitRuleStyleChangedPromise;
            InspectorTest.expectEqual(innerImplicitRuleStyle.text, "\n            color: yellow;\n        \n            &.explicit-nested-rule { \n            color: blue;\n        }\n\n        ", "Inner implicit style declaration text should contain the new `color` value.");

            let innerExplicitRuleStyle = findRuleStyleInRules(authoredRules,  { selector: "&.explicit-nested-rule", nestingRootSelector: ".rule-f" });
            InspectorTest.expectEqual(innerExplicitRuleStyle.text, " \n            color: blue;\n        ", "Inner explicit style declaration text should contain the expected `color` property.");
            let innerExplicitRuleStyleChangedPromise = domNodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
            getColorProperty(innerExplicitRuleStyle).rawValue = "cyan";
            await innerExplicitRuleStyleChangedPromise;
            InspectorTest.expectEqual(innerExplicitRuleStyle.text, "\n            color: cyan;\n        \n        ", "Inner explicit style declaration text should contain the new `color` value.");
        },
    })

    addTestCase({
        name: "ModifyCSSProperty.EnsureNestedRulesEditingDoesNotTrampleInnerRulesOriginalExcludesNewlines",
        description: "",
        selector: ".rule-g",
        async authoredRulesHandler(authoredRules, domNodeStyles) {
            let outerRuleStyle = findRuleStyleInRules(authoredRules, { selector: ".rule-g" });
            InspectorTest.expectEqual(outerRuleStyle.text, " color: red; @media(min-width: 0px) { &.explicit-nested-rule { color: blue; } color: green; } ", "Outer style declaration text should contain the expected `color` property.");
            let outerRuleStyleChangedPromise = domNodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
            getColorProperty(outerRuleStyle).rawValue = "magenta";
            await outerRuleStyleChangedPromise;
            InspectorTest.expectEqual(outerRuleStyle.text, "\n    color: magenta;\n\n    @media(min-width: 0px) { &.explicit-nested-rule { color: blue; } color: green; }\n\n", "Outer style declaration text should contain the new `color` value.");

            let innerImplicitRuleStyle = findRuleStyleInRules(authoredRules, { selector: "&", nestingRootSelector: ".rule-g" });
            InspectorTest.expectEqual(innerImplicitRuleStyle.text, " &.explicit-nested-rule { color: blue; } color: green; ", "Inner implicit style declaration text should contain the expected `color` property.");
            let innerImplicitRuleStyleChangedPromise = domNodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
            getColorProperty(innerImplicitRuleStyle).rawValue = "yellow";
            await innerImplicitRuleStyleChangedPromise;
            InspectorTest.expectEqual(innerImplicitRuleStyle.text, "\n            color: yellow;\n        \n            &.explicit-nested-rule { color: blue; }\n\n        ", "Inner implicit style declaration text should contain the new `color` value.");

            let innerExplicitRuleStyle = findRuleStyleInRules(authoredRules,  { selector: "&.explicit-nested-rule", nestingRootSelector: ".rule-g" });
            InspectorTest.expectEqual(innerExplicitRuleStyle.text, " color: blue; ", "Inner explicit style declaration text should contain the expected `color` property.");
            let innerExplicitRuleStyleChangedPromise = domNodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
            getColorProperty(innerExplicitRuleStyle).rawValue = "cyan";
            await innerExplicitRuleStyleChangedPromise;
            InspectorTest.expectEqual(innerExplicitRuleStyle.text, "\n            color: cyan;\n        \n        ", "Inner explicit style declaration text should contain the new `color` value.");
        },
    })

    WI.domManager.requestDocument((documentNode) => {
        documentNode.querySelector("#x", (contentNodeId) => {
            if (contentNodeId) {
                let domNode = WI.domManager.nodeForId(contentNodeId);
                nodeStyles = WI.cssManager.stylesForNode(domNode);

                let flatInheritedRules = nodeStyles.inheritedRules.flatMap((inheritedRuleInfo) => inheritedRuleInfo.matchedRules);
                authoredRules = [...nodeStyles.matchedRules, ...flatInheritedRules].filter((rule) => rule.type === WI.CSSStyleSheet.Type.Author);

                if (nodeStyles.needsRefresh) {
                    nodeStyles.singleFireEventListener(WI.DOMNodeStyles.Event.Refreshed, (event) => {
                        suite.runTestCasesAndFinish()
                    });
                } else
                    suite.runTestCasesAndFinish();
            } else {
                InspectorTest.fail("DOM node not found.");
                InspectorTest.completeTest();
            }
        });
    });
}
</script>
</head>
<body onload="runTest()">
    <p>Testing that CSSStyleDeclaration update immediately after modifying its properties when it is not locked.</p>
    <div id="x" class="test-node rule-a rule-b rule-c rule-d rule-e rule-f rule-g explicit-nested-rule" style="width: 100px"></div>
</body>
</html>
