Annotation of Amaya/amaya/XHTMLbuilder.c, revision 1.106
1.1 cvs 1: /*
2: *
1.101 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2004
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
8: /*
1.30 cvs 9: * XHTMLbuilder.c
1.23 cvs 10: * Builds the corresponding abstract tree for a Thot document of type HTML.
1.1 cvs 11: *
1.20 cvs 12: * Authors: L. Carcone
13: * V. Quint
1.1 cvs 14: */
15:
16: #define THOT_EXPORT extern
17: #include "amaya.h"
18: #include "css.h"
1.2 cvs 19: #include "parser.h"
20: #include "HTML.h"
1.30 cvs 21: #include "fetchHTMLname.h"
1.2 cvs 22:
1.13 cvs 23: #include "css_f.h"
1.76 vatton 24: #include "EDITstyle_f.h"
1.13 cvs 25: #include "fetchXMLname_f.h"
1.30 cvs 26: #include "fetchHTMLname_f.h"
1.22 cvs 27: #include "html2thot_f.h"
1.1 cvs 28: #include "HTMLactions_f.h"
29: #include "HTMLedit_f.h"
1.22 cvs 30: #include "HTMLform_f.h"
1.1 cvs 31: #include "HTMLimage_f.h"
32: #include "HTMLtable_f.h"
33: #include "HTMLimage_f.h"
1.104 vatton 34: #include "init_f.h"
1.1 cvs 35: #include "UIcss_f.h"
1.13 cvs 36: #include "styleparser_f.h"
1.2 cvs 37: #include "XHTMLbuilder_f.h"
1.13 cvs 38: #include "Xml2thot_f.h"
1.1 cvs 39:
1.30 cvs 40: #define MaxMsgLength 200
41:
1.47 cvs 42: /* Elements that cannot contain text as immediate children.
43: When some text is present in the HTML file it must be
44: surrounded by a Pseudo_paragraph element */
45: static int NoTextChild[] =
46: {
47: HTML_EL_Document, HTML_EL_HTML, HTML_EL_HEAD, HTML_EL_BODY,
48: HTML_EL_Definition_List, HTML_EL_Block_Quote, HTML_EL_Directory,
49: HTML_EL_Form, HTML_EL_Menu, HTML_EL_FIELDSET,
50: HTML_EL_Numbered_List, HTML_EL_Option_Menu,
51: HTML_EL_Unnumbered_List, HTML_EL_Definition, HTML_EL_List_Item,
52: HTML_EL_MAP, HTML_EL_map, HTML_EL_Applet,
53: HTML_EL_Object, HTML_EL_IFRAME, HTML_EL_NOFRAMES,
54: HTML_EL_Division, HTML_EL_Center, HTML_EL_NOSCRIPT,
55: HTML_EL_Data_cell, HTML_EL_Heading_cell,
56: 0};
57:
1.28 cvs 58: /* Define a pointer to let parser functions access the HTML entity table */
59: extern XmlEntity *pXhtmlEntityTable;
1.6 cvs 60:
1.30 cvs 61: /* maximum size of error messages */
62: #define MaxMsgLength 200
63:
1.6 cvs 64: /*----------------------------------------------------------------------
1.104 vatton 65: ParseCharsetAndContentType:
1.6 cvs 66: Parses the element HTTP-EQUIV and looks for the charset value.
67: ----------------------------------------------------------------------*/
1.104 vatton 68: void ParseCharsetAndContentType (Element el, Document doc)
1.30 cvs 69:
1.6 cvs 70: {
1.15 cvs 71: AttributeType attrType;
72: Attribute attr;
73: SSchema docSSchema;
74: CHARSET charset;
1.39 cvs 75: char *text, *text2, *ptrText, *str;
76: char charsetname[MAX_LENGTH];
1.15 cvs 77: int length;
1.6 cvs 78: int pos, index = 0;
79:
1.15 cvs 80: charset = TtaGetDocumentCharset (doc);
1.104 vatton 81: if (charset != UNDEFINED_CHARSET &&
82: DocumentMeta[doc] && DocumentMeta[doc]->content_type)
1.15 cvs 83: return;
1.6 cvs 84:
85: docSSchema = TtaGetDocumentSSchema (doc);
86: attrType.AttrSSchema = docSSchema;
87: attrType.AttrTypeNum = HTML_ATTR_http_equiv;
88: attr = TtaGetAttribute (el, attrType);
89: if (attr != NULL)
90: {
91: /* There is a HTTP-EQUIV attribute */
92: length = TtaGetTextAttributeLength (attr);
93: if (length > 0)
94: {
1.100 gully 95: text = (char *)TtaGetMemory (length + 1);
1.6 cvs 96: TtaGiveTextAttributeValue (attr, text, &length);
1.37 cvs 97: if (!strcasecmp (text, "content-type"))
1.6 cvs 98: {
99: attrType.AttrTypeNum = HTML_ATTR_meta_content;
100: attr = TtaGetAttribute (el, attrType);
101: if (attr != NULL)
102: {
103: length = TtaGetTextAttributeLength (attr);
104: if (length > 0)
105: {
1.100 gully 106: text2 = (char *)TtaGetMemory (length + 1);
1.6 cvs 107: TtaGiveTextAttributeValue (attr, text2, &length);
108: ptrText = text2;
109: while (*ptrText)
110: {
1.53 vatton 111: *ptrText = tolower (*ptrText);
1.6 cvs 112: ptrText++;
113: }
1.104 vatton 114:
115: if (!DocumentMeta[doc])
116: DocumentMeta[doc] = DocumentMetaDataAlloc ();
117: if (DocumentMeta[doc]->content_type == NULL)
1.6 cvs 118: {
1.104 vatton 119:
120: if (!strncmp (text2, "text/html", 9))
121: DocumentMeta[doc]->content_type = TtaStrdup ("text/html");
122: else
123: DocumentMeta[doc]->content_type = TtaStrdup (AM_XHTML_MIME_TYPE);
124: }
125:
126: if (charset == UNDEFINED_CHARSET)
127: {
128: /* the charset is not already defined by the http header */
129: str = strstr (text2, "charset=");
130: if (str)
131: {
132: pos = str - text2 + 8;
133: while (text2[pos] != SPACE &&
134: text2[pos] != TAB && text2[pos] != EOS)
135: charsetname[index++] = text2[pos++];
136: charsetname[index] = EOS;
137: charset = TtaGetCharset (charsetname);
138: if (charset != UNDEFINED_CHARSET)
139: TtaSetDocumentCharset (doc, charset, FALSE);
140: }
1.6 cvs 141: }
142: TtaFreeMemory (text2);
143: }
144: }
145: }
146: TtaFreeMemory (text);
147: }
148: }
149: }
150:
1.23 cvs 151: /*----------------------------------------------------------------------
1.47 cvs 152: XhtmlCannotContainText
153: Return TRUE if element el is a block element.
154: ----------------------------------------------------------------------*/
155: ThotBool XhtmlCannotContainText (ElementType elType)
156:
157: {
158: int i;
159: ThotBool ret;
160:
161: if (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML"))
162: /* not an HTML element */
163: ret = TRUE;
164: else
165: {
166: ret = FALSE;
167: i = 0;
168: while (NoTextChild[i] > 0 && NoTextChild[i] != elType.ElTypeNum)
169: i++;
170: if (NoTextChild[i] == elType.ElTypeNum)
171: ret = TRUE;
172: }
173: return ret;
1.23 cvs 174: }
175:
1.6 cvs 176: /*----------------------------------------------------------------------
177: XhtmlElementComplete
1.20 cvs 178: Complete Xhtml elements.
1.6 cvs 179: Check its attributes and its contents.
180: ----------------------------------------------------------------------*/
1.99 cvs 181: void XhtmlElementComplete (ParserData *context, Element el, int *error)
1.30 cvs 182: {
1.72 cvs 183: Document doc;
1.30 cvs 184: ElementType elType, newElType, childType;
1.104 vatton 185: Element child, desc, leaf, prev, next, last,
1.62 quint 186: elFrames, lastFrame, lastChild, parent, picture, content;
1.30 cvs 187: Attribute attr;
188: AttributeType attrType;
189: Language lang;
1.41 cvs 190: char *text;
1.39 cvs 191: char lastChar[2];
1.79 quint 192: char *name1, *data;
1.30 cvs 193: int length;
194: SSchema docSSchema;
1.106 ! quint 195: ThotBool isImage, isInline;
1.6 cvs 196:
197: *error = 0;
1.72 cvs 198: doc = context->doc;
1.6 cvs 199: docSSchema = TtaGetDocumentSSchema (doc);
200:
201: elType = TtaGetElementType (el);
1.106 ! quint 202: isInline = IsXMLElementInline (elType, doc);
1.96 quint 203: newElType.ElSSchema = elType.ElSSchema;
204:
1.106 ! quint 205: if (elType.ElTypeNum == HTML_EL_Paragraph ||
! 206: elType.ElTypeNum == HTML_EL_Address ||
! 207: elType.ElTypeNum == HTML_EL_H1 ||
! 208: elType.ElTypeNum == HTML_EL_H2 ||
! 209: elType.ElTypeNum == HTML_EL_H3 ||
! 210: elType.ElTypeNum == HTML_EL_H4 ||
! 211: elType.ElTypeNum == HTML_EL_H5 ||
! 212: elType.ElTypeNum == HTML_EL_H6 ||
! 213: elType.ElTypeNum == HTML_EL_Preformatted ||
! 214: elType.ElTypeNum == HTML_EL_Term ||
! 215: elType.ElTypeNum == HTML_EL_LEGEND ||
! 216: elType.ElTypeNum == HTML_EL_CAPTION ||
! 217: elType.ElTypeNum == HTML_EL_rb ||
! 218: elType.ElTypeNum == HTML_EL_rt ||
! 219: (isInline && elType.ElTypeNum != HTML_EL_Text_Area))
! 220: /* It's an element that is supposed to contain at least a Basic_Elem.
! 221: If it is empty, insert a Basic_Elem to allow the user to put the
! 222: selection within this element */
! 223: /* Don't do it for a Text_Area, as an Inserted_Text element has to be
1.97 quint 224: created (see below) */
1.96 quint 225: {
226: child = TtaGetFirstChild (el);
227: if (child == NULL)
228: /* it's an empty inline element */
229: /* insert a Basic_Elem element in the element */
230: {
231: newElType.ElTypeNum = HTML_EL_Basic_Elem;
232: child = TtaNewTree (doc, newElType, "");
233: TtaInsertFirstChild (&child, el, doc);
234: }
235: }
1.106 ! quint 236: if (!isInline)
1.96 quint 237: /* It's a block-level element. Is it within a character-level element? */
238: if (elType.ElTypeNum != HTML_EL_Comment_ &&
239: elType.ElTypeNum != HTML_EL_XMLPI)
1.6 cvs 240: BlockInCharLevelElem (el);
241:
242: switch (elType.ElTypeNum)
243: {
1.62 quint 244: case HTML_EL_Object: /* it's an object */
1.79 quint 245: data = NULL;
1.62 quint 246: isImage = FALSE;
247: /* is there a type attribute on the object element? */
248: attrType.AttrSSchema = elType.ElSSchema;
249: attrType.AttrTypeNum = HTML_ATTR_Object_type;
1.6 cvs 250: attr = TtaGetAttribute (el, attrType);
1.62 quint 251: if (attr)
252: /* there is a type attribute. Get its value to see if the object
253: represents an image */
1.6 cvs 254: {
255: length = TtaGetTextAttributeLength (attr);
256: if (length > 0)
257: {
1.100 gully 258: name1 = (char *)TtaGetMemory (length + 1);
1.6 cvs 259: TtaGiveTextAttributeValue (attr, name1, &length);
1.68 kahan 260: if (!strcmp (name1, AM_MATHML_MIME_TYPE) ||
1.62 quint 261: !strcmp (name1, "application/postscript") ||
262: !strcmp (name1, "image/x-bitmap") ||
263: !strcmp (name1, "image/x-xpixmap") ||
264: !strcmp (name1, "image/gif") ||
265: !strcmp (name1, "image/jpeg") ||
266: !strcmp (name1, "image/png") ||
1.67 kahan 267: !strcmp (name1, "image/svg") ||
1.83 cvs 268: !strcmp (name1, AM_SVG_MIME_TYPE) ||
269: !strcmp (name1, AM_XHTML_MIME_TYPE) ||
270: !strcmp (name1, "text/html") ||
271: !strcmp (name1, "text/htm") ||
272: !strcmp (name1, AM_GENERIC_XML_MIME_TYPE))
1.62 quint 273: isImage = TRUE;
274: TtaFreeMemory (name1);
275: }
276: }
1.79 quint 277:
278: attrType.AttrTypeNum = HTML_ATTR_data;
279: attr = TtaGetAttribute (el, attrType);
280: if (attr)
281: /* the object has a data attribute */
282: {
283: length = TtaGetTextAttributeLength (attr);
284: if (length > 0)
285: {
1.100 gully 286: data = (char *)TtaGetMemory (length + 1);
1.79 quint 287: TtaGiveTextAttributeValue (attr, data, &length);
288: if (!isImage)
289: if (!strcmp (&data[length-3], "mml") ||
290: !strcmp (&data[length-3], "gif") ||
291: !strcmp (&data[length-3], "jpg") ||
292: !strcmp (&data[length-4], "jpeg") ||
293: !strcmp (&data[length-3], "png") ||
294: !strcmp (&data[length-3], "svg") ||
1.80 cvs 295: !strcmp (&data[length-4], "svgz") ||
1.83 cvs 296: !strcmp (&data[length-3], "htm") ||
297: !strcmp (&data[length-4], "html") ||
298: !strcmp (&data[length-3], "xml"))
1.79 quint 299: isImage = TRUE;
300: }
301: }
1.62 quint 302: picture = NULL; /* no PICTURE element yet */
303: child = TtaGetFirstChild (el);
304: if (isImage)
305: /* the object represents an image. We need a PICTURE element as
306: child of the object to hold the image */
307: {
308: if (child)
309: {
310: elType = TtaGetElementType (child);
311: if (elType.ElTypeNum == HTML_EL_PICTURE_UNIT)
312: /* there is already a PICTURE element */
313: picture = child;
314: }
1.79 quint 315: /* if the object element has no PICTURE element as its first child
1.62 quint 316: create one */
317: if (!picture)
318: {
319: elType.ElTypeNum = HTML_EL_PICTURE_UNIT;
320: picture = TtaNewTree (doc, elType, "");
321: if (child)
322: TtaInsertSibling (picture, child, TRUE, doc);
323: else
324: TtaInsertFirstChild (&picture, el, doc);
325: child = picture;
326: }
327: /* copy attribute data of the object into the SRC attribute of
328: the PICTURE element */
1.79 quint 329: if (data)
330: /* the object has a data attribute */
331: {
332: attrType.AttrTypeNum = HTML_ATTR_SRC;
333: attr = TtaGetAttribute (picture, attrType);
334: if (attr == NULL)
335: {
336: attr = TtaNewAttribute (attrType);
337: TtaAttachAttribute (picture, attr, doc);
338: }
339: TtaSetAttributeText (attr, data, picture, doc);
340: }
341: attrType.AttrTypeNum = HTML_ATTR_Height_;
1.62 quint 342: attr = TtaGetAttribute (el, attrType);
343: if (attr)
1.79 quint 344: /* the Object has a height attribute. Applies it to the
345: picture element */
346: {
347: length = TtaGetTextAttributeLength (attr);
348: if (length > 0)
349: {
1.100 gully 350: text = (char *)TtaGetMemory (length + 1);
1.79 quint 351: TtaGiveTextAttributeValue (attr, text, &length);
352: /* create the corresponding attribute IntHeightPercent or */
353: /* IntHeightPxl */
354: CreateAttrHeightPercentPxl (text, el, doc, -1);
355: TtaFreeMemory (text);
356: }
357: }
358: attrType.AttrTypeNum = HTML_ATTR_Width__;
359: attr = TtaGetAttribute (el, attrType);
360: if (attr)
361: /* the Object has a width attribute. Applies it to the
362: picture element */
1.62 quint 363: {
364: length = TtaGetTextAttributeLength (attr);
365: if (length > 0)
1.6 cvs 366: {
1.100 gully 367: text = (char *)TtaGetMemory (length + 1);
1.79 quint 368: TtaGiveTextAttributeValue (attr, text, &length);
369: /* create the corresponding attribute IntWidthPercent or */
370: /* IntWidthPxl */
371: CreateAttrWidthPercentPxl (text, el, doc, -1);
372: TtaFreeMemory (text);
1.6 cvs 373: }
374: }
375: }
376: /* is the Object_Content element already created ? */
1.62 quint 377: if (child)
378: /* the object element has at least 1 child element */
379: {
380: content = NULL;
381: desc = child;
1.6 cvs 382: elType = TtaGetElementType (desc);
1.62 quint 383: if (elType.ElTypeNum != HTML_EL_Object_Content)
384: {
385: TtaNextSibling(&desc);
386: if (desc)
387: elType = TtaGetElementType (desc);
388: }
389: /* is it the Object_Content element ? */
390: if (elType.ElTypeNum == HTML_EL_Object_Content)
391: content = desc;
392: else
1.6 cvs 393: {
1.62 quint 394: /* create an Object_Content element */
395: elType.ElTypeNum = HTML_EL_Object_Content;
396: content = TtaNewElement (doc, elType);
397: if (picture)
398: TtaInsertSibling (content, picture, FALSE, doc);
399: else
400: TtaInsertSibling (content, child, TRUE, doc);
401: /* move previous existing children into Object_Content */
1.6 cvs 402: child = TtaGetLastChild(el);
1.62 quint 403: while (child != content)
404: {
405: TtaRemoveTree (child, doc);
406: TtaInsertFirstChild (&child, content, doc);
407: child = TtaGetLastChild(el);
408: }
409: }
1.6 cvs 410: }
1.79 quint 411: if (data)
412: TtaFreeMemory (data);
1.6 cvs 413: break;
1.62 quint 414:
1.105 cvs 415: case HTML_EL_IFRAME: /* it's an iframe */
416: child = TtaGetFirstChild (el);
417: /* is the Iframe_Content element already created ? */
418: if (child)
419: /* the iframe element has at least 1 child element */
420: {
421: content = NULL;
422: desc = child;
423: elType = TtaGetElementType (desc);
424: if (elType.ElTypeNum != HTML_EL_Iframe_Content)
425: {
426: TtaNextSibling(&desc);
427: if (desc)
428: elType = TtaGetElementType (desc);
429: }
430: /* is it the Iframe_Content element ? */
431: if (elType.ElTypeNum == HTML_EL_Iframe_Content)
432: content = desc;
433: else
434: {
435: /* create an Iframe_Content element */
436: elType.ElTypeNum = HTML_EL_Iframe_Content;
437: content = TtaNewElement (doc, elType);
438: TtaInsertSibling (content, child, TRUE, doc);
439: /* move previous existing children into Iframe_Content */
440: child = TtaGetLastChild(el);
441: while (child != content)
442: {
443: TtaRemoveTree (child, doc);
444: TtaInsertFirstChild (&child, content, doc);
445: child = TtaGetLastChild(el);
446: }
447: }
448: }
449: break;
450:
1.6 cvs 451: case HTML_EL_Unnumbered_List:
452: case HTML_EL_Numbered_List:
453: case HTML_EL_Menu:
454: case HTML_EL_Directory:
455: /* It's a List element. It should only have List_Item children.
456: If it has List element chidren, move these List elements
457: within their previous List_Item sibling. This is to fix
458: a bug in document generated by Mozilla. */
459: prev = NULL;
460: next = NULL;
461: child = TtaGetFirstChild (el);
462: while (child != NULL)
463: {
464: next = child;
465: TtaNextSibling (&next);
466: elType = TtaGetElementType (child);
467: if (elType.ElTypeNum == HTML_EL_Unnumbered_List ||
468: elType.ElTypeNum == HTML_EL_Numbered_List ||
469: elType.ElTypeNum == HTML_EL_Menu ||
470: elType.ElTypeNum == HTML_EL_Directory)
471: /* this list element is a child of another list element */
472: if (prev)
473: {
474: elType = TtaGetElementType (prev);
475: if (elType.ElTypeNum == HTML_EL_List_Item)
476: {
477: /* get the last child of the previous List_Item */
478: desc = TtaGetFirstChild (prev);
479: last = NULL;
480: while (desc)
481: {
482: last = desc;
483: TtaNextSibling (&desc);
484: }
485: /* move the list element after the last child of the
486: previous List_Item */
487: TtaRemoveTree (child, doc);
488: if (last)
489: TtaInsertSibling (child, last, FALSE, doc);
490: else
491: TtaInsertFirstChild (&child, prev, doc);
492: child = prev;
493: }
494: }
495: prev = child;
496: child = next;
497: }
498: break;
499:
500: case HTML_EL_FRAMESET:
501: /* The FRAMESET element is now complete. Gather all its FRAMESET
502: and FRAME children and wrap them up in a Frames element */
503: elFrames = NULL; lastFrame = NULL;
504: lastChild = NULL;
505: child = TtaGetFirstChild (el);
506: while (child != NULL)
507: {
508: next = child;
509: TtaNextSibling (&next);
510: elType = TtaGetElementType (child);
511: if (elType.ElTypeNum == HTML_EL_FRAMESET ||
512: elType.ElTypeNum == HTML_EL_FRAME ||
513: elType.ElTypeNum == HTML_EL_Comment_)
514: {
515: /* create the Frames element if it does not exist */
516: if (elFrames == NULL)
517: {
518: newElType.ElSSchema = docSSchema;
519: newElType.ElTypeNum = HTML_EL_Frames;
520: elFrames = TtaNewElement (doc, newElType);
1.63 cvs 521: if (DocumentMeta[doc]->xmlformat)
522: XmlSetElemLineNumber (elFrames);
523: else
524: SetHtmlElemLineNumber (elFrames);
1.6 cvs 525: TtaInsertSibling (elFrames, child, TRUE, doc);
526: }
527: /* move the element as the last child of the Frames element */
528: TtaRemoveTree (child, doc);
529: if (lastFrame == NULL)
530: TtaInsertFirstChild (&child, elFrames, doc);
531: else
532: TtaInsertSibling (child, lastFrame, FALSE, doc);
533: lastFrame = child;
534: }
535: child = next;
536: }
537: break;
538:
539: case HTML_EL_Input: /* it's an INPUT without any TYPE attribute */
540: /* Create a child of type Text_Input */
541: elType.ElTypeNum = HTML_EL_Text_Input;
542: child = TtaNewTree (doc, elType, "");
1.63 cvs 543: if (DocumentMeta[doc]->xmlformat)
544: XmlSetElemLineNumber (child);
545: else
546: SetHtmlElemLineNumber (child);
1.6 cvs 547: TtaInsertFirstChild (&child, el, doc);
548: /* now, process it like a Text_Input element */
549:
550: case HTML_EL_Text_Input:
551: case HTML_EL_Password_Input:
552: case HTML_EL_File_Input:
1.91 quint 553: /* set default size */
554: attrType.AttrSSchema = elType.ElSSchema;
555: attrType.AttrTypeNum = HTML_ATTR_IntAreaSize;
556: attr = TtaGetAttribute (el, attrType);
557: if (!attr)
558: CreateAttrIntAreaSize (20, el, doc);
1.6 cvs 559: /* get element Inserted_Text */
560: child = TtaGetFirstChild (el);
561: if (child != NULL)
562: {
563: attrType.AttrTypeNum = HTML_ATTR_Value_;
564: attr = TtaGetAttribute (el, attrType);
565: if (attr != NULL)
566: {
567: /* copy the value of attribute "value" into the first text
568: leaf of element */
569: length = TtaGetTextAttributeLength (attr);
570: if (length > 0)
571: {
572: /* get the text leaf */
573: leaf = TtaGetFirstChild (child);
574: if (leaf != NULL)
575: {
576: childType = TtaGetElementType (leaf);
577: if (childType.ElTypeNum == HTML_EL_TEXT_UNIT)
578: {
579: /* copy attribute value into the text leaf */
1.100 gully 580: text = (char *)TtaGetMemory (length + 1);
1.6 cvs 581: TtaGiveTextAttributeValue (attr, text, &length);
1.100 gully 582: TtaSetTextContent (leaf, (unsigned char *)text,
1.6 cvs 583: TtaGetDefaultLanguage (), doc);
584: TtaFreeMemory (text);
585: }
586: }
587: }
588: }
589: }
590: break;
591:
592: case HTML_EL_META:
1.104 vatton 593: ParseCharsetAndContentType (el, doc);
1.6 cvs 594: break;
595:
596: case HTML_EL_STYLE_: /* it's a STYLE element */
1.60 vatton 597: case HTML_EL_SCRIPT_: /* it's a SCRIPT element */
1.6 cvs 598: case HTML_EL_Preformatted: /* it's a PRE */
599: /* if the last line of the Preformatted is empty, remove it */
600: leaf = XmlLastLeafInElement (el);
601: if (leaf != NULL)
602: {
603: elType = TtaGetElementType (leaf);
604: if (elType.ElTypeNum == HTML_EL_TEXT_UNIT)
605: /* the last leaf is a TEXT element */
606: {
607: length = TtaGetTextLength (leaf);
608: if (length > 0)
609: {
1.100 gully 610: TtaGiveSubString (leaf, (unsigned char *)lastChar, length, 1);
1.6 cvs 611: if (lastChar[0] == EOL)
612: /* last character is new line, delete it */
613: {
614: if (length == 1)
615: /* empty TEXT element */
616: TtaDeleteTree (leaf, doc);
617: else
618: /* remove the last character */
619: TtaDeleteTextContent (leaf, length, 1, doc);
620: }
621: }
622: }
623: }
1.75 kahan 624: if (DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
1.63 cvs 625: {
626: if (IsXmlParsingCSS ())
627: {
628: text = GetStyleContents (el);
629: if (text)
630: {
1.71 vatton 631: ReadCSSRules (doc, NULL, text, NULL,
1.82 quint 632: TtaGetElementLineNumber (el), FALSE, el);
1.63 cvs 633: TtaFreeMemory (text);
634: }
635: SetXmlParsingCSS (FALSE);
636: }
637: }
638: else
1.6 cvs 639: {
1.63 cvs 640: if (IsHtmlParsingCSS ())
1.6 cvs 641: {
1.63 cvs 642: text = GetStyleContents (el);
643: if (text)
644: {
1.71 vatton 645: ReadCSSRules (doc, NULL, text, NULL,
1.82 quint 646: TtaGetElementLineNumber (el), FALSE, el);
1.63 cvs 647: TtaFreeMemory (text);
648: }
649: SetHtmlParsingCSS (FALSE);
1.6 cvs 650: }
651: }
652: /* and continue as if it were a Preformatted or a Script */
653: break;
654:
655: case HTML_EL_Text_Area: /* it's a Text_Area */
1.69 cvs 656: if (DocumentMeta[doc]->xmlformat)
657: SetParsingTextArea (FALSE);
658: else
659: SetHtmlParsingTextArea (FALSE);
1.6 cvs 660: child = TtaGetFirstChild (el);
661: if (child == NULL)
662: /* it's an empty Text_Area */
1.97 quint 663: /* insert a Inserted_Text element and a child Basic_Elem in the
664: Text_Area element */
1.6 cvs 665: {
666: newElType.ElTypeNum = HTML_EL_Inserted_Text;
667: child = TtaNewTree (doc, newElType, "");
668: TtaInsertFirstChild (&child, el, doc);
669: }
670: else
671: {
672: /* save the text into Default_Value attribute */
673: attrType.AttrSSchema = docSSchema;
674: attrType.AttrTypeNum = HTML_ATTR_Default_Value;
675: if (TtaGetAttribute (el, attrType) == NULL)
676: /* attribute Default_Value is missing */
677: {
678: desc = TtaGetFirstChild (child);
1.97 quint 679: if (desc)
680: {
681: length = TtaGetTextLength (desc);
682: if (length > 0)
683: {
684: length++;
685: attr = TtaNewAttribute (attrType);
686: TtaAttachAttribute (el, attr, doc);
1.100 gully 687: text = (char *)TtaGetMemory (length);
688: TtaGiveTextContent (desc, (unsigned char *)text, &length, &lang);
1.97 quint 689: TtaSetAttributeText (attr, text, el, doc);
690: TtaFreeMemory (text);
691: }
692: }
1.6 cvs 693: }
694: }
695: break;
1.103 quint 696:
1.6 cvs 697: case HTML_EL_Radio_Input:
698: case HTML_EL_Checkbox_Input:
699: /* put an attribute Checked if it is missing */
700: attrType.AttrSSchema = docSSchema;
701: attrType.AttrTypeNum = HTML_ATTR_Checked;
702: if (TtaGetAttribute (el, attrType) == NULL)
703: /* attribute Checked is missing */
704: {
705: attr = TtaNewAttribute (attrType);
706: TtaAttachAttribute (el, attr, doc);
707: TtaSetAttributeValue (attr, HTML_ATTR_Checked_VAL_No_, el, doc);
708: }
709: break;
710:
711: case HTML_EL_Option_Menu:
712: /* Check that at least one option has a SELECTED attribute */
713: OnlyOneOptionSelected (el, doc, TRUE);
714: break;
715:
716: case HTML_EL_PICTURE_UNIT:
717: break;
718:
719: case HTML_EL_LINK:
720: CheckCSSLink (el, doc, docSSchema);
721: break;
722:
723: case HTML_EL_Data_cell:
724: case HTML_EL_Heading_cell:
725: /* insert a pseudo paragraph into empty cells */
726: child = TtaGetFirstChild (el);
727: if (child == NULL)
728: {
729: elType.ElTypeNum = HTML_EL_Pseudo_paragraph;
730: child = TtaNewTree (doc, elType, "");
731: if (child != NULL)
732: TtaInsertFirstChild (&child, el, doc);
733: }
734:
1.80 cvs 735: /* detect whether we are parsing a whole table or just a cell */
1.63 cvs 736: if (DocumentMeta[doc]->xmlformat)
737: {
738: if (IsWithinXmlTable ())
1.102 quint 739: NewCell (el, doc, FALSE, FALSE, FALSE);
1.63 cvs 740: }
741: else
742: {
743: if (IsWithinHtmlTable ())
1.102 quint 744: NewCell (el, doc, FALSE, FALSE, FALSE);
1.63 cvs 745: }
1.6 cvs 746: break;
747:
748: case HTML_EL_Table:
749: CheckTable (el, doc);
750: SubWithinTable ();
751: break;
752:
753: case HTML_EL_TITLE:
754: /* show the TITLE in the main window */
755: UpdateTitle (el, doc);
756: break;
1.41 cvs 757:
758: case HTML_EL_rbc:
759: /* an rbc element has been read. Its parent should be a complex_ruby.
760: Change the type of the parent, as simple_ruby are created by
761: default */
762: parent = TtaGetParent (el);
763: if (parent)
764: {
765: newElType = TtaGetElementType (parent);
766: if (newElType.ElSSchema == elType.ElSSchema &&
767: newElType.ElTypeNum == HTML_EL_simple_ruby)
1.95 vatton 768: TtaChangeElementType (parent, HTML_EL_complex_ruby);
1.41 cvs 769: }
770: break;
771:
772: case HTML_EL_rtc1:
773: /* an rtc element has been parsed. If it has already a rtc1 sibling,
774: change its type to rtc2 */
775: prev = el;
776: do
777: {
778: TtaPreviousSibling(&prev);
779: if (prev)
780: {
781: newElType = TtaGetElementType (prev);
782: if (newElType.ElSSchema == elType.ElSSchema &&
783: newElType.ElTypeNum == HTML_EL_rtc1)
784: {
1.95 vatton 785: TtaChangeElementType (el, HTML_EL_rtc2);
1.41 cvs 786: prev = NULL;
787: }
788: }
789: }
790: while (prev);
791: break;
792:
1.6 cvs 793: default:
794: break;
795: }
796: }
1.1 cvs 797:
798: /*----------------------------------------------------------------------
1.30 cvs 799: PutInContent
800: Put the string ChrString in the leaf of current element.
801: ----------------------------------------------------------------------*/
1.39 cvs 802: Element PutInContent (char *ChrString, ParserData *context)
1.30 cvs 803:
804: {
805: Element el, child;
806: ElementType elType;
807: int length;
808:
809: el = NULL;
810: if (context->lastElement != NULL)
811: {
812: /* search first leaf of current element */
813: el = context->lastElement;
814: do
815: {
816: child = TtaGetFirstChild (el);
817: if (child != NULL)
818: el = child;
819: }
820: while (child != NULL);
821: elType = TtaGetElementType (el);
822: length = 0;
823: if (elType.ElTypeNum == 1)
824: length = TtaGetTextLength (el);
825: if (length == 0)
1.100 gully 826: TtaSetTextContent (el, (unsigned char *)ChrString, context->language, context->doc);
1.30 cvs 827: else
1.100 gully 828: TtaAppendTextContent (el, (unsigned char *)ChrString, context->doc);
1.30 cvs 829: }
830: return el;
831: }
832:
833: /*----------------------------------------------------------------------
1.93 vatton 834: UnknownXhtmlNameSpace
835: The element doesn't belong to a supported namespace
1.51 cvs 836: ----------------------------------------------------------------------*/
1.93 vatton 837: void UnknownXhtmlNameSpace (ParserData *context, Element *unknownEl,
838: char* content)
1.51 cvs 839: {
840: ElementType elType;
1.65 cvs 841: Element elText;
1.51 cvs 842:
843: /* Create a new Invalid_element */
844: elType.ElSSchema = GetXMLSSchema (XHTML_TYPE, context->doc);
1.94 cvs 845: elType.ElTypeNum = HTML_EL_XHTML_Unknown_namespace;
1.65 cvs 846: *unknownEl = TtaNewElement (context->doc, elType);
847: if (*unknownEl != NULL)
1.51 cvs 848: {
1.65 cvs 849: XmlSetElemLineNumber (*unknownEl);
850: InsertXmlElement (unknownEl);
1.51 cvs 851: context->lastElementClosed = TRUE;
852: elType.ElTypeNum = HTML_EL_TEXT_UNIT;
853: elText = TtaNewElement (context->doc, elType);
854: XmlSetElemLineNumber (elText);
1.65 cvs 855: TtaInsertFirstChild (&elText, *unknownEl, context->doc);
1.100 gully 856: TtaSetTextContent (elText, (unsigned char *)content, context->language, context->doc);
1.51 cvs 857: TtaSetAccessRight (elText, ReadOnly, context->doc);
858: }
859: }
860:
861: /*----------------------------------------------------------------------
1.30 cvs 862: CreateHTMLAttribute
863: create an attribute of type attrType for the element el.
864: ----------------------------------------------------------------------*/
1.93 vatton 865: void CreateHTMLAttribute (Element el,
866: AttributeType attrType,
867: char* text,
868: ThotBool isInvalid,
869: Document doc,
870: Attribute *lastAttribute,
871: Element *lastAttrElement)
1.30 cvs 872: {
873: int attrKind;
874: int length;
1.39 cvs 875: char *buffer;
1.30 cvs 876: Attribute attr, oldAttr;
877:
878: if (attrType.AttrTypeNum != 0)
879: {
880: oldAttr = TtaGetAttribute (el, attrType);
881: if (oldAttr != NULL)
882: /* this attribute already exists */
883: attr = oldAttr;
884: else
885: /* create a new attribute and attach it to the element */
886: {
887: attr = TtaNewAttribute (attrType);
888: TtaAttachAttribute (el, attr, doc);
889: }
890: *lastAttribute = attr;
891: *lastAttrElement = el;
892:
893: TtaGiveAttributeType (attr, &attrType, &attrKind);
894: if (attrKind == 0) /* enumerate */
895: TtaSetAttributeValue (attr, 1, el, doc);
896:
897: /* attribute BORDER without any value (ThotBool attribute) is */
898: /* considered as BORDER=1 */
899: if (attrType.AttrTypeNum == HTML_ATTR_Border)
900: TtaSetAttributeValue (attr, 1, el, doc);
901:
902: if (isInvalid)
903: /* Copy the name of the invalid attribute as the content */
904: /* of the Invalid_attribute attribute. */
905: {
1.37 cvs 906: length = strlen (text) + 2;
1.30 cvs 907: length += TtaGetTextAttributeLength (attr);
1.100 gully 908: buffer = (char *)TtaGetMemory (length + 1);
1.30 cvs 909: TtaGiveTextAttributeValue (attr, buffer, &length);
1.37 cvs 910: strcat (buffer, " ");
911: strcat (buffer, text);
1.30 cvs 912: TtaSetAttributeText (attr, buffer, el, doc);
913: TtaFreeMemory (buffer);
914: }
915: }
916: }
917:
918: /*----------------------------------------------------------------------
919: HTMLTypeAttrValue
920: Value val has been read for the HTML attribute TYPE.
921: Create a child for the current Thot element INPUT accordingly.
922: ----------------------------------------------------------------------*/
1.46 cvs 923: void HTMLTypeAttrValue (char *val,
1.30 cvs 924: Attribute lastAttribute,
925: Element lastAttrElement,
926: ParserData *context)
927:
928: {
929: ElementType elType;
930: Element newChild;
931: AttributeType attrType;
932: Attribute attr;
1.39 cvs 933: char msgBuffer[MaxMsgLength];
1.30 cvs 934: int value;
935: int numberOfLinesRead;
936:
937: value = MapAttrValue (DummyAttribute, val);
1.91 quint 938: if (value <= 0)
1.30 cvs 939: {
1.37 cvs 940: if (strlen (val) > MaxMsgLength - 40)
941: val[MaxMsgLength - 40] = EOS;
942: sprintf (msgBuffer, "Unknown attribute value \"type = %s\"", val);
1.42 cvs 943: HTMLParseError (context->doc, msgBuffer);
1.30 cvs 944: attrType.AttrSSchema = TtaGetDocumentSSchema (context->doc);
945: attrType.AttrTypeNum = pHTMLAttributeMapping[0].ThotAttribute;
1.37 cvs 946: sprintf (msgBuffer, "type=%s", val);
1.30 cvs 947: CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
948: context->doc, &lastAttribute, &lastAttrElement);
949: }
950: else
951: {
952: elType = TtaGetElementType (context->lastElement);
953: if (elType.ElTypeNum != HTML_EL_Input)
954: {
1.37 cvs 955: if (strlen (val) > MaxMsgLength - 40)
956: val[MaxMsgLength - 40] = EOS;
957: sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.30 cvs 958: }
959: else
960: {
961: elType.ElSSchema = TtaGetDocumentSSchema (context->doc);
962: elType.ElTypeNum = value;
963: newChild = TtaNewTree (context->doc, elType, "");
964: numberOfLinesRead = 0;
965: TtaSetElementLineNumber (newChild, numberOfLinesRead);
966: TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
967: if (value == HTML_EL_PICTURE_UNIT)
968: {
969: /* add the attribute IsInput to input pictures */
970: attrType.AttrSSchema = elType.ElSSchema;
971: attrType.AttrTypeNum = HTML_ATTR_IsInput;
972: attr = TtaNewAttribute (attrType);
973: TtaAttachAttribute (newChild, attr, context->doc);
974: }
975: }
976: }
977: }
978:
979: /*----------------------------------------------------------------------
980: XhtmlTypeAttrValue
981: Value val has been read for the HTML attribute TYPE.
982: Create a child for the current Thot element INPUT accordingly.
983: ----------------------------------------------------------------------*/
1.46 cvs 984: void XhtmlTypeAttrValue (char *val,
1.30 cvs 985: Attribute currentAttribute,
986: Element lastAttrElement,
987: ParserData *context)
988:
989: {
990: ElementType elType;
991: Element newChild;
992: AttributeType attrType;
993: Attribute attr;
1.39 cvs 994: char msgBuffer[MaxMsgLength];
1.30 cvs 995: int value;
996: ThotBool level;
997:
1.91 quint 998: /* Look in the dummy section of the attribute value table */
1.30 cvs 999: attrType.AttrTypeNum = DummyAttribute;
1.100 gully 1000: MapHTMLAttributeValue (val, &attrType, &value);
1.91 quint 1001: if (value <= 0)
1002: /* invalid value for the type attribute of an input element */
1.30 cvs 1003: {
1.37 cvs 1004: sprintf (msgBuffer, "Unknown attribute value \"type=%s\"", val);
1.100 gully 1005: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.36 cvs 1006: MapHTMLAttribute ("unknown_attr", &attrType, NULL,
1.30 cvs 1007: &level, context->doc);
1.37 cvs 1008: sprintf (msgBuffer, "type=%s", val);
1.30 cvs 1009: CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
1010: context->doc, ¤tAttribute, &lastAttrElement);
1011: }
1012: else
1.91 quint 1013: /* value is the Thot type of the element to be created for this value of
1014: the TYPE attribute */
1.30 cvs 1015: {
1016: elType = TtaGetElementType (context->lastElement);
1017: if (elType.ElTypeNum != HTML_EL_Input)
1018: {
1.37 cvs 1019: sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.100 gully 1020: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.30 cvs 1021: }
1022: else
1023: {
1024: elType.ElTypeNum = value;
1025: newChild = TtaNewTree (context->doc, elType, "");
1026: XmlSetElemLineNumber (newChild);
1027: TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
1028: if (value == HTML_EL_PICTURE_UNIT)
1029: {
1030: /* add the attribute IsInput to input pictures */
1031: attrType.AttrSSchema = elType.ElSSchema;
1032: attrType.AttrTypeNum = HTML_ATTR_IsInput;
1033: attr = TtaNewAttribute (attrType);
1034: TtaAttachAttribute (newChild, attr, context->doc);
1035: }
1036: }
1037: }
1038: }
1039:
1040: /*----------------------------------------------------------------------
1041: CreateAttrWidthPercentPxl
1.79 quint 1042: an HTML attribute "width" has been created for a Table, an image,
1043: an Object of a HR.
1.30 cvs 1044: Create the corresponding attribute IntWidthPercent or IntWidthPxl.
1045: oldWidth is -1 or the old image width.
1046: ----------------------------------------------------------------------*/
1.58 vatton 1047: void CreateAttrWidthPercentPxl (char *buffer, Element el,
1048: Document doc, int oldWidth)
1.30 cvs 1049: {
1050: AttributeType attrTypePxl, attrTypePercent;
1051: Attribute attrOld, attrNew;
1052: int length, val;
1.39 cvs 1053: char msgBuffer[MaxMsgLength];
1.79 quint 1054: ElementType elType, childType;
1055: Element origEl, child;
1.30 cvs 1056: int w, h;
1057: ThotBool isImage;
1058:
1.79 quint 1059: origEl = el;
1.30 cvs 1060: elType = TtaGetElementType (el);
1061: isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
1062: elType.ElTypeNum == HTML_EL_Data_cell ||
1.79 quint 1063: elType.ElTypeNum == HTML_EL_Heading_cell ||
1064: elType.ElTypeNum == HTML_EL_Object);
1065: if (elType.ElTypeNum == HTML_EL_Object)
1066: /* the width attribute is attached to an Object element */
1067: {
1068: child = TtaGetFirstChild (el);
1069: if (child)
1070: {
1071: childType = TtaGetElementType (child);
1072: if (childType.ElTypeNum == HTML_EL_PICTURE_UNIT)
1073: /* the Object element is of type image. apply the width
1074: attribute to the actual image element */
1075: el = child;
1076: }
1077: }
1.30 cvs 1078: /* remove trailing spaces */
1.37 cvs 1079: length = strlen (buffer) - 1;
1.30 cvs 1080: while (length > 0 && buffer[length] <= SPACE)
1081: length--;
1082: attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
1083: attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
1084: attrTypePxl.AttrTypeNum = HTML_ATTR_IntWidthPxl;
1085: attrTypePercent.AttrTypeNum = HTML_ATTR_IntWidthPercent;
1086: /* is the last character a '%' ? */
1087: if (buffer[length] == '%')
1088: {
1089: /* remove IntWidthPxl */
1090: attrOld = TtaGetAttribute (el, attrTypePxl);
1091: /* update IntWidthPercent */
1092: attrNew = TtaGetAttribute (el, attrTypePercent);
1093: if (attrNew == NULL)
1094: {
1095: attrNew = TtaNewAttribute (attrTypePercent);
1096: TtaAttachAttribute (el, attrNew, doc);
1097: }
1098: else if (isImage && oldWidth == -1)
1099: {
1100: if (attrOld == NULL)
1101: oldWidth = TtaGetAttributeValue (attrNew);
1102: else
1103: oldWidth = TtaGetAttributeValue (attrOld);
1104: }
1105: }
1106: else
1107: {
1108: /* remove IntWidthPercent */
1109: attrOld = TtaGetAttribute (el, attrTypePercent);
1110: /* update IntWidthPxl */
1111: attrNew = TtaGetAttribute (el, attrTypePxl);
1112: if (attrNew == NULL)
1113: {
1114: attrNew = TtaNewAttribute (attrTypePxl);
1115: TtaAttachAttribute (el, attrNew, doc);
1116: }
1117: else if (isImage && oldWidth == -1)
1118: {
1119: TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
1120: if (attrOld == NULL)
1121: oldWidth = w * TtaGetAttributeValue (attrNew) / 100;
1122: else
1123: oldWidth = w * TtaGetAttributeValue (attrOld) / 100;
1124: }
1125: }
1126:
1127: if (attrOld != NULL)
1128: TtaRemoveAttribute (el, attrOld, doc);
1.43 cvs 1129: if (sscanf (buffer, "%d", &val))
1.30 cvs 1130: TtaSetAttributeValue (attrNew, val, el, doc);
1131: else
1132: /* its not a number. Delete attribute and send an error message */
1133: {
1134: TtaRemoveAttribute (el, attrNew, doc);
1.37 cvs 1135: if (strlen (buffer) > MaxMsgLength - 30)
1.30 cvs 1136: buffer[MaxMsgLength - 30] = EOS;
1.37 cvs 1137: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42 cvs 1138: HTMLParseError (doc, msgBuffer);
1.30 cvs 1139: }
1140: if (isImage)
1.79 quint 1141: UpdateImageMap (origEl, doc, oldWidth, -1);
1.30 cvs 1142: }
1143:
1144: /*----------------------------------------------------------------------
1.58 vatton 1145: CreateAttrHeightPercentPxl
1.79 quint 1146: an HTML attribute "width" has been created for a Table, an image,
1147: an Object or a HR.
1.58 vatton 1148: Create the corresponding attribute IntHeightPercent or IntHeightPxl.
1149: oldHeight is -1 or the old image width.
1150: ----------------------------------------------------------------------*/
1151: void CreateAttrHeightPercentPxl (char *buffer, Element el,
1152: Document doc, int oldHeight)
1153: {
1154: AttributeType attrTypePxl, attrTypePercent;
1155: Attribute attrOld, attrNew;
1156: int length, val;
1157: char msgBuffer[MaxMsgLength];
1.79 quint 1158: ElementType elType, childType;
1159: Element origEl, child;
1.58 vatton 1160: int w, h;
1161: ThotBool isImage;
1162:
1.79 quint 1163: origEl = el;
1.58 vatton 1164: elType = TtaGetElementType (el);
1165: isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
1166: elType.ElTypeNum == HTML_EL_Data_cell ||
1.79 quint 1167: elType.ElTypeNum == HTML_EL_Heading_cell ||
1168: elType.ElTypeNum == HTML_EL_Object);
1169: if (elType.ElTypeNum == HTML_EL_Object)
1170: /* the height attribute is attached to an Object element */
1171: {
1172: child = TtaGetFirstChild (el);
1.81 cvs 1173: if (!child)
1174: return;
1175: else
1.79 quint 1176: {
1177: childType = TtaGetElementType (child);
1178: if (childType.ElTypeNum == HTML_EL_PICTURE_UNIT)
1179: /* the Object element is of type image. apply the width
1180: attribute to the actual image element */
1181: el = child;
1.81 cvs 1182: else
1183: return;
1.79 quint 1184: }
1185: }
1.58 vatton 1186: /* remove trailing spaces */
1187: length = strlen (buffer) - 1;
1188: while (length > 0 && buffer[length] <= SPACE)
1189: length--;
1190: attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
1191: attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
1192: attrTypePxl.AttrTypeNum = HTML_ATTR_IntHeightPxl;
1193: attrTypePercent.AttrTypeNum = HTML_ATTR_IntHeightPercent;
1194: /* is the last character a '%' ? */
1195: if (buffer[length] == '%')
1196: {
1197: /* remove IntHeightPxl */
1198: attrOld = TtaGetAttribute (el, attrTypePxl);
1199: /* update IntHeightPercent */
1200: attrNew = TtaGetAttribute (el, attrTypePercent);
1201: if (attrNew == NULL)
1202: {
1203: attrNew = TtaNewAttribute (attrTypePercent);
1204: TtaAttachAttribute (el, attrNew, doc);
1205: }
1206: else if (isImage && oldHeight == -1)
1207: {
1208: if (attrOld == NULL)
1209: oldHeight = TtaGetAttributeValue (attrNew);
1210: else
1211: oldHeight = TtaGetAttributeValue (attrOld);
1212: }
1213: }
1214: else
1215: {
1216: /* remove IntHeightPercent */
1217: attrOld = TtaGetAttribute (el, attrTypePercent);
1218: /* update IntHeightPxl */
1219: attrNew = TtaGetAttribute (el, attrTypePxl);
1220: if (attrNew == NULL)
1221: {
1222: attrNew = TtaNewAttribute (attrTypePxl);
1223: TtaAttachAttribute (el, attrNew, doc);
1224: }
1225: else if (isImage && oldHeight == -1)
1226: {
1227: TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
1228: if (attrOld == NULL)
1229: oldHeight = w * TtaGetAttributeValue (attrNew) / 100;
1230: else
1231: oldHeight = w * TtaGetAttributeValue (attrOld) / 100;
1232: }
1233: }
1234:
1235: if (attrOld != NULL)
1236: TtaRemoveAttribute (el, attrOld, doc);
1237: if (sscanf (buffer, "%d", &val))
1238: TtaSetAttributeValue (attrNew, val, el, doc);
1239: else
1240: /* its not a number. Delete attribute and send an error message */
1241: {
1242: TtaRemoveAttribute (el, attrNew, doc);
1243: if (strlen (buffer) > MaxMsgLength - 30)
1244: buffer[MaxMsgLength - 30] = EOS;
1245: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1246: HTMLParseError (doc, msgBuffer);
1247: }
1248: if (isImage)
1.79 quint 1249: UpdateImageMap (origEl, doc, oldHeight, -1);
1.58 vatton 1250: }
1251:
1252: /*----------------------------------------------------------------------
1.91 quint 1253: CreateAttrIntAreaSize
1254: an HTML attribute "size" has been created or modified for a input element.
1255: Create or update the corresponding attribute IntAreaSize.
1256: ----------------------------------------------------------------------*/
1257: void CreateAttrIntAreaSize (int value, Element el, Document doc)
1258: {
1259: AttributeType attrType;
1260: Attribute attr;
1261: ElementType elType;
1262:
1263: elType = TtaGetElementType (el);
1264: attrType.AttrSSchema = elType.ElSSchema;
1265: attrType.AttrTypeNum = HTML_ATTR_IntAreaSize;
1266: attr = TtaGetAttribute (el, attrType);
1267: if (!attr)
1268: {
1269: attr = TtaNewAttribute (attrType);
1270: TtaAttachAttribute (el, attr, doc);
1271: }
1272: /* the presentation rule associated with attribute IntAreaSize expresses
1273: the element width in "em". Convert the value into em */
1274: TtaSetAttributeValue (attr, (int) (value * 0.55), el, doc);
1275: }
1276:
1277: /*----------------------------------------------------------------------
1.30 cvs 1278: CreateAttrIntSize
1279: an HTML attribute "size" has been created for a Font element.
1280: Create the corresponding internal attribute.
1281: ----------------------------------------------------------------------*/
1.46 cvs 1282: void CreateAttrIntSize (char *buffer, Element el, Document doc)
1.30 cvs 1283:
1284: {
1285: AttributeType attrType;
1286: int val, ind, factor, delta;
1287: Attribute attr;
1.37 cvs 1288: char msgBuffer[MaxMsgLength];
1.30 cvs 1289:
1290: /* is the first character a '+' or a '-' ? */
1291: ind = 0;
1292: factor = 1;
1293: delta = 0;
1294: if (buffer[0] == '+')
1295: {
1296: attrType.AttrTypeNum = HTML_ATTR_IntSizeIncr;
1297: ind++;
1.90 vatton 1298: factor = 1;
1.30 cvs 1299: }
1300: else if (buffer[0] == '-')
1301: {
1302: attrType.AttrTypeNum = HTML_ATTR_IntSizeDecr;
1303: ind++;
1.90 vatton 1304: factor = 1;
1.30 cvs 1305: }
1306: else
1307: {
1308: attrType.AttrTypeNum = HTML_ATTR_IntSizeRel;
1309: delta = 1;
1310: }
1311: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
1312: attr = TtaGetAttribute (el, attrType);
1.43 cvs 1313: if (sscanf (&buffer[ind], "%d", &val))
1.30 cvs 1314: {
1315: val = val * factor + delta;
1316: if (attr == NULL)
1317: {
1318: /* this attribute doesn't exist, create it */
1319: attr = TtaNewAttribute (attrType);
1320: TtaAttachAttribute (el, attr, doc);
1321: }
1322: TtaSetAttributeValue (attr, val, el, doc);
1323: }
1324: else
1325: /* its not a number. Delete attribute and send an error message */
1326: {
1327: if (attr)
1328: TtaRemoveAttribute (el, attr, doc);
1.37 cvs 1329: if (strlen (buffer) > MaxMsgLength - 30)
1.30 cvs 1330: buffer[MaxMsgLength - 30] = EOS;
1.37 cvs 1331: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42 cvs 1332: HTMLParseError (doc, msgBuffer);
1.30 cvs 1333: }
1334: }
1335: /*----------------------------------------------------------------------
1336: EndOfHTMLAttributeValue
1337: Filling of an HTML attribute value
1338: ----------------------------------------------------------------------*/
1.48 vatton 1339: void EndOfHTMLAttributeValue (char *attrValue,
1340: AttributeMapping *lastMappedAttr,
1341: Attribute currentAttribute,
1342: Element lastAttrElement,
1343: ThotBool UnknownAttr,
1344: ParserData *context,
1345: ThotBool isXML)
1.30 cvs 1346: {
1.48 vatton 1347: AttributeType attrType, attrType1;
1348: Attribute attr;
1.79 quint 1349: ElementType elType;
1.48 vatton 1350: Element child, root;
1351: Language lang;
1352: char translation;
1353: char shape;
1354: char *buffer;
1355: char *attrName;
1356: char msgBuffer[MaxMsgLength];
1357: int val;
1358: int length;
1359: int attrKind;
1360: ThotBool done = FALSE;
1.88 vatton 1361: ThotBool loadcss;
1.30 cvs 1362:
1.48 vatton 1363: /* treatments of some particular HTML attributes */
1364: if (!strcmp (lastMappedAttr->XMLattribute, "style"))
1365: {
1366: TtaSetAttributeText (currentAttribute, attrValue,
1367: lastAttrElement, context->doc);
1.88 vatton 1368: /* check if we have to load CSS */
1369: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
1370: if (loadcss)
1371: ParseHTMLSpecificStyle (context->lastElement, attrValue,
1372: context->doc, 100, FALSE);
1.48 vatton 1373: done = TRUE;
1374: }
1375: else
1376: {
1377: if (!strcmp (lastMappedAttr->XMLattribute, "link"))
1.89 vatton 1378: HTMLSetAlinkColor (context->doc, context->lastElement, attrValue);
1.48 vatton 1379: else if (!strcmp (lastMappedAttr->XMLattribute, "alink"))
1.89 vatton 1380: HTMLSetAactiveColor (context->doc, context->lastElement, attrValue);
1.48 vatton 1381: else if (!strcmp (lastMappedAttr->XMLattribute, "vlink"))
1.89 vatton 1382: HTMLSetAvisitedColor (context->doc, context->lastElement, attrValue);
1.48 vatton 1383: }
1.30 cvs 1384:
1.48 vatton 1385: if (!done)
1386: {
1387: val = 0;
1388: translation = lastMappedAttr->AttrOrContent;
1389: switch (translation)
1390: {
1391: case 'C': /* Content */
1392: child = PutInContent (attrValue, context);
1393: if (child != NULL)
1.100 gully 1394: TtaAppendTextContent (child, (unsigned char *)"\" ", context->doc);
1.48 vatton 1395: break;
1396:
1397: case 'A':
1398: if (currentAttribute != NULL)
1399: {
1400: TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
1401: switch (attrKind)
1402: {
1403: case 0: /* enumerate */
1404: if (isXML)
1.100 gully 1405: MapHTMLAttributeValue (attrValue, &attrType, &val);
1.48 vatton 1406: else
1407: val = MapAttrValue (lastMappedAttr->ThotAttribute,
1.40 cvs 1408: attrValue);
1.48 vatton 1409: if (val < 0)
1410: {
1411: TtaGiveAttributeType (currentAttribute,
1412: &attrType, &attrKind);
1413: attrName = TtaGetAttributeName (attrType);
1414: sprintf (msgBuffer,
1.51 cvs 1415: "Invalid attribute value \"%s = %s\"",
1.48 vatton 1416: attrName, attrValue);
1417: if (isXML)
1.100 gully 1418: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.48 vatton 1419: else
1.84 quint 1420: /* we are parsing an HTML file, not an XHTML file */
1.51 cvs 1421: {
1.84 quint 1422: /* generate an error message in the log */
1.51 cvs 1423: HTMLParseError (context->doc, msgBuffer);
1.84 quint 1424: /* special case for value POLYGON of attribute
1425: shape (AREA element) */
1426: if (attrType.AttrTypeNum == HTML_ATTR_shape &&
1427: strcasecmp (attrValue, "POLYGON") == 0)
1428: {
1429: val = HTML_ATTR_shape_VAL_polygon;
1430: /* interpret it as if it were "poly" */
1431: TtaSetAttributeValue (currentAttribute, val,
1432: lastAttrElement, context->doc);
1433: }
1434: else
1435: /* remove the attribute and replace it by an */
1436: /* Invalid_attribute (not for XHTML) */
1437: {
1438: TtaRemoveAttribute (lastAttrElement,
1.51 cvs 1439: currentAttribute, context->doc);
1.84 quint 1440: attrType.AttrSSchema =
1441: TtaGetDocumentSSchema (context->doc);
1442: attrType.AttrTypeNum =
1443: pHTMLAttributeMapping[0].ThotAttribute;
1444: sprintf (msgBuffer, "%s=%s", attrName,attrValue);
1445: CreateHTMLAttribute (lastAttrElement, attrType,
1446: msgBuffer, TRUE, context->doc,
1447: ¤tAttribute, &lastAttrElement);
1448: }
1.48 vatton 1449: }
1450: }
1451: else
1452: TtaSetAttributeValue (currentAttribute, val,
1453: lastAttrElement, context->doc);
1454: break;
1455: case 1: /* integer */
1456: if (attrType.AttrTypeNum == HTML_ATTR_Border &&
1457: !strcasecmp (attrValue, "border"))
1458: {
1459: /* border="border" for a table */
1460: val = 1;
1461: TtaSetAttributeValue (currentAttribute, val,
1.30 cvs 1462: lastAttrElement, context->doc);
1.48 vatton 1463: }
1464: else if (sscanf (attrValue, "%d", &val))
1465: TtaSetAttributeValue (currentAttribute, val,
1466: lastAttrElement, context->doc);
1467: else
1468: {
1469: TtaRemoveAttribute (lastAttrElement, currentAttribute,
1470: context->doc);
1471: sprintf (msgBuffer,
1472: "Unknown attribute value \"%s\"",
1473: attrValue);
1474: if (isXML)
1.100 gully 1475: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.48 vatton 1476: else
1477: HTMLParseError (context->doc, msgBuffer);
1478: }
1479: break;
1480: case 2: /* text */
1481: if (!UnknownAttr)
1482: {
1483: TtaSetAttributeText (currentAttribute, attrValue,
1484: lastAttrElement, context->doc);
1.55 cvs 1485: if (attrType.AttrTypeNum == HTML_ATTR_Language)
1.48 vatton 1486: {
1487: /* it's a LANG attribute value */
1488: lang = TtaGetLanguageIdFromName (attrValue);
1.70 vatton 1489: if (lang < 0)
1.48 vatton 1490: {
1491: sprintf (msgBuffer,
1492: "warning - unsupported language: %s",
1493: attrValue);
1494: if (isXML)
1.100 gully 1495: XmlParseError (warningMessage, (unsigned char *)msgBuffer, 0);
1.48 vatton 1496: else
1497: HTMLParseError (context->doc, msgBuffer);
1498: }
1499: else
1500: {
1501: /* change current language */
1502: context->language = lang;
1503: if (isXML)
1504: SetLanguagInXmlStack (lang);
1505: else
1506: SetLanguagInHTMLStack (lang);
1507: }
1508: root = TtaGetRootElement (context->doc);
1509: if (lastAttrElement == root)
1510: /* it's a LANG attribute on the root element */
1511: /* set the RealLang attribute */
1512: {
1513: attrType1.AttrSSchema = TtaGetDocumentSSchema (context->doc);
1514: attrType1.AttrTypeNum = HTML_ATTR_RealLang;
1515: /* this attribute could be already present,
1516: (lang and xml:lang attributes) */
1517: if (!TtaGetAttribute (lastAttrElement,
1518: attrType1))
1519: /* it's not present. Add it */
1520: {
1521: attr = TtaNewAttribute (attrType1);
1522: TtaAttachAttribute (lastAttrElement,
1523: attr, context->doc);
1524: TtaSetAttributeValue (attr,
1525: HTML_ATTR_RealLang_VAL_Yes_,
1526: lastAttrElement,
1527: context->doc);
1528: }
1529: }
1530: }
1531: else if (attrType.AttrTypeNum == HTML_ATTR_accesskey)
1532: TtaAddAccessKey (context->doc, (unsigned int)attrValue[0],
1533: lastAttrElement);
1534: }
1535: else
1536: {
1.51 cvs 1537: /* this is the content of an invalid attribute */
1538: /* append it to the current Invalid_attribute */
1539: if (!isXML)
1540: {
1541: length = strlen (attrValue) + 2;
1542: length += TtaGetTextAttributeLength (currentAttribute);
1.100 gully 1543: buffer = (char *)TtaGetMemory (length + 1);
1.51 cvs 1544: TtaGiveTextAttributeValue (currentAttribute,
1545: buffer, &length);
1546: strcat (buffer, "=");
1547: strcat (buffer, attrValue);
1548: TtaSetAttributeText (currentAttribute, buffer,
1549: lastAttrElement, context->doc);
1550: TtaFreeMemory (buffer);
1551: }
1.48 vatton 1552: }
1553: break;
1554: case 3: /* reference */
1555: break;
1556: }
1557: }
1558: break;
1559:
1560: case SPACE:
1561: if (isXML)
1562: XhtmlTypeAttrValue (attrValue, currentAttribute,
1.30 cvs 1563: lastAttrElement, context);
1.48 vatton 1564: else
1565: HTMLTypeAttrValue (attrValue, currentAttribute,
1566: lastAttrElement, context);
1567: break;
1568:
1.30 cvs 1569: default:
1570: break;
1.48 vatton 1571: }
1.30 cvs 1572:
1573: if (lastMappedAttr->ThotAttribute == HTML_ATTR_Width__)
1.79 quint 1574: /* HTML attribute "width" */
1575: {
1576: /* if it's an Object element, wait until all attributes are handled,
1577: especially the data attribute that may generate the image to
1578: which the width has to be applied */
1579: elType = TtaGetElementType (lastAttrElement);
1580: if (elType.ElTypeNum != HTML_EL_Object)
1581: /* create the corresponding attribute IntWidthPercent or */
1582: /* IntWidthPxl */
1583: CreateAttrWidthPercentPxl (attrValue, lastAttrElement,
1584: context->doc, -1);
1585: }
1.58 vatton 1586: else if (lastMappedAttr->ThotAttribute == HTML_ATTR_Height_)
1.79 quint 1587: /* HTML attribute "height" */
1588: {
1589: /* if it's an Object element, wait until all attributes are handled,
1590: especially the data attribute that may generate the image to
1591: which the height has to be applied */
1592: elType = TtaGetElementType (lastAttrElement);
1593: if (elType.ElTypeNum != HTML_EL_Object)
1594: /* create the corresponding attribute IntHeightPercent or */
1595: /* IntHeightPxl */
1596: CreateAttrHeightPercentPxl (attrValue, lastAttrElement,
1597: context->doc, -1);
1598: }
1.91 quint 1599: else if (lastMappedAttr->ThotAttribute == HTML_ATTR_Area_Size)
1600: /* HTML attribute "size" for an element "input" */
1601: CreateAttrIntAreaSize (val, lastAttrElement, context->doc);
1.48 vatton 1602: else if (!strcmp (lastMappedAttr->XMLattribute, "size"))
1603: {
1604: TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
1605: if (attrType.AttrTypeNum == HTML_ATTR_Font_size)
1606: CreateAttrIntSize (attrValue, lastAttrElement, context->doc);
1607: }
1608: else if (!strcmp (lastMappedAttr->XMLattribute, "shape"))
1609: {
1610: child = TtaGetFirstChild (lastAttrElement);
1611: if (child != NULL)
1612: {
1613: switch (val)
1614: {
1615: case HTML_ATTR_shape_VAL_rectangle:
1616: shape = 'R';
1617: break;
1618: case HTML_ATTR_shape_VAL_circle:
1619: shape = 'a';
1620: break;
1621: case HTML_ATTR_shape_VAL_polygon:
1622: shape = 'p';
1623: break;
1624: default:
1625: shape = SPACE;
1626: break;
1627: }
1628: TtaSetGraphicsShape (child, shape, context->doc);
1629: }
1630: }
1631: else if (!strcmp (lastMappedAttr->XMLattribute, "value"))
1632: {
1633: elType = TtaGetElementType (lastAttrElement);
1634: if (elType.ElTypeNum == HTML_EL_Text_Input ||
1635: elType.ElTypeNum == HTML_EL_Password_Input ||
1636: elType.ElTypeNum == HTML_EL_File_Input ||
1637: elType.ElTypeNum == HTML_EL_Input)
1638: /* create a Default_Value attribute with the same content */
1639: {
1640: attrType1.AttrSSchema = attrType.AttrSSchema;
1641: attrType1.AttrTypeNum = HTML_ATTR_Default_Value;
1642: attr = TtaNewAttribute (attrType1);
1643: TtaAttachAttribute (lastAttrElement, attr, context->doc);
1644: TtaSetAttributeText (attr, attrValue,
1645: lastAttrElement, context->doc);
1646: }
1647: }
1.30 cvs 1648: else
1.48 vatton 1649: {
1650: /* Some HTML attributes are equivalent to a CSS property: */
1651: /* background -> background */
1652: /* bgcolor -> background */
1653: /* text -> color */
1654: /* color -> color */
1655: if (!strcmp (lastMappedAttr->XMLattribute, "background"))
1656: {
1657: if (strlen (attrValue) > MaxMsgLength - 30)
1658: attrValue[MaxMsgLength - 30] = EOS;
1.76 vatton 1659: HTMLSetBackgroundImage (context->doc, context->lastElement,
1.85 vatton 1660: REPEAT, attrValue, FALSE);
1.48 vatton 1661: }
1662: else if (!strcmp (lastMappedAttr->XMLattribute, "bgcolor"))
1.76 vatton 1663: HTMLSetBackgroundColor (context->doc, context->lastElement,
1664: attrValue);
1.48 vatton 1665: else if (!strcmp (lastMappedAttr->XMLattribute, "text") ||
1666: !strcmp (lastMappedAttr->XMLattribute, "color"))
1667: HTMLSetForegroundColor (context->doc,
1668: context->lastElement, attrValue);
1669: }
1670: }
1.30 cvs 1671: }
1672:
1673: /*----------------------------------------------------------------------
1.16 cvs 1674: MapHTMLAttributeValue
1.2 cvs 1675: Search in the Attribute Value Mapping Table the entry for the attribute
1.66 vatton 1676: ThotAtt and its value attVal. Returns the corresponding Thot value.
1.1 cvs 1677: ----------------------------------------------------------------------*/
1.100 gully 1678: void MapHTMLAttributeValue (char *attVal, const AttributeType * attrType, int *value)
1.1 cvs 1679: {
1.66 vatton 1680: MapXMLAttributeValue (XHTML_TYPE, attVal, attrType, value);
1.1 cvs 1681: }
Webmaster