summaryrefslogtreecommitdiff
path: root/css
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2015-05-03 16:10:15 +0100
committerMichael Drake <michael.drake@codethink.co.uk>2016-02-05 10:49:58 +0000
commit8e580ccd195d2b7ae896803391ef404cb3b41d3b (patch)
tree669ca709166eaefea33e9788bc6b1c398d3f8bb5 /css
parentf06ec6390a3286db180ad3fda97baab9e8b54663 (diff)
downloadnetsurf-8e580ccd195d2b7ae896803391ef404cb3b41d3b.tar.gz
netsurf-8e580ccd195d2b7ae896803391ef404cb3b41d3b.tar.bz2
Split out presentational hints handling.
Diffstat (limited to 'css')
-rw-r--r--css/Makefile2
-rw-r--r--css/hints.c1794
-rw-r--r--css/hints.h48
-rw-r--r--css/select.c1789
-rw-r--r--css/select.h6
5 files changed, 1849 insertions, 1790 deletions
diff --git a/css/Makefile b/css/Makefile
index 1280d57e1..127dbaa32 100644
--- a/css/Makefile
+++ b/css/Makefile
@@ -1,5 +1,5 @@
# CSS sources
-S_CSS := css.c dump.c internal.c select.c utils.c
+S_CSS := css.c dump.c internal.c hints.c select.c utils.c
S_CSS := $(addprefix css/,$(S_CSS))
diff --git a/css/hints.c b/css/hints.c
new file mode 100644
index 000000000..059b42bfa
--- /dev/null
+++ b/css/hints.c
@@ -0,0 +1,1794 @@
+/*
+ * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <strings.h>
+
+#include "utils/nsoption.h"
+#include "utils/corestrings.h"
+#include "utils/log.h"
+#include "utils/nsurl.h"
+#include "utils/utils.h"
+
+#include "css/hints.h"
+#include "css/select.h"
+
+/******************************************************************************
+ * Utility functions *
+ ******************************************************************************/
+
+/**
+ * Determine if a given character is whitespace
+ *
+ * \param c Character to consider
+ * \return true if character is whitespace, false otherwise
+ */
+static bool isWhitespace(char c)
+{
+ return c == ' ' || c == '\t' || c == '\f' || c == '\r' || c == '\n';
+}
+
+/**
+ * Determine if a given character is a valid hex digit
+ *
+ * \param c Character to consider
+ * \return true if character is a valid hex digit, false otherwise
+ */
+static bool isHex(char c)
+{
+ return ('0' <= c && c <= '9') ||
+ ('A' <= (c & ~0x20) && (c & ~0x20) <= 'F');
+}
+
+/**
+ * Convert a character representing a hex digit to the corresponding hex value
+ *
+ * \param c Character to convert
+ * \return Hex value represented by character
+ *
+ * \note This function assumes an ASCII-compatible character set
+ */
+static uint8_t charToHex(char c)
+{
+ /* 0-9 */
+ c -= '0';
+
+ /* A-F */
+ if (c > 9)
+ c -= 'A' - '9' - 1;
+
+ /* a-f */
+ if (c > 15)
+ c -= 'a' - 'A';
+
+ return c;
+}
+
+
+/******************************************************************************
+ * Common parsing functions *
+ ******************************************************************************/
+
+/**
+ * Parse a number string
+ *
+ * \param data Data to parse (NUL-terminated)
+ * \param maybe_negative Negative numbers permitted
+ * \param real Floating point numbers permitted
+ * \param value Pointer to location to receive numeric value
+ * \param consumed Pointer to location to receive number of input
+ * bytes consumed
+ * \return true on success, false on invalid input
+ */
+static bool parse_number(const char *data, bool maybe_negative, bool real,
+ css_fixed *value, size_t *consumed)
+{
+ size_t len;
+ const uint8_t *ptr;
+ int32_t intpart = 0;
+ int32_t fracpart = 0;
+ int32_t pwr = 1;
+ int sign = 1;
+
+ *consumed = 0;
+
+ len = strlen(data);
+ ptr = (const uint8_t *) data;
+
+ if (len == 0)
+ return false;
+
+ /* Skip leading whitespace */
+ while (len > 0 && isWhitespace(ptr[0])) {
+ len--;
+ ptr++;
+ }
+
+ if (len == 0)
+ return false;
+
+ /* Extract sign, if any */
+ if (ptr[0] == '+') {
+ len--;
+ ptr++;
+ } else if (ptr[0] == '-' && maybe_negative) {
+ sign = -1;
+ len--;
+ ptr++;
+ }
+
+ if (len == 0)
+ return false;
+
+ /* Must have a digit [0,9] */
+ if ('0' > ptr[0] || ptr[0] > '9')
+ return false;
+
+ /* Now extract intpart, assuming base 10 */
+ while (len > 0) {
+ /* Stop on first non-digit */
+ if (ptr[0] < '0' || '9' < ptr[0])
+ break;
+
+ /* Prevent overflow of 'intpart'; proper clamping below */
+ if (intpart < (1 << 22)) {
+ intpart *= 10;
+ intpart += ptr[0] - '0';
+ }
+ ptr++;
+ len--;
+ }
+
+ /* And fracpart, again, assuming base 10 */
+ if (real && len > 1 && ptr[0] == '.' &&
+ ('0' <= ptr[1] && ptr[1] <= '9')) {
+ ptr++;
+ len--;
+
+ while (len > 0) {
+ if (ptr[0] < '0' || '9' < ptr[0])
+ break;
+
+ if (pwr < 1000000) {
+ pwr *= 10;
+ fracpart *= 10;
+ fracpart += ptr[0] - '0';
+ }
+ ptr++;
+ len--;
+ }
+
+ fracpart = ((1 << 10) * fracpart + pwr/2) / pwr;
+ if (fracpart >= (1 << 10)) {
+ intpart++;
+ fracpart &= (1 << 10) - 1;
+ }
+ }
+
+ if (sign > 0) {
+ /* If the result is larger than we can represent,
+ * then clamp to the maximum value we can store. */
+ if (intpart >= (1 << 21)) {
+ intpart = (1 << 21) - 1;
+ fracpart = (1 << 10) - 1;
+ }
+ } else {
+ /* If the negated result is smaller than we can represent
+ * then clamp to the minimum value we can store. */
+ if (intpart >= (1 << 21)) {
+ intpart = -(1 << 21);
+ fracpart = 0;
+ } else {
+ intpart = -intpart;
+ if (fracpart) {
+ fracpart = (1 << 10) - fracpart;
+ intpart--;
+ }
+ }
+ }
+
+ *value = (intpart << 10) | fracpart;
+
+ *consumed = ptr - (const uint8_t *) data;
+
+ return true;
+}
+
+/**
+ * Parse a dimension string
+ *
+ * \param data Data to parse (NUL-terminated)
+ * \param strict Whether to enforce strict parsing rules
+ * \param length Pointer to location to receive dimension's length
+ * \param unit Pointer to location to receive dimension's unit
+ * \return true on success, false on invalid input
+ */
+static bool parse_dimension(const char *data, bool strict, css_fixed *length,
+ css_unit *unit)
+{
+ size_t len;
+ size_t read;
+ css_fixed value;
+
+ len = strlen(data);
+
+ if (parse_number(data, false, true, &value, &read) == false)
+ return false;
+
+ if (strict && value < INTTOFIX(1))
+ return false;
+
+ *length = value;
+
+ if (len > read && data[read] == '%')
+ *unit = CSS_UNIT_PCT;
+ else
+ *unit = CSS_UNIT_PX;
+
+ return true;
+}
+
+/**
+ * Mapping of colour name to CSS color
+ */
+struct colour_map {
+ const char *name;
+ css_color color;
+};
+
+/**
+ * Name comparator for named colour matching
+ *
+ * \param a Name to match
+ * \param b Colour map entry to consider
+ * \return 0 on match,
+ * < 0 if a < b,
+ * > 0 if b > a.
+ */
+static int cmp_colour_name(const void *a, const void *b)
+{
+ const char *aa = a;
+ const struct colour_map *bb = b;
+
+ return strcasecmp(aa, bb->name);
+}
+
+/**
+ * Parse a named colour
+ *
+ * \param name Name to parse
+ * \param result Pointer to location to receive css_color
+ * \return true on success, false on invalid input
+ */
+static bool parse_named_colour(const char *name, css_color *result)
+{
+ static const struct colour_map named_colours[] = {
+ { "aliceblue", 0xfff0f8ff },
+ { "antiquewhite", 0xfffaebd7 },
+ { "aqua", 0xff00ffff },
+ { "aquamarine", 0xff7fffd4 },
+ { "azure", 0xfff0ffff },
+ { "beige", 0xfff5f5dc },
+ { "bisque", 0xffffe4c4 },
+ { "black", 0xff000000 },
+ { "blanchedalmond", 0xffffebcd },
+ { "blue", 0xff0000ff },
+ { "blueviolet", 0xff8a2be2 },
+ { "brown", 0xffa52a2a },
+ { "burlywood", 0xffdeb887 },
+ { "cadetblue", 0xff5f9ea0 },
+ { "chartreuse", 0xff7fff00 },
+ { "chocolate", 0xffd2691e },
+ { "coral", 0xffff7f50 },
+ { "cornflowerblue", 0xff6495ed },
+ { "cornsilk", 0xfffff8dc },
+ { "crimson", 0xffdc143c },
+ { "cyan", 0xff00ffff },
+ { "darkblue", 0xff00008b },
+ { "darkcyan", 0xff008b8b },
+ { "darkgoldenrod", 0xffb8860b },
+ { "darkgray", 0xffa9a9a9 },
+ { "darkgreen", 0xff006400 },
+ { "darkgrey", 0xffa9a9a9 },
+ { "darkkhaki", 0xffbdb76b },
+ { "darkmagenta", 0xff8b008b },
+ { "darkolivegreen", 0xff556b2f },
+ { "darkorange", 0xffff8c00 },
+ { "darkorchid", 0xff9932cc },
+ { "darkred", 0xff8b0000 },
+ { "darksalmon", 0xffe9967a },
+ { "darkseagreen", 0xff8fbc8f },
+ { "darkslateblue", 0xff483d8b },
+ { "darkslategray", 0xff2f4f4f },
+ { "darkslategrey", 0xff2f4f4f },
+ { "darkturquoise", 0xff00ced1 },
+ { "darkviolet", 0xff9400d3 },
+ { "deeppink", 0xffff1493 },
+ { "deepskyblue", 0xff00bfff },
+ { "dimgray", 0xff696969 },
+ { "dimgrey", 0xff696969 },
+ { "dodgerblue", 0xff1e90ff },
+ { "feldspar", 0xffd19275 },
+ { "firebrick", 0xffb22222 },
+ { "floralwhite", 0xfffffaf0 },
+ { "forestgreen", 0xff228b22 },
+ { "fuchsia", 0xffff00ff },
+ { "gainsboro", 0xffdcdcdc },
+ { "ghostwhite", 0xfff8f8ff },
+ { "gold", 0xffffd700 },
+ { "goldenrod", 0xffdaa520 },
+ { "gray", 0xff808080 },
+ { "green", 0xff008000 },
+ { "greenyellow", 0xffadff2f },
+ { "grey", 0xff808080 },
+ { "honeydew", 0xfff0fff0 },
+ { "hotpink", 0xffff69b4 },
+ { "indianred", 0xffcd5c5c },
+ { "indigo", 0xff4b0082 },
+ { "ivory", 0xfffffff0 },
+ { "khaki", 0xfff0e68c },
+ { "lavender", 0xffe6e6fa },
+ { "lavenderblush", 0xfffff0f5 },
+ { "lawngreen", 0xff7cfc00 },
+ { "lemonchiffon", 0xfffffacd },
+ { "lightblue", 0xffadd8e6 },
+ { "lightcoral", 0xfff08080 },
+ { "lightcyan", 0xffe0ffff },
+ { "lightgoldenrodyellow", 0xfffafad2 },
+ { "lightgray", 0xffd3d3d3 },
+ { "lightgreen", 0xff90ee90 },
+ { "lightgrey", 0xffd3d3d3 },
+ { "lightpink", 0xffffb6c1 },
+ { "lightsalmon", 0xffffa07a },
+ { "lightseagreen", 0xff20b2aa },
+ { "lightskyblue", 0xff87cefa },
+ { "lightslateblue", 0xff8470ff },
+ { "lightslategray", 0xff778899 },
+ { "lightslategrey", 0xff778899 },
+ { "lightsteelblue", 0xffb0c4de },
+ { "lightyellow", 0xffffffe0 },
+ { "lime", 0xff00ff00 },
+ { "limegreen", 0xff32cd32 },
+ { "linen", 0xfffaf0e6 },
+ { "magenta", 0xffff00ff },
+ { "maroon", 0xff800000 },
+ { "mediumaquamarine", 0xff66cdaa },
+ { "mediumblue", 0xff0000cd },
+ { "mediumorchid", 0xffba55d3 },
+ { "mediumpurple", 0xff9370db },
+ { "mediumseagreen", 0xff3cb371 },
+ { "mediumslateblue", 0xff7b68ee },
+ { "mediumspringgreen", 0xff00fa9a },
+ { "mediumturquoise", 0xff48d1cc },
+ { "mediumvioletred", 0xffc71585 },
+ { "midnightblue", 0xff191970 },
+ { "mintcream", 0xfff5fffa },
+ { "mistyrose", 0xffffe4e1 },
+ { "moccasin", 0xffffe4b5 },
+ { "navajowhite", 0xffffdead },
+ { "navy", 0xff000080 },
+ { "oldlace", 0xfffdf5e6 },
+ { "olive", 0xff808000 },
+ { "olivedrab", 0xff6b8e23 },
+ { "orange", 0xffffa500 },
+ { "orangered", 0xffff4500 },
+ { "orchid", 0xffda70d6 },
+ { "palegoldenrod", 0xffeee8aa },
+ { "palegreen", 0xff98fb98 },
+ { "paleturquoise", 0xffafeeee },
+ { "palevioletred", 0xffdb7093 },
+ { "papayawhip", 0xffffefd5 },
+ { "peachpuff", 0xffffdab9 },
+ { "peru", 0xffcd853f },
+ { "pink", 0xffffc0cb },
+ { "plum", 0xffdda0dd },
+ { "powderblue", 0xffb0e0e6 },
+ { "purple", 0xff800080 },
+ { "red", 0xffff0000 },
+ { "rosybrown", 0xffbc8f8f },
+ { "royalblue", 0xff4169e1 },
+ { "saddlebrown", 0xff8b4513 },
+ { "salmon", 0xfffa8072 },
+ { "sandybrown", 0xfff4a460 },
+ { "seagreen", 0xff2e8b57 },
+ { "seashell", 0xfffff5ee },
+ { "sienna", 0xffa0522d },
+ { "silver", 0xffc0c0c0 },
+ { "skyblue", 0xff87ceeb },
+ { "slateblue", 0xff6a5acd },
+ { "slategray", 0xff708090 },
+ { "slategrey", 0xff708090 },
+ { "snow", 0xfffffafa },
+ { "springgreen", 0xff00ff7f },
+ { "steelblue", 0xff4682b4 },
+ { "tan", 0xffd2b48c },
+ { "teal", 0xff008080 },
+ { "thistle", 0xffd8bfd8 },
+ { "tomato", 0xffff6347 },
+ { "turquoise", 0xff40e0d0 },
+ { "violet", 0xffee82ee },
+ { "violetred", 0xffd02090 },
+ { "wheat", 0xfff5deb3 },
+ { "white", 0xffffffff },
+ { "whitesmoke", 0xfff5f5f5 },
+ { "yellow", 0xffffff00 },
+ { "yellowgreen", 0xff9acd32 }
+ };
+ const struct colour_map *entry;
+
+ entry = bsearch(name, named_colours,
+ sizeof(named_colours) / sizeof(named_colours[0]),
+ sizeof(named_colours[0]),
+ cmp_colour_name);
+
+ if (entry != NULL)
+ *result = entry->color;
+
+ return entry != NULL;
+}
+
+/**
+ * Parser for colours specified in attribute values.
+ *
+ * \param data Data to parse (NUL-terminated)
+ * \param result Pointer to location to receive resulting css_color
+ * \return true on success, false on invalid input
+ */
+bool nscss_parse_colour(const char *data, css_color *result)
+{
+ size_t len = strlen(data);
+ uint8_t r, g, b;
+
+ /* 2 */
+ if (len == 0)
+ return false;
+
+ /* 3 */
+ if (len == SLEN("transparent") && strcasecmp(data, "transparent") == 0)
+ return false;
+
+ /* 4 */
+ if (parse_named_colour(data, result))
+ return true;
+
+ /** \todo Implement HTML5's utterly insane legacy colour parsing */
+
+ if (data[0] == '#') {
+ data++;
+ len--;
+ }
+
+ if (len == 3 && isHex(data[0]) && isHex(data[1]) && isHex(data[2])) {
+ r = charToHex(data[0]);
+ g = charToHex(data[1]);
+ b = charToHex(data[2]);
+
+ r |= (r << 4);
+ g |= (g << 4);
+ b |= (b << 4);
+
+ *result = (0xff << 24) | (r << 16) | (g << 8) | b;
+
+ return true;
+ } else if (len == 6 && isHex(data[0]) && isHex(data[1]) &&
+ isHex(data[2]) && isHex(data[3]) && isHex(data[4]) &&
+ isHex(data[5])) {
+ r = (charToHex(data[0]) << 4) | charToHex(data[1]);
+ g = (charToHex(data[2]) << 4) | charToHex(data[3]);
+ b = (charToHex(data[4]) << 4) | charToHex(data[5]);
+
+ *result = (0xff << 24) | (r << 16) | (g << 8) | b;
+
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Parse a font \@size attribute
+ *
+ * \param size Data to parse (NUL-terminated)
+ * \param val Pointer to location to receive enum value
+ * \param len Pointer to location to receive length
+ * \param unit Pointer to location to receive unit
+ * \return True on success, false on failure
+ */
+static bool parse_font_size(const char *size, uint8_t *val,
+ css_fixed *len, css_unit *unit)
+{
+ static const uint8_t size_map[] = {
+ CSS_FONT_SIZE_XX_SMALL,
+ CSS_FONT_SIZE_SMALL,
+ CSS_FONT_SIZE_MEDIUM,
+ CSS_FONT_SIZE_LARGE,
+ CSS_FONT_SIZE_X_LARGE,
+ CSS_FONT_SIZE_XX_LARGE,
+ CSS_FONT_SIZE_DIMENSION /* xxx-large (see below) */
+ };
+
+ const char *p = size;
+ char mode;
+ int value = 0;
+
+ /* Skip whitespace */
+ while (*p != '\0' && isWhitespace(*p))
+ p++;
+
+ mode = *p;
+
+ /* Skip +/- */
+ if (mode == '+' || mode == '-')
+ p++;
+
+ /* Need at least one digit */
+ if (*p < '0' || *p > '9') {
+ return false;
+ }
+
+ /* Consume digits, computing value */
+ while ('0' <= *p && *p <= '9') {
+ value = value * 10 + (*p - '0');
+ p++;
+ }
+
+ /* Resolve relative sizes */
+ if (mode == '+')
+ value += 3;
+ else if (mode == '-')
+ value = 3 - value;
+
+ /* Clamp to range [1,7] */
+ if (value < 1)
+ value = 1;
+ else if (value > 7)
+ value = 7;
+
+ if (value == 7) {
+ /* Manufacture xxx-large */
+ *len = FDIV(FMUL(INTTOFIX(3), INTTOFIX(nsoption_int(font_size))),
+ F_10);
+ } else {
+ /* Len is irrelevant */
+ *len = 0;
+ }
+
+ *unit = CSS_UNIT_PT;
+ *val = size_map[value - 1];
+
+ return true;
+}
+
+
+/******************************************************************************
+ * Presentational hint handlers *
+ ******************************************************************************/
+
+static css_error node_presentational_hint_vertical_align(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *valign = NULL;
+ dom_exception err;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_col) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_thead) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tbody) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tfoot) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_valign, &valign);
+ if (err != DOM_NO_ERR || valign == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_top)) {
+ hint->status = CSS_VERTICAL_ALIGN_TOP;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_middle)) {
+ hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_bottom)) {
+ hint->status = CSS_VERTICAL_ALIGN_BOTTOM;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_baseline)) {
+ hint->status = CSS_VERTICAL_ALIGN_BASELINE;
+ } else {
+ dom_string_unref(valign);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(valign);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_applet) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_embed) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_iframe) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_object)) {
+ /** \todo input[type=image][align=*] - $11.3.3 */
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &valign);
+ if (err != DOM_NO_ERR || valign == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_top)) {
+ hint->status = CSS_VERTICAL_ALIGN_TOP;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_bottom) ||
+ dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_baseline)) {
+ hint->status = CSS_VERTICAL_ALIGN_BASELINE;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_texttop)) {
+ hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP;
+ } else if (dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_absmiddle) ||
+ dom_string_caseless_lwc_isequal(valign,
+ corestring_lwc_abscenter)) {
+ hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
+ } else {
+ dom_string_unref(valign);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(valign);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ }
+
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_text_align(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *align = NULL;
+ dom_exception err;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_p) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h1) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h2) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h3) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h4) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h5) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_h6)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &align);
+ if (err != DOM_NO_ERR || align == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_TEXT_ALIGN_LEFT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_CENTER;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_TEXT_ALIGN_RIGHT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_justify)) {
+ hint->status = CSS_TEXT_ALIGN_JUSTIFY;
+ } else {
+ dom_string_unref(align);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(align);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
+
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_caption)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &align);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (align == NULL || dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_justify)) {
+ hint->status = CSS_TEXT_ALIGN_JUSTIFY;
+ } else {
+ dom_string_unref(align);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (align != NULL)
+ dom_string_unref(align);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_div) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_thead) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_tbody) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_tfoot) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_tr) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_th)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_align, &align);
+ if (err != DOM_NO_ERR || align == NULL) {
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_center)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_justify)) {
+ hint->status = CSS_TEXT_ALIGN_JUSTIFY;
+ } else {
+ dom_string_unref(align);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(align);
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ /* Tables usually reset alignment */
+ hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC;
+
+ dom_string_unref(name);
+
+ return CSS_OK;
+ } else {
+ dom_string_unref(name);
+
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+}
+
+static css_error node_presentational_hint_padding_trbl(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_exception exc;
+ dom_string *cellpadding = NULL;
+ css_error result = CSS_PROPERTY_NOT_SET;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ if (tablenode != NULL) {
+ exc = dom_element_get_attribute(tablenode,
+ corestring_dom_cellpadding,
+ &cellpadding);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+ }
+
+ dom_string_unref(name);
+
+ if (cellpadding != NULL) {
+ if (parse_dimension(dom_string_data(cellpadding), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_PADDING_SET;
+ result = CSS_OK;
+ }
+ dom_string_unref(cellpadding);
+ }
+
+ return result;
+}
+
+static css_error node_presentational_hint_margin_rl(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint,
+ uint32_t property)
+{
+ dom_string *n;
+ dom_exception exc;
+
+ exc = dom_node_get_node_name(node, &n);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(n, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(n, corestring_lwc_applet)) {
+ dom_string_unref(n);
+ exc = dom_element_get_attribute(node,
+ corestring_dom_hspace, &n);
+ if (exc != DOM_NO_ERR) {
+ return CSS_BADPARM;
+ }
+
+ if (n == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (parse_dimension(dom_string_data(n), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ dom_string_unref(n);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ dom_string_unref(n);
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_table) ||
+ dom_string_caseless_lwc_isequal(n, corestring_lwc_align)) {
+ dom_string_unref(n);
+ exc = dom_element_get_attribute(node,
+ corestring_dom_align, &n);
+ if (exc != DOM_NO_ERR) {
+ return CSS_BADPARM;
+ }
+
+ if (n == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_center) ||
+ dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_abscenter) ||
+ dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_middle) ||
+ dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_absmiddle)) {
+ hint->status = CSS_MARGIN_AUTO;
+ } else {
+ dom_string_unref(n);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(n);
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_hr)) {
+ dom_string_unref(n);
+ exc = dom_element_get_attribute(node,
+ corestring_dom_align, &n);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (n == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_left)) {
+ if (property == CSS_PROP_MARGIN_LEFT) {
+ hint->data.length.value = 0;
+ hint->data.length.unit = CSS_UNIT_PX;
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ hint->status = CSS_MARGIN_AUTO;
+ }
+ } else if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_center)) {
+ hint->status = CSS_MARGIN_AUTO;
+ } else if (dom_string_caseless_lwc_isequal(n,
+ corestring_lwc_right)) {
+ if (property == CSS_PROP_MARGIN_RIGHT) {
+ hint->data.length.value = 0;
+ hint->data.length.unit = CSS_UNIT_PX;
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ hint->status = CSS_MARGIN_AUTO;
+ }
+ } else {
+ dom_string_unref(n);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ dom_string_unref(n);
+
+ return CSS_OK;
+ }
+
+ dom_string_unref(n);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_margin_tb(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name, *vspace = NULL;
+ dom_exception exc;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
+ exc = dom_element_get_attribute(node, corestring_dom_vspace,
+ &vspace);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+
+ dom_string_unref(name);
+
+ if (vspace == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (parse_dimension(dom_string_data(vspace), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_MARGIN_SET;
+ } else {
+ dom_string_unref(vspace);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(vspace);
+
+ return CSS_OK;
+}
+
+static css_error node_presentational_hint_border_trbl_width(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_exception exc;
+ dom_string *width = NULL;
+ bool is_table_cell = false;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+ if (tablenode != NULL) {
+ exc = dom_element_get_attribute(tablenode,
+ corestring_dom_border, &width);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+ is_table_cell = true;
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ exc = dom_element_get_attribute(node, corestring_dom_border,
+ &width);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+ }
+
+ dom_string_unref(name);
+
+ if (width == NULL)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (parse_dimension(dom_string_data(width), false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ if (is_table_cell &&
+ INTTOFIX(0) !=
+ hint->data.length.value) {
+ hint->data.length.value = INTTOFIX(1);
+ hint->data.length.unit = CSS_UNIT_PX;
+ }
+ hint->status = CSS_BORDER_WIDTH_WIDTH;
+ } else {
+ dom_string_unref(width);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(width);
+
+ return CSS_OK;
+}
+
+static css_error node_presentational_hint_border_trbl_style(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_exception exc;
+
+ exc = dom_node_get_node_name(node, &name);
+ if (exc != DOM_NO_ERR)
+ return CSS_BADPARM;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ if (tablenode != NULL) {
+ bool has_border = false;
+
+ exc = dom_element_has_attribute(tablenode,
+ corestring_dom_border,
+ &has_border);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+
+ if (has_border) {
+ hint->status = CSS_BORDER_STYLE_INSET;
+ dom_string_unref(name);
+ return CSS_OK;
+ }
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ bool has_border = false;
+
+ exc = dom_element_has_attribute(node,
+ corestring_dom_border,
+ &has_border);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return CSS_BADPARM;
+ }
+
+ if (has_border) {
+ hint->status = CSS_BORDER_STYLE_OUTSET;
+ dom_string_unref(name);
+ return CSS_OK;
+ }
+ }
+
+ dom_string_unref(name);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_border_trbl_color(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *bordercolor = NULL;
+ dom_exception err;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
+ css_qname qs;
+ dom_node *tablenode = NULL;
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_table);
+
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&tablenode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ if (tablenode != NULL) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_bordercolor,
+ &bordercolor);
+ }
+ /* No need to unref tablenode, named_ancestor_node does not
+ * return a reffed node to the CSS
+ */
+
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_table)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_bordercolor,
+ &bordercolor);
+ }
+
+ dom_string_unref(name);
+
+ if ((err != DOM_NO_ERR) || (bordercolor == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (nscss_parse_colour((const char *)dom_string_data(bordercolor),
+ &hint->data.color)) {
+ hint->status = CSS_BORDER_COLOR_COLOR;
+ dom_string_unref(bordercolor);
+ return CSS_OK;
+ }
+
+ dom_string_unref(bordercolor);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_border_spacing(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *cellspacing = NULL;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_table)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node,
+ corestring_dom_cellspacing, &cellspacing);
+ if ((err != DOM_NO_ERR) || (cellspacing == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+
+ if (parse_dimension((const char *)dom_string_data(cellspacing),
+ false,
+ &hint->data.position.h.value,
+ &hint->data.position.h.unit)) {
+
+ hint->data.position.v = hint->data.position.h;
+ hint->status = CSS_BORDER_SPACING_SET;
+
+ dom_string_unref(cellspacing);
+ return CSS_OK;
+ }
+
+ dom_string_unref(cellspacing);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_width(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *width = NULL;
+ dom_exception err;
+ bool textarea = false;
+ bool input = false;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_hr) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_table) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_width, &width);
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_textarea)) {
+ textarea = true;
+ err = dom_element_get_attribute(node,
+ corestring_dom_cols, &width);
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_input)) {
+ input = true;
+ err = dom_element_get_attribute(node,
+ corestring_dom_size, &width);
+ }
+
+ dom_string_unref(name);
+
+ if ((err != DOM_NO_ERR) || (width == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (parse_dimension((const char *)dom_string_data(width),
+ false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_WIDTH_SET;
+ dom_string_unref(width);
+
+ if (textarea) {
+ hint->data.length.unit = CSS_UNIT_EX;
+ }
+
+ if (input) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_type, &width);
+ if (err != DOM_NO_ERR) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if ((width == NULL) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_text) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_search) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_file) ||
+ dom_string_caseless_lwc_isequal(width,
+ corestring_lwc_password)) {
+ hint->data.length.unit = CSS_UNIT_EX;
+ }
+ dom_string_unref(width);
+ }
+
+ return CSS_OK;
+ }
+
+ dom_string_unref(width);
+ return CSS_PROPERTY_NOT_SET;
+
+}
+
+static css_error node_presentational_hint_height(nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_string *name;
+ dom_string *height = NULL;
+ dom_exception err;
+ bool textarea = false;
+
+ err = dom_node_get_node_name(node, &name);
+ if (err != DOM_NO_ERR)
+ return CSS_PROPERTY_NOT_SET;
+
+ if (dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
+ dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_height, &height);
+ } else if (dom_string_caseless_lwc_isequal(name,
+ corestring_lwc_textarea)) {
+ textarea = true;
+ err = dom_element_get_attribute(node,
+ corestring_dom_rows, &height);
+ }
+
+ dom_string_unref(name);
+
+ if ((err != DOM_NO_ERR) || (height == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (parse_dimension((const char *)dom_string_data(height),
+ false,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ hint->status = CSS_HEIGHT_SET;
+
+ if (textarea) {
+ hint->data.length.unit = CSS_UNIT_EM;
+ }
+
+ dom_string_unref(height);
+ return CSS_OK;
+ }
+
+ dom_string_unref(height);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_font_size(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *size;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_NOMEM;
+ }
+
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_font)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node, corestring_dom_size, &size);
+ if ((err != DOM_NO_ERR) || (size == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (parse_font_size((const char *)dom_string_data(size),
+ &hint->status,
+ &hint->data.length.value,
+ &hint->data.length.unit)) {
+ dom_string_unref(size);
+ return CSS_OK;
+ }
+
+ dom_string_unref(size);
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_float(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *align;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_NOMEM;
+ }
+
+ /** \todo input[type=image][align=*] - $11.3.3 */
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_table) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_applet) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_embed) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_iframe) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_img) &&
+ !dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_object)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node, corestring_dom_align, &align);
+ if ((err != DOM_NO_ERR) || (align == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_left)) {
+ hint->status = CSS_FLOAT_LEFT;
+ dom_string_unref(align);
+ return CSS_OK;
+ } else if (dom_string_caseless_lwc_isequal(align,
+ corestring_lwc_right)) {
+ hint->status = CSS_FLOAT_RIGHT;
+ dom_string_unref(align);
+ return CSS_OK;
+ }
+
+ dom_string_unref(align);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_color(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ css_error error;
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *color;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_NOMEM;
+ }
+
+ if (dom_string_caseless_lwc_isequal(node_name, corestring_lwc_a)) {
+ /* find body node */
+ css_qname qs;
+ dom_node *bodynode = NULL;
+ bool is_visited;
+
+ qs.ns = NULL;
+ qs.name = lwc_string_ref(corestring_lwc_body);
+ if (named_ancestor_node(ctx, node, &qs,
+ (void *)&bodynode) != CSS_OK) {
+ /* Didn't find, or had error */
+ lwc_string_unref(qs.name);
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ lwc_string_unref(qs.name);
+
+ /* deal with missing body ancestor */
+ if (bodynode == NULL) {
+ dom_string_unref(node_name);
+ return CSS_BADPARM;
+ }
+
+ error = node_is_visited(ctx, node, &is_visited);
+ if (error != CSS_OK)
+ return error;
+
+ if (is_visited) {
+ err = dom_element_get_attribute(bodynode,
+ corestring_dom_vlink, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ } else {
+ err = dom_element_get_attribute(bodynode,
+ corestring_dom_link, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ }
+ } else if (dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_body)) {
+ err = dom_element_get_attribute(node,
+ corestring_dom_text, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ } else {
+ err = dom_element_get_attribute(node,
+ corestring_dom_color, &color);
+ if ((err != DOM_NO_ERR) || (color == NULL)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+ }
+
+ if (!nscss_parse_colour((const char *)dom_string_data(color),
+ &hint->data.color)) {
+ dom_string_unref(color);
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ hint->status = CSS_COLOR_COLOR;
+
+ dom_string_unref(color);
+ dom_string_unref(node_name);
+
+ return CSS_OK;
+}
+
+static css_error node_presentational_hint_caption_side(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *node_name = NULL;
+ dom_string *align = NULL;
+
+ err = dom_node_get_node_name(node, &node_name);
+ if ((err != DOM_NO_ERR) || (node_name == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (!dom_string_caseless_lwc_isequal(node_name,
+ corestring_lwc_caption)) {
+ dom_string_unref(node_name);
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ dom_string_unref(node_name);
+
+ err = dom_element_get_attribute(node, corestring_dom_align, &align);
+ if ((err != DOM_NO_ERR) || (align == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (dom_string_caseless_lwc_isequal(align, corestring_lwc_bottom)) {
+ hint->status = CSS_CAPTION_SIDE_BOTTOM;
+ dom_string_unref(align);
+ return CSS_OK;
+ }
+
+ dom_string_unref(align);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_background_color(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *bgcolor;
+
+ err = dom_element_get_attribute(node,
+ corestring_dom_bgcolor, &bgcolor);
+ if ((err != DOM_NO_ERR) || (bgcolor == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ if (nscss_parse_colour((const char *)dom_string_data(bgcolor),
+ &hint->data.color)) {
+ hint->status = CSS_BACKGROUND_COLOR_COLOR;
+ dom_string_unref(bgcolor);
+ return CSS_OK;
+ }
+
+ dom_string_unref(bgcolor);
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+static css_error node_presentational_hint_background_image(
+ nscss_select_ctx *ctx,
+ dom_node *node,
+ css_hint *hint)
+{
+ dom_exception err;
+ dom_string *atr_val;
+ nserror error;
+ nsurl *url;
+ lwc_string *iurl;
+ lwc_error lerror;
+
+ err = dom_element_get_attribute(node,
+ corestring_dom_background, &atr_val);
+ if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
+ return CSS_PROPERTY_NOT_SET;
+ }
+
+ error = nsurl_join(ctx->base_url,
+ (const char *)dom_string_data(atr_val), &url);
+
+ dom_string_unref(atr_val);
+
+ if (error != NSERROR_OK) {
+ return CSS_NOMEM;
+ }
+
+ lerror = lwc_intern_string(nsurl_access(url),
+ nsurl_length(url), &iurl);
+
+ nsurl_unref(url);
+
+ if (lerror == lwc_error_oom) {
+ return CSS_NOMEM;
+ }
+
+ if (lerror == lwc_error_ok) {
+ hint->data.string = iurl;
+ hint->status = CSS_BACKGROUND_IMAGE_IMAGE;
+ return CSS_OK;
+ }
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
+/* Exported function, documeted in css/hints.h */
+css_error node_presentational_hint(void *pw, void *node,
+ uint32_t property, css_hint *hint)
+{
+
+ switch (property) {
+ case CSS_PROP_BACKGROUND_IMAGE:
+ return node_presentational_hint_background_image(pw, node, hint);
+
+ case CSS_PROP_BACKGROUND_COLOR:
+ return node_presentational_hint_background_color(pw, node, hint);
+ case CSS_PROP_CAPTION_SIDE:
+ return node_presentational_hint_caption_side(pw, node, hint);
+
+ case CSS_PROP_COLOR:
+ return node_presentational_hint_color(pw, node, hint);
+
+ case CSS_PROP_FLOAT:
+ return node_presentational_hint_float(pw, node, hint);
+
+ case CSS_PROP_FONT_SIZE:
+ return node_presentational_hint_font_size(pw, node, hint);
+
+ case CSS_PROP_HEIGHT:
+ return node_presentational_hint_height(pw, node, hint);
+
+ case CSS_PROP_WIDTH:
+ return node_presentational_hint_width(pw, node, hint);
+
+ case CSS_PROP_BORDER_SPACING:
+ return node_presentational_hint_border_spacing(pw, node, hint);
+
+ case CSS_PROP_BORDER_TOP_COLOR :
+ case CSS_PROP_BORDER_RIGHT_COLOR :
+ case CSS_PROP_BORDER_BOTTOM_COLOR :
+ case CSS_PROP_BORDER_LEFT_COLOR :
+ return node_presentational_hint_border_trbl_color(pw, node, hint);
+
+ case CSS_PROP_BORDER_TOP_STYLE :
+ case CSS_PROP_BORDER_RIGHT_STYLE :
+ case CSS_PROP_BORDER_BOTTOM_STYLE :
+ case CSS_PROP_BORDER_LEFT_STYLE :
+ return node_presentational_hint_border_trbl_style(pw, node, hint);
+
+ case CSS_PROP_BORDER_TOP_WIDTH :
+ case CSS_PROP_BORDER_RIGHT_WIDTH :
+ case CSS_PROP_BORDER_BOTTOM_WIDTH :
+ case CSS_PROP_BORDER_LEFT_WIDTH :
+ return node_presentational_hint_border_trbl_width(pw, node, hint);
+
+ case CSS_PROP_MARGIN_TOP :
+ case CSS_PROP_MARGIN_BOTTOM :
+ return node_presentational_hint_margin_tb(pw, node, hint);
+
+ case CSS_PROP_MARGIN_RIGHT:
+ case CSS_PROP_MARGIN_LEFT:
+ return node_presentational_hint_margin_rl(pw, node, hint, property);
+
+ case CSS_PROP_PADDING_TOP:
+ case CSS_PROP_PADDING_RIGHT :
+ case CSS_PROP_PADDING_BOTTOM :
+ case CSS_PROP_PADDING_LEFT:
+ return node_presentational_hint_padding_trbl(pw, node, hint);
+
+ case CSS_PROP_TEXT_ALIGN:
+ return node_presentational_hint_text_align(pw, node, hint);
+
+ case CSS_PROP_VERTICAL_ALIGN:
+ return node_presentational_hint_vertical_align(pw, node, hint);
+ }
+
+ return CSS_PROPERTY_NOT_SET;
+}
+
diff --git a/css/hints.h b/css/hints.h
new file mode 100644
index 000000000..68d4c1063
--- /dev/null
+++ b/css/hints.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_CSS_HINTS_H_
+#define NETSURF_CSS_HINTS_H_
+
+#include <stdint.h>
+
+#include "css/css.h"
+
+
+
+
+/**
+ * Callback to retrieve presentational hints for a node
+ *
+ * \param pw HTML document
+ * \param node DOM node
+ * \param property CSS property to retrieve
+ * \param hint Pointer to hint object to populate
+ * \return CSS_OK on success,
+ * CSS_PROPERTY_NOT_SET if there is no hint for the requested property,
+ * CSS_NOMEM on memory exhaustion.
+ */
+css_error node_presentational_hint(
+ void *pw,
+ void *node,
+ uint32_t property,
+ css_hint *hint);
+
+bool nscss_parse_colour(const char *data, css_color *result);
+
+#endif
diff --git a/css/select.c b/css/select.c
index e88d3f61f..a929cf10a 100644
--- a/css/select.c
+++ b/css/select.c
@@ -17,28 +17,23 @@
*/
#include <assert.h>
-#include <stdbool.h>
#include <string.h>
#include <strings.h>
-#include "content/content_protected.h"
#include "content/urldb.h"
#include "desktop/system_colour.h"
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/log.h"
-#include "utils/utils.h"
#include "css/internal.h"
+#include "css/hints.h"
#include "css/select.h"
-#include "css/utils.h"
static css_error node_name(void *pw, void *node, css_qname *qname);
static css_error node_classes(void *pw, void *node,
lwc_string ***classes, uint32_t *n_classes);
static css_error node_id(void *pw, void *node, lwc_string **id);
-static css_error named_ancestor_node(void *pw, void *node,
- const css_qname *qname, void **ancestor);
static css_error named_parent_node(void *pw, void *node,
const css_qname *qname, void **parent);
static css_error named_sibling_node(void *pw, void *node,
@@ -78,7 +73,6 @@ static css_error node_count_siblings(void *pw, void *node,
bool same_name, bool after, int32_t *count);
static css_error node_is_empty(void *pw, void *node, bool *match);
static css_error node_is_link(void *pw, void *node, bool *match);
-static css_error node_is_visited(void *pw, void *node, bool *match);
static css_error node_is_hover(void *pw, void *node, bool *match);
static css_error node_is_active(void *pw, void *node, bool *match);
static css_error node_is_focus(void *pw, void *node, bool *match);
@@ -88,8 +82,6 @@ static css_error node_is_checked(void *pw, void *node, bool *match);
static css_error node_is_target(void *pw, void *node, bool *match);
static css_error node_is_lang(void *pw, void *node,
lwc_string *lang, bool *match);
-static css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint);
static css_error ua_default_for_property(void *pw, uint32_t property,
css_hint *hint);
static css_error set_libcss_node_data(void *pw, void *node,
@@ -97,18 +89,9 @@ static css_error set_libcss_node_data(void *pw, void *node,
static css_error get_libcss_node_data(void *pw, void *node,
void **libcss_node_data);
-static int cmp_colour_name(const void *a, const void *b);
-static bool parse_named_colour(const char *data, css_color *result);
-static bool parse_dimension(const char *data, bool strict,
- css_fixed *length, css_unit *unit);
-static bool parse_number(const char *data, bool non_negative, bool real,
- css_fixed *value, size_t *consumed);
-static bool parse_font_size(const char *size, uint8_t *val,
- css_fixed *len, css_unit *unit);
+static css_error nscss_compute_font_size(void *pw, const css_hint *parent,
+ css_hint *size);
-static bool isWhitespace(char c);
-static bool isHex(char c);
-static uint8_t charToHex(char c);
/**
* Selection callback table for libcss
@@ -465,64 +448,6 @@ css_error nscss_compute_font_size(void *pw, const css_hint *parent,
return CSS_OK;
}
-/**
- * Parser for colours specified in attribute values.
- *
- * \param data Data to parse (NUL-terminated)
- * \param result Pointer to location to receive resulting css_color
- * \return true on success, false on invalid input
- */
-bool nscss_parse_colour(const char *data, css_color *result)
-{
- size_t len = strlen(data);
- uint8_t r, g, b;
-
- /* 2 */
- if (len == 0)
- return false;
-
- /* 3 */
- if (len == SLEN("transparent") && strcasecmp(data, "transparent") == 0)
- return false;
-
- /* 4 */
- if (parse_named_colour(data, result))
- return true;
-
- /** \todo Implement HTML5's utterly insane legacy colour parsing */
-
- if (data[0] == '#') {
- data++;
- len--;
- }
-
- if (len == 3 && isHex(data[0]) && isHex(data[1]) && isHex(data[2])) {
- r = charToHex(data[0]);
- g = charToHex(data[1]);
- b = charToHex(data[2]);
-
- r |= (r << 4);
- g |= (g << 4);
- b |= (b << 4);
-
- *result = (0xff << 24) | (r << 16) | (g << 8) | b;
-
- return true;
- } else if (len == 6 && isHex(data[0]) && isHex(data[1]) &&
- isHex(data[2]) && isHex(data[3]) && isHex(data[4]) &&
- isHex(data[5])) {
- r = (charToHex(data[0]) << 4) | charToHex(data[1]);
- g = (charToHex(data[2]) << 4) | charToHex(data[3]);
- b = (charToHex(data[4]) << 4) | charToHex(data[5]);
-
- *result = (0xff << 24) | (r << 16) | (g << 8) | b;
-
- return true;
- }
-
- return false;
-}
-
/******************************************************************************
* Style selection callbacks *
******************************************************************************/
@@ -1844,1230 +1769,6 @@ css_error node_is_lang(void *pw, void *node,
return CSS_OK;
}
-static css_error
-node_presentational_hint_vertical_align(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *valign = NULL;
- dom_exception err;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_col) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_thead) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tbody) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tfoot) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- err = dom_element_get_attribute(node,
- corestring_dom_valign, &valign);
- if (err != DOM_NO_ERR || valign == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_top)) {
- hint->status = CSS_VERTICAL_ALIGN_TOP;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_middle)) {
- hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_bottom)) {
- hint->status = CSS_VERTICAL_ALIGN_BOTTOM;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_baseline)) {
- hint->status = CSS_VERTICAL_ALIGN_BASELINE;
- } else {
- dom_string_unref(valign);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(valign);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_applet) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_embed) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_iframe) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_object)) {
- /** \todo input[type=image][align=*] - $11.3.3 */
- err = dom_element_get_attribute(node,
- corestring_dom_align, &valign);
- if (err != DOM_NO_ERR || valign == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_top)) {
- hint->status = CSS_VERTICAL_ALIGN_TOP;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_bottom) ||
- dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_baseline)) {
- hint->status = CSS_VERTICAL_ALIGN_BASELINE;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_texttop)) {
- hint->status = CSS_VERTICAL_ALIGN_TEXT_TOP;
- } else if (dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_absmiddle) ||
- dom_string_caseless_lwc_isequal(valign,
- corestring_lwc_abscenter)) {
- hint->status = CSS_VERTICAL_ALIGN_MIDDLE;
- } else {
- dom_string_unref(valign);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(valign);
- dom_string_unref(name);
-
- return CSS_OK;
- }
-
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_text_align(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *align = NULL;
- dom_exception err;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_p) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h1) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h2) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h3) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h4) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h5) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_h6)) {
- err = dom_element_get_attribute(node,
- corestring_dom_align, &align);
- if (err != DOM_NO_ERR || align == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_TEXT_ALIGN_LEFT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_CENTER;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_TEXT_ALIGN_RIGHT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_justify)) {
- hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- } else {
- dom_string_unref(align);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(align);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
-
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_caption)) {
- err = dom_element_get_attribute(node,
- corestring_dom_align, &align);
- if (err != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (align == NULL || dom_string_caseless_lwc_isequal(align,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_justify)) {
- hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- } else {
- dom_string_unref(align);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (align != NULL)
- dom_string_unref(align);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_div) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_thead) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_tbody) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_tfoot) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_tr) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name,
- corestring_lwc_th)) {
- err = dom_element_get_attribute(node,
- corestring_dom_align, &align);
- if (err != DOM_NO_ERR || align == NULL) {
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_center)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_CENTER;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_LEFT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_TEXT_ALIGN_LIBCSS_RIGHT;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_justify)) {
- hint->status = CSS_TEXT_ALIGN_JUSTIFY;
- } else {
- dom_string_unref(align);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(align);
- dom_string_unref(name);
-
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- /* Tables usually reset alignment */
- hint->status = CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC;
-
- dom_string_unref(name);
-
- return CSS_OK;
- } else {
- dom_string_unref(name);
-
- return CSS_PROPERTY_NOT_SET;
- }
-
-}
-
-static css_error
-node_presentational_hint_padding_trbl(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_exception exc;
- dom_string *cellpadding = NULL;
- css_error result = CSS_PROPERTY_NOT_SET;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- if (tablenode != NULL) {
- exc = dom_element_get_attribute(tablenode,
- corestring_dom_cellpadding,
- &cellpadding);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
- }
-
- dom_string_unref(name);
-
- if (cellpadding != NULL) {
- if (parse_dimension(dom_string_data(cellpadding), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_PADDING_SET;
- result = CSS_OK;
- }
- dom_string_unref(cellpadding);
- }
-
- return result;
-}
-
-static css_error
-node_presentational_hint_margin_rl(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint,
- uint32_t property)
-{
- dom_string *n;
- dom_exception exc;
-
- exc = dom_node_get_node_name(node, &n);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(n, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(n, corestring_lwc_applet)) {
- dom_string_unref(n);
- exc = dom_element_get_attribute(node,
- corestring_dom_hspace, &n);
- if (exc != DOM_NO_ERR) {
- return CSS_BADPARM;
- }
-
- if (n == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (parse_dimension(dom_string_data(n), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_MARGIN_SET;
- } else {
- dom_string_unref(n);
- return CSS_PROPERTY_NOT_SET;
- }
- dom_string_unref(n);
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_table) ||
- dom_string_caseless_lwc_isequal(n, corestring_lwc_align)) {
- dom_string_unref(n);
- exc = dom_element_get_attribute(node,
- corestring_dom_align, &n);
- if (exc != DOM_NO_ERR) {
- return CSS_BADPARM;
- }
-
- if (n == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_center) ||
- dom_string_caseless_lwc_isequal(n,
- corestring_lwc_abscenter) ||
- dom_string_caseless_lwc_isequal(n,
- corestring_lwc_middle) ||
- dom_string_caseless_lwc_isequal(n,
- corestring_lwc_absmiddle)) {
- hint->status = CSS_MARGIN_AUTO;
- } else {
- dom_string_unref(n);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(n);
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(n, corestring_lwc_hr)) {
- dom_string_unref(n);
- exc = dom_element_get_attribute(node,
- corestring_dom_align, &n);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (n == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_left)) {
- if (property == CSS_PROP_MARGIN_LEFT) {
- hint->data.length.value = 0;
- hint->data.length.unit = CSS_UNIT_PX;
- hint->status = CSS_MARGIN_SET;
- } else {
- hint->status = CSS_MARGIN_AUTO;
- }
- } else if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_center)) {
- hint->status = CSS_MARGIN_AUTO;
- } else if (dom_string_caseless_lwc_isequal(n,
- corestring_lwc_right)) {
- if (property == CSS_PROP_MARGIN_RIGHT) {
- hint->data.length.value = 0;
- hint->data.length.unit = CSS_UNIT_PX;
- hint->status = CSS_MARGIN_SET;
- } else {
- hint->status = CSS_MARGIN_AUTO;
- }
- } else {
- dom_string_unref(n);
- return CSS_PROPERTY_NOT_SET;
- }
- dom_string_unref(n);
-
- return CSS_OK;
- }
-
- dom_string_unref(n);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_margin_tb(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name, *vspace = NULL;
- dom_exception exc;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
- exc = dom_element_get_attribute(node, corestring_dom_vspace,
- &vspace);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
-
- dom_string_unref(name);
-
- if (vspace == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (parse_dimension(dom_string_data(vspace), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_MARGIN_SET;
- } else {
- dom_string_unref(vspace);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(vspace);
-
- return CSS_OK;
-}
-
-static css_error
-node_presentational_hint_border_trbl_width(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_exception exc;
- dom_string *width = NULL;
- bool is_table_cell = false;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
- if (tablenode != NULL) {
- exc = dom_element_get_attribute(tablenode,
- corestring_dom_border, &width);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
- is_table_cell = true;
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- exc = dom_element_get_attribute(node, corestring_dom_border,
- &width);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
- }
-
- dom_string_unref(name);
-
- if (width == NULL)
- return CSS_PROPERTY_NOT_SET;
-
- if (parse_dimension(dom_string_data(width), false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- if (is_table_cell &&
- INTTOFIX(0) !=
- hint->data.length.value) {
- hint->data.length.value = INTTOFIX(1);
- hint->data.length.unit = CSS_UNIT_PX;
- }
- hint->status = CSS_BORDER_WIDTH_WIDTH;
- } else {
- dom_string_unref(width);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(width);
-
- return CSS_OK;
-}
-
-static css_error
-node_presentational_hint_border_trbl_style(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_exception exc;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- return CSS_BADPARM;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
-
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- if (tablenode != NULL) {
- bool has_border = false;
-
- exc = dom_element_has_attribute(tablenode,
- corestring_dom_border,
- &has_border);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
-
- if (has_border) {
- hint->status = CSS_BORDER_STYLE_INSET;
- dom_string_unref(name);
- return CSS_OK;
- }
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- bool has_border = false;
-
- exc = dom_element_has_attribute(node,
- corestring_dom_border,
- &has_border);
- if (exc != DOM_NO_ERR) {
- dom_string_unref(name);
- return CSS_BADPARM;
- }
-
- if (has_border) {
- hint->status = CSS_BORDER_STYLE_OUTSET;
- dom_string_unref(name);
- return CSS_OK;
- }
- }
-
- dom_string_unref(name);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_border_trbl_color(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *bordercolor = NULL;
- dom_exception err;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th)) {
- css_qname qs;
- dom_node *tablenode = NULL;
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_table);
-
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&tablenode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- if (tablenode != NULL) {
- err = dom_element_get_attribute(node,
- corestring_dom_bordercolor,
- &bordercolor);
- }
- /* No need to unref tablenode, named_ancestor_node does not
- * return a reffed node to the CSS
- */
-
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_table)) {
- err = dom_element_get_attribute(node,
- corestring_dom_bordercolor,
- &bordercolor);
- }
-
- dom_string_unref(name);
-
- if ((err != DOM_NO_ERR) || (bordercolor == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (nscss_parse_colour((const char *)dom_string_data(bordercolor),
- &hint->data.color)) {
- hint->status = CSS_BORDER_COLOR_COLOR;
- dom_string_unref(bordercolor);
- return CSS_OK;
- }
-
- dom_string_unref(bordercolor);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_border_spacing(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *cellspacing = NULL;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_table)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node,
- corestring_dom_cellspacing, &cellspacing);
- if ((err != DOM_NO_ERR) || (cellspacing == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
-
- if (parse_dimension((const char *)dom_string_data(cellspacing),
- false,
- &hint->data.position.h.value,
- &hint->data.position.h.unit)) {
-
- hint->data.position.v = hint->data.position.h;
- hint->status = CSS_BORDER_SPACING_SET;
-
- dom_string_unref(cellspacing);
- return CSS_OK;
- }
-
- dom_string_unref(cellspacing);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_width(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *width = NULL;
- dom_exception err;
- bool textarea = false;
- bool input = false;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_hr) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_table) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
- err = dom_element_get_attribute(node,
- corestring_dom_width, &width);
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_textarea)) {
- textarea = true;
- err = dom_element_get_attribute(node,
- corestring_dom_cols, &width);
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_input)) {
- input = true;
- err = dom_element_get_attribute(node,
- corestring_dom_size, &width);
- }
-
- dom_string_unref(name);
-
- if ((err != DOM_NO_ERR) || (width == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (parse_dimension((const char *)dom_string_data(width),
- false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_WIDTH_SET;
- dom_string_unref(width);
-
- if (textarea) {
- hint->data.length.unit = CSS_UNIT_EX;
- }
-
- if (input) {
- err = dom_element_get_attribute(node,
- corestring_dom_type, &width);
- if (err != DOM_NO_ERR) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if ((width == NULL) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_text) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_search) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_file) ||
- dom_string_caseless_lwc_isequal(width,
- corestring_lwc_password)) {
- hint->data.length.unit = CSS_UNIT_EX;
- }
- dom_string_unref(width);
- }
-
- return CSS_OK;
- }
-
- dom_string_unref(width);
- return CSS_PROPERTY_NOT_SET;
-
-}
-
-static css_error
-node_presentational_hint_height(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_string *name;
- dom_string *height = NULL;
- dom_exception err;
- bool textarea = false;
-
- err = dom_node_get_node_name(node, &name);
- if (err != DOM_NO_ERR)
- return CSS_PROPERTY_NOT_SET;
-
- if (dom_string_caseless_lwc_isequal(name, corestring_lwc_iframe) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_td) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_th) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_tr) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_img) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_object) ||
- dom_string_caseless_lwc_isequal(name, corestring_lwc_applet)) {
- err = dom_element_get_attribute(node,
- corestring_dom_height, &height);
- } else if (dom_string_caseless_lwc_isequal(name,
- corestring_lwc_textarea)) {
- textarea = true;
- err = dom_element_get_attribute(node,
- corestring_dom_rows, &height);
- }
-
- dom_string_unref(name);
-
- if ((err != DOM_NO_ERR) || (height == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (parse_dimension((const char *)dom_string_data(height),
- false,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- hint->status = CSS_HEIGHT_SET;
-
- if (textarea) {
- hint->data.length.unit = CSS_UNIT_EM;
- }
-
- dom_string_unref(height);
- return CSS_OK;
- }
-
- dom_string_unref(height);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_font_size(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *size;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_NOMEM;
- }
-
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_font)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node, corestring_dom_size, &size);
- if ((err != DOM_NO_ERR) || (size == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (parse_font_size((const char *)dom_string_data(size),
- &hint->status,
- &hint->data.length.value,
- &hint->data.length.unit)) {
- dom_string_unref(size);
- return CSS_OK;
- }
-
- dom_string_unref(size);
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_float(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *align;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_NOMEM;
- }
-
- /** \todo input[type=image][align=*] - $11.3.3 */
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_table) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_applet) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_embed) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_iframe) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_img) &&
- !dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_object)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node, corestring_dom_align, &align);
- if ((err != DOM_NO_ERR) || (align == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_left)) {
- hint->status = CSS_FLOAT_LEFT;
- dom_string_unref(align);
- return CSS_OK;
- } else if (dom_string_caseless_lwc_isequal(align,
- corestring_lwc_right)) {
- hint->status = CSS_FLOAT_RIGHT;
- dom_string_unref(align);
- return CSS_OK;
- }
-
- dom_string_unref(align);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_color(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- css_error error;
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *color;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_NOMEM;
- }
-
- if (dom_string_caseless_lwc_isequal(node_name, corestring_lwc_a)) {
- /* find body node */
- css_qname qs;
- dom_node *bodynode = NULL;
- bool is_visited;
-
- qs.ns = NULL;
- qs.name = lwc_string_ref(corestring_lwc_body);
- if (named_ancestor_node(ctx, node, &qs,
- (void *)&bodynode) != CSS_OK) {
- /* Didn't find, or had error */
- lwc_string_unref(qs.name);
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- lwc_string_unref(qs.name);
-
- /* deal with missing body ancestor */
- if (bodynode == NULL) {
- dom_string_unref(node_name);
- return CSS_BADPARM;
- }
-
- error = node_is_visited(ctx, node, &is_visited);
- if (error != CSS_OK)
- return error;
-
- if (is_visited) {
- err = dom_element_get_attribute(bodynode,
- corestring_dom_vlink, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- } else {
- err = dom_element_get_attribute(bodynode,
- corestring_dom_link, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- }
- } else if (dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_body)) {
- err = dom_element_get_attribute(node,
- corestring_dom_text, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- } else {
- err = dom_element_get_attribute(node,
- corestring_dom_color, &color);
- if ((err != DOM_NO_ERR) || (color == NULL)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
- }
-
- if (!nscss_parse_colour((const char *)dom_string_data(color),
- &hint->data.color)) {
- dom_string_unref(color);
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- hint->status = CSS_COLOR_COLOR;
-
- dom_string_unref(color);
- dom_string_unref(node_name);
-
- return CSS_OK;
-}
-
-static css_error
-node_presentational_hint_caption_side(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *node_name = NULL;
- dom_string *align = NULL;
-
- err = dom_node_get_node_name(node, &node_name);
- if ((err != DOM_NO_ERR) || (node_name == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (!dom_string_caseless_lwc_isequal(node_name,
- corestring_lwc_caption)) {
- dom_string_unref(node_name);
- return CSS_PROPERTY_NOT_SET;
- }
-
- dom_string_unref(node_name);
-
- err = dom_element_get_attribute(node, corestring_dom_align, &align);
- if ((err != DOM_NO_ERR) || (align == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (dom_string_caseless_lwc_isequal(align, corestring_lwc_bottom)) {
- hint->status = CSS_CAPTION_SIDE_BOTTOM;
- dom_string_unref(align);
- return CSS_OK;
- }
-
- dom_string_unref(align);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_background_color(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *bgcolor;
-
- err = dom_element_get_attribute(node,
- corestring_dom_bgcolor, &bgcolor);
- if ((err != DOM_NO_ERR) || (bgcolor == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- if (nscss_parse_colour((const char *)dom_string_data(bgcolor),
- &hint->data.color)) {
- hint->status = CSS_BACKGROUND_COLOR_COLOR;
- dom_string_unref(bgcolor);
- return CSS_OK;
- }
-
- dom_string_unref(bgcolor);
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-static css_error
-node_presentational_hint_background_image(nscss_select_ctx *ctx,
- dom_node *node,
- css_hint *hint)
-{
- dom_exception err;
- dom_string *atr_val;
- nserror error;
- nsurl *url;
- lwc_string *iurl;
- lwc_error lerror;
-
- err = dom_element_get_attribute(node,
- corestring_dom_background, &atr_val);
- if ((err != DOM_NO_ERR) || (atr_val == NULL)) {
- return CSS_PROPERTY_NOT_SET;
- }
-
- error = nsurl_join(ctx->base_url,
- (const char *)dom_string_data(atr_val), &url);
-
- dom_string_unref(atr_val);
-
- if (error != NSERROR_OK) {
- return CSS_NOMEM;
- }
-
- lerror = lwc_intern_string(nsurl_access(url),
- nsurl_length(url), &iurl);
-
- nsurl_unref(url);
-
- if (lerror == lwc_error_oom) {
- return CSS_NOMEM;
- }
-
- if (lerror == lwc_error_ok) {
- hint->data.string = iurl;
- hint->status = CSS_BACKGROUND_IMAGE_IMAGE;
- return CSS_OK;
- }
-
- return CSS_PROPERTY_NOT_SET;
-}
-
-/**
- * Callback to retrieve presentational hints for a node
- *
- * \param pw HTML document
- * \param node DOM node
- * \param property CSS property to retrieve
- * \param hint Pointer to hint object to populate
- * \return CSS_OK on success,
- * CSS_PROPERTY_NOT_SET if there is no hint for the requested property,
- * CSS_NOMEM on memory exhaustion.
- */
-css_error node_presentational_hint(void *pw, void *node,
- uint32_t property, css_hint *hint)
-{
-
- switch (property) {
- case CSS_PROP_BACKGROUND_IMAGE:
- return node_presentational_hint_background_image(pw, node, hint);
-
- case CSS_PROP_BACKGROUND_COLOR:
- return node_presentational_hint_background_color(pw, node, hint);
- case CSS_PROP_CAPTION_SIDE:
- return node_presentational_hint_caption_side(pw, node, hint);
-
- case CSS_PROP_COLOR:
- return node_presentational_hint_color(pw, node, hint);
-
- case CSS_PROP_FLOAT:
- return node_presentational_hint_float(pw, node, hint);
-
- case CSS_PROP_FONT_SIZE:
- return node_presentational_hint_font_size(pw, node, hint);
-
- case CSS_PROP_HEIGHT:
- return node_presentational_hint_height(pw, node, hint);
-
- case CSS_PROP_WIDTH:
- return node_presentational_hint_width(pw, node, hint);
-
- case CSS_PROP_BORDER_SPACING:
- return node_presentational_hint_border_spacing(pw, node, hint);
-
- case CSS_PROP_BORDER_TOP_COLOR :
- case CSS_PROP_BORDER_RIGHT_COLOR :
- case CSS_PROP_BORDER_BOTTOM_COLOR :
- case CSS_PROP_BORDER_LEFT_COLOR :
- return node_presentational_hint_border_trbl_color(pw, node, hint);
-
- case CSS_PROP_BORDER_TOP_STYLE :
- case CSS_PROP_BORDER_RIGHT_STYLE :
- case CSS_PROP_BORDER_BOTTOM_STYLE :
- case CSS_PROP_BORDER_LEFT_STYLE :
- return node_presentational_hint_border_trbl_style(pw, node, hint);
-
- case CSS_PROP_BORDER_TOP_WIDTH :
- case CSS_PROP_BORDER_RIGHT_WIDTH :
- case CSS_PROP_BORDER_BOTTOM_WIDTH :
- case CSS_PROP_BORDER_LEFT_WIDTH :
- return node_presentational_hint_border_trbl_width(pw, node, hint);
-
- case CSS_PROP_MARGIN_TOP :
- case CSS_PROP_MARGIN_BOTTOM :
- return node_presentational_hint_margin_tb(pw, node, hint);
-
- case CSS_PROP_MARGIN_RIGHT:
- case CSS_PROP_MARGIN_LEFT:
- return node_presentational_hint_margin_rl(pw, node, hint, property);
-
- case CSS_PROP_PADDING_TOP:
- case CSS_PROP_PADDING_RIGHT :
- case CSS_PROP_PADDING_BOTTOM :
- case CSS_PROP_PADDING_LEFT:
- return node_presentational_hint_padding_trbl(pw, node, hint);
-
- case CSS_PROP_TEXT_ALIGN:
- return node_presentational_hint_text_align(pw, node, hint);
-
- case CSS_PROP_VERTICAL_ALIGN:
- return node_presentational_hint_vertical_align(pw, node, hint);
- }
-
- return CSS_PROPERTY_NOT_SET;
-}
-
/**
* Callback to retrieve the User-Agent defaults for a CSS property.
*
@@ -3151,487 +1852,3 @@ css_error get_libcss_node_data(void *pw, void *node, void **libcss_node_data)
return CSS_OK;
}
-
-/**
- * Mapping of colour name to CSS color
- */
-struct colour_map {
- const char *name;
- css_color color;
-};
-
-/**
- * Name comparator for named colour matching
- *
- * \param a Name to match
- * \param b Colour map entry to consider
- * \return 0 on match,
- * < 0 if a < b,
- * > 0 if b > a.
- */
-int cmp_colour_name(const void *a, const void *b)
-{
- const char *aa = a;
- const struct colour_map *bb = b;
-
- return strcasecmp(aa, bb->name);
-}
-
-/**
- * Parse a named colour
- *
- * \param name Name to parse
- * \param result Pointer to location to receive css_color
- * \return true on success, false on invalid input
- */
-bool parse_named_colour(const char *name, css_color *result)
-{
- static const struct colour_map named_colours[] = {
- { "aliceblue", 0xfff0f8ff },
- { "antiquewhite", 0xfffaebd7 },
- { "aqua", 0xff00ffff },
- { "aquamarine", 0xff7fffd4 },
- { "azure", 0xfff0ffff },
- { "beige", 0xfff5f5dc },
- { "bisque", 0xffffe4c4 },
- { "black", 0xff000000 },
- { "blanchedalmond", 0xffffebcd },
- { "blue", 0xff0000ff },
- { "blueviolet", 0xff8a2be2 },
- { "brown", 0xffa52a2a },
- { "burlywood", 0xffdeb887 },
- { "cadetblue", 0xff5f9ea0 },
- { "chartreuse", 0xff7fff00 },
- { "chocolate", 0xffd2691e },
- { "coral", 0xffff7f50 },
- { "cornflowerblue", 0xff6495ed },
- { "cornsilk", 0xfffff8dc },
- { "crimson", 0xffdc143c },
- { "cyan", 0xff00ffff },
- { "darkblue", 0xff00008b },
- { "darkcyan", 0xff008b8b },
- { "darkgoldenrod", 0xffb8860b },
- { "darkgray", 0xffa9a9a9 },
- { "darkgreen", 0xff006400 },
- { "darkgrey", 0xffa9a9a9 },
- { "darkkhaki", 0xffbdb76b },
- { "darkmagenta", 0xff8b008b },
- { "darkolivegreen", 0xff556b2f },
- { "darkorange", 0xffff8c00 },
- { "darkorchid", 0xff9932cc },
- { "darkred", 0xff8b0000 },
- { "darksalmon", 0xffe9967a },
- { "darkseagreen", 0xff8fbc8f },
- { "darkslateblue", 0xff483d8b },
- { "darkslategray", 0xff2f4f4f },
- { "darkslategrey", 0xff2f4f4f },
- { "darkturquoise", 0xff00ced1 },
- { "darkviolet", 0xff9400d3 },
- { "deeppink", 0xffff1493 },
- { "deepskyblue", 0xff00bfff },
- { "dimgray", 0xff696969 },
- { "dimgrey", 0xff696969 },
- { "dodgerblue", 0xff1e90ff },
- { "feldspar", 0xffd19275 },
- { "firebrick", 0xffb22222 },
- { "floralwhite", 0xfffffaf0 },
- { "forestgreen", 0xff228b22 },
- { "fuchsia", 0xffff00ff },
- { "gainsboro", 0xffdcdcdc },
- { "ghostwhite", 0xfff8f8ff },
- { "gold", 0xffffd700 },
- { "goldenrod", 0xffdaa520 },
- { "gray", 0xff808080 },
- { "green", 0xff008000 },
- { "greenyellow", 0xffadff2f },
- { "grey", 0xff808080 },
- { "honeydew", 0xfff0fff0 },
- { "hotpink", 0xffff69b4 },
- { "indianred", 0xffcd5c5c },
- { "indigo", 0xff4b0082 },
- { "ivory", 0xfffffff0 },
- { "khaki", 0xfff0e68c },
- { "lavender", 0xffe6e6fa },
- { "lavenderblush", 0xfffff0f5 },
- { "lawngreen", 0xff7cfc00 },
- { "lemonchiffon", 0xfffffacd },
- { "lightblue", 0xffadd8e6 },
- { "lightcoral", 0xfff08080 },
- { "lightcyan", 0xffe0ffff },
- { "lightgoldenrodyellow", 0xfffafad2 },
- { "lightgray", 0xffd3d3d3 },
- { "lightgreen", 0xff90ee90 },
- { "lightgrey", 0xffd3d3d3 },
- { "lightpink", 0xffffb6c1 },
- { "lightsalmon", 0xffffa07a },
- { "lightseagreen", 0xff20b2aa },
- { "lightskyblue", 0xff87cefa },
- { "lightslateblue", 0xff8470ff },
- { "lightslategray", 0xff778899 },
- { "lightslategrey", 0xff778899 },
- { "lightsteelblue", 0xffb0c4de },
- { "lightyellow", 0xffffffe0 },
- { "lime", 0xff00ff00 },
- { "limegreen", 0xff32cd32 },
- { "linen", 0xfffaf0e6 },
- { "magenta", 0xffff00ff },
- { "maroon", 0xff800000 },
- { "mediumaquamarine", 0xff66cdaa },
- { "mediumblue", 0xff0000cd },
- { "mediumorchid", 0xffba55d3 },
- { "mediumpurple", 0xff9370db },
- { "mediumseagreen", 0xff3cb371 },
- { "mediumslateblue", 0xff7b68ee },
- { "mediumspringgreen", 0xff00fa9a },
- { "mediumturquoise", 0xff48d1cc },
- { "mediumvioletred", 0xffc71585 },
- { "midnightblue", 0xff191970 },
- { "mintcream", 0xfff5fffa },
- { "mistyrose", 0xffffe4e1 },
- { "moccasin", 0xffffe4b5 },
- { "navajowhite", 0xffffdead },
- { "navy", 0xff000080 },
- { "oldlace", 0xfffdf5e6 },
- { "olive", 0xff808000 },
- { "olivedrab", 0xff6b8e23 },
- { "orange", 0xffffa500 },
- { "orangered", 0xffff4500 },
- { "orchid", 0xffda70d6 },
- { "palegoldenrod", 0xffeee8aa },
- { "palegreen", 0xff98fb98 },
- { "paleturquoise", 0xffafeeee },
- { "palevioletred", 0xffdb7093 },
- { "papayawhip", 0xffffefd5 },
- { "peachpuff", 0xffffdab9 },
- { "peru", 0xffcd853f },
- { "pink", 0xffffc0cb },
- { "plum", 0xffdda0dd },
- { "powderblue", 0xffb0e0e6 },
- { "purple", 0xff800080 },
- { "red", 0xffff0000 },
- { "rosybrown", 0xffbc8f8f },
- { "royalblue", 0xff4169e1 },
- { "saddlebrown", 0xff8b4513 },
- { "salmon", 0xfffa8072 },
- { "sandybrown", 0xfff4a460 },
- { "seagreen", 0xff2e8b57 },
- { "seashell", 0xfffff5ee },
- { "sienna", 0xffa0522d },
- { "silver", 0xffc0c0c0 },
- { "skyblue", 0xff87ceeb },
- { "slateblue", 0xff6a5acd },
- { "slategray", 0xff708090 },
- { "slategrey", 0xff708090 },
- { "snow", 0xfffffafa },
- { "springgreen", 0xff00ff7f },
- { "steelblue", 0xff4682b4 },
- { "tan", 0xffd2b48c },
- { "teal", 0xff008080 },
- { "thistle", 0xffd8bfd8 },
- { "tomato", 0xffff6347 },
- { "turquoise", 0xff40e0d0 },
- { "violet", 0xffee82ee },
- { "violetred", 0xffd02090 },
- { "wheat", 0xfff5deb3 },
- { "white", 0xffffffff },
- { "whitesmoke", 0xfff5f5f5 },
- { "yellow", 0xffffff00 },
- { "yellowgreen", 0xff9acd32 }
- };
- const struct colour_map *entry;
-
- entry = bsearch(name, named_colours,
- sizeof(named_colours) / sizeof(named_colours[0]),
- sizeof(named_colours[0]),
- cmp_colour_name);
-
- if (entry != NULL)
- *result = entry->color;
-
- return entry != NULL;
-}
-
-/**
- * Parse a dimension string
- *
- * \param data Data to parse (NUL-terminated)
- * \param strict Whether to enforce strict parsing rules
- * \param length Pointer to location to receive dimension's length
- * \param unit Pointer to location to receive dimension's unit
- * \return true on success, false on invalid input
- */
-bool parse_dimension(const char *data, bool strict, css_fixed *length,
- css_unit *unit)
-{
- size_t len;
- size_t read;
- css_fixed value;
-
- len = strlen(data);
-
- if (parse_number(data, false, true, &value, &read) == false)
- return false;
-
- if (strict && value < INTTOFIX(1))
- return false;
-
- *length = value;
-
- if (len > read && data[read] == '%')
- *unit = CSS_UNIT_PCT;
- else
- *unit = CSS_UNIT_PX;
-
- return true;
-}
-
-/**
- * Parse a number string
- *
- * \param data Data to parse (NUL-terminated)
- * \param maybe_negative Negative numbers permitted
- * \param real Floating point numbers permitted
- * \param value Pointer to location to receive numeric value
- * \param consumed Pointer to location to receive number of input
- * bytes consumed
- * \return true on success, false on invalid input
- */
-bool parse_number(const char *data, bool maybe_negative, bool real,
- css_fixed *value, size_t *consumed)
-{
- size_t len;
- const uint8_t *ptr;
- int32_t intpart = 0;
- int32_t fracpart = 0;
- int32_t pwr = 1;
- int sign = 1;
-
- *consumed = 0;
-
- len = strlen(data);
- ptr = (const uint8_t *) data;
-
- if (len == 0)
- return false;
-
- /* Skip leading whitespace */
- while (len > 0 && isWhitespace(ptr[0])) {
- len--;
- ptr++;
- }
-
- if (len == 0)
- return false;
-
- /* Extract sign, if any */
- if (ptr[0] == '+') {
- len--;
- ptr++;
- } else if (ptr[0] == '-' && maybe_negative) {
- sign = -1;
- len--;
- ptr++;
- }
-
- if (len == 0)
- return false;
-
- /* Must have a digit [0,9] */
- if ('0' > ptr[0] || ptr[0] > '9')
- return false;
-
- /* Now extract intpart, assuming base 10 */
- while (len > 0) {
- /* Stop on first non-digit */
- if (ptr[0] < '0' || '9' < ptr[0])
- break;
-
- /* Prevent overflow of 'intpart'; proper clamping below */
- if (intpart < (1 << 22)) {
- intpart *= 10;
- intpart += ptr[0] - '0';
- }
- ptr++;
- len--;
- }
-
- /* And fracpart, again, assuming base 10 */
- if (real && len > 1 && ptr[0] == '.' &&
- ('0' <= ptr[1] && ptr[1] <= '9')) {
- ptr++;
- len--;
-
- while (len > 0) {
- if (ptr[0] < '0' || '9' < ptr[0])
- break;
-
- if (pwr < 1000000) {
- pwr *= 10;
- fracpart *= 10;
- fracpart += ptr[0] - '0';
- }
- ptr++;
- len--;
- }
-
- fracpart = ((1 << 10) * fracpart + pwr/2) / pwr;
- if (fracpart >= (1 << 10)) {
- intpart++;
- fracpart &= (1 << 10) - 1;
- }
- }
-
- if (sign > 0) {
- /* If the result is larger than we can represent,
- * then clamp to the maximum value we can store. */
- if (intpart >= (1 << 21)) {
- intpart = (1 << 21) - 1;
- fracpart = (1 << 10) - 1;
- }
- } else {
- /* If the negated result is smaller than we can represent
- * then clamp to the minimum value we can store. */
- if (intpart >= (1 << 21)) {
- intpart = -(1 << 21);
- fracpart = 0;
- } else {
- intpart = -intpart;
- if (fracpart) {
- fracpart = (1 << 10) - fracpart;
- intpart--;
- }
- }
- }
-
- *value = (intpart << 10) | fracpart;
-
- *consumed = ptr - (const uint8_t *) data;
-
- return true;
-}
-
-/**
- * Parse a font \@size attribute
- *
- * \param size Data to parse (NUL-terminated)
- * \param val Pointer to location to receive enum value
- * \param len Pointer to location to receive length
- * \param unit Pointer to location to receive unit
- * \return True on success, false on failure
- */
-bool parse_font_size(const char *size, uint8_t *val,
- css_fixed *len, css_unit *unit)
-{
- static const uint8_t size_map[] = {
- CSS_FONT_SIZE_XX_SMALL,
- CSS_FONT_SIZE_SMALL,
- CSS_FONT_SIZE_MEDIUM,
- CSS_FONT_SIZE_LARGE,
- CSS_FONT_SIZE_X_LARGE,
- CSS_FONT_SIZE_XX_LARGE,
- CSS_FONT_SIZE_DIMENSION /* xxx-large (see below) */
- };
-
- const char *p = size;
- char mode;
- int value = 0;
-
- /* Skip whitespace */
- while (*p != '\0' && isWhitespace(*p))
- p++;
-
- mode = *p;
-
- /* Skip +/- */
- if (mode == '+' || mode == '-')
- p++;
-
- /* Need at least one digit */
- if (*p < '0' || *p > '9') {
- return false;
- }
-
- /* Consume digits, computing value */
- while ('0' <= *p && *p <= '9') {
- value = value * 10 + (*p - '0');
- p++;
- }
-
- /* Resolve relative sizes */
- if (mode == '+')
- value += 3;
- else if (mode == '-')
- value = 3 - value;
-
- /* Clamp to range [1,7] */
- if (value < 1)
- value = 1;
- else if (value > 7)
- value = 7;
-
- if (value == 7) {
- /* Manufacture xxx-large */
- *len = FDIV(FMUL(INTTOFIX(3), INTTOFIX(nsoption_int(font_size))),
- F_10);
- } else {
- /* Len is irrelevant */
- *len = 0;
- }
-
- *unit = CSS_UNIT_PT;
- *val = size_map[value - 1];
-
- return true;
-}
-
-/******************************************************************************
- * Utility functions *
- ******************************************************************************/
-
-/**
- * Determine if a given character is whitespace
- *
- * \param c Character to consider
- * \return true if character is whitespace, false otherwise
- */
-bool isWhitespace(char c)
-{
- return c == ' ' || c == '\t' || c == '\f' || c == '\r' || c == '\n';
-}
-
-/**
- * Determine if a given character is a valid hex digit
- *
- * \param c Character to consider
- * \return true if character is a valid hex digit, false otherwise
- */
-bool isHex(char c)
-{
- return ('0' <= c && c <= '9') ||
- ('A' <= (c & ~0x20) && (c & ~0x20) <= 'F');
-}
-
-/**
- * Convert a character representing a hex digit to the corresponding hex value
- *
- * \param c Character to convert
- * \return Hex value represented by character
- *
- * \note This function assumes an ASCII-compatible character set
- */
-uint8_t charToHex(char c)
-{
- /* 0-9 */
- c -= '0';
-
- /* A-F */
- if (c > 9)
- c -= 'A' - '9' - 1;
-
- /* a-f */
- if (c > 15)
- c -= 'a' - 'A';
-
- return c;
-}
-
diff --git a/css/select.h b/css/select.h
index 13b9e1201..0e0be9578 100644
--- a/css/select.h
+++ b/css/select.h
@@ -49,9 +49,9 @@ css_select_results *nscss_get_style(nscss_select_ctx *ctx, dom_node *n,
css_computed_style *nscss_get_blank_style(nscss_select_ctx *ctx,
const css_computed_style *parent);
-css_error nscss_compute_font_size(void *pw, const css_hint *parent,
- css_hint *size);
-bool nscss_parse_colour(const char *data, css_color *result);
+css_error named_ancestor_node(void *pw, void *node,
+ const css_qname *qname, void **ancestor);
+css_error node_is_visited(void *pw, void *node, bool *match);
#endif