merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-06-24 16:01:47 +02:00
Родитель 0db26e7d5d 848de192dd
Коммит 7fd037905e
171 изменённых файлов: 3702 добавлений и 5620 удалений

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

@ -683,7 +683,7 @@ getRoleCB(AtkObject *aAtkObj)
else if (aAtkObj->role == ATK_ROLE_TABLE_ROW && !IsAtkVersionAtLeast(2, 1)) else if (aAtkObj->role == ATK_ROLE_TABLE_ROW && !IsAtkVersionAtLeast(2, 1))
aAtkObj->role = ATK_ROLE_LIST_ITEM; aAtkObj->role = ATK_ROLE_LIST_ITEM;
else if (aAtkObj->role == ATK_ROLE_MATH && !IsAtkVersionAtLeast(2, 12)) else if (aAtkObj->role == ATK_ROLE_MATH && !IsAtkVersionAtLeast(2, 12))
aAtkObj->role = ATK_ROLE_PANEL; aAtkObj->role = ATK_ROLE_SECTION;
else if (aAtkObj->role == ATK_ROLE_STATIC && !IsAtkVersionAtLeast(2, 16)) else if (aAtkObj->role == ATK_ROLE_STATIC && !IsAtkVersionAtLeast(2, 16))
aAtkObj->role = ATK_ROLE_TEXT; aAtkObj->role = ATK_ROLE_TEXT;
else if ((aAtkObj->role == ATK_ROLE_MATH_FRACTION || else if ((aAtkObj->role == ATK_ROLE_MATH_FRACTION ||

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

@ -1067,7 +1067,7 @@ ROLE(SWITCH,
ROLE(MATHML_MATH, ROLE(MATHML_MATH,
"math", "math",
ATK_ROLE_MATH, ATK_ROLE_MATH,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
ROLE_SYSTEM_EQUATION, ROLE_SYSTEM_EQUATION,
ROLE_SYSTEM_EQUATION, ROLE_SYSTEM_EQUATION,
eNoNameRule) eNoNameRule)
@ -1075,7 +1075,7 @@ ROLE(MATHML_MATH,
ROLE(MATHML_IDENTIFIER, ROLE(MATHML_IDENTIFIER,
"mathml identifier", "mathml identifier",
ATK_ROLE_STATIC, ATK_ROLE_STATIC,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNameFromSubtreeRule) eNameFromSubtreeRule)
@ -1083,7 +1083,7 @@ ROLE(MATHML_IDENTIFIER,
ROLE(MATHML_NUMBER, ROLE(MATHML_NUMBER,
"mathml number", "mathml number",
ATK_ROLE_STATIC, ATK_ROLE_STATIC,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNameFromSubtreeRule) eNameFromSubtreeRule)
@ -1091,7 +1091,7 @@ ROLE(MATHML_NUMBER,
ROLE(MATHML_OPERATOR, ROLE(MATHML_OPERATOR,
"mathml operator", "mathml operator",
ATK_ROLE_STATIC, ATK_ROLE_STATIC,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNameFromSubtreeRule) eNameFromSubtreeRule)
@ -1099,7 +1099,7 @@ ROLE(MATHML_OPERATOR,
ROLE(MATHML_TEXT, ROLE(MATHML_TEXT,
"mathml text", "mathml text",
ATK_ROLE_STATIC, ATK_ROLE_STATIC,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNameFromSubtreeRule) eNameFromSubtreeRule)
@ -1107,7 +1107,7 @@ ROLE(MATHML_TEXT,
ROLE(MATHML_STRING_LITERAL, ROLE(MATHML_STRING_LITERAL,
"mathml string literal", "mathml string literal",
ATK_ROLE_STATIC, ATK_ROLE_STATIC,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNameFromSubtreeRule) eNameFromSubtreeRule)
@ -1115,15 +1115,15 @@ ROLE(MATHML_STRING_LITERAL,
ROLE(MATHML_GLYPH, ROLE(MATHML_GLYPH,
"mathml glyph", "mathml glyph",
ATK_ROLE_IMAGE, ATK_ROLE_IMAGE,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNameFromSubtreeRule) eNameFromSubtreeRule)
ROLE(MATHML_ROW, ROLE(MATHML_ROW,
"mathml row", "mathml row",
ATK_ROLE_PANEL, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1131,7 +1131,7 @@ ROLE(MATHML_ROW,
ROLE(MATHML_FRACTION, ROLE(MATHML_FRACTION,
"mathml fraction", "mathml fraction",
ATK_ROLE_MATH_FRACTION, ATK_ROLE_MATH_FRACTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1139,7 +1139,7 @@ ROLE(MATHML_FRACTION,
ROLE(MATHML_SQUARE_ROOT, ROLE(MATHML_SQUARE_ROOT,
"mathml square root", "mathml square root",
ATK_ROLE_MATH_ROOT, ATK_ROLE_MATH_ROOT,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1147,87 +1147,87 @@ ROLE(MATHML_SQUARE_ROOT,
ROLE(MATHML_ROOT, ROLE(MATHML_ROOT,
"mathml root", "mathml root",
ATK_ROLE_MATH_ROOT, ATK_ROLE_MATH_ROOT,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_FENCED, ROLE(MATHML_FENCED,
"mathml fenced", "mathml fenced",
ATK_ROLE_PANEL, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_ENCLOSED, ROLE(MATHML_ENCLOSED,
"mathml enclosed", "mathml enclosed",
ATK_ROLE_PANEL, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_STYLE, ROLE(MATHML_STYLE,
"mathml style", "mathml style",
ATK_ROLE_PANEL, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_SUB, ROLE(MATHML_SUB,
"mathml sub", "mathml sub",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_SUP, ROLE(MATHML_SUP,
"mathml sup", "mathml sup",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_SUB_SUP, ROLE(MATHML_SUB_SUP,
"mathml sub sup", "mathml sub sup",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_UNDER, ROLE(MATHML_UNDER,
"mathml under", "mathml under",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_OVER, ROLE(MATHML_OVER,
"mathml over", "mathml over",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_UNDER_OVER, ROLE(MATHML_UNDER_OVER,
"mathml under over", "mathml under over",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_MULTISCRIPTS, ROLE(MATHML_MULTISCRIPTS,
"mathml multiscripts", "mathml multiscripts",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1235,7 +1235,7 @@ ROLE(MATHML_MULTISCRIPTS,
ROLE(MATHML_TABLE, ROLE(MATHML_TABLE,
"mathml table", "mathml table",
ATK_ROLE_TABLE, ATK_ROLE_TABLE,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1243,7 +1243,7 @@ ROLE(MATHML_TABLE,
ROLE(MATHML_LABELED_ROW, ROLE(MATHML_LABELED_ROW,
"mathml labeled row", "mathml labeled row",
ATK_ROLE_TABLE_ROW, ATK_ROLE_TABLE_ROW,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1251,7 +1251,7 @@ ROLE(MATHML_LABELED_ROW,
ROLE(MATHML_TABLE_ROW, ROLE(MATHML_TABLE_ROW,
"mathml table row", "mathml table row",
ATK_ROLE_TABLE_ROW, ATK_ROLE_TABLE_ROW,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1259,23 +1259,23 @@ ROLE(MATHML_TABLE_ROW,
ROLE(MATHML_CELL, ROLE(MATHML_CELL,
"mathml cell", "mathml cell",
ATK_ROLE_TABLE_CELL, ATK_ROLE_TABLE_CELL,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_ACTION, ROLE(MATHML_ACTION,
"mathml action", "mathml action",
ATK_ROLE_UNKNOWN, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
ROLE(MATHML_ERROR, ROLE(MATHML_ERROR,
"mathml error", "mathml error",
ATK_ROLE_PANEL, ATK_ROLE_SECTION,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1283,7 +1283,7 @@ ROLE(MATHML_ERROR,
ROLE(MATHML_STACK, ROLE(MATHML_STACK,
"mathml stack", "mathml stack",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1291,7 +1291,7 @@ ROLE(MATHML_STACK,
ROLE(MATHML_LONG_DIVISION, ROLE(MATHML_LONG_DIVISION,
"mathml long division", "mathml long division",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1299,7 +1299,7 @@ ROLE(MATHML_LONG_DIVISION,
ROLE(MATHML_STACK_GROUP, ROLE(MATHML_STACK_GROUP,
"mathml stack group", "mathml stack group",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1307,7 +1307,7 @@ ROLE(MATHML_STACK_GROUP,
ROLE(MATHML_STACK_ROW, ROLE(MATHML_STACK_ROW,
"mathml stack row", "mathml stack row",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1315,7 +1315,7 @@ ROLE(MATHML_STACK_ROW,
ROLE(MATHML_STACK_CARRIES, ROLE(MATHML_STACK_CARRIES,
"mathml stack carries", "mathml stack carries",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1323,7 +1323,7 @@ ROLE(MATHML_STACK_CARRIES,
ROLE(MATHML_STACK_CARRY, ROLE(MATHML_STACK_CARRY,
"mathml stack carry", "mathml stack carry",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)
@ -1331,7 +1331,7 @@ ROLE(MATHML_STACK_CARRY,
ROLE(MATHML_STACK_LINE, ROLE(MATHML_STACK_LINE,
"mathml stack line", "mathml stack line",
ATK_ROLE_UNKNOWN, ATK_ROLE_UNKNOWN,
NSAccessibilityUnknownRole, NSAccessibilityGroupRole,
0, 0,
IA2_ROLE_UNKNOWN, IA2_ROLE_UNKNOWN,
eNoNameRule) eNoNameRule)

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

@ -503,6 +503,66 @@ GetClosestInterestingAccessible(id anObject)
case roles::DEFINITION: case roles::DEFINITION:
return @"AXDefinition"; return @"AXDefinition";
case roles::MATHML_MATH:
return @"AXDocumentMath";
case roles::MATHML_FRACTION:
return @"AXMathFraction";
case roles::MATHML_FENCED:
// XXX This should be AXMathFence, but doing so without implementing the
// whole fence interface seems to make VoiceOver crash, so we present it
// as a row for now.
return @"AXMathRow";
case roles::MATHML_SUB:
case roles::MATHML_SUP:
case roles::MATHML_SUB_SUP:
return @"AXMathSubscriptSuperscript";
case roles::MATHML_ROW:
return @"AXMathRow";
case roles::MATHML_UNDER:
case roles::MATHML_OVER:
case roles::MATHML_UNDER_OVER:
return @"AXMathUnderOver";
case roles::MATHML_SQUARE_ROOT:
return @"AXMathSquareRoot";
case roles::MATHML_ROOT:
return @"AXMathRoot";
case roles::MATHML_TEXT:
return @"AXMathText";
case roles::MATHML_NUMBER:
return @"AXMathNumber";
case roles::MATHML_IDENTIFIER:
return @"AXMathIdentifier";
case roles::MATHML_TABLE:
return @"AXMathTable";
case roles::MATHML_TABLE_ROW:
return @"AXMathTableRow";
case roles::MATHML_CELL:
return @"AXMathTableCell";
// XXX: NSAccessibility also uses subroles AXMathSeparatorOperator and
// AXMathFenceOperator. We should use the NS_MATHML_OPERATOR_FENCE and
// NS_MATHML_OPERATOR_SEPARATOR bits of nsOperatorFlags, but currently they
// are only available from the MathML layout code. Hence we just fallback
// to subrole AXMathOperator for now.
case roles::MATHML_OPERATOR:
return @"AXMathOperator";
case roles::MATHML_MULTISCRIPTS:
return @"AXMathMultiscript";
case roles::SWITCH: case roles::SWITCH:
return @"AXSwitch"; return @"AXSwitch";

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

@ -305,7 +305,6 @@
@RESPATH@/components/plugin.xpt @RESPATH@/components/plugin.xpt
@RESPATH@/components/pref.xpt @RESPATH@/components/pref.xpt
@RESPATH@/components/prefetch.xpt @RESPATH@/components/prefetch.xpt
@RESPATH@/components/profile.xpt
#ifdef MOZ_ENABLE_PROFILER_SPS #ifdef MOZ_ENABLE_PROFILER_SPS
@RESPATH@/components/profiler.xpt @RESPATH@/components/profiler.xpt
#endif #endif

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

@ -475,6 +475,7 @@ skip-if = e10s # Bug 1100687 - test directly manipulates content (content.docume
[browser_e10s_chrome_process.js] [browser_e10s_chrome_process.js]
[browser_e10s_javascript.js] [browser_e10s_javascript.js]
[browser_blockHPKP.js] [browser_blockHPKP.js]
tags = psm
skip-if = e10s # bug 1100687 - test directly manipulates content (content.document.getElementById) skip-if = e10s # bug 1100687 - test directly manipulates content (content.document.getElementById)
[browser_mcb_redirect.js] [browser_mcb_redirect.js]
[browser_windowactivation.js] [browser_windowactivation.js]

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

@ -306,7 +306,6 @@
@RESPATH@/components/plugin.xpt @RESPATH@/components/plugin.xpt
@RESPATH@/components/pref.xpt @RESPATH@/components/pref.xpt
@RESPATH@/components/prefetch.xpt @RESPATH@/components/prefetch.xpt
@RESPATH@/components/profile.xpt
#ifdef MOZ_ENABLE_PROFILER_SPS #ifdef MOZ_ENABLE_PROFILER_SPS
@RESPATH@/components/profiler.xpt @RESPATH@/components/profiler.xpt
#endif #endif

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

@ -98,6 +98,8 @@ public:
Element* GetOwnerElement(ErrorResult& aRv); Element* GetOwnerElement(ErrorResult& aRv);
bool IsNSAware() const { return mNsAware; }
protected: protected:
virtual Element* GetNameSpaceElement() override virtual Element* GetNameSpaceElement() override
{ {

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

@ -15,6 +15,7 @@
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/NamedNodeMapBinding.h" #include "mozilla/dom/NamedNodeMapBinding.h"
#include "mozilla/dom/NodeInfoInlines.h" #include "mozilla/dom/NodeInfoInlines.h"
#include "mozilla/Telemetry.h"
#include "nsAttrName.h" #include "nsAttrName.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsError.h" #include "nsError.h"
@ -271,6 +272,21 @@ nsDOMAttributeMap::SetNamedItemInternal(Attr& aAttr,
{ {
NS_ENSURE_TRUE(mContent, nullptr); NS_ENSURE_TRUE(mContent, nullptr);
if (!aAttr.IsNSAware() &&
!mContent->IsHTMLElement() &&
aAttr.OwnerDoc()->IsHTMLDocument()) {
// Check whether we have a non-lowercase name, and if so log some telemetry.
// We check whether the attr's document is HTML _before_ the adopt we do
// below, because we're trying to figure out whether we could lowercase the
// attr name at creation time. We restrict this to the !IsNSAware() case,
// because we only care about Attr nodes created via createAttribute.
nsIAtom* nameAtom = aAttr.NodeInfo()->NameAtom();
if (nsContentUtils::StringContainsASCIIUpper(nsDependentAtomString(nameAtom))) {
Telemetry::Accumulate(Telemetry::NONLOWERCASE_NONHTML_ATTR_NODE_SET,
true);
}
}
// XXX should check same-origin between mContent and aAttr however // XXX should check same-origin between mContent and aAttr however
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet // nsContentUtils::CheckSameOrigin can't deal with attributenodes yet

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

@ -7590,18 +7590,6 @@ nsGlobalWindow::ClearInterval(int32_t aHandle)
return rv.StealNSResult(); return rv.StealNSResult();
} }
NS_IMETHODIMP
nsGlobalWindow::SetTimeout(int32_t *_retval)
{
return SetTimeoutOrInterval(false, _retval);
}
NS_IMETHODIMP
nsGlobalWindow::SetInterval(int32_t *_retval)
{
return SetTimeoutOrInterval(true, _retval);
}
NS_IMETHODIMP NS_IMETHODIMP
nsGlobalWindow::SetResizable(bool aResizable) nsGlobalWindow::SetResizable(bool aResizable)
{ {
@ -11945,50 +11933,6 @@ nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
} }
nsresult
nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, int32_t *aReturn)
{
// This needs to forward to the inner window, but since the current
// inner may not be the inner in the calling scope, we need to treat
// this specially here as we don't want timeouts registered in a
// dying inner window to get registered and run on the current inner
// window. To get this right, we need to forward this call to the
// inner window that's calling window.setTimeout().
if (IsOuterWindow()) {
nsGlobalWindow* callerInner = CallerInnerWindow();
NS_ENSURE_TRUE(callerInner || nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
// If the caller and the callee share the same outer window,
// forward to the callee inner. Else, we forward to the current
// inner (e.g. someone is calling setTimeout() on a reference to
// some other window).
if (callerInner &&
callerInner->GetOuterWindow() == this &&
callerInner->IsInnerWindow()) {
return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn);
}
FORWARD_TO_INNER(SetTimeoutOrInterval, (aIsInterval, aReturn),
NS_ERROR_NOT_INITIALIZED);
}
int32_t interval = 0;
bool isInterval = aIsInterval;
nsCOMPtr<nsIScriptTimeoutHandler> handler;
nsresult rv = NS_CreateJSTimeoutHandler(this,
&isInterval,
&interval,
getter_AddRefs(handler));
if (!handler) {
*aReturn = 0;
return rv;
}
return SetTimeoutOrInterval(handler, interval, isInterval, aReturn);
}
int32_t int32_t
nsGlobalWindow::SetTimeoutOrInterval(Function& aFunction, int32_t aTimeout, nsGlobalWindow::SetTimeoutOrInterval(Function& aFunction, int32_t aTimeout,
const Sequence<JS::Value>& aArguments, const Sequence<JS::Value>& aArguments,

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

@ -129,12 +129,6 @@ class VRHMDInfo;
} // namespace gfx } // namespace gfx
} // namespace mozilla } // namespace mozilla
extern nsresult
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
bool *aIsInterval,
int32_t *aInterval,
nsIScriptTimeoutHandler **aRet);
extern already_AddRefed<nsIScriptTimeoutHandler> extern already_AddRefed<nsIScriptTimeoutHandler>
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
mozilla::dom::Function& aFunction, mozilla::dom::Function& aFunction,
@ -1335,7 +1329,6 @@ public:
} }
// JS specific timeout functions (JS args grabbed from context). // JS specific timeout functions (JS args grabbed from context).
nsresult SetTimeoutOrInterval(bool aIsInterval, int32_t* aReturn);
nsresult ResetTimersForNonBackgroundWindow(); nsresult ResetTimersForNonBackgroundWindow();
// The timeout implementation functions. // The timeout implementation functions.

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

@ -58,9 +58,6 @@ public:
return mArgs; return mArgs;
} }
nsresult Init(nsGlobalWindow *aWindow, bool *aIsInterval,
int32_t *aInterval, bool* aAllowEval);
void ReleaseJSObjects(); void ReleaseJSObjects();
private: private:
@ -248,136 +245,6 @@ nsJSScriptTimeoutHandler::ReleaseJSObjects()
} }
} }
nsresult
nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
int32_t *aInterval, bool *aAllowEval)
{
if (!aWindow->GetContextInternal() || !aWindow->FastGetGlobalJSObject()) {
// This window was already closed, or never properly initialized,
// don't let a timer be scheduled on such a window.
return NS_ERROR_NOT_INITIALIZED;
}
nsAXPCNativeCallContext *ncc = nullptr;
nsresult rv = nsContentUtils::XPConnect()->
GetCurrentNativeCallContext(&ncc);
NS_ENSURE_SUCCESS(rv, rv);
if (!ncc)
return NS_ERROR_NOT_AVAILABLE;
JSContext *cx = nullptr;
rv = ncc->GetJSContext(&cx);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t argc;
JS::Value *argv = nullptr;
ncc->GetArgc(&argc);
ncc->GetArgvPtr(&argv);
JS::Rooted<JSFlatString*> expr(cx);
JS::Rooted<JSObject*> funobj(cx);
if (argc < 1) {
::JS_ReportError(cx, "Function %s requires at least 2 parameter",
*aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
return NS_ERROR_DOM_TYPE_ERR;
}
int32_t interval = 0;
if (argc > 1) {
JS::Rooted<JS::Value> arg(cx, argv[1]);
if (!JS::ToInt32(cx, arg, &interval)) {
::JS_ReportError(cx,
"Second argument to %s must be a millisecond interval",
aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
return NS_ERROR_DOM_TYPE_ERR;
}
}
if (argc == 1) {
// If no interval was specified, treat this like a timeout, to avoid
// setting an interval of 0 milliseconds.
*aIsInterval = false;
}
JS::Rooted<JS::Value> arg(cx, argv[0]);
switch (::JS_TypeOfValue(cx, arg)) {
case JSTYPE_FUNCTION:
funobj = &arg.toObject();
break;
case JSTYPE_STRING:
case JSTYPE_OBJECT:
{
JSString *str = JS::ToString(cx, arg);
if (!str)
return NS_ERROR_OUT_OF_MEMORY;
expr = ::JS_FlattenString(cx, str);
if (!expr)
return NS_ERROR_OUT_OF_MEMORY;
argv[0] = JS::StringValue(str);
}
break;
default:
::JS_ReportError(cx, "useless %s call (missing quotes around argument?)",
*aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
// Return an error that nsGlobalWindow can recognize and turn into NS_OK.
return NS_ERROR_DOM_TYPE_ERR;
}
if (expr) {
// if CSP is enabled, and setTimeout/setInterval was called with a string,
// disable the registration and log an error
ErrorResult error;
*aAllowEval = CheckCSPForEval(cx, aWindow, error);
if (error.Failed() || !*aAllowEval) {
return error.StealNSResult();
}
MOZ_ASSERT(mExpr.IsEmpty());
AssignJSFlatString(mExpr, expr);
// Get the calling location.
nsJSUtils::GetCallingLocation(cx, mFileName, &mLineNo);
} else if (funobj) {
*aAllowEval = true;
mozilla::HoldJSObjects(this);
mFunction = new Function(funobj, GetIncumbentGlobal());
// Create our arg array. argc is the number of arguments passed
// to setTimeout or setInterval; the first two are our callback
// and the delay, so only arguments after that need to go in our
// array.
// std::max(argc - 2, 0) wouldn't work right because argc is unsigned.
uint32_t argCount = std::max(argc, 2u) - 2;
FallibleTArray<JS::Heap<JS::Value> > args;
if (!args.SetCapacity(argCount, fallible)) {
// No need to drop here, since we already have a non-null mFunction
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t idx = 0; idx < argCount; ++idx) {
*args.AppendElement(fallible) = argv[idx + 2];
}
args.SwapElements(mArgs);
} else {
NS_WARNING("No func and no expr - why are we here?");
}
*aInterval = interval;
return NS_OK;
}
const char16_t * const char16_t *
nsJSScriptTimeoutHandler::GetHandlerText() nsJSScriptTimeoutHandler::GetHandlerText()
{ {
@ -385,24 +252,6 @@ nsJSScriptTimeoutHandler::GetHandlerText()
return mExpr.get(); return mExpr.get();
} }
nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
bool *aIsInterval,
int32_t *aInterval,
nsIScriptTimeoutHandler **aRet)
{
*aRet = nullptr;
nsRefPtr<nsJSScriptTimeoutHandler> handler = new nsJSScriptTimeoutHandler();
bool allowEval;
nsresult rv = handler->Init(aWindow, aIsInterval, aInterval, &allowEval);
if (NS_FAILED(rv) || !allowEval) {
return rv;
}
handler.forget(aRet);
return NS_OK;
}
already_AddRefed<nsIScriptTimeoutHandler> already_AddRefed<nsIScriptTimeoutHandler>
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, Function& aFunction, NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, Function& aFunction,
const Sequence<JS::Value>& aArguments, const Sequence<JS::Value>& aArguments,

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

@ -678,13 +678,18 @@ nsXMLHttpRequest::AppendToResponseText(const char * aSrcBuffer,
&destBufferLen); &destBufferLen);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!mResponseText.SetCapacity(mResponseText.Length() + destBufferLen, fallible)) { uint32_t size = mResponseText.Length() + destBufferLen;
if (size < (uint32_t)destBufferLen) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!mResponseText.SetCapacity(size, fallible)) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
char16_t* destBuffer = mResponseText.BeginWriting() + mResponseText.Length(); char16_t* destBuffer = mResponseText.BeginWriting() + mResponseText.Length();
int32_t totalChars = mResponseText.Length(); CheckedInt32 totalChars = mResponseText.Length();
// This code here is basically a copy of a similar thing in // This code here is basically a copy of a similar thing in
// nsScanner::Append(const char* aBuffer, uint32_t aLen). // nsScanner::Append(const char* aBuffer, uint32_t aLen).
@ -697,9 +702,11 @@ nsXMLHttpRequest::AppendToResponseText(const char * aSrcBuffer,
MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(NS_SUCCEEDED(rv));
totalChars += destlen; totalChars += destlen;
if (!totalChars.isValid()) {
return NS_ERROR_OUT_OF_MEMORY;
}
mResponseText.SetLength(totalChars); mResponseText.SetLength(totalChars.value());
return NS_OK; return NS_OK;
} }

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

@ -756,6 +756,11 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject); JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject);
request = IDBOpenDBRequest::CreateForJS(this, scriptOwner); request = IDBOpenDBRequest::CreateForJS(this, scriptOwner);
if (!request) {
MOZ_ASSERT(!NS_IsMainThread());
aRv.ThrowUncatchableException();
return nullptr;
}
} }
MOZ_ASSERT(request); MOZ_ASSERT(request);

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

@ -442,11 +442,19 @@ class IDBOpenDBRequest::WorkerFeature final
: public mozilla::dom::workers::WorkerFeature : public mozilla::dom::workers::WorkerFeature
{ {
WorkerPrivate* mWorkerPrivate; WorkerPrivate* mWorkerPrivate;
#ifdef DEBUG
// This is only here so that assertions work in the destructor even if
// NoteAddFeatureFailed was called.
WorkerPrivate* mWorkerPrivateDEBUG;
#endif
public: public:
explicit explicit
WorkerFeature(WorkerPrivate* aWorkerPrivate) WorkerFeature(WorkerPrivate* aWorkerPrivate)
: mWorkerPrivate(aWorkerPrivate) : mWorkerPrivate(aWorkerPrivate)
#ifdef DEBUG
, mWorkerPrivateDEBUG(aWorkerPrivate)
#endif
{ {
MOZ_ASSERT(aWorkerPrivate); MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread(); aWorkerPrivate->AssertIsOnWorkerThread();
@ -456,11 +464,24 @@ public:
~WorkerFeature() ~WorkerFeature()
{ {
mWorkerPrivate->AssertIsOnWorkerThread(); #ifdef DEBUG
mWorkerPrivateDEBUG->AssertIsOnWorkerThread();
#endif
MOZ_COUNT_DTOR(IDBOpenDBRequest::WorkerFeature); MOZ_COUNT_DTOR(IDBOpenDBRequest::WorkerFeature);
mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); if (mWorkerPrivate) {
mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this);
}
}
void
NoteAddFeatureFailed()
{
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
mWorkerPrivate = nullptr;
} }
private: private:
@ -527,6 +548,7 @@ IDBOpenDBRequest::CreateForJS(IDBFactory* aFactory,
nsAutoPtr<WorkerFeature> feature(new WorkerFeature(workerPrivate)); nsAutoPtr<WorkerFeature> feature(new WorkerFeature(workerPrivate));
if (NS_WARN_IF(!workerPrivate->AddFeature(cx, feature))) { if (NS_WARN_IF(!workerPrivate->AddFeature(cx, feature))) {
feature->NoteAddFeatureFailed();
return nullptr; return nullptr;
} }

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

@ -5,20 +5,11 @@
#include "domstubs.idl" #include "domstubs.idl"
[scriptable, uuid(4237c376-d637-4b6e-9f8a-1da57e867834)] [scriptable, uuid(e0f739e3-47e2-4007-af30-181939e97a51)]
interface nsIDOMJSWindow : nsISupports interface nsIDOMJSWindow : nsISupports
{ {
void dump(in DOMString str); void dump(in DOMString str);
/**
* These methods take typeless arguments and optional arguments, the
* first argument is either a function or a string, the second
* argument must be a number (ms) and the rest of the arguments (2
* ... n) are passed to the callback function
*/
long setTimeout();
long setInterval();
/** /**
* These methods take one optional argument that's the timer ID to * These methods take one optional argument that's the timer ID to
* clear. Often in existing code these methods are passed undefined, * clear. Often in existing code these methods are passed undefined,

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

@ -104,13 +104,12 @@ void InitPreferredSampleRate()
cubeb* GetCubebContextUnlocked() cubeb* GetCubebContextUnlocked()
{ {
sMutex.AssertCurrentThreadOwns(); sMutex.AssertCurrentThreadOwns();
if (!sCubebContext) { if (sCubebContext ||
MOZ_ASSERT(NS_IsMainThread()); cubeb_init(&sCubebContext, "CubebUtils") == CUBEB_OK) {
if (cubeb_init(&sCubebContext, "CubebUtils") != CUBEB_OK) { return sCubebContext;
NS_WARNING("cubeb_init failed");
}
} }
return sCubebContext; NS_WARNING("cubeb_init failed");
return nullptr;
} }
uint32_t GetCubebLatency() uint32_t GetCubebLatency()

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

@ -10,7 +10,6 @@
#include <limits> #include <limits>
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "CubebUtils.h"
#include "VideoUtils.h" #include "VideoUtils.h"
#include "MediaDecoderStateMachine.h" #include "MediaDecoderStateMachine.h"
#include "ImageContainer.h" #include "ImageContainer.h"
@ -402,11 +401,6 @@ bool MediaDecoder::Init(MediaDecoderOwner* aOwner)
mOwner = aOwner; mOwner = aOwner;
mVideoFrameContainer = aOwner->GetVideoFrameContainer(); mVideoFrameContainer = aOwner->GetVideoFrameContainer();
MediaShutdownManager::Instance().Register(this); MediaShutdownManager::Instance().Register(this);
// We don't use the cubeb context yet, but need to ensure it is created on
// the main thread.
if (!CubebUtils::GetCubebContext()) {
NS_WARNING("Audio backend initialization failed.");
}
return true; return true;
} }

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

@ -286,6 +286,11 @@ public:
class EncryptionInfo { class EncryptionInfo {
public: public:
EncryptionInfo()
: mEncrypted(false)
{
}
struct InitData { struct InitData {
template<typename AInitDatas> template<typename AInitDatas>
InitData(const nsAString& aType, AInitDatas&& aInitData) InitData(const nsAString& aType, AInitDatas&& aInitData)
@ -305,22 +310,26 @@ public:
// True if the stream has encryption metadata // True if the stream has encryption metadata
bool IsEncrypted() const bool IsEncrypted() const
{ {
return !mInitDatas.IsEmpty(); return mEncrypted;
} }
template<typename AInitDatas> template<typename AInitDatas>
void AddInitData(const nsAString& aType, AInitDatas&& aInitData) void AddInitData(const nsAString& aType, AInitDatas&& aInitData)
{ {
mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData))); mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData)));
mEncrypted = true;
} }
void AddInitData(const EncryptionInfo& aInfo) void AddInitData(const EncryptionInfo& aInfo)
{ {
mInitDatas.AppendElements(aInfo.mInitDatas); mInitDatas.AppendElements(aInfo.mInitDatas);
mEncrypted = !!mInitDatas.Length();
} }
// One 'InitData' per encrypted buffer. // One 'InitData' per encrypted buffer.
InitDatas mInitDatas; InitDatas mInitDatas;
private:
bool mEncrypted;
}; };
class MediaInfo { class MediaInfo {

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

@ -31,6 +31,7 @@ using mozilla::dom::CrashReporterParent;
using mozilla::ipc::GeckoChildProcessHost; using mozilla::ipc::GeckoChildProcessHost;
#ifdef MOZ_CRASHREPORTER #ifdef MOZ_CRASHREPORTER
#include "nsPrintfCString.h"
using CrashReporter::AnnotationTable; using CrashReporter::AnnotationTable;
using CrashReporter::GetIDFromMinidump; using CrashReporter::GetIDFromMinidump;
#endif #endif
@ -196,6 +197,11 @@ AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure)
{ {
NS_WARNING("Timed out waiting for GMP async shutdown!"); NS_WARNING("Timed out waiting for GMP async shutdown!");
GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure); GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure);
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", parent->GetDisplayName().get(), parent),
NS_LITERAL_CSTRING("Timed out waiting for async shutdown"));
#endif
nsRefPtr<GeckoMediaPluginServiceParent> service = nsRefPtr<GeckoMediaPluginServiceParent> service =
GeckoMediaPluginServiceParent::GetSingleton(); GeckoMediaPluginServiceParent::GetSingleton();
if (service) { if (service) {
@ -239,8 +245,20 @@ GMPParent::RecvPGMPContentChildDestroyed()
{ {
--mGMPContentChildCount; --mGMPContentChildCount;
if (!IsUsed()) { if (!IsUsed()) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Content children destroyed"));
#endif
CloseIfUnused(); CloseIfUnused();
} }
#if defined(MOZ_CRASHREPORTER)
else {
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
nsPrintfCString("Content child destroyed, remaining: %u", mGMPContentChildCount));
}
#endif
return true; return true;
} }
@ -262,9 +280,19 @@ GMPParent::CloseIfUnused()
if (mAsyncShutdownRequired) { if (mAsyncShutdownRequired) {
if (!mAsyncShutdownInProgress) { if (!mAsyncShutdownInProgress) {
LOGD("%s: sending async shutdown notification", __FUNCTION__); LOGD("%s: sending async shutdown notification", __FUNCTION__);
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Sent BeginAsyncShutdown"));
#endif
mAsyncShutdownInProgress = true; mAsyncShutdownInProgress = true;
if (!SendBeginAsyncShutdown() || if (!SendBeginAsyncShutdown() ||
NS_FAILED(EnsureAsyncShutdownTimeoutSet())) { NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Could not send BeginAsyncShutdown - Aborting"));
#endif
AbortAsyncShutdown(); AbortAsyncShutdown();
} }
} }
@ -313,6 +341,11 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
mState = GMPStateUnloading; mState = GMPStateUnloading;
} }
if (mState != GMPStateNotLoaded && IsUsed()) { if (mState != GMPStateNotLoaded && IsUsed()) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
nsPrintfCString("Sent CloseActive, content children to close: %u", mGMPContentChildCount));
#endif
unused << SendCloseActive(); unused << SendCloseActive();
} }
} }
@ -568,6 +601,11 @@ GMPParent::ActorDestroy(ActorDestroyReason aWhy)
if (AbnormalShutdown == aWhy) { if (AbnormalShutdown == aWhy) {
nsRefPtr<GMPParent> self(this); nsRefPtr<GMPParent> self(this);
if (mAsyncShutdownRequired) { if (mAsyncShutdownRequired) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Actor destroyed"));
#endif
mService->AsyncShutdownComplete(this); mService->AsyncShutdownComplete(this);
mAsyncShutdownRequired = false; mAsyncShutdownRequired = false;
} }
@ -870,6 +908,11 @@ GMPParent::RecvAsyncShutdownComplete()
LOGD("%s", __FUNCTION__); LOGD("%s", __FUNCTION__);
MOZ_ASSERT(mAsyncShutdownRequired); MOZ_ASSERT(mAsyncShutdownRequired);
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Received AsyncShutdownComplete"));
#endif
AbortAsyncShutdown(); AbortAsyncShutdown();
return true; return true;
} }

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

@ -316,7 +316,7 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aMediaSource); MOZ_ASSERT(aMediaSource);
mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold", mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold",
75 * (1 << 20)); 100 * (1 << 20));
mContentManager = mContentManager =
SourceBufferContentManager::CreateManager(this, SourceBufferContentManager::CreateManager(this,
aMediaSource->GetDecoder(), aMediaSource->GetDecoder(),
@ -581,7 +581,7 @@ SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult&
// See if we have enough free space to append our new data. // See if we have enough free space to append our new data.
// As we can only evict once we have playable data, we must give a chance // As we can only evict once we have playable data, we must give a chance
// to the DASH player to provide a complete media segment. // to the DASH player to provide a complete media segment.
if (aLength > mEvictionThreshold || if (aLength > mEvictionThreshold || evicted == Result::BUFFER_FULL ||
((!mIsUsingFormatReader && ((!mIsUsingFormatReader &&
mContentManager->GetSize() > mEvictionThreshold - aLength) && mContentManager->GetSize() > mEvictionThreshold - aLength) &&
evicted != Result::CANT_EVICT)) { evicted != Result::CANT_EVICT)) {
@ -594,7 +594,6 @@ SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult&
aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR); aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
return nullptr; return nullptr;
} }
// TODO: Test buffer full flag.
return data.forget(); return data.forget();
} }

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

@ -57,6 +57,7 @@ public:
NO_DATA_EVICTED, NO_DATA_EVICTED,
DATA_EVICTED, DATA_EVICTED,
CANT_EVICT, CANT_EVICT,
BUFFER_FULL,
}; };
// Evicts data up to aPlaybackTime. aThreshold is used to // Evicts data up to aPlaybackTime. aThreshold is used to

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

@ -39,6 +39,34 @@ AppendStateToStr(TrackBuffersManager::AppendState aState)
static Atomic<uint32_t> sStreamSourceID(0u); static Atomic<uint32_t> sStreamSourceID(0u);
#ifdef MOZ_EME
class DispatchKeyNeededEvent : public nsRunnable {
public:
DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
nsTArray<uint8_t>& aInitData,
const nsString& aInitDataType)
: mDecoder(aDecoder)
, mInitData(aInitData)
, mInitDataType(aInitDataType)
{
}
NS_IMETHOD Run() {
// Note: Null check the owner, as the decoder could have been shutdown
// since this event was dispatched.
MediaDecoderOwner* owner = mDecoder->GetOwner();
if (owner) {
owner->DispatchEncrypted(mInitData, mInitDataType);
}
mDecoder = nullptr;
return NS_OK;
}
private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
nsTArray<uint8_t> mInitData;
nsString mInitDataType;
};
#endif // MOZ_EME
TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType) TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType)
: mInputBuffer(new MediaByteBuffer) : mInputBuffer(new MediaByteBuffer)
, mAppendState(AppendState::WAITING_FOR_SEGMENT) , mAppendState(AppendState::WAITING_FOR_SEGMENT)
@ -55,6 +83,9 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSource
, mMediaSourceDemuxer(mParentDecoder->GetDemuxer()) , mMediaSourceDemuxer(mParentDecoder->GetDemuxer())
, mMediaSourceDuration(mTaskQueue, Maybe<double>(), "TrackBuffersManager::mMediaSourceDuration (Mirror)") , mMediaSourceDuration(mTaskQueue, Maybe<double>(), "TrackBuffersManager::mMediaSourceDuration (Mirror)")
, mAbort(false) , mAbort(false)
, mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold",
100 * (1 << 20)))
, mEvictionOccurred(false)
, mMonitor("TrackBuffersManager") , mMonitor("TrackBuffersManager")
{ {
MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread"); MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread");
@ -176,6 +207,11 @@ TrackBuffersManager::EvictData(TimeUnit aPlaybackTime,
// Don't bother evicting less than 512KB. // Don't bother evicting less than 512KB.
return EvictDataResult::CANT_EVICT; return EvictDataResult::CANT_EVICT;
} }
if (mBufferFull && mEvictionOccurred) {
return EvictDataResult::BUFFER_FULL;
}
MSE_DEBUG("Reaching our size limit, schedule eviction of %lld bytes", toEvict); MSE_DEBUG("Reaching our size limit, schedule eviction of %lld bytes", toEvict);
nsCOMPtr<nsIRunnable> task = nsCOMPtr<nsIRunnable> task =
@ -345,12 +381,12 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
{ {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
// Remove any data we've already played, up to 5s behind.
TimeUnit lowerLimit = aPlaybackTime - TimeUnit::FromSeconds(5);
TimeUnit to;
// Video is what takes the most space, only evict there if we have video. // Video is what takes the most space, only evict there if we have video.
const auto& track = HasVideo() ? mVideoTracks : mAudioTracks; const auto& track = HasVideo() ? mVideoTracks : mAudioTracks;
const auto& buffer = track.mBuffers.LastElement(); const auto& buffer = track.mBuffers.LastElement();
// Remove any data we've already played, or before the next sample to be
// demuxed whichever is lowest.
TimeUnit lowerLimit = std::min(track.mNextSampleTime, aPlaybackTime);
uint32_t lastKeyFrameIndex = 0; uint32_t lastKeyFrameIndex = 0;
int64_t toEvict = aSizeToEvict; int64_t toEvict = aSizeToEvict;
uint32_t partialEvict = 0; uint32_t partialEvict = 0;
@ -369,18 +405,29 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
} }
partialEvict += sizeof(*frame) + frame->mSize; partialEvict += sizeof(*frame) + frame->mSize;
} }
int64_t finalSize = mSizeSourceBuffer - aSizeToEvict;
if (lastKeyFrameIndex > 0) { if (lastKeyFrameIndex > 0) {
MSE_DEBUG("Step1. Evicting %u bytes prior currentTime",
aSizeToEvict - toEvict);
CodedFrameRemoval( CodedFrameRemoval(
TimeInterval(TimeUnit::FromMicroseconds(0), TimeInterval(TimeUnit::FromMicroseconds(0),
TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex-1]->mTime))); TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex]->mTime - 1)));
} }
if (toEvict <= 0) {
if (mSizeSourceBuffer <= finalSize) {
return; return;
} }
// Still some to remove. Remove data starting from the end, up to 5s ahead toEvict = mSizeSourceBuffer - finalSize;
// of our playtime.
TimeUnit upperLimit = aPlaybackTime + TimeUnit::FromSeconds(5); // Still some to remove. Remove data starting from the end, up to 30s ahead
// of the later of the playback time or the next sample to be demuxed.
// 30s is a value chosen as it appears to work with YouTube.
TimeUnit upperLimit =
std::max(aPlaybackTime, track.mNextSampleTime) + TimeUnit::FromSeconds(30);
lastKeyFrameIndex = buffer.Length();
for (int32_t i = buffer.Length() - 1; i >= 0; i--) { for (int32_t i = buffer.Length() - 1; i >= 0; i--) {
const auto& frame = buffer[i]; const auto& frame = buffer[i];
if (frame->mKeyframe) { if (frame->mKeyframe) {
@ -396,9 +443,11 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
} }
partialEvict += sizeof(*frame) + frame->mSize; partialEvict += sizeof(*frame) + frame->mSize;
} }
if (lastKeyFrameIndex + 1 < buffer.Length()) { if (lastKeyFrameIndex < buffer.Length()) {
MSE_DEBUG("Step2. Evicting %u bytes from trailing data",
mSizeSourceBuffer - finalSize);
CodedFrameRemoval( CodedFrameRemoval(
TimeInterval(TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex+1]->mTime), TimeInterval(TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex]->GetEndTime() + 1),
TimeUnit::FromInfinity())); TimeUnit::FromInfinity()));
} }
} }
@ -559,9 +608,7 @@ TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval)
// This will be done by the MDSM during playback. // This will be done by the MDSM during playback.
// TODO properly, so it works even if paused. // TODO properly, so it works even if paused.
} }
// 4. If buffer full flag equals true and this object is ready to accept more bytes, then set the buffer full flag to false.
// TODO.
mBufferFull = false;
{ {
MonitorAutoLock mon(mMonitor); MonitorAutoLock mon(mMonitor);
mVideoBufferedRanges = mVideoTracks.mBufferedRanges; mVideoBufferedRanges = mVideoTracks.mBufferedRanges;
@ -580,6 +627,12 @@ TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval)
// Update our reported total size. // Update our reported total size.
mSizeSourceBuffer = mVideoTracks.mSizeBuffer + mAudioTracks.mSizeBuffer; mSizeSourceBuffer = mVideoTracks.mSizeBuffer + mAudioTracks.mSizeBuffer;
// 4. If buffer full flag equals true and this object is ready to accept more bytes, then set the buffer full flag to false.
if (mBufferFull && mSizeSourceBuffer < mEvictionThreshold) {
mBufferFull = false;
}
mEvictionOccurred = true;
// Tell our demuxer that data was removed. // Tell our demuxer that data was removed.
mMediaSourceDemuxer->NotifyTimeRangesChanged(); mMediaSourceDemuxer->NotifyTimeRangesChanged();
@ -953,17 +1006,19 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
mVideoTracks.mLastInfo = new SharedTrackInfo(info.mVideo, streamID); mVideoTracks.mLastInfo = new SharedTrackInfo(info.mVideo, streamID);
} }
// TODO CHECK ENCRYPTION
UniquePtr<EncryptionInfo> crypto = mInputDemuxer->GetCrypto(); UniquePtr<EncryptionInfo> crypto = mInputDemuxer->GetCrypto();
if (crypto && crypto->IsEncrypted()) { if (crypto && crypto->IsEncrypted()) {
#ifdef MOZ_EME #ifdef MOZ_EME
// Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING. // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) { for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
// NS_DispatchToMainThread( NS_DispatchToMainThread(
// new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc"))); new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
} }
#endif // MOZ_EME #endif // MOZ_EME
info.mCrypto = *crypto; info.mCrypto = *crypto;
// We clear our crypto init data array, so the MediaFormatReader will
// not emit an encrypted event for the same init data again.
info.mCrypto.mInitDatas.Clear();
mEncrypted = true; mEncrypted = true;
} }
@ -1180,8 +1235,10 @@ TrackBuffersManager::CompleteCodedFrameProcessing()
// Return to step 6.4 of Segment Parser Loop algorithm // Return to step 6.4 of Segment Parser Loop algorithm
// 4. If this SourceBuffer is full and cannot accept more media data, then set the buffer full flag to true. // 4. If this SourceBuffer is full and cannot accept more media data, then set the buffer full flag to true.
// TODO if (mSizeSourceBuffer >= mEvictionThreshold) {
mBufferFull = false; mBufferFull = true;
mEvictionOccurred = false;
}
// 5. If the input buffer does not contain a complete media segment, then jump to the need more data step below. // 5. If the input buffer does not contain a complete media segment, then jump to the need more data step below.
if (mParser->MediaSegmentRange().IsNull()) { if (mParser->MediaSegmentRange().IsNull()) {
@ -1360,78 +1417,84 @@ TrackBuffersManager::ProcessFrame(MediaRawData* aSample,
Maybe<uint32_t> firstRemovedIndex; Maybe<uint32_t> firstRemovedIndex;
TimeInterval removedInterval; TimeInterval removedInterval;
TrackBuffer& data = trackBuffer.mBuffers.LastElement(); TrackBuffer& data = trackBuffer.mBuffers.LastElement();
if (trackBuffer.mBufferedRanges.ContainsStrict(presentationTimestamp)) { bool removeCodedFrames =
trackBuffer.mHighestEndTimestamp.isSome()
? trackBuffer.mHighestEndTimestamp.ref() <= presentationTimestamp
: true;
if (removeCodedFrames) {
TimeUnit lowerBound = TimeUnit lowerBound =
trackBuffer.mHighestEndTimestamp.valueOr(presentationTimestamp); trackBuffer.mHighestEndTimestamp.valueOr(presentationTimestamp);
for (uint32_t i = 0; i < data.Length();) { if (trackBuffer.mBufferedRanges.ContainsStrict(lowerBound)) {
MediaRawData* sample = data[i].get(); for (uint32_t i = 0; i < data.Length();) {
if (sample->mTime >= lowerBound.ToMicroseconds() && MediaRawData* sample = data[i].get();
sample->mTime < frameEndTimestamp.ToMicroseconds()) { if (sample->mTime >= lowerBound.ToMicroseconds() &&
if (firstRemovedIndex.isNothing()) { sample->mTime < frameEndTimestamp.ToMicroseconds()) {
removedInterval = if (firstRemovedIndex.isNothing()) {
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime), removedInterval =
TimeUnit::FromMicroseconds(sample->GetEndTime())); TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
firstRemovedIndex = Some(i); TimeUnit::FromMicroseconds(sample->GetEndTime()));
} else { firstRemovedIndex = Some(i);
removedInterval = removedInterval.Span( } else {
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime), removedInterval = removedInterval.Span(
TimeUnit::FromMicroseconds(sample->GetEndTime()))); TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
} TimeUnit::FromMicroseconds(sample->GetEndTime())));
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
MSE_DEBUGV("Overlapping frame:%u ([%f, %f))",
i,
TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(),
TimeUnit::FromMicroseconds(sample->GetEndTime()).ToSeconds());
data.RemoveElementAt(i);
if (trackBuffer.mNextGetSampleIndex.isSome()) {
if (trackBuffer.mNextGetSampleIndex.ref() == i) {
MSE_DEBUG("Next sample to be played got evicted");
trackBuffer.mNextGetSampleIndex.reset();
} else if (trackBuffer.mNextGetSampleIndex.ref() > i) {
trackBuffer.mNextGetSampleIndex.ref()--;
} }
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
MSE_DEBUGV("Overlapping frame:%u ([%f, %f))",
i,
TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(),
TimeUnit::FromMicroseconds(sample->GetEndTime()).ToSeconds());
data.RemoveElementAt(i);
if (trackBuffer.mNextGetSampleIndex.isSome()) {
if (trackBuffer.mNextGetSampleIndex.ref() == i) {
MSE_DEBUG("Next sample to be played got evicted");
trackBuffer.mNextGetSampleIndex.reset();
} else if (trackBuffer.mNextGetSampleIndex.ref() > i) {
trackBuffer.mNextGetSampleIndex.ref()--;
}
}
} else {
i++;
} }
} else {
i++;
} }
} }
} // 15. Remove decoding dependencies of the coded frames removed in the previous step:
// 15. Remove decoding dependencies of the coded frames removed in the previous step: // Remove all coded frames between the coded frames removed in the previous step and the next random access point after those removed frames.
// Remove all coded frames between the coded frames removed in the previous step and the next random access point after those removed frames. if (firstRemovedIndex.isSome()) {
if (firstRemovedIndex.isSome()) { uint32_t start = firstRemovedIndex.ref();
uint32_t start = firstRemovedIndex.ref(); uint32_t end = start;
uint32_t end = start; for (;end < data.Length(); end++) {
for (;end < data.Length(); end++) { MediaRawData* sample = data[end].get();
MediaRawData* sample = data[end].get(); if (sample->mKeyframe) {
if (sample->mKeyframe) { break;
break; }
removedInterval = removedInterval.Span(
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
TimeUnit::FromMicroseconds(sample->GetEndTime())));
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
} }
removedInterval = removedInterval.Span( data.RemoveElementsAt(start, end - start);
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
TimeUnit::FromMicroseconds(sample->GetEndTime())));
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
}
data.RemoveElementsAt(start, end - start);
MSE_DEBUG("Removing undecodable frames from:%u (frames:%u) ([%f, %f))", MSE_DEBUG("Removing undecodable frames from:%u (frames:%u) ([%f, %f))",
start, end - start, start, end - start,
removedInterval.mStart.ToSeconds(), removedInterval.mEnd.ToSeconds()); removedInterval.mStart.ToSeconds(), removedInterval.mEnd.ToSeconds());
if (trackBuffer.mNextGetSampleIndex.isSome()) { if (trackBuffer.mNextGetSampleIndex.isSome()) {
if (trackBuffer.mNextGetSampleIndex.ref() >= start && if (trackBuffer.mNextGetSampleIndex.ref() >= start &&
trackBuffer.mNextGetSampleIndex.ref() < end) { trackBuffer.mNextGetSampleIndex.ref() < end) {
MSE_DEBUG("Next sample to be played got evicted"); MSE_DEBUG("Next sample to be played got evicted");
trackBuffer.mNextGetSampleIndex.reset(); trackBuffer.mNextGetSampleIndex.reset();
} else if (trackBuffer.mNextGetSampleIndex.ref() >= end) { } else if (trackBuffer.mNextGetSampleIndex.ref() >= end) {
trackBuffer.mNextGetSampleIndex.ref() -= end - start; trackBuffer.mNextGetSampleIndex.ref() -= end - start;
}
} }
}
// Update our buffered range to exclude the range just removed. // Update our buffered range to exclude the range just removed.
trackBuffer.mBufferedRanges -= removedInterval; trackBuffer.mBufferedRanges -= removedInterval;
MOZ_ASSERT(trackBuffer.mNextInsertionIndex.isNothing() || MOZ_ASSERT(trackBuffer.mNextInsertionIndex.isNothing() ||
trackBuffer.mNextInsertionIndex.ref() <= start); trackBuffer.mNextInsertionIndex.ref() <= start);
}
} }
// 16. Add the coded frame with the presentation timestamp, decode timestamp, and frame duration to the track buffer. // 16. Add the coded frame with the presentation timestamp, decode timestamp, and frame duration to the track buffer.
@ -1564,11 +1627,11 @@ TrackBuffersManager::RestoreCachedVariables()
{ {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
if (mTimestampOffset != mLastTimestampOffset) { if (mTimestampOffset != mLastTimestampOffset) {
nsRefPtr<TrackBuffersManager> self = this;
nsCOMPtr<nsIRunnable> task = nsCOMPtr<nsIRunnable> task =
NS_NewRunnableMethodWithArg<TimeUnit>( NS_NewRunnableFunction([self] {
mParent.get(), self->mParent->SetTimestampOffset(self->mTimestampOffset);
static_cast<void (dom::SourceBuffer::*)(const TimeUnit&)>(&dom::SourceBuffer::SetTimestampOffset), /* beauty uh? :) */ });
mTimestampOffset);
AbstractThread::MainThread()->Dispatch(task.forget()); AbstractThread::MainThread()->Dispatch(task.forget());
} }
} }

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

@ -310,6 +310,8 @@ private:
// Global size of this source buffer content. // Global size of this source buffer content.
Atomic<int64_t> mSizeSourceBuffer; Atomic<int64_t> mSizeSourceBuffer;
uint32_t mEvictionThreshold;
Atomic<bool> mEvictionOccurred;
// Monitor to protect following objects accessed across multipple threads. // Monitor to protect following objects accessed across multipple threads.
mutable Monitor mMonitor; mutable Monitor mMonitor;

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

@ -110,11 +110,6 @@ AudioContext::AudioContext(nsPIDOMWindow* aWindow,
// call them after mDestination has been set up. // call them after mDestination has been set up.
mDestination->CreateAudioChannelAgent(); mDestination->CreateAudioChannelAgent();
mDestination->SetIsOnlyNodeForContext(true); mDestination->SetIsOnlyNodeForContext(true);
// We don't use the cubeb context yet, but need to ensure it is created on
// the main thread.
if (!aIsOffline && !CubebUtils::GetCubebContext()) {
NS_WARNING("Audio backend initialization failed.");
}
} }
AudioContext::~AudioContext() AudioContext::~AudioContext()

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

@ -771,8 +771,11 @@ DOMStorageCache::StartDatabase()
sDatabase = db.forget(); sDatabase = db.forget();
} else { } else {
// Use DOMLocalStorageManager::Ensure in case we're called from
// DOMSessionStorageManager's initializer and we haven't yet initialized the
// local storage manager.
nsRefPtr<DOMStorageDBChild> db = new DOMStorageDBChild( nsRefPtr<DOMStorageDBChild> db = new DOMStorageDBChild(
DOMLocalStorageManager::Self()); DOMLocalStorageManager::Ensure());
nsresult rv = db->Init(); nsresult rv = db->Init();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {

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

@ -628,6 +628,21 @@ DOMLocalStorageManager::~DOMLocalStorageManager()
sSelf = nullptr; sSelf = nullptr;
} }
DOMLocalStorageManager*
DOMLocalStorageManager::Ensure()
{
if (sSelf) {
return sSelf;
}
// Cause sSelf to be populated.
nsCOMPtr<nsIDOMStorageManager> initializer =
do_GetService("@mozilla.org/dom/localStorage-manager;1");
MOZ_ASSERT(sSelf, "Didn't initialize?");
return sSelf;
}
// DOMSessionStorageManager // DOMSessionStorageManager
DOMSessionStorageManager::DOMSessionStorageManager() DOMSessionStorageManager::DOMSessionStorageManager()

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

@ -126,6 +126,9 @@ public:
// Global getter of localStorage manager service // Global getter of localStorage manager service
static DOMLocalStorageManager* Self() { return sSelf; } static DOMLocalStorageManager* Self() { return sSelf; }
// Like Self, but creates an instance if we're not yet initialized.
static DOMLocalStorageManager* Ensure();
private: private:
static DOMLocalStorageManager* sSelf; static DOMLocalStorageManager* sSelf;
}; };

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

@ -379,6 +379,7 @@ NS_INTERFACE_MAP_END
ServiceWorkerManager::ServiceWorkerManager() ServiceWorkerManager::ServiceWorkerManager()
: mActor(nullptr) : mActor(nullptr)
, mShuttingDown(false)
{ {
// Register this component to PBackground. // Register this component to PBackground.
MOZ_ALWAYS_TRUE(BackgroundChild::GetOrCreateForCurrentThread(this)); MOZ_ALWAYS_TRUE(BackgroundChild::GetOrCreateForCurrentThread(this));
@ -388,19 +389,19 @@ ServiceWorkerManager::~ServiceWorkerManager()
{ {
// The map will assert if it is not empty when destroyed. // The map will assert if it is not empty when destroyed.
mRegistrationInfos.Clear(); mRegistrationInfos.Clear();
MOZ_ASSERT(!mActor);
if (mActor) {
mActor->ManagerShuttingDown();
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
nsresult rv = NS_DispatchToMainThread(runnable);
unused << NS_WARN_IF(NS_FAILED(rv));
}
} }
void void
ServiceWorkerManager::Init() ServiceWorkerManager::Init()
{ {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
DebugOnly<nsresult> rv;
rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false /* ownsWeak */);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
if (XRE_GetProcessType() == GeckoProcessType_Default) { if (XRE_GetProcessType() == GeckoProcessType_Default) {
nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get(); nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
MOZ_ASSERT(swr); MOZ_ASSERT(swr);
@ -409,11 +410,8 @@ ServiceWorkerManager::Init()
swr->GetRegistrations(data); swr->GetRegistrations(data);
LoadRegistrations(data); LoadRegistrations(data);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) { if (obs) {
DebugOnly<nsresult> rv; DebugOnly<nsresult> rv;
rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false /* ownsWeak */);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = obs->AddObserver(this, PURGE_SESSION_HISTORY, false /* ownsWeak */); rv = obs->AddObserver(this, PURGE_SESSION_HISTORY, false /* ownsWeak */);
MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = obs->AddObserver(this, PURGE_DOMAIN_DATA, false /* ownsWeak */); rv = obs->AddObserver(this, PURGE_DOMAIN_DATA, false /* ownsWeak */);
@ -872,6 +870,7 @@ class ServiceWorkerRegisterJob final : public ServiceWorkerJob,
nsRefPtr<ServiceWorkerUpdateFinishCallback> mCallback; nsRefPtr<ServiceWorkerUpdateFinishCallback> mCallback;
nsCOMPtr<nsIPrincipal> mPrincipal; nsCOMPtr<nsIPrincipal> mPrincipal;
nsRefPtr<ServiceWorkerInfo> mUpdateAndInstallInfo; nsRefPtr<ServiceWorkerInfo> mUpdateAndInstallInfo;
nsCOMPtr<nsILoadGroup> mLoadGroup;
~ServiceWorkerRegisterJob() ~ServiceWorkerRegisterJob()
{ } { }
@ -892,15 +891,19 @@ public:
const nsCString& aScope, const nsCString& aScope,
const nsCString& aScriptSpec, const nsCString& aScriptSpec,
ServiceWorkerUpdateFinishCallback* aCallback, ServiceWorkerUpdateFinishCallback* aCallback,
nsIPrincipal* aPrincipal) nsIPrincipal* aPrincipal,
nsILoadGroup* aLoadGroup)
: ServiceWorkerJob(aQueue) : ServiceWorkerJob(aQueue)
, mScope(aScope) , mScope(aScope)
, mScriptSpec(aScriptSpec) , mScriptSpec(aScriptSpec)
, mCallback(aCallback) , mCallback(aCallback)
, mPrincipal(aPrincipal) , mPrincipal(aPrincipal)
, mLoadGroup(aLoadGroup)
, mJobType(REGISTER_JOB) , mJobType(REGISTER_JOB)
, mCanceled(false) , mCanceled(false)
{ } {
MOZ_ASSERT(mLoadGroup);
}
// [[Update]] // [[Update]]
ServiceWorkerRegisterJob(ServiceWorkerJobQueue* aQueue, ServiceWorkerRegisterJob(ServiceWorkerJobQueue* aQueue,
@ -1230,7 +1233,7 @@ private:
nsresult rv = nsresult rv =
serviceWorkerScriptCache::Compare(mRegistration->mPrincipal, cacheName, serviceWorkerScriptCache::Compare(mRegistration->mPrincipal, cacheName,
NS_ConvertUTF8toUTF16(mRegistration->mScriptSpec), NS_ConvertUTF8toUTF16(mRegistration->mScriptSpec),
this); this, mLoadGroup);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return Fail(rv); return Fail(rv);
} }
@ -1534,8 +1537,20 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
nsRefPtr<ServiceWorkerResolveWindowPromiseOnUpdateCallback> cb = nsRefPtr<ServiceWorkerResolveWindowPromiseOnUpdateCallback> cb =
new ServiceWorkerResolveWindowPromiseOnUpdateCallback(window, promise); new ServiceWorkerResolveWindowPromiseOnUpdateCallback(window, promise);
nsCOMPtr<nsILoadGroup> docLoadGroup = doc->GetDocumentLoadGroup();
nsRefPtr<WorkerLoadInfo::InterfaceRequestor> ir =
new WorkerLoadInfo::InterfaceRequestor(documentPrincipal, docLoadGroup);
ir->MaybeAddTabChild(docLoadGroup);
// Create a load group that is separate from, yet related to, the document's load group.
// This allows checks for interfaces like nsILoadContext to yield the values used by the
// the document, yet will not cancel the update job if the document's load group is cancelled.
nsCOMPtr<nsILoadGroup> loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
rv = loadGroup->SetNotificationCallbacks(ir);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
nsRefPtr<ServiceWorkerRegisterJob> job = nsRefPtr<ServiceWorkerRegisterJob> job =
new ServiceWorkerRegisterJob(queue, cleanedScope, spec, cb, documentPrincipal); new ServiceWorkerRegisterJob(queue, cleanedScope, spec, cb, documentPrincipal, loadGroup);
queue->Append(job); queue->Append(job);
AssertIsOnMainThread(); AssertIsOnMainThread();
@ -1553,9 +1568,11 @@ ServiceWorkerManager::AppendPendingOperation(ServiceWorkerJobQueue* aQueue,
MOZ_ASSERT(aQueue); MOZ_ASSERT(aQueue);
MOZ_ASSERT(aJob); MOZ_ASSERT(aJob);
PendingOperation* opt = mPendingOperations.AppendElement(); if (!mShuttingDown) {
opt->mQueue = aQueue; PendingOperation* opt = mPendingOperations.AppendElement();
opt->mJob = aJob; opt->mQueue = aQueue;
opt->mJob = aJob;
}
} }
void void
@ -1564,8 +1581,10 @@ ServiceWorkerManager::AppendPendingOperation(nsIRunnable* aRunnable)
MOZ_ASSERT(!mActor); MOZ_ASSERT(!mActor);
MOZ_ASSERT(aRunnable); MOZ_ASSERT(aRunnable);
PendingOperation* opt = mPendingOperations.AppendElement(); if (!mShuttingDown) {
opt->mRunnable = aRunnable; PendingOperation* opt = mPendingOperations.AppendElement();
opt->mRunnable = aRunnable;
}
} }
/* /*
@ -2383,8 +2402,10 @@ private:
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm->mActor); // Could it be that we are shutting down.
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope)); if (swm->mActor) {
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope));
}
nsAutoCString scopeKey; nsAutoCString scopeKey;
nsresult rv = swm->PrincipalToScopeKey(mPrincipal, scopeKey); nsresult rv = swm->PrincipalToScopeKey(mPrincipal, scopeKey);
@ -2735,10 +2756,15 @@ ServiceWorkerManager::StoreRegistration(
nsIPrincipal* aPrincipal, nsIPrincipal* aPrincipal,
ServiceWorkerRegistrationInfo* aRegistration) ServiceWorkerRegistrationInfo* aRegistration)
{ {
MOZ_ASSERT(mActor);
MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aRegistration); MOZ_ASSERT(aRegistration);
if (mShuttingDown) {
return;
}
MOZ_ASSERT(mActor);
ServiceWorkerRegistrationData data; ServiceWorkerRegistrationData data;
nsresult rv = PopulateRegistrationData(aPrincipal, aRegistration, data); nsresult rv = PopulateRegistrationData(aPrincipal, aRegistration, data);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
@ -4064,6 +4090,10 @@ ServiceWorkerManager::RemoveRegistrationInternal(ServiceWorkerRegistrationInfo*
MOZ_ASSERT(aRegistration); MOZ_ASSERT(aRegistration);
MOZ_ASSERT(!aRegistration->IsControllingDocuments()); MOZ_ASSERT(!aRegistration->IsControllingDocuments());
if (mShuttingDown) {
return;
}
// All callers should be either from a job in which case the actor is // All callers should be either from a job in which case the actor is
// available, or from MaybeStopControlling(), in which case, this will only be // available, or from MaybeStopControlling(), in which case, this will only be
// called if a valid registration is found. If a valid registration exists, // called if a valid registration is found. If a valid registration exists,
@ -4497,21 +4527,22 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
const char* aTopic, const char* aTopic,
const char16_t* aData) const char16_t* aData)
{ {
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (strcmp(aTopic, PURGE_SESSION_HISTORY) == 0) { if (strcmp(aTopic, PURGE_SESSION_HISTORY) == 0) {
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
RemoveAll(); RemoveAll();
PropagateRemoveAll(); PropagateRemoveAll();
return NS_OK; return NS_OK;
} }
if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) { if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) {
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
nsAutoString domain(aData); nsAutoString domain(aData);
RemoveAndPropagate(NS_ConvertUTF16toUTF8(domain)); RemoveAndPropagate(NS_ConvertUTF16toUTF8(domain));
return NS_OK; return NS_OK;
} }
if (strcmp(aTopic, WEBAPPS_CLEAR_DATA) == 0) { if (strcmp(aTopic, WEBAPPS_CLEAR_DATA) == 0) {
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
nsCOMPtr<mozIApplicationClearPrivateDataParams> params = nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
do_QueryInterface(aSubject); do_QueryInterface(aSubject);
if (NS_WARN_IF(!params)) { if (NS_WARN_IF(!params)) {
@ -4541,18 +4572,35 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
} }
RemoveAllRegistrations(principal); RemoveAllRegistrations(principal);
} else if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { return NS_OK;
}
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
mShuttingDown = true;
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) { if (obs) {
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
obs->RemoveObserver(this, PURGE_SESSION_HISTORY);
obs->RemoveObserver(this, PURGE_DOMAIN_DATA); if (XRE_GetProcessType() == GeckoProcessType_Default) {
obs->RemoveObserver(this, WEBAPPS_CLEAR_DATA); obs->RemoveObserver(this, PURGE_SESSION_HISTORY);
obs->RemoveObserver(this, PURGE_DOMAIN_DATA);
obs->RemoveObserver(this, WEBAPPS_CLEAR_DATA);
}
} }
} else {
MOZ_CRASH("Received message we aren't supposed to be registered for!"); if (mActor) {
mActor->ManagerShuttingDown();
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
nsresult rv = NS_DispatchToMainThread(runnable);
unused << NS_WARN_IF(NS_FAILED(rv));
mActor = nullptr;
}
return NS_OK;
} }
MOZ_CRASH("Received message we aren't supposed to be registered for!");
return NS_OK; return NS_OK;
} }

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

@ -552,6 +552,8 @@ private:
struct PendingOperation; struct PendingOperation;
nsTArray<PendingOperation> mPendingOperations; nsTArray<PendingOperation> mPendingOperations;
bool mShuttingDown;
}; };
} // namespace workers } // namespace workers

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

@ -77,7 +77,7 @@ public:
} }
nsresult nsresult
Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL) Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, nsILoadGroup* aLoadGroup)
{ {
MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aPrincipal);
AssertIsOnMainThread(); AssertIsOnMainThread();
@ -91,7 +91,8 @@ public:
rv = NS_NewChannel(getter_AddRefs(mChannel), rv = NS_NewChannel(getter_AddRefs(mChannel),
uri, aPrincipal, uri, aPrincipal,
nsILoadInfo::SEC_NORMAL, nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_SCRIPT); // FIXME(nsm): TYPE_SERVICEWORKER nsIContentPolicy::TYPE_SCRIPT, // FIXME(nsm): TYPE_SERVICEWORKER
aLoadGroup);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
@ -280,7 +281,7 @@ public:
nsresult nsresult
Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL,
const nsAString& aCacheName) const nsAString& aCacheName, nsILoadGroup* aLoadGroup)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aPrincipal);
@ -297,7 +298,7 @@ public:
} }
mCN = new CompareNetwork(this); mCN = new CompareNetwork(this);
nsresult rv = mCN->Initialize(aPrincipal, aURL); nsresult rv = mCN->Initialize(aPrincipal, aURL, aLoadGroup);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
@ -936,7 +937,8 @@ GenerateCacheName(nsAString& aName)
nsresult nsresult
Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName, Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName,
const nsAString& aURL, CompareCallback* aCallback) const nsAString& aURL, CompareCallback* aCallback,
nsILoadGroup* aLoadGroup)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aPrincipal);
@ -945,7 +947,7 @@ Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName,
nsRefPtr<CompareManager> cm = new CompareManager(aCallback); nsRefPtr<CompareManager> cm = new CompareManager(aCallback);
nsresult rv = cm->Initialize(aPrincipal, aURL, aCacheName); nsresult rv = cm->Initialize(aPrincipal, aURL, aCacheName, aLoadGroup);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }

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

@ -44,7 +44,7 @@ public:
nsresult nsresult
Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName, Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName,
const nsAString& aURL, CompareCallback* aCallback); const nsAString& aURL, CompareCallback* aCallback, nsILoadGroup* aLoadGroup);
} // serviceWorkerScriptCache namespace } // serviceWorkerScriptCache namespace

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

@ -5962,11 +5962,13 @@ WorkerPrivate::AddFeature(JSContext* aCx, WorkerFeature* aFeature)
} }
MOZ_ASSERT(!mFeatures.Contains(aFeature), "Already know about this one!"); MOZ_ASSERT(!mFeatures.Contains(aFeature), "Already know about this one!");
mFeatures.AppendElement(aFeature);
return mFeatures.Length() == 1 ? if (mFeatures.IsEmpty() && !ModifyBusyCountFromWorker(aCx, true)) {
ModifyBusyCountFromWorker(aCx, true) : return false;
true; }
mFeatures.AppendElement(aFeature);
return true;
} }
void void

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

@ -70,4 +70,6 @@ LOCAL_INCLUDES += [
'/layout/xul', '/layout/xul',
] ]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul' FINAL_LIBRARY = 'xul'

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

@ -59,6 +59,8 @@
#include "nsIBidiKeyboard.h" // for nsIBidiKeyboard #include "nsIBidiKeyboard.h" // for nsIBidiKeyboard
#endif #endif
#include "mozilla/dom/TabParent.h"
class nsPresContext; class nsPresContext;
using namespace mozilla; using namespace mozilla;
@ -985,6 +987,14 @@ nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
return true; return true;
} }
// If the source node is a remote browser, treat this as coming from a
// different document and allow the drop.
nsCOMPtr<nsIContent> sourceContent = do_QueryInterface(sourceNode);
TabParent* tp = TabParent::GetFrom(sourceContent);
if (tp) {
return true;
}
nsRefPtr<Selection> selection = mEditor->GetSelection(); nsRefPtr<Selection> selection = mEditor->GetSelection();
if (!selection) { if (!selection) {
return false; return false;

Двоичные данные
embedding/tests/winEmbed/SMALL.ICO

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 318 B

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

@ -1,591 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: Mozilla-sample-code 1.0
*
* Copyright (c) 2002 Netscape Communications Corporation and
* other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this Mozilla sample software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
// Local includes
#include "resource.h"
#include "winEmbed.h"
#include "WebBrowserChrome.h"
// OS headers
#include <stdio.h>
// Frozen APIs
#include "nsStringAPI.h"
#include "nsIComponentManager.h"
#include "nsIDOMWindow.h"
#include "nsIInterfaceRequestor.h"
#include "nsIRequest.h"
#include "nsIURI.h"
#include "nsIWebProgress.h"
#include "nsCWebBrowser.h"
// Glue APIs (not frozen, but safe to use because they are statically linked)
#include "nsComponentManagerUtils.h"
// NON-FROZEN APIS!
#include "nsIWebNavigation.h"
WebBrowserChrome::WebBrowserChrome()
{
mNativeWindow = nullptr;
mSizeSet = false;
}
WebBrowserChrome::~WebBrowserChrome()
{
WebBrowserChromeUI::Destroyed(this);
}
nsresult WebBrowserChrome::CreateBrowser(int32_t aX, int32_t aY,
int32_t aCX, int32_t aCY,
nsIWebBrowser **aBrowser)
{
NS_ENSURE_ARG_POINTER(aBrowser);
*aBrowser = nullptr;
mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
if (!mWebBrowser)
return NS_ERROR_FAILURE;
(void)mWebBrowser->SetContainerWindow(static_cast<nsIWebBrowserChrome*>(this));
nsCOMPtr<nsIBaseWindow> browserBaseWindow = do_QueryInterface(mWebBrowser);
mNativeWindow = WebBrowserChromeUI::CreateNativeWindow(static_cast<nsIWebBrowserChrome*>(this));
if (!mNativeWindow)
return NS_ERROR_FAILURE;
browserBaseWindow->InitWindow( mNativeWindow,
nullptr,
aX, aY, aCX, aCY);
browserBaseWindow->Create();
nsCOMPtr<nsIWebProgressListener> listener(static_cast<nsIWebProgressListener*>(this));
nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener));
(void)mWebBrowser->AddWebBrowserListener(thisListener,
NS_GET_IID(nsIWebProgressListener));
// The window has been created. Now register for history notifications
mWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsISHistoryListener));
if (mWebBrowser)
{
*aBrowser = mWebBrowser;
NS_ADDREF(*aBrowser);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//*****************************************************************************
// WebBrowserChrome::nsISupports
//*****************************************************************************
NS_IMPL_ADDREF(WebBrowserChrome)
NS_IMPL_RELEASE(WebBrowserChrome)
NS_INTERFACE_MAP_BEGIN(WebBrowserChrome)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) // optional
NS_INTERFACE_MAP_ENTRY(nsISHistoryListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIContextMenuListener)
NS_INTERFACE_MAP_ENTRY(nsITooltipListener)
NS_INTERFACE_MAP_END
//*****************************************************************************
// WebBrowserChrome::nsIInterfaceRequestor
//*****************************************************************************
NS_IMETHODIMP WebBrowserChrome::GetInterface(const nsIID &aIID, void** aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
*aInstancePtr = 0;
if (aIID.Equals(NS_GET_IID(nsIDOMWindow)))
{
if (mWebBrowser)
{
return mWebBrowser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr);
}
return NS_ERROR_NOT_INITIALIZED;
}
return QueryInterface(aIID, aInstancePtr);
}
//*****************************************************************************
// WebBrowserChrome::nsIWebBrowserChrome
//*****************************************************************************
NS_IMETHODIMP WebBrowserChrome::SetStatus(uint32_t aType, const char16_t* aStatus)
{
WebBrowserChromeUI::UpdateStatusBarText(this, aStatus);
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::GetWebBrowser(nsIWebBrowser** aWebBrowser)
{
NS_ENSURE_ARG_POINTER(aWebBrowser);
*aWebBrowser = mWebBrowser;
NS_IF_ADDREF(*aWebBrowser);
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::SetWebBrowser(nsIWebBrowser* aWebBrowser)
{
mWebBrowser = aWebBrowser;
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::GetChromeFlags(uint32_t* aChromeMask)
{
*aChromeMask = mChromeFlags;
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::SetChromeFlags(uint32_t aChromeMask)
{
mChromeFlags = aChromeMask;
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::DestroyBrowserWindow(void)
{
WebBrowserChromeUI::Destroy(this);
return NS_OK;
}
// IN: The desired browser client area dimensions.
NS_IMETHODIMP WebBrowserChrome::SizeBrowserTo(int32_t aWidth, int32_t aHeight)
{
/* This isn't exactly correct: we're setting the whole window to
the size requested for the browser. At time of writing, though,
it's fine and useful for winEmbed's purposes. */
WebBrowserChromeUI::SizeTo(this, aWidth, aHeight);
mSizeSet = true;
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::ShowAsModal(void)
{
if (mDependentParent)
AppCallbacks::EnableChromeWindow(mDependentParent, false);
mContinueModalLoop = true;
AppCallbacks::RunEventLoop(mContinueModalLoop);
if (mDependentParent)
AppCallbacks::EnableChromeWindow(mDependentParent, true);
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::IsWindowModal(bool *_retval)
{
*_retval = false;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP WebBrowserChrome::ExitModalEventLoop(nsresult aStatus)
{
mContinueModalLoop = false;
return NS_OK;
}
//*****************************************************************************
// WebBrowserChrome::nsIWebBrowserChromeFocus
//*****************************************************************************
NS_IMETHODIMP WebBrowserChrome::FocusNextElement()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP WebBrowserChrome::FocusPrevElement()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//*****************************************************************************
// WebBrowserChrome::nsIWebProgressListener
//*****************************************************************************
NS_IMETHODIMP WebBrowserChrome::OnProgressChange(nsIWebProgress *progress, nsIRequest *request,
int32_t curSelfProgress, int32_t maxSelfProgress,
int32_t curTotalProgress, int32_t maxTotalProgress)
{
WebBrowserChromeUI::UpdateProgress(this, curTotalProgress, maxTotalProgress);
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::OnStateChange(nsIWebProgress *progress, nsIRequest *request,
uint32_t progressStateFlags, nsresult status)
{
if ((progressStateFlags & STATE_START) && (progressStateFlags & STATE_IS_DOCUMENT))
{
WebBrowserChromeUI::UpdateBusyState(this, true);
}
if ((progressStateFlags & STATE_STOP) && (progressStateFlags & STATE_IS_DOCUMENT))
{
WebBrowserChromeUI::UpdateBusyState(this, false);
WebBrowserChromeUI::UpdateProgress(this, 0, 100);
WebBrowserChromeUI::UpdateStatusBarText(this, nullptr);
ContentFinishedLoading();
}
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsIURI *location,
uint32_t aFlags)
{
bool isSubFrameLoad = false; // Is this a subframe load
if (aWebProgress) {
nsCOMPtr<nsIDOMWindow> domWindow;
nsCOMPtr<nsIDOMWindow> topDomWindow;
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
if (domWindow) { // Get root domWindow
domWindow->GetTop(getter_AddRefs(topDomWindow));
}
if (domWindow != topDomWindow)
isSubFrameLoad = true;
}
if (!isSubFrameLoad)
WebBrowserChromeUI::UpdateCurrentURI(this);
return NS_OK;
}
NS_IMETHODIMP
WebBrowserChrome::OnStatusChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsresult aStatus,
const char16_t* aMessage)
{
WebBrowserChromeUI::UpdateStatusBarText(this, aMessage);
return NS_OK;
}
NS_IMETHODIMP
WebBrowserChrome::OnSecurityChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
uint32_t state)
{
return NS_OK;
}
//*****************************************************************************
// WebBrowserChrome::nsISHistoryListener
//*****************************************************************************
NS_IMETHODIMP
WebBrowserChrome::OnHistoryNewEntry(nsIURI * aNewURI)
{
return SendHistoryStatusMessage(aNewURI, "add");
}
NS_IMETHODIMP
WebBrowserChrome::OnHistoryGoBack(nsIURI * aBackURI, bool * aContinue)
{
// For now, let the operation continue
*aContinue = true;
return SendHistoryStatusMessage(aBackURI, "back");
}
NS_IMETHODIMP
WebBrowserChrome::OnHistoryGoForward(nsIURI * aForwardURI, bool * aContinue)
{
// For now, let the operation continue
*aContinue = true;
return SendHistoryStatusMessage(aForwardURI, "forward");
}
NS_IMETHODIMP
WebBrowserChrome::OnHistoryGotoIndex(int32_t aIndex, nsIURI * aGotoURI, bool * aContinue)
{
// For now, let the operation continue
*aContinue = true;
return SendHistoryStatusMessage(aGotoURI, "goto", aIndex);
}
NS_IMETHODIMP
WebBrowserChrome::OnHistoryReload(nsIURI * aURI, uint32_t aReloadFlags, bool * aContinue)
{
// For now, let the operation continue
*aContinue = true;
return SendHistoryStatusMessage(aURI, "reload", 0 /* no info to pass here */, aReloadFlags);
}
NS_IMETHODIMP
WebBrowserChrome::OnHistoryPurge(int32_t aNumEntries, bool *aContinue)
{
// For now let the operation continue
*aContinue = false;
return SendHistoryStatusMessage(nullptr, "purge", aNumEntries);
}
NS_IMETHODIMP
WebBrowserChrome::OnHistoryReplaceEntry(int32_t aIndex)
{
return SendHistoryStatusMessage(nullptr, "replace", aIndex);
}
static void
AppendIntToCString(int32_t info1, nsCString& aResult)
{
char intstr[10];
_snprintf(intstr, sizeof(intstr) - 1, "%i", info1);
intstr[sizeof(intstr) - 1] = '\0';
aResult.Append(intstr);
}
nsresult
WebBrowserChrome::SendHistoryStatusMessage(nsIURI * aURI, char * operation, int32_t info1, uint32_t aReloadFlags)
{
nsCString uriSpec;
if (aURI)
{
aURI->GetSpec(uriSpec);
}
nsCString status;
if(!(strcmp(operation, "back")))
{
status.AssignLiteral("Going back to url: ");
status.Append(uriSpec);
}
else if (!(strcmp(operation, "forward")))
{
// Going forward. XXX Get string from a resource file
status.AssignLiteral("Going forward to url: ");
status.Append(uriSpec);
}
else if (!(strcmp(operation, "reload")))
{
// Reloading. XXX Get string from a resource file
if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY &&
aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE)
{
status.AssignLiteral("Reloading url, (bypassing proxy and cache): ");
}
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY)
{
status.AssignLiteral("Reloading url, (bypassing proxy): ");
}
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE)
{
status.AssignLiteral("Reloading url, (bypassing cache): ");
}
else
{
status.AssignLiteral("Reloading url, (normal): ");
}
status.Append(uriSpec);
}
else if (!(strcmp(operation, "add")))
{
status.Assign(uriSpec);
status.AppendLiteral(" added to session History");
}
else if (!(strcmp(operation, "goto")))
{
status.AssignLiteral("Going to HistoryIndex: ");
AppendIntToCString(info1, status);
status.AppendLiteral(" Url: ");
status.Append(uriSpec);
}
else if (!(strcmp(operation, "purge")))
{
AppendIntToCString(info1, status);
status.AppendLiteral(" purged from Session History");
}
else if (!(strcmp(operation, "replace")))
{
status.AssignLiteral("Replacing HistoryIndex: ");
AppendIntToCString(info1, status);
}
nsString wstatus;
NS_CStringToUTF16(status, NS_CSTRING_ENCODING_UTF8, wstatus);
WebBrowserChromeUI::UpdateStatusBarText(this, wstatus.get());
return NS_OK;
}
void WebBrowserChrome::ContentFinishedLoading()
{
// if it was a chrome window and no one has already specified a size,
// size to content
if (mWebBrowser && !mSizeSet &&
(mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
nsCOMPtr<nsIDOMWindow> contentWin;
mWebBrowser->GetContentDOMWindow(getter_AddRefs(contentWin));
if (contentWin)
contentWin->SizeToContent();
WebBrowserChromeUI::ShowWindow(this, true);
}
}
//*****************************************************************************
// WebBrowserChrome::nsIEmbeddingSiteWindow
//*****************************************************************************
NS_IMETHODIMP WebBrowserChrome::SetDimensions(uint32_t aFlags, int32_t x, int32_t y, int32_t cx, int32_t cy)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP WebBrowserChrome::GetDimensions(uint32_t aFlags, int32_t *x, int32_t *y, int32_t *cx, int32_t *cy)
{
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION)
{
*x = 0;
*y = 0;
}
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER ||
aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)
{
*cx = 0;
*cy = 0;
}
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void setFocus (); */
NS_IMETHODIMP WebBrowserChrome::SetFocus()
{
WebBrowserChromeUI::SetFocus(this);
return NS_OK;
}
/* void blur (); */
NS_IMETHODIMP WebBrowserChrome::Blur()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute wstring title; */
NS_IMETHODIMP WebBrowserChrome::GetTitle(char16_t * *aTitle)
{
NS_ENSURE_ARG_POINTER(aTitle);
*aTitle = nullptr;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP WebBrowserChrome::SetTitle(const char16_t * aTitle)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute boolean visibility; */
NS_IMETHODIMP WebBrowserChrome::GetVisibility(bool * aVisibility)
{
NS_ENSURE_ARG_POINTER(aVisibility);
*aVisibility = true;
return NS_OK;
}
NS_IMETHODIMP WebBrowserChrome::SetVisibility(bool aVisibility)
{
return NS_OK;
}
/* attribute nativeSiteWindow siteWindow */
NS_IMETHODIMP WebBrowserChrome::GetSiteWindow(void * *aSiteWindow)
{
NS_ENSURE_ARG_POINTER(aSiteWindow);
*aSiteWindow = mNativeWindow;
return NS_OK;
}
//*****************************************************************************
// WebBrowserChrome::nsIObserver
//*****************************************************************************
NS_IMETHODIMP WebBrowserChrome::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
{
nsresult rv = NS_OK;
if (strcmp(aTopic, "profile-change-teardown") == 0)
{
// A profile change means death for this window
WebBrowserChromeUI::Destroy(this);
}
return rv;
}
//*****************************************************************************
// WebBrowserChrome::nsIContextMenuListener
//*****************************************************************************
/* void OnShowContextMenu (in unsigned long aContextFlags, in nsIDOMEvent aEvent, in nsIDOMNode aNode); */
NS_IMETHODIMP WebBrowserChrome::OnShowContextMenu(uint32_t aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
{
WebBrowserChromeUI::ShowContextMenu(this, aContextFlags, aEvent, aNode);
return NS_OK;
}
//*****************************************************************************
// WebBrowserChrome::nsITooltipListener
//*****************************************************************************
/* void OnShowTooltip (in long aXCoords, in long aYCoords, in wstring aTipText); */
NS_IMETHODIMP WebBrowserChrome::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText)
{
WebBrowserChromeUI::ShowTooltip(this, aXCoords, aYCoords, aTipText);
return NS_OK;
}
/* void OnHideTooltip (); */
NS_IMETHODIMP WebBrowserChrome::OnHideTooltip()
{
WebBrowserChromeUI::HideTooltip(this);
return NS_OK;
}

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

@ -1,124 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: Mozilla-sample-code 1.0
*
* Copyright (c) 2002 Netscape Communications Corporation and
* other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this Mozilla sample software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#ifndef __WebBrowserChrome__
#define __WebBrowserChrome__
// OS headers
#include <windows.h>
// FROZEN APIs
#include "nsStringAPI.h"
#include "nsIWebBrowserChrome.h"
#include "nsIWebBrowserChromeFocus.h"
#include "nsIContextMenuListener.h"
#include "nsIEmbeddingSiteWindow.h"
#include "nsIInterfaceRequestor.h"
#include "nsIObserver.h"
#include "nsISHistoryListener.h"
#include "nsITooltipListener.h"
#include "nsIWebProgressListener.h"
#include "nsIWebBrowser.h"
// GLUE APIs (not frozen, but safe because we're statically linking them)
#include "nsCOMPtr.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsWeakReference.h"
class WebBrowserChromeUI
{
public:
static HWND CreateNativeWindow(nsIWebBrowserChrome* chrome);
static void Destroy(nsIWebBrowserChrome* chrome);
static void Destroyed(nsIWebBrowserChrome* chrome);
static void SetFocus(nsIWebBrowserChrome *chrome);
static void UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const char16_t* aStatusText);
static void UpdateCurrentURI(nsIWebBrowserChrome *aChrome);
static void UpdateBusyState(nsIWebBrowserChrome *aChrome, bool aBusy);
static void UpdateProgress(nsIWebBrowserChrome *aChrome, int32_t aCurrent, int32_t aMax);
static void GetResourceStringById(int32_t aID, char ** aReturn);
static void ShowContextMenu(nsIWebBrowserChrome *aChrome, uint32_t aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode);
static void ShowTooltip(nsIWebBrowserChrome *aChrome, int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText);
static void HideTooltip(nsIWebBrowserChrome *aChrome);
static void ShowWindow(nsIWebBrowserChrome *aChrome, bool aShow);
static void SizeTo(nsIWebBrowserChrome *aChrome, int32_t aWidth, int32_t aHeight);
};
class WebBrowserChrome : public nsIWebBrowserChrome,
public nsIWebBrowserChromeFocus,
public nsIWebProgressListener,
public nsIEmbeddingSiteWindow,
public nsIInterfaceRequestor,
public nsISHistoryListener,
public nsIObserver,
public nsIContextMenuListener,
public nsITooltipListener,
public nsSupportsWeakReference
{
public:
WebBrowserChrome();
virtual ~WebBrowserChrome();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBBROWSERCHROME
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIEMBEDDINGSITEWINDOW
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSISHISTORYLISTENER
NS_DECL_NSIOBSERVER
NS_DECL_NSICONTEXTMENULISTENER
NS_DECL_NSITOOLTIPLISTENER
nsresult CreateBrowser(int32_t aX, int32_t aY, int32_t aCX, int32_t aCY,
nsIWebBrowser **aBrowser);
void SetParent(nsIWebBrowserChrome *aParent)
{ mDependentParent = aParent; }
protected:
nsresult SendHistoryStatusMessage(nsIURI * aURI, char * operation, int32_t info1=0, uint32_t info2=0);
void ContentFinishedLoading();
HWND mNativeWindow;
uint32_t mChromeFlags;
bool mContinueModalLoop;
bool mSizeSet;
nsCOMPtr<nsIWebBrowser> mWebBrowser;
nsCOMPtr<nsIWebBrowserChrome> mDependentParent; // opener (for dependent windows only)
};
#endif /* __WebBrowserChrome__ */

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

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: Mozilla-sample-code 1.0
*
* Copyright (c) 2002 Netscape Communications Corporation and
* other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this Mozilla sample software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "nsIWebBrowserChrome.h"
#include "WindowCreator.h"
#include "winEmbed.h"
WindowCreator::WindowCreator()
{
}
WindowCreator::~WindowCreator()
{
}
NS_IMPL_ISUPPORTS(WindowCreator, nsIWindowCreator)
NS_IMETHODIMP
WindowCreator::CreateChromeWindow(nsIWebBrowserChrome *parent,
uint32_t chromeFlags,
nsIWebBrowserChrome **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
AppCallbacks::CreateBrowserWindow(int32_t(chromeFlags), parent, _retval);
return *_retval ? NS_OK : NS_ERROR_FAILURE;
}

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

@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: Mozilla-sample-code 1.0
*
* Copyright (c) 2002 Netscape Communications Corporation and
* other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this Mozilla sample software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#ifndef __WindowCreator_h_
#define __WindowCreator_h_
#include "nsIWindowCreator.h"
class WindowCreator :
public nsIWindowCreator
{
public:
WindowCreator();
virtual ~WindowCreator();
NS_DECL_ISUPPORTS
NS_DECL_NSIWINDOWCREATOR
};
#endif

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

@ -1,44 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
GeckoProgram('winEmbed')
SOURCES += [
'WebBrowserChrome.cpp',
'WindowCreator.cpp',
'winEmbed.cpp',
]
XPI_NAME = 'winembed'
RESFILE = 'winEmbed.res'
if CONFIG['GNU_CC']:
# Get rid of console window
LDFLAGS += ['-mwindows']
else:
# Control the default heap size.
# This is the heap returned by GetProcessHeap().
# As we use the CRT heap, the default size is too large and wastes VM.
#
# The default heap size is 1MB on Win32.
# The heap will grow if need be.
#
# Set it to 256k. See bug 127069.
LDFLAGS += ['/HEAP:0x40000']
DISABLE_STL_WRAPPING = True
USE_LIBS += [
'profdirserviceprovidersa_s',
]
OS_LIBS += [
'ole32',
'comdlg32',
'shell32',
'version',
]

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

@ -1,69 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by winEmbed.rc
//
#define IDC_MYICON 2
#define IDD_WINEMBED_DIALOG 102
#define IDD_ABOUTBOX 103
#define IDS_APP_TITLE 103
#define IDM_ABOUT 104
#define MOZ_OpenURI 104
#define MOZ_GetURI 104
#define IDM_EXIT 105
#define IDS_HELLO 106
#define IDI_WINEMBED 107
#define IDS_ABOUT 107
#define IDI_SMALL 108
#define IDS_ABOUT_TITLE 108
#define IDC_WINEMBED 109
#define IDS_HIST_BACK 109
#define IDS_HIST_FORWARD 110
#define IDS_HIST_RELOAD_NORMAL 111
#define IDS_HIST_RELOAD_BYPASSPROXY 112
#define IDS_HIST_RELOAD_BYPASSCACHE 113
#define IDS_HIST_ADDURL 114
#define IDS_HIST_RELOAD_BYPASSPROXYANDCACHE 115
#define IDS_HIST_PURGE 116
#define IDS_HIST_GOTO 117
#define IDS_HIST_URL 118
#define IDR_MAINFRAME 128
#define IDD_BROWSER 130
#define IDD_BROWSER_NC 131
#define IDD_CHOOSEPROFILE 132
#define MOZ_EDIT_URI 1001
#define IDC_GO 1003
#define IDC_BROWSER 1004
#define IDC_ADDRESS 1005
#define IDC_STOP 1006
#define IDC_STATUS 1007
#define IDC_BACK 1008
#define IDC_FORWARD 1009
#define IDC_PROGRESS 1010
#define IDC_RELOAD 1011
#define IDC_PROFILELIST 1011
#define MOZ_Open 32771
#define MOZ_NewBrowser 32773
#define MOZ_NewEditor 32774
#define MOZ_Cut 32776
#define MOZ_Copy 32777
#define MOZ_Paste 32778
#define MOZ_Delete 32779
#define MOZ_SelectAll 32780
#define MOZ_SelectNone 32781
#define MOZ_GoBack 32782
#define MOZ_GoForward 32783
#define MOZ_About 32784
#define ID_DEBUG_THISSPACEFORRENT 32786
#define MOZ_SwitchProfile 32787
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 32788
#define _APS_NEXT_CONTROL_VALUE 1012
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

Двоичные данные
embedding/tests/winEmbed/winEmbed.ICO

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: Mozilla-sample-code 1.0
*
* Copyright (c) 2002 Netscape Communications Corporation and
* other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this Mozilla sample software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
class nsIWebBrowserChrome;
namespace AppCallbacks {
nsresult CreateBrowserWindow(uint32_t aChromeFlags,
nsIWebBrowserChrome *aParent,
nsIWebBrowserChrome **aNewWindow);
void EnableChromeWindow(nsIWebBrowserChrome *aWindow, bool aEnabled);
uint32_t RunEventLoop(bool &aRunCondition);
}

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

@ -1,265 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_WINEMBED ICON "winEmbed.ICO"
IDI_SMALL ICON "SMALL.ICO"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_WINEMBED MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "New Browser...", MOZ_NewBrowser
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "Cu&t", MOZ_Cut
MENUITEM "&Copy", MOZ_Copy
MENUITEM "&Paste", MOZ_Paste
MENUITEM SEPARATOR
MENUITEM "Select All", MOZ_SelectAll
MENUITEM "Select None", MOZ_SelectNone
END
POPUP "&Go"
BEGIN
MENUITEM "&Back", MOZ_GoBack
MENUITEM "&Forward", MOZ_GoForward
END
POPUP "&Debug"
BEGIN
MENUITEM "&This space for rent", ID_DEBUG_THISSPACEFORRENT
, GRAYED
END
POPUP "&Help"
BEGIN
MENUITEM "&About winEmbed...", MOZ_About
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""resource.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_APP_TITLE "winEmbed"
IDS_HELLO "Embedding Mozilla is so much fun!!"
IDS_ABOUT "winEmbed - Gecko embedding sample"
IDS_ABOUT_TITLE "About winEmbed"
IDS_HIST_BACK "Going Back to: "
IDS_HIST_FORWARD "Going Forward to: "
IDS_HIST_RELOAD_NORMAL "Reloading url, (normal) :"
END
STRINGTABLE
BEGIN
IDS_HIST_RELOAD_BYPASSPROXY "Reloading url, (bypassing Proxy) :"
IDS_HIST_RELOAD_BYPASSCACHE "Reloading url, (bypassing cache) :"
IDS_HIST_ADDURL " added to Session History"
IDS_HIST_RELOAD_BYPASSPROXYANDCACHE
"Reloading url, (bypassing Proxy and cache) :"
IDS_HIST_PURGE "purged from session history"
IDS_HIST_GOTO "Going to history index : "
IDS_HIST_URL " URL : "
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_BROWSER DIALOG 0, 0, 400, 217
STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "winEmbed sample - UNSUPPORTED"
MENU IDC_WINEMBED
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Back",IDC_BACK,1,1,21,13
PUSHBUTTON "Forward",IDC_FORWARD,23,1,30,13
PUSHBUTTON "Reload",IDC_RELOAD,57,1,28,13
PUSHBUTTON "Stop",IDC_STOP,86,1,25,13
LTEXT "Address:",IDC_STATIC,115,3,28,8
COMBOBOX IDC_ADDRESS,145,1,193,52,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "Go",IDC_GO,340,1,25,13
CONTROL "Embedded Browser",IDC_BROWSER,"WINEMBED",WS_TABSTOP,0,
16,400,192
CONTROL "Status",IDC_STATUS,"Static",SS_LEFTNOWORDWRAP |
SS_SUNKEN | WS_GROUP,0,208,316,9
CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
316,208,84,9
END
IDD_BROWSER_NC DIALOG 0, 0, 400, 217
STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "winEmbed chromeless sample"
MENU IDC_WINEMBED
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Embedded Browser",IDC_BROWSER,"WINEMBED",WS_TABSTOP,0,0,
400,217
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_BROWSER, DIALOG
BEGIN
RIGHTMARGIN, 292
BOTTOMMARGIN, 216
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (Ireland) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENI)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_EIRE
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CHOOSEPROFILE DIALOG 0, 0, 186, 154
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Choose Profile"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Available Profiles:",IDC_STATIC,7,7,56,8
LISTBOX IDC_PROFILELIST,7,18,117,129,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "Select",IDOK,129,18,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,36,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_CHOOSEPROFILE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 147
END
END
#endif // APSTUDIO_INVOKED
#endif // English (Ireland) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

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

@ -1,141 +0,0 @@
# Microsoft Developer Studio Project File - Name="winembed" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) External Target" 0x0106
CFG=winembed - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "winembed.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "winembed.mak" CFG="winembed - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "winembed - Win32 Release" (based on "Win32 (x86) External Target")
!MESSAGE "winembed - Win32 Debug" (based on "Win32 (x86) External Target")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
!IF "$(CFG)" == "winembed - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Cmd_Line "NMAKE /f winembed.mak"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "winembed.exe"
# PROP BASE Bsc_Name "winembed.bsc"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Cmd_Line "nmake /f makefile.win"
# PROP Rebuild_Opt "/a"
# PROP Target_File "win32_o.obj\winembed.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ELSEIF "$(CFG)" == "winembed - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Cmd_Line "NMAKE /f winembed.mak"
# PROP BASE Rebuild_Opt "/a"
# PROP BASE Target_File "winembed.exe"
# PROP BASE Bsc_Name "winembed.bsc"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Cmd_Line "nmake /f makefile.win"
# PROP Rebuild_Opt "/a"
# PROP Target_File "win32_d.obj\winembed.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
!ENDIF
# Begin Target
# Name "winembed - Win32 Release"
# Name "winembed - Win32 Debug"
!IF "$(CFG)" == "winembed - Win32 Release"
!ELSEIF "$(CFG)" == "winembed - Win32 Debug"
!ENDIF
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\WebBrowserChrome.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowCreator.cpp
# End Source File
# Begin Source File
SOURCE=.\winEmbed.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\WebBrowserChrome.h
# End Source File
# Begin Source File
SOURCE=.\WindowCreator.h
# End Source File
# Begin Source File
SOURCE=.\winEmbed.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\SMALL.ICO
# End Source File
# Begin Source File
SOURCE=.\winEmbed.ICO
# End Source File
# Begin Source File
SOURCE=.\winEmbed.rc
# End Source File
# End Group
# End Target
# End Project

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

@ -1639,10 +1639,14 @@ nsEventStatus AsyncPanZoomController::OnPanBegin(const PanGestureInput& aEvent)
} }
float dx = aEvent.mPanDisplacement.x, dy = aEvent.mPanDisplacement.y; float dx = aEvent.mPanDisplacement.x, dy = aEvent.mPanDisplacement.y;
double angle = atan2(dy, dx); // range [-pi, pi]
angle = fabs(angle); // range [0, pi]
HandlePanning(angle); if (dx || dy) {
double angle = atan2(dy, dx); // range [-pi, pi]
angle = fabs(angle); // range [0, pi]
HandlePanning(angle);
} else {
SetState(PANNING);
}
return nsEventStatus_eConsumeNoDefault; return nsEventStatus_eConsumeNoDefault;
} }

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

@ -605,12 +605,14 @@ static struct lutmABType *read_tag_lutmABType(struct mem_source *src, struct tag
memset(lut, 0, sizeof(struct lutmABType)); memset(lut, 0, sizeof(struct lutmABType));
lut->clut_table = &lut->clut_table_data[0]; lut->clut_table = &lut->clut_table_data[0];
for (i = 0; i < num_in_channels; i++) { if (clut_offset) {
lut->num_grid_points[i] = read_u8(src, clut_offset + i); for (i = 0; i < num_in_channels; i++) {
if (lut->num_grid_points[i] == 0) { lut->num_grid_points[i] = read_u8(src, clut_offset + i);
invalid_source(src, "bad grid_points"); if (lut->num_grid_points[i] == 0) {
invalid_source(src, "bad grid_points");
}
} }
} }
// Reverse the processing of transformation elements for mBA type. // Reverse the processing of transformation elements for mBA type.
lut->reversed = (type == LUT_MBA_TYPE); lut->reversed = (type == LUT_MBA_TYPE);

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

@ -149,43 +149,6 @@ public:
int32_t* aDestLength); int32_t* aDestLength);
}; };
//----------------------------------------------------------------------
// Class nsTableDecoderSupport [declaration]
/**
* Support class for a single-table-driven Unicode decoder.
*
* @created 15/Mar/1999
* @author Catalin Rotaru [CATA]
*/
class nsTableDecoderSupport : public nsBufferDecoderSupport
{
public:
/**
* Class constructor.
*/
nsTableDecoderSupport(uScanClassID aScanClass, uShiftInTable * aShiftInTable,
uMappingTable * aMappingTable, uint32_t aMaxLengthFactor);
/**
* Class destructor.
*/
virtual ~nsTableDecoderSupport();
protected:
uScanClassID mScanClass;
uShiftInTable * mShiftInTable;
uMappingTable * mMappingTable;
//--------------------------------------------------------------------
// Subclassing of nsBufferDecoderSupport class [declaration]
NS_IMETHOD ConvertNoBuff(const char * aSrc, int32_t * aSrcLength,
char16_t * aDest, int32_t * aDestLength);
};
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Class nsMultiTableDecoderSupport [declaration] // Class nsMultiTableDecoderSupport [declaration]

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

@ -12,55 +12,21 @@
#include "nsGBKToUnicode.h" #include "nsGBKToUnicode.h"
#include "gbku.h" #include "gbku.h"
#include "nsUnicodeDecodeHelper.h"
//------------------------------------------------------------
// nsGB18030Unique2BytesToUnicode
//------------------------------------------------------------
class nsGB18030Unique2BytesToUnicode : public nsTableDecoderSupport
{
public:
nsGB18030Unique2BytesToUnicode();
virtual ~nsGB18030Unique2BytesToUnicode()
{ }
protected:
};
static const uint16_t g_utGB18030Unique2Bytes[] = { static const uint16_t g_utGB18030Unique2Bytes[] = {
#include "gb18030uniq2b.ut" #include "gb18030uniq2b.ut"
}; };
nsGB18030Unique2BytesToUnicode::nsGB18030Unique2BytesToUnicode()
: nsTableDecoderSupport(u2BytesCharset, nullptr,
(uMappingTable*) &g_utGB18030Unique2Bytes, 1)
{
}
//------------------------------------------------------------
// nsGB18030Unique4BytesToUnicode
//------------------------------------------------------------
class nsGB18030Unique4BytesToUnicode : public nsTableDecoderSupport
{
public:
nsGB18030Unique4BytesToUnicode();
virtual ~nsGB18030Unique4BytesToUnicode()
{ }
protected:
};
static const uint16_t g_utGB18030Unique4Bytes[] = { static const uint16_t g_utGB18030Unique4Bytes[] = {
#include "gb180304bytes.ut" #include "gb180304bytes.ut"
}; };
nsGB18030Unique4BytesToUnicode::nsGB18030Unique4BytesToUnicode()
: nsTableDecoderSupport(u4BytesGB18030Charset, nullptr,
(uMappingTable*) &g_utGB18030Unique4Bytes, 1)
{
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Class nsGBKToUnicode [implementation] // Class nsGB18030ToUnicode [implementation]
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Subclassing of nsTablesDecoderSupport class [implementation] // Subclassing of nsBufferDecoderSupport class [implementation]
#define LEGAL_GBK_MULTIBYTE_FIRST_BYTE(c) \ #define LEGAL_GBK_MULTIBYTE_FIRST_BYTE(c) \
(UINT8_IN_RANGE(0x81, (c), 0xFE)) (UINT8_IN_RANGE(0x81, (c), 0xFE))
@ -207,14 +173,6 @@ NS_IMETHODIMP nsGB18030ToUnicode::ConvertNoBuff(const char* aSrc,
return rv; return rv;
} }
void nsGB18030ToUnicode::CreateExtensionDecoder()
{
mExtensionDecoder = new nsGB18030Unique2BytesToUnicode();
}
void nsGB18030ToUnicode::Create4BytesDecoder()
{
m4BytesDecoder = new nsGB18030Unique4BytesToUnicode();
}
bool nsGB18030ToUnicode::DecodeToSurrogate(const char* aSrc, char16_t* aOut) bool nsGB18030ToUnicode::DecodeToSurrogate(const char* aSrc, char16_t* aOut)
{ {
NS_ASSERTION(FIRST_BYTE_IS_SURROGATE(aSrc[0]), "illegal first byte"); NS_ASSERTION(FIRST_BYTE_IS_SURROGATE(aSrc[0]), "illegal first byte");
@ -250,43 +208,32 @@ bool nsGB18030ToUnicode::DecodeToSurrogate(const char* aSrc, char16_t* aOut)
} }
bool nsGB18030ToUnicode::TryExtensionDecoder(const char* aSrc, char16_t* aOut) bool nsGB18030ToUnicode::TryExtensionDecoder(const char* aSrc, char16_t* aOut)
{ {
if(!mExtensionDecoder) int32_t len = 2;
CreateExtensionDecoder(); int32_t dstlen = 1;
NS_ASSERTION(mExtensionDecoder, "cannot creqte 2 bytes unique converter"); nsresult res =
if(mExtensionDecoder) nsUnicodeDecodeHelper::ConvertByTable(aSrc, &len, aOut, &dstlen,
{ u2BytesCharset, nullptr,
nsresult res = mExtensionDecoder->Reset(); (uMappingTable*) &g_utGB18030Unique2Bytes,
NS_ASSERTION(NS_SUCCEEDED(res), "2 bytes unique conversoin reset failed"); false);
int32_t len = 2; NS_ASSERTION(NS_FAILED(res) || ((len==2) && (dstlen == 1)),
int32_t dstlen = 1; "some strange conversion result");
res = mExtensionDecoder->Convert(aSrc,&len, aOut, &dstlen); // if we failed, we then just use the 0xfffd
NS_ASSERTION(NS_FAILED(res) || ((len==2) && (dstlen == 1)), // therefore, we ignore the res here.
"some strange conversion result"); return NS_SUCCEEDED(res);
// if we failed, we then just use the 0xfffd
// therefore, we ignore the res here.
if(NS_SUCCEEDED(res))
return true;
}
return false;
} }
bool nsGB18030ToUnicode::Try4BytesDecoder(const char* aSrc, char16_t* aOut) bool nsGB18030ToUnicode::Try4BytesDecoder(const char* aSrc, char16_t* aOut)
{ {
if(!m4BytesDecoder) int32_t len = 4;
Create4BytesDecoder(); int32_t dstlen = 1;
if(m4BytesDecoder) nsresult res =
{ nsUnicodeDecodeHelper::ConvertByTable(aSrc, &len, aOut, &dstlen,
nsresult res = m4BytesDecoder->Reset(); u4BytesGB18030Charset, nullptr,
NS_ASSERTION(NS_SUCCEEDED(res), "4 bytes unique conversoin reset failed"); (uMappingTable*) &g_utGB18030Unique4Bytes,
int32_t len = 4; false);
int32_t dstlen = 1; NS_ASSERTION(NS_FAILED(res) || ((len==4) && (dstlen == 1)),
res = m4BytesDecoder->Convert(aSrc,&len, aOut, &dstlen); "some strange conversion result");
NS_ASSERTION(NS_FAILED(res) || ((len==4) && (dstlen == 1)), // if we failed, we then just use the 0xfffd
"some strange conversion result"); // therefore, we ignore the res here.
// if we failed, we then just use the 0xfffd return NS_SUCCEEDED(res);
// therefore, we ignore the res here.
if(NS_SUCCEEDED(res))
return true;
}
return false;
} }

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

@ -29,23 +29,17 @@ public:
*/ */
nsGB18030ToUnicode() : nsBufferDecoderSupport(1) nsGB18030ToUnicode() : nsBufferDecoderSupport(1)
{ {
mExtensionDecoder = nullptr;
m4BytesDecoder = nullptr;
} }
protected: protected:
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Subclassing of nsDecoderSupport class [declaration] // Subclassing of nsBufferDecoderSupport class [declaration]
NS_IMETHOD ConvertNoBuff(const char* aSrc, int32_t * aSrcLength, char16_t *aDest, int32_t * aDestLength); NS_IMETHOD ConvertNoBuff(const char* aSrc, int32_t * aSrcLength, char16_t *aDest, int32_t * aDestLength);
protected: protected:
nsGBKConvUtil mUtil; nsGBKConvUtil mUtil;
nsCOMPtr<nsIUnicodeDecoder> mExtensionDecoder;
nsCOMPtr<nsIUnicodeDecoder> m4BytesDecoder;
void CreateExtensionDecoder();
void Create4BytesDecoder();
bool TryExtensionDecoder(const char* aSrc, char16_t* aDest); bool TryExtensionDecoder(const char* aSrc, char16_t* aDest);
bool Try4BytesDecoder(const char* aSrc, char16_t* aDest); bool Try4BytesDecoder(const char* aSrc, char16_t* aDest);
bool DecodeToSurrogate(const char* aSrc, char16_t* aDest); bool DecodeToSurrogate(const char* aSrc, char16_t* aDest);

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

@ -198,39 +198,6 @@ NS_IMETHODIMP nsBufferDecoderSupport::GetMaxLength(const char* aSrc,
return NS_OK; return NS_OK;
} }
//----------------------------------------------------------------------
// Class nsTableDecoderSupport [implementation]
nsTableDecoderSupport::nsTableDecoderSupport(uScanClassID aScanClass,
uShiftInTable* aShiftInTable,
uMappingTable* aMappingTable,
uint32_t aMaxLengthFactor)
: nsBufferDecoderSupport(aMaxLengthFactor)
{
mScanClass = aScanClass;
mShiftInTable = aShiftInTable;
mMappingTable = aMappingTable;
}
nsTableDecoderSupport::~nsTableDecoderSupport()
{
}
//----------------------------------------------------------------------
// Subclassing of nsBufferDecoderSupport class [implementation]
NS_IMETHODIMP nsTableDecoderSupport::ConvertNoBuff(const char* aSrc,
int32_t* aSrcLength,
char16_t* aDest,
int32_t* aDestLength)
{
return nsUnicodeDecodeHelper::ConvertByTable(aSrc, aSrcLength,
aDest, aDestLength,
mScanClass,
mShiftInTable, mMappingTable,
mErrBehavior == kOnError_Signal);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Class nsMultiTableDecoderSupport [implementation] // Class nsMultiTableDecoderSupport [implementation]

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

@ -0,0 +1,13 @@
// |jit-test| baseline-eager; error: TypeError
try {
__defineGetter__("x", Iterator)()
} catch (e) {}
f = function() {
return (function() {
this.x
})
}()
try {
f()
} catch (e) {}
f()

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

@ -7666,14 +7666,13 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
Label failure; Label failure;
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0)); AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
Register objReg = InvalidReg; Register objReg = InvalidReg;
MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_)); MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
if (inputDefinitelyObject_) { if (inputDefinitelyObject_) {
objReg = R0.scratchReg(); objReg = R0.scratchReg();
} else { } else {
regs.take(R0);
// Guard input is an object and unbox. // Guard input is an object and unbox.
masm.branchTestObject(Assembler::NotEqual, R0, &failure); masm.branchTestObject(Assembler::NotEqual, R0, &failure);
objReg = masm.extractObject(R0, ExtractTemp0); objReg = masm.extractObject(R0, ExtractTemp0);
@ -7683,12 +7682,11 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
masm.branchTestObjClass(Assembler::NotEqual, objReg, tmp, outerClass_, &failure); masm.branchTestObjClass(Assembler::NotEqual, objReg, tmp, outerClass_, &failure);
masm.loadPtr(Address(objReg, ProxyDataOffset + offsetof(ProxyDataLayout, values)), tmp); masm.loadPtr(Address(objReg, ProxyDataOffset + offsetof(ProxyDataLayout, values)), tmp);
masm.loadValue(Address(tmp, offsetof(ProxyValueArray, privateSlot)), val); masm.loadValue(Address(tmp, offsetof(ProxyValueArray, privateSlot)), val);
objReg = masm.extractObject(val, ExtractTemp0); masm.movePtr(masm.extractObject(val, ExtractTemp0), objReg);
regs.add(val); regs.add(val);
regs.add(tmp); regs.add(tmp);
} }
} }
regs.takeUnchecked(objReg);
Register scratch = regs.takeAnyExcluding(ICTailCallReg); Register scratch = regs.takeAnyExcluding(ICTailCallReg);
@ -7704,6 +7702,13 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
regs.add(holderReg); regs.add(holderReg);
} }
// Box and push obj onto baseline frame stack for decompiler
if (inputDefinitelyObject_)
masm.tagValue(JSVAL_TYPE_OBJECT, objReg, R0);
EmitStowICValues(masm, 1);
if (inputDefinitelyObject_)
objReg = masm.extractObject(R0, ExtractTemp0);
// Push a stub frame so that we can perform a non-tail call. // Push a stub frame so that we can perform a non-tail call.
enterStubFrame(masm, scratch); enterStubFrame(masm, scratch);
@ -7715,15 +7720,14 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
masm.push(objReg); masm.push(objReg);
masm.push(callee); masm.push(callee);
if (!inputDefinitelyObject_) regs.add(R0);
regs.add(R0);
else
regs.add(objReg);
if (!callVM(DoCallNativeGetterInfo, masm)) if (!callVM(DoCallNativeGetterInfo, masm))
return false; return false;
leaveStubFrame(masm); leaveStubFrame(masm);
EmitUnstowICValues(masm, 1, /* discard = */true);
// Enter type monitor IC to type-check result. // Enter type monitor IC to type-check result.
EmitEnterTypeMonitorIC(masm); EmitEnterTypeMonitorIC(masm);

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

@ -97,6 +97,7 @@ enum JitSpewChannel {
}; };
class MIRGenerator; class MIRGenerator;
class TempAllocator;
// The JitSpewer is only available on debug builds. // The JitSpewer is only available on debug builds.
// None of the global functions have effect on non-debug builds. // None of the global functions have effect on non-debug builds.

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

@ -46,6 +46,7 @@ class LTableSwitchV : public LInstruction
class LGuardShape : public LInstruction {}; class LGuardShape : public LInstruction {};
class LGuardObjectGroup : public LInstruction {}; class LGuardObjectGroup : public LInstruction {};
class LMulI : public LInstruction {}; class LMulI : public LInstruction {};
class LRandom : public LInstructionHelper<1, 0, 5> {};
} // namespace jit } // namespace jit
} // namespace js } // namespace js

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

@ -85,7 +85,7 @@ class LIRGeneratorNone : public LIRGeneratorShared
void visitSimdValueX4(MSimdValueX4* lir) { MOZ_CRASH(); } void visitSimdValueX4(MSimdValueX4* lir) { MOZ_CRASH(); }
void visitSubstr(MSubstr*) { MOZ_CRASH(); } void visitSubstr(MSubstr*) { MOZ_CRASH(); }
void visitSimdBinaryArith(js::jit::MSimdBinaryArith*) { MOZ_CRASH(); } void visitSimdBinaryArith(js::jit::MSimdBinaryArith*) { MOZ_CRASH(); }
void visitRandom(MRandom* ) { MOZ_CRASH(); }
}; };

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

@ -143,6 +143,11 @@ class Operand
{ {
public: public:
Operand (const Address&) { MOZ_CRASH();} Operand (const Address&) { MOZ_CRASH();}
Operand (const Register) { MOZ_CRASH();}
Operand (const FloatRegister) { MOZ_CRASH();}
Operand (Register, Imm32 ) { MOZ_CRASH(); }
Operand (Register, int32_t ) { MOZ_CRASH(); }
}; };

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

@ -215,6 +215,8 @@ class Test:
test.test_join.append([name[len('test-join='):]]) test.test_join.append([name[len('test-join='):]])
elif name == 'ion-eager': elif name == 'ion-eager':
test.jitflags.append('--ion-eager') test.jitflags.append('--ion-eager')
elif name == 'baseline-eager':
test.jitflags.append('--baseline-eager')
elif name == 'dump-bytecode': elif name == 'dump-bytecode':
test.jitflags.append('--dump-bytecode') test.jitflags.append('--dump-bytecode')
elif name.startswith('--'): elif name.startswith('--'):

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

@ -12,7 +12,7 @@
#include "nsIConsoleMessage.idl" #include "nsIConsoleMessage.idl"
%{C++ %{C++
#include "nsString.h" // for nsDependentCString #include "nsStringGlue.h" // for nsDependentCString
%} %}
[scriptable, uuid(248b2c94-2736-4d29-bfdf-bc64a2e60d35)] [scriptable, uuid(248b2c94-2736-4d29-bfdf-bc64a2e60d35)]

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

@ -77,7 +77,7 @@ EXPORTS += [
'nsIFrameTraversal.h', 'nsIFrameTraversal.h',
'nsILayoutDebugger.h', 'nsILayoutDebugger.h',
'nsILayoutHistoryState.h', 'nsILayoutHistoryState.h',
'nsIPercentHeightObserver.h', 'nsIPercentBSizeObserver.h',
'nsIPresShell.h', 'nsIPresShell.h',
'nsIReflowCallback.h', 'nsIReflowCallback.h',
'nsLayoutUtils.h', 'nsLayoutUtils.h',

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

@ -734,31 +734,44 @@ nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame,
#endif #endif
#endif #endif
if (runCount == 1 && frameCount == 1 && bool isNonBidi = false;
nsIFrame* frame0 = frameCount > 0 ? aBpd->FrameAt(0) : nullptr;
nsIFrame* frame1 = frameCount > 1 ? aBpd->FrameAt(1) : nullptr;
// Non-bidi frames
if (runCount == 1 && (frameCount == 1 || frameCount == 2) &&
aBpd->mParagraphDepth == 0 && aBpd->GetDirection() == NSBIDI_LTR && aBpd->mParagraphDepth == 0 && aBpd->GetDirection() == NSBIDI_LTR &&
aBpd->GetParaLevel() == 0) { aBpd->GetParaLevel() == 0 &&
// We have a single left-to-right frame in a left-to-right paragraph, frame0 != NS_BIDI_CONTROL_FRAME &&
!frame0->Properties().Get(nsIFrame::EmbeddingLevelProperty()) &&
!frame0->Properties().Get(nsIFrame::BaseLevelProperty())) {
// We have a left-to-right frame in a left-to-right paragraph,
// without bidi isolation from the surrounding text. // without bidi isolation from the surrounding text.
// Make sure that the embedding level and base level frame properties aren't // The embedding level and base level frame properties aren't
// set (because if they are this frame used to have some other direction, // set (because if they are this frame used to have some other direction,
// so we can't do this optimization), and we're done. // so we can't do this optimization)
nsIFrame* frame = aBpd->FrameAt(0); // As long as this is the only frame, or it's followed by a linebreak,
if (frame != NS_BIDI_CONTROL_FRAME && // this is a non-bidi paragraph.
!frame->Properties().Get(nsIFrame::EmbeddingLevelProperty()) && if (!frame1 || (frame1 != NS_BIDI_CONTROL_FRAME &&
!frame->Properties().Get(nsIFrame::BaseLevelProperty())) { frame1->GetType() == nsGkAtoms::brFrame)) {
isNonBidi = true;
}
}
if (isNonBidi) {
#ifdef DEBUG #ifdef DEBUG
#ifdef NOISY_BIDI #ifdef NOISY_BIDI
printf("early return for single direction frame %p\n", (void*)frame); printf("early return for single direction frame %p\n", (void*)frame);
#endif #endif
#endif #endif
frame->AddStateBits(NS_FRAME_IS_BIDI); return NS_OK;
return NS_OK;
}
} }
nsIFrame* firstFrame = nullptr; nsIFrame* firstFrame = nullptr;
nsIFrame* lastFrame = nullptr; nsIFrame* lastFrame = nullptr;
// Bidi frames
for (; ;) { for (; ;) {
if (fragmentLength <= 0) { if (fragmentLength <= 0) {
// Get the next frame from mLogicalFrames // Get the next frame from mLogicalFrames

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

@ -115,9 +115,14 @@ AdjustCaretFrameForLineEnd(nsIFrame** aFrame, int32_t* aOffset)
} }
static bool static bool
IsBidiUI() IsKeyboardRTL()
{ {
return Preferences::GetBool("bidi.browser.ui"); bool isKeyboardRTL = false;
nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard();
if (bidiKeyboard) {
bidiKeyboard->IsLangRTL(&isKeyboardRTL);
}
return isKeyboardRTL;
} }
nsCaret::nsCaret() nsCaret::nsCaret()
@ -478,6 +483,21 @@ nsCaret::SetCaretPosition(nsIDOMNode* aNode, int32_t aOffset)
SchedulePaint(); SchedulePaint();
} }
bool
nsCaret::IsBidiUI()
{
nsIFrame* frame = nullptr;
if(Selection* selection = GetSelectionInternal()) {
int32_t contentOffset;
frame = GetFrameAndOffset(selection, mOverrideContent, mOverrideOffset,
&contentOffset);
}
return (frame && frame->GetStateBits() & NS_FRAME_IS_BIDI) ||
Preferences::GetBool("bidi.browser.ui");
}
void void
nsCaret::CheckSelectionLanguageChange() nsCaret::CheckSelectionLanguageChange()
{ {
@ -485,11 +505,8 @@ nsCaret::CheckSelectionLanguageChange()
return; return;
} }
bool isKeyboardRTL = false; bool isKeyboardRTL = IsKeyboardRTL();
nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard();
if (bidiKeyboard) {
bidiKeyboard->IsLangRTL(&isKeyboardRTL);
}
// Call SelectionLanguageChange on every paint. Mostly it will be a noop // Call SelectionLanguageChange on every paint. Mostly it will be a noop
// but it should be fast anyway. This guarantees we never paint the caret // but it should be fast anyway. This guarantees we never paint the caret
// at the wrong place. // at the wrong place.
@ -678,8 +695,9 @@ nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection,
if (theFrame->PresContext()->BidiEnabled()) if (theFrame->PresContext()->BidiEnabled())
{ {
// If there has been a reflow, take the caret Bidi level to be the level of the current frame // If there has been a reflow, take the caret Bidi level to be the level of the current frame
if (aBidiLevel & BIDI_LEVEL_UNDEFINED) if (aBidiLevel & BIDI_LEVEL_UNDEFINED) {
aBidiLevel = NS_GET_EMBEDDING_LEVEL(theFrame); aBidiLevel = NS_GET_EMBEDDING_LEVEL(theFrame);
}
int32_t start; int32_t start;
int32_t end; int32_t end;
@ -902,21 +920,22 @@ nsCaret::ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset,
} }
} }
// Simon -- make a hook to draw to the left or right of the caret to show keyboard language direction
aHookRect->SetEmpty(); aHookRect->SetEmpty();
if (!IsBidiUI()) {
Selection* selection = GetSelectionInternal();
if (!selection || !selection->GetFrameSelection()) {
return; return;
} }
bool isCaretRTL; if (IsBidiUI() || IsKeyboardRTL()) {
nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard(); // If caret level is RTL, draw the hook on the left; if LTR, to the right
// if bidiKeyboard->IsLangRTL() fails, there is no way to tell the
// keyboard direction, or the user has no right-to-left keyboard
// installed, so we never draw the hook.
if (bidiKeyboard && NS_SUCCEEDED(bidiKeyboard->IsLangRTL(&isCaretRTL))) {
// If keyboard language is RTL, draw the hook on the left; if LTR, to the right
// The height of the hook rectangle is the same as the width of the caret // The height of the hook rectangle is the same as the width of the caret
// rectangle. // rectangle.
int caretBidiLevel = selection->GetFrameSelection()->GetCaretBidiLevel();
if (caretBidiLevel & BIDI_LEVEL_UNDEFINED) {
caretBidiLevel = NS_GET_EMBEDDING_LEVEL(aFrame);
}
bool isCaretRTL = caretBidiLevel % 2;
if (isVertical) { if (isVertical) {
aHookRect->SetRect(aCaretRect->XMost() - bidiIndicatorSize, aHookRect->SetRect(aCaretRect->XMost() - bidiIndicatorSize,
aCaretRect->y + (isCaretRTL ? bidiIndicatorSize * -1 : aCaretRect->y + (isCaretRTL ? bidiIndicatorSize * -1 :

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

@ -158,6 +158,7 @@ class nsCaret final : public nsISelectionListener
protected: protected:
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure); static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
bool IsBidiUI();
void CheckSelectionLanguageChange(); void CheckSelectionLanguageChange();
void ResetBlinking(); void ResetBlinking();

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

@ -70,6 +70,7 @@
#include "nsCaret.h" #include "nsCaret.h"
#include "nsISelection.h" #include "nsISelection.h"
#include "nsDOMTokenList.h" #include "nsDOMTokenList.h"
#include "mozilla/RuleNodeCacheConditions.h"
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount(). // GetTickCount().
@ -129,7 +130,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
NS_ASSERTION(currElem.GetUnit() == eCSSUnit_Function, NS_ASSERTION(currElem.GetUnit() == eCSSUnit_Function,
"Stream should consist solely of functions!"); "Stream should consist solely of functions!");
nsCSSValue::Array* array = currElem.GetArrayValue(); nsCSSValue::Array* array = currElem.GetArrayValue();
bool canStoreInRuleTree = true; RuleNodeCacheConditions conditions;
switch (nsStyleTransformMatrix::TransformFunctionOf(array)) { switch (nsStyleTransformMatrix::TransformFunctionOf(array)) {
case eCSSKeyword_rotatex: case eCSSKeyword_rotatex:
{ {
@ -201,7 +202,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
case eCSSKeyword_translatex: case eCSSKeyword_translatex:
{ {
double x = nsStyleTransformMatrix::ProcessTranslatePart( double x = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(1), aContext, aPresContext, canStoreInRuleTree, array->Item(1), aContext, aPresContext, conditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
aFunctions.AppendElement(Translation(x, 0, 0)); aFunctions.AppendElement(Translation(x, 0, 0));
break; break;
@ -209,7 +210,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
case eCSSKeyword_translatey: case eCSSKeyword_translatey:
{ {
double y = nsStyleTransformMatrix::ProcessTranslatePart( double y = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(1), aContext, aPresContext, canStoreInRuleTree, array->Item(1), aContext, aPresContext, conditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
aFunctions.AppendElement(Translation(0, y, 0)); aFunctions.AppendElement(Translation(0, y, 0));
break; break;
@ -217,7 +218,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
case eCSSKeyword_translatez: case eCSSKeyword_translatez:
{ {
double z = nsStyleTransformMatrix::ProcessTranslatePart( double z = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(1), aContext, aPresContext, canStoreInRuleTree, array->Item(1), aContext, aPresContext, conditions,
nullptr); nullptr);
aFunctions.AppendElement(Translation(0, 0, z)); aFunctions.AppendElement(Translation(0, 0, z));
break; break;
@ -225,13 +226,13 @@ static void AddTransformFunctions(nsCSSValueList* aList,
case eCSSKeyword_translate: case eCSSKeyword_translate:
{ {
double x = nsStyleTransformMatrix::ProcessTranslatePart( double x = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(1), aContext, aPresContext, canStoreInRuleTree, array->Item(1), aContext, aPresContext, conditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
// translate(x) is shorthand for translate(x, 0) // translate(x) is shorthand for translate(x, 0)
double y = 0; double y = 0;
if (array->Count() == 3) { if (array->Count() == 3) {
y = nsStyleTransformMatrix::ProcessTranslatePart( y = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(2), aContext, aPresContext, canStoreInRuleTree, array->Item(2), aContext, aPresContext, conditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
} }
aFunctions.AppendElement(Translation(x, y, 0)); aFunctions.AppendElement(Translation(x, y, 0));
@ -240,13 +241,13 @@ static void AddTransformFunctions(nsCSSValueList* aList,
case eCSSKeyword_translate3d: case eCSSKeyword_translate3d:
{ {
double x = nsStyleTransformMatrix::ProcessTranslatePart( double x = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(1), aContext, aPresContext, canStoreInRuleTree, array->Item(1), aContext, aPresContext, conditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
double y = nsStyleTransformMatrix::ProcessTranslatePart( double y = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(2), aContext, aPresContext, canStoreInRuleTree, array->Item(2), aContext, aPresContext, conditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
double z = nsStyleTransformMatrix::ProcessTranslatePart( double z = nsStyleTransformMatrix::ProcessTranslatePart(
array->Item(3), aContext, aPresContext, canStoreInRuleTree, array->Item(3), aContext, aPresContext, conditions,
nullptr); nullptr);
aFunctions.AppendElement(Translation(x, y, z)); aFunctions.AppendElement(Translation(x, y, z));
@ -325,7 +326,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
nsStyleTransformMatrix::ProcessInterpolateMatrix(matrix, array, nsStyleTransformMatrix::ProcessInterpolateMatrix(matrix, array,
aContext, aContext,
aPresContext, aPresContext,
canStoreInRuleTree, conditions,
aRefBox); aRefBox);
aFunctions.AppendElement(TransformMatrix(gfx::ToMatrix4x4(matrix))); aFunctions.AppendElement(TransformMatrix(gfx::ToMatrix4x4(matrix)));
break; break;
@ -4909,7 +4910,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
} }
/* Get the matrix, then change its basis to factor in the origin. */ /* Get the matrix, then change its basis to factor in the origin. */
bool dummy; RuleNodeCacheConditions dummy;
gfx3DMatrix result; gfx3DMatrix result;
// Call IsSVGTransformed() regardless of the value of // Call IsSVGTransformed() regardless of the value of
// disp->mSpecifiedTransform, since we still need any transformFromSVGParent. // disp->mSpecifiedTransform, since we still need any transformFromSVGParent.

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

@ -3,28 +3,29 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsIPercentHeightObserver_h___ #ifndef nsIPercentBSizeObserver_h___
#define nsIPercentHeightObserver_h___ #define nsIPercentBSizeObserver_h___
#include "nsQueryFrame.h" #include "nsQueryFrame.h"
struct nsHTMLReflowState; struct nsHTMLReflowState;
/** /**
* This interface is supported by frames that need to provide computed height * This interface is supported by frames that need to provide computed bsize
* values to children during reflow which would otherwise not happen. Currently only * values to children during reflow which would otherwise not happen. Currently
* table cells support this. * only table cells support this.
*/ */
class nsIPercentHeightObserver class nsIPercentBSizeObserver
{ {
public: public:
NS_DECL_QUERYFRAME_TARGET(nsIPercentHeightObserver) NS_DECL_QUERYFRAME_TARGET(nsIPercentBSizeObserver)
// Notify the observer that aReflowState has no computed height, but it has a percent height // Notify the observer that aReflowState has no computed bsize,
virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState) = 0; // but it has a percent bsize
virtual void NotifyPercentBSize(const nsHTMLReflowState& aReflowState) = 0;
// Ask the observer if it should observe aReflowState.frame // Ask the observer if it should observe aReflowState.frame
virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState) = 0; virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState) = 0;
}; };
#endif // nsIPercentHeightObserver_h___ #endif // nsIPercentBSizeObserver_h___

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

@ -99,6 +99,7 @@
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/EventDispatcher.h" #include "mozilla/EventDispatcher.h"
#include "mozilla/EventStateManager.h" #include "mozilla/EventStateManager.h"
#include "mozilla/RuleNodeCacheConditions.h"
#ifdef MOZ_XUL #ifdef MOZ_XUL
#include "nsXULPopupManager.h" #include "nsXULPopupManager.h"
@ -464,7 +465,7 @@ GetScaleForValue(const StyleAnimationValue& aValue, nsIFrame* aFrame)
return gfxSize(); return gfxSize();
} }
bool dontCare; RuleNodeCacheConditions dontCare;
TransformReferenceBox refBox(aFrame); TransformReferenceBox refBox(aFrame);
gfx3DMatrix transform = nsStyleTransformMatrix::ReadTransforms( gfx3DMatrix transform = nsStyleTransformMatrix::ReadTransforms(
list->mHead, list->mHead,

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

@ -32,6 +32,8 @@ public:
nsStyleContext_id, nsStyleContext_id,
nsInheritedStyleData_id, nsInheritedStyleData_id,
nsResetStyleData_id, nsResetStyleData_id,
nsConditionalResetStyleData_id,
nsConditionalResetStyleDataEntry_id,
nsFrameList_id, nsFrameList_id,
CustomCounterStyle_id, CustomCounterStyle_id,

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

@ -3,13 +3,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head> </head>
<body onload="start()"> <body onload="start()">
<textarea onfocus="done()" style="-moz-appearance: none">س</textarea> <textarea onfocus="done()" style="-moz-appearance: none">س&lrm;</textarea>
<script> <script>
var textarea = document.querySelector("textarea"); var textarea = document.querySelector("textarea");
function start() { function start() {
textarea.focus(); textarea.focus();
} }
function done() { function done() {
textarea.selectionStart = textarea.selectionEnd = 2;
document.documentElement.removeAttribute("class"); document.documentElement.removeAttribute("class");
} }
</script> </script>

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

@ -1,12 +1,13 @@
<html class="reftest-wait"> <html class="reftest-wait">
<body onload="start()"> <body onload="start()">
<textarea dir="rtl" onfocus="done()" style="-moz-appearance: none">s</textarea> <textarea dir="rtl" onfocus="done()" style="-moz-appearance: none">s&rlm;</textarea>
<script> <script>
var textarea = document.querySelector("textarea"); var textarea = document.querySelector("textarea");
function start() { function start() {
textarea.focus(); textarea.focus();
} }
function done() { function done() {
textarea.selectionStart = textarea.selectionEnd = 2;
document.documentElement.removeAttribute("class"); document.documentElement.removeAttribute("class");
} }
</script> </script>

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

@ -472,6 +472,8 @@ public:
return IsVertical() != aOther.IsVertical(); return IsVertical() != aOther.IsVertical();
} }
uint8_t GetBits() const { return mWritingMode; }
private: private:
friend class LogicalPoint; friend class LogicalPoint;
friend class LogicalSize; friend class LogicalSize;

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

@ -53,7 +53,7 @@
#include "nsRange.h" #include "nsRange.h"
#include "nsITextControlFrame.h" #include "nsITextControlFrame.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIPercentHeightObserver.h" #include "nsIPercentBSizeObserver.h"
#include "nsStyleStructInlines.h" #include "nsStyleStructInlines.h"
#include "FrameLayerBuilder.h" #include "FrameLayerBuilder.h"
@ -4449,15 +4449,16 @@ nsFrame::DidReflow(nsPresContext* aPresContext,
NS_FRAME_HAS_DIRTY_CHILDREN); NS_FRAME_HAS_DIRTY_CHILDREN);
} }
// Notify the percent height observer if there is a percent height. // Notify the percent bsize observer if there is a percent bsize.
// The observer may be able to initiate another reflow with a computed // The observer may be able to initiate another reflow with a computed
// height. This happens in the case where a table cell has no computed // bsize. This happens in the case where a table cell has no computed
// height but can fabricate one when the cell height is known. // bsize but can fabricate one when the cell bsize is known.
if (aReflowState && aReflowState->mPercentHeightObserver && if (aReflowState && aReflowState->mPercentBSizeObserver &&
!GetPrevInFlow()) { !GetPrevInFlow()) {
const nsStyleCoord &height = aReflowState->mStylePosition->mHeight; const nsStyleCoord &bsize =
if (height.HasPercent()) { aReflowState->mStylePosition->BSize(aReflowState->GetWritingMode());
aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState); if (bsize.HasPercent()) {
aReflowState->mPercentBSizeObserver->NotifyPercentBSize(*aReflowState);
} }
} }
@ -9742,8 +9743,8 @@ static void DisplayReflowEnterPrint(nsPresContext* aPresContext,
if (aFrame->GetStateBits() & NS_FRAME_HAS_DIRTY_CHILDREN) if (aFrame->GetStateBits() & NS_FRAME_HAS_DIRTY_CHILDREN)
printf("dirty-children "); printf("dirty-children ");
if (aReflowState.mFlags.mSpecialHeightReflow) if (aReflowState.mFlags.mSpecialBSizeReflow)
printf("special-height "); printf("special-bsize ");
if (aReflowState.IsHResize()) if (aReflowState.IsHResize())
printf("h-resize "); printf("h-resize ");

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

@ -49,7 +49,7 @@ FRAME_ID(nsIMathMLFrame)
FRAME_ID(nsIMenuFrame) FRAME_ID(nsIMenuFrame)
FRAME_ID(nsIObjectFrame) FRAME_ID(nsIObjectFrame)
FRAME_ID(nsIPageSequenceFrame) FRAME_ID(nsIPageSequenceFrame)
FRAME_ID(nsIPercentHeightObserver) FRAME_ID(nsIPercentBSizeObserver)
FRAME_ID(nsIRootBox) FRAME_ID(nsIRootBox)
FRAME_ID(nsISVGChildFrame) FRAME_ID(nsISVGChildFrame)
FRAME_ID(nsISVGSVGFrame) FRAME_ID(nsISVGSVGFrame)

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

@ -621,7 +621,9 @@ private:
uint32_t aContentOffset, uint32_t aContentOffset,
nsSelectionAmount aAmount, nsSelectionAmount aAmount,
CaretAssociateHint aHint); CaretAssociateHint aHint);
void BidiLevelFromClick(nsIContent *aNewFocus, uint32_t aContentOffset); void BidiLevelFromClick(nsIContent *aNewFocus,
uint32_t aContentOffset,
CaretAssociateHint aHint);
nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode, nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode,
uint32_t aContentOffset, uint32_t aContentOffset,
CaretAssociateHint aHint, CaretAssociateHint aHint,

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

@ -550,7 +550,7 @@ FRAME_STATE_BIT(Placeholder, 23, PLACEHOLDER_FOR_POPUP)
FRAME_STATE_GROUP(TableCell, nsTableCellFrame) FRAME_STATE_GROUP(TableCell, nsTableCellFrame)
FRAME_STATE_BIT(TableCell, 28, NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) FRAME_STATE_BIT(TableCell, 28, NS_TABLE_CELL_HAS_PCT_OVER_BSIZE)
FRAME_STATE_BIT(TableCell, 29, NS_TABLE_CELL_HAD_SPECIAL_REFLOW) FRAME_STATE_BIT(TableCell, 29, NS_TABLE_CELL_HAD_SPECIAL_REFLOW)
FRAME_STATE_BIT(TableCell, 31, NS_TABLE_CELL_CONTENT_EMPTY) FRAME_STATE_BIT(TableCell, 31, NS_TABLE_CELL_CONTENT_EMPTY)
@ -579,10 +579,10 @@ FRAME_STATE_BIT(TableRowAndRowGroup, 28, NS_REPEATED_ROW_OR_ROWGROUP)
FRAME_STATE_GROUP(TableRow, nsTableRowFrame) FRAME_STATE_GROUP(TableRow, nsTableRowFrame)
// Indicates whether this row has any cells that have // Indicates whether this row has any cells that have
// non-auto-height and rowspan=1 // non-auto-bsize and rowspan=1
FRAME_STATE_BIT(TableRow, 29, NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT) FRAME_STATE_BIT(TableRow, 29, NS_ROW_HAS_CELL_WITH_STYLE_BSIZE)
FRAME_STATE_BIT(TableRow, 30, NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT) FRAME_STATE_BIT(TableRow, 30, NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE)
// == Frame state bits that apply to table row group frames =================== // == Frame state bits that apply to table row group frames ===================
@ -590,7 +590,7 @@ FRAME_STATE_BIT(TableRow, 30, NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT)
FRAME_STATE_GROUP(TableRowGroup, nsTableRowGroupFrame) FRAME_STATE_GROUP(TableRowGroup, nsTableRowGroupFrame)
FRAME_STATE_BIT(TableRowGroup, 27, NS_ROWGROUP_HAS_ROW_CURSOR) FRAME_STATE_BIT(TableRowGroup, 27, NS_ROWGROUP_HAS_ROW_CURSOR)
FRAME_STATE_BIT(TableRowGroup, 30, NS_ROWGROUP_HAS_STYLE_HEIGHT) FRAME_STATE_BIT(TableRowGroup, 30, NS_ROWGROUP_HAS_STYLE_BSIZE)
// thead or tfoot should be repeated on every printed page // thead or tfoot should be repeated on every printed page
FRAME_STATE_BIT(TableRowGroup, 31, NS_ROWGROUP_REPEATABLE) FRAME_STATE_BIT(TableRowGroup, 31, NS_ROWGROUP_REPEATABLE)

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

@ -22,7 +22,7 @@
#include "nsImageFrame.h" #include "nsImageFrame.h"
#include "nsTableFrame.h" #include "nsTableFrame.h"
#include "nsTableCellFrame.h" #include "nsTableCellFrame.h"
#include "nsIPercentHeightObserver.h" #include "nsIPercentBSizeObserver.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "nsFontInflationData.h" #include "nsFontInflationData.h"
@ -75,7 +75,7 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext,
mLineLayout = nullptr; mLineLayout = nullptr;
memset(&mFlags, 0, sizeof(mFlags)); memset(&mFlags, 0, sizeof(mFlags));
mDiscoveredClearance = nullptr; mDiscoveredClearance = nullptr;
mPercentHeightObserver = nullptr; mPercentBSizeObserver = nullptr;
if (aFlags & DUMMY_PARENT_REFLOW_STATE) { if (aFlags & DUMMY_PARENT_REFLOW_STATE) {
mFlags.mDummyParentReflowState = true; mFlags.mDummyParentReflowState = true;
@ -179,16 +179,16 @@ nsHTMLReflowState::nsHTMLReflowState(
MOZ_ASSERT(aPresContext, "no pres context"); MOZ_ASSERT(aPresContext, "no pres context");
MOZ_ASSERT(aFrame, "no frame"); MOZ_ASSERT(aFrame, "no frame");
MOZ_ASSERT(aPresContext == aFrame->PresContext(), "wrong pres context"); MOZ_ASSERT(aPresContext == aFrame->PresContext(), "wrong pres context");
NS_PRECONDITION(!mFlags.mSpecialHeightReflow || NS_PRECONDITION(!mFlags.mSpecialBSizeReflow ||
!NS_SUBTREE_DIRTY(aFrame), !NS_SUBTREE_DIRTY(aFrame),
"frame should be clean when getting special height reflow"); "frame should be clean when getting special bsize reflow");
parentReflowState = &aParentReflowState; parentReflowState = &aParentReflowState;
// If the parent is dirty, then the child is as well. // If the parent is dirty, then the child is as well.
// XXX Are the other cases where the parent reflows a child a second // XXX Are the other cases where the parent reflows a child a second
// time, as a resize? // time, as a resize?
if (!mFlags.mSpecialHeightReflow) if (!mFlags.mSpecialBSizeReflow)
frame->AddStateBits(parentReflowState->frame->GetStateBits() & frame->AddStateBits(parentReflowState->frame->GetStateBits() &
NS_FRAME_IS_DIRTY); NS_FRAME_IS_DIRTY);
@ -223,9 +223,9 @@ nsHTMLReflowState::nsHTMLReflowState(
mFlags.mDummyParentReflowState = false; mFlags.mDummyParentReflowState = false;
mDiscoveredClearance = nullptr; mDiscoveredClearance = nullptr;
mPercentHeightObserver = (aParentReflowState.mPercentHeightObserver && mPercentBSizeObserver = (aParentReflowState.mPercentBSizeObserver &&
aParentReflowState.mPercentHeightObserver->NeedsToObserve(*this)) aParentReflowState.mPercentBSizeObserver->NeedsToObserve(*this))
? aParentReflowState.mPercentHeightObserver : nullptr; ? aParentReflowState.mPercentBSizeObserver : nullptr;
if ((aFlags & DUMMY_PARENT_REFLOW_STATE) || if ((aFlags & DUMMY_PARENT_REFLOW_STATE) ||
(parentReflowState->mFlags.mDummyParentReflowState && (parentReflowState->mFlags.mDummyParentReflowState &&
@ -613,7 +613,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
// XXX Should we really need to null check mCBReflowState? (We do for // XXX Should we really need to null check mCBReflowState? (We do for
// at least nsBoxFrame). // at least nsBoxFrame).
if (IS_TABLE_CELL(aFrameType) && if (IS_TABLE_CELL(aFrameType) &&
(mFlags.mSpecialHeightReflow || (mFlags.mSpecialBSizeReflow ||
(frame->FirstInFlow()->GetStateBits() & (frame->FirstInFlow()->GetStateBits() &
NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) && NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) &&
(frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE)) { (frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE)) {
@ -662,16 +662,16 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
dependsOnCBBSize |= !nsLayoutUtils::IsNonWrapperBlock(frame); dependsOnCBBSize |= !nsLayoutUtils::IsNonWrapperBlock(frame);
} }
// If we're the descendant of a table cell that performs special height // If we're the descendant of a table cell that performs special bsize
// reflows and we could be the child that requires them, always set // reflows and we could be the child that requires them, always set
// the block-axis resize in case this is the first pass before the // the block-axis resize in case this is the first pass before the
// special height reflow. However, don't do this if it actually is // special bsize reflow. However, don't do this if it actually is
// the special height reflow, since in that case it will already be // the special bsize reflow, since in that case it will already be
// set correctly above if we need it set. // set correctly above if we need it set.
if (!IsBResize() && mCBReflowState && if (!IsBResize() && mCBReflowState &&
(IS_TABLE_CELL(mCBReflowState->frame->GetType()) || (IS_TABLE_CELL(mCBReflowState->frame->GetType()) ||
mCBReflowState->mFlags.mHeightDependsOnAncestorCell) && mCBReflowState->mFlags.mHeightDependsOnAncestorCell) &&
!mCBReflowState->mFlags.mSpecialHeightReflow && !mCBReflowState->mFlags.mSpecialBSizeReflow &&
dependsOnCBBSize) { dependsOnCBBSize) {
SetBResize(true); SetBResize(true);
mFlags.mHeightDependsOnAncestorCell = true; mFlags.mHeightDependsOnAncestorCell = true;
@ -681,7 +681,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
// It would be nice to check that |ComputedBSize != NS_AUTOHEIGHT| // It would be nice to check that |ComputedBSize != NS_AUTOHEIGHT|
// &&ed with the percentage bsize check. However, this doesn't get // &&ed with the percentage bsize check. However, this doesn't get
// along with table special height reflows, since a special height // along with table special bsize reflows, since a special bsize
// reflow (a quirk that makes such percentage height work on children // reflow (a quirk that makes such percentage height work on children
// of table cells) can cause not just a single percentage height to // of table cells) can cause not just a single percentage height to
// become fixed, but an entire descendant chain of percentage height // become fixed, but an entire descendant chain of percentage height

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

@ -18,7 +18,7 @@ class nsPresContext;
class nsRenderingContext; class nsRenderingContext;
class nsFloatManager; class nsFloatManager;
class nsLineLayout; class nsLineLayout;
class nsIPercentHeightObserver; class nsIPercentBSizeObserver;
struct nsHypotheticalBox; struct nsHypotheticalBox;
/** /**
@ -514,8 +514,8 @@ public:
uint8_t GetDisplay() const; uint8_t GetDisplay() const;
// a frame (e.g. nsTableCellFrame) which may need to generate a special // a frame (e.g. nsTableCellFrame) which may need to generate a special
// reflow for percent height calculations // reflow for percent bsize calculations
nsIPercentHeightObserver* mPercentHeightObserver; nsIPercentBSizeObserver* mPercentBSizeObserver;
// CSS margin collapsing sometimes requires us to reflow // CSS margin collapsing sometimes requires us to reflow
// optimistically assuming that margins collapse to see if clearance // optimistically assuming that margins collapse to see if clearance
@ -529,8 +529,8 @@ public:
int16_t mReflowDepth; int16_t mReflowDepth;
struct ReflowStateFlags { struct ReflowStateFlags {
uint16_t mSpecialHeightReflow:1; // used by tables to communicate special reflow (in process) to handle uint16_t mSpecialBSizeReflow:1; // used by tables to communicate special reflow (in process) to handle
// percent height frames inside cells which may not have computed heights // percent bsize frames inside cells which may not have computed bsizes
uint16_t mNextInFlowUntouched:1; // nothing in the frame's next-in-flow (or its descendants) uint16_t mNextInFlowUntouched:1; // nothing in the frame's next-in-flow (or its descendants)
// is changing // is changing
uint16_t mIsTopOfPage:1; // Is the current context at the top of a uint16_t mIsTopOfPage:1; // Is the current context at the top of a

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

@ -734,21 +734,39 @@ public:
} }
/** /**
* Set this frame's size from a logical size in its own writing direction * Set this frame's size from a logical size in its own writing direction.
* This leaves the frame's logical position unchanged, which means its
* physical position may change (for right-to-left modes).
*/ */
void SetSize(const mozilla::LogicalSize& aSize) { void SetSize(const mozilla::LogicalSize& aSize) {
SetSize(GetWritingMode(), aSize); SetSize(GetWritingMode(), aSize);
} }
/* /*
* Set this frame's size from a logical size in a different writing direction * Set this frame's size from a logical size in a different writing direction.
* This leaves the frame's logical position in the given mode unchanged,
* which means its physical position may change (for right-to-left modes).
*/ */
void SetSize(mozilla::WritingMode aWritingMode, void SetSize(mozilla::WritingMode aWritingMode,
const mozilla::LogicalSize& aSize) { const mozilla::LogicalSize& aSize)
SetSize(aSize.GetPhysicalSize(aWritingMode)); {
if ((!aWritingMode.IsVertical() && !aWritingMode.IsBidiLTR()) ||
aWritingMode.IsVerticalRL()) {
nscoord oldWidth = mRect.width;
SetSize(aSize.GetPhysicalSize(aWritingMode));
mRect.x -= mRect.width - oldWidth;
} else {
SetSize(aSize.GetPhysicalSize(aWritingMode));
}
} }
/**
* Set this frame's physical size. This leaves the frame's physical position
* (topLeft) unchanged.
*/
void SetSize(const nsSize& aSize) { void SetSize(const nsSize& aSize) {
SetRect(nsRect(mRect.TopLeft(), aSize)); SetRect(nsRect(mRect.TopLeft(), aSize));
} }
void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); } void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); }
void SetPosition(mozilla::WritingMode aWritingMode, void SetPosition(mozilla::WritingMode aWritingMode,
const mozilla::LogicalPoint& aPt, const mozilla::LogicalPoint& aPt,

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

@ -1431,12 +1431,13 @@ void nsFrameSelection::BidiLevelFromMove(nsIPresShell* aPresShell,
* @param aContentOffset is the new caret position, as an offset into aNode * @param aContentOffset is the new caret position, as an offset into aNode
*/ */
void nsFrameSelection::BidiLevelFromClick(nsIContent *aNode, void nsFrameSelection::BidiLevelFromClick(nsIContent *aNode,
uint32_t aContentOffset) uint32_t aContentOffset,
CaretAssociateHint aHint)
{ {
nsIFrame* clickInFrame=nullptr; nsIFrame* clickInFrame=nullptr;
int32_t OffsetNotUsed; int32_t OffsetNotUsed;
clickInFrame = GetFrameForNodeOffset(aNode, aContentOffset, mHint, &OffsetNotUsed); clickInFrame = GetFrameForNodeOffset(aNode, aContentOffset, aHint, &OffsetNotUsed);
if (!clickInFrame) if (!clickInFrame)
return; return;
@ -1515,7 +1516,7 @@ nsFrameSelection::HandleClick(nsIContent* aNewFocus,
// Don't take focus when dragging off of a table // Don't take focus when dragging off of a table
if (!mDragSelectingCells) if (!mDragSelectingCells)
{ {
BidiLevelFromClick(aNewFocus, aContentOffset); BidiLevelFromClick(aNewFocus, aContentOffset, aHint);
PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON); PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON);
if (aContinueSelection && if (aContinueSelection &&
AdjustForMaintainedSelection(aNewFocus, aContentOffset)) AdjustForMaintainedSelection(aNewFocus, aContentOffset))

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

@ -619,7 +619,8 @@ struct FlowLengthProperty {
}; };
int32_t nsTextFrame::GetInFlowContentLength() { int32_t nsTextFrame::GetInFlowContentLength() {
if (!(mState & NS_FRAME_IS_BIDI)) { if (!(mState & NS_FRAME_IS_BIDI) &&
!StyleText()->NewlineIsSignificant(this)) {
return mContent->TextLength() - mContentOffset; return mContent->TextLength() - mContentOffset;
} }
@ -631,7 +632,7 @@ int32_t nsTextFrame::GetInFlowContentLength() {
* mContentOffset but this frame is empty, logically it might be before the * mContentOffset but this frame is empty, logically it might be before the
* start of the cached flow. * start of the cached flow.
*/ */
if (flowLength && if (flowLength && !StyleText()->NewlineIsSignificant(this) &&
(flowLength->mStartOffset < mContentOffset || (flowLength->mStartOffset < mContentOffset ||
(flowLength->mStartOffset == mContentOffset && GetContentEnd() > mContentOffset)) && (flowLength->mStartOffset == mContentOffset && GetContentEnd() > mContentOffset)) &&
flowLength->mEndFlowOffset > mContentOffset) { flowLength->mEndFlowOffset > mContentOffset) {
@ -4804,6 +4805,18 @@ LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame)
} }
} }
static bool IsUnderlineRight(nsIFrame* aFrame)
{
nsIAtom* langAtom = aFrame->StyleFont()->mLanguage;
if (!langAtom) {
return false;
}
nsAtomString langStr(langAtom);
return (StringBeginsWith(langStr, NS_LITERAL_STRING("ja")) ||
StringBeginsWith(langStr, NS_LITERAL_STRING("ko"))) &&
(langStr.Length() == 2 || langStr[2] == '-');
}
void void
nsTextFrame::GetTextDecorations( nsTextFrame::GetTextDecorations(
nsPresContext* aPresContext, nsPresContext* aPresContext,
@ -4902,11 +4915,19 @@ nsTextFrame::GetTextDecorations(
color = nsLayoutUtils::GetColor(f, eCSSProperty_text_decoration_color); color = nsLayoutUtils::GetColor(f, eCSSProperty_text_decoration_color);
} }
if (textDecorations & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) { bool swapUnderlineAndOverline = vertical && IsUnderlineRight(f);
const uint8_t kUnderline =
swapUnderlineAndOverline ? NS_STYLE_TEXT_DECORATION_LINE_OVERLINE :
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
const uint8_t kOverline =
swapUnderlineAndOverline ? NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE :
NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
if (textDecorations & kUnderline) {
aDecorations.mUnderlines.AppendElement( aDecorations.mUnderlines.AppendElement(
nsTextFrame::LineDecoration(f, baselineOffset, color, style)); nsTextFrame::LineDecoration(f, baselineOffset, color, style));
} }
if (textDecorations & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) { if (textDecorations & kOverline) {
aDecorations.mOverlines.AppendElement( aDecorations.mOverlines.AppendElement(
nsTextFrame::LineDecoration(f, baselineOffset, color, style)); nsTextFrame::LineDecoration(f, baselineOffset, color, style));
} }
@ -5260,7 +5281,7 @@ static void DrawSelectionDecorations(gfxContext* aContext,
const gfxPoint& aPt, gfxFloat aICoordInFrame, gfxFloat aWidth, const gfxPoint& aPt, gfxFloat aICoordInFrame, gfxFloat aWidth,
gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics, gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics,
nsTextFrame::DrawPathCallbacks* aCallbacks, nsTextFrame::DrawPathCallbacks* aCallbacks,
bool aVertical) bool aVertical, uint8_t aDecoration)
{ {
gfxPoint pt(aPt); gfxPoint pt(aPt);
gfxSize size(aWidth, gfxSize size(aWidth,
@ -5338,8 +5359,10 @@ static void DrawSelectionDecorations(gfxContext* aContext,
size.height *= relativeSize; size.height *= relativeSize;
PaintDecorationLine(aFrame, aContext, aDirtyRect, color, nullptr, pt, PaintDecorationLine(aFrame, aContext, aDirtyRect, color, nullptr, pt,
(aVertical ? (pt.y - aPt.y) : (pt.x - aPt.x)) + aICoordInFrame, (aVertical ? (pt.y - aPt.y) : (pt.x - aPt.x)) + aICoordInFrame,
size, aAscent, aFontMetrics.underlineOffset, size, aAscent,
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, style, eSelectionDecoration, aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
aFontMetrics.underlineOffset : aFontMetrics.maxAscent,
aDecoration, style, eSelectionDecoration,
aCallbacks, aVertical, descentLimit); aCallbacks, aVertical, descentLimit);
} }
@ -5804,6 +5827,10 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
gfxFont* firstFont = aProvider.GetFontGroup()->GetFirstValidFont(); gfxFont* firstFont = aProvider.GetFontGroup()->GetFirstValidFont();
bool verticalRun = mTextRun->IsVertical(); bool verticalRun = mTextRun->IsVertical();
bool rightUnderline = verticalRun && IsUnderlineRight(this);
const uint8_t kDecoration =
rightUnderline ? NS_STYLE_TEXT_DECORATION_LINE_OVERLINE :
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
bool useVerticalMetrics = verticalRun && mTextRun->UseCenterBaseline(); bool useVerticalMetrics = verticalRun && mTextRun->UseCenterBaseline();
gfxFont::Metrics gfxFont::Metrics
decorationMetrics(firstFont->GetMetrics(useVerticalMetrics ? decorationMetrics(firstFont->GetMetrics(useVerticalMetrics ?
@ -5850,7 +5877,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType, this, DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType, this,
aTextPaintStyle, selectedStyle, pt, xInFrame, aTextPaintStyle, selectedStyle, pt, xInFrame,
width, mAscent / app, decorationMetrics, width, mAscent / app, decorationMetrics,
aCallbacks, verticalRun); aCallbacks, verticalRun, kDecoration);
} }
iterator.UpdateWithAdvance(advance); iterator.UpdateWithAdvance(advance);
} }

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

@ -772,9 +772,7 @@ nsMathMLmtableOuterFrame::GetRowFrameAt(nsPresContext* aPresContext,
nsIFrame* rgFrame = tableFrame->GetFirstPrincipalChild(); nsIFrame* rgFrame = tableFrame->GetFirstPrincipalChild();
if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame) if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame)
return nullptr; return nullptr;
nsTableIterator rowIter(*rgFrame); for (nsIFrame* rowFrame : rgFrame->PrincipalChildList()) {
nsIFrame* rowFrame = rowIter.First();
for ( ; rowFrame; rowFrame = rowIter.Next()) {
if (aRowIndex == 0) { if (aRowIndex == 0) {
DEBUG_VERIFY_THAT_FRAME_IS(rowFrame, TABLE_ROW); DEBUG_VERIFY_THAT_FRAME_IS(rowFrame, TABLE_ROW);
if (rowFrame->GetType() != nsGkAtoms::tableRowFrame) if (rowFrame->GetType() != nsGkAtoms::tableRowFrame)

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

@ -5,14 +5,14 @@
<style> <style>
table { table {
margin: 10px; margin: 10px;
border: 3px solid silver; border: 8px solid silver;
border-right-color: gray; border-right-color: gray;
border-bottom-color: gray; border-bottom-color: gray;
border-spacing: 5px; border-spacing: 5px;
border-collapse: collapse; border-collapse: collapse;
} }
td { td {
border: 5px solid black; border: 4px solid black;
width: 50px; width: 50px;
height: 20px; height: 20px;
text-align: center; text-align: center;

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

@ -5,14 +5,14 @@
<style> <style>
table { table {
margin: 10px; margin: 10px;
border: 3px solid silver; border: 8px solid silver;
border-right-color: gray; border-right-color: gray;
border-bottom-color: gray; border-bottom-color: gray;
border-spacing: 5px; border-spacing: 5px;
border-collapse: collapse; border-collapse: collapse;
} }
td { td {
border: 5px solid black; border: 4px solid black;
width: 50px; width: 50px;
height: 20px; height: 20px;
text-align: center; text-align: center;

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

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1175789 - underline and overline in various language</title>
<style type="text/css">
body {
font-family: "Arial", "Helvetica", "sans-serif";
}
div {
padding: .5em 1em;
line-height: 2em;
}
.underline {
text-decoration: underline;
}
.overline {
text-decoration: overline;
}
</style>
</head>
<body>
<dl>
<dt>lang="en-US"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ja"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="ko"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="ja-JP"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="ko-KR"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="zh"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
</dl>
</body>
</html>

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

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1175789 - underline and overline in various language</title>
<style type="text/css">
body {
font-family: "Arial", "Helvetica", "sans-serif";
}
div {
padding: .5em 1em;
line-height: 2em;
}
.underline {
text-decoration: underline;
}
.overline {
text-decoration: overline;
}
</style>
</head>
<body>
<dl>
<dt>lang="en-US"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ja"</dt>
<dd lang="ja">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ko"</dt>
<dd lang="ko">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ja-JP"</dt>
<dd lang="ja-JP">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ko-KR"</dt>
<dd lang="ko-KR">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="zh"</dt>
<dd lang="zh">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
</dl>
</body>
</html>

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

@ -149,6 +149,7 @@ fails == 1147834-relative-overconstrained-vertical-rl-rtl.html 1147834-top-left-
== 1172774-percent-padding-3.html 1172774-percent-vertical-ref.html == 1172774-percent-padding-3.html 1172774-percent-vertical-ref.html
== 1172774-percent-padding-4.html 1172774-percent-vertical-ref.html == 1172774-percent-padding-4.html 1172774-percent-vertical-ref.html
== 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html == 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html
== 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html
# Suite of tests from Gérard Talbot in bug 1079151 # Suite of tests from Gérard Talbot in bug 1079151
include abspos/reftest.list include abspos/reftest.list

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

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=78: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* an object that stores the result of determining whether a style struct that
* was computed can be cached in the rule tree, and if so, what the cache
* key is
*/
#include "RuleNodeCacheConditions.h"
#include "nsStyleContext.h"
#include "WritingModes.h"
using namespace mozilla;
bool
RuleNodeCacheConditions::Matches(nsStyleContext* aStyleContext) const
{
MOZ_ASSERT(Cacheable());
if ((mBits & eHaveFontSize) &&
mFontSize != aStyleContext->StyleFont()->mFont.size) {
return false;
}
if ((mBits & eHaveWritingMode) &&
(GetWritingMode() != WritingMode(aStyleContext).GetBits())) {
return false;
}
return true;
}
#ifdef DEBUG
void
RuleNodeCacheConditions::List() const
{
printf("{ ");
bool first = true;
if (mBits & eHaveFontSize) {
printf("FontSize(%d)", mFontSize);
first = false;
}
if (mBits & eHaveWritingMode) {
if (!first) {
printf(", ");
}
printf("WritingMode(0x%x)", GetWritingMode());
}
printf(" }");
}
#endif

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

@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* an object that stores the result of determining whether a style struct that
* was computed can be cached in the rule tree, and if so, what the conditions
* it relies on are
*/
#ifndef RuleNodeCacheConditions_h_
#define RuleNodeCacheConditions_h_
#include "mozilla/Attributes.h"
#include "nsCoord.h"
#include "nsTArray.h"
class nsStyleContext;
namespace mozilla {
class RuleNodeCacheConditions
{
public:
RuleNodeCacheConditions()
: mFontSize(0), mBits(0) {}
RuleNodeCacheConditions(const RuleNodeCacheConditions& aOther)
: mFontSize(aOther.mFontSize), mBits(aOther.mBits) {}
RuleNodeCacheConditions& operator=(const RuleNodeCacheConditions& aOther)
{
mFontSize = aOther.mFontSize;
mBits = aOther.mBits;
return *this;
}
bool operator==(const RuleNodeCacheConditions& aOther) const
{
return mFontSize == aOther.mFontSize &&
mBits == aOther.mBits;
}
bool operator!=(const RuleNodeCacheConditions& aOther) const
{
return !(*this == aOther);
}
bool Matches(nsStyleContext* aStyleContext) const;
void SetFontSizeDependency(nscoord aCoord)
{
MOZ_ASSERT(!(mBits & eHaveFontSize) || mFontSize == aCoord);
mFontSize = aCoord;
mBits |= eHaveFontSize;
}
void SetWritingModeDependency(uint8_t aWritingMode)
{
MOZ_ASSERT(!(mBits & eHaveWritingMode) || GetWritingMode() == aWritingMode);
mBits |= (static_cast<uint64_t>(aWritingMode) << eWritingModeShift) |
eHaveWritingMode;
}
void SetUncacheable()
{
mBits |= eUncacheable;
}
bool Cacheable() const
{
return !(mBits & eUncacheable);
}
bool CacheableWithDependencies() const
{
return !(mBits & eUncacheable) &&
(mBits & eHaveBitsMask) != 0;
}
bool CacheableWithoutDependencies() const
{
// We're not uncacheable and we have don't have a font-size or
// writing mode value.
return (mBits & eHaveBitsMask) == 0;
}
#ifdef DEBUG
void List() const;
#endif
private:
enum {
eUncacheable = 0x0001,
eHaveFontSize = 0x0002,
eHaveWritingMode = 0x0004,
eHaveBitsMask = 0x00ff,
eWritingModeMask = 0xff00,
eWritingModeShift = 8,
};
uint8_t GetWritingMode() const
{
return static_cast<uint8_t>(
(mBits & eWritingModeMask) >> eWritingModeShift);
}
// The font size from which em units are derived.
nscoord mFontSize;
// Values in mBits:
// bit 0: are we set to "uncacheable"?
// bit 1: do we have a font size value?
// bit 2: do we have a writing mode value?
// bits 2-7: unused
// bits 8-15: writing mode (uint8_t)
// bits 16-31: unused
uint32_t mBits;
};
} // namespace mozilla
#endif // !defined(RuleNodeCacheConditions_h_)

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

@ -7,7 +7,7 @@
#include "mozilla/ArrayUtils.h" #include "mozilla/ArrayUtils.h"
#include "mozilla/MathAlgorithms.h" #include "mozilla/MathAlgorithms.h"
#include "mozilla/RuleNodeCacheConditions.h"
#include "mozilla/StyleAnimationValue.h" #include "mozilla/StyleAnimationValue.h"
#include "nsStyleTransformMatrix.h" #include "nsStyleTransformMatrix.h"
#include "nsCOMArray.h" #include "nsCOMArray.h"
@ -2590,7 +2590,7 @@ StyleAnimationValue::ComputeValue(nsCSSProperty aProperty,
// context-sensitive. So if there's nothing cached, it's not context // context-sensitive. So if there's nothing cached, it's not context
// sensitive. // sensitive.
*aIsContextSensitive = *aIsContextSensitive =
!tmpStyleContext->RuleNode()->NodeHasCachedData(sid); !tmpStyleContext->RuleNode()->NodeHasCachedUnconditionalData(sid);
} }
// If we're not concerned whether the property is context sensitive then just // If we're not concerned whether the property is context sensitive then just
@ -2868,11 +2868,11 @@ SubstitutePixelValues(nsStyleContext* aStyleContext,
const nsCSSValue& aInput, nsCSSValue& aOutput) const nsCSSValue& aInput, nsCSSValue& aOutput)
{ {
if (aInput.IsCalcUnit()) { if (aInput.IsCalcUnit()) {
bool canStoreInRuleTree = true; RuleNodeCacheConditions conditions;
nsRuleNode::ComputedCalc c = nsRuleNode::ComputedCalc c =
nsRuleNode::SpecifiedCalcToComputedCalc(aInput, aStyleContext, nsRuleNode::SpecifiedCalcToComputedCalc(aInput, aStyleContext,
aStyleContext->PresContext(), aStyleContext->PresContext(),
canStoreInRuleTree); conditions);
nsStyleCoord::CalcValue c2; nsStyleCoord::CalcValue c2;
c2.mLength = c.mLength; c2.mLength = c.mLength;
c2.mPercent = c.mPercent; c2.mPercent = c.mPercent;
@ -2889,10 +2889,10 @@ SubstitutePixelValues(nsStyleContext* aStyleContext,
aOutput.SetArrayValue(outputArray, aInput.GetUnit()); aOutput.SetArrayValue(outputArray, aInput.GetUnit());
} else if (aInput.IsLengthUnit() && } else if (aInput.IsLengthUnit() &&
aInput.GetUnit() != eCSSUnit_Pixel) { aInput.GetUnit() != eCSSUnit_Pixel) {
bool canStoreInRuleTree = true; RuleNodeCacheConditions conditions;
nscoord len = nsRuleNode::CalcLength(aInput, aStyleContext, nscoord len = nsRuleNode::CalcLength(aInput, aStyleContext,
aStyleContext->PresContext(), aStyleContext->PresContext(),
canStoreInRuleTree); conditions);
aOutput.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(len), aOutput.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(len),
eCSSUnit_Pixel); eCSSUnit_Pixel);
} else { } else {

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

@ -256,7 +256,6 @@ xmp, pre, plaintext {
/* tables */ /* tables */
table { table {
writing-mode: horizontal-tb !important; /* XXX remove when bug 1077521 is fixed */
display: table; display: table;
border-spacing: 2px; border-spacing: 2px;
border-collapse: separate; border-collapse: separate;

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

@ -85,6 +85,7 @@ EXPORTS.mozilla += [
'CSSVariableResolver.h', 'CSSVariableResolver.h',
'CSSVariableValues.h', 'CSSVariableValues.h',
'IncrementalClearCOMRuleArray.h', 'IncrementalClearCOMRuleArray.h',
'RuleNodeCacheConditions.h',
'StyleAnimationValue.h', 'StyleAnimationValue.h',
] ]
@ -163,6 +164,7 @@ UNIFIED_SOURCES += [
'nsStyleTransformMatrix.cpp', 'nsStyleTransformMatrix.cpp',
'nsStyleUtil.cpp', 'nsStyleUtil.cpp',
'nsTransitionManager.cpp', 'nsTransitionManager.cpp',
'RuleNodeCacheConditions.cpp',
'StyleAnimationValue.cpp', 'StyleAnimationValue.cpp',
'StyleRule.cpp', 'StyleRule.cpp',
'SVGAttrAnimationRuleProcessor.cpp', 'SVGAttrAnimationRuleProcessor.cpp',

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

@ -254,7 +254,8 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
// We can't cache anything on the rule tree if we use any data from // We can't cache anything on the rule tree if we use any data from
// the style context, since data cached in the rule tree could be // the style context, since data cached in the rule tree could be
// used with a style context with a different value. // used with a style context with a different value.
aRuleData->mCanStoreInRuleTree = false; uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
aRuleData->mConditions.SetWritingModeDependency(wm);
} }
nsCSSValue* target = aRuleData->ValueFor(iProp); nsCSSValue* target = aRuleData->ValueFor(iProp);
if (target->GetUnit() == eCSSUnit_Null) { if (target->GetUnit() == eCSSUnit_Null) {
@ -693,7 +694,8 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID,
nsCSSProperty physicalProp = aPropID; nsCSSProperty physicalProp = aPropID;
if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) { if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) {
EnsurePhysicalProperty(physicalProp, aRuleData); EnsurePhysicalProperty(physicalProp, aRuleData);
aRuleData->mCanStoreInRuleTree = false; uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
aRuleData->mConditions.SetWritingModeDependency(wm);
} }
nsCSSValue* dest = aRuleData->ValueFor(physicalProp); nsCSSValue* dest = aRuleData->ValueFor(physicalProp);

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

@ -1265,7 +1265,7 @@ nsComputedDOMStyle::DoGetTransform()
nsStyleTransformMatrix::TransformReferenceBox refBox(mInnerFrame, nsStyleTransformMatrix::TransformReferenceBox refBox(mInnerFrame,
nsSize(0, 0)); nsSize(0, 0));
bool dummy; RuleNodeCacheConditions dummy;
gfx3DMatrix matrix = gfx3DMatrix matrix =
nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead, nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead,
mStyleContextHolder, mStyleContextHolder,

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

@ -28,7 +28,6 @@ nsRuleData::GetPoisonOffset()
nsRuleData::nsRuleData(uint32_t aSIDs, nsCSSValue* aValueStorage, nsRuleData::nsRuleData(uint32_t aSIDs, nsCSSValue* aValueStorage,
nsPresContext* aContext, nsStyleContext* aStyleContext) nsPresContext* aContext, nsStyleContext* aStyleContext)
: mSIDs(aSIDs), : mSIDs(aSIDs),
mCanStoreInRuleTree(true),
mPresContext(aContext), mPresContext(aContext),
mStyleContext(aStyleContext), mStyleContext(aStyleContext),
mValueStorage(aValueStorage) mValueStorage(aValueStorage)

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

@ -12,6 +12,7 @@
#define nsRuleData_h_ #define nsRuleData_h_
#include "mozilla/CSSVariableDeclarations.h" #include "mozilla/CSSVariableDeclarations.h"
#include "mozilla/RuleNodeCacheConditions.h"
#include "nsCSSProps.h" #include "nsCSSProps.h"
#include "nsCSSValue.h" #include "nsCSSValue.h"
#include "nsStyleStructFwd.h" #include "nsStyleStructFwd.h"
@ -25,7 +26,7 @@ typedef void (*nsPostResolveFunc)(void* aStyleStruct, nsRuleData* aData);
struct nsRuleData struct nsRuleData
{ {
const uint32_t mSIDs; const uint32_t mSIDs;
bool mCanStoreInRuleTree; mozilla::RuleNodeCacheConditions mConditions;
bool mIsImportantRule; bool mIsImportantRule;
uint16_t mLevel; // an nsStyleSet::sheetType uint16_t mLevel; // an nsStyleSet::sheetType
nsPresContext* const mPresContext; nsPresContext* const mPresContext;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -11,19 +11,21 @@
#ifndef nsRuleNode_h___ #ifndef nsRuleNode_h___
#define nsRuleNode_h___ #define nsRuleNode_h___
#include "mozilla/PodOperations.h"
#include "mozilla/RangedArray.h" #include "mozilla/RangedArray.h"
#include "mozilla/RuleNodeCacheConditions.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsStyleStruct.h" #include "nsStyleStruct.h"
class nsStyleContext;
struct nsRuleData;
class nsIStyleRule;
struct nsCSSValueList;
class nsCSSPropertySet; class nsCSSPropertySet;
class nsCSSValue; class nsCSSValue;
class nsIStyleRule;
class nsStyleContext;
class nsStyleCoord; class nsStyleCoord;
struct nsCSSRect;
struct nsCSSValueList;
struct nsCSSValuePairList; struct nsCSSValuePairList;
struct nsRuleData;
struct nsInheritedStyleData struct nsInheritedStyleData
{ {
@ -101,10 +103,146 @@ struct nsResetStyleData
} }
}; };
struct nsConditionalResetStyleData
{
static uint32_t GetBitForSID(const nsStyleStructID aSID) {
return 1 << aSID;
}
struct Entry
{
Entry(const mozilla::RuleNodeCacheConditions& aConditions,
void* aStyleStruct,
Entry* aNext)
: mConditions(aConditions), mStyleStruct(aStyleStruct), mNext(aNext) {}
void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
return aContext->PresShell()->
AllocateByObjectID(nsPresArena::nsConditionalResetStyleDataEntry_id, sz);
}
const mozilla::RuleNodeCacheConditions mConditions;
void* const mStyleStruct;
Entry* const mNext;
};
// Each entry is either a pointer to a style struct or a
// pointer to an Entry object. A bit in mConditionalBits
// means that it is an Entry.
mozilla::RangedArray<void*,
nsStyleStructID_Reset_Start,
nsStyleStructID_Reset_Count> mEntries;
uint32_t mConditionalBits;
nsConditionalResetStyleData()
{
for (nsStyleStructID i = nsStyleStructID_Reset_Start;
i < nsStyleStructID_Reset_Start + nsStyleStructID_Reset_Count;
i = nsStyleStructID(i + 1)) {
mEntries[i] = nullptr;
}
mConditionalBits = 0;
}
void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
return aContext->PresShell()->
AllocateByObjectID(nsPresArena::nsConditionalResetStyleData_id, sz);
}
void* GetStyleData(nsStyleStructID aSID) const {
if (mConditionalBits & GetBitForSID(aSID)) {
return nullptr;
}
return mEntries[aSID];
}
void* GetStyleData(nsStyleStructID aSID,
nsStyleContext* aStyleContext) const {
if (!(mConditionalBits & GetBitForSID(aSID))) {
return mEntries[aSID];
}
Entry* e = static_cast<Entry*>(mEntries[aSID]);
MOZ_ASSERT(e, "if mConditionalBits bit is set, we must have at least one "
"conditional style struct");
do {
if (e->mConditions.Matches(aStyleContext)) {
return e->mStyleStruct;
}
e = e->mNext;
} while (e);
return nullptr;
}
void SetStyleData(nsStyleStructID aSID, void* aStyleStruct) {
MOZ_ASSERT(!(mConditionalBits & GetBitForSID(aSID)),
"rule node should not have unconditional and conditional style "
"data for a given struct");
mEntries[aSID] = aStyleStruct;
}
void SetStyleData(nsStyleStructID aSID,
nsPresContext* aPresContext,
void* aStyleStruct,
const mozilla::RuleNodeCacheConditions& aConditions) {
MOZ_ASSERT((mConditionalBits & GetBitForSID(aSID)) ||
!mEntries[aSID],
"rule node should not have unconditional and conditional style "
"data for a given struct");
MOZ_ASSERT(aConditions.CacheableWithDependencies(),
"don't call SetStyleData with a cache key that has no "
"conditions or is uncacheable");
#ifdef DEBUG
for (Entry* e = static_cast<Entry*>(mEntries[aSID]); e; e = e->mNext) {
NS_WARN_IF_FALSE(e->mConditions != aConditions,
"wasteful to have duplicate conditional style data");
}
#endif
mConditionalBits |= GetBitForSID(aSID);
mEntries[aSID] =
new (aPresContext) Entry(aConditions, aStyleStruct,
static_cast<Entry*>(mEntries[aSID]));
}
void Destroy(uint64_t aBits, nsPresContext* aContext) {
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
void* name##Ptr = mEntries[eStyleStruct_##name]; \
if (name##Ptr) { \
if (!(mConditionalBits & NS_STYLE_INHERIT_BIT(name))) { \
if (!(aBits & NS_STYLE_INHERIT_BIT(name))) { \
static_cast<nsStyle##name*>(name##Ptr)->Destroy(aContext); \
} \
} else { \
Entry* e = static_cast<Entry*>(name##Ptr); \
MOZ_ASSERT(e, "if mConditionalBits bit is set, we must have at least " \
"one conditional style struct"); \
do { \
static_cast<nsStyle##name*>(e->mStyleStruct)->Destroy(aContext); \
Entry* next = e->mNext; \
aContext->PresShell()->FreeByObjectID( \
nsPresArena::nsConditionalResetStyleDataEntry_id, e); \
e = next; \
} while (e); \
} \
}
#define STYLE_STRUCT_INHERITED(name, checkdata_cb)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET
#undef STYLE_STRUCT_INHERITED
aContext->PresShell()->
FreeByObjectID(nsPresArena::nsConditionalResetStyleData_id, this);
}
};
struct nsCachedStyleData struct nsCachedStyleData
{ {
nsInheritedStyleData* mInheritedData; nsInheritedStyleData* mInheritedData;
nsResetStyleData* mResetData; nsConditionalResetStyleData* mResetData;
static bool IsReset(const nsStyleStructID aSID) { static bool IsReset(const nsStyleStructID aSID) {
MOZ_ASSERT(0 <= aSID && aSID < nsStyleStructID_Length, MOZ_ASSERT(0 <= aSID && aSID < nsStyleStructID_Length,
@ -117,13 +255,27 @@ struct nsCachedStyleData
} }
static uint32_t GetBitForSID(const nsStyleStructID aSID) { static uint32_t GetBitForSID(const nsStyleStructID aSID) {
return 1 << aSID; return nsConditionalResetStyleData::GetBitForSID(aSID);
} }
void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID) { void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID) {
if (IsReset(aSID)) { if (IsReset(aSID)) {
if (mResetData) { if (mResetData) {
return mResetData->mStyleStructs[aSID]; return mResetData->GetStyleData(aSID);
}
} else {
if (mInheritedData) {
return mInheritedData->mStyleStructs[aSID];
}
}
return nullptr;
}
void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID,
nsStyleContext* aStyleContext) {
if (IsReset(aSID)) {
if (mResetData) {
return mResetData->GetStyleData(aSID, aStyleContext);
} }
} else { } else {
if (mInheritedData) { if (mInheritedData) {
@ -137,9 +289,9 @@ struct nsCachedStyleData
nsPresContext *aPresContext, void *aData) { nsPresContext *aPresContext, void *aData) {
if (IsReset(aSID)) { if (IsReset(aSID)) {
if (!mResetData) { if (!mResetData) {
mResetData = new (aPresContext) nsResetStyleData; mResetData = new (aPresContext) nsConditionalResetStyleData;
} }
mResetData->mStyleStructs[aSID] = aData; mResetData->SetStyleData(aSID, aData);
} else { } else {
if (!mInheritedData) { if (!mInheritedData) {
mInheritedData = new (aPresContext) nsInheritedStyleData; mInheritedData = new (aPresContext) nsInheritedStyleData;
@ -149,15 +301,15 @@ struct nsCachedStyleData
} }
// Typesafe and faster versions of the above // Typesafe and faster versions of the above
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \ #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \ nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
return mInheritedData ? static_cast<nsStyle##name_*>( \ return mInheritedData ? static_cast<nsStyle##name_*>( \
mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nullptr; \ mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nullptr; \
} }
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \ #define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \ nsStyle##name_ * NS_FASTCALL GetStyle##name_ (nsStyleContext* aContext) { \
return mResetData ? static_cast<nsStyle##name_*>( \ return mResetData ? static_cast<nsStyle##name_*>( \
mResetData->mStyleStructs[eStyleStruct_##name_]) : nullptr; \ mResetData->GetStyleData(eStyleStruct_##name_, aContext)) : nullptr; \
} }
#include "nsStyleStructList.h" #include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET #undef STYLE_STRUCT_RESET
@ -435,119 +587,119 @@ protected:
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeVisibilityData(void* aStartStruct, ComputeVisibilityData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeFontData(void* aStartStruct, ComputeFontData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeColorData(void* aStartStruct, ComputeColorData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeBackgroundData(void* aStartStruct, ComputeBackgroundData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeMarginData(void* aStartStruct, ComputeMarginData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeBorderData(void* aStartStruct, ComputeBorderData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputePaddingData(void* aStartStruct, ComputePaddingData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeOutlineData(void* aStartStruct, ComputeOutlineData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeListData(void* aStartStruct, ComputeListData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputePositionData(void* aStartStruct, ComputePositionData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeTableData(void* aStartStruct, ComputeTableData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeTableBorderData(void* aStartStruct, ComputeTableBorderData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeContentData(void* aStartStruct, ComputeContentData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeQuotesData(void* aStartStruct, ComputeQuotesData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeTextData(void* aStartStruct, ComputeTextData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeTextResetData(void* aStartStruct, ComputeTextResetData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeUserInterfaceData(void* aStartStruct, ComputeUserInterfaceData(void* aStartStruct,
@ -555,49 +707,49 @@ protected:
nsStyleContext* aContext, nsStyleContext* aContext,
nsRuleNode* aHighestNode, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeUIResetData(void* aStartStruct, ComputeUIResetData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeXULData(void* aStartStruct, ComputeXULData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeColumnData(void* aStartStruct, ComputeColumnData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeSVGData(void* aStartStruct, ComputeSVGData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeSVGResetData(void* aStartStruct, ComputeSVGResetData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
const void* const void*
ComputeVariablesData(void* aStartStruct, ComputeVariablesData(void* aStartStruct,
const nsRuleData* aRuleData, const nsRuleData* aRuleData,
nsStyleContext* aContext, nsRuleNode* aHighestNode, nsStyleContext* aContext, nsRuleNode* aHighestNode,
RuleDetail aRuleDetail, RuleDetail aRuleDetail,
const bool aCanStoreInRuleTree); const mozilla::RuleNodeCacheConditions aConditions);
// helpers for |ComputeFontData| that need access to |mNoneBits|: // helpers for |ComputeFontData| that need access to |mNoneBits|:
static void SetFontSize(nsPresContext* aPresContext, static void SetFontSize(nsPresContext* aPresContext,
@ -610,7 +762,7 @@ protected:
nscoord aScriptLevelAdjustedParentSize, nscoord aScriptLevelAdjustedParentSize,
bool aUsedStartStruct, bool aUsedStartStruct,
bool aAtRoot, bool aAtRoot,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
static void SetFont(nsPresContext* aPresContext, static void SetFont(nsPresContext* aPresContext,
nsStyleContext* aContext, nsStyleContext* aContext,
@ -619,7 +771,7 @@ protected:
const nsStyleFont* aParentFont, const nsStyleFont* aParentFont,
nsStyleFont* aFont, nsStyleFont* aFont,
bool aStartStruct, bool aStartStruct,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
static void SetGenericFont(nsPresContext* aPresContext, static void SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext, nsStyleContext* aContext,
@ -633,17 +785,17 @@ protected:
GetShadowData(const nsCSSValueList* aList, GetShadowData(const nsCSSValueList* aList,
nsStyleContext* aContext, nsStyleContext* aContext,
bool aIsBoxShadow, bool aIsBoxShadow,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
bool SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter, bool SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
const nsCSSValue& aValue, const nsCSSValue& aValue,
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
void SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath, void SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
const nsCSSValue* aValue, const nsCSSValue* aValue,
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
private: private:
nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent, nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent,
@ -703,7 +855,7 @@ public:
// See comments in GetStyleData for an explanation of what the // See comments in GetStyleData for an explanation of what the
// code below does. // code below does.
#define STYLE_STRUCT(name_, checkdata_cb_) \ #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
template<bool aComputeData> \ template<bool aComputeData> \
const nsStyle##name_* \ const nsStyle##name_* \
GetStyle##name_(nsStyleContext* aContext) \ GetStyle##name_(nsStyleContext* aContext) \
@ -727,8 +879,36 @@ public:
MOZ_ASSERT(data, "should have aborted on out-of-memory"); \ MOZ_ASSERT(data, "should have aborted on out-of-memory"); \
return data; \ return data; \
} }
#define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
template<bool aComputeData> \
const nsStyle##name_* \
GetStyle##name_(nsStyleContext* aContext) \
{ \
NS_ASSERTION(IsUsedDirectly(), \
"if we ever call this on rule nodes that aren't used " \
"directly, we should adjust handling of mDependentBits " \
"in some way."); \
\
const nsStyle##name_ *data; \
data = mStyleData.GetStyle##name_(aContext); \
if (MOZ_LIKELY(data != nullptr)) \
return data; \
\
if (!aComputeData) \
return nullptr; \
\
data = static_cast<const nsStyle##name_ *> \
(WalkRuleTree(eStyleStruct_##name_, aContext)); \
\
MOZ_ASSERT(data, "should have aborted on out-of-memory"); \
return data; \
}
#include "nsStyleStructList.h" #include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_RESET
#undef STYLE_STRUCT_INHERITED
/* /*
* Garbage collection. Mark walks up the tree, marking any unmarked * Garbage collection. Mark walks up the tree, marking any unmarked
@ -764,7 +944,7 @@ public:
static nscoord CalcLength(const nsCSSValue& aValue, static nscoord CalcLength(const nsCSSValue& aValue,
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
struct ComputedCalc { struct ComputedCalc {
nscoord mLength; nscoord mLength;
@ -777,7 +957,7 @@ public:
SpecifiedCalcToComputedCalc(const nsCSSValue& aValue, SpecifiedCalcToComputedCalc(const nsCSSValue& aValue,
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree); mozilla::RuleNodeCacheConditions& aConditions);
// Compute the value of an nsStyleCoord that IsCalcUnit(). // Compute the value of an nsStyleCoord that IsCalcUnit().
// (Values that don't require aPercentageBasis should be handled // (Values that don't require aPercentageBasis should be handled
@ -799,7 +979,9 @@ public:
return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData; return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData;
} }
bool NodeHasCachedData(const nsStyleStructID aSID) { // Note that this will return false if we have cached conditional
// style structs.
bool NodeHasCachedUnconditionalData(const nsStyleStructID aSID) {
return !!mStyleData.GetStyleData(aSID); return !!mStyleData.GetStyleData(aSID);
} }

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

@ -148,7 +148,7 @@ float
ProcessTranslatePart(const nsCSSValue& aValue, ProcessTranslatePart(const nsCSSValue& aValue,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox* aRefBox, TransformReferenceBox* aRefBox,
TransformReferenceBox::DimensionGetter aDimensionGetter) TransformReferenceBox::DimensionGetter aDimensionGetter)
{ {
@ -172,12 +172,12 @@ ProcessTranslatePart(const nsCSSValue& aValue,
} else if (aValue.IsCalcUnit()) { } else if (aValue.IsCalcUnit()) {
nsRuleNode::ComputedCalc result = nsRuleNode::ComputedCalc result =
nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext, nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext,
aCanStoreInRuleTree); aConditions);
percent = result.mPercent; percent = result.mPercent;
offset = result.mLength; offset = result.mLength;
} else { } else {
offset = nsRuleNode::CalcLength(aValue, aContext, aPresContext, offset = nsRuleNode::CalcLength(aValue, aContext, aPresContext,
aCanStoreInRuleTree); aConditions);
} }
float translation = NSAppUnitsToFloatPixels(offset, float translation = NSAppUnitsToFloatPixels(offset,
@ -204,7 +204,7 @@ ProcessMatrix(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 7, "Invalid array!"); NS_PRECONDITION(aData->Count() == 7, "Invalid array!");
@ -223,10 +223,10 @@ ProcessMatrix(gfx3DMatrix& aMatrix,
* and their percent parts stored in aX[0] and aY[1]. * and their percent parts stored in aX[0] and aY[1].
*/ */
result._31 = ProcessTranslatePart(aData->Item(5), result._31 = ProcessTranslatePart(aData->Item(5),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
result._32 = ProcessTranslatePart(aData->Item(6), result._32 = ProcessTranslatePart(aData->Item(6),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
aMatrix.PreMultiply(result); aMatrix.PreMultiply(result);
@ -237,7 +237,7 @@ ProcessMatrix3D(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 17, "Invalid array!"); NS_PRECONDITION(aData->Count() == 17, "Invalid array!");
@ -259,13 +259,13 @@ ProcessMatrix3D(gfx3DMatrix& aMatrix,
temp._44 = aData->Item(16).GetFloatValue(); temp._44 = aData->Item(16).GetFloatValue();
temp._41 = ProcessTranslatePart(aData->Item(13), temp._41 = ProcessTranslatePart(aData->Item(13),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
temp._42 = ProcessTranslatePart(aData->Item(14), temp._42 = ProcessTranslatePart(aData->Item(14),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
temp._43 = ProcessTranslatePart(aData->Item(15), temp._43 = ProcessTranslatePart(aData->Item(15),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
nullptr); nullptr);
aMatrix.PreMultiply(temp); aMatrix.PreMultiply(temp);
@ -277,7 +277,7 @@ ProcessInterpolateMatrix(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 4, "Invalid array!"); NS_PRECONDITION(aData->Count() == 4, "Invalid array!");
@ -286,13 +286,13 @@ ProcessInterpolateMatrix(gfx3DMatrix& aMatrix,
if (aData->Item(1).GetUnit() == eCSSUnit_List) { if (aData->Item(1).GetUnit() == eCSSUnit_List) {
matrix1 = nsStyleTransformMatrix::ReadTransforms(aData->Item(1).GetListValue(), matrix1 = nsStyleTransformMatrix::ReadTransforms(aData->Item(1).GetListValue(),
aContext, aPresContext, aContext, aPresContext,
aCanStoreInRuleTree, aConditions,
aRefBox, nsPresContext::AppUnitsPerCSSPixel()); aRefBox, nsPresContext::AppUnitsPerCSSPixel());
} }
if (aData->Item(2).GetUnit() == eCSSUnit_List) { if (aData->Item(2).GetUnit() == eCSSUnit_List) {
matrix2 = ReadTransforms(aData->Item(2).GetListValue(), matrix2 = ReadTransforms(aData->Item(2).GetListValue(),
aContext, aPresContext, aContext, aPresContext,
aCanStoreInRuleTree, aConditions,
aRefBox, nsPresContext::AppUnitsPerCSSPixel()); aRefBox, nsPresContext::AppUnitsPerCSSPixel());
} }
double progress = aData->Item(3).GetPercentValue(); double progress = aData->Item(3).GetPercentValue();
@ -308,7 +308,7 @@ ProcessTranslateX(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 2, "Invalid array!"); NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
@ -316,7 +316,7 @@ ProcessTranslateX(gfx3DMatrix& aMatrix,
Point3D temp; Point3D temp;
temp.x = ProcessTranslatePart(aData->Item(1), temp.x = ProcessTranslatePart(aData->Item(1),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
aMatrix.Translate(temp); aMatrix.Translate(temp);
} }
@ -327,7 +327,7 @@ ProcessTranslateY(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 2, "Invalid array!"); NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
@ -335,7 +335,7 @@ ProcessTranslateY(gfx3DMatrix& aMatrix,
Point3D temp; Point3D temp;
temp.y = ProcessTranslatePart(aData->Item(1), temp.y = ProcessTranslatePart(aData->Item(1),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
aMatrix.Translate(temp); aMatrix.Translate(temp);
} }
@ -345,14 +345,14 @@ ProcessTranslateZ(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree) RuleNodeCacheConditions& aConditions)
{ {
NS_PRECONDITION(aData->Count() == 2, "Invalid array!"); NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
Point3D temp; Point3D temp;
temp.z = ProcessTranslatePart(aData->Item(1), aContext, temp.z = ProcessTranslatePart(aData->Item(1), aContext,
aPresContext, aCanStoreInRuleTree, aPresContext, aConditions,
nullptr); nullptr);
aMatrix.Translate(temp); aMatrix.Translate(temp);
} }
@ -363,7 +363,7 @@ ProcessTranslate(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 2 || aData->Count() == 3, "Invalid array!"); NS_PRECONDITION(aData->Count() == 2 || aData->Count() == 3, "Invalid array!");
@ -371,13 +371,13 @@ ProcessTranslate(gfx3DMatrix& aMatrix,
Point3D temp; Point3D temp;
temp.x = ProcessTranslatePart(aData->Item(1), temp.x = ProcessTranslatePart(aData->Item(1),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
/* If we read in a Y component, set it appropriately */ /* If we read in a Y component, set it appropriately */
if (aData->Count() == 3) { if (aData->Count() == 3) {
temp.y = ProcessTranslatePart(aData->Item(2), temp.y = ProcessTranslatePart(aData->Item(2),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
} }
aMatrix.Translate(temp); aMatrix.Translate(temp);
@ -388,7 +388,7 @@ ProcessTranslate3D(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData->Count() == 4, "Invalid array!"); NS_PRECONDITION(aData->Count() == 4, "Invalid array!");
@ -396,15 +396,15 @@ ProcessTranslate3D(gfx3DMatrix& aMatrix,
Point3D temp; Point3D temp;
temp.x = ProcessTranslatePart(aData->Item(1), temp.x = ProcessTranslatePart(aData->Item(1),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Width); &aRefBox, &TransformReferenceBox::Width);
temp.y = ProcessTranslatePart(aData->Item(2), temp.y = ProcessTranslatePart(aData->Item(2),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
&aRefBox, &TransformReferenceBox::Height); &aRefBox, &TransformReferenceBox::Height);
temp.z = ProcessTranslatePart(aData->Item(3), temp.z = ProcessTranslatePart(aData->Item(3),
aContext, aPresContext, aCanStoreInRuleTree, aContext, aPresContext, aConditions,
nullptr); nullptr);
aMatrix.Translate(temp); aMatrix.Translate(temp);
@ -592,12 +592,12 @@ ProcessPerspective(gfx3DMatrix& aMatrix,
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext *aContext, nsStyleContext *aContext,
nsPresContext *aPresContext, nsPresContext *aPresContext,
bool &aCanStoreInRuleTree) RuleNodeCacheConditions& aConditions)
{ {
NS_PRECONDITION(aData->Count() == 2, "Invalid array!"); NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
float depth = ProcessTranslatePart(aData->Item(1), aContext, float depth = ProcessTranslatePart(aData->Item(1), aContext,
aPresContext, aCanStoreInRuleTree, aPresContext, aConditions,
nullptr); nullptr);
aMatrix.Perspective(depth); aMatrix.Perspective(depth);
} }
@ -612,7 +612,7 @@ MatrixForTransformFunction(gfx3DMatrix& aMatrix,
const nsCSSValue::Array * aData, const nsCSSValue::Array * aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox) TransformReferenceBox& aRefBox)
{ {
NS_PRECONDITION(aData, "Why did you want to get data from a null array?"); NS_PRECONDITION(aData, "Why did you want to get data from a null array?");
@ -625,23 +625,23 @@ MatrixForTransformFunction(gfx3DMatrix& aMatrix,
switch (TransformFunctionOf(aData)) { switch (TransformFunctionOf(aData)) {
case eCSSKeyword_translatex: case eCSSKeyword_translatex:
ProcessTranslateX(aMatrix, aData, aContext, aPresContext, ProcessTranslateX(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_translatey: case eCSSKeyword_translatey:
ProcessTranslateY(aMatrix, aData, aContext, aPresContext, ProcessTranslateY(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_translatez: case eCSSKeyword_translatez:
ProcessTranslateZ(aMatrix, aData, aContext, aPresContext, ProcessTranslateZ(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree); aConditions);
break; break;
case eCSSKeyword_translate: case eCSSKeyword_translate:
ProcessTranslate(aMatrix, aData, aContext, aPresContext, ProcessTranslate(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_translate3d: case eCSSKeyword_translate3d:
ProcessTranslate3D(aMatrix, aData, aContext, aPresContext, ProcessTranslate3D(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_scalex: case eCSSKeyword_scalex:
ProcessScaleX(aMatrix, aData); ProcessScaleX(aMatrix, aData);
@ -682,19 +682,19 @@ MatrixForTransformFunction(gfx3DMatrix& aMatrix,
break; break;
case eCSSKeyword_matrix: case eCSSKeyword_matrix:
ProcessMatrix(aMatrix, aData, aContext, aPresContext, ProcessMatrix(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_matrix3d: case eCSSKeyword_matrix3d:
ProcessMatrix3D(aMatrix, aData, aContext, aPresContext, ProcessMatrix3D(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_interpolatematrix: case eCSSKeyword_interpolatematrix:
ProcessInterpolateMatrix(aMatrix, aData, aContext, aPresContext, ProcessInterpolateMatrix(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree, aRefBox); aConditions, aRefBox);
break; break;
case eCSSKeyword_perspective: case eCSSKeyword_perspective:
ProcessPerspective(aMatrix, aData, aContext, aPresContext, ProcessPerspective(aMatrix, aData, aContext, aPresContext,
aCanStoreInRuleTree); aConditions);
break; break;
default: default:
NS_NOTREACHED("Unknown transform function!"); NS_NOTREACHED("Unknown transform function!");
@ -716,7 +716,7 @@ gfx3DMatrix
ReadTransforms(const nsCSSValueList* aList, ReadTransforms(const nsCSSValueList* aList,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool &aCanStoreInRuleTree, RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox, TransformReferenceBox& aRefBox,
float aAppUnitsPerMatrixUnit) float aAppUnitsPerMatrixUnit)
{ {
@ -736,7 +736,7 @@ ReadTransforms(const nsCSSValueList* aList,
/* Read in a single transform matrix. */ /* Read in a single transform matrix. */
MatrixForTransformFunction(result, currElem.GetArrayValue(), aContext, MatrixForTransformFunction(result, currElem.GetArrayValue(), aContext,
aPresContext, aCanStoreInRuleTree, aRefBox); aPresContext, aConditions, aRefBox);
} }
float scale = float(nsPresContext::AppUnitsPerCSSPixel()) / aAppUnitsPerMatrixUnit; float scale = float(nsPresContext::AppUnitsPerCSSPixel()) / aAppUnitsPerMatrixUnit;

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

@ -17,6 +17,9 @@ class nsIFrame;
class nsStyleContext; class nsStyleContext;
class nsPresContext; class nsPresContext;
struct nsRect; struct nsRect;
namespace mozilla {
class RuleNodeCacheConditions;
}
/** /**
* A helper to generate gfxMatrixes from css transform functions. * A helper to generate gfxMatrixes from css transform functions.
@ -128,7 +131,7 @@ namespace nsStyleTransformMatrix {
float ProcessTranslatePart(const nsCSSValue& aValue, float ProcessTranslatePart(const nsCSSValue& aValue,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, mozilla::RuleNodeCacheConditions& aConditions,
TransformReferenceBox* aRefBox, TransformReferenceBox* aRefBox,
TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr); TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr);
@ -137,7 +140,7 @@ namespace nsStyleTransformMatrix {
const nsCSSValue::Array* aData, const nsCSSValue::Array* aData,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool& aCanStoreInRuleTree, mozilla::RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aBounds); TransformReferenceBox& aBounds);
/** /**
@ -147,8 +150,8 @@ namespace nsStyleTransformMatrix {
* @param aData The nsCSSValueList containing the transform functions * @param aData The nsCSSValueList containing the transform functions
* @param aContext The style context, used for unit conversion. * @param aContext The style context, used for unit conversion.
* @param aPresContext The presentation context, used for unit conversion. * @param aPresContext The presentation context, used for unit conversion.
* @param aCanStoreInRuleTree Set to false if the result cannot be cached * @param aConditions Set to uncachable (by calling SetUncacheable()) if the
* in the rule tree, otherwise untouched. * result cannot be cached in the rule tree, otherwise untouched.
* @param aBounds The frame's bounding rectangle. * @param aBounds The frame's bounding rectangle.
* @param aAppUnitsPerMatrixUnit The number of app units per device pixel. * @param aAppUnitsPerMatrixUnit The number of app units per device pixel.
* *
@ -159,7 +162,7 @@ namespace nsStyleTransformMatrix {
gfx3DMatrix ReadTransforms(const nsCSSValueList* aList, gfx3DMatrix ReadTransforms(const nsCSSValueList* aList,
nsStyleContext* aContext, nsStyleContext* aContext,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool &aCanStoreInRuleTree, mozilla::RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aBounds, TransformReferenceBox& aBounds,
float aAppUnitsPerMatrixUnit); float aAppUnitsPerMatrixUnit);

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

@ -82,7 +82,7 @@ nsTableCellFrame::Init(nsIContent* aContent,
// Let the base class do its initialization // Let the base class do its initialization
nsContainerFrame::Init(aContent, aParent, aPrevInFlow); nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) { if (HasAnyStateBits(NS_FRAME_FONT_INFLATION_CONTAINER)) {
AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT); AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
} }
@ -98,17 +98,17 @@ nsTableCellFrame::Init(nsIContent* aContent,
void void
nsTableCellFrame::DestroyFrom(nsIFrame* aDestructRoot) nsTableCellFrame::DestroyFrom(nsIFrame* aDestructRoot)
{ {
if (GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) { if (HasAnyStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN)) {
nsTableFrame::UnregisterPositionedTablePart(this, aDestructRoot); nsTableFrame::UnregisterPositionedTablePart(this, aDestructRoot);
} }
nsContainerFrame::DestroyFrom(aDestructRoot); nsContainerFrame::DestroyFrom(aDestructRoot);
} }
// nsIPercentHeightObserver methods // nsIPercentBSizeObserver methods
void void
nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState) nsTableCellFrame::NotifyPercentBSize(const nsHTMLReflowState& aReflowState)
{ {
// nsHTMLReflowState ensures the mCBReflowState of blocks inside a // nsHTMLReflowState ensures the mCBReflowState of blocks inside a
// cell is the cell frame, not the inner-cell block, and that the // cell is the cell frame, not the inner-cell block, and that the
@ -121,20 +121,20 @@ nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
const nsHTMLReflowState *cellRS = aReflowState.mCBReflowState; const nsHTMLReflowState *cellRS = aReflowState.mCBReflowState;
if (cellRS && cellRS->frame == this && if (cellRS && cellRS->frame == this &&
(cellRS->ComputedHeight() == NS_UNCONSTRAINEDSIZE || (cellRS->ComputedBSize() == NS_UNCONSTRAINEDSIZE ||
cellRS->ComputedHeight() == 0)) { // XXXldb Why 0? cellRS->ComputedBSize() == 0)) { // XXXldb Why 0?
// This is a percentage height on a frame whose percentage heights // This is a percentage bsize on a frame whose percentage bsizes
// are based on the height of the cell, since its containing block // are based on the bsize of the cell, since its containing block
// is the inner cell frame. // is the inner cell frame.
// We'll only honor the percent height if sibling-cells/ancestors // We'll only honor the percent bsize if sibling-cells/ancestors
// have specified/pct height. (Also, siblings only count for this if // have specified/pct bsize. (Also, siblings only count for this if
// both this cell and the sibling cell span exactly 1 row.) // both this cell and the sibling cell span exactly 1 row.)
if (nsTableFrame::AncestorsHaveStyleHeight(*cellRS) || if (nsTableFrame::AncestorsHaveStyleBSize(*cellRS) ||
(GetTableFrame()->GetEffectiveRowSpan(*this) == 1 && (GetTableFrame()->GetEffectiveRowSpan(*this) == 1 &&
(cellRS->parentReflowState->frame->GetStateBits() & cellRS->parentReflowState->frame->
NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT))) { HasAnyStateBits(NS_ROW_HAS_CELL_WITH_STYLE_BSIZE))) {
for (const nsHTMLReflowState *rs = aReflowState.parentReflowState; for (const nsHTMLReflowState *rs = aReflowState.parentReflowState;
rs != cellRS; rs != cellRS;
@ -142,7 +142,7 @@ nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE); rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
} }
nsTableFrame::RequestSpecialHeightReflow(*cellRS); nsTableFrame::RequestSpecialBSizeReflow(*cellRS);
} }
} }
} }
@ -165,7 +165,7 @@ nsTableCellFrame::NeedsToObserve(const nsHTMLReflowState& aReflowState)
return false; return false;
} }
// We always need to let the percent height observer be propagated // We always need to let the percent bsize observer be propagated
// from an outer table frame to an inner table frame. // from an outer table frame to an inner table frame.
nsIAtom *fType = aReflowState.frame->GetType(); nsIAtom *fType = aReflowState.frame->GetType();
if (fType == nsGkAtoms::tableFrame) { if (fType == nsGkAtoms::tableFrame) {
@ -175,6 +175,9 @@ nsTableCellFrame::NeedsToObserve(const nsHTMLReflowState& aReflowState)
// We need the observer to be propagated to all children of the cell // We need the observer to be propagated to all children of the cell
// (i.e., children of the child block) in quirks mode, but only to // (i.e., children of the child block) in quirks mode, but only to
// tables in standards mode. // tables in standards mode.
// XXX This may not be true in the case of orthogonal flows within
// the cell (bug 1174711 comment 8); we may need to observe isizes
// instead of bsizes for orthogonal children.
return rs->frame == this && return rs->frame == this &&
(PresContext()->CompatibilityMode() == eCompatibility_NavQuirks || (PresContext()->CompatibilityMode() == eCompatibility_NavQuirks ||
fType == nsGkAtoms::tableOuterFrame); fType == nsGkAtoms::tableOuterFrame);
@ -864,12 +867,12 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame"); DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
if (aReflowState.mFlags.mSpecialHeightReflow) { if (aReflowState.mFlags.mSpecialBSizeReflow) {
FirstInFlow()->AddStateBits(NS_TABLE_CELL_HAD_SPECIAL_REFLOW); FirstInFlow()->AddStateBits(NS_TABLE_CELL_HAD_SPECIAL_REFLOW);
} }
// see if a special height reflow needs to occur due to having a pct height // see if a special bsize reflow needs to occur due to having a pct height
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState); nsTableFrame::CheckRequestSpecialBSizeReflow(aReflowState);
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
WritingMode wm = aReflowState.GetWritingMode(); WritingMode wm = aReflowState.GetWritingMode();
@ -899,7 +902,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame"); NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame");
nsTableFrame* tableFrame = GetTableFrame(); nsTableFrame* tableFrame = GetTableFrame();
if (aReflowState.mFlags.mSpecialHeightReflow) { if (aReflowState.mFlags.mSpecialBSizeReflow) {
const_cast<nsHTMLReflowState&>(aReflowState). const_cast<nsHTMLReflowState&>(aReflowState).
SetComputedBSize(BSize(wm) - borderPadding.BStartEnd(wm)); SetComputedBSize(BSize(wm) - borderPadding.BStartEnd(wm));
DISPLAY_REFLOW_CHANGE(); DISPLAY_REFLOW_CHANGE();
@ -922,22 +925,22 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
availSize.ConvertTo(kidWM, wm)); availSize.ConvertTo(kidWM, wm));
// Don't be a percent height observer if we're in the middle of // Don't be a percent height observer if we're in the middle of
// special-height reflow, in case we get an accidental NotifyPercentHeight() // special-bsize reflow, in case we get an accidental NotifyPercentBSize()
// call (which we shouldn't honor during special-height reflow) // call (which we shouldn't honor during special-bsize reflow)
if (!aReflowState.mFlags.mSpecialHeightReflow) { if (!aReflowState.mFlags.mSpecialBSizeReflow) {
// mPercentHeightObserver is for children of cells in quirks mode, // mPercentBSizeObserver is for children of cells in quirks mode,
// but only those than are tables in standards mode. NeedsToObserve // but only those than are tables in standards mode. NeedsToObserve
// will determine how far this is propagated to descendants. // will determine how far this is propagated to descendants.
kidReflowState.mPercentHeightObserver = this; kidReflowState.mPercentBSizeObserver = this;
} }
// Don't propagate special height reflow state to our kids // Don't propagate special bsize reflow state to our kids
kidReflowState.mFlags.mSpecialHeightReflow = false; kidReflowState.mFlags.mSpecialBSizeReflow = false;
if (aReflowState.mFlags.mSpecialHeightReflow || if (aReflowState.mFlags.mSpecialBSizeReflow ||
(FirstInFlow()->GetStateBits() & NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) { FirstInFlow()->HasAnyStateBits(NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) {
// We need to force the kid to have mBResize set if we've had a // We need to force the kid to have mBResize set if we've had a
// special reflow in the past, since the non-special reflow needs to // special reflow in the past, since the non-special reflow needs to
// resize back to what it was without the special height reflow. // resize back to what it was without the special bsize reflow.
kidReflowState.SetBResize(true); kidReflowState.SetBResize(true);
} }
@ -953,7 +956,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
borderPadding.BStart(wm)); borderPadding.BStart(wm));
nsRect origRect = firstKid->GetRect(); nsRect origRect = firstKid->GetRect();
nsRect origVisualOverflow = firstKid->GetVisualOverflowRect(); nsRect origVisualOverflow = firstKid->GetVisualOverflowRect();
bool firstReflow = (firstKid->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; bool firstReflow = firstKid->HasAnyStateBits(NS_FRAME_FIRST_REFLOW);
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState, ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
wm, kidOrigin, containerWidth, 0, aStatus); wm, kidOrigin, containerWidth, 0, aStatus);
@ -965,7 +968,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
} }
// XXXbz is this invalidate actually needed, really? // XXXbz is this invalidate actually needed, really?
if (GetStateBits() & NS_FRAME_IS_DIRTY) { if (HasAnyStateBits(NS_FRAME_IS_DIRTY)) {
InvalidateFrameSubtree(); InvalidateFrameSubtree();
} }
@ -1013,7 +1016,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
// the overflow area will be computed when BlockDirAlignChild() gets called // the overflow area will be computed when BlockDirAlignChild() gets called
if (aReflowState.mFlags.mSpecialHeightReflow) { if (aReflowState.mFlags.mSpecialBSizeReflow) {
if (aDesiredSize.BSize(wm) > BSize(wm)) { if (aDesiredSize.BSize(wm) > BSize(wm)) {
// set a bit indicating that the pct bsize contents exceeded // set a bit indicating that the pct bsize contents exceeded
// the height that they could honor in the pass 2 reflow // the height that they could honor in the pass 2 reflow
@ -1026,7 +1029,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
// If our parent is in initial reflow, it'll handle invalidating our // If our parent is in initial reflow, it'll handle invalidating our
// entire overflow rect. // entire overflow rect.
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) && if (!GetParent()->HasAnyStateBits(NS_FRAME_FIRST_REFLOW) &&
nsSize(aDesiredSize.Width(), aDesiredSize.Height()) != mRect.Size()) { nsSize(aDesiredSize.Width(), aDesiredSize.Height()) != mRect.Size()) {
InvalidateFrame(); InvalidateFrame();
} }
@ -1047,7 +1050,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
NS_QUERYFRAME_HEAD(nsTableCellFrame) NS_QUERYFRAME_HEAD(nsTableCellFrame)
NS_QUERYFRAME_ENTRY(nsTableCellFrame) NS_QUERYFRAME_ENTRY(nsTableCellFrame)
NS_QUERYFRAME_ENTRY(nsITableCellLayout) NS_QUERYFRAME_ENTRY(nsITableCellLayout)
NS_QUERYFRAME_ENTRY(nsIPercentHeightObserver) NS_QUERYFRAME_ENTRY(nsIPercentBSizeObserver)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY

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