Diff
Modified: trunk/LayoutTests/ChangeLog (243263 => 243264)
--- trunk/LayoutTests/ChangeLog 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/LayoutTests/ChangeLog 2019-03-21 00:22:06 UTC (rev 243264)
@@ -1,3 +1,14 @@
+2019-03-20 Devin Rousso <[email protected]>
+
+ Web Inspector: Styles Redesign: Editing selector should not hide the rule
+ https://bugs.webkit.org/show_bug.cgi?id=178489
+ <rdar://problem/35062434>
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/unit-tests/multimap.html: Added.
+ * inspector/unit-tests/multimap-expected.txt: Added.
+
2019-03-20 Ryan Haddad <[email protected]>
Unreviewed, rebaseline two tests after r243241.
Added: trunk/LayoutTests/inspector/unit-tests/multimap-expected.txt (0 => 243264)
--- trunk/LayoutTests/inspector/unit-tests/multimap-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/unit-tests/multimap-expected.txt 2019-03-21 00:22:06 UTC (rev 243264)
@@ -0,0 +1,81 @@
+Testing all methods of Multimap.
+
+
+== Running test suite: Multimap
+-- Running test case: Multimap.prototype.constructor.Empty
+[]
+
+-- Running test case: Multimap.prototype.constructor.NonEmpty
+[["zero","one"],["zero","four"],["two","three"]]
+
+-- Running test case: Multimap.prototype.has
+PASS: has should return true if a key exists.
+PASS: has should return true if a value exists for an existing key.
+PASS: has should return false if a value doesn't exist for an existing key.
+PASS: has should return false if a key doesn't exist.
+PASS: has should return false if a key doesn't exist, even if the value exists for a different key.
+
+-- Running test case: Multimap.prototype.add.RepeatingKeysUniqueValues
+[["zero","one"],["zero","two"]]
+
+-- Running test case: Multimap.prototype.add.UniqueKeysRepeatingValues
+[["zero","one"],["two","one"],["three","one"]]
+
+-- Running test case: Multimap.prototype.add.RepeatingKeysRepeatingValues
+[["zero","one"],["zero","three"],["two","one"]]
+
+-- Running test case: Multimap.prototype.delete
+[[0,1],[2,3],[2,4]]
+PASS: The key 0 and the value 1 were successfully deleted.
+[[2,3],[2,4]]
+PASS: The key 2 and the value 3 were successfully deleted.
+[[2,4]]
+PASS: The key 2 and the value 4 were successfully deleted.
+[]
+
+-- Running test case: Multimap.prototype.delete.NonExistingValues
+[[0,1],[2,3],[4,4]]
+PASS: Nothing was removed for key 0 and value 3.
+PASS: Nothing was removed for key 0 and value 4.
+PASS: Nothing was removed for key 2 and value 1.
+PASS: Nothing was removed for key 2 and value 4.
+PASS: Nothing was removed for key 4 and value 1.
+PASS: Nothing was removed for key 4 and value 3.
+[[0,1],[2,3],[4,4]]
+
+-- Running test case: Multimap.prototype.delete.NonExistingKeys
+[[0,1],[2,3],[4,4]]
+PASS: Nothing was removed for key 1.
+PASS: Nothing was removed for key 3.
+PASS: Nothing was removed for key 5.
+[[0,1],[2,3],[4,4]]
+
+-- Running test case: Multimap.prototype.delete.AllValuesForKey
+[["opossum","badger"],["opossum","raccoon"],["raccoon","opossum"]]
+PASS: Nothing was removed for key "badger".
+[["opossum","badger"],["opossum","raccoon"],["raccoon","opossum"]]
+PASS: Values were removed for key "opossum".
+[["raccoon","opossum"]]
+
+-- Running test case: Multimap.prototype.clear
+[["one","two"],["one","five"],["three","four"],["three","six"]]
+[]
+
+-- Running test case: Multimap.prototype.keys
+[["one","two"],["one","five"],["three","four"],["three","six"]]
+["one","three"]
+
+-- Running test case: Multimap.prototype.values
+[["one","two"],["one","five"],["three","four"],["three","six"]]
+["two","five","four","six"]
+
+-- Running test case: Multimap.prototype.sets
+[["one","two"],["one","five"],["three","four"],["three","six"]]
+[["one",["two","five"]],["three",["four","six"]]]
+
+-- Running test case: Multimap.prototype.copy
+[["one","two"],["three","four"]]
+PASS: Copy should not return the same object.
+PASS: Copy should return a deep copy.
+PASS: Modifying the original should not modify the copy.
+
Added: trunk/LayoutTests/inspector/unit-tests/multimap.html (0 => 243264)
--- trunk/LayoutTests/inspector/unit-tests/multimap.html (rev 0)
+++ trunk/LayoutTests/inspector/unit-tests/multimap.html 2019-03-21 00:22:06 UTC (rev 243264)
@@ -0,0 +1,258 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = InspectorTest.createSyncSuite("Multimap");
+
+ suite.addTestCase({
+ name: "Multimap.prototype.constructor.Empty",
+ test() {
+ let multimap = new Multimap;
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.constructor.NonEmpty",
+ test() {
+ let multimap = new Multimap([["zero", "one"], ["two", "three"], ["zero", "four"]]);
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.has",
+ test() {
+ let multimap = new Multimap([["zero", "one"], ["two", "three"], ["zero", "four"]]);
+
+ InspectorTest.expectThat(multimap.has("zero"), "has should return true if a key exists.");
+ InspectorTest.expectThat(multimap.has("zero", "one"), "has should return true if a value exists for an existing key.");
+ InspectorTest.expectFalse(multimap.has("zero", "three"), "has should return false if a value doesn't exist for an existing key.");
+ InspectorTest.expectFalse(multimap.has("one"), "has should return false if a key doesn't exist.");
+ InspectorTest.expectFalse(multimap.has("one", "three"), "has should return false if a key doesn't exist, even if the value exists for a different key.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.add.RepeatingKeysUniqueValues",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("zero", "one");
+ multimap.add("zero", "two");
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.add.UniqueKeysRepeatingValues",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("zero", "one");
+ multimap.add("two", "one");
+ multimap.add("three", "one");
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.add.RepeatingKeysRepeatingValues",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("zero", "one");
+ multimap.add("two", "one");
+ multimap.add("zero", "one");
+ multimap.add("zero", "three");
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.delete",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add(0, 1);
+ multimap.add(2, 3);
+ multimap.add(2, 4);
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectThat(multimap.delete(0, 1), "The key 0 and the value 1 were successfully deleted.");
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectThat(multimap.delete(2, 3), "The key 2 and the value 3 were successfully deleted.");
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectThat(multimap.delete(2, 4), "The key 2 and the value 4 were successfully deleted.");
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.delete.NonExistingValues",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add(0, 1);
+ multimap.add(2, 3);
+ multimap.add(4, 4);
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectFalse(multimap.delete(0, 3), "Nothing was removed for key 0 and value 3.");
+ InspectorTest.expectFalse(multimap.delete(0, 4), "Nothing was removed for key 0 and value 4.");
+ InspectorTest.expectFalse(multimap.delete(2, 1), "Nothing was removed for key 2 and value 1.");
+ InspectorTest.expectFalse(multimap.delete(2, 4), "Nothing was removed for key 2 and value 4.");
+ InspectorTest.expectFalse(multimap.delete(4, 1), "Nothing was removed for key 4 and value 1.");
+ InspectorTest.expectFalse(multimap.delete(4, 3), "Nothing was removed for key 4 and value 3.");
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.delete.NonExistingKeys",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add(0, 1);
+ multimap.add(2, 3);
+ multimap.add(4, 4);
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectFalse(multimap.delete(1), "Nothing was removed for key 1.");
+ InspectorTest.expectFalse(multimap.delete(3), "Nothing was removed for key 3.");
+ InspectorTest.expectFalse(multimap.delete(5), "Nothing was removed for key 5.");
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.delete.AllValuesForKey",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("opossum", "badger");
+ multimap.add("opossum", "raccoon");
+ multimap.add("raccoon", "opossum");
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectFalse(multimap.delete("badger"), `Nothing was removed for key "badger".`);
+
+ InspectorTest.log(multimap);
+
+ InspectorTest.expectThat(multimap.delete("opossum"), `Values were removed for key "opossum".`);
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.clear",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("one", "two");
+ multimap.add("three", "four");
+ multimap.add("one", "five");
+ multimap.add("three", "six");
+
+ InspectorTest.log(multimap);
+
+ multimap.clear();
+
+ InspectorTest.log(multimap);
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.keys",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("one", "two");
+ multimap.add("three", "four");
+ multimap.add("one", "five");
+ multimap.add("three", "six");
+
+ InspectorTest.log(multimap);
+ InspectorTest.log(Array.from(multimap.keys()));
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.values",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("one", "two");
+ multimap.add("three", "four");
+ multimap.add("one", "five");
+ multimap.add("three", "six");
+
+ InspectorTest.log(multimap);
+ InspectorTest.log(Array.from(multimap.values()));
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.sets",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("one", "two");
+ multimap.add("three", "four");
+ multimap.add("one", "five");
+ multimap.add("three", "six");
+
+ InspectorTest.log(multimap);
+ InspectorTest.log(Array.from(multimap.sets()).map(([key, value]) => [key, Array.from(value)]));
+ },
+ });
+
+ suite.addTestCase({
+ name: "Multimap.prototype.copy",
+ test() {
+ let multimap = new Multimap;
+
+ multimap.add("one", "two");
+ multimap.add("three", "four");
+
+ InspectorTest.log(multimap);
+
+ let copy = multimap.copy();
+
+ InspectorTest.expectNotEqual(multimap, copy, "Copy should not return the same object.")
+ InspectorTest.expectEqual(JSON.stringify(multimap), JSON.stringify(copy), "Copy should return a deep copy.");
+
+ multimap.add("five", "six");
+
+ InspectorTest.expectNotShallowEqual(multimap, copy, "Modifying the original should not modify the copy.");
+ },
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Testing all methods of Multimap.</p>
+</body>
+</html>
Modified: trunk/Source/WebInspectorUI/ChangeLog (243263 => 243264)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-03-21 00:22:06 UTC (rev 243264)
@@ -1,5 +1,61 @@
2019-03-20 Devin Rousso <[email protected]>
+ Web Inspector: Styles Redesign: Editing selector should not hide the rule
+ https://bugs.webkit.org/show_bug.cgi?id=178489
+ <rdar://problem/35062434>
+
+ Reviewed by Timothy Hatcher.
+
+ Extracts the selector payload parsing logic inside `WI.DOMNodeStyles` into static functions
+ so that when the user changes the selector of a `WI.CSSRule`, it's able to process and
+ update itself with the new selector. This is mainly useful in the case where the `WI.CSSRule`
+ no longer applies to the selected node (meaning it won't be part of that node's
+ `WI.DOMNodeStyles`) in that it allows the `WI.SpreadsheetCSSStyleDeclarationSection` to
+ display the new selector text and the owner `WI.SpreadsheetRulesStyleDetailsPanel` to keep
+ that section visible even though it isn't applicable to the current node anymore.
+
+ * UserInterface/Models/DOMNodeStyles.js:
+ (WI.DOMNodeStyles):
+ (WI.DOMNodeStyles.parseSelectorListPayload): Added.
+ (WI.DOMNodeStyles.createSourceCodeLocation): Added.
+ (WI.DOMNodeStyles.prototype.refresh):
+ (WI.DOMNodeStyles.prototype.refresh.fetchedMatchedStyles):
+ (WI.DOMNodeStyles.prototype.refresh.fetchedInlineStyles):
+ (WI.DOMNodeStyles.prototype.refresh.fetchedComputedStyle):
+ (WI.DOMNodeStyles.prototype._parseStyleDeclarationPayload):
+ (WI.DOMNodeStyles.prototype._parseRulePayload):
+ (WI.DOMNodeStyles.prototype._styleSheetContentDidChange):
+ (WI.DOMNodeStyles.prototype.refresh.parseRuleMatchArrayPayload): Deleted.
+ (WI.DOMNodeStyles.prototype._createSourceCodeLocation): Deleted.
+ (WI.DOMNodeStyles.prototype._parseSelectorListPayload): Deleted.
+ Keep track of all `WI.CSSRule` and `WI.CSSStyleDeclaration` that have ever been associated
+ with this object, so that if a rule's selector is changed to no longer match, and then is
+ changed back to match again, we are able to update that rule instead of creating a new one.
+
+ * UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js:
+ (WI.SpreadsheetRulesStyleDetailsPanel.prototype.layout):
+ (WI.SpreadsheetRulesStyleDetailsPanel.prototype._handleSectionFilterApplied):
+ (WI.SpreadsheetRulesStyleDetailsPanel.prototype._handleSectionSelectorWillChange): Added.
+ Attempt to preserve the position of any sections that are changed and no longer apply to the
+ current node.
+
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.spreadsheetSelectorFieldDidChange):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderSelector):
+ Drive-by: remove unused CSS classes.
+
+ * UserInterface/Models/CSSRule.js:
+ (WI.CSSRule.prototype.update):
+ (WI.CSSRule.prototype._selectorResolved):
+ Drive-by: remove unused event.
+
+ * UserInterface/Base/Multimap.js:
+ (Multimap.prototype.has): Added.
+ (Multimap.prototype.sets): Added.
+ (Multimap.prototype.copy): Added.
+
+2019-03-20 Devin Rousso <[email protected]>
+
Web Inspector: no way to filter out all console messages or all evaluations/results
https://bugs.webkit.org/show_bug.cgi?id=167035
<rdar://problem/30023523>
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Multimap.js (243263 => 243264)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Multimap.js 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Multimap.js 2019-03-21 00:22:06 UTC (rev 243264)
@@ -35,6 +35,14 @@
// Public
+ has(key, value)
+ {
+ let valueSet = this._map.get(key);
+ if (!valueSet)
+ return false;
+ return value === undefined || valueSet.has(value);
+ }
+
get(key)
{
return this._map.get(key);
@@ -88,6 +96,11 @@
}
}
+ sets()
+ {
+ return this._map.entries();
+ }
+
*[Symbol.iterator]()
{
for (let [key, valueSet] of this._map) {
@@ -96,6 +109,11 @@
}
}
+ copy()
+ {
+ return new Multimap(this.toJSON());
+ }
+
toJSON()
{
return Array.from(this);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSRule.js (243263 => 243264)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSRule.js 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSRule.js 2019-03-21 00:22:06 UTC (rev 243264)
@@ -55,7 +55,7 @@
return !!this._id && (this._type === WI.CSSStyleSheet.Type.Author || this._type === WI.CSSStyleSheet.Type.Inspector);
}
- update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList, dontFireEvents)
+ update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList)
{
sourceCodeLocation = sourceCodeLocation || null;
selectorText = selectorText || "";
@@ -64,14 +64,6 @@
style = style || null;
mediaList = mediaList || [];
- var changed = false;
- if (!dontFireEvents) {
- changed = this._selectorText !== selectorText || !Array.shallowEqual(this._selectors, selectors) ||
- !Array.shallowEqual(this._matchedSelectorIndices, matchedSelectorIndices) || this._style !== style ||
- !!this._sourceCodeLocation !== !!sourceCodeLocation || this._mediaList.length !== mediaList.length;
- // FIXME: Look for differences in the media list arrays.
- }
-
if (this._style)
this._style.ownerRule = null;
@@ -84,9 +76,6 @@
if (this._style)
this._style.ownerRule = this;
-
- if (changed)
- this.dispatchEventToListeners(WI.CSSRule.Event.Changed);
}
get type()
@@ -162,11 +151,36 @@
_selectorResolved(rulePayload)
{
+ if (rulePayload) {
+ let selectorText = rulePayload.selectorList.text;
+ if (selectorText !== this._selectorText) {
+ let selectors = WI.DOMNodeStyles.parseSelectorListPayload(rulePayload.selectorList);
+
+ let sourceCodeLocation = null;
+ let sourceRange = rulePayload.selectorList.range;
+ if (sourceRange) {
+ sourceCodeLocation = WI.DOMNodeStyles.createSourceCodeLocation(rulePayload.sourceURL, {
+ line: sourceRange.startLine,
+ column: sourceRange.startColumn,
+ documentNode: this._nodeStyles.node.ownerDocument,
+ });
+ }
+
+ if (this._ownerStyleSheet) {
+ if (!sourceCodeLocation && this._ownerStyleSheet.isInspectorStyleSheet())
+ sourceCodeLocation = this._ownerStyleSheet.createSourceCodeLocation(sourceRange.startLine, sourceRange.startColumn);
+
+ sourceCodeLocation = this._ownerStyleSheet.offsetSourceCodeLocation(sourceCodeLocation);
+ }
+
+ this.update(sourceCodeLocation, selectorText, selectors, [], this._style, this._mediaList);
+ }
+ }
+
this.dispatchEventToListeners(WI.CSSRule.Event.SelectorChanged, {valid: !!rulePayload});
}
};
WI.CSSRule.Event = {
- Changed: "css-rule-changed",
SelectorChanged: "css-rule-invalid-selector"
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js (243263 => 243264)
--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js 2019-03-21 00:22:06 UTC (rev 243264)
@@ -32,8 +32,8 @@
console.assert(node);
this._node = node || null;
- this._rulesMap = {};
- this._styleDeclarationsMap = {};
+ this._rulesMap = new Map;
+ this._stylesMap = new Multimap;
this._matchedRules = [];
this._inheritedRules = [];
@@ -51,6 +51,51 @@
// Static
+ static parseSelectorListPayload(selectorList)
+ {
+ let selectors = selectorList.selectors;
+ if (!selectors.length)
+ return [];
+
+ // COMPATIBILITY (iOS 8): The selectorList payload was an array of selector text strings.
+ // Now they are CSSSelector objects with multiple properties.
+ if (typeof selectors[0] === "string") {
+ return selectors.map(function(selectorText) {
+ return new WI.CSSSelector(selectorText);
+ });
+ }
+
+ return selectors.map(function(selectorPayload) {
+ return new WI.CSSSelector(selectorPayload.text, selectorPayload.specificity, selectorPayload.dynamic);
+ });
+ }
+
+ static createSourceCodeLocation(sourceURL, {line, column, documentNode} = {})
+ {
+ if (!sourceURL)
+ return null;
+
+ let sourceCode = null;
+
+ // Try to use the node to find the frame which has the correct resource first.
+ if (documentNode) {
+ let mainResource = WI.networkManager.resourceForURL(documentNode.documentURL);
+ if (mainResource) {
+ let parentFrame = mainResource.parentFrame;
+ sourceCode = parentFrame.resourceForURL(sourceURL);
+ }
+ }
+
+ // If that didn't find the resource, then search all frames.
+ if (!sourceCode)
+ sourceCode = WI.networkManager.resourceForURL(sourceURL);
+
+ if (!sourceCode)
+ return null;
+
+ return sourceCode.createSourceCodeLocation(line || 0, column || 0);
+ }
+
static uniqueOrderedStyles(orderedStyles)
{
let uniqueOrderedStyles = [];
@@ -104,6 +149,8 @@
this._needsRefresh = false;
+ let previousStylesMap = this._stylesMap.copy();
+
let fetchedMatchedStylesPromise = new WI.WrappedPromise;
let fetchedInlineStylesPromise = new WI.WrappedPromise;
let fetchedComputedStylesPromise = new WI.WrappedPromise;
@@ -120,14 +167,13 @@
};
}
- function parseRuleMatchArrayPayload(matchArray, node, inherited)
- {
+ let parseRuleMatchArrayPayload = (matchArray, node, inherited, pseudoId) => {
var result = [];
// Iterate in reverse order to match the cascade order.
var ruleOccurrences = {};
for (var i = matchArray.length - 1; i >= 0; --i) {
- var rule = this._parseRulePayload(matchArray[i].rule, matchArray[i].matchingSelectors, node, inherited, ruleOccurrences);
+ var rule = this._parseRulePayload(matchArray[i].rule, matchArray[i].matchingSelectors, node, inherited, pseudoId, ruleOccurrences);
if (!rule)
continue;
result.push(rule);
@@ -134,7 +180,7 @@
}
return result;
- }
+ };
function fetchedMatchedStyles(error, matchedRulesPayload, pseudoElementRulesPayload, inheritedRulesPayload)
{
@@ -142,20 +188,12 @@
pseudoElementRulesPayload = pseudoElementRulesPayload || [];
inheritedRulesPayload = inheritedRulesPayload || [];
- // Move the current maps to previous.
- this._previousRulesMap = this._rulesMap;
- this._previousStyleDeclarationsMap = this._styleDeclarationsMap;
+ this._matchedRules = parseRuleMatchArrayPayload(matchedRulesPayload, this._node);
- // Clear the current maps.
- this._rulesMap = {};
- this._styleDeclarationsMap = {};
-
- this._matchedRules = parseRuleMatchArrayPayload.call(this, matchedRulesPayload, this._node);
-
this._pseudoElements.clear();
- for (var pseudoElementRulePayload of pseudoElementRulesPayload) {
- var pseudoElementRules = parseRuleMatchArrayPayload.call(this, pseudoElementRulePayload.matches, this._node);
- this._pseudoElements.set(pseudoElementRulePayload.pseudoId, {matchedRules: pseudoElementRules});
+ for (let {pseudoId, matches} of pseudoElementRulesPayload) {
+ let pseudoElementRules = parseRuleMatchArrayPayload(matches, this._node, false, pseudoId);
+ this._pseudoElements.set(pseudoId, {matchedRules: pseudoElementRules});
}
this._inheritedRules = [];
@@ -166,8 +204,8 @@
var inheritedRulePayload = inheritedRulesPayload[i];
var inheritedRuleInfo = {node: currentNode};
- inheritedRuleInfo.inlineStyle = inheritedRulePayload.inlineStyle ? this._parseStyleDeclarationPayload(inheritedRulePayload.inlineStyle, currentNode, true, WI.CSSStyleDeclaration.Type.Inline) : null;
- inheritedRuleInfo.matchedRules = inheritedRulePayload.matchedCSSRules ? parseRuleMatchArrayPayload.call(this, inheritedRulePayload.matchedCSSRules, currentNode, true) : [];
+ inheritedRuleInfo.inlineStyle = inheritedRulePayload.inlineStyle ? this._parseStyleDeclarationPayload(inheritedRulePayload.inlineStyle, currentNode, true, null, WI.CSSStyleDeclaration.Type.Inline) : null;
+ inheritedRuleInfo.matchedRules = inheritedRulePayload.matchedCSSRules ? parseRuleMatchArrayPayload(inheritedRulePayload.matchedCSSRules, currentNode, true) : [];
if (inheritedRuleInfo.inlineStyle || inheritedRuleInfo.matchedRules.length)
this._inheritedRules.push(inheritedRuleInfo);
@@ -181,8 +219,8 @@
function fetchedInlineStyles(error, inlineStylePayload, attributesStylePayload)
{
- this._inlineStyle = inlineStylePayload ? this._parseStyleDeclarationPayload(inlineStylePayload, this._node, false, WI.CSSStyleDeclaration.Type.Inline) : null;
- this._attributesStyle = attributesStylePayload ? this._parseStyleDeclarationPayload(attributesStylePayload, this._node, false, WI.CSSStyleDeclaration.Type.Attribute) : null;
+ this._inlineStyle = inlineStylePayload ? this._parseStyleDeclarationPayload(inlineStylePayload, this._node, false, null, WI.CSSStyleDeclaration.Type.Inline) : null;
+ this._attributesStyle = attributesStylePayload ? this._parseStyleDeclarationPayload(attributesStylePayload, this._node, false, null, WI.CSSStyleDeclaration.Type.Attribute) : null;
this._updateStyleCascade();
@@ -210,18 +248,15 @@
this._computedStyle = new WI.CSSStyleDeclaration(this, null, null, WI.CSSStyleDeclaration.Type.Computed, this._node, false, null, properties);
let significantChange = false;
- for (let key in this._styleDeclarationsMap) {
- // Check if the same key exists in the previous map and has the same style objects.
- if (key in this._previousStyleDeclarationsMap) {
- if (Array.shallowEqual(this._styleDeclarationsMap[key], this._previousStyleDeclarationsMap[key]))
- continue;
-
+ for (let [key, styles] of this._stylesMap.sets()) {
+ let previousStyles = previousStylesMap.get(key);
+ if (previousStyles) {
// Some styles have selectors such that they will match with the DOM node twice (for example "::before, ::after").
// In this case a second style for a second matching may be generated and added which will cause the shallowEqual
// to not return true, so in this case we just want to ensure that all the current styles existed previously.
let styleFound = false;
- for (let style of this._styleDeclarationsMap[key]) {
- if (this._previousStyleDeclarationsMap[key].includes(style)) {
+ for (let style of styles) {
+ if (previousStyles.has(style)) {
styleFound = true;
break;
}
@@ -233,7 +268,7 @@
if (!this._includeUserAgentRulesOnNextRefresh) {
// We can assume all the styles with the same key are from the same stylesheet and rule, so we only check the first.
- let firstStyle = this._styleDeclarationsMap[key][0];
+ let firstStyle = styles.firstValue;
if (firstStyle && firstStyle.ownerRule && firstStyle.ownerRule.type === WI.CSSStyleSheet.Type.UserAgent) {
// User Agent styles get different identifiers after some edits. This would cause us to fire a significant refreshed
// event more than it is helpful. And since the user agent stylesheet is static it shouldn't match differently
@@ -248,14 +283,14 @@
}
if (!significantChange) {
- for (var key in this._previousStyleDeclarationsMap) {
+ for (let [key, previousStyles] of previousStylesMap.sets()) {
// Check if the same key exists in current map. If it does exist it was already checked for equality above.
- if (key in this._styleDeclarationsMap)
+ if (this._stylesMap.has(key))
continue;
if (!this._includeUserAgentRulesOnNextRefresh) {
// See above for why we skip user agent style rules.
- var firstStyle = this._previousStyleDeclarationsMap[key][0];
+ let firstStyle = previousStyles.firstValue;
if (firstStyle && firstStyle.ownerRule && firstStyle.ownerRule.type === WI.CSSStyleSheet.Type.UserAgent)
continue;
}
@@ -266,12 +301,8 @@
}
}
- delete this._includeUserAgentRulesOnNextRefresh;
+ this._includeUserAgentRulesOnNextRefresh = false
- // Delete the previous maps now that any reused rules and style have been moved over.
- delete this._previousRulesMap;
- delete this._previousStyleDeclarationsMap;
-
this.dispatchEventToListeners(WI.DOMNodeStyles.Event.Refreshed, {significantChange});
fetchedComputedStylesPromise.resolve();
@@ -480,32 +511,6 @@
// Private
- _createSourceCodeLocation(sourceURL, sourceLine, sourceColumn)
- {
- if (!sourceURL)
- return null;
-
- var sourceCode;
-
- // Try to use the node to find the frame which has the correct resource first.
- if (this._node.ownerDocument) {
- var mainResource = WI.networkManager.resourceForURL(this._node.ownerDocument.documentURL);
- if (mainResource) {
- var parentFrame = mainResource.parentFrame;
- sourceCode = parentFrame.resourceForURL(sourceURL);
- }
- }
-
- // If that didn't find the resource, then search all frames.
- if (!sourceCode)
- sourceCode = WI.networkManager.resourceForURL(sourceURL);
-
- if (!sourceCode)
- return null;
-
- return sourceCode.createSourceCodeLocation(sourceLine || 0, sourceColumn || 0);
- }
-
_parseSourceRangePayload(payload)
{
if (!payload)
@@ -590,7 +595,7 @@
return new WI.CSSProperty(index, text, name, value, priority, enabled, overridden, implicit, anonymous, valid, styleSheetTextRange);
}
- _parseStyleDeclarationPayload(payload, node, inherited, type, rule, updateAllStyles)
+ _parseStyleDeclarationPayload(payload, node, inherited, pseudoId, type, rule)
{
if (!payload)
return null;
@@ -600,61 +605,26 @@
var id = payload.styleId;
var mapKey = id ? id.styleSheetId + ":" + id.ordinal : null;
-
+ if (pseudoId)
+ mapKey += ":" + pseudoId;
if (type === WI.CSSStyleDeclaration.Type.Attribute)
- mapKey = node.id + ":attribute";
+ mapKey += ":" + node.id + ":attribute";
- var styleDeclaration = rule ? rule.style : null;
- var styleDeclarations = [];
+ let style = rule ? rule.style : null;
- // Look for existing styles in the previous map if there is one, otherwise use the current map.
- var previousStyleDeclarationsMap = this._previousStyleDeclarationsMap || this._styleDeclarationsMap;
- if (mapKey && mapKey in previousStyleDeclarationsMap) {
- styleDeclarations = previousStyleDeclarationsMap[mapKey];
-
- // If we need to update all styles, then stop here and call _parseStyleDeclarationPayload for each style.
- // We need to parse multiple times so we reuse the right properties from each style.
- if (updateAllStyles && styleDeclarations.length) {
- for (var i = 0; i < styleDeclarations.length; ++i) {
- var styleDeclaration = styleDeclarations[i];
- this._parseStyleDeclarationPayload(payload, styleDeclaration.node, styleDeclaration.inherited, styleDeclaration.type, styleDeclaration.ownerRule);
+ let existingStyles = this._stylesMap.get(mapKey);
+ if (existingStyles && !style) {
+ for (let existingStyle of existingStyles) {
+ if (existingStyle.node === node && existingStyle.inherited === inherited) {
+ style = existingStyle;
+ break;
}
-
- return null;
}
-
- if (!styleDeclaration) {
- var filteredStyleDeclarations = styleDeclarations.filter(function(styleDeclaration) {
- // This case only applies for styles that are not part of a rule.
- if (styleDeclaration.ownerRule) {
- console.assert(!rule);
- return false;
- }
-
- if (styleDeclaration.node !== node)
- return false;
-
- if (styleDeclaration.inherited !== inherited)
- return false;
-
- return true;
- });
-
- console.assert(filteredStyleDeclarations.length <= 1);
- styleDeclaration = filteredStyleDeclarations[0] || null;
- }
}
- if (previousStyleDeclarationsMap !== this._styleDeclarationsMap) {
- // If the previous and current maps differ then make sure the found styleDeclaration is added to the current map.
- styleDeclarations = mapKey && mapKey in this._styleDeclarationsMap ? this._styleDeclarationsMap[mapKey] : [];
+ if (style)
+ this._stylesMap.add(mapKey, style);
- if (styleDeclaration && !styleDeclarations.includes(styleDeclaration)) {
- styleDeclarations.push(styleDeclaration);
- this._styleDeclarationsMap[mapKey] = styleDeclarations;
- }
- }
-
var shorthands = {};
for (var i = 0; payload.shorthandEntries && i < payload.shorthandEntries.length; ++i) {
var shorthand = payload.shorthandEntries[i];
@@ -670,7 +640,7 @@
if (inherited && WI.CSSProperty.isInheritedPropertyName(propertyPayload.name))
++inheritedPropertyCount;
- let property = this._parseStylePropertyPayload(propertyPayload, i, styleDeclaration);
+ let property = this._parseStylePropertyPayload(propertyPayload, i, style);
properties.push(property);
}
@@ -677,9 +647,9 @@
let text = payload.cssText;
var styleSheetTextRange = this._parseSourceRangePayload(payload.range);
- if (styleDeclaration) {
- styleDeclaration.update(text, properties, styleSheetTextRange);
- return styleDeclaration;
+ if (style) {
+ style.update(text, properties, styleSheetTextRange);
+ return style;
}
var styleSheet = id ? WI.cssManager.styleSheetForIdentifier(id.styleSheetId) : null;
@@ -692,37 +662,16 @@
if (inherited && !inheritedPropertyCount)
return null;
- styleDeclaration = new WI.CSSStyleDeclaration(this, styleSheet, id, type, node, inherited, text, properties, styleSheetTextRange);
+ style = new WI.CSSStyleDeclaration(this, styleSheet, id, type, node, inherited, text, properties, styleSheetTextRange);
- if (mapKey) {
- styleDeclarations.push(styleDeclaration);
- this._styleDeclarationsMap[mapKey] = styleDeclarations;
- }
+ if (mapKey)
+ this._stylesMap.add(mapKey, style);
- return styleDeclaration;
+ return style;
}
- _parseSelectorListPayload(selectorList)
+ _parseRulePayload(payload, matchedSelectorIndices, node, inherited, pseudoId, ruleOccurrences)
{
- var selectors = selectorList.selectors;
- if (!selectors.length)
- return [];
-
- // COMPATIBILITY (iOS 8): The selectorList payload was an array of selector text strings.
- // Now they are CSSSelector objects with multiple properties.
- if (typeof selectors[0] === "string") {
- return selectors.map(function(selectorText) {
- return new WI.CSSSelector(selectorText);
- });
- }
-
- return selectors.map(function(selectorPayload) {
- return new WI.CSSSelector(selectorPayload.text, selectorPayload.specificity, selectorPayload.dynamic);
- });
- }
-
- _parseRulePayload(payload, matchedSelectorIndices, node, inherited, ruleOccurrences)
- {
if (!payload)
return null;
@@ -732,7 +681,7 @@
// editability solely based on the existence of the id like the open source front-end does.
var id = payload.ruleId || payload.style.styleId;
- var mapKey = id ? id.styleSheetId + ":" + id.ordinal + ":" + (inherited ? "I" : "N") + ":" + node.id : null;
+ var mapKey = id ? id.styleSheetId + ":" + id.ordinal + ":" + (inherited ? "I" : "N") + ":" + (pseudoId ? pseudoId + ":" : "") + node.id : null;
// Rules can match multiple times if they have multiple selectors or because of inheritance. We keep a count
// of occurrences so we have unique rules per occurrence, that way properties will be correctly marked as overridden.
@@ -747,20 +696,9 @@
mapKey += ":" + occurrence;
}
- var rule = null;
+ let rule = this._rulesMap.get(mapKey);
- // Look for existing rules in the previous map if there is one, otherwise use the current map.
- var previousRulesMap = this._previousRulesMap || this._rulesMap;
- if (mapKey && mapKey in previousRulesMap) {
- rule = previousRulesMap[mapKey];
-
- if (previousRulesMap !== this._rulesMap) {
- // If the previous and current maps differ then make sure the found rule is added to the current map.
- this._rulesMap[mapKey] = rule;
- }
- }
-
- var style = this._parseStyleDeclarationPayload(payload.style, node, inherited, WI.CSSStyleDeclaration.Type.Rule, rule);
+ var style = this._parseStyleDeclarationPayload(payload.style, node, inherited, pseudoId, WI.CSSStyleDeclaration.Type.Rule, rule);
if (!style)
return null;
@@ -767,16 +705,23 @@
var styleSheet = id ? WI.cssManager.styleSheetForIdentifier(id.styleSheetId) : null;
var selectorText = payload.selectorList.text;
- var selectors = this._parseSelectorListPayload(payload.selectorList);
+ let selectors = DOMNodeStyles.parseSelectorListPayload(payload.selectorList);
var type = WI.CSSManager.protocolStyleSheetOriginToEnum(payload.origin);
var sourceCodeLocation = null;
var sourceRange = payload.selectorList.range;
- if (sourceRange)
- sourceCodeLocation = this._createSourceCodeLocation(payload.sourceURL, sourceRange.startLine, sourceRange.startColumn);
- else {
+ if (sourceRange) {
+ sourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(payload.sourceURL, {
+ line: sourceRange.startLine,
+ column: sourceRange.startColumn,
+ documentNode: this._node.ownerDocument,
+ });
+ } else {
// FIXME: Is it possible for a CSSRule to have a sourceLine without its selectorList having a sourceRange? Fall back just in case.
- sourceCodeLocation = this._createSourceCodeLocation(payload.sourceURL, payload.sourceLine);
+ sourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(payload.sourceURL, {
+ line: payload.sourceLine,
+ documentNode: this._node.ownerDocument,
+ });
}
if (styleSheet) {
@@ -791,7 +736,7 @@
var mediaItem = payload.media[i];
var mediaType = WI.CSSManager.protocolMediaSourceToEnum(mediaItem.source);
var mediaText = mediaItem.text;
- var mediaSourceCodeLocation = this._createSourceCodeLocation(mediaItem.sourceURL, mediaItem.sourceLine);
+ let mediaSourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(mediaItem.sourceURL, {line: mediaItem.sourceLine});
if (styleSheet)
mediaSourceCodeLocation = styleSheet.offsetSourceCodeLocation(mediaSourceCodeLocation);
@@ -809,7 +754,7 @@
rule = new WI.CSSRule(this, styleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList);
if (mapKey)
- this._rulesMap[mapKey] = rule;
+ this._rulesMap.set(mapKey, rule);
return rule;
}
@@ -829,7 +774,7 @@
// Ignore the stylesheet we know we just changed and handled above.
if (styleSheet === this._ignoreNextContentDidChangeForStyleSheet) {
- delete this._ignoreNextContentDidChangeForStyleSheet;
+ this._ignoreNextContentDidChangeForStyleSheet = null;
return;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js (243263 => 243264)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2019-03-21 00:22:06 UTC (rev 243264)
@@ -174,6 +174,7 @@
if (!selectorText || selectorText === this._style.ownerRule.selectorText)
this._discardSelectorChange();
else {
+ this.dispatchEventToListeners(WI.SpreadsheetCSSStyleDeclarationSection.Event.SelectorWillChange);
this._style.ownerRule.singleFireEventListener(WI.CSSRule.Event.SelectorChanged, this._renderSelector, this);
this._style.ownerRule.selectorText = selectorText;
}
@@ -302,18 +303,12 @@
var selectors = this._style.ownerRule.selectors;
var matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices;
- var alwaysMatch = !matchedSelectorIndices.length;
if (selectors.length) {
- let hasMatchingPseudoElementSelector = false;
for (let i = 0; i < selectors.length; ++i) {
- appendSelector(selectors[i], alwaysMatch || matchedSelectorIndices.includes(i));
+ appendSelector(selectors[i], matchedSelectorIndices.includes(i));
if (i < selectors.length - 1)
this._selectorElement.append(", ");
-
- if (matchedSelectorIndices.includes(i) && selectors[i].isPseudoElementSelector())
- hasMatchingPseudoElementSelector = true;
}
- this._element.classList.toggle("pseudo-element-selector", hasMatchingPseudoElementSelector);
} else
appendSelectorTextKnownToMatch(this._style.ownerRule.selectorText);
@@ -544,6 +539,7 @@
WI.SpreadsheetCSSStyleDeclarationSection.Event = {
FilterApplied: "spreadsheet-css-style-declaration-section-filter-applied",
+ SelectorWillChange: "spreadsheet-css-style-declaration-section-selector-will-change",
};
WI.SpreadsheetCSSStyleDeclarationSection.MatchedSelectorElementStyleClassName = "matched";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js (243263 => 243264)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js 2019-03-21 00:14:04 UTC (rev 243263)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js 2019-03-21 00:22:06 UTC (rev 243264)
@@ -214,57 +214,88 @@
this._shouldRefreshSubviews = false;
- this.removeAllSubviews();
+ let oldSections = this._sections.slice();
+ let preservedSections = oldSections.filter((section) => {
+ if (section[SpreadsheetRulesStyleDetailsPanel.SectionShowingForNodeSymbol] !== this.nodeStyles.node) {
+ section[SpreadsheetRulesStyleDetailsPanel.SectionShowingForNodeSymbol] = null;
+ section[SpreadsheetRulesStyleDetailsPanel.SectionIndexSymbol] = -1;
+ }
+ return section[SpreadsheetRulesStyleDetailsPanel.SectionShowingForNodeSymbol];
+ });
+ if (preservedSections.length) {
+ for (let section of oldSections) {
+ if (!preservedSections.includes(section))
+ this.removeSubview(section);
+ }
+ for (let header of this._headerMap.values())
+ header.remove();
+ } else
+ this.removeAllSubviews();
+
let previousStyle = null;
+ let currentHeader = null;
this._headerMap.clear();
this._sections = [];
- let createHeader = (text, nodeOrPseudoId) => {
- let header = this.element.appendChild(document.createElement("h2"));
- header.classList.add("section-header");
- header.append(text);
+ let addHeader = (text, nodeOrPseudoId) => {
+ currentHeader = this.element.appendChild(document.createElement("h2"));
+ currentHeader.classList.add("section-header");
+ currentHeader.append(text);
if (nodeOrPseudoId) {
if (nodeOrPseudoId instanceof WI.DOMNode) {
- header.append(" ", WI.linkifyNodeReference(nodeOrPseudoId, {
+ currentHeader.append(" ", WI.linkifyNodeReference(nodeOrPseudoId, {
maxLength: 100,
excludeRevealElement: true,
}));
} else
- header.append(" ", WI.CSSManager.displayNameForPseudoId(nodeOrPseudoId));
+ currentHeader.append(" ", WI.CSSManager.displayNameForPseudoId(nodeOrPseudoId));
+ }
+ };
- this._headerMap.set(nodeOrPseudoId, header);
+ let addSection = (section) => {
+ if (section.style.inherited && (!previousStyle || previousStyle.node !== section.style.node))
+ addHeader(WI.UIString("Inherited From"), section.style.node);
+
+ if (!section.isDescendantOf(this)) {
+ let referenceView = this.subviews[this._sections.length];
+ if (!referenceView || referenceView[SpreadsheetRulesStyleDetailsPanel.SectionIndexSymbol] === this._sections.length)
+ this.addSubview(section);
+ else
+ this.insertSubviewBefore(section, referenceView);
}
+
+ this._sections.push(section);
+ section.needsLayout();
+
+ if (currentHeader)
+ this._headerMap.set(section.style, currentHeader);
+
+ previousStyle = section.style;
};
let createSection = (style) => {
- let section = style[WI.SpreadsheetRulesStyleDetailsPanel.RuleSection];
+ let section = style[SpreadsheetRulesStyleDetailsPanel.StyleSectionSymbol];
if (!section) {
section = new WI.SpreadsheetCSSStyleDeclarationSection(this, style);
- style[WI.SpreadsheetRulesStyleDetailsPanel.RuleSection] = section;
+ section.addEventListener(WI.SpreadsheetCSSStyleDeclarationSection.Event.FilterApplied, this._handleSectionFilterApplied, this);
+ section.addEventListener(WI.SpreadsheetCSSStyleDeclarationSection.Event.SelectorWillChange, this._handleSectionSelectorWillChange, this);
+ style[SpreadsheetRulesStyleDetailsPanel.StyleSectionSymbol] = section;
}
- section.addEventListener(WI.SpreadsheetCSSStyleDeclarationSection.Event.FilterApplied, this._handleSectionFilterApplied, this);
-
if (this._newRuleSelector === style.selectorText && style.enabledProperties.length === 0)
section.startEditingRuleSelector();
- this.addSubview(section);
- section.needsLayout();
- this._sections.push(section);
+ addSection(section);
- previousStyle = style;
-
- return section;
+ let preservedSection = preservedSections.find((sectionToPreserve) => sectionToPreserve[SpreadsheetRulesStyleDetailsPanel.SectionIndexSymbol] === this._sections.length - 1);
+ if (preservedSection)
+ addSection(preservedSection);
};
- for (let style of this.nodeStyles.uniqueOrderedStyles) {
- if (style.inherited && (!previousStyle || previousStyle.node !== style.node))
- createHeader(WI.UIString("Inherited From"), style.node);
-
+ for (let style of this.nodeStyles.uniqueOrderedStyles)
createSection(style);
- }
let beforePseudoId = null;
let afterPseudoId = null;
@@ -277,23 +308,17 @@
afterPseudoId = 5;
}
+
for (let [pseudoId, pseudoElementInfo] of this.nodeStyles.pseudoElements) {
- let nodeOrPseudoId = null;
+ let pseudoElement = null;
if (pseudoId === beforePseudoId)
- nodeOrPseudoId = this.nodeStyles.node.beforePseudoElement();
+ pseudoElement = this.nodeStyles.node.beforePseudoElement();
else if (pseudoId === afterPseudoId)
- nodeOrPseudoId = this.nodeStyles.node.afterPseudoElement();
- else
- nodeOrPseudoId = pseudoId;
+ pseudoElement = this.nodeStyles.node.afterPseudoElement();
+ addHeader(WI.UIString("Pseudo-Element"), pseudoElement || pseudoId);
- createHeader(WI.UIString("Pseudo-Element"), nodeOrPseudoId);
-
- for (let style of WI.DOMNodeStyles.uniqueOrderedStyles(pseudoElementInfo.orderedStyles)) {
- let section = createSection(style);
-
- if (nodeOrPseudoId === pseudoId)
- section.__pseudoId = pseudoId;
- }
+ for (let style of WI.DOMNodeStyles.uniqueOrderedStyles(pseudoElementInfo.orderedStyles))
+ createSection(style);
}
this._newRuleSelector = null;
@@ -320,7 +345,7 @@
this.element.classList.remove("filter-non-matching");
- let header = this._headerMap.get(event.target.__pseudoId || event.target.style.node);
+ let header = this._headerMap.get(event.target.style);
if (header)
header.classList.remove(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);
}
@@ -335,6 +360,16 @@
const text = "";
this.nodeStyles.addRule(this._newRuleSelector, text, stylesheetId);
}
+
+ _handleSectionSelectorWillChange(event)
+ {
+ let section = event.target;
+ section[SpreadsheetRulesStyleDetailsPanel.SectionShowingForNodeSymbol] = this.nodeStyles.node;
+ section[SpreadsheetRulesStyleDetailsPanel.SectionIndexSymbol] = this._sections.indexOf(section);
+ console.assert(section[SpreadsheetRulesStyleDetailsPanel.SectionIndexSymbol] >= 0);
+ }
};
-WI.SpreadsheetRulesStyleDetailsPanel.RuleSection = Symbol("rule-section");
+WI.SpreadsheetRulesStyleDetailsPanel.StyleSectionSymbol = Symbol("style-section");
+WI.SpreadsheetRulesStyleDetailsPanel.SectionShowingForNodeSymbol = Symbol("style-showing-for-node");
+WI.SpreadsheetRulesStyleDetailsPanel.SectionIndexSymbol = Symbol("style-index");