Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3584 | sourcerer | 1 | /* Binding to generate HTMLdocument interface |
2 | * |
||
3 | * Copyright 2012 Vincent Sanders |
||
4 | * |
||
5 | * This file is part of NetSurf, http://www.netsurf-browser.org/ |
||
6 | * |
||
7 | * Released under the terms of the MIT License, |
||
8 | * http://www.opensource.org/licenses/mit-license |
||
9 | */ |
||
10 | |||
11 | webidlfile "html.idl"; |
||
12 | |||
13 | hdrcomment "Copyright 2012 Vincent Sanders |
||
14 | hdrcomment "This file is part of NetSurf, http://www.netsurf-browser.org/"; |
||
15 | hdrcomment "Released under the terms of the MIT License,"; |
||
16 | hdrcomment " http://www.opensource.org/licenses/mit-license"; |
||
17 | |||
18 | preamble %{ |
||
19 | |||
20 | #include |
||
21 | |||
22 | #include "utils/config.h" |
||
23 | #include "utils/log.h" |
||
24 | #include "utils/corestrings.h" |
||
25 | #include "utils/libdom.h" |
||
26 | #include "content/urldb.h" |
||
27 | #include "javascript/js.h" |
||
28 | #include "javascript/jsapi.h" |
||
29 | #include "render/html_internal.h" |
||
30 | |||
31 | #include "htmldocument.h" |
||
32 | #include "htmlelement.h" |
||
33 | #include "text.h" |
||
34 | #include "nodelist.h" |
||
35 | #include "location.h" |
||
36 | |||
37 | %} |
||
38 | |||
39 | #include "dom.bnd" |
||
40 | |||
41 | binding document { |
||
42 | type js_libdom; /* the binding type */ |
||
43 | |||
44 | interface Document; /* Web IDL interface to generate */ |
||
45 | |||
46 | /* parameters to constructor value stored in private |
||
47 | * context structure. |
||
48 | */ |
||
49 | private "dom_document *" node; |
||
50 | private "struct html_content *" htmlc; |
||
51 | |||
52 | /** location instantiated on first use */ |
||
53 | property unshared location; |
||
54 | |||
55 | /* compatability mode instantiated on first use */ |
||
56 | property unshared compatMode; |
||
57 | |||
58 | /* events through a single interface */ |
||
59 | property unshared type EventHandler; |
||
60 | } |
||
61 | |||
62 | api finalise %{ |
||
63 | if (private != NULL) { |
||
64 | JSLOG("dom_document %p in content %p", |
||
65 | private->node, private->htmlc); |
||
66 | dom_node_unref(private->node); |
||
67 | } |
||
68 | %} |
||
69 | |||
70 | |||
71 | getter location %{ |
||
72 | if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) { |
||
73 | /* already created - return it */ |
||
74 | return JS_TRUE; |
||
75 | } |
||
76 | jsret = jsapi_new_Location(cx, |
||
77 | NULL, |
||
78 | NULL, |
||
79 | llcache_handle_get_url(private->htmlc->base.llcache), |
||
80 | private->htmlc); |
||
81 | %} |
||
82 | |||
83 | getter URL %{ |
||
84 | jsval loc; |
||
85 | jsval jsstr = JSVAL_NULL; |
||
86 | if (JS_GetProperty(cx, obj, "location", &loc) == JS_TRUE) { |
||
87 | JS_GetProperty(cx, JSVAL_TO_OBJECT(loc), "href", &jsstr); |
||
88 | } |
||
89 | jsret = JSVAL_TO_STRING(jsstr); |
||
90 | %} |
||
91 | |||
92 | getter documentURI %{ |
||
93 | jsval loc; |
||
94 | jsval jsstr = JSVAL_NULL; |
||
95 | if (JS_GetProperty(cx, obj, "location", &loc) == JS_TRUE) { |
||
96 | JS_GetProperty(cx, JSVAL_TO_OBJECT(loc), "href", &jsstr); |
||
97 | } |
||
98 | jsret = JSVAL_TO_STRING(jsstr); |
||
99 | %} |
||
100 | |||
101 | |||
102 | getter compatMode %{ |
||
103 | /* Returns the string "CSS1Compat" if document is in no-quirks |
||
104 | * mode or limited-quirks mode, and "BackCompat", if document |
||
105 | * is in quirks mode. |
||
106 | */ |
||
107 | if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) { |
||
108 | /* already created, just use it */ |
||
109 | return JS_TRUE; |
||
110 | } |
||
111 | if (private->htmlc->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL) { |
||
112 | jsret = JS_NewStringCopyN(cx, "BackCompat", SLEN("BackCompat")); |
||
113 | } else { |
||
114 | jsret = JS_NewStringCopyN(cx, "CSS1Compat", SLEN("CSS1Compat")); |
||
115 | } |
||
116 | |||
117 | %} |
||
118 | |||
119 | /* |
||
120 | getter characterSet %{ |
||
121 | %} |
||
122 | |||
123 | getter contentType %{ |
||
124 | %} |
||
125 | */ |
||
126 | |||
127 | getter cookie %{ |
||
128 | char *cookie_str; |
||
129 | cookie_str = urldb_get_cookie(llcache_handle_get_url(private->htmlc->base.llcache), false); |
||
130 | if (cookie_str != NULL) { |
||
131 | jsret = JS_NewStringCopyN(cx, cookie_str, strlen(cookie_str)); |
||
132 | free(cookie_str); |
||
133 | } |
||
134 | %} |
||
135 | |||
136 | getter documentElement %{ |
||
137 | dom_exception exc; |
||
138 | dom_element *element; |
||
139 | |||
140 | /* document (html) element */ |
||
141 | exc = dom_document_get_document_element(private->node, (void *)&element); |
||
142 | if (exc != DOM_NO_ERR) { |
||
143 | return JS_FALSE; |
||
144 | } |
||
145 | |||
146 | if (element != NULL) { |
||
147 | jsret = jsapi_new_HTMLElement(cx, NULL, NULL, element, private->htmlc); |
||
148 | } |
||
149 | %} |
||
150 | |||
151 | getter head %{ |
||
152 | dom_node *element; |
||
153 | dom_node *head; |
||
154 | dom_exception exc; |
||
155 | |||
156 | /* document (html) element */ |
||
157 | exc = dom_document_get_document_element(private->node, &element); |
||
158 | if (exc != DOM_NO_ERR) { |
||
159 | return JS_FALSE; |
||
160 | } |
||
161 | |||
162 | if (element != NULL) { |
||
163 | head = libdom_find_first_element(element, corestring_lwc_head) ; |
||
164 | if (head != NULL) { |
||
165 | jsret = jsapi_new_HTMLElement(cx, NULL, NULL, (dom_element *)head, private->htmlc); |
||
166 | } |
||
167 | dom_node_unref(element); |
||
168 | } |
||
169 | %} |
||
170 | |||
171 | getter body %{ |
||
172 | dom_node *element; |
||
173 | dom_node *body; |
||
174 | dom_exception exc; |
||
175 | |||
176 | JSDBG("Getting your body"); |
||
177 | |||
178 | /* document (html) element */ |
||
179 | exc = dom_document_get_document_element(private->node, &element); |
||
180 | if (exc != DOM_NO_ERR) { |
||
181 | return JS_FALSE; |
||
182 | } |
||
183 | |||
184 | if (element != NULL) { |
||
185 | body = libdom_find_first_element(element, corestring_lwc_body) ; |
||
186 | if (body != NULL) { |
||
187 | jsret = jsapi_new_HTMLElement(cx, NULL, NULL, (dom_element *)body, private->htmlc); |
||
188 | } |
||
189 | dom_node_unref(element); |
||
190 | } |
||
191 | |||
192 | JSDBG("returning jsobject %p",jsret); |
||
193 | |||
194 | %} |
||
195 | |||
196 | operation getElementById %{ |
||
197 | dom_string *elementId_dom; |
||
198 | dom_element *element; |
||
199 | dom_exception exc; |
||
200 | |||
201 | exc = dom_string_create((unsigned char*)elementId, elementId_len, &elementId_dom); |
||
202 | if (exc != DOM_NO_ERR) { |
||
203 | return JS_FALSE; |
||
204 | } |
||
205 | |||
206 | exc = dom_document_get_element_by_id(private->node, elementId_dom, &element); |
||
207 | dom_string_unref(elementId_dom); |
||
208 | if (exc != DOM_NO_ERR) { |
||
209 | return JS_FALSE; |
||
210 | } |
||
211 | |||
212 | if (element != NULL) { |
||
213 | jsret = jsapi_new_HTMLElement(cx, NULL, NULL, element, private->htmlc); |
||
214 | } |
||
215 | %} |
||
216 | |||
217 | /* |
||
218 | * |
||
219 | * Dom 4 says this should return a htmlcollection, libdom currently |
||
220 | * returns DOM 3 spec of a nodelist |
||
221 | */ |
||
222 | /* HTMLCollection Document::getElementsByTagName(DOMString localName); */ |
||
223 | operation getElementsByTagName %{ |
||
224 | dom_string *localName_dom; |
||
225 | /* dom_html_collection *collection;*/ |
||
226 | dom_nodelist *nodelist; |
||
227 | dom_exception exc; |
||
228 | |||
229 | exc = dom_string_create((uint8_t *)localName, localName_len, &localName_dom); |
||
230 | if (exc != DOM_NO_ERR) { |
||
231 | return JS_FALSE; |
||
232 | } |
||
233 | |||
234 | exc = dom_document_get_elements_by_tag_name(private->node, localName_dom, /*&collection*/&nodelist); |
||
235 | dom_string_unref(localName_dom); |
||
236 | if (exc != DOM_NO_ERR) { |
||
237 | return JS_FALSE; |
||
238 | } |
||
239 | |||
240 | if (/*collection*/nodelist != NULL) { |
||
241 | /*jsret = jsapi_new_HTMLCollection(cx, |
||
242 | NULL, |
||
243 | NULL, |
||
244 | collection, |
||
245 | private->htmlc);*/ |
||
246 | jsret = jsapi_new_NodeList(cx, |
||
247 | NULL, |
||
248 | NULL, |
||
249 | nodelist, |
||
250 | private->htmlc); |
||
251 | } |
||
252 | |||
253 | %} |
||
254 | |||
255 | operation write %{ |
||
256 | if (private->htmlc->parser != NULL) { |
||
257 | dom_hubbub_parser_insert_chunk(private->htmlc->parser, (uint8_t *)text, text_len); |
||
258 | } |
||
259 | %} |
||
260 | |||
261 | /* interface Document (dom) { Text createTextNode(DOMString data); } */ |
||
262 | operation createTextNode %{ |
||
263 | dom_string *data_dom; |
||
264 | dom_exception exc; |
||
265 | dom_text *text; |
||
266 | |||
267 | if (data != NULL) { |
||
268 | |||
269 | JSDBG("Creating text node for string \"%s\"", data); |
||
270 | exc = dom_string_create((unsigned char*)data, data_len, &data_dom); |
||
271 | if (exc != DOM_NO_ERR) { |
||
272 | return JS_FALSE; |
||
273 | } |
||
274 | |||
275 | exc = dom_document_create_text_node(private->node, data_dom, &text); |
||
276 | dom_string_unref(data_dom); |
||
277 | if (exc != DOM_NO_ERR) { |
||
278 | return JS_FALSE; |
||
279 | } |
||
280 | |||
281 | jsret = jsapi_new_Text(cx, NULL, NULL, text, private->htmlc); |
||
282 | } |
||
283 | |||
284 | JSDBG("returning jsobject %p",jsret); |
||
285 | |||
286 | %} |
||
287 | |||
288 | /* interface Document (dom) { Comment createComment(DOMString data); } */ |
||
289 | operation createComment %{ |
||
290 | dom_string *data_dom; |
||
291 | dom_exception exc; |
||
292 | dom_comment *comment; |
||
293 | |||
294 | if (data != NULL) { |
||
295 | |||
296 | JSDBG("Creating string \"%s\"", data); |
||
297 | exc = dom_string_create((unsigned char*)data, |
||
298 | data_len, |
||
299 | &data_dom); |
||
300 | if (exc != DOM_NO_ERR) { |
||
301 | return JS_FALSE; |
||
302 | } |
||
303 | |||
304 | JSDBG("Creating comment object for dom string \"%s\"", |
||
305 | dom_string_data(data_dom)); |
||
306 | exc = dom_document_create_comment(private->node, |
||
307 | data_dom, |
||
308 | &comment); |
||
309 | dom_string_unref(data_dom); |
||
310 | if (exc != DOM_NO_ERR) { |
||
311 | return JS_FALSE; |
||
312 | } |
||
313 | |||
314 | jsret = jsapi_new_Comment(cx, NULL, NULL, comment, private->htmlc); |
||
315 | } |
||
316 | |||
317 | JSDBG("returning jsobject %p", jsret); |
||
318 | |||
319 | %} |
||
320 | |||
321 | /* in dom Document */ |
||
322 | operation createElement %{ |
||
323 | dom_string *localName_dom; |
||
324 | dom_exception exc; |
||
325 | dom_element *element; |
||
326 | |||
327 | if (localName != NULL) { |
||
328 | JSDBG("Creating text node for string \"%s\"", localName); |
||
329 | exc = dom_string_create((unsigned char*)localName, localName_len, &localName_dom); |
||
330 | if (exc != DOM_NO_ERR) { |
||
331 | return JS_FALSE; |
||
332 | } |
||
333 | |||
334 | exc = dom_document_create_element(private->node, localName_dom, &element); |
||
335 | dom_string_unref(localName_dom); |
||
336 | if (exc != DOM_NO_ERR) { |
||
337 | return JS_FALSE; |
||
338 | } |
||
339 | |||
340 | jsret = jsapi_new_HTMLElement(cx, NULL, NULL, element, private->htmlc); |
||
341 | } |
||
342 | |||
343 | JSDBG("returning jsobject %p",jsret); |
||
344 | |||
345 | %} |
||
346 | |||
347 | getter EventHandler %{ |
||
348 | JSLOG("propname[%d].name=\"%s\"", |
||
349 | tinyid, |
||
350 | jsclass_properties[tinyid].name); |
||
351 | %} |
||
352 | |||
353 | |||
354 | setter EventHandler %{ |
||
355 | dom_string *event_type_dom; |
||
356 | |||
357 | JSLOG("propname[%d].name=\"%s\"", |
||
358 | tinyid, |
||
359 | jsclass_properties[tinyid].name); |
||
360 | |||
361 | switch (tinyid) { |
||
362 | case JSAPI_PROP_TINYID_onabort: |
||
363 | event_type_dom = corestring_dom_abort; |
||
364 | break; |
||
365 | |||
366 | case JSAPI_PROP_TINYID_onblur: |
||
367 | event_type_dom = corestring_dom_blur; |
||
368 | break; |
||
369 | |||
370 | case JSAPI_PROP_TINYID_oncancel: |
||
371 | event_type_dom = corestring_dom_cancel; |
||
372 | break; |
||
373 | |||
374 | case JSAPI_PROP_TINYID_oncanplay: |
||
375 | event_type_dom = corestring_dom_canplay; |
||
376 | break; |
||
377 | |||
378 | case JSAPI_PROP_TINYID_oncanplaythrough: |
||
379 | event_type_dom = corestring_dom_canplaythrough; |
||
380 | break; |
||
381 | |||
382 | case JSAPI_PROP_TINYID_onchange: |
||
383 | event_type_dom = corestring_dom_change; |
||
384 | break; |
||
385 | |||
386 | case JSAPI_PROP_TINYID_onclick: |
||
387 | event_type_dom = corestring_dom_click; |
||
388 | break; |
||
389 | |||
390 | case JSAPI_PROP_TINYID_onclose: |
||
391 | event_type_dom = corestring_dom_close; |
||
392 | break; |
||
393 | |||
394 | case JSAPI_PROP_TINYID_oncontextmenu: |
||
395 | event_type_dom = corestring_dom_contextmenu; |
||
396 | break; |
||
397 | |||
398 | case JSAPI_PROP_TINYID_oncuechange: |
||
399 | event_type_dom = corestring_dom_cuechange; |
||
400 | break; |
||
401 | |||
402 | case JSAPI_PROP_TINYID_ondblclick: |
||
403 | event_type_dom = corestring_dom_dblclick; |
||
404 | break; |
||
405 | |||
406 | case JSAPI_PROP_TINYID_ondrag: |
||
407 | event_type_dom = corestring_dom_drag; |
||
408 | break; |
||
409 | |||
410 | case JSAPI_PROP_TINYID_ondragend: |
||
411 | event_type_dom = corestring_dom_dragend; |
||
412 | break; |
||
413 | |||
414 | case JSAPI_PROP_TINYID_ondragenter: |
||
415 | event_type_dom = corestring_dom_dragenter; |
||
416 | break; |
||
417 | |||
418 | case JSAPI_PROP_TINYID_ondragleave: |
||
419 | event_type_dom = corestring_dom_dragleave; |
||
420 | break; |
||
421 | |||
422 | case JSAPI_PROP_TINYID_ondragover: |
||
423 | event_type_dom = corestring_dom_dragover; |
||
424 | break; |
||
425 | |||
426 | case JSAPI_PROP_TINYID_ondragstart: |
||
427 | event_type_dom = corestring_dom_dragstart; |
||
428 | break; |
||
429 | |||
430 | case JSAPI_PROP_TINYID_ondrop: |
||
431 | event_type_dom = corestring_dom_drop; |
||
432 | break; |
||
433 | |||
434 | case JSAPI_PROP_TINYID_ondurationchange: |
||
435 | event_type_dom = corestring_dom_durationchange; |
||
436 | break; |
||
437 | |||
438 | case JSAPI_PROP_TINYID_onemptied: |
||
439 | event_type_dom = corestring_dom_emptied; |
||
440 | break; |
||
441 | |||
442 | case JSAPI_PROP_TINYID_onended: |
||
443 | event_type_dom = corestring_dom_ended; |
||
444 | break; |
||
445 | |||
446 | case JSAPI_PROP_TINYID_onerror: |
||
447 | event_type_dom = corestring_dom_error; |
||
448 | break; |
||
449 | |||
450 | case JSAPI_PROP_TINYID_onfocus: |
||
451 | event_type_dom = corestring_dom_focus; |
||
452 | break; |
||
453 | |||
454 | case JSAPI_PROP_TINYID_oninput: |
||
455 | event_type_dom = corestring_dom_input; |
||
456 | break; |
||
457 | |||
458 | case JSAPI_PROP_TINYID_oninvalid: |
||
459 | event_type_dom = corestring_dom_invalid; |
||
460 | break; |
||
461 | |||
462 | case JSAPI_PROP_TINYID_onkeydown: |
||
463 | event_type_dom = corestring_dom_keydown; |
||
464 | break; |
||
465 | |||
466 | case JSAPI_PROP_TINYID_onkeypress: |
||
467 | event_type_dom = corestring_dom_keypress; |
||
468 | break; |
||
469 | |||
470 | case JSAPI_PROP_TINYID_onkeyup: |
||
471 | event_type_dom = corestring_dom_keyup; |
||
472 | break; |
||
473 | |||
474 | case JSAPI_PROP_TINYID_onload: |
||
475 | event_type_dom = corestring_dom_load; |
||
476 | break; |
||
477 | |||
478 | case JSAPI_PROP_TINYID_onloadeddata: |
||
479 | event_type_dom = corestring_dom_loadeddata; |
||
480 | break; |
||
481 | |||
482 | case JSAPI_PROP_TINYID_onloadedmetadata: |
||
483 | event_type_dom = corestring_dom_loadedmetadata; |
||
484 | break; |
||
485 | |||
486 | case JSAPI_PROP_TINYID_onloadstart: |
||
487 | event_type_dom = corestring_dom_loadstart; |
||
488 | break; |
||
489 | |||
490 | case JSAPI_PROP_TINYID_onmousedown: |
||
491 | event_type_dom = corestring_dom_mousedown; |
||
492 | break; |
||
493 | |||
494 | case JSAPI_PROP_TINYID_onmousemove: |
||
495 | event_type_dom = corestring_dom_mousemove; |
||
496 | break; |
||
497 | |||
498 | case JSAPI_PROP_TINYID_onmouseout: |
||
499 | event_type_dom = corestring_dom_mouseout; |
||
500 | break; |
||
501 | |||
502 | case JSAPI_PROP_TINYID_onmouseover: |
||
503 | event_type_dom = corestring_dom_mouseover; |
||
504 | break; |
||
505 | |||
506 | case JSAPI_PROP_TINYID_onmouseup: |
||
507 | event_type_dom = corestring_dom_mouseup; |
||
508 | break; |
||
509 | |||
510 | case JSAPI_PROP_TINYID_onmousewheel: |
||
511 | event_type_dom = corestring_dom_mousewheel; |
||
512 | break; |
||
513 | |||
514 | case JSAPI_PROP_TINYID_onpause: |
||
515 | event_type_dom = corestring_dom_pause; |
||
516 | break; |
||
517 | |||
518 | case JSAPI_PROP_TINYID_onplay: |
||
519 | event_type_dom = corestring_dom_play; |
||
520 | break; |
||
521 | |||
522 | case JSAPI_PROP_TINYID_onplaying: |
||
523 | event_type_dom = corestring_dom_playing; |
||
524 | break; |
||
525 | |||
526 | case JSAPI_PROP_TINYID_onprogress: |
||
527 | event_type_dom = corestring_dom_progress; |
||
528 | break; |
||
529 | |||
530 | case JSAPI_PROP_TINYID_onratechange: |
||
531 | event_type_dom = corestring_dom_ratechange; |
||
532 | break; |
||
533 | |||
534 | case JSAPI_PROP_TINYID_onreset: |
||
535 | event_type_dom = corestring_dom_reset; |
||
536 | break; |
||
537 | |||
538 | case JSAPI_PROP_TINYID_onscroll: |
||
539 | event_type_dom = corestring_dom_scroll; |
||
540 | break; |
||
541 | |||
542 | case JSAPI_PROP_TINYID_onseeked: |
||
543 | event_type_dom = corestring_dom_seeked; |
||
544 | break; |
||
545 | |||
546 | case JSAPI_PROP_TINYID_onseeking: |
||
547 | event_type_dom = corestring_dom_seeking; |
||
548 | break; |
||
549 | |||
550 | case JSAPI_PROP_TINYID_onselect: |
||
551 | event_type_dom = corestring_dom_select; |
||
552 | break; |
||
553 | |||
554 | case JSAPI_PROP_TINYID_onshow: |
||
555 | event_type_dom = corestring_dom_show; |
||
556 | break; |
||
557 | |||
558 | case JSAPI_PROP_TINYID_onstalled: |
||
559 | event_type_dom = corestring_dom_stalled; |
||
560 | break; |
||
561 | |||
562 | case JSAPI_PROP_TINYID_onsubmit: |
||
563 | event_type_dom = corestring_dom_submit; |
||
564 | break; |
||
565 | |||
566 | case JSAPI_PROP_TINYID_onsuspend: |
||
567 | event_type_dom = corestring_dom_suspend; |
||
568 | break; |
||
569 | |||
570 | case JSAPI_PROP_TINYID_ontimeupdate: |
||
571 | event_type_dom = corestring_dom_timeupdate; |
||
572 | break; |
||
573 | |||
574 | case JSAPI_PROP_TINYID_onvolumechange: |
||
575 | event_type_dom = corestring_dom_volumechange; |
||
576 | break; |
||
577 | |||
578 | case JSAPI_PROP_TINYID_onwaiting: |
||
579 | event_type_dom = corestring_dom_waiting; |
||
580 | break; |
||
581 | |||
582 | case JSAPI_PROP_TINYID_onreadystatechange: |
||
583 | event_type_dom = corestring_dom_readystatechange; |
||
584 | break; |
||
585 | |||
586 | default: |
||
587 | JSLOG("called with unknown tinyid"); |
||
588 | return JS_TRUE; |
||
589 | } |
||
590 | |||
591 | js_dom_event_add_listener((struct jscontext *)cx, |
||
592 | private->node, |
||
593 | (dom_node *)private->node, |
||
594 | event_type_dom, |
||
595 | vp); |
||
596 | %} |