Chrome updates broke javascript .close()?

Twine Version: 2.3.5
I’ve just come back to my Twine project after an absence of about a year and discovered a bug that wasn’t there before.

I have a passage where the player enters a pub and clicks a link to play a song on the jukebox. This opens an external window using a bit of javascript to play a video from youtube. - This bit still works.

But now when you click the link to close the window nothing happens?
I know this isn’t a Twine question but hoping someone familiar with javascript might know if something has changed with Chrome/Edge permissions that could break it?

I’ve tried Chrome Version 122.0.6261.129 (Official Build) (64-bit) on Windows 10 and 11.

Many thanks!

<script>

var openedWindowMoney;

function openWindowMoney() {
  openedWindowMoney = window.open('https://www.youtube.com/watch?v=TC1Vfoq3PvU&ab_channel=Historyboy87','_blank', 'location=yes,height=400,width=400,scrollbars=yes,status=yes');
}


function closeOpenedWindowMoney() {
  openedWindowMoney.close();
}
</script>

(link:"Play song on jukebox")[<script> openWindowMoney(); </script>]
(link: "Stop song")[<script> closeOpenedWindowMoney(); </script>]

1 Like

Is there an error in the browser dev console?

2 Likes

I don’t get an error, it just doesn’t work to close it. When opening the window in Harlowe from the browser version of Twine, Firefox logs:
Storage access automatically granted for origin “https://www.youtube.com” on “https://twinery.org”.

I’m thinking it’s a new permissions policy thing? Weird. I can open a blank window and close it, but when it contains a YouTube link… it doesn’t close. Hmmm… this might be better asked on Stack Exchange.

1 Like

If I add the supplied code to a Passage of a new Harlowe v3.3.8 based Project I receive a ReferenceError: openWindowMoney is not defined error.

Which makes sense as the openWindowMoney() function is being defined in one Private Scoped execution context, and being executed in a different Private Scoped execution context. And things defined in one such scoped context are not available in another.

If I use a Namespace to raise the scope of the function definitions to a “Global” like Scope, by using code like the following in the Story > JavaScript area of the project…

let openedWindowMoney;

window.setup = window.setup || {};

setup.openWindowMoney = function openWindowMoney() {
	openedWindowMoney = window.open('https://www.youtube.com/watch?v=TC1Vfoq3PvU&ab_channel=Historyboy87','_blank', 'location=yes,height=400,width=400,scrollbars=yes,status=yes');
};

setup.closeOpenedWindowMoney = function closeOpenedWindowMoney() {
	openedWindowMoney.close();
};

…and then change the Passage content to use these new “Global” like functions…

(link:"Play song on jukebox")[<script> setup.openWindowMoney(); </script>]
(link: "Stop song")[<script> setup.closeOpenedWindowMoney(); </script>]

…then the Play song on jukebox link will open the video in a child window, but the Stop song link fails to close that child window just as you stated in your original post.

As to why the <window>.close() method doesn’t close that child window, the hint is in the Return value section of the <window>.open() method documentation (emphasis mine)…

Return value

If the browser successfully opens the new browsing context, a WindowProxy object is returned. The returned reference can be used to access properties and methods of the new context as long as it complies with the same-origin policy security requirements.

Simply put, the HTML document calling the method needs to be of the same origin (on the same domain) as the HTML document being opened. Which isn’t the case, unless your Story HTML file is hosted on the YouTube site.

1 Like

I disagree, this isn’t the same-origin policy at work. In general, you can window.close windows that you open when pointing to other domains.

If you change the URL from this:

https://www.youtube.com/watch?v=TC1Vfoq3PvU&ab_channel=Historyboy87

to this:

https://www.example.com/

you’ll find that the window opens and closes as expected.

Instead, I believe that this is something that YouTube is doing to defeat being closed.
I’m not 100% sure what YouTube is doing to prevent this, but I suspect it might have something to do with Content Security Policy.

More research might be able to dig up exactly what YouTube is doing to make it fail, but it likely won’t help you to fix the “Stop song” button.

I recommend just getting rid of the “Stop song” button entirely. The “Play song” button opens a pop-up window with a clear, visible close button, and YouTube itself includes a pause button that everyone knows how to use. Trying to close the window yourself seems unnecessary to me.

2 Likes

Thank you so much for taking the time to look into that for me everyone.
It’s annoying as the close button was keeping track of an ingame variable.
I.e the game knew whether a youtube music window was open or not and would not allow another window to open if there was one already open.

I’m not holding out much hope for a work around. I might have to trim the quests associated with it.

Many thanks again all. :+1:

1 Like

Ask this question on Stack Exchange. There are an infinite number of nerds on there with way more brain power than us. Your question isn’t Twine related, it’s JavaScript and browser permissions.

That said, I believe you can inject HTML into a window that you’ve opened. You could try opening a window with an iframe that contains the youtube video. That might work because the window would be 100% your domain then. Just grasping at straws here though.