[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:35:07 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 7784bef2ce7664523ae2dfbd9c431576804ba157
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Apr 20 21:20:23 2004 +0000
WebCore:
Reviewed by Hyatt
* WebCore.pbproj/project.pbxproj:
* khtml/khtml_part.cpp:
(KHTMLPart::handleMousePressEventDoubleClick): Improved name of expandToElement. Now is expandUsingGranularity.
(KHTMLPart::handleMousePressEventTripleClick): Ditto.
(KHTMLPart::handleMouseMoveEventSelection): Ditto.
* khtml/khtml_selection.cpp:
(KHTMLSelection::modify): Added support for modifying and extending selection right and left by word.
Also added support for extending selection up and down.
(KHTMLSelection::expandUsingGranularity): New name for expandToElement.
(KHTMLSelection::xPosForVerticalArrowNavigation): Made this function handle cases where we know we
want to use a particular position for calculating the right x position. We need this to handle
extending selection up and down, and for setting the caret to the right place when moving up
and down when a range is already selected.
(KHTMLSelection::validate): Name tweak. expandTo variable now granularity.
* khtml/khtml_selection.h: Make declaration changes for changes to cpp file.
* khtml/misc/helper.cpp:
(khtml::findWordBoundary): Added this hook for KDE to do their version of KWQFindWordBoundary
* khtml/misc/helper.h:
* khtml/rendering/render_block.cpp:
(khtml::RenderBlock::positionForCoordinates): Factor out closest box finder code to its own function
* khtml/rendering/render_line.cpp:
(InlineFlowBox::closestChildForXPos): New function. This is the factored code that was taken out of
render_block.cpp.
(InlineBox::closestLeafChildForXPos): Ditto.
* khtml/rendering/render_line.h: Ditto.
* khtml/rendering/render_replaced.cpp:
(RenderReplaced::positionForCoordinates): I think I am starting to get how the coordinate transforms work.
Made some fixups based on this greater sense of enlightenment.
* khtml/rendering/render_text.cpp:
(RenderText::positionForCoordinates): Ditto. Fix lastTextBox/firstTextBox code mistake.
* khtml/xml/dom_position.cpp:
(DOMPosition::previousWordPosition): Added.
(DOMPosition::nextWordPosition): Added.
(DOMPosition::previousLinePosition): No longer use nodeAtPoint. Use new closestLeafChildForXPos instead.
(DOMPosition::nextLinePosition): Ditto.
(DOMPosition::inLastEditableInContainingEditableBlock):
* khtml/xml/dom_position.h:
* kwq/KWQTextUtilities.cpp: Added.
(KWQFindWordBoundary): Factored out code that was in a static function in khtml_selection.cpp so
that DOMPosition can use it too.
* kwq/KWQTextUtilities.h: Added.
WebKit:
Reviewed by Hyatt
Added implementations for these methods.
* WebView.subproj/WebView.m:
(-[WebView moveUpAndModifySelection:]):
(-[WebView moveWordLeft:]):
(-[WebView moveWordLeftAndModifySelection:]):
(-[WebView moveWordRight:]):
(-[WebView moveWordRightAndModifySelection:]):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6431 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 3731d22..5f22656 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,49 @@
+2004-04-20 Ken Kocienda <kocienda at apple.com>
+
+ Reviewed by Hyatt
+
+ * WebCore.pbproj/project.pbxproj:
+ * khtml/khtml_part.cpp:
+ (KHTMLPart::handleMousePressEventDoubleClick): Improved name of expandToElement. Now is expandUsingGranularity.
+ (KHTMLPart::handleMousePressEventTripleClick): Ditto.
+ (KHTMLPart::handleMouseMoveEventSelection): Ditto.
+ * khtml/khtml_selection.cpp:
+ (KHTMLSelection::modify): Added support for modifying and extending selection right and left by word.
+ Also added support for extending selection up and down.
+ (KHTMLSelection::expandUsingGranularity): New name for expandToElement.
+ (KHTMLSelection::xPosForVerticalArrowNavigation): Made this function handle cases where we know we
+ want to use a particular position for calculating the right x position. We need this to handle
+ extending selection up and down, and for setting the caret to the right place when moving up
+ and down when a range is already selected.
+ (KHTMLSelection::validate): Name tweak. expandTo variable now granularity.
+ * khtml/khtml_selection.h: Make declaration changes for changes to cpp file.
+ * khtml/misc/helper.cpp:
+ (khtml::findWordBoundary): Added this hook for KDE to do their version of KWQFindWordBoundary
+ * khtml/misc/helper.h:
+ * khtml/rendering/render_block.cpp:
+ (khtml::RenderBlock::positionForCoordinates): Factor out closest box finder code to its own function
+ * khtml/rendering/render_line.cpp:
+ (InlineFlowBox::closestChildForXPos): New function. This is the factored code that was taken out of
+ render_block.cpp.
+ (InlineBox::closestLeafChildForXPos): Ditto.
+ * khtml/rendering/render_line.h: Ditto.
+ * khtml/rendering/render_replaced.cpp:
+ (RenderReplaced::positionForCoordinates): I think I am starting to get how the coordinate transforms work.
+ Made some fixups based on this greater sense of enlightenment.
+ * khtml/rendering/render_text.cpp:
+ (RenderText::positionForCoordinates): Ditto. Fix lastTextBox/firstTextBox code mistake.
+ * khtml/xml/dom_position.cpp:
+ (DOMPosition::previousWordPosition): Added.
+ (DOMPosition::nextWordPosition): Added.
+ (DOMPosition::previousLinePosition): No longer use nodeAtPoint. Use new closestLeafChildForXPos instead.
+ (DOMPosition::nextLinePosition): Ditto.
+ (DOMPosition::inLastEditableInContainingEditableBlock):
+ * khtml/xml/dom_position.h:
+ * kwq/KWQTextUtilities.cpp: Added.
+ (KWQFindWordBoundary): Factored out code that was in a static function in khtml_selection.cpp so
+ that DOMPosition can use it too.
+ * kwq/KWQTextUtilities.h: Added.
+
2004-04-19 Ken Kocienda <kocienda at apple.com>
Reviewed by Hyatt
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index d9f4f15..cdde0e8 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -532,6 +532,7 @@
BE91FC9206133697005E3790,
832556E5061DF155007B8054,
BC86FB8F061F5C23006BB822,
+ BE8BD8F506359F6000D3F20B,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -813,6 +814,7 @@
BE91FC9106133697005E3790,
832556E7061DF161007B8054,
BC86FB90061F5C23006BB822,
+ BE8BD8F406359F6000D3F20B,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@@ -860,7 +862,7 @@
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -f ../Tools/Scripts/embed-into-alex ]; then sh ../Tools/Scripts/embed-into-alex; fi";
+ shellScript = "#if [ -f ../Tools/Scripts/embed-into-alex ]; then sh ../Tools/Scripts/embed-into-alex; fi";
};
//250
//251
@@ -2716,6 +2718,34 @@
settings = {
};
};
+ BE8BD8F206359F6000D3F20B = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.cpp.cpp;
+ path = KWQTextUtilities.cpp;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ BE8BD8F306359F6000D3F20B = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ path = KWQTextUtilities.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ BE8BD8F406359F6000D3F20B = {
+ fileRef = BE8BD8F206359F6000D3F20B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ BE8BD8F506359F6000D3F20B = {
+ fileRef = BE8BD8F306359F6000D3F20B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
BE9185DD05EE59B80081354D = {
fileEncoding = 30;
isa = PBXFileReference;
@@ -3129,6 +3159,8 @@
93386B90037045B3008635CE,
93386B91037045B3008635CE,
F587852F02DE375901EA4122,
+ BE8BD8F206359F6000D3F20B,
+ BE8BD8F306359F6000D3F20B,
F587853502DE375901EA4122,
F587853602DE375901EA4122,
F587851B02DE375901EA4122,
diff --git a/WebCore/khtml/editing/SelectionController.cpp b/WebCore/khtml/editing/SelectionController.cpp
index 96d50e2..82dc803 100644
--- a/WebCore/khtml/editing/SelectionController.cpp
+++ b/WebCore/khtml/editing/SelectionController.cpp
@@ -46,6 +46,7 @@
#if APPLE_CHANGES
#include <KWQAssertions.h>
+#include <KWQTextUtilities.h>
#include <CoreServices/CoreServices.h>
#define EDIT_DEBUG 0
@@ -65,7 +66,6 @@ using khtml::RenderObject;
using khtml::RenderText;
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end);
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, KHTMLSelection &selection);
@@ -250,7 +250,7 @@ void KHTMLSelection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeI
validate();
}
-bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
+bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
DOMPosition pos;
@@ -258,76 +258,98 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
// EDIT FIXME: This needs to handle bidi
case RIGHT:
case FORWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(startNode());
- setBaseOffset(startOffset());
- setExtentNode(endNode());
- setExtentOffset(endOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().nextCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = endPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().nextCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = endPosition();
- else
- pos = endPosition().nextCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
}
break;
// EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(endNode());
- setBaseOffset(endOffset());
- setExtentNode(startNode());
- setExtentOffset(startOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().previousCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = startPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().previousCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = startPosition();
- else
- pos = startPosition().previousCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
}
break;
case UP:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+ }
break;
case DOWN:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().nextLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+ }
break;
}
@@ -342,25 +364,45 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
return true;
}
-void KHTMLSelection::expandToElement(ETextGranularity select)
+bool KHTMLSelection::expandUsingGranularity(ETextGranularity granularity)
{
- validate(select);
+ if (state() == NONE)
+ return false;
+
+ validate(granularity);
+ return true;
}
-int KHTMLSelection::xPosForVerticalArrowNavigation() const
+int KHTMLSelection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) const
{
int x = 0;
if (state() == NONE)
return x;
- KHTMLPart *part = startPosition().node()->getDocument()->part();
+ DOMPosition pos;
+ switch (type) {
+ case START:
+ pos = startPosition();
+ break;
+ case END:
+ pos = endPosition();
+ break;
+ case BASE:
+ pos = basePosition();
+ break;
+ case EXTENT:
+ pos = extentPosition();
+ break;
+ }
+
+ KHTMLPart *part = pos.node()->getDocument()->part();
if (!part)
return x;
- if (part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
+ if (recalc || part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
int y, w, h;
- startPosition().node()->renderer()->caretPos(startPosition().offset(), true, x, y, w, h);
+ pos.node()->renderer()->caretPos(pos.offset(), true, x, y, w, h);
part->setXPosForVerticalArrowNavigation(x);
}
else {
@@ -561,7 +603,7 @@ void KHTMLSelection::setEndOffset(long offset)
m_endOffset = offset;
}
-void KHTMLSelection::validate(ETextGranularity expandTo)
+void KHTMLSelection::validate(ETextGranularity granularity)
{
// move the base and extent nodes to their equivalent leaf positions
bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
@@ -625,7 +667,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
#else
- if (expandTo == CHARACTER) {
+ if (granularity == CHARACTER) {
if (m_baseIsStart) {
setStartNode(m_baseNode);
setStartOffset(m_baseOffset);
@@ -639,7 +681,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
}
- else if (expandTo == WORD) {
+ else if (granularity == WORD) {
int baseStartOffset = m_baseOffset;
int baseEndOffset = m_baseOffset;
int extentStartOffset = m_extentOffset;
@@ -648,13 +690,13 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
DOMString t = m_baseNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+ KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
}
if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
DOMString t = m_extentNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+ KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
}
if (m_baseIsStart) {
setStartNode(m_baseNode);
@@ -669,7 +711,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(baseEndOffset);
}
}
- else { // expandTo == LINE
+ else { // granularity == LINE
KHTMLSelection baseSelection = *this;
KHTMLSelection extentSelection = *this;
if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
@@ -822,55 +864,6 @@ bool KHTMLSelection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end)
-{
- TextBreakLocatorRef breakLocator;
- OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakWordMask, &breakLocator);
- if (status == noErr) {
- UniCharArrayOffset startOffset, endOffset;
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, 0, (const UniChar *)chars, len, position, &endOffset);
- if (status == noErr) {
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, kUCTextBreakGoBackwardsMask, (const UniChar *)chars, len, position, &startOffset);
- }
- UCDisposeTextBreakLocator(&breakLocator);
- if (status == noErr) {
- *start = startOffset;
- *end = endOffset;
- return;
- }
- }
-
- // If Carbon fails (why would it?), do a simple space/punctuation boundary check.
- if (chars[position].isSpace()) {
- int pos = position;
- while (chars[pos].isSpace() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isSpace() && pos < (int)len)
- pos++;
- *end = pos;
- } else if (chars[position].isPunct()) {
- int pos = position;
- while (chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- } else {
- int pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- }
-}
-
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
{
for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
diff --git a/WebCore/khtml/editing/SelectionController.h b/WebCore/khtml/editing/SelectionController.h
index f96e49a..326a0ea 100644
--- a/WebCore/khtml/editing/SelectionController.h
+++ b/WebCore/khtml/editing/SelectionController.h
@@ -64,7 +64,7 @@ public:
void moveTo(const KHTMLSelection &);
void moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset);
bool modify(EAlter, EDirection, ETextGranularity);
- void expandToElement(ETextGranularity);
+ bool expandUsingGranularity(ETextGranularity);
void clear();
bool moveToRenderedContent();
@@ -108,8 +108,10 @@ public:
friend class KHTMLPart;
private:
+ enum EPositionType { START, END, BASE, EXTENT };
+
void init();
- void validate(ETextGranularity expandTo=CHARACTER);
+ void validate(ETextGranularity granularity=CHARACTER);
void layoutCaret();
void needsCaretRepaint();
@@ -129,7 +131,7 @@ private:
bool nodeIsBeforeNode(DOM::NodeImpl *n1, DOM::NodeImpl *n2);
void calculateStartAndEnd(ETextGranularity select=CHARACTER);
- int xPosForVerticalArrowNavigation() const;
+ int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
DOM::NodeImpl *m_baseNode; // base node for the selection
long m_baseOffset; // offset into base node where selection is
diff --git a/WebCore/khtml/editing/selection.cpp b/WebCore/khtml/editing/selection.cpp
index 96d50e2..82dc803 100644
--- a/WebCore/khtml/editing/selection.cpp
+++ b/WebCore/khtml/editing/selection.cpp
@@ -46,6 +46,7 @@
#if APPLE_CHANGES
#include <KWQAssertions.h>
+#include <KWQTextUtilities.h>
#include <CoreServices/CoreServices.h>
#define EDIT_DEBUG 0
@@ -65,7 +66,6 @@ using khtml::RenderObject;
using khtml::RenderText;
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end);
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, KHTMLSelection &selection);
@@ -250,7 +250,7 @@ void KHTMLSelection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeI
validate();
}
-bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
+bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
DOMPosition pos;
@@ -258,76 +258,98 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
// EDIT FIXME: This needs to handle bidi
case RIGHT:
case FORWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(startNode());
- setBaseOffset(startOffset());
- setExtentNode(endNode());
- setExtentOffset(endOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().nextCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = endPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().nextCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = endPosition();
- else
- pos = endPosition().nextCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
}
break;
// EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(endNode());
- setBaseOffset(endOffset());
- setExtentNode(startNode());
- setExtentOffset(startOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().previousCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = startPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().previousCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = startPosition();
- else
- pos = startPosition().previousCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
}
break;
case UP:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+ }
break;
case DOWN:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().nextLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+ }
break;
}
@@ -342,25 +364,45 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
return true;
}
-void KHTMLSelection::expandToElement(ETextGranularity select)
+bool KHTMLSelection::expandUsingGranularity(ETextGranularity granularity)
{
- validate(select);
+ if (state() == NONE)
+ return false;
+
+ validate(granularity);
+ return true;
}
-int KHTMLSelection::xPosForVerticalArrowNavigation() const
+int KHTMLSelection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) const
{
int x = 0;
if (state() == NONE)
return x;
- KHTMLPart *part = startPosition().node()->getDocument()->part();
+ DOMPosition pos;
+ switch (type) {
+ case START:
+ pos = startPosition();
+ break;
+ case END:
+ pos = endPosition();
+ break;
+ case BASE:
+ pos = basePosition();
+ break;
+ case EXTENT:
+ pos = extentPosition();
+ break;
+ }
+
+ KHTMLPart *part = pos.node()->getDocument()->part();
if (!part)
return x;
- if (part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
+ if (recalc || part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
int y, w, h;
- startPosition().node()->renderer()->caretPos(startPosition().offset(), true, x, y, w, h);
+ pos.node()->renderer()->caretPos(pos.offset(), true, x, y, w, h);
part->setXPosForVerticalArrowNavigation(x);
}
else {
@@ -561,7 +603,7 @@ void KHTMLSelection::setEndOffset(long offset)
m_endOffset = offset;
}
-void KHTMLSelection::validate(ETextGranularity expandTo)
+void KHTMLSelection::validate(ETextGranularity granularity)
{
// move the base and extent nodes to their equivalent leaf positions
bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
@@ -625,7 +667,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
#else
- if (expandTo == CHARACTER) {
+ if (granularity == CHARACTER) {
if (m_baseIsStart) {
setStartNode(m_baseNode);
setStartOffset(m_baseOffset);
@@ -639,7 +681,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
}
- else if (expandTo == WORD) {
+ else if (granularity == WORD) {
int baseStartOffset = m_baseOffset;
int baseEndOffset = m_baseOffset;
int extentStartOffset = m_extentOffset;
@@ -648,13 +690,13 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
DOMString t = m_baseNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+ KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
}
if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
DOMString t = m_extentNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+ KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
}
if (m_baseIsStart) {
setStartNode(m_baseNode);
@@ -669,7 +711,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(baseEndOffset);
}
}
- else { // expandTo == LINE
+ else { // granularity == LINE
KHTMLSelection baseSelection = *this;
KHTMLSelection extentSelection = *this;
if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
@@ -822,55 +864,6 @@ bool KHTMLSelection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end)
-{
- TextBreakLocatorRef breakLocator;
- OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakWordMask, &breakLocator);
- if (status == noErr) {
- UniCharArrayOffset startOffset, endOffset;
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, 0, (const UniChar *)chars, len, position, &endOffset);
- if (status == noErr) {
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, kUCTextBreakGoBackwardsMask, (const UniChar *)chars, len, position, &startOffset);
- }
- UCDisposeTextBreakLocator(&breakLocator);
- if (status == noErr) {
- *start = startOffset;
- *end = endOffset;
- return;
- }
- }
-
- // If Carbon fails (why would it?), do a simple space/punctuation boundary check.
- if (chars[position].isSpace()) {
- int pos = position;
- while (chars[pos].isSpace() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isSpace() && pos < (int)len)
- pos++;
- *end = pos;
- } else if (chars[position].isPunct()) {
- int pos = position;
- while (chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- } else {
- int pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- }
-}
-
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
{
for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
diff --git a/WebCore/khtml/editing/selection.h b/WebCore/khtml/editing/selection.h
index f96e49a..326a0ea 100644
--- a/WebCore/khtml/editing/selection.h
+++ b/WebCore/khtml/editing/selection.h
@@ -64,7 +64,7 @@ public:
void moveTo(const KHTMLSelection &);
void moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset);
bool modify(EAlter, EDirection, ETextGranularity);
- void expandToElement(ETextGranularity);
+ bool expandUsingGranularity(ETextGranularity);
void clear();
bool moveToRenderedContent();
@@ -108,8 +108,10 @@ public:
friend class KHTMLPart;
private:
+ enum EPositionType { START, END, BASE, EXTENT };
+
void init();
- void validate(ETextGranularity expandTo=CHARACTER);
+ void validate(ETextGranularity granularity=CHARACTER);
void layoutCaret();
void needsCaretRepaint();
@@ -129,7 +131,7 @@ private:
bool nodeIsBeforeNode(DOM::NodeImpl *n1, DOM::NodeImpl *n2);
void calculateStartAndEnd(ETextGranularity select=CHARACTER);
- int xPosForVerticalArrowNavigation() const;
+ int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
DOM::NodeImpl *m_baseNode; // base node for the selection
long m_baseOffset; // offset into base node where selection is
diff --git a/WebCore/khtml/khtml_part.cpp b/WebCore/khtml/khtml_part.cpp
index cb13fca..1ae0d19 100644
--- a/WebCore/khtml/khtml_part.cpp
+++ b/WebCore/khtml/khtml_part.cpp
@@ -4544,7 +4544,7 @@ void KHTMLPart::handleMousePressEventDoubleClick(khtml::MousePressEvent *event)
DOMPosition pos(innerNode.handle()->positionForCoordinates(event->x(), event->y()));
if (pos.node() && (pos.node()->nodeType() == Node::TEXT_NODE || pos.node()->nodeType() == Node::CDATA_SECTION_NODE)) {
selection.moveTo(pos);
- selection.expandToElement(KHTMLSelection::WORD);
+ selection.expandUsingGranularity(KHTMLSelection::WORD);
}
}
@@ -4567,7 +4567,7 @@ void KHTMLPart::handleMousePressEventTripleClick(khtml::MousePressEvent *event)
DOMPosition pos(innerNode.handle()->positionForCoordinates(event->x(), event->y()));
if (pos.node() && (pos.node()->nodeType() == Node::TEXT_NODE || pos.node()->nodeType() == Node::CDATA_SECTION_NODE)) {
selection.moveTo(pos);
- selection.expandToElement(KHTMLSelection::LINE);
+ selection.expandUsingGranularity(KHTMLSelection::LINE);
}
}
@@ -4818,7 +4818,7 @@ void KHTMLPart::handleMouseMoveEventSelection(khtml::MouseMoveEvent *event)
#if APPLE_CHANGES
if (d->m_textElement != KHTMLSelection::CHARACTER) {
- sel.expandToElement(d->m_textElement);
+ sel.expandUsingGranularity(d->m_textElement);
}
#endif
diff --git a/WebCore/khtml/khtml_selection.cpp b/WebCore/khtml/khtml_selection.cpp
index 96d50e2..82dc803 100644
--- a/WebCore/khtml/khtml_selection.cpp
+++ b/WebCore/khtml/khtml_selection.cpp
@@ -46,6 +46,7 @@
#if APPLE_CHANGES
#include <KWQAssertions.h>
+#include <KWQTextUtilities.h>
#include <CoreServices/CoreServices.h>
#define EDIT_DEBUG 0
@@ -65,7 +66,6 @@ using khtml::RenderObject;
using khtml::RenderText;
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end);
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, KHTMLSelection &selection);
@@ -250,7 +250,7 @@ void KHTMLSelection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeI
validate();
}
-bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
+bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
DOMPosition pos;
@@ -258,76 +258,98 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
// EDIT FIXME: This needs to handle bidi
case RIGHT:
case FORWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(startNode());
- setBaseOffset(startOffset());
- setExtentNode(endNode());
- setExtentOffset(endOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().nextCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = endPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().nextCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = endPosition();
- else
- pos = endPosition().nextCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
}
break;
// EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(endNode());
- setBaseOffset(endOffset());
- setExtentNode(startNode());
- setExtentOffset(startOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().previousCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = startPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().previousCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = startPosition();
- else
- pos = startPosition().previousCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
}
break;
case UP:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+ }
break;
case DOWN:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().nextLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+ }
break;
}
@@ -342,25 +364,45 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
return true;
}
-void KHTMLSelection::expandToElement(ETextGranularity select)
+bool KHTMLSelection::expandUsingGranularity(ETextGranularity granularity)
{
- validate(select);
+ if (state() == NONE)
+ return false;
+
+ validate(granularity);
+ return true;
}
-int KHTMLSelection::xPosForVerticalArrowNavigation() const
+int KHTMLSelection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) const
{
int x = 0;
if (state() == NONE)
return x;
- KHTMLPart *part = startPosition().node()->getDocument()->part();
+ DOMPosition pos;
+ switch (type) {
+ case START:
+ pos = startPosition();
+ break;
+ case END:
+ pos = endPosition();
+ break;
+ case BASE:
+ pos = basePosition();
+ break;
+ case EXTENT:
+ pos = extentPosition();
+ break;
+ }
+
+ KHTMLPart *part = pos.node()->getDocument()->part();
if (!part)
return x;
- if (part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
+ if (recalc || part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
int y, w, h;
- startPosition().node()->renderer()->caretPos(startPosition().offset(), true, x, y, w, h);
+ pos.node()->renderer()->caretPos(pos.offset(), true, x, y, w, h);
part->setXPosForVerticalArrowNavigation(x);
}
else {
@@ -561,7 +603,7 @@ void KHTMLSelection::setEndOffset(long offset)
m_endOffset = offset;
}
-void KHTMLSelection::validate(ETextGranularity expandTo)
+void KHTMLSelection::validate(ETextGranularity granularity)
{
// move the base and extent nodes to their equivalent leaf positions
bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
@@ -625,7 +667,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
#else
- if (expandTo == CHARACTER) {
+ if (granularity == CHARACTER) {
if (m_baseIsStart) {
setStartNode(m_baseNode);
setStartOffset(m_baseOffset);
@@ -639,7 +681,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
}
- else if (expandTo == WORD) {
+ else if (granularity == WORD) {
int baseStartOffset = m_baseOffset;
int baseEndOffset = m_baseOffset;
int extentStartOffset = m_extentOffset;
@@ -648,13 +690,13 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
DOMString t = m_baseNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+ KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
}
if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
DOMString t = m_extentNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+ KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
}
if (m_baseIsStart) {
setStartNode(m_baseNode);
@@ -669,7 +711,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(baseEndOffset);
}
}
- else { // expandTo == LINE
+ else { // granularity == LINE
KHTMLSelection baseSelection = *this;
KHTMLSelection extentSelection = *this;
if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
@@ -822,55 +864,6 @@ bool KHTMLSelection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end)
-{
- TextBreakLocatorRef breakLocator;
- OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakWordMask, &breakLocator);
- if (status == noErr) {
- UniCharArrayOffset startOffset, endOffset;
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, 0, (const UniChar *)chars, len, position, &endOffset);
- if (status == noErr) {
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, kUCTextBreakGoBackwardsMask, (const UniChar *)chars, len, position, &startOffset);
- }
- UCDisposeTextBreakLocator(&breakLocator);
- if (status == noErr) {
- *start = startOffset;
- *end = endOffset;
- return;
- }
- }
-
- // If Carbon fails (why would it?), do a simple space/punctuation boundary check.
- if (chars[position].isSpace()) {
- int pos = position;
- while (chars[pos].isSpace() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isSpace() && pos < (int)len)
- pos++;
- *end = pos;
- } else if (chars[position].isPunct()) {
- int pos = position;
- while (chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- } else {
- int pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- }
-}
-
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
{
for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
diff --git a/WebCore/khtml/khtml_selection.h b/WebCore/khtml/khtml_selection.h
index f96e49a..326a0ea 100644
--- a/WebCore/khtml/khtml_selection.h
+++ b/WebCore/khtml/khtml_selection.h
@@ -64,7 +64,7 @@ public:
void moveTo(const KHTMLSelection &);
void moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset);
bool modify(EAlter, EDirection, ETextGranularity);
- void expandToElement(ETextGranularity);
+ bool expandUsingGranularity(ETextGranularity);
void clear();
bool moveToRenderedContent();
@@ -108,8 +108,10 @@ public:
friend class KHTMLPart;
private:
+ enum EPositionType { START, END, BASE, EXTENT };
+
void init();
- void validate(ETextGranularity expandTo=CHARACTER);
+ void validate(ETextGranularity granularity=CHARACTER);
void layoutCaret();
void needsCaretRepaint();
@@ -129,7 +131,7 @@ private:
bool nodeIsBeforeNode(DOM::NodeImpl *n1, DOM::NodeImpl *n2);
void calculateStartAndEnd(ETextGranularity select=CHARACTER);
- int xPosForVerticalArrowNavigation() const;
+ int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
DOM::NodeImpl *m_baseNode; // base node for the selection
long m_baseOffset; // offset into base node where selection is
diff --git a/WebCore/khtml/misc/helper.cpp b/WebCore/khtml/misc/helper.cpp
index 7bae657..607b703 100644
--- a/WebCore/khtml/misc/helper.cpp
+++ b/WebCore/khtml/misc/helper.cpp
@@ -23,9 +23,22 @@
#include "helper.h"
+#if APPLE_CHANGES
+#include "KWQTextUtilities.h"
+#endif
+
QPainter *khtml::printpainter = 0;
void khtml::setPrintPainter( QPainter *printer )
{
printpainter = printer;
}
+
+void khtml::findWordBoundary(QChar *chars, int len, int position, int *start, int *end)
+{
+#if APPLE_CHANGES
+ KWQFindWordBoundary(chars, len, position, start, end);
+#else
+ // KDE implementation
+#endif
+}
\ No newline at end of file
diff --git a/WebCore/khtml/misc/helper.h b/WebCore/khtml/misc/helper.h
index 537032e..a4622cd 100644
--- a/WebCore/khtml/misc/helper.h
+++ b/WebCore/khtml/misc/helper.h
@@ -22,8 +22,10 @@
#ifndef html_helper_h
#define html_helper_h
-#include <qcolor.h>
class QPainter;
+class QChar;
+
+#include <qcolor.h>
#include <qfontmetrics.h>
#include <qfont.h>
@@ -44,6 +46,10 @@ namespace khtml
// to get BiDi contexts right.
SelectionPointBeforeInLine,
SelectionPointAfterInLine };
+
+
+
+ void findWordBoundary(QChar *chars, int len, int position, int *start, int *end);
};
#endif
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 33dde28..f04a45b 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -2085,36 +2085,9 @@ DOMPosition RenderBlock::positionForCoordinates(int _x, int _y)
bottom = absy + root->bottomOverflow();
// check if this root line box is located at this y coordinate
if (_y >= top && _y < bottom && root->firstChild()) {
- InlineBox *closestBox = 0;
- bool useClosestBoxLeftEdge = true;
-
- if (_x <= absx + root->firstChild()->m_x) {
- // if the x coordinate is to the left of the root box's first child,
- // make the first child closest
- closestBox = root->firstChild();
- }
- else if (_x >= absx + root->lastChild()->m_x + root->lastChild()->m_width) {
- // if the x coordinate is to the right of the root box's last child,
- // make the last child closest
- closestBox = root->lastChild();
- useClosestBoxLeftEdge = false;
- }
- else {
- // look for the closest child for this root;
- // check only the right edges, since the left edge of the first
- // box has already been checked
- for (InlineBox *box = root->firstChild(); box; box = box->nextOnLine()) {
- if (_x < absx + box->m_x + box->m_width) {
- closestBox = box;
- useClosestBoxLeftEdge = false;
- break;
- }
- }
- }
- if (closestBox) {
- RenderObject *renderer = useClosestBoxLeftEdge ? closestBox->firstLeafChild()->object() : closestBox->lastLeafChild()->object();
- return renderer->positionForCoordinates(_x, _y);
- }
+ InlineBox *closestBox = root->closestLeafChildForXPos(_x, absx);
+ if (closestBox)
+ return closestBox->object()->positionForCoordinates(_x, _y);
}
}
return DOMPosition(element(), 0);
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
index 4859d66..a5f52aa 100644
--- a/WebCore/khtml/rendering/render_line.cpp
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -759,6 +759,41 @@ InlineBox* InlineFlowBox::lastLeafChild()
return box;
}
+InlineBox* InlineFlowBox::closestChildForXPos(int _x, int _tx)
+{
+ if (_x < _tx + firstChild()->m_x)
+ // if the x coordinate is to the left of the first child
+ return firstChild();
+ else if (_x >= _tx + lastChild()->m_x + lastChild()->m_width)
+ // if the x coordinate is to the right of the last child
+ return lastChild();
+ else
+ // look for the closest child;
+ // check only the right edges, since the left edge of the first
+ // box has already been checked
+ for (InlineBox *box = firstChild(); box; box = box->nextOnLine())
+ if (_x < _tx + box->m_x + box->m_width)
+ return box;
+
+ return 0;
+}
+
+InlineBox* InlineBox::closestLeafChildForXPos(int _x, int _tx)
+{
+ if (!isInlineFlowBox())
+ return this;
+
+ InlineFlowBox *flowBox = static_cast<InlineFlowBox*>(this);
+ if (!flowBox->firstChild())
+ return this;
+
+ InlineBox *box = flowBox->closestChildForXPos(_x, _tx);
+ if (!box)
+ return this;
+
+ return box->closestLeafChildForXPos(_x, _tx);
+}
+
void RootInlineBox::adjustVerticalPosition(int delta)
{
InlineFlowBox::adjustVerticalPosition(delta);
@@ -778,4 +813,3 @@ void RootInlineBox::childRemoved(InlineBox* box)
prev->markDirty();
}
}
-
diff --git a/WebCore/khtml/rendering/render_line.h b/WebCore/khtml/rendering/render_line.h
index 7052ceb..970393b 100644
--- a/WebCore/khtml/rendering/render_line.h
+++ b/WebCore/khtml/rendering/render_line.h
@@ -92,6 +92,7 @@ public:
virtual InlineBox* firstLeafChild();
virtual InlineBox* lastLeafChild();
+ InlineBox* closestLeafChildForXPos(int _x, int _tx);
RenderObject* object() const { return m_object; }
@@ -195,6 +196,7 @@ public:
virtual InlineBox* firstLeafChild();
virtual InlineBox* lastLeafChild();
+ InlineBox* closestChildForXPos(int _x, int _tx);
virtual void setConstructed() {
InlineBox::setConstructed();
diff --git a/WebCore/khtml/rendering/render_replaced.cpp b/WebCore/khtml/rendering/render_replaced.cpp
index 6ec4711..b993a7e 100644
--- a/WebCore/khtml/rendering/render_replaced.cpp
+++ b/WebCore/khtml/rendering/render_replaced.cpp
@@ -137,10 +137,10 @@ DOMPosition RenderReplaced::positionForCoordinates(int _x, int _y)
RootInlineBox *root = box->root();
int absx, absy;
- absolutePosition(absx, absy);
+ containingBlock()->absolutePosition(absx, absy);
int top = absy + root->topOverflow();
- int bottom = absy + root->bottomOverflow();
+ int bottom = root->nextRootBox() ? absy + root->nextRootBox()->topOverflow() : absy + root->bottomOverflow();
if (_y < top)
return DOMPosition(element(), caretMinOffset()); // coordinates are above
@@ -149,7 +149,7 @@ DOMPosition RenderReplaced::positionForCoordinates(int _x, int _y)
return DOMPosition(element(), caretMaxOffset()); // coordinates are below
if (element()) {
- if (_x <= absx + (width() / 2))
+ if (_x <= absx + xPos() + (width() / 2))
return DOMPosition(element(), 0);
return DOMPosition(element(), 1);
}
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 7db9f66..68a73c4 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -445,12 +445,12 @@ DOMPosition RenderText::positionForCoordinates(int _x, int _y)
return DOMPosition(element(), 0);
int absx, absy;
- absolutePosition(absx, absy);
+ containingBlock()->absolutePosition(absx, absy);
if (firstTextBox() && _y < absy + firstTextBox()->root()->bottomOverflow() && _x < absx + firstTextBox()->m_x) {
// at the y coordinate of the first line or above
// and the x coordinate is to the left than the first text box left edge
- return DOMPosition(element(), lastTextBox()->m_start);
+ return DOMPosition(element(), firstTextBox()->m_start);
}
if (lastTextBox() && _y >= absy + lastTextBox()->root()->topOverflow() && _x >= absx + lastTextBox()->m_x + lastTextBox()->m_width) {
diff --git a/WebCore/khtml/xml/dom_position.cpp b/WebCore/khtml/xml/dom_position.cpp
index f5aef10..f25cfa3 100644
--- a/WebCore/khtml/xml/dom_position.cpp
+++ b/WebCore/khtml/xml/dom_position.cpp
@@ -25,7 +25,9 @@
#include "dom_position.h"
+#include "helper.h"
#include "htmltags.h"
+#include "qstring.h"
#include "rendering/render_block.h"
#include "rendering/render_line.h"
#include "rendering/render_object.h"
@@ -45,6 +47,7 @@ using DOM::NodeImpl;
using khtml::InlineBox;
using khtml::InlineFlowBox;
using khtml::InlineTextBox;
+using khtml::RenderBlock;
using khtml::RenderObject;
using khtml::RenderText;
using khtml::RootInlineBox;
@@ -298,6 +301,58 @@ DOMPosition DOMPosition::nextCharacterPosition() const
return *this;
}
+DOMPosition DOMPosition::previousWordPosition() const
+{
+ if (isEmpty())
+ return DOMPosition();
+
+ DOMPosition pos = *this;
+ for (EditIterator it(*this); !it.atStart(); it.previous()) {
+ if (it.current().node()->nodeType() == Node::TEXT_NODE || it.current().node()->nodeType() == Node::CDATA_SECTION_NODE) {
+ DOMString t = it.current().node()->nodeValue();
+ QChar *chars = t.unicode();
+ uint len = t.length();
+ int start, end;
+ khtml::findWordBoundary(chars, len, it.current().offset(), &start, &end);
+ pos = DOMPosition(it.current().node(), start);
+ }
+ else {
+ pos = DOMPosition(it.current().node(), it.current().node()->caretMinOffset());
+ }
+ if (pos != *this)
+ return pos;
+ it.setPosition(pos);
+ }
+
+ return *this;
+}
+
+DOMPosition DOMPosition::nextWordPosition() const
+{
+ if (isEmpty())
+ return DOMPosition();
+
+ DOMPosition pos = *this;
+ for (EditIterator it(*this); !it.atEnd(); it.next()) {
+ if (it.current().node()->nodeType() == Node::TEXT_NODE || it.current().node()->nodeType() == Node::CDATA_SECTION_NODE) {
+ DOMString t = it.current().node()->nodeValue();
+ QChar *chars = t.unicode();
+ uint len = t.length();
+ int start, end;
+ khtml::findWordBoundary(chars, len, it.current().offset(), &start, &end);
+ pos = DOMPosition(it.current().node(), end);
+ }
+ else {
+ pos = DOMPosition(it.current().node(), it.current().node()->caretMaxOffset());
+ }
+ if (pos != *this)
+ return pos;
+ it.setPosition(pos);
+ }
+
+ return *this;
+}
+
DOMPosition DOMPosition::previousLinePosition(int x) const
{
if (!node())
@@ -310,10 +365,10 @@ DOMPosition DOMPosition::previousLinePosition(int x) const
if (!box)
return *this;
- NodeImpl *previousLineNode = 0;
+ RenderBlock *containingBlock = 0;
RootInlineBox *root = box->root()->prevRootBox();
if (root) {
- previousLineNode = node();
+ containingBlock = node()->renderer()->containingBlock();
}
else {
// This containing editable block does not have a previous line.
@@ -331,26 +386,19 @@ DOMPosition DOMPosition::previousLinePosition(int x) const
ASSERT(box);
// previous root line box found
root = box->root();
- previousLineNode = n;
+ containingBlock = n->renderer()->containingBlock();
}
}
}
- if (!root)
- return *this;
- ASSERT(previousLineNode);
-
- int absx, absy;
- previousLineNode->renderer()->containingBlock()->absolutePosition(absx, absy);
- int y = absy + root->topOverflow() + ((root->bottomOverflow() - root->topOverflow()) / 2);
-
- RenderObject::NodeInfo nodeInfo(true, true);
- previousLineNode->getDocument()->renderer()->layer()->nodeAtPoint(nodeInfo, x, y);
-
- if (!nodeInfo.innerNode() || !nodeInfo.innerNode()->renderer())
- return *this;
+ if (root) {
+ int absx, absy;
+ containingBlock->absolutePosition(absx, absy);
+ RenderObject *renderer = root->closestLeafChildForXPos(x, absx)->object();
+ return renderer->positionForCoordinates(x, absy + root->topOverflow());
+ }
- return nodeInfo.innerNode()->renderer()->positionForCoordinates(x, y);
+ return *this;
}
DOMPosition DOMPosition::nextLinePosition(int x) const
@@ -365,10 +413,10 @@ DOMPosition DOMPosition::nextLinePosition(int x) const
if (!box)
return *this;
- NodeImpl *nextLineNode = 0;
+ RenderBlock *containingBlock = 0;
RootInlineBox *root = box->root()->nextRootBox();
if (root) {
- nextLineNode = node();
+ containingBlock = node()->renderer()->containingBlock();
}
else {
// This containing editable block does not have a next line.
@@ -386,25 +434,19 @@ DOMPosition DOMPosition::nextLinePosition(int x) const
ASSERT(box);
// previous root line box found
root = box->root();
- nextLineNode = n;
+ containingBlock = n->renderer()->containingBlock();
}
}
}
- if (!root)
- return *this;
- ASSERT(nextLineNode);
-
- int absx, absy;
- nextLineNode->renderer()->containingBlock()->absolutePosition(absx, absy);
- int y = absy + root->topOverflow() + ((root->bottomOverflow() - root->topOverflow()) / 2);
-
- RenderObject::NodeInfo nodeInfo(true, true);
- nextLineNode->getDocument()->renderer()->layer()->nodeAtPoint(nodeInfo, x, y);
- if (!nodeInfo.innerNode() || !nodeInfo.innerNode()->renderer())
- return *this;
-
- return nodeInfo.innerNode()->renderer()->positionForCoordinates(x, y);
+ if (root) {
+ int absx, absy;
+ containingBlock->absolutePosition(absx, absy);
+ RenderObject *renderer = root->closestLeafChildForXPos(x, absx)->object();
+ return renderer->positionForCoordinates(x, absy + root->topOverflow());
+ }
+
+ return *this;
}
DOMPosition DOMPosition::equivalentUpstreamPosition() const
@@ -825,5 +867,3 @@ bool DOMPosition::inLastEditableInContainingEditableBlock() const
return true;
}
-
-
diff --git a/WebCore/khtml/xml/dom_position.h b/WebCore/khtml/xml/dom_position.h
index b94c867..13310cf 100644
--- a/WebCore/khtml/xml/dom_position.h
+++ b/WebCore/khtml/xml/dom_position.h
@@ -51,6 +51,8 @@ public:
DOMPosition nextRenderedEditablePosition() const;
DOMPosition previousCharacterPosition() const;
DOMPosition nextCharacterPosition() const;
+ DOMPosition previousWordPosition() const;
+ DOMPosition nextWordPosition() const;
DOMPosition previousLinePosition(int x) const;
DOMPosition nextLinePosition(int x) const;
DOMPosition equivalentUpstreamPosition() const;
diff --git a/WebCore/khtml/xml/dom_selection.cpp b/WebCore/khtml/xml/dom_selection.cpp
index 96d50e2..82dc803 100644
--- a/WebCore/khtml/xml/dom_selection.cpp
+++ b/WebCore/khtml/xml/dom_selection.cpp
@@ -46,6 +46,7 @@
#if APPLE_CHANGES
#include <KWQAssertions.h>
+#include <KWQTextUtilities.h>
#include <CoreServices/CoreServices.h>
#define EDIT_DEBUG 0
@@ -65,7 +66,6 @@ using khtml::RenderObject;
using khtml::RenderText;
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end);
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, KHTMLSelection &selection);
@@ -250,7 +250,7 @@ void KHTMLSelection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeI
validate();
}
-bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
+bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
{
DOMPosition pos;
@@ -258,76 +258,98 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
// EDIT FIXME: This needs to handle bidi
case RIGHT:
case FORWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(startNode());
- setBaseOffset(startOffset());
- setExtentNode(endNode());
- setExtentOffset(endOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().nextCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = endPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().nextCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = endPosition();
- else
- pos = endPosition().nextCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().nextWordPosition();
+ }
}
break;
// EDIT FIXME: This needs to handle bidi
case LEFT:
case BACKWARD:
- switch (elem) {
- case CHARACTER:
- if (alter == EXTEND) {
- if (!m_modifyBiasSet) {
- m_modifyBiasSet = true;
- setBaseNode(endNode());
- setBaseOffset(endOffset());
- setExtentNode(startNode());
- setExtentOffset(startOffset());
- }
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ if (granularity == CHARACTER)
+ pos = extentPosition().previousCharacterPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ m_modifyBiasSet = false;
+ if (state() == RANGE) {
+ if (granularity == CHARACTER)
+ pos = startPosition();
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
+ else {
+ if (granularity == CHARACTER)
pos = extentPosition().previousCharacterPosition();
- }
- else {
- m_modifyBiasSet = false;
- if (state() == RANGE)
- pos = startPosition();
- else
- pos = startPosition().previousCharacterPosition();
- }
- break;
- case WORD:
- // EDIT FIXME: implement
- break;
- case LINE:
- // EDIT FIXME: implement
- break;
+ else if (granularity == WORD)
+ pos = extentPosition().previousWordPosition();
+ }
}
break;
case UP:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(endNode());
+ setBaseOffset(endOffset());
+ setExtentNode(startNode());
+ setExtentOffset(startOffset());
+ }
+ pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+ }
break;
case DOWN:
- if (alter == EXTEND)
- ERROR("unimplemented");
- else
- pos = startPosition().nextLinePosition(xPosForVerticalArrowNavigation());
+ if (alter == EXTEND) {
+ if (!m_modifyBiasSet) {
+ m_modifyBiasSet = true;
+ setBaseNode(startNode());
+ setBaseOffset(startOffset());
+ setExtentNode(endNode());
+ setExtentOffset(endOffset());
+ }
+ pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+ }
+ else {
+ m_modifyBiasSet = false;
+ pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+ }
break;
}
@@ -342,25 +364,45 @@ bool KHTMLSelection::modify(EAlter alter, EDirection dir, ETextGranularity elem)
return true;
}
-void KHTMLSelection::expandToElement(ETextGranularity select)
+bool KHTMLSelection::expandUsingGranularity(ETextGranularity granularity)
{
- validate(select);
+ if (state() == NONE)
+ return false;
+
+ validate(granularity);
+ return true;
}
-int KHTMLSelection::xPosForVerticalArrowNavigation() const
+int KHTMLSelection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) const
{
int x = 0;
if (state() == NONE)
return x;
- KHTMLPart *part = startPosition().node()->getDocument()->part();
+ DOMPosition pos;
+ switch (type) {
+ case START:
+ pos = startPosition();
+ break;
+ case END:
+ pos = endPosition();
+ break;
+ case BASE:
+ pos = basePosition();
+ break;
+ case EXTENT:
+ pos = extentPosition();
+ break;
+ }
+
+ KHTMLPart *part = pos.node()->getDocument()->part();
if (!part)
return x;
- if (part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
+ if (recalc || part->xPosForVerticalArrowNavigation() == KHTMLPart::NoXPosForVerticalArrowNavigation) {
int y, w, h;
- startPosition().node()->renderer()->caretPos(startPosition().offset(), true, x, y, w, h);
+ pos.node()->renderer()->caretPos(pos.offset(), true, x, y, w, h);
part->setXPosForVerticalArrowNavigation(x);
}
else {
@@ -561,7 +603,7 @@ void KHTMLSelection::setEndOffset(long offset)
m_endOffset = offset;
}
-void KHTMLSelection::validate(ETextGranularity expandTo)
+void KHTMLSelection::validate(ETextGranularity granularity)
{
// move the base and extent nodes to their equivalent leaf positions
bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
@@ -625,7 +667,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
#else
- if (expandTo == CHARACTER) {
+ if (granularity == CHARACTER) {
if (m_baseIsStart) {
setStartNode(m_baseNode);
setStartOffset(m_baseOffset);
@@ -639,7 +681,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(m_baseOffset);
}
}
- else if (expandTo == WORD) {
+ else if (granularity == WORD) {
int baseStartOffset = m_baseOffset;
int baseEndOffset = m_baseOffset;
int extentStartOffset = m_extentOffset;
@@ -648,13 +690,13 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
DOMString t = m_baseNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+ KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
}
if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
DOMString t = m_extentNode->nodeValue();
QChar *chars = t.unicode();
uint len = t.length();
- findWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+ KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
}
if (m_baseIsStart) {
setStartNode(m_baseNode);
@@ -669,7 +711,7 @@ void KHTMLSelection::validate(ETextGranularity expandTo)
setEndOffset(baseEndOffset);
}
}
- else { // expandTo == LINE
+ else { // granularity == LINE
KHTMLSelection baseSelection = *this;
KHTMLSelection extentSelection = *this;
if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
@@ -822,55 +864,6 @@ bool KHTMLSelection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
#if APPLE_CHANGES
-static void findWordBoundary(QChar *chars, int len, int position, int *start, int *end)
-{
- TextBreakLocatorRef breakLocator;
- OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakWordMask, &breakLocator);
- if (status == noErr) {
- UniCharArrayOffset startOffset, endOffset;
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, 0, (const UniChar *)chars, len, position, &endOffset);
- if (status == noErr) {
- status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, kUCTextBreakGoBackwardsMask, (const UniChar *)chars, len, position, &startOffset);
- }
- UCDisposeTextBreakLocator(&breakLocator);
- if (status == noErr) {
- *start = startOffset;
- *end = endOffset;
- return;
- }
- }
-
- // If Carbon fails (why would it?), do a simple space/punctuation boundary check.
- if (chars[position].isSpace()) {
- int pos = position;
- while (chars[pos].isSpace() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isSpace() && pos < (int)len)
- pos++;
- *end = pos;
- } else if (chars[position].isPunct()) {
- int pos = position;
- while (chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- } else {
- int pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos >= 0)
- pos--;
- *start = pos+1;
- pos = position;
- while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos < (int)len)
- pos++;
- *end = pos;
- }
-}
-
static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
{
for (RenderObject *n = renderNode; n; n = n->nextSibling()) {
diff --git a/WebCore/khtml/xml/dom_selection.h b/WebCore/khtml/xml/dom_selection.h
index f96e49a..326a0ea 100644
--- a/WebCore/khtml/xml/dom_selection.h
+++ b/WebCore/khtml/xml/dom_selection.h
@@ -64,7 +64,7 @@ public:
void moveTo(const KHTMLSelection &);
void moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset);
bool modify(EAlter, EDirection, ETextGranularity);
- void expandToElement(ETextGranularity);
+ bool expandUsingGranularity(ETextGranularity);
void clear();
bool moveToRenderedContent();
@@ -108,8 +108,10 @@ public:
friend class KHTMLPart;
private:
+ enum EPositionType { START, END, BASE, EXTENT };
+
void init();
- void validate(ETextGranularity expandTo=CHARACTER);
+ void validate(ETextGranularity granularity=CHARACTER);
void layoutCaret();
void needsCaretRepaint();
@@ -129,7 +131,7 @@ private:
bool nodeIsBeforeNode(DOM::NodeImpl *n1, DOM::NodeImpl *n2);
void calculateStartAndEnd(ETextGranularity select=CHARACTER);
- int xPosForVerticalArrowNavigation() const;
+ int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
DOM::NodeImpl *m_baseNode; // base node for the selection
long m_baseOffset; // offset into base node where selection is
diff --git a/WebCore/kwq/KWQTextUtilities.cpp b/WebCore/kwq/KWQTextUtilities.cpp
new file mode 100644
index 0000000..9260bf1
--- /dev/null
+++ b/WebCore/kwq/KWQTextUtilities.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#import "KWQTextUtilities.h"
+
+#import <qstring.h>
+
+#import <CoreServices/CoreServices.h>
+
+void KWQFindWordBoundary(QChar *chars, int len, int position, int *start, int *end)
+{
+ TextBreakLocatorRef breakLocator;
+ OSStatus status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakWordMask, &breakLocator);
+ if (status == noErr) {
+ UniCharArrayOffset startOffset, endOffset;
+ status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, 0, (const UniChar *)chars, len, position, &endOffset);
+ if (status == noErr) {
+ status = UCFindTextBreak(breakLocator, kUCTextBreakWordMask, kUCTextBreakGoBackwardsMask, (const UniChar *)chars, len, position, &startOffset);
+ }
+ UCDisposeTextBreakLocator(&breakLocator);
+ if (status == noErr) {
+ *start = startOffset;
+ *end = endOffset;
+ return;
+ }
+ }
+
+ // If Carbon fails (why would it?), do a simple space/punctuation boundary check.
+ if (chars[position].isSpace()) {
+ int pos = position;
+ while (chars[pos].isSpace() && pos >= 0)
+ pos--;
+ *start = pos+1;
+ pos = position;
+ while (chars[pos].isSpace() && pos < (int)len)
+ pos++;
+ *end = pos;
+ } else if (chars[position].isPunct()) {
+ int pos = position;
+ while (chars[pos].isPunct() && pos >= 0)
+ pos--;
+ *start = pos+1;
+ pos = position;
+ while (chars[pos].isPunct() && pos < (int)len)
+ pos++;
+ *end = pos;
+ } else {
+ int pos = position;
+ while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos >= 0)
+ pos--;
+ *start = pos+1;
+ pos = position;
+ while (!chars[pos].isSpace() && !chars[pos].isPunct() && pos < (int)len)
+ pos++;
+ *end = pos;
+ }
+}
diff --git a/WebCore/kwq/KWQView.h b/WebCore/kwq/KWQTextUtilities.h
similarity index 89%
copy from WebCore/kwq/KWQView.h
copy to WebCore/kwq/KWQTextUtilities.h
index bac6d18..bedeb32 100644
--- a/WebCore/kwq/KWQView.h
+++ b/WebCore/kwq/KWQTextUtilities.h
@@ -22,12 +22,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-#import <Cocoa/Cocoa.h>
-class QWidget;
+#ifndef _KWQTextUtilities_h_
+#define _KWQTextUtilities_h_
+
+class QChar;
+
+void KWQFindWordBoundary(QChar *chars, int len, int position, int *start, int *end);
-// all AK View subclasses in KWQ should implement this protocol
- at protocol KWQWidgetHolder
-- (QWidget *)widget;
- at end
+#endif
\ No newline at end of file
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 65bfacd..f98ea94 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,16 @@
+2004-04-20 Ken Kocienda <kocienda at apple.com>
+
+ Reviewed by Hyatt
+
+ Added implementations for these methods.
+
+ * WebView.subproj/WebView.m:
+ (-[WebView moveUpAndModifySelection:]):
+ (-[WebView moveWordLeft:]):
+ (-[WebView moveWordLeftAndModifySelection:]):
+ (-[WebView moveWordRight:]):
+ (-[WebView moveWordRightAndModifySelection:]):
+
2004-04-20 John Sullivan <sullivan at apple.com>
- fixed <rdar://problem/3622393>: When in stealth mode, visited webpage
diff --git a/WebKit/WebView.subproj/WebView.m b/WebKit/WebView.subproj/WebView.m
index 1722273..a333b0a 100644
--- a/WebKit/WebView.subproj/WebView.m
+++ b/WebKit/WebView.subproj/WebView.m
@@ -2399,7 +2399,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
- (void)moveUpAndModifySelection:(id)sender
{
if ([self _currentSelectionIsEditable]) {
- ERROR("unimplemented");
+ [self _alterCurrentSelection:WebSelectByExtending direction:WebSelectUp granularity:WebSelectByCharacter];
return;
}
[[self nextResponder] tryToPerform:@selector(moveUpAndModifySelection:) with:sender];
@@ -2444,7 +2444,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
- (void)moveWordLeft:(id)sender
{
if ([self _currentSelectionIsEditable]) {
- ERROR("unimplemented");
+ [self _alterCurrentSelection:WebSelectByMoving direction:WebSelectLeft granularity:WebSelectByWord];
return;
}
[[self nextResponder] tryToPerform:@selector(moveWordLeft:) with:sender];
@@ -2453,7 +2453,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
- (void)moveWordLeftAndModifySelection:(id)sender
{
if ([self _currentSelectionIsEditable]) {
- ERROR("unimplemented");
+ [self _alterCurrentSelection:WebSelectByExtending direction:WebSelectLeft granularity:WebSelectByWord];
return;
}
[[self nextResponder] tryToPerform:@selector(moveWordLeftAndModifySelection:) with:sender];
@@ -2462,7 +2462,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
- (void)moveWordRight:(id)sender
{
if ([self _currentSelectionIsEditable]) {
- ERROR("unimplemented");
+ [self _alterCurrentSelection:WebSelectByMoving direction:WebSelectRight granularity:WebSelectByWord];
return;
}
[[self nextResponder] tryToPerform:@selector(moveWordRight:) with:sender];
@@ -2471,7 +2471,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
- (void)moveWordRightAndModifySelection:(id)sender
{
if ([self _currentSelectionIsEditable]) {
- ERROR("unimplemented");
+ [self _alterCurrentSelection:WebSelectByExtending direction:WebSelectRight granularity:WebSelectByWord];
return;
}
[[self nextResponder] tryToPerform:@selector(moveWordRightAndModifySelection:) with:sender];
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list