Merge mozilla-central to inbound a=merge

This commit is contained in:
Coroiu Cristina 2019-06-27 19:31:41 +03:00
commit 3861f1c2b6
77 changed files with 1122 additions and 287 deletions

View File

@ -30,6 +30,9 @@ let whitelist = [
{sourceName: /\b(html|mathml|ua)\.css$/i,
errorMessage: /Unknown property.*-moz-/i,
isFromDevTools: false},
{sourceName: /minimal-xul\.css$/i,
errorMessage: /Unknown property.*-moz-list-reversed/i,
isFromDevTools: false},
// Reserved to UA sheets unless layout.css.overflow-clip-box.enabled flipped to true.
{sourceName: /(?:res|gre-resources)\/forms\.css$/i,
errorMessage: /Unknown property.*overflow-clip-box/i,

View File

@ -10,6 +10,7 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Atomics.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/net/WebSocketChannel.h"
#include "mozilla/dom/File.h"
@ -176,7 +177,7 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
bool mOnCloseScheduled;
bool mFailed;
bool mDisconnectingOrDisconnected;
Atomic<bool> mDisconnectingOrDisconnected;
// Set attributes of DOM 'onclose' message
bool mCloseEventWasClean;
@ -231,9 +232,42 @@ class WebSocketImpl final : public nsIInterfaceRequestor,
}
};
NS_IMPL_ISUPPORTS(WebSocketImpl, nsIInterfaceRequestor, nsIWebSocketListener,
nsIObserver, nsISupportsWeakReference, nsIRequest,
nsIEventTarget)
NS_IMPL_ADDREF(WebSocketImpl)
NS_IMPL_QUERY_INTERFACE(WebSocketImpl, nsIInterfaceRequestor,
nsIWebSocketListener, nsIObserver,
nsISupportsWeakReference, nsIRequest, nsIEventTarget)
NS_IMETHODIMP_(MozExternalRefCountType) WebSocketImpl::Release(void) {
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
if (!mRefCnt.isThreadSafe) {
NS_ASSERT_OWNINGTHREAD(WebSocketImpl);
}
nsrefcnt count = mRefCnt - 1;
// If WebSocketImpl::Disconnect is not called, the last release of
// WebSocketImpl should be on the right thread.
if (count == 0 && !IsTargetThread() && !mDisconnectingOrDisconnected) {
DebugOnly<nsresult> rv = Dispatch(NewNonOwningRunnableMethod(
"dom::WebSocketImpl::Release", this, &WebSocketImpl::Release));
MOZ_ASSERT(NS_SUCCEEDED(rv));
return count;
}
count = --mRefCnt;
NS_LOG_RELEASE(this, count, "WebSocketImpl");
if (count == 0) {
if (!mRefCnt.isThreadSafe) {
NS_ASSERT_OWNINGTHREAD(WebSocketImpl);
}
mRefCnt = 1; /* stabilize */
delete (this);
return 0;
}
return count;
}
class CallDispatchConnectionCloseEvents final : public CancelableRunnable {
public:

View File

@ -2153,13 +2153,14 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
RuntimeService::GetDefaultJSSettings(mJSSettings);
mJSSettings.chrome.realmOptions.creationOptions().setClampAndJitterTime(
!UsesSystemPrincipal());
mJSSettings.content.realmOptions.creationOptions().setClampAndJitterTime(
!UsesSystemPrincipal());
if (mIsSecureContext) {
mJSSettings.chrome.realmOptions.creationOptions().setSecureContext(true);
mJSSettings.chrome.realmOptions.creationOptions().setClampAndJitterTime(
false);
mJSSettings.content.realmOptions.creationOptions().setSecureContext(true);
mJSSettings.content.realmOptions.creationOptions().setClampAndJitterTime(
false);
}
mIsInAutomation = xpc::IsInAutomation();

View File

@ -56,6 +56,7 @@ enum class OpenVRControllerType : uint16_t {
Vive,
WMR,
Knuckles,
Cosmos,
NumOpenVRControllerTypes
};

View File

@ -25,6 +25,7 @@
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h"
#include "binding/OpenVRCosmosBinding.h"
#include "binding/OpenVRKnucklesBinding.h"
#include "binding/OpenVRViveBinding.h"
#if defined(XP_WIN) // Windows Mixed Reality is only available in Windows.
@ -100,6 +101,7 @@ class ControllerManifestFile {
// We wanna keep these temporary files existing
// until Firefox is closed instead of following OpenVRSession's lifetime.
StaticRefPtr<ControllerManifestFile> sCosmosBindingFile;
StaticRefPtr<ControllerManifestFile> sKnucklesBindingFile;
StaticRefPtr<ControllerManifestFile> sViveBindingFile;
#if defined(XP_WIN)
@ -324,6 +326,7 @@ bool OpenVRSession::SetupContollerActions() {
nsCString viveManifest;
nsCString WMRManifest;
nsCString knucklesManifest;
nsCString cosmosManifest;
// Getting / Generating manifest file paths.
if (StaticPrefs::dom_vr_process_enabled()) {
@ -367,7 +370,6 @@ bool OpenVRSession::SetupContollerActions() {
}
}
#endif
if (vrParent->GetOpenVRControllerManifestPath(
OpenVRControllerType::Knuckles, &output)) {
knucklesManifest = output;
@ -383,6 +385,21 @@ bool OpenVRSession::SetupContollerActions() {
knucklesBindingFile.close();
}
}
if (vrParent->GetOpenVRControllerManifestPath(
OpenVRControllerType::Cosmos, &output)) {
cosmosManifest = output;
}
if (!cosmosManifest.Length() || !FileIsExisting(cosmosManifest)) {
if (!GenerateTempFileName(cosmosManifest)) {
return false;
}
OpenVRCosmosBinding cosmosBinding;
std::ofstream cosmosBindingFile(cosmosManifest.BeginReading());
if (cosmosBindingFile.is_open()) {
cosmosBindingFile << cosmosBinding.binding;
cosmosBindingFile.close();
}
}
} else {
// Without using VR process
if (!sControllerActionFile) {
@ -435,6 +452,26 @@ bool OpenVRSession::SetupContollerActions() {
}
knucklesManifest = sKnucklesBindingFile->GetFileName();
if (!sCosmosBindingFile) {
sCosmosBindingFile = ControllerManifestFile::CreateManifest();
NS_DispatchToMainThread(NS_NewRunnableFunction(
"ClearOnShutdown ControllerManifestFile",
[]() { ClearOnShutdown(&sCosmosBindingFile); }));
}
if (!sCosmosBindingFile->IsExisting()) {
nsCString cosmosBindingPath;
if (!GenerateTempFileName(cosmosBindingPath)) {
return false;
}
sCosmosBindingFile->SetFileName(cosmosBindingPath.BeginReading());
OpenVRCosmosBinding cosmosBinding;
std::ofstream cosmosBindingFile(sCosmosBindingFile->GetFileName());
if (cosmosBindingFile.is_open()) {
cosmosBindingFile << cosmosBinding.binding;
cosmosBindingFile.close();
}
}
cosmosManifest = sCosmosBindingFile->GetFileName();
#if defined(XP_WIN)
if (!sWMRBindingFile) {
sWMRBindingFile = ControllerManifestFile::CreateManifest();
@ -508,6 +545,8 @@ bool OpenVRSession::SetupContollerActions() {
"/actions/firefox/in/LHand_finger_ring_value", "vector1");
leftContollerInfo.mActionFingerPinky_Value = ControllerAction(
"/actions/firefox/in/LHand_finger_pinky_value", "vector1");
leftContollerInfo.mActionBumper_Pressed =
ControllerAction("/actions/firefox/in/LHand_bumper_pressed", "boolean");
ControllerInfo rightContollerInfo;
rightContollerInfo.mActionPose =
@ -556,6 +595,8 @@ bool OpenVRSession::SetupContollerActions() {
"/actions/firefox/in/RHand_finger_ring_value", "vector1");
rightContollerInfo.mActionFingerPinky_Value = ControllerAction(
"/actions/firefox/in/RHand_finger_pinky_value", "vector1");
rightContollerInfo.mActionBumper_Pressed =
ControllerAction("/actions/firefox/in/RHand_bumper_pressed", "boolean");
mControllerHand[OpenVRHand::Left] = leftContollerInfo;
mControllerHand[OpenVRHand::Right] = rightContollerInfo;
@ -580,6 +621,10 @@ bool OpenVRSession::SetupContollerActions() {
actionWriter.StringProperty("controller_type", "knuckles");
actionWriter.StringProperty("binding_url", knucklesManifest.BeginReading());
actionWriter.EndObject();
actionWriter.StartObjectElement();
actionWriter.StringProperty("controller_type", "vive_cosmos_controller");
actionWriter.StringProperty("binding_url", cosmosManifest.BeginReading());
actionWriter.EndObject();
#if defined(XP_WIN)
actionWriter.StartObjectElement();
actionWriter.StringProperty("controller_type", "holographic_controller");
@ -747,6 +792,13 @@ bool OpenVRSession::SetupContollerActions() {
"type", controller.mActionFingerPinky_Value.type.BeginReading());
actionWriter.EndObject();
actionWriter.StartObjectElement();
actionWriter.StringProperty(
"name", controller.mActionBumper_Pressed.name.BeginReading());
actionWriter.StringProperty(
"type", controller.mActionBumper_Pressed.type.BeginReading());
actionWriter.EndObject();
actionWriter.StartObjectElement();
actionWriter.StringProperty("name",
controller.mActionHaptic.name.BeginReading());
@ -772,7 +824,8 @@ bool OpenVRSession::SetupContollerActions() {
if (StaticPrefs::dom_vr_process_enabled()) {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"SendOpenVRControllerActionPathToParent",
[controllerAction, viveManifest, WMRManifest, knucklesManifest]() {
[controllerAction, viveManifest, WMRManifest, knucklesManifest,
cosmosManifest]() {
VRParent* vrParent = VRProcessChild::GetVRParent();
Unused << vrParent->SendOpenVRControllerActionPathToParent(
controllerAction);
@ -782,6 +835,8 @@ bool OpenVRSession::SetupContollerActions() {
OpenVRControllerType::WMR, WMRManifest);
Unused << vrParent->SendOpenVRControllerManifestPathToParent(
OpenVRControllerType::Knuckles, knucklesManifest);
Unused << vrParent->SendOpenVRControllerManifestPathToParent(
OpenVRControllerType::Cosmos, cosmosManifest);
}));
} else {
sControllerActionFile->SetFileName(controllerAction.BeginReading());
@ -1136,6 +1191,9 @@ void OpenVRSession::EnumerateControllers(VRSystemState& aState) {
mControllerHand[handIndex]
.mActionFingerPinky_Value.name.BeginReading(),
&mControllerHand[handIndex].mActionFingerPinky_Value.handle);
vr::VRInput()->GetActionHandle(
mControllerHand[handIndex].mActionBumper_Pressed.name.BeginReading(),
&mControllerHand[handIndex].mActionBumper_Pressed.handle);
nsCString deviceId;
GetControllerDeviceId(deviceType, originInfo.trackedDeviceIndex,
@ -1353,7 +1411,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionTrackpad_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionTrackpad_Touched.handle,
@ -1396,7 +1453,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionGrip_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionGrip_Touched.handle,
@ -1428,7 +1484,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionMenu_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionMenu_Touched.handle,
@ -1460,7 +1515,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionSystem_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionSystem_Touched.handle,
@ -1507,6 +1561,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
}
++buttonIdx;
}
// Button 5: B
if (mControllerHand[stateIndex].mActionB_Pressed.handle &&
vr::VRInput()->GetDigitalActionData(
@ -1522,7 +1577,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionB_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionB_Touched.handle, &actionData,
@ -1538,6 +1592,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
}
++buttonIdx;
}
// Axis 2 3: Thumbstick
// Button 6: Thumbstick
if (mControllerHand[stateIndex].mActionThumbstick_Analog.handle &&
@ -1551,7 +1606,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
controllerState.axisValue[axisIdx] = analogData.y * yAxisInvert;
++axisIdx;
}
if (mControllerHand[stateIndex].mActionThumbstick_Pressed.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionThumbstick_Pressed.handle,
@ -1559,13 +1613,13 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
actionData.bActive) {
bPressed = actionData.bState;
mask = (1ULL << buttonIdx);
controllerState.triggerValue[buttonIdx] = bPressed ? 1.0 : 0.0f;
if (bPressed) {
controllerState.buttonPressed |= mask;
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionThumbstick_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionThumbstick_Touched.handle,
@ -1581,6 +1635,25 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
}
++buttonIdx;
}
// Button 7: Bumper (Cosmos only)
if (mControllerHand[stateIndex].mActionBumper_Pressed.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionBumper_Pressed.handle, &actionData,
sizeof(actionData),
vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
actionData.bActive) {
bPressed = actionData.bState;
mask = (1ULL << buttonIdx);
controllerState.triggerValue[buttonIdx] = bPressed ? 1.0 : 0.0f;
if (bPressed) {
controllerState.buttonPressed |= mask;
} else {
controllerState.buttonPressed &= ~mask;
}
++buttonIdx;
}
// Button 7: Finger index
if (mControllerHand[stateIndex].mActionFingerIndex_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1591,6 +1664,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
UpdateTrigger(controllerState, buttonIdx, analogData.x, triggerThreshold);
++buttonIdx;
}
// Button 8: Finger middle
if (mControllerHand[stateIndex].mActionFingerMiddle_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1601,6 +1675,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
UpdateTrigger(controllerState, buttonIdx, analogData.x, triggerThreshold);
++buttonIdx;
}
// Button 9: Finger ring
if (mControllerHand[stateIndex].mActionFingerRing_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1611,6 +1686,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
UpdateTrigger(controllerState, buttonIdx, analogData.x, triggerThreshold);
++buttonIdx;
}
// Button 10: Finger pinky
if (mControllerHand[stateIndex].mActionFingerPinky_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1905,6 +1981,9 @@ void OpenVRSession::GetControllerDeviceId(
if (deviceId.Find("knuckles") != kNotFound) {
aId.AssignLiteral("OpenVR Knuckles");
isFound = true;
} else if (deviceId.Find("vive_cosmos_controller") != kNotFound) {
aId.AssignLiteral("OpenVR Cosmos");
isFound = true;
}
requiredBufferLen = mVRSystem->GetStringTrackedDeviceProperty(
aDeviceIndex, ::vr::Prop_SerialNumber_String, charBuf, 128, &err);

View File

@ -62,20 +62,25 @@ struct ControllerInfo {
ControllerAction mActionSystem_Pressed;
ControllerAction mActionSystem_Touched;
// --- Knuckles
// --- Knuckles & Cosmos
ControllerAction mActionA_Pressed;
ControllerAction mActionA_Touched;
ControllerAction mActionB_Pressed;
ControllerAction mActionB_Touched;
// --- Knuckles, Cosmos, and WMR
ControllerAction mActionThumbstick_Analog;
ControllerAction mActionThumbstick_Pressed;
ControllerAction mActionThumbstick_Touched;
// --- Knuckles
ControllerAction mActionFingerIndex_Value;
ControllerAction mActionFingerMiddle_Value;
ControllerAction mActionFingerRing_Value;
ControllerAction mActionFingerPinky_Value;
// --- Cosmos
ControllerAction mActionBumper_Pressed;
};
class OpenVRSession : public VRSession {

View File

@ -0,0 +1,204 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef GFX_VR_BLINDING_OPENVRCOSMOSBINDING_H
#define GFX_VR_BLINDING_OPENVRCOSMOSBINDING_H
namespace mozilla {
namespace gfx {
struct OpenVRCosmosBinding {
const char* binding =
// clang-format off
"{\n"
" \"version\" : \"0.1\", \n"
" \"controller_type\" : \"vive_cosmos_controller\", \n"
" \"description\" : \"Bindings for Firefox OpenVR for the Vive Cosmos controller\", \n"
" \"name\" : \"Firefox bindings for Vive Cosmos Controller\", \n"
" \"bindings\" : { \n"
" \"/actions/firefox\" : { \n"
" \"poses\" : [ \n"
" { \n"
" \"output\" : \"/actions/firefox/in/LHand_pose\", \n"
" \"path\" : \"/user/hand/left/pose/raw\" \n"
" },\n"
" { \n"
" \"output\" : \"/actions/firefox/in/RHand_pose\", \n"
" \"path\" : \"/user/hand/right/pose/raw\" \n"
" }\n"
" ],\n"
" \"haptics\" : [ \n"
" {\n"
" \"output\" : \"/actions/firefox/out/LHand_haptic\", \n"
" \"path\" : \"/user/hand/left/output/haptic\" \n"
" },\n"
" { \n"
" \"output\" : \"/actions/firefox/out/RHand_haptic\", \n"
" \"path\" : \"/user/hand/right/output/haptic\" \n"
" }\n"
" ],\n"
" \"sources\" : [ \n"
" {\n"
" \"inputs\" : { \n"
" \"pull\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_trigger_value\" \n"
" } \n"
" },\n"
" \"mode\" : \"trigger\", \n"
" \"path\" : \"/user/hand/left/input/trigger\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"pull\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_trigger_value\" \n"
" } \n"
" },\n"
" \"mode\" : \"trigger\", \n"
" \"path\" : \"/user/hand/right/input/trigger\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_grip_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_grip_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/paddle_heavy\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_grip_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_grip_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/paddle_heavy\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_system_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_system_touched\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/system\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_system_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_system_touched\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/system\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_a_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/a\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_a_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/a\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_b_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/b\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_b_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/b\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"position\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_thumbstick_analog\" \n"
" }, \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_thumbstick_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_thumbstick_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"joystick\", \n"
" \"path\" : \"/user/hand/left/input/joystick\" \n"
" },\n"
" {\n"
" \"inputs\" : { \n"
" \"position\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_thumbstick_analog\" \n"
" }, \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_thumbstick_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_thumbstick_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"joystick\", \n"
" \"path\" : \"/user/hand/right/input/joystick\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_bumper_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/bumper\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_bumper_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/bumper\" \n"
" } \n"
" ]\n"
" }\n"
" }\n"
"}";
// clang-format on
};
} // namespace gfx
} // namespace mozilla
#endif // GFX_VR_BLINDING_OPENVRCOSMOSBINDING_H

View File

@ -233,7 +233,7 @@ struct OpenVRKnucklesBinding {
" \"mode\" : \"trigger\", \n"
" \"path\" : \"/user/hand/right/input/finger/index\" \n"
" }, \n"
" {\n"
" {\n"
" \"inputs\" : { \n"
" \"pull\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_finger_middle_value\" \n"

View File

@ -11,7 +11,6 @@ namespace mozilla {
namespace gfx {
struct OpenVRWMRBinding {
// OpenVRWMRBinding();
const char* binding =
// clang-format off
"{\n"

View File

@ -2260,6 +2260,12 @@ AttachDecision GetPropIRGenerator::tryAttachTypedElement(
return AttachDecision::NoAction;
}
// BigInt boxing not yet implemented.
if (obj->is<TypedArrayObject>() &&
Scalar::isBigIntType(obj->as<TypedArrayObject>().type())) {
return AttachDecision::NoAction;
}
// Don't attach typed object stubs if the underlying storage could be
// detached, as the stub will always bail out.
if (IsPrimitiveArrayTypedObject(obj) && cx_->zone()->detachedTypedObjects) {
@ -3883,6 +3889,12 @@ AttachDecision SetPropIRGenerator::tryAttachSetTypedElement(
return AttachDecision::NoAction;
}
// bigIntArray[index] = rhsVal_ will throw as the RHS is a number.
if (obj->is<TypedArrayObject>() &&
Scalar::isBigIntType(obj->as<TypedArrayObject>().type())) {
return AttachDecision::NoAction;
}
bool handleOutOfBounds = false;
if (obj->is<TypedArrayObject>()) {
handleOutOfBounds = (index >= obj->as<TypedArrayObject>().length());

View File

@ -1413,12 +1413,16 @@ bool BigInt::calculateMaximumDigitsRequired(JSContext* cx, uint8_t radix,
size_t charcount, size_t* result) {
MOZ_ASSERT(2 <= radix && radix <= 36);
size_t bitsPerChar = maxBitsPerCharTable[radix];
uint8_t bitsPerChar = maxBitsPerCharTable[radix];
MOZ_ASSERT(charcount > 0);
MOZ_ASSERT(charcount <= std::numeric_limits<size_t>::max() / bitsPerChar);
uint64_t n =
CeilDiv(charcount * bitsPerChar, DigitBits * bitsPerCharTableMultiplier);
MOZ_ASSERT(charcount <= std::numeric_limits<uint64_t>::max() / bitsPerChar);
static_assert(
MaxDigitLength < std::numeric_limits<size_t>::max(),
"can't safely cast calculateMaximumDigitsRequired result to size_t");
uint64_t n = CeilDiv(static_cast<uint64_t>(charcount) * bitsPerChar,
DigitBits * bitsPerCharTableMultiplier);
if (n > MaxDigitLength) {
ReportOutOfMemory(cx);
return false;

View File

@ -2431,7 +2431,7 @@ struct RestyleManager::TextPostTraversalState {
ComputedStyle& ParentStyle() {
if (!mParentContext) {
mLazilyResolvedParentContext =
mParentRestyleState.StyleSet().ResolveServoStyle(mParentElement);
ServoStyleSet::ResolveServoStyle(mParentElement);
mParentContext = mLazilyResolvedParentContext;
}
return *mParentContext;
@ -2668,8 +2668,7 @@ bool RestyleManager::ProcessPostTraversal(Element* aElement,
static_cast<nsChangeHint>(Servo_TakeChangeHint(aElement, &wasRestyled));
RefPtr<ComputedStyle> upToDateStyleIfRestyled =
wasRestyled ? aRestyleState.StyleSet().ResolveServoStyle(*aElement)
: nullptr;
wasRestyled ? ServoStyleSet::ResolveServoStyle(*aElement) : nullptr;
// We should really fix the weird primary frame mapping for image maps
// (bug 135040)...
@ -2767,8 +2766,7 @@ bool RestyleManager::ProcessPostTraversal(Element* aElement,
const bool isDisplayContents = !styleFrame && aElement->HasServoData() &&
Servo_Element_IsDisplayContents(aElement);
if (isDisplayContents) {
oldOrDisplayContentsStyle =
aRestyleState.StyleSet().ResolveServoStyle(*aElement);
oldOrDisplayContentsStyle = ServoStyleSet::ResolveServoStyle(*aElement);
}
Maybe<ServoRestyleState> thisFrameRestyleState;

View File

@ -1761,7 +1761,7 @@ void nsCSSFrameConstructor::CreateGeneratedContentItem(
// above. We need to grab style with animations from the pseudo element and
// replace old one.
mPresShell->StyleSet()->StyleNewSubtree(container);
pseudoStyle = styleSet->ResolveServoStyle(*container);
pseudoStyle = ServoStyleSet::ResolveServoStyle(*container);
}
uint32_t contentCount = pseudoStyle->StyleContent()->ContentCount();
@ -2253,7 +2253,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
}
RefPtr<ComputedStyle> computedStyle =
mPresShell->StyleSet()->ResolveServoStyle(*aDocElement);
ServoStyleSet::ResolveServoStyle(*aDocElement);
const nsStyleDisplay* display = computedStyle->StyleDisplay();
@ -3843,6 +3843,18 @@ static void SetFlagsOnSubtree(nsIContent* aNode, uintptr_t aFlagsToSet) {
}
}
static void GatherSubtreeElements(Element* aElement,
nsTArray<Element*>& aElements) {
aElements.AppendElement(aElement);
StyleChildrenIterator iter(aElement);
for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
if (!c->IsElement()) {
continue;
}
GatherSubtreeElements(c->AsElement(), aElements);
}
}
nsresult nsCSSFrameConstructor::GetAnonymousContent(
nsIContent* aParent, nsIFrame* aParentFrame,
nsTArray<nsIAnonymousContentCreator::ContentInfo>& aContent) {
@ -3883,11 +3895,74 @@ nsresult nsCSSFrameConstructor::GetAnonymousContent(
}
}
// Some situations where we don't cache anonymous content styles:
//
// * when visibility is anything other than visible; we rely on visibility
// inheriting into anonymous content, but don't bother adding this state
// to the AnonymousContentKey, since it's not so common
//
// * when the medium is anything other than screen; some UA style sheet rules
// apply in e.g. print medium, and will give different results from the
// cached styles
bool allowStyleCaching =
StaticPrefs::layout_css_cached_scrollbar_styles_enabled() &&
aParentFrame->StyleVisibility()->mVisible == NS_STYLE_VISIBILITY_VISIBLE &&
mPresShell->GetPresContext()->Medium() == nsGkAtoms::screen;
// Compute styles for the anonymous content tree.
ServoStyleSet* styleSet = mPresShell->StyleSet();
// Eagerly compute styles for the anonymous content tree.
for (auto& info : aContent) {
if (info.mContent->IsElement()) {
styleSet->StyleNewSubtree(info.mContent->AsElement());
Element* e = Element::FromNode(info.mContent);
if (!e) {
continue;
}
if (info.mKey == AnonymousContentKey::None || !allowStyleCaching) {
// Most NAC subtrees do not use caching of computed styles. Just go
// ahead and eagerly style the subtree.
styleSet->StyleNewSubtree(e);
continue;
}
// We have a NAC subtree for which we can use cached styles.
AutoTArray<RefPtr<ComputedStyle>, 2> cachedStyles;
AutoTArray<Element*, 2> elements;
GatherSubtreeElements(e, elements);
styleSet->GetCachedAnonymousContentStyles(info.mKey, cachedStyles);
if (cachedStyles.IsEmpty()) {
// We haven't store cached styles for this kind of NAC subtree yet.
// Eagerly compute those styles, then cache them for later.
styleSet->StyleNewSubtree(e);
for (Element* e : elements) {
if (e->HasServoData()) {
cachedStyles.AppendElement(ServoStyleSet::ResolveServoStyle(*e));
} else {
cachedStyles.AppendElement(nullptr);
}
}
styleSet->PutCachedAnonymousContentStyles(info.mKey,
std::move(cachedStyles));
continue;
}
// We previously stored cached styles for this kind of NAC subtree.
// Iterate over them and set them on the subtree's elements.
MOZ_ASSERT(cachedStyles.Length() == elements.Length(),
"should always produce the same size NAC subtree");
for (size_t i = 0, len = cachedStyles.Length(); i != len; ++i) {
if (cachedStyles[i]) {
#ifdef DEBUG
// Assert that our cached style is the same as one we could compute.
RefPtr<ComputedStyle> cs = styleSet->ResolveStyleLazily(*elements[i]);
MOZ_ASSERT(
cachedStyles[i]->EqualForCachedAnonymousContentStyle(*cs),
"cached anonymous content styles should be identical to those we "
"would compute normally");
#endif
Servo_SetExplicitStyle(elements[i], cachedStyles[i]);
}
}
}
@ -4621,10 +4696,8 @@ void nsCSSFrameConstructor::InitAndRestoreFrame(
already_AddRefed<ComputedStyle> nsCSSFrameConstructor::ResolveComputedStyle(
nsIContent* aContent) {
ServoStyleSet* styleSet = mPresShell->StyleSet();
if (auto* element = Element::FromNode(aContent)) {
return styleSet->ResolveServoStyle(*element);
return ServoStyleSet::ResolveServoStyle(*element);
}
MOZ_ASSERT(aContent->IsText(),
@ -4646,7 +4719,7 @@ already_AddRefed<ComputedStyle> nsCSSFrameConstructor::ResolveComputedStyle(
// out.
RefPtr<ComputedStyle> parentStyle =
Servo_Element_GetPrimaryComputedValues(parent).Consume();
return styleSet->ResolveStyleForText(aContent, parentStyle);
return mPresShell->StyleSet()->ResolveStyleForText(aContent, parentStyle);
}
// MathML Mod - RBS

View File

@ -10044,12 +10044,12 @@ ComputedStyle* nsLayoutUtils::StyleForScrollbar(nsIFrame* aScrollbarPart) {
// from the element directly. This can happen on viewport, because
// the scrollbar of viewport may be shown when the root element has
// > display: none; overflow: scroll;
nsPresContext* pc = aScrollbarPart->PresContext();
MOZ_ASSERT(content == pc->Document()->GetRootElement(),
"Root element is the only case for this fallback "
"path to be triggered");
MOZ_ASSERT(
content == aScrollbarPart->PresContext()->Document()->GetRootElement(),
"Root element is the only case for this fallback "
"path to be triggered");
RefPtr<ComputedStyle> style =
pc->StyleSet()->ResolveServoStyle(*content->AsElement());
ServoStyleSet::ResolveServoStyle(*content->AsElement());
// Dropping the strong reference is fine because the style should be
// held strongly by the element.
return style.get();

View File

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
/* values to identify particular subtrees of native anonymous content */
#ifndef mozilla_AnonymousContentKey_h
#define mozilla_AnonymousContentKey_h
namespace mozilla {
// clang-format off
// We currently use cached anonymous content styles only for scrollbar parts,
// and we can fit the type of scrollbar part element along with its different
// options (such as orientation, and other attribute values that can affect
// styling) into a uint8_t.
//
// The lower three bits hold a Type_* value identifying the type of
// element, and the remaining bits store Flag_* values.
//
// A value of 0 is used to represent an anonymous content subtree that we don't
// cache styles for.
enum class AnonymousContentKey : uint8_t {
None = 0x00,
// all
Type_ScrollCorner = 0x01,
Type_Resizer = 0x02,
Type_Scrollbar = 0x03,
Type_ScrollbarButton = 0x04,
Type_Slider = 0x05,
// scrollbar, scrollbarbutton, slider
Flag_Vertical = 0x08,
// resizer
Flag_Resizer_Right = 0x08,
Flag_Resizer_Bottom = 0x10,
Flag_Resizer_Flip = 0x20,
// scrollbarbutton
Flag_ScrollbarButton_Down = 0x10,
Flag_ScrollbarButton_Bottom = 0x20,
Flag_ScrollbarButton_Decrement = 0x40,
};
// clang-format on
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AnonymousContentKey)
} // namespace mozilla
#endif // mozilla_AnonymousContentKey_h

View File

@ -134,6 +134,7 @@ EXPORTS += [
EXPORTS.mozilla += [
'!FrameIdList.h',
'!FrameTypeList.h',
'AnonymousContentKey.h',
'AspectRatio.h',
'AutoCopyListener.h',
'ColumnUtils.h',

View File

@ -9738,7 +9738,7 @@ ComputedStyle* nsFrame::DoGetParentComputedStyle(
pseudo == PseudoStyleType::tableWrapper) {
if (Servo_Element_IsDisplayContents(parentElement)) {
RefPtr<ComputedStyle> style =
PresShell()->StyleSet()->ResolveServoStyle(*parentElement);
ServoStyleSet::ResolveServoStyle(*parentElement);
// NOTE(emilio): we return a weak reference because the element also
// holds the style context alive. This is a bit silly (we could've
// returned a weak ref directly), but it's probably not worth

View File

@ -286,7 +286,7 @@ void nsHTMLFramesetFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
//
// Maybe we should change that though.
RefPtr<ComputedStyle> kidStyle =
presShell->StyleSet()->ResolveServoStyle(*child->AsElement());
ServoStyleSet::ResolveServoStyle(*child->AsElement());
nsIFrame* frame;
if (child->IsHTMLElement(nsGkAtoms::frameset)) {
frame = NS_NewHTMLFramesetFrame(presShell, kidStyle);

View File

@ -4756,6 +4756,51 @@ void ScrollFrameHelper::ReloadChildFrames() {
}
}
already_AddRefed<Element> ScrollFrameHelper::MakeScrollbar(
NodeInfo* aNodeInfo, bool aVertical, AnonymousContentKey& aKey) {
MOZ_ASSERT(aNodeInfo);
MOZ_ASSERT(
aNodeInfo->Equals(nsGkAtoms::scrollbar, nullptr, kNameSpaceID_XUL));
static constexpr nsLiteralString kOrientValues[2] = {
NS_LITERAL_STRING("horizontal"),
NS_LITERAL_STRING("vertical"),
};
aKey = AnonymousContentKey::Type_Scrollbar;
if (aVertical) {
aKey |= AnonymousContentKey::Flag_Vertical;
}
RefPtr<Element> e;
NS_TrustedNewXULElement(getter_AddRefs(e), do_AddRef(aNodeInfo));
#ifdef DEBUG
// Scrollbars can get restyled by theme changes. Whether such a restyle
// will actually reconstruct them correctly if it involves a frame
// reconstruct... I don't know. :(
e->SetProperty(nsGkAtoms::restylableAnonymousNode,
reinterpret_cast<void*>(true));
#endif // DEBUG
e->SetAttr(kNameSpaceID_None, nsGkAtoms::orient, kOrientValues[aVertical],
false);
e->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
NS_LITERAL_STRING("always"), false);
if (mIsRoot) {
e->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
reinterpret_cast<void*>(true));
e->SetAttr(kNameSpaceID_None, nsGkAtoms::root_, NS_LITERAL_STRING("true"),
false);
// Don't bother making style caching take [root="true"] styles into account.
aKey = AnonymousContentKey::None;
}
return e.forget();
}
bool ScrollFrameHelper::IsForTextControlWithNoScrollbars() const {
nsIFrame* parent = mOuter->GetParent();
// The anonymous <div> used by <inputs> never gets scrollbars.
@ -4773,6 +4818,8 @@ bool ScrollFrameHelper::IsForTextControlWithNoScrollbars() const {
nsresult ScrollFrameHelper::CreateAnonymousContent(
nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements) {
typedef nsIAnonymousContentCreator::ContentInfo ContentInfo;
nsPresContext* presContext = mOuter->PresContext();
// Don't create scrollbars if we're an SVG document being used as an image,
@ -4833,62 +4880,28 @@ nsresult ScrollFrameHelper::CreateAnonymousContent(
nsNodeInfoManager* nodeInfoManager =
presContext->Document()->NodeInfoManager();
RefPtr<NodeInfo> nodeInfo = nodeInfoManager->GetNodeInfo(
nsGkAtoms::scrollbar, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
if (canHaveHorizontal) {
RefPtr<NodeInfo> ni = nodeInfo;
NS_TrustedNewXULElement(getter_AddRefs(mHScrollbarContent), ni.forget());
#ifdef DEBUG
// Scrollbars can get restyled by theme changes. Whether such a restyle
// will actually reconstruct them correctly if it involves a frame
// reconstruct... I don't know. :(
mHScrollbarContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
reinterpret_cast<void*>(true));
#endif // DEBUG
{
RefPtr<NodeInfo> nodeInfo = nodeInfoManager->GetNodeInfo(
nsGkAtoms::scrollbar, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
NS_LITERAL_STRING("horizontal"), false);
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
NS_LITERAL_STRING("always"), false);
if (mIsRoot) {
mHScrollbarContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
reinterpret_cast<void*>(true));
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::root_,
NS_LITERAL_STRING("true"), false);
if (canHaveHorizontal) {
AnonymousContentKey key;
mHScrollbarContent = MakeScrollbar(nodeInfo, /* aVertical */ false, key);
aElements.AppendElement(ContentInfo(mHScrollbarContent, key));
}
if (!aElements.AppendElement(mHScrollbarContent))
return NS_ERROR_OUT_OF_MEMORY;
}
if (canHaveVertical) {
RefPtr<NodeInfo> ni = nodeInfo;
NS_TrustedNewXULElement(getter_AddRefs(mVScrollbarContent), ni.forget());
#ifdef DEBUG
// Scrollbars can get restyled by theme changes. Whether such a restyle
// will actually reconstruct them correctly if it involves a frame
// reconstruct... I don't know. :(
mVScrollbarContent->SetProperty(nsGkAtoms::restylableAnonymousNode,
reinterpret_cast<void*>(true));
#endif // DEBUG
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
NS_LITERAL_STRING("vertical"), false);
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
NS_LITERAL_STRING("always"), false);
if (mIsRoot) {
mVScrollbarContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
reinterpret_cast<void*>(true));
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::root_,
NS_LITERAL_STRING("true"), false);
if (canHaveVertical) {
AnonymousContentKey key;
mVScrollbarContent = MakeScrollbar(nodeInfo, /* aVertical */ true, key);
aElements.AppendElement(ContentInfo(mVScrollbarContent, key));
}
if (!aElements.AppendElement(mVScrollbarContent))
return NS_ERROR_OUT_OF_MEMORY;
}
if (isResizable) {
AnonymousContentKey key = AnonymousContentKey::Type_Resizer;
RefPtr<NodeInfo> nodeInfo;
nodeInfo = nodeInfoManager->GetNodeInfo(
nsGkAtoms::resizer, nullptr, kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
@ -4901,20 +4914,25 @@ nsresult ScrollFrameHelper::CreateAnonymousContent(
case StyleResize::Horizontal:
if (IsScrollbarOnRight()) {
dir.AssignLiteral("right");
key |= AnonymousContentKey::Flag_Resizer_Right;
} else {
dir.AssignLiteral("left");
}
break;
case StyleResize::Vertical:
dir.AssignLiteral("bottom");
key |= AnonymousContentKey::Flag_Resizer_Bottom;
if (!IsScrollbarOnRight()) {
mResizerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::flip,
EmptyString(), false);
key |= AnonymousContentKey::Flag_Resizer_Flip;
}
break;
case StyleResize::Both:
key |= AnonymousContentKey::Flag_Resizer_Bottom;
if (IsScrollbarOnRight()) {
dir.AssignLiteral("bottomright");
key |= AnonymousContentKey::Flag_Resizer_Right;
} else {
dir.AssignLiteral("bottomleft");
}
@ -4940,12 +4958,13 @@ nsresult ScrollFrameHelper::CreateAnonymousContent(
mResizerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
NS_LITERAL_STRING("always"), false);
if (!aElements.AppendElement(mResizerContent))
return NS_ERROR_OUT_OF_MEMORY;
aElements.AppendElement(ContentInfo(mResizerContent, key));
}
if (canHaveHorizontal && canHaveVertical) {
nodeInfo =
AnonymousContentKey key = AnonymousContentKey::Type_ScrollCorner;
RefPtr<NodeInfo> nodeInfo =
nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollcorner, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
NS_TrustedNewXULElement(getter_AddRefs(mScrollCornerContent),
@ -4955,8 +4974,15 @@ nsresult ScrollFrameHelper::CreateAnonymousContent(
nsGkAtoms::docLevelNativeAnonymousContent,
reinterpret_cast<void*>(true));
}
if (!aElements.AppendElement(mScrollCornerContent))
return NS_ERROR_OUT_OF_MEMORY;
aElements.AppendElement(ContentInfo(mScrollCornerContent, key));
}
// Don't cache styles if we are a child of a <select> element, since we have
// some UA style sheet rules that depend on the <select>'s attributes.
if (mOuter->GetContent()->IsHTMLElement(nsGkAtoms::select)) {
for (auto& info : aElements) {
info.mKey = AnonymousContentKey::None;
}
}
return NS_OK;

View File

@ -513,12 +513,17 @@ class ScrollFrameHelper : public nsIReflowCallback {
void UpdateMinimumScaleSize(const nsRect& aScrollableOverflow,
const nsSize& aICBSize);
// Return the scroll frame's "true outer size".
// This is mOuter->GetSize(), except when mOuter has been sized to reflect
// a virtual (layout) viewport in which case this returns the outer size
// used to size the physical (visual) viewport.
nsSize TrueOuterSize() const;
already_AddRefed<Element> MakeScrollbar(dom::NodeInfo* aNodeInfo,
bool aVertical,
AnonymousContentKey& aKey);
// owning references to the nsIAnonymousContentCreator-built content
nsCOMPtr<mozilla::dom::Element> mHScrollbarContent;
nsCOMPtr<mozilla::dom::Element> mVScrollbarContent;

View File

@ -12,6 +12,7 @@
#ifndef nsIAnonymousContentCreator_h___
#define nsIAnonymousContentCreator_h___
#include "mozilla/AnonymousContentKey.h"
#include "mozilla/ComputedStyle.h"
#include "nsQueryFrame.h"
@ -31,9 +32,12 @@ class nsIAnonymousContentCreator {
NS_DECL_QUERYFRAME_TARGET(nsIAnonymousContentCreator)
struct ContentInfo {
explicit ContentInfo(nsIContent* aContent) : mContent(aContent) {}
explicit ContentInfo(nsIContent* aContent,
mozilla::AnonymousContentKey aKey = mozilla::AnonymousContentKey::None)
: mContent(aContent), mKey(aKey) {}
nsIContent* mContent;
mozilla::AnonymousContentKey mKey;
};
/**

View File

@ -207,7 +207,7 @@ ComputedStyle* nsPlaceholderFrame::GetParentComputedStyleForOutOfFlow(
mContent ? mContent->GetFlattenedTreeParentElement() : nullptr;
if (parentElement && Servo_Element_IsDisplayContents(parentElement)) {
RefPtr<ComputedStyle> style =
PresShell()->StyleSet()->ResolveServoStyle(*parentElement);
ServoStyleSet::ResolveServoStyle(*parentElement);
*aProviderFrame = nullptr;
// See the comment in GetParentComputedStyle to see why returning this as a
// weak ref is fine.

View File

@ -8,7 +8,7 @@ fails != print-no-animations.html print-no-animations-notref.html # reftest harn
== animation-on-empty-height-frame.html about:blank
== in-visibility-hidden-animation.html in-visibility-hidden-animation-ref.html
== in-visibility-hidden-animation-pseudo-element.html in-visibility-hidden-animation-pseudo-element-ref.html
== in-visibility-hidden-animation-marker-pseudo-element.html in-visibility-hidden-animation-marker-pseudo-element-ref.html
pref(layout.css.marker.restricted,false) == in-visibility-hidden-animation-marker-pseudo-element.html in-visibility-hidden-animation-marker-pseudo-element-ref.html
== partially-out-of-view-animation.html partially-out-of-view-animation-ref.html
== animate-display-table-opacity.html animate-display-table-opacity-ref.html
# We need to run 100% opacity test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor
@ -58,13 +58,13 @@ fails-if(layerChecksEnabled) == background-position-important.html background-po
== stop-animation-on-discarded-pseudo-element.html about:blank
== updating-animation-on-pseudo-element.html updating-animation-on-pseudo-element-ref.html
== updating-animation-on-marker-pseudo-element.html updating-animation-on-marker-pseudo-element-ref.html
pref(layout.css.marker.restricted,false) == updating-animation-on-marker-pseudo-element.html updating-animation-on-marker-pseudo-element-ref.html
== content-on-pseudo-element-at-beginning.html content-on-pseudo-element-ref.html
== content-on-pseudo-element-at-half.html content-on-pseudo-element-ref.html
== content-on-marker-pseudo-element-at-beginning.html content-on-marker-pseudo-element-at-beginning-ref.html
== content-on-marker-pseudo-element-at-half.html content-on-marker-pseudo-element-at-beginning-ref.html
pref(layout.css.marker.restricted,false) == content-on-marker-pseudo-element-at-beginning.html content-on-marker-pseudo-element-at-beginning-ref.html
pref(layout.css.marker.restricted,false) == content-on-marker-pseudo-element-at-half.html content-on-marker-pseudo-element-at-beginning-ref.html
== reframe-and-animation-starts-at-the-same-time.html reframe-and-animation-starts-at-the-same-time-ref.html
== marker-reframe-and-animation-starts-at-the-same-time.html marker-reframe-and-animation-starts-at-the-same-time-ref.html
pref(layout.css.marker.restricted,false) == marker-reframe-and-animation-starts-at-the-same-time.html marker-reframe-and-animation-starts-at-the-same-time-ref.html
== change-animation-name-to-none-in-rule.html change-animation-name-in-rule-ref.html
== change-animation-name-to-other-in-rule.html change-animation-name-in-rule-ref.html
== change-animation-name-to-non-existent-in-rule.html change-animation-name-in-rule-ref.html

View File

@ -9,11 +9,9 @@
width: 500px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
width: 50%;
}

View File

@ -7,7 +7,7 @@
details {
display: inline;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -4,7 +4,7 @@
<html>
<style>
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -4,7 +4,7 @@
<html class="reftest-paged">
<style>
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -4,7 +4,7 @@
<html class="reftest-paged">
<style>
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -4,7 +4,7 @@
<html class="reftest-paged">
<style>
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -4,7 +4,7 @@
<html class="reftest-paged">
<style>
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -9,7 +9,7 @@
width: 500px;
height: 300px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -11,7 +11,7 @@
-webkit-column-rule: 1px solid lightgray;
border: 1px solid lightblue;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -9,7 +9,7 @@
grid-template-rows: auto;
grid-template-columns: repeat(3, 150px);
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -9,11 +9,9 @@
overflow: auto;
width: 500px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
width: 400px;
}

View File

@ -10,7 +10,7 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -10,7 +10,7 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
overflow: auto;
width: 200px;

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
overflow: hidden;
width: 200px;

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
overflow: auto;
width: 200px;

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
overflow: auto;
width: 200px;

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
overflow: hidden;
width: 200px;

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
overflow: hidden;
width: 200px;

View File

@ -10,11 +10,9 @@
width: 300px;
height: 200px;
}
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
background-color: green;
width: 200px;
height: 100px;

View File

@ -4,11 +4,9 @@
<html>
<style>
summary::marker {
summary {
/* Hide the triangle for comparing with div in reftest. */
list-style-type: none;
}
summary {
-moz-column-count: 3;
-moz-column-rule: 1px solid lightgray;
-webkit-column-count: 3;

View File

@ -394,4 +394,17 @@ void ComputedStyle::AddSizeOfIncludingThis(nsWindowSizes& aSizes,
mCachedInheritingStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
}
#ifdef DEBUG
bool ComputedStyle::EqualForCachedAnonymousContentStyle(
const ComputedStyle& aOther) const {
// One thing we can't add UA rules to prevent is different -x-lang
// values being inherited in. So we use this FFI function function rather
// than rely on CalcStyleDifference, which can't tell us which specific
// properties have changed.
return Servo_ComputedValues_EqualForCachedAnonymousContentStyle(this,
&aOther);
}
#endif
} // namespace mozilla

View File

@ -240,6 +240,10 @@ class ComputedStyle {
nsChangeHint CalcStyleDifference(const ComputedStyle& aNewContext,
uint32_t* aEqualStructs) const;
#ifdef DEBUG
bool EqualForCachedAnonymousContentStyle(const ComputedStyle&) const;
#endif
public:
/**
* Get a color that depends on link-visitedness using this and

View File

@ -2037,3 +2037,7 @@ void Gecko_LoadData_DeregisterLoad(const StyleLoadData* aData) {
MOZ_ASSERT(aData->load_id != 0);
ImageLoader::DeregisterCSSImageFromAllLoaders(*aData);
}
void Gecko_PrintfStderr(const nsCString* aStr) {
printf_stderr("%s", aStr->get());
}

View File

@ -732,6 +732,8 @@ bool Gecko_MediaFeatures_IsResourceDocument(const mozilla::dom::Document*);
nsAtom* Gecko_MediaFeatures_GetOperatingSystemVersion(
const mozilla::dom::Document*);
void Gecko_PrintfStderr(const nsCString*);
} // extern "C"
#endif // mozilla_GeckoBindings_h

View File

@ -990,6 +990,8 @@ bool ServoStyleSet::EnsureUniqueInnerOnCSSSheets() {
void ServoStyleSet::ClearCachedStyleData() {
ClearNonInheritingComputedStyles();
Servo_StyleSet_RebuildCachedData(mRawSet.get());
mCachedAnonymousContentStyles.Clear();
PodArrayZero(mCachedAnonymousContentStyleIndexes);
}
void ServoStyleSet::ForceDirtyAllShadowStyles() {

View File

@ -7,6 +7,7 @@
#ifndef mozilla_ServoStyleSet_h
#define mozilla_ServoStyleSet_h
#include "mozilla/AnonymousContentKey.h"
#include "mozilla/AtomArray.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/EventStates.h"
@ -294,8 +295,8 @@ class ServoStyleSet {
* Clears any cached style data that may depend on all sorts of computed
* values.
*
* Right now this clears the non-inheriting ComputedStyle cache, and resets
* the default computed values.
* Right now this clears the non-inheriting ComputedStyle cache, resets the
* default computed values, and clears cached anonymous content style.
*
* This does _not_, however, clear the stylist.
*/
@ -322,7 +323,8 @@ class ServoStyleSet {
*
* FIXME(emilio): Is there a point in this after bug 1367904?
*/
inline already_AddRefed<ComputedStyle> ResolveServoStyle(const dom::Element&);
static inline already_AddRefed<ComputedStyle> ResolveServoStyle(
const dom::Element&);
bool GetKeyframesForName(const dom::Element&, const ComputedStyle&,
nsAtom* aName,
@ -552,6 +554,42 @@ class ServoStyleSet {
nsCSSAnonBoxes::NonInheriting::_Count, RefPtr<ComputedStyle>>
mNonInheritingComputedStyles;
public:
void PutCachedAnonymousContentStyles(
AnonymousContentKey aKey, nsTArray<RefPtr<ComputedStyle>>&& aStyles) {
auto index = static_cast<size_t>(aKey);
MOZ_ASSERT(mCachedAnonymousContentStyles.Length() + aStyles.Length() < 256,
"(index, length) pairs must be bigger");
MOZ_ASSERT(mCachedAnonymousContentStyleIndexes[index].second == 0,
"shouldn't need to overwrite existing cached styles");
MOZ_ASSERT(!aStyles.IsEmpty(), "should have some styles to cache");
mCachedAnonymousContentStyleIndexes[index] = std::make_pair(
mCachedAnonymousContentStyles.Length(), aStyles.Length());
mCachedAnonymousContentStyles.AppendElements(std::move(aStyles));
}
void GetCachedAnonymousContentStyles(
AnonymousContentKey aKey, nsTArray<RefPtr<ComputedStyle>>& aStyles) {
auto index = static_cast<size_t>(aKey);
auto loc = mCachedAnonymousContentStyleIndexes[index];
aStyles.AppendElements(mCachedAnonymousContentStyles.Elements() + loc.first,
loc.second);
}
private:
// Map of AnonymousContentKey values to an (index, length) pair pointing into
// mCachedAnonymousContentStyles.
//
// We assert that the index and length values fit into uint8_ts.
std::pair<uint8_t, uint8_t>
mCachedAnonymousContentStyleIndexes[1
<< sizeof(AnonymousContentKey) * 8]{};
// Stores cached ComputedStyles for certain native anonymous content.
nsTArray<RefPtr<ComputedStyle>> mCachedAnonymousContentStyles;
StylistState mStylistState = StylistState::NotDirty;
bool mAuthorStyleDisabled = false;
bool mNeedsRestyleAfterEnsureUniqueInner = false;

View File

@ -19,8 +19,7 @@ nscoord ServoStyleSet::EvaluateSourceSizeList(
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveServoStyle(
const dom::Element& aElement) {
// TODO(emilio): mRawSet isn't used by this function, remove.
return Servo_ResolveStyle(&aElement, mRawSet.get()).Consume();
return Servo_ResolveStyle(&aElement).Consume();
}
} // namespace mozilla

View File

@ -385,6 +385,7 @@ skip-if = toolkit == 'android' # TIMED_OUT for android
[test_webkit_flex_display.html]
[test_first_letter_restrictions.html]
[test_first_line_restrictions.html]
[test_marker_restrictions.html]
[test_placeholder_restrictions.html]
[test_mql_event_listener_leaks.html]
[test_non_matching_sheet_media.html]

View File

@ -3516,6 +3516,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
/* XXX should test currentColor, but may or may not be initial */
@ -3560,6 +3561,7 @@ var gCSSProperties = {
domProp: "content",
inherited: false,
type: CSS_TYPE_LONGHAND,
applies_to_marker: true,
/* XXX needs to be on pseudo-elements */
initial_values: [ "normal", "none" ],
other_values: [ '""', "''", '"hello"', "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==')", 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==")', 'counter(foo)', 'counter(bar, upper-roman)', 'counters(foo, ".")', "counters(bar, '-', lower-greek)", "'-' counter(foo) '.'", "attr(title)", "open-quote", "close-quote", "no-open-quote", "no-close-quote", "close-quote attr(title) counters(foo, '.', upper-alpha)", "counter(foo, none)", "counters(bar, '.', none)", "attr(\\32)", "attr(\\2)", "attr(-\\2)", "attr(-\\32)", "counter(\\2)", "counters(\\32, '.')", "counter(-\\32, upper-roman)", "counters(-\\2, '-', lower-greek)", "counter(\\()", "counters(a\\+b, '.')", "counter(\\}, upper-alpha)", "-moz-alt-content", "counter(foo, symbols('*'))", "counter(foo, symbols(numeric '0' '1'))", "counters(foo, '.', symbols('*'))", "counters(foo, '.', symbols(numeric '0' '1'))" ],
@ -3615,6 +3617,7 @@ var gCSSProperties = {
domProp: "direction",
inherited: true,
type: CSS_TYPE_LONGHAND,
applies_to_marker: true,
initial_values: [ "ltr" ],
other_values: [ "rtl" ],
invalid_values: []
@ -3705,6 +3708,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ (gInitialFontFamilyIsSansSerif ? "sans-serif" : "serif") ],
@ -3717,6 +3721,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3741,6 +3746,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "auto" ],
@ -3753,6 +3759,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3765,6 +3772,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "medium",
@ -3790,6 +3798,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "none" ],
@ -3802,6 +3811,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3814,6 +3824,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3826,6 +3837,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "weight style" ],
@ -3853,6 +3865,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3869,6 +3882,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3881,6 +3895,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3895,6 +3910,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3914,6 +3930,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3931,6 +3948,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal" ],
@ -3943,6 +3961,7 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
initial_values: [ "normal", "400" ],
@ -4762,6 +4781,7 @@ var gCSSProperties = {
inherited: true,
type: CSS_TYPE_LONGHAND,
applies_to_cue: true,
applies_to_marker: true,
initial_values: [ "none" ],
other_values: [ "all" ],
invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0",
@ -5003,6 +5023,7 @@ var gCSSProperties = {
domProp: "unicodeBidi",
inherited: false,
type: CSS_TYPE_LONGHAND,
applies_to_marker: true,
initial_values: [ "normal" ],
other_values: [ "embed", "bidi-override", "isolate", "plaintext", "isolate-override" ],
invalid_values: [ "auto", "none", "-moz-isolate", "-moz-plaintext", "-moz-isolate-override" ]
@ -6275,6 +6296,7 @@ var gCSSProperties = {
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
alias_for: "font-feature-settings",
@ -6286,6 +6308,7 @@ var gCSSProperties = {
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_marker: true,
applies_to_placeholder: true,
applies_to_cue: true,
alias_for: "font-language-override",
@ -7520,6 +7543,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.font-variations.enabled")) {
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_placeholder: true,
applies_to_marker: true,
applies_to_cue: true,
initial_values: [ "normal" ],
other_values: [
@ -7547,6 +7571,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.font-variations.enabled")) {
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_placeholder: true,
applies_to_marker: true,
applies_to_cue: true,
initial_values: [ "auto" ],
other_values: [ "none" ],
@ -8213,6 +8238,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.osx-font-smoothing.enabled")) {
applies_to_first_line: true,
applies_to_placeholder: true,
applies_to_cue: true,
applies_to_marker: true,
initial_values: [ "auto" ],
other_values: [ "grayscale" ],
invalid_values: [ "none", "subpixel-antialiased", "antialiased" ]

View File

@ -0,0 +1,35 @@
<!doctype html>
<meta charset="utf-8">
<title>Test for ::marker property restrictions.</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="property_database.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<style id="s"></style>
<div id="test"></div>
<div id="control"></div>
<script>
const test = getComputedStyle($("test"), "::marker");
const control = getComputedStyle($("control"), "::marker");
for (const prop in gCSSProperties) {
const info = gCSSProperties[prop];
if (info.type == CSS_TYPE_TRUE_SHORTHAND)
continue;
let prereqs = "";
if (info.prerequisites)
for (let name in info.prerequisites)
prereqs += `${name}: ${info.prerequisites[name]}; `;
$("s").textContent = `
#control::marker { ${prop}: ${info.initial_values[0]}; ${prereqs} }
#test::marker { ${prop}: ${info.other_values[0]}; ${prereqs} }
`;
(info.applies_to_marker ? isnot : is)(
get_computed_value(test, prop),
get_computed_value(control, prop),
`${prop} should ${info.applies_to_marker ? "" : " not"} apply to ::marker`);
}
</script>

View File

@ -539,7 +539,9 @@ class BackgroundClipRenderingObserver : public SVGRenderingObserver {
NS_DECL_ISUPPORTS
private:
virtual ~BackgroundClipRenderingObserver() { StopObserving(); }
// We do not call StopObserving() since the observing and observed element
// are the same element (and because we could crash - see bug 1556441).
virtual ~BackgroundClipRenderingObserver() = default;
Element* GetReferencedElementWithoutObserving() final {
return mFrame->GetContent()->AsElement();

View File

@ -282,21 +282,50 @@ int32_t nsScrollbarFrame::MoveToNewPosition() {
return curpos;
}
static already_AddRefed<Element> MakeScrollbarButton(
dom::NodeInfo* aNodeInfo, bool aVertical, bool aBottom, bool aDown,
AnonymousContentKey& aKey) {
MOZ_ASSERT(aNodeInfo);
MOZ_ASSERT(
aNodeInfo->Equals(nsGkAtoms::scrollbarbutton, nullptr, kNameSpaceID_XUL));
static constexpr nsLiteralString kSbattrValues[2][2] = {
{
NS_LITERAL_STRING("scrollbar-up-top"),
NS_LITERAL_STRING("scrollbar-up-bottom"),
},
{
NS_LITERAL_STRING("scrollbar-down-top"),
NS_LITERAL_STRING("scrollbar-down-bottom"),
},
};
static constexpr nsLiteralString kTypeValues[2] = {
NS_LITERAL_STRING("decrement"),
NS_LITERAL_STRING("increment"),
};
aKey = AnonymousContentKey::Type_ScrollbarButton;
if (aVertical) {
aKey |= AnonymousContentKey::Flag_Vertical;
}
if (aBottom) {
aKey |= AnonymousContentKey::Flag_ScrollbarButton_Bottom;
}
if (aDown) {
aKey |= AnonymousContentKey::Flag_ScrollbarButton_Down;
}
RefPtr<Element> e;
NS_TrustedNewXULElement(getter_AddRefs(e), do_AddRef(aNodeInfo));
e->SetAttr(kNameSpaceID_None, nsGkAtoms::sbattr,
kSbattrValues[aDown][aBottom], false);
e->SetAttr(kNameSpaceID_None, nsGkAtoms::type, kTypeValues[aDown], false);
return e.forget();
}
nsresult nsScrollbarFrame::CreateAnonymousContent(
nsTArray<ContentInfo>& aElements) {
// clang-format off
// <xul:scrollbarbutton sbattr="scrollbar-up-top" type="decrement" xbl:inherits="curpos,maxpos,disabled"/>
// <xul:scrollbarbutton sbattr="scrollbar-down-top" type="increment" xbl:inherits="curpos,maxpos,disabled"/>
// <xul:slider flex="1" xbl:inherits="disabled,curpos,maxpos,pageincrement,increment,orient">
// <xul:thumb sbattr="scrollbar-thumb" xbl:inherits="orient,collapsed=disabled"
// align="center" pack="center"/>
// </xul:slider>
// <xul:scrollbarbutton sbattr="scrollbar-up-bottom" type="decrement" xbl:inherits="curpos,maxpos,disabled"/>
// <xul:scrollbarbutton sbattr="scrollbar-down-bottom" type="increment" xbl:inherits="curpos,maxpos,disabled"/>
// clang-format on
nsNodeInfoManager* nodeInfoManager = mContent->NodeInfo()->NodeInfoManager();
Element* el(GetContent()->AsElement());
@ -309,82 +338,79 @@ nsresult nsScrollbarFrame::CreateAnonymousContent(
nsAutoString orient;
el->GetAttr(kNameSpaceID_None, nsGkAtoms::orient, orient);
bool vertical = orient.EqualsLiteral("vertical");
NS_TrustedNewXULElement(
getter_AddRefs(mUpTopButton),
RefPtr<dom::NodeInfo> sbbNodeInfo =
nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbarbutton, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE));
mUpTopButton->SetAttr(kNameSpaceID_None, nsGkAtoms::sbattr,
NS_LITERAL_STRING("scrollbar-up-top"), false);
mUpTopButton->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("decrement"), false);
kNameSpaceID_XUL, nsINode::ELEMENT_NODE);
if (!aElements.AppendElement(mUpTopButton)) {
return NS_ERROR_OUT_OF_MEMORY;
{
AnonymousContentKey key;
mUpTopButton =
MakeScrollbarButton(sbbNodeInfo, vertical, /* aBottom */ false,
/* aDown */ false, key);
aElements.AppendElement(ContentInfo(mUpTopButton, key));
}
NS_TrustedNewXULElement(
getter_AddRefs(mDownTopButton),
nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbarbutton, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE));
mDownTopButton->SetAttr(kNameSpaceID_None, nsGkAtoms::sbattr,
NS_LITERAL_STRING("scrollbar-down-top"), false);
mDownTopButton->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("increment"), false);
if (!aElements.AppendElement(mDownTopButton)) {
return NS_ERROR_OUT_OF_MEMORY;
{
AnonymousContentKey key;
mDownTopButton =
MakeScrollbarButton(sbbNodeInfo, vertical, /* aBottom */ false,
/* aDown */ true, key);
aElements.AppendElement(ContentInfo(mDownTopButton, key));
}
NS_TrustedNewXULElement(
getter_AddRefs(mSlider),
nodeInfoManager->GetNodeInfo(nsGkAtoms::slider, nullptr, kNameSpaceID_XUL,
nsINode::ELEMENT_NODE));
mSlider->SetAttr(kNameSpaceID_None, nsGkAtoms::orient, orient, false);
mSlider->SetAttr(kNameSpaceID_None, nsGkAtoms::flex, NS_LITERAL_STRING("1"),
false);
{
AnonymousContentKey key = AnonymousContentKey::Type_Slider;
if (vertical) {
key |= AnonymousContentKey::Flag_Vertical;
}
if (!aElements.AppendElement(mSlider)) {
return NS_ERROR_OUT_OF_MEMORY;
NS_TrustedNewXULElement(
getter_AddRefs(mSlider),
nodeInfoManager->GetNodeInfo(nsGkAtoms::slider, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE));
mSlider->SetAttr(kNameSpaceID_None, nsGkAtoms::orient, orient, false);
mSlider->SetAttr(kNameSpaceID_None, nsGkAtoms::flex, NS_LITERAL_STRING("1"),
false);
aElements.AppendElement(ContentInfo(mSlider, key));
NS_TrustedNewXULElement(
getter_AddRefs(mThumb),
nodeInfoManager->GetNodeInfo(nsGkAtoms::thumb, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE));
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::orient, orient, false);
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::align,
NS_LITERAL_STRING("center"), false);
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::pack,
NS_LITERAL_STRING("center"), false);
mSlider->AppendChildTo(mThumb, false);
}
NS_TrustedNewXULElement(
getter_AddRefs(mThumb),
nodeInfoManager->GetNodeInfo(nsGkAtoms::thumb, nullptr, kNameSpaceID_XUL,
nsINode::ELEMENT_NODE));
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::sbattr,
NS_LITERAL_STRING("scrollbar-thumb"), false);
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::orient, orient, false);
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::align,
NS_LITERAL_STRING("center"), false);
mThumb->SetAttr(kNameSpaceID_None, nsGkAtoms::pack,
NS_LITERAL_STRING("center"), false);
mSlider->AppendChildTo(mThumb, false);
NS_TrustedNewXULElement(
getter_AddRefs(mUpBottomButton),
nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbarbutton, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE));
mUpBottomButton->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("decrement"), false);
mUpBottomButton->SetAttr(kNameSpaceID_None, nsGkAtoms::sbattr,
NS_LITERAL_STRING("scrollbar-up-bottom"), false);
if (!aElements.AppendElement(mUpBottomButton)) {
return NS_ERROR_OUT_OF_MEMORY;
{
AnonymousContentKey key;
mUpBottomButton =
MakeScrollbarButton(sbbNodeInfo, vertical, /* aBottom */ true,
/* aDown */ false, key);
aElements.AppendElement(ContentInfo(mUpBottomButton, key));
}
NS_TrustedNewXULElement(
getter_AddRefs(mDownBottomButton),
nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbarbutton, nullptr,
kNameSpaceID_XUL, nsINode::ELEMENT_NODE));
mDownBottomButton->SetAttr(kNameSpaceID_None, nsGkAtoms::sbattr,
NS_LITERAL_STRING("scrollbar-down-bottom"), false);
mDownBottomButton->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("increment"), false);
{
AnonymousContentKey key;
mDownBottomButton =
MakeScrollbarButton(sbbNodeInfo, vertical, /* aBottom */ true,
/* aDown */ true, key);
aElements.AppendElement(ContentInfo(mDownBottomButton, key));
}
if (!aElements.AppendElement(mDownBottomButton)) {
return NS_ERROR_OUT_OF_MEMORY;
// Don't cache styles if we are inside a <select> element, since we have
// some UA style sheet rules that depend on the <select>'s attributes.
if (GetContent()->GetParent() &&
GetContent()->GetParent()->IsHTMLElement(nsGkAtoms::select)) {
for (auto& info : aElements) {
info.mKey = AnonymousContentKey::None;
}
}
UpdateChildrenAttributeValue(nsGkAtoms::curpos, false);

View File

@ -4703,6 +4703,14 @@ VARCACHE_PREF(
RelaxedAtomicUint32, 4096
)
// Is the codepath for using cached scrollbar styles enabled?
VARCACHE_PREF(
Live,
"layout.css.cached-scrollbar-styles.enabled",
layout_css_cached_scrollbar_styles_enabled,
bool, false
)
// Is path() supported in clip-path?
VARCACHE_PREF(
Live,
@ -4903,6 +4911,17 @@ VARCACHE_PREF(
bool, false
)
// Pref to control whether the ::marker property restrictions defined in [1]
// apply.
//
// [1]: https://drafts.csswg.org/css-pseudo-4/#selectordef-marker
VARCACHE_PREF(
Live,
"layout.css.marker.restricted",
layout_css_marker_restricted,
bool, true
)
// Pref to control whether @-moz-document rules are enabled in content pages.
VARCACHE_PREF(
Live,

View File

@ -182,13 +182,18 @@ impl PseudoElement {
/// Property flag that properties must have to apply to this pseudo-element.
#[inline]
pub fn property_restriction(&self) -> Option<PropertyFlags> {
match *self {
PseudoElement::FirstLetter => Some(PropertyFlags::APPLIES_TO_FIRST_LETTER),
PseudoElement::FirstLine => Some(PropertyFlags::APPLIES_TO_FIRST_LINE),
PseudoElement::Placeholder => Some(PropertyFlags::APPLIES_TO_PLACEHOLDER),
PseudoElement::Cue => Some(PropertyFlags::APPLIES_TO_CUE),
_ => None,
}
Some(match *self {
PseudoElement::FirstLetter => PropertyFlags::APPLIES_TO_FIRST_LETTER,
PseudoElement::FirstLine => PropertyFlags::APPLIES_TO_FIRST_LINE,
PseudoElement::Placeholder => PropertyFlags::APPLIES_TO_PLACEHOLDER,
PseudoElement::Cue => PropertyFlags::APPLIES_TO_CUE,
PseudoElement::Marker
if unsafe { structs::StaticPrefs::sVarCache_layout_css_marker_restricted } =>
{
PropertyFlags::APPLIES_TO_MARKER
},
_ => return None,
})
}
/// Whether this pseudo-element should actually exist if it has

View File

@ -13,6 +13,7 @@ ${helpers.predefined_type(
initial_specified_value="specified::Content::normal()",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-content/#propdef-content",
flags="APPLIES_TO_MARKER",
servo_restyle_damage="rebuild_and_reflow",
)}

View File

@ -12,7 +12,7 @@ ${helpers.predefined_type(
"FontFamily",
initial_value="computed::FontFamily::serif()",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-family",
servo_restyle_damage="rebuild_and_reflow",
)}
@ -23,7 +23,7 @@ ${helpers.predefined_type(
initial_value="computed::FontStyle::normal()",
initial_specified_value="specified::FontStyle::normal()",
animation_value_type="FontStyle",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-style",
servo_restyle_damage="rebuild_and_reflow",
)}
@ -42,7 +42,7 @@ ${helpers.single_keyword_system(
gecko_ffi_name="mFont.variantCaps",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps",
custom_consts=font_variant_caps_custom_consts,
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
animation_value_type="discrete",
servo_restyle_damage="rebuild_and_reflow",
)}
@ -53,7 +53,7 @@ ${helpers.predefined_type(
initial_value="computed::FontWeight::normal()",
initial_specified_value="specified::FontWeight::normal()",
animation_value_type="Number",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight",
servo_restyle_damage="rebuild_and_reflow",
)}
@ -65,7 +65,7 @@ ${helpers.predefined_type(
initial_specified_value="specified::FontSize::medium()",
animation_value_type="NonNegativeLength",
allow_quirks="Yes",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size",
servo_restyle_damage="rebuild_and_reflow",
)}
@ -77,7 +77,7 @@ ${helpers.predefined_type(
initial_value="computed::FontSizeAdjust::none()",
initial_specified_value="specified::FontSizeAdjust::none()",
animation_value_type="ComputedValue",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust",
)}
@ -87,7 +87,7 @@ ${helpers.predefined_type(
products="gecko",
initial_value="specified::FontSynthesis::get_initial_value()",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-synthesis",
)}
@ -97,7 +97,7 @@ ${helpers.predefined_type(
initial_value="computed::FontStretch::hundred()",
initial_specified_value="specified::FontStretch::normal()",
animation_value_type="Percentage",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch",
servo_restyle_damage="rebuild_and_reflow",
)}
@ -109,7 +109,7 @@ ${helpers.single_keyword_system(
gecko_ffi_name="mFont.kerning",
gecko_constant_prefix="NS_FONT_KERNING",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-kerning",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
animation_value_type="discrete",
)}
@ -120,7 +120,7 @@ ${helpers.predefined_type(
initial_value="computed::FontVariantAlternates::get_initial_value()",
initial_specified_value="specified::FontVariantAlternates::get_initial_specified_value()",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates",
)}
@ -131,7 +131,7 @@ ${helpers.predefined_type(
initial_value="computed::FontVariantEastAsian::empty()",
initial_specified_value="specified::FontVariantEastAsian::empty()",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian",
)}
@ -142,7 +142,7 @@ ${helpers.predefined_type(
initial_value="computed::FontVariantLigatures::empty()",
initial_specified_value="specified::FontVariantLigatures::empty()",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures",
)}
@ -153,7 +153,7 @@ ${helpers.predefined_type(
initial_value="computed::FontVariantNumeric::empty()",
initial_specified_value="specified::FontVariantNumeric::empty()",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric",
)}
@ -164,7 +164,7 @@ ${helpers.single_keyword_system(
gecko_ffi_name="mFont.variantPosition",
gecko_constant_prefix="NS_FONT_VARIANT_POSITION",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
animation_value_type="discrete",
)}
@ -176,7 +176,7 @@ ${helpers.predefined_type(
initial_specified_value="specified::FontFeatureSettings::normal()",
extra_prefixes="moz:layout.css.prefixes.font-features",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings",
)}
@ -195,7 +195,7 @@ ${helpers.predefined_type(
initial_value="computed::FontVariationSettings::normal()",
initial_specified_value="specified::FontVariationSettings::normal()",
animation_value_type="ComputedValue",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="${variation_spec}",
)}
@ -207,7 +207,7 @@ ${helpers.predefined_type(
initial_specified_value="specified::FontLanguageOverride::normal()",
animation_value_type="discrete",
extra_prefixes="moz:layout.css.prefixes.font-features",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override",
)}
@ -219,7 +219,7 @@ ${helpers.single_keyword_system(
gecko_ffi_name="mFont.opticalSizing",
gecko_constant_prefix="NS_FONT_OPTICAL_SIZING",
animation_value_type="discrete",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
spec="https://www.w3.org/TR/css-fonts-4/#font-optical-sizing-def",
)}
@ -514,7 +514,7 @@ ${helpers.single_keyword(
gecko_pref="layout.css.osx-font-smoothing.enabled",
products="gecko",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
animation_value_type="discrete",
)}

View File

@ -38,6 +38,7 @@ ${helpers.single_keyword(
animation_value_type="none",
spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
needs_conversion=True,
flags="APPLIES_TO_MARKER",
servo_restyle_damage="rebuild_and_reflow",
)}

View File

@ -11,7 +11,7 @@ ${helpers.predefined_type(
"ColorPropertyValue",
"::cssparser::RGBA::new(0, 0, 0, 255)",
animation_value_type="AnimatedRGBA",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
flags="APPLIES_TO_CUE APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER APPLIES_TO_MARKER",
ignored_when_colors_disabled="True",
spec="https://drafts.csswg.org/css-color/#color",
)}
@ -349,7 +349,7 @@ ${helpers.single_keyword(
products="gecko",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-writing-modes-3/#text-combine-upright",
flags="APPLIES_TO_CUE",
flags="APPLIES_TO_CUE APPLIES_TO_MARKER",
)}
// SVG 1.1: Section 11 - Painting: Filling, Stroking and Marker Symbols

View File

@ -23,6 +23,7 @@ ${helpers.single_keyword(
"normal embed isolate bidi-override isolate-override plaintext",
animation_value_type="none",
spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi",
flags="APPLIES_TO_MARKER",
servo_restyle_damage="rebuild_and_reflow",
)}

View File

@ -956,13 +956,15 @@ bitflags! {
const APPLIES_TO_PLACEHOLDER = 1 << 5;
/// This longhand property applies to ::cue.
const APPLIES_TO_CUE = 1 << 6;
/// This longhand property applies to ::marker.
const APPLIES_TO_MARKER = 1 << 7;
/// This property's getComputedStyle implementation requires layout
/// to be flushed.
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 7;
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 8;
/// This property is a legacy shorthand.
///
/// https://drafts.csswg.org/css-cascade/#legacy-shorthand
const IS_LEGACY_SHORTHAND = 1 << 8;
const IS_LEGACY_SHORTHAND = 1 << 9;
/* The following flags are currently not used in Rust code, they
* only need to be listed in corresponding properties so that
@ -2836,6 +2838,19 @@ impl ComputedValues {
pub fn resolve_color(&self, color: computed::Color) -> RGBA {
color.to_rgba(self.get_inherited_text().clone_color())
}
/// Returns which longhand properties have different values in the two
/// ComputedValues.
#[cfg(feature = "gecko_debug")]
pub fn differing_properties(&self, other: &ComputedValues) -> LonghandIdSet {
let mut set = LonghandIdSet::new();
% for prop in data.longhands:
if self.clone_${prop.ident}() != other.clone_${prop.ident}() {
set.insert(LonghandId::${prop.camel_case});
}
% endfor
set
}
}
#[cfg(feature = "servo")]

View File

@ -3746,6 +3746,69 @@ pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(
}))
}
/// println_stderr!() calls Gecko's printf_stderr(), which, unlike eprintln!(),
/// will funnel output to Android logcat.
#[cfg(feature = "gecko_debug")]
macro_rules! println_stderr {
($($e:expr),+) => {
{
let mut s = nsCString::new();
write!(s, $($e),+).unwrap();
s.write_char('\n').unwrap();
unsafe { bindings::Gecko_PrintfStderr(&s); }
}
}
}
#[cfg(feature = "gecko_debug")]
fn dump_properties_and_rules(cv: &ComputedValues, properties: &LonghandIdSet) {
println_stderr!(" Properties:");
for p in properties.iter() {
let mut v = String::new();
cv.get_longhand_property_value(p, &mut CssWriter::new(&mut v)).unwrap();
println_stderr!(" {:?}: {}", p, v);
}
println_stderr!(" Rules:");
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
for rn in cv.rules().self_and_ancestors() {
if rn.importance().important() {
continue;
}
if let Some(d) = rn.style_source().and_then(|s| s.as_declarations()) {
println_stderr!(" [DeclarationBlock: {:?}]", d);
}
if let Some(r) = rn.style_source().and_then(|s| s.as_rule()) {
let mut s = nsString::new();
r.read_with(&guard).to_css(&guard, &mut s).unwrap();
println_stderr!(" {}", s);
}
}
}
#[cfg(feature = "gecko_debug")]
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_EqualForCachedAnonymousContentStyle(
a: &ComputedValues,
b: &ComputedValues,
) -> bool {
let mut differing_properties = a.differing_properties(b);
// Ignore any difference in -x-lang, which we can't override in the
// rules in minimal-xul.css, but which makes no difference for the
// anonymous content subtrees we cache style for.
differing_properties.remove(LonghandId::XLang);
if !differing_properties.is_empty() {
println_stderr!("Actual style:");
dump_properties_and_rules(a, &differing_properties);
println_stderr!("Expected style:");
dump_properties_and_rules(b, &differing_properties);
}
differing_properties.is_empty()
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_Init(doc: &structs::Document) -> *mut RawServoStyleSet {
let data = Box::new(PerDocumentStyleData::new(doc));
@ -5089,7 +5152,6 @@ pub extern "C" fn Servo_TakeChangeHint(
#[no_mangle]
pub extern "C" fn Servo_ResolveStyle(
element: &RawGeckoElement,
_raw_data: &RawServoStyleSet,
) -> Strong<ComputedValues> {
let element = GeckoElement(element);
debug!("Servo_ResolveStyle: {:?}", element);

View File

@ -13,9 +13,7 @@
% http://localhost/tests/perf-reftest-singletons/tiny-traversal-singleton.html
% http://localhost/tests/perf-reftest-singletons/nth-index-1.html
% http://localhost/tests/perf-reftest-singletons/nth-index-2.html
% http://localhost/tests/perf-reftest-singletons/bidi-resolution-1.html
% http://localhost/tests/perf-reftest-singletons/id-getter-1.html
% http://localhost/tests/perf-reftest-singletons/id-getter-2.html
% http://localhost/tests/perf-reftest-singletons/id-getter-3.html
@ -23,5 +21,5 @@
% http://localhost/tests/perf-reftest-singletons/id-getter-5.html
% http://localhost/tests/perf-reftest-singletons/id-getter-6.html
% http://localhost/tests/perf-reftest-singletons/id-getter-7.html
% http://localhost/tests/perf-reftest-singletons/abspos-reflow-1.html
% http://localhost/tests/perf-reftest-singletons/scrollbar-styles-1.html

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<style>
div { overflow: auto; }
</style>
<script src="util.js"></script>
<script>
window.onload = function() {
let root = document.createElement("div");
root.appendChild(build_dom(10000, "div"));
document.body.appendChild(root);
perf_start();
flush_layout(root);
perf_finish();
};
</script>
<body></body>

View File

@ -1 +1 @@
prefs: [dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true]
prefs: [dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true, layout.css.marker.restricted:false]

View File

@ -0,0 +1,2 @@
[marker-content-007.html]
prefs: [layout.css.marker.restricted:false]

View File

@ -0,0 +1,2 @@
[marker-content-008.html]
prefs: [layout.css.marker.restricted:false]

View File

@ -0,0 +1,2 @@
[marker-content-009.html]
prefs: [layout.css.marker.restricted:false]

View File

@ -0,0 +1,2 @@
[marker-content-011.html]
prefs: [layout.css.marker.restricted:false]

View File

@ -1 +1 @@
prefs: [dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true]
prefs: [dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true, layout.css.marker.restricted:false]

View File

@ -1 +1 @@
prefs: [dom.animations-api.autoremove.enabled:true, dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true]
prefs: [dom.animations-api.autoremove.enabled:true, dom.animations-api.compositing.enabled:true, dom.animations-api.core.enabled:true, dom.animations-api.getAnimations.enabled:true, dom.animations-api.implicit-keyframes.enabled:true, dom.animations-api.timelines.enabled:true, layout.css.step-position-jump.enabled:true, layout.css.marker.restricted:false]

View File

@ -17,22 +17,34 @@ correctly set into inactive state when permission is revoked.</p>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
var t = async_test("Tests that the video MediaStreamTrack objects are properly ended on permission revocation");
t.step(function () {
navigator.mediaDevices.getUserMedia({audio: true,video: true}).then(t.step_func(function (stream) {
var vidTrack = stream.getVideoTracks()[0];
assert_equals(vidTrack.readyState, "live", "The video track object is in live state");
var audTrack = stream.getAudioTracks()[0];
assert_equals(audTrack.readyState, "live", "The audio track object is in live state");
vidTrack.onended = t.step_func(function () {
assert_equals(vidTrack.readyState, "ended", "Video track has been ended as expected");
assert_equals(audTrack.readyState, "ended", "Audio track has been ended as expected");
assert_false(stream.active, "MediaStream has been inactive as expected");
t.done();
});
}), function (error) {}
);
});
'use strict';
promise_test(async t => {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
});
const vidTrack = stream.getVideoTracks()[0];
assert_equals(vidTrack.readyState, "live",
"The video track object is in live state");
const vidEnded = new Promise(r => vidTrack.onended = r);
const audTrack = stream.getAudioTracks()[0];
assert_equals(audTrack.readyState, "live",
"The audio track object is in live state");
const audEnded = new Promise(r => audTrack.onended = r);
await Promise.race([vidEnded, audEnded]);
assert_equals(stream.getTracks().filter(t => t.readyState == "ended").length,
1, "Only one track is ended after first track's ended event");
assert_equals(stream.getTracks().filter(t => t.readyState == "live").length,
1, "One track is still live after first track's ended event");
assert_true(stream.active, "MediaStream is still active");
await Promise.all([vidEnded, audEnded]);
assert_equals(vidTrack.readyState, "ended", "Video track ended as expected");
assert_equals(audTrack.readyState, "ended", "Audio track ended as expected");
assert_false(stream.active, "MediaStream has become inactive as expected");
}, "Tests that MediaStreamTracks end properly on permission revocation");
</script>
</body>
</html>

View File

@ -20,4 +20,14 @@ test(() => {
const mediaStream = new MediaStream();
assert_throws(new TypeError(), () => URL.createObjectURL(mediaStream));
}, "Passing MediaStream to URL.createObjectURL() should throw");
test(() => {
const mediaStream = new MediaStream();
assert_false("onactive" in mediaStream);
}, "MediaStream.onactive should not exist");
test(() => {
const mediaStream = new MediaStream();
assert_false("oninactive" in mediaStream);
}, "MediaStream.oninactive should not exist");
</script>

View File

@ -38,6 +38,61 @@
visibility: collapse;
}
/* Rules required for style caching of anonymous content scrollbar parts */
scrollcorner, resizer, scrollbar, scrollbarbutton, slider {
/* All scrollbar parts must not inherit any properties from the scrollable
* element (except for visibility), for the anonymous content style caching
* system to work.
*/
all: initial;
visibility: inherit;
/* These properties are not included in 'all'. */
-moz-list-reversed: initial;
-moz-font-smoothing-background-color: initial;
/* Using initial is not sufficient for direction, since its initial value can
* depend on the document's language.
*
* LTR is what we want for all scrollbar parts anyway, so that e.g. we don't
* reverse the rendering of a horizontal scrollbar.
*/
direction: ltr;
/* Similarly for font properties, whose initial values depend on the
* document's language. Scrollbar parts don't have any text or rely on
* font metrics.
*/
font: 16px sans-serif;
/* Duplicate the rules from the '*' rule above, which were clobbered by the
* 'all: initial' declaration.
*
* The other zero specificity rules above are on :root, and scrollbar parts
* cannot match :root, so no need to duplicate them.
*/
-moz-user-focus: ignore;
-moz-user-select: none;
display: -moz-box;
box-sizing: border-box;
}
thumb {
/* Prevent -moz-user-modify declaration from designmode.css having an
* effect. */
-moz-user-modify: initial;
}
/* There are other rules that set direction and cursor on scrollbar,
* expecting them to inherit into its children. Explicitly inherit those,
* overriding the 'all: initial; direction: ltr;' declarations above.
*/
scrollbarbutton, slider, thumb {
direction: inherit;
cursor: inherit;
}
/********** resizer **********/
resizer {
@ -97,11 +152,6 @@ resizer[dir="topright"] {
/********** scrollbar **********/
/* Scrollbars are never flipped even if BiDI kicks in. */
scrollbar[orient="horizontal"] {
direction: ltr;
}
thumb {
display: -moz-box !important;
}
@ -152,7 +202,7 @@ scrollbar[value="hidden"] {
}
@media (-moz-scrollbar-thumb-proportional) {
thumb[sbattr="scrollbar-thumb"] {
thumb {
-moz-box-flex: 1;
}
}