The extension is available in Chrome (direct link). The underlying javascript function is on github as well (github link).
The extension adds a context menu when you highlight text on a page. When clicked it reads the text aloud based on the speech options set through the option menu. There is also a shortcut using shift+ctrl+spacebar to read/stop text.
I wanted to build it. Especially for being able to read long text passages while I do something else on another screen. There is software that can read text but it's usually a third party application and the available speech extensions on the Chrome store were lackluster as well as potentially being harmful.
I learned a lot. I got the extension working in a way that I find acceptable. Since I learned so much I will write a bit about it and how I worked around the limitations.
It also lets me use it to read (at least some) text without having to focus my attention to the screen or having a third party application open (besides Chrome).
I started by creating the options page. I had done options on another extension and I knew it was more tedious than anything. I had issues getting the voice options into a drop down because it would take an indeterminate amount of time for the command to finish and I would't be able to fill or select options until it had finished. I found a solution on Stack Overflow that solved this by calling the function until it was available.
I learned how to add items to the context menu. Once I was able to add an entry and get the function handlers hooked up I was able to move on to the next piece, which was just calling a speech function with the options filled in.
I learned how to add a keyboard shortcut. This was so simple but exciting to me. I wanted to have a quick way to use the extension and a shortcut was just that. Since the rest of the work was done with the context menu I just had to hook up event handlers to call the speech function. I couldn't get the selected text the same way as when using the context menu. I found a solution on Stack Overflow that would execute a function on all tabs and return the selections in a callback. Once I had realized that the background page was the current window and I no longer had the text I was able to search for the solution pretty quickly. The last thing I did was add a variable to keep track of when it was reading so that I could figure out whether to start or stop reading when using the shortcut.
I learned the importance of some of the package manifest parameters. Initially I had an issue where the text would not read for longer than ~15 seconds which eventually I found the answer was that the background page that Chrome uses would only live for that long. I tried to get around this with looping (setTimeout) but that wasn't enough to keep it alive. I found out that I needed to make the background script persistent in the manifest and that solved that issue. I had actually taken the longest to figure this out because of the inconsistency with text length and speech rate.
Using the speech synthesis in Chrome is pretty simple so the biggest hurdles I had were getting all the variables at the right times. I had issues with the selected text not being available on the first time passing to the speech function, which I solved by storing it globally (on my background page) instead of passing it between functions. Another was the availability of the options. Both in the options menu and the speech function I had to wait until the voices function returned the available voices before I could set those parameters. I worked around that by calling when available instead of assuming they were available immediately (what I reference above).
Both of the bigger issues were found on Stack Overflow. Someone had even given the solution for creating the 'read parameters when available' that I adapted to read the voice options. The other was solved by making the background page persistent in the manifest instead of trying to keep it alive from the script. Most of the other things were found right in the Chrome documentation.
For now I don't have a desire to update it unless it breaks. A few things that might be nice but that may not work with the current set up would be to push the selected text to a text box that is in a collapsible panel, and as the text is read it removes it from the text box. Perhaps making it highlight the currently read text as it's reading (at least the snippet being read since individual characters/words might not work well). This would allow for appending text to be read instead of having to wait or stop the currently selection. I think these changes are a fairly big change from what it currently does though and would be something that might never be the direction I want to take with it. The code is available for other to use or learn from though so maybe someone makes the update on their own.