<!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.");
        }
    });

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

                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" style="width: 100px"></div>
</body>
</html>
