1 #ifndef __HTML_COMMON_HH__
2 #define __HTML_COMMON_HH__
3 
4 #include "url.h"
5 #include "bw.h"
6 
7 #include "lout/misc.hh"
8 #include "dw/core.hh"
9 #include "dw/image.hh"
10 #include "dw/style.hh"
11 
12 #include "image.hh"
13 
14 #include "form.hh"
15 
16 #include "styleengine.hh"
17 
18 /*
19  * Macros
20  */
21 
22 // "html struct" to Textblock
23 #define HT2TB(html)  ((Textblock*)(html->dw))
24 // "html struct" to "Layout"
25 #define HT2LT(html)  ((Layout*)html->bw->render_layout)
26 // "Image" to "Dw Widget"
27 #define IM2DW(Image)  ((Widget*)Image->dw)
28 // Top of the parsing stack
29 #define S_TOP(html)  (html->stack->getRef(html->stack->size()-1))
30 
31 // Add a bug-meter message.
32 #define BUG_MSG(...)                               \
33    D_STMT_START {                                  \
34          html->bugMessage(__VA_ARGS__);            \
35    } D_STMT_END
36 
37 
38 /*
39  * Typedefs
40  */
41 
42 typedef enum {
43    DT_NONE,
44    DT_UNRECOGNIZED,
45    DT_HTML,
46    DT_XHTML
47 } DilloHtmlDocumentType;
48 
49 typedef enum {
50    DILLO_HTML_PARSE_MODE_INIT = 0,
51    DILLO_HTML_PARSE_MODE_STASH,
52    DILLO_HTML_PARSE_MODE_STASH_AND_BODY,
53    DILLO_HTML_PARSE_MODE_VERBATIM,
54    DILLO_HTML_PARSE_MODE_BODY,
55    DILLO_HTML_PARSE_MODE_PRE
56 } DilloHtmlParseMode;
57 
58 typedef enum {
59    DILLO_HTML_TABLE_MODE_NONE,  /* no table at all */
60    DILLO_HTML_TABLE_MODE_TOP,   /* outside of <tr> */
61    DILLO_HTML_TABLE_MODE_TR,    /* inside of <tr>, outside of <td> */
62    DILLO_HTML_TABLE_MODE_TD     /* inside of <td> */
63 } DilloHtmlTableMode;
64 
65 typedef enum {
66    DILLO_HTML_TABLE_BORDER_SEPARATE,
67    DILLO_HTML_TABLE_BORDER_COLLAPSE
68 } DilloHtmlTableBorderMode;
69 
70 typedef enum {
71    HTML_LIST_NONE,
72    HTML_LIST_UNORDERED,
73    HTML_LIST_ORDERED
74 } DilloHtmlListMode;
75 
76 typedef enum {
77    IN_NONE        = 0,
78    IN_HTML        = 1 << 0,
79    IN_HEAD        = 1 << 1,
80    IN_BODY        = 1 << 2,
81    IN_FORM        = 1 << 3,
82    IN_SELECT      = 1 << 4,
83    IN_OPTION      = 1 << 5,
84    IN_OPTGROUP    = 1 << 6,
85    IN_TEXTAREA    = 1 << 7,
86    IN_BUTTON      = 1 << 8,
87    IN_MAP         = 1 << 9,
88    IN_PRE         = 1 << 10,
89    IN_LI          = 1 << 11,
90    IN_MEDIA       = 1 << 12,
91    IN_META_HACK   = 1 << 13,
92    IN_EOF         = 1 << 14,
93 } DilloHtmlProcessingState;
94 
95 /*
96  * Data Structures
97  */
98 
99 typedef struct {
100    DilloUrl *url;
101    DilloImage *image;
102 } DilloHtmlImage;
103 
104 typedef struct {
105    DilloHtmlParseMode parse_mode;
106    DilloHtmlTableMode table_mode;
107    DilloHtmlTableBorderMode table_border_mode;
108    bool cell_text_align_set;
109    bool display_none;
110    DilloHtmlListMode list_type;
111    int list_number;
112 
113    /* TagInfo index for the tag that's being processed */
114    int tag_idx;
115 
116    dw::core::Widget *textblock, *table;
117 
118    /* This is used to align list items (especially in enumerated lists) */
119    dw::core::Widget *ref_list_item;
120 
121    /* This is used for list items etc; if it is set to TRUE, breaks
122       have to be "handed over" (see Html_add_indented and
123       Html_eventually_pop_dw). */
124    bool hand_over_break;
125 } DilloHtmlState;
126 
127 /*
128  * Classes
129  */
130 
131 class DilloHtml {
132 private:
133    class HtmlLinkReceiver: public dw::core::Layout::LinkReceiver {
134    public:
135       DilloHtml *html;
136 
137       bool enter (dw::core::Widget *widget, int link, int img, int x, int y);
138       bool press (dw::core::Widget *widget, int link, int img, int x, int y,
139                   dw::core::EventButton *event);
140       bool click (dw::core::Widget *widget, int link, int img, int x, int y,
141                   dw::core::EventButton *event);
142    };
143    HtmlLinkReceiver linkReceiver;
144 
145 public:  //BUG: for now everything is public
146 
147    BrowserWindow *bw;
148    DilloUrl *page_url, *base_url;
149    dw::core::Widget *dw;    /* this is duplicated in the stack */
150 
151    /* -------------------------------------------------------------------*/
152    /* Variables required at parsing time                                 */
153    /* -------------------------------------------------------------------*/
154    char *Start_Buf;
155    int Start_Ofs;
156    char *content_type, *charset;
157    bool stop_parser;
158 
159    size_t CurrOfs, OldOfs, OldLine;
160 
161    DilloHtmlDocumentType DocType; /* as given by DOCTYPE tag */
162    float DocTypeVersion;          /* HTML or XHTML version number */
163 
164    /* vector of remote CSS resources, as given by the LINK element */
165    lout::misc::SimpleVector<DilloUrl*> *cssUrls;
166 
167    lout::misc::SimpleVector<DilloHtmlState> *stack;
168    StyleEngine *styleEngine;
169 
170    int InFlags; /* tracks which elements we are in */
171 
172    Dstr *Stash;
173    bool StashSpace;
174 
175    int pre_column;        /* current column, used in PRE tags with tabs */
176    bool PreFirstChar;     /* used to skip the first CR or CRLF in PRE tags */
177    bool PrevWasCR;        /* Flag to help parsing of "\r\n" in PRE tags */
178    bool PrevWasOpenTag;   /* Flag to help deferred parsing of white space */
179    bool InVisitedLink;    /* used to 'contrast_visited_colors' */
180    bool ReqTagClose;      /* Flag to help handling bad-formed HTML */
181    bool TagSoup;          /* Flag to enable the parser's cleanup functions */
182    bool loadCssFromStash; /* current stash content should be loaded as CSS */
183 
184    /* element counters: used for validation purposes.
185     * ATM they're used as three state flags {0,1,>1} */
186    uchar_t Num_HTML, Num_HEAD, Num_BODY, Num_TITLE;
187 
188    Dstr *attr_data;       /* Buffer for attribute value */
189 
190    int32_t non_css_link_color; /* as provided by link attribute in BODY */
191    int32_t non_css_visited_color; /* as provided by vlink attribute in BODY */
192    int32_t visited_color; /* as computed according to CSS */
193 
194    /* -------------------------------------------------------------------*/
195    /* Variables required after parsing (for page functionality)          */
196    /* -------------------------------------------------------------------*/
197    lout::misc::SimpleVector<DilloHtmlForm*> *forms;
198    lout::misc::SimpleVector<DilloHtmlInput*> *inputs_outside_form;
199    lout::misc::SimpleVector<DilloUrl*> *links;
200    lout::misc::SimpleVector<DilloHtmlImage*> *images;
201    dw::ImageMapsList maps;
202 
203 private:
204    void freeParseData();
205    void initDw();  /* Used by the constructor */
206 
207 public:
208    DilloHtml(BrowserWindow *bw, const DilloUrl *url, const char *content_type);
209    ~DilloHtml();
210    void bugMessage(const char *format, ... );
211    void connectSignals(dw::core::Widget *dw);
212    void write(char *Buf, int BufSize, int Eof);
213    int getCurrLineNumber();
214    void finishParsing(int ClientKey);
215    int formNew(DilloHtmlMethod method, const DilloUrl *action,
216                DilloHtmlEnc enc, const char *charset);
217    DilloHtmlForm *getCurrentForm ();
218    bool_t unloadedImages();
219    void loadImages (const DilloUrl *pattern);
220    void addCssUrl(const DilloUrl *url);
221 
222    // useful shortcuts
startElement(int tag)223    inline void startElement (int tag)
224    { styleEngine->startElement (tag, bw); }
startElement(const char * tagname)225    inline void startElement (const char *tagname)
226    { styleEngine->startElement (tagname, bw); }
227 
backgroundStyle()228    inline dw::core::style::Style *backgroundStyle ()
229    { return styleEngine->backgroundStyle (bw); }
style()230    inline dw::core::style::Style *style ()
231    { return styleEngine->style (bw); }
wordStyle()232    inline dw::core::style::Style *wordStyle ()
233    { return styleEngine->wordStyle (bw); }
234 
restyle()235    inline void restyle () { styleEngine->restyle (bw); }
236 
237 };
238 
239 /*
240  * Parser functions
241  */
242 
243 int a_Html_tag_index(const char *tag);
244 
245 const char *a_Html_get_attr(DilloHtml *html,
246                             const char *tag,
247                             int tagsize,
248                             const char *attrname);
249 
250 char *a_Html_get_attr_wdef(DilloHtml *html,
251                            const char *tag,
252                            int tagsize,
253                            const char *attrname,
254                            const char *def);
255 
256 DilloUrl *a_Html_url_new(DilloHtml *html,
257                          const char *url_str, const char *base_url,
258                          int use_base_url);
259 
260 void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize);
261 DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize);
262 
263 char *a_Html_parse_entities(DilloHtml *html, const char *token, int toksize);
264 void a_Html_pop_tag(DilloHtml *html, int TagIdx);
265 void a_Html_stash_init(DilloHtml *html);
266 int32_t a_Html_color_parse(DilloHtml *html, const char *str,
267                            int32_t default_color);
268 dw::core::style::Length a_Html_parse_length (DilloHtml *html,
269                                              const char *attr);
270 void a_Html_tag_set_align_attr(DilloHtml *html, const char *tag, int tagsize);
271 bool a_Html_tag_set_valign_attr(DilloHtml *html,
272                                 const char *tag, int tagsize);
273 
274 void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url);
275 
276 #endif /* __HTML_COMMON_HH__ */
277