Diff
Modified: trunk/LayoutTests/ChangeLog (189001 => 189002)
--- trunk/LayoutTests/ChangeLog 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/LayoutTests/ChangeLog 2015-08-26 23:48:49 UTC (rev 189002)
@@ -1,3 +1,23 @@
+2015-08-26 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Implement tracking of active stylesheets in the frontend
+ https://bugs.webkit.org/show_bug.cgi?id=105828
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/css/resources/import-level-1.css: Added.
+ * inspector/css/resources/import-level-2.css: Added.
+ * inspector/css/resources/stylesheet-events-subframe.html: Added.
+ * inspector/css/stylesheet-events-basic-expected.txt: Added.
+ * inspector/css/stylesheet-events-basic.html: Added.
+ * inspector/css/stylesheet-events-imports-expected.txt: Added.
+ * inspector/css/stylesheet-events-imports.html: Added.
+ * inspector/css/stylesheet-events-inspector-stylesheet-expected.txt: Added.
+ * inspector/css/stylesheet-events-inspector-stylesheet.html: Added.
+ * inspector/css/stylesheet-events-multiple-documents-expected.txt: Added.
+ * inspector/css/stylesheet-events-multiple-documents.html: Added.
+ Tests for different ways that StyleSheets can be added / removed.
+
2015-08-26 Andy Estes <aes...@apple.com>
Crash when following a Google search link to Twitter with Limit Adult Content enabled
Added: trunk/LayoutTests/inspector/css/resources/import-level-1.css (0 => 189002)
--- trunk/LayoutTests/inspector/css/resources/import-level-1.css (rev 0)
+++ trunk/LayoutTests/inspector/css/resources/import-level-1.css 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,2 @@
+@import url(import-level-2.css);
+body { color: #abc; }
Added: trunk/LayoutTests/inspector/css/resources/import-level-2.css (0 => 189002)
--- trunk/LayoutTests/inspector/css/resources/import-level-2.css (rev 0)
+++ trunk/LayoutTests/inspector/css/resources/import-level-2.css 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1 @@
+body { color: #def; }
Added: trunk/LayoutTests/inspector/css/resources/stylesheet-events-subframe.html (0 => 189002)
--- trunk/LayoutTests/inspector/css/resources/stylesheet-events-subframe.html (rev 0)
+++ trunk/LayoutTests/inspector/css/resources/stylesheet-events-subframe.html 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1 @@
+<link rel="stylesheet" href=""
Added: trunk/LayoutTests/inspector/css/stylesheet-events-basic-expected.txt (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-basic-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-basic-expected.txt 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,39 @@
+Test for CSS.styleSheetAdded and CSS.styleSheetRemoved events.
+
+
+== Running test suite: CSS.StyleSheetEvents.Basic
+-- Running test case: CheckNoStyleSheets
+PASS: Should be no stylesheets.
+
+-- Running test case: AddStyleTag
+PASS: StyleSheetAdded event should fire.
+
+-- Running test case: DisableStyleTag
+PASS: StyleSheetRemoved event should fire for the same CSSStyleSheet.
+
+-- Running test case: EnableStyleTag
+PASS: StyleSheetAdded event should fire with a new CSSStyleSheet.
+
+-- Running test case: RemoveStyleTag
+PASS: StyleSheetAdded event should fire.
+
+-- Running test case: AddExternalStyleSheet
+PASS: StyleSheetAdded event should fire.
+Added StyleSheet with URL: inspector/css/resources/external.css
+
+-- Running test case: DisableExternalStyleSheet
+PASS: StyleSheetRemoved event should fire for the same CSSStyleSheet.
+
+-- Running test case: EnableExternalStyleSheet
+PASS: StyleSheetAdded event should fire with a new CSSStyleSheet.
+
+-- Running test case: DisableExternalStyleSheetViaMediaAttribute
+PASS: StyleSheetRemoved event should fire for the same CSSStyleSheet.
+
+-- Running test case: EnableExternalStyleSheetViaMediaAttribute
+PASS: StyleSheetAdded event should fire with a new CSSStyleSheet.
+
+-- Running test case: RemoveExternalStyleSheet
+PASS: StyleSheetAdded event should fire.
+Removed StyleSheet with URL: inspector/css/resources/external.css
+
Added: trunk/LayoutTests/inspector/css/stylesheet-events-basic.html (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-basic.html (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-basic.html 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function addExternalStyleSheet() {
+ let link = document.createElement("link");
+ link.id = "externalStyleSheetId";
+ link.rel = "stylesheet";
+ link.href = ""
+ document.head.appendChild(link);
+}
+
+function removeExternalStyleSheet() {
+ document.getElementById("externalStyleSheetId").remove();
+}
+
+function disableExternalStyleSheetViaMediaAttribute() {
+ document.getElementById("externalStyleSheetId").media = "print";
+}
+
+function enableExternalStyleSheetViaMediaAttribute() {
+ document.getElementById("externalStyleSheetId").media = "screen";
+}
+
+function addStyleTag() {
+ let style = document.createElement("style");
+ style.id = "inlineStyleId";
+ style.textContent = "body { color: red; }";
+ document.body.appendChild(style);
+}
+
+function removeStyleTag() {
+ document.getElementById("inlineStyleId").remove();
+}
+
+function disableStyleSheet() {
+ document.styleSheets[0].disabled = true;
+}
+
+function enableStyleSheet() {
+ document.styleSheets[0].disabled = false;
+}
+
+function test()
+{
+ function sanitizeURL(url) {
+ return url.replace(/^.*?LayoutTests\//, "");
+ }
+
+ let suite = InspectorTest.createAsyncSuite("CSS.StyleSheetEvents.Basic");
+
+ suite.addTestCase({
+ name: "CheckNoStyleSheets",
+ description: "Ensure there are currently no stylesheets.",
+ test: (resolve, reject) => {
+ InspectorTest.expectThat(WebInspector.cssStyleManager.styleSheets.length === 0, "Should be no stylesheets.");
+ resolve();
+ }
+ });
+
+ function appendStyleSheetTests(args) {
+ let {title, addExpression, removeExpression, checkStyleSheetAddedCallback, checkStyleSheetRemovedCallback, extraEnableDisableTests} = args;
+
+ let addedStyleSheet;
+
+ suite.addTestCase({
+ name: `Add${title}`,
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage(addExpression);
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, function(event) {
+ addedStyleSheet = event.data.styleSheet;
+ InspectorTest.expectThat(addedStyleSheet instanceof WebInspector.CSSStyleSheet, "StyleSheetAdded event should fire.");
+ if (checkStyleSheetRemovedCallback)
+ checkStyleSheetAddedCallback(addedStyleSheet);
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: `Disable${title}`,
+ description: "Disable the newly added stylesheet.",
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage("disableStyleSheet()");
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, function(event) {
+ InspectorTest.assert(event.data.styleSheet instanceof WebInspector.CSSStyleSheet, "Event data should be a CSSStyleSheet");
+ InspectorTest.expectThat(addedStyleSheet === event.data.styleSheet, "StyleSheetRemoved event should fire for the same CSSStyleSheet.");
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: `Enable${title}`,
+ description: "Enable the just disabled stylesheet.",
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage("enableStyleSheet()");
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, function(event) {
+ InspectorTest.assert(event.data.styleSheet instanceof WebInspector.CSSStyleSheet, "Event data should be a CSSStyleSheet");
+ InspectorTest.expectThat(addedStyleSheet !== event.data.styleSheet, "StyleSheetAdded event should fire with a new CSSStyleSheet.");
+ addedStyleSheet = event.data.styleSheet;
+ resolve();
+ });
+ }
+ });
+
+ if (extraEnableDisableTests) {
+ let {title: extraDisableTitle, _expression_: extraDisableExpression} = extraEnableDisableTests.shift();
+ let {title: extraEnableTitle, _expression_: extraEnableExpression} = extraEnableDisableTests.shift();
+
+ suite.addTestCase({
+ name: extraDisableTitle,
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage(extraDisableExpression);
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, function(event) {
+ InspectorTest.assert(event.data.styleSheet instanceof WebInspector.CSSStyleSheet, "Event data should be a CSSStyleSheet");
+ InspectorTest.expectThat(addedStyleSheet === event.data.styleSheet, "StyleSheetRemoved event should fire for the same CSSStyleSheet.");
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: extraEnableTitle,
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage(extraEnableExpression);
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, function(event) {
+ InspectorTest.assert(event.data.styleSheet instanceof WebInspector.CSSStyleSheet, "Event data should be a CSSStyleSheet");
+ InspectorTest.expectThat(addedStyleSheet !== event.data.styleSheet, "StyleSheetAdded event should fire with a new CSSStyleSheet.");
+ addedStyleSheet = event.data.styleSheet;
+ resolve();
+ });
+ }
+ });
+ }
+
+ suite.addTestCase({
+ name: `Remove${title}`,
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage(removeExpression);
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, function(event) {
+ InspectorTest.expectThat(event.data.styleSheet instanceof WebInspector.CSSStyleSheet, "StyleSheetAdded event should fire.");
+ if (checkStyleSheetRemovedCallback)
+ checkStyleSheetRemovedCallback(event.data.styleSheet);
+ addedStyleSheet = null;
+ resolve();
+ });
+ }
+ });
+ }
+
+ appendStyleSheetTests({
+ title: "StyleTag",
+ addExpression: "addStyleTag()",
+ removeExpression: "removeStyleTag()",
+ });
+
+ appendStyleSheetTests({
+ title: "ExternalStyleSheet",
+ addExpression: "addExternalStyleSheet()",
+ removeExpression: "removeExternalStyleSheet()",
+ checkStyleSheetAddedCallback: (styleSheet) => { InspectorTest.log("Added StyleSheet with URL: " + sanitizeURL(styleSheet.url)); },
+ checkStyleSheetRemovedCallback: (styleSheet) => { InspectorTest.log("Removed StyleSheet with URL: " + sanitizeURL(styleSheet.url)); },
+ extraEnableDisableTests: [
+ {title: "DisableExternalStyleSheetViaMediaAttribute", _expression_: "disableExternalStyleSheetViaMediaAttribute()"},
+ {title: "EnableExternalStyleSheetViaMediaAttribute", _expression_: "enableExternalStyleSheetViaMediaAttribute()"},
+ ],
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Test for CSS.styleSheetAdded and CSS.styleSheetRemoved events.</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector/css/stylesheet-events-imports-expected.txt (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-imports-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-imports-expected.txt 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,24 @@
+Test for CSS.styleSheetAdded and CSS.styleSheetRemoved events with @import rules.
+
+
+== Running test suite: CSS.StyleSheetEvents.Imports
+-- Running test case: CheckStyleSheets
+PASS: Should be 3 stylesheets.
+inspector/css/stylesheet-events-imports.html
+inspector/css/resources/import-level-1.css
+inspector/css/resources/import-level-2.css
+
+-- Running test case: DisablePropagatesThroughImports
+StyleSheetRemoved: inspector/css/resources/import-level-1.css
+StyleSheetRemoved: inspector/css/resources/import-level-2.css
+StyleSheetRemoved: inspector/css/stylesheet-events-imports.html
+
+-- Running test case: EnablePropagatesThroughImports
+StyleSheetAdded: inspector/css/resources/import-level-1.css
+StyleSheetAdded: inspector/css/resources/import-level-2.css
+StyleSheetAdded: inspector/css/stylesheet-events-imports.html
+
+-- Running test case: DeleteImportRemovesStyleSheet
+StyleSheetRemoved: inspector/css/resources/import-level-1.css
+StyleSheetRemoved: inspector/css/resources/import-level-2.css
+
Added: trunk/LayoutTests/inspector/css/stylesheet-events-imports.html (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-imports.html (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-imports.html 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style id="inlineStyleId">
+@import url(resources/import-level-1.css);
+body { color: blue; }
+</style>
+<script>
+function disableStyleSheet() {
+ document.styleSheets[0].disabled = true;
+}
+
+function enableStyleSheet() {
+ document.styleSheets[0].disabled = false;
+}
+
+function removeImport() {
+ document.getElementById("inlineStyleId").sheet.deleteRule(0);
+}
+
+function test()
+{
+ function sanitizeURL(url) {
+ return url.replace(/^.*?LayoutTests\//, "");
+ }
+
+ function collectEvents(n, then) {
+ let remaining = n;
+ let collection = [];
+ return function(event) {
+ collection.push(event);
+ remaining--;
+ if (!remaining)
+ then(collection);
+ }
+ }
+
+ let currentStyleSheetAddedHandler, currentStyleSheetRemovedHandler;
+ WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, (event) => { currentStyleSheetAddedHandler(event); });
+ WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, (event) => { currentStyleSheetRemovedHandler(event); });
+
+ let suite = InspectorTest.createAsyncSuite("CSS.StyleSheetEvents.Imports");
+
+ suite.addTestCase({
+ name: "CheckStyleSheets",
+ description: "Ensure there are currently two stylesheets.",
+ test: (resolve, reject) => {
+ let styleSheets = WebInspector.cssStyleManager.styleSheets;
+ InspectorTest.expectThat(styleSheets.length === 3, "Should be 3 stylesheets.");
+ for (let styleSheet of styleSheets)
+ InspectorTest.log(sanitizeURL(styleSheet.url));
+ resolve();
+ }
+ });
+
+ suite.addTestCase({
+ name: "DisablePropagatesThroughImports",
+ description: "Disabling the top stylesheet containing imports will remove all stylesheets.",
+ test: (resolve, reject) => {
+ currentStyleSheetRemovedHandler = collectEvents(3, function(events) {
+ events.map((e) => sanitizeURL(e.data.styleSheet.url))
+ .sort()
+ .forEach((url) => { InspectorTest.log("StyleSheetRemoved: " + url); });
+ currentStyleSheetRemovedHandler = null;
+ resolve();
+ });
+ InspectorTest.evaluateInPage("disableStyleSheet()");
+ }
+ });
+
+ suite.addTestCase({
+ name: "EnablePropagatesThroughImports",
+ description: "Enabling the top stylesheet containing imports will add all stylesheets.",
+ test: (resolve, reject) => {
+ currentStyleSheetAddedHandler = collectEvents(3, function(events) {
+ events.map((e) => sanitizeURL(e.data.styleSheet.url))
+ .sort()
+ .forEach((url) => { InspectorTest.log("StyleSheetAdded: " + url); });
+ currentStyleSheetAddedHandler = null;
+ resolve();
+ });
+ InspectorTest.evaluateInPage("enableStyleSheet()");
+ }
+ });
+
+ suite.addTestCase({
+ name: "DeleteImportRemovesStyleSheet",
+ description: "Deleting the @import rule should remove that stylesheet and its imports.",
+ test: (resolve, reject) => {
+ currentStyleSheetRemovedHandler = collectEvents(2, function(events) {
+ events.map((e) => sanitizeURL(e.data.styleSheet.url))
+ .sort()
+ .forEach((url) => { InspectorTest.log("StyleSheetRemoved: " + url); });
+ currentStyleSheetRemovedHandler = null;
+ resolve();
+ });
+ InspectorTest.evaluateInPage("removeImport()");
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Test for CSS.styleSheetAdded and CSS.styleSheetRemoved events with @import rules.</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector/css/stylesheet-events-inspector-stylesheet-expected.txt (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-inspector-stylesheet-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-inspector-stylesheet-expected.txt 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,11 @@
+Test for CSS.styleSheetAdded for Inspector stylesheets.
+
+
+== Running test suite: CSS.StyleSheetEvents.InspectorStyleSheet
+-- Running test case: CheckNoStyleSheets
+PASS: Should be no stylesheets.
+
+-- Running test case: CreateInspectorStyleSheet
+PASS: Should be one stylesheet.
+PASS: StyleSheet origin is inspector.
+
Added: trunk/LayoutTests/inspector/css/stylesheet-events-inspector-stylesheet.html (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-inspector-stylesheet.html (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-inspector-stylesheet.html 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("CSS.StyleSheetEvents.InspectorStyleSheet");
+
+ let bodyNodeId;
+
+ suite.addTestCase({
+ name: "CheckNoStyleSheets",
+ description: "Ensure there are currently no stylesheets.",
+ test: (resolve, reject) => {
+ InspectorTest.expectThat(WebInspector.cssStyleManager.styleSheets.length === 0, "Should be no stylesheets.");
+ resolve();
+ }
+ });
+
+ suite.addTestCase({
+ name: "CreateInspectorStyleSheet",
+ description: "Creating an inspector stylesheet adds a stylesheet.",
+ test: (resolve, reject) => {
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, function(event) {
+ InspectorTest.expectThat(WebInspector.cssStyleManager.styleSheets.length === 1, "Should be one stylesheet.");
+ InspectorTest.assert(event.data.styleSheet instanceof WebInspector.CSSStyleSheet, "Event data should be a CSSStyleSheet");
+ InspectorTest.expectThat(event.data.styleSheet.origin === WebInspector.CSSStyleSheet.Type.Inspector, "StyleSheet origin is inspector.");
+ resolve();
+ });
+
+ // FIXME: Currently the only way to create an inspector stylesheet is through `CSS.addRule`.
+ CSSAgent.addRule(bodyNodeId, "body");
+ }
+ });
+
+ WebInspector.domTreeManager.requestDocument(function(documentNode) {
+ WebInspector.domTreeManager.querySelector(documentNode.id, "body", function(contentNodeId) {
+ bodyNodeId = contentNodeId;
+ suite.runTestCasesAndFinish();
+ });
+ });
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Test for CSS.styleSheetAdded for Inspector stylesheets.</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector/css/stylesheet-events-multiple-documents-expected.txt (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-multiple-documents-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-multiple-documents-expected.txt 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,19 @@
+CSS.styleSheetAdded and CSS.styleSheetRemoved for multiple documents.
+
+
+== Running test suite: CSS.StyleSheetEvents.MultipleDocuments
+-- Running test case: CheckStyleSheets
+PASS: Should be one stylesheets.
+URL: inspector/css/resources/external.css <mainframe>
+
+-- Running test case: CheckStyleSheetsAfterAddingSubframe
+PASS: Should be two stylesheets.
+PASS: New StyleSheet is for a subframe
+URL: inspector/css/resources/external.css <mainframe>
+URL: inspector/css/resources/external.css <childframe>
+
+-- Running test case: CheckStyleSheetsAfterRemovingSubframe
+PASS: Should be one stylesheet.
+PASS: Removed StyleSheet is for a subframe
+URL: inspector/css/resources/external.css <mainframe>
+
Added: trunk/LayoutTests/inspector/css/stylesheet-events-multiple-documents.html (0 => 189002)
--- trunk/LayoutTests/inspector/css/stylesheet-events-multiple-documents.html (rev 0)
+++ trunk/LayoutTests/inspector/css/stylesheet-events-multiple-documents.html 2015-08-26 23:48:49 UTC (rev 189002)
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<link rel="stylesheet" href=""
+<script>
+function addSubframe() {
+ var iframe = document.createElement("iframe");
+ iframe.id = "subframe";
+ iframe.src = ""
+ document.body.appendChild(iframe);
+}
+
+function removeSubframe() {
+ document.getElementById("subframe").remove();
+}
+
+function test()
+{
+ function sanitizeURL(url) {
+ return url.replace(/^.*?LayoutTests\//, "");
+ }
+
+ function logStyleSheets() {
+ WebInspector.cssStyleManager.styleSheets.sort((a, b) => a.url.localeCompare(b.url)).forEach(function(styleSheet) {
+ var frameString = styleSheet.parentFrame.id === WebInspector.frameResourceManager.mainFrame.id ? "<mainframe>" : "<childframe>";
+ InspectorTest.log(`URL: ${sanitizeURL(styleSheet.url)} ${frameString}`);
+ });
+ }
+
+ let suite = InspectorTest.createAsyncSuite("CSS.StyleSheetEvents.MultipleDocuments");
+
+ suite.addTestCase({
+ name: "CheckStyleSheets",
+ description: "Ensure there is currently one stylesheet.",
+ test: (resolve, reject) => {
+ InspectorTest.expectThat(WebInspector.cssStyleManager.styleSheets.length === 1, "Should be one stylesheets.");
+ logStyleSheets();
+ resolve();
+ }
+ });
+
+ suite.addTestCase({
+ name: "CheckStyleSheetsAfterAddingSubframe",
+ description: "Ensure subframe stylesheets are added.",
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage("addSubframe()");
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, function(event) {
+ InspectorTest.expectThat(WebInspector.cssStyleManager.styleSheets.length === 2, "Should be two stylesheets.");
+ InspectorTest.expectThat(event.data.styleSheet.parentFrame !== WebInspector.frameResourceManager.mainFrame.id, "New StyleSheet is for a subframe");
+ logStyleSheets();
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "CheckStyleSheetsAfterRemovingSubframe",
+ description: "Ensure subframe stylesheets are removed.",
+ test: (resolve, reject) => {
+ InspectorTest.evaluateInPage("removeSubframe()");
+ WebInspector.cssStyleManager.singleFireEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, function(event) {
+ InspectorTest.expectThat(WebInspector.cssStyleManager.styleSheets.length === 1, "Should be one stylesheet.");
+ InspectorTest.expectThat(event.data.styleSheet.parentFrame !== WebInspector.frameResourceManager.mainFrame.id, "Removed StyleSheet is for a subframe");
+ logStyleSheets();
+ resolve();
+ });
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>CSS.styleSheetAdded and CSS.styleSheetRemoved for multiple documents.</p>
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (189001 => 189002)
--- trunk/Source/_javascript_Core/ChangeLog 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-08-26 23:48:49 UTC (rev 189002)
@@ -1,3 +1,13 @@
+2015-08-26 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Implement tracking of active stylesheets in the frontend
+ https://bugs.webkit.org/show_bug.cgi?id=105828
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/protocol/CSS.json:
+ Add new events for when a StyleSheet is added or removed.
+
2015-08-26 Chris Dumez <cdu...@apple.com>
Distinguish Web IDL callback interfaces from Web IDL callback functions
Modified: trunk/Source/_javascript_Core/inspector/protocol/CSS.json (189001 => 189002)
--- trunk/Source/_javascript_Core/inspector/protocol/CSS.json 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/_javascript_Core/inspector/protocol/CSS.json 2015-08-26 23:48:49 UTC (rev 189002)
@@ -389,6 +389,20 @@
"description": "Fired whenever a stylesheet is changed as a result of the client operation."
},
{
+ "name": "styleSheetAdded",
+ "parameters": [
+ { "name": "header", "$ref": "CSSStyleSheetHeader", "description": "Added stylesheet metainfo." }
+ ],
+ "description": "Fired whenever an active document stylesheet is added."
+ },
+ {
+ "name": "styleSheetRemoved",
+ "parameters": [
+ { "name": "styleSheetId", "$ref": "StyleSheetId", "description": "Identifier of the removed stylesheet." }
+ ],
+ "description": "Fired whenever an active document stylesheet is removed."
+ },
+ {
"name": "namedFlowCreated",
"parameters": [
{ "name": "namedFlow", "$ref": "NamedFlow", "description": "The new Named Flow." }
Modified: trunk/Source/WebCore/ChangeLog (189001 => 189002)
--- trunk/Source/WebCore/ChangeLog 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/ChangeLog 2015-08-26 23:48:49 UTC (rev 189002)
@@ -1,3 +1,70 @@
+2015-08-26 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Implement tracking of active stylesheets in the frontend
+ https://bugs.webkit.org/show_bug.cgi?id=105828
+
+ Reviewed by Timothy Hatcher.
+
+ Tests: inspector/css/stylesheet-events-basic.html
+ inspector/css/stylesheet-events-imports.html
+ inspector/css/stylesheet-events-inspector-stylesheet.html
+
+ * inspector/InspectorInstrumentation.cpp:
+ (WebCore::InspectorInstrumentation::documentDetachedImpl):
+ (WebCore::InspectorInstrumentation::activeStyleSheetsUpdatedImpl):
+ * inspector/InspectorInstrumentation.h:
+ (WebCore::InspectorInstrumentation::documentDetached):
+ (WebCore::InspectorInstrumentation::activeStyleSheetsUpdated):
+ New hooks for when a document is detached or a document's style sheets are updated.
+
+ * dom/Document.cpp:
+ (WebCore::Document::prepareForDestruction):
+ Inform the inspector so the CSSAgent can remove document related data.
+
+ * dom/DocumentStyleSheetCollection.h:
+ * dom/DocumentStyleSheetCollection.cpp:
+ (WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):
+ Inform the inspector so the CSSAgent can push stylesheet related events.
+
+ (WebCore::DocumentStyleSheetCollection::activeStyleSheetsForInspector): Added.
+ CSSStyleSheets for the inspector include non-disabled author stylesheets
+ even if they are empty.
+
+ * inspector/InspectorCSSAgent.h:
+ * inspector/InspectorCSSAgent.cpp:
+ (WebCore::InspectorCSSAgent::reset):
+ (WebCore::InspectorCSSAgent::documentDetached):
+ Handling for the new list of known document to CSSStyleSheets map.
+
+ (WebCore::InspectorCSSAgent::enable):
+ When the CSS domain is enabled, tell the frontend about known stylesheets.
+
+ (WebCore::InspectorCSSAgent::activeStyleSheetsUpdated):
+ (WebCore::InspectorCSSAgent::setActiveStyleSheetsForDocument):
+ Diff the old list of known stylesheets to the new list of stylesheets
+ for an individual document. Then send appropriate added/removed events.
+
+ (WebCore::InspectorCSSAgent::collectAllStyleSheets):
+ (WebCore::InspectorCSSAgent::collectAllDocumentStyleSheets):
+ (WebCore::InspectorCSSAgent::collectStyleSheets):
+ Collect stylesheets recursively. A stylesheet may link to other stylesheets
+ through @import statements.
+
+ (WebCore::InspectorCSSAgent::getAllStyleSheets):
+ Use the new methods, this command should go away as it will no longer be useful.
+
+ (WebCore::InspectorCSSAgent::unbindStyleSheet):
+ (WebCore::InspectorCSSAgent::bindStyleSheet):
+ Create an InspectorStyleSheet from a CSSStyleSheet and add to the appropriate lists.
+ Likewise, unbinding will remove from the appropriate lists.
+
+ (WebCore::InspectorCSSAgent::viaInspectorStyleSheet):
+ (WebCore::InspectorCSSAgent::detectOrigin):
+ When creating the inspector stylesheet, which is a <style> element,
+ it will push a StyleSheetAdded event. In the process of binding this
+ new stylesheet use the m_creatingViaInspectorStyleSheet to add it to
+ out list of Inspector Stylesheets.
+
2015-08-26 Myles C. Maxfield <mmaxfi...@apple.com>
Add comment to LocaleToScriptMappingDefault.cpp
Modified: trunk/Source/WebCore/dom/Document.cpp (189001 => 189002)
--- trunk/Source/WebCore/dom/Document.cpp 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/dom/Document.cpp 2015-08-26 23:48:49 UTC (rev 189002)
@@ -2251,6 +2251,8 @@
page()->pointerLockController().documentDetached(this);
#endif
+ InspectorInstrumentation::documentDetached(*this);
+
stopActiveDOMObjects();
m_eventQueue.close();
#if ENABLE(FULLSCREEN_API)
Modified: trunk/Source/WebCore/dom/DocumentStyleSheetCollection.cpp (189001 => 189002)
--- trunk/Source/WebCore/dom/DocumentStyleSheetCollection.cpp 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/dom/DocumentStyleSheetCollection.cpp 2015-08-26 23:48:49 UTC (rev 189002)
@@ -33,6 +33,7 @@
#include "HTMLIFrameElement.h"
#include "HTMLLinkElement.h"
#include "HTMLStyleElement.h"
+#include "InspectorInstrumentation.h"
#include "Page.h"
#include "PageGroup.h"
#include "ProcessingInstruction.h"
@@ -483,6 +484,8 @@
m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
m_styleSheetsForStyleSheetList.swap(activeStyleSheets);
+ InspectorInstrumentation::activeStyleSheetsUpdated(m_document);
+
for (const auto& sheet : m_activeAuthorStyleSheets) {
if (sheet->contents().usesRemUnits())
m_usesRemUnits = true;
@@ -494,6 +497,27 @@
return requiresFullStyleRecalc;
}
+const Vector<RefPtr<CSSStyleSheet>> DocumentStyleSheetCollection::activeStyleSheetsForInspector() const
+{
+ Vector<RefPtr<CSSStyleSheet>> result;
+
+ result.appendVector(injectedAuthorStyleSheets());
+ result.appendVector(documentAuthorStyleSheets());
+
+ for (auto& styleSheet : m_styleSheetsForStyleSheetList) {
+ if (!is<CSSStyleSheet>(*styleSheet))
+ continue;
+
+ CSSStyleSheet& sheet = downcast<CSSStyleSheet>(*styleSheet);
+ if (sheet.disabled())
+ continue;
+
+ result.append(&sheet);
+ }
+
+ return result;
+}
+
bool DocumentStyleSheetCollection::activeStyleSheetsContains(const CSSStyleSheet* sheet) const
{
if (!m_weakCopyOfActiveStyleSheetListForFastLookup) {
Modified: trunk/Source/WebCore/dom/DocumentStyleSheetCollection.h (189001 => 189002)
--- trunk/Source/WebCore/dom/DocumentStyleSheetCollection.h 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/dom/DocumentStyleSheetCollection.h 2015-08-26 23:48:49 UTC (rev 189002)
@@ -59,6 +59,8 @@
const Vector<RefPtr<CSSStyleSheet>>& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
+ const Vector<RefPtr<CSSStyleSheet>> activeStyleSheetsForInspector() const;
+
CSSStyleSheet* pageUserSheet();
const Vector<RefPtr<CSSStyleSheet>>& documentUserStyleSheets() const { return m_userStyleSheets; }
const Vector<RefPtr<CSSStyleSheet>>& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp (189001 => 189002)
--- trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp 2015-08-26 23:48:49 UTC (rev 189002)
@@ -375,10 +375,12 @@
void InspectorCSSAgent::reset()
{
+ // FIXME: Should we be resetting on main frame navigations?
m_idToInspectorStyleSheet.clear();
m_cssStyleSheetToInspectorStyleSheet.clear();
m_nodeToInspectorStyleSheet.clear();
m_documentToInspectorStyleSheet.clear();
+ m_documentToKnownCSSStyleSheets.clear();
resetNonPersistentData();
}
@@ -393,6 +395,9 @@
void InspectorCSSAgent::enable(ErrorString&)
{
m_instrumentingAgents->setInspectorCSSAgent(this);
+
+ for (auto* document : m_domAgent->documents())
+ activeStyleSheetsUpdated(*document);
}
void InspectorCSSAgent::disable(ErrorString&)
@@ -400,12 +405,58 @@
m_instrumentingAgents->setInspectorCSSAgent(nullptr);
}
+void InspectorCSSAgent::documentDetached(Document& document)
+{
+ Vector<CSSStyleSheet*> emptyList;
+ setActiveStyleSheetsForDocument(document, emptyList);
+
+ m_documentToKnownCSSStyleSheets.remove(&document);
+}
+
void InspectorCSSAgent::mediaQueryResultChanged()
{
- if (m_frontendDispatcher)
- m_frontendDispatcher->mediaQueryResultChanged();
+ m_frontendDispatcher->mediaQueryResultChanged();
}
+void InspectorCSSAgent::activeStyleSheetsUpdated(Document& document)
+{
+ Vector<CSSStyleSheet*> cssStyleSheets;
+ collectAllDocumentStyleSheets(document, cssStyleSheets);
+
+ setActiveStyleSheetsForDocument(document, cssStyleSheets);
+}
+
+void InspectorCSSAgent::setActiveStyleSheetsForDocument(Document& document, Vector<CSSStyleSheet*>& activeStyleSheets)
+{
+ HashSet<CSSStyleSheet*>& previouslyKnownActiveStyleSheets = m_documentToKnownCSSStyleSheets.add(&document, HashSet<CSSStyleSheet*>()).iterator->value;
+
+ HashSet<CSSStyleSheet*> removedStyleSheets(previouslyKnownActiveStyleSheets);
+ Vector<CSSStyleSheet*> addedStyleSheets;
+ for (auto& activeStyleSheet : activeStyleSheets) {
+ if (removedStyleSheets.contains(activeStyleSheet))
+ removedStyleSheets.remove(activeStyleSheet);
+ else
+ addedStyleSheets.append(activeStyleSheet);
+ }
+
+ for (auto* cssStyleSheet : removedStyleSheets) {
+ previouslyKnownActiveStyleSheets.remove(cssStyleSheet);
+ RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(cssStyleSheet);
+ if (m_idToInspectorStyleSheet.contains(inspectorStyleSheet->id())) {
+ String id = unbindStyleSheet(inspectorStyleSheet.get());
+ m_frontendDispatcher->styleSheetRemoved(id);
+ }
+ }
+
+ for (auto* cssStyleSheet : addedStyleSheets) {
+ previouslyKnownActiveStyleSheets.add(cssStyleSheet);
+ if (!m_cssStyleSheetToInspectorStyleSheet.contains(cssStyleSheet)) {
+ InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssStyleSheet);
+ m_frontendDispatcher->styleSheetAdded(inspectorStyleSheet->buildObjectForStyleSheetInfo());
+ }
+ }
+}
+
void InspectorCSSAgent::didCreateNamedFlow(Document& document, WebKitNamedFlow& namedFlow)
{
int documentNodeId = documentNodeWithRequestedFlowsId(&document);
@@ -597,13 +648,39 @@
void InspectorCSSAgent::getAllStyleSheets(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>>& styleInfos)
{
styleInfos = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>::create();
- Vector<Document*> documents = m_domAgent->documents();
- for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it) {
- StyleSheetList& list = (*it)->styleSheets();
- for (unsigned i = 0; i < list.length(); ++i) {
- StyleSheet& styleSheet = *list.item(i);
- if (is<CSSStyleSheet>(styleSheet))
- collectStyleSheets(&downcast<CSSStyleSheet>(styleSheet), styleInfos.get());
+
+ Vector<InspectorStyleSheet*> inspectorStyleSheets;
+ collectAllStyleSheets(inspectorStyleSheets);
+ for (auto* inspectorStyleSheet : inspectorStyleSheets)
+ styleInfos->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo());
+}
+
+void InspectorCSSAgent::collectAllStyleSheets(Vector<InspectorStyleSheet*>& result)
+{
+ Vector<CSSStyleSheet*> cssStyleSheets;
+ for (auto* document : m_domAgent->documents())
+ collectAllDocumentStyleSheets(*document, cssStyleSheets);
+
+ for (auto* cssStyleSheet : cssStyleSheets)
+ result.append(bindStyleSheet(cssStyleSheet));
+}
+
+void InspectorCSSAgent::collectAllDocumentStyleSheets(Document& document, Vector<CSSStyleSheet*>& result)
+{
+ Vector<RefPtr<CSSStyleSheet>> cssStyleSheets = document.styleSheetCollection().activeStyleSheetsForInspector();
+ for (auto& cssStyleSheet : cssStyleSheets)
+ collectStyleSheets(cssStyleSheet.get(), result);
+}
+
+void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Vector<CSSStyleSheet*>& result)
+{
+ result.append(styleSheet);
+
+ for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
+ CSSRule* rule = styleSheet->item(i);
+ if (is<CSSImportRule>(*rule)) {
+ if (CSSStyleSheet* importedStyleSheet = downcast<CSSImportRule>(*rule).styleSheet())
+ collectStyleSheets(importedStyleSheet, result);
}
}
}
@@ -810,17 +887,13 @@
return documentNodeId;
}
-void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>* result)
+String InspectorCSSAgent::unbindStyleSheet(InspectorStyleSheet* inspectorStyleSheet)
{
- InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(styleSheet);
- result->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo());
- for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
- CSSRule* rule = styleSheet->item(i);
- if (is<CSSImportRule>(*rule)) {
- if (CSSStyleSheet* importedStyleSheet = downcast<CSSImportRule>(*rule).styleSheet())
- collectStyleSheets(importedStyleSheet, result);
- }
- }
+ String id = inspectorStyleSheet->id();
+ m_idToInspectorStyleSheet.remove(id);
+ if (inspectorStyleSheet->pageStyleSheet())
+ m_cssStyleSheetToInspectorStyleSheet.remove(inspectorStyleSheet->pageStyleSheet());
+ return id;
}
InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet)
@@ -832,6 +905,8 @@
inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, styleSheet, detectOrigin(styleSheet, document), InspectorDOMAgent::documentURLString(document), this);
m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet);
+ if (m_creatingViaInspectorStyleSheet)
+ m_documentToInspectorStyleSheet.add(document, inspectorStyleSheet);
}
return inspectorStyleSheet.get();
}
@@ -864,27 +939,18 @@
else
return nullptr;
+ // Inserting this <style> into the document will trigger activeStyleSheetsUpdated
+ // and we will create an InspectorStyleSheet for this <style>'s CSSStyleSheet.
+ // Set this flag, so when we create it, we put it into the via inspector hash map.
+ m_creatingViaInspectorStyleSheet = true;
InlineStyleOverrideScope overrideScope(document);
targetNode->appendChild(styleElement, ec);
+ m_creatingViaInspectorStyleSheet = false;
}
if (ec)
return nullptr;
- CSSStyleSheet* cssStyleSheet = nullptr;
- if (styleElement->isHTMLElement())
- cssStyleSheet = downcast<HTMLStyleElement>(*styleElement).sheet();
- else if (styleElement->isSVGElement())
- cssStyleSheet = downcast<SVGStyleElement>(*styleElement).sheet();
-
- if (!cssStyleSheet)
- return nullptr;
-
- String id = String::number(m_lastStyleSheetId++);
- inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, cssStyleSheet, Inspector::Protocol::CSS::StyleSheetOrigin::Inspector, InspectorDOMAgent::documentURLString(document), this);
- m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
- m_cssStyleSheetToInspectorStyleSheet.set(cssStyleSheet, inspectorStyleSheet);
- m_documentToInspectorStyleSheet.set(document, inspectorStyleSheet);
- return inspectorStyleSheet.get();
+ return m_documentToInspectorStyleSheet.get(document);
}
InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString& errorString, const String& styleSheetId)
@@ -899,17 +965,20 @@
Inspector::Protocol::CSS::StyleSheetOrigin InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument)
{
- auto origin = Inspector::Protocol::CSS::StyleSheetOrigin::Regular;
+ if (m_creatingViaInspectorStyleSheet)
+ return Inspector::Protocol::CSS::StyleSheetOrigin::Inspector;
+
if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty())
- origin = Inspector::Protocol::CSS::StyleSheetOrigin::UserAgent;
- else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document")
- origin = Inspector::Protocol::CSS::StyleSheetOrigin::User;
- else {
- InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false);
- if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet())
- origin = Inspector::Protocol::CSS::StyleSheetOrigin::Inspector;
- }
- return origin;
+ return Inspector::Protocol::CSS::StyleSheetOrigin::UserAgent;
+
+ if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document")
+ return Inspector::Protocol::CSS::StyleSheetOrigin::User;
+
+ InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false);
+ if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet())
+ return Inspector::Protocol::CSS::StyleSheetOrigin::Inspector;
+
+ return Inspector::Protocol::CSS::StyleSheetOrigin::Regular;
}
RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver, Element* element)
Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.h (189001 => 189002)
--- trunk/Source/WebCore/inspector/InspectorCSSAgent.h 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.h 2015-08-26 23:48:49 UTC (rev 189002)
@@ -100,7 +100,9 @@
void reset();
// InspectorInstrumentation callbacks.
+ void documentDetached(Document&);
void mediaQueryResultChanged();
+ void activeStyleSheetsUpdated(Document&);
void didCreateNamedFlow(Document&, WebKitNamedFlow&);
void willRemoveNamedFlow(Document&, WebKitNamedFlow&);
void didChangeRegionOverset(Document&, WebKitNamedFlow&);
@@ -140,8 +142,13 @@
InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element);
Element* elementForId(ErrorString&, int nodeId);
int documentNodeWithRequestedFlowsId(Document*);
- void collectStyleSheets(CSSStyleSheet*, Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>*);
+ void collectAllStyleSheets(Vector<InspectorStyleSheet*>&);
+ void collectAllDocumentStyleSheets(Document&, Vector<CSSStyleSheet*>&);
+ void collectStyleSheets(CSSStyleSheet*, Vector<CSSStyleSheet*>&);
+ void setActiveStyleSheetsForDocument(Document&, Vector<CSSStyleSheet*>& activeStyleSheets);
+
+ String unbindStyleSheet(InspectorStyleSheet*);
InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*);
InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent);
InspectorStyleSheet* assertStyleSheetForId(ErrorString&, const String&);
@@ -172,11 +179,13 @@
CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet;
NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet;
DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet;
+ HashMap<Document*, HashSet<CSSStyleSheet*>> m_documentToKnownCSSStyleSheets;
NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState;
HashSet<int> m_namedFlowCollectionsRequested;
std::unique_ptr<ChangeRegionOversetTask> m_changeRegionOversetTask;
int m_lastStyleSheetId;
+ bool m_creatingViaInspectorStyleSheet { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (189001 => 189002)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2015-08-26 23:48:49 UTC (rev 189002)
@@ -184,6 +184,12 @@
domDebuggerAgent->didInvalidateStyleAttr(node);
}
+void InspectorInstrumentation::documentDetachedImpl(InstrumentingAgents& instrumentingAgents, Document& document)
+{
+ if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
+ cssAgent->documentDetached(document);
+}
+
void InspectorInstrumentation::frameWindowDiscardedImpl(InstrumentingAgents& instrumentingAgents, DOMWindow* window)
{
if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
@@ -196,6 +202,12 @@
cssAgent->mediaQueryResultChanged();
}
+void InspectorInstrumentation::activeStyleSheetsUpdatedImpl(InstrumentingAgents& instrumentingAgents, Document& document)
+{
+ if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
+ cssAgent->activeStyleSheetsUpdated(document);
+}
+
void InspectorInstrumentation::didPushShadowRootImpl(InstrumentingAgents& instrumentingAgents, Element& host, ShadowRoot& root)
{
if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (189001 => 189002)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2015-08-26 23:48:49 UTC (rev 189002)
@@ -122,8 +122,10 @@
static void didRemoveDOMAttr(Document&, Element&, const AtomicString& name);
static void characterDataModified(Document&, CharacterData&);
static void didInvalidateStyleAttr(Document&, Node&);
+ static void documentDetached(Document&);
static void frameWindowDiscarded(Frame*, DOMWindow*);
static void mediaQueryResultChanged(Document&);
+ static void activeStyleSheetsUpdated(Document&);
static void didPushShadowRoot(Element& host, ShadowRoot&);
static void willPopShadowRoot(Element& host, ShadowRoot&);
static void pseudoElementCreated(Page*, PseudoElement&);
@@ -303,8 +305,10 @@
static void didRemoveDOMAttrImpl(InstrumentingAgents&, Element&, const AtomicString& name);
static void characterDataModifiedImpl(InstrumentingAgents&, CharacterData&);
static void didInvalidateStyleAttrImpl(InstrumentingAgents&, Node&);
+ static void documentDetachedImpl(InstrumentingAgents&, Document&);
static void frameWindowDiscardedImpl(InstrumentingAgents&, DOMWindow*);
static void mediaQueryResultChangedImpl(InstrumentingAgents&);
+ static void activeStyleSheetsUpdatedImpl(InstrumentingAgents&, Document&);
static void didPushShadowRootImpl(InstrumentingAgents&, Element& host, ShadowRoot&);
static void willPopShadowRootImpl(InstrumentingAgents&, Element& host, ShadowRoot&);
static void pseudoElementCreatedImpl(InstrumentingAgents&, PseudoElement&);
@@ -542,6 +546,13 @@
didInvalidateStyleAttrImpl(*instrumentingAgents, node);
}
+inline void InspectorInstrumentation::documentDetached(Document& document)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
+ documentDetachedImpl(*instrumentingAgents, document);
+}
+
inline void InspectorInstrumentation::frameWindowDiscarded(Frame* frame, DOMWindow* domWindow)
{
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
@@ -555,6 +566,13 @@
mediaQueryResultChangedImpl(*instrumentingAgents);
}
+inline void InspectorInstrumentation::activeStyleSheetsUpdated(Document& document)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
+ activeStyleSheetsUpdatedImpl(*instrumentingAgents, document);
+}
+
inline void InspectorInstrumentation::didPushShadowRoot(Element& host, ShadowRoot& root)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
Modified: trunk/Source/WebInspectorUI/ChangeLog (189001 => 189002)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-08-26 23:48:49 UTC (rev 189002)
@@ -1,5 +1,40 @@
2015-08-26 Joseph Pecoraro <pecor...@apple.com>
+ Web Inspector: Implement tracking of active stylesheets in the frontend
+ https://bugs.webkit.org/show_bug.cgi?id=105828
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Models/CSSStyleSheet.js:
+ (WebInspector.CSSStyleSheet):
+ (WebInspector.CSSStyleSheet.prototype.get origin):
+ (WebInspector.CSSStyleSheet.prototype.updateInfo):
+ Add a new origin attribute that has been sent from the backend for a while.
+
+ * UserInterface/Controllers/CSSStyleManager.js:
+ (WebInspector.CSSStyleManager.prototype.styleSheetAdded):
+ (WebInspector.CSSStyleManager.prototype.styleSheetRemoved):
+ Handle the new events by managing the new CSSStyleSheets.
+
+ (WebInspector.CSSStyleManager):
+ (WebInspector.CSSStyleManager.prototype._mainResourceDidChange):
+ Reset the legacy fetching flag. Fetching is only needed for legacy backends.
+
+ (WebInspector.CSSStyleManager.prototype._fetchInfoForAllStyleSheets):
+ Include the new origin property in the legacy updateInfo path.
+
+ * UserInterface/Protocol/CSSObserver.js:
+ (WebInspector.CSSObserver.prototype.styleSheetAdded):
+ (WebInspector.CSSObserver.prototype.styleSheetRemoved):
+ Forward to the manager.
+
+ * UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
+ (WebInspector.CSSStyleDetailsSidebarPanel):
+ Refresh the sidebar when stylesheets are added / removed, as that
+ may affect the style of the select element.
+
+2015-08-26 Joseph Pecoraro <pecor...@apple.com>
+
Web Inspector: Drop iOS 6 Legacy Remote Inspector Support
https://bugs.webkit.org/show_bug.cgi?id=148456
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSStyleManager.js (189001 => 189002)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSStyleManager.js 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSStyleManager.js 2015-08-26 23:48:49 UTC (rev 189002)
@@ -43,12 +43,35 @@
this._colorFormatSetting = new WebInspector.Setting("default-color-format", WebInspector.Color.Format.Original);
- this._fetchedInitialStyleSheets = false;
this._styleSheetIdentifierMap = new Map;
this._styleSheetFrameURLMap = new Map;
this._nodeStylesMap = {};
+
+ // COMPATIBILITY (iOS 9): Legacy backends did not send stylesheet
+ // added/removed events and must be fetched manually.
+ this._fetchedInitialStyleSheets = window.CSSAgent && window.CSSAgent.hasEvent("styleSheetAdded");
}
+ // Static
+
+ static protocolStyleSheetOriginToEnum(origin)
+ {
+ // FIXME: Switch from CSSRule.Type to CSSStyleSheet.Type everywhere.
+ switch (origin) {
+ case CSSAgent.StyleSheetOrigin.Regular:
+ return WebInspector.CSSStyleSheet.Type.Author;
+ case CSSAgent.StyleSheetOrigin.User:
+ return WebInspector.CSSStyleSheet.Type.User;
+ case CSSAgent.StyleSheetOrigin.UserAgent:
+ return WebInspector.CSSStyleSheet.Type.UserAgent;
+ case CSSAgent.StyleSheetOrigin.Inspector:
+ return WebInspector.CSSStyleSheet.Type.Inspector;
+ default:
+ console.assert(false, "Unknown StyleSheetOrigin", origin);
+ return CSSAgent.StyleSheetOrigin.Regular;
+ }
+ }
+
// Public
get preferredColorFormat()
@@ -152,6 +175,29 @@
this._updateResourceContent(styleSheet);
}
+ styleSheetAdded(styleSheetInfo)
+ {
+ console.assert(!this._styleSheetIdentifierMap.has(styleSheetInfo.styleSheetId), "Attempted to add a CSSStyleSheet but identifier was already in use");
+ let styleSheet = this.styleSheetForIdentifier(styleSheetInfo.styleSheetId);
+ let parentFrame = WebInspector.frameResourceManager.frameForIdentifier(styleSheetInfo.frameId);
+ let origin = WebInspector.CSSStyleManager.protocolStyleSheetOriginToEnum(styleSheetInfo.origin);
+ styleSheet.updateInfo(styleSheetInfo.sourceURL, parentFrame, origin, styleSheetInfo.isInline, styleSheetInfo.startLine, styleSheetInfo.startColumn);
+
+ this.dispatchEventToListeners(WebInspector.CSSStyleManager.Event.StyleSheetAdded, {styleSheet});
+ }
+
+ styleSheetRemoved(styleSheetIdentifier)
+ {
+ let styleSheet = this._styleSheetIdentifierMap.get(styleSheetIdentifier);
+ console.assert(styleSheet, "Attempted to remove a CSSStyleSheet that was not tracked");
+ if (!styleSheet)
+ return;
+
+ this._styleSheetIdentifierMap.delete(styleSheetIdentifier);
+
+ this.dispatchEventToListeners(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, {styleSheet});
+ }
+
// Private
_nodePseudoClassesDidChange(event)
@@ -187,7 +233,7 @@
// Clear our maps when the main frame navigates.
- this._fetchedInitialStyleSheets = false;
+ this._fetchedInitialStyleSheets = window.CSSAgent && window.CSSAgent.hasEvent("styleSheetAdded");
this._styleSheetIdentifierMap.clear();
this._styleSheetFrameURLMap.clear();
this._nodeStylesMap = {};
@@ -267,6 +313,7 @@
for (let styleSheetInfo of styleSheets) {
let parentFrame = WebInspector.frameResourceManager.frameForIdentifier(styleSheetInfo.frameId);
+ let origin = WebInspector.CSSStyleManager.protocolStyleSheetOriginToEnum(styleSheetInfo.origin);
// COMPATIBILITY (iOS 9): The info did not have 'isInline', 'startLine', and 'startColumn', so make false and 0 in these cases.
let isInline = styleSheetInfo.isInline || false;
@@ -274,7 +321,7 @@
let startColumn = styleSheetInfo.startColumn || 0;
let styleSheet = this.styleSheetForIdentifier(styleSheetInfo.styleSheetId);
- styleSheet.updateInfo(styleSheetInfo.sourceURL, parentFrame, isInline, startLine, startColumn);
+ styleSheet.updateInfo(styleSheetInfo.sourceURL, parentFrame, origin, isInline, startLine, startColumn);
let key = this._frameURLMapKey(parentFrame, styleSheetInfo.sourceURL);
this._styleSheetFrameURLMap.set(key, styleSheet);
@@ -374,4 +421,9 @@
}
};
+WebInspector.CSSStyleManager.Event = {
+ StyleSheetAdded: "css-style-manager-style-sheet-added",
+ StyleSheetRemoved: "css-style-manager-style-sheet-removed",
+};
+
WebInspector.CSSStyleManager.ForceablePseudoClasses = ["active", "focus", "hover", "visited"];
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (189001 => 189002)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2015-08-26 23:48:49 UTC (rev 189002)
@@ -613,7 +613,7 @@
_pauseReasonFromPayload(payload)
{
- // FIXME: Handle other backend pause seasons.
+ // FIXME: Handle other backend pause reasons.
switch (payload) {
case DebuggerAgent.PausedReason.Assert:
return WebInspector.DebuggerManager.PauseReason.Assertion;
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleSheet.js (189001 => 189002)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleSheet.js 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleSheet.js 2015-08-26 23:48:49 UTC (rev 189002)
@@ -34,6 +34,7 @@
this._id = id || null;
this._url = null;
this._parentFrame = null;
+ this._origin = null;
this._startLineNumber = 0;
this._startColumnNumber = 0;
@@ -62,6 +63,11 @@
return this._parentFrame;
}
+ get origin()
+ {
+ return this._origin;
+ }
+
get url()
{
return this._url;
@@ -137,7 +143,7 @@
// Protected
- updateInfo(url, parentFrame, inlineStyle, startLineNumber, startColumnNumber)
+ updateInfo(url, parentFrame, origin, inlineStyle, startLineNumber, startColumnNumber)
{
this._hasInfo = true;
@@ -145,6 +151,7 @@
this._urlComponents = undefined;
this._parentFrame = parentFrame || null;
+ this._origin = origin;
this._inlineStyleTag = inlineStyle;
this._startLineNumber = startLineNumber;
@@ -205,3 +212,10 @@
WebInspector.CSSStyleSheet.Event = {
ContentDidChange: "stylesheet-content-did-change"
};
+
+WebInspector.CSSStyleSheet.Type = {
+ Author: "css-stylesheet-type-author",
+ User: "css-stylesheet-type-user",
+ UserAgent: "css-stylesheet-type-user-agent",
+ Inspector: "css-stylesheet-type-inspector"
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/CSSObserver.js (189001 => 189002)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/CSSObserver.js 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/CSSObserver.js 2015-08-26 23:48:49 UTC (rev 189002)
@@ -37,14 +37,14 @@
WebInspector.cssStyleManager.styleSheetChanged(styleSheetId);
}
- styleSheetAdded(header)
+ styleSheetAdded(styleSheetInfo)
{
- // FIXME: Not implemented. <rdar://problem/13213680>
+ WebInspector.cssStyleManager.styleSheetAdded(styleSheetInfo);
}
- styleSheetRemoved(header)
+ styleSheetRemoved(id)
{
- // FIXME: Not implemented. <rdar://problem/13213680>
+ WebInspector.cssStyleManager.styleSheetRemoved(id);
}
namedFlowCreated(namedFlow)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js (189001 => 189002)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js 2015-08-26 23:36:58 UTC (rev 189001)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js 2015-08-26 23:48:49 UTC (rev 189002)
@@ -101,6 +101,9 @@
this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
optionsContainer.appendChild(this._filterBar.element);
+ WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, this.refresh, this);
+ WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, this.refresh, this);
+
this.element.appendChild(optionsContainer);
}