diff options
author | bors-servo <servo-ops@mozilla.com> | 2020-07-24 17:30:38 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-24 17:30:38 -0400 |
commit | b83433fb142a54c4987d330acae3fbd8cbd7044e (patch) | |
tree | b718d5a8542aa5614f024229d21489d263251bda | |
parent | ebec798263356817bbd3a2940e6f973f2704b886 (diff) | |
parent | 2d5c30d0421eb84e6a3e878fd0263640e7cf2db6 (diff) | |
download | servo-b83433fb142a54c4987d330acae3fbd8cbd7044e.tar.gz servo-b83433fb142a54c4987d330acae3fbd8cbd7044e.zip |
Auto merge of #27299 - avr1254:master, r=jdm
Implemented get element target algorithm
Added check for area and anchor element
Finished issue: Implemented get target and no opener algorithm
Implemented get element target and get element noopener algorithms.
<!-- Please describe your changes on the following line: -->
Used the algorithms in html spec to implement target and no opener algorithms.
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #27253 (GitHub issue number if applicable)
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
10 files changed, 90 insertions, 59 deletions
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 42589dfce36..e6a89b7e746 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -18,7 +18,9 @@ use crate::dom::element::{referrer_policy_for_element, Element}; use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::htmlareaelement::HTMLAreaElement; use crate::dom::htmlelement::HTMLElement; +use crate::dom::htmlformelement::HTMLFormElement; use crate::dom::htmlimageelement::HTMLImageElement; use crate::dom::mouseevent::MouseEvent; use crate::dom::node::{document_from_node, Node}; @@ -566,6 +568,52 @@ impl Activatable for HTMLAnchorElement { } } +/// <https://html.spec.whatwg.org/multipage/#get-an-element's-target> +pub fn get_element_target(subject: &Element) -> Option<DOMString> { + if !(subject.is::<HTMLAreaElement>() || + subject.is::<HTMLAnchorElement>() || + subject.is::<HTMLFormElement>()) + { + return None; + } + if subject.has_attribute(&local_name!("target")) { + return Some(subject.get_string_attribute(&local_name!("target"))); + } + + let doc = document_from_node(subject).base_element(); + match doc { + Some(doc) => { + let element = doc.upcast::<Element>(); + if element.has_attribute(&local_name!("target")) { + return Some(element.get_string_attribute(&local_name!("target"))); + } else { + return None; + } + }, + None => return None, + }; +} + +/// < https://html.spec.whatwg.org/multipage/#get-an-element's-noopener> +pub fn get_element_noopener(subject: &Element, target_attribute_value: Option<DOMString>) -> bool { + if !(subject.is::<HTMLAreaElement>() || + subject.is::<HTMLAnchorElement>() || + subject.is::<HTMLFormElement>()) + { + return false; + } + let target_is_blank = target_attribute_value + .as_ref() + .map_or(false, |target| target.to_lowercase() == "_blank"); + let link_types = match subject.get_attribute(&ns!(), &local_name!("rel")) { + Some(rel) => rel.Value(), + None => return target_is_blank, + }; + return link_types.contains("noreferrer") || + link_types.contains("noopener") || + (!link_types.contains("opener") && target_is_blank); +} + /// <https://html.spec.whatwg.org/multipage/#following-hyperlinks-2> pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) { // Step 1. @@ -581,29 +629,19 @@ pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) { let source = document.browsing_context().unwrap(); // Step 4-5: target attribute. - let target_attribute_value = subject.get_attribute(&ns!(), &local_name!("target")); - - // Step 6. - let noopener = if let Some(link_types) = subject.get_attribute(&ns!(), &local_name!("rel")) { - let values = link_types.Value(); - let contains_noopener = values.contains("noopener"); - let contains_noreferrer = values.contains("noreferrer"); - let contains_opener = values.contains("opener"); - let target_is_blank = if let Some(name) = target_attribute_value.as_ref() { - name.Value().to_lowercase() == "_blank" + let target_attribute_value = + if subject.is::<HTMLAreaElement>() || subject.is::<HTMLAnchorElement>() { + get_element_target(subject) } else { - false + None }; - - contains_noreferrer || contains_noopener || (!contains_opener && target_is_blank) - } else { - false - }; + // Step 6. + let noopener = get_element_noopener(subject, target_attribute_value.clone()); // Step 7. let (maybe_chosen, replace) = match target_attribute_value { Some(name) => { - let (maybe_chosen, new) = source.choose_browsing_context(name.Value(), noopener); + let (maybe_chosen, new) = source.choose_browsing_context(name, noopener); let replace = if new { HistoryEntryReplacement::Enabled } else { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 26b2eab46b9..af2ee5e5d15 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -32,6 +32,7 @@ use crate::dom::file::File; use crate::dom::formdata::FormData; use crate::dom::formdataevent::FormDataEvent; use crate::dom::globalscope::GlobalScope; +use crate::dom::htmlanchorelement::{get_element_noopener, get_element_target}; use crate::dom::htmlbuttonelement::HTMLButtonElement; use crate::dom::htmlcollection::CollectionFilter; use crate::dom::htmldatalistelement::HTMLDataListElement; @@ -595,12 +596,12 @@ impl HTMLFormElementMethods for HTMLFormElement { return names_vec; } - // https://html.spec.whatwg.org/multipage/#dom-form-checkvalidity + /// https://html.spec.whatwg.org/multipage/#dom-form-checkvalidity fn CheckValidity(&self) -> bool { self.static_validation().is_ok() } - // https://html.spec.whatwg.org/multipage/#dom-form-reportvalidity + /// https://html.spec.whatwg.org/multipage/#dom-form-reportvalidity fn ReportValidity(&self) -> bool { self.interactive_validation().is_ok() } @@ -765,10 +766,26 @@ impl HTMLFormElement { let enctype = submitter.enctype(); let method = submitter.method(); - // Step 17-21 - let target_attribute_value = submitter.target(); + // Step 17 + let target_attribute_value = + if submitter.is_submit_button() && submitter.target() != DOMString::new() { + Some(submitter.target()) + } else { + let form_owner = submitter.form_owner(); + let form = form_owner.as_ref().map(|form| &**form).unwrap_or(self); + get_element_target(form.upcast::<Element>()) + }; + + // Step 18 + let noopener = + get_element_noopener(self.upcast::<Element>(), target_attribute_value.clone()); + + // Step 19 let source = doc.browsing_context().unwrap(); - let (maybe_chosen, _new) = source.choose_browsing_context(target_attribute_value, false); + let (maybe_chosen, _new) = source + .choose_browsing_context(target_attribute_value.unwrap_or(DOMString::new()), noopener); + + // Step 20 let chosen = match maybe_chosen { Some(proxy) => proxy, None => return, @@ -777,6 +794,7 @@ impl HTMLFormElement { Some(doc) => doc, None => return, }; + // Step 21 let target_window = target_document.window(); let mut load_data = LoadData::new( LoadOrigin::Script(doc.origin().immutable().clone()), diff --git a/tests/wpt/metadata/css/CSS2/linebox/inline-negative-margin-001.html.ini b/tests/wpt/metadata/css/CSS2/linebox/inline-negative-margin-001.html.ini index 94a3570d26b..076c791cd3d 100644 --- a/tests/wpt/metadata/css/CSS2/linebox/inline-negative-margin-001.html.ini +++ b/tests/wpt/metadata/css/CSS2/linebox/inline-negative-margin-001.html.ini @@ -8,6 +8,9 @@ [[data-expected-height\] 3] expected: FAIL - [[data-expected-height\] 4] + [[data-expected-height\] 1] + expected: FAIL + + [[data-expected-height\] 2] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini new file mode 100644 index 00000000000..e7b87119c9f --- /dev/null +++ b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini @@ -0,0 +1,5 @@ +[opener-closed.html] + expected: TIMEOUT + [An auxiliary browsing context should report `null` for `window.opener` when that browsing context is discarded] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini new file mode 100644 index 00000000000..02ca2b1ed3a --- /dev/null +++ b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini @@ -0,0 +1,3 @@ +[choose-_blank-003.html] + [Context created by link targeting "_blank" should retain opener reference] + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-button-target.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-button-target.html.ini index ed15a5bf1e9..39cbc423f07 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-button-target.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-button-target.html.ini @@ -2,21 +2,12 @@ [<form rel="opener noopener"> with <button formtarget>] expected: FAIL - [<form rel="noopener noreferrer"> with <button formtarget>] - expected: FAIL - [<form rel=""> with <button formtarget>] expected: FAIL - [<form rel="noreferrer opener"> with <button formtarget>] - expected: FAIL - [<form rel="noopener"> with <button formtarget>] expected: FAIL - [<form rel="noreferrer"> with <button formtarget>] - expected: FAIL - [<form rel="opener"> with <button formtarget>] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-form-target.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-form-target.html.ini index c6f0c1bdbca..d4f691c53ac 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-form-target.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-form-target.html.ini @@ -1,13 +1,4 @@ [rel-form-target.html] - [<form rel="noopener noreferrer"> with <form target>] - expected: FAIL - - [<form rel="noreferrer opener"> with <form target>] - expected: FAIL - - [<form rel="noreferrer"> with <form target>] - expected: FAIL - [<form rel="opener noopener"> with <form target>] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-input-target.html.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-input-target.html.ini index 577c5192603..3d7d51bcbef 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-input-target.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-input-target.html.ini @@ -8,15 +8,6 @@ [<form rel=""> with <input formtarget>] expected: FAIL - [<form rel="noreferrer opener"> with <input formtarget>] - expected: FAIL - - [<form rel="noopener noreferrer"> with <input formtarget>] - expected: FAIL - - [<form rel="noreferrer"> with <input formtarget>] - expected: FAIL - [<form rel="noopener"> with <input formtarget>] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini b/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini index bfcdef49b4b..b3120da1666 100644 --- a/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini +++ b/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini @@ -3,15 +3,9 @@ [Check that targeting of rel=noopener with a given name ignores an existing window with that name] expected: NOTRUN - [Check that rel=noopener with target=_parent does a normal load] - expected: FAIL - [Check that targeting of rel=noopener with a given name reuses an existing window with that name] expected: FAIL [Check that rel=noopener with target=_top does a normal load] expected: FAIL - [Check that rel=noopener with target=_self does a normal load] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html.ini b/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html.ini index b95c66a34c9..e312ed40606 100644 --- a/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html.ini +++ b/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html.ini @@ -9,9 +9,6 @@ [Area element with target=_blank with rel=opener] expected: TIMEOUT - [Anchor element with target=_blank with implicit rel=noopener] - expected: FAIL - [Area element with target=_blank with implicit rel=noopener] expected: TIMEOUT |