Changeset 128903 in webkit
- Timestamp:
- Sep 18, 2012 10:23:37 AM (12 years ago)
- Location:
- trunk/Source/WebKit/chromium
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/chromium/ChangeLog
r128901 r128903 1 2012-09-18 Iain Merrick <husky@google.com> 2 3 [Chromium] Merge moveSelectionStart, moveSelectionEnd, and moveCaret into selectRange 4 https://bugs.webkit.org/show_bug.cgi?id=96508 5 6 Reviewed by Ryosuke Niwa. 7 8 These methods had "start" and "end" parameters, but this is incorrect. 9 selectRange() actually takes base and extent (where the user actually 10 touched), and selectionBounds() returns anchor and focus (base and extent 11 expanded to account for the selection granularity). 12 13 This patch fixes the parameter names, and updates selectRange, its test 14 and its documentation to reflect the correct usage. It also removes 15 moveSelectionStart/moveSelectionEnd/moveCaret (which aren't being used 16 yet), and updates WebFrameTest to show how these can be implemented via 17 selectRange. 18 19 * public/WebFrame.h: 20 (WebFrame): 21 * public/WebWidget.h: 22 (WebWidget): 23 (WebKit::WebWidget::selectionBounds): 24 * src/WebFrameImpl.cpp: 25 (WebKit::WebFrameImpl::selectRange): 26 * src/WebFrameImpl.h: 27 (WebFrameImpl): 28 * src/WebViewImpl.cpp: 29 (WebKit::WebViewImpl::selectionBounds): 30 * src/WebViewImpl.h: 31 (WebViewImpl): 32 * tests/WebFrameTest.cpp: 33 1 34 2012-09-18 Terry Anderson <tdanderson@chromium.org> 2 35 -
trunk/Source/WebKit/chromium/public/WebFrame.h
r127776 r128903 473 473 virtual bool selectWordAroundCaret() = 0; 474 474 475 // DEPRECATED: Use moveSelectionStart / moveSelectionEnd / moveCaret 476 // This method is intended for touch-based UIs, but it's missing some 477 // functionality needed on Android, like preventing collapsed selections. 478 virtual void selectRange(const WebPoint& start, const WebPoint& end) = 0; 475 // Select a range of text, as if by drag-selecting from base to extent 476 // with character granularity. 477 virtual void selectRange(const WebPoint& base, const WebPoint& extent) = 0; 479 478 480 479 virtual void selectRange(const WebRange&) = 0; 481 482 // The methods below are for adjusting the start and/or end of the current483 // selection by direct manipulation on a touch-based UI. To enter selection484 // mode in the first place, call selectRange() or send a fake mouse event.485 486 // Moves the start of the current selection, keeping the end fixed.487 // Returns true on success, false if there is no selection to modify.488 virtual bool moveSelectionStart(const WebPoint&, bool allowCollapsedSelection) = 0;489 490 // Moves the end of the current selection, keeping the start fixed.491 // Returns true on success, false if there is no selection to modify.492 virtual bool moveSelectionEnd(const WebPoint&, bool allowCollapsedSelection) = 0;493 494 // Move both endpoints of the current selection to the given position.495 // The caret will remain pinned inside the current editable region.496 // Returns true on success, false if there is no selection or if we're not editing.497 virtual bool moveCaret(const WebPoint&) = 0;498 480 499 481 // Printing ------------------------------------------------------------ -
trunk/Source/WebKit/chromium/public/WebWidget.h
r126940 r128903 195 195 virtual WebTextInputType textInputType() { return WebTextInputTypeNone; } 196 196 197 // Returns the start and endbounds of the current selection.197 // Returns the anchor and focus bounds of the current selection. 198 198 // If the selection range is empty, it returns the caret bounds. 199 virtual bool selectionBounds(WebRect& start, WebRect& end) const { return false; }199 virtual bool selectionBounds(WebRect& anchor, WebRect& focus) const { return false; } 200 200 201 201 // Returns the text direction at the start and end bounds of the current selection. -
trunk/Source/WebKit/chromium/src/WebFrameImpl.cpp
r128784 r128903 1467 1467 } 1468 1468 1469 void WebFrameImpl::selectRange(const WebPoint& start, const WebPoint& end) 1470 { 1471 if (start == end && moveCaret(start)) 1472 return; 1473 1474 if (moveSelectionStart(start, true) && moveSelectionEnd(end, true)) 1475 return; 1476 1477 // Failed to move endpoints, probably because there's no current selection. 1478 // Just set the selection explicitly (but this won't handle editable boundaries correctly). 1479 VisibleSelection newSelection(visiblePositionForWindowPoint(start), visiblePositionForWindowPoint(end)); 1469 void WebFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent) 1470 { 1471 VisiblePosition basePos = visiblePositionForWindowPoint(base); 1472 VisiblePosition extentPos = visiblePositionForWindowPoint(extent); 1473 VisibleSelection newSelection = VisibleSelection(basePos, extentPos); 1480 1474 if (frame()->selection()->shouldChangeSelection(newSelection)) 1481 1475 frame()->selection()->setSelection(newSelection, CharacterGranularity); 1482 }1483 1484 bool WebFrameImpl::moveSelectionStart(const WebPoint& point, bool allowCollapsedSelection)1485 {1486 const VisibleSelection& selection = frame()->selection()->selection();1487 if (selection.isNone())1488 return false;1489 1490 VisiblePosition start = visiblePositionForWindowPoint(point);1491 if (!allowCollapsedSelection) {1492 VisiblePosition maxStart = selection.visibleEnd().previous();1493 if (comparePositions(start, maxStart) > 0)1494 start = maxStart;1495 }1496 1497 // start is moving, so base=end, extent=start1498 VisibleSelection newSelection = VisibleSelection(selection.visibleEnd(), start);1499 frame()->selection()->setNonDirectionalSelectionIfNeeded(newSelection, CharacterGranularity);1500 return true;1501 }1502 1503 bool WebFrameImpl::moveSelectionEnd(const WebPoint& point, bool allowCollapsedSelection)1504 {1505 const VisibleSelection& selection = frame()->selection()->selection();1506 if (selection.isNone())1507 return false;1508 1509 VisiblePosition end = visiblePositionForWindowPoint(point);1510 if (!allowCollapsedSelection) {1511 VisiblePosition minEnd = selection.visibleStart().next();1512 if (comparePositions(end, minEnd) < 0)1513 end = minEnd;1514 }1515 1516 // end is moving, so base=start, extent=end1517 VisibleSelection newSelection = VisibleSelection(selection.visibleStart(), end);1518 frame()->selection()->setNonDirectionalSelectionIfNeeded(newSelection, CharacterGranularity);1519 return true;1520 }1521 1522 bool WebFrameImpl::moveCaret(const WebPoint& point)1523 {1524 FrameSelection* frameSelection = frame()->selection();1525 if (frameSelection->isNone() || !frameSelection->isContentEditable())1526 return false;1527 1528 VisiblePosition pos = visiblePositionForWindowPoint(point);1529 frameSelection->setExtent(pos, UserTriggered);1530 frameSelection->setBase(frameSelection->extent(), UserTriggered);1531 return true;1532 1476 } 1533 1477 -
trunk/Source/WebKit/chromium/src/WebFrameImpl.h
r128784 r128903 185 185 virtual WebString selectionAsMarkup() const; 186 186 virtual bool selectWordAroundCaret(); 187 virtual void selectRange(const WebPoint& start, const WebPoint& end);187 virtual void selectRange(const WebPoint& base, const WebPoint& extent); 188 188 virtual void selectRange(const WebRange&); 189 virtual bool moveSelectionStart(const WebPoint&, bool allowCollapsedSelection);190 virtual bool moveSelectionEnd(const WebPoint&, bool allowCollapsedSelection);191 virtual bool moveCaret(const WebPoint&);192 189 virtual int printBegin(const WebPrintParams&, 193 190 const WebNode& constrainToNode, -
trunk/Source/WebKit/chromium/src/WebViewImpl.cpp
r128794 r128903 2224 2224 } 2225 2225 2226 bool WebViewImpl::selectionBounds(WebRect& start, WebRect& end) const2226 bool WebViewImpl::selectionBounds(WebRect& anchor, WebRect& focus) const 2227 2227 { 2228 2228 const Frame* frame = focusedWebCoreFrame(); … … 2234 2234 2235 2235 if (selection->isCaret()) { 2236 start = end= frame->view()->contentsToWindow(selection->absoluteCaretBounds());2236 anchor = focus = frame->view()->contentsToWindow(selection->absoluteCaretBounds()); 2237 2237 return true; 2238 2238 } … … 2247 2247 selectedRange->startContainer(), 2248 2248 selectedRange->startOffset())); 2249 start= frame->editor()->firstRectForRange(range.get());2249 anchor = frame->editor()->firstRectForRange(range.get()); 2250 2250 2251 2251 range = Range::create(selectedRange->endContainer()->document(), … … 2254 2254 selectedRange->endContainer(), 2255 2255 selectedRange->endOffset()); 2256 end= frame->editor()->firstRectForRange(range.get());2257 2258 start = frame->view()->contentsToWindow(start);2259 end = frame->view()->contentsToWindow(end);2256 focus = frame->editor()->firstRectForRange(range.get()); 2257 2258 anchor = frame->view()->contentsToWindow(anchor); 2259 focus = frame->view()->contentsToWindow(focus); 2260 2260 2261 2261 if (!frame->selection()->selection().isBaseFirst()) 2262 std::swap( start, end);2262 std::swap(anchor, focus); 2263 2263 return true; 2264 2264 } -
trunk/Source/WebKit/chromium/src/WebViewImpl.h
r128133 r128903 168 168 virtual bool isSelectionEditable() const; 169 169 virtual WebColor backgroundColor() const; 170 virtual bool selectionBounds(WebRect& start, WebRect& end) const;170 virtual bool selectionBounds(WebRect& anchor, WebRect& focus) const; 171 171 virtual bool selectionTextDirection(WebTextDirection& start, WebTextDirection& end) const; 172 172 virtual bool caretOrSelectionRange(size_t* location, size_t* length); -
trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp
r128058 r128903 1073 1073 EXPECT_EQ("This text is initially selected.", selectionAsString(frame)); 1074 1074 webView->selectionBounds(startWebRect, endWebRect); 1075 frame->selectRange( WebPoint(0, 0), bottomRightMinusOne(endWebRect));1075 frame->selectRange(bottomRightMinusOne(endWebRect), WebPoint(0, 0)); 1076 1076 EXPECT_EQ("16-char header. This text is initially selected.", selectionAsString(frame)); 1077 1077 webView->close(); … … 1087 1087 } 1088 1088 1089 TEST_F(WebFrameTest, MoveSelectionStart)1089 TEST_F(WebFrameTest, SelectRangeCanMoveSelectionStart) 1090 1090 { 1091 1091 registerMockedHttpURLLoad("text_selection.html"); … … 1093 1093 WebFrame* frame = webView->mainFrame(); 1094 1094 1095 // moveSelectionStart() always returns false if there's no selection.1096 EXPECT_FALSE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), false));1097 EXPECT_FALSE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), true));1098 1099 frame->executeScript(WebScriptSource("selectElement('header_1');"));1100 EXPECT_EQ("Header 1.", selectionAsString(frame));1101 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "header_2")), false));1102 EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame));1103 1104 1095 // Select second span. We can move the start to include the first span. 1105 1096 frame->executeScript(WebScriptSource("selectElement('header_2');")); 1106 1097 EXPECT_EQ("Header 2.", selectionAsString(frame)); 1107 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), false));1098 frame->selectRange(bottomRightMinusOne(elementBounds(frame, "header_2")), topLeft(elementBounds(frame, "header_1"))); 1108 1099 EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame)); 1109 1100 1110 // If allowCollapsedSelection=false we can't move the selection start beyond the current end. 1111 // We end up with a single character selected. 1101 // We can move the start and end together. 1112 1102 frame->executeScript(WebScriptSource("selectElement('header_1');")); 1113 1103 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1114 EXPECT_TRUE(frame->moveSelectionStart(bottomRightMinusOne(elementBounds(frame, "header_1")), false)); 1115 EXPECT_EQ(".", selectionAsString(frame)); 1116 1117 // If allowCollapsedSelection=true we can move the start and end together. 1118 frame->executeScript(WebScriptSource("selectElement('header_1');")); 1119 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1120 EXPECT_TRUE(frame->moveSelectionStart(bottomRightMinusOne(elementBounds(frame, "header_1")), true)); 1104 frame->selectRange(bottomRightMinusOne(elementBounds(frame, "header_1")), bottomRightMinusOne(elementBounds(frame, "header_1"))); 1121 1105 EXPECT_EQ("", selectionAsString(frame)); 1122 1106 // Selection is a caret, not empty. 1123 1107 EXPECT_FALSE(frame->selectionRange().isNull()); 1124 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), true)); 1125 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1126 1127 // If allowCollapsedSelection=true we can move the start across the end. 1108 1109 // We can move the start across the end. 1128 1110 frame->executeScript(WebScriptSource("selectElement('header_1');")); 1129 1111 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1130 EXPECT_TRUE(frame->moveSelectionStart(bottomRightMinusOne(elementBounds(frame, "header_2")), true));1112 frame->selectRange(bottomRightMinusOne(elementBounds(frame, "header_1")), bottomRightMinusOne(elementBounds(frame, "header_2"))); 1131 1113 EXPECT_EQ(" Header 2.", selectionAsString(frame)); 1132 1114 … … 1134 1116 frame->executeScript(WebScriptSource("selectElement('footer_2');")); 1135 1117 EXPECT_EQ("Footer 2.", selectionAsString(frame)); 1136 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "editable_2")), true));1118 frame->selectRange(bottomRightMinusOne(elementBounds(frame, "footer_2")), topLeft(elementBounds(frame, "editable_2"))); 1137 1119 EXPECT_EQ(" [ Footer 1. Footer 2.", selectionAsString(frame)); 1138 1120 … … 1140 1122 frame->executeScript(WebScriptSource("selectElement('footer_2');")); 1141 1123 EXPECT_EQ("Footer 2.", selectionAsString(frame)); 1142 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_2")), true));1124 frame->selectRange(bottomRightMinusOne(elementBounds(frame, "footer_2")), topLeft(elementBounds(frame, "header_2"))); 1143 1125 EXPECT_EQ("Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1. Footer 2.", selectionAsString(frame)); 1144 1126 … … 1146 1128 frame->executeScript(WebScriptSource("selectElement('editable_2');")); 1147 1129 EXPECT_EQ("Editable 2.", selectionAsString(frame)); 1148 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_2")), true));1130 frame->selectRange(bottomRightMinusOne(elementBounds(frame, "editable_2")), topLeft(elementBounds(frame, "header_2"))); 1149 1131 EXPECT_EQ("[ Editable 1. Editable 2.", selectionAsString(frame)); 1150 1132 … … 1152 1134 } 1153 1135 1154 TEST_F(WebFrameTest, MoveSelectionEnd)1136 TEST_F(WebFrameTest, SelectRangeCanMoveSelectionEnd) 1155 1137 { 1156 1138 registerMockedHttpURLLoad("text_selection.html"); … … 1158 1140 WebFrame* frame = webView->mainFrame(); 1159 1141 1160 // moveSelectionEnd() always returns false if there's no selection.1161 EXPECT_FALSE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_1")), false));1162 EXPECT_FALSE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_1")), true));1163 1164 1142 // Select first span. We can move the end to include the second span. 1165 1143 frame->executeScript(WebScriptSource("selectElement('header_1');")); 1166 1144 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1167 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "header_2")), false));1145 frame->selectRange(topLeft(elementBounds(frame, "header_1")), bottomRightMinusOne(elementBounds(frame, "header_2"))); 1168 1146 EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame)); 1169 1147 1170 // If allowCollapsedSelection=false we can't move the selection end beyond the current start. 1171 // We end up with a single character selected. 1148 // We can move the start and end together. 1172 1149 frame->executeScript(WebScriptSource("selectElement('header_2');")); 1173 1150 EXPECT_EQ("Header 2.", selectionAsString(frame)); 1174 EXPECT_TRUE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_2")), false)); 1175 EXPECT_EQ("H", selectionAsString(frame)); 1176 1177 // If allowCollapsedSelection=true we can move the start and end together. 1178 frame->executeScript(WebScriptSource("selectElement('header_2');")); 1179 EXPECT_EQ("Header 2.", selectionAsString(frame)); 1180 EXPECT_TRUE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_2")), true)); 1151 frame->selectRange(topLeft(elementBounds(frame, "header_2")), topLeft(elementBounds(frame, "header_2"))); 1181 1152 EXPECT_EQ("", selectionAsString(frame)); 1182 1153 // Selection is a caret, not empty. 1183 1154 EXPECT_FALSE(frame->selectionRange().isNull()); 1184 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "header_2")), true)); 1185 EXPECT_EQ("Header 2.", selectionAsString(frame)); 1186 1187 // If allowCollapsedSelection=true we can move the end across the start. 1155 1156 // We can move the end across the start. 1188 1157 frame->executeScript(WebScriptSource("selectElement('header_2');")); 1189 1158 EXPECT_EQ("Header 2.", selectionAsString(frame)); 1190 EXPECT_TRUE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_1")), true));1159 frame->selectRange(topLeft(elementBounds(frame, "header_2")), topLeft(elementBounds(frame, "header_1"))); 1191 1160 EXPECT_EQ("Header 1. ", selectionAsString(frame)); 1192 1161 … … 1194 1163 frame->executeScript(WebScriptSource("selectElement('header_1');")); 1195 1164 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1196 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "editable_1")), true));1165 frame->selectRange(topLeft(elementBounds(frame, "header_1")), bottomRightMinusOne(elementBounds(frame, "editable_1"))); 1197 1166 EXPECT_EQ("Header 1. Header 2. ] ", selectionAsString(frame)); 1198 1167 … … 1200 1169 frame->executeScript(WebScriptSource("selectElement('header_1');")); 1201 1170 EXPECT_EQ("Header 1.", selectionAsString(frame)); 1202 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "footer_1")), true));1171 frame->selectRange(topLeft(elementBounds(frame, "header_1")), bottomRightMinusOne(elementBounds(frame, "footer_1"))); 1203 1172 EXPECT_EQ("Header 1. Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1.", selectionAsString(frame)); 1204 1173 … … 1206 1175 frame->executeScript(WebScriptSource("selectElement('editable_1');")); 1207 1176 EXPECT_EQ("Editable 1.", selectionAsString(frame)); 1208 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "footer_1")), true));1177 frame->selectRange(topLeft(elementBounds(frame, "editable_1")), bottomRightMinusOne(elementBounds(frame, "footer_1"))); 1209 1178 EXPECT_EQ("Editable 1. Editable 2. ]", selectionAsString(frame)); 1210 1211 webView->close();1212 }1213 1214 TEST_F(WebFrameTest, MoveCaret)1215 {1216 registerMockedHttpURLLoad("text_selection.html");1217 WebView* webView = createWebViewForTextSelection(m_baseURL + "text_selection.html");1218 WebFrame* frame = webView->mainFrame();1219 1220 // moveCaret() returns false if there's no selection, or if it isn't editable.1221 EXPECT_FALSE(frame->moveCaret(topLeft(elementBounds(frame, "editable"))));1222 frame->executeScript(WebScriptSource("selectElement('header_1');"));1223 EXPECT_EQ("Header 1.", selectionAsString(frame));1224 EXPECT_FALSE(frame->moveCaret(topLeft(elementBounds(frame, "editable"))));1225 1226 // Select the editable text span. Now moveCaret() works.1227 frame->executeScript(WebScriptSource("selectElement('editable_1');"));1228 EXPECT_EQ("Editable 1.", selectionAsString(frame));1229 1230 EXPECT_TRUE(frame->moveCaret(topLeft(elementBounds(frame, "editable_1"))));1231 EXPECT_EQ("", selectionAsString(frame));1232 EXPECT_FALSE(frame->selectionRange().isNull());1233 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "editable_1")), false));1234 EXPECT_EQ("Editable 1.", selectionAsString(frame));1235 1236 EXPECT_TRUE(frame->moveCaret(bottomRightMinusOne(elementBounds(frame, "editable_2"))));1237 EXPECT_EQ("", selectionAsString(frame));1238 EXPECT_FALSE(frame->selectionRange().isNull());1239 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "editable_2")), false));1240 EXPECT_EQ("Editable 2.", selectionAsString(frame));1241 1242 // Caret is pinned at the start of the editable region.1243 EXPECT_TRUE(frame->moveCaret(topLeft(elementBounds(frame, "header_1"))));1244 EXPECT_EQ("", selectionAsString(frame));1245 EXPECT_FALSE(frame->selectionRange().isNull());1246 EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "editable_1")), false));1247 EXPECT_EQ("[ Editable 1.", selectionAsString(frame));1248 1249 // Caret is pinned at the end of the editable region.1250 EXPECT_TRUE(frame->moveCaret(bottomRightMinusOne(elementBounds(frame, "footer_2"))));1251 EXPECT_EQ("", selectionAsString(frame));1252 EXPECT_FALSE(frame->selectionRange().isNull());1253 EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "editable_2")), false));1254 EXPECT_EQ("Editable 2. ]", selectionAsString(frame));1255 1179 1256 1180 webView->close();
Note: See TracChangeset
for help on using the changeset viewer.