Auto merge of #25575 - pshaughn:celoop, r=jdm

Prevent infinite recursion when upgrading custom elements

<!-- Please describe your changes on the following line: -->
The spec and tests were out of sync when I implemented #25410 and I mentioned I'd have an extra detail to attend to if whatwg/html#5126 landed; it did, and I did, and a couple test cases pass.

---
<!-- 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 two WPT test cases, see test metadata in commit

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

<!-- 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. -->
This commit is contained in:
bors-servo 2020-01-26 06:07:08 -05:00 committed by GitHub
commit e3a9063412
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 19 deletions

View file

@ -595,13 +595,17 @@ impl CustomElementDefinition {
/// <https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element>
#[allow(unsafe_code)]
pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
// Steps 1-2
// Step 1
let state = element.get_custom_element_state();
if state == CustomElementState::Custom || state == CustomElementState::Failed {
if state != CustomElementState::Undefined && state != CustomElementState::Uncustomized {
return;
}
// Step 3 happens later to save having to undo it in an exception
// Step 2
element.set_custom_element_definition(Rc::clone(&definition));
// Step 3
element.set_custom_element_state(CustomElementState::Failed);
// Step 4
for attr in element.attrs().iter() {
@ -639,14 +643,12 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
// Step 8 exception handling
if let Err(error) = result {
// Step 8.exception.1
element.set_custom_element_state(CustomElementState::Failed);
element.clear_custom_element_definition();
// Step 8.exception.2 isn't needed since step 3 hasn't happened yet
// Step 8.exception.3
// Step 8.exception.2
element.clear_reaction_queue();
// Step 8.exception.4
// Step 8.exception.3
let global = GlobalScope::current().expect("No current global");
let cx = global.get_cx();
unsafe {
@ -660,11 +662,7 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
// TODO Step 9: "If element is a form-associated custom element..."
// Step 10
element.set_custom_element_state(CustomElementState::Custom);
// Step 3
element.set_custom_element_definition(definition);
}
/// <https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element>

View file

@ -342,6 +342,10 @@ impl Element {
self.rare_data().as_ref()?.custom_element_definition.clone()
}
pub fn clear_custom_element_definition(&self) {
self.ensure_rare_data().custom_element_definition = None;
}
pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) {
self.ensure_rare_data()
.custom_element_reaction_queue

View file

@ -4,10 +4,3 @@
[If definition's disable shadow is true and element's shadow root is non-null, then throw a "NotSupportedError" DOMException.]
expected: FAIL
[Infinite constructor recursion with upgrade(this) should not be possible]
expected: FAIL
[Infinite constructor recursion with appendChild should not be possible]
expected: FAIL