Fix for bug 740069 (Generate JS bindings in C++ with a python script for DOM objects on the main thread and in workers. Infrastructure and new bindings for XMLHttpRequest). Patch by bent/bz/bholley/jst/khuey/peterv, r=bent/bz/bholley/jlebar/khuey/peterv/sicking/smaug.

--HG--
rename : js/xpconnect/tests/mochitest/test_bug462428.html => dom/bindings/test/test_lookupGetter.html
This commit is contained in:
Peter Van der Beken 2012-03-30 21:42:20 -07:00
parent 076f167058
commit c2e642fbcc
164 changed files with 15036 additions and 5057 deletions

View File

@ -94,8 +94,10 @@
#include "nsIContentSecurityPolicy.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/bindings/Utils.h"
using namespace mozilla;
using namespace mozilla::dom;
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
@ -2445,9 +2447,17 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
if (result) {
break;
}
} else if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
nsISupports *priv = (nsISupports *) js::GetObjectPrivate(aObj);
} else {
nsISupports *priv;
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
priv = (nsISupports *) js::GetObjectPrivate(aObj);
} else if ((jsClass->flags & JSCLASS_IS_DOMJSCLASS) &&
bindings::DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
priv = bindings::UnwrapDOMObject<nsISupports>(aObj, jsClass);
} else {
priv = nsnull;
}
#ifdef DEBUG
if (aAllowShortCircuit) {

View File

@ -6580,16 +6580,17 @@ nsContentUtils::ReleaseWrapper(nsISupports* aScriptObjectHolder,
nsWrapperCache* aCache)
{
if (aCache->PreservingWrapper()) {
// PreserveWrapper puts new DOM bindings in the JS holders hash, but they
// can also be in the DOM expando hash, so we need to try to remove them
// from both here.
JSObject* obj = aCache->GetWrapperPreserveColor();
if (aCache->IsDOMBinding()) {
if (aCache->IsDOMBinding() && obj) {
JSCompartment *compartment = js::GetObjectCompartment(obj);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(JS_GetCompartmentPrivate(compartment));
priv->RemoveDOMExpandoObject(obj);
}
else {
DropJSObjects(aScriptObjectHolder);
}
DropJSObjects(aScriptObjectHolder);
aCache->SetPreservingWrapper(false);
}

View File

@ -105,6 +105,7 @@
#include "nsIFileChannel.h"
#include "mozilla/Telemetry.h"
#include "sampler.h"
#include "mozilla/dom/bindings/XMLHttpRequestBinding.h"
#include "nsIDOMFormData.h"
#include "nsWrapperCacheInlines.h"
@ -483,6 +484,8 @@ nsXMLHttpRequest::nsXMLHttpRequest()
mResultArrayBuffer(nsnull)
{
nsLayoutStatics::AddRef();
SetIsDOMBinding();
#ifdef DEBUG
StaticAssertions();
#endif
@ -540,15 +543,17 @@ nsXMLHttpRequest::Init()
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ENSURE_STATE(subjectPrincipal);
mPrincipal = subjectPrincipal;
nsIScriptContext* context = GetScriptContextFromJSContext(cx);
nsCOMPtr<nsPIDOMWindow> window;
if (context) {
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(context->GetGlobalObject());
BindToOwner(window ? window->GetCurrentInnerWindow() : nsnull);
window = do_QueryInterface(context->GetGlobalObject());
if (window) {
window = window->GetCurrentInnerWindow();
}
}
Construct(subjectPrincipal, window);
return NS_OK;
}
/**
@ -561,11 +566,9 @@ nsXMLHttpRequest::Init(nsIPrincipal* aPrincipal,
nsIURI* aBaseURI)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
mPrincipal = aPrincipal;
BindToOwner(aOwnerWindow ? aOwnerWindow->GetCurrentInnerWindow() : nsnull);
mBaseURI = aBaseURI;
Construct(aPrincipal,
aOwnerWindow ? aOwnerWindow->GetCurrentInnerWindow() : nsnull,
aBaseURI);
return NS_OK;
}
@ -586,9 +589,9 @@ nsXMLHttpRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
// so re-set principal and script context.
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(aOwner);
NS_ENSURE_STATE(scriptPrincipal);
mPrincipal = scriptPrincipal->GetPrincipal();
BindToOwner(owner);
return NS_OK;
Construct(scriptPrincipal->GetPrincipal(), owner);
return NS_OK;
}
void
@ -1087,6 +1090,15 @@ nsXMLHttpRequest::StaticAssertions()
== bindings::prototypes::XMLHttpRequestResponseType::value(XML_HTTP_RESPONSE_TYPE_ ## _uc), \
#_uc " should match")
ASSERT_ENUM_EQUAL(_empty, DEFAULT);
ASSERT_ENUM_EQUAL(arraybuffer, ARRAYBUFFER);
ASSERT_ENUM_EQUAL(blob, BLOB);
ASSERT_ENUM_EQUAL(document, DOCUMENT);
ASSERT_ENUM_EQUAL(json, JSON);
ASSERT_ENUM_EQUAL(text, TEXT);
ASSERT_ENUM_EQUAL(moz_chunked_text, CHUNKED_TEXT);
ASSERT_ENUM_EQUAL(moz_chunked_arraybuffer, CHUNKED_ARRAYBUFFER);
ASSERT_ENUM_EQUAL(moz_blob, MOZ_BLOB);
#undef ASSERT_ENUM_EQUAL
}
#endif
@ -1122,6 +1134,13 @@ NS_IMETHODIMP nsXMLHttpRequest::SetResponseType(const nsAString& aResponseType)
return rv;
}
void
nsXMLHttpRequest::SetResponseType(XMLHttpRequestResponseType aType,
nsresult& aRv)
{
SetResponseType(ResponseType(aType), aRv);
}
void
nsXMLHttpRequest::SetResponseType(nsXMLHttpRequest::ResponseType aResponseType,
nsresult& aRv)
@ -2706,7 +2725,7 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult,
/* static */
nsresult
nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
const RequestBody* aBody,
const Nullable<RequestBody>& aBody,
nsIInputStream** aResult,
nsACString& aContentType, nsACString& aCharset)
{
@ -2714,7 +2733,7 @@ nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
return ::GetRequestBody(aVariant, aResult, aContentType, aCharset);
}
const RequestBody& body = *aBody;
const RequestBody& body = aBody.Value();
RequestBody::Value value = body.GetValue();
switch (body.GetType()) {
case nsXMLHttpRequest::RequestBody::ArrayBuffer:
@ -2764,11 +2783,11 @@ nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
NS_IMETHODIMP
nsXMLHttpRequest::Send(nsIVariant *aBody)
{
return Send(aBody, nsnull);
return Send(aBody, Nullable<RequestBody>());
}
nsresult
nsXMLHttpRequest::Send(nsIVariant* aVariant, const RequestBody* aBody)
nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
{
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
@ -2885,7 +2904,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const RequestBody* aBody)
mLoadTotal = 0;
mUploadProgress = 0;
mUploadProgressMax = 0;
if ((aVariant || aBody) && httpChannel &&
if ((aVariant || !aBody.IsNull()) && httpChannel &&
!method.EqualsLiteral("GET")) {
nsCAutoString charset;
@ -3841,6 +3860,20 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
return QueryInterface(aIID, aResult);
}
JS::Value
nsXMLHttpRequest::GetInterface(JSContext* aCx, nsIJSIID* aIID, nsresult& aRv)
{
const nsID* iid = aIID->GetID();
nsCOMPtr<nsISupports> result;
JS::Value v = JSVAL_NULL;
aRv = GetInterface(*iid, getter_AddRefs(result));
NS_ENSURE_SUCCESS(aRv, JSVAL_NULL);
JSObject* global = JS_GetGlobalForObject(aCx, GetWrapper());
aRv = nsContentUtils::WrapNative(aCx, global, result, iid, &v);
return NS_SUCCEEDED(aRv) ? v : JSVAL_NULL;
}
nsXMLHttpRequestUpload*
nsXMLHttpRequest::GetUpload()
{

View File

@ -67,16 +67,37 @@
#include "nsContentUtils.h"
#include "nsDOMFile.h"
#include "nsDOMBlobBuilder.h"
#include "nsIPrincipal.h"
#include "nsIScriptObjectPrincipal.h"
#include "mozilla/dom/bindings/XMLHttpRequestBinding.h"
#include "mozilla/dom/bindings/XMLHttpRequestUploadBinding.h"
#include "mozilla/Assertions.h"
class nsILoadGroup;
class AsyncVerifyRedirectCallbackForwarder;
class nsIUnicodeDecoder;
class nsIDOMFormData;
#define IMPL_EVENT_HANDLER(_lowercase, _capitalized) \
JSObject* GetOn##_lowercase() \
{ \
return GetListenerAsJSObject(mOn##_capitalized##Listener); \
} \
void SetOn##_lowercase(JSContext* aCx, JSObject* aCallback, nsresult& aRv) \
{ \
aRv = SetJSObjectListener(aCx, NS_LITERAL_STRING(#_lowercase), \
mOn##_capitalized##Listener, \
aCallback); \
}
class nsXHREventTarget : public nsDOMEventTargetHelper,
public nsIXMLHttpRequestEventTarget
{
public:
typedef mozilla::dom::bindings::prototypes::XMLHttpRequestResponseType::value
XMLHttpRequestResponseType;
virtual ~nsXHREventTarget() {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXHREventTarget,
@ -84,74 +105,14 @@ public:
NS_DECL_NSIXMLHTTPREQUESTEVENTTARGET
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
JSObject* GetOnloadstart()
{
return GetListenerAsJSObject(mOnLoadStartListener);
}
JSObject* GetOnprogress()
{
return GetListenerAsJSObject(mOnProgressListener);
}
JSObject* GetOnabort()
{
return GetListenerAsJSObject(mOnAbortListener);
}
JSObject* GetOnerror()
{
return GetListenerAsJSObject(mOnErrorListener);
}
JSObject* GetOnload()
{
return GetListenerAsJSObject(mOnLoadListener);
}
JSObject* GetOntimeout()
{
return GetListenerAsJSObject(mOnTimeoutListener);
}
JSObject* GetOnloadend()
{
return GetListenerAsJSObject(mOnLoadendListener);
}
void SetOnloadstart(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("loadstart"),
mOnLoadStartListener,
aCallback);
}
void SetOnprogress(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("progress"),
mOnProgressListener,
aCallback);
}
void SetOnabort(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("abort"), mOnAbortListener,
aCallback);
}
void SetOnerror(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("error"), mOnErrorListener,
aCallback);
}
void SetOnload(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("load"), mOnLoadListener,
aCallback);
}
void SetOntimeout(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("timeout"),
mOnTimeoutListener,
aCallback);
}
void SetOnloadend(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("loadend"),
mOnLoadendListener,
aCallback);
}
IMPL_EVENT_HANDLER(loadstart, LoadStart)
IMPL_EVENT_HANDLER(progress, Progress)
IMPL_EVENT_HANDLER(abort, Abort)
IMPL_EVENT_HANDLER(error, Error)
IMPL_EVENT_HANDLER(load, Load)
IMPL_EVENT_HANDLER(timeout, Timeout)
IMPL_EVENT_HANDLER(loadend, Loadend)
virtual void DisconnectFromOwner();
protected:
static inline JSObject* GetListenerAsJSObject(nsDOMEventListenerWrapper* aWrapper)
@ -161,20 +122,18 @@ protected:
JSObject* obj;
return holder && NS_SUCCEEDED(holder->GetJSObject(&obj)) ? obj : nsnull;
}
inline nsresult SetJSObjectListener(const nsAString& aType,
inline nsresult SetJSObjectListener(JSContext* aCx,
const nsAString& aType,
nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
JSObject* aCallback)
{
nsresult rv;
nsIScriptContext* context = GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMEventListener> listener;
if (aCallback) {
rv = nsContentUtils::XPConnect()->WrapJS(context->GetNativeContext(),
aCallback,
NS_GET_IID(nsIDOMEventListener),
getter_AddRefs(listener));
nsresult rv =
nsContentUtils::XPConnect()->WrapJS(aCx,
aCallback,
NS_GET_IID(nsIDOMEventListener),
getter_AddRefs(listener));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -197,12 +156,23 @@ public:
nsXMLHttpRequestUpload(nsDOMEventTargetHelper* aOwner)
{
BindToOwner(aOwner);
SetIsDOMBinding();
}
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
NS_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget::)
NS_DECL_NSIXMLHTTPREQUESTUPLOAD
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::bindings::prototypes::XMLHttpRequestUpload::Wrap(cx, scope, this, triedToWrap);
}
nsISupports* GetParentObject()
{
return GetOwner();
}
bool HasListeners()
{
return mListenerManager && mListenerManager->HasListeners();
@ -225,6 +195,43 @@ public:
nsXMLHttpRequest();
virtual ~nsXMLHttpRequest();
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::bindings::prototypes::XMLHttpRequest::Wrap(cx, scope, this, triedToWrap);
}
nsISupports* GetParentObject()
{
return GetOwner();
}
// The WebIDL parser converts constructors into methods called _Constructor.
static already_AddRefed<nsXMLHttpRequest>
_Constructor(nsISupports* aGlobal, nsresult& aRv)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
nsCOMPtr<nsIScriptObjectPrincipal> principal = do_QueryInterface(aGlobal);
if (!window || ! principal) {
aRv = NS_ERROR_FAILURE;
return NULL;
}
nsRefPtr<nsXMLHttpRequest> req = new nsXMLHttpRequest();
req->Construct(principal->GetPrincipal(), window);
return req.forget();
}
void Construct(nsIPrincipal* aPrincipal,
nsPIDOMWindow* aOwnerWindow,
nsIURI* aBaseURI = NULL)
{
MOZ_ASSERT(aPrincipal);
MOZ_ASSERT_IF(aOwnerWindow, aOwnerWindow->IsInnerWindow());
mPrincipal = aPrincipal;
BindToOwner(aOwnerWindow);
mBaseURI = aBaseURI;
}
NS_DECL_ISUPPORTS_INHERITED
// nsIXMLHttpRequest
@ -265,16 +272,7 @@ public:
#endif
// event handler
JSObject* GetOnreadystatechange()
{
return GetListenerAsJSObject(mOnReadystatechangeListener);
}
void SetOnreadystatechange(JSObject* aCallback, nsresult& aRv)
{
aRv = SetJSObjectListener(NS_LITERAL_STRING("readystatechange"),
mOnReadystatechangeListener,
aCallback);
}
IMPL_EVENT_HANDLER(readystatechange, Readystatechange)
// states
uint16_t GetReadyState();
@ -368,21 +366,25 @@ private:
};
static nsresult GetRequestBody(nsIVariant* aVariant,
const RequestBody* aBody,
const Nullable<RequestBody>& aBody,
nsIInputStream** aResult,
nsACString& aContentType,
nsACString& aCharset);
nsresult Send(nsIVariant* aVariant, const RequestBody* aBody);
nsresult Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody);
nsresult Send(const Nullable<RequestBody>& aBody)
{
return Send(nsnull, aBody);
}
nsresult Send(const RequestBody& aBody)
{
return Send(nsnull, &aBody);
return Send(Nullable<RequestBody>(aBody));
}
public:
void Send(nsresult& aRv)
{
aRv = Send(nsnull, nsnull);
aRv = Send(Nullable<RequestBody>());
}
void Send(JSObject* aArrayBuffer, nsresult& aRv)
{
@ -449,6 +451,11 @@ public:
// XXX Should we do some validation here?
mOverrideMimeType = aMimeType;
}
XMLHttpRequestResponseType GetResponseType()
{
return XMLHttpRequestResponseType(mResponseType);
}
void SetResponseType(XMLHttpRequestResponseType aType, nsresult& aRv);
JS::Value GetResponse(JSContext* aCx, nsresult& aRv);
void GetResponseText(nsString& aResponseText, nsresult& aRv);
nsIDocument* GetResponseXML(nsresult& aRv);
@ -463,6 +470,9 @@ public:
return mChannel;
}
// We need a GetInterface callable from JS for chrome JS
JS::Value GetInterface(JSContext*aCx, nsIJSIID* aIID, nsresult& aRv);
// This creates a trusted readystatechange event, which is not cancelable and
// doesn't bubble.
static nsresult CreateReadystatechangeEvent(nsIDOMEvent** aDOMEvent);
@ -712,6 +722,8 @@ protected:
nsTArray<RequestHeader> mModifiedRequestHeaders;
};
#undef IMPL_EVENT_HANDLER
// helper class to expose a progress DOM Event
class nsXMLHttpProgressEvent : public nsIDOMProgressEvent,

0
content/canvas/test/webgl/webgl-conformance-tests.html Normal file → Executable file
View File

View File

@ -77,6 +77,27 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMEventTargetHelper)
NS_DECL_NSIDOMEVENTTARGET
void AddEventListener(const nsAString& aType,
nsIDOMEventListener* aCallback, // XXX nullable
bool aCapture, Nullable<bool>& aWantsUntrusted,
nsresult& aRv)
{
aRv = AddEventListener(aType, aCallback, aCapture,
!aWantsUntrusted.IsNull() && aWantsUntrusted.Value(),
aWantsUntrusted.IsNull() ? 1 : 2);
}
void RemoveEventListener(const nsAString& aType,
nsIDOMEventListener* aCallback,
bool aCapture, nsresult& aRv)
{
aRv = RemoveEventListener(aType, aCallback, aCapture);
}
bool DispatchEvent(nsIDOMEvent* aEvent, nsresult& aRv)
{
bool result = false;
aRv = DispatchEvent(aEvent, &result);
return result;
}
void GetParentObject(nsIScriptGlobalObject **aParentObject)
{

View File

@ -90,6 +90,7 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../../../layout/style \
-I$(srcdir)/../../../dom/base \
-I$(topsrcdir)/xpcom/ds \
-I$(topsrcdir)/js/xpconnect/src \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT

View File

@ -59,10 +59,13 @@
#include "mozilla/scache/StartupCache.h"
#include "mozilla/scache/StartupCacheUtils.h"
#include "nsCCUncollectableMarker.h"
#include "mozilla/dom/bindings/Utils.h"
using namespace mozilla::scache;
using namespace mozilla;
using mozilla::dom::bindings::DestroyProtoOrIfaceCache;
static const char kXBLCachePrefix[] = "xblcache";
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
@ -180,6 +183,8 @@ nsXBLDocGlobalObject_finalize(JSContext *cx, JSObject *obj)
// The addref was part of JSObject construction
NS_RELEASE(nativeThis);
DestroyProtoOrIfaceCache(obj);
}
static JSBool

View File

@ -76,6 +76,8 @@ LOCAL_INCLUDES = -I$(srcdir)/../../../base/src \
-I$(srcdir)/../../../xbl/src \
-I$(srcdir)/../../../events/src \
-I$(topsrcdir)/xpcom/ds \
-I$(topsrcdir)/js/xpconnect/src \
-I$(topsrcdir)/dom/base \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT

View File

@ -66,6 +66,9 @@
#include "nsCCUncollectableMarker.h"
#include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
#include "xpcpublic.h"
#include "mozilla/dom/bindings/Utils.h"
using mozilla::dom::bindings::DestroyProtoOrIfaceCache;
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
@ -129,6 +132,8 @@ nsXULPDGlobalObject_finalize(JSContext *cx, JSObject *obj)
// The addref was part of JSObject construction
NS_RELEASE(nativeThis);
DestroyProtoOrIfaceCache(obj);
}

View File

@ -76,6 +76,7 @@ DIRS += \
DIRS += \
base \
bindings \
battery \
contacts \
power \

View File

@ -57,6 +57,8 @@
#include "xpcprivate.h"
#include "XPCWrapper.h"
#include "mozilla/dom/bindings/Common.h"
#include "nscore.h"
#include "nsDOMClassInfo.h"
#include "nsCRT.h"
@ -639,7 +641,6 @@ DOMCI_DATA(DOMConstructor, void)
0, \
false, \
false, \
NULL, \
NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
},
@ -656,7 +657,6 @@ DOMCI_DATA(DOMConstructor, void)
0, \
true, \
false, \
NULL, \
NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
},
@ -4465,7 +4465,11 @@ nsDOMClassInfo::Init()
sDisableGlobalScopePollutionSupport =
Preferences::GetBool("browser.dom.global_scope_pollution.disabled");
mozilla::dom::binding::Register(sClassInfoData);
// Proxy bindings
mozilla::dom::binding::Register(nameSpaceManager);
// Non-proxy bindings
mozilla::dom::bindings::Register(nameSpaceManager);
sIsInitialized = true;
@ -6571,6 +6575,15 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// We're resolving a name of a DOM interface for which there is no
// direct DOM class, create a constructor object...
// Lookup new DOM bindings.
mozilla::dom::binding::DefineInterface define =
name_struct->mDefineDOMInterface;
if (define && mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return rv;
}
nsRefPtr<nsDOMConstructor> constructor;
rv = nsDOMConstructor::Create(class_name,
nsnull,
@ -6628,7 +6641,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// Lookup new DOM bindings.
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
mozilla::dom::binding::DefineInterface define =
sClassInfoData[name_struct->mDOMClassInfoID].mDefineDOMInterface;
name_struct->mDefineDOMInterface;
if (define && mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
@ -6667,6 +6680,16 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
// We don't have a XPConnect prototype object, let ResolvePrototype create
// one.
// Lookup new DOM bindings.
mozilla::dom::binding::DefineInterface define =
name_struct->mDefineDOMInterface;
if (define && mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return rv;
}
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, nsnull,
name_struct, nameSpaceManager, nsnull, true,
did_resolve);
@ -7837,10 +7860,6 @@ NS_IMETHODIMP
nsEventTargetSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp, bool *_retval)
{
if (id == sAddEventListener_id) {
return NS_OK;
}
nsEventTargetSH::PreserveWrapper(GetNative(wrapper, obj));
return NS_OK;

View File

@ -103,8 +103,6 @@ struct nsDOMClassInfoData
PRUint32 mInterfacesBitmap;
bool mChromeOnly;
bool mDisabled;
// For new style DOM bindings.
mozilla::dom::binding::DefineInterface mDefineDOMInterface;
#ifdef NS_DEBUG
PRUint32 mDebugID;
#endif

View File

@ -108,6 +108,7 @@
#include "mozilla/FunctionTimer.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/bindings/Utils.h"
#include "sampler.h"
@ -2006,12 +2007,16 @@ nsJSContext::GetGlobalObject()
JSClass *c = JS_GetClass(global);
if (!c || ((~c->flags) & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
// Whenever we end up with globals that are JSCLASS_IS_DOMJSCLASS
// and have an nsISupports DOM object, we will need to modify this
// check here.
MOZ_ASSERT(!(c->flags & JSCLASS_IS_DOMJSCLASS));
if ((~c->flags) & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
return nsnull;
}
nsISupports *priv = (nsISupports *)js::GetObjectPrivate(global);
nsISupports *priv = static_cast<nsISupports*>(js::GetObjectPrivate(global));
nsCOMPtr<nsIXPConnectWrappedNative> wrapped_native =
do_QueryInterface(priv);

View File

@ -61,6 +61,8 @@
#include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
#include "mozilla/dom/bindings/Utils.h"
JSBool
nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
PRUint32* aLineno)
@ -99,7 +101,6 @@ nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
nsIScriptGlobalObject *
nsJSUtils::GetStaticScriptGlobal(JSContext* aContext, JSObject* aObj)
{
nsISupports* supports;
JSClass* clazz;
JSObject* glob = aObj; // starting point for search
@ -111,8 +112,12 @@ nsJSUtils::GetStaticScriptGlobal(JSContext* aContext, JSObject* aObj)
clazz = JS_GetClass(glob);
if (!clazz ||
!(clazz->flags & JSCLASS_HAS_PRIVATE) ||
// Whenever we end up with globals that are JSCLASS_IS_DOMJSCLASS
// and have an nsISupports DOM object, we will need to modify this
// check here.
MOZ_ASSERT(!(clazz->flags & JSCLASS_IS_DOMJSCLASS));
nsISupports* supports;
if (!(clazz->flags & JSCLASS_HAS_PRIVATE) ||
!(clazz->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) ||
!(supports = (nsISupports*)::JS_GetPrivate(glob))) {
return nsnull;

View File

@ -803,3 +803,12 @@ nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
void
nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAString& aName,
mozilla::dom::binding::DefineInterface aDefineDOMInterface)
{
nsGlobalNameStruct* s = LookupNameInternal(aName);
if (s) {
s->mDefineDOMInterface = aDefineDOMInterface;
}
}

View File

@ -97,6 +97,9 @@ struct nsGlobalNameStruct
nsCID mCID; // All other types...
};
// For new style DOM bindings.
mozilla::dom::binding::DefineInterface mDefineDOMInterface;
private:
// copy constructor
@ -166,7 +169,10 @@ public:
nsGlobalNameStruct* GetConstructorProto(const nsGlobalNameStruct* aStruct);
protected:
void RegisterDefineDOMInterface(const nsAString& aName,
mozilla::dom::binding::DefineInterface aDefineDOMInterface);
private:
// Adds a new entry to the hash and returns the nsGlobalNameStruct
// that aKey will be mapped to. If mType in the returned
// nsGlobalNameStruct is != eTypeNotInitialized, an entry for aKey

View File

@ -47,6 +47,16 @@ class XPCWrappedNativeScope;
typedef PRUptrdiff PtrBits;
namespace mozilla {
namespace dom {
namespace workers {
class DOMBindingBase;
} // namespace workers
} // namespace dom
} // namespace mozilla
#define NS_WRAPPERCACHE_IID \
{ 0x6f3179a1, 0x36f7, 0x4a5c, \
{ 0x8c, 0xf1, 0xad, 0xc8, 0x7c, 0xde, 0x3e, 0x87 } }
@ -72,7 +82,7 @@ typedef PRUptrdiff PtrBits;
* - a slim wrapper or the JSObject of an XPCWrappedNative wrapper
*
* If WRAPPER_IS_DOM_BINDING is set (IsDOMBinding() returns true):
* - a DOM binding object (proxy)
* - a DOM binding object (regular JS object or proxy)
*
* The finalizer for the wrapper clears the cache.
*
@ -82,6 +92,8 @@ typedef PRUptrdiff PtrBits;
*/
class nsWrapperCache
{
friend class mozilla::dom::workers::DOMBindingBase;
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_WRAPPERCACHE_IID)
@ -217,7 +229,7 @@ private:
/**
* If this bit is set then the wrapper for the native object is a DOM binding
* (proxy).
* (regular JS object or proxy).
*/
enum { WRAPPER_IS_DOM_BINDING = 1 << 1 };

View File

@ -0,0 +1,73 @@
# 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/.
import os
import cPickle
import WebIDL
from Configuration import *
from Codegen import CGBindingRoot, replaceFileIfChanged
# import Codegen in general, so we can set a variable on it
import Codegen
def generate_binding_header(config, outputprefix, webidlfile):
"""
|config| Is the configuration object.
|outputprefix| is a prefix to use for the header guards and filename.
"""
filename = outputprefix + ".h"
root = CGBindingRoot(config, outputprefix, webidlfile)
if replaceFileIfChanged(filename, root.declare()):
print "Generating binding header: %s" % (filename)
def generate_binding_cpp(config, outputprefix, webidlfile):
"""
|config| Is the configuration object.
|outputprefix| is a prefix to use for the header guards and filename.
"""
filename = outputprefix + ".cpp"
root = CGBindingRoot(config, outputprefix, webidlfile)
if replaceFileIfChanged(filename, root.define()):
print "Generating binding implementation: %s" % (filename)
def main():
# Parse arguments.
from optparse import OptionParser
usagestring = "usage: %prog [header|cpp] configFile outputPrefix webIDLFile"
o = OptionParser(usage=usagestring)
o.add_option("--verbose-errors", action='store_true', default=False,
help="When an error happens, display the Python traceback.")
o.add_option("--use-jsop-accessors", action='store_true', default=False,
dest='useJSOPAccessors',
help="Use JSPropertyOps instead of JSNatives for getters and setters")
(options, args) = o.parse_args()
Codegen.generateNativeAccessors = not options.useJSOPAccessors
if len(args) != 4 or (args[0] != "header" and args[0] != "cpp"):
o.error(usagestring)
buildTarget = args[0]
configFile = os.path.normpath(args[1])
outputPrefix = args[2]
webIDLFile = os.path.normpath(args[3])
# Load the parsing results
f = open('ParserResults.pkl', 'rb')
parserData = cPickle.load(f)
f.close()
# Create the configuration data.
config = Configuration(configFile, parserData)
# Generate the prototype classes.
if buildTarget == "header":
generate_binding_header(config, outputPrefix, webIDLFile);
elif buildTarget == "cpp":
generate_binding_cpp(config, outputPrefix, webIDLFile);
else:
assert False # not reached
if __name__ == '__main__':
main()

233
dom/bindings/Bindings.conf Normal file
View File

@ -0,0 +1,233 @@
# DOM Bindings Configuration.
#
# The WebIDL interfaces are defined in dom/webidl. For each such interface, there
# is a corresponding entry in the configuration table below. The configuration
# table maps each interface name to a |descriptor| or list of |descriptor|s.
#
# Valid fields for all descriptors:
# * nativeType - The native type (concrete class or XPCOM interface) that
# instances of this interface will unwrap to (required).
# * headerFile - The file in which the nativeType is declared (defaults
# to an educated guess).
# * castable - Indicates whether the value in the wrapper can be cast to
# nativeType, or whether it needs to be QI-ed (defaults to True
# for everything but callback interfaces).
# * concrete - Indicates whether there exist objects with this interface as
# their primary interface (defaults to True).
# * prefable - Indicates whether this binding is subject to the about:config
# pref, or whether it's always enabled (defaults to False).
# * workers - Indicates whether the descriptor is intended to be used for
# worker threads (defaults to false).
# * customTrace - The native class will use a custom trace hook (defaults to
# true for workers, false otherwise).
# * customFinalize - The native class will use a custom finalize hook
# (defaults to true for workers, false otherwise).
# * notflattened - The native type does not have nsIClassInfo, so when
# wrapping it the right IID needs to be passed in.
#
# The following fields are either a string, an array (defaults to an empty
# array) or a dictionary with three possible keys (all, getterOnly and
# setterOnly) each having such an array as the value
#
# * infallible - attributes and methods specified in the .webidl file that
# cannot fail and therefore do not require the final nsresult&
# argument
# * implicitJSContext - attributes and methods specified in the .webidl file
# that require a JSContext as the first argument
# * resultNotAddRefed - attributes and methods specified in the .webidl file
# that do not AddRef the return value
DOMInterfaces = {
'XMLHttpRequest': [
{
'nativeType': 'nsXMLHttpRequest',
'prefable': True,
'infallible': {
'all': [
'readyState', 'withCredentials', 'abort', 'statusText',
'getAllResponseHeaders', 'overrideMimeType', 'mozBackgroundRequest',
'multipart', 'channel', 'upload', 'status'
],
'getterOnly': [
'responseType', 'timeout', 'onreadystatechange'
]
},
'implicitJSContext': {
'all': [
'response', 'getInterface'
],
'setterOnly': [
'onreadystatechange'
]
},
'resultNotAddRefed': [ 'upload', 'responseXML' ]
},
{
'workers': True,
'nativeType': 'mozilla::dom::workers::XMLHttpRequest',
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequest.h',
'infallible': [
'readyState', 'statusText'
]
}],
'XMLHttpRequestUpload': [
{
'nativeType': 'nsXMLHttpRequestUpload',
'headerFile': 'nsXMLHttpRequest.h',
'prefable': True
},
{
'workers': True,
'nativeType': 'mozilla::dom::workers::XMLHttpRequestUpload',
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestUpload.h'
}],
'MozChannel': [
{
'nativeType': 'nsIChannel',
'prefable': True,
'castable': False,
'notflattened': True
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
'InputStream': [
{
'nativeType': 'nsIInputStream',
'prefable': True,
'castable': False,
'notflattened': True
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
'Document': [
{
'nativeType': 'nsIDocument',
'prefable': True,
'castable': False
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
'Blob': [
{
'nativeType': 'nsIDOMBlob',
'headerFile': 'nsIDOMFile.h',
'prefable': True,
'castable': False
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
'FormData': [
{
'nativeType': 'nsIDOMFormData',
'prefable': True,
'castable': False
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
'EventTarget': [
{
'nativeType': 'nsDOMEventTargetHelper',
'hasInstanceInterface': 'nsIDOMEventTarget',
'concrete': False,
'prefable': True,
},
{
'workers': True,
'nativeType': 'mozilla::dom::workers::EventTarget',
'headerFile': 'mozilla/dom/workers/bindings/EventTarget.h',
'concrete': False
}],
'Event': [
{
'nativeType': 'nsIDOMEvent',
'prefable': True,
'castable': False
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
'EventListener': [
{
'nativeType': 'nsIDOMEventListener',
'prefable': True
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h'
}],
'XMLHttpRequestEventTarget': [
{
'nativeType': 'nsXHREventTarget',
'headerFile': 'nsXMLHttpRequest.h',
'concrete': False,
'prefable': True,
'infallible': {
'getterOnly': [
'onabort', 'onerror', 'onload', 'onloadstart', 'onprogress',
'ontimeout', 'onloadend'
]
},
'implicitJSContext': {
'setterOnly': [
'onabort', 'onerror', 'onload', 'onloadstart', 'onprogress',
'ontimeout', 'onloadend'
]
}
},
{
'workers': True,
'concrete': False,
'nativeType': 'mozilla::dom::workers::XMLHttpRequestEventTarget',
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestEventTarget.h'
}],
'IID': [
{
'nativeType': 'nsIJSIID',
'headerFile': 'xpcjsid.h',
'prefable': True,
'castable': False
},
{
'workers': True,
'nativeType': 'JSObject',
'headerFile': 'jsapi.h',
'castable': False
}],
}

2982
dom/bindings/Codegen.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
# 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/.
autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
class Configuration:
"""
Represents global configuration state based on IDL parse data and
the configuration file.
"""
def __init__(self, filename, parseData):
# Read the configuration file.
glbl = {}
execfile(filename, glbl)
config = glbl['DOMInterfaces']
# Build descriptors for all the interfaces we have in the parse data.
# This allows callers to specify a subset of interfaces by filtering
# |parseData|.
self.descriptors = []
self.interfaces = {}
self.maxProtoChainLength = 0;
for thing in parseData:
if not thing.isInterface(): continue
iface = thing
if iface.identifier.name not in config: continue
self.interfaces[iface.identifier.name] = iface
entry = config[iface.identifier.name]
if not isinstance(entry, list):
assert isinstance(entry, dict)
entry = [entry]
self.descriptors.extend([Descriptor(self, iface, x) for x in entry])
# Mark the descriptors for which only a single nativeType implements
# an interface.
for descriptor in self.descriptors:
intefaceName = descriptor.interface.identifier.name
otherDescriptors = [d for d in self.descriptors
if d.interface.identifier.name == intefaceName]
descriptor.uniqueImplementation = len(otherDescriptors) == 1
self.enums = [e for e in parseData if e.isEnum()]
# Keep the descriptor list sorted for determinism.
self.descriptors.sort(lambda x,y: cmp(x.name, y.name))
def getInterface(self, ifname):
return self.interfaces[ifname]
def getDescriptors(self, **filters):
"""Gets the descriptors that match the given filters."""
curr = self.descriptors
for key, val in filters.iteritems():
if key == 'webIDLFile':
getter = lambda x: x.interface.filename()
elif key == 'hasInterfaceObject':
getter = lambda x: (not x.interface.isExternal() and
x.interface.hasInterfaceObject())
elif key == 'hasInterfacePrototypeObject':
getter = lambda x: (not x.interface.isExternal() and
x.interface.hasInterfacePrototypeObject())
elif key == 'hasInterfaceOrInterfacePrototypeObject':
getter = lambda x: x.hasInterfaceOrInterfacePrototypeObject()
elif key == 'isCallback':
getter = lambda x: x.interface.isCallback()
elif key == 'isExternal':
getter = lambda x: x.interface.isExternal()
else:
getter = lambda x: getattr(x, key)
curr = filter(lambda x: getter(x) == val, curr)
return curr
def getEnums(self, webIDLFile):
return filter(lambda e: e.filename() == webIDLFile, self.enums)
class Descriptor:
"""
Represents a single descriptor for an interface. See Bindings.conf.
"""
def __init__(self, config, interface, desc):
self.config = config
self.interface = interface
# Read the desc, and fill in the relevant defaults.
self.nativeType = desc['nativeType']
self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
headerDefault = self.nativeType
headerDefault = headerDefault.split("::")[-1] + ".h"
self.headerFile = desc.get('headerFile', headerDefault)
castableDefault = not self.interface.isCallback()
self.castable = desc.get('castable', castableDefault)
self.notflattened = desc.get('notflattened', False)
# If we're concrete, we need to crawl our ancestor interfaces and mark
# them as having a concrete descendant.
self.concrete = desc.get('concrete', True)
if self.concrete:
iface = self.interface
while iface:
iface.setUserData('hasConcreteDescendant', True)
iface = iface.parent
self.prefable = desc.get('prefable', False)
self.workers = desc.get('workers', False)
self.nativeIsISupports = not self.workers
self.customTrace = desc.get('customTrace', self.workers)
self.customFinalize = desc.get('customFinalize', self.workers)
def make_name(name):
return name + "_workers" if self.workers else name
self.name = make_name(interface.identifier.name)
# self.extendedAttributes is a dict of dicts, keyed on
# all/getterOnly/setterOnly and then on member name. Values are an
# array of extended attributes.
self.extendedAttributes = { 'all': {}, 'getterOnly': {}, 'setterOnly': {} }
def addExtendedAttribute(attribute, config):
def add(key, members, attribute):
for member in members:
self.extendedAttributes[key].setdefault(member, []).append(attribute)
if isinstance(config, dict):
for key in ['all', 'getterOnly', 'setterOnly']:
add(key, config.get(key, []), attribute)
elif isinstance(config, list):
add('all', config, attribute)
else:
assert isinstance(config, string)
add('all', [config], attribute)
for attribute in ['infallible', 'implicitJSContext', 'resultNotAddRefed']:
addExtendedAttribute(attribute, desc.get(attribute, {}))
self.binaryNames = desc.get('binaryNames', {})
# Build the prototype chain.
self.prototypeChain = []
parent = interface
while parent:
self.prototypeChain.insert(0, make_name(parent.identifier.name))
parent = parent.parent
config.maxProtoChainLength = max(config.maxProtoChainLength,
len(self.prototypeChain))
def hasInterfaceOrInterfacePrototypeObject(self):
# Forward-declared interfaces don't need either interface object or
# interface prototype object as they're going to use QI (on main thread)
# or be passed as a JSObject (on worker threads).
if self.interface.isExternal():
return False
return self.interface.hasInterfaceObject() or self.interface.hasInterfacePrototypeObject()
def getDescriptor(self, interfaceName):
"""
Gets the appropriate descriptor for the given interface name given the
context of the current descriptor. This selects the appropriate
implementation for cases like workers.
"""
iface = self.config.getInterface(interfaceName)
descriptors = self.config.getDescriptors(interface=iface)
# The only filter we currently have is workers vs non-workers.
matches = filter(lambda x: x.workers is self.workers, descriptors)
# After filtering, we should have exactly one result.
if len(matches) is not 1:
raise TypeError("For " + interfaceName + " found " +
str(len(matches)) + " matches");
return matches[0]
def getExtendedAttributes(self, member, getter=False, setter=False):
name = member.identifier.name
if member.isMethod():
return self.extendedAttributes['all'].get(name, [])
assert member.isAttr()
assert bool(getter) != bool(setter)
key = 'getterOnly' if getter else 'setterOnly'
return self.extendedAttributes['all'].get(name, []) + self.extendedAttributes[key].get(name, [])

104
dom/bindings/DOMJSClass.h Normal file
View File

@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* 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_dom_bindings_DOMJSClass_h
#define mozilla_dom_bindings_DOMJSClass_h
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/dom/bindings/PrototypeList.h" // auto-generated
// For non-global objects we use slot 0 for holding the raw object.
#define DOM_OBJECT_SLOT 0
// All DOM globals must have two slots at DOM_GLOBAL_OBJECT_SLOT and
// DOM_PROTOTYPE_SLOT. We have to start at 1 past JSCLASS_GLOBAL_SLOT_COUNT
// because XPConnect uses that one.
#define DOM_GLOBAL_OBJECT_SLOT (JSCLASS_GLOBAL_SLOT_COUNT + 1)
#define DOM_PROTOTYPE_SLOT (JSCLASS_GLOBAL_SLOT_COUNT + 2)
// We use these flag bits for the new bindings.
#define JSCLASS_IS_DOMJSCLASS JSCLASS_USERBIT1
#define JSCLASS_DOM_GLOBAL JSCLASS_USERBIT2
namespace mozilla {
namespace dom {
namespace bindings {
typedef bool
(* ResolveProperty)(JSContext* cx, JSObject* wrapper, jsid id, bool set,
JSPropertyDescriptor* desc);
typedef bool
(* EnumerateProperties)(JS::AutoIdVector& props);
struct NativePropertyHooks
{
ResolveProperty mResolveProperty;
EnumerateProperties mEnumerateProperties;
const NativePropertyHooks *mProtoHooks;
};
// Special JSClass for reflected DOM objects.
struct DOMJSClass
{
// It would be nice to just inherit from JSClass, but that precludes pure
// compile-time initialization of the form |DOMJSClass = {...};|, since C++
// only allows brace initialization for aggregate/POD types.
JSClass mBase;
// A list of interfaces that this object implements, in order of decreasing
// derivedness.
const prototypes::ID mInterfaceChain[prototypes::id::_ID_Count];
// We cache the VTable index of GetWrapperCache for objects that support it.
//
// -1 indicates that GetWrapperCache is not implemented on the underlying object.
// XXXkhuey this is unused and needs to die.
const int16_t mGetWrapperCacheVTableOffset;
// We store the DOM object in a reserved slot whose index is mNativeSlot.
// Sometimes it's an nsISupports and sometimes it's not; this class tells
// us which it is.
const bool mDOMObjectIsISupports;
// The slot to use to get the object reference from the object
const size_t mNativeSlot;
const NativePropertyHooks* mNativeHooks;
static DOMJSClass* FromJSClass(JSClass* base) {
MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
return reinterpret_cast<DOMJSClass*>(base);
}
static const DOMJSClass* FromJSClass(const JSClass* base) {
MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
return reinterpret_cast<const DOMJSClass*>(base);
}
static DOMJSClass* FromJSClass(js::Class* base) {
return FromJSClass(Jsvalify(base));
}
static const DOMJSClass* FromJSClass(const js::Class* base) {
return FromJSClass(Jsvalify(base));
}
JSClass* ToJSClass() { return &mBase; }
};
inline JSObject**
GetProtoOrIfaceArray(JSObject* global)
{
MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
return static_cast<JSObject**>(
js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).toPrivate());
}
} // namespace bindings
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_bindings_DOMJSClass_h */

81
dom/bindings/GlobalGen.py Normal file
View File

@ -0,0 +1,81 @@
# 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/.
# We do one global pass over all the WebIDL to generate our prototype enum
# and generate information for subsequent phases.
import os
import cStringIO
import WebIDL
import cPickle
from Configuration import *
from Codegen import GlobalGenRoots, replaceFileIfChanged
# import Codegen in general, so we can set a variable on it
import Codegen
def generate_file(config, name, action):
root = getattr(GlobalGenRoots, name)(config)
if action is 'declare':
filename = name + '.h'
code = root.declare()
else:
assert action is 'define'
filename = name + '.cpp'
code = root.define()
if replaceFileIfChanged(filename, code):
print "Generating %s" % (filename)
else:
print "%s hasn't changed - not touching it" % (filename)
def main():
# Parse arguments.
from optparse import OptionParser
usageString = "usage: %prog [options] webidldir [files]"
o = OptionParser(usage=usageString)
o.add_option("--cachedir", dest='cachedir', default=None,
help="Directory in which to cache lex/parse tables.")
o.add_option("--verbose-errors", action='store_true', default=False,
help="When an error happens, display the Python traceback.")
o.add_option("--use-jsop-accessors", action='store_true', default=False,
dest='useJSOPAccessors',
help="Use JSPropertyOps instead of JSNatives for getters and setters")
(options, args) = o.parse_args()
Codegen.generateNativeAccessors = not options.useJSOPAccessors
if len(args) < 2:
o.error(usageString)
configFile = args[0]
baseDir = args[1]
fileList = args[2:]
# Parse the WebIDL.
parser = WebIDL.Parser(options.cachedir)
for filename in fileList:
fullPath = os.path.normpath(os.path.join(baseDir, filename))
f = open(fullPath, 'rb')
lines = f.readlines()
f.close()
parser.parse(''.join(lines), fullPath)
parserResults = parser.finish()
# Write the parser results out to a pickle.
resultsFile = open('ParserResults.pkl', 'wb')
cPickle.dump(parserResults, resultsFile, -1)
resultsFile.close()
# Load the configuration.
config = Configuration(configFile, parserResults)
# Generate the prototype list.
generate_file(config, 'PrototypeList', 'declare')
# Generate the common code.
generate_file(config, 'Common', 'declare')
generate_file(config, 'Common', 'define')
if __name__ == '__main__':
main()

122
dom/bindings/Makefile.in Normal file
View File

@ -0,0 +1,122 @@
# 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/.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = dom
LIBRARY_NAME = dombindings_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
include $(topsrcdir)/config/config.mk
# Define USE_JSOP_ACCESSORS to a nonempty string like "yes" to use them
USE_JSOP_ACCESSORS =
ifdef USE_JSOP_ACCESSORS
DEFINES += -DUSE_JSOP_ACCESSORS
ACCESSOR_OPT = --use-jsop-accessors
else
ACCESSOR_OPT =
endif
# Need this to find all our DOM source files.
include $(topsrcdir)/dom/dom-config.mk
include $(topsrcdir)/dom/webidl/WebIDL.mk
binding_include_path := mozilla/dom/bindings
binding_header_files := $(subst .webidl,Binding.h,$(webidl_files))
binding_cpp_files := $(subst .webidl,Binding.cpp,$(webidl_files))
globalgen_targets := \
PrototypeList.h \
Common.h \
Common.cpp \
$(NULL)
CPPSRCS = \
$(binding_cpp_files) \
$(filter %.cpp, $(globalgen_targets)) \
Utils.cpp \
$(NULL)
EXPORTS_NAMESPACES = $(binding_include_path)
EXPORTS_$(binding_include_path) = \
DOMJSClass.h \
PrototypeList.h \
Common.h \
Nullable.h \
Utils.h \
$(binding_header_files) \
$(NULL)
LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
-I$(topsrcdir)/js/xpconnect/wrappers
TEST_DIRS += test
include $(topsrcdir)/config/rules.mk
bindinggen_dependencies := \
BindingGen.py \
Bindings.conf \
Configuration.py \
Codegen.py \
ParserResults.pkl \
$(GLOBAL_DEPS) \
$(NULL)
$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
$(webidl_base)/%.webidl \
$(NULL)
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
$(srcdir)/BindingGen.py $(ACCESSOR_OPT) header $(srcdir)/Bindings.conf $*Binding \
$(webidl_base)/$*.webidl
$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
$(webidl_base)/%.webidl \
$(NULL)
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
$(srcdir)/BindingGen.py $(ACCESSOR_OPT) cpp $(srcdir)/Bindings.conf $*Binding \
$(webidl_base)/$*.webidl
$(globalgen_targets): ParserResults.pkl
CACHE_DIR = _cache
globalgen_dependencies := \
GlobalGen.py \
Bindings.conf \
Configuration.py \
Codegen.py \
$(CACHE_DIR)/.done \
$(GLOBAL_DEPS) \
$(NULL)
$(CACHE_DIR)/.done:
$(MKDIR) -p $(CACHE_DIR)
@$(TOUCH) $@
ParserResults.pkl: $(globalgen_dependencies) \
$(addprefix $(webidl_base)/, $(webidl_files))
$(PYTHON_PATH) -I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
$(srcdir)/GlobalGen.py $(ACCESSOR_OPT) $(srcdir)/Bindings.conf $(webidl_base) \
--cachedir=$(CACHE_DIR) \
$(webidl_files)
GARBAGE += \
$(binding_header_files) \
$(binding_cpp_files) \
$(globalgen_targets) \
ParserResults.pkl \
webidlyacc.py \
parser.out \
$(NULL)

57
dom/bindings/Nullable.h Normal file
View File

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* vim: set ts=2 sw=2 et tw=79: */
/* 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_dom_bindings_Nullable_h
#define mozilla_dom_bindings_Nullable_h
#include "mozilla/Assertions.h"
namespace mozilla {
namespace dom {
namespace bindings {
// Support for nullable types
template <typename T>
struct Nullable
{
private:
T mValue;
bool mIsNull;
public:
Nullable()
: mIsNull(true)
{}
Nullable(T aValue)
: mValue(aValue)
, mIsNull(false)
{}
void SetValue(T aValue) {
mValue = aValue;
mIsNull = false;
}
void SetNull() {
mIsNull = true;
}
T Value() const {
MOZ_ASSERT(!mIsNull);
return mValue;
}
bool IsNull() const {
return mIsNull;
}
};
} // namespace bindings
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_bindings_Nullable_h */

244
dom/bindings/Utils.cpp Normal file
View File

@ -0,0 +1,244 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* vim: set ts=2 sw=2 et tw=79: */
/* 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 "Utils.h"
namespace mozilla {
namespace dom {
namespace bindings {
static bool
DefineConstants(JSContext* cx, JSObject* obj, ConstantSpec* cs)
{
for (; cs->name; ++cs) {
JSBool ok =
JS_DefineProperty(cx, obj, cs->name, cs->value, NULL, NULL,
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
if (!ok) {
return false;
}
}
return true;
}
static JSObject*
CreateInterfaceObject(JSContext* cx, JSObject* global,
JSClass* constructorClass, JSObject* proto,
JSFunctionSpec* staticMethods, ConstantSpec* constants,
const char* name)
{
JSObject* functionProto = JS_GetFunctionPrototype(cx, global);
if (!functionProto) {
return NULL;
}
JSObject* constructor =
JS_NewObject(cx, constructorClass, functionProto, global);
if (!constructor) {
return NULL;
}
if (staticMethods && !JS_DefineFunctions(cx, constructor, staticMethods)) {
return NULL;
}
if (constants && !DefineConstants(cx, constructor, constants)) {
return NULL;
}
if (proto && !JS_LinkConstructorAndPrototype(cx, constructor, proto)) {
return NULL;
}
// This is Enumerable: False per spec.
if (!JS_DefineProperty(cx, global, name, OBJECT_TO_JSVAL(constructor), NULL,
NULL, 0)) {
return NULL;
}
return constructor;
}
static JSObject*
CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
JSObject* parentProto, JSClass* protoClass,
JSFunctionSpec* methods,
JSPropertySpec* properties,
ConstantSpec* constants)
{
JSObject* ourProto = JS_NewObject(cx, protoClass, parentProto, global);
if (!ourProto) {
return NULL;
}
if (methods && !JS_DefineFunctions(cx, ourProto, methods)) {
return NULL;
}
if (properties && !JS_DefineProperties(cx, ourProto, properties)) {
return NULL;
}
if (constants && !DefineConstants(cx, ourProto, constants)) {
return NULL;
}
return ourProto;
}
JSObject*
CreateInterfaceObjects(JSContext *cx, JSObject *global, JSObject *parentProto,
JSClass *protoClass, JSClass *constructorClass,
JSFunctionSpec *methods, JSPropertySpec *properties,
ConstantSpec *constants, JSFunctionSpec *staticMethods,
const char* name)
{
MOZ_ASSERT(protoClass || constructorClass, "Need at least one class!");
MOZ_ASSERT(!(methods || properties) || protoClass,
"Methods or properties but no protoClass!");
MOZ_ASSERT(!staticMethods || constructorClass,
"Static methods but no constructorClass!");
MOZ_ASSERT(bool(name) == bool(constructorClass),
"Must have name precisely when we have an interface object");
JSObject* proto;
if (protoClass) {
proto = CreateInterfacePrototypeObject(cx, global, parentProto, protoClass,
methods, properties, constants);
if (!proto) {
return NULL;
}
}
else {
proto = NULL;
}
JSObject* interface;
if (constructorClass) {
interface = CreateInterfaceObject(cx, global, constructorClass, proto,
staticMethods, constants, name);
if (!interface) {
return NULL;
}
}
return protoClass ? proto : interface;
}
static bool
NativeInterface2JSObjectAndThrowIfFailed(XPCLazyCallContext& aLccx,
JSContext* aCx,
JS::Value* aRetval,
xpcObjectHelper& aHelper,
const nsIID* aIID,
bool aAllowNativeWrapper)
{
nsresult rv;
if (!XPCConvert::NativeInterface2JSObject(aLccx, aRetval, NULL, aHelper, aIID,
NULL, aAllowNativeWrapper, &rv)) {
// I can't tell if NativeInterface2JSObject throws JS exceptions
// or not. This is a sloppy stab at the right semantics; the
// method really ought to be fixed to behave consistently.
if (!JS_IsExceptionPending(aCx)) {
Throw<true>(aCx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
}
return false;
}
return true;
}
bool
DoHandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope,
nsISupports* value, JS::Value* vp)
{
if (JS_IsExceptionPending(cx)) {
return false;
}
XPCLazyCallContext lccx(JS_CALLER, cx, scope);
if (value) {
xpcObjectHelper helper(value);
return NativeInterface2JSObjectAndThrowIfFailed(lccx, cx, vp, helper, NULL,
true);
}
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
}
// Only set allowNativeWrapper to false if you really know you need it, if in
// doubt use true. Setting it to false disables security wrappers.
bool
XPCOMObjectToJsval(JSContext* cx, JSObject* scope, xpcObjectHelper &helper,
const nsIID* iid, bool allowNativeWrapper, JS::Value* rval)
{
XPCLazyCallContext lccx(JS_CALLER, cx, scope);
if (!NativeInterface2JSObjectAndThrowIfFailed(lccx, cx, rval, helper, iid,
allowNativeWrapper)) {
return false;
}
#ifdef DEBUG
JSObject* jsobj = JSVAL_TO_OBJECT(*rval);
if (jsobj && !js::GetObjectParent(jsobj))
NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
"Why did we recreate this wrapper?");
#endif
return true;
}
JSBool
QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
{
JS::Value thisv = JS_THIS(cx, vp);
if (thisv == JSVAL_NULL)
return false;
JSObject* obj = JSVAL_TO_OBJECT(thisv);
JSClass* clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp)) {
return Throw<true>(cx, NS_ERROR_FAILURE);
}
nsISupports* native = UnwrapDOMObject<nsISupports>(obj, clasp);
if (argc < 1) {
return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
}
JS::Value* argv = JS_ARGV(cx, vp);
if (!argv[0].isObject()) {
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
}
nsIJSIID* iid;
xpc_qsSelfRef iidRef;
if (NS_FAILED(xpc_qsUnwrapArg<nsIJSIID>(cx, argv[0], &iid, &iidRef.ptr,
&argv[0]))) {
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
}
MOZ_ASSERT(iid);
if (iid->GetID()->Equals(NS_GET_IID(nsIClassInfo))) {
nsresult rv;
nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(native, &rv);
if (NS_FAILED(rv)) {
return Throw<true>(cx, rv);
}
return WrapObject(cx, obj, ci, &NS_GET_IID(nsIClassInfo), vp);
}
// Lie, otherwise we need to check classinfo or QI
*vp = thisv;
return true;
}
} // namespace bindings
} // namespace dom
} // namespace mozilla

508
dom/bindings/Utils.h Normal file
View File

@ -0,0 +1,508 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* vim: set ts=2 sw=2 et tw=79: */
/* 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_dom_bindings_Utils_h__
#define mozilla_dom_bindings_Utils_h__
#include "mozilla/dom/bindings/DOMJSClass.h"
#include "jsapi.h"
#include "jstypedarray.h"
#include "XPCQuickStubs.h"
#include "XPCWrapper.h"
#include "nsTraceRefcnt.h"
#include "nsWrapperCacheInlines.h"
namespace mozilla {
namespace dom {
namespace bindings {
template<bool mainThread>
inline bool
Throw(JSContext* cx, nsresult rv)
{
// XXX Introduce exception machinery.
if (mainThread) {
XPCThrower::Throw(rv, cx);
} else {
if (!JS_IsExceptionPending(cx)) {
JS_ReportError(cx, "Exception thrown (nsresult = %x).", rv);
}
}
return false;
}
template<bool mainThread>
inline bool
ThrowMethodFailedWithDetails(JSContext* cx, nsresult rv,
const char* /* ifaceName */,
const char* /* memberName */)
{
return Throw<mainThread>(cx, rv);
}
inline bool
IsDOMClass(const JSClass* clasp)
{
return clasp->flags & JSCLASS_IS_DOMJSCLASS;
}
template <class T>
inline T*
UnwrapDOMObject(JSObject* obj, const JSClass* clasp)
{
MOZ_ASSERT(IsDOMClass(clasp));
MOZ_ASSERT(JS_GetClass(obj) == clasp);
size_t slot = DOMJSClass::FromJSClass(clasp)->mNativeSlot;
MOZ_ASSERT((slot == DOM_OBJECT_SLOT &&
!(clasp->flags & JSCLASS_DOM_GLOBAL)) ||
(slot == DOM_GLOBAL_OBJECT_SLOT &&
(clasp->flags & JSCLASS_DOM_GLOBAL)));
JS::Value val = js::GetReservedSlot(obj, slot);
// XXXbz/khuey worker code tries to unwrap interface objects (which have
// nothing here). That needs to stop.
// XXX We don't null-check UnwrapObject's result; aren't we going to crash
// anyway?
if (val.isUndefined()) {
return NULL;
}
return static_cast<T*>(val.toPrivate());
}
template <class T>
inline T*
UnwrapDOMObject(JSObject* obj, const js::Class* clasp)
{
return UnwrapDOMObject<T>(obj, Jsvalify(clasp));
}
// Some callers don't want to set an exception when unwrappin fails
// (for example, overload resolution uses unwrapping to tell what sort
// of thing it's looking at).
template <prototypes::ID PrototypeID, class T>
inline nsresult
UnwrapObject(JSContext* cx, JSObject* obj, T** value)
{
/* First check to see whether we have a DOM object */
JSClass* clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp)) {
/* Maybe we have a security wrapper or outer window? */
if (!js::IsWrapper(obj)) {
/* Not a DOM object, not a wrapper, just bail */
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
obj = XPCWrapper::Unwrap(cx, obj, false);
if (!obj) {
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
}
MOZ_ASSERT(!js::IsWrapper(obj));
clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp)) {
/* We don't have a DOM object */
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
}
MOZ_ASSERT(IsDOMClass(clasp));
/* This object is a DOM object. Double-check that it is safely
castable to T by checking whether it claims to inherit from the
class identified by protoID. */
DOMJSClass* domClass = DOMJSClass::FromJSClass(clasp);
if (domClass->mInterfaceChain[PrototypeTraits<PrototypeID>::Depth] ==
PrototypeID) {
*value = UnwrapDOMObject<T>(obj, clasp);
return NS_OK;
}
/* It's the wrong sort of DOM object */
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
inline bool
IsArrayLike(JSContext* cx, JSObject* obj)
{
MOZ_ASSERT(obj);
// For simplicity, check for security wrappers up front
if (js::IsWrapper(obj)) {
obj = XPCWrapper::Unwrap(cx, obj, false);
if (!obj) {
// Let's say it's not
return false;
}
}
// XXXbz need to detect platform objects (including listbinding
// ones) with indexGetters here!
return JS_IsArrayObject(cx, obj);
}
inline bool
IsPlatformObject(JSContext* cx, JSObject* obj)
{
// XXXbz Should be treating list-binding objects as platform objects
// too? The one consumer so far wants non-array-like platform
// objects, so listbindings that have an indexGetter should test
// false from here. Maybe this function should have a different
// name?
MOZ_ASSERT(obj);
// Fast-path the common case
JSClass* clasp = js::GetObjectJSClass(obj);
if (IsDOMClass(clasp)) {
return true;
}
// Now for simplicity check for security wrappers before anything else
if (js::IsWrapper(obj)) {
obj = XPCWrapper::Unwrap(cx, obj, false);
if (!obj) {
// Let's say it's not
return false;
}
clasp = js::GetObjectJSClass(obj);
}
return IS_WRAPPER_CLASS(js::Valueify(clasp)) || IsDOMClass(clasp) ||
JS_IsArrayBufferObject(obj);
}
template <class T>
inline nsresult
UnwrapObject(JSContext* cx, JSObject* obj, T* *value)
{
return UnwrapObject<static_cast<prototypes::ID>(
PrototypeIDMap<T>::PrototypeID)>(cx, obj, value);
}
const size_t kProtoOrIfaceCacheCount =
prototypes::id::_ID_Count + constructors::id::_ID_Count;
inline void
AllocateProtoOrIfaceCache(JSObject* obj)
{
MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
MOZ_ASSERT(js::GetReservedSlot(obj, DOM_PROTOTYPE_SLOT).isUndefined());
// Important: The () at the end ensure zero-initialization
JSObject** protoOrIfaceArray = new JSObject*[kProtoOrIfaceCacheCount]();
js::SetReservedSlot(obj, DOM_PROTOTYPE_SLOT,
JS::PrivateValue(protoOrIfaceArray));
}
inline void
DestroyProtoOrIfaceCache(JSObject* obj)
{
MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
JSObject** protoOrIfaceArray = GetProtoOrIfaceArray(obj);
delete [] protoOrIfaceArray;
}
struct ConstantSpec
{
const char* name;
JS::Value value;
};
/*
* Create a DOM interface object (if constructorClass is non-null) and/or a
* DOM interface prototype object (if protoClass is non-null).
*
* parentProto is the prototype to use for the interface prototype object.
* protoClass is the JSClass to use for the interface prototype object.
* This is null if we should not create an interface prototype
* object.
* constructorClass is the JSClass to use for the interface object.
* This is null if we should not create an interface object.
* methods and properties are to be defined on the interface prototype object;
* these arguments are allowed to be null if there are no
* methods or properties respectively.
* constants are to be defined on the interface object and on the interface
* prototype object; allowed to be null if there are no constants.
* staticMethods are to be defined on the interface object; allowed to be null
* if there are no static methods.
*
* At least one of protoClass and constructorClass should be non-null.
* If constructorClass is non-null, the resulting interface object will be
* defined on the given global with property name |name|, which must also be
* non-null.
*
* returns the interface prototype object if protoClass is non-null, else it
* returns the interface object.
*/
JSObject*
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* parentProto,
JSClass* protoClass, JSClass* constructorClass,
JSFunctionSpec* methods, JSPropertySpec* properties,
ConstantSpec* constants, JSFunctionSpec* staticMethods,
const char* name);
template <class T>
inline bool
WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp)
{
JSObject* obj = value->GetWrapper();
if (obj && js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) {
*vp = JS::ObjectValue(*obj);
return true;
}
if (!obj) {
bool triedToWrap;
obj = value->WrapObject(cx, scope, &triedToWrap);
if (!obj) {
// At this point, obj is null, so just return false. We could
// try to communicate triedToWrap to the caller, but in practice
// callers seem to be testing JS_IsExceptionPending(cx) to
// figure out whether WrapObject() threw instead.
return false;
}
}
// Now make sure that |obj| is wrapped for the compartment of |scope|
// correctly. That means entering the compartment of |scope|.
JSAutoEnterCompartment ac;
if (!ac.enter(cx, scope)) {
return false;
}
*vp = JS::ObjectValue(*obj);
return JS_WrapValue(cx, vp);
}
// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
template <template <class> class SmartPtr, class T>
inline bool
WrapNewBindingObject(JSContext* cx, JSObject* scope, const SmartPtr<T>& value,
JS::Value* vp)
{
return WrapNewBindingObject(cx, scope, value.get(), vp);
}
/**
* A method to handle new-binding wrap failure, by possibly falling back to
* wrapping as a non-new-binding object.
*/
bool
DoHandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope,
nsISupports* value, JS::Value* vp);
/**
* An easy way to call the above when you have a value which
* multiply-inherits from nsISupports.
*/
template <class T>
bool
HandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope, T* value,
JS::Value* vp)
{
nsCOMPtr<nsISupports> val;
CallQueryInterface(value, getter_AddRefs(val));
return DoHandleNewBindingWrappingFailure(cx, scope, val, vp);
}
// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
template <template <class> class SmartPtr, class T>
MOZ_ALWAYS_INLINE bool
HandleNewBindingWrappingFailure(JSContext* cx, JSObject* scope,
const SmartPtr<T>& value, JS::Value* vp)
{
return HandleNewBindingWrappingFailure(cx, scope, value.get(), vp);
}
struct EnumEntry {
const char* value;
size_t length;
};
inline int
FindEnumStringIndex(JSContext* cx, JS::Value v, const EnumEntry* values, bool* ok)
{
// JS_StringEqualsAscii is slow as molasses, so don't use it here.
JSString* str = JS_ValueToString(cx, v);
if (!str) {
*ok = false;
return 0;
}
JS::Anchor<JSString*> anchor(str);
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars) {
*ok = false;
return 0;
}
int i = 0;
for (const EnumEntry* value = values; value->value; ++value, ++i) {
if (length != value->length) {
continue;
}
bool equal = true;
const char* val = value->value;
for (size_t j = 0; j != length; ++j) {
if (unsigned(val[j]) != unsigned(chars[j])) {
equal = false;
break;
}
}
if (equal) {
*ok = true;
return i;
}
}
// XXX we don't know whether we're on the main thread, so play it safe
*ok = Throw<false>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
return 0;
}
inline nsWrapperCache*
GetWrapperCache(nsWrapperCache* cache)
{
return cache;
}
// nsGlobalWindow implements nsWrapperCache, but doesn't always use it. Don't
// try to use it without fixing that first.
class nsGlobalWindow;
inline nsWrapperCache*
GetWrapperCache(nsGlobalWindow* not_allowed);
inline nsWrapperCache*
GetWrapperCache(void* p)
{
return NULL;
}
// Only set allowNativeWrapper to false if you really know you need it, if in
// doubt use true. Setting it to false disables security wrappers.
bool
XPCOMObjectToJsval(JSContext* cx, JSObject* scope, xpcObjectHelper &helper,
const nsIID* iid, bool allowNativeWrapper, JS::Value* rval);
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, T* p, nsWrapperCache* cache,
const nsIID* iid, JS::Value* vp)
{
if (xpc_FastGetCachedWrapper(cache, scope, vp))
return true;
qsObjectHelper helper(p, cache);
return XPCOMObjectToJsval(cx, scope, helper, iid, true, vp);
}
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, T* p, const nsIID* iid,
JS::Value* vp)
{
return WrapObject(cx, scope, p, GetWrapperCache(p), iid, vp);
}
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, T* p, JS::Value* vp)
{
return WrapObject(cx, scope, p, NULL, vp);
}
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, nsCOMPtr<T> &p, const nsIID* iid,
JS::Value* vp)
{
return WrapObject(cx, scope, p.get(), iid, vp);
}
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, nsCOMPtr<T> &p, JS::Value* vp)
{
return WrapObject(cx, scope, p, NULL, vp);
}
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, nsRefPtr<T> &p, const nsIID* iid,
JS::Value* vp)
{
return WrapObject(cx, scope, p.get(), iid, vp);
}
template<class T>
inline bool
WrapObject(JSContext* cx, JSObject* scope, nsRefPtr<T> &p, JS::Value* vp)
{
return WrapObject(cx, scope, p, NULL, vp);
}
template<>
inline bool
WrapObject<JSObject>(JSContext* cx, JSObject* scope, JSObject* p, JS::Value* vp)
{
vp->setObjectOrNull(p);
return true;
}
template<class T>
static inline JSObject*
WrapNativeParent(JSContext* cx, JSObject* scope, T* p)
{
if (!p)
return scope;
nsWrapperCache* cache = GetWrapperCache(p);
JSObject* obj;
if (cache && (obj = cache->GetWrapper())) {
#ifdef DEBUG
qsObjectHelper helper(p, cache);
JS::Value debugVal;
bool ok = XPCOMObjectToJsval(cx, scope, helper, NULL, false, &debugVal);
NS_ASSERTION(ok && JSVAL_TO_OBJECT(debugVal) == obj,
"Unexpected object in nsWrapperCache");
#endif
return obj;
}
qsObjectHelper helper(p, cache);
JS::Value v;
return XPCOMObjectToJsval(cx, scope, helper, NULL, false, &v) ?
JSVAL_TO_OBJECT(v) :
NULL;
}
// Spec needs a name property
template <typename Spec>
static bool
InitIds(JSContext* cx, Spec* specs, jsid* ids)
{
Spec* spec = specs;
do {
JSString *str = ::JS_InternString(cx, spec->name);
if (!str) {
return false;
}
*ids = INTERNED_STRING_TO_JSID(cx, str);
} while (++ids, (++spec)->name);
return true;
}
JSBool
QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
} // namespace bindings
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_bindings_Utils_h__ */

View File

@ -0,0 +1 @@
A WebIDL parser written in Python to be used in Mozilla.

View File

@ -0,0 +1 @@
http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.409;content-type=text%2Fhtml%3b+charset=utf-8

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
__all__ = ['WebIDL']

View File

@ -0,0 +1,72 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is WebIDL Parser.
#
# The Initial Developer of the Original Code is
# the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Kyle Huey <me@kylehuey.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import os, sys
import glob
import WebIDL
class TestHarness(object):
def ok(self, condition, msg):
if condition:
print "TEST-PASS | %s" % msg
else:
print "TEST-UNEXPECTED-FAIL | %s" % msg
def check(self, a, b, msg):
if a == b:
print "TEST-PASS | %s" % msg
else:
print "TEST-UNEXPECTED-FAIL | %s" % msg
print "\tGot %s expected %s" % (a, b)
def run_tests():
harness = TestHarness()
tests = glob.iglob("tests/*.py")
sys.path.append("./tests")
for test in tests:
(testpath, ext) = os.path.splitext(os.path.basename(test))
_test = __import__(testpath, globals(), locals(), ['WebIDLTest'])
#try:
_test.WebIDLTest.__call__(WebIDL.Parser(), harness)
#except:
# print "TEST-UNEXPECTED-FAIL | Unhandled exception in Test %s" % testpath
# print sys.exc_info()[0]
print "Test %s Complete\n" % testpath
if __name__ == '__main__':
run_tests()

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface DoubleNull {
attribute any? foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface ArgumentIdentifierConflict {
void foo(boolean arg1, boolean arg1);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface VoidArgument1 {
void foo(void arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,25 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestArrayBuffer {
attribute ArrayBuffer attr;
void method(ArrayBuffer arg1, ArrayBuffer? arg2, ArrayBuffer[] arg3, sequence<ArrayBuffer> arg4);
};
""")
results = parser.finish()
iface = results[0]
harness.ok(True, "TestArrayBuffer interface parsed without error")
harness.check(len(iface.members), 2, "Interface should have two members")
attr = iface.members[0]
method = iface.members[1]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Expect an IDLAttribute")
harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod")
harness.check(str(attr.type), "ArrayBuffer", "Expect an ArrayBuffer type")
harness.ok(attr.type.isArrayBuffer(), "Expect an ArrayBuffer type")

View File

@ -0,0 +1,275 @@
import WebIDL
def WebIDLTest(parser, harness):
testData = [("::TestAttr%s::b", "b", "Byte%s", False),
("::TestAttr%s::rb", "rb", "Byte%s", True),
("::TestAttr%s::o", "o", "Octet%s", False),
("::TestAttr%s::ro", "ro", "Octet%s", True),
("::TestAttr%s::s", "s", "Short%s", False),
("::TestAttr%s::rs", "rs", "Short%s", True),
("::TestAttr%s::us", "us", "UnsignedShort%s", False),
("::TestAttr%s::rus", "rus", "UnsignedShort%s", True),
("::TestAttr%s::l", "l", "Long%s", False),
("::TestAttr%s::rl", "rl", "Long%s", True),
("::TestAttr%s::ul", "ul", "UnsignedLong%s", False),
("::TestAttr%s::rul", "rul", "UnsignedLong%s", True),
("::TestAttr%s::ll", "ll", "LongLong%s", False),
("::TestAttr%s::rll", "rll", "LongLong%s", True),
("::TestAttr%s::ull", "ull", "UnsignedLongLong%s", False),
("::TestAttr%s::rull", "rull", "UnsignedLongLong%s", True),
("::TestAttr%s::str", "str", "String%s", False),
("::TestAttr%s::rstr", "rstr", "String%s", True),
("::TestAttr%s::obj", "obj", "Object%s", False),
("::TestAttr%s::robj", "robj", "Object%s", True),
("::TestAttr%s::object", "object", "Object%s", False)]
parser.parse("""
interface TestAttr {
attribute byte b;
readonly attribute byte rb;
attribute octet o;
readonly attribute octet ro;
attribute short s;
readonly attribute short rs;
attribute unsigned short us;
readonly attribute unsigned short rus;
attribute long l;
readonly attribute long rl;
attribute unsigned long ul;
readonly attribute unsigned long rul;
attribute long long ll;
readonly attribute long long rll;
attribute unsigned long long ull;
readonly attribute unsigned long long rull;
attribute DOMString str;
readonly attribute DOMString rstr;
attribute object obj;
readonly attribute object robj;
attribute object _object;
};
interface TestAttrNullable {
attribute byte? b;
readonly attribute byte? rb;
attribute octet? o;
readonly attribute octet? ro;
attribute short? s;
readonly attribute short? rs;
attribute unsigned short? us;
readonly attribute unsigned short? rus;
attribute long? l;
readonly attribute long? rl;
attribute unsigned long? ul;
readonly attribute unsigned long? rul;
attribute long long? ll;
readonly attribute long long? rll;
attribute unsigned long long? ull;
readonly attribute unsigned long long? rull;
attribute DOMString? str;
readonly attribute DOMString? rstr;
attribute object? obj;
readonly attribute object? robj;
attribute object? _object;
};
interface TestAttrArray {
attribute byte[] b;
readonly attribute byte[] rb;
attribute octet[] o;
readonly attribute octet[] ro;
attribute short[] s;
readonly attribute short[] rs;
attribute unsigned short[] us;
readonly attribute unsigned short[] rus;
attribute long[] l;
readonly attribute long[] rl;
attribute unsigned long[] ul;
readonly attribute unsigned long[] rul;
attribute long long[] ll;
readonly attribute long long[] rll;
attribute unsigned long long[] ull;
readonly attribute unsigned long long[] rull;
attribute DOMString[] str;
readonly attribute DOMString[] rstr;
attribute object[] obj;
readonly attribute object[] robj;
attribute object[] _object;
};
interface TestAttrNullableArray {
attribute byte[]? b;
readonly attribute byte[]? rb;
attribute octet[]? o;
readonly attribute octet[]? ro;
attribute short[]? s;
readonly attribute short[]? rs;
attribute unsigned short[]? us;
readonly attribute unsigned short[]? rus;
attribute long[]? l;
readonly attribute long[]? rl;
attribute unsigned long[]? ul;
readonly attribute unsigned long[]? rul;
attribute long long[]? ll;
readonly attribute long long[]? rll;
attribute unsigned long long[]? ull;
readonly attribute unsigned long long[]? rull;
attribute DOMString[]? str;
readonly attribute DOMString[]? rstr;
attribute object[]? obj;
readonly attribute object[]? robj;
attribute object[]? _object;
};
interface TestAttrArrayOfNullableTypes {
attribute byte?[] b;
readonly attribute byte?[] rb;
attribute octet?[] o;
readonly attribute octet?[] ro;
attribute short?[] s;
readonly attribute short?[] rs;
attribute unsigned short?[] us;
readonly attribute unsigned short?[] rus;
attribute long?[] l;
readonly attribute long?[] rl;
attribute unsigned long?[] ul;
readonly attribute unsigned long?[] rul;
attribute long long?[] ll;
readonly attribute long long?[] rll;
attribute unsigned long long?[] ull;
readonly attribute unsigned long long?[] rull;
attribute DOMString?[] str;
readonly attribute DOMString?[] rstr;
attribute object?[] obj;
readonly attribute object?[] robj;
attribute object?[] _object;
};
interface TestAttrNullableArrayOfNullableTypes {
attribute byte?[]? b;
readonly attribute byte?[]? rb;
attribute octet?[]? o;
readonly attribute octet?[]? ro;
attribute short?[]? s;
readonly attribute short?[]? rs;
attribute unsigned short?[]? us;
readonly attribute unsigned short?[]? rus;
attribute long?[]? l;
readonly attribute long?[]? rl;
attribute unsigned long?[]? ul;
readonly attribute unsigned long?[]? rul;
attribute long long?[]? ll;
readonly attribute long long?[]? rll;
attribute unsigned long long?[]? ull;
readonly attribute unsigned long long?[]? rull;
attribute DOMString?[]? str;
readonly attribute DOMString?[]? rstr;
attribute object?[]? obj;
readonly attribute object?[]? robj;
attribute object?[]? _object;
};
""")
results = parser.finish()
def checkAttr(attr, QName, name, type, readonly):
harness.ok(isinstance(attr, WebIDL.IDLAttribute),
"Should be an IDLAttribute")
harness.ok(attr.isAttr(), "Attr is an Attr")
harness.ok(not attr.isMethod(), "Attr is not an method")
harness.ok(not attr.isConst(), "Attr is not a const")
harness.check(attr.identifier.QName(), QName, "Attr has the right QName")
harness.check(attr.identifier.name, name, "Attr has the right name")
harness.check(str(attr.type), type, "Attr has the right type")
harness.check(attr.readonly, readonly, "Attr's readonly state is correct")
harness.ok(True, "TestAttr interface parsed without error.")
harness.check(len(results), 6, "Should be six productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttr", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttr", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "", name, type % "", readonly)
iface = results[1]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttrNullable", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttrNullable", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly)
iface = results[2]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttrArray", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttrArray", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "Array", name, type % "Array", readonly)
iface = results[3]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttrNullableArray", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttrNullableArray", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "NullableArray", name, type % "ArrayOrNull", readonly)
iface = results[4]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttrArrayOfNullableTypes", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttrArrayOfNullableTypes", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "ArrayOfNullableTypes", name, type % "OrNullArray", readonly)
iface = results[5]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttrNullableArrayOfNullableTypes", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttrNullableArrayOfNullableTypes", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "NullableArrayOfNullableTypes", name, type % "OrNullArrayOrNull", readonly)

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface AttrSquenceType {
attribute sequence<bool> foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,41 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestBuiltins {
attribute boolean b;
attribute byte s8;
attribute octet u8;
attribute short s16;
attribute unsigned short u16;
attribute long s32;
attribute unsigned long u32;
attribute long long s64;
attribute unsigned long long u64;
attribute DOMTimeStamp ts;
};
""")
results = parser.finish()
harness.ok(True, "TestBuiltins interface parsed without error.")
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
iface = results[0]
harness.check(iface.identifier.QName(), "::TestBuiltins", "Interface has the right QName")
harness.check(iface.identifier.name, "TestBuiltins", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
members = iface.members
harness.check(len(members), 10, "Should be one production")
names = ["b", "s8", "u8", "s16", "u16", "s32", "u32", "s64", "u64", "ts"]
types = ["Boolean", "Byte", "Octet", "Short", "UnsignedShort", "Long", "UnsignedLong", "LongLong", "UnsignedLongLong", "DOMTimeStamp"]
for i in range(10):
attr = members[i]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
harness.check(attr.identifier.QName(), "::TestBuiltins::" + names[i], "Attr has correct QName")
harness.check(attr.identifier.name, names[i], "Attr has correct name")
harness.check(str(attr.type), types[i], "Attr type is the correct name")
harness.ok(attr.type.isPrimitive(), "Should be a primitive type")

View File

@ -0,0 +1,34 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestCallback {
attribute CallbackType? listener;
};
callback CallbackType = boolean (unsigned long arg);
""")
results = parser.finish()
harness.ok(True, "TestCallback interface parsed without error.")
harness.check(len(results), 2, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestCallback", "Interface has the right QName")
harness.check(iface.identifier.name, "TestCallback", "Interface has the right name")
harness.check(len(iface.members), 1, "Expect %s members" % 1)
attr = iface.members[0]
harness.ok(isinstance(attr, WebIDL.IDLAttribute),
"Should be an IDLAttribute")
harness.ok(attr.isAttr(), "Should be an attribute")
harness.ok(not attr.isMethod(), "Attr is not an method")
harness.ok(not attr.isConst(), "Attr is not a const")
harness.check(attr.identifier.QName(), "::TestCallback::listener", "Attr has the right QName")
harness.check(attr.identifier.name, "listener", "Attr has the right name")
t = attr.type
harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type")
harness.ok(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type")
harness.ok(t.isCallback(), "Attr has the right type")

View File

@ -0,0 +1,14 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
callback interface TestCallbackInterface {
attribute boolean bool;
};
""")
results = parser.finish()
iface = results[0]
harness.ok(iface.isCallback(), "Interface should be a callback")

View File

@ -0,0 +1,64 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestConsts {
const byte zero = 0;
const byte b = -1;
const octet o = 2;
const short s = -3;
const unsigned short us = 0x4;
const long l = -0X5;
const unsigned long ul = 6;
const unsigned long long ull = 7;
const long long ll = -010;
const boolean t = true;
const boolean f = false;
const boolean? n = null;
const boolean? nt = true;
const boolean? nf = false;
};
""")
results = parser.finish()
harness.ok(True, "TestConsts interface parsed without error.")
harness.check(len(results), 1, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName")
harness.check(iface.identifier.name, "TestConsts", "Interface has the right name")
harness.check(len(iface.members), 14, "Expect 14 members")
consts = iface.members
def checkConst(const, QName, name, type, value):
harness.ok(isinstance(const, WebIDL.IDLConst),
"Should be an IDLConst")
harness.ok(const.isConst(), "Const is a const")
harness.ok(not const.isAttr(), "Const is not an attr")
harness.ok(not const.isMethod(), "Const is not a method")
harness.check(const.identifier.QName(), QName, "Const has the right QName")
harness.check(const.identifier.name, name, "Const has the right name")
harness.check(str(const.type), type, "Const has the right type")
harness.ok(const.type.isPrimitive(), "All consts should be primitive")
harness.check(str(const.value.type), str(const.type),
"Const's value has the same type as the type")
harness.check(const.value.value, value, "Const value has the right value.")
checkConst(consts[0], "::TestConsts::zero", "zero", "Byte", 0)
checkConst(consts[1], "::TestConsts::b", "b", "Byte", -1)
checkConst(consts[2], "::TestConsts::o", "o", "Octet", 2)
checkConst(consts[3], "::TestConsts::s", "s", "Short", -3)
checkConst(consts[4], "::TestConsts::us", "us", "UnsignedShort", 4)
checkConst(consts[5], "::TestConsts::l", "l", "Long", -5)
checkConst(consts[6], "::TestConsts::ul", "ul", "UnsignedLong", 6)
checkConst(consts[7], "::TestConsts::ull", "ull", "UnsignedLongLong", 7)
checkConst(consts[8], "::TestConsts::ll", "ll", "LongLong", -8)
checkConst(consts[9], "::TestConsts::t", "t", "Boolean", True)
checkConst(consts[10], "::TestConsts::f", "f", "Boolean", False)
checkConst(consts[11], "::TestConsts::n", "n", "BooleanOrNull", None)
checkConst(consts[12], "::TestConsts::nt", "nt", "BooleanOrNull", True)
checkConst(consts[13], "::TestConsts::nf", "nf", "BooleanOrNull", False)

View File

@ -0,0 +1,75 @@
import WebIDL
def WebIDLTest(parser, harness):
def checkArgument(argument, QName, name, type, optional, variadic):
harness.ok(isinstance(argument, WebIDL.IDLArgument),
"Should be an IDLArgument")
harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
harness.check(argument.identifier.name, name, "Argument has the right name")
harness.check(str(argument.type), type, "Argument has the right return type")
harness.check(argument.optional, optional, "Argument has the right optional value")
harness.check(argument.variadic, variadic, "Argument has the right variadic value")
def checkMethod(method, QName, name, signatures,
static=False, getter=False, setter=False, creator=False,
deleter=False, legacycaller=False, stringifier=False):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.ok(method.isMethod(), "Method is a method")
harness.ok(not method.isAttr(), "Method is not an attr")
harness.ok(not method.isConst(), "Method is not a const")
harness.check(method.identifier.QName(), QName, "Method has the right QName")
harness.check(method.identifier.name, name, "Method has the right name")
harness.check(method.isStatic(), static, "Method has the correct static value")
harness.check(method.isGetter(), getter, "Method has the correct getter value")
harness.check(method.isSetter(), setter, "Method has the correct setter value")
harness.check(method.isCreator(), creator, "Method has the correct creator value")
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
sigpairs = zip(method.signatures(), signatures)
for (gotSignature, expectedSignature) in sigpairs:
(gotRetType, gotArgs) = gotSignature
(expectedRetType, expectedArgs) = expectedSignature
harness.check(str(gotRetType), expectedRetType,
"Method has the expected return type.")
for i in range(0, len(gotArgs)):
(QName, name, type, optional, variadic) = expectedArgs[i]
checkArgument(gotArgs[i], QName, name, type, optional, variadic)
parser.parse("""
[Constructor]
interface TestConstructorNoArgs {
};
[Constructor(DOMString name)]
interface TestConstructorWithArgs {
};
[Constructor(object foo), Constructor(boolean bar)]
interface TestConstructorOverloads {
};
""")
results = parser.finish()
harness.check(len(results), 3, "Should be two productions")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
checkMethod(results[0].ctor(), "::TestConstructorNoArgs::constructor",
"constructor", [("TestConstructorNoArgs", [])])
checkMethod(results[1].ctor(), "::TestConstructorWithArgs::constructor",
"constructor",
[("TestConstructorWithArgs",
[("::TestConstructorWithArgs::constructor::name", "name", "String", False, False)])])
checkMethod(results[2].ctor(), "::TestConstructorOverloads::constructor",
"constructor",
[("TestConstructorOverloads",
[("::TestConstructorOverloads::constructor::foo", "foo", "Object", False, False)]),
("TestConstructorOverloads",
[("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])])

View File

@ -0,0 +1,28 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
[Constructor, NoInterfaceObject]
interface TestConstructorNoInterfaceObject {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
[NoInterfaceObject, Constructor]
interface TestConstructorNoInterfaceObject {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface DoubleNull {
attribute byte?? foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,84 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface DuplicateQualifiers1 {
getter getter byte foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers2 {
setter setter byte foo(unsigned long index, byte value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers3 {
creator creator byte foo(unsigned long index, byte value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers4 {
deleter deleter byte foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers5 {
getter deleter getter byte foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
results = parser.parse("""
interface DuplicateQualifiers6 {
creator setter creator byte foo(unsigned long index, byte value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,14 @@
import WebIDL
def WebIDLTest(parser, harness):
try:
parser.parse("""
enum TestEmptyEnum {
};
""")
harness.ok(False, "Should have thrown!")
except:
harness.ok(True, "Parsing TestEmptyEnum enum should fail")
results = parser.finish()

View File

@ -0,0 +1,61 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
enum TestEnum {
"",
"foo",
"bar"
};
interface TestEnumInterface {
TestEnum doFoo(boolean arg);
readonly attribute TestEnum foo;
};
""")
results = parser.finish()
harness.ok(True, "TestEnumInterfaces interface parsed without error.")
harness.check(len(results), 2, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLEnum),
"Should be an IDLEnum")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
enum = results[0]
harness.check(enum.identifier.QName(), "::TestEnum", "Enum has the right QName")
harness.check(enum.identifier.name, "TestEnum", "Enum has the right name")
harness.check(enum.values(), ["", "foo", "bar"], "Enum has the right values")
iface = results[1]
harness.check(iface.identifier.QName(), "::TestEnumInterface", "Interface has the right QName")
harness.check(iface.identifier.name, "TestEnumInterface", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
members = iface.members
harness.check(len(members), 2, "Should be one production")
harness.ok(isinstance(members[0], WebIDL.IDLMethod),
"Should be an IDLMethod")
method = members[0]
harness.check(method.identifier.QName(), "::TestEnumInterface::doFoo",
"Method has correct QName")
harness.check(method.identifier.name, "doFoo", "Method has correct name")
signatures = method.signatures()
harness.check(len(signatures), 1, "Expect one signature")
(returnType, arguments) = signatures[0]
harness.check(str(returnType), "TestEnum", "Method type is the correct name")
harness.check(len(arguments), 1, "Method has the right number of arguments")
arg = arguments[0]
harness.ok(isinstance(arg, WebIDL.IDLArgument), "Should be an IDLArgument")
harness.check(str(arg.type), "Boolean", "Argument has the right type")
attr = members[1]
harness.check(attr.identifier.QName(), "::TestEnumInterface::foo",
"Attr has correct QName")
harness.check(attr.identifier.name, "foo", "Attr has correct name")
harness.check(str(attr.type), "TestEnum", "Attr type is the correct name")

View File

@ -0,0 +1,13 @@
import WebIDL
def WebIDLTest(parser, harness):
try:
parser.parse("""
enum TestEnumDuplicateValue {
"",
""
};
""")
harness.ok(False, "Should have thrown!")
except:
harness.ok(True, "Enum TestEnumDuplicateValue should throw")

View File

@ -0,0 +1,11 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
[Flippety]
interface TestExtendedAttr {
[Foopy] attribute byte b;
};
""")
results = parser.finish()

View File

@ -0,0 +1,15 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface ForwardDeclared;
interface ForwardDeclared;
interface TestForwardDecl {
attribute ForwardDeclared foo;
};
""")
results = parser.finish()
harness.ok(True, "TestForwardDeclared interface parsed without error.")

View File

@ -0,0 +1,18 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestIncompleteParent : NotYetDefined {
void foo();
};
interface NotYetDefined : EvenHigherOnTheChain {
};
interface EvenHigherOnTheChain {
};
""")
parser.finish()
harness.ok(True, "TestIncompleteParent interface parsed without error.")

View File

@ -0,0 +1,44 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestIncompleteTypes {
attribute FooInterface attr1;
FooInterface method1(FooInterface arg);
};
interface FooInterface {
};
""")
results = parser.finish()
harness.ok(True, "TestIncompleteTypes interface parsed without error.")
harness.check(len(results), 2, "Should be two productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestIncompleteTypes", "Interface has the right QName")
harness.check(iface.identifier.name, "TestIncompleteTypes", "Interface has the right name")
harness.check(len(iface.members), 2, "Expect 2 members")
attr = iface.members[0]
harness.ok(isinstance(attr, WebIDL.IDLAttribute),
"Should be an IDLAttribute")
method = iface.members[1]
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.check(attr.identifier.QName(), "::TestIncompleteTypes::attr1",
"Attribute has the right QName")
harness.check(attr.type.name.QName(), "::FooInterface",
"Previously unresolved type has the right name")
harness.check(method.identifier.QName(), "::TestIncompleteTypes::method1",
"Attribute has the right QName")
(returnType, args) = method.signatures()[0]
harness.check(returnType.name.QName(), "::FooInterface",
"Previously unresolved type has the right name")
harness.check(args[0].type.name.QName(), "::FooInterface",
"Previously unresolved type has the right name")

View File

@ -0,0 +1,54 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("interface Foo { };")
results = parser.finish()
harness.ok(True, "Empty interface parsed without error.")
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
iface = results[0]
harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName")
harness.check(iface.identifier.name, "Foo", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
parser.parse("interface Bar : Foo { };")
results = parser.finish()
harness.ok(True, "Empty interface parsed without error.")
harness.check(len(results), 2, "Should be two productions")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
iface = results[1]
harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName")
harness.check(iface.identifier.name, "Bar", "Interface has the right name")
harness.ok(isinstance(iface.parent, WebIDL.IDLInterface),
"Interface has a parent")
parser = parser.reset()
parser.parse("""
interface QNameBase {
attribute long foo;
};
interface QNameDerived : QNameBase {
attribute long long foo;
attribute byte bar;
};
""")
results = parser.finish()
harness.check(len(results), 2, "Should be two productions")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(results[1].parent, results[0], "Inheritance chain is right")
harness.check(len(results[0].members), 1, "Expect 1 productions")
harness.check(len(results[1].members), 2, "Expect 2 productions")
base = results[0]
derived = results[1]
harness.check(base.members[0].identifier.QName(), "::QNameBase::foo",
"Member has the right QName")
harness.check(derived.members[0].identifier.QName(), "::QNameDerived::foo",
"Member has the right QName")
harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar",
"Member has the right QName")

View File

@ -0,0 +1,15 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface IdentifierConflict {
const byte thing1 = 1;
const unsigned long thing1 = 1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,60 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers1 {
const byte thing1 = 1;
readonly attribute long thing1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers2 {
readonly attribute long thing1;
const byte thing1 = 1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers3 {
getter boolean thing1(DOMString name);
readonly attribute long thing1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers1 {
const byte thing1 = 1;
long thing1();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,114 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestMethods {
void basic();
static void basicStatic();
void basicWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
boolean basicBoolean();
static boolean basicStaticBoolean();
boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
void optionalArg(optional byte? arg1, optional sequence<byte> arg2);
void variadicArg(byte?... arg1);
void crazyTypes(sequence<long?[]>? arg1, boolean?[][]? arg2);
object getObject();
void setObject(object arg1);
void setAny(any arg1);
};
""")
results = parser.finish()
harness.ok(True, "TestMethods interface parsed without error.")
harness.check(len(results), 1, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName")
harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
harness.check(len(iface.members), 12, "Expect 12 members")
methods = iface.members
def checkArgument(argument, QName, name, type, optional, variadic):
harness.ok(isinstance(argument, WebIDL.IDLArgument),
"Should be an IDLArgument")
harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
harness.check(argument.identifier.name, name, "Argument has the right name")
harness.check(str(argument.type), type, "Argument has the right return type")
harness.check(argument.optional, optional, "Argument has the right optional value")
harness.check(argument.variadic, variadic, "Argument has the right variadic value")
def checkMethod(method, QName, name, signatures,
static=False, getter=False, setter=False, creator=False,
deleter=False, legacycaller=False, stringifier=False):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.ok(method.isMethod(), "Method is a method")
harness.ok(not method.isAttr(), "Method is not an attr")
harness.ok(not method.isConst(), "Method is not a const")
harness.check(method.identifier.QName(), QName, "Method has the right QName")
harness.check(method.identifier.name, name, "Method has the right name")
harness.check(method.isStatic(), static, "Method has the correct static value")
harness.check(method.isGetter(), getter, "Method has the correct getter value")
harness.check(method.isSetter(), setter, "Method has the correct setter value")
harness.check(method.isCreator(), creator, "Method has the correct creator value")
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
sigpairs = zip(method.signatures(), signatures)
for (gotSignature, expectedSignature) in sigpairs:
(gotRetType, gotArgs) = gotSignature
(expectedRetType, expectedArgs) = expectedSignature
harness.check(str(gotRetType), expectedRetType,
"Method has the expected return type.")
for i in range(0, len(gotArgs)):
(QName, name, type, optional, variadic) = expectedArgs[i]
checkArgument(gotArgs[i], QName, name, type, optional, variadic)
checkMethod(methods[0], "::TestMethods::basic", "basic", [("Void", [])])
checkMethod(methods[1], "::TestMethods::basicStatic", "basicStatic",
[("Void", [])], static=True)
checkMethod(methods[2], "::TestMethods::basicWithSimpleArgs",
"basicWithSimpleArgs",
[("Void",
[("::TestMethods::basicWithSimpleArgs::arg1", "arg1", "Boolean", False, False),
("::TestMethods::basicWithSimpleArgs::arg2", "arg2", "Byte", False, False),
("::TestMethods::basicWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])])
checkMethod(methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])])
checkMethod(methods[4], "::TestMethods::basicStaticBoolean", "basicStaticBoolean", [("Boolean", [])], static=True)
checkMethod(methods[5], "::TestMethods::basicBooleanWithSimpleArgs",
"basicBooleanWithSimpleArgs",
[("Boolean",
[("::TestMethods::basicBooleanWithSimpleArgs::arg1", "arg1", "Boolean", False, False),
("::TestMethods::basicBooleanWithSimpleArgs::arg2", "arg2", "Byte", False, False),
("::TestMethods::basicBooleanWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])])
checkMethod(methods[6], "::TestMethods::optionalArg",
"optionalArg",
[("Void",
[("::TestMethods::optionalArg::arg1", "arg1", "ByteOrNull", True, False),
("::TestMethods::optionalArg::arg2", "arg2", "ByteSequence", True, False)])])
checkMethod(methods[7], "::TestMethods::variadicArg",
"variadicArg",
[("Void",
[("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])])
checkMethod(methods[8], "::TestMethods::crazyTypes",
"crazyTypes",
[("Void",
[("::TestMethods::crazyTypes::arg1", "arg1", "LongOrNullArraySequenceOrNull", False, False),
("::TestMethods::crazyTypes::arg2", "arg2", "BooleanOrNullArrayArrayOrNull", False, False)])])
checkMethod(methods[9], "::TestMethods::getObject",
"getObject", [("Object", [])])
checkMethod(methods[10], "::TestMethods::setObject",
"setObject",
[("Void",
[("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])])
checkMethod(methods[11], "::TestMethods::setAny",
"setAny",
[("Void",
[("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface NullableVoid {
void? foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface OptionalConstraints1 {
void foo(optional byte arg1, byte arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,47 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestOverloads {
void basic();
void basic(long arg1);
boolean abitharder(unsigned long foo);
boolean abitharder(boolean foo);
void abitharder(long? foo);
};
""")
results = parser.finish()
harness.ok(True, "TestOverloads interface parsed without error.")
harness.check(len(results), 1, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
harness.check(len(iface.members), 2, "Expect %s members" % 2)
member = iface.members[0]
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
harness.check(member.identifier.name, "basic", "Method has the right name")
harness.check(member.hasOverloads(), True, "Method has overloads")
signatures = member.signatures()
harness.check(len(signatures), 2, "Method should have 2 signatures")
(retval, argumentSet) = signatures[0]
harness.check(str(retval), "Void", "Expect a void retval")
harness.check(len(argumentSet), 0, "Expect an empty argument set")
(retval, argumentSet) = signatures[1]
harness.check(str(retval), "Void", "Expect a void retval")
harness.check(len(argumentSet), 1, "Expect an argument set with one argument")
argument = argumentSet[0]
harness.ok(isinstance(argument, WebIDL.IDLArgument),
"Should be an IDLArgument")
harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
harness.check(argument.identifier.name, "arg1", "Argument has the right name")
harness.check(str(argument.type), "Long", "Argument has the right type")

View File

@ -0,0 +1,7 @@
def WebIDLTest(parser, harness):
parser.parse("")
parser.finish()
harness.ok(True, "Parsing nothing doesn't throw.")
parser.parse("interface Foo {};")
parser.finish()
harness.ok(True, "Parsing a silly interface doesn't throw.")

View File

@ -0,0 +1,364 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch1 {
getter long long foo(long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch2 {
getter void foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch3 {
getter boolean foo(unsigned long index, boolean extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch4 {
getter boolean foo(unsigned long... index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch5 {
getter boolean foo(optional unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch6 {
getter boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch7 {
deleter long long foo(long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch8 {
deleter void foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch9 {
deleter boolean foo(unsigned long index, boolean extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch10 {
deleter boolean foo(unsigned long... index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch11 {
deleter boolean foo(optional unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch12 {
deleter boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch13 {
setter long long foo(long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch14 {
setter void foo(unsigned long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch15 {
setter boolean foo(unsigned long index, boolean value, long long extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch16 {
setter boolean foo(unsigned long index, boolean... value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch17 {
setter boolean foo(unsigned long index, optional boolean value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch18 {
setter boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch19 {
setter boolean foo(unsigned long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch20 {
creator long long foo(long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch21 {
creator void foo(unsigned long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch22 {
creator boolean foo(unsigned long index, boolean value, long long extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch23 {
creator boolean foo(unsigned long index, boolean... value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch24 {
creator boolean foo(unsigned long index, optional boolean value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch25 {
creator boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch26 {
creator boolean foo(unsigned long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,73 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface SpecialMethods {
getter long long (unsigned long index);
setter long long (unsigned long index, long long value);
creator long long (unsigned long index, long long value);
deleter long long (unsigned long index);
getter boolean (DOMString name);
setter boolean (DOMString name, boolean value);
creator boolean (DOMString name, boolean value);
deleter boolean (DOMString name);
};
interface SpecialMethodsCombination {
getter deleter long long (unsigned long index);
setter creator long long (unsigned long index, long long value);
getter deleter boolean (DOMString name);
setter creator boolean (DOMString name, boolean value);
};
""")
results = parser.finish()
def checkMethod(method, QName, name,
static=False, getter=False, setter=False, creator=False,
deleter=False, legacycaller=False, stringifier=False):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.check(method.identifier.QName(), QName, "Method has the right QName")
harness.check(method.identifier.name, name, "Method has the right name")
harness.check(method.isStatic(), static, "Method has the correct static value")
harness.check(method.isGetter(), getter, "Method has the correct getter value")
harness.check(method.isSetter(), setter, "Method has the correct setter value")
harness.check(method.isCreator(), creator, "Method has the correct creator value")
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
harness.check(len(results), 2, "Expect 2 interfaces")
iface = results[0]
harness.check(len(iface.members), 8, "Expect 8 members")
checkMethod(iface.members[0], "::SpecialMethods::__indexedgetter", "__indexedgetter",
getter=True)
checkMethod(iface.members[1], "::SpecialMethods::__indexedsetter", "__indexedsetter",
setter=True)
checkMethod(iface.members[2], "::SpecialMethods::__indexedcreator", "__indexedcreator",
creator=True)
checkMethod(iface.members[3], "::SpecialMethods::__indexeddeleter", "__indexeddeleter",
deleter=True)
checkMethod(iface.members[4], "::SpecialMethods::__namedgetter", "__namedgetter",
getter=True)
checkMethod(iface.members[5], "::SpecialMethods::__namedsetter", "__namedsetter",
setter=True)
checkMethod(iface.members[6], "::SpecialMethods::__namedcreator", "__namedcreator",
creator=True)
checkMethod(iface.members[7], "::SpecialMethods::__nameddeleter", "__nameddeleter",
deleter=True)
iface = results[1]
harness.check(len(iface.members), 4, "Expect 4 members")
checkMethod(iface.members[0], "::SpecialMethodsCombination::__indexedgetterdeleter",
"__indexedgetterdeleter", getter=True, deleter=True)
checkMethod(iface.members[1], "::SpecialMethodsCombination::__indexedsettercreator",
"__indexedsettercreator", setter=True, creator=True)
checkMethod(iface.members[2], "::SpecialMethodsCombination::__namedgetterdeleter",
"__namedgetterdeleter", getter=True, deleter=True)
checkMethod(iface.members[3], "::SpecialMethodsCombination::__namedsettercreator",
"__namedsettercreator", setter=True, creator=True)

View File

@ -0,0 +1,62 @@
import WebIDL
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
getter deleter boolean (DOMString name);
getter boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
deleter boolean (DOMString name);
getter deleter boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
setter creator boolean (DOMString name);
creator boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
setter boolean (DOMString name);
creator setter boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,56 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
callback Function = any(any... arguments);
interface TestTreatNonCallableAsNull1 {
[TreatNonCallableAsNull] attribute Function? onfoo;
attribute Function? onbar;
};
""")
results = parser.finish()
iface = results[1]
attr = iface.members[0]
harness.check(attr.type.treatNonCallableAsNull(), True, "Got the expected value")
attr = iface.members[1]
harness.check(attr.type.treatNonCallableAsNull(), False, "Got the expected value")
parser = parser.reset()
threw = False
try:
parser.parse("""
callback Function = any(any... arguments);
interface TestTreatNonCallableAsNull2 {
[TreatNonCallableAsNull] attribute Function onfoo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
callback Function = any(any... arguments);
[TreatNonCallableAsNull]
interface TestTreatNonCallableAsNull3 {
attribute Function onfoo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,10 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
callback TestVariadicCallback = any(any... arguments);
""")
results = parser.finish()
harness.ok(True, "TestVariadicCallback callback parsed without error.")

View File

@ -0,0 +1,39 @@
def WebIDLTest(parser, harness):
threw = False
try:
results = parser.parse("""
interface VariadicConstraints1 {
void foo(byte... arg1, byte arg2);
};
""")
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
results = parser.parse("""
interface VariadicConstraints2 {
void foo(byte... arg1, optional byte arg2);
};
""")
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
results = parser.parse("""
interface VariadicConstraints3 {
void foo(optional byte... arg1);
};
""")
except:
threw = True
harness.ok(threw, "Should have thrown.")

View File

@ -0,0 +1,19 @@
# 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/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = dom/bindings/test
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_lookupGetter.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

View File

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=462428
-->
<head>
<title>Test for Bug 462428</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462428">Mozilla Bug 462428</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 462428 **/
var x = new XMLHttpRequest;
x.open("GET", "");
var getter = x.__lookupGetter__('readyState');
ok(getter !== undefined, "But able to look it up the normal way");
ok(!x.hasOwnProperty('readyState'), "property should still be on the prototype");
var sawProp = false;
for (var i in x) {
if (i === "readyState") {
sawProp = true;
}
}
ok(sawProp, "property should be enumerable");
is(getter.call(x), 1, "the getter actually works");
Object.getPrototypeOf(x).__defineSetter__('readyState', function() {});
is(getter.call(x), 1, "the getter works after defineSetter");
is(x.responseType, "", "Should have correct responseType up front");
var setter = x.__lookupSetter__('responseType');
setter.call(x, "document");
is(x.responseType, "document", "the setter is bound correctly");
</script>
</pre>
</body>
</html>

View File

@ -41,6 +41,9 @@
%{C++
#include "nsEvent.h"
#include "mozilla/dom/bindings/Nullable.h"
using mozilla::dom::bindings::Nullable;
class nsPresContext;
class nsEventChainPreVisitor;

View File

@ -74,6 +74,7 @@ _TEST_FILES = \
test_focus_docnav.xul \
window_focus_docnav.xul \
test_clonewrapper.xul \
test_moving_nodeList.xul \
$(NULL)
ifeq (WINNT,$(OS_ARCH))

View File

@ -0,0 +1,44 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=684115
-->
<window title="Mozilla Bug 684115"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=654370"
target="_blank">Mozilla Bug 684115</a>
</body>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
var firstWindow, secondWindow;
function iframe_loaded() {
if (!firstWindow || !secondWindow)
return;
var nodeList = firstWindow.document.childNodes;
ok(!("expando" in nodeList), "shouldn't be able to see expandos on the NodeList");
nodeList = firstWindow.wrappedJSObject.getNodeList();
ok(("expando" in nodeList), "should be able to see expandos on the NodeList");
is(nodeList.selectedIndex, -1, "can access selectedIndex in chrome");
secondWindow.wrappedJSObject.tryToUseNodeList(nodeList, ok);
nodeList = document.createElementNS("http://www.w3.org/1999/xhtml", "select").options;
secondWindow.wrappedJSObject.tryToUseNodeList(nodeList, ok);
SimpleTest.finish();
}
]]></script>
<iframe id="one" src="http://mochi.test:8888/tests/dom/tests/mochitest/general/file_moving_nodeList.html"
onload="firstWindow = this.contentWindow; iframe_loaded()" />
<iframe id="two" src="http://example.org/tests/dom/tests/mochitest/general/file_moving_nodeList.html"
onload="secondWindow = this.contentWindow; iframe_loaded()" />
</window>

View File

@ -3,9 +3,9 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=654370
https://bugzilla.mozilla.org/show_bug.cgi?id=684115
-->
<window title="Mozilla Bug 654370"
<window title="Mozilla Bug 684115"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
@ -13,7 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=654370
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=654370"
target="_blank">Mozilla Bug 654370</a>
target="_blank">Mozilla Bug 684115</a>
</body>
<!-- test code goes here -->
@ -25,7 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=654370
if (!firstWindow || !secondWindow)
return;
var xhr = firstWindow.wrappedJSObject.createXHR();
ok(!("expando" in xhr), "shouldn't be able to see expandos on the XHR");
ok(("expando" in xhr), "should be able to see expandos on the XHR");
is(xhr.readyState, XMLHttpRequest.UNSENT, "can access readyState in chrome");
secondWindow.wrappedJSObject.tryToUseXHR(xhr, ok);
secondWindow.wrappedJSObject.tryToUseXHR(new XMLHttpRequest(), ok);

View File

@ -75,6 +75,7 @@ _TEST_FILES = \
test_for_of.html \
test_focus_legend_noparent.html \
file_clonewrapper.html \
file_moving_nodeList.html \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,30 @@
<html>
<head>
<script>
document.childNodes.expando = "foo";
function getNodeList() {
var nodeList = document.createElement("select").options;
nodeList.expando = "foo";
return nodeList;
}
function tryToUseNodeList(nodeList, ok) {
function expectException(op, reason) {
try {
var result = op();
ok(false, "should have thrown an exception, got: " + result);
} catch (e) {
ok(/Permission denied/.test(e.toString()), reason);
}
}
expectException(function() { nodeList.length = 2; }, "should not be able to set attributes");
expectException(function() { nodeList.item(0); }, "should not have access to any functions");
expectException(function() { nodeList.foo = "foo"; }, "should not be able to add expandos");
}
</script>
</head>
<body>
</body>
</html>

View File

@ -2,7 +2,9 @@
<head>
<script>
function createXHR() {
return new XMLHttpRequest();
var xhr = new XMLHttpRequest();
xhr.expando = "foo";
return xhr;
}
function tryToUseXHR(xhr, ok) {

View File

@ -0,0 +1,15 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Constructor]
interface AnonXMLHttpRequest : XMLHttpRequest {
};

20
dom/webidl/Attr.webidl Normal file
View File

@ -0,0 +1,20 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Attr {
readonly attribute DOMString name;
attribute DOMString value;
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
};

View File

@ -0,0 +1,27 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface CharacterData : Node {
[TreatNullAs=EmptyString] attribute DOMString data;
readonly attribute unsigned long length;
DOMString substringData(unsigned long offset, unsigned long count);
void appendData(DOMString data);
void insertData(unsigned long offset, DOMString data);
void deleteData(unsigned long offset, unsigned long count);
void replaceData(unsigned long offset, unsigned long count, DOMString data);
// NEW
void before((Node or DOMString)... nodes);
void after((Node or DOMString)... nodes);
void replace((Node or DOMString)... nodes);
void remove();
};

14
dom/webidl/Comment.webidl Normal file
View File

@ -0,0 +1,14 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Comment : CharacterData {
};

View File

@ -0,0 +1,20 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Constructor(DOMString type, optional CustomEventInit eventInitDict)]
interface CustomEvent : Event {
readonly attribute any detail;
};
dictionary CustomEventInit : EventInit {
any detail;
};

View File

@ -0,0 +1,15 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DOMError {
readonly attribute DOMString name;
};

View File

@ -0,0 +1,22 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DOMImplementation {
boolean hasFeature(DOMString feature,
[TreatNullAs=EmptyString] DOMString version);
DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId,
DOMString systemId);
XMLDocument createDocument(DOMString? namespace, DOMString qualifiedName,
DocumentType? doctype);
Document createHTMLDocument(DOMString title);
};

View File

@ -0,0 +1,15 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DOMSettableTokenList : DOMTokenList {
attribute DOMString value;
};

View File

@ -0,0 +1,17 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DOMStringList {
readonly attribute unsigned long length;
getter DOMString? item(unsigned long index);
boolean contains(DOMString string);
};

View File

@ -0,0 +1,21 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DOMTokenList {
readonly attribute unsigned long length;
getter DOMString? item(unsigned long index);
boolean contains(DOMString token);
void add(DOMString token);
void remove(DOMString token);
boolean toggle(DOMString token);
stringifier DOMString ();
};

View File

@ -0,0 +1,50 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Document : Node {
readonly attribute DOMImplementation implementation;
readonly attribute DOMString URL;
readonly attribute DOMString documentURI;
readonly attribute DOMString compatMode;
readonly attribute DOMString characterSet;
readonly attribute DOMString contentType;
readonly attribute DocumentType? doctype;
readonly attribute Element? documentElement;
NodeList getElementsByTagName(DOMString qualifiedName);
NodeList getElementsByTagNameNS(DOMString? namespace, DOMString localName);
NodeList getElementsByClassName(DOMString classNames);
Element? getElementById(DOMString elementId);
Element createElement(DOMString localName);
Element createElementNS(DOMString? namespace, DOMString qualifiedName);
DocumentFragment createDocumentFragment();
Text createTextNode(DOMString data);
Comment createComment(DOMString data);
ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
Node importNode(Node node, optional boolean deep);
Node adoptNode(Node node);
Event createEvent(DOMString eventInterfaceName);
Range createRange();
NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow, optional NodeFilter? filter);
TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow, optional NodeFilter? filter);
// NEW
void prepend((Node or DOMString)... nodes);
void append((Node or DOMString)... nodes);
};
interface XMLDocument : Document {};

View File

@ -0,0 +1,17 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DocumentFragment : Node {
// NEW
void prepend((Node or DOMString)... nodes);
void append((Node or DOMString)... nodes);
};

View File

@ -0,0 +1,23 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DocumentType : Node {
readonly attribute DOMString name;
readonly attribute DOMString publicId;
readonly attribute DOMString systemId;
// NEW
void before((Node or DOMString)... nodes);
void after((Node or DOMString)... nodes);
void replace((Node or DOMString)... nodes);
void remove();
};

51
dom/webidl/Element.webidl Normal file
View File

@ -0,0 +1,51 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Element : Node {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
readonly attribute DOMString tagName;
attribute DOMString id;
attribute DOMString className;
readonly attribute DOMTokenList classList;
readonly attribute Attr[] attributes;
DOMString? getAttribute(DOMString name);
DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
void setAttribute(DOMString name, DOMString value);
void setAttributeNS(DOMString? namespace, DOMString name, DOMString value);
void removeAttribute(DOMString name);
void removeAttributeNS(DOMString? namespace, DOMString localName);
boolean hasAttribute(DOMString name);
boolean hasAttributeNS(DOMString? namespace, DOMString localName);
NodeList getElementsByTagName(DOMString qualifiedName);
NodeList getElementsByTagNameNS(DOMString? namespace, DOMString localName);
NodeList getElementsByClassName(DOMString classNames);
readonly attribute HTMLCollection children;
readonly attribute Element? firstElementChild;
readonly attribute Element? lastElementChild;
readonly attribute Element? previousElementSibling;
readonly attribute Element? nextElementSibling;
readonly attribute unsigned long childElementCount;
// NEW
void prepend((Node or DOMString)... nodes);
void append((Node or DOMString)... nodes);
void before((Node or DOMString)... nodes);
void after((Node or DOMString)... nodes);
void replace((Node or DOMString)... nodes);
void remove();
};

43
dom/webidl/Event.webidl Normal file
View File

@ -0,0 +1,43 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Constructor(DOMString type, optional EventInit eventInitDict)]
interface Event {
readonly attribute DOMString type;
readonly attribute EventTarget? target;
readonly attribute EventTarget? currentTarget;
const unsigned short CAPTURING_PHASE = 1;
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;
readonly attribute unsigned short eventPhase;
void stopPropagation();
void stopImmediatePropagation();
readonly attribute boolean bubbles;
readonly attribute boolean cancelable;
void preventDefault();
readonly attribute boolean defaultPrevented;
readonly attribute boolean isTrusted;
readonly attribute DOMTimeStamp timeStamp;
void initEvent(DOMString type, boolean bubbles, boolean cancelable);
};
/*
dictionary EventInit {
boolean bubbles;
boolean cancelable;
};
*/

View File

@ -0,0 +1,17 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Event;
callback interface EventListener {
void handleEvent(Event event);
};

View File

@ -0,0 +1,28 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Event;
interface EventTarget {
/* Passing null for wantsUntrusted means "default behavior", which
differs in content and chrome. In content that default boolean
value is true, while in chrome the default boolean value is
false. */
void addEventListener(DOMString type,
EventListener? listener,
optional boolean capture = false,
optional boolean? wantsUntrusted = null);
void removeEventListener(DOMString type,
EventListener? listener,
optional boolean capture = false);
boolean dispatchEvent(Event event);
};

View File

@ -0,0 +1,14 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#functiocn
*
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
* Opera Software ASA. You are granted a license to use, reproduce
* and create derivative works of this document.
*/
callback Function = any(any... arguments);

View File

@ -0,0 +1,17 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter object? namedItem(DOMString name); // only returns Element
};

64
dom/webidl/Node.webidl Normal file
View File

@ -0,0 +1,64 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface Node : EventTarget {
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2; // historical
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4; // historical
const unsigned short ENTITY_REFERENCE_NODE = 5; // historical
const unsigned short ENTITY_NODE = 6; // historical
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12; // historical
readonly attribute unsigned short nodeType;
readonly attribute DOMString nodeName;
readonly attribute DOMString? baseURI;
readonly attribute Document? ownerDocument;
readonly attribute Node? parentNode;
readonly attribute Element? parentElement;
boolean hasChildNodes();
readonly attribute NodeList childNodes;
readonly attribute Node? firstChild;
readonly attribute Node? lastChild;
readonly attribute Node? previousSibling;
readonly attribute Node? nextSibling;
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; // historical
unsigned short compareDocumentPosition(Node other);
boolean contains(Node? other);
attribute DOMString? nodeValue;
attribute DOMString? textContent;
Node insertBefore(Node node, Node? child);
Node appendChild(Node node);
Node replaceChild(Node node, Node child);
Node removeChild(Node child);
void normalize();
Node cloneNode(optional boolean deep);
boolean isEqualNode(Node? node);
DOMString lookupPrefix(DOMString? namespace);
DOMString lookupNamespaceURI(DOMString? prefix);
boolean isDefaultNamespace(DOMString? namespace);
;}

View File

@ -0,0 +1,35 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
callback interface NodeFilter {
// Constants for acceptNode()
const unsigned short FILTER_ACCEPT = 1;
const unsigned short FILTER_REJECT = 2;
const unsigned short FILTER_SKIP = 3;
// Constants for whatToShow
const unsigned long SHOW_ALL = 0xFFFFFFFF;
const unsigned long SHOW_ELEMENT = 0x1;
const unsigned long SHOW_ATTRIBUTE = 0x2; // historical
const unsigned long SHOW_TEXT = 0x4;
const unsigned long SHOW_CDATA_SECTION = 0x8; // historical
const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // historical
const unsigned long SHOW_ENTITY = 0x20; // historical
const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;
const unsigned long SHOW_COMMENT = 0x80;
const unsigned long SHOW_DOCUMENT = 0x100;
const unsigned long SHOW_DOCUMENT_TYPE = 0x200;
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;
const unsigned long SHOW_NOTATION = 0x800; // historical
unsigned short acceptNode(Node node);
};

View File

@ -0,0 +1,24 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface NodeIterator {
readonly attribute Node root;
readonly attribute Node? referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter? filter;
Node? nextNode();
Node? previousNode();
void detach();
;}

View File

@ -0,0 +1,16 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
};

Some files were not shown because too many files have changed in this diff Show More