mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
script: Implement Sanitizer.get() method (#44452)
Implement the `Sanitizer.get()` method. Same as the previous patches on Sanitizer API, the steps related to processing instructions are marked as TODO. Support for process instructions was recently added to the specification, and we will implement it later when tests are ready. Testing: Covered by WPT tests in `sanitizer-api/sanitizer-get.tentative.html` Fixes: Part of #43948 Signed-off-by: Kingsley Yung <kingsley@kkoyung.dev>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
@@ -109,11 +110,84 @@ impl SanitizerMethods<crate::DomTypeHolder> for Sanitizer {
|
|||||||
/// <https://wicg.github.io/sanitizer-api/#dom-sanitizer-get>
|
/// <https://wicg.github.io/sanitizer-api/#dom-sanitizer-get>
|
||||||
fn Get(&self) -> SanitizerConfig {
|
fn Get(&self) -> SanitizerConfig {
|
||||||
// Step 1. Let config be this’s configuration.
|
// Step 1. Let config be this’s configuration.
|
||||||
let config = self.configuration.borrow_mut();
|
let mut config = self.configuration.borrow_mut();
|
||||||
|
|
||||||
// TODO: Step 2 to Step 7
|
// Step 2. Assert: config is valid.
|
||||||
|
assert!(config.is_valid());
|
||||||
|
|
||||||
// Step 8. Return config.
|
match &mut config.elements {
|
||||||
|
// Step 3. If config["elements"] exists:
|
||||||
|
Some(config_elements) => {
|
||||||
|
// Step 3.1. For any element of config["elements"]:
|
||||||
|
for element in config_elements.iter_mut() {
|
||||||
|
// Step 3.1.1. If element["attributes"] exists:
|
||||||
|
if let Some(element_attributes) = &mut element.attributes_mut() {
|
||||||
|
// Step 3.1.1.1. Set element["attributes"] to the result of sort in
|
||||||
|
// ascending order element["attributes"], with attrA being less than item
|
||||||
|
// attrB.
|
||||||
|
element_attributes.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.1.2. If element["removeAttributes"] exists:
|
||||||
|
if let Some(element_remove_attributes) = &mut element.remove_attributes_mut() {
|
||||||
|
// Step 3.1.2.1. Set element["removeAttributes"] to the result of sort in
|
||||||
|
// ascending order element["removeAttributes"], with attrA being less than
|
||||||
|
// item attrB.
|
||||||
|
element_remove_attributes.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.2. Set config["elements"] to the result of sort in ascending order
|
||||||
|
// config["elements"], with elementA being less than item elementB.
|
||||||
|
config_elements.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
},
|
||||||
|
// Step 4. Otherwise:
|
||||||
|
None => {
|
||||||
|
// Step 4.1. Set config["removeElements"] to the result of sort in ascending order
|
||||||
|
// config["removeElements"], with elementA being less than item elementB.
|
||||||
|
if let Some(config_remove_elements) = &mut config.removeElements {
|
||||||
|
config_remove_elements.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5. If config["replaceWithChildrenElements"] exists:
|
||||||
|
if let Some(config_replace_with_children_elements) = &mut config.replaceWithChildrenElements
|
||||||
|
{
|
||||||
|
// Step 5.1.Set config["replaceWithChildrenElements"] to the result of sort in ascending
|
||||||
|
// order config["replaceWithChildrenElements"], with elementA being less than item
|
||||||
|
// elementB.
|
||||||
|
config_replace_with_children_elements.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Step 6. If config["processingInstructions"] exists:
|
||||||
|
// Step 6.1. Set config["processingInstructions"] to the result of sort in ascending order
|
||||||
|
// config["processingInstructions"], with piA["target"] being code unit less than
|
||||||
|
// piB["target"].
|
||||||
|
// Step 7. Otherwise:
|
||||||
|
// Step 7.1. Set config["removeProcessingInstructions"] to the result of sort in ascending
|
||||||
|
// order config["removeProcessingInstructions"], with piA["target"] being code unit less
|
||||||
|
// than piB["target"].
|
||||||
|
|
||||||
|
match &mut config.attributes {
|
||||||
|
// Step 8. If config["attributes"] exists:
|
||||||
|
Some(config_attributes) => {
|
||||||
|
// Step 8.1. Set config["attributes"] to the result of sort in ascending order
|
||||||
|
// config["attributes"], with attrA being less than item attrB.
|
||||||
|
config_attributes.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
},
|
||||||
|
// Step 9. Otherwise:
|
||||||
|
None => {
|
||||||
|
// Step 9.1. Set config["removeAttributes"] to the result of sort in ascending order
|
||||||
|
// config["removeAttributes"], with attrA being less than item attrB.
|
||||||
|
if let Some(config_remove_attributes) = &mut config.removeAttributes {
|
||||||
|
config_remove_attributes.sort_by(|item_a, item_b| item_a.compare(item_b));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 10. Return config.
|
||||||
(*config).clone()
|
(*config).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -807,6 +881,56 @@ trait NameMember: Sized {
|
|||||||
fn namespace_mut(&mut self) -> Option<&mut DOMString>;
|
fn namespace_mut(&mut self) -> Option<&mut DOMString>;
|
||||||
|
|
||||||
fn set_namespace(&mut self, namespace: Option<&str>);
|
fn set_namespace(&mut self, namespace: Option<&str>);
|
||||||
|
|
||||||
|
// <https://wicg.github.io/sanitizer-api/#sanitizerconfig-less-than-item>
|
||||||
|
fn is_less_than_item(&self, item_b: &Self) -> bool {
|
||||||
|
let item_a = self;
|
||||||
|
match item_a.namespace() {
|
||||||
|
// Step 1. If itemA["namespace"] is null:
|
||||||
|
None => {
|
||||||
|
// Step 1.1. If itemB["namespace"] is not null, then return true.
|
||||||
|
if item_b.namespace().is_some() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Step 2. Otherwise:
|
||||||
|
Some(item_a_namespace) => {
|
||||||
|
// Step 2.1. If itemB["namespace"] is null, then return false.
|
||||||
|
if item_b.namespace().is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2.2. If itemA["namespace"] is code unit less than itemB["namespace"], then
|
||||||
|
// return true.
|
||||||
|
if item_b
|
||||||
|
.namespace()
|
||||||
|
.is_some_and(|item_b_namespace| item_a_namespace < item_b_namespace)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2.3. If itemA["namespace"] is not itemB["namespace"], then return false.
|
||||||
|
if item_b
|
||||||
|
.namespace()
|
||||||
|
.is_some_and(|item_b_namespace| item_a_namespace != item_b_namespace)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3. Return itemA["name"] is code unit less than itemB["name"].
|
||||||
|
item_a.name() < item_b.name()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper of [`NameMember::is_less_than_item`] that returns [`std::cmp::Ordering`].
|
||||||
|
fn compare(&self, other: &Self) -> Ordering {
|
||||||
|
if self.is_less_than_item(other) {
|
||||||
|
Ordering::Less
|
||||||
|
} else {
|
||||||
|
Ordering::Greater
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NameMember for SanitizerElementWithAttributes {
|
impl NameMember for SanitizerElementWithAttributes {
|
||||||
@@ -973,7 +1097,9 @@ impl NameMember for SanitizerAttribute {
|
|||||||
/// [`SanitizerElementWithAttributes`].
|
/// [`SanitizerElementWithAttributes`].
|
||||||
trait AttributeMember {
|
trait AttributeMember {
|
||||||
fn attributes(&self) -> Option<&[SanitizerAttribute]>;
|
fn attributes(&self) -> Option<&[SanitizerAttribute]>;
|
||||||
|
fn attributes_mut(&mut self) -> Option<&mut Vec<SanitizerAttribute>>;
|
||||||
fn remove_attributes(&self) -> Option<&[SanitizerAttribute]>;
|
fn remove_attributes(&self) -> Option<&[SanitizerAttribute]>;
|
||||||
|
fn remove_attributes_mut(&mut self) -> Option<&mut Vec<SanitizerAttribute>>;
|
||||||
|
|
||||||
fn set_attributes(&mut self, attributes: Option<Vec<SanitizerAttribute>>);
|
fn set_attributes(&mut self, attributes: Option<Vec<SanitizerAttribute>>);
|
||||||
fn set_remove_attributes(&mut self, remove_attributes: Option<Vec<SanitizerAttribute>>);
|
fn set_remove_attributes(&mut self, remove_attributes: Option<Vec<SanitizerAttribute>>);
|
||||||
@@ -989,6 +1115,15 @@ impl AttributeMember for SanitizerElementWithAttributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn attributes_mut(&mut self) -> Option<&mut Vec<SanitizerAttribute>> {
|
||||||
|
match self {
|
||||||
|
SanitizerElementWithAttributes::String(_) => None,
|
||||||
|
SanitizerElementWithAttributes::SanitizerElementNamespaceWithAttributes(dictionary) => {
|
||||||
|
dictionary.attributes.as_mut()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn remove_attributes(&self) -> Option<&[SanitizerAttribute]> {
|
fn remove_attributes(&self) -> Option<&[SanitizerAttribute]> {
|
||||||
match self {
|
match self {
|
||||||
SanitizerElementWithAttributes::String(_) => None,
|
SanitizerElementWithAttributes::String(_) => None,
|
||||||
@@ -998,6 +1133,15 @@ impl AttributeMember for SanitizerElementWithAttributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_attributes_mut(&mut self) -> Option<&mut Vec<SanitizerAttribute>> {
|
||||||
|
match self {
|
||||||
|
SanitizerElementWithAttributes::String(_) => None,
|
||||||
|
SanitizerElementWithAttributes::SanitizerElementNamespaceWithAttributes(dictionary) => {
|
||||||
|
dictionary.removeAttributes.as_mut()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_attributes(&mut self, attributes: Option<Vec<SanitizerAttribute>>) {
|
fn set_attributes(&mut self, attributes: Option<Vec<SanitizerAttribute>>) {
|
||||||
match self {
|
match self {
|
||||||
SanitizerElementWithAttributes::String(name) => {
|
SanitizerElementWithAttributes::String(name) => {
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
[sanitizer-get.tentative.html]
|
|
||||||
[Sorting of attributes]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Sorting of removeAttributes]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Sorting of elements]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Sorting of removeElements]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Sorting of replaceWithChildrenElements]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Sorting of element's attributes]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Sorting of element's removeAttributes]
|
|
||||||
expected: FAIL
|
|
||||||
Reference in New Issue
Block a user