Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* Binding to generate HTMLdocument interface
  2.  *
  3.  * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
  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 <vince@netsurf-browser.org>";
  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 <dom/dom.h>
  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. %}
  597.