summaryrefslogtreecommitdiffstats
path: root/layout/style/nsCSSProps.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/style/nsCSSProps.h')
-rw-r--r--layout/style/nsCSSProps.h247
1 files changed, 247 insertions, 0 deletions
diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h
new file mode 100644
index 0000000000..a73fafc021
--- /dev/null
+++ b/layout/style/nsCSSProps.h
@@ -0,0 +1,247 @@
+/* -*- 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/. */
+
+/*
+ * methods for dealing with CSS properties and tables of the keyword
+ * values they accept
+ */
+
+#ifndef nsCSSProps_h___
+#define nsCSSProps_h___
+
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
+#include "nsString.h"
+#include "nsCSSPropertyID.h"
+#include "nsStyleStructFwd.h"
+#include "mozilla/UseCounter.h"
+#include "mozilla/CSSEnabledState.h"
+#include "mozilla/CSSPropFlags.h"
+#include "mozilla/EnumTypeTraits.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/gfx/gfxVarReceiver.h"
+#include "nsXULAppAPI.h"
+
+// Length of the "--" prefix on custom names (such as custom property names,
+// and, in the future, custom media query names).
+#define CSS_CUSTOM_NAME_PREFIX_LENGTH 2
+
+namespace mozilla {
+class ComputedStyle;
+}
+
+extern "C" {
+nsCSSPropertyID Servo_ResolveLogicalProperty(nsCSSPropertyID,
+ const mozilla::ComputedStyle*);
+nsCSSPropertyID Servo_Property_LookupEnabledForAllContent(const nsACString*);
+const uint8_t* Servo_Property_GetName(nsCSSPropertyID, uint32_t* aLength);
+}
+
+class nsCSSProps {
+ public:
+ typedef mozilla::CSSEnabledState EnabledState;
+ typedef mozilla::CSSPropFlags Flags;
+
+ static void AddRefTable(void);
+ static void ReleaseTable(void);
+
+ // Looks up the property with name aProperty and returns its corresponding
+ // nsCSSPropertyID value. If aProperty is the name of a custom property,
+ // then eCSSPropertyExtra_variable will be returned.
+ //
+ // This only returns properties enabled for all content, and resolves aliases
+ // to return the aliased property.
+ static nsCSSPropertyID LookupProperty(const nsACString& aProperty) {
+ return Servo_Property_LookupEnabledForAllContent(&aProperty);
+ }
+
+ // As above, but looked up using a property's IDL name.
+ // eCSSPropertyExtra_variable won't be returned from this method.
+ static nsCSSPropertyID LookupPropertyByIDLName(
+ const nsACString& aPropertyIDLName, EnabledState aEnabled);
+
+ // Returns whether aProperty is a custom property name, i.e. begins with
+ // "--". This assumes that the CSS Variables pref has been enabled.
+ static bool IsCustomPropertyName(const nsACString& aProperty);
+
+ static bool IsShorthand(nsCSSPropertyID aProperty) {
+ MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
+ "out of range");
+ return (aProperty >= eCSSProperty_COUNT_no_shorthands);
+ }
+
+ // Same but for @font-face descriptors
+ static nsCSSFontDesc LookupFontDesc(const nsACString& aProperty);
+
+ // The relevant invariants are asserted in Document.cpp
+ static mozilla::UseCounter UseCounterFor(nsCSSPropertyID aProperty) {
+ MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_with_aliases,
+ "out of range");
+ return mozilla::UseCounter(size_t(mozilla::eUseCounter_FirstCSSProperty) +
+ size_t(aProperty));
+ }
+
+ // Given a property enum, get the string value
+ //
+ // This string is static.
+ static const nsDependentCSubstring GetStringValue(nsCSSPropertyID aProperty) {
+ uint32_t len;
+ const uint8_t* chars = Servo_Property_GetName(aProperty, &len);
+ return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
+ }
+
+ static const nsCString& GetStringValue(nsCSSFontDesc aFontDesc);
+ static const nsCString& GetStringValue(nsCSSCounterDesc aCounterDesc);
+
+ private:
+ static const Flags kFlagsTable[eCSSProperty_COUNT];
+
+ public:
+ static bool PropHasFlags(nsCSSPropertyID aProperty, Flags aFlags) {
+ MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
+ "out of range");
+ return (nsCSSProps::kFlagsTable[aProperty] & aFlags) == aFlags;
+ }
+
+ static nsCSSPropertyID Physicalize(nsCSSPropertyID aProperty,
+ const mozilla::ComputedStyle& aStyle) {
+ MOZ_ASSERT(!IsShorthand(aProperty));
+ if (PropHasFlags(aProperty, Flags::IsLogical)) {
+ return Servo_ResolveLogicalProperty(aProperty, &aStyle);
+ }
+ return aProperty;
+ }
+
+ private:
+ // A table for shorthand properties. The appropriate index is the
+ // property ID minus eCSSProperty_COUNT_no_shorthands.
+ static const nsCSSPropertyID* const
+ kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands];
+
+ public:
+ /**
+ * Returns true if the backdrop-filter pref and WebRender are enabled.
+ */
+ static bool IsBackdropFilterAvailable(JSContext*, JSObject*) {
+ return IsEnabled(eCSSProperty_backdrop_filter);
+ }
+
+ /**
+ * Recoumputes the enabled state of a pref. If aPrefName is nullptr,
+ * recomputes the state of all prefs in gPropertyEnabled.
+ * aClosure is the pref callback closure data, which is not used.
+ */
+ static void RecomputeEnabledState(const char* aPrefName,
+ void* aClosure = nullptr);
+
+ /**
+ * Retrieve a singleton receiver to register with gfxVars
+ */
+ static mozilla::gfx::gfxVarReceiver& GfxVarReceiver();
+
+ static const nsCSSPropertyID* SubpropertyEntryFor(nsCSSPropertyID aProperty) {
+ MOZ_ASSERT(eCSSProperty_COUNT_no_shorthands <= aProperty &&
+ aProperty < eCSSProperty_COUNT,
+ "out of range");
+ return nsCSSProps::kSubpropertyTable[aProperty -
+ eCSSProperty_COUNT_no_shorthands];
+ }
+
+ private:
+ static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases];
+
+ private:
+ // Defined in the generated nsCSSPropsGenerated.inc.
+ static const char* const kIDLNameTable[eCSSProperty_COUNT];
+
+ public:
+ /**
+ * Returns the IDL name of the specified property, which must be a
+ * longhand, logical or shorthand property. The IDL name is the property
+ * name with any hyphen-lowercase character pairs replaced by an
+ * uppercase character:
+ * https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
+ *
+ * As a special case, the string "cssFloat" is returned for the float
+ * property. nullptr is returned for internal properties.
+ */
+ static const char* PropertyIDLName(nsCSSPropertyID aProperty) {
+ MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
+ "out of range");
+ return kIDLNameTable[aProperty];
+ }
+
+ private:
+ static const int32_t kIDLNameSortPositionTable[eCSSProperty_COUNT];
+
+ public:
+ /**
+ * Returns the position of the specified property in a list of all
+ * properties sorted by their IDL name.
+ */
+ static int32_t PropertyIDLNameSortPosition(nsCSSPropertyID aProperty) {
+ MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
+ "out of range");
+ return kIDLNameSortPositionTable[aProperty];
+ }
+
+ static bool IsEnabled(nsCSSPropertyID aProperty) {
+ MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_with_aliases,
+ "out of range");
+ // In the child process, assert that we're not trying to parse stylesheets
+ // before we've gotten all our prefs.
+ MOZ_ASSERT_IF(!XRE_IsParentProcess(),
+ mozilla::Preferences::ArePrefsInitedInContentProcess());
+ return gPropertyEnabled[aProperty];
+ }
+
+ public:
+ static bool IsEnabled(nsCSSPropertyID aProperty, EnabledState aEnabled) {
+ if (IsEnabled(aProperty)) {
+ return true;
+ }
+ if (aEnabled == EnabledState::IgnoreEnabledState) {
+ return true;
+ }
+ if ((aEnabled & EnabledState::InUASheets) &&
+ PropHasFlags(aProperty, Flags::EnabledInUASheets)) {
+ return true;
+ }
+ if ((aEnabled & EnabledState::InChrome) &&
+ PropHasFlags(aProperty, Flags::EnabledInChrome)) {
+ return true;
+ }
+ return false;
+ }
+
+ public:
+ struct PropertyPref {
+ nsCSSPropertyID mPropID;
+ const char* mPref;
+ };
+ static const PropertyPref kPropertyPrefTable[];
+
+// Storing the enabledstate_ value in an nsCSSPropertyID variable is a small
+// hack to avoid needing a separate variable declaration for its real type
+// (CSSEnabledState), which would then require using a block and
+// therefore a pair of macros by consumers for the start and end of the loop.
+#define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(it_, prop_, enabledstate_) \
+ for (const nsCSSPropertyID * \
+ it_ = nsCSSProps::SubpropertyEntryFor(prop_), \
+ es_ = (nsCSSPropertyID)((enabledstate_) | CSSEnabledState(0)); \
+ *it_ != eCSSProperty_UNKNOWN; ++it_) \
+ if (nsCSSProps::IsEnabled(*it_, (mozilla::CSSEnabledState)es_))
+};
+
+// MOZ_DBG support for nsCSSPropertyID
+
+inline std::ostream& operator<<(std::ostream& aOut, nsCSSPropertyID aProperty) {
+ return aOut << nsCSSProps::GetStringValue(aProperty);
+}
+
+#endif /* nsCSSProps_h___ */