Commit 7cd91bca authored by joone.hur's avatar joone.hur Committed by Commit bot

[Reland] Remove style spans to follow the styles of the block element

Note: The original CL was reverted because of breaking Win8 build:
https://codereview.chromium.org/2109973002/

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/2117663002
Cr-Commit-Position: refs/heads/master@{#403428}
parent deec23f3
<!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,20 @@ 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) {
node = enclosingBlock(insertionPos.anchorNode());
if (!node)
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