Merge inbound to central, a=merge

MozReview-Commit-ID: 3N9jinnrmjb
This commit is contained in:
Wes Kocher 2017-08-25 16:21:57 -07:00
commit 68149d6a59
349 changed files with 6707 additions and 2740 deletions

View File

@ -15,6 +15,8 @@
#if defined(XP_WIN)
#include "AccessibleWrap.h"
#include "Compatibility.h"
#include "mozilla/mscom/PassthruProxy.h"
#include "mozilla/mscom/Ptr.h"
#include "nsWinUtils.h"
#include "RootAccessible.h"
#endif
@ -624,17 +626,18 @@ DocAccessibleParent::MaybeInitWindowEmulation()
}
nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {
IAccessibleHolder hWndAccHolder;
IDispatchHolder hWndAccHolder;
::SetPropW(aHwnd, kPropNameDocAccParent, reinterpret_cast<HANDLE>(this));
SetEmulatedWindowHandle(aHwnd);
IAccessible* rawHWNDAcc = nullptr;
RefPtr<IAccessible> hwndAcc;
if (SUCCEEDED(::AccessibleObjectFromWindow(aHwnd, OBJID_WINDOW,
IID_IAccessible,
(void**)&rawHWNDAcc))) {
hWndAccHolder.Set(IAccessibleHolder::COMPtrType(rawHWNDAcc));
getter_AddRefs(hwndAcc)))) {
RefPtr<IDispatch> wrapped(mscom::PassthruProxy::Wrap<IDispatch>(WrapNotNull(hwndAcc)));
hWndAccHolder.Set(IDispatchHolder::COMPtrType(mscom::ToProxyUniquePtr(Move(wrapped))));
}
Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
@ -668,12 +671,14 @@ DocAccessibleParent::SendParentCOMProxy()
return;
}
IAccessible* rawNative = nullptr;
outerDoc->GetNativeInterface((void**) &rawNative);
MOZ_ASSERT(rawNative);
RefPtr<IAccessible> nativeAcc;
outerDoc->GetNativeInterface(getter_AddRefs(nativeAcc));
MOZ_ASSERT(nativeAcc);
IAccessibleHolder::COMPtrType ptr(rawNative);
IAccessibleHolder holder(Move(ptr));
RefPtr<IDispatch> wrapped(mscom::PassthruProxy::Wrap<IDispatch>(WrapNotNull(nativeAcc)));
IDispatchHolder::COMPtrType ptr(mscom::ToProxyUniquePtr(Move(wrapped)));
IDispatchHolder holder(Move(ptr));
if (!PDocAccessibleParent::SendParentCOMProxy(holder)) {
return;
}

View File

@ -41,6 +41,7 @@ namespace mozilla {
namespace a11y {
typedef uint32_t IAccessibleHolder;
typedef uint32_t IDispatchHolder;
typedef uint32_t IHandlerControlHolder;
} // namespace a11y

View File

@ -16,6 +16,7 @@ namespace mozilla {
namespace a11y {
typedef mozilla::mscom::COMPtrHolder<IAccessible, IID_IAccessible> IAccessibleHolder;
typedef mozilla::mscom::COMPtrHolder<IDispatch, IID_IDispatch> IDispatchHolder;
class Accessible;

View File

@ -49,10 +49,10 @@ DocAccessibleChild::Shutdown()
}
ipc::IPCResult
DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy)
DocAccessibleChild::RecvParentCOMProxy(const IDispatchHolder& aParentCOMProxy)
{
MOZ_ASSERT(!mParentProxy && !aParentCOMProxy.IsNull());
mParentProxy.reset(const_cast<IAccessibleHolder&>(aParentCOMProxy).Release());
mParentProxy.reset(const_cast<IDispatchHolder&>(aParentCOMProxy).Release());
SetConstructedInParentProcess();
for (uint32_t i = 0, l = mDeferredEvents.Length(); i < l; ++i) {
@ -66,13 +66,13 @@ DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy)
ipc::IPCResult
DocAccessibleChild::RecvEmulatedWindow(const WindowsHandle& aEmulatedWindowHandle,
const IAccessibleHolder& aEmulatedWindowCOMProxy)
const IDispatchHolder& aEmulatedWindowCOMProxy)
{
mEmulatedWindowHandle = reinterpret_cast<HWND>(aEmulatedWindowHandle);
if (!aEmulatedWindowCOMProxy.IsNull()) {
MOZ_ASSERT(!mEmulatedWindowProxy);
mEmulatedWindowProxy.reset(
const_cast<IAccessibleHolder&>(aEmulatedWindowCOMProxy).Release());
const_cast<IDispatchHolder&>(aEmulatedWindowCOMProxy).Release());
}
return IPC_OK();

View File

@ -28,17 +28,17 @@ public:
virtual void Shutdown() override;
virtual ipc::IPCResult
RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy) override;
RecvParentCOMProxy(const IDispatchHolder& aParentCOMProxy) override;
virtual ipc::IPCResult
RecvEmulatedWindow(const WindowsHandle& aEmulatedWindowHandle,
const IAccessibleHolder& aEmulatedWindowCOMProxy) override;
const IDispatchHolder& aEmulatedWindowCOMProxy) override;
virtual ipc::IPCResult
RecvRestoreFocus() override;
HWND GetNativeWindowHandle() const;
IAccessible* GetEmulatedWindowIAccessible() const { return mEmulatedWindowProxy.get(); }
IDispatch* GetEmulatedWindowIAccessible() const { return mEmulatedWindowProxy.get(); }
IAccessible* GetParentIAccessible() const { return mParentProxy.get(); }
IDispatch* GetParentIAccessible() const { return mParentProxy.get(); }
bool SendEvent(const uint64_t& aID, const uint32_t& type);
bool SendHideEvent(const uint64_t& aRootID, const bool& aFromUser);
@ -344,8 +344,8 @@ private:
};
bool mIsRemoteConstructed;
mscom::ProxyUniquePtr<IAccessible> mParentProxy;
mscom::ProxyUniquePtr<IAccessible> mEmulatedWindowProxy;
mscom::ProxyUniquePtr<IDispatch> mParentProxy;
mscom::ProxyUniquePtr<IDispatch> mEmulatedWindowProxy;
nsTArray<UniquePtr<DeferredEvent>> mDeferredEvents;
HWND mEmulatedWindowHandle;
};

View File

@ -16,6 +16,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/Move.h"
#include "mozilla/mscom/AgileReference.h"
#include "mozilla/mscom/FastMarshaler.h"
#include "mozilla/mscom/MainThreadInvoker.h"
#include "mozilla/mscom/Ptr.h"
#include "mozilla/mscom/StructStream.h"
@ -43,18 +44,25 @@ HandlerProvider::QueryInterface(REFIID riid, void** ppv)
return E_INVALIDARG;
}
RefPtr<IUnknown> punk;
if (riid == IID_IUnknown || riid == IID_IGeckoBackChannel) {
punk = static_cast<IGeckoBackChannel*>(this);
RefPtr<IUnknown> punk(static_cast<IGeckoBackChannel*>(this));
punk.forget(ppv);
return S_OK;
}
if (!punk) {
return E_NOINTERFACE;
if (riid == IID_IMarshal) {
if (!mFastMarshalUnk) {
HRESULT hr = mscom::FastMarshaler::Create(
static_cast<IGeckoBackChannel*>(this), getter_AddRefs(mFastMarshalUnk));
if (FAILED(hr)) {
return hr;
}
}
return mFastMarshalUnk->QueryInterface(riid, ppv);
}
punk.forget(ppv);
return S_OK;
return E_NOINTERFACE;
}
ULONG

View File

@ -67,6 +67,7 @@ private:
const IID mTargetUnkIid;
mscom::InterceptorTargetPtr<IUnknown> mTargetUnk; // Constant, main thread only
UniquePtr<mscom::StructToStream> mSerializer;
RefPtr<IUnknown> mFastMarshalUnk;
};
} // namespace a11y

View File

@ -8,6 +8,7 @@ include protocol PFileDescriptorSet;
include protocol PBrowser;
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::a11y::IDispatchHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
using mozilla::LayoutDeviceIntRect from "Units.h";
@ -71,9 +72,18 @@ parent:
returns (IAccessibleHolder aPluginCOMProxy);
child:
async ParentCOMProxy(IAccessibleHolder aParentCOMProxy);
/**
* We use IDispatchHolder instead of IAccessibleHolder for the following two
* methods because of sandboxing. IAccessible::get_accParent returns the parent
* as an IDispatch. COM is not smart enough to understand that IAccessible is
* derived from IDispatch, so during marshaling it attempts to QueryInterface
* on the parent's proxy for IDispatch. This will fail with E_ACCESSDENIED
* thanks to the sandbox. We can avoid this entirely by just giving content
* the correct interface to begin with: IDispatch.
*/
async ParentCOMProxy(IDispatchHolder aParentCOMProxy);
async EmulatedWindow(WindowsHandle aEmulatedWindowHandle,
IAccessibleHolder aEmulatedWindowCOMProxy);
IDispatchHolder aEmulatedWindowCOMProxy);
/*
* Called as a result of focus shifting from chrome to content
* elements through keyboard navigation.

View File

@ -56,7 +56,7 @@ DocAccessibleWrap::get_accParent(
// Emulated window proxy is only set for the top level content document when
// emulation is enabled.
IAccessible* dispParent = ipcDoc->GetEmulatedWindowIAccessible();
RefPtr<IDispatch> dispParent = ipcDoc->GetEmulatedWindowIAccessible();
if (!dispParent) {
dispParent = ipcDoc->GetParentIAccessible();
}
@ -65,8 +65,7 @@ DocAccessibleWrap::get_accParent(
return S_FALSE;
}
dispParent->AddRef();
*ppdispParent = static_cast<IDispatch*>(dispParent);
dispParent.forget(ppdispParent);
return S_OK;
}

View File

@ -4,6 +4,34 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("firefox.exe.manifest"):
BUG_COMPONENT = ("Core", "Widget: Win32")
with Files("module.ver"):
BUG_COMPONENT = ("Core", "Widget: Win32")
with Files("splash.rc"):
BUG_COMPONENT = ("Core", "Widget: Win32")
with Files("macversion.py"):
BUG_COMPONENT = ("Core", "Widget: Cocoa")
with Files("macbuild/**"):
BUG_COMPONENT = ("Core", "Widget: Cocoa")
with Files("moz.build"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("Makefile.in"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/**"):
BUG_COMPONENT = ("Firefox", "Theme")
with Files("profile/channel-prefs.js"):
BUG_COMPONENT = ("Firefox", "Installer")
with Files("profile/firefox.js"):
BUG_COMPONENT = ("Firefox", "General")
DIRS += ['profile/extensions']
GeckoProgram(CONFIG['MOZ_APP_NAME'])

View File

@ -68,6 +68,15 @@ var SidebarUI = {
enumerator.getNext();
if (!enumerator.hasMoreElements()) {
document.persist("sidebar-box", "sidebarcommand");
let xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
if (this._box.hasAttribute("positionend")) {
document.persist("sidebar-box", "positionend");
} else {
xulStore.removeValue(document.documentURI, "sidebar-box", "positionend");
}
document.persist("sidebar-box", "width");
document.persist("sidebar-title", "value");
}

View File

@ -502,9 +502,10 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
/* ::::: location bar & search bar ::::: */
/* url bar min-width is defined further down, together with the maximum size
* of the identity icon block, for different window sizes.
*/
#urlbar-container {
min-width: 50ch;
}
#search-container {
min-width: 25ch;
}
@ -684,69 +685,41 @@ html|input.urlbar-input[textoverflow]:not([focused]) {
-moz-user-focus: ignore;
}
/* We leave 49ch plus whatever space the download button will need when it
* appears. Normally this should be 16px for the icon, plus 2 * 2px padding
* plus the toolbarbutton-inner-padding. We're adding 4px to ensure things
* like rounding on hidpi don't accidentally result in the button going
* into overflow.
*/
#urlbar-container {
min-width: calc(49ch + 24px + 2 * var(--toolbarbutton-inner-padding));
}
#nav-bar[hasdownloads] #urlbar-container {
min-width: 49ch;
}
#identity-icon-labels {
max-width: 17em;
max-width: 18em;
}
@media (max-width: 700px) {
#urlbar-container {
min-width: calc(44ch + 24px + 2 * var(--toolbarbutton-inner-padding));
min-width: 45ch;
}
#nav-bar[hasdownloads] #urlbar-container {
min-width: 44ch;
}
#identity-icon-labels {
max-width: 60px;
max-width: 70px;
}
}
@media (max-width: 600px) {
#urlbar-container {
min-width: calc(39ch + 24px + 2 * var(--toolbarbutton-inner-padding));
min-width: 40ch;
}
#nav-bar[hasdownloads] #urlbar-container {
min-width: 39ch;
#identity-icon-labels {
max-width: 60px;
}
}
@media (max-width: 500px) {
#urlbar-container {
min-width: 35ch;
}
#identity-icon-labels {
max-width: 50px;
}
}
@media (max-width: 500px) {
@media (max-width: 400px) {
#urlbar-container {
min-width: calc(34ch + 24px + 2 * var(--toolbarbutton-inner-padding));
}
#nav-bar[hasdownloads] #urlbar-container {
min-width: 34ch;
min-width: 28ch;
}
#identity-icon-labels {
max-width: 40px;
}
}
@media (max-width: 400px) {
#urlbar-container {
min-width: calc(27ch + 24px + 2 * var(--toolbarbutton-inner-padding));
}
#nav-bar[hasdownloads] #urlbar-container {
min-width: 27ch;
}
#identity-icon-labels {
max-width: 30px;
}
}
#identity-icon-country-label {
direction: ltr;
@ -1088,7 +1061,20 @@ notification[value="translation"] {
}
/*** Visibility of downloads indicator controls ***/
#downloads-button[indicator] > .toolbarbutton-badge-stack > image.toolbarbutton-icon {
/* Bug 924050: If we've loaded the indicator, for now we hide it in the menu panel,
and just show the icon. This is a hack to side-step very weird layout bugs that
seem to be caused by the indicator stack interacting with the menu panel. */
#downloads-button[indicator]:not([cui-areatype="menu-panel"]) > .toolbarbutton-badge-stack > image.toolbarbutton-icon,
#downloads-button[indicator][cui-areatype="menu-panel"] > #downloads-indicator-anchor {
display: none;
}
toolbarpaletteitem[place="palette"] > #downloads-button[indicator] > .toolbarbutton-badge-stack > image.toolbarbutton-icon {
display: -moz-box;
}
toolbarpaletteitem[place="palette"] > #downloads-button[indicator] > #downloads-indicator-anchor {
display: none;
}

View File

@ -155,13 +155,15 @@
level="parent"
overflowpadding="30" />
<!-- for date/time picker. consumeoutsideclicks is set to never, so that
clicks on the anchored input box are never consumed. -->
<panel id="DateTimePickerPanel"
type="arrow"
hidden="true"
orient="vertical"
noautofocus="true"
noautohide="true"
consumeoutsideclicks="false"
norolluponanchor="true"
consumeoutsideclicks="never"
level="parent"
tabspecific="true">
</panel>
@ -904,18 +906,17 @@
</toolbaritem>
<!-- This is a placeholder for the Downloads Indicator. It is visible
before the Downloads Indicator overlay is loaded. -->
during the customization of the toolbar, in the palette, and before
the Downloads Indicator overlay is loaded. -->
<toolbarbutton id="downloads-button"
hidden="true"
class="toolbarbutton-1 chromeclass-toolbar-additional badged-button"
skipintoolbarset="true"
overflows="false"
key="key_openDownloads"
oncommand="DownloadsIndicatorView.onCommand(event);"
ondrop="DownloadsIndicatorView.onDrop(event);"
ondragover="DownloadsIndicatorView.onDragOver(event);"
ondragenter="DownloadsIndicatorView.onDragOver(event);"
label="&downloads.label;"
removable="true"
cui-areatype="toolbar"
tooltip="dynamic-shortcut-tooltip"/>

View File

@ -25,6 +25,9 @@ with Files("newtab/**"):
with Files("pageinfo/**"):
BUG_COMPONENT = ("Firefox", "Page Info Window")
with Files("test/about/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/alerts/**"):
BUG_COMPONENT = ("Toolkit", "Notifications and Alerts")
@ -34,6 +37,9 @@ with Files("test/captivePortal/**"):
with Files("test/chrome/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/contextMenu/**"):
BUG_COMPONENT = ("Firefox", "Menus")
with Files("test/forms/**"):
BUG_COMPONENT = ("Core", "Layout: Form Controls")
@ -43,6 +49,9 @@ with Files("test/newtab/**"):
with Files("test/pageinfo/**"):
BUG_COMPONENT = ("Firefox", "Page Info Window")
with Files("test/performance/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/performance/browser_appmenu_reflows.js"):
BUG_COMPONENT = ("Firefox", "Menus")
@ -64,9 +73,15 @@ with Files("test/referrer/**"):
with Files("test/siteIdentity/**"):
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
with Files("test/sidebar/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/static/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/sync/**"):
BUG_COMPONENT = ("Firefox", "Sync")
with Files("test/tabPrompts/**"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser")
@ -76,6 +91,9 @@ with Files("test/tabcrashed/**"):
with Files("test/tabs/**"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser")
with Files("test/touch/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/urlbar/**"):
BUG_COMPONENT = ("Firefox", "Location Bar")

View File

@ -175,7 +175,8 @@ skip-if = toolkit == "cocoa"
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_bug537013.js]
subsuite = clipboard
skip-if = e10s # Bug 1134458 - Find bar doesn't work correctly in a detached tab
skip-if = true # bug 1393813
# skip-if = e10s # Bug 1134458 - Find bar doesn't work correctly in a detached tab
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_bug537474.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.

View File

@ -74,7 +74,7 @@ async function expectFocusOnF6(backward, expectedDocument, expectedElement, onCo
}
is(fm.focusedWindow.document.documentElement.id, expectedDocument, desc + " document matches");
is(fm.focusedElement, expectedElement, desc + " element matches (wanted: " + expectedElement.id + " got: " + fm.focusedElement.id + ")");
is(fm.focusedElement, expectedElement, desc + " element matches");
if (onContent) {
window.messageManager.removeMessageListener("BrowserTest:FocusChanged", focusChangedListener);
@ -171,32 +171,15 @@ add_task(async function() {
});
// Navigate when the downloads panel is open
add_task(async function test_download_focus() {
add_task(async function() {
await pushPrefs(["accessibility.tabfocus", 7]);
let testTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
testTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
registerCleanupFunction(() => testTargetFile.remove(false));
let downloadsList = await Downloads.getList(Downloads.PUBLIC);
let download = {
source: "http://www.example.com/test-download.txt",
target: testTargetFile.path,
succeeded: true,
startTime: new Date(),
};
await downloadsList.add(await Downloads.createDownload(download));
await BrowserTestUtils.waitForCondition(() => {
let btn = document.getElementById("downloads-button");
return !btn.hidden && btn.getBoundingClientRect().width > 0;
});
let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", true);
EventUtils.synthesizeMouseAtCenter(document.getElementById("downloads-button"), { });
await popupShownPromise;
gURLBar.focus();
await expectFocusOnF6(false, "main-window", document.getElementById("downloadsListBox"),
await expectFocusOnF6(false, "main-window", document.getElementById("downloadsHistory"),
false, "focus with downloads panel open panel");
await expectFocusOnF6(false, "html1", "html1",
true, "focus with downloads panel open");
@ -206,7 +189,7 @@ add_task(async function test_download_focus() {
// Now go backwards
await expectFocusOnF6(true, "html1", "html1",
true, "back focus with downloads panel open");
await expectFocusOnF6(true, "main-window", document.getElementById("downloadsListBox"),
await expectFocusOnF6(true, "main-window", document.getElementById("downloadsHistory"),
false, "back focus with downloads panel open");
await expectFocusOnF6(true, "main-window", gURLBar.inputField,
false, "back focus downloads panel open urlbar");

View File

@ -20,13 +20,11 @@ var tests = [
location: "http://test1.example.org/",
effectiveHost: "test1.example.org"
},
/* This part is perma-crashing, see: Bug 1315092
{
name: "view-source",
location: "view-source:http://example.com/",
effectiveHost: null
},
*/
{
name: "normal HTTPS",
location: "https://example.com/",

View File

@ -9,8 +9,8 @@ const DRAG_WORD = "Firefox";
add_task(async function checkDragURL() {
await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
// Have to use something other than the URL bar as a source, so picking the
// home button somewhat arbitrarily:
EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
// downloads button somewhat arbitrarily:
EventUtils.synthesizeDrop(document.getElementById("downloads-button"), gURLBar,
[[{type: "text/plain", data: DRAG_URL}]], "copy", window);
is(gURLBar.value, TEST_URL, "URL bar value should not have changed");
is(gBrowser.selectedBrowser.userTypedValue, null, "Stored URL bar value should not have changed");
@ -19,7 +19,7 @@ add_task(async function checkDragURL() {
add_task(async function checkDragForbiddenURL() {
await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
EventUtils.synthesizeDrop(document.getElementById("downloads-button"), gURLBar,
[[{type: "text/plain", data: DRAG_FORBIDDEN_URL}]], "copy", window);
isnot(gURLBar.value, DRAG_FORBIDDEN_URL, "Shouldn't be allowed to drop forbidden URL on URL bar");
});
@ -27,11 +27,11 @@ add_task(async function checkDragForbiddenURL() {
add_task(async function checkDragText() {
await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
EventUtils.synthesizeDrop(document.getElementById("downloads-button"), gURLBar,
[[{type: "text/plain", data: DRAG_TEXT}]], "copy", window);
is(gURLBar.value, DRAG_TEXT, "Dragging normal text should replace the URL bar value");
EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar,
EventUtils.synthesizeDrop(document.getElementById("downloads-button"), gURLBar,
[[{type: "text/plain", data: DRAG_WORD}]], "copy", window);
is(gURLBar.value, DRAG_WORD, "Dragging a single word should replace the URL bar value");
});

View File

@ -11,7 +11,7 @@ skip-if = (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_in_frame.js]
skip-if = debug # bug 1369731
[browser_devices_get_user_media_multi_process.js]
skip-if = e10s && (asan || debug) # bug 1347625
skip-if = debug && (os == "win" || os == "mac") # bug 1393761
[browser_devices_get_user_media_screen.js]
[browser_devices_get_user_media_tear_off_tab.js]
[browser_devices_get_user_media_unprompted_access.js]

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
SPHINX_TREES['sslerrorreport'] = 'content/docs/sslerrorreport'
MOCHITEST_MANIFESTS += [

View File

@ -57,7 +57,7 @@ const kSubviewEvents = [
* The current version. We can use this to auto-add new default widgets as necessary.
* (would be const but isn't because of testing purposes)
*/
var kVersion = 11;
var kVersion = 10;
/**
* Buttons removed from built-ins by version they were removed. kVersion must be
@ -177,7 +177,7 @@ var CustomizableUIInternal = {
this.addListener(this);
this._defineBuiltInWidgets();
this.loadSavedState();
this._updateForNewVersion();
this._introduceNewBuiltinWidgets();
this._markObsoleteBuiltinButtonsSeen();
this.registerArea(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, {
@ -195,6 +195,7 @@ var CustomizableUIInternal = {
"urlbar-container",
"search-container",
"spring",
"downloads-button",
"library-button",
"sidebar-button",
];
@ -262,7 +263,7 @@ var CustomizableUIInternal = {
}
},
_updateForNewVersion() {
_introduceNewBuiltinWidgets() {
// We should still enter even if gSavedState.currentVersion >= kVersion
// because the per-widget pref facility is independent of versioning.
if (!gSavedState) {
@ -415,15 +416,6 @@ var CustomizableUIInternal = {
}
}
}
if (currentVersion < 11 && gSavedState && gSavedState.placements) {
for (let placements of Object.values(gSavedState.placements)) {
if (placements.includes("downloads-button")) {
placements.splice(placements.indexOf("downloads-button"), 1);
break;
}
}
}
},
/**

View File

@ -19,7 +19,7 @@ function test() {
"All future placements should be dealt with by now.");
let {CustomizableUIInternal, gFuturePlacements, gPalette} = CustomizableUIBSPass;
CustomizableUIInternal._updateForNewVersion();
CustomizableUIInternal._introduceNewBuiltinWidgets();
is(gFuturePlacements.size, 0,
"No change to future placements initially.");
@ -67,7 +67,7 @@ function test() {
}
// Then call the re-init routine so we re-add the builtin widgets
CustomizableUIInternal._updateForNewVersion();
CustomizableUIInternal._introduceNewBuiltinWidgets();
is(gFuturePlacements.size, 1,
"Should have 1 more future placement");
let haveNavbarPlacements = gFuturePlacements.has(CustomizableUI.AREA_NAVBAR);
@ -106,7 +106,7 @@ function test() {
"PanelUI-contents": ["panic-button", "edit-controls"],
},
};
CustomizableUIInternal._updateForNewVersion();
CustomizableUIInternal._introduceNewBuiltinWidgets();
let navbarPlacements = CustomizableUIBSPass.gSavedState.placements["nav-bar"];
let springs = navbarPlacements.filter(id => id.includes("spring"));
is(springs.length, 2, "Should have 2 toolbarsprings in placements now");

View File

@ -17,7 +17,7 @@ function test() {
CustomizableUIInternal.saveState();
CustomizableUIInternal.loadSavedState();
CustomizableUIInternal._updateForNewVersion();
CustomizableUIInternal._introduceNewBuiltinWidgets();
is(gFuturePlacements.size, 0,
"No change to future placements initially.");
@ -44,7 +44,7 @@ function test() {
let savedPlacements = CustomizableUIBSPass.gSavedState.placements[CustomizableUI.AREA_NAVBAR];
// Then call the re-init routine so we re-add the builtin widgets
CustomizableUIInternal._updateForNewVersion();
CustomizableUIInternal._introduceNewBuiltinWidgets();
is(gFuturePlacements.size, 1,
"Should have 1 more future placement");
let futureNavbarPlacements = gFuturePlacements.get(CustomizableUI.AREA_NAVBAR);

View File

@ -16,16 +16,16 @@ add_task(async function() {
skippedItem.setAttribute("skipintoolbarset", "true");
skippedItem.setAttribute("removable", "true");
navbar.customizationTarget.appendChild(skippedItem);
let libraryButton = document.getElementById("library-button");
let downloadsButton = document.getElementById("downloads-button");
await startCustomizing();
ok(CustomizableUI.inDefaultState, "Should still be in default state");
simulateItemDrag(skippedItem, libraryButton);
simulateItemDrag(skippedItem, downloadsButton);
ok(CustomizableUI.inDefaultState, "Should still be in default state");
let skippedItemWrapper = skippedItem.parentNode;
is(skippedItemWrapper.nextSibling && skippedItemWrapper.nextSibling.id,
libraryButton.parentNode.id, "Should be next to downloads button");
simulateItemDrag(libraryButton, skippedItem);
let downloadWrapper = libraryButton.parentNode;
downloadsButton.parentNode.id, "Should be next to downloads button");
simulateItemDrag(downloadsButton, skippedItem);
let downloadWrapper = downloadsButton.parentNode;
is(downloadWrapper.nextSibling && downloadWrapper.nextSibling.id,
skippedItem.parentNode.id, "Should be next to skipintoolbarset item");
ok(CustomizableUI.inDefaultState, "Should still be in default state");

View File

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

View File

@ -10,11 +10,11 @@ const kTestToolbarId = "test-empty-drag";
add_task(async function() {
await createToolbarWithPlacements(kTestToolbarId, []);
await startCustomizing();
let libraryButton = document.getElementById("library-button");
let downloadButton = document.getElementById("downloads-button");
let customToolbar = document.getElementById(kTestToolbarId);
simulateItemDrag(libraryButton, customToolbar);
assertAreaPlacements(kTestToolbarId, ["library-button"]);
ok(libraryButton.parentNode && libraryButton.parentNode.parentNode == customToolbar,
simulateItemDrag(downloadButton, customToolbar);
assertAreaPlacements(kTestToolbarId, ["downloads-button"]);
ok(downloadButton.parentNode && downloadButton.parentNode.parentNode == customToolbar,
"Button should really be in toolbar");
await endCustomizing();
removeCustomToolbars();

View File

@ -44,12 +44,12 @@ add_task(async function() {
// Drag an item and drop it onto the nav-bar customization target, but
// not over a particular item.
await startCustomizing();
let homeButton = document.getElementById("home-button");
simulateItemDrag(homeButton, navbar.customizationTarget);
let downloadsButton = document.getElementById("downloads-button");
simulateItemDrag(downloadsButton, navbar.customizationTarget);
await endCustomizing();
is(homeButton.previousSibling.id, lastVisible.id,
is(downloadsButton.previousSibling.id, lastVisible.id,
"The downloads button should be placed after the last visible item.");
await resetCustomization();

View File

@ -43,3 +43,28 @@ add_task(async function check_developer_subview_in_overflow() {
expectedPanel.hidePopup();
await Promise.resolve(); // wait for popup to hide fully.
});
/**
* This checks that non-subview-compatible items still work correctly.
* Ideally we should make the downloads panel and bookmarks/library item
* proper subview items, then this test can go away, and potentially we can
* simplify some of the subview anchoring code.
*/
add_task(async function check_downloads_panel_in_overflow() {
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
ok(navbar.hasAttribute("overflowing"), "Should still be overflowing");
let chevron = document.getElementById("nav-bar-overflow-button");
let shownPanelPromise = promisePanelElementShown(window, kOverflowPanel);
chevron.click();
await shownPanelPromise;
let button = document.getElementById("downloads-button");
button.click();
await waitForCondition(() => {
let panel = document.getElementById("downloadsPanel");
return panel && panel.state != "closed";
});
let downloadsPanel = document.getElementById("downloadsPanel");
isnot(downloadsPanel.state, "closed", "Should be attempting to show the downloads panel.");
downloadsPanel.hidePopup();
});

View File

@ -42,6 +42,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
PluralForm: "resource://gre/modules/PluralForm.jsm",
AppConstants: "resource://gre/modules/AppConstants.jsm",
AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.jsm",
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
DownloadHistory: "resource://gre/modules/DownloadHistory.jsm",
Downloads: "resource://gre/modules/Downloads.jsm",
DownloadUIHelper: "resource://gre/modules/DownloadUIHelper.jsm",
@ -1030,19 +1031,6 @@ const DownloadsViewPrototype = {
_updateView() {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
/**
* Computes aggregate values and propagates the changes to our views.
*/
_updateViews() {
// Do not update the status indicators during batch loads of download items.
if (this._loading) {
return;
}
this._refreshProperties();
this._views.forEach(this._updateView, this);
},
};
// DownloadsIndicatorData
@ -1156,6 +1144,31 @@ DownloadsIndicatorDataCtor.prototype = {
},
_attentionSuppressed: false,
/**
* Computes aggregate values and propagates the changes to our views.
*/
_updateViews() {
// Do not update the status indicators during batch loads of download items.
if (this._loading) {
return;
}
this._refreshProperties();
let widgetGroup = CustomizableUI.getWidget("downloads-button");
let inMenu = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
if (inMenu) {
if (this._attention == DownloadsCommon.ATTENTION_NONE) {
AppMenuNotifications.removeNotification(/^download-/);
} else {
let badgeClass = "download-" + this._attention;
AppMenuNotifications.showBadgeOnlyNotification(badgeClass);
}
}
this._views.forEach(this._updateView, this);
},
/**
* Updates the specified view with the current aggregate values.
*
@ -1315,6 +1328,19 @@ DownloadsSummaryData.prototype = {
// Propagation of properties to our views
/**
* Computes aggregate values and propagates the changes to our views.
*/
_updateViews() {
// Do not update the status indicators during batch loads of download items.
if (this._loading) {
return;
}
this._refreshProperties();
this._views.forEach(this._updateView, this);
},
/**
* Updates the specified view with the current aggregate values.
*

View File

@ -176,6 +176,13 @@ richlistitem.download button {
display: none;
}
/*** Downloads panel ***/
#downloadsPanel[hasdownloads] #emptyDownloads,
#downloadsPanel:not([hasdownloads]) #downloadsListBox {
display: none;
}
/*** Downloads panel multiview (main view and blocked-downloads subview) ***/
/* Hide all the usual buttons. */

View File

@ -702,8 +702,12 @@ var DownloadsView = {
let count = this._downloads.length;
let hiddenCount = count - this.kItemCountLimit;
if (count <= 0) {
DownloadsButton.hide();
if (count > 0) {
DownloadsCommon.log("Setting the panel's hasdownloads attribute to true.");
DownloadsPanel.panel.setAttribute("hasdownloads", "true");
} else {
DownloadsCommon.log("Removing the panel's hasdownloads attribute.");
DownloadsPanel.panel.removeAttribute("hasdownloads");
}
// If we've got some hidden downloads, we should activate the

View File

@ -117,6 +117,9 @@
onmouseout="DownloadsView.onDownloadMouseOut(event);"
oncontextmenu="DownloadsView.onDownloadContextMenu(event);"
ondragstart="DownloadsView.onDownloadDragStart(event);"/>
<description id="emptyDownloads"
mousethrough="always"
value="&downloadsPanelEmpty.label;"/>
</vbox>
<vbox id="downloadsFooter"
class="downloadsPanelFooter">

View File

@ -108,14 +108,35 @@ const DownloadsButton = {
indicator.open = this._anchorRequested;
// Determine if the indicator is located on an invisible toolbar.
if (!window.toolbar.visible) {
return null;
}
let widget = CustomizableUI.getWidget("downloads-button")
.forWindow(window);
// Determine if the indicator is located on an invisible toolbar.
if (!isElementVisible(indicator.parentNode) && !widget.overflowed) {
return null;
}
return DownloadsIndicatorView.indicatorAnchor;
},
/**
* Checks whether the indicator is, or will soon be visible in the browser
* window.
*
* @param aCallback
* Called once the indicator overlay has loaded. Gets a boolean
* argument representing the indicator visibility.
*/
checkIsVisible(aCallback) {
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay, () => {
if (!this._placeholder) {
aCallback(false);
} else {
let element = DownloadsIndicatorView.indicator || this._placeholder;
aCallback(isElementVisible(element.parentNode));
}
});
},
/**
* Indicates whether we should try and show the indicator temporarily as an
* anchor for the panel, even if the indicator would be hidden by default.
@ -143,36 +164,6 @@ const DownloadsButton = {
});
},
unhideAndPlace() {
if (this._placeholder.hasAttribute("hidden")) {
this._navBar.setAttribute("hasdownloads", "true");
this._placeholder.removeAttribute("hidden");
let insertionPoint = document.getElementById("urlbar-container");
while (insertionPoint && insertionPoint.nextElementSibling) {
let next = insertionPoint.nextElementSibling;
if (!next.hidden &&
(next.nodeName == "toolbarspring" ||
next.id == "downloads-button" || /* also have to ignore ourselves... */
next.id == "search-container" ||
next.id == "urlbar-search-splitter")) {
insertionPoint = next;
} else {
break;
}
}
if (insertionPoint && insertionPoint.nextElementSibling != this._placeholder &&
insertionPoint.nextElementSibling != this._placeholder.nextElementSibling) {
insertionPoint.insertAdjacentElement("afterend", this._placeholder);
}
}
},
hide() {
DownloadsPanel.hidePanel();
this._navBar.removeAttribute("hasdownloads");
this._placeholder.setAttribute("hidden", "true");
},
/**
* Allows the temporary anchor to be hidden.
*/
@ -261,6 +252,12 @@ const DownloadsIndicatorView = {
return;
}
// If we don't have a _placeholder, there's no chance that the overlay
// will load correctly: bail (and don't set _operational to true!)
if (!DownloadsButton._placeholder) {
return;
}
DownloadsOverlayLoader.ensureOverlayLoaded(
DownloadsButton.kIndicatorOverlay,
() => {
@ -342,7 +339,21 @@ const DownloadsIndicatorView = {
return;
}
if (!window.toolbar.visible) {
let anchor = DownloadsButton._placeholder;
let widgetGroup = CustomizableUI.getWidget("downloads-button");
let widget = widgetGroup.forWindow(window);
if (widget.overflowed || widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL) {
if (anchor && this._isAncestorPanelOpen(anchor)) {
// If the containing panel is open, don't do anything, because the
// notification would appear under the open panel. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=984023
return;
}
// Otherwise, try to use the anchor of the panel:
anchor = widget.anchor;
}
if (!anchor || !isElementVisible(anchor.parentNode)) {
// Our container isn't visible, so can't show the animation:
return;
}
@ -354,7 +365,6 @@ const DownloadsIndicatorView = {
// container.
// Note: no notifier animation for download finished in Photon
let notifier = this.notifier;
let anchor = DownloadsButton._placeholder;
if (aType == "start") {
// Show the notifier before measuring for size/placement. Being hidden by default
@ -413,9 +423,7 @@ const DownloadsIndicatorView = {
this._hasDownloads = aValue;
// If there is at least one download, ensure that the view elements are
// operational
if (aValue) {
DownloadsButton.unhideAndPlace();
this._ensureOperational();
}
}
@ -437,6 +445,7 @@ const DownloadsIndicatorView = {
if (this._percentComplete !== aValue) {
this._percentComplete = aValue;
this._refreshAttention();
if (this._percentComplete >= 0) {
this.indicator.setAttribute("progress", "true");
@ -462,14 +471,29 @@ const DownloadsIndicatorView = {
}
if (this._attention != aValue) {
this._attention = aValue;
if (this._attention == DownloadsCommon.ATTENTION_NONE) {
this.indicator.removeAttribute("attention");
} else {
this.indicator.setAttribute("attention", this._attention);
}
this._refreshAttention();
}
return this._attention;
},
_refreshAttention() {
// Check if the downloads button is in the menu panel, to determine which
// button needs to get a badge.
let widgetGroup = CustomizableUI.getWidget("downloads-button");
let inMenu = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
// For arrow-Styled indicator, suppress success attention if we have
// progress in toolbar
let suppressAttention = !inMenu &&
this._attention == DownloadsCommon.ATTENTION_SUCCESS &&
this._percentComplete >= 0;
if (suppressAttention || this._attention == DownloadsCommon.ATTENTION_NONE) {
this.indicator.removeAttribute("attention");
} else {
this.indicator.setAttribute("attention", this._attention);
}
},
_attention: DownloadsCommon.ATTENTION_NONE,
// User interface event functions
@ -480,7 +504,14 @@ const DownloadsIndicatorView = {
},
onCommand(aEvent) {
DownloadsPanel.showPanel();
// If the downloads button is in the menu panel, open the Library
let widgetGroup = CustomizableUI.getWidget("downloads-button");
if (widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL) {
DownloadsPanel.showDownloadsHistory();
} else {
DownloadsPanel.showPanel();
}
aEvent.stopPropagation();
},
@ -532,6 +563,11 @@ const DownloadsIndicatorView = {
},
get indicatorAnchor() {
let widget = CustomizableUI.getWidget("downloads-button")
.forWindow(window);
if (widget.overflowed) {
return widget.anchor;
}
return document.getElementById("downloads-indicator-anchor");
},

View File

@ -4,6 +4,8 @@ support-files = head.js
[browser_basic_functionality.js]
[browser_first_download_panel.js]
skip-if = os == "linux" # Bug 949434
[browser_overflow_anchor.js]
skip-if = os == "linux" # Bug 952422
[browser_confirm_unblock_download.js]
[browser_iframe_gone_mid_download.js]
[browser_indicatorDrop.js]

View File

@ -10,23 +10,16 @@
*/
add_task(async function test_height_reduced_after_removal() {
await task_addDownloads([
{ state: DownloadsCommon.DOWNLOAD_PAUSED },
{ state: DownloadsCommon.DOWNLOAD_FINISHED },
]);
await BrowserTestUtils.waitForCondition(() => {
let btn = document.getElementById("downloads-button");
return !btn.hidden && btn.getBoundingClientRect().width > 0;
});
await task_openPanel();
let panel = document.getElementById("downloadsPanel");
let heightBeforeRemoval = panel.getBoundingClientRect().height;
// We want to close the panel before we remove a download from the list.
// We want to close the panel before we remove the download from the list.
DownloadsPanel.hidePanel();
let publicList = await Downloads.getList(Downloads.PUBLIC);
await publicList.removeFinished();
await task_resetState();
await task_openPanel();
let heightAfterRemoval = panel.getBoundingClientRect().height;

View File

@ -32,9 +32,7 @@ add_task(async function test_first_download_panel() {
// time a download is started.
DownloadsCommon.getData(window).panelHasShownBefore = false;
info("waiting for panel open");
let promise = promisePanelOpened();
await task_addDownloads([{state: DownloadsCommon.DOWNLOAD_DOWNLOADING}]);
DownloadsCommon.getData(window)._notifyDownloadEvent("start");
await promise;

View File

@ -0,0 +1,114 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
registerCleanupFunction(async function() {
// Clean up when the test finishes.
await task_resetState();
});
/**
* Make sure the downloads button and indicator overflows into the nav-bar
* chevron properly, and then when those buttons are clicked in the overflow
* panel that the downloads panel anchors to the chevron.
*/
add_task(async function test_overflow_anchor() {
// Ensure that state is reset in case previous tests didn't finish.
await task_resetState();
// Record the original width of the window so we can put it back when
// this test finishes.
let oldWidth = window.outerWidth;
// The downloads button should not be overflowed to begin with.
let button = CustomizableUI.getWidget("downloads-button")
.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"];
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);
await waitForOverflowed(button, true);
let promise = promisePanelOpened();
button.node.doCommand();
await promise;
let panel = DownloadsPanel.panel;
let chevron = document.getElementById("nav-bar-overflow-button");
is(panel.anchorNode, chevron, "Panel should be anchored to the chevron.");
DownloadsPanel.hidePanel();
// Unlock the widths on the flex-y items.
unlockWidth(kFlexyItems);
// Put the window back to its original dimensions.
window.resizeTo(oldWidth, window.outerHeight);
// The downloads button should eventually be un-overflowed.
await waitForOverflowed(button, false);
// Now try opening the panel again.
promise = promisePanelOpened();
button.node.doCommand();
await promise;
is(panel.anchorNode.id, "downloads-indicator-anchor");
DownloadsPanel.hidePanel();
});
/**
* For some node IDs, finds the nodes and sets their min-width's to their
* current width, preventing them from flex-shrinking.
*
* @param aItemIDs an array of item IDs to set min-width on.
*/
function lockWidth(aItemIDs) {
for (let itemID of aItemIDs) {
let item = document.getElementById(itemID);
let curWidth = item.getBoundingClientRect().width + "px";
item.style.minWidth = curWidth;
}
}
/**
* Clears the min-width's set on a set of IDs by lockWidth.
*
* @param aItemIDs an array of ItemIDs to remove min-width on.
*/
function unlockWidth(aItemIDs) {
for (let itemID of aItemIDs) {
let item = document.getElementById(itemID);
item.style.minWidth = "";
}
}
/**
* Waits for a node to enter or exit the overflowed state.
*
* @param aItem the node to wait for.
* @param aIsOverflowed if we're waiting for the item to be overflowed.
*/
function waitForOverflowed(aItem, aIsOverflowed) {
if (aItem.overflowed == aIsOverflowed) {
return Promise.resolve();
}
return new Promise(resolve => {
let observer = new MutationObserver(function(aMutations) {
if (aItem.overflowed == aIsOverflowed) {
observer.disconnect();
resolve();
}
});
observer.observe(aItem.node, {attributes: true});
});
}

View File

@ -23,9 +23,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
registerCleanupFunction(function() {
gTestTargetFile.remove(false);
});
// The file may have been already deleted when removing a paused download.
registerCleanupFunction(() => OS.File.remove(gTestTargetFile.path,
{ ignoreAbsent: true }));
// Asynchronous support subroutines

View File

@ -72,6 +72,14 @@
["devtools", "panels"]
]
},
"find": {
"url": "chrome://browser/content/ext-find.js",
"schema": "chrome://browser/content/schemas/find.json",
"scopes": ["addon_parent"],
"paths": [
["find"]
]
},
"history": {
"url": "chrome://browser/content/ext-history.js",
"schema": "chrome://browser/content/schemas/history.json",

View File

@ -0,0 +1,106 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* global tabTracker */
"use strict";
/**
* runFindOperation
* Utility for `find` and `highlightResults`.
*
* @param {object} params - params to pass to message sender.
* @param {string} message - identifying component of message name.
*
* @returns {Promise} a promise that will be resolved or rejected based on the
* data received by the message listener.
*/
function runFindOperation(params, message) {
let {tabId} = params;
let tab = tabId ? tabTracker.getTab(tabId) : tabTracker.activeTab;
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
tabId = tabId || tabTracker.getId(tab);
return new Promise((resolve, reject) => {
mm.addMessageListener(`ext-Finder:${message}Finished`, function messageListener(message) {
mm.removeMessageListener(`ext-Finder:${message}Finished`, messageListener);
switch (message.data) {
case "Success":
resolve();
break;
case "OutOfRange":
reject({message: "index supplied was out of range"});
break;
case "NoResults":
reject({message: "no search results to highlight"});
break;
}
resolve(message.data);
});
mm.sendAsyncMessage(`ext-Finder:${message}`, params);
});
}
this.find = class extends ExtensionAPI {
getAPI(context) {
return {
find: {
/**
* browser.find.find
* Searches document and its frames for a given queryphrase and stores all found
* Range objects in an array accessible by other browser.find methods.
*
* @param {string} queryphrase - The string to search for.
* @param {object} params optional - may contain any of the following properties,
* all of which are optional:
* {number} tabId - Tab to query. Defaults to the active tab.
* {boolean} caseSensitive - Highlight only ranges with case sensitive match.
* {boolean} entireWord - Highlight only ranges that match entire word.
* {boolean} includeRangeData - Whether to return range data.
* {boolean} includeRectData - Whether to return rectangle data.
*
* @returns {object} data received by the message listener that includes:
* {number} count - number of results found.
* {array} rangeData (if opted) - serialized representation of ranges found.
* {array} rectData (if opted) - rect data of ranges found.
*/
find(queryphrase, params) {
params = params || {};
params.queryphrase = queryphrase;
return runFindOperation(params, "CollectResults");
},
/**
* browser.find.highlightResults
* Highlights range(s) found in previous browser.find.find.
*
* @param {object} params optional - may contain any of the following properties,
* all of which are optional:
* {number} rangeIndex - Found range to be highlighted. Default highlights all ranges.
* {number} tabId - Tab to highlight. Defaults to the active tab.
* {boolean} noScroll - Don't scroll to highlighted item.
*
* @returns {string} - data received by the message listener that may be:
* "Success" - Highlighting succeeded.
* "OutOfRange" - The index supplied was out of range.
* "NoResults" - There were no search results to highlight.
*/
highlightResults(params) {
params = params || {};
return runFindOperation(params, "HighlightResults");
},
/**
* browser.find.removeHighlighting
* Removes all hightlighting from previous search.
*
* @param {number} tabId optional
* Tab to clear highlighting in. Defaults to the active tab.
*/
removeHighlighting(tabId) {
let tab = tabId ? tabTracker.getTab(tabId) : tabTracker.activeTab;
tab.linkedBrowser.messageManager.sendAsyncMessage("ext-Finder:clearHighlighting");
},
},
};
}
};

View File

@ -23,6 +23,7 @@ browser.jar:
content/browser/ext-devtools-inspectedWindow.js
content/browser/ext-devtools-network.js
content/browser/ext-devtools-panels.js
content/browser/ext-find.js
content/browser/ext-geckoProfiler.js
content/browser/ext-history.js
content/browser/ext-menus.js

View File

@ -0,0 +1,121 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
{
"namespace": "manifest",
"types": [
{
"$extend": "OptionalPermission",
"choices": [{
"type": "string",
"enum": [
"find"
]
}]
}
]
},
{
"namespace": "find",
"description": "Use the <code>browser.find</code> API to interact with the browser's <code>Find</code> interface.",
"permissions": ["find"],
"functions": [
{
"name": "find",
"type": "function",
"async": true,
"description": "Search for text in document and store found ranges in array, in document order.",
"parameters": [
{
"name": "queryphrase",
"type": "string",
"description": "The string to search for."
},
{
"name": "params",
"type": "object",
"description": "Search parameters.",
"optional": true,
"properties": {
"tabId": {
"type": "integer",
"description": "Tab to query. Defaults to the active tab.",
"optional": true,
"minimum": 0
},
"caseSensitive": {
"type": "boolean",
"description": "Find only ranges with case sensitive match.",
"optional": true
},
"entireWord": {
"type": "boolean",
"description": "Find only ranges that match entire word.",
"optional": true
},
"includeRectData": {
"description": "Return rectangle data which describes visual position of search results.",
"type": "boolean",
"optional": true
},
"includeRangeData": {
"description": "Return range data which provides range data in a serializable form.",
"type": "boolean",
"optional": true
}
}
}
]
},
{
"name": "highlightResults",
"type": "function",
"async": true,
"description": "Highlight a range",
"parameters": [
{
"name": "params",
"type": "object",
"description": "highlightResults parameters",
"optional": true,
"properties": {
"rangeIndex": {
"type": "integer",
"description": "Found range to be highlighted. Default highlights all ranges.",
"minimum": 0,
"optional": true
},
"tabId": {
"type": "integer",
"description": "Tab to highlight. Defaults to the active tab.",
"minimum": 0,
"optional": true
},
"noScroll": {
"type": "boolean",
"description": "Don't scroll to highlighted item.",
"optional": true
}
}
}
]
},
{
"name": "removeHighlighting",
"type": "function",
"async": true,
"description": "Remove all highlighting from previous searches.",
"parameters": [
{
"name": "tabId",
"type": "integer",
"description": "Tab to highlight. Defaults to the active tab.",
"optional": true
}
]
}
]
}
]

View File

@ -12,6 +12,7 @@ browser.jar:
content/browser/schemas/devtools_inspected_window.json
content/browser/schemas/devtools_network.json
content/browser/schemas/devtools_panels.json
content/browser/schemas/find.json
content/browser/schemas/geckoProfiler.json
content/browser/schemas/history.json
content/browser/schemas/menus.json

View File

@ -10,6 +10,7 @@ support-files =
context_tabs_onUpdated_page.html
context_tabs_onUpdated_iframe.html
file_clearplugindata.html
file_find_frames.html
file_popup_api_injection_a.html
file_popup_api_injection_b.html
file_iframe_document.html
@ -73,6 +74,7 @@ skip-if = (os == 'win' && !debug) # bug 1352668
[browser_ext_devtools_page.js]
[browser_ext_devtools_panel.js]
[browser_ext_devtools_panels_elements.js]
[browser_ext_find.js]
[browser_ext_geckoProfiler_symbolicate.js]
[browser_ext_getViews.js]
[browser_ext_identity_indication.js]

View File

@ -0,0 +1,138 @@
/* global browser */
"use strict";
function frameScript() {
function getSelectedText() {
let frame = this.content.frames[0].frames[1];
let Ci = Components.interfaces;
let docShell = frame.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let selection = controller.getSelection(controller.SELECTION_FIND);
let range = selection.getRangeAt(0);
let r1 = frame.parent.frameElement.getBoundingClientRect();
let r2 = frame.frameElement.getBoundingClientRect();
let r3 = range.getBoundingClientRect();
let rect = {top: (r1.top + r2.top + r3.top), left: (r1.left + r2.left + r3.left)};
this.sendAsyncMessage("test:find:selectionTest", {text: selection.toString(), rect});
}
getSelectedText();
}
function waitForMessage(messageManager, topic) {
return new Promise(resolve => {
messageManager.addMessageListener(topic, function messageListener(message) {
messageManager.removeMessageListener(topic, messageListener);
resolve(message);
});
});
}
add_task(async function testDuplicatePinnedTab() {
async function background() {
function awaitLoad(tabId) {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
if (tabId == tabId_ && changed.status == "complete") {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
});
});
}
let url = "http://example.com/browser/browser/components/extensions/test/browser/file_find_frames.html";
let tab = await browser.tabs.update({url});
await awaitLoad(tab.id);
let data = await browser.find.find("banana", {includeRangeData: true});
let rangeData = data.rangeData;
browser.test.log("Test that `data.count` is the expected value.");
browser.test.assertEq(6, data.count, "The value returned from `data.count`");
browser.test.log("Test that `rangeData` has the proper number of values.");
browser.test.assertEq(6, rangeData.length, "The number of values held in `rangeData`");
browser.test.log("Test that the text found in the top window and nested frames corresponds to the proper position.");
let terms = ["Banana", "bAnana", "baNana", "banAna", "banaNa", "bananA"];
for (let i = 0; i < terms.length; i++) {
browser.test.assertEq(terms[i], rangeData[i].text, `The text at range position ${i}:`);
}
browser.test.log("Test that case sensitive match works properly.");
data = await browser.find.find("baNana", {caseSensitive: true, includeRangeData: true});
browser.test.assertEq(1, data.count, "The number of matches found:");
browser.test.assertEq("baNana", data.rangeData[0].text, "The text found:");
browser.test.log("Test that case insensitive match works properly.");
data = await browser.find.find("banana", {caseSensitive: false});
browser.test.assertEq(6, data.count, "The number of matches found:");
browser.test.log("Test that entire word match works properly.");
data = await browser.find.find("banana", {entireWord: true});
browser.test.assertEq(4, data.count, "The number of matches found, should skip 2 matches, \"banaNaland\" and \"bananAland\":");
browser.test.log("Test that `rangeData` is not returned if `includeRangeData` is false.");
data = await browser.find.find("banana", {caseSensitive: false, includeRangeData: false});
browser.test.assertEq(false, !!data.rangeData, "The boolean cast value of `rangeData`:");
browser.test.log("Test that `rectData` is not returned if `includeRectData` is false.");
data = await browser.find.find("banana", {caseSensitive: false, includeRectData: false});
browser.test.assertEq(false, !!data.rectData, "The boolean cast value of `rectData`:");
browser.test.log("Test that text spanning multiple inline elements is found.");
data = await browser.find.find("fruitcake");
browser.test.assertEq(1, data.count, "The number of matches found:");
browser.test.log("Test that text spanning multiple block elements is not found.");
data = await browser.find.find("angelfood");
browser.test.assertEq(0, data.count, "The number of matches found:");
browser.test.log("Test that `highlightResults` returns proper status code.");
await browser.find.find("banana");
await browser.test.assertRejects(browser.find.highlightResults({rangeIndex: 6}),
/index supplied was out of range/,
"rejected Promise should pass the expected error");
data = await browser.find.find("xyz");
await browser.test.assertRejects(browser.find.highlightResults({rangeIndex: 0}),
/no search results to highlight/,
"rejected Promise should pass the expected error");
data = await browser.find.find("banana", {includeRectData: true});
await browser.find.highlightResults({rangeIndex: 5});
browser.test.sendMessage("test:find:WebExtensionFinished", data.rectData);
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["find", "tabs"],
},
background,
});
await extension.startup();
let rectData = await extension.awaitMessage("test:find:WebExtensionFinished");
let {top, left} = rectData[5].rectsAndTexts.rectList[0];
await extension.unload();
let {selectedBrowser} = gBrowser;
let frameScriptUrl = `data:,(${frameScript})()`;
selectedBrowser.messageManager.loadFrameScript(frameScriptUrl, false);
let message = await waitForMessage(selectedBrowser.messageManager, "test:find:selectionTest");
info("Test that text was highlighted properly.");
is(message.data.text, "bananA", `The text that was highlighted: - Expected: bananA, Actual: ${message.data.text}`);
info("Test that rectangle data returned from the search matches the highlighted result.");
is(message.data.rect.top, top, `rect.top: - Expected: ${message.data.rect.top}, Actual: ${top}`);
is(message.data.rect.left, left, `rect.left: - Expected: ${message.data.rect.left}, Actual: ${left}`);
});

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<body>
<p>Banana 0</p>
<iframe src="data:text/html,<p>baNana 2</p>
<iframe src='data:text/html,banaNaland 4' height='50' width='100%'></iframe>
<iframe src='data:text/html,bananAland 5' height='50' width='100%'></iframe>
<p>banAna 3</p>" height="250" width="100%"></iframe>
<p>bAnana 1</p>
<p><b>fru</b>it<i><b>ca</b>ke</i></p>
<p>ang<div>elf</div>ood</p>
</body>
</html>

View File

@ -4,6 +4,12 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("distribution.js"):
BUG_COMPONENT = ("Firefox", "Distributions")
with Files("tests/**"):
BUG_COMPONENT = ("Firefox", "General")

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "Activity Streams: General")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Toolkit", "Application Update")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Plug-ins")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "DOM: Content Processes")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Networking")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Plug-ins")
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']

View File

@ -22,10 +22,15 @@ DIRS += [
if not CONFIG['RELEASE_OR_BETA']:
DIRS += [
'flyweb',
'formautofill',
'presentation',
]
# formautofill will be rolled out via balrog in release
if CONFIG['MOZ_UPDATE_CHANNEL'] != 'release':
DIRS += [
'formautofill',
]
# Only include the following system add-ons if building DevEdition or Nightly
if CONFIG['MOZ_DEV_EDITION'] or CONFIG['NIGHTLY_BUILD']:
DIRS += [

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "Tours")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -1,3 +1,6 @@
with Files("**"):
BUG_COMPONENT = ("Firefox", "Device Permissions")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Cloud Services", "Screenshots")
FINAL_TARGET_FILES.features['screenshots@mozilla.org'] += [
'bootstrap.js',
'install.rdf'

View File

@ -4,6 +4,9 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Shield", "Add-on")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View File

@ -78,18 +78,6 @@
@DIR_MACOS@updates/*
#endif
# bug 1391079 - remove this block before 57 uplift to beta
#ifdef XP_MACOSX
@DIR_MACOS@._firefox-bin.sig
@DIR_MACOS@._firefox.sig
@DIR_MACOS@._XUL.sig
@DIR_MACOS@firefox-bin.sig
@DIR_MACOS@firefox.sig
@DIR_MACOS@plugin-container.app/Contents/MacOS/._plugin-container.sig
@DIR_MACOS@plugin-container.app/Contents/MacOS/plugin-container.sig
@DIR_MACOS@XUL.sig
#endif
# Common Directory removals
@DIR_MACOS@chrome/
#ifdef XP_UNIX

View File

@ -79,7 +79,7 @@ libs-%:
@$(MAKE) -C ../../toolkit/locales libs-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$*
ifndef RELEASE_OR_BETA
ifneq (,$(wildcard ../extensions/formautofill/locales))
@$(MAKE) -C ../extensions/formautofill/locales AB_CD=$* XPI_NAME=locale-$*
endif
@$(MAKE) -C ../extensions/onboarding/locales AB_CD=$* XPI_NAME=locale-$*
@ -104,7 +104,7 @@ chrome-%:
@$(MAKE) -C ../../toolkit/locales chrome-$*
@$(MAKE) -C ../../services/sync/locales chrome AB_CD=$*
@$(MAKE) -C ../../extensions/spellcheck/locales chrome AB_CD=$*
ifndef RELEASE_OR_BETA
ifneq (,$(wildcard ../extensions/formautofill/locales))
@$(MAKE) -C ../extensions/formautofill/locales chrome AB_CD=$*
endif
@$(MAKE) -C ../extensions/pocket/locale chrome AB_CD=$*

View File

@ -100,6 +100,7 @@ webextPerms.description.browserSettings=Read and modify browser settings
webextPerms.description.clipboardRead=Get data from the clipboard
webextPerms.description.clipboardWrite=Input data to the clipboard
webextPerms.description.downloads=Download files and read and modify the browsers download history
webextPerms.description.find=Read the Web page text of all open tabs
webextPerms.description.geolocation=Access your location
webextPerms.description.history=Access browsing history
webextPerms.description.management=Monitor extension usage and manage themes

View File

@ -149,6 +149,11 @@
-->
<!ENTITY downloadsListEmpty.label "There are no downloads.">
<!-- LOCALIZATION NOTE (downloadsPanelEmpty.label):
This string is shown when there are no items in the Downloads Panel.
-->
<!ENTITY downloadsPanelEmpty.label "No downloads for this session.">
<!-- LOCALIZATION NOTE (downloadsListNoMatch.label):
This string is shown when some search terms are specified, but there are no
results in the Downloads view.

View File

@ -4,4 +4,22 @@
# 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/.
JAR_MANIFESTS += ['jar.mn']
JAR_MANIFESTS += ['jar.mn']
with Files("**"):
BUG_COMPONENT = ("Toolkit", "Build Config")
with Files("all-locales"):
BUG_COMPONENT = ("Core", "Localization")
with Files("en-US/**"):
BUG_COMPONENT = ("Core", "Localization")
with Files("search/**"):
BUG_COMPONENT = ("Firefox", "Search")
with Files("searchplugins/**"):
BUG_COMPONENT = ("Firefox", "Search")
with Files("shipped-locales"):
BUG_COMPONENT = ("Core", "Localization")

View File

@ -39,3 +39,51 @@ if CONFIG['MOZ_ARTIFACT_BUILDS']:
EXTRA_COMPONENTS += [
'../build/prebuilt-interfaces.manifest',
]
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("Makefile.in"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("*.mk"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("**/moz.build"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("moz.configure"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("app.mozbuild"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("moz.build"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("confvars.sh"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("LICENSE"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("branding/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("config/**"):
BUG_COMPONENT = ("Core", "Build Config")
with Files("docs/**"):
BUG_COMPONENT = ("Toolkit", "Telemetry")
with Files("docs/DirectoryLinksProvider.rst"):
BUG_COMPONENT = ("Firefox", "New Tab Page")
with Files("fonts/**"):
BUG_COMPONENT = ("Core", "Graphics: Text")
with Files("installer/**"):
BUG_COMPONENT = ("Firefox", "Installer")
with Files("tools/**"):
BUG_COMPONENT = ("Firefox", "General")

View File

@ -179,11 +179,8 @@ AC_SUBST_LIST(NSPR_CFLAGS)
AC_SUBST(NSPR_INCLUDE_DIR)
AC_SUBST(NSPR_LIB_DIR)
NSPR_PKGCONF_CHECK="nspr"
PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr"
if test -n "$MOZ_SYSTEM_NSPR"; then
# piggy back on $MOZ_SYSTEM_NSPR to set a variable for the nspr check for js.pc
NSPR_PKGCONF_CHECK="nspr >= $NSPR_MINVER"
_SAVE_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $NSPR_CFLAGS"
AC_TRY_COMPILE([#include "prlog.h"],
@ -193,8 +190,12 @@ if test -n "$MOZ_SYSTEM_NSPR"; then
,
AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT]))
CFLAGS=$_SAVE_CFLAGS
# piggy back on $MOZ_SYSTEM_NSPR to set a variable for the nspr check for js.pc
PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr >= $NSPR_MINVER"
elif test -n "$JS_POSIX_NSPR"; then
PKGCONF_REQUIRES_PRIVATE=
fi
AC_SUBST(NSPR_PKGCONF_CHECK)
AC_SUBST([PKGCONF_REQUIRES_PRIVATE])
fi # _IS_OUTER_CONFIGURE

View File

@ -448,7 +448,7 @@ skip-if = true # bug 1368569
[browser_dbg_worker-console-02.js]
skip-if = e10s && debug
[browser_dbg_worker-console-03.js]
skip-if = e10s && debug
skip-if = debug # bug 1334683
[browser_dbg_worker-console-04.js]
skip-if = e10s && debug
[browser_dbg_worker-source-map.js]

View File

@ -13,7 +13,7 @@ const SwatchBasedEditorTooltip = require("devtools/client/shared/widgets/tooltip
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/inspector.properties");
const Heritage = require("sdk/core/heritage");
const {extend} = require("devtools/shared/extend");
const colorWidgetPref = "devtools.inspector.colorWidget.enabled";
const NEW_COLOR_WIDGET = Services.prefs.getBoolPref(colorWidgetPref);
@ -50,7 +50,7 @@ function SwatchColorPickerTooltip(document,
this.cssColor4 = supportsCssColor4ColorFunction();
}
SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
SwatchColorPickerTooltip.prototype = extend(SwatchBasedEditorTooltip.prototype, {
/**
* Fill the tooltip with a new instance of the spectrum color picker widget
* initialized with the given color, and return the instance of spectrum

View File

@ -9,7 +9,7 @@ const {Task} = require("devtools/shared/task");
const {CubicBezierWidget} = require("devtools/client/shared/widgets/CubicBezierWidget");
const SwatchBasedEditorTooltip = require("devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip");
const Heritage = require("sdk/core/heritage");
const {extend} = require("devtools/shared/extend");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
@ -34,7 +34,7 @@ function SwatchCubicBezierTooltip(document) {
this._onUpdate = this._onUpdate.bind(this);
}
SwatchCubicBezierTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
SwatchCubicBezierTooltip.prototype = extend(SwatchBasedEditorTooltip.prototype, {
/**
* Fill the tooltip with a new instance of the cubic-bezier widget
* initialized with the given value, and return a promise that resolves to

View File

@ -8,7 +8,7 @@ const {Task} = require("devtools/shared/task");
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const SwatchBasedEditorTooltip = require("devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip");
const Heritage = require("sdk/core/heritage");
const {extend} = require("devtools/shared/extend");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
@ -36,7 +36,7 @@ function SwatchFilterTooltip(document, cssIsValid) {
this._onUpdate = this._onUpdate.bind(this);
}
SwatchFilterTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
SwatchFilterTooltip.prototype = extend(SwatchBasedEditorTooltip.prototype, {
/**
* Fill the tooltip with a new instance of the CSSFilterEditorWidget
* widget initialized with the given filter value, and return a promise

View File

@ -74,7 +74,7 @@ struct DevTools : public ::testing::Test {
static const JSClassOps globalClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr,
JS_GlobalObjectTraceHook
};
static const JSClass globalClass = {

View File

@ -4176,10 +4176,9 @@ Element::SetCustomElementData(CustomElementData* aData)
MOZ_DEFINE_MALLOC_SIZE_OF(ServoElementMallocSizeOf)
void
Element::AddSizeOfExcludingThis(SizeOfState& aState, nsStyleSizes& aSizes,
size_t* aNodeSize) const
Element::AddSizeOfExcludingThis(nsWindowSizes& aSizes, size_t* aNodeSize) const
{
FragmentOrElement::AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
FragmentOrElement::AddSizeOfExcludingThis(aSizes, aNodeSize);
if (HasServoData()) {
// Measure mServoData, excluding the ComputedValues. This measurement
@ -4188,23 +4187,23 @@ Element::AddSizeOfExcludingThis(SizeOfState& aState, nsStyleSizes& aSizes,
// output the memory measured within Servo code.
*aNodeSize +=
Servo_Element_SizeOfExcludingThisAndCVs(ServoElementMallocSizeOf,
&aState.mSeenPtrs, this);
&aSizes.mState.mSeenPtrs, this);
// Now measure just the ComputedValues (and style structs) under
// mServoData. This counts towards the relevant fields in |aSizes|.
RefPtr<ServoStyleContext> sc;
if (Servo_Element_HasPrimaryComputedValues(this)) {
sc = Servo_Element_GetPrimaryComputedValues(this).Consume();
if (!aState.HaveSeenPtr(sc.get())) {
sc->AddSizeOfIncludingThis(aState, aSizes, &aSizes.mComputedValuesDom);
if (!aSizes.mState.HaveSeenPtr(sc.get())) {
sc->AddSizeOfIncludingThis(aSizes, &aSizes.mLayoutComputedValuesDom);
}
for (size_t i = 0; i < nsCSSPseudoElements::kEagerPseudoCount; i++) {
if (Servo_Element_HasPseudoComputedValues(this, i)) {
sc = Servo_Element_GetPseudoComputedValues(this, i).Consume();
if (!aState.HaveSeenPtr(sc.get())) {
sc->AddSizeOfIncludingThis(aState, aSizes,
&aSizes.mComputedValuesDom);
if (!aSizes.mState.HaveSeenPtr(sc.get())) {
sc->AddSizeOfIncludingThis(aSizes,
&aSizes.mLayoutComputedValuesDom);
}
}
}

View File

@ -693,18 +693,19 @@ NS_IMPL_ISUPPORTS(nsNodeWeakReference,
nsNodeWeakReference::~nsNodeWeakReference()
{
if (mNode) {
NS_ASSERTION(mNode->Slots()->mWeakReference == this,
nsINode* node = static_cast<nsINode*>(mObject);
if (node) {
NS_ASSERTION(node->Slots()->mWeakReference == this,
"Weak reference has wrong value");
mNode->Slots()->mWeakReference = nullptr;
node->Slots()->mWeakReference = nullptr;
}
}
NS_IMETHODIMP
nsNodeWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr)
nsNodeWeakReference::QueryReferentFromScript(const nsIID& aIID, void** aInstancePtr)
{
return mNode ? mNode->QueryInterface(aIID, aInstancePtr) :
NS_ERROR_NULL_POINTER;
return QueryReferent(aIID, aInstancePtr);
}
size_t
@ -2576,16 +2577,16 @@ FragmentOrElement::FireNodeRemovedForChildren()
}
void
FragmentOrElement::AddSizeOfExcludingThis(SizeOfState& aState,
nsStyleSizes& aSizes,
FragmentOrElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const
{
nsIContent::AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
*aNodeSize += mAttrsAndChildren.SizeOfExcludingThis(aState.mMallocSizeOf);
nsIContent::AddSizeOfExcludingThis(aSizes, aNodeSize);
*aNodeSize +=
mAttrsAndChildren.SizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
nsDOMSlots* slots = GetExistingDOMSlots();
if (slots) {
*aNodeSize += slots->SizeOfIncludingThis(aState.mMallocSizeOf);
*aNodeSize += slots->SizeOfIncludingThis(aSizes.mState.mMallocSizeOf);
}
}

View File

@ -53,7 +53,7 @@ class nsNodeWeakReference final : public nsIWeakReference
{
public:
explicit nsNodeWeakReference(nsINode* aNode)
: mNode(aNode)
: nsIWeakReference(aNode)
{
}
@ -63,17 +63,14 @@ public:
// nsIWeakReference
NS_DECL_NSIWEAKREFERENCE
virtual size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
virtual bool IsAlive() const override { return mNode != nullptr; }
void NoticeNodeDestruction()
{
mNode = nullptr;
mObject = nullptr;
}
private:
~nsNodeWeakReference();
nsINode* MOZ_NON_OWNING_REF mNode;
};
/**

View File

@ -1678,7 +1678,7 @@ Selection::GetPrimaryFrameForFocusNode(nsIFrame** aReturnFrame,
*aReturnFrame = nullptr;
nsINode* focusNode = GetFocusNode();
if (!focusNode->IsContent() || !mFrameSelection) {
if (!focusNode || !focusNode->IsContent() || !mFrameSelection) {
return NS_ERROR_FAILURE;
}

View File

@ -653,26 +653,6 @@ nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
return NS_OK;
}
NS_IMETHODIMP
nsDOMClassInfo::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, JS::Value *vp,
bool *_retval)
{
NS_WARNING("nsDOMClassInfo::GetProperty Don't call me!");
return NS_OK;
}
NS_IMETHODIMP
nsDOMClassInfo::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, JS::Value *vp,
bool *_retval)
{
NS_WARNING("nsDOMClassInfo::SetProperty Don't call me!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, bool *_retval)

View File

@ -12574,8 +12574,7 @@ nsDocument::GetVisibilityState(nsAString& aState)
/* virtual */ void
nsIDocument::DocAddSizeOfExcludingThis(nsWindowSizes& aSizes) const
{
nsINode::AddSizeOfExcludingThis(aSizes.mState, aSizes.mStyleSizes,
&aSizes.mDOMOtherSize);
nsINode::AddSizeOfExcludingThis(aSizes, &aSizes.mDOMOtherSize);
if (mPresShell) {
mPresShell->AddSizeOfIncludingThis(aSizes);
@ -12622,8 +12621,7 @@ SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<StyleSheet>>& aSheets,
}
void
nsDocument::AddSizeOfExcludingThis(SizeOfState& aState,
nsStyleSizes& aSizes,
nsDocument::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const
{
// This AddSizeOfExcludingThis() overrides the one from nsINode. But
@ -12637,8 +12635,7 @@ static void
AddSizeOfNodeTree(nsIContent* aNode, nsWindowSizes& aWindowSizes)
{
size_t nodeSize = 0;
aNode->AddSizeOfIncludingThis(aWindowSizes.mState, aWindowSizes.mStyleSizes,
&nodeSize);
aNode->AddSizeOfIncludingThis(aWindowSizes, &nodeSize);
// This is where we transfer the nodeSize obtained from
// nsINode::AddSizeOfIncludingThis() to a value in nsWindowSizes.

View File

@ -1120,11 +1120,10 @@ nsGenericDOMDataNode::GetAttributeChangeHint(const nsIAtom* aAttribute,
}
void
nsGenericDOMDataNode::AddSizeOfExcludingThis(SizeOfState& aState,
nsStyleSizes& aSizes,
nsGenericDOMDataNode::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const
{
nsIContent::AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
*aNodeSize += mText.SizeOfExcludingThis(aState.mMallocSizeOf);
nsIContent::AddSizeOfExcludingThis(aSizes, aNodeSize);
*aNodeSize += mText.SizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
}

View File

@ -2755,7 +2755,7 @@ EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp)
}
static const JSFunctionSpec EnablePrivilegeSpec[] = {
JS_FS("enablePrivilege", EnablePrivilege, 1, 0),
JS_FN("enablePrivilege", EnablePrivilege, 1, 0),
JS_FS_END
};

View File

@ -2583,12 +2583,11 @@ nsINode::GetAccessibleNode()
}
void
nsINode::AddSizeOfExcludingThis(SizeOfState& aState, nsStyleSizes& aSizes,
size_t* aNodeSize) const
nsINode::AddSizeOfExcludingThis(nsWindowSizes& aSizes, size_t* aNodeSize) const
{
EventListenerManager* elm = GetExistingListenerManager();
if (elm) {
*aNodeSize += elm->SizeOfIncludingThis(aState.mMallocSizeOf);
*aNodeSize += elm->SizeOfIncludingThis(aSizes.mState.mMallocSizeOf);
}
// Measurement of the following members may be added later if DMD finds it is

View File

@ -268,8 +268,7 @@ private:
// AddSizeOfExcludingThis from its super-class. AddSizeOfIncludingThis() need
// not be defined, it is inherited from nsINode.
#define NS_DECL_ADDSIZEOFEXCLUDINGTHIS \
virtual void AddSizeOfExcludingThis(mozilla::SizeOfState& aState, \
nsStyleSizes& aSizes, \
virtual void AddSizeOfExcludingThis(nsWindowSizes& aSizes, \
size_t* aNodeSize) const override;
// Categories of node properties
@ -332,20 +331,18 @@ public:
// The following members don't need to be measured:
// - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere
//
virtual void AddSizeOfExcludingThis(mozilla::SizeOfState& aState,
nsStyleSizes& aSizes,
virtual void AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const;
// SizeOfIncludingThis doesn't need to be overridden by sub-classes because
// sub-classes of nsINode are guaranteed to be laid out in memory in such a
// way that |this| points to the start of the allocated object, even in
// methods of nsINode's sub-classes, so aState.mMallocSizeOf(this) is always
// safe to call no matter which object it was invoked on.
virtual void AddSizeOfIncludingThis(mozilla::SizeOfState& aState,
nsStyleSizes& aSizes,
// methods of nsINode's sub-classes, so aSizes.mState.mMallocSizeOf(this) is
// always safe to call no matter which object it was invoked on.
virtual void AddSizeOfIncludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const {
*aNodeSize += aState.mMallocSizeOf(this);
AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
*aNodeSize += aSizes.mState.mMallocSizeOf(this);
AddSizeOfExcludingThis(aSizes, aNodeSize);
}
friend class nsNodeUtils;

View File

@ -1098,10 +1098,10 @@ JProfSaveCircularJS(JSContext *cx, unsigned argc, JS::Value *vp)
}
static const JSFunctionSpec JProfFunctions[] = {
JS_FS("JProfStartProfiling", JProfStartProfilingJS, 0, 0),
JS_FS("JProfStopProfiling", JProfStopProfilingJS, 0, 0),
JS_FS("JProfClearCircular", JProfClearCircularJS, 0, 0),
JS_FS("JProfSaveCircular", JProfSaveCircularJS, 0, 0),
JS_FN("JProfStartProfiling", JProfStartProfilingJS, 0, 0),
JS_FN("JProfStopProfiling", JProfStopProfilingJS, 0, 0),
JS_FN("JProfClearCircular", JProfClearCircularJS, 0, 0),
JS_FN("JProfSaveCircular", JProfSaveCircularJS, 0, 0),
JS_FS_END
};
@ -1617,6 +1617,7 @@ nsJSContext::BeginCycleCollectionCallback()
// Create an ICC timer even if ICC is globally disabled, because we could be manually triggering
// an incremental collection, and we want to be sure to finish it.
sICCRunner = IdleTaskRunner::Create(ICCRunnerFired,
"BeginCycleCollectionCallback::ICCRunnerFired",
kICCIntersliceDelay,
kIdleICCSliceBudget,
true,
@ -1835,7 +1836,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
// Now start the actual GC after initial timer has fired.
sInterSliceGCRunner = IdleTaskRunner::Create([aClosure](TimeStamp aDeadline) {
return InterSliceGCRunnerFired(aDeadline, aClosure);
}, NS_INTERSLICE_GC_DELAY,
}, "GCTimerFired::InterSliceGCRunnerFired",
NS_INTERSLICE_GC_DELAY,
sActiveIntersliceGCBudget,
false,
[]{ return sShuttingDown; },
@ -2138,7 +2140,9 @@ nsJSContext::MaybePokeCC()
nsCycleCollector_dispatchDeferredDeletion();
sCCRunner =
IdleTaskRunner::Create(CCRunnerFired, NS_CC_SKIPPABLE_DELAY,
IdleTaskRunner::Create(CCRunnerFired,
"MaybePokeCC::CCRunnerFired",
NS_CC_SKIPPABLE_DELAY,
kForgetSkippableSliceDuration, true,
[]{ return sShuttingDown; },
TaskCategory::GarbageCollection);
@ -2327,7 +2331,8 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
sInterSliceGCRunner =
IdleTaskRunner::Create([](TimeStamp aDeadline) {
return InterSliceGCRunnerFired(aDeadline, nullptr);
}, NS_INTERSLICE_GC_DELAY,
}, "DOMGCSliceCallback::InterSliceGCRunnerFired",
NS_INTERSLICE_GC_DELAY,
sActiveIntersliceGCBudget,
false,
[]{ return sShuttingDown; },

View File

@ -337,6 +337,80 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"the objects it points to, which include XHRs.");
aWindowTotalSizes->mDOMEventTargetsSize += windowSizes.mDOMEventTargetsSize;
REPORT_SIZE("/dom/performance/user-entries",
windowSizes.mDOMPerformanceUserEntries,
"Memory used for performance user entries.");
aWindowTotalSizes->mDOMPerformanceUserEntries +=
windowSizes.mDOMPerformanceUserEntries;
REPORT_SIZE("/dom/performance/resource-entries",
windowSizes.mDOMPerformanceResourceEntries,
"Memory used for performance resource entries.");
aWindowTotalSizes->mDOMPerformanceResourceEntries +=
windowSizes.mDOMPerformanceResourceEntries;
REPORT_SIZE("/dom/other", windowSizes.mDOMOtherSize,
"Memory used by a window's DOM that isn't measured by the "
"other 'dom/' numbers.");
aWindowTotalSizes->mDOMOtherSize += windowSizes.mDOMOtherSize;
REPORT_SIZE("/style-sheets", windowSizes.mStyleSheetsSize,
"Memory used by style sheets within a window.");
aWindowTotalSizes->mStyleSheetsSize += windowSizes.mStyleSheetsSize;
REPORT_SIZE("/layout/pres-shell", windowSizes.mLayoutPresShellSize,
"Memory used by layout's PresShell, along with any structures "
"allocated in its arena and not measured elsewhere, "
"within a window.");
aWindowTotalSizes->mLayoutPresShellSize += windowSizes.mLayoutPresShellSize;
REPORT_SIZE("/layout/style-sets", windowSizes.mLayoutStyleSetsSize,
"Memory used by style sets within a window.");
aWindowTotalSizes->mLayoutStyleSetsSize += windowSizes.mLayoutStyleSetsSize;
REPORT_SIZE("/layout/text-runs", windowSizes.mLayoutTextRunsSize,
"Memory used for text-runs (glyph layout) in the PresShell's "
"frame tree, within a window.");
aWindowTotalSizes->mLayoutTextRunsSize += windowSizes.mLayoutTextRunsSize;
REPORT_SIZE("/layout/pres-contexts", windowSizes.mLayoutPresContextSize,
"Memory used for the PresContext in the PresShell's frame "
"within a window.");
aWindowTotalSizes->mLayoutPresContextSize +=
windowSizes.mLayoutPresContextSize;
REPORT_SIZE("/layout/frame-properties",
windowSizes.mLayoutFramePropertiesSize,
"Memory used for frame properties attached to frames "
"within a window.");
aWindowTotalSizes->mLayoutFramePropertiesSize +=
windowSizes.mLayoutFramePropertiesSize;
REPORT_SIZE("/layout/computed-values/dom",
windowSizes.mLayoutComputedValuesDom,
"Memory used by ComputedValues objects accessible from DOM "
"elements.");
aWindowTotalSizes->mLayoutComputedValuesDom +=
windowSizes.mLayoutComputedValuesDom;
REPORT_SIZE("/layout/computed-values/non-dom",
windowSizes.mLayoutComputedValuesNonDom,
"Memory used by ComputedValues objects not accessible from DOM "
"elements.");
aWindowTotalSizes->mLayoutComputedValuesNonDom +=
windowSizes.mLayoutComputedValuesNonDom;
REPORT_SIZE("/layout/computed-values/visited",
windowSizes.mLayoutComputedValuesVisited,
"Memory used by ComputedValues objects used for visited styles.");
aWindowTotalSizes->mLayoutComputedValuesVisited +=
windowSizes.mLayoutComputedValuesVisited;
REPORT_SIZE("/property-tables",
windowSizes.mPropertyTablesSize,
"Memory used for the property tables within a window.");
aWindowTotalSizes->mPropertyTablesSize += windowSizes.mPropertyTablesSize;
REPORT_COUNT("/dom/event-targets", windowSizes.mDOMEventTargetsCount,
"Number of non-node event targets in the event targets table "
"in a window's DOM, such as XHRs.");
@ -349,26 +423,6 @@ CollectWindowReports(nsGlobalWindow *aWindow,
aWindowTotalSizes->mDOMEventListenersCount +=
windowSizes.mDOMEventListenersCount;
REPORT_SIZE("/dom/other", windowSizes.mDOMOtherSize,
"Memory used by a window's DOM that isn't measured by the "
"other 'dom/' numbers.");
aWindowTotalSizes->mDOMOtherSize += windowSizes.mDOMOtherSize;
REPORT_SIZE("/property-tables",
windowSizes.mPropertyTablesSize,
"Memory used for the property tables within a window.");
aWindowTotalSizes->mPropertyTablesSize += windowSizes.mPropertyTablesSize;
REPORT_SIZE("/style-sheets", windowSizes.mStyleSheetsSize,
"Memory used by style sheets within a window.");
aWindowTotalSizes->mStyleSheetsSize += windowSizes.mStyleSheetsSize;
REPORT_SIZE("/layout/pres-shell", windowSizes.mLayoutPresShellSize,
"Memory used by layout's PresShell, along with any structures "
"allocated in its arena and not measured elsewhere, "
"within a window.");
aWindowTotalSizes->mLayoutPresShellSize += windowSizes.mLayoutPresShellSize;
REPORT_SIZE("/layout/line-boxes", windowSizes.mArenaSizes.mLineBoxes,
"Memory used by line boxes within a window.");
aWindowTotalSizes->mArenaSizes.mLineBoxes
@ -384,43 +438,38 @@ CollectWindowReports(nsGlobalWindow *aWindow,
aWindowTotalSizes->mArenaSizes.mStyleContexts
+= windowSizes.mArenaSizes.mStyleContexts;
REPORT_SIZE("/layout/gecko-style-structs", windowSizes.mArenaSizes.mStyleStructs,
"Memory used by style structs within a window.");
aWindowTotalSizes->mArenaSizes.mStyleStructs
+= windowSizes.mArenaSizes.mStyleStructs;
// There are many different kinds of style structs, but it is likely that
// only a few matter. Implement a cutoff so we don't bloat about:memory with
// many uninteresting entries.
const size_t STYLE_SUNDRIES_THRESHOLD =
js::MemoryReportingSundriesThreshold();
REPORT_SIZE("/layout/style-sets", windowSizes.mLayoutStyleSetsSize,
"Memory used by style sets within a window.");
aWindowTotalSizes->mLayoutStyleSetsSize += windowSizes.mLayoutStyleSetsSize;
// This is the Gecko style structs, which are in the nsPresArena.
size_t geckoStyleSundriesSize = 0;
#define STYLE_STRUCT(name_, cb_) \
{ \
size_t size = \
windowSizes.mArenaSizes.mGeckoStyleSizes.NS_STYLE_SIZES_FIELD(name_); \
if (size < STYLE_SUNDRIES_THRESHOLD) { \
geckoStyleSundriesSize += size; \
} else { \
REPORT_SIZE("/layout/gecko-style-structs/" # name_, size, \
"Memory used by the " #name_ " Gecko style structs " \
"within a window."); \
} \
aWindowTotalSizes->mArenaSizes.mGeckoStyleSizes.NS_STYLE_SIZES_FIELD(name_) += \
size; \
}
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
REPORT_SIZE("/layout/text-runs", windowSizes.mLayoutTextRunsSize,
"Memory used for text-runs (glyph layout) in the PresShell's "
"frame tree, within a window.");
aWindowTotalSizes->mLayoutTextRunsSize += windowSizes.mLayoutTextRunsSize;
REPORT_SIZE("/layout/pres-contexts", windowSizes.mLayoutPresContextSize,
"Memory used for the PresContext in the PresShell's frame "
"within a window.");
aWindowTotalSizes->mLayoutPresContextSize +=
windowSizes.mLayoutPresContextSize;
REPORT_SIZE("/layout/frame-properties", windowSizes.mLayoutFramePropertiesSize,
"Memory used for frame properties attached to frames "
"within a window.");
aWindowTotalSizes->mLayoutFramePropertiesSize +=
windowSizes.mLayoutFramePropertiesSize;
REPORT_SIZE("/dom/performance/user-entries",
windowSizes.mDOMPerformanceUserEntries,
"Memory used for performance user entries.");
aWindowTotalSizes->mDOMPerformanceUserEntries +=
windowSizes.mDOMPerformanceUserEntries;
REPORT_SIZE("/dom/performance/resource-entries",
windowSizes.mDOMPerformanceResourceEntries,
"Memory used for performance resource entries.");
aWindowTotalSizes->mDOMPerformanceResourceEntries +=
windowSizes.mDOMPerformanceResourceEntries;
if (geckoStyleSundriesSize > 0) {
REPORT_SIZE("/layout/gecko-style-structs/sundries", geckoStyleSundriesSize,
"The sum of all memory used by Gecko style structs which were "
"too small to be shown individually.");
}
// There are many different kinds of frames, but it is very likely
// that only a few matter. Implement a cutoff so we don't bloat
@ -452,56 +501,31 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"to be shown individually.");
}
// There are many different kinds of style structs, but it is likely that
// only a few matter. Implement a cutoff so we don't bloat about:memory with
// many uninteresting entries.
const size_t STYLE_SUNDRIES_THRESHOLD =
js::MemoryReportingSundriesThreshold();
size_t styleSundriesSize = 0;
// This is the Servo style structs.
size_t servoStyleSundriesSize = 0;
#define STYLE_STRUCT(name_, cb_) \
{ \
size_t size = windowSizes.mStyleSizes.NS_STYLE_SIZES_FIELD(name_); \
size_t size = windowSizes.mServoStyleSizes.NS_STYLE_SIZES_FIELD(name_); \
if (size < STYLE_SUNDRIES_THRESHOLD) { \
styleSundriesSize += size; \
servoStyleSundriesSize += size; \
} else { \
REPORT_SIZE("/layout/servo-style-structs/" # name_, size, \
"Memory used by the " #name_ " Servo style structs " \
"within a window."); \
} \
aWindowTotalSizes->mStyleSizes.NS_STYLE_SIZES_FIELD(name_) += size; \
aWindowTotalSizes->mServoStyleSizes.NS_STYLE_SIZES_FIELD(name_) += size; \
}
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
if (styleSundriesSize > 0) {
REPORT_SIZE("/layout/servo-style-structs/sundries", styleSundriesSize,
if (servoStyleSundriesSize > 0) {
REPORT_SIZE("/layout/servo-style-structs/sundries", servoStyleSundriesSize,
"The sum of all memory used by Servo style structs which were "
"too small to be shown individually.");
}
REPORT_SIZE("/layout/computed-values/dom",
windowSizes.mStyleSizes.mComputedValuesDom,
"Memory used by ComputedValues objects accessible from DOM "
"elements.");
aWindowTotalSizes->mStyleSizes.mComputedValuesDom +=
windowSizes.mStyleSizes.mComputedValuesDom;
REPORT_SIZE("/layout/computed-values/non-dom",
windowSizes.mStyleSizes.mComputedValuesNonDom,
"Memory used by ComputedValues objects not accessible from DOM "
"elements.");
aWindowTotalSizes->mStyleSizes.mComputedValuesNonDom +=
windowSizes.mStyleSizes.mComputedValuesNonDom;
REPORT_SIZE("/layout/computed-values/visited",
windowSizes.mStyleSizes.mComputedValuesVisited,
"Memory used by ComputedValues objects used for visited styles.");
aWindowTotalSizes->mStyleSizes.mComputedValuesVisited +=
windowSizes.mStyleSizes.mComputedValuesVisited;
#undef REPORT_SIZE
#undef REPORT_COUNT
}
@ -583,7 +607,8 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
KIND_OTHER, UNITS_BYTES, _amount, \
NS_LITERAL_CSTRING(_desc), aData);
REPORT("window-objects/dom/element-nodes", windowTotalSizes.mDOMElementNodesSize,
REPORT("window-objects/dom/element-nodes",
windowTotalSizes.mDOMElementNodesSize,
"This is the sum of all windows' 'dom/element-nodes' numbers.");
REPORT("window-objects/dom/text-nodes", windowTotalSizes.mDOMTextNodesSize,
@ -598,19 +623,46 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
REPORT("window-objects/dom/event-targets", windowTotalSizes.mDOMEventTargetsSize,
"This is the sum of all windows' 'dom/event-targets' numbers.");
REPORT("window-objects/dom/performance",
windowTotalSizes.mDOMPerformanceUserEntries +
windowTotalSizes.mDOMPerformanceResourceEntries,
"This is the sum of all windows' 'dom/performance/' numbers.");
REPORT("window-objects/dom/other", windowTotalSizes.mDOMOtherSize,
"This is the sum of all windows' 'dom/other' numbers.");
REPORT("window-objects/property-tables",
windowTotalSizes.mPropertyTablesSize,
"This is the sum of all windows' 'property-tables' numbers.");
REPORT("window-objects/style-sheets", windowTotalSizes.mStyleSheetsSize,
"This is the sum of all windows' 'style-sheets' numbers.");
REPORT("window-objects/layout/pres-shell", windowTotalSizes.mLayoutPresShellSize,
REPORT("window-objects/layout/pres-shell",
windowTotalSizes.mLayoutPresShellSize,
"This is the sum of all windows' 'layout/arenas' numbers.");
REPORT("window-objects/layout/style-sets",
windowTotalSizes.mLayoutStyleSetsSize,
"This is the sum of all windows' 'layout/style-sets' numbers.");
REPORT("window-objects/layout/text-runs", windowTotalSizes.mLayoutTextRunsSize,
"This is the sum of all windows' 'layout/text-runs' numbers.");
REPORT("window-objects/layout/pres-contexts",
windowTotalSizes.mLayoutPresContextSize,
"This is the sum of all windows' 'layout/pres-contexts' numbers.");
REPORT("window-objects/layout/frame-properties",
windowTotalSizes.mLayoutFramePropertiesSize,
"This is the sum of all windows' 'layout/frame-properties' numbers.");
REPORT("window-objects/layout/computed-values",
windowTotalSizes.mLayoutComputedValuesDom +
windowTotalSizes.mLayoutComputedValuesNonDom +
windowTotalSizes.mLayoutComputedValuesVisited,
"This is the sum of all windows' 'layout/computed-values/' numbers.");
REPORT("window-objects/property-tables",
windowTotalSizes.mPropertyTablesSize,
"This is the sum of all windows' 'property-tables' numbers.");
REPORT("window-objects/layout/line-boxes",
windowTotalSizes.mArenaSizes.mLineBoxes,
"This is the sum of all windows' 'layout/line-boxes' numbers.");
@ -623,21 +675,18 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
windowTotalSizes.mArenaSizes.mStyleContexts,
"This is the sum of all windows' 'layout/style-contexts' numbers.");
REPORT("window-objects/layout/gecko-style-structs",
windowTotalSizes.mArenaSizes.mStyleStructs,
"This is the sum of all windows' 'layout/gecko-style-structs' numbers.");
size_t geckoStyleTotal = 0;
#define STYLE_STRUCT(name_, cb_) \
geckoStyleTotal += \
windowTotalSizes.mArenaSizes.mGeckoStyleSizes.NS_STYLE_SIZES_FIELD(name_);
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
REPORT("window-objects/layout/style-sets", windowTotalSizes.mLayoutStyleSetsSize,
"This is the sum of all windows' 'layout/style-sets' numbers.");
REPORT("window-objects/layout/text-runs", windowTotalSizes.mLayoutTextRunsSize,
"This is the sum of all windows' 'layout/text-runs' numbers.");
REPORT("window-objects/layout/pres-contexts", windowTotalSizes.mLayoutPresContextSize,
"This is the sum of all windows' 'layout/pres-contexts' numbers.");
REPORT("window-objects/layout/frame-properties", windowTotalSizes.mLayoutFramePropertiesSize,
"This is the sum of all windows' 'layout/frame-properties' numbers.");
REPORT("window-objects/layout/gecko-style-structs", geckoStyleTotal,
"Memory used for style structs within windows. This is the sum of "
"all windows' 'layout/gecko-style-structs/' numbers.");
size_t frameTotal = 0;
#define FRAME_ID(classname, ...) \
@ -651,25 +700,19 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
"Memory used for layout frames within windows. "
"This is the sum of all windows' 'layout/frames/' numbers.");
size_t styleTotal = 0;
size_t servoStyleTotal = 0;
#define STYLE_STRUCT(name_, cb_) \
styleTotal += windowTotalSizes.mStyleSizes.NS_STYLE_SIZES_FIELD(name_);
servoStyleTotal += \
windowTotalSizes.mServoStyleSizes.NS_STYLE_SIZES_FIELD(name_);
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
REPORT("window-objects/layout/servo-style-structs", styleTotal,
REPORT("window-objects/layout/servo-style-structs", servoStyleTotal,
"Memory used for style structs within windows. This is the sum of "
"all windows' 'layout/servo-style-structs/' numbers.");
REPORT("window-objects/layout/computed-values",
windowTotalSizes.mStyleSizes.mComputedValuesDom +
windowTotalSizes.mStyleSizes.mComputedValuesNonDom +
windowTotalSizes.mStyleSizes.mComputedValuesVisited,
"This is the sum of all windows' 'layout/computed-values/' "
"numbers.");
#undef REPORT
return NS_OK;

View File

@ -41,14 +41,64 @@ public:
#define ADD_TO_TOTAL_SIZE(kind, mSize) total += mSize;
#define DECL_SIZE(kind, mSize) size_t mSize;
#define NS_STYLE_SIZES_FIELD(name_) mStyle##name_
struct nsStyleSizes
{
nsStyleSizes()
:
#define STYLE_STRUCT(name_, cb_) \
NS_STYLE_SIZES_FIELD(name_)(0),
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
dummy()
{}
void addToTabSizes(nsTabSizes* aSizes) const
{
#define STYLE_STRUCT(name_, cb_) \
aSizes->add(nsTabSizes::Style, NS_STYLE_SIZES_FIELD(name_));
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
}
size_t getTotalSize() const
{
size_t total = 0;
#define STYLE_STRUCT(name_, cb_) \
total += NS_STYLE_SIZES_FIELD(name_);
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
return total;
}
#define STYLE_STRUCT(name_, cb_) \
size_t NS_STYLE_SIZES_FIELD(name_);
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
// Present just to absorb the trailing comma in the constructor.
int dummy;
};
#define NS_ARENA_SIZES_FIELD(classname) mArena##classname
struct nsArenaSizes {
#define FOR_EACH_SIZE(macro) \
macro(Other, mLineBoxes) \
macro(Style, mRuleNodes) \
macro(Style, mStyleContexts) \
macro(Style, mStyleStructs)
macro(Style, mStyleContexts)
nsArenaSizes()
:
@ -61,7 +111,7 @@ struct nsArenaSizes {
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
dummy()
mGeckoStyleSizes()
{}
void addToTabSizes(nsTabSizes* aSizes) const
@ -74,6 +124,8 @@ struct nsArenaSizes {
#include "nsFrameIdList.h"
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
mGeckoStyleSizes.addToTabSizes(aSizes);
}
size_t getTotalSize() const
@ -89,6 +141,8 @@ struct nsArenaSizes {
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
total += mGeckoStyleSizes.getTotalSize();
return total;
}
@ -101,74 +155,9 @@ struct nsArenaSizes {
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
// Present just to absorb the trailing comma in the constructor.
int dummy;
#undef FOR_EACH_SIZE
};
#define NS_STYLE_SIZES_FIELD(name_) mStyle##name_
struct nsStyleSizes
{
#define FOR_EACH_SIZE(macro) \
macro(Style, mComputedValuesDom) \
macro(Style, mComputedValuesNonDom) \
macro(Style, mComputedValuesVisited)
nsStyleSizes()
:
FOR_EACH_SIZE(ZERO_SIZE)
#define STYLE_STRUCT(name_, cb_) \
NS_STYLE_SIZES_FIELD(name_)(0),
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
dummy()
{}
void addToTabSizes(nsTabSizes* aSizes) const
{
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
#define STYLE_STRUCT(name_, cb_) \
aSizes->add(nsTabSizes::Style, NS_STYLE_SIZES_FIELD(name_));
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
}
size_t getTotalSize() const
{
size_t total = 0;
FOR_EACH_SIZE(ADD_TO_TOTAL_SIZE)
#define STYLE_STRUCT(name_, cb_) \
total += NS_STYLE_SIZES_FIELD(name_);
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
return total;
}
FOR_EACH_SIZE(DECL_SIZE)
#define STYLE_STRUCT(name_, cb_) \
size_t NS_STYLE_SIZES_FIELD(name_);
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
// Present just to absorb the trailing comma in the constructor.
int dummy;
// This is Gecko-only because in Stylo these style structs are stored outside
// the nsPresArena, and so measured elsewhere.
nsStyleSizes mGeckoStyleSizes;
#undef FOR_EACH_SIZE
};
@ -190,6 +179,9 @@ class nsWindowSizes
macro(Other, mLayoutTextRunsSize) \
macro(Other, mLayoutPresContextSize) \
macro(Other, mLayoutFramePropertiesSize) \
macro(Style, mLayoutComputedValuesDom) \
macro(Style, mLayoutComputedValuesNonDom) \
macro(Style, mLayoutComputedValuesVisited) \
macro(Other, mPropertyTablesSize) \
public:
@ -199,14 +191,14 @@ public:
mDOMEventTargetsCount(0),
mDOMEventListenersCount(0),
mArenaSizes(),
mStyleSizes(),
mServoStyleSizes(),
mState(aState)
{}
void addToTabSizes(nsTabSizes* aSizes) const {
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
mArenaSizes.addToTabSizes(aSizes);
mStyleSizes.addToTabSizes(aSizes);
mServoStyleSizes.addToTabSizes(aSizes);
}
size_t getTotalSize() const
@ -215,7 +207,7 @@ public:
FOR_EACH_SIZE(ADD_TO_TOTAL_SIZE)
total += mArenaSizes.getTotalSize();
total += mStyleSizes.getTotalSize();
total += mServoStyleSizes.getTotalSize();
return total;
}
@ -229,7 +221,7 @@ public:
// This is Stylo-only because in Gecko these style structs are stored in the
// nsPresArena, and so are measured as part of that.
nsStyleSizes mStyleSizes;
nsStyleSizes mServoStyleSizes;
mozilla::SizeOfState& mState;

View File

@ -785,7 +785,7 @@ skip-if = debug == true && toolkit == 'android' # Timing dependent, skip slow de
support-files = file_title.xul
[test_treewalker_nextsibling.xml]
[test_user_select.html]
skip-if = (toolkit == 'android') || (os == 'win' && !debug) # Windows is timing dependent(bug 1383512)
skip-if = toolkit == 'android'
[test_viewport_scroll.html]
[test_viewsource_forbidden_in_object.html]
[test_w3element_traversal.html]

View File

@ -333,7 +333,15 @@ function test()
clear();
SimpleTest.finish();
}
window.onload = function() { setTimeout(test, 0); };
// These tests depends on the Ahem font being loaded and rendered so wait for
// font to load, then wait a frame for them to be rendered too.
window.onload = function() {
document.fonts.ready.then(function() {
requestAnimationFrame(test);
});
};
SimpleTest.waitForExplicitFinish();
</script>
</pre>

View File

@ -2048,8 +2048,6 @@ NativePropertyHooks sEmptyNativePropertyHooks = {
const js::ClassOps sBoringInterfaceObjectClassClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */

View File

@ -476,8 +476,6 @@ class CGDOMJSClass(CGThing):
static const js::ClassOps sClassOps = {
${addProperty}, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
${newEnumerate}, /* newEnumerate */
${resolve}, /* resolve */
@ -767,8 +765,6 @@ class CGInterfaceObjectJSClass(CGThing):
static const js::ClassOps sInterfaceObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */

View File

@ -59,8 +59,6 @@ SimpleGlobal_moved(JSObject *obj, const JSObject *old)
}
static const js::ClassOps SimpleGlobalClassOps = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,

View File

@ -406,12 +406,11 @@ HTMLAnchorElement::IntrinsicState() const
}
void
HTMLAnchorElement::AddSizeOfExcludingThis(SizeOfState& aState,
nsStyleSizes& aSizes,
HTMLAnchorElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const
{
nsGenericHTMLElement::AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
*aNodeSize += Link::SizeOfExcludingThis(aState);
nsGenericHTMLElement::AddSizeOfExcludingThis(aSizes, aNodeSize);
*aNodeSize += Link::SizeOfExcludingThis(aSizes.mState);
}
} // namespace dom

View File

@ -220,12 +220,11 @@ HTMLAreaElement::IntrinsicState() const
}
void
HTMLAreaElement::AddSizeOfExcludingThis(SizeOfState& aState,
nsStyleSizes& aSizes,
HTMLAreaElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const
{
nsGenericHTMLElement::AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
*aNodeSize += Link::SizeOfExcludingThis(aState);
nsGenericHTMLElement::AddSizeOfExcludingThis(aSizes, aNodeSize);
*aNodeSize += Link::SizeOfExcludingThis(aSizes.mState);
}
JSObject*

View File

@ -509,12 +509,11 @@ HTMLLinkElement::IntrinsicState() const
}
void
HTMLLinkElement::AddSizeOfExcludingThis(SizeOfState& aState,
nsStyleSizes& aSizes,
HTMLLinkElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
size_t* aNodeSize) const
{
nsGenericHTMLElement::AddSizeOfExcludingThis(aState, aSizes, aNodeSize);
*aNodeSize += Link::SizeOfExcludingThis(aState);
nsGenericHTMLElement::AddSizeOfExcludingThis(aSizes, aNodeSize);
*aNodeSize += Link::SizeOfExcludingThis(aSizes.mState);
}
JSObject*

View File

@ -25043,8 +25043,6 @@ CreateIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
static const JSClassOps sNormalJSContextGlobalClassOps = {
/* addProperty */ nullptr,
/* delProperty */ nullptr,
/* getProperty */ nullptr,
/* setProperty */ nullptr,
/* enumerate */ nullptr,
/* newEnumerate */ nullptr,
/* resolve */ nullptr,

View File

@ -61,6 +61,11 @@ interface nsIPaymentCreateActionRequest : nsIPaymentActionRequest
*/
readonly attribute uint64_t tabId;
/*
* The top level document's principal
*/
readonly attribute nsIPrincipal topLevelPrincipal;
/*
* The methodData information of the payment request.
*/
@ -82,6 +87,7 @@ interface nsIPaymentCreateActionRequest : nsIPaymentActionRequest
void initRequest(in AString aRequestId,
in nsIPaymentActionCallback aCallback,
in uint64_t aTabId,
in nsIPrincipal aPrincipal,
in nsIArray aMethodData,
in nsIPaymentDetails aDetails,
in nsIPaymentOptions aOptions);

View File

@ -5,6 +5,7 @@
#include "nsISupports.idl"
#include "nsIVariant.idl"
#include "nsIPrincipal.idl"
interface nsIArray;
@ -77,6 +78,7 @@ interface nsIPaymentOptions : nsISupports
interface nsIPaymentRequest : nsISupports
{
readonly attribute uint64_t tabId;
readonly attribute nsIPrincipal topLevelPrincipal;
readonly attribute AString requestId;
readonly attribute nsIArray paymentMethods;
readonly attribute nsIPaymentDetails paymentDetails;

View File

@ -662,7 +662,13 @@ ContentChild::Init(MessageLoop* aIOLoop,
SetProcessName(NS_LITERAL_STRING("Web Content"));
#ifdef NIGHTLY_BUILD
HangMonitor::RegisterAnnotator(PendingInputEventHangAnnotator::sSingleton);
// NOTE: We have to register the annotator on the main thread, as annotators
// only affect a single thread.
SystemGroup::Dispatch(TaskCategory::Other,
NS_NewRunnableFunction("RegisterPendingInputEventHangAnnotator", [] {
HangMonitor::RegisterAnnotator(
PendingInputEventHangAnnotator::sSingleton);
}));
#endif
return true;

View File

@ -85,6 +85,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitor.h"
#include "mozilla/ProcessHangMonitorIPC.h"
#include "mozilla/Scheduler.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/ScriptPreloader.h"
#include "mozilla/Services.h"
@ -2016,8 +2017,7 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
nsAutoCString value;
Preferences::GetCString(ContentPrefs::GetContentPref(i), value);
stringPrefs.Append(nsPrintfCString("%u:%d;%s|", i, value.Length(), value.get()));
}
}
break;
case nsIPrefBranch::PREF_INVALID:
break;
@ -2027,6 +2027,8 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
}
}
nsCString schedulerPrefs = Scheduler::GetPrefs();
extraArgs.push_back("-intPrefs");
extraArgs.push_back(intPrefs.get());
extraArgs.push_back("-boolPrefs");
@ -2034,6 +2036,11 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
extraArgs.push_back("-stringPrefs");
extraArgs.push_back(stringPrefs.get());
// Scheduler prefs need to be handled differently because the scheduler needs
// to start up in the content process before the normal preferences service.
extraArgs.push_back("-schedulerPrefs");
extraArgs.push_back(schedulerPrefs.get());
if (gSafeMode) {
extraArgs.push_back("-safeMode");
}

View File

@ -8,6 +8,7 @@
#include "ContentProcess.h"
#include "ContentPrefs.h"
#include "mozilla/Scheduler.h"
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include <stdlib.h>
@ -115,6 +116,7 @@ ContentProcess::Init(int aArgc, char* aArgv[])
bool foundIntPrefs = false;
bool foundBoolPrefs = false;
bool foundStringPrefs = false;
bool foundSchedulerPrefs = false;
uint64_t childID;
bool isForBrowser;
@ -125,6 +127,7 @@ ContentProcess::Init(int aArgc, char* aArgv[])
nsCOMPtr<nsIFile> profileDir;
#endif
char* schedulerPrefs;
InfallibleTArray<PrefSetting> prefsArray;
for (int idx = aArgc; idx > 0; idx--) {
if (!aArgv[idx]) {
@ -204,8 +207,10 @@ ContentProcess::Init(int aArgc, char* aArgv[])
}
SET_PREF_PHASE(END_INIT_PREFS);
foundStringPrefs = true;
}
else if (!strcmp(aArgv[idx], "-safeMode")) {
} else if (!strcmp(aArgv[idx], "-schedulerPrefs")) {
schedulerPrefs = aArgv[idx + 1];
foundSchedulerPrefs = true;
} else if (!strcmp(aArgv[idx], "-safeMode")) {
gSafeMode = true;
}
@ -226,7 +231,13 @@ ContentProcess::Init(int aArgc, char* aArgv[])
}
#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */
bool allFound = foundAppdir && foundChildID && foundIsForBrowser && foundIntPrefs && foundBoolPrefs && foundStringPrefs;
bool allFound = foundAppdir
&& foundChildID
&& foundIsForBrowser
&& foundIntPrefs
&& foundBoolPrefs
&& foundStringPrefs
&& foundSchedulerPrefs;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
allFound &= foundProfile;
@ -237,6 +248,7 @@ ContentProcess::Init(int aArgc, char* aArgv[])
}
}
Preferences::SetInitPreferences(&prefsArray);
Scheduler::SetPrefs(schedulerPrefs);
mContent.Init(IOThreadChild::message_loop(),
ParentPid(),
IOThreadChild::channel(),

View File

@ -164,6 +164,8 @@ NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
nsTArray<TabChild*>* TabChild::sActiveTabs;
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren;
StaticMutex sTabChildrenMutex;
@ -1117,6 +1119,14 @@ TabChild::ActorDestroy(ActorDestroyReason why)
TabChild::~TabChild()
{
if (sActiveTabs) {
sActiveTabs->RemoveElement(this);
if (sActiveTabs->IsEmpty()) {
delete sActiveTabs;
sActiveTabs = nullptr;
}
}
DestroyWindow();
nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation());
@ -2589,6 +2599,19 @@ TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
docShell->SetIsActive(aIsActive);
}
if (aIsActive) {
if (!sActiveTabs) {
sActiveTabs = new nsTArray<TabChild*>();
}
sActiveTabs->AppendElement(this);
} else {
if (sActiveTabs) {
sActiveTabs->RemoveElement(this);
// We don't delete sActiveTabs here when it's empty since that
// could cause a lot of churn. Instead, we wait until ~TabChild.
}
}
if (aIsActive) {
MakeVisible();

View File

@ -750,8 +750,24 @@ public:
return mWidgetNativeData;
}
void MaybeDispatchCoalescedMouseMoveEvents();
static bool HasActiveTabs()
{
return sActiveTabs && !sActiveTabs->IsEmpty();
}
// Returns whichever TabChild is currently in the foreground. If there are
// multiple TabChilds in the foreground (due to multiple windows being open),
// this returns null. This should only be called if HasActiveTabs() returns
// true.
static const nsTArray<TabChild*>& GetActiveTabs()
{
MOZ_ASSERT(HasActiveTabs());
return *sActiveTabs;
}
protected:
virtual ~TabChild();
@ -947,6 +963,12 @@ private:
WindowsHandle mWidgetNativeData;
// This state is used to keep track of the current active tabs (the ones in
// the foreground). There may be more than one if there are multiple browser
// windows open. There may be none if this process does not host any
// foreground tabs.
static nsTArray<TabChild*>* sActiveTabs;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

View File

@ -74,11 +74,13 @@ NS_IMETHODIMP
PaymentCreateActionRequest::InitRequest(const nsAString& aRequestId,
nsIPaymentActionCallback* aCallback,
const uint64_t aTabId,
nsIPrincipal* aTopLevelPrincipal,
nsIArray* aMethodData,
nsIPaymentDetails* aDetails,
nsIPaymentOptions* aOptions)
{
NS_ENSURE_ARG_POINTER(aCallback);
NS_ENSURE_ARG_POINTER(aTopLevelPrincipal);
NS_ENSURE_ARG_POINTER(aMethodData);
NS_ENSURE_ARG_POINTER(aDetails);
NS_ENSURE_ARG_POINTER(aOptions);
@ -87,6 +89,7 @@ PaymentCreateActionRequest::InitRequest(const nsAString& aRequestId,
return rv;
}
mTabId = aTabId;
mTopLevelPrincipal = aTopLevelPrincipal;
mMethodData = aMethodData;
mDetails = aDetails;
mOptions = aOptions;
@ -101,6 +104,16 @@ PaymentCreateActionRequest::GetTabId(uint64_t* aTabId)
return NS_OK;
}
NS_IMETHODIMP
PaymentCreateActionRequest::GetTopLevelPrincipal(nsIPrincipal** aTopLevelPrincipal)
{
NS_ENSURE_ARG_POINTER(aTopLevelPrincipal);
MOZ_ASSERT(mTopLevelPrincipal);
nsCOMPtr<nsIPrincipal> principal = mTopLevelPrincipal;
principal.forget(aTopLevelPrincipal);
return NS_OK;
}
NS_IMETHODIMP
PaymentCreateActionRequest::GetMethodData(nsIArray** aMethodData)
{

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