aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py40
-rw-r--r--components/script/dom/bindings/utils.rs89
-rw-r--r--components/script/dom/htmlimageelement.rs17
-rw-r--r--components/script/dom/webidls/HTMLImageElement.webidl2
-rw-r--r--tests/wpt/metadata/MANIFEST.json6
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini51
-rw-r--r--tests/wpt/mozilla/tests/mozilla/interfaces.html1
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/Image-constructor.html29
8 files changed, 157 insertions, 78 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 832dd564736..2847401e65c 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -2286,11 +2286,25 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
call = """\
do_create_interface_objects(cx, receiver, parent_proto.handle(),
%s, %s,
+ &named_constructors,
%s,
&sNativeProperties, rval);""" % (protoClass, constructor, domClass)
+ createArray = """\
+let named_constructors: [(NonNullJSNative, &'static str, u32); %d] = [
+""" % len(self.descriptor.interface.namedConstructors)
+ for ctor in self.descriptor.interface.namedConstructors:
+ constructHook = CONSTRUCT_HOOK_NAME + "_" + ctor.identifier.name;
+ constructArgs = methodLength(ctor)
+ constructor = '(%s as NonNullJSNative, "%s", %d)' % (
+ constructHook, ctor.identifier.name, constructArgs)
+ createArray += constructor
+ createArray += ","
+ createArray += "];"
+
return CGList([
CGGeneric(getParentProto),
+ CGGeneric(createArray),
CGGeneric(call % self.properties.variableNames())
], "\n")
@@ -4422,6 +4436,30 @@ let args = CallArgs::from_vp(vp, argc);
self.descriptor, self._ctor)
return CGList([preamble, callGenerator])
+class CGClassNameConstructHook(CGAbstractExternMethod):
+ """
+ JS-visible named constructor for our objects
+ """
+ def __init__(self, descriptor, ctor):
+ args = [Argument('*mut JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')]
+ self._ctor = ctor
+ CGAbstractExternMethod.__init__(self, descriptor,
+ CONSTRUCT_HOOK_NAME + "_" +
+ self._ctor.identifier.name,
+ 'u8', args)
+
+ def definition_body(self):
+ preamble = CGGeneric("""\
+let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object());
+let args = CallArgs::from_vp(vp, argc);
+""")
+ name = self._ctor.identifier.name
+ nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
+ callGenerator = CGMethodCall(["global.r()"], nativeName, True,
+ self.descriptor, self._ctor)
+ return CGList([preamble, callGenerator])
+
+
class CGClassFinalizeHook(CGAbstractClassHook):
"""
A hook for finalize, used to release our native object.
@@ -4568,6 +4606,8 @@ class CGDescriptor(CGThing):
if descriptor.interface.hasInterfaceObject():
cgThings.append(CGClassConstructHook(descriptor))
+ for ctor in descriptor.interface.namedConstructors:
+ cgThings.append(CGClassNameConstructHook(descriptor, ctor))
cgThings.append(CGInterfaceObjectJSClass(descriptor))
if not descriptor.interface.isCallback():
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index f8df9805ebd..5a2eb51f2ce 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -205,6 +205,7 @@ pub fn do_create_interface_objects(cx: *mut JSContext,
proto_proto: HandleObject,
proto_class: Option<&'static JSClass>,
constructor: Option<(NonNullJSNative, &'static str, u32)>,
+ named_constructors: &[(NonNullJSNative, &'static str, u32)],
dom_class: *const DOMClass,
members: &'static NativeProperties,
rval: MutableHandleObject) {
@@ -226,6 +227,55 @@ pub fn do_create_interface_objects(cx: *mut JSContext,
native, nargs, rval.handle(),
members, s.as_ptr())
}
+
+ for ctor in named_constructors.iter() {
+ let (cnative, cname, cnargs) = *ctor;
+
+ let cs = CString::new(cname).unwrap();
+ let constructor = RootedObject::new(cx, create_constructor(cx, cnative, cnargs, cs.as_ptr()));
+ assert!(!constructor.ptr.is_null());
+ unsafe {
+ assert!(JS_DefineProperty1(cx, constructor.handle(), "prototype".as_ptr() as *const i8,
+ rval.handle(),
+ JSPROP_PERMANENT | JSPROP_READONLY,
+ None, None) != 0);
+ }
+ define_constructor(cx, receiver, cs.as_ptr(), constructor.handle());
+ }
+
+}
+
+fn create_constructor(cx: *mut JSContext,
+ constructor_native: NonNullJSNative,
+ ctor_nargs: u32,
+ name: *const libc::c_char) -> *mut JSObject {
+ unsafe {
+ let fun = JS_NewFunction(cx, Some(constructor_native), ctor_nargs,
+ JSFUN_CONSTRUCTOR, name);
+ assert!(!fun.is_null());
+
+ let constructor = JS_GetFunctionObject(fun);
+ assert!(!constructor.is_null());
+
+ constructor
+ }
+}
+
+fn define_constructor(cx: *mut JSContext,
+ receiver: HandleObject,
+ name: *const libc::c_char,
+ constructor: HandleObject) {
+ unsafe {
+ let mut already_defined = 0;
+ assert!(JS_AlreadyHasOwnProperty(cx, receiver, name, &mut already_defined) != 0);
+
+ if already_defined == 0 {
+ assert!(JS_DefineProperty1(cx, receiver, name,
+ constructor,
+ 0, None, None) != 0);
+ }
+
+ }
}
/// Creates the *interface object*.
@@ -236,39 +286,28 @@ fn create_interface_object(cx: *mut JSContext,
ctor_nargs: u32, proto: HandleObject,
members: &'static NativeProperties,
name: *const libc::c_char) {
- unsafe {
- let fun = JS_NewFunction(cx, Some(constructor_native), ctor_nargs,
- JSFUN_CONSTRUCTOR, name);
- assert!(!fun.is_null());
+ let constructor = RootedObject::new(cx, create_constructor(cx, constructor_native, ctor_nargs, name));
+ assert!(!constructor.ptr.is_null());
- let constructor = RootedObject::new(cx, JS_GetFunctionObject(fun));
- assert!(!constructor.ptr.is_null());
-
- if let Some(static_methods) = members.static_methods {
- define_methods(cx, constructor.handle(), static_methods);
- }
+ if let Some(static_methods) = members.static_methods {
+ define_methods(cx, constructor.handle(), static_methods);
+ }
- if let Some(static_properties) = members.static_attrs {
- define_properties(cx, constructor.handle(), static_properties);
- }
+ if let Some(static_properties) = members.static_attrs {
+ define_properties(cx, constructor.handle(), static_properties);
+ }
- if let Some(constants) = members.consts {
- define_constants(cx, constructor.handle(), constants);
- }
+ if let Some(constants) = members.consts {
+ define_constants(cx, constructor.handle(), constants);
+ }
+ unsafe {
if !proto.get().is_null() {
assert!(JS_LinkConstructorAndPrototype(cx, constructor.handle(), proto) != 0);
}
-
- let mut already_defined = 0;
- assert!(JS_AlreadyHasOwnProperty(cx, receiver, name, &mut already_defined) != 0);
-
- if already_defined == 0 {
- assert!(JS_DefineProperty1(cx, receiver, name,
- constructor.handle(),
- 0, None, None) != 0);
- }
}
+
+ define_constructor(cx, receiver, name, constructor.handle());
}
/// Defines constants on `obj`.
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index 2ea5442bff6..6580e4f42a5 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -7,8 +7,10 @@ use dom::attr::{AttrHelpers, AttrValue};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, EventTargetCast, HTMLElementCast,
HTMLImageElementDerived};
+use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{LayoutJS, Root};
use dom::bindings::refcounted::Trusted;
@@ -151,6 +153,21 @@ impl HTMLImageElement {
let element = HTMLImageElement::new_inherited(localName, prefix, document);
Node::reflect_node(box element, document, HTMLImageElementBinding::Wrap)
}
+
+ pub fn Image(global: GlobalRef,
+ width: Option<u32>,
+ height: Option<u32>) -> Fallible<Root<HTMLImageElement>> {
+ let document = global.as_window().Document();
+ let image = HTMLImageElement::new("img".to_owned(), None, document.r());
+ if let Some(w) = width {
+ image.SetWidth(w);
+ }
+ if let Some(h) = height {
+ image.SetHeight(h);
+ }
+
+ Ok(image)
+ }
}
pub trait LayoutHTMLImageElementHelpers {
diff --git a/components/script/dom/webidls/HTMLImageElement.webidl b/components/script/dom/webidls/HTMLImageElement.webidl
index 71b49229393..defbfb68257 100644
--- a/components/script/dom/webidls/HTMLImageElement.webidl
+++ b/components/script/dom/webidls/HTMLImageElement.webidl
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.whatwg.org/html/#htmlimageelement
-//[NamedConstructor=Image(optional unsigned long width, optional unsigned long height)]
+[NamedConstructor=Image(optional unsigned long width, optional unsigned long height)]
interface HTMLImageElement : HTMLElement {
attribute DOMString alt;
attribute DOMString src;
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 5b780fd14da..68e5e677b29 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -14118,6 +14118,10 @@
"url": "/html/semantics/embedded-content/the-img-element/img.complete.html"
},
{
+ "path": "html/semantics/embedded-content/the-img-element/Image-constructor.html",
+ "url": "/html/semantics/embedded-content/the-img-element/Image-constructor.html"
+ },
+ {
"path": "html/semantics/embedded-content/the-img-element/relevant-mutations.html",
"url": "/html/semantics/embedded-content/the-img-element/relevant-mutations.html"
},
@@ -30594,4 +30598,4 @@
"rev": "075802c1d3387d07e31cd5887459d539b1297c8d",
"url_base": "/",
"version": 2
-} \ No newline at end of file
+}
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index 02a810d184b..975b61ab307 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -2745,18 +2745,6 @@
[HTMLImageElement interface: document.createElement("img") must inherit property "lowsrc" with the proper type (14)]
expected: FAIL
- [HTMLImageElement must be primary interface of new Image()]
- expected: FAIL
-
- [Stringification of new Image()]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "alt" with the proper type (0)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "src" with the proper type (1)]
- expected: FAIL
-
[HTMLImageElement interface: new Image() must inherit property "srcset" with the proper type (2)]
expected: FAIL
@@ -2766,51 +2754,12 @@
[HTMLImageElement interface: new Image() must inherit property "crossOrigin" with the proper type (4)]
expected: FAIL
- [HTMLImageElement interface: new Image() must inherit property "useMap" with the proper type (5)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "isMap" with the proper type (6)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "width" with the proper type (7)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "height" with the proper type (8)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "naturalWidth" with the proper type (9)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "naturalHeight" with the proper type (10)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "complete" with the proper type (11)]
- expected: FAIL
-
[HTMLImageElement interface: new Image() must inherit property "currentSrc" with the proper type (12)]
expected: FAIL
- [HTMLImageElement interface: new Image() must inherit property "name" with the proper type (13)]
- expected: FAIL
-
[HTMLImageElement interface: new Image() must inherit property "lowsrc" with the proper type (14)]
expected: FAIL
- [HTMLImageElement interface: new Image() must inherit property "align" with the proper type (15)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "hspace" with the proper type (16)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "vspace" with the proper type (17)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "longDesc" with the proper type (18)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "border" with the proper type (19)]
- expected: FAIL
-
[HTMLIFrameElement interface: existence and properties of interface object]
expected: FAIL
diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html
index e1933f77c76..effcfdae208 100644
--- a/tests/wpt/mozilla/tests/mozilla/interfaces.html
+++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html
@@ -168,6 +168,7 @@ var interfaceNamesInGlobalScope = [
"HTMLUnknownElement",
"HTMLVideoElement",
"ImageData",
+ "Image",
"KeyboardEvent",
"Location",
"MessageEvent",
diff --git a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/Image-constructor.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/Image-constructor.html
new file mode 100644
index 00000000000..528d3c80773
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-img-element/Image-constructor.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<title>DOM Image constructor Test</title>
+<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element" />
+<meta name="assert" content="Tests the Image constructor for the img-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+
+<div id="log"></div>
+<script>
+ test(function() {
+ var img = new Image();
+ assert_true(img != undefined);
+ }, "Image constructor works");
+
+ test(function() {
+ assert_true(Image.prototype === HTMLImageElement.prototype);
+ }, "Image and HTMLImageElement share a prototype");
+
+ test(function() {
+ assert_true((new Image()).localName === "img");
+ }, "Image localName is img");
+
+ test(function() {
+ assert_true((new Image()).namespaceURI === "http://www.w3.org/1999/xhtml");
+ }, "Image namespace URI is correct");
+
+</script>