Commit 52206993 authored by joone.hur's avatar joone.hur Committed by Commit bot

Remove style spans to follow the styles of the block element

This CL removes style spans to follow the styles of the block
element(li, pre, td, and h1~6) when the text of the pasted
or merged element becomes a part of the block element.

BUG=226941
TEST=third_party/WebKit/LayoutTests/editing/deleting/backspace-merge-into-block-element.html

Review-Url: https://codereview.chromium.org/2102913002
Cr-Commit-Position: refs/heads/master@{#402659}
parent 4ce66b51
<!doctype HTML>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<style>
p {
font-size: 20px;
line-height: 22px;
color: red;
}
</style>
<div id="log"></div>
<script>
test(() => {
assert_selection(
'<div contenteditable="true"><h1>Heading 1:</h1>^<p>|paragraph was merged.</p></div>',
'delete',
'<div contenteditable="true"><h1>Heading 1:|paragraph was merged.</h1></div>',
'Make a paragraph into a heading');
assert_selection(
'<div contenteditable="true"><pre>Preformatted text:</pre>^<p>|paragraph was merged.</p></div>',
'delete',
'<div contenteditable="true"><pre>Preformatted text:|paragraph was merged.</pre></div>',
'Make a paragraph into a pre');
assert_selection(
'<div contenteditable="true"><ul><li>List Item:</li></ul>^<p>|paragraph was merged.</p></div>',
'delete',
'<div contenteditable="true"><ul><li>List Item:|paragraph was merged.</li></ul></div>',
'Make a paragraph into a list');
assert_selection(
'<div contenteditable="true"><table><tbody><tr><td>Table:</td></tr></tbody></table>^<p>|paragraph was merged.</p></div>',
'delete',
'<div contenteditable="true"><table><tbody><tr><td>Table:|paragraph was merged.</td></tr></tbody></table></div>',
'Make a paragraph into a table');
}, 'merge into a block by backspace');
</script>
<!doctype HTML>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
#editable p {
font-size: 20px;
line-height: 22px;
color: red;
}
</style>
<div contenteditable="true" id="editable">
<ul>
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
</ul>
<p>Paragraph</p>
</div>
<script>
test(function() {
var editor = document.getElementById('editable');
var range = document.createRange();
var selection = window.getSelection();
range.setStart(editor.childNodes[2], 0);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
editor.focus();
document.execCommand('delete');
var htmlPara = document.getElementsByTagName('li')[2].outerHTML;
assert_equals(htmlPara, '<li>list item 3Paragraph</li>');
}, 'make a paragraph into a list by backspace');
</script>
......@@ -7,10 +7,7 @@ WebKit preserves the inline style of the merged paragraph, and "world" should be
| "
"
| <h1>
| "hello<#selection-caret>"
| <span>
| style="color: green;"
| "world"
| "hello<#selection-caret>world"
| <font>
| color="red"
| "
......
......@@ -35,6 +35,7 @@
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Element.h"
#include "core/dom/NodeComputedStyle.h"
#include "core/dom/Text.h"
#include "core/editing/EditingUtilities.h"
#include "core/editing/FrameSelection.h"
......@@ -794,6 +795,23 @@ static void removeHeadContents(ReplacementFragment& fragment)
}
}
static bool followBlockElementStyle(const Node* node)
{
if (!node->isHTMLElement())
return false;
const HTMLElement& element = toHTMLElement(*node);
return element.computedStyle()->display() == LIST_ITEM
|| element.computedStyle()->display() == TABLE_CELL
|| element.hasTagName(preTag)
|| element.hasTagName(h1Tag)
|| element.hasTagName(h2Tag)
|| element.hasTagName(h3Tag)
|| element.hasTagName(h4Tag)
|| element.hasTagName(h5Tag)
|| element.hasTagName(h6Tag);
}
// Remove style spans before insertion if they are unnecessary. It's faster because we'll
// avoid doing a layout.
static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos)
......@@ -807,10 +825,19 @@ static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const
if (isMailPasteAsQuotationHTMLBlockQuoteElement(topNode) || enclosingNodeOfType(firstPositionInOrBeforeNode(topNode), isMailHTMLBlockquoteElement, CanCrossEditingBoundary))
return false;
// Remove style spans to follow the styles of list item when |fragment| becomes a list item.
// See bug http://crbug.com/335955.
// Remove style spans to follow the styles of parent block element when |fragment| becomes a part of it.
// See bugs http://crbug.com/226941 and http://crbug.com/335955.
HTMLSpanElement* wrappingStyleSpan = toHTMLSpanElement(topNode);
if (isListItem(enclosingBlock(insertionPos.anchorNode()))) {
const Node* node = insertionPos.anchorNode();
// |node| can be an inline element like <br> under <li>
// e.g.) editing/execCommand/switch-list-type.html
// editing/deleting/backspace-merge-into-block.html
if (node->computedStyle()->display() == INLINE) {
if (!(node = enclosingBlock(insertionPos.anchorNode())))
return false;
}
if (followBlockElementStyle(node)) {
fragment.removeNodePreservingChildren(wrappingStyleSpan);
return true;
}
......
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