Closed Bug 1303838 Opened 8 years ago Closed 8 years ago

Not switch to existing "target" tab when opening anchor link with a fragment

Categories

(Core :: DOM: Navigation, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla55
Tracking Status
firefox55 --- fixed

People

(Reporter: dev.coding, Assigned: freesamael)

References

(Depends on 1 open bug)

Details

(Keywords: ux-userfeedback, Whiteboard: [parity-Chrome][parity-Edge][parity-IE])

Attachments

(3 files, 7 obsolete files)

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Build ID: 20160623154057

Steps to reproduce:

Let's say you have some links that open in a named tab, with a fragment:
<a href="mypage.html#section-1" target="my-tab">My page</a>
<a href="mypage.html#section-2" target="my-tab">My page</a>
<a href="mypage.html#section-3" target="my-tab">My page</a>




Actual results:

Then when you click the first link, the tab opens up and go front.
But when you click another link without having closed the "my-tab" tab, then the "my-tab" tab will *not* move to front: it stays back, and so, it feels like the link did not open.


Expected results:

The "my-tab" tab should be put to front (ie: it becomes the active tab, as Opera do).
Attached file Showcase
Show case: open in FF, click the 1st link, and the tab will be opened with the correct hash fragment (title becomes red).
Then click the 2nd link on that 1st tab, without closing the opened tab (with the red title): the 2nd tab will not be on front, but its hash fragment gets updated (text becomes red, title becomes black).
Edge and IE11 has same behavior of Firefox. But tab highlighted.
Chrome's behavior is as the expected.
Status: UNCONFIRMED → NEW
Component: Untriaged → Tabbed Browser
Ever confirmed: true
Keywords: ux-userfeedback
Whiteboard: [parity-Chrome][parity-Edge][parity-IE]
Version: 47 Branch → Trunk
Component: Tabbed Browser → Document Navigation
Product: Firefox → Core
Initially I thought this was a dupe of bug 668213 but now I think it might be a dupe of bug 321493. Do you think it's the same as either of those bugs?
Flags: needinfo?(xenos)
(In reply to Andrew Overholt [:overholt] from comment #3)
> Initially I thought this was a dupe of bug 668213 but now I think it might
> be a dupe of bug 321493. Do you think it's the same as either of those bugs?

No not a duplication.  They are different bug.
Attached file testcase
Oh, so you're saying the root problem here is that 'tab' (in your example) isn't focused upon subsequent link clicking? Sorry I was wrong on the dupes; I was thrown off by the anchors.
Flags: needinfo?(xenos) → needinfo?(alice0775)
(In reply to Andrew Overholt [:overholt] from comment #6)
> Oh, so you're saying the root problem here is that 'tab' (in your example)
> isn't focused upon subsequent link clicking? Sorry I was wrong on the dupes;
> I was thrown off by the anchors.

yep.
Flags: needinfo?(alice0775)
Yes, that's it: you're not lead to the other tab.

When the link points to another domain (like in attachment 8793635 [details]), then this issue is not very blocking: when you click a link for the 2nd time, you see that the tab is loading the new page, even if you're not lead to that new tab.

But when you have a fragment identifier in the link, then the tab won't show any loading sign and stays in the background: it very looks like the link is just "not working".

I believe that this is another consequence of the drastic fix for #310825
Samael, I am guessing that you might have some thoughts about this issue. Could you please take a look? Thanks!
Flags: needinfo?(sawang)
If I didn't misunderstand it, the first link click basically goes to openURIInFrame() [1], which honors the preference "browser.tabs.loadDivertedInBackground" to decide if it should focus on the newly opened tab; While in subsequent link clicks docshell should be able to find the target docshell directly and use targetDocShell->InternalLoad() to load the URI. Looks to me that in the second case it doesn't try to gain focus at all.

window.open() looks to have the similar execution path and has the same behavior. I expect if we change the behavior for <a href>, window.open() will also be changed.

I'm not quite familiar with HTML specs but my interpretation for window.open() [3] is that although it says the target browsing context should navigate to the given resource, it didn't define if the user agent should focus on the target browsering context.

Chrome / Safari / Opera do focus on the target browsering context. I can try to do the same thing on gecko. Do we need any UI / UX input for that before actually making the change?

[1] https://dxr.mozilla.org/mozilla-central/rev/b1d60f2f68c7cccc96fcf9a2075bb430a500a0f2/browser/base/content/browser.js#5030
[2] https://dxr.mozilla.org/mozilla-central/rev/b1d60f2f68c7cccc96fcf9a2075bb430a500a0f2/docshell/base/nsDocShell.cpp#10002-10022
[3] https://html.spec.whatwg.org/multipage/browsers.html#dom-open
Flags: needinfo?(sawang)
Assignee: nobody → sawang
Hi Mike,

I may start working on this recently, but I'm not familiar with mozilla's process on UX behavior change. Do you know if we need any kind of UX review?

And talking about the implementation, since the first link click (or window.open) would honor "browser.tabs.loadDivertedInBackground", I think we should make following link clicks or window.open follow the same preference. Does it sound reasonable?
Flags: needinfo?(mconley)
I suspect we'll want to converge with the other browsers and switch browser tabs in this case, especially since it's a user initiated action as opposed to script.

Let's ask phlsa from UX just in case, though.
Flags: needinfo?(mconley) → needinfo?(philipp)
Cool, thanks phlsa.

Got everything you need, freesamael?
Flags: needinfo?(sawang)
Yes that's all I need. Thanks.
Flags: needinfo?(sawang)
Attached patch v0 (obsolete) — Splinter Review
Merge "DOMServiceWorkerFocusClient" & "DOMWebNotificationClicked"
to "DOMWindowFocus" event. Utilize the event to switch tab when
loading links to an existing target tab.
Attached patch v1 (obsolete) — Splinter Review
Clean up
Attachment #8806263 - Attachment is obsolete: true
Comment on attachment 8806266 [details] [diff] [review]
v1

Hi Mike,

Would you help to review this patch?
Attachment #8806266 - Flags: review?(mconley)
Hi Catalin & Nikhil,

Just want to bring your attention that I'm merging "DOMServiceWorkerFocusClient" & "DOMWebNotificationClicked"
events since they have the same behavior currently. Kindly let me know if it doesn't sound correct.
Flags: needinfo?(nsm.nikhil)
Flags: needinfo?(catalin.badea392)
Looks good to me. Is this event also going to be used on Fennec?
Flags: needinfo?(nsm.nikhil)
Flags: needinfo?(catalin.badea392)
Comment on attachment 8806266 [details] [diff] [review]
v1

Review of attachment 8806266 [details] [diff] [review]:
-----------------------------------------------------------------

This looks mostly good - just some concerns about the tests, mostly; you should take advantage of add_task and BrowserTestUtils for readability.

I'm also not 100% sure if that's the right place in nsDocShell to put that sort of thing. It looks okay to me, but you might want smaug to double-check.

::: browser/base/content/content.js
@@ +621,5 @@
>  
>  // TODO: Load this lazily so the JSM is run only if a relevant event/message fires.
>  var pluginContent = new PluginContent(global);
>  
> +addEventListener("DOMWindowFocus", function(event) {

Can you double-check that custom events with this name fired from web content won't be handled?

::: browser/base/content/test/general/browser_bug1303838.js
@@ +1,2 @@
> +const BASE_URL = "http://example.com/browser/browser/base/content/test/general/";
> +

Please add a header docstring describing exactly what this test is testing.

@@ +2,5 @@
> +
> +add_task(function* test() {
> +  let tab = gBrowser.loadOneTab(BASE_URL + 'file_bug1303838.html', {inBackground: false});
> +  let testTab;
> +  return promiseTabLoaded(tab)

Instead of using .then(), you can take advantage of add_task and yield Promises, like:

let tab = gBrowser.loadOneTab(BASE_URL + 'file_bug1303838.html', {inBackground: false});
let testTab;
yield promiseTabLoaded(tab);
is(gBrowser.tabs.length, 2, "Check tabs.length");
is(gBrowser.selectedTab, tab, "Check selectedTab");

yield pushPrefs(['browser.tabs.loadDivertedInBackground', false]);

...etc

Don't forget to look at BrowserTestUtils for some handy utility functions for tests.

@@ +50,5 @@
> +  .then(() => gBrowser.removeTab(testTab))
> +  .then(() => gBrowser.removeTab(tab));
> +});
> +
> +function clickLink(linkId, tab, testTab)

I believe there's a utility function in BrowserTestUtils that you can use instead.

::: docshell/base/nsDocShell.cpp
@@ +10092,5 @@
>          //      do nothing.
>        }
> +
> +      // Switch to target tab if we're focused window, and the target is top
> +      // level. Take loadDivertedInBackground into acount so the behavior

Nit: "acount" -> "account"
Attachment #8806266 - Flags: review?(mconley)
Attachment #8806266 - Flags: review-
Attachment #8806266 - Flags: feedback+
Attached patch v2 (obsolete) — Splinter Review
Merge "DOMServiceWorkerFocusClient" & "DOMWebNotificationClicked"
to "DOMWindowFocus" event. Utilize the event to switch tab when
loading links to an existing target tab.

MozReview-Commit-ID: Hd1NkVkrJA1
Attachment #8806266 - Attachment description: Switch to existing target tab when clicking links → v1
Attachment #8806266 - Attachment is obsolete: true
Attachment #8806263 - Attachment description: Switch to existing target tab when clicking links → v0
Comment on attachment 8813153 [details] [diff] [review]
v2

Hi Mike,

Could you help to check the updated test case?

(In reply to Mike Conley (:mconley) from comment #21)
> > +addEventListener("DOMWindowFocus", function(event) {
> 
> Can you double-check that custom events with this name fired from web
> content won't be handled?

I only did manual test on that. The events generated from web content are untrusted events so won't be delivered to this event handler.
 
> > +function clickLink(linkId, tab, testTab)
> 
> I believe there's a utility function in BrowserTestUtils that you can use
> instead.

Changed to BrowserTestUtils.synthesizeMouse, but I still need to wait for tab loaded so I'm keep this function.
Attachment #8813153 - Flags: review?(mconley)
Comment on attachment 8813153 [details] [diff] [review]
v2

Hi Olli,

I'm trying to make not only the first click, but all consequent clicks to a link opening in an existing tab to honor the preference "browser.tabs.loadDivertedInBackground", and switch focus to the target tab if necessary. Does the docshell modification look correct to you?

(In reply to Mike Conley (:mconley) from comment #21)
> I'm also not 100% sure if that's the right place in nsDocShell to put that
> sort of thing. It looks okay to me, but you might want smaug to double-check.
Attachment #8813153 - Flags: superreview?(bugs)
Comment on attachment 8813153 [details] [diff] [review]
v2

>@@ -10107,16 +10107,27 @@ nsDocShell::InternalLoad(nsIURI* aURI,
>         // helper-app style protocol (ie. mailto://)
>         //
>         rv = NS_OK;
>       } else if (isNewWindow) {
>         // XXX: Once new windows are created hidden, the new
>         //      window will need to be made visible...  For now,
>         //      do nothing.
>       }
>+
>+      // Switch to target tab if we're focused window, and the target is top
>+      // level. Take loadDivertedInBackground into account so the behavior
>+      // would be the same as how the tab first opened.
>+      if (isTargetTopLevelDocShell && mIsActive &&
>+          !Preferences::GetBool("browser.tabs.loadDivertedInBackground", false)) {
>+        if (NS_FAILED(nsContentUtils::DispatchFocusChromeEvent(
>+            targetDocShell->GetWindow()))) {
>+          return NS_ERROR_FAILURE;
>+        }
>+      }
>     }
Why isTargetTopLevelDocShell only?  What do other browsers do there? And we clearly at least need a test for iframes.
Please add a test and test also what other browsers do and depending on that, change this code.
And please test also the case when we don't open new tabs but new windows (can't recall the pref name for that).
Attachment #8813153 - Flags: superreview?(bugs) → superreview-
Comment on attachment 8813153 [details] [diff] [review]
v2

As per comment 25, the code and test need be updated so cancel review request.
Attachment #8813153 - Flags: review?(mconley)
Attached patch v3 (obsolete) — Splinter Review
update
Attachment #8813153 - Attachment description: Switch to existing target tab when clicking links → v2
Attachment #8813153 - Attachment is obsolete: true
Attachment #8830185 - Attachment description: Switch to existing target tab when clicking links → v3
Attachment #8830185 - Attachment is obsolete: true
Attached patch v4 (obsolete) — Splinter Review
update
Comment on attachment 8830190 [details] [diff] [review]
v4

> What do other browsers do there?

The test case is updated with different types of links:
1. Link to load a page into the background tab.
2. Link to an anchor of the background tab.
3. Link to load a page into an iframe of the background tab.

With all 3 types of links, Chrome, Safari & Opera switch to the background tabs immediately after link clicked, and Chrome on Android has the same behavior as desktop. Edge doesn't switch at all, but it has a very good indicator - the updated tab's background flashes with orange color until user manually switches to the tab.

Would you take a look on the updated patch?
Attachment #8830190 - Flags: review?(bugs)
Attachment #8830190 - Flags: review?(bugs) → review+
Er, hmm, do we have tests when link clicking happens in iframe?
Flags: needinfo?(sawang)
(In reply to Olli Pettay [:smaug] from comment #30)
> Er, hmm, do we have tests when link clicking happens in iframe?

No. I can update the test. Do you want to make another review for that?
Flags: needinfo?(sawang)
rs+ for such change to the test.
Attached patch v5 (obsolete) — Splinter Review
Update the test case.
Attachment #8830190 - Attachment description: Switch to existing target tab when clicking links → v4
Attachment #8830190 - Attachment is obsolete: true
Attachment #8833911 - Attachment description: Switch to existing target tab when clicking links → Switch to existing target tab when clicking links. r=smaug
Attachment #8833911 - Flags: review+
Attached patch v6 (obsolete) — Splinter Review
Was encountering intermittent timeout. Thought somehow location change didn't occur but turns out it's the progress listener in the test script got free'd. There wasn't any strong ref to the listener when location change occured. Silly me.
Attachment #8833911 - Attachment description: Switch to existing target tab when clicking links. r=smaug → v5
Attachment #8833911 - Attachment is obsolete: true
Attachment #8848030 - Attachment description: Switch to existing target tab when clicking links → Switch to existing target tab when clicking links. r=smaug
Attachment #8848030 - Flags: review+
Pushed by cbook@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/20537ebcebdb
Switch to existing target tab when clicking links. r=smaug
Keywords: checkin-needed
Backout by cbook@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/0635931c726c
Backed out changeset 20537ebcebdb for eslint failure
Driveby because I looked at browser/base/content/test/general/browser.ini today: Please don't put new tests into the dumping ground that is browser/base/content/test/general/.

You probably want a more relevant directory, somewhere under docshell/ or dom/ .
Attachment #8848030 - Attachment description: Switch to existing target tab when clicking links. r=smaug → v6
Attachment #8848030 - Attachment is obsolete: true
Flags: needinfo?(sawang)
Attachment #8850419 - Attachment description: Switch to existing target tab when clicking links → Switch to existing target tab when clicking links. r=smaug
(In reply to :Gijs from comment #39)
> Driveby because I looked at browser/base/content/test/general/browser.ini
> today: Please don't put new tests into the dumping ground that is
> browser/base/content/test/general/.
> 
> You probably want a more relevant directory, somewhere under docshell/ or
> dom/ .

Thanks for your reminding. I often get confused about where I should put test cases.
Pushed by cbook@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/d47b335bd9a5
Switch to existing target tab when clicking links. r=smaug
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/d47b335bd9a5
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
Depends on: 1373604
Depends on: 1425988
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: