I'm building a Chrome Extension for Google Docs, and I am trying to get the selected text from the current document being edited:
However when I trying running this code, it's returning an empty string ' ':
const docsFrame = document.getElementsByClassName('docs-texteventtarget-iframe')[0]
docsFrame.contentDocument.getSelection().toString()
There was a library called Google Docs Utils that used to be able to do this, but since Docs switched to Canvas-based rendering, the library no longer works.
EDIT:
Here's an example Google Docs to test it out
EDIT # 2:
Made some progress, found this thread with a lot of potential soltutions on it: https://github.com/Amaimersion/google-docs-utils/issues/10
I figured out how to accomplish it with the help of the thread I mentioned above and through studying some open source code. I am not sure if I am allowed to post open source code here and to avoid licensing conflicts, I will post here the general steps I found:
Enable screen reader functionality / SVG reading. Google will add svg and rect elements to ".kix-canvas-tile-selection"
that contain the text that was typed in. Look towards the second half of this thread for different solutions to enabling this.
Use $(".kix-page-paginated").get()
to get the current page on Google Docs. Then use $(window).height() calculations to figure out what page the user is currently on.
After accomplishing the two above, you can use a function like so below to get the line of text
function getSelectedLineOfText(page) {
const overlaps = (a, b) => a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top
const selectionRects = $(".kix-canvas-tile-selection > svg > rect", page).get()
.map(el => el.getBoundingClientRect())
// Using text elements on that page and the selection rects, find the actual selected line of text.
const textElements $("svg > g[role=paragraph] > rect", page).get();
Note: as you can see from the function name, this can only get an entire selected line in the file. It can't get the specific text selected within a line.
So here, "name is Bob. Hi my name is Bob. Hi my name is Bob." will be returned. I was struggling to get more specific than this, so if anyone has a clue, please feel free to add / create another answer.