[cbhm] copy&paste error in webkit
[framework/uifw/cbhm.git] / src / xconverter.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  */
17
18 #include "xconverter.h"
19
20 static char *html_to_entry(AppData *ad, int type_index, const char *str);
21 static char *efl_to_entry(AppData *ad, int type_index, const char *str);
22 static char *text_to_entry(AppData *ad, int type_index, const char *str);
23 static char *image_path_to_entry(AppData *ad, int type_index, const char *str);
24
25 static char *make_close_tag(Eina_List* nodes);
26 static char *do_not_convert(AppData *ad, int type_index, const char *str);
27 static char *html_to_efl(AppData *ad, int type_index, const char *str);
28 static char *efl_to_html(AppData *ad, int type_index, const char *str);
29 static char *text_to_html(AppData *ad, int type_index, const char *str);
30 static char *text_to_efl(AppData *ad, int type_index, const char *str);
31 static char *to_text(AppData *ad, int type_index, const char *str);
32 static char *image_path_to_html(AppData *ad, int type_index, const char *str);
33 static char *image_path_to_efl(AppData *ad, int type_index, const char *str);
34 static char *image_path_to_text(AppData *ad, int type_index, const char *str);
35 //static char *efl_to_efl(AppData *ad, int type_index, const char *str);
36 //static char *html_to_html(AppData *ad, int type_index, const char *str);
37 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str);
38
39 int atom_type_index_get(AppData *ad, Ecore_X_Atom atom)
40 {
41         int i, j;
42         for (i = 0; i < ATOM_INDEX_MAX; i++)
43         {
44                 for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
45                         if (ad->targetAtoms[i].atom[j] == atom)
46                                 return i;
47         }
48         return -1;
49 }
50
51 void init_target_atoms(AppData *ad)
52 {
53         int atom_cnt[ATOM_INDEX_MAX] = {
54                 1, 5, 2, 1, 2
55         };
56         char *targetAtomNames[][5] = {
57                 { "TARGETS" },
58                 { "UTF8-STRING", "STRING", "TEXT", "text/plain;charset=utf-8", "text/plain" },
59                 { "text/html;charset=utf-8", "text/html" },
60                 { "application/x-elementary-markup" },
61                 { "text/uri", "text/uri-list" }
62         };
63         text_converter_func converts_for_entry[ATOM_INDEX_MAX] = {
64                 NULL, text_to_entry, html_to_entry, efl_to_entry, image_path_to_entry
65         };
66
67         text_converter_func converts[ATOM_INDEX_MAX][ATOM_INDEX_MAX] = {
68                 {NULL, NULL, NULL, NULL, NULL},
69                 {NULL, do_not_convert, text_to_html, text_to_efl, NULL},
70                 {NULL, to_text, do_not_convert, html_to_efl, NULL},
71                 {NULL, to_text, efl_to_html, do_not_convert, NULL},
72                 {NULL, image_path_to_text, image_path_to_html, image_path_to_efl, image_path_to_image_path}
73         };
74
75         int i, j;
76         for (i = 0; i < ATOM_INDEX_MAX; i++)
77         {
78                 ad->targetAtoms[i].atom_cnt = atom_cnt[i];
79                 ad->targetAtoms[i].name = MALLOC(sizeof(char *) * atom_cnt[i]);
80                 ad->targetAtoms[i].atom = MALLOC(sizeof(Ecore_X_Atom) * atom_cnt[i]);
81                 for (j = 0; j < atom_cnt[i]; j++)
82                 {
83                         DMSG("atomName: %s\n", targetAtomNames[i][j]);
84                         ad->targetAtoms[i].name[j] = strdup(targetAtomNames[i][j]);
85                         ad->targetAtoms[i].atom[j] = ecore_x_atom_get(targetAtomNames[i][j]);
86                 }
87                 ad->targetAtoms[i].convert_for_entry = converts_for_entry[i];
88
89                 for (j = 0; j < ATOM_INDEX_MAX; j++)
90                         ad->targetAtoms[i].convert_to_target[j] = converts[i][j];
91                 //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, target_converters[i]);
92                 //ecore_x_selection_converter_atom_add(ad->targetAtoms[i].atom, generic_converter);
93         }
94 }
95
96 void depose_target_atoms(AppData *ad)
97 {
98         int i, j;
99         for (i = 0; i < ATOM_INDEX_MAX; i++)
100         {
101                 for (j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
102                 {
103                         if (ad->targetAtoms[i].name[j])
104                                 FREE(ad->targetAtoms[i].name[j]);
105                 }
106                 if (ad->targetAtoms[i].name)
107                         FREE(ad->targetAtoms[i].name);
108                 if (ad->targetAtoms[i].atom)
109                         FREE(ad->targetAtoms[i].atom);
110         }
111 }
112
113 static Eina_Bool targets_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
114 {
115         CALLED();
116
117         int count;
118         int i, j;
119
120         for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
121         {
122                 if (ad->targetAtoms[item->type_index].convert_to_target[i])
123                         count += ad->targetAtoms[i].atom_cnt;
124         }
125
126         *data_ret = MALLOC(sizeof(Ecore_X_Atom) * count);
127         DMSG("item_type: %d, target Atom cnt: %d\n", item->type_index, count);
128         if (!*data_ret)
129                 return EINA_FALSE;
130
131         for (i = 0, count = 0; i < ATOM_INDEX_MAX; i++)
132         {
133                 if (ad->targetAtoms[item->type_index].convert_to_target[i])
134                 {
135                         for(j = 0; j < ad->targetAtoms[i].atom_cnt; j++)
136                         {
137                                 ((Ecore_X_Atom *)*data_ret)[count++] = ad->targetAtoms[i].atom[j];
138                                 DMSG("send target atom: %s\n", ad->targetAtoms[i].name[j]);
139                         }
140                 }
141         }
142
143         if (size_ret) *size_ret = count;
144         if (ttype) *ttype = ECORE_X_ATOM_ATOM;
145         if (tsize) *tsize = 32;
146         return EINA_TRUE;
147 }
148
149 Eina_Bool generic_converter(AppData *ad, Ecore_X_Atom reqAtom, CNP_ITEM *item, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *tsize)
150 {
151         CALLED();
152
153         if (ad->targetAtoms[ATOM_INDEX_TARGET].atom[0] == reqAtom)
154                 return targets_converter(ad, reqAtom, item, data_ret, size_ret, ttype, tsize);
155
156         int req_index = atom_type_index_get(ad, reqAtom);
157         int type_index = item->type_index;
158
159         if (ad->targetAtoms[type_index].convert_to_target[req_index])
160         {
161                 *data_ret = ad->targetAtoms[type_index].convert_to_target[req_index](ad, type_index, item->data);
162                 if (!*data_ret)
163                         return EINA_FALSE;
164                 if (size_ret) *size_ret = strlen(*data_ret);
165                 if (ttype) *ttype = ad->targetAtoms[item->type_index].atom[0];
166                 if (tsize) *tsize = 8;
167                 return EINA_TRUE;
168         }
169
170         return EINA_FALSE;
171 }
172
173 /* For convert EFL to HTML */
174
175 #define TAGPOS_START    0x00000001
176 #define TAGPOS_END      0x00000002
177 #define TAGPOS_ALONE    0x00000003
178
179 /* TEXTBLOCK tag using stack but close tag word has no mean maybe bug...
180  * TEXTBLOCK <b>bold<font>font</b>bold</font>
181  * HTML <b>bold<font>font bold</b>font</font> */
182
183 typedef struct _TagTable {
184         char *src;
185         char *dst;
186 }TagTable;
187
188 TagTable _EFLtoHTMLConvertTable[] = {
189         {"font", "font"},
190         {"underline", "del"},
191         {"strikethrough", "ins"},
192         {"br", "br"},
193         {"ps", "br"},
194         {"b", "b"},
195         {"item", "img"}
196 };
197
198 TagTable _HTMLtoEFLConvertTable[] = {
199         {"font", ""},
200         {"del", "underline"},
201         {"u", "underline"},
202         {"ins", "strikethrough"},
203         {"s", "strikethrough"},
204         {"br", "br"},
205         {"b", "b"},
206         {"strong", "b"},
207         {"img", "item"}
208 };
209
210
211 typedef struct _TagNode TagNode, *PTagNode;
212 struct _TagNode {
213         char *tag;  //EINA_STRINGSHARE if NULL just str
214         char *tag_str;
215         char *str;
216         const char *pos_in_ori_str;
217         PTagNode matchTag;
218         void *tagData;
219         unsigned char tagPosType;
220 };
221
222 typedef struct _FontTagData FontTagData, *PFontTagData;
223 struct _FontTagData {
224         char *name;
225         char *color;
226         char *size;
227         char *bg_color;
228 };
229
230
231 typedef struct _ItemTagData ItemTagData, *PItemTagData;
232 struct _ItemTagData {
233         char *href;
234         char *width;
235         char *height;
236 };
237
238 #define SAFEFREE(ptr) \
239         do\
240 {\
241         if (ptr)\
242         FREE(ptr);\
243         ptr = NULL;\
244 } while(0);\
245
246 #define freeAndAssign(dst, value) \
247         do\
248 {\
249         if (value)\
250         {\
251                 SAFEFREE(dst);\
252                 dst = value;\
253         }\
254 } while(0);
255
256 static PTagNode _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str);
257 static PTagNode _get_start_node(const char *str);
258 static PTagNode _get_next_node(PTagNode prev);
259 static void _delete_node(PTagNode node);
260 static void _link_match_tags(Eina_List *nodes);
261 static char *_get_tag_value(const char *tag_str, const char *tag_name);
262 static char *_convert_to_html(Eina_List* nodes);
263 static void _set_EFL_tag_data(Eina_List* nodes);
264 static char *_convert_to_edje(Eina_List* nodes);
265 static void _set_HTML_tag_data(Eina_List* nodes);
266 static void cleanup_tag_list(Eina_List *nodeList);
267 static PFontTagData _set_EFL_font_data(PFontTagData data, const char *tag_str);
268 static PItemTagData _set_EFL_item_data(PItemTagData data, const char *tag_str);
269 static PFontTagData _set_HTML_font_data(PFontTagData data, const char *tag_str);
270 static PItemTagData _set_HTML_img_data(PItemTagData data, const char *tag_str);
271
272 #ifdef DEBUG
273 static void _dumpNode(Eina_List* nodes);
274 #endif
275
276 static PTagNode
277 _new_tag_node(char *tag, char *tag_str, char* str, const char *pos_in_ori_str)
278 {
279         PTagNode newNode = CALLOC(1, sizeof(TagNode));
280         if (tag)
281                 eina_str_tolower(&tag);
282         newNode->tag = tag;
283         if (tag_str)
284                 eina_str_tolower(&tag_str);
285         newNode->tag_str = tag_str;
286         newNode->str = str;
287         newNode->pos_in_ori_str = pos_in_ori_str;
288         return newNode;
289 }
290
291 static PTagNode
292 _get_start_node(const char *str)
293 {
294         char *startStr = NULL;
295         if (!str || str[0] == '\0')
296                 return NULL;
297
298         if (str[0] != '<')
299         {
300                 char *tagStart = strchr(str, '<');
301                 if (!tagStart)
302                         startStr = strdup(str);
303                 else
304                 {
305                         int strLength = tagStart - str;
306                         startStr = MALLOC(sizeof(char) * (strLength + 1));
307                         strncpy(startStr, str, strLength);
308                         startStr[strLength] = '\0';
309                 }
310         }
311
312         return _new_tag_node(NULL, NULL, startStr, str);
313 }
314
315 static PTagNode
316 _get_next_node(PTagNode prev)
317 {
318         PTagNode retTag = NULL;
319         char *tagStart;
320         char *tagEnd;
321         char *tagNameEnd = NULL;
322         char *nextTagStart;
323
324         if (prev->tag == NULL)
325                 tagStart = strchr(prev->pos_in_ori_str, '<');
326         else
327                 tagStart = strchr(prev->pos_in_ori_str + 1, '<');
328
329         if (!tagStart)
330                 return retTag;
331
332         tagEnd = strchr(tagStart, '>');
333         nextTagStart = strchr(tagStart + 1, '<');
334
335         if (!tagEnd || (nextTagStart && (nextTagStart < tagEnd)))
336                 return _get_start_node(tagStart + 1);
337
338         int spCnt = 5;
339         char *spArray[spCnt];
340         spArray[0] = strchr(tagStart, '=');
341         spArray[1] = strchr(tagStart, '_');
342         spArray[2] = strchr(tagStart, ' ');
343         spArray[3] = strchr(tagStart, '\t');
344         spArray[4] = strchr(tagStart, '\n');
345         tagNameEnd = tagEnd;
346
347         int i;
348         for (i = 0; i < spCnt; i++)
349         {
350                 if (spArray[i] && spArray[i] < tagNameEnd)
351                         tagNameEnd = spArray[i];
352         }
353
354         int tagLength = tagNameEnd - tagStart - 1;
355         char *tagName = NULL;
356         if (!strncmp(&tagStart[1], "/item", tagLength))
357                 tagName = strdup("");
358         else
359                 tagName = strndup(&tagStart[1], tagLength);
360
361         int tagStrLength = 0;
362         char *tagStr = NULL;
363         if (tagName)
364         {
365                 tagStrLength = tagEnd - tagStart + 1;
366                 tagStr = strndup(tagStart, tagStrLength);
367         }
368
369         unsigned int strLength = nextTagStart ? (unsigned int)(nextTagStart - tagEnd - 1) : strlen(&tagEnd[1]);
370         char *str = strndup(&tagEnd[1], strLength);
371
372         retTag = _new_tag_node(tagName, tagStr, str, tagStart);
373         return retTag;
374 }
375
376
377 static void
378 _delete_node(PTagNode node)
379 {
380         if (node)
381         {
382                 SAFEFREE(node->tag_str);
383                 SAFEFREE(node->str);
384
385                 if (node->tagData)
386                 {
387                         if (node->tag)
388                         {
389                                 if (!strcmp("font", node->tag))
390                                 {
391                                         PFontTagData data = node->tagData;
392                                         SAFEFREE(data->name);
393                                         SAFEFREE(data->color);
394                                         SAFEFREE(data->size);
395                                         SAFEFREE(data->bg_color);
396                                 }
397                                 if (!strcmp("item", node->tag))
398                                 {
399                                         PItemTagData data = node->tagData;
400                                         SAFEFREE(data->href);
401                                         SAFEFREE(data->width);
402                                         SAFEFREE(data->height);
403                                 }
404
405                         }
406                         SAFEFREE(node->tagData);
407                 }
408                 SAFEFREE(node->tag);
409                 SAFEFREE(node);
410         }
411 }
412
413 static void
414 _link_match_tags(Eina_List *nodes)
415 {
416         Eina_List *stack = NULL;
417
418         PTagNode trail, popData;
419         Eina_List *l, *r;
420
421         EINA_LIST_FOREACH(nodes, l, trail)
422         {
423                 if (!trail->tag || trail->tag[0] == '\0')
424                         continue;
425                 if (!strcmp("br/", trail->tag))
426                 {
427                         trail->tagPosType = TAGPOS_ALONE;
428                         continue;
429                 }
430                 else if (!strcmp("item", trail->tag) || !strcmp("img", trail->tag))
431                 {
432                         trail->tagPosType = TAGPOS_ALONE;
433                         continue;
434                 }
435
436                 if (trail->tag[0] != '/') // PUSH
437                 {
438                         stack = eina_list_append(stack, trail);
439                         /*             eina_array_push(stack, trail);
440                                                    DMSG("stack: %d, tag %s\n", eina_array_count_get(stack), trail->tag);*/
441                         DMSG("stack: %d, tag %s\n", eina_list_count(stack), trail->tag);
442                 }
443                 else // POP
444                 {
445                         if (!eina_list_count(stack))
446                         {
447                                 DMSG("tag not matched %s\n", trail->tag);
448                                 continue;
449                         }
450
451                         EINA_LIST_REVERSE_FOREACH(stack, r, popData)
452                         {
453                                 if (popData->tag && !strcmp(popData->tag, &trail->tag[1]))
454                                 {
455                                         popData->tagPosType = TAGPOS_START;
456                                         trail->tagPosType = TAGPOS_END;
457                                         popData->matchTag = trail;
458                                         trail->matchTag = popData;
459                                         stack = eina_list_remove_list(stack, r);
460                                         break;
461                                 }
462                         }
463                         /*             popData = eina_array_pop(stack);
464
465                                                    popData->tagPosType = TAGPOS_START;
466                                                    trail->tagPosType = TAGPOS_END;
467                                                    popData->matchTag = trail;
468                                                    trail->matchTag = popData;
469                                                    DMSG("pop stack: %d, tag %s\n", eina_array_count_get(stack), trail->tag);
470                          */
471                 }
472         }
473
474         /*   if (eina_array_count_get(stack))
475                  DMSG("stack state: %d, tag %s\n", eina_array_count_get(stack), trail->tag);*/
476
477         /* Make Dummy close tag */
478         /*   while ((popData = eina_array_pop(stack)))  */
479
480         EINA_LIST_REVERSE_FOREACH(stack, r, popData)
481         {
482                 PTagNode newData;
483                 int tagLength = strlen(popData->tag);
484                 char *tagName = MALLOC(sizeof(char) * (tagLength + 2));
485
486                 tagName[0] = '/';
487                 tagName[1] = '\0';
488                 strcat(tagName, popData->tag);
489
490                 newData = _new_tag_node(tagName, NULL, NULL, NULL);
491                 popData->tagPosType = TAGPOS_START;
492                 newData->tagPosType = TAGPOS_END;
493                 popData->matchTag = newData;
494                 newData->matchTag = popData;
495                 nodes = eina_list_append(nodes, newData);
496                 /*        DMSG("stack: %d, tag %s\n", eina_array_count_get(stack), popData->tag);*/
497         }
498         /*   DMSG("stack_top: %d\n", eina_array_count_get(stack));
499                  eina_array_free(stack);*/
500         eina_list_free(stack);
501 }
502
503 static char *
504 _get_tag_value(const char *tag_str, const char *tag_name)
505 {
506         if (!tag_name || !tag_str)
507                 return NULL;
508
509         char *tag;
510         if ((tag = strstr(tag_str, tag_name)))
511         {
512                 if (tag[strlen(tag_name)] == '_')
513                         return NULL;
514                 char *value = strchr(tag, '=');
515                 if (value)
516                 {
517                         do
518                         {
519                                 value++;
520                         } while (!isalnum(*value) && *value != '#');
521
522                         int spCnt = 6;
523                         char *spArray[spCnt];
524                         spArray[0] = strchr(value, ' ');
525                         spArray[1] = strchr(value, '>');
526                         spArray[2] = strchr(value, '\"');
527                         spArray[3] = strchr(value, '\'');
528                         spArray[4] = strchr(value, '\t');
529                         spArray[5] = strchr(value, '\n');
530                         char *valueEnd = strchr(value, '\0');
531
532                         int i;
533                         int start = 0;
534                         if ((!strncmp(tag_str, "<item", 5) && !strcmp(tag_name, "href")) // EFL img tag
535                || (!strncmp(tag_str, "<img", 4) && !strcmp(tag_name, "src"))) // HTML img tag
536                start = 1;
537
538                         for (i = start; i < spCnt; i++)
539                         {
540                                 if (spArray[i] && spArray[i] < valueEnd)
541                                         valueEnd = spArray[i];
542                         }
543
544                         int valueLength = valueEnd - value;
545                         return strndup(value, valueLength);
546                 }
547         }
548         return NULL;
549 }
550
551 static PFontTagData
552 _set_EFL_font_data(PFontTagData data, const char *tag_str)
553 {
554         char *value;
555
556         if (!data)
557                 data = CALLOC(1, sizeof(FontTagData));
558         value = _get_tag_value(tag_str, "font_size");
559         freeAndAssign(data->size, value);
560         value = _get_tag_value(tag_str, "color");
561         freeAndAssign(data->color, value);
562         value = _get_tag_value(tag_str, "bgcolor");
563         freeAndAssign(data->bg_color, value);
564         value = _get_tag_value(tag_str, "font");
565         freeAndAssign(data->name, value);
566
567         return data;
568 }
569
570 static PItemTagData
571 _set_EFL_item_data(PItemTagData data, const char *tag_str)
572 {
573         char *value;
574
575         if (!data)
576                 data = CALLOC(1, sizeof(ItemTagData));
577         value = _get_tag_value(tag_str, "href");
578         if (value)
579         {
580                 char *path = strstr(value, "file://");
581                 if (path)
582                 {
583                         char *modify = MALLOC(sizeof(char) * (strlen(value) + 1));
584                         strncpy(modify, "file://", 8);
585                         path += 7;
586                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
587                         {
588                                 path++;
589                         }
590                         strcat(modify, path);
591                         data->href = modify;
592                         DMSG("image href ---%s---\n", data->href);
593                         FREE(value);
594                 }
595                 else
596                         freeAndAssign(data->href, value);
597         }
598
599         value = _get_tag_value(tag_str, "absize");
600         if (value)
601         {
602                 char *xpos = strchr(value, 'x');
603                 if (xpos)
604                 {
605                         int absizeLen = strlen(value);
606                         freeAndAssign(data->width, strndup(value, xpos - value));
607                         freeAndAssign(data->height, strndup(xpos + 1, absizeLen - (xpos - value) - 1));
608                         DMSG("image width: -%s-, height: -%s-\n", data->width, data->height);
609                 }
610                 FREE(value);
611         }
612         return data;
613 }
614
615 static void
616 _set_EFL_tag_data(Eina_List* nodes)
617 {
618         PTagNode trail;
619         Eina_List *l;
620
621         EINA_LIST_FOREACH(nodes, l, trail)
622         {
623                 if (!trail->tag)
624                         continue;
625                 if (!strcmp("font", trail->tag) || !strcmp("color", trail->tag))
626                         trail->tagData = _set_EFL_font_data(trail->tagData, trail->tag_str);
627                 else if (!strcmp("item", trail->tag))
628                         trail->tagData = _set_EFL_item_data(trail->tagData, trail->tag_str);
629         }
630 }
631
632 static PFontTagData
633 _set_HTML_font_data(PFontTagData data, const char *tag_str)
634 {
635         char *value;
636
637         if (!data)
638                 data = CALLOC(1, sizeof(FontTagData));
639         value = _get_tag_value(tag_str, "size");
640         freeAndAssign(data->size, value);
641         value = _get_tag_value(tag_str, "color");
642         freeAndAssign(data->color, value);
643         value = _get_tag_value(tag_str, "bgcolor");
644         freeAndAssign(data->bg_color, value);
645         value = _get_tag_value(tag_str, "face");
646         freeAndAssign(data->name, value);
647
648         return data;
649 }
650
651 static PItemTagData
652 _set_HTML_img_data(PItemTagData data, const char *tag_str)
653 {
654         char *value;
655
656         if (!data)
657                 data = CALLOC(1, sizeof(ItemTagData));
658         value = _get_tag_value(tag_str, "src");
659         if (value)
660         {
661                 char *path = strstr(value, "file://");
662                 if (path)
663                 {
664                         char *modify = MALLOC(sizeof(char) * (strlen(value) + 1));
665                         strncpy(modify, "file://", 8);
666                         path += 7;
667                         while (path[1] && path[0] && path[1] == '/' && path[0] == '/')
668                         {
669                                 path++;
670                         }
671                         strcat(modify, path);
672                         data->href = modify;
673                         DMSG("image src ---%s---\n", data->href);
674                         FREE(value);
675                 }
676                 else
677                         freeAndAssign(data->href, value);
678         }
679
680         value = _get_tag_value(tag_str, "width");
681         freeAndAssign(data->width, value);
682         value = _get_tag_value(tag_str, "height");
683         freeAndAssign(data->height, value);
684         return data;
685 }
686
687 static void
688 _set_HTML_tag_data(Eina_List* nodes)
689 {
690         PTagNode trail;
691         Eina_List *l;
692
693         EINA_LIST_FOREACH(nodes, l, trail)
694         {
695                 if (!trail->tag)
696                         continue;
697                 if (!strcmp("font", trail->tag) || !strcmp("color", trail->tag))
698                         trail->tagData = _set_HTML_font_data(trail->tagData, trail->tag_str);
699                 else if (!strcmp("img", trail->tag))
700                         trail->tagData = _set_HTML_img_data(trail->tagData, trail->tag_str);
701         }
702 }
703
704 #ifdef DEBUG
705 static void
706 _dumpNode(Eina_List* nodes)
707 {
708         PTagNode trail;
709         Eina_List *l;
710
711         EINA_LIST_FOREACH(nodes, l, trail)
712         {
713                 DMSG("tag: %s, tag_str: %s, str: %s, tagPosType: %d\n",
714                                 trail->tag, trail->tag_str, trail->str, trail->tagPosType);
715                 DMSG("matchTag: %x ", (unsigned int)trail->matchTag);
716                 if (trail->matchTag)
717                         DMSG("matchTag->tag_str: %s", trail->matchTag->tag_str);
718                 if (trail->tagData)
719                 {
720                         if (!strcmp(trail->tag, "font"))
721                         {
722                                 PFontTagData data = trail->tagData;
723                                 DMSG(" tagData->name: %s, tagData->color: %s, tagData->size: %s, tagData->bg_color: %s",
724                                                 data->name, data->color, data->size, data->bg_color);
725                         }
726                         else if (!strcmp(trail->tag, "item") || !strcmp(trail->tag, "img"))
727                         {
728                                 PItemTagData data = trail->tagData;
729                                 DMSG(" tagData->href: %s, tagData->width: %s, tagData->height: %s",
730                                                 data->href, data->width, data->height);
731                         }
732                         else
733                                 DMSG("\nERROR!!!! not need tagData");
734                 }
735                 DMSG("\n");
736         }
737 }
738 #endif
739
740 static char *
741 _convert_to_html(Eina_List* nodes)
742 {
743         PTagNode trail;
744         Eina_List *l;
745
746         Eina_Strbuf *html = eina_strbuf_new();
747
748         int tableCnt = sizeof(_EFLtoHTMLConvertTable) / sizeof(TagTable);
749
750         EINA_LIST_FOREACH(nodes, l, trail)
751         {
752                 if (trail->tag)
753                 {
754                         char *tagName = trail->tagPosType == TAGPOS_END ?
755                                 trail->matchTag->tag : trail->tag;
756                         int j;
757                         for(j = 0; j < tableCnt; j++)
758                         {
759                                 if (!strcmp(_EFLtoHTMLConvertTable[j].src, tagName))
760                                 {
761                                         switch(trail->tagPosType)
762                                         {
763                                                 case TAGPOS_END:
764                                                         eina_strbuf_append(html, "</");
765                                                         break;
766                                                 default:
767                                                         eina_strbuf_append(html, "<");
768                                                         break;
769                                         }
770
771                                         eina_strbuf_append(html, _EFLtoHTMLConvertTable[j].dst);
772                                         if (trail->tagPosType != TAGPOS_END)
773                                         {
774                                                 if (!strcmp(_EFLtoHTMLConvertTable[j].src, "font"))
775                                                 {
776                                                         PFontTagData data = trail->tagData;
777                                                         if (data->name)
778                                                         {
779                                                         }
780                                                         if (data->color)
781                                                         {
782                                                                 char *color = strdup(data->color);
783                                                                 if (color && color[0] == '#' && strlen(color) == 9)
784                                                                 {
785                                                                         color[7] = '\0';
786                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", color);
787                                                                         FREE(color);
788                                                                 }
789                                                                 else
790                                                                         eina_strbuf_append_printf(html, " color=\"%s\"", data->color);
791                                                         }
792                                                         if (data->size)
793                                                                 eina_strbuf_append_printf(html, " size=\"%s\"", data->size);
794                                                         if (data->bg_color)
795                                                         {
796                                                         }
797                                                 }
798                                                 else if (!strcmp(_EFLtoHTMLConvertTable[j].src, "item"))
799                                                 {
800                                                         PItemTagData data = trail->tagData;
801                                                         if (data->href)
802                                                                 eina_strbuf_append_printf(html, " src=\"%s\"", data->href);
803                                                         if (data->width)
804                                                                 eina_strbuf_append_printf(html, " width=\"%s\"", data->width);
805                                                         if (data->height)
806                                                                 eina_strbuf_append_printf(html, " height=\"%s\"", data->height);
807                                                 }
808                                         }
809                                         switch(trail->tagPosType)
810                                         {
811                                                 /* closed tag does not need in HTML
812                                                    case TAGPOS_ALONE:
813                                                    eina_strbuf_append(html, " />");
814                                                    break;*/
815                                                 default:
816                                                         eina_strbuf_append(html, ">");
817                                                         break;
818                                         }
819                                         break;
820                                 }
821                         }
822                 }
823                 if (trail->str)
824                         eina_strbuf_append(html, trail->str);
825         }
826
827         eina_strbuf_replace_all(html, "  ", " &nbsp;");
828         char *ret = eina_strbuf_string_steal(html);
829         eina_strbuf_free(html);
830         return ret;
831 }
832
833 #define IMAGE_DEFAULT_WIDTH "240"
834 #define IMAGE_DEFAULT_HEIGHT "180"
835
836
837 static char *
838 _convert_to_edje(Eina_List* nodes)
839 {
840         PTagNode trail;
841         Eina_List *l;
842
843         Eina_Strbuf *edje = eina_strbuf_new();
844
845         int tableCnt = sizeof(_HTMLtoEFLConvertTable) / sizeof(TagTable);
846
847         EINA_LIST_FOREACH(nodes, l, trail)
848         {
849                 if (trail->tag)
850                 {
851                         char *tagName = trail->tagPosType == TAGPOS_END ?
852                                 trail->matchTag->tag : trail->tag;
853                         int j;
854                         for(j = 0; j < tableCnt; j++)
855                         {
856                                 if (!strcmp(_HTMLtoEFLConvertTable[j].src, tagName))
857                                 {
858                                         if (_HTMLtoEFLConvertTable[j].dst[0] != '\0')
859                                         {
860                                                 switch(trail->tagPosType)
861                                                 {
862                                                         case TAGPOS_END:
863                                                                 eina_strbuf_append(edje, "</");
864                                                                 break;
865                                                         default:
866                                                                 eina_strbuf_append(edje, "<");
867                                                                 break;
868                                                 }
869
870                                                 eina_strbuf_append(edje, _HTMLtoEFLConvertTable[j].dst);
871                                         }
872                                         if (trail->tagPosType != TAGPOS_END)
873                                         {
874                                                 if (!strcmp(_HTMLtoEFLConvertTable[j].src, "font"))
875                                                 {
876                                                         PFontTagData data = trail->tagData;
877                                                         if (data->name)
878                                                         {
879                                                         }
880                                                         if (data->color)
881                                                         {
882                                                                 if (data->color[0] == '#' && strlen(data->color) == 7)
883                                                                         eina_strbuf_append_printf(edje, "<color=%sff>", data->color);
884                                                                 else
885                                                                         eina_strbuf_append_printf(edje, "<color=%s>", data->color);
886
887                                                         }
888                                                         if (data->size)
889                                                                 eina_strbuf_append_printf(edje, "<font_size=%s>", data->size);
890                                                         if (data->bg_color)
891                                                         {
892                                                         }
893                                                         break;
894                                                 }
895                                                 else if (!strcmp(_HTMLtoEFLConvertTable[j].src, "img"))
896                                                 {
897                                                         PItemTagData data = trail->tagData;
898                                                         char *width = IMAGE_DEFAULT_WIDTH, *height = IMAGE_DEFAULT_HEIGHT;
899                                                         if (data->width)
900                                                                 width = data->width;
901                                                         if (data->height)
902                                                                 height = data->height;
903                                                         eina_strbuf_append_printf(edje, " absize=%sx%s", width, height);
904                                                         if (data->href)
905                                                                 eina_strbuf_append_printf(edje, " href=%s></item>", data->href);
906                                                         break;
907                                                 }
908                                         }
909                                         else
910                                         {
911                                                 if (_HTMLtoEFLConvertTable[j].dst[0] == '\0')
912                                                 {
913                                                         if (!strcmp(_HTMLtoEFLConvertTable[j].src, "font"))
914                                                         {
915                                                                 if (trail->matchTag->tagData)
916                                                                 {
917                                                                         PFontTagData data = trail->matchTag->tagData;
918                                                                         if (data->name)
919                                                                         {
920                                                                         }
921                                                                         if (data->color)
922                                                                                 eina_strbuf_append_printf(edje, "</color>");
923                                                                         if (data->size)
924                                                                                 eina_strbuf_append_printf(edje, "</font>");
925                                                                         if (data->bg_color)
926                                                                         {
927                                                                         }
928                                                                         break;
929                                                                 }
930                                                         }
931                                                 }
932                                         }
933                                         switch(trail->tagPosType)
934                                         {
935                                                 /* not support in efl
936                                                    case TAGPOS_ALONE:
937                                                    eina_strbuf_append(edje, " />");
938                                                    break;
939                                                  */
940                                                 default:
941                                                         eina_strbuf_append(edje, ">");
942                                                         break;
943                                         }
944                                         break;
945                                 }
946                         }/* for(j = 0; j < tableCnt; j++) end */
947                 }
948                 if (trail->str)
949                         eina_strbuf_append(edje, trail->str);
950         }
951
952         eina_strbuf_replace_all(edje, "&nbsp;", " ");
953         char *ret = eina_strbuf_string_steal(edje);
954         eina_strbuf_free(edje);
955         return ret;
956 }
957
958 char *string_for_entry_get(AppData *ad, int type_index, const char *str)
959 {
960         DMSG("type_index: %d ", type_index);
961         DMSG("str: %s\n", str);
962         if (ad->targetAtoms[type_index].convert_for_entry)
963                 return ad->targetAtoms[type_index].convert_for_entry(ad, type_index, str);
964         return NULL;
965 }
966
967 static char *make_close_tag(Eina_List* nodes)
968 {
969         CALLED();
970         PTagNode trail;
971         Eina_List *l;
972
973         Eina_Strbuf *tag_str = eina_strbuf_new();
974
975         EINA_LIST_FOREACH(nodes, l, trail)
976         {
977                 if (trail->tag)
978                 {
979                         if (trail->tag_str)
980                                 eina_strbuf_append(tag_str, trail->tag_str);
981                         else
982                         {
983                                 eina_strbuf_append(tag_str, "<");
984                                 eina_strbuf_append(tag_str, trail->tag);
985                                 eina_strbuf_append(tag_str, ">");
986                         }
987                 }
988                 if (trail->str)
989                         eina_strbuf_append(tag_str, trail->str);
990         }
991
992         char *ret = eina_strbuf_string_steal(tag_str);
993         eina_strbuf_free(tag_str);
994         return ret;
995 }
996
997 static char *do_not_convert(AppData *ad, int type_index, const char *str)
998 {
999         DMSG("str: %s\n", str);
1000         if (type_index != ATOM_INDEX_TEXT)
1001         {
1002                 Eina_List *nodeList = NULL;
1003                 PTagNode nodeData;
1004
1005                 nodeData = _get_start_node(str);
1006
1007                 while (nodeData)
1008                 {
1009                         nodeList = eina_list_append(nodeList, nodeData);
1010                         nodeData = _get_next_node(nodeData);
1011                 }
1012
1013                 _link_match_tags(nodeList);
1014
1015 #ifdef DEBUG
1016                 _dumpNode(nodeList);
1017 #endif
1018                 char *ret = make_close_tag(nodeList);
1019                 cleanup_tag_list(nodeList);
1020                 DMSG("convert str: %s\n", ret);
1021                 return ret;
1022         }
1023         return strdup(str);
1024 }
1025 /*
1026    static char *efl_to_efl(AppData *ad, int type_index, const char *str)
1027    {
1028    CALLED();
1029    return NULL;
1030    }
1031
1032    static char *html_to_html(AppData *ad, int type_index, const char *str)
1033    {
1034    CALLED();
1035    return NULL;
1036    }
1037  */
1038
1039 #define IMAGE_DEFAULT_WIDTH "240"
1040 #define IMAGE_DEFAULT_HEIGHT "180"
1041 static char *make_image_path_tag(int type_index, const char *str)
1042 {
1043         char *img_tag_str = "file://%s";
1044         char *efl_img_tag = "<item absize="IMAGE_DEFAULT_WIDTH"x"IMAGE_DEFAULT_HEIGHT" href=file://%s>";
1045         char *html_img_tag = "<img src=\"file://%s\">";
1046
1047         switch (type_index)
1048         {
1049                 case ATOM_INDEX_HTML:
1050                         img_tag_str = html_img_tag;
1051                         break;
1052                 case ATOM_INDEX_EFL:
1053                         img_tag_str = efl_img_tag;
1054                         break;
1055                 case ATOM_INDEX_TEXT:
1056                 case ATOM_INDEX_IMAGE:
1057                         break;
1058                 default:
1059                         DMSG("ERROR: wrong type_index: %d\n", type_index);
1060                         return NULL;
1061         }
1062
1063         size_t len = snprintf(NULL, 0, img_tag_str, str) + 1;
1064         char *ret = MALLOC(sizeof(char) * len);
1065         if (ret)
1066                 snprintf(ret, len, img_tag_str, str);
1067         return ret;
1068 }
1069
1070 static char *image_path_to_text(AppData *ad, int type_index, const char *str)
1071 {
1072         DMSG("str: %s\n", str);
1073         return make_image_path_tag(ATOM_INDEX_TEXT, str);
1074 }
1075
1076 static char *image_path_to_html(AppData *ad, int type_index, const char *str)
1077 {
1078         DMSG("str: %s\n", str);
1079         return make_image_path_tag(ATOM_INDEX_HTML, str);
1080 }
1081
1082 static char *image_path_to_efl(AppData *ad, int type_index, const char *str)
1083 {
1084         DMSG("str: %s\n", str);
1085         return make_image_path_tag(ATOM_INDEX_EFL, str);
1086 }
1087
1088 static char *image_path_to_image_path(AppData *ad, int type_index, const char *str)
1089 {
1090         DMSG("str: %s\n", str);
1091         return make_image_path_tag(ATOM_INDEX_IMAGE, str);;
1092 }
1093 static char *markup_to_entry(AppData *ad, int type_index, const char *str)
1094 {
1095         CALLED();
1096         if (!str)
1097                 return NULL;
1098
1099         Eina_Strbuf *strbuf = eina_strbuf_new();
1100         if (!strbuf)
1101                 return strdup(str);
1102         eina_strbuf_prepend(strbuf, "<font_size=18><color=#000000FF>");
1103
1104         const char *trail = str;
1105         char *image_tag_str = NULL;
1106         char *html_img_tag = "img";
1107         char *efl_img_tag = "item";
1108         if (type_index == ATOM_INDEX_HTML) /* HTML */
1109                 image_tag_str = html_img_tag;
1110         else if (type_index == ATOM_INDEX_EFL) /* EFL */
1111                 image_tag_str = efl_img_tag;
1112
1113         while (trail && *trail)
1114         {
1115                 const char *pretrail = trail;
1116                 unsigned long length;
1117                 char *temp;
1118                 char *endtag;
1119
1120                 trail = strchr(trail, '<');
1121                 if (!trail)
1122                 {
1123                         eina_strbuf_append(strbuf, pretrail);
1124                         break;
1125                 }
1126                 endtag = strchr(trail, '>');
1127                 if (!endtag)
1128                         break;
1129
1130                 length = trail - pretrail;
1131
1132                 temp = strndup(pretrail, length);
1133                 if (!temp)
1134                 {
1135                         trail++;
1136                         continue;
1137                 }
1138
1139                 eina_strbuf_append(strbuf, temp);
1140                 FREE(temp);
1141                 trail++;
1142
1143                 if (trail[0] == '/')
1144                 {
1145                         trail = endtag + 1;
1146                         continue;
1147                 }
1148
1149                 if (strncmp(trail, "br", 2) == 0)
1150                 {
1151                         eina_strbuf_append(strbuf, "<br>");
1152                         trail = endtag + 1;
1153                         continue;
1154                 }
1155
1156                 if (image_tag_str && strncmp(trail, image_tag_str, strlen(image_tag_str)) == 0)
1157                 {
1158                         char *src = strstr(trail, "file://");
1159                         char *src_endtag = strchr(trail, '>');
1160                         if (!src || !src_endtag || src_endtag < src)
1161                                 continue;
1162
1163                         length = src_endtag - src;
1164
1165                         src = strndup(src, length);
1166                         if (!src)
1167                         {
1168                                 trail = endtag + 1;
1169                                 continue;
1170                         }
1171                         temp = src;
1172                         while(*temp)
1173                         {
1174                                 if (*temp == '\"' || *temp == '>')
1175                                         *temp = '\0';
1176                                 else
1177                                         temp++;
1178                         }
1179
1180                         eina_strbuf_append_printf(strbuf, "<item absize=66x62 href=%s></item>", src);
1181                         DTRACE("src str: %s \n", src);
1182                         FREE(src);
1183                 }
1184                 trail = endtag + 1;
1185         }
1186
1187         if (type_index == ATOM_INDEX_HTML)
1188                 eina_strbuf_replace_all(strbuf, "&nbsp;", " ");
1189
1190         char *entry_str = eina_strbuf_string_steal(strbuf);
1191         eina_strbuf_free(strbuf);
1192         return entry_str;
1193 }
1194
1195 static char *html_to_entry(AppData *ad, int type_index, const char *str)
1196 {
1197         DMSG("str: %s\n", str);
1198         return markup_to_entry(ad, type_index, str);
1199 }
1200
1201 static char *efl_to_entry(AppData *ad, int type_index, const char *str)
1202 {
1203         DMSG("str: %s\n", str);
1204         return markup_to_entry(ad, type_index, str);
1205 }
1206
1207 static char *image_path_to_entry(AppData *ad, int type_index, const char *str)
1208 {
1209         CALLED();
1210         return NULL;
1211 }
1212
1213 static char *text_to_entry(AppData *ad, int type_index, const char *str)
1214 {
1215         DMSG("str: %s\n", str);
1216         char *markup = NULL;
1217         markup = _elm_util_text_to_mkup(str);
1218         char *for_entry = markup_to_entry(ad, type_index, markup);
1219         FREE(markup);
1220         return for_entry;
1221 }
1222
1223 static Eina_List *make_tag_list(int type_index, const char *str)
1224 {
1225         Eina_List *nodeList = NULL;
1226         PTagNode nodeData;
1227
1228         nodeData = _get_start_node(str);
1229
1230         while (nodeData)
1231         {
1232                 nodeList = eina_list_append(nodeList, nodeData);
1233                 nodeData = _get_next_node(nodeData);
1234         }
1235
1236         _link_match_tags(nodeList);
1237
1238         switch(type_index)
1239         {
1240                 case ATOM_INDEX_EFL:
1241                         _set_EFL_tag_data(nodeList);
1242                         break;
1243                 case ATOM_INDEX_HTML:
1244                         _set_HTML_tag_data(nodeList);
1245                         break;
1246                 default:
1247                         DMSG("wrong index: %d\n");
1248         }
1249
1250 #ifdef DEBUG
1251         _dumpNode(nodeList);
1252 #endif
1253         return nodeList;
1254 }
1255
1256 static void cleanup_tag_list(Eina_List *nodeList)
1257 {
1258         Eina_List *trail;
1259         PTagNode nodeData;
1260
1261         EINA_LIST_FOREACH(nodeList, trail, nodeData)
1262                 _delete_node(nodeData);
1263         eina_list_free(nodeList);
1264 }
1265
1266 static char *html_to_efl(AppData *ad, int type_index, const char *str)
1267 {
1268         CALLED();
1269         Eina_List *nodeList = NULL;
1270         nodeList = make_tag_list(type_index, str);
1271         char *ret = _convert_to_edje(nodeList);
1272         DMSG("efl: %s\n", ret);
1273         cleanup_tag_list(nodeList);
1274
1275         return ret;
1276 }
1277
1278 static char *efl_to_html(AppData *ad, int type_index, const char *str)
1279 {
1280         CALLED();
1281         Eina_List *nodeList = NULL;
1282         nodeList = make_tag_list(type_index, str);
1283         char *ret = _convert_to_html(nodeList);
1284         DMSG("html: %s\n", ret);
1285         cleanup_tag_list(nodeList);
1286
1287         return ret;
1288 }
1289
1290 static char *text_to_html(AppData *ad, int type_index, const char *str)
1291 {
1292         DMSG("str: %s\n", str);
1293         char *markup = NULL;
1294         markup = _elm_util_text_to_mkup(str);
1295         char *html = efl_to_html(ad, ATOM_INDEX_EFL, markup);
1296         FREE(markup);
1297         return html;
1298 }
1299
1300 static char *text_to_efl(AppData *ad, int type_index, const char *str)
1301 {
1302         DMSG("str: %s\n", str);
1303         char *ret = NULL;
1304         ret = _elm_util_text_to_mkup(str);
1305         return ret;
1306 }
1307
1308 static char *to_text(AppData *ad, int type_index, const char *str)
1309 {
1310         DMSG("str: %s\n", str);
1311         char *text = NULL;
1312         if (type_index == ATOM_INDEX_HTML)
1313         {
1314                 Eina_Strbuf *buf = eina_strbuf_new();
1315                 if (buf)
1316                 {
1317                         char *html;
1318                         eina_strbuf_append(buf, str);
1319                         eina_strbuf_replace_all(buf, "&nbsp;", " ");
1320                         html = eina_strbuf_string_steal(buf);
1321                         eina_strbuf_free(buf);
1322                         text = _elm_util_mkup_to_text(html);
1323                         free(html);
1324                         return text;
1325                 }
1326         }
1327
1328         text = _elm_util_mkup_to_text(str);
1329         return text;
1330 }
1331