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