OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/css/ActiveStyleSheets.h" | 5 #include "core/css/ActiveStyleSheets.h" |
6 | 6 |
7 #include "core/css/CSSStyleSheet.h" | 7 #include "core/css/CSSStyleSheet.h" |
8 #include "core/css/RuleSet.h" | 8 #include "core/css/RuleSet.h" |
9 #include "core/css/resolver/ScopedStyleResolver.h" | 9 #include "core/css/resolver/ScopedStyleResolver.h" |
10 #include "core/dom/ContainerNode.h" | 10 #include "core/dom/ContainerNode.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 index++) { | 30 index++) { |
31 if (new_style_sheets[index].second == old_style_sheets[index].second) | 31 if (new_style_sheets[index].second == old_style_sheets[index].second) |
32 continue; | 32 continue; |
33 | 33 |
34 if (new_style_sheets[index].second) | 34 if (new_style_sheets[index].second) |
35 changed_rule_sets.insert(new_style_sheets[index].second); | 35 changed_rule_sets.insert(new_style_sheets[index].second); |
36 if (old_style_sheets[index].second) | 36 if (old_style_sheets[index].second) |
37 changed_rule_sets.insert(old_style_sheets[index].second); | 37 changed_rule_sets.insert(old_style_sheets[index].second); |
38 } | 38 } |
39 | 39 |
| 40 // If we add a sheet for which the media attribute currently doesn't match, we |
| 41 // have a null RuleSet and there's no need to do any style invalidation. |
| 42 // However, we need to tell the StyleEngine to re-collect viewport and device |
| 43 // dependent media query results so that we can correctly update active style |
| 44 // sheets when such media query evaluations change. |
| 45 bool adds_non_matching_mq = false; |
| 46 |
40 if (index == old_style_sheet_count) { | 47 if (index == old_style_sheet_count) { |
41 // The old stylesheet vector is a prefix of the new vector in terms of | 48 // The old stylesheet vector is a prefix of the new vector in terms of |
42 // StyleSheets. If none of the RuleSets changed, we only need to add the new | 49 // StyleSheets. If none of the RuleSets changed, we only need to add the new |
43 // sheets to the ScopedStyleResolver (ActiveSheetsAppended). | 50 // sheets to the ScopedStyleResolver (ActiveSheetsAppended). |
44 bool rule_sets_changed_in_common_prefix = !changed_rule_sets.IsEmpty(); | 51 bool rule_sets_changed_in_common_prefix = !changed_rule_sets.IsEmpty(); |
45 for (; index < new_style_sheet_count; index++) { | 52 for (; index < new_style_sheet_count; index++) { |
46 if (new_style_sheets[index].second) | 53 if (new_style_sheets[index].second) |
47 changed_rule_sets.insert(new_style_sheets[index].second); | 54 changed_rule_sets.insert(new_style_sheets[index].second); |
| 55 else if (new_style_sheets[index].first->HasMediaQueryResults()) |
| 56 adds_non_matching_mq = true; |
48 } | 57 } |
49 if (rule_sets_changed_in_common_prefix) | 58 if (rule_sets_changed_in_common_prefix) |
50 return kActiveSheetsChanged; | 59 return kActiveSheetsChanged; |
51 if (changed_rule_sets.IsEmpty()) | 60 if (changed_rule_sets.IsEmpty() && !adds_non_matching_mq) |
52 return kNoActiveSheetsChanged; | 61 return kNoActiveSheetsChanged; |
53 return kActiveSheetsAppended; | 62 return kActiveSheetsAppended; |
54 } | 63 } |
55 | 64 |
56 if (index == new_style_sheet_count) { | 65 if (index == new_style_sheet_count) { |
57 // Sheets removed from the end. | 66 // Sheets removed from the end. |
58 for (; index < old_style_sheet_count; index++) { | 67 for (; index < old_style_sheet_count; index++) { |
59 if (old_style_sheets[index].second) | 68 if (old_style_sheets[index].second) |
60 changed_rule_sets.insert(old_style_sheets[index].second); | 69 changed_rule_sets.insert(old_style_sheets[index].second); |
| 70 else if (old_style_sheets[index].first->HasMediaQueryResults()) |
| 71 adds_non_matching_mq = true; |
61 } | 72 } |
62 return changed_rule_sets.IsEmpty() ? kNoActiveSheetsChanged | 73 return changed_rule_sets.IsEmpty() && !adds_non_matching_mq |
63 : kActiveSheetsChanged; | 74 ? kNoActiveSheetsChanged |
| 75 : kActiveSheetsChanged; |
64 } | 76 } |
65 | 77 |
66 DCHECK_LT(index, old_style_sheet_count); | 78 DCHECK_LT(index, old_style_sheet_count); |
67 DCHECK_LT(index, new_style_sheet_count); | 79 DCHECK_LT(index, new_style_sheet_count); |
68 | 80 |
69 // Both the new and old active stylesheet vectors have stylesheets following | 81 // Both the new and old active stylesheet vectors have stylesheets following |
70 // the common prefix. Figure out which were added or removed by sorting the | 82 // the common prefix. Figure out which were added or removed by sorting the |
71 // merged vector of old and new sheets. | 83 // merged vector of old and new sheets. |
72 | 84 |
73 ActiveStyleSheetVector merged_sorted; | 85 ActiveStyleSheetVector merged_sorted; |
74 merged_sorted.ReserveCapacity(old_style_sheet_count + new_style_sheet_count - | 86 merged_sorted.ReserveCapacity(old_style_sheet_count + new_style_sheet_count - |
75 2 * index); | 87 2 * index); |
76 merged_sorted.AppendRange(old_style_sheets.begin() + index, | 88 merged_sorted.AppendRange(old_style_sheets.begin() + index, |
77 old_style_sheets.end()); | 89 old_style_sheets.end()); |
78 merged_sorted.AppendRange(new_style_sheets.begin() + index, | 90 merged_sorted.AppendRange(new_style_sheets.begin() + index, |
79 new_style_sheets.end()); | 91 new_style_sheets.end()); |
80 | 92 |
81 std::sort(merged_sorted.begin(), merged_sorted.end()); | 93 std::sort(merged_sorted.begin(), merged_sorted.end()); |
82 | 94 |
83 auto merged_iterator = merged_sorted.begin(); | 95 auto merged_iterator = merged_sorted.begin(); |
84 while (merged_iterator != merged_sorted.end()) { | 96 while (merged_iterator != merged_sorted.end()) { |
85 const auto& sheet1 = *merged_iterator++; | 97 const auto& sheet1 = *merged_iterator++; |
86 if (merged_iterator == merged_sorted.end() || | 98 if (merged_iterator == merged_sorted.end() || |
87 (*merged_iterator).first != sheet1.first) { | 99 (*merged_iterator).first != sheet1.first) { |
88 // Sheet either removed or inserted. | 100 // Sheet either removed or inserted. |
89 if (sheet1.second) | 101 if (sheet1.second) |
90 changed_rule_sets.insert(sheet1.second); | 102 changed_rule_sets.insert(sheet1.second); |
| 103 else if (sheet1.first->HasMediaQueryResults()) |
| 104 adds_non_matching_mq = true; |
91 continue; | 105 continue; |
92 } | 106 } |
93 | 107 |
94 // Sheet present in both old and new. | 108 // Sheet present in both old and new. |
95 const auto& sheet2 = *merged_iterator++; | 109 const auto& sheet2 = *merged_iterator++; |
96 | 110 |
97 if (sheet1.second == sheet2.second) | 111 if (sheet1.second == sheet2.second) |
98 continue; | 112 continue; |
99 | 113 |
100 // Active rules for the given stylesheet changed. | 114 // Active rules for the given stylesheet changed. |
101 // DOM, CSSOM, or media query changes. | 115 // DOM, CSSOM, or media query changes. |
102 if (sheet1.second) | 116 if (sheet1.second) |
103 changed_rule_sets.insert(sheet1.second); | 117 changed_rule_sets.insert(sheet1.second); |
104 if (sheet2.second) | 118 if (sheet2.second) |
105 changed_rule_sets.insert(sheet2.second); | 119 changed_rule_sets.insert(sheet2.second); |
106 } | 120 } |
107 return changed_rule_sets.IsEmpty() ? kNoActiveSheetsChanged | 121 return changed_rule_sets.IsEmpty() && !adds_non_matching_mq |
108 : kActiveSheetsChanged; | 122 ? kNoActiveSheetsChanged |
| 123 : kActiveSheetsChanged; |
109 } | 124 } |
110 | 125 |
111 } // namespace blink | 126 } // namespace blink |
OLD | NEW |