From a0910bf9257347f409ca7830ba8a70c9b9b7bade Mon Sep 17 00:00:00 2001 From: Wukong Sun Date: Tue, 11 Mar 2025 17:06:22 +0800 Subject: [PATCH 1/4] fix: mf-6659 skip hidden content during extract post message --- .../site-adaptors/twitter.com/utils/fetch.ts | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts b/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts index 84ff7653bedc..7a273cdb8443 100644 --- a/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts +++ b/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts @@ -97,12 +97,28 @@ function resolveType(content: string) { return 'normal' } +function getVisibleText(node: Node) { + if (node.nodeType === Node.TEXT_NODE) return node.textContent + if (node.nodeType !== Node.ELEMENT_NODE) return '' + if ( + (node as Element).getAttribute('aria-hidden') === 'true' && // getBoundingClientRect() causes layout, getAttribute() is cheaper + (node as Element).getBoundingClientRect().width === 0 + ) + return '' + let text = '' + for (const child of node.childNodes) { + text += getVisibleText(child) + } + return text +} + export function postContentMessageParser(node: HTMLElement): TypedMessage { function make(node: Node): TypedMessage { if (node.nodeType === Node.TEXT_NODE) { if (!node.nodeValue) return makeTypedMessageEmpty() return makeTypedMessageText(node.nodeValue, getElementStyle(node.parentElement)) - } else if (node instanceof HTMLAnchorElement) { + } + if (node instanceof HTMLAnchorElement) { const anchor = node const href = anchor.getAttribute('title') ?? anchor.getAttribute('href') if (href?.includes('/photo/')) { @@ -131,7 +147,7 @@ export function postContentMessageParser(node: HTMLElement): TypedMessage { makeTypedMessageEmpty(), ) } - const content = anchor.textContent + const content = getVisibleText(anchor) if (!content) return makeTypedMessageEmpty() const altImage = node.querySelector('img') return makeTypedMessageAnchor( From bac57e54df1e6ca3753aeb35bb6b098295460e92 Mon Sep 17 00:00:00 2001 From: Wukong Sun Date: Tue, 11 Mar 2025 17:53:29 +0800 Subject: [PATCH 2/4] fix: mf-6658 address in link --- .../SiteAdaptor/components/LinkModifier.tsx | 33 +++++++++++-- .../SiteAdaptor/components/TextModifier.tsx | 49 +++++-------------- .../SiteAdaptor/components/WarningCard.tsx | 8 ++- .../src/SiteAdaptor/hooks/useCheckLink.ts | 38 ++++++++++++++ .../src/SiteAdaptor/hooks/useDetectAddress.ts | 31 ++++++++++++ packages/plugins/ScamWarning/src/constants.ts | 4 ++ packages/plugins/ScamWarning/src/utils.ts | 10 ++++ .../web3-constants/evm/nft-red-packet.json | 6 +-- 8 files changed, 133 insertions(+), 46 deletions(-) create mode 100644 packages/plugins/ScamWarning/src/SiteAdaptor/hooks/useCheckLink.ts create mode 100644 packages/plugins/ScamWarning/src/SiteAdaptor/hooks/useDetectAddress.ts diff --git a/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx b/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx index 7d1ec568b929..216efe204bec 100644 --- a/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx +++ b/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx @@ -10,6 +10,9 @@ import { usePopoverControl } from './usePopoverControl.js' import { WarningCard } from './WarningCard.js' import { SecurityProvider } from '../../constants.js' import { GoPlusLabs } from '@masknet/web3-providers' +import { extractAddresses } from '../../utils.js' +import { useDetectAddress } from '../hooks/useDetectAddress.js' +import { AddressTag } from './TextModifier.js' const useStyles = makeStyles()({ link: { @@ -19,6 +22,9 @@ const useStyles = makeStyles()({ gap: 4, verticalAlign: 'bottom', }, + address: { + display: 'contents', + }, icon: { width: 18, height: 18, @@ -26,20 +32,20 @@ const useStyles = makeStyles()({ overflow: 'hidden', cursor: 'pointer', }, -}) +})) function isTCO(url: string | null) { if (!url) return false return url.startsWith('https://t.co/') } -export const LinkModifier = memo>(function ModifyLink({ +export const LinkModifier = memo>(function LinkModifier({ fallback, ...props }) { const { classes } = useStyles() const { data } = useQuery({ - queryKey: ['scam-warning', 'check-link', props.href], + queryKey: ['scam-warning', 'check-link', props.href, props.children], queryFn: async () => { const resolvedLink = isTCO(props.href) ? await resolveTCOLink(props.href) : props.href if (!resolvedLink) return { isScam: false } @@ -50,16 +56,35 @@ export const LinkModifier = memo + + + {props.children} + {props.suggestedPostImage} + + + ) + } + return fallback + } return ( diff --git a/packages/plugins/ScamWarning/src/SiteAdaptor/components/TextModifier.tsx b/packages/plugins/ScamWarning/src/SiteAdaptor/components/TextModifier.tsx index 7bb29ef994ba..f56e168265c9 100644 --- a/packages/plugins/ScamWarning/src/SiteAdaptor/components/TextModifier.tsx +++ b/packages/plugins/ScamWarning/src/SiteAdaptor/components/TextModifier.tsx @@ -1,16 +1,11 @@ import { Icons } from '@masknet/icons' import type { Plugin } from '@masknet/plugin-infra' import { makeStyles, ShadowRootPopper } from '@masknet/theme' -import { GoPlusLabs } from '@masknet/web3-providers' -import { isValidAddress } from '@masknet/web3-shared-evm' -import { isValidAddress as isSolAddress } from '@masknet/web3-shared-solana' -import { useQuery } from '@tanstack/react-query' import { Fragment, memo, useMemo } from 'react' -import { EVM_ADDRESS, SecurityProvider, SOLANA_ADDRESS, TRON_ADDRESS } from '../../constants.js' -import { PluginScamRPC } from '../../messages.js' -import { isTronAddress } from '../../utils.js' +import { extractAddresses } from '../../utils.js' import { usePopoverControl } from './usePopoverControl.js' import { WarningCard } from './WarningCard.js' +import { useDetectAddress } from '../hooks/useDetectAddress.js' const useStyles = makeStyles()({ text: { @@ -27,40 +22,25 @@ const useStyles = makeStyles()({ overflow: 'hidden', cursor: 'pointer', }, -}) +})) type TextModifierProps = PropsOf interface AddressTagProps { address: string text: string + nested?: boolean + className?: string } -const AddressTag = memo(function AddressTag({ address, text }) { - const { classes } = useStyles() +export const AddressTag = memo(function AddressTag({ address, text, className, nested }) { + const { classes, cx } = useStyles() const { open, anchorEl, iconRef, onMouseEnter, onMouseLeave } = usePopoverControl() - const { data } = useQuery({ - queryKey: ['detect-address', address], - queryFn: async () => { - if (isValidAddress(address)) { - return { isScam: await PluginScamRPC.checkAddress(address), provider: SecurityProvider.ScamSniffer } - } - if (isSolAddress(address)) - return { - isScam: await GoPlusLabs.checkIfAddressIsScam('solana', address), - provider: SecurityProvider.GoPlus, - } - if (isTronAddress(address)) - return { - isScam: GoPlusLabs.checkIfAddressIsScam('tron', address), - provider: SecurityProvider.GoPlus, - } - return { isScam: false, provider: null } - }, - }) + const { data } = useDetectAddress(address) + if (!data?.isScam) return text return ( - + (function AddressTag({ address, text }) onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} /> - {address} + {nested ? null : address} (function TextModifier({ fallback, children: fullText }) { - const addresses = useMemo(() => { - const evmAddresses = fullText.match(EVM_ADDRESS) || [] - const solAddresses = fullText.match(SOLANA_ADDRESS) || [] - const tronAddresses = fullText.match(TRON_ADDRESS) || [] - return [...evmAddresses, ...solAddresses, ...tronAddresses] - }, [fullText]) + const addresses = useMemo(() => extractAddresses(fullText), [fullText]) const segments = useMemo(() => { let leftOffset = 0 diff --git a/packages/plugins/ScamWarning/src/SiteAdaptor/components/WarningCard.tsx b/packages/plugins/ScamWarning/src/SiteAdaptor/components/WarningCard.tsx index ee9cc29946f2..8fd3fd2e13db 100644 --- a/packages/plugins/ScamWarning/src/SiteAdaptor/components/WarningCard.tsx +++ b/packages/plugins/ScamWarning/src/SiteAdaptor/components/WarningCard.tsx @@ -65,6 +65,7 @@ const useStyles = makeStyles()((theme) => ({ minWidth: 0, textOverflow: 'ellipsis', overflow: 'hidden', + whiteSpace: 'nowrap', }, link: { textDecoration: 'underline', @@ -130,10 +131,13 @@ export const WarningCard = memo(function WarningCard({ link, address, securityPr
{link ? - + {link} - : {address}} + : + {address} + + }