summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dom/bindings/Bindings.conf4
-rw-r--r--dom/media/PeerConnection.js2
-rw-r--r--dom/media/tests/mochitest/addTurnsSelfsignedCert.js26
-rw-r--r--dom/media/tests/mochitest/mochitest.ini3
-rw-r--r--dom/media/tests/mochitest/pc.js30
-rw-r--r--dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html38
-rw-r--r--dom/media/webaudio/blink/DynamicsCompressor.h5
-rw-r--r--dom/network/PTCPSocket.ipdl3
-rw-r--r--dom/network/TCPSocketChild.cpp5
-rw-r--r--dom/network/TCPSocketChild.h2
-rw-r--r--dom/network/TCPSocketParent.cpp20
-rw-r--r--dom/network/TCPSocketParent.h1
-rw-r--r--dom/webidl/CSS.webidl10
-rw-r--r--js/src/builtin/Array.js31
-rw-r--r--js/src/builtin/String.js33
-rw-r--r--js/src/builtin/TypedArray.js39
-rw-r--r--js/src/gc/StoreBuffer.h2
-rw-r--r--js/src/jsarray.cpp3
-rw-r--r--js/src/jsstr.cpp3
-rw-r--r--js/src/vm/TypedArrayObject.cpp4
-rw-r--r--layout/generic/ReflowInput.cpp14
-rw-r--r--layout/generic/ReflowInput.h6
-rw-r--r--layout/generic/nsFlexContainerFrame.cpp269
-rw-r--r--layout/generic/nsFlexContainerFrame.h27
-rw-r--r--layout/generic/nsFrame.cpp11
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-horiz-001v.xhtml73
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-vert-001v.xhtml75
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-001v.xhtml105
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-001v.xhtml107
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001v.html128
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-002v.html128
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-003v.html128
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-004v.html128
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-005v.html129
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-006v.html129
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-002v.xhtml86
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-003v.xhtml88
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010-ref.html94
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010.html88
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011-ref.html97
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011.html89
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012-ref.html97
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012.html90
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013-ref.html98
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013.html89
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014-ref.html96
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014.html88
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015-ref.html96
-rw-r--r--layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015.html89
-rw-r--r--layout/style/CSS.cpp13
-rw-r--r--layout/style/nsCSSParser.cpp19
-rw-r--r--layout/style/nsCSSParser.h14
-rw-r--r--layout/style/test/test_css_supports.html2
-rw-r--r--media/mtransport/nr_socket_prsock.cpp34
-rw-r--r--media/mtransport/nr_socket_prsock.h3
-rw-r--r--media/mtransport/nricectx.cpp9
-rw-r--r--media/mtransport/nricectx.h1
-rw-r--r--media/mtransport/test_nr_socket.cpp55
-rw-r--r--media/mtransport/test_nr_socket.h3
-rw-r--r--media/mtransport/third_party/nICEr/src/ice/ice_candidate.c8
-rw-r--r--media/mtransport/third_party/nICEr/src/ice/ice_ctx.h1
-rw-r--r--media/mtransport/third_party/nICEr/src/net/transport_addr.h1
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp24
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h1
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp11
-rw-r--r--media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h3
-rw-r--r--modules/libpref/init/all.js4
-rw-r--r--netwerk/base/nsISocketTransport.idl5
-rw-r--r--netwerk/base/nsSocketTransport2.cpp34
-rw-r--r--netwerk/base/nsSocketTransport2.h1
-rw-r--r--netwerk/protocol/http/TunnelUtils.cpp6
-rw-r--r--testing/tools/iceserver/iceserver.py72
72 files changed, 3141 insertions, 189 deletions
diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
index 989757548a..146bf8d15b 100644
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -170,10 +170,6 @@ DOMInterfaces = {
'headerFile': 'Crypto.h'
},
-'CSS': {
- 'concrete': False,
-},
-
'CSS2Properties': {
'nativeType': 'nsDOMCSSDeclaration'
},
diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js
index d2f098b1fa..77b7a58980 100644
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -588,7 +588,7 @@ RTCPeerConnection.prototype = {
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
"SyntaxError");
}
- if (url.scheme in { stuns:1, turns:1 }) {
+ if (url.scheme in { stuns:1 }) {
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.");
}
});
diff --git a/dom/media/tests/mochitest/addTurnsSelfsignedCert.js b/dom/media/tests/mochitest/addTurnsSelfsignedCert.js
new file mode 100644
index 0000000000..cad3d04465
--- /dev/null
+++ b/dom/media/tests/mochitest/addTurnsSelfsignedCert.js
@@ -0,0 +1,26 @@
+/* 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/. */
+
+"use strict";
+
+var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+// This is only usable from the parent process, even for doing simple stuff like
+// serializing a cert.
+var gCertMaker = Cc["@mozilla.org/security/x509certdb;1"].
+ getService(Ci.nsIX509CertDB);
+
+var gCertOverrides = Cc["@mozilla.org/security/certoverride;1"].
+ getService(Ci.nsICertOverrideService);
+
+
+addMessageListener('add-turns-certs', certs => {
+ var port = 5349;
+ certs.forEach(certDescription => {
+ var cert = gCertMaker.constructX509FromBase64(certDescription.cert);
+ gCertOverrides.rememberValidityOverride(certDescription.hostname, port,
+ cert, Ci.nsICertOverrideService.ERROR_UNTRUSTED, false);
+ });
+ sendAsyncMessage('certs-added');
+});
diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini
index 22006ffa2f..948d938a30 100644
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -13,6 +13,7 @@ support-files =
blacksilence.js
turnConfig.js
sdpUtils.js
+ addTurnsSelfsignedCert.js
!/dom/canvas/test/captureStream_common.js
!/dom/canvas/test/webgl-mochitest/webgl-util.js
!/dom/media/test/manifest.js
@@ -98,6 +99,8 @@ skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
[test_peerConnection_basicAudioNATRelayTCP.html]
skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
+[test_peerConnection_basicAudioNATRelayTLS.html]
+skip-if = true # need pyopenssl on builders, see bug 1323439
[test_peerConnection_basicAudioRequireEOC.html]
skip-if = (android_version == '18' && debug) # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_basicAudioPcmaPcmuOnly.html]
diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js
index a9383358f9..2e9c7c63f1 100644
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1822,6 +1822,33 @@ function createHTML(options) {
var iceServerWebsocket;
var iceServersArray = [];
+var addTurnsSelfsignedCerts = () => {
+ var gUrl = SimpleTest.getTestFileURL('addTurnsSelfsignedCert.js');
+ var gScript = SpecialPowers.loadChromeScript(gUrl);
+ var certs = [];
+ // If the ICE server is running TURNS, and includes a "cert" attribute in
+ // its JSON, we set up an override that will forgive things like
+ // self-signed for it.
+ iceServersArray.forEach(iceServer => {
+ if (iceServer.hasOwnProperty("cert")) {
+ iceServer.urls.forEach(url => {
+ if (url.startsWith("turns:")) {
+ // Assumes no port or params!
+ certs.push({"cert": iceServer.cert, "hostname": url.substr(6)});
+ }
+ });
+ }
+ });
+
+ return new Promise((resolve, reject) => {
+ gScript.addMessageListener('certs-added', () => {
+ resolve();
+ });
+
+ gScript.sendAsyncMessage('add-turns-certs', certs);
+ });
+};
+
var setupIceServerConfig = useIceServer => {
// We disable ICE support for HTTP proxy when using a TURN server, because
// mochitest uses a fake HTTP proxy to serve content, which will eat our STUN
@@ -1863,7 +1890,8 @@ var setupIceServerConfig = useIceServer => {
return enableHttpProxy(false)
.then(spawnIceServer)
- .then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); });
+ .then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); })
+ .then(addTurnsSelfsignedCerts);
};
function runNetworkTest(testFunction, fixtureOptions) {
diff --git a/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html
new file mode 100644
index 0000000000..c295955d81
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+ createHTML({
+ bug: "1231975",
+ title: "Basic audio-only peer connection with port dependent NAT that blocks STUN"
+ });
+
+ var test;
+ runNetworkTest(options => {
+ SpecialPowers.pushPrefEnv(
+ {
+ 'set': [
+ ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
+ ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT'],
+ ['media.peerconnection.nat_simulator.block_udp', true],
+ ['media.peerconnection.nat_simulator.block_tcp', true]
+ ]
+ }, function (options) {
+ options = options || {};
+ options.expectedLocalCandidateType = "relayed-tcp";
+ options.expectedRemoteCandidateType = "relayed-tcp";
+ // No reason to wait for gathering to complete like the other NAT tests,
+ // since relayed-tcp is the only thing that can work.
+ test = new PeerConnectionTest(options);
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.run();
+ })
+ }, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/media/webaudio/blink/DynamicsCompressor.h b/dom/media/webaudio/blink/DynamicsCompressor.h
index f460836b49..24f4fc7f71 100644
--- a/dom/media/webaudio/blink/DynamicsCompressor.h
+++ b/dom/media/webaudio/blink/DynamicsCompressor.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2022 Moonchild Productions.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -104,7 +105,7 @@ protected:
float m_lastAnchor;
float m_lastFilterStageGain;
- typedef struct {
+ typedef struct ZeroPoleFilterPack4 {
ZeroPole filters[4];
size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
diff --git a/dom/network/PTCPSocket.ipdl b/dom/network/PTCPSocket.ipdl
index aa7c51e45f..ea00856029 100644
--- a/dom/network/PTCPSocket.ipdl
+++ b/dom/network/PTCPSocket.ipdl
@@ -44,7 +44,8 @@ parent:
// address specified in |localAddr| and |localPort|.
async OpenBind(nsCString host, uint16_t port,
nsCString localAddr, uint16_t localPort,
- bool useSSL, bool aUseArrayBuffers, nsCString aFilter);
+ bool useSSL, bool reuseAddrPort,
+ bool aUseArrayBuffers, nsCString aFilter);
// When child's send() is called, this message requrests parent to send
// data and update it's trackingNumber.
diff --git a/dom/network/TCPSocketChild.cpp b/dom/network/TCPSocketChild.cpp
index 9e1dce2769..b2b8db78a3 100644
--- a/dom/network/TCPSocketChild.cpp
+++ b/dom/network/TCPSocketChild.cpp
@@ -108,7 +108,7 @@ void
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
- bool aUseSSL)
+ bool aUseSSL, bool aReuseAddrPort)
{
mSocket = aSocket;
AddIPDLReference();
@@ -117,7 +117,8 @@ TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
aRemotePort);
PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
nsCString(aLocalHost), aLocalPort,
- aUseSSL, true, mFilterName);
+ aUseSSL, aReuseAddrPort,
+ true, mFilterName);
}
void
diff --git a/dom/network/TCPSocketChild.h b/dom/network/TCPSocketChild.h
index 7e9b59e8b5..46e9b0a90f 100644
--- a/dom/network/TCPSocketChild.h
+++ b/dom/network/TCPSocketChild.h
@@ -55,7 +55,7 @@ public:
void SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
- bool aUseSSL);
+ bool aUseSSL, bool aUseRealtimeOptions);
NS_IMETHOD SendSendArray(nsTArray<uint8_t>& aArray,
uint32_t aTrackingNumber);
void SendSend(const nsACString& aData, uint32_t aTrackingNumber);
diff --git a/dom/network/TCPSocketParent.cpp b/dom/network/TCPSocketParent.cpp
index 313d13f759..96eab44510 100644
--- a/dom/network/TCPSocketParent.cpp
+++ b/dom/network/TCPSocketParent.cpp
@@ -149,6 +149,7 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
+ const bool& aReuseAddrPort,
const bool& aUseArrayBuffers,
const nsCString& aFilter)
{
@@ -167,14 +168,27 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
}
nsCOMPtr<nsISocketTransport> socketTransport;
- rv = sts->CreateTransport(nullptr, 0,
- aRemoteHost, aRemotePort,
- nullptr, getter_AddRefs(socketTransport));
+ if (aUseSSL) {
+ const char* socketTypes[1];
+ socketTypes[0] = "ssl";
+ rv = sts->CreateTransport(socketTypes, 1,
+ aRemoteHost, aRemotePort,
+ nullptr, getter_AddRefs(socketTransport));
+ } else {
+ rv = sts->CreateTransport(nullptr, 0,
+ aRemoteHost, aRemotePort,
+ nullptr, getter_AddRefs(socketTransport));
+ }
+
if (NS_FAILED(rv)) {
FireInteralError(this, __LINE__);
return true;
}
+ // in most cases aReuseAddrPort is false, but ICE TCP needs
+ // sockets options set that allow addr/port reuse
+ socketTransport->SetReuseAddrPort(aReuseAddrPort);
+
PRNetAddr prAddr;
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
FireInteralError(this, __LINE__);
diff --git a/dom/network/TCPSocketParent.h b/dom/network/TCPSocketParent.h
index 07112f1e2d..e0f987b17f 100644
--- a/dom/network/TCPSocketParent.h
+++ b/dom/network/TCPSocketParent.h
@@ -54,6 +54,7 @@ public:
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
+ const bool& aReuseAddrPort,
const bool& aUseArrayBuffers,
const nsCString& aFilter) override;
diff --git a/dom/webidl/CSS.webidl b/dom/webidl/CSS.webidl
index b5cdab2d18..2a9746e2c9 100644
--- a/dom/webidl/CSS.webidl
+++ b/dom/webidl/CSS.webidl
@@ -10,15 +10,15 @@
* liability, trademark and document use rules apply.
*/
-interface CSS {
+namespace CSS {
[Throws]
- static boolean supports(DOMString property, DOMString value);
+ boolean supports(DOMString property, DOMString value);
[Throws]
- static boolean supports(DOMString conditionText);
+ boolean supports(DOMString conditionText);
};
// http://dev.w3.org/csswg/cssom/#the-css.escape%28%29-method
-partial interface CSS {
- static DOMString escape(DOMString ident);
+partial namespace CSS {
+ DOMString escape(DOMString ident);
};
diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js
index 05fc41bc14..1e7776e228 100644
--- a/js/src/builtin/Array.js
+++ b/js/src/builtin/Array.js
@@ -833,7 +833,7 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) {
}
// Step 7.
- assert(usingIterator === undefined, "`items` can't be an Iterable after step 6.g.iv");
+ assert(usingIterator === undefined, "`items` cannot be an Iterable after step 6.g.iv");
// Steps 8-9.
var arrayLike = ToObject(items);
@@ -1181,6 +1181,35 @@ function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunctio
return targetIndex;
}
+// ES2022 at() method on the built-in indexables
+// Array.prototype.at(index)
+function ArrayAt(index) {
+ // Step 1.
+ var O = ToObject(this);
+
+ // Step 2.
+ var len = ToLength(O.length);
+
+ // Step 3.
+ var relativeIndex = ToInteger(index);
+
+ // Steps 4-5.
+ var k;
+ if (relativeIndex >= 0) {
+ k = relativeIndex;
+ } else {
+ k = len + relativeIndex;
+ }
+
+ // Step 6.
+ if (k < 0 || k >= len) {
+ return undefined;
+ }
+
+ // Step 7.
+ return O[k];
+}
+
function ArrayStaticConcat(arr, arg1) {
if (arguments.length < 1)
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat');
diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js
index 233a7323b2..b0928fe88c 100644
--- a/js/src/builtin/String.js
+++ b/js/src/builtin/String.js
@@ -784,6 +784,39 @@ function String_static_raw(callSite, ...substitutions) {
}
}
+// ES2022 at() method on the built-in indexables
+// String.prototype.at(index)
+function String_at(index) {
+ // Step 1.
+ if (this === undefined || this === null)
+ ThrowIncompatibleMethod("at", this);
+
+ // Step 2.
+ var string = ToString(this);
+
+ // Step 3.
+ var len = string.length;
+
+ // Step 4.
+ var relativeIndex = ToInteger(index);
+
+ // Steps 5-6.
+ var k;
+ if (relativeIndex >= 0) {
+ k = relativeIndex;
+ } else {
+ k = len + relativeIndex;
+ }
+
+ // Step 7.
+ if (k < 0 || k >= len) {
+ return undefined;
+ }
+
+ // Step 8.
+ return string[k];
+}
+
/**
* Compare String str1 against String str2, using the locale and collation
* options provided.
diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js
index a1934051da..5b7a1dfc22 100644
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -1308,6 +1308,45 @@ function TypedArraySubarray(begin, end) {
return TypedArraySpeciesCreateWithBuffer(obj, buffer, beginByteOffset, newLength);
}
+// ES2022 at() method on the built-in indexables
+// %TypedArray%.prototype.at(index)
+function TypedArrayAt(index) {
+ // Step 1.
+ var obj = this;
+
+ // Step 2.
+ // This function is not generic.
+ if (!IsObject(obj) || !IsTypedArray(obj)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, obj, index,
+ "TypedArrayAt");
+ }
+ GetAttachedArrayBuffer(obj);
+
+ // If we got here, `this` is either a typed array or a wrapper for one.
+
+ // Step 3.
+ var len = TypedArrayLength(obj);
+
+ // Step 4.
+ var relativeIndex = ToInteger(index);
+
+ // Steps 5-6.
+ var k;
+ if (relativeIndex >= 0) {
+ k = relativeIndex;
+ } else {
+ k = len + relativeIndex;
+ }
+
+ // Step 7.
+ if (k < 0 || k >= len) {
+ return undefined;
+ }
+
+ // Step 8.
+ return obj[k];
+}
+
// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
function TypedArrayValues() {
// Step 1.
diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h
index ade111739d..f9158ef9c2 100644
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -332,7 +332,7 @@ class StoreBuffer
explicit operator bool() const { return objectAndKind_ != 0; }
- typedef struct {
+ typedef struct Hasher {
typedef SlotsEdge Lookup;
static HashNumber hash(const Lookup& l) { return l.objectAndKind_ ^ l.start_ ^ l.count_; }
static bool match(const SlotsEdge& k, const Lookup& l) { return k == l; }
diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp
index a1b9f74b4f..912f393942 100644
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3189,6 +3189,9 @@ static const JSFunctionSpec array_methods[] = {
JS_SELF_HOSTED_FN("flat", "ArrayFlat", 0,0),
JS_SELF_HOSTED_FN("flatMap", "ArrayFlatMap", 1,0),
+ /* ES2022 additions */
+ JS_SELF_HOSTED_FN("at", "ArrayAt", 1,0),
+
JS_FS_END
};
diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp
index 6eb11b1cc1..4167d78741 100644
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2847,6 +2847,9 @@ static const JSFunctionSpec string_methods[] = {
/* Python-esque sequence methods. */
JS_FN("concat", str_concat, 1,0),
JS_SELF_HOSTED_FN("slice", "String_slice", 2,0),
+
+ /* ES2022 additions */
+ JS_SELF_HOSTED_FN("at", "String_at", 1,0),
/* HTML string methods. */
JS_SELF_HOSTED_FN("bold", "String_bold", 0,0),
diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp
index 84d73411bf..1b8a1089ae 100644
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1538,6 +1538,10 @@ TypedArrayObject::protoFunctions[] = {
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
JS_SELF_HOSTED_FN("toString", "ArrayToString", 0, 0),
JS_SELF_HOSTED_FN("toLocaleString", "TypedArrayToLocaleString", 2, 0),
+
+ /* ES2022 additions */
+ JS_SELF_HOSTED_FN("at", "TypedArrayAt", 1, 0),
+
JS_FS_END
};
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index 1af7e798ef..994e2cfbb6 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -225,7 +225,7 @@ ReflowInput::ReflowInput(
CheckNextInFlowParenthood(aFrame, aParentReflowInput.mFrame);
mFlags.mAssumingHScrollbar = mFlags.mAssumingVScrollbar = false;
mFlags.mIsColumnBalancing = false;
- mFlags.mIsFlexContainerMeasuringHeight = false;
+ mFlags.mIsFlexContainerMeasuringBSize = false;
mFlags.mDummyParentReflowInput = false;
mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP);
mFlags.mUseAutoBSize = !!(aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE);
@@ -2403,15 +2403,15 @@ ReflowInput::InitConstraints(nsPresContext* aPresContext,
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
// If we're inside of a flex container that needs to measure our
- // auto height, pass that information along to ComputeSize().
- if (mFlags.mIsFlexContainerMeasuringHeight) {
+ // auto BSize, pass that information along to ComputeSize().
+ if (mFlags.mIsFlexContainerMeasuringBSize) {
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoBSize);
}
} else {
- MOZ_ASSERT(!mFlags.mIsFlexContainerMeasuringHeight,
+ MOZ_ASSERT(!mFlags.mIsFlexContainerMeasuringBSize,
"We're not in a flex container, so the flag "
- "'mIsFlexContainerMeasuringHeight' shouldn't be set");
+ "'mIsFlexContainerMeasuringBSize' shouldn't be set");
}
}
@@ -2993,7 +2993,7 @@ ReflowInput::ComputeMinMaxValues(const LogicalSize&aCBSize)
minBSize.HasPercent()) ||
(mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE &&
minBSize.IsCalcUnit() && minBSize.CalcHasPercent()) ||
- mFlags.mIsFlexContainerMeasuringHeight) {
+ mFlags.mIsFlexContainerMeasuringBSize) {
ComputedMinBSize() = 0;
} else {
ComputedMinBSize() = ComputeBSizeValue(aCBSize.BSize(wm),
@@ -3015,7 +3015,7 @@ ReflowInput::ComputeMinMaxValues(const LogicalSize&aCBSize)
maxBSize.HasPercent()) ||
(mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE &&
maxBSize.IsCalcUnit() && maxBSize.CalcHasPercent()) ||
- mFlags.mIsFlexContainerMeasuringHeight) {
+ mFlags.mIsFlexContainerMeasuringBSize) {
ComputedMaxBSize() = NS_UNCONSTRAINEDSIZE;
} else {
ComputedMaxBSize() = ComputeBSizeValue(aCBSize.BSize(wm),
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
index a70549d8eb..e84d386a82 100644
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -203,9 +203,9 @@ public:
uint32_t mHeightDependsOnAncestorCell:1; // Does frame height depend on
// an ancestor table-cell?
uint32_t mIsColumnBalancing:1; // nsColumnSetFrame is balancing columns
- uint32_t mIsFlexContainerMeasuringHeight:1; // nsFlexContainerFrame is
- // reflowing this child to
- // measure its intrinsic height.
+ uint32_t mIsFlexContainerMeasuringBSize:1; // nsFlexContainerFrame is
+ // reflowing this child to
+ // measure its intrinsic BSize.
uint32_t mDummyParentReflowInput:1; // a "fake" reflow state made
// in order to be the parent
// of a real one
diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp
index 18a0643f14..b4907a4862 100644
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -511,6 +511,15 @@ public:
// visibility:collapse.
bool IsStrut() const { return mIsStrut; }
+ // Returns true if this item's inline axis is parallel (or antiparallel)
+ // to the container's main axis. Otherwise (i.e. if this item's inline axis
+ // is orthogonal to the container's main axis), this function returns false.
+ bool IsInlineAxisMainAxis() const { return mIsInlineAxisMainAxis; }
+
+ // Same as above, but for cross axis. Equivalent to !IsInlineAxisMainAxis().
+ // This just exists for convenience/readability at callsites.
+ bool IsInlineAxisCrossAxis() const { return !mIsInlineAxisMainAxis; }
+
WritingMode GetWritingMode() const { return mWM; }
uint8_t GetAlignSelf() const { return mAlignSelf; }
@@ -749,10 +758,8 @@ protected:
void CheckForMinSizeAuto(const ReflowInput& aFlexItemReflowInput,
const FlexboxAxisTracker& aAxisTracker);
- // Our frame:
- nsIFrame* const mFrame;
-
- // Values that we already know in constructor: (and are hence mostly 'const')
+ // Values that we already know in constructor (and are hence mostly 'const'):
+ nsIFrame* const mFrame; // The flex item's frame.
const float mFlexGrow;
const float mFlexShrink;
@@ -785,6 +792,7 @@ protected:
// until after main-size has been resolved. In particular, these could share
// memory with mMainPosn through mAscent, and mIsStretched.
float mShareOfWeightSoFar;
+ const WritingMode mWM; // The flex item's writing mode.
bool mIsFrozen;
bool mHadMinViolation;
bool mHadMaxViolation;
@@ -795,11 +803,11 @@ protected:
bool mIsStretched; // See IsStretched() documentation
bool mIsStrut; // Is this item a "strut" left behind by an element
// with visibility:collapse?
+ const bool mIsInlineAxisMainAxis; // See IsInlineAxisMainAxis() documentation
// Does this item need to resolve a min-[width|height]:auto (in main-axis).
bool mNeedsMinSizeAutoResolution;
- const WritingMode mWM; // The flex item's writing mode.
uint8_t mAlignSelf; // My "align-self" computed value (with "auto"
// swapped out for parent"s "align-items" value,
// in our constructor).
@@ -1492,21 +1500,26 @@ nsFlexContainerFrame::GenerateFlexItemForChild(
// Static helper-functions for ResolveAutoFlexBasisAndMinSize():
// -------------------------------------------------------------
-// Indicates whether the cross-size property is set to something definite.
-// The logic here should be similar to the logic for isAutoWidth/isAutoHeight
+// Indicates whether the cross-size property is set to something definite,
+// for the purpose of intrinsic ratio calculations.
+// The logic here should be similar to the logic for isAutoISize/isAutoBSize
// in nsFrame::ComputeSizeWithIntrinsicDimensions().
static bool
IsCrossSizeDefinite(const ReflowInput& aItemReflowInput,
const FlexboxAxisTracker& aAxisTracker)
{
const nsStylePosition* pos = aItemReflowInput.mStylePosition;
- if (aAxisTracker.IsCrossAxisHorizontal()) {
- return pos->mWidth.GetUnit() != eStyleUnit_Auto;
- }
- // else, vertical. (We need to use IsAutoHeight() to catch e.g. %-height
- // applied to indefinite-height containing block, which counts as auto.)
- nscoord cbHeight = aItemReflowInput.mCBReflowInput->ComputedHeight();
- return !nsLayoutUtils::IsAutoHeight(pos->mHeight, cbHeight);
+ const WritingMode containerWM = aAxisTracker.GetWritingMode();
+
+ if (aAxisTracker.IsColumnOriented()) {
+ // Column-oriented means cross axis is container's inline axis.
+ return pos->ISize(containerWM).GetUnit() != eStyleUnit_Auto;
+ }
+ // Else, we're row-oriented, which means cross axis is container's block
+ // axis. We need to use IsAutoBSize() to catch e.g. %-BSize applied to
+ // indefinite container BSize, which counts as auto.
+ nscoord cbBSize = aItemReflowInput.mCBReflowInput->ComputedBSize();
+ return !nsLayoutUtils::IsAutoBSize(pos->BSize(containerWM), cbBSize);
}
// If aFlexItem has a definite cross size, this function returns it, for usage
@@ -1676,9 +1689,10 @@ nsFlexContainerFrame::
const ReflowInput& aItemReflowInput,
const FlexboxAxisTracker& aAxisTracker)
{
- // (Note: We should never have a used flex-basis of "auto" if our main axis
- // is horizontal; width values should always be resolvable without reflow.)
- const bool isMainSizeAuto = (!aAxisTracker.IsMainAxisHorizontal() &&
+ // (Note: We can guarantee that the flex-basis will have already been
+ // resolved if the main axis is the same is the same as the item's inline
+ // axis. Inline-axis values should always be resolvable without reflow.)
+ const bool isMainSizeAuto = (!aFlexItem.IsInlineAxisMainAxis() &&
NS_AUTOHEIGHT == aFlexItem.GetFlexBaseSize());
const bool isMainMinSizeAuto = aFlexItem.NeedsMinSizeAutoResolution();
@@ -1709,10 +1723,14 @@ nsFlexContainerFrame::
flexContainerRI->ComputedISize(),
flexContainerRI->ComputedBSize());
// Is container's cross size "definite"?
- // (Container's cross size is definite if cross-axis is horizontal, or if
- // cross-axis is vertical and the cross-size is not NS_AUTOHEIGHT.)
- if (aAxisTracker.IsCrossAxisHorizontal() ||
+ // - If it's column-oriented, then "yes", because its cross size is its
+ // inline-size which is always definite from its descendants' perspective.
+ // - Otherwise (if it's row-oriented), then we check the actual size
+ // and call it definite if it's not NS_AUTOHEIGHT.
+ if (aAxisTracker.IsColumnOriented() ||
containerCrossSize != NS_AUTOHEIGHT) {
+ // Container's cross size is "definite", so we can resolve the item's
+ // stretched cross size using that.
aFlexItem.ResolveStretchedCrossSize(containerCrossSize, aAxisTracker);
}
}
@@ -1744,7 +1762,7 @@ nsFlexContainerFrame::
// Measure content, if needed (w/ intrinsic-width method or a reflow)
if (minSizeNeedsToMeasureContent || flexBasisNeedsToMeasureContent) {
- if (aAxisTracker.IsMainAxisHorizontal()) {
+ if (aFlexItem.IsInlineAxisMainAxis()) {
if (minSizeNeedsToMeasureContent) {
nscoord frameMinISize =
aFlexItem.Frame()->GetMinISize(aItemReflowInput.mRenderingContext);
@@ -1755,30 +1773,32 @@ nsFlexContainerFrame::
"reflow state, for horizontal flexbox. It shouldn't need "
"special handling here");
} else {
- // If this item is flexible (vertically), or if we're measuring the
- // 'auto' min-height and our main-size is something else, then we assume
- // that the computed-height we're reflowing with now could be different
- // from the one we'll use for this flex item's "actual" reflow later on.
- // In that case, we need to be sure the flex item treats this as a
- // vertical resize, even though none of its ancestors are necessarily
- // being vertically resized.
- // (Note: We don't have to do this for width, because InitResizeFlags
- // will always turn on mHResize on when it sees that the computed width
- // is different from current width, and that's all we need.)
- bool forceVerticalResizeForMeasuringReflow =
+ // If this item is flexible (in its block axis)...
+ // OR if we're measuring its 'auto' min-BSize, with its main-size (in its
+ // block axis) being something non-"auto"...
+ // THEN: we assume that the computed BSize that we're reflowing with now
+ // could be different from the one we'll use for this flex item's
+ // "actual" reflow later on. In that case, we need to be sure the flex
+ // item treats this as a block-axis resize (regardless of whether there
+ // are actually any ancestors being resized in that axis).
+ // (Note: We don't have to do this for the inline axis, because
+ // InitResizeFlags will always turn on mIsIResize on when it sees that
+ // the computed ISize is different from current ISize, and that's all we
+ // need.)
+ bool forceBResizeForMeasuringReflow =
!aFlexItem.IsFrozen() || // Is the item flexible?
!flexBasisNeedsToMeasureContent; // Are we *only* measuring it for
- // 'min-height:auto'?
+ // 'min-block-size:auto'?
- nscoord contentHeight =
- MeasureFlexItemContentHeight(aPresContext, aFlexItem,
- forceVerticalResizeForMeasuringReflow,
- *flexContainerRI);
+ nscoord contentBSize =
+ MeasureFlexItemContentBSize(aPresContext, aFlexItem,
+ forceBResizeForMeasuringReflow,
+ *flexContainerRI);
if (minSizeNeedsToMeasureContent) {
- resolvedMinSize = std::min(resolvedMinSize, contentHeight);
+ resolvedMinSize = std::min(resolvedMinSize, contentBSize);
}
if (flexBasisNeedsToMeasureContent) {
- aFlexItem.SetFlexBaseSizeAndMainSize(contentHeight);
+ aFlexItem.SetFlexBaseSizeAndMainSize(contentBSize);
}
}
}
@@ -1800,7 +1820,7 @@ nsFlexContainerFrame::
* intrinsic size is marked as dirty (due to a style or DOM change).
*
* In particular the computed height may change between measuring reflows due to
- * how the mIsFlexContainerMeasuringReflow flag affects size computation (see
+ * how the mIsFlexContainerMeasuringBSize flag affects size computation (see
* bug 1336708).
*
* Caching it prevents us from doing exponential reflows in cases of deeply
@@ -1812,27 +1832,27 @@ class nsFlexContainerFrame::CachedMeasuringReflowResult
{
// Members that are part of the cache key:
const LogicalSize mAvailableSize;
- const nscoord mComputedHeight;
+ const nscoord mComputedBSize;
// Members that are part of the cache value:
- const nscoord mHeight;
+ const nscoord mBSize;
const nscoord mAscent;
public:
CachedMeasuringReflowResult(const ReflowInput& aReflowInput,
const ReflowOutput& aDesiredSize)
: mAvailableSize(aReflowInput.AvailableSize())
- , mComputedHeight(aReflowInput.ComputedHeight())
- , mHeight(aDesiredSize.Height())
+ , mComputedBSize(aReflowInput.ComputedBSize())
+ , mBSize(aDesiredSize.BSize(aReflowInput.GetWritingMode()))
, mAscent(aDesiredSize.BlockStartAscent())
{}
bool IsValidFor(const ReflowInput& aReflowInput) const {
return mAvailableSize == aReflowInput.AvailableSize() &&
- mComputedHeight == aReflowInput.ComputedHeight();
+ mComputedBSize == aReflowInput.ComputedBSize();
}
- nscoord Height() const { return mHeight; }
+ nscoord BSize() const { return mBSize; }
nscoord Ascent() const { return mAscent; }
};
@@ -1841,7 +1861,7 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(CachedFlexMeasuringReflow,
CachedMeasuringReflowResult);
const CachedMeasuringReflowResult&
-nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
+nsFlexContainerFrame::MeasureAscentAndBSizeForFlexItem(
FlexItem& aItem,
nsPresContext* aPresContext,
ReflowInput& aChildReflowInput)
@@ -1892,43 +1912,44 @@ nsFlexContainerFrame::MarkIntrinsicISizesDirty()
nscoord
nsFlexContainerFrame::
- MeasureFlexItemContentHeight(nsPresContext* aPresContext,
- FlexItem& aFlexItem,
- bool aForceVerticalResizeForMeasuringReflow,
- const ReflowInput& aParentReflowInput)
+ MeasureFlexItemContentBSize(nsPresContext* aPresContext,
+ FlexItem& aFlexItem,
+ bool aForceBResizeForMeasuringReflow,
+ const ReflowInput& aParentReflowInput)
{
// Set up a reflow state for measuring the flex item's auto-height:
WritingMode wm = aFlexItem.Frame()->GetWritingMode();
LogicalSize availSize = aParentReflowInput.ComputedSize(wm);
availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
ReflowInput
- childRIForMeasuringHeight(aPresContext, aParentReflowInput,
- aFlexItem.Frame(), availSize,
- nullptr, ReflowInput::CALLER_WILL_INIT);
- childRIForMeasuringHeight.mFlags.mIsFlexContainerMeasuringHeight = true;
- childRIForMeasuringHeight.Init(aPresContext);
+ childRIForMeasuringBSize(aPresContext, aParentReflowInput,
+ aFlexItem.Frame(), availSize,
+ nullptr, ReflowInput::CALLER_WILL_INIT);
+ childRIForMeasuringBSize.mFlags.mIsFlexContainerMeasuringBSize = true;
+ childRIForMeasuringBSize.Init(aPresContext);
if (aFlexItem.IsStretched()) {
- childRIForMeasuringHeight.SetComputedWidth(aFlexItem.GetCrossSize());
- childRIForMeasuringHeight.SetHResize(true);
+ childRIForMeasuringBSize.SetComputedISize(aFlexItem.GetCrossSize());
+ childRIForMeasuringBSize.SetIResize(true);
}
- if (aForceVerticalResizeForMeasuringReflow) {
- childRIForMeasuringHeight.SetVResize(true);
+ if (aForceBResizeForMeasuringReflow) {
+ childRIForMeasuringBSize.SetBResize(true);
}
const CachedMeasuringReflowResult& reflowResult =
- MeasureAscentAndHeightForFlexItem(aFlexItem, aPresContext,
- childRIForMeasuringHeight);
+ MeasureAscentAndBSizeForFlexItem(aFlexItem, aPresContext,
+ childRIForMeasuringBSize);
aFlexItem.SetAscent(reflowResult.Ascent());
- // Subtract border/padding in vertical axis, to get _just_
- // the effective computed value of the "height" property.
- nscoord childDesiredHeight = reflowResult.Height() -
- childRIForMeasuringHeight.ComputedPhysicalBorderPadding().TopBottom();
- return std::max(0, childDesiredHeight);
+ // Subtract border/padding in block axis, to get _just_
+ // the effective computed value of the BSize property.
+ nscoord childDesiredBSize = reflowResult.BSize() -
+ childRIForMeasuringBSize.ComputedLogicalBorderPadding().BStartEnd(wm);
+
+ return std::max(0, childDesiredBSize);
}
FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput,
@@ -1952,14 +1973,16 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput,
mCrossPosn(0),
mAscent(0),
mShareOfWeightSoFar(0.0f),
+ mWM(aFlexItemReflowInput.GetWritingMode()),
mIsFrozen(false),
mHadMinViolation(false),
mHadMaxViolation(false),
mHadMeasuringReflow(false),
mIsStretched(false),
mIsStrut(false),
+ mIsInlineAxisMainAxis(aAxisTracker.IsRowOriented() !=
+ aAxisTracker.GetWritingMode().IsOrthogonalTo(mWM))
// mNeedsMinSizeAutoResolution is initialized in CheckForMinSizeAuto()
- mWM(aFlexItemReflowInput.GetWritingMode())
// mAlignSelf, see below
{
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
@@ -1967,6 +1990,10 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput,
"placeholder frames should not be treated as flex items");
MOZ_ASSERT(!(mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
"out-of-flow frames should not be treated as flex items");
+ MOZ_ASSERT(mIsInlineAxisMainAxis ==
+ nsFlexContainerFrame::IsItemInlineAxisMainAxis(mFrame),
+ "public API should be consistent with internal state (about "
+ "whether flex item's inline axis is flex container's main axis)");
const ReflowInput* containerRS = aFlexItemReflowInput.mParentReflowInput;
if (IsLegacyBox(containerRS->mFrame)) {
@@ -2047,14 +2074,17 @@ FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize,
mCrossPosn(0),
mAscent(0),
mShareOfWeightSoFar(0.0f),
+ // Struts don't do layout, so its WM doesn't matter at this point. So, we
+ // just share container's WM for simplicity:
+ mWM(aContainerWM),
mIsFrozen(true),
mHadMinViolation(false),
mHadMaxViolation(false),
mHadMeasuringReflow(false),
mIsStretched(false),
mIsStrut(true), // (this is the constructor for making struts, after all)
+ mIsInlineAxisMainAxis(true), // (doesn't matter b/c we're not doing layout)
mNeedsMinSizeAutoResolution(false),
- mWM(aContainerWM),
mAlignSelf(NS_STYLE_ALIGN_FLEX_START)
{
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
@@ -2171,15 +2201,28 @@ FlexItem::CanMainSizeInfluenceCrossSize(
return true;
}
- if (aAxisTracker.IsCrossAxisHorizontal()) {
- // If the cross axis is horizontal, then changes to the item's main size
- // (height) can't influence its cross size (width), if the item is a block
- // with a horizontal writing-mode.
- // XXXdholbert This doesn't account for vertical writing-modes, items with
- // aspect ratios, items that are multicol elements, & items that are
- // multi-line vertical flex containers. In all of those cases, a change to
- // the height could influence the width.
- return false;
+ if (IsInlineAxisCrossAxis()) {
+ // If we get here, this function is really asking: "can changes to this
+ // item's block size have an influence on its inline size"? For blocks and
+ // tables, the answer is "no".
+ if (mFrame->GetType() == nsGkAtoms::blockFrame ||
+ mFrame->GetType() == nsGkAtoms::tableWrapperFrame) {
+ // XXXdholbert (Maybe use an IsFrameOfType query or something more
+ // general to test this across all frame types? For now, I'm just
+ // optimizing for block and table, since those are common containers that
+ // can contain arbitrarily-large subtrees (and that reliably have ISize
+ // being unaffected by BSize, per CSS2). So optimizing away needless
+ // relayout is possible & especially valuable for these containers.)
+ return false;
+ }
+ // Other opt-outs can go here, as they're identified as being useful
+ // (particularly for containers where an extra reflow is expensive). But in
+ // general, we have to assume that a flexed BSize *could* influence the
+ // ISize. Some examples where this can definitely happen:
+ // * Intrinsically-sized multicol with fixed-ISize columns, which adds
+ // columns (i.e. grows in inline axis) depending on its block size.
+ // * Intrinsically-sized multi-line column-oriented flex container, which
+ // adds flex lines (i.e. grows in inline axis) depending on its block size.
}
// Default assumption, if we haven't proven otherwise: the resolved main size
@@ -4083,19 +4126,10 @@ nsFlexContainerFrame::SizeItemInCrossAxis(
ReflowInput& aChildReflowInput,
FlexItem& aItem)
{
- if (aAxisTracker.IsCrossAxisHorizontal()) {
- MOZ_ASSERT(aItem.HasIntrinsicRatio(),
- "For now, caller's CanMainSizeInfluenceCrossSize check should "
- "only allow us to get here for items with intrinsic ratio");
- // XXXdholbert When we finish support for vertical writing-modes,
- // (in bug 1079155 or a dependency), we'll relax the horizontal check in
- // CanMainSizeInfluenceCrossSize, and this function will need to be able
- // to measure the baseline & width (given our resolved height)
- // of vertical-writing-mode flex items here.
- // For now, we only expect to get here for items with an intrinsic aspect
- // ratio; and for those items, we can just read the size off of the reflow
- // state, without performing reflow.
- aItem.SetCrossSize(aChildReflowInput.ComputedWidth());
+ // If cross axis is the item's inline axis, just use ISize from reflow state,
+ // and don't bother with a full reflow.
+ if (aItem.IsInlineAxisCrossAxis()) {
+ aItem.SetCrossSize(aChildReflowInput.ComputedISize());
return;
}
@@ -4104,16 +4138,18 @@ nsFlexContainerFrame::SizeItemInCrossAxis(
if (aItem.GetAlignSelf() == NS_STYLE_ALIGN_STRETCH) {
// This item's got "align-self: stretch", so we probably imposed a
- // stretched computed height on it during its previous reflow. We're
- // not imposing that height for *this* measuring reflow, so we need to
- // tell it to treat this reflow as a vertical resize (regardless of
- // whether any of its ancestors are being resized).
- aChildReflowInput.SetVResize(true);
+ // stretched computed cross-size on it during its previous
+ // reflow. We're not imposing that BSize for *this* "measuring" reflow, so
+ // we need to tell it to treat this reflow as a resize in its block axis
+ // (regardless of whether any of its ancestors are actually being resized).
+ // (Note: we know that the cross axis is the item's *block* axis -- if it
+ // weren't, then we would've taken the early-return above.)
+ aChildReflowInput.SetBResize(true);
}
// Potentially reflow the item, and get the sizing info.
const CachedMeasuringReflowResult& reflowResult =
- MeasureAscentAndHeightForFlexItem(aItem, aPresContext, aChildReflowInput);
+ MeasureAscentAndBSizeForFlexItem(aItem, aPresContext, aChildReflowInput);
// Save the sizing info that we learned from this reflow
// -----------------------------------------------------
@@ -4125,7 +4161,7 @@ nsFlexContainerFrame::SizeItemInCrossAxis(
// so we don't bother with making aAxisTracker pick the cross-axis component
// for us.)
nscoord crossAxisBorderPadding = aItem.GetBorderPadding().TopBottom();
- if (reflowResult.Height() < crossAxisBorderPadding) {
+ if (reflowResult.BSize() < crossAxisBorderPadding) {
// Child's requested size isn't large enough for its border/padding!
// This is OK for the trivial nsFrame::Reflow() impl, but other frame
// classes should know better. So, if we get here, the child had better be
@@ -4138,7 +4174,7 @@ nsFlexContainerFrame::SizeItemInCrossAxis(
aItem.SetCrossSize(0);
} else {
// (normal case)
- aItem.SetCrossSize(reflowResult.Height() - crossAxisBorderPadding);
+ aItem.SetCrossSize(reflowResult.BSize() - crossAxisBorderPadding);
}
aItem.SetAscent(reflowResult.Ascent());
@@ -4389,6 +4425,41 @@ nsFlexContainerFrame::CalculatePackingSpace(uint32_t aNumThingsToPack,
*aPackingSpaceRemaining -= totalEdgePackingSpace;
}
+/* static */
+bool
+nsFlexContainerFrame::IsItemInlineAxisMainAxis(nsIFrame* aFrame)
+{
+ MOZ_ASSERT(aFrame && aFrame->IsFlexItem(), "expecting arg to be a flex item");
+ const WritingMode flexItemWM = aFrame->GetWritingMode();
+ const nsIFrame* flexContainer = aFrame->GetParent();
+
+ if (IsLegacyBox(flexContainer)) {
+ // For legacy boxes, the main axis is determined by "box-orient", and we can
+ // just directly check if that's vertical, and compare that to whether the
+ // item's WM is also vertical:
+ bool boxOrientIsVertical =
+ (flexContainer->StyleXUL()->mBoxOrient == StyleBoxOrient::Vertical);
+ return flexItemWM.IsVertical() == boxOrientIsVertical;
+ }
+
+ // For modern CSS flexbox, we get our return value by asking two questions
+ // and comparing their answers.
+ // Question 1: does aFrame have the same inline axis as its flex container?
+ bool itemInlineAxisIsParallelToParent =
+ !flexItemWM.IsOrthogonalTo(flexContainer->GetWritingMode());
+
+ // Question 2: is aFrame's flex container row-oriented? (This tells us
+ // whether the flex container's main axis is its inline axis.)
+ auto flexDirection = flexContainer->StylePosition()->mFlexDirection;
+ bool flexContainerIsRowOriented =
+ flexDirection == NS_STYLE_FLEX_DIRECTION_ROW ||
+ flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE;
+
+ // aFrame's inline axis is its flex container's main axis IFF the above
+ // questions have the same answer.
+ return flexContainerIsRowOriented == itemInlineAxisIsParallelToParent;
+}
+
void
nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h
index 39de79b577..e349709876 100644
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -133,6 +133,21 @@ public:
uint32_t* aNumPackingSpacesRemaining,
nscoord* aPackingSpaceRemaining);
+ /**
+ * Given a frame for a flex item, this method returns true IFF that flex
+ * item's inline axis is the same as (i.e. not orthogonal to) its flex
+ * container's main axis.
+ *
+ * (This method is only intended to be used from external
+ * callers. Inside of flex reflow code, FlexItem::IsInlineAxisMainAxis() is
+ * equivalent & more optimal.)
+ *
+ * @param aFrame a flex item (must return true from IsFlexItem)
+ * @return true iff aFrame's inline axis is the same as (i.e. not orthogonal
+ * to) its flex container's main axis. Otherwise, false.
+ */
+ static bool IsItemInlineAxisMainAxis(nsIFrame* aFrame);
+
protected:
// Protected constructor & destructor
explicit nsFlexContainerFrame(nsStyleContext* aContext)
@@ -207,20 +222,20 @@ protected:
* This avoids exponential reflows, see the comment on
* CachedMeasuringReflowResult.
*/
- const CachedMeasuringReflowResult& MeasureAscentAndHeightForFlexItem(
+ const CachedMeasuringReflowResult& MeasureAscentAndBSizeForFlexItem(
FlexItem& aItem,
nsPresContext* aPresContext,
ReflowInput& aChildReflowInput);
/**
- * This method performs a "measuring" reflow to get the content height of
- * aFlexItem.Frame() (treating it as if it had auto-height), & returns the
- * resulting height.
+ * This method performs a "measuring" reflow to get the content BSize of
+ * aFlexItem.Frame() (treating it as if it had a computed BSize of "auto"),
+ * and returns the resulting BSize measurement.
* (Helper for ResolveAutoFlexBasisAndMinSize().)
*/
- nscoord MeasureFlexItemContentHeight(nsPresContext* aPresContext,
+ nscoord MeasureFlexItemContentBSize(nsPresContext* aPresContext,
FlexItem& aFlexItem,
- bool aForceVerticalResizeForMeasuringReflow,
+ bool aForceBSizeForMeasuringReflow,
const ReflowInput& aParentReflowInput);
/**
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 43ad970890..9bc4941e0b 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -39,6 +39,7 @@
#include "mozilla/Logging.h"
#include "mozilla/Sprintf.h"
#include "nsFrameManager.h"
+#include "nsFlexContainerFrame.h"
#include "nsLayoutUtils.h"
#include "LayoutLogging.h"
#include "mozilla/RestyleManager.h"
@@ -4752,12 +4753,11 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext,
}
bool isFlexItem = (parentFrameType == nsGkAtoms::flexContainerFrame &&
!(GetStateBits() & NS_FRAME_OUT_OF_FLOW));
+
bool isInlineFlexItem = false;
if (isFlexItem) {
- uint32_t flexDirection = GetParent()->StylePosition()->mFlexDirection;
isInlineFlexItem =
- flexDirection == NS_STYLE_FLEX_DIRECTION_ROW ||
- flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE;
+ nsFlexContainerFrame::IsItemInlineAxisMainAxis(this);
const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis);
SetCoordToFlexBasis(isInlineFlexItem, false, flexBasis,
@@ -4973,11 +4973,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
// from our style struct. (Otherwise, we'll be using an irrelevant value in
// the aspect-ratio calculations below.)
if (isFlexItem) {
- uint32_t flexDirection =
- GetParent()->StylePosition()->mFlexDirection;
isInlineFlexItem =
- flexDirection == NS_STYLE_FLEX_DIRECTION_ROW ||
- flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE;
+ nsFlexContainerFrame::IsItemInlineAxisMainAxis(this);
// If FlexItemMainSizeOverride frame-property is set, then that means the
// flex container is imposing a main-size on this flex item for it to use
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-horiz-001v.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-horiz-001v.xhtml
new file mode 100644
index 0000000000..f1dfdfdb86
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-horiz-001v.xhtml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- Testcase with blocks as flex items in a horizontal flex container, with
+ various "flex" values and various combinations of the items
+ and with various writing-modes on the items. -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>
+ CSS Test: Testing flexbox layout algorithm property on block flex items in a horizontal flex container
+ (with various writing-modes on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
+ <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#layout-algorithm"/>
+ <link rel="match" href="flexbox-basic-block-horiz-001-ref.xhtml"/>
+ <style>
+ div { height: 100px; }
+ div.flexbox {
+ border: 1px dashed blue;
+ width: 200px;
+ font-size: 10px;
+ display: flex;
+ }
+ div.a {
+ flex: 1 0 30px;
+ background: lightgreen;
+ writing-mode: vertical-lr;
+ }
+ div.b {
+ flex: 2 0 20px;
+ background: yellow;
+ writing-mode: vertical-rl;
+ }
+ div.c {
+ flex: 3 0 40px;
+ background: orange;
+ writing-mode: sideways-lr;
+ }
+ div.flexNone {
+ flex: none;
+ background: pink;
+ writing-mode: vertical-lr;
+ }
+ div.flexBasis {
+ flex: 0 0 20px;
+ background: gray;
+ writing-mode: sideways-rl;
+ }
+ div.spacer {
+ width: 15px;
+ height: 15px;
+ background: purple;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="flexbox"><div class="a"></div><div class="b"/></div>
+ <div class="flexbox"><div class="a"/><div class="c"/></div>
+ <div class="flexbox"><div class="a"/>
+ <div class="flexNone"><div class="spacer"/></div>
+ </div>
+ <div class="flexbox"><div class="b"/><div class="c"/></div>
+ <div class="flexbox"><div class="b"/>
+ <div class="flexNone"><div class="spacer"/><div class="spacer"/></div>
+ </div>
+
+ <div class="flexbox">
+ <div class="a"/><div class="b"/><div class="flexBasis"/><div class="c"/>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-vert-001v.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-vert-001v.xhtml
new file mode 100644
index 0000000000..da943dfc56
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-vert-001v.xhtml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- Testcase with blocks as flex items in a vertical flex container, with
+ various "flex" values and various combinations of the items. -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>
+ CSS Test: Testing flexbox layout algorithm property on block flex items in a vertical flex container
+ (with various writing-modes on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
+ <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#layout-algorithm"/>
+ <link rel="match" href="flexbox-basic-block-vert-001-ref.xhtml"/>
+ <style>
+ div { width: 50px; }
+ div.flexbox {
+ float: left;
+ border: 1px dashed blue;
+ height: 200px;
+ font-size: 10px;
+ display: flex;
+ flex-direction: column;
+ }
+ div.a {
+ flex: 1 0 30px;
+ background: lightgreen;
+ writing-mode: vertical-lr;
+ }
+ div.b {
+ flex: 2 0 20px;
+ background: yellow;
+ writing-mode: vertical-rl;
+ }
+ div.c {
+ flex: 3 0 40px;
+ background: orange;
+ writing-mode: sideways-lr;
+ }
+ div.flexNone {
+ flex: none;
+ background: pink;
+ writing-mode: vertical-lr;
+ }
+ div.flexBasis {
+ flex: 0 0 20px;
+ background: gray;
+ writing-mode: sideways-rl;
+ }
+ div.spacer {
+ display: inline-block;
+ width: 15px;
+ height: 15px;
+ background: purple;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="flexbox"><div class="a"></div><div class="b"/></div>
+ <div class="flexbox"><div class="a"/><div class="c"/></div>
+ <div class="flexbox"><div class="a"/>
+ <div class="flexNone"><div class="spacer"/></div>
+ </div>
+ <div class="flexbox"><div class="b"/><div class="c"/></div>
+ <div class="flexbox"><div class="b"/>
+ <div class="flexNone"><div class="spacer"/><div class="spacer"/></div>
+ </div>
+
+ <div class="flexbox">
+ <div class="a"/><div class="b"/><div class="flexBasis"/><div class="c"/>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-001v.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-001v.xhtml
new file mode 100644
index 0000000000..ad623d77f7
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-001v.xhtml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!--
+ This test checks that canvas elements behave correctly as flex items.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>
+ CSS Test: Testing flexbox layout algorithm property on canvas flex items in a horizontal flex container
+ (with a vertical writing-mode on the canvas flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
+ <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#layout-algorithm"/>
+ <link rel="match" href="flexbox-basic-canvas-horiz-001-ref.xhtml"/>
+ <style>
+ div.flexbox {
+ width: 200px;
+ background: lightgreen;
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 5px;
+ line-height: 8px;
+ }
+ canvas {
+ min-width: 0;
+ width: 10px;
+ height: 20px;
+ border: 1px dotted green;
+ writing-mode: vertical-lr;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- A) One flex item -->
+ <div class="flexbox">
+ <canvas/>
+ </div>
+
+ <!-- B) Text and a canvas (ensure they aren't merged into one flex item) -->
+ <div class="flexbox">
+ some words <canvas/>
+ </div>
+
+ <!-- C) Two canvas elements, getting stretched by different ratios, from 0.
+
+ Space-to-be-distributed = 200px - borders = 200 - (1 + 1) - (1 + 1)
+ = 196px
+
+ 1st element gets 5/8 of space: 5/8 * 196px = 122.5px
+ 1st element gets 3/8 of space: 3/8 * 196px = 73.5px
+ -->
+ <div class="flexbox">
+ <canvas style="flex: 5"/>
+ <canvas style="flex: 3"/>
+ </div>
+
+ <!-- D) Two canvas elements, getting stretched by different ratios, from
+ different flex bases.
+
+ Space-to-be-distributed = 200px - (33 + 1 + 1) - (13 + 1 + 1) = 150px
+ 1st element gets 2/5 of space: 33px + 2/5 * 150px = 93px
+ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px
+ -->
+ <div class="flexbox">
+ <canvas style="width: 33px; flex: 2 auto"/>
+ <canvas style="width: 13px; flex: 3 auto"/>
+ </div>
+
+ <!-- E) Two flex items, getting shrunk by different amounts.
+
+ Space-to-be-distributed = 200px - (150 + 1 + 1) - (100 + 1 + 1) = -54px
+ First element scaled flex ratio = 4 * 150 = 600
+ Second element scaled flex ratio = 3 * 100 = 300
+ * So, total flexibility is 600 + 300 = 900
+
+ 1st element gets 600/900 of space: 150 + 600/900 * -54 = 114px
+ 2nd element gets 300/900 of space: 100 + 300/900 * -54 = 82px
+ -->
+ <div class="flexbox">
+ <canvas style="width: 150px; flex: 1 4 auto"/>
+ <canvas style="width: 100px; flex: 1 3 auto"/>
+ </div>
+
+ <!-- F) Making sure we don't grow past max-width -->
+ <!-- Same as (D), except we've added a max-width on the second element.
+ -->
+ <div class="flexbox">
+ <canvas style="width: 33px; flex: 2 auto"/>
+ <canvas style="width: 13px; max-width: 90px; flex: 3 auto"/>
+ </div>
+
+ <!-- G) Making sure we grow at least as large as min-width -->
+ <!-- Same as (C), except we've added a min-width on the second element.
+ -->
+ <div class="flexbox">
+ <canvas style="width: 33px; flex: 2 auto"/>
+ <canvas style="width: 13px; min-width: 150px; flex: 3 auto"/>
+ </div>
+
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-001v.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-001v.xhtml
new file mode 100644
index 0000000000..057f63ae62
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-001v.xhtml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!--
+ This test checks that canvas elements behave correctly as flex items.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>
+ CSS Test: Testing flexbox layout algorithm property on canvas flex items in a vertical flex container
+ (with a vertical writing-mode on the canvas flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
+ <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#layout-algorithm"/>
+ <link rel="match" href="flexbox-basic-canvas-vert-001-ref.xhtml"/>
+ <style>
+ div.flexbox {
+ height: 200px;
+ background: lightgreen;
+ display: flex;
+ justify-content: space-between;
+ flex-direction: column;
+ float: left;
+ margin-right: 10px;
+ font: 8px monospace;
+ }
+ canvas {
+ width: 20px;
+ height: 10px;
+ min-height: 0;
+ border: 1px dotted green;
+ writing-mode: vertical-lr;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- A) One flex item -->
+ <div class="flexbox">
+ <canvas/>
+ </div>
+
+ <!-- B) Text and a canvas (ensure they aren't merged into one flex item) -->
+ <div class="flexbox">
+ a b <canvas/>
+ </div>
+
+ <!-- C) Two canvas elements, getting stretched by different ratios, from 0.
+
+ Space-to-be-distributed = 200px - borders = 200 - (1 + 1) - (1 + 1)
+ = 196px
+
+ 1st element gets 5/8 of space: 5/8 * 196px = 122.5px
+ 1st element gets 3/8 of space: 3/8 * 196px = 73.5px
+ -->
+ <div class="flexbox">
+ <canvas style="flex: 5"/>
+ <canvas style="flex: 3"/>
+ </div>
+
+ <!-- D) Two canvas elements, getting stretched by different ratios, from
+ different flex bases.
+
+ Space-to-be-distributed = 200px - (33 + 1 + 1) - (13 + 1 + 1) = 150px
+ 1st element gets 2/5 of space: 33px + 2/5 * 150px = 93px
+ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px
+ -->
+ <div class="flexbox">
+ <canvas style="height: 33px; flex: 2 auto"/>
+ <canvas style="height: 13px; flex: 3 auto"/>
+ </div>
+
+ <!-- E) Two flex items, getting shrunk by different amounts.
+
+ Space-to-be-distributed = 200px - (150 + 1 + 1) - (100 + 1 + 1) = -54px
+ First element scaled flex ratio = 4 * 150 = 600
+ Second element scaled flex ratio = 3 * 100 = 300
+ * So, total flexibility is 600 + 300 = 900
+
+ 1st element gets 600/900 of space: 150 + 600/900 * -54 = 114px
+ 2nd element gets 300/900 of space: 100 + 300/900 * -54 = 82px
+ -->
+ <div class="flexbox">
+ <canvas style="height: 150px; flex: 1 4 auto"/>
+ <canvas style="height: 100px; flex: 1 3 auto"/>
+ </div>
+
+ <!-- F) Making sure we don't grow past max-height -->
+ <!-- Same as (D), except we've added a max-height on the second element.
+ -->
+ <div class="flexbox">
+ <canvas style="height: 33px; flex: 2 auto"/>
+ <canvas style="height: 13px; max-height: 90px; flex: 3 auto"/>
+ </div>
+
+ <!-- G) Making sure we grow at least as large as min-height -->
+ <!-- Same as (C), except we've added a min-height on the second element.
+ -->
+ <div class="flexbox">
+ <canvas style="height: 33px; flex: 2 auto"/>
+ <canvas style="height: 13px; min-height: 150px; flex: 3 auto"/>
+ </div>
+
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001v.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001v.html
new file mode 100644
index 0000000000..4cc910b9e2
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-001v.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ CSS Test: Testing how explicit main-size & cross-size constraints
+ influence sizing on non-stretched flex item w/ intrinsic ratio
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
+ <link rel="match" href="flexbox-intrinsic-ratio-001-ref.html">
+ <style>
+ .flexbox {
+ display: flex;
+ flex-direction: row;
+ border: 1px solid black;
+ margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
+ width: 40px;
+ height: 40px;
+
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ float: left; /* For testing in "rows" */
+ }
+ br { clear: both; }
+
+ .flexbox > * {
+ writing-mode: vertical-lr;
+
+ /* Disable "min-width:auto"/"min-height:auto" to focus purely on
+ later channels of influence. */
+ min-width: 0;
+ min-height: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. -->
+
+ <!-- Row 1: no special sizing: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png">
+ </div>
+ <br>
+
+ <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="flex: 0 0 30px">
+ </div>
+ <br>
+
+ <!-- Row 3: min main-size OR min cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 4: max main-size OR max cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ max-height: 6px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 6px;
+ max-height: 10px">
+ </div>
+ <br>
+
+ <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 10px;
+ min-height: 30px">
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-002v.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-002v.html
new file mode 100644
index 0000000000..0df92f9954
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-002v.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ CSS Test: Testing how explicit main-size & cross-size constraints
+ influence sizing on non-stretched flex item w/ intrinsic ratio
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
+ <link rel="match" href="flexbox-intrinsic-ratio-001-ref.html">
+ <style>
+ .flexbox {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid black;
+ margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
+ width: 40px;
+ height: 40px;
+
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ float: left; /* For testing in "rows" */
+ }
+ br { clear: both; }
+
+ .flexbox > * {
+ writing-mode: vertical-lr;
+
+ /* Disable "min-width:auto"/"min-height:auto" to focus purely on
+ later channels of influence. */
+ min-width: 0;
+ min-height: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. -->
+
+ <!-- Row 1: no special sizing: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png">
+ </div>
+ <br>
+
+ <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="flex: 0 0 30px">
+ </div>
+ <br>
+
+ <!-- Row 3: min main-size OR min cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 4: max main-size OR max cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ max-height: 6px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 6px;
+ max-height: 10px">
+ </div>
+ <br>
+
+ <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 10px;
+ min-height: 30px">
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-003v.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-003v.html
new file mode 100644
index 0000000000..cb9275fd8c
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-003v.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ CSS Test: Testing how explicit main-size & cross-size constraints
+ influence sizing on stretched flex item w/ intrinsic ratio
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
+ <link rel="match" href="flexbox-intrinsic-ratio-003-ref.html">
+ <style>
+ .flexbox {
+ display: flex;
+ flex-direction: row;
+ border: 1px solid black;
+ margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
+ width: 40px;
+ height: 40px;
+
+ justify-content: flex-start;
+ align-items: stretch;
+
+ float: left; /* For testing in "rows" */
+ }
+ br { clear: both; }
+
+ .flexbox > * {
+ writing-mode: vertical-rl;
+
+ /* Disable "min-width:auto"/"min-height:auto" to focus purely on
+ later channels of influence. */
+ min-width: 0;
+ min-height: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. -->
+
+ <!-- Row 1: no special sizing: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png">
+ </div>
+ <br>
+
+ <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="flex: 0 0 30px">
+ </div>
+ <br>
+
+ <!-- Row 3: min main-size OR min cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 4: max main-size OR max cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ max-height: 6px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 6px;
+ max-height: 10px">
+ </div>
+ <br>
+
+ <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 10px;
+ min-height: 30px">
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-004v.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-004v.html
new file mode 100644
index 0000000000..01c5271c45
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-004v.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ CSS Test: Testing how explicit main-size & cross-size constraints
+ influence sizing on stretched flex item w/ intrinsic ratio
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
+ <link rel="match" href="flexbox-intrinsic-ratio-004-ref.html">
+ <style>
+ .flexbox {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid black;
+ margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
+ width: 40px;
+ height: 40px;
+
+ justify-content: flex-start;
+ align-items: stretch;
+
+ float: left; /* For testing in "rows" */
+ }
+ br { clear: both; }
+
+ .flexbox > * {
+ writing-mode: vertical-rl;
+
+ /* Disable "min-width:auto"/"min-height:auto" to focus purely on
+ later channels of influence. */
+ min-width: 0;
+ min-height: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. -->
+
+ <!-- Row 1: no special sizing: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png">
+ </div>
+ <br>
+
+ <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="flex: 0 0 30px">
+ </div>
+ <br>
+
+ <!-- Row 3: min main-size OR min cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 4: max main-size OR max cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ max-height: 6px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 6px;
+ max-height: 10px">
+ </div>
+ <br>
+
+ <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 10px;
+ min-height: 30px">
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-005v.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-005v.html
new file mode 100644
index 0000000000..ed1dcace0f
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-005v.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ CSS Test: Testing how explicit main-size & cross-size constraints
+ influence sizing on non-stretched flexible flex item w/ intrinsic ratio
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
+ <link rel="match" href="flexbox-intrinsic-ratio-005-ref.html">
+ <style>
+ .flexbox {
+ display: flex;
+ flex-direction: row;
+ border: 1px solid black;
+ margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
+ width: 40px;
+ height: 40px;
+
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ float: left; /* For testing in "rows" */
+ }
+ br { clear: both; }
+
+ .flexbox > * {
+ flex: 1;
+ writing-mode: vertical-lr;
+
+ /* Disable "min-width:auto"/"min-height:auto" to focus purely on
+ later channels of influence. */
+ min-width: 0;
+ min-height: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. -->
+
+ <!-- Row 1: no special sizing: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png">
+ </div>
+ <br>
+
+ <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="flex: 1 1 30px">
+ </div>
+ <br>
+
+ <!-- Row 3: min main-size OR min cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 4: max main-size OR max cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ max-height: 6px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 6px;
+ max-height: 10px">
+ </div>
+ <br>
+
+ <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 10px;
+ min-height: 30px">
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-006v.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-006v.html
new file mode 100644
index 0000000000..8c12fad8c7
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-intrinsic-ratio-006v.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>
+ CSS Test: Testing how explicit main-size & cross-size constraints
+ influence sizing on non-stretched flexible flex item w/ intrinsic ratio
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size">
+ <link rel="match" href="flexbox-intrinsic-ratio-006-ref.html">
+ <style>
+ .flexbox {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid black;
+ margin: 0 2px 2px 0; /* (Just for spacing things out, visually) */
+ width: 40px;
+ height: 40px;
+
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ float: left; /* For testing in "rows" */
+ }
+ br { clear: both; }
+
+ .flexbox > * {
+ flex: 1;
+ writing-mode: vertical-lr;
+
+ /* Disable "min-width:auto"/"min-height:auto" to focus purely on
+ later channels of influence. */
+ min-width: 0;
+ min-height: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- NOTE: solidblue.png has an intrinsic size of 16px by 16px. -->
+
+ <!-- Row 1: no special sizing: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png">
+ </div>
+ <br>
+
+ <!-- Row 2: Specified main-size, cross-size, or flex-basis: -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="flex: 1 1 30px">
+ </div>
+ <br>
+
+ <!-- Row 3: min main-size OR min cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ min-height: 34px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 34px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 4: max main-size OR max cross-size, or both -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ max-height: 6px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 6px;
+ max-height: 10px">
+ </div>
+ <br>
+
+ <!-- Row 5: min main-size vs. max cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ min-height: 30px">
+ </div>
+ <br>
+
+ <!-- Row 6: min|max main-size vs. explicit cross-size, & vice versa -->
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="min-width: 30px;
+ height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 30px;
+ max-height: 10px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="max-width: 10px;
+ height: 30px">
+ </div>
+ <div class="flexbox">
+ <img src="support/solidblue.png" style="width: 10px;
+ min-height: 30px">
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-002v.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-002v.xhtml
new file mode 100644
index 0000000000..a02e3406c9
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-002v.xhtml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- Testcase with margin/border/padding on flex items
+ and with various writing-modes on the items. -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>
+ CSS Test: Testing margins, borders, and padding on flex items in a horizontal flex container
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
+ <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#layout-algorithm"/>
+ <link rel="match" href="flexbox-mbp-horiz-002-ref.xhtml"/>
+ <style>
+ div { height: 100px; border: 0; }
+ div.flexbox {
+ width: 200px;
+ font-size: 10px;
+ display: flex;
+ }
+ div.a {
+ flex: 1 0 9px;
+ background: lightgreen;
+ margin-left: 1px;
+ margin-right: 3px;
+ border-style: dotted;
+ border-left-width: 2px;
+ border-right-width: 4px;
+ padding-left: 5px;
+ padding-right: 6px;
+ writing-mode: vertical-lr;
+ }
+ div.b {
+ flex: 2 0 1px;
+ background: yellow;
+ margin-left: 2px;
+ margin-right: 4px;
+ border-style: dashed;
+ border-left-width: 7px;
+ border-right-width: 3px;
+ padding-left: 1px;
+ padding-right: 2px;
+ writing-mode: vertical-rl;
+ }
+ div.c {
+ flex: 3 0 40px;
+ background: orange;
+ writing-mode: sideways-lr;
+ }
+ div.flexNone {
+ flex: none;
+ background: pink;
+ writing-mode: vertical-lr;
+ }
+ div.flexBasis {
+ flex: 0 0 20px;
+ background: gray;
+ writing-mode: sideways-rl;
+ }
+ div.spacer {
+ width: 15px;
+ height: 15px;
+ background: purple;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="flexbox"><div class="a"></div><div class="b"/></div>
+ <div class="flexbox"><div class="a"/><div class="c"/></div>
+ <div class="flexbox"><div class="a"/>
+ <div class="flexNone"><div class="spacer"/></div>
+ </div>
+ <div class="flexbox"><div class="b"/><div class="c"/></div>
+ <div class="flexbox"><div class="b"/>
+ <div class="flexNone"><div class="spacer"/><div class="spacer"/></div>
+ </div>
+
+ <div class="flexbox">
+ <div class="a"/><div class="b"/><div class="flexBasis"/><div class="c"/>
+ </div>
+ </body>
+</html>
+
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-003v.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-003v.xhtml
new file mode 100644
index 0000000000..8baef30227
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-003v.xhtml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- Testcase with border/padding on a flex container and on its children -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>
+ CSS Test: Testing borders and padding on a horizontal flex container and its flex items
+ (with a vertical writing-mode on the flex items).
+ </title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"/>
+ <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#layout-algorithm"/>
+ <link rel="match" href="flexbox-mbp-horiz-003-ref.xhtml"/>
+ <style>
+ div { height: 20px; border: 0; }
+ div.flexbox {
+ width: 200px;
+ display: flex;
+ margin-bottom: 2px;
+ }
+
+ <!-- customizations for flex container border/padding -->
+ .borderA {
+ border-style: dashed;
+ border-color: purple;
+ border-top-width: 6px;
+ border-right-width: 4px;
+ border-bottom-width: 2px;
+ border-left-width: 8px;
+ }
+
+ .borderB {
+ border-style: dashed;
+ border-color: purple;
+ border-top-width: 4px;
+ border-right-width: 5px;
+ border-bottom-width: 6px;
+ border-left-width: 7px;
+ }
+
+ .paddingA {
+ padding: 4px 3px 2px 1px;
+ }
+
+ .paddingB {
+ padding: 8px 11px 14px 17px;
+ }
+
+ div.child1 {
+ flex: 1 0 24px;
+ background: lightgreen;
+ border-style: dotted;
+ border-left-width: 2px;
+ border-right-width: 4px;
+ writing-mode: vertical-rl;
+ }
+ div.child2 {
+ flex: 2 0 10px;
+ background: yellow;
+ border-style: dashed;
+ border-left-width: 7px;
+ border-right-width: 3px;
+ writing-mode: vertical-lr;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="flexbox borderA"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox borderA paddingA"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox borderA paddingB"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox borderB"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox borderB paddingA"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox borderB paddingB"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox paddingA"
+ ><div class="child1"/><div class="child2"/></div>
+ <div class="flexbox paddingB"
+ ><div class="child1"/><div class="child2"/></div>
+ </body>
+</html>
+
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010-ref.html
new file mode 100644
index 0000000000..e488416412
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010-ref.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>CSS Reftest Reference</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: block;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 150px;
+ width: 500px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+
+ .container > .hl, .container > .hr {
+ /* In the testcase, these items are stretched vertically
+ via the default "align-self:stretch" behavior, and because
+ they have a height of "auto".
+ (The rest of the items have a non-auto height from "inline-size"
+ and their vertical writing-mode, so those ones do not stretch.) */
+ height: 118px;
+ }
+
+ .container.hl > * { float: left; }
+ .container.hr > * { float: right; }
+
+ </style>
+</head>
+<body>
+
+<div class="container hl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container hl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container hr">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container hr">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010.html
new file mode 100644
index 0000000000..55c50e850f
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-010.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: Testing a mix of flex items with various values for
+ 'writing-mode' / 'direction' in a horizontal row-oriented flex container.
+ </title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-direction-property">
+ <link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+ <link rel="match" href="flexbox-writing-mode-010-ref.html">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: flex;
+ flex-direction: row;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 150px;
+ width: 500px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+ </style>
+</head>
+<body>
+
+<div class="container hl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container hl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container hr">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container hr">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011-ref.html
new file mode 100644
index 0000000000..8b926490b6
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011-ref.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>CSS Reftest Reference</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: block;
+ float: left;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 500px;
+ width: 150px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+
+ /* This really floats to top ('logical left'), since all the containers
+ have a vertical writing mode. */
+ float: left;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+
+
+ .container > .vl, .container > .vr,
+ .container > .vl_rtl, .container > .vr_rtl {
+ /* In the testcase, these items are stretched horizontally
+ via the default "align-self:stretch" behavior, and because
+ they have a width of "auto".
+ (The rest of the items have a non-auto width from "inline-size"
+ and their horizontal writing-mode, so those ones do not stretch.) */
+ width: 126px;
+ }
+ </style>
+</head>
+<body>
+
+<div class="container vl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container vr">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vr">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011.html
new file mode 100644
index 0000000000..6114e19275
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-011.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: Testing a mix of flex items with various values for
+ 'writing-mode' / 'direction' in a vertical row-oriented flex container.
+ </title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-direction-property">
+ <link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+ <link rel="match" href="flexbox-writing-mode-011-ref.html">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: flex;
+ flex-direction: row;
+ float: left;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 500px;
+ width: 150px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+ </style>
+</head>
+<body>
+
+<div class="container vl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container vr">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vr">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012-ref.html
new file mode 100644
index 0000000000..c03358be42
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012-ref.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>CSS Reftest Reference</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: block;
+ float: left;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 500px;
+ width: 150px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+
+ /* This really floats to top ('logical left'), since all the containers
+ have a vertical writing mode. */
+ float: right;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+
+
+ .container > .vl, .container > .vr,
+ .container > .vl_rtl, .container > .vr_rtl {
+ /* In the testcase, these items are stretched horizontally
+ via the default "align-self:stretch" behavior, and because
+ they have a width of "auto".
+ (The rest of the items have a non-auto width from "inline-size"
+ and their horizontal writing-mode, so those ones do not stretch.) */
+ width: 126px;
+ }
+ </style>
+</head>
+<body>
+
+<div class="container vl_rtl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vl_rtl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container vr_rtl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vr_rtl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012.html
new file mode 100644
index 0000000000..a7b05f178d
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-012.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: Testing a mix of flex items with various values for
+ 'writing-mode' / 'direction' in a vertical row-oriented flex container
+ with 'direction' flipped.
+ </title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-direction-property">
+ <link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+ <link rel="match" href="flexbox-writing-mode-012-ref.html">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: flex;
+ flex-direction: row;
+ float: left;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 500px;
+ width: 150px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+ </style>
+</head>
+<body>
+
+<div class="container vl_rtl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vl_rtl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container vr_rtl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vr_rtl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013-ref.html
new file mode 100644
index 0000000000..2a27003a5c
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013-ref.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>CSS Reftest Reference</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: block;
+ float: left;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 500px;
+ width: 150px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ nocollapse {
+ /* special element to disable margin-collapsing */
+ display: block;
+ overflow: hidden;
+ height: 0;
+ }
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+
+ .container > .vl, .container > .vr,
+ .container > .vl_rtl, .container > .vr_rtl {
+ /* In the testcase, these items are stretched horizontally
+ via the default "align-self:stretch" behavior, and because
+ they have a width of "auto".
+ (The rest of the items have a non-auto width from "inline-size"
+ and their horizontal writing-mode, so those ones do not stretch.) */
+ width: 126px;
+ }
+ </style>
+</head>
+<body>
+
+<div class="container hl">
+ <span class="hl small">a b c</span> <nocollapse></nocollapse>
+ <span class="hl big">d e</span> <nocollapse></nocollapse>
+ <span class="hr small">a b c</span> <nocollapse></nocollapse>
+ <span class="hr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl small">a b c</span> <nocollapse></nocollapse>
+ <span class="vl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container hl">
+ <span class="vr small">a b c</span> <nocollapse></nocollapse>
+ <span class="vr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vl_rtl big">d e</span> <nocollapse></nocollapse>
+ <span class="vr_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vr_rtl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container hr">
+ <span class="hl small">a b c</span> <nocollapse></nocollapse>
+ <span class="hl big">d e</span> <nocollapse></nocollapse>
+ <span class="hr small">a b c</span> <nocollapse></nocollapse>
+ <span class="hr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl small">a b c</span> <nocollapse></nocollapse>
+ <span class="vl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container hr">
+ <span class="vr small">a b c</span> <nocollapse></nocollapse>
+ <span class="vr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vl_rtl big">d e</span> <nocollapse></nocollapse>
+ <span class="vr_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vr_rtl big">d e</span> <nocollapse></nocollapse>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013.html
new file mode 100644
index 0000000000..a5d483c442
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-013.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: Testing a mix of flex items with various values for
+ 'writing-mode' / 'direction' in a horizontal column-oriented flex container.
+ </title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-direction-property">
+ <link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+ <link rel="match" href="flexbox-writing-mode-013-ref.html">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: flex;
+ flex-direction: column;
+ float: left;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 500px;
+ width: 150px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+ </style>
+</head>
+<body>
+
+<div class="container hl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container hl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container hr">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container hr">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014-ref.html
new file mode 100644
index 0000000000..4e4f5904a1
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014-ref.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>CSS Reftest Reference</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: block;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 150px;
+ width: 500px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ nocollapse {
+ /* special element to disable margin-collapsing */
+ display: block;
+ overflow: hidden;
+ height: 0;
+ }
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+
+ .container > .hl, .container > .hr {
+ /* In the testcase, these items are stretched vertically
+ via the default "align-self:stretch" behavior, and because
+ they have a height of "auto".
+ (The rest of the items have a non-auto height from "inline-size"
+ and their vertical writing-mode, so those ones do not stretch.) */
+ height: 118px;
+ }
+ </style>
+</head>
+<body>
+
+<div class="container vl">
+ <span class="hl small">a b c</span> <nocollapse></nocollapse>
+ <span class="hl big">d e</span> <nocollapse></nocollapse>
+ <span class="hr small">a b c</span> <nocollapse></nocollapse>
+ <span class="hr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl small">a b c</span> <nocollapse></nocollapse>
+ <span class="vl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container vl">
+ <span class="vr small">a b c</span> <nocollapse></nocollapse>
+ <span class="vr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vl_rtl big">d e</span> <nocollapse></nocollapse>
+ <span class="vr_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vr_rtl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container vr">
+ <span class="hl small">a b c</span> <nocollapse></nocollapse>
+ <span class="hl big">d e</span> <nocollapse></nocollapse>
+ <span class="hr small">a b c</span> <nocollapse></nocollapse>
+ <span class="hr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl small">a b c</span> <nocollapse></nocollapse>
+ <span class="vl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container vr">
+ <span class="vr small">a b c</span> <nocollapse></nocollapse>
+ <span class="vr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vl_rtl big">d e</span> <nocollapse></nocollapse>
+ <span class="vr_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vr_rtl big">d e</span> <nocollapse></nocollapse>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014.html
new file mode 100644
index 0000000000..1a5443279a
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-014.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: Testing a mix of flex items with various values for
+ 'writing-mode' / 'direction' in a vertical column-oriented flex container.
+ </title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-direction-property">
+ <link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+ <link rel="match" href="flexbox-writing-mode-014-ref.html">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: flex;
+ flex-direction: column;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 150px;
+ width: 500px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+ </style>
+</head>
+<body>
+
+<div class="container vl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container vr">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vr">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015-ref.html
new file mode 100644
index 0000000000..a236ca11d5
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015-ref.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>CSS Reftest Reference</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: block;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 150px;
+ width: 500px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ nocollapse {
+ /* special element to disable margin-collapsing */
+ display: block;
+ overflow: hidden;
+ height: 0;
+ }
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+
+ .container > .hl, .container > .hr {
+ /* In the testcase, these items are stretched vertically
+ via the default "align-self:stretch" behavior, and because
+ they have a height of "auto".
+ (The rest of the items have a non-auto height from "inline-size"
+ and their vertical writing-mode, so those ones do not stretch.) */
+ height: 118px;
+ }
+ </style>
+</head>
+<body>
+
+<div class="container vl_rtl">
+ <span class="hl small">a b c</span> <nocollapse></nocollapse>
+ <span class="hl big">d e</span> <nocollapse></nocollapse>
+ <span class="hr small">a b c</span> <nocollapse></nocollapse>
+ <span class="hr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl small">a b c</span> <nocollapse></nocollapse>
+ <span class="vl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container vl_rtl">
+ <span class="vr small">a b c</span> <nocollapse></nocollapse>
+ <span class="vr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vl_rtl big">d e</span> <nocollapse></nocollapse>
+ <span class="vr_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vr_rtl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container vr_rtl">
+ <span class="hl small">a b c</span> <nocollapse></nocollapse>
+ <span class="hl big">d e</span> <nocollapse></nocollapse>
+ <span class="hr small">a b c</span> <nocollapse></nocollapse>
+ <span class="hr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl small">a b c</span> <nocollapse></nocollapse>
+ <span class="vl big">d e</span> <nocollapse></nocollapse>
+</div>
+<div class="container vr_rtl">
+ <span class="vr small">a b c</span> <nocollapse></nocollapse>
+ <span class="vr big">d e</span> <nocollapse></nocollapse>
+ <span class="vl_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vl_rtl big">d e</span> <nocollapse></nocollapse>
+ <span class="vr_rtl small">a b c</span><nocollapse></nocollapse>
+ <span class="vr_rtl big">d e</span> <nocollapse></nocollapse>
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015.html
new file mode 100644
index 0000000000..af1f9b8456
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-writing-mode-015.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+ <title>
+ CSS Test: Testing a mix of flex items with various values for
+ 'writing-mode' / 'direction' in a vertical column-oriented flex container
+ with 'direction' flipped.
+ </title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-direction-property">
+ <link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+ <link rel="match" href="flexbox-writing-mode-015-ref.html">
+ <link rel="stylesheet" type="text/css" href="support/ahem.css">
+ <style>
+ .container {
+ display: flex;
+ flex-direction: column;
+ border: 2px solid purple;
+ padding: 2px;
+ margin-bottom: 2em;
+ height: 150px;
+ width: 500px;
+ }
+
+ span {
+ display: block;
+ background: lightgrey;
+ border: 2px solid black;
+ /* If browser supports it, signal the inline direction with border color: */
+ border-block-start-color: orange;
+ border-inline-start-color: lime;
+
+ margin: 11px 13px 17px 7px;
+ inline-size: 6px;
+ }
+
+ .small { font: 12px Ahem; }
+ .big { font: 20px Ahem; }
+
+ .hl { writing-mode: horizontal-tb; direction: ltr; }
+ .hr { writing-mode: horizontal-tb; direction: rtl; }
+ .vl { writing-mode: vertical-lr; direction: ltr; }
+ .vr { writing-mode: vertical-rl; direction: ltr; }
+ .vl_rtl { writing-mode: vertical-lr; direction: rtl; }
+ .vr_rtl { writing-mode: vertical-rl; direction: rtl; }
+ </style>
+</head>
+<body>
+
+<div class="container vl_rtl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vl_rtl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+<div class="container vr_rtl">
+ <span class="hl small">a b c</span>
+ <span class="hl big">d e</span>
+ <span class="hr small">a b c</span>
+ <span class="hr big">d e</span>
+ <span class="vl small">a b c</span>
+ <span class="vl big">d e</span>
+</div>
+<div class="container vr_rtl">
+ <span class="vr small">a b c</span>
+ <span class="vr big">d e</span>
+ <span class="vl_rtl small">a b c</span>
+ <span class="vl_rtl big">d e</span>
+ <span class="vr_rtl small">a b c</span>
+ <span class="vr_rtl big">d e</span>
+</div>
+
+</body>
+</html>
diff --git a/layout/style/CSS.cpp b/layout/style/CSS.cpp
index b70f67a505..1078945ee5 100644
--- a/layout/style/CSS.cpp
+++ b/layout/style/CSS.cpp
@@ -62,12 +62,6 @@ CSS::Supports(const GlobalObject& aGlobal,
return false;
}
- if (info.mStyleBackendType == StyleBackendType::Servo) {
- NS_ConvertUTF16toUTF8 property(aProperty);
- NS_ConvertUTF16toUTF8 value(aValue);
- return Servo_CSSSupports(&property, &value);
- }
-
nsCSSParser parser;
return parser.EvaluateSupportsDeclaration(aProperty, aValue, info.mDocURI,
info.mBaseURI, info.mPrincipal);
@@ -86,13 +80,10 @@ CSS::Supports(const GlobalObject& aGlobal,
return false;
}
- if (info.mStyleBackendType == StyleBackendType::Servo) {
- MOZ_CRASH("stylo: CSS.supports() with arguments is not yet implemented");
- }
-
nsCSSParser parser;
return parser.EvaluateSupportsCondition(aCondition, info.mDocURI,
- info.mBaseURI, info.mPrincipal);
+ info.mBaseURI, info.mPrincipal,
+ css::SupportsParsingSettings::ImpliedParentheses);
}
/* static */ void
diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index 6a65f06646..b981a553f3 100644
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -257,7 +257,8 @@ public:
bool EvaluateSupportsCondition(const nsAString& aCondition,
nsIURI* aDocURL,
nsIURI* aBaseURL,
- nsIPrincipal* aDocPrincipal);
+ nsIPrincipal* aDocPrincipal,
+ SupportsParsingSettings aSettings = SupportsParsingSettings::Normal);
bool ParseCounterStyleName(const nsAString& aBuffer,
nsIURI* aURL,
@@ -2457,7 +2458,8 @@ bool
CSSParserImpl::EvaluateSupportsCondition(const nsAString& aDeclaration,
nsIURI* aDocURL,
nsIURI* aBaseURL,
- nsIPrincipal* aDocPrincipal)
+ nsIPrincipal* aDocPrincipal,
+ SupportsParsingSettings aSettings)
{
nsCSSScanner scanner(aDeclaration, 0);
css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aDocURL);
@@ -2465,7 +2467,13 @@ CSSParserImpl::EvaluateSupportsCondition(const nsAString& aDeclaration,
nsAutoSuppressErrors suppressErrors(this);
bool conditionMet;
- bool parsedOK = ParseSupportsCondition(conditionMet) && !GetToken(true);
+ bool parsedOK;
+
+ if (aSettings == SupportsParsingSettings::ImpliedParentheses) {
+ parsedOK = ParseSupportsConditionInParensInsideParens(conditionMet) && !GetToken(true);
+ } else {
+ parsedOK = ParseSupportsCondition(conditionMet) && !GetToken(true);
+ }
CLEAR_ERROR();
ReleaseScanner();
@@ -18245,10 +18253,11 @@ bool
nsCSSParser::EvaluateSupportsCondition(const nsAString& aCondition,
nsIURI* aDocURL,
nsIURI* aBaseURL,
- nsIPrincipal* aDocPrincipal)
+ nsIPrincipal* aDocPrincipal,
+ SupportsParsingSettings aSettings)
{
return static_cast<CSSParserImpl*>(mImpl)->
- EvaluateSupportsCondition(aCondition, aDocURL, aBaseURL, aDocPrincipal);
+ EvaluateSupportsCondition(aCondition, aDocURL, aBaseURL, aDocPrincipal, aSettings);
}
bool
diff --git a/layout/style/nsCSSParser.h b/layout/style/nsCSSParser.h
index 37cd325f20..e3d526659d 100644
--- a/layout/style/nsCSSParser.h
+++ b/layout/style/nsCSSParser.h
@@ -34,6 +34,12 @@ namespace css {
class Rule;
class Declaration;
class StyleRule;
+
+enum class SupportsParsingSettings {
+ Normal,
+ ImpliedParentheses
+};
+
} // namespace css
} // namespace mozilla
@@ -257,11 +263,17 @@ public:
/**
* Parse an @supports condition and returns the result of evaluating the
* condition.
+ *
+ * The one-argument CSS.supports() allows for providing an @supports condition
+ * without parentheses, i.e. the parentheses are "implied". In such a case,
+ * aSettings can be set to ImpliedParentheses.
*/
bool EvaluateSupportsCondition(const nsAString& aCondition,
nsIURI* aDocURL,
nsIURI* aBaseURL,
- nsIPrincipal* aDocPrincipal);
+ nsIPrincipal* aDocPrincipal,
+ mozilla::css::SupportsParsingSettings aSettings
+ = mozilla::css::SupportsParsingSettings::Normal);
typedef void (*VariableEnumFunc)(const nsAString&, void*);
diff --git a/layout/style/test/test_css_supports.html b/layout/style/test/test_css_supports.html
index fa5b3fdcba..a500a3798b 100644
--- a/layout/style/test/test_css_supports.html
+++ b/layout/style/test/test_css_supports.html
@@ -22,6 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=779917
function runTest()
{
var passingConditions = [
+ "color: green",
"(color: green)",
"((color: green))",
"(color: green !important)",
@@ -69,7 +70,6 @@ function runTest()
"(color: green) or an-extension(that is [unbalanced)",
"not(unknown: unknown)",
"(color: green) or(color: blue)",
- "color: green",
"(color: green;)",
"(font-family: 'Helvetica\n",
"(font-family: 'Helvetica\n')",
diff --git a/media/mtransport/nr_socket_prsock.cpp b/media/mtransport/nr_socket_prsock.cpp
index 80e5ef51e4..3fd223349c 100644
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -858,6 +858,10 @@ int NrSocket::connect(nr_transport_addr *addr) {
PRNetAddr naddr;
int32_t connect_status, getsockname_status;
+ // TODO: Add TLS layer with nsISocketProviderService?
+ if (addr->tls_host[0] != '\0')
+ ABORT(R_INTERNAL);
+
if ((r=nr_transport_addr_to_praddr(addr, &naddr)))
ABORT(r);
@@ -1840,7 +1844,7 @@ void NrTcpSocketIpc::close() {
}
int NrTcpSocketIpc::connect(nr_transport_addr *addr) {
- nsCString remote_addr, local_addr;
+ nsCString remote_addr, local_addr, tls_host;
int32_t remote_port, local_port;
int r, _status;
if ((r=nr_transport_addr_get_addrstring_and_port(addr,
@@ -1856,6 +1860,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) {
ABORT(r);
}
+ tls_host = addr->tls_host;
+
state_ = mirror_state_ = NR_CONNECTING;
RUN_ON_THREAD(io_thread_,
mozilla::WrapRunnable(RefPtr<NrTcpSocketIpc>(this),
@@ -1863,7 +1869,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) {
remote_addr,
static_cast<uint16_t>(remote_port),
local_addr,
- static_cast<uint16_t>(local_port)),
+ static_cast<uint16_t>(local_port),
+ tls_host),
NS_DISPATCH_NORMAL);
// Make caller wait for ready to write.
@@ -1939,7 +1946,8 @@ int NrTcpSocketIpc::accept(nr_transport_addr *addrp, nr_socket **sockp) {
void NrTcpSocketIpc::connect_i(const nsACString &remote_addr,
uint16_t remote_port,
const nsACString &local_addr,
- uint16_t local_port) {
+ uint16_t local_port,
+ const nsACString &tls_host) {
ASSERT_ON_THREAD(io_thread_);
mirror_state_ = NR_CONNECTING;
@@ -1948,11 +1956,21 @@ void NrTcpSocketIpc::connect_i(const nsACString &remote_addr,
// Bug 1285330: put filtering back in here
- // XXX remove remote!
- socket_child_->SendWindowlessOpenBind(this,
- remote_addr, remote_port,
- local_addr, local_port,
- /* use ssl */ false);
+ if (tls_host.IsEmpty()) {
+ // XXX remove remote!
+ socket_child_->SendWindowlessOpenBind(this,
+ remote_addr, remote_port,
+ local_addr, local_port,
+ /* use ssl */ false,
+ /* reuse addr port */ true);
+ } else {
+ // XXX remove remote!
+ socket_child_->SendWindowlessOpenBind(this,
+ tls_host, remote_port,
+ local_addr, local_port,
+ /* use ssl */ true,
+ /* reuse addr port */ true);
+ }
}
void NrTcpSocketIpc::write_i(nsAutoPtr<InfallibleTArray<uint8_t>> arr,
diff --git a/media/mtransport/nr_socket_prsock.h b/media/mtransport/nr_socket_prsock.h
index 5ed9a6a219..7d372ccb16 100644
--- a/media/mtransport/nr_socket_prsock.h
+++ b/media/mtransport/nr_socket_prsock.h
@@ -369,7 +369,8 @@ private:
void connect_i(const nsACString &remote_addr,
uint16_t remote_port,
const nsACString &local_addr,
- uint16_t local_port);
+ uint16_t local_port,
+ const nsACString &tls_host);
void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf,
uint32_t tracking_number);
void close_i();
diff --git a/media/mtransport/nricectx.cpp b/media/mtransport/nricectx.cpp
index be50f50169..75d3d2519d 100644
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -108,6 +108,7 @@ MOZ_MTLOG_MODULE("mtransport")
const char kNrIceTransportUdp[] = "udp";
const char kNrIceTransportTcp[] = "tcp";
+const char kNrIceTransportTls[] = "tls";
static bool initialized = false;
@@ -210,6 +211,9 @@ nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server) const {
server->transport = IPPROTO_UDP;
} else if (transport_ == kNrIceTransportTcp) {
server->transport = IPPROTO_TCP;
+ } else if (transport_ == kNrIceTransportTls) {
+ server->transport = IPPROTO_TCP;
+ server->tls = 1;
} else {
MOZ_MTLOG(ML_ERROR, "Unsupported STUN server transport: " << transport_);
return NS_ERROR_FAILURE;
@@ -586,6 +590,7 @@ NrIceCtx::Initialize(const std::string& ufrag,
nsCString mapping_type;
nsCString filtering_type;
bool block_udp = false;
+ bool block_tcp = false;
nsresult rv;
nsCOMPtr<nsIPrefService> pref_service =
@@ -604,6 +609,9 @@ NrIceCtx::Initialize(const std::string& ufrag,
rv = pref_branch->GetBoolPref(
"media.peerconnection.nat_simulator.block_udp",
&block_udp);
+ rv = pref_branch->GetBoolPref(
+ "media.peerconnection.nat_simulator.block_tcp",
+ &block_tcp);
}
}
@@ -614,6 +622,7 @@ NrIceCtx::Initialize(const std::string& ufrag,
test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get());
test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get());
test_nat->block_udp_ = block_udp;
+ test_nat->block_tcp_ = block_tcp;
test_nat->enabled_ = true;
SetNat(test_nat);
}
diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h
index ce104ac317..87122121e5 100644
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -90,6 +90,7 @@ class NrIceMediaStream;
extern const char kNrIceTransportUdp[];
extern const char kNrIceTransportTcp[];
+extern const char kNrIceTransportTls[];
class NrIceStunServer {
public:
diff --git a/media/mtransport/test_nr_socket.cpp b/media/mtransport/test_nr_socket.cpp
index e7dad79cd1..fb2de3096e 100644
--- a/media/mtransport/test_nr_socket.cpp
+++ b/media/mtransport/test_nr_socket.cpp
@@ -200,6 +200,7 @@ int TestNat::create_socket_factory(nr_socket_factory **factorypp) {
TestNrSocket::TestNrSocket(TestNat *nat)
: nat_(nat),
+ tls_(false),
timer_handle_(nullptr) {
nat_->insert_socket(this);
}
@@ -473,6 +474,10 @@ int TestNrSocket::connect(nr_transport_addr *addr) {
return R_INTERNAL;
}
+ if (addr->tls_host[0] != '\0') {
+ tls_ = true;
+ }
+
if (!nat_->enabled_
|| addr->protocol==IPPROTO_UDP // Horrible hack to allow default address
// discovery to work. Only works because
@@ -508,6 +513,24 @@ int TestNrSocket::connect(nr_transport_addr *addr) {
}
int TestNrSocket::write(const void *msg, size_t len, size_t *written) {
+ UCHAR *buf = static_cast<UCHAR*>(const_cast<void*>(msg));
+ if (nat_->block_stun_ && nr_is_stun_message(buf, len)) {
+ // Should cause this socket to be abandoned
+ r_log(LOG_GENERIC, LOG_DEBUG,
+ "TestNrSocket %s dropping outgoing TCP "
+ "because it is configured to drop STUN",
+ my_addr().as_string);
+ return R_INTERNAL;
+ }
+
+ if (nat_->block_tcp_ && !tls_) {
+ // Should cause this socket to be abandoned
+ r_log(LOG_GENERIC, LOG_DEBUG,
+ "TestNrSocket %s dropping outgoing TCP "
+ "because it is configured to drop TCP",
+ my_addr().as_string);
+ return R_INTERNAL;
+ }
if (port_mappings_.empty()) {
// The no-nat case, just pass call through.
@@ -518,7 +541,11 @@ int TestNrSocket::write(const void *msg, size_t len, size_t *written) {
} else {
destroy_stale_port_mappings();
if (port_mappings_.empty()) {
- return -1;
+ r_log(LOG_GENERIC, LOG_DEBUG,
+ "TestNrSocket %s dropping outgoing TCP "
+ "because the port mapping was stale",
+ my_addr().as_string);
+ return R_INTERNAL;
}
// This is TCP only
MOZ_ASSERT(port_mappings_.size() == 1);
@@ -533,18 +560,34 @@ int TestNrSocket::write(const void *msg, size_t len, size_t *written) {
}
int TestNrSocket::read(void *buf, size_t maxlen, size_t *len) {
+ int r;
if (port_mappings_.empty()) {
- return internal_socket_->read(buf, maxlen, len);
+ r = internal_socket_->read(buf, maxlen, len);
} else {
MOZ_ASSERT(port_mappings_.size() == 1);
- int bytesRead =
- port_mappings_.front()->external_socket_->read(buf, maxlen, len);
- if (bytesRead > 0 && nat_->refresh_on_ingress_) {
+ r = port_mappings_.front()->external_socket_->read(buf, maxlen, len);
+ if (!r && nat_->refresh_on_ingress_) {
port_mappings_.front()->last_used_ = PR_IntervalNow();
}
- return bytesRead;
}
+
+ if (r) {
+ return r;
+ }
+
+ if (nat_->block_tcp_ && !tls_) {
+ // Should cause this socket to be abandoned
+ return R_INTERNAL;
+ }
+
+ UCHAR *cbuf = static_cast<UCHAR*>(const_cast<void*>(buf));
+ if (nat_->block_stun_ && nr_is_stun_message(cbuf, *len)) {
+ // Should cause this socket to be abandoned
+ return R_INTERNAL;
+ }
+
+ return r;
}
int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg,
diff --git a/media/mtransport/test_nr_socket.h b/media/mtransport/test_nr_socket.h
index 91c9030f17..a47a88beb9 100644
--- a/media/mtransport/test_nr_socket.h
+++ b/media/mtransport/test_nr_socket.h
@@ -137,6 +137,7 @@ class TestNat {
refresh_on_ingress_(false),
block_udp_(false),
block_stun_(false),
+ block_tcp_(false),
delay_stun_resp_ms_(0),
sockets_() {}
@@ -168,6 +169,7 @@ class TestNat {
bool refresh_on_ingress_;
bool block_udp_;
bool block_stun_;
+ bool block_tcp_;
/* Note: this can only delay a single response so far (bug 1253657) */
uint32_t delay_stun_resp_ms_;
@@ -319,6 +321,7 @@ class TestNrSocket : public NrSocketBase {
// same nat.
RefPtr<NrSocketBase> internal_socket_;
RefPtr<TestNat> nat_;
+ bool tls_;
// Since our comparison logic is different depending on what kind of NAT
// we simulate, and the STL does not make it very easy to switch out the
// comparison function at runtime, and these lists are going to be very
diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c
index e48b7b5e1a..879b77933e 100644
--- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c
@@ -666,6 +666,14 @@ static int nr_ice_candidate_resolved_cb(void *cb_arg, nr_transport_addr *addr)
if(r=nr_transport_addr_copy(&cand->stun_server_addr,addr))
ABORT(r);
+ if (cand->stun_server->tls) {
+ /* Copy over the DNS name; needed for TLS. There is already a null at the
+ * end of the buffer, leave it there. */
+ strncpy(cand->stun_server_addr.tls_host,
+ cand->stun_server->u.dnsname.host,
+ sizeof(cand->stun_server_addr.tls_host) - 1);
+ }
+
if (cand->tcp_type == TCP_TYPE_PASSIVE || cand->tcp_type == TCP_TYPE_SO){
if (r=nr_socket_multi_tcp_stun_server_connect(cand->osock, addr))
ABORT(r);
diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
index cc79304f08..1e815ac2ac 100644
--- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
@@ -63,6 +63,7 @@ typedef struct nr_ice_stun_server_ {
} u;
int id;
int transport;
+ int tls; /* Whether to use TLS or not */
} nr_ice_stun_server;
typedef struct nr_ice_turn_server_ {
diff --git a/media/mtransport/third_party/nICEr/src/net/transport_addr.h b/media/mtransport/third_party/nICEr/src/net/transport_addr.h
index dfec633291..06c8b8c9c5 100644
--- a/media/mtransport/third_party/nICEr/src/net/transport_addr.h
+++ b/media/mtransport/third_party/nICEr/src/net/transport_addr.h
@@ -66,6 +66,7 @@ typedef struct nr_transport_addr_ {
/* A string version.
56 = 5 ("IP6:[") + 39 (ipv6 address) + 2 ("]:") + 5 (port) + 4 (/UDP) + 1 (null) */
char as_string[56];
+ char tls_host[256];
} nr_transport_addr;
typedef struct nr_transport_addr_mask_ {
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index 3b4363a13c..ad87fa1f91 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -335,6 +335,7 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
, mSTSThread(nullptr)
, mAllowIceLoopback(false)
, mAllowIceLinkLocal(false)
+ , mForceIceTcp(false)
, mMedia(nullptr)
, mUuidGen(MakeUnique<PCUuidGenerator>())
, mNumAudioStreams(0)
@@ -365,6 +366,8 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
"media.peerconnection.ice.loopback", false);
mAllowIceLinkLocal = Preferences::GetBool(
"media.peerconnection.ice.link_local", false);
+ mForceIceTcp = Preferences::GetBool(
+ "media.peerconnection.ice.force_ice_tcp", false);
#endif
memset(mMaxReceiving, 0, sizeof(mMaxReceiving));
memset(mMaxSending, 0, sizeof(mMaxSending));
@@ -526,8 +529,8 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer)
if (!(isStun || isStuns || isTurn || isTurns)) {
return NS_ERROR_FAILURE;
}
- if (isTurns || isStuns) {
- continue; // TODO: Support TURNS and STUNS (Bug 1056934)
+ if (isStuns) {
+ continue; // TODO: Support STUNS (Bug 1056934)
}
nsAutoCString spec;
rv = url->GetSpec(spec);
@@ -576,6 +579,11 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer)
if (port == -1)
port = (isStuns || isTurns)? 5349 : 3478;
+ if (isStuns || isTurns) {
+ // Should we barf if transport is set to udp or something?
+ transport = "tls";
+ }
+
// First check the known good ports for webrtc
bool knownGoodPort = false;
for (int i = 0; !knownGoodPort && gGoodWebrtcPortList[i]; i++) {
@@ -2255,6 +2263,11 @@ NS_IMETHODIMP
PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
PC_AUTO_ENTER_API_CALL(true);
+ if (mForceIceTcp && std::string::npos != std::string(aCandidate).find(" UDP ")) {
+ CSFLogError(logTag, "Blocking remote UDP candidate: %s", aCandidate);
+ return NS_OK;
+ }
+
JSErrorResult rv;
RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
@@ -3106,7 +3119,7 @@ PeerConnectionImpl::SetSignalingState_m(PCImplSignalingState aSignalingState,
mNegotiationNeeded = false;
// If we're rolling back a local offer, we might need to remove some
// transports, but nothing further needs to be done.
- mMedia->ActivateOrRemoveTransports(*mJsepSession);
+ mMedia->ActivateOrRemoveTransports(*mJsepSession, mForceIceTcp);
if (!rollback) {
mMedia->UpdateMediaPipelines(*mJsepSession);
InitializeDataChannel();
@@ -3268,6 +3281,11 @@ PeerConnectionImpl::CandidateReady(const std::string& candidate,
uint16_t level) {
PC_AUTO_ENTER_API_CALL_VOID_RETURN(false);
+ if (mForceIceTcp && std::string::npos != candidate.find(" UDP ")) {
+ CSFLogError(logTag, "Blocking local UDP candidate: %s", candidate.c_str());
+ return;
+ }
+
std::string mid;
bool skipped = false;
nsresult res = mJsepSession->AddLocalIceCandidate(candidate,
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
index 7b53ea1160..098b34249a 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -803,6 +803,7 @@ private:
bool mAllowIceLoopback;
bool mAllowIceLinkLocal;
+ bool mForceIceTcp;
RefPtr<PeerConnectionMedia> mMedia;
// The JSEP negotiation session.
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
index 0d388a8f49..0306b57904 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -457,7 +457,8 @@ PeerConnectionMedia::EnsureTransport_s(size_t aLevel, size_t aComponentCount)
}
void
-PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
+PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession,
+ const bool forceIceTcp)
{
auto transports = aSession.GetTransports();
for (size_t i = 0; i < transports.size(); ++i) {
@@ -480,6 +481,14 @@ PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
RemoveTransportFlow(i, true);
}
+ if (forceIceTcp) {
+ candidates.erase(std::remove_if(candidates.begin(),
+ candidates.end(),
+ [](const std::string & s) {
+ return s.find(" UDP "); }),
+ candidates.end());
+ }
+
RUN_ON_THREAD(
GetSTSThread(),
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
index c0001a5e54..8908e51546 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -270,7 +270,8 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
// Activate or remove ICE transports at the conclusion of offer/answer,
// or when rollback occurs.
- void ActivateOrRemoveTransports(const JsepSession& aSession);
+ void ActivateOrRemoveTransports(const JsepSession& aSession,
+ const bool forceIceTcp);
// Start ICE checks.
void StartIceChecks(const JsepSession& session);
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 4a57e5fcaa..317de736b0 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1467,8 +1467,8 @@ pref("network.http.referer.XOriginTrimmingPolicy", 0);
pref("network.http.referer.XOriginPolicy", 0);
// Include an origin header on non-GET and non-HEAD requests regardless of CORS
-// 0=never send, 1=send when same-origin only, 2=always send
-pref("network.http.sendOriginHeader", 0);
+// 0=never send, 1=send when same-origin only, 2=always send (careful!)
+pref("network.http.sendOriginHeader", 1);
// Controls whether referrer attributes in <a>, <img>, <area>, <iframe>, and <link> are honoured
pref("network.http.enablePerElementReferrer", true);
diff --git a/netwerk/base/nsISocketTransport.idl b/netwerk/base/nsISocketTransport.idl
index 9b5bc23fb7..3525aad5d9 100644
--- a/netwerk/base/nsISocketTransport.idl
+++ b/netwerk/base/nsISocketTransport.idl
@@ -130,6 +130,11 @@ interface nsISocketTransport : nsITransport
void setTimeout(in unsigned long aType, in unsigned long aValue);
/**
+ * True to set addr and port reuse socket options.
+ */
+ void setReuseAddrPort(in bool reuseAddrPort);
+
+ /**
* Values for the aType parameter passed to get/setTimeout.
*/
const unsigned long TIMEOUT_CONNECT = 0;
diff --git a/netwerk/base/nsSocketTransport2.cpp b/netwerk/base/nsSocketTransport2.cpp
index ff5fc3070d..ab20737443 100644
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -737,6 +737,7 @@ nsSocketTransport::nsSocketTransport()
, mProxyTransparentResolvesHost(false)
, mHttpsProxy(false)
, mConnectionFlags(0)
+ , mReuseAddrPort(false)
, mState(STATE_CLOSED)
, mAttached(false)
, mInputClosed(true)
@@ -1354,6 +1355,32 @@ nsSocketTransport::InitiateSocket()
status = PR_SetSocketOption(fd, &opt);
NS_ASSERTION(status == PR_SUCCESS, "unable to make socket non-blocking");
+ if (mReuseAddrPort) {
+ SOCKET_LOG((" Setting port/addr reuse socket options\n"));
+
+ // Set ReuseAddr for TCP sockets to enable having several
+ // sockets bound to same local IP and port
+ PRSocketOptionData opt_reuseaddr;
+ opt_reuseaddr.option = PR_SockOpt_Reuseaddr;
+ opt_reuseaddr.value.reuse_addr = PR_TRUE;
+ status = PR_SetSocketOption(fd, &opt_reuseaddr);
+ if (status != PR_SUCCESS) {
+ SOCKET_LOG((" Couldn't set reuse addr socket option: %d\n",
+ status));
+ }
+
+ // And also set ReusePort for platforms supporting this socket option
+ PRSocketOptionData opt_reuseport;
+ opt_reuseport.option = PR_SockOpt_Reuseport;
+ opt_reuseport.value.reuse_port = PR_TRUE;
+ status = PR_SetSocketOption(fd, &opt_reuseport);
+ if (status != PR_SUCCESS
+ && PR_GetError() != PR_OPERATION_NOT_SUPPORTED_ERROR) {
+ SOCKET_LOG((" Couldn't set reuse port socket option: %d\n",
+ status));
+ }
+ }
+
// disable the nagle algorithm - if we rely on it to coalesce writes into
// full packets the final packet of a multi segment POST/PUT or pipeline
// sequence is delayed a full rtt
@@ -2469,6 +2496,13 @@ nsSocketTransport::SetTimeout(uint32_t type, uint32_t value)
}
NS_IMETHODIMP
+nsSocketTransport::SetReuseAddrPort(bool reuseAddrPort)
+{
+ mReuseAddrPort = reuseAddrPort;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsSocketTransport::SetQoSBits(uint8_t aQoSBits)
{
// Don't do any checking here of bits. Why? Because as of RFC-4594
diff --git a/netwerk/base/nsSocketTransport2.h b/netwerk/base/nsSocketTransport2.h
index 89b75efa57..a61e432b48 100644
--- a/netwerk/base/nsSocketTransport2.h
+++ b/netwerk/base/nsSocketTransport2.h
@@ -295,6 +295,7 @@ private:
bool mProxyTransparentResolvesHost;
bool mHttpsProxy;
uint32_t mConnectionFlags;
+ bool mReuseAddrPort;
// The origin attributes are used to create sockets. The first party domain
// will eventually be used to isolate OCSP cache and is only non-empty when
diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp
index eeaf57f55c..01075d2c0c 100644
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -1686,6 +1686,12 @@ SocketTransportShim::SetTimeout(uint32_t aType, uint32_t aValue)
}
NS_IMETHODIMP
+SocketTransportShim::SetReuseAddrPort(bool aReuseAddrPort)
+{
+ return mWrapped->SetReuseAddrPort(aReuseAddrPort);
+}
+
+NS_IMETHODIMP
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits)
{
return mWrapped->GetQoSBits(aQoSBits);
diff --git a/testing/tools/iceserver/iceserver.py b/testing/tools/iceserver/iceserver.py
index 2089301af8..85d0f3ee54 100644
--- a/testing/tools/iceserver/iceserver.py
+++ b/testing/tools/iceserver/iceserver.py
@@ -10,7 +10,9 @@ import passlib.utils # for saslprep
import copy
import random
import operator
+import os
import platform
+import string
import time
from string import Template
from twisted.internet import reactor, protocol
@@ -715,6 +717,38 @@ def prune_allocations():
del allocations[key]
allocation.close()
+CERT_FILE = "selfsigned.crt"
+KEY_FILE = "private.key"
+
+def create_self_signed_cert(name):
+ from OpenSSL import crypto
+ if os.path.isfile(CERT_FILE) and os.path.isfile(KEY_FILE):
+ return
+
+ # create a key pair
+ k = crypto.PKey()
+ k.generate_key(crypto.TYPE_RSA, 1024)
+
+ # create a self-signed cert
+ cert = crypto.X509()
+ cert.get_subject().C = "US"
+ cert.get_subject().ST = "TX"
+ cert.get_subject().L = "Dallas"
+ cert.get_subject().O = "Mozilla test iceserver"
+ cert.get_subject().OU = "Mozilla test iceserver"
+ cert.get_subject().CN = name
+ cert.set_serial_number(1000)
+ cert.gmtime_adj_notBefore(0)
+ cert.gmtime_adj_notAfter(10*365*24*60*60)
+ cert.set_issuer(cert.get_subject())
+ cert.set_pubkey(k)
+ cert.sign(k, 'sha1')
+
+ open(CERT_FILE, "wt").write(
+ crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
+ open(KEY_FILE, "wt").write(
+ crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
+
if __name__ == "__main__":
random.seed()
@@ -739,20 +773,48 @@ if __name__ == "__main__":
except:
pass
+ try:
+ from twisted.internet import ssl
+ from OpenSSL import SSL
+ create_self_signed_cert(hostname)
+ tls_context_factory = ssl.DefaultOpenSSLContextFactory(KEY_FILE, CERT_FILE, SSL.TLSv1_2_METHOD)
+ reactor.listenSSL(5349, TcpStunHandlerFactory(), tls_context_factory, interface=interface_4)
+
+ try:
+ reactor.listenSSL(5349, TcpStunHandlerFactory(), tls_context_factory, interface=interface_6)
+ except:
+ pass
+
+ f = open(CERT_FILE, 'r');
+ lines = f.readlines();
+ lines.pop(0); # Remove BEGIN CERTIFICATE
+ lines.pop(); # Remove END CERTIFICATE
+ lines = map(string.strip, lines);
+ certbase64 = string.join(lines, '');
+
+ turns_url = ', "turns:' + hostname + '"'
+ cert_prop = ', "cert":"' + certbase64 + '"'
+ except:
+ turns_url = ''
+ cert_prop = ''
+ pass
+
allocation_pruner = LoopingCall(prune_allocations)
allocation_pruner.start(1)
template = Template(
'[\
-{"url":"stun:$hostname"}, \
-{"url":"stun:$hostname?transport=tcp"}, \
-{"username":"$user","credential":"$pwd","url":"turn:$hostname"}, \
-{"username":"$user","credential":"$pwd","url":"turn:$hostname?transport=tcp"}]'
+{"urls":["stun:$hostname", "stun:$hostname?transport=tcp"]}, \
+{"username":"$user","credential":"$pwd","urls": \
+["turn:$hostname", "turn:$hostname?transport=tcp" $turns_url] \
+$cert_prop}]' # Hack to make it easier to override cert checks
)
print(template.substitute(user=turn_user,
pwd=turn_pass,
- hostname=hostname))
+ hostname=hostname,
+ turns_url=turns_url,
+ cert_prop=cert_prop))
reactor.run()