mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-03-25 08:22:55 +03:00
make events work on elements
This commit is contained in:
parent
878fe3e68c
commit
897acff532
@ -26,6 +26,10 @@
|
||||
typedef struct jscontext jscontext;
|
||||
typedef struct jsobject jsobject;
|
||||
|
||||
struct dom_document;
|
||||
struct dom_node;
|
||||
struct dom_string;
|
||||
|
||||
/** Initialise javascript interpreter */
|
||||
void js_initialise(void);
|
||||
|
||||
@ -51,10 +55,16 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv);
|
||||
/* execute some javascript in a context */
|
||||
bool js_exec(jscontext *ctx, const char *txt, size_t txtlen);
|
||||
|
||||
struct dom_document;
|
||||
struct dom_node;
|
||||
|
||||
/* fire an event at a dom node */
|
||||
bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, struct dom_node *target);
|
||||
|
||||
bool
|
||||
js_dom_event_add_listener(jscontext *ctx,
|
||||
struct dom_document *document,
|
||||
struct dom_node *node,
|
||||
struct dom_string *event_type_dom,
|
||||
void *js_funcval);
|
||||
|
||||
|
||||
#endif /* _NETSURF_JAVASCRIPT_JS_H_ */
|
||||
|
@ -32,7 +32,7 @@ void js_initialise(void)
|
||||
/* Create a JS runtime. */
|
||||
|
||||
#if JS_VERSION >= 180
|
||||
JS_SetCStringsAreUTF8(); /* we prefer our runtime to be utf-8 */
|
||||
JS_SetCStringsAreUTF8(); /* we prefer our runtime to be utf-8 */
|
||||
#endif
|
||||
|
||||
rt = JS_NewRuntime(8L * 1024L * 1024L);
|
||||
@ -97,7 +97,7 @@ void js_destroycontext(jscontext *ctx)
|
||||
*
|
||||
* This performs the following actions
|
||||
* 1. constructs a new global object by initialising a window class
|
||||
* 2. Instantiate the global a window object
|
||||
* 2. Instantiate the global a window object
|
||||
*/
|
||||
jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
|
||||
{
|
||||
@ -116,7 +116,7 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
|
||||
}
|
||||
|
||||
window = jsapi_new_Window(cx, window_proto, NULL, win_priv, doc_priv);
|
||||
|
||||
|
||||
return (jsobject *)window;
|
||||
}
|
||||
|
||||
@ -139,9 +139,9 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (JS_EvaluateScript(cx,
|
||||
JS_GetGlobalObject(cx),
|
||||
txt, txtlen,
|
||||
if (JS_EvaluateScript(cx,
|
||||
JS_GetGlobalObject(cx),
|
||||
txt, txtlen,
|
||||
"<head>", 0, &rval) == JS_TRUE) {
|
||||
|
||||
return true;
|
||||
@ -174,8 +174,8 @@ bool js_fire_event(jscontext *ctx, const char *type, dom_document *doc, dom_node
|
||||
JSLOG("Dispatching event %s at window", type);
|
||||
|
||||
/* create and initialise and event object */
|
||||
exc = dom_string_create((unsigned char*)type,
|
||||
strlen(type),
|
||||
exc = dom_string_create((unsigned char*)type,
|
||||
strlen(type),
|
||||
&type_dom);
|
||||
if (exc != DOM_NO_ERR) {
|
||||
return false;
|
||||
@ -200,18 +200,18 @@ bool js_fire_event(jscontext *ctx, const char *type, dom_document *doc, dom_node
|
||||
/* dispatch event at the window object */
|
||||
argv[0] = OBJECT_TO_JSVAL(jsevent);
|
||||
|
||||
ret = JS_CallFunctionName(cx,
|
||||
JS_GetGlobalObject(cx),
|
||||
"dispatchEvent",
|
||||
1,
|
||||
argv,
|
||||
ret = JS_CallFunctionName(cx,
|
||||
JS_GetGlobalObject(cx),
|
||||
"dispatchEvent",
|
||||
1,
|
||||
argv,
|
||||
&rval);
|
||||
} else {
|
||||
JSLOG("Dispatching event %s at %p", type, node);
|
||||
|
||||
/* create and initialise and event object */
|
||||
exc = dom_string_create((unsigned char*)type,
|
||||
strlen(type),
|
||||
exc = dom_string_create((unsigned char*)type,
|
||||
strlen(type),
|
||||
&type_dom);
|
||||
if (exc != DOM_NO_ERR) {
|
||||
return false;
|
||||
@ -237,3 +237,93 @@ bool js_fire_event(jscontext *ctx, const char *type, dom_document *doc, dom_node
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct js_dom_event_private {
|
||||
JSContext *cx; /* javascript context */
|
||||
jsval funcval; /* javascript function to call */
|
||||
struct dom_node *node; /* dom node event listening on */
|
||||
dom_string *type; /* event type */
|
||||
dom_event_listener *listener; /* the listener containing this */
|
||||
};
|
||||
|
||||
static void
|
||||
js_dom_event_listener(struct dom_event *event, void *pw)
|
||||
{
|
||||
struct js_dom_event_private *private = pw;
|
||||
jsval event_argv[1];
|
||||
jsval event_rval;
|
||||
JSObject *jsevent;
|
||||
|
||||
JSLOG("WOOT dom event with %p", private);
|
||||
|
||||
if (!JSVAL_IS_VOID(private->funcval)) {
|
||||
jsevent = jsapi_new_Event(private->cx, NULL, NULL, event);
|
||||
if (jsevent != NULL) {
|
||||
|
||||
/* dispatch event at the window object */
|
||||
event_argv[0] = OBJECT_TO_JSVAL(jsevent);
|
||||
|
||||
JS_CallFunctionValue(private->cx,
|
||||
NULL,
|
||||
private->funcval,
|
||||
1,
|
||||
event_argv,
|
||||
&event_rval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add a listener to a dom node
|
||||
*
|
||||
* 1. Create a dom_event_listener From a handle_event function pointer
|
||||
* and a private word In a document context
|
||||
*
|
||||
* 2. Register for your events on a target (dom nodes are targets)
|
||||
* dom_event_target_add_event_listener(node, evt_name, listener,
|
||||
* capture_or_not)
|
||||
*
|
||||
*/
|
||||
|
||||
bool
|
||||
js_dom_event_add_listener(jscontext *ctx,
|
||||
struct dom_document *document,
|
||||
struct dom_node *node,
|
||||
struct dom_string *event_type_dom,
|
||||
void *js_funcval)
|
||||
{
|
||||
JSContext *cx = (JSContext *)ctx;
|
||||
dom_exception exc;
|
||||
struct js_dom_event_private *private;
|
||||
|
||||
private = malloc(sizeof(struct js_dom_event_private));
|
||||
if (private == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
exc = dom_event_listener_create(document,
|
||||
js_dom_event_listener,
|
||||
private,
|
||||
&private->listener);
|
||||
if (exc != DOM_NO_ERR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private->cx = cx;
|
||||
private->funcval = *(jsval *)js_funcval;
|
||||
private->node = node;
|
||||
private->type = event_type_dom;
|
||||
|
||||
JSLOG("adding %p to listener", private);
|
||||
|
||||
JS_AddValueRoot(cx, &private->funcval);
|
||||
exc = dom_event_target_add_event_listener(private->node,
|
||||
private->type,
|
||||
private->listener,
|
||||
true);
|
||||
if (exc != DOM_NO_ERR) {
|
||||
JSLOG("failed to add listener");
|
||||
JS_RemoveValueRoot(cx, &private->funcval);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -23,7 +23,9 @@ preamble %{
|
||||
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/corestrings.h"
|
||||
|
||||
#include "javascript/js.h"
|
||||
#include "javascript/jsapi.h"
|
||||
#include "javascript/jsapi/binding.h"
|
||||
|
||||
@ -218,24 +220,248 @@ getter childElementCount %{
|
||||
%}
|
||||
|
||||
getter EventHandler %{
|
||||
JSLOG("propname[%d]=\"%s\"",
|
||||
JSLOG("propname[%d].name=\"%s\"",
|
||||
tinyid,
|
||||
jsclass_properties[tinyid].name);
|
||||
%}
|
||||
|
||||
|
||||
setter EventHandler %{
|
||||
JSLOG("propname[%d]=\"%s\"",
|
||||
tinyid,
|
||||
dom_string *event_type_dom;
|
||||
|
||||
JSLOG("propname[%d].name=\"%s\"",
|
||||
tinyid,
|
||||
jsclass_properties[tinyid].name);
|
||||
|
||||
/*
|
||||
1. Create a dom_event_listener From a handle_event function pointer
|
||||
and a private word In a document context
|
||||
switch (tinyid) {
|
||||
case JSAPI_PROP_TINYID_onabort:
|
||||
event_type_dom = corestring_dom_abort;
|
||||
break;
|
||||
|
||||
2. Register for your events on a target (dom nodes are targets)
|
||||
dom_event_target_add_event_listener(node, evt_name, listener,
|
||||
capture_or_not)
|
||||
case JSAPI_PROP_TINYID_onblur:
|
||||
event_type_dom = corestring_dom_blur;
|
||||
break;
|
||||
|
||||
*/
|
||||
case JSAPI_PROP_TINYID_oncancel:
|
||||
event_type_dom = corestring_dom_cancel;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_oncanplay:
|
||||
event_type_dom = corestring_dom_canplay;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_oncanplaythrough:
|
||||
event_type_dom = corestring_dom_canplaythrough;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onchange:
|
||||
event_type_dom = corestring_dom_change;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onclick:
|
||||
event_type_dom = corestring_dom_click;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onclose:
|
||||
event_type_dom = corestring_dom_close;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_oncontextmenu:
|
||||
event_type_dom = corestring_dom_contextmenu;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_oncuechange:
|
||||
event_type_dom = corestring_dom_cuechange;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondblclick:
|
||||
event_type_dom = corestring_dom_dblclick;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondrag:
|
||||
event_type_dom = corestring_dom_drag;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondragend:
|
||||
event_type_dom = corestring_dom_dragend;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondragenter:
|
||||
event_type_dom = corestring_dom_dragenter;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondragleave:
|
||||
event_type_dom = corestring_dom_dragleave;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondragover:
|
||||
event_type_dom = corestring_dom_dragover;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondragstart:
|
||||
event_type_dom = corestring_dom_dragstart;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondrop:
|
||||
event_type_dom = corestring_dom_drop;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ondurationchange:
|
||||
event_type_dom = corestring_dom_durationchange;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onemptied:
|
||||
event_type_dom = corestring_dom_emptied;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onended:
|
||||
event_type_dom = corestring_dom_ended;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onerror:
|
||||
event_type_dom = corestring_dom_error;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onfocus:
|
||||
event_type_dom = corestring_dom_focus;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_oninput:
|
||||
event_type_dom = corestring_dom_input;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_oninvalid:
|
||||
event_type_dom = corestring_dom_invalid;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onkeydown:
|
||||
event_type_dom = corestring_dom_keydown;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onkeypress:
|
||||
event_type_dom = corestring_dom_keypress;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onkeyup:
|
||||
event_type_dom = corestring_dom_keyup;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onload:
|
||||
event_type_dom = corestring_dom_load;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onloadeddata:
|
||||
event_type_dom = corestring_dom_loadeddata;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onloadedmetadata:
|
||||
event_type_dom = corestring_dom_loadedmetadata;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onloadstart:
|
||||
event_type_dom = corestring_dom_loadstart;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onmousedown:
|
||||
event_type_dom = corestring_dom_mousedown;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onmousemove:
|
||||
event_type_dom = corestring_dom_mousemove;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onmouseout:
|
||||
event_type_dom = corestring_dom_mouseout;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onmouseover:
|
||||
event_type_dom = corestring_dom_mouseover;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onmouseup:
|
||||
event_type_dom = corestring_dom_mouseup;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onmousewheel:
|
||||
event_type_dom = corestring_dom_mousewheel;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onpause:
|
||||
event_type_dom = corestring_dom_pause;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onplay:
|
||||
event_type_dom = corestring_dom_play;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onplaying:
|
||||
event_type_dom = corestring_dom_playing;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onprogress:
|
||||
event_type_dom = corestring_dom_progress;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onratechange:
|
||||
event_type_dom = corestring_dom_ratechange;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onreset:
|
||||
event_type_dom = corestring_dom_reset;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onscroll:
|
||||
event_type_dom = corestring_dom_scroll;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onseeked:
|
||||
event_type_dom = corestring_dom_seeked;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onseeking:
|
||||
event_type_dom = corestring_dom_seeking;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onselect:
|
||||
event_type_dom = corestring_dom_select;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onshow:
|
||||
event_type_dom = corestring_dom_show;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onstalled:
|
||||
event_type_dom = corestring_dom_stalled;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onsubmit:
|
||||
event_type_dom = corestring_dom_submit;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onsuspend:
|
||||
event_type_dom = corestring_dom_suspend;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_ontimeupdate:
|
||||
event_type_dom = corestring_dom_timeupdate;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onvolumechange:
|
||||
event_type_dom = corestring_dom_volumechange;
|
||||
break;
|
||||
|
||||
case JSAPI_PROP_TINYID_onwaiting:
|
||||
event_type_dom = corestring_dom_waiting;
|
||||
break;
|
||||
|
||||
default:
|
||||
JSLOG("called with unknown tinyid");
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
js_dom_event_add_listener((struct jscontext *)cx,
|
||||
private->htmlc->document,
|
||||
(dom_node *)private->node,
|
||||
event_type_dom,
|
||||
vp);
|
||||
%}
|
||||
|
30
test/js/event-onclick.html
Normal file
30
test/js/event-onclick.html
Normal file
@ -0,0 +1,30 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>alert onclick example</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function causealert()
|
||||
{
|
||||
var txt = document.getElementById("p1").textContent;
|
||||
alert(txt);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div style="border: 1px solid red">
|
||||
<p id="p1">First line of paragraph.<br /></p>
|
||||
</div><br />
|
||||
|
||||
<button id="button1" >add another textNode.</button>
|
||||
|
||||
<script>
|
||||
var button = document.getElementById("button1");
|
||||
|
||||
button.onclick = causealert;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -5,12 +5,15 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>JavaScript Tests</h1>
|
||||
|
||||
|
||||
<h2>Window</h2>
|
||||
<ul>
|
||||
<li><a href="window.lately.html">location</a></li>
|
||||
<li><a href="window-enumerate.html">enumerate</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Document write</h2>
|
||||
<ul>
|
||||
<li><a href="inline-doc-write-simple.html">Simple document write</a></li>
|
||||
@ -22,7 +25,9 @@
|
||||
<li><a href="inline-innerhtml.html">Inline script innerHtml test</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>DOM tests</h2>
|
||||
|
||||
<h3>Reference method tests</h3>
|
||||
<ul>
|
||||
<li><a href="dom-element-firstElementChild.html">firstElementChild</a></li>
|
||||
@ -31,24 +36,34 @@
|
||||
<li><a href="dom-element-childElementCount.html">childElementCount</a></li>
|
||||
<li><a href="doc-dom2.html">getElementById</a></li>
|
||||
<li><a href="dom-getElementsByTagName.html">getElementsByTagName</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h3>Enumeration tests</h3>
|
||||
<ul>
|
||||
<li><a href="dom-node-enumerate.html">Node element interface</a></li>
|
||||
<li><a href="dom-body-enumerate.html">Body element interface</a></li>
|
||||
<li><a href="dom-document-enumerate.html">Document interface</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>Document element specific</h3>
|
||||
<ul>
|
||||
<li><a href="dom-doc-cookie.html">Cookie dispaly (only from server)</a></li>
|
||||
<li><a href="dom-doc-location.html">location</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Dom events</h2>
|
||||
<ul>
|
||||
<li><a href="event-onload.html">window.onload</a></li>
|
||||
<li><a href="event-onclick.html">button.onclick</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Assorted</h2>
|
||||
<ul>
|
||||
<li><a href="assorted-log-doc-write.html">console.log and document.write</a></li>
|
||||
|
||||
<li><a href="wikipedia-lcm.html">Example from wikipedia</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user