whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.02k stars 2.62k forks source link

Deprecate alert(), confirm(), prompt() #2894

Open jasonwilliams opened 7 years ago

jasonwilliams commented 7 years ago

Deprecate alert(), confirm(), prompt()

Motivations

The alert(), confirm() and prompt() APis are more and more being used in malicious ways [7][8], such as keeping a user on the page and not allowing them to leave, mainly by web scams, or abusive advertising (usually by looping the alert box).
On Chrome (iOS) the situation was so bad i would have to restart the phone, as re-opening the browser would just reload the page. I belive this has now been fixed[1]

These dialogs are synchronous in their nature which means the javascript engine needs to pause until a response is obtained, sometimes locking up the whole browser. There is work being done to seperate such tasks, however on some phones the whole browser still locks up.

Chromium's latest policy no longer condones the usage of these Apis either[2]

Test Case

https://codepen.io/jayflux/pen/jLVYvo Here i haven't included an infinite loop, but only 6 iterations to show what happens.

What is being done?

Chromium have blocked alerts() from being called in an unload handler[3] but this isn't enough, pages have got around this by starting the loop once you enter the page.
Chrome iOS have now added a supress option in their browser[1]
Window.showModalDialog() has been deprecated and removed in hrome 43, and Firefox 55. [4]

The Chrome team have also added a policy discouraging developers from using such APIs https://developers.google.com/web/updates/2017/03/dialogs-policy

Project Old Spice by Chromium to stop javascript dialogs from blocking the window

In the upcoming Fall Creators Update Microsoft Edge [Windows 10 16226] have made sure alert(), prompt(), confirm() don't block the user from being able to close the tab [9]

Alternatives

The Notifications API[5] is very useful and should be used for notifiying the user of events, and has good basic support across all modern browsers. For those needing to gain user input

[6] should be used instead. I understand dialog is not well supported across modern browsers yet, Google have provided a polyfill untill this is the case https://github.com/GoogleChrome/dialog-polyfill.

Having dialogs native in the browser should reduce the concern of overhead (needing scripts, plugins just to show a confirmation/alert box).

With these alternatives in place, and a comprehensive set of tools in the web ecosystem i believe there is no need to ever use these APIs anymore and thus should be deprecated from the specification

Further conversation here: https://discourse.wicg.io/t/proposal-deprecate-alert-confirm-prompt/2264

1: https://bugs.chromium.org/p/chromium/issues/detail?id=485969
2: https://developers.google.com/web/updates/2017/03/dialogs-policy
3: https://bugs.chromium.org/p/chromium/issues/detail?id=68780
4: https://developer.mozilla.org/en/docs/Web/API/Window/showModalDialog
5: https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API
6: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
7: https://support.mozilla.org/en-US/questions/690130
8: https://discussions.apple.com/thread/7045611?start=0&tstart=0 9: https://blogs.windows.com/windowsexperience/2017/06/21/announcing-windows-10-insider-preview-build-16226-pc/#4ObsXt8hmfuv2xv5.97

domenic commented 7 years ago

What concrete proposal you mean by "deprecate"?

jasonwilliams commented 7 years ago

@domenic maybe i can just remove the proposal part

domenic commented 7 years ago

I still don't understand. What desired outcome are you hoping for getting implemented in browsers?

jasonwilliams commented 7 years ago

@domenic this isn't a request for something to be implemented, this is an intent to deprecate these APIs from the spec. Similar to https://github.com/whatwg/html/issues/75

domenic commented 7 years ago

I see. We don't generally deprecate things except as a warning that browsers are starting to remove them and that we anticipate them being removed from the spec eventually.

Absent any concrete statements from browsers in that direction, I'll close this thread. Happy to continue discussion in the closed thread though.

RByers commented 7 years ago

Note that in chromium we (Avi Drissman in particular) are totally working to try to fix this. But Domenic is right, it really starts as implementation work and once we have a good idea of what we can successfully ship in one browser we talk about updating specs.

smaug---- commented 7 years ago

Well, it would be good to get all the browser vendors behind the idea that removing alert() etc in general is a good thing. And removing features from platform without discussing with others isn't really a good work mode.

FWIW, I think we should try to get rid of these modal dialogs. How to do that is unclear.

Also, Chrome's and Firefox' implementation for these are very different. Chrome seems to block way more.

domenic commented 7 years ago

@annevk what action do you see us accomplishing in this thread so that you reopened it? I still think it's inappropriate to change the specification until we have concrete removal plans.

annevk commented 7 years ago

@domenic I figured it deserved some more implementer input especially since there seems to be interest in removing them eventually. E.g., we could consider what we did with synchronous XMLHttpRequest. Make a pretty strong declaration of harm.

jasonwilliams commented 7 years ago

Statistics from Chromium show dialog usage to be quite low: https://www.chromestatus.com/metrics/feature/timeline/popularity/950 https://www.chromestatus.com/metrics/feature/timeline/popularity/951 https://www.chromestatus.com/metrics/feature/timeline/popularity/952

Alert is under 0.08%

Firefox currently don't have telemetry data for this, but a ticket has been raised: https://bugzilla.mozilla.org/show_bug.cgi?id=1390234

domenic commented 7 years ago

That's not "quite low" :). 0.08% of internet users is extremely high. At one point our threshold was 0.003% before considering deprecation/removal, but that was considered too high, so today it's even more conservative (and not any particular concrete number).

jasonwilliams commented 7 years ago

Domenic sure that's fair, do you know what sort of numbers 0.08% represent?

At one point our threshold was 0.003% before considering deprecation/removal

Does this logic still apply if something is used to harm to users?

domenic commented 7 years ago

Well, very roughly, using only public data, we have internet population of 3.2 billion Chrome usage share ~50% 0.08% = 1.28 million people as of 2015. Note that 0.08% is page views, not users, so this is already pretty sketchy. So combining all these imprecisions, that's surely off by a lot, but probably not be more than one order of magnitude in either direction?

Does this logic still apply if something is used to harm to users?

In general no, which is why people like @avidrissman are working to remove the harmful aspects by e.g. changing them to not look like native system dialogs, or preventing them from stealing focus, etc. But such interventions are already allowed by the spec. You're talking about something else entirely, deprecation, which is not about reducing user harm.

matkoniecz commented 3 years ago

Please, do not deprecate them. Especially alert() is very useful, especially for more beginner programmers in simpler tools (see just this example). Not everyone is making/using some highly complex React apps, simple tools have their place. And at least for me alert() remained useful as something clearly acting when debugging my first half-broken React project.

There may be some problems and they should be fixed making them to not look like native system dialogs, or preventing them from stealing focus, etc

In the same way as nowadays repeated alert() are blockable by user (at least in Firefox) unlike in past where buggy/malicious alerts could render browser unusable.

On Chrome (iOS) the situation was so bad i would have to restart the phone, as re-opening the browser would just reload the page. I belive this has now been fixed

Using bug/bad design in one specific browser as even part of justification for removal of long-standing, widely used and useful tool is absurd. Especially if that is now fixed.

zefir-git commented 1 year ago

@matkoniecz Debugging with alert() is not a good idea. To follow your execution flow, use console.log(). To block execution, use break points or the browser debugger. This is not complicated technology! It comes with every browser and if you use an IDE, it becomes x100 further easier.

alert(), confirm(), pmompt() etc. are NOT debugging tools. These functions are anti-consumer and anti-user-experience. If you have seen websites that heavily use alert and etc. you may have noticed how annoying they are as they block the entire tab. In many browsers, you cannot even close the tab before resolving the pop-up. The only browser feature allowing you to at all save yourself is this checkbox: image which shows after a tab shows multiple alerts. Now why do you think that was needed?

Simple JS that tracks your mouse movement and detects when it is outside/approaching the end of the web content, could easily assume you're trying to close the tab and start spamming you with alerts. But that's not even needed. Any developer can at any time decide to do that.

So LITERALLY the browser allows you (the user) to "deprecate" these because of how annoying alerts are and because of how they can be abused.

Now, it's important to note that some developers use these functions without malicious intent in production. They just don't care about user experience and simply want to get the job done fast. In my view, this is not the correct approach.

As a final note: using alert(), prompt(), confirm(), etc. has one benefit. Depending on your browser, operating system, desktop environment, theme, etc., these can look like native application pop-ups. This is good as it helps your UI blend with the user's system (not with your web page design though). However, in most browsers, and OS's, this is not the case. The alerts are extremely ugly and don't blend with anything (neither the page, nor your computer's system UI). An exception to this is Firefox if you use Gnome DE and have the third-party Firefox Gnome theme installed and mobile browsers.

So please explain why one would need this. And why do you think it should appear on more websites?

matkoniecz commented 1 year ago

These functions are anti-consumer and anti-user-experience. If you have seen websites that heavily use alert and etc. you may have noticed how annoying they are as they block the entire tab. In many browsers, you cannot even close the tab before resolving the pop-up. The only browser feature allowing you to at all save yourself is this checkbox

This checbox entirely resolves this problem.

So LITERALLY the browser allows you (the user) to "deprecate" these because of how annoying alerts are and because of how they can be abused.

control != deprecation

zefir-git commented 1 year ago

@matkoniecz

This checbox entirely resolves this problem.

the checkbox does not resolve the problem. The checkbox only shows after 1 tab has shown 3 or more alerts. Other tabs (even of the same website) can still show prompts. And if the developer of the website has relied entirely on showing alerts, then I will not see the potentially important information.

The problem still exists. The problem is that developers want to use this and are using this. Which leads to more web apps relying on alerts. More encounters with difficult-to-use and annoying websites. The idea of deprecating this is to stop developers in their tracks when they see a warning in their IDE or a failed code quality/analysis check and not to prevent all existing sites using alert from working, it's to stop developers even thinking about using it. And I still don't understand why you would want to use this. This is a useless feature that is annoying at best.

Deprecating will not remove the functionality, as far as I know. That to my knowledge is to state that it is not recommended and not supported.

control != deprecation

This is why I have placed it in "quotes".

matkoniecz commented 1 year ago

And I still don't understand why you would want to use this.

I mentioned it in https://github.com/whatwg/html/issues/2894#issuecomment-893365430 - and also I used it in some cases in projects used only by myself where I wanted to show super-visible message box. Built in alert was much better than logs or importing entire framework or manually handcrafting DOM.

Also in some low use projects used by others, but I mentioned self-used projects first to make clear that it is far from uniform user hostile. Also, while alert can be used in user hostile way - at least it is clearly visible unlike say ad tracking/collecting private data and other typical uses of JS.

This is a useless feature that is annoying at best.

No, at best it is a simple way to show prominent message to user who wants to see a prominent message. That remained in use for long rather various JS methods that are on constant deprecation treadmill.

The idea of deprecating this is to stop developers in their tracks when they see a warning in their IDE or a failed code quality/analysis check and not to prevent all existing sites using alert from working

not true, see

Well, it would be good to get all the browser vendors behind the idea that removing alert() etc in general is a good thing.

in https://github.com/whatwg/html/issues/2894#issuecomment-322158608

zefir-git commented 1 year ago

In my experience as a user, any use of these prompts degrades the experience. Importing an entire framework for this is excessive.

For showing a prominent message, hand-crafting a modal or something like that would be much better. For something really important that the user definitely needs to see—use Notification. To let the user know the email they entered is invalid, simply append red text after the input or use .setCustomValidity. To log debug information, you can use console.

I agree with ultimately removing this from all browsers. This won't happen right away. Most likely it will be deprecated for several years before being completely removed. This is my guess based on previous things that browsers have deprecated and removed.

In my opinion, writing clean, modern and maintainable code is really important. To this day you can find large production websites using deprecated technologies, clearly very old code, anti-consumer features, etc. Thus seeing alert() in JavaScript source code is a big red flag for me.

What follows are some code snippets that anyone reading can feel free to use to replace their usage of alert.

alert replacements # 1. For debugging At your disposal you have `console.log` which is the most generic function for logging debug messages. You can use things like `console.error` and etc if you want some special style (console.log allows for custom CSS btw) and appearance, but these are mostly useless for simple debugging. ```diff - if (something) alert("it works"); + if (something) console.log("it works"); ``` You can see these messages in your browser developer tools, usually opened with Ctrl+Shift+I. (make sure you are in the console tab). The most powerful debugging tool, however, is the debugger you get with any major browser in dev tools. With the debugger, you can go through your code one by line to see where a bug occurs. You can skip over lines and much more. Have a look here (this is a tutorial from MDN): https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/What_are_browser_developer_tools#the_javascript_debugger # 2. For displaying a prominent message to the user ## 2.1. Extremely basic box with just text and a button ```js const showMessage = message => { const container = document.createElement("div"); // Replace this styling here with whatever you want container.style.position = 'fixed'; container.style.border = '1px solid #ccc'; container.style.left = '50%'; container.style.top = '50%'; container.style.transform = 'translate(-50%, -50%)'; container.style.padding = '6px'; container.style.display = 'flex'; container.style.columnGap = '6px'; container.textContent = message; const button = document.createElement("button"); button.textContent = "Close"; button.addEventListener("click", () => container.remove()); container.append(button); document.body.append(button); } ``` ## 2.2 A more advanced, user-friendly modal To convey information in a non-obtrusive way consider creating a modal. Style it to match the rest of your website. Here are the core features you should consider: 1. Accessibility. Add labels, screen reader text and aria attributes. 2. Usability. 2.1. When pressing Esc the modal should close 2.2. When clicking outside the modal, it should close 2.3. The primary modal action (e.g. a close button, or an input) should be focused when the modal is opened. If you have an input etc. it should be submittable with just Enter. 2.4. If the modal has more than text, e.g. buttons, inputs, links, etc. pressing Tab and Shift+Tab should only focus elements inside the modal (and not content behind it on your web page). You can do this by implementing a "focus trap" (you trap focus inside the modal while it's open). Get a list of all focusable elements. When tab is pressed and focus is on the last element in your modal, set the focus to the first element. And so on. 3. Don't add slow animations that make the modal take more than 300ms to appear. 4. Ensure proper text size, contrast etc. I do not endorse Bootstrap, but if you use it already, I am pretty sure they provide ready made modals for you which aren't perfect but are better than `alert()`. # 3. Non-obtrusive messages (e.g. form validation) Perhaps the user entered an incorrect password. Perhaps their entered e-mail does not look quite right. There is no need to show an annoying alert. You can consider this: ```html

``` With the following CSS you can make the `p` after an `input` show with red text when the input is invalid: ```css input + p { display: none; } input:invalid + p { display: block; color: red; } ``` And now all you need to do is use the browser built-in validation mechanism (bear in mind all of this is a demo): ```js const email = document.getElementById("email"); // the result of your validation, e.g. error returned from your API server const error = "Your e-mail address is invalid"; emailInput.setCustomValidity(error); // to clear this later, just set custom validity to `""` const p = email.nextElementSibling.textContent = error; // if you don't want to use a paragraph at all, you can use another browser built-in feature: email.reportValidity(); ``` There are of course endless more possibilities that can best suit your project. Almost anything is better than `alert()`.
domenic commented 1 year ago

Hey folks, this sort of back and forth is probably best held in other venues, instead of one which notifies 669 watchers with each exchange.