зеркало из https://github.com/mozilla/gecko-dev.git
Bug 766406 - Implement "Request Desktop Site". r=mfinkle
This commit is contained in:
Родитель
3de1510717
Коммит
d719f7187f
|
@ -574,6 +574,7 @@ abstract public class BrowserApp extends GeckoApp
|
|||
MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf);
|
||||
MenuItem charEncoding = aMenu.findItem(R.id.char_encoding);
|
||||
MenuItem findInPage = aMenu.findItem(R.id.find_in_page);
|
||||
MenuItem desktopMode = aMenu.findItem(R.id.desktop_mode);
|
||||
|
||||
if (tab == null || tab.getURL() == null) {
|
||||
bookmark.setEnabled(false);
|
||||
|
@ -608,6 +609,7 @@ abstract public class BrowserApp extends GeckoApp
|
|||
}
|
||||
|
||||
forward.setEnabled(tab.canDoForward());
|
||||
desktopMode.setChecked(tab.getDesktopMode());
|
||||
|
||||
// Disable share menuitem for about:, chrome:, file:, and resource: URIs
|
||||
String scheme = Uri.parse(tab.getURL()).getScheme();
|
||||
|
|
|
@ -698,6 +698,19 @@ abstract public class GeckoApp
|
|||
case R.id.find_in_page:
|
||||
mFindInPageBar.show();
|
||||
return true;
|
||||
case R.id.desktop_mode:
|
||||
Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
||||
if (selectedTab == null)
|
||||
return true;
|
||||
JSONObject args = new JSONObject();
|
||||
try {
|
||||
args.put("desktopMode", !item.isChecked());
|
||||
args.put("tabId", selectedTab.getId());
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "error building json arguments");
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("DesktopMode:Change", args.toString()));
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
@ -1215,6 +1228,20 @@ abstract public class GeckoApp
|
|||
} else if (event.equals("WebApps:Uninstall")) {
|
||||
String uniqueURI = message.getString("uniqueURI");
|
||||
GeckoAppShell.uninstallWebApp(uniqueURI);
|
||||
} else if (event.equals("DesktopMode:Changed")) {
|
||||
int tabId = message.getInt("tabId");
|
||||
boolean desktopMode = message.getBoolean("desktopMode");
|
||||
final Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
tab.setDesktopMode(desktopMode);
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
if (tab == Tabs.getInstance().getSelectedTab())
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
||||
|
@ -1890,6 +1917,7 @@ abstract public class GeckoApp
|
|||
GeckoAppShell.registerGeckoEventListener("WebApps:Open", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("WebApps:Install", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("WebApps:Uninstall", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("DesktopMode:Changed", GeckoApp.mAppContext);
|
||||
|
||||
if (SmsManager.getInstance() != null) {
|
||||
SmsManager.getInstance().start();
|
||||
|
@ -2232,6 +2260,7 @@ abstract public class GeckoApp
|
|||
GeckoAppShell.unregisterGeckoEventListener("WebApps:Open", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("WebApps:Install", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("WebApps:Uninstall", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("DesktopMode:Changed", GeckoApp.mAppContext);
|
||||
|
||||
if (mFavicons != null)
|
||||
mFavicons.close();
|
||||
|
|
|
@ -69,6 +69,7 @@ public final class Tab {
|
|||
private int mState;
|
||||
private ByteBuffer mThumbnailBuffer;
|
||||
private Bitmap mThumbnailBitmap;
|
||||
private boolean mDesktopMode;
|
||||
|
||||
public static final int STATE_DELAYED = 0;
|
||||
public static final int STATE_LOADING = 1;
|
||||
|
@ -661,4 +662,12 @@ public final class Tab {
|
|||
int b = Integer.parseInt(matcher.group(3));
|
||||
return Color.rgb(r, g, b);
|
||||
}
|
||||
|
||||
public void setDesktopMode(boolean enabled) {
|
||||
mDesktopMode = enabled;
|
||||
}
|
||||
|
||||
public boolean getDesktopMode() {
|
||||
return mDesktopMode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<!ENTITY share_title "Share via">
|
||||
<!ENTITY save_as_pdf "Save as PDF">
|
||||
<!ENTITY find_in_page "Find in Page">
|
||||
<!ENTITY desktop_mode "Request Desktop Site">
|
||||
|
||||
<!-- Localization note (find_text, find_prev, find_next, find_close) : These strings are used
|
||||
as alternate text for accessibility. They are not visible in the UI. -->
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
<item gecko:id="@+id/find_in_page"
|
||||
gecko:title="@string/find_in_page" />
|
||||
|
||||
<item gecko:id="@+id/desktop_mode"
|
||||
gecko:title="@string/desktop_mode"
|
||||
gecko:checkable="true" />
|
||||
|
||||
<item gecko:id="@+id/site_settings"
|
||||
gecko:icon="@drawable/ic_menu_clear_site_settings"
|
||||
gecko:title="@string/site_settings_title" />
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
<item gecko:id="@+id/find_in_page"
|
||||
gecko:title="@string/find_in_page" />
|
||||
|
||||
<item gecko:id="@+id/desktop_mode"
|
||||
gecko:title="@string/desktop_mode"
|
||||
gecko:checkable="true" />
|
||||
|
||||
<item gecko:id="@+id/site_settings"
|
||||
gecko:icon="@drawable/ic_menu_clear_site_settings"
|
||||
gecko:title="@string/site_settings_title" />
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
<item gecko:id="@+id/find_in_page"
|
||||
gecko:title="@string/find_in_page" />
|
||||
|
||||
<item gecko:id="@+id/desktop_mode"
|
||||
gecko:title="@string/desktop_mode"
|
||||
gecko:checkable="true" />
|
||||
|
||||
<item gecko:id="@+id/site_settings"
|
||||
gecko:icon="@drawable/ic_menu_clear_site_settings"
|
||||
gecko:title="@string/site_settings_title" />
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
<item android:id="@+id/find_in_page"
|
||||
android:title="@string/find_in_page" />
|
||||
|
||||
<item android:id="@+id/desktop_mode"
|
||||
android:title="@string/desktop_mode"
|
||||
android:checkable="true" />
|
||||
|
||||
<item android:id="@+id/site_settings"
|
||||
android:title="@string/site_settings_title" />
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<string name="share_title">&share_title;</string>
|
||||
<string name="save_as_pdf">&save_as_pdf;</string>
|
||||
<string name="find_in_page">&find_in_page;</string>
|
||||
<string name="desktop_mode">&desktop_mode;</string>
|
||||
|
||||
<string name="find_text">&find_text;</string>
|
||||
<string name="find_prev">&find_prev;</string>
|
||||
|
|
|
@ -1729,15 +1729,25 @@ var SelectionHandler = {
|
|||
|
||||
|
||||
var UserAgent = {
|
||||
DESKTOP_UA: null,
|
||||
|
||||
init: function ua_init() {
|
||||
Services.obs.addObserver(this, "DesktopMode:Change", false);
|
||||
Services.obs.addObserver(this, "http-on-modify-request", false);
|
||||
|
||||
// See https://developer.mozilla.org/en/Gecko_user_agent_string_reference
|
||||
this.DESKTOP_UA = Cc["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Ci.nsIHttpProtocolHandler).userAgent
|
||||
.replace(/Android; [a-zA-Z]+/, "X11; Linux x86_64")
|
||||
.replace(/Gecko\/[0-9\.]+/, "Gecko/20100101");
|
||||
},
|
||||
|
||||
uninit: function ua_uninit() {
|
||||
Services.obs.removeObserver(this, "DesktopMode:Change");
|
||||
Services.obs.removeObserver(this, "http-on-modify-request");
|
||||
},
|
||||
|
||||
getRequestLoadContext: function ua_getRequestLoadContext(aRequest) {
|
||||
_getRequestLoadContext: function ua_getRequestLoadContext(aRequest) {
|
||||
if (aRequest && aRequest.notificationCallbacks) {
|
||||
try {
|
||||
return aRequest.notificationCallbacks.getInterface(Ci.nsILoadContext);
|
||||
|
@ -1753,25 +1763,42 @@ var UserAgent = {
|
|||
return null;
|
||||
},
|
||||
|
||||
getWindowForRequest: function ua_getWindowForRequest(aRequest) {
|
||||
let loadContext = this.getRequestLoadContext(aRequest);
|
||||
_getWindowForRequest: function ua_getWindowForRequest(aRequest) {
|
||||
let loadContext = this._getRequestLoadContext(aRequest);
|
||||
if (loadContext)
|
||||
return loadContext.associatedWindow;
|
||||
return null;
|
||||
},
|
||||
|
||||
observe: function ua_observe(aSubject, aTopic, aData) {
|
||||
if (!(aSubject instanceof Ci.nsIHttpChannel))
|
||||
return;
|
||||
switch (aTopic) {
|
||||
case "DesktopMode:Change": {
|
||||
let args = JSON.parse(aData);
|
||||
let tab = BrowserApp.getTabForId(args.tabId);
|
||||
if (tab != null)
|
||||
tab.reloadWithMode(args.desktopMode);
|
||||
break;
|
||||
}
|
||||
case "http-on-modify-request": {
|
||||
let channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
|
||||
let channelWindow = this._getWindowForRequest(channel);
|
||||
let tab = BrowserApp.getTabForWindow(channelWindow);
|
||||
if (tab == null)
|
||||
break;
|
||||
|
||||
let channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
|
||||
let channelWindow = this.getWindowForRequest(channel);
|
||||
if (BrowserApp.getBrowserForWindow(channelWindow)) {
|
||||
if (channel.URI.host.indexOf("youtube") != -1) {
|
||||
let ua = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent;
|
||||
// Send XUL UA to YouTube; temporary hack to make videos play
|
||||
if (channel.URI.host.indexOf("youtube") != -1) {
|
||||
let ua = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent;
|
||||
#expand let version = "__MOZ_APP_VERSION__";
|
||||
ua += " Fennec/" + version;
|
||||
channel.setRequestHeader("User-Agent", ua, false);
|
||||
ua += " Fennec/" + version;
|
||||
channel.setRequestHeader("User-Agent", ua, false);
|
||||
}
|
||||
|
||||
// Send desktop UA if "Request Desktop Site" is enabled
|
||||
if (tab.desktopMode && (channel.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI))
|
||||
channel.setRequestHeader("User-Agent", this.DESKTOP_UA, false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1895,6 +1922,8 @@ function Tab(aURL, aParams) {
|
|||
this.pluginDoorhangerTimeout = null;
|
||||
this.shouldShowPluginDoorhanger = true;
|
||||
this.clickToPlayPluginsActivated = false;
|
||||
this.desktopMode = false;
|
||||
this.originalURI = null;
|
||||
}
|
||||
|
||||
Tab.prototype = {
|
||||
|
@ -1987,6 +2016,53 @@ Tab.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reloads the tab with the desktop mode setting.
|
||||
*/
|
||||
reloadWithMode: function (aDesktopMode) {
|
||||
// Set desktop mode for tab and send change to Java
|
||||
if (this.desktopMode != aDesktopMode) {
|
||||
this.desktopMode = aDesktopMode;
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "DesktopMode:Changed",
|
||||
desktopMode: aDesktopMode,
|
||||
tabId: this.id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Only reload the page for http/https schemes
|
||||
let currentURI = this.browser.currentURI;
|
||||
if (!currentURI.schemeIs("http") && !currentURI.schemeIs("https"))
|
||||
return;
|
||||
|
||||
let url = currentURI.spec;
|
||||
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
|
||||
if (this.originalURI && !this.originalURI.equals(currentURI)) {
|
||||
// We were redirected; reload the original URL
|
||||
url = this.originalURI.spec;
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
|
||||
} else {
|
||||
// Many sites use mobile-specific URLs, such as:
|
||||
// http://m.yahoo.com
|
||||
// http://www.google.com/m
|
||||
// If the user clicks "Request Desktop Site" while on a mobile site, it
|
||||
// will appear to do nothing since the mobile URL is still being
|
||||
// requested. To address this, we do the following:
|
||||
// 1) Remove the path from the URL (http://www.google.com/m?q=query -> http://www.google.com)
|
||||
// 2) If a host subdomain is "m", remove it (http://en.m.wikipedia.org -> http://en.wikipedia.org)
|
||||
// This means the user is sent to site's home page, but this is better
|
||||
// than the setting having no effect at all.
|
||||
if (aDesktopMode)
|
||||
url = currentURI.prePath.replace(/([\/\.])m\./g, "$1");
|
||||
else
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
|
||||
}
|
||||
|
||||
this.browser.docShell.loadURI(url, flags, null, null, null);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (!this.browser)
|
||||
return;
|
||||
|
@ -2590,7 +2666,11 @@ Tab.prototype = {
|
|||
let success = false;
|
||||
let uri = "";
|
||||
try {
|
||||
uri = aRequest.QueryInterface(Components.interfaces.nsIChannel).originalURI.spec;
|
||||
// Remember original URI for UA changes on redirected pages
|
||||
this.originalURI = aRequest.QueryInterface(Components.interfaces.nsIChannel).originalURI;
|
||||
|
||||
if (this.originalURI != null)
|
||||
uri = this.originalURI.spec;
|
||||
} catch (e) { }
|
||||
try {
|
||||
success = aRequest.QueryInterface(Components.interfaces.nsIHttpChannel).requestSucceeded;
|
||||
|
|
Загрузка…
Ссылка в новой задаче