@inboxsdk/core 1.1.5 → 1.1.7
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/background.js +1 -0
- package/inboxsdk.js +31 -36
- package/inboxsdk.js.map +1 -1
- package/package.json +1 -1
- package/pageWorld.js +1 -1
- package/pageWorld.js.map +1 -1
- package/src/inboxsdk-js/header.d.ts +19 -0
- package/src/inboxsdk-js/header.d.ts.map +1 -0
- package/src/inboxsdk-js/header.js +1 -1
- package/src/inboxsdk.d.ts +10 -10
- package/src/injected-js/gmail/constants.d.ts +1 -1
- package/src/injected-js/gmail/constants.d.ts.map +1 -1
- package/src/injected-js/gmail/setup-gmail-interceptor.d.ts +3 -4
- package/src/injected-js/gmail/setup-gmail-interceptor.d.ts.map +1 -0
- package/src/injected-js/gmail/setup-gmail-interceptor.js +896 -896
- package/src/injected-js/gmail/sync-compose-processor-20220909.d.ts +1 -1
- package/src/injected-js/gmail/sync-compose-processor-20220909.d.ts.map +1 -1
- package/src/injected-js/gmail/sync-compose-processor.d.ts +3 -3
- package/src/injected-js/gmail/sync-compose-request-processor.d.ts.map +1 -1
- package/src/injected-js/gmail/sync-compose-request-processor.js +0 -1
- package/src/injected-js/gmail/thread-identifier/click-and-get-popup-url.d.ts +2 -0
- package/src/injected-js/gmail/thread-identifier/click-and-get-popup-url.d.ts.map +1 -0
- package/src/injected-js/gmail/thread-identifier/click-and-get-popup-url.js +66 -78
- package/src/injected-js/gmail/thread-identifier/index.d.ts +3 -0
- package/src/injected-js/gmail/thread-identifier/index.d.ts.map +1 -0
- package/src/injected-js/gmail/thread-identifier/index.js +100 -98
- package/src/injected-js/gmail/thread-identifier/thread-row-parser.d.ts +7 -0
- package/src/injected-js/gmail/thread-identifier/thread-row-parser.d.ts.map +1 -0
- package/src/injected-js/gmail/thread-identifier/thread-row-parser.js +51 -61
- package/src/injected-js/main.d.ts +2 -0
- package/src/injected-js/main.d.ts.map +1 -0
- package/src/injected-js/main.js +44 -43
- package/src/injected-js/message-metadata-holder.d.ts +7 -0
- package/src/injected-js/message-metadata-holder.d.ts.map +1 -0
- package/src/injected-js/message-metadata-holder.js +89 -97
- package/src/injected-js/setup-data-exposer.d.ts +2 -0
- package/src/injected-js/setup-data-exposer.d.ts.map +1 -0
- package/src/injected-js/setup-data-exposer.js +126 -118
- package/src/injected-js/setup-error-silencer.d.ts +2 -0
- package/src/injected-js/setup-error-silencer.d.ts.map +1 -0
- package/src/injected-js/setup-error-silencer.js +16 -24
- package/src/injected-js/setup-event-reemitter.d.ts +2 -0
- package/src/injected-js/setup-event-reemitter.d.ts.map +1 -0
- package/src/injected-js/setup-event-reemitter.js +46 -59
- package/src/injected-js/setupInboxCustomViewLinkFixer.d.ts +2 -0
- package/src/injected-js/setupInboxCustomViewLinkFixer.d.ts.map +1 -0
- package/src/injected-js/setupInboxCustomViewLinkFixer.js +24 -26
- package/src/injected-js/setupPushStateListener.d.ts +2 -0
- package/src/injected-js/setupPushStateListener.d.ts.map +1 -0
- package/src/injected-js/setupPushStateListener.js +14 -23
- package/src/injected-js/xhr-helper.d.ts +2 -0
- package/src/injected-js/xhr-helper.d.ts.map +1 -0
- package/src/injected-js/xhr-helper.js +73 -83
- package/src/injected-js/xhr-proxy-factory.d.ts +97 -0
- package/src/injected-js/xhr-proxy-factory.d.ts.map +1 -0
- package/src/injected-js/xhr-proxy-factory.js +503 -451
- package/src/platform-implementation-js/constants/router.d.ts +37 -5
- package/src/platform-implementation-js/constants/router.d.ts.map +1 -0
- package/src/platform-implementation-js/constants/router.js +57 -60
- package/src/platform-implementation-js/constants/toolbars.d.ts +2 -0
- package/src/platform-implementation-js/constants/toolbars.d.ts.map +1 -0
- package/src/platform-implementation-js/constants/toolbars.js +4 -11
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-toolbar-button-for-app.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-toolbar-button-for-app.js +0 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/get-url-object.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/get-url-object.js +0 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/getSyncThreadForOldGmailThreadId.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/getSyncThreadForOldGmailThreadId.js +0 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/getSyncThreadFromSyncThreadId.d.ts +4 -6
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/getSyncThreadFromSyncThreadId.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/getSyncThreadFromSyncThreadId.js +55 -62
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/gmail-load-event.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/gmail-load-event.js +0 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/goto-view.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/goto-view.js +0 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/setup-route-view-driver-stream.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/setup-route-view-driver-stream.js +4 -5
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/thread-row-identifier.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/thread-row-identifier.js +4 -9
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/track-events.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/track-events.js +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/user-info.d.ts +2 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/user-info.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/user-info.js +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver.d.ts +4 -3
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/make-xhr-interceptor.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/make-xhr-interceptor.js +0 -1
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/index.d.ts +19 -6
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/index.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/index.js +75 -80
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-companion-global-icon-area.d.ts +5 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-companion-global-icon-area.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-companion-global-icon-area.js +13 -22
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-companion-thread-icon-area.d.ts +5 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-companion-thread-icon-area.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-companion-thread-icon-area.js +18 -26
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-to-icon-area.d.ts +5 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-to-icon-area.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/add-to-icon-area.js +13 -30
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/index.d.ts +44 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/index.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/primary/index.js +681 -601
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-toolbar-button-view/monitor-top-banner-size-and-react.d.ts +2 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-toolbar-button-view/monitor-top-banner-size-and-react.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-toolbar-button-view/monitor-top-banner-size-and-react.js +23 -24
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-toolbar-button-view.d.ts +19 -3
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-toolbar-button-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-toolbar-button-view.js +156 -150
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-area-view.d.ts +20 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-area-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-area-view.js +101 -96
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-card-view.d.ts +40 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-card-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-card-view.js +287 -265
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-collapsible-section-view.d.ts +61 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-collapsible-section-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-collapsible-section-view.js +689 -524
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-button.d.ts +5 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-button.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-button.js +124 -118
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-compose-notice.d.ts +15 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-compose-notice.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-compose-notice.js +47 -51
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-inner-sidebar.d.ts +8 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-inner-sidebar.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-inner-sidebar.js +8 -16
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-outer-sidebar.d.ts +8 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-outer-sidebar.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-outer-sidebar.js +23 -31
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-recipient-row.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-recipient-row.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-recipient-row.js +61 -66
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-tooltip-to-button.d.ts +6 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-tooltip-to-button.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/add-tooltip-to-button.js +64 -48
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/ensure-app-button-toolbars-are-closed.d.ts +2 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/ensure-app-button-toolbars-are-closed.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/ensure-app-button-toolbars-are-closed.js +10 -17
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/ensure-grouping-is-open.d.ts +2 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/ensure-grouping-is-open.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/ensure-grouping-is-open.js +14 -23
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/focus.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/focus.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/focus.js +13 -16
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/from-manager.d.ts +7 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/from-manager.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/from-manager.js +57 -59
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-additional-action-toolbar.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-additional-action-toolbar.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-additional-action-toolbar.js +49 -49
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-address-changes-stream.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-address-changes-stream.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-address-changes-stream.js +89 -89
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-address-information-extractor.d.ts +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-address-information-extractor.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-body-changes-stream.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-body-changes-stream.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-body-changes-stream.js +13 -21
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-formatting-area-offset-left.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-formatting-area-offset-left.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-formatting-area-offset-left.js +16 -23
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-minimized-stream.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-minimized-stream.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-minimized-stream.js +14 -22
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-recipients.d.ts +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-recipients.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-response-type-changes-stream.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-response-type-changes-stream.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/get-response-type-changes-stream.js +23 -29
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/insert-link-into-body.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/insert-link-into-body.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/insert-link-into-body.js +17 -25
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/manage-button-grouping.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/manage-button-grouping.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/manage-button-grouping.js +317 -252
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/monitor-selection-range.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/monitor-selection-range.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/monitor-selection-range.js +22 -18
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/override-edit-subject.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/override-edit-subject.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/override-edit-subject.js +57 -50
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/position-formatting-toolbar.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/position-formatting-toolbar.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/position-formatting-toolbar.js +18 -20
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/size-fixer.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/size-fixer.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/size-fixer.js +114 -113
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/update-insert-more-area-left.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/update-insert-more-area-left.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view/update-insert-more-area-left.js +15 -18
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view.d.ts +189 -118
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-compose-view.js +1480 -1333
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/attachment-icon.d.ts +1 -2
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/attachment-icon.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/attachment-icon.js +1 -2
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/get-updated-contact.d.ts +3 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/get-updated-contact.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view/get-updated-contact.js +69 -70
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view.d.ts +67 -6
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-message-view.js +715 -637
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-route-view/gmail-route-processor.d.ts +44 -6
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-route-view/gmail-route-processor.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-route-view/gmail-route-processor.js +100 -101
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-route-view/gmail-route-view.d.ts +72 -3
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-route-view/gmail-route-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-route-view/gmail-route-view.js +502 -438
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-row-list-view.d.ts +39 -8
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-row-list-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-row-list-view.js +229 -211
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-row-view.d.ts +117 -5
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-row-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-row-view.js +938 -821
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view/add-icon-area.d.ts +5 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view/add-icon-area.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view/add-icon-area.js +66 -61
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view.d.ts +18 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view.js +520 -457
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-view/width-manager.d.ts +7 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-view/width-manager.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-view/width-manager.js +24 -27
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-view.d.ts +69 -7
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-view.js +646 -523
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-toolbar-view.d.ts +58 -11
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-toolbar-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-toolbar-view.js +436 -383
- package/src/platform-implementation-js/dom-driver/gmail/views/native-gmail-nav-item-view.d.ts +35 -7
- package/src/platform-implementation-js/dom-driver/gmail/views/native-gmail-nav-item-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/views/native-gmail-nav-item-view.js +265 -235
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-accessory-button-view.d.ts +2 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-accessory-button-view.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-accessory-button-view.js +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-parent-accessory-button-view.d.ts +2 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-parent-accessory-button-view.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/create-parent-accessory-button-view.js +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/inbox-dropdown-button-view.d.ts +7 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/inbox-dropdown-button-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/inbox-dropdown-button-view.js +22 -30
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/modal-button-view.d.ts +4 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/modal-button-view.d.ts.map +1 -1
- package/src/platform-implementation-js/dom-driver/gmail/widgets/buttons/modal-button-view.js +6 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-action-button-view.d.ts +11 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-action-button-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-action-button-view.js +35 -41
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-label-view.d.ts +18 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-label-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-label-view.js +96 -97
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-mole-view-driver.d.ts +18 -15
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-mole-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-mole-view-driver.js +170 -170
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-tooltip-view.d.ts +47 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-tooltip-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/gmail/widgets/gmail-tooltip-view.js +325 -279
- package/src/platform-implementation-js/dom-driver/inbox/views/inbox-backdrop.d.ts +16 -0
- package/src/platform-implementation-js/dom-driver/inbox/views/inbox-backdrop.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/inbox/views/inbox-backdrop.js +56 -61
- package/src/platform-implementation-js/dom-driver/inbox/views/inbox-drawer-view.d.ts +31 -3
- package/src/platform-implementation-js/dom-driver/inbox/views/inbox-drawer-view.d.ts.map +1 -0
- package/src/platform-implementation-js/dom-driver/inbox/views/inbox-drawer-view.js +275 -252
- package/src/platform-implementation-js/driver-common/compose/getDiscardStream.d.ts +6 -0
- package/src/platform-implementation-js/driver-common/compose/getDiscardStream.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/compose/getDiscardStream.js +27 -32
- package/src/platform-implementation-js/driver-common/compose/getPresendingStream.d.ts +7 -0
- package/src/platform-implementation-js/driver-common/compose/getPresendingStream.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/compose/getPresendingStream.js +45 -43
- package/src/platform-implementation-js/driver-common/getGmailMessageIdForSyncMessageId.d.ts +5 -6
- package/src/platform-implementation-js/driver-common/getGmailMessageIdForSyncMessageId.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/getGmailMessageIdForSyncMessageId.js +11 -19
- package/src/platform-implementation-js/driver-common/getGmailThreadIdForRfcMessageId.d.ts +5 -6
- package/src/platform-implementation-js/driver-common/getGmailThreadIdForRfcMessageId.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/getGmailThreadIdForRfcMessageId.js +39 -48
- package/src/platform-implementation-js/driver-common/getRfcMessageIdForSyncMessageId.d.ts +5 -0
- package/src/platform-implementation-js/driver-common/getRfcMessageIdForSyncMessageId.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/getRfcMessageIdForSyncMessageId.js +12 -20
- package/src/platform-implementation-js/driver-common/getThreadIdFromMessageId.d.ts +5 -0
- package/src/platform-implementation-js/driver-common/getThreadIdFromMessageId.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/getThreadIdFromMessageId.js +11 -19
- package/src/platform-implementation-js/driver-common/inboxAjax.d.ts +4 -0
- package/src/platform-implementation-js/driver-common/inboxAjax.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/inboxAjax.js +5 -13
- package/src/platform-implementation-js/driver-common/requestGmailThread.d.ts +4 -0
- package/src/platform-implementation-js/driver-common/requestGmailThread.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/requestGmailThread.js +22 -32
- package/src/platform-implementation-js/driver-common/sidebar/AppSidebar.d.ts +50 -0
- package/src/platform-implementation-js/driver-common/sidebar/AppSidebar.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/sidebar/AppSidebar.js +228 -279
- package/src/platform-implementation-js/driver-common/sidebar/ContentPanelViewDriver.d.ts +25 -1
- package/src/platform-implementation-js/driver-common/sidebar/ContentPanelViewDriver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-common/sidebar/ContentPanelViewDriver.js +142 -147
- package/src/platform-implementation-js/driver-interfaces/compose-view-driver.d.ts +106 -133
- package/src/platform-implementation-js/driver-interfaces/compose-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-interfaces/compose-view-driver.js +1 -1
- package/src/platform-implementation-js/driver-interfaces/driver.d.ts +31 -139
- package/src/platform-implementation-js/driver-interfaces/driver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-interfaces/driver.js +1 -1
- package/src/platform-implementation-js/driver-interfaces/message-view-driver.d.ts +44 -0
- package/src/platform-implementation-js/driver-interfaces/message-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-interfaces/message-view-driver.js +1 -5
- package/src/platform-implementation-js/driver-interfaces/mole-view-driver.d.ts +18 -20
- package/src/platform-implementation-js/driver-interfaces/mole-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-interfaces/mole-view-driver.js +1 -1
- package/src/platform-implementation-js/driver-interfaces/route-view-driver.d.ts +19 -0
- package/src/platform-implementation-js/driver-interfaces/route-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-interfaces/route-view-driver.js +1 -1
- package/src/platform-implementation-js/driver-interfaces/thread-row-view-driver.d.ts +11 -0
- package/src/platform-implementation-js/driver-interfaces/thread-row-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/driver-interfaces/thread-row-view-driver.js +1 -1
- package/src/platform-implementation-js/lib/css-selector-escape.d.ts +2 -0
- package/src/platform-implementation-js/lib/css-selector-escape.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/css-selector-escape.js +6 -12
- package/src/platform-implementation-js/lib/delay-asap.d.ts +1 -1
- package/src/platform-implementation-js/lib/delay-asap.d.ts.map +1 -1
- package/src/platform-implementation-js/lib/delay-asap.js +0 -2
- package/src/platform-implementation-js/lib/dom/get-selection.d.ts +3 -0
- package/src/platform-implementation-js/lib/dom/get-selection.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/dom/get-selection.js +22 -24
- package/src/platform-implementation-js/lib/dom/insert-html-at-cursor.d.ts +3 -0
- package/src/platform-implementation-js/lib/dom/insert-html-at-cursor.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/dom/insert-html-at-cursor.js +78 -75
- package/src/platform-implementation-js/lib/dom/is-node-in-range.d.ts +2 -0
- package/src/platform-implementation-js/lib/dom/is-node-in-range.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/dom/is-node-in-range.js +12 -17
- package/src/platform-implementation-js/lib/dom/make-element-stream-merger.d.ts.map +1 -1
- package/src/platform-implementation-js/lib/dom/set-css.d.ts +2 -0
- package/src/platform-implementation-js/lib/dom/set-css.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/dom/set-css.js +18 -23
- package/src/platform-implementation-js/lib/dom/set-value-and-dispatch-event.d.ts +2 -0
- package/src/platform-implementation-js/lib/dom/set-value-and-dispatch-event.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/dom/set-value-and-dispatch-event.js +6 -12
- package/src/platform-implementation-js/lib/dom/simulate-drag-and-drop.d.ts +4 -0
- package/src/platform-implementation-js/lib/dom/simulate-drag-and-drop.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/dom/simulate-drag-and-drop.js +84 -93
- package/src/platform-implementation-js/lib/extract-contact-from-email-contact-string.d.ts +1 -1
- package/src/platform-implementation-js/lib/extract-contact-from-email-contact-string.d.ts.map +1 -1
- package/src/platform-implementation-js/lib/handle-compose-link-chips.d.ts +4 -0
- package/src/platform-implementation-js/lib/handle-compose-link-chips.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/handle-compose-link-chips.js +106 -97
- package/src/platform-implementation-js/lib/inject-script-EMBEDDED.d.ts.map +1 -1
- package/src/platform-implementation-js/lib/inject-script-EMBEDDED.js +1 -1
- package/src/platform-implementation-js/lib/insert-link-chip-into-body.d.ts +4 -0
- package/src/platform-implementation-js/lib/insert-link-chip-into-body.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/insert-link-chip-into-body.js +32 -39
- package/src/platform-implementation-js/lib/logger.d.ts +1 -0
- package/src/platform-implementation-js/lib/logger.d.ts.map +1 -1
- package/src/platform-implementation-js/lib/parseParamsFromRouteID.d.ts +2 -0
- package/src/platform-implementation-js/lib/parseParamsFromRouteID.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/parseParamsFromRouteID.js +12 -18
- package/src/platform-implementation-js/lib/populateRouteID.d.ts +2 -5
- package/src/platform-implementation-js/lib/populateRouteID.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/populateRouteID.js +16 -21
- package/src/platform-implementation-js/lib/react/ElementContainer.d.ts +15 -0
- package/src/platform-implementation-js/lib/react/ElementContainer.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/react/ElementContainer.js +24 -36
- package/src/platform-implementation-js/lib/routeIDmatchesHash.d.ts +2 -4
- package/src/platform-implementation-js/lib/routeIDmatchesHash.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/routeIDmatchesHash.js +8 -15
- package/src/platform-implementation-js/lib/toItemWithLifetimeStream.d.ts +2 -4
- package/src/platform-implementation-js/lib/toItemWithLifetimeStream.d.ts.map +1 -0
- package/src/platform-implementation-js/lib/toItemWithLifetimeStream.js +12 -19
- package/src/platform-implementation-js/main-INTEGRATED-PAGEWORLD.js +1 -1
- package/src/platform-implementation-js/main.d.ts.map +1 -1
- package/src/platform-implementation-js/main.js +1 -4
- package/src/platform-implementation-js/namespaces/compose.d.ts +13 -0
- package/src/platform-implementation-js/namespaces/compose.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/compose.js +56 -61
- package/src/platform-implementation-js/namespaces/conversations.d.ts +24 -0
- package/src/platform-implementation-js/namespaces/conversations.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/conversations.js +79 -78
- package/src/platform-implementation-js/namespaces/global.d.ts +11 -0
- package/src/platform-implementation-js/namespaces/global.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/global.js +28 -36
- package/src/platform-implementation-js/namespaces/keyboard.d.ts +11 -0
- package/src/platform-implementation-js/namespaces/keyboard.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/keyboard.js +27 -40
- package/src/platform-implementation-js/namespaces/lists.d.ts +14 -0
- package/src/platform-implementation-js/namespaces/lists.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/lists.js +38 -50
- package/src/platform-implementation-js/namespaces/modal.d.ts +10 -0
- package/src/platform-implementation-js/namespaces/modal.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/modal.js +40 -48
- package/src/platform-implementation-js/namespaces/nav-menu.d.ts +16 -0
- package/src/platform-implementation-js/namespaces/nav-menu.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/nav-menu.js +29 -36
- package/src/platform-implementation-js/namespaces/router.d.ts +50 -1
- package/src/platform-implementation-js/namespaces/router.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/router.js +126 -137
- package/src/platform-implementation-js/namespaces/search.d.ts +7 -0
- package/src/platform-implementation-js/namespaces/search.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/search.js +25 -34
- package/src/platform-implementation-js/namespaces/toolbars.d.ts +15 -0
- package/src/platform-implementation-js/namespaces/toolbars.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/toolbars.js +138 -140
- package/src/platform-implementation-js/namespaces/user.d.ts +13 -0
- package/src/platform-implementation-js/namespaces/user.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/user.js +53 -62
- package/src/platform-implementation-js/namespaces/widgets.d.ts +16 -0
- package/src/platform-implementation-js/namespaces/widgets.d.ts.map +1 -0
- package/src/platform-implementation-js/namespaces/widgets.js +68 -77
- package/src/platform-implementation-js/platform-implementation.d.ts +54 -126
- package/src/platform-implementation-js/platform-implementation.d.ts.map +1 -0
- package/src/platform-implementation-js/platform-implementation.js +176 -147
- package/src/platform-implementation-js/views/app-toolbar-button-view.d.ts +11 -0
- package/src/platform-implementation-js/views/app-toolbar-button-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/app-toolbar-button-view.js +42 -51
- package/src/platform-implementation-js/views/collapsible-section-view.d.ts +12 -0
- package/src/platform-implementation-js/views/collapsible-section-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/collapsible-section-view.js +58 -86
- package/src/platform-implementation-js/views/compose-view.d.ts +2 -1
- package/src/platform-implementation-js/views/compose-view.d.ts.map +1 -1
- package/src/platform-implementation-js/views/content-panel-view.d.ts +12 -0
- package/src/platform-implementation-js/views/content-panel-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/content-panel-view.js +35 -50
- package/src/platform-implementation-js/views/conversations/attachment-card-view.d.ts +18 -0
- package/src/platform-implementation-js/views/conversations/attachment-card-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/conversations/attachment-card-view.js +39 -44
- package/src/platform-implementation-js/views/conversations/custom-message-view.d.ts +28 -0
- package/src/platform-implementation-js/views/conversations/custom-message-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/conversations/custom-message-view.js +115 -103
- package/src/platform-implementation-js/views/conversations/message-view.d.ts +34 -0
- package/src/platform-implementation-js/views/conversations/message-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/conversations/message-view.js +197 -209
- package/src/platform-implementation-js/views/conversations/thread-view.d.ts +23 -0
- package/src/platform-implementation-js/views/conversations/thread-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/conversations/thread-view.js +93 -100
- package/src/platform-implementation-js/views/native-nav-item-view.d.ts +11 -0
- package/src/platform-implementation-js/views/native-nav-item-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/native-nav-item-view.js +56 -62
- package/src/platform-implementation-js/views/nav-item-view.d.ts +12 -22
- package/src/platform-implementation-js/views/nav-item-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/nav-item-view.js +123 -124
- package/src/platform-implementation-js/views/route-view/custom-route-view.d.ts +9 -0
- package/src/platform-implementation-js/views/route-view/custom-route-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/route-view/custom-route-view.js +24 -36
- package/src/platform-implementation-js/views/route-view/dummy-route-view-driver.d.ts +14 -0
- package/src/platform-implementation-js/views/route-view/dummy-route-view-driver.d.ts.map +1 -0
- package/src/platform-implementation-js/views/route-view/dummy-route-view-driver.js +27 -38
- package/src/platform-implementation-js/views/route-view/list-route-view.d.ts +13 -0
- package/src/platform-implementation-js/views/route-view/list-route-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/route-view/list-route-view.js +41 -51
- package/src/platform-implementation-js/views/route-view/route-view.d.ts +11 -0
- package/src/platform-implementation-js/views/route-view/route-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/route-view/route-view.js +41 -51
- package/src/platform-implementation-js/views/section-view.d.ts +11 -0
- package/src/platform-implementation-js/views/section-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/section-view.js +56 -81
- package/src/platform-implementation-js/views/thread-row-view.d.ts +27 -0
- package/src/platform-implementation-js/views/thread-row-view.d.ts.map +1 -0
- package/src/platform-implementation-js/views/thread-row-view.js +87 -94
- package/src/platform-implementation-js/widgets/buttons/basic-button-view-controller.d.ts +4 -0
- package/src/platform-implementation-js/widgets/buttons/basic-button-view-controller.d.ts.map +1 -1
- package/src/platform-implementation-js/widgets/drawer-view.d.ts +13 -0
- package/src/platform-implementation-js/widgets/drawer-view.d.ts.map +1 -0
- package/src/platform-implementation-js/widgets/drawer-view.js +46 -53
- package/src/platform-implementation-js/widgets/modal-view.d.ts +18 -0
- package/src/platform-implementation-js/widgets/modal-view.d.ts.map +1 -0
- package/src/platform-implementation-js/widgets/modal-view.js +95 -91
- package/src/platform-implementation-js/widgets/mole-view.d.ts +12 -0
- package/src/platform-implementation-js/widgets/mole-view.d.ts.map +1 -0
- package/src/platform-implementation-js/widgets/mole-view.js +37 -46
- package/src/platform-implementation-js/widgets/top-message-bar-view.d.ts +8 -0
- package/src/platform-implementation-js/widgets/top-message-bar-view.d.ts.map +1 -0
- package/src/platform-implementation-js/widgets/top-message-bar-view.js +13 -21
- package/src/injected-js/gmail/modify-suggestions.test.js +0 -20
- package/src/injected-js/gmail/sync-compose-request-processor.test.js +0 -80
- package/src/injected-js/gmail/thread-identifier/thread-row-parser.test.js +0 -41
- package/src/injected-js/xhr-proxy-factory.test.js +0 -1052
- package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/open-draft-by-message-id.test.js +0 -22
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-sidebar-view/index.test.js +0 -125
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-attachment-card-view.test.js +0 -141
- package/src/platform-implementation-js/dom-driver/gmail/views/gmail-thread-sidebar-view.test.js +0 -209
- package/src/platform-implementation-js/lib/array-to-lifetimes.js +0 -69
- package/src/platform-implementation-js/lib/array-to-lifetimes.test.js +0 -155
- package/src/platform-implementation-js/lib/dom/querySelectorOne.js +0 -13
- package/src/platform-implementation-js/lib/extract-contact-from-email-contact-string.test.js +0 -39
- package/src/platform-implementation-js/lib/make-revocable-function.js +0 -38
- package/src/platform-implementation-js/lib/make-revocable-function.test.js +0 -61
- package/src/platform-implementation-js/lib/parseParamsFromRouteID.test.js +0 -19
- package/src/platform-implementation-js/lib/populateRouteID.test.js +0 -32
- package/src/platform-implementation-js/lib/routeIDmatchesHash.test.js +0 -17
|
@@ -1,1379 +1,1526 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var _ensureAppButtonToolbarsAreClosed = _interopRequireDefault(require("./gmail-compose-view/ensure-app-button-toolbars-are-closed"));
|
|
43
|
-
var _sizeFixer = _interopRequireDefault(require("./gmail-compose-view/size-fixer"));
|
|
44
|
-
var _addTooltipToButton = _interopRequireDefault(require("./gmail-compose-view/add-tooltip-to-button"));
|
|
45
|
-
var _addRecipientRow = _interopRequireDefault(require("./gmail-compose-view/add-recipient-row"));
|
|
46
|
-
var _addButton = _interopRequireDefault(require("./gmail-compose-view/add-button"));
|
|
47
|
-
var _setRecipients = _interopRequireDefault(require("./gmail-compose-view/set-recipients"));
|
|
48
|
-
var _focus = _interopRequireDefault(require("./gmail-compose-view/focus"));
|
|
49
|
-
var _monitorSelectionRange = _interopRequireDefault(require("./gmail-compose-view/monitor-selection-range"));
|
|
50
|
-
var _manageButtonGrouping = _interopRequireDefault(require("./gmail-compose-view/manage-button-grouping"));
|
|
51
|
-
var _getSelection = require("../../../lib/dom/get-selection");
|
|
52
|
-
var _getMinimizedStream = _interopRequireDefault(require("./gmail-compose-view/get-minimized-stream"));
|
|
53
|
-
var _censorHTMLstring = _interopRequireDefault(require("../../../../common/censorHTMLstring"));
|
|
54
|
-
var _insertLinkIntoBody = _interopRequireDefault(require("./gmail-compose-view/insert-link-into-body"));
|
|
55
|
-
var _getAddressChangesStream = _interopRequireDefault(require("./gmail-compose-view/get-address-changes-stream"));
|
|
56
|
-
var _getBodyChangesStream = _interopRequireDefault(require("./gmail-compose-view/get-body-changes-stream"));
|
|
57
|
-
var _getRecipients = _interopRequireDefault(require("./gmail-compose-view/get-recipients"));
|
|
58
|
-
var _getResponseTypeChangesStream = _interopRequireDefault(require("./gmail-compose-view/get-response-type-changes-stream"));
|
|
59
|
-
var _getPresendingStream = _interopRequireDefault(require("../../../driver-common/compose/getPresendingStream"));
|
|
60
|
-
var _getDiscardStream = _interopRequireDefault(require("../../../driver-common/compose/getDiscardStream"));
|
|
61
|
-
var _updateInsertMoreAreaLeft = _interopRequireDefault(require("./gmail-compose-view/update-insert-more-area-left"));
|
|
62
|
-
var _setupLinkPopovers = _interopRequireDefault(require("./gmail-compose-view/setupLinkPopovers"));
|
|
63
|
-
var _getFormattingAreaOffsetLeft = _interopRequireDefault(require("./gmail-compose-view/get-formatting-area-offset-left"));
|
|
64
|
-
var _overrideEditSubject = _interopRequireDefault(require("./gmail-compose-view/override-edit-subject"));
|
|
65
|
-
var _detectClassicRecipientsArea = _interopRequireDefault(require("./gmail-compose-view/detectClassicRecipientsArea"));
|
|
66
|
-
var _censorHTMLtree = _interopRequireDefault(require("../../../../common/censorHTMLtree"));
|
|
67
|
-
var _pageParser = require("./gmail-compose-view/page-parser");
|
|
68
|
-
var _pageParserTree = _interopRequireDefault(require("page-parser-tree"));
|
|
69
|
-
var _tagTree = require("tag-tree");
|
|
70
|
-
var fromManager = _interopRequireWildcard(require("./gmail-compose-view/from-manager"));
|
|
71
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
72
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
+
import autoHtml from 'auto-html';
|
|
4
|
+
import t from 'transducers.js';
|
|
5
|
+
import once from 'lodash/once';
|
|
6
|
+
import escape from 'lodash/escape';
|
|
7
|
+
import includes from 'lodash/includes';
|
|
8
|
+
import constant from 'lodash/constant';
|
|
9
|
+
import find from 'lodash/find';
|
|
10
|
+
import asap from 'asap';
|
|
11
|
+
import delay from 'pdelay';
|
|
12
|
+
import * as Kefir from 'kefir';
|
|
13
|
+
import closest from 'closest-ng';
|
|
14
|
+
import kefirBus from 'kefir-bus';
|
|
15
|
+
import kefirStopper from 'kefir-stopper';
|
|
16
|
+
import delayAsap from '../../../lib/delay-asap';
|
|
17
|
+
import { simulateClick } from '../../../lib/dom/simulate-mouse-event';
|
|
18
|
+
import simulateKey from '../../../lib/dom/simulate-key';
|
|
19
|
+
import querySelector from '../../../lib/dom/querySelectorOrFail';
|
|
20
|
+
import isElementVisible from '../../../../common/isElementVisible';
|
|
21
|
+
import makeElementChildStream from '../../../lib/dom/make-element-child-stream';
|
|
22
|
+
import { simulateDragOver, simulateDrop, simulateDragEnd, } from '../../../lib/dom/simulate-drag-and-drop';
|
|
23
|
+
import * as GmailResponseProcessor from '../gmail-response-processor';
|
|
24
|
+
import GmailElementGetter from '../gmail-element-getter';
|
|
25
|
+
import setCss from '../../../lib/dom/set-css';
|
|
26
|
+
import waitFor from '../../../lib/wait-for';
|
|
27
|
+
import streamWaitFor from '../../../lib/stream-wait-for';
|
|
28
|
+
import makeMutationObserverChunkedStream from '../../../lib/dom/make-mutation-observer-chunked-stream';
|
|
29
|
+
import handleComposeLinkChips from '../../../lib/handle-compose-link-chips';
|
|
30
|
+
import insertLinkChipIntoBody from '../../../lib/insert-link-chip-into-body';
|
|
31
|
+
import addComposeNotice from './gmail-compose-view/add-compose-notice';
|
|
32
|
+
import addStatusBar from './gmail-compose-view/add-status-bar';
|
|
33
|
+
import insertHTMLatCursor from '../../../lib/dom/insert-html-at-cursor';
|
|
34
|
+
import ensureGroupingIsOpen from './gmail-compose-view/ensure-grouping-is-open';
|
|
35
|
+
import ensureAppButtonToolbarsAreClosed from './gmail-compose-view/ensure-app-button-toolbars-are-closed';
|
|
36
|
+
import sizeFixer from './gmail-compose-view/size-fixer';
|
|
37
|
+
import addTooltipToButton from './gmail-compose-view/add-tooltip-to-button';
|
|
38
|
+
import addRecipientRow from './gmail-compose-view/add-recipient-row';
|
|
39
|
+
import addButton from './gmail-compose-view/add-button';
|
|
40
|
+
import setRecipients from './gmail-compose-view/set-recipients';
|
|
41
|
+
import focus from './gmail-compose-view/focus';
|
|
73
42
|
// import addOuterSidebar from './gmail-compose-view/add-outer-sidebar';
|
|
43
|
+
import monitorSelectionRange from './gmail-compose-view/monitor-selection-range';
|
|
44
|
+
import manageButtonGrouping from './gmail-compose-view/manage-button-grouping';
|
|
45
|
+
import { getSelectedHTMLInElement, getSelectedTextInElement, } from '../../../lib/dom/get-selection';
|
|
46
|
+
import getMinimizedStream from './gmail-compose-view/get-minimized-stream';
|
|
47
|
+
import censorHTMLstring from '../../../../common/censorHTMLstring';
|
|
48
|
+
import insertLinkIntoBody from './gmail-compose-view/insert-link-into-body';
|
|
49
|
+
import getAddressChangesStream from './gmail-compose-view/get-address-changes-stream';
|
|
50
|
+
import getBodyChangesStream from './gmail-compose-view/get-body-changes-stream';
|
|
51
|
+
import getRecipients from './gmail-compose-view/get-recipients';
|
|
52
|
+
import getResponseTypeChangesStream from './gmail-compose-view/get-response-type-changes-stream';
|
|
53
|
+
import getPresendingStream from '../../../driver-common/compose/getPresendingStream';
|
|
54
|
+
import getDiscardStream from '../../../driver-common/compose/getDiscardStream';
|
|
55
|
+
import updateInsertMoreAreaLeft from './gmail-compose-view/update-insert-more-area-left';
|
|
56
|
+
import setupLinkPopOvers from './gmail-compose-view/setupLinkPopovers';
|
|
57
|
+
import getFormattingAreaOffsetLeft from './gmail-compose-view/get-formatting-area-offset-left';
|
|
58
|
+
import overrideEditSubject from './gmail-compose-view/override-edit-subject';
|
|
59
|
+
import detectClassicRecipientsArea from './gmail-compose-view/detectClassicRecipientsArea';
|
|
60
|
+
import { makePageParser, getRecipientRowElements, } from './gmail-compose-view/page-parser';
|
|
61
|
+
import * as fromManager from './gmail-compose-view/from-manager';
|
|
74
62
|
let hasReportedMissingBody = false;
|
|
75
63
|
class GmailComposeView {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
64
|
+
_element;
|
|
65
|
+
_seenBodyElement;
|
|
66
|
+
_isInlineReplyForm;
|
|
67
|
+
_isFullscreen;
|
|
68
|
+
_isStandalone;
|
|
69
|
+
_emailWasSent;
|
|
70
|
+
_driver;
|
|
71
|
+
_managedViewControllers;
|
|
72
|
+
_eventStream;
|
|
73
|
+
_isTriggeringADraftSavePending;
|
|
74
|
+
_buttonViewControllerTooltipMap;
|
|
75
|
+
_composeID;
|
|
76
|
+
_messageIDElement;
|
|
77
|
+
_messageId;
|
|
78
|
+
_finalMessageId; // Set only after the message is sent.
|
|
79
|
+
_initialMessageId;
|
|
80
|
+
_targetMessageID;
|
|
81
|
+
_draftSaving;
|
|
82
|
+
_draftIDpromise;
|
|
83
|
+
_threadID;
|
|
84
|
+
_stopper;
|
|
85
|
+
_lastSelectionRange;
|
|
86
|
+
_requestModifiers;
|
|
87
|
+
_isListeningToAjaxInterceptStream;
|
|
88
|
+
_formattingArea;
|
|
89
|
+
_closedProgrammatically = false;
|
|
90
|
+
_destroyed = false;
|
|
91
|
+
_removedFromDOMStopper;
|
|
92
|
+
_hasSetupLinkPopOvers = false;
|
|
93
|
+
_page;
|
|
94
|
+
tagTree;
|
|
95
|
+
ready;
|
|
96
|
+
constructor(element, xhrInterceptorStream, driver, options) {
|
|
97
|
+
this;
|
|
98
|
+
this._element = element;
|
|
99
|
+
this._element.classList.add('inboxsdk__compose');
|
|
100
|
+
if (options.isInlineReplyForm) {
|
|
101
|
+
this._element.classList.add('inboxsdk__compose_inlineReply');
|
|
102
|
+
}
|
|
103
|
+
this._isInlineReplyForm = options.isInlineReplyForm;
|
|
104
|
+
this._isStandalone = options.isStandalone;
|
|
105
|
+
this._isFullscreen = false;
|
|
106
|
+
this._emailWasSent = false;
|
|
107
|
+
this._messageId = null;
|
|
108
|
+
this._finalMessageId = null;
|
|
109
|
+
this._draftSaving = false;
|
|
110
|
+
this._draftIDpromise = null;
|
|
111
|
+
this._driver = driver;
|
|
112
|
+
this._stopper = kefirStopper();
|
|
113
|
+
this._managedViewControllers = [];
|
|
114
|
+
this._requestModifiers = {};
|
|
115
|
+
this._isListeningToAjaxInterceptStream = false;
|
|
116
|
+
this._eventStream = kefirBus();
|
|
117
|
+
this._removedFromDOMStopper = kefirStopper();
|
|
118
|
+
this._isTriggeringADraftSavePending = false;
|
|
119
|
+
this._page = makePageParser(element, driver.getLogger());
|
|
120
|
+
this.tagTree = this._page.tree;
|
|
121
|
+
let saveAndSendStream;
|
|
122
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
123
|
+
saveAndSendStream = xhrInterceptorStream // we know _getDraftIDfromForm will work because by the time we're
|
|
124
|
+
// getting an ajax event Gmail's JS has generated an ID and added it to the DOM.
|
|
125
|
+
.filter((event) => event.draftID === this._getDraftIDfromForm())
|
|
126
|
+
.map((event) => {
|
|
127
|
+
switch (event.type) {
|
|
128
|
+
case 'emailSending': {
|
|
129
|
+
return {
|
|
130
|
+
eventName: 'sending',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
case 'emailSent': {
|
|
134
|
+
const syncThreadID = event.threadID;
|
|
135
|
+
const syncMessageID = event.messageID;
|
|
136
|
+
if (event.oldMessageID)
|
|
137
|
+
this._messageId = event.oldMessageID;
|
|
138
|
+
if (event.oldThreadID)
|
|
139
|
+
this._threadID = event.oldThreadID;
|
|
140
|
+
driver.removeCachedGmailMessageIdForSyncMessageId(syncMessageID);
|
|
141
|
+
driver.removeCachedOldGmailThreadIdFromSyncThreadId(syncThreadID);
|
|
142
|
+
return {
|
|
143
|
+
eventName: 'sent',
|
|
144
|
+
data: {
|
|
145
|
+
getThreadID: once(async () => {
|
|
146
|
+
if (event.oldThreadID) {
|
|
147
|
+
return event.oldThreadID;
|
|
148
|
+
}
|
|
149
|
+
return await driver.getOldGmailThreadIdFromSyncThreadId(syncThreadID);
|
|
150
|
+
}),
|
|
151
|
+
getMessageID: once(async () => {
|
|
152
|
+
if (event.oldMessageID) {
|
|
153
|
+
return event.oldMessageID;
|
|
154
|
+
}
|
|
155
|
+
return await driver.getGmailMessageIdForSyncMessageId(syncMessageID);
|
|
156
|
+
}),
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
case 'emailSendFailed': {
|
|
161
|
+
return {
|
|
162
|
+
eventName: 'sendCanceled',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
case 'emailDraftReceived': {
|
|
166
|
+
this._messageId = event.oldMessageID;
|
|
167
|
+
this._threadID = event.oldThreadID;
|
|
168
|
+
return {
|
|
169
|
+
eventName: 'draftSaved',
|
|
170
|
+
data: {
|
|
171
|
+
getThreadID() {
|
|
172
|
+
return Promise.resolve(event.oldThreadID);
|
|
173
|
+
},
|
|
174
|
+
getMessageID() {
|
|
175
|
+
return Promise.resolve(event.oldMessageID);
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
133
179
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
getMessageID: (0, _once.default)(async () => {
|
|
137
|
-
if (event.oldMessageID) {
|
|
138
|
-
return event.oldMessageID;
|
|
180
|
+
default: {
|
|
181
|
+
return null;
|
|
139
182
|
}
|
|
140
|
-
return await driver.getGmailMessageIdForSyncMessageId(syncMessageID);
|
|
141
|
-
})
|
|
142
183
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
184
|
+
})
|
|
185
|
+
.filter(Boolean);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
saveAndSendStream = xhrInterceptorStream
|
|
189
|
+
.filter((event) => event.composeId === this.getComposeID())
|
|
190
|
+
.map((event) => {
|
|
191
|
+
switch (event.type) {
|
|
192
|
+
case 'emailSending': {
|
|
193
|
+
return [
|
|
194
|
+
{
|
|
195
|
+
eventName: 'sending',
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
}
|
|
199
|
+
case 'emailSent': {
|
|
200
|
+
const response = GmailResponseProcessor.interpretSentEmailResponse(event.response);
|
|
201
|
+
if (includes(['tr', 'eu'], response.messageID)) {
|
|
202
|
+
return [
|
|
203
|
+
{
|
|
204
|
+
eventName: 'sendCanceled',
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
}
|
|
208
|
+
this._emailWasSent = true;
|
|
209
|
+
if (response.messageID) {
|
|
210
|
+
this._finalMessageId = response.messageID;
|
|
211
|
+
}
|
|
212
|
+
this._messageId = null;
|
|
213
|
+
const data = {
|
|
214
|
+
getThreadID: () => Promise.resolve(response.threadID),
|
|
215
|
+
getMessageID: () => Promise.resolve(response.messageID),
|
|
216
|
+
};
|
|
217
|
+
['threadID', 'gmailThreadId'].forEach((prop) => {
|
|
218
|
+
// These properties are nonenumerable.
|
|
219
|
+
Object.defineProperty(data, prop, {
|
|
220
|
+
get: () => {
|
|
221
|
+
this._driver
|
|
222
|
+
.getLogger()
|
|
223
|
+
.deprecationWarning(`composeView sent event.${prop}`, 'composeView sent event.getThreadID()');
|
|
224
|
+
return response.threadID;
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
['messageID', 'gmailMessageId'].forEach((prop) => {
|
|
229
|
+
Object.defineProperty(data, prop, {
|
|
230
|
+
get: () => {
|
|
231
|
+
this._driver
|
|
232
|
+
.getLogger()
|
|
233
|
+
.deprecationWarning(`composeView sent event.${prop}`, 'composeView sent event.getMessageID()');
|
|
234
|
+
return response.messageID;
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
return [
|
|
239
|
+
{
|
|
240
|
+
eventName: 'sent',
|
|
241
|
+
data,
|
|
242
|
+
},
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
case 'emailDraftSaveSending': {
|
|
246
|
+
this._draftSaving = true;
|
|
247
|
+
return [
|
|
248
|
+
{
|
|
249
|
+
eventName: 'draftSaving',
|
|
250
|
+
},
|
|
251
|
+
];
|
|
252
|
+
}
|
|
253
|
+
case 'emailDraftReceived': {
|
|
254
|
+
this._draftSaving = false;
|
|
255
|
+
let response;
|
|
256
|
+
try {
|
|
257
|
+
response = GmailResponseProcessor.interpretSentEmailResponse(event.response);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
if (this._driver.getAppId() === 'sdk_streak_21e9788951') {
|
|
261
|
+
this._driver.getLogger().error(err, {
|
|
262
|
+
connectionDetails: event.connectionDetails,
|
|
263
|
+
response: event.response,
|
|
264
|
+
});
|
|
265
|
+
throw err;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
throw err;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (response.messageID === 'eu') {
|
|
272
|
+
return []; // save was canceled
|
|
273
|
+
}
|
|
274
|
+
const events = [
|
|
275
|
+
{
|
|
276
|
+
eventName: 'draftSaved',
|
|
277
|
+
data: response,
|
|
278
|
+
},
|
|
279
|
+
];
|
|
280
|
+
if (!response.messageID) {
|
|
281
|
+
this._driver
|
|
282
|
+
.getLogger()
|
|
283
|
+
.error(new Error('Missing message id from emailDraftReceived'));
|
|
284
|
+
}
|
|
285
|
+
else if (response.messageID &&
|
|
286
|
+
this._messageId !== response.messageID) {
|
|
287
|
+
if (/^[0-9a-f]+$/i.test(response.messageID)) {
|
|
288
|
+
this._messageId = response.messageID;
|
|
289
|
+
events.push({
|
|
290
|
+
eventName: 'messageIDChange',
|
|
291
|
+
data: this._messageId,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
this._driver
|
|
296
|
+
.getLogger()
|
|
297
|
+
.error(new Error('Invalid message id from emailDraftReceived'), {
|
|
298
|
+
value: response.messageID,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return events;
|
|
303
|
+
}
|
|
304
|
+
default:
|
|
305
|
+
return [];
|
|
306
|
+
}
|
|
307
|
+
})
|
|
308
|
+
.flatten()
|
|
309
|
+
.map((event) => {
|
|
310
|
+
if (this._driver.getLogger().shouldTrackEverything()) {
|
|
311
|
+
driver.getLogger().eventSite('compose.debug.xhr', {
|
|
312
|
+
eventName: event.eventName,
|
|
313
|
+
});
|
|
164
314
|
}
|
|
165
|
-
|
|
315
|
+
return event;
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
this._eventStream.plug(Kefir.merge([
|
|
319
|
+
saveAndSendStream,
|
|
320
|
+
Kefir.fromEvents(this._element, 'buttonAdded').map(() => {
|
|
321
|
+
return {
|
|
322
|
+
eventName: 'buttonAdded',
|
|
323
|
+
};
|
|
324
|
+
}),
|
|
325
|
+
Kefir.fromEvents(this._element, 'resize').map(() => ({
|
|
326
|
+
eventName: 'resize',
|
|
327
|
+
})),
|
|
328
|
+
Kefir.fromEvents(this._element, 'composeFullscreenStateChanged').map(() => {
|
|
329
|
+
this._updateComposeFullscreenState();
|
|
330
|
+
return {
|
|
331
|
+
eventName: 'fullscreenChanged',
|
|
332
|
+
data: {
|
|
333
|
+
fullscreen: this._isFullscreen,
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
}),
|
|
337
|
+
]));
|
|
338
|
+
Kefir.fromEvents(this._element, 'closedProgrammatically')
|
|
339
|
+
.takeUntilBy(this._stopper)
|
|
340
|
+
.onValue(() => {
|
|
341
|
+
this._closedProgrammatically = true;
|
|
342
|
+
});
|
|
343
|
+
this._buttonViewControllerTooltipMap = new WeakMap();
|
|
344
|
+
const initialBodyElement = this.getMaybeBodyElement();
|
|
345
|
+
this.ready = constant((initialBodyElement
|
|
346
|
+
? Kefir.constant(initialBodyElement)
|
|
347
|
+
: streamWaitFor(() => this.getMaybeBodyElement(), 3 * 60 * 1000 //timeout
|
|
348
|
+
))
|
|
349
|
+
.takeUntilBy(this._stopper)
|
|
350
|
+
.map((bodyElement) => {
|
|
351
|
+
this._seenBodyElement = bodyElement;
|
|
352
|
+
this._composeID = this._element.querySelector('input[name="composeid"]').value;
|
|
353
|
+
this._messageIDElement = this._element.querySelector('input[name="draft"]');
|
|
354
|
+
if (!this._messageIDElement) {
|
|
355
|
+
driver
|
|
356
|
+
.getLogger()
|
|
357
|
+
.error(new Error('Could not find compose message id field'));
|
|
358
|
+
// stub so other things don't fail
|
|
359
|
+
this._messageIDElement = document.createElement('input');
|
|
166
360
|
}
|
|
167
|
-
|
|
361
|
+
this._setupIDs();
|
|
362
|
+
this._setupStreams();
|
|
363
|
+
this._setupConsistencyCheckers();
|
|
364
|
+
this._updateComposeFullscreenState();
|
|
168
365
|
{
|
|
169
|
-
|
|
366
|
+
// try and handle the case where the user types in a bad email address
|
|
367
|
+
// we get the presending event but then no other events will pass because
|
|
368
|
+
// a modal comes up informing the user of the bad email address
|
|
369
|
+
this.getEventStream()
|
|
370
|
+
.filter(({ eventName }) => eventName === 'presending')
|
|
371
|
+
.takeUntilBy(this._stopper)
|
|
372
|
+
.onValue(() => {
|
|
373
|
+
makeElementChildStream(document.body)
|
|
374
|
+
.map((event) => event.el)
|
|
375
|
+
.filter((node) => node.getAttribute &&
|
|
376
|
+
node.getAttribute('role') === 'alertdialog')
|
|
377
|
+
.takeUntilBy(Kefir.merge([
|
|
378
|
+
this.getEventStream().filter(({ eventName }) => eventName === 'sendCanceled' ||
|
|
379
|
+
eventName === 'sending'),
|
|
380
|
+
Kefir.later(15, undefined),
|
|
381
|
+
]))
|
|
382
|
+
.onValue(() => {
|
|
383
|
+
this._eventStream.emit({
|
|
384
|
+
eventName: 'sendCanceled',
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
});
|
|
170
388
|
}
|
|
389
|
+
return this;
|
|
390
|
+
})
|
|
391
|
+
.toProperty());
|
|
392
|
+
this.ready().onError((errorObject) => {
|
|
393
|
+
driver.getLogger().error(errorObject, {
|
|
394
|
+
hasForm: !!this.getElement().querySelector('form'),
|
|
395
|
+
class: this.getElement().getAttribute('class'),
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
// v2 Data behaves differently whereby the compose element is removed
|
|
399
|
+
// from the page while the send is in flight instead of waiting for the
|
|
400
|
+
// send to come back, so we have to handle that difference
|
|
401
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
402
|
+
Kefir.merge([
|
|
403
|
+
// if we get a presending then we let the other stream wait for
|
|
404
|
+
// sent. But if we get a sendCanceled, then a regular destroy can
|
|
405
|
+
// pass through
|
|
406
|
+
this._removedFromDOMStopper.filterBy(this._eventStream
|
|
407
|
+
.filter(({ eventName }) => eventName === 'presending' || eventName === 'sendCanceled')
|
|
408
|
+
.map(({ eventName }) => eventName === 'sendCanceled')
|
|
409
|
+
.toProperty(() => true)),
|
|
410
|
+
Kefir.combine([
|
|
411
|
+
this._removedFromDOMStopper,
|
|
412
|
+
this._eventStream.filter(({ eventName }) => eventName === 'sent'),
|
|
413
|
+
]),
|
|
414
|
+
])
|
|
415
|
+
.take(1) // we delay asap here so that the event stream is not destroyed before listeners here the sent event
|
|
416
|
+
.flatMap(() => delayAsap(null))
|
|
417
|
+
.onValue(() => this._destroy());
|
|
171
418
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
419
|
+
else {
|
|
420
|
+
this._removedFromDOMStopper.onValue(() => this._destroy());
|
|
421
|
+
}
|
|
422
|
+
detectClassicRecipientsArea();
|
|
423
|
+
}
|
|
424
|
+
destroy() {
|
|
425
|
+
// this gets called when the element gets removed from the DOM
|
|
426
|
+
// however we don't want to pass through that destroy event right away
|
|
427
|
+
this._removedFromDOMStopper.destroy();
|
|
428
|
+
this._page.dump();
|
|
429
|
+
}
|
|
430
|
+
_destroy() {
|
|
431
|
+
this._eventStream.emit({
|
|
432
|
+
eventName: 'destroy',
|
|
433
|
+
data: {
|
|
434
|
+
messageID: this.getMessageID(),
|
|
435
|
+
closedByInboxSDK: this._closedProgrammatically,
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
this._eventStream.end();
|
|
439
|
+
this._managedViewControllers.forEach((vc) => {
|
|
440
|
+
vc.destroy();
|
|
441
|
+
});
|
|
442
|
+
this._requestModifiers = {};
|
|
443
|
+
this._managedViewControllers.length = 0;
|
|
444
|
+
this._stopper.destroy();
|
|
445
|
+
this._destroyed = true;
|
|
446
|
+
}
|
|
447
|
+
getStopper() {
|
|
448
|
+
return this._stopper;
|
|
449
|
+
}
|
|
450
|
+
getEventStream() {
|
|
451
|
+
return this._eventStream;
|
|
452
|
+
}
|
|
453
|
+
getGmailDriver() {
|
|
454
|
+
return this._driver;
|
|
455
|
+
}
|
|
456
|
+
isDestroyed() {
|
|
457
|
+
return this._destroyed;
|
|
458
|
+
}
|
|
459
|
+
_setupStreams() {
|
|
460
|
+
this._eventStream.plug(getAddressChangesStream(this));
|
|
461
|
+
this._eventStream.plug(getBodyChangesStream(this));
|
|
462
|
+
this._eventStream.plug(getResponseTypeChangesStream(this));
|
|
463
|
+
this._eventStream.plug(getPresendingStream({
|
|
464
|
+
element: this.getElement(),
|
|
465
|
+
sendButton: this.getSendButton(),
|
|
466
|
+
sendAndArchive: this.getSendAndArchiveButton(),
|
|
467
|
+
}));
|
|
468
|
+
let discardButton;
|
|
469
|
+
try {
|
|
470
|
+
discardButton = this.getDiscardButton();
|
|
471
|
+
}
|
|
472
|
+
catch (err) {
|
|
473
|
+
// handle failures of this.getDiscardButton()
|
|
474
|
+
this._driver
|
|
475
|
+
.getLogger()
|
|
476
|
+
.errorSite(new Error('Failed to find discard button'), {
|
|
477
|
+
html: censorHTMLstring(this._element.outerHTML),
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
if (discardButton) {
|
|
481
|
+
this._eventStream.plug(getDiscardStream({
|
|
482
|
+
element: this.getElement(),
|
|
483
|
+
discardButton,
|
|
484
|
+
}));
|
|
485
|
+
}
|
|
486
|
+
this._eventStream.plug(Kefir.fromEvents(this.getElement(), 'inboxSDKsendCanceled').map(() => ({
|
|
487
|
+
eventName: 'sendCanceled',
|
|
488
|
+
})));
|
|
489
|
+
this._eventStream.plug(Kefir.fromEvents(this.getElement(), 'inboxSDKdiscardCanceled').map(() => ({
|
|
490
|
+
eventName: 'discardCanceled',
|
|
491
|
+
})));
|
|
492
|
+
this._eventStream.plug(Kefir.later(10, undefined)
|
|
493
|
+
.flatMap(() => getMinimizedStream(this))
|
|
494
|
+
.changes()
|
|
495
|
+
.map((minimized) => ({
|
|
496
|
+
eventName: minimized ? 'minimized' : 'restored',
|
|
497
|
+
})));
|
|
498
|
+
if (!this._driver.isUsingSyncAPI()) {
|
|
499
|
+
makeMutationObserverChunkedStream(this._messageIDElement, {
|
|
500
|
+
attributes: true,
|
|
501
|
+
attributeFilter: ['value'],
|
|
502
|
+
})
|
|
503
|
+
.takeUntilBy(this._eventStream.filter(() => false).beforeEnd(() => null))
|
|
504
|
+
.map(() => this._getMessageIDfromForm())
|
|
505
|
+
.filter((messageID) => messageID &&
|
|
506
|
+
!this._emailWasSent &&
|
|
507
|
+
this._messageId !== messageID)
|
|
508
|
+
.onValue((messageID) => {
|
|
509
|
+
this._messageId = messageID;
|
|
510
|
+
this._eventStream.emit({
|
|
511
|
+
eventName: 'messageIDChange',
|
|
512
|
+
data: this._messageId,
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
_setupConsistencyCheckers() {
|
|
518
|
+
try {
|
|
519
|
+
handleComposeLinkChips(this);
|
|
520
|
+
monitorSelectionRange(this);
|
|
521
|
+
manageButtonGrouping(this);
|
|
522
|
+
sizeFixer(this._driver, this);
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
this._driver.getLogger().error(err);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
_setupIDs() {
|
|
529
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
530
|
+
const syncTargetMessageID = this._getTargetMessageID();
|
|
531
|
+
if (syncTargetMessageID) {
|
|
532
|
+
this._driver
|
|
533
|
+
.getGmailMessageIdForSyncMessageId(syncTargetMessageID)
|
|
534
|
+
.then((gmailMessageId) => (this._targetMessageID = gmailMessageId));
|
|
181
535
|
}
|
|
182
|
-
|
|
183
|
-
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this._finalMessageId = response.messageID;
|
|
193
|
-
}
|
|
194
|
-
this._messageId = null;
|
|
195
|
-
const data = {
|
|
196
|
-
getThreadID: () => Promise.resolve(response.threadID),
|
|
197
|
-
getMessageID: () => Promise.resolve(response.messageID)
|
|
198
|
-
};
|
|
199
|
-
['threadID', 'gmailThreadId'].forEach(prop => {
|
|
200
|
-
// These properties are nonenumerable.
|
|
201
|
-
Object.defineProperty(data, prop, {
|
|
202
|
-
get: () => {
|
|
203
|
-
this._driver.getLogger().deprecationWarning(`composeView sent event.${prop}`, 'composeView sent event.getThreadID()');
|
|
204
|
-
return response.threadID;
|
|
205
|
-
}
|
|
536
|
+
const syncMessageId = this._getMessageIDfromForm();
|
|
537
|
+
if (syncMessageId) {
|
|
538
|
+
this._driver
|
|
539
|
+
.getGmailMessageIdForSyncDraftId(syncMessageId)
|
|
540
|
+
.then((gmailMessageId) => {
|
|
541
|
+
this._initialMessageId = gmailMessageId;
|
|
542
|
+
this._messageId = gmailMessageId;
|
|
543
|
+
})
|
|
544
|
+
.catch(() => {
|
|
545
|
+
//do nothing because this means the message hasn't been saved yet
|
|
206
546
|
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
get: () => {
|
|
211
|
-
this._driver.getLogger().deprecationWarning(`composeView sent event.${prop}`, 'composeView sent event.getMessageID()');
|
|
212
|
-
return response.messageID;
|
|
213
|
-
}
|
|
547
|
+
this._driver.reportRecentSyncDraftId(syncMessageId);
|
|
548
|
+
this._stopper.onValue(() => {
|
|
549
|
+
this._driver.reportDraftClosed(syncMessageId);
|
|
214
550
|
});
|
|
215
|
-
});
|
|
216
|
-
return [{
|
|
217
|
-
eventName: 'sent',
|
|
218
|
-
data
|
|
219
|
-
}];
|
|
220
551
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
eventName: 'draftSaving'
|
|
226
|
-
}];
|
|
552
|
+
else {
|
|
553
|
+
this._driver
|
|
554
|
+
.getLogger()
|
|
555
|
+
.error(new Error('Draft is missing sync draft id'));
|
|
227
556
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
557
|
+
const legacyThreadIdElement = this._element.querySelector('input[name="lts"]');
|
|
558
|
+
if (legacyThreadIdElement &&
|
|
559
|
+
typeof legacyThreadIdElement.value === 'string')
|
|
560
|
+
this._threadID = legacyThreadIdElement.value;
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
this._targetMessageID = this._getTargetMessageID();
|
|
564
|
+
this._messageId = this._initialMessageId = this._getMessageIDfromForm();
|
|
565
|
+
this._threadID = this._getThreadID();
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
_updateComposeFullscreenState() {
|
|
569
|
+
if (this._isInlineReplyForm) {
|
|
570
|
+
this._isFullscreen = false;
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
if (this._isStandalone) {
|
|
574
|
+
this._isFullscreen = true;
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
const fullScreenContainer = GmailElementGetter.getFullscreenComposeWindowContainer();
|
|
578
|
+
if (!fullScreenContainer) {
|
|
579
|
+
this._isFullscreen = false;
|
|
243
580
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return []; // save was canceled
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const events = [{
|
|
250
|
-
eventName: 'draftSaved',
|
|
251
|
-
data: response
|
|
252
|
-
}];
|
|
253
|
-
if (!response.messageID) {
|
|
254
|
-
this._driver.getLogger().error(new Error('Missing message id from emailDraftReceived'));
|
|
255
|
-
} else if (response.messageID && this._messageId !== response.messageID) {
|
|
256
|
-
if (/^[0-9a-f]+$/i.test(response.messageID)) {
|
|
257
|
-
this._messageId = response.messageID;
|
|
258
|
-
events.push({
|
|
259
|
-
eventName: 'messageIDChange',
|
|
260
|
-
data: this._messageId
|
|
261
|
-
});
|
|
262
|
-
} else {
|
|
263
|
-
this._driver.getLogger().error(new Error('Invalid message id from emailDraftReceived'), {
|
|
264
|
-
value: response.messageID
|
|
265
|
-
});
|
|
581
|
+
else {
|
|
582
|
+
this._isFullscreen = fullScreenContainer.contains(this._element);
|
|
266
583
|
}
|
|
267
|
-
}
|
|
268
|
-
return events;
|
|
269
584
|
}
|
|
270
|
-
default:
|
|
271
|
-
return [];
|
|
272
585
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
586
|
+
}
|
|
587
|
+
focus() {
|
|
588
|
+
focus(this);
|
|
589
|
+
}
|
|
590
|
+
insertBodyTextAtCursor(text) {
|
|
591
|
+
return this.insertBodyHTMLAtCursor(escape(text).replace(/\n/g, '<br>'));
|
|
592
|
+
}
|
|
593
|
+
insertBodyHTMLAtCursor(html) {
|
|
594
|
+
var retVal = insertHTMLatCursor(this.getBodyElement(), html, this.getLastSelectionRange());
|
|
595
|
+
this._triggerDraftSave();
|
|
596
|
+
// sometimes the html inserted can be quite large, so we need ot make sure that GMail resizes the compose window
|
|
597
|
+
// triggering an enter press forces Gmail to resize compose
|
|
598
|
+
simulateKey(this.getBodyElement(), 13, 13);
|
|
599
|
+
return retVal;
|
|
600
|
+
}
|
|
601
|
+
insertLinkIntoBody(text, href) {
|
|
602
|
+
var retVal = insertLinkIntoBody(this, text, href);
|
|
603
|
+
this._triggerDraftSave();
|
|
604
|
+
return retVal;
|
|
605
|
+
}
|
|
606
|
+
insertLinkChipIntoBody(options) {
|
|
607
|
+
var retVal = insertLinkChipIntoBody(this, options);
|
|
608
|
+
this._triggerDraftSave();
|
|
609
|
+
return retVal;
|
|
610
|
+
}
|
|
611
|
+
setSubject(text) {
|
|
612
|
+
this._element.querySelector('input[name=subjectbox]').value = text;
|
|
613
|
+
this._triggerDraftSave();
|
|
614
|
+
}
|
|
615
|
+
setBodyHTML(html) {
|
|
616
|
+
this.getBodyElement().innerHTML = html;
|
|
617
|
+
this._triggerDraftSave();
|
|
618
|
+
}
|
|
619
|
+
setBodyText(text) {
|
|
620
|
+
this.getBodyElement().textContent = text;
|
|
621
|
+
this._triggerDraftSave();
|
|
622
|
+
}
|
|
623
|
+
setToRecipients(emails) {
|
|
624
|
+
setRecipients(this, 'to', emails);
|
|
625
|
+
this._triggerDraftSave();
|
|
626
|
+
}
|
|
627
|
+
setCcRecipients(emails) {
|
|
628
|
+
setRecipients(this, 'cc', emails);
|
|
629
|
+
this._triggerDraftSave();
|
|
630
|
+
}
|
|
631
|
+
setBccRecipients(emails) {
|
|
632
|
+
setRecipients(this, 'bcc', emails);
|
|
633
|
+
this._triggerDraftSave();
|
|
634
|
+
}
|
|
635
|
+
addRecipientRow(options) {
|
|
636
|
+
return addRecipientRow(this, options);
|
|
637
|
+
}
|
|
638
|
+
forceRecipientRowsOpen() {
|
|
639
|
+
this._element.classList.add('inboxsdk__compose_forceRecipientsOpen');
|
|
640
|
+
return () => {
|
|
641
|
+
this._element.classList.remove('inboxsdk__compose_forceRecipientsOpen');
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
hideNativeRecipientRows() {
|
|
645
|
+
const nativeRecipientRows = getRecipientRowElements(this._element);
|
|
646
|
+
nativeRecipientRows.forEach((row) => {
|
|
647
|
+
row.classList.add('inboxsdk__compose_forceRecipientRowHidden');
|
|
648
|
+
});
|
|
649
|
+
return () => {
|
|
650
|
+
nativeRecipientRows.forEach((row) => {
|
|
651
|
+
row.classList.remove('inboxsdk__compose_forceRecipientRowHidden');
|
|
652
|
+
});
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
hideRecipientArea() {
|
|
656
|
+
this._element.classList.add('inboxsdk__compose_hideRecipientArea');
|
|
657
|
+
return () => {
|
|
658
|
+
this._element.classList.remove('inboxsdk__compose_hideRecipientArea');
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
getFromContact() {
|
|
662
|
+
return fromManager.getFromContact(this._driver, this);
|
|
663
|
+
}
|
|
664
|
+
getFromContactChoices() {
|
|
665
|
+
return fromManager.getFromContactChoices(this._driver, this);
|
|
666
|
+
}
|
|
667
|
+
setFromEmail(email) {
|
|
668
|
+
fromManager.setFromEmail(this._driver, this, email);
|
|
669
|
+
}
|
|
670
|
+
addButton(buttonDescriptor, groupOrderHint, extraOnClickOptions) {
|
|
671
|
+
return addButton(this, buttonDescriptor, groupOrderHint, extraOnClickOptions);
|
|
672
|
+
}
|
|
673
|
+
addTooltipToButton(buttonViewController, buttonDescriptor, tooltipDescriptor) {
|
|
674
|
+
var tooltip = addTooltipToButton(this, buttonViewController, buttonDescriptor, tooltipDescriptor);
|
|
675
|
+
this._buttonViewControllerTooltipMap.set(buttonViewController, tooltip);
|
|
676
|
+
}
|
|
677
|
+
closeButtonTooltip(buttonViewController) {
|
|
678
|
+
if (!this._buttonViewControllerTooltipMap) {
|
|
679
|
+
return;
|
|
278
680
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return {
|
|
284
|
-
eventName: 'buttonAdded'
|
|
285
|
-
};
|
|
286
|
-
}), Kefir.fromEvents(this._element, 'resize').map(() => ({
|
|
287
|
-
eventName: 'resize'
|
|
288
|
-
})), Kefir.fromEvents(this._element, 'composeFullscreenStateChanged').map(() => {
|
|
289
|
-
this._updateComposeFullscreenState();
|
|
290
|
-
return {
|
|
291
|
-
eventName: 'fullscreenChanged',
|
|
292
|
-
data: {
|
|
293
|
-
fullscreen: this._isFullscreen
|
|
681
|
+
var tooltip = this._buttonViewControllerTooltipMap.get(buttonViewController);
|
|
682
|
+
if (tooltip) {
|
|
683
|
+
tooltip.destroy();
|
|
684
|
+
this._buttonViewControllerTooltipMap.delete(buttonViewController);
|
|
294
685
|
}
|
|
295
|
-
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this._setupIDs();
|
|
313
|
-
this._setupStreams();
|
|
314
|
-
this._setupConsistencyCheckers();
|
|
315
|
-
this._updateComposeFullscreenState();
|
|
316
|
-
{
|
|
317
|
-
// try and handle the case where the user types in a bad email address
|
|
318
|
-
// we get the presending event but then no other events will pass because
|
|
319
|
-
// a modal comes up informing the user of the bad email address
|
|
320
|
-
this.getEventStream().filter(_ref => {
|
|
321
|
-
let {
|
|
322
|
-
eventName
|
|
323
|
-
} = _ref;
|
|
324
|
-
return eventName === 'presending';
|
|
325
|
-
}).takeUntilBy(this._stopper).onValue(() => {
|
|
326
|
-
(0, _makeElementChildStream.default)(document.body).map(event => event.el).filter(node => node.getAttribute && node.getAttribute('role') === 'alertdialog').takeUntilBy(Kefir.merge([this.getEventStream().filter(_ref2 => {
|
|
327
|
-
let {
|
|
328
|
-
eventName
|
|
329
|
-
} = _ref2;
|
|
330
|
-
return eventName === 'sendCanceled' || eventName === 'sending';
|
|
331
|
-
}), Kefir.later(15)])).onValue(() => {
|
|
332
|
-
this._eventStream.emit({
|
|
333
|
-
eventName: 'sendCanceled'
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
return this;
|
|
339
|
-
}).toProperty());
|
|
340
|
-
this.ready().onError(errorObject => {
|
|
341
|
-
driver.getLogger().error(errorObject, {
|
|
342
|
-
hasForm: !!this.getElement().querySelector('form'),
|
|
343
|
-
class: this.getElement().getAttribute('class')
|
|
344
|
-
});
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
// v2 Data behaves differently whereby the compose element is removed
|
|
348
|
-
// from the page while the send is in flight instead of waiting for the
|
|
349
|
-
// send to come back, so we have to handle that difference
|
|
350
|
-
if (this._driver.isUsingSyncAPI()) {
|
|
351
|
-
Kefir.merge([
|
|
352
|
-
// if we get a presending then we let the other stream wait for
|
|
353
|
-
// sent. But if we get a sendCanceled, then a regular destroy can
|
|
354
|
-
// pass through
|
|
355
|
-
this._removedFromDOMStopper.filterBy(this._eventStream.filter(_ref3 => {
|
|
356
|
-
let {
|
|
357
|
-
eventName
|
|
358
|
-
} = _ref3;
|
|
359
|
-
return eventName === 'presending' || eventName === 'sendCanceled';
|
|
360
|
-
}).map(_ref4 => {
|
|
361
|
-
let {
|
|
362
|
-
eventName
|
|
363
|
-
} = _ref4;
|
|
364
|
-
return eventName === 'sendCanceled';
|
|
365
|
-
}).toProperty(() => true)), Kefir.combine([this._removedFromDOMStopper, this._eventStream.filter(_ref5 => {
|
|
366
|
-
let {
|
|
367
|
-
eventName
|
|
368
|
-
} = _ref5;
|
|
369
|
-
return eventName === 'sent';
|
|
370
|
-
})])]).take(1)
|
|
371
|
-
// we delay asap here so that the event stream is not destroyed before listeners here the sent event
|
|
372
|
-
.flatMap(() => (0, _delayAsap.default)(null)).onValue(() => this._destroy());
|
|
373
|
-
} else {
|
|
374
|
-
this._removedFromDOMStopper.onValue(() => this._destroy());
|
|
375
|
-
}
|
|
376
|
-
(0, _detectClassicRecipientsArea.default)();
|
|
377
|
-
}
|
|
378
|
-
destroy() {
|
|
379
|
-
// this gets called when the element gets removed from the DOM
|
|
380
|
-
// however we don't want to pass through that destroy event right away
|
|
381
|
-
this._removedFromDOMStopper.destroy();
|
|
382
|
-
this._page.dump();
|
|
383
|
-
}
|
|
384
|
-
_destroy() {
|
|
385
|
-
this._eventStream.emit({
|
|
386
|
-
eventName: 'destroy',
|
|
387
|
-
data: {
|
|
388
|
-
messageID: this.getMessageID(),
|
|
389
|
-
closedByInboxSDK: this._closedProgrammatically
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
this._eventStream.end();
|
|
393
|
-
this._managedViewControllers.forEach(vc => {
|
|
394
|
-
vc.destroy();
|
|
395
|
-
});
|
|
396
|
-
this._requestModifiers = {};
|
|
397
|
-
this._managedViewControllers.length = 0;
|
|
398
|
-
this._stopper.destroy();
|
|
399
|
-
this._destroyed = true;
|
|
400
|
-
}
|
|
401
|
-
getStopper() {
|
|
402
|
-
return this._stopper;
|
|
403
|
-
}
|
|
404
|
-
getEventStream() {
|
|
405
|
-
return this._eventStream;
|
|
406
|
-
}
|
|
407
|
-
getGmailDriver() {
|
|
408
|
-
return this._driver;
|
|
409
|
-
}
|
|
410
|
-
isDestroyed() {
|
|
411
|
-
return this._destroyed;
|
|
412
|
-
}
|
|
413
|
-
_setupStreams() {
|
|
414
|
-
this._eventStream.plug((0, _getAddressChangesStream.default)(this));
|
|
415
|
-
this._eventStream.plug((0, _getBodyChangesStream.default)(this));
|
|
416
|
-
this._eventStream.plug((0, _getResponseTypeChangesStream.default)(this));
|
|
417
|
-
this._eventStream.plug((0, _getPresendingStream.default)({
|
|
418
|
-
element: this.getElement(),
|
|
419
|
-
sendButton: this.getSendButton(),
|
|
420
|
-
sendAndArchive: this.getSendAndArchiveButton()
|
|
421
|
-
}));
|
|
422
|
-
let discardButton;
|
|
423
|
-
try {
|
|
424
|
-
discardButton = this.getDiscardButton();
|
|
425
|
-
} catch (err) {
|
|
426
|
-
// handle failures of this.getDiscardButton()
|
|
427
|
-
this._driver.getLogger().errorSite(new Error('Failed to find discard button'), {
|
|
428
|
-
html: (0, _censorHTMLstring.default)(this._element.outerHTML)
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
if (discardButton) {
|
|
432
|
-
this._eventStream.plug((0, _getDiscardStream.default)({
|
|
433
|
-
element: this.getElement(),
|
|
434
|
-
discardButton
|
|
435
|
-
}));
|
|
436
|
-
}
|
|
437
|
-
this._eventStream.plug(Kefir.fromEvents(this.getElement(), 'inboxSDKsendCanceled').map(() => ({
|
|
438
|
-
eventName: 'sendCanceled'
|
|
439
|
-
})));
|
|
440
|
-
this._eventStream.plug(Kefir.fromEvents(this.getElement(), 'inboxSDKdiscardCanceled').map(() => ({
|
|
441
|
-
eventName: 'discardCanceled'
|
|
442
|
-
})));
|
|
443
|
-
this._eventStream.plug(Kefir.later(10).flatMap(() => (0, _getMinimizedStream.default)(this)).changes().map(minimized => ({
|
|
444
|
-
eventName: minimized ? 'minimized' : 'restored'
|
|
445
|
-
})));
|
|
446
|
-
if (!this._driver.isUsingSyncAPI()) {
|
|
447
|
-
(0, _makeMutationObserverChunkedStream.default)(this._messageIDElement, {
|
|
448
|
-
attributes: true,
|
|
449
|
-
attributeFilter: ['value']
|
|
450
|
-
}).takeUntilBy(this._eventStream.filter(() => false).beforeEnd(() => null)).map(() => this._getMessageIDfromForm()).filter(messageID => messageID && !this._emailWasSent && this._messageId !== messageID).onValue(messageID => {
|
|
451
|
-
this._messageId = messageID;
|
|
452
|
-
this._eventStream.emit({
|
|
453
|
-
eventName: 'messageIDChange',
|
|
454
|
-
data: this._messageId
|
|
686
|
+
}
|
|
687
|
+
addComposeNotice(options = {}) {
|
|
688
|
+
const composeNotice = addComposeNotice(this, options);
|
|
689
|
+
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
690
|
+
bubbles: false,
|
|
691
|
+
cancelable: false,
|
|
692
|
+
detail: null,
|
|
693
|
+
}));
|
|
694
|
+
Kefir.fromEvents(composeNotice, 'destroy')
|
|
695
|
+
.flatMap(delayAsap)
|
|
696
|
+
.takeUntilBy(this._stopper)
|
|
697
|
+
.onValue(() => {
|
|
698
|
+
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
699
|
+
bubbles: false,
|
|
700
|
+
cancelable: false,
|
|
701
|
+
detail: null,
|
|
702
|
+
}));
|
|
455
703
|
});
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
const syncMessageId = this._getMessageIDfromForm();
|
|
476
|
-
if (syncMessageId) {
|
|
477
|
-
this._driver.getGmailMessageIdForSyncDraftId(syncMessageId).then(gmailMessageId => {
|
|
478
|
-
this._initialMessageId = gmailMessageId;
|
|
479
|
-
this._messageId = gmailMessageId;
|
|
480
|
-
}).catch(() => {
|
|
481
|
-
//do nothing because this means the message hasn't been saved yet
|
|
704
|
+
return composeNotice;
|
|
705
|
+
}
|
|
706
|
+
addStatusBar(options = {}) {
|
|
707
|
+
const statusBar = addStatusBar(this, options);
|
|
708
|
+
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
709
|
+
bubbles: false,
|
|
710
|
+
cancelable: false,
|
|
711
|
+
detail: null,
|
|
712
|
+
}));
|
|
713
|
+
Kefir.fromEvents(statusBar, 'destroy')
|
|
714
|
+
.flatMap(delayAsap)
|
|
715
|
+
.takeUntilBy(this._stopper)
|
|
716
|
+
.onValue(() => {
|
|
717
|
+
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
718
|
+
bubbles: false,
|
|
719
|
+
cancelable: false,
|
|
720
|
+
detail: null,
|
|
721
|
+
}));
|
|
482
722
|
});
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
723
|
+
return statusBar;
|
|
724
|
+
}
|
|
725
|
+
hideNativeStatusBar() {
|
|
726
|
+
const statusArea = this.getStatusArea();
|
|
727
|
+
const nativeStatusBar = querySelector(statusArea, 'table');
|
|
728
|
+
const formattingToolbar = this.getFormattingToolbar();
|
|
729
|
+
const isFormattingToolbarOpen = formattingToolbar && formattingToolbar.style.display !== 'none';
|
|
730
|
+
nativeStatusBar.style.display = 'none';
|
|
731
|
+
if (formattingToolbar && isFormattingToolbarOpen) {
|
|
732
|
+
formattingToolbar.style.display = 'none';
|
|
733
|
+
}
|
|
734
|
+
return () => {
|
|
735
|
+
nativeStatusBar.style.display = '';
|
|
736
|
+
if (formattingToolbar && isFormattingToolbarOpen) {
|
|
737
|
+
formattingToolbar.style.display = '';
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
replaceSendButton(el) {
|
|
742
|
+
const sendButton = this.getSendButtonGroup();
|
|
743
|
+
const sendAndArchive = this.getSendAndArchiveButton();
|
|
744
|
+
sendButton.style.display = 'none';
|
|
745
|
+
const sendAndArchiveParent = sendAndArchive && sendAndArchive.parentElement;
|
|
746
|
+
if (sendAndArchiveParent instanceof HTMLElement) {
|
|
747
|
+
sendAndArchiveParent.style.display = 'none';
|
|
748
|
+
}
|
|
749
|
+
const container = document.createElement('div');
|
|
750
|
+
container.classList.add('inboxsdk__compose_customSendContainer');
|
|
751
|
+
container.appendChild(el);
|
|
752
|
+
sendButton.insertAdjacentElement('afterend', container);
|
|
753
|
+
this._element.setAttribute('data-inboxsdk-send-replaced', '');
|
|
754
|
+
const removalStopper = kefirStopper();
|
|
755
|
+
Kefir.fromEvents(this.getBodyElement(), 'keydown')
|
|
756
|
+
.takeUntilBy(this._stopper)
|
|
757
|
+
.takeUntilBy(removalStopper)
|
|
758
|
+
.filter((domEvent) => (domEvent.which === 9 || domEvent.keyCode === 9) && !domEvent.shiftKey)
|
|
759
|
+
.onValue((domEvent) => {
|
|
760
|
+
// Because of the way the compose DOM is structured, the natural
|
|
761
|
+
// tab order does not flow from the compose body to the status bar.
|
|
762
|
+
// Gmail modifies this flow programatically by focusing the send button,
|
|
763
|
+
// so we have replicate this behavior when the native send button isn't
|
|
764
|
+
// visible.
|
|
765
|
+
const statusArea = this.getStatusArea();
|
|
766
|
+
const focusableEls = statusArea.querySelectorAll('[tabindex]');
|
|
767
|
+
if (focusableEls.length === 0)
|
|
768
|
+
return;
|
|
769
|
+
const firstVisibleEl = Array.from(focusableEls).find((el) => el.offsetParent !== null);
|
|
770
|
+
if (!firstVisibleEl)
|
|
771
|
+
return;
|
|
772
|
+
domEvent.preventDefault();
|
|
773
|
+
domEvent.stopPropagation();
|
|
774
|
+
domEvent.stopImmediatePropagation();
|
|
775
|
+
firstVisibleEl.focus();
|
|
486
776
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
777
|
+
return () => {
|
|
778
|
+
removalStopper.destroy();
|
|
779
|
+
container.remove();
|
|
780
|
+
this._element.removeAttribute('data-inboxsdk-send-replaced');
|
|
781
|
+
sendButton.style.display = '';
|
|
782
|
+
if (sendAndArchiveParent instanceof HTMLElement) {
|
|
783
|
+
sendAndArchiveParent.style.display = '';
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
hideDiscardButton() {
|
|
788
|
+
const discardBtn = this.getDiscardButton();
|
|
789
|
+
discardBtn.style.display = 'none';
|
|
790
|
+
return () => {
|
|
791
|
+
discardBtn.style.display = '';
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
ensureFormattingToolbarIsHidden() {
|
|
795
|
+
const formattingToggleButton = this.getFormattingToolbarToggleButton();
|
|
796
|
+
const formattingToolbar = this.getFormattingToolbar();
|
|
797
|
+
if (formattingToggleButton &&
|
|
798
|
+
formattingToolbar &&
|
|
799
|
+
formattingToolbar.style.display === '') {
|
|
800
|
+
simulateClick(formattingToggleButton);
|
|
510
801
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
insertBodyTextAtCursor(text) {
|
|
518
|
-
return this.insertBodyHTMLAtCursor((0, _escape.default)(text).replace(/\n/g, '<br>'));
|
|
519
|
-
}
|
|
520
|
-
insertBodyHTMLAtCursor(html) {
|
|
521
|
-
var retVal = (0, _insertHtmlAtCursor.default)(this.getBodyElement(), html, this.getLastSelectionRange());
|
|
522
|
-
this._triggerDraftSave();
|
|
523
|
-
|
|
524
|
-
// sometimes the html inserted can be quite large, so we need ot make sure that GMail resizes the compose window
|
|
525
|
-
// triggering an enter press forces Gmail to resize compose
|
|
526
|
-
(0, _simulateKey.default)(this.getBodyElement(), 13, 13);
|
|
527
|
-
return retVal;
|
|
528
|
-
}
|
|
529
|
-
insertLinkIntoBody(text, href) {
|
|
530
|
-
var retVal = (0, _insertLinkIntoBody.default)(this, text, href);
|
|
531
|
-
this._triggerDraftSave();
|
|
532
|
-
return retVal;
|
|
533
|
-
}
|
|
534
|
-
insertLinkChipIntoBody(options) {
|
|
535
|
-
var retVal = (0, _insertLinkChipIntoBody.default)(this, options);
|
|
536
|
-
this._triggerDraftSave();
|
|
537
|
-
return retVal;
|
|
538
|
-
}
|
|
539
|
-
setSubject(text) {
|
|
540
|
-
this._element.querySelector('input[name=subjectbox]').value = text;
|
|
541
|
-
this._triggerDraftSave();
|
|
542
|
-
}
|
|
543
|
-
setBodyHTML(html) {
|
|
544
|
-
this.getBodyElement().innerHTML = html;
|
|
545
|
-
this._triggerDraftSave();
|
|
546
|
-
}
|
|
547
|
-
setBodyText(text) {
|
|
548
|
-
this.getBodyElement().textContent = text;
|
|
549
|
-
this._triggerDraftSave();
|
|
550
|
-
}
|
|
551
|
-
setToRecipients(emails) {
|
|
552
|
-
(0, _setRecipients.default)(this, 'to', emails);
|
|
553
|
-
this._triggerDraftSave();
|
|
554
|
-
}
|
|
555
|
-
setCcRecipients(emails) {
|
|
556
|
-
(0, _setRecipients.default)(this, 'cc', emails);
|
|
557
|
-
this._triggerDraftSave();
|
|
558
|
-
}
|
|
559
|
-
setBccRecipients(emails) {
|
|
560
|
-
(0, _setRecipients.default)(this, 'bcc', emails);
|
|
561
|
-
this._triggerDraftSave();
|
|
562
|
-
}
|
|
563
|
-
addRecipientRow(options) {
|
|
564
|
-
return (0, _addRecipientRow.default)(this, options);
|
|
565
|
-
}
|
|
566
|
-
forceRecipientRowsOpen() {
|
|
567
|
-
this._element.classList.add('inboxsdk__compose_forceRecipientsOpen');
|
|
568
|
-
return () => {
|
|
569
|
-
this._element.classList.remove('inboxsdk__compose_forceRecipientsOpen');
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
hideNativeRecipientRows() {
|
|
573
|
-
const nativeRecipientRows = (0, _pageParser.getRecipientRowElements)(this._element);
|
|
574
|
-
nativeRecipientRows.forEach(row => {
|
|
575
|
-
row.classList.add('inboxsdk__compose_forceRecipientRowHidden');
|
|
576
|
-
});
|
|
577
|
-
return () => {
|
|
578
|
-
nativeRecipientRows.forEach(row => {
|
|
579
|
-
row.classList.remove('inboxsdk__compose_forceRecipientRowHidden');
|
|
580
|
-
});
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
hideRecipientArea() {
|
|
584
|
-
this._element.classList.add('inboxsdk__compose_hideRecipientArea');
|
|
585
|
-
return () => {
|
|
586
|
-
this._element.classList.remove('inboxsdk__compose_hideRecipientArea');
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
getFromContact() {
|
|
590
|
-
return fromManager.getFromContact(this._driver, this);
|
|
591
|
-
}
|
|
592
|
-
getFromContactChoices() {
|
|
593
|
-
return fromManager.getFromContactChoices(this._driver, this);
|
|
594
|
-
}
|
|
595
|
-
setFromEmail(email) {
|
|
596
|
-
fromManager.setFromEmail(this._driver, this, email);
|
|
597
|
-
}
|
|
598
|
-
addButton(buttonDescriptor, groupOrderHint, extraOnClickOptions) {
|
|
599
|
-
return (0, _addButton.default)(this, buttonDescriptor, groupOrderHint, extraOnClickOptions);
|
|
600
|
-
}
|
|
601
|
-
addTooltipToButton(buttonViewController, buttonDescriptor, tooltipDescriptor) {
|
|
602
|
-
var tooltip = (0, _addTooltipToButton.default)(this, buttonViewController, buttonDescriptor, tooltipDescriptor);
|
|
603
|
-
this._buttonViewControllerTooltipMap.set(buttonViewController, tooltip);
|
|
604
|
-
}
|
|
605
|
-
closeButtonTooltip(buttonViewController) {
|
|
606
|
-
if (!this._buttonViewControllerTooltipMap) {
|
|
607
|
-
return;
|
|
608
|
-
}
|
|
609
|
-
var tooltip = this._buttonViewControllerTooltipMap.get(buttonViewController);
|
|
610
|
-
if (tooltip) {
|
|
611
|
-
tooltip.destroy();
|
|
612
|
-
this._buttonViewControllerTooltipMap.delete(buttonViewController);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
addComposeNotice() {
|
|
616
|
-
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
617
|
-
const composeNotice = (0, _addComposeNotice.default)(this, options);
|
|
618
|
-
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
619
|
-
bubbles: false,
|
|
620
|
-
cancelable: false,
|
|
621
|
-
detail: null
|
|
622
|
-
}));
|
|
623
|
-
Kefir.fromEvents(composeNotice, 'destroy').flatMap(_delayAsap.default).takeUntilBy(this._stopper).onValue(() => {
|
|
624
|
-
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
625
|
-
bubbles: false,
|
|
626
|
-
cancelable: false,
|
|
627
|
-
detail: null
|
|
628
|
-
}));
|
|
629
|
-
});
|
|
630
|
-
return composeNotice;
|
|
631
|
-
}
|
|
632
|
-
addStatusBar() {
|
|
633
|
-
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
634
|
-
const statusBar = (0, _addStatusBar.default)(this, options);
|
|
635
|
-
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
636
|
-
bubbles: false,
|
|
637
|
-
cancelable: false,
|
|
638
|
-
detail: null
|
|
639
|
-
}));
|
|
640
|
-
Kefir.fromEvents(statusBar, 'destroy').flatMap(_delayAsap.default).takeUntilBy(this._stopper).onValue(() => {
|
|
641
|
-
this._element.dispatchEvent(new CustomEvent('resize', {
|
|
642
|
-
bubbles: false,
|
|
643
|
-
cancelable: false,
|
|
644
|
-
detail: null
|
|
645
|
-
}));
|
|
646
|
-
});
|
|
647
|
-
return statusBar;
|
|
648
|
-
}
|
|
649
|
-
hideNativeStatusBar() {
|
|
650
|
-
const statusArea = this.getStatusArea();
|
|
651
|
-
const nativeStatusBar = (0, _querySelectorOrFail.default)(statusArea, 'table');
|
|
652
|
-
const formattingToolbar = this.getFormattingToolbar();
|
|
653
|
-
const isFormattingToolbarOpen = formattingToolbar && formattingToolbar.style.display !== 'none';
|
|
654
|
-
nativeStatusBar.style.display = 'none';
|
|
655
|
-
if (formattingToolbar && isFormattingToolbarOpen) {
|
|
656
|
-
formattingToolbar.style.display = 'none';
|
|
657
|
-
}
|
|
658
|
-
return () => {
|
|
659
|
-
nativeStatusBar.style.display = '';
|
|
660
|
-
if (formattingToolbar && isFormattingToolbarOpen) {
|
|
661
|
-
formattingToolbar.style.display = '';
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
replaceSendButton(el) {
|
|
666
|
-
const sendButton = this.getSendButtonGroup();
|
|
667
|
-
const sendAndArchive = this.getSendAndArchiveButton();
|
|
668
|
-
sendButton.style.display = 'none';
|
|
669
|
-
const sendAndArchiveParent = sendAndArchive && sendAndArchive.parentElement;
|
|
670
|
-
if (sendAndArchiveParent instanceof HTMLElement) {
|
|
671
|
-
sendAndArchiveParent.style.display = 'none';
|
|
672
|
-
}
|
|
673
|
-
const container = document.createElement('div');
|
|
674
|
-
container.classList.add('inboxsdk__compose_customSendContainer');
|
|
675
|
-
container.appendChild(el);
|
|
676
|
-
sendButton.insertAdjacentElement('afterend', container);
|
|
677
|
-
this._element.setAttribute('data-inboxsdk-send-replaced', '');
|
|
678
|
-
const removalStopper = (0, _kefirStopper.default)();
|
|
679
|
-
Kefir.fromEvents(this.getBodyElement(), 'keydown').takeUntilBy(this._stopper).takeUntilBy(removalStopper).filter(domEvent => (domEvent.which === 9 || domEvent.keyCode === 9) && !domEvent.shiftKey).onValue(domEvent => {
|
|
680
|
-
// Because of the way the compose DOM is structured, the natural
|
|
681
|
-
// tab order does not flow from the compose body to the status bar.
|
|
682
|
-
// Gmail modifies this flow programatically by focusing the send button,
|
|
683
|
-
// so we have replicate this behavior when the native send button isn't
|
|
684
|
-
// visible.
|
|
685
|
-
const statusArea = this.getStatusArea();
|
|
686
|
-
const focusableEls = statusArea.querySelectorAll('[tabindex]');
|
|
687
|
-
if (focusableEls.length === 0) return;
|
|
688
|
-
const firstVisibleEl = Array.from(focusableEls).find(el => el.offsetParent !== null);
|
|
689
|
-
if (!firstVisibleEl) return;
|
|
690
|
-
domEvent.preventDefault();
|
|
691
|
-
domEvent.stopPropagation();
|
|
692
|
-
domEvent.stopImmediatePropagation();
|
|
693
|
-
firstVisibleEl.focus();
|
|
694
|
-
});
|
|
695
|
-
return () => {
|
|
696
|
-
removalStopper.destroy();
|
|
697
|
-
container.remove();
|
|
698
|
-
this._element.removeAttribute('data-inboxsdk-send-replaced');
|
|
699
|
-
sendButton.style.display = '';
|
|
700
|
-
if (sendAndArchiveParent instanceof HTMLElement) {
|
|
701
|
-
sendAndArchiveParent.style.display = '';
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
hideDiscardButton() {
|
|
706
|
-
const discardBtn = this.getDiscardButton();
|
|
707
|
-
discardBtn.style.display = 'none';
|
|
708
|
-
return () => {
|
|
709
|
-
discardBtn.style.display = '';
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
ensureFormattingToolbarIsHidden() {
|
|
713
|
-
const formattingToggleButton = this.getFormattingToolbarToggleButton();
|
|
714
|
-
const formattingToolbar = this.getFormattingToolbar();
|
|
715
|
-
if (formattingToggleButton && formattingToolbar && formattingToolbar.style.display === '') {
|
|
716
|
-
(0, _simulateMouseEvent.simulateClick)(formattingToggleButton);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
close() {
|
|
720
|
-
if (this.isInlineReplyForm()) {
|
|
721
|
-
console.warn("Trying to close an inline reply which doesn't work.");
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
this._element.dispatchEvent(new CustomEvent('closedProgrammatically', {
|
|
725
|
-
bubbles: false,
|
|
726
|
-
cancelable: false,
|
|
727
|
-
detail: null
|
|
728
|
-
}));
|
|
729
|
-
if (this._isFullscreen) {
|
|
730
|
-
this._eventStream.filter(_ref6 => {
|
|
731
|
-
let {
|
|
732
|
-
eventName
|
|
733
|
-
} = _ref6;
|
|
734
|
-
return eventName === 'fullscreenChanged';
|
|
735
|
-
}).onValue(() => (0, _simulateMouseEvent.simulateClick)(this.getCloseButton()));
|
|
736
|
-
(0, _simulateMouseEvent.simulateClick)(this.getMoleSwitchButton());
|
|
737
|
-
} else {
|
|
738
|
-
(0, _simulateMouseEvent.simulateClick)(this.getCloseButton());
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
send(_ref7) {
|
|
742
|
-
let {
|
|
743
|
-
sendAndArchive
|
|
744
|
-
} = _ref7;
|
|
745
|
-
// asap necessary so if send() is called after presending event.cancel(), the new presending event
|
|
746
|
-
// must happen after the sendCanceled event (which is also delayed by asap).
|
|
747
|
-
(0, _asap.default)(() => {
|
|
748
|
-
const sendAndArchiveButton = this.getSendAndArchiveButton();
|
|
749
|
-
if (sendAndArchive && sendAndArchiveButton) {
|
|
750
|
-
(0, _simulateMouseEvent.simulateClick)(sendAndArchiveButton);
|
|
751
|
-
} else {
|
|
752
|
-
(0, _simulateMouseEvent.simulateClick)(this.getSendButton());
|
|
753
|
-
}
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
discard() {
|
|
757
|
-
(0, _simulateMouseEvent.simulateClick)(this.getDiscardButton());
|
|
758
|
-
}
|
|
759
|
-
popOut() {
|
|
760
|
-
if (!this.isInlineReplyForm()) {
|
|
761
|
-
throw new Error('Can only pop out inline reply compose views');
|
|
762
|
-
}
|
|
763
|
-
const popOutBtn = (0, _querySelectorOrFail.default)(this._element, '.M9 > [role=menu]:first-child > .SK > [role=menuitem]:last-child');
|
|
764
|
-
(0, _simulateMouseEvent.simulateClick)(popOutBtn);
|
|
765
|
-
}
|
|
766
|
-
overrideEditSubject() {
|
|
767
|
-
(0, _overrideEditSubject.default)(this._driver, this);
|
|
768
|
-
}
|
|
769
|
-
_hideDropzones() {
|
|
770
|
-
(0, _setCss.default)('compose dropzone hider', 'body > .aC7 .aC9 {visibility: hidden;}');
|
|
771
|
-
}
|
|
772
|
-
_reenableDropzones() {
|
|
773
|
-
(0, _setCss.default)('compose dropzone hider', null);
|
|
774
|
-
}
|
|
775
|
-
_dropzonesVisible() {
|
|
776
|
-
return (0, _find.default)(document.querySelectorAll('body > .aC7:not(.aWP)'), _isElementVisible.default) != null;
|
|
777
|
-
}
|
|
778
|
-
_findDropzoneForThisCompose(inline) {
|
|
779
|
-
// Iterate through all the dropzones and find the one visually contained by
|
|
780
|
-
// this compose.
|
|
781
|
-
const rect = this._element.getBoundingClientRect();
|
|
782
|
-
const dropzoneSelector = inline ? 'body > .aC7:not(.aWP)' : 'body > .aC7.aWP';
|
|
783
|
-
const el = _transducers.default.toArray(Array.prototype.slice.call(document.querySelectorAll(dropzoneSelector)), _transducers.default.compose(_transducers.default.filter(_isElementVisible.default), _transducers.default.filter(dropzone => {
|
|
784
|
-
const top = parseInt(dropzone.style.top, 10);
|
|
785
|
-
const bottom = top + parseInt(dropzone.style.height, 10);
|
|
786
|
-
const left = parseInt(dropzone.style.left, 10);
|
|
787
|
-
const right = left + parseInt(dropzone.style.width, 10);
|
|
788
|
-
return top >= rect.top && left >= rect.left && right <= rect.right && bottom <= rect.bottom;
|
|
789
|
-
}), _transducers.default.take(1)))[0];
|
|
790
|
-
if (!el) {
|
|
791
|
-
throw new Error('Failed to find dropzone');
|
|
792
|
-
}
|
|
793
|
-
return el;
|
|
794
|
-
}
|
|
795
|
-
async _attachFiles(files, inline) {
|
|
796
|
-
this._hideDropzones();
|
|
797
|
-
const endDrag = (0, _once.default)(() => (0, _simulateDragAndDrop.simulateDragEnd)(this._element, files));
|
|
798
|
-
try {
|
|
799
|
-
let firstLoop = true;
|
|
800
|
-
for (let partitionedFiles of _transducers.default.partition(files, 3)) {
|
|
801
|
-
if (firstLoop) {
|
|
802
|
-
firstLoop = false;
|
|
803
|
-
} else {
|
|
804
|
-
await (0, _pdelay.default)(500);
|
|
802
|
+
}
|
|
803
|
+
close() {
|
|
804
|
+
if (this.isInlineReplyForm()) {
|
|
805
|
+
console.warn("Trying to close an inline reply which doesn't work.");
|
|
806
|
+
return;
|
|
805
807
|
}
|
|
806
|
-
(
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
isInlineReplyForm() {
|
|
833
|
-
return this._isInlineReplyForm;
|
|
834
|
-
}
|
|
835
|
-
getBodyElement() {
|
|
836
|
-
const el = this.getMaybeBodyElement();
|
|
837
|
-
if (!el) throw new Error('Could not find body element');
|
|
838
|
-
return el;
|
|
839
|
-
}
|
|
840
|
-
getMaybeBodyElement() {
|
|
841
|
-
return this._element.querySelector('.Ap [g_editable=true]');
|
|
842
|
-
}
|
|
843
|
-
getTopFormElement() {
|
|
844
|
-
return (0, _querySelectorOrFail.default)(this._element, 'td > form');
|
|
845
|
-
}
|
|
846
|
-
getHTMLContent() {
|
|
847
|
-
return this.getBodyElement().innerHTML;
|
|
848
|
-
}
|
|
849
|
-
getTextContent() {
|
|
850
|
-
return this.getBodyElement().textContent;
|
|
851
|
-
}
|
|
852
|
-
getSelectedBodyHTML() {
|
|
853
|
-
return (0, _getSelection.getSelectedHTMLInElement)(this.getBodyElement(), this.getLastSelectionRange());
|
|
854
|
-
}
|
|
855
|
-
getSelectedBodyText() {
|
|
856
|
-
return (0, _getSelection.getSelectedTextInElement)(this.getBodyElement(), this.getLastSelectionRange());
|
|
857
|
-
}
|
|
858
|
-
getSubject() {
|
|
859
|
-
return this.getSubjectInput().value;
|
|
860
|
-
}
|
|
861
|
-
getSubjectInput() {
|
|
862
|
-
return this._element.querySelector('input[name=subjectbox]');
|
|
863
|
-
}
|
|
864
|
-
getMetadataFormElement() {
|
|
865
|
-
const container = this.getBodyElement().closest('.aoP');
|
|
866
|
-
if (!container) {
|
|
867
|
-
throw new Error('Could not find compose container');
|
|
868
|
-
}
|
|
869
|
-
return (0, _querySelectorOrFail.default)(container, 'form.bAs');
|
|
870
|
-
}
|
|
871
|
-
getToRecipients() {
|
|
872
|
-
return (0, _getRecipients.default)(this, 'to');
|
|
873
|
-
}
|
|
874
|
-
getCcRecipients() {
|
|
875
|
-
return (0, _getRecipients.default)(this, 'cc');
|
|
876
|
-
}
|
|
877
|
-
getBccRecipients() {
|
|
878
|
-
return (0, _getRecipients.default)(this, 'bcc');
|
|
879
|
-
}
|
|
880
|
-
getAdditionalActionToolbar() {
|
|
881
|
-
return require('./gmail-compose-view/get-additional-action-toolbar').default(this);
|
|
882
|
-
}
|
|
883
|
-
updateInsertMoreAreaLeft(oldFormattingAreaOffsetLeft) {
|
|
884
|
-
(0, _updateInsertMoreAreaLeft.default)(this, oldFormattingAreaOffsetLeft);
|
|
885
|
-
}
|
|
886
|
-
_getFormattingAreaOffsetLeft() {
|
|
887
|
-
return (0, _getFormattingAreaOffsetLeft.default)(this);
|
|
888
|
-
}
|
|
889
|
-
getFormattingArea() {
|
|
890
|
-
let formattingArea = this._formattingArea;
|
|
891
|
-
if (!formattingArea) {
|
|
892
|
-
formattingArea = this._formattingArea = this._element.querySelector('.oc');
|
|
893
|
-
}
|
|
894
|
-
return formattingArea;
|
|
895
|
-
}
|
|
896
|
-
getFormattingToolbar() {
|
|
897
|
-
return this._element.querySelector('.aX');
|
|
898
|
-
}
|
|
899
|
-
getFormattingToolbarArrow() {
|
|
900
|
-
const el = this.getFormattingToolbar();
|
|
901
|
-
if (!el) throw new Error('Failed to find formatting toolbar');
|
|
902
|
-
return (0, _querySelectorOrFail.default)(el, '.aA4');
|
|
903
|
-
}
|
|
904
|
-
getFormattingToolbarToggleButton() {
|
|
905
|
-
const innerElement = (0, _querySelectorOrFail.default)(this._element, '[role=button] .dv');
|
|
906
|
-
const btn = (0, _closestNg.default)(innerElement, '[role=button]');
|
|
907
|
-
if (!btn) throw new Error('failed to find button');
|
|
908
|
-
return btn;
|
|
909
|
-
}
|
|
910
|
-
getStatusBarPrependContainer() {
|
|
911
|
-
return this._element.querySelector('.inboxsdk__compose_statusBarPrependContainer');
|
|
912
|
-
}
|
|
913
|
-
getScrollBody() {
|
|
914
|
-
var scrollBody = this._element.querySelector('table .GP');
|
|
915
|
-
if (!scrollBody) {
|
|
916
|
-
throw new Error('Failed to find scroll body');
|
|
917
|
-
}
|
|
918
|
-
return scrollBody;
|
|
919
|
-
}
|
|
920
|
-
getStatusArea() {
|
|
921
|
-
let statusArea = this._element.querySelector('.aDg .aDj > .aDh');
|
|
922
|
-
if (!statusArea) throw new Error('Failed to find status area');
|
|
923
|
-
return statusArea;
|
|
924
|
-
}
|
|
925
|
-
getInsertMoreArea() {
|
|
926
|
-
return (0, _querySelectorOrFail.default)(this._element, '.eq');
|
|
927
|
-
}
|
|
928
|
-
getInsertLinkButton() {
|
|
929
|
-
return (0, _querySelectorOrFail.default)(this._element, '.e5.aaA.aMZ');
|
|
930
|
-
}
|
|
931
|
-
getSendButton() {
|
|
932
|
-
return (0, _querySelectorOrFail.default)(this._element, '.IZ .Up div > div[role=button]:not(.Uo):not([aria-haspopup=true]):not([class^=inboxsdk_])');
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
// When schedule send is available, this returns the element that contains both buttons.
|
|
936
|
-
getSendButtonGroup() {
|
|
937
|
-
const scheduleSend = this._element.querySelector('.IZ .Up div > [role=button][aria-haspopup=true]:not([class^=inboxsdk_])');
|
|
938
|
-
if (scheduleSend) {
|
|
939
|
-
return scheduleSend.parentElement;
|
|
940
|
-
}
|
|
941
|
-
return this.getSendButton();
|
|
942
|
-
}
|
|
943
|
-
getSendAndArchiveButton() {
|
|
944
|
-
if (!this.isReply()) {
|
|
945
|
-
return null;
|
|
946
|
-
}
|
|
947
|
-
const sendAndArchiveButton = this._element.querySelector('.IZ .Up div > div[role=button].Uo:not([aria-haspopup=true]):not([class^=inboxsdk_])');
|
|
948
|
-
if (sendAndArchiveButton) {
|
|
949
|
-
return sendAndArchiveButton;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
// TODO is the rest of this function necessary?
|
|
953
|
-
|
|
954
|
-
const sendButton = this.getSendButton();
|
|
955
|
-
const parent = sendButton.parentElement;
|
|
956
|
-
if (!(parent instanceof HTMLElement)) throw new Error('should not happen');
|
|
957
|
-
if (parent.childElementCount <= 1) {
|
|
958
|
-
this._driver.getLogger().eventSdkPassive('getSendAndArchiveButton - old method - failed to find, childElementCount <= 1');
|
|
959
|
-
return null;
|
|
960
|
-
}
|
|
961
|
-
const firstNotSendElement = parent.children[0] !== sendButton ? parent.children[0] : parent.children[1];
|
|
962
|
-
const result = !firstNotSendElement ? null : firstNotSendElement.querySelector('[role=button]');
|
|
963
|
-
if (result) {
|
|
964
|
-
this._driver.getLogger().eventSdkPassive('getSendAndArchiveButton - old method - found');
|
|
965
|
-
} else {
|
|
966
|
-
this._driver.getLogger().eventSdkPassive('getSendAndArchiveButton - old method - failed to find');
|
|
967
|
-
}
|
|
968
|
-
return result;
|
|
969
|
-
}
|
|
970
|
-
getCloseButton() {
|
|
971
|
-
return this._element.querySelectorAll('.Hm > img')[2];
|
|
972
|
-
}
|
|
973
|
-
getMoleSwitchButton() {
|
|
974
|
-
return this._element.querySelectorAll('.Hm > img')[1];
|
|
975
|
-
}
|
|
976
|
-
getBottomBarTable() {
|
|
977
|
-
return (0, _querySelectorOrFail.default)(this._element, '.aoP .aDh > table');
|
|
978
|
-
}
|
|
979
|
-
getBottomToolbarContainer() {
|
|
980
|
-
return (0, _querySelectorOrFail.default)(this._element, '.aoP .aDj');
|
|
981
|
-
}
|
|
982
|
-
getDiscardButton() {
|
|
983
|
-
return (0, _querySelectorOrFail.default)(this._element, '.gU .oh');
|
|
984
|
-
}
|
|
985
|
-
getComposeID() {
|
|
986
|
-
return this._composeID;
|
|
987
|
-
}
|
|
988
|
-
getInitialMessageID() {
|
|
989
|
-
return this._initialMessageId;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
// For use only when isUsingSyncAPI() is true — gets the draft ID
|
|
993
|
-
// from the input that used to hold the hex message ID. Still does not
|
|
994
|
-
// populate until first save.
|
|
995
|
-
_getDraftIDfromForm() {
|
|
996
|
-
const value = this._messageIDElement && this._messageIDElement.value || null;
|
|
997
|
-
if (typeof value === 'string' && value !== 'undefined' && value !== 'null') {
|
|
998
|
-
if (this._driver.isUsingSyncAPI()) {
|
|
999
|
-
return value.replace('#', '').replace('msg-a:', '');
|
|
1000
|
-
} else {
|
|
1001
|
-
this._driver.getLogger().error(new Error('Invalid draft id in element'), {
|
|
1002
|
-
value
|
|
808
|
+
this._element.dispatchEvent(new CustomEvent('closedProgrammatically', {
|
|
809
|
+
bubbles: false,
|
|
810
|
+
cancelable: false,
|
|
811
|
+
detail: null,
|
|
812
|
+
}));
|
|
813
|
+
if (this._isFullscreen) {
|
|
814
|
+
this._eventStream
|
|
815
|
+
.filter(({ eventName }) => eventName === 'fullscreenChanged')
|
|
816
|
+
.onValue(() => simulateClick(this.getCloseButton()));
|
|
817
|
+
simulateClick(this.getMoleSwitchButton());
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
simulateClick(this.getCloseButton());
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
send({ sendAndArchive }) {
|
|
824
|
+
// asap necessary so if send() is called after presending event.cancel(), the new presending event
|
|
825
|
+
// must happen after the sendCanceled event (which is also delayed by asap).
|
|
826
|
+
asap(() => {
|
|
827
|
+
const sendAndArchiveButton = this.getSendAndArchiveButton();
|
|
828
|
+
if (sendAndArchive && sendAndArchiveButton) {
|
|
829
|
+
simulateClick(sendAndArchiveButton);
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
simulateClick(this.getSendButton());
|
|
833
|
+
}
|
|
1003
834
|
});
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
835
|
+
}
|
|
836
|
+
discard() {
|
|
837
|
+
simulateClick(this.getDiscardButton());
|
|
838
|
+
}
|
|
839
|
+
popOut() {
|
|
840
|
+
if (!this.isInlineReplyForm()) {
|
|
841
|
+
throw new Error('Can only pop out inline reply compose views');
|
|
842
|
+
}
|
|
843
|
+
const popOutBtn = querySelector(this._element, '.M9 > [role=menu]:first-child > .SK > [role=menuitem]:last-child');
|
|
844
|
+
simulateClick(popOutBtn);
|
|
845
|
+
}
|
|
846
|
+
overrideEditSubject() {
|
|
847
|
+
overrideEditSubject(this._driver, this);
|
|
848
|
+
}
|
|
849
|
+
_hideDropzones() {
|
|
850
|
+
setCss('compose dropzone hider', 'body > .aC7 .aC9 {visibility: hidden;}');
|
|
851
|
+
}
|
|
852
|
+
_reenableDropzones() {
|
|
853
|
+
setCss('compose dropzone hider', null);
|
|
854
|
+
}
|
|
855
|
+
_dropzonesVisible() {
|
|
856
|
+
return (find(document.querySelectorAll('body > .aC7:not(.aWP)'), isElementVisible) != null);
|
|
857
|
+
}
|
|
858
|
+
_findDropzoneForThisCompose(inline) {
|
|
859
|
+
// Iterate through all the dropzones and find the one visually contained by
|
|
860
|
+
// this compose.
|
|
861
|
+
const rect = this._element.getBoundingClientRect();
|
|
862
|
+
const dropzoneSelector = inline
|
|
863
|
+
? 'body > .aC7:not(.aWP)'
|
|
864
|
+
: 'body > .aC7.aWP';
|
|
865
|
+
const el = t.toArray(Array.prototype.slice.call(document.querySelectorAll(dropzoneSelector)), t.compose(t.filter(isElementVisible), t.filter((dropzone) => {
|
|
866
|
+
const top = parseInt(dropzone.style.top, 10);
|
|
867
|
+
const bottom = top + parseInt(dropzone.style.height, 10);
|
|
868
|
+
const left = parseInt(dropzone.style.left, 10);
|
|
869
|
+
const right = left + parseInt(dropzone.style.width, 10);
|
|
870
|
+
return (top >= rect.top &&
|
|
871
|
+
left >= rect.left &&
|
|
872
|
+
right <= rect.right &&
|
|
873
|
+
bottom <= rect.bottom);
|
|
874
|
+
}), t.take(1)))[0];
|
|
875
|
+
if (!el) {
|
|
876
|
+
throw new Error('Failed to find dropzone');
|
|
1020
877
|
}
|
|
1021
|
-
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
878
|
+
return el;
|
|
879
|
+
}
|
|
880
|
+
async _attachFiles(files, inline) {
|
|
881
|
+
this._hideDropzones();
|
|
882
|
+
const endDrag = once(() => simulateDragEnd(this._element, files));
|
|
883
|
+
try {
|
|
884
|
+
let firstLoop = true;
|
|
885
|
+
for (const partitionedFiles of t.partition(files, 3)) {
|
|
886
|
+
if (firstLoop) {
|
|
887
|
+
firstLoop = false;
|
|
888
|
+
}
|
|
889
|
+
else {
|
|
890
|
+
await delay(500);
|
|
891
|
+
}
|
|
892
|
+
simulateDragOver(this._element, partitionedFiles);
|
|
893
|
+
await waitFor(() => this._dropzonesVisible(), 20 * 1000);
|
|
894
|
+
const dropzone = this._findDropzoneForThisCompose(inline);
|
|
895
|
+
simulateDrop(dropzone, partitionedFiles);
|
|
896
|
+
endDrag();
|
|
897
|
+
await waitFor(() => !this._dropzonesVisible(), 20 * 1000);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
catch (err) {
|
|
901
|
+
this._driver.getLogger().error(err);
|
|
902
|
+
}
|
|
903
|
+
finally {
|
|
904
|
+
endDrag();
|
|
905
|
+
this._reenableDropzones();
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
attachFiles(files) {
|
|
909
|
+
return this._attachFiles(files, false);
|
|
910
|
+
}
|
|
911
|
+
attachInlineFiles(files) {
|
|
912
|
+
return this._attachFiles(files, true);
|
|
913
|
+
}
|
|
914
|
+
isForward() {
|
|
915
|
+
return Boolean(this._element.querySelector('.Un.J-JN-M-I .mI'));
|
|
916
|
+
}
|
|
917
|
+
isReply() {
|
|
918
|
+
return this._isInlineReplyForm || !!this._element.querySelector('.HQ');
|
|
919
|
+
}
|
|
920
|
+
isInlineReplyForm() {
|
|
921
|
+
return this._isInlineReplyForm;
|
|
922
|
+
}
|
|
923
|
+
getBodyElement() {
|
|
924
|
+
const el = this.getMaybeBodyElement();
|
|
925
|
+
if (!el)
|
|
926
|
+
throw new Error('Could not find body element');
|
|
927
|
+
return el;
|
|
928
|
+
}
|
|
929
|
+
getMaybeBodyElement() {
|
|
930
|
+
return this._element.querySelector('.Ap [g_editable=true]');
|
|
931
|
+
}
|
|
932
|
+
getTopFormElement() {
|
|
933
|
+
return querySelector(this._element, 'td > form');
|
|
934
|
+
}
|
|
935
|
+
getHTMLContent() {
|
|
936
|
+
return this.getBodyElement().innerHTML;
|
|
937
|
+
}
|
|
938
|
+
getTextContent() {
|
|
939
|
+
return this.getBodyElement().textContent;
|
|
940
|
+
}
|
|
941
|
+
getSelectedBodyHTML() {
|
|
942
|
+
return getSelectedHTMLInElement(this.getBodyElement(), this.getLastSelectionRange());
|
|
943
|
+
}
|
|
944
|
+
getSelectedBodyText() {
|
|
945
|
+
return getSelectedTextInElement(this.getBodyElement(), this.getLastSelectionRange());
|
|
946
|
+
}
|
|
947
|
+
getSubject() {
|
|
948
|
+
return this.getSubjectInput().value;
|
|
949
|
+
}
|
|
950
|
+
getSubjectInput() {
|
|
951
|
+
return this._element.querySelector('input[name=subjectbox]');
|
|
952
|
+
}
|
|
953
|
+
getMetadataFormElement() {
|
|
954
|
+
const container = this.getBodyElement().closest('.aoP');
|
|
955
|
+
if (!container) {
|
|
956
|
+
throw new Error('Could not find compose container');
|
|
957
|
+
}
|
|
958
|
+
return querySelector(container, 'form.bAs');
|
|
959
|
+
}
|
|
960
|
+
getToRecipients() {
|
|
961
|
+
return getRecipients(this, 'to');
|
|
962
|
+
}
|
|
963
|
+
getCcRecipients() {
|
|
964
|
+
return getRecipients(this, 'cc');
|
|
965
|
+
}
|
|
966
|
+
getBccRecipients() {
|
|
967
|
+
return getRecipients(this, 'bcc');
|
|
968
|
+
}
|
|
969
|
+
getAdditionalActionToolbar() {
|
|
970
|
+
return require('./gmail-compose-view/get-additional-action-toolbar').default(this);
|
|
971
|
+
}
|
|
972
|
+
updateInsertMoreAreaLeft(oldFormattingAreaOffsetLeft) {
|
|
973
|
+
updateInsertMoreAreaLeft(this, oldFormattingAreaOffsetLeft);
|
|
974
|
+
}
|
|
975
|
+
_getFormattingAreaOffsetLeft() {
|
|
976
|
+
return getFormattingAreaOffsetLeft(this);
|
|
977
|
+
}
|
|
978
|
+
getFormattingArea() {
|
|
979
|
+
let formattingArea = this._formattingArea;
|
|
980
|
+
if (!formattingArea) {
|
|
981
|
+
formattingArea = this._formattingArea =
|
|
982
|
+
this._element.querySelector('.oc');
|
|
983
|
+
}
|
|
984
|
+
return formattingArea;
|
|
985
|
+
}
|
|
986
|
+
getFormattingToolbar() {
|
|
987
|
+
return this._element.querySelector('.aX');
|
|
988
|
+
}
|
|
989
|
+
getFormattingToolbarArrow() {
|
|
990
|
+
const el = this.getFormattingToolbar();
|
|
991
|
+
if (!el)
|
|
992
|
+
throw new Error('Failed to find formatting toolbar');
|
|
993
|
+
return querySelector(el, '.aA4');
|
|
994
|
+
}
|
|
995
|
+
getFormattingToolbarToggleButton() {
|
|
996
|
+
const innerElement = querySelector(this._element, '[role=button] .dv');
|
|
997
|
+
const btn = closest(innerElement, '[role=button]');
|
|
998
|
+
if (!btn)
|
|
999
|
+
throw new Error('failed to find button');
|
|
1000
|
+
return btn;
|
|
1001
|
+
}
|
|
1002
|
+
getStatusBarPrependContainer() {
|
|
1003
|
+
return this._element.querySelector('.inboxsdk__compose_statusBarPrependContainer');
|
|
1004
|
+
}
|
|
1005
|
+
getScrollBody() {
|
|
1006
|
+
var scrollBody = this._element.querySelector('table .GP');
|
|
1007
|
+
if (!scrollBody) {
|
|
1008
|
+
throw new Error('Failed to find scroll body');
|
|
1009
|
+
}
|
|
1010
|
+
return scrollBody;
|
|
1011
|
+
}
|
|
1012
|
+
getStatusArea() {
|
|
1013
|
+
const statusArea = this._element.querySelector('.aDg .aDj > .aDh');
|
|
1014
|
+
if (!statusArea)
|
|
1015
|
+
throw new Error('Failed to find status area');
|
|
1016
|
+
return statusArea;
|
|
1017
|
+
}
|
|
1018
|
+
getInsertMoreArea() {
|
|
1019
|
+
return querySelector(this._element, '.eq');
|
|
1020
|
+
}
|
|
1021
|
+
getInsertLinkButton() {
|
|
1022
|
+
return querySelector(this._element, '.e5.aaA.aMZ');
|
|
1023
|
+
}
|
|
1024
|
+
getSendButton() {
|
|
1025
|
+
return querySelector(this._element, '.IZ .Up div > div[role=button]:not(.Uo):not([aria-haspopup=true]):not([class^=inboxsdk_])');
|
|
1026
|
+
}
|
|
1027
|
+
// When schedule send is available, this returns the element that contains both buttons.
|
|
1028
|
+
getSendButtonGroup() {
|
|
1029
|
+
const scheduleSend = this._element.querySelector('.IZ .Up div > [role=button][aria-haspopup=true]:not([class^=inboxsdk_])');
|
|
1030
|
+
if (scheduleSend) {
|
|
1031
|
+
return scheduleSend.parentElement;
|
|
1032
|
+
}
|
|
1033
|
+
return this.getSendButton();
|
|
1034
|
+
}
|
|
1035
|
+
getSendAndArchiveButton() {
|
|
1036
|
+
if (!this.isReply()) {
|
|
1051
1037
|
return null;
|
|
1052
|
-
}
|
|
1053
|
-
return draftID;
|
|
1054
1038
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
return null;
|
|
1059
|
-
} else {
|
|
1060
|
-
return this.getDraftID();
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
getDraftID() {
|
|
1065
|
-
let draftIDpromise = this._draftIDpromise;
|
|
1066
|
-
if (!draftIDpromise) {
|
|
1067
|
-
draftIDpromise = this._draftIDpromise = this._getDraftIDimplementation();
|
|
1068
|
-
}
|
|
1069
|
-
return draftIDpromise;
|
|
1070
|
-
}
|
|
1071
|
-
async _getDraftIDimplementation() {
|
|
1072
|
-
if (this._driver.isUsingSyncAPI()) {
|
|
1073
|
-
const draftID = this._getDraftIDfromForm();
|
|
1074
|
-
// we want to keep the semantics that getDraftID doesn't return until
|
|
1075
|
-
// the draft is actually saved on Gmail's servers
|
|
1076
|
-
if (this._messageId) {
|
|
1077
|
-
// if we have a messageId that means there is a draft on the server
|
|
1078
|
-
return draftID;
|
|
1079
|
-
} else {
|
|
1080
|
-
// there may be a draft on the server, so let's find out
|
|
1081
|
-
const syncMessageId = this._getMessageIDfromForm();
|
|
1082
|
-
if (syncMessageId) {
|
|
1083
|
-
try {
|
|
1084
|
-
// If this succeeds, then the draft must exist on the server and we
|
|
1085
|
-
// can safely return the draft id we know.
|
|
1086
|
-
const gmailMessageId = await this._driver.getGmailMessageIdForSyncDraftId(syncMessageId);
|
|
1087
|
-
} catch (e) {
|
|
1088
|
-
// draft doesn't exist so we wait until it does
|
|
1089
|
-
await this._eventStream.filter(_ref8 => {
|
|
1090
|
-
let {
|
|
1091
|
-
eventName
|
|
1092
|
-
} = _ref8;
|
|
1093
|
-
return eventName === 'draftSaved';
|
|
1094
|
-
}).beforeEnd(() => null).map(() => this._getDraftIDfromForm()).take(1).toPromise();
|
|
1095
|
-
}
|
|
1096
|
-
return draftID;
|
|
1039
|
+
const sendAndArchiveButton = this._element.querySelector('.IZ .Up div > div[role=button].Uo:not([aria-haspopup=true]):not([class^=inboxsdk_])');
|
|
1040
|
+
if (sendAndArchiveButton) {
|
|
1041
|
+
return sendAndArchiveButton;
|
|
1097
1042
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
if (!this._messageId) {
|
|
1108
|
-
// The compose was closed before it got an id.
|
|
1043
|
+
// TODO is the rest of this function necessary?
|
|
1044
|
+
const sendButton = this.getSendButton();
|
|
1045
|
+
const parent = sendButton.parentElement;
|
|
1046
|
+
if (!(parent instanceof HTMLElement))
|
|
1047
|
+
throw new Error('should not happen');
|
|
1048
|
+
if (parent.childElementCount <= 1) {
|
|
1049
|
+
this._driver
|
|
1050
|
+
.getLogger()
|
|
1051
|
+
.eventSdkPassive('getSendAndArchiveButton - old method - failed to find, childElementCount <= 1');
|
|
1109
1052
|
return null;
|
|
1110
|
-
}
|
|
1111
1053
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1054
|
+
const firstNotSendElement = parent.children[0] !== sendButton
|
|
1055
|
+
? parent.children[0]
|
|
1056
|
+
: parent.children[1];
|
|
1057
|
+
const result = !firstNotSendElement
|
|
1058
|
+
? null
|
|
1059
|
+
: firstNotSendElement.querySelector('[role=button]');
|
|
1060
|
+
if (result) {
|
|
1061
|
+
this._driver
|
|
1062
|
+
.getLogger()
|
|
1063
|
+
.eventSdkPassive('getSendAndArchiveButton - old method - found');
|
|
1064
|
+
}
|
|
1065
|
+
else {
|
|
1066
|
+
this._driver
|
|
1067
|
+
.getLogger()
|
|
1068
|
+
.eventSdkPassive('getSendAndArchiveButton - old method - failed to find');
|
|
1069
|
+
}
|
|
1070
|
+
return result;
|
|
1071
|
+
}
|
|
1072
|
+
getCloseButton() {
|
|
1073
|
+
return this._element.querySelectorAll('.Hm > img')[2];
|
|
1074
|
+
}
|
|
1075
|
+
getMoleSwitchButton() {
|
|
1076
|
+
return this._element.querySelectorAll('.Hm > img')[1];
|
|
1077
|
+
}
|
|
1078
|
+
getBottomBarTable() {
|
|
1079
|
+
return querySelector(this._element, '.aoP .aDh > table');
|
|
1080
|
+
}
|
|
1081
|
+
getBottomToolbarContainer() {
|
|
1082
|
+
return querySelector(this._element, '.aoP .aDj');
|
|
1083
|
+
}
|
|
1084
|
+
getDiscardButton() {
|
|
1085
|
+
return querySelector(this._element, '.gU .oh');
|
|
1086
|
+
}
|
|
1087
|
+
getComposeID() {
|
|
1088
|
+
return this._composeID;
|
|
1089
|
+
}
|
|
1090
|
+
getInitialMessageID() {
|
|
1091
|
+
return this._initialMessageId;
|
|
1092
|
+
}
|
|
1093
|
+
// For use only when isUsingSyncAPI() is true — gets the draft ID
|
|
1094
|
+
// from the input that used to hold the hex message ID. Still does not
|
|
1095
|
+
// populate until first save.
|
|
1096
|
+
_getDraftIDfromForm() {
|
|
1097
|
+
const value = (this._messageIDElement && this._messageIDElement.value) || null;
|
|
1098
|
+
if (typeof value === 'string' &&
|
|
1099
|
+
value !== 'undefined' &&
|
|
1100
|
+
value !== 'null') {
|
|
1101
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
1102
|
+
return value.replace('#', '').replace('msg-a:', '');
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
this._driver
|
|
1106
|
+
.getLogger()
|
|
1107
|
+
.error(new Error('Invalid draft id in element'), {
|
|
1108
|
+
value,
|
|
1109
|
+
});
|
|
1133
1110
|
}
|
|
1134
|
-
|
|
1135
|
-
// maaaaybe the draft is saving, but we failed to detect that.
|
|
1136
|
-
// Let's log whether things would've worked out a little in the future.
|
|
1137
|
-
setTimeout(async () => {
|
|
1138
|
-
const newMessageId = this._messageId;
|
|
1139
|
-
if (!newMessageId) {
|
|
1140
|
-
throw new Error('Should not happen');
|
|
1141
|
-
}
|
|
1142
|
-
const {
|
|
1143
|
-
draftID,
|
|
1144
|
-
debugData
|
|
1145
|
-
} = await this._driver.getDraftIDForMessageID(newMessageId, true);
|
|
1146
|
-
const err = new Error('Failed to read draft ID -- after check');
|
|
1147
|
-
this._driver.getLogger().error(err, {
|
|
1148
|
-
message: 'getDraftID error -- after check',
|
|
1149
|
-
messageIdChanged: messageId !== newMessageId,
|
|
1150
|
-
gotDraftID: draftID != null,
|
|
1151
|
-
debugData: draftID ? null : debugData
|
|
1152
|
-
});
|
|
1153
|
-
}, 10 * 1000);
|
|
1154
|
-
throw new Error('Failed to read draft ID');
|
|
1155
|
-
}
|
|
1156
|
-
lastMessageId = messageId;
|
|
1157
|
-
const {
|
|
1158
|
-
draftID,
|
|
1159
|
-
debugData
|
|
1160
|
-
} = await this._driver.getDraftIDForMessageID(messageId);
|
|
1161
|
-
lastDebugData = debugData;
|
|
1162
|
-
if (draftID) {
|
|
1163
|
-
return draftID;
|
|
1164
|
-
}
|
|
1165
1111
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1112
|
+
return null;
|
|
1113
|
+
}
|
|
1114
|
+
_getMessageIDfromForm() {
|
|
1115
|
+
const value = (this._messageIDElement && this._messageIDElement.value) || null;
|
|
1116
|
+
if (typeof value === 'string' &&
|
|
1117
|
+
value !== 'undefined' &&
|
|
1118
|
+
value !== 'null') {
|
|
1119
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
1120
|
+
return value.replace('#', ''); //annoyingly the hash is included
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
if (/^[0-9a-f]+$/i.test(value)) {
|
|
1124
|
+
return value;
|
|
1125
|
+
}
|
|
1126
|
+
else {
|
|
1127
|
+
this._driver
|
|
1128
|
+
.getLogger()
|
|
1129
|
+
.error(new Error('Invalid message id in element'), {
|
|
1130
|
+
value,
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
getMessageID() {
|
|
1138
|
+
return this._messageId;
|
|
1139
|
+
}
|
|
1140
|
+
getTargetMessageID() {
|
|
1141
|
+
return this._targetMessageID;
|
|
1142
|
+
}
|
|
1143
|
+
getThreadID() {
|
|
1144
|
+
return this._threadID;
|
|
1145
|
+
}
|
|
1146
|
+
async getCurrentDraftID() {
|
|
1147
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
1148
|
+
// This function is mostly a mirror of _getDraftIDimplementation, but
|
|
1149
|
+
// instead of waiting when finding out it's not saved, just returns null.
|
|
1150
|
+
const draftID = this._getDraftIDfromForm();
|
|
1151
|
+
if (this._messageId) {
|
|
1152
|
+
return draftID;
|
|
1153
|
+
}
|
|
1154
|
+
else {
|
|
1155
|
+
const syncMessageId = this._getMessageIDfromForm();
|
|
1156
|
+
if (syncMessageId) {
|
|
1157
|
+
try {
|
|
1158
|
+
// If this succeeds, then the draft must exist on the server and we
|
|
1159
|
+
// can safely return the draft id we know.
|
|
1160
|
+
const gmailMessageId = await this._driver.getGmailMessageIdForSyncDraftId(syncMessageId);
|
|
1161
|
+
}
|
|
1162
|
+
catch (e) {
|
|
1163
|
+
// ignore error, it's probably that the draft isn't saved yet.
|
|
1164
|
+
return null;
|
|
1165
|
+
}
|
|
1166
|
+
return draftID;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
else {
|
|
1171
|
+
if (!this.getMessageID()) {
|
|
1172
|
+
return null;
|
|
1173
|
+
}
|
|
1174
|
+
else {
|
|
1175
|
+
return this.getDraftID();
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
getDraftID() {
|
|
1180
|
+
let draftIDpromise = this._draftIDpromise;
|
|
1181
|
+
if (!draftIDpromise) {
|
|
1182
|
+
draftIDpromise = this._draftIDpromise = this._getDraftIDimplementation();
|
|
1183
|
+
}
|
|
1184
|
+
return draftIDpromise;
|
|
1185
|
+
}
|
|
1186
|
+
async _getDraftIDimplementation() {
|
|
1187
|
+
if (this._driver.isUsingSyncAPI()) {
|
|
1188
|
+
const draftID = this._getDraftIDfromForm();
|
|
1189
|
+
// we want to keep the semantics that getDraftID doesn't return until
|
|
1190
|
+
// the draft is actually saved on Gmail's servers
|
|
1191
|
+
if (this._messageId) {
|
|
1192
|
+
// if we have a messageId that means there is a draft on the server
|
|
1193
|
+
return draftID;
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
// there may be a draft on the server, so let's find out
|
|
1197
|
+
const syncMessageId = this._getMessageIDfromForm();
|
|
1198
|
+
if (syncMessageId) {
|
|
1199
|
+
try {
|
|
1200
|
+
// If this succeeds, then the draft must exist on the server and we
|
|
1201
|
+
// can safely return the draft id we know.
|
|
1202
|
+
const gmailMessageId = await this._driver.getGmailMessageIdForSyncDraftId(syncMessageId);
|
|
1203
|
+
}
|
|
1204
|
+
catch (e) {
|
|
1205
|
+
// draft doesn't exist so we wait until it does
|
|
1206
|
+
await this._eventStream
|
|
1207
|
+
.filter(({ eventName }) => eventName === 'draftSaved')
|
|
1208
|
+
.beforeEnd(() => null)
|
|
1209
|
+
.map(() => this._getDraftIDfromForm())
|
|
1210
|
+
.take(1)
|
|
1211
|
+
.toPromise();
|
|
1212
|
+
}
|
|
1213
|
+
return draftID;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
else {
|
|
1218
|
+
let i = -1;
|
|
1219
|
+
let lastDebugData = null;
|
|
1220
|
+
try {
|
|
1221
|
+
// If this compose view doesn't have a message id yet, wait until it gets
|
|
1222
|
+
// one or it's closed.
|
|
1223
|
+
if (!this._messageId) {
|
|
1224
|
+
await this._eventStream
|
|
1225
|
+
.filter((event) => event.eventName === 'messageIDChange')
|
|
1226
|
+
.beforeEnd(() => null)
|
|
1227
|
+
.take(1)
|
|
1228
|
+
.toPromise();
|
|
1229
|
+
if (!this._messageId) {
|
|
1230
|
+
// The compose was closed before it got an id.
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
// We make an AJAX request against gmail to find the draft ID for our
|
|
1235
|
+
// current message ID. However, our message ID can change before that
|
|
1236
|
+
// request finishes. If we fail to get our draft ID and we see that our
|
|
1237
|
+
// message ID has changed since we made the request, then we try again.
|
|
1238
|
+
let lastMessageId = null;
|
|
1239
|
+
// eslint-disable-next-line no-constant-condition
|
|
1240
|
+
while (true) {
|
|
1241
|
+
i++;
|
|
1242
|
+
const messageId = this._messageId;
|
|
1243
|
+
if (!messageId) {
|
|
1244
|
+
throw new Error('Should not happen');
|
|
1245
|
+
}
|
|
1246
|
+
if (lastMessageId === messageId) {
|
|
1247
|
+
// It's possible that the server received a draft save request from us
|
|
1248
|
+
// already, causing the draft id lookup to fail, but we haven't gotten
|
|
1249
|
+
// the draft save response yet. Wait for that response to finish and
|
|
1250
|
+
// keep trying if it looks like that might be the case.
|
|
1251
|
+
if (this._draftSaving) {
|
|
1252
|
+
await this._eventStream
|
|
1253
|
+
.filter((event) => event.eventName === 'messageIDChange')
|
|
1254
|
+
.beforeEnd(() => null)
|
|
1255
|
+
.take(1)
|
|
1256
|
+
.toPromise();
|
|
1257
|
+
continue;
|
|
1258
|
+
}
|
|
1259
|
+
// maaaaybe the draft is saving, but we failed to detect that.
|
|
1260
|
+
// Let's log whether things would've worked out a little in the future.
|
|
1261
|
+
setTimeout(async () => {
|
|
1262
|
+
const newMessageId = this._messageId;
|
|
1263
|
+
if (!newMessageId) {
|
|
1264
|
+
throw new Error('Should not happen');
|
|
1265
|
+
}
|
|
1266
|
+
const { draftID, debugData } = await this._driver.getDraftIDForMessageID(newMessageId, true);
|
|
1267
|
+
const err = new Error('Failed to read draft ID -- after check');
|
|
1268
|
+
this._driver.getLogger().error(err, {
|
|
1269
|
+
message: 'getDraftID error -- after check',
|
|
1270
|
+
messageIdChanged: messageId !== newMessageId,
|
|
1271
|
+
gotDraftID: draftID != null,
|
|
1272
|
+
debugData: draftID ? null : debugData,
|
|
1273
|
+
});
|
|
1274
|
+
}, 10 * 1000);
|
|
1275
|
+
throw new Error('Failed to read draft ID');
|
|
1276
|
+
}
|
|
1277
|
+
lastMessageId = messageId;
|
|
1278
|
+
const { draftID, debugData } = await this._driver.getDraftIDForMessageID(messageId);
|
|
1279
|
+
lastDebugData = debugData;
|
|
1280
|
+
if (draftID) {
|
|
1281
|
+
return draftID;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
catch (err) {
|
|
1286
|
+
this._driver.getLogger().error(err, {
|
|
1287
|
+
message: 'getDraftID error',
|
|
1288
|
+
removedFromDOM: !document.contains(this._element),
|
|
1289
|
+
destroyed: this._destroyed,
|
|
1290
|
+
isFullscreen: this._isFullscreen,
|
|
1291
|
+
isStandalone: this._isStandalone,
|
|
1292
|
+
emailWasSent: this._emailWasSent,
|
|
1293
|
+
i,
|
|
1294
|
+
lastDebugData,
|
|
1295
|
+
});
|
|
1296
|
+
throw err;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
addManagedViewController(viewController) {
|
|
1301
|
+
this._managedViewControllers.push(viewController);
|
|
1302
|
+
}
|
|
1303
|
+
ensureGroupingIsOpen(type) {
|
|
1304
|
+
ensureGroupingIsOpen(this._element, type);
|
|
1305
|
+
}
|
|
1306
|
+
ensureAppButtonToolbarsAreClosed() {
|
|
1307
|
+
ensureAppButtonToolbarsAreClosed(this._element);
|
|
1308
|
+
}
|
|
1309
|
+
isMinimized() {
|
|
1310
|
+
const element = this.getElement();
|
|
1311
|
+
const bodyElement = this.getMaybeBodyElement();
|
|
1312
|
+
const bodyContainer = find(element.children, (child) => child.contains(bodyElement));
|
|
1313
|
+
if (!bodyContainer) {
|
|
1314
|
+
if (!hasReportedMissingBody) {
|
|
1315
|
+
hasReportedMissingBody = true;
|
|
1316
|
+
this._driver
|
|
1317
|
+
.getLogger()
|
|
1318
|
+
.error(new Error('isMinimized failed to find bodyContainer'), {
|
|
1319
|
+
bodyElement: !!bodyElement,
|
|
1320
|
+
hasMessageIDElement: !!this._messageIDElement,
|
|
1321
|
+
ended: this._eventStream.ended,
|
|
1322
|
+
bodyElStillInCompose: this._element.contains(this._seenBodyElement),
|
|
1323
|
+
seenBodyElHtml: censorHTMLstring(this._seenBodyElement.outerHTML),
|
|
1324
|
+
composeHtml: censorHTMLstring(element.outerHTML),
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
return false;
|
|
1328
|
+
}
|
|
1329
|
+
return bodyContainer.style.display !== '';
|
|
1330
|
+
}
|
|
1331
|
+
setMinimized(minimized) {
|
|
1332
|
+
if (minimized !== this.isMinimized()) {
|
|
1333
|
+
if (this._isInlineReplyForm)
|
|
1334
|
+
throw new Error('Not implemented for inline compose views');
|
|
1335
|
+
const minimizeButton = querySelector(this._element, '.Hm > img');
|
|
1336
|
+
simulateClick(minimizeButton);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
setFullscreen(fullscreen) {
|
|
1340
|
+
if (fullscreen !== this.isFullscreen()) {
|
|
1341
|
+
if (this._isInlineReplyForm)
|
|
1342
|
+
throw new Error('Not implemented for inline compose views');
|
|
1343
|
+
const fullscreenButton = querySelector(this._element, '.Hm > img:nth-of-type(2)');
|
|
1344
|
+
simulateClick(fullscreenButton);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
setTitleBarColor(color) {
|
|
1348
|
+
const buttonParent = querySelector(this._element, '.nH.Hy.aXJ table.cf.Ht td.Hm');
|
|
1349
|
+
const elementsToModify = [
|
|
1350
|
+
querySelector(this._element, '.nH.Hy.aXJ .pi > .l.o'),
|
|
1351
|
+
querySelector(this._element, '.nH.Hy.aXJ .l.m'),
|
|
1352
|
+
querySelector(this._element, '.nH.Hy.aXJ .l.m > .l.n'),
|
|
1353
|
+
];
|
|
1354
|
+
buttonParent.classList.add('inboxsdk__compose_customTitleBarColor');
|
|
1355
|
+
elementsToModify.forEach((el) => {
|
|
1356
|
+
el.style.backgroundColor = color;
|
|
1204
1357
|
});
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
el.style.backgroundColor = color;
|
|
1230
|
-
});
|
|
1231
|
-
return () => {
|
|
1232
|
-
buttonParent.classList.remove('inboxsdk__compose_customTitleBarColor');
|
|
1233
|
-
elementsToModify.forEach(el => {
|
|
1234
|
-
el.style.backgroundColor = '';
|
|
1235
|
-
});
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
setTitleBarText(text) {
|
|
1239
|
-
if (this.isInlineReplyForm()) {
|
|
1240
|
-
throw new Error('setTitleBarText() is not supported on inline compose views');
|
|
1241
|
-
}
|
|
1242
|
-
const titleBarTable = (0, _querySelectorOrFail.default)(this._element, '.nH.Hy.aXJ table.cf.Ht');
|
|
1243
|
-
if (titleBarTable.classList.contains('inboxsdk__compose_hasCustomTitleBarText')) {
|
|
1244
|
-
throw new Error('Custom title bar text is already registered for this compose view');
|
|
1245
|
-
}
|
|
1246
|
-
const titleTextParent = (0, _querySelectorOrFail.default)(titleBarTable, 'div.Hp').parentElement;
|
|
1247
|
-
if (!(titleTextParent instanceof HTMLElement)) {
|
|
1248
|
-
throw new Error('Could not locate title bar text parent');
|
|
1249
|
-
}
|
|
1250
|
-
titleBarTable.classList.add('inboxsdk__compose_hasCustomTitleBarText');
|
|
1251
|
-
titleTextParent.classList.add('inboxsdk__compose_nativeTitleBarText');
|
|
1252
|
-
const customTitleText = document.createElement('td');
|
|
1253
|
-
customTitleText.classList.add('inboxsdk__compose_customTitleBarText');
|
|
1254
|
-
customTitleText.innerHTML = (0, _autoHtml.default)`
|
|
1358
|
+
return () => {
|
|
1359
|
+
buttonParent.classList.remove('inboxsdk__compose_customTitleBarColor');
|
|
1360
|
+
elementsToModify.forEach((el) => {
|
|
1361
|
+
el.style.backgroundColor = '';
|
|
1362
|
+
});
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
setTitleBarText(text) {
|
|
1366
|
+
if (this.isInlineReplyForm()) {
|
|
1367
|
+
throw new Error('setTitleBarText() is not supported on inline compose views');
|
|
1368
|
+
}
|
|
1369
|
+
const titleBarTable = querySelector(this._element, '.nH.Hy.aXJ table.cf.Ht');
|
|
1370
|
+
if (titleBarTable.classList.contains('inboxsdk__compose_hasCustomTitleBarText')) {
|
|
1371
|
+
throw new Error('Custom title bar text is already registered for this compose view');
|
|
1372
|
+
}
|
|
1373
|
+
const titleTextParent = querySelector(titleBarTable, 'div.Hp').parentElement;
|
|
1374
|
+
if (!(titleTextParent instanceof HTMLElement)) {
|
|
1375
|
+
throw new Error('Could not locate title bar text parent');
|
|
1376
|
+
}
|
|
1377
|
+
titleBarTable.classList.add('inboxsdk__compose_hasCustomTitleBarText');
|
|
1378
|
+
titleTextParent.classList.add('inboxsdk__compose_nativeTitleBarText');
|
|
1379
|
+
const customTitleText = document.createElement('td');
|
|
1380
|
+
customTitleText.classList.add('inboxsdk__compose_customTitleBarText');
|
|
1381
|
+
customTitleText.innerHTML = autoHtml `
|
|
1255
1382
|
<div class="Hp">
|
|
1256
1383
|
<h2 class="a3E">
|
|
1257
1384
|
<div class="aYF">${text}</div>
|
|
1258
1385
|
</h2>
|
|
1259
1386
|
</div>
|
|
1260
1387
|
`;
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1388
|
+
titleTextParent.insertAdjacentElement('afterend', customTitleText);
|
|
1389
|
+
return () => {
|
|
1390
|
+
customTitleText.remove();
|
|
1391
|
+
titleBarTable.classList.remove('inboxsdk__compose_hasCustomTitleBarText');
|
|
1392
|
+
titleTextParent.classList.remove('inboxsdk__compose_nativeTitleBarText');
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
_triggerDraftSave() {
|
|
1396
|
+
if (this._isTriggeringADraftSavePending) {
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
this._isTriggeringADraftSavePending = true;
|
|
1401
|
+
// Done asynchronously with setTimeout because if it's done synchronously
|
|
1402
|
+
// or after an asap step after an inline compose view's creation, Gmail
|
|
1403
|
+
// interprets the fake keypress and decides to add a '¾' character.
|
|
1404
|
+
Kefir.later(0, undefined)
|
|
1405
|
+
.takeUntilBy(this._stopper)
|
|
1406
|
+
.onValue(() => {
|
|
1407
|
+
this._isTriggeringADraftSavePending = false;
|
|
1408
|
+
const body = this.getMaybeBodyElement();
|
|
1409
|
+
if (body) {
|
|
1410
|
+
const unsilence = this._driver
|
|
1411
|
+
.getPageCommunicator()
|
|
1412
|
+
.silenceGmailErrorsForAMoment();
|
|
1413
|
+
try {
|
|
1414
|
+
simulateKey(body, 190, 0);
|
|
1415
|
+
}
|
|
1416
|
+
finally {
|
|
1417
|
+
unsilence();
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
// If this compose is a reply, then this gets the message ID of the message
|
|
1424
|
+
// we're replying to.
|
|
1425
|
+
_getTargetMessageID() {
|
|
1426
|
+
const input = this._element.querySelector('input[name="rm"]');
|
|
1427
|
+
return input &&
|
|
1428
|
+
typeof input.value === 'string' &&
|
|
1429
|
+
input.value != 'undefined'
|
|
1430
|
+
? input.value.replace('#', '')
|
|
1431
|
+
: null;
|
|
1432
|
+
}
|
|
1433
|
+
_getThreadID() {
|
|
1434
|
+
const targetID = this.getTargetMessageID();
|
|
1435
|
+
try {
|
|
1436
|
+
return targetID ? this._driver.getThreadIDForMessageID(targetID) : null;
|
|
1287
1437
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
// If this compose is a reply, then this gets the message ID of the message
|
|
1293
|
-
// we're replying to.
|
|
1294
|
-
_getTargetMessageID() {
|
|
1295
|
-
const input = this._element.querySelector('input[name="rm"]');
|
|
1296
|
-
return input && typeof input.value === 'string' && input.value != 'undefined' ? input.value.replace('#', '') : null;
|
|
1297
|
-
}
|
|
1298
|
-
_getThreadID() {
|
|
1299
|
-
const targetID = this.getTargetMessageID();
|
|
1300
|
-
try {
|
|
1301
|
-
return targetID ? this._driver.getThreadIDForMessageID(targetID) : null;
|
|
1302
|
-
} catch (err) {
|
|
1303
|
-
this._driver.getLogger().error(err);
|
|
1304
|
-
return null;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
getElement() {
|
|
1308
|
-
return this._element;
|
|
1309
|
-
}
|
|
1310
|
-
isFullscreen() {
|
|
1311
|
-
return this._isFullscreen;
|
|
1312
|
-
}
|
|
1313
|
-
getLastSelectionRange() {
|
|
1314
|
-
// The selection range can become invalid if the compose view has become expanded or
|
|
1315
|
-
// minimized since the range was set.
|
|
1316
|
-
const range = this._lastSelectionRange;
|
|
1317
|
-
if (range && !this.getBodyElement().contains(range.commonAncestorContainer)) {
|
|
1318
|
-
this._lastSelectionRange = undefined;
|
|
1319
|
-
}
|
|
1320
|
-
return this._lastSelectionRange;
|
|
1321
|
-
}
|
|
1322
|
-
setLastSelectionRange(lastSelectionRange) {
|
|
1323
|
-
this._lastSelectionRange = lastSelectionRange;
|
|
1324
|
-
}
|
|
1325
|
-
registerRequestModifier(modifier) {
|
|
1326
|
-
const keyId = this._driver.isUsingSyncAPI() ? this._getDraftIDfromForm() : this.getComposeID();
|
|
1327
|
-
if (!keyId) throw new Error('keyId should be set here');
|
|
1328
|
-
const modifierId = this._driver.getPageCommunicator().registerComposeRequestModifier(keyId, this._driver.getAppId());
|
|
1329
|
-
this._requestModifiers[modifierId] = modifier;
|
|
1330
|
-
this._startListeningForModificationRequests();
|
|
1331
|
-
this._stopper.onValue(() => {
|
|
1332
|
-
this._driver.getPageCommunicator().unregisterComposeRequestModifier(keyId, modifierId);
|
|
1333
|
-
});
|
|
1334
|
-
}
|
|
1335
|
-
_startListeningForModificationRequests() {
|
|
1336
|
-
if (this._isListeningToAjaxInterceptStream) {
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
|
-
const keyId = this._driver.isUsingSyncAPI() ? this._getDraftIDfromForm() : this.getComposeID();
|
|
1340
|
-
if (!keyId) throw new Error('keyId should be set here');
|
|
1341
|
-
this._driver.getPageCommunicator().ajaxInterceptStream.filter(_ref9 => {
|
|
1342
|
-
let {
|
|
1343
|
-
type,
|
|
1344
|
-
composeid,
|
|
1345
|
-
draftID,
|
|
1346
|
-
modifierId
|
|
1347
|
-
} = _ref9;
|
|
1348
|
-
return type === 'inboxSDKmodifyComposeRequest' && (composeid === keyId || keyId === draftID) && Boolean(this._requestModifiers[modifierId]);
|
|
1349
|
-
}).takeUntilBy(this._stopper).onValue(_ref10 => {
|
|
1350
|
-
let {
|
|
1351
|
-
modifierId,
|
|
1352
|
-
composeParams
|
|
1353
|
-
} = _ref10;
|
|
1354
|
-
if (this._driver.getLogger().shouldTrackEverything()) {
|
|
1355
|
-
this._driver.getLogger().eventSite('inboxSDKmodifyComposeRequest');
|
|
1356
|
-
}
|
|
1357
|
-
const modifier = this._requestModifiers[modifierId];
|
|
1358
|
-
const result = new Promise(resolve => resolve(modifier(composeParams)));
|
|
1359
|
-
result.then(newComposeParams => this._driver.getPageCommunicator().modifyComposeRequest(keyId, modifierId, newComposeParams || composeParams)).then(x => {
|
|
1360
|
-
if (this._driver.getLogger().shouldTrackEverything()) {
|
|
1361
|
-
this._driver.getLogger().eventSite('composeRequestModified');
|
|
1438
|
+
catch (err) {
|
|
1439
|
+
this._driver.getLogger().error(err);
|
|
1440
|
+
return null;
|
|
1362
1441
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
this.
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1442
|
+
}
|
|
1443
|
+
getElement() {
|
|
1444
|
+
return this._element;
|
|
1445
|
+
}
|
|
1446
|
+
isFullscreen() {
|
|
1447
|
+
return this._isFullscreen;
|
|
1448
|
+
}
|
|
1449
|
+
getLastSelectionRange() {
|
|
1450
|
+
// The selection range can become invalid if the compose view has become expanded or
|
|
1451
|
+
// minimized since the range was set.
|
|
1452
|
+
const range = this._lastSelectionRange;
|
|
1453
|
+
if (range &&
|
|
1454
|
+
!this.getBodyElement().contains(range.commonAncestorContainer)) {
|
|
1455
|
+
this._lastSelectionRange = undefined;
|
|
1456
|
+
}
|
|
1457
|
+
return this._lastSelectionRange;
|
|
1458
|
+
}
|
|
1459
|
+
setLastSelectionRange(lastSelectionRange) {
|
|
1460
|
+
this._lastSelectionRange = lastSelectionRange;
|
|
1461
|
+
}
|
|
1462
|
+
registerRequestModifier(modifier) {
|
|
1463
|
+
const keyId = this._driver.isUsingSyncAPI()
|
|
1464
|
+
? this._getDraftIDfromForm()
|
|
1465
|
+
: this.getComposeID();
|
|
1466
|
+
if (!keyId)
|
|
1467
|
+
throw new Error('keyId should be set here');
|
|
1468
|
+
const modifierId = this._driver
|
|
1469
|
+
.getPageCommunicator()
|
|
1470
|
+
.registerComposeRequestModifier(keyId, this._driver.getAppId());
|
|
1471
|
+
this._requestModifiers[modifierId] = modifier;
|
|
1472
|
+
this._startListeningForModificationRequests();
|
|
1473
|
+
this._stopper.onValue(() => {
|
|
1474
|
+
this._driver
|
|
1475
|
+
.getPageCommunicator()
|
|
1476
|
+
.unregisterComposeRequestModifier(keyId, modifierId);
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
_startListeningForModificationRequests() {
|
|
1480
|
+
if (this._isListeningToAjaxInterceptStream) {
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
const keyId = this._driver.isUsingSyncAPI()
|
|
1484
|
+
? this._getDraftIDfromForm()
|
|
1485
|
+
: this.getComposeID();
|
|
1486
|
+
if (!keyId)
|
|
1487
|
+
throw new Error('keyId should be set here');
|
|
1488
|
+
this._driver
|
|
1489
|
+
.getPageCommunicator()
|
|
1490
|
+
.ajaxInterceptStream.filter(({ type, composeid, draftID, modifierId }) => type === 'inboxSDKmodifyComposeRequest' &&
|
|
1491
|
+
(composeid === keyId || keyId === draftID) &&
|
|
1492
|
+
Boolean(this._requestModifiers[modifierId]))
|
|
1493
|
+
.takeUntilBy(this._stopper)
|
|
1494
|
+
.onValue(({ modifierId, composeParams }) => {
|
|
1495
|
+
if (this._driver.getLogger().shouldTrackEverything()) {
|
|
1496
|
+
this._driver.getLogger().eventSite('inboxSDKmodifyComposeRequest');
|
|
1497
|
+
}
|
|
1498
|
+
const modifier = this._requestModifiers[modifierId];
|
|
1499
|
+
const result = new Promise((resolve) => resolve(modifier(composeParams)));
|
|
1500
|
+
result
|
|
1501
|
+
.then((newComposeParams) => this._driver
|
|
1502
|
+
.getPageCommunicator()
|
|
1503
|
+
.modifyComposeRequest(keyId, modifierId, newComposeParams || composeParams))
|
|
1504
|
+
.then((x) => {
|
|
1505
|
+
if (this._driver.getLogger().shouldTrackEverything()) {
|
|
1506
|
+
this._driver.getLogger().eventSite('composeRequestModified');
|
|
1507
|
+
}
|
|
1508
|
+
return x;
|
|
1509
|
+
})
|
|
1510
|
+
.catch((err) => {
|
|
1511
|
+
this._driver
|
|
1512
|
+
.getPageCommunicator()
|
|
1513
|
+
.modifyComposeRequest(keyId, modifierId, composeParams);
|
|
1514
|
+
this._driver.getLogger().error(err);
|
|
1515
|
+
});
|
|
1516
|
+
});
|
|
1517
|
+
this._isListeningToAjaxInterceptStream = true;
|
|
1518
|
+
}
|
|
1519
|
+
setupLinkPopOvers() {
|
|
1520
|
+
if (!this._hasSetupLinkPopOvers) {
|
|
1521
|
+
this._hasSetupLinkPopOvers = true;
|
|
1522
|
+
this._eventStream.plug(setupLinkPopOvers(this));
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1377
1525
|
}
|
|
1378
|
-
|
|
1379
|
-
exports.default = _default;
|
|
1526
|
+
export default GmailComposeView;
|