Bug 1244074 - Part 3: Add skeleton ServoStyleSheet and a StyleSheetHandle smart pointer. r=dholbert

This commit is contained in:
Cameron McCormack 2016-02-24 18:01:11 +11:00
parent 66f8d2acd3
commit 4f8d4767e0
7 changed files with 626 additions and 1 deletions

View File

@ -0,0 +1,152 @@
/* -*- 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"
using namespace mozilla::dom;
namespace mozilla {
nsIURI*
ServoStyleSheet::GetSheetURI() const
{
MOZ_CRASH("stylo: not implemented");
}
nsIURI*
ServoStyleSheet::GetOriginalURI() const
{
MOZ_CRASH("stylo: not implemented");
}
nsIURI*
ServoStyleSheet::GetBaseURI() const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI)
{
MOZ_CRASH("stylo: not implemented");
}
bool
ServoStyleSheet::IsApplicable() const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::SetComplete()
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::SetParsingMode(css::SheetParsingMode aMode)
{
MOZ_CRASH("stylo: not implemented");
}
bool
ServoStyleSheet::HasRules() const
{
MOZ_CRASH("stylo: not implemented");
}
nsIDocument*
ServoStyleSheet::GetOwningDocument() const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::SetOwningDocument(nsIDocument* aDocument)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::SetOwningNode(nsINode* aOwningNode)
{
MOZ_CRASH("stylo: not implemented");
}
nsINode*
ServoStyleSheet::GetOwnerNode() const
{
MOZ_CRASH("stylo: not implemented");
}
StyleSheetHandle
ServoStyleSheet::GetParentSheet() const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::AppendStyleSheet(StyleSheetHandle aSheet)
{
MOZ_CRASH("stylo: not implemented");
}
nsIPrincipal*
ServoStyleSheet::Principal() const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::SetPrincipal(nsIPrincipal* aPrincipal)
{
MOZ_CRASH("stylo: not implemented");
}
CORSMode
ServoStyleSheet::GetCORSMode() const
{
MOZ_CRASH("stylo: not implemented");
}
net::ReferrerPolicy
ServoStyleSheet::GetReferrerPolicy() const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::GetIntegrity(dom::SRIMetadata& aResult) const
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::ParseSheet(const nsAString& aInput,
nsIURI* aSheetURI,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber,
css::SheetParsingMode aParsingMode)
{
MOZ_CRASH("stylo: not implemented");
}
size_t
ServoStyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
MOZ_CRASH("stylo: not implemented");
}
#ifdef DEBUG
void
ServoStyleSheet::List(FILE* aOut, int32_t aIndex) const
{
MOZ_CRASH("stylo: not implemented");
}
#endif
} // namespace mozilla

View File

@ -0,0 +1,68 @@
/* -*- 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 mozilla_ServoStyleSheet_h
#define mozilla_ServoStyleSheet_h
#include "mozilla/StyleSheetHandle.h"
#include "nsStringFwd.h"
namespace mozilla {
/**
* CSS style sheet object that is a wrapper for a Servo Stylesheet.
*/
class ServoStyleSheet
{
public:
NS_INLINE_DECL_REFCOUNTING(ServoStyleSheet)
nsIURI* GetSheetURI() const;
nsIURI* GetOriginalURI() const;
nsIURI* GetBaseURI() const;
void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI);
bool IsApplicable() const;
void SetComplete();
void SetParsingMode(css::SheetParsingMode aMode);
bool HasRules() const;
nsIDocument* GetOwningDocument() const;
void SetOwningDocument(nsIDocument* aDocument);
void SetOwningNode(nsINode* aOwningNode);
nsINode* GetOwnerNode() const;
StyleSheetHandle GetParentSheet() const;
void AppendStyleSheet(StyleSheetHandle aSheet);
nsIPrincipal* Principal() const;
void SetPrincipal(nsIPrincipal* aPrincipal);
CORSMode GetCORSMode() const;
net::ReferrerPolicy GetReferrerPolicy() const;
void GetIntegrity(dom::SRIMetadata& aResult) const;
void ParseSheet(const nsAString& aInput,
nsIURI* aSheetURI,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber,
css::SheetParsingMode aParsingMode);
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
#ifdef DEBUG
void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
#endif
protected:
~ServoStyleSheet() {}
};
} // namespace mozilla
#endif // mozilla_ServoStyleSheet_h

View File

@ -75,7 +75,7 @@ public:
ServoStyleSet* AsServo()
{
MOZ_ASSERT(IsServo());
return reinterpret_cast<ServoStyleSet*>(mValue);
return reinterpret_cast<ServoStyleSet*>(mValue & ~SERVO_BIT);
}
nsStyleSet* GetAsGecko() { return IsGecko() ? AsGecko() : nullptr; }

View File

@ -0,0 +1,196 @@
/* -*- 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 mozilla_StyleSheetHandle_h
#define mozilla_StyleSheetHandle_h
#include "mozilla/css/SheetParsingMode.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "mozilla/CORSMode.h"
#include "mozilla/HandleRefPtr.h"
#include "mozilla/RefCountType.h"
namespace mozilla {
namespace dom {
class SRIMetadata;
} // namespace dom
class CSSStyleSheet;
class ServoStyleSheet;
} // namespace mozilla
class nsIDocument;
class nsIPrincipal;
class nsIURI;
namespace mozilla {
#define SERVO_BIT 0x1
/**
* Smart pointer class that can hold a pointer to either a CSSStyleSheet
* or a ServoStyleSheet.
*/
class StyleSheetHandle
{
public:
typedef HandleRefPtr<StyleSheetHandle> RefPtr;
// We define this Ptr class with a StyleSheet API that forwards on to the
// wrapped pointer, rather than putting these methods on StyleSheetHandle
// itself, so that we can have StyleSheetHandle behave like a smart pointer
// and be dereferenced with operator->.
class Ptr
{
public:
friend class ::mozilla::StyleSheetHandle;
bool IsGecko() const { return !IsServo(); }
bool IsServo() const
{
MOZ_ASSERT(mValue);
#ifdef MOZ_STYLO
return mValue & SERVO_BIT;
#else
return false;
#endif
}
CSSStyleSheet* AsGecko()
{
MOZ_ASSERT(IsGecko());
return reinterpret_cast<CSSStyleSheet*>(mValue);
}
ServoStyleSheet* AsServo()
{
MOZ_ASSERT(IsServo());
return reinterpret_cast<ServoStyleSheet*>(mValue & ~SERVO_BIT);
}
CSSStyleSheet* GetAsGecko() { return IsGecko() ? AsGecko() : nullptr; }
ServoStyleSheet* GetAsServo() { return IsServo() ? AsServo() : nullptr; }
const CSSStyleSheet* AsGecko() const
{
return const_cast<Ptr*>(this)->AsGecko();
}
const ServoStyleSheet* AsServo() const
{
MOZ_ASSERT(IsServo());
return const_cast<Ptr*>(this)->AsServo();
}
void* AsVoidPtr() const
{
return reinterpret_cast<void*>(mValue & ~SERVO_BIT);
}
const CSSStyleSheet* GetAsGecko() const { return IsGecko() ? AsGecko() : nullptr; }
const ServoStyleSheet* GetAsServo() const { return IsServo() ? AsServo() : nullptr; }
// These inline methods are defined in StyleSheetHandleInlines.h.
inline MozExternalRefCountType AddRef();
inline MozExternalRefCountType Release();
// Style sheet interface. These inline methods are defined in
// StyleSheetHandleInlines.h and just forward to the underlying
// CSSStyleSheet or ServoStyleSheet. See corresponding comments in
// CSSStyleSheet.h for descriptions of these methods.
inline nsIURI* GetSheetURI() const;
inline nsIURI* GetOriginalURI() const;
inline nsIURI* GetBaseURI() const;
inline void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI);
inline bool IsApplicable() const;
inline void SetComplete();
inline void SetParsingMode(css::SheetParsingMode aMode);
inline bool HasRules() const;
inline nsIDocument* GetOwningDocument() const;
inline void SetOwningDocument(nsIDocument* aDocument);
inline nsINode* GetOwnerNode() const;
inline void SetOwningNode(nsINode* aNode);
inline StyleSheetHandle GetParentSheet() const;
inline void AppendStyleSheet(StyleSheetHandle aSheet);
inline nsIPrincipal* Principal() const;
inline void SetPrincipal(nsIPrincipal* aPrincipal);
inline CORSMode GetCORSMode() const;
inline net::ReferrerPolicy GetReferrerPolicy() const;
inline void GetIntegrity(dom::SRIMetadata& aResult) const;
inline size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
#ifdef DEBUG
inline void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
#endif
private:
// Stores a pointer to an CSSStyleSheet or a ServoStyleSheet. The least
// significant bit is 0 for the former, 1 for the latter.
uintptr_t mValue;
};
MOZ_IMPLICIT StyleSheetHandle(decltype(nullptr) = nullptr)
{
mPtr.mValue = 0;
}
StyleSheetHandle(const StyleSheetHandle& aOth) {
mPtr.mValue = aOth.mPtr.mValue;
}
MOZ_IMPLICIT StyleSheetHandle(CSSStyleSheet* aSet) { *this = aSet; }
MOZ_IMPLICIT StyleSheetHandle(ServoStyleSheet* aSet) { *this = aSet; }
MOZ_IMPLICIT StyleSheetHandle(const ::RefPtr<CSSStyleSheet>& aSet)
{
*this = aSet.get();
}
MOZ_IMPLICIT StyleSheetHandle(const ::RefPtr<ServoStyleSheet>& aSet)
{
*this = aSet.get();
}
StyleSheetHandle& operator=(decltype(nullptr)) { mPtr.mValue = 0; return *this; }
StyleSheetHandle& operator=(CSSStyleSheet* aSheet)
{
MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aSheet) & SERVO_BIT),
"least significant bit shouldn't be set; we use it for state");
mPtr.mValue = reinterpret_cast<uintptr_t>(aSheet);
return *this;
}
StyleSheetHandle& operator=(ServoStyleSheet* aSheet)
{
#ifdef MOZ_STYLO
MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aSheet) & SERVO_BIT),
"least significant bit shouldn't be set; we use it for state");
mPtr.mValue =
aSheet ? (reinterpret_cast<uintptr_t>(aSheet) | SERVO_BIT) : 0;
return *this;
#else
MOZ_CRASH("should not have a ServoStyleSheet object when MOZ_STYLO is "
"disabled");
#endif
}
// Make StyleSheetHandle usable in boolean contexts.
explicit operator bool() const { return !!mPtr.mValue; }
bool operator!() const { return !mPtr.mValue; }
// Make StyleSheetHandle behave like a smart pointer.
Ptr* operator->() { return &mPtr; }
const Ptr* operator->() const { return &mPtr; }
bool operator==(const StyleSheetHandle& aOther) const
{
return mPtr.mValue == aOther.mPtr.mValue;
}
private:
Ptr mPtr;
};
#undef SERVO_BIT
} // namespace mozilla
#endif // mozilla_StyleSheetHandle_h

View File

@ -0,0 +1,204 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_StyleSheetHandleInlines_h
#define mozilla_StyleSheetHandleInlines_h
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/ServoStyleSheet.h"
#define FORWARD_CONCRETE(method_, geckoargs_, servoargs_) \
if (IsGecko()) { \
return AsGecko()->method_ geckoargs_; \
} else { \
return AsServo()->method_ servoargs_; \
}
#define FORWARD(method_, args_) FORWARD_CONCRETE(method_, args_, args_)
namespace mozilla {
MozExternalRefCountType
StyleSheetHandle::Ptr::AddRef()
{
FORWARD(AddRef, ());
}
MozExternalRefCountType
StyleSheetHandle::Ptr::Release()
{
FORWARD(Release, ());
}
nsIURI*
StyleSheetHandle::Ptr::GetSheetURI() const
{
FORWARD(GetSheetURI, ());
}
nsIURI*
StyleSheetHandle::Ptr::GetOriginalURI() const
{
FORWARD(GetOriginalURI, ());
}
nsIURI*
StyleSheetHandle::Ptr::GetBaseURI() const
{
FORWARD(GetBaseURI, ());
}
void
StyleSheetHandle::Ptr::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI)
{
FORWARD(SetURIs, (aSheetURI, aOriginalSheetURI, aBaseURI));
}
bool
StyleSheetHandle::Ptr::IsApplicable() const
{
FORWARD(IsApplicable, ());
}
void
StyleSheetHandle::Ptr::SetComplete()
{
FORWARD(SetComplete, ());
}
void
StyleSheetHandle::Ptr::SetParsingMode(css::SheetParsingMode aMode)
{
FORWARD(SetParsingMode, (aMode));
}
bool
StyleSheetHandle::Ptr::HasRules() const
{
FORWARD(HasRules, ());
}
nsIDocument*
StyleSheetHandle::Ptr::GetOwningDocument() const
{
FORWARD(GetOwningDocument, ());
}
void
StyleSheetHandle::Ptr::SetOwningDocument(nsIDocument* aDocument)
{
FORWARD(SetOwningDocument, (aDocument));
}
nsINode*
StyleSheetHandle::Ptr::GetOwnerNode() const
{
FORWARD(GetOwnerNode, ());
}
void
StyleSheetHandle::Ptr::SetOwningNode(nsINode* aNode)
{
FORWARD(SetOwningNode, (aNode));
}
StyleSheetHandle
StyleSheetHandle::Ptr::GetParentSheet() const
{
FORWARD(GetParentSheet, ());
}
void
StyleSheetHandle::Ptr::AppendStyleSheet(StyleSheetHandle aSheet)
{
FORWARD_CONCRETE(AppendStyleSheet, (aSheet->AsGecko()), (aSheet->AsServo()));
}
nsIPrincipal*
StyleSheetHandle::Ptr::Principal() const
{
FORWARD(Principal, ());
}
void
StyleSheetHandle::Ptr::SetPrincipal(nsIPrincipal* aPrincipal)
{
FORWARD(SetPrincipal, (aPrincipal));
}
mozilla::CORSMode
StyleSheetHandle::Ptr::GetCORSMode() const
{
FORWARD(GetCORSMode, ());
}
mozilla::net::ReferrerPolicy
StyleSheetHandle::Ptr::GetReferrerPolicy() const
{
FORWARD(GetReferrerPolicy, ());
}
void
StyleSheetHandle::Ptr::GetIntegrity(dom::SRIMetadata& aResult) const
{
FORWARD(GetIntegrity, (aResult));
}
size_t
StyleSheetHandle::Ptr::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
FORWARD(SizeOfIncludingThis, (aMallocSizeOf));
}
#ifdef DEBUG
void
StyleSheetHandle::Ptr::List(FILE* aOut, int32_t aIndex) const
{
FORWARD(List, (aOut, aIndex));
}
#endif
} // namespace mozilla
#undef FORWARD
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
mozilla::StyleSheetHandle& aField,
const char* aName,
uint32_t aFlags = 0)
{
if (aField && aField->IsGecko()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, aName);
aCallback.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, aField->AsGecko()));
}
}
inline void
ImplCycleCollectionUnlink(mozilla::StyleSheetHandle& aField)
{
aField = nullptr;
}
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
mozilla::StyleSheetHandle::RefPtr& aField,
const char* aName,
uint32_t aFlags = 0)
{
if (aField && aField->IsGecko()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, aName);
aCallback.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, aField->AsGecko()));
}
}
inline void
ImplCycleCollectionUnlink(mozilla::StyleSheetHandle::RefPtr& aField)
{
aField = nullptr;
}
#endif // mozilla_StyleSheetHandleInlines_h

View File

@ -90,11 +90,14 @@ EXPORTS.mozilla += [
'RuleNodeCacheConditions.h',
'RuleProcessorCache.h',
'ServoStyleSet.h',
'ServoStyleSheet.h',
'SheetType.h',
'StyleAnimationValue.h',
'StyleBackendType.h',
'StyleSetHandle.h',
'StyleSetHandleInlines.h',
'StyleSheetHandle.h',
'StyleSheetHandleInlines.h',
]
EXPORTS.mozilla.dom += [
@ -178,6 +181,7 @@ UNIFIED_SOURCES += [
'RuleNodeCacheConditions.cpp',
'RuleProcessorCache.cpp',
'ServoStyleSet.cpp',
'ServoStyleSheet.cpp',
'StyleAnimationValue.cpp',
'StyleRule.cpp',
'SVGAttrAnimationRuleProcessor.cpp',

View File

@ -18,6 +18,7 @@
#include "nsCSSRuleProcessor.h"
#include "nsDeviceContext.h"
#include "nsIDocument.h"
#include "nsContentUtils.h"
using namespace mozilla;