aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/dom')
-rw-r--r--src/components/script/dom/attr.rs6
-rw-r--r--src/components/script/dom/attrlist.rs2
-rw-r--r--src/components/script/dom/bindings/callback.rs9
-rw-r--r--src/components/script/dom/bindings/codegen/BindingGen.py49
-rw-r--r--src/components/script/dom/bindings/codegen/Bindings.conf21
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py1603
-rw-r--r--src/components/script/dom/bindings/codegen/GlobalGen.py29
-rw-r--r--src/components/script/dom/bindings/conversions.rs247
-rw-r--r--src/components/script/dom/bindings/js.rs11
-rw-r--r--src/components/script/dom/bindings/proxyhandler.rs9
-rw-r--r--src/components/script/dom/bindings/utils.rs139
-rw-r--r--src/components/script/dom/blob.rs2
-rw-r--r--src/components/script/dom/clientrect.rs2
-rw-r--r--src/components/script/dom/clientrectlist.rs2
-rw-r--r--src/components/script/dom/console.rs2
-rw-r--r--src/components/script/dom/document.rs105
-rw-r--r--src/components/script/dom/domexception.rs2
-rw-r--r--src/components/script/dom/domimplementation.rs2
-rw-r--r--src/components/script/dom/domparser.rs2
-rw-r--r--src/components/script/dom/element.rs35
-rw-r--r--src/components/script/dom/event.rs2
-rw-r--r--src/components/script/dom/eventdispatcher.rs7
-rw-r--r--src/components/script/dom/formdata.rs2
-rw-r--r--src/components/script/dom/htmlcollection.rs80
-rw-r--r--src/components/script/dom/htmldatalistelement.rs1
-rw-r--r--src/components/script/dom/htmlelement.rs6
-rw-r--r--src/components/script/dom/htmlfieldsetelement.rs1
-rw-r--r--src/components/script/dom/htmlformelement.rs1
-rw-r--r--src/components/script/dom/htmlmapelement.rs1
-rw-r--r--src/components/script/dom/location.rs2
-rw-r--r--src/components/script/dom/mouseevent.rs2
-rw-r--r--src/components/script/dom/navigator.rs2
-rw-r--r--src/components/script/dom/node.rs121
-rw-r--r--src/components/script/dom/nodelist.rs8
-rw-r--r--src/components/script/dom/testbinding.rs155
-rw-r--r--src/components/script/dom/uievent.rs2
-rw-r--r--src/components/script/dom/validitystate.rs2
-rw-r--r--src/components/script/dom/webidls/Document.webidl4
-rw-r--r--src/components/script/dom/webidls/Element.webidl1
-rw-r--r--src/components/script/dom/webidls/HTMLCollection.webidl3
-rw-r--r--src/components/script/dom/webidls/Node.webidl21
-rw-r--r--src/components/script/dom/webidls/TestBinding.webidl101
-rw-r--r--src/components/script/dom/window.rs27
-rw-r--r--src/components/script/dom/windowproxy.rs4
44 files changed, 1316 insertions, 1519 deletions
diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs
index 906e1b7f02c..8357665b63d 100644
--- a/src/components/script/dom/attr.rs
+++ b/src/components/script/dom/attr.rs
@@ -43,18 +43,18 @@ impl Attr {
}
}
- pub fn new(window: &Window, local_name: DOMString, value: DOMString) -> JS<Attr> {
+ pub fn new(window: &JS<Window>, local_name: DOMString, value: DOMString) -> JS<Attr> {
let name = local_name.clone();
Attr::new_helper(window, local_name, value, name, Null, None)
}
- pub fn new_ns(window: &Window, local_name: DOMString, value: DOMString,
+ pub fn new_ns(window: &JS<Window>, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace,
prefix: Option<DOMString>) -> JS<Attr> {
Attr::new_helper(window, local_name, value, name, namespace, prefix)
}
- fn new_helper(window: &Window, local_name: DOMString, value: DOMString,
+ fn new_helper(window: &JS<Window>, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace,
prefix: Option<DOMString>) -> JS<Attr> {
let attr = Attr::new_inherited(local_name, value, name, namespace, prefix);
diff --git a/src/components/script/dom/attrlist.rs b/src/components/script/dom/attrlist.rs
index 100f057fe8f..b172e976705 100644
--- a/src/components/script/dom/attrlist.rs
+++ b/src/components/script/dom/attrlist.rs
@@ -27,7 +27,7 @@ impl AttrList {
pub fn new(window: &JS<Window>, elem: &JS<Element>) -> JS<AttrList> {
reflect_dom_object(~AttrList::new_inherited(window.clone(), elem.clone()),
- window.get(), AttrListBinding::Wrap)
+ window, AttrListBinding::Wrap)
}
pub fn Length(&self) -> u32 {
diff --git a/src/components/script/dom/bindings/callback.rs b/src/components/script/dom/bindings/callback.rs
index 10cb35c3af4..b965fcbfb72 100644
--- a/src/components/script/dom/bindings/callback.rs
+++ b/src/components/script/dom/bindings/callback.rs
@@ -3,9 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::utils::Reflectable;
-use js::jsapi::{JSContext, JSObject, JS_WrapObject, JSVal, JS_ObjectIsCallable};
+use js::jsapi::{JSContext, JSObject, JS_WrapObject, JS_ObjectIsCallable};
use js::jsapi::{JS_GetProperty, JSTracer, JS_CallTracer};
-use js::{JSVAL_IS_OBJECT, JSVAL_TO_OBJECT, JSTRACE_OBJECT};
+use js::jsval::JSVal;
+use js::JSTRACE_OBJECT;
use std::cast;
use std::libc;
@@ -66,8 +67,8 @@ impl CallbackInterface {
return false;
}
- if !JSVAL_IS_OBJECT(*callable) ||
- JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(*callable)) == 0 {
+ if !callable.is_object() ||
+ JS_ObjectIsCallable(cx, callable.to_object()) == 0 {
//ThrowErrorMessage(cx, MSG_NOT_CALLABLE, description.get());
return false;
}
diff --git a/src/components/script/dom/bindings/codegen/BindingGen.py b/src/components/script/dom/bindings/codegen/BindingGen.py
index e292427e33b..408280dacfb 100644
--- a/src/components/script/dom/bindings/codegen/BindingGen.py
+++ b/src/components/script/dom/bindings/codegen/BindingGen.py
@@ -10,30 +10,6 @@ import cPickle
import WebIDL
from Configuration import *
from CodegenRust 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 generate_binding_rs(config, outputprefix, webidlfile):
"""
@@ -43,27 +19,23 @@ def generate_binding_rs(config, outputprefix, webidlfile):
filename = outputprefix + ".rs"
root = CGBindingRoot(config, outputprefix, webidlfile)
- root2 = CGBindingRoot(config, outputprefix, webidlfile)
- if replaceFileIfChanged(filename, root.declare() + root2.define()):
- #if replaceFileIfChanged(filename, root.declare()):
+ 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"
+ usagestring = "usage: %prog 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.")
(options, args) = o.parse_args()
- if len(args) != 4 or (args[0] != "header" and args[0] != "cpp" and args[0] != "rs"):
+ if len(args) != 3:
o.error(usagestring)
- buildTarget = args[0]
- configFile = os.path.normpath(args[1])
- outputPrefix = args[2]
- webIDLFile = os.path.normpath(args[3])
+ configFile = os.path.normpath(args[0])
+ outputPrefix = args[1]
+ webIDLFile = os.path.normpath(args[2])
# Load the parsing results
f = open('ParserResults.pkl', 'rb')
@@ -74,14 +46,7 @@ def main():
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);
- elif buildTarget == "rs":
- generate_binding_rs(config, outputPrefix, webIDLFile);
- else:
- assert False # not reached
+ generate_binding_rs(config, outputPrefix, webIDLFile);
if __name__ == '__main__':
main()
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf
index aabb3511bee..369d08bfdf0 100644
--- a/src/components/script/dom/bindings/codegen/Bindings.conf
+++ b/src/components/script/dom/bindings/codegen/Bindings.conf
@@ -26,12 +26,23 @@ DOMInterfaces = {
'Console': {},
'Document': {
'needsAbstract': [
+ 'anchors',
+ 'applets',
'body',
'createComment',
'createDocumentFragment',
'createElement',
'createProcessingInstruction',
'createTextNode',
+ 'embeds',
+ 'forms',
+ 'getElementsByClassName',
+ 'getElementsByTagName',
+ 'getElementsByTagNameNS',
+ 'images',
+ 'links',
+ 'plugins',
+ 'scripts',
'title',
],
},
@@ -43,6 +54,9 @@ DOMInterfaces = {
'attributes',
'getBoundingClientRect',
'getClientRects',
+ 'getElementsByClassName',
+ 'getElementsByTagName',
+ 'getElementsByTagNameNS',
'id',
'innerHTML',
'outerHTML',
@@ -85,10 +99,17 @@ DOMInterfaces = {
'ValidityState': {},
'Window': {
'createGlobal': True,
+ 'needsAbstract': [
+ 'console',
+ 'location',
+ 'navigator',
+ ],
},
'WindowProxy': {},
+'TestBinding': {},
+
}
# FIXME: This should be renamed: https://github.com/mozilla/servo/issues/1625
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 7492723eca4..2162d445c24 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -141,11 +141,9 @@ class CGThing():
"""
def __init__(self):
pass # Nothing for now
- def declare(self):
- """Produce code for a header file."""
- assert(False) # Override me!
+
def define(self):
- """Produce code for a cpp file."""
+ """Produce code for a Rust file."""
assert(False) # Override me!
class CGMethodCall(CGThing):
@@ -290,7 +288,7 @@ class CGMethodCall(CGThing):
# also allow the unwrapping test to skip having to do codegen
# for the null-or-undefined case, which we already handled
# above.
- caseBody.append(CGGeneric("if JSVAL_IS_OBJECT(%s) {" %
+ caseBody.append(CGGeneric("if (%s).is_object() {" %
(distinguishingArg)))
for idx, sig in enumerate(interfacesSigs):
caseBody.append(CGIndenter(CGGeneric("loop {")));
@@ -570,11 +568,11 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
# Handle the non-object cases by wrapping up the whole
# thing in an if cascade.
templateBody = (
- "if JSVAL_IS_OBJECT(${val}) {\n" +
+ "if (${val}).is_object() {\n" +
CGIndenter(CGGeneric(templateBody)).define() + "\n")
if type.nullable():
templateBody += (
- "} else if RUST_JSVAL_IS_NULL(${val}) != 0 || RUST_JSVAL_IS_VOID(${val}) != 0 {\n"
+ "} else if (${val}).is_null_or_undefined() {\n"
" %s;\n" % codeToSetNull)
templateBody += (
"} else {\n" +
@@ -593,303 +591,34 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
raise TypeError("Can't handle array arguments yet")
if type.isSequence():
- assert not isEnforceRange and not isClamp
-
- if failureCode is not None:
- raise TypeError("Can't handle sequences when failureCode is not None")
- nullable = type.nullable();
- # Be very careful not to change "type": we need it later
- if nullable:
- elementType = type.inner.inner
- else:
- elementType = type.inner
-
- # We have to be careful with reallocation behavior for arrays. In
- # particular, if we have a sequence of elements which are themselves
- # sequences (so nsAutoTArrays) or have sequences as members, we have a
- # problem. In that case, resizing the outermost nsAutoTarray to the
- # right size will memmove its elements, but nsAutoTArrays are not
- # memmovable and hence will end up with pointers to bogus memory, which
- # is bad. To deal with this, we disallow sequences, arrays,
- # dictionaries, and unions which contain sequences as sequence item
- # types. If WebIDL ever adds another container type, we'd have to
- # disallow it as well.
- if typeIsSequenceOrHasSequenceMember(elementType):
- raise TypeError("Can't handle a sequence containing another "
- "sequence as an element or member of an element. "
- "See the big comment explaining why.\n%s" %
- str(type.location))
-
- (elementTemplate, elementDeclType,
- elementHolderType, dealWithOptional,
- initialValue) = getJSToNativeConversionTemplate(
- elementType, descriptorProvider, isMember=True)
- if dealWithOptional:
- raise TypeError("Shouldn't have optional things in sequences")
- if elementHolderType is not None:
- raise TypeError("Shouldn't need holders for sequences")
-
- typeName = CGWrapper(elementDeclType, pre="Sequence< ", post=" >")
- if nullable:
- typeName = CGWrapper(typeName, pre="Nullable< ", post=" >")
- arrayRef = "${declName}.Value()"
- else:
- arrayRef = "${declName}"
- # If we're optional, the const will come from the Optional
- mutableTypeName = typeName
- if not isOptional:
- typeName = CGWrapper(typeName, pre="const ")
-
- templateBody = ("""JSObject* seq = &${val}.toObject();\n
-if (!IsArrayLike(cx, seq)) {
- return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
-}
-uint32_t length;
-// JS_GetArrayLength actually works on all objects
-if (!JS_GetArrayLength(cx, seq, &length)) {
- return false;
-}
-Sequence< %s > &arr = const_cast< Sequence< %s >& >(%s);
-if (!arr.SetCapacity(length)) {
- return Throw(cx, NS_ERROR_OUT_OF_MEMORY);
-}
-for (uint32_t i = 0; i < length; ++i) {
- jsval temp;
- if (!JS_GetElement(cx, seq, i, &temp)) {
- return false;
- }
-""" % (elementDeclType.define(),
- elementDeclType.define(),
- arrayRef))
-
- templateBody += CGIndenter(CGGeneric(
- string.Template(elementTemplate).substitute(
- {
- "val" : "temp",
- "valPtr": "&temp",
- "declName" : "(*arr.AppendElement())"
- }
- ))).define()
-
- templateBody += "\n}"
- templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
- type,
- "const_cast< %s & >(${declName}).SetNull()" % mutableTypeName.define())
- return (templateBody, typeName, None, isOptional, None)
+ raise TypeError("Can't handle sequence arguments yet")
if type.isUnion():
if isMember:
raise TypeError("Can't handle unions as members, we have a "
"holderType")
- nullable = type.nullable();
- if nullable:
- type = type.inner
-
- assert(defaultValue is None or
- (isinstance(defaultValue, IDLNullValue) and nullable))
-
- unionArgumentObj = "${holderName}"
- #if isOptional or nullable:
- # unionArgumentObj += ".get_mut_ref()"
-
- memberTypes = type.flatMemberTypes
- names = []
-
- interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
- if len(interfaceMemberTypes) > 0:
- interfaceObject = []
- for memberType in interfaceMemberTypes:
- if type.isGeckoInterface():
- name = memberType.inner.identifier.name
- else:
- name = memberType.name
- interfaceObject.append(CGGeneric("{res = %s.TrySetTo%s(cx, ${val}, ${valPtr}); res.is_err() || !res.unwrap()}" % (unionArgumentObj, name)))
- names.append(name)
- interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"), pre="done = ", post=";\n", reindent=True)
- else:
- interfaceObject = None
-
- arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
- if len(arrayObjectMemberTypes) > 0:
- assert len(arrayObjectMemberTypes) == 1
- memberType = arrayObjectMemberTypes[0]
- name = memberType.name
- arrayObject = CGGeneric("done = {res = %s.TrySetTo%s(cx, ${val}, ${valPtr}); res.is_err() || !res.unwrap()};" % (unionArgumentObj, name))
- # XXX Now we're supposed to check for an array or a platform object
- # that supports indexed properties... skip that last for now. It's a
- # bit of a pain.
- arrayObject = CGWrapper(CGIndenter(arrayObject),
- pre="if (IsArrayLike(cx, &argObj)) {\n",
- post="}")
- names.append(name)
- else:
- arrayObject = None
- dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
- if len(dateObjectMemberTypes) > 0:
- assert len(dateObjectMemberTypes) == 1
- memberType = dateObjectMemberTypes[0]
- name = memberType.name
- dateObject = CGGeneric("%s.SetTo%s(cx, ${val}, ${valPtr});\n"
- "done = true;" % (unionArgumentObj, name))
- dateObject = CGWrapper(CGIndenter(dateObject),
- pre="if (JS_ObjectIsDate(cx, &argObj)) {\n",
- post="\n}")
- names.append(name)
- else:
- dateObject = None
-
- callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
- if len(callbackMemberTypes) > 0:
- assert len(callbackMemberTypes) == 1
- memberType = callbackMemberTypes[0]
- name = memberType.name
- callbackObject = CGGeneric("done = {res = %s.TrySetTo%s(cx, ${val}, ${valPtr}); res.is_err() || !res.unwrap()};" % (unionArgumentObj, name))
- names.append(name)
- else:
- callbackObject = None
-
- dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
- if len(dictionaryMemberTypes) > 0:
- raise TypeError("No support for unwrapping dictionaries as member "
- "of a union")
- else:
- dictionaryObject = None
-
- if callbackObject or dictionaryObject:
- nonPlatformObject = CGList([callbackObject, dictionaryObject], "\n")
- nonPlatformObject = CGWrapper(CGIndenter(nonPlatformObject),
- pre="if (!IsPlatformObject(cx, &argObj)) {\n",
- post="\n}")
- else:
- nonPlatformObject = None
-
- objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
- if len(objectMemberTypes) > 0:
- object = CGGeneric("%s.SetToObject(&argObj);\n"
- "done = true;" % unionArgumentObj)
- else:
- object = None
-
- hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object
- if hasObjectTypes:
- # If we try more specific object types first then we need to check
- # whether that succeeded before converting to object.
- if object and (interfaceObject or arrayObject or dateObject or nonPlatformObject):
- object = CGWrapper(CGIndenter(object), pre="if (!done) {\n",
- post=("\n}"))
-
- if arrayObject or dateObject or nonPlatformObject:
- # An object can be both an array object and not a platform
- # object, but we shouldn't have both in the union's members
- # because they are not distinguishable.
- assert not (arrayObject and nonPlatformObject)
- templateBody = CGList([arrayObject, dateObject, nonPlatformObject], " else ")
- else:
- templateBody = None
- if interfaceObject:
- if templateBody:
- templateBody = CGList([templateBody, object], "\n")
- templateBody = CGWrapper(CGIndenter(templateBody),
- pre="if (!done) {\n", post=("\n}"))
- templateBody = CGList([interfaceObject, templateBody], "\n")
- else:
- templateBody = CGList([templateBody, object], "\n")
-
- if any([arrayObject, dateObject, nonPlatformObject, object]):
- templateBody.prepend(CGGeneric("JSObject& argObj = ${val}.toObject();"))
- templateBody = CGWrapper(CGIndenter(templateBody),
- pre="if JSVAL_IS_OBJECT(${val}) {\n",
- post="\n}")
- else:
- templateBody = CGGeneric()
-
- otherMemberTypes = filter(lambda t: t.isString() or t.isEnum(),
- memberTypes)
- otherMemberTypes.extend(t for t in memberTypes if t.isPrimitive())
- if len(otherMemberTypes) > 0:
- assert len(otherMemberTypes) == 1
- memberType = otherMemberTypes[0]
- if memberType.isEnum():
- name = memberType.inner.identifier.name
- else:
- name = memberType.name
- other = CGGeneric("done = {res = %s.TrySetTo%s(cx, ${val}, ${valPtr}); res.is_err() || !res.unwrap()};" % (unionArgumentObj, name))
- names.append(name)
- if hasObjectTypes:
- other = CGWrapper(CGIndenter(other), "{\n", post="\n}")
- if object:
- join = " else "
- else:
- other = CGWrapper(other, pre="if (!done) ")
- join = "\n"
- templateBody = CGList([templateBody, other], join)
- else:
- other = None
-
- templateBody = CGWrapper(templateBody, pre="let mut done = false;\n"
- "let mut res = Ok(true);\n")
- throw = CGGeneric("if res.is_err() {\n"
- " return 0;\n"
- "}\n"
- "if !done {\n"
- " return throw_not_in_union(cx, \"%s\");\n"
- "}" % ", ".join(names))
- templateBody = CGWrapper(CGIndenter(CGList([templateBody, throw], "\n")), pre="{\n", post="\n}")
-
- typeName = type.name
- argumentTypeName = typeName + "Argument"
- if nullable:
- typeName = "Option<" + typeName + " >"
- nonConstDecl = "${declName}"
-
- def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
- null = CGGeneric("if %s(RUST_JSVAL_IS_NULL(${val}) != 0 || RUST_JSVAL_IS_VOID(${val}) != 0) {\n"
- " %s = None;\n"
- "}" % (extraConditionForNull, setToNullVar))
- templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
- return CGList([null, templateBody], " else ")
+ declType = CGGeneric(type.name)
+ value = CGGeneric("value")
+ if type.nullable():
+ declType = CGWrapper(declType, pre="Option<", post=" >")
+ value = CGWrapper(value, pre="Some(", post=")")
- if type.hasNullableType:
- templateBody = handleNull(templateBody, unionArgumentObj)
+ templateBody = CGGeneric("match %s::from_value(cx, ${val}) {\n"
+ " Err(()) => { %s },\n"
+ " Ok(value) => ${declName} = %s,\n"
+ "}" % (type.name, exceptionCode, value.define()))
- declType = CGGeneric(typeName)
- holderType = CGGeneric(argumentTypeName)
- if isOptional:
- mutableDecl = nonConstDecl + ".Value()"
- declType = CGWrapper(declType, pre="const Optional<", post=" >")
- holderType = CGWrapper(holderType, pre="Option<", post=" >")
- constructDecl = CGGeneric(nonConstDecl + ".Construct();")
- if nullable:
- constructHolder = CGGeneric("${holderName} = Some(%s.SetValue());" % mutableDecl)
- else:
- constructHolder = CGGeneric("${holderName} = Some(${declName}.Value());")
- else:
- mutableDecl = nonConstDecl
- constructDecl = None
- holderInit = "${declName}"
- if nullable:
- holderInit += ".get_mut_ref()"
- else:
- holderInit = "&mut " + holderInit
- constructHolder = CGWrapper(holderType, pre="let mut ${holderName} = ", post="::new(" + holderInit + ");")
- if nullable:
- constructHolder = CGWrapper(constructHolder, pre="${declName} = Some(uninit());\n")
- holderType = None
+ if type.nullable():
+ templateBody = CGIfElseWrapper(
+ "(${val}).is_null_or_undefined()",
+ CGGeneric("${declName} = None;"),
+ templateBody)
- templateBody = CGList([constructHolder, templateBody], "\n")
- if nullable:
- if defaultValue:
- assert(isinstance(defaultValue, IDLNullValue))
- valueMissing = "!(${haveValue}) || "
- else:
- valueMissing = ""
- templateBody = handleNull(templateBody, mutableDecl,
- extraConditionForNull=valueMissing)
- templateBody = CGWrapper(CGIndenter(CGList([constructDecl, templateBody], "\n")),
- pre="{\n", post="\n}")
+ templateBody = handleDefaultNull(templateBody.define(),
+ "${declName} = None")
- return templateBody.define(), declType, holderType, False, "uninit()" if not nullable else None
+ return (templateBody, declType, None, isOptional, "None" if isOptional else None)
if type.isGeckoInterface():
assert not isEnforceRange and not isClamp
@@ -900,39 +629,19 @@ for (uint32_t i = 0; i < length; ++i) {
if descriptor.interface.isCallback():
name = descriptor.nativeType
declType = CGGeneric("Option<%s>" % name);
- conversion = (" ${declName} = Some(%s::new(JSVAL_TO_OBJECT(${val})));\n" % name)
+ conversion = (" ${declName} = Some(%s::new((${val}).to_object()));\n" % name)
template = wrapObjectTemplate(conversion, type,
"${declName} = None",
failureCode)
return (template, declType, None, isOptional, None)
- # This is an interface that we implement as a concrete class
- # or an XPCOM interface.
-
- argIsPointer = type.nullable()
-
# Sequences and callbacks have to hold a strong ref to the thing being
# passed down.
forceOwningType = descriptor.interface.isCallback() or isMember
typePtr = descriptor.nativeType
- # Compute a few things:
- # - declType is the type we want to return as the first element of our
- # tuple.
- # - holderType is the type we want to return as the third element
- # of our tuple.
-
- # Set up some sensible defaults for these things insofar as we can.
- holderType = None
- initialValue = None
- if argIsPointer or isOptional:
- declType = "Option<" + typePtr + ">"
- initialValue = "None"
- else:
- declType = typePtr
-
templateBody = ""
if descriptor.castable:
if descriptor.interface.isConsequential():
@@ -942,17 +651,17 @@ for (uint32_t i = 0; i < length; ++i) {
if failureCode is not None:
templateBody += str(CastableObjectUnwrapper(
descriptor,
- "JSVAL_TO_OBJECT(${val})",
+ "(${val}).to_object()",
"${declName}",
failureCode,
- isOptional or argIsPointer or type.nullable(),
+ isOptional or type.nullable(),
preUnwrapped=preSuccess, postUnwrapped=postSuccess))
else:
templateBody += str(FailureFatalCastableObjectUnwrapper(
descriptor,
- "JSVAL_TO_OBJECT(${val})",
+ "(${val}).to_object()",
"${declName}",
- isOptional or argIsPointer or type.nullable()))
+ isOptional or type.nullable()))
else:
templateBody += (
"match unwrap_value::<" + typePtr + ">(&${val} as *JSVal, "
@@ -969,66 +678,14 @@ for (uint32_t i = 0; i < length; ++i) {
type, "${declName} = None",
failureCode)
- declType = CGGeneric(declType)
- if holderType is not None:
- holderType = CGGeneric(holderType)
- return (templateBody, declType, holderType, isOptional, initialValue)
+ declType = CGGeneric(typePtr)
+ if type.nullable() or isOptional:
+ declType = CGWrapper(declType, pre="Option<", post=">")
+
+ return (templateBody, declType, None, isOptional, "None" if isOptional else None)
if type.isSpiderMonkeyInterface():
- assert not isEnforceRange and not isClamp
- if isMember:
- raise TypeError("Can't handle member arraybuffers or "
- "arraybuffer views because making sure all the "
- "objects are properly rooted is hard")
- name = type.name
- # By default, we use a Maybe<> to hold our typed array. And in the optional
- # non-nullable case we want to pass Optional<TypedArray> to consumers, not
- # Optional<NonNull<TypedArray> >, so jump though some hoops to do that.
- holderType = "Maybe<%s>" % name
- constructLoc = "${holderName}"
- constructMethod = "construct"
- constructInternal = "ref"
- if type.nullable():
- if isOptional:
- declType = "const Optional<" + name + "*>"
- else:
- declType = name + "*"
- else:
- if isOptional:
- declType = "const Optional<" + name + ">"
- # We don't need a holder in this case
- holderType = None
- constructLoc = "(const_cast<Optional<" + name + ">& >(${declName}))"
- constructMethod = "Construct"
- constructInternal = "Value"
- else:
- declType = "NonNull<" + name + ">"
- template = (
- "%s.%s(cx, &${val}.toObject());\n"
- "if (!%s.%s().inited()) {\n"
- "%s" # No newline here because onFailureBadType() handles that
- "}\n" %
- (constructLoc, constructMethod, constructLoc, constructInternal,
- CGIndenter(onFailureBadType(failureCode, type.name)).define()))
- nullableTarget = ""
- if type.nullable():
- if isOptional:
- mutableDecl = "(const_cast<Optional<" + name + "*>& >(${declName}))"
- template += "%s.Construct();\n" % mutableDecl
- nullableTarget = "%s.Value()" % mutableDecl
- else:
- nullableTarget = "${declName}"
- template += "%s = ${holderName}.addr();" % nullableTarget
- elif not isOptional:
- template += "${declName} = ${holderName}.addr();"
- template = wrapObjectTemplate(template, isDefinitelyObject, type,
- "%s = NULL" % nullableTarget,
- failureCode)
-
- if holderType is not None:
- holderType = CGGeneric(holderType)
- # We handle all the optional stuff ourselves; no need for caller to do it.
- return (template, CGGeneric(declType), holderType, False, None)
+ raise TypeError("Can't handle SpiderMonkey interface arguments yet")
if type.isString():
assert not isEnforceRange and not isClamp
@@ -1039,43 +696,48 @@ for (uint32_t i = 0; i < length; ++i) {
}
if treatNullAs not in treatAs:
raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs)
- nullBehavior = treatAs[treatNullAs]
+ if type.nullable():
+ nullBehavior = "()"
+ else:
+ nullBehavior = treatAs[treatNullAs]
- def getConversionCode(varName, isOptional=False):
+ def getConversionCode(isOptional=False):
strval = "strval"
if isOptional:
strval = "Some(%s)" % strval
- if type.nullable():
- call = "jsval_to_domstring(cx, ${val})"
- else:
- call = "jsval_to_str(cx, ${val}, %s)" % nullBehavior
+
conversionCode = (
- "let strval = %s;\n"
- "if strval.is_err() {\n"
- " return 0;\n"
- "}\n"
- "let strval = strval.unwrap();\n"
- "%s = %s;" % (call, varName, strval))
+ "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n"
+ " Ok(strval) => ${declName} = %s,\n"
+ " Err(_) => return 0,\n"
+ "}" % (nullBehavior, strval))
+
if defaultValue is None:
return conversionCode
if isinstance(defaultValue, IDLNullValue):
assert(type.nullable())
return handleDefault(conversionCode,
- "%s.SetNull()" % varName)
- return handleDefault(
- conversionCode,
- ("static data: [u8, ..%s] = [ %s ];\n"
- "%s = str::from_utf8(data).to_owned()" %
- (len(defaultValue.value) + 1,
- ", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]),
- varName)))
+ "${declName}.SetNull()")
+
+ value = "str::from_utf8(data).to_owned()"
+ if type.nullable():
+ value = "Some(%s)" % value
+
+ default = (
+ "static data: [u8, ..%s] = [ %s ];\n"
+ "${declName} = %s" %
+ (len(defaultValue.value) + 1,
+ ", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]),
+ value))
+
+ return handleDefault(conversionCode, default)
if isMember:
# We have to make a copy, because our jsval may well not
# live as long as our string needs to.
declType = CGGeneric("DOMString")
- return ("%s\n" % getConversionCode("${declName}"),
+ return ("%s\n" % getConversionCode(),
declType, None, isOptional, None)
declType = "DOMString"
@@ -1089,8 +751,7 @@ for (uint32_t i = 0; i < length; ++i) {
return (
"%s\n" %
- #"const_cast<%s&>(${declName}) = &${holderName};" %
- (getConversionCode("${declName}", isOptional)),
+ (getConversionCode(isOptional)),
CGGeneric(declType), None, #CGGeneric("FakeDependentString"),
False,
initialValue)
@@ -1156,26 +817,21 @@ for (uint32_t i = 0; i < length; ++i) {
if isMember:
raise TypeError("Can't handle member 'any'; need to sort out "
"rooting issues")
- templateBody = "${declName} = ${val};"
+
+ declType = CGGeneric("JSVal")
+ value = CGGeneric("${val}")
+ if isOptional:
+ declType = CGWrapper(declType, pre="Option<", post=">")
+ value = CGWrapper(value, pre="Some(", post=")")
+
+ templateBody = "${declName} = %s;" % value.define()
templateBody = handleDefaultNull(templateBody,
- "${declName} = JSVAL_NULL")
- return (templateBody, CGGeneric("JSVal"), None, isOptional, "JSVAL_NULL")
+ "${declName} = NullValue()")
- if type.isObject():
- assert not isEnforceRange and not isClamp
+ return (templateBody, declType, None, isOptional, "None" if isOptional else None)
- if isMember:
- raise TypeError("Can't handle member 'object'; need to sort out "
- "rooting issues")
- template = wrapObjectTemplate("${declName} = &${val}.toObject();",
- isDefinitelyObject, type,
- "${declName} = NULL",
- failureCode)
- if type.nullable():
- declType = CGGeneric("JSObject*")
- else:
- declType = CGGeneric("NonNull<JSObject>")
- return (template, declType, None, isOptional, None)
+ if type.isObject():
+ raise TypeError("Can't handle object arguments yet")
if type.isDictionary():
if failureCode is not None:
@@ -1201,7 +857,7 @@ for (uint32_t i = 0; i < length; ++i) {
# actually do want a jsval, and we only handle null anyway
if defaultValue is not None:
assert(isinstance(defaultValue, IDLNullValue))
- val = "if ${haveValue} { ${val} } else { JSVAL_NULL }"
+ val = "if ${haveValue} { ${val} } else { NullValue() }"
else:
val = "${val}"
@@ -1232,54 +888,42 @@ for (uint32_t i = 0; i < length; ++i) {
if failureCode is None:
failureCode = 'return 0'
+ successVal = "v"
+ if preSuccess or postSuccess:
+ successVal = preSuccess + successVal + postSuccess
+ #XXXjdm support conversionBehavior here
+ template = (
+ "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
+ " Ok(v) => ${declName} = %s,\n"
+ " Err(_) => { %s }\n"
+ "}" % (successVal, exceptionCode))
+
if type.nullable():
- dataLoc = "${declName}.SetValue()"
- nullCondition = "(RUST_JSVAL_IS_NULL(${val}) != 0 || RUST_JSVAL_IS_VOID(${val}) != 0)"
- if defaultValue is not None and isinstance(defaultValue, IDLNullValue):
- nullCondition = "!(${haveValue}) || " + nullCondition
- successVal = "val_"
- if preSuccess or postSuccess:
- successVal = preSuccess + successVal + postSuccess
- #XXXjdm support conversionBehavior here
- template = (
- "if (%s) {\n"
- " ${declName} = None;\n"
- "} else {\n"
- " match JSValConvertible::from_jsval(cx, ${val}) {\n"
- " Some(val_) => ${declName} = Some(%s),\n"
- " None => %s\n"
- " }\n"
- "}" % (nullCondition, successVal, failureCode))
declType = CGGeneric("Option<" + typeName + ">")
else:
- assert(defaultValue is None or
- not isinstance(defaultValue, IDLNullValue))
- dataLoc = "${declName}"
- #XXXjdm conversionBehavior should be used
- successVal = "v"
- if preSuccess or postSuccess:
- successVal = preSuccess + successVal + postSuccess
- template = (
- "match JSValConvertible::from_jsval(cx, ${val}) {\n"
- " None => %s,\n"
- " Some(v) => %s = %s\n"
- "}" % (failureCode, dataLoc, successVal))
declType = CGGeneric(typeName)
- if (defaultValue is not None and
- # We already handled IDLNullValue, so just deal with the other ones
- not isinstance(defaultValue, IDLNullValue)):
- tag = defaultValue.type.tag()
- if tag in numericTags:
- defaultStr = defaultValue.value
+
+ if defaultValue is not None:
+ if isinstance(defaultValue, IDLNullValue):
+ assert type.nullable()
+ defaultStr = "None"
else:
- assert(tag == IDLType.Tags.bool)
- defaultStr = toStringBool(defaultValue.value)
+ tag = defaultValue.type.tag()
+ if tag in numericTags:
+ defaultStr = defaultValue.value
+ else:
+ assert(tag == IDLType.Tags.bool)
+ defaultStr = toStringBool(defaultValue.value)
+
+ if type.nullable():
+ defaultStr = "Some(%s)" % defaultStr
+
template = CGWrapper(CGIndenter(CGGeneric(template)),
pre="if ${haveValue} {\n",
post=("\n"
"} else {\n"
- " %s = %s;\n"
- "}" % (dataLoc, defaultStr))).define()
+ " ${declName} = %s;\n"
+ "}" % defaultStr)).define()
initialVal = "false" if typeName == "bool" else ("0 as %s" % typeName)
if type.nullable():
@@ -1468,94 +1112,20 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
return ("${jsvalRef} = %s;\n" +
tail) % (value)
- def wrapAndSetPtr(wrapCall, failureCode=None):
- """
- Returns the code to set the jsval by calling "wrapCall". "failureCode"
- is the code to run if calling "wrapCall" fails
- """
- if failureCode is None:
- if not haveSuccessCode:
- return wrapCall + ";\n" + "return if (*vp).v != 0 { 1 } else { 0 };"
- failureCode = "return 0;"
- str = ("if !(%s != 0) {\n" +
- CGIndenter(CGGeneric(failureCode)).define() + "\n" +
- "}\n" +
- successCode) % (wrapCall)
- return str
-
if type is None or type.isVoid():
- return (setValue("JSVAL_VOID"), True)
+ return (setValue("UndefinedValue()"), True)
if type.isArray():
raise TypeError("Can't handle array return values yet")
if type.isSequence():
- if type.nullable():
- # Nullable sequences are Nullable< nsTArray<T> >
- (recTemplate, recInfall) = getWrapTemplateForType(type.inner, descriptorProvider,
- "%s.Value()" % result, successCode,
- isCreator, exceptionCode)
- return ("""
-if (%s.IsNull()) {
-%s
-}
-%s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(), recTemplate), recInfall)
-
- # Now do non-nullable sequences. We use setting the element
- # in the array as our succcess code because when we succeed in
- # wrapping that's what we should do.
- innerTemplate = wrapForType(
- type.inner, descriptorProvider,
- {
- 'result' : "%s[i]" % result,
- 'successCode': ("if (!JS_DefineElement(cx, returnArray, i, tmp,\n"
- " NULL, NULL, JSPROP_ENUMERATE)) {\n"
- " return false;\n"
- "}"),
- 'jsvalRef': "tmp",
- 'jsvalPtr': "&tmp",
- 'isCreator': isCreator
- }
- )
- innerTemplate = CGIndenter(CGGeneric(innerTemplate)).define()
- return (("""
-uint32_t length = %s.Length();
-JSObject *returnArray = JS_NewArrayObject(cx, length, NULL);
-if (!returnArray) {
- return false;
-}
-jsval tmp;
-for (uint32_t i = 0; i < length; ++i) {
-%s
-}\n""" % (result, innerTemplate)) + setValue("JS::ObjectValue(*returnArray)"), False)
+ raise TypeError("Can't handle sequence return values yet")
if type.isGeckoInterface():
- descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
- if type.nullable():
- wrappingCode = ("if %s.is_none() {\n" % (result) +
- CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
- "}\n" +
- "let mut %s = %s.unwrap();\n" % (result, result))
- else:
- wrappingCode = ""
- if not descriptor.interface.isCallback():
- wrap = "GetReflector(cx, (%s).reflector(), ${jsvalPtr} as *mut JSVal)" % result
- # Non-prefable bindings can only fail to wrap as a new-binding object
- # if they already threw an exception. Same thing for
- # non-prefable bindings.
- failed = ("assert!(unsafe { JS_IsExceptionPending(cx) != 0 });\n" +
- "%s" % exceptionCode)
- wrappingCode += wrapAndSetPtr(wrap, failed)
- else:
- wrap = "GetReflector(cx, (%s).reflector(), ${jsvalPtr} as *mut JSVal)" % result
- wrappingCode += wrapAndSetPtr(wrap)
- return (wrappingCode, False)
+ return (setValue("(%s).to_jsval(cx)" % result), True)
if type.isString():
- if type.nullable():
- return (wrapAndSetPtr("*${jsvalPtr} = domstring_to_jsval(cx, %s)" % result), False)
- else:
- return (wrapAndSetPtr("*${jsvalPtr} = str_to_jsval(cx, %s)" % result), False)
+ return (setValue("(%s).to_jsval(cx)" % result), True)
if type.isEnum():
if type.nullable():
@@ -1569,7 +1139,7 @@ if %(resultStr)s.is_null() {
""" % { "result" : result,
"resultStr" : result + "_str",
"strings" : type.inner.identifier.name + "Values::strings" } +
- setValue("RUST_STRING_TO_JSVAL(%s_str)" % result), False)
+ setValue("StringValue(&*(%s_str))" % result), False)
if type.isCallback():
assert not type.isInterface()
@@ -1590,43 +1160,17 @@ if %(resultStr)s.is_null() {
# See comments in WrapNewBindingObject explaining why we need
# to wrap here.
if type.nullable():
- toValue = "RUST_OBJECT_TO_JSVAL(%s)"
+ toValue = "ObjectOrNullValue(%s)"
else:
- toValue = "RUST_OBJECT_TO_JSVAL(%s)"
+ toValue = "ObjectValue(&*(%s))"
# NB: setValue(..., True) calls JS_WrapValue(), so is fallible
return (setValue(toValue % result, True), False)
if not type.isPrimitive():
raise TypeError("Need to learn to wrap %s" % type)
- if type.nullable():
- (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider,
- "%s.Value()" % result, successCode,
- isCreator, exceptionCode)
- return ("if (%s.IsNull()) {\n" % result +
- CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
- "}\n" + recTemplate, recInfal)
-
- tag = type.tag()
-
- if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
- IDLType.Tags.uint16, IDLType.Tags.int32]:
- return (setValue("RUST_INT_TO_JSVAL(%s as i32)" % result), True)
-
- elif tag in [IDLType.Tags.int64, IDLType.Tags.uint64, IDLType.Tags.float,
- IDLType.Tags.double]:
- # XXXbz will cast to double do the "even significand" thing that webidl
- # calls for for 64-bit ints? Do we care?
- return (setValue("RUST_JS_NumberValue(%s as f64)" % result), True)
+ return (setValue("(%s).to_jsval(cx)" % result), True)
- elif tag == IDLType.Tags.uint32:
- return (setValue("RUST_UINT_TO_JSVAL(%s)" % result), True)
-
- elif tag == IDLType.Tags.bool:
- return (setValue("RUST_BOOLEAN_TO_JSVAL(%s as JSBool)" % result), True)
-
- else:
- raise TypeError("Need to learn to wrap primitive: %s" % type)
def wrapForType(type, descriptorProvider, templateValues):
"""
@@ -1685,7 +1229,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.isPrimitive() and returnType.tag() in builtinNames:
result = CGGeneric(builtinNames[returnType.tag()])
if returnType.nullable():
- result = CGWrapper(result, pre="Nullable<", post=">")
+ result = CGWrapper(result, pre="Option<", post=">")
return result, False
if returnType.isString():
result = CGGeneric("DOMString")
@@ -1712,17 +1256,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.isObject() or returnType.isSpiderMonkeyInterface():
return CGGeneric("*JSObject"), False
if returnType.isSequence():
- nullable = returnType.nullable()
- if nullable:
- returnType = returnType.inner
- # If our result is already addrefed, use the right type in the
- # sequence argument here.
- (result, _) = getRetvalDeclarationForType(returnType.inner,
- descriptorProvider)
- result = CGWrapper(result, pre="nsTArray< ", post=" >")
- if nullable:
- result = CGWrapper(result, pre="Nullable< ", post=" >")
- return result, True
+ raise TypeError("We don't support sequence return values")
+
raise TypeError("Don't know how to declare return value for %s" %
returnType)
@@ -2038,9 +1573,7 @@ class CGNativePropertyHooks(CGThing):
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
- def declare(self):
- #return "extern const NativePropertyHooks NativeHooks;\n"
- return ""
+
def define(self):
if self.descriptor.concrete and self.descriptor.proxy:
resolveOwnProperty = "ResolveOwnProperty"
@@ -2063,20 +1596,14 @@ class CGIndenter(CGThing):
A class that takes another CGThing and generates code that indents that
CGThing by some number of spaces. The default indent is two spaces.
"""
- def __init__(self, child, indentLevel=2, declareOnly=False):
+ def __init__(self, child, indentLevel=2):
CGThing.__init__(self)
self.child = child
self.indent = " " * indentLevel
- self.declareOnly = declareOnly
- def declare(self):
- decl = self.child.declare()
- if decl is not "":
- return re.sub(lineStartDetector, self.indent, decl)
- else:
- return ""
+
def define(self):
defn = self.child.define()
- if defn is not "" and not self.declareOnly:
+ if defn is not "":
return re.sub(lineStartDetector, self.indent, defn)
else:
return defn
@@ -2085,62 +1612,49 @@ class CGWrapper(CGThing):
"""
Generic CGThing that wraps other CGThings with pre and post text.
"""
- def __init__(self, child, pre="", post="", declarePre=None,
- declarePost=None, definePre=None, definePost=None,
- declareOnly=False, defineOnly=False, reindent=False):
+ def __init__(self, child, pre="", post="", reindent=False):
CGThing.__init__(self)
self.child = child
- self.declarePre = declarePre or pre
- self.declarePost = declarePost or post
- self.definePre = definePre or pre
- self.definePost = definePost or post
- self.declareOnly = declareOnly
- self.defineOnly = defineOnly
+ self.pre = pre
+ self.post = post
self.reindent = reindent
- def declare(self):
- if self.defineOnly:
- return ''
- decl = self.child.declare()
- if self.reindent:
- # We don't use lineStartDetector because we don't want to
- # insert whitespace at the beginning of our _first_ line.
- decl = stripTrailingWhitespace(
- decl.replace("\n", "\n" + (" " * len(self.declarePre))))
- return self.declarePre + decl + self.declarePost
+
def define(self):
- if self.declareOnly:
- return ''
defn = self.child.define()
if self.reindent:
# We don't use lineStartDetector because we don't want to
# insert whitespace at the beginning of our _first_ line.
defn = stripTrailingWhitespace(
- defn.replace("\n", "\n" + (" " * len(self.definePre))))
- return self.definePre + defn + self.definePost
+ defn.replace("\n", "\n" + (" " * len(self.pre))))
+ return self.pre + defn + self.post
class CGImports(CGWrapper):
"""
Generates the appropriate import/use statements.
"""
- def __init__(self, descriptors, dictionaries, declareImports, defineImports, child):
+ def __init__(self, child, imports):
"""
- Builds a set of imports to cover |descriptors|.
-
- Also includes the files in |declareIncludes| in the header
- file and the files in |defineIncludes| in the .cpp.
+ Adds a set of imports.
"""
+ ignored_warnings = [
+ # Allow unreachable_code because we use 'break' in a way that
+ # sometimes produces two 'break's in a row. See for example
+ # CallbackMember.getArgConversions.
+ 'unreachable_code',
+ 'non_uppercase_statics',
+ 'unused_imports',
+ 'unused_variable',
+ 'unused_unsafe',
+ 'unused_mut',
+ 'dead_assignment',
+ 'dead_code',
+ ]
+
+ statements = ['#[allow(%s)];' % ','.join(ignored_warnings)]
+ statements.extend('use %s;' % i for i in sorted(imports))
- # TODO imports to cover descriptors, etc.
-
- def _useString(imports):
- # Allow unreachable_code because we use 'break' in a way that sometimes produces
- # two 'break's in a row. See for example CallbackMember.getArgConversions.
- return '\n'.join([
- '#[allow(unreachable_code,non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut,dead_assignment,dead_code)];',
- ''.join('use %s;\n' % i for i in imports),
- ''])
CGWrapper.__init__(self, child,
- declarePre=_useString(sorted(declareImports)))
+ pre='\n'.join(statements) + '\n\n')
@staticmethod
def getDeclarationFilename(decl):
@@ -2157,23 +1671,20 @@ class CGIfWrapper(CGWrapper):
post="\n}")
class CGNamespace(CGWrapper):
- def __init__(self, namespace, child, declareOnly=False, public=False):
+ def __init__(self, namespace, child, public=False):
pre = "%smod %s {\n" % ("pub " if public else "", namespace)
post = "} // mod %s\n" % namespace
- CGWrapper.__init__(self, child, pre=pre, post=post,
- declareOnly=declareOnly)
+ CGWrapper.__init__(self, child, pre=pre, post=post)
+
@staticmethod
- def build(namespaces, child, declareOnly=False, public=False):
+ def build(namespaces, child, public=False):
"""
Static helper method to build multiple wrapped namespaces.
"""
if not namespaces:
- return CGWrapper(child, declareOnly=declareOnly)
- inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly, public=public)
- return CGNamespace(namespaces[0], inner, declareOnly=declareOnly, public=public)
-
- def declare(self):
- return ""
+ return child
+ inner = CGNamespace.build(namespaces[1:], child, public=public)
+ return CGNamespace(namespaces[0], inner, public=public)
def DOMClass(descriptor):
protoList = ['PrototypeList::id::' + proto for proto in descriptor.prototypeChain]
@@ -2196,9 +1707,7 @@ class CGDOMJSClass(CGThing):
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
- def declare(self):
- #return "extern DOMJSClass Class;\n"
- return ""
+
def define(self):
traceHook = "Some(%s)" % TRACE_HOOK_NAME
if self.descriptor.createGlobal:
@@ -2250,9 +1759,7 @@ class CGPrototypeJSClass(CGThing):
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
- def declare(self):
- # We're purely for internal consumption
- return ""
+
def define(self):
return """
static PrototypeClassName__: [u8, ..%s] = %s;
@@ -2288,9 +1795,7 @@ class CGInterfaceObjectJSClass(CGThing):
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
- def declare(self):
- # We're purely for internal consumption
- return ""
+
def define(self):
if True:
return ""
@@ -2331,23 +1836,28 @@ class CGList(CGThing):
self.children.insert(0, child)
def join(self, generator):
return self.joiner.join(filter(lambda s: len(s) > 0, (child for child in generator)))
- def declare(self):
- return self.join(child.declare() for child in self.children if child is not None)
+
def define(self):
return self.join(child.define() for child in self.children if child is not None)
+
+class CGIfElseWrapper(CGList):
+ def __init__(self, condition, ifTrue, ifFalse):
+ kids = [ CGIfWrapper(ifTrue, condition),
+ CGWrapper(CGIndenter(ifFalse), pre=" else {\n", post="\n}") ]
+ CGList.__init__(self, kids)
+
+
class CGGeneric(CGThing):
"""
A class that spits out a fixed string into the codegen. Can spit out a
separate string for the declaration too.
"""
- def __init__(self, define="", declare=""):
- self.declareText = declare
- self.defineText = define
- def declare(self):
- return self.declareText
+ def __init__(self, text):
+ self.text = text
+
def define(self):
- return self.defineText
+ return self.text
def getTypes(descriptor):
"""
@@ -2486,22 +1996,17 @@ class CGAbstractMethod(CGThing):
alwaysInline should be True to generate an inline method annotated with
MOZ_ALWAYS_INLINE.
- static should be True to generate a static method, which only has
- a definition.
-
If templateArgs is not None it should be a list of strings containing
template arguments, and the function will be templatized using those
arguments.
"""
- def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, static=False, extern=False, pub=False, templateArgs=None, unsafe=True):
+ def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, extern=False, pub=False, templateArgs=None, unsafe=True):
CGThing.__init__(self)
self.descriptor = descriptor
self.name = name
self.returnType = returnType
self.args = args
- self.inline = inline
self.alwaysInline = alwaysInline
- self.static = static
self.extern = extern
self.templateArgs = templateArgs
self.pub = pub;
@@ -2512,44 +2017,32 @@ class CGAbstractMethod(CGThing):
if self.templateArgs is None:
return ''
return '<%s>\n' % ', '.join(self.templateArgs)
+
def _decorators(self):
decorators = []
if self.alwaysInline:
decorators.append('#[inline(always)]')
- elif self.inline:
- #decorators.append('inline')
- pass
+
if self.extern:
decorators.append('extern')
- if not self.extern:
- pass
- if self.static:
- #decorators.append('static')
- pass
+
if self.pub:
decorators.append('pub')
+
if not decorators:
return ''
- #maybeNewline = " " if self.inline else "\n"
- maybeNewline = " "
- return ' '.join(decorators) + maybeNewline
+ return ' '.join(decorators) + ' '
+
def _returnType(self):
return (" -> %s" % self.returnType) if self.returnType != "void" else ""
def _unsafe_open(self):
return "\n unsafe {" if self.unsafe else ""
def _unsafe_close(self):
return "\n }\n" if self.unsafe else ""
- def declare(self):
- if self.inline:
- return self._define()
- #return "%sfn %s%s(%s)%s;\n" % (self._decorators(), self.name, self._template(),
- # self._argstring(), self._returnType())
- return ""
- def _define(self, fromDeclare=False):
+ def define(self, fromDeclare=False):
return self.definition_prologue(fromDeclare) + "\n" + self.definition_body() + self.definition_epilogue()
- def define(self):
- return "" if self.inline else self._define()
+
def definition_prologue(self, fromDeclare):
return "%sfn %s%s(%s)%s {%s" % (self._decorators(), self.name, self._template(),
self._argstring(fromDeclare), self._returnType(), self._unsafe_open())
@@ -2569,12 +2062,11 @@ def CreateBindingJSObject(descriptor, parent=None):
if descriptor.proxy:
assert not descriptor.createGlobal
handler = """
- let page = page_from_context(aCx);
- let mut js_info = (*page).js_info();
+ let js_info = aScope.get().page().js_info();
let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint));
""" % descriptor.name
create += handler + """ let obj = NewProxyObject(aCx, *handler,
- ptr::to_unsafe_ptr(&RUST_PRIVATE_TO_JSVAL(squirrel_away_unique(aObject) as *libc::c_void)),
+ ptr::to_unsafe_ptr(&PrivateValue(squirrel_away_unique(aObject) as *libc::c_void)),
proto, %s,
ptr::null(), ptr::null());
if obj.is_null() {
@@ -2592,25 +2084,30 @@ def CreateBindingJSObject(descriptor, parent=None):
}
JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32,
- RUST_PRIVATE_TO_JSVAL(squirrel_away_unique(aObject) as *libc::c_void));
+ PrivateValue(squirrel_away_unique(aObject) as *libc::c_void));
"""
return create
-class CGWrapWithCacheMethod(CGAbstractMethod):
+class CGWrapMethod(CGAbstractMethod):
def __init__(self, descriptor):
assert descriptor.interface.hasInterfacePrototypeObject()
- args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'),
- Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)]
- CGAbstractMethod.__init__(self, descriptor, 'Wrap_', '*JSObject', args)
+ if not descriptor.createGlobal:
+ args = [Argument('*JSContext', 'aCx'), Argument('&JS<Window>', 'aScope'),
+ Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)]
+ else:
+ args = [Argument('*JSContext', 'aCx'),
+ Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)]
+ CGAbstractMethod.__init__(self, descriptor, 'Wrap', '*JSObject', args, pub=True)
def definition_body(self):
if not self.descriptor.createGlobal:
return """
- assert!(aScope.is_not_null());
- assert!(((*JS_GetClass(aScope)).flags & JSCLASS_IS_GLOBAL) != 0);
+ let scope = aScope.reflector().get_jsobject();
+ assert!(scope.is_not_null());
+ assert!(((*JS_GetClass(scope)).flags & JSCLASS_IS_GLOBAL) != 0);
- //JSAutoCompartment ac(aCx, aScope);
- let proto = GetProtoObject(aCx, aScope, aScope);
+ //JSAutoCompartment ac(aCx, scope);
+ let proto = GetProtoObject(aCx, scope, scope);
if proto.is_null() {
return ptr::null();
}
@@ -2619,28 +2116,15 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
(*raw).mut_reflector().set_jsobject(obj);
- return obj;""" % CreateBindingJSObject(self.descriptor, "aScope")
+ return obj;""" % CreateBindingJSObject(self.descriptor, "scope")
else:
return """
- assert!(aScope.is_null());
-
%s
let proto = GetProtoObject(aCx, obj, obj);
JS_SetPrototype(aCx, obj, proto);
(*raw).mut_reflector().set_jsobject(obj);
return obj;""" % CreateBindingJSObject(self.descriptor)
-class CGWrapMethod(CGAbstractMethod):
- def __init__(self, descriptor):
- # XXX can we wrap if we don't have an interface prototype object?
- assert descriptor.interface.hasInterfacePrototypeObject()
- args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'),
- Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)]
- CGAbstractMethod.__init__(self, descriptor, 'Wrap', '*JSObject', args, inline=True, pub=True)
-
- def definition_body(self):
- return "return Wrap_(aCx, aScope, aObject);"
-
class CGAbstractExternMethod(CGAbstractMethod):
"""
Abstract base class for codegen of implementation-only (no
@@ -2649,9 +2133,6 @@ class CGAbstractExternMethod(CGAbstractMethod):
def __init__(self, descriptor, name, returnType, args):
CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
inline=False, extern=True)
- def declare(self):
- # We only have implementation
- return ""
class PropertyArrays():
def __init__(self, descriptor):
@@ -2709,38 +2190,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
# if we don't need to create anything, why are we generating this?
assert needInterfaceObject or needInterfacePrototypeObject
- idsToInit = []
- if False: #XXXjdm don't need xray stuff yet
- for var in self.properties.xrayRelevantArrayNames():
- props = getattr(self.properties, var)
- # We only have non-chrome ids to init if we have no chrome ids.
- if props.hasChromeOnly():
- idsToInit.append(props.variableName(True))
- elif props.hasNonChromeOnly():
- idsToInit.append(props.variableName(False))
- if len(idsToInit) > 0:
- setup = CGList([CGGeneric("let page = page_from_context(aCx);"),
- CGList([CGGeneric("let mut js_info = (*page).js_info();\n"
- "let %s_ids_mut = js_info.get().get_ref().dom_static.attribute_ids.get(&(PrototypeList::id::%s as uint));" % (varname, self.descriptor.name)) for varname in idsToInit], '\n')], '\n')
- initIds = CGList(
- [CGGeneric("!InitIds(aCx, %s, *%s_ids_mut)" % (varname, varname)) for
- varname in idsToInit], ' ||\n')
- if len(idsToInit) > 1:
- initIds = CGWrapper(initIds, pre="(", post=")", reindent=True)
- initIds = CGList(
- [CGGeneric("%s_ids_mut[0] == JSID_VOID &&" % idsToInit[0]), initIds],
- "\n")
- initIds = CGWrapper(initIds, pre="if ", post=" {", reindent=True)
- initIds = CGList(
- [setup,
- initIds,
- CGGeneric((" %s_ids_mut[0] = JSID_VOID;\n"
- " return ptr::null();") % idsToInit[0]),
- CGGeneric("}")],
- "\n")
- else:
- initIds = None
-
prefCacheData = []
for var in self.properties.arrayNames():
props = getattr(self.properties, var)
@@ -2807,7 +2256,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
chrome = None
functionBody = CGList(
- [CGGeneric(getParentProto), initIds, prefCache, chrome,
+ [CGGeneric(getParentProto), prefCache, chrome,
CGGeneric(call % self.properties.variableNames(False))],
"\n\n")
#return CGIndenter(CGWrapper(functionBody, pre="/*", post="*/return ptr::null()")).define()
@@ -2822,7 +2271,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aGlobal'),
Argument('*JSObject', 'aReceiver')]
CGAbstractMethod.__init__(self, descriptor, name,
- '*JSObject', args, inline=True, pub=pub)
+ '*JSObject', args, pub=pub)
self.id = idPrefix + "id::" + self.descriptor.name
def definition_body(self):
return """
@@ -2881,10 +2330,6 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
args = [Argument('&mut JSPageInfo', 'js_info')]
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'bool', args, pub=True)
- def declare(self):
- #return CGAbstractMethod.declare(self)
- return ""
-
def define(self):
return CGAbstractMethod.define(self)
@@ -3272,18 +2717,6 @@ class CGGenericMethod(CGAbstractBindingMethod):
"let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n"
"return CallJitMethodOp(_info, cx, obj, this as *libc::c_void, argc, &*vp);"))
-class CGAbstractStaticMethod(CGAbstractMethod):
- """
- Abstract base class for codegen of implementation-only (no
- declaration) static methods.
- """
- def __init__(self, descriptor, name, returnType, args):
- CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
- inline=False, static=True)
- def declare(self):
- # We only have implementation
- return ""
-
class CGSpecializedMethod(CGAbstractExternMethod):
"""
A class for generating the C++ code for a specialized method that the JIT
@@ -3394,7 +2827,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
def generate_code(self):
return CGIndenter(CGGeneric(
- "let undef = JSVAL_VOID;\n"
+ "let undef = UndefinedValue();\n"
"let argv: *JSVal = if argc != 0 { JS_ARGV(cx, vp as *JSVal) } else { &undef as *JSVal };\n"
"let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp as *JSVal));\n"
"let ok = with_gc_disabled(cx, || {\n"
@@ -3403,7 +2836,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
"if ok == 0 {\n"
" return 0;\n"
"}\n"
- "*vp = JSVAL_VOID;\n"
+ "*vp = UndefinedValue();\n"
"return 1;"))
class CGSpecializedSetter(CGAbstractExternMethod):
@@ -3458,9 +2891,6 @@ class CGMemberJITInfo(CGThing):
self.member = member
self.descriptor = descriptor
- def declare(self):
- return ""
-
def defineJitInfo(self, infoName, opName, infallible):
protoID = "PrototypeList::id::%s as u32" % self.descriptor.name
depth = self.descriptor.interface.inheritanceDepth()
@@ -3534,9 +2964,6 @@ class CGEnum(CGThing):
CGThing.__init__(self)
self.enum = enum
- def declare(self):
- return ""
-
def define(self):
return """
#[repr(uint)]
@@ -3654,176 +3081,178 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
name = type.name
typeName = "/*" + type.name + "*/"
- tryNextCode = """{
- return Ok(true);
-}"""
(template, declType, holderType,
dealWithOptional, initialValue) = getJSToNativeConversionTemplate(
- type, descriptorProvider, failureCode=tryNextCode,
- isDefinitelyObject=True, isOptional=type.nullable(), preSuccess="e" + name + "(", postSuccess=")")
+ type, descriptorProvider, failureCode="return Ok(None);",
+ exceptionCode='return Err(());',
+ isDefinitelyObject=True, isOptional=False)
structType = declType.define()
externalType = getUnionAccessorSignatureType(type, descriptorProvider).define()
- if type.isObject():
- setter = CGGeneric("pub fn SetToObject(obj: *JSObject) {\n"
- " mUnion = Some(eObject(obj));\n"
- "}")
- else:
- jsConversion = string.Template(template).substitute(
- {
- "val": "value",
- "valPtr": "pvalue",
- "declName": "*self.mUnion",
- "holderName": "m" + name + "Holder"
- }
- )
- jsConversion = CGWrapper(CGGeneric(jsConversion),
- post="\n"
- "return Ok(false);")
- setter = CGWrapper(CGIndenter(jsConversion),
- pre="pub fn TrySetTo" + name + "(&mut self, cx: *JSContext, value: JSVal, pvalue: *JSVal) -> Result<bool,()> {\n",
- post="\n"
- "}")
+ assert not type.isObject()
+ jsConversion = string.Template(template).substitute({
+ "val": "value",
+ "valPtr": None,
+ "declName": "retval",
+ "holderName": None,
+ })
+ jsConversion = CGWrapper(CGGeneric(jsConversion),
+ pre="let retval;\n",
+ post="\nOk(Some(retval))")
return {
- "name": name,
- "typeName": typeName,
- "structType": structType,
- "externalType": externalType,
- "optRef": 'ref ' if externalType[0] == '&' else '',
- "setter": CGIndenter(setter).define(),
- "holderType": holderType.define() if holderType else None
- }
-
-def mapTemplate(template, templateVarArray):
- return map(lambda v: string.Template(template).substitute(v),
- templateVarArray)
+ "name": name,
+ "typeName": typeName,
+ "jsConversion": jsConversion,
+ }
class CGUnionStruct(CGThing):
def __init__(self, type, descriptorProvider):
+ assert not type.nullable()
+ assert not type.hasNullableType
+
CGThing.__init__(self)
- self.type = type.unroll()
+ self.type = type
self.descriptorProvider = descriptorProvider
- def declare(self):
+ def define(self):
templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
self.type.flatMemberTypes)
+ enumValues = [
+ " e%s(%s)," % (v["name"], v["typeName"]) for v in templateVars
+ ]
+ return ("pub enum %s {\n"
+ "%s\n"
+ "}\n") % (self.type, "\n".join(enumValues))
- callDestructors = []
- enumValues = []
- methods = []
- if self.type.hasNullableType:
- callDestructors.append(" case eNull:\n"
- " break;")
- enumValues.append("eNull")
- methods.append(""" pub fn IsNull(&self) -> bool {
- match *self {
- eNull => true,
- _ => false
- }
- }""")
-
- destructorTemplate = """ fn Destroy${name}(&mut self) {
- assert!(Is${name}(), "Wrong type!");
- *self.mUnion = None;
- }"""
- destructors = mapTemplate(destructorTemplate, templateVars)
- callDestructors.extend(mapTemplate(" case e${name}:\n"
- " Destroy${name}();\n"
- " break;", templateVars))
- enumValues.extend(mapTemplate("e${name}(${typeName})", templateVars))
- methodTemplate = """ pub fn Is${name}(&self) -> bool {
- match *self {
- e${name}(_) => true,
- _ => false
- }
- }
- pub fn GetAs${name}<'a>(&'a self) -> ${externalType} {
- assert!(self.Is${name}());
- match *self {
- e${name}(${optRef}inner) => inner,
- _ => unreachable!()
- }
- }"""
- methods.extend(mapTemplate(methodTemplate, templateVars))
- values = mapTemplate("UnionMember<${structType} > m${name};", templateVars)
- return string.Template("""
-pub enum ${structName} {
- ${enumValues}
-}
-
-impl ${structName} {
-${methods}
-}
-""").substitute(
- {
- "structName": self.type.__str__(),
- "callDestructors": "\n".join(callDestructors),
- "destructors": "\n".join(destructors),
- "methods": "\n\n".join(methods),
- "enumValues": ",\n ".join(enumValues),
- "values": "\n ".join(values),
- })
-
- def define(self):
- return """
-"""
class CGUnionConversionStruct(CGThing):
def __init__(self, type, descriptorProvider):
+ assert not type.nullable()
+ assert not type.hasNullableType
+
CGThing.__init__(self)
- self.type = type.unroll()
+ self.type = type
self.descriptorProvider = descriptorProvider
- def declare(self):
- setters = []
+ def from_value_method(self):
+ memberTypes = self.type.flatMemberTypes
+ names = []
+ conversions = []
- if self.type.hasNullableType:
- setters.append(""" pub fn SetNull(&mut self) -> bool
- {
- mUnion = Some(eNull);
- return true;
- }""")
+ interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
+ if len(interfaceMemberTypes) > 0:
+ def get_name(memberType):
+ if self.type.isGeckoInterface():
+ return memberType.inner.identifier.name
+
+ return memberType.name
+
+ def get_match(name):
+ return (
+ "match %s::TryConvertTo%s(cx, value) {\n"
+ " Err(_) => return Err(()),\n"
+ " Ok(Some(value)) => return Ok(e%s(value)),\n"
+ " Ok(None) => (),\n"
+ "}\n") % (self.type, name, name)
+
+ typeNames = [get_name(memberType) for memberType in interfaceMemberTypes]
+ interfaceObject = CGList(CGGeneric(get_match(typeName)) for typeName in typeNames)
+ names.extend(typeNames)
+ else:
+ interfaceObject = None
- templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
- self.type.flatMemberTypes)
- structName = self.type.__str__()
-
- setters.extend(mapTemplate("${setter}", templateVars))
- private = "\n".join(mapTemplate(""" fn SetAs${name}() -> &${structType}
- {
- mUnion.mType = mUnion.e${name};
- return mUnion.mValue.m${name}.SetValue();
- }""", templateVars))
- private += "\n\n"
- holders = filter(lambda v: v["holderType"] is not None, templateVars)
- if len(holders) > 0:
- private += "\n".join(mapTemplate(" ${holderType} m${name}Holder;", holders))
- private += "\n\n"
- private += " " + structName + "& mUnion;"
- return string.Template("""
-pub struct ${structName}Argument<'a> {
- mUnion: &'a mut ${innerType}
-}
+ arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
+ if len(arrayObjectMemberTypes) > 0:
+ assert len(arrayObjectMemberTypes) == 1
+ raise TypeError("Can't handle arrays or sequences in unions.")
+ else:
+ arrayObject = None
-impl<'a> ${structName}Argument<'a> {
- pub fn new(union: &'a mut ${innerType}) -> ${structName}Argument<'a> {
- ${structName}Argument {
- mUnion: union
- }
- }
+ dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
+ if len(dateObjectMemberTypes) > 0:
+ assert len(dateObjectMemberTypes) == 1
+ raise TypeError("Can't handle dates in unions.")
+ else:
+ dateObject = None
-${setters}
-}
-""").substitute({"structName": structName,
- "innerType": ("Option<%s>" % structName) if self.type.nullable() else structName,
- "setters": "\n\n".join(setters),
- })
+ callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
+ if len(callbackMemberTypes) > 0:
+ assert len(callbackMemberTypes) == 1
+ raise TypeError("Can't handle callbacks in unions.")
+ else:
+ callbackObject = None
+
+ dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
+ if len(dictionaryMemberTypes) > 0:
+ raise TypeError("No support for unwrapping dictionaries as member "
+ "of a union")
+ else:
+ dictionaryObject = None
+
+ if callbackObject or dictionaryObject:
+ assert False, "Not currently supported"
+ else:
+ nonPlatformObject = None
+
+ objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
+ if len(objectMemberTypes) > 0:
+ raise TypeError("Can't handle objects in unions.")
+ else:
+ object = None
+
+ hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object
+ if hasObjectTypes:
+ assert interfaceObject
+ templateBody = CGList([interfaceObject], "\n")
+ conversions.append(CGIfWrapper(templateBody, "value.is_object()"))
+
+ otherMemberTypes = [
+ t for t in memberTypes if t.isPrimitive() or t.isString() or t.isEnum()
+ ]
+ if len(otherMemberTypes) > 0:
+ assert len(otherMemberTypes) == 1
+ memberType = otherMemberTypes[0]
+ if memberType.isEnum():
+ name = memberType.inner.identifier.name
+ else:
+ name = memberType.name
+ match = (
+ "match %s::TryConvertTo%s(cx, value) {\n"
+ " Err(_) => return Err(()),\n"
+ " Ok(Some(value)) => return Ok(e%s(value)),\n"
+ " Ok(None) => (),\n"
+ "}\n") % (self.type, name, name)
+ conversions.append(CGGeneric(match))
+ names.append(name)
+
+ conversions.append(CGGeneric(
+ "throw_not_in_union(cx, \"%s\");\n"
+ "Err(())" % ", ".join(names)))
+ return CGWrapper(
+ CGIndenter(CGList(conversions, "\n\n")),
+ pre="pub fn from_value(cx: *JSContext, value: JSVal) -> Result<%s, ()> {\n" % self.type,
+ post="\n}")
+
+ def try_method(self, t):
+ templateVars = getUnionTypeTemplateVars(t, self.descriptorProvider)
+ returnType = "Result<Option<%s>, ()>" % templateVars["typeName"]
+ jsConversion = templateVars["jsConversion"]
+
+ return CGWrapper(
+ CGIndenter(jsConversion, 4),
+ pre="pub fn TryConvertTo%s(cx: *JSContext, value: JSVal) -> %s {\n" % (t.name, returnType),
+ post="\n}")
def define(self):
+ methods = [self.from_value_method()]
+ methods.extend(self.try_method(t) for t in self.type.flatMemberTypes)
return """
-"""
+impl %s {
+%s
+}""" % (self.type, CGIndenter(CGList(methods, "\n\n")).define())
+
class ClassItem:
""" Use with CGClass """
@@ -4206,7 +3635,7 @@ class CGClass(CGThing):
in self.templateSpecialization])
return className
- def declare(self):
+ def define(self):
result = ''
if self.templateArgs:
templateArgs = [a.declare() for a in self.templateArgs]
@@ -4282,8 +3711,6 @@ class CGClass(CGThing):
result += "}"
return result
- def define(self):
- return ''
class CGXrayHelper(CGAbstractExternMethod):
def __init__(self, descriptor, name, args, properties):
@@ -4293,13 +3720,13 @@ class CGXrayHelper(CGAbstractExternMethod):
def definition_body(self):
varNames = self.properties.variableNames(True)
- setup = "let page = page_from_context(cx);\n"
+ setup = ("let window = global_object_for_js_object(wrapper);\n"
+ "let js_info = window.get().page().js_info();\n")
methods = self.properties.methods
if methods.hasNonChromeOnly() or methods.hasChromeOnly():
methodArgs = "Some(zip_copies(%(methods)s, *method_ids))" % varNames
- setup += "let mut js_info = (*page).js_info();\n" \
- "let method_ids = js_info.get().get_ref().dom_static.method_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
+ setup += "let method_ids = js_info.get().get_ref().dom_static.method_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
else:
methodArgs = "None"
methodArgs = CGGeneric(methodArgs)
@@ -4307,8 +3734,7 @@ class CGXrayHelper(CGAbstractExternMethod):
attrs = self.properties.attrs
if attrs.hasNonChromeOnly() or attrs.hasChromeOnly():
attrArgs = "Some(zip_copies(%(attrs)s, *attr_ids))" % varNames
- setup += "let mut js_info = (*page).js_info();\n" \
- "let attr_ids = js_info.get().get_ref().dom_static.attribute_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
+ setup += "let attr_ids = js_info.get().get_ref().dom_static.attribute_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
else:
attrArgs = "None"
attrArgs = CGGeneric(attrArgs)
@@ -4316,8 +3742,7 @@ class CGXrayHelper(CGAbstractExternMethod):
consts = self.properties.consts
if consts.hasNonChromeOnly() or consts.hasChromeOnly():
constArgs = "Some(zip_copies(%(consts)s, *const_ids))" % varNames
- setup += "let mut js_info = (*page).js_info();\n" \
- "let const_ids = js_info.get().get_ref().dom_static.constant_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
+ setup += "let const_ids = js_info.get().get_ref().dom_static.constant_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
else:
constArgs = "None"
constArgs = CGGeneric(constArgs)
@@ -4439,14 +3864,13 @@ class CGProxyUnwrap(CGAbstractMethod):
def __init__(self, descriptor):
args = [Argument('*JSObject', 'obj')]
CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*' + descriptor.concreteType, args, alwaysInline=True)
- def declare(self):
- return ""
+
def definition_body(self):
return """ /*if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
obj = js::UnwrapObject(obj);
}*/
//MOZ_ASSERT(IsProxy(obj));
- let box_: *Box<%s> = cast::transmute(RUST_JSVAL_TO_PRIVATE(GetProxyPrivate(obj)));
+ let box_: *Box<%s> = cast::transmute(GetProxyPrivate(obj).to_private());
return ptr::to_unsafe_ptr(&(*box_).data);""" % (self.descriptor.concreteType)
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
@@ -4707,7 +4131,7 @@ if found {
return 1;
}
%s
-*vp = JSVAL_VOID;
+*vp = UndefinedValue();
return 1;""" % (getIndexedOrExpando, getNamed)
def definition_body(self):
@@ -4768,7 +4192,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def finalizeHook(descriptor, hookName, context):
release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj));
-let _: %s %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val));
+let _: %s %s = cast::transmute(val.to_private());
debug!("%s finalize: {:p}", this);
""" % (DOMObjectPointerType(descriptor), descriptor.concreteType, descriptor.concreteType)
return release
@@ -4805,13 +4229,7 @@ class CGClassConstructHook(CGAbstractExternMethod):
def generate_code(self):
preamble = """
- //JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
- //XXXjdm Gecko obtains a GlobalObject from the global (maybe from the private value,
- // or through unwrapping a slot or something). We'll punt and get the Window
- // from the context for now.
- let page = page_from_context(cx);
- let frame = (*page).frame();
- let global = frame.get().get_ref().window.clone();
+ let global = global_object_for_js_object(JS_CALLEE(cx, &*vp).to_object());
let obj = global.reflector().get_jsobject();
"""
nativeName = MakeNativeName(self._ctor.identifier.name)
@@ -4835,9 +4253,7 @@ class CGDOMJSProxyHandlerDOMClass(CGThing):
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
- def declare(self):
- #return "extern const DOMClass Class;\n"
- return ""
+
def define(self):
return """
static Class: DOMClass = """ + DOMClass(self.descriptor) + """;
@@ -4852,6 +4268,11 @@ class CGDescriptor(CGThing):
cgThings = []
if descriptor.interface.hasInterfacePrototypeObject():
+ cgThings.append(CGGetProtoObjectMethod(descriptor))
+ else:
+ cgThings.append(CGGetConstructorObjectMethod(descriptor))
+
+ if descriptor.interface.hasInterfacePrototypeObject():
(hasMethod, hasGetter, hasLenientGetter,
hasSetter, hasLenientSetter) = False, False, False, False, False
for m in descriptor.interface.members:
@@ -4892,12 +4313,8 @@ class CGDescriptor(CGThing):
cgThings.append(CGPrototypeJSClass(descriptor))
properties = PropertyArrays(descriptor)
- cgThings.append(CGGeneric(define=str(properties)))
+ cgThings.append(CGGeneric(str(properties)))
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
- if descriptor.interface.hasInterfacePrototypeObject():
- cgThings.append(CGGetProtoObjectMethod(descriptor))
- else:
- cgThings.append(CGGetConstructorObjectMethod(descriptor))
# Set up our Xray callbacks as needed.
if descriptor.interface.hasInterfacePrototypeObject():
@@ -4937,18 +4354,15 @@ class CGDescriptor(CGThing):
cgThings.append(CGDOMJSClass(descriptor))
pass
- cgThings.append(CGWrapWithCacheMethod(descriptor))
cgThings.append(CGWrapMethod(descriptor))
- cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n")
+ cgThings = CGList(cgThings, "\n")
cgThings = CGWrapper(cgThings, pre='\n', post='\n')
#self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
# cgThings),
# post='\n')
self.cgRoot = cgThings
- def declare(self):
- return self.cgRoot.declare()
def define(self):
return self.cgRoot.define()
@@ -4992,8 +4406,6 @@ class CGNamespacedEnum(CGThing):
# Save the result.
self.node = curr
- def declare(self):
- return self.node.declare()
def define(self):
return self.node.define()
@@ -5016,9 +4428,12 @@ class CGDictionary(CGThing):
defaultValue=member.defaultValue))
for member in dictionary.members ]
- def declare(self):
+ def define(self):
if not self.generatable:
return ""
+ return self.struct() + "\n" + self.impl()
+
+ def struct(self):
d = self.dictionary
if d.parent:
inheritance = " parent: %s::%s,\n" % (self.makeModuleName(d.parent),
@@ -5039,9 +4454,7 @@ class CGDictionary(CGThing):
"}").substitute( { "selfName": self.makeClassName(d),
"inheritance": inheritance }))
- def define(self):
- if not self.generatable:
- return ""
+ def impl(self):
d = self.dictionary
if d.parent:
initParent = ("// Per spec, we init the parent's members first\n"
@@ -5104,9 +4517,9 @@ class CGDictionary(CGThing):
" }\n"
"${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"
+ " let temp: JSVal = NullValue();\n"
+ " let isNull = val.is_null_or_undefined();\n"
+ " if !isNull && val.is_primitive() {\n"
" return 0; //XXXjdm throw properly here\n"
" //return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
" }\n"
@@ -5166,15 +4579,15 @@ class CGDictionary(CGThing):
if True: #XXXjdm hack until 'static mut' exists for global jsids
propName = member.identifier.name
- propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, RUST_JSVAL_TO_OBJECT(val), s, ptr::to_unsafe_ptr(&found)) })' %
+ propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, val.to_object(), s, ptr::to_unsafe_ptr(&found)) })' %
propName)
- propGet = ('"%s".to_c_str().with_ref(|s| { JS_GetProperty(cx, RUST_JSVAL_TO_OBJECT(val), s, ptr::to_unsafe_ptr(&temp)) })' %
+ propGet = ('"%s".to_c_str().with_ref(|s| { JS_GetProperty(cx, val.to_object(), s, ptr::to_unsafe_ptr(&temp)) })' %
propName)
else:
propId = self.makeIdName(member.identifier.name);
- propCheck = ("JS_HasPropertyById(cx, RUST_JSVAL_TO_OBJECT(val), %s, ptr::to_unsafe_ptr(&found))" %
+ propCheck = ("JS_HasPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&found))" %
propId)
- propGet = ("JS_GetPropertyById(cx, RUST_JSVAL_TO_OBJECT(val), %s, ptr::to_unsafe_ptr(&temp))" %
+ propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&temp))" %
propId)
conversionReplacements = {
@@ -5270,8 +4683,8 @@ class CGBindingRoot(CGThing):
CGList([CGGeneric(" use dom::bindings::utils::EnumEntry;"),
CGEnum(e)]), public=True)
def makeEnumTypedef(e):
- return CGGeneric(declare=("pub type %s = self::%sValues::valuelist;\n" %
- (e.identifier.name, e.identifier.name)))
+ return CGGeneric("pub type %s = self::%sValues::valuelist;\n" %
+ (e.identifier.name, e.identifier.name))
cgthings = [ fun(e) for e in config.getEnums(webIDLFile)
for fun in [makeEnum, makeEnumTypedef] ]
@@ -5321,46 +4734,79 @@ class CGBindingRoot(CGThing):
# Add imports
#XXXjdm This should only import the namespace for the current binding,
# not every binding ever.
- curr = CGImports(descriptors,
- dictionaries,
- ['js::*',
- 'js::jsapi::*',
- 'js::jsfriendapi::bindgen::*',
- 'js::glue::*',
- 'dom::types::*',
- 'dom::bindings::js::JS',
- 'dom::bindings::utils::*',
- 'dom::bindings::trace::Traceable',
- 'dom::bindings::callback::*',
- 'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult, throw_method_failed_with_details, throw_not_in_union}',
- 'dom::bindings::conversions::*',
- 'dom::bindings::codegen::*', #XXXjdm
- 'dom::bindings::codegen::UnionTypes::*', #XXXjdm
- 'dom::bindings::codegen::UnionConversions::*', #XXXjdm
- 'script_task::{JSPageInfo, page_from_context}',
- 'dom::bindings::proxyhandler',
- 'dom::bindings::proxyhandler::*',
- 'servo_util::str::DOMString',
- 'servo_util::vec::zip_copies',
- 'std::cast',
- 'std::libc',
- 'std::ptr',
- 'std::vec',
- 'std::str',
- 'std::num',
- 'std::unstable::intrinsics::uninit',
- 'std::unstable::raw::Box',
- ],
- [],
- curr)
+ curr = CGImports(curr, [
+ 'js::{crust, JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}',
+ 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}',
+ 'js::{JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_SHIFT}',
+ 'js::{JSCLASS_RESERVED_SLOTS_MASK, JSID_VOID, JSJitInfo}',
+ 'js::{JSPROP_ENUMERATE, JSPROP_NATIVE_ACCESSORS, JSPROP_SHARED}',
+ 'js::{JSRESOLVE_ASSIGNING, JSRESOLVE_QUALIFIED}',
+ 'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}',
+ 'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
+ 'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
+ 'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_IsExceptionPending}',
+ 'js::jsapi::{JS_NewObject, JS_ObjectIsCallable, JS_SetPrototype}',
+ 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSBool, JSContext}',
+ 'js::jsapi::{JSClass, JSFreeOp, JSFunctionSpec, JSHandleObject, jsid}',
+ 'js::jsapi::{JSNativeWrapper, JSObject, JSPropertyDescriptor}',
+ 'js::jsapi::{JSPropertyOpWrapper, JSPropertySpec}',
+ 'js::jsapi::{JSStrictPropertyOpWrapper, JSString, JSTracer}',
+ 'js::jsval::JSVal',
+ 'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
+ 'js::jsval::{NullValue, UndefinedValue}',
+ 'js::glue::{CallJitMethodOp, CallJitPropertyOp, CreateProxyHandler}',
+ 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
+ 'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}',
+ 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
+ 'dom::types::*',
+ 'dom::bindings::js::JS',
+ 'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
+ 'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
+ 'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
+ 'dom::bindings::utils::{DOMJSClass}',
+ 'dom::bindings::utils::{FindEnumStringIndex, GetArrayIndexFromId}',
+ 'dom::bindings::utils::{GetPropertyOnPrototype, GetProtoOrIfaceArray}',
+ 'dom::bindings::utils::{HasPropertyOnPrototype, IntVal}',
+ 'dom::bindings::utils::{jsid_to_str}',
+ 'dom::bindings::utils::{NativePropertyHooks}',
+ 'dom::bindings::utils::global_object_for_js_object',
+ 'dom::bindings::utils::{Reflectable}',
+ 'dom::bindings::utils::{squirrel_away_unique}',
+ 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
+ 'dom::bindings::utils::{unwrap_object, VoidVal, with_gc_disabled}',
+ 'dom::bindings::utils::{with_gc_enabled, XrayResolveProperty}',
+ 'dom::bindings::trace::Traceable',
+ 'dom::bindings::callback::{CallbackContainer,CallbackInterface}',
+ 'dom::bindings::callback::{CallSetup,ExceptionHandling}',
+ 'dom::bindings::callback::{WrapCallThisObject}',
+ 'dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible}',
+ 'dom::bindings::conversions::{Default, Empty}',
+ 'dom::bindings::codegen::*',
+ 'dom::bindings::codegen::UnionTypes::*',
+ 'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}',
+ 'dom::bindings::error::{throw_method_failed_with_details}',
+ 'script_task::JSPageInfo',
+ 'dom::bindings::proxyhandler',
+ 'dom::bindings::proxyhandler::{_obj_toString, defineProperty}',
+ 'dom::bindings::proxyhandler::{FillPropertyDescriptor, GetExpandoObject}',
+ 'dom::bindings::proxyhandler::{getPropertyDescriptor}',
+ 'servo_util::str::DOMString',
+ 'servo_util::vec::zip_copies',
+ 'std::cast',
+ 'std::libc',
+ 'std::ptr',
+ 'std::vec',
+ 'std::str',
+ 'std::num',
+ 'std::unstable::raw::Box',
+ ])
# Add the auto-generated comment.
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
# Store the final result.
self.root = curr
- def declare(self):
- return stripTrailingWhitespace(self.root.declare())
+
def define(self):
return stripTrailingWhitespace(self.root.define())
@@ -5747,7 +5193,7 @@ class CGCallback(CGClass):
# the private method.
argnames = [arg.name for arg in args]
argnamesWithThis = ["s.GetContext()", "thisObjJS"] + argnames
- argnamesWithoutThis = ["s.GetContext()", "JSVAL_TO_OBJECT(JSVAL_NULL)"] + argnames
+ argnamesWithoutThis = ["s.GetContext()", "ptr::null()"] + argnames
# Now that we've recorded the argnames for our call to our private
# method, insert our optional argument for deciding whether the
# CallSetup should re-throw exceptions on aRv.
@@ -5912,7 +5358,7 @@ class CallbackMember(CGNativeMember):
if self.argCount > 0:
replacements["argCount"] = self.argCountStr
replacements["argvDecl"] = string.Template(
- "let mut argv = vec::from_elem(${argCount}, JSVAL_VOID);\n"
+ "let mut argv = vec::from_elem(${argCount}, UndefinedValue());\n"
).substitute(replacements)
else:
# Avoid weird 0-sized arrays
@@ -6001,7 +5447,7 @@ class CallbackMember(CGNativeMember):
{
'result' : result,
'successCode' : "continue;" if arg.variadic else "break;",
- 'jsvalRef' : "argv.handleAt(%s)" % jsvalIndex,
+ 'jsvalRef' : "argv[%s]" % jsvalIndex,
'jsvalHandle' : "argv.handleAt(%s)" % jsvalIndex,
'jsvalPtr': "&mut argv[%s]" % jsvalIndex,
# XXXbz we don't have anything better to use for 'obj',
@@ -6096,7 +5542,7 @@ class CallbackMethod(CallbackMember):
CallbackMember.__init__(self, sig, name, descriptorProvider,
needThisHandling, rethrowContentException)
def getRvalDecl(self):
- return "let mut rval = JSVAL_VOID;\n"
+ return "let mut rval = UndefinedValue();\n"
def getCall(self):
replacements = {
@@ -6163,9 +5609,9 @@ class CallbackOperationBase(CallbackMethod):
return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
return (
'let isCallable = unsafe { JS_ObjectIsCallable(cx, self.parent.callback) != 0 };\n'
- 'let mut callable = JSVAL_VOID;\n'
+ 'let mut callable = UndefinedValue();\n'
'if isCallable {\n'
- ' callable = unsafe { RUST_OBJECT_TO_JSVAL(self.parent.callback) };\n'
+ ' callable = unsafe { ObjectValue(&*self.parent.callback) };\n'
'} else {\n'
'%s'
'}\n' % CGIndenter(CGGeneric(getCallableFromProp)).define())
@@ -6249,74 +5695,23 @@ class GlobalGenRoots():
@staticmethod
def PrototypeList(config):
-
# Prototype ID enum.
protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)]
- idEnum = CGNamespacedEnum('id', 'ID', protos, [0], deriving="Eq")
- idEnum = CGList([idEnum])
- idEnum.append(CGGeneric(declare="pub static MAX_PROTO_CHAIN_LENGTH: uint = " +
- str(config.maxProtoChainLength) + ";\n\n"))
+ return CGList([
+ CGGeneric(AUTOGENERATED_WARNING_COMMENT),
+ CGGeneric("pub static MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength),
+ CGNamespacedEnum('id', 'ID', protos, [0], deriving="Eq"),
+ ])
- # Wrap all of that in our namespaces.
- #idEnum = CGNamespace.build(['mozilla', 'dom', 'prototypes'],
- # CGWrapper(idEnum, pre='\n'))
- #idEnum = CGWrapper(idEnum, post='\n')
-
- curr = CGList([idEnum])
-
- # Constructor ID enum.
- constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True,
- hasInterfacePrototypeObject=False)]
- idEnum = CGNamespacedEnum('id', 'ID', constructors, [0])
-
- # Wrap all of that in our namespaces.
- idEnum = CGNamespace.build(['mozilla', 'dom', 'constructors'],
- CGWrapper(idEnum, pre='\n'))
- idEnum = CGWrapper(idEnum, post='\n')
-
- #XXXjdm Not sure what to do with the constructors right now
- #curr.append(idEnum)
-
- #traitsDecl = CGGeneric(declare="""
-#template <prototypes::ID PrototypeID>
-#struct PrototypeTraits;
-#
-#template <class ConcreteClass>
-#struct PrototypeIDMap;
-#""")
-
- #traitsDecl = CGNamespace.build(['mozilla', 'dom'],
- # CGWrapper(traitsDecl, post='\n'))
-
- #curr.append(traitsDecl)
-
- # Add the auto-generated comment.
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
-
- # Done.
- return curr
@staticmethod
def RegisterBindings(config):
-
# TODO - Generate the methods we want
- curr = CGRegisterProtos(config)
-
- # Wrap all of that in our namespaces.
- #curr = CGNamespace.build(['mozilla', 'dom'],
- # CGWrapper(curr, post='\n'))
- #curr = CGWrapper(curr, post='\n')
-
- # Add the includes
- defineIncludes = [CGImports.getDeclarationFilename(desc.interface)
- for desc in config.getDescriptors(hasInterfaceObject=True,
- register=True)]
- curr = CGImports([], [], ['dom::bindings::codegen',
- 'script_task::JSPageInfo'], defineIncludes, curr)
-
- # Done.
- return curr
+ return CGImports(CGRegisterProtos(config), [
+ 'dom::bindings::codegen',
+ 'script_task::JSPageInfo',
+ ])
@staticmethod
def InterfaceTypes(config):
@@ -6327,7 +5722,7 @@ class GlobalGenRoots():
return "dom::%s" % descriptor.name.lower()
descriptors = [d.name for d in config.getDescriptors(register=True, hasInterfaceObject=True)]
- curr = CGList([CGGeneric(declare="pub use dom::%s::%s;\n" % (name.lower(), name)) for name in descriptors])
+ curr = CGList([CGGeneric("pub use dom::%s::%s;\n" % (name.lower(), name)) for name in descriptors])
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
return curr
@@ -6335,7 +5730,7 @@ class GlobalGenRoots():
def BindingDeclarations(config):
descriptors = [d.name for d in config.getDescriptors(register=True)]
- curr = CGList([CGGeneric(declare="pub mod %sBinding;\n" % name) for name in descriptors])
+ curr = CGList([CGGeneric("pub mod %sBinding;\n" % name) for name in descriptors])
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
return curr
@@ -6343,19 +5738,19 @@ class GlobalGenRoots():
def InheritTypes(config):
descriptors = config.getDescriptors(register=True, hasInterfaceObject=True)
- allprotos = [CGGeneric(declare="#[allow(unused_imports)];\n"),
- CGGeneric(declare="use dom::types::*;\n"),
- CGGeneric(declare="use dom::bindings::js::JS;\n"),
- CGGeneric(declare="use dom::bindings::trace::Traceable;\n"),
- CGGeneric(declare="use extra::serialize::{Encodable, Encoder};\n"),
- CGGeneric(declare="use js::jsapi::JSTracer;\n\n")]
+ allprotos = [CGGeneric("#[allow(unused_imports)];\n"),
+ CGGeneric("use dom::types::*;\n"),
+ CGGeneric("use dom::bindings::js::JS;\n"),
+ CGGeneric("use dom::bindings::trace::Traceable;\n"),
+ CGGeneric("use extra::serialize::{Encodable, Encoder};\n"),
+ CGGeneric("use js::jsapi::JSTracer;\n\n")]
for descriptor in descriptors:
name = descriptor.name
- protos = [CGGeneric(declare='pub trait %s {}\n' % (name + 'Base'))]
+ protos = [CGGeneric('pub trait %s {}\n' % (name + 'Base'))]
for proto in descriptor.prototypeChain:
- protos += [CGGeneric(declare='impl %s for %s {}\n' % (proto + 'Base',
+ protos += [CGGeneric('impl %s for %s {}\n' % (proto + 'Base',
descriptor.concreteType))]
- derived = [CGGeneric(declare='pub trait %s { fn %s(&self) -> bool; }\n' %
+ derived = [CGGeneric('pub trait %s { fn %s(&self) -> bool; }\n' %
(name + 'Derived', 'is_' + name.lower()))]
for protoName in descriptor.prototypeChain[1:-1]:
protoDescriptor = config.getDescriptor(protoName)
@@ -6368,10 +5763,10 @@ class GlobalGenRoots():
'selfName': name + 'Derived',
'baseName': protoDescriptor.concreteType,
'parentName': protoDescriptor.prototypeChain[-2].lower()})
- derived += [CGGeneric(declare=delegate)]
- derived += [CGGeneric(declare='\n')]
+ derived += [CGGeneric(delegate)]
+ derived += [CGGeneric('\n')]
- cast = [CGGeneric(declare=string.Template('''pub trait ${castTraitName} {
+ cast = [CGGeneric(string.Template('''pub trait ${castTraitName} {
fn from<T: ${fromBound}>(derived: &JS<T>) -> JS<Self> {
unsafe { derived.clone().transmute() }
}
@@ -6385,9 +5780,9 @@ class GlobalGenRoots():
'castTraitName': name + 'Cast',
'fromBound': name + 'Base',
'toBound': name + 'Derived'})),
- CGGeneric(declare="impl %s for %s {}\n\n" % (name + 'Cast', name))]
+ CGGeneric("impl %s for %s {}\n\n" % (name + 'Cast', name))]
- trace = [CGGeneric(declare=string.Template('''impl Traceable for ${name} {
+ trace = [CGGeneric(string.Template('''impl Traceable for ${name} {
fn trace(&self, tracer: *mut JSTracer) {
unsafe {
self.encode(&mut *tracer);
@@ -6442,45 +5837,43 @@ class GlobalGenRoots():
#stack[len(elements)].append(clazz)
- curr = CGList([stack[0], curr], "\n")
+ curr = CGList([stack[0], curr, UnionConversions(config.getDescriptors())], "\n")
#curr = CGHeaders([], [], includes, [], curr)
# Add include guards.
#curr = CGIncludeGuard('UnionTypes', curr)
- curr = CGImports([], [], ['dom::bindings::js::JS',
- 'dom::types::*'], [], curr)
-
- # Add the auto-generated comment.
- curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
-
- # Done.
- return curr
-
- @staticmethod
- def UnionConversions(config):
-
- unions = UnionConversions(config.getDescriptors())
- curr = unions
-
- # Wrap all of that in our namespaces.
- #curr = CGNamespace.build(['mozilla', 'dom'], unions)
-
- curr = CGWrapper(curr, post='\n')
-
- #curr = CGHeaders([], [], ["nsDebug.h", "mozilla/dom/UnionTypes.h", "nsDOMQS.h"], [], curr)
-
- # Add include guards.
- #curr = CGIncludeGuard('UnionConversions', curr)
-
- curr = CGImports([], [], ['dom::bindings::utils::unwrap_jsmanaged',
- 'dom::bindings::codegen::UnionTypes::*',
- 'dom::bindings::codegen::PrototypeList',
- 'dom::bindings::conversions::JSValConvertible',
- 'js::*',
- 'js::jsapi::*',
- 'js::glue::*'], [], curr)
+ curr = CGImports(curr, [
+ 'dom::bindings::utils::unwrap_jsmanaged',
+ 'dom::bindings::codegen::PrototypeList',
+ 'dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible}',
+ 'dom::bindings::error::throw_not_in_union',
+ 'dom::bindings::js::JS',
+ 'dom::types::*',
+ 'js::{crust, JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}',
+ 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}',
+ 'js::{JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_SHIFT}',
+ 'js::{JSCLASS_RESERVED_SLOTS_MASK, JSID_VOID, JSJitInfo}',
+ 'js::{JSPROP_ENUMERATE, JSPROP_NATIVE_ACCESSORS, JSPROP_SHARED}',
+ 'js::{JSRESOLVE_ASSIGNING, JSRESOLVE_QUALIFIED}',
+ 'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}',
+ 'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
+ 'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
+ 'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_IsExceptionPending}',
+ 'js::jsapi::{JS_NewObject, JS_ObjectIsCallable, JS_SetPrototype}',
+ 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSBool, JSContext}',
+ 'js::jsapi::{JSClass, JSFreeOp, JSFunctionSpec, JSHandleObject, jsid}',
+ 'js::jsapi::{JSNativeWrapper, JSObject, JSPropertyDescriptor}',
+ 'js::jsapi::{JSPropertyOpWrapper, JSPropertySpec}',
+ 'js::jsapi::{JSStrictPropertyOpWrapper, JSString, JSTracer}',
+ 'js::jsval::JSVal',
+ 'js::jsval::PrivateValue',
+ 'js::glue::{CallJitMethodOp, CallJitPropertyOp, CreateProxyHandler}',
+ 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
+ 'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}',
+ 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
+ ])
# Add the auto-generated comment.
curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
diff --git a/src/components/script/dom/bindings/codegen/GlobalGen.py b/src/components/script/dom/bindings/codegen/GlobalGen.py
index bd8b3d70793..90310fc9aff 100644
--- a/src/components/script/dom/bindings/codegen/GlobalGen.py
+++ b/src/components/script/dom/bindings/codegen/GlobalGen.py
@@ -17,21 +17,11 @@ from CodegenRust import GlobalGenRoots, replaceFileIfChanged
# import Codegen in general, so we can set a variable on it
import Codegen
-def generate_file(config, name, action):
+def generate_file(config, name):
+ filename = name + '.rs'
root = getattr(GlobalGenRoots, name)(config)
- if action is 'declare':
- filename = name + '.rs'
- code = root.declare()
- elif action == 'declare+define':
- filename = name + '.rs'
- code = root.declare()
- root2 = getattr(GlobalGenRoots, name)(config)
- code += root2.define()
- else:
- assert action is 'define'
- filename = name + '.rs'
- code = root.define()
+ code = root.define()
if replaceFileIfChanged(filename, code):
print "Generating %s" % (filename)
@@ -75,22 +65,21 @@ def main():
config = Configuration(configFile, parserResults)
# Generate the prototype list.
- generate_file(config, 'PrototypeList', 'declare+define')
+ generate_file(config, 'PrototypeList')
# Generate the common code.
- generate_file(config, 'RegisterBindings', 'declare+define')
+ generate_file(config, 'RegisterBindings')
# Generate the type list.
- generate_file(config, 'InterfaceTypes', 'declare+define')
+ generate_file(config, 'InterfaceTypes')
# Generate the type list.
- generate_file(config, 'InheritTypes', 'declare+define')
+ generate_file(config, 'InheritTypes')
# Generate the module declarations.
- generate_file(config, 'BindingDeclarations', 'declare+define')
+ generate_file(config, 'BindingDeclarations')
- generate_file(config, 'UnionTypes', 'declare+define')
- generate_file(config, 'UnionConversions', 'declare+define')
+ generate_file(config, 'UnionTypes')
if __name__ == '__main__':
main()
diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs
index 116b74e8efa..311745603a5 100644
--- a/src/components/script/dom/bindings/conversions.rs
+++ b/src/components/script/dom/bindings/conversions.rs
@@ -2,114 +2,259 @@
* 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/. */
-use js::jsapi::{JSVal, JSBool, JSContext};
-use js::jsapi::{JS_ValueToInt64, JS_ValueToECMAInt32, JS_ValueToECMAUint32};
+use dom::bindings::js::JS;
+use dom::bindings::utils::Reflectable;
+use dom::bindings::utils::jsstring_to_str;
+use servo_util::str::DOMString;
+
+use js::jsapi::{JSBool, JSContext};
+use js::jsapi::{JS_ValueToUint64, JS_ValueToInt64};
+use js::jsapi::{JS_ValueToECMAUint32, JS_ValueToECMAInt32};
use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean};
-use js::{JSVAL_FALSE, JSVAL_TRUE};
-use js::glue::{RUST_UINT_TO_JSVAL, RUST_DOUBLE_TO_JSVAL};
+use js::jsapi::{JS_NewUCStringCopyN, JS_ValueToString};
+use js::jsapi::{JS_WrapValue};
+use js::jsval::JSVal;
+use js::jsval::{NullValue, BooleanValue, Int32Value, UInt32Value, StringValue};
+use js::jsval::ObjectValue;
+use js::glue::RUST_JS_NumberValue;
+use std::libc;
+
+pub trait ToJSValConvertible {
+ fn to_jsval(&self, cx: *JSContext) -> JSVal;
+}
-pub trait JSValConvertible {
- fn to_jsval(&self) -> JSVal;
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<Self>;
+pub trait FromJSValConvertible<T> {
+ fn from_jsval(cx: *JSContext, val: JSVal, option: T) -> Result<Self, ()>;
}
unsafe fn convert_from_jsval<T: Default>(
cx: *JSContext, value: JSVal,
- convert_fn: extern "C" unsafe fn(*JSContext, JSVal, *T) -> JSBool) -> Option<T> {
+ convert_fn: extern "C" unsafe fn(*JSContext, JSVal, *T) -> JSBool) -> Result<T, ()> {
let mut ret = Default::default();
if convert_fn(cx, value, &mut ret as *mut T as *T) == 0 {
- None
+ Err(())
} else {
- Some(ret)
+ Ok(ret)
+ }
+}
+
+
+impl ToJSValConvertible for bool {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ BooleanValue(*self)
+ }
+}
+
+impl FromJSValConvertible<()> for bool {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<bool, ()> {
+ let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) };
+ result.map(|b| b != 0)
+ }
+}
+
+impl ToJSValConvertible for i8 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ Int32Value(*self as i32)
+ }
+}
+
+impl FromJSValConvertible<()> for i8 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<i8, ()> {
+ let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) };
+ result.map(|v| v as i8)
+ }
+}
+
+impl ToJSValConvertible for u8 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ Int32Value(*self as i32)
+ }
+}
+
+impl FromJSValConvertible<()> for u8 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<u8, ()> {
+ let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) };
+ result.map(|v| v as u8)
+ }
+}
+
+impl ToJSValConvertible for i16 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ Int32Value(*self as i32)
+ }
+}
+
+impl FromJSValConvertible<()> for i16 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<i16, ()> {
+ let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) };
+ result.map(|v| v as i16)
+ }
+}
+
+impl ToJSValConvertible for u16 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ Int32Value(*self as i32)
+ }
+}
+
+impl FromJSValConvertible<()> for u16 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<u16, ()> {
+ unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) }
+ }
+}
+
+impl ToJSValConvertible for i32 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ Int32Value(*self)
+ }
+}
+
+impl FromJSValConvertible<()> for i32 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<i32, ()> {
+ unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }
}
}
+impl ToJSValConvertible for u32 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
+ UInt32Value(*self)
+ }
+}
+
+impl FromJSValConvertible<()> for u32 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<u32, ()> {
+ unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) }
+ }
+}
-impl JSValConvertible for i64 {
- fn to_jsval(&self) -> JSVal {
+impl ToJSValConvertible for i64 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
unsafe {
- RUST_DOUBLE_TO_JSVAL(*self as f64)
+ RUST_JS_NumberValue(*self as f64)
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i64> {
+impl FromJSValConvertible<()> for i64 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<i64, ()> {
unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) }
}
}
-impl JSValConvertible for u32 {
- fn to_jsval(&self) -> JSVal {
+impl ToJSValConvertible for u64 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
unsafe {
- RUST_UINT_TO_JSVAL(*self)
+ RUST_JS_NumberValue(*self as f64)
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u32> {
- unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) }
+impl FromJSValConvertible<()> for u64 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<u64, ()> {
+ unsafe { convert_from_jsval(cx, val, JS_ValueToUint64) }
}
}
-impl JSValConvertible for i32 {
- fn to_jsval(&self) -> JSVal {
+impl ToJSValConvertible for f32 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
unsafe {
- RUST_UINT_TO_JSVAL(*self as u32)
+ RUST_JS_NumberValue(*self as f64)
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i32> {
- unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }
+impl FromJSValConvertible<()> for f32 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<f32, ()> {
+ let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) };
+ result.map(|f| f as f32)
}
}
-impl JSValConvertible for u16 {
- fn to_jsval(&self) -> JSVal {
+impl ToJSValConvertible for f64 {
+ fn to_jsval(&self, _cx: *JSContext) -> JSVal {
unsafe {
- RUST_UINT_TO_JSVAL(*self as u32)
+ RUST_JS_NumberValue(*self)
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u16> {
- unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) }
+impl FromJSValConvertible<()> for f64 {
+ fn from_jsval(cx: *JSContext, val: JSVal, _option: ()) -> Result<f64, ()> {
+ unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }
}
}
-impl JSValConvertible for bool {
- fn to_jsval(&self) -> JSVal {
- if *self {
- JSVAL_TRUE
- } else {
- JSVAL_FALSE
+impl ToJSValConvertible for DOMString {
+ fn to_jsval(&self, cx: *JSContext) -> JSVal {
+ unsafe {
+ let string_utf16 = self.to_utf16();
+ let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr(), string_utf16.len() as libc::size_t);
+ if jsstr.is_null() {
+ fail!("JS_NewUCStringCopyN failed");
+ }
+ StringValue(&*jsstr)
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<bool> {
- let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) };
- result.map(|b| b != 0)
+#[deriving(Eq)]
+pub enum StringificationBehavior {
+ Default,
+ Empty,
+}
+
+impl Default for StringificationBehavior {
+ fn default() -> StringificationBehavior {
+ Default
}
}
-impl JSValConvertible for f32 {
- fn to_jsval(&self) -> JSVal {
- unsafe {
- RUST_DOUBLE_TO_JSVAL(*self as f64)
+impl FromJSValConvertible<StringificationBehavior> for DOMString {
+ fn from_jsval(cx: *JSContext, value: JSVal, nullBehavior: StringificationBehavior) -> Result<DOMString, ()> {
+ if nullBehavior == Empty && value.is_null() {
+ Ok(~"")
+ } else {
+ let jsstr = unsafe { JS_ValueToString(cx, value) };
+ if jsstr.is_null() {
+ debug!("JS_ValueToString failed");
+ Err(())
+ } else {
+ Ok(jsstring_to_str(cx, jsstr))
+ }
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f32> {
- let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) };
- result.map(|f| f as f32)
+impl<T: Reflectable> ToJSValConvertible for JS<T> {
+ fn to_jsval(&self, cx: *JSContext) -> JSVal {
+ let obj = self.reflector().get_jsobject();
+ assert!(obj.is_not_null());
+ let mut value = ObjectValue(unsafe { &*obj });
+ if unsafe { JS_WrapValue(cx, &mut value as *mut JSVal as *JSVal) } == 0 {
+ fail!("JS_WrapValue failed.");
+ }
+ value
}
}
-impl JSValConvertible for f64 {
- fn to_jsval(&self) -> JSVal {
- unsafe {
- RUST_DOUBLE_TO_JSVAL(*self as f64)
+impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> {
+ fn to_jsval(&self, cx: *JSContext) -> JSVal {
+ match self {
+ &Some(ref value) => value.to_jsval(cx),
+ &None => NullValue(),
}
}
+}
- fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f64> {
- unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }
+impl<X: Default, T: FromJSValConvertible<X>> FromJSValConvertible<()> for Option<T> {
+ fn from_jsval(cx: *JSContext, value: JSVal, _: ()) -> Result<Option<T>, ()> {
+ if value.is_null_or_undefined() {
+ Ok(None)
+ } else {
+ let option: X = Default::default();
+ let result: Result<T, ()> = FromJSValConvertible::from_jsval(cx, value, option);
+ result.map(Some)
+ }
}
}
diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs
index 4aaf3506ae8..9f8e44ba06f 100644
--- a/src/components/script/dom/bindings/js.rs
+++ b/src/components/script/dom/bindings/js.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::utils::{Reflector, Reflectable};
-use dom::window;
+use dom::window::Window;
use js::jsapi::{JSContext, JSObject};
use layout_interface::TrustedNodeAddress;
@@ -31,12 +31,11 @@ impl <T> Clone for JS<T> {
impl<T: Reflectable> JS<T> {
pub fn new(mut obj: ~T,
- window: &window::Window,
- wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~T) -> *JSObject) -> JS<T> {
- let cx = window.get_cx();
- let scope = window.reflector().get_jsobject();
+ window: &JS<Window>,
+ wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> *JSObject) -> JS<T> {
+ let cx = window.get().get_cx();
let raw: *mut T = &mut *obj;
- if wrap_fn(cx, scope, obj).is_null() {
+ if wrap_fn(cx, window, obj).is_null() {
fail!("Could not eagerly wrap object");
}
JS {
diff --git a/src/components/script/dom/bindings/proxyhandler.rs b/src/components/script/dom/bindings/proxyhandler.rs
index 2f8267d4f29..aaf75a7bc7a 100644
--- a/src/components/script/dom/bindings/proxyhandler.rs
+++ b/src/components/script/dom/bindings/proxyhandler.rs
@@ -6,7 +6,8 @@ use dom::bindings::utils::is_dom_proxy;
use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar};
use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free};
use js::jsapi::{JSBool, JS_DefinePropertyById, JS_NewObjectWithGivenProto};
-use js::glue::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra, RUST_OBJECT_TO_JSVAL};
+use js::jsval::ObjectValue;
+use js::glue::GetProxyExtra;
use js::glue::{GetObjectProto, GetObjectParent, SetProxyExtra, GetProxyHandler};
use js::glue::InvokeGetOwnPropertyDescriptor;
use js::crust::{JS_StrictPropertyStub};
@@ -97,10 +98,10 @@ pub fn GetExpandoObject(obj: *JSObject) -> *JSObject {
unsafe {
assert!(is_dom_proxy(obj));
let val = GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
- if RUST_JSVAL_IS_VOID(val) == 1 {
+ if val.is_undefined() {
ptr::null()
} else {
- RUST_JSVAL_TO_OBJECT(val)
+ val.to_object()
}
}
}
@@ -116,7 +117,7 @@ pub fn EnsureExpandoObject(cx: *JSContext, obj: *JSObject) -> *JSObject {
return ptr::null();
}
- SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, RUST_OBJECT_TO_JSVAL(expando));
+ SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(&*expando));
}
return expando;
}
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index 22f10b65c47..54e518fcc97 100644
--- a/src/components/script/dom/bindings/utils.rs
+++ b/src/components/script/dom/bindings/utils.rs
@@ -19,41 +19,30 @@ use std::str;
use std::vec;
use std::unstable::raw::Box;
use js::glue::*;
-use js::glue::{RUST_OBJECT_TO_JSVAL};
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
-use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
+use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo};
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAndLength};
use js::jsapi::{JS_ObjectIsRegExp, JS_ObjectIsDate};
use js::jsapi::{JS_InternString, JS_GetFunctionObject};
use js::jsapi::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject};
-use js::jsapi::{JS_NewUCStringCopyN, JS_DefineFunctions, JS_DefineProperty};
+use js::jsapi::{JS_DefineFunctions, JS_DefineProperty};
use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative};
-use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
+use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSPropertyDescriptor};
use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
use js::jsapi::{JSString};
use js::jsapi::{JS_AllowGC, JS_InhibitGC};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
-use js::{JSPROP_ENUMERATE, JSVAL_NULL, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
+use js::jsval::JSVal;
+use js::jsval::{PrivateValue, ObjectValue, NullValue, Int32Value};
+use js::jsval::{UInt32Value, DoubleValue, BooleanValue, UndefinedValue};
+use js::{JSPROP_ENUMERATE, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER};
-use js::{JSPROP_SETTER, JSVAL_VOID, JSVAL_TRUE, JSVAL_FALSE};
+use js::JSPROP_SETTER;
use js::{JSFUN_CONSTRUCTOR, JSPROP_READONLY};
use js;
-mod jsval {
- use js::glue::{RUST_JSVAL_IS_NULL, RUST_JSVAL_IS_VOID};
- use js::jsapi::JSVal;
-
- pub fn is_null(v: JSVal) -> bool {
- unsafe { RUST_JSVAL_IS_NULL(v) == 1 }
- }
-
- pub fn is_undefined(v: JSVal) -> bool {
- unsafe { RUST_JSVAL_IS_VOID(v) == 1 }
- }
-}
-
pub struct GlobalStaticData {
proxy_handlers: HashMap<uint, *libc::c_void>,
attribute_ids: HashMap<uint, ~[jsid]>,
@@ -96,7 +85,7 @@ pub unsafe fn dom_object_slot(obj: *JSObject) -> u32 {
pub unsafe fn unwrap<T>(obj: *JSObject) -> T {
let slot = dom_object_slot(obj);
let val = JS_GetReservedSlot(obj, slot);
- cast::transmute(RUST_JSVAL_TO_PRIVATE(val))
+ cast::transmute(val.to_private())
}
pub unsafe fn get_dom_class(obj: *JSObject) -> Result<DOMClass, ()> {
@@ -142,7 +131,7 @@ pub fn unwrap_jsmanaged<T: Reflectable>(obj: *JSObject,
pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
unsafe {
- let obj = RUST_JSVAL_TO_OBJECT(*val);
+ let obj = (*val).to_object();
unwrap_object(obj, proto_id, proto_depth)
}
}
@@ -172,59 +161,6 @@ pub fn jsid_to_str(cx: *JSContext, id: jsid) -> DOMString {
}
}
-#[deriving(Eq)]
-pub enum StringificationBehavior {
- Default,
- Empty,
-}
-
-pub fn jsval_to_str(cx: *JSContext, v: JSVal,
- nullBehavior: StringificationBehavior) -> Result<DOMString, ()> {
- if jsval::is_null(v) && nullBehavior == Empty {
- Ok(~"")
- } else {
- let jsstr = unsafe { JS_ValueToString(cx, v) };
- if jsstr.is_null() {
- debug!("JS_ValueToString failed");
- Err(())
- } else {
- Ok(jsstring_to_str(cx, jsstr))
- }
- }
-}
-
-pub fn jsval_to_domstring(cx: *JSContext, v: JSVal) -> Result<Option<DOMString>, ()> {
- if jsval::is_null(v) || jsval::is_undefined(v) {
- Ok(None)
- } else {
- let jsstr = unsafe { JS_ValueToString(cx, v) };
- if jsstr.is_null() {
- debug!("JS_ValueToString failed");
- Err(())
- } else {
- Ok(Some(jsstring_to_str(cx, jsstr)))
- }
- }
-}
-
-pub unsafe fn str_to_jsval(cx: *JSContext, string: DOMString) -> JSVal {
- let string_utf16 = string.to_utf16();
- let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr(), string_utf16.len() as libc::size_t);
- if jsstr.is_null() {
- // FIXME: is there something else we should do on failure?
- JSVAL_NULL
- } else {
- RUST_STRING_TO_JSVAL(jsstr)
- }
-}
-
-pub unsafe fn domstring_to_jsval(cx: *JSContext, string: Option<DOMString>) -> JSVal {
- match string {
- None => JSVAL_NULL,
- Some(s) => str_to_jsval(cx, s),
- }
-}
-
// We use slot 0 for holding the raw object. This is safe for both
// globals and non-globals.
pub static DOM_OBJECT_SLOT: uint = 0;
@@ -310,7 +246,7 @@ pub struct DOMJSClass {
pub fn GetProtoOrIfaceArray(global: *JSObject) -> **JSObject {
unsafe {
/*assert ((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0;*/
- cast::transmute(RUST_JSVAL_TO_PRIVATE(JS_GetReservedSlot(global, DOM_PROTOTYPE_SLOT)))
+ cast::transmute(JS_GetReservedSlot(global, DOM_PROTOTYPE_SLOT).to_private())
}
}
@@ -335,7 +271,7 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO
unsafe {
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
- RUST_PRIVATE_TO_JSVAL(domClass as *libc::c_void));
+ PrivateValue(domClass as *libc::c_void));
}
}
@@ -394,7 +330,7 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
}
if alreadyDefined == 0 &&
- JS_DefineProperty(cx, receiver, name, RUST_OBJECT_TO_JSVAL(constructor),
+ JS_DefineProperty(cx, receiver, name, ObjectValue(&*constructor),
None, None, 0) == 0 {
return ptr::null();
}
@@ -412,13 +348,12 @@ fn DefineConstants(cx: *JSContext, obj: *JSObject, constants: *ConstantSpec) ->
return true;
}
let jsval = match spec.value {
- NullVal => JSVAL_NULL,
- IntVal(i) => RUST_INT_TO_JSVAL(i),
- UintVal(u) => RUST_UINT_TO_JSVAL(u),
- DoubleVal(d) => RUST_DOUBLE_TO_JSVAL(d),
- BoolVal(b) if b => JSVAL_TRUE,
- BoolVal(_) => JSVAL_FALSE,
- VoidVal => JSVAL_VOID
+ NullVal => NullValue(),
+ IntVal(i) => Int32Value(i),
+ UintVal(u) => UInt32Value(u),
+ DoubleVal(d) => DoubleValue(d),
+ BoolVal(b) => BooleanValue(b),
+ VoidVal => UndefinedValue(),
};
if JS_DefineProperty(cx, obj, spec.name,
jsval, None,
@@ -482,7 +417,7 @@ pub fn initialize_global(global: *JSObject) {
let box_ = squirrel_away_unboxed(protoArray);
JS_SetReservedSlot(global,
DOM_PROTOTYPE_SLOT,
- RUST_PRIVATE_TO_JSVAL(box_ as *libc::c_void));
+ PrivateValue(box_ as *libc::c_void));
}
}
@@ -493,8 +428,8 @@ pub trait Reflectable {
pub fn reflect_dom_object<T: Reflectable>
(obj: ~T,
- window: &window::Window,
- wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~T) -> *JSObject)
+ window: &JS<window::Window>,
+ wrap_fn: extern "Rust" fn(*JSContext, &JS<window::Window>, ~T) -> *JSObject)
-> JS<T> {
JS::new(obj, window, wrap_fn)
}
@@ -525,16 +460,6 @@ impl Reflector {
}
}
-pub fn GetReflector(cx: *JSContext, reflector: &Reflector,
- vp: *mut JSVal) -> JSBool {
- let obj = reflector.get_jsobject();
- assert!(obj.is_not_null());
- unsafe {
- *vp = RUST_OBJECT_TO_JSVAL(obj);
- return JS_WrapValue(cx, cast::transmute(vp));
- }
-}
-
pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found: *mut bool,
vp: *JSVal) -> bool {
unsafe {
@@ -720,32 +645,30 @@ pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject {
}
/// Returns the global object of the realm that the given JS object was created in.
-fn global_object_for_js_object(obj: *JSObject) -> *Box<window::Window> {
+pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
unsafe {
let global = GetGlobalForObjectCrossCompartment(obj);
let clasp = JS_GetClass(global);
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
// FIXME(jdm): Either don't hardcode or sanity assert prototype stuff.
- match unwrap_object::<*Box<window::Window>>(global, PrototypeList::id::Window, 1) {
- Ok(win) => win,
+ match unwrap_object::<*mut Box<window::Window>>(global, PrototypeList::id::Window, 1) {
+ Ok(win) => JS::from_box(win),
Err(_) => fail!("found DOM global that doesn't unwrap to Window"),
}
}
}
fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
- unsafe {
- let win = global_object_for_js_object(obj);
- let js_info = (*win).data.page().js_info();
- match *js_info.get() {
- Some(ref info) => info.js_context.borrow().ptr,
- None => fail!("no JS context for DOM global")
- }
+ let win = global_object_for_js_object(obj);
+ let js_info = win.get().page().js_info();
+ match *js_info.get() {
+ Some(ref info) => info.js_context.borrow().ptr,
+ None => fail!("no JS context for DOM global")
}
}
/// Returns the global object of the realm that the given DOM object was created in.
-pub fn global_object_for_dom_object<T: Reflectable>(obj: &T) -> *Box<window::Window> {
+pub fn global_object_for_dom_object<T: Reflectable>(obj: &T) -> JS<window::Window> {
global_object_for_js_object(obj.reflector().get_jsobject())
}
diff --git a/src/components/script/dom/blob.rs b/src/components/script/dom/blob.rs
index 87034e5107e..f1c4f677cf3 100644
--- a/src/components/script/dom/blob.rs
+++ b/src/components/script/dom/blob.rs
@@ -25,7 +25,7 @@ impl Blob {
pub fn new(window: &JS<Window>) -> JS<Blob> {
reflect_dom_object(~Blob::new_inherited(window.clone()),
- window.get(),
+ window,
BlobBinding::Wrap)
}
}
diff --git a/src/components/script/dom/clientrect.rs b/src/components/script/dom/clientrect.rs
index e4fd8716c26..2e68044c115 100644
--- a/src/components/script/dom/clientrect.rs
+++ b/src/components/script/dom/clientrect.rs
@@ -36,7 +36,7 @@ impl ClientRect {
top: Au, bottom: Au,
left: Au, right: Au) -> JS<ClientRect> {
let rect = ClientRect::new_inherited(window.clone(), top, bottom, left, right);
- reflect_dom_object(~rect, window.get(), ClientRectBinding::Wrap)
+ reflect_dom_object(~rect, window, ClientRectBinding::Wrap)
}
diff --git a/src/components/script/dom/clientrectlist.rs b/src/components/script/dom/clientrectlist.rs
index bae001379ae..3d8ade6031f 100644
--- a/src/components/script/dom/clientrectlist.rs
+++ b/src/components/script/dom/clientrectlist.rs
@@ -28,7 +28,7 @@ impl ClientRectList {
pub fn new(window: &JS<Window>,
rects: ~[JS<ClientRect>]) -> JS<ClientRectList> {
reflect_dom_object(~ClientRectList::new_inherited(window.clone(), rects),
- window.get(), ClientRectListBinding::Wrap)
+ window, ClientRectListBinding::Wrap)
}
pub fn Length(&self) -> u32 {
diff --git a/src/components/script/dom/console.rs b/src/components/script/dom/console.rs
index 3c5a219b39c..8a7a935e918 100644
--- a/src/components/script/dom/console.rs
+++ b/src/components/script/dom/console.rs
@@ -20,7 +20,7 @@ impl Console {
}
}
- pub fn new(window: &Window) -> JS<Console> {
+ pub fn new(window: &JS<Window>) -> JS<Console> {
reflect_dom_object(~Console::new_inherited(), window, ConsoleBinding::Wrap)
}
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index 5994f653f18..07660e30e88 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -21,6 +21,7 @@ use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId};
use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection;
+use dom::nodelist::NodeList;
use dom::htmlelement::HTMLElement;
use dom::htmlheadelement::HTMLHeadElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
@@ -34,7 +35,7 @@ use dom::window::Window;
use html::hubbub_html_parser::build_element_from_tag;
use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks};
use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
-use servo_util::namespace::Null;
+use servo_util::namespace::{Namespace, Null};
use servo_util::str::DOMString;
use extra::url::{Url, from_str};
@@ -86,10 +87,10 @@ impl Document {
pub fn reflect_document<D: Reflectable+DocumentBase>
(document: ~D,
window: &JS<Window>,
- wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~D) -> *JSObject)
+ wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~D) -> *JSObject)
-> JS<D> {
assert!(document.reflector().get_jsobject().is_null());
- let raw_doc = reflect_dom_object(document, window.get(), wrap_fn);
+ let raw_doc = reflect_dom_object(document, window, wrap_fn);
assert!(raw_doc.reflector().get_jsobject().is_not_null());
let document = DocumentCast::from(&raw_doc);
@@ -211,8 +212,22 @@ impl Document {
}
// http://dom.spec.whatwg.org/#dom-document-getelementsbytagname
- pub fn GetElementsByTagName(&self, tag: DOMString) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| elem.tag_name == tag)
+ pub fn GetElementsByTagName(&self, abstract_self: &JS<Document>, tag_name: DOMString) -> JS<HTMLCollection> {
+ HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), tag_name)
+ }
+
+ // http://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens
+ pub fn GetElementsByTagNameNS(&self, abstract_self: &JS<Document>, maybe_ns: Option<DOMString>, tag_name: DOMString) -> JS<HTMLCollection> {
+ let namespace = match maybe_ns {
+ Some(namespace) => Namespace::from_str(namespace),
+ None => Null
+ };
+ HTMLCollection::by_tag_name_ns(&self.window, &NodeCast::from(abstract_self), tag_name, namespace)
+ }
+
+ // http://dom.spec.whatwg.org/#dom-document-getelementsbyclassname
+ pub fn GetElementsByClassName(&self, abstract_self: &JS<Document>, classes: DOMString) -> JS<HTMLCollection> {
+ HTMLCollection::by_class_name(&self.window, &NodeCast::from(abstract_self), classes)
}
// http://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
@@ -403,69 +418,89 @@ impl Document {
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-getelementsbyname
- pub fn GetElementsByName(&self, name: DOMString) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| {
- elem.get_attribute(Null, "name").map_default(false, |attr| {
+ pub fn GetElementsByName(&self, name: DOMString) -> JS<NodeList> {
+ self.createNodeList(|node| {
+ if !node.is_element() {
+ return false;
+ }
+
+ let element: JS<Element> = ElementCast::to(node);
+ element.get().get_attribute(Null, "name").map_default(false, |attr| {
attr.get().value_ref() == name
})
})
}
- pub fn Images(&self) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| "img" == elem.tag_name)
+ pub fn Images(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"img")
}
- pub fn Embeds(&self) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| "embed" == elem.tag_name)
+ pub fn Embeds(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"embed")
}
- pub fn Plugins(&self) -> JS<HTMLCollection> {
- self.Embeds()
+ pub fn Plugins(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ self.Embeds(abstract_self)
}
- pub fn Links(&self) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| {
- ("a" == elem.tag_name || "area" == elem.tag_name) &&
- elem.get_attribute(Null, "href").is_some()
+ pub fn Links(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), |elem| {
+ ("a" == elem.get().tag_name || "area" == elem.get().tag_name) &&
+ elem.get().get_attribute(Null, "href").is_some()
})
}
- pub fn Forms(&self) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| "form" == elem.tag_name)
+ pub fn Forms(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"form")
}
- pub fn Scripts(&self) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| "script" == elem.tag_name)
+ pub fn Scripts(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"script")
}
- pub fn Anchors(&self) -> JS<HTMLCollection> {
- self.createHTMLCollection(|elem| {
- "a" == elem.tag_name && elem.get_attribute(Null, "name").is_some()
+ pub fn Anchors(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1847
+ HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), |elem| {
+ "a" == elem.get().tag_name && elem.get().get_attribute(Null, "name").is_some()
})
}
- pub fn Applets(&self) -> JS<HTMLCollection> {
+ pub fn Applets(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
// FIXME: This should be return OBJECT elements containing applets.
- self.createHTMLCollection(|elem| "applet" == elem.tag_name)
+ HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"applet")
}
- pub fn createHTMLCollection(&self, callback: |elem: &Element| -> bool) -> JS<HTMLCollection> {
- let mut elements = ~[];
+ pub fn create_collection<T>(&self, callback: |elem: &JS<Node>| -> Option<JS<T>>) -> ~[JS<T>] {
+ let mut nodes = ~[];
match self.GetDocumentElement() {
None => {},
Some(root) => {
let root: JS<Node> = NodeCast::from(&root);
for child in root.traverse_preorder() {
- if child.is_element() {
- let elem: JS<Element> = ElementCast::to(&child);
- if callback(elem.get()) {
- elements.push(elem);
- }
+ match callback(&child) {
+ Some(node) => nodes.push(node),
+ None => (),
}
}
}
}
- HTMLCollection::new(&self.window, elements)
+ nodes
+ }
+
+ pub fn createNodeList(&self, callback: |node: &JS<Node>| -> bool) -> JS<NodeList> {
+ NodeList::new_simple_list(&self.window, self.create_collection(|node| {
+ if !callback(node) {
+ return None;
+ }
+
+ Some(node.clone())
+ }))
}
pub fn content_changed(&self) {
diff --git a/src/components/script/dom/domexception.rs b/src/components/script/dom/domexception.rs
index f6eb1751adc..9d8142ac938 100644
--- a/src/components/script/dom/domexception.rs
+++ b/src/components/script/dom/domexception.rs
@@ -48,7 +48,7 @@ impl DOMException {
}
}
- pub fn new(window: &Window, code: DOMErrorName) -> JS<DOMException> {
+ pub fn new(window: &JS<Window>, code: DOMErrorName) -> JS<DOMException> {
reflect_dom_object(~DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap)
}
}
diff --git a/src/components/script/dom/domimplementation.rs b/src/components/script/dom/domimplementation.rs
index 47ba1026dec..5a11d0119d4 100644
--- a/src/components/script/dom/domimplementation.rs
+++ b/src/components/script/dom/domimplementation.rs
@@ -34,7 +34,7 @@ impl DOMImplementation {
}
pub fn new(owner: &JS<Window>) -> JS<DOMImplementation> {
- reflect_dom_object(~DOMImplementation::new_inherited(owner.clone()), owner.get(),
+ reflect_dom_object(~DOMImplementation::new_inherited(owner.clone()), owner,
DOMImplementationBinding::Wrap)
}
}
diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs
index 3e20ea2941a..1ab00d1f14d 100644
--- a/src/components/script/dom/domparser.rs
+++ b/src/components/script/dom/domparser.rs
@@ -26,7 +26,7 @@ impl DOMParser {
}
pub fn new(owner: &JS<Window>) -> JS<DOMParser> {
- reflect_dom_object(~DOMParser::new_inherited(owner.clone()), owner.get(),
+ reflect_dom_object(~DOMParser::new_inherited(owner.clone()), owner,
DOMParserBinding::Wrap)
}
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index 2805ea8c25e..95e4e7f9af9 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -220,7 +220,7 @@ impl Element {
None => {
let doc = self.node.owner_doc();
let doc = doc.get();
- let new_attr = Attr::new_ns(doc.window.get(), local_name.clone(), value.clone(),
+ let new_attr = Attr::new_ns(&doc.window, local_name.clone(), value.clone(),
name.clone(), namespace.clone(),
prefix);
self.attrs.push(new_attr);
@@ -370,6 +370,13 @@ impl Element {
_ => false
}
}
+
+ pub fn has_class(&self, name: &str) -> bool {
+ // FIXME: https://github.com/mozilla/servo/issues/1840
+ let class_names = self.get_string_attribute("class");
+ let mut classes = class_names.split(' ');
+ classes.any(|class| name == class)
+ }
}
// http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes
@@ -503,25 +510,27 @@ impl Element {
self.GetAttributeNS(namespace, local_name).is_some()
}
- // http://dom.spec.whatwg.org/#dom-element-getelementsbytagname
- pub fn GetElementsByTagName(&self, _localname: DOMString) -> JS<HTMLCollection> {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1660
+ pub fn GetElementsByTagName(&self, abstract_self: &JS<Element>, localname: DOMString) -> JS<HTMLCollection> {
let doc = self.node.owner_doc();
- HTMLCollection::new(&doc.get().window, ~[])
+ let doc = doc.get();
+ HTMLCollection::by_tag_name(&doc.window, &NodeCast::from(abstract_self), localname)
}
- // http://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens
- pub fn GetElementsByTagNameNS(&self, _namespace: Option<DOMString>, _localname: DOMString) -> Fallible<JS<HTMLCollection>> {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1660
+ pub fn GetElementsByTagNameNS(&self, abstract_self: &JS<Element>, maybe_ns: Option<DOMString>,
+ localname: DOMString) -> JS<HTMLCollection> {
let doc = self.node.owner_doc();
- Ok(HTMLCollection::new(&doc.get().window, ~[]))
+ let doc = doc.get();
+ let namespace = match maybe_ns {
+ Some(namespace) => Namespace::from_str(namespace),
+ None => Null
+ };
+ HTMLCollection::by_tag_name_ns(&doc.window, &NodeCast::from(abstract_self), localname, namespace)
}
- // http://dom.spec.whatwg.org/#dom-element-getelementsbyclassname
- pub fn GetElementsByClassName(&self, _names: DOMString) -> JS<HTMLCollection> {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1660
+ pub fn GetElementsByClassName(&self, abstract_self: &JS<Element>, classes: DOMString) -> JS<HTMLCollection> {
let doc = self.node.owner_doc();
- HTMLCollection::new(&doc.get().window, ~[])
+ let doc = doc.get();
+ HTMLCollection::by_class_name(&doc.window, &NodeCast::from(abstract_self), classes)
}
// http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects
diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs
index 4c3fb0e5b5b..6b612b4a220 100644
--- a/src/components/script/dom/event.rs
+++ b/src/components/script/dom/event.rs
@@ -77,7 +77,7 @@ impl Event {
pub fn new(window: &JS<Window>) -> JS<Event> {
reflect_dom_object(~Event::new_inherited(HTMLEventTypeId),
- window.get(),
+ window,
EventBinding::Wrap)
}
diff --git a/src/components/script/dom/eventdispatcher.rs b/src/components/script/dom/eventdispatcher.rs
index c22ef7716c1..699dc1f68b5 100644
--- a/src/components/script/dom/eventdispatcher.rs
+++ b/src/components/script/dom/eventdispatcher.rs
@@ -17,10 +17,9 @@ pub fn dispatch_event(target: &JS<EventTarget>,
{
let event = event.get_mut();
- event.target = match pseudo_target {
- Some(pseudo_target) => Some(pseudo_target),
- None => Some(target.clone())
- };
+ event.target = pseudo_target.or_else(|| {
+ Some(target.clone())
+ });
event.dispatching = true;
}
diff --git a/src/components/script/dom/formdata.rs b/src/components/script/dom/formdata.rs
index 011722ea275..bd4c7a03d6e 100644
--- a/src/components/script/dom/formdata.rs
+++ b/src/components/script/dom/formdata.rs
@@ -38,7 +38,7 @@ impl FormData {
}
pub fn new(form: Option<JS<HTMLFormElement>>, window: &JS<Window>) -> JS<FormData> {
- reflect_dom_object(~FormData::new_inherited(form, window.clone()), window.get(), FormDataBinding::Wrap)
+ reflect_dom_object(~FormData::new_inherited(form, window.clone()), window, FormDataBinding::Wrap)
}
pub fn Constructor(window: &JS<Window>, form: Option<JS<HTMLFormElement>>)
diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs
index 0ad4d94d357..96e04d46d3b 100644
--- a/src/components/script/dom/htmlcollection.rs
+++ b/src/components/script/dom/htmlcollection.rs
@@ -2,18 +2,16 @@
* 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/. */
+use dom::bindings::codegen::InheritTypes::{ElementCast};
use dom::bindings::codegen::HTMLCollectionBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
-use dom::bindings::error::Fallible;
use dom::element::Element;
+use dom::node::{Node, NodeHelpers};
use dom::window::Window;
+use servo_util::namespace::Namespace;
use servo_util::str::DOMString;
-use js::jsapi::{JSObject, JSContext};
-
-use std::ptr;
-
#[deriving(Encodable)]
pub struct HTMLCollection {
elements: ~[JS<Element>],
@@ -32,13 +30,46 @@ impl HTMLCollection {
pub fn new(window: &JS<Window>, elements: ~[JS<Element>]) -> JS<HTMLCollection> {
reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), elements),
- window.get(), HTMLCollectionBinding::Wrap)
+ window, HTMLCollectionBinding::Wrap)
+ }
+}
+
+impl HTMLCollection {
+ pub fn create(window: &JS<Window>, root: &JS<Node>, predicate: |elem: &JS<Element>| -> bool) -> JS<HTMLCollection> {
+ let mut elements = ~[];
+ for child in root.traverse_preorder() {
+ if child.is_element() {
+ let elem: JS<Element> = ElementCast::to(&child);
+ if predicate(&elem) {
+ elements.push(elem);
+ }
+ }
+ }
+ HTMLCollection::new(window, elements)
+ }
+
+ pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag_name: DOMString) -> JS<HTMLCollection> {
+ HTMLCollection::create(window, root, |elem| elem.get().tag_name == tag_name)
+ }
+
+ pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag_name: DOMString, namespace: Namespace) -> JS<HTMLCollection> {
+ HTMLCollection::create(window, root, |elem| elem.get().namespace == namespace && elem.get().tag_name == tag_name)
}
-
+
+ pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1840
+ let classes: ~[&str] = classes.split(' ').collect();
+ HTMLCollection::create(window, root, |elem| classes.iter().all(|class| elem.get().has_class(*class)))
+ }
+}
+
+impl HTMLCollection {
+ // http://dom.spec.whatwg.org/#dom-htmlcollection-length
pub fn Length(&self) -> u32 {
self.elements.len() as u32
}
+ // http://dom.spec.whatwg.org/#dom-htmlcollection-item
pub fn Item(&self, index: u32) -> Option<JS<Element>> {
if index < self.Length() {
Some(self.elements[index].clone())
@@ -47,17 +78,40 @@ impl HTMLCollection {
}
}
- pub fn NamedItem(&self, _cx: *JSContext, _name: DOMString) -> Fallible<*JSObject> {
- Ok(ptr::null())
+ // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
+ pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> {
+ // Step 1.
+ if key.is_empty() {
+ return None;
+ }
+
+ // Step 2.
+ self.elements.iter().find(|elem| {
+ let elem = elem.get();
+ elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key
+ }).map(|maybe_elem| maybe_elem.clone())
}
+}
+impl HTMLCollection {
pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> {
- *found = true;
- self.Item(index)
+ let maybe_elem = self.Item(index);
+ *found = maybe_elem.is_some();
+ maybe_elem
}
- pub fn NamedGetter(&self, _cx: *JSContext, _name: Option<DOMString>, _found: &mut bool) -> Fallible<*JSObject> {
- Ok(ptr::null())
+ pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<JS<Element>> {
+ match maybe_name {
+ Some(name) => {
+ let maybe_elem = self.NamedItem(name);
+ *found = maybe_elem.is_some();
+ maybe_elem
+ },
+ None => {
+ *found = false;
+ None
+ }
+ }
}
}
diff --git a/src/components/script/dom/htmldatalistelement.rs b/src/components/script/dom/htmldatalistelement.rs
index 6cd888029c2..ef3f91f1702 100644
--- a/src/components/script/dom/htmldatalistelement.rs
+++ b/src/components/script/dom/htmldatalistelement.rs
@@ -42,6 +42,7 @@ impl HTMLDataListElement {
impl HTMLDataListElement {
pub fn Options(&self) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1842
let doc = self.htmlelement.element.node.owner_doc();
let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
diff --git a/src/components/script/dom/htmlelement.rs b/src/components/script/dom/htmlelement.rs
index b27afdfff2e..8464d23aec0 100644
--- a/src/components/script/dom/htmlelement.rs
+++ b/src/components/script/dom/htmlelement.rs
@@ -10,8 +10,8 @@ use dom::document::Document;
use dom::element::{Element, ElementTypeId, HTMLElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{Node, ElementNodeTypeId};
-use js::jsapi::{JSContext, JSVal};
-use js::JSVAL_NULL;
+use js::jsapi::JSContext;
+use js::jsval::{JSVal, NullValue};
use servo_util::namespace;
use servo_util::str::DOMString;
@@ -66,7 +66,7 @@ impl HTMLElement {
}
pub fn GetItemValue(&self, _cx: *JSContext) -> Fallible<JSVal> {
- Ok(JSVAL_NULL)
+ Ok(NullValue())
}
pub fn SetItemValue(&mut self, _cx: *JSContext, _val: JSVal) -> ErrorResult {
diff --git a/src/components/script/dom/htmlfieldsetelement.rs b/src/components/script/dom/htmlfieldsetelement.rs
index cdfc6eab402..4dec639d041 100644
--- a/src/components/script/dom/htmlfieldsetelement.rs
+++ b/src/components/script/dom/htmlfieldsetelement.rs
@@ -69,6 +69,7 @@ impl HTMLFieldSetElement {
}
pub fn Elements(&self) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1843
let doc = self.htmlelement.element.node.owner_doc();
let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
diff --git a/src/components/script/dom/htmlformelement.rs b/src/components/script/dom/htmlformelement.rs
index 03d2ee8eeb1..a1ca7d5dc2f 100644
--- a/src/components/script/dom/htmlformelement.rs
+++ b/src/components/script/dom/htmlformelement.rs
@@ -115,6 +115,7 @@ impl HTMLFormElement {
}
pub fn Elements(&self) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1844
let doc = self.htmlelement.element.node.owner_doc();
let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
diff --git a/src/components/script/dom/htmlmapelement.rs b/src/components/script/dom/htmlmapelement.rs
index 41516e9a5d2..d343073a278 100644
--- a/src/components/script/dom/htmlmapelement.rs
+++ b/src/components/script/dom/htmlmapelement.rs
@@ -51,6 +51,7 @@ impl HTMLMapElement {
}
pub fn Areas(&self) -> JS<HTMLCollection> {
+ // FIXME: https://github.com/mozilla/servo/issues/1845
let doc = self.htmlelement.element.node.owner_doc();
let doc = doc.get();
HTMLCollection::new(&doc.window, ~[])
diff --git a/src/components/script/dom/location.rs b/src/components/script/dom/location.rs
index 7d0c5294711..2fc06fb353b 100644
--- a/src/components/script/dom/location.rs
+++ b/src/components/script/dom/location.rs
@@ -41,7 +41,7 @@ impl Location {
}
}
- pub fn new(window: &Window, page: Rc<Page>) -> JS<Location> {
+ pub fn new(window: &JS<Window>, page: Rc<Page>) -> JS<Location> {
reflect_dom_object(~Location::new_inherited(page),
window,
LocationBinding::Wrap)
diff --git a/src/components/script/dom/mouseevent.rs b/src/components/script/dom/mouseevent.rs
index 0e11d2e838b..8741ea48a68 100644
--- a/src/components/script/dom/mouseevent.rs
+++ b/src/components/script/dom/mouseevent.rs
@@ -54,7 +54,7 @@ impl MouseEvent {
pub fn new(window: &JS<Window>) -> JS<MouseEvent> {
reflect_dom_object(~MouseEvent::new_inherited(),
- window.get(),
+ window,
MouseEventBinding::Wrap)
}
diff --git a/src/components/script/dom/navigator.rs b/src/components/script/dom/navigator.rs
index e3c648ec4ed..140fa082f91 100644
--- a/src/components/script/dom/navigator.rs
+++ b/src/components/script/dom/navigator.rs
@@ -21,7 +21,7 @@ impl Navigator {
}
}
- pub fn new(window: &Window) -> JS<Navigator> {
+ pub fn new(window: &JS<Window>) -> JS<Navigator> {
reflect_dom_object(~Navigator::new_inherited(),
window,
NavigatorBinding::Wrap)
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs
index ef3b4a03ffa..9999503a758 100644
--- a/src/components/script/dom/node.rs
+++ b/src/components/script/dom/node.rs
@@ -754,10 +754,10 @@ impl Node {
pub fn reflect_node<N: Reflectable+NodeBase>
(node: ~N,
document: &JS<Document>,
- wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~N) -> *JSObject)
+ wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~N) -> *JSObject)
-> JS<N> {
assert!(node.reflector().get_jsobject().is_null());
- let node = reflect_dom_object(node, document.get().window.get(), wrap_fn);
+ let node = reflect_dom_object(node, &document.get().window, wrap_fn);
assert!(node.reflector().get_jsobject().is_not_null());
node
}
@@ -840,6 +840,7 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-baseuri
pub fn GetBaseURI(&self) -> Option<DOMString> {
+ // FIXME (#1824) implement.
None
}
@@ -873,6 +874,20 @@ impl Node {
self.first_child.is_some()
}
+ // http://dom.spec.whatwg.org/#dom-node-childnodes
+ pub fn ChildNodes(&mut self, abstract_self: &JS<Node>) -> JS<NodeList> {
+ match self.child_list {
+ None => {
+ let doc = self.owner_doc();
+ let doc = doc.get();
+ let list = NodeList::new_child_list(&doc.window, abstract_self);
+ self.child_list = Some(list.clone());
+ list
+ }
+ Some(ref list) => list.clone()
+ }
+ }
+
// http://dom.spec.whatwg.org/#dom-node-firstchild
pub fn GetFirstChild(&self) -> Option<JS<Node>> {
self.first_child.clone()
@@ -909,9 +924,16 @@ impl Node {
}
// http://dom.spec.whatwg.org/#dom-node-nodevalue
- pub fn SetNodeValue(&mut self, _abstract_self: &JS<Node>, _val: Option<DOMString>)
+ pub fn SetNodeValue(&mut self, abstract_self: &mut JS<Node>, val: Option<DOMString>)
-> ErrorResult {
- // FIXME: Stub - https://github.com/mozilla/servo/issues/1655
+ match self.type_id {
+ CommentNodeTypeId |
+ TextNodeTypeId |
+ ProcessingInstructionNodeTypeId => {
+ self.SetTextContent(abstract_self, val);
+ }
+ _ => {}
+ }
Ok(())
}
@@ -942,18 +964,39 @@ impl Node {
}
}
- // http://dom.spec.whatwg.org/#dom-node-childnodes
- pub fn ChildNodes(&mut self, abstract_self: &JS<Node>) -> JS<NodeList> {
- match self.child_list {
- None => {
- let doc = self.owner_doc();
- let doc = doc.get();
- let list = NodeList::new_child_list(&doc.window, abstract_self);
- self.child_list = Some(list.clone());
- list
+ // http://dom.spec.whatwg.org/#dom-node-textcontent
+ pub fn SetTextContent(&mut self, abstract_self: &mut JS<Node>, value: Option<DOMString>)
+ -> ErrorResult {
+ let value = null_str_as_empty(&value);
+ match self.type_id {
+ DocumentFragmentNodeTypeId |
+ ElementNodeTypeId(..) => {
+ // Step 1-2.
+ let node = if value.len() == 0 {
+ None
+ } else {
+ let document = self.owner_doc();
+ Some(NodeCast::from(&document.get().CreateTextNode(&document, value)))
+ };
+ // Step 3.
+ Node::replace_all(node, abstract_self);
}
- Some(ref list) => list.clone()
+ CommentNodeTypeId |
+ TextNodeTypeId |
+ ProcessingInstructionNodeTypeId => {
+ self.wait_until_safe_to_modify_dom();
+
+ let mut characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self);
+ characterdata.get_mut().data = value.clone();
+
+ // Notify the document that the content of this node is different
+ let document = self.owner_doc();
+ document.get().content_changed();
+ }
+ DoctypeNodeTypeId |
+ DocumentNodeTypeId => {}
}
+ Ok(())
}
// http://dom.spec.whatwg.org/#concept-node-adopt
@@ -1227,41 +1270,6 @@ impl Node {
}
}
- // http://dom.spec.whatwg.org/#dom-node-textcontent
- pub fn SetTextContent(&mut self, abstract_self: &mut JS<Node>, value: Option<DOMString>)
- -> ErrorResult {
- let value = null_str_as_empty(&value);
- match self.type_id {
- DocumentFragmentNodeTypeId |
- ElementNodeTypeId(..) => {
- // Step 1-2.
- let node = if value.len() == 0 {
- None
- } else {
- let document = self.owner_doc();
- Some(NodeCast::from(&document.get().CreateTextNode(&document, value)))
- };
- // Step 3.
- Node::replace_all(node, abstract_self);
- }
- CommentNodeTypeId |
- TextNodeTypeId |
- ProcessingInstructionNodeTypeId => {
- self.wait_until_safe_to_modify_dom();
-
- let mut characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self);
- characterdata.get_mut().data = value.clone();
-
- // Notify the document that the content of this node is different
- let document = self.owner_doc();
- document.get().content_changed();
- }
- DoctypeNodeTypeId |
- DocumentNodeTypeId => {}
- }
- Ok(())
- }
-
// http://dom.spec.whatwg.org/#dom-node-insertbefore
pub fn InsertBefore(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>, child: Option<JS<Node>>)
-> Fallible<JS<Node>> {
@@ -1415,7 +1423,7 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-normalize
pub fn Normalize(&mut self) {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1655
+ // FIXME (#1823) implement.
}
// http://dom.spec.whatwg.org/#dom-node-clonenode
@@ -1500,7 +1508,7 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
pub fn CompareDocumentPosition(&self, _other: &JS<Node>) -> u16 {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1655
+ // FIXME (#1794) implement.
0
}
@@ -1514,19 +1522,19 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-lookupprefix
pub fn LookupPrefix(&self, _prefix: Option<DOMString>) -> Option<DOMString> {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1655
+ // FIXME (#1826) implement.
None
}
// http://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri
pub fn LookupNamespaceURI(&self, _namespace: Option<DOMString>) -> Option<DOMString> {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1655
+ // FIXME (#1826) implement.
None
}
// http://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
pub fn IsDefaultNamespace(&self, _namespace: Option<DOMString>) -> bool {
- // FIXME: stub - https://github.com/mozilla/servo/issues/1655
+ // FIXME (#1826) implement.
false
}
@@ -1545,11 +1553,6 @@ impl Node {
None
}
- // http://dom.spec.whatwg.org/#dom-node-hasattributes
- pub fn HasAttributes(&self) -> bool {
- false
- }
-
//
// Low-level pointer stitching
//
diff --git a/src/components/script/dom/nodelist.rs b/src/components/script/dom/nodelist.rs
index 84de1a56d19..ab2bbb7f575 100644
--- a/src/components/script/dom/nodelist.rs
+++ b/src/components/script/dom/nodelist.rs
@@ -31,18 +31,18 @@ impl NodeList {
}
}
- pub fn new(window: JS<Window>,
+ pub fn new(window: &JS<Window>,
list_type: NodeListType) -> JS<NodeList> {
reflect_dom_object(~NodeList::new_inherited(window.clone(), list_type),
- window.get(), NodeListBinding::Wrap)
+ window, NodeListBinding::Wrap)
}
pub fn new_simple_list(window: &JS<Window>, elements: ~[JS<Node>]) -> JS<NodeList> {
- NodeList::new(window.clone(), Simple(elements))
+ NodeList::new(window, Simple(elements))
}
pub fn new_child_list(window: &JS<Window>, node: &JS<Node>) -> JS<NodeList> {
- NodeList::new(window.clone(), Children(node.clone()))
+ NodeList::new(window, Children(node.clone()))
}
pub fn Length(&self) -> u32 {
diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs
new file mode 100644
index 00000000000..514260c5c10
--- /dev/null
+++ b/src/components/script/dom/testbinding.rs
@@ -0,0 +1,155 @@
+/* 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/. */
+
+use dom::bindings::js::JS;
+use dom::bindings::utils::{Reflector, Reflectable};
+use dom::blob::Blob;
+use dom::window::Window;
+use servo_util::str::DOMString;
+
+use js::jsapi::JSContext;
+use js::jsval::{JSVal, NullValue};
+
+#[deriving(Encodable)]
+pub struct TestBinding {
+ reflector: Reflector,
+ window: JS<Window>,
+}
+
+impl TestBinding {
+ pub fn BooleanAttribute(&self) -> bool { false }
+ pub fn SetBooleanAttribute(&self, _: bool) {}
+ pub fn ByteAttribute(&self) -> i8 { 0 }
+ pub fn SetByteAttribute(&self, _: i8) {}
+ pub fn OctetAttribute(&self) -> u8 { 0 }
+ pub fn SetOctetAttribute(&self, _: u8) {}
+ pub fn ShortAttribute(&self) -> i16 { 0 }
+ pub fn SetShortAttribute(&self, _: i16) {}
+ pub fn UnsignedShortAttribute(&self) -> u16 { 0 }
+ pub fn SetUnsignedShortAttribute(&self, _: u16) {}
+ pub fn LongAttribute(&self) -> i32 { 0 }
+ pub fn SetLongAttribute(&self, _: i32) {}
+ pub fn UnsignedLongAttribute(&self) -> u32 { 0 }
+ pub fn SetUnsignedLongAttribute(&self, _: u32) {}
+ pub fn LongLongAttribute(&self) -> i64 { 0 }
+ pub fn SetLongLongAttribute(&self, _: i64) {}
+ pub fn UnsignedLongLongAttribute(&self) -> u64 { 0 }
+ pub fn SetUnsignedLongLongAttribute(&self, _: u64) {}
+ pub fn FloatAttribute(&self) -> f32 { 0. }
+ pub fn SetFloatAttribute(&self, _: f32) {}
+ pub fn DoubleAttribute(&self) -> f64 { 0. }
+ pub fn SetDoubleAttribute(&self, _: f64) {}
+ pub fn StringAttribute(&self) -> DOMString { ~"" }
+ pub fn SetStringAttribute(&self, _: DOMString) {}
+ pub fn InterfaceAttribute(&self) -> JS<Blob> { Blob::new(&self.window) }
+ pub fn SetInterfaceAttribute(&self, _: &JS<Blob>) {}
+ pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() }
+ pub fn SetAnyAttribute(&self, _: *JSContext, _: JSVal) {}
+
+ pub fn GetBooleanAttributeNullable(&self) -> Option<bool> { Some(false) }
+ pub fn SetBooleanAttributeNullable(&self, _: Option<bool>) {}
+ pub fn GetByteAttributeNullable(&self) -> Option<i8> { Some(0) }
+ pub fn SetByteAttributeNullable(&self, _: Option<i8>) {}
+ pub fn GetOctetAttributeNullable(&self) -> Option<u8> { Some(0) }
+ pub fn SetOctetAttributeNullable(&self, _: Option<u8>) {}
+ pub fn GetShortAttributeNullable(&self) -> Option<i16> { Some(0) }
+ pub fn SetShortAttributeNullable(&self, _: Option<i16>) {}
+ pub fn GetUnsignedShortAttributeNullable(&self) -> Option<u16> { Some(0) }
+ pub fn SetUnsignedShortAttributeNullable(&self, _: Option<u16>) {}
+ pub fn GetLongAttributeNullable(&self) -> Option<i32> { Some(0) }
+ pub fn SetLongAttributeNullable(&self, _: Option<i32>) {}
+ pub fn GetUnsignedLongAttributeNullable(&self) -> Option<u32> { Some(0) }
+ pub fn SetUnsignedLongAttributeNullable(&self, _: Option<u32>) {}
+ pub fn GetLongLongAttributeNullable(&self) -> Option<i64> { Some(0) }
+ pub fn SetLongLongAttributeNullable(&self, _: Option<i64>) {}
+ pub fn GetUnsignedLongLongAttributeNullable(&self) -> Option<u64> { Some(0) }
+ pub fn SetUnsignedLongLongAttributeNullable(&self, _: Option<u64>) {}
+ pub fn GetFloatAttributeNullable(&self) -> Option<f32> { Some(0.) }
+ pub fn SetFloatAttributeNullable(&self, _: Option<f32>) {}
+ pub fn GetDoubleAttributeNullable(&self) -> Option<f64> { Some(0.) }
+ pub fn SetDoubleAttributeNullable(&self, _: Option<f64>) {}
+ pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") }
+ pub fn SetStringAttributeNullable(&self, _: Option<DOMString>) {}
+ pub fn GetInterfaceAttributeNullable(&self) -> Option<JS<Blob>> { Some(Blob::new(&self.window)) }
+ pub fn SetInterfaceAttributeNullable(&self, _: Option<JS<Blob>>) {}
+
+ // FIXME (issue #1813) Doesn't currently compile.
+ // pub fn PassOptionalBoolean(&self, _: Option<bool>) {}
+ // pub fn PassOptionalByte(&self, _: Option<i8>) {}
+ // pub fn PassOptionalOctet(&self, _: Option<u8>) {}
+ // pub fn PassOptionalShort(&self, _: Option<i16>) {}
+ // pub fn PassOptionalUnsignedShort(&self, _: Option<u16>) {}
+ // pub fn PassOptionalLong(&self, _: Option<i32>) {}
+ // pub fn PassOptionalUnsignedLong(&self, _: Option<u32>) {}
+ // pub fn PassOptionalLongLong(&self, _: Option<i64>) {}
+ // pub fn PassOptionalUnsignedLongLong(&self, _: Option<u64>) {}
+ // pub fn PassOptionalFloat(&self, _: Option<f32>) {}
+ // pub fn PassOptionalDouble(&self, _: Option<f64>) {}
+ pub fn PassOptionalString(&self, _: Option<DOMString>) {}
+ pub fn PassOptionalInterface(&self, _: Option<JS<Blob>>) {}
+ pub fn PassOptionalAny(&self, _: *JSContext, _: Option<JSVal>) {}
+
+ // pub fn PassOptionalNullableBoolean(&self, _: Option<Option<bool>>) {}
+ // pub fn PassOptionalNullableByte(&self, _: Option<Option<i8>>) {}
+ // pub fn PassOptionalNullableOctet(&self, _: Option<Option<u8>>) {}
+ // pub fn PassOptionalNullableShort(&self, _: Option<Option<i16>>) {}
+ // pub fn PassOptionalNullableUnsignedShort(&self, _: Option<Option<u16>>) {}
+ // pub fn PassOptionalNullableLong(&self, _: Option<Option<i32>>) {}
+ // pub fn PassOptionalNullableUnsignedLong(&self, _: Option<Option<u32>>) {}
+ // pub fn PassOptionalNullableLongLong(&self, _: Option<Option<i64>>) {}
+ // pub fn PassOptionalNullableUnsignedLongLong(&self, _: Option<Option<u64>>) {}
+ // pub fn PassOptionalNullableFloat(&self, _: Option<Option<f32>>) {}
+ // pub fn PassOptionalNullableDouble(&self, _: Option<Option<f64>>) {}
+ pub fn PassOptionalNullableString(&self, _: Option<Option<DOMString>>) {}
+ // pub fn PassOptionalNullableInterface(&self, _: Option<Option<JS<Blob>>>) {}
+
+ pub fn PassOptionalBooleanWithDefault(&self, _: bool) {}
+ pub fn PassOptionalByteWithDefault(&self, _: i8) {}
+ pub fn PassOptionalOctetWithDefault(&self, _: u8) {}
+ pub fn PassOptionalShortWithDefault(&self, _: i16) {}
+ pub fn PassOptionalUnsignedShortWithDefault(&self, _: u16) {}
+ pub fn PassOptionalLongWithDefault(&self, _: i32) {}
+ pub fn PassOptionalUnsignedLongWithDefault(&self, _: u32) {}
+ pub fn PassOptionalLongLongWithDefault(&self, _: i64) {}
+ pub fn PassOptionalUnsignedLongLongWithDefault(&self, _: u64) {}
+ pub fn PassOptionalStringWithDefault(&self, _: DOMString) {}
+
+ pub fn PassOptionalNullableBooleanWithDefault(&self, _: Option<bool>) {}
+ pub fn PassOptionalNullableByteWithDefault(&self, _: Option<i8>) {}
+ pub fn PassOptionalNullableOctetWithDefault(&self, _: Option<u8>) {}
+ pub fn PassOptionalNullableShortWithDefault(&self, _: Option<i16>) {}
+ pub fn PassOptionalNullableUnsignedShortWithDefault(&self, _: Option<u16>) {}
+ pub fn PassOptionalNullableLongWithDefault(&self, _: Option<i32>) {}
+ pub fn PassOptionalNullableUnsignedLongWithDefault(&self, _: Option<u32>) {}
+ pub fn PassOptionalNullableLongLongWithDefault(&self, _: Option<i64>) {}
+ pub fn PassOptionalNullableUnsignedLongLongWithDefault(&self, _: Option<u64>) {}
+ pub fn PassOptionalNullableFloatWithDefault(&self, _: Option<f32>) {}
+ pub fn PassOptionalNullableDoubleWithDefault(&self, _: Option<f64>) {}
+ // pub fn PassOptionalNullableStringWithDefault(&self, _: Option<DOMString>) {}
+ pub fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JS<Blob>>) {}
+ pub fn PassOptionalAnyWithDefault(&self, _: *JSContext, _: JSVal) {}
+
+ pub fn PassOptionalNullableBooleanWithNonNullDefault(&self, _: Option<bool>) {}
+ pub fn PassOptionalNullableByteWithNonNullDefault(&self, _: Option<i8>) {}
+ pub fn PassOptionalNullableOctetWithNonNullDefault(&self, _: Option<u8>) {}
+ pub fn PassOptionalNullableShortWithNonNullDefault(&self, _: Option<i16>) {}
+ pub fn PassOptionalNullableUnsignedShortWithNonNullDefault(&self, _: Option<u16>) {}
+ pub fn PassOptionalNullableLongWithNonNullDefault(&self, _: Option<i32>) {}
+ pub fn PassOptionalNullableUnsignedLongWithNonNullDefault(&self, _: Option<u32>) {}
+ pub fn PassOptionalNullableLongLongWithNonNullDefault(&self, _: Option<i64>) {}
+ pub fn PassOptionalNullableUnsignedLongLongWithNonNullDefault(&self, _: Option<u64>) {}
+ // pub fn PassOptionalNullableFloatWithNonNullDefault(&self, _: Option<f32>) {}
+ // pub fn PassOptionalNullableDoubleWithNonNullDefault(&self, _: Option<f64>) {}
+ pub fn PassOptionalNullableStringWithNonNullDefault(&self, _: Option<DOMString>) {}
+}
+
+impl Reflectable for TestBinding {
+ fn reflector<'a>(&'a self) -> &'a Reflector {
+ &self.reflector
+ }
+
+ fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
+ &mut self.reflector
+ }
+}
diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs
index f5564bee284..46ca3736fc3 100644
--- a/src/components/script/dom/uievent.rs
+++ b/src/components/script/dom/uievent.rs
@@ -37,7 +37,7 @@ impl UIEvent {
pub fn new(window: &JS<Window>) -> JS<UIEvent> {
reflect_dom_object(~UIEvent::new_inherited(UIEventTypeId),
- window.get(),
+ window,
UIEventBinding::Wrap)
}
diff --git a/src/components/script/dom/validitystate.rs b/src/components/script/dom/validitystate.rs
index 1d7a690ffab..4ad6d8657e4 100644
--- a/src/components/script/dom/validitystate.rs
+++ b/src/components/script/dom/validitystate.rs
@@ -25,7 +25,7 @@ impl ValidityState {
pub fn new(window: &JS<Window>) -> JS<ValidityState> {
reflect_dom_object(~ValidityState::new_inherited(window.clone()),
- window.get(),
+ window,
ValidityStateBinding::Wrap)
}
}
diff --git a/src/components/script/dom/webidls/Document.webidl b/src/components/script/dom/webidls/Document.webidl
index daa91f540fb..98df0b2aef9 100644
--- a/src/components/script/dom/webidls/Document.webidl
+++ b/src/components/script/dom/webidls/Document.webidl
@@ -21,6 +21,8 @@ interface Document : Node {
readonly attribute DocumentType? doctype;
readonly attribute Element? documentElement;
HTMLCollection getElementsByTagName(DOMString localName);
+ HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
+ HTMLCollection getElementsByClassName(DOMString classNames);
Element? getElementById(DOMString elementId);
[Creator, Throws]
@@ -44,7 +46,7 @@ partial interface Document {
attribute DOMString title;
attribute HTMLElement? body;
readonly attribute HTMLHeadElement? head;
- /*NodeList*/ HTMLCollection getElementsByName(DOMString elementName);
+ NodeList getElementsByName(DOMString elementName);
readonly attribute HTMLCollection images;
readonly attribute HTMLCollection embeds;
diff --git a/src/components/script/dom/webidls/Element.webidl b/src/components/script/dom/webidls/Element.webidl
index 6c393f00067..e26c9415d4a 100644
--- a/src/components/script/dom/webidls/Element.webidl
+++ b/src/components/script/dom/webidls/Element.webidl
@@ -51,7 +51,6 @@ interface Element : Node {
boolean hasAttributeNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByTagName(DOMString localName);
- [Throws]
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
};
diff --git a/src/components/script/dom/webidls/HTMLCollection.webidl b/src/components/script/dom/webidls/HTMLCollection.webidl
index 2c1fc60e04a..7389e776834 100644
--- a/src/components/script/dom/webidls/HTMLCollection.webidl
+++ b/src/components/script/dom/webidls/HTMLCollection.webidl
@@ -10,6 +10,5 @@
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
- [Throws]
- getter object? namedItem(DOMString name); // only returns Element
+ getter Element? namedItem(DOMString name);
};
diff --git a/src/components/script/dom/webidls/Node.webidl b/src/components/script/dom/webidls/Node.webidl
index f21d528be26..0670e6eb3f6 100644
--- a/src/components/script/dom/webidls/Node.webidl
+++ b/src/components/script/dom/webidls/Node.webidl
@@ -50,14 +50,6 @@ interface Node : EventTarget {
attribute DOMString? nodeValue;
[SetterThrows, Pure]
attribute DOMString? textContent;
- [Throws]
- Node insertBefore(Node node, Node? child);
- [Throws]
- Node appendChild(Node node);
- [Throws]
- Node replaceChild(Node node, Node child);
- [Throws]
- Node removeChild(Node child);
void normalize();
[Throws]
@@ -69,7 +61,7 @@ interface Node : EventTarget {
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
+ const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
unsigned short compareDocumentPosition(Node other);
boolean contains(Node? other);
@@ -77,6 +69,15 @@ interface Node : EventTarget {
DOMString? lookupNamespaceURI(DOMString? prefix);
boolean isDefaultNamespace(DOMString? namespace);
+ [Throws]
+ Node insertBefore(Node node, Node? child);
+ [Throws]
+ Node appendChild(Node node);
+ [Throws]
+ Node replaceChild(Node node, Node child);
+ [Throws]
+ Node removeChild(Node child);
+
// Mozilla-specific stuff
// These have been moved to Element in the spec.
// If we move namespaceURI, prefix and localName to Element they should return
@@ -87,6 +88,4 @@ interface Node : EventTarget {
readonly attribute DOMString? prefix;
[Constant]
readonly attribute DOMString? localName;
-
- boolean hasAttributes();
};
diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl
new file mode 100644
index 00000000000..3a967f5484a
--- /dev/null
+++ b/src/components/script/dom/webidls/TestBinding.webidl
@@ -0,0 +1,101 @@
+/* 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/. */
+
+interface TestBinding {
+ attribute boolean booleanAttribute;
+ attribute byte byteAttribute;
+ attribute octet octetAttribute;
+ attribute short shortAttribute;
+ attribute unsigned short unsignedShortAttribute;
+ attribute long longAttribute;
+ attribute unsigned long unsignedLongAttribute;
+ attribute long long longLongAttribute;
+ attribute unsigned long long unsignedLongLongAttribute;
+ attribute float floatAttribute;
+ attribute double doubleAttribute;
+ attribute DOMString stringAttribute;
+ attribute Blob interfaceAttribute;
+ attribute any anyAttribute;
+
+ attribute boolean? booleanAttributeNullable;
+ attribute byte? byteAttributeNullable;
+ attribute octet? octetAttributeNullable;
+ attribute short? shortAttributeNullable;
+ attribute unsigned short? unsignedShortAttributeNullable;
+ attribute long? longAttributeNullable;
+ attribute unsigned long? unsignedLongAttributeNullable;
+ attribute long long? longLongAttributeNullable;
+ attribute unsigned long long? unsignedLongLongAttributeNullable;
+ attribute float? floatAttributeNullable;
+ attribute double? doubleAttributeNullable;
+ attribute DOMString? stringAttributeNullable;
+ attribute Blob? interfaceAttributeNullable;
+
+ // FIXME (issue #1813) Doesn't currently compile.
+ // void passOptionalBoolean(optional boolean arg);
+ // void passOptionalByte(optional byte arg);
+ // void passOptionalOctet(optional octet arg);
+ // void passOptionalShort(optional short arg);
+ // void passOptionalUnsignedShort(optional unsigned short arg);
+ // void passOptionalLong(optional long arg);
+ // void passOptionalUnsignedLong(optional unsigned long arg);
+ // void passOptionalLongLong(optional long long arg);
+ // void passOptionalUnsignedLongLong(optional unsigned long long arg);
+ // void passOptionalFloat(optional float arg);
+ // void passOptionalDouble(optional double arg);
+ void passOptionalString(optional DOMString arg);
+ void passOptionalInterface(optional Blob arg);
+ void passOptionalAny(optional any arg);
+
+ // void passOptionalNullableBoolean(optional boolean? arg);
+ // void passOptionalNullableByte(optional byte? arg);
+ // void passOptionalNullableOctet(optional octet? arg);
+ // void passOptionalNullableShort(optional short? arg);
+ // void passOptionalNullableUnsignedShort(optional unsigned short? arg);
+ // void passOptionalNullableLong(optional long? arg);
+ // void passOptionalNullableUnsignedLong(optional unsigned long? arg);
+ // void passOptionalNullableLongLong(optional long long? arg);
+ // void passOptionalNullableUnsignedLongLong(optional unsigned long long? arg);
+ // void passOptionalNullableFloat(optional float? arg);
+ // void passOptionalNullableDouble(optional double? arg);
+ void passOptionalNullableString(optional DOMString? arg);
+ // void passOptionalNullableInterface(optional Blob? arg);
+
+ void passOptionalBooleanWithDefault(optional boolean arg = false);
+ void passOptionalByteWithDefault(optional byte arg = 0);
+ void passOptionalOctetWithDefault(optional octet arg = 19);
+ void passOptionalShortWithDefault(optional short arg = 5);
+ void passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2);
+ void passOptionalLongWithDefault(optional long arg = 7);
+ void passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6);
+ void passOptionalLongLongWithDefault(optional long long arg = -12);
+ void passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
+ void passOptionalStringWithDefault(optional DOMString arg = "");
+
+ void passOptionalNullableBooleanWithDefault(optional boolean? arg = null);
+ void passOptionalNullableByteWithDefault(optional byte? arg = null);
+ void passOptionalNullableOctetWithDefault(optional octet? arg = null);
+ void passOptionalNullableShortWithDefault(optional short? arg = null);
+ void passOptionalNullableUnsignedShortWithDefault(optional unsigned short? arg = null);
+ void passOptionalNullableLongWithDefault(optional long? arg = null);
+ void passOptionalNullableUnsignedLongWithDefault(optional unsigned long? arg = null);
+ void passOptionalNullableLongLongWithDefault(optional long long? arg = null);
+ void passOptionalNullableUnsignedLongLongWithDefault(optional unsigned long long? arg = null);
+ // void passOptionalNullableStringWithDefault(optional DOMString? arg = null);
+ void passOptionalNullableInterfaceWithDefault(optional Blob? arg = null);
+ void passOptionalAnyWithDefault(optional any arg = null);
+
+ void passOptionalNullableBooleanWithNonNullDefault(optional boolean? arg = false);
+ void passOptionalNullableByteWithNonNullDefault(optional byte? arg = 7);
+ void passOptionalNullableOctetWithNonNullDefault(optional octet? arg = 7);
+ void passOptionalNullableShortWithNonNullDefault(optional short? arg = 7);
+ void passOptionalNullableUnsignedShortWithNonNullDefault(optional unsigned short? arg = 7);
+ void passOptionalNullableLongWithNonNullDefault(optional long? arg = 7);
+ void passOptionalNullableUnsignedLongWithNonNullDefault(optional unsigned long? arg = 7);
+ void passOptionalNullableLongLongWithNonNullDefault(optional long long? arg = 7);
+ void passOptionalNullableUnsignedLongLongWithNonNullDefault(optional unsigned long long? arg = 7);
+ // void passOptionalNullableFloatWithNonNullDefault(optional float? arg = 0.0);
+ // void passOptionalNullableDoubleWithNonNullDefault(optional double? arg = 0.0);
+ void passOptionalNullableStringWithNonNullDefault(optional DOMString? arg = "");
+};
diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs
index 68a9e3364b9..7c3d2e90280 100644
--- a/src/components/script/dom/window.rs
+++ b/src/components/script/dom/window.rs
@@ -20,8 +20,10 @@ use servo_util::str::DOMString;
use servo_util::task::{spawn_named};
use js::glue::*;
-use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JSVal};
-use js::{JSVAL_NULL, JSPROP_ENUMERATE};
+use js::jsapi::{JSObject, JSContext, JS_DefineProperty};
+use js::jsval::JSVal;
+use js::jsval::{NullValue, ObjectValue};
+use js::JSPROP_ENUMERATE;
use std::cast;
use std::comm::SharedChan;
@@ -29,7 +31,6 @@ use std::comm::Select;
use std::hashmap::HashSet;
use std::io::timer::Timer;
use std::num;
-use std::ptr;
use std::rc::Rc;
use std::to_bytes::Cb;
@@ -176,23 +177,23 @@ impl Window {
None
}
- pub fn Location(&mut self) -> JS<Location> {
+ pub fn Location(&mut self, abstract_self: &JS<Window>) -> JS<Location> {
if self.location.is_none() {
- self.location = Some(Location::new(self, self.extra.page.clone()));
+ self.location = Some(Location::new(abstract_self, self.extra.page.clone()));
}
self.location.get_ref().clone()
}
- pub fn Console(&mut self) -> JS<Console> {
+ pub fn Console(&mut self, abstract_self: &JS<Window>) -> JS<Console> {
if self.console.is_none() {
- self.console = Some(Console::new(self));
+ self.console = Some(Console::new(abstract_self));
}
self.console.get_ref().clone()
}
- pub fn Navigator(&mut self) -> JS<Navigator> {
+ pub fn Navigator(&mut self, abstract_self: &JS<Window>) -> JS<Navigator> {
if self.navigator.is_none() {
- self.navigator = Some(Navigator::new(self));
+ self.navigator = Some(Navigator::new(abstract_self));
}
self.navigator.get_ref().clone()
}
@@ -208,8 +209,8 @@ impl Window {
pub fn Print(&self) {
}
- pub fn ShowModalDialog(&self, _cx: *JSContext, _url: DOMString, _argument: JSVal) -> JSVal {
- JSVAL_NULL
+ pub fn ShowModalDialog(&self, _cx: *JSContext, _url: DOMString, _argument: Option<JSVal>) -> JSVal {
+ NullValue()
}
}
@@ -311,14 +312,14 @@ impl Window {
};
let raw: *mut Window = &mut *win;
- let global = WindowBinding::Wrap(cx, ptr::null(), win);
+ let global = WindowBinding::Wrap(cx, win);
assert!(global.is_not_null());
unsafe {
let fn_names = ["window","self"];
for str in fn_names.iter() {
(*str).to_c_str().with_ref(|name| {
JS_DefineProperty(cx, global, name,
- RUST_OBJECT_TO_JSVAL(global),
+ ObjectValue(&*global),
Some(cast::transmute(GetJSClassHookStubPointer(PROPERTY_STUB))),
Some(cast::transmute(GetJSClassHookStubPointer(STRICT_PROPERTY_STUB))),
JSPROP_ENUMERATE);
diff --git a/src/components/script/dom/windowproxy.rs b/src/components/script/dom/windowproxy.rs
index 35304d25d3c..dc1e0092f36 100644
--- a/src/components/script/dom/windowproxy.rs
+++ b/src/components/script/dom/windowproxy.rs
@@ -13,11 +13,11 @@ pub struct WindowProxy {
}
impl WindowProxy {
- pub fn new(owner: JS<Window>) -> JS<WindowProxy> {
+ pub fn new(owner: &JS<Window>) -> JS<WindowProxy> {
let proxy = ~WindowProxy {
reflector_: Reflector::new()
};
- reflect_dom_object(proxy, owner.get(), WindowProxyBinding::Wrap)
+ reflect_dom_object(proxy, owner, WindowProxyBinding::Wrap)
}
}