merge mozilla-inbound to mozilla-central. r=merge a=merge

MozReview-Commit-ID: JSRVc5yW6Kx
This commit is contained in:
Sebastian Hengst 2017-09-07 12:39:12 +02:00
Родитель ac6ee9f873 fe96089fe4
Коммит 8eb249afcc
416 изменённых файлов: 7039 добавлений и 305239 удалений

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

@ -1503,6 +1503,7 @@ DocAccessible::DoInitialUpdate()
#if defined(XP_WIN)
IAccessibleHolder holder(CreateHolderFromAccessible(this));
MOZ_DIAGNOSTIC_ASSERT(!holder.IsNull());
int32_t childID = AccessibleWrap::GetChildIDFor(this);
#else
int32_t holder = 0, childID = 0;

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

@ -409,11 +409,8 @@ pref("browser.search.context.loadInBackground", false);
// comma seperated list of of engines to hide in the search panel.
pref("browser.search.hiddenOneOffs", "");
// Mirrors whether the search-container widget is in the navigation toolbar. The
// default value of this preference must match the DEFAULT_AREA_PLACEMENTS of
// UITelemetry.jsm, the navbarPlacements of CustomizableUI.jsm, and the
// position and attributes of the search-container element in browser.xul.
pref("browser.search.widget.inNavBar", true);
// Mirrors whether the search-container widget is in the navigation toolbar.
pref("browser.search.widget.inNavBar", false);
#ifndef RELEASE_OR_BETA
pref("browser.search.reset.enabled", true);

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

@ -4,7 +4,6 @@
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
@namespace svg url("http://www.w3.org/2000/svg");
:root {
--panelui-subview-transition-duration: 150ms;

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

@ -437,9 +437,9 @@
position="bottomcenter topright"
tabspecific="true"
noautofocus="true"
copyURL-title="&copyURLCmd.label;"
copyURL-title="&pageAction.copyLink.label;"
emailLink-title="&emailPageCmd.label;"
sendToDevice-title="&sendToDevice.label3;"
sendToDevice-title="&pageAction.sendTabToDevice.label;"
sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;">
<photonpanelmultiview id="pageActionPanelMultiView"
mainViewId="pageActionPanelMainView"
@ -910,7 +910,7 @@
class="urlbar-icon urlbar-page-action"
role="button"
tooltiptext="&pageActionButton.tooltip;"
onclick="BrowserPageActions.mainButtonClicked(event);"/>
onmousedown="BrowserPageActions.mainButtonClicked(event);"/>
<hbox id="star-button-box"
hidden="true"
class="urlbar-icon-wrapper urlbar-page-action"
@ -932,12 +932,6 @@
</textbox>
</toolbaritem>
<toolbaritem id="search-container" title="&searchItem.title;"
align="center" class="chromeclass-toolbar-additional panel-wide-item"
cui-areatype="toolbar"
flex="100" persist="width" removable="true">
<searchbar id="searchbar" flex="1"/>
</toolbaritem>
<toolbarspring cui-areatype="toolbar" class="chromeclass-toolbar-additional"/>
<!-- This is a placeholder for the Downloads Indicator. It is visible
@ -946,7 +940,7 @@
<toolbarbutton id="downloads-button"
class="toolbarbutton-1 chromeclass-toolbar-additional badged-button"
key="key_openDownloads"
oncommand="DownloadsIndicatorView.onCommand(event);"
onmousedown="DownloadsIndicatorView.onCommand(event);"
ondrop="DownloadsIndicatorView.onDrop(event);"
ondragover="DownloadsIndicatorView.onDragOver(event);"
ondragenter="DownloadsIndicatorView.onDragOver(event);"
@ -957,7 +951,7 @@
<toolbarbutton id="library-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
removable="true"
oncommand="PanelUI.showSubView('appMenu-libraryView', this, null, event);"
onmousedown="PanelUI.showSubView('appMenu-libraryView', this, null, event);"
closemenu="none"
cui-areatype="toolbar"
tooltiptext="&libraryButton.tooltip;"
@ -1089,7 +1083,6 @@
<toolbarbutton id="bookmarks-menu-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
removable="true"
type="menu"
label="&bookmarksMenuButton2.label;"
tooltip="dynamic-shortcut-tooltip"
@ -1098,7 +1091,6 @@
ondragover="PlacesMenuDNDHandler.onDragOver(event);"
ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"
ondrop="PlacesMenuDNDHandler.onDrop(event);"
cui-areatype="toolbar"
oncommand="BookmarkingUI.onCommand(event);">
<observes element="bookmarkThisPageBroadcaster" attribute="starred"/>
<observes element="bookmarkThisPageBroadcaster" attribute="buttontooltiptext"/>
@ -1184,6 +1176,15 @@
key="manBookmarkKb"/>
</menupopup>
</toolbarbutton>
<toolbaritem id="search-container"
class="chromeclass-toolbar-additional panel-wide-item"
title="&searchItem.title;"
align="center"
flex="100"
persist="width">
<searchbar id="searchbar" flex="1"/>
</toolbaritem>
</toolbarpalette>
<box id="library-animatable-box" class="toolbarbutton-animatable-box">
<image class="toolbarbutton-animatable-image"/>

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

@ -483,6 +483,8 @@ add_task(async function() {
add_task(async function() {
info("Cmd+k should focus the search box in the toolbar when it's present");
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, async function(browser) {
await BrowserTestUtils.synthesizeMouseAtCenter("#brandLogo", {}, browser);
@ -494,6 +496,8 @@ add_task(async function() {
await promiseWaitForCondition(() => doc.activeElement === searchInput);
is(searchInput, doc.activeElement, "Search bar should be the active element.");
});
Services.prefs.clearUserPref("browser.search.widget.inNavBar");
});
add_task(async function() {

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

@ -397,6 +397,7 @@ support-files = test_offline_gzip.html gZipOfflineChild.cacheManifest gZipOfflin
[browser_plainTextLinks.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_printpreview.js]
skip-if = os == 'win' # Bug 1384127
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_private_browsing_window.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.

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

@ -2,16 +2,10 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
// Remove the search bar from toolbar
CustomizableUI.removeWidgetFromArea("search-container");
// Test that Ctrl/Cmd + K will focus the url bar
let focusPromise = BrowserTestUtils.waitForEvent(gURLBar, "focus");
EventUtils.synthesizeKey("k", { accelKey: true });
await focusPromise;
Assert.equal(document.activeElement, gURLBar.inputField, "URL Bar should be focused");
// Reset changes made to toolbar
CustomizableUI.reset();
});

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

@ -193,7 +193,6 @@ var CustomizableUIInternal = {
"home-button",
"spring",
"urlbar-container",
"search-container",
"spring",
"downloads-button",
"library-button",
@ -4181,7 +4180,7 @@ OverflowableToolbar.prototype = {
let chevronId = this._toolbar.getAttribute("overflowbutton");
this._chevron = doc.getElementById(chevronId);
this._chevron.addEventListener("command", this);
this._chevron.addEventListener("mousedown", this);
this._chevron.addEventListener("dragover", this);
this._chevron.addEventListener("dragend", this);
@ -4230,7 +4229,7 @@ OverflowableToolbar.prototype = {
case "aftercustomization":
this._enable();
break;
case "command":
case "mousedown":
if (aEvent.target == this._chevron) {
this._onClickChevron(aEvent);
} else {

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

@ -36,6 +36,10 @@ const SearchWidgetTracker = {
CustomizableUI.addListener(this);
Services.prefs.addObserver(PREF_NAME,
() => this.syncWidgetWithPreference());
// The placement of the widget always takes priority, and the preference
// should always match the actual placement when the browser starts up.
this.syncPreferenceWithWidget();
},
onCustomizeEnd() {

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

@ -475,7 +475,7 @@
checkboxhidden="true"
hidden="true">
<popupnotificationcontent id="update-restart-notification-content" orient="vertical">
<description id="update-restart-description">&updateRestart.message;</description>
<description id="update-restart-description">&updateRestart.message2;</description>
</popupnotificationcontent>
</popupnotification>
</panel>

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

@ -7,15 +7,8 @@ const WIDGET_ID = "search-container";
const PREF_NAME = "browser.search.widget.inNavBar";
function checkDefaults() {
// If the following defaults change, then the DEFAULT_AREA_PLACEMENTS of
// UITelemetry.jsm, the navbarPlacements of CustomizableUI.jsm, and the
// position and attributes of the search-container element in browser.xul
// should also change at the same time.
ok(Services.prefs.getBoolPref(PREF_NAME));
let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID);
is(placement.area, CustomizableUI.AREA_NAVBAR);
is(placement.position,
CustomizableUI.getPlacementOfWidget("urlbar-container").position + 1);
ok(!Services.prefs.getBoolPref(PREF_NAME));
is(CustomizableUI.getPlacementOfWidget(WIDGET_ID), null);
}
add_task(async function test_defaults() {
@ -24,23 +17,27 @@ add_task(async function test_defaults() {
});
add_task(async function test_syncPreferenceWithWidget() {
// Moving the widget to any position outside of the navigation toolbar should
// turn the preference to false.
CustomizableUI.addWidgetToArea(WIDGET_ID, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
ok(!Services.prefs.getBoolPref(PREF_NAME));
// Moving the widget back to any position in the navigation toolbar should
// turn the preference to true again.
// Moving the widget to any position in the navigation toolbar should turn the
// preference to true.
CustomizableUI.addWidgetToArea(WIDGET_ID, CustomizableUI.AREA_NAVBAR);
ok(Services.prefs.getBoolPref(PREF_NAME));
// Moving the widget to any position outside of the navigation toolbar should
// turn the preference back to false.
CustomizableUI.addWidgetToArea(WIDGET_ID, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
ok(!Services.prefs.getBoolPref(PREF_NAME));
});
add_task(async function test_syncWidgetWithPreference() {
// This should move the widget the customization palette.
Services.prefs.setBoolPref(PREF_NAME, false);
is(CustomizableUI.getPlacementOfWidget(WIDGET_ID), null);
// This should return the widget to its default placement.
// setting the preference should move the widget to the navigation toolbar and
// place it right after the location bar.
Services.prefs.setBoolPref(PREF_NAME, true);
let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID);
is(placement.area, CustomizableUI.AREA_NAVBAR);
is(placement.position,
CustomizableUI.getPlacementOfWidget("urlbar-container").position + 1);
// This should move the widget back to the customization palette.
Services.prefs.setBoolPref(PREF_NAME, false);
checkDefaults();
});

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

@ -16,10 +16,8 @@ async function waitForSearchBarFocus() {
// Ctrl+K should open the menu panel and focus the search bar if the search bar is in the panel.
add_task(async function() {
let searchbar = document.getElementById("searchbar");
gCustomizeMode.addToPanel(searchbar);
let placement = CustomizableUI.getPlacementOfWidget("search-container");
is(placement.area, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, "Should be in panel");
CustomizableUI.addWidgetToArea("search-container",
CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
let shownPanelPromise = promiseOverflowShown(window);
sendWebSearchKeyCommand();
@ -35,10 +33,8 @@ add_task(async function() {
// Ctrl+K should give focus to the searchbar when the searchbar is in the menupanel and the panel is already opened.
add_task(async function() {
let searchbar = document.getElementById("searchbar");
gCustomizeMode.addToPanel(searchbar);
let placement = CustomizableUI.getPlacementOfWidget("search-container");
is(placement.area, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, "Should be in panel");
CustomizableUI.addWidgetToArea("search-container",
CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
await document.getElementById("nav-bar").overflowable.show();
@ -59,7 +55,9 @@ add_task(async function() {
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
window.resizeTo(360, window.outerHeight);
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.getAttribute("overflowing") == "true");
ok(!navbar.querySelector("#search-container"), "Search container should be overflowing");
@ -75,6 +73,9 @@ add_task(async function() {
let hiddenPanelPromise = promiseOverflowHidden(window);
EventUtils.synthesizeKey("VK_ESCAPE", {});
await hiddenPanelPromise;
Services.prefs.setBoolPref("browser.search.widget.inNavBar", false);
navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
window.resizeTo(this.originalWindowWidth, window.outerHeight);
await waitForCondition(() => !navbar.hasAttribute("overflowing"));
@ -83,12 +84,15 @@ add_task(async function() {
// Ctrl+K should focus the search bar if it is in the navbar and not overflowing.
add_task(async function() {
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
let placement = CustomizableUI.getPlacementOfWidget("search-container");
is(placement.area, CustomizableUI.AREA_NAVBAR, "Should be in nav-bar");
sendWebSearchKeyCommand();
await waitForSearchBarFocus();
Services.prefs.setBoolPref("browser.search.widget.inNavBar", false);
});

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

@ -10,7 +10,7 @@ add_task(async function() {
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
let oldChildCount = navbar.customizationTarget.childElementCount;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");

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

@ -13,7 +13,7 @@ add_task(async function() {
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
let oldChildCount = navbar.customizationTarget.childElementCount;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
is(navbar.currentSet, oldCurrentSet, "Currentset should be the same when overflowing.");

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

@ -23,7 +23,7 @@ add_task(async function() {
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(!navbar.querySelector("#" + kSidebarBtn), "Sidebar button should no longer be in the navbar");
@ -65,7 +65,7 @@ add_task(async function() {
CustomizableUI.addWidgetToArea(kTestBtn2, navbar.id);
ok(!navbar.hasAttribute("overflowing"), "Should still have a non-overflowing toolbar.");
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(!navbar.querySelector("#" + kTestBtn2), "Test button should not be in the navbar");
@ -94,7 +94,7 @@ add_task(async function() {
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(!navbar.querySelector("#" + kSidebarBtn), "Sidebar button should no longer be in the navbar");

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

@ -9,11 +9,11 @@ add_task(async function() {
await startCustomizing();
let devButton = document.getElementById("developer-button");
let downloadsButton = document.getElementById("downloads-button");
let searchBox = document.getElementById("search-container");
let homeButton = document.getElementById("home-button");
let palette = document.getElementById("customization-palette");
ok(devButton && downloadsButton && searchBox && palette, "Stuff should exist");
ok(devButton && downloadsButton && homeButton && palette, "Stuff should exist");
simulateItemDrag(devButton, downloadsButton);
simulateItemDrag(searchBox, palette);
simulateItemDrag(homeButton, palette);
await gCustomizeMode.reset();
ok(CustomizableUI.inDefaultState, "Should be back in default state");
await endCustomizing();

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

@ -69,14 +69,14 @@ add_task(async function menu_button_popup() {
});
add_task(async function searchbar_in_panel() {
let searchbar = document.getElementById("searchbar");
gCustomizeMode.addToPanel(searchbar);
let placement = CustomizableUI.getPlacementOfWidget("search-container");
is(placement.area, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, "Should be in panel");
CustomizableUI.addWidgetToArea("search-container",
CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
await waitForOverflowButtonShown();
await document.getElementById("nav-bar").overflowable.show();
let searchbar = document.getElementById("searchbar");
await waitForCondition(() => "value" in searchbar && searchbar.value === "");
// Focusing a non-empty searchbox will cause us to open the

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

@ -12,7 +12,7 @@ add_task(async function() {
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");

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

@ -67,7 +67,7 @@ add_task(async function() {
}
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
let testWidgetId = kTestWidgetPrefix + 3;
@ -116,7 +116,7 @@ add_task(async function() {
}
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
let testWidgetId = kTestWidgetPrefix + 3;
@ -166,7 +166,7 @@ add_task(async function() {
}
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
let testWidgetId = kTestWidgetPrefix + 3;
@ -225,7 +225,7 @@ add_task(async function() {
}
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
// Find last widget that doesn't allow overflowing
@ -286,7 +286,7 @@ add_task(async function() {
ok(!toolbarNode.hasAttribute("overflowing"), "Toolbar shouldn't overflow to start with.");
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
@ -337,7 +337,7 @@ add_task(async function() {
ok(!toolbarNode.hasAttribute("overflowing"), "Toolbar shouldn't overflow to start with.");
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
@ -386,7 +386,7 @@ add_task(async function() {
ok(!toolbarNode.hasAttribute("overflowing"), "Toolbar shouldn't overflow to start with.");
let originalWindowWidth = window.outerWidth;
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");

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

@ -35,7 +35,7 @@ add_task(async function addOverflowingToolbar() {
isnot(oldChildCount, 0, "Toolbar should have non-overflowing widgets");
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(toolbarNode.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");

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

@ -10,7 +10,6 @@ var gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget
const kBookmarksButton = "bookmarks-menu-button";
const kBookmarksItems = "personal-bookmarks";
const kOriginalWindowWidth = window.outerWidth;
const kSmallWidth = 400;
/**
* Helper function that opens the bookmarks menu, and returns a Promise that
@ -141,7 +140,7 @@ function checkBookmarksItemsChevronContextMenu() {
*/
function overflowEverything() {
info("Waiting for overflow");
window.resizeTo(kSmallWidth, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
return waitForCondition(() => gNavBar.hasAttribute("overflowing"));
}

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

@ -145,6 +145,11 @@ add_task(async function urlbar_context() {
// Right-click on the searchbar and moving it to the menu
// and back should move the search-container instead.
add_task(async function searchbar_context_move_to_panel_and_back() {
// This is specifically testing the addToPanel function for the search bar, so
// we have to move it to its correct position in the navigation toolbar first.
// The preference will be restored when the customizations are reset later.
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
let searchbar = document.getElementById("searchbar");
gCustomizeMode.addToPanel(searchbar);
let placement = CustomizableUI.getPlacementOfWidget("search-container");
@ -167,7 +172,7 @@ add_task(async function searchbar_context_move_to_panel_and_back() {
is(placement, null, "Should be in palette");
CustomizableUI.reset();
placement = CustomizableUI.getPlacementOfWidget("search-container");
is(placement.area, CustomizableUI.AREA_NAVBAR, "Should be in navbar");
is(placement, null, "Should be in palette");
});
// Right-click on an item within the panel should

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

@ -128,7 +128,7 @@ add_task(async function test_panelui_customize_to_toolbar() {
CustomizableUI.reset();
});
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));
// Mac will update the enabled state even when the buttons are overflowing,

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

@ -23,7 +23,7 @@ add_task(async function check_developer_subview_in_overflow() {
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
window.resizeTo(400, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForCondition(() => navbar.hasAttribute("overflowing"));

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

@ -27,6 +27,8 @@ var {synthesizeDragStart, synthesizeDrop} = EventUtils;
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kTabEventFailureTimeoutInMs = 20000;
const kForceOverflowWidthPx = 300;
function createDummyXULButton(id, label, win = window) {
let btn = document.createElementNS(kNSXUL, "toolbarbutton");
btn.id = id;

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

@ -1,6 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// This is the same value used by CustomizableUI tests.
const kForceOverflowWidthPx = 200;
registerCleanupFunction(async function() {
// Clean up when the test finishes.
await task_resetState();
@ -24,20 +27,18 @@ add_task(async function test_overflow_anchor() {
.forWindow(window);
ok(!button.overflowed, "Downloads button should not be overflowed.");
// Hack - we lock the size of the default flex-y items in the nav-bar,
// namely, the URL and search inputs. That way we can resize the
// window without worrying about them flexing.
const kFlexyItems = ["urlbar-container", "search-container"];
// Hack - we lock the size of the default flex-y items in the nav-bar, namely,
// the URL input. That way we can resize the window without worrying about it
// flexing.
const kFlexyItems = ["urlbar-container"];
registerCleanupFunction(() => unlockWidth(kFlexyItems));
lockWidth(kFlexyItems);
// Resize the window to half of its original size. That should
// be enough to overflow the downloads button.
window.resizeTo(oldWidth / 2, window.outerHeight);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await waitForOverflowed(button, true);
let promise = promisePanelOpened();
button.node.doCommand();
button.node.dispatchEvent(new Event("mousedown"));
await promise;
let panel = DownloadsPanel.panel;
@ -57,7 +58,7 @@ add_task(async function test_overflow_anchor() {
// Now try opening the panel again.
promise = promisePanelOpened();
button.node.doCommand();
button.node.dispatchEvent(new Event("mousedown"));
await promise;
is(panel.anchorNode.id, "downloads-indicator-anchor");

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

@ -549,7 +549,7 @@
}
]]></handler>
<handler event="click" button="0">
<handler event="mousedown" button="0">
<![CDATA[
// Ignore clicks on the search go button.
if (event.originalTarget.getAttribute("anonid") == "search-go-button") {

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

@ -131,6 +131,12 @@ async function prepareTest() {
await focusPromise;
}
add_task(async function testSetup() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
});
add_task(async function testSetupEngine() {
await promiseSetEngine();
});

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

@ -123,13 +123,15 @@ async function testSearchEngine(engineDetails) {
name: "search bar search",
searchURL: base + engineDetails.codes.submission,
run() {
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
let sb = BrowserSearch.searchBar;
sb.focus();
sb.value = "foo";
registerCleanupFunction(function() {
sb.value = "";
});
EventUtils.synthesizeKey("VK_RETURN", {});
},
postTest() {
BrowserSearch.searchBar.value = "";
Services.prefs.setBoolPref("browser.search.widget.inNavBar", false);
}
},
{
@ -169,6 +171,10 @@ async function testSearchEngine(engineDetails) {
let receivedURI = await stateChangePromise;
Assert.equal(receivedURI, test.searchURL);
if (test.postTest) {
await test.postTest(tab);
}
}
engine.alias = undefined;

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

@ -120,6 +120,12 @@ add_task(async function tests() {
let engine = Services.search.getEngineByName("Google");
ok(engine, "Google");
// Show the search bar after initializing the search service, to avoid the
// synchronous initialization to interfere.
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b";
// Keyword uses a slightly different code

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

@ -120,6 +120,12 @@ add_task(async function tests() {
let engine = Services.search.getEngineByName("Google");
ok(engine, "Google");
// Show the search bar after initializing the search service, to avoid the
// synchronous initialization to interfere.
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8";
let url;

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

@ -9,7 +9,9 @@ function test() {
waitForExplicitFinish();
resetPreferences();
let calledTestTelemetry = false;
function testTelemetry() {
calledTestTelemetry = true;
// Find the right bucket for the "Foo" engine.
let engine = Services.search.getEngineByName("Foo");
let histogramKey = (engine.identifier || "other-Foo") + ".searchbar";
@ -58,8 +60,11 @@ function test() {
break;
case "engine-current":
is(Services.search.currentEngine.name, "Foo", "Current engine is Foo");
testTelemetry();
// We may be called again when resetting the engine at the end.
if (!calledTestTelemetry) {
is(Services.search.currentEngine.name, "Foo", "Current engine is Foo");
testTelemetry();
}
break;
case "engine-removed":
@ -70,7 +75,10 @@ function test() {
}
Services.obs.addObserver(observer, "browser-search-engine-modified");
SpecialPowers.pushPrefEnv({set: [["toolkit.telemetry.enabled", true]]}).then(function() {
SpecialPowers.pushPrefEnv({set: [
["toolkit.telemetry.enabled", true],
["browser.search.widget.inNavBar", true],
]}).then(function() {
Services.search.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
null, "data:image/x-icon,%00", false);
});

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

@ -3,18 +3,26 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Tests that keyboard navigation in the search panel works as designed.
const searchbar = document.getElementById("searchbar");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
"searchbar-search-button");
const diacritic_engine = "Foo \u2661";
var Preferences =
Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
let searchbar;
let searchIcon;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
let currentEngine = Services.search.currentEngine;
await promiseNewEngine("testEngine_diacritics.xml", {setAsCurrent: false});
registerCleanupFunction(() => {

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

@ -3,11 +3,7 @@
const TEST_ENGINE_NAME = "Foo";
const TEST_ENGINE_BASENAME = "testEngine.xml";
const searchbar = document.getElementById("searchbar");
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
const oneOffBinding = document.getAnonymousElementByAttribute(
searchPopup, "anonid", "search-one-off-buttons"
);
@ -21,7 +17,19 @@ const searchInNewTabMenuItem = document.getAnonymousElementByAttribute(
oneOffBinding, "anonid", "search-one-offs-context-open-in-new-tab"
);
let searchbar;
let searchIcon;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
await promiseNewEngine(TEST_ENGINE_BASENAME, {
setAsCurrent: false,
});

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

@ -6,13 +6,9 @@ const SEARCHBAR_BASE_ID = "searchbar-engine-one-off-item-";
const URLBAR_BASE_ID = "urlbar-engine-one-off-item-";
const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
const searchbar = document.getElementById("searchbar");
const urlbar = document.getElementById("urlbar");
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const urlbarPopup = document.getElementById("PopupAutoCompleteRichResult");
const searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
const searchOneOffBinding = document.getAnonymousElementByAttribute(
searchPopup, "anonid", "search-one-off-buttons"
);
@ -28,7 +24,19 @@ function resetEngine() {
registerCleanupFunction(resetEngine);
let searchbar;
let searchIcon;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
await promiseNewEngine(TEST_ENGINE_BASENAME, {
setAsCurrent: false,
});

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

@ -5,11 +5,7 @@
const isMac = ("nsILocalFileMac" in Ci);
const searchbar = document.getElementById("searchbar");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
"searchbar-search-button");
const oneOffsContainer =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
@ -55,8 +51,19 @@ function synthesizeNativeMouseMove(aElement) {
});
}
let searchbar;
let searchIcon;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
await promiseNewEngine("testEngine.xml");
});
@ -92,9 +99,9 @@ add_task(async function test_notext() {
});
add_task(async function test_text() {
textbox.value = "foo";
searchbar._textbox.value = "foo";
registerCleanupFunction(() => {
textbox.value = "";
searchbar._textbox.value = "";
});
let promise = promiseEvent(searchPopup, "popupshown");
@ -133,7 +140,8 @@ add_task(async function test_text() {
EventUtils.synthesizeMouseAtCenter(searchbarEngine, {});
});
let url = Services.search.currentEngine.getSubmission(textbox.value).uri.spec;
let url = Services.search.currentEngine
.getSubmission(searchbar._textbox.value).uri.spec;
await promiseTabLoadEvent(gBrowser.selectedTab, url);
// Move the cursor out of the panel area to avoid messing with other tests.

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

@ -3,9 +3,9 @@
// whether there is an autocomplete entry for the private search.
add_task(async function() {
// Don't use about:home as the homepage for new windows
Services.prefs.setIntPref("browser.startup.page", 0);
registerCleanupFunction(() => Services.prefs.clearUserPref("browser.startup.page"));
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
let windowsToClose = [];

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

@ -106,6 +106,12 @@ function promiseContentSearchReady(browser) {
});
}
add_task(async function() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
});
for (let engine of SEARCH_ENGINE_DETAILS) {
add_task(async function() {
let previouslySelectedEngine = Services.search.currentEngine;

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

@ -1,7 +1,5 @@
// Tests that keyboard navigation in the search panel works as designed.
const searchbar = document.getElementById("searchbar");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const oneOffsContainer =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
@ -22,7 +20,17 @@ function getOpenSearchItems() {
return os;
}
let searchbar;
let textbox;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
textbox = searchbar._textbox;
await promiseNewEngine("testEngine.xml");
// First cleanup the form history in case other tests left things there.

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

@ -8,10 +8,6 @@ this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
const searchbar = document.getElementById("searchbar");
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid", "searchbar-search-button");
const goButton = document.getAnonymousElementByAttribute(searchbar, "anonid", "search-go-button");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const kValues = ["long text", "long text 2", "long text 3"];
@ -62,7 +58,25 @@ async function startCustomizing(aWindow = window) {
return eventPromise;
}
let searchbar;
let textbox;
let searchIcon;
let goButton;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
textbox = searchbar._textbox;
searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
goButton = document.getAnonymousElementByAttribute(
searchbar, "anonid", "search-go-button"
);
await promiseNewEngine("testEngine.xml");
// First cleanup the form history in case other tests left things there.

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

@ -1,13 +1,9 @@
// Tests that keyboard navigation in the search panel works as designed.
const searchbar = document.getElementById("searchbar");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const oneOffsContainer =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
"search-one-off-buttons");
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
"searchbar-search-button");
const kValues = ["foo1", "foo2", "foo3"];
@ -23,7 +19,21 @@ function getOpenSearchItems() {
return os;
}
let searchbar;
let textbox;
let searchIcon;
add_task(async function init() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
searchbar = document.getElementById("searchbar");
textbox = searchbar._textbox;
searchIcon = document.getAnonymousElementByAttribute(
searchbar, "anonid", "searchbar-search-button"
);
await promiseNewEngine("testEngine.xml");
// First cleanup the form history in case other tests left things there.

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

@ -4,13 +4,18 @@
// popup shows a submenu that lists them instead of showing them in the popup
// itself.
const searchbar = document.getElementById("searchbar");
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const oneOffsContainer =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
"search-one-off-buttons");
add_task(async function test() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
let searchbar = document.getElementById("searchbar");
let rootDir = getRootDirectory(gTestPath);
let url = rootDir + "tooManyEnginesOffered.html";
await BrowserTestUtils.openNewForegroundTab(gBrowser, url);

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

@ -9,7 +9,11 @@
const BROWSER_SEARCH_PREF = "browser.search.";
function test() {
add_task(async function test() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
let engine = Services.search.getEngineByName("Yahoo");
ok(engine, "Yahoo");
@ -129,4 +133,4 @@ function test() {
};
isSubObjectOf(EXPECTED_ENGINE, engine, "Yahoo");
}
});

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

@ -273,11 +273,18 @@ var tests = [
is(icon.src, "", "Popup should have no icon");
is(buttons.hasChildNodes(), false, "Popup should have no buttons");
// Place the search bar in the navigation toolbar temporarily.
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
await showInfoPromise("search", "search title", "search text");
is(popup.popupBoxObject.anchorNode, document.getElementById("searchbar"), "Popup should be anchored to the searchbar");
is(title.textContent, "search title", "Popup should have correct title");
is(desc.textContent, "search text", "Popup should have correct description text");
await SpecialPowers.popPrefEnv();
}),
function test_getConfigurationVersion(done) {
function callback(result) {

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

@ -162,6 +162,11 @@ add_UITour_task(async function test_getConfiguration_selectedSearchEngine() {
});
add_UITour_task(async function test_setSearchTerm() {
// Place the search bar in the navigation toolbar temporarily.
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
const TERM = "UITour Search Term";
await gContentAPI.setSearchTerm(TERM);
@ -169,13 +174,22 @@ add_UITour_task(async function test_setSearchTerm() {
// The UITour gets to the searchbar element through a promise, so the value setting
// only happens after a tick.
await waitForConditionPromise(() => searchbar.value == TERM, "Correct term set");
await SpecialPowers.popPrefEnv();
});
add_UITour_task(async function test_clearSearchTerm() {
// Place the search bar in the navigation toolbar temporarily.
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
await gContentAPI.setSearchTerm("");
let searchbar = document.getElementById("searchbar");
// The UITour gets to the searchbar element through a promise, so the value setting
// only happens after a tick.
await waitForConditionPromise(() => searchbar.value == "", "Search term cleared");
await SpecialPowers.popPrefEnv();
});

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

@ -29,8 +29,6 @@ function getExpectedTargets() {
"privateWindow",
...(hasQuit ? ["quit"] : []),
"readerMode-urlBar",
"search",
"searchIcon",
"trackingProtection",
"urlbar",
];
@ -62,17 +60,16 @@ add_UITour_task(async function test_availableTargets_changeWidgets() {
"Targets should not be cached after reset");
});
add_UITour_task(async function test_availableTargets_exceptionFromGetTarget() {
// The query function for the "search" target will throw if it's not found.
// Make sure the callback still fires with the other available targets.
CustomizableUI.removeWidgetFromArea("search-container");
let data = await getConfigurationPromise("availableTargets");
let expecteds = getExpectedTargets();
// Default minus "search" and "searchIcon"
expecteds = expecteds.filter(target => target != "search" && target != "searchIcon");
ok_targets(data, expecteds);
CustomizableUI.reset();
add_UITour_task(async function test_availableTargets_search() {
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
try {
let data = await getConfigurationPromise("availableTargets");
let expecteds = getExpectedTargets();
expecteds = ["search", "searchIcon", ...expecteds];
ok_targets(data, expecteds);
} finally {
Services.prefs.clearUserPref("browser.search.widget.inNavBar");
}
});
add_UITour_task(async function test_availableTargets_removeUrlbarPageActionsAll() {

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

@ -13,15 +13,17 @@ function test() {
var tests = [
function test_openSearchPanel(done) {
let searchbar = document.getElementById("searchbar");
// If suggestions are enabled, the panel will attempt to use the network to connect
// to the suggestions provider, causing the test suite to fail.
// If suggestions are enabled, the panel will attempt to use the network to
// connect to the suggestions provider, causing the test suite to fail. We
// also change the preference to display the search bar during the test.
Services.prefs.setBoolPref("browser.search.widget.inNavBar", true);
Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("browser.search.widget.inNavBar");
Services.prefs.clearUserPref("browser.search.suggest.enabled");
});
let searchbar = document.getElementById("searchbar");
ok(!searchbar.textbox.open, "Popup starts as closed");
gContentAPI.openSearchPanel(() => {
ok(searchbar.textbox.open, "Popup was opened");

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

@ -556,7 +556,7 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY bookmarkThisLinkCmd.accesskey "L">
<!ENTITY bookmarkThisFrameCmd.label "Bookmark This Frame">
<!ENTITY bookmarkThisFrameCmd.accesskey "m">
<!ENTITY copyURLCmd.label "Copy URL">
<!ENTITY pageAction.copyLink.label "Copy Link">
<!ENTITY copyURLFeedback.label "Copied!">
<!ENTITY emailPageCmd.label "Email Link…">
<!ENTITY emailPageCmd.accesskey "E">
@ -965,7 +965,7 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY updateManual.cancelButton.accesskey "N">
<!ENTITY updateManual.panelUI.label "Download a fresh copy of &brandShorterName;">
<!ENTITY updateRestart.message "After a quick restart, &brandShorterName; will restore all your open tabs and windows.">
<!ENTITY updateRestart.message2 "After a quick restart, &brandShorterName; will restore all your open tabs and windows that are not in Private Browsing mode.">
<!ENTITY updateRestart.header.message2 "Restart to update &brandShorterName;.">
<!ENTITY updateRestart.acceptButton.label "Restart and Restore">
<!ENTITY updateRestart.acceptButton.accesskey "R">
@ -977,7 +977,7 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY pageAction.addToUrlbar.label "Add to Address Bar">
<!ENTITY pageAction.removeFromUrlbar.label "Remove from Address Bar">
<!ENTITY sendToDevice.label3 "Send Page to Device">
<!ENTITY pageAction.sendTabToDevice.label "Send Tab to Device">
<!ENTITY sendToDevice.syncNotReady.label "Syncing Devices…">
<!ENTITY libraryButton.tooltip "View history, saved bookmarks, and more">

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

@ -55,7 +55,6 @@ XPCOMUtils.defineLazyGetter(this, "DEFAULT_AREA_PLACEMENTS", function() {
"stop-reload-button",
"home-button",
"urlbar-container",
"search-container",
"downloads-button",
"library-button",
"sidebar-button",
@ -88,6 +87,7 @@ XPCOMUtils.defineLazyGetter(this, "DEFAULT_AREAS", function() {
XPCOMUtils.defineLazyGetter(this, "PALETTE_ITEMS", function() {
let result = [
"bookmarks-menu-button",
"search-container",
"open-file-button",
"developer-button",
"feed-button",

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

@ -64,6 +64,10 @@ function clickSearchbarSuggestion(entryName) {
}
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({ set: [
["browser.search.widget.inNavBar", true],
]});
// Create two new search engines. Mark one as the default engine, so
// the test don't crash. We need to engines for this test as the searchbar
// doesn't display the default search engine among the one-off engines.

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

@ -8,7 +8,6 @@
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
@namespace svg url("http://www.w3.org/2000/svg");
%include ../shared/browser.inc.css

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

@ -9,7 +9,6 @@
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
@namespace svg url("http://www.w3.org/2000/svg");
%include ../shared/browser.inc.css

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

@ -6,7 +6,6 @@
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
@namespace svg url("http://www.w3.org/2000/svg");
%include ../shared/browser.inc.css

6
config/external/moz.build поставляемый
Просмотреть файл

@ -44,12 +44,6 @@ if not CONFIG['MOZ_SYSTEM_PNG']:
if CONFIG['CPU_ARCH'] == 'arm':
external_dirs += ['media/openmax_dl']
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
external_dirs += [
'media/sphinxbase',
'media/pocketsphinx',
]
if CONFIG['MOZ_FFVPX']:
external_dirs += ['media/ffvpx']

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

@ -3,17 +3,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This file should not be modified and is a duplicate from the debugger.html project.
* Any changes to this file should be imported from the upstream debugger.html project.
* This file is a duplicate from the debugger.html project and has diverged in terms of
* some of styles that are kept. Any changes to the styles in this file should be synced
* back to the appropriate styles in the debugger.html project.
* Create a pull request at https://github.com/devtools-html/debugger.html to sync
* any changes to the existing styles.
*/
:root {
--accordion-header-background: var(--theme-toolbar-background);
}
:root.theme-dark {
--accordion-header-background: #141416;
}
.accordion {
background-color: var(--theme-body-background);
background-color: var(--theme-sidebar-background);
width: 100%;
}
.accordion ._header {
background-color: var(--theme-toolbar-background);
background-color: var(--accordion-header-background);
border-bottom: 1px solid var(--theme-splitter-color);
cursor: pointer;
font-size: 12px;

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

@ -9,7 +9,7 @@
<link rel="stylesheet" href="chrome://devtools/content/netmonitor/src/assets/styles/netmonitor.css"/>
<script src="chrome://devtools/content/shared/theme-switching.js"></script>
</head>
<body class="theme-sidebar" role="application">
<body class="theme-body" role="application">
<div id="mount"></div>
<script>
"use strict";
@ -38,25 +38,36 @@
window.Netmonitor = {
bootstrap({ toolbox }) {
this.mount = document.querySelector("#mount");
const connection = {
tabConnection: {
tabTarget: toolbox.target,
},
toolbox,
};
const openLink = (link) => {
let parentDoc = toolbox.doc;
let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
let top = iframe.ownerDocument.defaultView.top;
top.openUILinkIn(link, "tab");
};
const App = createFactory(require("./src/components/app"));
const sourceMapService = toolbox.sourceMapURLService;
render(Provider({ store }, App({ sourceMapService })), this.mount);
const app = App({ sourceMapService, openLink });
render(Provider({ store }, app), this.mount);
return onFirefoxConnect(connection, actions, store.getState);
},
destroy() {
unmountComponentAtNode(this.mount);
return onDisconnect();
}
},
};
// Implement support for chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
// Implement support for:
// chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
// where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
@ -64,7 +75,8 @@
let href = window.location.href.replace(/chrome:/, "http://");
let url = new window.URL(href);
// If query parameters are given in a chrome tab, the inspector is running in standalone.
// If query parameters are given in a chrome tab, the inspector
// is running in standalone.
if (window.location.protocol === "chrome:" && url.search.length > 1) {
const { targetFromURL } = require("devtools/client/framework/target-from-url");
@ -83,7 +95,8 @@
};
window.Netmonitor.bootstrap({ toolbox });
})().catch(e => {
window.alert("Unable to start the network monitor:" + e.message + "\n" + e.stack);
window.alert("Unable to start the network monitor:" +
e.message + "\n" + e.stack);
});
}
</script>

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

@ -21,10 +21,14 @@ const { div } = DOM;
* App component
* The top level component for representing main panel
*/
function App({ statisticsOpen, sourceMapService }) {
function App({
openLink,
sourceMapService,
statisticsOpen,
}) {
return (
div({ className: "network-monitor" },
!statisticsOpen ? MonitorPanel({sourceMapService}) : StatisticsPanel()
!statisticsOpen ? MonitorPanel({ openLink, sourceMapService }) : StatisticsPanel()
)
);
}
@ -32,9 +36,10 @@ function App({ statisticsOpen, sourceMapService }) {
App.displayName = "App";
App.propTypes = {
statisticsOpen: PropTypes.bool.isRequired,
openLink: PropTypes.func,
// Service to enable the source map feature.
sourceMapService: PropTypes.object,
statisticsOpen: PropTypes.bool.isRequired,
};
module.exports = connect(

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

@ -31,6 +31,7 @@ const SECTION_NAMES = [
*/
function CookiesPanel({
request,
openLink,
}) {
let {
requestCookies = { cookies: [] },
@ -62,6 +63,7 @@ function CookiesPanel({
object,
filterPlaceHolder: COOKIES_FILTER_TEXT,
sectionNames: SECTION_NAMES,
openLink,
})
)
);
@ -71,6 +73,7 @@ CookiesPanel.displayName = "CookiesPanel";
CookiesPanel.propTypes = {
request: PropTypes.object.isRequired,
openLink: PropTypes.func,
};
/**

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

@ -54,7 +54,8 @@ const HeadersPanel = createClass({
propTypes: {
cloneSelectedRequest: PropTypes.func.isRequired,
request: PropTypes.object.isRequired,
renderValue: PropTypes.func
renderValue: PropTypes.func,
openLink: PropTypes.func,
},
getInitialState() {
@ -125,6 +126,7 @@ const HeadersPanel = createClass({
render() {
const {
openLink,
cloneSelectedRequest,
request: {
fromCache,
@ -256,6 +258,7 @@ const HeadersPanel = createClass({
filterPlaceHolder: HEADERS_FILTER_TEXT,
sectionNames: Object.keys(object),
renderValue: this.renderValue,
openLink,
}),
)
);

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

@ -40,6 +40,7 @@ const MonitorPanel = createClass({
request: PropTypes.object,
// Service to enable the source map feature.
sourceMapService: PropTypes.object,
openLink: PropTypes.func,
updateRequest: PropTypes.func.isRequired,
},
@ -104,7 +105,13 @@ const MonitorPanel = createClass({
},
render() {
let { isEmpty, networkDetailsOpen, sourceMapService } = this.props;
let {
isEmpty,
networkDetailsOpen,
sourceMapService,
openLink
} = this.props;
let initialWidth = Services.prefs.getIntPref(
"devtools.netmonitor.panes-network-details-width");
let initialHeight = Services.prefs.getIntPref(
@ -123,6 +130,7 @@ const MonitorPanel = createClass({
endPanel: networkDetailsOpen && NetworkDetailsPanel({
ref: "endPanel",
sourceMapService,
openLink,
}),
endPanelCollapsed: !networkDetailsOpen,
endPanelControl: true,

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

@ -28,6 +28,7 @@ function NetworkDetailsPanel({
request,
selectTab,
sourceMapService,
openLink,
}) {
if (!request) {
return null;
@ -38,10 +39,11 @@ function NetworkDetailsPanel({
!request.isCustom ?
TabboxPanel({
activeTabId,
cloneSelectedRequest,
request,
selectTab,
sourceMapService,
cloneSelectedRequest,
openLink,
}) :
CustomRequestPanel({
request,
@ -60,6 +62,7 @@ NetworkDetailsPanel.propTypes = {
selectTab: PropTypes.func.isRequired,
// Service to enable the source map feature.
sourceMapService: PropTypes.object,
openLink: PropTypes.func,
};
module.exports = connect(

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

@ -34,7 +34,10 @@ const SECTION_NAMES = [
* Params panel component
* Displays the GET parameters and POST data of a request
*/
function ParamsPanel({ request }) {
function ParamsPanel({
openLink,
request,
}) {
let {
formDataSections,
mimeType,
@ -92,6 +95,7 @@ function ParamsPanel({ request }) {
object,
filterPlaceHolder: PARAMS_FILTER_TEXT,
sectionNames: SECTION_NAMES,
openLink,
})
)
);
@ -101,6 +105,7 @@ ParamsPanel.displayName = "ParamsPanel";
ParamsPanel.propTypes = {
request: PropTypes.object.isRequired,
openLink: PropTypes.func,
};
/**

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

@ -49,6 +49,7 @@ const PropertiesView = createClass({
expandableStrings: PropTypes.bool,
filterPlaceHolder: PropTypes.string,
sectionNames: PropTypes.array,
openLink: PropTypes.func,
},
getDefaultProps() {
@ -148,6 +149,7 @@ const PropertiesView = createClass({
renderRow,
renderValue,
sectionNames,
openLink,
} = this.props;
return (
@ -181,6 +183,7 @@ const PropertiesView = createClass({
onFilter: (props) => this.onFilter(props, sectionNames),
renderRow: renderRow || this.renderRowWithEditor,
renderValue: renderValue || this.renderValueWithRep,
openLink,
}),
),
)

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

@ -33,6 +33,7 @@ const ResponsePanel = createClass({
propTypes: {
request: PropTypes.object.isRequired,
openLink: PropTypes.func,
},
getInitialState() {
@ -110,7 +111,8 @@ const ResponsePanel = createClass({
},
render() {
let { responseContent, url } = this.props.request;
let { openLink, request } = this.props;
let { responseContent, url } = request;
if (!responseContent || typeof responseContent.content.text !== "string") {
return null;
@ -175,6 +177,7 @@ const ResponsePanel = createClass({
object,
filterPlaceHolder: JSON_FILTER_TEXT,
sectionNames: Object.keys(object),
openLink,
}),
)
);

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

@ -24,7 +24,10 @@ const { div, input, span } = DOM;
* This contains details about the secure connection used including the protocol,
* the cipher suite, and certificate details
*/
function SecurityPanel({ request }) {
function SecurityPanel({
openLink,
request,
}) {
const { securityInfo, url } = request;
if (!securityInfo || !url) {
@ -101,6 +104,7 @@ function SecurityPanel({ request }) {
renderValue: (props) => renderValue(props, securityInfo.weaknessReasons),
enableFilter: false,
expandedNodes: TreeViewClass.getExpandedNodes(object),
openLink,
})
);
}
@ -109,6 +113,7 @@ SecurityPanel.displayName = "SecurityPanel";
SecurityPanel.propTypes = {
request: PropTypes.object.isRequired,
openLink: PropTypes.func,
};
function renderValue(props, weaknessReasons = []) {

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

@ -16,7 +16,11 @@ const { div } = DOM;
// Components
const StackTrace = createFactory(require("devtools/client/shared/components/stack-trace"));
function StackTracePanel({ request, sourceMapService }) {
function StackTracePanel({
openLink,
request,
sourceMapService,
}) {
let { stacktrace } = request.cause;
return (
@ -25,6 +29,7 @@ function StackTracePanel({ request, sourceMapService }) {
stacktrace,
onViewSourceInDebugger: ({ url, line }) => viewSourceInDebugger(url, line),
sourceMapService,
openLink,
}),
)
);
@ -36,6 +41,7 @@ StackTracePanel.propTypes = {
request: PropTypes.object.isRequired,
// Service to enable the source map feature.
sourceMapService: PropTypes.object,
openLink: PropTypes.func,
};
module.exports = StackTracePanel;

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

@ -41,6 +41,7 @@ function TabboxPanel({
request,
selectTab,
sourceMapService,
openLink,
}) {
if (!request) {
return null;
@ -58,25 +59,25 @@ function TabboxPanel({
id: PANELS.HEADERS,
title: HEADERS_TITLE,
},
HeadersPanel({ request, cloneSelectedRequest }),
HeadersPanel({ request, cloneSelectedRequest, openLink }),
),
TabPanel({
id: PANELS.COOKIES,
title: COOKIES_TITLE,
},
CookiesPanel({ request }),
CookiesPanel({ request, openLink }),
),
TabPanel({
id: PANELS.PARAMS,
title: PARAMS_TITLE,
},
ParamsPanel({ request }),
ParamsPanel({ request, openLink }),
),
TabPanel({
id: PANELS.RESPONSE,
title: RESPONSE_TITLE,
},
ResponsePanel({ request }),
ResponsePanel({ request, openLink }),
),
TabPanel({
id: PANELS.TIMINGS,
@ -89,14 +90,14 @@ function TabboxPanel({
id: PANELS.STACK_TRACE,
title: STACK_TRACE_TITLE,
},
StackTracePanel({ request, sourceMapService }),
StackTracePanel({ request, sourceMapService, openLink }),
),
request.securityState && request.securityState !== "insecure" &&
TabPanel({
id: PANELS.SECURITY,
title: SECURITY_TITLE,
},
SecurityPanel({ request }),
SecurityPanel({ request, openLink }),
),
)
);
@ -111,6 +112,7 @@ TabboxPanel.propTypes = {
selectTab: PropTypes.func.isRequired,
// Service to enable the source map feature.
sourceMapService: PropTypes.object,
openLink: PropTypes.func,
};
module.exports = connect()(TabboxPanel);

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

@ -7,7 +7,7 @@
.tabs {
height: 100%;
background: var(--theme-body-background);
background: var(--theme-sidebar-background);
display: flex;
flex-direction: column;
}

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

@ -117,7 +117,9 @@ window {
border-bottom-width: 0px;
border-top-width: 1px;
border-top-color: var(--theme-splitter-color);
background-color: var(--theme-toolbar-background);
/* Bug 1262668 - Use the same background as the body so the breadcrumbs toolbar doesn't
get mistaken as a splitter */
background-color: var(--theme-body-background);
display: block;
position: relative;
}

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

@ -6,11 +6,13 @@
.theme-light {
--rule-highlight-background-color: #ffee99;
--rule-overridden-item-border-color: var(--theme-content-color3);
--rule-header-background-color: var(--theme-toolbar-background);
}
.theme-dark {
--rule-highlight-background-color: #594724;
--rule-overridden-item-border-color: var(--theme-content-color1);
--rule-header-background-color: #141416;
}
.theme-firebug {
@ -18,6 +20,7 @@
--rule-property-name: darkgreen;
--rule-property-value: darkblue;
--rule-overridden-item-border-color: var(--theme-content-color2);
--rule-header-background-color: var(--theme-header-background);
}
/* Rule View Tabpanel */
@ -219,7 +222,7 @@
}
.ruleview-header {
background-color: var(--theme-toolbar-background);
background-color: var(--rule-header-background-color);
border-bottom: 1px solid var(--theme-splitter-color);
font-size: 12px;
padding: 4px;
@ -239,7 +242,6 @@
padding: 3px 4px 2px 4px;
line-height: inherit;
min-height: 0;
background: var(--theme-header-background);
}
:root[platform="win"] .ruleview-header,

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

@ -93,7 +93,7 @@
:root.theme-dark {
--theme-body-background: var(--grey-80);
--theme-sidebar-background: var(--grey-80);
--theme-sidebar-background: var(--grey-90);
--theme-contrast-background: #ffb35b;
/* Toolbar */

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

@ -233,7 +233,7 @@
/* The color of the thin line in the arrow-shaped separator between 2 unselected
crumbs. There is no theme variable for this, this used to be an image. */
--line-color: #ACACAC;
--background-color: var(--theme-toolbar-background);
--background-color: var(--theme-body-background);
}
#debugger-toolbar .breadcrumbs-widget-item::before {

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

@ -107,6 +107,7 @@ function NetworkEventMessage({
activeTabId: networkMessageActiveTabId,
request: networkMessageUpdate,
sourceMapService: serviceContainer.sourceMapService,
openLink: serviceContainer.openLink,
selectTab: (tabId) => {
dispatch(actions.selectNetworkMessageTab(tabId));
},

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

@ -80,7 +80,9 @@ NewConsoleOutputWrapper.prototype = {
}]));
},
hudProxyClient: this.jsterm.hud.proxy.client,
openLink: url => this.jsterm.hud.owner.openLink(url),
openLink: url => {
this.jsterm.hud.owner.openLink(url);
},
createElement: nodename => {
return this.document.createElementNS("http://www.w3.org/1999/xhtml", nodename);
},

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

@ -915,6 +915,7 @@ function CssRule(cssSheet, domRule, element) {
// parse domRule.selectorText on call to this.selectors
this._selectors = null;
this.line = domUtils.getRuleLine(this.domRule);
this.column = domUtils.getRuleColumn(this.domRule);
this.source = this._cssSheet.shortSource + ":" + this.line;
if (this.mediaText) {
this.source += " @media " + this.mediaText;
@ -1107,6 +1108,16 @@ CssSelector.prototype = {
return this.cssRule.line;
},
/**
* Retrieve the column of the parent CSSStyleRule in the parent CSSStyleSheet.
*
* @return {number} the column of the parent CSSStyleRule in the parent
* stylesheet.
*/
get ruleColumn() {
return this.cssRule.column;
},
/**
* Retrieve specificity information for the current selector.
*
@ -1391,6 +1402,16 @@ CssSelectorInfo.prototype = {
return this.selector.ruleLine;
},
/**
* Retrieve the column of the parent CSSStyleRule in the parent CSSStyleSheet.
*
* @return {number} the column of the parent CSSStyleRule in the parent
* stylesheet.
*/
get ruleColumn() {
return this.selector.ruleColumn;
},
/**
* Check if the selector comes from a browser-provided stylesheet.
*
@ -1458,6 +1479,13 @@ CssSelectorInfo.prototype = {
return 1;
}
if (this.ruleColumn > that.ruleColumn) {
return -1;
}
if (that.ruleColumn > this.ruleColumn) {
return 1;
}
return 0;
},

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

@ -10,6 +10,8 @@
.inheritable-rule {
font-size: 15px;
}
/* Has to be on one line, is such for test */
.column-rule { font-size: 20px; } .column-rule { font-size: 25px; }
.uninheritable-rule {
background-color: #f06;
}
@ -62,7 +64,7 @@
</div>
<!-- Matched checks -->
<div id="matched-parent" class="external-rule inheritable-rule uninheritable-rule" style="color: red;">
<div id="matched-parent" class="external-rule inheritable-rule column-rule uninheritable-rule" style="color: red;">
<div id="matched-test-node" style="font-size: 10px" class="external-rule">
Here is the test node.
</div>

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

@ -52,17 +52,23 @@ addTest(function testMatchedStyles() {
is(matched[0].rule.href, gInspectee.defaultView.location.href,
"Node style comes from this document");
is(matched[1].sourceText, ".inheritable-rule", "Second match comes from a rule");
is(matched[1].selector, ".inheritable-rule", "Second style has a selector");
is(matched[1].value, "15px", "Second match has the expected value");
is(matched[1].sourceText, ".column-rule",
"Second match comes from a rule");
is(matched[1].selector, ".column-rule",
"Second match comes from highest line number");
is(matched[1].value, "25px", "Second match comes from highest column");
is(matched[1].status, CssLogic.STATUS.PARENT_MATCH,
"Second match is from the parent");
"Second match is from the parent");
is(matched[1].rule.parentStyleSheet.href, null,
"Inline stylesheet shouldn't have an href");
"Inline stylesheet shouldn't have an href");
is(matched[1].rule.parentStyleSheet.nodeHref, gInspectee.defaultView.location.href,
"Inline stylesheet's nodeHref should match the current document");
"Inline stylesheet's nodeHref should match the current document");
ok(!matched[1].rule.parentStyleSheet.system,
"Inline stylesheet shouldn't be a system stylesheet.");
"Inline stylesheet shouldn't be a system stylesheet.");
// matched[2] is only there to test matched[1]; do not need to test
is(matched[3].value, "15px", "Third match has the expected value");
}).then(runNextTest));
});

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

@ -43,6 +43,7 @@
#include "nsArray.h"
#include "nsArrayUtils.h"
#include "nsContentSecurityManager.h"
#include "nsICaptivePortalService.h"
#include "nsIDOMStorage.h"
#include "nsIContentViewer.h"
@ -221,6 +222,7 @@
#include "mozilla/dom/PerformanceNavigation.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Encoding.h"
#include "nsJSEnvironment.h"
#include "IUrlClassifierUITelemetry.h"
#ifdef MOZ_TOOLKIT_SEARCH
@ -9942,36 +9944,13 @@ nsDocShell::InternalLoad(nsIURI* aURI,
isTargetTopLevelDocShell = true;
}
if (contentType == nsIContentPolicy::TYPE_DOCUMENT &&
nsIOService::BlockToplevelDataUriNavigations()) {
bool isDataURI =
(NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI);
// Let's block all toplevel document navigations to a data: URI.
// In all cases where the toplevel document is navigated to a
// data: URI the triggeringPrincipal is a codeBasePrincipal, or
// a NullPrincipal. In other cases, e.g. typing a data: URL into
// the URL-Bar, the triggeringPrincipal is a SystemPrincipal;
// we don't want to block those loads. Only exception, loads coming
// from an external applicaton (e.g. Thunderbird) don't load
// using a codeBasePrincipal, but we want to block those loads.
bool loadFromExternal = (aLoadType == LOAD_NORMAL_EXTERNAL);
if (isDataURI && (loadFromExternal ||
!nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal))) {
NS_ConvertUTF8toUTF16 specUTF16(aURI->GetSpecOrDefault());
if (specUTF16.Length() > 50) {
specUTF16.Truncate(50);
specUTF16.AppendLiteral("...");
}
const char16_t* params[] = { specUTF16.get() };
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DATA_URI_BLOCKED"),
// no doc available, log to browser console
nullptr,
nsContentUtils::eSECURITY_PROPERTIES,
"BlockTopLevelDataURINavigation",
params, ArrayLength(params));
return NS_OK;
}
if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
aURI,
contentType,
aTriggeringPrincipal,
(aLoadType == LOAD_NORMAL_EXTERNAL))) {
// logging to console happens within AllowTopLevelNavigationToDataURI
return NS_OK;
}
// If there's no targetDocShell, that means we are about to create a new
@ -11726,6 +11705,11 @@ nsDocShell::DoChannelLoad(nsIChannel* aChannel,
rv = aURILoader->OpenURI(aChannel, openFlags, this);
NS_ENSURE_SUCCESS(rv, rv);
// We're about to load a new page and it may take time before necko
// gives back any data, so main thread might have a chance to process a
// collector slice
nsJSContext::MaybeRunNextCollectorSlice(this, JS::gcreason::DOCSHELL);
return NS_OK;
}

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

@ -111,6 +111,10 @@ DocumentFragment::Constructor(const GlobalObject& aGlobal,
return window->GetDoc()->CreateDocumentFragment();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(DocumentFragment,
FragmentOrElement,
mHost)
// QueryInterface implementation for DocumentFragment
NS_INTERFACE_MAP_BEGIN(DocumentFragment)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY

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

@ -43,6 +43,8 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocumentFragment,
FragmentOrElement)
// interface nsIDOMNode
NS_FORWARD_NSIDOMNODE_TO_NSINODE
@ -120,12 +122,12 @@ public:
return nullptr;
}
nsIContent* GetHost() const
Element* GetHost() const
{
return mHost;
}
void SetHost(nsIContent* aHost)
void SetHost(Element* aHost)
{
mHost = aHost;
}
@ -145,7 +147,7 @@ protected:
nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;
nsIContent* mHost; // Weak
nsCOMPtr<Element> mHost;
};
} // namespace dom

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

@ -59,14 +59,14 @@ NS_INTERFACE_MAP_END_INHERITING(DocumentFragment)
NS_IMPL_ADDREF_INHERITED(ShadowRoot, DocumentFragment)
NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment)
ShadowRoot::ShadowRoot(nsIContent* aContent,
ShadowRoot::ShadowRoot(Element* aElement,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
nsXBLPrototypeBinding* aProtoBinding)
: DocumentFragment(aNodeInfo), mPoolHost(aContent),
: DocumentFragment(aNodeInfo), mPoolHost(aElement),
mProtoBinding(aProtoBinding), mShadowElement(nullptr),
mInsertionPointChanged(false), mIsComposedDocParticipant(false)
{
SetHost(aContent);
SetHost(aElement);
// Nodes in a shadow tree should never store a value
// in the subtree root pointer, nodes in the shadow tree
@ -75,7 +75,7 @@ ShadowRoot::ShadowRoot(nsIContent* aContent,
SetFlags(NODE_IS_IN_SHADOW_TREE);
ExtendedDOMSlots()->mBindingParent = aContent;
ExtendedDOMSlots()->mBindingParent = aElement;
ExtendedDOMSlots()->mContainingShadow = this;
// Add the ShadowRoot as a mutation observer on the host to watch

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

@ -42,7 +42,7 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
ShadowRoot(nsIContent* aContent, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
ShadowRoot(Element* aElement, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
nsXBLPrototypeBinding* aProtoBinding);
void AddToIdTable(Element* aElement, nsIAtom* aId);

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

@ -1438,7 +1438,7 @@ nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener)
NS_IMETHODIMP
nsDOMWindowUtils::RunNextCollectorTimer()
{
nsJSContext::RunNextCollectorTimer();
nsJSContext::RunNextCollectorTimer(JS::gcreason::DOM_WINDOW_UTILS);
return NS_OK;
}

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

@ -12771,23 +12771,23 @@ nsDocument::DocAddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const
// PresShell, which contains the frame tree.
nsIDocument::DocAddSizeOfExcludingThis(aWindowSizes);
aWindowSizes.mStyleSheetsSize +=
aWindowSizes.mLayoutStyleSheetsSize +=
SizeOfOwnedSheetArrayExcludingThis(mStyleSheets,
aWindowSizes.mState.mMallocSizeOf);
// Note that we do not own the sheets pointed to by mOnDemandBuiltInUASheets
// (the nsLayoutStyleSheetCache singleton does).
aWindowSizes.mStyleSheetsSize +=
aWindowSizes.mLayoutStyleSheetsSize +=
mOnDemandBuiltInUASheets.ShallowSizeOfExcludingThis(
aWindowSizes.mState.mMallocSizeOf);
for (auto& sheetArray : mAdditionalSheets) {
aWindowSizes.mStyleSheetsSize +=
aWindowSizes.mLayoutStyleSheetsSize +=
SizeOfOwnedSheetArrayExcludingThis(sheetArray,
aWindowSizes.mState.mMallocSizeOf);
}
// Lumping in the loader with the style-sheets size is not ideal,
// but most of the things in there are in fact stylesheets, so it
// doesn't seem worthwhile to separate it out.
aWindowSizes.mStyleSheetsSize +=
aWindowSizes.mLayoutStyleSheetsSize +=
CSSLoader()->SizeOfIncludingThis(aWindowSizes.mState.mMallocSizeOf);
aWindowSizes.mDOMOtherSize += mAttrStyleSheet

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

@ -340,8 +340,8 @@ interface nsIContentPolicy : nsISupports
/* When adding new content types, please update nsContentBlocker,
* NS_CP_ContentTypeName, nsCSPContext, all nsIContentPolicy
* implementations, the static_assert in dom/cache/DBSchema.cpp,
* and other things that are not listed here that are related to
* nsIContentPolicy. */
* ChannelWrapper.webidl, ChannelWrapper.cpp, and other things that
* are not listed here that are related to nsIContentPolicy. */
//////////////////////////////////////////////////////////////////////

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

@ -83,10 +83,14 @@
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "nsCycleCollectionNoteRootCallback.h"
#include "GeckoProfiler.h"
#include "mozilla/IdleTaskRunner.h"
#include "nsIDocShell.h"
#include "nsIPresShell.h"
#include "nsViewManager.h"
#include "mozilla/EventStateManager.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -216,12 +220,6 @@ static bool sCompactOnUserInactive;
static uint32_t sCompactOnUserInactiveDelay = NS_DEAULT_INACTIVE_GC_DELAY;
static bool sIsCompactingOnUserInactive = false;
// In testing, we call RunNextCollectorTimer() to ensure that the collectors are run more
// aggressively than they would be in regular browsing. sExpensiveCollectorPokes keeps
// us from triggering expensive full collections too frequently.
static int32_t sExpensiveCollectorPokes = 0;
static const int32_t kPokesBetweenExpensiveCollectorTriggers = 5;
static TimeDuration sGCUnnotifiedTotalTime;
static const char*
@ -1980,62 +1978,98 @@ nsJSContext::LoadEnd()
sLoadingInProgress = false;
}
// Only trigger expensive timers when they have been checked a number of times.
static bool
ReadyToTriggerExpensiveCollectorTimer()
{
bool ready = kPokesBetweenExpensiveCollectorTriggers < ++sExpensiveCollectorPokes;
if (ready) {
sExpensiveCollectorPokes = 0;
}
return ready;
}
// Check all of the various collector timers/runners and see if they are waiting to fire.
// For the synchronous collector timers/runners, sGCTimer and sCCRunner, we only want to
// trigger the collection occasionally, because they are expensive. The incremental collector
// timers, sInterSliceGCRunner and sICCRunner, are fast and need to be run many times, so
// always run their corresponding timer.
// This does not check sFullGCTimer, as that's a more expensive collection we run
// on a long timer.
// static
void
nsJSContext::RunNextCollectorTimer()
nsJSContext::RunNextCollectorTimer(JS::gcreason::Reason aReason,
mozilla::TimeStamp aDeadline)
{
if (sShuttingDown) {
return;
}
if (sGCTimer) {
if (ReadyToTriggerExpensiveCollectorTimer()) {
GCTimerFired(nullptr, reinterpret_cast<void *>(JS::gcreason::DOM_WINDOW_UTILS));
}
GCTimerFired(nullptr, reinterpret_cast<void*>(aReason));
return;
}
nsCOMPtr<nsIRunnable> runnable;
if (sInterSliceGCRunner) {
InterSliceGCRunnerFired(TimeStamp(), nullptr);
return;
sInterSliceGCRunner->SetDeadline(aDeadline);
runnable = sInterSliceGCRunner;
} else {
// Check the CC timers after the GC timers, because the CC timers won't do
// anything if a GC is in progress.
MOZ_ASSERT(!sCCLockedOut, "Don't check the CC timers if the CC is locked out.");
}
// Check the CC timers after the GC timers, because the CC timers won't do
// anything if a GC is in progress.
MOZ_ASSERT(!sCCLockedOut, "Don't check the CC timers if the CC is locked out.");
if (sCCRunner) {
if (ReadyToTriggerExpensiveCollectorTimer()) {
CCRunnerFired(TimeStamp());
}
return;
sCCRunner->SetDeadline(aDeadline);
runnable = sCCRunner;
}
if (sICCRunner) {
ICCRunnerFired(TimeStamp());
sICCRunner->SetDeadline(aDeadline);
runnable = sICCRunner;
}
if (runnable) {
runnable->Run();
}
}
// static
void
nsJSContext::MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
JS::gcreason::Reason aReason)
{
if (!aDocShell || !XRE_IsContentProcess()) {
return;
}
nsCOMPtr<nsIDocShellTreeItem> root;
aDocShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
if (root == aDocShell) {
// We don't want to run collectors when loading the top level page.
return;
}
nsIDocument* rootDocument = root->GetDocument();
if (!rootDocument ||
rootDocument->GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE ||
rootDocument->IsInBackgroundWindow()) {
return;
}
nsIPresShell* presShell = rootDocument->GetShell();
if (!presShell) {
return;
}
nsViewManager* vm = presShell->GetViewManager();
if (!vm) {
return;
}
// GetLastUserEventTime returns microseconds.
uint32_t lastEventTime = 0;
vm->GetLastUserEventTime(lastEventTime);
uint32_t currentTime =
PR_IntervalToMicroseconds(PR_IntervalNow());
// Only try to trigger collectors more often if user hasn't interacted with
// the page for awhile.
if ((currentTime - lastEventTime) >
(NS_USER_INTERACTION_INTERVAL * PR_USEC_PER_MSEC)) {
Maybe<TimeStamp> next = nsRefreshDriver::GetNextTickHint();
// Try to not delay the next RefreshDriver tick, so give a reasonable
// deadline for collectors.
if (next.isSome()) {
nsJSContext::RunNextCollectorTimer(aReason, next.value());
}
}
}
// static
@ -2409,7 +2443,6 @@ mozilla::dom::StartupJSEnvironment()
sDidShutdown = false;
sShuttingDown = false;
gCCStats.Init();
sExpensiveCollectorPokes = 0;
}
static void

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

@ -21,6 +21,7 @@
class nsICycleCollectorListener;
class nsScriptNameSpaceManager;
class nsIDocShell;
namespace JS {
class AutoValueVector;
@ -101,7 +102,14 @@ public:
static uint32_t GetMaxCCSliceTimeSinceClear();
static void ClearMaxCCSliceTime();
static void RunNextCollectorTimer();
// If there is some pending CC or GC timer/runner, this will run it.
static void RunNextCollectorTimer(JS::gcreason::Reason aReason,
mozilla::TimeStamp aDeadline = mozilla::TimeStamp());
// If user has been idle and aDocShell is for an iframe being loaded in an
// already loaded top level docshell, this will run a CC or GC
// timer/runner if there is such pending.
static void MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
JS::gcreason::Reason aReason);
// The GC should probably run soon, in the zone of object aObj (if given).
static void PokeGC(JS::gcreason::Reason aReason, JSObject* aObj, int aDelay = 0);

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

@ -11,7 +11,6 @@
#include "nsNodeInfoManager.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/NodeInfo.h"
#include "mozilla/dom/NodeInfoInlines.h"
#include "nsCOMPtr.h"
@ -420,9 +419,6 @@ nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal *aPrincipal)
NS_ASSERTION(aPrincipal, "Must have principal by this point!");
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsExpandedPrincipal(aPrincipal),
"Documents shouldn't have an expanded principal");
if (nsContentUtils::IsExpandedPrincipal(aPrincipal)) {
Telemetry::Accumulate(Telemetry::DOCUMENT_WITH_EXPANDED_PRINCIPAL, 1);
}
mPrincipal = aPrincipal;
}

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

@ -1487,6 +1487,27 @@ nsRange::SetEnd(nsINode* aContainer, uint32_t aOffset)
return NS_OK;
}
void
nsRange::SelectNodesInContainer(nsINode* aContainer,
nsIContent* aStartContent,
nsIContent* aEndContent)
{
MOZ_ASSERT(aContainer);
MOZ_ASSERT(aContainer->IndexOf(aStartContent) <= aContainer->IndexOf(aEndContent));
MOZ_ASSERT(aStartContent && aContainer->IndexOf(aStartContent) != -1);
MOZ_ASSERT(aEndContent && aContainer->IndexOf(aEndContent) != -1);
nsINode* newRoot = ComputeRootNode(aContainer, mMaySpanAnonymousSubtrees);
MOZ_ASSERT(newRoot);
if (!newRoot) {
return;
}
RawRangeBoundary start(aContainer, aStartContent->GetPreviousSibling());
RawRangeBoundary end(aContainer, aEndContent);
DoSetRange(start, end, newRoot);
}
nsresult
nsRange::SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
nsINode* aEndContainer, uint32_t aEndOffset)

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

@ -172,6 +172,19 @@ public:
nsresult SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
nsINode* aEndContainer, uint32_t aEndOffset);
/**
* Adds all nodes between |aStartContent| and |aEndContent| to the range.
* The start offset will be set before |aStartContent|,
* while the end offset will be set immediately after |aEndContent|.
*
* Caller must guarantee both nodes are non null and
* children of |aContainer| and that |aEndContent| is after |aStartContent|.
*/
void
SelectNodesInContainer(nsINode* aContainer,
nsIContent* aStartContent,
nsIContent* aEndContent);
/**
* CollapseTo() works similar to call both SetStart() and SetEnd() with
* same node and offset. This just calls SetStartAndParent() to set

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

@ -35,7 +35,8 @@ const int32_t kTimeBetweenChecks = 45; /* seconds */
nsWindowMemoryReporter::nsWindowMemoryReporter()
: mLastCheckForGhostWindows(TimeStamp::NowLoRes()),
mCycleCollectorIsRunning(false),
mCheckTimerWaitingForCCEnd(false)
mCheckTimerWaitingForCCEnd(false),
mGhostWindowCount(0)
{
}
@ -120,8 +121,7 @@ nsWindowMemoryReporter::Init()
/* weakRef = */ true);
}
RegisterStrongMemoryReporter(new GhostWindowsReporter());
RegisterGhostWindowsDistinguishedAmount(GhostWindowsReporter::DistinguishedAmount);
RegisterGhostWindowsDistinguishedAmount(GhostWindowsDistinguishedAmount);
}
/* static */ nsWindowMemoryReporter*
@ -354,9 +354,10 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"other 'dom/' numbers.");
aWindowTotalSizes->mDOMOtherSize += windowSizes.mDOMOtherSize;
REPORT_SIZE("/style-sheets", windowSizes.mStyleSheetsSize,
REPORT_SIZE("/layout/style-sheets", windowSizes.mLayoutStyleSheetsSize,
"Memory used by style sheets within a window.");
aWindowTotalSizes->mStyleSheetsSize += windowSizes.mStyleSheetsSize;
aWindowTotalSizes->mLayoutStyleSheetsSize +=
windowSizes.mLayoutStyleSheetsSize;
REPORT_SIZE("/layout/pres-shell", windowSizes.mLayoutPresShellSize,
"Memory used by layout's PresShell, along with any structures "
@ -628,6 +629,17 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
aData);
}
MOZ_COLLECT_REPORT(
"ghost-windows", KIND_OTHER, UNITS_COUNT, ghostWindows.Count(),
"The number of ghost windows present (the number of nodes underneath "
"explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost "
"window is not shown in any tab, does not share a domain with any non-detached "
"windows, and has met these criteria for at least "
"memory.ghost_window_timeout_seconds, or has survived a round of "
"about:memory's minimize memory usage button.\n\n"
"Ghost windows can happen legitimately, but they are often indicative of "
"leaks in the browser or add-ons.");
WindowPaths windowPaths;
WindowPaths topWindowPaths;
@ -680,8 +692,9 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
REPORT("window-objects/dom/other", windowTotalSizes.mDOMOtherSize,
"This is the sum of all windows' 'dom/other' numbers.");
REPORT("window-objects/style-sheets", windowTotalSizes.mStyleSheetsSize,
"This is the sum of all windows' 'style-sheets' numbers.");
REPORT("window-objects/layout/style-sheets",
windowTotalSizes.mLayoutStyleSheetsSize,
"This is the sum of all windows' 'layout/style-sheets' numbers.");
REPORT("window-objects/layout/pres-shell",
windowTotalSizes.mLayoutPresShellSize,
@ -921,6 +934,7 @@ nsWindowMemoryReporter::CheckForGhostWindows(
KillCheckTimer();
nsTHashtable<nsCStringHashKey> nonDetachedWindowDomains;
nsDataHashtable<nsISupportsHashKey, nsCString> domainMap;
// Populate nonDetachedWindowDomains.
for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) {
@ -935,8 +949,13 @@ nsWindowMemoryReporter::CheckForGhostWindows(
nsCOMPtr<nsIURI> uri = GetWindowURI(window);
nsAutoCString domain;
if (uri) {
tldService->GetBaseDomain(uri, 0, domain);
domain = domainMap.LookupForAdd(uri).OrInsert([&]() {
nsCString d;
tldService->GetBaseDomain(uri, 0, d);
return d;
});
}
nonDetachedWindowDomains.PutEntry(domain);
}
@ -944,6 +963,7 @@ nsWindowMemoryReporter::CheckForGhostWindows(
// if it's not null.
uint32_t ghostTimeout = GetGhostTimeout();
TimeStamp now = mLastCheckForGhostWindows;
mGhostWindowCount = 0;
for (auto iter = mDetachedWindows.Iter(); !iter.Done(); iter.Next()) {
nsWeakPtr weakKey = do_QueryInterface(iter.Key());
nsCOMPtr<mozIDOMWindow> iwindow = do_QueryReferent(weakKey);
@ -994,6 +1014,7 @@ nsWindowMemoryReporter::CheckForGhostWindows(
} else if ((now - timeStamp).ToSeconds() > ghostTimeout) {
// This definitely is a ghost window, so add it to aOutGhostIDs, if
// that is not null.
mGhostWindowCount++;
if (aOutGhostIDs && window) {
aOutGhostIDs->PutEntry(window->WindowID());
}
@ -1002,15 +1023,10 @@ nsWindowMemoryReporter::CheckForGhostWindows(
}
}
NS_IMPL_ISUPPORTS(nsWindowMemoryReporter::GhostWindowsReporter,
nsIMemoryReporter)
/* static */ int64_t
nsWindowMemoryReporter::GhostWindowsReporter::DistinguishedAmount()
nsWindowMemoryReporter::GhostWindowsDistinguishedAmount()
{
nsTHashtable<nsUint64HashKey> ghostWindows;
sWindowReporter->CheckForGhostWindows(&ghostWindows);
return ghostWindows.Count();
return sWindowReporter->mGhostWindowCount;
}
void

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

@ -103,40 +103,11 @@ public:
static nsWindowMemoryReporter* Get();
void ObserveDOMWindowDetached(nsGlobalWindow* aWindow);
static int64_t GhostWindowsDistinguishedAmount();
private:
~nsWindowMemoryReporter();
/**
* nsGhostWindowReporter generates the "ghost-windows" report, which counts
* the number of ghost windows present.
*/
class GhostWindowsReporter final : public nsIMemoryReporter
{
~GhostWindowsReporter() {}
public:
NS_DECL_ISUPPORTS
static int64_t DistinguishedAmount();
NS_IMETHOD
CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
bool aAnonymize) override
{
MOZ_COLLECT_REPORT(
"ghost-windows", KIND_OTHER, UNITS_COUNT, DistinguishedAmount(),
"The number of ghost windows present (the number of nodes underneath "
"explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost "
"window is not shown in any tab, does not share a domain with any non-detached "
"windows, and has met these criteria for at least "
"memory.ghost_window_timeout_seconds, or has survived a round of "
"about:memory's minimize memory usage button.\n\n"
"Ghost windows can happen legitimately, but they are often indicative of "
"leaks in the browser or add-ons.");
return NS_OK;
}
};
// Protect ctor, use Init() instead.
nsWindowMemoryReporter();
@ -199,6 +170,8 @@ private:
bool mCycleCollectorIsRunning;
bool mCheckTimerWaitingForCCEnd;
int64_t mGhostWindowCount;
};
#endif // nsWindowMemoryReporter_h__

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

@ -173,7 +173,7 @@ class nsWindowSizes
macro(DOM, mDOMPerformanceUserEntries) \
macro(DOM, mDOMPerformanceResourceEntries) \
macro(DOM, mDOMOtherSize) \
macro(Style, mStyleSheetsSize) \
macro(Style, mLayoutStyleSheetsSize) \
macro(Other, mLayoutPresShellSize) \
macro(Style, mLayoutGeckoStyleSets) \
macro(Style, mLayoutServoStyleSetsStylistRuleTree) \

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

@ -135,6 +135,10 @@ DOMInterfaces = {
'nativeType': 'nsDOMCaretPosition',
},
'ChannelWrapper': {
'nativeType': 'mozilla::extensions::ChannelWrapper',
},
'CharacterData': {
'nativeType': 'nsGenericDOMDataNode',
'concrete': False

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

@ -33,7 +33,8 @@ MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call
MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, JSEXN_TYPEERR, "\"this\" object does not implement interface {0}.")
MSG_DEF(MSG_NOT_IN_UNION, 2, JSEXN_TYPEERR, "{0} could not be converted to any of: {1}.")
MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, JSEXN_TYPEERR, "Illegal constructor.")
MSG_DEF(MSG_ILLEGAL_PR_CONSTRUCTOR, 1, JSEXN_TYPEERR, "TypeError:{0}")
MSG_DEF(MSG_ILLEGAL_TYPE_PR_CONSTRUCTOR, 1, JSEXN_TYPEERR, "TypeError:{0}")
MSG_DEF(MSG_ILLEGAL_RANGE_PR_CONSTRUCTOR, 1, JSEXN_RANGEERR, "RangeError:{0}")
MSG_DEF(MSG_CONSTRUCTOR_WITHOUT_NEW, 1, JSEXN_TYPEERR, "Constructor {0} requires 'new'")
MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, JSEXN_TYPEERR, "Non-finite value is out of range for {0}.")
MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "Value is out of range for {0}.")

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

@ -107,8 +107,6 @@ using namespace dom;
//#define DEBUG_DOCSHELL_FOCUS
#define NS_USER_INTERACTION_INTERVAL 5000 // ms
static const LayoutDeviceIntPoint kInvalidRefPoint = LayoutDeviceIntPoint(-1,-1);
static uint32_t gMouseOrKeyboardEventCounter = 0;

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

@ -18,6 +18,8 @@
#include "nsIFrame.h"
#include "Units.h"
#define NS_USER_INTERACTION_INTERVAL 5000 // ms
class nsFrameLoader;
class nsIContent;
class nsIDocument;

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

@ -17,7 +17,7 @@ interface nsIArray;
interface nsIEventListenerChange : nsISupports
{
readonly attribute nsIDOMEventTarget target;
readonly attribute nsIArray changedListenerNames;
[noscript] readonly attribute nsIArray changedListenerNames;
};
[scriptable, function, uuid(aa7c95f6-d3b5-44b3-9597-1d9f19b9c5f2)]

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

@ -108,22 +108,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674
var expected = expectedEventChanges[i];
if (current.target == expected.target) {
// expected.target.listeners should be a subset of
// current.changedListenerNames if all expected listener changes were
// sent. We may get random other event listener changes here too, not
// just the one from the test.
is(current.target, expected.target, current.target + " = " + expected.target);
var eNames = current.changedListenerNames.enumerate();
var listeners = [];
while (eNames.hasMoreElements()) {
var listenerName = eNames.getNext().QueryInterface(Ci.nsIAtom).toString();
listeners.push(listenerName);
}
var matchAll = expected.listeners.every(function(val)
{ return listeners.indexOf(val) >= 0; });
if (!matchAll)
return;
++i;
}
} catch(ex) {

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

@ -3567,13 +3567,17 @@ HTMLInputElement::NeedToInitializeEditorForEvent(
// are lazily initialized. We don't need to initialize the control for
// certain types of events, because we know that those events are safe to be
// handled without the editor being initialized. These events include:
// mousein/move/out, overflow/underflow, and DOM mutation events.
// mousein/move/out, overflow/underflow, DOM mutation, and void events. Void
// events are dispatched frequently by async keyboard scrolling to focused
// elements, so it's important to handle them to prevent excessive DOM
// mutations.
if (!IsSingleLineTextControl(false) ||
aVisitor.mEvent->mClass == eMutationEventClass) {
return false;
}
switch (aVisitor.mEvent->mMessage) {
case eVoidEvent:
case eMouseMove:
case eMouseEnterIntoWidget:
case eMouseExitFromWidget:

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше