aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <servo-ops@mozilla.com>2020-07-24 17:30:38 -0400
committerGitHub <noreply@github.com>2020-07-24 17:30:38 -0400
commitb83433fb142a54c4987d330acae3fbd8cbd7044e (patch)
treeb718d5a8542aa5614f024229d21489d263251bda
parentebec798263356817bbd3a2940e6f973f2704b886 (diff)
parent2d5c30d0421eb84e6a3e878fd0263640e7cf2db6 (diff)
downloadservo-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. -->
-rw-r--r--components/script/dom/htmlanchorelement.rs72
-rw-r--r--components/script/dom/htmlformelement.rs28
-rw-r--r--tests/wpt/metadata/css/CSS2/linebox/inline-negative-margin-001.html.ini5
-rw-r--r--tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini5
-rw-r--r--tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-button-target.html.ini9
-rw-r--r--tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-form-target.html.ini9
-rw-r--r--tests/wpt/metadata/html/semantics/forms/form-submission-target/rel-input-target.html.ini9
-rw-r--r--tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html.ini3
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