{"id":346368,"date":"2021-08-09T14:23:44","date_gmt":"2021-08-09T21:23:44","guid":{"rendered":"https:\/\/css-tricks.com\/?p=346368"},"modified":"2021-08-09T14:59:47","modified_gmt":"2021-08-09T21:59:47","slug":"choice-words-about-the-upcoming-deprecation-of-javascript-dialogs","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/choice-words-about-the-upcoming-deprecation-of-javascript-dialogs\/","title":{"rendered":"Choice Words about the Upcoming Deprecation of JavaScript Dialogs"},"content":{"rendered":"\n

It might be the very first thing a lot of people learn in JavaScript:<\/p>\n\n\n\n

alert(\"Hello, World\");<\/code><\/pre>\n\n\n\n

One day at CodePen, we woke up to a ton of customer support tickets about their Pens being broken, which ultimately boiled down to a version of Chrome that shipped where they ripped out alert()<\/code> from functioning in cross-origin iframes. And all other native “JavaScript Dialogs” like confirm()<\/code>, prompt()<\/code> and I-don’t-know-what-else (onbeforeunload<\/code>?, .htpasswd<\/code> protected assets?).<\/p>\n\n\n\n\n\n\n\n

Cross-origin iframes are essentially the heart of how CodePen<\/a> works. You write code, and we execute it for you in an iframe that doesn’t share the same domain as CodePen itself, as the very first line of security defense. We didn’t hear any heads up or anything, but I’m sure the plans were on display<\/a>. <\/p>\n\n\n\n

I tweeted<\/a> out of dismay. I get that there are potential security concerns here. JavaScript dialogs look the same<\/em> whether they are triggered by an iframe or not, so apparently it’s confusing-at-best when they’re triggered by an iframe, particularly a cross-origin iframe where the parent page likely has little control. Well, outside of, ya know, a website like CodePen. Chrome cite performance concerns as well, as the nature of these JavaScript dialogs is that they block the main thread when open, which essentially halts everything. <\/p>\n\n\n\n

There are all sorts of security and UX-annoyance issues that can come from iframes though. That’s why sandboxing is a thing.<\/strong> I can do this:<\/p>\n\n\n\n

<iframe sandbox><\/iframe><\/code><\/pre>\n\n\n\n

And that sucker is locked down. If some form tried to submit something in there: nope<\/em>, won’t work. What if it tries to trigger a download? Nope. Ask for device access? No way. It can’t even load any JavaScript at all<\/em>. That is unless I let it:<\/p>\n\n\n\n

<iframe sandbox=\"allow-scripts allow-downloads ...etc\"><\/iframe><\/code><\/pre>\n\n\n\n

So why not an attribute for JavaScript dialogs? Ironically, there already is one: allow-modals<\/code>. I’m not entirely sure why that isn’t good enough, but as I understand it, nuking JavaScript dialogs in cross-origin iframes is just a stepping stone on the ultimate goal: removing them from the web platform entirely.<\/strong><\/p>\n\n\n\n

Daaaaaang. Entirely? That’s the word. Imagine the number of programming tutorials that will just be outright broken. <\/p>\n\n\n\n

For now, even the cross-origin removal is delayed until January 2022, but as far as we know this is going to proceed, and then subsequent steps will happen to remove them entirely. This is spearheaded by Chrome<\/a>, but the status reports<\/a> that both Firefox<\/a> and Safari are on board with the change. Plus, this is a specced change<\/a>, so I guess we can waggle our fingers literally everywhere here, if you, like me, feel like this wasn’t particularly well-handled. <\/p>\n\n\n\n

What we’ve been told so far, the solution is to use postMessage<\/code> if you really absolutely need<\/em> to keep this functionality for cross-origin iframes. That sends the string the user uses in window.alert<\/code> up to the parent page and triggers the alert from there. I’m not the biggest fan here, because:<\/p>\n\n\n\n

  1. postMessage<\/code> is not blocking like JavaScript dialogs are.<\/strong> This changes application flow. <\/li>
  2. I have to inject code into users code for this.<\/strong> This is new technical debt and it can harm the expectations of expected user output (e.g. an extra <script><\/code> in their HTML has weird implications, like changing what :nth-child<\/code> and friends select). <\/li>
  3. I’m generally concerned about passing anything<\/em> user-generated to a parent to execute. I’m sure there are theoretical ways to do it safely, but XSS attack vectors are always surprising in their ingenouity.<\/li><\/ol>\n\n\n\n

    Even lower-key suggestions, like window.alert = console.log<\/code>, have essentially the same issues. <\/p>\n\n\n\n

    Allow me to hand the mic over to others for their opinions.<\/p>\n\n\n\n

    Couldn’t the alert be contained to the iframe instead of showing up in the parent window?<\/p>Jaden Baptista<\/em>, Twitter<\/a><\/cite><\/blockquote>\n\n\n\n

    Yes, please! Doesn’t that solve a big part of this? While making the UX of these dialogs more useful? Put the dang dialogs inside<\/em> the <iframe><\/code>. <\/p>\n\n\n\n

    “Don’t break the web.” to “Don’t break 90% of the web.” and now “Don’t break the web whose content we agree with.”<\/p>Matthew Phillips<\/em>, Twitter<\/a><\/cite><\/blockquote>\n\n\n\n

    I respect the desire to get rid of inelegant parts [of the HTML spec] that can be seen as historical mistakes and that cause implementation complexity, but I can\u2019t shake the feeling that the existing use cases are treated with very little respect or curiosity.<\/p>Dan Abramov<\/em>, Twitter<\/a><\/cite><\/blockquote>\n\n\n\n

    It’s weird to me this is part of the HTML spec, not the JavaScript spec. Right?!<\/p>\n\n\n\n

    I always thought there was a sort of “prime directive” not to break the web? I’ve literally seen web-based games that used alert<\/code> as a “pause”, leveraging the blocking nature as a feature. Like: <button onclick=\"alert('paused')\">Pause<\/button><\/code>[.] Funny, but true.<\/p>Ben Lesh<\/em>, Twitter<\/a><\/cite><\/blockquote>\n\n\n\n

    A metric was cited that only 0.006% of all page views contain a cross-origin iframe that uses these functions, yet:<\/p>\n\n\n\n

    Seems like a misleading metric for something like confirm()<\/code>. E.g. if account deletion flow is using confirm()<\/code> and breaks because of a change to it, this doesn\u2019t mean account deletion flow wasn\u2019t important. It just means people don\u2019t hit it on every session.<\/p>Dan Abramov<\/em>, Twitter<\/a><\/cite><\/blockquote>\n\n\n\n

    That’s what’s extra concerning to me: alert()<\/code> is one thing, but confirm()<\/code> literally returns true<\/code> or false<\/code>, meaning it is a logical control structure in a program. Removing that breaks websites, no question. Chris Ferdinandi showed me this little obscure website that uses it:<\/p>\n\n\n\n

    \"\"<\/figure>\n\n\n\n

    Speaking of Chris:<\/p>\n\n\n\n

    The condescending \u201cdid you actually read it, it\u2019s so clear\u201d refrain is patronizing AF. It\u2019s the equivalent of \u201cjust\u201d or \u201csimply\u201d in developer documentation.<\/p>

    I read it. I didn\u2019t understand it. That\u2019s why I asked someone whose literal job is communicating with developers about changes Chrome makes to the platform.<\/p>

    This is not isolated to one developer at Chrome. The entire message thread where this change was surfaced is filled with folks begging Chrome not to move forward with this proposal because it will break all-the-things.<\/p>Chris Ferdinandi<\/em>, “Google vs. the web”<\/a>
    <\/cite><\/blockquote>\n\n\n\n

    And here’s Jeremy:<\/p>\n\n\n\n

    […] breaking changes don\u2019t<\/em> happen often on the web. They are\u2014and should be\u2014rare. If that were to change, the web would suffer massively in terms of predictability<\/a>.<\/p>

    Secondly, the onus is not<\/em> on web developers to keep track of older features in danger of being deprecated. That\u2019s on the browser makers. I sincerely hope we\u2019re not expected to consult a site called canistilluse.com<\/code>.<\/p>Jeremy Keith, “Foundations”<\/a><\/cite><\/blockquote>\n\n\n\n

    I’ve painted a pretty bleak picture here. To be fair, there were some tweets with the Yes!! Finally!!<\/em> vibe, but they didn’t feel like critical assessments to me as much as random Google cheerleading.<\/p>\n\n\n\n

    Believe it or not, I generally am<\/em> a fan of Google and think they do a good job of pushing the web forward. I also think it’s appropriate to waggle fingers when I see problems and request they do better. “Better” here means way<\/em> more developer and user outreach to spell out the situation, way<\/em> more conversation about the potential implications and transition ideas, and way<\/em> more openness to bending the course ahead.<\/p>\n","protected":false},"excerpt":{"rendered":"

    It might be the very first thing a lot of people learn in JavaScript: One day at CodePen, we woke up to a ton of customer support tickets about their Pens being broken, which ultimately boiled down to a version of Chrome that shipped where they ripped out alert() from functioning in cross-origin iframes. And […]<\/p>\n","protected":false},"author":3,"featured_media":346448,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"Cross-origin iframes are basically the heart of how CodePen works. You write code, we execute it for you in an iframe that doesn't share the same domain as CodePen itself, as the first line of defense. We didn't hear any heads up or anything.","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[1391,432,1365],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-09-at-10.49.34-AM.png?fit=2116%2C1716&ssl=1","jetpack-related-posts":[{"id":362672,"url":"https:\/\/css-tricks.com\/replace-javascript-dialogs-html-dialog-element\/","url_meta":{"origin":346368,"position":0},"title":"Replace JavaScript Dialogs With the New HTML Dialog Element","date":"February 8, 2022","format":false,"excerpt":"You know how there are JavaScript dialogs for alerting, confirming, and prompting user actions? Say you want to replace JavaScript dialogs with the new HTML dialog element. Let me explain. I recently worked on a project with a lot of API calls and user feedback gathered with JavaScript dialogs. While\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/01\/dialog-confirm.jpg?fit=1200%2C599&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":283765,"url":"https:\/\/css-tricks.com\/using-details-for-menus-and-dialogs-is-an-interesting-idea\/","url_meta":{"origin":346368,"position":1},"title":"Using <details> for Menus and Dialogs is an Interesting Idea","date":"March 21, 2019","format":false,"excerpt":"One of the most empowering things you can learn as a new front-end developer who is starting to learn JavaScript is to change classes. If you can change classes, you can use your CSS skills to control a lot on a page. Toggle a class to one thing, style it\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/03\/accordion.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":322507,"url":"https:\/\/css-tricks.com\/on-the-web-share-api\/","url_meta":{"origin":346368,"position":2},"title":"On the Web Share API","date":"October 5, 2020","format":false,"excerpt":"I think the Web Share API is very cool (here's our coverage). In a nutshell, it taps into the native sharing features on whatever platform you're on, if that platform supports it. I like this: Web Share API activated on iOS A heck of a lot more than these things:\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/10\/ios-shar-sheet.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":296590,"url":"https:\/\/css-tricks.com\/some-hands-on-with-the-html-dialog-element\/","url_meta":{"origin":346368,"position":3},"title":"Some Hands-On with the HTML Dialog Element","date":"October 7, 2019","format":false,"excerpt":"This is me looking at the HTML element for the first time. I've been aware of it for a while, but haven't taken it for a spin yet. It has some pretty cool and compelling features. I can't decide for you if you should use it in production on your\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/10\/dialog-featured.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":155634,"url":"https:\/\/css-tricks.com\/modular-future-web-components\/","url_meta":{"origin":346368,"position":4},"title":"A Guide to Web Components","date":"November 11, 2013","format":false,"excerpt":"The following is a guest post by Rob Dodson (@rob_dodson). Rob and I were going back and forth in CodePen support getting Polymer (a web components polyfill, kinda) working on a demo of his. We did get it working, and things kind of evolved into this article. Take it away\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":9448,"url":"https:\/\/css-tricks.com\/prevent-white-flash-iframe\/","url_meta":{"origin":346368,"position":5},"title":"Prevent White Flash While Iframe Loads","date":"May 17, 2011","format":false,"excerpt":"How to prevent an iframe from flashing white while the page is loading. An ugly problem when the background of your site is anything other than white.","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"featured_media_src_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-09-at-10.49.34-AM.png?fit=1024%2C830&ssl=1","_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/346368"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=346368"}],"version-history":[{"count":10,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/346368\/revisions"}],"predecessor-version":[{"id":346521,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/346368\/revisions\/346521"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/346448"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=346368"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=346368"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=346368"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}