MCPcopy Create free account
hub / github.com/Yorick-Ryu/deep-share / injectDocxButton

Function injectDocxButton

scripts/injectDocxButton.js:6–296  ·  view source on GitHub ↗

* DeepShare DOCX Button Injector * Injects a DOCX conversion button into the DeepSeek interface

()

Source from the content-addressed store, hash-verified

4 */
5
6function injectDocxButton() {
7 console.debug('Initializing DOCX button injection');
8 let floatingContainer = null;
9
10 // Function to observe and inject the button
11 function observeAndInjectButton() {
12 // Create a mutation observer to watch for the copy button
13 const observer = new MutationObserver((mutations) => {
14 for (const mutation of mutations) {
15 if (mutation.type === 'childList') {
16 // More robust selector targeting button containers and groups
17 const buttonContainers = document.querySelectorAll('.ds-flex[style*="align-items"][style*="gap"], div[class*="ds-flex"][style*="align-items: center"]');
18
19 buttonContainers.forEach(container => {
20 // Find button groups more flexibly - look for containers with gap and align-items
21 const buttonGroup = container.querySelector('.ds-flex[style*="align-items"][style*="gap"], div[class*="ds-flex"][style*="align-items"]') || container;
22
23 // Look for copy buttons using multiple strategies
24 let copyButtons = buttonGroup.querySelectorAll('[role="button"][tabindex]');
25
26 // Fallback: look for clickable divs that might be buttons
27 if (copyButtons.length === 0) {
28 copyButtons = buttonGroup.querySelectorAll('div[tabindex][role], div[style*="cursor"][role]');
29 }
30
31 // Further fallback: look for elements with button-like characteristics
32 if (copyButtons.length === 0) {
33 copyButtons = buttonGroup.querySelectorAll('div[class*="button"], div[class*="btn"], div[style*="cursor: pointer"]');
34 }
35
36 copyButtons.forEach(copyBtn => {
37 // More flexible check for copy button with prioritized strategies
38 // Strategy 1: .ds-icon-button class with role attribute and SVG path starting with M6.149
39 const isStrategy1 = copyBtn.classList.contains('ds-icon-button') &&
40 copyBtn.hasAttribute('role') &&
41 copyBtn.querySelector('svg path[d^="M6.149"]');
42
43 // Strategy 2 (most stable): First button with role="button"
44 const isStrategy2 = copyBtn === buttonGroup.querySelector('[role="button"]') ||
45 copyBtn === Array.from(buttonGroup.children).find(child =>
46 child.hasAttribute('role') && child.getAttribute('role') === 'button');
47
48 const isCopyButton = isStrategy1 || isStrategy2;
49
50 if (!isCopyButton) return;
51
52 // Check if this is an AI response (not a user message)
53 // Strategy: Look for distinctive patterns between user messages and AI responses
54
55 // 1. User messages have the "d29f3d7d" class in their ds-message container
56 const isUserMessage = copyBtn.closest('.d29f3d7d, [class*="d29f3d7d"]');
57
58 // 2. AI responses are in containers with "_4f9bf79" class
59 const isAIContainer = copyBtn.closest('._4f9bf79, [class*="_4f9bf79"]');
60
61 // 3. AI responses typically have markdown content nearby
62 const nearbyMarkdown = copyBtn.closest('div').querySelector('.ds-markdown') ||
63 copyBtn.parentElement?.parentElement?.querySelector('.ds-markdown');

Callers 1

Calls 2

observeAndInjectButtonFunction · 0.85
debugMethod · 0.80

Tested by

no test coverage detected