<rdar://problem/
4026787> text typed after a link (pasted or Mail Link to this Page) is part of the link, underlined and colored blue
The concept of this change is every time you type at the very
start or very end of a link (even if nested in further inner
elements), the typed text goes outside the link instead of inside.
* khtml/editing/htmlediting.cpp:
(khtml::InsertTextCommand::prepareForTextInsertion): Check whether
we are at the first visible position or last visible position of a
special element. For now this only includes HTML A elements that
are links (i.e. they have an href).
(khtml::isSpecialElement): Helper function that identifies special
elements (for now only links).
(khtml::isFirstVisiblePositionInSpecialElement): Checks if a given DOM
position is equivalent to the first visible position in some containing
editable special element.
(khtml::positionBeforeNode): Returns the DOM position immediately
before a node.
(khtml::positionBeforeContainingSpecialElement): Gives a DOM
position immediately before the outermost editable containing
special element where the passed-in position is equivalent to the
first visible position.
(khtml::maxRangeOffset): Helper to get the maximum allowed
range/position offset for a node, does the right thing based on
whether the node would use a character offset or child offset.
(khtml::isLastVisiblePositionInSpecialElement): Similar to above,
but for end of node instead of start.
(khtml::positionAfterNode): Ditto.
(khtml::positionAfterContainingSpecialElement): Ditto.
Some layout tests changed - I looked over all the diffs and found
that the only changes were "junk nodes" like empty spans and text
nodes moving from one spot in the tree to another. These changes
are all harmless and do not affect layout or future editing.
* layout-tests/editing/inserting/typing-003-expected.txt:
* layout-tests/editing/style/remove-underline-across-paragraph-expected.txt:
* layout-tests/editing/style/remove-underline-across-paragraph-in-bold-expected.txt:
* layout-tests/editing/style/remove-underline-after-paragraph-expected.txt:
* layout-tests/editing/style/remove-underline-after-paragraph-in-bold-expected.txt:
* layout-tests/editing/style/remove-underline-expected.txt:
* layout-tests/editing/style/remove-underline-from-stylesheet-expected.txt:
* layout-tests/editing/style/remove-underline-in-bold-expected.txt:
* layout-tests/editing/style/typing-style-003-expected.txt:
* layout-tests/editing/style/unbold-in-bold-expected.txt:
* layout-tests/editing/style/underline-expected.txt:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8868
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x140 [border: (2px solid #FF0000)]
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderText {TEXT} at (14,14) size 732x112
text run at (14,14) width 696: "xxxx x xx xxxx xxxxxx xxxxx xxxxxx xxx xx xxxx xxx xxx xx x xxxxx"
text run at (14,42) width 732: "xxxxxxxxxxxx xxxxxxxx xxx xxxx xxxxx xx xxx xxxx xxxx xxxxx xxxxxx"
text run at (14,70) width 714: "xxx xx xxxx xxx xxx xx xxxxxx xxxxx xxxxxx xxx xx xxxx xxx xxx xx x"
text run at (14,98) width 360: "xxxxx xxxxxxxxxxxx xxxxxxxx xxx "
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
-start: position 233 of child 4 {TEXT} of root {DIV}
-upstream: position 233 of child 4 {TEXT} of root {DIV}
-downstream: position 233 of child 4 {TEXT} of root {DIV}
+start: position 233 of child 1 {TEXT} of root {DIV}
+upstream: position 233 of child 1 {TEXT} of root {DIV}
+downstream: position 1 of child 4 {TEXT} of root {DIV}
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderBlock (anonymous) at (14,14) size 756x28
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 78x28
RenderText {TEXT} at (0,0) size 78x28
text run at (0,0) width 78: "xxxxxx "
RenderText {TEXT} at (78,0) size 72x28
text run at (78,0) width 72: "xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
RenderBlock {DIV} at (14,42) size 756x28
RenderText {TEXT} at (0,0) size 78x28
text run at (0,0) width 78: " xxxxxx"
RenderText {TEXT} at (78,0) size 78x28
text run at (78,0) width 78: " xxxxxx"
selection is RANGE:
-start: position 0 of child 5 {TEXT} of root {DIV}
-upstream: position 7 of child 1 {TEXT} of child 4 {SPAN} of root {DIV}
-downstream: position 0 of child 5 {TEXT} of root {DIV}
+start: position 0 of child 2 {TEXT} of root {DIV}
+upstream: position 7 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 2 {TEXT} of root {DIV}
end: position 7 of child 1 {TEXT} of child 6 {DIV} of root {DIV}
upstream: position 7 of child 1 {TEXT} of child 6 {DIV} of root {DIV}
downstream: position 0 of child 1 {TEXT} of child 2 {SPAN} of child 6 {DIV} of root {DIV}
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderBlock (anonymous) at (14,14) size 756x28
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 150x28
RenderInline {B} at (0,0) size 78x28
RenderText {TEXT} at (0,0) size 78x28
RenderInline {B} at (0,0) size 72x28
RenderText {TEXT} at (78,0) size 72x28
text run at (78,0) width 72: "xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
RenderBlock {DIV} at (14,42) size 756x28
RenderInline {SPAN} at (0,0) size 156x28
RenderInline {B} at (0,0) size 78x28
RenderText {TEXT} at (78,0) size 78x28
text run at (78,0) width 78: " xxxxxx"
selection is RANGE:
-start: position 0 of child 1 {TEXT} of child 2 {B} of child 4 {SPAN} of root {DIV}
-upstream: position 7 of child 1 {TEXT} of child 1 {B} of child 4 {SPAN} of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 2 {B} of child 4 {SPAN} of root {DIV}
+start: position 0 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of root {DIV}
+upstream: position 7 of child 1 {TEXT} of child 1 {B} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of root {DIV}
end: position 7 of child 1 {TEXT} of child 1 {B} of child 1 {SPAN} of child 5 {DIV} of root {DIV}
upstream: position 7 of child 1 {TEXT} of child 1 {B} of child 1 {SPAN} of child 5 {DIV} of root {DIV}
downstream: position 0 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of child 5 {DIV} of root {DIV}
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderBlock (anonymous) at (14,14) size 756x28
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 150x28
RenderText {TEXT} at (0,0) size 150x28
text run at (0,0) width 150: "xxxxxx xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
RenderBlock {DIV} at (14,42) size 756x28
RenderText {TEXT} at (0,0) size 156x28
text run at (0,0) width 156: " xxxxxx xxxxxx"
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderBlock (anonymous) at (14,14) size 756x28
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 150x28
RenderInline {B} at (0,0) size 150x28
RenderText {TEXT} at (0,0) size 150x28
text run at (0,0) width 150: "xxxxxx xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
RenderBlock {DIV} at (14,42) size 756x28
RenderInline {B} at (0,0) size 156x28
RenderText {TEXT} at (0,0) size 156x28
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 78x28
RenderText {TEXT} at (14,14) size 78x28
text run at (14,14) width 78: "xxxxxx "
RenderInline {SPAN} at (0,0) size 78x28
RenderText {TEXT} at (164,14) size 78x28
text run at (164,14) width 78: " xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
selection is RANGE:
-start: position 0 of child 5 {TEXT} of root {DIV}
-upstream: position 7 of child 1 {TEXT} of child 4 {SPAN} of root {DIV}
-downstream: position 0 of child 5 {TEXT} of root {DIV}
-end: position 6 of child 5 {TEXT} of root {DIV}
-upstream: position 6 of child 5 {TEXT} of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 6 {SPAN} of root {DIV}
+start: position 0 of child 2 {TEXT} of root {DIV}
+upstream: position 7 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 2 {TEXT} of root {DIV}
+end: position 6 of child 2 {TEXT} of root {DIV}
+upstream: position 6 of child 2 {TEXT} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 3 {SPAN} of root {DIV}
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 78x28
- RenderText {TEXT} at (0,0) size 0x0
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderText {TEXT} at (14,14) size 78x28
text run at (14,14) width 78: "xxxxxx "
RenderText {TEXT} at (92,14) size 72x28
RenderInline {SPAN} at (0,0) size 78x28
RenderText {TEXT} at (164,14) size 78x28
text run at (164,14) width 78: " xxxxxx"
+ RenderText {TEXT} at (0,0) size 0x0
+ RenderInline {SPAN} at (0,0) size 0x0
+ RenderText {TEXT} at (0,0) size 0x0
selection is RANGE:
start: position 0 of child 2 {TEXT} of root {DIV}
-upstream: position 7 of child 4 {TEXT} of child 1 {SPAN} of root {DIV}
+upstream: position 7 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
downstream: position 0 of child 2 {TEXT} of root {DIV}
end: position 6 of child 2 {TEXT} of root {DIV}
upstream: position 6 of child 2 {TEXT} of root {DIV}
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 228x28
RenderInline {B} at (0,0) size 78x28
RenderText {TEXT} at (14,14) size 78x28
RenderInline {B} at (0,0) size 78x28
RenderText {TEXT} at (164,14) size 78x28
text run at (164,14) width 78: " xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
selection is RANGE:
-start: position 0 of child 1 {TEXT} of child 2 {B} of child 4 {SPAN} of root {DIV}
-upstream: position 7 of child 1 {TEXT} of child 1 {B} of child 4 {SPAN} of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 2 {B} of child 4 {SPAN} of root {DIV}
-end: position 6 of child 1 {TEXT} of child 2 {B} of child 4 {SPAN} of root {DIV}
-upstream: position 6 of child 1 {TEXT} of child 2 {B} of child 4 {SPAN} of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 3 {B} of child 4 {SPAN} of root {DIV}
+start: position 0 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of root {DIV}
+upstream: position 7 of child 1 {TEXT} of child 1 {B} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of root {DIV}
+end: position 6 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of root {DIV}
+upstream: position 6 of child 1 {TEXT} of child 2 {B} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 3 {B} of child 1 {SPAN} of root {DIV}
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 177x28
- RenderText {TEXT} at (0,0) size 0x0
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderText {TEXT} at (14,14) size 36x28
text run at (14,14) width 36: "xxx"
RenderInline {B} at (0,0) size 141x28
RenderInline {SPAN} at (0,0) size 36x28
RenderText {TEXT} at (155,14) size 36x28
text run at (155,14) width 36: "xxx"
+ RenderText {TEXT} at (0,0) size 0x0
+ RenderInline {SPAN} at (0,0) size 0x0
+ RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
-start: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 5 {B} of child 1 {SPAN} of root {DIV}
-upstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 5 {B} of child 1 {SPAN} of root {DIV}
-downstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 5 {B} of child 1 {SPAN} of root {DIV}
+start: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 2 {B} of child 1 {SPAN} of root {DIV}
+upstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 2 {B} of child 1 {SPAN} of root {DIV}
+downstream: position 1 of child 5 {TEXT} of child 1 {SPAN} of root {DIV}
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {B} at (0,0) size 78x28
RenderText {TEXT} at (14,14) size 78x28
text run at (14,14) width 78: "xxxxxx "
RenderInline {B} at (0,0) size 78x28
RenderText {TEXT} at (164,14) size 78x28
text run at (164,14) width 78: " xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
selection is RANGE:
-start: position 0 of child 5 {TEXT} of root {DIV}
-upstream: position 7 of child 1 {TEXT} of child 4 {B} of root {DIV}
-downstream: position 0 of child 5 {TEXT} of root {DIV}
-end: position 6 of child 5 {TEXT} of root {DIV}
-upstream: position 6 of child 5 {TEXT} of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 6 {B} of root {DIV}
+start: position 0 of child 2 {TEXT} of root {DIV}
+upstream: position 7 of child 1 {TEXT} of child 1 {B} of root {DIV}
+downstream: position 0 of child 2 {TEXT} of root {DIV}
+end: position 6 of child 2 {TEXT} of root {DIV}
+upstream: position 6 of child 2 {TEXT} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 3 {B} of root {DIV}
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
- RenderInline {SPAN} at (0,0) size 0x0
- RenderText {TEXT} at (0,0) size 0x0
RenderInline {SPAN} at (0,0) size 228x28
RenderText {TEXT} at (14,14) size 228x28
text run at (14,14) width 228: "xxxxxx xxxxxx xxxxxx"
+ RenderInline {SPAN} at (0,0) size 0x28
+ RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
-start: position 20 of child 1 {TEXT} of child 4 {SPAN} of root {DIV}
-upstream: position 20 of child 1 {TEXT} of child 4 {SPAN} of root {DIV}
-downstream: position 20 of child 1 {TEXT} of child 4 {SPAN} of root {DIV}
+start: position 20 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+upstream: position 20 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+downstream: position 1 of child 4 {TEXT} of root {DIV}
+2005-03-11 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Kevin.
+
+ <rdar://problem/4026787> text typed after a link (pasted or Mail Link to this Page) is part of the link, underlined and colored blue
+
+ The concept of this change is every time you type at the very
+ start or very end of a link (even if nested in further inner
+ elements), the typed text goes outside the link instead of inside.
+
+ * khtml/editing/htmlediting.cpp:
+ (khtml::InsertTextCommand::prepareForTextInsertion): Check whether
+ we are at the first visible position or last visible position of a
+ special element. For now this only includes HTML A elements that
+ are links (i.e. they have an href).
+ (khtml::isSpecialElement): Helper function that identifies special
+ elements (for now only links).
+ (khtml::isFirstVisiblePositionInSpecialElement): Checks if a given DOM
+ position is equivalent to the first visible position in some containing
+ editable special element.
+ (khtml::positionBeforeNode): Returns the DOM position immediately
+ before a node.
+ (khtml::positionBeforeContainingSpecialElement): Gives a DOM
+ position immediately before the outermost editable containing
+ special element where the passed-in position is equivalent to the
+ first visible position.
+ (khtml::maxRangeOffset): Helper to get the maximum allowed
+ range/position offset for a node, does the right thing based on
+ whether the node would use a character offset or child offset.
+ (khtml::isLastVisiblePositionInSpecialElement): Similar to above,
+ but for end of node instead of start.
+ (khtml::positionAfterNode): Ditto.
+ (khtml::positionAfterContainingSpecialElement): Ditto.
+
+ Some layout tests changed - I looked over all the diffs and found
+ that the only changes were "junk nodes" like empty spans and text
+ nodes moving from one spot in the tree to another. These changes
+ are all harmless and do not affect layout or future editing.
+
+ * layout-tests/editing/inserting/typing-003-expected.txt:
+ * layout-tests/editing/style/remove-underline-across-paragraph-expected.txt:
+ * layout-tests/editing/style/remove-underline-across-paragraph-in-bold-expected.txt:
+ * layout-tests/editing/style/remove-underline-after-paragraph-expected.txt:
+ * layout-tests/editing/style/remove-underline-after-paragraph-in-bold-expected.txt:
+ * layout-tests/editing/style/remove-underline-expected.txt:
+ * layout-tests/editing/style/remove-underline-from-stylesheet-expected.txt:
+ * layout-tests/editing/style/remove-underline-in-bold-expected.txt:
+ * layout-tests/editing/style/typing-style-003-expected.txt:
+ * layout-tests/editing/style/unbold-in-bold-expected.txt:
+ * layout-tests/editing/style/underline-expected.txt:
+
2005-03-11 Adele Amchan <adele@apple.com>
backing out fix for <rdar://problem/4021711> REGRESSION (125-188): blank pages when browsing forum at cooperativeresearch.org - cached external script problem
#include "dom_positioniterator.h"
#include "dom_stringimpl.h"
#include "dom_textimpl.h"
+#include "dom2_range.h"
#include "dom2_rangeimpl.h"
#include "html_elementimpl.h"
#include "html_imageimpl.h"
{
}
+static bool isSpecialElement(NodeImpl *n)
+{
+ if (!n->isHTMLElement())
+ return false;
+
+ if (n->id() == ID_A && n->hasAnchor())
+ return true;
+
+ return false;
+}
+
+static bool isFirstVisiblePositionInSpecialElement(const Position& pos)
+{
+ VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
+
+ for (NodeImpl *n = pos.node(); n; n = n->parentNode()) {
+ if (VisiblePosition(n, 0, DOWNSTREAM) != vPos)
+ return false;
+ if (n->rootEditableElement() == NULL)
+ return false;
+ if (isSpecialElement(n))
+ return true;
+ }
+
+ return false;
+}
+
+Position positionBeforeNode(NodeImpl *node)
+{
+ return Position(node->parentNode(), node->nodeIndex());
+}
+
+Position positionBeforeContainingSpecialElement(const Position& pos)
+{
+ ASSERT(isFirstVisiblePositionInSpecialElement(pos));
+
+ VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM);
+
+ NodeImpl *outermostSpecialElement = NULL;
+
+ for (NodeImpl *n = pos.node(); n; n = n->parentNode()) {
+ if (VisiblePosition(n, 0, DOWNSTREAM) != vPos)
+ break;
+ if (n->rootEditableElement() == NULL)
+ break;
+ if (isSpecialElement(n))
+ outermostSpecialElement = n;
+ }
+
+ ASSERT(outermostSpecialElement);
+
+ return positionBeforeNode(outermostSpecialElement);
+}
+
+static int maxRangeOffset(NodeImpl *n)
+{
+ if (DOM::offsetInCharacters(n->nodeType()))
+ return n->maxOffset();
+
+ if (n->isElementNode())
+ return n->childNodeCount();
+
+ return 1;
+}
+
+static bool isLastVisiblePositionInSpecialElement(const Position& pos)
+{
+ // make sure to get a range-compliant version of the position
+ Position rangePos = VisiblePosition(pos, DOWNSTREAM).position();
+
+ VisiblePosition vPos = VisiblePosition(rangePos, DOWNSTREAM);
+
+ for (NodeImpl *n = rangePos.node(); n; n = n->parentNode()) {
+ if (VisiblePosition(n, maxRangeOffset(n), DOWNSTREAM) != vPos)
+ return false;
+ if (n->rootEditableElement() == NULL)
+ return false;
+ if (isSpecialElement(n))
+ return true;
+ }
+
+ return false;
+}
+
+Position positionAfterNode(NodeImpl *node)
+{
+ return Position(node->parentNode(), node->nodeIndex() + 1);
+}
+
+Position positionAfterContainingSpecialElement(const Position& pos)
+{
+ ASSERT(isLastVisiblePositionInSpecialElement(pos));
+
+ // make sure to get a range-compliant version of the position
+ Position rangePos = VisiblePosition(pos, DOWNSTREAM).position();
+
+ VisiblePosition vPos = VisiblePosition(rangePos, DOWNSTREAM);
+
+ NodeImpl *outermostSpecialElement = NULL;
+
+ for (NodeImpl *n = rangePos.node(); n; n = n->parentNode()) {
+ if (VisiblePosition(n, maxRangeOffset(n), DOWNSTREAM) != vPos)
+ break;
+ if (n->rootEditableElement() == NULL)
+ break;
+ if (isSpecialElement(n))
+ outermostSpecialElement = n;
+ }
+
+ ASSERT(outermostSpecialElement);
+
+ return positionAfterNode(outermostSpecialElement);
+}
+
Position InsertTextCommand::prepareForTextInsertion(bool adjustDownstream)
{
// Prepare for text input by looking at the current position.
Selection typingStyleRange;
+ if (isFirstVisiblePositionInSpecialElement(pos)) {
+ pos = positionBeforeContainingSpecialElement(pos);
+ } else if (isLastVisiblePositionInSpecialElement(pos)) {
+ pos = positionAfterContainingSpecialElement(pos);
+ }
+
if (!pos.node()->isTextNode()) {
NodeImpl *textNode = document()->createEditingTextNode("");
NodeImpl *nodeToInsert = textNode;
// Now insert the node in the right place
- if (pos.node()->isEditableBlock()) {
+ if (pos.node()->rootEditableElement() != NULL) {
LOG(Editing, "prepareForTextInsertion case 1");
- appendNode(nodeToInsert, pos.node());
+ insertNodeAt(nodeToInsert, pos.node(), pos.offset());
}
else if (pos.node()->caretMinOffset() == pos.offset()) {
LOG(Editing, "prepareForTextInsertion case 2");