mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Generate DOMParser bindings.
This commit is contained in:
parent
de7e26d173
commit
886eb35dfd
20 changed files with 417 additions and 144 deletions
|
@ -1 +1 @@
|
|||
Subproject commit aefcf146400a42e7302243db2844f4022f938fc0
|
||||
Subproject commit fe2f31f7f33150615e0cc5385cf869053e64a65a
|
|
@ -3,9 +3,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
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 js::jsapi::{JSObject, JSContext};
|
||||
use js::jsapi::{JSObject, JSContext, JSVal};
|
||||
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
|
||||
|
||||
pub trait ClientRect {
|
||||
fn Top(&self) -> f32;
|
||||
|
@ -62,19 +63,35 @@ impl CacheableWrapper for ClientRectImpl {
|
|||
unsafe { cast::transmute(&self.wrapper) }
|
||||
}
|
||||
|
||||
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
||||
let mut unused = false;
|
||||
ClientRectBinding::Wrap(cx, scope, self, &mut unused)
|
||||
fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
fail!(~"nyi")
|
||||
}
|
||||
|
||||
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
fail!(~"nyi")
|
||||
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
||||
let mut unused = false;
|
||||
ClientRectBinding::Wrap(cx, scope, self, &mut unused)
|
||||
}
|
||||
}
|
||||
|
||||
impl BindingObject for ClientRectImpl {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
use content::content_task::task_from_context;
|
||||
use dom::bindings::clientrect::{ClientRect, ClientRectImpl};
|
||||
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};
|
||||
|
||||
pub trait ClientRectList {
|
||||
fn Length(&self) -> u32;
|
||||
fn Item(&self, index: u32) -> Option<~ClientRectImpl>;
|
||||
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<~ClientRectImpl>;
|
||||
fn Item(&self, index: u32) -> Option<@mut ClientRectImpl>;
|
||||
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<@mut ClientRectImpl>;
|
||||
}
|
||||
|
||||
pub struct ClientRectListImpl {
|
||||
|
@ -24,16 +24,16 @@ impl ClientRectList for ClientRectListImpl {
|
|||
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 {
|
||||
let (top, bottom, left, right) = self.rects[index];
|
||||
Some(~ClientRect(top, bottom, left, right))
|
||||
Some(@mut ClientRect(top, bottom, left, right))
|
||||
} else {
|
||||
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;
|
||||
self.Item(index)
|
||||
}
|
||||
|
@ -53,19 +53,19 @@ impl CacheableWrapper for ClientRectListImpl {
|
|||
unsafe { cast::transmute(&self.wrapper) }
|
||||
}
|
||||
|
||||
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
||||
let mut unused = false;
|
||||
ClientRectListBinding::Wrap(cx, scope, self, &mut unused)
|
||||
fn wrap_object_unique(~self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
fail!(~"nyi")
|
||||
}
|
||||
|
||||
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
fail!(~"nyi")
|
||||
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
||||
let mut unused = false;
|
||||
ClientRectListBinding::Wrap(cx, scope, self, &mut unused)
|
||||
}
|
||||
}
|
||||
|
||||
impl BindingObject for ClientRectListImpl {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
||||
let content = task_from_context(cx);
|
||||
unsafe { OpaqueBindingReference(Right((*content).window.get() as @CacheableWrapper)) }
|
||||
unsafe { (*content).window.get() as @mut CacheableWrapper }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,14 +116,13 @@ DOMInterfaces = {
|
|||
'ClientRect': [
|
||||
{
|
||||
'nativeType': 'ClientRectImpl',
|
||||
'pointerType': '@mut '
|
||||
}],
|
||||
|
||||
'ClientRectList': [
|
||||
{
|
||||
'nativeType': 'ClientRectListImpl',
|
||||
#'headerFile': 'nsClientRect.h',
|
||||
#'prefable': True,
|
||||
#'resultNotAddRefed': [ 'item' ]
|
||||
'pointerType': '@mut '
|
||||
}],
|
||||
|
||||
'CSS2Properties': {
|
||||
|
@ -136,13 +135,10 @@ DOMInterfaces = {
|
|||
'prefable': True
|
||||
},
|
||||
|
||||
'Document': [
|
||||
{
|
||||
'nativeType': 'nsIDocument',
|
||||
'DOMParser': {
|
||||
'nativeType': 'DOMParser',
|
||||
'pointerType': '@mut '
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
}],
|
||||
|
||||
'DOMSettableTokenList': [
|
||||
{
|
||||
|
@ -213,8 +209,7 @@ DOMInterfaces = {
|
|||
'HTMLCollection': [
|
||||
{
|
||||
'nativeType': 'HTMLCollection',
|
||||
#'prefable': True,
|
||||
#'resultNotAddRefed': [ 'item' ]
|
||||
'pointerType': '@mut '
|
||||
}],
|
||||
|
||||
'HTMLOptionsCollection': [
|
||||
|
@ -516,9 +511,9 @@ addExternalHTMLElement('HTMLOptGroupElement')
|
|||
addExternalHTMLElement('HTMLVideoElement')
|
||||
addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
|
||||
addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
|
||||
#addExternalIface('ClientRect')
|
||||
addExternalIface('CSSRule')
|
||||
addExternalIface('CSSValue')
|
||||
addExternalIface('Document', nativeType='Document', pointerType='@mut ')
|
||||
addExternalIface('DOMStringList', nativeType='nsDOMStringList',
|
||||
headerFile='nsDOMLists.h')
|
||||
addExternalIface('Element', nativeType='AbstractNode', pointerType='')
|
||||
|
|
|
@ -1098,22 +1098,19 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
"yet")
|
||||
enum = type.inner.identifier.name
|
||||
if invalidEnumValueFatal:
|
||||
handleInvalidEnumValueCode = " MOZ_ASSERT(index >= 0);\n"
|
||||
handleInvalidEnumValueCode = " return 0;\n"
|
||||
else:
|
||||
handleInvalidEnumValueCode = (
|
||||
" if (index < 0) {\n"
|
||||
" return true;\n"
|
||||
" }\n")
|
||||
handleInvalidEnumValueCode = " return 1;\n"
|
||||
|
||||
template = (
|
||||
"{\n"
|
||||
" bool ok;\n"
|
||||
" int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n"
|
||||
" if (!ok) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
#" int index = FindEnumStringIndex<%(invalidEnumValueFatal)s>(cx, ${val}, %(values)s, \"%(enumtype)s\", &ok);\n"
|
||||
" let result = FindEnumStringIndex(cx, ${val}, %(values)s);\n"
|
||||
" if result.is_err() {\n"
|
||||
"%(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,
|
||||
"values" : enum + "Values::strings",
|
||||
"invalidEnumValueFatal" : toStringBool(invalidEnumValueFatal),
|
||||
|
@ -1529,7 +1526,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
if not isCreator:
|
||||
raise MethodNotCreatorError(descriptor.interface.identifier.name)
|
||||
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.
|
||||
assert(not descriptor.prefable or not descriptor.workers)
|
||||
if not descriptor.prefable:
|
||||
|
@ -1547,12 +1544,11 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
|
||||
wrappingCode += wrapAndSetPtr(wrap, failed)
|
||||
else:
|
||||
if descriptor.notflattened:
|
||||
getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
|
||||
else:
|
||||
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)
|
||||
return (wrappingCode, False)
|
||||
|
||||
|
@ -1701,10 +1697,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
|
|||
descriptor = descriptorProvider.getDescriptor(
|
||||
returnType.unroll().inner.identifier.name)
|
||||
result = CGGeneric(descriptor.nativeType)
|
||||
if resultAlreadyAddRefed:
|
||||
if returnType.nullable():
|
||||
result = CGWrapper(result, pre=("Option<" + descriptor.pointerType), post=">")
|
||||
else:
|
||||
result = CGWrapper(result, post="*")
|
||||
result = CGWrapper(result, pre=descriptor.pointerType)
|
||||
return result, False
|
||||
if returnType.isCallback():
|
||||
# XXXbz we're going to assume that callback types are always
|
||||
|
@ -2154,20 +2150,23 @@ class CGIfWrapper(CGWrapper):
|
|||
post="\n}")
|
||||
|
||||
class CGNamespace(CGWrapper):
|
||||
def __init__(self, namespace, child, declareOnly=False):
|
||||
pre = "mod %s {\n" % namespace
|
||||
def __init__(self, namespace, child, declareOnly=False, 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)
|
||||
@staticmethod
|
||||
def build(namespaces, child, declareOnly=False):
|
||||
def build(namespaces, child, declareOnly=False, 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)
|
||||
return CGNamespace(namespaces[0], inner, 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 ""
|
||||
|
||||
def DOMClass(descriptor):
|
||||
protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain]
|
||||
|
@ -2474,7 +2473,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
|
|||
|
||||
return """ *aTriedToWrap = true;
|
||||
let mut parent = aObject.GetParentObject(aCx);
|
||||
let parent = WrapNativeParent(aCx, aScope, &mut parent);
|
||||
let parent = WrapNativeParent(aCx, aScope, parent);
|
||||
if parent.is_null() {
|
||||
return ptr::null();
|
||||
}
|
||||
|
@ -2502,11 +2501,11 @@ class CGWrapMethod(CGAbstractMethod):
|
|||
# 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('~' + 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)
|
||||
|
||||
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);"
|
||||
|
||||
class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
|
@ -3289,6 +3288,46 @@ class CGMemberJITInfo(CGThing):
|
|||
return result
|
||||
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):
|
||||
def __init__(self, descriptor, name, args, properties):
|
||||
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 release
|
||||
|
||||
class CGClassConstructHook(CGAbstractStaticMethod):
|
||||
class CGClassConstructHook(CGAbstractExternMethod):
|
||||
"""
|
||||
JS-visible constructor for our objects
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('*JSContext', 'cx'), Argument('unsigned', 'argc'), Argument('*jsval', 'vp')]
|
||||
CGAbstractStaticMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
|
||||
args = [Argument('*JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')]
|
||||
CGAbstractExternMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
|
||||
'JSBool', args)
|
||||
self._ctor = self.descriptor.interface.ctor()
|
||||
|
||||
def define(self):
|
||||
if not self._ctor:
|
||||
return ""
|
||||
return CGAbstractStaticMethod.define(self)
|
||||
return CGAbstractExternMethod.define(self)
|
||||
|
||||
def definition_body(self):
|
||||
return self.generate_code()
|
||||
|
||||
def generate_code(self):
|
||||
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:
|
||||
preArgs = ["cx", "obj"]
|
||||
else:
|
||||
preamble += """
|
||||
nsISupports* global;
|
||||
xpc_qsSelfRef globalRef;
|
||||
{
|
||||
nsresult rv;
|
||||
JS::Value val = OBJECT_TO_JSVAL(obj);
|
||||
rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val);
|
||||
if (NS_FAILED(rv)) {
|
||||
return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
}
|
||||
}
|
||||
//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 content = task_from_context(cx);
|
||||
let global = (*content).window.get();
|
||||
let obj = global.get_wrappercache().get_wrapper();
|
||||
"""
|
||||
preArgs = ["global"]
|
||||
|
||||
|
@ -3835,6 +3870,17 @@ class CGBindingRoot(CGThing):
|
|||
|
||||
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
|
||||
cgthings.extend([CGDescriptor(x) for x in descriptors])
|
||||
|
||||
|
@ -3846,6 +3892,8 @@ class CGBindingRoot(CGThing):
|
|||
# CGWrapper(curr, pre="\n"))
|
||||
|
||||
# Add imports
|
||||
#XXXjdm This should only import the namespace for the current binding,
|
||||
# not every binding ever.
|
||||
curr = CGImports(descriptors,
|
||||
dictionaries,
|
||||
['js::*',
|
||||
|
@ -3854,14 +3902,17 @@ class CGBindingRoot(CGThing):
|
|||
'js::jsfriendapi::bindgen::*',
|
||||
'js::glue::bindgen::*',
|
||||
'js::glue::*',
|
||||
'dom::node::AbstractNode',
|
||||
'dom::node::AbstractNode', #XXXjdm
|
||||
'dom::document::Document', #XXXjdm
|
||||
'dom::bindings::utils::*',
|
||||
'dom::bindings::conversions::*',
|
||||
'dom::bindings::clientrect::*', #XXXjdm
|
||||
'dom::bindings::clientrectlist::*', #XXXjdm
|
||||
'dom::bindings::htmlcollection::*', #XXXjdm
|
||||
'dom::bindings::proxyhandler::*',
|
||||
'content::content_task::task_from_context'
|
||||
'dom::domparser::*', #XXXjdm
|
||||
'content::content_task::task_from_context',
|
||||
'dom::bindings::utils::EnumEntry',
|
||||
],
|
||||
[],
|
||||
curr)
|
||||
|
|
48
src/servo/dom/bindings/codegen/DOMParser.webidl
Normal file
48
src/servo/dom/bindings/codegen/DOMParser.webidl
Normal 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);*/
|
||||
};
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "ClientRectBinding.h"
|
||||
#include "ClientRectListBinding.h"
|
||||
#include "DOMParserBinding.h"
|
||||
#include "HTMLCollectionBinding.h"
|
||||
#include "nsScriptNameSpaceManager.h"
|
||||
|
||||
|
@ -14,6 +15,7 @@ Register(nsScriptNameSpaceManager* aNameSpaceManager)
|
|||
|
||||
REGISTER_PROTO(ClientRect, nullptr);
|
||||
REGISTER_PROTO(ClientRectList, nullptr);
|
||||
REGISTER_PROTO(DOMParser, nullptr);
|
||||
REGISTER_PROTO(HTMLCollection, nullptr);
|
||||
|
||||
#undef REGISTER_PROTO
|
||||
|
|
|
@ -14,6 +14,7 @@ use js::glue::bindgen::*;
|
|||
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB};
|
||||
use core::ptr::null;
|
||||
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::{jsval_to_str, WrapNewBindingObject, CacheableWrapper};
|
||||
use dom::bindings::utils::WrapperCache;
|
||||
|
@ -50,15 +51,16 @@ extern fn getElementsByTagName(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSB
|
|||
arg0 = str(strval.get());
|
||||
|
||||
let doc = &mut (*unwrap(obj)).payload;
|
||||
let rval: Option<~HTMLCollection>;
|
||||
let rval: Option<@mut HTMLCollection>;
|
||||
rval = doc.getElementsByTagName(arg0);
|
||||
if rval.is_none() {
|
||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||
} else {
|
||||
let cache = doc.get_wrappercache();
|
||||
let rval = rval.get() as @mut CacheableWrapper;
|
||||
assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
|
||||
rval.get(),
|
||||
cast::transmute(vp)));
|
||||
rval,
|
||||
cast::transmute(vp)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -115,6 +117,15 @@ pub fn init(compartment: @mut Compartment, doc: @mut Document) {
|
|||
|
||||
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(
|
||||
compartment.new_object_with_proto(~"DocumentInstance", ~"Document",
|
||||
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));
|
||||
JS_SetReservedSlot(instance.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
|
||||
}
|
||||
|
||||
compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(instance.ptr),
|
||||
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
||||
JSPROP_ENUMERATE);
|
||||
instance.ptr
|
||||
}
|
||||
|
||||
impl CacheableWrapper for Document {
|
||||
|
@ -140,7 +147,8 @@ impl CacheableWrapper for Document {
|
|||
fail!(~"need to implement wrapping");
|
||||
}
|
||||
|
||||
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
fail!(~"need to implement wrapping");
|
||||
fn wrap_object_shared(@mut self, cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
let content = task_from_context(cx);
|
||||
unsafe { create((*content).compartment.get(), self) }
|
||||
}
|
||||
}
|
||||
|
|
44
src/servo/dom/bindings/domparser.rs
Normal file
44
src/servo/dom/bindings/domparser.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,9 +102,10 @@ extern fn getClientRects(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
|
|||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||
} else {
|
||||
let cache = node.get_wrappercache();
|
||||
let rval = rval.get() as @mut CacheableWrapper;
|
||||
assert!(WrapNewBindingObject(cx, cache.get_wrapper(),
|
||||
rval.get(),
|
||||
cast::transmute(vp)));
|
||||
rval,
|
||||
cast::transmute(vp)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use content::content_task::task_from_context;
|
||||
use dom::node::AbstractNode;
|
||||
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 js::jsapi::{JSObject, JSContext};
|
||||
|
||||
|
@ -46,9 +46,9 @@ pub impl HTMLCollection {
|
|||
}
|
||||
|
||||
impl BindingObject for HTMLCollection {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
||||
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) }
|
||||
}
|
||||
|
||||
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;
|
||||
HTMLCollectionBinding::Wrap(cx, scope, self, &mut unused)
|
||||
}
|
||||
|
||||
fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
||||
fail!(~"nyi")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ impl CacheableWrapper for AbstractNode {
|
|||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use js::jsapi::bindgen::{JS_ValueToString,
|
|||
JS_DefineProperties,
|
||||
JS_WrapValue, JS_ForwardGetPropertyTo,
|
||||
JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject,
|
||||
JS_EncodeString, JS_free};
|
||||
JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
|
||||
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
|
||||
use js::glue::bindgen::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
|
||||
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 dom::bindings::document;
|
||||
use dom::bindings::node;
|
||||
use dom::document::Document;
|
||||
use dom::node::AbstractNode;
|
||||
|
||||
static TOSTRING_CLASS_RESERVED_SLOT: u64 = 0;
|
||||
|
@ -356,6 +358,7 @@ pub mod prototypes {
|
|||
pub enum Prototype {
|
||||
ClientRect,
|
||||
ClientRectList,
|
||||
DOMParser,
|
||||
HTMLCollection,
|
||||
_ID_Count
|
||||
}
|
||||
|
@ -540,7 +543,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) ->
|
|||
}
|
||||
|
||||
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 {
|
||||
//XXXjdm we should be storing the box pointer instead of the inner
|
||||
let box = squirrel_away(protoArray);
|
||||
|
@ -554,7 +557,7 @@ pub fn initialize_global(global: *JSObject) {
|
|||
pub trait CacheableWrapper {
|
||||
fn get_wrappercache(&mut self) -> &mut WrapperCache;
|
||||
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 {
|
||||
|
@ -577,64 +580,48 @@ pub impl WrapperCache {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn WrapNewBindingObject<T: CacheableWrapper>(cx: *JSContext, scope: *JSObject,
|
||||
mut value: ~T, vp: *mut JSVal) -> bool {
|
||||
pub fn WrapNewBindingObject(cx: *JSContext, scope: *JSObject,
|
||||
mut value: @mut CacheableWrapper,
|
||||
vp: *mut JSVal) -> bool {
|
||||
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)*/ {
|
||||
*vp = RUST_OBJECT_TO_JSVAL(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
let obj = if obj.is_not_null() {
|
||||
obj
|
||||
} else {
|
||||
value.wrap_object_unique(cx, scope)
|
||||
};
|
||||
|
||||
let obj = value.wrap_object_shared(cx, scope);
|
||||
if obj.is_null() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
|
||||
cache.set_wrapper(obj);
|
||||
*vp = RUST_OBJECT_TO_JSVAL(obj);
|
||||
return JS_WrapValue(cx, cast::transmute(vp)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpaqueBindingReference(Either<~CacheableWrapper, @CacheableWrapper>);
|
||||
|
||||
pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, p: &mut OpaqueBindingReference) -> *JSObject {
|
||||
match p {
|
||||
&OpaqueBindingReference(Left(ref mut p)) => {
|
||||
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)
|
||||
}
|
||||
pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableWrapper) -> *JSObject {
|
||||
let cache = p.get_wrappercache();
|
||||
let wrapper = cache.get_wrapper();
|
||||
if wrapper.is_not_null() {
|
||||
return wrapper;
|
||||
}
|
||||
let wrapper = p.wrap_object_shared(cx, scope);
|
||||
cache.set_wrapper(wrapper);
|
||||
wrapper
|
||||
}
|
||||
|
||||
pub struct BindingReference<T>(Either<~T, @mut T>);
|
||||
|
||||
pub trait BindingObject {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference;
|
||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper;
|
||||
}
|
||||
|
||||
pub impl<T: BindingObject + CacheableWrapper> BindingReference<T> {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
|
||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
||||
match **self {
|
||||
Left(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 {
|
||||
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 {
|
||||
|
@ -794,10 +782,87 @@ impl DerivedWrapper for AbstractNode {
|
|||
unsafe { *vp = RUST_OBJECT_TO_JSVAL(node::create(cx, self).ptr) };
|
||||
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 {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ impl CacheableWrapper for Window {
|
|||
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?");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ pub fn Document(root: AbstractNode) -> Document {
|
|||
}
|
||||
|
||||
pub impl Document {
|
||||
fn getElementsByTagName(&self, tag: DOMString) -> Option<~HTMLCollection> {
|
||||
fn getElementsByTagName(&self, tag: DOMString) -> Option<@mut HTMLCollection> {
|
||||
let mut elements = ~[];
|
||||
let tag = match tag {
|
||||
str(s) => s,
|
||||
|
@ -35,6 +35,6 @@ pub impl Document {
|
|||
}
|
||||
}
|
||||
};
|
||||
Some(~HTMLCollection::new(elements))
|
||||
Some(@mut HTMLCollection::new(elements))
|
||||
}
|
||||
}
|
30
src/servo/dom/domparser.rs
Normal file
30
src/servo/dom/domparser.rs
Normal 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)
|
||||
}
|
||||
}
|
|
@ -144,8 +144,8 @@ pub impl<'self> Element {
|
|||
self.attrs.push(Attr::new(name.to_str(), value_cell.take()));
|
||||
}
|
||||
|
||||
fn getClientRects(&self) -> Option<~ClientRectListImpl> {
|
||||
Some(~ClientRectListImpl::new())
|
||||
fn getClientRects(&self) -> Option<@mut ClientRectListImpl> {
|
||||
Some(@mut ClientRectListImpl::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -385,4 +385,7 @@ pub fn define_bindings(compartment: @mut Compartment, doc: @mut Document, win: @
|
|||
assert!(codegen::HTMLCollectionBinding::DefineDOMInterface(compartment.cx.ptr,
|
||||
compartment.global_obj.ptr,
|
||||
&mut unused));
|
||||
assert!(codegen::DOMParserBinding::DefineDOMInterface(compartment.cx.ptr,
|
||||
compartment.global_obj.ptr,
|
||||
&mut unused));
|
||||
}
|
||||
|
|
|
@ -68,14 +68,17 @@ pub mod dom {
|
|||
pub mod proxyhandler;
|
||||
pub mod clientrect;
|
||||
pub mod clientrectlist;
|
||||
pub mod domparser;
|
||||
pub mod htmlcollection;
|
||||
pub mod codegen {
|
||||
pub mod ClientRectBinding;
|
||||
pub mod ClientRectListBinding;
|
||||
pub mod DOMParserBinding;
|
||||
pub mod HTMLCollectionBinding;
|
||||
}
|
||||
}
|
||||
pub mod document;
|
||||
pub mod domparser;
|
||||
pub mod element;
|
||||
pub mod event;
|
||||
pub mod node;
|
||||
|
|
|
@ -32,3 +32,9 @@ window.alert(tags[0]);
|
|||
window.alert(tags[1]);
|
||||
window.alert(tags[2]);
|
||||
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"));
|
Loading…
Add table
Add a link
Reference in a new issue