2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
26 #include "swfdec_xml_node.h"
27 #include "swfdec_xml.h"
28 #include "swfdec_as_array.h"
29 #include "swfdec_as_native_function.h"
30 #include "swfdec_as_object.h"
31 #include "swfdec_as_strings.h"
32 #include "swfdec_debug.h"
33 #include "swfdec_internal.h"
34 #include "swfdec_as_internal.h"
35 #include "swfdec_load_object.h"
36 #include "swfdec_player_internal.h"
38 G_DEFINE_TYPE (SwfdecXmlNode
, swfdec_xml_node
, SWFDEC_TYPE_AS_OBJECT
)
41 swfdec_xml_node_do_mark (SwfdecAsObject
*object
)
43 SwfdecXmlNode
*node
= SWFDEC_XML_NODE (object
);
45 if (node
->name
!= NULL
)
46 swfdec_as_string_mark (node
->name
);
47 if (node
->value
!= NULL
)
48 swfdec_as_string_mark (node
->value
);
49 if (node
->parent
!= NULL
)
50 swfdec_as_object_mark (SWFDEC_AS_OBJECT (node
->parent
));
51 if (node
->children
!= NULL
)
52 swfdec_as_object_mark (SWFDEC_AS_OBJECT (node
->children
));
53 if (node
->attributes
!= NULL
)
54 swfdec_as_object_mark (SWFDEC_AS_OBJECT (node
->attributes
));
55 if (node
->childNodes
!= NULL
)
56 swfdec_as_object_mark (SWFDEC_AS_OBJECT (node
->childNodes
));
58 SWFDEC_AS_OBJECT_CLASS (swfdec_xml_node_parent_class
)->mark (object
);
62 swfdec_xml_node_class_init (SwfdecXmlNodeClass
*klass
)
64 SwfdecAsObjectClass
*asobject_class
= SWFDEC_AS_OBJECT_CLASS (klass
);
66 asobject_class
->mark
= swfdec_xml_node_do_mark
;
70 swfdec_xml_node_init (SwfdecXmlNode
*xml_node
)
77 swfdec_xml_node_num_children (SwfdecXmlNode
*node
)
79 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), 0);
81 return swfdec_as_array_get_length (node
->children
);
84 static SwfdecXmlNode
*
85 swfdec_xml_node_get_child (SwfdecXmlNode
*node
, gint32 ind
)
89 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
90 g_return_val_if_fail (ind
>= 0, NULL
);
92 if (ind
>= swfdec_xml_node_num_children (node
))
95 swfdec_as_array_get_value (node
->children
, ind
, &val
);
97 g_return_val_if_fail (SWFDEC_AS_VALUE_IS_OBJECT (&val
), NULL
);
98 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (
99 SWFDEC_AS_VALUE_GET_OBJECT (&val
)), NULL
);
101 return SWFDEC_XML_NODE (SWFDEC_AS_VALUE_GET_OBJECT (&val
));
105 swfdec_xml_node_index_of_child (SwfdecXmlNode
*node
, SwfdecXmlNode
*child
)
109 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), -1);
110 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (child
), -1);
112 num
= swfdec_xml_node_num_children (node
);
113 for (i
= 0; i
< num
; i
++) {
114 if (swfdec_xml_node_get_child (node
, i
) == child
)
122 swfdec_xml_node_update_childNodes (SwfdecXmlNode
*node
)
128 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
131 SWFDEC_AS_VALUE_SET_INT (&val
, 0);
132 swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (node
->childNodes
),
133 SWFDEC_AS_STR_length
, &val
);
136 num
= swfdec_xml_node_num_children (node
);
137 vals
= g_malloc (sizeof (SwfdecAsValue
) * num
);
138 for (i
= 0; i
< num
; i
++) {
139 SWFDEC_AS_VALUE_SET_OBJECT (&vals
[i
],
140 SWFDEC_AS_OBJECT (swfdec_xml_node_get_child (node
, i
)));
142 swfdec_as_array_append_with_flags (node
->childNodes
, num
, vals
,
143 SWFDEC_AS_VARIABLE_CONSTANT
);
148 swfdec_xml_node_getNamespaceForPrefix (SwfdecXmlNode
*node
, const char *prefix
)
153 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
155 if (prefix
== NULL
|| strlen (prefix
) == 0) {
156 var
= swfdec_as_context_get_string (SWFDEC_AS_OBJECT (node
)->context
,
159 var
= swfdec_as_context_give_string (SWFDEC_AS_OBJECT (node
)->context
,
160 g_strconcat ("xmlns:", prefix
, NULL
));
164 swfdec_as_object_get_variable (node
->attributes
, var
, &val
);
165 if (!SWFDEC_AS_VALUE_IS_UNDEFINED (&val
)) {
166 return swfdec_as_value_to_string (SWFDEC_AS_OBJECT (node
)->context
, &val
);
169 } while (node
!= NULL
);
175 const char *namespace;
176 const char *variable
;
177 } ForeachFindNamespaceData
;
180 swfdec_xml_node_foreach_find_namespace (SwfdecAsObject
*object
,
181 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
184 ForeachFindNamespaceData
*fdata
= data
;
186 // check whether it's namespace variable (xmlns or xmlns:*)
187 if (strlen (variable
) < strlen("xmlns"))
190 if (g_ascii_strncasecmp (variable
, "xmlns", strlen("xmlns")))
193 if (variable
[strlen("xmlns")] != '\0' && variable
[strlen("xmlns")] != ':')
196 // ok, now check if the uri is the one we are searching for
197 uri
= swfdec_as_value_to_string (object
->context
, value
);
198 if (!g_ascii_strcasecmp (uri
, fdata
->namespace)) {
199 fdata
->variable
= variable
;
207 swfdec_xml_node_getPrefixForNamespace (SwfdecXmlNode
*node
,
208 const char *namespace)
210 ForeachFindNamespaceData fdata
;
212 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
213 g_return_val_if_fail (namespace != NULL
, NULL
);
215 fdata
.namespace = namespace;
216 fdata
.variable
= NULL
;
219 swfdec_as_object_foreach (node
->attributes
,
220 swfdec_xml_node_foreach_find_namespace
, &fdata
);
222 } while (node
!= NULL
&& fdata
.variable
== NULL
);
224 if (fdata
.variable
!= NULL
) {
227 p
= strchr (fdata
.variable
, ':');
228 if (p
== NULL
|| *(p
+ 1) == '\0')
229 return SWFDEC_AS_STR_EMPTY
;
231 return swfdec_as_context_get_string (SWFDEC_AS_OBJECT (node
)->context
,
239 swfdec_xml_node_get_nodeType (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
240 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
242 if (!SWFDEC_IS_VALID_XML_NODE (object
))
245 SWFDEC_AS_VALUE_SET_INT (ret
, SWFDEC_XML_NODE (object
)->type
);
249 swfdec_xml_node_get_nodeValue (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
250 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
252 if (!SWFDEC_IS_VALID_XML_NODE (object
))
255 if (SWFDEC_XML_NODE (object
)->value
!= NULL
) {
256 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_XML_NODE (object
)->value
);
258 SWFDEC_AS_VALUE_SET_NULL (ret
);
263 swfdec_xml_node_set_nodeValue (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
264 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
268 if (!SWFDEC_IS_VALID_XML_NODE (object
))
274 value
= swfdec_as_value_to_string (cx
, &argv
[0]);
276 SWFDEC_XML_NODE (object
)->value
= value
;
277 SWFDEC_AS_VALUE_SET_STRING (ret
, value
);
281 swfdec_xml_node_get_nodeName (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
282 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
284 if (!SWFDEC_IS_VALID_XML_NODE (object
))
287 if (SWFDEC_XML_NODE (object
)->name
!= NULL
) {
288 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_XML_NODE (object
)->name
);
290 SWFDEC_AS_VALUE_SET_NULL (ret
);
295 swfdec_xml_node_set_nodeName (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
296 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
300 if (!SWFDEC_IS_VALID_XML_NODE (object
))
307 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]))
310 name
= swfdec_as_value_to_string (cx
, &argv
[0]);
312 SWFDEC_XML_NODE (object
)->name
= name
;
313 SWFDEC_AS_VALUE_SET_STRING (ret
, name
);
317 swfdec_xml_node_get_prefix (SwfdecXmlNode
*node
)
321 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
323 if (node
->name
== NULL
)
326 p
= strchr (node
->name
, ':');
327 if (p
== NULL
|| *(p
+ 1) == '\0')
330 return swfdec_as_context_give_string (SWFDEC_AS_OBJECT (node
)->context
,
331 g_strndup (node
->name
, p
- node
->name
));
335 swfdec_xml_node_do_get_prefix (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
336 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
340 if (!SWFDEC_IS_VALID_XML_NODE (object
))
343 if (SWFDEC_XML_NODE (object
)->name
== NULL
) {
344 SWFDEC_AS_VALUE_SET_NULL (ret
);
348 prefix
= swfdec_xml_node_get_prefix (SWFDEC_XML_NODE (object
));
349 if (prefix
!= NULL
) {
350 SWFDEC_AS_VALUE_SET_STRING (ret
, prefix
);
352 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
357 swfdec_xml_node_get_localName (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
358 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
360 const char *p
, *name
;
362 if (!SWFDEC_IS_VALID_XML_NODE (object
))
365 if (SWFDEC_XML_NODE (object
)->name
== NULL
) {
366 SWFDEC_AS_VALUE_SET_NULL (ret
);
370 name
= SWFDEC_XML_NODE (object
)->name
;
371 p
= strchr (name
, ':');
372 if (p
== NULL
|| *(p
+ 1) == '\0') {
373 SWFDEC_AS_VALUE_SET_STRING (ret
, name
);
378 SWFDEC_AS_VALUE_SET_STRING (ret
,
379 swfdec_as_context_give_string (cx
, g_strdup (p
)));
383 swfdec_xml_node_get_namespaceURI (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
384 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
388 if (!SWFDEC_IS_VALID_XML_NODE (object
))
391 if (SWFDEC_XML_NODE (object
)->name
== NULL
) {
392 SWFDEC_AS_VALUE_SET_NULL (ret
);
396 uri
= swfdec_xml_node_getNamespaceForPrefix (SWFDEC_XML_NODE (object
),
397 swfdec_xml_node_get_prefix (SWFDEC_XML_NODE (object
)));
399 SWFDEC_AS_VALUE_SET_STRING (ret
, uri
);
401 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
406 swfdec_xml_node_get_attributes (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
407 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
409 if (!SWFDEC_IS_VALID_XML_NODE (object
))
412 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_XML_NODE (object
)->attributes
);
416 swfdec_xml_node_get_parentNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
417 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
419 if (!SWFDEC_IS_VALID_XML_NODE (object
))
422 if (SWFDEC_XML_NODE (object
)->parent
!= NULL
) {
423 SWFDEC_AS_VALUE_SET_OBJECT (ret
,
424 SWFDEC_AS_OBJECT (SWFDEC_XML_NODE (object
)->parent
));
426 SWFDEC_AS_VALUE_SET_NULL (ret
);
430 static SwfdecXmlNode
*
431 swfdec_xml_node_previousSibling (SwfdecXmlNode
*node
)
435 if (node
->parent
== NULL
)
438 i
= swfdec_xml_node_index_of_child (node
->parent
, node
);
444 return swfdec_xml_node_get_child (node
->parent
, i
- 1);
448 swfdec_xml_node_get_previousSibling (SwfdecAsContext
*cx
,
449 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
451 SwfdecXmlNode
*sibling
;
453 if (!SWFDEC_IS_VALID_XML_NODE (object
))
456 sibling
= swfdec_xml_node_previousSibling (SWFDEC_XML_NODE (object
));
457 if (sibling
!= NULL
) {
458 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (sibling
));
460 SWFDEC_AS_VALUE_SET_NULL (ret
);
464 static SwfdecXmlNode
*
465 swfdec_xml_node_nextSibling (SwfdecXmlNode
*node
)
469 if (node
->parent
== NULL
)
472 i
= swfdec_xml_node_index_of_child (node
->parent
, node
);
475 return swfdec_xml_node_get_child (node
->parent
, i
+ 1);
479 swfdec_xml_node_get_nextSibling (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
480 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
482 SwfdecXmlNode
*sibling
;
484 if (!SWFDEC_IS_VALID_XML_NODE (object
))
487 sibling
= swfdec_xml_node_nextSibling (SWFDEC_XML_NODE (object
));
488 if (sibling
!= NULL
) {
489 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (sibling
));
491 SWFDEC_AS_VALUE_SET_NULL (ret
);
496 swfdec_xml_node_get_firstChild (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
497 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
499 SwfdecXmlNode
*child
;
501 if (!SWFDEC_IS_VALID_XML_NODE (object
))
504 child
= swfdec_xml_node_get_child (SWFDEC_XML_NODE (object
), 0);
506 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (child
));
508 SWFDEC_AS_VALUE_SET_NULL (ret
);
513 swfdec_xml_node_get_lastChild (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
514 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
517 SwfdecXmlNode
*child
;
519 if (!SWFDEC_IS_VALID_XML_NODE (object
))
522 num
= swfdec_xml_node_num_children (SWFDEC_XML_NODE (object
));
524 SWFDEC_AS_VALUE_SET_NULL (ret
);
528 child
= swfdec_xml_node_get_child (SWFDEC_XML_NODE (object
), num
- 1);
529 g_assert (child
!= NULL
);
531 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (child
));
535 swfdec_xml_node_get_childNodes (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
536 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
538 if (!SWFDEC_IS_VALID_XML_NODE (object
))
541 SWFDEC_AS_VALUE_SET_OBJECT (ret
,
542 SWFDEC_AS_OBJECT (SWFDEC_XML_NODE (object
)->childNodes
));
545 SWFDEC_AS_NATIVE (253, 7, swfdec_xml_node_do_getNamespaceForPrefix
)
547 swfdec_xml_node_do_getNamespaceForPrefix (SwfdecAsContext
*cx
,
548 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
550 const char *namespace;
552 if (!SWFDEC_IS_VALID_XML_NODE (object
))
556 SWFDEC_AS_VALUE_SET_NULL (ret
);
560 namespace = swfdec_xml_node_getNamespaceForPrefix (SWFDEC_XML_NODE (object
),
561 swfdec_as_value_to_string (cx
, &argv
[0]));
563 if (namespace != NULL
) {
564 SWFDEC_AS_VALUE_SET_STRING (ret
, namespace);
566 SWFDEC_AS_VALUE_SET_NULL (ret
);
570 SWFDEC_AS_NATIVE (253, 8, swfdec_xml_node_do_getPrefixForNamespace
)
572 swfdec_xml_node_do_getPrefixForNamespace (SwfdecAsContext
*cx
,
573 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
577 if (!SWFDEC_IS_VALID_XML_NODE (object
))
581 SWFDEC_AS_VALUE_SET_NULL (ret
);
585 prefix
= swfdec_xml_node_getPrefixForNamespace (SWFDEC_XML_NODE (object
),
586 swfdec_as_value_to_string (cx
, &argv
[0]));
588 if (prefix
!= NULL
) {
589 SWFDEC_AS_VALUE_SET_STRING (ret
, prefix
);
591 SWFDEC_AS_VALUE_SET_NULL (ret
);
596 swfdec_xml_node_foreach_copy_attributes (SwfdecAsObject
*object
,
597 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
599 SwfdecAsObject
*target
= data
;
600 swfdec_as_object_set_variable (target
, variable
, value
);
605 swfdec_xml_node_copy_attributes (SwfdecXmlNode
*node
, SwfdecXmlNode
*target
)
607 swfdec_as_object_foreach (node
->attributes
,
608 swfdec_xml_node_foreach_copy_attributes
, target
->attributes
);
611 static SwfdecXmlNode
*
612 swfdec_xml_node_clone (SwfdecAsContext
*cx
, SwfdecXmlNode
*node
, gboolean deep
)
616 g_assert (SWFDEC_IS_AS_CONTEXT (cx
));
617 g_assert (SWFDEC_IS_VALID_XML_NODE (node
));
619 new = swfdec_xml_node_new (cx
, SWFDEC_XML_NODE_ELEMENT
, SWFDEC_AS_STR_EMPTY
);
622 new->type
= node
->type
;
623 new->name
= node
->name
;
624 new->value
= node
->value
;
626 swfdec_xml_node_copy_attributes (node
, new);
630 SwfdecXmlNode
*child
, *child_new
;
633 num
= swfdec_xml_node_num_children (node
);
635 for (i
= 0; i
< num
; i
++) {
636 child
= swfdec_xml_node_get_child (node
, i
);
637 child_new
= swfdec_xml_node_clone (cx
, child
, TRUE
);
638 child_new
->parent
= new;
639 SWFDEC_AS_VALUE_SET_OBJECT (&val
, SWFDEC_AS_OBJECT (child_new
));
640 swfdec_as_array_push (new->children
, &val
);
643 swfdec_xml_node_update_childNodes (new);
649 SWFDEC_AS_NATIVE (253, 1, swfdec_xml_node_cloneNode
)
651 swfdec_xml_node_cloneNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
652 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
657 if (!SWFDEC_IS_VALID_XML_NODE (object
))
661 deep
= swfdec_as_value_to_boolean (cx
, &argv
[0]);
666 new = swfdec_xml_node_clone (cx
, SWFDEC_XML_NODE (object
), deep
);
667 SWFDEC_AS_VALUE_SET_OBJECT (ret
, SWFDEC_AS_OBJECT (new));
671 swfdec_xml_node_removeNode (SwfdecXmlNode
*node
)
675 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
677 if (node
->parent
== NULL
)
680 i
= swfdec_xml_node_index_of_child (node
->parent
, node
);
683 swfdec_as_array_remove (node
->parent
->children
, i
);
684 swfdec_xml_node_update_childNodes (node
->parent
);
688 SWFDEC_AS_NATIVE (253, 2, swfdec_xml_node_do_removeNode
)
690 swfdec_xml_node_do_removeNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
691 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
693 if (!SWFDEC_IS_VALID_XML_NODE (object
))
696 swfdec_xml_node_removeNode (SWFDEC_XML_NODE (object
));
700 swfdec_xml_node_removeChildren (SwfdecXmlNode
*node
)
704 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
706 num
= swfdec_xml_node_num_children (node
);
708 for (i
= 0; i
< num
; i
++) {
709 swfdec_xml_node_removeNode (swfdec_xml_node_get_child (node
, 0));
714 swfdec_xml_node_insertAt (SwfdecXmlNode
*node
, SwfdecXmlNode
*child
, gint32 ind
)
718 g_assert (SWFDEC_IS_VALID_XML_NODE (node
));
719 g_assert (SWFDEC_IS_VALID_XML_NODE (child
));
722 // remove the previous parent of the child
723 swfdec_xml_node_removeNode (child
);
725 // insert child to node's childNodes array
726 SWFDEC_AS_VALUE_SET_OBJECT (&val
, SWFDEC_AS_OBJECT (child
));
727 swfdec_as_array_insert (node
->children
, ind
, &val
);
728 swfdec_xml_node_update_childNodes (node
);
730 // set node as parent of child
731 child
->parent
= node
;
734 SWFDEC_AS_NATIVE (253, 3, swfdec_xml_node_insertBefore
)
736 swfdec_xml_node_insertBefore (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
737 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
740 SwfdecAsObject
*child
, *point
;
742 if (!SWFDEC_IS_VALID_XML_NODE (object
))
748 if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv
[0]))
751 child
= SWFDEC_AS_VALUE_GET_OBJECT (&argv
[0]);
752 if (!SWFDEC_IS_VALID_XML_NODE (child
))
756 if (swfdec_xml_node_index_of_child (SWFDEC_XML_NODE (object
),
757 SWFDEC_XML_NODE (child
)) != -1)
760 if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv
[1]))
763 point
= SWFDEC_AS_VALUE_GET_OBJECT (&argv
[1]);
764 if (!SWFDEC_IS_VALID_XML_NODE (point
))
767 i
= swfdec_xml_node_index_of_child (SWFDEC_XML_NODE (object
),
768 SWFDEC_XML_NODE (point
));
771 swfdec_xml_node_insertAt (SWFDEC_XML_NODE (object
),
772 SWFDEC_XML_NODE (child
), i
);
777 swfdec_xml_node_appendChild (SwfdecXmlNode
*node
, SwfdecXmlNode
*child
)
781 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
782 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (child
));
783 g_return_if_fail (node
->children
!= NULL
);
785 // remove the previous parent of the child
786 swfdec_xml_node_removeNode (child
);
788 // append child to node's childNodes array
789 SWFDEC_AS_VALUE_SET_OBJECT (&val
, SWFDEC_AS_OBJECT (child
));
790 swfdec_as_array_push (node
->children
, &val
);
791 swfdec_xml_node_update_childNodes (node
);
793 // set node as parent of child
794 child
->parent
= node
;
797 SWFDEC_AS_NATIVE (253, 4, swfdec_xml_node_do_appendChild
)
799 swfdec_xml_node_do_appendChild (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
800 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
802 SwfdecAsObject
*child
;
804 if (!SWFDEC_IS_VALID_XML_NODE (object
))
810 if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv
[0]))
813 child
= SWFDEC_AS_VALUE_GET_OBJECT (&argv
[0]);
814 if (!SWFDEC_IS_VALID_XML_NODE (child
))
818 if (swfdec_xml_node_index_of_child (SWFDEC_XML_NODE (object
),
819 SWFDEC_XML_NODE (child
)) != -1)
822 swfdec_xml_node_appendChild (SWFDEC_XML_NODE (object
),
823 SWFDEC_XML_NODE (child
));
826 SWFDEC_AS_NATIVE (253, 5, swfdec_xml_node_hasChildNodes
)
828 swfdec_xml_node_hasChildNodes (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
829 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
831 if (!SWFDEC_IS_VALID_XML_NODE (object
))
834 if (swfdec_xml_node_num_children (SWFDEC_XML_NODE (object
)) > 0) {
835 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
, TRUE
);
837 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
, FALSE
);
842 swfdec_xml_node_foreach_string_append_attribute (SwfdecAsObject
*object
,
843 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
845 GString
*string
= *(GString
**)data
;
848 string
= g_string_append (string
, " ");
849 string
= g_string_append (string
, variable
);
850 string
= g_string_append (string
, "=\"");
852 swfdec_xml_escape (swfdec_as_value_to_string (object
->context
, value
));
853 string
= g_string_append (string
, escaped
);
855 string
= g_string_append (string
, "\"");
861 swfdec_xml_node_toString (SwfdecXmlNode
*node
)
864 SwfdecAsObject
*object
;
866 g_assert (SWFDEC_IS_VALID_XML_NODE (node
));
868 object
= SWFDEC_AS_OBJECT (node
);
870 string
= g_string_new ("");
871 if (SWFDEC_IS_XML (node
)) {
872 if (SWFDEC_XML (node
)->xmlDecl
!= NULL
)
873 string
= g_string_append (string
, SWFDEC_XML (node
)->xmlDecl
);
874 if (SWFDEC_XML (node
)->docTypeDecl
!= NULL
)
875 string
= g_string_append (string
, SWFDEC_XML (node
)->docTypeDecl
);
878 switch (node
->type
) {
879 case SWFDEC_XML_NODE_ELEMENT
:
881 SwfdecXmlNode
*child
;
885 if (node
->name
== NULL
) {
892 string
= g_string_append (string
, "<");
893 string
= g_string_append (string
, node
->name
);
895 swfdec_as_object_foreach (node
->attributes
,
896 swfdec_xml_node_foreach_string_append_attribute
, &string
);
899 num
= swfdec_xml_node_num_children (node
);
903 string
= g_string_append (string
, ">");
905 for (i
= 0; i
< num
; i
++) {
906 child
= swfdec_xml_node_get_child (node
, i
);
907 g_assert (child
!= NULL
);
908 string
= g_string_append (string
, swfdec_xml_node_toString (child
));
912 string
= g_string_append (string
, "</");
913 string
= g_string_append (string
, node
->name
);
914 string
= g_string_append (string
, ">");
918 string
= g_string_append (string
, " />");
923 case SWFDEC_XML_NODE_TEXT
:
926 char *escaped
= swfdec_xml_escape (node
->value
);
927 string
= g_string_append (string
, escaped
);
933 return swfdec_as_context_give_string (object
->context
,
934 g_string_free (string
, FALSE
));
937 SWFDEC_AS_NATIVE (253, 6, swfdec_xml_node_do_toString
)
939 swfdec_xml_node_do_toString (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
940 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
942 if (!SWFDEC_IS_VALID_XML_NODE (object
))
945 SWFDEC_AS_VALUE_SET_STRING (ret
,
946 swfdec_xml_node_toString (SWFDEC_XML_NODE (object
)));
950 swfdec_xml_node_init_properties (SwfdecXmlNode
*node
, int type
,
953 SwfdecAsObject
*object
;
955 g_return_if_fail (SWFDEC_IS_XML_NODE (node
));
956 g_return_if_fail (value
!= NULL
);
958 object
= SWFDEC_AS_OBJECT (node
);
962 // FIXME: use _global.Array constructor?
963 node
->children
= SWFDEC_AS_ARRAY (swfdec_as_array_new (object
->context
));
964 node
->attributes
= swfdec_as_object_new_empty (object
->context
);
966 if (node
->type
== SWFDEC_XML_NODE_ELEMENT
) {
972 node
->childNodes
= SWFDEC_AS_ARRAY (swfdec_as_array_new (object
->context
));
976 swfdec_xml_node_new (SwfdecAsContext
*context
, SwfdecXmlNodeType type
,
983 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
985 size
= sizeof (SwfdecXmlNode
);
986 if (!swfdec_as_context_use_mem (context
, size
))
988 node
= g_object_new (SWFDEC_TYPE_XML_NODE
, NULL
);
989 swfdec_as_object_add (SWFDEC_AS_OBJECT (node
), context
, size
);
990 swfdec_as_object_get_variable (context
->global
, SWFDEC_AS_STR_XMLNode
, &val
);
991 if (!SWFDEC_AS_VALUE_IS_OBJECT (&val
))
993 swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (node
), SWFDEC_AS_VALUE_GET_OBJECT (&val
));
995 swfdec_xml_node_init_properties (node
, type
,
996 swfdec_as_context_get_string (SWFDEC_AS_OBJECT (node
)->context
, value
));
1002 swfdec_xml_node_add_variable (SwfdecAsObject
*object
, const char *variable
,
1003 SwfdecAsNative get
, SwfdecAsNative set
)
1005 SwfdecAsFunction
*get_func
, *set_func
;
1007 g_return_if_fail (SWFDEC_IS_AS_OBJECT (object
));
1008 g_return_if_fail (variable
!= NULL
);
1009 g_return_if_fail (get
!= NULL
);
1012 swfdec_as_native_function_new (object
->context
, variable
, get
, 0, NULL
);
1013 if (get_func
== NULL
)
1018 swfdec_as_native_function_new (object
->context
, variable
, set
, 0, NULL
);
1023 swfdec_as_object_add_variable (object
, variable
, get_func
, set_func
, 0);
1026 SWFDEC_AS_CONSTRUCTOR (253, 0, swfdec_xml_node_construct
, swfdec_xml_node_get_type
)
1028 swfdec_xml_node_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
1029 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
1031 if (!swfdec_as_context_is_constructing (cx
)) {
1032 SWFDEC_FIXME ("What do we do if not constructing?");
1036 g_assert (SWFDEC_IS_XML_NODE (object
));
1038 if (!SWFDEC_PLAYER (cx
)->xml_node_properties_initialized
) {
1040 SwfdecAsObject
*proto
;
1042 swfdec_as_object_get_variable (object
, SWFDEC_AS_STR___proto__
, &val
);
1043 g_return_if_fail (SWFDEC_AS_VALUE_IS_OBJECT (&val
));
1044 proto
= SWFDEC_AS_VALUE_GET_OBJECT (&val
);
1046 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_nodeType
,
1047 swfdec_xml_node_get_nodeType
, NULL
);
1048 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_nodeValue
,
1049 swfdec_xml_node_get_nodeValue
, swfdec_xml_node_set_nodeValue
);
1050 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_nodeName
,
1051 swfdec_xml_node_get_nodeName
, swfdec_xml_node_set_nodeName
);
1052 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_prefix
,
1053 swfdec_xml_node_do_get_prefix
, NULL
);
1054 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_localName
,
1055 swfdec_xml_node_get_localName
, NULL
);
1056 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_namespaceURI
,
1057 swfdec_xml_node_get_namespaceURI
, NULL
);
1058 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_attributes
,
1059 swfdec_xml_node_get_attributes
, NULL
);
1060 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_parentNode
,
1061 swfdec_xml_node_get_parentNode
, NULL
);
1062 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_previousSibling
,
1063 swfdec_xml_node_get_previousSibling
, NULL
);
1064 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_nextSibling
,
1065 swfdec_xml_node_get_nextSibling
, NULL
);
1066 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_firstChild
,
1067 swfdec_xml_node_get_firstChild
, NULL
);
1068 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_lastChild
,
1069 swfdec_xml_node_get_lastChild
, NULL
);
1070 swfdec_xml_node_add_variable (proto
, SWFDEC_AS_STR_childNodes
,
1071 swfdec_xml_node_get_childNodes
, NULL
);
1073 SWFDEC_PLAYER (cx
)->xml_node_properties_initialized
= TRUE
;
1080 if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[0]) ||
1081 SWFDEC_AS_VALUE_IS_UNDEFINED (&argv
[1]))
1084 swfdec_xml_node_init_properties (SWFDEC_XML_NODE (object
),
1085 swfdec_as_value_to_integer (cx
, &argv
[0]),
1086 swfdec_as_value_to_string (cx
, &argv
[1]));
1088 SWFDEC_AS_VALUE_SET_OBJECT (ret
, object
);