From ef1eb5b59df798dc9a3e8df93fe46500aa4244e9 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 26 Jul 2015 17:52:27 +0100 Subject: make the duktape libdom generator output initializers --- README | 229 +++++++++++++++++++-- src/duk-libdom.c | 326 +++++++++++++++++++++++++++--- src/nsgenbind-parser.y | 124 +++++++----- test/data/bindings/HTMLUnknownElement.bnd | 2 + test/data/bindings/browser-duk.bnd | 113 +++++++++-- 5 files changed, 691 insertions(+), 103 deletions(-) diff --git a/README b/README index 039bd6a..eb42c83 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -genjsbind +nsgenbind ========= -This is a tool to generate javascript to dom bindings from w3c webidl +This is a tool to generate JavaScript to DOM bindings from w3c webidl files and a binding configuration file. building @@ -16,7 +16,7 @@ nsgenbind [-v] [-g] [-D] [-W] [-I idlpath] inputfile outputdir -v The verbose switch makes the tool verbose about what operations it is -performing instead of teh default of only reporting errors. +performing instead of the default of only reporting errors. -g The generated code will be augmented with runtime debug logging so it @@ -40,15 +40,15 @@ which to place its output. Debug output ------------ -as well as the generated source the tool will output seevral debugging -files with the -D switch in use. +In addition to the generated source the tool will output several + debugging files with the -D switch in use. interface.dot The interfaces IDL dot file contains all the interfaces and their relationship. graphviz can be used to convert this into a visual representation which is sometimes useful to help in debugging - missing or incorrect IDL inheritance. + missing or incorrect interface inheritance. Processing the dot file with graphviz can produce very large files so care must be taken with options. Some examples that produce @@ -65,17 +65,17 @@ Web IDL ------- The IDL is specified in a w3c document[1] but the second edition is in -draft[2] and covers many of the features actually used in the whatwg -dom and html spec. + draft[2] and covers many of the features actually used in the whatwg + dom and HTML spec. The principal usage of the IDL is to define the interface between -scripts and a browsers internal state. For example the DOM[3] and -HTML[4] specs contain all the IDL for acessing the DOM and interacting -with a web browser (this not strictly true as there are several -interfaces simply not in the standards such as console). + scripts and a browsers internal state. For example the DOM[3] and + HTML[4] specs contain all the IDL for accessing the DOM and interacting + with a web browser (this not strictly true as there are several + interfaces simply not in the standards such as console). The IDL uses some slightly strange names than other object orientated -systems. + systems. IDL | JS | OOP | Notes -----------+------------------+----------------+---------------------------- @@ -88,6 +88,209 @@ systems. attribute | property | property | Variables set per instance -----------+------------------+----------------+---------------------------- + +Binding file +------------ + +The binding file controls how the code generator constructs its +output. It is deliberately similar to c++ in syntax and uses OOP +nomenclature to describe the annotations (class, method, etc. instead +of interface, operation, etc.) + +The binding file consists of three types of element: + + binding + + The binding element has an identifier controlling which type of + output is produced (currently duk_libdom and jsapi_libdom). + + The binding block may contain one or more directives which + control overall generation behaviour: + + webidl + + This takes a quoted string which identifies a WebIDL file to + process. There may be many of these directives as required + but without at least one the binding is not very useful as + it will generate no output. + + preface + + This takes a cdata block. There may only be one of these per + binding, subsequent directives will be ignored. + + The preface is emitted in every generated source file before + any other output and generally is used for copyright + comments and similar. It is immediately followed by the + binding tools preamble comments. + + prologue + + This takes a cdata block. There may only be one of these per + binding, subsequent directives will be ignored. + + The prologue is emitted in every generated source file after + the class preface has been generated. It is often used for + include directives required across all modules. + + epilogue + + This takes a cdata block. There may only be one of these per + binding, subsequent directives will be ignored. + + The epilogue is emitted after the generated code and the + class epilogue + + postface + + This takes a cdata block. There may only be one of these per + binding, subsequent directives will be ignored. + + The postface is emitted as the very last element of the + generated source files. + + + class + + The class controls the generation of source for an IDL interface + private member variables are declared here and header and + footer elements specific to this class. + + private + + variables added to the private structure for the class. + + preface + + This takes a cdata block. There may only be one of these per + class, subsequent directives will be ignored. + + The preface is emitted in every generated source file after + the binding preface and tool preamble. + + prologue + + This takes a cdata block. There may only be one of these per + class, subsequent directives will be ignored. + + The prologue is emitted in every generated source file after + the binding prologue has been generated. + + epilogue + + This takes a cdata block. There may only be one of these per + class, subsequent directives will be ignored. + + The epilogue is emitted after the generated code and before + the binding epilogue + + postface + + This takes a cdata block. There may only be one of these per + class, subsequent directives will be ignored. + + The postface is emitted after the binding epilogue. + + + methods + + The methods allow a binding to provide code to be inserted in + the output and to control the class initializer and finalizer + (note not the constructor/destructor) + + All these are in the syntax of: + + methodtype declarator ( parameters ) + + They may optionally be followed by a cdata block which will be + added to the appropriate method in the output. A semicolon may + be used instead of the cdata block but this is not obviously + useful except in the case of the init type. + + methods and getters/setters for properties must specify both + class and name using the c++ style double colon separated + identifiers i.e. class::identifier + + Note: the class names must match the IDL interface names in the + binding but they will almost certainly have to be translated + into more suitable class names for generated output. + + init + + The declarator for this method type need only identify the + class (an identifier may be provided but will be ignored). + + TODO: should it become necessary to defeat the automated + generation of an initializer altogether the identifier can + be checked and if set to the class name (like a + constructor) output body simply becomes a verbatim copy of + the cdata block. + + The parameter list may be empty or contain type/identifier + tuples. If there is a parent interface it will be called + with the parameters necessary for its initializer, hence the + entire ancestry will be initialised. + + The parameters passed to the parent are identified by + matching the identifier with the parents initializer + parameter identifier, if the type does not match a type + cast is inserted. + + It is sometimes desirable for the parent initializer + identifier to be different from the childs identifier. In + this case the identifier may have an alias added by having + a double colon followed by a second identifier. + + For example consider the case below where HTMLElement + inherits from Element which inherits from Node. + + init Node("struct dom_node *" node); + init Element("struct dom_element *" element::node); + init HTMLElement("struct dom_html_element *" html_element::element); + + The three initializers have parameters with different + identifiers but specify the identifier as it appears in + their parents parameter list. This allows for differing + parameter ordering and identifier naming while allowing the + automated enforcement of correct initializer calling + chains. + + + fini + + The declarator for this method type need only identify the + class (an identifier may be provided but will be ignored). + + The cdata block is output. + + The parent finalizer is called (finalizers have no parameters + so do not need the complexity of initializers. + + method + + The declarator for this method type must contain both the + class and the identifier. + + The cdata block is output. + + getter + + The declarator for this method type must contain both the + class and the identifier. + + The cdata block is output. + + setter + + The declarator for this method type must contain both the + class and the identifier. + + The cdata block is output. + + +References +---------- + [1] http://www.w3.org/TR/WebIDL/ [2] https://heycam.github.io/webidl/ [3] https://dom.spec.whatwg.org/ diff --git a/src/duk-libdom.c b/src/duk-libdom.c index 4d8ecf5..ee45eaf 100644 --- a/src/duk-libdom.c +++ b/src/duk-libdom.c @@ -22,6 +22,9 @@ #include "interface-map.h" #include "duk-libdom.h" +/** prefix for all generated functions */ +#define DLPFX "duckky" + #define NSGENBIND_PREAMBLE \ "/* Generated by nsgenbind\n" \ " *\n" \ @@ -94,6 +97,40 @@ static char *gen_class_name(struct interface_map_entry *interfacee) return name; } +/** + * find method by type on class + */ +static struct genbind_node * +find_class_method(struct genbind_node *node, + struct genbind_node *prev, + enum genbind_node_type nodetype) +{ + struct genbind_node *res_node; + + res_node = genbind_node_find_type( + genbind_node_getnode(node), + prev, GENBIND_NODE_TYPE_METHOD); + while (res_node != NULL) { + struct genbind_node *type_node; + enum genbind_node_type *type; + + type_node = genbind_node_find_type( + genbind_node_getnode(res_node), + NULL, GENBIND_NODE_TYPE_METHOD_TYPE); + + type = (enum genbind_node_type *)genbind_node_getint(type_node); + if (*type == nodetype) { + break; + } + + res_node = genbind_node_find_type( + genbind_node_getnode(node), + res_node, GENBIND_NODE_TYPE_METHOD); + } + + return res_node; +} + /** * output character data of node of given type. * @@ -110,19 +147,258 @@ output_cdata(FILE* outf, genbind_node_getnode(node), NULL, nodetype)); if (cdata != NULL) { - fprintf(outf, "%s\n", cdata); + fprintf(outf, "%s", cdata); + } + return 0; +} + +/** + * Output code to create a private structure + * + */ +static int output_duckky_create_private(FILE* outf, char *class_name) +{ + fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n", + class_name); + fprintf(outf, "\tif (priv == NULL) return 0;\n"); + fprintf(outf, "\tduk_push_pointer(ctx, priv);\n"); + fprintf(outf, "\tduk_put_prop_string(ctx, 0, PRIVATE_MAGIC)\n\n"); + + return 0; +} + +/** + * generate code that gets a private pointer + */ +static int output_ducky_safe_get_private(FILE* outf, char *class_name, int idx) +{ + fprintf(outf, + "\t%s_private_t *priv = dukky_get_private(ctx, %d);\n", + class_name, idx); + fprintf(outf, "\tif (priv == NULL) return 0;\n\n"); + return 0; +} + + +/** + * generate the interface constructor + */ +static int +output_interface_constructor(FILE* outf, struct interface_map_entry *interfacee) +{ + /* constructor definition */ + fprintf(outf, + "duk_ret_t %s_%s___constructor(duk_context *ctx)\n", + DLPFX, interfacee->class_name); + fprintf(outf,"{\n"); + + output_duckky_create_private(outf, interfacee->class_name); + + /* generate call to initialisor */ + fprintf(outf, + "\t%s_%s___init(ctx, priv, duk_get_pointer(ctx, 1));\n", + DLPFX, interfacee->class_name); + + fprintf(outf, "\tduk_set_top(ctx, 1);\n"); + fprintf(outf, "\treturn 1;\n"); + + fprintf(outf, "}\n\n"); + + return 0; +} + +/** + * generate the interface destructor + */ +static int +output_interface_destructor(FILE* outf, struct interface_map_entry *interfacee) +{ + /* destructor definition */ + fprintf(outf, + "duk_ret_t %s_%s___destructor(duk_context *ctx)\n", + DLPFX, interfacee->class_name); + fprintf(outf,"{\n"); + + output_ducky_safe_get_private(outf, interfacee->class_name, 0); + + /* generate call to finaliser */ + fprintf(outf, + "\t%s_%s___fini(ctx, priv);\n", + DLPFX, interfacee->class_name); + + fprintf(outf,"\tfree(priv);\n"); + fprintf(outf,"\treturn 0;\n"); + + fprintf(outf, "}\n\n"); + + return 0; +} + +/** + * generate an initialisor call to parent interface + */ +static int +output_interface_inherit_init(FILE* outf, + struct interface_map_entry *interfacee, + struct interface_map_entry *inherite) +{ + struct genbind_node *init_node; + struct genbind_node *inh_init_node; + struct genbind_node *param_node; + struct genbind_node *inh_param_node; + + /* only need to call parent initialisor if there is one */ + if (inherite == NULL) { + return 0; } + + /* find the initialisor method on the class (if any) */ + init_node = find_class_method(interfacee->class, + NULL, + GENBIND_METHOD_TYPE_INIT); + + + inh_init_node = find_class_method(inherite->class, + NULL, + GENBIND_METHOD_TYPE_INIT); + + + + fprintf(outf, "\t%s_%s___init(ctx, &priv->parent", + DLPFX, inherite->class_name); + + /* for each parameter in the parent find a matching named + * parameter to pass and cast if necessary + */ + + inh_param_node = genbind_node_find_type( + genbind_node_getnode(inh_init_node), + NULL, GENBIND_NODE_TYPE_PARAMETER); + while (inh_param_node != NULL) { + char *param_name; + param_name = genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode(inh_param_node), + NULL, + GENBIND_NODE_TYPE_IDENT)); + + param_node = genbind_node_find_type_ident( + genbind_node_getnode(init_node), + NULL, + GENBIND_NODE_TYPE_PARAMETER, + param_name); + if (param_node == NULL) { + fprintf(stderr, "class \"%s\" (interface %s) parent class \"%s\" (interface %s) initialisor requires a parameter \"%s\" with compatible identifier\n", + interfacee->class_name, + interfacee->name, + inherite->class_name, + inherite->name, + param_name); + return -1; + } else { + char *param_type; + char *inh_param_type; + + fprintf(outf, ", "); + + /* cast the parameter if required */ + param_type = genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode(param_node), + NULL, + GENBIND_NODE_TYPE_TYPE)); + + inh_param_type = genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode(inh_param_node), + NULL, + GENBIND_NODE_TYPE_TYPE)); + + if (strcmp(param_type, inh_param_type) != 0) { + fprintf(outf, "(%s)", inh_param_type); + } + + /* output the parameter identifier */ + output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT); + } + + inh_param_node = genbind_node_find_type( + genbind_node_getnode(inh_init_node), + inh_param_node, GENBIND_NODE_TYPE_METHOD); + } + + fprintf(outf, ");\n"); + return 0; } +static int +output_interface_init(FILE* outf, + struct interface_map_entry *interfacee, + struct interface_map_entry *inherite) +{ + struct genbind_node *init_node; + struct genbind_node *param_node; + int res; + + /* find the initialisor method on the class (if any) */ + init_node = find_class_method(interfacee->class, + NULL, + GENBIND_METHOD_TYPE_INIT); + + /* initialisor definition */ + fprintf(outf, + "void %s_%s___init(duk_context *ctx, %s_private_t *priv", + DLPFX, interfacee->class_name, interfacee->class_name); + + /* output the paramters on the method (if any) */ + param_node = genbind_node_find_type( + genbind_node_getnode(init_node), + NULL, GENBIND_NODE_TYPE_PARAMETER); + while (param_node != NULL) { + fprintf(outf, ", "); + output_cdata(outf, param_node, GENBIND_NODE_TYPE_TYPE); + output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT); + + param_node = genbind_node_find_type( + genbind_node_getnode(init_node), + param_node, GENBIND_NODE_TYPE_METHOD); + } + + fprintf(outf,")\n{\n"); + + /* if this interface inherits ensure we call its initialisor */ + res = output_interface_inherit_init(outf, interfacee, inherite); + if (res != 0) { + return res; + } + + /* generate log statement */ + if (options->dbglog) { + fprintf(outf, + "\tLOG(\"Initialise %%p (priv=%%p)\", duk_get_heapptr(ctx, 0), priv);\n" ); + } + + /* output the initaliser code from the binding */ + output_cdata(outf, init_node, GENBIND_NODE_TYPE_CDATA); + + fprintf(outf, "}\n\n"); + + return 0; + +} + static int output_interface_fini(FILE* outf, struct interface_map_entry *interfacee, struct interface_map_entry *inherite) { struct genbind_node *fini_node; - struct genbind_node *type_node; - int *type; + + /* find the finaliser method on the class (if any) */ + fini_node = find_class_method(interfacee->class, + NULL, + GENBIND_METHOD_TYPE_FINI); /* finaliser definition */ fprintf(outf, @@ -136,24 +412,7 @@ output_interface_fini(FILE* outf, "\tLOG(\"Finalise %%p\", duk_get_heapptr(ctx, 0));\n" ); } - /* find the finaliser method on the class (if any) */ - fini_node = genbind_node_find_type( - genbind_node_getnode(interfacee->class), - NULL, GENBIND_NODE_TYPE_METHOD); - while (fini_node != NULL) { - type_node = genbind_node_find_type( - genbind_node_getnode(fini_node), - NULL, GENBIND_NODE_TYPE_METHOD_TYPE); - - type = genbind_node_getint(type_node); - if (*type == GENBIND_METHOD_TYPE_FINI) { - break; - } - - fini_node = genbind_node_find_type( - genbind_node_getnode(interfacee->class), - fini_node, GENBIND_NODE_TYPE_METHOD); - } + /* output the finialisor code from the binding */ output_cdata(outf, fini_node, GENBIND_NODE_TYPE_CDATA); /* if this interface inherits ensure we call its finaliser */ @@ -162,7 +421,7 @@ output_interface_fini(FILE* outf, "\tdukky_%s___fini(ctx, &priv->parent);\n", inherite->class_name); } - fprintf(outf, "}\n"); + fprintf(outf, "}\n\n"); return 0; } @@ -180,7 +439,9 @@ static int output_interface(struct genbind_node *genbind, int ifacenamelen; struct genbind_node *binding_node; struct interface_map_entry *inherite; + int res = 0; + /* compute clas name */ interfacee->class_name = gen_class_name(interfacee); /* generate source filename */ @@ -198,15 +459,15 @@ static int output_interface(struct genbind_node *genbind, /* find parent interface entry */ inherite = interface_map_inherit_entry(interface_map, interfacee); - /* nsgenbind preamble */ - fprintf(ifacef, "%s\n", NSGENBIND_PREAMBLE); - binding_node = genbind_node_find_type(genbind, NULL, GENBIND_NODE_TYPE_BINDING); /* binding preface */ output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE); + /* nsgenbind preamble */ + fprintf(ifacef, "\n%s\n", NSGENBIND_PREAMBLE); + /* class preface */ output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE); @@ -216,14 +477,24 @@ static int output_interface(struct genbind_node *genbind, /* class prologue */ output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PROLOGUE); + fprintf(ifacef, "\n"); + /* initialisor */ - //output_interface_init(); + res = output_interface_init(ifacef, interfacee, inherite); + if (res != 0) { + goto op_error; + } /* finaliser */ output_interface_fini(ifacef, interfacee, inherite); /* constructor */ + output_interface_constructor(ifacef, interfacee); + /* destructor */ + output_interface_destructor(ifacef, interfacee); + + fprintf(ifacef, "\n"); /* class epilogue */ output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_EPILOGUE); @@ -237,9 +508,10 @@ static int output_interface(struct genbind_node *genbind, /* binding postface */ output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_POSTFACE); +op_error: fclose(ifacef); - return 0; + return res; } int duk_libdom_output(struct genbind_node *genbind, diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y index 454fb56..456decb 100644 --- a/src/nsgenbind-parser.y +++ b/src/nsgenbind-parser.y @@ -32,6 +32,65 @@ static void nsgenbind_error(YYLTYPE *locp, errtxt = strdup(str); } +static struct genbind_node * +add_method(struct genbind_node **genbind_ast, + long methodtype, + struct genbind_node *declarator, + char *cdata) +{ + struct genbind_node *res_node; + struct genbind_node *method_node; + struct genbind_node *class_node; + struct genbind_node *cdata_node; + char *class_name; + + /* extract the class name from the declarator */ + class_name = genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode( + genbind_node_find_type( + declarator, + NULL, + GENBIND_NODE_TYPE_CLASS)), + NULL, + GENBIND_NODE_TYPE_IDENT)); + + if (cdata == NULL) { + cdata_node = declarator; + } else { + cdata_node = genbind_new_node(GENBIND_NODE_TYPE_CDATA, + declarator, + cdata); + } + + /* generate method node */ + method_node = genbind_new_node(GENBIND_NODE_TYPE_METHOD, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE, + cdata_node, + (void *)methodtype)); + + class_node = genbind_node_find_type_ident(*genbind_ast, + NULL, + GENBIND_NODE_TYPE_CLASS, + class_name); + if (class_node == NULL) { + /* no existing class so manufacture one and attach method */ + res_node = genbind_new_node(GENBIND_NODE_TYPE_CLASS, NULL, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, + method_node, + class_name)); + + } else { + /* update the existing class */ + + /* link member node into class_node */ + genbind_node_add(class_node, method_node); + + res_node = NULL; /* updating so no need to add a new node */ + } + return res_node; +} %} @@ -199,6 +258,17 @@ TypeIdent $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, genbind_new_node(GENBIND_NODE_TYPE_TYPE, NULL, $1), $2); } + | + TOK_STRING_LITERAL TOK_IDENTIFIER TOK_DBLCOLON TOK_IDENTIFIER + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_IDENT, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, + genbind_new_node(GENBIND_NODE_TYPE_TYPE, + NULL, + $1), + $2), + $4); + } ; Preface @@ -330,54 +400,14 @@ Method : MethodType MethodDeclarator CBlock { - struct genbind_node *declarator; - struct genbind_node *method_node; - struct genbind_node *class_node; - char *class_name; - - declarator = $2; - - /* extract the class name from the declarator */ - class_name = genbind_node_gettext( - genbind_node_find_type( - genbind_node_getnode( - genbind_node_find_type( - declarator, - NULL, - GENBIND_NODE_TYPE_CLASS)), - NULL, - GENBIND_NODE_TYPE_IDENT)); - - /* generate method node */ - method_node = genbind_new_node(GENBIND_NODE_TYPE_METHOD, NULL, - genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE, - genbind_new_node(GENBIND_NODE_TYPE_CDATA, - declarator, $3), - (void *)$1)); - - - - class_node = genbind_node_find_type_ident(*genbind_ast, - NULL, - GENBIND_NODE_TYPE_CLASS, - class_name); - if (class_node == NULL) { - /* no existing class so manufacture one and attach method */ - $$ = genbind_new_node(GENBIND_NODE_TYPE_CLASS, NULL, - genbind_new_node(GENBIND_NODE_TYPE_IDENT, - method_node, - class_name)); - - } else { - /* update the existing class */ - - /* link member node into class_node */ - genbind_node_add(class_node, method_node); - - $$ = NULL; /* updating so no need to add a new node */ - } + $$ = add_method(genbind_ast, $1, $2, $3); } - + | + MethodType MethodDeclarator ';' + { + $$ = add_method(genbind_ast, $1, $2, NULL); + } + ; Class : diff --git a/test/data/bindings/HTMLUnknownElement.bnd b/test/data/bindings/HTMLUnknownElement.bnd index 376a823..faabaec 100644 --- a/test/data/bindings/HTMLUnknownElement.bnd +++ b/test/data/bindings/HTMLUnknownElement.bnd @@ -15,3 +15,5 @@ class HTMLUnknownElement { /* class post */ %}; } + +init HTMLUnknownElement("struct dom_html_element *" html_unknown_element::html_element); diff --git a/test/data/bindings/browser-duk.bnd b/test/data/bindings/browser-duk.bnd index 273eae9..392f652 100644 --- a/test/data/bindings/browser-duk.bnd +++ b/test/data/bindings/browser-duk.bnd @@ -39,31 +39,112 @@ binding duk_libdom { #include "HTMLUnknownElement.bnd" +/* specialisations of html_element */ +init HTMLFontElement("struct dom_html_element *" html_font_element::html_element); +init HTMLDirectoryElement("struct dom_html_element *" html_directory_element::html_element); +init HTMLFrameElement("struct dom_html_element *" html_frame_element::html_element); +init HTMLFrameSetElement("struct dom_html_element *" html_frame_set_element::html_element); +init HTMLMarqueeElement("struct dom_html_element *" html_marquee_element::html_element); +init HTMLAppletElement("struct dom_html_element *" html_applet_element::html_element); +init HTMLCanvasElement("struct dom_html_element *" html_canvas_element::html_element); +init HTMLTemplateElement("struct dom_html_element *" html_template_element::html_element); +init HTMLScriptElement("struct dom_html_element *" html_script_element::html_element); +init HTMLDialogElement("struct dom_html_element *" html_dialog_element::html_element); +init HTMLMenuItemElement("struct dom_html_element *" html_menu_item_element::html_element); +init HTMLMenuElement("struct dom_html_element *" html_menu_element::html_element); +init HTMLDetailsElement("struct dom_html_element *" html_details_element::html_element); +init HTMLLegendElement("struct dom_html_element *" html_legend_element::html_element); +init HTMLFieldSetElement("struct dom_html_element *" html_field_set_element::html_element); +init HTMLMeterElement("struct dom_html_element *" html_meter_element::html_element); +init HTMLProgressElement("struct dom_html_element *" html_progress_element::html_element); +init HTMLOutputElement("struct dom_html_element *" html_output_element::html_element); +init HTMLKeygenElement("struct dom_html_element *" html_keygen_element::html_element); +init HTMLTextAreaElement("struct dom_html_element *" html_text_area_element::html_element); +init HTMLOptionElement("struct dom_html_element *" html_option_element::html_element); +init HTMLOptGroupElement("struct dom_html_element *" html_opt_group_element::html_element); +init HTMLDataListElement("struct dom_html_element *" html_data_list_element::html_element); +init HTMLSelectElement("struct dom_html_element *" html_select_element::html_element); +init HTMLButtonElement("struct dom_html_element *" html_button_element::html_element); +init HTMLInputElement("struct dom_html_element *" html_input_element::html_element); +init HTMLLabelElement("struct dom_html_element *" html_label_element::html_element); +init HTMLFormElement("struct dom_html_element *" html_form_element::html_element); +init HTMLTableCellElement("struct dom_html_element *" html_table_cell_element::html_element); +init HTMLTableRowElement("struct dom_html_element *" html_table_row_element::html_element); +init HTMLTableSectionElement("struct dom_html_element *" html_table_section_element::html_element); +init HTMLTableColElement("struct dom_html_element *" html_table_col_element::html_element); +init HTMLTableCaptionElement("struct dom_html_element *" html_table_caption_element::html_element); +init HTMLTableElement("struct dom_html_element *" html_table_element::html_element); +init HTMLAreaElement("struct dom_html_element *" html_area_element::html_element); +init HTMLMapElement("struct dom_html_element *" html_map_element::html_element); +init HTMLMediaElement("struct dom_html_element *" html_media_element::html_element); +init HTMLTrackElement("struct dom_html_element *" html_track_element::html_element); +init HTMLParamElement("struct dom_html_element *" html_param_element::html_element); +init HTMLObjectElement("struct dom_html_element *" html_object_element::html_element); +init HTMLEmbedElement("struct dom_html_element *" html_embed_element::html_element); +init HTMLIFrameElement("struct dom_html_element *" html_i_frame_element::html_element); +init HTMLImageElement("struct dom_html_element *" html_image_element::html_element); +init HTMLSourceElement("struct dom_html_element *" html_source_element::html_element); +init HTMLPictureElement("struct dom_html_element *" html_picture_element::html_element); +init HTMLModElement("struct dom_html_element *" html_mod_element::html_element); +init HTMLBRElement("struct dom_html_element *" html_br_element::html_element); +init HTMLSpanElement("struct dom_html_element *" html_span_element::html_element); +init HTMLTimeElement("struct dom_html_element *" html_time_element::html_element); +init HTMLDataElement("struct dom_html_element *" html_data_element::html_element); +init HTMLAnchorElement("struct dom_html_element *" html_anchor_element::html_element); +init HTMLDivElement("struct dom_html_element *" html_div_element::html_element); +init HTMLDListElement("struct dom_html_element *" html_d_list_element::html_element); +init HTMLLIElement("struct dom_html_element *" html_li_element::html_element); +init HTMLUListElement("struct dom_html_element *" html_u_list_element::html_element); +init HTMLOListElement("struct dom_html_element *" html_o_list_element::html_element); +init HTMLQuoteElement("struct dom_html_element *" html_quote_element::html_element); +init HTMLPreElement("struct dom_html_element *" html_pre_element::html_element); +init HTMLHRElement("struct dom_html_element *" html_hr_element::html_element); +init HTMLParagraphElement("struct dom_html_element *" html_paragraph_element::html_element); +init HTMLHeadingElement("struct dom_html_element *" html_heading_element::html_element); +init HTMLBodyElement("struct dom_html_element *" html_body_element::html_element); +init HTMLStyleElement("struct dom_html_element *" html_style_element::html_element); +init HTMLMetaElement("struct dom_html_element *" html_meta_element::html_element); +init HTMLLinkElement("struct dom_html_element *" html_link_element::html_element); +init HTMLBaseElement("struct dom_html_element *" html_base_element::html_element); +init HTMLTitleElement("struct dom_html_element *" html_title_element::html_element); +init HTMLHeadElement("struct dom_html_element *" html_head_element::html_element); +init HTMLHtmlElement("struct dom_html_element *" html_html_element::html_element); + +/* specialisations of HTMLTableCellElement */ +init HTMLTableHeaderCellElement("struct dom_html_element *" html_table_header_cell_element::html_table_cell_element); +init HTMLTableDataCellElement("struct dom_html_element *" html_table_data_cell_element::html_table_cell_element); + +/* specialisations of html_media_element */ +init HTMLAudioElement("struct dom_html_element *" html_audio_element::html_media_element); +init HTMLVideoElement("struct dom_html_element *" html_video_element::html_media_element); + +init HTMLElement("struct dom_html_element *" html_element::element); + +init Text("struct dom_node_text *" text::character_data); +init Comment("struct dom_node_comment *" comment::character_data); +init ProcessingInstruction("struct dom_node_text *" text::character_data); + +init XMLDocument("struct dom_document *" document); + +init Element("struct dom_element *" element::node); +init CharacterData("struct dom_node_character_data *" character_data::node); +init DocumentFragment("struct dom_document *" document::node); +init DocumentType("struct dom_document *" document::node); +init Document("struct dom_document *" document::node); + class Node { private "dom_node *" node; - - preface %{ - %}; - - prologue %{ - %}; - - epilogue %{ - %}; - - postface %{ - %}; } -init Node("dom_node *" node) +init Node("struct dom_node *" node) %{ - private->node = node; - dom_node_ref(node); + priv->node = node; + dom_node_ref(node); %} fini Node() %{ - dom_node_unref(private->node); + dom_node_unref(priv->node); %} method Node::AppendChild() -- cgit v1.2.3