mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 699052 - Android back button should close the selected tab and return to the parent tab when possible [r=mfinkle]
This commit is contained in:
parent
efc97fe9ac
commit
c9a6ef2daf
@ -548,7 +548,7 @@ abstract public class GeckoApp
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Permissions:Get", null));
|
||||
return true;
|
||||
case R.id.addons:
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("about:addons"));
|
||||
loadUrlInNewTab("about:addons");
|
||||
return true;
|
||||
case R.id.agent_mode:
|
||||
Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
||||
@ -911,12 +911,10 @@ abstract public class GeckoApp
|
||||
doCameraCapture();
|
||||
} else if (event.equals("Tab:Added")) {
|
||||
Log.i(LOGTAG, "Created a new tab");
|
||||
int tabId = message.getInt("tabID");
|
||||
String uri = message.getString("uri");
|
||||
Tab tab = handleAddTab(message);
|
||||
Boolean selected = message.getBoolean("selected");
|
||||
handleAddTab(tabId, uri);
|
||||
if (selected)
|
||||
handleSelectTab(tabId);
|
||||
handleSelectTab(tab.getId());
|
||||
} else if (event.equals("Tab:Closed")) {
|
||||
Log.i(LOGTAG, "Destroyed a tab");
|
||||
int tabId = message.getInt("tabID");
|
||||
@ -1137,14 +1135,17 @@ abstract public class GeckoApp
|
||||
});
|
||||
}
|
||||
|
||||
void handleAddTab(final int tabId, final String uri) {
|
||||
final Tab tab = Tabs.getInstance().addTab(tabId, uri);
|
||||
Tab handleAddTab(JSONObject params) throws JSONException {
|
||||
Log.i(LOGTAG, params.toString());
|
||||
final Tab tab = Tabs.getInstance().addTab(params);
|
||||
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mBrowserToolbar.updateTabs(Tabs.getInstance().getCount());
|
||||
}
|
||||
});
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
void handleCloseTab(final int tabId) {
|
||||
@ -2008,10 +2009,31 @@ abstract public class GeckoApp
|
||||
return;
|
||||
}
|
||||
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
if (tab == null || !tab.doBack()) {
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
if (tab == null) {
|
||||
moveTaskToBack(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tab.doBack())
|
||||
return;
|
||||
|
||||
if (tab.isExternal()) {
|
||||
moveTaskToBack(true);
|
||||
tabs.closeTab(tab);
|
||||
return;
|
||||
}
|
||||
|
||||
int parentId = tab.getParentId();
|
||||
Tab parent = tabs.getTab(parentId);
|
||||
if (parent != null) {
|
||||
// The back button should always return to the parent (not a sibling).
|
||||
tabs.closeTab(tab, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
moveTaskToBack(true);
|
||||
}
|
||||
|
||||
static int kCaptureIndex = 0;
|
||||
@ -2128,6 +2150,22 @@ abstract public class GeckoApp
|
||||
loadRequest(url, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the link as a new tab, and mark the selected tab as its "parent".
|
||||
* Use this for tabs opened by the browser chrome, so users can press the
|
||||
* "Back" button to return to the previous tab.
|
||||
*/
|
||||
public void loadUrlInNewTab(String url) {
|
||||
JSONObject args = new JSONObject();
|
||||
try {
|
||||
args.put("url", url);
|
||||
args.put("parentId", Tabs.getInstance().getSelectedTabId());
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "error building JSON arguments");
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Add", args.toString()));
|
||||
}
|
||||
|
||||
public GeckoSoftwareLayerClient getSoftwareLayerClient() { return mSoftwareLayerClient; }
|
||||
public LayerController getLayerController() { return mLayerController; }
|
||||
|
||||
|
@ -55,7 +55,7 @@ class LinkPreference extends Preference {
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
GeckoApp.mAppContext.loadUrl(mUrl, AwesomeBar.Type.ADD);
|
||||
GeckoApp.mAppContext.loadUrlInNewTab(mUrl);
|
||||
callChangeListener(mUrl);
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ public class Tab {
|
||||
private Drawable mThumbnail;
|
||||
private List<HistoryEntry> mHistory;
|
||||
private int mHistoryIndex;
|
||||
private int mParentId;
|
||||
private boolean mExternal;
|
||||
private boolean mLoading;
|
||||
private boolean mBookmark;
|
||||
private HashMap<String, DoorHanger> mDoorHangers;
|
||||
@ -89,12 +91,14 @@ public class Tab {
|
||||
}
|
||||
|
||||
public Tab() {
|
||||
this(-1, "");
|
||||
this(-1, "", false, -1);
|
||||
}
|
||||
|
||||
public Tab(int id, String url) {
|
||||
public Tab(int id, String url, boolean external, int parentId) {
|
||||
mId = id;
|
||||
mUrl = url;
|
||||
mExternal = external;
|
||||
mParentId = parentId;
|
||||
mTitle = "";
|
||||
mFavicon = null;
|
||||
mFaviconUrl = null;
|
||||
@ -113,6 +117,10 @@ public class Tab {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public int getParentId() {
|
||||
return mParentId;
|
||||
}
|
||||
|
||||
public String getURL() {
|
||||
return mUrl;
|
||||
}
|
||||
@ -178,6 +186,10 @@ public class Tab {
|
||||
return mBookmark;
|
||||
}
|
||||
|
||||
public boolean isExternal() {
|
||||
return mExternal;
|
||||
}
|
||||
|
||||
public void updateURL(String url) {
|
||||
if (url != null && url.length() > 0) {
|
||||
mUrl = url;
|
||||
|
@ -44,6 +44,7 @@ import android.graphics.drawable.*;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class Tabs implements GeckoEventListener {
|
||||
private static final String LOGTAG = "GeckoTabs";
|
||||
@ -67,11 +68,16 @@ public class Tabs implements GeckoEventListener {
|
||||
return tabs.size();
|
||||
}
|
||||
|
||||
public Tab addTab(int id, String url) {
|
||||
public Tab addTab(JSONObject params) throws JSONException {
|
||||
int id = params.getInt("tabID");
|
||||
if (tabs.containsKey(id))
|
||||
return tabs.get(id);
|
||||
|
||||
Tab tab = new Tab(id, url);
|
||||
String url = params.getString("uri");
|
||||
Boolean external = params.getBoolean("external");
|
||||
int parentId = params.getInt("parentId");
|
||||
|
||||
Tab tab = new Tab(id, url, external, parentId);
|
||||
tabs.put(id, tab);
|
||||
order.add(tab);
|
||||
Log.i(LOGTAG, "Added a tab with id: " + id + ", url: " + url);
|
||||
@ -127,6 +133,42 @@ public class Tabs implements GeckoEventListener {
|
||||
return tabs.get(id);
|
||||
}
|
||||
|
||||
/** Close tab and then select the default next tab */
|
||||
public void closeTab(Tab tab) {
|
||||
closeTab(tab, getNextTab(tab));
|
||||
}
|
||||
|
||||
/** Close tab and then select nextTab */
|
||||
public void closeTab(Tab tab, Tab nextTab) {
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Select", String.valueOf(nextTab.getId())));
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Close", String.valueOf(tab.getId())));
|
||||
}
|
||||
|
||||
/** Return the tab that will be selected by default after this one is closed */
|
||||
public Tab getNextTab(Tab tab) {
|
||||
Tab selectedTab = getSelectedTab();
|
||||
if (selectedTab != tab)
|
||||
return selectedTab;
|
||||
|
||||
int index = getIndexOf(tab);
|
||||
Tab nextTab = getTabAt(index + 1);
|
||||
if (nextTab == null)
|
||||
nextTab = getTabAt(index - 1);
|
||||
|
||||
Tab parent = getTab(tab.getParentId());
|
||||
if (parent != null) {
|
||||
// If the next tab is a sibling, switch to it. Otherwise go back to the parent.
|
||||
if (nextTab != null && nextTab.getParentId() == tab.getParentId())
|
||||
return nextTab;
|
||||
else
|
||||
return parent;
|
||||
}
|
||||
return nextTab;
|
||||
}
|
||||
|
||||
public HashMap<Integer, Tab> getTabs() {
|
||||
if (getCount() == 0)
|
||||
return null;
|
||||
|
@ -180,23 +180,7 @@ public class TabsTray extends Activity implements GeckoApp.OnTabsChangedListener
|
||||
String tabId = v.getTag().toString();
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getTab(Integer.parseInt(tabId));
|
||||
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
if (tabs.isSelectedTab(tab)) {
|
||||
int index = tabs.getIndexOf(tab);
|
||||
if (index >= 1)
|
||||
index--;
|
||||
else
|
||||
index = 1;
|
||||
int id = tabs.getTabAt(index).getId();
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Select", String.valueOf(id)));
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Close", tabId));
|
||||
} else {
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Close", tabId));
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Select", String.valueOf(tabs.getSelectedTabId())));
|
||||
}
|
||||
tabs.closeTab(tab);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -582,22 +582,21 @@ var BrowserApp = {
|
||||
});
|
||||
},
|
||||
|
||||
getSearchOrFixupURI: function(aData) {
|
||||
let args = JSON.parse(aData);
|
||||
getSearchOrFixupURI: function(aParams) {
|
||||
let uri;
|
||||
if (args.engine) {
|
||||
if (aParams.engine) {
|
||||
let engine;
|
||||
if (args.engine == "__default__")
|
||||
if (aParams.engine == "__default__")
|
||||
engine = Services.search.currentEngine || Services.search.defaultEngine;
|
||||
else
|
||||
engine = Services.search.getEngineByName(args.engine);
|
||||
engine = Services.search.getEngineByName(aParams.engine);
|
||||
|
||||
if (engine)
|
||||
uri = engine.getSubmission(args.url).uri;
|
||||
uri = engine.getSubmission(aParams.url).uri;
|
||||
} else {
|
||||
uri = URIFixup.createFixupURI(args.url, Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
|
||||
uri = URIFixup.createFixupURI(aParams.url, Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
|
||||
}
|
||||
return uri ? uri.spec : args.url;
|
||||
return uri ? uri.spec : aParams.url;
|
||||
},
|
||||
|
||||
scrollToFocusedInput: function(aBrowser) {
|
||||
@ -629,14 +628,17 @@ var BrowserApp = {
|
||||
} else if (aTopic == "Session:Stop") {
|
||||
browser.stop();
|
||||
} else if (aTopic == "Tab:Add" || aTopic == "Tab:Load") {
|
||||
let data = JSON.parse(aData);
|
||||
|
||||
// Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
|
||||
// inheriting the currently loaded document's principal.
|
||||
let params = {
|
||||
selected: true,
|
||||
parentId: ("parentId" in data) ? data.parentId : -1,
|
||||
flags: Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER
|
||||
};
|
||||
|
||||
let url = this.getSearchOrFixupURI(aData);
|
||||
let url = this.getSearchOrFixupURI(data);
|
||||
if (aTopic == "Tab:Add")
|
||||
this.addTab(url, params);
|
||||
else
|
||||
@ -807,7 +809,7 @@ var NativeWindow = {
|
||||
this.linkContext,
|
||||
function(aTarget) {
|
||||
let url = NativeWindow.contextmenus._getLinkURL(aTarget);
|
||||
BrowserApp.addTab(url, { selected: false });
|
||||
BrowserApp.addTab(url, { selected: false, parentId: BrowserApp.selectedTab.id });
|
||||
});
|
||||
|
||||
this.add(Strings.browser.GetStringFromName("contextmenu.fullScreen"),
|
||||
@ -1020,9 +1022,18 @@ nsBrowserAccess.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
let newTab = (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW || aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB);
|
||||
|
||||
let parentId = -1;
|
||||
if (newTab && !isExternal) {
|
||||
let parent = BrowserApp.getTabForBrowser(BrowserApp.getBrowserForWindow(aOpener));
|
||||
if (parent)
|
||||
parentId = parent.id;
|
||||
}
|
||||
|
||||
let browser;
|
||||
if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW || aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
|
||||
let tab = BrowserApp.addTab("about:blank", { selected: true });
|
||||
if (newTab) {
|
||||
let tab = BrowserApp.addTab("about:blank", { external: isExternal, parentId: parentId, selected: true });
|
||||
browser = tab.browser;
|
||||
} else { // OPEN_CURRENTWINDOW and illegal values
|
||||
browser = BrowserApp.selectedBrowser;
|
||||
@ -1114,6 +1125,8 @@ Tab.prototype = {
|
||||
type: "Tab:Added",
|
||||
tabID: this.id,
|
||||
uri: aURL,
|
||||
parentId: ("parentId" in aParams) ? aParams.parentId : -1,
|
||||
external: ("external" in aParams) ? aParams.external : false,
|
||||
selected: ("selected" in aParams) ? aParams.selected : true
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user