]> gitweb.michael.orlitzky.com - libsvgtiny.git/commitdiff
src/svgtiny_css.c: add user handler function
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 17 Oct 2023 15:35:13 +0000 (11:35 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Mon, 9 Jun 2025 01:13:06 +0000 (21:13 -0400)
This function needs to be passed to dom_node_set_user_data() in
set_libcss_node_data(), but we couldn't implement it before our
css_select_handler was defined, because it passes the address of
that select handler to css_libcss_node_data_handler().

src/svgtiny_css.c

index e24bd0b6e1aedb11da1845a7295a86b49424e067..f86e3dac74eaefe29044f591b86888ecc67afae7 100644 (file)
@@ -1858,6 +1858,59 @@ css_error ua_default_for_property(void *pw, uint32_t property,
 }
 
 
+/**
+ * A "user handler" function that we pass to dom_node_set_user_data()
+ * in set_libcss_node_data(). The set_libcss_node_data() documentation
+ * says that if the node (on which data is set) is is deleted or
+ * cloned, or if its ancestors are modified, then we must call
+ * css_libcss_node_data_handler() on the user data. This function
+ * basically just checks to see which DOM event has happened and
+ * calls css_libcss_node_data_handler() when any of those criteria
+ * are met.
+ */
+static void svgtiny_dom_user_data_handler(dom_node_operation operation,
+       dom_string *key, void *data, struct dom_node *src,
+       struct dom_node *dst)
+{
+       /* Technically we should compare "key" against the one used in
+        * get/set_libcss_node_data(), but at the moment libcss is the
+        * only user of this libdom feature, and eliding the compare
+        * saves us the trouble of figuring out how to reference that
+        * interned_userdata_key from this handler. */
+       UNUSED(key);
+
+       if (data == NULL) {
+               /* No data */
+               return;
+       }
+
+       /* Check the DOM operation, and make the corresponding call to
+        * css_libcss_node_data_handler(). No error handling is done.
+        */
+       switch (operation) {
+               case DOM_NODE_CLONED:
+                       css_libcss_node_data_handler(&svgtiny_select_handler,
+                                               CSS_NODE_CLONED,
+                                               NULL, src, dst, data);
+                       break;
+               case DOM_NODE_RENAMED:
+                       css_libcss_node_data_handler(&svgtiny_select_handler,
+                                               CSS_NODE_MODIFIED,
+                                               NULL, src, NULL, data);
+                       break;
+               case DOM_NODE_IMPORTED:
+               case DOM_NODE_ADOPTED:
+               case DOM_NODE_DELETED:
+                       css_libcss_node_data_handler(&svgtiny_select_handler,
+                                               CSS_NODE_DELETED,
+                                               NULL, src, NULL, data);
+                       break;
+               default:
+                       /* Our list of cases should have been exhaustive */
+                       assert(false);
+       }
+}
+
 /**
  * Store libcss data on a node
  *
@@ -1869,13 +1922,15 @@ css_error ua_default_for_property(void *pw, uint32_t property,
  * \param node               Libdom SVG node on which to store the data
  * \param libcss_node_data   Pointer to the data to store
  *
- * \return Always returns CSS_OK
+ * \return CSS_OK on success, CSS_NOMEM if libdom runs out of memory,
+ *         or CSS_INVALID if any other error occurs
  */
 css_error set_libcss_node_data(void *pw, void *node,
                void *libcss_node_data)
 {
        struct svgtiny_parse_state *state;
        void *old_data;
+       dom_exception err;
 
        /* A unique "userdata key" (a string) is used to identify this
         * data. The fourth parameter (NULL) is a "user handler
@@ -1883,13 +1938,20 @@ css_error set_libcss_node_data(void *pw, void *node,
         * it to NULL to avoid a circular reference mess that would
         * break the build temporarily. */
        state = (struct svgtiny_parse_state *)pw;
-       dom_node_set_user_data((dom_node *)node,
-                               state->interned_userdata_key,
-                               libcss_node_data,
-                               NULL,
-                               &old_data);
 
-       /* dom_node_set_user_data() always returns DOM_NO_ERR */
+       err = dom_node_set_user_data((dom_node *)node,
+                                       state->interned_userdata_key,
+                                       libcss_node_data,
+                                       NULL,
+                                       &old_data);
+
+       if (err == DOM_NO_MEM_ERR) {
+               return CSS_NOMEM;
+       }
+       else if (err != DOM_NO_ERR) {
+               return CSS_INVALID;
+       }
+
        return CSS_OK;
 }