mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Merge mozilla-central to inbound a=merge
This commit is contained in:
commit
3861f1c2b6
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -56,6 +56,7 @@ enum class OpenVRControllerType : uint16_t {
|
||||
Vive,
|
||||
WMR,
|
||||
Knuckles,
|
||||
Cosmos,
|
||||
NumOpenVRControllerTypes
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
204
gfx/vr/service/binding/OpenVRCosmosBinding.h
Normal file
204
gfx/vr/service/binding/OpenVRCosmosBinding.h
Normal 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
|
@ -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"
|
||||
|
@ -11,7 +11,6 @@ namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
struct OpenVRWMRBinding {
|
||||
// OpenVRWMRBinding();
|
||||
const char* binding =
|
||||
// clang-format off
|
||||
"{\n"
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
56
layout/generic/AnonymousContentKey.h
Normal file
56
layout/generic/AnonymousContentKey.h
Normal 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
|
@ -134,6 +134,7 @@ EXPORTS += [
|
||||
EXPORTS.mozilla += [
|
||||
'!FrameIdList.h',
|
||||
'!FrameTypeList.h',
|
||||
'AnonymousContentKey.h',
|
||||
'AspectRatio.h',
|
||||
'AutoCopyListener.h',
|
||||
'ColumnUtils.h',
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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%;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
details {
|
||||
display: inline;
|
||||
}
|
||||
summary::marker {
|
||||
summary {
|
||||
/* Hide the triangle for comparing with div in reftest. */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<html>
|
||||
<style>
|
||||
summary::marker {
|
||||
summary {
|
||||
/* Hide the triangle for comparing with div in reftest. */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
}
|
||||
summary::marker {
|
||||
summary {
|
||||
/* Hide the triangle for comparing with div in reftest. */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
}
|
||||
summary::marker {
|
||||
summary {
|
||||
/* Hide the triangle for comparing with div in reftest. */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
}
|
||||
summary::marker {
|
||||
summary {
|
||||
/* Hide the triangle for comparing with div in reftest. */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -990,6 +990,8 @@ bool ServoStyleSet::EnsureUniqueInnerOnCSSSheets() {
|
||||
void ServoStyleSet::ClearCachedStyleData() {
|
||||
ClearNonInheritingComputedStyles();
|
||||
Servo_StyleSet_RebuildCachedData(mRawSet.get());
|
||||
mCachedAnonymousContentStyles.Clear();
|
||||
PodArrayZero(mCachedAnonymousContentStyleIndexes);
|
||||
}
|
||||
|
||||
void ServoStyleSet::ForceDirtyAllShadowStyles() {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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" ]
|
||||
|
35
layout/style/test/test_marker_restrictions.html
Normal file
35
layout/style/test/test_marker_restrictions.html
Normal 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>
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
)}
|
||||
|
||||
|
@ -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",
|
||||
)}
|
||||
|
||||
|
@ -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",
|
||||
)}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
)}
|
||||
|
||||
|
@ -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")]
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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>
|
@ -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]
|
||||
|
@ -0,0 +1,2 @@
|
||||
[marker-content-007.html]
|
||||
prefs: [layout.css.marker.restricted:false]
|
@ -0,0 +1,2 @@
|
||||
[marker-content-008.html]
|
||||
prefs: [layout.css.marker.restricted:false]
|
@ -0,0 +1,2 @@
|
||||
[marker-content-009.html]
|
||||
prefs: [layout.css.marker.restricted:false]
|
@ -0,0 +1,2 @@
|
||||
[marker-content-011.html]
|
||||
prefs: [layout.css.marker.restricted:false]
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user