Skip to content
This repository has been archived by the owner on Dec 15, 2018. It is now read-only.

Commit

Permalink
Bug 1210478 - Add Meta URL resolution in RemoteNewTabLocation
Browse files Browse the repository at this point in the history
  • Loading branch information
oyiptong committed Nov 4, 2015
1 parent 2c9cd95 commit b9c4590
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 15 deletions.
134 changes: 123 additions & 11 deletions browser/components/newtab/RemoteNewTabLocation.jsm
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
/* globals Services */
/* globals Services, UpdateUtils, XPCOMUtils, URL, NewTabPrefsProvider */
/* exported RemoteNewTabLocation */

"use strict";

this.EXPORTED_SYMBOLS = ["RemoteNewTabLocation"];

Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.importGlobalProperties(["URL"]);
const {interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.importGlobalProperties(["URL"]);

// TODO: will get dynamically set in bug 1210478
const DEFAULT_PAGE_LOCATION = "https://newtab.cdn.mozilla.net/v2/nightly/en-US/index.html";
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");

this.RemoteNewTabLocation = {
_url: new URL(DEFAULT_PAGE_LOCATION),
_overridden: false,
// The preference that tells whether to match the OS locale
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";

// The preference that tells what locale the user selected
const PREF_SELECTED_LOCALE = "general.useragent.locale";

const DEFAULT_PAGE_LOCATION = "https://newtab.cdn.mozilla.net/%VERSION%/%CHANNEL%/%LOCALE%/index.html";

const VALID_CHANNELS = new Set(["esr", "release", "beta", "aurora", "nightly"]);

const NEWTAB_VERSION = "0";

let RemoteLocationProvider = function() {
NewTabPrefsProvider.prefs.on(PREF_SELECTED_LOCALE, this.updateMaybe.bind(this));
NewTabPrefsProvider.prefs.on(PREF_MATCH_OS_LOCALE, this.updateMaybe.bind(this));
this._url = this.generateDefaultURL();
this._overridden = false;
};

RemoteLocationProvider.prototype = {
get href() {
return this._url.href;
},
Expand All @@ -26,17 +47,108 @@ this.RemoteNewTabLocation = {
return this._overridden;
},

override: function(newURL) {
/**
* Gets the currently selected locale
*
* @return {String} the selected locale or "en-US" if none is selected
*/
get locale() {
let result = "en-US";
let matchOS;

try {
matchOS = Services.prefs.getBoolPref(PREF_MATCH_OS_LOCALE);
}
catch (e) {}

if (matchOS) {
result = Services.locale.getLocaleComponentForUserAgent();
}

try {
let locale = Services.prefs.getComplexValue(PREF_SELECTED_LOCALE,
Ci.nsIPrefLocalizedString);
if (locale) {
result = locale.data;
}
}
catch (e) {}

try {
result = Services.prefs.getCharPref(PREF_SELECTED_LOCALE);
}
catch (e) {}

return result;
},

get version() {
return NEWTAB_VERSION;
},

get channels() {
return VALID_CHANNELS;
},

/**
* Returns the release name from an Update Channel name
*
* @return {String} a release name based on the update channel. Defaults to nightly
*/
releaseFromUpdateChannel(channel) {
let result = "nightly";
if (VALID_CHANNELS.has(channel)) {
result = channel;
}
return result;
},

/*
* Updates the location when the page is not overriden.
* Useful when there is a pref change
*/
updateMaybe() {
if (!this.overridden) {
let url = this.generateDefaultURL();
if (url !== this._url) {
this._url = url;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
}
}
},

/*
* Generate a default url based on locale and update channel
*/
generateDefaultURL() {
let releaseName = this.releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
let uri = DEFAULT_PAGE_LOCATION
.replace("%VERSION%", NEWTAB_VERSION)
.replace("%LOCALE%", this.locale)
.replace("%CHANNEL%", releaseName);
return new URL(uri);
},

/*
* Override the Remote newtab page location.
*/
override(newURL) {
this._url = new URL(newURL);
this._overridden = true;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
},

reset: function() {
this._url = new URL(DEFAULT_PAGE_LOCATION);
/*
* Reset the newtab page location to the default value
*/
reset() {
this._url = this.generateDefaultURL();
this._overridden = false;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
}
};

let RemoteNewTabLocation = new RemoteLocationProvider();
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
/* globals ok, equal, RemoteNewTabLocation, Services */
/* globals ok, equal, RemoteNewTabLocation, NewTabPrefsProvider, Services */
"use strict";

Components.utils.import("resource:///modules/RemoteNewTabLocation.jsm");
Components.utils.import("resource:///modules/NewTabPrefsProvider.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.importGlobalProperties(["URL"]);

add_task(function* () {
var notificationPromise;
let defaultHref = RemoteNewTabLocation.href;
const defaultHref = RemoteNewTabLocation.href;

add_task(function *test_defaults() {

ok(RemoteNewTabLocation.href, "Default location has an href");
ok(RemoteNewTabLocation.origin, "Default location has an origin");
ok(!RemoteNewTabLocation.overridden, "Default location is not overridden");

});

add_task(function *test_overrides() {
let testURL = new URL("https://example.com/");
let notificationPromise;

notificationPromise = changeNotificationPromise(testURL.href);
RemoteNewTabLocation.override(testURL.href);
Expand All @@ -29,6 +34,41 @@ add_task(function* () {
equal(RemoteNewTabLocation.href, defaultHref, "Remote href should be reset");
});

add_task(function *test_updates() {
let notificationPromise;
Services.prefs.setBoolPref("intl.locale.matchOS", false);
NewTabPrefsProvider.prefs.startTracking();

notificationPromise = changeNotificationPromise(defaultHref);
Services.prefs.setBoolPref("intl.locale.matchOS", true);
yield notificationPromise;
equal(RemoteNewTabLocation.href, defaultHref, "Remote href should be updated");

let testURL = new URL("https://example.com/");
RemoteNewTabLocation.override(testURL.href);
notificationPromise = changeNotificationPromise(defaultHref);
Services.prefs.setBoolPref("intl.locale.matchOS", false);
equal(RemoteNewTabLocation.href, testURL.href, "Remote href should not update when overridden");
RemoteNewTabLocation.reset();
yield notificationPromise;
equal(RemoteNewTabLocation.href, defaultHref, "href updates on reset, not on override");

NewTabPrefsProvider.prefs.stopTracking();
});

add_task(function *test_release_names() {
let valid_channels = RemoteNewTabLocation.channels;
let invalid_channels = new Set(["default", "invalid"]);

for (let channel of valid_channels) {
equal(channel, RemoteNewTabLocation.releaseFromUpdateChannel(channel), "release == channel name when valid");
}

for (let channel of invalid_channels) {
equal("nightly", RemoteNewTabLocation.releaseFromUpdateChannel(channel), "release == nightly when invalid");
}
});

function changeNotificationPromise(aNewURL) {
return new Promise(resolve => {
Services.obs.addObserver(function observer(aSubject, aTopic, aData) { // jshint ignore:line
Expand Down

0 comments on commit b9c4590

Please sign in to comment.