This commit is contained in:
Phil Ringnalda 2016-01-09 11:44:32 -08:00
Родитель c5e1a2b4ca 5734bab58d
Коммит 542a3fabcb
86 изменённых файлов: 1012 добавлений и 651 удалений

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

@ -184,7 +184,6 @@ var TrackingProtection = {
}, },
showIntroPanel: Task.async(function*() { showIntroPanel: Task.async(function*() {
let mm = gBrowser.selectedBrowser.messageManager;
let brandBundle = document.getElementById("bundle_brand"); let brandBundle = document.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName"); let brandShortName = brandBundle.getString("brandShortName");
@ -219,7 +218,7 @@ var TrackingProtection = {
let panelTarget = yield UITour.getTarget(window, "trackingProtection"); let panelTarget = yield UITour.getTarget(window, "trackingProtection");
UITour.initForBrowser(gBrowser.selectedBrowser, window); UITour.initForBrowser(gBrowser.selectedBrowser, window);
UITour.showInfo(window, mm, panelTarget, UITour.showInfo(window, panelTarget,
gNavigatorBundle.getString("trackingProtection.intro.title"), gNavigatorBundle.getString("trackingProtection.intro.title"),
gNavigatorBundle.getFormattedString("trackingProtection.intro.description", gNavigatorBundle.getFormattedString("trackingProtection.intro.description",
[brandShortName]), [brandShortName]),

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

@ -1759,17 +1759,8 @@ nsContextMenu.prototype = {
selectedText = selectedText.substr(0,truncLength) + this.ellipsis; selectedText = selectedText.substr(0,truncLength) + this.ellipsis;
} }
// Use the current engine if the search bar is visible, the default
// engine otherwise.
var engineName = "";
var ss = Cc["@mozilla.org/browser/search-service;1"].
getService(Ci.nsIBrowserSearchService);
if (isElementVisible(BrowserSearch.searchBar))
engineName = ss.currentEngine.name;
else
engineName = ss.defaultEngine.name;
// format "Search <engine> for <selection>" string to show in menu // format "Search <engine> for <selection>" string to show in menu
let engineName = Services.search.currentEngine.name;
var menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch", var menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch",
[engineName, [engineName,
selectedText]); selectedText]);

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

@ -261,27 +261,21 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
}).api(), }).api(),
create: function(createProperties, callback) { create: function(createProperties, callback) {
if (!createProperties) {
createProperties = {};
}
let url = createProperties.url || aboutNewTabService.newTabURL; let url = createProperties.url || aboutNewTabService.newTabURL;
url = extension.baseURI.resolve(url); url = context.uri.resolve(url);
function createInWindow(window) { function createInWindow(window) {
let tab = window.gBrowser.addTab(url); let tab = window.gBrowser.addTab(url);
let active = true; let active = true;
if ("active" in createProperties) { if (createProperties.active !== null) {
active = createProperties.active; active = createProperties.active;
} else if ("selected" in createProperties) {
active = createProperties.selected;
} }
if (active) { if (active) {
window.gBrowser.selectedTab = tab; window.gBrowser.selectedTab = tab;
} }
if ("index" in createProperties) { if (createProperties.index !== null) {
window.gBrowser.moveTabTo(tab, createProperties.index); window.gBrowser.moveTabTo(tab, createProperties.index);
} }

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

@ -24,6 +24,7 @@ support-files =
[browser_ext_tabs_executeScript_bad.js] [browser_ext_tabs_executeScript_bad.js]
[browser_ext_tabs_query.js] [browser_ext_tabs_query.js]
[browser_ext_tabs_getCurrent.js] [browser_ext_tabs_getCurrent.js]
[browser_ext_tabs_create.js]
[browser_ext_tabs_update.js] [browser_ext_tabs_update.js]
[browser_ext_tabs_onUpdated.js] [browser_ext_tabs_onUpdated.js]
[browser_ext_tabs_sendMessage.js] [browser_ext_tabs_sendMessage.js]

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

@ -0,0 +1,169 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(function* () {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
gBrowser.selectedTab = tab;
// TODO: Multiple windows.
// Using pre-loaded new tab pages interferes with onUpdated events.
// It probably shouldn't.
SpecialPowers.setBoolPref("browser.newtab.preload", false);
registerCleanupFunction(() => {
SpecialPowers.clearUserPref("browser.newtab.preload");
});
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["tabs"],
"background": { "page": "bg/background.html" },
},
files: {
"bg/blank.html": `<html><head><meta charset="utf-8"></head></html>`,
"bg/background.html": `<html><head>
<meta charset="utf-8">
<script src="background.js"></script>
</head></html>`,
"bg/background.js": function() {
// Wrap API methods in promise-based variants.
let promiseTabs = {};
Object.keys(browser.tabs).forEach(method => {
promiseTabs[method] = (...args) => {
return new Promise(resolve => {
browser.tabs[method](...args, resolve);
});
};
});
let activeTab;
let activeWindow;
function runTests() {
const DEFAULTS = {
index: 2,
windowId: activeWindow,
active: true,
pinned: false,
url: "about:newtab",
};
let tests = [
{
create: { url: "http://example.com/" },
result: { url: "http://example.com/" },
},
{
create: { url: "blank.html" },
result: { url: browser.runtime.getURL("bg/blank.html") },
},
{
create: {},
result: { url: "about:newtab" },
},
{
create: { active: false },
result: { active: false },
},
{
create: { active: true },
result: { active: true },
},
{
create: { pinned: true },
result: { pinned: true, index: 0 },
},
{
create: { pinned: true, active: true },
result: { pinned: true, active: true, index: 0 },
},
{
create: { pinned: true, active: false },
result: { pinned: true, active: false, index: 0 },
},
{
create: { index: 1 },
result: { index: 1 },
},
{
create: { index: 1, active: false },
result: { index: 1, active: false },
},
{
create: { windowId: activeWindow },
result: { windowId: activeWindow },
},
];
function nextTest() {
if (!tests.length) {
browser.test.notifyPass("tabs.create");
return;
}
let test = tests.shift();
let expected = Object.assign({}, DEFAULTS, test.result);
browser.test.log(`Testing tabs.create(${JSON.stringify(test.create)}), expecting ${JSON.stringify(test.result)}`);
let tabId;
let updatedPromise = new Promise(resolve => {
let onUpdated = (changedTabId, changed) => {
if (changedTabId === tabId && changed.url) {
browser.tabs.onUpdated.removeListener(onUpdated);
resolve(changed.url);
}
};
browser.tabs.onUpdated.addListener(onUpdated);
});
promiseTabs.create(test.create).then(tab => {
tabId = tab.id;
for (let key of Object.keys(expected)) {
if (key === "url") {
// FIXME: This doesn't get updated until later in the load cycle.
continue;
}
browser.test.assertEq(expected[key], tab[key], `Expected value for tab.${key}`);
}
return updatedPromise;
}).then(url => {
browser.test.assertEq(expected.url, url, `Expected value for tab.url`);
return promiseTabs.remove(tabId);
}).then(() => {
return promiseTabs.update(activeTab, { active: true });
}).then(() => {
nextTest();
});
}
nextTest();
}
browser.tabs.query({ active: true, currentWindow: true }, tabs => {
activeTab = tabs[0].id;
activeWindow = tabs[0].windowId;
runTests();
});
},
},
});
yield extension.startup();
yield extension.awaitFinish("tabs.create");
yield extension.unload();
yield BrowserTestUtils.removeTab(tab);
});

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

@ -38,7 +38,6 @@ const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const nsIWindowMediator = Components.interfaces.nsIWindowMediator; const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher; const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo; const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator; const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED; const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
@ -262,10 +261,7 @@ function logSystemBasedSearch(engine) {
} }
function doSearch(searchTerm, cmdLine) { function doSearch(searchTerm, cmdLine) {
var ss = Components.classes["@mozilla.org/browser/search-service;1"] var engine = Services.search.defaultEngine;
.getService(nsIBrowserSearchService);
var engine = ss.defaultEngine;
logSystemBasedSearch(engine); logSystemBasedSearch(engine);
var submission = engine.getSubmission(searchTerm, null, "system"); var submission = engine.getSubmission(searchTerm, null, "system");
@ -796,9 +792,7 @@ nsDefaultCommandLineHandler.prototype = {
} }
if (allowedParams.indexOf(formParam) != -1) { if (allowedParams.indexOf(formParam) != -1) {
var term = params.get("q"); var term = params.get("q");
var ss = Components.classes["@mozilla.org/browser/search-service;1"] var engine = Services.search.defaultEngine;
.getService(nsIBrowserSearchService);
var engine = ss.defaultEngine;
logSystemBasedSearch(engine); logSystemBasedSearch(engine);
var submission = engine.getSubmission(term, null, "system"); var submission = engine.getSubmission(term, null, "system");
uri = submission.uri; uri = submission.uri;

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

@ -446,30 +446,6 @@ BrowserGlue.prototype = {
Preferences.set("browser.search.hiddenOneOffs", Preferences.set("browser.search.hiddenOneOffs",
hiddenList.join(",")); hiddenList.join(","));
} }
if (data != "engine-default" && data != "engine-current") {
break;
}
// Enforce that the search service's defaultEngine is always equal to
// its currentEngine. The search service will notify us any time either
// of them are changed (either by directly setting the relevant prefs,
// i.e. if add-ons try to change this directly, or if the
// nsIBrowserSearchService setters are called).
// No need to initialize the search service, since it's guaranteed to be
// initialized already when this notification fires.
let ss = Services.search;
if (ss.currentEngine.name == ss.defaultEngine.name)
return;
if (data == "engine-current")
ss.defaultEngine = ss.currentEngine;
else
ss.currentEngine = ss.defaultEngine;
break;
case "browser-search-service":
if (data != "init-complete")
return;
Services.obs.removeObserver(this, "browser-search-service");
this._syncSearchEngines();
break; break;
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
case "nsPref:changed": case "nsPref:changed":
@ -568,16 +544,6 @@ BrowserGlue.prototype = {
} }
}, },
_syncSearchEngines: function () {
// Only do this if the search service is already initialized. This function
// gets called in finalUIStartup and from a browser-search-service observer,
// to catch both cases (search service initialization occurring before and
// after final-ui-startup)
if (Services.search.isInitialized) {
Services.search.defaultEngine = Services.search.currentEngine;
}
},
// initialization (called on application startup) // initialization (called on application startup)
_init: function BG__init() { _init: function BG__init() {
let os = Services.obs; let os = Services.obs;
@ -609,7 +575,6 @@ BrowserGlue.prototype = {
os.addObserver(this, "keyword-search", false); os.addObserver(this, "keyword-search", false);
#endif #endif
os.addObserver(this, "browser-search-engine-modified", false); os.addObserver(this, "browser-search-engine-modified", false);
os.addObserver(this, "browser-search-service", false);
os.addObserver(this, "restart-in-safe-mode", false); os.addObserver(this, "restart-in-safe-mode", false);
os.addObserver(this, "flash-plugin-hang", false); os.addObserver(this, "flash-plugin-hang", false);
os.addObserver(this, "xpi-signature-changed", false); os.addObserver(this, "xpi-signature-changed", false);
@ -669,10 +634,6 @@ BrowserGlue.prototype = {
os.removeObserver(this, "keyword-search"); os.removeObserver(this, "keyword-search");
#endif #endif
os.removeObserver(this, "browser-search-engine-modified"); os.removeObserver(this, "browser-search-engine-modified");
try {
os.removeObserver(this, "browser-search-service");
// may have already been removed by the observer
} catch (ex) {}
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
Services.prefs.removeObserver(POLARIS_ENABLED, this); Services.prefs.removeObserver(POLARIS_ENABLED, this);
#endif #endif
@ -823,8 +784,6 @@ BrowserGlue.prototype = {
// handle any UI migration // handle any UI migration
this._migrateUI(); this._migrateUI();
this._syncSearchEngines();
WebappManager.init(); WebappManager.init();
PageThumbs.init(); PageThumbs.init();
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD

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

@ -0,0 +1,35 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?xml-stylesheet href="chrome://global/skin/"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
<!DOCTYPE prefwindow SYSTEM "chrome://browser/locale/preferences/donottrack.dtd" >
<prefwindow id="DoNotTrackDialog" type="child"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="&window.title;"
style="width: &window.width;; height: &window.height;;"
dlgbuttons="accept,cancel">
<prefpane>
<preferences>
<preference id="privacy.donottrackheader.enabled"
name="privacy.donottrackheader.enabled"
type="bool"/>
</preferences>
<hbox align="center" pack="start">
<!-- Work around focus ring not showing properly. -->
<spacer style="width: 1em;"/>
<checkbox label="&doNotTrackCheckbox.label;"
accesskey="&doNotTrackCheckbox.accesskey;"
preference="privacy.donottrackheader.enabled"/>
<label class="text-link doNotTrackLearnMore"
value="&doNotTrackLearnMore.label;"
href="https://www.mozilla.org/dnt"/>
</hbox>
</prefpane>
</prefwindow>

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

@ -30,7 +30,10 @@ var gPrivacyPane = {
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "tracking-protection"; let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "tracking-protection";
link.setAttribute("href", url); link.setAttribute("href", url);
this.trackingProtectionReadPrefs();
document.getElementById("trackingprotectionbox").hidden = false; document.getElementById("trackingprotectionbox").hidden = false;
document.getElementById("trackingprotectionpbmbox").hidden = true;
}, },
#endif #endif
@ -108,6 +111,10 @@ var gPrivacyPane = {
gPrivacyPane.clearPrivateDataNow(true); gPrivacyPane.clearPrivateDataNow(true);
return false; return false;
}); });
setEventListener("doNotTrackSettings", "click", function () {
gPrivacyPane.showDoNotTrackSettings();
return false;
});
setEventListener("privateBrowsingAutoStart", "command", setEventListener("privateBrowsingAutoStart", "command",
gPrivacyPane.updateAutostart); gPrivacyPane.updateAutostart);
setEventListener("cookieExceptions", "command", setEventListener("cookieExceptions", "command",
@ -116,8 +123,54 @@ var gPrivacyPane = {
gPrivacyPane.showCookies); gPrivacyPane.showCookies);
setEventListener("clearDataSettings", "command", setEventListener("clearDataSettings", "command",
gPrivacyPane.showClearPrivateDataSettings); gPrivacyPane.showClearPrivateDataSettings);
setEventListener("trackingProtectionRadioGroup", "command",
gPrivacyPane.trackingProtectionWritePrefs);
setEventListener("trackingProtectionExceptions", "command",
gPrivacyPane.showTrackingProtectionExceptions);
setEventListener("changeBlockList", "command", setEventListener("changeBlockList", "command",
gPrivacyPane.showBlockLists); gPrivacyPane.showBlockLists);
setEventListener("changeBlockListPBM", "command",
gPrivacyPane.showBlockLists);
},
// TRACKING PROTECTION MODE
/**
* Selects the right item of the Tracking Protection radiogroup.
*/
trackingProtectionReadPrefs() {
let enabledPref = document.getElementById("privacy.trackingprotection.enabled");
let pbmPref = document.getElementById("privacy.trackingprotection.pbmode.enabled");
let radiogroup = document.getElementById("trackingProtectionRadioGroup");
// Global enable takes precedence over enabled in Private Browsing.
radiogroup.value = enabledPref.value ? "always" :
pbmPref.value ? "private" :
"never";
},
/**
* Sets the pref values based on the selected item of the radiogroup.
*/
trackingProtectionWritePrefs() {
let enabledPref = document.getElementById("privacy.trackingprotection.enabled");
let pbmPref = document.getElementById("privacy.trackingprotection.pbmode.enabled");
let radiogroup = document.getElementById("trackingProtectionRadioGroup");
switch (radiogroup.value) {
case "always":
enabledPref.value = true;
pbmPref.value = true;
break;
case "private":
enabledPref.value = false;
pbmPref.value = true;
break;
case "never":
enabledPref.value = false;
pbmPref.value = false;
break;
}
}, },
// HISTORY MODE // HISTORY MODE
@ -371,6 +424,21 @@ var gPrivacyPane = {
this._shouldPromptForRestart = true; this._shouldPromptForRestart = true;
}, },
/**
* Displays fine-grained, per-site preferences for tracking protection.
*/
showTrackingProtectionExceptions() {
let bundlePreferences = document.getElementById("bundlePreferences");
let params = {
permissionType: "trackingprotection",
hideStatusColumn: true,
windowTitle: bundlePreferences.getString("trackingprotectionpermissionstitle"),
introText: bundlePreferences.getString("trackingprotectionpermissionstext"),
};
gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
null, params);
},
/** /**
* Displays the available block lists for tracking protection. * Displays the available block lists for tracking protection.
*/ */
@ -386,6 +454,14 @@ var gPrivacyPane = {
null, params); null, params);
}, },
/**
* Displays the Do Not Track settings dialog.
*/
showDoNotTrackSettings() {
gSubDialog.open("chrome://browser/content/preferences/donottrack.xul",
"resizable=no");
},
// HISTORY // HISTORY
/* /*

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

@ -10,9 +10,6 @@
<preferences id="privacyPreferences" hidden="true" data-category="panePrivacy"> <preferences id="privacyPreferences" hidden="true" data-category="panePrivacy">
<!-- Tracking --> <!-- Tracking -->
<preference id="privacy.donottrackheader.enabled"
name="privacy.donottrackheader.enabled"
type="bool"/>
<preference id="privacy.trackingprotection.enabled" <preference id="privacy.trackingprotection.enabled"
name="privacy.trackingprotection.enabled" name="privacy.trackingprotection.enabled"
type="bool"/> type="bool"/>
@ -30,6 +27,9 @@
<preference id="pref.privacy.disable_button.change_blocklist" <preference id="pref.privacy.disable_button.change_blocklist"
name="pref.privacy.disable_button.change_blocklist" name="pref.privacy.disable_button.change_blocklist"
type="bool"/> type="bool"/>
<preference id="pref.privacy.disable_button.tracking_protection_exceptions"
name="pref.privacy.disable_button.tracking_protection_exceptions"
type="bool"/>
<!-- Location Bar --> <!-- Location Bar -->
<preference id="browser.urlbar.autocomplete.enabled" <preference id="browser.urlbar.autocomplete.enabled"
@ -87,32 +87,40 @@
<!-- Tracking --> <!-- Tracking -->
<groupbox id="trackingGroup" data-category="panePrivacy" hidden="true"> <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true">
<caption><label>&tracking.label;</label></caption>
<vbox>
<hbox align="center">
<checkbox id="privacyDoNotTrackCheckbox"
label="&dntTrackingNotOkay4.label;"
accesskey="&dntTrackingNotOkay4.accesskey;"
preference="privacy.donottrackheader.enabled"/>
<label id="doNotTrackInfo"
class="text-link"
href="https://www.mozilla.org/dnt">
&doNotTrackInfo.label;
</label>
</hbox>
</vbox>
<vbox id="trackingprotectionbox" hidden="true"> <vbox id="trackingprotectionbox" hidden="true">
<hbox align="center"> <hbox align="start">
<checkbox id="trackingProtection" <vbox>
preference="privacy.trackingprotection.enabled" <caption><label>&trackingProtectionHeader.label;
accesskey="&trackingProtection5.accesskey;" <label id="trackingProtectionLearnMore" class="text-link"
label="&trackingProtection5.label;" />
<label id="trackingProtectionLearnMore"
class="text-link"
value="&trackingProtectionLearnMore.label;"/> value="&trackingProtectionLearnMore.label;"/>
</label></caption>
<radiogroup id="trackingProtectionRadioGroup">
<radio value="always"
label="&trackingProtectionAlways.label;"
accesskey="&trackingProtectionAlways.accesskey;"/>
<radio value="private"
label="&trackingProtectionPrivate.label;"
accesskey="&trackingProtectionPrivate.accesskey;"/>
<radio value="never"
label="&trackingProtectionNever.label;"
accesskey="&trackingProtectionNever.accesskey;"/>
</radiogroup>
</vbox>
<spacer flex="1" />
<vbox>
<button id="trackingProtectionExceptions"
label="&trackingProtectionExceptions.label;"
accesskey="&trackingProtectionExceptions.accesskey;"
preference="pref.privacy.disable_button.tracking_protection_exceptions"/>
<button id="changeBlockList"
label="&changeBlockList.label;"
accesskey="&changeBlockList.accesskey;"
preference="pref.privacy.disable_button.change_blocklist"/>
</vbox>
</hbox> </hbox>
</vbox> </vbox>
<vbox id="trackingprotectionpbmbox"> <vbox id="trackingprotectionpbmbox">
<caption><label>&tracking.label;</label></caption>
<hbox align="center"> <hbox align="center">
<checkbox id="trackingProtectionPBM" <checkbox id="trackingProtectionPBM"
preference="privacy.trackingprotection.pbmode.enabled" preference="privacy.trackingprotection.pbmode.enabled"
@ -122,11 +130,16 @@
class="text-link" class="text-link"
value="&trackingProtectionPBMLearnMore.label;"/> value="&trackingProtectionPBMLearnMore.label;"/>
<spacer flex="1" /> <spacer flex="1" />
<button id="changeBlockList" <button id="changeBlockListPBM"
label="&changeBlockList.label;" accesskey="&changeBlockList.accesskey;" label="&changeBlockList.label;" accesskey="&changeBlockList.accesskey;"
preference="pref.privacy.disable_button.change_blocklist"/> preference="pref.privacy.disable_button.change_blocklist"/>
</hbox> </hbox>
</vbox> </vbox>
<vbox>
<description>&doNotTrack.pre.label;<html:a
class="inline-link" id="doNotTrackSettings" href="#"
>&doNotTrack.settings.label;</html:a>&doNotTrack.post.label;</description>
</vbox>
</groupbox> </groupbox>
<!-- History --> <!-- History -->

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

@ -97,7 +97,7 @@ var gSubDialog = {
handleEvent: function(aEvent) { handleEvent: function(aEvent) {
switch (aEvent.type) { switch (aEvent.type) {
case "command": case "command":
this.close(aEvent); this._frame.contentWindow.close();
break; break;
case "dialogclosing": case "dialogclosing":
this._onDialogClosing(aEvent); this._onDialogClosing(aEvent);
@ -127,7 +127,7 @@ var gSubDialog = {
_onUnload: function(aEvent) { _onUnload: function(aEvent) {
if (aEvent.target.location.href == this._openedURL) { if (aEvent.target.location.href == this._openedURL) {
this.close(this._closingEvent); this._frame.contentWindow.close();
} }
}, },

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

@ -32,7 +32,6 @@ skip-if = e10s # Bug ?????? - "leaked until shutdown [nsGlobalWindow #99 about:
[browser_sanitizeOnShutdown_prefLocked.js] [browser_sanitizeOnShutdown_prefLocked.js]
[browser_searchsuggestions.js] [browser_searchsuggestions.js]
[browser_subdialogs.js] [browser_subdialogs.js]
skip-if = e10s # Bug 1087114
support-files = subdialog.xul support-files = subdialog.xul
[browser_telemetry.js] [browser_telemetry.js]
# Skip this test on Android and B2G as FHR and Telemetry are separate systems there. # Skip this test on Android and B2G as FHR and Telemetry are separate systems there.

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

@ -7,175 +7,195 @@
* Tests for the sub-dialog infrastructure, not for actual sub-dialog functionality. * Tests for the sub-dialog infrastructure, not for actual sub-dialog functionality.
*/ */
var gTeardownAfterClose = false;
const gDialogURL = getRootDirectory(gTestPath) + "subdialog.xul"; const gDialogURL = getRootDirectory(gTestPath) + "subdialog.xul";
function test() { function* open_subdialog_and_test_generic_start_state(browser, domcontentloadedFn) {
waitForExplicitFinish(); let domcontentloadedFnStr = domcontentloadedFn ?
open_preferences((win) => { "(" + domcontentloadedFn.toString() + ")()" :
Task.spawn(function () { "";
for (let test of gTests) { return ContentTask.spawn(browser, {gDialogURL, domcontentloadedFnStr}, function*(args) {
info("STARTING TEST: " + test.desc); let {gDialogURL, domcontentloadedFnStr} = args;
try { let rv = { acceptCount: 0 };
yield test.run(); let win = content.window;
} finally { let subdialog = win.gSubDialog;
if (test.teardown) { subdialog.open(gDialogURL, null, rv);
yield test.teardown();
info("waiting for subdialog DOMFrameContentLoaded");
yield ContentTaskUtils.waitForEvent(win, "DOMFrameContentLoaded", true);
let result;
if (domcontentloadedFnStr) {
result = eval(domcontentloadedFnStr);
}
info("waiting for subdialog load");
yield ContentTaskUtils.waitForEvent(subdialog._frame, "load");
info("subdialog window is loaded");
let expectedStyleSheetURLs = subdialog._injectedStyleSheets.slice(0);
for (let styleSheet of subdialog._frame.contentDocument.styleSheets) {
let index = expectedStyleSheetURLs.indexOf(styleSheet.href);
if (index >= 0) {
expectedStyleSheetURLs.splice(index, 1);
} }
} }
}
}); ok(!!subdialog._frame.contentWindow, "The dialog should be non-null");
isnot(subdialog._frame.contentWindow.location.toString(), "about:blank",
"Subdialog URL should not be about:blank");
is(win.getComputedStyle(subdialog._overlay, "").visibility, "visible",
"Overlay should be visible");
is(expectedStyleSheetURLs.length, 0,
"No stylesheets that were expected are missing");
return result;
}); });
} }
var gTests = [{ function* close_subdialog_and_test_generic_end_state(browser, closingFn, closingButton, acceptCount, options) {
desc: "Check titlebar, focus, return value, title changes, and accepting", let dialogclosingPromise = ContentTask.spawn(browser, {closingButton, acceptCount}, function*(expectations) {
run: function* () { let win = content.window;
let rv = { acceptCount: 0 }; let subdialog = win.gSubDialog;
let deferredClose = Promise.defer(); let frame = subdialog._frame;
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, rv, info("waiting for dialogclosing");
(aEvent) => dialogClosingCallback(deferredClose, aEvent)); let closingEvent =
let dialog = yield dialogPromise; yield ContentTaskUtils.waitForEvent(frame.contentWindow, "dialogclosing");
let actualAcceptCount = frame.contentWindow.arguments &&
frame.contentWindow.arguments[0].acceptCount;
// Check focus is in the textbox info("waiting for about:blank load");
is(dialog.document.activeElement.value, "Default text", "Textbox with correct text is focused"); yield ContentTaskUtils.waitForEvent(frame, "load");
// Titlebar isnot(win.getComputedStyle(subdialog._overlay, "").visibility, "visible",
is(content.document.getElementById("dialogTitle").textContent, "Sample sub-dialog", "overlay is not visible");
"Dialog title should be correct initially"); is(frame.getAttribute("style"), "", "inline styles should be cleared");
let receivedEvent = waitForEvent(gBrowser.selectedBrowser, "DOMTitleChanged"); is(frame.contentWindow.location.href.toString(), "about:blank",
"sub-dialog should be unloaded");
is(closingEvent.detail.button, expectations.closingButton,
"closing event should indicate button was '" + expectations.closingButton + "'");
is(actualAcceptCount, expectations.acceptCount,
"should be 1 if accepted, 0 if canceled, undefined if closed w/out button");
});
if (options && options.runClosingFnOutsideOfContentTask) {
yield closingFn();
} else {
ContentTask.spawn(browser, null, closingFn);
}
yield dialogclosingPromise;
}
let tab;
add_task(function* test_initialize() {
tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
});
add_task(function* check_titlebar_focus_returnval_titlechanges_accepting() {
yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
let domtitlechangedPromise = BrowserTestUtils.waitForEvent(tab.linkedBrowser, "DOMTitleChanged");
yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
let dialog = content.window.gSubDialog._frame.contentWindow;
let dialogTitleElement = content.document.getElementById("dialogTitle");
is(dialogTitleElement.textContent, "Sample sub-dialog",
"Title should be correct initially");
is(dialog.document.activeElement.value, "Default text",
"Textbox with correct text is focused");
dialog.document.title = "Updated title"; dialog.document.title = "Updated title";
// Wait for the title change listener });
yield receivedEvent;
is(content.document.getElementById("dialogTitle").textContent, "Updated title",
"Dialog title should be updated with changes");
let closingPromise = promiseDialogClosing(dialog); info("waiting for DOMTitleChanged event");
yield domtitlechangedPromise;
ContentTask.spawn(tab.linkedBrowser, null, function*() {
let dialogTitleElement = content.document.getElementById("dialogTitle");
is(dialogTitleElement.textContent, "Updated title", "subdialog should have updated title");
});
// Accept the dialog // Accept the dialog
dialog.document.documentElement.acceptDialog(); yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
let closingEvent = yield closingPromise; function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
is(closingEvent.detail.button, "accept", "closing event should indicate button was 'accept'"); "accept", 1);
});
yield deferredClose.promise; add_task(function* check_canceling_dialog() {
is(rv.acceptCount, 1, "return value should have been updated"); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
},
},
{
desc: "Check canceling the dialog",
run: function* () {
let rv = { acceptCount: 0 };
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, rv,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let dialog = yield dialogPromise;
let closingPromise = promiseDialogClosing(dialog); info("canceling the dialog");
yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
function() { content.window.gSubDialog._frame.contentDocument.documentElement.cancelDialog(); },
"cancel", 0);
});
info("cancelling the dialog"); add_task(function* window_close_on_dialog() {
dialog.document.documentElement.cancelDialog(); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
let closingEvent = yield closingPromise; info("canceling the dialog");
is(closingEvent.detail.button, "cancel", "closing event should indicate button was 'cancel'"); yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
null, 0);
});
yield deferredClose.promise; add_task(function* click_close_button_on_dialog() {
is(rv.acceptCount, 0, "return value should NOT have been updated"); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
},
},
{
desc: "Check window.close on the dialog",
run: function* () {
let rv = { acceptCount: 0 };
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, rv,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let dialog = yield dialogPromise;
let closingPromise = promiseDialogClosing(dialog); info("canceling the dialog");
info("window.close called on the dialog"); yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
dialog.window.close(); function() { return BrowserTestUtils.synthesizeMouseAtCenter("#dialogClose", {}, tab.linkedBrowser); },
null, 0, {runClosingFnOutsideOfContentTask: true});
});
let closingEvent = yield closingPromise; add_task(function* back_navigation_on_subdialog_should_close_dialog() {
is(closingEvent.detail.button, null, "closing event should indicate no button was clicked"); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
yield deferredClose.promise; info("canceling the dialog");
is(rv.acceptCount, 0, "return value should NOT have been updated"); yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
}, function() { content.window.gSubDialog._frame.goBack(); },
}, null, undefined);
{ });
desc: "Check clicking the close button on the dialog",
run: function* () {
let rv = { acceptCount: 0 };
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, rv,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let dialog = yield dialogPromise;
yield EventUtils.synthesizeMouseAtCenter(content.document.getElementById("dialogClose"), {}, add_task(function* back_navigation_on_browser_tab_should_close_dialog() {
content.window); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
yield deferredClose.promise; info("canceling the dialog");
is(rv.acceptCount, 0, "return value should NOT have been updated"); yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
}, function() { tab.linkedBrowser.goBack(); },
}, null, undefined, {runClosingFnOutsideOfContentTask: true});
{ });
desc: "Check that 'back' navigation will close the dialog",
run: function* () {
let rv = { acceptCount: 0 };
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, rv,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let dialog = yield dialogPromise;
info("cancelling the dialog"); add_task(function* escape_should_close_dialog() {
content.gSubDialog._frame.goBack(); todo(false, "BrowserTestUtils.sendChar('VK_ESCAPE') triggers " +
"'can't access dead object' on `navigator` in this test. " +
"See bug 1238065.")
return;
yield deferredClose.promise; yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
is(rv.acceptCount, 0, "return value should NOT have been updated");
},
},
{
desc: "Hitting escape in the dialog",
run: function* () {
let rv = { acceptCount: 0 };
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, rv,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let dialog = yield dialogPromise;
EventUtils.synthesizeKey("VK_ESCAPE", {}, content.window); info("canceling the dialog");
yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
function() { return BrowserTestUtils.sendChar("VK_ESCAPE", tab.linkedBrowser); },
null, undefined, {runClosingFnOutsideOfContentTask: true});
});
yield deferredClose.promise; add_task(function* correct_width_and_height_should_be_used_for_dialog() {
is(rv.acceptCount, 0, "return value should NOT have been updated"); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
},
},
{
desc: "Check that width and height from the sub-dialog are used to size the <browser>",
run: function* () {
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, null,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let dialog = yield dialogPromise;
is(content.gSubDialog._frame.style.width, "32em", "Width should be set on the frame from the dialog"); yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
is(content.gSubDialog._frame.style.height, "5em", "Height should be set on the frame from the dialog"); let frameStyle = content.window.gSubDialog._frame.style;
is(frameStyle.width, "32em", "Width should be set on the frame from the dialog");
is(frameStyle.height, "5em", "Height should be set on the frame from the dialog");
});
content.gSubDialog.close(); yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
yield deferredClose.promise; function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
}, null, 0);
}, });
{
desc: "Check that a set width and content causing wrapping still lead to correct scrollHeight-implied height",
run: function* () {
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, null,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
let oldHeight; add_task(function* wrapped_text_in_dialog_should_have_expected_scrollHeight() {
content.addEventListener("DOMFrameContentLoaded", function frame2Loaded() { let oldHeight = yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
content.removeEventListener("DOMFrameContentLoaded", frame2Loaded); let frame = content.window.gSubDialog._frame;
let doc = content.gSubDialog._frame.contentDocument; let doc = frame.contentDocument;
oldHeight = doc.documentElement.scrollHeight; let oldHeight = doc.documentElement.scrollHeight;
doc.documentElement.style.removeProperty("height"); doc.documentElement.style.removeProperty("height");
doc.getElementById("desc").textContent = ` doc.getElementById("desc").textContent = `
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
@ -189,86 +209,63 @@ var gTests = [{
architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
voluptatem sequi nesciunt.` voluptatem sequi nesciunt.`
doc = null; return oldHeight;
}); });
let dialog = yield dialogPromise; yield ContentTask.spawn(tab.linkedBrowser, oldHeight, function*(oldHeight) {
let frame = content.window.gSubDialog._frame;
is(content.gSubDialog._frame.style.width, "32em", "Width should be set on the frame from the dialog"); let docEl = frame.contentDocument.documentElement;
let docEl = content.gSubDialog._frame.contentDocument.documentElement; is(frame.style.width, "32em",
ok(docEl.scrollHeight > oldHeight, "Content height increased (from " + oldHeight + " to " + docEl.scrollHeight + ")."); "Width should be set on the frame from the dialog");
is(content.gSubDialog._frame.style.height, docEl.scrollHeight + "px", "Height on the frame should be higher now"); ok(docEl.scrollHeight > oldHeight,
"Content height increased (from " + oldHeight + " to " + docEl.scrollHeight + ").");
content.gSubDialog.close(); is(frame.style.height, docEl.scrollHeight + "px",
yield deferredClose.promise; "Height on the frame should be higher now");
},
},
{
desc: "Check that a dialog that is too high gets cut down to size",
run: function* () {
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, null,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
content.addEventListener("DOMFrameContentLoaded", function frame3Loaded() {
content.removeEventListener("DOMFrameContentLoaded", frame3Loaded);
content.gSubDialog._frame.contentDocument.documentElement.style.height = '100000px';
}); });
let dialog = yield dialogPromise; yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
null, 0);
});
is(content.gSubDialog._frame.style.width, "32em", "Width should be set on the frame from the dialog"); add_task(function* dialog_too_tall_should_get_reduced_in_height() {
let newHeight = content.gSubDialog._frame.contentDocument.documentElement.scrollHeight; yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
ok(parseInt(content.gSubDialog._frame.style.height) < window.innerHeight, let frame = content.window.gSubDialog._frame;
frame.contentDocument.documentElement.style.height = '100000px';
});
yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
let frame = content.window.gSubDialog._frame;
is(frame.style.width, "32em", "Width should be set on the frame from the dialog");
ok(parseInt(frame.style.height) < content.window.innerHeight,
"Height on the frame should be smaller than window's innerHeight"); "Height on the frame should be smaller than window's innerHeight");
content.gSubDialog.close();
yield deferredClose.promise;
}
},
{
desc: "Check that scrollWidth and scrollHeight from the sub-dialog are used to size the <browser>",
run: function* () {
let deferredClose = Promise.defer();
let dialogPromise = openAndLoadSubDialog(gDialogURL, null, null,
(aEvent) => dialogClosingCallback(deferredClose, aEvent));
content.addEventListener("DOMFrameContentLoaded", function frameLoaded() {
content.removeEventListener("DOMFrameContentLoaded", frameLoaded);
content.gSubDialog._frame.contentDocument.documentElement.style.removeProperty("height");
content.gSubDialog._frame.contentDocument.documentElement.style.removeProperty("width");
}); });
let dialog = yield dialogPromise; yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
null, 0);
});
ok(content.gSubDialog._frame.style.width.endsWith("px"), add_task(function* scrollWidth_and_scrollHeight_from_subdialog_should_size_the_browser() {
"Width (" + content.gSubDialog._frame.style.width + ") should be set to a px value of the scrollWidth from the dialog"); yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
ok(content.gSubDialog._frame.style.height.endsWith("px"), let frame = content.window.gSubDialog._frame;
"Height (" + content.gSubDialog._frame.style.height + ") should be set to a px value of the scrollHeight from the dialog"); frame.contentDocument.documentElement.style.removeProperty("height");
frame.contentDocument.documentElement.style.removeProperty("width");
});
gTeardownAfterClose = true; yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
content.gSubDialog.close(); let frame = content.window.gSubDialog._frame;
yield deferredClose.promise; ok(frame.style.width.endsWith("px"),
}, "Width (" + frame.style.width + ") should be set to a px value of the scrollWidth from the dialog");
}]; ok(frame.style.height.endsWith("px"),
"Height (" + frame.style.height + ") should be set to a px value of the scrollHeight from the dialog");
});
function promiseDialogClosing(dialog) { yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
return waitForEvent(dialog, "dialogclosing"); function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
} null, 0);
});
function dialogClosingCallback(aPromise, aEvent) { add_task(function* test_shutdown() {
// Wait for the close handler to unload the page gBrowser.removeTab(tab);
waitForEvent(content.gSubDialog._frame, "load", 4000).then((aEvt) => { });
info("Load event happened: " + !(aEvt instanceof Error));
is_element_hidden(content.gSubDialog._overlay, "Overlay is not visible");
is(content.gSubDialog._frame.getAttribute("style"), "",
"Check that inline styles were cleared");
is(content.gSubDialog._frame.contentWindow.location.toString(), "about:blank",
"Check the sub-dialog was unloaded");
if (gTeardownAfterClose) {
content.close();
finish();
}
aPromise.resolve();
}, Cu.reportError);
}

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

@ -12,6 +12,7 @@ browser.jar:
* content/browser/preferences/cookies.js * content/browser/preferences/cookies.js
* content/browser/preferences/connection.xul * content/browser/preferences/connection.xul
content/browser/preferences/connection.js content/browser/preferences/connection.js
content/browser/preferences/donottrack.xul
* content/browser/preferences/fonts.xul * content/browser/preferences/fonts.xul
content/browser/preferences/fonts.js content/browser/preferences/fonts.js
content/browser/preferences/handlers.xml content/browser/preferences/handlers.xml

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

@ -249,6 +249,10 @@ var gPermissionManager = {
var urlLabel = document.getElementById("urlLabel"); var urlLabel = document.getElementById("urlLabel");
urlLabel.hidden = !urlFieldVisible; urlLabel.hidden = !urlFieldVisible;
if (aParams.hideStatusColumn) {
document.getElementById("statusCol").hidden = true;
}
let treecols = document.getElementsByTagName("treecols")[0]; let treecols = document.getElementsByTagName("treecols")[0];
treecols.addEventListener("click", event => { treecols.addEventListener("click", event => {
if (event.target.nodeName != "treecol" || event.button != 0) { if (event.target.nodeName != "treecol" || event.button != 0) {

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

@ -130,8 +130,7 @@
<property name="currentEngine"> <property name="currentEngine">
<setter><![CDATA[ <setter><![CDATA[
let ss = Services.search; Services.search.currentEngine = val;
ss.defaultEngine = ss.currentEngine = val;
return val; return val;
]]></setter> ]]></setter>
<getter><![CDATA[ <getter><![CDATA[

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

@ -530,13 +530,18 @@ this.UITour = {
} }
let infoOptions = {}; let infoOptions = {};
if (typeof data.closeButtonCallbackID == "string") {
infoOptions.closeButtonCallback = () => {
this.sendPageCallback(messageManager, data.closeButtonCallbackID);
};
}
if (typeof data.targetCallbackID == "string") {
infoOptions.targetCallback = details => {
this.sendPageCallback(messageManager, data.targetCallbackID, details);
};
}
if (typeof data.closeButtonCallbackID == "string") this.showInfo(window, target, data.title, data.text, iconURL, buttons, infoOptions);
infoOptions.closeButtonCallbackID = data.closeButtonCallbackID;
if (typeof data.targetCallbackID == "string")
infoOptions.targetCallbackID = data.targetCallbackID;
this.showInfo(window, messageManager, target, data.title, data.text, iconURL, buttons, infoOptions);
}).catch(log.error); }).catch(log.error);
break; break;
} }
@ -1395,17 +1400,17 @@ this.UITour = {
* Show an info panel. * Show an info panel.
* *
* @param {ChromeWindow} aChromeWindow * @param {ChromeWindow} aChromeWindow
* @param {nsIMessageSender} aMessageManager
* @param {Node} aAnchor * @param {Node} aAnchor
* @param {String} [aTitle=""] * @param {String} [aTitle=""]
* @param {String} [aDescription=""] * @param {String} [aDescription=""]
* @param {String} [aIconURL=""] * @param {String} [aIconURL=""]
* @param {Object[]} [aButtons=[]] * @param {Object[]} [aButtons=[]]
* @param {Object} [aOptions={}] * @param {Object} [aOptions={}]
* @param {String} [aOptions.closeButtonCallbackID] * @param {String} [aOptions.closeButtonCallback]
* @param {String} [aOptions.targetCallback]
*/ */
showInfo: function(aChromeWindow, aMessageManager, aAnchor, aTitle = "", aDescription = "", aIconURL = "", showInfo(aChromeWindow, aAnchor, aTitle = "", aDescription = "",
aButtons = [], aOptions = {}) { aIconURL = "", aButtons = [], aOptions = {}) {
function showInfoPanel(aAnchorEl) { function showInfoPanel(aAnchorEl) {
aAnchorEl.focus(); aAnchorEl.focus();
@ -1461,8 +1466,9 @@ this.UITour = {
let tooltipClose = document.getElementById("UITourTooltipClose"); let tooltipClose = document.getElementById("UITourTooltipClose");
let closeButtonCallback = (event) => { let closeButtonCallback = (event) => {
this.hideInfo(document.defaultView); this.hideInfo(document.defaultView);
if (aOptions && aOptions.closeButtonCallbackID) if (aOptions && aOptions.closeButtonCallback) {
this.sendPageCallback(aMessageManager, aOptions.closeButtonCallbackID); aOptions.closeButtonCallback();
}
}; };
tooltipClose.addEventListener("command", closeButtonCallback); tooltipClose.addEventListener("command", closeButtonCallback);
@ -1471,16 +1477,16 @@ this.UITour = {
target: aAnchor.targetName, target: aAnchor.targetName,
type: event.type, type: event.type,
}; };
this.sendPageCallback(aMessageManager, aOptions.targetCallbackID, details); aOptions.targetCallback(details);
}; };
if (aOptions.targetCallbackID && aAnchor.addTargetListener) { if (aOptions.targetCallback && aAnchor.addTargetListener) {
aAnchor.addTargetListener(document, targetCallback); aAnchor.addTargetListener(document, targetCallback);
} }
tooltip.addEventListener("popuphiding", function tooltipHiding(event) { tooltip.addEventListener("popuphiding", function tooltipHiding(event) {
tooltip.removeEventListener("popuphiding", tooltipHiding); tooltip.removeEventListener("popuphiding", tooltipHiding);
tooltipClose.removeEventListener("command", closeButtonCallback); tooltipClose.removeEventListener("command", closeButtonCallback);
if (aOptions.targetCallbackID && aAnchor.removeTargetListener) { if (aOptions.targetCallback && aAnchor.removeTargetListener) {
aAnchor.removeTargetListener(document, targetCallback); aAnchor.removeTargetListener(document, targetCallback);
} }
}); });

31
browser/extensions/pocket/bootstrap.js поставляемый
Просмотреть файл

@ -25,6 +25,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "Pocket",
XPCOMUtils.defineLazyGetter(this, "gPocketBundle", function() { XPCOMUtils.defineLazyGetter(this, "gPocketBundle", function() {
return Services.strings.createBundle("chrome://pocket/locale/pocket.properties"); return Services.strings.createBundle("chrome://pocket/locale/pocket.properties");
}); });
XPCOMUtils.defineLazyGetter(this, "gPocketStyleURI", function() {
return Services.io.newURI("chrome://pocket/skin/pocket.css", null, null);
});
const PREF_BRANCH = "extensions.pocket."; const PREF_BRANCH = "extensions.pocket.";
@ -286,10 +289,12 @@ function pktUIGetter(prop, window) {
var PocketOverlay = { var PocketOverlay = {
startup: function(reason) { startup: function(reason) {
let styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"]
.getService(Ci.nsIStyleSheetService);
this._sheetType = styleSheetService.AUTHOR_SHEET;
this._cachedSheet = styleSheetService.preloadSheet(gPocketStyleURI,
this._sheetType);
CreatePocketWidget(reason); CreatePocketWidget(reason);
Services.obs.addObserver(this,
"browser-delayed-startup-finished",
false);
CustomizableUI.addListener(this); CustomizableUI.addListener(this);
PocketContextMenu.init(); PocketContextMenu.init();
PocketReader.startup(); PocketReader.startup();
@ -322,9 +327,7 @@ var PocketOverlay = {
PocketContextMenu.shutdown(); PocketContextMenu.shutdown();
PocketReader.shutdown(); PocketReader.shutdown();
}, },
observe: function(aSubject, aTopic, aData) { onWindowOpened: function(window) {
// new browser window, initialize the "overlay"
let window = aSubject;
this.setWindowScripts(window); this.setWindowScripts(window);
this.addStyles(window); this.addStyles(window);
this.updateWindow(window); this.updateWindow(window);
@ -435,21 +438,13 @@ var PocketOverlay = {
}, },
addStyles: function(win) { addStyles: function(win) {
let xmlPI = win.document.createProcessingInstruction("xml-stylesheet", let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
"type=\"text/css\" href=\"chrome://pocket/skin/pocket.css\""); utils.addSheet(this._cachedSheet, this._sheetType);
win.document.insertBefore(xmlPI, win.document.documentElement);
}, },
removeStyles: function(win) { removeStyles: function(win) {
let el = win.document.documentElement.previousSibling; let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
while (el) { utils.removeSheet(gPocketStyleURI, this._sheetType);
if (el.nodeType == el.PROCESSING_INSTRUCTION_NODE &&
el.sheet && el.sheet.href == "chrome://pocket/skin/pocket.css") {
el.remove();
break;
}
el = el.previousSibling;
}
} }
} }

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

@ -0,0 +1,12 @@
<!-- 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/. -->
<!ENTITY window.title "Do Not Track">
<!ENTITY window.width "40em">
<!ENTITY window.height "8em">
<!ENTITY doNotTrackCheckbox.label "Use Do Not Track">
<!ENTITY doNotTrackCheckbox.accesskey "U">
<!ENTITY doNotTrackLearnMore.label "Learn More">

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

@ -19,6 +19,8 @@ acceptVeryLargeMinimumFont=Keep my changes anyway
#### Permissions Manager #### Permissions Manager
trackingprotectionpermissionstext=You have disabled Tracking Protection on these sites.
trackingprotectionpermissionstitle=Exceptions - Tracking Protection
cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow. cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow.
cookiepermissionstitle=Exceptions - Cookies cookiepermissionstitle=Exceptions - Cookies
addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow. addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow.

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

@ -2,20 +2,30 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this - 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/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY tracking.label "Tracking"> <!ENTITY trackingProtectionHeader.label "Use Tracking Protection">
<!ENTITY trackingProtectionAlways.label "Always">
<!ENTITY dntTrackingNotOkay4.label "Request that sites not track you"> <!ENTITY trackingProtectionAlways.accesskey "y">
<!ENTITY dntTrackingNotOkay4.accesskey "n"> <!ENTITY trackingProtectionPrivate.label "Only in private windows">
<!ENTITY doNotTrackInfo.label "Learn More"> <!ENTITY trackingProtectionPrivate.accesskey "l">
<!ENTITY trackingProtection5.label "Use Tracking Protection"> <!ENTITY trackingProtectionNever.label "Never">
<!ENTITY trackingProtection5.accesskey "i"> <!ENTITY trackingProtectionNever.accesskey "n">
<!ENTITY trackingProtectionLearnMore.label "Learn more"> <!ENTITY trackingProtectionLearnMore.label "Learn more">
<!ENTITY trackingProtectionExceptions.label "Exceptions…">
<!ENTITY trackingProtectionExceptions.accesskey "x">
<!ENTITY tracking.label "Tracking">
<!ENTITY trackingProtectionPBM5.label "Use Tracking Protection in Private Windows"> <!ENTITY trackingProtectionPBM5.label "Use Tracking Protection in Private Windows">
<!ENTITY trackingProtectionPBM5.accesskey "v"> <!ENTITY trackingProtectionPBM5.accesskey "v">
<!ENTITY trackingProtectionPBMLearnMore.label "Learn more"> <!ENTITY trackingProtectionPBMLearnMore.label "Learn more">
<!ENTITY changeBlockList.label "Change Block List"> <!ENTITY changeBlockList.label "Change Block List">
<!ENTITY changeBlockList.accesskey "C"> <!ENTITY changeBlockList.accesskey "C">
<!-- LOCALIZATION NOTE (doNotTrack.pre.label): include a trailing space as needed -->
<!-- LOCALIZATION NOTE (doNotTrack.post.label): include a starting space as needed -->
<!ENTITY doNotTrack.pre.label "You can also ">
<!ENTITY doNotTrack.settings.label "manage your Do Not Track settings">
<!ENTITY doNotTrack.post.label ".">
<!ENTITY history.label "History"> <!ENTITY history.label "History">
<!ENTITY locationBar.label "Location Bar"> <!ENTITY locationBar.label "Location Bar">

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

@ -70,6 +70,7 @@
locale/browser/preferences/cookies.dtd (%chrome/browser/preferences/cookies.dtd) locale/browser/preferences/cookies.dtd (%chrome/browser/preferences/cookies.dtd)
locale/browser/preferences/content.dtd (%chrome/browser/preferences/content.dtd) locale/browser/preferences/content.dtd (%chrome/browser/preferences/content.dtd)
locale/browser/preferences/connection.dtd (%chrome/browser/preferences/connection.dtd) locale/browser/preferences/connection.dtd (%chrome/browser/preferences/connection.dtd)
locale/browser/preferences/donottrack.dtd (%chrome/browser/preferences/donottrack.dtd)
locale/browser/preferences/applications.dtd (%chrome/browser/preferences/applications.dtd) locale/browser/preferences/applications.dtd (%chrome/browser/preferences/applications.dtd)
locale/browser/preferences/fonts.dtd (%chrome/browser/preferences/fonts.dtd) locale/browser/preferences/fonts.dtd (%chrome/browser/preferences/fonts.dtd)
locale/browser/preferences/main.dtd (%chrome/browser/preferences/main.dtd) locale/browser/preferences/main.dtd (%chrome/browser/preferences/main.dtd)

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

@ -189,7 +189,7 @@ var ReaderParent = {
} else { } else {
icon += "reader-tour.png"; icon += "reader-tour.png";
} }
UITour.showInfo(win, browser.messageManager, target, UITour.showInfo(win, target,
browserBundle.GetStringFromName("readingList.promo.firstUse.readerView.title"), browserBundle.GetStringFromName("readingList.promo.firstUse.readerView.title"),
browserBundle.GetStringFromName("readingList.promo.firstUse.readerView.body"), browserBundle.GetStringFromName("readingList.promo.firstUse.readerView.body"),
icon); icon);

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

@ -16,10 +16,11 @@
%define forwardTransitionLength 150ms %define forwardTransitionLength 150ms
%define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper %define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
%define conditionalForwardWithUrlbarWidth 31
:root { :root {
--backbutton-urlbar-overlap: 6px; --backbutton-urlbar-overlap: 6px;
/* icon width + border + horizontal padding (includes the overlap from backbutton-urlbar-overlap) */
--forwardbutton-width: 31px;
--toolbarbutton-hover-background: rgba(255,255,255,.5) linear-gradient(rgba(255,255,255,.5), transparent); --toolbarbutton-hover-background: rgba(255,255,255,.5) linear-gradient(rgba(255,255,255,.5), transparent);
--toolbarbutton-hover-bordercolor: rgba(0,0,0,.25); --toolbarbutton-hover-bordercolor: rgba(0,0,0,.25);
@ -743,7 +744,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
padding-right: 3px; padding-right: 3px;
border-left-style: none; border-left-style: none;
border-radius: 0; border-radius: 0;
max-width: @conditionalForwardWithUrlbarWidth@px; max-width: var(--forwardbutton-width);
} }
@conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button { @conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button {
@ -751,7 +752,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
} }
@conditionalForwardWithUrlbar@ > #forward-button[disabled] { @conditionalForwardWithUrlbar@ > #forward-button[disabled] {
margin-left: -@conditionalForwardWithUrlbarWidth@px; margin-left: calc(0px - var(--forwardbutton-width));
} }
@conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] { @conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] {
@ -761,7 +762,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
@conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] { @conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
/* when not hovered anymore, trigger a new transition to hide the forward button immediately */ /* when not hovered anymore, trigger a new transition to hide the forward button immediately */
margin-left: -@conditionalForwardWithUrlbarWidth@.01px; margin-left: calc(-0.01px - var(--forwardbutton-width));
} }
/* undo close tab menu item */ /* undo close tab menu item */

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

@ -4,6 +4,10 @@
%include ../shared/devedition.inc.css %include ../shared/devedition.inc.css
:root {
--forwardbutton-width: 29px;
}
:root[devtoolstheme="dark"] .findbar-closebutton:not(:hover), :root[devtoolstheme="dark"] .findbar-closebutton:not(:hover),
:root[devtoolstheme="dark"] #sidebar-header > .close-icon:not(:hover), :root[devtoolstheme="dark"] #sidebar-header > .close-icon:not(:hover),
.tab-close-button[visuallyselected]:not(:hover) { .tab-close-button[visuallyselected]:not(:hover) {

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

@ -8,7 +8,6 @@
%filter substitution %filter substitution
%define forwardTransitionLength 150ms %define forwardTransitionLength 150ms
%define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper %define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
%define conditionalForwardWithUrlbarWidth 32
%define toolbarButtonPressed :hover:active:not([disabled="true"]):not([cui-areatype="menu-panel"]) %define toolbarButtonPressed :hover:active:not([disabled="true"]):not([cui-areatype="menu-panel"])
%define windowButtonMarginTop 11px %define windowButtonMarginTop 11px
@ -21,6 +20,8 @@
--tabs-toolbar-color: #333; --tabs-toolbar-color: #333;
--backbutton-urlbar-overlap: 6px; --backbutton-urlbar-overlap: 6px;
/* icon width + border + horizontal padding (includes the overlap from backbutton-urlbar-overlap) */
--forwardbutton-width: 32px;
--toolbarbutton-hover-background: hsla(0,0%,100%,.1) linear-gradient(hsla(0,0%,100%,.3), hsla(0,0%,100%,.1)) padding-box; --toolbarbutton-hover-background: hsla(0,0%,100%,.1) linear-gradient(hsla(0,0%,100%,.3), hsla(0,0%,100%,.1)) padding-box;
--toolbarbutton-hover-bordercolor: hsla(0,0%,0%,.2); --toolbarbutton-hover-bordercolor: hsla(0,0%,0%,.2);
@ -1371,7 +1372,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
} }
@conditionalForwardWithUrlbar@ > #forward-button[disabled] { @conditionalForwardWithUrlbar@ > #forward-button[disabled] {
margin-left: -@conditionalForwardWithUrlbarWidth@px; margin-left: calc(0px - var(--forwardbutton-width));
} }
@conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] { @conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] {
@ -1381,7 +1382,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
@conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] { @conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
/* when not hovered anymore, trigger a new transition to hide the forward button immediately */ /* when not hovered anymore, trigger a new transition to hide the forward button immediately */
margin-left: -@conditionalForwardWithUrlbarWidth@.01px; margin-left: calc(-0.01px - var(--forwardbutton-width));
} }
.unified-nav-back[_moz-menuactive]:-moz-locale-dir(ltr), .unified-nav-back[_moz-menuactive]:-moz-locale-dir(ltr),

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

@ -41,6 +41,18 @@
#forward-button { #forward-button {
-moz-border-start: none !important; -moz-border-start: none !important;
/* browser.css and friends set up the width of the button to be 32px.
* They then set margin-left to -2px to ensure the button is not too wide
* compared to the back button, and set padding-left to center the icon
* correctly.
* In our theme, the back and forward buttons are the same width, with the
* back button being 32px with 1px border on both sides. To ensure the
* forward button's content box looks like it is the same size with width
* set to 32px and a 1px border on only 1 side, we overlap by 1px, so both
* buttons end up with a content box that looks like it's 30px.
*/
margin-left: -1px;
padding-left: 1px;
} }
#forward-button > .toolbarbutton-icon { #forward-button > .toolbarbutton-icon {

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

@ -222,11 +222,12 @@ treecol {
/* Privacy pane */ /* Privacy pane */
#doNotTrackInfo, .doNotTrackLearnMore,
#trackingProtectionPBMLearnMore, #trackingProtectionPBMLearnMore,
#trackingProtectionLearnMore { #trackingProtectionLearnMore {
-moz-margin-start: 1.5em !important; -moz-margin-start: 1.5em !important;
margin-top: 0; margin-top: 0;
font-weight: normal;
} }
/* Collapse the non-active vboxes in decks to use only the height the /* Collapse the non-active vboxes in decks to use only the height the

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

@ -20,6 +20,9 @@
--backbutton-urlbar-overlap: 6px; --backbutton-urlbar-overlap: 6px;
/* icon width + border + horizontal padding (includes the overlap from backbutton-urlbar-overlap) */
--forwardbutton-width: 31px;
--toolbarbutton-vertical-inner-padding: 2px; --toolbarbutton-vertical-inner-padding: 2px;
--toolbarbutton-vertical-outer-padding: 8px; --toolbarbutton-vertical-outer-padding: 8px;
@ -939,9 +942,7 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
border-radius: 0 !important; border-radius: 0 !important;
padding-left: calc(var(--backbutton-urlbar-overlap) + 3px) !important; padding-left: calc(var(--backbutton-urlbar-overlap) + 3px) !important;
padding-right: 3px !important; padding-right: 3px !important;
% icon width + border + horizontal padding without --backbutton-urlbar-overlap max-width: var(--forwardbutton-width) !important;
%define forwardButtonWidth 25
max-width: calc(@forwardButtonWidth@px + var(--backbutton-urlbar-overlap)) !important;
} }
@conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button { @conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button {
@ -949,7 +950,7 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
} }
@conditionalForwardWithUrlbar@ > #forward-button[disabled] { @conditionalForwardWithUrlbar@ > #forward-button[disabled] {
margin-left: calc(-@forwardButtonWidth@px - var(--backbutton-urlbar-overlap)); margin-left: calc(0px - var(--forwardbutton-width));
} }
@conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] { @conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] {
@ -959,7 +960,7 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
@conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] { @conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
/* when not hovered anymore, trigger a new transition to hide the forward button immediately */ /* when not hovered anymore, trigger a new transition to hide the forward button immediately */
margin-left: calc(-@forwardButtonWidth@.01px - var(--backbutton-urlbar-overlap)); margin-left: calc(-0.01px - var(--forwardbutton-width));
} }
#back-button { #back-button {

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

@ -4,6 +4,10 @@
%include ../shared/devedition.inc.css %include ../shared/devedition.inc.css
:root {
--forwardbutton-width: 29px;
}
:root[devtoolstheme="dark"], :root[devtoolstheme="dark"],
:root[devtoolstheme="light"] { :root[devtoolstheme="light"] {
/* Matches the #browser-border-start, #browser-border-end color */ /* Matches the #browser-border-start, #browser-border-end color */

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

@ -5725,6 +5725,7 @@ MOZ_DIRECTX_SDK_PATH=
MOZ_D3DCOMPILER_XP_DLL= MOZ_D3DCOMPILER_XP_DLL=
MOZ_D3DCOMPILER_XP_CAB= MOZ_D3DCOMPILER_XP_CAB=
if test "$COMPILE_ENVIRONMENT" ; then
case "$target_os" in case "$target_os" in
*mingw*) *mingw*)
MOZ_ANGLE_RENDERER=1 MOZ_ANGLE_RENDERER=1
@ -5887,7 +5888,9 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
AC_MSG_ERROR([ Install Windows SDK 8.0+, as well as DirectX SDK (June 2010 version or newer), or reconfigure without this flag.]) AC_MSG_ERROR([ Install Windows SDK 8.0+, as well as DirectX SDK (June 2010 version or newer), or reconfigure without this flag.])
fi fi
fi fi
fi fi # MOZ_ANGLE_RENDERER
fi # COMPILE_ENVIRONMENT
dnl ======================================================== dnl ========================================================
@ -6280,41 +6283,49 @@ dnl minimum minor version of Unicode NSIS isn't in the path
dnl (unless in case of cross compiling, for which Unicode dnl (unless in case of cross compiling, for which Unicode
dnl is not yet sufficient). dnl is not yet sufficient).
if test "$OS_ARCH" = "WINNT"; then if test "$OS_ARCH" = "WINNT"; then
MIN_NSIS_MAJOR_VER=2 MIN_NSIS_MAJOR_VER=3
MIN_NSIS_MINOR_VER=46 MIN_NSIS_MINOR_VER=0
MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensis-3.0b1.exe makensisu-3.0a2.exe makensisu-2.46.exe makensis) MIN_NSIS_PRERELEASE_TYPE=b
MIN_NSIS_PRERELEASE_VER=1
MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensis-3.0b3.exe makensis-3.0b1.exe makensis)
if test -n "$MAKENSISU" -a "$MAKENSISU" != ":"; then if test -n "$MAKENSISU" -a "$MAKENSISU" != ":"; then
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null` MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null`
changequote(,)
MAKENSISU_PARSED_VER=`echo "$MAKENSISU_VER" | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\).*\-Unicode$/\1/g'`
changequote([,])
if test "$MAKENSISU_PARSED_VER" = ""; then
changequote(,) changequote(,)
MAKENSISU_PARSED_VER=`echo "$MAKENSISU_VER" | sed -e 's/^v\([0-9]\+\.[0-9]\+\).*$/\1/g'` MAKENSISU_PARSED_VER=`echo "$MAKENSISU_VER" | sed -e 's/^v\([0-9]\+\.[0-9]\+\).*$/\1/g'`
changequote([,]) changequote([,])
fi
MAKENSISU_MAJOR_VER=0 MAKENSISU_MAJOR_VER=0
MAKENSISU_MINOR_VER=0 MAKENSISU_MINOR_VER=0
MAKENSISU_PRERELEASE_TYPE=$MIN_NSIS_PRERELEASE_TYPE
MAKENSISU_PRERELEASE_VER=$MIN_NSIS_PRERELEASE_VER
if test ! "$MAKENSISU_PARSED_VER" = ""; then if test ! "$MAKENSISU_PARSED_VER" = ""; then
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_PARSED_VER | $AWK -F\. '{ print $1 }'` MAKENSISU_MAJOR_VER=`echo $MAKENSISU_PARSED_VER | $AWK -F\. '{ print $1 }'`
MAKENSISU_MINOR_VER=`echo $MAKENSISU_PARSED_VER | $AWK -F\. '{ print $2 }'` MAKENSISU_MINOR_VER=`echo $MAKENSISU_PARSED_VER | $AWK -F\. '{ print $2 }'`
changequote(,)
MAKENSISU_PARSED_PRERELEASE=`echo "$MAKENSISU_VER" | sed -e 's/^v[0-9]\+\.[0-9]\+\([^0-9]\+\)\([0-9]\+\).*$/\1.\2/g'`
changequote([,])
if test ! "$MAKENSISU_PARSED_PRERELEASE" = "$MAKENSISU_VER"; then
MAKENSISU_PRERELEASE_TYPE=`echo $MAKENSISU_PARSED_PRERELEASE | $AWK -F\. '{ print $1 }'`
MAKENSISU_PRERELEASE_VER=`echo $MAKENSISU_PARSED_PRERELEASE | $AWK -F\. '{ print $2 }'`
fi fi
AC_MSG_CHECKING([for Unicode NSIS version $MIN_NSIS_MAJOR_VER.$MIN_NSIS_MINOR_VER or greater]) fi
AC_MSG_CHECKING([for NSIS version $MIN_NSIS_MAJOR_VER.$MIN_NSIS_MINOR_VER$MIN_NSIS_PRERELEASE_TYPE$MIN_NSIS_PRERELEASE_VER or greater])
if test "$MAKENSISU_MAJOR_VER" -eq $MIN_NSIS_MAJOR_VER -a \ if test "$MAKENSISU_MAJOR_VER" -eq $MIN_NSIS_MAJOR_VER -a \
"$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER || "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER -a \
test "$MAKENSISU_MAJOR_VER" -gt $MIN_NSIS_MAJOR_VER; then "$MAKENSISU_PRERELEASE_TYPE" = "$MIN_NSIS_PRERELEASE_TYPE" -a \
"$MAKENSISU_PRERELEASE_VER" -ge $MIN_NSIS_PRERELEASE_VER; then
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
AC_MSG_RESULT([Found NSIS Version: $MAKENSISU_VER])
else else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
if test -z "$CROSS_COMPILE"; then if test -z "$CROSS_COMPILE"; then
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS version $MIN_NSIS_MAJOR_VER.$MIN_NSIS_MINOR_VER or greater in your path.]) AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or NSIS version $MIN_NSIS_MAJOR_VER.$MIN_NSIS_MINOR_VER$MIN_NSIS_PRERELEASE_TYPE$MIN_NSIS_PRERELEASE_VER or greater in your path.])
else else
MAKENSISU= MAKENSISU=
fi fi
fi fi
elif test -z "$CROSS_COMPILE"; then elif test -z "$CROSS_COMPILE"; then
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS version $MIN_NSIS_MAJOR_VER.$MIN_NSIS_MINOR_VER or greater in your path.]) AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or NSIS version $MIN_NSIS_MAJOR_VER.$MIN_NSIS_MINOR_VER$MIN_NSIS_PRERELEASE_TYPE$MIN_NSIS_PRERELEASE_VER or greater in your path.])
else else
MAKENSISU= MAKENSISU=
fi fi
@ -8146,12 +8157,15 @@ if test "$MOZ_TREE_CAIRO"; then
MOZ_ENABLE_D2D_SURFACE=1 MOZ_ENABLE_D2D_SURFACE=1
MOZ_ENABLE_DWRITE_FONT=1 MOZ_ENABLE_DWRITE_FONT=1
if test "$COMPILE_ENVIRONMENT"; then
MOZ_CHECK_HEADER(d3d9.h, MOZ_ENABLE_D3D9_LAYER=1) MOZ_CHECK_HEADER(d3d9.h, MOZ_ENABLE_D3D9_LAYER=1)
dnl D3D10 Layers depend on D2D Surfaces. dnl D3D10 Layers depend on D2D Surfaces.
if test -n "$WIN32_D2D_SURFACE_FEATURE"; then if test -n "$WIN32_D2D_SURFACE_FEATURE"; then
MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1) MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
fi fi
fi
;; ;;
esac esac
if test "$USE_FC_FREETYPE"; then if test "$USE_FC_FREETYPE"; then

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

@ -1,6 +1,7 @@
content devtools client/ content devtools client/
skin devtools classic/1.0 client/themes/ skin devtools classic/1.0 client/themes/
resource devtools . resource devtools .
locale devtools en-US client/locales/en-US/
content webide client/webide/content/ content webide client/webide/content/
skin webide classic/1.0 client/webide/themes/ skin webide classic/1.0 client/webide/themes/

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

@ -1,54 +0,0 @@
"use strict";
var SOURCE_URL = getFileUrl("setBreakpoint-on-line-with-no-offests-in-gcd-script.js");
function run_test() {
return Task.spawn(function* () {
do_test_pending();
let global = testGlobal("test");
loadSubScript(SOURCE_URL, global);
Cu.forceGC();
DebuggerServer.registerModule("xpcshell-test/testactors");
DebuggerServer.init(() => true);
DebuggerServer.addTestGlobal(global);
let client = new DebuggerClient(DebuggerServer.connectPipe());
yield connect(client);
let tab = yield findTab(client, "test");
let [, tabClient] = yield attachTab(client, tab);
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let source = yield findSource(threadClient, SOURCE_URL);
let sourceClient = threadClient.source(source);
let location = { line: 7 };
let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
do_check_true(packet.isPending);
executeSoon(function () {
reload(tabClient).then(function () {
loadSubScript(SOURCE_URL, global);
});
});
packet = yield waitForPaused(threadClient);
do_check_eq(packet.type, "paused");
let why = packet.why;
do_check_eq(why.type, "breakpoint");
do_check_eq(why.actors.length, 1);
do_check_eq(why.actors[0], breakpointClient.actor);
let frame = packet.frame;
let where = frame.where;
do_check_eq(where.source.actor, source.actor);
do_check_eq(where.line, location.line + 1);
let variables = frame.environment.bindings.variables;
do_check_eq(variables.a.value, 1);
do_check_eq(variables.c.value.type, "undefined");
yield resume(threadClient);
yield close(client);
do_test_finished();
});
}

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

@ -471,8 +471,13 @@ pref("plugin.default.state", 1);
// The breakpad report server to link to in about:crashes // The breakpad report server to link to in about:crashes
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/"); pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
pref("app.support.baseURL", "http://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/"); pref("app.support.baseURL", "http://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/");
// Used to submit data to input from about:feedback // Used to submit data to input from about:feedback
pref("app.feedback.postURL", "https://input.mozilla.org/api/v1/feedback/"); pref("app.feedback.postURL", "https://input.mozilla.org/api/v1/feedback/");
// URL for feedback page
pref("app.feedbackURL", "about:feedback");
pref("app.privacyURL", "https://www.mozilla.org/privacy/firefox/"); pref("app.privacyURL", "https://www.mozilla.org/privacy/firefox/");
pref("app.creditsURL", "http://www.mozilla.org/credits/"); pref("app.creditsURL", "http://www.mozilla.org/credits/");
pref("app.channelURL", "http://www.mozilla.org/%LOCALE%/firefox/channel/"); pref("app.channelURL", "http://www.mozilla.org/%LOCALE%/firefox/channel/");

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

@ -67,7 +67,14 @@ public abstract class SessionParser {
int selectedIndex = -1; int selectedIndex = -1;
try { try {
for (String sessionString : sessionStrings) { for (String sessionString : sessionStrings) {
final JSONObject window = new JSONObject(sessionString).getJSONArray("windows").getJSONObject(0); final JSONArray windowsArray = new JSONObject(sessionString).getJSONArray("windows");
if (windowsArray.length() == 0) {
// Session json can be empty if the user has opted out of session restore.
Log.d(LOGTAG, "Session restore file is empty, no session entries found.");
continue;
}
final JSONObject window = windowsArray.getJSONObject(0);
final JSONArray tabs = window.getJSONArray("tabs"); final JSONArray tabs = window.getJSONArray("tabs");
final int optSelected = window.optInt("selected", -1); final int optSelected = window.optInt("selected", -1);
final JSONArray closedTabs = window.optJSONArray("closedTabs"); final JSONArray closedTabs = window.optJSONArray("closedTabs");

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

@ -133,18 +133,15 @@ OnSharedPreferenceChangeListener
private static final String PREFS_TRACKING_PROTECTION_PB = "privacy.trackingprotection.pbmode.enabled"; private static final String PREFS_TRACKING_PROTECTION_PB = "privacy.trackingprotection.pbmode.enabled";
public static final String PREFS_VOICE_INPUT_ENABLED = NON_PREF_PREFIX + "voice_input_enabled"; public static final String PREFS_VOICE_INPUT_ENABLED = NON_PREF_PREFIX + "voice_input_enabled";
public static final String PREFS_QRCODE_ENABLED = NON_PREF_PREFIX + "qrcode_enabled"; public static final String PREFS_QRCODE_ENABLED = NON_PREF_PREFIX + "qrcode_enabled";
private static final String PREFS_ADVANCED = NON_PREF_PREFIX + "advanced.enabled";
private static final String PREFS_ACCESSIBILITY = NON_PREF_PREFIX + "accessibility.enabled";
private static final String PREFS_CUSTOMIZE_HOME = NON_PREF_PREFIX + "customize_home";
private static final String PREFS_TRACKING_PROTECTION_PRIVATE_BROWSING = "privacy.trackingprotection.pbmode.enabled"; private static final String PREFS_TRACKING_PROTECTION_PRIVATE_BROWSING = "privacy.trackingprotection.pbmode.enabled";
private static final String PREFS_TRACKING_PROTECTION_LEARN_MORE = NON_PREF_PREFIX + "trackingprotection.learn_more"; private static final String PREFS_TRACKING_PROTECTION_LEARN_MORE = NON_PREF_PREFIX + "trackingprotection.learn_more";
private static final String PREFS_CLEAR_PRIVATE_DATA = NON_PREF_PREFIX + "privacy.clear"; private static final String PREFS_CLEAR_PRIVATE_DATA = NON_PREF_PREFIX + "privacy.clear";
private static final String PREFS_CLEAR_PRIVATE_DATA_EXIT = NON_PREF_PREFIX + "history.clear_on_exit"; private static final String PREFS_CLEAR_PRIVATE_DATA_EXIT = NON_PREF_PREFIX + "history.clear_on_exit";
private static final String PREFS_SCREEN_ADVANCED = NON_PREF_PREFIX + "advanced_screen"; private static final String PREFS_SCREEN_ADVANCED = NON_PREF_PREFIX + "advanced_screen";
private static final String PREFS_CATEGORY_HOMEPAGE = NON_PREF_PREFIX + "category_homepage";
public static final String PREFS_HOMEPAGE = NON_PREF_PREFIX + "homepage"; public static final String PREFS_HOMEPAGE = NON_PREF_PREFIX + "homepage";
public static final String PREFS_HISTORY_SAVED_SEARCH = NON_PREF_PREFIX + "search.search_history.enabled"; public static final String PREFS_HISTORY_SAVED_SEARCH = NON_PREF_PREFIX + "search.search_history.enabled";
private static final String PREFS_FAQ_LINK = NON_PREF_PREFIX + "faq.link"; private static final String PREFS_FAQ_LINK = NON_PREF_PREFIX + "faq.link";
private static final String PREFS_FEEDBACK_LINK = NON_PREF_PREFIX + "feedback.link";
private static final String ACTION_STUMBLER_UPLOAD_PREF = AppConstants.ANDROID_PACKAGE_NAME + ".STUMBLER_PREF"; private static final String ACTION_STUMBLER_UPLOAD_PREF = AppConstants.ANDROID_PACKAGE_NAME + ".STUMBLER_PREF";
@ -852,6 +849,18 @@ OnSharedPreferenceChangeListener
final String url = getResources().getString(R.string.faq_link, VERSION, OS, LOCALE); final String url = getResources().getString(R.string.faq_link, VERSION, OS, LOCALE);
((LinkPreference) pref).setUrl(url); ((LinkPreference) pref).setUrl(url);
} else if (PREFS_FEEDBACK_LINK.equals(key)) {
PrefsHelper.getPref("app.feedbackURL", new PrefsHelper.PrefHandlerBase() {
@Override
public void prefValue(String prefName, final String value) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
((LinkPreference) pref).setUrl(value);
}
});
}
});
} }
// Some Preference UI elements are not actually preferences, // Some Preference UI elements are not actually preferences,

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

@ -35,12 +35,7 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
configuration.put(Restrictable.ADVANCED_SETTINGS, false); configuration.put(Restrictable.ADVANCED_SETTINGS, false);
configuration.put(Restrictable.CAMERA_MICROPHONE, false); configuration.put(Restrictable.CAMERA_MICROPHONE, false);
configuration.put(Restrictable.DATA_CHOICES, false); configuration.put(Restrictable.DATA_CHOICES, false);
// Hold behind Nightly flag until we have an actual block list deployed.
if (AppConstants.NIGHTLY_BUILD) {
configuration.put(Restrictable.BLOCK_LIST, false); configuration.put(Restrictable.BLOCK_LIST, false);
}
configuration.put(Restrictable.TELEMETRY, false); configuration.put(Restrictable.TELEMETRY, false);
configuration.put(Restrictable.HEALTH_REPORT, true); configuration.put(Restrictable.HEALTH_REPORT, true);
configuration.put(Restrictable.DEFAULT_THEME, true); configuration.put(Restrictable.DEFAULT_THEME, true);
@ -49,12 +44,18 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
/** /**
* These restrictions are hidden from the admin configuration UI. * These restrictions are hidden from the admin configuration UI.
*/ */
private static List<Restrictable> hiddenRestrictions = Arrays.asList( private static List<Restrictable> hiddenRestrictions = new ArrayList<>();
Restrictable.MASTER_PASSWORD, static {
Restrictable.GUEST_BROWSING, hiddenRestrictions.add(Restrictable.MASTER_PASSWORD);
Restrictable.DATA_CHOICES, hiddenRestrictions.add(Restrictable.GUEST_BROWSING);
Restrictable.DEFAULT_THEME hiddenRestrictions.add(Restrictable.DATA_CHOICES);
); hiddenRestrictions.add(Restrictable.DEFAULT_THEME);
// Hold behind Nightly flag until we have an actual block list deployed.
if (!AppConstants.NIGHTLY_BUILD){
hiddenRestrictions.add(Restrictable.BLOCK_LIST);
}
}
/* package-private */ static boolean shouldHide(Restrictable restrictable) { /* package-private */ static boolean shouldHide(Restrictable restrictable) {
return hiddenRestrictions.contains(restrictable); return hiddenRestrictions.contains(restrictable);

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

@ -354,7 +354,7 @@ public class DateTimePicker extends FrameLayout {
mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1); mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1);
mMonthSpinner = setupSpinner(R.id.month, 1, mMonthSpinner = setupSpinner(R.id.month, 1,
mTempDate.get(Calendar.MONTH)); mTempDate.get(Calendar.MONTH) + 1); // Month is 0-based
mMonthSpinner.setFormatter(TWO_DIGIT_FORMATTER); mMonthSpinner.setFormatter(TWO_DIGIT_FORMATTER);
mMonthSpinner.setDisplayedValues(mShortMonths); mMonthSpinner.setDisplayedValues(mShortMonths);
mMonthSpinnerInput = (EditText) mMonthSpinner.getChildAt(1); mMonthSpinnerInput = (EditText) mMonthSpinner.getChildAt(1);

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 603 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1023 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 775 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

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

@ -19,7 +19,6 @@
<org.mozilla.gecko.preferences.LinkPreference android:key="android.not_a_preference.feedback.link" <org.mozilla.gecko.preferences.LinkPreference android:key="android.not_a_preference.feedback.link"
android:title="@string/pref_vendor_feedback" android:title="@string/pref_vendor_feedback"
android:persistent="false" android:persistent="false"/>
url="about:feedback" />
</PreferenceScreen> </PreferenceScreen>

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

@ -4,15 +4,57 @@
"use strict"; "use strict";
var Feedback = { var Feedback = {
observe: function(aMessage, aTopic, aData) {
if (aTopic !== "Feedback:Show")
return;
// Only prompt for feedback if this isn't a distribution build. get _feedbackURL() {
delete this._feedbackURL;
return this._feedbackURL = Services.prefs.getCharPref("app.feedbackURL");
},
observe: function(aMessage, aTopic, aData) {
if (aTopic !== "Feedback:Show") {
return;
}
// Don't prompt for feedback in distribution builds.
try { try {
Services.prefs.getCharPref("distribution.id"); Services.prefs.getCharPref("distribution.id");
} catch (e) { return;
BrowserApp.addTab("about:feedback?source=feedback-prompt", { selected: true, parentId: BrowserApp.selectedTab.id }); } catch (e) {}
let url = this._feedbackURL + "?source=feedback-prompt";
let browser = BrowserApp.selectOrAddTab(url, { parentId: BrowserApp.selectedTab.id }).browser;
browser.addEventListener("FeedbackClose", this, false, true);
browser.addEventListener("FeedbackMaybeLater", this, false, true);
browser.addEventListener("FeedbackOpenPlay", this, false, true);
},
handleEvent: function(event) {
if (!this._isAllowed(event.target)) {
return;
} }
switch (event.type) {
case "FeedbackClose":
// Do nothing.
break;
case "FeedbackMaybeLater":
Messaging.sendRequest({ type: "Feedback:MaybeLater" });
break;
case "FeedbackOpenPlay":
Messaging.sendRequest({ type: "Feedback:OpenPlayStore" });
break;
}
let win = event.target.ownerDocument.defaultView.top;
BrowserApp.closeTab(BrowserApp.getTabForWindow(win));
},
_isAllowed: function(node) {
let uri = node.ownerDocument.documentURIObject;
let feedbackURI = Services.io.newURI(this._feedbackURL, null, null);
return uri.prePath === feedbackURI.prePath;
} }
}; };

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

@ -51,24 +51,31 @@ browser.contentHandlers.types.0.uri=https://add.my.yahoo.com/rss?url=%s
# mobile/android/tests/browser/robocop/testDistribution.java # mobile/android/tests/browser/robocop/testDistribution.java
# to reflect the new set of IDs reported as tiles data. # to reflect the new set of IDs reported as tiles data.
# #
browser.suggestedsites.list.0=mozilla browser.suggestedsites.list.0=facebook
browser.suggestedsites.list.1=fxaddons browser.suggestedsites.list.1=youtube
browser.suggestedsites.list.2=fxsupport browser.suggestedsites.list.2=amazon
browser.suggestedsites.list.3=wikipedia
browser.suggestedsites.list.4=twitter
browser.suggestedsites.mozilla.title=The Mozilla Project browser.suggestedsites.facebook.title=Facebook
browser.suggestedsites.mozilla.url=https://www.mozilla.org/en-US/ browser.suggestedsites.facebook.url=https://m.facebook.com/
browser.suggestedsites.mozilla.bgcolor=#ce4e41 browser.suggestedsites.facebook.bgcolor=#385185
browser.suggestedsites.mozilla.trackingid=632
browser.suggestedsites.fxaddons.title=Add-ons: Customize Firefox browser.suggestedsites.youtube.title=YouTube
browser.suggestedsites.fxaddons.url=https://addons.mozilla.org/en-US/android/ browser.suggestedsites.youtube.url=https://m.youtube.com/
browser.suggestedsites.fxaddons.bgcolor=#62be06 browser.suggestedsites.youtube.bgcolor=#cd201f
browser.suggestedsites.fxaddons.trackingid=630
browser.suggestedsites.fxsupport.title=Firefox Help and Support browser.suggestedsites.amazon.title=Amazon
browser.suggestedsites.fxsupport.url=https://support.mozilla.org/en-US/products/mobile browser.suggestedsites.amazon.url=https://www.amazon.com/
browser.suggestedsites.fxsupport.bgcolor=#f37c00 browser.suggestedsites.amazon.bgcolor=#000000
browser.suggestedsites.fxsupport.trackingid=631
browser.suggestedsites.wikipedia.title=Wikipedia
browser.suggestedsites.wikipedia.url=https://www.wikipedia.org/
browser.suggestedsites.wikipedia.bgcolor=#000000
browser.suggestedsites.twitter.title=Twitter
browser.suggestedsites.twitter.url=https://mobile.twitter.com/
browser.suggestedsites.twitter.bgcolor=#55acee
browser.suggestedsites.restricted.list.0=restricted_fxsupport browser.suggestedsites.restricted.list.0=restricted_fxsupport
browser.suggestedsites.restricted.list.1=webmaker browser.suggestedsites.restricted.list.1=webmaker

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

@ -420,14 +420,17 @@ interface nsIBrowserSearchService : nsISupports
void removeEngine(in nsISearchEngine engine); void removeEngine(in nsISearchEngine engine);
/** /**
* The default search engine. Returns the first visible engine if the default * Alias for the currentEngine attribute, kept for add-on compatibility.
* engine is hidden. May be null if there are no visible search engines.
*/ */
attribute nsISearchEngine defaultEngine; attribute nsISearchEngine defaultEngine;
/** /**
* The currently active search engine. May be null if there are no visible * The currently active search engine.
* search engines. * Unless the application doesn't ship any search plugin, this should never
* be null. If the currently active engine is removed, this attribute will
* fallback first to the original default engine if it's not hidden, then to
* the first visible engine, and as a last resort it will unhide the original
* default engine.
*/ */
attribute nsISearchEngine currentEngine; attribute nsISearchEngine currentEngine;

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

@ -75,7 +75,7 @@ class ProcessExecutionMixin(LoggingMixin):
""" """
args = self._normalize_command(args, require_unix_environment) args = self._normalize_command(args, require_unix_environment)
self.log(logging.INFO, 'new_process', {'args': args}, ' '.join(args)) self.log(logging.INFO, 'new_process', {'args': ' '.join(args)}, '{args}')
def handleLine(line): def handleLine(line):
# Converts str to unicode on Python 2 and bytes to str on Python 3. # Converts str to unicode on Python 2 and bytes to str on Python 3.
@ -144,7 +144,7 @@ class ProcessExecutionMixin(LoggingMixin):
ensure_exit_code = 0 ensure_exit_code = 0
if status != ensure_exit_code: if status != ensure_exit_code:
raise Exception('Process executed with non-0 exit code: %s' % args) raise Exception('Process executed with non-0 exit code %d: %s' % (status, args))
return status return status

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

@ -50,6 +50,7 @@ import re
import shutil import shutil
import stat import stat
import subprocess import subprocess
import tarfile
import tempfile import tempfile
import urlparse import urlparse
import zipfile import zipfile
@ -131,6 +132,41 @@ class AndroidArtifactJob(ArtifactJob):
writer.add(basename.encode('utf-8'), f) writer.add(basename.encode('utf-8'), f)
class LinuxArtifactJob(ArtifactJob):
def process_artifact(self, filename, processed_filename):
with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
prefix = 'firefox/'
whitelist = {
'application.ini',
'crashreporter',
'dependentlibs.list',
'firefox',
'firefox-bin',
'platform.ini',
'plugin-container',
'updater',
'webapprt-stub',
}
with tarfile.open(filename) as reader:
for f in reader:
if not f.isfile():
continue
if not f.name.startswith(prefix):
raise ValueError('Archive format changed! Filename should start with "firefox/"; was "{filename}"'.format(filename=f.name))
basename = f.name[len(prefix):]
if not basename.endswith('.so') and \
basename not in whitelist:
continue
self.log(logging.INFO, 'artifact',
{'basename': basename},
'Adding {basename} to processed archive')
writer.add(basename.encode('utf-8'), reader.extractfile(f), mode=f.mode)
class MacArtifactJob(ArtifactJob): class MacArtifactJob(ArtifactJob):
def process_artifact(self, filename, processed_filename): def process_artifact(self, filename, processed_filename):
tempdir = tempfile.mkdtemp() tempdir = tempfile.mkdtemp()
@ -223,14 +259,44 @@ class MacArtifactJob(ArtifactJob):
pass pass
# Keep the keys of this map in sync with the |mach artifact| --job options. class WinArtifactJob(ArtifactJob):
def process_artifact(self, filename, processed_filename):
with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
prefix = 'firefox/'
whitelist = {
'dependentlibs.list',
'platform.ini',
'application.ini',
}
for f in JarReader(filename):
if not f.filename.startswith(prefix):
raise ValueError('Archive format changed! Filename should start with "firefox/"; was "{filename}"'.format(filename=f.filename))
basename = f.filename[len(prefix):]
if not basename.endswith('.dll') and \
not basename.endswith('.exe') and \
basename not in whitelist:
continue
self.log(logging.INFO, 'artifact',
{'basename': basename},
'Adding {basename} to processed archive')
writer.add(basename.encode('utf-8'), f)
# Keep the keys of this map in sync with the |mach artifact| --job
# options. The keys of this map correspond to entries at
# https://tools.taskcluster.net/index/artifacts/#buildbot.branches.mozilla-central/buildbot.branches.mozilla-central.
JOB_DETAILS = { JOB_DETAILS = {
# 'android-api-9': (AndroidArtifactJob, 'public/build/fennec-(.*)\.android-arm\.apk'), # 'android-api-9': (AndroidArtifactJob, 'public/build/fennec-(.*)\.android-arm\.apk'),
'android-api-11': (AndroidArtifactJob, 'public/build/fennec-(.*)\.android-arm\.apk'), 'android-api-11': (AndroidArtifactJob, 'public/build/fennec-(.*)\.android-arm\.apk'),
'android-x86': (AndroidArtifactJob, 'public/build/fennec-(.*)\.android-i386\.apk'), 'android-x86': (AndroidArtifactJob, 'public/build/fennec-(.*)\.android-i386\.apk'),
# 'linux': (ArtifactJob, 'public/build/firefox-(.*)\.linux-i686\.tar\.bz2'), 'linux': (LinuxArtifactJob, 'public/build/firefox-(.*)\.linux-i686\.tar\.bz2'),
# 'linux64': (ArtifactJob, 'public/build/firefox-(.*)\.linux-x86_64\.tar\.bz2'), 'linux64': (LinuxArtifactJob, 'public/build/firefox-(.*)\.linux-x86_64\.tar\.bz2'),
'macosx64': (MacArtifactJob, 'public/build/firefox-(.*)\.mac\.dmg'), 'macosx64': (MacArtifactJob, 'public/build/firefox-(.*)\.mac\.dmg'),
'win32': (WinArtifactJob, 'public/build/firefox-(.*)\.win32.zip'),
'win64': (WinArtifactJob, 'public/build/firefox-(.*)\.win64.zip'),
} }
def get_job_details(job, log=None): def get_job_details(job, log=None):
@ -342,12 +408,39 @@ class PushHeadCache(CacheManager):
@cachedmethod(operator.attrgetter('_cache')) @cachedmethod(operator.attrgetter('_cache'))
def pushheads(self, tree, parent): def pushheads(self, tree, parent):
try:
pushheads = subprocess.check_output([self._hg, 'log', pushheads = subprocess.check_output([self._hg, 'log',
'--template', '{node}\n', '--template', '{node}\n',
'-r', 'last(pushhead("{tree}") & ::"{parent}", {num})'.format( '-r', 'last(pushhead("{tree}") and ::"{parent}", {num})'.format(
tree=tree, parent=parent, num=NUM_PUSHHEADS_TO_QUERY_PER_PARENT)]) tree=tree, parent=parent, num=NUM_PUSHHEADS_TO_QUERY_PER_PARENT)])
pushheads = pushheads.strip().split('\n') # Filter blank lines.
pushheads = [ pushhead for pushhead in pushheads.strip().split('\n') if pushhead ]
if pushheads:
return pushheads return pushheads
except subprocess.CalledProcessError as e:
# Probably don't have the mozext extension installed.
ret = subprocess.call([self._hg, 'showconfig', 'extensions.mozext'])
if ret:
raise Exception('Could not find candidate pushheads.\n\n'
'You need to enable the "mozext" hg extension: '
'see https://developer.mozilla.org/en-US/docs/Artifact_builds')
raise e
# Probably don't have the pushlog database present locally. Check.
tree_pushheads = subprocess.check_output([self._hg, 'log',
'--template', '{node}\n',
'-r', 'last(pushhead("{tree}"))'.format(tree=tree)])
# Filter blank lines.
tree_pushheads = [ pushhead for pushhead in tree_pushheads.strip().split('\n') if pushhead ]
if tree_pushheads:
# Okay, we have some pushheads but no candidates. This can happen
# for legitimate reasons: old revisions with no upstream builds
# remaining; or new revisions that don't have upstream builds yet.
return []
raise Exception('Could not find any pushheads for tree "{tree}".\n\n'
'Try running |hg pushlogsync|; '
'see https://developer.mozilla.org/en-US/docs/Artifact_builds'.format(tree=tree))
class TaskCache(CacheManager): class TaskCache(CacheManager):
@ -516,7 +609,7 @@ class Artifacts(object):
if info.filename.endswith('.ini'): if info.filename.endswith('.ini'):
continue continue
n = mozpath.join(bindir, info.filename) n = mozpath.join(bindir, info.filename)
fh = FileAvoidWrite(n, mode='r') fh = FileAvoidWrite(n, mode='rb')
shutil.copyfileobj(zf.open(info), fh) shutil.copyfileobj(zf.open(info), fh)
file_existed, file_updated = fh.close() file_existed, file_updated = fh.close()
self.log(logging.INFO, 'artifact', self.log(logging.INFO, 'artifact',

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

@ -633,7 +633,7 @@ class Build(MachCommandBase):
self.log(logging.INFO, 'artifact', self.log(logging.INFO, 'artifact',
{}, "Running |mach artifact install|.") {}, "Running |mach artifact install|.")
args = [os.path.join(self.topsrcdir, 'mach'), 'artifact', 'install'] args = [os.path.join(self.topsrcdir, 'mach'), 'artifact', 'install']
self._run_command_in_srcdir(args=args, self._run_command_in_srcdir(args=args, require_unix_environment=True,
pass_thru=True, ensure_exit_code=True) pass_thru=True, ensure_exit_code=True)
@CommandProvider @CommandProvider
@ -1397,10 +1397,19 @@ class MachDebug(MachCommandBase):
class ArtifactSubCommand(SubCommand): class ArtifactSubCommand(SubCommand):
def __call__(self, func): def __call__(self, func):
after = SubCommand.__call__(self, func) after = SubCommand.__call__(self, func)
jobchoices = {
'android-api-11',
'android-x86',
'linux',
'linux64',
'macosx64',
'win32',
'win64'
}
args = [ args = [
CommandArgument('--tree', metavar='TREE', type=str, CommandArgument('--tree', metavar='TREE', type=str,
help='Firefox tree.'), help='Firefox tree.'),
CommandArgument('--job', metavar='JOB', choices=['android-api-11', 'android-x86', 'macosx64'], CommandArgument('--job', metavar='JOB', choices=jobchoices,
help='Build job.'), help='Build job.'),
CommandArgument('--verbose', '-v', action='store_true', CommandArgument('--verbose', '-v', action='store_true',
help='Print verbose output.'), help='Print verbose output.'),
@ -1446,6 +1455,9 @@ class PackageFrontend(MachCommandBase):
cache_dir = os.path.join(state_dir, 'package-frontend') cache_dir = os.path.join(state_dir, 'package-frontend')
import which import which
if self._is_windows():
hg = which.which('hg.exe')
else:
hg = which.which('hg') hg = which.which('hg')
# Absolutely must come after the virtualenv is populated! # Absolutely must come after the virtualenv is populated!
@ -1460,12 +1472,16 @@ class PackageFrontend(MachCommandBase):
return (tree, job) return (tree, job)
if self.substs.get('MOZ_BUILD_APP', '') == 'mobile/android': if self.substs.get('MOZ_BUILD_APP', '') == 'mobile/android':
if self.substs['ANDROID_CPU_ARCH'] == 'x86': if self.substs['ANDROID_CPU_ARCH'] == 'x86':
return (tree, 'android-x86') return tree, 'android-x86'
return (tree, 'android-api-11') return tree, 'android-api-11'
if self.defines.get('XP_MACOSX', False): # TODO: check for 32/64 bit builds. We'd like to use HAVE_64BIT_BUILD
# TODO: check for 64 bit builds. We'd like to use HAVE_64BIT_BUILD
# but that relies on the compile environment. # but that relies on the compile environment.
return (tree, 'macosx64') if self.defines.get('XP_LINUX', False):
return tree, 'linux64'
if self.defines.get('XP_MACOSX', False):
return tree, 'macosx64'
if self.defines.get('XP_WIN', False):
return tree, 'win32'
raise Exception('Cannot determine default tree and job for |mach artifact|!') raise Exception('Cannot determine default tree and job for |mach artifact|!')
@ArtifactSubCommand('artifact', 'install', @ArtifactSubCommand('artifact', 'install',

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

@ -166,7 +166,12 @@ class FileAvoidWrite(BytesIO):
existing.close() existing.close()
ensureParentDir(self.name) ensureParentDir(self.name)
with open(self.name, 'w') as file: # Maintain 'b' if specified. 'U' only applies to modes starting with
# 'r', so it is dropped.
writemode = 'w'
if 'b' in self.mode:
writemode += 'b'
with open(self.name, writemode) as file:
file.write(buf) file.write(buf)
if self._capture_diff: if self._capture_diff:

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

@ -75,7 +75,7 @@ config = {
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared', 'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-firefox', 'MOZ_OBJDIR': 'obj-firefox',
'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/nsis-2.46u;C:/mozilla-build/python27;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;' 'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PDBSTR_PATH': '/c/Program Files (x86)/Windows Kits/8.0/Debuggers/x64/srcsrv/pdbstr.exe', 'PDBSTR_PATH': '/c/Program Files (x86)/Windows Kits/8.0/Debuggers/x64/srcsrv/pdbstr.exe',

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

@ -76,7 +76,7 @@ config = {
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared', 'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-firefox', 'MOZ_OBJDIR': 'obj-firefox',
'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/nsis-2.46u;C:/mozilla-build/python27;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;' 'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PDBSTR_PATH': '/c/Program Files (x86)/Windows Kits/8.0/Debuggers/x64/srcsrv/pdbstr.exe', 'PDBSTR_PATH': '/c/Program Files (x86)/Windows Kits/8.0/Debuggers/x64/srcsrv/pdbstr.exe',

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

@ -75,7 +75,8 @@ config = {
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared', 'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-firefox', 'MOZ_OBJDIR': 'obj-firefox',
'PATH': 'C:/mozilla-build/python27;C:/mozilla-build/buildbotve/scripts;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PDBSTR_PATH': '/c/Program Files (x86)/Windows Kits/8.0/Debuggers/x64/srcsrv/pdbstr.exe', 'PDBSTR_PATH': '/c/Program Files (x86)/Windows Kits/8.0/Debuggers/x64/srcsrv/pdbstr.exe',
'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'), 'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'),

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

@ -26,7 +26,7 @@ config = {
'MOZ_AUTOMATION': '1', 'MOZ_AUTOMATION': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-firefox', 'MOZ_OBJDIR': 'obj-firefox',
'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/nsis-2.46u;C:/mozilla-build/python27;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;' 'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'), 'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'),

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

@ -25,7 +25,7 @@ config = {
'MOZ_AUTOMATION': '1', 'MOZ_AUTOMATION': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-firefox', 'MOZ_OBJDIR': 'obj-firefox',
'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/nsis-2.46u;C:/mozilla-build/python27;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;' 'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'), 'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'),

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

@ -25,7 +25,8 @@ config = {
'MOZ_AUTOMATION': '1', 'MOZ_AUTOMATION': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-firefox', 'MOZ_OBJDIR': 'obj-firefox',
'PATH': 'C:/mozilla-build/python27;C:/mozilla-build/buildbotve/scripts;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'), 'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'),
'TINDERBOX_OUTPUT': '1', 'TINDERBOX_OUTPUT': '1',

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

@ -25,7 +25,7 @@ config = {
'MOZ_AUTOMATION': '1', 'MOZ_AUTOMATION': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-graphene', 'MOZ_OBJDIR': 'obj-graphene',
'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/nsis-2.46u;C:/mozilla-build/python27;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;' 'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'), 'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'),

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

@ -25,7 +25,7 @@ config = {
'MOZ_AUTOMATION': '1', 'MOZ_AUTOMATION': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': 'obj-horizon', 'MOZ_OBJDIR': 'obj-horizon',
'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/nsis-2.46u;C:/mozilla-build/python27;' 'PATH': 'C:/mozilla-build/nsis-3.0b1;C:/mozilla-build/python27;'
'C:/mozilla-build/buildbotve/scripts;' 'C:/mozilla-build/buildbotve/scripts;'
'%s' % (os.environ.get('path')), '%s' % (os.environ.get('path')),
'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'), 'PROPERTIES_FILE': os.path.join(os.getcwd(), 'buildprops.json'),

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

@ -924,21 +924,6 @@ function getLocalizedPref(aPrefName, aDefault) {
return aDefault; return aDefault;
} }
/**
* Wrapper for nsIPrefBranch::setComplexValue.
* @param aPrefName
* The name of the pref to set.
*/
function setLocalizedPref(aPrefName, aValue) {
const nsIPLS = Ci.nsIPrefLocalizedString;
try {
var pls = Components.classes["@mozilla.org/pref-localizedstring;1"]
.createInstance(Ci.nsIPrefLocalizedString);
pls.data = aValue;
Services.prefs.setComplexValue(aPrefName, nsIPLS, pls);
} catch (ex) {}
}
/** /**
* Wrapper for nsIPrefBranch::getBoolPref. * Wrapper for nsIPrefBranch::getBoolPref.
* @param aPrefName * @param aPrefName
@ -3122,7 +3107,6 @@ SearchService.prototype = {
this._engines = {}; this._engines = {};
this.__sortedEngines = null; this.__sortedEngines = null;
this._currentEngine = null; this._currentEngine = null;
this._defaultEngine = null;
this._visibleDefaultEngines = []; this._visibleDefaultEngines = [];
this._metaData = {}; this._metaData = {};
this._cacheFileJSON = null; this._cacheFileJSON = null;
@ -3987,10 +3971,6 @@ SearchService.prototype = {
this._currentEngine = null; this._currentEngine = null;
} }
if (engineToRemove == this.defaultEngine) {
this._defaultEngine = null;
}
if (engineToRemove._readOnly) { if (engineToRemove._readOnly) {
// Just hide it (the "hidden" setter will notify) and remove its alias to // Just hide it (the "hidden" setter will notify) and remove its alias to
// avoid future conflicts with other engines. // avoid future conflicts with other engines.
@ -4082,52 +4062,10 @@ SearchService.prototype = {
} }
}, },
get defaultEngine() { get defaultEngine() { return this.currentEngine; },
this._ensureInitialized();
if (!this._defaultEngine) {
let defPref = getGeoSpecificPrefName(BROWSER_SEARCH_PREF + "defaultenginename");
let defaultEngine = this.getEngineByName(getLocalizedPref(defPref, ""))
if (!defaultEngine)
defaultEngine = this._getSortedEngines(false)[0] || null;
this._defaultEngine = defaultEngine;
}
if (this._defaultEngine.hidden)
return this._getSortedEngines(false)[0];
return this._defaultEngine;
},
set defaultEngine(val) { set defaultEngine(val) {
this._ensureInitialized(); this.currentEngine = val;
// Sometimes we get wrapped nsISearchEngine objects (external XPCOM callers),
// and sometimes we get raw Engine JS objects (callers in this file), so
// handle both.
if (!(val instanceof Ci.nsISearchEngine) && !(val instanceof Engine))
FAIL("Invalid argument passed to defaultEngine setter");
let newDefaultEngine = this.getEngineByName(val.name);
if (!newDefaultEngine)
FAIL("Can't find engine in store!", Cr.NS_ERROR_UNEXPECTED);
if (newDefaultEngine == this._defaultEngine)
return;
this._defaultEngine = newDefaultEngine;
let defPref = getGeoSpecificPrefName(BROWSER_SEARCH_PREF + "defaultenginename");
// If we change the default engine in the future, that change should impact
// users who have switched away from and then back to the build's "default"
// engine. So clear the user pref when the defaultEngine is set to the
// build's default engine, so that the defaultEngine getter falls back to
// whatever the default is.
if (this._defaultEngine == this._originalDefaultEngine) {
Services.prefs.clearUserPref(defPref);
}
else {
setLocalizedPref(defPref, this._defaultEngine.name);
}
notifyAction(this._defaultEngine, SEARCH_ENGINE_DEFAULT);
}, },
get currentEngine() { get currentEngine() {
@ -4204,6 +4142,7 @@ SearchService.prototype = {
this.setGlobalAttr("current", newName); this.setGlobalAttr("current", newName);
this.setGlobalAttr("hash", getVerificationHash(newName)); this.setGlobalAttr("hash", getVerificationHash(newName));
notifyAction(this._currentEngine, SEARCH_ENGINE_DEFAULT);
notifyAction(this._currentEngine, SEARCH_ENGINE_CURRENT); notifyAction(this._currentEngine, SEARCH_ENGINE_CURRENT);
}, },

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

@ -458,18 +458,14 @@ function installTestEngine() {
} }
/** /**
* Wrapper for nsIPrefBranch::setComplexValue. * Set a localized preference on the default branch
* @param aPrefName * @param aPrefName
* The name of the pref to set. * The name of the pref to set.
*/ */
function setLocalizedPref(aPrefName, aValue) { function setLocalizedDefaultPref(aPrefName, aValue) {
const nsIPLS = Ci.nsIPrefLocalizedString; let value = "data:text/plain," + BROWSER_SEARCH_PREF + aPrefName + "=" + aValue;
try { Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF)
var pls = Components.classes["@mozilla.org/pref-localizedstring;1"] .setCharPref(aPrefName, value);
.createInstance(Ci.nsIPrefLocalizedString);
pls.data = aValue;
Services.prefs.setComplexValue(aPrefName, nsIPLS, pls);
} catch (ex) {}
} }
@ -496,8 +492,8 @@ function setUpGeoDefaults() {
do_get_file("data/engine2.xml").copyTo(engineDir, "engine2.xml"); do_get_file("data/engine2.xml").copyTo(engineDir, "engine2.xml");
setLocalizedPref("browser.search.defaultenginename", "Test search engine"); setLocalizedDefaultPref("defaultenginename", "Test search engine");
setLocalizedPref("browser.search.defaultenginename.US", "A second test engine"); setLocalizedDefaultPref("defaultenginename.US", "A second test engine");
do_register_cleanup(function() { do_register_cleanup(function() {
removeMetadata(); removeMetadata();

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

@ -17,13 +17,15 @@ function run_test() {
} }
add_task(function* test_defaultEngine() { add_task(function* test_defaultEngine() {
let search = Services.search;
let originalDefault = search.defaultEngine;
let [engine1, engine2] = yield addTestEngines([ let [engine1, engine2] = yield addTestEngines([
{ name: "Test search engine", xmlFileName: "engine.xml" }, { name: "Test search engine", xmlFileName: "engine.xml" },
{ name: "A second test engine", xmlFileName: "engine2.xml" }, { name: "A second test engine", xmlFileName: "engine2.xml" },
]); ]);
let search = Services.search;
search.defaultEngine = engine1; search.defaultEngine = engine1;
do_check_eq(search.defaultEngine, engine1); do_check_eq(search.defaultEngine, engine1);
search.defaultEngine = engine2 search.defaultEngine = engine2
@ -32,22 +34,18 @@ add_task(function* test_defaultEngine() {
do_check_eq(search.defaultEngine, engine1); do_check_eq(search.defaultEngine, engine1);
// Test that hiding the currently-default engine affects the defaultEngine getter // Test that hiding the currently-default engine affects the defaultEngine getter
// (when the default is hidden, we fall back to the first in the list, so move // We fallback first to the original default...
// our second engine to that position)
search.moveEngine(engine2, 0);
engine1.hidden = true; engine1.hidden = true;
do_check_eq(search.defaultEngine, engine2); do_check_eq(search.defaultEngine, originalDefault);
// Test that the default engine is restored when it is unhidden // ... and then to the first visible engine in the list, so move our second
engine1.hidden = false; // engine to that position.
do_check_eq(search.defaultEngine, engine1); search.moveEngine(engine2, 0);
originalDefault.hidden = true;
do_check_eq(search.defaultEngine, engine2);
// Test that setting defaultEngine to an already-hidden engine works, but // Test that setting defaultEngine to an already-hidden engine works, but
// doesn't change the return value of the getter // doesn't change the return value of the getter
engine2.hidden = true; search.defaultEngine = engine1;
search.moveEngine(engine1, 0)
search.defaultEngine = engine2;
do_check_eq(search.defaultEngine, engine1);
engine2.hidden = false;
do_check_eq(search.defaultEngine, engine2); do_check_eq(search.defaultEngine, engine2);
}); });

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

@ -48,11 +48,8 @@ add_task(function* test_persistAcrossRestarts() {
do_check_eq(Services.search.currentEngine.name, kTestEngineName); do_check_eq(Services.search.currentEngine.name, kTestEngineName);
// Cleanup (set the engine back to default). // Cleanup (set the engine back to default).
Services.search.currentEngine = Services.search.defaultEngine; Services.search.resetToOriginalDefaultEngine();
// This check is no longer valid with bug 1102416's patch - defaultEngine do_check_eq(Services.search.currentEngine.name, getDefaultEngineName());
// is not based on the same value as _originalDefaultEngine in non-Firefox
// users of the search service.
//do_check_eq(Services.search.currentEngine.name, getDefaultEngineName());
}); });
// An engine set without a valid hash should be ignored. // An engine set without a valid hash should be ignored.

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

@ -863,7 +863,7 @@ EnvironmentCache.prototype = {
this._log.trace("observe - aTopic: " + aTopic + ", aData: " + aData); this._log.trace("observe - aTopic: " + aTopic + ", aData: " + aData);
switch (aTopic) { switch (aTopic) {
case SEARCH_ENGINE_MODIFIED_TOPIC: case SEARCH_ENGINE_MODIFIED_TOPIC:
if (aData != "engine-default" && aData != "engine-current") { if (aData != "engine-current") {
return; return;
} }
// Record the new default search choice and send the change notification. // Record the new default search choice and send the change notification.

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

@ -1115,10 +1115,10 @@ add_task(function* test_defaultSearchEngine() {
for (let engine of Services.search.getEngines()) { for (let engine of Services.search.getEngines()) {
Services.search.removeEngine(engine); Services.search.removeEngine(engine);
} }
// The search service does not notify "engine-default" when removing a default engine. // The search service does not notify "engine-current" when removing a default engine.
// Manually force the notification. // Manually force the notification.
// TODO: remove this when bug 1165341 is resolved. // TODO: remove this when bug 1165341 is resolved.
Services.obs.notifyObservers(null, "browser-search-engine-modified", "engine-default"); Services.obs.notifyObservers(null, "browser-search-engine-modified", "engine-current");
// Then check that no default engine is reported if none is available. // Then check that no default engine is reported if none is available.
data = TelemetryEnvironment.currentEnvironment; data = TelemetryEnvironment.currentEnvironment;