mirror of
https://github.com/servo/servo.git
synced 2025-08-08 06:55:31 +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/. */
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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='')
|
||||||
|
|
|
@ -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)
|
||||||
|
|
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 "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
|
||||||
|
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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);
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
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()));
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"));
|
Loading…
Add table
Add a link
Reference in a new issue