- Revision
- 144995
- Author
- [email protected]
- Date
- 2013-03-06 16:07:02 -0800 (Wed, 06 Mar 2013)
Log Message
InsertUnorderedList can lead to lost content and assertions in moveParagraphs
https://bugs.webkit.org/show_bug.cgi?id=111228
Reviewed by Ryosuke Niwa.
Source/WebCore:
When a list is wrapped in a presentational inline like a b tag, we'd create markup that included
everything up to the b tag from moveParagraphs when intending to only move the contents of the
list item. This could make it impossible to remove content from a list and trigger loss of
editable text.
Test: editing/execCommand/insert-remove-block-list-inside-presentational-inline.html
* editing/EditingStyle.cpp:
(WebCore::elementMatchesAndPropertyIsNotInInlineStyleDecl): Ensure there's an inline style
before calling propertyExistsInStyle.
(WebCore::HTMLElementEquivalent::propertyExistsInStyle): Removing null check for style.
All callers ensure this value isn't null.
* editing/markup.cpp:
(WebCore::highestAncestorToWrapMarkup): Avoid going over RenderBlocks when finding the highest
presentational ancestor to avoid leaving the bounds of the original paragraph.
LayoutTests:
* editing/deleting/pruning-after-merge-1-expected.txt:
* editing/execCommand/insert-remove-block-list-inside-presentational-inline-expected.txt: Added.
* editing/execCommand/insert-remove-block-list-inside-presentational-inline.html: Added.
* editing/pasteboard/paste-and-sanitize-expected.txt:
* editing/pasteboard/paste-and-sanitize.html:
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (144994 => 144995)
--- trunk/LayoutTests/ChangeLog 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/LayoutTests/ChangeLog 2013-03-07 00:07:02 UTC (rev 144995)
@@ -1,3 +1,16 @@
+2013-03-06 Levi Weintraub <[email protected]>
+
+ InsertUnorderedList can lead to lost content and assertions in moveParagraphs
+ https://bugs.webkit.org/show_bug.cgi?id=111228
+
+ Reviewed by Ryosuke Niwa.
+
+ * editing/deleting/pruning-after-merge-1-expected.txt:
+ * editing/execCommand/insert-remove-block-list-inside-presentational-inline-expected.txt: Added.
+ * editing/execCommand/insert-remove-block-list-inside-presentational-inline.html: Added.
+ * editing/pasteboard/paste-and-sanitize-expected.txt:
+ * editing/pasteboard/paste-and-sanitize.html:
+
2013-03-06 Rafael Weinstein <[email protected]>
Unreviewed gardening.
Modified: trunk/LayoutTests/editing/deleting/pruning-after-merge-1-expected.txt (144994 => 144995)
--- trunk/LayoutTests/editing/deleting/pruning-after-merge-1-expected.txt 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/LayoutTests/editing/deleting/pruning-after-merge-1-expected.txt 2013-03-07 00:07:02 UTC (rev 144995)
@@ -5,7 +5,7 @@
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldDeleteDOMRange:range from 1 of #text > DIV > BODY > HTML > #document to 1 of #text > DIV > B > DIV > BODY > HTML > #document
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV > B > DIV > BODY > HTML > #document to 2 of #text > DIV > B > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > DIV > BODY > HTML > #document to 1 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > DIV > BODY > HTML > #document to 1 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
This tests the pruning that delete does when the it merges two paragraphs when the selection to delete spans multiple blocks.
Added: trunk/LayoutTests/editing/execCommand/insert-remove-block-list-inside-presentational-inline-expected.txt (0 => 144995)
--- trunk/LayoutTests/editing/execCommand/insert-remove-block-list-inside-presentational-inline-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-remove-block-list-inside-presentational-inline-expected.txt 2013-03-07 00:07:02 UTC (rev 144995)
@@ -0,0 +1,10 @@
+This test verifies insertUnorderedList can properly undo its own DOM manipulation.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS document.getElementsByTagName('ul').length == 0 is true
+
Added: trunk/LayoutTests/editing/execCommand/insert-remove-block-list-inside-presentational-inline.html (0 => 144995)
--- trunk/LayoutTests/editing/execCommand/insert-remove-block-list-inside-presentational-inline.html (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-remove-block-list-inside-presentational-inline.html 2013-03-07 00:07:02 UTC (rev 144995)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body _onload_="runTest();">
+<div id="console"></div>
+<div contenteditable="true" id="root"><b>one</b><div><b>two</b></div><div><b>three</b></div><div><br></div></div>
+<script>
+var root = document.getElementById("root");
+function toggleList() {
+ var temporaryBlock = document.createElement('div');
+ temporaryBlock.style.cssText = "height: 0";
+ temporaryBlock.appendChild(document.createTextNode('x'));
+ root.insertBefore(temporaryBlock, root.firstChild);
+ document.execCommand('insertUnorderedList');
+ root.removeChild(temporaryBlock);
+}
+
+function runTest() {
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ description("This test verifies insertUnorderedList can properly undo its own DOM manipulation.");
+ root.focus();
+ document.execCommand("SelectAll");
+ toggleList();
+ toggleList();
+ toggleList();
+ toggleList();
+ shouldBeTrue("document.getElementsByTagName('ul').length == 0");
+
+ if (window.testRunner)
+ root.parentNode.removeChild(root);
+}
+</script>
+<script src=""
+</body>
Modified: trunk/LayoutTests/editing/pasteboard/paste-and-sanitize-expected.txt (144994 => 144995)
--- trunk/LayoutTests/editing/pasteboard/paste-and-sanitize-expected.txt 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/LayoutTests/editing/pasteboard/paste-and-sanitize-expected.txt 2013-03-07 00:07:02 UTC (rev 144995)
@@ -4,7 +4,7 @@
PASS confirmedMarkup is '<b><i>Hello</i></b>'
PASS confirmedMarkup is '<b><i>Hello</i></b>'
PASS confirmedMarkup is 'Hello'
-PASS confirmedMarkup is '<b><i>Hello</i></b>'
+PASS confirmedMarkup is '<i style="font-weight: bold;">Hello</i>'
PASS confirmedMarkup is '<div style="text-align: center;"><b>Hello</b></div>'
PASS confirmedMarkup is '<div><b><i>hello</i></b></div><div><b><i>world</i></b></div>'
PASS confirmedMarkup is '<b><i><span style="font-weight: normal;"><b><i>hello1</i></b><b><i> hello2</i></b></span></i></b>'
Modified: trunk/LayoutTests/editing/pasteboard/paste-and-sanitize.html (144994 => 144995)
--- trunk/LayoutTests/editing/pasteboard/paste-and-sanitize.html 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/LayoutTests/editing/pasteboard/paste-and-sanitize.html 2013-03-07 00:07:02 UTC (rev 144995)
@@ -38,7 +38,7 @@
testPaste("div", "<b><i>Hello</i></b>", "<b><i>Hello</i></b>");
testPaste("div", "<div><b><i><span style=\"font-weight: normal\"><b><i>Hello</i></b></span></i></b></div>", "<b><i>Hello</i></b>");
testPaste("div", "<div><div><div>Hello</div></div></div>", "Hello");
-testPaste("div", "<div><b><div><i>Hello</i></div></b></div>", "<b><i>Hello</i></b>");
+testPaste("div", "<div><b><div><i>Hello</i></div></b></div>", "<i style=\"font-weight: bold;\">Hello</i>");
testPaste("div", "<div><div style=\"text-align: center;\"><b>Hello</b></div></div>", "<div style=\"text-align: center;\"><b>Hello</b></div>");
testPaste("div", "<div><b><i><span style=\"font-weight: normal\"><b><i>hello</i></b></span></i></b></div><div><b><i><span style=\"font-weight: normal\"><b><i>world</i></b></span></i></b></div>",
"<div><b><i>hello</i></b></div><div><b><i>world</i></b></div>");
Modified: trunk/Source/WebCore/ChangeLog (144994 => 144995)
--- trunk/Source/WebCore/ChangeLog 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/Source/WebCore/ChangeLog 2013-03-07 00:07:02 UTC (rev 144995)
@@ -1,3 +1,26 @@
+2013-03-06 Levi Weintraub <[email protected]>
+
+ InsertUnorderedList can lead to lost content and assertions in moveParagraphs
+ https://bugs.webkit.org/show_bug.cgi?id=111228
+
+ Reviewed by Ryosuke Niwa.
+
+ When a list is wrapped in a presentational inline like a b tag, we'd create markup that included
+ everything up to the b tag from moveParagraphs when intending to only move the contents of the
+ list item. This could make it impossible to remove content from a list and trigger loss of
+ editable text.
+
+ Test: editing/execCommand/insert-remove-block-list-inside-presentational-inline.html
+
+ * editing/EditingStyle.cpp:
+ (WebCore::elementMatchesAndPropertyIsNotInInlineStyleDecl): Ensure there's an inline style
+ before calling propertyExistsInStyle.
+ (WebCore::HTMLElementEquivalent::propertyExistsInStyle): Removing null check for style.
+ All callers ensure this value isn't null.
+ * editing/markup.cpp:
+ (WebCore::highestAncestorToWrapMarkup): Avoid going over RenderBlocks when finding the highest
+ presentational ancestor to avoid leaving the bounds of the original paragraph.
+
2013-03-06 Adam Klein <[email protected]>
[V8] Use implicit references instead of object groups to keep registered MutationObservers alive
Modified: trunk/Source/WebCore/editing/EditingStyle.cpp (144994 => 144995)
--- trunk/Source/WebCore/editing/EditingStyle.cpp 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/Source/WebCore/editing/EditingStyle.cpp 2013-03-07 00:07:02 UTC (rev 144995)
@@ -128,7 +128,7 @@
virtual ~HTMLElementEquivalent() { }
virtual bool matches(const Element* element) const { return !m_tagName || element->hasTagName(*m_tagName); }
virtual bool hasAttribute() const { return false; }
- virtual bool propertyExistsInStyle(const StylePropertySet* style) const { return style && style->getPropertyCSSValue(m_propertyID); }
+ virtual bool propertyExistsInStyle(const StylePropertySet* style) const { return style->getPropertyCSSValue(m_propertyID); }
virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const;
virtual void addToStyle(Element*, EditingStyle*) const;
@@ -974,7 +974,7 @@
static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLElementEquivalent* equivalent, const StyledElement* element,
EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style)
{
- return equivalent->matches(element) && !equivalent->propertyExistsInStyle(element->inlineStyle())
+ return equivalent->matches(element) && (!element->inlineStyle() || !equivalent->propertyExistsInStyle(element->inlineStyle()))
&& (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsInStyle(style));
}
Modified: trunk/Source/WebCore/editing/markup.cpp (144994 => 144995)
--- trunk/Source/WebCore/editing/markup.cpp 2013-03-06 23:56:27 UTC (rev 144994)
+++ trunk/Source/WebCore/editing/markup.cpp 2013-03-07 00:07:02 UTC (rev 144995)
@@ -56,6 +56,7 @@
#include "MarkupAccumulator.h"
#include "NodeTraversal.h"
#include "Range.h"
+#include "RenderBlock.h"
#include "RenderObject.h"
#include "Settings.h"
#include "StylePropertySet.h"
@@ -522,7 +523,7 @@
Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
if (checkAncestor->renderer()) {
- Node* newSpecialCommonAncestor = highestEnclosingNodeOfType(firstPositionInNode(checkAncestor), &isElementPresentational);
+ Node* newSpecialCommonAncestor = highestEnclosingNodeOfType(firstPositionInNode(checkAncestor), &isElementPresentational, CanCrossEditingBoundary, checkAncestor->renderer()->containingBlock()->node());
if (newSpecialCommonAncestor)
specialCommonAncestor = newSpecialCommonAncestor;
}