Bug 768035 - Implement SiteSpecificUserAgent for Fennec. r=bnicholson

This commit is contained in:
Wes Johnston 2013-02-28 14:02:21 -08:00
Родитель 0dec93958f
Коммит 3807195da3
5 изменённых файлов: 81 добавлений и 32 удалений

Просмотреть файл

@ -30,6 +30,9 @@ XPCOMUtils.defineLazyGetter(this, "DebuggerServer", function() {
return DebuggerServer;
});
XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides",
"resource://gre/modules/UserAgentOverrides.jsm");
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
Cu.import("resource://gre/modules/NetUtil.jsm");
return NetUtil;
@ -2590,7 +2593,8 @@ var UserAgent = {
init: function ua_init() {
Services.obs.addObserver(this, "DesktopMode:Change", false);
Services.obs.addObserver(this, "http-on-modify-request", false);
UserAgentOverrides.init();
UserAgentOverrides.addComplexOverride(this.onRequest.bind(this));
// See https://developer.mozilla.org/en/Gecko_user_agent_string_reference
this.DESKTOP_UA = Cc["@mozilla.org/network/protocol;1?name=http"]
@ -2601,7 +2605,39 @@ var UserAgent = {
uninit: function ua_uninit() {
Services.obs.removeObserver(this, "DesktopMode:Change");
Services.obs.removeObserver(this, "http-on-modify-request");
UserAgentOverrides.uninit();
},
onRequest: function(channel, defaultUA) {
let channelWindow = this._getWindowForRequest(channel);
let tab = BrowserApp.getTabForWindow(channelWindow);
if (tab == null)
return;
let ua = this.getUserAgentForUriAndTab(channel.URI, tab, defaultUA);
if (ua)
channel.setRequestHeader("User-Agent", ua, false);
},
getUserAgentForWindow: function ua_getUserAgentForWindow(aWindow, defaultUA) {
let tab = BrowserApp.getTabForWindow(aWindow.top);
if (tab)
return this.getUserAgentForUriAndTab(tab.browser.currentURI, tab, defaultUA);
return defaultUA;
},
getUserAgentForUriAndTab: function ua_getUserAgentForUriAndTab(aUri, aTab, defaultUA) {
if (this.YOUTUBE_DOMAIN.test(aUri.host)) {
// Send the phone UA to youtube if this is a tablet
if (defaultUA.indexOf("Android; Mobile;") === -1)
return defaultUA.replace("Android;", "Android; Mobile;");
}
// Send desktop UA if "Request Desktop Site" is enabled
if (aTab.desktopMode)
return this.DESKTOP_UA;
return defaultUA;
},
_getRequestLoadContext: function ua_getRequestLoadContext(aRequest) {
@ -2628,36 +2664,11 @@ var UserAgent = {
},
observe: function ua_observe(aSubject, aTopic, aData) {
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;
if (this.YOUTUBE_DOMAIN.test(channel.URI.host)) {
let ua = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent;
// Send the phone UA to youtube if this is a tablet
if (ua.indexOf("Android; Mobile;") === -1) {
ua = ua.replace("Android;", "Android; Mobile;");
channel.setRequestHeader("User-Agent", ua, false);
}
}
// Send desktop UA if "Request Desktop Site" is enabled
if (tab.desktopMode)
channel.setRequestHeader("User-Agent", this.DESKTOP_UA, false);
break;
}
if (aTopic === "DesktopMode:Change") {
let args = JSON.parse(aData);
let tab = BrowserApp.getTabForId(args.tabId);
if (tab != null)
tab.reloadWithMode(args.desktopMode);
}
}
};

Просмотреть файл

@ -38,6 +38,7 @@ EXTRA_COMPONENTS = \
LoginManagerPrompter.js \
BlocklistPrompt.js \
NSSDialogService.js \
SiteSpecificUserAgent.js \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -93,3 +93,7 @@ contract @mozilla.org/addons/blocklist-prompt;1 {4e6ea350-b09a-11df-94e2-0800200
# NSSDialogService.js
component {cbc08081-49b6-4561-9c18-a7707a50bda1} NSSDialogService.js
contract @mozilla.org/nsCertificateDialogs;1 {cbc08081-49b6-4561-9c18-a7707a50bda1}
# SiteSpecificUserAgent.js
component {d5234c9d-0ee2-4b3c-9da3-18be9e5cf7e6} SiteSpecificUserAgent.js
contract @mozilla.org/dom/site-specific-user-agent;1 {d5234c9d-0ee2-4b3c-9da3-18be9e5cf7e6}

Просмотреть файл

@ -0,0 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/UserAgentOverrides.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const DEFAULT_UA = Cc["@mozilla.org/network/protocol;1?name=http"]
.getService(Ci.nsIHttpProtocolHandler)
.userAgent;
function SiteSpecificUserAgent() {}
SiteSpecificUserAgent.prototype = {
getUserAgentForURIAndWindow: function ssua_getUserAgentForURIAndWindow(aURI, aWindow) {
let win = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getMostRecentWindow("navigator:browser");
if (win && win.UserAgent) {
return win.UserAgent.getUserAgentForWindow(aWindow, DEFAULT_UA);
}
return DEFAULT_UA;
},
classID: Components.ID("{d5234c9d-0ee2-4b3c-9da3-18be9e5cf7e6}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsISiteSpecificUserAgent])
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SiteSpecificUserAgent]);

Просмотреть файл

@ -554,6 +554,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/components/PromptService.js
@BINPATH@/components/SessionStore.js
@BINPATH@/components/Sidebar.js
@BINPATH@/components/SiteSpecificUserAgent.js
#ifdef MOZ_SAFE_BROWSING
@BINPATH@/components/SafeBrowsing.jsm
#endif