css: Add gtk_css_token_source_consume_number()

This is totally so we can parse
  color: rgb(calc(255 * 0.3), calc(255 * 0.6), calc(255 * 0.3));
which Webkit totally can, but Firefox and IE totally can't.

And GTK has to be at least the 2nd best CSS engine in the world.
This commit is contained in:
Benjamin Otte
2016-03-18 22:38:24 +01:00
parent 87d3bb5799
commit 945bddf120
4 changed files with 45 additions and 47 deletions

View File

@@ -874,28 +874,6 @@ parse_comma (GtkCssTokenSource *source)
return TRUE;
}
static gboolean
parse_number (GtkCssTokenSource *source,
double *d)
{
const GtkCssToken *token;
token = gtk_css_token_source_get_token (source);
if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_NUMBER))
{
*d = token->number.number;
gtk_css_token_source_consume_token (source);
return TRUE;
}
else
{
gtk_css_token_source_error (source, "Expected a number.");
gtk_css_token_source_consume_all (source);
return FALSE;
}
}
static gboolean
parse_percentage (GtkCssTokenSource *source,
double *d)
@@ -982,11 +960,11 @@ gtk_css_color_value_token_parse (GtkCssTokenSource *source)
}
else
{
if (!parse_number (source, &rgba.red) ||
if (!gtk_css_token_source_consume_number (source, &rgba.red) ||
!parse_comma (source) ||
!parse_number (source, &rgba.green) ||
!gtk_css_token_source_consume_number (source, &rgba.green) ||
!parse_comma (source) ||
!parse_number (source, &rgba.blue))
!gtk_css_token_source_consume_number (source, &rgba.blue))
return NULL;
rgba.red = CLAMP (rgba.red, 0, 255.0) / 255.0;
rgba.green = CLAMP (rgba.green, 0, 255.0) / 255.0;
@@ -996,7 +974,7 @@ gtk_css_color_value_token_parse (GtkCssTokenSource *source)
if (has_alpha)
{
if (!parse_comma (source) ||
!parse_number (source, &rgba.alpha))
!gtk_css_token_source_consume_number (source, &rgba.alpha))
return NULL;
rgba.alpha = CLAMP (rgba.alpha, 0, 1.0);
}
@@ -1044,7 +1022,7 @@ gtk_css_color_value_token_parse (GtkCssTokenSource *source)
if (child == NULL)
return NULL;
if (!parse_comma (source) ||
!parse_number (source, &d))
!gtk_css_token_source_consume_number (source, &d))
{
_gtk_css_value_unref (child);
return NULL;
@@ -1065,7 +1043,7 @@ gtk_css_color_value_token_parse (GtkCssTokenSource *source)
if (child == NULL)
return NULL;
if (!parse_comma (source) ||
!parse_number (source, &d))
!gtk_css_token_source_consume_number (source, &d))
{
_gtk_css_value_unref (child);
return NULL;
@@ -1092,7 +1070,7 @@ gtk_css_color_value_token_parse (GtkCssTokenSource *source)
return NULL;
}
if (!parse_comma (source) ||
!parse_number (source, &d))
!gtk_css_token_source_consume_number (source, &d))
{
_gtk_css_value_unref (child1);
_gtk_css_value_unref (child2);

View File

@@ -333,28 +333,19 @@ token_parse_cubic_bezier (GtkCssTokenSource *source,
gpointer data)
{
double *numbers = data;
const GtkCssToken *token;
token = gtk_css_token_source_get_token (source);
if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_NUMBER))
if (!gtk_css_token_source_consume_number (source, &numbers[n]))
return FALSE;
/* XXX: This error is too late */
if (n % 2 == 0 &&
(numbers[n] < 0 || numbers[n] > 1.0))
{
numbers[n] = token->number.number;
if (n % 2 == 0 &&
(numbers[n] < 0 || numbers[n] > 1.0))
{
gtk_css_token_source_error (source, "Value %g out of range. Must be from 0.0 to 1.0", numbers[n]);
return FALSE;
}
gtk_css_token_source_consume_token (source);
return TRUE;
}
else
{
gtk_css_token_source_error (source, "Expected a number");
gtk_css_token_source_consume_all (source);
gtk_css_token_source_error (source, "Value %g out of range. Must be from 0.0 to 1.0", numbers[n]);
return FALSE;
}
return TRUE;
}
static gboolean

View File

@@ -21,6 +21,7 @@
#include "gtkcsstokensourceprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssprovider.h"
typedef struct _GtkCssTokenSourceTokenizer GtkCssTokenSourceTokenizer;
@@ -392,6 +393,32 @@ gtk_css_token_source_consume_function (GtkCssTokenSource *source,
return result;
}
gboolean
gtk_css_token_source_consume_number (GtkCssTokenSource *source,
double *number)
{
const GtkCssToken *token;
GtkCssValue *value;
token = gtk_css_token_source_get_token (source);
if (gtk_css_token_is (token, GTK_CSS_TOKEN_NUMBER) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER))
{
*number = token->number.number;
gtk_css_token_source_consume_token (source);
return TRUE;
}
/* because CSS allows calc() in numbers. Go CSS! */
value = gtk_css_number_value_token_parse (source, GTK_CSS_PARSE_NUMBER);
if (value == NULL)
return FALSE;
*number = _gtk_css_number_value_get (value, 100);
_gtk_css_value_unref (value);
return TRUE;
}
GtkCssTokenType
gtk_css_token_get_pending_block (GtkCssTokenSource *source)
{

View File

@@ -73,6 +73,8 @@ gboolean gtk_css_token_source_consume_function (GtkCssTokenSour
guint max_args,
gboolean (* parse_func) (GtkCssTokenSource *, guint, gpointer),
gpointer data);
gboolean gtk_css_token_source_consume_number (GtkCssTokenSource *source,
double *number);
void gtk_css_token_source_emit_error (GtkCssTokenSource *source,
const GError *error);