From 36321b0be46f086c3cc89310d9d3bfee1f323db7 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Mon, 27 Apr 2020 16:44:30 +0800 Subject: [PATCH] fix: cannot focus compositon dialog in twitter --- .../InjectedComponents/PostDialog.tsx | 7 ++- .../Wallet/UI/RedPacket/RedPacketDialog.tsx | 8 +-- .../twitter.com/ui/injectPostDialog.tsx | 50 +++++++++++-------- .../twitter.com/ui/injectPostDialogHint.tsx | 23 +++++---- .../twitter.com/utils/selector.ts | 3 +- src/utils/jss/ShadowRootDialog.tsx | 8 +-- 6 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/components/InjectedComponents/PostDialog.tsx b/src/components/InjectedComponents/PostDialog.tsx index 0a14d7a98db1..278c0f061673 100644 --- a/src/components/InjectedComponents/PostDialog.tsx +++ b/src/components/InjectedComponents/PostDialog.tsx @@ -13,6 +13,7 @@ import { Chip, ThemeProvider, Theme, + DialogProps, } from '@material-ui/core' import { MessageCenter, CompositionEvent } from '../../utils/messages' import { useCapturedInput } from '../../utils/hooks/useCapturedEvents' @@ -96,6 +97,8 @@ export interface PostDialogUIProps onFinishButtonClicked: () => void onCloseButtonClicked: () => void onSetSelected: SelectRecipientsUIProps['onSetSelected'] + DialogProps?: Partial + RedPacketDialogProps?: Partial SelectRecipientsUIProps?: Partial } export function PostDialogUI(props: PostDialogUIProps) { @@ -131,7 +134,8 @@ export function PostDialogUI(props: PostDialogUIProps) { onEscapeKeyDown={props.onCloseButtonClicked} BackdropProps={{ className: classes.backdrop, - }}> + }} + {...props.DialogProps}> setRedPacketDialogOpen(false)} onDecline={() => setRedPacketDialogOpen(false)} + DialogProps={props.DialogProps} /> ) diff --git a/src/plugins/Wallet/UI/RedPacket/RedPacketDialog.tsx b/src/plugins/Wallet/UI/RedPacket/RedPacketDialog.tsx index ade5dc9481a6..2fbbee3aa934 100644 --- a/src/plugins/Wallet/UI/RedPacket/RedPacketDialog.tsx +++ b/src/plugins/Wallet/UI/RedPacket/RedPacketDialog.tsx @@ -12,6 +12,7 @@ import { InputLabel, Select, MenuItem, + DialogProps, } from '@material-ui/core' import { useStylesExtends, or } from '../../../../components/custom-ui-helper' import { DialogDismissIconUI } from '../../../../components/InjectedComponents/DialogDismissIcon' @@ -28,7 +29,7 @@ import { WalletRecord, ERC20TokenRecord, } from '../../database/types' -import { useLastRecognizedIdentity, useCurrentIdentity } from '../../../../components/DataSource/useActivatedUI' +import { useCurrentIdentity } from '../../../../components/DataSource/useActivatedUI' import { useCapturedInput } from '../../../../utils/hooks/useCapturedEvents' import { PluginMessageCenter } from '../../../PluginMessages' import { getActivatedUI } from '../../../../social-network/ui' @@ -58,6 +59,7 @@ interface RedPacketDialogProps open: boolean onConfirm: (opt?: RedPacketJSONPayload | null) => void onDecline: () => void + DialogProps?: Partial } const useNewPacketStyles = makeStyles(theme => @@ -471,7 +473,6 @@ export function RedPacketDialogUI( props: RedPacketDialogProps & NewPacketProps & ExistingPacketProps & { tab?: [0 | 1, (next: 0 | 1) => void] }, ) { const classes = useStylesExtends(useStyles(), props) - const rootRef = useRef(null) const [currentTab, setCurrentTab] = or(props.tab, useState<0 | 1>(0)) as [ number, React.Dispatch>, @@ -504,7 +505,8 @@ export function RedPacketDialogUI( disableEnforceFocus BackdropProps={{ className: classes.backdrop, - }}> + }} + {...props.DialogProps}> diff --git a/src/social-network-provider/twitter.com/ui/injectPostDialog.tsx b/src/social-network-provider/twitter.com/ui/injectPostDialog.tsx index 2cb75c162eb2..998e0abc18a3 100644 --- a/src/social-network-provider/twitter.com/ui/injectPostDialog.tsx +++ b/src/social-network-provider/twitter.com/ui/injectPostDialog.tsx @@ -5,10 +5,8 @@ import { renderInShadowRoot } from '../../../utils/jss/renderInShadowRoot' import { PostDialog } from '../../../components/InjectedComponents/PostDialog' import { useTwitterButton, useTwitterCloseButton, useTwitterLabel, useTwitterDialog } from '../utils/theme' import { makeStyles } from '@material-ui/styles' -import { postEditorInPopupSelector, rootSelector } from '../utils/selector' +import { postEditorContentInPopupSelector, rootSelector } from '../utils/selector' import { Theme } from '@material-ui/core' -import { useValueRef } from '../../../utils/hooks/useValueRef' -import { instanceOfTwitterUI } from '.' const useStyles = makeStyles((theme: Theme) => ({ MUIInputInput: { @@ -34,7 +32,7 @@ const useStyles = makeStyles((theme: Theme) => ({ export function injectPostDialogAtTwitter() { if (location.hostname.indexOf(twitterUrl.hostIdentifier) === -1) return - renderPostDialogTo('popup', postEditorInPopupSelector()) + renderPostDialogTo('popup', postEditorContentInPopupSelector()) renderPostDialogTo('timeline', rootSelector()) } @@ -52,25 +50,33 @@ function renderPostDialogTo(reason: 'timeline' | 'popup', ls: LiveSelector(null) + const dialogProps = { + disablePortal: true, + container: () => rootRef.current, + } return ( - + + }} + reason={props.reason} + /> + ) } diff --git a/src/social-network-provider/twitter.com/ui/injectPostDialogHint.tsx b/src/social-network-provider/twitter.com/ui/injectPostDialogHint.tsx index c627067bafba..021aa03148fc 100644 --- a/src/social-network-provider/twitter.com/ui/injectPostDialogHint.tsx +++ b/src/social-network-provider/twitter.com/ui/injectPostDialogHint.tsx @@ -13,11 +13,17 @@ import { hasEditor, isCompose } from '../utils/postBox' export function injectPostDialogHintAtTwitter() { if (location.hostname.indexOf(twitterUrl.hostIdentifier) === -1) return const emptyNode = document.createElement('div') - renderPostDialogHintTo(postEditorInTimelineSelector().map(x => (hasEditor() ? x : emptyNode))) - renderPostDialogHintTo(postEditorInPopupSelector().map(x => (isCompose() && hasEditor() ? x : emptyNode))) + renderPostDialogHintTo( + 'timeline', + postEditorInTimelineSelector().map(x => (hasEditor() ? x : emptyNode)), + ) + renderPostDialogHintTo( + 'popup', + postEditorInPopupSelector().map(x => (isCompose() && hasEditor() ? x : emptyNode)), + ) } -function renderPostDialogHintTo(ls: LiveSelector) { +function renderPostDialogHintTo(reason: 'timeline' | 'popup', ls: LiveSelector) { const watcher = new MutationObserverWatcher(ls) .setDOMProxyOption({ afterShadowRootInit: { mode: 'closed' }, @@ -27,7 +33,7 @@ function renderPostDialogHintTo(ls: LiveSelector) { subtree: true, }) - renderInShadowRoot(, watcher.firstDOMProxy.afterShadow) + renderInShadowRoot(, watcher.firstDOMProxy.afterShadow) } export const useTwitterThemedPostDialogHint = makeStyles((theme: Theme) => ({ @@ -53,15 +59,14 @@ export const useTwitterThemedPostDialogHint = makeStyles((theme: Theme) => ({ }, })) -function PostDialogHintAtTwitter() { +function PostDialogHintAtTwitter({ reason }: { reason: 'timeline' | 'popup' }) { const classes = { ...useTwitterThemedPostDialogHint(), ...useTwitterButton(), } - const onHintButtonClicked = useCallback( - () => MessageCenter.emit('compositionUpdated', { reason: 'timeline', open: true }), - [], - ) + const onHintButtonClicked = useCallback(() => MessageCenter.emit('compositionUpdated', { reason, open: true }), [ + reason, + ]) return ( LiveSelector = () => querySelector( export const composeAnchorSelector: () => LiveSelector = () => querySelector('a[href="/compose/tweet"]') - +export const postEditorContentInPopupSelector: () => LiveSelector = () => + querySelector('[aria-labelledby="modal-header"] > div:first-child > div:nth-child(3)') export const postEditorInPopupSelector: () => LiveSelector = () => querySelector( '[aria-labelledby="modal-header"] > div:first-child > div:nth-child(3) > div:first-child > div:first-child', diff --git a/src/utils/jss/ShadowRootDialog.tsx b/src/utils/jss/ShadowRootDialog.tsx index 33acca1a0946..d13607cba8ce 100644 --- a/src/utils/jss/ShadowRootDialog.tsx +++ b/src/utils/jss/ShadowRootDialog.tsx @@ -1,21 +1,21 @@ import React from 'react' -import { Dialog, withMobileDialog } from '@material-ui/core' +import { Dialog, withMobileDialog, DialogProps } from '@material-ui/core' import '../../utils/jss/ShadowRootPortal' import { PortalShadowRoot } from '../../utils/jss/ShadowRootPortal' import { useSheetsRegistryStyles } from './renderInShadowRoot' const ResponsiveDialog = withMobileDialog({ breakpoint: 'xs' })(Dialog) -export default function ShadowRootDialog(_props: any) { +export default function ShadowRootDialog(_props: DialogProps) { const ref = React.useRef(null) const styles = useSheetsRegistryStyles(ref.current) // ? I need the render tree to get the shadowroot. Is the extra div must be rendered? // ? can style be transported to shadowroot directly instead of with dialog children? - const { children, ...props } = _props + const { children, container, ...props } = _props return (
- + {children}