Closed Bug 1032243 Opened 10 years ago Closed 10 years ago

about:newtab should use native Promise implementation

Categories

(Firefox :: New Tab Page, defect)

33 Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
Firefox 33

People

(Reporter: getify, Assigned: ttaubert)

References

Details

Attachments

(3 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:33.0) Gecko/20100101 Firefox/33.0 (Beta/Release)
Build ID: 20140629030206

Steps to reproduce:

var p = new Promise(function(resolve){
   setTimeout(function(){ resolve(42); },100);
});

Object.freeze(p);

p.then(function(msg){ console.log(msg); });



Actual results:

The test never prints out `42`, presumably because the `Object.freeze(..)` is somehow affecting the way state is stored/managed for the promise instance.


Expected results:

The test should print out `42` after 100ms, and should not throw any errors. Confirmed with @allenwb that promises state/behavior should not be affected by `Object.freeze(..)`.

"Promise instances have no specified own properties, so O.freeze shouldn't change their behavior." --@awbjs

IOW, promise state/behavior must be only be managed by internal slots (or some other mechanism which is not exposed with external properties) that cannot be affected by `Object.freeze(..)`.
OS: Mac OS X → All
Hardware: x86 → All
> User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:33.0) Gecko/20100101
> Firefox/33.0 (Beta/Release)

Which is it?  Beta is currently 31, not 33.  Are you even using Firefox at all?  ;)

> The test never prints out `42`

I see "42" in the console both in nightly 33 and in beta 31.  Nor surprising, since I wouldn't expect Object.freeze to affect any of the Promise guts.
Flags: needinfo?(getify)
> Which is it?

I am using nightly. If nightly is incorrectly reporting itself (I certainly didn't make any changes to what was filled in) to bugzilla, then that's another bug in nightly. ;-)

> I see "42" in the console

I certainly do not, which is why I filed the bug. Attaching a screenshot to show exactly what I'm seeing, and clarifying the above question about which browser I'm in.
Flags: needinfo?(getify)
> I am using nightly.

What is navigator.userAgent for you?  What I see in a current nightly is:

  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:33.0) Gecko/20100101 Firefox/33.0"

without the "(Beta/Release)" bit.

> I certainly do not, which is why I filed the bug.

OK.  I just checked again, and I definitely see "42" in the console in a 2014-06-30 nightly, both when putting your script in the console itself and when putting it in a web page.  I'm on Mac, like you, albeit on 10.9.

So let's try to figure out what's different in our setups.  Do you see the problem in safe mode?  In a clean profile?
Flags: needinfo?(getify)
> navigator.userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:33.0) Gecko/20100101 Firefox/33.0"

> Do you see the problem in safe mode?

Yes.

> In a clean profile?

Yes.

-------

But I think I just narrowed down my reproduce steps, and this is pretty weird.

When I open firefox nightly, on the very first/only default tab (which I default to about:blank, btw), then the test above works and prints 42. When I click the new-tab icon (the "+" in the tab bar), and try it in any subsequent tab, the test above fails.

If you omit or comment-out the `Object.freeze(obj)` line, the test works in any tab.

So, weirdly, it appears that `Object.freeze(..)` seems to affect the promise only in second/third/fourth/etc tabs.

BTW, I tried those same steps in safe mode (no add-ons), and also in the clean profile: same behavior with difference between first tab and subsequent tabs.
Flags: needinfo?(getify)
BTW, even more weird info.

It continues to work on that first tab even if I navigate to a real page and then go back to "about:blank".

On the subsequent tabs, if I first navigate to a real page, then back to "about:blank", those tabs start passing the test too.

So, it's only a new "about:blank" tab without any navigation that seems to be suffering.
Even more clear reproduce steps:

I just checked my new tab settings, and the URL was set to "about:newtab". I changed it to "about:blank" (which seems to basically load the same sort of blank page), and now when I launch new tabs, the tests above work. If I then type "about:newtab" into the URL, and hit <enter>, then the test stops working. When I type "about:blank" into the URL, and hit <enter>, then the test starts working again.

So, it now clearly appears that something about the environment of "about:newtab" is having the problem with `Object.freeze(..)` + promises.
Summary: Promises should not be affected by `Object.freeze(..)` → Promises should not be affected by `Object.freeze(..)` when on the "about:newtab" page
Oh, about:newtab.

That redefines window.Promise to some nonstandard thing, so you're not actually getting standard Promises.  You're getting whatever that page wants to redefine Promise to.  Specifically, it's the thing in Promise.jsm.

That thing does in fact fail if you Object.freeze its objects, since its not an actual Promise implementation, just a sorta-close polyfill.

So the only possible bug here is that about:newtab is using this thing at all.  On the other hand, it can do whatever it wants to, just like web pages can redefine Promise, so I'm not sure whether this is a bug that's worth fixing.
Status: UNCONFIRMED → NEW
Component: JavaScript Engine → New Tab Page
Ever confirmed: true
Product: Core → Firefox
> On the other hand, it can do whatever it wants to

I'm not sure I understand exactly what about:newtab is supposed to be, or why it's supposed to be different from about:blank?

But it seems like a pretty unfortunate footgun that the default page people get when they open a new tab (I certainly never chose about:newtab over about:blank, because I never even knew it was a thing) is some sort of weird/broken/patched web environment that's not as fresh as a blank page implies it is. It is extremely common for web developers to open a new tab, pop up the console, and try some code. Sounds like nearly everyone of them is silently being led into danger.

It's not even like the address bar gives any indication that you're on this special about:newtab page as opposed to (like I assumed) about:blank.

I can throw out several mitigating behaviors as suggestions to implement a "fix" for this footgun:

1. make this blank default about:newtab the same fresh environment as about:blank, so there is no footgun.
2. make it so that by default your new tab is about:blank, but let you pick about:newtab (with proper warning and explanation of what it is and why it's different) if you want.
3. add a console message by default in about:newtab that explains it's not the same thing as about:blank and to be careful of assuming a fresh JS environment. that way you get warned of the footgun before you shoot yourself with it.
4. make the URL bar clearly indicate you're on something other than about:blank so it's more obvious that it may not indeed be a fresh empty JS environment. that way you get a clue that there could be a footgun lurking so you know to go looking for it. also, have some online documentation (MDN?) that makes these sorts of details clear, so that google searches turn up useful info like this.
Summary: Promises should not be affected by `Object.freeze(..)` when on the "about:newtab" page → "about:newtab" breaks certain expected JS behaviors (like Promises)
One other piece of anecdotal evidence to support my claim: I teach JS classes on a continual basis. I always teach by having students open up a web console in a browser tab and entering in the code I am showing them, so they can see it themselves. I am pretty sure nearly every student (of hundreds) I've ever had could have fallen into traps like this, because they all probably just open a new tab and never think about it (and I didn't even know it was a thing to warn them about).

I am not aware (doesn't mean it doesn't happen) of any such footguns with chrome, which is (TBH) the more common student tool. But it would be great if students who choose FF to learn in wouldn't have possible weird behaviors that trip them (and their teacher!) up in their learning. :)
> you're not actually getting standard Promises.  You're getting whatever that page wants to redefine Promise to. Specifically, it's the thing in Promise.jsm.

FYI: I have a "pretty darn close to spec" polyfill for promises that you might consider swapping in for whatever sorta-promise thing is in Promise.jsm: https://github.com/getify/native-promise-only Mine is definitely not susceptible to such issues because it keeps promise state in an internal closure, not in object properties. :)
> I'm not sure I understand exactly what about:newtab is supposed to be

It's the default "new tab" page.

> or why it's supposed to be different from about:blank?

Did you at some point hide all the stuff it shows by default?  See the little disclosure square at its top right.

> is some sort of weird/broken/patched web environment

It's not a web environment at all.  It's basically part of the browser UI.

> It is extremely common for web developers to open a new tab, pop up the console, and try
> some code.

They will have a bad time with that, since this particular global is loading tons of scripts of various sorts.  Maybe we should have the console on about:newtab not actually run against the page or something...

Note that in Chrome the "new tab" page is likewise not about:blank and has all sorts of JS gunk it loads.  Try doing that and typing "google" in the console, for example.  Lots of other stuff in there too.

On the other hand, in Safari all the devtools menuitems are disabled on their new tab page, so you can never open a console on it at all.  Maybe we should just do that.

> 1. make this blank default about:newtab the same fresh environment as about:blank, so
> there is no footgun.

That would somewhat defeat the purpose of the about:newtab page, which is to actually provide some browser UI functionality.

> 2. make it so that by default your new tab is about:blank

Likewise.  This is optimized for normal users, not web developers.

> add a console message by default in about:newtab that explains it's not the same thing
> as about:blank

This is totally doable.

> make the URL bar clearly indicate you're on something other than about:blank

Again, that would defeat the purpose for most users.  Most users have never heard of about:blank.

> I always teach by having students open up a web console in a browser tab and entering in
> the code I am showing them

As I said above, this is a terrible idea in every browser I have that allows you to open a web console in this situation at all.  You should be using an explicit page that they load instead of whatever UI a browser loads in its new tabs.  That would also let your students use Safari without being completely confused.

> FYI: I have a "pretty darn close to spec" polyfill for promises that you might consider 

The plan is to replace Promise.jsm with the actual Promise implementation.  I doubt your polyfill addresses the concerns that keep people using Promise.jsm right now (see dependency tree of bug 885333.
> You should be using an explicit page that they load

I do, it's called the blank page. That's what literally every JS workshop and live-code-along talk I've ever been to has suggested. Whether that's a "good idea" or not is not nearly as relevant as the fact that it's practically ubiquitous understanding that if you're on the "about:blank" empty page, you have a clean fresh JS env in which to work.

Moreover, Chrome makes this easy for devs. FF is making this harder for devs in footgun'ish ways. (see below)


>> make the URL bar clearly indicate you're on something other than about:blank
> Again, that would defeat the purpose for most users.  Most users have never heard of about:blank.

In Chrome, their new-tab page shows an empty address bar (like FF), but when you go to about:blank, it actually shows "about:blank" in the URL address bar. If you set your new-tab URL to be "about:blank", it shows "about:blank" in the address bar when you open a new tab.

This makes it a very convenient way to help people know if they are legitimately in the empty fresh JS environment as opposed to this weird new-tab environment.

NOTE: I always configure my browser new-tab pages to be completely blank, as do many of the developers I work with, which actively makes it less clear the difference. When you do that, there's no visible difference EXCEPT for the address bar in Chrome (which turns out to be enough). In FF, there's no visible difference AT ALL.

As I see it, FF is being a little more hostile to developers in this use-case, because it obscures the fact that you can either be in about:newtab or about:blank, and there's no visible indication in the address bar of the difference.

So, when I tell Chrome-using students "make sure the address bar says 'about:blank'", it's an easy way for them to distinguish. Until now, I didn't know FF had (at least) two different pages where the address bar would be blank, so I was always mistakenly telling FF-using students "make sure the address bar is empty".

NOW, I will have to tell them "even though the address bar may be empty, make sure you manually type 'about:blank' into the address bar. no, no, don't worry that when you type 'about:blank' and hit <enter> it makes the 'about:blank' you just typed go away. the only way to know you're in the about:blank page is to make sure you've typed it."

This confusing behavior is all kinds of footgun'ish hostile to devs in this use-case. It's a shame that, as it stands, I'll have to tell students that Chrome is more well-suited to their usage.
> I do, it's called the blank page.

Sure, but the new tab page (about:newtab) is not blank.  That's obvious because it has big things showing on it unless you set preferences or toggle widgets to hide them.  And even then it has the disclosure widget for those things showing!

> In FF, there's no visible difference AT ALL

The about:newtab page in Firefox by default shows a Google search field, a search button, and 9 web page tiles.  In a clean profile those tiles show me logos for facebook, youtube, Wired, Lightbeam, Mozilla, Wikipedia, Trulia, Amazon, and BBC.  It looks absolutely nothing like a blank page.  So I'm pretty confused about why you think there is no (shouting) visible difference, when the difference is huge.

You can tell your students whatever you want, obviously.

Again, I think we should consider disabling devtools completely on about:newtab, like Safari does, to prevent that footgun.
> The about:newtab page in Firefox by default shows a Google search field, a search button, and 9 web page tiles.

It's been so long ago that I hid all that visual clutter that I didn't even remember doing it. I (like a lot of devs I know) prefer the minimal/blank environment as the default. I've had "about:blank" as my home page (and I thought my new-tab page) since I first got into browser webdev in the IE4 days 15+ years ago. It's so engrained in my brain to have the "about:blank" environment as my starting point, it never occurred to me that browsers would have things that look an awful lot like "about:blank" but not actually be "about:blank".

Quoting myself from above:

> NOTE: I always configure my browser new-tab pages to be completely blank, as do many of the developers I work with, which actively makes it less clear the difference. When you do that, there's no visible difference EXCEPT for the address bar in Chrome (which turns out to be enough). In FF, there's no visible difference AT ALL.

I'm slightly incorrect, there is *one* (very subtle) visual difference in FF... the little gray icon in the upper-right (see new screenshot attachment).

Of course, I cannot control how devs have their browsers configured. But many do have it configured like I do, which is to have a minimal interface that's more optimized to the "hey, I need to quickly open a new tab, and try some code in the console."

So, I'll have to change my instructions to students to be: "Make sure the address bar is empty, AND the page is white & blank, AND there's *NO* little gray icon in the upper-right... THEN you'll know you're in the right 'about:blank' page. If not or unsure, make sure to type 'about:blank' and hit <enter>."

Or... "just go to a blank tab in Chrome."

> I think we should consider disabling devtools completely on about:newtab

FWIW, that would have made it obvious I was just shot by a footgun, but it wouldn't do anything to make the footgun harder to run into, easier to avoid, easier to explain, etc. To me, it's a non-solution solution.
Let me rephrase your comment as I'm hearing it:

  Do my bidding, or I will tell all my students to use Chrome instead of Firefox.

Which is, of course, your privilege.  But, again, we're optimizing the Firefox UI for users in general, not your students.
One possible viable option, of course, is to hide the url in the url bar only of it matches the new tab url.  That's a bit hard given that the new-window and new-tab urls can be different, of course.
And that new-tab urls can be random http URLS, too.
Boris, would it not be better to simply show about:blank in the address bar if showing the about:blank page? The same way about:mozilla shows in the address bar when looking at that easter egg page.
> Let me rephrase your comment as I'm hearing it:

You're choosing to hear it wrongly.

My argument is: here's this pretty common developer use-case, which Chrome is better at than FF. Is there anyway we can make it better for FF devs **other than to tell FF users to go to Chrome**.

> we're optimizing the Firefox UI for users in general, not your students.

Since you've already admitted that most (non-developer) users don't even know what "about:blank" is, I'm not sure why simply having the address bar print "about:blank" (like Chrome does) when you are actually on the "about:blank" page would de-optimize for those general users?

All I'm wanting is for it to be more obvious that the blankly-configured about:newtab is definitely different than the really-blank about:blank. Since about:newtab is "optimized for users in general", I abandoned suggesting any changes to about:newtab, and rather suggested changing the other one, the one you admitted none of those users even know about, to make **it** more clearly different.
One other thing: lots of web APIs behave totally weirdly on toplevel about:blank.  document.cookie doesn't work right (and in fact works differently in different browsers; not all of them are following the spec here).  IndexedDB, localStorage, and other APIs tied to origins do not work right.

If you're trying to teach anything that's part of the web platform outside of pure JS, you really want to be using an http:// URL to get sane behavior.
> Boris, would it not be better to simply show about:blank in the address bar

That would make life more difficult for users who chose to have that be their default new tab url, no?  Now they would have to clear that text before typing in the url bar.

> I'm not sure why simply having the address bar print "about:blank" (like Chrome does)
> when you are actually on the "about:blank" page would de-optimize for those general users?

It wouldn't.  It would deoptimize for users who set their new-tab page to be about:blank (something that's not possible in Chrome as far as I can tell).
> It would deoptimize for users who set their new-tab page to be about:blank 

Most of whom are not trying to develop against it, note.  Not least because as I pointed out in comment 22 trying to develop against it is a really bad idea.
> If you're trying to teach anything that's part of the web platform outside of pure JS

Of course. Whenever they're learning about real non-trivial app development, there's pre-defined exercises they work in, which are real pages.

It's when I'm teaching them about all of the core JS language, which is the majority of my teaching, that they tend to use blank pages with the web console. "What does ~~'11.3' do? Try it in your console."
See Also: → 1032816
Perhaps another way to look at this is we're missing a devtools feature:

  "provide a pristine javascript environment for testing"

If we had something better and easier, then perhaps people would not fall back to abusing about:newtab.

I opened bug 1032816 discuss that issue.
(In reply to Boris Zbarsky [:bz] from comment #23)
> > Boris, would it not be better to simply show about:blank in the address bar
> 
> That would make life more difficult for users who chose to have that be
> their default new tab url, no?  Now they would have to clear that text
> before typing in the url bar.

Clicking into the address bar automatically selects the text already present, meaning a user can click and type just as they would if it was blank, no need to hit delete or backspace.

Those that are then setting the new tab action to load about:blank are likely developers or power users, considering this only seems to be configurable though about:config, not through any ui that a normal user would likely use. Not having the address shown in the address bar is of little benefit to developers and power users.
> Most users have never heard of about:blank.
> It would deoptimize for users who set their new-tab page to be about:blank
> Most of whom are not trying to develop against it, note.

This series of assertions seems contradictory and confuses me.

If "most users" haven't heard of "about:blank", and FF gives no web UI for setting your new-tab page to it (you have to change it manually in about:config), then what set of users do you think regularly go to the trouble to set "about:blank" as their default?

It must definitely be a smaller subset by your reasoning above. I would think that smaller subset tends to be developers, as knowing about "about:blank" (and even knowing how to use about:config) is probably more a power-user/developer type of thing.

If it's only for a smaller subset of users than the general user base you usually optimize for, and at least a decent amount of that smaller subset is likely developers, it sure seems like optimizing for them is at least a reasonable thing to consider.

What's the downside? Your de-optimization you listed:

> Now they would have to clear that text before typing in the url bar.

...Which is easily solvable by having the address bar contents highlighted when you focus it. Near as I can tell, FF is already doing that with both mouse and keyboard focusing to the address bar.

Maybe the only extra case that would need special handling is: "open a new tab and automatically focus the address bar. if 'about:blank' is the default contents of the address bar when that new tab auto focus occurs, highlight the contents, because most people who go to the address bar want to replace 'about:blank', not edit/append to it."
There are plenty of user studies showing that users get confused by the select-highlight behavior and still manually clear.

> considering this only seems to be configurable though about:config, not through any ui
> that a normal user would likely use

Uh...  The "new tab URI" setting is right there in the preferences.  I'm pretty tired of you not bothering to actually look at your screen before claiming things in this bug.

I think I'm done here, since now we're off into the UI weeds and I'm not a UI expert.  I care about the platform end here, which is working as it should.
(In reply to Boris Zbarsky [:bz] from comment #29)
> There are plenty of user studies showing that users get confused by the
> select-highlight behavior and still manually clear.
> 
> > considering this only seems to be configurable though about:config, not through any ui
> > that a normal user would likely use
> 
> Uh...  The "new tab URI" setting is right there in the preferences.  I'm
> pretty tired of you not bothering to actually look at your screen before
> claiming things in this bug.
> 
> I think I'm done here, since now we're off into the UI weeds and I'm not a
> UI expert.  I care about the platform end here, which is working as it
> should.

I've certainly looked for a ui option to change the new tab URI, can not find it. Is that option only in nightly?

If I set the new tab uri to be about:mozilla it is not cleared when creating a new tab, but just typing about:blank will clear the address bar, any address I type and browse to should not be removed from the address bar.
> Is that option only in nightly?

No.  Firefox 30, open preferences, select the General panel, and type whatever URI you want in the nice textfield labeled "Home Page".
> The "new tab URI" setting is right there in the preferences.
> type whatever URI you want in the nice textfield labeled "Home Page".

Which is of course NOT AT ALL the same thing as what URL gets loaded by default into a **NEW TAB**, which is what we're discussing.

Like lpotter, I have **also** looked hard to find a "new tab URI" setting in the main preferences. I have never found it. And I'm using the latest nightly. There's definitely a setting for "When nightly starts" and "Home page", but I see no option anywhere for "When a tab opens..."

> I'm pretty tired of you not bothering to actually look at your screen before claiming things in this bug.

Good grief. That's totally not what's happening. I've been playing very close attention to detail, posting screenshots of what I am seeing, etc. I don't know what other sort of good faith effort I could be making.

But I similarly am done with this issue, since you'd rather make rude accusations rather than assume that there's simple miscommunication.
(In reply to Boris Zbarsky [:bz] from comment #31)
> > Is that option only in nightly?
> 
> No.  Firefox 30, open preferences, select the General panel, and type
> whatever URI you want in the nice textfield labeled "Home Page".

That is not the new tab uri, that is the homepage, that is not loaded when creating a new tab.
Kyle, I'm sorry, I was wrong.  That preference does in fact control only the first tab in a window...

I still maintain that I should not be in the business of designing UI, and neither should you, probably.  ;)
I do design UI, and clearing the address bar when I browse to about:blank is confusing and undesired behavior.
Paolo, since you were interested in Promise.jsm issues...
(In reply to Boris Zbarsky [:bz] from comment #36)
> Paolo, since you were interested in Promise.jsm issues...

Thanks! Filed bug 1033406 specifically for the Promise.jsm bug, leaving this one for the "about:newtab" environment more generally.
Good point, we didn't have a native Promise implementation back when I wrote about:newtab v1. For all the other bugs/suggestions mentioned here we should have separate bugs.
Summary: "about:newtab" breaks certain expected JS behaviors (like Promises) → about:newtab should use native Promise implementation
Includes a fix for a test that started failing now due to Promise.jsm working slightly differently.
Assignee: nobody → ttaubert
Status: NEW → ASSIGNED
Attachment #8449866 - Flags: review?(adw)
Attachment #8449866 - Flags: review?(adw) → review+
https://hg.mozilla.org/mozilla-central/rev/ade6fa3be16e
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → Firefox 33
NOTE: I've filed this bug (https://bugzilla.mozilla.org/show_bug.cgi?id=1096336) to cover all the "about:blank" behaviors I've identified as annoying to developers, given that we now have a FF developer edition, where some of the user-centric assumptions here may not necessarily need to apply.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: