@inboxsdk/core 0.2.28-alpha.3 → 0.2.28-alpha.4
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.
- package/inboxsdk.js +1 -1
- package/inboxsdk.js.map +1 -1
- package/package.json +1 -1
- package/src/build/exec.js +26 -0
- package/src/build/spawn.js +17 -0
- package/src/common/ajax.js +90 -0
- package/src/common/cachebust-url.js +10 -0
- package/src/common/censorHTMLstring.js +37 -0
- package/src/common/censorHTMLtree.js +28 -0
- package/src/common/censorJSONTree.js +15 -0
- package/src/common/connectivity-test.js +21 -0
- package/src/common/defer.js +11 -0
- package/src/common/find-parent.js +10 -0
- package/src/common/get-extension-id.js +7 -0
- package/src/common/get-or-fail.js +8 -0
- package/src/common/get-session-id.js +14 -0
- package/src/common/get-stack-trace.js +6 -0
- package/src/common/html-to-text.js +7 -0
- package/src/common/isElementVisible.js +6 -0
- package/src/common/load-script.js +127 -0
- package/src/common/log-error.js +191 -0
- package/src/common/quoted-split.js +18 -0
- package/src/common/rate-limit-queuer.js +57 -0
- package/src/common/rate-limit.js +14 -0
- package/src/common/version.js +6 -0
- package/src/inboxsdk-js/loading/platform-implementation-loader.js +27 -0
- package/src/injected-js/gmail/constants.js +2 -0
- package/src/injected-js/gmail/modify-suggestions.js +106 -0
- package/src/injected-js/gmail/setup-gmonkey-handler.js +49 -0
- package/src/injected-js/gmail/sync-compose-processor-20220909.js +298 -0
- package/src/injected-js/gmail/sync-compose-processor.js +55 -0
- package/src/injected-js/gmail/sync-compose-request-processor.js +110 -0
- package/src/injected-js/injected-logger.js +50 -0
- package/src/injected-js/setupCustomViewEventAssassin.js +90 -0
- package/src/platform-implementation-js/constants/nav-item-types.js +19 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-app-menu-item.js +21 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-collapsible-panel.js +28 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-nav-item.js +98 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-support-item.js +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/encodeDraftUrlId.js +8 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/get-rfc-message-id-for-gmail-message-id.js +12 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/get-rfc-message-id-for-gmail-thread-id.js +33 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/isIntegratedViewGmail.js +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/open-draft-by-message-id.js +44 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/track-gmail-styles.js +95 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-element-getter/get-main-content-element-changed-stream.js +38 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-element-getter/wait-for-gmail-mode-to-settle.js +12 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-element-getter.js +253 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-page-communicator.js +200 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-response-processor.js +533 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-sync-response-processor.js +289 -0
- package/src/platform-implementation-js/dom-driver/gmail/is-compose-titlebar-light-color.js +21 -0
- package/src/platform-implementation-js/dom-driver/gmail/makePageParserTree.js +28 -0
- package/src/platform-implementation-js/dom-driver/gmail/pageParserOptions.js +19 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-menu-item-view.js +126 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-status-bar.js +101 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/detectClassicRecipientsArea.js +38 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-address-information-extractor.js +28 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-recipients.js +22 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/gmail-compose-button-view.js +233 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/page-parser.js +223 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/set-recipients.js +157 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/setupLinkPopovers.js +109 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/attachment-icon.js +5 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-nav-item-view.js +759 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-support-item-view.js +84 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/button-color-classes.js +33 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/button-view.js +325 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-accessory-button-view.js +58 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-parent-accessory-button-view.js +55 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/modal-button-view.js +96 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/more-dropdown-button-view.js +30 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/more-parent-accessory-button-view.js +10 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-dropdown-view.js +22 -0
- package/src/platform-implementation-js/driver-common/getAccountUrlPart.js +17 -0
- package/src/platform-implementation-js/driver-common/getOriginalMessagePage.js +33 -0
- package/src/platform-implementation-js/driver-common/getSyncThreadsForSearch.js +49 -0
- package/src/platform-implementation-js/driver-common/gmailAjax.js +65 -0
- package/src/platform-implementation-js/driver-common/render-custom-icon.js +16 -0
- package/src/platform-implementation-js/driver-common/update-icon.js +90 -0
- package/src/platform-implementation-js/lib/ErrorCollector.js +47 -0
- package/src/platform-implementation-js/lib/Membrane.js +22 -0
- package/src/platform-implementation-js/lib/ScrollableContainByScreen.js +30 -0
- package/src/platform-implementation-js/lib/attemptWithRetries.js +16 -0
- package/src/platform-implementation-js/lib/common-page-communicator.js +137 -0
- package/src/platform-implementation-js/lib/delay-asap.js +12 -0
- package/src/platform-implementation-js/lib/delay-idle.js +16 -0
- package/src/platform-implementation-js/lib/dom/block-and-reemit-keyboard-events.js +36 -0
- package/src/platform-implementation-js/lib/dom/generic-button-view.js +39 -0
- package/src/platform-implementation-js/lib/dom/get-insert-before-element.js +39 -0
- package/src/platform-implementation-js/lib/dom/insert-element-in-order.js +38 -0
- package/src/platform-implementation-js/lib/dom/keyboard-shortcut-stream.js +12 -0
- package/src/platform-implementation-js/lib/dom/make-element-child-stream.js +79 -0
- package/src/platform-implementation-js/lib/dom/make-element-stream-merger.js +28 -0
- package/src/platform-implementation-js/lib/dom/make-element-view-stream.js +15 -0
- package/src/platform-implementation-js/lib/dom/make-mutation-observer-chunked-stream.js +15 -0
- package/src/platform-implementation-js/lib/dom/make-mutation-observer-stream.js +5 -0
- package/src/platform-implementation-js/lib/dom/outsideClicksAndEscape.js +39 -0
- package/src/platform-implementation-js/lib/dom/parentNodes.js +8 -0
- package/src/platform-implementation-js/lib/dom/querySelectorOrFail.js +6 -0
- package/src/platform-implementation-js/lib/dom/reemitClickEventForReact.js +22 -0
- package/src/platform-implementation-js/lib/dom/simulate-key.js +46 -0
- package/src/platform-implementation-js/lib/dom/simulate-mouse-event.js +16 -0
- package/src/platform-implementation-js/lib/dom/trigger-relay-event.js +7 -0
- package/src/platform-implementation-js/lib/extract-contact-from-email-contact-string.js +25 -0
- package/src/platform-implementation-js/lib/fake-window-resize.js +5 -0
- package/src/platform-implementation-js/lib/from-event-target-capture.js +12 -0
- package/src/platform-implementation-js/lib/fromEventsWithOptions.js +10 -0
- package/src/platform-implementation-js/lib/handler-registry.js +67 -0
- package/src/platform-implementation-js/lib/idMap.js +45 -0
- package/src/platform-implementation-js/lib/imageRequest.js +8 -0
- package/src/platform-implementation-js/lib/incrementName.js +7 -0
- package/src/platform-implementation-js/lib/inject-script-EMBEDDED.js +14 -0
- package/src/platform-implementation-js/lib/inject-script.js +33 -0
- package/src/platform-implementation-js/lib/is-valid-app-id.js +27 -0
- package/src/platform-implementation-js/lib/is-valid-email.js +14 -0
- package/src/platform-implementation-js/lib/isNotNil.js +5 -0
- package/src/platform-implementation-js/lib/isStreakAppId.js +11 -0
- package/src/platform-implementation-js/lib/logger.js +441 -0
- package/src/platform-implementation-js/lib/persistent-queue.js +107 -0
- package/src/platform-implementation-js/lib/safe-event-emitter.js +17 -0
- package/src/platform-implementation-js/lib/stopper-pool.js +41 -0
- package/src/platform-implementation-js/lib/stream-wait-for.js +30 -0
- package/src/platform-implementation-js/lib/wait-for.js +28 -0
- package/src/platform-implementation-js/lib/waitForAsync.js +19 -0
- package/src/platform-implementation-js/namespaces/app-menu.d.ts.map +1 -1
- package/src/platform-implementation-js/namespaces/app-menu.js +31 -0
- package/src/platform-implementation-js/namespaces/butter-bar.js +163 -0
- package/src/platform-implementation-js/views/SimpleElementView.js +16 -0
- package/src/platform-implementation-js/views/app-menu-item-view.js +257 -0
- package/src/platform-implementation-js/views/collapsible-panel-view.js +222 -0
- package/src/platform-implementation-js/views/compose-button-view.js +45 -0
- package/src/platform-implementation-js/views/compose-view.js +312 -0
- package/src/platform-implementation-js/views/keyboard-shortcut-handle.js +14 -0
- package/src/platform-implementation-js/widgets/buttons/basic-button-view-controller.js +39 -0
- package/src/platform-implementation-js/widgets/buttons/dropdown-button-view-controller.js +98 -0
- package/src/platform-implementation-js/widgets/buttons/dropdown-view.js +122 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import isNotNil from '../../lib/isNotNil';
|
|
3
|
+
export function extractThreadsFromSearchResponse(response) {
|
|
4
|
+
const parsedResponse = JSON.parse(response);
|
|
5
|
+
if (Array.isArray(parsedResponse)) {
|
|
6
|
+
try {
|
|
7
|
+
return extractThreadsFromSearchResponse_20220909(parsedResponse);
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const threadDescriptors = parsedResponse && parsedResponse[3];
|
|
14
|
+
if (!threadDescriptors)
|
|
15
|
+
return [];
|
|
16
|
+
return threadDescriptors
|
|
17
|
+
.map((descriptorWrapper, index) => {
|
|
18
|
+
const descriptor = descriptorWrapper[1];
|
|
19
|
+
if (!descriptor)
|
|
20
|
+
return null;
|
|
21
|
+
return {
|
|
22
|
+
subject: descriptor[1],
|
|
23
|
+
snippet: descriptor[2],
|
|
24
|
+
syncThreadID: descriptor[4],
|
|
25
|
+
// It seems Gmail is A/B testing including gmailThreadID in descriptor[20] and not including
|
|
26
|
+
// the encoded version of it in descriptor[18], so pull it from [20] if [18] is not set.
|
|
27
|
+
oldGmailThreadID: descriptor[18] != null
|
|
28
|
+
? new BigNumber(descriptor[18]).toString(16)
|
|
29
|
+
: descriptor[20],
|
|
30
|
+
rawResponse: descriptorWrapper,
|
|
31
|
+
extraMetaData: {
|
|
32
|
+
snippet: (parsedResponse[15] &&
|
|
33
|
+
parsedResponse[15][1] &&
|
|
34
|
+
parsedResponse[15][1][index]) ||
|
|
35
|
+
'',
|
|
36
|
+
syncMessageData: descriptor[5].map((md) => ({
|
|
37
|
+
syncMessageID: md[1],
|
|
38
|
+
oldMessageID: md[56],
|
|
39
|
+
date: +md[7],
|
|
40
|
+
})),
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
})
|
|
44
|
+
.filter(isNotNil);
|
|
45
|
+
}
|
|
46
|
+
export function extractThreadsFromSearchResponse_20220909(parsedResponse) {
|
|
47
|
+
const threadDescriptors = parsedResponse && parsedResponse[2];
|
|
48
|
+
if (!threadDescriptors)
|
|
49
|
+
return [];
|
|
50
|
+
return threadDescriptors
|
|
51
|
+
.map((descriptorWrapper, index) => {
|
|
52
|
+
const descriptor = descriptorWrapper[0];
|
|
53
|
+
if (!descriptor)
|
|
54
|
+
return null;
|
|
55
|
+
return {
|
|
56
|
+
subject: descriptor[0],
|
|
57
|
+
snippet: descriptor[1],
|
|
58
|
+
syncThreadID: descriptor[3],
|
|
59
|
+
// It seems Gmail is A/B testing including gmailThreadID in descriptor[20] and not including
|
|
60
|
+
// the encoded version of it in descriptor[18], so pull it from [20] if [18] is not set.
|
|
61
|
+
oldGmailThreadID: descriptor[17] != null
|
|
62
|
+
? new BigNumber(descriptor[17]).toString(16)
|
|
63
|
+
: descriptor[19],
|
|
64
|
+
rawResponse: descriptorWrapper,
|
|
65
|
+
extraMetaData: {
|
|
66
|
+
snippet: (parsedResponse[14] &&
|
|
67
|
+
parsedResponse[14][0] &&
|
|
68
|
+
parsedResponse[14][0][index]) ||
|
|
69
|
+
'',
|
|
70
|
+
syncMessageData: descriptor[4].map((md) => ({
|
|
71
|
+
syncMessageID: md[0],
|
|
72
|
+
oldMessageID: md[55],
|
|
73
|
+
date: +md[6],
|
|
74
|
+
})),
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
})
|
|
78
|
+
.filter(isNotNil);
|
|
79
|
+
}
|
|
80
|
+
export function extractThreadsFromThreadResponse(response) {
|
|
81
|
+
const parsedResponse = JSON.parse(response);
|
|
82
|
+
if (Array.isArray(parsedResponse)) {
|
|
83
|
+
return extractThreadsFromThreadResponse_20220909(parsedResponse);
|
|
84
|
+
}
|
|
85
|
+
const threadDescriptors = parsedResponse && parsedResponse[2];
|
|
86
|
+
if (!threadDescriptors)
|
|
87
|
+
throw new Error('Failed to process thread response');
|
|
88
|
+
return threadDescriptors
|
|
89
|
+
.map((descriptorWrapper) => {
|
|
90
|
+
if (typeof descriptorWrapper[1] === 'string' &&
|
|
91
|
+
Array.isArray(descriptorWrapper[3]) &&
|
|
92
|
+
!(descriptorWrapper[2] &&
|
|
93
|
+
descriptorWrapper[2][1] &&
|
|
94
|
+
descriptorWrapper[2][1][14] &&
|
|
95
|
+
Array.isArray(descriptorWrapper[2][2]))) {
|
|
96
|
+
return {
|
|
97
|
+
syncThreadID: descriptorWrapper[1],
|
|
98
|
+
oldGmailThreadID: (descriptorWrapper[2] &&
|
|
99
|
+
descriptorWrapper[2][1] &&
|
|
100
|
+
descriptorWrapper[2][1][16]) ||
|
|
101
|
+
undefined,
|
|
102
|
+
extraMetaData: {
|
|
103
|
+
snippet: (descriptorWrapper[2] &&
|
|
104
|
+
descriptorWrapper[2][1] &&
|
|
105
|
+
descriptorWrapper[2][1][3]) ||
|
|
106
|
+
undefined,
|
|
107
|
+
syncMessageData: (descriptorWrapper[3] || [])
|
|
108
|
+
.filter((md) => Boolean(md[2]))
|
|
109
|
+
.map((md) => ({
|
|
110
|
+
syncMessageID: md[1],
|
|
111
|
+
date: +md[2][17],
|
|
112
|
+
recipients: getRecipientsFromMessageDescriptor(md),
|
|
113
|
+
})),
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const threadDescriptor = descriptorWrapper[2] && descriptorWrapper[2][1];
|
|
119
|
+
if (!threadDescriptor)
|
|
120
|
+
return null;
|
|
121
|
+
let syncMessageData;
|
|
122
|
+
const fullMessageDescriptors = Array.isArray(descriptorWrapper[3]) && descriptorWrapper[3];
|
|
123
|
+
if (fullMessageDescriptors) {
|
|
124
|
+
syncMessageData = fullMessageDescriptors.map((md) => ({
|
|
125
|
+
syncMessageID: md[1],
|
|
126
|
+
date: +md[2][17],
|
|
127
|
+
recipients: getRecipientsFromMessageDescriptor(md),
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const messageDescriptors = descriptorWrapper[2] && descriptorWrapper[2][2];
|
|
132
|
+
syncMessageData = messageDescriptors.map((md) => ({
|
|
133
|
+
syncMessageId: md[1],
|
|
134
|
+
date: +md[16],
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
subject: threadDescriptor[2],
|
|
139
|
+
snippet: threadDescriptor[3],
|
|
140
|
+
syncThreadID: threadDescriptor[1],
|
|
141
|
+
oldGmailThreadID: new BigNumber(threadDescriptor[14]).toString(16),
|
|
142
|
+
rawResponse: descriptorWrapper,
|
|
143
|
+
extraMetaData: {
|
|
144
|
+
syncMessageData,
|
|
145
|
+
snippet: '',
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
.filter(isNotNil);
|
|
151
|
+
}
|
|
152
|
+
function extractThreadsFromThreadResponse_20220909(parsedResponse) {
|
|
153
|
+
const threadDescriptors = parsedResponse && parsedResponse[1];
|
|
154
|
+
if (!threadDescriptors)
|
|
155
|
+
throw new Error('Failed to process thread response');
|
|
156
|
+
return threadDescriptors
|
|
157
|
+
.map((descriptorWrapper) => {
|
|
158
|
+
if (typeof descriptorWrapper[0] === 'string' &&
|
|
159
|
+
Array.isArray(descriptorWrapper[2]) &&
|
|
160
|
+
!(descriptorWrapper[1] &&
|
|
161
|
+
descriptorWrapper[1][0] &&
|
|
162
|
+
descriptorWrapper[1][0][13] &&
|
|
163
|
+
Array.isArray(descriptorWrapper[1][1]))) {
|
|
164
|
+
return {
|
|
165
|
+
syncThreadID: descriptorWrapper[0],
|
|
166
|
+
oldGmailThreadID: (descriptorWrapper[1] &&
|
|
167
|
+
descriptorWrapper[1][0] &&
|
|
168
|
+
descriptorWrapper[1][0][15]) ||
|
|
169
|
+
undefined,
|
|
170
|
+
extraMetaData: {
|
|
171
|
+
snippet: (descriptorWrapper[1] &&
|
|
172
|
+
descriptorWrapper[1][0] &&
|
|
173
|
+
descriptorWrapper[1][0][2]) ||
|
|
174
|
+
undefined,
|
|
175
|
+
syncMessageData: (descriptorWrapper[2] || [])
|
|
176
|
+
.filter((md) => Boolean(md[1]))
|
|
177
|
+
.map((md) => ({
|
|
178
|
+
syncMessageID: md[0],
|
|
179
|
+
date: +md[1][16],
|
|
180
|
+
recipients: getRecipientsFromMessageDescriptor_20220909(md),
|
|
181
|
+
})),
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
const threadDescriptor = descriptorWrapper[1] && descriptorWrapper[1][0];
|
|
187
|
+
if (!threadDescriptor)
|
|
188
|
+
return null;
|
|
189
|
+
let syncMessageData;
|
|
190
|
+
const fullMessageDescriptors = Array.isArray(descriptorWrapper[2]) && descriptorWrapper[2];
|
|
191
|
+
if (fullMessageDescriptors) {
|
|
192
|
+
syncMessageData = fullMessageDescriptors.map((md) => ({
|
|
193
|
+
syncMessageID: md[0],
|
|
194
|
+
date: +md[1][16],
|
|
195
|
+
recipients: getRecipientsFromMessageDescriptor_20220909(md),
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const messageDescriptors = descriptorWrapper[1] && descriptorWrapper[1][1];
|
|
200
|
+
syncMessageData = messageDescriptors.map((md) => ({
|
|
201
|
+
syncMessageId: md[0],
|
|
202
|
+
date: +md[15],
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
subject: threadDescriptor[1],
|
|
207
|
+
snippet: threadDescriptor[2],
|
|
208
|
+
syncThreadID: threadDescriptor[0],
|
|
209
|
+
oldGmailThreadID: new BigNumber(threadDescriptor[13]).toString(16),
|
|
210
|
+
rawResponse: descriptorWrapper,
|
|
211
|
+
extraMetaData: {
|
|
212
|
+
syncMessageData,
|
|
213
|
+
snippet: '',
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
.filter(isNotNil);
|
|
219
|
+
}
|
|
220
|
+
function getRecipientsFromMessageDescriptor(messageDescriptor) {
|
|
221
|
+
if (!messageDescriptor[2])
|
|
222
|
+
return;
|
|
223
|
+
const to = messageDescriptor[2][1] || [];
|
|
224
|
+
const cc = messageDescriptor[2][2] || [];
|
|
225
|
+
const bcc = messageDescriptor[2][3] || [];
|
|
226
|
+
return to
|
|
227
|
+
.concat(cc)
|
|
228
|
+
.concat(bcc)
|
|
229
|
+
.map((recipientDescriptor) => ({
|
|
230
|
+
emailAddress: recipientDescriptor[2],
|
|
231
|
+
name: recipientDescriptor[3],
|
|
232
|
+
}));
|
|
233
|
+
}
|
|
234
|
+
function getRecipientsFromMessageDescriptor_20220909(messageDescriptor) {
|
|
235
|
+
if (!messageDescriptor[1])
|
|
236
|
+
return;
|
|
237
|
+
const to = messageDescriptor[1][0] || [];
|
|
238
|
+
const cc = messageDescriptor[1][1] || [];
|
|
239
|
+
const bcc = messageDescriptor[1][2] || [];
|
|
240
|
+
return to
|
|
241
|
+
.concat(cc)
|
|
242
|
+
.concat(bcc)
|
|
243
|
+
.map((recipientDescriptor) => ({
|
|
244
|
+
emailAddress: recipientDescriptor[1],
|
|
245
|
+
name: recipientDescriptor[2],
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
export function replaceThreadsInSearchResponse(response, replacementThreads, _unused // TODO why is this unused?
|
|
249
|
+
) {
|
|
250
|
+
const parsedResponse = JSON.parse(response);
|
|
251
|
+
if (Array.isArray(parsedResponse)) {
|
|
252
|
+
try {
|
|
253
|
+
return replaceThreadsInSearchResponse_20220909(parsedResponse, replacementThreads, _unused);
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
return response;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (parsedResponse[3] || replacementThreads.length) {
|
|
260
|
+
parsedResponse[3] = replacementThreads.map(({ rawResponse }, index) => ({
|
|
261
|
+
...rawResponse,
|
|
262
|
+
'2': index,
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
if (parsedResponse[15] || replacementThreads.length) {
|
|
266
|
+
parsedResponse[15] = {
|
|
267
|
+
...parsedResponse[15],
|
|
268
|
+
'1': replacementThreads.map(({ extraMetaData }) => extraMetaData.snippet),
|
|
269
|
+
'2': replacementThreads.map(({ extraMetaData }) => extraMetaData.syncMessageData.map(({ syncMessageID }) => syncMessageID)),
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return JSON.stringify(parsedResponse);
|
|
273
|
+
}
|
|
274
|
+
export function replaceThreadsInSearchResponse_20220909(parsedResponse, replacementThreads, _unused // TODO why is this unused?
|
|
275
|
+
) {
|
|
276
|
+
if (parsedResponse[2] || replacementThreads.length) {
|
|
277
|
+
parsedResponse[2] = replacementThreads.map(({ rawResponse }, index) => {
|
|
278
|
+
const res = [...rawResponse];
|
|
279
|
+
res[1] = index;
|
|
280
|
+
return res;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (parsedResponse[14] || replacementThreads.length) {
|
|
284
|
+
parsedResponse[14] = [...parsedResponse[14]];
|
|
285
|
+
parsedResponse[14][0] = replacementThreads.map(({ extraMetaData }) => extraMetaData.snippet);
|
|
286
|
+
parsedResponse[14][1] = replacementThreads.map(({ extraMetaData }) => extraMetaData.syncMessageData.map(({ syncMessageID }) => syncMessageID));
|
|
287
|
+
}
|
|
288
|
+
return JSON.stringify(parsedResponse);
|
|
289
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import once from 'lodash/once';
|
|
2
|
+
function isGmailRuleForTitlebarWideIcons() {
|
|
3
|
+
return !![...document.styleSheets].find((s) => {
|
|
4
|
+
try {
|
|
5
|
+
if (s.cssRules) {
|
|
6
|
+
return [...s.cssRules].find((rule) => rule instanceof CSSStyleRule &&
|
|
7
|
+
rule.selectorText === '.Hl' &&
|
|
8
|
+
rule.style.width === '24px');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
// Some stylesheets are crossorigin and throw if we try to access
|
|
13
|
+
// their rules. Don't worry about them.
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const isComposeTitleBarLightColor = once(() => {
|
|
19
|
+
return !isGmailRuleForTitlebarWideIcons();
|
|
20
|
+
});
|
|
21
|
+
export default isComposeTitleBarLightColor;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import PageParserTree from 'page-parser-tree';
|
|
2
|
+
import udKefir from 'ud-kefir';
|
|
3
|
+
import pageParserOptions from './pageParserOptions';
|
|
4
|
+
import censorHTMLtree from '../../../common/censorHTMLtree';
|
|
5
|
+
const pageParserOptionsStream = udKefir(module, pageParserOptions);
|
|
6
|
+
export default function makePageParserTree(driver, root) {
|
|
7
|
+
const _driver = driver;
|
|
8
|
+
function transformOptions(pageParserOptions) {
|
|
9
|
+
return !_driver
|
|
10
|
+
? pageParserOptions
|
|
11
|
+
: {
|
|
12
|
+
...pageParserOptions,
|
|
13
|
+
logError(err, el) {
|
|
14
|
+
const details = {
|
|
15
|
+
el,
|
|
16
|
+
html: el ? censorHTMLtree(el) : null,
|
|
17
|
+
};
|
|
18
|
+
_driver.getLogger().errorSite(err, details);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const page = new PageParserTree(root, transformOptions(pageParserOptions));
|
|
23
|
+
pageParserOptionsStream.changes().onValue((pageParserOptions) => {
|
|
24
|
+
console.log('replacing PageParserTree options'); //eslint-disable-line no-console
|
|
25
|
+
page.replaceOptions(transformOptions(pageParserOptions));
|
|
26
|
+
});
|
|
27
|
+
return page;
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const pageParserOptions = {
|
|
2
|
+
tags: {},
|
|
3
|
+
watchers: [
|
|
4
|
+
{
|
|
5
|
+
sources: [null],
|
|
6
|
+
tag: 'composeLinkPopOverContainer',
|
|
7
|
+
selectors: ['body', '.Lf.a5s'],
|
|
8
|
+
},
|
|
9
|
+
],
|
|
10
|
+
finders: {
|
|
11
|
+
supportMenu: {
|
|
12
|
+
fn: (root) => root.querySelectorAll('header[role=banner] div:not([aria-label]):not([data-ogsr-up]) > div:not(.inboxsdk__appButton) > div[data-tooltip] + div[role=menu]'),
|
|
13
|
+
},
|
|
14
|
+
composeLinkPopOverContainer: {
|
|
15
|
+
fn: (root) => root.querySelectorAll('body > .Lf.a5s'),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
export default pageParserOptions;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import querySelector from '../../../lib/dom/querySelectorOrFail';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
import GmailElementGetter from '../gmail-element-getter';
|
|
5
|
+
export const NATIVE_CLASS = 'Xa';
|
|
6
|
+
export const INBOXSDK_CLASS = 'inboxsdk__appMenuItem';
|
|
7
|
+
export const ELEMENT_CLASS = `${NATIVE_CLASS} ${INBOXSDK_CLASS}`;
|
|
8
|
+
const ICON_ELEMENT_CLASS = 'V6 CL';
|
|
9
|
+
const HEADING_ELEMENT_CLASS = 'apW';
|
|
10
|
+
const ICON_ELEMENT_SELECTOR = '.V6.CL';
|
|
11
|
+
const HEADING_ELEMENT_SELECTOR = '.apW';
|
|
12
|
+
export class GmailAppMenuItemView extends EventEmitter {
|
|
13
|
+
static elementCss = {
|
|
14
|
+
HOVER: 'aIk',
|
|
15
|
+
ACTIVE: 'apV',
|
|
16
|
+
};
|
|
17
|
+
#menuItemDescriptor;
|
|
18
|
+
#element;
|
|
19
|
+
#destroyed = false;
|
|
20
|
+
#driver;
|
|
21
|
+
get element() {
|
|
22
|
+
return this.#element;
|
|
23
|
+
}
|
|
24
|
+
setMenuItemDescriptor(newMenuItemDescriptor) {
|
|
25
|
+
this.#menuItemDescriptor = newMenuItemDescriptor;
|
|
26
|
+
this.#update();
|
|
27
|
+
}
|
|
28
|
+
get menuItemDescriptor() {
|
|
29
|
+
return this.#menuItemDescriptor;
|
|
30
|
+
}
|
|
31
|
+
constructor(driver) {
|
|
32
|
+
super();
|
|
33
|
+
this.#element = this.#setupElement();
|
|
34
|
+
this.#driver = driver;
|
|
35
|
+
driver.getStopper().onValue(() => this.remove());
|
|
36
|
+
this.#element.addEventListener('click', (e) => this.#onClick(e));
|
|
37
|
+
this.#element.addEventListener('mouseover', this.#onHover);
|
|
38
|
+
this.#element.addEventListener('mouseout', this.#onBlur);
|
|
39
|
+
}
|
|
40
|
+
remove() {
|
|
41
|
+
if (this.#destroyed)
|
|
42
|
+
return;
|
|
43
|
+
this.#destroyed = true;
|
|
44
|
+
this.element?.remove();
|
|
45
|
+
this.emit('destroy');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
blur() {
|
|
51
|
+
this.element?.classList.remove(GmailAppMenuItemView.elementCss.HOVER);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
hover() {
|
|
57
|
+
if (this.element?.classList.contains(GmailAppMenuItemView.elementCss.ACTIVE)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.element?.classList.add(GmailAppMenuItemView.elementCss.HOVER);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
activate() {
|
|
66
|
+
this.element?.classList.remove(GmailAppMenuItemView.elementCss.HOVER);
|
|
67
|
+
this.element?.classList.add(GmailAppMenuItemView.elementCss.ACTIVE);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
deactivate() {
|
|
73
|
+
this.element?.classList.remove(GmailAppMenuItemView.elementCss.ACTIVE);
|
|
74
|
+
}
|
|
75
|
+
#setupElement() {
|
|
76
|
+
const element = document.createElement('div');
|
|
77
|
+
element.className = ELEMENT_CLASS;
|
|
78
|
+
element.innerHTML = `
|
|
79
|
+
<div class="${ICON_ELEMENT_CLASS}" aria-label="" role="link" tabindex="-1"></div>
|
|
80
|
+
<div class="${HEADING_ELEMENT_CLASS}" role="heading" aria-level="2"></div>
|
|
81
|
+
`.trim();
|
|
82
|
+
return element;
|
|
83
|
+
}
|
|
84
|
+
#update() {
|
|
85
|
+
const element = this.element;
|
|
86
|
+
if (!element)
|
|
87
|
+
return;
|
|
88
|
+
element.className = cx(ELEMENT_CLASS, this.#menuItemDescriptor?.className);
|
|
89
|
+
this.#updateName(element);
|
|
90
|
+
this.#updateIcon(element);
|
|
91
|
+
this.#updateARIA(element);
|
|
92
|
+
}
|
|
93
|
+
#updateName(element) {
|
|
94
|
+
const headingElement = querySelector(element, HEADING_ELEMENT_SELECTOR);
|
|
95
|
+
headingElement.textContent = this.#menuItemDescriptor?.name ?? '';
|
|
96
|
+
}
|
|
97
|
+
#updateIcon(element) {
|
|
98
|
+
const iconContainerEl = querySelector(element, ICON_ELEMENT_SELECTOR);
|
|
99
|
+
const { iconUrl, iconClassName } = this.#menuItemDescriptor ?? {};
|
|
100
|
+
if (iconUrl) {
|
|
101
|
+
const theme = GmailElementGetter.isDarkTheme()
|
|
102
|
+
? iconUrl.darkTheme
|
|
103
|
+
: iconUrl.lightTheme;
|
|
104
|
+
iconContainerEl.style.setProperty('--background-image', `url(${theme})`);
|
|
105
|
+
}
|
|
106
|
+
iconContainerEl.className = cx(ICON_ELEMENT_CLASS, iconClassName);
|
|
107
|
+
}
|
|
108
|
+
#updateARIA(element) {
|
|
109
|
+
const iconContainerEl = querySelector(element, ICON_ELEMENT_SELECTOR);
|
|
110
|
+
iconContainerEl.setAttribute('aria-label', this.#menuItemDescriptor?.name ?? '');
|
|
111
|
+
}
|
|
112
|
+
#onClick(e) {
|
|
113
|
+
this.emit('click');
|
|
114
|
+
this.#menuItemDescriptor?.onClick?.(e);
|
|
115
|
+
if (this.#menuItemDescriptor?.routeID) {
|
|
116
|
+
this.#driver.goto(this.#menuItemDescriptor.routeID, this.#menuItemDescriptor?.routeParams);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
#onBlur = (e) => {
|
|
120
|
+
this.emit('blur', e);
|
|
121
|
+
};
|
|
122
|
+
#onHover = (e) => {
|
|
123
|
+
this.emit('hover', e);
|
|
124
|
+
this.#menuItemDescriptor?.onHover?.(e);
|
|
125
|
+
};
|
|
126
|
+
}
|
package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-status-bar.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { defn } from 'ud';
|
|
2
|
+
import Kefir from 'kefir';
|
|
3
|
+
import kefirStopper from 'kefir-stopper';
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import insertElementInOrder from '../../../../lib/dom/insert-element-in-order';
|
|
6
|
+
import Logger from '../../../../lib/logger';
|
|
7
|
+
import querySelector from '../../../../lib/dom/querySelectorOrFail';
|
|
8
|
+
import SimpleElementView from '../../../../views/SimpleElementView';
|
|
9
|
+
export default defn(module, addStatusBar);
|
|
10
|
+
function addStatusBar(gmailComposeView, options) {
|
|
11
|
+
const { height, orderHint, addAboveNativeStatusBar } = {
|
|
12
|
+
height: 40,
|
|
13
|
+
orderHint: 0,
|
|
14
|
+
addAboveNativeStatusBar: false,
|
|
15
|
+
...options,
|
|
16
|
+
};
|
|
17
|
+
const statusbar = new StatusBar(gmailComposeView, height, orderHint, addAboveNativeStatusBar);
|
|
18
|
+
gmailComposeView
|
|
19
|
+
.getStopper()
|
|
20
|
+
.takeUntilBy(Kefir.fromEvents(statusbar, 'destroy'))
|
|
21
|
+
.onValue(() => statusbar.destroy());
|
|
22
|
+
return statusbar;
|
|
23
|
+
}
|
|
24
|
+
function createElement(orderHint, addAboveNativeStatusBar) {
|
|
25
|
+
const el = document.createElement('div');
|
|
26
|
+
el.className = cx('aDh', 'inboxsdk__compose_statusbar', {
|
|
27
|
+
inboxsdk__addAboveNative: addAboveNativeStatusBar,
|
|
28
|
+
});
|
|
29
|
+
el.style.fontFamily = 'Roboto,RobotoDraft,Helvetica,Arial,sans-serif';
|
|
30
|
+
el.style.fontSize = '15.6px';
|
|
31
|
+
el.setAttribute('data-order-hint', String(orderHint));
|
|
32
|
+
return el;
|
|
33
|
+
}
|
|
34
|
+
class StatusBar extends SimpleElementView {
|
|
35
|
+
_addAboveNativeStatusBar;
|
|
36
|
+
_gmailComposeView;
|
|
37
|
+
_nativeStatusContainer;
|
|
38
|
+
_prependContainer = null;
|
|
39
|
+
_stopper = kefirStopper();
|
|
40
|
+
constructor(gmailComposeView, height, orderHint, addAboveNativeStatusBar) {
|
|
41
|
+
super(createElement(orderHint, addAboveNativeStatusBar));
|
|
42
|
+
this._addAboveNativeStatusBar = addAboveNativeStatusBar;
|
|
43
|
+
this._gmailComposeView = gmailComposeView;
|
|
44
|
+
this._nativeStatusContainer = querySelector(gmailComposeView.getElement(), '.iN > tbody .aDj');
|
|
45
|
+
this._setStatusBar();
|
|
46
|
+
this.setHeight(height);
|
|
47
|
+
}
|
|
48
|
+
destroy() {
|
|
49
|
+
if (this.destroyed) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
super.destroy();
|
|
53
|
+
this._stopper.destroy();
|
|
54
|
+
if (this._prependContainer &&
|
|
55
|
+
this._prependContainer.children.length === 0) {
|
|
56
|
+
this._prependContainer.remove();
|
|
57
|
+
}
|
|
58
|
+
this._updateTotalHeight();
|
|
59
|
+
}
|
|
60
|
+
setHeight(newHeight) {
|
|
61
|
+
this.el.style.height = newHeight + 'px';
|
|
62
|
+
this._updateTotalHeight();
|
|
63
|
+
}
|
|
64
|
+
_updateTotalHeight() {
|
|
65
|
+
const totalAddedStatusBarHeight = Array.from(this._gmailComposeView
|
|
66
|
+
.getElement()
|
|
67
|
+
.querySelectorAll('.inboxsdk__compose_statusbar'))
|
|
68
|
+
.map((el) => el.getBoundingClientRect().height)
|
|
69
|
+
.reduce((a, b) => a + b, 0);
|
|
70
|
+
this._gmailComposeView
|
|
71
|
+
.getElement()
|
|
72
|
+
.style.setProperty('--inboxsdk-total-added-statusbar-height', totalAddedStatusBarHeight + 'px');
|
|
73
|
+
}
|
|
74
|
+
_setStatusBar() {
|
|
75
|
+
try {
|
|
76
|
+
const statusArea = this._gmailComposeView.getStatusArea();
|
|
77
|
+
this._gmailComposeView
|
|
78
|
+
.getElement()
|
|
79
|
+
.classList.add('inboxsdk__compose_statusbarActive');
|
|
80
|
+
if (this._addAboveNativeStatusBar) {
|
|
81
|
+
const prependContainer = (this._prependContainer =
|
|
82
|
+
statusArea.querySelector('.inboxsdk__compose_statusBarPrependContainer') || document.createElement('div'));
|
|
83
|
+
prependContainer.classList.add('inboxsdk__compose_statusBarPrependContainer');
|
|
84
|
+
statusArea.insertAdjacentElement('afterbegin', prependContainer);
|
|
85
|
+
insertElementInOrder(prependContainer, this.el);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
if (this._gmailComposeView.isInlineReplyForm()) {
|
|
89
|
+
const nativeStatusBar = querySelector(this._gmailComposeView.getElement(), '.iN > tbody .aDj .aDh .IZ');
|
|
90
|
+
insertElementInOrder(nativeStatusBar, this.el);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
insertElementInOrder(statusArea, this.el);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
Logger.error(err);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import once from 'lodash/once';
|
|
2
|
+
export default once(function detectClassicRecipientsArea() {
|
|
3
|
+
const styleSheetWithComposeRules = [...document.styleSheets].find((s) => {
|
|
4
|
+
try {
|
|
5
|
+
if (s.cssRules) {
|
|
6
|
+
// Both classic and new recipients Gmail should have this rule
|
|
7
|
+
return [...s.cssRules].find((rule) => rule instanceof CSSStyleRule &&
|
|
8
|
+
rule.selectorText === '.aoI' &&
|
|
9
|
+
rule.style.fontSize &&
|
|
10
|
+
rule.style.color);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
// Some stylesheets are crossorigin and throw if we try to access
|
|
15
|
+
// their rules. Don't worry about them.
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
});
|
|
19
|
+
if (styleSheetWithComposeRules) {
|
|
20
|
+
// Check if we don't have any of these specific rules.
|
|
21
|
+
// If so, we're on classic recipients Gmail.
|
|
22
|
+
const hasOverflowYVisibleRule = [
|
|
23
|
+
...styleSheetWithComposeRules.cssRules,
|
|
24
|
+
].some((rule) => rule instanceof CSSStyleRule &&
|
|
25
|
+
rule.selectorText === '.aoI' &&
|
|
26
|
+
rule.style.overflowY === 'visible');
|
|
27
|
+
if (hasOverflowYVisibleRule) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const hasOverflowYAutoRule = [...styleSheetWithComposeRules.cssRules].some((rule) => rule instanceof CSSStyleRule &&
|
|
31
|
+
rule.selectorText === '.aaZ > .M9 > .aoI' &&
|
|
32
|
+
rule.style.overflowY === 'auto');
|
|
33
|
+
if (hasOverflowYAutoRule) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
document.body.classList.add('inboxsdk__classic_gmail_recipients_area');
|
|
37
|
+
}
|
|
38
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Logger from '../../../../lib/logger';
|
|
2
|
+
import extractContactFromEmailContactString from '../../../../lib/extract-contact-from-email-contact-string';
|
|
3
|
+
import censorHTMLstring from '../../../../../common/censorHTMLstring';
|
|
4
|
+
export default function getAddressInformationExtractor(addressType, composeView) {
|
|
5
|
+
return function (node) {
|
|
6
|
+
const contactNode = node instanceof HTMLInputElement &&
|
|
7
|
+
node.getAttribute('name') === addressType
|
|
8
|
+
? node
|
|
9
|
+
: node.querySelector(`input[name='${addressType}']`);
|
|
10
|
+
if (contactNode) {
|
|
11
|
+
var contactInfoString = contactNode.value;
|
|
12
|
+
try {
|
|
13
|
+
return extractContactFromEmailContactString(contactInfoString);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
// The user might have typed in a partial address. We can just ignore that.
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
Logger.error(new Error(`contactNode can't be found`), {
|
|
22
|
+
addressType,
|
|
23
|
+
composeViewHtml: censorHTMLstring(composeView.getElement().outerHTML),
|
|
24
|
+
});
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-recipients.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getRecipientChips } from './page-parser';
|
|
2
|
+
import getAddressInformationExtractor from './get-address-information-extractor';
|
|
3
|
+
import isNotNil from '../../../../lib/isNotNil';
|
|
4
|
+
export default function getRecipients(gmailComposeView, addressType) {
|
|
5
|
+
const contactNodes = getRecipientChips(gmailComposeView.getElement(), addressType);
|
|
6
|
+
return Array.from(contactNodes)
|
|
7
|
+
.map((contactNode) => {
|
|
8
|
+
if (contactNode.getAttribute('role') === 'option') {
|
|
9
|
+
// new recipient
|
|
10
|
+
// https://workspaceupdates.googleblog.com/2021/10/visual-updates-for-composing-email-in-gmail.html
|
|
11
|
+
return {
|
|
12
|
+
name: contactNode.getAttribute('data-name'),
|
|
13
|
+
emailAddress: contactNode.getAttribute('data-hovercard-id'),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// old
|
|
18
|
+
return getAddressInformationExtractor(addressType, gmailComposeView)(contactNode);
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
.filter(isNotNil);
|
|
22
|
+
}
|