- remove isFirstVisiblePositionInBlock and isLastVisiblePositionInBlock, in favor of isStartOfBlock and isEndOfBlock
It turned out that both isEndOfBlock and isLastVisiblePositionInBlock had (different) bugs,
and there was code relying on the bugs of each. So in addition I fixed isEndOfBlock and fixed
the parts of the code relying on buggy behavior.
I also removed the includeEndOfLine parameter to endOfBlock since no one used it and it's not
clear if it would ever be useful.
* khtml/editing/htmlediting.cpp:
(khtml::InsertLineBreakCommand::doApply): Use new calls.
(khtml::InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion): Don't gratuitously make
an UPSTREAM VisiblePosition, as this will cause trouble comparing it to end of block.
(khtml::InsertParagraphSeparatorCommand::doApply): Use new calls.
(khtml::ReplaceSelectionCommand::doApply): Use new calls. Also, don't make a position <BR,0> and test
if it is the end of a block, that can never be true, although the buggy code in
isLastVisiblePositionInBlock would say it is. Make <BR,1> instead.
* khtml/editing/markup.cpp:
(khtml::createMarkup): Instead of checking isEndOfBlock on the start position, check if the start's
next is in a different block, to avoid relying on the buggy old isEndOfBlock behavior.
* khtml/editing/visible_position.cpp:
(khtml::isFirstVisiblePositionInParagraph): Use isStartOfBlock.
(khtml::isLastVisiblePositionInParagraph): Use isEndOfBlock.
* khtml/editing/visible_position.h:
* khtml/editing/visible_units.cpp:
(khtml::endOfBlock): Greatly simplify, and no longer consider the start of a descendant
block to be the end of the block. That's inconsistent with how startOfBlock works. Also
remove include end of line parameter.
(khtml::isEndOfBlock): Don't pass unneeded parameter.
* khtml/editing/visible_units.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9148
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2005-05-09 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Kevin.
+
+ - remove isFirstVisiblePositionInBlock and isLastVisiblePositionInBlock, in favor of isStartOfBlock and isEndOfBlock
+
+ It turned out that both isEndOfBlock and isLastVisiblePositionInBlock had (different) bugs,
+ and there was code relying on the bugs of each. So in addition I fixed isEndOfBlock and fixed
+ the parts of the code relying on buggy behavior.
+
+ I also removed the includeEndOfLine parameter to endOfBlock since no one used it and it's not
+ clear if it would ever be useful.
+
+ * khtml/editing/htmlediting.cpp:
+ (khtml::InsertLineBreakCommand::doApply): Use new calls.
+ (khtml::InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion): Don't gratuitously make
+ an UPSTREAM VisiblePosition, as this will cause trouble comparing it to end of block.
+ (khtml::InsertParagraphSeparatorCommand::doApply): Use new calls.
+ (khtml::ReplaceSelectionCommand::doApply): Use new calls. Also, don't make a position <BR,0> and test
+ if it is the end of a block, that can never be true, although the buggy code in
+ isLastVisiblePositionInBlock would say it is. Make <BR,1> instead.
+ * khtml/editing/markup.cpp:
+ (khtml::createMarkup): Instead of checking isEndOfBlock on the start position, check if the start's
+ next is in a different block, to avoid relying on the buggy old isEndOfBlock behavior.
+ * khtml/editing/visible_position.cpp:
+ (khtml::isFirstVisiblePositionInParagraph): Use isStartOfBlock.
+ (khtml::isLastVisiblePositionInParagraph): Use isEndOfBlock.
+ * khtml/editing/visible_position.h:
+ * khtml/editing/visible_units.cpp:
+ (khtml::endOfBlock): Greatly simplify, and no longer consider the start of a descendant
+ block to be the end of the block. That's inconsistent with how startOfBlock works. Also
+ remove include end of line parameter.
+ (khtml::isEndOfBlock): Don't pass unneeded parameter.
+ * khtml/editing/visible_units.h:
+
2005-05-09 Adele Peterson <adele@apple.com>
fix for <rdar://problem/4110775> Crash will occur when double-clicking outerHTML link on W3 DOM test
bool atStart = pos.offset() <= pos.node()->caretMinOffset();
bool atEnd = pos.offset() >= pos.node()->caretMaxOffset();
- bool atEndOfBlock = isLastVisiblePositionInBlock(VisiblePosition(pos, selection.startAffinity()));
+ bool atEndOfBlock = isEndOfBlock(VisiblePosition(pos, selection.startAffinity()));
if (atEndOfBlock) {
LOG(Editing, "input newline case 1");
// It is only important to set a style to apply later if we're at the boundaries of
// a paragraph. Otherwise, content that is moved as part of the work of the command
// will lend their styles to the new paragraph without any extra work needed.
- VisiblePosition visiblePos(pos, UPSTREAM);
+ VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY);
if (!isFirstVisiblePositionInParagraph(visiblePos) && !isLastVisiblePositionInParagraph(visiblePos))
return;
return;
VisiblePosition visiblePos(pos, affinity);
- bool isFirstInBlock = isFirstVisiblePositionInBlock(visiblePos);
- bool isLastInBlock = isLastVisiblePositionInBlock(visiblePos);
+ bool isFirstInBlock = isStartOfBlock(visiblePos);
+ bool isLastInBlock = isEndOfBlock(visiblePos);
bool startBlockIsRoot = startBlock == startBlock->rootEditableElement();
// This is the block that is going to be inserted.
VisiblePosition visibleStart(selection.start(), selection.startAffinity());
VisiblePosition visibleEnd(selection.end(), selection.endAffinity());
- bool startAtStartOfBlock = isFirstVisiblePositionInBlock(visibleStart);
- bool startAtEndOfBlock = isLastVisiblePositionInBlock(visibleStart);
+ bool startAtStartOfBlock = isStartOfBlock(visibleStart);
+ bool startAtEndOfBlock = isEndOfBlock(visibleStart);
bool startAtBlockBoundary = startAtStartOfBlock || startAtEndOfBlock;
NodeImpl *startBlock = selection.start().node()->enclosingBlockFlowElement();
NodeImpl *endBlock = selection.end().node()->enclosingBlockFlowElement();
NodeImpl *insertionBlock = insertionPos.node()->enclosingBlockFlowElement();
bool insertionBlockIsRoot = insertionBlock == insertionBlock->rootEditableElement();
VisiblePosition visiblePos(insertionPos, DOWNSTREAM);
- if (!insertionBlockIsRoot && isProbablyBlock(refNode) && isFirstVisiblePositionInBlock(visiblePos))
+ if (!insertionBlockIsRoot && isProbablyBlock(refNode) && isStartOfBlock(visiblePos))
insertNodeBeforeAndUpdateNodesInserted(refNode, insertionBlock);
- else if (!insertionBlockIsRoot && isProbablyBlock(refNode) && isLastVisiblePositionInBlock(visiblePos)) {
+ else if (!insertionBlockIsRoot && isProbablyBlock(refNode) && isEndOfBlock(visiblePos)) {
insertNodeAfterAndUpdateNodesInserted(refNode, insertionBlock);
} else if (mergeStart && !isProbablyBlock(refNode)) {
Position pos = visiblePos.next().deepEquivalent().downstream();
else {
if (m_lastNodeInserted && m_lastNodeInserted->id() == ID_BR && !document()->inStrictMode()) {
document()->updateLayout();
- VisiblePosition pos(Position(m_lastNodeInserted, 0), DOWNSTREAM);
- if (isLastVisiblePositionInBlock(pos)) {
+ VisiblePosition pos(Position(m_lastNodeInserted, 1), DOWNSTREAM);
+ if (isEndOfBlock(pos)) {
NodeImpl *next = m_lastNodeInserted->traverseNextNode();
bool hasTrailingBR = next && next->id() == ID_BR && m_lastNodeInserted->enclosingBlockFlowElement() == next->enclosingBlockFlowElement();
if (!hasTrailingBR) {
NodeImpl *startNode = range->startNode();
VisiblePosition visibleStart(range->startPosition(), VP_DEFAULT_AFFINITY);
VisiblePosition visibleEnd(range->endPosition(), VP_DEFAULT_AFFINITY);
- if (isEndOfBlock(visibleStart)) {
+ if (!inSameBlock(visibleStart, visibleStart.next())) {
if (visibleStart == visibleEnd.previous())
return interchangeNewlineString;
markups.append(interchangeNewlineString);
*/
#include "visible_position.h"
+#include "visible_units.h"
#include "misc/htmltags.h"
#include "rendering/render_line.h"
if (pos.isNull())
return false;
- return pos.deepEquivalent().upstream().node()->id() == ID_BR || isFirstVisiblePositionInBlock(pos);
-}
-
-bool isFirstVisiblePositionInBlock(const VisiblePosition &pos)
-{
- if (pos.isNull())
- return false;
-
- Position upstream = pos.deepEquivalent().upstream();
- return upstream.node()->isBlockFlow() && upstream.offset() == 0;
+ return pos.deepEquivalent().upstream().node()->id() == ID_BR || isStartOfBlock(pos);
}
bool isFirstVisiblePositionInNode(const VisiblePosition &pos, const NodeImpl *node)
if (pos.isNull())
return false;
- return pos.deepEquivalent().downstream().node()->id() == ID_BR || isLastVisiblePositionInBlock(pos);
-}
-
-bool isLastVisiblePositionInBlock(const VisiblePosition &pos)
-{
- if (pos.isNull())
- return false;
-
- VisiblePosition next = pos.next();
- if (next.isNull())
- return true;
-
- switch (blockRelationship(pos, next)) {
- case NoBlockRelationship:
- case SameBlockRelationship:
- case AncestorBlockRelationship:
- return false;
- case OtherBlockRelationship:
- case PeerBlockRelationship:
- case DescendantBlockRelationship:
- return true;
- }
- ASSERT_NOT_REACHED();
- return false;
+ return pos.deepEquivalent().downstream().node()->id() == ID_BR || isEndOfBlock(pos);
}
bool isLastVisiblePositionInNode(const VisiblePosition &pos, const NodeImpl *node)
bool visiblePositionsInDifferentBlocks(const VisiblePosition &, const VisiblePosition &);
bool isFirstVisiblePositionOnLine(const VisiblePosition &);
bool isFirstVisiblePositionInParagraph(const VisiblePosition &);
-bool isFirstVisiblePositionInBlock(const VisiblePosition &);
bool isFirstVisiblePositionInNode(const VisiblePosition &, const DOM::NodeImpl *);
bool isLastVisiblePositionOnLine(const VisiblePosition &);
bool isLastVisiblePositionInParagraph(const VisiblePosition &);
-bool isLastVisiblePositionInBlock(const VisiblePosition &);
bool isLastVisiblePositionInNode(const VisiblePosition &, const DOM::NodeImpl *);
} // namespace khtml
}
// written, but not yet tested
-VisiblePosition endOfBlock(const VisiblePosition &c, EIncludeLineBreak includeLineBreak)
+VisiblePosition endOfBlock(const VisiblePosition &c)
{
Position p = c.deepEquivalent();
return VisiblePosition();
NodeImpl *startBlock = startNode->enclosingBlockFlowElement();
- NodeImpl *stayInsideBlock = includeLineBreak ? 0 : startBlock;
- NodeImpl *node = startNode;
- long offset = p.offset();
-
- for (NodeImpl *n = startNode; n; n = n->traverseNextNode(stayInsideBlock)) {
- RenderObject *r = n->renderer();
- if (!r)
- continue;
- RenderStyle *style = r->style();
- if (style->visibility() != VISIBLE)
- continue;
- if (r->isBlockFlow()) {
- if (includeLineBreak)
- return VisiblePosition(n, 0, DOWNSTREAM);
- break;
- }
- if (r->isText()) {
- if (includeLineBreak && !n->isAncestor(startBlock))
- return VisiblePosition(n, 0, DOWNSTREAM);
- node = n;
- offset = static_cast<RenderText *>(r)->length();
- } else if (r->isReplaced()) {
- node = n;
- offset = 1;
- if (includeLineBreak && !n->isAncestor(startBlock))
- break;
- }
- }
-
- return VisiblePosition(node, offset, DOWNSTREAM);
+ return VisiblePosition(startBlock, startBlock->childNodeCount(), VP_DEFAULT_AFFINITY);
}
bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b)
bool isEndOfBlock(const VisiblePosition &pos)
{
- return pos.isNotNull() && isEqualIgnoringAffinity(pos, endOfBlock(pos, DoNotIncludeLineBreak));
+ return pos.isNotNull() && isEqualIgnoringAffinity(pos, endOfBlock(pos));
}
// ---------
// blocks (true paragraphs; line break elements don't break blocks)
VisiblePosition startOfBlock(const VisiblePosition &);
-VisiblePosition endOfBlock(const VisiblePosition &, EIncludeLineBreak = DoNotIncludeLineBreak);
+VisiblePosition endOfBlock(const VisiblePosition &);
bool inSameBlock(const VisiblePosition &, const VisiblePosition &);
bool isStartOfBlock(const VisiblePosition &);
bool isEndOfBlock(const VisiblePosition &);