--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -32,28 +32,35 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_From
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal)
SERVO_BINDING_FUNC(Servo_StyleSheet_AddRef, void,
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_Release, void,
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_HasRules, bool,
RawServoStyleSheetBorrowed sheet)
+SERVO_BINDING_FUNC(Servo_StyleSheet_GetRules, ServoCssRulesStrong,
+ RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSetOwned)
SERVO_BINDING_FUNC(Servo_StyleSet_Drop, void, RawServoStyleSetOwned set)
SERVO_BINDING_FUNC(Servo_StyleSet_AppendStyleSheet, void,
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet,
RawServoStyleSheetBorrowed reference)
+// CSSRuleList
+SERVO_BINDING_FUNC(Servo_CssRules_ListTypes, void,
+ ServoCssRulesBorrowed rules,
+ nsTArrayBorrowed_uintptr_t result)
+
// Animations API
SERVO_BINDING_FUNC(Servo_ParseProperty,
RawServoDeclarationBlockStrong,
const nsACString* property, const nsACString* value,
const nsACString* base_url, ThreadSafeURIHolder* base,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal)
SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -6,16 +6,17 @@
#ifndef mozilla_ServoBindingTypes_h
#define mozilla_ServoBindingTypes_h
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
struct ServoComputedValues;
+struct ServoCssRules;
struct RawServoStyleSheet;
struct RawServoStyleSet;
struct RawServoDeclarationBlock;
namespace mozilla {
namespace dom {
class Element;
class StyleChildrenIterator;
@@ -67,16 +68,17 @@ typedef nsIDocument RawGeckoDocument;
DECL_BORROWED_MUT_REF_TYPE_FOR(type_)
#define DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_) \
typedef type_* type_##OwnedOrNull; \
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) \
DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR(type_)
DECL_ARC_REF_TYPE_FOR(ServoComputedValues)
+DECL_ARC_REF_TYPE_FOR(ServoCssRules)
DECL_ARC_REF_TYPE_FOR(RawServoStyleSheet)
DECL_ARC_REF_TYPE_FOR(RawServoDeclarationBlock)
// This is a reference to a reference of RawServoDeclarationBlock, which
// corresponds to Option<&Arc<RawServoDeclarationBlock>> in Servo side.
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoDeclarationBlockStrong)
DECL_OWNED_REF_TYPE_FOR(RawServoStyleSet)
DECL_NULLABLE_OWNED_REF_TYPE_FOR(StyleChildrenIterator)
@@ -116,16 +118,17 @@ DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSValu
Servo_##name_##_AddRef(aPtr); \
} \
static void Release(type_* aPtr) { \
Servo_##name_##_Release(aPtr); \
} \
}; \
}
+DEFINE_REFPTR_TRAITS(CssRules, ServoCssRules)
DEFINE_REFPTR_TRAITS(StyleSheet, RawServoStyleSheet)
DEFINE_REFPTR_TRAITS(ComputedValues, ServoComputedValues)
DEFINE_REFPTR_TRAITS(DeclarationBlock, RawServoDeclarationBlock)
#undef DEFINE_REFPTR_TRAITS
extern "C" void Servo_StyleSet_Drop(RawServoStyleSetOwned ptr);
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -40,16 +40,17 @@ using namespace mozilla::dom;
already_AddRefed<type_> \
type_##Strong::Consume() { \
RefPtr<type_> result; \
result.swap(mPtr); \
return result.forget(); \
}
IMPL_STRONG_REF_TYPE_FOR(ServoComputedValues)
+IMPL_STRONG_REF_TYPE_FOR(ServoCssRules)
IMPL_STRONG_REF_TYPE_FOR(RawServoStyleSheet)
IMPL_STRONG_REF_TYPE_FOR(RawServoDeclarationBlock)
#undef IMPL_STRONG_REF_TYPE_FOR
uint32_t
Gecko_ChildrenCount(RawGeckoNodeBorrowed aNode)
{
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -59,16 +59,26 @@ struct nsStyleDisplay;
void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr); \
void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr);
#define NS_IMPL_HOLDER_FFI_REFCOUNTING(class_, name_) \
void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \
{ NS_ADDREF(aPtr); } \
void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \
{ NS_RELEASE(aPtr); } \
+
+#define DEFINE_ARRAY_TYPE_FOR(type_) \
+ struct nsTArrayBorrowed_##type_ { \
+ nsTArray<type_>* mArray; \
+ MOZ_IMPLICIT nsTArrayBorrowed_##type_(nsTArray<type_>* aArray) \
+ : mArray(aArray) {} \
+ }
+DEFINE_ARRAY_TYPE_FOR(uintptr_t);
+#undef DEFINE_ARRAY_TYPE_FOR
+
extern "C" {
// Object refcounting.
NS_DECL_HOLDER_FFI_REFCOUNTING(nsIPrincipal, Principal)
NS_DECL_HOLDER_FFI_REFCOUNTING(nsIURI, URI)
// DOM Traversal.
uint32_t Gecko_ChildrenCount(RawGeckoNodeBorrowed node);
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -0,0 +1,77 @@
+/* -*- 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/. */
+
+/* representation of CSSRuleList for stylo */
+
+#include "mozilla/ServoCSSRuleList.h"
+
+#include "mozilla/ServoBindings.h"
+
+namespace mozilla {
+
+ServoCSSRuleList::ServoCSSRuleList(ServoStyleSheet* aStyleSheet,
+ already_AddRefed<ServoCssRules> aRawRules)
+ : mStyleSheet(aStyleSheet)
+ , mRawRules(aRawRules)
+{
+ Servo_CssRules_ListTypes(mRawRules, &mRules);
+ // XXX We may want to eagerly create object for import rule, so that
+ // we don't lose the reference to child stylesheet when our own
+ // stylesheet goes away.
+}
+
+nsIDOMCSSRule*
+ServoCSSRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
+{
+ if (aIndex >= mRules.Length()) {
+ aFound = false;
+ return nullptr;
+ }
+ aFound = true;
+ uintptr_t rule = mRules[aIndex];
+ if (rule <= kMaxRuleType) {
+ RefPtr<css::Rule> ruleObj = nullptr;
+ switch (rule) {
+ case nsIDOMCSSRule::STYLE_RULE:
+ case nsIDOMCSSRule::MEDIA_RULE:
+ case nsIDOMCSSRule::FONT_FACE_RULE:
+ case nsIDOMCSSRule::KEYFRAMES_RULE:
+ case nsIDOMCSSRule::NAMESPACE_RULE:
+ // XXX create corresponding rules
+ default:
+ MOZ_CRASH("stylo: not implemented yet");
+ }
+ ruleObj->SetStyleSheet(mStyleSheet);
+ rule = CastToUint(ruleObj.forget().take());
+ mRules[aIndex] = rule;
+ }
+ return CastToPtr(rule)->GetDOMRule();
+}
+
+template<typename Func>
+void
+ServoCSSRuleList::EnumerateRules(Func aCallback)
+{
+ for (uintptr_t rule : mRules) {
+ if (rule > kMaxRuleType) {
+ aCallback(CastToPtr(rule));
+ }
+ }
+}
+
+void
+ServoCSSRuleList::DropReference()
+{
+ mStyleSheet = nullptr;
+ EnumerateRules([](css::Rule* rule) { rule->SetStyleSheet(nullptr); });
+}
+
+ServoCSSRuleList::~ServoCSSRuleList()
+{
+ EnumerateRules([](css::Rule* rule) { rule->Release(); });
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoCSSRuleList.h
@@ -0,0 +1,65 @@
+/* -*- 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/. */
+
+/* representation of CSSRuleList for stylo */
+
+#ifndef mozilla_ServoCSSRuleList_h
+#define mozilla_ServoCSSRuleList_h
+
+#include "mozilla/ServoBindingTypes.h"
+#include "mozilla/dom/CSSRuleList.h"
+
+namespace mozilla {
+
+class ServoStyleSheet;
+namespace css {
+class Rule;
+} // namespace css
+
+class ServoCSSRuleList final : public CSSRuleList
+{
+public:
+ ServoCSSRuleList(ServoStyleSheet* aStyleSheet,
+ already_AddRefed<ServoCssRules> aRawRules);
+
+ ServoStyleSheet* GetParentObject() final { return mStyleSheet; }
+
+ nsIDOMCSSRule* IndexedGetter(uint32_t aIndex, bool& aFound) final;
+ uint32_t Length() final { return mRules.Length(); }
+
+ void DropReference();
+
+private:
+ virtual ~ServoCSSRuleList();
+
+ // XXX Is it possible to have an address lower than or equal to 255?
+ // Is it possible to have more than 255 CSS rule types?
+ static const uintptr_t kMaxRuleType = UINT8_MAX;
+
+ static uintptr_t CastToUint(css::Rule* aPtr) {
+ return reinterpret_cast<uintptr_t>(aPtr);
+ }
+ static css::Rule* CastToPtr(uintptr_t aInt) {
+ MOZ_ASSERT(aInt > kMaxRuleType);
+ return reinterpret_cast<css::Rule*>(aInt);
+ }
+
+ template<typename Func>
+ void EnumerateRules(Func aCallback);
+
+ // mStyleSheet may be nullptr when it drops the reference to us.
+ ServoStyleSheet* mStyleSheet;
+ RefPtr<ServoCssRules> mRawRules;
+ // Array stores either a number indicating rule type, or a pointer to
+ // css::Rule. If the value is less than kMaxRuleType, the given rule
+ // instance has not been constructed, and the value means the type
+ // of the rule. Otherwise, it is a pointer.
+ nsTArray<uintptr_t> mRules;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ServoCSSRuleList_h
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -1,31 +1,37 @@
/* -*- 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/. */
#include "mozilla/ServoStyleSheet.h"
#include "mozilla/StyleBackendType.h"
+#include "mozilla/ServoBindings.h"
+#include "mozilla/ServoCSSRuleList.h"
+#include "mozilla/dom/CSSRuleList.h"
namespace mozilla {
ServoStyleSheet::ServoStyleSheet(css::SheetParsingMode aParsingMode,
CORSMode aCORSMode,
net::ReferrerPolicy aReferrerPolicy,
const dom::SRIMetadata& aIntegrity)
: StyleSheet(StyleBackendType::Servo, aParsingMode)
, mSheetInfo(aCORSMode, aReferrerPolicy, aIntegrity)
{
}
ServoStyleSheet::~ServoStyleSheet()
{
DropSheet();
+ if (mRuleList) {
+ mRuleList->DropReference();
+ }
}
bool
ServoStyleSheet::HasRules() const
{
return mSheet && Servo_StyleSheet_HasRules(mSheet);
}
@@ -117,18 +123,21 @@ nsIDOMCSSRule*
ServoStyleSheet::GetDOMOwnerRule() const
{
return nullptr;
}
CSSRuleList*
ServoStyleSheet::GetCssRulesInternal(ErrorResult& aRv)
{
- aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
- return nullptr;
+ if (!mRuleList) {
+ RefPtr<ServoCssRules> rawRules = Servo_StyleSheet_GetRules(mSheet).Consume();
+ mRuleList = new ServoCSSRuleList(this, rawRules.forget());
+ }
+ return mRuleList;
}
uint32_t
ServoStyleSheet::InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex, ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return 0;
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -11,16 +11,18 @@
#include "mozilla/RefPtr.h"
#include "mozilla/ServoBindingTypes.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInfo.h"
#include "nsStringFwd.h"
namespace mozilla {
+class ServoCSSRuleList;
+
/**
* CSS style sheet object that is a wrapper for a Servo Stylesheet.
*/
class ServoStyleSheet : public StyleSheet
{
public:
ServoStyleSheet(css::SheetParsingMode aParsingMode,
CORSMode aCORSMode,
@@ -75,16 +77,17 @@ protected:
uint32_t InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex, ErrorResult& aRv);
void DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv);
private:
void DropSheet();
RefPtr<RawServoStyleSheet> mSheet;
+ RefPtr<ServoCSSRuleList> mRuleList;
StyleSheetInfo mSheetInfo;
friend class StyleSheet;
};
} // namespace mozilla
#endif // mozilla_ServoStyleSheet_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -91,16 +91,17 @@ EXPORTS.mozilla += [
'HandleRefPtr.h',
'IncrementalClearCOMRuleArray.h',
'LayerAnimationInfo.h',
'RuleNodeCacheConditions.h',
'RuleProcessorCache.h',
'ServoBindingList.h',
'ServoBindings.h',
'ServoBindingTypes.h',
+ 'ServoCSSRuleList.h',
'ServoDeclarationBlock.h',
'ServoElementSnapshot.h',
'ServoStyleSet.h',
'ServoStyleSheet.h',
'ServoTypes.h',
'ServoUtils.h',
'SheetType.h',
'StyleAnimationValue.h',
@@ -191,16 +192,17 @@ UNIFIED_SOURCES += [
'nsStyleSet.cpp',
'nsStyleStruct.cpp',
'nsStyleTransformMatrix.cpp',
'nsStyleUtil.cpp',
'nsTransitionManager.cpp',
'RuleNodeCacheConditions.cpp',
'RuleProcessorCache.cpp',
'ServoBindings.cpp',
+ 'ServoCSSRuleList.cpp',
'ServoDeclarationBlock.cpp',
'ServoElementSnapshot.cpp',
'ServoStyleSet.cpp',
'ServoStyleSheet.cpp',
'StyleAnimationValue.cpp',
'StyleRule.cpp',
'StyleSheet.cpp',
'SVGAttrAnimationRuleProcessor.cpp',
--- a/servo/components/style/binding_tools/regen.py
+++ b/servo/components/style/binding_tools/regen.py
@@ -321,18 +321,23 @@ COMPILATION_TARGETS = {
"nsStyleUIReset",
"nsStyleUnion",
"nsStyleUnit",
"nsStyleUserInterface",
"nsStyleVariables",
"nsStyleVisibility",
"nsStyleXUL",
],
+ "array_types": {
+ "uintptr_t": "usize",
+ },
"servo_nullable_arc_types": [
- "ServoComputedValues", "RawServoStyleSheet",
+ "ServoComputedValues",
+ "ServoCssRules",
+ "RawServoStyleSheet",
"RawServoDeclarationBlock"
],
"servo_owned_types": [
"RawServoStyleSet",
"StyleChildrenIterator",
],
"servo_immutable_borrow_types": [
"RawGeckoNode",
@@ -523,16 +528,24 @@ def build(objdir, target_name, debug, de
flags.append("--whitelist-var")
flags.append(header)
if "opaque_types" in current_target:
for ty in current_target["opaque_types"]:
flags.append("--opaque-type")
flags.append(ty)
+ if "array_types" in current_target:
+ for cpp_type, rust_type in current_target["array_types"].items():
+ flags.append("--blacklist-type")
+ flags.append("nsTArrayBorrowed_{}".format(cpp_type))
+ flags.append("--raw-line")
+ flags.append("pub type nsTArrayBorrowed_{0}<'a> = &'a mut ::gecko_bindings::structs::nsTArray<{1}>;"
+ .format(cpp_type, rust_type))
+
if "blacklist_types" in current_target:
for ty in current_target["blacklist_types"]:
flags.append("--blacklist-type")
flags.append(ty)
if "servo_nullable_arc_types" in current_target:
for ty in current_target["servo_nullable_arc_types"]:
flags.append("--blacklist-type")
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -6,39 +6,44 @@
//! Ideally, it would be in geckolib itself, but coherence
//! forces us to keep the traits and implementations here
#![allow(unsafe_code)]
use app_units::Au;
use gecko::values::{convert_rgba_to_nscolor, StyleCoordHelpers};
use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue};
-use gecko_bindings::bindings::{RawServoStyleSheet, RawServoDeclarationBlock, ServoComputedValues};
+use gecko_bindings::bindings::{RawServoStyleSheet, RawServoDeclarationBlock, ServoComputedValues, ServoCssRules};
use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage};
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut};
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
use parking_lot::RwLock;
use properties::{ComputedValues, PropertyDeclarationBlock};
-use stylesheets::Stylesheet;
+use stylesheets::{CssRule, Stylesheet};
use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto};
unsafe impl HasFFI for Stylesheet {
type FFIType = RawServoStyleSheet;
}
unsafe impl HasArcFFI for Stylesheet {}
unsafe impl HasFFI for ComputedValues {
type FFIType = ServoComputedValues;
}
unsafe impl HasArcFFI for ComputedValues {}
unsafe impl HasFFI for RwLock<PropertyDeclarationBlock> {
type FFIType = RawServoDeclarationBlock;
}
unsafe impl HasArcFFI for RwLock<PropertyDeclarationBlock> {}
+unsafe impl HasFFI for RwLock<Vec<CssRule>> {
+ type FFIType = ServoCssRules;
+}
+unsafe impl HasArcFFI for RwLock<Vec<CssRule>> {}
+
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
let has_percentage = other.percentage.is_some();
nsStyleCoord_CalcValue {
mLength: other.length.0,
mPercent: other.percentage.unwrap_or(0.0),
mHasPercent: has_percentage,
}
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -1,18 +1,24 @@
/* automatically generated by rust-bindgen */
pub use nsstring::{nsACString, nsAString};
type nsACString_internal = nsACString;
type nsAString_internal = nsAString;
+pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>;
pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
enum ServoComputedValuesVoid{ }
pub struct ServoComputedValues(ServoComputedValuesVoid);
+pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>;
+pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>;
+pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
+enum ServoCssRulesVoid{ }
+pub struct ServoCssRules(ServoCssRulesVoid);
pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>;
pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>;
pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet;
enum RawServoStyleSheetVoid{ }
pub struct RawServoStyleSheet(RawServoStyleSheetVoid);
pub type RawServoDeclarationBlockStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoDeclarationBlock>;
pub type RawServoDeclarationBlockBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlock>;
pub type RawServoDeclarationBlockBorrowed<'a> = &'a RawServoDeclarationBlock;
@@ -183,16 +189,22 @@ unsafe impl Sync for nsStyleVisibility {
use gecko_bindings::structs::nsStyleXUL;
unsafe impl Send for nsStyleXUL {}
unsafe impl Sync for nsStyleXUL {}
pub type RawGeckoNode = nsINode;
pub type RawGeckoElement = Element;
pub type RawGeckoDocument = nsIDocument;
extern "C" {
+ pub fn Servo_CssRules_AddRef(ptr: ServoCssRulesBorrowed);
+}
+extern "C" {
+ pub fn Servo_CssRules_Release(ptr: ServoCssRulesBorrowed);
+}
+extern "C" {
pub fn Servo_StyleSheet_AddRef(ptr: RawServoStyleSheetBorrowed);
}
extern "C" {
pub fn Servo_StyleSheet_Release(ptr: RawServoStyleSheetBorrowed);
}
extern "C" {
pub fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed);
}
@@ -930,16 +942,20 @@ extern "C" {
*mut ThreadSafePrincipalHolder)
-> RawServoStyleSheetStrong;
}
extern "C" {
pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
-> bool;
}
extern "C" {
+ pub fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed)
+ -> ServoCssRulesStrong;
+}
+extern "C" {
pub fn Servo_StyleSet_Init() -> RawServoStyleSetOwned;
}
extern "C" {
pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed,
sheet: RawServoStyleSheetBorrowed);
}
extern "C" {
pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowed,
@@ -954,16 +970,20 @@ extern "C" {
pub fn Servo_StyleSet_InsertStyleSheetBefore(set:
RawServoStyleSetBorrowed,
sheet:
RawServoStyleSheetBorrowed,
reference:
RawServoStyleSheetBorrowed);
}
extern "C" {
+ pub fn Servo_CssRules_ListRuleTypes(rules: ServoCssRulesBorrowed,
+ result: nsTArrayBorrowed_uintptr_t);
+}
+extern "C" {
pub fn Servo_ParseProperty(property: *const nsACString_internal,
value: *const nsACString_internal,
base_url: *const nsACString_internal,
base: *mut ThreadSafeURIHolder,
referrer: *mut ThreadSafeURIHolder,
principal: *mut ThreadSafePrincipalHolder)
-> RawServoDeclarationBlockStrong;
}
--- a/servo/components/style/stylesheets.rs
+++ b/servo/components/style/stylesheets.rs
@@ -78,17 +78,52 @@ pub enum CssRule {
Namespace(Arc<RwLock<NamespaceRule>>),
Style(Arc<RwLock<StyleRule>>),
Media(Arc<RwLock<MediaRule>>),
FontFace(Arc<RwLock<FontFaceRule>>),
Viewport(Arc<RwLock<ViewportRule>>),
Keyframes(Arc<RwLock<KeyframesRule>>),
}
+pub enum CssRuleType {
+ // https://drafts.csswg.org/cssom/#the-cssrule-interface
+ Style = 1,
+ Charset = 2,
+ Import = 3,
+ Media = 4,
+ FontFace = 5,
+ Page = 6,
+ // https://drafts.csswg.org/css-animations-1/#interface-cssrule-idl
+ Keyframes = 7,
+ Keyframe = 8,
+ // https://drafts.csswg.org/cssom/#the-cssrule-interface
+ Margin = 9,
+ Namespace = 10,
+ // https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface
+ CounterStyle = 11,
+ // https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface
+ Supports = 12,
+ // https://drafts.csswg.org/css-fonts-3/#om-fontfeaturevalues
+ FontFeatureValues = 14,
+ // https://drafts.csswg.org/css-device-adapt/#css-rule-interface
+ Viewport = 15,
+}
+
impl CssRule {
+ pub fn rule_type(&self) -> CssRuleType {
+ match *self {
+ CssRule::Style(_) => CssRuleType::Style,
+ CssRule::Media(_) => CssRuleType::Media,
+ CssRule::FontFace(_) => CssRuleType::FontFace,
+ CssRule::Keyframes(_) => CssRuleType::Keyframes,
+ CssRule::Namespace(_) => CssRuleType::Namespace,
+ CssRule::Viewport(_) => CssRuleType::Viewport,
+ }
+ }
+
/// Call `f` with the slice of rules directly contained inside this rule.
///
/// Note that only some types of rules can contain rules. An empty slice is used for others.
pub fn with_nested_rules_and_mq<F, R>(&self, mut f: F) -> R
where F: FnMut(&[CssRule], Option<&MediaList>) -> R {
match *self {
CssRule::Namespace(_) |
CssRule::Style(_) |
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -20,36 +20,38 @@ use style::gecko::snapshot::GeckoElement
use style::gecko::traversal::RecalcStyleOnly;
use style::gecko::wrapper::{GeckoElement, GeckoNode};
use style::gecko::wrapper::DUMMY_BASE_URL;
use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed};
use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
+use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
use style::gecko_bindings::bindings::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
use style::gecko_bindings::bindings::{nsACString, nsAString};
use style::gecko_bindings::bindings::Gecko_Utf8SliceToString;
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
+use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom};
use style::gecko_bindings::structs::ServoElementSnapshot;
use style::gecko_bindings::structs::nsRestyleHint;
use style::gecko_bindings::structs::nsString;
use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI};
use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
use style::parallel;
use style::parser::{ParserContext, ParserContextExtraData};
use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration};
use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock};
use style::properties::{apply_declarations, parse_one_declaration};
use style::selector_impl::PseudoElementCascadeType;
use style::sequential;
use style::string_cache::Atom;
-use style::stylesheets::{Origin, Stylesheet};
+use style::stylesheets::{CssRule, Origin, Stylesheet};
use style::timer::Timer;
use style_traits::ToCss;
use url::Url;
/*
* For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
* the C header in Gecko. In order to catch accidental mismatches, we run rust-bindgen against
* those signatures as well, giving us a second declaration of all the Servo_* functions in this
@@ -254,26 +256,52 @@ pub extern "C" fn Servo_StyleSet_RemoveS
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
!Stylesheet::as_arc(&raw_sheet).rules.0.read().is_empty()
}
#[no_mangle]
+pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong {
+ Stylesheet::as_arc(&sheet).rules.0.clone().into_strong()
+}
+
+#[no_mangle]
pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed) -> () {
unsafe { Stylesheet::addref(sheet) };
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> () {
unsafe { Stylesheet::release(sheet) };
}
#[no_mangle]
+pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
+ result: nsTArrayBorrowed_uintptr_t) -> () {
+ let rules = RwLock::<Vec<CssRule>>::as_arc(&rules).read();
+ let iter = rules.iter().map(|rule| rule.rule_type() as usize);
+ let (size, upper) = iter.size_hint();
+ debug_assert_eq!(size, upper.unwrap());
+ unsafe { result.set_len(size as u32) };
+ result.iter_mut().zip(iter).fold((), |_, (r, v)| *r = v);
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_CssRules_AddRef(rules: ServoCssRulesBorrowed) -> () {
+ unsafe { RwLock::<Vec<CssRule>>::addref(rules) };
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_CssRules_Release(rules: ServoCssRulesBorrowed) -> () {
+ unsafe { RwLock::<Vec<CssRule>>::release(rules) };
+}
+
+#[no_mangle]
pub extern "C" fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed)
-> ServoComputedValuesStrong {
let node = GeckoNode(node);
// Gecko erroneously calls this function from ServoRestyleManager::RecreateStyleContexts.
// We plan to fix that, but just support it for now until that code gets rewritten.
if node.is_text_node() {
error!("Don't call Servo_ComputedValue_Get() for text nodes");