1 /*
2  * This source file is part of libRocket, the HTML/CSS Interface Middleware
3  *
4  * For the latest information, see http://www.librocket.com
5  *
6  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 #include "precompiled.h"
29 #include "Element.h"
30 #include "ElementStyleProxy.h"
31 #include "LuaEventListener.h"
32 #include "ElementAttributesProxy.h"
33 #include "ElementChildNodesProxy.h"
34 #include <Rocket/Core/Lua/Utilities.h>
35 
36 
37 namespace Rocket {
38 namespace Core {
39 namespace Lua {
40 typedef ElementDocument Document;
41 
ExtraInit(lua_State * L,int metatable_index)42 template<> void ExtraInit<Element>(lua_State* L, int metatable_index)
43 {
44     int top = lua_gettop(L);
45     //guarantee the "Element.As" table exists
46     lua_getfield(L,metatable_index-1,"As");
47     if(lua_isnoneornil(L,-1)) //if it doesn't exist, create it
48     {
49         lua_newtable(L);
50         lua_setfield(L,metatable_index-1,"As");
51     }
52     lua_pop(L,1); //pop the result of lua_getfield
53     lua_pushcfunction(L,Elementnew);
54     lua_setfield(L,metatable_index-1,"new");
55     lua_settop(L,top);
56 }
57 
Elementnew(lua_State * L)58 int Elementnew(lua_State* L)
59 {
60     const char* tag = luaL_checkstring(L,1);
61     Element* ele = new Element(tag);
62     LuaType<Element>::push(L,ele,true);
63     ele->RemoveReference();
64     return 1;
65 }
66 
67 //methods
ElementAddEventListener(lua_State * L,Element * obj)68 int ElementAddEventListener(lua_State* L, Element* obj)
69 {
70     int top = lua_gettop(L);
71     bool capture = false;
72     //default false if they didn't pass it in
73     if (top > 2)
74 		capture = CHECK_BOOL(L,3);
75 
76     const char* event = luaL_checkstring(L,1);
77 
78     LuaEventListener* listener = NULL;
79     int type = lua_type(L,2);
80     if(type == LUA_TFUNCTION)
81     {
82         listener = new LuaEventListener(L, 2);
83     }
84     else if(type == LUA_TSTRING)
85     {
86         const char* code = luaL_checkstring(L,2);
87         listener = new LuaEventListener(code);
88     }
89 	else
90 	{
91 		Log::Message(Log::LT_WARNING, "Lua Context:AddEventLisener's 2nd argument can only be a Lua function or a string, you passed in a %s", lua_typename(L,type));
92 	}
93 
94     if(listener != NULL)
95     {
96         obj->AddEventListener(event,listener,capture);
97     }
98     return 0;
99 }
100 
ElementAppendChild(lua_State * L,Element * obj)101 int ElementAppendChild(lua_State* L, Element* obj)
102 {
103     Element* ele = LuaType<Element>::check(L,1);
104     obj->AppendChild(ele);
105     return 0;
106 }
107 
ElementBlur(lua_State * L,Element * obj)108 int ElementBlur(lua_State* L, Element* obj)
109 {
110     obj->Blur();
111     return 0;
112 }
113 
ElementClick(lua_State * L,Element * obj)114 int ElementClick(lua_State* L, Element* obj)
115 {
116     obj->Click();
117     return 0;
118 }
119 
ElementClone(lua_State * L,Element * obj)120 int ElementClone(lua_State* L, Element* obj) {
121 	auto el = obj->Clone();
122 	LuaType<Element>::push(L,el,true);
123 	el->RemoveReference();
124 	return 1;
125 }
126 
ElementDispatchEvent(lua_State * L,Element * obj)127 int ElementDispatchEvent(lua_State* L, Element* obj)
128 {
129     const char* event = luaL_checkstring(L,1);
130     Dictionary params;
131     lua_pushnil(L); //becauase lua_next pops a key from the stack first, we don't want to pop the table
132     while(lua_next(L,2) != 0)
133     {
134         //[-1] is value, [-2] is key
135         int type = lua_type(L,-1);
136         const char* key = luaL_checkstring(L,-2); //key HAS to be a string, or things will go bad
137         switch(type)
138         {
139 		case LUA_TNUMBER:
140             params.Set(key,(float)lua_tonumber(L,-1));
141             break;
142 		case LUA_TBOOLEAN:
143             params.Set(key,CHECK_BOOL(L,-1));
144             break;
145 		case LUA_TSTRING:
146             params.Set(key,luaL_checkstring(L,-1));
147             break;
148         case LUA_TUSERDATA:
149         case LUA_TLIGHTUSERDATA:
150             params.Set(key,lua_touserdata(L,-1));
151             break;
152         default:
153             break;
154         }
155     }
156     obj->DispatchEvent(event,params,false);
157     return 0;
158 }
159 
ElementFocus(lua_State * L,Element * obj)160 int ElementFocus(lua_State* L, Element* obj)
161 {
162     obj->Focus();
163     return 0;
164 }
165 
ElementGetAttribute(lua_State * L,Element * obj)166 int ElementGetAttribute(lua_State* L, Element* obj)
167 {
168     const char* name = luaL_checkstring(L,1);
169     Variant* var = obj->GetAttribute(name);
170     PushVariant(L,var);
171     return 1;
172 }
173 
ElementGetElementById(lua_State * L,Element * obj)174 int ElementGetElementById(lua_State* L, Element* obj)
175 {
176     const char* id = luaL_checkstring(L,1);
177     Element* ele = obj->GetElementById(id);
178     LuaType<Element>::push(L,ele,false);
179     return 1;
180 }
181 
ElementGetElementsByTagName(lua_State * L,Element * obj)182 int ElementGetElementsByTagName(lua_State* L, Element* obj)
183 {
184     const char* tag = luaL_checkstring(L,1);
185     ElementList list;
186     obj->GetElementsByTagName(list,tag);
187     lua_newtable(L);
188     for(unsigned int i = 0; i < list.size(); i++)
189     {
190         lua_pushinteger(L,i + 1);
191         LuaType<Element>::push(L,list[i],false);
192         lua_settable(L,-3); //-3 is the table
193     }
194     return 1;
195 }
196 
ElementGetElementsByClassName(lua_State * L,Element * obj)197 int ElementGetElementsByClassName(lua_State* L, Element* obj)
198 {
199     const char* class_name = luaL_checkstring(L,1);
200     ElementList list;
201     obj->GetElementsByClassName(list,class_name);
202     lua_newtable(L);
203     for(unsigned int i = 0; i < list.size(); i++)
204     {
205         lua_pushinteger(L,i + 1);
206         LuaType<Element>::push(L,list[i],false);
207         lua_settable(L,-3); //-3 is the table
208     }
209     return 1;
210 }
211 
ElementHasAttribute(lua_State * L,Element * obj)212 int ElementHasAttribute(lua_State* L, Element* obj)
213 {
214     const char* name = luaL_checkstring(L,1);
215     lua_pushboolean(L,obj->HasAttribute(name));
216     return 1;
217 }
218 
ElementHasChildNodes(lua_State * L,Element * obj)219 int ElementHasChildNodes(lua_State* L, Element* obj)
220 {
221     lua_pushboolean(L,obj->HasChildNodes());
222     return 1;
223 }
224 
ElementInsertBefore(lua_State * L,Element * obj)225 int ElementInsertBefore(lua_State* L, Element* obj)
226 {
227     Element* element = LuaType<Element>::check(L,1);
228     Element* adjacent = LuaType<Element>::check(L,2);
229     obj->InsertBefore(element,adjacent);
230     return 0;
231 }
232 
ElementIsClassSet(lua_State * L,Element * obj)233 int ElementIsClassSet(lua_State* L, Element* obj)
234 {
235     const char* name = luaL_checkstring(L,1);
236     lua_pushboolean(L,obj->IsClassSet(name));
237     return 1;
238 }
239 
ElementRemoveAttribute(lua_State * L,Element * obj)240 int ElementRemoveAttribute(lua_State* L, Element* obj)
241 {
242     const char* name = luaL_checkstring(L,1);
243     obj->RemoveAttribute(name);
244     return 0;
245 }
246 
ElementRemoveChild(lua_State * L,Element * obj)247 int ElementRemoveChild(lua_State* L, Element* obj)
248 {
249     Element* element = LuaType<Element>::check(L,1);
250     lua_pushboolean(L,obj->RemoveChild(element));
251     return 1;
252 }
253 
ElementReplaceChild(lua_State * L,Element * obj)254 int ElementReplaceChild(lua_State* L, Element* obj)
255 {
256     Element* inserted = LuaType<Element>::check(L,1);
257     Element* replaced = LuaType<Element>::check(L,2);
258     lua_pushboolean(L,obj->ReplaceChild(inserted,replaced));
259     return 1;
260 }
261 
ElementScrollIntoView(lua_State * L,Element * obj)262 int ElementScrollIntoView(lua_State* L, Element* obj)
263 {
264     bool align = CHECK_BOOL(L,1);
265     obj->ScrollIntoView(align);
266     return 0;
267 }
268 
ElementSetAttribute(lua_State * L,Element * obj)269 int ElementSetAttribute(lua_State* L, Element* obj)
270 {
271     const char* name = luaL_checkstring(L,1);
272     const char* value = luaL_checkstring(L,2);
273     obj->SetAttribute(name,String(value));
274     return 0;
275 }
276 
ElementSetClass(lua_State * L,Element * obj)277 int ElementSetClass(lua_State* L, Element* obj)
278 {
279     const char* name = luaL_checkstring(L,1);
280     bool value = CHECK_BOOL(L,2);
281     obj->SetClass(name,value);
282     return 0;
283 }
284 
ElementSetPseudoClass(lua_State * L,Element * obj)285 int ElementSetPseudoClass(lua_State* L, Element* obj)
286 {
287     const char* name = luaL_checkstring(L,1);
288     bool value = CHECK_BOOL(L,2);
289     obj->SetPseudoClass(name,value);
290     return 0;
291 }
292 
293 //getters
ElementGetAttrattributes(lua_State * L)294 int ElementGetAttrattributes(lua_State* L)
295 {
296     Element* ele = LuaType<Element>::check(L,1);
297     LUACHECKOBJ(ele);
298     ElementAttributesProxy* proxy = new ElementAttributesProxy();
299     proxy->owner = ele;
300     LuaType<ElementAttributesProxy>::push(L,proxy,true);
301     return 1;
302 }
303 
ElementGetAttrchild_nodes(lua_State * L)304 int ElementGetAttrchild_nodes(lua_State* L)
305 {
306     Element* ele = LuaType<Element>::check(L,1);
307     LUACHECKOBJ(ele);
308     ElementChildNodesProxy* ecnp = new ElementChildNodesProxy();
309     ecnp->owner = ele;
310     LuaType<ElementChildNodesProxy>::push(L,ecnp,true);
311     return 1;
312 }
313 
ElementGetAttrclass_name(lua_State * L)314 int ElementGetAttrclass_name(lua_State* L)
315 {
316     Element* ele = LuaType<Element>::check(L,1);
317     LUACHECKOBJ(ele);
318     const char* classnames = ele->GetClassNames().CString();
319     lua_pushstring(L,classnames);
320     return 1;
321 }
322 
ElementGetAttrclient_left(lua_State * L)323 int ElementGetAttrclient_left(lua_State* L)
324 {
325     Element* ele = LuaType<Element>::check(L,1);
326     LUACHECKOBJ(ele);
327     lua_pushnumber(L,ele->GetClientLeft());
328     return 1;
329 }
330 
ElementGetAttrclient_height(lua_State * L)331 int ElementGetAttrclient_height(lua_State* L)
332 {
333     Element* ele = LuaType<Element>::check(L,1);
334     LUACHECKOBJ(ele);
335     lua_pushnumber(L,ele->GetClientHeight());
336     return 1;
337 }
338 
ElementGetAttrclient_top(lua_State * L)339 int ElementGetAttrclient_top(lua_State* L)
340 {
341     Element* ele = LuaType<Element>::check(L,1);
342     LUACHECKOBJ(ele);
343     lua_pushnumber(L,ele->GetClientTop());
344     return 1;
345 }
346 
ElementGetAttrclient_width(lua_State * L)347 int ElementGetAttrclient_width(lua_State* L)
348 {
349     Element* ele = LuaType<Element>::check(L,1);
350     LUACHECKOBJ(ele);
351     lua_pushnumber(L,ele->GetClientWidth());
352     return 1;
353 }
354 
ElementGetAttrfirst_child(lua_State * L)355 int ElementGetAttrfirst_child(lua_State* L)
356 {
357     Element* ele = LuaType<Element>::check(L,1);
358     LUACHECKOBJ(ele);
359     Element* child = ele->GetFirstChild();
360     if(child == NULL)
361         lua_pushnil(L);
362     else
363         LuaType<Element>::push(L,child,false);
364     return 1;
365 }
366 
ElementGetAttrid(lua_State * L)367 int ElementGetAttrid(lua_State* L)
368 {
369     Element* ele = LuaType<Element>::check(L,1);
370     LUACHECKOBJ(ele);
371     lua_pushstring(L,ele->GetId().CString());
372     return 1;
373 }
374 
ElementGetAttrinner_rml(lua_State * L)375 int ElementGetAttrinner_rml(lua_State* L)
376 {
377     Element* ele = LuaType<Element>::check(L,1);
378     LUACHECKOBJ(ele);
379     lua_pushstring(L,ele->GetInnerRML().CString());
380     return 1;
381 }
382 
ElementGetAttrlast_child(lua_State * L)383 int ElementGetAttrlast_child(lua_State* L)
384 {
385     Element* ele = LuaType<Element>::check(L,1);
386     LUACHECKOBJ(ele);
387     Element* child = ele->GetLastChild();
388     if(child == NULL)
389         lua_pushnil(L);
390     else
391         LuaType<Element>::push(L,child,false);
392     return 1;
393 }
394 
ElementGetAttrnext_sibling(lua_State * L)395 int ElementGetAttrnext_sibling(lua_State* L)
396 {
397     Element* ele = LuaType<Element>::check(L,1);
398     LUACHECKOBJ(ele);
399     Element* sibling = ele->GetNextSibling();
400     if(sibling == NULL)
401         lua_pushnil(L);
402     else
403         LuaType<Element>::push(L,sibling,false);
404     return 1;
405 }
406 
ElementGetAttroffset_height(lua_State * L)407 int ElementGetAttroffset_height(lua_State* L)
408 {
409     Element* ele = LuaType<Element>::check(L,1);
410     LUACHECKOBJ(ele);
411     lua_pushnumber(L,ele->GetOffsetHeight());
412     return 1;
413 }
414 
ElementGetAttroffset_left(lua_State * L)415 int ElementGetAttroffset_left(lua_State* L)
416 {
417     Element* ele = LuaType<Element>::check(L,1);
418     LUACHECKOBJ(ele);
419     lua_pushnumber(L,ele->GetOffsetLeft());
420     return 1;
421 }
422 
ElementGetAttroffset_parent(lua_State * L)423 int ElementGetAttroffset_parent(lua_State* L)
424 {
425     Element* ele = LuaType<Element>::check(L,1);
426     LUACHECKOBJ(ele);
427     Element* parent = ele->GetOffsetParent();
428     LuaType<Element>::push(L,parent,false);
429     return 1;
430 }
431 
ElementGetAttroffset_top(lua_State * L)432 int ElementGetAttroffset_top(lua_State* L)
433 {
434     Element* ele = LuaType<Element>::check(L,1);
435     LUACHECKOBJ(ele);
436     lua_pushnumber(L, ele->GetOffsetTop());
437     return 1;
438 }
439 
ElementGetAttroffset_width(lua_State * L)440 int ElementGetAttroffset_width(lua_State* L)
441 {
442     Element* ele = LuaType<Element>::check(L,1);
443     LUACHECKOBJ(ele);
444     lua_pushnumber(L,ele->GetOffsetWidth());
445     return 1;
446 }
447 
ElementGetAttrowner_document(lua_State * L)448 int ElementGetAttrowner_document(lua_State* L)
449 {
450     Element* ele = LuaType<Element>::check(L,1);
451     LUACHECKOBJ(ele);
452     Document* doc = ele->GetOwnerDocument();
453     LuaType<Document>::push(L,doc,false);
454     return 1;
455 }
456 
ElementGetAttrparent_node(lua_State * L)457 int ElementGetAttrparent_node(lua_State* L)
458 {
459     Element* ele = LuaType<Element>::check(L,1);
460     LUACHECKOBJ(ele);
461     Element* parent = ele->GetParentNode();
462     if(parent == NULL)
463         lua_pushnil(L);
464     else
465         LuaType<Element>::push(L,parent,false);
466     return 1;
467 }
468 
ElementGetAttrprevious_sibling(lua_State * L)469 int ElementGetAttrprevious_sibling(lua_State* L)
470 {
471     Element* ele = LuaType<Element>::check(L,1);
472     LUACHECKOBJ(ele);
473     Element* sibling = ele->GetPreviousSibling();
474     if(sibling == NULL)
475         lua_pushnil(L);
476     else
477         LuaType<Element>::push(L,sibling,false);
478     return 1;
479 }
480 
ElementGetAttrscroll_height(lua_State * L)481 int ElementGetAttrscroll_height(lua_State* L)
482 {
483     Element* ele = LuaType<Element>::check(L,1);
484     LUACHECKOBJ(ele);
485     lua_pushnumber(L,ele->GetScrollHeight());
486     return 1;
487 }
488 
ElementGetAttrscroll_left(lua_State * L)489 int ElementGetAttrscroll_left(lua_State* L)
490 {
491     Element* ele = LuaType<Element>::check(L,1);
492     LUACHECKOBJ(ele);
493     lua_pushnumber(L,ele->GetScrollLeft());
494     return 1;
495 }
496 
ElementGetAttrscroll_top(lua_State * L)497 int ElementGetAttrscroll_top(lua_State* L)
498 {
499     Element* ele = LuaType<Element>::check(L,1);
500     LUACHECKOBJ(ele);
501     lua_pushnumber(L,ele->GetScrollTop());
502     return 1;
503 }
504 
ElementGetAttrscroll_width(lua_State * L)505 int ElementGetAttrscroll_width(lua_State* L)
506 {
507     Element* ele = LuaType<Element>::check(L,1);
508     LUACHECKOBJ(ele);
509     lua_pushnumber(L,ele->GetScrollWidth());
510     return 1;
511 }
512 
ElementGetAttrstyle(lua_State * L)513 int ElementGetAttrstyle(lua_State* L)
514 {
515     Element* ele = LuaType<Element>::check(L,1);
516     LUACHECKOBJ(ele);
517     ElementStyleProxy* prox = new ElementStyleProxy();
518     prox->owner = ele;
519     LuaType<ElementStyleProxy>::push(L,prox,true);
520     return 1;
521 }
522 
ElementGetAttrtag_name(lua_State * L)523 int ElementGetAttrtag_name(lua_State* L)
524 {
525     Element* ele = LuaType<Element>::check(L,1);
526     LUACHECKOBJ(ele);
527     lua_pushstring(L,ele->GetTagName().CString());
528     return 1;
529 }
530 
531 
532 //setters
ElementSetAttrclass_name(lua_State * L)533 int ElementSetAttrclass_name(lua_State* L)
534 {
535     Element* ele = LuaType<Element>::check(L,1);
536     LUACHECKOBJ(ele);
537     const char* name = luaL_checkstring(L,2);
538     ele->SetClassNames(name);
539     return 0;
540 }
541 
ElementSetAttrid(lua_State * L)542 int ElementSetAttrid(lua_State* L)
543 {
544     Element* ele = LuaType<Element>::check(L,1);
545     LUACHECKOBJ(ele);
546     const char* id = luaL_checkstring(L,2);
547     ele->SetId(id);
548     return 0;
549 }
550 
ElementSetAttrinner_rml(lua_State * L)551 int ElementSetAttrinner_rml(lua_State* L)
552 {
553     Element* ele = LuaType<Element>::check(L,1);
554     LUACHECKOBJ(ele);
555     const char* rml = luaL_checkstring(L,2);
556     ele->SetInnerRML(rml);
557     return 0;
558 }
559 
ElementSetAttrscroll_left(lua_State * L)560 int ElementSetAttrscroll_left(lua_State* L)
561 {
562     Element* ele = LuaType<Element>::check(L,1);
563     LUACHECKOBJ(ele);
564     float scroll = (float)luaL_checknumber(L,2);
565     ele->SetScrollLeft(scroll);
566     return 0;
567 }
568 
ElementSetAttrscroll_top(lua_State * L)569 int ElementSetAttrscroll_top(lua_State* L)
570 {
571     Element* ele = LuaType<Element>::check(L,1);
572     LUACHECKOBJ(ele);
573     float scroll = (float)luaL_checknumber(L,2);
574     ele->SetScrollTop(scroll);
575     return 0;
576 }
577 
578 
579 
580 
581 RegType<Element> ElementMethods[] =
582 {
583     LUAMETHOD(Element,AddEventListener)
584     LUAMETHOD(Element,AppendChild)
585     LUAMETHOD(Element,Blur)
586     LUAMETHOD(Element,Click)
587     LUAMETHOD(Element,Clone)
588     LUAMETHOD(Element,DispatchEvent)
589     LUAMETHOD(Element,Focus)
590     LUAMETHOD(Element,GetAttribute)
591     LUAMETHOD(Element,GetElementById)
592     LUAMETHOD(Element,GetElementsByTagName)
593     LUAMETHOD(Element,GetElementsByClassName)
594     LUAMETHOD(Element,HasAttribute)
595     LUAMETHOD(Element,HasChildNodes)
596     LUAMETHOD(Element,InsertBefore)
597     LUAMETHOD(Element,IsClassSet)
598     LUAMETHOD(Element,RemoveAttribute)
599     LUAMETHOD(Element,RemoveChild)
600     LUAMETHOD(Element,ReplaceChild)
601     LUAMETHOD(Element,ScrollIntoView)
602     LUAMETHOD(Element,SetAttribute)
603     LUAMETHOD(Element,SetClass)
604     LUAMETHOD(Element,SetPseudoClass)
605     { NULL, NULL },
606 };
607 
608 luaL_Reg ElementGetters[] =
609 {
610     LUAGETTER(Element,attributes)
611     LUAGETTER(Element,child_nodes)
612     LUAGETTER(Element,class_name)
613     LUAGETTER(Element,client_left)
614     LUAGETTER(Element,client_height)
615     LUAGETTER(Element,client_top)
616     LUAGETTER(Element,client_width)
617     LUAGETTER(Element,first_child)
618     LUAGETTER(Element,id)
619     LUAGETTER(Element,inner_rml)
620     LUAGETTER(Element,last_child)
621     LUAGETTER(Element,next_sibling)
622     LUAGETTER(Element,offset_height)
623     LUAGETTER(Element,offset_left)
624     LUAGETTER(Element,offset_parent)
625     LUAGETTER(Element,offset_top)
626     LUAGETTER(Element,offset_width)
627     LUAGETTER(Element,owner_document)
628     LUAGETTER(Element,parent_node)
629     LUAGETTER(Element,previous_sibling)
630     LUAGETTER(Element,scroll_height)
631     LUAGETTER(Element,scroll_left)
632     LUAGETTER(Element,scroll_top)
633     LUAGETTER(Element,scroll_width)
634     LUAGETTER(Element,style)
635     LUAGETTER(Element,tag_name)
636     { NULL, NULL },
637 };
638 
639 luaL_Reg ElementSetters[] =
640 {
641     LUASETTER(Element,class_name)
642     LUASETTER(Element,id)
643     LUASETTER(Element,inner_rml)
644     LUASETTER(Element,scroll_left)
645     LUASETTER(Element,scroll_top)
646     { NULL, NULL },
647 };
648 
649 LUACORETYPEDEFINE(Element,true)
650 }
651 }
652 }
653