mirror of
https://github.com/servo/servo.git
synced 2025-06-20 07:08:59 +01:00
Generate bindings for Window.
This commit is contained in:
parent
5546f2105b
commit
a2bdab7989
24 changed files with 227 additions and 278 deletions
|
@ -401,6 +401,9 @@ DOMInterfaces = {
|
||||||
'implicitJSContext': [ 'constructor' ]
|
'implicitJSContext': [ 'constructor' ]
|
||||||
}],
|
}],
|
||||||
|
|
||||||
|
'Window': {
|
||||||
|
},
|
||||||
|
|
||||||
'WindowProxy': {
|
'WindowProxy': {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -567,5 +570,4 @@ addExternalIface('WebGLShaderPrecisionFormat',
|
||||||
headerFile='WebGLContext.h')
|
headerFile='WebGLContext.h')
|
||||||
addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
|
addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
|
||||||
headerFile='WebGLContext.h')
|
headerFile='WebGLContext.h')
|
||||||
addExternalIface('Window')
|
|
||||||
addExternalIface('XULElement')
|
addExternalIface('XULElement')
|
||||||
|
|
|
@ -1158,8 +1158,8 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||||
"rooting issues")
|
"rooting issues")
|
||||||
templateBody = "${declName} = ${val};"
|
templateBody = "${declName} = ${val};"
|
||||||
templateBody = handleDefaultNull(templateBody,
|
templateBody = handleDefaultNull(templateBody,
|
||||||
"${declName} = JS::NullValue()")
|
"${declName} = JSVAL_NULL")
|
||||||
return (templateBody, CGGeneric("JS::Value"), None, isOptional, None)
|
return (templateBody, CGGeneric("JSVal"), None, isOptional, "JSVAL_NULL")
|
||||||
|
|
||||||
if type.isObject():
|
if type.isObject():
|
||||||
assert not isEnforceRange and not isClamp
|
assert not isEnforceRange and not isClamp
|
||||||
|
@ -1263,7 +1263,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||||
" %s = %s;\n"
|
" %s = %s;\n"
|
||||||
"}" % (dataLoc, defaultStr))).define()
|
"}" % (dataLoc, defaultStr))).define()
|
||||||
|
|
||||||
return (template, declType, None, isOptional, None)
|
return (template, declType, None, isOptional, "0 as %s" % typeName)
|
||||||
|
|
||||||
def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
|
def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
|
||||||
argcAndIndex=None):
|
argcAndIndex=None):
|
||||||
|
@ -1308,11 +1308,7 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
|
||||||
originalDeclName = replacements["declName"]
|
originalDeclName = replacements["declName"]
|
||||||
if declType is not None:
|
if declType is not None:
|
||||||
if dealWithOptional:
|
if dealWithOptional:
|
||||||
replacements["declName"] = (
|
mutableDeclType = CGWrapper(declType, pre="Option< ", post=" >")
|
||||||
"const_cast< %s & >(%s.Value())" %
|
|
||||||
(declType.define(), originalDeclName))
|
|
||||||
mutableDeclType = CGWrapper(declType, pre="Optional< ", post=" >")
|
|
||||||
declType = CGWrapper(mutableDeclType, pre="const ")
|
|
||||||
newDecl = [CGGeneric("let mut "),
|
newDecl = [CGGeneric("let mut "),
|
||||||
CGGeneric(originalDeclName),
|
CGGeneric(originalDeclName),
|
||||||
CGGeneric(": "),
|
CGGeneric(": "),
|
||||||
|
@ -1327,17 +1323,6 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
|
||||||
)
|
)
|
||||||
|
|
||||||
if argcAndIndex is not None:
|
if argcAndIndex is not None:
|
||||||
if dealWithOptional:
|
|
||||||
declConstruct = CGIndenter(
|
|
||||||
CGGeneric("const_cast< %s &>(%s).Construct();" %
|
|
||||||
(mutableDeclType.define(), originalDeclName)))
|
|
||||||
if holderType is not None:
|
|
||||||
holderConstruct = CGIndenter(
|
|
||||||
CGGeneric("const_cast< %s &>(%s).Construct();" %
|
|
||||||
(mutableHolderType.define(), originalHolderName)))
|
|
||||||
else:
|
|
||||||
holderConstruct = None
|
|
||||||
else:
|
|
||||||
declConstruct = None
|
declConstruct = None
|
||||||
holderConstruct = None
|
holderConstruct = None
|
||||||
|
|
||||||
|
@ -2155,7 +2140,7 @@ class CGImports(CGWrapper):
|
||||||
# TODO imports to cover descriptors, etc.
|
# TODO imports to cover descriptors, etc.
|
||||||
|
|
||||||
def _useString(imports):
|
def _useString(imports):
|
||||||
return '#[allow(non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut)];' + ''.join(['use %s;\n' % i for i in imports]) + '\n'
|
return '#[allow(non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut,dead_assignment)];\n' + ''.join(['use %s;\n' % i for i in imports]) + '\n'
|
||||||
CGWrapper.__init__(self, child,
|
CGWrapper.__init__(self, child,
|
||||||
declarePre=_useString(sorted(declareImports)))
|
declarePre=_useString(sorted(declareImports)))
|
||||||
|
|
||||||
|
@ -4373,6 +4358,7 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::mouseevent::*', #XXXjdm
|
'dom::mouseevent::*', #XXXjdm
|
||||||
'dom::uievent::*', #XXXjdm
|
'dom::uievent::*', #XXXjdm
|
||||||
'dom::windowproxy::*', #XXXjdm
|
'dom::windowproxy::*', #XXXjdm
|
||||||
|
'dom::window::Window', #XXXjdm
|
||||||
'dom::bindings::codegen::*', #XXXjdm
|
'dom::bindings::codegen::*', #XXXjdm
|
||||||
'script_task::{JSPageInfo, page_from_context}',
|
'script_task::{JSPageInfo, page_from_context}',
|
||||||
'dom::bindings::utils::EnumEntry',
|
'dom::bindings::utils::EnumEntry',
|
||||||
|
|
71
src/components/script/dom/bindings/codegen/Window.webidl
Normal file
71
src/components/script/dom/bindings/codegen/Window.webidl
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* 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://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object
|
||||||
|
*/
|
||||||
|
|
||||||
|
[NamedPropertiesObject]
|
||||||
|
/*sealed*/ interface Window /*: EventTarget*/ {
|
||||||
|
// the current browsing context
|
||||||
|
/*[Unforgeable] readonly attribute WindowProxy window;
|
||||||
|
[Replaceable] readonly attribute WindowProxy self;*/
|
||||||
|
[Unforgeable] readonly attribute Document document;
|
||||||
|
attribute DOMString name;
|
||||||
|
/*[PutForwards=href, Unforgeable] readonly attribute Location location;
|
||||||
|
readonly attribute History history;
|
||||||
|
[Replaceable] readonly attribute BarProp locationbar;
|
||||||
|
[Replaceable] readonly attribute BarProp menubar;
|
||||||
|
[Replaceable] readonly attribute BarProp personalbar;
|
||||||
|
[Replaceable] readonly attribute BarProp scrollbars;
|
||||||
|
[Replaceable] readonly attribute BarProp statusbar;
|
||||||
|
[Replaceable] readonly attribute BarProp toolbar;*/
|
||||||
|
attribute DOMString status;
|
||||||
|
void close();
|
||||||
|
readonly attribute boolean closed;
|
||||||
|
void stop();
|
||||||
|
void focus();
|
||||||
|
void blur();
|
||||||
|
|
||||||
|
// other browsing contexts
|
||||||
|
/*[Replaceable] readonly attribute WindowProxy frames;
|
||||||
|
[Replaceable] readonly attribute unsigned long length;
|
||||||
|
[Unforgeable] readonly attribute WindowProxy top;
|
||||||
|
attribute WindowProxy? opener;
|
||||||
|
readonly attribute WindowProxy parent;*/
|
||||||
|
readonly attribute Element? frameElement;
|
||||||
|
/*WindowProxy open(optional DOMString url = "about:blank", optional DOMString target = "_blank", optional DOMString features = "", optional boolean replace = false);
|
||||||
|
getter WindowProxy (unsigned long index);*/
|
||||||
|
getter object (DOMString name);
|
||||||
|
|
||||||
|
// the user agent
|
||||||
|
/*readonly attribute Navigator navigator;
|
||||||
|
readonly attribute External external;
|
||||||
|
readonly attribute ApplicationCache applicationCache;*/
|
||||||
|
|
||||||
|
// user prompts
|
||||||
|
void alert(optional DOMString message = "");
|
||||||
|
boolean confirm(optional DOMString message = "");
|
||||||
|
DOMString? prompt(optional DOMString message = "", optional DOMString default = "");
|
||||||
|
void print();
|
||||||
|
any showModalDialog(DOMString url, optional any argument);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
/*Window implements GlobalEventHandlers;
|
||||||
|
Window implements WindowEventHandlers;*/
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface WindowTimers {
|
||||||
|
//long setTimeout(Function handler, optional long timeout, any... arguments);
|
||||||
|
//XXXjdm No support for Function or variadic arguments yet
|
||||||
|
long setTimeout(any handler, optional long timeout/*, any... arguments*/);
|
||||||
|
/*long setTimeout(DOMString handler, optional long timeout, any... arguments);
|
||||||
|
void clearTimeout(long handle);
|
||||||
|
long setInterval(Function handler, optional long timeout, any... arguments);
|
||||||
|
long setInterval(DOMString handler, optional long timeout, any... arguments);
|
||||||
|
void clearInterval(long handle);*/
|
||||||
|
};
|
||||||
|
Window implements WindowTimers;
|
|
@ -24,8 +24,8 @@ impl CacheableWrapper for DOMParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for DOMParser {
|
impl BindingObject for DOMParser {
|
||||||
fn GetParentObject(&self, _cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
return self.owner as @mut CacheableWrapper;
|
Some(self.owner as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use js::glue::*;
|
||||||
use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
|
use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
|
||||||
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
||||||
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB};
|
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB};
|
||||||
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction};
|
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction, JS_GetGlobalObject};
|
||||||
use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
|
use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
|
||||||
use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
|
use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
|
||||||
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype};
|
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype};
|
||||||
|
@ -616,7 +616,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, ..24]); //XXXjdm PrototyepList::id::_ID_Count
|
let protoArray = @mut ([0 as *JSObject, ..25]); //XXXjdm PrototyepList::id::_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);
|
||||||
|
@ -679,7 +679,9 @@ pub fn WrapNewBindingObject(cx: *JSContext, scope: *JSObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableWrapper) -> *JSObject {
|
pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: Option<@mut CacheableWrapper>) -> *JSObject {
|
||||||
|
match p {
|
||||||
|
Some(ref mut p) => {
|
||||||
let cache = p.get_wrappercache();
|
let cache = p.get_wrappercache();
|
||||||
let wrapper = cache.get_wrapper();
|
let wrapper = cache.get_wrapper();
|
||||||
if wrapper.is_not_null() {
|
if wrapper.is_not_null() {
|
||||||
|
@ -688,10 +690,13 @@ pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableW
|
||||||
let wrapper = p.wrap_object_shared(cx, scope);
|
let wrapper = p.wrap_object_shared(cx, scope);
|
||||||
cache.set_wrapper(wrapper);
|
cache.set_wrapper(wrapper);
|
||||||
wrapper
|
wrapper
|
||||||
|
}
|
||||||
|
None => unsafe { JS_GetGlobalObject(cx) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BindingObject {
|
pub trait BindingObject {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper;
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found: *mut bool,
|
pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found: *mut bool,
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
// DOM bindings for the Window object.
|
|
||||||
|
|
||||||
use dom::bindings::utils::{rust_box, squirrel_away, CacheableWrapper};
|
|
||||||
use dom::bindings::utils::{WrapperCache};
|
|
||||||
use dom::window::Window;
|
|
||||||
use super::utils;
|
|
||||||
|
|
||||||
use std::cast;
|
|
||||||
use std::libc;
|
|
||||||
use std::libc::c_uint;
|
|
||||||
use std::ptr::null;
|
|
||||||
use std::ptr;
|
|
||||||
use std::result;
|
|
||||||
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
|
|
||||||
use js::global::jsval_to_rust_str;
|
|
||||||
use js::glue::*;
|
|
||||||
use js::glue::RUST_JSVAL_TO_INT;
|
|
||||||
use js::jsapi::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
|
|
||||||
use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot};
|
|
||||||
use js::jsapi::{JS_ValueToString};
|
|
||||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
|
|
||||||
use js::jsapi::{JSNativeWrapper};
|
|
||||||
use js::rust::Compartment;
|
|
||||||
use js::{JS_ARGV, JSPROP_ENUMERATE, JSVAL_NULL};
|
|
||||||
use js::{JS_THIS_OBJECT, JS_SET_RVAL};
|
|
||||||
|
|
||||||
extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let argv = JS_ARGV(cx, vp);
|
|
||||||
assert!(argc == 1);
|
|
||||||
// Abstract this pattern and use it in debug, too?
|
|
||||||
let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
|
|
||||||
if jsstr.is_null() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.alert(jsval_to_rust_str(cx, jsstr));
|
|
||||||
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let argv = JS_ARGV(cx, vp);
|
|
||||||
assert!(argc >= 2);
|
|
||||||
|
|
||||||
//TODO: don't crash when passed a non-integer value for the timeout
|
|
||||||
|
|
||||||
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.setTimeout(
|
|
||||||
RUST_JSVAL_TO_INT(*ptr::offset(argv, 1)) as int,
|
|
||||||
argc, argv);
|
|
||||||
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn close(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.close();
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn gc(cx: *JSContext, _argc: c_uint, _vp: *JSVal) -> JSBool {
|
|
||||||
unsafe {
|
|
||||||
let runtime = JS_GetRuntime(cx);
|
|
||||||
JS_GC(runtime);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
|
|
||||||
let val = JS_GetReservedSlot(obj, 0);
|
|
||||||
cast::transmute(RUST_JSVAL_TO_PRIVATE(val))
|
|
||||||
}
|
|
||||||
|
|
||||||
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
|
||||||
debug!("finalize!");
|
|
||||||
unsafe {
|
|
||||||
let val = JS_GetReservedSlot(obj, 0);
|
|
||||||
let _: @Window = cast::transmute(RUST_JSVAL_TO_PRIVATE(val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(compartment: @mut Compartment) {
|
|
||||||
let proto = utils::define_empty_prototype(~"Window", None, compartment);
|
|
||||||
compartment.register_class(utils::instance_jsclass(~"WindowInstance", finalize, null()));
|
|
||||||
|
|
||||||
/* Define methods on a window */
|
|
||||||
let methods = [
|
|
||||||
JSFunctionSpec {
|
|
||||||
name: compartment.add_name(~"alert"),
|
|
||||||
call: JSNativeWrapper { op: alert, info: null() },
|
|
||||||
nargs: 1,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()
|
|
||||||
},
|
|
||||||
JSFunctionSpec {
|
|
||||||
name: compartment.add_name(~"setTimeout"),
|
|
||||||
call: JSNativeWrapper { op: setTimeout, info: null() },
|
|
||||||
nargs: 2,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()
|
|
||||||
},
|
|
||||||
JSFunctionSpec {
|
|
||||||
name: compartment.add_name(~"close"),
|
|
||||||
call: JSNativeWrapper { op: close, info: null() },
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()
|
|
||||||
},
|
|
||||||
JSFunctionSpec {
|
|
||||||
name: compartment.add_name(~"_trigger_gc"),
|
|
||||||
call: JSNativeWrapper { op: gc, info: null() },
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()
|
|
||||||
},
|
|
||||||
JSFunctionSpec {
|
|
||||||
name: null(),
|
|
||||||
call: JSNativeWrapper { op: null(), info: null() },
|
|
||||||
nargs: 0,
|
|
||||||
flags: 0,
|
|
||||||
selfHostedName: null()
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create(compartment: @mut Compartment, win: @mut Window) {
|
|
||||||
let obj = result::unwrap(
|
|
||||||
compartment.new_object_with_proto(~"WindowInstance",
|
|
||||||
~"Window", null()));
|
|
||||||
|
|
||||||
win.get_wrappercache().set_wrapper(obj.ptr);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(win));
|
|
||||||
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
|
|
||||||
|
|
||||||
//TODO: All properties/methods on Window need to be available on the global
|
|
||||||
// object as well. We probably want a special JSClass with a resolve hook.
|
|
||||||
compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
|
|
||||||
JS_PropertyStub, JS_StrictPropertyStub,
|
|
||||||
JSPROP_ENUMERATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CacheableWrapper for Window {
|
|
||||||
fn get_wrappercache(&mut self) -> &mut WrapperCache {
|
|
||||||
unsafe { cast::transmute(&self.wrapper) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
|
|
||||||
fail!(~"should this be called?");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -34,10 +34,10 @@ impl CacheableWrapper for Blob {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for Blob {
|
impl BindingObject for Blob {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,10 +76,10 @@ impl CacheableWrapper for ClientRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for ClientRect {
|
impl BindingObject for ClientRect {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,10 @@ impl CacheableWrapper for ClientRectList {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for ClientRectList {
|
impl BindingObject for ClientRectList {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ impl CacheableWrapper for AbstractDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for AbstractDocument {
|
impl BindingObject for AbstractDocument {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
do self.with_mut_base |doc| {
|
do self.with_mut_base |doc| {
|
||||||
doc.GetParentObject(cx)
|
doc.GetParentObject(cx)
|
||||||
}
|
}
|
||||||
|
@ -183,10 +183,10 @@ impl CacheableWrapper for Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for Document {
|
impl BindingObject for Document {
|
||||||
fn GetParentObject(&self, _cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
match self.window {
|
match self.window {
|
||||||
Some(win) => win as @mut CacheableWrapper,
|
Some(win) => Some(win as @mut CacheableWrapper),
|
||||||
None => fail!("whoops")
|
None => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,10 +126,10 @@ impl CacheableWrapper for Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for Event {
|
impl BindingObject for Event {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,11 @@ impl CacheableWrapper for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for EventTarget {
|
impl BindingObject for EventTarget {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
// TODO(tkuehn): This only handles top-level pages. Needs to handle subframes.
|
// TODO(tkuehn): This only handles top-level pages. Needs to handle subframes.
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,10 @@ impl CacheableWrapper for FormData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for FormData {
|
impl BindingObject for FormData {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,11 @@ impl HTMLCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for HTMLCollection {
|
impl BindingObject for HTMLCollection {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
// TODO(tkuehn): This only handles the top-level frame. Need to grab subframes.
|
// TODO(tkuehn): This only handles the top-level frame. Need to grab subframes.
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ use dom::htmlcollection::HTMLCollection;
|
||||||
use dom::node::{AbstractNode, ScriptView};
|
use dom::node::{AbstractNode, ScriptView};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
use js::JSPROP_ENUMERATE;
|
|
||||||
use js::glue::*;
|
|
||||||
use js::jsapi::{JSObject, JSContext};
|
use js::jsapi::{JSObject, JSContext};
|
||||||
|
|
||||||
use std::libc;
|
use std::libc;
|
||||||
|
@ -27,24 +25,8 @@ impl HTMLDocument {
|
||||||
parent: Document::new(root, window, HTML)
|
parent: Document::new(root, window, HTML)
|
||||||
};
|
};
|
||||||
|
|
||||||
let cache = ptr::to_mut_unsafe_ptr(doc.get_wrappercache());
|
|
||||||
let compartment = unsafe { (*window.get_ref().page).js_info.get_ref().js_compartment };
|
let compartment = unsafe { (*window.get_ref().page).js_info.get_ref().js_compartment };
|
||||||
let abstract = AbstractDocument::as_abstract(compartment.cx.ptr, doc);
|
AbstractDocument::as_abstract(compartment.cx.ptr, doc)
|
||||||
match window {
|
|
||||||
Some(win) => {
|
|
||||||
unsafe {
|
|
||||||
//FIXME: This is a hack until Window is autogenerated
|
|
||||||
let compartment = (*win.page).js_info.get_ref().js_compartment;
|
|
||||||
compartment.define_property(~"document",
|
|
||||||
RUST_OBJECT_TO_JSVAL((*cache).wrapper),
|
|
||||||
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
|
||||||
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
|
||||||
JSPROP_ENUMERATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => ()
|
|
||||||
}
|
|
||||||
abstract
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
|
fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
|
||||||
|
@ -210,7 +192,7 @@ impl CacheableWrapper for HTMLDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for HTMLDocument {
|
impl BindingObject for HTMLDocument {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
self.parent.GetParentObject(cx)
|
self.parent.GetParentObject(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ impl CacheableWrapper for MouseEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for MouseEvent {
|
impl BindingObject for MouseEvent {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
self.parent.GetParentObject(cx)
|
self.parent.GetParentObject(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -512,7 +512,6 @@ impl VoidPtrLike for AbstractNode<LayoutView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn define_bindings(compartment: @mut Compartment) {
|
pub fn define_bindings(compartment: @mut Compartment) {
|
||||||
bindings::window::init(compartment);
|
|
||||||
bindings::node::init(compartment);
|
bindings::node::init(compartment);
|
||||||
bindings::element::init(compartment);
|
bindings::element::init(compartment);
|
||||||
bindings::text::init(compartment);
|
bindings::text::init(compartment);
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl CacheableWrapper for UIEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for UIEvent {
|
impl BindingObject for UIEvent {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
self.parent.GetParentObject(cx)
|
self.parent.GetParentObject(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,23 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::utils::WrapperCache;
|
use dom::bindings::codegen::WindowBinding;
|
||||||
use dom::bindings::window;
|
use dom::bindings::utils::{WrapperCache, DOMString, null_string};
|
||||||
|
use dom::bindings::utils::{CacheableWrapper, BindingObject};
|
||||||
|
use dom::document::AbstractDocument;
|
||||||
|
use dom::node::{AbstractNode, ScriptView};
|
||||||
|
|
||||||
use layout_interface::ReflowForScriptQuery;
|
use layout_interface::ReflowForScriptQuery;
|
||||||
use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
|
use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
|
||||||
use servo_msg::compositor_msg::ScriptListener;
|
use servo_msg::compositor_msg::ScriptListener;
|
||||||
|
|
||||||
|
use js::glue::*;
|
||||||
|
use js::jsapi::{JSObject, JSContext};
|
||||||
|
use js::{JSVAL_NULL, JSPROP_ENUMERATE};
|
||||||
|
|
||||||
|
use std::cast;
|
||||||
use std::comm;
|
use std::comm;
|
||||||
use std::comm::Chan;
|
use std::comm::Chan;
|
||||||
use std::libc;
|
|
||||||
use std::int;
|
use std::int;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -49,44 +56,101 @@ pub struct TimerData {
|
||||||
args: ~[JSVal],
|
args: ~[JSVal],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn TimerData(argc: libc::c_uint, argv: *JSVal) -> TimerData {
|
|
||||||
unsafe {
|
|
||||||
let mut args = ~[];
|
|
||||||
|
|
||||||
let mut i = 2;
|
|
||||||
while i < argc as uint {
|
|
||||||
args.push(*ptr::offset(argv, i));
|
|
||||||
i += 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
TimerData {
|
|
||||||
funval : *argv,
|
|
||||||
args : args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: delayed_send shouldn't require Copy
|
|
||||||
#[allow(non_implicitly_copyable_typarams)]
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn alert(&self, s: &str) {
|
pub fn Alert(&self, s: &DOMString) {
|
||||||
// Right now, just print to the console
|
// Right now, just print to the console
|
||||||
io::println(fmt!("ALERT: %s", s));
|
io::println(fmt!("ALERT: %s", s.to_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&self) {
|
pub fn Close(&self) {
|
||||||
self.timer_chan.send(TimerMessage_TriggerExit);
|
self.timer_chan.send(TimerMessage_TriggerExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setTimeout(&self, timeout: int, argc: libc::c_uint, argv: *JSVal) {
|
pub fn Document(&self) -> AbstractDocument {
|
||||||
|
unsafe {
|
||||||
|
(*self.page).frame.get().document
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Name(&self) -> DOMString {
|
||||||
|
null_string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn SetName(&self, _name: &DOMString) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Status(&self) -> DOMString {
|
||||||
|
null_string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn SetStatus(&self, _status: &DOMString) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Closed(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Stop(&self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Focus(&self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Blur(&self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetFrameElement(&self) -> Option<AbstractNode<ScriptView>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Confirm(&self, _message: &DOMString) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Prompt(&self, _message: &DOMString, _default: &DOMString) -> DOMString {
|
||||||
|
null_string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Print(&self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ShowModalDialog(&self, _cx: *JSContext, _url: &DOMString, _argument: JSVal) -> JSVal {
|
||||||
|
JSVAL_NULL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CacheableWrapper for Window {
|
||||||
|
fn get_wrappercache(&mut self) -> &mut WrapperCache {
|
||||||
|
unsafe { cast::transmute(&self.wrapper) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
|
||||||
|
let mut unused = false;
|
||||||
|
WindowBinding::Wrap(cx, scope, self, &mut unused)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BindingObject for Window {
|
||||||
|
fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Window {
|
||||||
|
pub fn SetTimeout(&self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 {
|
||||||
let timeout = int::max(0, timeout) as uint;
|
let timeout = int::max(0, timeout) as uint;
|
||||||
|
|
||||||
// Post a delayed message to the per-window timer task; it will dispatch it
|
// Post a delayed message to the per-window timer task; it will dispatch it
|
||||||
// to the relevant script handler that will deal with it.
|
// to the relevant script handler that will deal with it.
|
||||||
|
let data = ~TimerData {
|
||||||
|
funval: callback,
|
||||||
|
args: ~[]
|
||||||
|
};
|
||||||
timer::delayed_send(&uv_global_loop::get(),
|
timer::delayed_send(&uv_global_loop::get(),
|
||||||
timeout,
|
timeout,
|
||||||
&self.timer_chan,
|
&self.timer_chan,
|
||||||
TimerMessage_Fire(~TimerData(argc, argv)));
|
TimerMessage_Fire(data));
|
||||||
|
return 0; //TODO return handle into list of active timers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn content_changed(&self) {
|
pub fn content_changed(&self) {
|
||||||
|
@ -121,7 +185,13 @@ impl Window {
|
||||||
unsafe {
|
unsafe {
|
||||||
// TODO(tkuehn): This just grabs the top-level page. Need to handle subframes.
|
// TODO(tkuehn): This just grabs the top-level page. Need to handle subframes.
|
||||||
let compartment = (*page).js_info.get_ref().js_compartment;
|
let compartment = (*page).js_info.get_ref().js_compartment;
|
||||||
window::create(compartment, win);
|
let cache = ptr::to_unsafe_ptr(win.get_wrappercache());
|
||||||
|
win.wrap_object_shared(compartment.cx.ptr, ptr::null()); //XXXjdm proper scope
|
||||||
|
compartment.define_property(~"window",
|
||||||
|
RUST_OBJECT_TO_JSVAL((*cache).wrapper),
|
||||||
|
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||||
|
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
||||||
|
JSPROP_ENUMERATE);
|
||||||
}
|
}
|
||||||
win
|
win
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,10 @@ impl WindowProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingObject for WindowProxy {
|
impl BindingObject for WindowProxy {
|
||||||
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
|
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
|
||||||
let page = page_from_context(cx);
|
let page = page_from_context(cx);
|
||||||
unsafe {
|
unsafe {
|
||||||
(*page).frame.get_ref().window as @mut CacheableWrapper
|
Some((*page).frame.get_ref().window as @mut CacheableWrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ pub mod dom {
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
pub mod window;
|
|
||||||
pub mod proxyhandler;
|
pub mod proxyhandler;
|
||||||
pub mod domparser;
|
pub mod domparser;
|
||||||
pub mod codegen {
|
pub mod codegen {
|
||||||
|
@ -47,6 +46,7 @@ pub mod dom {
|
||||||
pub mod PrototypeList;
|
pub mod PrototypeList;
|
||||||
pub mod RegisterBindings;
|
pub mod RegisterBindings;
|
||||||
pub mod UIEventBinding;
|
pub mod UIEventBinding;
|
||||||
|
pub mod WindowBinding;
|
||||||
pub mod WindowProxyBinding;
|
pub mod WindowProxyBinding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//window.alert(ClientRect);
|
//window.alert(ClientRect);
|
||||||
//window.alert(ClientRectList);
|
//window.alert(ClientRectList);
|
||||||
|
window.alert(window);
|
||||||
|
var document = window.document;
|
||||||
window.alert("==1==");
|
window.alert("==1==");
|
||||||
window.alert(document.documentElement);
|
window.alert(document.documentElement);
|
||||||
window.alert(document.documentElement.firstChild);
|
window.alert(document.documentElement.firstChild);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var divs = document.getElementsByTagName("div");
|
var divs = window.document.getElementsByTagName("div");
|
||||||
var div = divs[0];
|
var div = divs[0];
|
||||||
|
|
||||||
var count = 1000000;
|
var count = 1000000;
|
||||||
|
|
|
@ -7,7 +7,7 @@ function setWidth(w, i) {
|
||||||
window.setTimeout(function() { setWidth(w, i); }, 50);
|
window.setTimeout(function() { setWidth(w, i); }, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
var elem = document.documentElement.firstChild.firstChild.nextSibling.firstChild;
|
var elem = window.document.documentElement.firstChild.firstChild.nextSibling.firstChild;
|
||||||
window.alert(elem.tagName);
|
window.alert(elem.tagName);
|
||||||
window.alert(elem instanceof HTMLImageElement);
|
window.alert(elem instanceof HTMLImageElement);
|
||||||
window.alert(elem instanceof HTMLElement);
|
window.alert(elem instanceof HTMLElement);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue