--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -48,16 +48,17 @@
#include "mozilla/css/ImportRule.h"
#include "nsThreadUtils.h"
#include "nsGkAtoms.h"
#include "nsIThreadInternal.h"
#include "nsINetworkPredictor.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/URL.h"
#include "mozilla/AsyncEventDispatcher.h"
+#include "mozilla/ServoBindings.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/ConsoleReportCollector.h"
#ifdef MOZ_XUL
#include "nsXULPrototypeCache.h"
#endif
@@ -1400,35 +1401,35 @@ Loader::InsertSheetInDoc(StyleSheet* aSh
* to put it anyway. So just append for now. (In the future if we
* want to insert the sheet at the correct position, we'll need to
* restore CSSStyleSheet::InsertStyleSheetAt, which was removed in
* bug 1220506.)
*/
nsresult
Loader::InsertChildSheet(StyleSheet* aSheet,
StyleSheet* aParentSheet,
- ImportRule* aParentRule)
+ ImportRule* aGeckoParentRule,
+ RawServoImportRule* aServoParentRule)
{
LOG(("css::Loader::InsertChildSheet"));
- NS_PRECONDITION(aSheet, "Nothing to insert");
- NS_PRECONDITION(aParentSheet, "Need a parent to insert into");
- NS_PRECONDITION(aParentSheet, "How did we get imported?");
-
- // XXXheycam The InsertChildSheet API doesn't work with ServoStyleSheets,
- // since they won't have Gecko ImportRules in them.
- if (aSheet->IsServo()) {
- return NS_ERROR_FAILURE;
+ MOZ_ASSERT(aSheet, "Nothing to insert");
+ MOZ_ASSERT(aParentSheet, "Need a parent to insert into");
+ MOZ_ASSERT_IF(aSheet->IsGecko(), aGeckoParentRule && !aServoParentRule);
+ MOZ_ASSERT_IF(aSheet->IsServo(), aServoParentRule && !aGeckoParentRule);
+ if (aSheet->IsGecko()) {
+ // child sheets should always start out enabled, even if they got
+ // cloned off of top-level sheets which were disabled
+ aSheet->AsGecko()->SetEnabled(true);
+ aGeckoParentRule->SetSheet(aSheet->AsGecko()); // This sets the ownerRule on the sheet
+ } else {
+ RefPtr<RawServoStyleSheet> sheet =
+ Servo_ImportRule_GetSheet(aServoParentRule).Consume();
+ aSheet->AsServo()->SetSheetForImport(sheet);
}
-
- // child sheets should always start out enabled, even if they got
- // cloned off of top-level sheets which were disabled
- aSheet->AsGecko()->SetEnabled(true);
-
aParentSheet->AppendStyleSheet(aSheet);
- aParentRule->SetSheet(aSheet->AsGecko()); // This sets the ownerRule on the sheet
LOG((" Inserting into parent sheet"));
return NS_OK;
}
/**
* LoadSheet handles the actual load of a sheet. If the load is
* supposed to be synchronous it just opens a channel synchronously
@@ -1768,17 +1769,18 @@ Loader::ParseSheet(const nsAString& aInp
if (aLoadData->mSheet->IsGecko()) {
nsCSSParser parser(this, aLoadData->mSheet->AsGecko());
rv = parser.ParseSheet(aInput, sheetURI, baseURI,
aLoadData->mSheet->Principal(),
aLoadData->mLineNumber);
} else {
rv =
- aLoadData->mSheet->AsServo()->ParseSheet(aInput, sheetURI, baseURI,
+ aLoadData->mSheet->AsServo()->ParseSheet(this,
+ aInput, sheetURI, baseURI,
aLoadData->mSheet->Principal(),
aLoadData->mLineNumber);
}
mParsingDatas.RemoveElementAt(mParsingDatas.Length() - 1);
if (NS_FAILED(rv)) {
LOG_ERROR((" Low-level error in parser!"));
@@ -2190,35 +2192,45 @@ HaveAncestorDataWithURI(SheetLoadData *a
return false;
}
nsresult
Loader::LoadChildSheet(StyleSheet* aParentSheet,
nsIURI* aURL,
nsMediaList* aMedia,
- ImportRule* aParentRule,
+ ImportRule* aGeckoParentRule,
+ RawServoImportRule* aServoParentRule,
LoaderReusableStyleSheets* aReusableSheets)
{
LOG(("css::Loader::LoadChildSheet"));
NS_PRECONDITION(aURL, "Must have a URI to load");
NS_PRECONDITION(aParentSheet, "Must have a parent sheet");
+ // Servo doesn't support reusable sheets.
+ MOZ_ASSERT_IF(aReusableSheets, aParentSheet->IsGecko());
+ MOZ_ASSERT_IF(aParentSheet->IsGecko(), aGeckoParentRule && !aServoParentRule);
+ MOZ_ASSERT_IF(aParentSheet->IsServo(), aServoParentRule && !aGeckoParentRule);
+
if (!mEnabled) {
LOG_WARN((" Not enabled"));
return NS_ERROR_NOT_AVAILABLE;
}
LOG_URI(" Child uri: '%s'", aURL);
nsCOMPtr<nsINode> owningNode;
// check for an owning document: if none, don't bother walking up the parent
// sheets
- if (aParentSheet->GetOwningDocument()) {
+ //
+ // FIXME(emilio): Figure out whether this walk up is necessary (try seems
+ // green without it), and fix the parenting of stylesheets in the servo case
+ // if that's the case.
+ if (aParentSheet->GetOwningDocument() && aParentSheet->IsGecko()) {
StyleSheet* topSheet = aParentSheet;
while (StyleSheet* parent = topSheet->GetParentSheet()) {
topSheet = parent;
}
owningNode = topSheet->GetOwnerNode();
}
nsISupports* context = owningNode;
@@ -2259,34 +2271,35 @@ Loader::LoadChildSheet(StyleSheet* aPare
// Now that we know it's safe to load this (passes security check and not a
// loop) do so.
RefPtr<StyleSheet> sheet;
RefPtr<CSSStyleSheet> reusableSheet;
StyleSheetState state;
if (aReusableSheets && aReusableSheets->FindReusableStyleSheet(aURL, reusableSheet)) {
sheet = reusableSheet;
- aParentRule->SetSheet(reusableSheet);
+ aGeckoParentRule->SetSheet(reusableSheet);
state = eSheetComplete;
} else {
bool isAlternate;
const nsSubstring& empty = EmptyString();
// For now, use CORS_NONE for child sheets
rv = CreateSheet(aURL, nullptr, principal,
aParentSheet->ParsingMode(),
CORS_NONE, aParentSheet->GetReferrerPolicy(),
EmptyString(), // integrity is only checked on main sheet
parentData ? parentData->mSyncLoad : false,
false, empty, state, &isAlternate, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
PrepareSheet(sheet, empty, empty, aMedia, nullptr, isAlternate);
}
- rv = InsertChildSheet(sheet, aParentSheet, aParentRule);
+ rv = InsertChildSheet(sheet, aParentSheet, aGeckoParentRule,
+ aServoParentRule);
NS_ENSURE_SUCCESS(rv, rv);
if (state == eSheetComplete) {
LOG((" Sheet already complete"));
// We're completely done. No need to notify, even, since the
// @import rule addition/modification will trigger the right style
// changes automatically.
return NS_OK;
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -280,25 +280,29 @@ public:
* complete aParentSheet will be QIed to nsICSSLoaderObserver and
* asynchronously notified, just like for LoadStyleLink. Note that if the
* child sheet is already complete when this method returns, no
* nsICSSLoaderObserver notification will be sent.
*
* @param aParentSheet the parent of this child sheet
* @param aURL the URL of the child sheet
* @param aMedia the already-parsed media list for the child sheet
- * @param aRule the @import rule importing this child. This is used to
- * properly order the child sheet list of aParentSheet.
+ * @param aGeckoParentRule the @import rule importing this child, when using
+ * Gecko's style system. This is used to properly
+ * order the child sheet list of aParentSheet.
+ * @param aServoParentRule the @import rule importing this child, when using
+ * Servo's style system.
* @param aSavedSheets any saved style sheets which could be reused
* for this load
*/
nsresult LoadChildSheet(StyleSheet* aParentSheet,
nsIURI* aURL,
nsMediaList* aMedia,
- ImportRule* aRule,
+ ImportRule* aGeckoParentRule,
+ RawServoImportRule* aServoParentRule,
LoaderReusableStyleSheets* aSavedSheets);
/**
* Synchronously load and return the stylesheet at aURL. Any child sheets
* will also be loaded synchronously. Note that synchronous loads over some
* protocols may involve spinning up a new event loop, so use of this method
* does NOT guarantee not receiving any events before the sheet loads. This
* method can be used to load sheets not associated with a document.
@@ -479,17 +483,18 @@ private:
bool isAlternate);
nsresult InsertSheetInDoc(StyleSheet* aSheet,
nsIContent* aLinkingContent,
nsIDocument* aDocument);
nsresult InsertChildSheet(StyleSheet* aSheet,
StyleSheet* aParentSheet,
- ImportRule* aParentRule);
+ ImportRule* aGeckoParentRule,
+ RawServoImportRule* aServoParentRule);
nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
bool aIsPreload,
SheetParsingMode aParsingMode,
bool aUseSystemPrincipal,
nsIPrincipal* aOriginPrincipal,
const nsCString& aCharset,
RefPtr<StyleSheet>* aSheet,
--- a/layout/style/ServoArcTypeList.h
+++ b/layout/style/ServoArcTypeList.h
@@ -6,8 +6,9 @@
/* a list of all Servo Arc types used in stylo bindings for preprocessing */
SERVO_ARC_TYPE(CssRules, ServoCssRules)
SERVO_ARC_TYPE(StyleSheet, RawServoStyleSheet)
SERVO_ARC_TYPE(ComputedValues, ServoComputedValues)
SERVO_ARC_TYPE(DeclarationBlock, RawServoDeclarationBlock)
SERVO_ARC_TYPE(StyleRule, RawServoStyleRule)
+SERVO_ARC_TYPE(ImportRule, RawServoImportRule)
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -21,22 +21,36 @@
// Element data
SERVO_BINDING_FUNC(Servo_Element_ClearData, void, RawGeckoElementBorrowed node)
SERVO_BINDING_FUNC(Servo_Element_ShouldTraverse, bool, RawGeckoElementBorrowed node)
// Styleset and Stylesheet management
SERVO_BINDING_FUNC(Servo_StyleSheet_Empty, RawServoStyleSheetStrong,
mozilla::css::SheetParsingMode parsing_mode)
SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes, RawServoStyleSheetStrong,
+ mozilla::css::Loader* loader,
+ mozilla::ServoStyleSheet* gecko_stylesheet,
const nsACString* data,
mozilla::css::SheetParsingMode parsing_mode,
const nsACString* base_url,
ThreadSafeURIHolder* base,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal)
+SERVO_BINDING_FUNC(Servo_ImportRule_GetSheet,
+ RawServoStyleSheetStrong,
+ const RawServoImportRuleBorrowed import_rule)
+SERVO_BINDING_FUNC(Servo_StyleSheet_ClearAndUpdate,
+ void,
+ RawServoStyleSheetBorrowed stylesheet,
+ mozilla::css::Loader* loader,
+ mozilla::ServoStyleSheet* gecko_stylesheet,
+ const nsACString* data,
+ ThreadSafeURIHolder* base,
+ ThreadSafeURIHolder* referrer,
+ ThreadSafePrincipalHolder* principal)
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, bool flush)
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -5,26 +5,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoBindings.h"
#include "ChildIterator.h"
#include "StyleStructContext.h"
#include "gfxFontFamilyList.h"
#include "nsAttrValueInlines.h"
+#include "nsCSSParser.h"
#include "nsCSSRuleProcessor.h"
#include "nsContentUtils.h"
#include "nsDOMTokenList.h"
#include "nsIContentInlines.h"
#include "nsIDOMNode.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "nsINode.h"
#include "nsIPrincipal.h"
#include "nsNameSpaceManager.h"
+#include "nsNetUtil.h"
#include "nsRuleNode.h"
#include "nsString.h"
#include "nsStyleStruct.h"
#include "nsStyleUtil.h"
#include "nsTArray.h"
#include "mozilla/EventStates.h"
#include "mozilla/ServoElementSnapshot.h"
@@ -1016,16 +1018,51 @@ Gecko_CSSValue_SetFunction(nsCSSValueBor
}
nsCSSValueBorrowedMut
Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut aCSSValue, int32_t aIndex)
{
return &aCSSValue->GetArrayValue()->Item(aIndex);
}
+void
+Gecko_LoadStyleSheet(css::Loader* aLoader,
+ ServoStyleSheet* aParent,
+ RawServoImportRuleStrong aImportRule,
+ const uint8_t* aURLString,
+ uint32_t aURLStringLength,
+ const uint8_t* aMediaString,
+ uint32_t aMediaStringLength)
+{
+ MOZ_ASSERT(aLoader, "Should've catched this before");
+ MOZ_ASSERT(aParent, "Only used for @import, so parent should exist!");
+ MOZ_ASSERT(aURLString, "Invalid URLs shouldn't be loaded!");
+ RefPtr<nsMediaList> media = new nsMediaList();
+ if (aMediaStringLength) {
+ MOZ_ASSERT(aMediaString);
+ // TODO(emilio, bug 1325878): This is not great, though this is going away
+ // soon anyway, when we can have a Servo-backed nsMediaList.
+ nsDependentCSubstring medium(reinterpret_cast<const char*>(aMediaString),
+ aMediaStringLength);
+ nsCSSParser mediumParser(aLoader);
+ mediumParser.ParseMediaList(
+ NS_ConvertUTF8toUTF16(medium), nullptr, 0, media);
+ }
+
+ nsDependentCSubstring urlSpec(reinterpret_cast<const char*>(aURLString),
+ aURLStringLength);
+
+ // Servo's loader guarantees that the URL is valid.
+ nsCOMPtr<nsIURI> uri;
+ MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), urlSpec));
+
+ RefPtr<RawServoImportRule> import = aImportRule.Consume();
+ aLoader->LoadChildSheet(aParent, uri, media, nullptr, import, nullptr);
+}
+
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
#define STYLE_STRUCT(name, checkdata_cb) \
\
void \
Gecko_Construct_nsStyle##name(nsStyle##name* ptr) \
{ \
new (ptr) nsStyle##name(StyleStructContext::ServoContext()); \
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -24,16 +24,17 @@
* Functions beginning with Servo_ are implemented in Servo and invoked from Gecko.
*/
class nsIAtom;
class nsIPrincipal;
class nsIURI;
struct nsFont;
namespace mozilla {
+ class ServoStyleSheet;
class FontFamilyList;
enum FontFamilyType : uint32_t;
}
using mozilla::FontFamilyList;
using mozilla::FontFamilyType;
using mozilla::ServoElementSnapshot;
struct nsStyleList;
struct nsStyleImage;
@@ -89,16 +90,23 @@ RawGeckoNodeBorrowedOrNull Gecko_GetLast
RawGeckoNodeBorrowedOrNull Gecko_GetPrevSibling(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetNextSibling(RawGeckoNodeBorrowed node);
RawGeckoElementBorrowedOrNull Gecko_GetParentElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetFirstChildElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetNextSiblingElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetDocumentElement(RawGeckoDocumentBorrowed document);
+void Gecko_LoadStyleSheet(mozilla::css::Loader* loader,
+ mozilla::ServoStyleSheet* parent,
+ RawServoImportRuleStrong import_rule,
+ const uint8_t* url_bytes,
+ uint32_t url_length,
+ const uint8_t* media_bytes,
+ uint32_t media_length);
// By default, Servo walks the DOM by traversing the siblings of the DOM-view
// first child. This generally works, but misses anonymous children, which we
// want to traverse during styling. To support these cases, we create an
// optional heap-allocated iterator for nodes that need it. If the creation
// method returns null, Servo falls back to the aforementioned simpler (and
// faster) sibling traversal.
StyleChildrenIteratorOwnedOrNull Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed node);
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -57,43 +57,46 @@ ServoStyleSheet::GetParentSheet() const
// to fix SetOwningDocument to propagate the owning document down
// to the children.
MOZ_CRASH("stylo: not implemented");
}
void
ServoStyleSheet::AppendStyleSheet(ServoStyleSheet* aSheet)
{
- // XXXheycam: When we implement support for child sheets, we'll have
- // to fix SetOwningDocument to propagate the owning document down
- // to the children.
- MOZ_CRASH("stylo: not implemented");
+ aSheet->mDocument = mDocument;
}
nsresult
-ServoStyleSheet::ParseSheet(const nsAString& aInput,
+ServoStyleSheet::ParseSheet(css::Loader* aLoader,
+ const nsAString& aInput,
nsIURI* aSheetURI,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber)
{
- DropSheet();
-
RefPtr<ThreadSafeURIHolder> base = new ThreadSafeURIHolder(aBaseURI);
RefPtr<ThreadSafeURIHolder> referrer = new ThreadSafeURIHolder(aSheetURI);
RefPtr<ThreadSafePrincipalHolder> principal =
new ThreadSafePrincipalHolder(aSheetPrincipal);
nsCString baseString;
nsresult rv = aBaseURI->GetSpec(baseString);
NS_ENSURE_SUCCESS(rv, rv);
NS_ConvertUTF16toUTF8 input(aInput);
- mSheet = Servo_StyleSheet_FromUTF8Bytes(&input, mParsingMode, &baseString,
- base, referrer, principal).Consume();
+ if (!mSheet) {
+ mSheet =
+ Servo_StyleSheet_FromUTF8Bytes(aLoader, this, &input, mParsingMode,
+ &baseString, base, referrer,
+ principal).Consume();
+ } else {
+ Servo_StyleSheet_ClearAndUpdate(mSheet, aLoader, this, &input, base,
+ referrer, principal);
+ }
return NS_OK;
}
void
ServoStyleSheet::LoadFailed()
{
mSheet = Servo_StyleSheet_Empty(mParsingMode).Consume();
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -13,16 +13,20 @@
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInfo.h"
#include "nsStringFwd.h"
namespace mozilla {
class ServoCSSRuleList;
+namespace css {
+class Loader;
+}
+
/**
* CSS style sheet object that is a wrapper for a Servo Stylesheet.
*/
class ServoStyleSheet : public StyleSheet
{
public:
ServoStyleSheet(css::SheetParsingMode aParsingMode,
CORSMode aCORSMode,
@@ -31,17 +35,18 @@ public:
bool HasRules() const;
void SetOwningDocument(nsIDocument* aDocument);
ServoStyleSheet* GetParentSheet() const;
void AppendStyleSheet(ServoStyleSheet* aSheet);
- MOZ_MUST_USE nsresult ParseSheet(const nsAString& aInput,
+ MOZ_MUST_USE nsresult ParseSheet(css::Loader* aLoader,
+ const nsAString& aInput,
nsIURI* aSheetURI,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber);
/**
* Called instead of ParseSheet to initialize the Servo stylesheet object
* for a failed load. Either ParseSheet or LoadFailed must be called before
@@ -51,16 +56,20 @@ public:
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
#ifdef DEBUG
void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
#endif
RawServoStyleSheet* RawSheet() const { return mSheet; }
+ void SetSheetForImport(RawServoStyleSheet* aSheet) {
+ MOZ_ASSERT(!mSheet);
+ mSheet = aSheet;
+ }
// WebIDL StyleSheet API
nsMediaList* Media() final;
// WebIDL CSSStyleSheet API
// Can't be inline because we can't include ImportRule here. And can't be
// called GetOwnerRule because that would be ambiguous with the ImportRule
// version.
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3810,17 +3810,19 @@ CSSParserImpl::ProcessImport(const nsStr
// import url is bad
REPORT_UNEXPECTED_P(PEImportBadURI, aURLSpec);
OUTPUT_ERROR();
}
return;
}
if (mChildLoader) {
- mChildLoader->LoadChildSheet(mSheet, url, aMedia, rule, mReusableSheets);
+ mChildLoader->LoadChildSheet(mSheet, url, aMedia, rule,
+ /* aServoParentRule = */ nullptr,
+ mReusableSheets);
}
}
// Parse the {} part of an @media or @-moz-document rule.
bool
CSSParserImpl::ParseGroupRule(css::GroupRule* aRule,
RuleAppendFunc aAppendFunc,
void* aData)
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -966,17 +966,20 @@ nsLayoutStylesheetCache::BuildPreference
NS_ASSERTION(sheetText.Length() <= kPreallocSize,
"kPreallocSize should be big enough to build preference style "
"sheet without reallocation");
if (sheet->IsGecko()) {
sheet->AsGecko()->ReparseSheet(sheetText);
} else {
- nsresult rv = sheet->AsServo()->ParseSheet(sheetText, uri, uri, nullptr, 0);
+ ServoStyleSheet* servoSheet = sheet->AsServo();
+ // NB: The pref sheet never has @import rules.
+ nsresult rv =
+ servoSheet->ParseSheet(nullptr, sheetText, uri, uri, nullptr, 0);
// Parsing the about:PreferenceStyleSheet URI can only fail on OOM. If we
// are OOM before we parsed any documents we might as well abort.
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
}
#undef NS_GET_R_G_B
}
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -217,16 +217,17 @@ mod bindings {
"NS_STYLE_.*",
"NS_CORNER_.*",
"NS_RADIUS_.*",
"BORDER_COLOR_.*",
"BORDER_STYLE_.*"
];
let whitelist = [
"RawGecko.*",
+ "mozilla::ServoStyleSheet",
"mozilla::ServoElementSnapshot.*",
"mozilla::ConsumeStyleBehavior",
"mozilla::LazyComputeBehavior",
"mozilla::css::SheetParsingMode",
"mozilla::TraversalRootBehavior",
"mozilla::DisplayItemClip", // Needed because bindgen generates
// specialization tests for this even
// though it shouldn't.
@@ -505,30 +506,33 @@ mod bindings {
"nsStyleUnion",
"nsStyleUnit",
"nsStyleUserInterface",
"nsStyleVariables",
"nsStyleVisibility",
"nsStyleXUL",
"nscoord",
"nsresult",
+ "Loader",
+ "ServoStyleSheet",
];
struct ArrayType {
cpp_type: &'static str,
rust_type: &'static str
}
let array_types = [
ArrayType { cpp_type: "uintptr_t", rust_type: "usize" },
];
let servo_nullable_arc_types = [
"ServoComputedValues",
"ServoCssRules",
"RawServoStyleSheet",
"RawServoDeclarationBlock",
"RawServoStyleRule",
+ "RawServoImportRule",
];
struct ServoOwnedType {
name: &'static str,
opaque: bool,
}
let servo_owned_types = [
ServoOwnedType { name: "RawServoStyleSet", opaque: true },
ServoOwnedType { name: "StyleChildrenIterator", opaque: true },
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -6,25 +6,25 @@
//! 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, RawServoStyleRule};
+use gecko_bindings::bindings::{RawServoStyleSheet, RawServoDeclarationBlock, RawServoStyleRule, RawServoImportRule};
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage};
use gecko_bindings::structs::nsresult;
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::{CssRules, RulesMutateError, Stylesheet, StyleRule};
+use stylesheets::{CssRules, RulesMutateError, Stylesheet, StyleRule, ImportRule};
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;
@@ -41,16 +41,21 @@ unsafe impl HasFFI for RwLock<CssRules>
}
unsafe impl HasArcFFI for RwLock<CssRules> {}
unsafe impl HasFFI for RwLock<StyleRule> {
type FFIType = RawServoStyleRule;
}
unsafe impl HasArcFFI for RwLock<StyleRule> {}
+unsafe impl HasFFI for RwLock<ImportRule> {
+ type FFIType = RawServoImportRule;
+}
+unsafe impl HasArcFFI for RwLock<ImportRule> {}
+
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
@@ -139,16 +139,18 @@ unsafe impl Sync for nsStyleVariables {}
use gecko_bindings::structs::nsStyleVisibility;
unsafe impl Send for nsStyleVisibility {}
unsafe impl Sync for nsStyleVisibility {}
use gecko_bindings::structs::nsStyleXUL;
unsafe impl Send for nsStyleXUL {}
unsafe impl Sync for nsStyleXUL {}
use gecko_bindings::structs::nscoord;
use gecko_bindings::structs::nsresult;
+use gecko_bindings::structs::Loader;
+use gecko_bindings::structs::ServoStyleSheet;
pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>;
pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
enum ServoComputedValuesVoid { }
pub struct ServoComputedValues(ServoComputedValuesVoid);
pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>;
pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
@@ -165,16 +167,21 @@ pub type RawServoDeclarationBlockBorrowe
pub type RawServoDeclarationBlockBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlock>;
enum RawServoDeclarationBlockVoid { }
pub struct RawServoDeclarationBlock(RawServoDeclarationBlockVoid);
pub type RawServoStyleRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleRule>;
pub type RawServoStyleRuleBorrowed<'a> = &'a RawServoStyleRule;
pub type RawServoStyleRuleBorrowedOrNull<'a> = Option<&'a RawServoStyleRule>;
enum RawServoStyleRuleVoid { }
pub struct RawServoStyleRule(RawServoStyleRuleVoid);
+pub type RawServoImportRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoImportRule>;
+pub type RawServoImportRuleBorrowed<'a> = &'a RawServoImportRule;
+pub type RawServoImportRuleBorrowedOrNull<'a> = Option<&'a RawServoImportRule>;
+enum RawServoImportRuleVoid { }
+pub struct RawServoImportRule(RawServoImportRuleVoid);
pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>;
pub type RawServoStyleSetOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<RawServoStyleSet>;
pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet;
pub type RawServoStyleSetBorrowedOrNull<'a> = Option<&'a RawServoStyleSet>;
pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet;
pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>;
enum RawServoStyleSetVoid { }
pub struct RawServoStyleSet(RawServoStyleSetVoid);
@@ -233,16 +240,22 @@ extern "C" {
}
extern "C" {
pub fn Servo_StyleRule_AddRef(ptr: RawServoStyleRuleBorrowed);
}
extern "C" {
pub fn Servo_StyleRule_Release(ptr: RawServoStyleRuleBorrowed);
}
extern "C" {
+ pub fn Servo_ImportRule_AddRef(ptr: RawServoImportRuleBorrowed);
+}
+extern "C" {
+ pub fn Servo_ImportRule_Release(ptr: RawServoImportRuleBorrowed);
+}
+extern "C" {
pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned);
}
extern "C" {
pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void,
aCapacity: usize, aElementSize: usize);
}
extern "C" {
pub fn Gecko_ClearPODTArray(aArray: *mut ::std::os::raw::c_void,
@@ -308,16 +321,23 @@ extern "C" {
pub fn Gecko_GetNextSiblingElement(element: RawGeckoElementBorrowed)
-> RawGeckoElementBorrowedOrNull;
}
extern "C" {
pub fn Gecko_GetDocumentElement(document: RawGeckoDocumentBorrowed)
-> RawGeckoElementBorrowedOrNull;
}
extern "C" {
+ pub fn Gecko_LoadStyleSheet(loader: *mut Loader,
+ parent: *mut ServoStyleSheet,
+ import_rule: RawServoImportRuleStrong,
+ url_bytes: *const u8, url_length: u32,
+ media_bytes: *const u8, media_length: u32);
+}
+extern "C" {
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed)
-> StyleChildrenIteratorOwnedOrNull;
}
extern "C" {
pub fn Gecko_DropStyleChildrenIterator(it: StyleChildrenIteratorOwned);
}
extern "C" {
pub fn Gecko_GetNextStyleChild(it: StyleChildrenIteratorBorrowedMut)
@@ -963,27 +983,46 @@ extern "C" {
pub fn Servo_Element_ShouldTraverse(node: RawGeckoElementBorrowed)
-> bool;
}
extern "C" {
pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode)
-> RawServoStyleSheetStrong;
}
extern "C" {
- pub fn Servo_StyleSheet_FromUTF8Bytes(data: *const nsACString_internal,
+ pub fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
+ gecko_stylesheet:
+ *mut ServoStyleSheet,
+ data: *const nsACString_internal,
parsing_mode: SheetParsingMode,
base_url:
*const nsACString_internal,
base: *mut ThreadSafeURIHolder,
referrer: *mut ThreadSafeURIHolder,
principal:
*mut ThreadSafePrincipalHolder)
-> RawServoStyleSheetStrong;
}
extern "C" {
+ pub fn Servo_ImportRule_GetSheet(import_rule: RawServoImportRuleBorrowed)
+ -> RawServoStyleSheetStrong;
+}
+extern "C" {
+ pub fn Servo_StyleSheet_ClearAndUpdate(stylesheet:
+ RawServoStyleSheetBorrowed,
+ loader: *mut Loader,
+ gecko_stylesheet:
+ *mut ServoStyleSheet,
+ data: *const nsACString_internal,
+ base: *mut ThreadSafeURIHolder,
+ referrer: *mut ThreadSafeURIHolder,
+ principal:
+ *mut ThreadSafePrincipalHolder);
+}
+extern "C" {
pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
-> bool;
}
extern "C" {
pub fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed)
-> ServoCssRulesStrong;
}
extern "C" {
--- a/servo/components/style/gecko_bindings/structs_debug.rs
+++ b/servo/components/style/gecko_bindings/structs_debug.rs
@@ -1000,16 +1000,17 @@ pub mod root {
pub const NS_STYLE_SCROLL_SNAP_TYPE_PROXIMITY: ::std::os::raw::c_uint = 2;
pub const NS_STYLE_ORIENTATION_PORTRAIT: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_ORIENTATION_LANDSCAPE: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_SCAN_PROGRESSIVE: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_SCAN_INTERLACE: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_DISPLAY_MODE_BROWSER: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_DISPLAY_MODE_MINIMAL_UI: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_DISPLAY_MODE_STANDALONE: ::std::os::raw::c_uint = 2;
+ pub const NS_STYLE_DISPLAY_MODE_FULLSCREEN: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_INHERIT_MASK: ::std::os::raw::c_uint = 16777215;
pub const NS_STYLE_HAS_TEXT_DECORATION_LINES: ::std::os::raw::c_uint =
16777216;
pub const NS_STYLE_HAS_PSEUDO_ELEMENT_DATA: ::std::os::raw::c_uint =
33554432;
pub const NS_STYLE_RELEVANT_LINK_VISITED: ::std::os::raw::c_uint =
67108864;
pub const NS_STYLE_IS_STYLE_IF_VISITED: ::std::os::raw::c_uint =
@@ -2357,16 +2358,24 @@ pub mod root {
pub static mut StyleSheet__cycleCollectorGlobal:
root::mozilla::StyleSheet_cycleCollection;
}
#[test]
fn bindgen_test_layout_StyleSheet() {
assert_eq!(::std::mem::size_of::<StyleSheet>() , 88usize);
assert_eq!(::std::mem::align_of::<StyleSheet>() , 8usize);
}
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct ServoStyleSheet {
+ pub _address: u8,
+ }
+ impl Clone for ServoStyleSheet {
+ fn clone(&self) -> Self { *self }
+ }
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Side {
eSideTop = 0,
eSideRight = 1,
eSideBottom = 2,
eSideLeft = 3,
}
@@ -2588,17 +2597,17 @@ pub mod root {
}
impl Clone for FramePropertyDescriptorUntyped {
fn clone(&self) -> Self { *self }
}
/**
* The FramePropertyTable is optimized for storing 0 or 1 properties on
* a given frame. Storing very large numbers of properties on a single
* frame will not be efficient.
- *
+ *
* Property values are passed as void* but do not actually have to be
* valid pointers. You can use NS_INT32_TO_PTR/NS_PTR_TO_INT32 to
* store int32_t values. Null/zero values can be stored and retrieved.
* Of course, the destructor function (if any) must handle such values
* correctly.
*/
#[repr(C)]
#[derive(Debug)]
--- a/servo/components/style/gecko_bindings/structs_release.rs
+++ b/servo/components/style/gecko_bindings/structs_release.rs
@@ -1000,16 +1000,17 @@ pub mod root {
pub const NS_STYLE_SCROLL_SNAP_TYPE_PROXIMITY: ::std::os::raw::c_uint = 2;
pub const NS_STYLE_ORIENTATION_PORTRAIT: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_ORIENTATION_LANDSCAPE: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_SCAN_PROGRESSIVE: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_SCAN_INTERLACE: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_DISPLAY_MODE_BROWSER: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_DISPLAY_MODE_MINIMAL_UI: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_DISPLAY_MODE_STANDALONE: ::std::os::raw::c_uint = 2;
+ pub const NS_STYLE_DISPLAY_MODE_FULLSCREEN: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_INHERIT_MASK: ::std::os::raw::c_uint = 16777215;
pub const NS_STYLE_HAS_TEXT_DECORATION_LINES: ::std::os::raw::c_uint =
16777216;
pub const NS_STYLE_HAS_PSEUDO_ELEMENT_DATA: ::std::os::raw::c_uint =
33554432;
pub const NS_STYLE_RELEVANT_LINK_VISITED: ::std::os::raw::c_uint =
67108864;
pub const NS_STYLE_IS_STYLE_IF_VISITED: ::std::os::raw::c_uint =
@@ -2340,16 +2341,24 @@ pub mod root {
pub static mut StyleSheet__cycleCollectorGlobal:
root::mozilla::StyleSheet_cycleCollection;
}
#[test]
fn bindgen_test_layout_StyleSheet() {
assert_eq!(::std::mem::size_of::<StyleSheet>() , 80usize);
assert_eq!(::std::mem::align_of::<StyleSheet>() , 8usize);
}
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct ServoStyleSheet {
+ pub _address: u8,
+ }
+ impl Clone for ServoStyleSheet {
+ fn clone(&self) -> Self { *self }
+ }
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Side {
eSideTop = 0,
eSideRight = 1,
eSideBottom = 2,
eSideLeft = 3,
}
@@ -2571,17 +2580,17 @@ pub mod root {
}
impl Clone for FramePropertyDescriptorUntyped {
fn clone(&self) -> Self { *self }
}
/**
* The FramePropertyTable is optimized for storing 0 or 1 properties on
* a given frame. Storing very large numbers of properties on a single
* frame will not be efficient.
- *
+ *
* Property values are passed as void* but do not actually have to be
* valid pointers. You can use NS_INT32_TO_PTR/NS_PTR_TO_INT32 to
* store int32_t values. Null/zero values can be stored and retrieved.
* Of course, the destructor function (if any) must handle such values
* correctly.
*/
#[repr(C)]
#[derive(Debug)]
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -31,36 +31,40 @@ use style::gecko::wrapper::GeckoElement;
use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
use style::gecko_bindings::bindings::{RawServoStyleRuleBorrowed, RawServoStyleRuleStrong};
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::{nsACString, nsAString};
use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
+use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
use style::gecko_bindings::structs;
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
use style::gecko_bindings::structs::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint};
+use style::gecko_bindings::structs::Loader;
+use style::gecko_bindings::structs::ServoStyleSheet;
use style::gecko_bindings::structs::nsresult;
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, PropertyId};
use style::properties::{apply_declarations, parse_one_declaration};
use style::restyle_hints::RestyleHint;
use style::selector_parser::PseudoElementCascadeType;
use style::sequential;
use style::string_cache::Atom;
-use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StyleRule};
+use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StyleRule, ImportRule};
+use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::thread_state;
use style::timer::Timer;
use style::traversal::{recalc_style_at, DomTraversal, PerLevelTraversalData};
use style_traits::ToCss;
use stylesheet_loader::StylesheetLoader;
/*
* For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
@@ -220,27 +224,28 @@ pub extern "C" fn Servo_Element_ShouldTr
pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyleSheetStrong {
let url = ServoUrl::parse("about:blank").unwrap();
let extra_data = ParserContextExtraData::default();
let origin = match mode {
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
SheetParsingMode::eUserSheetFeatures => Origin::User,
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
};
- let loader = StylesheetLoader::new();
let sheet = Arc::new(Stylesheet::from_str(
- "", url, origin, Default::default(), Some(&loader),
+ "", url, origin, Default::default(), None,
Box::new(StdoutErrorReporter), extra_data));
unsafe {
transmute(sheet)
}
}
#[no_mangle]
-pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(data: *const nsACString,
+pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
+ stylesheet: *mut ServoStyleSheet,
+ data: *const nsACString,
mode: SheetParsingMode,
base_url: *const nsACString,
base: *mut ThreadSafeURIHolder,
referrer: *mut ThreadSafeURIHolder,
principal: *mut ThreadSafePrincipalHolder)
-> RawServoStyleSheetStrong {
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
@@ -252,26 +257,72 @@ pub extern "C" fn Servo_StyleSheet_FromU
let base_str = unsafe { base_url.as_ref().unwrap().as_str_unchecked() };
let url = ServoUrl::parse(base_str).unwrap();
let extra_data = unsafe { ParserContextExtraData {
base: Some(GeckoArcURI::new(base)),
referrer: Some(GeckoArcURI::new(referrer)),
principal: Some(GeckoArcPrincipal::new(principal)),
}};
- let loader = StylesheetLoader::new();
+ let loader = if loader.is_null() {
+ None
+ } else {
+ Some(StylesheetLoader::new(loader, stylesheet))
+ };
+
+ // FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
+ let loader: Option<&StyleStylesheetLoader> = match loader {
+ None => None,
+ Some(ref s) => Some(s),
+ };
+
let sheet = Arc::new(Stylesheet::from_str(
- input, url, origin, Default::default(), Some(&loader),
+ input, url, origin, Default::default(), loader,
Box::new(StdoutErrorReporter), extra_data));
unsafe {
transmute(sheet)
}
}
#[no_mangle]
+pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheetBorrowed,
+ loader: *mut Loader,
+ gecko_stylesheet: *mut ServoStyleSheet,
+ data: *const nsACString,
+ base: *mut ThreadSafeURIHolder,
+ referrer: *mut ThreadSafeURIHolder,
+ principal: *mut ThreadSafePrincipalHolder)
+{
+ let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
+ let extra_data = unsafe { ParserContextExtraData {
+ base: Some(GeckoArcURI::new(base)),
+ referrer: Some(GeckoArcURI::new(referrer)),
+ principal: Some(GeckoArcPrincipal::new(principal)),
+ }};
+
+ let loader = if loader.is_null() {
+ None
+ } else {
+ Some(StylesheetLoader::new(loader, gecko_stylesheet))
+ };
+
+ // FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
+ let loader: Option<&StyleStylesheetLoader> = match loader {
+ None => None,
+ Some(ref s) => Some(s),
+ };
+
+ let sheet = Stylesheet::as_arc(&stylesheet);
+ sheet.rules.write().0.clear();
+
+ Stylesheet::update_from_str(&sheet, input, loader,
+ Box::new(StdoutErrorReporter), extra_data);
+}
+
+#[no_mangle]
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowed,
raw_sheet: RawServoStyleSheetBorrowed,
flush: bool) {
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let sheet = HasArcFFI::as_arc(&raw_sheet);
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.push(sheet.clone());
data.stylesheets_changed = true;
@@ -453,16 +504,26 @@ pub extern "C" fn Servo_StyleRule_GetCss
#[no_mangle]
pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed, result: *mut nsAString) -> () {
let rule = RwLock::<StyleRule>::as_arc(&rule);
rule.read().selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
}
#[no_mangle]
+pub extern "C" fn Servo_ImportRule_AddRef(rule: RawServoImportRuleBorrowed) -> () {
+ unsafe { RwLock::<ImportRule>::addref(rule) };
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_ImportRule_Release(rule: RawServoImportRuleBorrowed) -> () {
+ unsafe { RwLock::<ImportRule>::release(rule) };
+}
+
+#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
pseudo_tag: *mut nsIAtom,
raw_data: RawServoStyleSetBorrowed)
-> ServoComputedValuesStrong {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let atom = Atom::from(pseudo_tag);
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true);
@@ -828,16 +889,24 @@ pub extern "C" fn Servo_NoteExplicitHint
restyle_data.hint.insert(&restyle_hint.into());
restyle_data.damage |= damage;
} else {
debug!("(Element not styled, discarding hints)");
}
}
#[no_mangle]
+pub extern "C" fn Servo_ImportRule_GetSheet(import_rule:
+ RawServoImportRuleBorrowed)
+ -> RawServoStyleSheetStrong {
+ let import_rule = RwLock::<ImportRule>::as_arc(&import_rule);
+ unsafe { transmute(import_rule.read().stylesheet.clone()) }
+}
+
+#[no_mangle]
pub extern "C" fn Servo_CheckChangeHint(element: RawGeckoElementBorrowed) -> nsChangeHint
{
let element = GeckoElement(element);
if element.get_data().is_none() {
error!("Trying to get change hint from unstyled element");
return nsChangeHint(0);
}
--- a/servo/ports/geckolib/stylesheet_loader.rs
+++ b/servo/ports/geckolib/stylesheet_loader.rs
@@ -1,21 +1,47 @@
/* 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/. */
use parking_lot::RwLock;
+use std::mem;
use std::sync::Arc;
+use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
+use style::gecko_bindings::structs::{Loader, ServoStyleSheet};
use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
+use style_traits::ToCss;
-pub struct StylesheetLoader;
+pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet);
impl StylesheetLoader {
- pub fn new() -> Self {
- StylesheetLoader
+ pub fn new(loader: *mut Loader, parent: *mut ServoStyleSheet) -> Self {
+ StylesheetLoader(loader, parent)
}
}
impl StyleStylesheetLoader for StylesheetLoader {
- fn request_stylesheet(&self, _import: &Arc<RwLock<ImportRule>>) {
- // FIXME(emilio): Implement `@import` in stylo.
+ fn request_stylesheet(&self, import_rule: &Arc<RwLock<ImportRule>>) {
+ let import = import_rule.read();
+ let (spec_bytes, spec_len) = import.url.as_slice_components()
+ .expect("Import only loads valid URLs");
+
+ // TODO(emilio): We probably want to share media representation with
+ // Gecko in Stylo.
+ //
+ // This also allows us to get rid of a bunch of extra work to evaluate
+ // and ensure parity, and shouldn't be much Gecko work given we always
+ // evaluate them on the main thread.
+ //
+ // Meanwhile, this works.
+ let media = import.stylesheet.media.read().to_css_string();
+
+ unsafe {
+ Gecko_LoadStyleSheet(self.0,
+ self.1,
+ mem::transmute(import_rule.clone()),
+ spec_bytes,
+ spec_len as u32,
+ media.as_bytes().as_ptr(),
+ media.len() as u32);
+ }
}
}