Commit c281c2a5 authored by Joey Arhar's avatar Joey Arhar Committed by Commit Bot

Fix duplicate head and body from insertAdjacentHTML

This patch makes document.body.insertAdjacentHTML('afterend', '<p>')
insert the <p> as a sibling of document.body rather than creating a
duplicate body and putting <p> in the duplicate.

This fix was made in webkit in 2016:
https://github.com/WebKit/webkit/commit/e3ca66a98a2a5edd553c411d6249a3a6a176174a

fast/dom/insertAdjacentHTML-DocumentFragment-crash no longer produces a
console message because using insertAdjacentHTML to create a child of a
DocumentFragment now works, just as it does in safari and firefox.

Bug: 978148
Change-Id: I22248b914753a450e54f0a72066f5b0dcf584cb2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1824030Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700842}
parent 5f73c340
......@@ -116,6 +116,7 @@
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h"
#include "third_party/blink/renderer/core/html/forms/html_form_controls_collection.h"
#include "third_party/blink/renderer/core/html/forms/html_options_collection.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_element.h"
......@@ -4429,6 +4430,7 @@ void Element::setOuterHTML(const StringOrTrustedHTML& string_or_html,
}
}
// Step 4 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
Node* Element::InsertAdjacent(const String& where,
Node* new_child,
ExceptionState& exception_state) {
......@@ -4537,13 +4539,13 @@ ScriptPromise Element::updateRendering(ScriptState* script_state) {
}
// Step 1 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
static Element* ContextElementForInsertion(const String& where,
Element* element,
ExceptionState& exception_state) {
static Node* ContextNodeForInsertion(const String& where,
Element* element,
ExceptionState& exception_state) {
if (DeprecatedEqualIgnoringCase(where, "beforeBegin") ||
DeprecatedEqualIgnoringCase(where, "afterEnd")) {
Element* parent = element->parentElement();
if (!parent) {
Node* parent = element->parentNode();
if (!parent || IsA<Document>(parent)) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNoModificationAllowedError,
"The element has no parent.");
......@@ -4578,11 +4580,22 @@ void Element::insertAdjacentText(const String& where,
void Element::insertAdjacentHTML(const String& where,
const String& markup,
ExceptionState& exception_state) {
Element* context_element =
ContextElementForInsertion(where, this, exception_state);
if (!context_element)
Node* context_node = ContextNodeForInsertion(where, this, exception_state);
if (!context_node)
return;
// Step 2 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
Element* context_element;
if (!IsA<Element>(context_node) ||
(context_node->GetDocument().IsHTMLDocument() &&
IsA<HTMLHtmlElement>(context_node))) {
context_element =
MakeGarbageCollected<HTMLBodyElement>(context_node->GetDocument());
} else {
context_element = To<Element>(context_node);
}
// Step 3 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
DocumentFragment* fragment = CreateFragmentForInnerOuterHTML(
markup, context_element, kAllowScriptingContent, "insertAdjacentHTML",
exception_state);
......
......@@ -995,6 +995,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
scoped_refptr<ComputedStyle> OriginalStyleForLayoutObject();
// Step 4 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
Node* InsertAdjacent(const String& where, Node* new_child, ExceptionState&);
virtual void ParserDidSetAttributes() {}
......
This is a testharness.js-based test.
PASS beforeBegin content without next sibling
PASS Afterbegin content without next sibling
PASS BeforeEnd content without next sibling
PASS afterend content without next sibling
PASS beforeBegin content again, with next sibling
PASS Afterbegin content again, with next sibling
PASS BeforeEnd content again, with next sibling
PASS afterend content again, with next sibling
PASS Should throw when inserting with invalid position string
PASS When the parent node is null, insertAdjacentHTML should throw for beforebegin and afterend (text)
PASS When the parent node is null, insertAdjacentHTML should throw for beforebegin and afterend (comments)
PASS When the parent node is null, insertAdjacentHTML should throw for beforebegin and afterend (elements)
PASS When the parent node is a document, insertAdjacentHTML should throw for beforebegin and afterend (text)
PASS When the parent node is a document, insertAdjacentHTML should throw for beforebegin and afterend (comments)
PASS When the parent node is a document, insertAdjacentHTML should throw for beforebegin and afterend (elements)
PASS Inserting after being and before end should order things correctly
PASS beforeBegin child node not in tree but has parent
PASS Afterbegin child node not in tree but has parent
PASS BeforeEnd child node not in tree but has parent
PASS afterend child node not in tree but has parent
PASS Should not run script when appending things which have descendant <script> inserted via insertAdjacentHTML
PASS beforeBegin content2 without next sibling
PASS Afterbegin content2 without next sibling
PASS BeforeEnd content2 without next sibling
PASS afterend content2 without next sibling
PASS beforeBegin content2 test again, now that there's a next sibling
PASS Afterbegin content2 test again, now that there's a next sibling
PASS BeforeEnd content2 test again, now that there's a next sibling
PASS afterend content2 test again, now that there's a next sibling
FAIL Inserting kids of the <html> element should not do weird things with implied <body>/<head> tags assert_equals: Should still have one head expected 1 but got 3
Harness: the test ran to completion.
CONSOLE ERROR: line 9: Uncaught NoModificationAllowedError: Failed to execute 'insertAdjacentHTML' on 'Element': The element has no parent.
This test passes if it doesn't crash (or ASSERT).
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment