Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Side by Side Diff: third_party/WebKit/Source/core/editing/SelectionController.cpp

Issue 1845193002: Fix long-press image selection inside editables. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disable Mac-only failure (Mac doesn't support long-press anyway) Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * Copyright (C) 2015 Google Inc. All rights reserved. 5 * Copyright (C) 2015 Google Inc. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } else { 280 } else {
281 granularity = CharacterGranularity; 281 granularity = CharacterGranularity;
282 m_selectionState = SelectionState::PlacedCaret; 282 m_selectionState = SelectionState::PlacedCaret;
283 } 283 }
284 284
285 this->selection().setNonDirectionalSelectionIfNeeded(selection, granularity) ; 285 this->selection().setNonDirectionalSelectionIfNeeded(selection, granularity) ;
286 286
287 return true; 287 return true;
288 } 288 }
289 289
290 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult & result, AppendTrailingWhitespace appendTrailingWhitespace) 290 void SelectionController::selectClosestWordFromHitTestResult(const HitTestResult & result, AppendTrailingWhitespace appendTrailingWhitespace, SelectInputEventTyp e selectInputEventType)
291 { 291 {
292 Node* innerNode = result.innerNode(); 292 Node* innerNode = result.innerNode();
293 VisibleSelectionInFlatTree newSelection; 293 VisibleSelectionInFlatTree newSelection;
294 294
295 if (!innerNode || !innerNode->layoutObject()) 295 if (!innerNode || !innerNode->layoutObject())
296 return; 296 return;
297 297
298 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(result ); 298 // Special-case image local offset to always be zero, to avoid triggering
299 // LayoutReplaced::positionFromPoint's advancement of the position at the
300 // mid-point of the the image (which was intended for mouse-drag selection
301 // and isn't desirable for long-press).
302 HitTestResult adjustedHitTestResult = result;
303 if (selectInputEventType == SelectInputEventType::GestureLongPress && result .image())
304 adjustedHitTestResult.setNodeAndPosition(result.innerNode(), LayoutPoint (0, 0));
305
306 const VisiblePositionInFlatTree& pos = visiblePositionOfHitTestResult(adjust edHitTestResult);
299 if (pos.isNotNull()) { 307 if (pos.isNotNull()) {
300 newSelection = VisibleSelectionInFlatTree(pos); 308 newSelection = VisibleSelectionInFlatTree(pos);
301 newSelection.expandUsingGranularity(WordGranularity); 309 newSelection.expandUsingGranularity(WordGranularity);
302 } 310 }
303 311
304 #if OS(ANDROID) 312 if (selectInputEventType == SelectInputEventType::GestureLongPress) {
305 // If node doesn't have text except space, tab or line break, do not 313 // If node doesn't have text except space, tab or line break, do not
306 // select that 'empty' area. 314 // select that 'empty' area.
307 EphemeralRangeInFlatTree range = EphemeralRangeInFlatTree(newSelection.start (), newSelection.end()); 315 EphemeralRangeInFlatTree range(newSelection.start(), newSelection.end()) ;
308 const String& str = plainText(range, TextIteratorDefaultBehavior); 316 const String& str = plainText(range, TextIteratorEmitsObjectReplacementC haracter);
309 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace()) 317 if (str.isEmpty() || str.simplifyWhiteSpace().containsOnlyWhitespace())
310 return; 318 return;
311 #endif 319 }
312 320
313 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne wSelection.isRange()) 321 if (appendTrailingWhitespace == AppendTrailingWhitespace::ShouldAppend && ne wSelection.isRange())
314 newSelection.appendTrailingWhitespace(); 322 newSelection.appendTrailingWhitespace();
315 323
316 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); 324 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
317 } 325 }
318 326
319 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes tResult& result, AppendTrailingWhitespace appendTrailingWhitespace) 327 void SelectionController::selectClosestMisspellingFromHitTestResult(const HitTes tResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
320 { 328 {
321 Node* innerNode = result.innerNode(); 329 Node* innerNode = result.innerNode();
(...skipping 20 matching lines...) Expand all
342 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity); 350 updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelection ToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
343 } 351 }
344 352
345 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi tTestResults& result) 353 void SelectionController::selectClosestWordFromMouseEvent(const MouseEventWithHi tTestResults& result)
346 { 354 {
347 if (!m_mouseDownMayStartSelect) 355 if (!m_mouseDownMayStartSelect)
348 return; 356 return;
349 357
350 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend; 358 AppendTrailingWhitespace appendTrailingWhitespace = (result.event().clickCou nt() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? AppendTrai lingWhitespace::ShouldAppend : AppendTrailingWhitespace::DontAppend;
351 359
352 return selectClosestWordFromHitTestResult(result.hitTestResult(), appendTrai lingWhitespace); 360 return selectClosestWordFromHitTestResult(result.hitTestResult(), appendTrai lingWhitespace, SelectInputEventType::Mouse);
353 } 361 }
354 362
355 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven tWithHitTestResults& result) 363 void SelectionController::selectClosestMisspellingFromMouseEvent(const MouseEven tWithHitTestResults& result)
356 { 364 {
357 if (!m_mouseDownMayStartSelect) 365 if (!m_mouseDownMayStartSelect)
358 return; 366 return;
359 367
360 selectClosestMisspellingFromHitTestResult(result.hitTestResult(), 368 selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
361 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi tespace::DontAppend); 369 (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingW hitespaceEnabled()) ? AppendTrailingWhitespace::ShouldAppend : AppendTrailingWhi tespace::DontAppend);
362 370
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 541
534 return false; 542 return false;
535 } 543 }
536 544
537 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges tureEvent, const HitTestResult& hitTestResult) 545 bool SelectionController::handleGestureLongPress(const PlatformGestureEvent& ges tureEvent, const HitTestResult& hitTestResult)
538 { 546 {
539 if (hitTestResult.isLiveLink()) 547 if (hitTestResult.isLiveLink())
540 return false; 548 return false;
541 549
542 Node* innerNode = hitTestResult.innerNode(); 550 Node* innerNode = hitTestResult.innerNode();
543 #if OS(ANDROID)
544 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() || innerNode->isTextNode() || innerNode->canStartSelection()); 551 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() || innerNode->isTextNode() || innerNode->canStartSelection());
545 #else
546 bool innerNodeIsSelectable = innerNode && (innerNode->isContentEditable() || innerNode->isTextNode());
547 #endif
548 if (!innerNodeIsSelectable) 552 if (!innerNodeIsSelectable)
549 return false; 553 return false;
550 554
551 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace:: DontAppend); 555 selectClosestWordFromHitTestResult(hitTestResult, AppendTrailingWhitespace:: DontAppend, SelectInputEventType::GestureLongPress);
552 return selection().isRange(); 556 return selection().isRange();
553 } 557 }
554 558
555 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult s& mev, const LayoutPoint& position) 559 void SelectionController::sendContextMenuEvent(const MouseEventWithHitTestResult s& mev, const LayoutPoint& position)
556 { 560 {
557 if (selection().contains(position) 561 if (selection().contains(position)
558 || mev.scrollbar() 562 || mev.scrollbar()
559 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse. 563 // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
560 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items 564 // If the selection is non-editable, we do word selection to make it eas ier to use the contextual menu items
561 // available for text selections. But only if we're above text. 565 // available for text selections. But only if we're above text.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 else 621 else
618 m_selectionState = SelectionState::HaveNotStartedSelection; 622 m_selectionState = SelectionState::HaveNotStartedSelection;
619 } 623 }
620 624
621 FrameSelection& SelectionController::selection() const 625 FrameSelection& SelectionController::selection() const
622 { 626 {
623 return m_frame->selection(); 627 return m_frame->selection();
624 } 628 }
625 629
626 } // namespace blink 630 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/SelectionController.h ('k') | third_party/WebKit/Source/web/tests/WebViewTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698