2012-11-26 02:04:01 +04:00
|
|
|
/* Binding to generate window interface
|
|
|
|
*
|
|
|
|
* Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
|
|
|
|
*
|
|
|
|
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
|
|
|
*
|
|
|
|
* Released under the terms of the MIT License,
|
|
|
|
* http://www.opensource.org/licenses/mit-license
|
|
|
|
*/
|
2012-10-30 00:09:29 +04:00
|
|
|
|
|
|
|
|
|
|
|
webidlfile "html.idl";
|
2013-01-03 02:43:29 +04:00
|
|
|
webidlfile "dom.idl";
|
2013-06-02 23:58:57 +04:00
|
|
|
webidlfile "console.idl";
|
2012-10-30 00:09:29 +04:00
|
|
|
|
2012-11-26 02:04:01 +04:00
|
|
|
hdrcomment "Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>";
|
|
|
|
hdrcomment "This file is part of NetSurf, http://www.netsurf-browser.org/";
|
|
|
|
hdrcomment "Released under the terms of the MIT License,";
|
|
|
|
hdrcomment " http://www.opensource.org/licenses/mit-license";
|
2012-10-30 00:09:29 +04:00
|
|
|
|
|
|
|
preamble %{
|
|
|
|
|
|
|
|
#include <dom/dom.h>
|
2013-01-03 02:43:29 +04:00
|
|
|
|
2012-10-30 00:09:29 +04:00
|
|
|
#include "utils/config.h"
|
|
|
|
#include "utils/log.h"
|
2012-11-28 22:07:36 +04:00
|
|
|
#include "utils/corestrings.h"
|
2012-12-20 21:00:06 +04:00
|
|
|
#include "render/html_internal.h"
|
2012-10-30 00:09:29 +04:00
|
|
|
#include "javascript/jsapi.h"
|
|
|
|
|
2012-12-20 21:00:06 +04:00
|
|
|
#include "console.h"
|
|
|
|
#include "navigator.h"
|
|
|
|
#include "event.h"
|
|
|
|
#include "node.h"
|
|
|
|
#include "htmlcollection.h"
|
|
|
|
#include "nodelist.h"
|
|
|
|
#include "htmldocument.h"
|
|
|
|
#include "text.h"
|
2013-01-02 21:19:32 +04:00
|
|
|
#include "comment.h"
|
2012-12-20 21:00:06 +04:00
|
|
|
#include "htmlelement.h"
|
|
|
|
#include "window.h"
|
|
|
|
#include "location.h"
|
2012-11-28 22:53:11 +04:00
|
|
|
|
2013-02-07 22:16:37 +04:00
|
|
|
struct browser_window *jsapi_get_browser_window(JSContext *cx);
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
prologue %{
|
|
|
|
|
|
|
|
struct browser_window *jsapi_get_browser_window(JSContext *cx)
|
|
|
|
{
|
|
|
|
struct jsclass_private *private;
|
|
|
|
|
|
|
|
private = JS_GetInstancePrivate(cx,
|
|
|
|
JS_GetGlobalObject(cx),
|
|
|
|
&JSClass_Window,
|
|
|
|
NULL);
|
|
|
|
if (private != NULL) {
|
|
|
|
return private->bw;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
static bool
|
|
|
|
init_user_prototypes(JSContext *cx,
|
|
|
|
struct jsclass_private *private,
|
|
|
|
JSObject *parent)
|
|
|
|
{
|
|
|
|
/* Initialises all the user javascript classes to make their
|
|
|
|
* prototypes available.
|
|
|
|
*/
|
|
|
|
/** @todo should we be managing these prototype objects ourselves */
|
|
|
|
private->prototype_Document = jsapi_InitClass_Document(cx, parent);
|
|
|
|
if (private->prototype_Document == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Navigator = jsapi_InitClass_Navigator(cx, parent);
|
|
|
|
if (private->prototype_Navigator == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Location = jsapi_InitClass_Location(cx, parent);
|
|
|
|
if (private->prototype_Location == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Console = jsapi_InitClass_Console(cx, parent);
|
|
|
|
if (private->prototype_Console == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_HTMLElement = jsapi_InitClass_HTMLElement(cx, parent);
|
|
|
|
if (private->prototype_HTMLElement == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_HTMLCollection = jsapi_InitClass_HTMLCollection(cx, parent);
|
|
|
|
if (private->prototype_HTMLCollection == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_NodeList = jsapi_InitClass_NodeList(cx, parent);
|
|
|
|
if (private->prototype_NodeList == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Text = jsapi_InitClass_Text(cx, parent);
|
|
|
|
if (private->prototype_Text == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Comment = jsapi_InitClass_Comment(cx, parent);
|
|
|
|
if (private->prototype_Comment == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Node = jsapi_InitClass_Node(cx, parent);
|
|
|
|
if (private->prototype_Node == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private->prototype_Event = jsapi_InitClass_Event(cx, parent);
|
|
|
|
if (private->prototype_Event == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-10-30 00:09:29 +04:00
|
|
|
%}
|
|
|
|
|
2012-11-02 03:30:28 +04:00
|
|
|
binding window {
|
|
|
|
type js_libdom; /* the binding type */
|
|
|
|
|
|
|
|
interface Window; /* Web IDL interface to generate */
|
|
|
|
|
|
|
|
private "struct browser_window *" bw;
|
|
|
|
private "struct html_content *" htmlc;
|
2012-11-19 21:23:24 +04:00
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
/* prototypes held in this object */
|
|
|
|
internal "JSObject *" prototype_Document;
|
|
|
|
internal "JSObject *" prototype_Navigator;
|
|
|
|
internal "JSObject *" prototype_Location;
|
|
|
|
internal "JSObject *" prototype_Console;
|
|
|
|
internal "JSObject *" prototype_HTMLElement;
|
|
|
|
internal "JSObject *" prototype_HTMLCollection;
|
|
|
|
internal "JSObject *" prototype_NodeList;
|
|
|
|
internal "JSObject *" prototype_Text;
|
|
|
|
internal "JSObject *" prototype_Comment;
|
|
|
|
internal "JSObject *" prototype_Node;
|
|
|
|
internal "JSObject *" prototype_Event;
|
2012-11-23 17:48:11 +04:00
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
/** document instantiated on first use */
|
|
|
|
property unshared document;
|
|
|
|
|
|
|
|
/** navigator instantiated on first use */
|
|
|
|
property unshared navigator;
|
|
|
|
|
|
|
|
/** console instantiated on first use */
|
|
|
|
property unshared console;
|
|
|
|
|
|
|
|
/** location is unshared */
|
|
|
|
property unshared location;
|
|
|
|
|
|
|
|
/** @todo instantiate forms, history etc. attributes */
|
|
|
|
|
|
|
|
/* events through a single interface */
|
2012-11-23 17:48:11 +04:00
|
|
|
property unshared type EventHandler;
|
2012-11-02 03:30:28 +04:00
|
|
|
}
|
2012-10-30 03:46:07 +04:00
|
|
|
|
2012-11-06 22:06:23 +04:00
|
|
|
api mark %{
|
2013-06-02 23:58:57 +04:00
|
|
|
|
2012-11-06 22:06:23 +04:00
|
|
|
if (private != NULL) {
|
2013-06-02 23:58:57 +04:00
|
|
|
if (private->prototype_Document != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Document);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_Navigator != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Navigator);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_Location != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Location);
|
2012-11-06 22:06:23 +04:00
|
|
|
}
|
2013-06-02 23:58:57 +04:00
|
|
|
|
|
|
|
if (private->prototype_Console != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Console);
|
2012-11-06 22:06:23 +04:00
|
|
|
}
|
2013-06-02 23:58:57 +04:00
|
|
|
|
|
|
|
if (private->prototype_HTMLElement != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_HTMLElement);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_HTMLCollection != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_HTMLCollection);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_NodeList != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_NodeList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_Text != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Text);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_Comment != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Comment);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_Node != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Node);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (private->prototype_Event != NULL) {
|
|
|
|
JSAPI_GCMARK(private->prototype_Event);
|
2012-11-06 22:06:23 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
%}
|
|
|
|
|
2012-11-03 17:52:13 +04:00
|
|
|
api global %{
|
|
|
|
%}
|
2012-10-30 03:46:07 +04:00
|
|
|
|
2012-10-30 00:09:29 +04:00
|
|
|
api init %{
|
|
|
|
prototype = JS_NewCompartmentAndGlobalObject(cx, &JSClass_Window, NULL);
|
|
|
|
if (prototype == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @todo reconsider global object handling. future
|
|
|
|
* editions of spidermonkey appear to be removing the
|
|
|
|
* idea of a global so we probably need to handle
|
|
|
|
* global object references internally
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* set the contexts global */
|
|
|
|
JS_SetGlobalObject(cx, prototype);
|
|
|
|
|
|
|
|
/* Populate the global object with the standard globals, like
|
|
|
|
* Object and Array.
|
|
|
|
*/
|
|
|
|
if (!JS_InitStandardClasses(cx, prototype)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add functions to prototype */
|
|
|
|
if (!JS_DefineFunctions(cx, prototype, jsclass_functions)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add properties to prototype */
|
|
|
|
if (!JS_DefineProperties(cx, prototype, jsclass_properties))
|
|
|
|
return NULL;
|
2013-06-03 14:55:37 +04:00
|
|
|
|
|
|
|
/* as the global just got changed, force a GC run */
|
|
|
|
JS_GC(cx);
|
2012-10-30 00:09:29 +04:00
|
|
|
%}
|
|
|
|
|
|
|
|
api new %{
|
|
|
|
/* @todo sort out windows that are not globals */
|
|
|
|
assert(parent == NULL);
|
|
|
|
|
2013-01-03 02:43:29 +04:00
|
|
|
/* the window object is the global so its prototype *is* the instance */
|
|
|
|
newobject = prototype;
|
2012-10-30 00:09:29 +04:00
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
if (init_user_prototypes(cx, private, prototype) == false) {
|
|
|
|
/* prototype initialisation failed */
|
2012-10-30 00:09:29 +04:00
|
|
|
free(private);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
LOG(("Created new window object %p", newobject));
|
|
|
|
%}
|
|
|
|
|
|
|
|
getter document %{
|
|
|
|
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
|
|
|
|
/* already created - return it */
|
|
|
|
return JS_TRUE;
|
2012-10-30 00:09:29 +04:00
|
|
|
}
|
2012-10-31 05:22:35 +04:00
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
/* instantiate the subclasses off the window global */
|
|
|
|
jsret = jsapi_new_Document(cx,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(dom_document *)dom_node_ref(private->htmlc->document),
|
|
|
|
private->htmlc);
|
|
|
|
%}
|
|
|
|
|
|
|
|
getter navigator %{
|
|
|
|
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
|
|
|
|
/* already created - return it */
|
|
|
|
return JS_TRUE;
|
2012-10-30 00:09:29 +04:00
|
|
|
}
|
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
jsret = jsapi_new_Navigator(cx, NULL, NULL);
|
|
|
|
%}
|
2012-11-02 03:30:28 +04:00
|
|
|
|
2013-06-02 23:58:57 +04:00
|
|
|
getter console %{
|
|
|
|
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
|
|
|
|
/* already created - return it */
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
jsret = jsapi_new_Console(cx, NULL, NULL);
|
2012-10-30 00:09:29 +04:00
|
|
|
%}
|
|
|
|
|
2012-11-02 03:30:28 +04:00
|
|
|
operation confirm %{
|
|
|
|
warn_user(message, NULL);
|
|
|
|
%}
|
2012-10-30 00:09:29 +04:00
|
|
|
|
2012-11-02 03:30:28 +04:00
|
|
|
operation alert %{
|
|
|
|
warn_user(message, NULL);
|
|
|
|
%}
|
2012-10-30 00:09:29 +04:00
|
|
|
|
2012-11-02 03:30:28 +04:00
|
|
|
operation prompt %{
|
|
|
|
warn_user(message, NULL);
|
|
|
|
%}
|
|
|
|
|
2012-11-28 22:07:36 +04:00
|
|
|
/* boolean dispatchEvent(Event event); */
|
|
|
|
operation dispatchEvent %{
|
|
|
|
/* this implementation is unique to the window object as it is
|
2013-01-03 02:43:29 +04:00
|
|
|
* not a "real" dom node.
|
2012-11-28 22:07:36 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* caution, this must match the struct generated from event.bnd */
|
2012-11-29 02:08:11 +04:00
|
|
|
struct {
|
|
|
|
dom_event *event;
|
|
|
|
} *event_private;
|
|
|
|
dom_string *type_dom = NULL;
|
|
|
|
dom_exception exc;
|
|
|
|
jsval eventval = JSVAL_VOID;
|
|
|
|
jsval event_argv[1];
|
|
|
|
jsval event_rval;
|
|
|
|
|
|
|
|
event_private = JS_GetInstancePrivate(cx, event, &JSClass_Event, NULL);
|
|
|
|
if (event_private->event == NULL) {
|
|
|
|
/** @todo type error? */
|
2012-11-28 22:07:36 +04:00
|
|
|
jsret = JS_FALSE;
|
|
|
|
} else {
|
2012-11-29 02:08:11 +04:00
|
|
|
exc = dom_event_get_type(event_private->event, &type_dom);
|
|
|
|
if (exc == DOM_NO_ERR) {
|
|
|
|
|
|
|
|
if (dom_string_isequal(type_dom, corestring_dom_load)) {
|
|
|
|
JS_GetProperty(cx, JSAPI_THIS_OBJECT(cx, vp), "onload", &eventval);
|
|
|
|
}
|
|
|
|
|
2012-11-29 02:35:40 +04:00
|
|
|
if (!JSVAL_IS_VOID(eventval)) {
|
2012-11-29 02:08:11 +04:00
|
|
|
event_argv[0] = eventval;
|
|
|
|
jsret = JS_CallFunctionValue(cx, NULL, eventval, 1, event_argv, &event_rval);
|
2012-11-28 22:07:36 +04:00
|
|
|
}
|
|
|
|
}
|
2013-01-03 02:43:29 +04:00
|
|
|
}
|
2012-11-28 22:07:36 +04:00
|
|
|
%}
|
|
|
|
|
2012-12-07 16:08:56 +04:00
|
|
|
getter location %{
|
2013-06-02 23:58:57 +04:00
|
|
|
if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
|
|
|
|
/* already created - return it */
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* should get the docuemnts location
|
2012-12-07 16:08:56 +04:00
|
|
|
jsval loc;
|
|
|
|
JS_GetProperty(cx, private->document, "location", &loc);
|
|
|
|
jsret = JSVAL_TO_OBJECT(loc);
|
2013-06-02 23:58:57 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
jsret = jsapi_new_Location(cx,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
llcache_handle_get_url(private->htmlc->base.llcache));
|
2012-12-07 16:08:56 +04:00
|
|
|
%}
|
|
|
|
|
|
|
|
getter window %{
|
|
|
|
jsret = obj;
|
|
|
|
%}
|
|
|
|
|
|
|
|
getter self %{
|
|
|
|
jsret = obj;
|
|
|
|
%}
|
|
|
|
|
2013-06-04 02:10:53 +04:00
|
|
|
/* very iffy implementation */
|
|
|
|
getter top %{
|
|
|
|
jsret = obj;
|
|
|
|
%}
|
|
|
|
|
2012-11-23 17:48:11 +04:00
|
|
|
getter EventHandler %{
|
2012-11-28 22:07:36 +04:00
|
|
|
/* this implementation is unique to the window object as it is
|
2013-01-03 02:43:29 +04:00
|
|
|
* not a dom node.
|
2012-11-28 22:07:36 +04:00
|
|
|
*/
|
2013-01-03 02:43:29 +04:00
|
|
|
JSLOG("propname[%d]=\"%s\"",
|
2012-12-03 21:34:03 +04:00
|
|
|
tinyid,
|
|
|
|
jsclass_properties[tinyid].name);
|
2012-11-23 17:48:11 +04:00
|
|
|
%}
|
|
|
|
|
|
|
|
setter EventHandler %{
|
2012-11-28 22:07:36 +04:00
|
|
|
/* this implementation is unique to the window object as it is
|
2013-01-03 02:43:29 +04:00
|
|
|
* not a dom node.
|
2012-11-28 22:07:36 +04:00
|
|
|
*/
|
2013-01-03 02:43:29 +04:00
|
|
|
JSLOG("propname[%d]=\"%s\"",
|
|
|
|
tinyid,
|
2012-12-03 21:34:03 +04:00
|
|
|
jsclass_properties[tinyid].name);
|
2012-11-23 17:48:11 +04:00
|
|
|
%}
|