layout/style/nsCSSStyleSheet.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/nsCSSStyleSheet.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,363 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +// vim:cindent:tabstop=2:expandtab:shiftwidth=2:
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/* representation of a CSS style sheet */
    1.11 +
    1.12 +#ifndef nsCSSStyleSheet_h_
    1.13 +#define nsCSSStyleSheet_h_
    1.14 +
    1.15 +#include "mozilla/Attributes.h"
    1.16 +#include "mozilla/MemoryReporting.h"
    1.17 +#include "mozilla/dom/Element.h"
    1.18 +
    1.19 +#include "nscore.h"
    1.20 +#include "nsCOMPtr.h"
    1.21 +#include "nsAutoPtr.h"
    1.22 +#include "nsIStyleSheet.h"
    1.23 +#include "nsIDOMCSSStyleSheet.h"
    1.24 +#include "nsICSSLoaderObserver.h"
    1.25 +#include "nsCOMArray.h"
    1.26 +#include "nsTArray.h"
    1.27 +#include "nsString.h"
    1.28 +#include "mozilla/CORSMode.h"
    1.29 +#include "nsCycleCollectionParticipant.h"
    1.30 +#include "nsWrapperCache.h"
    1.31 +
    1.32 +class nsXMLNameSpaceMap;
    1.33 +class nsCSSRuleProcessor;
    1.34 +class nsIPrincipal;
    1.35 +class nsIURI;
    1.36 +class nsMediaList;
    1.37 +class nsMediaQueryResultCacheKey;
    1.38 +class nsCSSStyleSheet;
    1.39 +class nsPresContext;
    1.40 +
    1.41 +namespace mozilla {
    1.42 +namespace css {
    1.43 +class Rule;
    1.44 +class GroupRule;
    1.45 +class ImportRule;
    1.46 +}
    1.47 +}
    1.48 +
    1.49 +// -------------------------------
    1.50 +// CSS Style Sheet Inner Data Container
    1.51 +//
    1.52 +
    1.53 +class nsCSSStyleSheetInner {
    1.54 +public:
    1.55 +  friend class nsCSSStyleSheet;
    1.56 +  friend class nsCSSRuleProcessor;
    1.57 +private:
    1.58 +  nsCSSStyleSheetInner(nsCSSStyleSheet* aPrimarySheet,
    1.59 +                       mozilla::CORSMode aCORSMode);
    1.60 +  nsCSSStyleSheetInner(nsCSSStyleSheetInner& aCopy,
    1.61 +                       nsCSSStyleSheet* aPrimarySheet);
    1.62 +  ~nsCSSStyleSheetInner();
    1.63 +
    1.64 +  nsCSSStyleSheetInner* CloneFor(nsCSSStyleSheet* aPrimarySheet);
    1.65 +  void AddSheet(nsCSSStyleSheet* aSheet);
    1.66 +  void RemoveSheet(nsCSSStyleSheet* aSheet);
    1.67 +
    1.68 +  void RebuildNameSpaces();
    1.69 +
    1.70 +  // Create a new namespace map
    1.71 +  nsresult CreateNamespaceMap();
    1.72 +
    1.73 +  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    1.74 +
    1.75 +  nsAutoTArray<nsCSSStyleSheet*, 8> mSheets;
    1.76 +  nsCOMPtr<nsIURI>       mSheetURI; // for error reports, etc.
    1.77 +  nsCOMPtr<nsIURI>       mOriginalSheetURI;  // for GetHref.  Can be null.
    1.78 +  nsCOMPtr<nsIURI>       mBaseURI; // for resolving relative URIs
    1.79 +  nsCOMPtr<nsIPrincipal> mPrincipal;
    1.80 +  nsCOMArray<mozilla::css::Rule> mOrderedRules;
    1.81 +  nsAutoPtr<nsXMLNameSpaceMap> mNameSpaceMap;
    1.82 +  // Linked list of child sheets.  This is al fundamentally broken, because
    1.83 +  // each of the child sheets has a unique parent... We can only hope (and
    1.84 +  // currently this is the case) that any time page JS can get ts hands on a
    1.85 +  // child sheet that means we've already ensured unique inners throughout its
    1.86 +  // parent chain and things are good.
    1.87 +  nsRefPtr<nsCSSStyleSheet> mFirstChild;
    1.88 +  mozilla::CORSMode      mCORSMode;
    1.89 +  bool                   mComplete;
    1.90 +
    1.91 +#ifdef DEBUG
    1.92 +  bool                   mPrincipalSet;
    1.93 +#endif
    1.94 +};
    1.95 +
    1.96 +
    1.97 +// -------------------------------
    1.98 +// CSS Style Sheet
    1.99 +//
   1.100 +
   1.101 +class CSSRuleListImpl;
   1.102 +
   1.103 +// CID for the nsCSSStyleSheet class
   1.104 +// ca926f30-2a7e-477e-8467-803fb32af20a
   1.105 +#define NS_CSS_STYLE_SHEET_IMPL_CID     \
   1.106 +{ 0xca926f30, 0x2a7e, 0x477e, \
   1.107 + { 0x84, 0x67, 0x80, 0x3f, 0xb3, 0x2a, 0xf2, 0x0a } }
   1.108 +
   1.109 +
   1.110 +class nsCSSStyleSheet MOZ_FINAL : public nsIStyleSheet,
   1.111 +                                  public nsIDOMCSSStyleSheet,
   1.112 +                                  public nsICSSLoaderObserver,
   1.113 +                                  public nsWrapperCache
   1.114 +{
   1.115 +public:
   1.116 +  nsCSSStyleSheet(mozilla::CORSMode aCORSMode);
   1.117 +
   1.118 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   1.119 +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSStyleSheet,
   1.120 +                                                         nsIStyleSheet)
   1.121 +
   1.122 +  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_SHEET_IMPL_CID)
   1.123 +
   1.124 +  // nsIStyleSheet interface
   1.125 +  virtual nsIURI* GetSheetURI() const MOZ_OVERRIDE;
   1.126 +  virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE;
   1.127 +  virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE;
   1.128 +  virtual void GetType(nsString& aType) const MOZ_OVERRIDE;
   1.129 +  virtual bool HasRules() const MOZ_OVERRIDE;
   1.130 +  virtual bool IsApplicable() const MOZ_OVERRIDE;
   1.131 +  virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE;
   1.132 +  virtual bool IsComplete() const MOZ_OVERRIDE;
   1.133 +  virtual void SetComplete() MOZ_OVERRIDE;
   1.134 +  virtual nsIStyleSheet* GetParentSheet() const MOZ_OVERRIDE;  // may be null
   1.135 +  virtual nsIDocument* GetOwningDocument() const MOZ_OVERRIDE;  // may be null
   1.136 +  virtual void SetOwningDocument(nsIDocument* aDocument) MOZ_OVERRIDE;
   1.137 +
   1.138 +  // Find the ID of the owner inner window.
   1.139 +  uint64_t FindOwningWindowInnerID() const;
   1.140 +#ifdef DEBUG
   1.141 +  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
   1.142 +#endif
   1.143 +
   1.144 +  void AppendStyleSheet(nsCSSStyleSheet* aSheet);
   1.145 +  void InsertStyleSheetAt(nsCSSStyleSheet* aSheet, int32_t aIndex);
   1.146 +
   1.147 +  // XXX do these belong here or are they generic?
   1.148 +  void PrependStyleRule(mozilla::css::Rule* aRule);
   1.149 +  void AppendStyleRule(mozilla::css::Rule* aRule);
   1.150 +  void ReplaceStyleRule(mozilla::css::Rule* aOld, mozilla::css::Rule* aNew);
   1.151 +
   1.152 +  int32_t StyleRuleCount() const;
   1.153 +  mozilla::css::Rule* GetStyleRuleAt(int32_t aIndex) const;
   1.154 +
   1.155 +  nsresult DeleteRuleFromGroup(mozilla::css::GroupRule* aGroup, uint32_t aIndex);
   1.156 +  nsresult InsertRuleIntoGroup(const nsAString& aRule, mozilla::css::GroupRule* aGroup, uint32_t aIndex, uint32_t* _retval);
   1.157 +  nsresult ReplaceRuleInGroup(mozilla::css::GroupRule* aGroup, mozilla::css::Rule* aOld, mozilla::css::Rule* aNew);
   1.158 +
   1.159 +  int32_t StyleSheetCount() const;
   1.160 +
   1.161 +  /**
   1.162 +   * SetURIs must be called on all sheets before parsing into them.
   1.163 +   * SetURIs may only be called while the sheet is 1) incomplete and 2)
   1.164 +   * has no rules in it
   1.165 +   */
   1.166 +  void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI);
   1.167 +
   1.168 +  /**
   1.169 +   * SetPrincipal should be called on all sheets before parsing into them.
   1.170 +   * This can only be called once with a non-null principal.  Calling this with
   1.171 +   * a null pointer is allowed and is treated as a no-op.
   1.172 +   */
   1.173 +  void SetPrincipal(nsIPrincipal* aPrincipal);
   1.174 +
   1.175 +  // Principal() never returns a null pointer.
   1.176 +  nsIPrincipal* Principal() const { return mInner->mPrincipal; }
   1.177 +
   1.178 +  // The document this style sheet is associated with.  May be null
   1.179 +  nsIDocument* GetDocument() const { return mDocument; }
   1.180 +
   1.181 +  void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
   1.182 +  void SetMedia(nsMediaList* aMedia);
   1.183 +  void SetOwningNode(nsINode* aOwningNode) { mOwningNode = aOwningNode; /* Not ref counted */ }
   1.184 +
   1.185 +  void SetOwnerRule(mozilla::css::ImportRule* aOwnerRule) { mOwnerRule = aOwnerRule; /* Not ref counted */ }
   1.186 +  mozilla::css::ImportRule* GetOwnerRule() const { return mOwnerRule; }
   1.187 +
   1.188 +  nsXMLNameSpaceMap* GetNameSpaceMap() const { return mInner->mNameSpaceMap; }
   1.189 +
   1.190 +  already_AddRefed<nsCSSStyleSheet> Clone(nsCSSStyleSheet* aCloneParent,
   1.191 +                                          mozilla::css::ImportRule* aCloneOwnerRule,
   1.192 +                                          nsIDocument* aCloneDocument,
   1.193 +                                          nsINode* aCloneOwningNode) const;
   1.194 +
   1.195 +  bool IsModified() const { return mDirty; }
   1.196 +
   1.197 +  void SetModifiedByChildRule() {
   1.198 +    NS_ASSERTION(mDirty,
   1.199 +                 "sheet must be marked dirty before handing out child rules");
   1.200 +    DidDirty();
   1.201 +  }
   1.202 +
   1.203 +  nsresult AddRuleProcessor(nsCSSRuleProcessor* aProcessor);
   1.204 +  nsresult DropRuleProcessor(nsCSSRuleProcessor* aProcessor);
   1.205 +
   1.206 +  /**
   1.207 +   * Like the DOM insertRule() method, but doesn't do any security checks
   1.208 +   */
   1.209 +  nsresult InsertRuleInternal(const nsAString& aRule,
   1.210 +                              uint32_t aIndex, uint32_t* aReturn);
   1.211 +
   1.212 +  /* Get the URI this sheet was originally loaded from, if any.  Can
   1.213 +     return null */
   1.214 +  virtual nsIURI* GetOriginalURI() const;
   1.215 +
   1.216 +  // nsICSSLoaderObserver interface
   1.217 +  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
   1.218 +                              nsresult aStatus) MOZ_OVERRIDE;
   1.219 +
   1.220 +  enum EnsureUniqueInnerResult {
   1.221 +    // No work was needed to ensure a unique inner.
   1.222 +    eUniqueInner_AlreadyUnique,
   1.223 +    // A clone was done to ensure a unique inner (which means the style
   1.224 +    // rules in this sheet have changed).
   1.225 +    eUniqueInner_ClonedInner
   1.226 +  };
   1.227 +  EnsureUniqueInnerResult EnsureUniqueInner();
   1.228 +
   1.229 +  // Append all of this sheet's child sheets to aArray.
   1.230 +  void AppendAllChildSheets(nsTArray<nsCSSStyleSheet*>& aArray);
   1.231 +
   1.232 +  bool UseForPresentation(nsPresContext* aPresContext,
   1.233 +                            nsMediaQueryResultCacheKey& aKey) const;
   1.234 +
   1.235 +  nsresult ParseSheet(const nsAString& aInput);
   1.236 +
   1.237 +  // nsIDOMStyleSheet interface
   1.238 +  NS_DECL_NSIDOMSTYLESHEET
   1.239 +
   1.240 +  // nsIDOMCSSStyleSheet interface
   1.241 +  NS_DECL_NSIDOMCSSSTYLESHEET
   1.242 +
   1.243 +  // Function used as a callback to rebuild our inner's child sheet
   1.244 +  // list after we clone a unique inner for ourselves.
   1.245 +  static bool RebuildChildList(mozilla::css::Rule* aRule, void* aBuilder);
   1.246 +
   1.247 +  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   1.248 +
   1.249 +  // Get this style sheet's CORS mode
   1.250 +  mozilla::CORSMode GetCORSMode() const { return mInner->mCORSMode; }
   1.251 +
   1.252 +  mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
   1.253 +  void SetScopeElement(mozilla::dom::Element* aScopeElement)
   1.254 +  {
   1.255 +    mScopeElement = aScopeElement;
   1.256 +  }
   1.257 +
   1.258 +  // WebIDL StyleSheet API
   1.259 +  // Our nsIStyleSheet::GetType is a const method, so it ends up
   1.260 +  // ambiguous with with the XPCOM version.  Just disambiguate.
   1.261 +  void GetType(nsString& aType) {
   1.262 +    const_cast<const nsCSSStyleSheet*>(this)->GetType(aType);
   1.263 +  }
   1.264 +  // Our XPCOM GetHref is fine for WebIDL
   1.265 +  nsINode* GetOwnerNode() const { return mOwningNode; }
   1.266 +  nsCSSStyleSheet* GetParentStyleSheet() const { return mParent; }
   1.267 +  // Our nsIStyleSheet::GetTitle is a const method, so it ends up
   1.268 +  // ambiguous with with the XPCOM version.  Just disambiguate.
   1.269 +  void GetTitle(nsString& aTitle) {
   1.270 +    const_cast<const nsCSSStyleSheet*>(this)->GetTitle(aTitle);
   1.271 +  }
   1.272 +  nsMediaList* Media();
   1.273 +  bool Disabled() const { return mDisabled; }
   1.274 +  // The XPCOM SetDisabled is fine for WebIDL
   1.275 +
   1.276 +  // WebIDL CSSStyleSheet API
   1.277 +  // Can't be inline because we can't include ImportRule here.  And can't be
   1.278 +  // called GetOwnerRule because that would be ambiguous with the ImportRule
   1.279 +  // version.
   1.280 +  nsIDOMCSSRule* GetDOMOwnerRule() const;
   1.281 +  nsIDOMCSSRuleList* GetCssRules(mozilla::ErrorResult& aRv);
   1.282 +  uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
   1.283 +                      mozilla::ErrorResult& aRv) {
   1.284 +    uint32_t retval;
   1.285 +    aRv = InsertRule(aRule, aIndex, &retval);
   1.286 +    return retval;
   1.287 +  }
   1.288 +  void DeleteRule(uint32_t aIndex, mozilla::ErrorResult& aRv) {
   1.289 +    aRv = DeleteRule(aIndex);
   1.290 +  }
   1.291 +
   1.292 +  // WebIDL miscellaneous bits
   1.293 +  mozilla::dom::ParentObject GetParentObject() const {
   1.294 +    if (mOwningNode) {
   1.295 +      return mozilla::dom::ParentObject(mOwningNode);
   1.296 +    }
   1.297 +
   1.298 +    return mozilla::dom::ParentObject(static_cast<nsIStyleSheet*>(mParent),
   1.299 +                                      mParent);
   1.300 +  }
   1.301 +  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   1.302 +
   1.303 +private:
   1.304 +  nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
   1.305 +                  nsCSSStyleSheet* aParentToUse,
   1.306 +                  mozilla::css::ImportRule* aOwnerRuleToUse,
   1.307 +                  nsIDocument* aDocumentToUse,
   1.308 +                  nsINode* aOwningNodeToUse);
   1.309 +
   1.310 +  nsCSSStyleSheet(const nsCSSStyleSheet& aCopy) MOZ_DELETE;
   1.311 +  nsCSSStyleSheet& operator=(const nsCSSStyleSheet& aCopy) MOZ_DELETE;
   1.312 +
   1.313 +protected:
   1.314 +  virtual ~nsCSSStyleSheet();
   1.315 +
   1.316 +  void ClearRuleCascades();
   1.317 +
   1.318 +  void     WillDirty();
   1.319 +  void     DidDirty();
   1.320 +
   1.321 +  // Return success if the subject principal subsumes the principal of our
   1.322 +  // inner, error otherwise.  This will also succeed if the subject has
   1.323 +  // UniversalXPConnect or if access is allowed by CORS.  In the latter case,
   1.324 +  // it will set the principal of the inner to the subject principal.
   1.325 +  nsresult SubjectSubsumesInnerPrincipal();
   1.326 +
   1.327 +  // Add the namespace mapping from this @namespace rule to our namespace map
   1.328 +  nsresult RegisterNamespaceRule(mozilla::css::Rule* aRule);
   1.329 +
   1.330 +  // Drop our reference to mRuleCollection
   1.331 +  void DropRuleCollection();
   1.332 +
   1.333 +  // Drop our reference to mMedia
   1.334 +  void DropMedia();
   1.335 +
   1.336 +  // Unlink our inner, if needed, for cycle collection
   1.337 +  void UnlinkInner();
   1.338 +  // Traverse our inner, if needed, for cycle collection
   1.339 +  void TraverseInner(nsCycleCollectionTraversalCallback &);
   1.340 +
   1.341 +protected:
   1.342 +  nsString              mTitle;
   1.343 +  nsRefPtr<nsMediaList> mMedia;
   1.344 +  nsRefPtr<nsCSSStyleSheet> mNext;
   1.345 +  nsCSSStyleSheet*      mParent;    // weak ref
   1.346 +  mozilla::css::ImportRule* mOwnerRule; // weak ref
   1.347 +
   1.348 +  nsRefPtr<CSSRuleListImpl> mRuleCollection;
   1.349 +  nsIDocument*          mDocument; // weak ref; parents maintain this for their children
   1.350 +  nsINode*              mOwningNode; // weak ref
   1.351 +  bool                  mDisabled;
   1.352 +  bool                  mDirty; // has been modified 
   1.353 +  nsRefPtr<mozilla::dom::Element> mScopeElement;
   1.354 +
   1.355 +  nsCSSStyleSheetInner* mInner;
   1.356 +
   1.357 +  nsAutoTArray<nsCSSRuleProcessor*, 8>* mRuleProcessors;
   1.358 +
   1.359 +  friend class nsMediaList;
   1.360 +  friend class nsCSSRuleProcessor;
   1.361 +  friend struct ChildSheetListBuilder;
   1.362 +};
   1.363 +
   1.364 +NS_DEFINE_STATIC_IID_ACCESSOR(nsCSSStyleSheet, NS_CSS_STYLE_SHEET_IMPL_CID)
   1.365 +
   1.366 +#endif /* !defined(nsCSSStyleSheet_h_) */

mercurial