Title: [241189] trunk
Revision
241189
Author
[email protected]
Date
2019-02-07 22:51:52 -0800 (Thu, 07 Feb 2019)

Log Message

PseudoElement created for any ::before/::after selector regardless of whether a content property exists
https://bugs.webkit.org/show_bug.cgi?id=194423
<rdar://problem/46787260>

Reviewed by Antti Koivisto.

Source/WebCore:

Test: inspector/css/pseudo-creation.html

* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolvePseudoStyle):
We should only be creating `PseudoElement`s if we actually have a `content` proprety in the
`PseudoElement`'s style. Otherwise, we end up creating `PseudoElement`s for every CSS rule
that has a `::before`/`::after`, only to immediately destroy them as there is nothing to show.

LayoutTests:

* inspector/css/pseudo-creation.html: Added.
* inspector/css/pseudo-creation-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (241188 => 241189)


--- trunk/LayoutTests/ChangeLog	2019-02-08 06:39:38 UTC (rev 241188)
+++ trunk/LayoutTests/ChangeLog	2019-02-08 06:51:52 UTC (rev 241189)
@@ -1,3 +1,14 @@
+2019-02-07  Devin Rousso  <[email protected]>
+
+        PseudoElement created for any ::before/::after selector regardless of whether a content property exists
+        https://bugs.webkit.org/show_bug.cgi?id=194423
+        <rdar://problem/46787260>
+
+        Reviewed by Antti Koivisto.
+
+        * inspector/css/pseudo-creation.html: Added.
+        * inspector/css/pseudo-creation-expected.txt: Added.
+
 2019-02-07  Justin Fan  <[email protected]>
 
         [Web GPU] GPUDevice::createTexture implementation prototype

Added: trunk/LayoutTests/inspector/css/pseudo-creation-expected.txt (0 => 241189)


--- trunk/LayoutTests/inspector/css/pseudo-creation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/css/pseudo-creation-expected.txt	2019-02-08 06:51:52 UTC (rev 241189)
@@ -0,0 +1,22 @@
+Testing when CSS.events.pseudoElementCreated and CSS.events.pseudoElementDestroyed are fired.
+
+Requesting document...
+
+Calling "createElementWithClass("test-pseudo-without-content")"...
+Checking for nodes with class ".test-pseudo-without-content"...
+PASS: There should be 1 node with the class ".test-pseudo-without-content".
+
+Calling "removeElementWithClass("test-pseudo-without-content")"...
+Checking for nodes with class ".test-pseudo-without-content"...
+PASS: There should be 0 node with the class ".test-pseudo-without-content".
+
+Calling "createElementWithClass("test-pseudo-with-content")"...
+Checking for nodes with class ".test-pseudo-with-content"...
+PASS: Created ::before pseudo element
+PASS: There should be 1 node with the class ".test-pseudo-with-content".
+
+Calling "removeElementWithClass("test-pseudo-with-content")"...
+Checking for nodes with class ".test-pseudo-with-content"...
+PASS: Removed ::before pseudo element
+PASS: There should be 0 node with the class ".test-pseudo-with-content".
+

Added: trunk/LayoutTests/inspector/css/pseudo-creation.html (0 => 241189)


--- trunk/LayoutTests/inspector/css/pseudo-creation.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/css/pseudo-creation.html	2019-02-08 06:51:52 UTC (rev 241189)
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+.test-pseudo-without-content::before {
+    color: red;
+}
+.test-pseudo-with-content::before {
+    content: "TEST";
+}
+</style>
+<script>
+
+function createElementWithClass(className) {
+    let element = document.body.appendChild(document.createElement("div"));
+    element.classList.add(className);
+}
+
+function removeElementWithClass(className) {
+    let element = document.querySelector(`.${className}`);
+    element.classList.remove(className);
+
+    // Don't remove the element, as that removes the entire subtree rather than just the pseudo element.
+}
+
+function test() {
+    ProtocolTest.debug();
+
+    let documentNode = null;
+    let pseudoElement = null;
+
+    function handlePromiseReject(error) {
+        console.log(error);
+        ProtocolTest.log(error);
+        ProtocolTest.completeTest();
+    }
+
+    function evaluateWithLog(_expression_) {
+        ProtocolTest.log("");
+        ProtocolTest.log(`Calling "${_expression_}"...`);
+        return ProtocolTest.evaluateInPage(_expression_)
+        .catch(handlePromiseReject);
+    }
+
+    function checkElementsWithClass(className, expectedCount) {
+        ProtocolTest.log(`Checking for nodes with class ".${className}"...`);
+        return InspectorProtocol.awaitCommand({
+            method: "DOM.querySelectorAll",
+            params: {
+                nodeId: documentNode.nodeId,
+                selector: `.${className}`,
+            },
+        })
+        .then((result) => {
+            ProtocolTest.expectEqual(result.nodeIds.length, expectedCount, `There should be ${expectedCount} node with the class ".${className}".`);
+        })
+        .catch(handlePromiseReject);
+    }
+
+    function createElementWithClass(className) {
+        return evaluateWithLog(`createElementWithClass("${className}")`)
+        .then(() => checkElementsWithClass(className, 1))
+        .catch(handlePromiseReject);
+    }
+
+    function removeElementWithClass(className) {
+        return evaluateWithLog(`removeElementWithClass("${className}")`)
+        .then(() => checkElementsWithClass(className, 0))
+        .catch(handlePromiseReject);
+    }
+
+    InspectorProtocol.eventHandler["DOM.pseudoElementAdded"] = (response) => {
+        pseudoElement = response.params.pseudoElement;
+
+        ProtocolTest.pass(`Created ::${pseudoElement.pseudoType} pseudo element`);
+    };
+
+    InspectorProtocol.eventHandler["DOM.pseudoElementRemoved"] = (response) => {
+        ProtocolTest.expectEqual(response.params.pseudoElementId, pseudoElement.nodeId, `Removed ::${pseudoElement.pseudoType} pseudo element`);
+    };
+
+    ProtocolTest.log("Requesting document...");
+    InspectorProtocol.sendCommand("DOM.getDocument", {}, (response) => {
+        InspectorProtocol.checkForError(response);
+
+        documentNode = response.result.root;
+
+        Promise.resolve()
+        .then(() => createElementWithClass("test-pseudo-without-content"))
+        .then(() => removeElementWithClass("test-pseudo-without-content"))
+        .then(() => createElementWithClass("test-pseudo-with-content"))
+        .then(() => removeElementWithClass("test-pseudo-with-content"))
+        .then(() => ProtocolTest.completeTest())
+        .catch(handlePromiseReject);
+    });
+}
+
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Testing when CSS.events.pseudoElementCreated and CSS.events.pseudoElementDestroyed are fired.</p>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (241188 => 241189)


--- trunk/Source/WebCore/ChangeLog	2019-02-08 06:39:38 UTC (rev 241188)
+++ trunk/Source/WebCore/ChangeLog	2019-02-08 06:51:52 UTC (rev 241189)
@@ -1,3 +1,19 @@
+2019-02-07  Devin Rousso  <[email protected]>
+
+        PseudoElement created for any ::before/::after selector regardless of whether a content property exists
+        https://bugs.webkit.org/show_bug.cgi?id=194423
+        <rdar://problem/46787260>
+
+        Reviewed by Antti Koivisto.
+
+        Test: inspector/css/pseudo-creation.html
+
+        * style/StyleTreeResolver.cpp:
+        (WebCore::Style::TreeResolver::resolvePseudoStyle):
+        We should only be creating `PseudoElement`s if we actually have a `content` proprety in the
+        `PseudoElement`'s style. Otherwise, we end up creating `PseudoElement`s for every CSS rule
+        that has a `::before`/`::after`, only to immediately destroy them as there is nothing to show.
+
 2019-02-07  Chris Dumez  <[email protected]>
 
         Mark more heap-allocated classes as fast allocated

Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (241188 => 241189)


--- trunk/Source/WebCore/style/StyleTreeResolver.cpp	2019-02-08 06:39:38 UTC (rev 241188)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp	2019-02-08 06:51:52 UTC (rev 241189)
@@ -43,6 +43,7 @@
 #include "Page.h"
 #include "PlatformStrategies.h"
 #include "RenderElement.h"
+#include "RenderStyle.h"
 #include "RenderView.h"
 #include "RuntimeEnabledFeatures.h"
 #include "Settings.h"
@@ -252,7 +253,7 @@
         return { };
 
     auto pseudoStyle = scope().styleResolver.pseudoStyleForElement(element, { pseudoId }, *elementUpdate.style, &scope().selectorFilter);
-    if (!pseudoStyle)
+    if (!pseudoElementRendererIsNeeded(pseudoStyle.get()))
         return { };
 
     PseudoElement* pseudoElement = pseudoId == PseudoId::Before ? element.beforePseudoElement() : element.afterPseudoElement();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to