2 * Copyright (C) 2007-2008 Benjamin Otte <otte@gnome.org>
3 * 2007 Pekka Lampila <pekka.lampila@iki.fi>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
27 #include "swfdec_xml_node.h"
28 #include "swfdec_xml.h"
29 #include "swfdec_as_array.h"
30 #include "swfdec_as_native_function.h"
31 #include "swfdec_as_object.h"
32 #include "swfdec_as_strings.h"
33 #include "swfdec_debug.h"
34 #include "swfdec_internal.h"
35 #include "swfdec_as_internal.h"
36 #include "swfdec_load_object.h"
37 #include "swfdec_player_internal.h"
39 G_DEFINE_TYPE (SwfdecXmlNode
, swfdec_xml_node
, SWFDEC_TYPE_AS_RELAY
)
42 swfdec_xml_node_mark (SwfdecGcObject
*object
)
44 SwfdecXmlNode
*node
= SWFDEC_XML_NODE (object
);
46 if (node
->name
!= NULL
)
47 swfdec_as_string_mark (node
->name
);
48 if (node
->value
!= NULL
)
49 swfdec_as_string_mark (node
->value
);
50 if (node
->parent
!= NULL
)
51 swfdec_gc_object_mark (node
->parent
);
52 if (node
->children
!= NULL
)
53 swfdec_as_object_mark (node
->children
);
54 if (node
->attributes
!= NULL
)
55 swfdec_as_object_mark (node
->attributes
);
56 if (node
->child_nodes
!= NULL
)
57 swfdec_as_object_mark (node
->child_nodes
);
59 SWFDEC_GC_OBJECT_CLASS (swfdec_xml_node_parent_class
)->mark (object
);
63 swfdec_xml_node_class_init (SwfdecXmlNodeClass
*klass
)
65 SwfdecGcObjectClass
*gc_class
= SWFDEC_GC_OBJECT_CLASS (klass
);
67 gc_class
->mark
= swfdec_xml_node_mark
;
71 swfdec_xml_node_init (SwfdecXmlNode
*xml_node
)
78 swfdec_xml_node_num_children (SwfdecXmlNode
*node
)
80 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), 0);
82 return swfdec_as_array_get_length (node
->children
);
86 swfdec_xml_node_get_child (SwfdecXmlNode
*node
, gint32 index_
)
90 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
91 g_return_val_if_fail (index_
>= 0, NULL
);
93 if (index_
>= swfdec_xml_node_num_children (node
))
96 swfdec_as_array_get_value (node
->children
, index_
, &val
);
98 g_return_val_if_fail (SWFDEC_AS_VALUE_IS_OBJECT (val
), NULL
);
99 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (
100 SWFDEC_AS_VALUE_GET_OBJECT (val
)->relay
), NULL
);
102 return SWFDEC_XML_NODE (SWFDEC_AS_VALUE_GET_OBJECT (val
)->relay
);
106 swfdec_xml_node_index_of_child (SwfdecXmlNode
*node
, SwfdecXmlNode
*child
)
110 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), -1);
111 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (child
), -1);
113 num
= swfdec_xml_node_num_children (node
);
114 for (i
= 0; i
< num
; i
++) {
115 if (swfdec_xml_node_get_child (node
, i
) == child
)
123 swfdec_xml_node_update_child_nodes (SwfdecXmlNode
*node
)
129 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
132 val
= swfdec_as_value_from_integer (swfdec_gc_object_get_context (node
), 0);
133 swfdec_as_object_set_variable (node
->child_nodes
,
134 SWFDEC_AS_STR_length
, &val
);
137 num
= swfdec_xml_node_num_children (node
);
138 vals
= g_malloc (sizeof (SwfdecAsValue
) * num
);
139 for (i
= 0; i
< num
; i
++) {
140 SWFDEC_AS_VALUE_SET_OBJECT (&vals
[i
], swfdec_as_relay_get_as_object (
141 SWFDEC_AS_RELAY (swfdec_xml_node_get_child (node
, i
))));
143 swfdec_as_array_append_with_flags (node
->child_nodes
, num
, vals
,
144 SWFDEC_AS_VARIABLE_CONSTANT
);
149 swfdec_xml_node_get_attribute (SwfdecXmlNode
*node
, const char *name
)
153 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
154 g_return_val_if_fail (name
!= NULL
, NULL
);
156 if (swfdec_as_object_get_variable (node
->attributes
, name
, &val
)) {
157 return swfdec_as_value_to_string (swfdec_gc_object_get_context (node
), val
);
164 swfdec_xml_node_getNamespaceForPrefix (SwfdecXmlNode
*node
, const char *prefix
)
169 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
171 if (prefix
== NULL
|| strlen (prefix
) == 0) {
172 var
= swfdec_as_context_get_string (swfdec_gc_object_get_context (node
),
175 var
= swfdec_as_context_give_string (swfdec_gc_object_get_context (node
),
176 g_strconcat ("xmlns:", prefix
, NULL
));
180 swfdec_as_object_get_variable (node
->attributes
, var
, &val
);
181 if (!SWFDEC_AS_VALUE_IS_UNDEFINED (val
)) {
182 return swfdec_as_value_to_string (swfdec_gc_object_get_context (node
), val
);
185 } while (node
!= NULL
);
191 const char *namespace;
192 const char *variable
;
193 } ForeachFindNamespaceData
;
196 swfdec_xml_node_foreach_find_namespace (SwfdecAsObject
*object
,
197 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
200 ForeachFindNamespaceData
*fdata
= data
;
202 // check whether it's namespace variable (xmlns or xmlns:*)
203 if (strlen (variable
) < strlen("xmlns"))
206 if (g_ascii_strncasecmp (variable
, "xmlns", strlen("xmlns")))
209 if (variable
[strlen("xmlns")] != '\0' && variable
[strlen("xmlns")] != ':')
212 // ok, now check if the uri is the one we are searching for
213 uri
= swfdec_as_value_to_string (object
->context
, *value
);
214 if (!g_ascii_strcasecmp (uri
, fdata
->namespace)) {
215 fdata
->variable
= variable
;
223 swfdec_xml_node_getPrefixForNamespace (SwfdecXmlNode
*node
,
224 const char *namespace)
226 ForeachFindNamespaceData fdata
;
228 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
229 g_return_val_if_fail (namespace != NULL
, NULL
);
231 fdata
.namespace = namespace;
232 fdata
.variable
= NULL
;
235 swfdec_as_object_foreach (node
->attributes
,
236 swfdec_xml_node_foreach_find_namespace
, &fdata
);
238 } while (node
!= NULL
&& fdata
.variable
== NULL
);
240 if (fdata
.variable
!= NULL
) {
243 p
= strchr (fdata
.variable
, ':');
244 if (p
== NULL
|| *(p
+ 1) == '\0')
245 return SWFDEC_AS_STR_EMPTY
;
247 return swfdec_as_context_get_string (swfdec_gc_object_get_context (node
),
255 swfdec_xml_node_get_nodeType (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
256 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
260 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
262 if (!SWFDEC_IS_VALID_XML_NODE (node
))
265 *ret
= swfdec_as_value_from_integer (cx
, node
->type
);
269 swfdec_xml_node_get_nodeValue (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
270 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
274 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
276 if (!SWFDEC_IS_VALID_XML_NODE (node
))
279 if (node
->value
!= NULL
) {
280 SWFDEC_AS_VALUE_SET_STRING (ret
, node
->value
);
282 SWFDEC_AS_VALUE_SET_NULL (ret
);
287 swfdec_xml_node_set_nodeValue (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
288 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
293 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "s", &value
);
295 if (!SWFDEC_IS_VALID_XML_NODE (node
))
299 SWFDEC_AS_VALUE_SET_STRING (ret
, value
);
303 swfdec_xml_node_get_nodeName (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
304 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
308 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
310 if (!SWFDEC_IS_VALID_XML_NODE (node
))
313 if (node
->name
!= NULL
) {
314 SWFDEC_AS_VALUE_SET_STRING (ret
, node
->name
);
316 SWFDEC_AS_VALUE_SET_NULL (ret
);
321 swfdec_xml_node_set_nodeName (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
322 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
327 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "s", &name
);
329 if (!SWFDEC_IS_VALID_XML_NODE (node
))
333 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
337 SWFDEC_AS_VALUE_SET_STRING (ret
, name
);
341 swfdec_xml_node_get_prefix (SwfdecXmlNode
*node
)
345 g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (node
), NULL
);
347 if (node
->name
== NULL
)
350 p
= strchr (node
->name
, ':');
351 if (p
== NULL
|| *(p
+ 1) == '\0')
354 return swfdec_as_context_give_string (swfdec_gc_object_get_context (node
),
355 g_strndup (node
->name
, p
- node
->name
));
359 swfdec_xml_node_do_get_prefix (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
360 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
365 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
367 if (!SWFDEC_IS_VALID_XML_NODE (node
))
370 if (node
->name
== NULL
) {
371 SWFDEC_AS_VALUE_SET_NULL (ret
);
375 prefix
= swfdec_xml_node_get_prefix (node
);
376 if (prefix
!= NULL
) {
377 SWFDEC_AS_VALUE_SET_STRING (ret
, prefix
);
379 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
384 swfdec_xml_node_get_localName (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
385 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
387 const char *p
, *name
;
390 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
392 if (!SWFDEC_IS_VALID_XML_NODE (node
))
395 if (node
->name
== NULL
) {
396 SWFDEC_AS_VALUE_SET_NULL (ret
);
401 p
= strchr (name
, ':');
402 if (p
== NULL
|| *(p
+ 1) == '\0') {
403 SWFDEC_AS_VALUE_SET_STRING (ret
, name
);
408 SWFDEC_AS_VALUE_SET_STRING (ret
,
409 swfdec_as_context_get_string (cx
, p
));
413 swfdec_xml_node_get_namespaceURI (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
414 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
419 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
421 if (!SWFDEC_IS_VALID_XML_NODE (node
))
424 if (node
->name
== NULL
) {
425 SWFDEC_AS_VALUE_SET_NULL (ret
);
429 uri
= swfdec_xml_node_getNamespaceForPrefix (node
,
430 swfdec_xml_node_get_prefix (node
));
432 SWFDEC_AS_VALUE_SET_STRING (ret
, uri
);
434 SWFDEC_AS_VALUE_SET_STRING (ret
, SWFDEC_AS_STR_EMPTY
);
439 swfdec_xml_node_get_attributes (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
440 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
444 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
446 if (!SWFDEC_IS_VALID_XML_NODE (node
))
449 SWFDEC_AS_VALUE_SET_OBJECT (ret
, node
->attributes
);
453 swfdec_xml_node_get_parentNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
454 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
458 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
460 if (!SWFDEC_IS_VALID_XML_NODE (node
))
463 if (node
->parent
!= NULL
) {
464 SWFDEC_AS_VALUE_SET_OBJECT (ret
,
465 swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node
->parent
)));
467 SWFDEC_AS_VALUE_SET_NULL (ret
);
471 static SwfdecXmlNode
*
472 swfdec_xml_node_previousSibling (SwfdecXmlNode
*node
)
476 if (node
->parent
== NULL
)
479 i
= swfdec_xml_node_index_of_child (node
->parent
, node
);
485 return swfdec_xml_node_get_child (node
->parent
, i
- 1);
489 swfdec_xml_node_get_previousSibling (SwfdecAsContext
*cx
,
490 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
492 SwfdecXmlNode
*sibling
;
495 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
497 if (!SWFDEC_IS_VALID_XML_NODE (node
))
500 sibling
= swfdec_xml_node_previousSibling (node
);
501 if (sibling
!= NULL
) {
502 SWFDEC_AS_VALUE_SET_OBJECT (ret
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sibling
)));
504 SWFDEC_AS_VALUE_SET_NULL (ret
);
508 static SwfdecXmlNode
*
509 swfdec_xml_node_nextSibling (SwfdecXmlNode
*node
)
513 if (node
->parent
== NULL
)
516 i
= swfdec_xml_node_index_of_child (node
->parent
, node
);
519 return swfdec_xml_node_get_child (node
->parent
, i
+ 1);
523 swfdec_xml_node_get_nextSibling (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
524 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
526 SwfdecXmlNode
*sibling
;
529 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
531 if (!SWFDEC_IS_VALID_XML_NODE (node
))
534 sibling
= swfdec_xml_node_nextSibling (node
);
535 if (sibling
!= NULL
) {
536 SWFDEC_AS_VALUE_SET_OBJECT (ret
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sibling
)));
538 SWFDEC_AS_VALUE_SET_NULL (ret
);
543 swfdec_xml_node_get_firstChild (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
544 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
546 SwfdecXmlNode
*child
;
549 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
551 if (!SWFDEC_IS_VALID_XML_NODE (node
))
554 child
= swfdec_xml_node_get_child (node
, 0);
556 SWFDEC_AS_VALUE_SET_OBJECT (ret
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child
)));
558 SWFDEC_AS_VALUE_SET_NULL (ret
);
563 swfdec_xml_node_get_lastChild (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
564 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
567 SwfdecXmlNode
*child
;
570 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
572 if (!SWFDEC_IS_VALID_XML_NODE (node
))
575 num
= swfdec_xml_node_num_children (node
);
577 SWFDEC_AS_VALUE_SET_NULL (ret
);
581 child
= swfdec_xml_node_get_child (node
, num
- 1);
582 g_assert (child
!= NULL
);
584 SWFDEC_AS_VALUE_SET_OBJECT (ret
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child
)));
588 swfdec_xml_node_get_childNodes (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
589 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
593 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
595 if (!SWFDEC_IS_VALID_XML_NODE (node
))
598 SWFDEC_AS_VALUE_SET_OBJECT (ret
, node
->child_nodes
);
601 SWFDEC_AS_NATIVE (253, 7, swfdec_xml_node_do_getNamespaceForPrefix
)
603 swfdec_xml_node_do_getNamespaceForPrefix (SwfdecAsContext
*cx
,
604 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
606 const char *namespace, *prefix
;
609 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "|s", &prefix
);
611 if (!SWFDEC_IS_VALID_XML_NODE (node
))
615 SWFDEC_AS_VALUE_SET_NULL (ret
);
619 namespace = swfdec_xml_node_getNamespaceForPrefix (node
, prefix
);
621 if (namespace != NULL
) {
622 SWFDEC_AS_VALUE_SET_STRING (ret
, namespace);
624 SWFDEC_AS_VALUE_SET_NULL (ret
);
628 SWFDEC_AS_NATIVE (253, 8, swfdec_xml_node_do_getPrefixForNamespace
)
630 swfdec_xml_node_do_getPrefixForNamespace (SwfdecAsContext
*cx
,
631 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
633 const char *namespace, *prefix
;
636 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "|s", &namespace);
638 if (!SWFDEC_IS_VALID_XML_NODE (node
))
642 SWFDEC_AS_VALUE_SET_NULL (ret
);
646 prefix
= swfdec_xml_node_getPrefixForNamespace (node
, namespace);
648 if (prefix
!= NULL
) {
649 SWFDEC_AS_VALUE_SET_STRING (ret
, prefix
);
651 SWFDEC_AS_VALUE_SET_NULL (ret
);
656 swfdec_xml_node_foreach_copy_attributes (SwfdecAsObject
*object
,
657 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
659 SwfdecAsObject
*target
= data
;
660 swfdec_as_object_set_variable (target
, variable
, value
);
665 swfdec_xml_node_copy_attributes (SwfdecXmlNode
*node
, SwfdecXmlNode
*target
)
667 swfdec_as_object_foreach (node
->attributes
,
668 swfdec_xml_node_foreach_copy_attributes
, target
->attributes
);
671 static SwfdecXmlNode
*
672 swfdec_xml_node_clone (SwfdecAsContext
*cx
, SwfdecXmlNode
*node
, gboolean deep
)
676 g_assert (SWFDEC_IS_AS_CONTEXT (cx
));
677 g_assert (SWFDEC_IS_VALID_XML_NODE (node
));
679 new = swfdec_xml_node_new (cx
, SWFDEC_XML_NODE_ELEMENT
, SWFDEC_AS_STR_EMPTY
);
682 new->type
= node
->type
;
683 new->name
= node
->name
;
684 new->value
= node
->value
;
686 swfdec_xml_node_copy_attributes (node
, new);
690 SwfdecXmlNode
*child
, *child_new
;
693 num
= swfdec_xml_node_num_children (node
);
695 for (i
= 0; i
< num
; i
++) {
696 child
= swfdec_xml_node_get_child (node
, i
);
697 child_new
= swfdec_xml_node_clone (cx
, child
, TRUE
);
698 child_new
->parent
= new;
699 SWFDEC_AS_VALUE_SET_OBJECT (&val
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child_new
)));
700 swfdec_as_array_push (new->children
, &val
);
703 swfdec_xml_node_update_child_nodes (new);
709 SWFDEC_AS_NATIVE (253, 1, swfdec_xml_node_cloneNode
)
711 swfdec_xml_node_cloneNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
712 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
714 gboolean deep
= FALSE
;
715 SwfdecXmlNode
*new, *node
;
717 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "|b", &deep
);
719 if (!SWFDEC_IS_VALID_XML_NODE (node
))
722 new = swfdec_xml_node_clone (cx
, node
, deep
);
724 SWFDEC_AS_VALUE_SET_OBJECT (ret
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (new)));
728 swfdec_xml_node_removeNode (SwfdecXmlNode
*node
)
732 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
734 if (node
->parent
== NULL
)
737 i
= swfdec_xml_node_index_of_child (node
->parent
, node
);
740 swfdec_as_array_remove (node
->parent
->children
, i
);
741 swfdec_xml_node_update_child_nodes (node
->parent
);
745 SWFDEC_AS_NATIVE (253, 2, swfdec_xml_node_do_removeNode
)
747 swfdec_xml_node_do_removeNode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
748 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
752 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
754 if (!SWFDEC_IS_VALID_XML_NODE (node
))
757 swfdec_xml_node_removeNode (node
);
761 swfdec_xml_node_removeChildren (SwfdecXmlNode
*node
)
765 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
767 num
= swfdec_xml_node_num_children (node
);
769 for (i
= 0; i
< num
; i
++) {
770 swfdec_xml_node_removeNode (swfdec_xml_node_get_child (node
, 0));
775 swfdec_xml_node_insertAt (SwfdecXmlNode
*node
, SwfdecXmlNode
*child
, gint32 ind
)
779 g_assert (SWFDEC_IS_VALID_XML_NODE (node
));
780 g_assert (SWFDEC_IS_VALID_XML_NODE (child
));
783 if (swfdec_gc_object_get_context (node
)->version
>= 8) {
784 SwfdecXmlNode
*parent
= node
;
785 while (parent
!= NULL
) {
788 parent
= parent
->parent
;
792 // remove the previous parent of the child
793 swfdec_xml_node_removeNode (child
);
795 // insert child to node's child_nodes array
796 SWFDEC_AS_VALUE_SET_OBJECT (&val
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child
)));
797 swfdec_as_array_insert (node
->children
, ind
, &val
);
798 swfdec_xml_node_update_child_nodes (node
);
800 // set node as parent of child
801 child
->parent
= node
;
804 SWFDEC_AS_NATIVE (253, 3, swfdec_xml_node_insertBefore
)
806 swfdec_xml_node_insertBefore (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
807 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
810 SwfdecAsObject
*child
, *point
;
811 SwfdecXmlNode
*node
, *child_node
, *point_node
;
813 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "oo", &child
, &point
);
815 if (!SWFDEC_IS_VALID_XML_NODE (node
) ||
816 !SWFDEC_IS_VALID_XML_NODE (child
->relay
) ||
817 !SWFDEC_IS_VALID_XML_NODE (point
->relay
))
820 child_node
= SWFDEC_XML_NODE (child
->relay
);
821 point_node
= SWFDEC_XML_NODE (point
->relay
);
824 if (swfdec_xml_node_index_of_child (node
, child_node
) != -1)
827 i
= swfdec_xml_node_index_of_child (node
, point_node
);
830 swfdec_xml_node_insertAt (node
, child_node
, i
);
835 swfdec_xml_node_appendChild (SwfdecXmlNode
*node
, SwfdecXmlNode
*child
)
837 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (node
));
838 g_return_if_fail (SWFDEC_IS_VALID_XML_NODE (child
));
839 g_return_if_fail (node
->children
!= NULL
);
841 swfdec_xml_node_insertAt (node
, child
,
842 swfdec_as_array_get_length (node
->children
));
845 SWFDEC_AS_NATIVE (253, 4, swfdec_xml_node_do_appendChild
)
847 swfdec_xml_node_do_appendChild (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
848 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
850 SwfdecAsObject
*child
;
851 SwfdecXmlNode
*node
, *child_node
;
853 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "o", &child
);
855 if (!SWFDEC_IS_VALID_XML_NODE (node
) ||
856 !SWFDEC_IS_VALID_XML_NODE (child
->relay
))
859 child_node
= SWFDEC_XML_NODE (child
->relay
);
862 if (swfdec_xml_node_index_of_child (node
, child_node
) != -1)
865 swfdec_xml_node_appendChild (node
, child_node
);
868 SWFDEC_AS_NATIVE (253, 5, swfdec_xml_node_hasChildNodes
)
870 swfdec_xml_node_hasChildNodes (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
871 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
875 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
877 if (!SWFDEC_IS_VALID_XML_NODE (node
))
880 SWFDEC_AS_VALUE_SET_BOOLEAN (ret
,
881 swfdec_xml_node_num_children (node
) > 0);
885 swfdec_xml_node_foreach_string_append_attribute (SwfdecAsObject
*object
,
886 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
888 GString
*string
= *(GString
**)data
;
891 string
= g_string_append (string
, " ");
892 string
= g_string_append (string
, variable
);
893 string
= g_string_append (string
, "=\"");
895 swfdec_xml_escape (swfdec_as_value_to_string (object
->context
, *value
));
896 string
= g_string_append (string
, escaped
);
898 string
= g_string_append (string
, "\"");
904 swfdec_xml_node_toString (SwfdecXmlNode
*node
)
908 g_assert (SWFDEC_IS_VALID_XML_NODE (node
));
910 string
= g_string_new ("");
911 if (SWFDEC_IS_XML (node
)) {
912 if (SWFDEC_XML (node
)->xml_decl
!= NULL
)
913 string
= g_string_append (string
, SWFDEC_XML (node
)->xml_decl
);
914 if (SWFDEC_XML (node
)->doc_type_decl
!= NULL
)
915 string
= g_string_append (string
, SWFDEC_XML (node
)->doc_type_decl
);
918 switch (node
->type
) {
919 case SWFDEC_XML_NODE_ELEMENT
:
921 SwfdecXmlNode
*child
;
925 if (node
->name
== NULL
) {
932 string
= g_string_append (string
, "<");
933 string
= g_string_append (string
, node
->name
);
935 swfdec_as_object_foreach (node
->attributes
,
936 swfdec_xml_node_foreach_string_append_attribute
, &string
);
939 num
= swfdec_xml_node_num_children (node
);
943 string
= g_string_append (string
, ">");
945 for (i
= 0; i
< num
; i
++) {
946 child
= swfdec_xml_node_get_child (node
, i
);
947 g_assert (child
!= NULL
);
948 string
= g_string_append (string
, swfdec_xml_node_toString (child
));
952 string
= g_string_append (string
, "</");
953 string
= g_string_append (string
, node
->name
);
954 string
= g_string_append (string
, ">");
958 string
= g_string_append (string
, " />");
963 case SWFDEC_XML_NODE_TEXT
:
966 char *escaped
= swfdec_xml_escape (node
->value
);
967 string
= g_string_append (string
, escaped
);
973 return swfdec_as_context_give_string (swfdec_gc_object_get_context (node
),
974 g_string_free (string
, FALSE
));
977 SWFDEC_AS_NATIVE (253, 6, swfdec_xml_node_do_toString
)
979 swfdec_xml_node_do_toString (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
980 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
984 SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE
, &node
, "");
986 if (!SWFDEC_IS_VALID_XML_NODE (node
))
989 SWFDEC_AS_VALUE_SET_STRING (ret
, swfdec_xml_node_toString (node
));
993 swfdec_xml_node_init_values (SwfdecXmlNode
*node
, int type
, const char* value
)
997 g_return_if_fail (SWFDEC_IS_XML_NODE (node
));
998 g_return_if_fail (value
!= NULL
);
1000 cx
= swfdec_gc_object_get_context (node
);
1003 node
->parent
= NULL
;
1004 node
->children
= swfdec_as_array_new (cx
);
1005 node
->attributes
= swfdec_as_object_new_empty (cx
);
1007 if (node
->type
== SWFDEC_XML_NODE_ELEMENT
) {
1010 node
->value
= value
;
1013 node
->child_nodes
= swfdec_as_array_new (cx
);
1017 swfdec_xml_node_init_properties (SwfdecAsContext
*cx
)
1020 SwfdecAsObject
*node
, *proto
;
1022 // FIXME: We should only initialize if the prototype Object has not been
1023 // initialized by any object's constructor with native properties
1024 // (TextField, TextFormat, XML, XMLNode at least)
1026 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (cx
));
1028 swfdec_as_object_get_variable (cx
->global
, SWFDEC_AS_STR_XMLNode
, &val
);
1029 if (!SWFDEC_AS_VALUE_IS_OBJECT (val
))
1031 node
= SWFDEC_AS_VALUE_GET_OBJECT (val
);
1033 swfdec_as_object_get_variable (node
, SWFDEC_AS_STR_prototype
, &val
);
1034 if (!SWFDEC_AS_VALUE_IS_OBJECT (val
))
1036 proto
= SWFDEC_AS_VALUE_GET_OBJECT (val
);
1038 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_nodeType
,
1039 swfdec_xml_node_get_nodeType
, NULL
);
1040 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_nodeValue
,
1041 swfdec_xml_node_get_nodeValue
, swfdec_xml_node_set_nodeValue
);
1042 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_nodeName
,
1043 swfdec_xml_node_get_nodeName
, swfdec_xml_node_set_nodeName
);
1044 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_prefix
,
1045 swfdec_xml_node_do_get_prefix
, NULL
);
1046 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_localName
,
1047 swfdec_xml_node_get_localName
, NULL
);
1048 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_namespaceURI
,
1049 swfdec_xml_node_get_namespaceURI
, NULL
);
1050 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_attributes
,
1051 swfdec_xml_node_get_attributes
, NULL
);
1052 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_parentNode
,
1053 swfdec_xml_node_get_parentNode
, NULL
);
1054 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_previousSibling
,
1055 swfdec_xml_node_get_previousSibling
, NULL
);
1056 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_nextSibling
,
1057 swfdec_xml_node_get_nextSibling
, NULL
);
1058 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_firstChild
,
1059 swfdec_xml_node_get_firstChild
, NULL
);
1060 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_lastChild
,
1061 swfdec_xml_node_get_lastChild
, NULL
);
1062 swfdec_as_object_add_native_variable (proto
, SWFDEC_AS_STR_childNodes
,
1063 swfdec_xml_node_get_childNodes
, NULL
);
1067 swfdec_xml_node_new_no_properties (SwfdecAsContext
*context
,
1068 SwfdecXmlNodeType type
, const char* value
)
1070 SwfdecXmlNode
*node
;
1071 SwfdecAsObject
*object
;
1073 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
1074 g_return_val_if_fail (value
!= NULL
, NULL
);
1076 object
= swfdec_as_object_new (context
, NULL
);
1077 swfdec_as_object_set_constructor_by_name (object
,
1078 SWFDEC_AS_STR_XMLNode
, NULL
);
1080 node
= g_object_new (SWFDEC_TYPE_XML_NODE
, "context", context
, NULL
);
1081 swfdec_as_object_set_relay (object
, SWFDEC_AS_RELAY (node
));
1082 swfdec_xml_node_init_values (node
, type
, value
);
1088 swfdec_xml_node_new (SwfdecAsContext
*context
, SwfdecXmlNodeType type
,
1091 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
1093 swfdec_xml_node_init_properties (context
);
1095 return swfdec_xml_node_new_no_properties (context
, type
, value
);
1098 SWFDEC_AS_NATIVE (253, 0, swfdec_xml_node_construct
)
1100 swfdec_xml_node_construct (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
1101 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*ret
)
1103 SwfdecXmlNode
*node
;
1107 if (!swfdec_as_context_is_constructing (cx
))
1110 SWFDEC_AS_CHECK (0, NULL
, "is", &type
, &value
);
1112 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]) ||
1113 SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[1]))
1116 swfdec_xml_node_init_properties (cx
);
1118 node
= g_object_new (SWFDEC_TYPE_XML_NODE
, "context", cx
, NULL
);
1119 swfdec_as_object_set_relay (object
, SWFDEC_AS_RELAY (node
));
1120 swfdec_xml_node_init_values (node
, type
, value
);
1122 SWFDEC_AS_VALUE_SET_OBJECT (ret
, object
);