Merge m-c to graphics

MozReview-Commit-ID: LPeWBwbK82h
This commit is contained in:
Kartikaya Gupta 2017-01-12 12:40:09 -05:00
commit c65ab1c730
978 changed files with 59758 additions and 22064 deletions

View File

@ -8,6 +8,7 @@ module.exports = {
"rules": {
"mozilla/import-globals": "warn",
"mozilla/no-import-into-var-and-global": "error",
"mozilla/no-useless-parameters": "error",
// No (!foo in bar) or (!object instanceof Class)
"no-unsafe-negation": "error",

View File

@ -32,7 +32,6 @@ function dumpAccessibleNode(aNode, level) {
function dumpAccessibleTree(aNode, level) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
level = level || 0;
dumpAccessibleNode(aNode, level);
@ -48,14 +47,12 @@ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
}
function A(o) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var acc = Components.classes['@mozilla.org/accessibilityService;1']
.getService(Components.interfaces.nsIAccessibilityService);
var acc = SpecialPowers.Cc['@mozilla.org/accessibilityService;1']
.getService(SpecialPowers.Ci.nsIAccessibilityService);
return acc.getAccessibleFor(o);
}
function beginAccessible() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
dumpAccessibleTree(A(document),0);
}
setTimeout(beginAccessible, 100);

View File

@ -56,6 +56,6 @@ function destroy() {
// stop listening to preference changes
let branch = prefTargetNS(this).branch;
branch.removeObserver('', prefTargetNS(this).observer, false);
branch.removeObserver('', prefTargetNS(this).observer);
prefTargetNS(this).observer = null;
}

View File

@ -60,7 +60,7 @@ exports.asyncWindowLeakTest = function*(assert, asyncTestFunc) {
// Stop tracking new windows and attempt to GC any resources allocated
// by the test body.
Services.obs.removeObserver(windowObserver, "domwindowopened", false);
Services.obs.removeObserver(windowObserver, "domwindowopened");
yield gc();
// Check to see if any of the windows we saw survived the GC. We consider

View File

@ -2,8 +2,8 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
const { Services } = Cu.import('resource://gre/modules/Services.jsm');
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
const { Services } = Cu.import('resource://gre/modules/Services.jsm', {});
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm', {});
var processId;

View File

@ -45,7 +45,7 @@ this.SafeMode = {
return new Promise((aResolve, aReject) => {
let observer = function(aSubject, aTopic, aData) {
if (Services.prefs.getCharPref(kSafeModePref)) {
Services.prefs.removeObserver(kSafeModePref, observer, false);
Services.prefs.removeObserver(kSafeModePref, observer);
aResolve();
}
}

View File

@ -12,8 +12,8 @@ var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
const { SystemAppProxy } = Cu.import("resource://gre/modules/SystemAppProxy.jsm");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { SystemAppProxy } = Cu.import("resource://gre/modules/SystemAppProxy.jsm", {});
var eventHandler = function(evt) {
if (!evt.detail || evt.detail.type !== "permission-prompt") {
@ -33,4 +33,3 @@ addMessageListener("teardown", function() {
addMessageListener("permission-response", function(detail) {
SystemAppProxy._sendCustomEvent('mozContentEvent', detail);
});

View File

@ -9,8 +9,8 @@
}
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm', {});
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm', {});
const manager = Cc["@mozilla.org/presentation-device/manager;1"]
.getService(Ci.nsIPresentationDeviceManager);
@ -91,4 +91,3 @@ addMessageListener('trigger-device-prompt', function(request_options) {
addMessageListener('presentation-select-response', function(detail) {
SystemAppProxy._sendCustomEvent('mozContentEvent', detail);
});

View File

@ -5,8 +5,8 @@
'use strict';
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm', {});
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm', {});
const glue = Cc["@mozilla.org/presentation/requestuiglue;1"]
.createInstance(Ci.nsIPresentationRequestUIGlue);

View File

@ -3,7 +3,7 @@ var Ci = Components.interfaces;
Cu.importGlobalProperties(['File']);
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
// Load a duplicated copy of the jsm to prevent messing with the currently running one
var scope = {};

View File

@ -1,6 +1,6 @@
var Cu = Components.utils;
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
// Load a duplicated copy of the jsm to prevent messing with the currently running one
var scope = {};

View File

@ -19,7 +19,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager",
// At end of test, restore original state
const ORIGINAL_AUTH_URI = Services.prefs.getCharPref("identity.fxaccounts.auth.uri");
var { SystemAppProxy } = Cu.import("resource://gre/modules/FxAccountsMgmtService.jsm");
var { SystemAppProxy } = Cu.import("resource://gre/modules/FxAccountsMgmtService.jsm", {});
const ORIGINAL_SENDCUSTOM = SystemAppProxy._sendCustomEvent;
do_register_cleanup(function() {
Services.prefs.setCharPref("identity.fxaccounts.auth.uri", ORIGINAL_AUTH_URI);
@ -208,5 +208,3 @@ function httpd_setup (handlers, port=-1) {
return server;
}

View File

@ -961,7 +961,6 @@ pref("security.sandbox.content.level", 2);
pref("security.sandbox.content.level", 1);
#endif
#if defined(MOZ_STACKWALKING)
// This controls the depth of stack trace that is logged when Windows sandbox
// logging is turned on. This is only currently available for the content
// process because the only other sandbox (for GMP) has too strict a policy to
@ -969,7 +968,6 @@ pref("security.sandbox.content.level", 1);
pref("security.sandbox.windows.log.stackTraceDepth", 0);
#endif
#endif
#endif
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
// This pref is discussed in bug 1083344, the naming is inspired from its

View File

@ -124,8 +124,8 @@ var DevEdition = {
uninit() {
Services.prefs.removeObserver(this._devtoolsThemePrefName, this);
Services.obs.removeObserver(this, "lightweight-theme-styling-update", false);
Services.obs.removeObserver(this, "lightweight-theme-window-updated", false);
Services.obs.removeObserver(this, "lightweight-theme-styling-update");
Services.obs.removeObserver(this, "lightweight-theme-window-updated");
if (this.styleSheet) {
this.styleSheet.removeEventListener("load", this);
}

View File

@ -207,18 +207,12 @@ let gDecoderDoctorHandler = {
}
if (type == "adobe-cdm-not-activated" &&
AppConstants.platform == "win") {
if (!AppConstants.isPlatformAndVersionAtLeast("win", "6.1")) {
return gNavigatorBundle.getString("decoder.noCodecsVista.message");
}
return gNavigatorBundle.getString("decoder.noCodecs.message");
}
if (type == "platform-decoder-not-found") {
if (AppConstants.isPlatformAndVersionAtLeast("win", "6.1")) {
if (AppConstants.platform == "win") {
return gNavigatorBundle.getString("decoder.noHWAcceleration.message");
}
if (AppConstants.isPlatformAndVersionAtLeast("win", "6")) {
return gNavigatorBundle.getString("decoder.noHWAccelerationVista.message");
}
if (AppConstants.platform == "linux") {
return gNavigatorBundle.getString("decoder.noCodecsLinux.message");
}

View File

@ -1412,7 +1412,7 @@ var BookmarkingUI = {
if (event.target == event.currentTarget) {
updatePlacesContextMenu(true);
Services.prefs.removeObserver(this.RECENTLY_BOOKMARKED_PREF, prefObserver, false);
Services.prefs.removeObserver(this.RECENTLY_BOOKMARKED_PREF, prefObserver);
PlacesUtils.bookmarks.removeObserver(this._recentlyBookmarkedObserver);
this._recentlyBookmarkedObserver = null;
if (placesContextMenu) {

View File

@ -137,15 +137,15 @@ var gSyncUI = {
// Note that we don't show login errors in a notification bar here, but do
// still need to track a login-failed state so the "Tools" menu updates
// with the correct state.
_loginFailed() {
loginFailed() {
// If Sync isn't already ready, we don't want to force it to initialize
// by referencing Weave.Status - and it isn't going to be accurate before
// Sync is ready anyway.
if (!this.weaveService.ready) {
this.log.debug("_loginFailed has sync not ready, so returning false");
this.log.debug("loginFailed has sync not ready, so returning false");
return false;
}
this.log.debug("_loginFailed has sync state=${sync}",
this.log.debug("loginFailed has sync state=${sync}",
{ sync: Weave.Status.login});
return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
},
@ -163,7 +163,7 @@ var gSyncUI = {
if (!gBrowser)
return Promise.resolve();
let loginFailed = this._loginFailed();
let loginFailed = this.loginFailed();
// Start off with a clean slate
document.getElementById("sync-reauth-state").hidden = true;
@ -266,7 +266,7 @@ var gSyncUI = {
// via the UI.
handleToolbarButton() {
this._needsSetup().then(needsSetup => {
if (needsSetup || this._loginFailed()) {
if (needsSetup || this.loginFailed()) {
this.openSetup();
} else {
this.doSync();
@ -380,7 +380,7 @@ var gSyncUI = {
let needsSetup = yield this._needsSetup();
let needsVerification = yield this._needsVerification();
let loginFailed = this._loginFailed();
let loginFailed = this.loginFailed();
// This is a little messy as the Sync buttons are 1/2 Sync related and
// 1/2 FxA related - so for some strings we use Sync strings, but for
// others we reach into gFxAccounts for strings.

View File

@ -127,11 +127,6 @@ XPCOMUtils.defineLazyGetter(this, "gCustomizeMode", function() {
return new scope.CustomizeMode(window);
});
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function() {
// Only show resizers on Windows 2000 and XP
return AppConstants.isPlatformAndVersionAtMost("win", "5.9");
});
XPCOMUtils.defineLazyGetter(this, "gPrefService", function() {
return Services.prefs;
});
@ -3402,8 +3397,6 @@ var PrintPreviewListener = {
this._chromeState.notificationsOpen = !notificationBox.notificationsHidden;
notificationBox.notificationsHidden = true;
gBrowser.updateWindowResizers();
this._chromeState.findOpen = gFindBarInitialized && !gFindBar.hidden;
if (gFindBarInitialized)
gFindBar.close();
@ -5240,7 +5233,6 @@ function setToolbarVisibility(toolbar, isVisible, persist = true) {
PlacesToolbarHelper.init();
BookmarkingUI.onToolbarVisibilityChange();
gBrowser.updateWindowResizers();
if (isVisible)
ToolbarIconColor.inferFromText();
}
@ -7784,6 +7776,9 @@ var TabContextMenu = {
for (let menuItem of menuItems)
menuItem.disabled = disabled;
if (this.contextTab.hasAttribute("customizemode"))
document.getElementById("context_openTabInWindow").disabled = true;
if (AppConstants.E10S_TESTING_ONLY) {
menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-remote");
for (let menuItem of menuItems) {

View File

@ -474,6 +474,9 @@
accesskey="&syncedTabs.context.copy.accesskey;"
id="syncedTabsCopySelected"/>
<menuseparator/>
<menuitem label="&syncedTabs.context.openAllInTabs.label;"
accesskey="&syncedTabs.context.openAllInTabs.accesskey;"
id="syncedTabsOpenAllInTabs"/>
<menuitem label="&syncSyncNowItem.label;"
accesskey="&syncSyncNowItem.accesskey;"
id="syncedTabsRefresh"/>
@ -545,9 +548,7 @@
#ifdef MENUBAR_CAN_AUTOHIDE
toolbarname="&menubarCmd.label;"
accesskey="&menubarCmd.accesskey;"
#if defined(MOZ_WIDGET_GTK)
autohide="true"
#endif
#endif
context="toolbar-context-menu">
<toolbaritem id="menubar-items" align="center">

View File

@ -215,18 +215,6 @@
]]></body>
</method>
<method name="updateWindowResizers">
<body><![CDATA[
if (!window.gShowPageResizers)
return;
var show = window.windowState == window.STATE_NORMAL;
for (let i = 0; i < this.browsers.length; i++) {
this.browsers[i].showWindowResizer = show;
}
]]></body>
</method>
<method name="_setCloseKeyState">
<parameter name="aEnabled"/>
<body><![CDATA[
@ -538,9 +526,10 @@
<parameter name="aBrowser"/>
<parameter name="aStartsBlank"/>
<parameter name="aWasPreloadedBrowser"/>
<parameter name="aOrigStateFlags"/>
<body>
<![CDATA[
let stateFlags = 0;
let stateFlags = aOrigStateFlags || 0;
// Initialize mStateFlags to non-zero e.g. when creating a progress
// listener for preloaded browsers as there was no progress listener
// around when the content started loading. If the content didn't
@ -1971,10 +1960,6 @@
b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.opener);
}
if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
b.setAttribute("showresizer", "true");
}
if (!aParams.isPreloadBrowser && this.hasAttribute("autocompletepopup")) {
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
}
@ -2839,6 +2824,9 @@
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
var isPending = aOtherTab.hasAttribute("pending");
let otherTabListener = remoteBrowser._tabListeners.get(aOtherTab);
let stateFlags = otherTabListener.mStateFlags;
// Expedite the removal of the icon if it was already scheduled.
if (aOtherTab._soundPlayingAttrRemovalTimer) {
clearTimeout(aOtherTab._soundPlayingAttrRemovalTimer);
@ -2896,7 +2884,7 @@
this.mIsBusy = true;
}
this._swapBrowserDocShells(aOurTab, otherBrowser, Ci.nsIBrowser.SWAP_DEFAULT);
this._swapBrowserDocShells(aOurTab, otherBrowser, Ci.nsIBrowser.SWAP_DEFAULT, stateFlags);
}
// Unregister the previously opened URI
@ -2969,6 +2957,7 @@
<parameter name="aOurTab"/>
<parameter name="aOtherBrowser"/>
<parameter name="aFlags"/>
<parameter name="aStateFlags"/>
<body>
<![CDATA[
// Unhook our progress listener
@ -3025,7 +3014,8 @@
}
// Restore the progress listener
tabListener = this.mTabProgressListener(aOurTab, ourBrowser, false, false);
tabListener = this.mTabProgressListener(aOurTab, ourBrowser, false, false,
aStateFlags);
this._tabListeners.set(aOurTab, tabListener);
const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
@ -4963,7 +4953,6 @@
this.appendChild(this._autoScrollPopup);
this.mCurrentBrowser.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
this.mCurrentBrowser.droppedLinkHandler = handleDroppedLink;
this.updateWindowResizers();
// Hook up the event listeners to the first browser
var tabListener = this.mTabProgressListener(this.mCurrentTab, this.mCurrentBrowser, true, false);
@ -5036,9 +5025,9 @@
<destructor>
<![CDATA[
Services.obs.removeObserver(this, "live-resize-start", false);
Services.obs.removeObserver(this, "live-resize-end", false);
Services.obs.removeObserver(this, "contextual-identity-updated", false);
Services.obs.removeObserver(this, "live-resize-start");
Services.obs.removeObserver(this, "live-resize-end");
Services.obs.removeObserver(this, "contextual-identity-updated");
for (let tab of this.tabs) {
let browser = tab.linkedBrowser;
@ -6007,8 +5996,6 @@
this._handleTabSelect();
this.mTabstripWidth = width;
}
this.tabbrowser.updateWindowResizers();
break;
case "mouseout":
// If the "related target" (the node to which the pointer went) is not

View File

@ -52,7 +52,7 @@ function checkPage(data) {
Services.obs.addObserver(function observer(aSubject, aTopic) {
ok(!Services.io.offline, "After clicking the Try Again button, we're back " +
"online.");
Services.obs.removeObserver(observer, "network:offline-status-changed", false);
Services.obs.removeObserver(observer, "network:offline-status-changed");
finish();
}, "network:offline-status-changed", false);

View File

@ -10,7 +10,7 @@ const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts
const PROGRESS_NOTIFICATION = "addon-progress";
const { REQUIRE_SIGNING } = Cu.import("resource://gre/modules/addons/AddonConstants.jsm", {});
const { Task } = Cu.import("resource://gre/modules/Task.jsm");
const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
var rootDir = getRootDirectory(gTestPath);
var rootPath = rootDir.split('/');

View File

@ -10,15 +10,23 @@ const ID = "permissions@test.mozilla.org";
const DEFAULT_EXTENSION_ICON = "chrome://browser/content/extension.svg";
Services.perms.add(makeURI("https://example.com/"), "install",
Services.perms.ALLOW_ACTION);
function promisePopupNotificationShown(name) {
return new Promise(resolve => {
PopupNotifications.panel.addEventListener("popupshown", () => {
function popupshown() {
let notification = PopupNotifications.getNotification(name);
if (!notification) { return; }
ok(notification, `${name} notification shown`);
ok(PopupNotifications.isPanelOpen, "notification panel open");
PopupNotifications.panel.removeEventListener("popupshown", popupshown);
resolve(PopupNotifications.panel.firstChild);
}, {once: true});
}
PopupNotifications.panel.addEventListener("popupshown", popupshown);
});
}
@ -60,8 +68,14 @@ function checkNotification(panel, url) {
const INSTALL_FUNCTIONS = [
function installMozAM(url) {
return ContentTask.spawn(gBrowser.selectedBrowser, url, function*(cUrl) {
return content.wrappedJSObject.installMozAM(cUrl);
ContentTask.spawn(gBrowser.selectedBrowser, url, function*(cUrl) {
content.wrappedJSObject.installMozAM(cUrl);
});
},
function installTrigger(url) {
ContentTask.spawn(gBrowser.selectedBrowser, url, function*(cUrl) {
content.wrappedJSObject.installTrigger(cUrl);
});
},
];
@ -78,7 +92,37 @@ add_task(function* () {
function* runOnce(installFn, url, cancel) {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
let installPromise = installFn(url);
let installPromise = new Promise(resolve => {
let listener = {
onDownloadCancelled() {
AddonManager.removeInstallListener(listener);
resolve(false);
},
onDownloadFailed() {
AddonManager.removeInstallListener(listener);
resolve(false);
},
onInstallCancelled() {
AddonManager.removeInstallListener(listener);
resolve(false);
},
onInstallEnded() {
AddonManager.removeInstallListener(listener);
resolve(true);
},
onInstallFailed() {
AddonManager.removeInstallListener(listener);
resolve(false);
},
};
AddonManager.addInstallListener(listener);
});
installFn(url);
let panel = yield promisePopupNotificationShown("addon-webext-permissions");
checkNotification(panel, url);
@ -92,10 +136,10 @@ add_task(function* () {
let result = yield installPromise;
let addon = yield promiseGetAddonByID(ID);
if (cancel) {
is(result, "onInstallCancelled", "Installation was cancelled");
ok(!result, "Installation was cancelled");
is(addon, null, "Extension is not installed");
} else {
is(result, "onInstallEnded", "Installation completed");
ok(result, "Installation completed");
isnot(addon, null, "Extension is installed");
addon.uninstall();
}

View File

@ -21,7 +21,7 @@ var Downloads = (Components.utils.import("resource://gre/modules/Downloads.jsm",
function promiseFormHistoryRemoved() {
let deferred = Promise.defer();
Services.obs.addObserver(function onfh() {
Services.obs.removeObserver(onfh, "satchel-storage-changed", false);
Services.obs.removeObserver(onfh, "satchel-storage-changed");
deferred.resolve();
}, "satchel-storage-changed", false);
return deferred.promise;

View File

@ -177,3 +177,40 @@ add_task(function* test_dragging_adoption_events() {
yield BrowserTestUtils.closeWindow(win1);
yield BrowserTestUtils.closeWindow(win2);
});
/**
* Tests that per-site zoom settings remain active after a tab is
* dragged between windows.
*/
add_task(function* test_dragging_zoom_handling() {
const ZOOM_FACTOR = 1.62;
let win1 = yield BrowserTestUtils.openNewBrowserWindow();
let win2 = yield BrowserTestUtils.openNewBrowserWindow();
let tab1 = yield BrowserTestUtils.openNewForegroundTab(win1.gBrowser);
let tab2 = yield BrowserTestUtils.openNewForegroundTab(win2.gBrowser,
"http://example.com/");
win2.FullZoom.setZoom(ZOOM_FACTOR);
FullZoomHelper.zoomTest(tab2, ZOOM_FACTOR,
"Original tab should have correct zoom factor");
let effect = EventUtils.synthesizeDrop(tab2, tab1,
[[{type: TAB_DROP_TYPE, data: tab2}]],
null, win2, win1);
is(effect, "move", "Tab should be moved from win2 to win1.");
// Delay slightly to make sure we've finished executing any promise
// chains in the zoom code.
yield new Promise(resolve => setTimeout(resolve, 0));
FullZoomHelper.zoomTest(win1.gBrowser.selectedTab, ZOOM_FACTOR,
"Dragged tab should have correct zoom factor");
win1.FullZoom.reset();
yield BrowserTestUtils.closeWindow(win1);
yield BrowserTestUtils.closeWindow(win2);
});

View File

@ -7,19 +7,13 @@
<body>
<script type="text/javascript">
function installMozAM(url) {
return navigator.mozAddonManager.createInstall({url}).then(install => new Promise(resolve => {
const EVENTS = [
"onDownloadCancelled",
"onDownloadFailed",
"onInstallCancelled",
"onInstallEnded",
"onInstallFailed",
];
for (let event of EVENTS) {
install.addEventListener(event, () => { resolve(event); });
}
return navigator.mozAddonManager.createInstall({url}).then(install => {
install.install();
}));
});
}
function installTrigger(url) {
InstallTrigger.install({extension: url});
}
</script>
</body>

View File

@ -40,8 +40,8 @@ window.addEventListener("message", function(event) {
getService(SpecialPowers.Ci.nsIPermissionManager);
var ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
var uri1 = ioService.newURI(frames.testFrame.location, null, null);
var uri2 = ioService.newURI(frames.testFrame3.location, null, null);
var uri1 = ioService.newURI(frames.testFrame.location);
var uri2 = ioService.newURI(frames.testFrame3.location);
var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);

View File

@ -44,6 +44,22 @@ var tests = [
copyVal: "<e>xample.com",
copyExpected: "e"
},
{
copyVal: "<e>x<a>mple.com",
copyExpected: "ea"
},
{
copyVal: "<e><xa>mple.com",
copyExpected: "exa"
},
{
copyVal: "<e><xa>mple.co<m>",
copyExpected: "exam"
},
{
copyVal: "<e><xample.co><m>",
copyExpected: "example.com"
},
// pageproxystate="valid" from this point on (due to the load)
{
@ -63,6 +79,14 @@ var tests = [
copyVal: "<e>xample.com",
copyExpected: "e"
},
{
copyVal: "<e>xample.co<m>",
copyExpected: "em"
},
{
copyVal: "<exam><ple.com>",
copyExpected: "example.com"
},
{
loadURL: "http://example.com/foo",
@ -200,15 +224,38 @@ function testCopy(copyVal, targetValue, cb) {
waitForClipboard(targetValue, function() {
gURLBar.focus();
if (copyVal) {
let startBracket = copyVal.indexOf("<");
let endBracket = copyVal.indexOf(">");
if (startBracket == -1 || endBracket == -1 ||
startBracket > endBracket ||
copyVal.replace("<", "").replace(">", "") != gURLBar.textValue) {
let offsets = [];
while (true) {
let startBracket = copyVal.indexOf("<");
let endBracket = copyVal.indexOf(">");
if (startBracket == -1 && endBracket == -1) {
break;
}
if (startBracket > endBracket || startBracket == -1) {
offsets = [];
break;
}
offsets.push([startBracket, endBracket - 1]);
copyVal = copyVal.replace("<", "").replace(">", "");
}
if (offsets.length == 0 ||
copyVal != gURLBar.textValue) {
ok(false, "invalid copyVal: " + copyVal);
}
gURLBar.selectionStart = startBracket;
gURLBar.selectionEnd = endBracket - 1;
gURLBar.selectionStart = offsets[0][0];
gURLBar.selectionEnd = offsets[0][1];
if (offsets.length > 1) {
let sel = gURLBar.editor.selection;
let r0 = sel.getRangeAt(0);
let node0 = r0.startContainer;
sel.removeAllRanges();
offsets.map(function(startEnd) {
let range = r0.cloneRange();
range.setStart(node0, startEnd[0]);
range.setEnd(node0, startEnd[1]);
sel.addRange(range);
});
}
} else {
gURLBar.select();
}

View File

@ -758,7 +758,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<body><![CDATA[
// Grab the actual input field's value, not our value, which could include moz-action:
var inputVal = this.inputField.value;
var selectedVal = inputVal.substring(this.selectionStart, this.selectionEnd);
let selection = this.editor.selection;
var selectedVal = selection.toString();
// Handle multiple-range selection as a string for simplicity.
if (selection.rangeCount > 1) {
return selectedVal;
}
// If the selection doesn't start at the beginning or doesn't span the full domain or
// the URL bar is modified or there is no text at all, nothing else to do here.

View File

@ -1,12 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML -*- -->
<!-- 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/. -->
<overlay id="win6-browser-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<toolbar id="toolbar-menubar"
autohide="true"/>
</overlay>

View File

@ -6,9 +6,6 @@ browser.jar:
#ifdef XP_MACOSX
% overlay chrome://mozapps/content/update/updates.xul chrome://browser/content/softwareUpdateOverlay.xul
#endif
#ifdef XP_WIN
% overlay chrome://browser/content/browser.xul chrome://browser/content/win6BrowserOverlay.xul os=WINNT osversion>=6
#endif
% overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
% overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
@ -179,9 +176,6 @@ browser.jar:
* content/browser/webrtcIndicator.xul (content/webrtcIndicator.xul)
content/browser/webrtcIndicator.js (content/webrtcIndicator.js)
#endif
#ifdef XP_WIN
content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
#endif
# the following files are browser-specific overrides
* content/browser/license.html (/toolkit/content/license.html)
% override chrome://global/content/license.html chrome://browser/content/license.html

View File

@ -26,15 +26,11 @@
<label class="identity-popup-headline hostless" crop="end"/>
</label>
<description class="identity-popup-connection-not-secure"
value="&identity.connectionNotSecure;"
when-connection="not-secure secure-cert-user-overridden"/>
when-connection="not-secure secure-cert-user-overridden">&identity.connectionNotSecure;</description>
<description class="identity-popup-connection-secure"
value="&identity.connectionSecure;"
when-connection="secure secure-ev"/>
<description value="&identity.connectionInternal;"
when-connection="chrome"/>
<description value="&identity.connectionFile;"
when-connection="file"/>
when-connection="secure secure-ev">&identity.connectionSecure;</description>
<description when-connection="chrome">&identity.connectionInternal;</description>
<description when-connection="file">&identity.connectionFile;</description>
<vbox id="identity-popup-security-descriptions">
<description class="identity-popup-warning-gray"
@ -105,11 +101,9 @@
<label class="identity-popup-headline hostless" crop="end"/>
</label>
<description class="identity-popup-connection-not-secure"
value="&identity.connectionNotSecure;"
when-connection="not-secure secure-cert-user-overridden"/>
when-connection="not-secure secure-cert-user-overridden">&identity.connectionNotSecure;</description>
<description class="identity-popup-connection-secure"
value="&identity.connectionSecure;"
when-connection="secure secure-ev"/>
when-connection="secure secure-ev">&identity.connectionSecure;</description>
</vbox>
<vbox id="identity-popup-securityView-body" flex="1">

View File

@ -38,6 +38,7 @@ const kPrefCustomizationState = "browser.uiCustomization.state";
const kPrefCustomizationAutoAdd = "browser.uiCustomization.autoAdd";
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
const kPrefDrawInTitlebar = "browser.tabs.drawInTitlebar";
const kPrefSelectedThemeID = "lightweightThemes.selectedThemeID";
const kPrefWebIDEInNavbar = "devtools.webide.widget.inNavbarByDefault";
const kExpectedWindowURL = "chrome://browser/content/browser.xul";
@ -262,24 +263,14 @@ var CustomizableUIInternal = {
defaultCollapsed: false,
}, true);
if (AppConstants.platform != "macosx") {
if (AppConstants.MENUBAR_CAN_AUTOHIDE) {
this.registerArea(CustomizableUI.AREA_MENUBAR, {
legacy: true,
type: CustomizableUI.TYPE_TOOLBAR,
defaultPlacements: [
"menubar-items",
],
get defaultCollapsed() {
if (AppConstants.MENUBAR_CAN_AUTOHIDE) {
if (AppConstants.platform == "linux") {
return true;
}
// This is duplicated logic from /browser/base/jar.mn
// for win6BrowserOverlay.xul.
return AppConstants.isPlatformAndVersionAtLeast("win", 6);
}
return false;
}
defaultCollapsed: true,
}, true);
}
@ -1930,15 +1921,7 @@ var CustomizableUIInternal = {
// state immediately when a browser window opens, which is important for
// other consumers of this API.
loadSavedState() {
let state = null;
try {
state = Services.prefs.getCharPref(kPrefCustomizationState);
} catch (e) {
log.debug("No saved state found");
// This will fail if nothing has been customized, so silently fall back to
// the defaults.
}
let state = Services.prefs.getCharPref(kPrefCustomizationState);
if (!state) {
return;
}
@ -2524,18 +2507,18 @@ var CustomizableUIInternal = {
},
_resetUIState() {
try {
gUIStateBeforeReset.drawInTitlebar = Services.prefs.getBoolPref(kPrefDrawInTitlebar);
gUIStateBeforeReset.uiCustomizationState = Services.prefs.getCharPref(kPrefCustomizationState);
gUIStateBeforeReset.currentTheme = LightweightThemeManager.currentTheme;
} catch (e) { }
this._resetExtraToolbars();
Services.prefs.clearUserPref(kPrefCustomizationState);
gUIStateBeforeReset.selectedThemeID = Services.prefs.getCharPref(kPrefSelectedThemeID);
let selectedThemeID = Services.prefs.getDefaultBranch("").getCharPref(kPrefSelectedThemeID);
LightweightThemeManager.currentTheme =
selectedThemeID ? LightweightThemeManager.getUsedTheme(selectedThemeID) : null;
gUIStateBeforeReset.drawInTitlebar = Services.prefs.getBoolPref(kPrefDrawInTitlebar);
Services.prefs.clearUserPref(kPrefDrawInTitlebar);
LightweightThemeManager.currentTheme = null;
log.debug("State reset");
gUIStateBeforeReset.uiCustomizationState = Services.prefs.getCharPref(kPrefCustomizationState);
Services.prefs.clearUserPref(kPrefCustomizationState);
// Reset placements to make restoring default placements possible.
gPlacements = new Map();
@ -2603,7 +2586,7 @@ var CustomizableUIInternal = {
let uiCustomizationState = gUIStateBeforeReset.uiCustomizationState;
let drawInTitlebar = gUIStateBeforeReset.drawInTitlebar;
let currentTheme = gUIStateBeforeReset.currentTheme;
let selectedThemeID = gUIStateBeforeReset.selectedThemeID;
// Need to clear the previous state before setting the prefs
// because pref observers may check if there is a previous UI state.
@ -2611,7 +2594,8 @@ var CustomizableUIInternal = {
Services.prefs.setCharPref(kPrefCustomizationState, uiCustomizationState);
Services.prefs.setBoolPref(kPrefDrawInTitlebar, drawInTitlebar);
LightweightThemeManager.currentTheme = currentTheme;
LightweightThemeManager.currentTheme =
selectedThemeID ? LightweightThemeManager.getUsedTheme(selectedThemeID) : null;
this.loadSavedState();
// If the user just customizes toolbar/titlebar visibility, gSavedState will be null
// and we don't need to do anything else here:
@ -2790,8 +2774,9 @@ var CustomizableUIInternal = {
return false;
}
if (LightweightThemeManager.currentTheme) {
log.debug(LightweightThemeManager.currentTheme + " theme is non-default");
if (Services.prefs.getDefaultBranch("").getCharPref(kPrefSelectedThemeID) !=
Services.prefs.getCharPref(kPrefSelectedThemeID)) {
log.debug(kPrefSelectedThemeID + " pref is non-default");
return false;
}

View File

@ -449,7 +449,7 @@ CustomizeMode.prototype = {
yield this._doTransition(false);
this.removeLWTStyling();
Services.obs.removeObserver(this, "lightweight-theme-window-updated", false);
Services.obs.removeObserver(this, "lightweight-theme-window-updated");
if (this.browser.selectedTab == gTab) {
if (gTab.linkedBrowser.currentURI.spec == "about:blank") {

View File

@ -60,12 +60,12 @@ add_task(function*() {
function promiseObserverNotification(aObserver) {
let deferred = Promise.defer();
function notificationCallback(e) {
Services.obs.removeObserver(notificationCallback, aObserver, false);
Services.obs.removeObserver(notificationCallback, aObserver);
clearTimeout(timeoutId);
deferred.resolve();
}
let timeoutId = setTimeout(() => {
Services.obs.removeObserver(notificationCallback, aObserver, false);
Services.obs.removeObserver(notificationCallback, aObserver);
deferred.reject("Notification '" + aObserver + "' did not happen within 20 seconds.");
}, kTimeoutInMS);
Services.obs.addObserver(notificationCallback, aObserver, false);

View File

@ -436,8 +436,8 @@ DistributionCustomizer.prototype = {
value = value.replace(/%LOCALE%/g, this._locale);
value = value.replace(/%LANGUAGE%/g, this._language);
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults._prefBranch.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
}
defaults._prefBranch.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
} catch (e) { /* ignore bad prefs and move on */ }
}
}

View File

@ -324,6 +324,7 @@ function MenuItem(extension, createProperties, isRoot = false) {
this.setDefaults();
this.setProps(createProperties);
if (!this.hasOwnProperty("_id")) {
this.id = gNextMenuItemID++;
}
@ -351,6 +352,12 @@ MenuItem.prototype = {
if (createProperties.targetUrlPatterns != null) {
this.targetUrlMatchPattern = new MatchPattern(this.targetUrlPatterns);
}
// If a child MenuItem does not specify any contexts, then it should
// inherit the contexts specified from its parent.
if (createProperties.parentId && !createProperties.contexts) {
this.contexts = this.parent.contexts;
}
},
setDefaults() {

View File

@ -11,7 +11,7 @@ var {
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
const ssOnChangedTopic = "sessionstore-closed-objects-changed";
const SS_ON_CLOSED_OBJECTS_CHANGED = "sessionstore-closed-objects-changed";
function getRecentlyClosed(maxResults, extension) {
let recentlyClosed = [];
@ -62,6 +62,7 @@ extensions.registerSchemaAPI("sessions", "addon_parent", context => {
let maxResults = filter.maxResults == undefined ? this.MAX_SESSION_RESULTS : filter.maxResults;
return Promise.resolve(getRecentlyClosed(maxResults, extension));
},
restore: function(sessionId) {
let session, closedId;
if (sessionId) {
@ -90,31 +91,15 @@ extensions.registerSchemaAPI("sessions", "addon_parent", context => {
}
return createSession(session, extension, closedId);
},
onChanged: new SingletonEventManager(context, "sessions.onChanged", fire => {
let listenerCount = 0;
let observer = {
observe: function() {
this.emit("changed");
},
};
EventEmitter.decorate(observer);
let listener = (event) => {
let observer = () => {
context.runSafe(fire);
};
observer.on("changed", listener);
listenerCount++;
if (listenerCount == 1) {
Services.obs.addObserver(observer, ssOnChangedTopic, false);
}
Services.obs.addObserver(observer, SS_ON_CLOSED_OBJECTS_CHANGED, false);
return () => {
observer.off("changed", listener);
listenerCount -= 1;
if (!listenerCount) {
Services.obs.removeObserver(observer, ssOnChangedTopic);
}
Services.obs.removeObserver(observer, SS_ON_CLOSED_OBJECTS_CHANGED);
};
}).api(),
},

View File

@ -710,6 +710,15 @@ ExtensionTabManager.prototype = {
incognito: Boolean(tab.state && tab.state.isPrivate),
};
if (this.hasTabPermission(tab)) {
let entries = tab.state ? tab.state.entries : tab.entries;
result.url = entries[0].url;
result.title = entries[0].title;
if (tab.image) {
result.favIconUrl = tab.image;
}
}
return result;
},

View File

@ -63,6 +63,7 @@ support-files =
[browser_ext_runtime_setUninstallURL.js]
[browser_ext_sessions_getRecentlyClosed.js]
[browser_ext_sessions_getRecentlyClosed_private.js]
[browser_ext_sessions_getRecentlyClosed_tabs.js]
[browser_ext_sessions_restore.js]
[browser_ext_simple.js]
[browser_ext_tab_runtimeConnect.js]

View File

@ -14,8 +14,8 @@ add_task(function* test_actionContextMenus() {
const contexts = ["page_action", "browser_action"];
const parentId = browser.contextMenus.create({contexts, title: "parent"});
await browser.contextMenus.create({contexts, parentId, title: "click A"});
await browser.contextMenus.create({contexts, parentId, title: "click B"});
await browser.contextMenus.create({parentId, title: "click A"});
await browser.contextMenus.create({parentId, title: "click B"});
for (let i = 1; i < 9; i++) {
await browser.contextMenus.create({contexts, title: `click ${i}`});
@ -69,8 +69,11 @@ add_task(function* test_tabContextMenu() {
permissions: ["contextMenus"],
},
async background() {
await browser.contextMenus.create({title: "alpha", contexts: ["tab"]});
await browser.contextMenus.create({title: "beta", contexts: ["tab"]});
await browser.contextMenus.create({
id: "alpha-beta-parent", title: "alpha-beta parent", contexts: ["tab"],
});
await browser.contextMenus.create({parentId: "alpha-beta-parent", title: "alpha"});
await browser.contextMenus.create({parentId: "alpha-beta-parent", title: "beta"});
browser.contextMenus.onClicked.addListener((info, tab) => {
browser.test.sendMessage("click", {info, tab});
@ -103,7 +106,7 @@ add_task(function* test_tabContextMenu() {
is(separator.tagName, "menuseparator", "Separator before first extension item");
is(submenu.tagName, "menu", "Correct submenu type");
is(submenu.label, "Generated extension", "Correct submenu title");
is(submenu.label, "alpha-beta parent", "Correct submenu title");
is(gamma.tagName, "menuitem", "Third menu item type is correct");
is(gamma.label, "gamma", "Third menu item label is correct");

View File

@ -0,0 +1,96 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function expectedTabInfo(tab, window) {
let browser = tab.linkedBrowser;
return {
url: browser.currentURI.spec,
title: browser.contentTitle,
favIconUrl: window.gBrowser.getIcon(tab),
};
}
function checkTabInfo(expected, actual) {
for (let prop in expected) {
is(actual[prop], expected[prop], `Expected value found for ${prop} of tab object.`);
}
}
add_task(async function test_sessions_get_recently_closed_tabs() {
async function background() {
browser.test.onMessage.addListener(async msg => {
if (msg == "check-sessions") {
let recentlyClosed = await browser.sessions.getRecentlyClosed();
browser.test.sendMessage("recentlyClosed", recentlyClosed);
}
});
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["sessions", "tabs"],
},
background,
});
let win = await BrowserTestUtils.openNewBrowserWindow();
await BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, "about:addons");
await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
let expectedTabs = [];
let tab = win.gBrowser.selectedTab;
expectedTabs.push(expectedTabInfo(tab, win));
for (let url of ["about:robots", "about:mozilla"]) {
tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, url);
expectedTabs.push(expectedTabInfo(tab, win));
}
await extension.startup();
// Test with a closed tab.
await BrowserTestUtils.removeTab(tab);
extension.sendMessage("check-sessions");
let recentlyClosed = await extension.awaitMessage("recentlyClosed");
let tabInfo = recentlyClosed[0].tab;
let expectedTab = expectedTabs.pop();
checkTabInfo(expectedTab, tabInfo);
// Test with a closed window containing tabs.
await BrowserTestUtils.closeWindow(win);
extension.sendMessage("check-sessions");
recentlyClosed = await extension.awaitMessage("recentlyClosed");
let tabInfos = recentlyClosed[0].window.tabs;
is(tabInfos.length, 2, "Expected number of tabs in closed window.");
for (let x = 0; x < tabInfos.length; x++) {
checkTabInfo(expectedTabs[x], tabInfos[x]);
}
await extension.unload();
// Test without tabs permission.
extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["sessions"],
},
background,
});
await extension.startup();
extension.sendMessage("check-sessions");
recentlyClosed = await extension.awaitMessage("recentlyClosed");
tabInfos = recentlyClosed[0].window.tabs;
is(tabInfos.length, 2, "Expected number of tabs in closed window.");
for (let tabInfo of tabInfos) {
for (let prop in expectedTabs[0]) {
is(undefined,
tabInfo[prop],
`${prop} of tab object is undefined without tabs permission.`);
}
}
await extension.unload();
});

View File

@ -17,8 +17,8 @@
* promiseContentDimensions alterContent
*/
const {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm");
const {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
const {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm", {});
const {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
// We run tests under two different configurations, from browser.ini and
// browser-remote.ini. When running from browser-remote.ini, the tests are

View File

@ -2,7 +2,7 @@
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let eseBackStage = Cu.import("resource:///modules/ESEDBReader.jsm");
let eseBackStage = Cu.import("resource:///modules/ESEDBReader.jsm", {});
let ESE = eseBackStage.ESE;
let KERNEL = eseBackStage.KERNEL;
let gLibs = eseBackStage.gLibs;
@ -468,4 +468,3 @@ add_task(function*() {
}
}
});

View File

@ -1,6 +1,6 @@
"use strict";
let AutoMigrateBackstage = Cu.import("resource:///modules/AutoMigrate.jsm"); /* globals AutoMigrate */
Cu.import("resource:///modules/AutoMigrate.jsm", this);
let gShimmedMigratorKeyPicker = null;
let gShimmedMigrator = null;
@ -11,6 +11,8 @@ const kUsecPerMin = 60 * 1000000;
// we get in trouble because the object itself is frozen, and Proxies can't
// return a different value to an object when directly proxying a frozen
// object.
let AutoMigrateBackstage = Cu.import("resource:///modules/AutoMigrate.jsm", {});
AutoMigrateBackstage.MigrationUtils = new Proxy({}, {
get(target, name) {
if (name == "getMigratorKeyForDefaultBrowser" && gShimmedMigratorKeyPicker) {
@ -608,4 +610,3 @@ add_task(function* checkUndoVisitsState() {
"1 unrelated.org visits should have persisted as it's not involved in the import.");
yield PlacesTestUtils.clearHistory();
});

View File

@ -98,7 +98,7 @@ PrefsProvider.prototype = {
uninit() {
for (let pref of gPrefsMap.keys()) {
Services.prefs.removeObserver(pref, this, false);
Services.prefs.removeObserver(pref, this);
}
}
};

View File

@ -56,7 +56,7 @@ SearchProvider.prototype = {
uninit() {
try {
Services.obs.removeObserver(this, CURRENT_ENGINE, true);
Services.obs.removeObserver(this, CURRENT_ENGINE);
} catch (e) {
Cu.reportError(e);
}

View File

@ -10,7 +10,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/PageThumbs.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
const {OS} = Cu.import("resource://gre/modules/osfile.jsm");
const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
XPCOMUtils.defineLazyModuleGetter(this, "BackgroundPageThumbs",
"resource://gre/modules/BackgroundPageThumbs.jsm");

View File

@ -439,8 +439,7 @@ BrowserGlue.prototype = {
this._flashHangCount = 0;
this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve);
if (AppConstants.isPlatformAndVersionAtMost("win", "5.2") ||
AppConstants.platform == "macosx") {
if (AppConstants.platform == "macosx") {
// Handles prompting to inform about incompatibilites when accessibility
// and e10s are active together.
E10SAccessibilityCheck.init();

View File

@ -42,7 +42,7 @@ function clearAllPlacesFavicons() {
observe(aSubject, aTopic, aData) {
if (aTopic === "places-favicons-expired") {
resolve();
Services.obs.removeObserver(observer, "places-favicons-expired", false);
Services.obs.removeObserver(observer, "places-favicons-expired");
}
}
};
@ -102,7 +102,7 @@ function observeFavicon(aFirstPartyDomain, aExpectedCookie, aPageURI) {
}
if (faviconReqXUL && faviconReqPlaces) {
Services.obs.removeObserver(observer, "http-on-modify-request", false);
Services.obs.removeObserver(observer, "http-on-modify-request");
resolve();
}
}
@ -132,8 +132,8 @@ function waitOnFaviconResponse(aFaviconURL) {
};
resolve(result);
Services.obs.removeObserver(observer, "http-on-examine-response", false);
Services.obs.removeObserver(observer, "http-on-examine-cached-response", false);
Services.obs.removeObserver(observer, "http-on-examine-response");
Services.obs.removeObserver(observer, "http-on-examine-cached-response");
}
}
};

View File

@ -42,7 +42,7 @@ function clearAllPlacesFavicons() {
observe(aSubject, aTopic, aData) {
if (aTopic === "places-favicons-expired") {
resolve();
Services.obs.removeObserver(observer, "places-favicons-expired", false);
Services.obs.removeObserver(observer, "places-favicons-expired");
}
}
};
@ -196,7 +196,7 @@ function* doTest(aTestPage, aFaviconHost, aFaviconURL) {
// Waiting for favicon requests are all made.
yield observer.promise;
Services.obs.removeObserver(observer, "http-on-modify-request", false);
Services.obs.removeObserver(observer, "http-on-modify-request");
yield BrowserTestUtils.removeTab(tabInfo.tab);
}

View File

@ -41,7 +41,7 @@ var gSearchPane = {
Services.obs.addObserver(this, "browser-search-engine-modified", false);
window.addEventListener("unload", () => {
Services.obs.removeObserver(this, "browser-search-engine-modified", false);
Services.obs.removeObserver(this, "browser-search-engine-modified");
});
this._initAutocomplete();

View File

@ -35,19 +35,43 @@ const mockOfflineAppCacheHelper = {
const mockSiteDataManager = {
sites: new Map([
[
"https://account.xyz.com/",
{
usage: 1024 * 200,
host: "account.xyz.com",
status: Ci.nsIPermissionManager.ALLOW_ACTION
}
],
[
"https://shopping.xyz.com/",
{
usage: 102400,
usage: 1024 * 100,
host: "shopping.xyz.com",
status: Ci.nsIPermissionManager.DENY_ACTION
}
],
[
"https://video.bar.com/",
{
usage: 1024 * 20,
host: "video.bar.com",
status: Ci.nsIPermissionManager.ALLOW_ACTION
}
],
[
"https://music.bar.com/",
{
usage: 10240,
usage: 1024 * 10,
host: "music.bar.com",
status: Ci.nsIPermissionManager.DENY_ACTION
}
],
[
"https://books.foo.com/",
{
usage: 1024 * 2,
host: "books.foo.com",
status: Ci.nsIPermissionManager.ALLOW_ACTION
}
],
@ -304,3 +328,49 @@ add_task(function* () {
}
});
add_task(function* () {
yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
mockSiteDataManager.register();
let updatePromise = promiseSitesUpdated();
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield updatePromise;
// Open the siteDataSettings subdialog
let doc = gBrowser.selectedBrowser.contentDocument;
let settingsBtn = doc.getElementById("siteDataSettings");
let dialogOverlay = doc.getElementById("dialogOverlay");
let dialogPromise = promiseLoadSubDialog("chrome://browser/content/preferences/siteDataSettings.xul");
settingsBtn.doCommand();
yield dialogPromise;
is(dialogOverlay.style.visibility, "visible", "The dialog should be visible");
let frameDoc = doc.getElementById("dialogFrame").contentDocument;
let searchBox = frameDoc.getElementById("searchBox");
let mockOrigins = Array.from(mockSiteDataManager.sites.keys());
searchBox.value = "xyz";
searchBox.doCommand();
assertSitesListed(mockOrigins.filter(o => o.includes("xyz")));
searchBox.value = "bar";
searchBox.doCommand();
assertSitesListed(mockOrigins.filter(o => o.includes("bar")));
searchBox.value = "";
searchBox.doCommand();
assertSitesListed(mockOrigins);
mockSiteDataManager.unregister();
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
function assertSitesListed(origins) {
let sitesList = frameDoc.getElementById("sitesList");
let totalSitesNumber = sitesList.getElementsByTagName("richlistitem").length;
is(totalSitesNumber, origins.length, "Should list the right sites number");
origins.forEach(origin => {
let site = sitesList.querySelector(`richlistitem[data-origin="${origin}"]`);
ok(site instanceof XULElement, `Should list the site of ${origin}`);
});
}
});

View File

@ -2,6 +2,10 @@
* 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/. */
#searchBoxContainer {
-moz-box-align: center;
}
#sitesList {
min-height: 20em;
}

View File

@ -23,6 +23,7 @@ let gSiteDataSettings = {
_sites: null,
_list: null,
_searchBox: null,
init() {
function setEventListener(id, eventType, callback) {
@ -31,6 +32,7 @@ let gSiteDataSettings = {
}
this._list = document.getElementById("sitesList");
this._searchBox = document.getElementById("searchBox");
SiteDataManager.getSites().then(sites => {
this._sites = sites;
let sortCol = document.getElementById("hostCol");
@ -41,6 +43,7 @@ let gSiteDataSettings = {
setEventListener("hostCol", "click", this.onClickTreeCol);
setEventListener("usageCol", "click", this.onClickTreeCol);
setEventListener("statusCol", "click", this.onClickTreeCol);
setEventListener("searchBox", "command", this.onCommandSearch);
},
/**
@ -89,19 +92,29 @@ let gSiteDataSettings = {
col.setAttribute("data-last-sortDirection", sortDirection);
},
/**
* @param sites {Array} array of metadata of sites
*/
_buildSitesList(sites) {
// Clear old entries.
while (this._list.childNodes.length > 1) {
this._list.removeChild(this._list.lastChild);
let oldItems = this._list.querySelectorAll("richlistitem");
for (let item of oldItems) {
item.remove();
}
let prefStrBundle = document.getElementById("bundlePreferences");
let keyword = this._searchBox.value.toLowerCase().trim();
for (let data of sites) {
let host = data.uri.host;
if (keyword && !host.includes(keyword)) {
continue;
}
let statusStrId = data.status === Ci.nsIPermissionManager.ALLOW_ACTION ? "important" : "default";
let size = DownloadUtils.convertByteUnits(data.usage);
let item = document.createElement("richlistitem");
item.setAttribute("data-origin", data.uri.spec);
item.setAttribute("host", data.uri.host);
item.setAttribute("host", host);
item.setAttribute("status", prefStrBundle.getString(statusStrId));
item.setAttribute("usage", prefStrBundle.getFormattedString("siteUsage", size));
this._list.appendChild(item);
@ -111,5 +124,9 @@ let gSiteDataSettings = {
onClickTreeCol(e) {
this._sortSites(this._sites, e.target);
this._buildSitesList(this._sites);
},
onCommandSearch() {
this._buildSitesList(this._sites);
}
};

View File

@ -26,6 +26,12 @@
<description>&settings.description;</description>
<separator class="thin"/>
<hbox id="searchBoxContainer">
<label accesskey="&search.accesskey;" control="searchBox">&search.label;</label>
<textbox id="searchBox" type="search" flex="1"/>
</hbox>
<separator class="thin"/>
<richlistbox id="sitesList" orient="vertical" flex="1">
<listheader>
<treecol flex="4" width="50" label="&hostCol.label;" id="hostCol"/>

View File

@ -35,7 +35,7 @@ function clearAllPlacesFavicons() {
observe(aSubject, aTopic, aData) {
if (aTopic === "places-favicons-expired") {
resolve();
Services.obs.removeObserver(observer, "places-favicons-expired", false);
Services.obs.removeObserver(observer, "places-favicons-expired");
}
}
};
@ -105,7 +105,7 @@ function observeFavicon(aIsPrivate, aExpectedCookie, aPageURI) {
if (faviconReqXUL && faviconReqPlaces) {
resolve();
Services.obs.removeObserver(observer, "http-on-modify-request", false);
Services.obs.removeObserver(observer, "http-on-modify-request");
}
}
};
@ -134,8 +134,8 @@ function waitOnFaviconResponse(aFaviconURL) {
};
resolve(result);
Services.obs.removeObserver(observer, "http-on-examine-response", false);
Services.obs.removeObserver(observer, "http-on-examine-cached-response", false);
Services.obs.removeObserver(observer, "http-on-examine-response");
Services.obs.removeObserver(observer, "http-on-examine-cached-response");
}
}
};

View File

@ -51,6 +51,20 @@ function promiseEvent(aTarget, aEventName, aPreventDefault) {
return BrowserTestUtils.waitForEvent(aTarget, aEventName, false, cancelEvent);
}
/**
* Adds a new search engine to the search service and confirms it completes.
*
* @param {String} basename The file to load that contains the search engine
* details.
* @param {Object} [options] Options for the test:
* - {String} [iconURL] The icon to use for the search engine.
* - {Boolean} [setAsCurrent] Whether to set the new engine to be the
* current engine or not.
* - {String} [testPath] Used to override the current test path if this
* file is used from a different directory.
* @returns {Promise} The promise is resolved once the engine is added, or
* rejected if the addition failed.
*/
function promiseNewEngine(basename, options = {}) {
return new Promise((resolve, reject) => {
// Default the setAsCurrent option to true.
@ -59,7 +73,7 @@ function promiseNewEngine(basename, options = {}) {
info("Waiting for engine to be added: " + basename);
Services.search.init({
onInitComplete() {
let url = getRootDirectory(gTestPath) + basename;
let url = getRootDirectory(options.testPath || gTestPath) + basename;
let current = Services.search.currentEngine;
Services.search.addEngine(url, null, options.iconURL || "", false, {
onSuccess(engine) {

View File

@ -3613,7 +3613,7 @@ var SessionStoreInternal = {
* true if we want to reload into a fresh process
*/
restoreTabContent: function (aTab, aLoadArguments = null, aReloadInFreshProcess = false) {
if (aTab.hasAttribute("customizemode")) {
if (aTab.hasAttribute("customizemode") && !aLoadArguments) {
return;
}

View File

@ -72,6 +72,7 @@ SyncedTabsDeckComponent.prototype = {
init() {
Services.obs.addObserver(this, this._SyncedTabs.TOPIC_TABS_CHANGED, false);
Services.obs.addObserver(this, FxAccountsCommon.ONLOGIN_NOTIFICATION, false);
Services.obs.addObserver(this, "weave:service:login:change", false);
// Go ahead and trigger sync
this._SyncedTabs.syncTabs()
@ -94,6 +95,7 @@ SyncedTabsDeckComponent.prototype = {
uninit() {
Services.obs.removeObserver(this, this._SyncedTabs.TOPIC_TABS_CHANGED);
Services.obs.removeObserver(this, FxAccountsCommon.ONLOGIN_NOTIFICATION);
Services.obs.removeObserver(this, "weave:service:login:change");
this._deckView.destroy();
},
@ -104,6 +106,7 @@ SyncedTabsDeckComponent.prototype = {
this.updatePanel();
break;
case FxAccountsCommon.ONLOGIN_NOTIFICATION:
case "weave:service:login:change":
this.updatePanel();
break;
default:
@ -119,7 +122,7 @@ SyncedTabsDeckComponent.prototype = {
getPanelStatus() {
return this._accountStatus().then(exists => {
if (!exists) {
if (!exists || this._getChromeWindow(this._window).gSyncUI.loginFailed()) {
return this.PANELS.NOT_AUTHED_INFO;
}
if (!this._SyncedTabs.isConfiguredToSyncTabs) {

View File

@ -287,9 +287,7 @@ TabListView.prototype = {
if (itemNode.classList.contains("client")) {
let where = getChromeWindow(this._window).whereToOpenLink(event);
if (where != "current") {
const tabs = itemNode.querySelector(".item-tabs-list").childNodes;
const urls = [...tabs].map(tab => tab.dataset.url);
this.props.onOpenTabs(urls, where);
this._openAllClientTabs(itemNode, where);
}
}
@ -355,6 +353,13 @@ TabListView.prototype = {
}
},
onOpenAllInTabs() {
let item = this._getSelectedClientNode();
if (item) {
this._openAllClientTabs(item, "tab");
}
},
onFilter(event) {
let query = event.target.value;
if (query) {
@ -383,6 +388,14 @@ TabListView.prototype = {
return null;
},
_getSelectedClientNode() {
let item = this.container.querySelector('.item.selected');
if (this._isClient(item)) {
return item;
}
return null;
},
// Set up the custom context menu
_setupContextMenu() {
Services.els.addSystemEventListener(this._window, "contextmenu", this, false);
@ -461,6 +474,9 @@ TabListView.prototype = {
case "syncedTabsOpenSelectedInPrivateWindow":
this.onOpenSelectedFromContextMenu(event);
break;
case "syncedTabsOpenAllInTabs":
this.onOpenAllInTabs();
break;
case "syncedTabsBookmarkSelected":
this.onBookmarkTab();
break;
@ -506,11 +522,18 @@ TabListView.prototype = {
let el = menu.firstChild;
while (el) {
if (showTabOptions || el.getAttribute("id") === "syncedTabsRefresh") {
el.hidden = false;
} else {
el.hidden = true;
let show = false;
if (showTabOptions) {
if (el.getAttribute("id") != "syncedTabsOpenAllInTabs") {
show = true;
}
} else if (el.getAttribute("id") == "syncedTabsOpenAllInTabs") {
const tabs = item.querySelectorAll(".item-tabs-list > .item.tab");
show = tabs.length > 0;
} else if (el.getAttribute("id") == "syncedTabsRefresh") {
show = true;
}
el.hidden = !show;
el = el.nextSibling;
}
@ -564,5 +587,15 @@ TabListView.prototype = {
_isTab(item) {
return item && item.classList.contains("tab");
},
_isClient(item) {
return item && item.classList.contains("client");
},
_openAllClientTabs(clientNode, where) {
const tabs = clientNode.querySelector(".item-tabs-list").childNodes;
const urls = [...tabs].map(tab => tab.dataset.url);
this.props.onOpenTabs(urls, where);
}
};

View File

@ -310,6 +310,7 @@ add_task(function* testSyncedTabsSidebarContextMenu() {
["menuitem#syncedTabsBookmarkSelected", { hidden: false }],
["menuitem#syncedTabsCopySelected", { hidden: false }],
["menuseparator", { hidden: false }],
["menuitem#syncedTabsOpenAllInTabs", { hidden: true }],
["menuitem#syncedTabsRefresh", { hidden: false }],
];
yield* testContextMenu(syncedTabsDeckComponent,
@ -317,7 +318,7 @@ add_task(function* testSyncedTabsSidebarContextMenu() {
"#tab-7cqCr77ptzX3-0",
tabMenuItems);
info("Right-clicking a client shouldn't show any actions");
info("Right-clicking a client should show the Open All in Tabs action");
let sidebarMenuItems = [
["menuitem#syncedTabsOpenSelected", { hidden: true }],
["menuitem#syncedTabsOpenSelectedInTab", { hidden: true }],
@ -327,12 +328,31 @@ add_task(function* testSyncedTabsSidebarContextMenu() {
["menuitem#syncedTabsBookmarkSelected", { hidden: true }],
["menuitem#syncedTabsCopySelected", { hidden: true }],
["menuseparator", { hidden: true }],
["menuitem#syncedTabsOpenAllInTabs", { hidden: false }],
["menuitem#syncedTabsRefresh", { hidden: false }],
];
yield* testContextMenu(syncedTabsDeckComponent,
"#SyncedTabsSidebarContext",
"#item-7cqCr77ptzX3",
sidebarMenuItems);
info("Right-clicking a client without any tabs should not show the Open All in Tabs action");
let menuItems = [
["menuitem#syncedTabsOpenSelected", { hidden: true }],
["menuitem#syncedTabsOpenSelectedInTab", { hidden: true }],
["menuitem#syncedTabsOpenSelectedInWindow", { hidden: true }],
["menuitem#syncedTabsOpenSelectedInPrivateWindow", { hidden: true }],
["menuseparator", { hidden: true }],
["menuitem#syncedTabsBookmarkSelected", { hidden: true }],
["menuitem#syncedTabsCopySelected", { hidden: true }],
["menuseparator", { hidden: true }],
["menuitem#syncedTabsOpenAllInTabs", { hidden: true }],
["menuitem#syncedTabsRefresh", { hidden: false }],
];
yield* testContextMenu(syncedTabsDeckComponent,
"#SyncedTabsSidebarContext",
"#item-OL3EJCsdb2JD",
sidebarMenuItems);
menuItems);
});
add_task(testClean);

View File

@ -122,6 +122,12 @@ add_task(function* testObserver() {
Assert.ok(component.observe.calledWith(null, FxAccountsCommon.ONLOGIN_NOTIFICATION, ""),
"component is notified of login");
Assert.equal(component.updatePanel.callCount, 3, "triggers panel update again");
Services.obs.notifyObservers(null, "weave:service:login:change", "");
Assert.ok(component.observe.calledWith(null, "weave:service:login:change", ""),
"component is notified of login change");
Assert.equal(component.updatePanel.callCount, 4, "triggers panel update again");
});
add_task(function* testPanelStatus() {
@ -134,6 +140,16 @@ add_task(function* testPanelStatus() {
let SyncedTabsMock = {
getTabClients() {}
};
let loginFailed = false;
let chromeWindowMock = {
gSyncUI: {
loginFailed() {
return loginFailed;
}
}
};
let getChromeWindowMock = sinon.stub();
getChromeWindowMock.returns(chromeWindowMock);
sinon.stub(listStore, "getData");
@ -143,6 +159,7 @@ add_task(function* testPanelStatus() {
deckStore,
listComponent,
SyncedTabs: SyncedTabsMock,
getChromeWindowMock
});
let isAuthed = false;
@ -152,6 +169,11 @@ add_task(function* testPanelStatus() {
isAuthed = true;
loginFailed = true;
result = yield component.getPanelStatus();
Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
loginFailed = false;
SyncedTabsMock.isConfiguredToSyncTabs = false;
result = yield component.getPanelStatus();
Assert.equal(result, component.PANELS.TABS_DISABLED);

View File

@ -373,7 +373,8 @@ const kTestPairs = [
];
Components.utils.import("resource://gre/modules/Timer.jsm");
let detectorModule = Components.utils.import("resource:///modules/translation/LanguageDetector.jsm");
let detectorModule = Components.utils.import("resource:///modules/translation/LanguageDetector.jsm", {});
const LanguageDetector = detectorModule.LanguageDetector;
function check_result(result, langCode, expected) {
equal(result.language, langCode, "Expected language code");

View File

@ -32,7 +32,7 @@ var tests = [
let windowDestroyedDeferred = Promise.defer();
let onDOMWindowDestroyed = (aWindow) => {
if (gContentWindow && aWindow == gContentWindow) {
Services.obs.removeObserver(onDOMWindowDestroyed, "dom-window-destroyed", false);
Services.obs.removeObserver(onDOMWindowDestroyed, "dom-window-destroyed");
windowDestroyedDeferred.resolve();
}
};

View File

@ -47,7 +47,7 @@ add_task(function* test_setup() {
Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI);
Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0);
let ExperimentsScope = Cu.import("resource:///modules/experiments/Experiments.jsm");
let ExperimentsScope = Cu.import("resource:///modules/experiments/Experiments.jsm", {});
let Experiments = ExperimentsScope.Experiments;
gPolicy = new Experiments.Policy();

View File

@ -5,7 +5,7 @@
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/TelemetryLog.jsm");
var bsp = Cu.import("resource:///modules/experiments/Experiments.jsm");
var {TELEMETRY_LOG, Experiments} = Cu.import("resource:///modules/experiments/Experiments.jsm", {});
const MANIFEST_HANDLER = "manifests/handler";
@ -21,7 +21,7 @@ var gPolicy = null;
var gManifestObject = null;
var gManifestHandlerURI = null;
const TLOG = bsp.TELEMETRY_LOG;
const TLOG = TELEMETRY_LOG;
function checkEvent(event, id, data) {
do_print("Checking message " + id);

View File

@ -197,11 +197,11 @@ var PdfJs = {
uninit: function uninit() {
if (this._initialized) {
Services.prefs.removeObserver(PREF_DISABLED, this, false);
Services.prefs.removeObserver(PREF_DISABLED_PLUGIN_TYPES, this, false);
Services.obs.removeObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
Services.obs.removeObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false);
Services.obs.removeObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false);
Services.prefs.removeObserver(PREF_DISABLED, this);
Services.prefs.removeObserver(PREF_DISABLED_PLUGIN_TYPES, this);
Services.obs.removeObserver(this, TOPIC_PDFJS_HANDLER_CHANGED);
Services.obs.removeObserver(this, TOPIC_PLUGINS_LIST_UPDATED);
Services.obs.removeObserver(this, TOPIC_PLUGIN_INFO_UPDATED);
this._initialized = false;
}
this._ensureUnregistered();

View File

@ -110,7 +110,7 @@ var PdfjsChromeUtils = {
this._mmg.removeMessageListener('PDFJS:Parent:removeEventListener', this);
this._mmg.removeMessageListener('PDFJS:Parent:updateControlState', this);
Services.obs.removeObserver(this, 'quit-application', false);
Services.obs.removeObserver(this, 'quit-application');
this._mmg = null;
this._ppmm = null;

View File

@ -756,6 +756,10 @@ you can use these alternative items. Otherwise, their values should be empty. -
when Sync is configured but syncing tabs is disabled. -->
<!ENTITY syncedTabs.sidebar.tabsnotsyncing.label "Turn on tab syncing to view a list of tabs from your other devices.">
<!-- LOCALIZATION NOTE (syncedTabs.context.open.accesskey,
syncedTabs.context.openAllInTabs.accesskey):
These access keys are identical because their associated menu items are
mutually exclusive -->
<!ENTITY syncedTabs.context.open.label "Open">
<!ENTITY syncedTabs.context.open.accesskey "O">
<!ENTITY syncedTabs.context.openInNewTab.label "Open in a New Tab">
@ -769,6 +773,9 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY syncedTabs.context.copy.label "Copy">
<!ENTITY syncedTabs.context.copy.accesskey "C">
<!ENTITY syncedTabs.context.openAllInTabs.label "Open All in Tabs">
<!ENTITY syncedTabs.context.openAllInTabs.accesskey "O">
<!ENTITY syncBrand.shortName.label "Sync">

View File

@ -597,8 +597,6 @@ emeNotifications.drmContentPlaying.message2 = Some audio or video on this site u
emeNotifications.drmContentPlaying.button.label = Configure…
emeNotifications.drmContentPlaying.button.accesskey = C
# LOCALIZATION NOTE(emeNotifications.drmContentDisabled.message): NB: inserted via innerHTML, so please don't use <, > or & in this string. %S will be the 'learn more' link
emeNotifications.drmContentDisabled.message = You must enable DRM to play some audio or video on this page. %S
emeNotifications.drmContentDisabled.button.label = Enable DRM
emeNotifications.drmContentDisabled.button.accesskey = E
# LOCALIZATION NOTE(emeNotifications.drmContentDisabled.learnMoreLabel): NB: inserted via innerHTML, so please don't use <, > or & in this string.
@ -728,10 +726,8 @@ pendingCrashReports.alwaysSend = Always Send
decoder.noCodecs.button = Learn how
decoder.noCodecs.accesskey = L
decoder.noCodecs.message = To play video, you may need to install Microsofts Media Feature Pack.
decoder.noCodecsVista.message = To play video, you may need to install Microsofts Platform Update Supplement for Windows Vista.
decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsofts Media Feature Pack.
decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsofts Platform Update Supplement for Windows Vista.
decoder.noPulseAudio.message = To play audio, you may need to install the required PulseAudio software.
decoder.unsupportedLibavcodec.message = libavcodec may be vulnerable or is not supported, and should be updated to play video.

View File

@ -7,3 +7,5 @@
<!ENTITY hostCol.label "Site">
<!ENTITY statusCol.label "Status">
<!ENTITY usageCol.label "Storage">
<!ENTITY search.label "Search:">
<!ENTITY search.accesskey "S">

View File

@ -212,7 +212,7 @@ let urlbarListener = {
},
uninit() {
Services.obs.removeObserver(this, AUTOCOMPLETE_ENTER_TEXT_TOPIC, true);
Services.obs.removeObserver(this, AUTOCOMPLETE_ENTER_TEXT_TOPIC);
},
observe(subject, topic, data) {
@ -300,9 +300,9 @@ let BrowserUsageTelemetry = {
},
uninit() {
Services.obs.removeObserver(this, DOMWINDOW_OPENED_TOPIC, false);
Services.obs.removeObserver(this, TELEMETRY_SUBSESSIONSPLIT_TOPIC, false);
Services.obs.removeObserver(this, WINDOWS_RESTORED_TOPIC, false);
Services.obs.removeObserver(this, DOMWINDOW_OPENED_TOPIC);
Services.obs.removeObserver(this, TELEMETRY_SUBSESSIONSPLIT_TOPIC);
Services.obs.removeObserver(this, WINDOWS_RESTORED_TOPIC);
urlbarListener.uninit();
},

View File

@ -909,9 +909,9 @@ this.PluginCrashReporter = {
},
uninit() {
Services.obs.removeObserver(this, "plugin-crashed", false);
Services.obs.removeObserver(this, "gmp-plugin-crash", false);
Services.obs.removeObserver(this, "profile-after-change", false);
Services.obs.removeObserver(this, "plugin-crashed");
Services.obs.removeObserver(this, "gmp-plugin-crash");
Services.obs.removeObserver(this, "profile-after-change");
this.initialized = false;
},

View File

@ -21,6 +21,15 @@ this.ExtensionsUI = {
observe(subject, topic, data) {
if (topic == "webextension-permission-prompt") {
let {target, info} = subject.wrappedJSObject;
// Dismiss the progress notification. Note that this is bad if
// there are multiple simultaneous installs happening, see
// bug 1329884 for a longer explanation.
let progressNotification = target.ownerGlobal.PopupNotifications.getNotification("addon-progress", target);
if (progressNotification) {
progressNotification.remove();
}
this.showPermissionsPrompt(target, info).then(answer => {
Services.obs.notifyObservers(subject, "webextension-permission-response",
JSON.stringify(answer));

View File

@ -14,6 +14,8 @@ support-files =
contentSearchBadImage.xml
contentSearchSuggestions.sjs
contentSearchSuggestions.xml
!/browser/components/search/test/head.js
!/browser/components/search/test/testEngine.xml
[browser_NetworkPrioritizer.js]
[browser_PermissionUI.js]
[browser_ProcessHangNotifications.js]

View File

@ -7,6 +7,24 @@ const CONTENT_SEARCH_MSG = "ContentSearch";
const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js";
var gMsgMan;
/* eslint no-undef:"error" */
/* import-globals-from ../../components/search/test/head.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/components/search/test/head.js",
this);
let originalEngine = Services.search.currentEngine;
add_task(function* setup() {
yield promiseNewEngine("testEngine.xml", {
setAsCurrent: true,
testPath: "chrome://mochitests/content/browser/browser/components/search/test/",
});
registerCleanupFunction(() => {
Services.search.currentEngine = originalEngine;
});
});
add_task(function* GetState() {
yield addTab();

View File

@ -60,12 +60,12 @@ add_task(function* asyncCleanup() {
function promiseObserverNotification(aObserver) {
let deferred = Promise.defer();
function notificationCallback(e) {
Services.obs.removeObserver(notificationCallback, aObserver, false);
Services.obs.removeObserver(notificationCallback, aObserver);
clearTimeout(timeoutId);
deferred.resolve();
}
let timeoutId = setTimeout(() => {
Services.obs.removeObserver(notificationCallback, aObserver, false);
Services.obs.removeObserver(notificationCallback, aObserver);
deferred.reject("Notification '" + aObserver + "' did not happen within 20 seconds.");
}, kTimeoutInMS);
Services.obs.addObserver(notificationCallback, aObserver, false);

View File

@ -18,12 +18,6 @@ content.addEventListener(SERVICE_EVENT_TYPE, event => {
// Forward messages from the test to the in-content service.
addMessageListener(TEST_MSG, msg => {
content.dispatchEvent(
new content.CustomEvent(CLIENT_EVENT_TYPE, {
detail: msg.data,
})
);
// If the message is a search, stop the page from loading and then tell the
// test that it loaded.
if (msg.data.type == "Search") {
@ -34,6 +28,12 @@ addMessageListener(TEST_MSG, msg => {
});
});
}
content.dispatchEvent(
new content.CustomEvent(CLIENT_EVENT_TYPE, {
detail: msg.data,
})
);
});
function waitForLoadAndStopIt(expectedURL, callback) {

View File

@ -117,16 +117,16 @@ body.compact .newtab-cell {
}
/* SITES */
body:not(.compact) .newtab-site {
.newtab-site {
border-radius: var(--cell-corner-radius);
box-shadow: 0 1px 3px #c1c1c1;
text-decoration: none;
transition-property: top, left, opacity, box-shadow, background-color;
}
body:not(.compact) .newtab-cell:not([ignorehover]) .newtab-control:hover ~ .newtab-link,
body:not(.compact) .newtab-cell:not([ignorehover]) .newtab-link:hover,
body:not(.compact) .newtab-site[dragged] {
.newtab-cell:not([ignorehover]) .newtab-control:hover ~ .newtab-link,
.newtab-cell:not([ignorehover]) .newtab-link:hover,
.newtab-site[dragged] {
border: 2px solid white;
box-shadow: 0 0 6px 1px #add6ff;
margin: -2px;

View File

@ -29,12 +29,14 @@ AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [
esac
fi
# if we are debugging, profiling or using sanitizers, we want a frame pointer.
# If we are debugging, profiling, using sanitizers, or on win32 we want a
# frame pointer.
if test -z "$MOZ_OPTIMIZE" -o \
-n "$MOZ_PROFILING" -o \
-n "$MOZ_DEBUG" -o \
-n "$MOZ_MSAN" -o \
-n "$MOZ_ASAN"; then
-n "$MOZ_ASAN" -o \
"$OS_ARCH:$CPU_ARCH" = "WINNT:x86"; then
MOZ_FRAMEPTR_FLAGS="$MOZ_ENABLE_FRAME_PTR"
else
MOZ_FRAMEPTR_FLAGS="$MOZ_DISABLE_FRAME_PTR"

View File

@ -98,14 +98,17 @@ AC_SUBST(USE_ICU)
AC_SUBST(ICU_DATA_FILE)
AC_SUBST(MOZ_ICU_DATA_ARCHIVE)
if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM_ICU"; then
if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
fi
dnl We build ICU as a static library.
AC_DEFINE(U_STATIC_IMPLEMENTATION)
if test -n "$USE_ICU"; then
dnl Source files that use ICU should have control over which parts of the ICU
dnl namespace they want to use.
AC_DEFINE(U_USING_ICU_NAMESPACE,0)
if test -z "$MOZ_SYSTEM_ICU"; then
if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
fi
dnl We build ICU as a static library.
AC_DEFINE(U_STATIC_IMPLEMENTATION)
fi
fi
])

View File

@ -184,6 +184,7 @@ inline bool isIgnoredPathForImplicitCtor(const Decl *Declaration) {
End = llvm::sys::path::rend(FileName);
for (; Begin != End; ++Begin) {
if (Begin->compare_lower(StringRef("skia")) == 0 ||
Begin->compare_lower(StringRef("sfntly")) == 0 ||
Begin->compare_lower(StringRef("angle")) == 0 ||
Begin->compare_lower(StringRef("harfbuzz")) == 0 ||
Begin->compare_lower(StringRef("hunspell")) == 0 ||
@ -241,6 +242,7 @@ inline bool isIgnoredPathForSprintfLiteral(const CallExpr *Call, const SourceMan
Begin->compare_lower(StringRef("mtransport")) == 0 ||
Begin->compare_lower(StringRef("protobuf")) == 0 ||
Begin->compare_lower(StringRef("skia")) == 0 ||
Begin->compare_lower(StringRef("sfntly")) == 0 ||
// Gtest uses snprintf as GTEST_SNPRINTF_ with sizeof
Begin->compare_lower(StringRef("testing")) == 0) {
return true;

View File

@ -14,4 +14,6 @@ fi
MOZ_AUTOMATION_INSTALLER=${MOZ_AUTOMATION_INSTALLER-1}
export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=c:/builds/crash-stats-api.token
export MAKECAB=$topsrcdir/makecab.exe
TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
export MAKECAB=$TOOLTOOL_DIR/makecab.exe

View File

@ -1317,6 +1317,7 @@ xlocale.h
#ifdef MOZ_SYSTEM_ICU
unicode/locid.h
unicode/numsys.h
unicode/plurrule.h
unicode/timezone.h
unicode/ucal.h
unicode/uchar.h
@ -1327,6 +1328,7 @@ unicode/udatpg.h
unicode/uenum.h
unicode/unorm.h
unicode/unum.h
unicode/upluralrules.h
unicode/ustring.h
unicode/utypes.h
#endif

View File

@ -283,6 +283,8 @@ module.exports = {
"no-return-assign": "error",
// Allow use of javascript: urls.
"no-script-url": "off",
// Disallow assignments like foo = foo
"no-self-assign": "error",
// Disallow comparisons where both sides are exactly the same.
"no-self-compare": "error",
// Disallow use of comma operator.
@ -332,6 +334,10 @@ module.exports = {
"no-unsafe-finally": "error",
// Allow using variables before they are defined.
"no-use-before-define": "off",
// Disallow useless Function.prototype.{call/apply}
"no-useless-call": "error",
// Disallow useless return;
"no-useless-return": "error",
// We use var-only-at-top-level instead of no-var as we allow top level
// vars.
"no-var": "off",

View File

@ -122,7 +122,7 @@ add_task(function* reloadButtonReloadsAddon() {
const onBootstrapInstallCalled = new Promise(done => {
Services.obs.addObserver(function listener() {
Services.obs.removeObserver(listener, ADDON_NAME, false);
Services.obs.removeObserver(listener, ADDON_NAME);
info("Add-on was re-installed: " + ADDON_NAME);
done();
}, ADDON_NAME, false);

View File

@ -543,7 +543,5 @@ SelectorAutocompleter.prototype = {
// the autoSelect item has been selected.
return this._showPopup(result.suggestions, firstPart, state);
});
return;
}
};

View File

@ -1089,11 +1089,11 @@ CssRuleView.prototype = {
this.element.appendChild(div);
}
let inheritedSource = rule.inheritedSource;
let inheritedSource = rule.inherited;
if (inheritedSource && inheritedSource !== lastInheritedSource) {
let div = this.styleDocument.createElementNS(HTML_NS, "div");
div.className = this._getRuleViewHeaderClassName();
div.textContent = inheritedSource;
div.textContent = rule.inheritedSource;
lastInheritedSource = inheritedSource;
this.element.appendChild(div);
}
@ -1607,7 +1607,6 @@ RuleViewTool.prototype = {
toolbox.getCurrentPanel().selectStyleSheet(url, line, column);
});
}
return;
});
},

View File

@ -150,6 +150,7 @@ skip-if = (os == "win" && debug) # bug 963492: win.
[browser_rules_inherited-properties_01.js]
[browser_rules_inherited-properties_02.js]
[browser_rules_inherited-properties_03.js]
[browser_rules_inherited-properties_04.js]
[browser_rules_inline-source-map.js]
[browser_rules_invalid.js]
[browser_rules_invalid-source-map.js]

View File

@ -0,0 +1,32 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that different inherited properties sections are created for rules
// inherited from several elements of the same type.
const TEST_URI = `
<div style="cursor:pointer">
A
<div style="cursor:pointer">
B<a>Cursor</a>
</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("a", inspector);
yield elementStyleInherit(inspector, view);
});
function* elementStyleInherit(inspector, view) {
let gutters = view.element.querySelectorAll(".theme-gutter");
is(gutters.length, 2,
"Gutters should contains 2 sections");
ok(gutters[0].textContent, "Inherited from div");
ok(gutters[1].textContent, "Inherited from div");
}

View File

@ -16,7 +16,7 @@
.getService(SpecialPowers.Ci.nsIIOService);
var style = "data:text/css,a { background-color: seagreen; }";
var uri = gIOService.newURI(style, null, null);
var uri = gIOService.newURI(style);
var windowUtils = SpecialPowers.wrap(window)
.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
.getInterface(SpecialPowers.Ci.nsIDOMWindowUtils);

View File

@ -14,7 +14,7 @@
.getService(SpecialPowers.Ci.nsIIOService);
var style = "data:text/css,div { background-color: seagreen; }";
var uri = gIOService.newURI(style, null, null);
var uri = gIOService.newURI(style);
var windowUtils = SpecialPowers.wrap(window)
.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
.getInterface(SpecialPowers.Ci.nsIDOMWindowUtils);

View File

@ -119,6 +119,10 @@ requestCookies=Request cookies
# in the network details params tab identifying the response cookies.
responseCookies=Response cookies
# LOCALIZATION NOTE (responsePayload): This is the label displayed
# in the network details response tab identifying the response payload.
responsePayload=Response payload
# LOCALIZATION NOTE (jsonFilterText): This is the text displayed
# in the response tab of the network details pane for the JSON filtering input.
jsonFilterText=Filter properties

View File

@ -644,7 +644,6 @@ exports.fetchImmediatelyDominated = TaskCache.declareCacheableTask({
nodes: response.nodes,
moreChildrenAvailable: response.moreChildrenAvailable,
});
return;
}
});
@ -700,17 +699,15 @@ exports.refreshSelectedDominatorTree = function (heapWorker) {
return;
}
// We need to check for the snapshot state because if there was an error,
// we can't continue and if we are still saving or reading the snapshot,
// then takeSnapshotAndCensus will finish the job for us
if (snapshot.state === states.READ) {
if (snapshot.dominatorTree) {
yield dispatch(fetchDominatorTree(heapWorker, snapshot.id));
} else {
yield dispatch(computeAndFetchDominatorTree(heapWorker, snapshot.id));
}
} else {
// If there was an error, we can't continue. If we are still saving or
// reading the snapshot, then takeSnapshotAndCensus will finish the job
// for us.
return;
}
};
};

View File

@ -8,6 +8,8 @@ const general = {
CONTENT_SIZE_DECIMALS: 2,
FILTER_SEARCH_DELAY: 200,
REQUEST_TIME_DECIMALS: 2,
// 100 KB in bytes
SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE: 102400,
};
const actionTypes = {

View File

@ -3,51 +3,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-disable mozilla/reject-some-requires */
/* globals window, dumpn, $, NetMonitorView, gNetwork */
/* globals window, dumpn, $, gNetwork */
"use strict";
const promise = require("promise");
const EventEmitter = require("devtools/shared/event-emitter");
const Editor = require("devtools/client/sourceeditor/editor");
const { Heritage } = require("devtools/client/shared/widgets/view-helpers");
const { Task } = require("devtools/shared/task");
const { ToolSidebar } = require("devtools/client/framework/sidebar");
const { VariablesView } = require("resource://devtools/client/shared/widgets/VariablesView.jsm");
const { VariablesViewController } = require("resource://devtools/client/shared/widgets/VariablesViewController.jsm");
const { EVENTS } = require("./events");
const { L10N } = require("./l10n");
const { Filters } = require("./filter-predicates");
const {
decodeUnicodeUrl,
formDataURI,
getUrlBaseName,
} = require("./request-utils");
const { createFactory } = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const ParamsPanel = createFactory(require("./shared/components/params-panel"));
const PreviewPanel = createFactory(require("./shared/components/preview-panel"));
const ResponsePanel = createFactory(require("./shared/components/response-panel"));
const SecurityPanel = createFactory(require("./shared/components/security-panel"));
const TimingsPanel = createFactory(require("./shared/components/timings-panel"));
// 100 KB in bytes
const SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE = 102400;
const HEADERS_SIZE_DECIMALS = 3;
const CONTENT_MIME_TYPE_MAPPINGS = {
"/ecmascript": Editor.modes.js,
"/javascript": Editor.modes.js,
"/x-javascript": Editor.modes.js,
"/html": Editor.modes.html,
"/xhtml": Editor.modes.html,
"/xml": Editor.modes.html,
"/atom": Editor.modes.html,
"/soap": Editor.modes.html,
"/vnd.mpeg.dash.mpd": Editor.modes.html,
"/rdf": Editor.modes.css,
"/rss": Editor.modes.css,
"/css": Editor.modes.css
};
const GENERIC_VARIABLES_VIEW_SETTINGS = {
lazyEmpty: true,
// ms
@ -106,6 +87,13 @@ DetailsView.prototype = {
PreviewPanel()
), this._previewPanelNode);
this._responsePanelNode = $("#react-response-tabpanel-hook");
ReactDOM.render(Provider(
{ store },
ResponsePanel()
), this._responsePanelNode);
this._securityPanelNode = $("#react-security-tabpanel-hook");
ReactDOM.render(Provider(
@ -136,12 +124,6 @@ DetailsView.prototype = {
emptyText: L10N.getStr("cookiesEmptyText"),
searchPlaceholder: L10N.getStr("cookiesFilterText")
}));
this._json = new VariablesView($("#response-content-json"),
Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
onlyEnumVisible: true,
searchPlaceholder: L10N.getStr("jsonFilterText")
}));
VariablesViewController.attach(this._json);
this._requestHeaders = L10N.getStr("requestHeaders");
this._requestHeadersFromUpload = L10N.getStr("requestHeadersFromUpload");
@ -159,6 +141,7 @@ DetailsView.prototype = {
dumpn("Destroying the DetailsView");
ReactDOM.unmountComponentAtNode(this._paramsPanelNode);
ReactDOM.unmountComponentAtNode(this._previewPanelNode);
ReactDOM.unmountComponentAtNode(this._responsePanelNode);
ReactDOM.unmountComponentAtNode(this._securityPanelNode);
ReactDOM.unmountComponentAtNode(this._timingsPanelNode);
this.sidebar.destroy();
@ -175,11 +158,7 @@ DetailsView.prototype = {
* Returns a promise that resolves upon population the view.
*/
populate: function (data) {
$("#response-content-info-header").hidden = true;
$("#response-content-json-box").hidden = true;
$("#response-content-textarea-box").hidden = true;
$("#raw-headers").hidden = true;
$("#response-content-image-box").hidden = true;
let isHtml = Filters.html(data);
@ -205,7 +184,6 @@ DetailsView.prototype = {
this._headers.empty();
this._cookies.empty();
this._json.empty();
this._dataSrc = { src: data, populated: [] };
this._onTabSelect();
@ -254,10 +232,6 @@ DetailsView.prototype = {
yield view._setResponseCookies(src.responseCookies);
yield view._setRequestCookies(src.requestCookies);
break;
// "Response"
case 3:
yield view._setResponseBody(src.url, src.responseContent);
break;
}
viewState.updating[tab] = false;
}).then(() => {
@ -471,125 +445,9 @@ DetailsView.prototype = {
}
}),
/**
* Sets the network response body shown in this view.
*
* @param string url
* The request's url.
* @param object response
* The message received from the server.
* @return object
* A promise that is resolved when the response body is set.
*/
_setResponseBody: Task.async(function* (url, response) {
if (!response) {
return;
}
let { mimeType, text, encoding } = response.content;
let responseBody = yield gNetwork.getString(text);
// Handle json, which we tentatively identify by checking the MIME type
// for "json" after any word boundary. This works for the standard
// "application/json", and also for custom types like "x-bigcorp-json".
// Additionally, we also directly parse the response text content to
// verify whether it's json or not, to handle responses incorrectly
// labeled as text/plain instead.
let jsonMimeType, jsonObject, jsonObjectParseError;
try {
jsonMimeType = /\bjson/.test(mimeType);
jsonObject = JSON.parse(responseBody);
} catch (e) {
jsonObjectParseError = e;
}
if (jsonMimeType || jsonObject) {
// Extract the actual json substring in case this might be a "JSONP".
// This regex basically parses a function call and captures the
// function name and arguments in two separate groups.
let jsonpRegex = /^\s*([\w$]+)\s*\(\s*([^]*)\s*\)\s*;?\s*$/;
let [_, callbackPadding, jsonpString] = // eslint-disable-line
responseBody.match(jsonpRegex) || [];
// Make sure this is a valid JSON object first. If so, nicely display
// the parsing results in a variables view. Otherwise, simply show
// the contents as plain text.
if (callbackPadding && jsonpString) {
try {
jsonObject = JSON.parse(jsonpString);
} catch (e) {
jsonObjectParseError = e;
}
}
// Valid JSON or JSONP.
if (jsonObject) {
$("#response-content-json-box").hidden = false;
let jsonScopeName = callbackPadding
? L10N.getFormatStr("jsonpScopeName", callbackPadding)
: L10N.getStr("jsonScopeName");
let jsonVar = { label: jsonScopeName, rawObject: jsonObject };
yield this._json.controller.setSingleVariable(jsonVar).expanded;
} else {
// Malformed JSON.
$("#response-content-textarea-box").hidden = false;
let infoHeader = $("#response-content-info-header");
infoHeader.setAttribute("value", jsonObjectParseError);
infoHeader.setAttribute("tooltiptext", jsonObjectParseError);
infoHeader.hidden = false;
let editor = yield NetMonitorView.editor("#response-content-textarea");
editor.setMode(Editor.modes.js);
editor.setText(responseBody);
}
} else if (mimeType.includes("image/")) {
// Handle images.
$("#response-content-image-box").setAttribute("align", "center");
$("#response-content-image-box").setAttribute("pack", "center");
$("#response-content-image-box").hidden = false;
$("#response-content-image").src = formDataURI(mimeType, encoding, responseBody);
// Immediately display additional information about the image:
// file name, mime type and encoding.
$("#response-content-image-name-value").setAttribute("value",
getUrlBaseName(url));
$("#response-content-image-mime-value").setAttribute("value", mimeType);
// Wait for the image to load in order to display the width and height.
$("#response-content-image").onload = e => {
// XUL images are majestic so they don't bother storing their dimensions
// in width and height attributes like the rest of the folk. Hack around
// this by getting the bounding client rect and subtracting the margins.
let { width, height } = e.target.getBoundingClientRect();
let dimensions = (width - 2) + " \u00D7 " + (height - 2);
$("#response-content-image-dimensions-value").setAttribute("value",
dimensions);
};
} else {
$("#response-content-textarea-box").hidden = false;
let editor = yield NetMonitorView.editor("#response-content-textarea");
editor.setMode(Editor.modes.text);
editor.setText(responseBody);
// Maybe set a more appropriate mode in the Source Editor if possible,
// but avoid doing this for very large files.
if (responseBody.length < SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
let mapping = Object.keys(CONTENT_MIME_TYPE_MAPPINGS).find(key => {
return mimeType.includes(key);
});
if (mapping) {
editor.setMode(CONTENT_MIME_TYPE_MAPPINGS[mapping]);
}
}
}
window.emit(EVENTS.RESPONSE_BODY_DISPLAYED);
}),
_dataSrc: null,
_headers: null,
_cookies: null,
_json: null,
_requestHeaders: "",
_responseHeaders: "",
_requestCookies: "",

View File

@ -55,9 +55,6 @@ const EVENTS = {
// When the request post params are displayed in the UI.
REQUEST_POST_PARAMS_DISPLAYED: "NetMonitor:RequestPostParamsAvailable",
// When the response body is displayed in the UI.
RESPONSE_BODY_DISPLAYED: "NetMonitor:ResponseBodyAvailable",
// When the image response thumbnail is displayed in the UI.
RESPONSE_IMAGE_THUMBNAIL_DISPLAYED:
"NetMonitor:ResponseImageThumbnailAvailable",

View File

@ -8,8 +8,6 @@
"use strict";
const { testing: isTesting } = require("devtools/shared/flags");
const promise = require("promise");
const Editor = require("devtools/client/sourceeditor/editor");
const { Task } = require("devtools/shared/task");
const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
const { RequestsMenuView } = require("./requests-menu-view");
@ -32,12 +30,6 @@ const WDA_DEFAULT_VERIFY_INTERVAL = 50;
// ms
const WDA_DEFAULT_GIVE_UP_TIMEOUT = isTesting ? 45000 : 2000;
const DEFAULT_EDITOR_CONFIG = {
mode: Editor.modes.text,
readOnly: true,
lineNumbers: true
};
/**
* Object defining the network monitor view components.
*/
@ -102,11 +94,6 @@ var NetMonitorView = {
Prefs.networkDetailsHeight = this._detailsPane.getAttribute("height");
this._detailsPane = null;
for (let p of this._editorPromises.values()) {
let editor = yield p;
editor.destroy();
}
}),
/**
@ -214,35 +201,8 @@ var NetMonitorView = {
ACTIVITY_TYPE.RELOAD.WITH_CACHE_DEFAULT);
},
/**
* Lazily initializes and returns a promise for a Editor instance.
*
* @param string id
* The id of the editor placeholder node.
* @return object
* A promise that is resolved when the editor is available.
*/
editor: function (id) {
dumpn("Getting a NetMonitorView editor: " + id);
if (this._editorPromises.has(id)) {
return this._editorPromises.get(id);
}
let deferred = promise.defer();
this._editorPromises.set(id, deferred.promise);
// Initialize the source editor and store the newly created instance
// in the ether of a resolved promise's value.
let editor = new Editor(DEFAULT_EDITOR_CONFIG);
editor.appendTo($(id)).then(() => deferred.resolve(editor));
return deferred.promise;
},
_body: null,
_detailsPane: null,
_editorPromises: new Map()
};
/**

View File

@ -217,42 +217,8 @@
</tabpanel>
<tabpanel id="response-tabpanel"
class="tabpanel-content">
<vbox flex="1">
<label id="response-content-info-header"/>
<vbox id="response-content-json-box" flex="1" hidden="true">
<vbox id="response-content-json" flex="1" context="network-response-popup" />
</vbox>
<vbox id="response-content-textarea-box" flex="1" hidden="true">
<vbox id="response-content-textarea" flex="1"/>
</vbox>
<vbox id="response-content-image-box" flex="1" hidden="true">
<image id="response-content-image"/>
<hbox>
<label class="plain tabpanel-summary-label"
data-localization="content=netmonitor.response.name"/>
<label id="response-content-image-name-value"
class="plain tabpanel-summary-value devtools-monospace"
crop="end"
flex="1"/>
</hbox>
<hbox>
<label class="plain tabpanel-summary-label"
data-localization="content=netmonitor.response.dimensions"/>
<label id="response-content-image-dimensions-value"
class="plain tabpanel-summary-value devtools-monospace"
crop="end"
flex="1"/>
</hbox>
<hbox>
<label class="plain tabpanel-summary-label"
data-localization="content=netmonitor.response.mime"/>
<label id="response-content-image-mime-value"
class="plain tabpanel-summary-value devtools-monospace"
crop="end"
flex="1"/>
</hbox>
</vbox>
</vbox>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-response-tabpanel-hook"/>
</tabpanel>
<tabpanel id="timings-tabpanel"
class="tabpanel-content">

Some files were not shown because too many files have changed in this diff Show More