Generate DOMParser bindings.

This commit is contained in:
Josh Matthews 2013-04-01 15:14:31 -04:00
parent de7e26d173
commit 886eb35dfd
20 changed files with 417 additions and 144 deletions

@ -1 +1 @@
Subproject commit aefcf146400a42e7302243db2844f4022f938fc0 Subproject commit fe2f31f7f33150615e0cc5385cf869053e64a65a

View file

@ -3,9 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use content::content_task::task_from_context; use content::content_task::task_from_context;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, OpaqueBindingReference}; use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::bindings::codegen::ClientRectBinding; use dom::bindings::codegen::ClientRectBinding;
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext, JSVal};
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
pub trait ClientRect { pub trait ClientRect {
fn Top(&self) -> f32; fn Top(&self) -> f32;
@ -62,19 +63,35 @@ impl CacheableWrapper for ClientRectImpl {
unsafe { cast::transmute(&self.wrapper) } unsafe { cast::transmute(&self.wrapper) }
} }
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject { fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
let mut unused = false; fail!(~"nyi")
ClientRectBinding::Wrap(cx, scope, self, &mut unused)
} }
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fail!(~"nyi") let mut unused = false;
ClientRectBinding::Wrap(cx, scope, self, &mut unused)
} }
} }
impl BindingObject for ClientRectImpl { impl BindingObject for ClientRectImpl {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference { fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
let content = task_from_context(cx); let content = task_from_context(cx);
unsafe { OpaqueBindingReference(Right((*content).window.get() as @CacheableWrapper)) } unsafe { (*content).window.get() as @mut CacheableWrapper }
} }
} }
impl DerivedWrapper for ClientRectImpl {
fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
fail!(~"nyi")
}
fn wrap_shared(@mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32 {
let obj = self.wrap_object_shared(cx, scope);
if obj.is_null() {
return 0;
} else {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(obj) };
return 1;
}
}
}

View file

@ -5,13 +5,13 @@
use content::content_task::task_from_context; use content::content_task::task_from_context;
use dom::bindings::clientrect::{ClientRect, ClientRectImpl}; use dom::bindings::clientrect::{ClientRect, ClientRectImpl};
use dom::bindings::codegen::ClientRectListBinding; use dom::bindings::codegen::ClientRectListBinding;
use dom::bindings::utils::{WrapperCache, CacheableWrapper, BindingObject, OpaqueBindingReference}; use dom::bindings::utils::{WrapperCache, CacheableWrapper, BindingObject};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
pub trait ClientRectList { pub trait ClientRectList {
fn Length(&self) -> u32; fn Length(&self) -> u32;
fn Item(&self, index: u32) -> Option<~ClientRectImpl>; fn Item(&self, index: u32) -> Option<@mut ClientRectImpl>;
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<~ClientRectImpl>; fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut ClientRectImpl>;
} }
pub struct ClientRectListImpl { pub struct ClientRectListImpl {
@ -24,16 +24,16 @@ impl ClientRectList for ClientRectListImpl {
self.rects.len() as u32 self.rects.len() as u32
} }
fn Item(&self, index: u32) -> Option<~ClientRectImpl> { fn Item(&self, index: u32) -> Option<@mut ClientRectImpl> {
if index < self.rects.len() as u32 { if index < self.rects.len() as u32 {
let (top, bottom, left, right) = self.rects[index]; let (top, bottom, left, right) = self.rects[index];
Some(~ClientRect(top, bottom, left, right)) Some(@mut ClientRect(top, bottom, left, right))
} else { } else {
None None
} }
} }
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<~ClientRectImpl> { fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut ClientRectImpl> {
*found = index < self.rects.len() as u32; *found = index < self.rects.len() as u32;
self.Item(index) self.Item(index)
} }
@ -53,19 +53,19 @@ impl CacheableWrapper for ClientRectListImpl {
unsafe { cast::transmute(&self.wrapper) } unsafe { cast::transmute(&self.wrapper) }
} }
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject { fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
let mut unused = false; fail!(~"nyi")
ClientRectListBinding::Wrap(cx, scope, self, &mut unused)
} }
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fail!(~"nyi") let mut unused = false;
ClientRectListBinding::Wrap(cx, scope, self, &mut unused)
} }
} }
impl BindingObject for ClientRectListImpl { impl BindingObject for ClientRectListImpl {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference { fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
let content = task_from_context(cx); let content = task_from_context(cx);
unsafe { OpaqueBindingReference(Right((*content).window.get() as @CacheableWrapper)) } unsafe { (*content).window.get() as @mut CacheableWrapper }
} }
} }

View file

@ -116,14 +116,13 @@ DOMInterfaces = {
'ClientRect': [ 'ClientRect': [
{ {
'nativeType': 'ClientRectImpl', 'nativeType': 'ClientRectImpl',
'pointerType': '@mut '
}], }],
'ClientRectList': [ 'ClientRectList': [
{ {
'nativeType': 'ClientRectListImpl', 'nativeType': 'ClientRectListImpl',
#'headerFile': 'nsClientRect.h', 'pointerType': '@mut '
#'prefable': True,
#'resultNotAddRefed': [ 'item' ]
}], }],
'CSS2Properties': { 'CSS2Properties': {
@ -136,13 +135,10 @@ DOMInterfaces = {
'prefable': True 'prefable': True
}, },
'Document': [ 'DOMParser': {
{ 'nativeType': 'DOMParser',
'nativeType': 'nsIDocument', 'pointerType': '@mut '
}, },
{
'workers': True,
}],
'DOMSettableTokenList': [ 'DOMSettableTokenList': [
{ {
@ -213,8 +209,7 @@ DOMInterfaces = {
'HTMLCollection': [ 'HTMLCollection': [
{ {
'nativeType': 'HTMLCollection', 'nativeType': 'HTMLCollection',
#'prefable': True, 'pointerType': '@mut '
#'resultNotAddRefed': [ 'item' ]
}], }],
'HTMLOptionsCollection': [ 'HTMLOptionsCollection': [
@ -516,9 +511,9 @@ addExternalHTMLElement('HTMLOptGroupElement')
addExternalHTMLElement('HTMLVideoElement') addExternalHTMLElement('HTMLVideoElement')
addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h') addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h') addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
#addExternalIface('ClientRect')
addExternalIface('CSSRule') addExternalIface('CSSRule')
addExternalIface('CSSValue') addExternalIface('CSSValue')
addExternalIface('Document', nativeType='Document', pointerType='@mut ')
addExternalIface('DOMStringList', nativeType='nsDOMStringList', addExternalIface('DOMStringList', nativeType='nsDOMStringList',
headerFile='nsDOMLists.h') headerFile='nsDOMLists.h')
addExternalIface('Element', nativeType='AbstractNode', pointerType='') addExternalIface('Element', nativeType='AbstractNode', pointerType='')

View file

@ -1098,22 +1098,19 @@ for (uint32_t i = 0; i < length; ++i) {
"yet") "yet")
enum = type.inner.identifier.name enum = type.inner.identifier.name
if invalidEnumValueFatal: if invalidEnumValueFatal:
handleInvalidEnumValueCode = " MOZ_ASSERT(index >= 0);\n" handleInvalidEnumValueCode = " return 0;\n"
else: else:
handleInvalidEnumValueCode = ( handleInvalidEnumValueCode = " return 1;\n"
" if (index < 0) {\n"
" return true;\n"
" }\n")
template = ( template = (
"{\n" "{\n"
" bool ok;\n" #" int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n"
" int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n" " let result = FindEnumStringIndex(cx, ${val}, %(values)s);\n"
" if (!ok) {\n" " if result.is_err() {\n"
" return false;\n"
" }\n"
"%(handleInvalidEnumValueCode)s" "%(handleInvalidEnumValueCode)s"
" ${declName} = static_cast<%(enumtype)s>(index);\n" " }\n"
" let index = result.get();\n"
" ${declName} = cast::transmute(index); //XXXjdm need some range checks up in here\n"
"}" % { "enumtype" : enum, "}" % { "enumtype" : enum,
"values" : enum + "Values::strings", "values" : enum + "Values::strings",
"invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal), "invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal),
@ -1529,7 +1526,7 @@ for (uint32_t i = 0; i < length; ++i) {
if not isCreator: if not isCreator:
raise MethodNotCreatorError(descriptor.interface.identifier.name) raise MethodNotCreatorError(descriptor.interface.identifier.name)
wrapMethod = "WrapNewBindingNonWrapperCachedObject" wrapMethod = "WrapNewBindingNonWrapperCachedObject"
wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result) wrap = "%s(cx, ${obj}, %s as @mut CacheableWrapper, ${jsvalPtr})" % (wrapMethod, result)
# We don't support prefable stuff in workers. # We don't support prefable stuff in workers.
assert(not descriptor.prefable or not descriptor.workers) assert(not descriptor.prefable or not descriptor.workers)
if not descriptor.prefable: if not descriptor.prefable:
@ -1547,12 +1544,11 @@ for (uint32_t i = 0; i < length; ++i) {
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result) failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
wrappingCode += wrapAndSetPtr(wrap, failed) wrappingCode += wrapAndSetPtr(wrap, failed)
else: else:
if descriptor.notflattened:
getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
else:
getIID = ""
#wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalPtr})" % (result, getIID) #wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalPtr})" % (result, getIID)
wrap = "%s.wrap(cx, ${obj}, %s${jsvalPtr})" % (result, getIID) if descriptor.pointerType == '':
wrap = "%s.wrap(cx, ${obj}, ${jsvalPtr})" % result
else:
wrap = "if WrapNewBindingObject(cx, ${obj}, %s as @mut CacheableWrapper, ${jsvalPtr}) { 1 } else { 0 };" % result
wrappingCode += wrapAndSetPtr(wrap) wrappingCode += wrapAndSetPtr(wrap)
return (wrappingCode, False) return (wrappingCode, False)
@ -1701,10 +1697,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
descriptor = descriptorProvider.getDescriptor( descriptor = descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name) returnType.unroll().inner.identifier.name)
result = CGGeneric(descriptor.nativeType) result = CGGeneric(descriptor.nativeType)
if resultAlreadyAddRefed: if returnType.nullable():
result = CGWrapper(result, pre=("Option<" + descriptor.pointerType), post=">") result = CGWrapper(result, pre=("Option<" + descriptor.pointerType), post=">")
else: else:
result = CGWrapper(result, post="*") result = CGWrapper(result, pre=descriptor.pointerType)
return result, False return result, False
if returnType.isCallback(): if returnType.isCallback():
# XXXbz we're going to assume that callback types are always # XXXbz we're going to assume that callback types are always
@ -2154,20 +2150,23 @@ class CGIfWrapper(CGWrapper):
post="\n}") post="\n}")
class CGNamespace(CGWrapper): class CGNamespace(CGWrapper):
def __init__(self, namespace, child, declareOnly=False): def __init__(self, namespace, child, declareOnly=False, public=False):
pre = "mod %s {\n" % namespace pre = "%smod %s {\n" % ("pub " if public else "", namespace)
post = "} // mod %s\n" % namespace post = "} // mod %s\n" % namespace
CGWrapper.__init__(self, child, pre=pre, post=post, CGWrapper.__init__(self, child, pre=pre, post=post,
declareOnly=declareOnly) declareOnly=declareOnly)
@staticmethod @staticmethod
def build(namespaces, child, declareOnly=False): def build(namespaces, child, declareOnly=False, public=False):
""" """
Static helper method to build multiple wrapped namespaces. Static helper method to build multiple wrapped namespaces.
""" """
if not namespaces: if not namespaces:
return CGWrapper(child, declareOnly=declareOnly) return CGWrapper(child, declareOnly=declareOnly)
inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly) inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly, public=public)
return CGNamespace(namespaces[0], inner, declareOnly=declareOnly) return CGNamespace(namespaces[0], inner, declareOnly=declareOnly, public=public)
def declare(self):
return ""
def DOMClass(descriptor): def DOMClass(descriptor):
protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain] protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain]
@ -2474,7 +2473,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
return """ *aTriedToWrap = true; return """ *aTriedToWrap = true;
let mut parent = aObject.GetParentObject(aCx); let mut parent = aObject.GetParentObject(aCx);
let parent = WrapNativeParent(aCx, aScope, &mut parent); let parent = WrapNativeParent(aCx, aScope, parent);
if parent.is_null() { if parent.is_null() {
return ptr::null(); return ptr::null();
} }
@ -2502,11 +2501,11 @@ class CGWrapMethod(CGAbstractMethod):
# XXX can we wrap if we don't have an interface prototype object? # XXX can we wrap if we don't have an interface prototype object?
assert descriptor.interface.hasInterfacePrototypeObject() assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'), args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'),
Argument('~' + descriptor.nativeType, 'aObject'), Argument('*mut bool', 'aTriedToWrap')] Argument(descriptor.pointerType + descriptor.nativeType, 'aObject'), Argument('*mut bool', 'aTriedToWrap')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', '*JSObject', args, inline=True, pub=True) CGAbstractMethod.__init__(self, descriptor, 'Wrap', '*JSObject', args, inline=True, pub=True)
def definition_body(self): def definition_body(self):
return " let mut binding = BindingReference(Left(aObject)); \ return " let mut binding = BindingReference(Right(aObject)); \
return Wrap_(aCx, aScope, &mut binding, aTriedToWrap);" return Wrap_(aCx, aScope, &mut binding, aTriedToWrap);"
class CGWrapNonWrapperCacheMethod(CGAbstractMethod): class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
@ -3289,6 +3288,46 @@ class CGMemberJITInfo(CGThing):
return result return result
raise TypeError("Illegal member type to CGPropertyJITInfo") raise TypeError("Illegal member type to CGPropertyJITInfo")
def getEnumValueName(value):
# Some enum values can be empty strings. Others might have weird
# characters in them. Deal with the former by returning "_empty",
# deal with possible name collisions from that by throwing if the
# enum value is actually "_empty", and throw on any value
# containing non-ASCII chars for now. Replace all chars other than
# [0-9A-Za-z_] with '_'.
if re.match("[^\x20-\x7E]", value):
raise SyntaxError('Enum value "' + value + '" contains non-ASCII characters')
if re.match("^[0-9]", value):
raise SyntaxError('Enum value "' + value + '" starts with a digit')
value = re.sub(r'[^0-9A-Za-z_]', '_', value)
if re.match("^_[A-Z]|__", value):
raise SyntaxError('Enum value "' + value + '" is reserved by the C++ spec')
if value == "_empty":
raise SyntaxError('"_empty" is not an IDL enum value we support yet')
if value == "":
return "_empty"
return MakeNativeName(value)
class CGEnum(CGThing):
def __init__(self, enum):
CGThing.__init__(self)
self.enum = enum
def declare(self):
return ""
def define(self):
return """
pub enum valuelist {
%s
}
pub static strings: &'static [EnumEntry] = &[
%s,
];
""" % (",\n ".join(map(getEnumValueName, self.enum.values())),
",\n ".join(['EnumEntry {value: &"' + val + '", length: ' + str(len(val)) + '}' for val in self.enum.values()]))
class CGXrayHelper(CGAbstractExternMethod): class CGXrayHelper(CGAbstractExternMethod):
def __init__(self, descriptor, name, args, properties): def __init__(self, descriptor, name, args, properties):
CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args)
@ -3574,42 +3613,38 @@ let _: %s = cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val));
#return clearWrapper + release #return clearWrapper + release
return release return release
class CGClassConstructHook(CGAbstractStaticMethod): class CGClassConstructHook(CGAbstractExternMethod):
""" """
JS-visible constructor for our objects JS-visible constructor for our objects
""" """
def __init__(self, descriptor): def __init__(self, descriptor):
args = [Argument('*JSContext', 'cx'), Argument('unsigned', 'argc'), Argument('*jsval', 'vp')] args = [Argument('*JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')]
CGAbstractStaticMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME, CGAbstractExternMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
'JSBool', args) 'JSBool', args)
self._ctor = self.descriptor.interface.ctor() self._ctor = self.descriptor.interface.ctor()
def define(self): def define(self):
if not self._ctor: if not self._ctor:
return "" return ""
return CGAbstractStaticMethod.define(self) return CGAbstractExternMethod.define(self)
def definition_body(self): def definition_body(self):
return self.generate_code() return self.generate_code()
def generate_code(self): def generate_code(self):
preamble = """ preamble = """
JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp))); //JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
""" """
if self.descriptor.workers: if self.descriptor.workers:
preArgs = ["cx", "obj"] preArgs = ["cx", "obj"]
else: else:
preamble += """ preamble += """
nsISupports* global; //XXXjdm Gecko obtains a GlobalObject from the global (maybe from the private value,
xpc_qsSelfRef globalRef; // or through unwrapping a slot or something). We'll punt and get the Window
{ // from the context for now.
nsresult rv; let content = task_from_context(cx);
JS::Value val = OBJECT_TO_JSVAL(obj); let global = (*content).window.get();
rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val); let obj = global.get_wrappercache().get_wrapper();
if (NS_FAILED(rv)) {
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
}
}
""" """
preArgs = ["global"] preArgs = ["global"]
@ -3835,6 +3870,17 @@ class CGBindingRoot(CGThing):
cgthings = [] cgthings = []
# Do codegen for all the enums
def makeEnum(e):
return CGNamespace.build([e.identifier.name + "Values"],
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)))
cgthings = [ fun(e) for e in config.getEnums(webIDLFile)
for fun in [makeEnum, makeEnumTypedef] ]
# Do codegen for all the descriptors # Do codegen for all the descriptors
cgthings.extend([CGDescriptor(x) for x in descriptors]) cgthings.extend([CGDescriptor(x) for x in descriptors])
@ -3846,6 +3892,8 @@ class CGBindingRoot(CGThing):
# CGWrapper(curr, pre="\n")) # CGWrapper(curr, pre="\n"))
# Add imports # Add imports
#XXXjdm This should only import the namespace for the current binding,
# not every binding ever.
curr = CGImports(descriptors, curr = CGImports(descriptors,
dictionaries, dictionaries,
['js::*', ['js::*',
@ -3854,14 +3902,17 @@ class CGBindingRoot(CGThing):
'js::jsfriendapi::bindgen::*', 'js::jsfriendapi::bindgen::*',
'js::glue::bindgen::*', 'js::glue::bindgen::*',
'js::glue::*', 'js::glue::*',
'dom::node::AbstractNode', 'dom::node::AbstractNode', #XXXjdm
'dom::document::Document', #XXXjdm
'dom::bindings::utils::*', 'dom::bindings::utils::*',
'dom::bindings::conversions::*', 'dom::bindings::conversions::*',
'dom::bindings::clientrect::*', #XXXjdm 'dom::bindings::clientrect::*', #XXXjdm
'dom::bindings::clientrectlist::*', #XXXjdm 'dom::bindings::clientrectlist::*', #XXXjdm
'dom::bindings::htmlcollection::*', #XXXjdm 'dom::bindings::htmlcollection::*', #XXXjdm
'dom::bindings::proxyhandler::*', 'dom::bindings::proxyhandler::*',
'content::content_task::task_from_context' 'dom::domparser::*', #XXXjdm
'content::content_task::task_from_context',
'dom::bindings::utils::EnumEntry',
], ],
[], [],
curr) curr)

View file

@ -0,0 +1,48 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://domparsing.spec.whatwg.org/#the-domparser-interface
*/
/*interface Principal;
interface URI;
interface InputStream;*/
interface Document;
enum SupportedType {
"text/html",
"text/xml",
"application/xml",
"application/xhtml+xml",
"image/svg+xml"
};
// the latter is Mozilla-specific
/*[Constructor,
Constructor(Principal? prin, optional URI? documentURI = null,
optional URI? baseURI = null)]*/
[Constructor]
interface DOMParser {
[Creator, Throws]
Document parseFromString(DOMString str, SupportedType type);
/* // Mozilla-specific stuff
// Throws if the passed-in length is greater than the actual sequence length
[Creator, Throws, ChromeOnly]
Document parseFromBuffer(sequence<octet> buf, unsigned long bufLen,
SupportedType type);
// Throws if the passed-in length is greater than the actual typed array length
[Creator, Throws, ChromeOnly]
Document parseFromBuffer(Uint8Array buf, unsigned long bufLen,
SupportedType type);
[Creator, Throws, ChromeOnly]
Document parseFromStream(InputStream stream, DOMString? charset,
long contentLength, SupportedType type);
[Throws, ChromeOnly]
void init(optional Principal? principal = null,
optional URI? documentURI = null,
optional URI? baseURI = null);*/
};

View file

@ -1,5 +1,6 @@
#include "ClientRectBinding.h" #include "ClientRectBinding.h"
#include "ClientRectListBinding.h" #include "ClientRectListBinding.h"
#include "DOMParserBinding.h"
#include "HTMLCollectionBinding.h" #include "HTMLCollectionBinding.h"
#include "nsScriptNameSpaceManager.h" #include "nsScriptNameSpaceManager.h"
@ -14,6 +15,7 @@ Register(nsScriptNameSpaceManager* aNameSpaceManager)
REGISTER_PROTO(ClientRect, nullptr); REGISTER_PROTO(ClientRect, nullptr);
REGISTER_PROTO(ClientRectList, nullptr); REGISTER_PROTO(ClientRectList, nullptr);
REGISTER_PROTO(DOMParser, nullptr);
REGISTER_PROTO(HTMLCollection, nullptr); REGISTER_PROTO(HTMLCollection, nullptr);
#undef REGISTER_PROTO #undef REGISTER_PROTO

View file

@ -14,6 +14,7 @@ use js::glue::bindgen::*;
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB}; use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
use core::ptr::null; use core::ptr::null;
use core::libc::c_uint; use core::libc::c_uint;
use content::content_task::task_from_context;
use dom::bindings::utils::{DOMString, rust_box, squirrel_away, str}; use dom::bindings::utils::{DOMString, rust_box, squirrel_away, str};
use dom::bindings::utils::{jsval_to_str, WrapNewBindingObject, CacheableWrapper}; use dom::bindings::utils::{jsval_to_str, WrapNewBindingObject, CacheableWrapper};
use dom::bindings::utils::WrapperCache; use dom::bindings::utils::WrapperCache;
@ -50,15 +51,16 @@ extern fn getElementsByTagName(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSB
arg0 = str(strval.get()); arg0 = str(strval.get());
let doc = &mut (*unwrap(obj)).payload; let doc = &mut (*unwrap(obj)).payload;
let rval: Option<~HTMLCollection>; let rval: Option<@mut HTMLCollection>;
rval = doc.getElementsByTagName(arg0); rval = doc.getElementsByTagName(arg0);
if rval.is_none() { if rval.is_none() {
JS_SET_RVAL(cx, vp, JSVAL_NULL); JS_SET_RVAL(cx, vp, JSVAL_NULL);
} else { } else {
let cache = doc.get_wrappercache(); let cache = doc.get_wrappercache();
let rval = rval.get() as @mut CacheableWrapper;
assert!(WrapNewBindingObject(cx, cache.get_wrapper(), assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
rval.get(), rval,
cast::transmute(vp))); cast::transmute(vp)));
} }
return 1; return 1;
} }
@ -115,6 +117,15 @@ pub fn init(compartment: @mut Compartment, doc: @mut Document) {
compartment.register_class(utils::instance_jsclass(~"DocumentInstance", finalize)); compartment.register_class(utils::instance_jsclass(~"DocumentInstance", finalize));
let ptr = create(compartment, doc);
compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
}
pub fn create(compartment: @mut Compartment, doc: @mut Document) -> *JSObject {
let instance : jsobj = result::unwrap( let instance : jsobj = result::unwrap(
compartment.new_object_with_proto(~"DocumentInstance", ~"Document", compartment.new_object_with_proto(~"DocumentInstance", ~"Document",
compartment.global_obj.ptr)); compartment.global_obj.ptr));
@ -124,11 +135,7 @@ pub fn init(compartment: @mut Compartment, doc: @mut Document) {
let raw_ptr: *libc::c_void = cast::reinterpret_cast(&squirrel_away(doc)); let raw_ptr: *libc::c_void = cast::reinterpret_cast(&squirrel_away(doc));
JS_SetReservedSlot(instance.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr)); JS_SetReservedSlot(instance.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
} }
instance.ptr
compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(instance.ptr),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
} }
impl CacheableWrapper for Document { impl CacheableWrapper for Document {
@ -140,7 +147,8 @@ impl CacheableWrapper for Document {
fail!(~"need to implement wrapping"); fail!(~"need to implement wrapping");
} }
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping"); let content = task_from_context(cx);
unsafe { create((*content).compartment.get(), self) }
} }
} }

View file

@ -0,0 +1,44 @@
use dom::bindings::codegen::DOMParserBinding;
use dom::bindings::utils::{CacheableWrapper, WrapperCache};
use dom::bindings::utils::{BindingObject, DerivedWrapper};
use dom::domparser::DOMParser;
use js::jsapi::{JSContext, JSObject, JSVal};
use js::glue::bindgen::{RUST_OBJECT_TO_JSVAL};
impl CacheableWrapper for DOMParser {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
unsafe { cast::transmute(&self.wrapper) }
}
fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping");
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
DOMParserBinding::Wrap(cx, scope, self, &mut unused)
}
}
impl BindingObject for DOMParser {
fn GetParentObject(&self, _cx: *JSContext) -> @mut CacheableWrapper {
return self.owner as @mut CacheableWrapper;
}
}
impl DerivedWrapper for DOMParser {
fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
fail!(~"nyi")
}
fn wrap_shared(@mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32 {
let obj = self.wrap_object_shared(cx, scope);
if obj.is_null() {
return 0;
} else {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(obj) };
return 1;
}
}
}

View file

@ -102,9 +102,10 @@ extern fn getClientRects(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
JS_SET_RVAL(cx, vp, JSVAL_NULL); JS_SET_RVAL(cx, vp, JSVAL_NULL);
} else { } else {
let cache = node.get_wrappercache(); let cache = node.get_wrappercache();
let rval = rval.get() as @mut CacheableWrapper;
assert!(WrapNewBindingObject(cx, cache.get_wrapper(), assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
rval.get(), rval,
cast::transmute(vp))); cast::transmute(vp)));
} }
return 1; return 1;
} }

View file

@ -5,7 +5,7 @@
use content::content_task::task_from_context; use content::content_task::task_from_context;
use dom::node::AbstractNode; use dom::node::AbstractNode;
use dom::bindings::codegen::HTMLCollectionBinding; use dom::bindings::codegen::HTMLCollectionBinding;
use dom::bindings::utils::{DOMString, ErrorResult, OpaqueBindingReference}; use dom::bindings::utils::{DOMString, ErrorResult};
use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache}; use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
@ -46,9 +46,9 @@ pub impl HTMLCollection {
} }
impl BindingObject for HTMLCollection { impl BindingObject for HTMLCollection {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference { fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
let content = task_from_context(cx); let content = task_from_context(cx);
unsafe { OpaqueBindingReference(Right((*content).window.get() as @CacheableWrapper)) } unsafe { (*content).window.get() as @mut CacheableWrapper }
} }
} }
@ -57,12 +57,12 @@ impl CacheableWrapper for HTMLCollection {
unsafe { cast::transmute(&self.wrapper) } unsafe { cast::transmute(&self.wrapper) }
} }
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject { fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false; let mut unused = false;
HTMLCollectionBinding::Wrap(cx, scope, self, &mut unused) HTMLCollectionBinding::Wrap(cx, scope, self, &mut unused)
} }
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
}
} }

View file

@ -175,7 +175,7 @@ impl CacheableWrapper for AbstractNode {
fail!(~"need to implement wrapping"); fail!(~"need to implement wrapping");
} }
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping"); fail!(~"need to implement wrapping");
} }
} }

View file

@ -18,7 +18,7 @@ use js::jsapi::bindgen::{JS_ValueToString,
JS_DefineProperties, JS_DefineProperties,
JS_WrapValue, JS_ForwardGetPropertyTo, JS_WrapValue, JS_ForwardGetPropertyTo,
JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject, JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject,
JS_EncodeString, JS_free}; JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
use js::glue::bindgen::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL}; use js::glue::bindgen::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB,
@ -30,7 +30,9 @@ use content::content_task::task_from_context;
use core::hashmap::HashMap; use core::hashmap::HashMap;
use dom::bindings::document;
use dom::bindings::node; use dom::bindings::node;
use dom::document::Document;
use dom::node::AbstractNode; use dom::node::AbstractNode;
static TOSTRING_CLASS_RESERVED_SLOT: u64 = 0; static TOSTRING_CLASS_RESERVED_SLOT: u64 = 0;
@ -356,6 +358,7 @@ pub mod prototypes {
pub enum Prototype { pub enum Prototype {
ClientRect, ClientRect,
ClientRectList, ClientRectList,
DOMParser,
HTMLCollection, HTMLCollection,
_ID_Count _ID_Count
} }
@ -540,7 +543,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) ->
} }
pub fn initialize_global(global: *JSObject) { pub fn initialize_global(global: *JSObject) {
let protoArray = @mut ([0 as *JSObject, ..3]); //XXXjdm prototypes::_ID_COUNT let protoArray = @mut ([0 as *JSObject, ..4]); //XXXjdm prototypes::_ID_COUNT
unsafe { unsafe {
//XXXjdm we should be storing the box pointer instead of the inner //XXXjdm we should be storing the box pointer instead of the inner
let box = squirrel_away(protoArray); let box = squirrel_away(protoArray);
@ -554,7 +557,7 @@ pub fn initialize_global(global: *JSObject) {
pub trait CacheableWrapper { pub trait CacheableWrapper {
fn get_wrappercache(&mut self) -> &mut WrapperCache; fn get_wrappercache(&mut self) -> &mut WrapperCache;
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject; fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject;
fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject; fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject;
} }
pub struct WrapperCache { pub struct WrapperCache {
@ -577,64 +580,48 @@ pub impl WrapperCache {
} }
} }
pub fn WrapNewBindingObject<T: CacheableWrapper>(cx: *JSContext, scope: *JSObject, pub fn WrapNewBindingObject(cx: *JSContext, scope: *JSObject,
mut value: ~T, vp: *mut JSVal) -> bool { mut value: @mut CacheableWrapper,
vp: *mut JSVal) -> bool {
unsafe { unsafe {
let obj = value.get_wrappercache().get_wrapper(); let mut cache = value.get_wrappercache();
let mut obj = cache.get_wrapper();
if obj.is_not_null() /*&& js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)*/ { if obj.is_not_null() /*&& js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)*/ {
*vp = RUST_OBJECT_TO_JSVAL(obj); *vp = RUST_OBJECT_TO_JSVAL(obj);
return true; return true;
} }
let obj = if obj.is_not_null() { let obj = value.wrap_object_shared(cx, scope);
obj
} else {
value.wrap_object_unique(cx, scope)
};
if obj.is_null() { if obj.is_null() {
return false; return false;
} }
// MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx)); // MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
cache.set_wrapper(obj);
*vp = RUST_OBJECT_TO_JSVAL(obj); *vp = RUST_OBJECT_TO_JSVAL(obj);
return JS_WrapValue(cx, cast::transmute(vp)) != 0; return JS_WrapValue(cx, cast::transmute(vp)) != 0;
} }
} }
pub struct OpaqueBindingReference(Either<~CacheableWrapper, @CacheableWrapper>); pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableWrapper) -> *JSObject {
let cache = p.get_wrappercache();
pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, p: &mut OpaqueBindingReference) -> *JSObject { let wrapper = cache.get_wrapper();
match p { if wrapper.is_not_null() {
&OpaqueBindingReference(Left(ref mut p)) => { return wrapper;
let cache = p.get_wrappercache();
let obj = cache.get_wrapper();
if obj.is_not_null() {
return obj;
}
let mut tmp: ~CacheableWrapper = unstable::intrinsics::init();
tmp <-> *p;
tmp.wrap_object_unique(cx, scope)
}
&OpaqueBindingReference(Right(ref mut p)) => {
let cache = p.get_wrappercache();
let obj = cache.get_wrapper();
if obj.is_not_null() {
return obj;
}
p.wrap_object_shared(cx, scope)
}
} }
let wrapper = p.wrap_object_shared(cx, scope);
cache.set_wrapper(wrapper);
wrapper
} }
pub struct BindingReference<T>(Either<~T, @mut T>); pub struct BindingReference<T>(Either<~T, @mut T>);
pub trait BindingObject { pub trait BindingObject {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference; fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper;
} }
pub impl<T: BindingObject + CacheableWrapper> BindingReference<T> { pub impl<T: BindingObject + CacheableWrapper> BindingReference<T> {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference { fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
match **self { match **self {
Left(ref obj) => obj.GetParentObject(cx), Left(ref obj) => obj.GetParentObject(cx),
Right(ref obj) => obj.GetParentObject(cx) Right(ref obj) => obj.GetParentObject(cx)
@ -781,6 +768,7 @@ pub fn InitIds(cx: *JSContext, specs: &[JSPropertySpec], ids: &mut [jsid]) -> bo
pub trait DerivedWrapper { pub trait DerivedWrapper {
fn wrap(&mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32; fn wrap(&mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32;
fn wrap_shared(@mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32;
} }
impl DerivedWrapper for AbstractNode { impl DerivedWrapper for AbstractNode {
@ -794,10 +782,87 @@ impl DerivedWrapper for AbstractNode {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(node::create(cx, self).ptr) }; unsafe { *vp = RUST_OBJECT_TO_JSVAL(node::create(cx, self).ptr) };
return 1; return 1;
} }
fn wrap_shared(@mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
fail!(~"nyi")
}
}
/*impl DerivedWrapper for Document {
fn wrap(&mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32 {
let cache = self.get_wrappercache();
let wrapper = cache.get_wrapper();
if wrapper.is_not_null() {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
return 1;
}
let content = task_from_context(cx);
unsafe {
let compartment = (*content).compartment.get();
*vp = RUST_OBJECT_TO_JSVAL(document::create(compartment, self));
}
return 1;
}
}*/
pub impl Document {
fn wrap(@mut self, cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 {
let cache = self.get_wrappercache();
let wrapper = cache.get_wrapper();
if wrapper.is_not_null() {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
return 1;
}
let content = task_from_context(cx);
unsafe {
let compartment = (*content).compartment.get();
*vp = RUST_OBJECT_TO_JSVAL(document::create(compartment, self));
}
return 1;
}
} }
pub enum Error { pub enum Error {
FailureUnknown FailureUnknown
} }
pub type ErrorResult = Result<(), Error>; pub type ErrorResult = Result<(), Error>;
pub struct EnumEntry {
value: &'static str,
length: uint
}
pub fn FindEnumStringIndex(cx: *JSContext,
v: JSVal,
values: &[EnumEntry]) -> Result<uint, ()> {
unsafe {
let jsstr = JS_ValueToString(cx, v);
if jsstr.is_null() {
return Err(());
}
let length = 0;
let chars = JS_GetStringCharsAndLength(cx, jsstr, ptr::to_unsafe_ptr(&length));
if chars.is_null() {
return Err(());
}
for values.eachi |i, value| {
if value.length != length as uint {
loop;
}
let mut equal = true;
for uint::iterate(0, length as uint) |j| {
if value.value[j] as u16 != *chars.offset(j) {
equal = false;
break;
}
};
if equal {
return Ok(i);
}
}
return Err(()); //XXX pass in behaviour for value not found
}
}

View file

@ -141,7 +141,7 @@ impl CacheableWrapper for Window {
fail!(~"should this be called?"); fail!(~"should this be called?");
} }
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"should this be called?"); fail!(~"should this be called?");
} }
} }

View file

@ -20,7 +20,7 @@ pub fn Document(root: AbstractNode) -> Document {
} }
pub impl Document { pub impl Document {
fn getElementsByTagName(&self, tag: DOMString) -> Option<~HTMLCollection> { fn getElementsByTagName(&self, tag: DOMString) -> Option<@mut HTMLCollection> {
let mut elements = ~[]; let mut elements = ~[];
let tag = match tag { let tag = match tag {
str(s) => s, str(s) => s,
@ -35,6 +35,6 @@ pub impl Document {
} }
} }
}; };
Some(~HTMLCollection::new(elements)) Some(@mut HTMLCollection::new(elements))
} }
} }

View file

@ -0,0 +1,30 @@
use dom::bindings::utils::{DOMString, ErrorResult, WrapperCache};
use dom::bindings::codegen::DOMParserBinding;
use dom::document::Document;
use dom::element::{Element, HTMLHtmlElement, HTMLHtmlElementTypeId};
use dom::node::Node;
use dom::window::Window;
pub struct DOMParser {
owner: @mut Window, //XXXjdm Document instead?
wrapper: WrapperCache
}
pub impl DOMParser {
fn new(owner: @mut Window) -> DOMParser {
DOMParser {
owner: owner,
wrapper: WrapperCache::new()
}
}
fn Constructor(owner: @mut Window, _rv: &mut ErrorResult) -> @mut DOMParser {
@mut DOMParser::new(owner)
}
fn ParseFromString(&self, _s: DOMString, _type_: DOMParserBinding::SupportedType, _rv: &mut ErrorResult) -> @mut Document {
let root = ~HTMLHtmlElement { parent: Element::new(HTMLHtmlElementTypeId, ~"html") };
let root = unsafe { Node::as_abstract_node(root) };
@mut Document(root)
}
}

View file

@ -144,8 +144,8 @@ pub impl<'self> Element {
self.attrs.push(Attr::new(name.to_str(), value_cell.take())); self.attrs.push(Attr::new(name.to_str(), value_cell.take()));
} }
fn getClientRects(&self) -> Option<~ClientRectListImpl> { fn getClientRects(&self) -> Option<@mut ClientRectListImpl> {
Some(~ClientRectListImpl::new()) Some(@mut ClientRectListImpl::new())
} }
} }

View file

@ -385,4 +385,7 @@ pub fn define_bindings(compartment: @mut Compartment, doc: @mut Document, win: @
assert!(codegen::HTMLCollectionBinding::DefineDOMInterface(compartment.cx.ptr, assert!(codegen::HTMLCollectionBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr, compartment.global_obj.ptr,
&mut unused)); &mut unused));
assert!(codegen::DOMParserBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused));
} }

View file

@ -68,14 +68,17 @@ pub mod dom {
pub mod proxyhandler; pub mod proxyhandler;
pub mod clientrect; pub mod clientrect;
pub mod clientrectlist; pub mod clientrectlist;
pub mod domparser;
pub mod htmlcollection; pub mod htmlcollection;
pub mod codegen { pub mod codegen {
pub mod ClientRectBinding; pub mod ClientRectBinding;
pub mod ClientRectListBinding; pub mod ClientRectListBinding;
pub mod DOMParserBinding;
pub mod HTMLCollectionBinding; pub mod HTMLCollectionBinding;
} }
} }
pub mod document; pub mod document;
pub mod domparser;
pub mod element; pub mod element;
pub mod event; pub mod event;
pub mod node; pub mod node;

View file

@ -32,3 +32,9 @@ window.alert(tags[0]);
window.alert(tags[1]); window.alert(tags[1]);
window.alert(tags[2]); window.alert(tags[2]);
window.alert(tags[3]); window.alert(tags[3]);
window.alert("DOMParser:");
window.alert(DOMParser);
let parser = new DOMParser();
window.alert(parser);
window.alert(parser.parseFromString("<html></html>", "text/html"));