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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,6 +8,7 @@ include protocol PFileDescriptorSet;
include protocol PBrowser; include protocol PBrowser;
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h"; 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::WindowsHandle from "ipc/IPCMessageUtils.h";
using mozilla::LayoutDeviceIntRect from "Units.h"; using mozilla::LayoutDeviceIntRect from "Units.h";
@ -71,9 +72,18 @@ parent:
returns (IAccessibleHolder aPluginCOMProxy); returns (IAccessibleHolder aPluginCOMProxy);
child: 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, async EmulatedWindow(WindowsHandle aEmulatedWindowHandle,
IAccessibleHolder aEmulatedWindowCOMProxy); IDispatchHolder aEmulatedWindowCOMProxy);
/* /*
* Called as a result of focus shifting from chrome to content * Called as a result of focus shifting from chrome to content
* elements through keyboard navigation. * 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 // Emulated window proxy is only set for the top level content document when
// emulation is enabled. // emulation is enabled.
IAccessible* dispParent = ipcDoc->GetEmulatedWindowIAccessible(); RefPtr<IDispatch> dispParent = ipcDoc->GetEmulatedWindowIAccessible();
if (!dispParent) { if (!dispParent) {
dispParent = ipcDoc->GetParentIAccessible(); dispParent = ipcDoc->GetParentIAccessible();
} }
@ -65,8 +65,7 @@ DocAccessibleWrap::get_accParent(
return S_FALSE; return S_FALSE;
} }
dispParent->AddRef(); dispParent.forget(ppdispParent);
*ppdispParent = static_cast<IDispatch*>(dispParent);
return S_OK; return S_OK;
} }

View file

@ -4,6 +4,34 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
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'] DIRS += ['profile/extensions']
GeckoProgram(CONFIG['MOZ_APP_NAME']) GeckoProgram(CONFIG['MOZ_APP_NAME'])

View file

@ -68,6 +68,15 @@ var SidebarUI = {
enumerator.getNext(); enumerator.getNext();
if (!enumerator.hasMoreElements()) { if (!enumerator.hasMoreElements()) {
document.persist("sidebar-box", "sidebarcommand"); 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-box", "width");
document.persist("sidebar-title", "value"); document.persist("sidebar-title", "value");
} }

View file

@ -502,9 +502,10 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
/* ::::: location bar & search bar ::::: */ /* ::::: location bar & search bar ::::: */
/* url bar min-width is defined further down, together with the maximum size #urlbar-container {
* of the identity icon block, for different window sizes. min-width: 50ch;
*/ }
#search-container { #search-container {
min-width: 25ch; min-width: 25ch;
} }
@ -684,69 +685,41 @@ html|input.urlbar-input[textoverflow]:not([focused]) {
-moz-user-focus: ignore; -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 { #identity-icon-labels {
max-width: 17em; max-width: 18em;
} }
@media (max-width: 700px) { @media (max-width: 700px) {
#urlbar-container { #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 { #identity-icon-labels {
max-width: 60px; max-width: 70px;
} }
} }
@media (max-width: 600px) { @media (max-width: 600px) {
#urlbar-container { #urlbar-container {
min-width: calc(39ch + 24px + 2 * var(--toolbarbutton-inner-padding)); min-width: 40ch;
} }
#nav-bar[hasdownloads] #urlbar-container { #identity-icon-labels {
min-width: 39ch; max-width: 60px;
}
}
@media (max-width: 500px) {
#urlbar-container {
min-width: 35ch;
} }
#identity-icon-labels { #identity-icon-labels {
max-width: 50px; max-width: 50px;
} }
} }
@media (max-width: 500px) { @media (max-width: 400px) {
#urlbar-container { #urlbar-container {
min-width: calc(34ch + 24px + 2 * var(--toolbarbutton-inner-padding)); min-width: 28ch;
}
#nav-bar[hasdownloads] #urlbar-container {
min-width: 34ch;
} }
#identity-icon-labels { #identity-icon-labels {
max-width: 40px; 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 { #identity-icon-country-label {
direction: ltr; direction: ltr;
@ -1088,7 +1061,20 @@ notification[value="translation"] {
} }
/*** Visibility of downloads indicator controls ***/ /*** 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; display: none;
} }

View file

@ -155,13 +155,15 @@
level="parent" level="parent"
overflowpadding="30" /> 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" <panel id="DateTimePickerPanel"
type="arrow" type="arrow"
hidden="true" hidden="true"
orient="vertical" orient="vertical"
noautofocus="true" noautofocus="true"
noautohide="true" norolluponanchor="true"
consumeoutsideclicks="false" consumeoutsideclicks="never"
level="parent" level="parent"
tabspecific="true"> tabspecific="true">
</panel> </panel>
@ -904,18 +906,17 @@
</toolbaritem> </toolbaritem>
<!-- This is a placeholder for the Downloads Indicator. It is visible <!-- 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" <toolbarbutton id="downloads-button"
hidden="true"
class="toolbarbutton-1 chromeclass-toolbar-additional badged-button" class="toolbarbutton-1 chromeclass-toolbar-additional badged-button"
skipintoolbarset="true"
overflows="false"
key="key_openDownloads" key="key_openDownloads"
oncommand="DownloadsIndicatorView.onCommand(event);" oncommand="DownloadsIndicatorView.onCommand(event);"
ondrop="DownloadsIndicatorView.onDrop(event);" ondrop="DownloadsIndicatorView.onDrop(event);"
ondragover="DownloadsIndicatorView.onDragOver(event);" ondragover="DownloadsIndicatorView.onDragOver(event);"
ondragenter="DownloadsIndicatorView.onDragOver(event);" ondragenter="DownloadsIndicatorView.onDragOver(event);"
label="&downloads.label;" label="&downloads.label;"
removable="true"
cui-areatype="toolbar" cui-areatype="toolbar"
tooltip="dynamic-shortcut-tooltip"/> tooltip="dynamic-shortcut-tooltip"/>

View file

@ -25,6 +25,9 @@ with Files("newtab/**"):
with Files("pageinfo/**"): with Files("pageinfo/**"):
BUG_COMPONENT = ("Firefox", "Page Info Window") BUG_COMPONENT = ("Firefox", "Page Info Window")
with Files("test/about/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/alerts/**"): with Files("test/alerts/**"):
BUG_COMPONENT = ("Toolkit", "Notifications and Alerts") BUG_COMPONENT = ("Toolkit", "Notifications and Alerts")
@ -34,6 +37,9 @@ with Files("test/captivePortal/**"):
with Files("test/chrome/**"): with Files("test/chrome/**"):
BUG_COMPONENT = ("Firefox", "General") BUG_COMPONENT = ("Firefox", "General")
with Files("test/contextMenu/**"):
BUG_COMPONENT = ("Firefox", "Menus")
with Files("test/forms/**"): with Files("test/forms/**"):
BUG_COMPONENT = ("Core", "Layout: Form Controls") BUG_COMPONENT = ("Core", "Layout: Form Controls")
@ -43,6 +49,9 @@ with Files("test/newtab/**"):
with Files("test/pageinfo/**"): with Files("test/pageinfo/**"):
BUG_COMPONENT = ("Firefox", "Page Info Window") BUG_COMPONENT = ("Firefox", "Page Info Window")
with Files("test/performance/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/performance/browser_appmenu_reflows.js"): with Files("test/performance/browser_appmenu_reflows.js"):
BUG_COMPONENT = ("Firefox", "Menus") BUG_COMPONENT = ("Firefox", "Menus")
@ -64,9 +73,15 @@ with Files("test/referrer/**"):
with Files("test/siteIdentity/**"): with Files("test/siteIdentity/**"):
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
with Files("test/sidebar/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/static/**"): with Files("test/static/**"):
BUG_COMPONENT = ("Firefox", "General") BUG_COMPONENT = ("Firefox", "General")
with Files("test/sync/**"):
BUG_COMPONENT = ("Firefox", "Sync")
with Files("test/tabPrompts/**"): with Files("test/tabPrompts/**"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser") BUG_COMPONENT = ("Firefox", "Tabbed Browser")
@ -76,6 +91,9 @@ with Files("test/tabcrashed/**"):
with Files("test/tabs/**"): with Files("test/tabs/**"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser") BUG_COMPONENT = ("Firefox", "Tabbed Browser")
with Files("test/touch/**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("test/urlbar/**"): with Files("test/urlbar/**"):
BUG_COMPONENT = ("Firefox", "Location Bar") 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. # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_bug537013.js] [browser_bug537013.js]
subsuite = clipboard 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. # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_bug537474.js] [browser_bug537474.js]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. # 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.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) { if (onContent) {
window.messageManager.removeMessageListener("BrowserTest:FocusChanged", focusChangedListener); window.messageManager.removeMessageListener("BrowserTest:FocusChanged", focusChangedListener);
@ -171,32 +171,15 @@ add_task(async function() {
}); });
// Navigate when the downloads panel is open // Navigate when the downloads panel is open
add_task(async function test_download_focus() { add_task(async function() {
await pushPrefs(["accessibility.tabfocus", 7]); 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); let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", true);
EventUtils.synthesizeMouseAtCenter(document.getElementById("downloads-button"), { }); EventUtils.synthesizeMouseAtCenter(document.getElementById("downloads-button"), { });
await popupShownPromise; await popupShownPromise;
gURLBar.focus(); 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"); false, "focus with downloads panel open panel");
await expectFocusOnF6(false, "html1", "html1", await expectFocusOnF6(false, "html1", "html1",
true, "focus with downloads panel open"); true, "focus with downloads panel open");
@ -206,7 +189,7 @@ add_task(async function test_download_focus() {
// Now go backwards // Now go backwards
await expectFocusOnF6(true, "html1", "html1", await expectFocusOnF6(true, "html1", "html1",
true, "back focus with downloads panel open"); 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"); false, "back focus with downloads panel open");
await expectFocusOnF6(true, "main-window", gURLBar.inputField, await expectFocusOnF6(true, "main-window", gURLBar.inputField,
false, "back focus downloads panel open urlbar"); false, "back focus downloads panel open urlbar");

View file

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

View file

@ -9,8 +9,8 @@ const DRAG_WORD = "Firefox";
add_task(async function checkDragURL() { add_task(async function checkDragURL() {
await BrowserTestUtils.withNewTab(TEST_URL, function(browser) { await BrowserTestUtils.withNewTab(TEST_URL, function(browser) {
// Have to use something other than the URL bar as a source, so picking the // Have to use something other than the URL bar as a source, so picking the
// home button somewhat arbitrarily: // downloads button somewhat arbitrarily:
EventUtils.synthesizeDrop(document.getElementById("home-button"), gURLBar, EventUtils.synthesizeDrop(document.getElementById("downloads-button"), gURLBar,
[[{type: "text/plain", data: DRAG_URL}]], "copy", window); [[{type: "text/plain", data: DRAG_URL}]], "copy", window);
is(gURLBar.value, TEST_URL, "URL bar value should not have changed"); 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"); 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() { add_task(async function checkDragForbiddenURL() {
await BrowserTestUtils.withNewTab(TEST_URL, function(browser) { 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); [[{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"); 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() { add_task(async function checkDragText() {
await BrowserTestUtils.withNewTab(TEST_URL, function(browser) { 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); [[{type: "text/plain", data: DRAG_TEXT}]], "copy", window);
is(gURLBar.value, DRAG_TEXT, "Dragging normal text should replace the URL bar value"); 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); [[{type: "text/plain", data: DRAG_WORD}]], "copy", window);
is(gURLBar.value, DRAG_WORD, "Dragging a single word should replace the URL bar value"); 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] [browser_devices_get_user_media_in_frame.js]
skip-if = debug # bug 1369731 skip-if = debug # bug 1369731
[browser_devices_get_user_media_multi_process.js] [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_screen.js]
[browser_devices_get_user_media_tear_off_tab.js] [browser_devices_get_user_media_tear_off_tab.js]
[browser_devices_get_user_media_unprompted_access.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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
SPHINX_TREES['sslerrorreport'] = 'content/docs/sslerrorreport' SPHINX_TREES['sslerrorreport'] = 'content/docs/sslerrorreport'
MOCHITEST_MANIFESTS += [ 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. * 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) * (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 * Buttons removed from built-ins by version they were removed. kVersion must be
@ -177,7 +177,7 @@ var CustomizableUIInternal = {
this.addListener(this); this.addListener(this);
this._defineBuiltInWidgets(); this._defineBuiltInWidgets();
this.loadSavedState(); this.loadSavedState();
this._updateForNewVersion(); this._introduceNewBuiltinWidgets();
this._markObsoleteBuiltinButtonsSeen(); this._markObsoleteBuiltinButtonsSeen();
this.registerArea(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, { this.registerArea(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, {
@ -195,6 +195,7 @@ var CustomizableUIInternal = {
"urlbar-container", "urlbar-container",
"search-container", "search-container",
"spring", "spring",
"downloads-button",
"library-button", "library-button",
"sidebar-button", "sidebar-button",
]; ];
@ -262,7 +263,7 @@ var CustomizableUIInternal = {
} }
}, },
_updateForNewVersion() { _introduceNewBuiltinWidgets() {
// We should still enter even if gSavedState.currentVersion >= kVersion // We should still enter even if gSavedState.currentVersion >= kVersion
// because the per-widget pref facility is independent of versioning. // because the per-widget pref facility is independent of versioning.
if (!gSavedState) { 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."); "All future placements should be dealt with by now.");
let {CustomizableUIInternal, gFuturePlacements, gPalette} = CustomizableUIBSPass; let {CustomizableUIInternal, gFuturePlacements, gPalette} = CustomizableUIBSPass;
CustomizableUIInternal._updateForNewVersion(); CustomizableUIInternal._introduceNewBuiltinWidgets();
is(gFuturePlacements.size, 0, is(gFuturePlacements.size, 0,
"No change to future placements initially."); "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 // Then call the re-init routine so we re-add the builtin widgets
CustomizableUIInternal._updateForNewVersion(); CustomizableUIInternal._introduceNewBuiltinWidgets();
is(gFuturePlacements.size, 1, is(gFuturePlacements.size, 1,
"Should have 1 more future placement"); "Should have 1 more future placement");
let haveNavbarPlacements = gFuturePlacements.has(CustomizableUI.AREA_NAVBAR); let haveNavbarPlacements = gFuturePlacements.has(CustomizableUI.AREA_NAVBAR);
@ -106,7 +106,7 @@ function test() {
"PanelUI-contents": ["panic-button", "edit-controls"], "PanelUI-contents": ["panic-button", "edit-controls"],
}, },
}; };
CustomizableUIInternal._updateForNewVersion(); CustomizableUIInternal._introduceNewBuiltinWidgets();
let navbarPlacements = CustomizableUIBSPass.gSavedState.placements["nav-bar"]; let navbarPlacements = CustomizableUIBSPass.gSavedState.placements["nav-bar"];
let springs = navbarPlacements.filter(id => id.includes("spring")); let springs = navbarPlacements.filter(id => id.includes("spring"));
is(springs.length, 2, "Should have 2 toolbarsprings in placements now"); is(springs.length, 2, "Should have 2 toolbarsprings in placements now");

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -43,3 +43,28 @@ add_task(async function check_developer_subview_in_overflow() {
expectedPanel.hidePopup(); expectedPanel.hidePopup();
await Promise.resolve(); // wait for popup to hide fully. 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", PluralForm: "resource://gre/modules/PluralForm.jsm",
AppConstants: "resource://gre/modules/AppConstants.jsm", AppConstants: "resource://gre/modules/AppConstants.jsm",
AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.jsm", AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.jsm",
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
DownloadHistory: "resource://gre/modules/DownloadHistory.jsm", DownloadHistory: "resource://gre/modules/DownloadHistory.jsm",
Downloads: "resource://gre/modules/Downloads.jsm", Downloads: "resource://gre/modules/Downloads.jsm",
DownloadUIHelper: "resource://gre/modules/DownloadUIHelper.jsm", DownloadUIHelper: "resource://gre/modules/DownloadUIHelper.jsm",
@ -1030,19 +1031,6 @@ const DownloadsViewPrototype = {
_updateView() { _updateView() {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED; 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 // DownloadsIndicatorData
@ -1156,6 +1144,31 @@ DownloadsIndicatorDataCtor.prototype = {
}, },
_attentionSuppressed: false, _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. * Updates the specified view with the current aggregate values.
* *
@ -1315,6 +1328,19 @@ DownloadsSummaryData.prototype = {
// Propagation of properties to our views // 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. * Updates the specified view with the current aggregate values.
* *

View file

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

View file

@ -702,8 +702,12 @@ var DownloadsView = {
let count = this._downloads.length; let count = this._downloads.length;
let hiddenCount = count - this.kItemCountLimit; let hiddenCount = count - this.kItemCountLimit;
if (count <= 0) { if (count > 0) {
DownloadsButton.hide(); 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 // If we've got some hidden downloads, we should activate the

View file

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

View file

@ -108,14 +108,35 @@ const DownloadsButton = {
indicator.open = this._anchorRequested; indicator.open = this._anchorRequested;
// Determine if the indicator is located on an invisible toolbar. let widget = CustomizableUI.getWidget("downloads-button")
if (!window.toolbar.visible) { .forWindow(window);
return null; // Determine if the indicator is located on an invisible toolbar.
} if (!isElementVisible(indicator.parentNode) && !widget.overflowed) {
return null;
}
return DownloadsIndicatorView.indicatorAnchor; 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 * 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. * 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. * Allows the temporary anchor to be hidden.
*/ */
@ -261,6 +252,12 @@ const DownloadsIndicatorView = {
return; 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( DownloadsOverlayLoader.ensureOverlayLoaded(
DownloadsButton.kIndicatorOverlay, DownloadsButton.kIndicatorOverlay,
() => { () => {
@ -342,7 +339,21 @@ const DownloadsIndicatorView = {
return; 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: // Our container isn't visible, so can't show the animation:
return; return;
} }
@ -354,7 +365,6 @@ const DownloadsIndicatorView = {
// container. // container.
// Note: no notifier animation for download finished in Photon // Note: no notifier animation for download finished in Photon
let notifier = this.notifier; let notifier = this.notifier;
let anchor = DownloadsButton._placeholder;
if (aType == "start") { if (aType == "start") {
// Show the notifier before measuring for size/placement. Being hidden by default // Show the notifier before measuring for size/placement. Being hidden by default
@ -413,9 +423,7 @@ const DownloadsIndicatorView = {
this._hasDownloads = aValue; this._hasDownloads = aValue;
// If there is at least one download, ensure that the view elements are // If there is at least one download, ensure that the view elements are
// operational
if (aValue) { if (aValue) {
DownloadsButton.unhideAndPlace();
this._ensureOperational(); this._ensureOperational();
} }
} }
@ -437,6 +445,7 @@ const DownloadsIndicatorView = {
if (this._percentComplete !== aValue) { if (this._percentComplete !== aValue) {
this._percentComplete = aValue; this._percentComplete = aValue;
this._refreshAttention();
if (this._percentComplete >= 0) { if (this._percentComplete >= 0) {
this.indicator.setAttribute("progress", "true"); this.indicator.setAttribute("progress", "true");
@ -462,14 +471,29 @@ const DownloadsIndicatorView = {
} }
if (this._attention != aValue) { if (this._attention != aValue) {
this._attention = aValue; this._attention = aValue;
if (this._attention == DownloadsCommon.ATTENTION_NONE) { this._refreshAttention();
this.indicator.removeAttribute("attention");
} else {
this.indicator.setAttribute("attention", this._attention);
}
} }
return this._attention; 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, _attention: DownloadsCommon.ATTENTION_NONE,
// User interface event functions // User interface event functions
@ -480,7 +504,14 @@ const DownloadsIndicatorView = {
}, },
onCommand(aEvent) { 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(); aEvent.stopPropagation();
}, },
@ -532,6 +563,11 @@ const DownloadsIndicatorView = {
}, },
get indicatorAnchor() { get indicatorAnchor() {
let widget = CustomizableUI.getWidget("downloads-button")
.forWindow(window);
if (widget.overflowed) {
return widget.anchor;
}
return document.getElementById("downloads-indicator-anchor"); return document.getElementById("downloads-indicator-anchor");
}, },

View file

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

View file

@ -10,23 +10,16 @@
*/ */
add_task(async function test_height_reduced_after_removal() { add_task(async function test_height_reduced_after_removal() {
await task_addDownloads([ await task_addDownloads([
{ state: DownloadsCommon.DOWNLOAD_PAUSED },
{ state: DownloadsCommon.DOWNLOAD_FINISHED }, { state: DownloadsCommon.DOWNLOAD_FINISHED },
]); ]);
await BrowserTestUtils.waitForCondition(() => {
let btn = document.getElementById("downloads-button");
return !btn.hidden && btn.getBoundingClientRect().width > 0;
});
await task_openPanel(); await task_openPanel();
let panel = document.getElementById("downloadsPanel"); let panel = document.getElementById("downloadsPanel");
let heightBeforeRemoval = panel.getBoundingClientRect().height; 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(); DownloadsPanel.hidePanel();
let publicList = await Downloads.getList(Downloads.PUBLIC); await task_resetState();
await publicList.removeFinished();
await task_openPanel(); await task_openPanel();
let heightAfterRemoval = panel.getBoundingClientRect().height; let heightAfterRemoval = panel.getBoundingClientRect().height;

View file

@ -32,9 +32,7 @@ add_task(async function test_first_download_panel() {
// time a download is started. // time a download is started.
DownloadsCommon.getData(window).panelHasShownBefore = false; DownloadsCommon.getData(window).panelHasShownBefore = false;
info("waiting for panel open");
let promise = promisePanelOpened(); let promise = promisePanelOpened();
await task_addDownloads([{state: DownloadsCommon.DOWNLOAD_DOWNLOADING}]);
DownloadsCommon.getData(window)._notifyDownloadEvent("start"); DownloadsCommon.getData(window)._notifyDownloadEvent("start");
await promise; 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"]); var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
registerCleanupFunction(function() { // The file may have been already deleted when removing a paused download.
gTestTargetFile.remove(false); registerCleanupFunction(() => OS.File.remove(gTestTargetFile.path,
}); { ignoreAbsent: true }));
// Asynchronous support subroutines // Asynchronous support subroutines

View file

@ -72,6 +72,14 @@
["devtools", "panels"] ["devtools", "panels"]
] ]
}, },
"find": {
"url": "chrome://browser/content/ext-find.js",
"schema": "chrome://browser/content/schemas/find.json",
"scopes": ["addon_parent"],
"paths": [
["find"]
]
},
"history": { "history": {
"url": "chrome://browser/content/ext-history.js", "url": "chrome://browser/content/ext-history.js",
"schema": "chrome://browser/content/schemas/history.json", "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-inspectedWindow.js
content/browser/ext-devtools-network.js content/browser/ext-devtools-network.js
content/browser/ext-devtools-panels.js content/browser/ext-devtools-panels.js
content/browser/ext-find.js
content/browser/ext-geckoProfiler.js content/browser/ext-geckoProfiler.js
content/browser/ext-history.js content/browser/ext-history.js
content/browser/ext-menus.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_inspected_window.json
content/browser/schemas/devtools_network.json content/browser/schemas/devtools_network.json
content/browser/schemas/devtools_panels.json content/browser/schemas/devtools_panels.json
content/browser/schemas/find.json
content/browser/schemas/geckoProfiler.json content/browser/schemas/geckoProfiler.json
content/browser/schemas/history.json content/browser/schemas/history.json
content/browser/schemas/menus.json content/browser/schemas/menus.json

View file

@ -10,6 +10,7 @@ support-files =
context_tabs_onUpdated_page.html context_tabs_onUpdated_page.html
context_tabs_onUpdated_iframe.html context_tabs_onUpdated_iframe.html
file_clearplugindata.html file_clearplugindata.html
file_find_frames.html
file_popup_api_injection_a.html file_popup_api_injection_a.html
file_popup_api_injection_b.html file_popup_api_injection_b.html
file_iframe_document.html file_iframe_document.html
@ -73,6 +74,7 @@ skip-if = (os == 'win' && !debug) # bug 1352668
[browser_ext_devtools_page.js] [browser_ext_devtools_page.js]
[browser_ext_devtools_panel.js] [browser_ext_devtools_panel.js]
[browser_ext_devtools_panels_elements.js] [browser_ext_devtools_panels_elements.js]
[browser_ext_find.js]
[browser_ext_geckoProfiler_symbolicate.js] [browser_ext_geckoProfiler_symbolicate.js]
[browser_ext_getViews.js] [browser_ext_getViews.js]
[browser_ext_identity_indication.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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("distribution.js"):
BUG_COMPONENT = ("Firefox", "Distributions")
with Files("tests/**"): with Files("tests/**"):
BUG_COMPONENT = ("Firefox", "General") 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "Activity Streams: General")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Toolkit", "Application Update")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Core", "Plug-ins")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Core", "DOM: Content Processes")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Core", "Networking")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Core", "Plug-ins")
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini'] MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']

View file

@ -22,10 +22,15 @@ DIRS += [
if not CONFIG['RELEASE_OR_BETA']: if not CONFIG['RELEASE_OR_BETA']:
DIRS += [ DIRS += [
'flyweb', 'flyweb',
'formautofill',
'presentation', '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 # Only include the following system add-ons if building DevEdition or Nightly
if CONFIG['MOZ_DEV_EDITION'] or CONFIG['NIGHTLY_BUILD']: if CONFIG['MOZ_DEV_EDITION'] or CONFIG['NIGHTLY_BUILD']:
DIRS += [ DIRS += [

View file

@ -4,6 +4,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Firefox", "Tours")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Cloud Services", "Screenshots")
FINAL_TARGET_FILES.features['screenshots@mozilla.org'] += [ FINAL_TARGET_FILES.features['screenshots@mozilla.org'] += [
'bootstrap.js', 'bootstrap.js',
'install.rdf' 'install.rdf'

View file

@ -4,6 +4,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**"):
BUG_COMPONENT = ("Shield", "Add-on")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']

View file

@ -78,18 +78,6 @@
@DIR_MACOS@updates/* @DIR_MACOS@updates/*
#endif #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 # Common Directory removals
@DIR_MACOS@chrome/ @DIR_MACOS@chrome/
#ifdef XP_UNIX #ifdef XP_UNIX

View file

@ -79,7 +79,7 @@ libs-%:
@$(MAKE) -C ../../toolkit/locales libs-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)' @$(MAKE) -C ../../toolkit/locales libs-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$* @$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../extensions/spellcheck/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-$* @$(MAKE) -C ../extensions/formautofill/locales AB_CD=$* XPI_NAME=locale-$*
endif endif
@$(MAKE) -C ../extensions/onboarding/locales AB_CD=$* XPI_NAME=locale-$* @$(MAKE) -C ../extensions/onboarding/locales AB_CD=$* XPI_NAME=locale-$*
@ -104,7 +104,7 @@ chrome-%:
@$(MAKE) -C ../../toolkit/locales chrome-$* @$(MAKE) -C ../../toolkit/locales chrome-$*
@$(MAKE) -C ../../services/sync/locales chrome AB_CD=$* @$(MAKE) -C ../../services/sync/locales chrome AB_CD=$*
@$(MAKE) -C ../../extensions/spellcheck/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=$* @$(MAKE) -C ../extensions/formautofill/locales chrome AB_CD=$*
endif endif
@$(MAKE) -C ../extensions/pocket/locale chrome AB_CD=$* @$(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.clipboardRead=Get data from the clipboard
webextPerms.description.clipboardWrite=Input data to 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.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.geolocation=Access your location
webextPerms.description.history=Access browsing history webextPerms.description.history=Access browsing history
webextPerms.description.management=Monitor extension usage and manage themes webextPerms.description.management=Monitor extension usage and manage themes

View file

@ -149,6 +149,11 @@
--> -->
<!ENTITY downloadsListEmpty.label "There are no downloads."> <!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): <!-- LOCALIZATION NOTE (downloadsListNoMatch.label):
This string is shown when some search terms are specified, but there are no This string is shown when some search terms are specified, but there are no
results in the Downloads view. 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 # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 += [ EXTRA_COMPONENTS += [
'../build/prebuilt-interfaces.manifest', '../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_INCLUDE_DIR)
AC_SUBST(NSPR_LIB_DIR) AC_SUBST(NSPR_LIB_DIR)
NSPR_PKGCONF_CHECK="nspr" PKGCONF_REQUIRES_PRIVATE="Requires.private: nspr"
if test -n "$MOZ_SYSTEM_NSPR"; then 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 _SAVE_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $NSPR_CFLAGS" CFLAGS="$CFLAGS $NSPR_CFLAGS"
AC_TRY_COMPILE([#include "prlog.h"], 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])) AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT]))
CFLAGS=$_SAVE_CFLAGS 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 fi
AC_SUBST(NSPR_PKGCONF_CHECK) AC_SUBST([PKGCONF_REQUIRES_PRIVATE])
fi # _IS_OUTER_CONFIGURE fi # _IS_OUTER_CONFIGURE

View file

@ -448,7 +448,7 @@ skip-if = true # bug 1368569
[browser_dbg_worker-console-02.js] [browser_dbg_worker-console-02.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_worker-console-03.js] [browser_dbg_worker-console-03.js]
skip-if = e10s && debug skip-if = debug # bug 1334683
[browser_dbg_worker-console-04.js] [browser_dbg_worker-console-04.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_worker-source-map.js] [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 {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/inspector.properties"); 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 colorWidgetPref = "devtools.inspector.colorWidget.enabled";
const NEW_COLOR_WIDGET = Services.prefs.getBoolPref(colorWidgetPref); const NEW_COLOR_WIDGET = Services.prefs.getBoolPref(colorWidgetPref);
@ -50,7 +50,7 @@ function SwatchColorPickerTooltip(document,
this.cssColor4 = supportsCssColor4ColorFunction(); 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 * Fill the tooltip with a new instance of the spectrum color picker widget
* initialized with the given color, and return the instance of spectrum * 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 {CubicBezierWidget} = require("devtools/client/shared/widgets/CubicBezierWidget");
const SwatchBasedEditorTooltip = require("devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip"); 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"; const XHTML_NS = "http://www.w3.org/1999/xhtml";
@ -34,7 +34,7 @@ function SwatchCubicBezierTooltip(document) {
this._onUpdate = this._onUpdate.bind(this); 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 * Fill the tooltip with a new instance of the cubic-bezier widget
* initialized with the given value, and return a promise that resolves to * 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 {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
const SwatchBasedEditorTooltip = require("devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip"); 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"; const XHTML_NS = "http://www.w3.org/1999/xhtml";
@ -36,7 +36,7 @@ function SwatchFilterTooltip(document, cssIsValid) {
this._onUpdate = this._onUpdate.bind(this); 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 * Fill the tooltip with a new instance of the CSSFilterEditorWidget
* widget initialized with the given filter value, and return a promise * 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 = { static const JSClassOps globalClassOps = {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook JS_GlobalObjectTraceHook
}; };
static const JSClass globalClass = { static const JSClass globalClass = {

View file

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

View file

@ -693,18 +693,19 @@ NS_IMPL_ISUPPORTS(nsNodeWeakReference,
nsNodeWeakReference::~nsNodeWeakReference() nsNodeWeakReference::~nsNodeWeakReference()
{ {
if (mNode) { nsINode* node = static_cast<nsINode*>(mObject);
NS_ASSERTION(mNode->Slots()->mWeakReference == this,
if (node) {
NS_ASSERTION(node->Slots()->mWeakReference == this,
"Weak reference has wrong value"); "Weak reference has wrong value");
mNode->Slots()->mWeakReference = nullptr; node->Slots()->mWeakReference = nullptr;
} }
} }
NS_IMETHODIMP NS_IMETHODIMP
nsNodeWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr) nsNodeWeakReference::QueryReferentFromScript(const nsIID& aIID, void** aInstancePtr)
{ {
return mNode ? mNode->QueryInterface(aIID, aInstancePtr) : return QueryReferent(aIID, aInstancePtr);
NS_ERROR_NULL_POINTER;
} }
size_t size_t
@ -2576,16 +2577,16 @@ FragmentOrElement::FireNodeRemovedForChildren()
} }
void void
FragmentOrElement::AddSizeOfExcludingThis(SizeOfState& aState, FragmentOrElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
nsStyleSizes& aSizes,
size_t* aNodeSize) const size_t* aNodeSize) const
{ {
nsIContent::AddSizeOfExcludingThis(aState, aSizes, aNodeSize); nsIContent::AddSizeOfExcludingThis(aSizes, aNodeSize);
*aNodeSize += mAttrsAndChildren.SizeOfExcludingThis(aState.mMallocSizeOf); *aNodeSize +=
mAttrsAndChildren.SizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
nsDOMSlots* slots = GetExistingDOMSlots(); nsDOMSlots* slots = GetExistingDOMSlots();
if (slots) { 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: public:
explicit nsNodeWeakReference(nsINode* aNode) explicit nsNodeWeakReference(nsINode* aNode)
: mNode(aNode) : nsIWeakReference(aNode)
{ {
} }
@ -63,17 +63,14 @@ public:
// nsIWeakReference // nsIWeakReference
NS_DECL_NSIWEAKREFERENCE NS_DECL_NSIWEAKREFERENCE
virtual size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const override; virtual size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
virtual bool IsAlive() const override { return mNode != nullptr; }
void NoticeNodeDestruction() void NoticeNodeDestruction()
{ {
mNode = nullptr; mObject = nullptr;
} }
private: private:
~nsNodeWeakReference(); ~nsNodeWeakReference();
nsINode* MOZ_NON_OWNING_REF mNode;
}; };
/** /**

View file

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

View file

@ -653,26 +653,6 @@ nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
return NS_OK; 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 NS_IMETHODIMP
nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, bool *_retval) JSObject *obj, bool *_retval)

View file

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

View file

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

View file

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

View file

@ -2583,12 +2583,11 @@ nsINode::GetAccessibleNode()
} }
void void
nsINode::AddSizeOfExcludingThis(SizeOfState& aState, nsStyleSizes& aSizes, nsINode::AddSizeOfExcludingThis(nsWindowSizes& aSizes, size_t* aNodeSize) const
size_t* aNodeSize) const
{ {
EventListenerManager* elm = GetExistingListenerManager(); EventListenerManager* elm = GetExistingListenerManager();
if (elm) { 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 // 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 // AddSizeOfExcludingThis from its super-class. AddSizeOfIncludingThis() need
// not be defined, it is inherited from nsINode. // not be defined, it is inherited from nsINode.
#define NS_DECL_ADDSIZEOFEXCLUDINGTHIS \ #define NS_DECL_ADDSIZEOFEXCLUDINGTHIS \
virtual void AddSizeOfExcludingThis(mozilla::SizeOfState& aState, \ virtual void AddSizeOfExcludingThis(nsWindowSizes& aSizes, \
nsStyleSizes& aSizes, \
size_t* aNodeSize) const override; size_t* aNodeSize) const override;
// Categories of node properties // Categories of node properties
@ -332,20 +331,18 @@ public:
// The following members don't need to be measured: // The following members don't need to be measured:
// - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere // - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere
// //
virtual void AddSizeOfExcludingThis(mozilla::SizeOfState& aState, virtual void AddSizeOfExcludingThis(nsWindowSizes& aSizes,
nsStyleSizes& aSizes,
size_t* aNodeSize) const; size_t* aNodeSize) const;
// SizeOfIncludingThis doesn't need to be overridden by sub-classes because // 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 // 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 // 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 // methods of nsINode's sub-classes, so aSizes.mState.mMallocSizeOf(this) is
// safe to call no matter which object it was invoked on. // always safe to call no matter which object it was invoked on.
virtual void AddSizeOfIncludingThis(mozilla::SizeOfState& aState, virtual void AddSizeOfIncludingThis(nsWindowSizes& aSizes,
nsStyleSizes& aSizes,
size_t* aNodeSize) const { size_t* aNodeSize) const {
*aNodeSize += aState.mMallocSizeOf(this); *aNodeSize += aSizes.mState.mMallocSizeOf(this);
AddSizeOfExcludingThis(aState, aSizes, aNodeSize); AddSizeOfExcludingThis(aSizes, aNodeSize);
} }
friend class nsNodeUtils; friend class nsNodeUtils;

View file

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

View file

@ -337,6 +337,80 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"the objects it points to, which include XHRs."); "the objects it points to, which include XHRs.");
aWindowTotalSizes->mDOMEventTargetsSize += windowSizes.mDOMEventTargetsSize; 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, REPORT_COUNT("/dom/event-targets", windowSizes.mDOMEventTargetsCount,
"Number of non-node event targets in the event targets table " "Number of non-node event targets in the event targets table "
"in a window's DOM, such as XHRs."); "in a window's DOM, such as XHRs.");
@ -349,26 +423,6 @@ CollectWindowReports(nsGlobalWindow *aWindow,
aWindowTotalSizes->mDOMEventListenersCount += aWindowTotalSizes->mDOMEventListenersCount +=
windowSizes.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, REPORT_SIZE("/layout/line-boxes", windowSizes.mArenaSizes.mLineBoxes,
"Memory used by line boxes within a window."); "Memory used by line boxes within a window.");
aWindowTotalSizes->mArenaSizes.mLineBoxes aWindowTotalSizes->mArenaSizes.mLineBoxes
@ -384,43 +438,38 @@ CollectWindowReports(nsGlobalWindow *aWindow,
aWindowTotalSizes->mArenaSizes.mStyleContexts aWindowTotalSizes->mArenaSizes.mStyleContexts
+= windowSizes.mArenaSizes.mStyleContexts; += windowSizes.mArenaSizes.mStyleContexts;
REPORT_SIZE("/layout/gecko-style-structs", windowSizes.mArenaSizes.mStyleStructs, // There are many different kinds of style structs, but it is likely that
"Memory used by style structs within a window."); // only a few matter. Implement a cutoff so we don't bloat about:memory with
aWindowTotalSizes->mArenaSizes.mStyleStructs // many uninteresting entries.
+= windowSizes.mArenaSizes.mStyleStructs; const size_t STYLE_SUNDRIES_THRESHOLD =
js::MemoryReportingSundriesThreshold();
REPORT_SIZE("/layout/style-sets", windowSizes.mLayoutStyleSetsSize, // This is the Gecko style structs, which are in the nsPresArena.
"Memory used by style sets within a window."); size_t geckoStyleSundriesSize = 0;
aWindowTotalSizes->mLayoutStyleSetsSize += windowSizes.mLayoutStyleSetsSize; #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, if (geckoStyleSundriesSize > 0) {
"Memory used for text-runs (glyph layout) in the PresShell's " REPORT_SIZE("/layout/gecko-style-structs/sundries", geckoStyleSundriesSize,
"frame tree, within a window."); "The sum of all memory used by Gecko style structs which were "
aWindowTotalSizes->mLayoutTextRunsSize += windowSizes.mLayoutTextRunsSize; "too small to be shown individually.");
}
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;
// There are many different kinds of frames, but it is very likely // 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 // that only a few matter. Implement a cutoff so we don't bloat
@ -452,56 +501,31 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"to be shown individually."); "to be shown individually.");
} }
// There are many different kinds of style structs, but it is likely that // This is the Servo style structs.
// only a few matter. Implement a cutoff so we don't bloat about:memory with size_t servoStyleSundriesSize = 0;
// many uninteresting entries.
const size_t STYLE_SUNDRIES_THRESHOLD =
js::MemoryReportingSundriesThreshold();
size_t styleSundriesSize = 0;
#define STYLE_STRUCT(name_, cb_) \ #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) { \ if (size < STYLE_SUNDRIES_THRESHOLD) { \
styleSundriesSize += size; \ servoStyleSundriesSize += size; \
} else { \ } else { \
REPORT_SIZE("/layout/servo-style-structs/" # name_, size, \ REPORT_SIZE("/layout/servo-style-structs/" # name_, size, \
"Memory used by the " #name_ " Servo style structs " \ "Memory used by the " #name_ " Servo style structs " \
"within a window."); \ "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 #define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h" #include "nsStyleStructList.h"
#undef STYLE_STRUCT #undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES #undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
if (styleSundriesSize > 0) { if (servoStyleSundriesSize > 0) {
REPORT_SIZE("/layout/servo-style-structs/sundries", styleSundriesSize, REPORT_SIZE("/layout/servo-style-structs/sundries", servoStyleSundriesSize,
"The sum of all memory used by Servo style structs which were " "The sum of all memory used by Servo style structs which were "
"too small to be shown individually."); "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_SIZE
#undef REPORT_COUNT #undef REPORT_COUNT
} }
@ -583,7 +607,8 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
KIND_OTHER, UNITS_BYTES, _amount, \ KIND_OTHER, UNITS_BYTES, _amount, \
NS_LITERAL_CSTRING(_desc), aData); 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."); "This is the sum of all windows' 'dom/element-nodes' numbers.");
REPORT("window-objects/dom/text-nodes", windowTotalSizes.mDOMTextNodesSize, REPORT("window-objects/dom/text-nodes", windowTotalSizes.mDOMTextNodesSize,
@ -598,19 +623,46 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
REPORT("window-objects/dom/event-targets", windowTotalSizes.mDOMEventTargetsSize, REPORT("window-objects/dom/event-targets", windowTotalSizes.mDOMEventTargetsSize,
"This is the sum of all windows' 'dom/event-targets' numbers."); "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, REPORT("window-objects/dom/other", windowTotalSizes.mDOMOtherSize,
"This is the sum of all windows' 'dom/other' numbers."); "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, REPORT("window-objects/style-sheets", windowTotalSizes.mStyleSheetsSize,
"This is the sum of all windows' 'style-sheets' numbers."); "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."); "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", REPORT("window-objects/layout/line-boxes",
windowTotalSizes.mArenaSizes.mLineBoxes, windowTotalSizes.mArenaSizes.mLineBoxes,
"This is the sum of all windows' 'layout/line-boxes' numbers."); "This is the sum of all windows' 'layout/line-boxes' numbers.");
@ -623,21 +675,18 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
windowTotalSizes.mArenaSizes.mStyleContexts, windowTotalSizes.mArenaSizes.mStyleContexts,
"This is the sum of all windows' 'layout/style-contexts' numbers."); "This is the sum of all windows' 'layout/style-contexts' numbers.");
REPORT("window-objects/layout/gecko-style-structs", size_t geckoStyleTotal = 0;
windowTotalSizes.mArenaSizes.mStyleStructs, #define STYLE_STRUCT(name_, cb_) \
"This is the sum of all windows' 'layout/gecko-style-structs' numbers."); 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, REPORT("window-objects/layout/gecko-style-structs", geckoStyleTotal,
"This is the sum of all windows' 'layout/style-sets' numbers."); "Memory used for style structs within windows. This is the sum of "
"all windows' 'layout/gecko-style-structs/' 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.");
size_t frameTotal = 0; size_t frameTotal = 0;
#define FRAME_ID(classname, ...) \ #define FRAME_ID(classname, ...) \
@ -651,25 +700,19 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
"Memory used for layout frames within windows. " "Memory used for layout frames within windows. "
"This is the sum of all windows' 'layout/frames/' numbers."); "This is the sum of all windows' 'layout/frames/' numbers.");
size_t styleTotal = 0; size_t servoStyleTotal = 0;
#define STYLE_STRUCT(name_, cb_) \ #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 #define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h" #include "nsStyleStructList.h"
#undef STYLE_STRUCT #undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES #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 " "Memory used for style structs within windows. This is the sum of "
"all windows' 'layout/servo-style-structs/' numbers."); "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 #undef REPORT
return NS_OK; return NS_OK;

View file

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

View file

@ -333,7 +333,15 @@ function test()
clear(); clear();
SimpleTest.finish(); 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(); SimpleTest.waitForExplicitFinish();
</script> </script>
</pre> </pre>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -662,7 +662,13 @@ ContentChild::Init(MessageLoop* aIOLoop,
SetProcessName(NS_LITERAL_STRING("Web Content")); SetProcessName(NS_LITERAL_STRING("Web Content"));
#ifdef NIGHTLY_BUILD #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 #endif
return true; return true;

View file

@ -85,6 +85,7 @@
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitor.h" #include "mozilla/ProcessHangMonitor.h"
#include "mozilla/ProcessHangMonitorIPC.h" #include "mozilla/ProcessHangMonitorIPC.h"
#include "mozilla/Scheduler.h"
#include "mozilla/ScopeExit.h" #include "mozilla/ScopeExit.h"
#include "mozilla/ScriptPreloader.h" #include "mozilla/ScriptPreloader.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
@ -2016,8 +2017,7 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
nsAutoCString value; nsAutoCString value;
Preferences::GetCString(ContentPrefs::GetContentPref(i), value); Preferences::GetCString(ContentPrefs::GetContentPref(i), value);
stringPrefs.Append(nsPrintfCString("%u:%d;%s|", i, value.Length(), value.get())); stringPrefs.Append(nsPrintfCString("%u:%d;%s|", i, value.Length(), value.get()));
}
}
break; break;
case nsIPrefBranch::PREF_INVALID: case nsIPrefBranch::PREF_INVALID:
break; break;
@ -2027,6 +2027,8 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
} }
} }
nsCString schedulerPrefs = Scheduler::GetPrefs();
extraArgs.push_back("-intPrefs"); extraArgs.push_back("-intPrefs");
extraArgs.push_back(intPrefs.get()); extraArgs.push_back(intPrefs.get());
extraArgs.push_back("-boolPrefs"); extraArgs.push_back("-boolPrefs");
@ -2034,6 +2036,11 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
extraArgs.push_back("-stringPrefs"); extraArgs.push_back("-stringPrefs");
extraArgs.push_back(stringPrefs.get()); 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) { if (gSafeMode) {
extraArgs.push_back("-safeMode"); extraArgs.push_back("-safeMode");
} }

View file

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

View file

@ -164,6 +164,8 @@ NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
static const char BEFORE_FIRST_PAINT[] = "before-first-paint"; static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
nsTArray<TabChild*>* TabChild::sActiveTabs;
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap; typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren; static TabChildMap* sTabChildren;
StaticMutex sTabChildrenMutex; StaticMutex sTabChildrenMutex;
@ -1117,6 +1119,14 @@ TabChild::ActorDestroy(ActorDestroyReason why)
TabChild::~TabChild() TabChild::~TabChild()
{ {
if (sActiveTabs) {
sActiveTabs->RemoveElement(this);
if (sActiveTabs->IsEmpty()) {
delete sActiveTabs;
sActiveTabs = nullptr;
}
}
DestroyWindow(); DestroyWindow();
nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation()); nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation());
@ -2589,6 +2599,19 @@ TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
docShell->SetIsActive(aIsActive); 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) { if (aIsActive) {
MakeVisible(); MakeVisible();

View file

@ -750,8 +750,24 @@ public:
return mWidgetNativeData; return mWidgetNativeData;
} }
void MaybeDispatchCoalescedMouseMoveEvents(); 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: protected:
virtual ~TabChild(); virtual ~TabChild();
@ -947,6 +963,12 @@ private:
WindowsHandle mWidgetNativeData; 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); DISALLOW_EVIL_CONSTRUCTORS(TabChild);
}; };

View file

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

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