summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc112
1 files changed, 103 insertions, 9 deletions
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
index bf07c43d7b3..5c70b1ea1ed 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -27,6 +27,7 @@
#include <algorithm>
#include "third_party/blink/renderer/bindings/core/v8/script_regexp.h"
+#include "third_party/blink/renderer/core/css/css_container_rule.h"
#include "third_party/blink/renderer/core/css/css_import_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
@@ -482,6 +483,47 @@ bool VerifyMediaText(Document* document, const String& media_text) {
return true;
}
+bool VerifyContainerQueryText(Document* document,
+ const String& container_query_text) {
+ DEFINE_STATIC_LOCAL(String, bogus_property_name, ("-webkit-boguz-propertee"));
+ auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(
+ ParserContextForDocument(document));
+ CSSRuleSourceDataList* source_data =
+ MakeGarbageCollected<CSSRuleSourceDataList>();
+ String text = "@container " + container_query_text + " { div { " +
+ bogus_property_name + ": none; } }";
+ StyleSheetHandler handler(text, document, source_data);
+ CSSParser::ParseSheetForInspector(ParserContextForDocument(document),
+ style_sheet, text, handler);
+
+ // TODO(crbug.com/1146422): for now these checks are identical to
+ // those for media queries. We should enforce container-query-specific
+ // checks once the spec is finalized.
+ // Exactly one container rule should be parsed.
+ unsigned rule_count = source_data->size();
+ if (rule_count != 1 || source_data->at(0)->type != StyleRule::kContainer)
+ return false;
+
+ // Container rule should have exactly one style rule child.
+ CSSRuleSourceDataList& child_source_data = source_data->at(0)->child_rules;
+ rule_count = child_source_data.size();
+ if (rule_count != 1 || !child_source_data.at(0)->HasProperties())
+ return false;
+
+ // Exactly one property should be in style rule.
+ Vector<CSSPropertySourceData>& property_data =
+ child_source_data.at(0)->property_data;
+ unsigned property_count = property_data.size();
+ if (property_count != 1)
+ return false;
+
+ // Check for the property name.
+ if (property_data.at(0).name != bogus_property_name)
+ return false;
+
+ return true;
+}
+
void FlattenSourceData(const CSSRuleSourceDataList& data_list,
CSSRuleSourceDataList* result) {
for (CSSRuleSourceData* data : data_list) {
@@ -499,6 +541,7 @@ void FlattenSourceData(const CSSRuleSourceDataList& data_list,
case StyleRule::kMedia:
case StyleRule::kSupports:
case StyleRule::kKeyframes:
+ case StyleRule::kContainer:
result->push_back(data);
FlattenSourceData(data->child_rules, result);
break;
@@ -521,6 +564,9 @@ CSSRuleList* AsCSSRuleList(CSSRule* rule) {
if (auto* keyframes_rule = DynamicTo<CSSKeyframesRule>(rule))
return keyframes_rule->cssRules();
+ if (auto* container_rule = DynamicTo<CSSContainerRule>(rule))
+ return container_rule->cssRules();
+
return nullptr;
}
@@ -547,6 +593,7 @@ void CollectFlatRules(RuleList rule_list, CSSRuleVector* result) {
case CSSRule::kMediaRule:
case CSSRule::kSupportsRule:
case CSSRule::kKeyframesRule:
+ case CSSRule::kContainerRule:
result->push_back(rule);
CollectFlatRules(AsCSSRuleList(rule), result);
break;
@@ -775,22 +822,15 @@ bool InspectorStyle::TextForRange(const SourceRange& range, String* result) {
void InspectorStyle::PopulateAllProperties(
Vector<CSSPropertySourceData>& result) {
- HashSet<String> source_property_names;
-
if (source_data_ && source_data_->HasProperties()) {
Vector<CSSPropertySourceData>& source_property_data =
source_data_->property_data;
- for (const auto& data : source_property_data) {
+ for (const auto& data : source_property_data)
result.push_back(data);
- source_property_names.insert(data.name.DeprecatedLower());
- }
}
for (int i = 0, size = style_->length(); i < size; ++i) {
String name = style_->item(i);
- if (!source_property_names.insert(name.DeprecatedLower()).is_new_entry)
- continue;
-
if (!IsValidCSSPropertyID(
CssPropertyID(style_->GetExecutionContext(), name)))
continue;
@@ -1165,6 +1205,47 @@ CSSMediaRule* InspectorStyleSheet::SetMediaRuleText(
return media_rule;
}
+CSSContainerRule* InspectorStyleSheet::SetContainerRuleText(
+ const SourceRange& range,
+ const String& text,
+ SourceRange* new_range,
+ String* old_text,
+ ExceptionState& exception_state) {
+ if (!VerifyContainerQueryText(page_style_sheet_->OwnerDocument(), text)) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "Selector or container query text is not valid.");
+ return nullptr;
+ }
+
+ CSSRuleSourceData* source_data = FindRuleByHeaderRange(range);
+ if (!source_data || !source_data->HasContainer()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotFoundError,
+ "Source range didn't match existing source range");
+ return nullptr;
+ }
+
+ CSSRule* rule = RuleForSourceData(source_data);
+ if (!rule || !rule->parentStyleSheet() ||
+ rule->GetType() != CSSRule::kContainerRule) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotFoundError,
+ "CQ Source range didn't match existing style source range");
+ return nullptr;
+ }
+
+ CSSContainerRule* container_rule =
+ InspectorCSSAgent::AsCSSContainerRule(rule);
+ container_rule->container()->setMediaText(
+ page_style_sheet_->OwnerDocument()->GetExecutionContext(), text);
+
+ ReplaceText(source_data->rule_header_range, text, new_range, old_text);
+ OnStyleSheetTextChanged();
+
+ return container_rule;
+}
+
CSSRuleSourceData* InspectorStyleSheet::RuleSourceDataAfterSourceRange(
const SourceRange& source_range) {
DCHECK(source_data_);
@@ -1532,12 +1613,25 @@ InspectorStyleSheet::BuildObjectForStyleSheetInfo() {
text_length, *line_endings, start);
}
+ // DevTools needs to be able to distinguish between constructed
+ // stylesheets created with `new` and constructed stylesheets
+ // imported as a CSS module. Only the latter have a separate
+ // source file to display.
+ // For constructed stylesheets created with `new`, Url()
+ // returns the URL of the document in which the sheet was created,
+ // which may confuse the client. Only set the URL if we have a
+ // proper URL of the source of the stylesheet.
+ const String& source_url =
+ (style_sheet->IsConstructed() && !style_sheet->IsForCSSModuleScript())
+ ? String()
+ : Url();
+
std::unique_ptr<protocol::CSS::CSSStyleSheetHeader> result =
protocol::CSS::CSSStyleSheetHeader::create()
.setStyleSheetId(Id())
.setOrigin(origin_)
.setDisabled(style_sheet->disabled())
- .setSourceURL(Url())
+ .setSourceURL(source_url)
.setTitle(style_sheet->title())
.setFrameId(frame ? IdentifiersFactory::FrameId(frame) : "")
.setIsInline(style_sheet->IsInline() && !StartsAtZero())