Search code examples
javascriptapiwindowstate

How to use windows.WindowState API (JavaScript)?


I like to use the windows.WindowState API, but got the error "windows is not defined".

const windowState = windows.WindowState;

I am developing a WebExtension, which makes use of the speech synthesis API. The problem with it is, when speech is paused, that API can’t be used on other tabs anymore! To prevent this, that speech has to be stopped instead of paused. But in this case, the whole paragraph has to be repeated from start, if the user wants to resume the text on the first tab again. That is, why I want to distinguish between different visability changes (I am using the 'visibilitychange', 'blur' and 'focus' event for this):

  • TabLeave ➔ stop speech
  • TabEnter ➔ start speech again, if user made this setting
  • LostFocus & WndMinimized ➔ pause speech, if user made this setting
  • GotFocus & WndRestored/WndMaximized ➔ resume speech, if it was paused before and the user made this setting

My "manifest.json":

{
    "description": "My extension.",
    "manifest_version": 2,
    "name": "Lesehilfe",
    "version": "1.0",
    "homepage_url": "https://dummy.de",

    "icons": {
        "32": "icons/aero_arrow_reading_aid_32x32.cur"
    },

    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js": ["lib/tinycolor.js", "lib/input_action.js", "lib/state_change.js", "lib/print.js", "lib/xLabs_library.js", "options.js", "content.js"],
            "css": ["style.css", "resources.css"]
        }
    ],

    "background": {
        "scripts": ["background.js"]
    },

    "options_ui": {
        "page": "options.html",
        "browser_style": true,
        "chrome_style": true,
        "_comment": "browser_style is for Firefox, non-standard chrome_style for Chrome and Opera"
    },

    "permissions": [
        "storage",
        "notifications",
        "activeTab"
    ]
}

Problem demo:

<html>
    <body style="text-align: center;">
        <strong>Speech Synthesis API Test</strong>
        <p id="SOquestion">
I am developing a WebExtension, which makes use of the speech synthesis API. The problem with it is, when speech is paused, that API can’t be used on other tabs anymore! To prevent this, that speech has to be stopped instead of paused. But in this case, the whole paragraph has to be repeated from start, if the user wants to resume the text on the first tab again. That is, why I want to distinguish between different visability changes (I am using the 'visibilitychange', 'blur' and 'focus' event for this):
        </p>
        <button id="btnPlayPause">▶</button><!-- Play sign -->
        <button id="btnStop">⏹</button>    <!-- Stop sign -->
        <script>
            function onCompletion(e) {
                btnPlayPause.innerText = "▶";  // Play sign
            }

            var btnPlayPause = document.getElementById("btnPlayPause");
            var btnStop = document.getElementById("btnStop");
            var text = document.getElementById("SOquestion").innerText;

            var synth = window.speechSynthesis;
            var utterThis = new SpeechSynthesisUtterance(text);
            utterThis.onend = onCompletion;
            utterThis.lang = 'en-UK';

            btnPlayPause.addEventListener('click', (e) => {
                if (synth.paused) {
                    btnPlayPause.innerText = "⏸";  // Pause sign
                    synth.resume();
                    return;
                }
                if (synth.speaking) {
                    btnPlayPause.innerText = "▶";   // Play sign
                    synth.pause();
                    return;
                }
                btnPlayPause.innerText = "⏸";      // Pause sign
                synth.speak(utterThis);
            }, false);
            
            btnStop.addEventListener('click', (e) => {
                onCompletion();
                synth.cancel();
            }, false);
        </script>
    </body>
</html>

Please follow these steps:

  • run code snippet
  • click play button
  • click pause (same button)
  • navigate to some other tab, which has an article
  • go into Firefox reader mode
  • start speech synthesis there

➔ it should not play any speech output (at least this happens to me)

  • now compare the same with stopping the speech instead of pausing it

My questions are:

  • Is the windows.WindowState API limited to the background script only, or can it be used on the content script too?
  • What permission does it need?

Solution

    1. Question (content/background):

    The windows.WindowState API is not included in this list - therefore it can only be used in background scripts. And the base object is browser or chrome. Here some lines of code for use in an onMessage listener:

    // does only work on Firefox (or Chromium with polyfill) due to the use of promise
    return browser.windows.getCurrent().then(win => {
        return {windowState: win.state};
    });
    
    // old version for Chromium
    chrome.windows.getCurrent(null, (win) => {
        sendResponse({windowState: win.state});
    });
    return true;
    
    1. Question (permission):

    This API does not need any permission.