<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test() {
    let suite = InspectorTest.createAsyncSuite("OverriddenProperty");

    function logProperty(property) {
        let text = property.formattedText || "REMOVED";
        if (property.overridden)
            text += " overridden";
        InspectorTest.log(text);
    }

    function getNodeStyles(selector, callback) {
        WI.domManager.requestDocument((documentNode) => {
            documentNode.querySelector(selector, (contentNodeId) => {
                if (!contentNodeId) {
                    InspectorTest.fail("DOM node not found.");
                    InspectorTest.completeTest();
                    return;
                }

                let domNode = WI.domManager.nodeForId(contentNodeId);
                let nodeStyles = WI.cssManager.stylesForNode(domNode);

                if (nodeStyles.needsRefresh) {
                    nodeStyles.singleFireEventListener(WI.DOMNodeStyles.Event.Refreshed, (event) => {
                        callback(nodeStyles);
                    });
                } else
                    callback(nodeStyles);
            });
        });
    }

    function getStyleDeclaration(selector, callback, resolve) {
        getNodeStyles(selector, (nodeStyles) => {
            let matchedRule = null;
            for (let rule of nodeStyles.matchedRules) {
                if (rule.selectorText === selector) {
                    matchedRule = rule;
                    break;
                }
            }

            if (!matchedRule) {
                InspectorTest.fail(`Couldn't find ${selector}`);
                resolve();
                return;
            }

            callback(matchedRule.style)
        });
    }

    suite.addTestCase({
        name: "OverriddenProperty.effectivePropertyRemoved",
        description: "Test that CSSProperty.prototype.overridden is cleared when the overriding (effective) property is removed.",
        test(resolve, reject) {
            getNodeStyles("#x", (nodeStyles) => {
                let inlineStyle = nodeStyles.inlineStyle;
                let styleRule = nodeStyles.matchedRules[0];
                let inlineStyleProperty = inlineStyle.enabledProperties[0];
                let styleRuleProperty = styleRule.style.enabledProperties[0];

                function log() {
                    logProperty(inlineStyleProperty);
                    logProperty(styleRuleProperty);
                    InspectorTest.log("");
                }

                log();

                inlineStyleProperty.remove();

                styleRuleProperty.addEventListener(WI.CSSProperty.Event.OverriddenStatusChanged, (event) => {
                    // FIXME: <https://webkit.org/b/195651> OverriddenStatusChanged may fire more than once.
                    if (styleRuleProperty.overridden)
                        return;

                    InspectorTest.log("OverriddenStatusChanged event fired.");
                    log();
                    resolve();
                });
            });
        }
    });

    suite.addTestCase({
        name: "OverriddenProperty.OverriddenByShorthand",
        test(resolve, reject) {
            getStyleDeclaration(".longhand-overridden-by-shorthand", (style) => {
                const dontCreateIfMissing = true;
                let borderTopColorProperty = style.propertyForName("border-top-color", dontCreateIfMissing);
                InspectorTest.expectTrue(borderTopColorProperty.overridden, "border-top-color is overridden.");

                let borderColorProperty = style.propertyForName("border-color", dontCreateIfMissing);
                InspectorTest.expectFalse(borderColorProperty.overridden, "border-color is NOT overridden.");

                resolve();
            }, reject);
        }
    });

    suite.addTestCase({
        name: "OverriddenProperty.OverriddenByImportantShorthand",
        test(resolve, reject) {
            getStyleDeclaration(".longhand-overridden-by-important-shorthand", (style) => {
                const dontCreateIfMissing = true;
                let borderColorProperty = style.propertyForName("border-color", dontCreateIfMissing);
                InspectorTest.expectFalse(borderColorProperty.overridden, "border-color is NOT overridden.");

                let borderTopColorProperty = style.propertyForName("border-top-color", dontCreateIfMissing);
                InspectorTest.expectTrue(borderTopColorProperty.overridden, "border-top-color is overridden.");

                resolve();
            }, reject);
        }
    });

    suite.addTestCase({
        name: "OverriddenProperty.NotOverriddenByImportantLonghand",
        test(resolve, reject) {
            getStyleDeclaration(".shorthand-overridden-by-important-longhand", (style) => {
                const dontCreateIfMissing = true;
                let borderTopColorProperty = style.propertyForName("border-top-color", dontCreateIfMissing);
                InspectorTest.expectFalse(borderTopColorProperty.overridden, "border-top-color is NOT overridden.");

                let borderColorProperty = style.propertyForName("border-color", dontCreateIfMissing);
                InspectorTest.expectFalse(borderColorProperty.overridden, "border-color is NOT overridden.");

                resolve();
            }, reject);
        }
    });

    suite.addTestCase({
        name: "OverriddenProperty.NotOverriddenByLonghand",
        test(resolve, reject) {
            getStyleDeclaration(".shorthand-not-overridden-by-longhand", (style) => {
                const dontCreateIfMissing = true;
                let borderColorProperty = style.propertyForName("border-color", dontCreateIfMissing);
                InspectorTest.expectFalse(borderColorProperty.overridden, "border-color is NOT overridden.");

                let borderTopColorProperty = style.propertyForName("border-top-color", dontCreateIfMissing);
                InspectorTest.expectFalse(borderTopColorProperty.overridden, "border-top-color is NOT overridden.");

                resolve();
            }, reject);
        }
    });

    suite.addTestCase({
        name: "OverriddenProperty.MixedCaseVariablesNotOverridden",
        test(resolve, reject) {
            getStyleDeclaration(".mixed-case-variables-not-overridden", (style) => {
                const dontCreateIfMissing = true;
                let lowercaseVariableProperty = style.propertyForName("--foo", dontCreateIfMissing);
                InspectorTest.expectFalse(lowercaseVariableProperty.overridden, "`--foo` is NOT overridden.");

                let uppercaseVariableProperty = style.propertyForName("--FOO", dontCreateIfMissing);
                InspectorTest.expectFalse(uppercaseVariableProperty.overridden, "`--FOO` is NOT overridden.");

                resolve();
            }, reject);
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p>Test that CSSProperty.prototype.overridden is set correctly.</p>
    <style>
    #x {
        color: red;
    }

    .longhand-overridden-by-shorthand {
        border-top-color: red;
        border-color: green;
    }

    .longhand-overridden-by-important-shorthand {
        border-color: green !important;
        border-top-color: red;
    }

    .shorthand-overridden-by-important-longhand {
        border-top-color: red !important;
        border-color: green;
    }

    .shorthand-not-overridden-by-longhand {
        border-color: green;
        border-top-color: red;
    }

    .mixed-case-variables-not-overridden {
        --foo: green;
        --FOO: red;
    }
    </style>
    <div id="x" style="color: green"></div>
    <div class="longhand-overridden-by-shorthand"></div>
    <div class="longhand-overridden-by-important-shorthand"></div>
    <div class="shorthand-overridden-by-important-longhand"></div>
    <div class="shorthand-not-overridden-by-longhand"></div>
    <div class="mixed-case-variables-not-overridden"></div>
</body>
</html>
