@@ -102,7 +102,6 @@ export function setupTwitterObserver(
102102 observer . observe ( twitterReactRoot , { childList : true , subtree : true } ) ;
103103 } ) ;
104104}
105-
106105async function handleNewNode (
107106 node : Element ,
108107 config : ActionAdapter ,
@@ -114,17 +113,32 @@ async function handleNewNode(
114113 if ( ! element || element . localName !== 'div' ) {
115114 return ;
116115 }
117- const rootElement = findElementByTestId ( element , 'card.wrapper' ) ;
118- if ( ! rootElement ) {
119- return ;
120- }
121- // handle link preview only, assuming that link preview is a must for actions
122- const linkPreview = rootElement . children [ 0 ] as HTMLDivElement ;
123- if ( ! linkPreview ) {
124- return ;
116+
117+ let anchor ;
118+
119+ const linkPreview = findLinkPreview ( element ) ;
120+
121+ let container = findContainerInTweet (
122+ linkPreview ?. card ?? element ,
123+ Boolean ( linkPreview ) ,
124+ ) ;
125+ if ( linkPreview ) {
126+ anchor = linkPreview . anchor ;
127+ container && container . remove ( ) ;
128+ container = linkPreview . card . parentElement as HTMLElement ;
129+ } else {
130+ if ( container ) {
131+ return ;
132+ }
133+ const link = findLastLinkInText ( element ) ;
134+ if ( link ) {
135+ anchor = link . anchor ;
136+ container = getContainerForLink ( link . tweetText ) ;
137+ }
125138 }
126139
127- const anchor = linkPreview . children [ 0 ] as HTMLAnchorElement ;
140+ if ( ! anchor || ! container ) return ;
141+
128142 const shortenedUrl = anchor . href ;
129143 const actionUrl = await resolveTwitterShortenedUrl ( shortenedUrl ) ;
130144 const interstitialData = isInterstitial ( actionUrl ) ;
@@ -174,7 +188,7 @@ async function handleNewNode(
174188 return ;
175189 }
176190
177- rootElement . parentElement ? .replaceChildren (
191+ addMargin ( container ) . replaceChildren (
178192 createAction ( {
179193 originalUrl : actionUrl ,
180194 action,
@@ -242,3 +256,63 @@ function findElementByTestId(element: Element, testId: string) {
242256 }
243257 return element . querySelector ( `[data-testid="${ testId } "]` ) ;
244258}
259+
260+ function findContainerInTweet ( element : Element , searchUp ?: boolean ) {
261+ const message = searchUp
262+ ? ( element . closest ( `[data-testid="tweet"]` ) ??
263+ element . closest ( `[data-testid="messageEntry"]` ) )
264+ : ( findElementByTestId ( element , 'tweet' ) ??
265+ findElementByTestId ( element , 'messageEntry' ) ) ;
266+
267+ if ( message ) {
268+ return message . querySelector ( '.dialect-wrapper' ) as HTMLElement ;
269+ }
270+ return null ;
271+ }
272+
273+ function findLinkPreview ( element : Element ) {
274+ const card = findElementByTestId ( element , 'card.wrapper' ) ;
275+ if ( ! card ) {
276+ return null ;
277+ }
278+
279+ const anchor = card . children [ 0 ] ?. children [ 0 ] as HTMLAnchorElement ;
280+
281+ return anchor ? { anchor, card } : null ;
282+ }
283+ function findLastLinkInText ( element : Element ) {
284+ const tweetText = findElementByTestId ( element , 'tweetText' ) ;
285+ if ( ! tweetText ) {
286+ return null ;
287+ }
288+
289+ const links = tweetText . getElementsByTagName ( 'a' ) ;
290+ if ( links . length > 0 ) {
291+ const anchor = links [ links . length - 1 ] as HTMLAnchorElement ;
292+ return { anchor, tweetText } ;
293+ }
294+ return null ;
295+ }
296+
297+ function getContainerForLink ( tweetText : Element ) {
298+ const root = document . createElement ( 'div' ) ;
299+ root . className = 'dialect-wrapper' ;
300+ const dm = tweetText . closest ( `[data-testid="messageEntry"]` ) ;
301+ if ( dm ) {
302+ root . classList . add ( 'dialect-dm' ) ;
303+ tweetText . parentElement ?. parentElement ?. prepend ( root ) ;
304+ } else {
305+ tweetText . parentElement ?. append ( root ) ;
306+ }
307+ return root ;
308+ }
309+
310+ function addMargin ( element : HTMLElement ) {
311+ if ( element && element . classList . contains ( 'dialect-wrapper' ) ) {
312+ element . style . marginTop = '12px' ;
313+ if ( element . classList . contains ( 'dialect-dm' ) ) {
314+ element . style . marginBottom = '8px' ;
315+ }
316+ }
317+ return element ;
318+ }
0 commit comments