[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
rniwa at webkit.org
rniwa at webkit.org
Wed Dec 22 14:39:47 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit aeeef96044d41cc7b99bb23f127fd813e8906c98
Author: rniwa at webkit.org <rniwa at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Oct 15 04:09:48 2010 +0000
2010-10-14 Ryosuke Niwa <rniwa at webkit.org>
Reviewed by Tony Chang and Darin Adler.
execCommand FormatBlock creates lots of blockquotes
https://bugs.webkit.org/show_bug.cgi?id=19795
The bug was caused by WebKit's not reusing the block node added by previous iteration
and its inserting block node at wrong places.
Fixed the bug by rewriting FormatBlockCommand::formatRange. New code resembles that of
IndentOutdentCommand::indentIntoBlockquote. The difference between two is that formatRange
avoids the existing block elements when replacing blocks and it also adds a placeholder
when removing the existing block caused paragraphs to collapse.
Also fixed a bug in moveParagraphWithClones where erroneous br is added to the start of
the block element to which the paragraph is moved if the block element is the start of a paragraph
and not the end of a paragraph.
Tests: editing/execCommand/format-block-multiple-paragraphs.html
editing/execCommand/format-block-table.html
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::moveParagraphWithClones): No longer adds erroneous br.
* editing/EditorCommand.cpp:
(WebCore::executeFormatBlock):
* editing/FormatBlockCommand.cpp:
(WebCore::FormatBlockCommand::formatRange): Rewritten; see above.
(WebCore::FormatBlockCommand::isElementToApplyInFormatBlockCommand): Renamed from validBlockElement
and moved from htmlediting.cpp.
(WebCore::enclosingBlockToSplitTreeTo): Added.
* editing/FormatBlockCommand.h:
* editing/VisiblePosition.cpp:
(WebCore::enclosingBlockFlowElement): Changed the return type to Element*
* editing/VisiblePosition.h:
2010-10-14 Ryosuke Niwa <rniwa at webkit.org>
Reviewed by Tony Chang and Darin Adler.
execCommand FormatBlock creates lots of blockquotes
https://bugs.webkit.org/show_bug.cgi?id=19795
Added tests to ensure WebKit does not add multiple block elements when applying block element to
multiple paragraphs. Also added a test to ensure formatBlock works with tables.
* fast/html/nav-element-expected.txt: Preserved new lines and removed redundant br.
* editing/execCommand/format-block-expected.txt: Preserved span and removed erroneous br.
* editing/execCommand/format-block-from-range-selection-expected.txt: Merged dl's and removed erroneous br.
* editing/execCommand/format-block-multiple-paragraphs-expected.txt: Added.
* editing/execCommand/format-block-multiple-paragraphs.html: Added.
* editing/execCommand/format-block-table-expected.txt: Added.
* editing/execCommand/format-block-table.html: Added.
* editing/execCommand/format-block-with-braces-expected.txt: Removed erroneous br.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69836 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d6bd84a..7781c98 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2010-10-14 Ryosuke Niwa <rniwa at webkit.org>
+
+ Reviewed by Tony Chang and Darin Adler.
+
+ execCommand FormatBlock creates lots of blockquotes
+ https://bugs.webkit.org/show_bug.cgi?id=19795
+
+ Added tests to ensure WebKit does not add multiple block elements when applying block element to
+ multiple paragraphs. Also added a test to ensure formatBlock works with tables.
+
+ * fast/html/nav-element-expected.txt: Preserved new lines and removed redundant br.
+ * editing/execCommand/format-block-expected.txt: Preserved span and removed erroneous br.
+ * editing/execCommand/format-block-from-range-selection-expected.txt: Merged dl's and removed erroneous br.
+ * editing/execCommand/format-block-multiple-paragraphs-expected.txt: Added.
+ * editing/execCommand/format-block-multiple-paragraphs.html: Added.
+ * editing/execCommand/format-block-table-expected.txt: Added.
+ * editing/execCommand/format-block-table.html: Added.
+ * editing/execCommand/format-block-with-braces-expected.txt: Removed erroneous br.
+
2010-10-14 Kinuko Yasuda <kinuko at chromium.org>
Unreviewed, asssigned a bug number to failing filesystem tests.
diff --git a/LayoutTests/editing/execCommand/format-block-expected.txt b/LayoutTests/editing/execCommand/format-block-expected.txt
index 9b21c11..03f0262 100644
--- a/LayoutTests/editing/execCommand/format-block-expected.txt
+++ b/LayoutTests/editing/execCommand/format-block-expected.txt
@@ -52,7 +52,6 @@ After FormatBlock:
"
| <pre>
| "Make Pre"
-| <br>
| "
"
| <br>
@@ -62,8 +61,9 @@ After FormatBlock:
| "Foo"
| <br>
| <h1>
-| "Make h1"
-| <br>
+| <span>
+| id="item2"
+| "Make h1"
| "baz"
| "
"
diff --git a/LayoutTests/editing/execCommand/format-block-from-range-selection-expected.txt b/LayoutTests/editing/execCommand/format-block-from-range-selection-expected.txt
index f8d91ac..aa68510 100644
--- a/LayoutTests/editing/execCommand/format-block-from-range-selection-expected.txt
+++ b/LayoutTests/editing/execCommand/format-block-from-range-selection-expected.txt
@@ -32,22 +32,23 @@ after FormatBlock:
"
| <dl>
| "Fo<#selection-anchor>o"
+| <br>
+| "bar"
+| <br>
+| <span>
+| "baz"
+| <br>
+| "raz"
+| <br>
+| "
+dar"
+| <br>
+| "
+"
+| "yar<#selection-focus>"
| "
"
-| <div>
-| <dl>
-| "bar"
-| <span>
-| <dl>
-| "baz"
-| <dl>
-| "raz"
-| <dl>
-| "dar"
-| " "
| "
"
-| <dl>
-| "ya<#selection-focus>r"
| "
"
diff --git a/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-expected.txt b/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-expected.txt
new file mode 100644
index 0000000..a524cc8
--- /dev/null
+++ b/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-expected.txt
@@ -0,0 +1,233 @@
+This tests ensures formatBlock do not make multiple elements when formatting multiple paragraphs.
+
+Formatting:
+| "
+"
+| <div>
+| "<#selection-anchor>hello"
+| <div>
+| "world"
+| <div>
+| "WebKit<#selection-focus>"
+| "
+"
+
+by p yields:
+| "
+"
+| <p>
+| "<#selection-anchor>hello"
+| <br>
+| "world"
+| <br>
+| "WebKit<#selection-focus>"
+| "
+"
+
+Formatting:
+| "
+"
+| <p>
+| "<#selection-anchor>hello"
+| <p>
+| "world<#selection-focus>"
+| "
+"
+
+by blockquote yields:
+| "
+"
+| <blockquote>
+| "<#selection-anchor>hello"
+| <br>
+| "world<#selection-focus>"
+| "
+"
+
+Formatting:
+| "
+"
+| <div>
+| "<#selection-anchor>hello"
+| <pre>
+| "world<#selection-focus>"
+| "
+"
+
+by p yields:
+| "
+"
+| <div>
+| <p>
+| "<#selection-anchor>hello"
+| <br>
+| "world<#selection-focus>"
+| "
+"
+
+Formatting:
+| "
+"
+| <h1>
+| "<#selection-anchor>hello"
+| <div>
+| <h2>
+| "world"
+| <h3>
+| "WebKit<#selection-focus>"
+| "
+"
+
+by pre yields:
+| "
+"
+| <pre>
+| "<#selection-anchor>hello"
+| <br>
+| "world"
+| <br>
+| "WebKit<#selection-focus>"
+| "
+"
+
+Formatting:
+| "
+"
+| <div>
+| "hello"
+| <p>
+| "<#selection-anchor>world"
+| "webki<#selection-focus>t"
+| "
+"
+
+by h1 yields:
+| "
+"
+| <div>
+| "hello"
+| <h1>
+| "<#selection-anchor>world"
+| <br>
+| "webkit<#selection-focus>"
+| "
+"
+
+Formatting:
+| "
+"
+| <pre>
+| "<#selection-anchor>hello
+world<#selection-focus>
+webkit
+"
+| "
+"
+
+by blockquote yields:
+| "
+"
+| <pre>
+| <blockquote>
+| "<#selection-anchor>hello"
+| <br>
+| "world<#selection-focus>"
+| <br>
+| "webkit"
+| "
+"
+
+Formatting:
+| "
+"
+| <pre>
+| "hello
+<#selection-anchor>world
+webki<#selection-focus>t
+"
+| "
+"
+
+by blockquote yields:
+| "
+"
+| <pre>
+| "hello
+"
+| <blockquote>
+| "<#selection-anchor>world"
+| <br>
+| "webki<#selection-focus>t"
+| "
+"
+
+Formatting:
+| "
+<#selection-anchor>hello"
+| <p>
+| "world<#selection-focus>"
+| <p>
+| "webkit"
+| "
+
+"
+
+by pre yields:
+| <pre>
+| "<#selection-anchor>
+hello"
+| <br>
+| "worl<#selection-focus>d"
+| <p>
+| "webkit"
+| "
+
+"
+
+Formatting:
+| "
+"
+| <div>
+| "hello"
+| <div>
+| "<#selection-anchor>world"
+| <div>
+| "webki<#selection-focus>t"
+| "
+"
+
+by pre yields:
+| "
+"
+| <div>
+| "hello"
+| <pre>
+| "<#selection-anchor>world"
+| <br>
+| "webki<#selection-focus>t"
+| "
+"
+
+Formatting:
+| "
+"
+| <ul>
+| <li>
+| "<#selection-anchor>hello"
+| <li>
+| "world<#selection-focus>"
+| "
+"
+
+by blockquote yields:
+| "
+"
+| <blockquote>
+| <ul>
+| <li>
+| "<#selection-anchor>hello"
+| <ul>
+| <li>
+| "world<#selection-focus>"
+| "
+"
diff --git a/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html b/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html
new file mode 100644
index 0000000..dc41425
--- /dev/null
+++ b/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/dump-as-markup.js"></script>
+<div id="test0" contenteditable>
+<div>hello</div><div>world</div><div>WebKit</div>
+</div>
+<div id="test1" contenteditable>
+<p>hello</p><p>world</p>
+</div>
+<div id="test2" contenteditable>
+<div>hello<pre>world</pre></div>
+</div>
+<div id="test3" contenteditable>
+<h1>hello</h1><div><h2>world</h2><h3>WebKit</h3></div>
+</div>
+<div id="test4" contenteditable>
+<div>hello<p>world</p>webkit</div>
+</div>
+<div id="test5" contenteditable>
+<pre>hello
+world
+webkit
+</pre>
+</div>
+<div id="test6" contenteditable>
+<pre>hello
+world
+webkit
+</pre>
+</div>
+<div id="test7" contenteditable>
+hello<p>world</p><p>webkit</p>
+</pre>
+</div>
+<div id="test8" contenteditable>
+<div>hello</div><div>world</div><div>webkit</div>
+</div>
+<div id="test9" contenteditable>
+<ul><li>hello</li><li>world</li></ul>
+</div>
+<script>
+
+Markup.description('This tests ensures formatBlock do not make multiple elements when formatting multiple paragraphs.')
+
+function testIndentation(containerId, selector, value) {
+ var container = document.getElementById(containerId);
+ selector(container);
+ Markup.dump(container, 'Formatting');
+ document.execCommand('FormatBlock', false, value);
+ Markup.dump(container, 'by ' + value + ' yields');
+}
+
+function selectAll(container) {
+ window.getSelection().selectAllChildren(container);
+}
+
+function selectorForLines(first, last) {
+ return function (container) {
+ window.getSelection().setPosition(container, 0);
+ for (var i = 0; i < first - 1; i++)
+ window.getSelection().modify('move', 'forward', 'line');
+ for (var i = 0; i < Math.abs(last - first, 0) + 1; i++)
+ window.getSelection().modify('extend', 'forward', 'line');
+ window.getSelection().modify('extend', 'backward', 'character');
+ }
+}
+
+testIndentation('test0', selectAll, 'p');
+testIndentation('test1', selectAll, 'blockquote');
+testIndentation('test2', selectAll, 'p');
+testIndentation('test3', selectAll, 'pre');
+testIndentation('test4', selectorForLines(2, 3), 'h1');
+testIndentation('test5', selectorForLines(1, 2), 'blockquote');
+testIndentation('test6', selectorForLines(2, 3), 'blockquote');
+testIndentation('test7', selectorForLines(1, 2), 'pre');
+testIndentation('test8', selectorForLines(2, 3), 'pre');
+testIndentation('test9', selectAll, 'blockquote');
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/execCommand/format-block-table-expected.txt b/LayoutTests/editing/execCommand/format-block-table-expected.txt
new file mode 100644
index 0000000..7f6ddde
--- /dev/null
+++ b/LayoutTests/editing/execCommand/format-block-table-expected.txt
@@ -0,0 +1,124 @@
+
+Formatting:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "hello"
+| <td>
+| "world"
+| "
+"
+
+by p yields:
+| "
+"
+| <p>
+| <#selection-anchor>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "hello"
+| <td>
+| "world"
+| <#selection-focus>
+| "
+"
+
+Formatting:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "<#selection-anchor>hello<#selection-focus>"
+| <td>
+| "world"
+| "
+"
+
+by blockquote yields:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <blockquote>
+| "<#selection-anchor>hello<#selection-focus>"
+| <td>
+| "world"
+| "
+"
+
+Formatting:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <p>
+| "<#selection-anchor>hello"
+| <div>
+| "world<#selection-focus>"
+| <td>
+| "WebKit"
+| "
+"
+
+by h3 yields:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <h3>
+| "<#selection-anchor>hello"
+| <br>
+| "world<#selection-focus>"
+| <td>
+| "WebKit"
+| "
+"
+
+Formatting:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <ul>
+| <li>
+| "<#selection-anchor>hello"
+| <li>
+| "world<#selection-focus>"
+| <td>
+| "WebKit"
+| "
+"
+
+by address yields:
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <address>
+| <ul>
+| <li>
+| "<#selection-anchor>hello"
+| <ul>
+| <li>
+| "world<#selection-focus>"
+| <td>
+| "WebKit"
+| "
+"
diff --git a/LayoutTests/editing/execCommand/format-block-table.html b/LayoutTests/editing/execCommand/format-block-table.html
new file mode 100644
index 0000000..28ba100
--- /dev/null
+++ b/LayoutTests/editing/execCommand/format-block-table.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/dump-as-markup.js"></script>
+<div id="test0" contenteditable>
+<table><tr><td>hello</td><td>world</td></tr></table>
+</div>
+<div id="test1" contenteditable>
+<table><tr><td>hello</td><td>world</td></tr></table>
+</div>
+<div id="test2" contenteditable>
+<table><tr><td><p>hello</p><div>world</div></td><td>WebKit</td></tr></table>
+</div>
+<div id="test3" contenteditable>
+<table><tr><td><ul><li>hello</li><li>world</li></ul></td><td>WebKit</td></tr></table>
+</div>
+<script>
+
+function testIndentation(containerId, selector, value) {
+ var container = document.getElementById(containerId);
+ selector(container);
+ Markup.dump(container, 'Formatting');
+ document.execCommand('FormatBlock', false, value);
+ Markup.dump(container, 'by ' + value + ' yields');
+}
+
+function selectAll(container) {
+ window.getSelection().selectAllChildren(container);
+}
+
+function selectFirstCell(container) {
+ window.getSelection().selectAllChildren(container.getElementsByTagName('td')[0]);
+}
+
+testIndentation('test0', selectAll, 'p');
+testIndentation('test1', selectFirstCell, 'blockquote');
+testIndentation('test2', selectFirstCell, 'h3');
+testIndentation('test3', selectFirstCell, 'address');
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/execCommand/format-block-with-braces-expected.txt b/LayoutTests/editing/execCommand/format-block-with-braces-expected.txt
index 89b4435..2b5b4dc 100644
--- a/LayoutTests/editing/execCommand/format-block-with-braces-expected.txt
+++ b/LayoutTests/editing/execCommand/format-block-with-braces-expected.txt
@@ -16,5 +16,6 @@ Format Me
After FormatBlock with <h1>:
| <h1>
-| "<#selection-caret>Format Me"
-| <br>
+| "
+<#selection-caret>Format Me
+"
diff --git a/LayoutTests/fast/html/nav-element-expected.txt b/LayoutTests/fast/html/nav-element-expected.txt
index 742d349..4cab53a 100644
--- a/LayoutTests/fast/html/nav-element-expected.txt
+++ b/LayoutTests/fast/html/nav-element-expected.txt
@@ -24,5 +24,7 @@ DOM for the above (so this test can dump as text)
<p><br></p>
-<div contenteditable="true" id="editable"><nav>Test of FormatBlock behavior. This text should have a green border.<br></nav></div>
+<div contenteditable="true" id="editable"><nav>
+Test of FormatBlock behavior. This text should have a green border.
+</nav></div>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 77e2ea5..953f1f0 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,39 @@
+2010-10-14 Ryosuke Niwa <rniwa at webkit.org>
+
+ Reviewed by Tony Chang and Darin Adler.
+
+ execCommand FormatBlock creates lots of blockquotes
+ https://bugs.webkit.org/show_bug.cgi?id=19795
+
+ The bug was caused by WebKit's not reusing the block node added by previous iteration
+ and its inserting block node at wrong places.
+
+ Fixed the bug by rewriting FormatBlockCommand::formatRange. New code resembles that of
+ IndentOutdentCommand::indentIntoBlockquote. The difference between two is that formatRange
+ avoids the existing block elements when replacing blocks and it also adds a placeholder
+ when removing the existing block caused paragraphs to collapse.
+
+ Also fixed a bug in moveParagraphWithClones where erroneous br is added to the start of
+ the block element to which the paragraph is moved if the block element is the start of a paragraph
+ and not the end of a paragraph.
+
+ Tests: editing/execCommand/format-block-multiple-paragraphs.html
+ editing/execCommand/format-block-table.html
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::moveParagraphWithClones): No longer adds erroneous br.
+ * editing/EditorCommand.cpp:
+ (WebCore::executeFormatBlock):
+ * editing/FormatBlockCommand.cpp:
+ (WebCore::FormatBlockCommand::formatRange): Rewritten; see above.
+ (WebCore::FormatBlockCommand::isElementToApplyInFormatBlockCommand): Renamed from validBlockElement
+ and moved from htmlediting.cpp.
+ (WebCore::enclosingBlockToSplitTreeTo): Added.
+ * editing/FormatBlockCommand.h:
+ * editing/VisiblePosition.cpp:
+ (WebCore::enclosingBlockFlowElement): Changed the return type to Element*
+ * editing/VisiblePosition.h:
+
2010-10-14 Justin Schuh <jschuh at chromium.org>
Reviewed by James Robinson.
diff --git a/WebCore/editing/ApplyBlockElementCommand.cpp b/WebCore/editing/ApplyBlockElementCommand.cpp
index d810555..ecd3d9b 100644
--- a/WebCore/editing/ApplyBlockElementCommand.cpp
+++ b/WebCore/editing/ApplyBlockElementCommand.cpp
@@ -112,10 +112,8 @@ void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel
VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection);
bool atEnd = false;
+ Position end;
while (endOfCurrentParagraph != endAfterSelection && !atEnd) {
- Position start;
- Position end;
-
if (endOfCurrentParagraph == endOfLastParagraph)
atEnd = true;
diff --git a/WebCore/editing/CompositeEditCommand.cpp b/WebCore/editing/CompositeEditCommand.cpp
index f27a2e5..4cb3005 100644
--- a/WebCore/editing/CompositeEditCommand.cpp
+++ b/WebCore/editing/CompositeEditCommand.cpp
@@ -863,7 +863,8 @@ void CompositeEditCommand::moveParagraphWithClones(const VisiblePosition& startO
beforeParagraph = VisiblePosition(beforeParagraph.deepEquivalent());
afterParagraph = VisiblePosition(afterParagraph.deepEquivalent());
- if (beforeParagraph.isNotNull() && !isTableElement(beforeParagraph.deepEquivalent().node()) && (!isEndOfParagraph(beforeParagraph) || beforeParagraph == afterParagraph)) {
+ if (beforeParagraph.isNotNull() && !isTableElement(beforeParagraph.deepEquivalent().node())
+ && ((!isEndOfParagraph(beforeParagraph) && !isStartOfParagraph(beforeParagraph)) || beforeParagraph == afterParagraph)) {
// FIXME: Trim text between beforeParagraph and afterParagraph if they aren't equal.
insertNodeAt(createBreakElement(document()), beforeParagraph.deepEquivalent());
}
diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp
index a7a5af5..a8a23fb 100644
--- a/WebCore/editing/EditorCommand.cpp
+++ b/WebCore/editing/EditorCommand.cpp
@@ -432,8 +432,6 @@ static bool executeFormatBlock(Frame* frame, Event*, EditorCommandSource, const
String tagName = value.lower();
if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
tagName = tagName.substring(1, tagName.length() - 2);
- if (!validBlockTag(tagName))
- return false;
ExceptionCode ec;
String localName, prefix;
@@ -441,6 +439,9 @@ static bool executeFormatBlock(Frame* frame, Event*, EditorCommandSource, const
return false;
QualifiedName qualifiedTagName(prefix, localName, xhtmlNamespaceURI);
+ if (!FormatBlockCommand::isElementToApplyInFormatBlockCommand(qualifiedTagName))
+ return false;
+
applyCommand(FormatBlockCommand::create(frame->document(), qualifiedTagName));
return true;
}
diff --git a/WebCore/editing/FormatBlockCommand.cpp b/WebCore/editing/FormatBlockCommand.cpp
index c4e81e2..1673235 100644
--- a/WebCore/editing/FormatBlockCommand.cpp
+++ b/WebCore/editing/FormatBlockCommand.cpp
@@ -36,46 +36,91 @@ namespace WebCore {
using namespace HTMLNames;
+static Node* enclosingBlockToSplitTreeTo(Node* startNode);
+
FormatBlockCommand::FormatBlockCommand(Document* document, const QualifiedName& tagName)
: ApplyBlockElementCommand(document, tagName)
{
}
-void FormatBlockCommand::formatRange(const Position&, const Position& end, RefPtr<Element>&)
+void FormatBlockCommand::formatRange(const Position& start, const Position& end, RefPtr<Element>& blockNode)
{
- setEndingSelection(VisiblePosition(end));
+ Node* nodeToSplitTo = enclosingBlockToSplitTreeTo(start.node());
+ RefPtr<Node> outerBlock = (start.node() == nodeToSplitTo) ? start.node() : splitTreeToNode(start.node(), nodeToSplitTo);
+ RefPtr<Node> nodeAfterInsertionPosition = outerBlock;
+
+ Element* refNode = enclosingBlockFlowElement(end);
+ Element* root = editableRootForPosition(start);
+ if (isElementToApplyInFormatBlockCommand(refNode->tagQName()) && start == startOfBlock(start) && end == endOfBlock(end)
+ && refNode != root && !root->isDescendantOf(refNode)) {
+ // Already in a block element that only contains the current paragraph
+ if (refNode->hasTagName(tagName()))
+ return;
+ nodeAfterInsertionPosition = refNode;
+ }
+
+ if (!blockNode) {
+ // Create a new blockquote and insert it as a child of the root editable element. We accomplish
+ // this by splitting all parents of the current paragraph up to that point.
+ blockNode = createBlockElement();
+ insertNodeBefore(blockNode, nodeAfterInsertionPosition);
+ }
- Node* refNode = enclosingBlockFlowElement(endingSelection().visibleStart());
- if (refNode->hasTagName(tagName()))
- // We're already in a block with the format we want, so we don't have to do anything
- return;
+ Position lastParagraphInBlockNode = lastPositionInNode(blockNode.get());
+ bool wasEndOfParagraph = isEndOfParagraph(lastParagraphInBlockNode);
- VisiblePosition paragraphStart = startOfParagraph(end);
- VisiblePosition paragraphEnd = endOfParagraph(end);
- VisiblePosition blockStart = startOfBlock(endingSelection().visibleStart());
- VisiblePosition blockEnd = endOfBlock(endingSelection().visibleStart());
- RefPtr<Element> blockNode = createBlockElement();
- RefPtr<Element> placeholder = createBreakElement(document());
+ moveParagraphWithClones(start, end, blockNode.get(), outerBlock.get());
- Node* root = endingSelection().start().node()->rootEditableElement();
- if (validBlockTag(refNode->nodeName().lower()) &&
- paragraphStart == blockStart && paragraphEnd == blockEnd &&
- refNode != root && !root->isDescendantOf(refNode))
- // Already in a valid block tag that only contains the current paragraph, so we can swap with the new tag
- insertNodeBefore(blockNode, refNode);
- else {
- // Avoid inserting inside inline elements that surround paragraphStart with upstream().
- // This is only to avoid creating bloated markup.
- insertNodeAt(blockNode, paragraphStart.deepEquivalent().upstream());
+ if (wasEndOfParagraph && !isEndOfParagraph(lastParagraphInBlockNode) && !isStartOfParagraph(lastParagraphInBlockNode))
+ insertBlockPlaceholder(lastParagraphInBlockNode);
+}
+
+// FIXME: We should consider merging this function with isElementForFormatBlockCommand in Editor.cpp
+// Checks if a tag name is valid for execCommand('FormatBlock').
+bool FormatBlockCommand::isElementToApplyInFormatBlockCommand(const QualifiedName& tagName)
+{
+ DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, blockTags, ());
+ if (blockTags.isEmpty()) {
+ blockTags.add(addressTag);
+ blockTags.add(articleTag);
+ blockTags.add(asideTag);
+ blockTags.add(blockquoteTag);
+ blockTags.add(ddTag);
+ blockTags.add(divTag);
+ blockTags.add(dlTag);
+ blockTags.add(dtTag);
+ blockTags.add(footerTag);
+ blockTags.add(h1Tag);
+ blockTags.add(h2Tag);
+ blockTags.add(h3Tag);
+ blockTags.add(h4Tag);
+ blockTags.add(h5Tag);
+ blockTags.add(h6Tag);
+ blockTags.add(headerTag);
+ blockTags.add(hgroupTag);
+ blockTags.add(navTag);
+ blockTags.add(pTag);
+ blockTags.add(preTag);
+ blockTags.add(sectionTag);
}
- appendNode(placeholder, blockNode);
+ return blockTags.contains(tagName);
+}
- VisiblePosition destination(Position(placeholder.get(), 0));
- if (paragraphStart == paragraphEnd && !lineBreakExistsAtVisiblePosition(paragraphStart)) {
- setEndingSelection(destination);
- return;
+Node* enclosingBlockToSplitTreeTo(Node* startNode)
+{
+ Node* lastBlock = startNode;
+ for (Node* n = startNode; n; n = n->parentNode()) {
+ if (!n->isContentEditable())
+ return lastBlock;
+ if (isTableCell(n) || n->hasTagName(bodyTag) || !n->parentNode() || !n->parentNode()->isContentEditable()
+ || (n->isElementNode() && FormatBlockCommand::isElementToApplyInFormatBlockCommand(static_cast<Element*>(n)->tagQName())))
+ return n;
+ if (isBlock(n))
+ lastBlock = n;
+ if (isListElement(n))
+ return n->parentNode()->isContentEditable() ? n->parentNode() : n;
}
- moveParagraph(paragraphStart, paragraphEnd, destination, true, false);
+ return lastBlock;
}
}
diff --git a/WebCore/editing/FormatBlockCommand.h b/WebCore/editing/FormatBlockCommand.h
index 5e9cb96..68a1f47 100644
--- a/WebCore/editing/FormatBlockCommand.h
+++ b/WebCore/editing/FormatBlockCommand.h
@@ -38,11 +38,13 @@ public:
return adoptRef(new FormatBlockCommand(document, tagName));
}
+ static bool isElementToApplyInFormatBlockCommand(const QualifiedName& tagName);
+
private:
FormatBlockCommand(Document*, const QualifiedName& tagName);
- virtual void formatRange(const Position&, const Position&, RefPtr<Element>&);
- virtual EditAction editingAction() const { return EditActionFormatBlock; }
+ void formatRange(const Position&, const Position&, RefPtr<Element>&);
+ EditAction editingAction() const { return EditActionFormatBlock; }
};
} // namespace WebCore
diff --git a/WebCore/editing/VisiblePosition.cpp b/WebCore/editing/VisiblePosition.cpp
index 1e68538..760c68c 100644
--- a/WebCore/editing/VisiblePosition.cpp
+++ b/WebCore/editing/VisiblePosition.cpp
@@ -634,7 +634,7 @@ bool setEnd(Range *r, const VisiblePosition &visiblePosition)
return code == 0;
}
-Node *enclosingBlockFlowElement(const VisiblePosition &visiblePosition)
+Element* enclosingBlockFlowElement(const VisiblePosition &visiblePosition)
{
if (visiblePosition.isNull())
return NULL;
diff --git a/WebCore/editing/VisiblePosition.h b/WebCore/editing/VisiblePosition.h
index fe795a1..e649b68 100644
--- a/WebCore/editing/VisiblePosition.h
+++ b/WebCore/editing/VisiblePosition.h
@@ -136,7 +136,7 @@ bool setEnd(Range*, const VisiblePosition&);
VisiblePosition startVisiblePosition(const Range*, EAffinity);
VisiblePosition endVisiblePosition(const Range*, EAffinity);
-Node *enclosingBlockFlowElement(const VisiblePosition&);
+Element* enclosingBlockFlowElement(const VisiblePosition&);
bool isFirstVisiblePositionInNode(const VisiblePosition&, const Node*);
bool isLastVisiblePositionInNode(const VisiblePosition&, const Node*);
diff --git a/WebCore/editing/htmlediting.cpp b/WebCore/editing/htmlediting.cpp
index 9ec71e7..7927900 100644
--- a/WebCore/editing/htmlediting.cpp
+++ b/WebCore/editing/htmlediting.cpp
@@ -465,39 +465,6 @@ bool isSpecialElement(const Node *n)
return false;
}
-// Checks if a string is a valid tag for the FormatBlockCommand function of execCommand. Expects lower case strings.
-bool validBlockTag(const AtomicString& blockTag)
-{
- if (blockTag.isEmpty())
- return false;
-
- DEFINE_STATIC_LOCAL(HashSet<AtomicString>, blockTags, ());
- if (blockTags.isEmpty()) {
- blockTags.add(addressTag.localName());
- blockTags.add(articleTag.localName());
- blockTags.add(asideTag.localName());
- blockTags.add(blockquoteTag.localName());
- blockTags.add(ddTag.localName());
- blockTags.add(divTag.localName());
- blockTags.add(dlTag.localName());
- blockTags.add(dtTag.localName());
- blockTags.add(footerTag.localName());
- blockTags.add(h1Tag.localName());
- blockTags.add(h2Tag.localName());
- blockTags.add(h3Tag.localName());
- blockTags.add(h4Tag.localName());
- blockTags.add(h5Tag.localName());
- blockTags.add(h6Tag.localName());
- blockTags.add(headerTag.localName());
- blockTags.add(hgroupTag.localName());
- blockTags.add(navTag.localName());
- blockTags.add(pTag.localName());
- blockTags.add(preTag.localName());
- blockTags.add(sectionTag.localName());
- }
- return blockTags.contains(blockTag);
-}
-
static Node* firstInSpecialElement(const Position& pos)
{
// FIXME: This begins at pos.node(), which doesn't necessarily contain pos (suppose pos was [img, 0]). See <rdar://problem/5027702>.
diff --git a/WebCore/editing/htmlediting.h b/WebCore/editing/htmlediting.h
index aaf6ef2..1892357 100644
--- a/WebCore/editing/htmlediting.h
+++ b/WebCore/editing/htmlediting.h
@@ -228,8 +228,6 @@ VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
String stringWithRebalancedWhitespace(const String&, bool, bool);
const String& nonBreakingSpaceString();
-bool validBlockTag(const AtomicString&);
-
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list