summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@users.noreply.github.com>2017-12-05 18:36:17 +0100
committerGitHub <noreply@github.com>2017-12-05 18:36:17 +0100
commitf2ac9337cd5e097d0fb26bc3a02dcd44f8d0e2f0 (patch)
tree1da7e9ff1af3f8249fe7a214ee6e0f1e5a633789
parent8c66c6bc50342103692899928449477e806b21ed (diff)
parente021016bf830bde28bae69bfe9d3605fba49a9e5 (diff)
downloadpalemoon-f2ac9337cd5e097d0fb26bc3a02dcd44f8d0e2f0.tar.gz
Merge branch 'master' into html_details-summary_improvements_7
-rw-r--r--dom/base/nsIContent.h12
-rw-r--r--dom/events/EventNameList.h8
-rw-r--r--dom/webidl/Document.webidl5
-rw-r--r--dom/webidl/EventHandler.webidl2
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp15
-rw-r--r--js/src/frontend/FoldConstants.cpp14
-rw-r--r--js/src/frontend/ParseNode.cpp15
-rw-r--r--js/src/frontend/ParseNode.h8
-rw-r--r--js/src/frontend/Parser.cpp18
-rw-r--r--js/src/frontend/TokenKind.h8
-rw-r--r--js/src/frontend/TokenStream.cpp5
-rw-r--r--js/src/jit/BaselineCompiler.cpp6
-rw-r--r--js/src/jit/BaselineCompiler.h1
-rw-r--r--js/src/jit/BaselineIC.cpp7
-rw-r--r--js/src/jsreflect.cpp55
-rw-r--r--js/src/jsreflect.h4
-rw-r--r--js/src/vm/Interpreter.cpp13
-rw-r--r--js/src/vm/Opcodes.h10
-rw-r--r--js/src/vm/Xdr.h2
-rw-r--r--layout/base/crashtests/1297835.html6
-rw-r--r--layout/base/crashtests/crashtests.list1
-rw-r--r--layout/base/nsCSSFrameConstructor.cpp38
-rw-r--r--layout/base/nsCSSFrameConstructor.h21
-rw-r--r--layout/generic/DetailsFrame.cpp63
-rw-r--r--layout/generic/DetailsFrame.h6
-rw-r--r--layout/generic/crashtests/1304441.html9
-rw-r--r--layout/generic/crashtests/crashtests.list1
-rw-r--r--layout/reftests/details-summary/details-after.html21
-rw-r--r--layout/reftests/details-summary/details-before.html21
-rw-r--r--layout/reftests/details-summary/details-first-line-ref.html18
-rw-r--r--layout/reftests/details-summary/details-first-line.html24
-rw-r--r--layout/reftests/details-summary/details-in-ol-ref.html8
-rw-r--r--layout/reftests/details-summary/details-in-ol.html8
-rw-r--r--layout/reftests/details-summary/open-details-after.html21
-rw-r--r--layout/reftests/details-summary/open-details-before.html21
-rw-r--r--layout/reftests/details-summary/open-details-first-line-1.html24
-rw-r--r--layout/reftests/details-summary/open-details-first-line-2.html24
-rw-r--r--layout/reftests/details-summary/open-details-first-line-ref.html19
-rw-r--r--layout/reftests/details-summary/open-summary-inline-style-ref.html14
-rw-r--r--layout/reftests/details-summary/open-summary-inline-style.html22
-rw-r--r--layout/reftests/details-summary/open-summary-table-cell-style-ref.html14
-rw-r--r--layout/reftests/details-summary/open-summary-table-cell-style.html21
-rw-r--r--layout/reftests/details-summary/overflow-scroll-details-ref.html31
-rw-r--r--layout/reftests/details-summary/overflow-scroll-details.html42
-rw-r--r--layout/reftests/details-summary/reftest.list12
-rw-r--r--layout/style/nsTransitionManager.cpp4
-rw-r--r--modules/libpref/init/all.js3
47 files changed, 649 insertions, 76 deletions
diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h
index b0a251f37..8b6c4635e 100644
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -310,6 +310,18 @@ public:
GetBindingParent();
}
+ bool IsGeneratedContentContainerForBefore() const
+ {
+ return IsRootOfNativeAnonymousSubtree() &&
+ mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore;
+ }
+
+ bool IsGeneratedContentContainerForAfter() const
+ {
+ return IsRootOfNativeAnonymousSubtree() &&
+ mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentafter;
+ }
+
/**
* Set attribute values. All attribute values are assumed to have a
* canonical string representation that can be used for these
diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h
index 36e2110d8..360861503 100644
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -193,6 +193,10 @@ EVENT(dragenter,
NS_DRAGDROP_ENTER,
EventNameType_HTMLXUL,
eDragEventClass)
+EVENT(dragexit,
+ NS_DRAGDROP_EXIT_SYNTH,
+ EventNameType_HTMLXUL,
+ eDragEventClass)
EVENT(dragleave,
NS_DRAGDROP_LEAVE_SYNTH,
EventNameType_HTMLXUL,
@@ -738,10 +742,6 @@ NON_IDL_EVENT(commandupdate,
NS_XUL_COMMAND_UPDATE,
EventNameType_XUL,
eBasicEventClass)
-NON_IDL_EVENT(dragexit,
- NS_DRAGDROP_EXIT_SYNTH,
- EventNameType_XUL,
- eDragEventClass)
NON_IDL_EVENT(dragdrop,
NS_DRAGDROP_DRAGDROP,
EventNameType_XUL,
diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl
index 81160b619..b9f948595 100644
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -253,10 +253,15 @@ partial interface Document {
// https://w3c.github.io/page-visibility/#extensions-to-the-document-interface
partial interface Document {
+ [Pref="dom.visibilityAPI.enabled"]
readonly attribute boolean hidden;
+ [Pref="dom.visibilityAPI.enabled"]
readonly attribute boolean mozHidden;
+ [Pref="dom.visibilityAPI.enabled"]
readonly attribute VisibilityState visibilityState;
+ [Pref="dom.visibilityAPI.enabled"]
readonly attribute VisibilityState mozVisibilityState;
+ [Pref="dom.visibilityAPI.enabled"]
attribute EventHandler onvisibilitychange;
};
diff --git a/dom/webidl/EventHandler.webidl b/dom/webidl/EventHandler.webidl
index 29252ebc6..a2217459b 100644
--- a/dom/webidl/EventHandler.webidl
+++ b/dom/webidl/EventHandler.webidl
@@ -45,7 +45,7 @@ interface GlobalEventHandlers {
attribute EventHandler ondrag;
attribute EventHandler ondragend;
attribute EventHandler ondragenter;
- //(Not implemented)attribute EventHandler ondragexit;
+ attribute EventHandler ondragexit;
attribute EventHandler ondragleave;
attribute EventHandler ondragover;
attribute EventHandler ondragstart;
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index ab58bc165..f799b8d03 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -7105,6 +7105,7 @@ frontend::EmitTree(ExclusiveContext* cx, BytecodeEmitter* bce, ParseNode* pn)
case PNK_MULASSIGN:
case PNK_DIVASSIGN:
case PNK_MODASSIGN:
+ case PNK_POWASSIGN:
if (!EmitAssignment(cx, bce, pn->pn_left, pn->getOp(), pn->pn_right))
return false;
break;
@@ -7154,6 +7155,20 @@ frontend::EmitTree(ExclusiveContext* cx, BytecodeEmitter* bce, ParseNode* pn)
break;
}
+ case PNK_POW: {
+ MOZ_ASSERT(pn->isArity(PN_LIST));
+ /* Right-associative operator chain. */
+ for (ParseNode* subexpr = pn->pn_head; subexpr; subexpr = subexpr->pn_next) {
+ if (!EmitTree(cx, bce, subexpr))
+ return false;
+ }
+ for (int i = 0; i < pn->pn_count - 1; i++) {
+ if (!Emit1(cx, bce, JSOP_POW))
+ return false;
+ }
+ break;
+ }
+
case PNK_THROW:
case PNK_TYPEOF:
case PNK_VOID:
diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp
index 956a55a81..2eaf119e8 100644
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -363,6 +363,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_STAR:
case PNK_DIV:
case PNK_MOD:
+ case PNK_POW:
case PNK_ASSIGN:
case PNK_ADDASSIGN:
case PNK_SUBASSIGN:
@@ -375,6 +376,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_MULASSIGN:
case PNK_DIVASSIGN:
case PNK_MODASSIGN:
+ case PNK_POWASSIGN:
case PNK_COMMA:
case PNK_ARRAY:
case PNK_OBJECT:
@@ -523,6 +525,10 @@ FoldBinaryNumeric(ExclusiveContext* cx, JSOp op, ParseNode* pn1, ParseNode* pn2,
d = js_fmod(d, d2);
}
break;
+
+ case JSOP_POW:
+ d = ecmaPow(d, d2);
+ break;
default:;
}
@@ -1001,6 +1007,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp,
case PNK_URSH:
case PNK_DIV:
case PNK_MOD:
+ case PNK_POW:
MOZ_ASSERT(pn->getArity() == PN_LIST);
MOZ_ASSERT(pn->pn_count >= 2);
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
@@ -1012,6 +1019,13 @@ Fold(ExclusiveContext* cx, ParseNode** pnp,
if (!pn2->isKind(PNK_NUMBER))
break;
}
+
+ // No constant-folding for (a**b**c[**d][...]), because
+ // (**) is right-associative and we would have to reverse
+ // the list first. It's not worth doing that.
+ if (pn->getKind() == PNK_POW && pn->pn_count > 2)
+ break;
+
if (!pn2) {
JSOp op = pn->getOp();
diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp
index 679788de9..fb2ee74d9 100644
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -257,6 +257,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_MULASSIGN:
case PNK_DIVASSIGN:
case PNK_MODASSIGN:
+ case PNK_POWASSIGN:
// ...and a few others.
case PNK_ELEM:
case PNK_IMPORT_SPEC:
@@ -442,6 +443,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_STAR:
case PNK_DIV:
case PNK_MOD:
+ case PNK_POW:
case PNK_COMMA:
case PNK_NEW:
case PNK_CALL:
@@ -575,7 +577,18 @@ ParseNode::appendOrCreateList(ParseNodeKind kind, JSOp op, ParseNode* left, Pars
// processing such a tree, exactly implemented that way, would blow the
// the stack. We use a list node that uses O(1) stack to represent
// such operations: (+ a b c).
- if (left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC)) {
+ //
+ // (**) is right-associative; per spec |a ** b ** c| parses as
+ // (** a (** b c)). But we treat this the same way, creating a list
+ // node: (** a b c). All consumers must understand that this must be
+ // processed with a right fold, whereas the list (+ a b c) must be
+ // processed with a left fold because (+) is left-associative.
+ //
+ if (left->isKind(kind) &&
+ left->isOp(op) &&
+ (js_CodeSpec[op].format & JOF_LEFTASSOC ||
+ (kind == PNK_POW && !left->pn_parens)))
+ {
ListNode* list = &left->as<ListNode>();
list->append(right);
diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h
index a856945e5..df682e342 100644
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -183,6 +183,7 @@ class UpvarCookie
F(STAR) \
F(DIV) \
F(MOD) \
+ F(POW) \
\
/* Assignment operators (= += -= etc.). */ \
/* ParseNode::isAssignment assumes all these are consecutive. */ \
@@ -197,7 +198,8 @@ class UpvarCookie
F(URSHASSIGN) \
F(MULASSIGN) \
F(DIVASSIGN) \
- F(MODASSIGN)
+ F(MODASSIGN) \
+ F(POWASSIGN)
/*
* Parsing builds a tree of nodes that directs code generation. This tree is
@@ -216,9 +218,9 @@ enum ParseNodeKind
#undef EMIT_ENUM
PNK_LIMIT, /* domain size */
PNK_BINOP_FIRST = PNK_OR,
- PNK_BINOP_LAST = PNK_MOD,
+ PNK_BINOP_LAST = PNK_POW,
PNK_ASSIGNMENT_START = PNK_ASSIGN,
- PNK_ASSIGNMENT_LAST = PNK_MODASSIGN
+ PNK_ASSIGNMENT_LAST = PNK_POWASSIGN
};
/*
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 370a58ea5..6753da52c 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -5871,7 +5871,8 @@ static const JSOp ParseNodeKindToJSOp[] = {
JSOP_SUB,
JSOP_MUL,
JSOP_DIV,
- JSOP_MOD
+ JSOP_MOD,
+ JSOP_POW
};
static inline JSOp
@@ -5918,7 +5919,8 @@ static const int PrecedenceTable[] = {
9, /* PNK_SUB */
10, /* PNK_STAR */
10, /* PNK_DIV */
- 10 /* PNK_MOD */
+ 10, /* PNK_MOD */
+ 11 /* PNK_POW */
};
static const int PRECEDENCE_CLASSES = 10;
@@ -5940,8 +5942,8 @@ template <typename ParseHandler>
MOZ_ALWAYS_INLINE typename ParseHandler::Node
Parser<ParseHandler>::orExpr1(InvokedPrediction invoked)
{
- // Shift-reduce parser for the left-associative binary operator part of
- // the JS syntax.
+ // Shift-reduce parser for the binary operator part of the JS expression
+ // syntax.
// Conceptually there's just one stack, a stack of pairs (lhs, op).
// It's implemented using two separate arrays, though.
@@ -5975,10 +5977,9 @@ Parser<ParseHandler>::orExpr1(InvokedPrediction invoked)
// stack, reduce. This combines nodes on the stack until we form the
// actual lhs of pnk.
//
- // The >= in this condition works because all the operators in question
- // are left-associative; if any were not, the case where two operators
- // have equal precedence would need to be handled specially, and the
- // stack would need to be a Vector.
+ // The >= in this condition works because it is appendOrCreateList's
+ // job to decide if the operator in question is left- or
+ // right-associative, and build the corresponding tree.
while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
depth--;
ParseNodeKind combiningPnk = kindStack[depth];
@@ -6176,6 +6177,7 @@ Parser<ParseHandler>::assignExpr(InvokedPrediction invoked)
case TOK_MULASSIGN: kind = PNK_MULASSIGN; op = JSOP_MUL; break;
case TOK_DIVASSIGN: kind = PNK_DIVASSIGN; op = JSOP_DIV; break;
case TOK_MODASSIGN: kind = PNK_MODASSIGN; op = JSOP_MOD; break;
+ case TOK_POWASSIGN: kind = PNK_POWASSIGN; op = JSOP_POW; break;
case TOK_ARROW: {
tokenStream.seek(start);
diff --git a/js/src/frontend/TokenKind.h b/js/src/frontend/TokenKind.h
index cf5d67a2e..d4137567c 100644
--- a/js/src/frontend/TokenKind.h
+++ b/js/src/frontend/TokenKind.h
@@ -119,7 +119,7 @@
* range-testing. \
*/ \
/* \
- * Binary operators tokens, TOK_OR thru TOK_MOD. These must be in the same \
+ * Binary operators tokens, TOK_OR thru TOK_POW. These must be in the same \
* order as F(OR) and friends in FOR_EACH_PARSE_NODE_KIND in ParseNode.h. \
*/ \
macro(OR, "'||'") /* logical or */ \
@@ -160,7 +160,8 @@
macro(MUL, "'*'") \
macro(DIV, "'/'") \
macro(MOD, "'%'") \
- range(BINOP_LAST, MOD) \
+ macro(POW, "'**'") \
+ range(BINOP_LAST, POW) \
\
/* Unary operation tokens. */ \
macro(TYPEOF, "keyword 'typeof'") \
@@ -184,7 +185,8 @@
macro(MULASSIGN, "'*='") \
macro(DIVASSIGN, "'/='") \
macro(MODASSIGN, "'%='") \
- range(ASSIGNMENT_LAST, MODASSIGN)
+ macro(POWASSIGN, "'*='") \
+ range(ASSIGNMENT_LAST, POWASSIGN)
#define TOKEN_KIND_RANGE_EMIT_NONE(name, value)
#define FOR_EACH_TOKEN_KIND(macro) \
diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp
index a2360f51c..1e73d16a4 100644
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1499,7 +1499,10 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
goto out;
case '*':
- tp->type = matchChar('=') ? TOK_MULASSIGN : TOK_MUL;
+ if (matchChar('*'))
+ tp->type = matchChar('=') ? TOK_POWASSIGN : TOK_POW;
+ else
+ tp->type = matchChar('=') ? TOK_MULASSIGN : TOK_MUL;
goto out;
case '/':
diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp
index cd17fdb0e..f5f06ead3 100644
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1578,6 +1578,12 @@ BaselineCompiler::emit_JSOP_MOD()
}
bool
+BaselineCompiler::emit_JSOP_POW()
+{
+ return emitBinaryArith();
+}
+
+bool
BaselineCompiler::emitBinaryArith()
{
// Keep top JSStack value in R0 and R2
diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h
index 2dba2ef86..a4b73fa44 100644
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -78,6 +78,7 @@ namespace jit {
_(JSOP_MUL) \
_(JSOP_DIV) \
_(JSOP_MOD) \
+ _(JSOP_POW) \
_(JSOP_LT) \
_(JSOP_LE) \
_(JSOP_GT) \
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 280cea386..fc82c963e 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -2459,6 +2459,10 @@ DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame, ICBinaryArith_Fallbac
if (!ModValues(cx, &lhsCopy, &rhsCopy, ret))
return false;
break;
+ case JSOP_POW:
+ if (!math_pow_handle(cx, lhsCopy, rhsCopy, ret))
+ return false;
+ break;
case JSOP_BITOR: {
int32_t result;
if (!BitOr(cx, lhs, rhs, &result))
@@ -2559,7 +2563,7 @@ DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame, ICBinaryArith_Fallbac
}
// Handle only int32 or double.
- if (!lhs.isNumber() || !rhs.isNumber()) {
+ if (!lhs.isNumber() || !rhs.isNumber() && op != JSOP_POW) {
stub->noteUnoptimizableOperands();
return true;
}
@@ -2812,6 +2816,7 @@ ICBinaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm)
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, NumberMod), MoveOp::DOUBLE);
MOZ_ASSERT(ReturnDoubleReg == FloatReg0);
break;
+ // ???
default:
MOZ_CRASH("Unexpected op");
}
diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp
index 58887a9b3..1968597bf 100644
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -41,6 +41,7 @@ char const * const js::aopNames[] = {
"*=", /* AOP_STAR */
"/=", /* AOP_DIV */
"%=", /* AOP_MOD */
+ "**=", /* AOP_POW */
"<<=", /* AOP_LSH */
">>=", /* AOP_RSH */
">>>=", /* AOP_URSH */
@@ -66,6 +67,7 @@ char const * const js::binopNames[] = {
"*", /* BINOP_STAR */
"/", /* BINOP_DIV */
"%", /* BINOP_MOD */
+ "**", /* BINOP_POW */
"|", /* BINOP_BITOR */
"^", /* BINOP_BITXOR */
"&", /* BINOP_BITAND */
@@ -1719,6 +1721,7 @@ class ASTSerializer
bool statements(ParseNode* pn, NodeVector& elts);
bool expressions(ParseNode* pn, NodeVector& elts);
bool leftAssociate(ParseNode* pn, MutableHandleValue dst);
+ bool rightAssociate(ParseNode* pn, MutableHandleValue dst);
bool functionArgs(ParseNode* pn, ParseNode* pnargs, ParseNode* pndestruct, ParseNode* pnbody,
NodeVector& args, NodeVector& defaults, MutableHandleValue rest);
@@ -1832,6 +1835,8 @@ ASTSerializer::aop(JSOp op)
return AOP_DIV;
case JSOP_MOD:
return AOP_MOD;
+ case JSOP_POW:
+ return AOP_POW;
case JSOP_LSH:
return AOP_LSH;
case JSOP_RSH:
@@ -1910,6 +1915,8 @@ ASTSerializer::binop(ParseNodeKind kind, JSOp op)
return BINOP_DIV;
case PNK_MOD:
return BINOP_MOD;
+ case PNK_POW:
+ return BINOP_POW;
case PNK_BITOR:
return BINOP_BITOR;
case PNK_BITXOR:
@@ -2588,6 +2595,50 @@ ASTSerializer::leftAssociate(ParseNode* pn, MutableHandleValue dst)
}
bool
+ASTSerializer::rightAssociate(ParseNode* pn, MutableHandleValue dst)
+{
+ MOZ_ASSERT(pn->isArity(PN_LIST));
+ MOZ_ASSERT(pn->pn_count >= 1);
+
+ // First, we need to reverse the list, so that we can traverse it in the correct order.
+ // It's OK to destructively reverse the list, because there are no other consumers.
+
+ ParseNode* head = pn->pn_head;
+ ParseNode* prev = nullptr;
+ ParseNode* current = head;
+ ParseNode* next;
+ while (current != nullptr)
+ {
+ next = current->pn_next;
+ current->pn_next = prev;
+ prev = current;
+ current = next;
+ }
+
+ head = prev;
+
+ RootedValue right(cx);
+ if (!expression(head, &right))
+ return false;
+ for (ParseNode* next = head->pn_next; next; next = next->pn_next) {
+ RootedValue left(cx);
+ if (!expression(next, &left))
+ return false;
+
+ TokenPos subpos(pn->pn_pos.begin, next->pn_pos.end);
+
+ BinaryOperator op = binop(pn->getKind(), pn->getOp());
+ LOCAL_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT);
+
+ if (!builder.binaryExpression(op, left, right, &subpos, &right))
+ return false;
+ }
+
+ dst.set(right);
+ return true;
+}
+
+bool
ASTSerializer::comprehensionBlock(ParseNode* pn, MutableHandleValue dst)
{
LOCAL_ASSERT(pn->isArity(PN_BINARY));
@@ -2775,6 +2826,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_MULASSIGN:
case PNK_DIVASSIGN:
case PNK_MODASSIGN:
+ case PNK_POWASSIGN:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
@@ -2811,6 +2863,9 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_INSTANCEOF:
return leftAssociate(pn, dst);
+ case PNK_POW:
+ return rightAssociate(pn, dst);
+
case PNK_DELETE:
case PNK_TYPEOF:
case PNK_VOID:
diff --git a/js/src/jsreflect.h b/js/src/jsreflect.h
index a592bfe0c..e87001da1 100644
--- a/js/src/jsreflect.h
+++ b/js/src/jsreflect.h
@@ -26,7 +26,7 @@ enum AssignmentOperator {
/* assign */
AOP_ASSIGN = 0,
/* operator-assign */
- AOP_PLUS, AOP_MINUS, AOP_STAR, AOP_DIV, AOP_MOD,
+ AOP_PLUS, AOP_MINUS, AOP_STAR, AOP_DIV, AOP_MOD, AOP_POW,
/* shift-assign */
AOP_LSH, AOP_RSH, AOP_URSH,
/* binary */
@@ -45,7 +45,7 @@ enum BinaryOperator {
/* shift */
BINOP_LSH, BINOP_RSH, BINOP_URSH,
/* arithmetic */
- BINOP_ADD, BINOP_SUB, BINOP_STAR, BINOP_DIV, BINOP_MOD,
+ BINOP_ADD, BINOP_SUB, BINOP_STAR, BINOP_DIV, BINOP_MOD, BINOP_POW,
/* binary */
BINOP_BITOR, BINOP_BITXOR, BINOP_BITAND,
/* misc */
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index 35a3d171d..bf52d3db7 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1665,7 +1665,6 @@ CASE(JSOP_UNUSED146)
CASE(JSOP_UNUSED147)
CASE(JSOP_UNUSED148)
CASE(JSOP_BACKPATCH)
-CASE(JSOP_UNUSED150)
CASE(JSOP_UNUSED157)
CASE(JSOP_UNUSED158)
CASE(JSOP_UNUSED159)
@@ -2276,6 +2275,18 @@ CASE(JSOP_MOD)
}
END_CASE(JSOP_MOD)
+CASE(JSOP_POW)
+{
+ RootedValue& lval = rootValue0, &rval = rootValue1;
+ lval = REGS.sp[-2];
+ rval = REGS.sp[-1];
+ MutableHandleValue res = REGS.stackHandleAt(-2);
+ if (!math_pow_handle(cx, lval, rval, res))
+ goto error;
+ REGS.sp--;
+}
+END_CASE(JSOP_POW)
+
CASE(JSOP_NOT)
{
bool cond = ToBoolean(REGS.stackHandleAt(-1));
diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h
index f5a95a337..528f4e779 100644
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -1421,7 +1421,15 @@
* Stack: =>
*/ \
macro(JSOP_BACKPATCH, 149,"backpatch", NULL, 5, 0, 0, JOF_JUMP) \
- macro(JSOP_UNUSED150, 150,"unused150", NULL, 1, 0, 0, JOF_BYTE) \
+ /*
+ * Pops the top two values 'lval' and 'rval' from the stack, then pushes
+ * the result of 'Math.pow(lval, rval)'.
+ * Category: Operators
+ * Type: Arithmetic Operators
+ * Operands:
+ * Stack: lval, rval => (lval ** rval)
+ */ \
+ macro(JSOP_POW, 150, "pow", "**", 1, 2, 1, JOF_BYTE|JOF_ARITH) \
\
/*
* Pops the top of stack value as 'v', sets pending exception as 'v',
diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h
index d0dd54f40..13c3431b2 100644
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -29,7 +29,7 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 249;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 250;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
diff --git a/layout/base/crashtests/1297835.html b/layout/base/crashtests/1297835.html
new file mode 100644
index 000000000..47c9e3ea4
--- /dev/null
+++ b/layout/base/crashtests/1297835.html
@@ -0,0 +1,6 @@
+<body onload="document.documentElement.offsetWidth; document.querySelector('details').style.color = 'green'">
+ <details style="display: block; overflow: scroll;">
+ <summary>Some summary</summary>
+ The details
+ </details>
+</body>
diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list
index 7588c3ed7..73d880baa 100644
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -458,3 +458,4 @@ load 1061028.html
load 1116104.html
load 1107508-1.html
load 1127198-1.html
+load 1297835.html
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index 3dd6c215f..6577bb42c 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3510,13 +3510,6 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement,
return nullptr;
}
- if (aTag == nsGkAtoms::summary &&
- (!aParentFrame || aParentFrame->GetType() != nsGkAtoms::detailsFrame)) {
- // <summary> is special only if it is a direct child of <details>. If it
- // isn't, construct it as a normal block frame instead of a summary frame.
- return nullptr;
- }
-
static const FrameConstructionDataByTag sHTMLData[] = {
SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData),
SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
@@ -5601,9 +5594,15 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
}
// When constructing a child of a non-open <details>, create only the frame
- // for the main <summary> element, and skip other elements.
+ // for the main <summary> element, and skip other elements. This only applies
+ // to things that are not roots of native anonymous subtrees (except for
+ // ::before and ::after); we always want to create "internal" anonymous
+ // content.
auto* details = HTMLDetailsElement::FromContentOrNull(parent);
- if (details && !details->Open()) {
+ if (details && !details->Open() &&
+ (!aContent->IsRootOfNativeAnonymousSubtree() ||
+ aContent->IsGeneratedContentContainerForBefore() ||
+ aContent->IsGeneratedContentContainerForAfter())) {
auto* summary = HTMLSummaryElement::FromContentOrNull(aContent);
if (!summary || !summary->IsMainSummary()) {
SetAsUndisplayedContent(aState, aItems, aContent, styleContext,
@@ -5765,10 +5764,23 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
return;
}
- FrameConstructionItem* item =
- aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
- pendingBinding, styleContext.forget(),
- aSuppressWhiteSpaceOptimizations, aAnonChildren);
+ FrameConstructionItem* item = nullptr;
+ if (details && details->Open()) {
+ auto* summary = HTMLSummaryElement::FromContentOrNull(aContent);
+ if (summary && summary->IsMainSummary()) {
+ // If details is open, the main summary needs to be rendered as if it is
+ // the first child, so add the item to the front of the item list.
+ item = aItems.PrependItem(data, aContent, aTag, aNameSpaceID,
+ pendingBinding, styleContext.forget(),
+ aSuppressWhiteSpaceOptimizations, aAnonChildren);
+ }
+ }
+
+ if (!item) {
+ item = aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
+ pendingBinding, styleContext.forget(),
+ aSuppressWhiteSpaceOptimizations, aAnonChildren);
+ }
item->mIsText = isText;
item->mIsGeneratedContent = isGeneratedContent;
item->mIsAnonymousContentCreatorContent =
diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h
index df6f9c020..cf306df71 100644
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -853,6 +853,27 @@ private:
return item;
}
+ // Arguments are the same as AppendItem().
+ FrameConstructionItem* PrependItem(const FrameConstructionData* aFCData,
+ nsIContent* aContent,
+ nsIAtom* aTag,
+ int32_t aNameSpaceID,
+ PendingBinding* aPendingBinding,
+ already_AddRefed<nsStyleContext>&& aStyleContext,
+ bool aSuppressWhiteSpaceOptimizations,
+ nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren)
+ {
+ FrameConstructionItem* item =
+ new FrameConstructionItem(aFCData, aContent, aTag, aNameSpaceID,
+ aPendingBinding, aStyleContext,
+ aSuppressWhiteSpaceOptimizations,
+ aAnonChildren);
+ PR_INSERT_LINK(item, &mItems);
+ ++mItemCount;
+ ++mDesiredParentCounts[item->DesiredParentType()];
+ return item;
+ }
+
void AppendUndisplayedItem(nsIContent* aContent,
nsStyleContext* aStyleContext) {
mUndisplayedItems.AppendElement(UndisplayedItem(aContent, aStyleContext));
diff --git a/layout/generic/DetailsFrame.cpp b/layout/generic/DetailsFrame.cpp
index 8a761e1a3..4184d0078 100644
--- a/layout/generic/DetailsFrame.cpp
+++ b/layout/generic/DetailsFrame.cpp
@@ -46,48 +46,43 @@ DetailsFrame::GetType() const
void
DetailsFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList)
{
+#ifdef DEBUG
if (aListID == kPrincipalList) {
- HTMLDetailsElement* details = HTMLDetailsElement::FromContent(GetContent());
- bool isOpen = details->Open();
-
- if (isOpen) {
- // If details is open, the first summary needs to be rendered as if it is
- // the first child.
- for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
- HTMLSummaryElement* summary =
- HTMLSummaryElement::FromContent(e.get()->GetContent());
-
- if (summary && summary->IsMainSummary()) {
- // Take out the first summary frame and insert it to the beginning of
- // the list.
- aChildList.RemoveFrame(e.get());
- aChildList.InsertFrame(nullptr, nullptr, e.get());
- break;
- }
- }
- }
+ CheckValidMainSummary(aChildList);
+ }
+#endif
-#ifdef DEBUG
- for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
- HTMLSummaryElement* summary =
- HTMLSummaryElement::FromContent(e.get()->GetContent());
+ nsBlockFrame::SetInitialChildList(aListID, aChildList);
+}
- if (e.get() == aChildList.FirstChild()) {
- if (summary && summary->IsMainSummary()) {
- break;
+#ifdef DEBUG
+bool
+DetailsFrame::CheckValidMainSummary(const nsFrameList& aFrameList) const
+{
+ for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
+ HTMLSummaryElement* summary =
+ HTMLSummaryElement::FromContent(e.get()->GetContent());
+
+ if (e.get() == aFrameList.FirstChild()) {
+ if (summary && summary->IsMainSummary()) {
+ return true;
+ } else if (e.get()->GetContent() == GetContent()) {
+ // The child frame's content is the same as our content, which means
+ // it's a kind of wrapper frame. Descend into its child list to find
+ // main summary.
+ if (CheckValidMainSummary(e.get()->PrincipalChildList())) {
+ return true;
}
- } else {
- MOZ_ASSERT(!summary || !summary->IsMainSummary(),
- "Rest of the children are neither summary elements nor"
- "the main summary!");
}
+ } else {
+ NS_ASSERTION(!summary || !summary->IsMainSummary(),
+ "Rest of the children are either not summary element "
+ "or are not the main summary!");
}
-#endif
-
}
-
- nsBlockFrame::SetInitialChildList(aListID, aChildList);
+ return false;
}
+#endif
void
DetailsFrame::DestroyFrom(nsIFrame* aDestructRoot)
diff --git a/layout/generic/DetailsFrame.h b/layout/generic/DetailsFrame.h
index 2a9a517f7..1eb4ea87b 100644
--- a/layout/generic/DetailsFrame.h
+++ b/layout/generic/DetailsFrame.h
@@ -38,6 +38,12 @@ public:
}
#endif
+#ifdef DEBUG
+ // Check the frame of the main summary element is the first child in the frame
+ // list. Returns true if we found the main summary frame; false otherwise.
+ bool CheckValidMainSummary(const nsFrameList& aFrameList) const;
+#endif
+
void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) override;
diff --git a/layout/generic/crashtests/1304441.html b/layout/generic/crashtests/1304441.html
new file mode 100644
index 000000000..26d7dcdd6
--- /dev/null
+++ b/layout/generic/crashtests/1304441.html
@@ -0,0 +1,9 @@
+<details>
+<summary>
+<li>
+<style>
+summary{
+all:initial
+}
+:first-child::first-line
+{}
diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list
index 02f85e0b4..519a374a8 100644
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -580,3 +580,4 @@ load 1222783.xhtml
load details-display-none-summary-1.html
load details-display-none-summary-2.html
load details-display-none-summary-3.html
+load 1304441.html
diff --git a/layout/reftests/details-summary/details-after.html b/layout/reftests/details-summary/details-after.html
new file mode 100644
index 000000000..6746919d7
--- /dev/null
+++ b/layout/reftests/details-summary/details-after.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+ <style>
+ details::after {
+ content: "This is the details.";
+ /* Match the margins and display of <p> */
+ display: block;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ }
+ </style>
+</head>
+<html>
+ <body>
+ <details>
+ <summary>Summary</summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/details-before.html b/layout/reftests/details-summary/details-before.html
new file mode 100644
index 000000000..103908919
--- /dev/null
+++ b/layout/reftests/details-summary/details-before.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+ <style>
+ details::before {
+ content: "This is the details.";
+ /* Match the margins and display of <p> */
+ display: block;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ }
+ </style>
+</head>
+<html>
+ <body>
+ <details>
+ <summary>Summary</summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/details-first-line-ref.html b/layout/reftests/details-summary/details-first-line-ref.html
new file mode 100644
index 000000000..0e76b97f2
--- /dev/null
+++ b/layout/reftests/details-summary/details-first-line-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ div#details::first-line {
+ color: blue;
+ }
+ </style>
+ <body>
+ <div id="details">
+ <span>Summary
+ <div>Block in summary</div>
+ </span>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/details-first-line.html b/layout/reftests/details-summary/details-first-line.html
new file mode 100644
index 000000000..4ad2d9af5
--- /dev/null
+++ b/layout/reftests/details-summary/details-first-line.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ summary {
+ display: inline; /* ::first-line appiles only to inline element. */
+ }
+
+ details::first-line {
+ color: blue;
+ }
+ </style>
+ <body>
+ <details>
+ <summary>Summary
+ <!-- Need ib-split so that the summary has multiple frames. -->
+ <div>Block in summary</div>
+ </summary>
+ <p>This is the details.</p>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/details-in-ol-ref.html b/layout/reftests/details-summary/details-in-ol-ref.html
index e6d2c3ab5..1aaa67b5c 100644
--- a/layout/reftests/details-summary/details-in-ol-ref.html
+++ b/layout/reftests/details-summary/details-in-ol-ref.html
@@ -18,6 +18,14 @@
<li>Second item in summary</li>
</ol>
</div>
+ <svg>
+ <foreignObject width="300" height="300">
+ <ol>
+ <li>First item in foreignObject</li>
+ <li>Second item in foreignObject</li>
+ </ol>
+ </foreignObject>
+ </svg>
</summary>
<p>This is the details.</p>
<li>First item in details</li>
diff --git a/layout/reftests/details-summary/details-in-ol.html b/layout/reftests/details-summary/details-in-ol.html
index d5417936e..974c42776 100644
--- a/layout/reftests/details-summary/details-in-ol.html
+++ b/layout/reftests/details-summary/details-in-ol.html
@@ -25,6 +25,14 @@
<li>Second item in summary</li>
</ol>
</div>
+ <svg>
+ <foreignObject width="300" height="300">
+ <ol>
+ <li>First item in foreignObject</li>
+ <li>Second item in foreignObject</li>
+ </ol>
+ </foreignObject>
+ </svg>
</summary>
<p>This is the details.</p>
<!-- Although html spec does not allow <li> inside <details>, we
diff --git a/layout/reftests/details-summary/open-details-after.html b/layout/reftests/details-summary/open-details-after.html
new file mode 100644
index 000000000..1c5d8b725
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-after.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+ <style>
+ details::after {
+ content: "This is the details.";
+ /* Match the margins and display of <p> */
+ display: block;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ }
+ </style>
+</head>
+<html>
+ <body>
+ <details open>
+ <summary>Summary</summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-details-before.html b/layout/reftests/details-summary/open-details-before.html
new file mode 100644
index 000000000..a35a58111
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-before.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+ <style>
+ details::before {
+ content: "This is the details.";
+ /* Match the margins and display of <p> */
+ display: block;
+ margin-block-start: 1em;
+ margin-block-end: 1em;
+ }
+ </style>
+</head>
+<html>
+ <body>
+ <details open>
+ <summary>Summary</summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-details-first-line-1.html b/layout/reftests/details-summary/open-details-first-line-1.html
new file mode 100644
index 000000000..a579d0342
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-first-line-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ summary {
+ display: inline; /* ::first-line appiles only to inline element. */
+ }
+
+ details::first-line {
+ color: blue;
+ }
+ </style>
+ <body>
+ <details open>
+ <summary>Summary
+ <!-- Need ib-split so that the summary has multiple frames. -->
+ <div>Block in summary</div>
+ </summary>
+ <span>This is the details.</span>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-details-first-line-2.html b/layout/reftests/details-summary/open-details-first-line-2.html
new file mode 100644
index 000000000..93af8f462
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-first-line-2.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ summary {
+ display: inline; /* ::first-line appiles only to inline element. */
+ }
+
+ details::first-line {
+ color: blue;
+ }
+ </style>
+ <body>
+ <details open>
+ <span>This is the details.</span>
+ <summary>Summary
+ <!-- Need ib-split so that the summary has multiple frames. -->
+ <div>Block in summary</div>
+ </summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-details-first-line-ref.html b/layout/reftests/details-summary/open-details-first-line-ref.html
new file mode 100644
index 000000000..d975ecfc7
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-first-line-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ div#details::first-line {
+ color: blue;
+ }
+ </style>
+ <body>
+ <div id="details">
+ <span>Summary
+ <div>Block in summary</div>
+ </span>
+ <span>This is the details.</span>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-summary-inline-style-ref.html b/layout/reftests/details-summary/open-summary-inline-style-ref.html
new file mode 100644
index 000000000..f0be2f66d
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-inline-style-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <body>
+ <div>
+ <span>Summary
+ <div>Block in summary</div>
+ </span>
+ <p>This is the details.</p>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-summary-inline-style.html b/layout/reftests/details-summary/open-summary-inline-style.html
new file mode 100644
index 000000000..1c28d62fe
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-inline-style.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ summary {
+ display: inline;
+ }
+ </style>
+ <body>
+ <details open>
+ <p>This is the details.</p>
+ <!-- Make summary the second element child so that layout will try to
+ render it as the first child. -->
+ <summary>Summary
+ <!-- Need ib-split so that the summary has multiple frames. -->
+ <div>Block in summary</div>
+ </summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-summary-table-cell-style-ref.html b/layout/reftests/details-summary/open-summary-table-cell-style-ref.html
new file mode 100644
index 000000000..634bfec1d
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-table-cell-style-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <body>
+ <div>
+ <span style="display: table-cell;">Summary
+ <div>Block in summary</div>
+ </span>
+ <p>This is the details.</p>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/open-summary-table-cell-style.html b/layout/reftests/details-summary/open-summary-table-cell-style.html
new file mode 100644
index 000000000..9b6ef4034
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-table-cell-style.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ summary {
+ display: table-cell;
+ }
+ </style>
+ <body>
+ <details open>
+ <p>This is the details.</p>
+ <!-- Make summary the second element child so that layout will try to
+ render it as the first child. -->
+ <summary>Summary
+ <div>Block in summary</div>
+ </summary>
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/overflow-scroll-details-ref.html b/layout/reftests/details-summary/overflow-scroll-details-ref.html
new file mode 100644
index 000000000..b85a242c9
--- /dev/null
+++ b/layout/reftests/details-summary/overflow-scroll-details-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ div#details {
+ background-color: orange;
+ overflow: scroll;
+ width: 300px;
+ height: 200px;
+ }
+ div#summary {
+ background-color: green;
+ width: 200px;
+ height: 100px;
+ }
+ </style>
+ <body>
+ <div id="details">
+ <div id="summary">Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+ sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
+ in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
+ officia deserunt mollit anim id est laborum.
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/overflow-scroll-details.html b/layout/reftests/details-summary/overflow-scroll-details.html
new file mode 100644
index 000000000..62ef22f4a
--- /dev/null
+++ b/layout/reftests/details-summary/overflow-scroll-details.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <style>
+ details {
+ background-color: orange;
+ overflow: scroll;
+ width: 300px;
+ height: 200px;
+ }
+ summary::-moz-list-bullet {
+ /* Hide the triangle for comparing with div in reftest. */
+ list-style-type: none;
+ }
+ summary {
+ background-color: green;
+ width: 200px;
+ height: 100px;
+ }
+ </style>
+ <body>
+ <details>
+ <summary>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
+ ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
+ voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
+ mollit anim id est laborum.
+ </summary>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
+ velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
+ cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+ est laborum.
+ </details>
+ </body>
+</html>
diff --git a/layout/reftests/details-summary/reftest.list b/layout/reftests/details-summary/reftest.list
index e8616ba41..fbbc822c6 100644
--- a/layout/reftests/details-summary/reftest.list
+++ b/layout/reftests/details-summary/reftest.list
@@ -4,6 +4,8 @@
== summary-not-first-child.html single-summary.html
== open-summary-not-first-child.html open-single-summary.html
== open-summary-block-style.html open-summary-block-style-ref.html
+== open-summary-inline-style.html open-summary-inline-style-ref.html
+== open-summary-table-cell-style.html open-summary-table-cell-style-ref.html
== no-summary.html no-summary-ref.html
== open-no-summary.html open-no-summary-ref.html
== summary-not-in-details.html summary-not-in-details-ref.html
@@ -35,6 +37,7 @@
# With 'overflow' property
== overflow-hidden-open-details.html overflow-hidden-open-details-ref.html
== overflow-auto-open-details.html overflow-auto-open-details-ref.html
+== overflow-scroll-details.html overflow-scroll-details-ref.html
# With pagination property
== details-page-break-after-1.html details-two-pages.html
@@ -61,6 +64,9 @@
== details-three-columns.html details-three-columns-ref.html
== details-writing-mode.html details-writing-mode-ref.html
== details-in-ol.html details-in-ol-ref.html
+== details-first-line.html details-first-line-ref.html
+== open-details-first-line-1.html open-details-first-line-ref.html
+== open-details-first-line-2.html open-details-first-line-ref.html
== summary-three-columns.html summary-three-columns-ref.html
# Dispatch mouse click to summary
@@ -89,3 +95,9 @@
== key-enter-open-second-summary.html open-multiple-summary.html
== key-enter-prevent-default.html single-summary.html
== key-space-single-summary.html open-single-summary.html
+
+# Generated content bits
+== details-after.html single-summary.html
+== details-before.html single-summary.html
+== open-details-after.html open-single-summary.html
+== open-details-before.html open-single-summary.html
diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp
index f8bb1441a..c4bc32251 100644
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -162,9 +162,9 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
}
NS_ASSERTION((pseudoType == nsCSSPseudoElements::ePseudo_before &&
- aElement->Tag() == nsGkAtoms::mozgeneratedcontentbefore) ||
+ aElement->IsGeneratedContentContainerForBefore()) ||
(pseudoType == nsCSSPseudoElements::ePseudo_after &&
- aElement->Tag() == nsGkAtoms::mozgeneratedcontentafter),
+ aElement->IsGeneratedContentContainerForAfter()),
"Unexpected aElement coming through");
// Else the element we want to use from now on is the element the
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index f3c1fca6b..6551eb596 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -134,6 +134,9 @@ pref("dom.select_events.enabled", true);
// Whether or not selection events on text controls are enabled
pref("dom.select_events.textcontrols.enabled", true);
+// Whether or not the document visbility API is enabled
+pref("dom.visibilityAPI.enabled", true);
+
// Whether or not Web Workers are enabled.
pref("dom.workers.enabled", true);
// The number of workers per domain allowed to run concurrently.