Захват контента в прямом эфире из документов Google в скрипте контента с расширением ChromeJavascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Захват контента в прямом эфире из документов Google в скрипте контента с расширением Chrome

Сообщение Anonymous »

Я строю расширение Chrome (Manifest v3), которое необходимо захватить полный текст документа Google в режиме реального времени, включая набор, делеции, пасты, отмену/редо и форматирование изменений, поэтому я могу отправить его в базу данных для хранения и использования позже. Тем не менее, Google Docs не использует стандартный или простой довольственный элемент, поэтому ни один из обычных подходов DOM или клавиш -эвизирования не работает надежно. < /P>
Здесь я пробовал < /p>

Прослушивание событий в довольных элементах. /> < /ol>

Проблема не может сохранить Ptrack вставки в середине текста или редактирование в любом месте, кроме конца < /li>
< /ul>

Делать неправильно
Вот мои консольные журналы, которые возникают, кажется, не обнаруживает никаких изменений, а код следует за
Спасибо
журналы консоли:
🟢 Начальное обслуживание. Наблюдатель ...
content.js:1 📝 Docs Buffer Synced uped
3content.js:1.
function setupGoogleDocsBufferSync() {
// 1) Only activate on docs.google.com
if (window.location.hostname !== 'docs.google.com') return;
console.log('🟢 MotherTongue content script loaded on', window.location.href);

// 2) Wait for the main container to appear
function tryAttachObserver() {
const appView = document.querySelector('.kix-appview');
if (!appView) {
// Try again in 500ms
setTimeout(tryAttachObserver, 500);
console.log('Looking for .kix-appview...');
return;
}

// 3) Keep track of the last text we sent, so we only send diffs
console.log('Found .kix-appview, starting observer...');
let lastSnapshot = '';

// 4) Create a MutationObserver to watch for any DOM/text changes
const observer = new MutationObserver(() => {
console.log('Observing');
const lines = Array.from(document.querySelectorAll('.kix-lineview'));
const fullText = lines.map(line => line.innerText).join('\n').trim();
if (fullText !== lastSnapshot) {
lastSnapshot = fullText;
console.log('Detected change, sending buffer update');
chrome.runtime.sendMessage({
type: 'update_buffer',
buffer: fullText
});
}
});

observer.observe(appView, {
childList: true,
subtree: true,
characterData: true
});

console.log('📝 Docs buffer sync enabled');
}

tryAttachObserver();
}

window.addEventListener('load', setupGoogleDocsBufferSync);

background.js
// src/scripts/background.js
/* global chrome */
import { subscribeToAuthChanges } from '../../../shared/services/firebase/auth.js';

let currentUid = null;
let isMonitoring = true;

let pendingBuffer = '';
let sendTimer = null;
console.log('🟢 MotherTongue background service worker loaded');

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
switch (msg.type) {
case 'get_monitoring':
sendResponse({ active: isMonitoring });
return true;

case 'SET_MONITORING':
isMonitoring = msg.active;
broadcastMonitoringStatus();
sendResponse({ success: true });
return true;

case 'clear_buffer':
clearBuffer();
return true;

case 'update_buffer':
console.log('🔄 Buffer update received, will check if monitoring');
if (isMonitoring) handleBufferUpdate(msg.buffer);
return true;

case 'analyze':
analyzeText(msg, sendResponse);
return true;

case 'get_tab_id':
sendResponse({ tabId: sender.tab ? sender.tab.id : null });
return true;

case 'get_current_user':
sendResponse({ userId: currentUid });
return true;

default:
return false;
}
});

// Keep track of auth state
subscribeToAuthChanges(user => {
if (user) {
currentUid = user.uid;
console.log('🔑 Signed in as', currentUid);
} else {
currentUid = null;
console.log('🔒 No user signed in');
}
});

/** Broadcast the current monitoring status to all tabs */
function broadcastMonitoringStatus() {
chrome.tabs.query({}, tabs => {
for (const tab of tabs) {
chrome.tabs.sendMessage(
tab.id,
{ type: 'MONITORING_STATUS', active: isMonitoring },
() => {
if (chrome.runtime.lastError) {
// No listener in that tab
}
}
);
}
});
}

/** Clear the in-memory buffer and the backend copy */
function clearBuffer() {
pendingBuffer = '';
if (currentUid) {
sendToBackend('', 'clear');
}
}

/**
* Receive a full-doc update, trim it, and schedule a backend sync.
* @param {string} buffer
*/
function handleBufferUpdate(buffer) {
console.log('📝 handleBufferUpdate called, length:', buffer.length);

// Keep only the last 1000 words
const words = buffer.split(/\s+/);
pendingBuffer = words.slice(-1000).join(' ');

// Throttle: only send once per 10 seconds
if (!sendTimer) {
sendTimer = setTimeout(() => {
sendToBackend(pendingBuffer, 'update');
sendTimer = null;
}, 10000);
}
}

/**
* POST the buffer to your backend API for Firestore storage.
* @param {string} buffer
* @param {'update'|'clear'} action
*/
function sendToBackend(buffer, action = 'update') {
if (!currentUid) {
console.warn('No user signed in; skipping backend sync');
return;
}

fetch('http://localhost:5000/api/buffer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: currentUid,
buffer,
action
})
})
.then(r => r.json())
.then(() => {
console.log(`✅ Buffer ${action}d in Firestore via backend`);
})
.catch(err => {
console.error(`❌ Failed to ${action} buffer:`, err);
});
}

/** Handle quiz analysis requests from popup or content script */
function analyzeText(msg, sendResponse) {
fetch('http://localhost:5000/api/analysis', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: msg.text,
userId: currentUid,
source: msg.source || 'buffer'
})
})
.then(r => r.json())
.then(data => sendResponse(data))
.catch(err => sendResponse({ error: err.message }));
}



Подробнее здесь: https://stackoverflow.com/questions/796 ... tent-scrip
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Javascript»