Removed closestRenderedPosition function from Position class and gave this work
to VisiblePosition instead. However, in order to make the transfer possible,
VisiblePosition needed upstream and downstream affinities added to its
constructors. Also moved the EAffinity enum into its own file. Also moved it
to the khtml namespace.
Updated several functions which used closestRenderedPosition to use VisiblePosition
instead.
Also deleted Position::equivalentShallowPosition. This was unused.
* ForwardingHeaders/editing/text_affinity.h: Added.
* ForwardingHeaders/editing/visible_position.h: Added.
* WebCore.pbproj/project.pbxproj: Added new files.
* khtml/editing/selection.cpp:
(khtml::Selection::validate): Use VisiblePosition instead of closestRenderedPosition.
* khtml/editing/selection.h:
* khtml/editing/text_affinity.h: Added.
* khtml/editing/visible_position.cpp:
(khtml::VisiblePosition::VisiblePosition):
(khtml::VisiblePosition::initUpstream): New helper for finding upstream visible position.
(khtml::VisiblePosition::initDownstream): Was old init function that unconditionally did
downstream checks for visible position. Renamed to describe this more clearly.
* khtml/editing/visible_position.h:
* khtml/editing/visible_units.cpp:
(khtml::previousWordBoundary): Use VisiblePosition instead of closestRenderedPosition.
(khtml::nextWordBoundary): Use VisiblePosition instead of closestRenderedPosition.
* khtml/xml/dom_docimpl.cpp:
(DocumentImpl::updateSelection): Use VisiblePosition instead of closestRenderedPosition.
* khtml/xml/dom_position.cpp:
(DOM::Position::closestRenderedPosition): Removed.
* khtml/xml/dom_position.h: Removed two functions mentioned above.
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::fontForSelection) Use VisiblePosition instead of closestRenderedPosition.:
* kwq/WebCoreBridge.mm:
(-[WebCoreBridge setSelectedDOMRange:affinity:]): Use VisiblePosition instead of closestRenderedPosition.
* layout-tests/editing/deleting/delete-block-merge-contents-012-expected.txt: Updated expected results.
* layout-tests/editing/deleting/delete-block-merge-contents-017-expected.txt: Ditto.
* layout-tests/editing/deleting/delete-contiguous-ws-001-expected.txt: Ditto.
* layout-tests/editing/selection/move-by-character-004-expected.txt: Ditto.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7691
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
RenderText {TEXT} at (71,0) size 106x28
text run at (71,0) width 106: " some text."
selection is CARET:
-start: position 0 of child 2 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
+start: position 8 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
upstream: position 8 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
downstream: position 0 of child 2 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
RenderText {TEXT} at (71,0) size 106x28
text run at (71,0) width 106: " some text."
selection is CARET:
-start: position 7 of child 2 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
+start: position 8 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
upstream: position 8 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
downstream: position 7 of child 2 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
text run at (52,14) width 40: " baz"
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
-start: position 8 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+start: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 8 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
RenderImage {IMG} at (75,232) size 76x103
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
-start: position 0 of child 2 {IMG} of child 2 {SPAN} of root {DIV}
+start: position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 0 of child 2 {IMG} of child 2 {SPAN} of root {DIV}
+2004-09-27 Ken Kocienda <kocienda@apple.com>
+
+ Reviewed by John
+
+ Removed closestRenderedPosition function from Position class and gave this work
+ to VisiblePosition instead. However, in order to make the transfer possible,
+ VisiblePosition needed upstream and downstream affinities added to its
+ constructors. Also moved the EAffinity enum into its own file. Also moved it
+ to the khtml namespace.
+
+ Updated several functions which used closestRenderedPosition to use VisiblePosition
+ instead.
+
+ Also deleted Position::equivalentShallowPosition. This was unused.
+
+ * ForwardingHeaders/editing/text_affinity.h: Added.
+ * ForwardingHeaders/editing/visible_position.h: Added.
+ * WebCore.pbproj/project.pbxproj: Added new files.
+ * khtml/editing/selection.cpp:
+ (khtml::Selection::validate): Use VisiblePosition instead of closestRenderedPosition.
+ * khtml/editing/selection.h:
+ * khtml/editing/text_affinity.h: Added.
+ * khtml/editing/visible_position.cpp:
+ (khtml::VisiblePosition::VisiblePosition):
+ (khtml::VisiblePosition::initUpstream): New helper for finding upstream visible position.
+ (khtml::VisiblePosition::initDownstream): Was old init function that unconditionally did
+ downstream checks for visible position. Renamed to describe this more clearly.
+ * khtml/editing/visible_position.h:
+ * khtml/editing/visible_units.cpp:
+ (khtml::previousWordBoundary): Use VisiblePosition instead of closestRenderedPosition.
+ (khtml::nextWordBoundary): Use VisiblePosition instead of closestRenderedPosition.
+ * khtml/xml/dom_docimpl.cpp:
+ (DocumentImpl::updateSelection): Use VisiblePosition instead of closestRenderedPosition.
+ * khtml/xml/dom_position.cpp:
+ (DOM::Position::closestRenderedPosition): Removed.
+ * khtml/xml/dom_position.h: Removed two functions mentioned above.
+ * kwq/KWQKHTMLPart.mm:
+ (KWQKHTMLPart::fontForSelection) Use VisiblePosition instead of closestRenderedPosition.:
+ * kwq/WebCoreBridge.mm:
+ (-[WebCoreBridge setSelectedDOMRange:affinity:]): Use VisiblePosition instead of closestRenderedPosition.
+ * layout-tests/editing/deleting/delete-block-merge-contents-012-expected.txt: Updated expected results.
+ * layout-tests/editing/deleting/delete-block-merge-contents-017-expected.txt: Ditto.
+ * layout-tests/editing/deleting/delete-contiguous-ws-001-expected.txt: Ditto.
+ * layout-tests/editing/selection/move-by-character-004-expected.txt: Ditto.
+
2004-09-27 Ken Kocienda <kocienda@apple.com>
Reviewed by Darin and Maciej
--- /dev/null
+#import <text_affinity.h>
--- /dev/null
+#import <visible_position.h>
93ABE075070285F600BD91F9,
932B9835070297DC0032804F,
939FF8EF0702B1B100979E5E,
+ BECE67BE07087B250007C14B,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
BE02D4E7066F908A0076809F,
93ABE067070285F600BD91F9,
93ABE066070285F600BD91F9,
+ BECE67BD07087B250007C14B,
932B9834070297DC0032804F,
93ABE069070285F600BD91F9,
93ABE068070285F600BD91F9,
refType = 4;
sourceTree = "<group>";
};
+ BECE67BD07087B250007C14B = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ name = text_affinity.h;
+ path = editing/text_affinity.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ BECE67BE07087B250007C14B = {
+ fileRef = BECE67BD07087B250007C14B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
BEF7EEA005FF8F0D009717EE = {
fileEncoding = 30;
isa = PBXFileReference;
#define EDIT_DEBUG 0
using DOM::DOMString;
-using DOM::DOWNSTREAM;
using DOM::ElementImpl;
using DOM::Node;
using DOM::NodeImpl;
if (m_base.isNotNull()) {
m_base.node()->getDocument()->updateLayout();
updatedLayout = true;
- m_base = m_base.equivalentDeepPosition().closestRenderedPosition(affinity());
+ m_base = VisiblePosition(m_base).deepEquivalent();
if (baseAndExtentEqual)
m_extent = m_base;
}
if (m_extent.isNotNull() && !baseAndExtentEqual) {
if (!updatedLayout)
m_extent.node()->getDocument()->updateLayout();
- m_extent = m_extent.equivalentDeepPosition().closestRenderedPosition(affinity());
+ m_extent = VisiblePosition(m_extent).deepEquivalent();
}
// Make sure we do not have a dangling start or end
enum EAlter { MOVE, EXTEND };
enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
- typedef DOM::EAffinity EAffinity;
typedef DOM::Range Range;
typedef DOM::Position Position;
#define EDIT_DEBUG 0
using DOM::DOMString;
-using DOM::DOWNSTREAM;
using DOM::ElementImpl;
using DOM::Node;
using DOM::NodeImpl;
if (m_base.isNotNull()) {
m_base.node()->getDocument()->updateLayout();
updatedLayout = true;
- m_base = m_base.equivalentDeepPosition().closestRenderedPosition(affinity());
+ m_base = VisiblePosition(m_base).deepEquivalent();
if (baseAndExtentEqual)
m_extent = m_base;
}
if (m_extent.isNotNull() && !baseAndExtentEqual) {
if (!updatedLayout)
m_extent.node()->getDocument()->updateLayout();
- m_extent = m_extent.equivalentDeepPosition().closestRenderedPosition(affinity());
+ m_extent = VisiblePosition(m_extent).deepEquivalent();
}
// Make sure we do not have a dangling start or end
enum EAlter { MOVE, EXTEND };
enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
- typedef DOM::EAffinity EAffinity;
typedef DOM::Range Range;
typedef DOM::Position Position;
--- /dev/null
+/*
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef KHTML_EDITING_TEXT_AFFINITY_H
+#define KHTML_EDITING_TEXT_AFFINITY_H
+
+namespace khtml {
+
+// These match the AppKit values for these concepts.
+// From NSTextView.h:
+// NSSelectionAffinityUpstream = 0
+// NSSelectionAffinityDownstream = 1
+enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 };
+
+}
+
+#endif
namespace khtml {
-VisiblePosition::VisiblePosition(NodeImpl *node, long offset)
+VisiblePosition::VisiblePosition(NodeImpl *node, long offset, EAffinity affinity)
{
- init(Position(node, offset));
+ Position pos = Position(node, offset);
+ switch (affinity) {
+ case UPSTREAM:
+ initUpstream(pos);
+ break;
+ case DOWNSTREAM:
+ initDownstream(pos);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
}
-VisiblePosition::VisiblePosition(const Position &pos)
+VisiblePosition::VisiblePosition(const Position &pos, EAffinity affinity)
{
- init(pos);
+ switch (affinity) {
+ case UPSTREAM:
+ initUpstream(pos);
+ break;
+ case DOWNSTREAM:
+ initDownstream(pos);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
}
-void VisiblePosition::init(const Position &pos)
+void VisiblePosition::initUpstream(const Position &pos)
{
Position deepPos = deepEquivalent(pos);
-
+
+ if (isCandidate(deepPos)) {
+ m_deepPosition = deepPos;
+ Position next = nextVisiblePosition(deepPos);
+ if (next.isNotNull()) {
+ Position previous = previousVisiblePosition(next);
+ if (previous.isNotNull())
+ m_deepPosition = previous;
+ }
+ }
+ else {
+ Position previous = previousVisiblePosition(deepPos);
+ if (previous.isNotNull()) {
+ m_deepPosition = previous;
+ }
+ else {
+ Position next = nextVisiblePosition(deepPos);
+ if (next.isNotNull())
+ m_deepPosition = next;
+ }
+ }
+}
+
+void VisiblePosition::initDownstream(const Position &pos)
+{
+ Position deepPos = deepEquivalent(pos);
+
if (isCandidate(deepPos)) {
m_deepPosition = deepPos;
Position previous = previousVisiblePosition(deepPos);
#define KHTML_EDITING_VISIBLE_POSITION_H
#include "xml/dom_position.h"
+#include "text_affinity.h"
namespace DOM {
class Range;
typedef DOM::Position Position;
VisiblePosition() { }
- VisiblePosition(NodeImpl *, long offset);
- VisiblePosition(const Position &);
+ VisiblePosition(NodeImpl *, long offset, EAffinity affinity=DOWNSTREAM);
+ VisiblePosition(const Position &, EAffinity affinity=DOWNSTREAM);
void clear() { m_deepPosition.clear(); }
#endif
private:
- void init(const Position &);
+ void initUpstream(const Position &);
+ void initDownstream(const Position &);
static Position deepEquivalent(const Position &);
static Position rangeCompliantEquivalent(const Position &);
#include "xml/dom_docimpl.h"
using DOM::DocumentImpl;
-using DOM::DOWNSTREAM;
using DOM::NodeImpl;
using DOM::Position;
using DOM::Range;
-using DOM::UPSTREAM;
namespace khtml {
}
// Use DOWNSTREAM here so that we don't jump past words at the start of lines.
// <rdar://problem/3765519> REGRESSION (Mail): word movement goes too far upstream at start of line
- return pos.equivalentDeepPosition().closestRenderedPosition(DOWNSTREAM);
+ return VisiblePosition(pos).deepEquivalent();
}
static VisiblePosition nextWordBoundary(const VisiblePosition &c, unsigned (*searchFunction)(const QChar *, unsigned))
charIt.advance(next - 1);
pos = Position(charIt.range().endContainer().handle(), charIt.range().endOffset());
}
- return pos.equivalentDeepPosition().closestRenderedPosition(UPSTREAM);
+ return VisiblePosition(pos, UPSTREAM).deepEquivalent();
}
static unsigned startWordBoundary(const QChar *characters, unsigned length)
#include "cssvalues.h"
#include "editing/jsediting.h"
+#include "editing/visible_position.h"
#include "editing/visible_text.h"
#include <kio/job.h>
canvas->clearSelection();
}
else {
- Position startPos = Position(s.start()).closestRenderedPosition(UPSTREAM);
- Position endPos = Position(s.end()).closestRenderedPosition(DOWNSTREAM);
+ Position startPos = VisiblePosition(s.start(), UPSTREAM).deepEquivalent();
+ Position endPos = VisiblePosition(s.end(), DOWNSTREAM).deepEquivalent();
if (startPos.isNotNull() && endPos.isNotNull()) {
RenderObject *startRenderer = startPos.node()->renderer();
RenderObject *endRenderer = endPos.node()->renderer();
return Position(node()->parentNode(), o + offset());
}
-Position Position::equivalentShallowPosition() const
-{
- if (isNull())
- return *this;
-
- Position pos(*this);
- while (pos.offset() == pos.node()->caretMinOffset() && pos.node()->parentNode() && pos.node() == pos.node()->parentNode()->firstChild())
- pos = Position(pos.node()->parentNode(), 0);
- return pos;
-}
-
Position Position::equivalentDeepPosition() const
{
if (isNull() || node()->isAtomicNode())
return pos;
}
-Position Position::closestRenderedPosition(EAffinity affinity) const
-{
- if (isNull() || inRenderedContent())
- return *this;
-
- Position pos;
- PositionIterator it(*this);
-
- switch (affinity) {
- case UPSTREAM:
- // look upstream first
- it.setPosition(*this);
- while (!it.atStart()) {
- it.previous();
- if (it.current().inRenderedContent())
- return it.current();
- }
- // if this does not find something rendered, look downstream
- it.setPosition(*this);
- while (!it.atEnd()) {
- it.next();
- if (it.current().inRenderedContent())
- return it.current();
- }
- break;
- case DOWNSTREAM:
- // look downstream first
- it.setPosition(*this);
- while (!it.atEnd()) {
- it.next();
- if (it.current().inRenderedContent())
- return it.current();
- }
- // if this does not find something rendered, look upstream
- it.setPosition(*this);
- while (!it.atStart()) {
- it.previous();
- if (it.current().inRenderedContent())
- return it.current();
- }
- break;
- }
-
- return Position();
-}
-
bool Position::inRenderedContent() const
{
if (isNull())
#ifndef __dom_position_h__
#define __dom_position_h__
+#include "text_affinity.h"
+
namespace DOM {
class CSSComputedStyleDeclarationImpl;
class Range;
class RangeImpl;
-// These match the AppKit values for these concepts.
-// From NSTextView.h:
-// NSSelectionAffinityUpstream = 0
-// NSSelectionAffinityDownstream = 1
-enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 };
-
enum EStayInBlock { DoNotStayInBlock = false, StayInBlock = true };
class Position
Position downstream(EStayInBlock stayInBlock = DoNotStayInBlock) const;
Position equivalentRangeCompliantPosition() const;
- Position equivalentShallowPosition() const;
Position equivalentDeepPosition() const;
- Position closestRenderedPosition(EAffinity) const;
bool inRenderedContent() const;
bool isRenderedCharacter() const;
bool rendersInDifferentPosition(const Position &pos) const;
using DOM::Range;
using DOM::RangeImpl;
using DOM::TextImpl;
-using DOM::UPSTREAM;
using khtml::Cache;
using khtml::CharacterIterator;
using khtml::startOfWord;
using khtml::startVisiblePosition;
using khtml::TextIterator;
+using khtml::UPSTREAM;
using khtml::VISIBLE;
using khtml::VisiblePosition;
using khtml::WordAwareIterator;
return nil;
if (d->m_selection.isCaret()) {
- Position pos(d->m_selection.start().equivalentDeepPosition().closestRenderedPosition(UPSTREAM));
+ Position pos = VisiblePosition(d->m_selection.start(), UPSTREAM).deepEquivalent();
ASSERT(pos.isNotNull());
if (!pos.inRenderedContent())
return nil;
using DOM::NodeImpl;
using DOM::Position;
using DOM::Range;
-using DOM::UPSTREAM;
using khtml::Decoder;
using khtml::DeleteSelectionCommand;
using khtml::ReplaceSelectionCommand;
using khtml::Selection;
using khtml::TypingCommand;
+using khtml::UPSTREAM;
using khtml::VisiblePosition;
using KJS::ExecState;
// If that bug wasn't an issue, we could just make the position from the range directly.
Position start(startContainer, [range startOffset]);
Position end(endContainer, [range endOffset]);
- start = start.equivalentDeepPosition().closestRenderedPosition(UPSTREAM);
+ start = VisiblePosition(start, UPSTREAM).deepEquivalent();
Selection selection(start, end);
- selection.setAffinity(static_cast<DOM::EAffinity>(selectionAffinity));
+ selection.setAffinity(static_cast<khtml::EAffinity>(selectionAffinity));
_part->setSelection(selection);
}