Closed Bug 1270782 Opened 8 years ago Closed 7 years ago

Add ability to provide custom "back" and "forward"

Categories

(WebExtensions :: Untriaged, defect)

defect
Not set
normal

Tracking

(firefox49 affected)

RESOLVED WONTFIX
Tracking Status
firefox49 --- affected

People

(Reporter: yuki, Unassigned)

References

Details

(Whiteboard: [design-decision-denied] triaged)

This is a request for new API.

My XUL-based addon "Back to Owner Tab" provides ability to switch back to the "parent" tab, when the "back" button has no more back-history for the current tab. Moreover, "Forward" button will focus to the most recent visited "child" tab, if there is no more foward-history for the current tab.

https://addons.mozilla.org/firefox/addon/back-to-owner-tab/

To migrate the addon or implement new addon like it, we need something new API to override functionality of "Back" and "Foward" buttons with custom actions.

The purpose of the existing `chrome.webNavigation.onBeforeNavigate` ( https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/WebNavigation/onBeforeNavigate ) seems different to this request. `chrome.webNavigation.onBeforeNavigate` doesn't work for "no more back-history" cases, because the button is grayed out by Firefox. The API I suggested provides ability to turn the "Back" button activated and provide custom feature for the time.
(Or, this functionality will possibly extended features of `chrome.webNavigation.onBeforeNavigate`.)
Moreover, the added action should appear as the previous item of the first history (for "Back" button) or the next item of the last history (for "Forward" button) in the right-click menu on navigation buttons (and the "History" menu).
Whiteboard: [design-decision-needed] triaged
Bug 1252272 is about being able to use WebExtension APIs in SDK or other add-ons and the technical workings of making that happen, rather than new APIs.
No longer blocks: 1252272
It seems like there would be multiple changes here:

* extend the features of chrome.webNavigation.onBeforeNavigate to include something that fires before the back button is triggered

* create a way to manipulate the history of that tab, I don't think history applies to a tab and hence the back/forwards actions

* (and most controversially) allow the above methods to block the UI, something I'm really not happy about
I got an advice that the feature can be done by a fake history entry (history.pushState), so I'm planning to try it. If it couldn't be done, I'll add a comment here.
Flags: needinfo?(yuki)
I've tested the history.popState() and related APIs and I've realized that it solves my issue only partially. Here is a sample code I've tested:

~~~
// Run this in the browser console, without e10s. When you run
// this code in a new tab, the "Back" button goes to the previous
// (left) tab if you cannot go back anymore. The "Forward" button
// goes to the next (right) tab if you cannot go forward anymore.

var BACK_TO_PREVIOUS_TAB_STATE = '_moz-back-to-previous-tab';
var FORWARD_TO_NEXT_TAB_STATE = '_moz-forward-to-next-tab';

var uri = content.location.href;
var prevTab = gBrowser.selectedTab.previousSibling;
var nextTab = gBrowser.selectedTab.nextSibling;

content.history.replaceState(BACK_TO_PREVIOUS_TAB_STATE, 'Previous Tab', '');
content.history.pushState(null, null, uri);
content.history.pushState(FORWARD_TO_NEXT_TAB_STATE, 'Next Tab', '');
content.history.back();

content.addEventListener('popstate', function(aEvent) {
  switch (aEvent.state) {
    case BACK_TO_PREVIOUS_TAB_STATE:
      content.history.forward();
      // This code touches to the gBrowser directly for now, but
      // WebExtensions addon will just send a message triggering
      // "back to previous tab" operation, to the background script
      // or someone.
      gBrowser.selectedTab = prevTab;
      break;
    case FORWARD_TO_NEXT_TAB_STATE:
      content.history.back();
      gBrowser.selectedTab = nextTab;
      break;
  }
});
~~~

Some problems are still there:

 * When I click a link in the tab, the "FORWARD_TO_NEXT_TAB_STATE" state will be lost.
   Of course, after the page is successfully transitioned, I can do `history.pushState()' again
   to re-register the "FORWARD_TO_NEXT_TAB_STATE" state again. However, `history` just provides a
   property to count the total number of history entries but there is no property to tell the
   index of the current history entry. As the result, I cannot know when I should re-register the
   "FORWARD_TO_NEXT_TAB_STATE" state again.
 * The event listener for the "popstate" event must be registered for all each history entry
   if the tab has multiple entries in its session history.
 * I don't know the hack can work with scripts of the website itself. I think the custom event
   listener registered by my addon may conflict to the one registered by the website.
 * There is no way to remove fake history entries created by the addon, when the addon is
   disabled or uninstalled. Then avoided history entries will be left.
Flags: needinfo?(yuki)
Some of problems I figured out at https://bugzilla.mozilla.org/show_bug.cgi?id=1270782#c5 seem to be solved by adding new features like history.pushState/replaceState, to the chrome.webNavigation or something.

https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webNavigation

Because the history.pushState and related APIs are mainly designed for webpage scripts, they are not enough useful for long-live, cross-page scripts like addons. Instead, if WebExtensions provides similar features, I don't need to hack the "Back" and "Foward" buttons themselves.
Then the better summary may be: Add features to operate session history entries like history.pushState.
Just want to add a note that https://addons.mozilla.org/en-US/firefox/addon/backtrack-tab-history/ would also require the ability to customise back and forwards in order to be ported to WebExtensions. However, session history manipulation alone would not be sufficient, it would also need to modify the popup menus themselves.

I rather suspect that's out of scope for WebExtensions, but this seemed like the right place to mention it.
To be discussed at January 24 WebExtensions Triage meeting. 

Agenda: https://docs.google.com/document/d/1add-6FL8mzksvzbyB83HUmEkVmKERd-nt740AYr-4PE/edit#
Flags: needinfo?(amckay)
After chatting about this in the meeting we decided this would not be a good idea. Being able to manipulate history.pushState will allow some of these use cases. But large concern about:

* changing built in navigation without that being obvious to a user
* the performance concerns of an extension taking the time to respond
* the value of the use cases and the code we'd have to maintain.

...meant that we don't think this is a good idea.
Status: NEW → RESOLVED
Closed: 7 years ago
Flags: needinfo?(amckay)
Resolution: --- → WONTFIX
Whiteboard: [design-decision-needed] triaged → [design-decision-denied] triaged
Product: Toolkit → WebExtensions
You need to log in before you can comment on or make changes to this bug.