michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set ts=8 sts=4 et sw=4 tw=99: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsDOMQS_h__ michael@0: #define nsDOMQS_h__ michael@0: michael@0: #include "nsDOMClassInfoID.h" michael@0: #include "nsGenericHTMLElement.h" michael@0: #include "mozilla/dom/HTMLCanvasElement.h" michael@0: #include "mozilla/dom/HTMLFormElement.h" michael@0: #include "mozilla/dom/HTMLImageElement.h" michael@0: #include "mozilla/dom/HTMLOptionElement.h" michael@0: #include "HTMLOptGroupElement.h" michael@0: #include "mozilla/dom/HTMLVideoElement.h" michael@0: #include "nsHTMLDocument.h" michael@0: #include "nsICSSDeclaration.h" michael@0: #include "nsSVGElement.h" michael@0: #include "mozilla/dom/Event.h" michael@0: #include "mozilla/dom/UIEvent.h" michael@0: #include "mozilla/dom/MouseEvent.h" michael@0: #include "mozilla/dom/EventTargetBinding.h" michael@0: #include "mozilla/dom/NodeBinding.h" michael@0: #include "mozilla/dom/ElementBinding.h" michael@0: #include "mozilla/dom/HTMLElementBinding.h" michael@0: #include "mozilla/dom/DocumentBinding.h" michael@0: #include "mozilla/dom/SVGElementBinding.h" michael@0: #include "mozilla/dom/HTMLDocumentBinding.h" michael@0: #include "XPCQuickStubs.h" michael@0: #include "nsGlobalWindow.h" michael@0: michael@0: template michael@0: struct ProtoIDAndDepth michael@0: { michael@0: enum { michael@0: PrototypeID = mozilla::dom::prototypes::id::_ID_Count, michael@0: Depth = -1 michael@0: }; michael@0: }; michael@0: michael@0: #define NEW_BINDING(_native, _id) \ michael@0: template<> \ michael@0: struct ProtoIDAndDepth<_native> \ michael@0: { \ michael@0: enum { \ michael@0: PrototypeID = mozilla::dom::prototypes::id::_id, \ michael@0: Depth = mozilla::dom::PrototypeTraits< \ michael@0: static_cast(PrototypeID)>::Depth \ michael@0: }; \ michael@0: } michael@0: michael@0: NEW_BINDING(mozilla::dom::EventTarget, EventTarget); michael@0: NEW_BINDING(nsINode, Node); michael@0: NEW_BINDING(mozilla::dom::Element, Element); michael@0: NEW_BINDING(nsGenericHTMLElement, HTMLElement); michael@0: NEW_BINDING(nsIDocument, Document); michael@0: NEW_BINDING(nsDocument, Document); michael@0: NEW_BINDING(nsHTMLDocument, HTMLDocument); michael@0: NEW_BINDING(nsSVGElement, SVGElement); michael@0: NEW_BINDING(mozilla::dom::Event, Event); michael@0: NEW_BINDING(mozilla::dom::UIEvent, UIEvent); michael@0: NEW_BINDING(mozilla::dom::MouseEvent, MouseEvent); michael@0: NEW_BINDING(nsGlobalWindow, Window); michael@0: michael@0: #define DEFINE_UNWRAP_CAST(_interface, _base, _bit) \ michael@0: template <> \ michael@0: MOZ_ALWAYS_INLINE bool \ michael@0: xpc_qsUnwrapThis<_interface>(JSContext *cx, \ michael@0: JS::HandleObject obj, \ michael@0: _interface **ppThis, \ michael@0: nsISupports **pThisRef, \ michael@0: JS::MutableHandleValue pThisVal, \ michael@0: bool failureFatal) \ michael@0: { \ michael@0: nsresult rv; \ michael@0: nsISupports *native = \ michael@0: castNativeFromWrapper(cx, obj, _bit, \ michael@0: ProtoIDAndDepth<_interface>::PrototypeID, \ michael@0: ProtoIDAndDepth<_interface>::Depth, \ michael@0: pThisRef, pThisVal, &rv); \ michael@0: *ppThis = nullptr; /* avoids uninitialized warnings in callers */ \ michael@0: if (failureFatal && !native) \ michael@0: return xpc_qsThrow(cx, rv); \ michael@0: *ppThis = static_cast<_interface*>(static_cast<_base*>(native)); \ michael@0: return true; \ michael@0: } \ michael@0: \ michael@0: template <> \ michael@0: MOZ_ALWAYS_INLINE nsresult \ michael@0: xpc_qsUnwrapArg<_interface>(JSContext *cx, \ michael@0: JS::HandleValue v, \ michael@0: _interface **ppArg, \ michael@0: nsISupports **ppArgRef, \ michael@0: JS::MutableHandleValue vp) \ michael@0: { \ michael@0: nsresult rv; \ michael@0: nsISupports *native = \ michael@0: castNativeArgFromWrapper(cx, v, _bit, \ michael@0: ProtoIDAndDepth<_interface>::PrototypeID, \ michael@0: ProtoIDAndDepth<_interface>::Depth, \ michael@0: ppArgRef, vp, &rv); \ michael@0: if (NS_SUCCEEDED(rv)) \ michael@0: *ppArg = static_cast<_interface*>(static_cast<_base*>(native)); \ michael@0: return rv; \ michael@0: } \ michael@0: \ michael@0: template <> \ michael@0: inline nsresult \ michael@0: xpc_qsUnwrapArg<_interface>(JSContext *cx, \ michael@0: JS::HandleValue v, \ michael@0: _interface **ppArg, \ michael@0: _interface **ppArgRef, \ michael@0: JS::MutableHandleValue vp) \ michael@0: { \ michael@0: nsISupports* argRef = static_cast<_base*>(*ppArgRef); \ michael@0: nsresult rv = xpc_qsUnwrapArg<_interface>(cx, v, ppArg, &argRef, vp); \ michael@0: *ppArgRef = static_cast<_interface*>(static_cast<_base*>(argRef)); \ michael@0: return rv; \ michael@0: } \ michael@0: \ michael@0: namespace mozilla { \ michael@0: namespace dom { \ michael@0: \ michael@0: template <> \ michael@0: MOZ_ALWAYS_INLINE nsresult \ michael@0: UnwrapArg<_interface>(JSContext *cx, \ michael@0: JS::HandleValue v, \ michael@0: _interface **ppArg, \ michael@0: nsISupports **ppArgRef, \ michael@0: JS::MutableHandleValue vp) \ michael@0: { \ michael@0: return xpc_qsUnwrapArg<_interface>(cx, v, ppArg, ppArgRef, vp); \ michael@0: } \ michael@0: \ michael@0: template <> \ michael@0: inline nsresult \ michael@0: UnwrapArg<_interface>(JSContext *cx, \ michael@0: JS::HandleValue v, \ michael@0: _interface **ppArg, \ michael@0: _interface **ppArgRef, \ michael@0: JS::MutableHandleValue vp) \ michael@0: { \ michael@0: return xpc_qsUnwrapArg<_interface>(cx, v, ppArg, ppArgRef, vp); \ michael@0: } \ michael@0: \ michael@0: } /* namespace dom */ \ michael@0: } /* namespace mozilla */ michael@0: michael@0: #undef DOMCI_CASTABLE_INTERFACE michael@0: michael@0: #undef DOMCI_CASTABLE_INTERFACE michael@0: #define DOMCI_CASTABLE_INTERFACE(_interface, _base, _bit, _extra) \ michael@0: DEFINE_UNWRAP_CAST(_interface, _base, _bit) michael@0: michael@0: DOMCI_CASTABLE_INTERFACES(unused) michael@0: michael@0: #undef DOMCI_CASTABLE_INTERFACE michael@0: michael@0: inline nsresult michael@0: xpc_qsUnwrapArg_HTMLElement(JSContext *cx, michael@0: JS::HandleValue v, michael@0: nsIAtom *aTag, michael@0: nsIContent **ppArg, michael@0: nsISupports **ppArgRef, michael@0: JS::MutableHandleValue vp) michael@0: { michael@0: nsGenericHTMLElement *elem; michael@0: JS::RootedValue val(cx); michael@0: nsresult rv = michael@0: xpc_qsUnwrapArg(cx, v, &elem, ppArgRef, &val); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: if (elem->IsHTML(aTag)) { michael@0: *ppArg = elem; michael@0: vp.set(val); michael@0: } else { michael@0: rv = NS_ERROR_XPC_BAD_CONVERT_JS; michael@0: } michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: #define DEFINE_UNWRAP_CAST_HTML(_tag, _clazz) \ michael@0: template <> \ michael@0: inline nsresult \ michael@0: xpc_qsUnwrapArg<_clazz>(JSContext *cx, \ michael@0: JS::HandleValue v, \ michael@0: _clazz **ppArg, \ michael@0: nsISupports **ppArgRef, \ michael@0: JS::MutableHandleValue vp) \ michael@0: { \ michael@0: nsIContent *elem; \ michael@0: nsresult rv = xpc_qsUnwrapArg_HTMLElement(cx, v, nsGkAtoms::_tag, &elem, \ michael@0: ppArgRef, vp); \ michael@0: if (NS_SUCCEEDED(rv)) \ michael@0: *ppArg = static_cast<_clazz*>(elem); \ michael@0: return rv; \ michael@0: } \ michael@0: \ michael@0: template <> \ michael@0: inline nsresult \ michael@0: xpc_qsUnwrapArg<_clazz>(JSContext *cx, JS::HandleValue v, _clazz **ppArg, \ michael@0: _clazz **ppArgRef, JS::MutableHandleValue vp) \ michael@0: { \ michael@0: nsISupports* argRef = static_cast(*ppArgRef); \ michael@0: nsresult rv = xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, &argRef, vp); \ michael@0: *ppArgRef = static_cast<_clazz*>(static_cast(argRef)); \ michael@0: return rv; \ michael@0: } \ michael@0: \ michael@0: namespace mozilla { \ michael@0: namespace dom { \ michael@0: \ michael@0: template <> \ michael@0: inline nsresult \ michael@0: UnwrapArg<_clazz>(JSContext *cx, \ michael@0: JS::HandleValue v, \ michael@0: _clazz **ppArg, \ michael@0: nsISupports **ppArgRef, \ michael@0: JS::MutableHandleValue vp) \ michael@0: { \ michael@0: return xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, ppArgRef, vp); \ michael@0: } \ michael@0: \ michael@0: template <> \ michael@0: inline nsresult \ michael@0: UnwrapArg<_clazz>(JSContext *cx, JS::HandleValue v, _clazz **ppArg, \ michael@0: _clazz **ppArgRef, JS::MutableHandleValue vp) \ michael@0: { \ michael@0: return xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, ppArgRef, vp); \ michael@0: } \ michael@0: \ michael@0: } /* namespace dom */ \ michael@0: } /* namespace mozilla */ michael@0: michael@0: DEFINE_UNWRAP_CAST_HTML(canvas, mozilla::dom::HTMLCanvasElement) michael@0: DEFINE_UNWRAP_CAST_HTML(form, mozilla::dom::HTMLFormElement) michael@0: DEFINE_UNWRAP_CAST_HTML(img, mozilla::dom::HTMLImageElement) michael@0: DEFINE_UNWRAP_CAST_HTML(optgroup, mozilla::dom::HTMLOptGroupElement) michael@0: DEFINE_UNWRAP_CAST_HTML(option, mozilla::dom::HTMLOptionElement) michael@0: DEFINE_UNWRAP_CAST_HTML(video, mozilla::dom::HTMLVideoElement) michael@0: michael@0: inline nsISupports* michael@0: ToSupports(nsContentList *p) michael@0: { michael@0: return static_cast(p); michael@0: } michael@0: michael@0: inline nsISupports* michael@0: ToCanonicalSupports(nsContentList *p) michael@0: { michael@0: return static_cast(p); michael@0: } michael@0: michael@0: #endif /* nsDOMQS_h__ */