mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
f727e9c4ef
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "33a8ca00e3128502d0c4c834236be335c0060f43",
|
||||
"revision": "cd1a16d6212a1867ecf1d1cfcd62f80abf9ae0b1",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -137,7 +137,7 @@ var MigrationWizard = {
|
||||
if (sourceProfiles && sourceProfiles.length == 1)
|
||||
this._selectedProfile = sourceProfiles[0];
|
||||
else
|
||||
this._selectedProfile = "";
|
||||
this._selectedProfile = null;
|
||||
}
|
||||
},
|
||||
|
||||
@ -157,27 +157,32 @@ var MigrationWizard = {
|
||||
// and we canceled the dialog. When that happens, _migrator will be null.
|
||||
if (this._migrator) {
|
||||
var sourceProfiles = this._migrator.sourceProfiles;
|
||||
for (var i = 0; i < sourceProfiles.length; ++i) {
|
||||
|
||||
for (let profile of sourceProfiles) {
|
||||
var item = document.createElement("radio");
|
||||
item.id = sourceProfiles[i];
|
||||
item.setAttribute("label", sourceProfiles[i]);
|
||||
item.id = profile.id;
|
||||
item.setAttribute("label", profile.name);
|
||||
profiles.appendChild(item);
|
||||
}
|
||||
}
|
||||
|
||||
profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile) : profiles.firstChild;
|
||||
profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile.id) : profiles.firstChild;
|
||||
},
|
||||
|
||||
onSelectProfilePageRewound: function ()
|
||||
{
|
||||
var profiles = document.getElementById("profiles");
|
||||
this._selectedProfile = profiles.selectedItem.id;
|
||||
this._selectedProfile = this._migrator.sourceProfiles.find(
|
||||
profile => profile.id == profiles.selectedItem.id
|
||||
) || null;
|
||||
},
|
||||
|
||||
onSelectProfilePageAdvanced: function ()
|
||||
{
|
||||
var profiles = document.getElementById("profiles");
|
||||
this._selectedProfile = profiles.selectedItem.id;
|
||||
this._selectedProfile = this._migrator.sourceProfiles.find(
|
||||
profile => profile.id == profiles.selectedItem.id
|
||||
) || null;
|
||||
|
||||
// If we're automigrating or just doing bookmarks don't show the item selection page
|
||||
if (this._autoMigrate)
|
||||
|
@ -8,7 +8,7 @@
|
||||
interface nsIArray;
|
||||
interface nsIProfileStartup;
|
||||
|
||||
[scriptable, uuid(44993E0E-74E8-4BEC-9D66-AD8156E0A274)]
|
||||
[scriptable, uuid(30e5a7ec-f71e-4f41-9dbd-7429c02132ec)]
|
||||
interface nsIBrowserProfileMigrator : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -30,7 +30,7 @@ interface nsIBrowserProfileMigrator : nsISupports
|
||||
* @param aStartup helper interface which is non-null if called during startup.
|
||||
* @param aProfile profile to migrate from, if there is more than one.
|
||||
*/
|
||||
void migrate(in unsigned short aItems, in nsIProfileStartup aStartup, in wstring aProfile);
|
||||
void migrate(in unsigned short aItems, in nsIProfileStartup aStartup, in jsval aProfile);
|
||||
|
||||
/**
|
||||
* A bit field containing profile items that this migrator
|
||||
@ -41,7 +41,7 @@ interface nsIBrowserProfileMigrator : nsISupports
|
||||
* @return bit field containing profile items (see above)
|
||||
* @note a return value of 0 represents no items rather than ALL.
|
||||
*/
|
||||
unsigned short getMigrateData(in wstring aProfile, in boolean aDoingStartup);
|
||||
unsigned short getMigrateData(in jsval aProfile, in boolean aDoingStartup);
|
||||
|
||||
/**
|
||||
* Whether or not there is any data that can be imported from this
|
||||
|
@ -93,7 +93,7 @@ ChromeProfileMigrator.prototype.getResources =
|
||||
function Chrome_getResources(aProfile) {
|
||||
if (this._chromeUserDataFolder) {
|
||||
let profileFolder = this._chromeUserDataFolder.clone();
|
||||
profileFolder.append(aProfile);
|
||||
profileFolder.append(aProfile.id);
|
||||
if (profileFolder.exists()) {
|
||||
let possibleResources = [GetBookmarksResource(profileFolder),
|
||||
GetHistoryResource(profileFolder),
|
||||
@ -112,7 +112,7 @@ Object.defineProperty(ChromeProfileMigrator.prototype, "sourceProfiles", {
|
||||
if (!this._chromeUserDataFolder)
|
||||
return [];
|
||||
|
||||
let profiles;
|
||||
let profiles = [];
|
||||
try {
|
||||
// Local State is a JSON file that contains profile info.
|
||||
let localState = this._chromeUserDataFolder.clone();
|
||||
@ -127,20 +127,30 @@ Object.defineProperty(ChromeProfileMigrator.prototype, "sourceProfiles", {
|
||||
let inputStream = NetUtil.readInputStreamToString(fstream, fstream.available(),
|
||||
{ charset: "UTF-8" });
|
||||
let info_cache = JSON.parse(inputStream).profile.info_cache;
|
||||
if (info_cache)
|
||||
profiles = Object.keys(info_cache);
|
||||
for (let profileFolderName in info_cache) {
|
||||
let profileFolder = this._chromeUserDataFolder.clone();
|
||||
profileFolder.append(profileFolderName);
|
||||
profiles.push({
|
||||
id: profileFolderName,
|
||||
name: info_cache[profileFolderName].name || profileFolderName,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError("Error detecting Chrome profiles: " + e);
|
||||
// If we weren't able to detect any profiles above, fallback to the Default profile.
|
||||
let defaultProfileFolder = this._chromeUserDataFolder.clone();
|
||||
defaultProfileFolder.append("Default");
|
||||
if (defaultProfileFolder.exists())
|
||||
profiles = ["Default"];
|
||||
if (defaultProfileFolder.exists()) {
|
||||
profiles = [{
|
||||
id: "Default",
|
||||
name: "Default",
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
// Only list profiles from which any data can be imported
|
||||
return this.__sourceProfiles = profiles.filter(function(profileName) {
|
||||
let resources = this.getResources(profileName);
|
||||
return this.__sourceProfiles = profiles.filter(function(profile) {
|
||||
let resources = this.getResources(profile);
|
||||
return resources && resources.length > 0;
|
||||
}, this);
|
||||
}
|
||||
|
@ -92,7 +92,10 @@ this.MigratorPrototype = {
|
||||
/**
|
||||
* OVERRIDE IF AND ONLY IF the source supports multiple profiles.
|
||||
*
|
||||
* Returns array of profiles (by names) from which data may be imported.
|
||||
* Returns array of profile objects from which data may be imported. The object
|
||||
* should have the following keys:
|
||||
* id - a unique string identifier for the profile
|
||||
* name - a pretty name to display to the user in the UI
|
||||
*
|
||||
* Only profiles from which data can be imported should be listed. Otherwise
|
||||
* the behavior of the migration wizard isn't well-defined.
|
||||
@ -313,14 +316,15 @@ this.MigratorPrototype = {
|
||||
|
||||
/*** PRIVATE STUFF - DO NOT OVERRIDE ***/
|
||||
_getMaybeCachedResources: function PMB__getMaybeCachedResources(aProfile) {
|
||||
let profileKey = aProfile ? aProfile.id : "";
|
||||
if (this._resourcesByProfile) {
|
||||
if (aProfile in this._resourcesByProfile)
|
||||
return this._resourcesByProfile[aProfile];
|
||||
if (profileKey in this._resourcesByProfile)
|
||||
return this._resourcesByProfile[profileKey];
|
||||
}
|
||||
else {
|
||||
this._resourcesByProfile = { };
|
||||
}
|
||||
return this._resourcesByProfile[aProfile] = this.getResources(aProfile);
|
||||
return this._resourcesByProfile[profileKey] = this.getResources(aProfile);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@ function run_test() {
|
||||
do_check_true(migrator.sourceExists);
|
||||
|
||||
// Ensure bookmarks migration is available.
|
||||
let availableSources = migrator.getMigrateData("FieldOfFlowers", false);
|
||||
let availableSources = migrator.getMigrateData(null, false);
|
||||
do_check_true((availableSources & MigrationUtils.resourceTypes.BOOKMARKS) > 0);
|
||||
|
||||
// Wait for the imported bookmarks. Check that "From Internet Explorer"
|
||||
@ -52,5 +52,5 @@ function run_test() {
|
||||
}, "Migration:Ended", false);
|
||||
|
||||
migrator.migrate(MigrationUtils.resourceTypes.BOOKMARKS, null,
|
||||
"FieldOfFlowers");
|
||||
null);
|
||||
}
|
||||
|
@ -1,16 +1,26 @@
|
||||
/* 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/. */
|
||||
* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["Translation"];
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"Translation",
|
||||
"TranslationProvider",
|
||||
];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
const TRANSLATION_PREF_SHOWUI = "browser.translation.ui.show";
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Metrics.jsm", this);
|
||||
Cu.import("resource://gre/modules/Task.jsm", this);
|
||||
|
||||
const DAILY_COUNTER_FIELD = {type: Metrics.Storage.FIELD_DAILY_COUNTER};
|
||||
const DAILY_LAST_TEXT_FIELD = {type: Metrics.Storage.FIELD_DAILY_LAST_TEXT};
|
||||
|
||||
|
||||
this.Translation = {
|
||||
supportedSourceLanguages: ["en", "zh", "ja", "es", "de", "fr", "ru", "ar", "ko", "pt"],
|
||||
@ -28,16 +38,20 @@ this.Translation = {
|
||||
},
|
||||
|
||||
languageDetected: function(aBrowser, aDetectedLanguage) {
|
||||
if (this.supportedSourceLanguages.indexOf(aDetectedLanguage) == -1 ||
|
||||
aDetectedLanguage == this.defaultTargetLanguage)
|
||||
return;
|
||||
|
||||
TranslationHealthReport.recordTranslationOpportunity(aDetectedLanguage);
|
||||
|
||||
if (!Services.prefs.getBoolPref(TRANSLATION_PREF_SHOWUI))
|
||||
return;
|
||||
|
||||
if (this.supportedSourceLanguages.indexOf(aDetectedLanguage) != -1 &&
|
||||
aDetectedLanguage != this.defaultTargetLanguage) {
|
||||
if (!aBrowser.translationUI)
|
||||
aBrowser.translationUI = new TranslationUI(aBrowser);
|
||||
if (!aBrowser.translationUI)
|
||||
aBrowser.translationUI = new TranslationUI(aBrowser);
|
||||
|
||||
aBrowser.translationUI.showTranslationUI(aDetectedLanguage);
|
||||
}
|
||||
|
||||
aBrowser.translationUI.showTranslationUI(aDetectedLanguage);
|
||||
}
|
||||
};
|
||||
|
||||
@ -187,3 +201,228 @@ TranslationUI.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper methods for recording translation data in FHR.
|
||||
*/
|
||||
let TranslationHealthReport = {
|
||||
/**
|
||||
* Record a translation opportunity in the health report.
|
||||
* @param language
|
||||
* The language of the page.
|
||||
*/
|
||||
recordTranslationOpportunity: function (language) {
|
||||
this._withProvider(provider => provider.recordTranslationOpportunity(language));
|
||||
},
|
||||
|
||||
/**
|
||||
* Record a translation in the health report.
|
||||
* @param langFrom
|
||||
* The language of the page.
|
||||
* @param langTo
|
||||
* The language translated to
|
||||
* @param numCharacters
|
||||
* The number of characters that were translated
|
||||
*/
|
||||
recordTranslation: function (langFrom, langTo, numCharacters) {
|
||||
this._withProvider(provider => provider.recordTranslation(langFrom, langTo, numCharacters));
|
||||
},
|
||||
|
||||
/**
|
||||
* Record a change of the detected language in the health report. This should
|
||||
* only be called when actually executing a translation not every time the
|
||||
* user changes in the language in the UI.
|
||||
*
|
||||
* @param beforeFirstTranslation
|
||||
* A boolean indicating if we are recording a change of detected
|
||||
* language before translating the page for the first time. If we
|
||||
* have already translated the page from the detected language and
|
||||
* the user has manually adjusted the detected language false should
|
||||
* be passed.
|
||||
*/
|
||||
recordLanguageChange: function (beforeFirstTranslation) {
|
||||
this._withProvider(provider => provider.recordLanguageChange(beforeFirstTranslation));
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the translation provider and pass it to the given function.
|
||||
*
|
||||
* @param callback
|
||||
* The function that will be passed the translation provider.
|
||||
*/
|
||||
_withProvider: function (callback) {
|
||||
try {
|
||||
let reporter = Cc["@mozilla.org/datareporting/service;1"]
|
||||
.getService().wrappedJSObject.healthReporter;
|
||||
|
||||
if (reporter) {
|
||||
reporter.onInit().then(function () {
|
||||
callback(reporter.getProvider("org.mozilla.translation"));
|
||||
}, Cu.reportError);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds usage data about the Translation feature.
|
||||
*
|
||||
* This is a special telemetry measurement that is transmitted in the FHR
|
||||
* payload. Data will only be recorded/transmitted when both telemetry and
|
||||
* FHR are enabled. Additionally, if telemetry was previously enabled but
|
||||
* is currently disabled, old recorded data will not be transmitted.
|
||||
*/
|
||||
function TranslationMeasurement1() {
|
||||
Metrics.Measurement.call(this);
|
||||
|
||||
this._serializers[this.SERIALIZE_JSON].singular =
|
||||
this._wrapJSONSerializer(this._serializers[this.SERIALIZE_JSON].singular);
|
||||
|
||||
this._serializers[this.SERIALIZE_JSON].daily =
|
||||
this._wrapJSONSerializer(this._serializers[this.SERIALIZE_JSON].daily);
|
||||
}
|
||||
|
||||
TranslationMeasurement1.prototype = Object.freeze({
|
||||
__proto__: Metrics.Measurement.prototype,
|
||||
|
||||
name: "translation",
|
||||
version: 1,
|
||||
|
||||
fields: {
|
||||
translationOpportunityCount: DAILY_COUNTER_FIELD,
|
||||
pageTranslatedCount: DAILY_COUNTER_FIELD,
|
||||
charactersTranslatedCount: DAILY_COUNTER_FIELD,
|
||||
translationOpportunityCountsByLanguage: DAILY_LAST_TEXT_FIELD,
|
||||
pageTranslatedCountsByLanguage: DAILY_LAST_TEXT_FIELD,
|
||||
detectedLanguageChangedBefore: DAILY_COUNTER_FIELD,
|
||||
detectedLanguageChangedAfter: DAILY_COUNTER_FIELD,
|
||||
},
|
||||
|
||||
shouldIncludeField: function (field) {
|
||||
if (!Services.prefs.getBoolPref("toolkit.telemetry.enabled")) {
|
||||
// This measurement should only be included when telemetry is
|
||||
// enabled, so we will not include any fields.
|
||||
return false;
|
||||
}
|
||||
|
||||
return field in this._fields;
|
||||
},
|
||||
|
||||
_getDailyLastTextFieldAsJSON: function(name, date) {
|
||||
let id = this.fieldID(name);
|
||||
|
||||
return this.storage.getDailyLastTextFromFieldID(id, date).then((data) => {
|
||||
if (data.hasDay(date)) {
|
||||
data = JSON.parse(data.getDay(date));
|
||||
} else {
|
||||
data = {};
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
},
|
||||
|
||||
_wrapJSONSerializer: function (serializer) {
|
||||
let _parseInPlace = function(o, k) {
|
||||
if (k in o) {
|
||||
o[k] = JSON.parse(o[k]);
|
||||
}
|
||||
};
|
||||
|
||||
return function (data) {
|
||||
let result = serializer(data);
|
||||
|
||||
// Special case the serialization of these fields so that
|
||||
// they are sent as objects, not stringified objects.
|
||||
_parseInPlace(result, "translationOpportunityCountsByLanguage");
|
||||
_parseInPlace(result, "pageTranslatedCountsByLanguage");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.TranslationProvider = function () {
|
||||
Metrics.Provider.call(this);
|
||||
}
|
||||
|
||||
TranslationProvider.prototype = Object.freeze({
|
||||
__proto__: Metrics.Provider.prototype,
|
||||
|
||||
name: "org.mozilla.translation",
|
||||
|
||||
measurementTypes: [
|
||||
TranslationMeasurement1,
|
||||
],
|
||||
|
||||
recordTranslationOpportunity: function (language, date=new Date()) {
|
||||
let m = this.getMeasurement(TranslationMeasurement1.prototype.name,
|
||||
TranslationMeasurement1.prototype.version);
|
||||
|
||||
return this._enqueueTelemetryStorageTask(function* recordTask() {
|
||||
yield m.incrementDailyCounter("translationOpportunityCount", date);
|
||||
|
||||
let langCounts = yield m._getDailyLastTextFieldAsJSON(
|
||||
"translationOpportunityCountsByLanguage", date);
|
||||
|
||||
langCounts[language] = (langCounts[language] || 0) + 1;
|
||||
langCounts = JSON.stringify(langCounts);
|
||||
|
||||
yield m.setDailyLastText("translationOpportunityCountsByLanguage",
|
||||
langCounts, date);
|
||||
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
recordTranslation: function (langFrom, langTo, numCharacters, date=new Date()) {
|
||||
let m = this.getMeasurement(TranslationMeasurement1.prototype.name,
|
||||
TranslationMeasurement1.prototype.version);
|
||||
|
||||
return this._enqueueTelemetryStorageTask(function* recordTask() {
|
||||
yield m.incrementDailyCounter("pageTranslatedCount", date);
|
||||
yield m.incrementDailyCounter("charactersTranslatedCount", date,
|
||||
numCharacters);
|
||||
|
||||
let langCounts = yield m._getDailyLastTextFieldAsJSON(
|
||||
"pageTranslatedCountsByLanguage", date);
|
||||
|
||||
let counts = langCounts[langFrom] || {};
|
||||
counts["total"] = (counts["total"] || 0) + 1;
|
||||
counts[langTo] = (counts[langTo] || 0) + 1;
|
||||
langCounts[langFrom] = counts;
|
||||
langCounts = JSON.stringify(langCounts);
|
||||
|
||||
yield m.setDailyLastText("pageTranslatedCountsByLanguage",
|
||||
langCounts, date);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
recordLanguageChange: function (beforeFirstTranslation) {
|
||||
let m = this.getMeasurement(TranslationMeasurement1.prototype.name,
|
||||
TranslationMeasurement1.prototype.version);
|
||||
|
||||
return this._enqueueTelemetryStorageTask(function* recordTask() {
|
||||
if (beforeFirstTranslation) {
|
||||
yield m.incrementDailyCounter("detectedLanguageChangedBefore");
|
||||
} else {
|
||||
yield m.incrementDailyCounter("detectedLanguageChangedAfter");
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_enqueueTelemetryStorageTask: function (task) {
|
||||
if (!Services.prefs.getBoolPref("toolkit.telemetry.enabled")) {
|
||||
// This measurement should only be included when telemetry is
|
||||
// enabled, so don't record any data.
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
return this.enqueueStorageOperation(() => {
|
||||
return Task.spawn(task);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -21,5 +21,9 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/xpcshell.ini'
|
||||
'test/unit/xpcshell.ini'
|
||||
]
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'translation.manifest',
|
||||
]
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
// tests the translation infobar, using a fake 'Translation' implementation.
|
||||
|
||||
Components.utils.import("resource:///modules/translation/Translation.jsm");
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/translation/Translation.jsm", tmp);
|
||||
let {Translation} = tmp;
|
||||
|
||||
const kLanguagesPref = "browser.translation.neverForLanguages";
|
||||
const kShowUIPref = "browser.translation.ui.show";
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
// tests the translation infobar, using a fake 'Translation' implementation.
|
||||
|
||||
Components.utils.import("resource:///modules/translation/Translation.jsm");
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/translation/Translation.jsm", tmp);
|
||||
let {Translation} = tmp;
|
||||
|
||||
const kShowUIPref = "browser.translation.ui.show";
|
||||
|
||||
|
269
browser/components/translation/test/unit/test_healthreport.js
Normal file
269
browser/components/translation/test/unit/test_healthreport.js
Normal file
@ -0,0 +1,269 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm", this);
|
||||
Cu.import("resource://gre/modules/Metrics.jsm", this);
|
||||
Cu.import("resource:///modules/translation/Translation.jsm", this);
|
||||
Cu.import("resource://testing-common/services/healthreport/utils.jsm", this);
|
||||
|
||||
// At end of test, restore original state.
|
||||
const ORIGINAL_TELEMETRY_ENABLED = Services.prefs.getBoolPref("toolkit.telemetry.enabled");
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function setup() {
|
||||
do_get_profile();
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
do_register_cleanup(function() {
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled",
|
||||
ORIGINAL_TELEMETRY_ENABLED);
|
||||
});
|
||||
|
||||
add_task(function test_constructor() {
|
||||
let provider = new TranslationProvider();
|
||||
});
|
||||
|
||||
// Provider can initialize and de-initialize properly.
|
||||
add_task(function* test_init() {
|
||||
let storage = yield Metrics.Storage("init");
|
||||
let provider = new TranslationProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
// Test recording translation opportunities.
|
||||
add_task(function* test_translation_opportunity() {
|
||||
let storage = yield Metrics.Storage("opportunity");
|
||||
let provider = new TranslationProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
// Initially nothing should be configured.
|
||||
let now = new Date();
|
||||
let m = provider.getMeasurement("translation", 1);
|
||||
let values = yield m.getValues();
|
||||
Assert.equal(values.days.size, 0);
|
||||
Assert.ok(!values.days.hasDay(now));
|
||||
|
||||
// Record an opportunity.
|
||||
yield provider.recordTranslationOpportunity("fr", now);
|
||||
|
||||
values = yield m.getValues();
|
||||
Assert.equal(values.days.size, 1);
|
||||
Assert.ok(values.days.hasDay(now));
|
||||
let day = values.days.getDay(now);
|
||||
Assert.ok(day.has("translationOpportunityCount"));
|
||||
Assert.equal(day.get("translationOpportunityCount"), 1);
|
||||
|
||||
Assert.ok(day.has("translationOpportunityCountsByLanguage"));
|
||||
let countsByLanguage = JSON.parse(day.get("translationOpportunityCountsByLanguage"));
|
||||
Assert.equal(countsByLanguage["fr"], 1);
|
||||
|
||||
// Record more opportunities.
|
||||
yield provider.recordTranslationOpportunity("fr", now);
|
||||
yield provider.recordTranslationOpportunity("fr", now);
|
||||
yield provider.recordTranslationOpportunity("es", now);
|
||||
|
||||
values = yield m.getValues();
|
||||
let day = values.days.getDay(now);
|
||||
Assert.ok(day.has("translationOpportunityCount"));
|
||||
Assert.equal(day.get("translationOpportunityCount"), 4);
|
||||
|
||||
Assert.ok(day.has("translationOpportunityCountsByLanguage"));
|
||||
countsByLanguage = JSON.parse(day.get("translationOpportunityCountsByLanguage"));
|
||||
Assert.equal(countsByLanguage["fr"], 3);
|
||||
Assert.equal(countsByLanguage["es"], 1);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
// Test recording a translation.
|
||||
add_task(function* test_record_translation() {
|
||||
let storage = yield Metrics.Storage("translation");
|
||||
let provider = new TranslationProvider();
|
||||
yield provider.init(storage);
|
||||
let now = new Date();
|
||||
|
||||
// Record a translation.
|
||||
yield provider.recordTranslation("fr", "es", 1000, now);
|
||||
|
||||
let m = provider.getMeasurement("translation", 1);
|
||||
let values = yield m.getValues();
|
||||
Assert.equal(values.days.size, 1);
|
||||
Assert.ok(values.days.hasDay(now));
|
||||
let day = values.days.getDay(now);
|
||||
Assert.ok(day.has("pageTranslatedCount"));
|
||||
Assert.equal(day.get("pageTranslatedCount"), 1);
|
||||
Assert.ok(day.has("charactersTranslatedCount"));
|
||||
Assert.equal(day.get("charactersTranslatedCount"), 1000);
|
||||
|
||||
Assert.ok(day.has("pageTranslatedCountsByLanguage"));
|
||||
let countsByLanguage = JSON.parse(day.get("pageTranslatedCountsByLanguage"));
|
||||
Assert.ok("fr" in countsByLanguage);
|
||||
Assert.equal(countsByLanguage["fr"]["total"], 1);
|
||||
Assert.equal(countsByLanguage["fr"]["es"], 1);
|
||||
|
||||
// Record more translations.
|
||||
yield provider.recordTranslation("fr", "es", 1, now);
|
||||
yield provider.recordTranslation("fr", "en", 2, now);
|
||||
yield provider.recordTranslation("es", "en", 4, now);
|
||||
|
||||
values = yield m.getValues();
|
||||
let day = values.days.getDay(now);
|
||||
Assert.ok(day.has("pageTranslatedCount"));
|
||||
Assert.equal(day.get("pageTranslatedCount"), 4);
|
||||
Assert.ok(day.has("charactersTranslatedCount"));
|
||||
Assert.equal(day.get("charactersTranslatedCount"), 1007);
|
||||
|
||||
Assert.ok(day.has("pageTranslatedCountsByLanguage"));
|
||||
let countsByLanguage = JSON.parse(day.get("pageTranslatedCountsByLanguage"));
|
||||
Assert.ok("fr" in countsByLanguage);
|
||||
Assert.equal(countsByLanguage["fr"]["total"], 3);
|
||||
Assert.equal(countsByLanguage["fr"]["es"], 2);
|
||||
Assert.equal(countsByLanguage["fr"]["en"], 1);
|
||||
Assert.ok("es" in countsByLanguage);
|
||||
Assert.equal(countsByLanguage["es"]["total"], 1);
|
||||
Assert.equal(countsByLanguage["es"]["en"], 1);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
// Test recording changing languages.
|
||||
add_task(function* test_record_translation() {
|
||||
let storage = yield Metrics.Storage("translation");
|
||||
let provider = new TranslationProvider();
|
||||
yield provider.init(storage);
|
||||
let now = new Date();
|
||||
|
||||
// Record a language change before translation.
|
||||
yield provider.recordLanguageChange(true);
|
||||
|
||||
// Record two language changes after translation.
|
||||
yield provider.recordLanguageChange(false);
|
||||
yield provider.recordLanguageChange(false);
|
||||
|
||||
|
||||
let m = provider.getMeasurement("translation", 1);
|
||||
let values = yield m.getValues();
|
||||
Assert.equal(values.days.size, 1);
|
||||
Assert.ok(values.days.hasDay(now));
|
||||
let day = values.days.getDay(now);
|
||||
|
||||
Assert.ok(day.has("detectedLanguageChangedBefore"));
|
||||
Assert.equal(day.get("detectedLanguageChangedBefore"), 1);
|
||||
Assert.ok(day.has("detectedLanguageChangedAfter"));
|
||||
Assert.equal(day.get("detectedLanguageChangedAfter"), 2);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
// Test the payload after recording with telemetry enabled.
|
||||
add_task(function* test_healthreporter_json() {
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
|
||||
|
||||
let reporter = yield getHealthReporter("healthreporter_json");
|
||||
yield reporter.init();
|
||||
try {
|
||||
let now = new Date();
|
||||
let provider = new TranslationProvider();
|
||||
yield reporter._providerManager.registerProvider(provider);
|
||||
|
||||
yield provider.recordTranslationOpportunity("fr", now);
|
||||
yield provider.recordLanguageChange(true);
|
||||
yield provider.recordTranslation("fr", "en", 1000, now);
|
||||
yield provider.recordLanguageChange(false);
|
||||
|
||||
yield provider.recordTranslationOpportunity("es", now);
|
||||
yield provider.recordTranslation("es", "en", 1000, now);
|
||||
|
||||
yield reporter.collectMeasurements();
|
||||
let payload = yield reporter.getJSONPayload(true);
|
||||
let today = reporter._formatDate(now);
|
||||
|
||||
Assert.ok(today in payload.data.days);
|
||||
let day = payload.data.days[today];
|
||||
|
||||
Assert.ok("org.mozilla.translation.translation" in day);
|
||||
|
||||
let translations = day["org.mozilla.translation.translation"];
|
||||
|
||||
Assert.equal(translations["translationOpportunityCount"], 2);
|
||||
Assert.equal(translations["pageTranslatedCount"], 2);
|
||||
Assert.equal(translations["charactersTranslatedCount"], 2000);
|
||||
|
||||
Assert.ok("translationOpportunityCountsByLanguage" in translations);
|
||||
Assert.equal(translations["translationOpportunityCountsByLanguage"]["fr"], 1);
|
||||
Assert.equal(translations["translationOpportunityCountsByLanguage"]["es"], 1);
|
||||
|
||||
Assert.ok("pageTranslatedCountsByLanguage" in translations);
|
||||
Assert.ok("fr" in translations["pageTranslatedCountsByLanguage"]);
|
||||
Assert.equal(translations["pageTranslatedCountsByLanguage"]["fr"]["total"], 1);
|
||||
Assert.equal(translations["pageTranslatedCountsByLanguage"]["fr"]["en"], 1);
|
||||
|
||||
Assert.ok("es" in translations["pageTranslatedCountsByLanguage"]);
|
||||
Assert.equal(translations["pageTranslatedCountsByLanguage"]["es"]["total"], 1);
|
||||
Assert.equal(translations["pageTranslatedCountsByLanguage"]["es"]["en"], 1);
|
||||
|
||||
Assert.ok("detectedLanguageChangedBefore" in translations);
|
||||
Assert.equal(translations["detectedLanguageChangedBefore"], 1);
|
||||
Assert.ok("detectedLanguageChangedAfter" in translations);
|
||||
Assert.equal(translations["detectedLanguageChangedAfter"], 1);
|
||||
} finally {
|
||||
reporter._shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
// Test the payload after recording with telemetry disabled.
|
||||
add_task(function* test_healthreporter_json() {
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
|
||||
|
||||
let reporter = yield getHealthReporter("healthreporter_json");
|
||||
yield reporter.init();
|
||||
try {
|
||||
let now = new Date();
|
||||
let provider = new TranslationProvider();
|
||||
yield reporter._providerManager.registerProvider(provider);
|
||||
|
||||
yield provider.recordTranslationOpportunity("fr", now);
|
||||
yield provider.recordLanguageChange(true);
|
||||
yield provider.recordTranslation("fr", "en", 1000, now);
|
||||
yield provider.recordLanguageChange(false);
|
||||
|
||||
yield provider.recordTranslationOpportunity("es", now);
|
||||
yield provider.recordTranslation("es", "en", 1000, now);
|
||||
|
||||
yield reporter.collectMeasurements();
|
||||
let payload = yield reporter.getJSONPayload(true);
|
||||
let today = reporter._formatDate(now);
|
||||
|
||||
Assert.ok(today in payload.data.days);
|
||||
let day = payload.data.days[today];
|
||||
|
||||
Assert.ok("org.mozilla.translation.translation" in day);
|
||||
|
||||
let translations = day["org.mozilla.translation.translation"];
|
||||
|
||||
Assert.ok(!("translationOpportunityCount" in translations));
|
||||
Assert.ok(!("pageTranslatedCount" in translations));
|
||||
Assert.ok(!("charactersTranslatedCount" in translations));
|
||||
Assert.ok(!("translationOpportunityCountsByLanguage" in translations));
|
||||
Assert.ok(!("pageTranslatedCountsByLanguage" in translations));
|
||||
Assert.ok(!("detectedLanguageChangedBefore" in translations));
|
||||
Assert.ok(!("detectedLanguageChangedAfter" in translations));
|
||||
} finally {
|
||||
reporter._shutdown();
|
||||
}
|
||||
});
|
@ -4,3 +4,4 @@ tail =
|
||||
firefox-appdir = browser
|
||||
|
||||
[test_cld2.js]
|
||||
[test_healthreport.js]
|
3
browser/components/translation/translation.manifest
Normal file
3
browser/components/translation/translation.manifest
Normal file
@ -0,0 +1,3 @@
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
category healthreport-js-provider-default TranslationProvider resource:///modules/translation/Translation.jsm
|
||||
#endif
|
@ -22,16 +22,16 @@ const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
const ITCHPAD_URL = "chrome://browser/content/devtools/projecteditor.xul";
|
||||
|
||||
// Enabled Plugins
|
||||
require("projecteditor/plugins/dirty/lib/dirty");
|
||||
require("projecteditor/plugins/delete/lib/delete");
|
||||
require("projecteditor/plugins/new/lib/new");
|
||||
require("projecteditor/plugins/save/lib/save");
|
||||
require("projecteditor/plugins/image-view/lib/plugin");
|
||||
require("projecteditor/plugins/app-manager/lib/plugin");
|
||||
require("projecteditor/plugins/status-bar/lib/plugin");
|
||||
require("projecteditor/plugins/dirty/dirty");
|
||||
require("projecteditor/plugins/delete/delete");
|
||||
require("projecteditor/plugins/new/new");
|
||||
require("projecteditor/plugins/save/save");
|
||||
require("projecteditor/plugins/image-view/plugin");
|
||||
require("projecteditor/plugins/app-manager/plugin");
|
||||
require("projecteditor/plugins/status-bar/plugin");
|
||||
|
||||
// Uncomment to enable logging.
|
||||
// require("projecteditor/plugins/logging/lib/logging");
|
||||
// require("projecteditor/plugins/logging/logging");
|
||||
|
||||
/**
|
||||
* This is the main class tying together an instance of the ProjectEditor.
|
||||
|
@ -125,12 +125,12 @@
|
||||
<!ENTITY certificateTab.label "Certificates">
|
||||
<!ENTITY certSelection.description "When a server requests my personal certificate:">
|
||||
<!ENTITY certs.auto "Select one automatically">
|
||||
<!ENTITY certs.auto.accesskey "l">
|
||||
<!ENTITY certs.auto.accesskey "S">
|
||||
<!ENTITY certs.ask "Ask me every time">
|
||||
<!ENTITY certs.ask.accesskey "i">
|
||||
<!ENTITY certs.ask.accesskey "A">
|
||||
<!ENTITY viewCerts.label "View Certificates">
|
||||
<!ENTITY viewCerts.accesskey "s">
|
||||
<!ENTITY viewCerts.accesskey "C">
|
||||
<!ENTITY verify2.label "Validation">
|
||||
<!ENTITY verify2.accesskey "V">
|
||||
<!ENTITY viewSecurityDevices.label "Security Devices">
|
||||
<!ENTITY viewSecurityDevices.accesskey "y">
|
||||
<!ENTITY viewSecurityDevices.accesskey "D">
|
||||
|
@ -9,7 +9,7 @@
|
||||
<!ENTITY dntTrackingNotOkay.label2 "Tell sites that I do not want to be tracked">
|
||||
<!ENTITY dntTrackingNotOkay.accesskey "n">
|
||||
<!ENTITY dntTrackingOkay.label2 "Tell sites that I want to be tracked">
|
||||
<!ENTITY dntTrackingOkay.accesskey "t">
|
||||
<!ENTITY dntTrackingOkay.accesskey "h">
|
||||
<!ENTITY doNotTrackInfo.label "Learn More">
|
||||
|
||||
<!ENTITY history.label "History">
|
||||
|
@ -9,13 +9,13 @@
|
||||
<!ENTITY warnCloseMultipleTabs.accesskey "m">
|
||||
|
||||
<!ENTITY warnOpenManyTabs.label "Warn me when opening multiple tabs might slow down &brandShortName;">
|
||||
<!ENTITY warnOpenManyTabs.accesskey "o">
|
||||
<!ENTITY warnOpenManyTabs.accesskey "d">
|
||||
|
||||
<!ENTITY restoreTabsOnDemand.label "Don’t load tabs until selected">
|
||||
<!ENTITY restoreTabsOnDemand.accesskey "l">
|
||||
<!ENTITY restoreTabsOnDemand.accesskey "u">
|
||||
|
||||
<!ENTITY switchToNewTabs.label "When I open a link in a new tab, switch to it immediately">
|
||||
<!ENTITY switchToNewTabs.accesskey "s">
|
||||
<!ENTITY switchToNewTabs.accesskey "h">
|
||||
|
||||
<!ENTITY showTabsInTaskbar.label "Show tab previews in the Windows taskbar">
|
||||
<!ENTITY showTabsInTaskbar.accesskey "k">
|
||||
|
@ -1528,6 +1528,67 @@ Example
|
||||
}
|
||||
|
||||
|
||||
org.mozilla.translation.translation
|
||||
-----------------------------------
|
||||
|
||||
This daily measurement contains information about the usage of the translation
|
||||
feature. It is a special telemetry measurement which will only be recorded in
|
||||
FHR if telemetry is enabled.
|
||||
|
||||
Version 1
|
||||
^^^^^^^^^
|
||||
|
||||
Daily counts are reported in the following properties:
|
||||
|
||||
translationOpportunityCount
|
||||
Integer count of the number of opportunities there were to translate a page.
|
||||
pageTranslatedCount
|
||||
Integer count of the number of pages translated.
|
||||
charactersTranslatedCount
|
||||
Integer count of the number of characters translated.
|
||||
detectedLanguageChangedBefore
|
||||
Integer count of the number of times the user manually adjusted the detected
|
||||
language before translating.
|
||||
detectedLanguageChangedAfter
|
||||
Integer count of the number of times the user manually adjusted the detected
|
||||
language after having first translated the page.
|
||||
|
||||
Additional daily counts broken down by language are reported in the following
|
||||
properties:
|
||||
|
||||
translationOpportunityCountsByLanguage
|
||||
A mapping from language to count of opportunities to translate that
|
||||
language.
|
||||
pageTranslatedCountsByLanguage
|
||||
A mapping from language to the counts of pages translated from that
|
||||
language. Each language entry will be an object containing a "total" member
|
||||
along with individual counts for each language translated to.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
"org.mozilla.translation.translation": {
|
||||
"_v": 1,
|
||||
"translationOpportunityCount": 134,
|
||||
"pageTranslatedCount": 6,
|
||||
"charactersTranslatedCount": "1126",
|
||||
"detectedLanguageChangedBefore": 1,
|
||||
"detectedLanguageChangedAfter": 2,
|
||||
"translationOpportunityCountsByLanguage": {
|
||||
"fr": 100,
|
||||
"es": 34
|
||||
},
|
||||
"pageTranslatedCountsByLanguage": {
|
||||
"fr": {
|
||||
"total": 6,
|
||||
"es": 5,
|
||||
"en": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
org.mozilla.experiments.info
|
||||
----------------------------------
|
||||
|
@ -542,6 +542,9 @@ let WebConsoleUtils = {
|
||||
get usageCount() {
|
||||
if (WebConsoleUtils._usageCount < CONSOLE_ENTRY_THRESHOLD) {
|
||||
WebConsoleUtils._usageCount = Services.prefs.getIntPref("devtools.selfxss.count")
|
||||
if (Services.prefs.getBoolPref("devtools.chrome.enabled")) {
|
||||
WebConsoleUtils.usageCount = CONSOLE_ENTRY_THRESHOLD;
|
||||
}
|
||||
}
|
||||
return WebConsoleUtils._usageCount;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user