[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
kocienda
kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:49:22 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 6438cf29300fad0cbb706e283289b589dd1eb55a
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jul 9 18:31:01 2004 +0000
Reviewed by Hyatt
Some improvements to fix:
<rdar://problem/3723111> Caret not drawn when selection set to unrendered content
* khtml/editing/htmlediting_impl.cpp:
(khtml::TypingCommandImpl::issueCommandForDeleteKey): Adjust selection to delete if
selected position is not rendered.
* khtml/rendering/render_block.cpp:
(khtml::RenderBlock::paintObject): Use new caretPosition() function on Selection to
figure out whether to paint.
* khtml/xml/dom_position.cpp:
(DOM::Position::previousCharacterPosition): Now correctly deals with a start
position that is not rendered.
(DOM::Position::nextCharacterPosition): Ditto.
(DOM::Position::closestRenderedPosition): New helper.
* khtml/xml/dom_position.h:
(DOM::): Moved in EAffinity from Selection header. Now used in closestRenderedPosition function.
* khtml/xml/dom_selection.cpp:
(DOM::Selection::Selection): Added new m_caretPosition member. This is the position of the caret
after a caret layout. This may be different from start or end if start and end are not rendered.
(DOM::Selection::init):
(DOM::Selection::modifyExtendingRightForward): New helper to clean up modify() and make it more readble.
(DOM::Selection::modifyMovingRightForward): Ditto.
(DOM::Selection::modifyExtendingLeftBackward): Ditto.
(DOM::Selection::modifyMovingLeftBackward): Ditto.
(DOM::Selection::modify): Use new helpers to make this more readble.
(DOM::Selection::layoutCaret): Uses new closestRenderedPosition helper to place the caret if in unrendered
content.
(DOM::Selection::paintCaret): Remove moveToRenderedContent. obsolete.
* khtml/xml/dom_selection.h:
(DOM::Selection::caretPosition): New accessor.
* kwq/WebCoreBridge.mm:
(-[WebCoreBridge setSelectedDOMRange:affinity:]): EAffinity no longer a member enum of Selection class.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6984 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 44c287e..2282d1a 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,41 @@
+2004-07-09 Ken Kocienda <kocienda at apple.com>
+
+ Reviewed by Hyatt
+
+ Some improvements to fix:
+
+ <rdar://problem/3723111> Caret not drawn when selection set to unrendered content
+
+ * khtml/editing/htmlediting_impl.cpp:
+ (khtml::TypingCommandImpl::issueCommandForDeleteKey): Adjust selection to delete if
+ selected position is not rendered.
+ * khtml/rendering/render_block.cpp:
+ (khtml::RenderBlock::paintObject): Use new caretPosition() function on Selection to
+ figure out whether to paint.
+ * khtml/xml/dom_position.cpp:
+ (DOM::Position::previousCharacterPosition): Now correctly deals with a start
+ position that is not rendered.
+ (DOM::Position::nextCharacterPosition): Ditto.
+ (DOM::Position::closestRenderedPosition): New helper.
+ * khtml/xml/dom_position.h:
+ (DOM::): Moved in EAffinity from Selection header. Now used in closestRenderedPosition function.
+ * khtml/xml/dom_selection.cpp:
+ (DOM::Selection::Selection): Added new m_caretPosition member. This is the position of the caret
+ after a caret layout. This may be different from start or end if start and end are not rendered.
+ (DOM::Selection::init):
+ (DOM::Selection::modifyExtendingRightForward): New helper to clean up modify() and make it more readble.
+ (DOM::Selection::modifyMovingRightForward): Ditto.
+ (DOM::Selection::modifyExtendingLeftBackward): Ditto.
+ (DOM::Selection::modifyMovingLeftBackward): Ditto.
+ (DOM::Selection::modify): Use new helpers to make this more readble.
+ (DOM::Selection::layoutCaret): Uses new closestRenderedPosition helper to place the caret if in unrendered
+ content.
+ (DOM::Selection::paintCaret): Remove moveToRenderedContent. obsolete.
+ * khtml/xml/dom_selection.h:
+ (DOM::Selection::caretPosition): New accessor.
+ * kwq/WebCoreBridge.mm:
+ (-[WebCoreBridge setSelectedDOMRange:affinity:]): EAffinity no longer a member enum of Selection class.
+
2004-07-08 David Hyatt <hyatt at apple.com>
Fix for the table layout test that failed because of a change in how innerText worked. We need to do
diff --git a/WebCore/khtml/editing/SelectionController.cpp b/WebCore/khtml/editing/SelectionController.cpp
index 9f68914..ef99b2d 100644
--- a/WebCore/khtml/editing/SelectionController.cpp
+++ b/WebCore/khtml/editing/SelectionController.cpp
@@ -120,6 +120,7 @@ Selection::Selection(const Selection &o)
m_caretX = o.m_caretX;
m_caretY = o.m_caretY;
m_caretSize = o.m_caretSize;
+ m_caretPosition = o.m_caretPosition;
}
}
@@ -130,6 +131,7 @@ void Selection::init()
m_caretX = 0;
m_caretY = 0;
m_caretSize = 0;
+ m_caretPosition = emptyPosition();
m_baseIsStart = true;
m_needsCaretLayout = true;
m_modifyBiasSet = false;
@@ -194,92 +196,121 @@ void Selection::moveTo(const Position &base, const Position &extent)
validate();
}
+Position Selection::modifyExtendingRightForward(ETextGranularity granularity)
+{
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ assignBaseAndExtent(start(), end());
+ }
+ Position pos = extent().closestRenderedPosition(affinity());
+ switch (granularity) {
+ case CHARACTER:
+ pos = pos.nextCharacterPosition();
+ break;
+ case WORD:
+ pos = pos.nextWordPosition();
+ break;
+ case LINE:
+ pos = pos.nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyMovingRightForward(ETextGranularity granularity)
+{
+ m_modifyBiasSet = false;
+ Position pos;
+ switch (granularity) {
+ case CHARACTER:
+ if (state() == RANGE)
+ pos = end().closestRenderedPosition(affinity());
+ else
+ pos = extent().closestRenderedPosition(affinity()).nextCharacterPosition();
+ break;
+ case WORD:
+ pos = extent().closestRenderedPosition(affinity()).nextWordPosition();
+ break;
+ case LINE:
+ pos = end().closestRenderedPosition(affinity()).nextLinePosition(xPosForVerticalArrowNavigation(END, state() == RANGE));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyExtendingLeftBackward(ETextGranularity granularity)
+{
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ assignBaseAndExtent(end(), start());
+ }
+ Position pos = extent().closestRenderedPosition(affinity());
+ switch (granularity) {
+ case CHARACTER:
+ pos = pos.previousCharacterPosition();
+ break;
+ case WORD:
+ pos = pos.previousWordPosition();
+ break;
+ case LINE:
+ pos = pos.previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyMovingLeftBackward(ETextGranularity granularity)
+{
+ m_modifyBiasSet = false;
+ Position pos;
+ switch (granularity) {
+ case CHARACTER:
+ if (state() == RANGE)
+ pos = start().closestRenderedPosition(affinity());
+ else
+ pos = extent().closestRenderedPosition(affinity()).previousCharacterPosition();
+ break;
+ case WORD:
+ pos = extent().closestRenderedPosition(affinity()).previousWordPosition();
+ break;
+ case LINE:
+ pos = start().closestRenderedPosition(affinity()).previousLinePosition(xPosForVerticalArrowNavigation(START, state() == RANGE));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
Position pos;
-
+
switch (dir) {
- // EDIT FIXME: This needs to handle bidi
+ // EDIT FIXME: These need to handle bidi
case RIGHT:
case FORWARD:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- assignBaseAndExtent(start(), end());
- }
- switch (granularity) {
- case CHARACTER:
- pos = extent().nextCharacterPosition();
- break;
- case WORD:
- pos = extent().nextWordPosition();
- break;
- case LINE:
- pos = extent().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
- else {
- m_modifyBiasSet = false;
- switch (granularity) {
- case CHARACTER:
- pos = (state() == RANGE) ? end() : extent().nextCharacterPosition();
- break;
- case WORD:
- pos = extent().nextWordPosition();
- break;
- case LINE:
- pos = end().nextLinePosition(xPosForVerticalArrowNavigation(END, state() == RANGE));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
+ if (alter == EXTEND)
+ pos = modifyExtendingRightForward(granularity);
+ else
+ pos = modifyMovingRightForward(granularity);
break;
- // EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- assignBaseAndExtent(end(), start());
- }
- switch (granularity) {
- case CHARACTER:
- pos = extent().previousCharacterPosition();
- break;
- case WORD:
- pos = extent().previousWordPosition();
- break;
- case LINE:
- pos = extent().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
- else {
- m_modifyBiasSet = false;
- switch (granularity) {
- case CHARACTER:
- pos = (state() == RANGE) ? start() : extent().previousCharacterPosition();
- break;
- case WORD:
- pos = extent().previousWordPosition();
- break;
- case LINE:
- pos = start().previousLinePosition(xPosForVerticalArrowNavigation(START, state() == RANGE));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
+ if (alter == EXTEND)
+ pos = modifyExtendingLeftBackward(granularity);
+ else
+ pos = modifyMovingLeftBackward(granularity);
break;
}
@@ -439,15 +470,25 @@ Range Selection::toRange() const
void Selection::layoutCaret()
{
- if (isEmpty() || !start().node()->renderer()) {
+ if (state() != CARET) {
m_caretX = m_caretY = m_caretSize = 0;
+ return;
}
- else {
- // EDIT FIXME: Enhance call to pass along selection
- // upstream/downstream affinity to get the right position.
- int w;
- start().node()->renderer()->caretPos(start().offset(), true, m_caretX, m_caretY, w, m_caretSize);
+
+ Position pos = start();
+ if (!pos.inRenderedContent())
+ pos = pos.closestRenderedPosition(affinity());
+
+ if (pos.isEmpty() || !pos.inRenderedContent()) {
+ m_caretX = m_caretY = m_caretSize = 0;
+ return;
}
+
+ // EDIT FIXME: Enhance call to pass along selection
+ // upstream/downstream affinity to get the right position.
+ int w;
+ m_caretPosition = pos;
+ pos.node()->renderer()->caretPos(pos.offset(), true, m_caretX, m_caretY, w, m_caretSize);
m_needsCaretLayout = false;
}
@@ -503,13 +544,8 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
if (m_state != CARET)
return;
- if (m_needsCaretLayout) {
- Position pos = start();
- if (!pos.inRenderedContent()) {
- moveToRenderedContent();
- }
+ if (m_needsCaretLayout)
layoutCaret();
- }
QRect caretRect(m_caretX, m_caretY, 1, m_caretSize);
if (caretRect.intersects(rect)) {
diff --git a/WebCore/khtml/editing/SelectionController.h b/WebCore/khtml/editing/SelectionController.h
index 39e3933..9eb67d4 100644
--- a/WebCore/khtml/editing/SelectionController.h
+++ b/WebCore/khtml/editing/SelectionController.h
@@ -50,12 +50,6 @@ public:
enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
enum ETextGranularity { CHARACTER, WORD, LINE, PARAGRAPH };
- // These match the AppKit values for these concepts.
- // From NSTextView.h:
- // NSSelectionAffinityUpstream = 0
- // NSSelectionAffinityDownstream = 1
- enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 };
-
Selection();
Selection(const Range &);
Selection(const Position &);
@@ -87,6 +81,7 @@ public:
Position extent() const { return m_extent; }
Position start() const { return m_start; }
Position end() const { return m_end; }
+ Position caretPosition() const { return m_caretPosition; }
QRect getRepaintRect() const;
void setNeedsLayout(bool flag=true);
@@ -124,6 +119,11 @@ private:
void assignEnd(const Position &pos) { m_end = pos; }
void assignStartAndEnd(const Position &start, const Position &end) { m_start = start; m_end = end; }
+ Position modifyExtendingRightForward(ETextGranularity);
+ Position modifyMovingRightForward(ETextGranularity);
+ Position modifyExtendingLeftBackward(ETextGranularity);
+ Position modifyMovingLeftBackward(ETextGranularity);
+
void layoutCaret();
void needsCaretRepaint();
void paintCaret(QPainter *p, const QRect &rect);
@@ -139,10 +139,11 @@ private:
EState m_state; // the state of the selection
EAffinity m_affinity; // the upstream/downstream affinity of the selection
- int m_caretX; // caret coordinates and size
+ int m_caretX; // caret coordinates, size, and position
int m_caretY;
int m_caretSize;
-
+ Position m_caretPosition;
+
bool m_baseIsStart : 1; // true if base node is before the extent node
bool m_needsCaretLayout : 1; // true if the caret position needs to be calculated
bool m_modifyBiasSet : 1; // true if the selection has been horizontally
diff --git a/WebCore/khtml/editing/htmlediting_impl.cpp b/WebCore/khtml/editing/htmlediting_impl.cpp
index a4f74f5..cf06e4c 100644
--- a/WebCore/khtml/editing/htmlediting_impl.cpp
+++ b/WebCore/khtml/editing/htmlediting_impl.cpp
@@ -2420,7 +2420,10 @@ void TypingCommandImpl::issueCommandForDeleteKey()
// we're at the start of a root editable block...do nothing
return;
}
- selectionToDelete = Selection(pos.previousCharacterPosition(), pos);
+ if (pos.inRenderedContent())
+ selectionToDelete = Selection(pos.previousCharacterPosition(), pos);
+ else
+ selectionToDelete = Selection(pos.equivalentUpstreamPosition().previousCharacterPosition(), pos.equivalentDownstreamPosition());
}
deleteSelection(selectionToDelete);
typingAddedToOpenCommand();
diff --git a/WebCore/khtml/editing/selection.cpp b/WebCore/khtml/editing/selection.cpp
index 9f68914..ef99b2d 100644
--- a/WebCore/khtml/editing/selection.cpp
+++ b/WebCore/khtml/editing/selection.cpp
@@ -120,6 +120,7 @@ Selection::Selection(const Selection &o)
m_caretX = o.m_caretX;
m_caretY = o.m_caretY;
m_caretSize = o.m_caretSize;
+ m_caretPosition = o.m_caretPosition;
}
}
@@ -130,6 +131,7 @@ void Selection::init()
m_caretX = 0;
m_caretY = 0;
m_caretSize = 0;
+ m_caretPosition = emptyPosition();
m_baseIsStart = true;
m_needsCaretLayout = true;
m_modifyBiasSet = false;
@@ -194,92 +196,121 @@ void Selection::moveTo(const Position &base, const Position &extent)
validate();
}
+Position Selection::modifyExtendingRightForward(ETextGranularity granularity)
+{
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ assignBaseAndExtent(start(), end());
+ }
+ Position pos = extent().closestRenderedPosition(affinity());
+ switch (granularity) {
+ case CHARACTER:
+ pos = pos.nextCharacterPosition();
+ break;
+ case WORD:
+ pos = pos.nextWordPosition();
+ break;
+ case LINE:
+ pos = pos.nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyMovingRightForward(ETextGranularity granularity)
+{
+ m_modifyBiasSet = false;
+ Position pos;
+ switch (granularity) {
+ case CHARACTER:
+ if (state() == RANGE)
+ pos = end().closestRenderedPosition(affinity());
+ else
+ pos = extent().closestRenderedPosition(affinity()).nextCharacterPosition();
+ break;
+ case WORD:
+ pos = extent().closestRenderedPosition(affinity()).nextWordPosition();
+ break;
+ case LINE:
+ pos = end().closestRenderedPosition(affinity()).nextLinePosition(xPosForVerticalArrowNavigation(END, state() == RANGE));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyExtendingLeftBackward(ETextGranularity granularity)
+{
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ assignBaseAndExtent(end(), start());
+ }
+ Position pos = extent().closestRenderedPosition(affinity());
+ switch (granularity) {
+ case CHARACTER:
+ pos = pos.previousCharacterPosition();
+ break;
+ case WORD:
+ pos = pos.previousWordPosition();
+ break;
+ case LINE:
+ pos = pos.previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyMovingLeftBackward(ETextGranularity granularity)
+{
+ m_modifyBiasSet = false;
+ Position pos;
+ switch (granularity) {
+ case CHARACTER:
+ if (state() == RANGE)
+ pos = start().closestRenderedPosition(affinity());
+ else
+ pos = extent().closestRenderedPosition(affinity()).previousCharacterPosition();
+ break;
+ case WORD:
+ pos = extent().closestRenderedPosition(affinity()).previousWordPosition();
+ break;
+ case LINE:
+ pos = start().closestRenderedPosition(affinity()).previousLinePosition(xPosForVerticalArrowNavigation(START, state() == RANGE));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
Position pos;
-
+
switch (dir) {
- // EDIT FIXME: This needs to handle bidi
+ // EDIT FIXME: These need to handle bidi
case RIGHT:
case FORWARD:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- assignBaseAndExtent(start(), end());
- }
- switch (granularity) {
- case CHARACTER:
- pos = extent().nextCharacterPosition();
- break;
- case WORD:
- pos = extent().nextWordPosition();
- break;
- case LINE:
- pos = extent().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
- else {
- m_modifyBiasSet = false;
- switch (granularity) {
- case CHARACTER:
- pos = (state() == RANGE) ? end() : extent().nextCharacterPosition();
- break;
- case WORD:
- pos = extent().nextWordPosition();
- break;
- case LINE:
- pos = end().nextLinePosition(xPosForVerticalArrowNavigation(END, state() == RANGE));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
+ if (alter == EXTEND)
+ pos = modifyExtendingRightForward(granularity);
+ else
+ pos = modifyMovingRightForward(granularity);
break;
- // EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- assignBaseAndExtent(end(), start());
- }
- switch (granularity) {
- case CHARACTER:
- pos = extent().previousCharacterPosition();
- break;
- case WORD:
- pos = extent().previousWordPosition();
- break;
- case LINE:
- pos = extent().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
- else {
- m_modifyBiasSet = false;
- switch (granularity) {
- case CHARACTER:
- pos = (state() == RANGE) ? start() : extent().previousCharacterPosition();
- break;
- case WORD:
- pos = extent().previousWordPosition();
- break;
- case LINE:
- pos = start().previousLinePosition(xPosForVerticalArrowNavigation(START, state() == RANGE));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
+ if (alter == EXTEND)
+ pos = modifyExtendingLeftBackward(granularity);
+ else
+ pos = modifyMovingLeftBackward(granularity);
break;
}
@@ -439,15 +470,25 @@ Range Selection::toRange() const
void Selection::layoutCaret()
{
- if (isEmpty() || !start().node()->renderer()) {
+ if (state() != CARET) {
m_caretX = m_caretY = m_caretSize = 0;
+ return;
}
- else {
- // EDIT FIXME: Enhance call to pass along selection
- // upstream/downstream affinity to get the right position.
- int w;
- start().node()->renderer()->caretPos(start().offset(), true, m_caretX, m_caretY, w, m_caretSize);
+
+ Position pos = start();
+ if (!pos.inRenderedContent())
+ pos = pos.closestRenderedPosition(affinity());
+
+ if (pos.isEmpty() || !pos.inRenderedContent()) {
+ m_caretX = m_caretY = m_caretSize = 0;
+ return;
}
+
+ // EDIT FIXME: Enhance call to pass along selection
+ // upstream/downstream affinity to get the right position.
+ int w;
+ m_caretPosition = pos;
+ pos.node()->renderer()->caretPos(pos.offset(), true, m_caretX, m_caretY, w, m_caretSize);
m_needsCaretLayout = false;
}
@@ -503,13 +544,8 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
if (m_state != CARET)
return;
- if (m_needsCaretLayout) {
- Position pos = start();
- if (!pos.inRenderedContent()) {
- moveToRenderedContent();
- }
+ if (m_needsCaretLayout)
layoutCaret();
- }
QRect caretRect(m_caretX, m_caretY, 1, m_caretSize);
if (caretRect.intersects(rect)) {
diff --git a/WebCore/khtml/editing/selection.h b/WebCore/khtml/editing/selection.h
index 39e3933..9eb67d4 100644
--- a/WebCore/khtml/editing/selection.h
+++ b/WebCore/khtml/editing/selection.h
@@ -50,12 +50,6 @@ public:
enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
enum ETextGranularity { CHARACTER, WORD, LINE, PARAGRAPH };
- // These match the AppKit values for these concepts.
- // From NSTextView.h:
- // NSSelectionAffinityUpstream = 0
- // NSSelectionAffinityDownstream = 1
- enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 };
-
Selection();
Selection(const Range &);
Selection(const Position &);
@@ -87,6 +81,7 @@ public:
Position extent() const { return m_extent; }
Position start() const { return m_start; }
Position end() const { return m_end; }
+ Position caretPosition() const { return m_caretPosition; }
QRect getRepaintRect() const;
void setNeedsLayout(bool flag=true);
@@ -124,6 +119,11 @@ private:
void assignEnd(const Position &pos) { m_end = pos; }
void assignStartAndEnd(const Position &start, const Position &end) { m_start = start; m_end = end; }
+ Position modifyExtendingRightForward(ETextGranularity);
+ Position modifyMovingRightForward(ETextGranularity);
+ Position modifyExtendingLeftBackward(ETextGranularity);
+ Position modifyMovingLeftBackward(ETextGranularity);
+
void layoutCaret();
void needsCaretRepaint();
void paintCaret(QPainter *p, const QRect &rect);
@@ -139,10 +139,11 @@ private:
EState m_state; // the state of the selection
EAffinity m_affinity; // the upstream/downstream affinity of the selection
- int m_caretX; // caret coordinates and size
+ int m_caretX; // caret coordinates, size, and position
int m_caretY;
int m_caretSize;
-
+ Position m_caretPosition;
+
bool m_baseIsStart : 1; // true if base node is before the extent node
bool m_needsCaretLayout : 1; // true if the caret position needs to be calculated
bool m_modifyBiasSet : 1; // true if the selection has been horizontally
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 1227efb..a978411 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1309,9 +1309,9 @@ void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty)
*/
if (paintAction == PaintActionForeground) {
const Selection &s = document()->part()->selection();
- NodeImpl *baseNode = s.base().node();
- RenderObject *renderer = baseNode ? baseNode->renderer() : 0;
- if (renderer && renderer->containingBlock() == this && baseNode->isContentEditable()) {
+ NodeImpl *caretNode = s.caretPosition().node();
+ RenderObject *renderer = caretNode ? caretNode->renderer() : 0;
+ if (renderer && renderer->containingBlock() == this && caretNode->isContentEditable()) {
document()->part()->paintCaret(i.p, i.r);
document()->part()->paintDragCaret(i.p, i.r);
}
diff --git a/WebCore/khtml/xml/dom_position.cpp b/WebCore/khtml/xml/dom_position.cpp
index e958195..00962fd 100644
--- a/WebCore/khtml/xml/dom_position.cpp
+++ b/WebCore/khtml/xml/dom_position.cpp
@@ -237,6 +237,7 @@ Position Position::previousCharacterPosition() const
PositionIterator it(*this);
bool atStartOfLine = isFirstRenderedPositionOnLine();
+ bool rendered = inRenderedContent();
while (!it.atStart()) {
Position pos = it.previous();
@@ -244,7 +245,7 @@ Position Position::previousCharacterPosition() const
if (pos.node()->rootEditableElement() != fromRootEditableElement)
return *this;
- if (atStartOfLine) {
+ if (atStartOfLine || !rendered) {
if (pos.inRenderedContent())
return pos;
}
@@ -264,6 +265,7 @@ Position Position::nextCharacterPosition() const
PositionIterator it(*this);
bool atEndOfLine = isLastRenderedPositionOnLine();
+ bool rendered = inRenderedContent();
while (!it.atEnd()) {
Position pos = it.next();
@@ -271,7 +273,7 @@ Position Position::nextCharacterPosition() const
if (pos.node()->rootEditableElement() != fromRootEditableElement)
return *this;
- if (atEndOfLine) {
+ if (atEndOfLine || !rendered) {
if (pos.inRenderedContent())
return pos;
}
@@ -558,6 +560,42 @@ Position Position::equivalentShallowPosition() const
return pos;
}
+Position Position::closestRenderedPosition(EAffinity affinity) const
+{
+ if (inRenderedContent())
+ return *this;
+
+ Position pos;
+
+ pos = affinity == UPSTREAM ? equivalentUpstreamPosition() : equivalentDownstreamPosition();
+ if (pos.inRenderedContent())
+ return pos;
+
+ pos = affinity == DOWNSTREAM ? equivalentDownstreamPosition() : equivalentUpstreamPosition();
+ if (pos.inRenderedContent())
+ return pos;
+
+ pos = *this;
+ Position prev(previousCharacterPosition());
+ while (prev != pos && prev.node()->inSameContainingBlockFlowElement(node())) {
+ if (prev.inRenderedContent())
+ return prev;
+ pos = prev;
+ prev = pos.previousCharacterPosition();
+ }
+
+ pos = *this;
+ Position next(nextCharacterPosition());
+ while (next != pos && next.node()->inSameContainingBlockFlowElement(node())) {
+ if (next.inRenderedContent())
+ return next;
+ pos = next;
+ next = pos.nextCharacterPosition();
+ }
+
+ return Position();
+}
+
bool Position::atStartOfContainingEditableBlock() const
{
return renderedOffset() == 0 && inFirstEditableInContainingEditableBlock();
diff --git a/WebCore/khtml/xml/dom_position.h b/WebCore/khtml/xml/dom_position.h
index f22ac39..8809134 100644
--- a/WebCore/khtml/xml/dom_position.h
+++ b/WebCore/khtml/xml/dom_position.h
@@ -31,6 +31,12 @@ namespace DOM {
class ElementImpl;
class NodeImpl;
+// These match the AppKit values for these concepts.
+// From NSTextView.h:
+// NSSelectionAffinityUpstream = 0
+// NSSelectionAffinityDownstream = 1
+enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 };
+
class Position
{
public:
@@ -62,6 +68,7 @@ public:
Position equivalentDownstreamPosition() const;
Position equivalentRangeCompliantPosition() const;
Position equivalentShallowPosition() const;
+ Position closestRenderedPosition(EAffinity) const;
bool atStartOfContainingEditableBlock() const;
bool atStartOfRootEditableElement() const;
bool inRenderedContent() const;
diff --git a/WebCore/khtml/xml/dom_selection.cpp b/WebCore/khtml/xml/dom_selection.cpp
index 9f68914..ef99b2d 100644
--- a/WebCore/khtml/xml/dom_selection.cpp
+++ b/WebCore/khtml/xml/dom_selection.cpp
@@ -120,6 +120,7 @@ Selection::Selection(const Selection &o)
m_caretX = o.m_caretX;
m_caretY = o.m_caretY;
m_caretSize = o.m_caretSize;
+ m_caretPosition = o.m_caretPosition;
}
}
@@ -130,6 +131,7 @@ void Selection::init()
m_caretX = 0;
m_caretY = 0;
m_caretSize = 0;
+ m_caretPosition = emptyPosition();
m_baseIsStart = true;
m_needsCaretLayout = true;
m_modifyBiasSet = false;
@@ -194,92 +196,121 @@ void Selection::moveTo(const Position &base, const Position &extent)
validate();
}
+Position Selection::modifyExtendingRightForward(ETextGranularity granularity)
+{
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ assignBaseAndExtent(start(), end());
+ }
+ Position pos = extent().closestRenderedPosition(affinity());
+ switch (granularity) {
+ case CHARACTER:
+ pos = pos.nextCharacterPosition();
+ break;
+ case WORD:
+ pos = pos.nextWordPosition();
+ break;
+ case LINE:
+ pos = pos.nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyMovingRightForward(ETextGranularity granularity)
+{
+ m_modifyBiasSet = false;
+ Position pos;
+ switch (granularity) {
+ case CHARACTER:
+ if (state() == RANGE)
+ pos = end().closestRenderedPosition(affinity());
+ else
+ pos = extent().closestRenderedPosition(affinity()).nextCharacterPosition();
+ break;
+ case WORD:
+ pos = extent().closestRenderedPosition(affinity()).nextWordPosition();
+ break;
+ case LINE:
+ pos = end().closestRenderedPosition(affinity()).nextLinePosition(xPosForVerticalArrowNavigation(END, state() == RANGE));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyExtendingLeftBackward(ETextGranularity granularity)
+{
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ assignBaseAndExtent(end(), start());
+ }
+ Position pos = extent().closestRenderedPosition(affinity());
+ switch (granularity) {
+ case CHARACTER:
+ pos = pos.previousCharacterPosition();
+ break;
+ case WORD:
+ pos = pos.previousWordPosition();
+ break;
+ case LINE:
+ pos = pos.previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
+Position Selection::modifyMovingLeftBackward(ETextGranularity granularity)
+{
+ m_modifyBiasSet = false;
+ Position pos;
+ switch (granularity) {
+ case CHARACTER:
+ if (state() == RANGE)
+ pos = start().closestRenderedPosition(affinity());
+ else
+ pos = extent().closestRenderedPosition(affinity()).previousCharacterPosition();
+ break;
+ case WORD:
+ pos = extent().closestRenderedPosition(affinity()).previousWordPosition();
+ break;
+ case LINE:
+ pos = start().closestRenderedPosition(affinity()).previousLinePosition(xPosForVerticalArrowNavigation(START, state() == RANGE));
+ break;
+ case PARAGRAPH:
+ // not implemented
+ break;
+ }
+ return pos;
+}
+
bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
Position pos;
-
+
switch (dir) {
- // EDIT FIXME: This needs to handle bidi
+ // EDIT FIXME: These need to handle bidi
case RIGHT:
case FORWARD:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- assignBaseAndExtent(start(), end());
- }
- switch (granularity) {
- case CHARACTER:
- pos = extent().nextCharacterPosition();
- break;
- case WORD:
- pos = extent().nextWordPosition();
- break;
- case LINE:
- pos = extent().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
- else {
- m_modifyBiasSet = false;
- switch (granularity) {
- case CHARACTER:
- pos = (state() == RANGE) ? end() : extent().nextCharacterPosition();
- break;
- case WORD:
- pos = extent().nextWordPosition();
- break;
- case LINE:
- pos = end().nextLinePosition(xPosForVerticalArrowNavigation(END, state() == RANGE));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
+ if (alter == EXTEND)
+ pos = modifyExtendingRightForward(granularity);
+ else
+ pos = modifyMovingRightForward(granularity);
break;
- // EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- assignBaseAndExtent(end(), start());
- }
- switch (granularity) {
- case CHARACTER:
- pos = extent().previousCharacterPosition();
- break;
- case WORD:
- pos = extent().previousWordPosition();
- break;
- case LINE:
- pos = extent().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
- else {
- m_modifyBiasSet = false;
- switch (granularity) {
- case CHARACTER:
- pos = (state() == RANGE) ? start() : extent().previousCharacterPosition();
- break;
- case WORD:
- pos = extent().previousWordPosition();
- break;
- case LINE:
- pos = start().previousLinePosition(xPosForVerticalArrowNavigation(START, state() == RANGE));
- break;
- case PARAGRAPH:
- // not implemented
- break;
- }
- }
+ if (alter == EXTEND)
+ pos = modifyExtendingLeftBackward(granularity);
+ else
+ pos = modifyMovingLeftBackward(granularity);
break;
}
@@ -439,15 +470,25 @@ Range Selection::toRange() const
void Selection::layoutCaret()
{
- if (isEmpty() || !start().node()->renderer()) {
+ if (state() != CARET) {
m_caretX = m_caretY = m_caretSize = 0;
+ return;
}
- else {
- // EDIT FIXME: Enhance call to pass along selection
- // upstream/downstream affinity to get the right position.
- int w;
- start().node()->renderer()->caretPos(start().offset(), true, m_caretX, m_caretY, w, m_caretSize);
+
+ Position pos = start();
+ if (!pos.inRenderedContent())
+ pos = pos.closestRenderedPosition(affinity());
+
+ if (pos.isEmpty() || !pos.inRenderedContent()) {
+ m_caretX = m_caretY = m_caretSize = 0;
+ return;
}
+
+ // EDIT FIXME: Enhance call to pass along selection
+ // upstream/downstream affinity to get the right position.
+ int w;
+ m_caretPosition = pos;
+ pos.node()->renderer()->caretPos(pos.offset(), true, m_caretX, m_caretY, w, m_caretSize);
m_needsCaretLayout = false;
}
@@ -503,13 +544,8 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
if (m_state != CARET)
return;
- if (m_needsCaretLayout) {
- Position pos = start();
- if (!pos.inRenderedContent()) {
- moveToRenderedContent();
- }
+ if (m_needsCaretLayout)
layoutCaret();
- }
QRect caretRect(m_caretX, m_caretY, 1, m_caretSize);
if (caretRect.intersects(rect)) {
diff --git a/WebCore/khtml/xml/dom_selection.h b/WebCore/khtml/xml/dom_selection.h
index 39e3933..9eb67d4 100644
--- a/WebCore/khtml/xml/dom_selection.h
+++ b/WebCore/khtml/xml/dom_selection.h
@@ -50,12 +50,6 @@ public:
enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
enum ETextGranularity { CHARACTER, WORD, LINE, PARAGRAPH };
- // These match the AppKit values for these concepts.
- // From NSTextView.h:
- // NSSelectionAffinityUpstream = 0
- // NSSelectionAffinityDownstream = 1
- enum EAffinity { UPSTREAM = 0, DOWNSTREAM = 1 };
-
Selection();
Selection(const Range &);
Selection(const Position &);
@@ -87,6 +81,7 @@ public:
Position extent() const { return m_extent; }
Position start() const { return m_start; }
Position end() const { return m_end; }
+ Position caretPosition() const { return m_caretPosition; }
QRect getRepaintRect() const;
void setNeedsLayout(bool flag=true);
@@ -124,6 +119,11 @@ private:
void assignEnd(const Position &pos) { m_end = pos; }
void assignStartAndEnd(const Position &start, const Position &end) { m_start = start; m_end = end; }
+ Position modifyExtendingRightForward(ETextGranularity);
+ Position modifyMovingRightForward(ETextGranularity);
+ Position modifyExtendingLeftBackward(ETextGranularity);
+ Position modifyMovingLeftBackward(ETextGranularity);
+
void layoutCaret();
void needsCaretRepaint();
void paintCaret(QPainter *p, const QRect &rect);
@@ -139,10 +139,11 @@ private:
EState m_state; // the state of the selection
EAffinity m_affinity; // the upstream/downstream affinity of the selection
- int m_caretX; // caret coordinates and size
+ int m_caretX; // caret coordinates, size, and position
int m_caretY;
int m_caretSize;
-
+ Position m_caretPosition;
+
bool m_baseIsStart : 1; // true if base node is before the extent node
bool m_needsCaretLayout : 1; // true if the caret position needs to be calculated
bool m_modifyBiasSet : 1; // true if the selection has been horizontally
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index 3c306cd..10e6965 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -1395,7 +1395,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
DocumentImpl *doc = startContainer->getDocument();
doc->updateLayout();
Selection selection(Position(startContainer, [range startOffset]), Position(endContainer, [range endOffset]));
- selection.setAffinity(static_cast<Selection::EAffinity>(selectionAffinity));
+ selection.setAffinity(static_cast<DOM::EAffinity>(selectionAffinity));
_part->setSelection(selection);
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list