Annotation of Amaya/amaya/XHTMLbuilder.c, revision 1.107
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:
1.107 ! quint 725: case HTML_EL_List_Item:
! 726: case HTML_EL_Definition:
! 727: /* insert a pseudo paragraph into empty cells or list items */
1.6 cvs 728: child = TtaGetFirstChild (el);
729: if (child == NULL)
730: {
731: elType.ElTypeNum = HTML_EL_Pseudo_paragraph;
732: child = TtaNewTree (doc, elType, "");
733: if (child != NULL)
734: TtaInsertFirstChild (&child, el, doc);
735: }
1.107 ! quint 736: if (elType.ElTypeNum == HTML_EL_Data_cell ||
! 737: elType.ElTypeNum == HTML_EL_Heading_cell)
! 738: /* detect whether we are parsing a whole table or just a cell */
1.63 cvs 739: {
1.107 ! quint 740: if (DocumentMeta[doc]->xmlformat)
! 741: {
! 742: if (IsWithinXmlTable ())
! 743: NewCell (el, doc, FALSE, FALSE, FALSE);
! 744: }
! 745: else
! 746: {
! 747: if (IsWithinHtmlTable ())
! 748: NewCell (el, doc, FALSE, FALSE, FALSE);
! 749: }
1.63 cvs 750: }
1.6 cvs 751: break;
752:
753: case HTML_EL_Table:
754: CheckTable (el, doc);
755: SubWithinTable ();
756: break;
757:
758: case HTML_EL_TITLE:
759: /* show the TITLE in the main window */
760: UpdateTitle (el, doc);
761: break;
1.41 cvs 762:
763: case HTML_EL_rbc:
764: /* an rbc element has been read. Its parent should be a complex_ruby.
765: Change the type of the parent, as simple_ruby are created by
766: default */
767: parent = TtaGetParent (el);
768: if (parent)
769: {
770: newElType = TtaGetElementType (parent);
771: if (newElType.ElSSchema == elType.ElSSchema &&
772: newElType.ElTypeNum == HTML_EL_simple_ruby)
1.95 vatton 773: TtaChangeElementType (parent, HTML_EL_complex_ruby);
1.41 cvs 774: }
775: break;
776:
777: case HTML_EL_rtc1:
778: /* an rtc element has been parsed. If it has already a rtc1 sibling,
779: change its type to rtc2 */
780: prev = el;
781: do
782: {
783: TtaPreviousSibling(&prev);
784: if (prev)
785: {
786: newElType = TtaGetElementType (prev);
787: if (newElType.ElSSchema == elType.ElSSchema &&
788: newElType.ElTypeNum == HTML_EL_rtc1)
789: {
1.95 vatton 790: TtaChangeElementType (el, HTML_EL_rtc2);
1.41 cvs 791: prev = NULL;
792: }
793: }
794: }
795: while (prev);
796: break;
797:
1.6 cvs 798: default:
799: break;
800: }
801: }
1.1 cvs 802:
803: /*----------------------------------------------------------------------
1.30 cvs 804: PutInContent
805: Put the string ChrString in the leaf of current element.
806: ----------------------------------------------------------------------*/
1.39 cvs 807: Element PutInContent (char *ChrString, ParserData *context)
1.30 cvs 808:
809: {
810: Element el, child;
811: ElementType elType;
812: int length;
813:
814: el = NULL;
815: if (context->lastElement != NULL)
816: {
817: /* search first leaf of current element */
818: el = context->lastElement;
819: do
820: {
821: child = TtaGetFirstChild (el);
822: if (child != NULL)
823: el = child;
824: }
825: while (child != NULL);
826: elType = TtaGetElementType (el);
827: length = 0;
828: if (elType.ElTypeNum == 1)
829: length = TtaGetTextLength (el);
830: if (length == 0)
1.100 gully 831: TtaSetTextContent (el, (unsigned char *)ChrString, context->language, context->doc);
1.30 cvs 832: else
1.100 gully 833: TtaAppendTextContent (el, (unsigned char *)ChrString, context->doc);
1.30 cvs 834: }
835: return el;
836: }
837:
838: /*----------------------------------------------------------------------
1.93 vatton 839: UnknownXhtmlNameSpace
840: The element doesn't belong to a supported namespace
1.51 cvs 841: ----------------------------------------------------------------------*/
1.93 vatton 842: void UnknownXhtmlNameSpace (ParserData *context, Element *unknownEl,
843: char* content)
1.51 cvs 844: {
845: ElementType elType;
1.65 cvs 846: Element elText;
1.51 cvs 847:
848: /* Create a new Invalid_element */
849: elType.ElSSchema = GetXMLSSchema (XHTML_TYPE, context->doc);
1.94 cvs 850: elType.ElTypeNum = HTML_EL_XHTML_Unknown_namespace;
1.65 cvs 851: *unknownEl = TtaNewElement (context->doc, elType);
852: if (*unknownEl != NULL)
1.51 cvs 853: {
1.65 cvs 854: XmlSetElemLineNumber (*unknownEl);
855: InsertXmlElement (unknownEl);
1.51 cvs 856: context->lastElementClosed = TRUE;
857: elType.ElTypeNum = HTML_EL_TEXT_UNIT;
858: elText = TtaNewElement (context->doc, elType);
859: XmlSetElemLineNumber (elText);
1.65 cvs 860: TtaInsertFirstChild (&elText, *unknownEl, context->doc);
1.100 gully 861: TtaSetTextContent (elText, (unsigned char *)content, context->language, context->doc);
1.51 cvs 862: TtaSetAccessRight (elText, ReadOnly, context->doc);
863: }
864: }
865:
866: /*----------------------------------------------------------------------
1.30 cvs 867: CreateHTMLAttribute
868: create an attribute of type attrType for the element el.
869: ----------------------------------------------------------------------*/
1.93 vatton 870: void CreateHTMLAttribute (Element el,
871: AttributeType attrType,
872: char* text,
873: ThotBool isInvalid,
874: Document doc,
875: Attribute *lastAttribute,
876: Element *lastAttrElement)
1.30 cvs 877: {
878: int attrKind;
879: int length;
1.39 cvs 880: char *buffer;
1.30 cvs 881: Attribute attr, oldAttr;
882:
883: if (attrType.AttrTypeNum != 0)
884: {
885: oldAttr = TtaGetAttribute (el, attrType);
886: if (oldAttr != NULL)
887: /* this attribute already exists */
888: attr = oldAttr;
889: else
890: /* create a new attribute and attach it to the element */
891: {
892: attr = TtaNewAttribute (attrType);
893: TtaAttachAttribute (el, attr, doc);
894: }
895: *lastAttribute = attr;
896: *lastAttrElement = el;
897:
898: TtaGiveAttributeType (attr, &attrType, &attrKind);
899: if (attrKind == 0) /* enumerate */
900: TtaSetAttributeValue (attr, 1, el, doc);
901:
902: /* attribute BORDER without any value (ThotBool attribute) is */
903: /* considered as BORDER=1 */
904: if (attrType.AttrTypeNum == HTML_ATTR_Border)
905: TtaSetAttributeValue (attr, 1, el, doc);
906:
907: if (isInvalid)
908: /* Copy the name of the invalid attribute as the content */
909: /* of the Invalid_attribute attribute. */
910: {
1.37 cvs 911: length = strlen (text) + 2;
1.30 cvs 912: length += TtaGetTextAttributeLength (attr);
1.100 gully 913: buffer = (char *)TtaGetMemory (length + 1);
1.30 cvs 914: TtaGiveTextAttributeValue (attr, buffer, &length);
1.37 cvs 915: strcat (buffer, " ");
916: strcat (buffer, text);
1.30 cvs 917: TtaSetAttributeText (attr, buffer, el, doc);
918: TtaFreeMemory (buffer);
919: }
920: }
921: }
922:
923: /*----------------------------------------------------------------------
924: HTMLTypeAttrValue
925: Value val has been read for the HTML attribute TYPE.
926: Create a child for the current Thot element INPUT accordingly.
927: ----------------------------------------------------------------------*/
1.46 cvs 928: void HTMLTypeAttrValue (char *val,
1.30 cvs 929: Attribute lastAttribute,
930: Element lastAttrElement,
931: ParserData *context)
932:
933: {
934: ElementType elType;
935: Element newChild;
936: AttributeType attrType;
937: Attribute attr;
1.39 cvs 938: char msgBuffer[MaxMsgLength];
1.30 cvs 939: int value;
940: int numberOfLinesRead;
941:
942: value = MapAttrValue (DummyAttribute, val);
1.91 quint 943: if (value <= 0)
1.30 cvs 944: {
1.37 cvs 945: if (strlen (val) > MaxMsgLength - 40)
946: val[MaxMsgLength - 40] = EOS;
947: sprintf (msgBuffer, "Unknown attribute value \"type = %s\"", val);
1.42 cvs 948: HTMLParseError (context->doc, msgBuffer);
1.30 cvs 949: attrType.AttrSSchema = TtaGetDocumentSSchema (context->doc);
950: attrType.AttrTypeNum = pHTMLAttributeMapping[0].ThotAttribute;
1.37 cvs 951: sprintf (msgBuffer, "type=%s", val);
1.30 cvs 952: CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
953: context->doc, &lastAttribute, &lastAttrElement);
954: }
955: else
956: {
957: elType = TtaGetElementType (context->lastElement);
958: if (elType.ElTypeNum != HTML_EL_Input)
959: {
1.37 cvs 960: if (strlen (val) > MaxMsgLength - 40)
961: val[MaxMsgLength - 40] = EOS;
962: sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.30 cvs 963: }
964: else
965: {
966: elType.ElSSchema = TtaGetDocumentSSchema (context->doc);
967: elType.ElTypeNum = value;
968: newChild = TtaNewTree (context->doc, elType, "");
969: numberOfLinesRead = 0;
970: TtaSetElementLineNumber (newChild, numberOfLinesRead);
971: TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
972: if (value == HTML_EL_PICTURE_UNIT)
973: {
974: /* add the attribute IsInput to input pictures */
975: attrType.AttrSSchema = elType.ElSSchema;
976: attrType.AttrTypeNum = HTML_ATTR_IsInput;
977: attr = TtaNewAttribute (attrType);
978: TtaAttachAttribute (newChild, attr, context->doc);
979: }
980: }
981: }
982: }
983:
984: /*----------------------------------------------------------------------
985: XhtmlTypeAttrValue
986: Value val has been read for the HTML attribute TYPE.
987: Create a child for the current Thot element INPUT accordingly.
988: ----------------------------------------------------------------------*/
1.46 cvs 989: void XhtmlTypeAttrValue (char *val,
1.30 cvs 990: Attribute currentAttribute,
991: Element lastAttrElement,
992: ParserData *context)
993:
994: {
995: ElementType elType;
996: Element newChild;
997: AttributeType attrType;
998: Attribute attr;
1.39 cvs 999: char msgBuffer[MaxMsgLength];
1.30 cvs 1000: int value;
1001: ThotBool level;
1002:
1.91 quint 1003: /* Look in the dummy section of the attribute value table */
1.30 cvs 1004: attrType.AttrTypeNum = DummyAttribute;
1.100 gully 1005: MapHTMLAttributeValue (val, &attrType, &value);
1.91 quint 1006: if (value <= 0)
1007: /* invalid value for the type attribute of an input element */
1.30 cvs 1008: {
1.37 cvs 1009: sprintf (msgBuffer, "Unknown attribute value \"type=%s\"", val);
1.100 gully 1010: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.36 cvs 1011: MapHTMLAttribute ("unknown_attr", &attrType, NULL,
1.30 cvs 1012: &level, context->doc);
1.37 cvs 1013: sprintf (msgBuffer, "type=%s", val);
1.30 cvs 1014: CreateHTMLAttribute (context->lastElement, attrType, msgBuffer, TRUE,
1015: context->doc, ¤tAttribute, &lastAttrElement);
1016: }
1017: else
1.91 quint 1018: /* value is the Thot type of the element to be created for this value of
1019: the TYPE attribute */
1.30 cvs 1020: {
1021: elType = TtaGetElementType (context->lastElement);
1022: if (elType.ElTypeNum != HTML_EL_Input)
1023: {
1.37 cvs 1024: sprintf (msgBuffer, "Duplicate attribute \"type = %s\"", val);
1.100 gully 1025: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.30 cvs 1026: }
1027: else
1028: {
1029: elType.ElTypeNum = value;
1030: newChild = TtaNewTree (context->doc, elType, "");
1031: XmlSetElemLineNumber (newChild);
1032: TtaInsertFirstChild (&newChild, context->lastElement, context->doc);
1033: if (value == HTML_EL_PICTURE_UNIT)
1034: {
1035: /* add the attribute IsInput to input pictures */
1036: attrType.AttrSSchema = elType.ElSSchema;
1037: attrType.AttrTypeNum = HTML_ATTR_IsInput;
1038: attr = TtaNewAttribute (attrType);
1039: TtaAttachAttribute (newChild, attr, context->doc);
1040: }
1041: }
1042: }
1043: }
1044:
1045: /*----------------------------------------------------------------------
1046: CreateAttrWidthPercentPxl
1.79 quint 1047: an HTML attribute "width" has been created for a Table, an image,
1048: an Object of a HR.
1.30 cvs 1049: Create the corresponding attribute IntWidthPercent or IntWidthPxl.
1050: oldWidth is -1 or the old image width.
1051: ----------------------------------------------------------------------*/
1.58 vatton 1052: void CreateAttrWidthPercentPxl (char *buffer, Element el,
1053: Document doc, int oldWidth)
1.30 cvs 1054: {
1055: AttributeType attrTypePxl, attrTypePercent;
1056: Attribute attrOld, attrNew;
1057: int length, val;
1.39 cvs 1058: char msgBuffer[MaxMsgLength];
1.79 quint 1059: ElementType elType, childType;
1060: Element origEl, child;
1.30 cvs 1061: int w, h;
1062: ThotBool isImage;
1063:
1.79 quint 1064: origEl = el;
1.30 cvs 1065: elType = TtaGetElementType (el);
1066: isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
1067: elType.ElTypeNum == HTML_EL_Data_cell ||
1.79 quint 1068: elType.ElTypeNum == HTML_EL_Heading_cell ||
1069: elType.ElTypeNum == HTML_EL_Object);
1070: if (elType.ElTypeNum == HTML_EL_Object)
1071: /* the width attribute is attached to an Object element */
1072: {
1073: child = TtaGetFirstChild (el);
1074: if (child)
1075: {
1076: childType = TtaGetElementType (child);
1077: if (childType.ElTypeNum == HTML_EL_PICTURE_UNIT)
1078: /* the Object element is of type image. apply the width
1079: attribute to the actual image element */
1080: el = child;
1081: }
1082: }
1.30 cvs 1083: /* remove trailing spaces */
1.37 cvs 1084: length = strlen (buffer) - 1;
1.30 cvs 1085: while (length > 0 && buffer[length] <= SPACE)
1086: length--;
1087: attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
1088: attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
1089: attrTypePxl.AttrTypeNum = HTML_ATTR_IntWidthPxl;
1090: attrTypePercent.AttrTypeNum = HTML_ATTR_IntWidthPercent;
1091: /* is the last character a '%' ? */
1092: if (buffer[length] == '%')
1093: {
1094: /* remove IntWidthPxl */
1095: attrOld = TtaGetAttribute (el, attrTypePxl);
1096: /* update IntWidthPercent */
1097: attrNew = TtaGetAttribute (el, attrTypePercent);
1098: if (attrNew == NULL)
1099: {
1100: attrNew = TtaNewAttribute (attrTypePercent);
1101: TtaAttachAttribute (el, attrNew, doc);
1102: }
1103: else if (isImage && oldWidth == -1)
1104: {
1105: if (attrOld == NULL)
1106: oldWidth = TtaGetAttributeValue (attrNew);
1107: else
1108: oldWidth = TtaGetAttributeValue (attrOld);
1109: }
1110: }
1111: else
1112: {
1113: /* remove IntWidthPercent */
1114: attrOld = TtaGetAttribute (el, attrTypePercent);
1115: /* update IntWidthPxl */
1116: attrNew = TtaGetAttribute (el, attrTypePxl);
1117: if (attrNew == NULL)
1118: {
1119: attrNew = TtaNewAttribute (attrTypePxl);
1120: TtaAttachAttribute (el, attrNew, doc);
1121: }
1122: else if (isImage && oldWidth == -1)
1123: {
1124: TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
1125: if (attrOld == NULL)
1126: oldWidth = w * TtaGetAttributeValue (attrNew) / 100;
1127: else
1128: oldWidth = w * TtaGetAttributeValue (attrOld) / 100;
1129: }
1130: }
1131:
1132: if (attrOld != NULL)
1133: TtaRemoveAttribute (el, attrOld, doc);
1.43 cvs 1134: if (sscanf (buffer, "%d", &val))
1.30 cvs 1135: TtaSetAttributeValue (attrNew, val, el, doc);
1136: else
1137: /* its not a number. Delete attribute and send an error message */
1138: {
1139: TtaRemoveAttribute (el, attrNew, doc);
1.37 cvs 1140: if (strlen (buffer) > MaxMsgLength - 30)
1.30 cvs 1141: buffer[MaxMsgLength - 30] = EOS;
1.37 cvs 1142: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42 cvs 1143: HTMLParseError (doc, msgBuffer);
1.30 cvs 1144: }
1145: if (isImage)
1.79 quint 1146: UpdateImageMap (origEl, doc, oldWidth, -1);
1.30 cvs 1147: }
1148:
1149: /*----------------------------------------------------------------------
1.58 vatton 1150: CreateAttrHeightPercentPxl
1.79 quint 1151: an HTML attribute "width" has been created for a Table, an image,
1152: an Object or a HR.
1.58 vatton 1153: Create the corresponding attribute IntHeightPercent or IntHeightPxl.
1154: oldHeight is -1 or the old image width.
1155: ----------------------------------------------------------------------*/
1156: void CreateAttrHeightPercentPxl (char *buffer, Element el,
1157: Document doc, int oldHeight)
1158: {
1159: AttributeType attrTypePxl, attrTypePercent;
1160: Attribute attrOld, attrNew;
1161: int length, val;
1162: char msgBuffer[MaxMsgLength];
1.79 quint 1163: ElementType elType, childType;
1164: Element origEl, child;
1.58 vatton 1165: int w, h;
1166: ThotBool isImage;
1167:
1.79 quint 1168: origEl = el;
1.58 vatton 1169: elType = TtaGetElementType (el);
1170: isImage = (elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
1171: elType.ElTypeNum == HTML_EL_Data_cell ||
1.79 quint 1172: elType.ElTypeNum == HTML_EL_Heading_cell ||
1173: elType.ElTypeNum == HTML_EL_Object);
1174: if (elType.ElTypeNum == HTML_EL_Object)
1175: /* the height attribute is attached to an Object element */
1176: {
1177: child = TtaGetFirstChild (el);
1.81 cvs 1178: if (!child)
1179: return;
1180: else
1.79 quint 1181: {
1182: childType = TtaGetElementType (child);
1183: if (childType.ElTypeNum == HTML_EL_PICTURE_UNIT)
1184: /* the Object element is of type image. apply the width
1185: attribute to the actual image element */
1186: el = child;
1.81 cvs 1187: else
1188: return;
1.79 quint 1189: }
1190: }
1.58 vatton 1191: /* remove trailing spaces */
1192: length = strlen (buffer) - 1;
1193: while (length > 0 && buffer[length] <= SPACE)
1194: length--;
1195: attrTypePxl.AttrSSchema = TtaGetDocumentSSchema (doc);
1196: attrTypePercent.AttrSSchema = TtaGetDocumentSSchema (doc);
1197: attrTypePxl.AttrTypeNum = HTML_ATTR_IntHeightPxl;
1198: attrTypePercent.AttrTypeNum = HTML_ATTR_IntHeightPercent;
1199: /* is the last character a '%' ? */
1200: if (buffer[length] == '%')
1201: {
1202: /* remove IntHeightPxl */
1203: attrOld = TtaGetAttribute (el, attrTypePxl);
1204: /* update IntHeightPercent */
1205: attrNew = TtaGetAttribute (el, attrTypePercent);
1206: if (attrNew == NULL)
1207: {
1208: attrNew = TtaNewAttribute (attrTypePercent);
1209: TtaAttachAttribute (el, attrNew, doc);
1210: }
1211: else if (isImage && oldHeight == -1)
1212: {
1213: if (attrOld == NULL)
1214: oldHeight = TtaGetAttributeValue (attrNew);
1215: else
1216: oldHeight = TtaGetAttributeValue (attrOld);
1217: }
1218: }
1219: else
1220: {
1221: /* remove IntHeightPercent */
1222: attrOld = TtaGetAttribute (el, attrTypePercent);
1223: /* update IntHeightPxl */
1224: attrNew = TtaGetAttribute (el, attrTypePxl);
1225: if (attrNew == NULL)
1226: {
1227: attrNew = TtaNewAttribute (attrTypePxl);
1228: TtaAttachAttribute (el, attrNew, doc);
1229: }
1230: else if (isImage && oldHeight == -1)
1231: {
1232: TtaGiveBoxSize (el, doc, 1, UnPixel, &w, &h);
1233: if (attrOld == NULL)
1234: oldHeight = w * TtaGetAttributeValue (attrNew) / 100;
1235: else
1236: oldHeight = w * TtaGetAttributeValue (attrOld) / 100;
1237: }
1238: }
1239:
1240: if (attrOld != NULL)
1241: TtaRemoveAttribute (el, attrOld, doc);
1242: if (sscanf (buffer, "%d", &val))
1243: TtaSetAttributeValue (attrNew, val, el, doc);
1244: else
1245: /* its not a number. Delete attribute and send an error message */
1246: {
1247: TtaRemoveAttribute (el, attrNew, doc);
1248: if (strlen (buffer) > MaxMsgLength - 30)
1249: buffer[MaxMsgLength - 30] = EOS;
1250: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1251: HTMLParseError (doc, msgBuffer);
1252: }
1253: if (isImage)
1.79 quint 1254: UpdateImageMap (origEl, doc, oldHeight, -1);
1.58 vatton 1255: }
1256:
1257: /*----------------------------------------------------------------------
1.91 quint 1258: CreateAttrIntAreaSize
1259: an HTML attribute "size" has been created or modified for a input element.
1260: Create or update the corresponding attribute IntAreaSize.
1261: ----------------------------------------------------------------------*/
1262: void CreateAttrIntAreaSize (int value, Element el, Document doc)
1263: {
1264: AttributeType attrType;
1265: Attribute attr;
1266: ElementType elType;
1267:
1268: elType = TtaGetElementType (el);
1269: attrType.AttrSSchema = elType.ElSSchema;
1270: attrType.AttrTypeNum = HTML_ATTR_IntAreaSize;
1271: attr = TtaGetAttribute (el, attrType);
1272: if (!attr)
1273: {
1274: attr = TtaNewAttribute (attrType);
1275: TtaAttachAttribute (el, attr, doc);
1276: }
1277: /* the presentation rule associated with attribute IntAreaSize expresses
1278: the element width in "em". Convert the value into em */
1279: TtaSetAttributeValue (attr, (int) (value * 0.55), el, doc);
1280: }
1281:
1282: /*----------------------------------------------------------------------
1.30 cvs 1283: CreateAttrIntSize
1284: an HTML attribute "size" has been created for a Font element.
1285: Create the corresponding internal attribute.
1286: ----------------------------------------------------------------------*/
1.46 cvs 1287: void CreateAttrIntSize (char *buffer, Element el, Document doc)
1.30 cvs 1288:
1289: {
1290: AttributeType attrType;
1291: int val, ind, factor, delta;
1292: Attribute attr;
1.37 cvs 1293: char msgBuffer[MaxMsgLength];
1.30 cvs 1294:
1295: /* is the first character a '+' or a '-' ? */
1296: ind = 0;
1297: factor = 1;
1298: delta = 0;
1299: if (buffer[0] == '+')
1300: {
1301: attrType.AttrTypeNum = HTML_ATTR_IntSizeIncr;
1302: ind++;
1.90 vatton 1303: factor = 1;
1.30 cvs 1304: }
1305: else if (buffer[0] == '-')
1306: {
1307: attrType.AttrTypeNum = HTML_ATTR_IntSizeDecr;
1308: ind++;
1.90 vatton 1309: factor = 1;
1.30 cvs 1310: }
1311: else
1312: {
1313: attrType.AttrTypeNum = HTML_ATTR_IntSizeRel;
1314: delta = 1;
1315: }
1316: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
1317: attr = TtaGetAttribute (el, attrType);
1.43 cvs 1318: if (sscanf (&buffer[ind], "%d", &val))
1.30 cvs 1319: {
1320: val = val * factor + delta;
1321: if (attr == NULL)
1322: {
1323: /* this attribute doesn't exist, create it */
1324: attr = TtaNewAttribute (attrType);
1325: TtaAttachAttribute (el, attr, doc);
1326: }
1327: TtaSetAttributeValue (attr, val, el, doc);
1328: }
1329: else
1330: /* its not a number. Delete attribute and send an error message */
1331: {
1332: if (attr)
1333: TtaRemoveAttribute (el, attr, doc);
1.37 cvs 1334: if (strlen (buffer) > MaxMsgLength - 30)
1.30 cvs 1335: buffer[MaxMsgLength - 30] = EOS;
1.37 cvs 1336: sprintf (msgBuffer, "Invalid attribute value \"%s\"", buffer);
1.42 cvs 1337: HTMLParseError (doc, msgBuffer);
1.30 cvs 1338: }
1339: }
1340: /*----------------------------------------------------------------------
1341: EndOfHTMLAttributeValue
1342: Filling of an HTML attribute value
1343: ----------------------------------------------------------------------*/
1.48 vatton 1344: void EndOfHTMLAttributeValue (char *attrValue,
1345: AttributeMapping *lastMappedAttr,
1346: Attribute currentAttribute,
1347: Element lastAttrElement,
1348: ThotBool UnknownAttr,
1349: ParserData *context,
1350: ThotBool isXML)
1.30 cvs 1351: {
1.48 vatton 1352: AttributeType attrType, attrType1;
1353: Attribute attr;
1.79 quint 1354: ElementType elType;
1.48 vatton 1355: Element child, root;
1356: Language lang;
1357: char translation;
1358: char shape;
1359: char *buffer;
1360: char *attrName;
1361: char msgBuffer[MaxMsgLength];
1362: int val;
1363: int length;
1364: int attrKind;
1365: ThotBool done = FALSE;
1.88 vatton 1366: ThotBool loadcss;
1.30 cvs 1367:
1.48 vatton 1368: /* treatments of some particular HTML attributes */
1369: if (!strcmp (lastMappedAttr->XMLattribute, "style"))
1370: {
1371: TtaSetAttributeText (currentAttribute, attrValue,
1372: lastAttrElement, context->doc);
1.88 vatton 1373: /* check if we have to load CSS */
1374: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
1375: if (loadcss)
1376: ParseHTMLSpecificStyle (context->lastElement, attrValue,
1377: context->doc, 100, FALSE);
1.48 vatton 1378: done = TRUE;
1379: }
1380: else
1381: {
1382: if (!strcmp (lastMappedAttr->XMLattribute, "link"))
1.89 vatton 1383: HTMLSetAlinkColor (context->doc, context->lastElement, attrValue);
1.48 vatton 1384: else if (!strcmp (lastMappedAttr->XMLattribute, "alink"))
1.89 vatton 1385: HTMLSetAactiveColor (context->doc, context->lastElement, attrValue);
1.48 vatton 1386: else if (!strcmp (lastMappedAttr->XMLattribute, "vlink"))
1.89 vatton 1387: HTMLSetAvisitedColor (context->doc, context->lastElement, attrValue);
1.48 vatton 1388: }
1.30 cvs 1389:
1.48 vatton 1390: if (!done)
1391: {
1392: val = 0;
1393: translation = lastMappedAttr->AttrOrContent;
1394: switch (translation)
1395: {
1396: case 'C': /* Content */
1397: child = PutInContent (attrValue, context);
1398: if (child != NULL)
1.100 gully 1399: TtaAppendTextContent (child, (unsigned char *)"\" ", context->doc);
1.48 vatton 1400: break;
1401:
1402: case 'A':
1403: if (currentAttribute != NULL)
1404: {
1405: TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
1406: switch (attrKind)
1407: {
1408: case 0: /* enumerate */
1409: if (isXML)
1.100 gully 1410: MapHTMLAttributeValue (attrValue, &attrType, &val);
1.48 vatton 1411: else
1412: val = MapAttrValue (lastMappedAttr->ThotAttribute,
1.40 cvs 1413: attrValue);
1.48 vatton 1414: if (val < 0)
1415: {
1416: TtaGiveAttributeType (currentAttribute,
1417: &attrType, &attrKind);
1418: attrName = TtaGetAttributeName (attrType);
1419: sprintf (msgBuffer,
1.51 cvs 1420: "Invalid attribute value \"%s = %s\"",
1.48 vatton 1421: attrName, attrValue);
1422: if (isXML)
1.100 gully 1423: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.48 vatton 1424: else
1.84 quint 1425: /* we are parsing an HTML file, not an XHTML file */
1.51 cvs 1426: {
1.84 quint 1427: /* generate an error message in the log */
1.51 cvs 1428: HTMLParseError (context->doc, msgBuffer);
1.84 quint 1429: /* special case for value POLYGON of attribute
1430: shape (AREA element) */
1431: if (attrType.AttrTypeNum == HTML_ATTR_shape &&
1432: strcasecmp (attrValue, "POLYGON") == 0)
1433: {
1434: val = HTML_ATTR_shape_VAL_polygon;
1435: /* interpret it as if it were "poly" */
1436: TtaSetAttributeValue (currentAttribute, val,
1437: lastAttrElement, context->doc);
1438: }
1439: else
1440: /* remove the attribute and replace it by an */
1441: /* Invalid_attribute (not for XHTML) */
1442: {
1443: TtaRemoveAttribute (lastAttrElement,
1.51 cvs 1444: currentAttribute, context->doc);
1.84 quint 1445: attrType.AttrSSchema =
1446: TtaGetDocumentSSchema (context->doc);
1447: attrType.AttrTypeNum =
1448: pHTMLAttributeMapping[0].ThotAttribute;
1449: sprintf (msgBuffer, "%s=%s", attrName,attrValue);
1450: CreateHTMLAttribute (lastAttrElement, attrType,
1451: msgBuffer, TRUE, context->doc,
1452: ¤tAttribute, &lastAttrElement);
1453: }
1.48 vatton 1454: }
1455: }
1456: else
1457: TtaSetAttributeValue (currentAttribute, val,
1458: lastAttrElement, context->doc);
1459: break;
1460: case 1: /* integer */
1461: if (attrType.AttrTypeNum == HTML_ATTR_Border &&
1462: !strcasecmp (attrValue, "border"))
1463: {
1464: /* border="border" for a table */
1465: val = 1;
1466: TtaSetAttributeValue (currentAttribute, val,
1.30 cvs 1467: lastAttrElement, context->doc);
1.48 vatton 1468: }
1469: else if (sscanf (attrValue, "%d", &val))
1470: TtaSetAttributeValue (currentAttribute, val,
1471: lastAttrElement, context->doc);
1472: else
1473: {
1474: TtaRemoveAttribute (lastAttrElement, currentAttribute,
1475: context->doc);
1476: sprintf (msgBuffer,
1477: "Unknown attribute value \"%s\"",
1478: attrValue);
1479: if (isXML)
1.100 gully 1480: XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
1.48 vatton 1481: else
1482: HTMLParseError (context->doc, msgBuffer);
1483: }
1484: break;
1485: case 2: /* text */
1486: if (!UnknownAttr)
1487: {
1488: TtaSetAttributeText (currentAttribute, attrValue,
1489: lastAttrElement, context->doc);
1.55 cvs 1490: if (attrType.AttrTypeNum == HTML_ATTR_Language)
1.48 vatton 1491: {
1492: /* it's a LANG attribute value */
1493: lang = TtaGetLanguageIdFromName (attrValue);
1.70 vatton 1494: if (lang < 0)
1.48 vatton 1495: {
1496: sprintf (msgBuffer,
1497: "warning - unsupported language: %s",
1498: attrValue);
1499: if (isXML)
1.100 gully 1500: XmlParseError (warningMessage, (unsigned char *)msgBuffer, 0);
1.48 vatton 1501: else
1502: HTMLParseError (context->doc, msgBuffer);
1503: }
1504: else
1505: {
1506: /* change current language */
1507: context->language = lang;
1508: if (isXML)
1509: SetLanguagInXmlStack (lang);
1510: else
1511: SetLanguagInHTMLStack (lang);
1512: }
1513: root = TtaGetRootElement (context->doc);
1514: if (lastAttrElement == root)
1515: /* it's a LANG attribute on the root element */
1516: /* set the RealLang attribute */
1517: {
1518: attrType1.AttrSSchema = TtaGetDocumentSSchema (context->doc);
1519: attrType1.AttrTypeNum = HTML_ATTR_RealLang;
1520: /* this attribute could be already present,
1521: (lang and xml:lang attributes) */
1522: if (!TtaGetAttribute (lastAttrElement,
1523: attrType1))
1524: /* it's not present. Add it */
1525: {
1526: attr = TtaNewAttribute (attrType1);
1527: TtaAttachAttribute (lastAttrElement,
1528: attr, context->doc);
1529: TtaSetAttributeValue (attr,
1530: HTML_ATTR_RealLang_VAL_Yes_,
1531: lastAttrElement,
1532: context->doc);
1533: }
1534: }
1535: }
1536: else if (attrType.AttrTypeNum == HTML_ATTR_accesskey)
1537: TtaAddAccessKey (context->doc, (unsigned int)attrValue[0],
1538: lastAttrElement);
1539: }
1540: else
1541: {
1.51 cvs 1542: /* this is the content of an invalid attribute */
1543: /* append it to the current Invalid_attribute */
1544: if (!isXML)
1545: {
1546: length = strlen (attrValue) + 2;
1547: length += TtaGetTextAttributeLength (currentAttribute);
1.100 gully 1548: buffer = (char *)TtaGetMemory (length + 1);
1.51 cvs 1549: TtaGiveTextAttributeValue (currentAttribute,
1550: buffer, &length);
1551: strcat (buffer, "=");
1552: strcat (buffer, attrValue);
1553: TtaSetAttributeText (currentAttribute, buffer,
1554: lastAttrElement, context->doc);
1555: TtaFreeMemory (buffer);
1556: }
1.48 vatton 1557: }
1558: break;
1559: case 3: /* reference */
1560: break;
1561: }
1562: }
1563: break;
1564:
1565: case SPACE:
1566: if (isXML)
1567: XhtmlTypeAttrValue (attrValue, currentAttribute,
1.30 cvs 1568: lastAttrElement, context);
1.48 vatton 1569: else
1570: HTMLTypeAttrValue (attrValue, currentAttribute,
1571: lastAttrElement, context);
1572: break;
1573:
1.30 cvs 1574: default:
1575: break;
1.48 vatton 1576: }
1.30 cvs 1577:
1578: if (lastMappedAttr->ThotAttribute == HTML_ATTR_Width__)
1.79 quint 1579: /* HTML attribute "width" */
1580: {
1581: /* if it's an Object element, wait until all attributes are handled,
1582: especially the data attribute that may generate the image to
1583: which the width has to be applied */
1584: elType = TtaGetElementType (lastAttrElement);
1585: if (elType.ElTypeNum != HTML_EL_Object)
1586: /* create the corresponding attribute IntWidthPercent or */
1587: /* IntWidthPxl */
1588: CreateAttrWidthPercentPxl (attrValue, lastAttrElement,
1589: context->doc, -1);
1590: }
1.58 vatton 1591: else if (lastMappedAttr->ThotAttribute == HTML_ATTR_Height_)
1.79 quint 1592: /* HTML attribute "height" */
1593: {
1594: /* if it's an Object element, wait until all attributes are handled,
1595: especially the data attribute that may generate the image to
1596: which the height has to be applied */
1597: elType = TtaGetElementType (lastAttrElement);
1598: if (elType.ElTypeNum != HTML_EL_Object)
1599: /* create the corresponding attribute IntHeightPercent or */
1600: /* IntHeightPxl */
1601: CreateAttrHeightPercentPxl (attrValue, lastAttrElement,
1602: context->doc, -1);
1603: }
1.91 quint 1604: else if (lastMappedAttr->ThotAttribute == HTML_ATTR_Area_Size)
1605: /* HTML attribute "size" for an element "input" */
1606: CreateAttrIntAreaSize (val, lastAttrElement, context->doc);
1.48 vatton 1607: else if (!strcmp (lastMappedAttr->XMLattribute, "size"))
1608: {
1609: TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
1610: if (attrType.AttrTypeNum == HTML_ATTR_Font_size)
1611: CreateAttrIntSize (attrValue, lastAttrElement, context->doc);
1612: }
1613: else if (!strcmp (lastMappedAttr->XMLattribute, "shape"))
1614: {
1615: child = TtaGetFirstChild (lastAttrElement);
1616: if (child != NULL)
1617: {
1618: switch (val)
1619: {
1620: case HTML_ATTR_shape_VAL_rectangle:
1621: shape = 'R';
1622: break;
1623: case HTML_ATTR_shape_VAL_circle:
1624: shape = 'a';
1625: break;
1626: case HTML_ATTR_shape_VAL_polygon:
1627: shape = 'p';
1628: break;
1629: default:
1630: shape = SPACE;
1631: break;
1632: }
1633: TtaSetGraphicsShape (child, shape, context->doc);
1634: }
1635: }
1636: else if (!strcmp (lastMappedAttr->XMLattribute, "value"))
1637: {
1638: elType = TtaGetElementType (lastAttrElement);
1639: if (elType.ElTypeNum == HTML_EL_Text_Input ||
1640: elType.ElTypeNum == HTML_EL_Password_Input ||
1641: elType.ElTypeNum == HTML_EL_File_Input ||
1642: elType.ElTypeNum == HTML_EL_Input)
1643: /* create a Default_Value attribute with the same content */
1644: {
1645: attrType1.AttrSSchema = attrType.AttrSSchema;
1646: attrType1.AttrTypeNum = HTML_ATTR_Default_Value;
1647: attr = TtaNewAttribute (attrType1);
1648: TtaAttachAttribute (lastAttrElement, attr, context->doc);
1649: TtaSetAttributeText (attr, attrValue,
1650: lastAttrElement, context->doc);
1651: }
1652: }
1.30 cvs 1653: else
1.48 vatton 1654: {
1655: /* Some HTML attributes are equivalent to a CSS property: */
1656: /* background -> background */
1657: /* bgcolor -> background */
1658: /* text -> color */
1659: /* color -> color */
1660: if (!strcmp (lastMappedAttr->XMLattribute, "background"))
1661: {
1662: if (strlen (attrValue) > MaxMsgLength - 30)
1663: attrValue[MaxMsgLength - 30] = EOS;
1.76 vatton 1664: HTMLSetBackgroundImage (context->doc, context->lastElement,
1.85 vatton 1665: REPEAT, attrValue, FALSE);
1.48 vatton 1666: }
1667: else if (!strcmp (lastMappedAttr->XMLattribute, "bgcolor"))
1.76 vatton 1668: HTMLSetBackgroundColor (context->doc, context->lastElement,
1669: attrValue);
1.48 vatton 1670: else if (!strcmp (lastMappedAttr->XMLattribute, "text") ||
1671: !strcmp (lastMappedAttr->XMLattribute, "color"))
1672: HTMLSetForegroundColor (context->doc,
1673: context->lastElement, attrValue);
1674: }
1675: }
1.30 cvs 1676: }
1677:
1678: /*----------------------------------------------------------------------
1.16 cvs 1679: MapHTMLAttributeValue
1.2 cvs 1680: Search in the Attribute Value Mapping Table the entry for the attribute
1.66 vatton 1681: ThotAtt and its value attVal. Returns the corresponding Thot value.
1.1 cvs 1682: ----------------------------------------------------------------------*/
1.100 gully 1683: void MapHTMLAttributeValue (char *attVal, const AttributeType * attrType, int *value)
1.1 cvs 1684: {
1.66 vatton 1685: MapXMLAttributeValue (XHTML_TYPE, attVal, attrType, value);
1.1 cvs 1686: }
Webmaster