@inboxsdk/core 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/inboxsdk.js +7 -34
  2. package/inboxsdk.js.map +1 -1
  3. package/package.json +1 -1
  4. package/pageWorld.js +1 -1
  5. package/pageWorld.js.map +1 -1
  6. package/src/common/version.d.ts.map +1 -1
  7. package/src/common/version.js +3 -1
  8. package/src/injected-js/main.js +0 -9
  9. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/index.test.js +6 -2
  10. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/index.js +4 -2
  11. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view.js +4 -2
  12. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view.test.js +6 -2
  13. package/src/platform-implementation-js/driver-common/sidebar/ContentPanelViewDriver.js +2 -2
  14. package/src/platform-implementation-js/driver-common/sidebar/constants.d.ts +9 -0
  15. package/src/platform-implementation-js/driver-common/sidebar/constants.d.ts.map +1 -0
  16. package/src/platform-implementation-js/driver-common/sidebar/constants.js +26 -0
  17. package/src/platform-implementation-js/lib/idMap.d.ts +7 -0
  18. package/src/platform-implementation-js/lib/idMap.d.ts.map +1 -1
  19. package/src/platform-implementation-js/lib/idMap.js +35 -0
  20. package/src/platform-implementation-js/platform-implementation.d.ts +0 -3
  21. package/src/platform-implementation-js/platform-implementation.js +1 -9
  22. package/src/injected-js/inbox/setupAjaxInterceptor.js +0 -211
  23. package/src/injected-js/inbox/setupClickAndGetNewIframeSrc.js +0 -67
  24. package/src/injected-js/inbox/setupComposeViewDraftIDFinder.js +0 -35
  25. package/src/injected-js/inbox/setupInboxFakeWindowResizeListener.js +0 -29
  26. package/src/platform-implementation-js/dom-driver/inbox/__mocks__/getSidebarClassnames.js +0 -13
  27. package/src/platform-implementation-js/dom-driver/inbox/addNavItem.js +0 -38
  28. package/src/platform-implementation-js/dom-driver/inbox/addRecipientRow.js +0 -55
  29. package/src/platform-implementation-js/dom-driver/inbox/createLink.js +0 -19
  30. package/src/platform-implementation-js/dom-driver/inbox/createLink.test.js +0 -27
  31. package/src/platform-implementation-js/dom-driver/inbox/detection/appToolbarLocation/parser.js +0 -43
  32. package/src/platform-implementation-js/dom-driver/inbox/detection/attachmentCard/parser.js +0 -34
  33. package/src/platform-implementation-js/dom-driver/inbox/detection/attachmentOverlay/parser.js +0 -53
  34. package/src/platform-implementation-js/dom-driver/inbox/detection/chatSidebar/parser.js +0 -31
  35. package/src/platform-implementation-js/dom-driver/inbox/detection/compose/parser.js +0 -103
  36. package/src/platform-implementation-js/dom-driver/inbox/detection/message/parser.js +0 -69
  37. package/src/platform-implementation-js/dom-driver/inbox/detection/nativeDrawer/parser.js +0 -32
  38. package/src/platform-implementation-js/dom-driver/inbox/detection/searchBar/parser.js +0 -28
  39. package/src/platform-implementation-js/dom-driver/inbox/detection/thread/parser.js +0 -49
  40. package/src/platform-implementation-js/dom-driver/inbox/detection/thread-row/parser.js +0 -100
  41. package/src/platform-implementation-js/dom-driver/inbox/getComposeViewDriverLiveSet.js +0 -99
  42. package/src/platform-implementation-js/dom-driver/inbox/getInboxMessageIdForInboxThreadId.js +0 -36
  43. package/src/platform-implementation-js/dom-driver/inbox/getSidebarClassnames.js +0 -114
  44. package/src/platform-implementation-js/dom-driver/inbox/getSidebarClassnames.test.js +0 -73
  45. package/src/platform-implementation-js/dom-driver/inbox/gotoView.js +0 -39
  46. package/src/platform-implementation-js/dom-driver/inbox/gotoView.test.js +0 -28
  47. package/src/platform-implementation-js/dom-driver/inbox/inbox-butter-bar-driver.js +0 -148
  48. package/src/platform-implementation-js/dom-driver/inbox/inbox-driver.js +0 -863
  49. package/src/platform-implementation-js/dom-driver/inbox/inbox-page-communicator.js +0 -62
  50. package/src/platform-implementation-js/dom-driver/inbox/inboxResponseProcessor.js +0 -12
  51. package/src/platform-implementation-js/dom-driver/inbox/inboxResponseProcessor.test.js +0 -18
  52. package/src/platform-implementation-js/dom-driver/inbox/makePageParserTree.js +0 -33
  53. package/src/platform-implementation-js/dom-driver/inbox/pageParserOptions.js +0 -265
  54. package/src/platform-implementation-js/dom-driver/inbox/registerSearchSuggestionsProvider.js +0 -301
  55. package/src/platform-implementation-js/dom-driver/inbox/setupCustomAutocompleteSelectionHandling.js +0 -183
  56. package/src/platform-implementation-js/dom-driver/inbox/setupRouteViewDriverStream.js +0 -64
  57. package/src/platform-implementation-js/dom-driver/inbox/setupRouteViewDriverStream.test.js +0 -72
  58. package/src/platform-implementation-js/dom-driver/inbox/views/InboxLabelView.js +0 -78
  59. package/src/platform-implementation-js/dom-driver/inbox/views/InboxMoleViewDriver.js +0 -296
  60. package/src/platform-implementation-js/dom-driver/inbox/views/InboxToolbarButtonView.js +0 -91
  61. package/src/platform-implementation-js/dom-driver/inbox/views/InboxToolbarView.js +0 -53
  62. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-app-sidebar-view.js +0 -271
  63. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-app-toolbar-button-view.js +0 -160
  64. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-app-toolbar-tooltip-view.js +0 -57
  65. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-attachment-card-view.js +0 -197
  66. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-attachment-overlay-view.js +0 -83
  67. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-chat-sidebar-view.js +0 -45
  68. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-compose-button-view.js +0 -116
  69. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-compose-view.js +0 -842
  70. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-custom-route-view.js +0 -75
  71. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-dropdown-view.js +0 -25
  72. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-dummy-route-view.js +0 -63
  73. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-message-view.js +0 -274
  74. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-modal-view.js +0 -112
  75. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-route-view.js +0 -96
  76. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-thread-row-view.js +0 -315
  77. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-thread-view.js +0 -218
  78. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-thread-view.test.js +0 -171
  79. package/src/platform-implementation-js/dom-driver/inbox/views/inbox-tooltip-view.js +0 -127
  80. package/src/platform-implementation-js/dom-driver/inbox/views/inboxNavItemView.js +0 -311
  81. package/src/platform-implementation-js/dom-driver/inbox/waitForAnimationClickBlockerGone.js +0 -26
@@ -1,301 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = registerSearchSuggestionsProvider;
8
- var _kefir = _interopRequireDefault(require("kefir"));
9
- var _kefirBus = _interopRequireDefault(require("kefir-bus"));
10
- var _kefirStopper = _interopRequireDefault(require("kefir-stopper"));
11
- var _toItemWithLifetimeStream = _interopRequireDefault(require("../../lib/toItemWithLifetimeStream"));
12
- var _makeMutationObserverChunkedStream = _interopRequireDefault(require("../../lib/dom/make-mutation-observer-chunked-stream"));
13
- var _fromEventTargetCapture = _interopRequireDefault(require("../../lib/from-event-target-capture"));
14
- var _insertElementInOrder = _interopRequireDefault(require("../../lib/dom/insert-element-in-order"));
15
- var _parser = _interopRequireDefault(require("./detection/searchBar/parser"));
16
- var _copyAndValidateAutocompleteResults = _interopRequireDefault(require("../../lib/copyAndValidateAutocompleteResults"));
17
- var _setupCustomAutocompleteSelectionHandling = _interopRequireDefault(require("./setupCustomAutocompleteSelectionHandling"));
18
- var _autoHtml = _interopRequireDefault(require("auto-html"));
19
- const ORDERING_ATTR = 'data-inboxsdk-search-provider-count';
20
- const DEFAULT_RESULT_ICON = '//www.gstatic.com/images/icons/material/system/2x/search_black_24dp.png';
21
- const getProviderOrder = () => {
22
- const {
23
- documentElement
24
- } = document;
25
- if (!documentElement) {
26
- throw new Error();
27
- }
28
- const orderAttr = documentElement.getAttribute(ORDERING_ATTR);
29
- const providerOrder = (orderAttr ? parseInt(orderAttr) + 1 : 0).toString();
30
- documentElement.setAttribute(ORDERING_ATTR, providerOrder);
31
- return providerOrder;
32
- };
33
- const handleResultChosen = _ref => {
34
- let {
35
- driver,
36
- searchInput,
37
- result,
38
- event
39
- } = _ref;
40
- if (typeof result.onClick === 'function') {
41
- result.onClick();
42
- }
43
- if (typeof result.externalURL === 'string') {
44
- window.open(result.externalURL);
45
- }
46
- if (result.routeName && result.routeParams) {
47
- driver.goto(result.routeName, result.routeParams);
48
- }
49
- if (typeof result.searchTerm === 'string') {
50
- searchInput.value = result.searchTerm;
51
- searchInput.dispatchEvent(new Event('input'));
52
- }
53
- };
54
- const renderResultsList = _ref2 => {
55
- let {
56
- driver,
57
- searchInput,
58
- removalStream,
59
- results,
60
- providerOrder
61
- } = _ref2;
62
- const container = document.createElement('div');
63
- container.setAttribute('data-order-hint', providerOrder);
64
- container.classList.add('inboxsdk__search_suggestion_group');
65
- results.forEach(result => {
66
- const listItem = document.createElement('li');
67
- const description = result.description || result.descriptionHTML ? (0, _autoHtml.default)`
68
- <span class="inboxsdk__search_suggestion_desc">
69
- ${result.description || {
70
- __html: result.descriptionHTML
71
- }}
72
- </span>
73
- ` : '';
74
- listItem.classList.add('inboxsdk__search_suggestion');
75
- listItem.innerHTML = (0, _autoHtml.default)`
76
- <img src="${result.iconUrl || DEFAULT_RESULT_ICON}">
77
- <span>
78
- <span class="inboxsdk__search_suggestion_name" role="option">
79
- ${result.name || {
80
- __html: result.nameHTML
81
- }}
82
- </span>
83
- ${{
84
- __html: description
85
- }}
86
- </span>
87
- `;
88
- _kefir.default.fromEvents(listItem, 'click').takeUntilBy(removalStream).onValue(event => handleResultChosen({
89
- driver,
90
- searchInput,
91
- result,
92
- event
93
- }));
94
- container.appendChild(listItem);
95
- });
96
- return container;
97
- };
98
- function registerSearchSuggestionsProvider(driver, handler) {
99
- const stopper = (0, _kefirStopper.default)();
100
- const providerOrder = getProviderOrder();
101
- (0, _toItemWithLifetimeStream.default)(driver.getTagTree().getAllByTag('searchBar')).flatMap(_ref3 => {
102
- let {
103
- el,
104
- removalStream
105
- } = _ref3;
106
- const {
107
- searchInput
108
- } = (0, _parser.default)(el.getValue()).elements;
109
- if (searchInput instanceof HTMLInputElement) {
110
- return _kefir.default.constant({
111
- searchInput,
112
- searchInputRemovalStream: removalStream
113
- });
114
- } else {
115
- return _kefir.default.never();
116
- }
117
- }).flatMap(_ref4 => {
118
- let {
119
- searchInput,
120
- searchInputRemovalStream
121
- } = _ref4;
122
- return (0, _toItemWithLifetimeStream.default)(driver.getTagTree().getAllByTag('searchAutocompleteResults')).takeUntilBy(searchInputRemovalStream).map(_ref5 => {
123
- let {
124
- el,
125
- removalStream
126
- } = _ref5;
127
- return {
128
- searchInput,
129
- searchInputRemovalStream,
130
- resultsEl: el.getValue(),
131
- resultsElRemovalStream: removalStream
132
- };
133
- });
134
- }).flatMap(_ref6 => {
135
- let {
136
- searchInput,
137
- searchInputRemovalStream,
138
- resultsEl,
139
- resultsElRemovalStream
140
- } = _ref6;
141
- const inputs = _kefir.default.fromEvents(searchInput, 'input').takeUntilBy(searchInputRemovalStream).takeUntilBy(resultsElRemovalStream);
142
- const enterAndTabPresses = _kefir.default.fromEvents(searchInput, 'keydown').filter(_ref7 => {
143
- let {
144
- keyCode
145
- } = _ref7;
146
- return keyCode === 13 || keyCode === 9;
147
- }).takeUntilBy(searchInputRemovalStream).takeUntilBy(resultsElRemovalStream);
148
- return inputs.map(event => ({
149
- event,
150
- searchInput,
151
- resultsEl,
152
- inputStream: inputs,
153
- enterAndTabPresses,
154
- resultsElRemovalStream
155
- }));
156
- }).flatMapLatest(item => {
157
- const suggestionsResponse = driver.getPageCommunicator().ajaxInterceptStream.filter(_ref8 => {
158
- let {
159
- type
160
- } = _ref8;
161
- return type === 'searchSuggestionsReceieved';
162
- });
163
- const removalStream = _kefir.default.merge([
164
- // Handle cleanup when a new search query is entered. We want to wait
165
- // to remove our old results until *after* Inbox's results from the new
166
- // query have come back, since that will allow our modifications to
167
- // switch from old -> new in sync with Inbox's native suggestions.
168
- // If we didn't wait on `suggestionsResponse` to trigger cleanup,
169
- // Our modifications would disappear the moment the user started typing,
170
- // which ends up looking jarring and inconsistent with Inbox's results
171
- // which stick around until the new results are ready.
172
- item.inputStream.take(1).flatMap(() => suggestionsResponse),
173
- // Handle cleanup when the user deletes their entire search query.
174
- item.inputStream.filter(_ref9 => {
175
- let {
176
- target: {
177
- value
178
- }
179
- } = _ref9;
180
- return value === '';
181
- }), item.resultsElRemovalStream]).take(1);
182
- return _kefir.default.combine([_kefir.default.fromPromise(Promise.resolve(handler(item.event.target.value))),
183
- // Wait to send results to the UI until Inbox's results have come back
184
- // to avoid rendering too soon.
185
- suggestionsResponse.take(1)]).takeUntilBy(removalStream).map(_ref10 => {
186
- let [results, _ignored] = _ref10;
187
- return {
188
- ...item,
189
- removalStream,
190
- results
191
- };
192
- });
193
- }).takeUntilBy(stopper).flatMap(_ref11 => {
194
- let {
195
- resultsEl,
196
- searchInput,
197
- resultsElRemovalStream,
198
- removalStream,
199
- enterAndTabPresses,
200
- results
201
- } = _ref11;
202
- try {
203
- const validatedResults = (0, _copyAndValidateAutocompleteResults.default)(driver, results);
204
- return _kefir.default.constant({
205
- resultsEl,
206
- searchInput,
207
- resultsElRemovalStream,
208
- removalStream,
209
- enterAndTabPresses,
210
- results: validatedResults
211
- });
212
- } catch (error) {
213
- return _kefir.default.constantError(error);
214
- }
215
- }).filter(_ref12 => {
216
- let {
217
- results
218
- } = _ref12;
219
- return results.length > 0;
220
- }).onError(error => driver.getLogger().error(error)).onValue(_ref13 => {
221
- let {
222
- resultsEl,
223
- searchInput,
224
- resultsElRemovalStream,
225
- removalStream,
226
- enterAndTabPresses,
227
- results
228
- } = _ref13;
229
- (0, _setupCustomAutocompleteSelectionHandling.default)({
230
- resultsEl,
231
- resultsElRemovalStream,
232
- searchInput
233
- });
234
- const suggestionsElement = renderResultsList({
235
- driver,
236
- searchInput,
237
- removalStream,
238
- results,
239
- providerOrder
240
- });
241
- (0, _insertElementInOrder.default)(resultsEl, suggestionsElement);
242
-
243
- // NOTE: Because we're manually overriding the 'display' property, we've
244
- // basically taken responsibility for showing/hiding `resultsEl`
245
- // since Inbox no longer knows when the element is truly visible.
246
- // When we want to show results for a search term but Inbox doesn't have
247
- // any results, we need to force the results element to be displayed.
248
- // When Inbox hides the element it also removes a class that applies
249
- // some padding adjustments, so we have to force that as well.
250
- resultsEl.style.display = 'block';
251
- resultsEl.style.padding = '6px 0';
252
- removalStream.onValue(() => {
253
- suggestionsElement.remove();
254
-
255
- // Because we've mostly overridden Inbox's native show/hide logic we're
256
- // responsible for hiding `resultsEl` in a couple removal cases:
257
- // 1) when we go directly from only custom results to having
258
- // no text in the search box.
259
- // 2) when there are only custom results and the user subsequently
260
- // enters a search that returns no results of any type.
261
- if (searchInput.value === '' || resultsEl.matches(':empty')) {
262
- resultsEl.style.display = 'none';
263
- }
264
- });
265
-
266
- // We have to take over responsibility for hiding `resultsEl` when
267
- // the user presses enter or tab because our other overrides prevent Inbox
268
- // from handling this sensibly.
269
- enterAndTabPresses.takeUntilBy(removalStream).take(1).onValue(() => {
270
- resultsEl.style.display = 'none';
271
- });
272
-
273
- // When Inbox gets the *first* set of suggestions after opening search,
274
- // it clears away the current children of the `resultsEl` element.
275
- // When this happens, our modifications will get cleared away if
276
- // we've already added them — this can happen if Inbox skips a turn of
277
- // the event loop between getting the AJAX response back and rendering to
278
- // the DOM. To handle this case, we watch `resultsEl` for mutations
279
- // and re-add our modifications if they've been cleared.
280
- // We also force `resultsEl` to show because the first time
281
- // we display modifications that aren't accompanied by native results
282
- // Inbox hides `resultsEl` after we force it to show. Because Inbox
283
- // removes the previous search's results in the same event loop tick as
284
- // hiding `resultsEl`, we can hook into the child element removal and
285
- // re-show it before the hidden state gets painted to the screen.
286
- // We need to stop this entire process when tab or enter is pressed,
287
- // because if a custom result was selected when the key was pressed
288
- // then Inbox will remove the native results that no longer match the
289
- // search term — causing this observer to fire and subsequently
290
- // re-show `resultsEl` just as we're trying to manually hide it.
291
- (0, _makeMutationObserverChunkedStream.default)(resultsEl, {
292
- childList: true
293
- }).takeUntilBy(enterAndTabPresses).takeUntilBy(removalStream).onValue(() => {
294
- resultsEl.style.display = 'block';
295
- if (suggestionsElement.parentElement !== resultsEl) {
296
- (0, _insertElementInOrder.default)(resultsEl, suggestionsElement);
297
- }
298
- });
299
- });
300
- return () => stopper.destroy();
301
- }
@@ -1,183 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = setupCustomAutocompleteSelectionHandling;
8
- var _kefir = _interopRequireDefault(require("kefir"));
9
- var _fromEventTargetCapture = _interopRequireDefault(require("../../lib/from-event-target-capture"));
10
- var _closestNg = _interopRequireDefault(require("closest-ng"));
11
- const SELECTION_MASTER_ATTR = 'data-inboxsdk-selection-master-claimed';
12
- const hasNativeResults = resultsEl => resultsEl.querySelectorAll('li:not(.inboxsdk__search_suggestion)').length > 0;
13
- const hasCustomResults = resultsEl => resultsEl.querySelectorAll('.inboxsdk__search_suggestion').length > 0;
14
- const getSelectedNativeResult = resultsEl => {
15
- const nativeResults = resultsEl.querySelectorAll('li:not(.inboxsdk__search_suggestion)');
16
-
17
- // Unfortunately there are no distinguishable features of a selected
18
- // native result besides its background color... (ಥ﹏ಥ)
19
- return Array.from(nativeResults).find(result => {
20
- const {
21
- backgroundColor
22
- } = getComputedStyle(result);
23
- const colorValues = backgroundColor.match(/([\d.]+)/g);
24
- return colorValues && parseFloat(colorValues[3]) > 0;
25
- });
26
- };
27
- const selectFirstCustomResult = resultsEl => {
28
- const firstCustomResult = resultsEl.querySelector('.inboxsdk__search_suggestion_group:first-of-type > ' + '.inboxsdk__search_suggestion:first-child');
29
- firstCustomResult && firstCustomResult.classList.add('inboxsdk__selected');
30
- };
31
- const setupCustomResultHoverListeners = (resultsEl, resultsElRemovalStream) => {
32
- _kefir.default.fromEvents(resultsEl, 'mouseover').takeUntilBy(resultsElRemovalStream).map(_ref => {
33
- let {
34
- target
35
- } = _ref;
36
- return (0, _closestNg.default)(target, '.inboxsdk__search_suggestion:not(.inboxsdk__selected)');
37
- }).filter(Boolean).onValue(el => {
38
- const customResults = resultsEl.querySelectorAll('.inboxsdk__search_suggestion.inboxsdk__selected');
39
-
40
- // Needed to ensure custom results selected via keyboard events
41
- // have their selected state removed (since no mouseout event fires).
42
- Array.from(customResults).forEach(result => result.classList.remove('inboxsdk__selected'));
43
- el.classList.add('inboxsdk__selected');
44
- });
45
- _kefir.default.fromEvents(resultsEl, 'mouseout').takeUntilBy(resultsElRemovalStream).map(_ref2 => {
46
- let {
47
- target
48
- } = _ref2;
49
- return (0, _closestNg.default)(target, '.inboxsdk__search_suggestion.inboxsdk__selected');
50
- }).filter(Boolean).onValue(el => el.classList.remove('inboxsdk__selected'));
51
- };
52
- function setupCustomAutocompleteSelectionHandling(_ref3) {
53
- let {
54
- resultsEl,
55
- resultsElRemovalStream,
56
- searchInput
57
- } = _ref3;
58
- if (resultsEl.hasAttribute(SELECTION_MASTER_ATTR)) {
59
- return;
60
- }
61
- resultsEl.setAttribute(SELECTION_MASTER_ATTR, 'true');
62
-
63
- // We need to be able to cancel up/down arrow events before Inbox gets them,
64
- // but we only want to listen for events that happen while the search box
65
- // is in focus (since that's when up/down arrows manipulate selection).
66
- // As a result, we need to grab the search box's parent element so we can
67
- // capture and cancel events prior to Inbox's listeners (and our own).
68
- const searchInputParent = searchInput.parentElement;
69
- if (!searchInputParent) {
70
- throw new Error();
71
- }
72
- const keyboardEvents = (0, _fromEventTargetCapture.default)(searchInputParent, 'keydown').takeUntilBy(resultsElRemovalStream);
73
- const upArrowPresses = keyboardEvents.filter(_ref4 => {
74
- let {
75
- keyCode
76
- } = _ref4;
77
- return keyCode === 38;
78
- });
79
- const downArrowPresses = keyboardEvents.filter(_ref5 => {
80
- let {
81
- keyCode
82
- } = _ref5;
83
- return keyCode === 40;
84
- });
85
- const enterPresses = keyboardEvents.filter(_ref6 => {
86
- let {
87
- keyCode
88
- } = _ref6;
89
- return keyCode === 13;
90
- });
91
- upArrowPresses.onValue(event => {
92
- const selectedNativeResult = getSelectedNativeResult(resultsEl);
93
- const selectedCustomResult = resultsEl.querySelector('.inboxsdk__search_suggestion.inboxsdk__selected');
94
- const customResultGroup = selectedCustomResult && (0, _closestNg.default)(selectedCustomResult, '.inboxsdk__search_suggestion_group');
95
- if (selectedNativeResult) {
96
- return;
97
- }
98
- if (selectedCustomResult && customResultGroup && selectedCustomResult.matches(':first-child') && customResultGroup.matches(':first-of-type')) {
99
- // If there are native results, Inbox will automatically select
100
- // the last one when it sees this up arrow press, so all we need to do
101
- // is remove the highlighting from our result. If there *aren't* any
102
- // native results, then nothing will be selected, which is consistent
103
- // with native behavior (hitting the up arrow with the first item selected
104
- // leaves *nothing* selected).
105
- selectedCustomResult.classList.remove('inboxsdk__selected');
106
- } else if (hasCustomResults(resultsEl) && !selectedCustomResult) {
107
- event.stopPropagation();
108
- const lastCustomResult = resultsEl.querySelector('.inboxsdk__search_suggestion_group:last-of-type > ' + '.inboxsdk__search_suggestion:last-child');
109
- lastCustomResult && lastCustomResult.classList.add('inboxsdk__selected');
110
- } else if (selectedCustomResult && customResultGroup) {
111
- event.stopPropagation();
112
- selectedCustomResult.classList.remove('inboxsdk__selected');
113
-
114
- // The case where this is the first result in the first group
115
- // has already been handled above, so if this check is true then
116
- // the selected result is the first item in a non-first group.
117
- if (selectedCustomResult.matches(':first-child')) {
118
- const previousResultGroup = customResultGroup.previousElementSibling;
119
- const customResultToSelect = previousResultGroup && previousResultGroup.querySelector('.inboxsdk__search_suggestion:last-child');
120
- customResultToSelect && customResultToSelect.classList.add('inboxsdk__selected');
121
- } else {
122
- const previousCustomResult = selectedCustomResult.previousElementSibling;
123
- previousCustomResult && previousCustomResult.classList.add('inboxsdk__selected');
124
- }
125
- }
126
- });
127
- downArrowPresses.onValue(event => {
128
- const selectedNativeResult = getSelectedNativeResult(resultsEl);
129
- const selectedCustomResult = resultsEl.querySelector('.inboxsdk__search_suggestion.inboxsdk__selected');
130
- const customResultGroup = selectedCustomResult && (0, _closestNg.default)(selectedCustomResult, '.inboxsdk__search_suggestion_group');
131
- if (selectedNativeResult && !selectedNativeResult.matches(':last-of-type')) {
132
- return;
133
- }
134
- if (selectedNativeResult) {
135
- selectFirstCustomResult(resultsEl);
136
- } else if (selectedCustomResult && customResultGroup && selectedCustomResult.matches(':last-child') && customResultGroup.matches(':last-of-type')) {
137
- // Inbox's native behavior is to leave nothing selected when you hit
138
- // the down arrow while the last item is selected, so we don't
139
- // try to select any other results if the last custom result is currently
140
- // selected.
141
- event.stopPropagation();
142
- selectedCustomResult.classList.remove('inboxsdk__selected');
143
- } else if (!selectedCustomResult) {
144
- // Inbox will automatically select the first native result if
145
- // one exists.
146
- if (hasNativeResults(resultsEl)) {
147
- return;
148
- }
149
-
150
- // Theoretically we could stop propegation here, but inbox doesn't do
151
- // anything with the event anyway given that there's no results to select.
152
- selectFirstCustomResult(resultsEl);
153
- } else if (selectedCustomResult && customResultGroup) {
154
- event.stopPropagation();
155
- selectedCustomResult.classList.remove('inboxsdk__selected');
156
-
157
- // The case where this is the last result in the last group
158
- // has already been handled above, so if this check is true then
159
- // the selected result is the last item in a non-last group.
160
- if (selectedCustomResult.matches(':last-child')) {
161
- const nextResultGroup = customResultGroup.nextElementSibling;
162
- const customResultToSelect = nextResultGroup && nextResultGroup.querySelector('.inboxsdk__search_suggestion:first-child');
163
- customResultToSelect && customResultToSelect.classList.add('inboxsdk__selected');
164
- } else {
165
- const nextCustomResult = selectedCustomResult.nextElementSibling;
166
- nextCustomResult && nextCustomResult.classList.add('inboxsdk__selected');
167
- }
168
- }
169
- });
170
- enterPresses.onValue(event => {
171
- const selectedCustomResult = resultsEl.querySelector('.inboxsdk__search_suggestion.inboxsdk__selected');
172
-
173
- // If the user hits enter and has a custom result selected, we want to
174
- // trigger the custom result's action *but* avoid letting the native
175
- // behavior (hiding `resultsEl`) happen.
176
- if (selectedCustomResult) {
177
- event.stopPropagation();
178
- selectedCustomResult.dispatchEvent(new MouseEvent('click'));
179
- }
180
- });
181
- keyboardEvents.onEnd(() => resultsEl.removeAttribute(SELECTION_MASTER_ATTR));
182
- setupCustomResultHoverListeners(resultsEl, resultsElRemovalStream);
183
- }
@@ -1,64 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = setupRouteViewDriverStream;
8
- var _kefir = _interopRequireDefault(require("kefir"));
9
- var _inboxDriver = _interopRequireDefault(require("./inbox-driver"));
10
- var _inboxRouteView = _interopRequireDefault(require("./views/inbox-route-view"));
11
- var _inboxCustomRouteView = _interopRequireDefault(require("./views/inbox-custom-route-view"));
12
- var _inboxDummyRouteView = _interopRequireDefault(require("./views/inbox-dummy-route-view"));
13
- var _routeIDmatchesHash = _interopRequireDefault(require("../../lib/routeIDmatchesHash"));
14
- function setupRouteViewDriverStream(driver) {
15
- const customRouteIDs = driver.getCustomRouteIDs();
16
- let lastRouteView = null;
17
- driver.getStopper().onValue(() => {
18
- if (lastRouteView) {
19
- lastRouteView.destroy();
20
- }
21
- });
22
- return _kefir.default.merge([_kefir.default.merge([_kefir.default.fromEvents(document, 'inboxSDKpushState'), _kefir.default.fromEvents(window, 'popstate')]).map(e => process.env.NODE_ENV === 'test' && e.detail && e.detail.__test_url || document.location.href), _kefir.default.fromEvents(window, 'hashchange').map(e => e.newURL)
23
- // When the user hits back and leaves a hash URL, a hashchange *and*
24
- // popstate events are emitted. Let's just process the popstate event
25
- // alone.
26
- .filter(href => /#/.test(href))]).toProperty(() => document.location.href).map(href => {
27
- const m = /#([^?]*)/.exec(href);
28
- if (!m) return {
29
- type: 'NATIVE'
30
- };
31
- const hash = m[1];
32
- for (let routeIDs of customRouteIDs) {
33
- let routeID = (0, _routeIDmatchesHash.default)(routeIDs, hash);
34
- if (routeID) {
35
- return {
36
- hash,
37
- type: 'CUSTOM',
38
- routeID
39
- };
40
- }
41
- }
42
- return {
43
- type: 'OTHER_APP_CUSTOM'
44
- };
45
- }).map(detail => {
46
- if (detail.type === 'CUSTOM') {
47
- return new _inboxCustomRouteView.default(detail.routeID, detail.hash);
48
- } else if (detail.type === 'NATIVE') {
49
- driver.showNativeRouteView();
50
- return new _inboxDummyRouteView.default('NATIVE');
51
- } else if (detail.type === 'OTHER_APP_CUSTOM') {
52
- return new _inboxDummyRouteView.default('OTHER_APP_CUSTOM');
53
- } else {
54
- driver.getLogger().error(new Error('should not happen'));
55
- return new _inboxDummyRouteView.default('UNKNOWN');
56
- }
57
- }).map(routeView => {
58
- if (lastRouteView) {
59
- lastRouteView.destroy();
60
- }
61
- lastRouteView = routeView;
62
- return routeView;
63
- });
64
- }
@@ -1,72 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- var _lodash = _interopRequireDefault(require("lodash"));
5
- var _pdelay = _interopRequireDefault(require("pdelay"));
6
- var _kefir = _interopRequireDefault(require("kefir"));
7
- var _kefirBus = _interopRequireDefault(require("kefir-bus"));
8
- var _inboxRouteView = _interopRequireDefault(require("./views/inbox-route-view"));
9
- var _inboxCustomRouteView = _interopRequireDefault(require("./views/inbox-custom-route-view"));
10
- var _inboxDummyRouteView = _interopRequireDefault(require("./views/inbox-dummy-route-view"));
11
- var _setupRouteViewDriverStream = _interopRequireDefault(require("./setupRouteViewDriverStream"));
12
- jest.mock('./getSidebarClassnames');
13
- const stopper = (0, _kefirBus.default)();
14
- afterEach(() => {
15
- stopper.emit(null);
16
- });
17
- function makeMockDriver() {
18
- return {
19
- getStopper: _lodash.default.constant(stopper),
20
- getCustomRouteIDs: _lodash.default.constant(new Set()),
21
- showNativeRouteView: jest.fn()
22
- };
23
- }
24
- test('test', async () => {
25
- const items = [];
26
- const driver = makeMockDriver();
27
- driver.getCustomRouteIDs().add('foo/:id');
28
- driver.getCustomRouteIDs().add('bar/:id/blah');
29
- (0, _setupRouteViewDriverStream.default)(driver).takeUntilBy(stopper).onValue(item => {
30
- items.push(item);
31
- });
32
- expect(items.length).toBe(1);
33
- expect(items[0]).toBeInstanceOf(_inboxDummyRouteView.default);
34
- const firstStopper = jest.fn();
35
- items[0].getStopper().onValue(firstStopper);
36
- expect(firstStopper).toHaveBeenCalledTimes(0);
37
- document.dispatchEvent(new CustomEvent('inboxSDKpushState', {
38
- bubbles: false,
39
- cancelable: false,
40
- detail: {
41
- __test_url: 'https://inbox.google.com/u/0/snoozed',
42
- args: ['%5B1%2C%5B%5B11%2C0%2Cfalse%2Cnull%2Cnull%2C0%5D%5D%5D', '', '/u/0/snoozed']
43
- }
44
- }));
45
- expect(items.length).toBe(2);
46
- expect(items[1]).toBeInstanceOf(_inboxDummyRouteView.default);
47
- expect(firstStopper).toHaveBeenCalledTimes(1);
48
- expect(driver.showNativeRouteView).toHaveBeenCalledTimes(2);
49
-
50
- // TODO test breaks here because jest+jsdom now emits popstate event along with HashChangeEvent.
51
- // Might be real bug here.
52
- if (true) return; // eslint-disable-line
53
- document.location.hash = '#bar/123/blah';
54
- await (0, _pdelay.default)(1);
55
- expect(items.length).toBe(3);
56
- expect(items[2]).toBeInstanceOf(_inboxCustomRouteView.default);
57
- expect(items[2].getRouteID()).toBe('bar/:id/blah');
58
- expect(items[2].getParams()).toEqual({
59
- id: '123'
60
- });
61
- expect(driver.showNativeRouteView).toHaveBeenCalledTimes(2);
62
- document.dispatchEvent(new CustomEvent('inboxSDKpushState', {
63
- bubbles: false,
64
- cancelable: false,
65
- detail: {
66
- __test_url: 'https://inbox.google.com/u/0/done',
67
- args: ['%5B1%2C%5B%5B2%2C0%2Cfalse%2Cnull%2Cnull%2C0%5D%5D%5D', '', '/u/0/done']
68
- }
69
- }));
70
- expect(items.length).toBe(4);
71
- expect(items[3]).toBeInstanceOf(_inboxDummyRouteView.default);
72
- });