auto merge of #573 : jdm/servo/domevent, r=metajack

This commit is contained in:
bors-servo 2013-07-12 08:45:33 -07:00
commit 0c4119b496
16 changed files with 895 additions and 146 deletions

View file

@ -256,6 +256,9 @@ DOMInterfaces = {
'workers': True,
}],
'MouseEvent': {
},
'NodeList': [
{
'nativeType': 'nsINodeList',
@ -333,6 +336,9 @@ DOMInterfaces = {
'resultNotAddRefed': [ 'getItem' ]
}],
'UIEvent': {
},
'WebGLRenderingContext': {
'nativeType': 'mozilla::WebGLContext',
'headerFile': 'WebGLContext.h',
@ -499,7 +505,7 @@ def addExternalIface(iface, nativeType=None, headerFile=None, pointerType=None):
# If you add one of these, you need to make sure nsDOMQS.h has the relevant
# macros added for it
def addExternalHTMLElement(element):
nativeElement = 'ns' + element
nativeElement = element
addExternalIface(element, nativeType=nativeElement,
headerFile=nativeElement + '.h')
@ -520,7 +526,7 @@ addExternalIface('File')
addExternalIface('HitRegionOptions', nativeType='nsISupports')
addExternalIface('HTMLElement')
addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
addExternalIface('Node', nativeType='nsINode')
addExternalIface('Node', nativeType='AbstractNode<ScriptView>', pointerType='')
addExternalIface('PaintRequest')
addExternalIface('SVGLength')
addExternalIface('SVGMatrix')
@ -552,4 +558,5 @@ addExternalIface('WebGLShaderPrecisionFormat',
addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
headerFile='WebGLContext.h')
addExternalIface('Window')
addExternalIface('WindowProxy', nativeType='WindowProxy')
addExternalIface('XULElement')

View file

@ -24,16 +24,21 @@ def replaceFileIfChanged(filename, newContents):
Read a copy of the old file, so that we don't touch it if it hasn't changed.
Returns True if the file was updated, false otherwise.
"""
oldFileContents = ""
try:
oldFile = open(filename, 'rb')
oldFileContents = ''.join(oldFile.readlines())
oldFile.close()
except:
pass
#XXXjdm This doesn't play well with make right now.
# Force the file to always be updated, or else changing CodegenRust.py
# will cause many autogenerated bindings to be regenerated perpetually
# until the result is actually different.
if newContents == oldFileContents:
return False
#oldFileContents = ""
#try:
# oldFile = open(filename, 'rb')
# oldFileContents = ''.join(oldFile.readlines())
# oldFile.close()
#except:
# pass
#if newContents == oldFileContents:
# return False
f = open(filename, 'wb')
f.write(newContents)
@ -91,6 +96,8 @@ class CastableObjectUnwrapper():
assert descriptor.castable
self.substitution = { "type" : descriptor.nativeType,
"depth": descriptor.interface.inheritanceDepth(),
"prototype": "prototypes::id::" + descriptor.name,
"protoID" : "prototypes::id::" + descriptor.name + " as uint",
"source" : source,
"target" : target,
@ -115,8 +122,14 @@ class CastableObjectUnwrapper():
def __str__(self):
return string.Template(
"""${target} = unwrap(${source});
"""match unwrap_object(${source}, ${prototype}, ${depth}) {
Ok(val) => ${target} = val,
Err(()) => {
${codeOnFailure}
}
}
""").substitute(self.substitution)
#"""{
# nsresult rv = UnwrapObject<${protoID}, ${type}>(cx, ${source}, ${target});
# if (NS_FAILED(rv)) {
@ -130,7 +143,7 @@ class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
"""
def __init__(self, descriptor, source, target):
CastableObjectUnwrapper.__init__(self, descriptor, source, target,
"return Throw<%s>(cx, rv);" %
"return 0; //XXXjdm return Throw<%s>(cx, rv);" %
toStringBool(not descriptor.workers))
class CGThing():
@ -394,6 +407,10 @@ class FakeCastableDescriptor():
self.pointerType = descriptor.pointerType
self.name = descriptor.name
self.hasXPConnectImpls = descriptor.hasXPConnectImpls
class FakeInterface:
def inheritanceDepth(self):
return descriptor.interface.inheritanceDepth()
self.interface = FakeInterface()
def dictionaryHasSequenceMember(dictionary):
return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
@ -543,7 +560,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
CGIndenter(CGGeneric(templateBody)).define() + "\n")
if type.nullable():
templateBody += (
"} else if (${val}.isNullOrUndefined()) {\n"
"} else if RUST_JSVAL_IS_NULL(${val}) != 0 || RUST_JSVAL_IS_VOID(${val}) != 0 {\n"
" %s;\n" % codeToSetNull)
templateBody += (
"} else {\n" +
@ -878,7 +895,7 @@ for (uint32_t i = 0; i < length; ++i) {
not descriptor.workers) or isMember
typeName = descriptor.nativeType
typePtr = typeName + "*"
typePtr = descriptor.pointerType + typeName
# Compute a few things:
# - declType is the type we want to return as the first element of our
@ -889,15 +906,9 @@ for (uint32_t i = 0; i < length; ++i) {
# Set up some sensible defaults for these things insofar as we can.
holderType = None
if argIsPointer:
if forceOwningType:
declType = "nsRefPtr<" + typeName + ">"
else:
declType = typePtr
declType = "Option<" + typePtr + ">"
else:
if forceOwningType:
declType = "OwningNonNull<" + typeName + ">"
else:
declType = descriptor.pointerType + typeName
declType = typePtr
templateBody = ""
if descriptor.castable:
@ -931,41 +942,19 @@ for (uint32_t i = 0; i < length; ++i) {
elif descriptor.workers:
templateBody += "${declName} = &${val}.toObject();"
else:
# Either external, or new-binding non-castable. We always have a
# holder for these, because we don't actually know whether we have
# to addref when unwrapping or not. So we just pass an
# getter_AddRefs(nsRefPtr) to XPConnect and if we'll need a release
# it'll put a non-null pointer in there.
if forceOwningType:
# Don't return a holderType in this case; our declName
# will just own stuff.
templateBody += "nsRefPtr<" + typeName + "> ${holderName};\n"
else:
holderType = "nsRefPtr<" + typeName + ">"
templateBody += (
"jsval tmpVal = ${val};\n" +
typePtr + " tmp;\n"
"if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), &tmpVal))) {\n")
"match unwrap_value::<" + typePtr + ">(&${val} as *JSVal, "
"prototypes::id::%s, %d) {\n" % (descriptor.name, descriptor.interface.inheritanceDepth() if descriptor.concrete else 0) +
" Err(()) => {")
templateBody += CGIndenter(onFailureBadType(failureCode,
descriptor.interface.identifier.name)).define()
templateBody += ("}\n"
"MOZ_ASSERT(tmp);\n")
if not isDefinitelyObject:
# Our tmpVal will go out of scope, so we can't rely on it
# for rooting
templateBody += (
"if (tmpVal != ${val} && !${holderName}) {\n"
" // We have to have a strong ref, because we got this off\n"
" // some random object that might get GCed\n"
" ${holderName} = tmp;\n"
"}\n")
# And store our tmp, before it goes out of scope.
templateBody += "${declName} = tmp;"
templateBody += (
" }\n"
" Ok(unwrapped) => ${declName} = Some(unwrapped)\n"
"}\n")
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
type, "${declName} = NULL",
type, "${declName} = None",
failureCode)
declType = CGGeneric(declType)
@ -1305,10 +1294,15 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
(holderType.define(), originalHolderName))
mutableHolderType = CGWrapper(holderType, pre="Optional< ", post=" >")
holderType = CGWrapper(mutableHolderType, pre="const ")
result.append(
CGList([holderType, CGGeneric(" "),
CGGeneric(originalHolderName),
CGGeneric(";")]))
tmpresult = [CGGeneric("let "),
CGGeneric(originalHolderName),
CGGeneric(": "),
holderType]
if initialValue:
tmpresult += [CGGeneric(" = "),
initialValue]
tmpresult += [CGGeneric(";")]
result.append(CGList(tmpresult))
originalDeclName = replacements["declName"]
if declType is not None:
@ -2073,7 +2067,7 @@ class CGNativePropertyHooks(CGThing):
parentHooks = ("&" + toBindingNamespace(parent.identifier.name) + "::NativeHooks"
if parent else '0 as *NativePropertyHooks')
return """
static NativeHooks: NativePropertyHooks = NativePropertyHooks { resolve_own_property: /*%s*/ 0 as *u8, resolve_property: ResolveProperty, enumerate_own_properties: /*%s*/ 0 as *u8, enumerate_properties: /*EnumerateProperties*/ 0 as *u8, proto_hooks: %s };
static NativeHooks: NativePropertyHooks = NativePropertyHooks { resolve_own_property: /*%s*/ 0 as *u8, resolve_property: ResolveProperty, enumerate_own_properties: /*%s*/ 0 as *u8, enumerate_properties: /*EnumerateProperties*/ 0 as *u8, proto_hooks: /*%s*/ 0 as *NativePropertyHooks };
""" % (resolveOwnProperty, enumerateOwnProperties, parentHooks)
# We'll want to insert the indent at the beginnings of lines, but we
@ -2729,11 +2723,11 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
A method for getting a per-interface object (a prototype object or interface
constructor object).
"""
def __init__(self, descriptor, name, idPrefix=""):
def __init__(self, descriptor, name, idPrefix="", pub=False):
args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aGlobal'),
Argument('*JSObject', 'aReceiver')]
CGAbstractMethod.__init__(self, descriptor, name,
'*JSObject', args, inline=True)
'*JSObject', args, inline=True, pub=pub)
self.id = idPrefix + "id::" + self.descriptor.name
def definition_body(self):
return """
@ -2765,7 +2759,7 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
"""
def __init__(self, descriptor):
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
"prototypes::")
"prototypes::", pub=True)
def definition_body(self):
return """
/* Get the interface prototype object for this class. This will create the
@ -2846,7 +2840,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
getPrototypeOf: ptr::null()
};
(*script_context).dom_static.proxy_handlers.insert(prototypes::id::%s as uint,
CreateProxyHandler(ptr::to_unsafe_ptr(&traps)));
CreateProxyHandler(ptr::to_unsafe_ptr(&traps), ptr::to_unsafe_ptr(&Class) as *libc::c_void));
""" % self.descriptor.name
else:
@ -3107,6 +3101,25 @@ class FakeArgument():
self.enforceRange = False
self.clamp = False
class CGSetterCall(CGPerSignatureCall):
"""
A class to generate a native object setter call for a particular IDL
setter.
"""
def __init__(self, argType, nativeMethodName, descriptor, attr):
CGPerSignatureCall.__init__(self, None, [],
[FakeArgument(argType, attr)],
nativeMethodName, False, descriptor, attr,
setter=True)
def wrap_return_value(self):
# We have no return value
return "\nreturn 1;"
def getArgc(self):
return "1"
def getArgvDecl(self):
# We just get our stuff from our last arg no matter what
return ""
class CGAbstractBindingMethod(CGAbstractExternMethod):
"""
Common class to generate the JSNatives for all our methods, getters, and
@ -3119,7 +3132,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
if unwrapFailureCode is None:
self.unwrapFailureCode = ("return Throw<%s>(cx, rv);" %
self.unwrapFailureCode = ("return 0; //XXXjdm return Throw<%s>(cx, rv);" %
toStringBool(not descriptor.workers))
else:
self.unwrapFailureCode = unwrapFailureCode
@ -3138,7 +3151,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
def getThis(self):
return CGIndenter(
CGGeneric("let obj: *JSObject = JS_THIS_OBJECT(cx, vp);\n"
CGGeneric("let obj: *JSObject = JS_THIS_OBJECT(cx, cast::transmute(vp));\n"
"if obj.is_null() {\n"
" return false as JSBool;\n"
"}\n"
@ -3248,6 +3261,56 @@ class CGSpecializedGetter(CGAbstractExternMethod):
self.descriptor, self.attr)),
pre=" let obj = (*obj.unnamed);\n").define()
class CGGenericSetter(CGAbstractBindingMethod):
"""
A class for generating the Rust code for an IDL attribute setter.
"""
def __init__(self, descriptor, lenientThis=False):
args = [Argument('*JSContext', 'cx'), Argument('uint', 'argc'),
Argument('*mut JSVal', 'vp')]
if lenientThis:
name = "genericLenientSetter"
unwrapFailureCode = (
"MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
"return true;")
else:
name = "genericSetter"
unwrapFailureCode = None
CGAbstractBindingMethod.__init__(self, descriptor, name, args,
unwrapFailureCode)
def generate_code(self):
return CGIndenter(CGGeneric(
"let undef = JSVAL_VOID;\n"
"let argv: *JSVal = if argc != 0 { JS_ARGV(cx, cast::transmute(vp)) } else { &undef as *JSVal };\n"
"let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, cast::transmute(vp)));\n"
"if CallJitPropertyOp(info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, cast::transmute(vp)) == 0 {"
" return 0;\n"
"}\n"
"*vp = JSVAL_VOID;\n"
"return 1;"))
class CGSpecializedSetter(CGAbstractExternMethod):
"""
A class for generating the code for a specialized attribute setter
that the JIT can call with lower overhead.
"""
def __init__(self, descriptor, attr):
self.attr = attr
name = 'set_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'),
Argument('*mut %s' % descriptor.nativeType, 'this'),
Argument('*mut JSVal', 'argv')]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
def definition_body(self):
name = self.attr.identifier.name
nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
return CGWrapper(CGIndenter(CGSetterCall(self.attr.type, nativeName,
self.descriptor, self.attr)),
pre=" let obj = (*obj.unnamed);\n").define()
def infallibleForMember(member, type, descriptorProvider):
"""
Determine the fallibility of changing a C++ value of IDL type "type" into
@ -3786,7 +3849,7 @@ class CGDescriptor(CGThing):
else:
hasGetter = True
if not m.readonly:
#cgThings.append(CGSpecializedSetter(descriptor, m))
cgThings.append(CGSpecializedSetter(descriptor, m))
if m.hasLenientThis():
hasLenientSetter = True
else:
@ -3796,7 +3859,7 @@ class CGDescriptor(CGThing):
if hasGetter: cgThings.append(CGGenericGetter(descriptor))
#if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
# lenientThis=True))
#if hasSetter: cgThings.append(CGGenericSetter(descriptor))
if hasSetter: cgThings.append(CGGenericSetter(descriptor))
#if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
# lenientThis=True))
@ -3926,7 +3989,8 @@ class CGDictionary(CGThing):
return ""
d = self.dictionary
if d.parent:
inheritance = ": public %s " % self.makeClassName(d.parent) #XXXjdm
inheritance = " parent: %s::%s,\n" % (self.makeModuleName(d.parent),
self.makeClassName(d.parent))
else:
inheritance = ""
memberDecls = [" %s: %s," %
@ -3934,7 +3998,8 @@ class CGDictionary(CGThing):
for m in self.memberInfo]
return (string.Template(
"pub struct ${selfName} {\n" + #XXXjdm deal with inheritance
"pub struct ${selfName} {\n" +
"${inheritance}" +
"\n".join(memberDecls) + "\n" +
# NOTE: jsids are per-runtime, so don't use them in workers
"\n".join(" //static jsid " +
@ -3949,13 +4014,13 @@ class CGDictionary(CGThing):
d = self.dictionary
if d.parent:
initParent = ("// Per spec, we init the parent's members first\n"
"if (!%s::Init(cx, val)) {\n"
" return false;\n"
"}\n" % self.makeClassName(d.parent))
"if self.parent.Init(cx, val) == 0 {\n"
" return 0;\n"
"}\n")
else:
initParent = ""
memberInits = [CGIndenter(self.getMemberConversion(m)).define()
memberInits = [CGIndenter(self.getMemberConversion(m), indentLevel=6).define()
for m in self.memberInfo]
idinit = [CGGeneric('!InternJSString(cx, %s, "%s")' %
(m.identifier.name + "_id", m.identifier.name))
@ -3970,11 +4035,11 @@ class CGDictionary(CGThing):
def defaultValue(ty):
if ty is "bool":
return "false"
elif ty in ["i32", "u32"]:
elif ty in ["i32", "u32", "i16", "u16"]:
return "0"
elif ty is "nsString":
return "\"\""
elif ty.startswith("Optional"):
elif ty.startswith("Option"):
return "None"
else:
return "/* uh oh: %s */" % ty
@ -3987,42 +4052,43 @@ class CGDictionary(CGThing):
for m in d.members) + "\n"
"\n"
"impl ${selfName} {\n"
"fn new() -> ${selfName} {\n"
" ${selfName} {\n" +
"\n".join(" %s: %s," % (m[0].identifier.name, defaultValue(self.getMemberType(m))) for m in self.memberInfo) + "\n"
" pub fn new() -> ${selfName} {\n"
" ${selfName} {\n" +
((" parent: %s::%s::new(),\n" % (self.makeModuleName(d.parent),
self.makeClassName(d.parent))) if d.parent else "") +
"\n".join(" %s: %s," % (m[0].identifier.name, defaultValue(self.getMemberType(m))) for m in self.memberInfo) + "\n"
" }\n"
" }\n"
"}\n"
"\n"
"fn InitIds(cx: *JSContext) -> bool {\n"
" //MOZ_ASSERT(!initedIds);\n"
"/*${idInit}\n"
" initedIds = true;*/ //XXXjdm\n"
" return true;\n"
"}\n"
" pub fn InitIds(&mut self, cx: *JSContext) -> bool {\n"
" //MOZ_ASSERT(!initedIds);\n"
" /*${idInit}\n"
" initedIds = true;*/ //XXXjdm\n"
" return true;\n"
" }\n"
"\n" if not self.workers else "") +
"fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool\n"
"{\n"
" unsafe {\n" +
" pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n"
" unsafe {\n" +
# NOTE: jsids are per-runtime, so don't use them in workers
(" if (!initedIds && !${selfName}::InitIds(cx)) {\n"
" return 0;\n"
" }\n" if not self.workers else "") +
(" if (!initedIds && !self.InitIds(cx)) {\n"
" return 0;\n"
" }\n" if not self.workers else "") +
"${initParent}"
" let mut found: JSBool = 0;\n"
" let temp: JSVal = JSVAL_NULL;\n"
" let isNull = RUST_JSVAL_IS_NULL(val) != 0 || RUST_JSVAL_IS_VOID(val) != 0;\n"
" if !isNull && RUST_JSVAL_IS_PRIMITIVE(val) != 0 {\n"
" return 0; //XXXjdm throw properly here\n"
" //return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
" }\n"
" let mut found: JSBool = 0;\n"
" let temp: JSVal = JSVAL_NULL;\n"
" let isNull = RUST_JSVAL_IS_NULL(val) != 0 || RUST_JSVAL_IS_VOID(val) != 0;\n"
" if !isNull && RUST_JSVAL_IS_PRIMITIVE(val) != 0 {\n"
" return 0; //XXXjdm throw properly here\n"
" //return Throw<${isMainThread}>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
" }\n"
"\n"
"${initMembers}\n"
" return 1;\n"
" return 1;\n"
" }\n"
" }\n"
"}\n"
"}").substitute({
"selfName": self.makeClassName(d),
"initParent": CGIndenter(CGGeneric(initParent)).define(),
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=6).define(),
"initMembers": "\n\n".join(memberInits),
"idInit": CGIndenter(idinit).define(),
"isMainThread": toStringBool(not self.workers)
@ -4036,6 +4102,15 @@ class CGDictionary(CGThing):
def makeClassName(self, dictionary):
return self.makeDictionaryName(dictionary, self.workers)
@staticmethod
def makeModuleName(dictionary):
name = dictionary.identifier.name
if name.endswith('Init'):
return toBindingNamespace(name.replace('Init', ''))
#XXXjdm This breaks on the test webidl files, sigh.
#raise TypeError("No idea how to find this dictionary's definition: " + name)
return "/* uh oh */ %s" % name
def getMemberType(self, memberInfo):
(member, (templateBody, declType,
holderType, dealWithOptional, initialValue)) = memberInfo
@ -4209,6 +4284,10 @@ class CGBindingRoot(CGThing):
'dom::event::*', #XXXjdm
'dom::eventtarget::*', #XXXjdm
'dom::formdata::*', #XXXjdm
'dom::mouseevent::*', #XXXjdm
'dom::uievent::*', #XXXjdm
'dom::windowproxy::*', #XXXjdm
'dom::bindings::codegen::*', #XXXjdm
'script_task::task_from_context',
'dom::bindings::utils::EnumEntry',
'dom::node::ScriptView',

View file

@ -1,3 +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/.
*
* For more information on this interface please see
* http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
*
* 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;

View file

@ -0,0 +1,76 @@
/* -*- 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/.
*
* For more information on this interface please see
* http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface MouseEvent : UIEvent {
readonly attribute long screenX;
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
readonly attribute boolean metaKey;
readonly attribute unsigned short button;
readonly attribute unsigned short buttons;
readonly attribute EventTarget? relatedTarget;
// Deprecated in DOM Level 3:
[Throws]
void initMouseEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
WindowProxy? viewArg,
long detailArg,
long screenXArg,
long screenYArg,
long clientXArg,
long clientYArg,
boolean ctrlKeyArg,
boolean altKeyArg,
boolean shiftKeyArg,
boolean metaKeyArg,
unsigned short buttonArg,
EventTarget? relatedTargetArg);
// Introduced in DOM Level 3:
boolean getModifierState(DOMString keyArg);
};
// Event Constructor Syntax:
[Constructor(DOMString typeArg, optional MouseEventInit mouseEventInitDict)]
partial interface MouseEvent
{
};
// Suggested initMouseEvent replacement initializer:
dictionary MouseEventInit {
// Attributes from Event:
boolean bubbles = false;
boolean cancelable = false;
// Attributes from UIEvent:
WindowProxy? view = null;
long detail = 0;
// Attributes for MouseEvent:
long screenX = 0;
long screenY = 0;
long clientX = 0;
long clientY = 0;
boolean ctrlKey = false;
boolean shiftKey = false;
boolean altKey = false;
boolean metaKey = false;
unsigned short button = 0;
// Note: "buttons" was not previously initializable through initMouseEvent!
unsigned short buttons = 0;
EventTarget? relatedTarget = null;
};

View file

@ -1,34 +0,0 @@
#include "BlobBinding.h"
#include "ClientRectBinding.h"
#include "ClientRectListBinding.h"
#include "DOMParserBinding.h"
#include "EventBinding.h"
#include "EventTargetBinding.h"
#include "FormDataBinding.h"
#include "HTMLCollectionBinding.h"
#include "nsScriptNameSpaceManager.h"
namespace mozilla {
namespace dom {
void
Register(nsScriptNameSpaceManager* aNameSpaceManager)
{
#define REGISTER_PROTO(_dom_class, _pref_check) \
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check);
REGISTER_PROTO(Blob, nullptr);
REGISTER_PROTO(ClientRect, nullptr);
REGISTER_PROTO(ClientRectList, nullptr);
REGISTER_PROTO(DOMParser, nullptr);
REGISTER_PROTO(Event, nullptr);
REGISTER_PROTO(EventTarget, nullptr);
REGISTER_PROTO(FormData, nullptr);
REGISTER_PROTO(HTMLCollection, nullptr);
#undef REGISTER_PROTO
}
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,48 @@
/* -*- 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/.
*
* For more information on this interface please see
* http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface WindowProxy;
interface Node;
[Constructor(DOMString type, optional UIEventInit eventInitDict)]
interface UIEvent : Event
{
readonly attribute WindowProxy? view;
readonly attribute long detail;
void initUIEvent(DOMString aType,
boolean aCanBubble,
boolean aCancelable,
WindowProxy? aView,
long aDetail);
};
// Additional DOM0 properties.
partial interface UIEvent {
const long SCROLL_PAGE_UP = -32768;
const long SCROLL_PAGE_DOWN = 32768;
readonly attribute long layerX;
readonly attribute long layerY;
readonly attribute long pageX;
readonly attribute long pageY;
readonly attribute unsigned long which;
readonly attribute Node? rangeParent;
readonly attribute long rangeOffset;
attribute boolean cancelBubble;
readonly attribute boolean isChar;
};
dictionary UIEventInit : EventInit
{
WindowProxy? view = null;
long detail = 0;
};

View file

@ -429,17 +429,19 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
pass
class IDLInterface(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
def __init__(self, location, parentScope, name, parent, members,
isPartial):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
assert not isPartial or not parent
self.parent = parent
self.parent = None
self._callback = False
self._finished = False
self.members = list(members) # clone the list
self.members = []
self.implementedInterfaces = set()
self._consequential = False
self._isPartial = True
# self.interfacesBasedOnSelf is the set of interfaces that inherit from
# self or have self as a consequential interface, including self itself.
# Used for distinguishability checking.
@ -447,6 +449,12 @@ class IDLInterface(IDLObjectWithScope):
IDLObjectWithScope.__init__(self, location, parentScope, name)
if not isPartial:
self.setNonPartial(location, parent, members)
else:
# Just remember our members for now
self.members = list(members) # clone the list
def __str__(self):
return "Interface '%s'" % self.identifier.name
@ -482,6 +490,11 @@ class IDLInterface(IDLObjectWithScope):
self._finished = True
if self._isPartial:
raise WebIDLError("Interface %s does not have a non-partial "
"declaration" % self.identifier.name,
[self.location])
assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder)
parent = self.parent.finish(scope) if self.parent else None
if parent and isinstance(parent, IDLExternalInterface):
@ -749,6 +762,21 @@ class IDLInterface(IDLObjectWithScope):
def getExtendedAttribute(self, name):
return self._extendedAttrDict.get(name, None)
def setNonPartial(self, location, parent, members):
assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
if not self._isPartial:
raise WebIDLError("Two non-partial definitions for the "
"same interface",
[location, self.location])
self._isPartial = False
# Now make it look like we were parsed at this new location, since
# that's the place where the interface is "really" defined
self.location = location
assert not self.parent
self.parent = parent
# Put the new members at the beginning
self.members = members + self.members
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
@ -2742,9 +2770,25 @@ class Parser(Tokenizer):
"""
location = self.getLocation(p, 1)
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
members = p[5]
p[0] = IDLInterface(location, self.globalScope(), identifier, p[3], members)
parent = p[3]
try:
if self.globalScope()._lookupIdentifier(identifier):
p[0] = self.globalScope()._lookupIdentifier(identifier)
if not isinstance(p[0], IDLInterface):
raise WebIDLError("Partial interface has the same name as "
"non-interface object",
[location, p[0].location])
p[0].setNonPartial(location, parent, members)
return
except Exception, ex:
if isinstance(ex, WebIDLError):
raise ex
pass
p[0] = IDLInterface(location, self.globalScope(), identifier, parent,
members, isPartial=False)
def p_InterfaceForwardDecl(self, p):
"""
@ -2766,6 +2810,29 @@ class Parser(Tokenizer):
"""
PartialInterface : PARTIAL INTERFACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON
"""
location = self.getLocation(p, 2)
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
members = p[5]
try:
if self.globalScope()._lookupIdentifier(identifier):
p[0] = self.globalScope()._lookupIdentifier(identifier)
if not isinstance(p[0], IDLInterface):
raise WebIDLError("Partial interface has the same name as "
"non-interface object",
[location, p[0].location])
# Just throw our members into the existing IDLInterface. If we
# have extended attributes, those will get added to it
# automatically.
p[0].members.extend(members)
return
except Exception, ex:
if isinstance(ex, WebIDLError):
raise ex
pass
p[0] = IDLInterface(location, self.globalScope(), identifier, None,
members, isPartial=True)
pass
def p_Inheritance(self, p):