mirror of
https://github.com/servo/servo.git
synced 2025-10-01 00:59:15 +01:00
html: Count <image> attributes state changes as the relevant mutations (#39483)
Follow the HTML specification and take into account that state changes of the <image> 'crossorigin' and 'referrerpolicy' content attributes (not 'crossOrigin' and 'referrerPolicy' IDL attributes) should be counted as relevant mutations. See https://html.spec.whatwg.org/multipage/#relevant-mutations Testing: Improvements in the following tests - html/dom/reflection-embedded.html - html/semantics/embedded-content/the-img-element/relevant-mutations.html Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
parent
aaa7f83176
commit
af74db4e92
6 changed files with 96 additions and 245 deletions
|
@ -5428,17 +5428,18 @@ impl TaskOnce for ElementPerformFullscreenExit {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#cors-settings-attribute>
|
||||
pub(crate) fn reflect_cross_origin_attribute(element: &Element) -> Option<DOMString> {
|
||||
let attr = element.get_attribute(&ns!(), &local_name!("crossorigin"));
|
||||
|
||||
if let Some(mut val) = attr.map(|v| v.Value()) {
|
||||
val.make_ascii_lowercase();
|
||||
if val == "anonymous" || val == "use-credentials" {
|
||||
return Some(val);
|
||||
}
|
||||
return Some(DOMString::from("anonymous"));
|
||||
}
|
||||
None
|
||||
element
|
||||
.get_attribute(&ns!(), &local_name!("crossorigin"))
|
||||
.map(|attribute| {
|
||||
let value = attribute.value().to_ascii_lowercase();
|
||||
if value == "anonymous" || value == "use-credentials" {
|
||||
DOMString::from(value)
|
||||
} else {
|
||||
DOMString::from("anonymous")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn set_cross_origin_attribute(
|
||||
|
@ -5454,38 +5455,38 @@ pub(crate) fn set_cross_origin_attribute(
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#referrer-policy-attribute>
|
||||
pub(crate) fn reflect_referrer_policy_attribute(element: &Element) -> DOMString {
|
||||
let attr =
|
||||
element.get_attribute_by_name(DOMString::from_string(String::from("referrerpolicy")));
|
||||
|
||||
if let Some(mut val) = attr.map(|v| v.Value()) {
|
||||
val.make_ascii_lowercase();
|
||||
if val == "no-referrer" ||
|
||||
val == "no-referrer-when-downgrade" ||
|
||||
val == "same-origin" ||
|
||||
val == "origin" ||
|
||||
val == "strict-origin" ||
|
||||
val == "origin-when-cross-origin" ||
|
||||
val == "strict-origin-when-cross-origin" ||
|
||||
val == "unsafe-url"
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
DOMString::new()
|
||||
element
|
||||
.get_attribute(&ns!(), &local_name!("referrerpolicy"))
|
||||
.map(|attribute| {
|
||||
let value = attribute.value().to_ascii_lowercase();
|
||||
if value == "no-referrer" ||
|
||||
value == "no-referrer-when-downgrade" ||
|
||||
value == "same-origin" ||
|
||||
value == "origin" ||
|
||||
value == "strict-origin" ||
|
||||
value == "origin-when-cross-origin" ||
|
||||
value == "strict-origin-when-cross-origin" ||
|
||||
value == "unsafe-url"
|
||||
{
|
||||
DOMString::from(value)
|
||||
} else {
|
||||
DOMString::new()
|
||||
}
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub(crate) fn referrer_policy_for_element(element: &Element) -> ReferrerPolicy {
|
||||
element
|
||||
.get_attribute_by_name(DOMString::from_string(String::from("referrerpolicy")))
|
||||
.map(|attribute: DomRoot<Attr>| determine_policy_for_token(attribute.Value().str()))
|
||||
.get_attribute(&ns!(), &local_name!("referrerpolicy"))
|
||||
.map(|attribute| determine_policy_for_token(&attribute.value()))
|
||||
.unwrap_or(element.owner_document().get_referrer_policy())
|
||||
}
|
||||
|
||||
pub(crate) fn cors_setting_for_element(element: &Element) -> Option<CorsSettings> {
|
||||
reflect_cross_origin_attribute(element).and_then(|attr| match attr.str() {
|
||||
"anonymous" => Some(CorsSettings::Anonymous),
|
||||
"use-credentials" => Some(CorsSettings::UseCredentials),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
element
|
||||
.get_attribute(&ns!(), &local_name!("crossorigin"))
|
||||
.map(|attribute| CorsSettings::from_enumerated_attribute(&attribute.value()))
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use net_traits::image_cache::{
|
|||
Image, ImageCache, ImageCacheResult, ImageLoadListener, ImageOrMetadataAvailable,
|
||||
ImageResponse, PendingImageId, UsePlaceholder,
|
||||
};
|
||||
use net_traits::request::{Destination, Initiator, RequestId};
|
||||
use net_traits::request::{CorsSettings, Destination, Initiator, RequestId};
|
||||
use net_traits::{
|
||||
FetchMetadata, FetchResponseListener, FetchResponseMsg, NetworkError, ReferrerPolicy,
|
||||
ResourceFetchTiming, ResourceTimingType,
|
||||
|
@ -1603,22 +1603,6 @@ fn parse_a_sizes_attribute(value: &str) -> SourceSizeList {
|
|||
SourceSizeList::parse(&context, &mut parser)
|
||||
}
|
||||
|
||||
fn get_correct_referrerpolicy_from_raw_token(token: &DOMString) -> DOMString {
|
||||
if token.is_empty() {
|
||||
// Empty token is treated as the default referrer policy inside determine_policy_for_token,
|
||||
// so it should remain unchanged.
|
||||
DOMString::new()
|
||||
} else {
|
||||
let policy = determine_policy_for_token(token.str());
|
||||
|
||||
if policy == ReferrerPolicy::EmptyString {
|
||||
return DOMString::new();
|
||||
}
|
||||
|
||||
DOMString::from_string(policy.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
impl HTMLImageElementMethods<crate::DomTypeHolder> for HTMLImageElement {
|
||||
// https://html.spec.whatwg.org/multipage/#dom-image
|
||||
|
@ -1784,24 +1768,8 @@ impl HTMLImageElementMethods<crate::DomTypeHolder> for HTMLImageElement {
|
|||
reflect_referrer_policy_attribute(self.upcast::<Element>())
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-img-referrerpolicy
|
||||
fn SetReferrerPolicy(&self, value: DOMString, can_gc: CanGc) {
|
||||
let referrerpolicy_attr_name = local_name!("referrerpolicy");
|
||||
let element = self.upcast::<Element>();
|
||||
let previous_correct_attribute_value = get_correct_referrerpolicy_from_raw_token(
|
||||
&element.get_string_attribute(&referrerpolicy_attr_name),
|
||||
);
|
||||
let correct_value_or_empty_string = get_correct_referrerpolicy_from_raw_token(&value);
|
||||
if previous_correct_attribute_value != correct_value_or_empty_string {
|
||||
// Setting the attribute to the same value will update the image.
|
||||
// We don't want to start an update if referrerpolicy is set to the same value.
|
||||
element.set_string_attribute(
|
||||
&referrerpolicy_attr_name,
|
||||
correct_value_or_empty_string,
|
||||
can_gc,
|
||||
);
|
||||
}
|
||||
}
|
||||
// <https://html.spec.whatwg.org/multipage/#dom-img-referrerpolicy>
|
||||
make_setter!(SetReferrerPolicy, "referrerpolicy");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-img-decode>
|
||||
fn Decode(&self, can_gc: CanGc) -> Rc<Promise> {
|
||||
|
@ -1874,9 +1842,51 @@ impl VirtualMethods for HTMLImageElement {
|
|||
&local_name!("src") |
|
||||
&local_name!("srcset") |
|
||||
&local_name!("width") |
|
||||
&local_name!("crossorigin") |
|
||||
&local_name!("sizes") |
|
||||
&local_name!("referrerpolicy") => self.update_the_image_data(can_gc),
|
||||
&local_name!("sizes") => {
|
||||
// <https://html.spec.whatwg.org/multipage/#reacting-to-dom-mutations>
|
||||
// The element's src, srcset, width, or sizes attributes are set, changed, or
|
||||
// removed.
|
||||
self.update_the_image_data(can_gc);
|
||||
},
|
||||
&local_name!("crossorigin") => {
|
||||
// <https://html.spec.whatwg.org/multipage/#reacting-to-dom-mutations>
|
||||
// The element's crossorigin attribute's state is changed.
|
||||
let cross_origin_state_changed = match mutation {
|
||||
AttributeMutation::Removed | AttributeMutation::Set(None) => true,
|
||||
AttributeMutation::Set(Some(old_value)) => {
|
||||
let new_cors_setting =
|
||||
CorsSettings::from_enumerated_attribute(&attr.value());
|
||||
let old_cors_setting = CorsSettings::from_enumerated_attribute(old_value);
|
||||
|
||||
new_cors_setting != old_cors_setting
|
||||
},
|
||||
};
|
||||
|
||||
if cross_origin_state_changed {
|
||||
self.update_the_image_data(can_gc);
|
||||
}
|
||||
},
|
||||
&local_name!("referrerpolicy") => {
|
||||
// <https://html.spec.whatwg.org/multipage/#reacting-to-dom-mutations>
|
||||
// The element's referrerpolicy attribute's state is changed.
|
||||
let referrer_policy_state_changed = match mutation {
|
||||
AttributeMutation::Removed | AttributeMutation::Set(None) => {
|
||||
let referrer_policy = determine_policy_for_token(&attr.value());
|
||||
|
||||
referrer_policy != ReferrerPolicy::EmptyString
|
||||
},
|
||||
AttributeMutation::Set(Some(old_value)) => {
|
||||
let new_referrer_policy = determine_policy_for_token(&attr.value());
|
||||
let old_referrer_policy = determine_policy_for_token(old_value);
|
||||
|
||||
new_referrer_policy != old_referrer_policy
|
||||
},
|
||||
};
|
||||
|
||||
if referrer_policy_state_changed {
|
||||
self.update_the_image_data(can_gc);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'HTMLImageElement': {
|
||||
'canGc': ['RequestSubmit', 'ReportValidity', 'Reset','SetRel', 'Decode', 'SetCrossOrigin', 'SetWidth', 'SetHeight', 'SetReferrerPolicy'],
|
||||
'canGc': ['RequestSubmit', 'ReportValidity', 'Reset','SetRel', 'Decode', 'SetCrossOrigin', 'SetWidth', 'SetHeight'],
|
||||
},
|
||||
|
||||
'HTMLInputElement': {
|
||||
|
|
|
@ -137,6 +137,17 @@ pub enum CorsSettings {
|
|||
UseCredentials,
|
||||
}
|
||||
|
||||
impl CorsSettings {
|
||||
/// <https://html.spec.whatwg.org/multipage/#cors-settings-attribute>
|
||||
pub fn from_enumerated_attribute(value: &str) -> CorsSettings {
|
||||
match value.to_ascii_lowercase().as_str() {
|
||||
"anonymous" => CorsSettings::Anonymous,
|
||||
"use-credentials" => CorsSettings::UseCredentials,
|
||||
_ => CorsSettings::Anonymous,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [Parser Metadata](https://fetch.spec.whatwg.org/#concept-request-parser-metadata)
|
||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub enum ParserMetadata {
|
||||
|
|
162
tests/wpt/meta/html/dom/reflection-embedded.html.ini
vendored
162
tests/wpt/meta/html/dom/reflection-embedded.html.ini
vendored
|
@ -503,168 +503,6 @@
|
|||
[img.srcset: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to ""]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to undefined]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to 7]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to 1.5]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "5%"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "+100"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to ".5"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to true]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to false]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to object "[object Object\]"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to NaN]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to -Infinity]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to object "test-toString"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to object "test-valueOf"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xno-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "no-referrer\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "o-referrer"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "NO-REFERRER"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xno-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "no-referrer-when-downgrade\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "o-referrer-when-downgrade"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "NO-REFERRER-WHEN-DOWNGRADE"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xsame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "same-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "ame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "SAME-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "ſame-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xorigin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "rigin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xstrict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "strict-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "trict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "STRICT-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "ſtrict-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xorigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "rigin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "origin-when-croſſ-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xstrict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "strict-origin-when-cross-origin\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "trict-origin-when-cross-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "STRICT-ORIGIN-WHEN-CROSS-ORIGIN"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "ſtrict-origin-when-croſſ-origin"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "xunsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "unsafe-url\\0"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "nsafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "UNSAFE-URL"]
|
||||
expected: FAIL
|
||||
|
||||
[img.referrerPolicy: IDL set to "unſafe-url"]
|
||||
expected: FAIL
|
||||
|
||||
[img.decoding: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[relevant-mutations.html]
|
||||
[crossorigin state not changed: empty to anonymous]
|
||||
expected: FAIL
|
||||
|
||||
[crossorigin state not changed: use-credentials to USE-CREDENTIALS]
|
||||
expected: FAIL
|
||||
|
||||
[crossorigin state not changed: anonymous to foobar]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue