Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the form owner concept #15283

Closed
wants to merge 10 commits into from
Closed

Implement the form owner concept #15283

wants to merge 10 commits into from

Conversation

@canova
Copy link
Member

canova commented Jan 28, 2017

Implemention of the core logic for form owners. It's rebased version of #6613, addressed most of the comments and fixed some of the code. I needed to update the code by hand instead of rebasing old main commit because of the massive merge conflicts over the years.

The html5ever PR is here: servo/html5ever#249

Currently I'm using my html5ever fork to run the tests. I'll undo the changes in Cargo.toml and Cargo.lock once it gets merged.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #3553 (github issue number if applicable).
  • There are tests for these changes

This change is Reviewable

@highfive
Copy link

highfive commented Jan 28, 2017

Heads up! This PR modifies the following files:

  • @fitzgen: components/script/Cargo.toml, components/script/dom/htmlselectelement.rs, components/script/dom/document.rs, components/script/dom/htmllegendelement.rs, components/script/dom/element.rs, components/script/dom/htmlfieldsetelement.rs, components/script/dom/servoparser/html.rs, components/script/dom/virtualmethods.rs, components/script/dom/htmlobjectelement.rs, components/script/dom/htmllabelelement.rs, components/script/dom/htmltextareaelement.rs, components/script/dom/htmloutputelement.rs, components/script/dom/htmlimageelement.rs, components/script/dom/htmlinputelement.rs, components/script/dom/htmlbuttonelement.rs, components/script/dom/node.rs, components/script/dom/htmlformelement.rs
  • @KiChjang: components/script/Cargo.toml, components/script/dom/htmlselectelement.rs, components/script/dom/document.rs, components/script/dom/htmllegendelement.rs, components/script/dom/element.rs, components/script/dom/htmlfieldsetelement.rs, components/script/dom/servoparser/html.rs, components/script/dom/virtualmethods.rs, components/script/dom/htmlobjectelement.rs, components/script/dom/htmllabelelement.rs, components/script/dom/htmltextareaelement.rs, components/script/dom/htmloutputelement.rs, components/script/dom/htmlimageelement.rs, components/script/dom/htmlinputelement.rs, components/script/dom/htmlbuttonelement.rs, components/script/dom/node.rs, components/script/dom/htmlformelement.rs
@canova
Copy link
Member Author

canova commented Jan 28, 2017

r? @jdm
New added form_owner_and_table.html test is failing currently but I'll investigate the problem tomorrow. Other added tests are currently passing. I need to also run a try build to see if I broke something.

@highfive highfive assigned jdm and unassigned Ms2ger Jan 28, 2017
@canova
Copy link
Member Author

canova commented Jan 28, 2017

@bors-servo
Copy link
Contributor

bors-servo commented Jan 28, 2017

Trying commit ef9cac0 with merge bbc4f64...

bors-servo added a commit that referenced this pull request Jan 28, 2017
Implement the form owner concept

<!-- Please describe your changes on the following line: -->
Implemention of the core logic for form owners. It's rebased version of #6613, addressed most of the comments and fixed some of the code. I needed to update the code by hand instead of rebasing old main commit because of the massive merge conflicts over the years.

Currently I'm using my html5ever fork to run the tests. I'll undo the changes in Cargo.toml and Cargo.lock once it gets merged.

---
<!-- 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 #3553 (github issue number if applicable).

<!-- Either: -->
- [X] There are tests for these changes

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15283)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jan 28, 2017

💔 Test failed - linux-dev

@jdm
Copy link
Member

jdm commented Jan 28, 2017

  ▶ Unexpected subtest result in /html/semantics/forms/form-control-infrastructure/form.html:
  └ PASS [expected FAIL] label-in-table-with-control.form

  ▶ Unexpected subtest result in /html/semantics/forms/form-control-infrastructure/form.html:
  └ PASS [expected FAIL] label-in-table-for.form

  ▶ Unexpected subtest result in /html/semantics/forms/form-control-infrastructure/form.html:
  │ FAIL [expected PASS] label.form
  │   → assert_equals: label.form expected null but got Element node <form id="form">
<p><button id="button">button</button>
<...
  │ 
  │ testLabel/<@http://web-platform.test:8000/html/semantics/forms/form-control-infrastructure/form.html:81:5
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1406:20
  │ test@http://web-platform.test:8000/resources/testharness.js:501:9
  │ testLabel@http://web-platform.test:8000/html/semantics/forms/form-control-infrastructure/form.html:78:3
  └ @http://web-platform.test:8000/html/semantics/forms/form-control-infrastructure/form.html:85:1

  ▶ Unexpected subtest result in /html/semantics/forms/form-control-infrastructure/form.html:
  │ FAIL [expected PASS] label-in-table.form
  │   → assert_equals: label.form expected null but got Element node <form id="form3"></form>
  │ 
  │ testLabel/<@http://web-platform.test:8000/html/semantics/forms/form-control-infrastructure/form.html:81:5
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1406:20
  │ test@http://web-platform.test:8000/resources/testharness.js:501:9
  │ testLabel@http://web-platform.test:8000/html/semantics/forms/form-control-infrastructure/form.html:78:3
  └ @http://web-platform.test:8000/html/semantics/forms/form-control-infrastructure/form.html:94:1

  ▶ CRASH [expected OK] /html/semantics/forms/resetting-a-form/reset-form.html
  │ 
  │ VMware, Inc.
  │ Gallium 0.4 on softpipe
  │ 3.3 (Core Profile) Mesa 12.0.1
  │ not yet implemented (thread ScriptThread PipelineId { namespace_id: PipelineNamespaceId(0), index: PipelineIndex(1) }, at /Users/servo/buildbot/slave/mac-rel-wpt1/build/components/script/dom/htmlformelement.rs:654)
  │ stack backtrace:
  │    0:        0x10534bc6e - backtrace::backtrace::trace::h05b30eb9c9ea9aaa
  │    1:        0x10534bf7c - backtrace::capture::Backtrace::new::hd6fb6e83f9059b0d
  │    2:        0x1041d00f4 - servo::main::{{closure}}::hfe009f9dcda553cc
  │    3:        0x105d05564 - std::panicking::rust_panic_with_hook::h33761bada49f3713
  │    4:        0x1043f3534 - std::panicking::begin_panic::hf16f59ea153d03ea
  │    5:        0x1047440f0 - script::dom::htmlformelement::HTMLFormElement::reset::h128594eee2b14ab3
  │    6:        0x10444e33b - std::panicking::try::do_call::h4300f1ebd1e5b90e
  │    7:        0x105d0647a - __rust_maybe_catch_panic
  │    8:        0x1049ce020 - script::dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementBinding::reset::he27a56e267712168
  │    9:        0x104b57e68 - CallJitMethodOp
  │   10:        0x104674113 - script::dom::bindings::utils::generic_call::h97caee99528742d7
  │   11:        0x104fc1aee - 2js23InternalCallOrConstructEP9JSContextRKN2JS8CallArgsENS_14MaybeConstruct
  │   12:        0x104fbb30c - _ZL9InterpretP9JSContextRN2js8RunStateE
  │   13:        0x104fae9ca - 2js9RunScriptEP9JSContextRNS_8RunState
  │   14:        0x104fc1e42 - 2js23InternalCallOrConstructEP9JSContextRKN2JS8CallArgsENS_14MaybeConstruct
  │   15:        0x104fc1fa5 - 2js4CallEP9JSContextN2JS6HandleINS2_5ValueEEES5_RKNS_13AnyInvokeArgsENS2_13MutableHandleIS4_E
  │   16:        0x104eee4d0 - 2js9fun_applyEP9JSContextjPN2JS5Value
  │   17:        0x104fc1aee - 2js23InternalCallOrConstructEP9JSContextRKN2JS8CallArgsENS_14MaybeConstruct
  │   18:        0x104fbb30c - _ZL9InterpretP9JSContextRN2js8RunStateE
  │   19:        0x104fae9ca - 2js9RunScriptEP9JSContextRNS_8RunState
  │   20:        0x104fc2981 - _ZN2js13ExecuteKernelEP9JSContextN2JS6HandleIP8JSScriptEER8JSObjectRKNS2_5ValueENS_16AbstractFramePtrEPS9_
  │   21:        0x104fc2ad7 - 2js7ExecuteEP9JSContextN2JS6HandleIP8JSScriptEER8JSObjectPNS2_5Value
  │   22:        0x104e90a88 - _ZL8EvaluateP9JSContextN2JS6HandleIP8JSObjectEENS2_IPN2js11StaticScopeEEERKNS1_22ReadOnlyCompileOptionsERNS1_18SourceBufferHolderENS1_13MutableHandleINS1_5ValueEEE
  │   23:        0x104e90c45 - 2JS8EvaluateEP9JSContextRKNS_22ReadOnlyCompileOptionsEPKDsmNS_13MutableHandleINS_5ValueEE
  │   24:        0x104719739 - script::dom::globalscope::GlobalScope::evaluate_script_on_global_with_result::ha18c0a0349b7083e
  │   25:        0x104776193 - script::dom::htmlscriptelement::HTMLScriptElement::execute::h499aa81fb515cfb7
  │   26:        0x10477439b - script::dom::htmlscriptelement::HTMLScriptElement::prepare::hb1bdd2f230f2fb89
  │   27:        0x1047c8dfc - script::dom::servoparser::ServoParser::do_parse_sync::h34666ed83b35150e
  │   28:        0x1047c8b66 - script::dom::servoparser::ServoParser::parse_sync::h101a970af8f26898
  │   29:        0x1047c76b6 - script::dom::servoparser::ServoParser::resume_with_pending_parsing_blocking_script::ha976fdf55ff1ce94
  │   30:        0x1046d3c7e - script::dom::document::Document::process_pending_parsing_blocking_script::hfa05777ecaf76d70
  │   31:        0x1046d3885 - script::dom::document::Document::pending_parsing_blocking_script_loaded::h9664964978802b97
  │   32:        0x1047732bf - <script::dom::htmlscriptelement::ScriptContext as net_traits::FetchResponseListener>::process_response_eof::h0ad6366679da3973
  │   33:        0x104846abd - <script::network_listener::ListenerRunnable<A, Listener> as script::script_thread::Runnable>::handler::h73af4d13e3698d15
  │   34:        0x10484e882 - <script::script_thread::CancellableRunnable<T> as script::script_thread::Runnable>::handler::hee626778b24667da
  │   35:        0x1048684c1 - script::script_thread::ScriptThread::handle_msg_from_script::h599af8ff8a2bc0fd
  │   36:        0x1048631d5 - script::script_thread::ScriptThread::handle_msgs::{{closure}}::h6d4abf84d28ef2c3
  │   37:        0x10485e81b - script::script_thread::ScriptThread::handle_msgs::h0625f27481ecd3b8
  │   38:        0x10451cdd7 - std::panicking::try::do_call::he05758f7896ded07
  │   39:        0x105d0647a - __rust_maybe_catch_panic
  │   40:        0x1045ab0ba - <F as alloc::boxed::FnBox<A>>::call_box::heeb5f37ee44a8ef5
  │   41:        0x105d044e4 - std::sys::imp::thread::Thread::new::thread_start::he1b44499d44cc4a4
  │   42:     0x7fff8afbb059 - _pthread_body
  │   43:     0x7fff8afbafd6 - _pthread_start
  │ ERROR:servo: not yet implemented
  └ Pipeline failed in hard-fail mode.  Crashing!

  ▶ Unexpected subtest result in /html/semantics/forms/the-legend-element/legend-form.html:
  │ FAIL [expected PASS] Check if legend.form returns its parent when it's inside a fieldset
  │   → assert_not_equals: got disallowed value null
  │ 
  │ @http://web-platform.test:8000/html/semantics/forms/the-legend-element/legend-form.html:26:3
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1406:20
  │ test@http://web-platform.test:8000/resources/testharness.js:501:9
  └ @http://web-platform.test:8000/html/semantics/forms/the-legend-element/legend-form.html:24:1
@canova canova force-pushed the canova:form-owner branch from ef9cac0 to ad034f7 Jan 30, 2017
@canova canova force-pushed the canova:form-owner branch from ad034f7 to 967a3a0 Jan 31, 2017
@canova
Copy link
Member Author

canova commented Jan 31, 2017

@jdm I think it's ready to review now :) Failing tests are passing and removed some fail expectations. I want to test it one more time to see if everything is ok.
@bors-servo try

@bors-servo
Copy link
Contributor

bors-servo commented Jan 31, 2017

Trying commit c60dad5 with merge 22718c8...

bors-servo added a commit that referenced this pull request Jan 31, 2017
Implement the form owner concept

<!-- Please describe your changes on the following line: -->
Implemention of the core logic for form owners. It's rebased version of #6613, addressed most of the comments and fixed some of the code. I needed to update the code by hand instead of rebasing old main commit because of the massive merge conflicts over the years.

The html5ever PR is here: servo/html5ever#249

Currently I'm using my html5ever fork to run the tests. I'll undo the changes in Cargo.toml and Cargo.lock once it gets merged.

---
<!-- 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 #3553 (github issue number if applicable).

<!-- Either: -->
- [X] There are tests for these changes

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15283)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Jan 31, 2017

💔 Test failed - linux-rel-wpt

@canova canova force-pushed the canova:form-owner branch from fedbaf4 to 8438ce8 Jan 31, 2017
@jdm
Copy link
Member

jdm commented Feb 3, 2017

I have only skimmed the changes so far, but I would like to find a way to reduce all of the duplicate implementations of FormControl, bind_to_tree, etc. What if we added a as_form_control helper (like as_maybe_activatable) that we could use from Element::bind_to_tree?

@canova
Copy link
Member Author

canova commented Feb 4, 2017

I suppose we can do that, I'll try this.

@bors-servo
Copy link
Contributor

bors-servo commented Feb 7, 2017

The latest upstream changes (presumably #15405) made this pull request unmergeable. Please resolve the merge conflicts.

@canova canova force-pushed the canova:form-owner branch from 8438ce8 to b038f64 Feb 8, 2017
@canova
Copy link
Member Author

canova commented Feb 9, 2017

I moved the bind_form_control_to_tree/unbind_form_control_from_tree calls to Element's bind/unbind functions. This reduced the duplication a bit.

There are still FormControl's methods to move. But they look like they can't removed easily(AFAIK). Because form_owner and set_form_owner methods access directly to form_owner field of the struct. And we don't know if this struct has that field or not. (For example HTMLLabelElement doesn't need to store a form_owner field.) Also to_element was predefined inside FormControl before, but we needed to remove DerivedFrom<Element> from FormControl trait to be able to use as_maybe_form_control helper method. And we can't upcast like this self.upcast::<Element>() if trait is not derived from Element. And not every form control has form attribute, so I can't generalize attribute_mutated either.

Copy link
Member

jdm left a comment

Thank you so much for tackling this! I've left a bunch of comments, but I appreciate the work you did to update the original PR and clean up some of the code duplication.

}
}
}


This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

nit: remove this empty line.

@@ -2043,6 +2057,7 @@ impl Document {
ignore_destructive_writes_counter: Default::default(),
dom_count: Cell::new(1),
fullscreen_element: MutNullableJS::new(None),
form_id_listener_map: DOMRefCell::new(HashMap::new()),

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

nit: form_id_listener_map: Default::default()

let mut data_set = Vec::new();
for child in node.traverse_preorder() {
for child in controls.iter() {
let child = child.upcast::<Node>();
// Step 3.1: The field element is disabled.
match child.downcast::<Element>() {

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

Downcasting to Element right after upcasting away from it is a bit silly. Let's do:

for child in controls.iter() {
    // Step 3.1: The field is disabled.
    if child.disabled_state() {
        continue;
    }
    let child = child.upcast::<Node>();
    ...
}
@@ -646,14 +651,28 @@ impl HTMLFormElement {
}
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOutputElement)) => {
// Unimplemented
{}
unimplemented!()

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

It's not clear to me that we actually want to panic if some web content calls reset() on a form that contains an <output> element.

This comment has been minimized.

@canova

canova Feb 15, 2017

Author Member

Yeah, at first I thought this can panic here but later I realized it's breaking some tests. Removed it afterwards.


fn to_element<'a>(&'a self) -> &'a Element;

fn is_reassociatable(&self) -> bool {

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

Let's call this is_listed to match the spec.

placeholder.appendChild(form1);
placeholder.appendChild(form2);

test(function() {

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

Let's make this test call encapsulate all of the code in testControl.

@@ -0,0 +1,234 @@
<!DOCTYPE html>

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

All of these tests belong in tests/wpt/web-platform-tests/html/semantics/forms/form-control-infrastructure/ since they're testing behaviour that is described in the specification.

@@ -651,7 +652,7 @@ impl HTMLFormElement {
}
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOutputElement)) => {
// Unimplemented
unimplemented!()
{}

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

We should just be able to remove the {} here.

@@ -174,11 +172,18 @@ impl HTMLLabelElement {

impl FormControl for HTMLLabelElement {
fn form_owner(&self) -> Option<Root<HTMLFormElement>> {
self.form_owner.get()
if let Some(e) = self.GetControl() {

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member
self.GetControl().and_then(|e| {
    let form_control = e.upcast::<Element>().as_maybe_form_control()
                        .expect("Element must be a form control");
    form_control.form_owner()
})
// FIXME: We should call `form_attribute_mutated` method here,
// but also we don't want to call reset_form_owner() method in
// `form_attribute_mutated`. We should fix this.
// self.form_attribute_mutated(AttributeMutation::Removed);

This comment has been minimized.

@jdm

jdm Feb 14, 2017

Member

Let's split form_attribute_mutated into register_if_necessary, unregister_if_necessary, and form_attribute_mutated. form_attribute_mutated can call the other two methods based on the mutation, and code like bind_form_control_to_tree can call those methods and reset_form_owner as needed.

@canova canova force-pushed the canova:form-owner branch from 5bc9b52 to cce035a Feb 16, 2017
@canova canova removed the S-needs-rebase label Feb 16, 2017
@bors-servo
Copy link
Contributor

bors-servo commented Feb 18, 2017

The latest upstream changes (presumably #15588) made this pull request unmergeable. Please resolve the merge conflicts.

@canova canova force-pushed the canova:form-owner branch 2 times, most recently from f9267e9 to 32b964d Feb 23, 2017
@canova
Copy link
Member Author

canova commented Feb 23, 2017

@jdm Sorry couldn't look at this PR recently. I've addressed most of your comments and rebased.

Why is this change necessary? Do we have a test that covers it?

I've looked at the algorithm and the spec but couldn't find the reason. It was like this in the previous PR. Saw your comment about this line and thought it should be necessary:

A comment explaining why it's important to perform these operations separately would help. I had to think about it for a minute.

@bors-servo
Copy link
Contributor

bors-servo commented Feb 24, 2017

The latest upstream changes (presumably #15715) made this pull request unmergeable. Please resolve the merge conflicts.

@canova canova force-pushed the canova:form-owner branch from 32b964d to b1980b5 Feb 24, 2017
mukilan and others added 10 commits Jan 28, 2017
…m_tree when it shouldn't
Because label has a different form owner concept. It should reflect its control's form owner. When it doesn't have a control it should print null.
…ethods
@canova canova force-pushed the canova:form-owner branch from b1980b5 to 438c0f8 Feb 24, 2017
@canova canova removed the S-needs-rebase label Feb 24, 2017
@bors-servo
Copy link
Contributor

bors-servo commented Feb 27, 2017

The latest upstream changes (presumably #15752) made this pull request unmergeable. Please resolve the merge conflicts.

@nox nox assigned nox and unassigned jdm Mar 3, 2017
@nox
Copy link
Member

nox commented Mar 3, 2017

@jdm Stealing this from you, I'm sure it will make you insanely angry to see people steal reviews from your queue.

@nox
Copy link
Member

nox commented Mar 14, 2017

Superseded by #15938, thanks @mukilan and @canaltinova.

@nox nox closed this Mar 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

7 participants
You can’t perform that action at this time.