forked from enlightenment/efl
evas/textblock: fix to keep original format when a markup tag is matched to a style tag.
Summary: We can define a style tag as opener, closer and own closer. If there is a markup tag that is matched to style tag, it is reprocessed to format node inside of textblock. But, when the format node will be converted to markup text, '/' character can be appended to text at closer and own closer style tag. Even if original markup tag does not has '/' character, it will be appended according to format node information. It makes some issue when compare input text with output text. @fix Test Plan: This commit includes test case. Reviewers: woohyun, raster, sohyun, tasn Subscribers: herdsman, cedric Differential Revision: https://phab.enlightenment.org/D1037
This commit is contained in:
parent
fdf71e9a66
commit
1984961ba6
|
@ -2936,7 +2936,7 @@ _layout_format_pop(Ctxt *c, const char *format)
|
||||||
Eina_List *redo_nodes = NULL;
|
Eina_List *redo_nodes = NULL;
|
||||||
|
|
||||||
/* Generic pop, should just pop. */
|
/* Generic pop, should just pop. */
|
||||||
if (((format[0] == ' ') && !format[1]) ||
|
if (((format[0] == '/') && !format[1]) ||
|
||||||
!format[0])
|
!format[0])
|
||||||
{
|
{
|
||||||
_format_unref_free(c->obj, fmt);
|
_format_unref_free(c->obj, fmt);
|
||||||
|
@ -2962,7 +2962,7 @@ _layout_format_pop(Ctxt *c, const char *format)
|
||||||
* starting tag, and the starting tag's next char is either
|
* starting tag, and the starting tag's next char is either
|
||||||
* NULL or white. Skip the starting '+'. */
|
* NULL or white. Skip the starting '+'. */
|
||||||
if (_FORMAT_IS_CLOSER_OF(
|
if (_FORMAT_IS_CLOSER_OF(
|
||||||
fmt->fnode->orig_format, format, len))
|
fmt->fnode->orig_format, format + 1, len - 1))
|
||||||
{
|
{
|
||||||
_format_unref_free(c->obj, fmt);
|
_format_unref_free(c->obj, fmt);
|
||||||
break;
|
break;
|
||||||
|
@ -4993,7 +4993,7 @@ _format_changes_invalidate_text_nodes(Ctxt *c)
|
||||||
size_t fstr_len;
|
size_t fstr_len;
|
||||||
fstr_len = strlen(fstr);
|
fstr_len = strlen(fstr);
|
||||||
/* Generic popper, just pop */
|
/* Generic popper, just pop */
|
||||||
if (((fstr[0] == ' ') && !fstr[1]) || !fstr[0])
|
if (((fstr[0] == '/') && !fstr[1]) || !fstr[0])
|
||||||
{
|
{
|
||||||
fstack = eina_list_remove_list(fstack, fstack);
|
fstack = eina_list_remove_list(fstack, fstack);
|
||||||
balance--;
|
balance--;
|
||||||
|
@ -5007,7 +5007,7 @@ _format_changes_invalidate_text_nodes(Ctxt *c)
|
||||||
EINA_LIST_FOREACH(fstack, i, fnode2)
|
EINA_LIST_FOREACH(fstack, i, fnode2)
|
||||||
{
|
{
|
||||||
if (_FORMAT_IS_CLOSER_OF(
|
if (_FORMAT_IS_CLOSER_OF(
|
||||||
fnode2->orig_format, fstr, fstr_len))
|
fnode2->orig_format, fstr + 1, fstr_len - 1))
|
||||||
{
|
{
|
||||||
fstack = eina_list_remove_list(fstack, i);
|
fstack = eina_list_remove_list(fstack, i);
|
||||||
break;
|
break;
|
||||||
|
@ -5901,21 +5901,11 @@ _textblock_style_generic_set(Evas_Object *eo_obj, Evas_Textblock_Style *ts,
|
||||||
const char *match;
|
const char *match;
|
||||||
size_t format_len = eina_stringshare_strlen(fnode->orig_format);
|
size_t format_len = eina_stringshare_strlen(fnode->orig_format);
|
||||||
/* Is this safe to use alloca here? Strings might possibly get large */
|
/* Is this safe to use alloca here? Strings might possibly get large */
|
||||||
char *format = alloca(format_len + 2);
|
|
||||||
|
|
||||||
if (!fnode->opener)
|
if (fnode->own_closer)
|
||||||
{
|
format_len--;
|
||||||
format[0] = '/';
|
|
||||||
format[1] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
format[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
strcat(format, fnode->orig_format);
|
match = _textblock_format_node_from_style_tag(o, fnode, fnode->orig_format,
|
||||||
|
|
||||||
match = _textblock_format_node_from_style_tag(o, fnode, format,
|
|
||||||
format_len);
|
format_len);
|
||||||
|
|
||||||
if (match && fnode->format && strcmp(match, fnode->format))
|
if (match && fnode->format && strcmp(match, fnode->format))
|
||||||
|
@ -6401,11 +6391,7 @@ _markup_get_format_append(Eina_Strbuf *txt, Evas_Object_Textblock_Node_Format *f
|
||||||
|
|
||||||
// FIXME: need to escape
|
// FIXME: need to escape
|
||||||
s = fnode->orig_format;
|
s = fnode->orig_format;
|
||||||
if (!fnode->opener && !fnode->own_closer)
|
|
||||||
eina_strbuf_append_char(txt, '/');
|
|
||||||
eina_strbuf_append(txt, s);
|
eina_strbuf_append(txt, s);
|
||||||
if (fnode->own_closer)
|
|
||||||
eina_strbuf_append_char(txt, '/');
|
|
||||||
}
|
}
|
||||||
eina_strbuf_append_char(txt, '>');
|
eina_strbuf_append_char(txt, '>');
|
||||||
}
|
}
|
||||||
|
@ -7077,7 +7063,7 @@ _evas_textblock_node_format_remove_pair(Eo *eo_obj, Evas_Textblock_Data *o, Evas
|
||||||
size_t fstr_len;
|
size_t fstr_len;
|
||||||
fstr_len = strlen(fstr);
|
fstr_len = strlen(fstr);
|
||||||
/* Generic popper, just pop */
|
/* Generic popper, just pop */
|
||||||
if (((fstr[0] == ' ') && !fstr[1]) || !fstr[0])
|
if (((fstr[0] == '/') && !fstr[1]) || !fstr[0])
|
||||||
{
|
{
|
||||||
fstack = eina_list_remove_list(fstack, fstack);
|
fstack = eina_list_remove_list(fstack, fstack);
|
||||||
if (!fstack)
|
if (!fstack)
|
||||||
|
@ -7095,7 +7081,7 @@ _evas_textblock_node_format_remove_pair(Eo *eo_obj, Evas_Textblock_Data *o, Evas
|
||||||
EINA_LIST_FOREACH(fstack, i, fnode)
|
EINA_LIST_FOREACH(fstack, i, fnode)
|
||||||
{
|
{
|
||||||
if (_FORMAT_IS_CLOSER_OF(
|
if (_FORMAT_IS_CLOSER_OF(
|
||||||
fnode->orig_format, fstr, fstr_len))
|
fnode->orig_format, fstr + 1, fstr_len - 1))
|
||||||
{
|
{
|
||||||
/* Last one, this is our item! */
|
/* Last one, this is our item! */
|
||||||
if (!eina_list_next(i))
|
if (!eina_list_next(i))
|
||||||
|
@ -7723,7 +7709,7 @@ _evas_textblock_node_format_remove_matching(Evas_Textblock_Data *o,
|
||||||
size_t fstr_len;
|
size_t fstr_len;
|
||||||
fstr_len = strlen(fstr);
|
fstr_len = strlen(fstr);
|
||||||
/* Generic popper, just pop (if there's anything to pop). */
|
/* Generic popper, just pop (if there's anything to pop). */
|
||||||
if (formats && (((fstr[0] == ' ') && !fstr[1]) || !fstr[0]))
|
if (formats && (((fstr[0] == '/') && !fstr[1]) || !fstr[0]))
|
||||||
{
|
{
|
||||||
fnode = eina_list_data_get(formats);
|
fnode = eina_list_data_get(formats);
|
||||||
formats = eina_list_remove_list(formats, formats);
|
formats = eina_list_remove_list(formats, formats);
|
||||||
|
@ -7738,7 +7724,7 @@ _evas_textblock_node_format_remove_matching(Evas_Textblock_Data *o,
|
||||||
EINA_LIST_FOREACH_SAFE(formats, i, next, fnode)
|
EINA_LIST_FOREACH_SAFE(formats, i, next, fnode)
|
||||||
{
|
{
|
||||||
if (_FORMAT_IS_CLOSER_OF(
|
if (_FORMAT_IS_CLOSER_OF(
|
||||||
fnode->orig_format, fstr, fstr_len))
|
fnode->orig_format, fstr + 1, fstr_len - 1))
|
||||||
{
|
{
|
||||||
fnode = eina_list_data_get(i);
|
fnode = eina_list_data_get(i);
|
||||||
formats = eina_list_remove_list(formats, i);
|
formats = eina_list_remove_list(formats, i);
|
||||||
|
@ -8519,6 +8505,7 @@ _evas_textblock_node_format_new(Evas_Textblock_Data *o, const char *_format)
|
||||||
if ((format_len > 0) && format[format_len - 1] == '>')
|
if ((format_len > 0) && format[format_len - 1] == '>')
|
||||||
{
|
{
|
||||||
format_len--; /* We don't care about '>' */
|
format_len--; /* We don't care about '>' */
|
||||||
|
n->orig_format = eina_stringshare_add_length(format, format_len);
|
||||||
/* Check if it closes itself, i.e. one of the following:
|
/* Check if it closes itself, i.e. one of the following:
|
||||||
* 1. Ends with a "/" e.g. "<my_tag/>"
|
* 1. Ends with a "/" e.g. "<my_tag/>"
|
||||||
* 2. Is a paragraph separator */
|
* 2. Is a paragraph separator */
|
||||||
|
@ -8562,8 +8549,6 @@ _evas_textblock_node_format_new(Evas_Textblock_Data *o, const char *_format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n->orig_format = eina_stringshare_add_length(format, format_len);
|
|
||||||
|
|
||||||
if (!pre_stripped_format)
|
if (!pre_stripped_format)
|
||||||
pre_stripped_format = n->orig_format;
|
pre_stripped_format = n->orig_format;
|
||||||
}
|
}
|
||||||
|
@ -8591,12 +8576,23 @@ _evas_textblock_node_format_new(Evas_Textblock_Data *o, const char *_format)
|
||||||
/* Strip format */
|
/* Strip format */
|
||||||
{
|
{
|
||||||
const char *tmp = pre_stripped_format;
|
const char *tmp = pre_stripped_format;
|
||||||
|
int len = strlen(tmp);
|
||||||
if ((*tmp == '+') || (*tmp == '-'))
|
if ((*tmp == '+') || (*tmp == '-'))
|
||||||
{
|
{
|
||||||
|
len--;
|
||||||
tmp++;
|
tmp++;
|
||||||
while (*tmp == ' ') tmp++;
|
while (*tmp == ' ') tmp++;
|
||||||
}
|
}
|
||||||
n->format = eina_stringshare_add(tmp);
|
if (tmp[len - 1] == '/')
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
else if (tmp[0] == '/')
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
n->format = eina_stringshare_add_length(tmp, len);
|
||||||
}
|
}
|
||||||
format = n->format;
|
format = n->format;
|
||||||
|
|
||||||
|
@ -9286,11 +9282,25 @@ evas_textblock_node_format_text_get(const Evas_Object_Textblock_Node_Format *fmt
|
||||||
{
|
{
|
||||||
static char *ret = NULL;
|
static char *ret = NULL;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
const char *stripped;
|
||||||
|
size_t stripped_len;
|
||||||
|
|
||||||
if (!fmt) return NULL;
|
if (!fmt) return NULL;
|
||||||
|
|
||||||
if (ret) free(ret);
|
if (ret) free(ret);
|
||||||
ret = malloc(strlen(fmt->orig_format) + 2 + 1);
|
stripped = fmt->orig_format;
|
||||||
|
stripped_len = strlen(fmt->orig_format);
|
||||||
|
if (stripped[stripped_len - 1] == '/')
|
||||||
|
{
|
||||||
|
stripped_len--;
|
||||||
|
}
|
||||||
|
else if (stripped[0] == '/')
|
||||||
|
{
|
||||||
|
stripped++;
|
||||||
|
stripped_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = calloc(stripped_len + 2 + 1, sizeof(char));
|
||||||
tmp = ret;
|
tmp = ret;
|
||||||
|
|
||||||
if (fmt->opener && !fmt->own_closer)
|
if (fmt->opener && !fmt->own_closer)
|
||||||
|
@ -9303,7 +9313,7 @@ evas_textblock_node_format_text_get(const Evas_Object_Textblock_Node_Format *fmt
|
||||||
*(tmp++) = '-';
|
*(tmp++) = '-';
|
||||||
*(tmp++) = ' ';
|
*(tmp++) = ' ';
|
||||||
}
|
}
|
||||||
strcpy(tmp, fmt->orig_format);
|
strncpy(tmp, stripped, stripped_len);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2662,6 +2662,11 @@ START_TEST(evas_textblock_style)
|
||||||
evas_object_textblock_size_formatted_get(tb, &nw, &nh);
|
evas_object_textblock_size_formatted_get(tb, &nw, &nh);
|
||||||
fail_if((w >= nw) || (h >= nh));
|
fail_if((w >= nw) || (h >= nh));
|
||||||
|
|
||||||
|
/* Style tag test */
|
||||||
|
buf = "Test <br><br/><ps><ps/><tab><tab/>";
|
||||||
|
evas_object_textblock_text_markup_set(tb, buf);
|
||||||
|
fail_if(strcmp(buf, evas_object_textblock_text_markup_get(tb)));
|
||||||
|
|
||||||
/* Style padding. */
|
/* Style padding. */
|
||||||
evas_object_textblock_text_markup_set(tb, "Test");
|
evas_object_textblock_text_markup_set(tb, "Test");
|
||||||
evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
|
evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
|
||||||
|
|
Loading…
Reference in New Issue