Bug 1325878: Allow creating empty Servo MediaList. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 10 Apr 2017 08:01:38 +0800
changeset 561037 6a90efbc300bd9d3ab669e6647ffbbc9dae6107d
parent 561036 0279b33c78a2b29e887df71c1d1abd57348af889
child 561038 2a834789d009463d3835e368dca5a2240d7e10be
push id53604
push userbmo:emilio+bugs@crisal.io
push dateWed, 12 Apr 2017 05:05:04 +0000
reviewersxidorn
bugs1325878
milestone55.0a1
Bug 1325878: Allow creating empty Servo MediaList. r?xidorn MozReview-Commit-ID: H7owjPB8dRi
layout/style/MediaList.cpp
layout/style/MediaList.h
layout/style/ServoBindingList.h
layout/style/ServoMediaList.cpp
layout/style/ServoMediaList.h
servo/ports/geckolib/glue.rs
--- a/layout/style/MediaList.cpp
+++ b/layout/style/MediaList.cpp
@@ -5,17 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* base class for representation of media lists */
 
 #include "mozilla/dom/MediaList.h"
 
 #include "mozAutoDocUpdate.h"
 #include "mozilla/dom/MediaListBinding.h"
+#include "mozilla/ServoMediaList.h"
 #include "mozilla/StyleSheetInlines.h"
+#include "nsCSSParser.h"
+#include "nsMediaList.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
@@ -63,16 +66,31 @@ MediaList::DoMediaChange(Func aCallback)
   }
   /* XXXldb Pass something meaningful? */
   if (doc) {
     doc->StyleRuleChanged(mStyleSheet, nullptr);
   }
   return rv;
 }
 
+/* static */ already_AddRefed<MediaList>
+MediaList::Create(nsIDocument* aDocument, const nsAString& aMedia)
+{
+  MOZ_ASSERT(aDocument);
+  if (aDocument->IsStyledByServo()) {
+    RefPtr<ServoMediaList> mediaList = new ServoMediaList(aMedia);
+    return mediaList.forget();
+  }
+
+  nsCSSParser parser;
+  RefPtr<nsMediaList> mediaList = new nsMediaList();
+  parser.ParseMediaList(aMedia, nullptr, 0, mediaList);
+  return mediaList.forget();
+}
+
 NS_IMETHODIMP
 MediaList::GetMediaText(nsAString& aMediaText)
 {
   GetText(aMediaText);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/layout/style/MediaList.h
+++ b/layout/style/MediaList.h
@@ -10,16 +10,18 @@
 #define mozilla_dom_MediaList_h
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/ServoUtils.h"
 
 #include "nsIDOMMediaList.h"
 #include "nsWrapperCache.h"
 
+class nsIDocument;
+
 namespace mozilla {
 class StyleSheet;
 
 namespace dom {
 
 // XXX This class doesn't use the branch dispatch approach that we use
 //     elsewhere for stylo, but instead just relies on virtual call.
 //     That's because this class should not be critical to performance,
@@ -30,16 +32,22 @@ namespace dom {
 
 class MediaList : public nsIDOMMediaList
                 , public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaList)
 
+  /**
+   * Creates a MediaList backed by the StyleBackendType of the document.
+   */
+  static already_AddRefed<MediaList> Create(nsIDocument* aDocument,
+                                            const nsAString& aMedia);
+
   virtual already_AddRefed<MediaList> Clone() = 0;
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
   nsISupports* GetParentObject() const { return nullptr; }
 
   virtual void GetText(nsAString& aMediaText) = 0;
   virtual void SetText(const nsAString& aMediaText) = 0;
 
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -256,16 +256,17 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
                    nscolor value)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetFontFamily, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    const nsAString& value)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetTextDecorationColorOverride, void,
                    RawServoDeclarationBlockBorrowed declarations)
 
 // MediaList
+SERVO_BINDING_FUNC(Servo_MediaList_Create, RawServoMediaListStrong)
 SERVO_BINDING_FUNC(Servo_MediaList_GetText, void,
                    RawServoMediaListBorrowed list, nsAString* result)
 SERVO_BINDING_FUNC(Servo_MediaList_SetText, void,
                    RawServoMediaListBorrowed list, const nsACString* text)
 SERVO_BINDING_FUNC(Servo_MediaList_GetLength, uint32_t,
                    RawServoMediaListBorrowed list)
 SERVO_BINDING_FUNC(Servo_MediaList_GetMediumAt, bool,
                    RawServoMediaListBorrowed list, uint32_t index,
--- a/layout/style/ServoMediaList.cpp
+++ b/layout/style/ServoMediaList.cpp
@@ -16,16 +16,27 @@ already_AddRefed<dom::MediaList>
 ServoMediaList::Clone()
 {
   // Currently MediaList::Clone() is only called from CSSStyleSheet's
   // constructor, so we don't need to support it at the moment.
   MOZ_ASSERT_UNREACHABLE("stylo: ServoMediaList doesn't support clone");
   return nullptr;
 }
 
+ServoMediaList::ServoMediaList()
+  : mRawList(Servo_MediaList_Create().Consume())
+{
+}
+
+ServoMediaList::ServoMediaList(const nsAString& aMedia)
+  : ServoMediaList()
+{
+  SetText(aMedia);
+}
+
 void
 ServoMediaList::GetText(nsAString& aMediaText)
 {
   Servo_MediaList_GetText(mRawList, &aMediaText);
 }
 
 void
 ServoMediaList::SetText(const nsAString& aMediaText)
--- a/layout/style/ServoMediaList.h
+++ b/layout/style/ServoMediaList.h
@@ -14,16 +14,18 @@
 
 namespace mozilla {
 
 class ServoMediaList final : public dom::MediaList
 {
 public:
   explicit ServoMediaList(already_AddRefed<RawServoMediaList> aRawList)
     : mRawList(aRawList) {}
+  explicit ServoMediaList(const nsAString& aMedia);
+  ServoMediaList();
 
   already_AddRefed<dom::MediaList> Clone() final;
 
   void GetText(nsAString& aMediaText) final;
   void SetText(const nsAString& aMediaText) final;
 
   uint32_t Length() final;
   void IndexedGetter(uint32_t aIndex, bool& aFound,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1151,16 +1151,24 @@ pub extern "C" fn Servo_DeclarationBlock
 
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawServoDeclarationBlockBorrowed,
                                                             property: nsCSSPropertyID) {
     remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ()))
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_MediaList_Create() -> RawServoMediaListStrong {
+
+    let global_style_data = &*GLOBAL_STYLE_DATA;
+    Arc::new(global_style_data.shared_lock.wrap(MediaList::default())).into_strong()
+
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed, result: *mut nsAString) {
     read_locked_arc(list, |list: &MediaList| {
         list.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
     })
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed, text: *const nsACString) {