OLD | NEW |
(Empty) | |
| 1 [TOC] |
| 2 |
| 3 # Touch-to-Search |
| 4 |
| 5 Touch-to-Search is a feature that allows a Chrome user to quickly run Google |
| 6 searches by touching the text they wish to search for on a web page they are |
| 7 viewing. The search results are displayed in an overlay that can be "promoted" |
| 8 into a new tab if the user desires. |
| 9 |
| 10 ### Nomenclature |
| 11 |
| 12 The original name for Touch-to-Search was "Contextual Search", and usage of that |
| 13 name persists in many contexts, including all of the class names in this code. |
| 14 |
| 15 ### Availability |
| 16 |
| 17 Touch-to-Search was available in a limited Finch trial on iOS phone devices in |
| 18 M41-44, and will be available to all users (phone and tablet) in M49. It is |
| 19 also available via `chrome://flags`. |
| 20 |
| 21 ### Bug component |
| 22 |
| 23 [`Cr-UI-Browser-Mobile-TouchToSearch`](https://code.google.com/p/chromium/issues
/list?can=2&q=Cr%3DUI-Browser-Mobile-TouchToSearch) |
| 24 |
| 25 ## Behavior {#behavior} |
| 26 |
| 27 Generally speaking, a touch-to-search interaction goes through some or all of |
| 28 the following phases, and the transitions between each phase are asynchronous. |
| 29 |
| 30 1. **Touch**: The user taps on a word on the web page. This yields both the |
| 31 tapped word and the surrounding text for use as context. |
| 32 2. **Dispatch**: The word and context are dispatched as a query to Google Search |
| 33 servers. The Touch-to-Search UI is displayed with the initial tapped text |
| 34 and surrounding context displayed. |
| 35 3. **Resolution**: The resolved search term is returned along with the URL of |
| 36 the search results page. The UI is updated with the resolved search term, and |
| 37 the search results page starts to load. |
| 38 5. **Page Display**: The search tab page load is complete. |
| 39 6. **Promotion**: The contextual search panel is promoted to a new tab. This is |
| 40 initiated by user action (such as tapping on the search term, or tapping a link |
| 41 in the search results tab). |
| 42 |
| 43 There is a slightly different flow of states for when the user long-presses on |
| 44 a word on the web page, initiating an iOS text selection. |
| 45 |
| 46 Additionally, during or between many of these phases, the user may be |
| 47 interacting with the touch-to-search panel, changing its position. |
| 48 |
| 49 ### Opt-Out flow |
| 50 |
| 51 ### Privacy controls |
| 52 |
| 53 ## Controller architecture |
| 54 |
| 55 ## Touch detection and handling |
| 56 |
| 57 Touch detection is handled both by native code and injected javascript. Broadly |
| 58 speaking, detection happens as follows: |
| 59 |
| 60 1. The Touch-to-Search controller adds a `UITapGestureRecognizer` to the current |
| 61 tab's web view. |
| 62 2. When this tap recognizer fires, the injected JavaScript method |
| 63 `handleTapAtPoint()` is called. This method determines if the tap was inside |
| 64 a plain text word. |
| 65 3. If it was, a 'context' object is returned that includes the URL of the page, |
| 66 the word that was tapped, the text surrounding the tapped word, and the position |
| 67 of the tapped word inside the text. |
| 68 4. Once the Touch-to-Search controller receives the callback from the javascript |
| 69 call, it displays the Touch-to-Search UI and composes and sends the search query |
| 70 for resolution. |
| 71 |
| 72 This takes the Touch-to-Search system from the **Touch** to **Dispatch** phases |
| 73 as described in [Behavior](#behavior), above. |
| 74 |
| 75 (There are numerous complicating factors inside this sequence; they are detailed |
| 76 in sections below.) |
| 77 |
| 78 ### DOM Mutation Lock. |
| 79 |
| 80 In order to highlight text on the web page, Touch-to-Search inserts (via the |
| 81 JavaScript component) HTML and CSS. So that this DOM modification doesn't |
| 82 interfere with other DOM modifications performed by Chrome (for example, |
| 83 find-in-page highlighting), tap processing is performed after obtaining a DOM |
| 84 mutation lock on the page. |
| 85 |
| 86 ### Tap delay. |
| 87 |
| 88 Some pages may dynamically adjust the page in response to a tap (for example, |
| 89 a non-native drop-down menu may be implemented this way). In order to give a |
| 90 page time to update in response to a tap, tap processing is delayed by |
| 91 (currently) 800ms. |
| 92 |
| 93 ### Tap rejection on mutated DOM elements. |
| 94 |
| 95 Tapping on sections of a page that have recently been changed doesn't trigger |
| 96 touch-to-search, again on the assumption that a recently-updated part of the |
| 97 page is actually a control updating in response to the tap. To detect this, each |
| 98 DOM modification on the page is observed via a JavaScript MutationObserver. |
| 99 For each mutation, the time and the mutated DOM element are recorded. Taps that |
| 100 are in elements contained by or containing elements modified since the original |
| 101 native tap event are rejected. In conjunction with the tap processing delay |
| 102 (above), this is implemented by checking for DOM elements modified as long ago |
| 103 as the tap processing was delayed. |
| 104 |
| 105 The list of modified DOM elements is cleared of records older than the 800ms tap |
| 106 delay every time a mutation occurs, but not more frequently than the tap delay. |
| 107 |
| 108 ## Views |
| 109 |
| 110 The Touch-to-Search UI consists of the following views, which appear above the |
| 111 active tab: |
| 112 |
| 113 * The **panel** (`ContextualSearchPanelView`), which contains the other views |
| 114 and moves up and down in response to user gestures. |
| 115 * The **header** (`ContextualSearchHeaderView`), which displays the tapped |
| 116 word and its context, and other UI elements. |
| 117 * The **search tab**, a specially-configured Tab which is displayed inside the |
| 118 panel, containing the results of the tap-to-search query. |
| 119 |
| 120 ### Panel positions |
| 121 |
| 122 The panel can be in several different positions relative to the current tab. |
| 123 The panel's horizontal position never varies; it is always the width of the tab. |
| 124 Vertically, the panel can be in any of four position. These are named |
| 125 differently on iOS and Android; Android names are in parenthesis. (At some point |
| 126 iOS will standardize on the Android names). |
| 127 |
| 128 Position | Description |
| 129 --------------------------| ------- |
| 130 `DISMISSED` (`CLOSED`) | Panel is offscreen, just below the current tab, |
| 131 `PEEKING` (`PEEKED`) | Panel is showing only the header at the bottom of th
e tab. |
| 132 `PREVIEWING` (`EXPANDED`) | Panel covers 2/3 of the tab, showing most of the sea
rch results. |
| 133 `COVERING` (`MAXIMIZED`) | Panel covers the entire tab, so the header overlaps
the toolbar. |
| 134 |
| 135 ### Header |
| 136 |
| 137 The header is the main piece of UI for touch-to-search. It shows the currently |
| 138 active search term, indicates the progress of the search term resolution, shows |
| 139 the "Google G" for brand identification, and shows a control that hints as to |
| 140 how to expand/dismiss the panel. |
| 141 |
| 142 ## Animations |
| 143 |
| 144 ### Durations |
| 145 |
| 146 Animations use standard material animation durations: |
| 147 |
| 148 Animation | Duration |
| 149 ---------------------------------| -------: |
| 150 Panel movement (non-dismissing) | *0.35s* |
| 151 Panel dismissal | *0.25s* |
| 152 Text and other transitions | *0.25s* |
| 153 |
| 154 |
| 155 ### Panel position changes |
| 156 |
| 157 #### `PEEKING` to `PREVIEWING` |
| 158 |
| 159 As the panel moves from `PEEKING` to `PREVIEWING` (whether dragged or animated), |
| 160 the following animations occur: |
| 161 |
| 162 1. The header control rotates clockwise from pointing upwards to pointing |
| 163 downwards. |
| 164 2. The current tab's web page content is shaded with (approximately) 66% opaque |
| 165 black. |
| 166 |
| 167 #### `PREVIEWING` to `COVERING` |
| 168 |
| 169 ### Search term resolution and loading |
| 170 |
| 171 #### Touch {#anim-search-touch} |
| 172 |
| 173 When touch-to-search is initiated (assuming the panel is `DISMISSED`): |
| 174 |
| 175 1. The panel moves to `PEEKING` (*0.35s*). The header is in the "initial" state. |
| 176 2. The tapped word is highlighted. This is not animated. |
| 177 3. After the panel motion completes, the header text and control fade in |
| 178 (*0.25s*). |
| 179 4. After the fade-in is complete, the G-logo irises in (*0.25s*). |
| 180 |
| 181 (Total animation time: *0.85s*) |
| 182 |
| 183 These animations aren't preempted even if resolution occurs after they complete. |
| 184 |
| 185 ##### Implementation notes. |
| 186 |
| 187 The G-logo iris effect is implemented by adding a circular alpha channel layer |
| 188 as a mask to the G-logo image view; this mask layer is initially scaled to be |
| 189 very small, and has its transform animated to scale up and reveal the logo. |
| 190 |
| 191 #### Dispatch |
| 192 |
| 193 There is currently no animation during dispatch. |
| 194 |
| 195 #### Resolution |
| 196 |
| 197 When resolution occurs: |
| 198 |
| 199 1. If possible, the highlighted text on the web page is expanded to cover the |
| 200 resolved search term. |
| 201 2. After any initial (see [Touch](#anim-search-touch), above) animations |
| 202 complete, the context text views fade, the query text cross-fades to show the |
| 203 resolved text, and (*not implemented*) the resolved text moves to be |
| 204 leading-aligned and to the leading side of the header (*0.25s*). |
| 205 3. (*Not implemented*) *1.0s* after the text transitions complete, the resolved |
| 206 text moves upwards and the search results caption text fades in underneath. |
| 207 |
| 208 ### Promotion |
| 209 |
| 210 ## See also |
| 211 |
OLD | NEW |