# HG changeset patch
# Node ID 3db354e62dd1
# Parent  8747bf715804
diff --git a/xeme/tests/testextension.c b/xeme/tests/testextension.c
--- a/xeme/tests/testextension.c
+++ b/xeme/tests/testextension.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Xeme Developers
+ * Copyright (C) 2023-2024 Xeme Developers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,24 +25,18 @@
 static void
 test_xeme_extension_properties(void) {
 	XemeExtension *extension = NULL;
-	char *element = NULL;
 	char *namespace = NULL;
 
 	extension = g_object_new(
 		XEME_TYPE_EXTENSION,
-		"element", "element1",
 		"namespace", "namespace1",
 		NULL);
 
 	g_object_get(
 		G_OBJECT(extension),
-		"element", &element,
 		"namespace", &namespace,
 		NULL);
 
-	g_assert_cmpstr(element, ==, "element1");
-	g_clear_pointer(&element, g_free);
-
 	g_assert_cmpstr(namespace, ==, "namespace1");
 	g_clear_pointer(&namespace, g_free);
 
@@ -68,12 +62,14 @@
 
 static void
 test_xeme_extension_normal_parse_start(XemeExtension *extension,
+                                       const char *element_name,
                                        XemeInputStream *input,
                                        GMarkupParseContext *context)
 {
 	TestXemeExtensionNormal *normal = NULL;
 
 	g_assert_true(TEST_XEME_IS_EXTENSION_NORMAL(extension));
+	g_assert_cmpstr(element_name, ==, "element1");
 	g_assert_true(XEME_IS_INPUT_STREAM(input));
 	g_assert_nonnull(context);
 
@@ -85,11 +81,15 @@
 
 static void
 test_xeme_extension_normal_parse_end(XemeExtension *extension,
+                                     const char *element_name,
+                                     XemeInputStream *stream,
                                      GMarkupParseContext *context)
 {
 	TestXemeExtensionNormal *normal = NULL;
 
 	g_assert_true(TEST_XEME_IS_EXTENSION_NORMAL(extension));
+	g_assert_cmpstr(element_name, ==, "element1");
+	g_assert_true(XEME_IS_INPUT_STREAM(stream));
 	g_assert_nonnull(context);
 
 	normal = TEST_XEME_EXTENSION_NORMAL(extension);
@@ -146,12 +146,14 @@
 
 	input = xeme_input_stream_new();
 
-	xeme_extension_parse_start(XEME_EXTENSION(extension), input, context);
+	xeme_extension_parse_start(XEME_EXTENSION(extension), "element1", input,
+	                           context);
 	g_assert_cmpuint(extension->parse_start, ==, 1);
 	g_assert_cmpuint(extension->parse_end, ==, 0);
 	g_assert_cmpuint(extension->serialize, ==, 0);
 
-	xeme_extension_parse_end(XEME_EXTENSION(extension), context);
+	xeme_extension_parse_end(XEME_EXTENSION(extension), "element1", input,
+	                         context);
 	g_assert_cmpuint(extension->parse_start, ==, 1);
 	g_assert_cmpuint(extension->parse_end, ==, 1);
 	g_assert_cmpuint(extension->serialize, ==, 0);
diff --git a/xeme/tests/testextensionmap.c b/xeme/tests/testextensionmap.c
--- a/xeme/tests/testextensionmap.c
+++ b/xeme/tests/testextensionmap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Xeme Developers
+ * Copyright (C) 2023-2024 Xeme Developers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -34,7 +34,6 @@
 
 	extension = g_object_new(
 		XEME_TYPE_EXTENSION,
-		"element", "foobar",
 		"namespace", "baz",
 		NULL);
 
@@ -44,12 +43,12 @@
 	g_assert_cmpuint(xeme_extension_map_get_size(map), ==, 1);
 
 	/* Look up the extension we added. */
-	lookup = xeme_extension_map_lookup(map, "foobar", "baz");
+	lookup = xeme_extension_map_lookup(map, "baz");
 	g_assert_true(XEME_IS_EXTENSION(lookup));
 	g_assert_true(lookup == extension);
 
 	/* Look up a fake extension. */
-	lookup = xeme_extension_map_lookup(map, "pidgy", "pie");
+	lookup = xeme_extension_map_lookup(map, "pie");
 	g_assert_null(lookup);
 
 	/* Remove our extension. */
@@ -58,7 +57,7 @@
 	g_assert_cmpuint(xeme_extension_map_get_size(map), ==, 0);
 
 	/* Make sure our extension is gone. */
-	lookup = xeme_extension_map_lookup(map, "foobar", "baz");
+	lookup = xeme_extension_map_lookup(map, "baz");
 	g_assert_null(lookup);
 
 	/* Cleanup. */
@@ -80,12 +79,14 @@
 
 static void
 test_xeme_extension_parse_start(XemeExtension *extension,
+                                const char *element_name,
                                 XemeInputStream *input,
                                 GMarkupParseContext *context)
 {
 	TestXemeExtension *test_extension = NULL;
 
 	g_assert_true(TEST_XEME_IS_EXTENSION(extension));
+	g_assert_cmpstr(element_name, ==, "foobar");
 	g_assert_true(XEME_IS_INPUT_STREAM(input));
 	g_assert_nonnull(context);
 
@@ -157,7 +158,6 @@
 
 	extension = g_object_new(
 		test_xeme_extension_get_type(),
-		"element", "foobar",
 		"namespace", "baz",
 		NULL);
 	xeme_extension_map_add(map, XEME_EXTENSION(extension));
diff --git a/xeme/xemeextension.h b/xeme/xemeextension.h
--- a/xeme/xemeextension.h
+++ b/xeme/xemeextension.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Xeme Developers
+ * Copyright (C) 2023-2024 Xeme Developers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -49,8 +49,8 @@
 	GObjectClass parent;
 
 	/*< public >*/
-	void (*parse_start)(XemeExtension *extension, XemeInputStream *input, GMarkupParseContext *context);
-	void (*parse_end)(XemeExtension *extension, GMarkupParseContext *context);
+	void (*parse_start)(XemeExtension *extension, const char *element_name, XemeInputStream *input, GMarkupParseContext *context);
+	void (*parse_end)(XemeExtension *extension, const char *element_name, XemeInputStream *input, GMarkupParseContext *context);
 	char *(*serialize)(XemeExtension *extension);
 
 	/*< private >*/
@@ -58,17 +58,6 @@
 };
 
 /**
- * xeme_extension_get_element:
- * @extension: The instance.
- *
- * Gets the name of the element from @extension.
- *
- * Since: 0.1
- */
-XEME_AVAILABLE_IN_0_1
-const char *xeme_extension_get_element(XemeExtension *extension);
-
-/**
  * xeme_extension_get_namespace:
  * @extension: The instance.
  *
@@ -82,6 +71,7 @@
 /**
  * xeme_extension_parse_start:
  * @extension: The instance.
+ * @element_name: The name of the element that is being parsed.
  * @input: The [class@XemeInputStream] that is being parsed.
  * @context: The [struct@GLib.MarkupParseContext] of the parser.
  *
@@ -97,11 +87,13 @@
  * Since: 0.1
  */
 XEME_AVAILABLE_IN_0_1
-void xeme_extension_parse_start(XemeExtension *extension, XemeInputStream *input, GMarkupParseContext *context);
+void xeme_extension_parse_start(XemeExtension *extension, const char *element_name, XemeInputStream *input, GMarkupParseContext *context);
 
 /**
  * xeme_extension_parse_end:
  * @extension: The instance.
+ * @element_name: The name of the element that is being parsed.
+ * @input: The [class@XemeInputStream] that is being parsed.
  * @context: The [struct@GLib.MarkupParseContext] of the parser.
  *
  * Finishes a previous call to [method@XemeExtension.parse_start].
@@ -112,7 +104,7 @@
  * Since: 0.1
  */
 XEME_AVAILABLE_IN_0_1
-void xeme_extension_parse_end(XemeExtension *extension, GMarkupParseContext *context);
+void xeme_extension_parse_end(XemeExtension *extension, const char *element_name, XemeInputStream *input, GMarkupParseContext *context);
 
 /**
  * xeme_extension_serialize:
diff --git a/xeme/xemeextension.c b/xeme/xemeextension.c
--- a/xeme/xemeextension.c
+++ b/xeme/xemeextension.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Xeme Developers
+ * Copyright (C) 2023-2024 Xeme Developers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,14 +21,12 @@
 
 enum {
 	PROP_0,
-	PROP_ELEMENT,
 	PROP_NAMESPACE,
 	N_PROPERTIES,
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
 
 typedef struct {
-	char *element;
 	char *namespace;
 } XemeExtensionPrivate;
 
@@ -38,23 +36,6 @@
  * Helpers
  *****************************************************************************/
 static void
-xeme_extension_set_element(XemeExtension *extension, const char *element) {
-	XemeExtensionPrivate *priv = NULL;
-
-	g_return_if_fail(XEME_IS_EXTENSION(extension));
-
-	priv = xeme_extension_get_instance_private(extension);
-
-	if(!xeme_str_equal(priv->element, element)) {
-		g_free(priv->element);
-		priv->element = g_strdup(element);
-
-		g_object_notify_by_pspec(G_OBJECT(extension),
-		                         properties[PROP_ELEMENT]);
-	}
-}
-
-static void
 xeme_extension_set_namespace(XemeExtension *extension, const char *namespace) {
 	XemeExtensionPrivate *priv = NULL;
 
@@ -81,7 +62,6 @@
 
 	priv = xeme_extension_get_instance_private(extension);
 
-	g_clear_pointer(&priv->element, g_free);
 	g_clear_pointer(&priv->namespace, g_free);
 
 	G_OBJECT_CLASS(xeme_extension_parent_class)->finalize(obj);
@@ -94,9 +74,6 @@
 	XemeExtension *extension = XEME_EXTENSION(obj);
 
 	switch(param_id) {
-	case PROP_ELEMENT:
-		g_value_set_string(value, xeme_extension_get_element(extension));
-		break;
 	case PROP_NAMESPACE:
 		g_value_set_string(value, xeme_extension_get_namespace(extension));
 		break;
@@ -113,9 +90,6 @@
 	XemeExtension *extension = XEME_EXTENSION(obj);
 
 	switch(param_id) {
-	case PROP_ELEMENT:
-		xeme_extension_set_element(extension, g_value_get_string(value));
-		break;
 	case PROP_NAMESPACE:
 		xeme_extension_set_namespace(extension, g_value_get_string(value));
 		break;
@@ -138,19 +112,6 @@
 	obj_class->set_property = xeme_extension_set_property;
 
 	/**
-	 * XemeExtension:element:
-	 *
-	 * The name of the element that's being extended.
-	 *
-	 * Since: 0.1
-	 */
-	properties[PROP_ELEMENT] = g_param_spec_string(
-		"element", "element",
-		"The name of the element that's being extended.",
-		NULL,
-		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-	/**
 	 * XemeExtension:namespace:
 	 *
 	 * The namespace of the extension.
@@ -170,17 +131,6 @@
  * Public API
  *****************************************************************************/
 const char *
-xeme_extension_get_element(XemeExtension *extension) {
-	XemeExtensionPrivate *priv = NULL;
-
-	g_return_val_if_fail(XEME_IS_EXTENSION(extension), NULL);
-
-	priv = xeme_extension_get_instance_private(extension);
-
-	return priv->element;
-}
-
-const char *
 xeme_extension_get_namespace(XemeExtension *extension) {
 	XemeExtensionPrivate *priv = NULL;
 
@@ -192,33 +142,36 @@
 }
 
 void
-xeme_extension_parse_start(XemeExtension *extension, XemeInputStream *input,
-                           GMarkupParseContext *context)
+xeme_extension_parse_start(XemeExtension *extension, const char *element_name,
+                           XemeInputStream *input, GMarkupParseContext *context)
 {
 	XemeExtensionClass *klass = NULL;
 
 	g_return_if_fail(XEME_IS_EXTENSION(extension));
+	g_return_if_fail(!xeme_str_is_empty(element_name));
 	g_return_if_fail(XEME_IS_INPUT_STREAM(input));
 	g_return_if_fail(context != NULL);
 
 	klass = XEME_EXTENSION_GET_CLASS(extension);
 	if(klass != NULL && klass->parse_start != NULL) {
-		klass->parse_start(extension, input, context);
+		klass->parse_start(extension, element_name, input, context);
 	}
 }
 
 void
-xeme_extension_parse_end(XemeExtension *extension,
-                         GMarkupParseContext *context)
+xeme_extension_parse_end(XemeExtension *extension, const char *element_name,
+                         XemeInputStream *input, GMarkupParseContext *context)
 {
 	XemeExtensionClass *klass = NULL;
 
 	g_return_if_fail(XEME_IS_EXTENSION(extension));
+	g_return_if_fail(!xeme_str_is_empty(element_name));
+	g_return_if_fail(XEME_IS_INPUT_STREAM(input));
 	g_return_if_fail(context != NULL);
 
 	klass = XEME_EXTENSION_GET_CLASS(extension);
 	if(klass != NULL && klass->parse_end != NULL) {
-		klass->parse_end(extension, context);
+		klass->parse_end(extension, element_name, input, context);
 	}
 }
 
diff --git a/xeme/xemeextensionmap.h b/xeme/xemeextensionmap.h
--- a/xeme/xemeextensionmap.h
+++ b/xeme/xemeextensionmap.h
@@ -84,18 +84,16 @@
 /**
  * xeme_extension_map_lookup:
  * @map: The instance.
- * @element: (not nullable): The name of the element of the extension.
- * @namespace: The namespace of the extension.
+ * @namespace: (not nullable): The namespace of the extension.
  *
- * Look if an extension matching @element and @namespace has been added to
- * @map.
+ * Look if an extension matching @namespace has been added to @map.
  *
  * Returns: (transfer none): The extension if found, otherwise %NULL.
  *
  * Since: 0.1
  */
 XEME_AVAILABLE_IN_0_1
-XemeExtension *xeme_extension_map_lookup(XemeExtensionMap *map, const char *element, const char *namespace);
+XemeExtension *xeme_extension_map_lookup(XemeExtensionMap *map, const char *namespace);
 
 /**
  * xeme_extension_map_get_size:
diff --git a/xeme/xemeextensionmap.c b/xeme/xemeextensionmap.c
--- a/xeme/xemeextensionmap.c
+++ b/xeme/xemeextensionmap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 Xeme Developers
+ * Copyright (C) 2023-2024 Xeme Developers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -63,25 +63,6 @@
 	g_clear_pointer(&data, g_free);
 }
 
-static inline char *
-xeme_extension_map_generate_key(const char *element, const char *namespace) {
-	return g_strconcat(element, XEME_EXTENSION_MAP_DELIMITER, namespace, NULL);
-}
-
-static inline char *
-xeme_extension_map_generate_key_from_extension(XemeExtension *extension) {
-	const char *element = NULL;
-	const char *namespace = NULL;
-
-	element = xeme_extension_get_element(extension);
-	g_return_val_if_fail(!xeme_str_is_empty(element), NULL);
-
-	namespace = xeme_extension_get_namespace(extension);
-	g_return_val_if_fail(!xeme_str_is_empty(namespace), NULL);
-
-	return xeme_extension_map_generate_key(element, namespace);
-}
-
 /******************************************************************************
  * Parser
  *****************************************************************************/
@@ -107,7 +88,7 @@
 		return;
 	}
 
-	extension = xeme_extension_map_lookup(data->map, element_name, namespace);
+	extension = xeme_extension_map_lookup(data->map, namespace);
 	if(!XEME_IS_EXTENSION(extension)) {
 		g_message("unknown extension element '%s' with namespace '%s'",
 		          element_name, namespace);
@@ -115,12 +96,12 @@
 	}
 
 	g_set_object(&data->extension, extension);
-	xeme_extension_parse_start(extension, data->input, context);
+	xeme_extension_parse_start(extension, element_name, data->input, context);
 }
 
 static void
 xeme_extension_map_parser_element_end(GMarkupParseContext *context,
-                                      G_GNUC_UNUSED const char *element_name,
+                                      const char *element_name,
                                       gpointer user_data,
                                       G_GNUC_UNUSED GError **error)
 {
@@ -131,7 +112,8 @@
 		return;
 	}
 
-	xeme_extension_parse_end(data->extension, context);
+	xeme_extension_parse_end(data->extension, element_name, data->input,
+	                         context);
 	g_clear_object(&data->extension);
 }
 
@@ -175,50 +157,37 @@
 
 gboolean
 xeme_extension_map_add(XemeExtensionMap *map, XemeExtension *extension) {
-	char *key = NULL;
-
-	g_return_val_if_fail(XEME_IS_EXTENSION_MAP(map), FALSE);
-	g_return_val_if_fail(XEME_IS_EXTENSION(extension), FALSE);
-
-	key = xeme_extension_map_generate_key_from_extension(extension);
-	g_return_val_if_fail(key != NULL, FALSE);
-
-	return g_hash_table_insert(map->extensions, key, g_object_ref(extension));
-}
-
-gboolean
-xeme_extension_map_remove(XemeExtensionMap *map, XemeExtension *extension) {
-	char *key = NULL;
-	gboolean ret = FALSE;
+	const char *namespace = NULL;
 
 	g_return_val_if_fail(XEME_IS_EXTENSION_MAP(map), FALSE);
 	g_return_val_if_fail(XEME_IS_EXTENSION(extension), FALSE);
 
-	key = xeme_extension_map_generate_key_from_extension(extension);
-	g_return_val_if_fail(key != NULL, FALSE);
+	namespace = xeme_extension_get_namespace(extension);
+	g_return_val_if_fail(namespace != NULL, FALSE);
+
+	return g_hash_table_insert(map->extensions, g_strdup(namespace),
+	                           g_object_ref(extension));
+}
 
-	ret = g_hash_table_remove(map->extensions, key);
-	g_free(key);
+gboolean
+xeme_extension_map_remove(XemeExtensionMap *map, XemeExtension *extension) {
+	const char *namespace = NULL;
 
-	return ret;
+	g_return_val_if_fail(XEME_IS_EXTENSION_MAP(map), FALSE);
+	g_return_val_if_fail(XEME_IS_EXTENSION(extension), FALSE);
+
+	namespace = xeme_extension_get_namespace(extension);
+	g_return_val_if_fail(namespace != NULL, FALSE);
+
+	return g_hash_table_remove(map->extensions, namespace);
 }
 
 XemeExtension *
-xeme_extension_map_lookup(XemeExtensionMap *map, const char *element,
-                          const char *namespace)
-{
-	XemeExtension *extension = NULL;
-	char *key = NULL;
-
+xeme_extension_map_lookup(XemeExtensionMap *map, const char *namespace) {
 	g_return_val_if_fail(XEME_IS_EXTENSION_MAP(map), NULL);
-	g_return_val_if_fail(!xeme_str_is_empty(element), NULL);
 	g_return_val_if_fail(!xeme_str_is_empty(namespace), NULL);
 
-	key = xeme_extension_map_generate_key(element, namespace);
-	extension = g_hash_table_lookup(map->extensions, key);
-	g_free(key);
-
-	return extension;
+	return g_hash_table_lookup(map->extensions, namespace);
 }
 
 guint
