OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.contextualsearch; | 5 package org.chromium.chrome.browser.contextualsearch; |
6 | 6 |
7 import android.os.Handler; | |
8 import android.text.TextUtils; | 7 import android.text.TextUtils; |
9 | 8 |
10 import org.chromium.base.VisibleForTesting; | 9 import org.chromium.base.VisibleForTesting; |
11 import org.chromium.chrome.browser.ChromeActivity; | 10 import org.chromium.chrome.browser.ChromeActivity; |
12 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; | 11 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; |
13 import org.chromium.chrome.browser.contextualsearch.ContextualSearchBlacklist.Bl acklistReason; | 12 import org.chromium.chrome.browser.contextualsearch.ContextualSearchBlacklist.Bl acklistReason; |
14 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; | 13 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; |
15 import org.chromium.chrome.browser.tab.Tab; | 14 import org.chromium.chrome.browser.tab.Tab; |
16 import org.chromium.content.browser.ContentViewCore; | 15 import org.chromium.content.browser.ContentViewCore; |
17 import org.chromium.content_public.browser.GestureStateListener; | 16 import org.chromium.content_public.browser.GestureStateListener; |
(...skipping 10 matching lines...) Expand all Loading... | |
28 | 27 |
29 /** | 28 /** |
30 * The type of selection made by the user. | 29 * The type of selection made by the user. |
31 */ | 30 */ |
32 public enum SelectionType { | 31 public enum SelectionType { |
33 UNDETERMINED, | 32 UNDETERMINED, |
34 TAP, | 33 TAP, |
35 LONG_PRESS | 34 LONG_PRESS |
36 } | 35 } |
37 | 36 |
38 // The number of milliseconds to wait for a selection change after a tap bef ore considering | |
39 // the tap invalid. This can't be too small or the subsequent taps may not have established | |
40 // a new selection in time. This is because selectWordAroundCaret doesn't a lways select. | |
41 // TODO(donnd): Fix in Blink, crbug.com/435778. | |
42 private static final int INVALID_IF_NO_SELECTION_CHANGE_AFTER_TAP_MS = 50; | |
43 | |
44 // The default navigation-detection-delay in milliseconds. | |
45 private static final int TAP_NAVIGATION_DETECTION_DELAY = 16; | |
46 | |
47 private static final String CONTAINS_WORD_PATTERN = "(\\w|\\p{L}|\\p{N})+"; | 37 private static final String CONTAINS_WORD_PATTERN = "(\\w|\\p{L}|\\p{N})+"; |
48 // A URL is: | 38 // A URL is: |
49 // 1: scheme:// | 39 // 1: scheme:// |
50 // 1+: any word char, _ or - | 40 // 1+: any word char, _ or - |
51 // 1+: . followed by 1+ of any word char, _ or - | 41 // 1+: . followed by 1+ of any word char, _ or - |
52 // 0-1: 0+ of any word char or .,@?^=%&:/~#- followed by any word char or @?^-%&/~+#- | 42 // 0-1: 0+ of any word char or .,@?^=%&:/~#- followed by any word char or @?^-%&/~+#- |
53 // TODO(twellington): expand accepted schemes? | 43 // TODO(twellington): expand accepted schemes? |
54 private static final Pattern URL_PATTERN = Pattern.compile("((http|https|fil e|ftp|ssh)://)" | 44 private static final Pattern URL_PATTERN = Pattern.compile("((http|https|fil e|ftp|ssh)://)" |
55 + "([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+# -])?"); | 45 + "([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+# -])?"); |
56 | 46 |
57 // Max selection length must be limited or the entire request URL can go pas t the 2K limit. | 47 // Max selection length must be limited or the entire request URL can go pas t the 2K limit. |
58 private static final int MAX_SELECTION_LENGTH = 100; | 48 private static final int MAX_SELECTION_LENGTH = 100; |
59 | 49 |
60 private final ChromeActivity mActivity; | 50 private final ChromeActivity mActivity; |
61 private final ContextualSearchSelectionHandler mHandler; | 51 private final ContextualSearchSelectionHandler mHandler; |
62 private final Runnable mHandleInvalidTapRunnable; | |
63 private final Handler mRunnableHandler; | |
64 private final float mPxToDp; | 52 private final float mPxToDp; |
65 private final Pattern mContainsWordPattern; | 53 private final Pattern mContainsWordPattern; |
66 | 54 |
67 private String mSelectedText; | 55 private String mSelectedText; |
68 private SelectionType mSelectionType; | 56 private SelectionType mSelectionType; |
69 private boolean mWasTapGestureDetected; | 57 private boolean mWasTapGestureDetected; |
70 // Reflects whether the last tap was valid and whether we still have a tap-b ased selection. | 58 // Reflects whether the last tap was valid and whether we still have a tap-b ased selection. |
71 private ContextualSearchTapState mLastTapState; | 59 private ContextualSearchTapState mLastTapState; |
72 private TapSuppressionHeuristics mTapHeuristics; | |
73 private boolean mIsWaitingForInvalidTapDetection; | 60 private boolean mIsWaitingForInvalidTapDetection; |
74 private boolean mShouldHandleSelectionModification; | 61 private boolean mShouldHandleSelectionModification; |
75 private boolean mDidExpandSelection; | 62 private boolean mDidExpandSelection; |
76 | 63 |
77 // Position of the selection. | 64 // Position of the selection. |
78 private float mX; | 65 private float mX; |
79 private float mY; | 66 private float mY; |
80 | 67 |
81 // The time of the most last scroll activity, or 0 if none. | 68 // The time of the most last scroll activity, or 0 if none. |
82 private long mLastScrollTimeNs; | 69 private long mLastScrollTimeNs; |
83 | 70 |
71 // When the last tap gesture happened. | |
72 private long mTapTimeNanoseconds; | |
73 | |
84 // Tracks whether a Context Menu has just been shown and the UX has been dis missed. | 74 // Tracks whether a Context Menu has just been shown and the UX has been dis missed. |
85 // The selection may be unreliable until the next reset. See crbug.com/6284 36. | 75 // The selection may be unreliable until the next reset. See crbug.com/6284 36. |
86 private boolean mIsContextMenuShown; | 76 private boolean mIsContextMenuShown; |
87 | 77 |
88 private class ContextualSearchGestureStateListener extends GestureStateListe ner { | 78 private class ContextualSearchGestureStateListener extends GestureStateListe ner { |
89 @Override | 79 @Override |
90 public void onScrollStarted(int scrollOffsetY, int scrollExtentY) { | 80 public void onScrollStarted(int scrollOffsetY, int scrollExtentY) { |
91 mHandler.handleScroll(); | 81 mHandler.handleScroll(); |
92 } | 82 } |
93 | 83 |
94 @Override | 84 @Override |
95 public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { | 85 public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { |
96 mLastScrollTimeNs = System.nanoTime(); | 86 mLastScrollTimeNs = System.nanoTime(); |
97 } | 87 } |
98 | 88 |
99 @Override | 89 @Override |
100 public void onScrollUpdateGestureConsumed() { | 90 public void onScrollUpdateGestureConsumed() { |
101 // The onScrollEnded notification is unreliable, so mark time during scroll updates too. | 91 // The onScrollEnded notification is unreliable, so mark time during scroll updates too. |
102 // See crbug.com/600863. | 92 // See crbug.com/600863. |
103 mLastScrollTimeNs = System.nanoTime(); | 93 mLastScrollTimeNs = System.nanoTime(); |
104 } | 94 } |
105 | 95 |
106 // TODO(donnd): Remove this once we get notification of the selection ch anging | 96 // TODO(donnd): Remove this once we get notification of the selection ch anging |
107 // after a tap-select gets a subsequent tap nearby. Currently there's n o | 97 // after a tap-select gets a subsequent tap nearby. Currently there's n o |
108 // notification in this case. | 98 // notification in this case. |
109 // See crbug.com/444114. | 99 // See crbug.com/444114. |
110 @Override | 100 @Override |
111 public void onSingleTap(boolean consumed) { | 101 public void onSingleTap(boolean consumed) { |
112 // We may be notified that a tap has happened even when the system c onsumed the event. | 102 // TODO(donnd): remove completely! |
113 // This is being used to support tapping on an existing selection to show the selection | |
114 // handles. We should process this tap unless we have already shown the selection | |
115 // handles (have a long-press selection) and the tap was consumed. | |
116 if (!(consumed && mSelectionType == SelectionType.LONG_PRESS)) { | |
117 scheduleInvalidTapNotification(); | |
118 } | |
119 } | 103 } |
120 } | 104 } |
121 | 105 |
122 /** | 106 /** |
123 * Constructs a new Selection controller for the given activity. Callbacks will be issued | 107 * Constructs a new Selection controller for the given activity. Callbacks will be issued |
124 * through the given selection handler. | 108 * through the given selection handler. |
125 * @param activity The {@link ChromeActivity} to control. | 109 * @param activity The {@link ChromeActivity} to control. |
126 * @param handler The handler for callbacks. | 110 * @param handler The handler for callbacks. |
127 */ | 111 */ |
128 public ContextualSearchSelectionController(ChromeActivity activity, | 112 public ContextualSearchSelectionController(ChromeActivity activity, |
129 ContextualSearchSelectionHandler handler) { | 113 ContextualSearchSelectionHandler handler) { |
130 mActivity = activity; | 114 mActivity = activity; |
131 mHandler = handler; | 115 mHandler = handler; |
132 mPxToDp = 1.f / mActivity.getResources().getDisplayMetrics().density; | 116 mPxToDp = 1.f / mActivity.getResources().getDisplayMetrics().density; |
133 | |
134 mRunnableHandler = new Handler(); | |
135 mHandleInvalidTapRunnable = new Runnable() { | |
136 @Override | |
137 public void run() { | |
138 onInvalidTapDetectionTimeout(); | |
139 } | |
140 }; | |
141 | |
142 mContainsWordPattern = Pattern.compile(CONTAINS_WORD_PATTERN); | 117 mContainsWordPattern = Pattern.compile(CONTAINS_WORD_PATTERN); |
143 } | 118 } |
144 | 119 |
145 /** | 120 /** |
146 * Notifies that the base page has started loading a page. | 121 * Notifies that the base page has started loading a page. |
147 */ | 122 */ |
148 void onBasePageLoadStarted() { | 123 void onBasePageLoadStarted() { |
149 resetAllStates(); | 124 resetAllStates(); |
150 } | 125 } |
151 | 126 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 * @param selection The selection portion of the context. | 214 * @param selection The selection portion of the context. |
240 */ | 215 */ |
241 void handleSelectionChanged(String selection) { | 216 void handleSelectionChanged(String selection) { |
242 if (mDidExpandSelection) { | 217 if (mDidExpandSelection) { |
243 mSelectedText = selection; | 218 mSelectedText = selection; |
244 mDidExpandSelection = false; | 219 mDidExpandSelection = false; |
245 return; | 220 return; |
246 } | 221 } |
247 | 222 |
248 if (selection == null || selection.isEmpty()) { | 223 if (selection == null || selection.isEmpty()) { |
249 scheduleInvalidTapNotification(); | 224 mHandler.handleSelectionCleared(); |
250 // When the user taps on the page it will place the caret in that po sition, which | 225 // When the user taps on the page it will place the caret in that po sition, which |
251 // will trigger a onSelectionChanged event with an empty string. | 226 // will trigger a onSelectionChanged event with an empty string. |
252 if (mSelectionType == SelectionType.TAP) { | 227 if (mSelectionType == SelectionType.TAP) { |
253 // Since we mostly ignore a selection that's empty, we only need to partially reset. | 228 // Since we mostly ignore a selection that's empty, we only need to partially reset. |
254 resetSelectionStates(); | 229 resetSelectionStates(); |
255 return; | 230 return; |
256 } | 231 } |
257 } | 232 } |
258 if (!selection.isEmpty()) { | |
259 unscheduleInvalidTapNotification(); | |
260 } | |
261 | 233 |
262 mSelectedText = selection; | 234 mSelectedText = selection; |
263 | 235 |
264 if (mWasTapGestureDetected) { | 236 if (mWasTapGestureDetected) { |
265 mSelectionType = SelectionType.TAP; | 237 assert mSelectionType == SelectionType.TAP; |
266 handleSelection(selection, mSelectionType); | 238 handleSelection(selection, mSelectionType); |
267 mWasTapGestureDetected = false; | 239 mWasTapGestureDetected = false; |
268 } else { | 240 } else { |
269 boolean isValidSelection = validateSelectionSuppression(selection); | 241 boolean isValidSelection = validateSelectionSuppression(selection); |
270 mHandler.handleSelectionModification(selection, isValidSelection, mX , mY); | 242 mHandler.handleSelectionModification(selection, isValidSelection, mX , mY); |
271 } | 243 } |
272 } | 244 } |
273 | 245 |
274 /** | 246 /** |
275 * Handles a notification that a selection event took place. | 247 * Handles a notification that a selection event took place. |
276 * @param eventType The type of event that took place. | 248 * @param eventType The type of event that took place. |
277 * @param posXPix The x coordinate of the selection start handle. | 249 * @param posXPix The x coordinate of the selection start handle. |
278 * @param posYPix The y coordinate of the selection start handle. | 250 * @param posYPix The y coordinate of the selection start handle. |
279 */ | 251 */ |
280 void handleSelectionEvent(int eventType, float posXPix, float posYPix) { | 252 void handleSelectionEvent(int eventType, float posXPix, float posYPix) { |
281 boolean shouldHandleSelection = false; | 253 boolean shouldHandleSelection = false; |
282 switch (eventType) { | 254 switch (eventType) { |
283 case SelectionEventType.SELECTION_HANDLES_SHOWN: | 255 case SelectionEventType.SELECTION_HANDLES_SHOWN: |
284 if (!mIsContextMenuShown) { | 256 if (!mIsContextMenuShown) { |
285 mWasTapGestureDetected = false; | 257 mWasTapGestureDetected = false; |
286 mSelectionType = SelectionType.LONG_PRESS; | 258 mSelectionType = SelectionType.LONG_PRESS; |
287 shouldHandleSelection = true; | 259 shouldHandleSelection = true; |
288 // Since we're showing pins, we don't care if the previous t ap was invalid | 260 // Since we're showing pins, we don't care if the previous t ap was invalid |
289 // anymore. | 261 // anymore. |
Theresa
2017/04/25 17:30:42
Can we remove this comment too?
Donn Denman
2017/04/25 22:35:38
Done.
| |
290 unscheduleInvalidTapNotification(); | |
291 } | 262 } |
292 break; | 263 break; |
293 case SelectionEventType.SELECTION_HANDLES_CLEARED: | 264 case SelectionEventType.SELECTION_HANDLES_CLEARED: |
294 mHandler.handleSelectionDismissal(); | 265 mHandler.handleSelectionDismissal(); |
295 resetAllStates(); | 266 resetAllStates(); |
296 break; | 267 break; |
297 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: | 268 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: |
298 shouldHandleSelection = mShouldHandleSelectionModification; | 269 shouldHandleSelection = mShouldHandleSelectionModification; |
299 break; | 270 break; |
300 default: | 271 default: |
(...skipping 26 matching lines...) Expand all Loading... | |
327 } | 298 } |
328 | 299 |
329 /** | 300 /** |
330 * Resets all internal state of this class, including the tap state. | 301 * Resets all internal state of this class, including the tap state. |
331 */ | 302 */ |
332 private void resetAllStates() { | 303 private void resetAllStates() { |
333 resetSelectionStates(); | 304 resetSelectionStates(); |
334 mLastTapState = null; | 305 mLastTapState = null; |
335 mLastScrollTimeNs = 0; | 306 mLastScrollTimeNs = 0; |
336 mIsContextMenuShown = false; | 307 mIsContextMenuShown = false; |
308 mTapTimeNanoseconds = 0; | |
309 mDidExpandSelection = false; | |
337 } | 310 } |
338 | 311 |
339 /** | 312 /** |
340 * Resets all of the internal state of this class that handles the selection . | 313 * Resets all of the internal state of this class that handles the selection . |
341 */ | 314 */ |
342 private void resetSelectionStates() { | 315 private void resetSelectionStates() { |
343 mSelectionType = SelectionType.UNDETERMINED; | 316 mSelectionType = SelectionType.UNDETERMINED; |
344 mSelectedText = null; | 317 mSelectedText = null; |
345 | 318 |
346 mWasTapGestureDetected = false; | 319 mWasTapGestureDetected = false; |
(...skipping 10 matching lines...) Expand all Loading... | |
357 /** | 330 /** |
358 * Handles an unhandled tap gesture. | 331 * Handles an unhandled tap gesture. |
359 * @param x The x coordinate in px. | 332 * @param x The x coordinate in px. |
360 * @param y The y coordinate in px. | 333 * @param y The y coordinate in px. |
361 */ | 334 */ |
362 void handleShowUnhandledTapUIIfNeeded(int x, int y) { | 335 void handleShowUnhandledTapUIIfNeeded(int x, int y) { |
363 mWasTapGestureDetected = false; | 336 mWasTapGestureDetected = false; |
364 // TODO(donnd): refactor to avoid needing a new handler API method as su ggested by Pedro. | 337 // TODO(donnd): refactor to avoid needing a new handler API method as su ggested by Pedro. |
365 if (mSelectionType != SelectionType.LONG_PRESS) { | 338 if (mSelectionType != SelectionType.LONG_PRESS) { |
366 mWasTapGestureDetected = true; | 339 mWasTapGestureDetected = true; |
367 long tapTimeNanoseconds = System.nanoTime(); | 340 mSelectionType = SelectionType.TAP; |
368 // TODO(donnd): add a policy method to get adjusted tap count. | 341 mTapTimeNanoseconds = System.nanoTime(); |
369 ChromePreferenceManager prefs = ChromePreferenceManager.getInstance( ); | |
370 int adjustedTapsSinceOpen = prefs.getContextualSearchTapCount() | |
371 - prefs.getContextualSearchTapQuickAnswerCount(); | |
372 // Explicitly destroy the old heuristics so native code can dispose data. | |
373 if (mTapHeuristics != null) mTapHeuristics.destroy(); | |
374 mTapHeuristics = | |
375 new TapSuppressionHeuristics(this, mLastTapState, x, y, adju stedTapsSinceOpen); | |
376 // TODO(donnd): Move to be called when the panel closes to work with states that change. | |
377 mTapHeuristics.logConditionState(); | |
378 // Tell the manager what it needs in order to log metrics on whether the tap would have | |
379 // been suppressed if each of the heuristics were satisfied. | |
380 mHandler.handleMetricsForWouldSuppressTap(mTapHeuristics); | |
381 mX = x; | 342 mX = x; |
382 mY = y; | 343 mY = y; |
383 boolean shouldSuppressTap = mTapHeuristics.shouldSuppressTap(); | 344 mHandler.handleValidTap(); |
384 if (shouldSuppressTap) { | |
385 mHandler.handleSuppressedTap(); | |
386 } else { | |
387 // TODO(donnd): Find a better way to determine that a navigation will be triggered | |
388 // by the tap, or merge with other time-consuming actions like g athering surrounding | |
389 // text or detecting page mutations. | |
390 new Handler().postDelayed(new Runnable() { | |
391 @Override | |
392 public void run() { | |
393 mHandler.handleValidTap(); | |
394 } | |
395 }, TAP_NAVIGATION_DETECTION_DELAY); | |
396 } | |
397 // Remember the tap state for subsequent tap evaluation. | |
398 mLastTapState = | |
399 new ContextualSearchTapState(x, y, tapTimeNanoseconds, shoul dSuppressTap); | |
400 } else { | 345 } else { |
401 // Long press; reset last tap state. | 346 // Long press; reset last tap state. |
402 mLastTapState = null; | 347 mLastTapState = null; |
403 mHandler.handleInvalidTap(); | 348 mHandler.handleInvalidTap(); |
404 } | 349 } |
405 } | 350 } |
406 | 351 |
407 /** | 352 /** |
353 * Handles Tap suppression by making a callback to either the handler's hand leSuppressedTap or | |
Theresa
2017/04/25 17:30:42
nit: #handleSuppressedTap() or #handleNonSuppresse
Donn Denman
2017/04/25 22:35:37
Done.
| |
354 * handleNonSuppressedTap after a possible delay. | |
355 * This should be called when the context is fully build (by gathering surro unding text | |
Theresa
2017/04/25 17:30:42
nit: s/build/built
Donn Denman
2017/04/25 22:35:38
Done.
| |
356 * if needed, etc) but before showing any UX. | |
357 */ | |
358 void handleShouldSuppressTap() { | |
359 int x = (int) mX; | |
360 int y = (int) mY; | |
361 | |
362 // TODO(donnd): add a policy method to get adjusted tap count. | |
363 ChromePreferenceManager prefs = ChromePreferenceManager.getInstance(); | |
364 int adjustedTapsSinceOpen = prefs.getContextualSearchTapCount() | |
365 - prefs.getContextualSearchTapQuickAnswerCount(); | |
366 TapSuppressionHeuristics tapHeuristics = | |
367 new TapSuppressionHeuristics(this, mLastTapState, x, y, adjusted TapsSinceOpen); | |
368 // TODO(donnd): Move to be called when the panel closes to work with sta tes that change. | |
369 tapHeuristics.logConditionState(); | |
370 // Tell the manager what it needs in order to log metrics on whether the tap would have | |
371 // been suppressed if each of the heuristics were satisfied. | |
372 mHandler.handleMetricsForWouldSuppressTap(tapHeuristics); | |
373 | |
374 boolean shouldSuppressTap = tapHeuristics.shouldSuppressTap(); | |
375 if (mTapTimeNanoseconds != 0) { | |
376 // Remember the tap state for subsequent tap evaluation. | |
377 mLastTapState = | |
378 new ContextualSearchTapState(x, y, mTapTimeNanoseconds, shou ldSuppressTap); | |
379 } else { | |
380 mLastTapState = null; | |
381 } | |
382 | |
383 if (shouldSuppressTap) { | |
384 mHandler.handleSuppressedTap(); | |
385 } else { | |
386 mHandler.handleNonSuppressedTap(); | |
387 } | |
388 } | |
389 | |
390 /** | |
408 * Gets the base page ContentViewCore. | 391 * Gets the base page ContentViewCore. |
409 * Deprecated, use getBaseWebContents instead. | 392 * Deprecated, use getBaseWebContents instead. |
410 * @return The Base Page's {@link ContentViewCore}, or {@code null} if there is no current tab. | 393 * @return The Base Page's {@link ContentViewCore}, or {@code null} if there is no current tab. |
411 */ | 394 */ |
412 @Deprecated | 395 @Deprecated |
413 ContentViewCore getBaseContentView() { | 396 ContentViewCore getBaseContentView() { |
414 Tab currentTab = mActivity.getActivityTab(); | 397 Tab currentTab = mActivity.getActivityTab(); |
415 return currentTab != null ? currentTab.getContentViewCore() : null; | 398 return currentTab != null ? currentTab.getContentViewCore() : null; |
416 } | 399 } |
417 | 400 |
(...skipping 12 matching lines...) Expand all Loading... | |
430 } | 413 } |
431 | 414 |
432 /** | 415 /** |
433 * Expands the current selection by the specified amounts. | 416 * Expands the current selection by the specified amounts. |
434 * @param selectionStartAdjust The start offset adjustment of the selection to use to highlight | 417 * @param selectionStartAdjust The start offset adjustment of the selection to use to highlight |
435 * the search term. | 418 * the search term. |
436 * @param selectionEndAdjust The end offset adjustment of the selection to u se to highlight | 419 * @param selectionEndAdjust The end offset adjustment of the selection to u se to highlight |
437 * the search term. | 420 * the search term. |
438 */ | 421 */ |
439 void adjustSelection(int selectionStartAdjust, int selectionEndAdjust) { | 422 void adjustSelection(int selectionStartAdjust, int selectionEndAdjust) { |
440 // TODO(donnd): add code to verify that the selection is still valid bef ore changing it. | |
441 // crbug.com/508354 | |
Theresa
2017/04/25 17:30:42
Why is this TODO no longer neeeded?
Donn Denman
2017/04/25 22:35:37
Added a check in handleSearchTermResolutionRespons
| |
442 | |
443 if (selectionStartAdjust == 0 && selectionEndAdjust == 0) return; | 423 if (selectionStartAdjust == 0 && selectionEndAdjust == 0) return; |
444 WebContents basePageWebContents = getBaseWebContents(); | 424 WebContents basePageWebContents = getBaseWebContents(); |
445 if (basePageWebContents != null) { | 425 if (basePageWebContents != null) { |
446 mDidExpandSelection = true; | 426 mDidExpandSelection = true; |
447 basePageWebContents.adjustSelectionByCharacterOffset( | 427 basePageWebContents.adjustSelectionByCharacterOffset( |
448 selectionStartAdjust, selectionEndAdjust); | 428 selectionStartAdjust, selectionEndAdjust); |
449 } | 429 } |
450 } | 430 } |
451 | 431 |
452 // ========================================================================= =================== | 432 // ========================================================================= =================== |
453 // Invalid Tap Notification | |
454 // ========================================================================= =================== | |
455 | |
456 /** | |
457 * Schedules a notification to check if the tap was invalid. | |
458 * When we call selectWordAroundCaret it selects nothing in cases where the tap was invalid. | |
459 * We have no way to know other than scheduling a notification to check late r. | |
460 * This allows us to hide the bar when there's no selection. | |
461 */ | |
462 private void scheduleInvalidTapNotification() { | |
463 // TODO(donnd): Fix selectWordAroundCaret to we can tell if it selects, instead | |
464 // of using a timer here! See crbug.com/435778. | |
465 mRunnableHandler.postDelayed(mHandleInvalidTapRunnable, | |
466 INVALID_IF_NO_SELECTION_CHANGE_AFTER_TAP_MS); | |
467 } | |
468 | |
469 /** | |
470 * Un-schedules all pending notifications to check if a tap was invalid. | |
471 */ | |
472 private void unscheduleInvalidTapNotification() { | |
473 mRunnableHandler.removeCallbacks(mHandleInvalidTapRunnable); | |
474 mIsWaitingForInvalidTapDetection = true; | |
475 } | |
476 | |
477 /** | |
478 * Notify's the system that tap gesture has been completed. | |
479 */ | |
480 private void onInvalidTapDetectionTimeout() { | |
481 mHandler.handleInvalidTap(); | |
482 mIsWaitingForInvalidTapDetection = false; | |
483 } | |
484 | |
485 // ========================================================================= =================== | |
486 // Selection Modification | 433 // Selection Modification |
487 // ========================================================================= =================== | 434 // ========================================================================= =================== |
488 | 435 |
489 /** | 436 /** |
490 * This method checks whether the selection modification should be handled. This method | 437 * This method checks whether the selection modification should be handled. This method |
491 * is needed to allow modifying selections that are occluded by the Panel. | 438 * is needed to allow modifying selections that are occluded by the Panel. |
492 * See crbug.com/489461. | 439 * See crbug.com/489461. |
493 * | 440 * |
494 * @param reason The reason the panel is closing. | 441 * @param reason The reason the panel is closing. |
495 * @return Whether the selection modification should be handled. | 442 * @return Whether the selection modification should be handled. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 // Starts are inclusive and ends are non-inclusive for both GSAContext & matcher. | 568 // Starts are inclusive and ends are non-inclusive for both GSAContext & matcher. |
622 while (matcher.find()) { | 569 while (matcher.find()) { |
623 if (startOffset >= matcher.start() && endOffset <= matcher.end()) { | 570 if (startOffset >= matcher.start() && endOffset <= matcher.end()) { |
624 return true; | 571 return true; |
625 } | 572 } |
626 } | 573 } |
627 | 574 |
628 return false; | 575 return false; |
629 } | 576 } |
630 } | 577 } |
OLD | NEW |