mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Merge m-c to inbound. a=merge
This commit is contained in:
commit
ac665ca41c
@ -822,12 +822,20 @@ getParentCB(AtkObject *aAtkObj)
|
||||
gint
|
||||
getChildCountCB(AtkObject *aAtkObj)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
|
||||
return 0;
|
||||
if (AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj)) {
|
||||
if (nsAccUtils::MustPrune(accWrap)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<gint>(accWrap->EmbeddedChildCount());
|
||||
}
|
||||
|
||||
ProxyAccessible* proxy = GetProxy(aAtkObj);
|
||||
if (proxy && !proxy->MustPruneChildren()) {
|
||||
return proxy->EmbeddedChildCount();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AtkObject *
|
||||
|
@ -248,12 +248,7 @@ EventQueue::CoalesceReorderEvents(AccEvent* aTailEvent)
|
||||
|
||||
// Coalesce earlier event of the same target.
|
||||
if (thisEvent->mAccessible == aTailEvent->mAccessible) {
|
||||
if (thisEvent->mEventRule == AccEvent::eDoNotEmit) {
|
||||
AccReorderEvent* tailReorder = downcast_accEvent(aTailEvent);
|
||||
tailReorder->DoNotEmitAll();
|
||||
} else {
|
||||
thisEvent->mEventRule = AccEvent::eDoNotEmit;
|
||||
}
|
||||
thisEvent->mEventRule = AccEvent::eDoNotEmit;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -690,8 +690,9 @@ GroupPos
|
||||
ARIAGridCellAccessible::GroupPosition()
|
||||
{
|
||||
int32_t count = 0, index = 0;
|
||||
if (nsCoreUtils::GetUIntAttr(Table()->AsAccessible()->GetContent(),
|
||||
nsGkAtoms::aria_colcount, &count) &&
|
||||
Accessible* table = Table()->AsAccessible();
|
||||
if (table && nsCoreUtils::GetUIntAttr(table->GetContent(),
|
||||
nsGkAtoms::aria_colcount, &count) &&
|
||||
nsCoreUtils::GetUIntAttr(mContent, nsGkAtoms::aria_colindex, &index)) {
|
||||
return GroupPos(0, index, count);
|
||||
}
|
||||
|
@ -147,8 +147,9 @@ GroupPos
|
||||
HTMLTableCellAccessible::GroupPosition()
|
||||
{
|
||||
int32_t count = 0, index = 0;
|
||||
if (nsCoreUtils::GetUIntAttr(Table()->AsAccessible()->GetContent(),
|
||||
nsGkAtoms::aria_colcount, &count) &&
|
||||
Accessible* table = Table()->AsAccessible();
|
||||
if (table && nsCoreUtils::GetUIntAttr(table->GetContent(),
|
||||
nsGkAtoms::aria_colcount, &count) &&
|
||||
nsCoreUtils::GetUIntAttr(mContent, nsGkAtoms::aria_colindex, &index)) {
|
||||
return GroupPos(0, index, count);
|
||||
}
|
||||
|
@ -1727,6 +1727,22 @@ DocAccessibleChild::RecvTakeFocus(const uint64_t& aID)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvEmbeddedChildCount(const uint64_t& aID,
|
||||
uint32_t* aCount)
|
||||
{
|
||||
*aCount = 0;
|
||||
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (!acc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aCount = acc->EmbeddedChildCount();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvIndexOfEmbeddedChild(const uint64_t& aID,
|
||||
const uint64_t& aChildID,
|
||||
|
@ -434,6 +434,9 @@ public:
|
||||
|
||||
virtual bool RecvTakeFocus(const uint64_t& aID) override;
|
||||
|
||||
virtual bool RecvEmbeddedChildCount(const uint64_t& aID, uint32_t* aCount)
|
||||
override final;
|
||||
|
||||
virtual bool RecvIndexOfEmbeddedChild(const uint64_t& aID,
|
||||
const uint64_t& aChildID,
|
||||
uint32_t* aChildIdx) override final;
|
||||
|
@ -226,6 +226,7 @@ child:
|
||||
prio(high) sync Step(uint64_t aID) returns(double aStep);
|
||||
|
||||
prio(high) sync TakeFocus(uint64_t aID);
|
||||
prio(high) sync EmbeddedChildCount(uint64_t aID) returns(uint32_t aCount);
|
||||
prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
|
||||
returns(uint32_t childIdx);
|
||||
prio(high) sync EmbeddedChildAt(uint64_t aID, uint32_t aChildIdx)
|
||||
|
@ -979,6 +979,14 @@ ProxyAccessible::TakeFocus()
|
||||
unused << mDoc->SendTakeFocus(mID);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ProxyAccessible::EmbeddedChildCount() const
|
||||
{
|
||||
uint32_t count;
|
||||
unused << mDoc->SendEmbeddedChildCount(mID, &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
int32_t
|
||||
ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
|
||||
{
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
|
||||
// XXX evaluate if this is fast enough.
|
||||
size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
|
||||
uint32_t EmbeddedChildCount() const;
|
||||
int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
|
||||
ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
|
||||
bool MustPruneChildren() const;
|
||||
|
@ -8,6 +8,7 @@
|
||||
[test_bug1040735.html]
|
||||
[test_bug1100602.html]
|
||||
[test_bug1175913.html]
|
||||
[test_bug1189277.html]
|
||||
[test_canvas.html]
|
||||
[test_colorpicker.xul]
|
||||
[test_contextmenu.xul]
|
||||
|
85
accessible/tests/mochitest/treeupdate/test_bug1189277.html
Normal file
85
accessible/tests/mochitest/treeupdate/test_bug1189277.html
Normal file
@ -0,0 +1,85 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Test hide/show events for HTMLListBulletAccessibles on list restyle</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../name.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function runTest()
|
||||
{
|
||||
this.containerNode = getNode("outerDiv");
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode("child")),
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode),
|
||||
new invokerChecker(EVENT_HIDE, getNode("childDoc")),
|
||||
new invokerChecker(EVENT_SHOW, "newChildDoc")
|
||||
];
|
||||
|
||||
this.invoke = function runTest_invoke()
|
||||
{
|
||||
this.containerNode.removeChild(getNode("child"));
|
||||
|
||||
var docContainer = getNode("docContainer");
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("src", "http://example.com");
|
||||
iframe.setAttribute("id", "newChildDoc");
|
||||
|
||||
docContainer.removeChild(getNode("childDoc"));
|
||||
docContainer.appendChild(iframe);
|
||||
}
|
||||
|
||||
this.getID = function runTest_getID()
|
||||
{
|
||||
return "check show events are not incorrectly coalesced";
|
||||
}
|
||||
}
|
||||
|
||||
gA11yEventDumpToConsole = true;
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new runTest());
|
||||
gQueue.invoke(); // SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1189277"
|
||||
title="content process crash caused by missing show event">
|
||||
Mozilla Bug 1189277
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="outerDiv">
|
||||
<div id="child">foo</div>
|
||||
<div id="docContainer">
|
||||
<iframe id="childDoc" src="about:blank">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1160,14 +1160,6 @@ pref("browser.flash-protected-mode-flip.enable", false);
|
||||
// Whether we've already flipped protected mode automatically
|
||||
pref("browser.flash-protected-mode-flip.done", false);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// On mac, the default pref is per-architecture
|
||||
pref("dom.ipc.plugins.enabled.i386", true);
|
||||
pref("dom.ipc.plugins.enabled.x86_64", true);
|
||||
#else
|
||||
pref("dom.ipc.plugins.enabled", true);
|
||||
#endif
|
||||
|
||||
pref("dom.ipc.shims.enabledWarnings", false);
|
||||
|
||||
// Start the browser in e10s mode
|
||||
|
@ -188,8 +188,11 @@ function initIndexedDBRow()
|
||||
|
||||
var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"]
|
||||
.getService(nsIQuotaManager);
|
||||
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Components.interfaces.nsIScriptSecurityManager)
|
||||
.createCodebasePrincipal(gPermURI, {});
|
||||
gUsageRequest =
|
||||
quotaManager.getUsageForURI(gPermURI, onIndexedDBUsageCallback);
|
||||
quotaManager.getUsageForPrincipal(principal, onIndexedDBUsageCallback);
|
||||
|
||||
var status = document.getElementById("indexedDBStatus");
|
||||
var button = document.getElementById("indexedDBClear");
|
||||
@ -201,9 +204,13 @@ function initIndexedDBRow()
|
||||
|
||||
function onIndexedDBClear()
|
||||
{
|
||||
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Components.interfaces.nsIScriptSecurityManager)
|
||||
.createCodebasePrincipal(gPermURI, {});
|
||||
|
||||
Components.classes["@mozilla.org/dom/quota/manager;1"]
|
||||
.getService(nsIQuotaManager)
|
||||
.clearStoragesForURI(gPermURI);
|
||||
.clearStoragesForPrincipal(principal);
|
||||
|
||||
Components.classes["@mozilla.org/serviceworkers/manager;1"]
|
||||
.getService(Components.interfaces.nsIServiceWorkerManager)
|
||||
@ -213,8 +220,9 @@ function onIndexedDBClear()
|
||||
initIndexedDBRow();
|
||||
}
|
||||
|
||||
function onIndexedDBUsageCallback(uri, usage, fileUsage)
|
||||
function onIndexedDBUsageCallback(principal, usage, fileUsage)
|
||||
{
|
||||
let uri = principal.URI;
|
||||
if (!uri.equals(gPermURI)) {
|
||||
throw new Error("Callback received for bad URI: " + uri);
|
||||
}
|
||||
|
@ -257,8 +257,8 @@ public:
|
||||
}
|
||||
void dumpAnnotationReason(DiagnosticsEngine &Diag, QualType T, SourceLocation Loc);
|
||||
|
||||
void reportErrorIfAbsent(DiagnosticsEngine &Diag, QualType T, SourceLocation Loc,
|
||||
unsigned ErrorID, unsigned NoteID) {
|
||||
void reportErrorIfPresent(DiagnosticsEngine &Diag, QualType T, SourceLocation Loc,
|
||||
unsigned ErrorID, unsigned NoteID) {
|
||||
if (hasEffectiveAnnotation(T)) {
|
||||
Diag.Report(Loc, ErrorID) << T;
|
||||
Diag.Report(Loc, NoteID);
|
||||
@ -1127,24 +1127,24 @@ void DiagnosticsMatcher::ScopeChecker::run(
|
||||
return;
|
||||
|
||||
case AV_Global:
|
||||
StackClass.reportErrorIfAbsent(Diag, T, Loc, StackID, GlobalNoteID);
|
||||
HeapClass.reportErrorIfAbsent(Diag, T, Loc, HeapID, GlobalNoteID);
|
||||
StackClass.reportErrorIfPresent(Diag, T, Loc, StackID, GlobalNoteID);
|
||||
HeapClass.reportErrorIfPresent(Diag, T, Loc, HeapID, GlobalNoteID);
|
||||
break;
|
||||
|
||||
case AV_Automatic:
|
||||
GlobalClass.reportErrorIfAbsent(Diag, T, Loc, GlobalID, StackNoteID);
|
||||
HeapClass.reportErrorIfAbsent(Diag, T, Loc, HeapID, StackNoteID);
|
||||
GlobalClass.reportErrorIfPresent(Diag, T, Loc, GlobalID, StackNoteID);
|
||||
HeapClass.reportErrorIfPresent(Diag, T, Loc, HeapID, StackNoteID);
|
||||
break;
|
||||
|
||||
case AV_Temporary:
|
||||
GlobalClass.reportErrorIfAbsent(Diag, T, Loc, GlobalID, TemporaryNoteID);
|
||||
HeapClass.reportErrorIfAbsent(Diag, T, Loc, HeapID, TemporaryNoteID);
|
||||
GlobalClass.reportErrorIfPresent(Diag, T, Loc, GlobalID, TemporaryNoteID);
|
||||
HeapClass.reportErrorIfPresent(Diag, T, Loc, HeapID, TemporaryNoteID);
|
||||
break;
|
||||
|
||||
case AV_Heap:
|
||||
GlobalClass.reportErrorIfAbsent(Diag, T, Loc, GlobalID, HeapNoteID);
|
||||
StackClass.reportErrorIfAbsent(Diag, T, Loc, StackID, HeapNoteID);
|
||||
NonHeapClass.reportErrorIfAbsent(Diag, T, Loc, NonHeapID, HeapNoteID);
|
||||
GlobalClass.reportErrorIfPresent(Diag, T, Loc, GlobalID, HeapNoteID);
|
||||
StackClass.reportErrorIfPresent(Diag, T, Loc, StackID, HeapNoteID);
|
||||
NonHeapClass.reportErrorIfPresent(Diag, T, Loc, NonHeapID, HeapNoteID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,15 +29,15 @@ want to export this environment variable from your shell's init scripts.
|
||||
NO_MERCURIAL_SETUP = '''
|
||||
*** MERCURIAL NOT CONFIGURED ***
|
||||
|
||||
mach has detected that you have never run `mach mercurial-setup`.
|
||||
mach has detected that you have never run `{mach} mercurial-setup`.
|
||||
|
||||
Running this command will ensure your Mercurial version control tool is up
|
||||
to date and optimally configured for a better, more productive experience
|
||||
when working on Mozilla projects.
|
||||
|
||||
Please run `mach mercurial-setup` now.
|
||||
Please run `{mach} mercurial-setup` now.
|
||||
|
||||
Note: `mach mercurial-setup` does not make any changes without prompting
|
||||
Note: `{mach} mercurial-setup` does not make any changes without prompting
|
||||
you first.
|
||||
'''.strip()
|
||||
|
||||
@ -45,18 +45,18 @@ OLD_MERCURIAL_TOOLS = '''
|
||||
*** MERCURIAL CONFIGURATION POTENTIALLY OUT OF DATE ***
|
||||
|
||||
mach has detected that it has been a while since you have run
|
||||
`mach mercurial-setup`.
|
||||
`{mach} mercurial-setup`.
|
||||
|
||||
Having the latest Mercurial tools and configuration should lead to a better,
|
||||
more productive experience when working on Mozilla projects.
|
||||
|
||||
Please run `mach mercurial-setup` now.
|
||||
Please run `{mach} mercurial-setup` now.
|
||||
|
||||
Reminder: `mach mercurial-setup` does not make any changes without
|
||||
Reminder: `{mach} mercurial-setup` does not make any changes without
|
||||
prompting you first.
|
||||
|
||||
To avoid this message in the future, run `mach mercurial-setup` once a month.
|
||||
Or, schedule `mach mercurial-setup --update-only` to run automatically in
|
||||
To avoid this message in the future, run `{mach} mercurial-setup` once a month.
|
||||
Or, schedule `{mach} mercurial-setup --update-only` to run automatically in
|
||||
the background at least once a month.
|
||||
'''.strip()
|
||||
|
||||
@ -275,10 +275,10 @@ def bootstrap(topsrcdir, mozilla_dir=None):
|
||||
|
||||
# No last run file means mercurial-setup has never completed.
|
||||
if mtime is None:
|
||||
print(NO_MERCURIAL_SETUP, file=sys.stderr)
|
||||
print(NO_MERCURIAL_SETUP.format(mach=sys.argv[0]), file=sys.stderr)
|
||||
sys.exit(2)
|
||||
elif time.time() - mtime > MERCURIAL_SETUP_FATAL_INTERVAL:
|
||||
print(OLD_MERCURIAL_TOOLS, file=sys.stderr)
|
||||
print(OLD_MERCURIAL_TOOLS.format(mach=sys.argv[0]), file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
def populate_context(context, key=None):
|
||||
|
@ -86,6 +86,12 @@ nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiHostPort(nsACString &_hostport)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiSpec(nsACString &_spec)
|
||||
{
|
||||
|
@ -111,7 +111,7 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoCString host;
|
||||
nsAutoCString hostPort;
|
||||
|
||||
// chrome: URLs don't have a meaningful origin, so make
|
||||
// sure we just get the full spec for them.
|
||||
@ -120,10 +120,10 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
|
||||
bool isChrome;
|
||||
nsresult rv = origin->SchemeIs("chrome", &isChrome);
|
||||
if (NS_SUCCEEDED(rv) && !isChrome) {
|
||||
rv = origin->GetAsciiHost(host);
|
||||
rv = origin->GetAsciiHostPort(hostPort);
|
||||
// Some implementations return an empty string, treat it as no support
|
||||
// for asciiHost by that implementation.
|
||||
if (host.IsEmpty()) {
|
||||
if (hostPort.IsEmpty()) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -153,26 +153,7 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t port;
|
||||
if (NS_SUCCEEDED(rv) && !isChrome) {
|
||||
rv = origin->GetPort(&port);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !isChrome) {
|
||||
nsAutoCString hostPort;
|
||||
if (host.FindChar(':') != -1) {
|
||||
hostPort.Assign("[");
|
||||
hostPort.Append(host);
|
||||
hostPort.Append("]");
|
||||
} else {
|
||||
hostPort.Assign(host);
|
||||
}
|
||||
|
||||
if (port != -1) {
|
||||
hostPort.Append(':');
|
||||
hostPort.AppendInt(port, 10);
|
||||
}
|
||||
|
||||
rv = origin->GetScheme(aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
aOrigin.AppendLiteral("://");
|
||||
|
@ -2251,8 +2251,10 @@ ia64*-hpux*)
|
||||
_DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
|
||||
CFLAGS="$CFLAGS -W3 -Gy"
|
||||
CXXFLAGS="$CXXFLAGS -W3 -Gy"
|
||||
if test "$CPU_ARCH" = "x86"; then
|
||||
if test "$CPU_ARCH" = "x86" -a -z "$CLANG_CL"; then
|
||||
dnl VS2012+ defaults to -arch:SSE2.
|
||||
dnl Clang-cl gets confused by -arch:IA32, so don't add it.
|
||||
dnl (See https://llvm.org/bugs/show_bug.cgi?id=24335)
|
||||
CFLAGS="$CFLAGS -arch:IA32"
|
||||
CXXFLAGS="$CXXFLAGS -arch:IA32"
|
||||
fi
|
||||
|
@ -5,20 +5,29 @@
|
||||
#ifndef UseCounter_h_
|
||||
#define UseCounter_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
enum UseCounter {
|
||||
enum UseCounter : int16_t {
|
||||
eUseCounter_UNKNOWN = -1,
|
||||
#define USE_COUNTER_DOM_METHOD(interface_, name_) \
|
||||
eUseCounter_##interface_##_##name_,
|
||||
#define USE_COUNTER_DOM_ATTRIBUTE(interface_, name_) \
|
||||
eUseCounter_##interface_##_##name_,
|
||||
eUseCounter_##interface_##_##name_##_getter, \
|
||||
eUseCounter_##interface_##_##name_##_setter,
|
||||
#define USE_COUNTER_CSS_PROPERTY(name_, id_) \
|
||||
eUseCounter_property_##id_,
|
||||
#include "mozilla/dom/UseCounterList.h"
|
||||
#undef USE_COUNTER_DOM_METHOD
|
||||
#undef USE_COUNTER_DOM_ATTRIBUTE
|
||||
#undef USE_COUNTER_CSS_PROPERTY
|
||||
|
||||
#define DEPRECATED_OPERATION(op_) \
|
||||
eUseCounter_##op_,
|
||||
#include "nsDeprecatedOperationList.h"
|
||||
#undef DEPRECATED_OPERATION
|
||||
|
||||
eUseCounter_Count
|
||||
};
|
||||
|
||||
|
@ -18,12 +18,18 @@
|
||||
//
|
||||
// method <IDL interface name>.<IDL operation name>
|
||||
// attribute <IDL interface name>.<IDL attribute name>
|
||||
// property <CSS property name>
|
||||
// property <CSS property method name>
|
||||
//
|
||||
// The |CSS property method name| should be identical to the |method|
|
||||
// argument to CSS_PROP and related macros. The method name is
|
||||
// identical to the name of the property, except that all hyphens are
|
||||
// removed and CamelCase naming is used. See nsCSSPropList.h for
|
||||
// further details.
|
||||
//
|
||||
// To actually cause use counters to be incremented, DOM methods
|
||||
// and attributes must have a [UseCounter] extended attribute in
|
||||
// the Web IDL file, and CSS properties must be declared with
|
||||
// the CSS_PROPERTY_HAS_USE_COUNTER flag in nsCSSPropList.h.
|
||||
// the Web IDL file. CSS properties require no special treatment
|
||||
// beyond being listed below.
|
||||
//
|
||||
// You might reasonably ask why we have this file and we require
|
||||
// annotating things with [UseCounter] in the relevant WebIDL file as
|
||||
@ -31,3 +37,8 @@
|
||||
// dependencies were correct would have been rather difficult, and
|
||||
// annotating the WebIDL files does nothing for identifying CSS
|
||||
// property usage, which we would also like to track.
|
||||
|
||||
method SVGSVGElement.getElementById
|
||||
attribute SVGSVGElement.currentScale
|
||||
property Fill
|
||||
property FillOpacity
|
||||
|
@ -45,7 +45,7 @@ def generate_list(f, counters):
|
||||
print('USE_COUNTER_DOM_ATTRIBUTE(%s, %s)' % (counter['interface_name'], counter['attribute_name']), file=f)
|
||||
elif counter['type'] == 'property':
|
||||
prop = counter['property_name']
|
||||
print('USE_COUNTER_CSS_PROPERTY(%s, %s)' % (prop, prop.replace('-', '_')), file=f)
|
||||
print('USE_COUNTER_CSS_PROPERTY(%s, %s)' % (prop, prop), file=f)
|
||||
|
||||
print_optional_macro_undeclare('USE_COUNTER_DOM_METHOD')
|
||||
print_optional_macro_undeclare('USE_COUNTER_DOM_ATTRIBUTE')
|
||||
@ -55,19 +55,20 @@ def generate_property_map(f, counters):
|
||||
print(AUTOGENERATED_WARNING_COMMENT, file=f)
|
||||
print('''
|
||||
enum {
|
||||
// XXX is this the right define?
|
||||
#define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_
|
||||
#define CSS_PROP_LIST_INCLUDE_LOGICAL
|
||||
#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \\
|
||||
kwtable_, stylestruct_, stylestructoffset_, animtype_) \\
|
||||
USE_COUNTER_FOR_CSS_PROPERTY_##id_ = eUseCounter_UNKNOWN,
|
||||
USE_COUNTER_FOR_CSS_PROPERTY_##method_ = eUseCounter_UNKNOWN,
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP
|
||||
#undef CSS_PROP_LIST_INCLUDE_LOGICAL
|
||||
#undef CSS_PROP_PUBLIC_OR_PRIVATE
|
||||
};
|
||||
''', file=f)
|
||||
for counter in counters:
|
||||
if counter['type'] == 'property':
|
||||
prop = counter['property_name'].replace('-', '_')
|
||||
prop = counter['property_name']
|
||||
print('#define USE_COUNTER_FOR_CSS_PROPERTY_%s eUseCounter_property_%s' % (prop, prop), file=f)
|
||||
|
||||
def use_counter_list(output_header, conf_filename):
|
||||
|
@ -103,6 +103,9 @@
|
||||
#include "nsIStyleSheetService.h"
|
||||
#include "nsContentPermissionHelper.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsDocument.h"
|
||||
#include "HTMLImageElement.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#undef GetClassName
|
||||
@ -3163,30 +3166,6 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight,
|
||||
float aBottom, float aLeft)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (!presShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop),
|
||||
nsPresContext::CSSPixelsToAppUnits(aRight),
|
||||
nsPresContext::CSSPixelsToAppUnits(aBottom),
|
||||
nsPresContext::CSSPixelsToAppUnits(aLeft));
|
||||
presShell->SetContentDocumentFixedPositionMargins(margins);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
|
||||
{
|
||||
@ -3919,6 +3898,30 @@ nsDOMWindowUtils::LeaveChaosMode()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::ForceUseCounterFlush(nsIDOMNode *aNode)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
|
||||
if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode)) {
|
||||
mozilla::css::ImageLoader* loader = doc->StyleImageLoader();
|
||||
loader->FlushUseCounters();
|
||||
|
||||
static_cast<nsDocument*>(doc.get())->ReportUseCounters();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsIContent> content = do_QueryInterface(aNode)) {
|
||||
if (HTMLImageElement* img = HTMLImageElement::FromContent(content)) {
|
||||
img->FlushUseCounters();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
|
||||
bool* aRetVal)
|
||||
@ -3934,6 +3937,21 @@ nsDOMWindowUtils::HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
|
||||
aRetVal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetNextPaintSyncId(int32_t aSyncId)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
if (nsIWidget* widget = GetWidget()) {
|
||||
nsRefPtr<LayerManager> lm = widget->GetLayerManager();
|
||||
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
ClientLayerManager* clm = static_cast<ClientLayerManager*>(lm.get());
|
||||
clm->SetNextPaintSyncId(aSyncId);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
|
||||
|
@ -1647,6 +1647,8 @@ nsDocument::~nsDocument()
|
||||
}
|
||||
}
|
||||
|
||||
ReportUseCounters();
|
||||
|
||||
mInDestructor = true;
|
||||
mInUnlinkOrDeletion = true;
|
||||
|
||||
@ -4595,6 +4597,8 @@ nsIDocument::SetContainer(nsDocShell* aContainer)
|
||||
if (sameTypeRoot == aContainer) {
|
||||
static_cast<nsDocument*>(this)->SetIsTopLevelContentDocument(true);
|
||||
}
|
||||
|
||||
static_cast<nsDocument*>(this)->SetIsContentDocument(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4794,6 +4798,18 @@ nsDocument::SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument)
|
||||
mIsTopLevelContentDocument = aIsTopLevelContentDocument;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::IsContentDocument() const
|
||||
{
|
||||
return mIsContentDocument;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetIsContentDocument(bool aIsContentDocument)
|
||||
{
|
||||
mIsContentDocument = aIsContentDocument;
|
||||
}
|
||||
|
||||
nsPIDOMWindow *
|
||||
nsDocument::GetWindowInternal() const
|
||||
{
|
||||
@ -10389,6 +10405,19 @@ static const char* kDocumentWarnings[] = {
|
||||
};
|
||||
#undef DOCUMENT_WARNING
|
||||
|
||||
static UseCounter
|
||||
OperationToUseCounter(nsIDocument::DeprecatedOperations aOperation)
|
||||
{
|
||||
switch(aOperation) {
|
||||
#define DEPRECATED_OPERATION(_op) \
|
||||
case nsIDocument::e##_op: return eUseCounter_##_op;
|
||||
#include "nsDeprecatedOperationList.h"
|
||||
#undef DEPRECATED_OPERATION
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsIDocument::HasWarnedAbout(DeprecatedOperations aOperation) const
|
||||
{
|
||||
@ -10404,6 +10433,7 @@ nsIDocument::WarnOnceAbout(DeprecatedOperations aOperation,
|
||||
return;
|
||||
}
|
||||
mDeprecationWarnedAbout[aOperation] = true;
|
||||
const_cast<nsIDocument*>(this)->SetDocumentAndPageUseCounter(OperationToUseCounter(aOperation));
|
||||
uint32_t flags = asError ? nsIScriptError::errorFlag
|
||||
: nsIScriptError::warningFlag;
|
||||
nsContentUtils::ReportToConsole(flags,
|
||||
@ -12756,6 +12786,196 @@ nsDocument::Evaluate(const nsAString& aExpression, nsIDOMNode* aContextNode,
|
||||
aInResult, aResult);
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsIDocument::GetTopLevelContentDocument()
|
||||
{
|
||||
nsDocument* parent;
|
||||
|
||||
if (!mLoadedAsData) {
|
||||
parent = static_cast<nsDocument*>(this);
|
||||
} else {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(GetScopeObject());
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
parent = static_cast<nsDocument*>(window->GetExtantDoc());
|
||||
if (!parent) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (parent->IsTopLevelContentDocument()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If we ever have a non-content parent before we hit a toplevel content
|
||||
// parent, then we're never going to find one. Just bail.
|
||||
if (!parent->IsContentDocument()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIDocument* candidate = parent->GetParentDocument();
|
||||
parent = static_cast<nsDocument*>(candidate);
|
||||
} while (parent);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::PropagateUseCounters(nsIDocument* aParentDocument)
|
||||
{
|
||||
MOZ_ASSERT(this != aParentDocument);
|
||||
|
||||
// What really matters here is that our use counters get propagated as
|
||||
// high up in the content document hierarchy as possible. So,
|
||||
// starting with aParentDocument, we need to find the toplevel content
|
||||
// document, and propagate our use counters into its
|
||||
// mChildDocumentUseCounters.
|
||||
nsIDocument* contentParent = aParentDocument->GetTopLevelContentDocument();
|
||||
|
||||
if (!contentParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
contentParent->mChildDocumentUseCounters |= mUseCounters;
|
||||
contentParent->mChildDocumentUseCounters |= mChildDocumentUseCounters;
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::SetPageUseCounter(UseCounter aUseCounter)
|
||||
{
|
||||
// We want to set the use counter on the "page" that owns us; the definition
|
||||
// of "page" depends on what kind of document we are. See the comments below
|
||||
// for details. In any event, checking all the conditions below is
|
||||
// reasonably expensive, so we cache whether we've notified our owning page.
|
||||
if (mNotifiedPageForUseCounter[aUseCounter]) {
|
||||
return;
|
||||
}
|
||||
mNotifiedPageForUseCounter[aUseCounter] = true;
|
||||
|
||||
if (mDisplayDocument) {
|
||||
// If we are a resource document, we won't have a docshell and so we won't
|
||||
// record any page use counters on this document. Instead, we should
|
||||
// forward it up to the document that loaded us.
|
||||
MOZ_ASSERT(!mDocumentContainer);
|
||||
mDisplayDocument->SetChildDocumentUseCounter(aUseCounter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsBeingUsedAsImage()) {
|
||||
// If this is an SVG image document, we also won't have a docshell.
|
||||
MOZ_ASSERT(!mDocumentContainer);
|
||||
return;
|
||||
}
|
||||
|
||||
// We only care about use counters in content. If we're already a toplevel
|
||||
// content document, then we should have already set the use counter on
|
||||
// ourselves, and we are done.
|
||||
nsIDocument* contentParent = GetTopLevelContentDocument();
|
||||
if (!contentParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this == contentParent) {
|
||||
MOZ_ASSERT(GetUseCounter(aUseCounter));
|
||||
return;
|
||||
}
|
||||
|
||||
contentParent->SetChildDocumentUseCounter(aUseCounter);
|
||||
}
|
||||
|
||||
static bool
|
||||
MightBeAboutOrChromeScheme(nsIURI* aURI)
|
||||
{
|
||||
MOZ_ASSERT(aURI);
|
||||
bool isAbout = true;
|
||||
bool isChrome = true;
|
||||
aURI->SchemeIs("about", &isAbout);
|
||||
aURI->SchemeIs("chrome", &isChrome);
|
||||
return isAbout || isChrome;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ReportUseCounters()
|
||||
{
|
||||
static const bool sDebugUseCounters = false;
|
||||
if (mReportedUseCounters) {
|
||||
return;
|
||||
}
|
||||
|
||||
mReportedUseCounters = true;
|
||||
|
||||
if (Telemetry::HistogramUseCounterCount > 0 &&
|
||||
(IsContentDocument() || IsResourceDoc())) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NodePrincipal()->GetURI(getter_AddRefs(uri));
|
||||
if (!uri || MightBeAboutOrChromeScheme(uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sDebugUseCounters) {
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
|
||||
// URIs can be rather long for data documents, so truncate them to
|
||||
// some reasonable length.
|
||||
spec.Truncate(std::min(128U, spec.Length()));
|
||||
printf("-- Use counters for %s --\n", spec.get());
|
||||
}
|
||||
|
||||
// We keep separate counts for individual documents and top-level
|
||||
// pages to more accurately track how many web pages might break if
|
||||
// certain features were removed. Consider the case of a single
|
||||
// HTML document with several SVG images and/or iframes with
|
||||
// sub-documents of their own. If we maintained a single set of use
|
||||
// counters and all the sub-documents use a particular feature, then
|
||||
// telemetry would indicate that we would be breaking N documents if
|
||||
// that feature were removed. Whereas with a document/top-level
|
||||
// page split, we can see that N documents would be affected, but
|
||||
// only a single web page would be affected.
|
||||
for (int32_t c = 0;
|
||||
c < eUseCounter_Count; ++c) {
|
||||
UseCounter uc = static_cast<UseCounter>(c);
|
||||
|
||||
Telemetry::ID id =
|
||||
static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter + uc * 2);
|
||||
bool value = GetUseCounter(uc);
|
||||
|
||||
if (sDebugUseCounters && value) {
|
||||
const char* name = Telemetry::GetHistogramName(id);
|
||||
if (name) {
|
||||
printf(" %s", name);
|
||||
} else {
|
||||
printf(" #%d", id);
|
||||
}
|
||||
printf(": %d\n", value);
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(id, value);
|
||||
|
||||
if (IsTopLevelContentDocument()) {
|
||||
id = static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter +
|
||||
uc * 2 + 1);
|
||||
value = GetUseCounter(uc) || GetChildDocumentUseCounter(uc);
|
||||
|
||||
if (sDebugUseCounters && value) {
|
||||
const char* name = Telemetry::GetHistogramName(id);
|
||||
if (name) {
|
||||
printf(" %s", name);
|
||||
} else {
|
||||
printf(" #%d", id);
|
||||
}
|
||||
printf(": %d\n", value);
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(id, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XPathEvaluator*
|
||||
nsIDocument::XPathEvaluator()
|
||||
{
|
||||
|
@ -972,6 +972,8 @@ public:
|
||||
*/
|
||||
void OnAppThemeChanged();
|
||||
|
||||
void ReportUseCounters();
|
||||
|
||||
private:
|
||||
void AddOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet);
|
||||
nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
|
||||
@ -1478,12 +1480,15 @@ public:
|
||||
|
||||
static void XPCOMShutdown();
|
||||
|
||||
bool mIsTopLevelContentDocument:1;
|
||||
bool mIsTopLevelContentDocument: 1;
|
||||
bool mIsContentDocument: 1;
|
||||
|
||||
bool IsTopLevelContentDocument();
|
||||
|
||||
void SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument);
|
||||
|
||||
bool IsContentDocument() const;
|
||||
void SetIsContentDocument(bool aIsContentDocument);
|
||||
|
||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
|
||||
#ifdef MOZ_EME
|
||||
@ -1676,6 +1681,14 @@ public:
|
||||
// The value is saturated to kPointerLockRequestLimit+1 = 3.
|
||||
uint8_t mCancelledPointerLockRequests:2;
|
||||
|
||||
// Whether we have reported use counters for this document with Telemetry yet.
|
||||
// Normally this is only done at document destruction time, but for image
|
||||
// documents (SVG documents) that are not guaranteed to be destroyed, we
|
||||
// report use counters when the image cache no longer has any imgRequestProxys
|
||||
// pointing to them. We track whether we ever reported use counters so
|
||||
// that we only report them once for the document.
|
||||
bool mReportedUseCounters:1;
|
||||
|
||||
uint8_t mPendingFullscreenRequests;
|
||||
|
||||
uint8_t mXMLDeclarationBits;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "mozilla/net/ReferrerPolicy.h" // for member
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/dom/DocumentBinding.h"
|
||||
#include "mozilla/UseCounter.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "Units.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
@ -1714,7 +1715,7 @@ public:
|
||||
|
||||
bool IsResourceDoc() const {
|
||||
return IsBeingUsedAsImage() || // Are we a helper-doc for an SVG image?
|
||||
!!mDisplayDocument; // Are we an external resource doc?
|
||||
mHasDisplayDocument; // Are we an external resource doc?
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1743,6 +1744,7 @@ public:
|
||||
NS_PRECONDITION(!aDisplayDocument->GetDisplayDocument(),
|
||||
"Display documents should not nest");
|
||||
mDisplayDocument = aDisplayDocument;
|
||||
mHasDisplayDocument = !!aDisplayDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2316,6 +2318,8 @@ public:
|
||||
eAttributeChanged
|
||||
};
|
||||
|
||||
nsIDocument* GetTopLevelContentDocument();
|
||||
|
||||
/**
|
||||
* Registers an unresolved custom element that is a candidate for
|
||||
* upgrade when the definition is registered via registerElement.
|
||||
@ -2579,6 +2583,41 @@ public:
|
||||
|
||||
bool DidFireDOMContentLoaded() const { return mDidFireDOMContentLoaded; }
|
||||
|
||||
void SetDocumentUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
if (!mUseCounters[aUseCounter]) {
|
||||
mUseCounters[aUseCounter] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SetPageUseCounter(mozilla::UseCounter aUseCounter);
|
||||
|
||||
void SetDocumentAndPageUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
SetDocumentUseCounter(aUseCounter);
|
||||
SetPageUseCounter(aUseCounter);
|
||||
}
|
||||
|
||||
void PropagateUseCounters(nsIDocument* aParentDocument);
|
||||
|
||||
protected:
|
||||
bool GetUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
return mUseCounters[aUseCounter];
|
||||
}
|
||||
|
||||
void SetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
if (!mChildDocumentUseCounters[aUseCounter]) {
|
||||
mChildDocumentUseCounters[aUseCounter] = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
|
||||
{
|
||||
return mChildDocumentUseCounters[aUseCounter];
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::bitset<eDeprecatedOperationCount> mDeprecationWarnedAbout;
|
||||
mutable std::bitset<eDocumentWarningCount> mDocWarningWarnedAbout;
|
||||
@ -2810,6 +2849,12 @@ protected:
|
||||
// caches.
|
||||
bool mDidDocumentOpen : 1;
|
||||
|
||||
// Whether this document has a display document and thus is considered to
|
||||
// be a resource document. Normally this is the same as !!mDisplayDocument,
|
||||
// but mDisplayDocument is cleared during Unlink. mHasDisplayDocument is
|
||||
// valid in the document's destructor.
|
||||
bool mHasDisplayDocument : 1;
|
||||
|
||||
// Is the current mFontFaceSet valid?
|
||||
bool mFontFaceSetDirty : 1;
|
||||
|
||||
@ -2956,6 +3001,14 @@ protected:
|
||||
|
||||
// Our live MediaQueryLists
|
||||
PRCList mDOMMediaQueryLists;
|
||||
|
||||
// Flags for use counters used directly by this document.
|
||||
std::bitset<mozilla::eUseCounter_Count> mUseCounters;
|
||||
// Flags for use counters used by any child documents of this document.
|
||||
std::bitset<mozilla::eUseCounter_Count> mChildDocumentUseCounters;
|
||||
// Flags for whether we've notified our top-level "page" of a use counter
|
||||
// for this child document.
|
||||
std::bitset<mozilla::eUseCounter_Count> mNotifiedPageForUseCounter;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
|
||||
|
@ -191,6 +191,12 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
|
||||
}
|
||||
|
||||
if (aType == imgINotificationObserver::DECODE_COMPLETE) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
aRequest->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
container->PropagateUseCounters(GetOurOwnerDoc());
|
||||
}
|
||||
|
||||
UpdateImageState(true);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,15 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
file_messagemanager_unload.html
|
||||
file_use_counter_outer.html
|
||||
file_use_counter_svg_getElementById.svg
|
||||
file_use_counter_svg_currentScale.svg
|
||||
file_use_counter_svg_background.html
|
||||
file_use_counter_svg_list_style_image.html
|
||||
file_use_counter_svg_fill_pattern_definition.svg
|
||||
file_use_counter_svg_fill_pattern.svg
|
||||
file_use_counter_svg_fill_pattern_internal.svg
|
||||
file_use_counter_svg_fill_pattern_data.svg
|
||||
|
||||
[browser_bug593387.js]
|
||||
skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.iframe.addEventListener)
|
||||
@ -17,3 +26,4 @@ skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s
|
||||
skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
|
||||
[browser_bug1058164.js]
|
||||
skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
|
||||
[browser_use_counters.js]
|
||||
|
276
dom/base/test/browser_use_counters.js
Normal file
276
dom/base/test/browser_use_counters.js
Normal file
@ -0,0 +1,276 @@
|
||||
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
|
||||
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
|
||||
const gHttpTestRoot = "http://example.com/browser/dom/base/test/";
|
||||
|
||||
/**
|
||||
* Enable local telemetry recording for the duration of the tests.
|
||||
*/
|
||||
let gOldContentCanRecord = false;
|
||||
add_task(function* test_initialize() {
|
||||
gOldContentCanRecord = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
|
||||
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
|
||||
let old = telemetry.canRecordExtended;
|
||||
telemetry.canRecordExtended = true;
|
||||
return old;
|
||||
});
|
||||
info("canRecord for content: " + gOldContentCanRecord);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
// Check that use counters are incremented by SVGs loaded directly in iframes.
|
||||
yield check_use_counter_iframe("file_use_counter_svg_getElementById.svg",
|
||||
"SVGSVGELEMENT_GETELEMENTBYID");
|
||||
yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
|
||||
"SVGSVGELEMENT_CURRENTSCALE_getter");
|
||||
yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
|
||||
"SVGSVGELEMENT_CURRENTSCALE_setter");
|
||||
|
||||
// Check that use counters are incremented by SVGs loaded as images.
|
||||
// Note that SVG images are not permitted to execute script, so we can only
|
||||
// check for properties here.
|
||||
yield check_use_counter_img("file_use_counter_svg_getElementById.svg",
|
||||
"PROPERTY_FILL");
|
||||
yield check_use_counter_img("file_use_counter_svg_currentScale.svg",
|
||||
"PROPERTY_FILL");
|
||||
|
||||
// Check that use counters are incremented by directly loading SVGs
|
||||
// that reference patterns defined in another SVG file.
|
||||
yield check_use_counter_direct("file_use_counter_svg_fill_pattern.svg",
|
||||
"PROPERTY_FILLOPACITY", /*xfail=*/true);
|
||||
|
||||
// Check that use counters are incremented by directly loading SVGs
|
||||
// that reference patterns defined in the same file or in data: URLs.
|
||||
yield check_use_counter_direct("file_use_counter_svg_fill_pattern_internal.svg",
|
||||
"PROPERTY_FILLOPACITY");
|
||||
// data: URLs don't correctly propagate to their referring document yet.
|
||||
//yield check_use_counter_direct("file_use_counter_svg_fill_pattern_data.svg",
|
||||
// "PROPERTY_FILL_OPACITY");
|
||||
|
||||
// Check that use counters are incremented by SVGs loaded as CSS images in
|
||||
// pages loaded in iframes. Again, SVG images in CSS aren't permitted to
|
||||
// execute script, so we need to use properties here.
|
||||
yield check_use_counter_iframe("file_use_counter_svg_background.html",
|
||||
"PROPERTY_FILL");
|
||||
yield check_use_counter_iframe("file_use_counter_svg_list_style_image.html",
|
||||
"PROPERTY_FILL");
|
||||
|
||||
// Check that even loads from the imglib cache update use counters. The
|
||||
// background images should still be there, because we just loaded them
|
||||
// in the last set of tests. But we won't get updated counts for the
|
||||
// document counters, because we won't be re-parsing the SVG documents.
|
||||
yield check_use_counter_iframe("file_use_counter_svg_background.html",
|
||||
"PROPERTY_FILL", false);
|
||||
yield check_use_counter_iframe("file_use_counter_svg_list_style_image.html",
|
||||
"PROPERTY_FILL", false);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, { oldCanRecord: gOldContentCanRecord }, function (arg) {
|
||||
Cu.import("resource://gre/modules/PromiseUtils.jsm");
|
||||
yield new Promise(resolve => {
|
||||
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
|
||||
telemetry.canRecordExtended = arg.oldCanRecord;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function waitForDestroyedDocuments() {
|
||||
let deferred = promise.defer();
|
||||
SpecialPowers.exactGC(window, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForPageLoad(browser) {
|
||||
return ContentTask.spawn(browser, null, function*() {
|
||||
Cu.import("resource://gre/modules/PromiseUtils.jsm");
|
||||
yield new Promise(resolve => {
|
||||
let listener = () => {
|
||||
removeEventListener("load", listener, true);
|
||||
resolve();
|
||||
}
|
||||
addEventListener("load", listener, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function grabHistogramsFromContent(browser, use_counter_middlefix) {
|
||||
return ContentTask.spawn(browser, { middlefix: use_counter_middlefix }, function* (arg) {
|
||||
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
|
||||
function snapshot_histogram(name) {
|
||||
return telemetry.getHistogramById(name).snapshot();
|
||||
}
|
||||
|
||||
let histogram_page_name = "USE_COUNTER_" + arg.middlefix + "_PAGE";
|
||||
let histogram_document_name = "USE_COUNTER_" + arg.middlefix + "_DOCUMENT";
|
||||
let histogram_page = snapshot_histogram(histogram_page_name);
|
||||
let histogram_document = snapshot_histogram(histogram_document_name);
|
||||
return [histogram_page.sum, histogram_document.sum];
|
||||
});
|
||||
}
|
||||
|
||||
let check_use_counter_iframe = Task.async(function* (file, use_counter_middlefix, check_documents=true) {
|
||||
info("checking " + file + " with histogram " + use_counter_middlefix);
|
||||
|
||||
let newTab = gBrowser.addTab( "about:blank");
|
||||
gBrowser.selectedTab = newTab;
|
||||
newTab.linkedBrowser.stop();
|
||||
|
||||
// Hold on to the current values of the telemetry histograms we're
|
||||
// interested in.
|
||||
let [histogram_page_before, histogram_document_before] =
|
||||
yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
|
||||
|
||||
gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html");
|
||||
yield waitForPageLoad(gBrowser.selectedBrowser);
|
||||
|
||||
// Inject our desired file into the iframe of the newly-loaded page.
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) {
|
||||
Cu.import("resource://gre/modules/PromiseUtils.jsm");
|
||||
let deferred = PromiseUtils.defer();
|
||||
|
||||
let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let iframe = content.document.getElementById('content');
|
||||
iframe.src = opts.file;
|
||||
let listener = (event) => {
|
||||
event.target.removeEventListener("load", listener, true);
|
||||
|
||||
// We flush the main document first, then the iframe's document to
|
||||
// ensure any propagation that might happen from child->parent should
|
||||
// have already happened when counters are reported to telemetry.
|
||||
wu.forceUseCounterFlush(content.document);
|
||||
wu.forceUseCounterFlush(iframe.contentDocument);
|
||||
|
||||
deferred.resolve();
|
||||
};
|
||||
iframe.addEventListener("load", listener, true);
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
|
||||
// Tear down the page.
|
||||
gBrowser.removeTab(newTab);
|
||||
|
||||
// The histograms only get recorded when the document actually gets
|
||||
// destroyed, which might not have happened yet due to GC/CC effects, etc.
|
||||
// Try to force document destruction.
|
||||
yield waitForDestroyedDocuments();
|
||||
|
||||
// Grab histograms again and compare.
|
||||
let [histogram_page_after, histogram_document_after] =
|
||||
yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
|
||||
|
||||
is(histogram_page_after, histogram_page_before + 1,
|
||||
"page counts for " + use_counter_middlefix + " after are correct");
|
||||
if (check_documents) {
|
||||
is(histogram_document_after, histogram_document_before + 1,
|
||||
"document counts " + use_counter_middlefix + " after are correct");
|
||||
}
|
||||
});
|
||||
|
||||
let check_use_counter_img = Task.async(function* (file, use_counter_middlefix) {
|
||||
info("checking " + file + " as image with histogram " + use_counter_middlefix);
|
||||
|
||||
let newTab = gBrowser.addTab("about:blank");
|
||||
gBrowser.selectedTab = newTab;
|
||||
newTab.linkedBrowser.stop();
|
||||
|
||||
// Hold on to the current values of the telemetry histograms we're
|
||||
// interested in.
|
||||
let [histogram_page_before, histogram_document_before] =
|
||||
yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
|
||||
|
||||
gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html");
|
||||
yield waitForPageLoad(gBrowser.selectedBrowser);
|
||||
|
||||
// Inject our desired file into the img of the newly-loaded page.
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) {
|
||||
Cu.import("resource://gre/modules/PromiseUtils.jsm");
|
||||
let deferred = PromiseUtils.defer();
|
||||
|
||||
let img = content.document.getElementById('display');
|
||||
img.src = opts.file;
|
||||
let listener = (event) => {
|
||||
img.removeEventListener("load", listener, true);
|
||||
|
||||
// Flush for the image. It matters what order we do these in, so that
|
||||
// the image can propagate its use counters to the document prior to the
|
||||
// document reporting its use counters.
|
||||
let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
wu.forceUseCounterFlush(img);
|
||||
|
||||
// Flush for the main window.
|
||||
wu.forceUseCounterFlush(content.document);
|
||||
|
||||
deferred.resolve();
|
||||
};
|
||||
img.addEventListener("load", listener, true);
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
|
||||
// Tear down the page.
|
||||
gBrowser.removeTab(newTab);
|
||||
|
||||
// The histograms only get recorded when the document actually gets
|
||||
// destroyed, which might not have happened yet due to GC/CC effects, etc.
|
||||
// Try to force document destruction.
|
||||
yield waitForDestroyedDocuments();
|
||||
|
||||
// Grab histograms again and compare.
|
||||
let [histogram_page_after, histogram_document_after] =
|
||||
yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
|
||||
is(histogram_page_after, histogram_page_before + 1,
|
||||
"page counts for " + use_counter_middlefix + " after are correct");
|
||||
is(histogram_document_after, histogram_document_before + 1,
|
||||
"document counts " + use_counter_middlefix + " after are correct");
|
||||
});
|
||||
|
||||
let check_use_counter_direct = Task.async(function* (file, use_counter_middlefix, xfail=false) {
|
||||
info("checking " + file + " with histogram " + use_counter_middlefix);
|
||||
|
||||
let newTab = gBrowser.addTab( "about:blank");
|
||||
gBrowser.selectedTab = newTab;
|
||||
newTab.linkedBrowser.stop();
|
||||
|
||||
// Hold on to the current values of the telemetry histograms we're
|
||||
// interested in.
|
||||
let [histogram_page_before, histogram_document_before] =
|
||||
yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
|
||||
|
||||
gBrowser.selectedBrowser.loadURI(gHttpTestRoot + file);
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
Cu.import("resource://gre/modules/PromiseUtils.jsm");
|
||||
yield new Promise(resolve => {
|
||||
let listener = () => {
|
||||
removeEventListener("load", listener, true);
|
||||
|
||||
let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
wu.forceUseCounterFlush(content.document);
|
||||
|
||||
setTimeout(resolve, 0);
|
||||
}
|
||||
addEventListener("load", listener, true);
|
||||
});
|
||||
});
|
||||
|
||||
// Tear down the page.
|
||||
gBrowser.removeTab(newTab);
|
||||
|
||||
// The histograms only get recorded when the document actually gets
|
||||
// destroyed, which might not have happened yet due to GC/CC effects, etc.
|
||||
// Try to force document destruction.
|
||||
yield waitForDestroyedDocuments();
|
||||
|
||||
// Grab histograms again and compare.
|
||||
let [histogram_page_after, histogram_document_after] =
|
||||
yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
|
||||
(xfail ? todo_is : is)(histogram_page_after, histogram_page_before + 1,
|
||||
"page counts for " + use_counter_middlefix + " after are correct");
|
||||
(xfail ? todo_is : is)(histogram_document_after, histogram_document_before + 1,
|
||||
"document counts " + use_counter_middlefix + " after are correct");
|
||||
});
|
17
dom/base/test/file_use_counter_outer.html
Normal file
17
dom/base/test/file_use_counter_outer.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=968923
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 968923</title>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a>
|
||||
<img id="display" />
|
||||
<iframe id="content">
|
||||
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
22
dom/base/test/file_use_counter_svg_background.html
Normal file
22
dom/base/test/file_use_counter_svg_background.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=968923
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 968923</title>
|
||||
<style>
|
||||
/* Use a query string to work around imagelib caching.
|
||||
Otherwise, we won't get use counters for this file. */
|
||||
body { background-image: url('file_use_counter_svg_getElementById.svg?asbackground=1') }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a>
|
||||
<img id="display" />
|
||||
<iframe id="content" src="about:blank">
|
||||
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
18
dom/base/test/file_use_counter_svg_currentScale.svg
Normal file
18
dom/base/test/file_use_counter_svg_currentScale.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="4in" height="3in" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<desc>Test graphic for hitting currentScale
|
||||
</desc>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
document.documentElement.currentScale = document.documentElement.currentScale;
|
||||
]]>
|
||||
</script>
|
||||
<image id="i1" x="200" y="200" width="100px" height="80px"
|
||||
xlink:href="no-such-scheme:nothing">
|
||||
</image>
|
||||
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
|
||||
</svg>
|
After Width: | Height: | Size: 680 B |
15
dom/base/test/file_use_counter_svg_fill_pattern.svg
Normal file
15
dom/base/test/file_use_counter_svg_fill_pattern.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
|
||||
<!-- Outline the drawing area in blue -->
|
||||
<rect fill="none" stroke="blue"
|
||||
x="1" y="1" width="798" height="398"/>
|
||||
|
||||
<!-- The ellipse is filled using a triangle pattern paint server
|
||||
and stroked with black -->
|
||||
<ellipse fill="url(http://example.com/browser/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg#TrianglePattern)" stroke="black" stroke-width="5"
|
||||
cx="400" cy="200" rx="350" ry="150" />
|
||||
</svg>
|
After Width: | Height: | Size: 763 B |
15
dom/base/test/file_use_counter_svg_fill_pattern_data.svg
Normal file
15
dom/base/test/file_use_counter_svg_fill_pattern_data.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
|
||||
<!-- Outline the drawing area in blue -->
|
||||
<rect fill="none" stroke="blue"
|
||||
x="1" y="1" width="798" height="398"/>
|
||||
|
||||
<!-- The ellipse is filled using a triangle pattern paint server
|
||||
and stroked with black -->
|
||||
<ellipse fill="url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iIAogICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI4Y20iIGhlaWdodD0iNGNtIiB2aWV3Qm94PSIwIDAgODAwIDQwMCIgdmVyc2lvbj0iMS4xIgogICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlc2M+Qm9ycm93ZWQgZnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcvcHNlcnZlcnMuaHRtbDwvZGVzYz4KICA8ZGVmcz4KICAgIDxwYXR0ZXJuIGlkPSJUcmlhbmdsZVBhdHRlcm4iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgICAgICAgICB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIKICAgICAgICAgICAgIHZpZXdCb3g9IjAgMCAxMCAxMCIgPgogICAgICA8cGF0aCBkPSJNIDAgMCBMIDcgMCBMIDMuNSA3IHoiIGZpbGw9InJlZCIgZmlsbC1vcGFjaXR5PSIwLjciIHN0cm9rZT0iYmx1ZSIgLz4KICAgIDwvcGF0dGVybj4gCiAgPC9kZWZzPgo8L3N2Zz4K#TrianglePattern)" stroke="black" stroke-width="5"
|
||||
cx="400" cy="200" rx="350" ry="150" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
|
||||
<defs>
|
||||
<pattern id="TrianglePattern" patternUnits="userSpaceOnUse"
|
||||
x="0" y="0" width="100" height="100"
|
||||
viewBox="0 0 10 10" >
|
||||
<path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" fill-opacity="0.7" stroke="blue" />
|
||||
</pattern>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 591 B |
23
dom/base/test/file_use_counter_svg_fill_pattern_internal.svg
Normal file
23
dom/base/test/file_use_counter_svg_fill_pattern_internal.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
|
||||
<!-- Outline the drawing area in blue -->
|
||||
<rect fill="none" stroke="blue"
|
||||
x="1" y="1" width="798" height="398"/>
|
||||
|
||||
<defs>
|
||||
<pattern id="TrianglePattern" patternUnits="userSpaceOnUse"
|
||||
x="0" y="0" width="100" height="100"
|
||||
viewBox="0 0 10 10" >
|
||||
<path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" fill-opacity="0.7" stroke="blue" />
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<!-- The ellipse is filled using a triangle pattern paint server
|
||||
and stroked with black -->
|
||||
<ellipse fill="url(#TrianglePattern)" stroke="black" stroke-width="5"
|
||||
cx="400" cy="200" rx="350" ry="150" />
|
||||
</svg>
|
After Width: | Height: | Size: 944 B |
23
dom/base/test/file_use_counter_svg_getElementById.svg
Normal file
23
dom/base/test/file_use_counter_svg_getElementById.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="4in" height="3in" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<desc>Test graphic for hitting getElementById
|
||||
</desc>
|
||||
<image id="i1" x="200" y="200" width="100px" height="80px"
|
||||
xlink:href="no-such-scheme:nothing">
|
||||
</image>
|
||||
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
|
||||
<script type="text/javascript"> <![CDATA[
|
||||
var image = document.documentElement.getElementById("i1");
|
||||
image.addEventListener("load",
|
||||
function() {
|
||||
document.documentElement.removeAttribute("class");
|
||||
},
|
||||
false);
|
||||
]]>
|
||||
</script>
|
||||
</svg>
|
After Width: | Height: | Size: 881 B |
22
dom/base/test/file_use_counter_svg_list_style_image.html
Normal file
22
dom/base/test/file_use_counter_svg_list_style_image.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=968923
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 968923</title>
|
||||
<style>
|
||||
/* Use a query string to work around imagelib caching.
|
||||
Otherwise, we won't get use counters for this file. */
|
||||
ul { list-style-image: url('file_use_counter_svg_currentScale.svg?asliststyleimage=1') }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a>
|
||||
<ul>
|
||||
<li>Some text</li>
|
||||
<li>Some other text</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -41,7 +41,7 @@ def read_conf(conf_filename):
|
||||
'interface_name': interface_name,
|
||||
'attribute_name': attribute_name }
|
||||
continue
|
||||
m = re.match(r'property ([a-z0-9-]+)$', line)
|
||||
m = re.match(r'property ([A-Za-z0-9]+)$', line)
|
||||
if m:
|
||||
property_name = m.group(1)
|
||||
yield { 'type': 'property',
|
||||
@ -70,7 +70,9 @@ def generate_histograms(filename):
|
||||
append_counters(method.replace('.', '_').upper(), 'called %s' % method)
|
||||
elif counter['type'] == 'attribute':
|
||||
attr = '%s.%s' % (counter['interface_name'], counter['attribute_name'])
|
||||
append_counters(attr.replace('.', '_').upper(), 'got or set %s' % attr)
|
||||
counter_name = attr.replace('.', '_').upper()
|
||||
append_counters('%s_getter' % counter_name, 'got %s' % attr)
|
||||
append_counters('%s_setter' % counter_name, 'set %s' % attr)
|
||||
elif counter['type'] == 'property':
|
||||
prop = counter['property_name']
|
||||
append_counters('PROPERTY_%s' % prop.replace('-', '_').upper(), "used the '%s' property" % prop)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/UseCounter.h"
|
||||
|
||||
#include "AccessCheck.h"
|
||||
#include "jsfriendapi.h"
|
||||
@ -30,6 +31,7 @@
|
||||
#include "XrayWrapper.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "prprf.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
@ -46,6 +48,7 @@
|
||||
#include "WorkerPrivate.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "ipc/ErrorIPCUtils.h"
|
||||
#include "mozilla/UseCounter.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -3050,5 +3053,15 @@ AssertReflectorHasGivenProto(JSContext* aCx, JSObject* aReflector,
|
||||
} // namespace binding_detail
|
||||
#endif // DEBUG
|
||||
|
||||
void
|
||||
SetDocumentAndPageUseCounter(JSContext* aCx, JSObject* aObject,
|
||||
UseCounter aUseCounter)
|
||||
{
|
||||
nsGlobalWindow* win = xpc::WindowGlobalOrNull(js::UncheckedUnwrap(aObject));
|
||||
if (win && win->GetDocument()) {
|
||||
win->GetDocument()->SetDocumentAndPageUseCounter(aUseCounter);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -42,6 +42,9 @@ class nsIJSID;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
enum UseCounter : int16_t;
|
||||
|
||||
namespace dom {
|
||||
template<typename DataType> class MozMap;
|
||||
|
||||
@ -3317,6 +3320,10 @@ bool
|
||||
GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
|
||||
JS::MutableHandle<JSObject*> aDesiredProto);
|
||||
|
||||
void
|
||||
SetDocumentAndPageUseCounter(JSContext* aCx, JSObject* aObject,
|
||||
UseCounter aUseCounter);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -6836,7 +6836,8 @@ class CGPerSignatureCall(CGThing):
|
||||
|
||||
def __init__(self, returnType, arguments, nativeMethodName, static,
|
||||
descriptor, idlNode, argConversionStartsAt=0, getter=False,
|
||||
setter=False, isConstructor=False, resultVar=None):
|
||||
setter=False, isConstructor=False, useCounterName=None,
|
||||
resultVar=None):
|
||||
assert idlNode.isMethod() == (not getter and not setter)
|
||||
assert idlNode.isAttr() == (getter or setter)
|
||||
# Constructors are always static
|
||||
@ -7047,6 +7048,12 @@ class CGPerSignatureCall(CGThing):
|
||||
self.getArguments(), argsPre, returnType,
|
||||
self.extendedAttributes, descriptor, nativeMethodName,
|
||||
static, argsPost=argsPost, resultVar=resultVar))
|
||||
|
||||
if useCounterName:
|
||||
# Generate a telemetry call for when [UseCounter] is used.
|
||||
code = "SetDocumentAndPageUseCounter(cx, obj, eUseCounter_%s);\n" % useCounterName
|
||||
cgThings.append(CGGeneric(code))
|
||||
|
||||
self.cgRoot = CGList(cgThings)
|
||||
|
||||
def getArguments(self):
|
||||
@ -7211,6 +7218,11 @@ class CGMethodCall(CGThing):
|
||||
methodName = "%s.%s" % (descriptor.interface.identifier.name, method.identifier.name)
|
||||
argDesc = "argument %d of " + methodName
|
||||
|
||||
if method.getExtendedAttribute("UseCounter"):
|
||||
useCounterName = methodName.replace(".", "_")
|
||||
else:
|
||||
useCounterName = None
|
||||
|
||||
def requiredArgCount(signature):
|
||||
arguments = signature[1]
|
||||
if len(arguments) == 0:
|
||||
@ -7225,7 +7237,8 @@ class CGMethodCall(CGThing):
|
||||
nativeMethodName, static, descriptor,
|
||||
method,
|
||||
argConversionStartsAt=argConversionStartsAt,
|
||||
isConstructor=isConstructor)
|
||||
isConstructor=isConstructor,
|
||||
useCounterName=useCounterName)
|
||||
|
||||
def filteredSignatures(signatures, descriptor):
|
||||
def typeExposedInWorkers(type):
|
||||
@ -7630,9 +7643,14 @@ class CGGetterCall(CGPerSignatureCall):
|
||||
getter.
|
||||
"""
|
||||
def __init__(self, returnType, nativeMethodName, descriptor, attr):
|
||||
if attr.getExtendedAttribute("UseCounter"):
|
||||
useCounterName = "%s_%s_getter" % (descriptor.interface.identifier.name,
|
||||
attr.identifier.name)
|
||||
else:
|
||||
useCounterName = None
|
||||
CGPerSignatureCall.__init__(self, returnType, [], nativeMethodName,
|
||||
attr.isStatic(), descriptor, attr,
|
||||
getter=True)
|
||||
getter=True, useCounterName=useCounterName)
|
||||
|
||||
|
||||
class FakeIdentifier():
|
||||
@ -7679,10 +7697,15 @@ class CGSetterCall(CGPerSignatureCall):
|
||||
setter.
|
||||
"""
|
||||
def __init__(self, argType, nativeMethodName, descriptor, attr):
|
||||
if attr.getExtendedAttribute("UseCounter"):
|
||||
useCounterName = "%s_%s_setter" % (descriptor.interface.identifier.name,
|
||||
attr.identifier.name)
|
||||
else:
|
||||
useCounterName = None
|
||||
CGPerSignatureCall.__init__(self, None,
|
||||
[FakeArgument(argType, attr, allowTreatNonCallableAsNull=True)],
|
||||
nativeMethodName, attr.isStatic(),
|
||||
descriptor, attr, setter=True)
|
||||
descriptor, attr, setter=True, useCounterName=useCounterName)
|
||||
|
||||
def wrap_return_value(self):
|
||||
attr = self.idlNode
|
||||
@ -12855,6 +12878,13 @@ class CGBindingRoot(CGThing):
|
||||
bindingHeaders["mozilla/dom/ScriptSettings.h"] = dictionaries # AutoJSAPI
|
||||
bindingHeaders["xpcpublic.h"] = dictionaries # xpc::UnprivilegedJunkScope
|
||||
|
||||
# For things that have [UseCounter]
|
||||
def descriptorRequiresTelemetry(desc):
|
||||
iface = desc.interface
|
||||
return any(m.getExtendedAttribute("UseCounter") for m in iface.members)
|
||||
bindingHeaders["mozilla/UseCounter.h"] = any(
|
||||
descriptorRequiresTelemetry(d) for d in descriptors)
|
||||
|
||||
cgthings.extend(traverseMethods)
|
||||
cgthings.extend(unlinkMethods)
|
||||
|
||||
|
@ -4026,6 +4026,11 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
"readonly attributes" % attr.value(),
|
||||
[attr.location, self.location])
|
||||
self._setDependsOn(attr.value())
|
||||
elif identifier == "UseCounter":
|
||||
if self.stringifier:
|
||||
raise WebIDLError("[UseCounter] must not be used on a "
|
||||
"stringifier attribute",
|
||||
[attr.location, self.location])
|
||||
elif (identifier == "Pref" or
|
||||
identifier == "Deprecated" or
|
||||
identifier == "SetterThrows" or
|
||||
@ -4431,6 +4436,15 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
"""
|
||||
return self.maplikeOrSetlike is not None
|
||||
|
||||
def isSpecial(self):
|
||||
return (self.isGetter() or
|
||||
self.isSetter() or
|
||||
self.isCreator() or
|
||||
self.isDeleter() or
|
||||
self.isLegacycaller() or
|
||||
self.isStringifier() or
|
||||
self.isJsonifier())
|
||||
|
||||
def hasOverloads(self):
|
||||
return self._hasOverloads
|
||||
|
||||
@ -4712,6 +4726,11 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
raise WebIDLError("[Alias] takes an identifier or string",
|
||||
[attr.location])
|
||||
self._addAlias(attr.value())
|
||||
elif identifier == "UseCounter":
|
||||
if self.isSpecial():
|
||||
raise WebIDLError("[UseCounter] must not be used on a special "
|
||||
"operation",
|
||||
[attr.location, self.location])
|
||||
elif (identifier == "Throws" or
|
||||
identifier == "NewObject" or
|
||||
identifier == "ChromeOnly" or
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "mozilla/dom/ChannelInfo.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
@ -18,6 +19,26 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
void
|
||||
ChannelInfo::InitFromDocument(nsIDocument* aDoc)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mInited, "Cannot initialize the object twice");
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfo = aDoc->GetSecurityInfo();
|
||||
if (securityInfo) {
|
||||
SetSecurityInfo(securityInfo);
|
||||
}
|
||||
|
||||
// mRedirected flag and mRedirectedURISpec are only important for maintaining
|
||||
// the channel's redirected status. If the ChannelInfo is initialized from
|
||||
// a document, that document has already asked the channel from which it was
|
||||
// loaded about the current channel URI, so it won't matter if a future
|
||||
// ResurrectInfoOnChannel() call misses whether the channel was redirected.
|
||||
mRedirected = false;
|
||||
mInited = true;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelInfo::InitFromChannel(nsIChannel* aChannel)
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIChannel;
|
||||
class nsIDocument;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
@ -66,6 +67,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void InitFromDocument(nsIDocument* aDoc);
|
||||
void InitFromChannel(nsIChannel* aChannel);
|
||||
void InitFromIPCChannelInfo(const IPCChannelInfo& aChannelInfo);
|
||||
|
||||
|
@ -159,6 +159,22 @@ Response::Constructor(const GlobalObject& aGlobal,
|
||||
nsRefPtr<InternalResponse> internalResponse =
|
||||
new InternalResponse(aInit.mStatus, statusText);
|
||||
|
||||
// Grab a valid channel info from the global so this response is 'valid' for
|
||||
// interception.
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global);
|
||||
MOZ_ASSERT(window);
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
ChannelInfo info;
|
||||
info.InitFromDocument(doc);
|
||||
internalResponse->InitChannelInfo(info);
|
||||
} else {
|
||||
workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(worker);
|
||||
internalResponse->InitChannelInfo(worker->GetChannelInfo());
|
||||
}
|
||||
|
||||
nsRefPtr<Response> r = new Response(global, internalResponse);
|
||||
|
||||
if (aInit.mHeaders.WasPassed()) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsIScriptContext.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include "mozilla/dom/HTMLFormElement.h"
|
||||
#include "nsAttrValueOrString.h"
|
||||
#include "imgLoader.h"
|
||||
#include "Image.h"
|
||||
|
||||
// Responsive images!
|
||||
#include "mozilla/dom/HTMLSourceElement.h"
|
||||
@ -1301,6 +1303,18 @@ HTMLImageElement::MediaFeatureValuesChanged()
|
||||
QueueImageLoadTask();
|
||||
}
|
||||
|
||||
void
|
||||
HTMLImageElement::FlushUseCounters()
|
||||
{
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
GetRequest(CURRENT_REQUEST, getter_AddRefs(request));
|
||||
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
request->GetImage(getter_AddRefs(container));
|
||||
|
||||
static_cast<image::Image*>(container.get())->ReportUseCounters();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -265,6 +265,12 @@ public:
|
||||
const nsAString& aMediaAttr,
|
||||
nsAString& aResult);
|
||||
|
||||
/**
|
||||
* If this image's src pointers to an SVG document, flush the SVG document's
|
||||
* use counters to telemetry. Only used for testing purposes.
|
||||
*/
|
||||
void FlushUseCounters();
|
||||
|
||||
protected:
|
||||
virtual ~HTMLImageElement();
|
||||
|
||||
|
@ -236,6 +236,7 @@ LOCAL_INCLUDES += [
|
||||
'/dom/xul',
|
||||
'/editor/libeditor',
|
||||
'/editor/txmgr',
|
||||
'/image',
|
||||
'/layout/forms',
|
||||
'/layout/generic',
|
||||
'/layout/style',
|
||||
|
@ -6,13 +6,16 @@ const nsIQuotaManager = Components.interfaces.nsIQuotaManager;
|
||||
|
||||
let gURI = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI("http://localhost", null, null);
|
||||
|
||||
function onUsageCallback(uri, usage, fileUsage) {}
|
||||
function onUsageCallback(principal, usage, fileUsage) {}
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"]
|
||||
.getService(nsIQuotaManager);
|
||||
var quotaRequest = quotaManager.getUsageForURI(gURI, onUsageCallback);
|
||||
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Components.interfaces.nsIScriptSecurityManager)
|
||||
.createCodebasePrincipal(gURI, {});
|
||||
var quotaRequest = quotaManager.getUsageForPrincipal(principal, onUsageCallback);
|
||||
quotaRequest.cancel();
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService)
|
||||
|
@ -92,7 +92,7 @@ function testSteps()
|
||||
|
||||
let usageBeforeMaintenance;
|
||||
|
||||
quotaManager.getUsageForURI(uri, (url, usage) => {
|
||||
quotaManager.getUsageForPrincipal(principal, (principal, usage) => {
|
||||
ok(usage > 0, "Usage is non-zero");
|
||||
usageBeforeMaintenance = usage;
|
||||
continueToNextStep();
|
||||
@ -118,7 +118,7 @@ function testSteps()
|
||||
|
||||
let usageAfterMaintenance;
|
||||
|
||||
quotaManager.getUsageForURI(uri, (url, usage) => {
|
||||
quotaManager.getUsageForPrincipal(principal, (principal, usage) => {
|
||||
ok(usage > 0, "Usage is non-zero");
|
||||
usageAfterMaintenance = usage;
|
||||
continueToNextStep();
|
||||
|
@ -259,7 +259,10 @@ function resetOrClearAllDatabases(callback, clear) {
|
||||
let uri = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI("http://foo.com", null, null);
|
||||
quotaManager.getUsageForURI(uri, function(usage, fileUsage) {
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.createCodebasePrincipal(uri, {});
|
||||
quotaManager.getUsageForPrincipal(principal, function(principal, usage, fileUsage) {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ interface nsIJSRAIIHelper;
|
||||
interface nsIContentPermissionRequest;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(47fa312b-2ad1-4b80-8a0a-c9822e2d1ec9)]
|
||||
[scriptable, uuid(6ddc9a79-18cd-4dbc-9975-68928e6c9857)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1625,19 +1625,6 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
|
||||
|
||||
/**
|
||||
* Set margins for the layout of fixed position elements in the content
|
||||
* document. These are used on mobile, where the viewable area can be
|
||||
* temporarily obscured by the browser chrome. In this situation, we're ok
|
||||
* with scrollable page content being obscured, but fixed position content
|
||||
* cannot be revealed without removing the obscuring chrome, so we use these
|
||||
* margins so that it can remain visible.
|
||||
*
|
||||
* The caller of this method must have chrome privileges.
|
||||
*/
|
||||
void setContentDocumentFixedPositionMargins(in float aTop, in float aRight,
|
||||
in float aBottom, in float aLeft);
|
||||
|
||||
/**
|
||||
* These are used to control whether dialogs (alert, prompt, confirm) are
|
||||
* allowed.
|
||||
@ -1847,6 +1834,19 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
* @param aSheetType One of the nsIStyleSheetService.*_SHEET constants.
|
||||
*/
|
||||
bool hasRuleProcessorUsedByMultipleStyleSets(in unsigned long aSheetType);
|
||||
|
||||
/*
|
||||
* Force the use counters for the node's associated document(s) to be
|
||||
* flushed to telemetry. For example, a document node will flush its own
|
||||
* counters and an image node with an SVG source will flush the SVG
|
||||
* document's counters. Normally, use counters are flushed to telemetry
|
||||
* upon document destruction, but as document destruction is somewhat
|
||||
* non-deterministic, we have this method here for more determinism when
|
||||
* running tests.
|
||||
*/
|
||||
void forceUseCounterFlush(in nsIDOMNode aNode);
|
||||
|
||||
void setNextPaintSyncId(in long aSyncId);
|
||||
};
|
||||
|
||||
[scriptable, uuid(c694e359-7227-4392-a138-33c0cc1f15a6)]
|
||||
|
@ -380,6 +380,7 @@ MP3TrackDemuxer::Duration(int64_t aNumFrames) const {
|
||||
MediaByteRange
|
||||
MP3TrackDemuxer::FindNextFrame() {
|
||||
static const int BUFFER_SIZE = 4096;
|
||||
static const int MAX_SKIPPED_BYTES = 10 * BUFFER_SIZE;
|
||||
|
||||
MP3DEMUXER_LOGV("FindNext() Begin mOffset=%" PRIu64 " mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64
|
||||
@ -393,8 +394,13 @@ MP3TrackDemuxer::FindNextFrame() {
|
||||
const uint8_t* frameBeg = nullptr;
|
||||
const uint8_t* bufferEnd = nullptr;
|
||||
|
||||
while (frameBeg == bufferEnd &&
|
||||
(read = Read(buffer, mOffset, BUFFER_SIZE)) > 0) {
|
||||
while (frameBeg == bufferEnd) {
|
||||
if ((!mParser.FirstFrame().Length() &&
|
||||
mOffset - mParser.ID3Header().Size() > MAX_SKIPPED_BYTES) ||
|
||||
(read = Read(buffer, mOffset, BUFFER_SIZE)) == 0) {
|
||||
// This is not a valid MPEG audio stream or we've reached EOS, give up.
|
||||
break;
|
||||
}
|
||||
MOZ_ASSERT(mOffset + read > mOffset);
|
||||
mOffset += read;
|
||||
bufferEnd = buffer + read;
|
||||
|
@ -132,8 +132,6 @@ MediaDecoder::InitStatics()
|
||||
|
||||
// Log modules.
|
||||
gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
|
||||
gMozPromiseLog = PR_NewLogModule("MozPromise");
|
||||
gStateWatchingLog = PR_NewLogModule("StateWatching");
|
||||
gMediaTimerLog = PR_NewLogModule("MediaTimer");
|
||||
gMediaSampleLog = PR_NewLogModule("MediaSample");
|
||||
}
|
||||
|
@ -152,8 +152,6 @@ EXPORTS += [
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'MediaManager.h',
|
||||
'StateMirroring.h',
|
||||
'StateWatching.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.media.webrtc += [
|
||||
|
@ -44,6 +44,7 @@ using layers::ImageContainer;
|
||||
using layers::D3D9SurfaceImage;
|
||||
using layers::D3D9RecycleAllocator;
|
||||
using layers::D3D11ShareHandleImage;
|
||||
using layers::D3D11RecycleAllocator;
|
||||
|
||||
class D3D9DXVA2Manager : public DXVA2Manager
|
||||
{
|
||||
@ -71,6 +72,7 @@ private:
|
||||
RefPtr<D3D9RecycleAllocator> mTextureClientAllocator;
|
||||
nsRefPtr<IDirectXVideoDecoderService> mDecoderService;
|
||||
UINT32 mResetToken;
|
||||
bool mFirstFrame;
|
||||
};
|
||||
|
||||
void GetDXVA2ExtendedFormatFromMFMediaType(IMFMediaType *pType,
|
||||
@ -178,6 +180,7 @@ D3D9DXVA2Manager::SupportsConfig(IMFMediaType* aType)
|
||||
|
||||
D3D9DXVA2Manager::D3D9DXVA2Manager()
|
||||
: mResetToken(0)
|
||||
, mFirstFrame(true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(D3D9DXVA2Manager);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -350,7 +353,8 @@ D3D9DXVA2Manager::CopyToImage(IMFSample* aSample,
|
||||
"Wrong format?");
|
||||
|
||||
D3D9SurfaceImage* videoImage = static_cast<D3D9SurfaceImage*>(image.get());
|
||||
hr = videoImage->SetData(D3D9SurfaceImage::Data(surface, aRegion, mTextureClientAllocator));
|
||||
hr = videoImage->SetData(D3D9SurfaceImage::Data(surface, aRegion, mTextureClientAllocator, mFirstFrame));
|
||||
mFirstFrame = false;
|
||||
|
||||
image.forget(aOutImage);
|
||||
|
||||
@ -412,12 +416,13 @@ private:
|
||||
HRESULT CreateFormatConverter();
|
||||
|
||||
HRESULT CreateOutputSample(RefPtr<IMFSample>& aSample,
|
||||
RefPtr<ID3D11Texture2D>& aTexture);
|
||||
ID3D11Texture2D* aTexture);
|
||||
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
RefPtr<IMFDXGIDeviceManager> mDXGIDeviceManager;
|
||||
RefPtr<MFTDecoder> mTransform;
|
||||
RefPtr<D3D11RecycleAllocator> mTextureClientAllocator;
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
UINT mDeviceManagerToken;
|
||||
@ -483,41 +488,27 @@ D3D11DXVA2Manager::Init(nsACString& aFailureReason)
|
||||
return hr;
|
||||
}
|
||||
|
||||
mTextureClientAllocator = new D3D11RecycleAllocator(layers::ImageBridgeChild::GetSingleton(),
|
||||
mDevice);
|
||||
mTextureClientAllocator->SetMaxPoolSize(5);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
D3D11DXVA2Manager::CreateOutputSample(RefPtr<IMFSample>& aSample, RefPtr<ID3D11Texture2D>& aTexture)
|
||||
D3D11DXVA2Manager::CreateOutputSample(RefPtr<IMFSample>& aSample, ID3D11Texture2D* aTexture)
|
||||
{
|
||||
RefPtr<IMFSample> sample;
|
||||
HRESULT hr = wmf::MFCreateSample(byRef(sample));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
desc.Width = mWidth;
|
||||
desc.Height = mHeight;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(texture));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
RefPtr<IMFMediaBuffer> buffer;
|
||||
hr = wmf::MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), texture, 0, FALSE, byRef(buffer));
|
||||
hr = wmf::MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), aTexture, 0, FALSE, byRef(buffer));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
sample->AddBuffer(buffer);
|
||||
|
||||
aSample = sample;
|
||||
aTexture = texture;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -535,11 +526,23 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
||||
// to create a copy of that frame as a sharable resource, save its share
|
||||
// handle, and put that handle into the rendering pipeline.
|
||||
|
||||
HRESULT hr = mTransform->Input(aVideoSample);
|
||||
ImageFormat format = ImageFormat::D3D11_SHARE_HANDLE_TEXTURE;
|
||||
nsRefPtr<Image> image(aContainer->CreateImage(format));
|
||||
NS_ENSURE_TRUE(image, E_FAIL);
|
||||
NS_ASSERTION(image->GetFormat() == ImageFormat::D3D11_SHARE_HANDLE_TEXTURE,
|
||||
"Wrong format?");
|
||||
|
||||
D3D11ShareHandleImage* videoImage = static_cast<D3D11ShareHandleImage*>(image.get());
|
||||
HRESULT hr = videoImage->SetData(D3D11ShareHandleImage::Data(mTextureClientAllocator,
|
||||
gfx::IntSize(mWidth, mHeight),
|
||||
aRegion));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = mTransform->Input(aVideoSample);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
RefPtr<IMFSample> sample;
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
RefPtr<ID3D11Texture2D> texture = videoImage->GetTexture();
|
||||
hr = CreateOutputSample(sample, texture);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
@ -555,16 +558,6 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
||||
keyedMutex->ReleaseSync(0);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
ImageFormat format = ImageFormat::D3D11_SHARE_HANDLE_TEXTURE;
|
||||
nsRefPtr<Image> image(aContainer->CreateImage(format));
|
||||
NS_ENSURE_TRUE(image, E_FAIL);
|
||||
NS_ASSERTION(image->GetFormat() == ImageFormat::D3D11_SHARE_HANDLE_TEXTURE,
|
||||
"Wrong format?");
|
||||
|
||||
D3D11ShareHandleImage* videoImage = static_cast<D3D11ShareHandleImage*>(image.get());
|
||||
hr = videoImage->SetData(D3D11ShareHandleImage::Data(texture, mDevice, mContext, aRegion));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
image.forget(aOutImage);
|
||||
|
||||
return S_OK;
|
||||
|
@ -36,7 +36,7 @@ interface nsIClearSiteDataCallback : nsISupports
|
||||
void callback(in nsresult rv);
|
||||
};
|
||||
|
||||
[scriptable, uuid(50677599-323f-4c7d-a450-307bdb7acbf0)]
|
||||
[scriptable, uuid(0f73bbd2-fc89-41df-b31b-38c09903d187)]
|
||||
interface nsIPluginHost : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -193,10 +193,4 @@ interface nsIPluginHost : nsISupports
|
||||
* passed in the FakePluginTagInit when registering.
|
||||
*/
|
||||
void unregisterFakePlugin(in AUTF8String handlerURI);
|
||||
|
||||
/**
|
||||
* Returns true if plugins with the given mimetype will run out of process.
|
||||
*/
|
||||
boolean isPluginOOP(in AUTF8String aMimeType);
|
||||
};
|
||||
|
||||
|
@ -249,157 +249,6 @@ nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
|
||||
host->PluginCrashed(this, pluginDumpID, browserDumpID);
|
||||
}
|
||||
|
||||
bool
|
||||
nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
|
||||
{
|
||||
if (XRE_IsContentProcess()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
// We force OOP on Linux/GTK3 because some plugins use GTK2 and both GTK
|
||||
// libraries can't be loaded in the same process.
|
||||
return true;
|
||||
#else
|
||||
if (PR_GetEnv("MOZ_DISABLE_OOP_PLUGINS")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aPluginTag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
// Certain assistive technologies don't want oop Flash, thus we have a special
|
||||
// pref for them to disable oop Flash (refer to bug 785047 for details).
|
||||
bool useA11yPref = false;
|
||||
#ifdef XP_WIN
|
||||
useA11yPref = a11y::Compatibility::IsJAWS();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
// On Windows Vista+, we force Flash to run in OOPP mode because Adobe
|
||||
// doesn't test Flash in-process and there are known stability bugs.
|
||||
if (aPluginTag->mIsFlashPlugin && IsVistaOrLater()) {
|
||||
#ifdef ACCESSIBILITY
|
||||
if (!useA11yPref)
|
||||
return true;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
nsIPrefBranch* prefs = Preferences::GetRootBranch();
|
||||
if (!prefs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get per-library whitelist/blacklist pref string
|
||||
// "dom.ipc.plugins.enabled.filename.dll" and fall back to the default value
|
||||
// of "dom.ipc.plugins.enabled"
|
||||
// The "filename.dll" part can contain shell wildcard pattern
|
||||
|
||||
nsAutoCString prefFile(aPluginTag->mFullPath.get());
|
||||
int32_t slashPos = prefFile.RFindCharInSet("/\\");
|
||||
if (kNotFound == slashPos)
|
||||
return false;
|
||||
prefFile.Cut(0, slashPos + 1);
|
||||
ToLowerCase(prefFile);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#if defined(__i386__)
|
||||
nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.i386.");
|
||||
#elif defined(__x86_64__)
|
||||
nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.x86_64.");
|
||||
#elif defined(__ppc__)
|
||||
nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.ppc.");
|
||||
#endif
|
||||
#else
|
||||
nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.");
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
if (useA11yPref)
|
||||
prefGroupKey.AssignLiteral("dom.ipc.plugins.enabled.a11y.");
|
||||
#endif
|
||||
|
||||
if (BrowserTabsRemoteAutostart()) {
|
||||
// dom.ipc.plugins.java.enabled is obsolete in Nightly w/e10s, we've
|
||||
// flipped the default to ON and now have a force-disable pref. This
|
||||
// way we don't break non-e10s browsers.
|
||||
if (aPluginTag->mIsJavaPlugin &&
|
||||
Preferences::GetBool("dom.ipc.plugins.java.force-disable", false)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Java plugins include a number of different file names,
|
||||
// so use the mime type (mIsJavaPlugin) and a special pref.
|
||||
if (aPluginTag->mIsJavaPlugin &&
|
||||
!Preferences::GetBool("dom.ipc.plugins.java.enabled", true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t prefCount;
|
||||
char** prefNames;
|
||||
nsresult rv = prefs->GetChildList(prefGroupKey.get(),
|
||||
&prefCount, &prefNames);
|
||||
|
||||
bool oopPluginsEnabled = false;
|
||||
bool prefSet = false;
|
||||
|
||||
if (NS_SUCCEEDED(rv) && prefCount > 0) {
|
||||
uint32_t prefixLength = prefGroupKey.Length();
|
||||
for (uint32_t currentPref = 0; currentPref < prefCount; currentPref++) {
|
||||
// Get the mask
|
||||
const char* maskStart = prefNames[currentPref] + prefixLength;
|
||||
bool match = false;
|
||||
|
||||
int valid = NS_WildCardValid(maskStart);
|
||||
if (valid == INVALID_SXP) {
|
||||
continue;
|
||||
}
|
||||
else if(valid == NON_SXP) {
|
||||
// mask is not a shell pattern, compare it as normal string
|
||||
match = (strcmp(prefFile.get(), maskStart) == 0);
|
||||
}
|
||||
else {
|
||||
match = (NS_WildCardMatch(prefFile.get(), maskStart, 0) == MATCH);
|
||||
}
|
||||
|
||||
if (match && NS_SUCCEEDED(Preferences::GetBool(prefNames[currentPref],
|
||||
&oopPluginsEnabled))) {
|
||||
prefSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
|
||||
}
|
||||
|
||||
if (!prefSet) {
|
||||
oopPluginsEnabled =
|
||||
#ifdef XP_MACOSX
|
||||
#if defined(__i386__)
|
||||
Preferences::GetBool("dom.ipc.plugins.enabled.i386", false);
|
||||
#elif defined(__x86_64__)
|
||||
Preferences::GetBool("dom.ipc.plugins.enabled.x86_64", false);
|
||||
#elif defined(__ppc__)
|
||||
Preferences::GetBool("dom.ipc.plugins.enabled.ppc", false);
|
||||
#endif
|
||||
#else
|
||||
#ifdef ACCESSIBILITY
|
||||
useA11yPref ? Preferences::GetBool("dom.ipc.plugins.enabled.a11y", false) :
|
||||
#endif
|
||||
Preferences::GetBool("dom.ipc.plugins.enabled", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
return oopPluginsEnabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline PluginLibrary*
|
||||
GetNewPluginLibrary(nsPluginTag *aPluginTag)
|
||||
{
|
||||
@ -411,10 +260,7 @@ GetNewPluginLibrary(nsPluginTag *aPluginTag)
|
||||
return PluginModuleContentParent::LoadModule(aPluginTag->mId);
|
||||
}
|
||||
|
||||
if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
|
||||
return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
|
||||
}
|
||||
return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
|
||||
return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
|
||||
}
|
||||
|
||||
// Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
|
||||
|
@ -52,8 +52,6 @@ public:
|
||||
// minidump was written.
|
||||
void PluginCrashed(const nsAString& pluginDumpID,
|
||||
const nsAString& browserDumpID);
|
||||
|
||||
static bool RunPluginOOP(const nsPluginTag *aPluginTag);
|
||||
|
||||
nsresult Shutdown();
|
||||
|
||||
|
@ -1100,18 +1100,6 @@ nsPluginHost::GetBlocklistStateForType(const nsACString &aMimeType,
|
||||
return tag->GetBlocklistState(aState);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginHost::IsPluginOOP(const nsACString& aMimeType,
|
||||
bool* aResult)
|
||||
{
|
||||
nsPluginTag* tag = FindNativePluginForType(aMimeType, true);
|
||||
if (!tag) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
*aResult = nsNPAPIPlugin::RunPluginOOP(tag);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType,
|
||||
uint32_t aExcludeFlags,
|
||||
@ -1342,35 +1330,11 @@ nsPluginHost::FindNativePluginForExtension(const nsACString & aExtension,
|
||||
return preferredPlugin;
|
||||
}
|
||||
|
||||
static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag,
|
||||
nsNPAPIPlugin **aOutNPAPIPlugin)
|
||||
{
|
||||
// If this is an in-process plugin we'll need to load it here if we haven't already.
|
||||
if (!nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
|
||||
if (aPluginTag->mFullPath.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
file->InitWithPath(NS_ConvertUTF8toUTF16(aPluginTag->mFullPath));
|
||||
nsPluginFile pluginFile(file);
|
||||
PRLibrary* pluginLibrary = nullptr;
|
||||
|
||||
if (NS_FAILED(pluginFile.LoadPlugin(&pluginLibrary)) || !pluginLibrary)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
aPluginTag->mLibrary = pluginLibrary;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsPluginHost::EnsurePluginLoaded(nsPluginTag* aPluginTag)
|
||||
{
|
||||
nsRefPtr<nsNPAPIPlugin> plugin = aPluginTag->mPlugin;
|
||||
if (!plugin) {
|
||||
nsresult rv = CreateNPAPIPlugin(aPluginTag, getter_AddRefs(plugin));
|
||||
nsresult rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, getter_AddRefs(plugin));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -2320,14 +2284,6 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||
*aPluginsChanged = true;
|
||||
}
|
||||
|
||||
// Avoid adding different versions of the same plugin if they are running
|
||||
// in-process, otherwise we risk undefined behaviour.
|
||||
if (!nsNPAPIPlugin::RunPluginOOP(pluginTag)) {
|
||||
if (HaveSamePlugin(pluginTag)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't add the same plugin again if it hasn't changed
|
||||
if (nsPluginTag* duplicate = FirstPluginWithPath(pluginTag->mFullPath)) {
|
||||
if (pluginTag->mLastModifiedTime == duplicate->mLastModifiedTime) {
|
||||
@ -2738,12 +2694,6 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
|
||||
/// to be more sane and avoid this dance
|
||||
nsPluginTag *tag = static_cast<nsPluginTag *>(basetag.get());
|
||||
|
||||
if (!nsNPAPIPlugin::RunPluginOOP(tag)) {
|
||||
// Don't expose non-OOP plugins to content processes since we have no way
|
||||
// to bridge them over.
|
||||
continue;
|
||||
}
|
||||
|
||||
aPlugins->AppendElement(PluginTag(tag->mId,
|
||||
tag->Name(),
|
||||
tag->Description(),
|
||||
|
@ -8,7 +8,7 @@ load 570884.html
|
||||
# the X server, which is a bad assumption for <browser remote>.
|
||||
# Plugin arch is going to change anyway with OOP content so skipping
|
||||
# this test for now is OK.
|
||||
skip-if(browserIsRemote||!haveTestPlugin||http.platform!="X11"||!testPluginIsOOP()) load 598862.html
|
||||
skip-if(browserIsRemote||!haveTestPlugin||http.platform!="X11") load 598862.html
|
||||
|
||||
# SkiaGL is causing a compositor hang here, disable temporarily while that gets resolved in bug 908363
|
||||
skip-if(Android) load 626602-1.html
|
||||
|
@ -11,12 +11,6 @@
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.expectChildProcessCrash();
|
||||
|
||||
crashAndGetCrashServiceRecord("crash", function (cm, crash) {
|
||||
|
@ -11,12 +11,6 @@
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.expectChildProcessCrash();
|
||||
|
||||
// the default timeout is annoying high for mochitest runs
|
||||
|
@ -15,18 +15,11 @@
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
function start() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
if (navigator.platform.startsWith("Win")) {
|
||||
SimpleTest.expectAssertions(0, 350);
|
||||
}
|
||||
else {
|
||||
if (navigator.platform.startsWith("Win")) {
|
||||
SimpleTest.expectAssertions(0, 350);
|
||||
}
|
||||
|
||||
setTimeout(checkGCRace, 1000);
|
||||
}
|
||||
setTimeout(checkGCRace, 1000);
|
||||
}
|
||||
|
||||
var nested = false;
|
||||
|
@ -22,12 +22,6 @@
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Default plugin hang timeout is too high for mochitests
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefBranch);
|
||||
|
@ -9,12 +9,6 @@
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var iframe = document.getElementById('iframe1');
|
||||
var p = iframe.contentDocument.getElementById('plugin1');
|
||||
|
||||
|
@ -88,16 +88,10 @@ function onPluginCrashed(aEvent) {
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService);
|
||||
os.addObserver(testObserver, "plugin-crashed", true);
|
||||
|
||||
|
||||
document.addEventListener("PluginCrashed", onPluginCrashed, false);
|
||||
|
||||
var pluginElement = document.getElementById("plugin1");
|
||||
|
@ -91,11 +91,6 @@ function onPluginCrashed(aEvent) {
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
// the test harness will have set MOZ_CRASHREPORTER_NO_REPORT,
|
||||
// ensure that we can change the setting and have our minidumps
|
||||
// wind up in Crash Reports/pending
|
||||
@ -106,7 +101,7 @@ function runTests() {
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService);
|
||||
os.addObserver(testObserver, "plugin-crashed", true);
|
||||
|
||||
|
||||
document.addEventListener("PluginCrashed", onPluginCrashed, false);
|
||||
|
||||
var pluginElement = document.getElementById("plugin1");
|
||||
|
@ -123,12 +123,6 @@ function onPluginCrashed(aEvent) {
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
todo(false, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// the test harness will have set MOZ_CRASHREPORTER_NO_REPORT,
|
||||
// ensure that we can change the setting and have our minidumps
|
||||
// wind up in Crash Reports/pending
|
||||
@ -142,7 +136,7 @@ function runTests() {
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService);
|
||||
os.addObserver(testObserver, "crash-report-status", true);
|
||||
|
||||
|
||||
document.addEventListener("PluginCrashed", onPluginCrashed, false);
|
||||
|
||||
var pluginElement = document.getElementById("plugin1");
|
||||
|
@ -9,12 +9,6 @@
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.expectChildProcessCrash();
|
||||
|
||||
var iframe = document.getElementById('iframe1');
|
||||
|
@ -13,12 +13,6 @@
|
||||
var iframe = document.getElementById('iframe1');
|
||||
|
||||
function mainLoaded() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.expectChildProcessCrash();
|
||||
|
||||
var p = iframe.contentDocument.createElement('embed');
|
||||
|
@ -130,12 +130,6 @@ function onPluginCrashed(aEvent) {
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
todo(false, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Default plugin hang timeout is too high for mochitests
|
||||
Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", 1);
|
||||
|
||||
|
@ -9,12 +9,6 @@
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.expectChildProcessCrash();
|
||||
|
||||
// the default timeout is annoying high for mochitest runs
|
||||
|
@ -96,11 +96,6 @@ function finishTest() {
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
resetVars();
|
||||
|
||||
hanguiOperation("Prime ChromeWorker", 0, false, false, HANGUIOP_NOTHING, 0,
|
||||
|
@ -22,12 +22,6 @@
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTests() {
|
||||
if (!SimpleTest.testPluginIsOOP()) {
|
||||
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Default plugin hang timeout is too high for mochitests
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefBranch);
|
||||
|
@ -21,11 +21,9 @@
|
||||
var didPaint = function() {};
|
||||
|
||||
function startTest() {
|
||||
if (SimpleTest.testPluginIsOOP()) {
|
||||
if (p.getPaintCount() < 1) {
|
||||
setTimeout(startTest, 0);
|
||||
return;
|
||||
}
|
||||
if (p.getPaintCount() < 1) {
|
||||
setTimeout(startTest, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
didPaint = function() {
|
||||
|
@ -1,16 +1,7 @@
|
||||
function paintCountIs(plugin, expected, msg) {
|
||||
var count = plugin.getPaintCount();
|
||||
var realExpected = expected;
|
||||
var isAsync = SimpleTest.testPluginIsOOP();
|
||||
if (isAsync) {
|
||||
++realExpected; // extra paint at startup for all async-rendering plugins
|
||||
} else {
|
||||
try {
|
||||
if (SpecialPowers.Cc["@mozilla.org/gfx/info;1"].getService(SpecialPowers.Ci.nsIGfxInfo).D2DEnabled) {
|
||||
realExpected *= 2;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
++realExpected; // extra paint at startup for all async-rendering plugins
|
||||
ok(realExpected == count, msg + " (expected " + expected +
|
||||
" independent paints, expected " + realExpected + " logged paints, got " +
|
||||
count + " actual paints)");
|
||||
|
@ -8,8 +8,8 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) =
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-2.html border-padding-2-ref.html # bug 629430
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(!haveTestPlugin) skip-if(Android||B2G) == border-padding-3.html border-padding-3-ref.html # bug 629430 # bug 773482
|
||||
# The following two "pluginproblemui-direction" tests are unreliable on all platforms. They should be re-written or replaced.
|
||||
#random-if(cocoaWidget||d2d||/^Windows\x20NT\x205\.1/.test(http.oscpu)) fails-if(!haveTestPlugin&&!Android) skip-if(!testPluginIsOOP()) == pluginproblemui-direction-1.html pluginproblemui-direction-1-ref.html # bug 567367
|
||||
#random-if(cocoaWidget) fails-if(!haveTestPlugin&&!Android) skip-if(!testPluginIsOOP()) == pluginproblemui-direction-2.html pluginproblemui-direction-2-ref.html
|
||||
#random-if(cocoaWidget||d2d||/^Windows\x20NT\x205\.1/.test(http.oscpu)) fails-if(!haveTestPlugin&&!Android) == pluginproblemui-direction-1.html pluginproblemui-direction-1-ref.html # bug 567367
|
||||
#random-if(cocoaWidget) fails-if(!haveTestPlugin&&!Android) == pluginproblemui-direction-2.html pluginproblemui-direction-2-ref.html
|
||||
fails-if(!haveTestPlugin) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
|
||||
fails-if(!haveTestPlugin) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <algorithm>
|
||||
#include "GeckoProfiler.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/dom/PContent.h"
|
||||
#include "mozilla/dom/asmjscache/AsmJSCache.h"
|
||||
@ -669,20 +670,16 @@ class GetUsageOp
|
||||
UsageInfo mUsageInfo;
|
||||
|
||||
const nsCString mGroup;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIUsageCallback> mCallback;
|
||||
const uint32_t mAppId;
|
||||
const bool mIsApp;
|
||||
const bool mInMozBrowserOnly;
|
||||
|
||||
public:
|
||||
GetUsageOp(const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
bool aIsApp,
|
||||
nsIURI* aURI,
|
||||
nsIUsageCallback* aCallback,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowserOnly);
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIUsageCallback* aCallback);
|
||||
|
||||
private:
|
||||
~GetUsageOp()
|
||||
@ -3404,32 +3401,6 @@ QuotaManager::GetStorageId(PersistenceType aPersistenceType,
|
||||
aDatabaseId = str;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
QuotaManager::GetInfoFromURI(nsIURI* aURI,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsACString* aGroup,
|
||||
nsACString* aOrigin,
|
||||
bool* aIsApp)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = secMan->GetAppCodebasePrincipal(aURI, aAppId, aInMozBrowser,
|
||||
getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetInfoFromPrincipal(principal, aGroup, aOrigin, aIsApp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
TryGetInfoForAboutURI(nsIPrincipal* aPrincipal,
|
||||
nsACString& aGroup,
|
||||
@ -3709,36 +3680,27 @@ QuotaManager::GetDirectoryMetadata(nsIFile* aDirectory,
|
||||
NS_IMPL_ISUPPORTS(QuotaManager, nsIQuotaManager, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManager::GetUsageForURI(nsIURI* aURI,
|
||||
nsIUsageCallback* aCallback,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowserOnly,
|
||||
uint8_t aOptionalArgCount,
|
||||
nsIQuotaRequest** _retval)
|
||||
QuotaManager::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsIUsageCallback* aCallback,
|
||||
nsIQuotaRequest** _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aPrincipal);
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
|
||||
// This only works from the main process.
|
||||
NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
if (!aOptionalArgCount) {
|
||||
aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
}
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString group;
|
||||
nsCString origin;
|
||||
bool isApp;
|
||||
nsresult rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, &group, &origin,
|
||||
&isApp);
|
||||
nsresult rv = GetInfoFromPrincipal(aPrincipal, &group, &origin, &isApp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<GetUsageOp> op =
|
||||
new GetUsageOp(group, origin, isApp, aURI, aCallback, aAppId,
|
||||
aInMozBrowserOnly);
|
||||
new GetUsageOp(group, origin, isApp, aPrincipal, aCallback);
|
||||
|
||||
op->RunImmediately();
|
||||
|
||||
@ -3764,15 +3726,12 @@ QuotaManager::Clear()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManager::ClearStoragesForURI(nsIURI* aURI,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowserOnly,
|
||||
const nsACString& aPersistenceType,
|
||||
uint8_t aOptionalArgCount)
|
||||
QuotaManager::ClearStoragesForPrincipal(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aPersistenceType)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aPrincipal);
|
||||
|
||||
Nullable<PersistenceType> persistenceType;
|
||||
nsresult rv =
|
||||
@ -3784,18 +3743,16 @@ QuotaManager::ClearStoragesForURI(nsIURI* aURI,
|
||||
// This only works from the main process.
|
||||
NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
if (!aOptionalArgCount) {
|
||||
aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
||||
}
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString origin;
|
||||
rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, nullptr, &origin,
|
||||
nullptr);
|
||||
rv = GetInfoFromPrincipal(aPrincipal, nullptr, &origin, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const mozilla::OriginAttributes& attrs =
|
||||
mozilla::BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
|
||||
|
||||
nsAutoCString pattern;
|
||||
GetOriginPatternString(aAppId, aInMozBrowserOnly, origin, pattern);
|
||||
GetOriginPatternString(attrs.mAppId, attrs.mInBrowser, origin, pattern);
|
||||
|
||||
nsRefPtr<OriginClearOp> op =
|
||||
new OriginClearOp(persistenceType, OriginScope::FromPattern(pattern));
|
||||
@ -4625,24 +4582,20 @@ SaveOriginAccessTimeOp::DoDirectoryWork(QuotaManager* aQuotaManager)
|
||||
GetUsageOp::GetUsageOp(const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
bool aIsApp,
|
||||
nsIURI* aURI,
|
||||
nsIUsageCallback* aCallback,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowserOnly)
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIUsageCallback* aCallback)
|
||||
: NormalOriginOperationBase(Nullable<PersistenceType>(),
|
||||
OriginScope::FromOrigin(aOrigin),
|
||||
/* aExclusive */ false)
|
||||
, mGroup(aGroup)
|
||||
, mURI(aURI)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mCallback(aCallback)
|
||||
, mAppId(aAppId)
|
||||
, mIsApp(aIsApp)
|
||||
, mInMozBrowserOnly(aInMozBrowserOnly)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aGroup.IsEmpty());
|
||||
MOZ_ASSERT(!aOrigin.IsEmpty());
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(aCallback);
|
||||
}
|
||||
|
||||
@ -4777,12 +4730,11 @@ GetUsageOp::SendResults()
|
||||
mUsageInfo.ResetUsage();
|
||||
}
|
||||
|
||||
mCallback->OnUsageResult(mURI, mUsageInfo.TotalUsage(), mUsageInfo.FileUsage(), mAppId,
|
||||
mInMozBrowserOnly);
|
||||
mCallback->OnUsageResult(mPrincipal, mUsageInfo.TotalUsage(), mUsageInfo.FileUsage());
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
mURI = nullptr;
|
||||
mPrincipal = nullptr;
|
||||
mCallback = nullptr;
|
||||
}
|
||||
|
||||
|
@ -306,14 +306,6 @@ public:
|
||||
Client::Type aClientType,
|
||||
nsACString& aDatabaseId);
|
||||
|
||||
static nsresult
|
||||
GetInfoFromURI(nsIURI* aURI,
|
||||
uint32_t aAppId,
|
||||
bool aInMozBrowser,
|
||||
nsACString* aGroup,
|
||||
nsACString* aOrigin,
|
||||
bool* aIsApp);
|
||||
|
||||
static nsresult
|
||||
GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsACString* aGroup,
|
||||
|
@ -7,27 +7,24 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIQuotaRequest;
|
||||
interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface nsIUsageCallback;
|
||||
|
||||
[scriptable, builtinclass, uuid(2968fcd5-1872-4ddc-8c16-62b27e357f31)]
|
||||
[scriptable, builtinclass, uuid(101cf53c-e7f3-4723-9f43-a23a85c8eda0)]
|
||||
interface nsIQuotaManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Schedules an asynchronous callback that will return the total amount of
|
||||
* disk space being used by storages for the given origin.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI whose usage is being queried.
|
||||
* @param aPrincipal
|
||||
* A principal for the origin whose usage is being queried.
|
||||
* @param aCallback
|
||||
* The callback that will be called when the usage is available.
|
||||
*/
|
||||
[optional_argc]
|
||||
nsIQuotaRequest
|
||||
getUsageForURI(in nsIURI aURI,
|
||||
in nsIUsageCallback aCallback,
|
||||
[optional] in unsigned long aAppId,
|
||||
[optional] in boolean aInMozBrowserOnly);
|
||||
getUsageForPrincipal(in nsIPrincipal aPrincipal,
|
||||
in nsIUsageCallback aCallback);
|
||||
|
||||
/**
|
||||
* Removes all storages. The files may not be deleted immediately depending
|
||||
@ -44,15 +41,12 @@ interface nsIQuotaManager : nsISupports
|
||||
* Removes all storages stored for the given URI. The files may not be
|
||||
* deleted immediately depending on prohibitive concurrent operations.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI whose storages are to be cleared.
|
||||
* @param aPrincipal
|
||||
* A principal for the origin whose storages are to be cleared.
|
||||
*/
|
||||
[optional_argc]
|
||||
void
|
||||
clearStoragesForURI(in nsIURI aURI,
|
||||
[optional] in unsigned long aAppId,
|
||||
[optional] in boolean aInMozBrowserOnly,
|
||||
[optional] in ACString aPersistenceType);
|
||||
clearStoragesForPrincipal(in nsIPrincipal aPrincipal,
|
||||
[optional] in ACString aPersistenceType);
|
||||
|
||||
/**
|
||||
* Resets quota and storage management. This can be used to force
|
||||
|
@ -6,15 +6,12 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
|
||||
[scriptable, function, uuid(7b0f9928-0ddc-42c7-b9f2-6b2308b90b18)]
|
||||
[scriptable, function, uuid(54b9f44f-533f-41ee-8fa8-86cc978125f0)]
|
||||
interface nsIUsageCallback : nsISupports
|
||||
{
|
||||
void
|
||||
onUsageResult(in nsIURI aURI,
|
||||
in unsigned long long aUsage,
|
||||
in unsigned long long aFileUsage,
|
||||
in unsigned long aAppId,
|
||||
in boolean aInMozBrowserOnly);
|
||||
void onUsageResult(in nsIPrincipal aPrincipal,
|
||||
in unsigned long long aUsage,
|
||||
in unsigned long long aFileUsage);
|
||||
};
|
||||
|
@ -1183,9 +1183,27 @@ MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName),
|
||||
nsCSSProps::eEnabledForAllContent);
|
||||
if (propertyID != eCSSProperty_UNKNOWN) {
|
||||
bool changed; // outparam for ParseProperty. (ignored)
|
||||
bool changed = false; // outparam for ParseProperty.
|
||||
mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
|
||||
mElement->NodePrincipal(), mDecl, &changed, false, true);
|
||||
if (changed) {
|
||||
// The normal reporting of use counters by the nsCSSParser won't happen
|
||||
// since it doesn't have a sheet.
|
||||
if (nsCSSProps::IsShorthand(propertyID)) {
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, propertyID,
|
||||
nsCSSProps::eEnabledForAllContent) {
|
||||
UseCounter useCounter = nsCSSProps::UseCounterFor(*subprop);
|
||||
if (useCounter != eUseCounter_UNKNOWN) {
|
||||
mElement->OwnerDoc()->SetDocumentAndPageUseCounter(useCounter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UseCounter useCounter = nsCSSProps::UseCounterFor(propertyID);
|
||||
if (useCounter != eUseCounter_UNKNOWN) {
|
||||
mElement->OwnerDoc()->SetDocumentAndPageUseCounter(useCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(aMappedAttrName == nsGkAtoms::lang,
|
||||
|
@ -34,6 +34,7 @@ skip-if = true
|
||||
[test_ril_worker_voiceprivacy.js]
|
||||
[test_ril_worker_ecm.js]
|
||||
[test_ril_worker_stk.js]
|
||||
requesttimeoutfactor = 2
|
||||
[test_ril_worker_barring_password.js]
|
||||
[test_ril_worker_cdma_info_rec.js]
|
||||
[test_ril_system_messenger.js]
|
||||
|
@ -33,6 +33,7 @@ interface SVGSVGElement : SVGGraphicsElement {
|
||||
readonly attribute float screenPixelToMillimeterY;
|
||||
readonly attribute boolean useCurrentView;
|
||||
// readonly attribute SVGViewSpec currentView;
|
||||
[UseCounter]
|
||||
attribute float currentScale;
|
||||
readonly attribute SVGPoint currentTranslate;
|
||||
|
||||
@ -70,6 +71,7 @@ interface SVGSVGElement : SVGGraphicsElement {
|
||||
SVGTransform createSVGTransform();
|
||||
[NewObject]
|
||||
SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix);
|
||||
[UseCounter]
|
||||
Element? getElementById(DOMString elementId);
|
||||
};
|
||||
|
||||
|
@ -1033,9 +1033,7 @@ private:
|
||||
mWorkerPrivate->SetBaseURI(finalURI);
|
||||
|
||||
// Store the channel info if needed.
|
||||
if (mWorkerPrivate->IsServiceWorker()) {
|
||||
mWorkerPrivate->InitChannelInfo(channel);
|
||||
}
|
||||
mWorkerPrivate->InitChannelInfo(channel);
|
||||
|
||||
// Now to figure out which principal to give this worker.
|
||||
WorkerPrivate* parent = mWorkerPrivate->GetParent();
|
||||
|
@ -503,14 +503,12 @@ public:
|
||||
const ChannelInfo&
|
||||
GetChannelInfo() const
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
return mLoadInfo.mChannelInfo;
|
||||
}
|
||||
|
||||
void
|
||||
SetChannelInfo(const ChannelInfo& aChannelInfo)
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
|
||||
MOZ_ASSERT(aChannelInfo.IsInitialized());
|
||||
|
@ -1,12 +1,21 @@
|
||||
self.addEventListener("install", function(event) {
|
||||
event.waitUntil(caches.open("cache").then(function(cache) {
|
||||
return cache.add("index.html");
|
||||
var synth = new Response('<!DOCTYPE html><script>window.parent.postMessage({status: "done-synth-sw"}, "*");</script>',
|
||||
{headers:{"Content-Type": "text/html"}});
|
||||
return Promise.all([
|
||||
cache.add("index.html"),
|
||||
cache.put("synth-sw.html", synth),
|
||||
]);
|
||||
}));
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", function(event) {
|
||||
if (event.request.url.indexOf("index.html") >= 0) {
|
||||
event.respondWith(caches.match(event.request));
|
||||
} else if (event.request.url.indexOf("synth-sw.html") >= 0) {
|
||||
event.respondWith(caches.match(event.request));
|
||||
} else if (event.request.url.indexOf("synth-window.html") >= 0) {
|
||||
event.respondWith(caches.match(event.request));
|
||||
} else if (event.request.url.indexOf("synth.html") >= 0) {
|
||||
event.respondWith(new Response('<!DOCTYPE html><script>window.parent.postMessage({status: "done-synth"}, "*");</script>',
|
||||
{headers:{"Content-Type": "text/html"}}));
|
||||
|
@ -9,6 +9,12 @@
|
||||
window.parent.postMessage({status: "registrationdone"}, "*");
|
||||
}
|
||||
|
||||
navigator.serviceWorker.ready.then(done);
|
||||
navigator.serviceWorker.ready.then(reg => {
|
||||
return window.caches.open("cache").then(function(cache) {
|
||||
var synth = new Response('<!DOCTYPE html><script>window.parent.postMessage({status: "done-synth-window"}, "*");</scri' + 'pt>',
|
||||
{headers:{"Content-Type": "text/html"}});
|
||||
return cache.put('synth-window.html', synth).then(_ => done(reg));
|
||||
});
|
||||
});
|
||||
navigator.serviceWorker.register("https_test.js", {scope: "."});
|
||||
</script>
|
||||
|
@ -31,6 +31,10 @@
|
||||
ios.offline = true;
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/index.html";
|
||||
} else if (e.data.status == "done") {
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/synth-sw.html";
|
||||
} else if (e.data.status == "done-synth-sw") {
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/synth-window.html";
|
||||
} else if (e.data.status == "done-synth-window") {
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/synth.html";
|
||||
} else if (e.data.status == "done-synth") {
|
||||
ios.offline = false;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIIDNService.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "prprf.h"
|
||||
@ -847,9 +846,7 @@ nsPermissionManager::InitDB(bool aRemoveFile)
|
||||
}
|
||||
|
||||
rv = OpenDatabase(permissionsFile);
|
||||
if (rv == NS_ERROR_UNEXPECTED) {
|
||||
return rv;
|
||||
} else if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
LogToConsole(NS_LITERAL_STRING("permissions.sqlite is corrupted! Try again!"));
|
||||
|
||||
// Add telemetry probe
|
||||
@ -863,6 +860,8 @@ nsPermissionManager::InitDB(bool aRemoveFile)
|
||||
rv = OpenDatabase(permissionsFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
LogToConsole(NS_LITERAL_STRING("OpenDatabase to permissions.sqlite is successful!"));
|
||||
} else if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool ready;
|
||||
@ -2743,19 +2742,6 @@ nsPermissionManager::_DoImport(nsIInputStream *inputStream, mozIStorageConnectio
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPermissionManager::NormalizeToACE(nsCString &aHost)
|
||||
{
|
||||
// lazily init the IDN service
|
||||
if (!mIDNService) {
|
||||
nsresult rv;
|
||||
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return mIDNService->ConvertUTF8toACE(aHost, aHost);
|
||||
}
|
||||
|
||||
void
|
||||
nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
mozIStorageAsyncStatement* aStmt,
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
class nsIPermission;
|
||||
class nsIIDNService;
|
||||
class mozIStorageConnection;
|
||||
class mozIStorageAsyncStatement;
|
||||
|
||||
@ -239,7 +238,6 @@ private:
|
||||
|
||||
nsresult RemoveAllInternal(bool aNotifyObservers);
|
||||
nsresult RemoveAllFromMemory();
|
||||
nsresult NormalizeToACE(nsCString &aHost);
|
||||
static void UpdateDB(OperationType aOp,
|
||||
mozIStorageAsyncStatement* aStmt,
|
||||
int64_t aID,
|
||||
@ -264,8 +262,6 @@ private:
|
||||
nsresult
|
||||
FetchPermissions();
|
||||
|
||||
nsCOMPtr<nsIIDNService> mIDNService;
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> mDBConn;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> mStmtInsert;
|
||||
nsCOMPtr<mozIStorageAsyncStatement> mStmtDelete;
|
||||
|
@ -19,16 +19,15 @@ namespace layers {
|
||||
HRESULT
|
||||
D3D11ShareHandleImage::SetData(const Data& aData)
|
||||
{
|
||||
NS_ENSURE_TRUE(aData.mTexture, E_POINTER);
|
||||
mTexture = aData.mTexture;
|
||||
mPictureRect = aData.mRegion;
|
||||
mSize = aData.mSize;
|
||||
|
||||
D3D11_TEXTURE2D_DESC frameDesc;
|
||||
mTexture->GetDesc(&frameDesc);
|
||||
|
||||
mFormat = gfx::SurfaceFormat::B8G8R8A8;
|
||||
mSize.width = frameDesc.Width;
|
||||
mSize.height = frameDesc.Height;
|
||||
mTextureClient =
|
||||
aData.mAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::B8G8R8A8,
|
||||
mSize);
|
||||
if (!mTextureClient) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -42,29 +41,23 @@ D3D11ShareHandleImage::GetSize()
|
||||
TextureClient*
|
||||
D3D11ShareHandleImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
mTextureClient = TextureClientD3D11::Create(aClient->GetForwarder(),
|
||||
mFormat,
|
||||
TextureFlags::DEFAULT,
|
||||
mTexture,
|
||||
mSize);
|
||||
}
|
||||
return mTextureClient;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
{
|
||||
if (!mTexture) {
|
||||
RefPtr<ID3D11Texture2D> texture = GetTexture();
|
||||
if (!texture) {
|
||||
NS_WARNING("Cannot readback from shared texture because no texture is available.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11Device> device;
|
||||
mTexture->GetDevice(byRef(device));
|
||||
texture->GetDevice(byRef(device));
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> keyedMutex;
|
||||
if (FAILED(mTexture->QueryInterface(static_cast<IDXGIKeyedMutex**>(byRef(keyedMutex))))) {
|
||||
if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(byRef(keyedMutex))))) {
|
||||
NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
|
||||
return nullptr;
|
||||
}
|
||||
@ -75,7 +68,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
mTexture->GetDesc(&desc);
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
|
||||
softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
@ -102,7 +95,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
context->CopyResource(softTexture, mTexture);
|
||||
context->CopyResource(softTexture, texture);
|
||||
keyedMutex->ReleaseSync(0);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
@ -137,8 +130,40 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
|
||||
ID3D11Texture2D*
|
||||
D3D11ShareHandleImage::GetTexture() const {
|
||||
return mTexture;
|
||||
return mTextureClient->GetD3D11Texture();
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
D3D11RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aSize,
|
||||
BackendSelector aSelector,
|
||||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
return TextureClientD3D11::Create(mSurfaceAllocator,
|
||||
aFormat,
|
||||
TextureFlags::DEFAULT,
|
||||
mDevice,
|
||||
aSize);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClientD3D11>
|
||||
D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
RefPtr<TextureClient> textureClient =
|
||||
CreateOrRecycle(aFormat,
|
||||
aSize,
|
||||
BackendSelector::Content,
|
||||
layers::TextureFlags::DEFAULT);
|
||||
if (!textureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<TextureClientD3D11> textureD3D11 = static_cast<TextureClientD3D11*>(textureClient.get());
|
||||
return textureD3D11.forget();
|
||||
}
|
||||
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -11,10 +11,36 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "d3d11.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
#include "mozilla/layers/TextureClientRecycleAllocator.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class D3D11RecycleAllocator : public TextureClientRecycleAllocator
|
||||
{
|
||||
public:
|
||||
explicit D3D11RecycleAllocator(ISurfaceAllocator* aAllocator,
|
||||
ID3D11Device* aDevice)
|
||||
: TextureClientRecycleAllocator(aAllocator)
|
||||
, mDevice(aDevice)
|
||||
{}
|
||||
|
||||
already_AddRefed<TextureClientD3D11>
|
||||
CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
protected:
|
||||
virtual already_AddRefed<TextureClient>
|
||||
Allocate(gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aSize,
|
||||
BackendSelector aSelector,
|
||||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags aAllocFlags) override;
|
||||
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
};
|
||||
|
||||
// Image class that wraps a ID3D11Texture2D. This class copies the image
|
||||
// passed into SetData(), so that it can be accessed from other D3D devices.
|
||||
// This class also manages the synchronization of the copy, to ensure the
|
||||
@ -23,17 +49,14 @@ class D3D11ShareHandleImage : public Image {
|
||||
public:
|
||||
|
||||
struct Data {
|
||||
Data(ID3D11Texture2D* aTexture,
|
||||
ID3D11Device* aDevice,
|
||||
ID3D11DeviceContext* aContext,
|
||||
Data(D3D11RecycleAllocator* aAllocator,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntRect& aRegion)
|
||||
: mTexture(aTexture),
|
||||
mDevice(aDevice),
|
||||
mContext(aContext),
|
||||
mRegion(aRegion) {}
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
: mAllocator(aAllocator)
|
||||
, mSize(aSize)
|
||||
, mRegion(aRegion) {}
|
||||
RefPtr<D3D11RecycleAllocator> mAllocator;
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntRect mRegion;
|
||||
};
|
||||
|
||||
@ -58,11 +81,7 @@ private:
|
||||
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntRect mPictureRect;
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
HANDLE mShareHandle;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
|
||||
RefPtr<TextureClientD3D11> mTextureClient;
|
||||
};
|
||||
|
||||
} // namepace layers
|
||||
|
@ -19,6 +19,7 @@ D3D9SurfaceImage::D3D9SurfaceImage()
|
||||
: Image(nullptr, ImageFormat::D3D9_RGB32_TEXTURE)
|
||||
, mSize(0, 0)
|
||||
, mValid(false)
|
||||
, mIsFirstFrame(false)
|
||||
{}
|
||||
|
||||
D3D9SurfaceImage::~D3D9SurfaceImage()
|
||||
@ -83,6 +84,7 @@ D3D9SurfaceImage::SetData(const Data& aData)
|
||||
mTextureClient = textureClient;
|
||||
mSize = region.Size();
|
||||
mQuery = query;
|
||||
mIsFirstFrame = aData.mIsFirstFrame;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -103,7 +105,7 @@ D3D9SurfaceImage::EnsureSynchronized()
|
||||
return;
|
||||
}
|
||||
int iterations = 0;
|
||||
while (iterations < 10) {
|
||||
while (iterations < (mIsFirstFrame ? 100 : 10)) {
|
||||
HRESULT hr = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
|
||||
if (hr == S_FALSE) {
|
||||
Sleep(1);
|
||||
|
@ -51,15 +51,18 @@ public:
|
||||
struct Data {
|
||||
Data(IDirect3DSurface9* aSurface,
|
||||
const gfx::IntRect& aRegion,
|
||||
D3D9RecycleAllocator* aAllocator)
|
||||
D3D9RecycleAllocator* aAllocator,
|
||||
bool aIsFirstFrame)
|
||||
: mSurface(aSurface)
|
||||
, mRegion(aRegion)
|
||||
, mAllocator(aAllocator)
|
||||
, mIsFirstFrame(aIsFirstFrame)
|
||||
{}
|
||||
|
||||
RefPtr<IDirect3DSurface9> mSurface;
|
||||
gfx::IntRect mRegion;
|
||||
RefPtr<D3D9RecycleAllocator> mAllocator;
|
||||
bool mIsFirstFrame;
|
||||
};
|
||||
|
||||
D3D9SurfaceImage();
|
||||
@ -90,6 +93,7 @@ private:
|
||||
RefPtr<IDirect3DQuery9> mQuery;
|
||||
RefPtr<SharedTextureClientD3D9> mTextureClient;
|
||||
bool mValid;
|
||||
bool mIsFirstFrame;
|
||||
};
|
||||
|
||||
} // namepace layers
|
||||
|
@ -1702,11 +1702,9 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
}
|
||||
if (GetIsFixedPosition()) {
|
||||
LayerPoint anchor = GetFixedPositionAnchor();
|
||||
LayerMargin margin = GetFixedPositionMargins();
|
||||
aStream << nsPrintfCString(" [isFixedPosition scrollId=%d anchor=%s margin=%f,%f,%f,%f]",
|
||||
aStream << nsPrintfCString(" [isFixedPosition scrollId=%d anchor=%s]",
|
||||
GetFixedPositionScrollContainerId(),
|
||||
ToString(anchor).c_str(),
|
||||
margin.top, margin.right, margin.bottom, margin.left).get();
|
||||
ToString(anchor).c_str()).get();
|
||||
}
|
||||
if (GetIsStickyPosition()) {
|
||||
aStream << nsPrintfCString(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f "
|
||||
|
@ -1151,9 +1151,8 @@ public:
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* If a layer represents a fixed position element or elements that are on
|
||||
* a document that has had fixed position element margins set on it, this
|
||||
* data is stored on the layer for use by the compositor.
|
||||
* If a layer represents a fixed position element, this data is stored on the
|
||||
* layer for use by the compositor.
|
||||
*
|
||||
* - |aScrollId| identifies the scroll frame that this element is fixed
|
||||
* with respect to.
|
||||
@ -1162,30 +1161,19 @@ public:
|
||||
* point, that is, the point which remains in the same position when
|
||||
* compositing the layer tree with a transformation (such as when
|
||||
* asynchronously scrolling and zooming).
|
||||
*
|
||||
* - |aMargins| are the fixed position margins set on the document this
|
||||
* element is part of. Storing them here allows for asynchronous
|
||||
* animation of the margins by reconciling the difference between this
|
||||
* value and a value that is updated more frequently.
|
||||
* If the left or top margins are negative, it means that the elements
|
||||
* this layer represents are auto-positioned, and so fxed position
|
||||
* margins should not have an effect on the corresponding axis.
|
||||
*/
|
||||
void SetFixedPositionData(FrameMetrics::ViewID aScrollId,
|
||||
const LayerPoint& aAnchor,
|
||||
const LayerMargin& aMargins)
|
||||
const LayerPoint& aAnchor)
|
||||
{
|
||||
if (!mFixedPositionData ||
|
||||
mFixedPositionData->mScrollId != aScrollId ||
|
||||
mFixedPositionData->mAnchor != aAnchor ||
|
||||
mFixedPositionData->mMargins != aMargins) {
|
||||
mFixedPositionData->mAnchor != aAnchor) {
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionData", this));
|
||||
if (!mFixedPositionData) {
|
||||
mFixedPositionData = MakeUnique<FixedPositionData>();
|
||||
}
|
||||
mFixedPositionData->mScrollId = aScrollId;
|
||||
mFixedPositionData->mAnchor = aAnchor;
|
||||
mFixedPositionData->mMargins = aMargins;
|
||||
Mutated();
|
||||
}
|
||||
}
|
||||
@ -1279,7 +1267,6 @@ public:
|
||||
bool GetIsStickyPosition() { return mStickyPositionData; }
|
||||
FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mFixedPositionData ? mFixedPositionData->mScrollId : FrameMetrics::NULL_SCROLL_ID; }
|
||||
LayerPoint GetFixedPositionAnchor() { return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint(); }
|
||||
LayerMargin GetFixedPositionMargins() { return mFixedPositionData ? mFixedPositionData->mMargins : LayerMargin(); }
|
||||
FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
|
||||
const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
|
||||
const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
|
||||
@ -1783,7 +1770,6 @@ protected:
|
||||
struct FixedPositionData {
|
||||
FrameMetrics::ViewID mScrollId;
|
||||
LayerPoint mAnchor;
|
||||
LayerMargin mMargins;
|
||||
};
|
||||
UniquePtr<FixedPositionData> mFixedPositionData;
|
||||
struct StickyPositionData {
|
||||
|
@ -790,6 +790,12 @@ ClientLayerManager::AsyncPanZoomEnabled() const
|
||||
return mWidget && mWidget->AsyncPanZoomEnabled();
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::SetNextPaintSyncId(int32_t aSyncId)
|
||||
{
|
||||
mForwarder->SetPaintSyncId(aSyncId);
|
||||
}
|
||||
|
||||
ClientLayer::~ClientLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
|
@ -253,6 +253,8 @@ public:
|
||||
|
||||
bool AsyncPanZoomEnabled() const override;
|
||||
|
||||
void SetNextPaintSyncId(int32_t aSyncId);
|
||||
|
||||
protected:
|
||||
enum TransactionPhase {
|
||||
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user