I’m creating a Chrome extension that needs to swap out certain words with preset values in Google Docs as you type, kind of like how Grammarly works. I’ve tried using Google App Scripts and the Google Docs API, but they’re too slow. I want the changes to happen instantly.
I’ve figured out that Google Docs uses an iframe called ‘docs-texteventtarget-iframe’ to catch keypress events. I can detect these events in my content script, but I can’t figure out how to actually change the text in the document.
Here’s a snippet of my code:
const docFrame = document.querySelector('iframe.docs-texteventtarget-iframe');
if (docFrame?.contentDocument) {
let typedText = '';
docFrame.contentDocument.addEventListener('keyup', (e) => {
if (e.key.match(/^[a-z0-9 !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]$/i)) {
typedText += e.key;
}
const shortcuts = JSON.parse(localStorage.getItem('my_shortcuts') || '{}');
const match = Object.entries(shortcuts).find(([k]) => typedText.endsWith(k));
if (match) {
typedText = '';
// How do I replace the text in the Google Doc here?
}
});
}
Any ideas on how to make this work? I’ve looked at other questions about accessing Google Docs content, but they don’t cover real-time updates using content scripts.
Having dealt with similar challenges, I can say that real-time text replacement in Google Docs is indeed complex. One approach you might consider is using MutationObservers to track changes in the document’s content. This method allows you to detect when text is added or modified, and then you can programmatically replace it.
Here’s a basic concept:
Set up a MutationObserver on the main document body.
When mutations occur, check if they match your replacement criteria.
If a match is found, use document.execCommand to replace the text.
Keep in mind that this method may have performance implications for large documents. Also, be cautious about potential conflicts with Google Docs’ own operations. Extensive testing will be crucial to ensure reliability across different scenarios and document sizes.
I’ve worked on a similar project and encountered the same challenges. Google Docs’ architecture makes real-time text replacement tricky, but there’s a workaround that might help.
Instead of trying to directly modify the document content, consider simulating keystrokes to delete the original text and insert the replacement. You can use the document.execCommand() method to achieve this, though it’s worth noting that it’s deprecated but still widely supported.
Here’s a rough idea of how you could modify your code:
if (match) {
typedText = '';
const [key, value] = match;
const backspaces = key.length;
// Simulate backspaces to delete the original text
for (let i = 0; i < backspaces; i++) {
document.execCommand('delete');
}
// Insert the replacement text
document.execCommand('insertText', false, value);
}
This approach isn’t perfect and may have some limitations, but it’s a start. You might need to fine-tune it based on Google Docs’ specific behavior. Also, be aware that Google might change their implementation at any time, potentially breaking this solution.
Hey, i tried something similar before. its tricky cuz google docs is weird. have u considered using contenteditable? might work better. u could make a div overlay the doc and intercept keystrokes there. then update the actual doc behind the scenes. just an idea, might be worth a shot!