dom/base/nsDOMClassInfo.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 sw=2 et tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef nsDOMClassInfo_h___
     8 #define nsDOMClassInfo_h___
    10 #include "mozilla/Attributes.h"
    11 #include "nsIXPCScriptable.h"
    12 #include "nsIScriptGlobalObject.h"
    13 #include "nsIDOMScriptObjectFactory.h"
    14 #include "js/Id.h"
    15 #include "nsIXPConnect.h"
    17 #ifdef XP_WIN
    18 #undef GetClassName
    19 #endif
    21 class nsContentList;
    22 class nsDocument;
    23 struct nsGlobalNameStruct;
    24 class nsGlobalWindow;
    25 class nsIScriptSecurityManager;
    27 struct nsDOMClassInfoData;
    29 typedef nsIClassInfo* (*nsDOMClassInfoConstructorFnc)
    30   (nsDOMClassInfoData* aData);
    32 typedef nsresult (*nsDOMConstructorFunc)(nsISupports** aNewObject);
    34 struct nsDOMClassInfoData
    35 {
    36   const char *mName;
    37   const char16_t *mNameUTF16;
    38   union {
    39     nsDOMClassInfoConstructorFnc mConstructorFptr;
    40     nsDOMClassInfoExternalConstructorFnc mExternalConstructorFptr;
    41   } u;
    43   nsIClassInfo *mCachedClassInfo; // low bit is set to 1 if external,
    44                                   // so be sure to mask if necessary!
    45   const nsIID *mProtoChainInterface;
    46   const nsIID **mInterfaces;
    47   uint32_t mScriptableFlags : 31; // flags must not use more than 31 bits!
    48   uint32_t mHasClassInterface : 1;
    49   uint32_t mInterfacesBitmap;
    50   bool mChromeOnly : 1;
    51   bool mAllowXBL : 1;
    52   bool mDisabled : 1;
    53 #ifdef DEBUG
    54   uint32_t mDebugID;
    55 #endif
    56 };
    58 struct nsExternalDOMClassInfoData : public nsDOMClassInfoData
    59 {
    60   const nsCID *mConstructorCID;
    61 };
    64 // To be used with the nsDOMClassInfoData::mCachedClassInfo pointer.
    65 // The low bit is set when we created a generic helper for an external
    66 // (which holds on to the nsDOMClassInfoData).
    67 #define GET_CLEAN_CI_PTR(_ptr) (nsIClassInfo*)(uintptr_t(_ptr) & ~0x1)
    68 #define MARK_EXTERNAL(_ptr) (nsIClassInfo*)(uintptr_t(_ptr) | 0x1)
    69 #define IS_EXTERNAL(_ptr) (uintptr_t(_ptr) & 0x1)
    72 class nsDOMClassInfo : public nsXPCClassInfo
    73 {
    74   friend class nsHTMLDocumentSH;
    75 public:
    76   nsDOMClassInfo(nsDOMClassInfoData* aData);
    77   virtual ~nsDOMClassInfo();
    79   NS_DECL_NSIXPCSCRIPTABLE
    81   NS_DECL_ISUPPORTS
    83   NS_DECL_NSICLASSINFO
    85   // Helper method that returns a *non* refcounted pointer to a
    86   // helper. So please note, don't release this pointer, if you do,
    87   // you better make sure you've addreffed before release.
    88   //
    89   // Whaaaaa! I wanted to name this method GetClassInfo, but nooo,
    90   // some of Microsoft devstudio's headers #defines GetClassInfo to
    91   // GetClassInfoA so I can't, those $%#@^! bastards!!! What gives
    92   // them the right to do that?
    94   static nsIClassInfo* GetClassInfoInstance(nsDOMClassInfoData* aData);
    96   static void ShutDown();
    98   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
    99   {
   100     return new nsDOMClassInfo(aData);
   101   }
   103   /*
   104    * The following two functions exist because of the way that Xray wrappers
   105    * work. In order to allow scriptable helpers to define non-IDL defined but
   106    * still "safe" properties for Xray wrappers, we call into the scriptable
   107    * helper with |obj| being the wrapper.
   108    *
   109    * Ideally, that would be the end of the story, however due to complications
   110    * dealing with document.domain, it's possible to end up in a scriptable
   111    * helper with a wrapper, even though we should be treating the lookup as a
   112    * transparent one.
   113    *
   114    * Note: So ObjectIsNativeWrapper(cx, obj) check usually means "through xray
   115    * wrapper this part is not visible" while combined with
   116    * || xpc::WrapperFactory::XrayWrapperNotShadowing(obj) it means "through
   117    * xray wrapper it is visible only if it does not hide any native property."
   118    */
   119   static bool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj);
   121   static nsISupports *GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj);
   123   static nsIXPConnect *XPConnect()
   124   {
   125     return sXPConnect;
   126   }
   127   static nsIScriptSecurityManager *ScriptSecurityManager()
   128   {
   129     return sSecMan;
   130   }
   132 protected:
   133   friend nsIClassInfo* NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
   135   const nsDOMClassInfoData* mData;
   137   virtual void PreserveWrapper(nsISupports *aNative) MOZ_OVERRIDE
   138   {
   139   }
   141   virtual uint32_t GetInterfacesBitmap() MOZ_OVERRIDE
   142   {
   143     return mData->mInterfacesBitmap;
   144   }
   146   static nsresult Init();
   147   static nsresult RegisterClassProtos(int32_t aDOMClassInfoID);
   148   static nsresult RegisterExternalClasses();
   149   nsresult ResolveConstructor(JSContext *cx, JSObject *obj,
   150                               JSObject **objp);
   152   // Checks if id is a number and returns the number, if aIsNumber is
   153   // non-null it's set to true if the id is a number and false if it's
   154   // not a number. If id is not a number this method returns -1
   155   static int32_t GetArrayIndexFromId(JSContext *cx, JS::Handle<jsid> id,
   156                                      bool *aIsNumber = nullptr);
   158   static nsIXPConnect *sXPConnect;
   159   static nsIScriptSecurityManager *sSecMan;
   161   // nsIXPCScriptable code
   162   static nsresult DefineStaticJSVals(JSContext *cx);
   164   static bool sIsInitialized;
   166 public:
   167   static jsid sLocation_id;
   168   static jsid sConstructor_id;
   169   static jsid sLength_id;
   170   static jsid sItem_id;
   171   static jsid sNamedItem_id;
   172   static jsid sEnumerate_id;
   173   static jsid sTop_id;
   174   static jsid sDocument_id;
   175   static jsid sWrappedJSObject_id;
   176 };
   178 // THIS ONE ISN'T SAFE!! It assumes that the private of the JSObject is
   179 // an nsISupports.
   180 inline
   181 const nsQueryInterface
   182 do_QueryWrappedNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj)
   183 {
   184   return nsQueryInterface(nsDOMClassInfo::GetNative(wrapper, obj));
   185 }
   187 // THIS ONE ISN'T SAFE!! It assumes that the private of the JSObject is
   188 // an nsISupports.
   189 inline
   190 const nsQueryInterfaceWithError
   191 do_QueryWrappedNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj,
   192                       nsresult *aError)
   194 {
   195   return nsQueryInterfaceWithError(nsDOMClassInfo::GetNative(wrapper, obj),
   196                                    aError);
   197 }
   199 inline
   200 nsQueryInterface
   201 do_QueryWrapper(JSContext *cx, JSObject *obj)
   202 {
   203   nsISupports *native =
   204     nsDOMClassInfo::XPConnect()->GetNativeOfWrapper(cx, obj);
   205   return nsQueryInterface(native);
   206 }
   208 inline
   209 nsQueryInterfaceWithError
   210 do_QueryWrapper(JSContext *cx, JSObject *obj, nsresult* error)
   211 {
   212   nsISupports *native =
   213     nsDOMClassInfo::XPConnect()->GetNativeOfWrapper(cx, obj);
   214   return nsQueryInterfaceWithError(native, error);
   215 }
   218 typedef nsDOMClassInfo nsDOMGenericSH;
   220 // Makes sure that the wrapper is preserved if new properties are added.
   221 class nsEventTargetSH : public nsDOMGenericSH
   222 {
   223 protected:
   224   nsEventTargetSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   225   {
   226   }
   228   virtual ~nsEventTargetSH()
   229   {
   230   }
   231 public:
   232   NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
   233                        JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
   234   NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   235                          JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
   237   virtual void PreserveWrapper(nsISupports *aNative) MOZ_OVERRIDE;
   239   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   240   {
   241     return new nsEventTargetSH(aData);
   242   }
   243 };
   245 // Window scriptable helper
   247 class nsWindowSH : public nsDOMGenericSH
   248 {
   249 protected:
   250   nsWindowSH(nsDOMClassInfoData *aData) : nsDOMGenericSH(aData)
   251   {
   252   }
   254   virtual ~nsWindowSH()
   255   {
   256   }
   258   static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
   259                                 JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
   260                                 JS::MutableHandle<JSPropertyDescriptor> desc);
   262   friend class nsGlobalWindow;
   263 public:
   264   NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
   265                        JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
   266   NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) MOZ_OVERRIDE;
   267   NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   268                         JSObject *obj) MOZ_OVERRIDE;
   269   NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   270                        JSObject *obj, bool *_retval) MOZ_OVERRIDE;
   271   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   272                         JSObject *obj, jsid id, JSObject **objp,
   273                         bool *_retval) MOZ_OVERRIDE;
   274   NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
   275                          JSObject * obj, JSObject * *_retval) MOZ_OVERRIDE;
   277   static bool NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin,
   278                                 const nsAString& aName,
   279                                 const nsGlobalNameStruct& aNameStruct);
   281   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   282   {
   283     return new nsWindowSH(aData);
   284   }
   285 };
   287 // Location scriptable helper
   289 class nsLocationSH : public nsDOMGenericSH
   290 {
   291 protected:
   292   nsLocationSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   293   {
   294   }
   296   virtual ~nsLocationSH()
   297   {
   298   }
   300 public:
   301   NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
   302                        JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
   303   NS_IMETHODIMP AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   304                             JSObject *obj, jsid id, JS::Value *vp, bool *_retval);
   306   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   307   {
   308     return new nsLocationSH(aData);
   309   }
   310 };
   313 // Generic array scriptable helper
   315 class nsGenericArraySH : public nsDOMClassInfo
   316 {
   317 protected:
   318   nsGenericArraySH(nsDOMClassInfoData* aData) : nsDOMClassInfo(aData)
   319   {
   320   }
   322   virtual ~nsGenericArraySH()
   323   {
   324   }
   326 public:
   327   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   328                         JSObject *obj, jsid id, JSObject **objp,
   329                         bool *_retval) MOZ_OVERRIDE;
   330   NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   331                        JSObject *obj, bool *_retval) MOZ_OVERRIDE;
   333   virtual nsresult GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   334                              JS::Handle<JSObject*> obj, uint32_t *length);
   336   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   337   {
   338     return new nsGenericArraySH(aData);
   339   }
   340 };
   343 // Array scriptable helper
   345 class nsArraySH : public nsGenericArraySH
   346 {
   347 protected:
   348   nsArraySH(nsDOMClassInfoData* aData) : nsGenericArraySH(aData)
   349   {
   350   }
   352   virtual ~nsArraySH()
   353   {
   354   }
   356   // Subclasses need to override this, if the implementation can't fail it's
   357   // allowed to not set *aResult.
   358   virtual nsISupports* GetItemAt(nsISupports *aNative, uint32_t aIndex,
   359                                  nsWrapperCache **aCache, nsresult *aResult) = 0;
   361 public:
   362   NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   363                          JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
   365 private:
   366   // Not implemented, nothing should create an instance of this class.
   367   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData);
   368 };
   371 // CSSRuleList helper
   373 class nsCSSRuleListSH : public nsArraySH
   374 {
   375 protected:
   376   nsCSSRuleListSH(nsDOMClassInfoData* aData) : nsArraySH(aData)
   377   {
   378   }
   380   virtual ~nsCSSRuleListSH()
   381   {
   382   }
   384   virtual nsISupports* GetItemAt(nsISupports *aNative, uint32_t aIndex,
   385                                  nsWrapperCache **aCache, nsresult *aResult) MOZ_OVERRIDE;
   387 public:
   388   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   389   {
   390     return new nsCSSRuleListSH(aData);
   391   }
   392 };
   394 // WebApps Storage helpers
   396 class nsStorage2SH : public nsDOMGenericSH
   397 {
   398 protected:
   399   nsStorage2SH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   400   {
   401   }
   403   virtual ~nsStorage2SH()
   404   {
   405   }
   407   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   408                         JSObject *obj, jsid id, JSObject **objp,
   409                         bool *_retval) MOZ_OVERRIDE;
   410   NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   411                          JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
   412   NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   413                          JSObject *obj, jsid id, JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
   414   NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   415                          JSObject *obj, jsid id, bool *_retval) MOZ_OVERRIDE;
   416   NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   417                           JSObject *obj, uint32_t enum_op, JS::Value *statep,
   418                           jsid *idp, bool *_retval) MOZ_OVERRIDE;
   420 public:
   421   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   422   {
   423     return new nsStorage2SH(aData);
   424   }
   425 };
   427 // Event handler 'this' translator class, this is called by XPConnect
   428 // when a "function interface" (nsIDOMEventListener) is called, this
   429 // class extracts 'this' fomr the first argument to the called
   430 // function (nsIDOMEventListener::HandleEvent(in nsIDOMEvent)), this
   431 // class will pass back nsIDOMEvent::currentTarget to be used as
   432 // 'this'.
   434 class nsEventListenerThisTranslator : public nsIXPCFunctionThisTranslator
   435 {
   436 public:
   437   nsEventListenerThisTranslator()
   438   {
   439   }
   441   virtual ~nsEventListenerThisTranslator()
   442   {
   443   }
   445   // nsISupports
   446   NS_DECL_ISUPPORTS
   448   // nsIXPCFunctionThisTranslator
   449   NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
   450 };
   452 class nsDOMConstructorSH : public nsDOMGenericSH
   453 {
   454 protected:
   455   nsDOMConstructorSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   456   {
   457   }
   459 public:
   460   NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
   461                        JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
   462   NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) MOZ_OVERRIDE
   463   {
   464     return NS_OK;
   465   }
   466   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   467                         JSObject *obj, jsid id, JSObject **objp,
   468                         bool *_retval) MOZ_OVERRIDE;
   469   NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   470                   JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
   472   NS_IMETHOD Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   473                        JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
   475   NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
   476                          JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
   477                          bool *_retval);
   479   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   480   {
   481     return new nsDOMConstructorSH(aData);
   482   }
   483 };
   485 class nsNonDOMObjectSH : public nsDOMGenericSH
   486 {
   487 protected:
   488   nsNonDOMObjectSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   489   {
   490   }
   492   virtual ~nsNonDOMObjectSH()
   493   {
   494   }
   496 public:
   497   NS_IMETHOD GetFlags(uint32_t *aFlags) MOZ_OVERRIDE;
   499   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   500   {
   501     return new nsNonDOMObjectSH(aData);
   502   }
   503 };
   505 #endif /* nsDOMClassInfo_h___ */

mercurial