static css_error node_has_attribute_includes(void *pw, void *node,
const css_qname *qname, lwc_string *word,
bool *match);
+static css_error node_has_attribute_prefix(void *pw, void *node,
+ const css_qname *qname, lwc_string *prefix,
+ bool *match);
/**
return CSS_OK;
}
+
+
+/**
+ * Test the given node for an attribute whose value begins with the
+ * given prefix
+ *
+ * This will return true (via the "match" pointer) if the libdom node
+ * has an attribute with the given name and whose value begins with
+ * the given prefix string. The comparison is case-sensitive. This
+ * corresponds to [attr^=value] in CSS.
+ *
+ * \param pw Pointer to the current SVG parser state
+ * \param node Libdom SVG node to test
+ * \param qname Attribute name to check for
+ * \param prefix Value prefix to check for
+ * \param match Pointer to the test result
+ *
+ * \return Returns CSS_OK if successful and CSS_NOMEM if we cannot
+ * intern the attribute name (which usually indicates memory
+ * exhaustion)
+ */
+css_error node_has_attribute_prefix(void *pw, void *node,
+ const css_qname *qname, lwc_string *prefix,
+ bool *match)
+{
+ UNUSED(pw);
+ dom_string *name;
+ dom_string *attr_val;
+ dom_exception err;
+ const char *avdata; /* attribute value data */
+ size_t avdata_len; /* length of that attribute value data */
+ size_t prefixlen; /* length of "prefix" */
+
+ prefixlen = lwc_string_length(prefix);
+ if (prefixlen == 0) {
+ /* In this case, the spec says that "if 'val' is the
+ * empty string, it will never represent anything." */
+ return CSS_OK;
+ }
+
+ /* Intern the attribute name as a dom_string so we can
+ * use dom_element_get_attribute() */
+ err = dom_string_create_interned(
+ (const uint8_t *) lwc_string_data(qname->name),
+ lwc_string_length(qname->name),
+ &name);
+ if (err != DOM_NO_ERR) {
+ return CSS_NOMEM;
+ }
+
+ err = dom_element_get_attribute((dom_node *)node, name, &attr_val);
+ if ((err != DOM_NO_ERR) || (attr_val == NULL)) {
+ /* There was an error getting the attribute's value or
+ * the attribute doesn't exist. So, no match? */
+ dom_string_unref(name);
+ *match = false;
+ return CSS_OK;
+ }
+
+ /* Otherwise, we have the attribute value from the given node,
+ * and the first thing we want to do is check to see if the
+ * whole thing matches the prefix. */
+ dom_string_unref(name);
+ *match = dom_string_lwc_isequal(attr_val, prefix);
+
+ /* If not, check to see if an, uh, prefix matches the
+ * prefix */
+ if (*match == false) {
+ avdata = dom_string_data(attr_val);
+ avdata_len = dom_string_byte_length(attr_val);
+ if ((avdata_len >= prefixlen) &&
+ (strncasecmp(avdata,
+ lwc_string_data(prefix),
+ prefixlen) == 0)) {
+ /* Use strncasecmp to compare only the first
+ * "n" characters, where "n" is the length of
+ * the prefix. */
+ *match = true;
+ }
+ }
+
+ dom_string_unref(attr_val);
+
+ return CSS_OK;
+}