Escribí una extensión de Chrome que cuenta las palabras en un documento de Google y las compara con los recuentos de palabras sugeridos de una fuente de datos (CSV, tabla o base de datos).
Mi método fue analizar cada span.kix-lineview-text-block en la página, que dejó de funcionar cuando Google cambió a una pantalla de lienzo SVG . Aquí hay una captura de pantalla que muestra todos los recuentos de palabras en 0.
La alternativa recomendada para analizar la página es la autenticación . Es decir, usar Oauth 2.0 para autorizar solicitudes y editar contenido a través de la bien documentada API de Google Docs .
La descripción general de la API de GDocs tiene sentido . Pero soy nuevo en la autenticación y demasiado novato para dar sentido a esta respuesta . Google ofrece un tutorial de inicio rápido , pero no he podido hacerlo funcionar como una extensión.
Claramente, hay una brecha en mi conocimiento, y no sé qué buscar ("autenticación de la extensión de Chrome de Google Docs" lléveme aquí...) La mayoría de los ejemplos de Google usan Java/PHP/Python , lo que me hace preguntarme si le estoy ladrando al árbol equivocado.
¿Podría alguien más inteligente que yo señalar lo que estoy buscando y/o dónde aprenderlo?
TL; DR: tengo una extensión de Chrome que funciona principalmente y necesita datos de un documento de Google. ¿Cómo dibujo el resto del búho?
Parece un desperdicio obtener datos de una API remota cuando todo está presente localmente, así que aquí hay una solución alternativa que extrae el texto de las partes internas del documento. Dado que las secuencias de comandos de contenido se ejecutan en un entorno aislado, tendremos que colocar el código del extractor en el contexto de la página y usar la mensajería DOM para comunicarnos con la secuencia de comandos de contenido.
Guión de contenido (ManifestV2):
// Adds the extractor into the page context (aka "main world") const script = document.createElement('script'); const eventId = `${Math.random()}${performance.now()}`; script.textContent = `(${eventId => { window.addEventListener(eventId, () => { const doc = document.querySelector('.docs-texteventtarget-iframe').contentDocument; const key = Object.keys(doc).find(k => k.startsWith('closure_')); const res = dig(key ? doc[key] : doc.defaultView, new Set()); window.dispatchEvent(new CustomEvent(`${eventId}res`, { detail: res || '' })); }); function dig(src, seen) { seen.add(src); if (!Array.isArray(src)) src = Object.values(src); for (let v, len = src.length, i = 0; i < len; i++) { try { if (!(v = src[i]) || Object.prototype.toString.call(v) === '[object Window]' || seen.has(v)) { continue; } } catch (e) {} seen.add(v) if (typeof v === 'string' && v[0] === '\x03' && v.endsWith('\n') || typeof v === 'object' && (v = dig(v, seen))) { return v; } } } }})(${JSON.stringify(eventId)})`; document.documentElement.appendChild(script); script.remove(); // Listens for messages from the extension chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg === 'getDocText') { sendResponse(getDocText()); } }); // Calls the extractor via synchronous DOM messaging function getDocText() { let res; window.addEventListener(`${eventId}res`, e => { res = e.detail }, {once: true}); window.dispatchEvent(new CustomEvent(eventId)); return res; }En ManifestV3, la única diferencia es que, en lugar de script.textContent, usará script.src + un archivo de script separado expuesto en web_accessible_resources como se muestra en el método 1 aquí . En el futuro, ManifestV3 permitirá registrar código en el mundo principal directamente.