Bug 1899533 - [devtools] Add InspectorUtils method to validate a value against a given syntax. r=emilio.

Differential Revision: https://phabricator.services.mozilla.com/D211975
This commit is contained in:
Nicolas Chevobbe 2024-06-03 19:53:00 +00:00
parent 541fb3e8a1
commit 08e9a99b4c
6 changed files with 90 additions and 0 deletions

View File

@ -90,6 +90,7 @@ namespace InspectorUtils {
[NewObject] NodeList getOverflowingChildrenOfElement(Element element); [NewObject] NodeList getOverflowingChildrenOfElement(Element element);
sequence<DOMString> getRegisteredCssHighlights(Document document, optional boolean activeOnly = false); sequence<DOMString> getRegisteredCssHighlights(Document document, optional boolean activeOnly = false);
sequence<InspectorCSSPropertyDefinition> getCSSRegisteredProperties(Document document); sequence<InspectorCSSPropertyDefinition> getCSSRegisteredProperties(Document document);
boolean valueMatchesSyntax(Document document, UTF8String value, UTF8String syntax);
// Get the first rule body text within initialText // Get the first rule body text within initialText
// Consider the following example: // Consider the following example:

View File

@ -1006,6 +1006,14 @@ void InspectorUtils::GetCSSRegisteredProperties(
} }
} }
/* static */
bool InspectorUtils::ValueMatchesSyntax(GlobalObject&, Document& aDocument,
const nsACString& aValue,
const nsACString& aSyntax) {
return Servo_Value_Matches_Syntax(&aValue, &aSyntax,
aDocument.DefaultStyleAttrURLData());
}
/* static */ /* static */
void InspectorUtils::GetRuleBodyText(GlobalObject&, void InspectorUtils::GetRuleBodyText(GlobalObject&,
const nsACString& aInitialText, const nsACString& aInitialText,

View File

@ -271,6 +271,13 @@ class InspectorUtils {
GlobalObject& aGlobal, Document& aDocument, GlobalObject& aGlobal, Document& aDocument,
nsTArray<InspectorCSSPropertyDefinition>& aResult); nsTArray<InspectorCSSPropertyDefinition>& aResult);
/**
* Returns whether or not a CSS property value is valid for the passed syntax
*/
static bool ValueMatchesSyntax(GlobalObject&, Document& aDocument,
const nsACString& aValue,
const nsACString& aSyntax);
/** /**
* Get the rule body text within aInitialText * Get the rule body text within aInitialText
*/ */

View File

@ -88,3 +88,5 @@ skip-if = ["os == 'android'"]
["test_selectormatcheselement.html"] ["test_selectormatcheselement.html"]
["test_supports.html"] ["test_supports.html"]
["test_valueMatchesSyntax.html"]

View File

@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test InspectorUtils.valueMatchesSyntax</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<code>InspectorUtils.valueMatchesSyntax</code>
<script>
add_task(async function() {
const test = (value, syntax, expected) =>
is(
SpecialPowers.InspectorUtils.valueMatchesSyntax(document, value, syntax),
expected,
`"${value}" ${expected ? "matches" : "does not match"} "${syntax}"`
);
test("red", "<color>", true);
test("10px", "<color>", false);
test("10px", "<color> | <length>", true);
test("10px 1em", "<length>+", true);
test("10px, 1em", "<length>+", false);
test("10px, 1em", "<length>#", true);
test("10px 1em", "<length>#", false);
test("calc(100% - 20px)", "<length>", false);
test("calc(100% - 20px)", "<length-percentage>", true);
test("big", "big | bigger | BIGGER", true);
test("bigger", "big | bigger | BIGGER", true);
test("BIGGER", "big | bigger | BIGGER", true);
test("BIG", "big | bigger | BIGGER", false);
test("red", "<invalid-syntax>", false);
test("whatever 10px, 1em red", "*", true);
});
</script>
</body>
</html>

View File

@ -9113,6 +9113,40 @@ pub extern "C" fn Servo_GetRegisteredCustomProperties(
} }
} }
#[no_mangle]
pub unsafe extern "C" fn Servo_Value_Matches_Syntax(
value: &nsACString,
syntax: &nsACString,
extra_data: *mut URLExtraData,
) -> bool {
use style::properties_and_values::syntax::Descriptor;
use style::properties_and_values::value::{
AllowComputationallyDependent,
SpecifiedValue,
};
// Attempt to consume a syntax definition from syntax.
let syntax = unsafe { syntax.as_str_unchecked() };
let Ok(syntax) = Descriptor::from_str(syntax, /* preserve_specified = */ false) else {
return false;
};
let css_text = unsafe { value.as_str_unchecked() };
let mut input = ParserInput::new(css_text);
let mut input = Parser::new(&mut input);
input.skip_whitespace();
let url_data = unsafe { UrlExtraData::from_ptr_ref(&extra_data) };
SpecifiedValue::parse(
&mut input,
&syntax,
url_data,
AllowComputationallyDependent::Yes,
).is_ok()
}
#[repr(C)] #[repr(C)]
pub struct SelectorWarningData { pub struct SelectorWarningData {
/// Index to the selector generating the warning. /// Index to the selector generating the warning.