Commit 367f7e99 authored by Joel Einbinder's avatar Joel Einbinder Committed by Commit Bot

DevTools: Don't crash when text nodes are edited to be whitespace

DevTools ignores whitespace-only text nodes. But if a text node
that previously had text becomes whitespace-only, no childNodeRemoved
event is fired and DevTools would get confused.

Bug: 880372
Change-Id: I8f740a6e32d1c1a15a32443a2a702996028f64fa
Reviewed-on: https://chromium-review.googlesource.com/c/1257899
Commit-Queue: Joel Einbinder <einbinder@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596443}
parent f46cfe8f
...@@ -28,8 +28,8 @@ Bringing things back ...@@ -28,8 +28,8 @@ Bringing things back
Wrapper identity: identity Wrapper identity: identity
Event Symbol(AttrRemoved): H2 Event Symbol(AttrRemoved): H2
Event Symbol(AttrRemoved): H2 Event Symbol(AttrRemoved): H2
Event Symbol(CharacterDataModified): #text
Event Symbol(NodeInserted): LI Event Symbol(NodeInserted): LI
Event Symbol(NodeRemoved): #text
==========8<========== ==========8<==========
<div id="container" style="display:none"> <div id="container" style="display:none">
<p>WebKit is used by <a href="http://www.apple.com/safari/">Safari</a>, Dashboard, etc..</p> <p>WebKit is used by <a href="http://www.apple.com/safari/">Safari</a>, Dashboard, etc..</p>
......
Tests that DOMAgent.setOuterHTML can handle whitespace-only text nodes.
Setting textContent to " "
Setting textContent to "NOT_WHITESPACE"
Event Symbol(NodeInserted): #text
Setting textContent to "OTHER_NOT_WHITESPACE"
Event Symbol(CharacterDataModified): #text
Setting textContent to " "
Event Symbol(NodeRemoved): #text
Setting textContent to ""
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function() {
TestRunner.addResult(`Tests that DOMAgent.setOuterHTML can handle whitespace-only text nodes.\n`);
await TestRunner.loadModule('elements_test_runner');
await TestRunner.showPanel('elements');
await TestRunner.loadHTML(`
<div id="container" style="display:none">
<child id="identity"></child>
</div>
`);
await TestRunner.evaluateInPagePromise(`
document.getElementById("identity").wrapperIdentity = "identity";
`);
async function setChildTextContent(textContent) {
var text = ElementsTestRunner.containerText.replace(/<child id="identity">.*<\/child>/, `<child id="identity">${textContent}</child>`);
TestRunner.addResult(`Setting textContent to "${textContent}"`)
await TestRunner.DOMAgent.setOuterHTML(ElementsTestRunner.containerId, text);
dumpEvents();
}
function dumpEvents() {
ElementsTestRunner.events.sort();
for (let i = 0; i < ElementsTestRunner.events.length; ++i)
TestRunner.addResult(ElementsTestRunner.events[i]);
ElementsTestRunner.events = [];
TestRunner.addResult("");
}
await new Promise(x => ElementsTestRunner.setUpTestSuite(x));
await setChildTextContent(' ')
await setChildTextContent('NOT_WHITESPACE')
await setChildTextContent('OTHER_NOT_WHITESPACE')
await setChildTextContent(' ')
await setChildTextContent('')
TestRunner.completeTest();
})();
...@@ -46,7 +46,6 @@ Running: testSetTextContentWithEmptyText ...@@ -46,7 +46,6 @@ Running: testSetTextContentWithEmptyText
Running: testClearTextNodeTextContent Running: testClearTextNodeTextContent
//*[@id="textTest"] //*[@id="textTest"]
//*[@id="textTest"]/text() ""
Running: testAppendChildWhenHidden Running: testAppendChildWhenHidden
<No highlights> <No highlights>
......
...@@ -1872,7 +1872,10 @@ void InspectorDOMAgent::DidInsertDOMNode(Node* node) { ...@@ -1872,7 +1872,10 @@ void InspectorDOMAgent::DidInsertDOMNode(Node* node) {
void InspectorDOMAgent::WillRemoveDOMNode(Node* node) { void InspectorDOMAgent::WillRemoveDOMNode(Node* node) {
if (IsWhitespace(node)) if (IsWhitespace(node))
return; return;
DOMNodeRemoved(node);
}
void InspectorDOMAgent::DOMNodeRemoved(Node* node) {
ContainerNode* parent = node->parentNode(); ContainerNode* parent = node->parentNode();
// If parent is not mapped yet -> ignore the event. // If parent is not mapped yet -> ignore the event.
...@@ -1950,6 +1953,10 @@ void InspectorDOMAgent::StyleAttributeInvalidated( ...@@ -1950,6 +1953,10 @@ void InspectorDOMAgent::StyleAttributeInvalidated(
} }
void InspectorDOMAgent::CharacterDataModified(CharacterData* character_data) { void InspectorDOMAgent::CharacterDataModified(CharacterData* character_data) {
if (IsWhitespace(character_data)) {
DOMNodeRemoved(character_data);
return;
}
int id = document_node_to_id_map_->at(character_data); int id = document_node_to_id_map_->at(character_data);
if (!id) { if (!id) {
// Push text node if it is being created. // Push text node if it is being created.
......
...@@ -299,6 +299,7 @@ class CORE_EXPORT InspectorDOMAgent final ...@@ -299,6 +299,7 @@ class CORE_EXPORT InspectorDOMAgent final
void PushChildNodesToFrontend(int node_id, void PushChildNodesToFrontend(int node_id,
int depth = 1, int depth = 1,
bool traverse_frames = false); bool traverse_frames = false);
void DOMNodeRemoved(Node*);
void InvalidateFrameOwnerElement(HTMLFrameOwnerElement*); void InvalidateFrameOwnerElement(HTMLFrameOwnerElement*);
......
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