]> git.saurik.com Git - wxWidgets.git/blame - src/html/winpars.cpp
use wxIsSameDouble() and wxIsNullDouble() for warning-less double comparison of doubles
[wxWidgets.git] / src / html / winpars.cpp
CommitLineData
5526e819 1/////////////////////////////////////////////////////////////////////////////
69941f05 2// Name: winpars.cpp
5526e819
VS
3// Purpose: wxHtmlParser class (generic parser)
4// Author: Vaclav Slavik
69941f05 5// RCS-ID: $Id$
5526e819 6// Copyright: (c) 1999 Vaclav Slavik
65571936 7// Licence: wxWindows licence
5526e819
VS
8/////////////////////////////////////////////////////////////////////////////
9
3096bd2f 10#include "wx/wxprec.h"
5526e819
VS
11
12#include "wx/defs.h"
f6bcfd97 13#if wxUSE_HTML && wxUSE_STREAMS
5526e819 14
2b5f62a0 15#ifdef __BORLANDC__
5526e819
VS
16#pragma hdrstop
17#endif
18
19#ifndef WXPRECOMP
04dbb646
VZ
20 #include "wx/intl.h"
21 #include "wx/dc.h"
5526e819
VS
22#endif
23
69941f05
VS
24#include "wx/html/htmldefs.h"
25#include "wx/html/winpars.h"
26#include "wx/html/htmlwin.h"
b250d384 27#include "wx/fontmap.h"
f3c82859 28#include "wx/log.h"
3403ccd5 29#include "wx/settings.h"
3ec372c8 30#include "wx/uri.h"
5526e819
VS
31
32
33//-----------------------------------------------------------------------------
34// wxHtmlWinParser
35//-----------------------------------------------------------------------------
36
4f44ea36 37IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinParser, wxHtmlParser)
5526e819
VS
38
39wxList wxHtmlWinParser::m_Modules;
40
04db5c3f 41wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindow *wnd) : wxHtmlParser()
5526e819 42{
211dfedd
VS
43 m_tmpStrBuf = NULL;
44 m_tmpStrBufSize = 0;
5526e819
VS
45 m_Window = wnd;
46 m_Container = NULL;
47 m_DC = NULL;
48 m_CharHeight = m_CharWidth = 0;
d1da8872 49 m_UseLink = false;
2b5f62a0 50#if !wxUSE_UNICODE
b250d384 51 m_EncConv = NULL;
2b5f62a0
VZ
52 m_InputEnc = wxFONTENCODING_ISO8859_1;
53 m_OutputEnc = wxFONTENCODING_DEFAULT;
54#endif
b6d93b26 55 m_lastWordCell = NULL;
5526e819
VS
56
57 {
58 int i, j, k, l, m;
59 for (i = 0; i < 2; i++)
60 for (j = 0; j < 2; j++)
61 for (k = 0; k < 2; k++)
62 for (l = 0; l < 2; l++)
3c8c8da2 63 for (m = 0; m < 7; m++)
e3c7fd79 64 {
5526e819 65 m_FontsTable[i][j][k][l][m] = NULL;
f1ad10f3 66 m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
2b5f62a0 67#if !wxUSE_UNICODE
b250d384 68 m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
2b5f62a0 69#endif
f1ad10f3 70 }
4eecf115
VS
71
72 SetFonts(wxEmptyString, wxEmptyString, NULL);
5526e819
VS
73 }
74
75 // fill in wxHtmlParser's tables:
222ed1d6 76 wxList::compatibility_iterator node = m_Modules.GetFirst();
3c8c8da2 77 while (node)
4f9297b0
VS
78 {
79 wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node->GetData();
80 mod->FillHandlersTable(this);
81 node = node->GetNext();
5526e819
VS
82 }
83}
84
b250d384
VS
85wxHtmlWinParser::~wxHtmlWinParser()
86{
87 int i, j, k, l, m;
88
89 for (i = 0; i < 2; i++)
90 for (j = 0; j < 2; j++)
91 for (k = 0; k < 2; k++)
92 for (l = 0; l < 2; l++)
3c8c8da2 93 for (m = 0; m < 7; m++)
e3c7fd79 94 {
3c8c8da2 95 if (m_FontsTable[i][j][k][l][m] != NULL)
b250d384
VS
96 delete m_FontsTable[i][j][k][l][m];
97 }
2b5f62a0 98#if !wxUSE_UNICODE
211dfedd 99 delete m_EncConv;
2b5f62a0 100#endif
211dfedd 101 delete[] m_tmpStrBuf;
b250d384
VS
102}
103
5526e819
VS
104void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
105{
106 m_Modules.Append(module);
107}
108
f6bcfd97
BP
109void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
110{
111 m_Modules.DeleteObject(module);
112}
113
fbfb8bcc 114void wxHtmlWinParser::SetFonts(const wxString& normal_face, const wxString& fixed_face,
4eecf115 115 const int *sizes)
5526e819 116{
4eecf115
VS
117 static int default_sizes[7] =
118 {
119 wxHTML_FONT_SIZE_1,
d1da8872
WS
120 wxHTML_FONT_SIZE_2,
121 wxHTML_FONT_SIZE_3,
122 wxHTML_FONT_SIZE_4,
123 wxHTML_FONT_SIZE_5,
124 wxHTML_FONT_SIZE_6,
125 wxHTML_FONT_SIZE_7
4eecf115 126 };
d1da8872 127
4eecf115
VS
128 if (sizes == NULL) sizes = default_sizes;
129
c9f56e70
VS
130 int i, j, k, l, m;
131
132 for (i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
5526e819
VS
133 m_FontFaceFixed = fixed_face;
134 m_FontFaceNormal = normal_face;
3c8c8da2 135
2b5f62a0 136#if !wxUSE_UNICODE
b250d384 137 SetInputEncoding(m_InputEnc);
2b5f62a0 138#endif
c9f56e70
VS
139
140 for (i = 0; i < 2; i++)
141 for (j = 0; j < 2; j++)
142 for (k = 0; k < 2; k++)
143 for (l = 0; l < 2; l++)
144 for (m = 0; m < 7; m++) {
3c8c8da2 145 if (m_FontsTable[i][j][k][l][m] != NULL)
e3c7fd79 146 {
c9f56e70
VS
147 delete m_FontsTable[i][j][k][l][m];
148 m_FontsTable[i][j][k][l][m] = NULL;
149 }
150 }
5526e819
VS
151}
152
10e5c7ea
VS
153void wxHtmlWinParser::SetStandardFonts(int size,
154 const wxString& normal_face,
155 const wxString& fixed_face)
7acd3625 156{
10e5c7ea 157 wxFont defaultFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
d1da8872 158
7acd3625
RD
159 int f_sizes[7];
160 if (size == -1)
10e5c7ea 161 size = defaultFont.GetPointSize();
7acd3625
RD
162
163 f_sizes[0] = int(size * 0.6);
164 f_sizes[1] = int(size * 0.8);
165 f_sizes[2] = size;
166 f_sizes[3] = int(size * 1.2);
167 f_sizes[4] = int(size * 1.4);
168 f_sizes[5] = int(size * 1.6);
169 f_sizes[6] = int(size * 1.8);
10e5c7ea 170
d1da8872 171 wxString normal = normal_face.empty() ?
10e5c7ea 172 defaultFont.GetFaceName() : normal_face;
d1da8872 173
10e5c7ea 174 SetFonts(normal, fixed_face, f_sizes);
7acd3625
RD
175}
176
5526e819
VS
177void wxHtmlWinParser::InitParser(const wxString& source)
178{
179 wxHtmlParser::InitParser(source);
2b5f62a0 180 wxASSERT_MSG(m_DC != NULL, wxT("no DC assigned to wxHtmlWinParser!!"));
5526e819
VS
181
182 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
f2c2fa4d 183 m_FontSize = 3; //default one
5526e819 184 CreateCurrentFont(); // we're selecting default font into
2b5f62a0 185 m_DC->GetTextExtent( wxT("H"), &m_CharWidth, &m_CharHeight);
5526e819 186 /* NOTE : we're not using GetCharWidth/Height() because
0e8c8233 187 of differences under X and win
5526e819
VS
188 */
189
d1da8872 190 m_UseLink = false;
9548f380 191 m_Link = wxHtmlLinkInfo( wxEmptyString );
5526e819
VS
192 m_LinkColor.Set(0, 0, 0xFF);
193 m_ActualColor.Set(0, 0, 0);
efba2b89 194 m_Align = wxHTML_ALIGN_LEFT;
d1da8872 195 m_tmpLastWasSpace = false;
b6d93b26 196 m_lastWordCell = NULL;
5526e819
VS
197
198 OpenContainer();
5526e819 199 OpenContainer();
2b5f62a0 200
fa2f5d3b 201#if !wxUSE_UNICODE
2b5f62a0
VZ
202 wxString charset = ExtractCharsetInformation(source);
203 if (!charset.empty())
204 {
205 wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charset);
206 if (enc != wxFONTENCODING_SYSTEM)
207 SetInputEncoding(enc);
208 }
209#endif
210
4f9297b0 211 m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
44d0c580 212 wxColour windowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ;
eb6a4098 213 m_Container->InsertCell(
3403ccd5
RD
214 new wxHtmlColourCell(GetWindow() ?
215 GetWindow()->GetBackgroundColour() :
44d0c580 216 windowColour,
eb6a4098 217 wxHTML_CLR_BACKGROUND));
4f9297b0 218 m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
5526e819
VS
219}
220
5526e819
VS
221void wxHtmlWinParser::DoneParser()
222{
223 m_Container = NULL;
2b5f62a0
VZ
224#if !wxUSE_UNICODE
225 SetInputEncoding(wxFONTENCODING_ISO8859_1); // for next call
226#endif
5526e819
VS
227 wxHtmlParser::DoneParser();
228}
229
5526e819
VS
230wxObject* wxHtmlWinParser::GetProduct()
231{
232 wxHtmlContainerCell *top;
233
234 CloseContainer();
235 OpenContainer();
67cfebc2 236
5526e819 237 top = m_Container;
4f9297b0 238 while (top->GetParent()) top = top->GetParent();
ace0fab4
VS
239 top->RemoveExtraSpacing(true, true);
240
5526e819
VS
241 return top;
242}
243
0423bdc7 244wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
6cc4e6b8 245 const wxString& url) const
04db5c3f 246{
04db5c3f 247 if ( m_Window )
6cc4e6b8 248 {
6cc4e6b8
VS
249 wxString myurl(url);
250 wxHtmlOpeningStatus status;
251 for (;;)
252 {
4bfa3189
WS
253 wxString myfullurl(myurl);
254
4bfa3189 255 // consider url as absolute path first
7e496014
WS
256 wxURI current(myurl);
257 myfullurl = current.BuildUnescapedURI();
4bfa3189
WS
258
259 // if not absolute then ...
260 if( current.IsReference() )
261 {
262 wxString basepath = GetFS()->GetPath();
7e496014 263 wxURI base(basepath);
4bfa3189 264
7e496014 265 // ... try to apply base path if valid ...
4bfa3189
WS
266 if( !base.IsReference() )
267 {
268 wxURI path(myfullurl);
269 path.Resolve( base );
7e496014 270 myfullurl = path.BuildUnescapedURI();
4bfa3189
WS
271 }
272 else
273 {
274 // ... or force such addition if not included already
7e496014 275 if( !current.GetPath().Contains(base.GetPath()) )
4bfa3189
WS
276 {
277 basepath += myurl;
7e496014
WS
278 wxURI connected( basepath );
279 myfullurl = connected.BuildUnescapedURI();
4bfa3189
WS
280 }
281 }
282 }
4bfa3189 283
0423bdc7 284 wxString redirect;
4bfa3189 285 status = m_Window->OnOpeningURL(type, myfullurl, &redirect);
0423bdc7 286 if ( status != wxHTML_REDIRECT )
6cc4e6b8 287 break;
0423bdc7
VZ
288
289 myurl = redirect;
6cc4e6b8 290 }
0423bdc7 291
6cc4e6b8
VS
292 if ( status == wxHTML_BLOCK )
293 return NULL;
2c892c0b
VZ
294
295 return GetFS()->OpenFile(myurl);
6cc4e6b8 296 }
2c892c0b
VZ
297
298 return wxHtmlParser::OpenURL(type, url);
04db5c3f 299}
5526e819 300
211dfedd 301void wxHtmlWinParser::AddText(const wxChar* txt)
5526e819
VS
302{
303 wxHtmlCell *c;
e3c7fd79
VZ
304 size_t i = 0,
305 x,
306 lng = wxStrlen(txt);
211dfedd 307 register wxChar d;
5526e819 308 int templen = 0;
f23e92e7 309 wxChar nbsp = GetEntitiesParser()->GetCharForCode(160 /* nbsp */);
211dfedd
VS
310
311 if (lng+1 > m_tmpStrBufSize)
312 {
313 delete[] m_tmpStrBuf;
314 m_tmpStrBuf = new wxChar[lng+1];
315 m_tmpStrBufSize = lng+1;
316 }
317 wxChar *temp = m_tmpStrBuf;
3c8c8da2
VZ
318
319 if (m_tmpLastWasSpace)
4f9297b0 320 {
3c8c8da2
VZ
321 while ((i < lng) &&
322 ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) || (txt[i] == wxT(' ')) ||
211dfedd 323 (txt[i] == wxT('\t')))) i++;
5526e819
VS
324 }
325
3c8c8da2 326 while (i < lng)
4f9297b0 327 {
5526e819
VS
328 x = 0;
329 d = temp[templen++] = txt[i];
3c8c8da2 330 if ((d == wxT('\n')) || (d == wxT('\r')) || (d == wxT(' ')) || (d == wxT('\t')))
e3c7fd79 331 {
5526e819 332 i++, x++;
3c8c8da2 333 while ((i < lng) && ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) ||
211dfedd 334 (txt[i] == wxT(' ')) || (txt[i] == wxT('\t')))) i++, x++;
5526e819
VS
335 }
336 else i++;
337
3c8c8da2 338 if (x)
e3c7fd79 339 {
211dfedd 340 temp[templen-1] = wxT(' ');
5526e819
VS
341 temp[templen] = 0;
342 templen = 0;
2b5f62a0 343#if !wxUSE_UNICODE
3c8c8da2 344 if (m_EncConv)
daa616fc 345 m_EncConv->Convert(temp);
2b5f62a0 346#endif
88dcf47c 347 size_t len = wxStrlen(temp);
f23e92e7 348 for (size_t j = 0; j < len; j++)
88dcf47c
VS
349 if (temp[j] == nbsp)
350 temp[j] = wxT(' ');
351 c = new wxHtmlWordCell(temp, *(GetDC()));
3c8c8da2 352 if (m_UseLink)
daa616fc 353 c->SetLink(m_Link);
4f9297b0 354 m_Container->InsertCell(c);
b6d93b26
VS
355 ((wxHtmlWordCell*)c)->SetPreviousWord(m_lastWordCell);
356 m_lastWordCell = (wxHtmlWordCell*)c;
d1da8872 357 m_tmpLastWasSpace = true;
5526e819
VS
358 }
359 }
af035b26
VS
360
361 if (templen && (templen > 1 || temp[0] != wxT(' ')))
4f9297b0 362 {
5526e819 363 temp[templen] = 0;
2b5f62a0 364#if !wxUSE_UNICODE
3c8c8da2 365 if (m_EncConv)
daa616fc 366 m_EncConv->Convert(temp);
2b5f62a0 367#endif
88dcf47c 368 size_t len = wxStrlen(temp);
f23e92e7 369 for (size_t j = 0; j < len; j++)
88dcf47c
VS
370 if (temp[j] == nbsp)
371 temp[j] = wxT(' ');
372 c = new wxHtmlWordCell(temp, *(GetDC()));
211dfedd 373 if (m_UseLink)
daa616fc 374 c->SetLink(m_Link);
4f9297b0 375 m_Container->InsertCell(c);
b6d93b26
VS
376 ((wxHtmlWordCell*)c)->SetPreviousWord(m_lastWordCell);
377 m_lastWordCell = (wxHtmlWordCell*)c;
d1da8872 378 m_tmpLastWasSpace = false;
5526e819
VS
379 }
380}
381
382
383
384wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
385{
386 m_Container = new wxHtmlContainerCell(m_Container);
4f9297b0 387 m_Container->SetAlignHor(m_Align);
d1da8872 388 m_tmpLastWasSpace = true;
5526e819
VS
389 /* to avoid space being first character in paragraph */
390 return m_Container;
391}
392
393
394
395wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
396{
d1da8872 397 m_tmpLastWasSpace = true;
5526e819
VS
398 /* to avoid space being first character in paragraph */
399 return m_Container = c;
400}
401
402
403
404wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
405{
4f9297b0 406 m_Container = m_Container->GetParent();
5526e819
VS
407 return m_Container;
408}
409
410
f2c2fa4d
VS
411void wxHtmlWinParser::SetFontSize(int s)
412{
413 if (s < 1) s = 1;
414 else if (s > 7) s = 7;
415 m_FontSize = s;
416}
417
418
419
5526e819
VS
420wxFont* wxHtmlWinParser::CreateCurrentFont()
421{
422 int fb = GetFontBold(),
423 fi = GetFontItalic(),
424 fu = GetFontUnderlined(),
425 ff = GetFontFixed(),
f2c2fa4d 426 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
5526e819 427
f1ad10f3
VS
428 wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
429 wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
430 wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
2b5f62a0 431#if !wxUSE_UNICODE
b250d384 432 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
2b5f62a0 433#endif
f1ad10f3 434
2b5f62a0
VZ
435 if (*fontptr != NULL && (*faceptr != face
436#if !wxUSE_UNICODE
437 || *encptr != m_OutputEnc
438#endif
439 ))
4f9297b0 440 {
f1ad10f3
VS
441 delete *fontptr;
442 *fontptr = NULL;
443 }
444
3c8c8da2 445 if (*fontptr == NULL)
4f9297b0 446 {
f1ad10f3
VS
447 *faceptr = face;
448 *fontptr = new wxFont(
7a5e6267 449 (int) (m_FontsSizes[fs] * m_PixelScale),
f1ad10f3
VS
450 ff ? wxMODERN : wxSWISS,
451 fi ? wxITALIC : wxNORMAL,
452 fb ? wxBOLD : wxNORMAL,
d1da8872 453 fu ? true : false, face
2b5f62a0
VZ
454#if wxUSE_UNICODE
455 );
456#else
457 , m_OutputEnc);
458 *encptr = m_OutputEnc;
459#endif
5526e819 460 }
4f9297b0 461 m_DC->SetFont(**fontptr);
f1ad10f3 462 return (*fontptr);
5526e819
VS
463}
464
465
466
f2c2fa4d
VS
467void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
468{
3c8c8da2 469 m_Link = link;
f2c2fa4d
VS
470 m_UseLink = (link.GetHref() != wxEmptyString);
471}
472
473
3c8c8da2 474void wxHtmlWinParser::SetFontFace(const wxString& face)
b250d384 475{
3c8c8da2 476 if (GetFontFixed()) m_FontFaceFixed = face;
b250d384
VS
477 else m_FontFaceNormal = face;
478
2b5f62a0 479#if !wxUSE_UNICODE
b250d384
VS
480 if (m_InputEnc != wxFONTENCODING_DEFAULT)
481 SetInputEncoding(m_InputEnc);
2b5f62a0 482#endif
b250d384
VS
483}
484
485
486
2b5f62a0 487#if !wxUSE_UNICODE
b250d384
VS
488void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
489{
490 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
3c8c8da2 491 if (m_EncConv)
daa616fc 492 {
3c8c8da2 493 delete m_EncConv;
daa616fc
VS
494 m_EncConv = NULL;
495 }
b250d384
VS
496
497 if (enc == wxFONTENCODING_DEFAULT) return;
498
499 wxFontEncoding altfix, altnorm;
500 bool availfix, availnorm;
3c8c8da2
VZ
501
502 // exact match?
142b3bc2
VS
503 availnorm = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceNormal);
504 availfix = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceFixed);
3c8c8da2 505 if (availnorm && availfix)
b250d384 506 m_OutputEnc = enc;
3c8c8da2 507
b250d384 508 // alternatives?
d1da8872
WS
509 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, false) &&
510 wxFontMapper::Get()->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, false) &&
b250d384
VS
511 altnorm == altfix)
512 m_OutputEnc = altnorm;
3c8c8da2 513
b250d384
VS
514 // at least normal face?
515 else if (availnorm)
516 m_OutputEnc = enc;
d1da8872 517 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, false))
b250d384 518 m_OutputEnc = altnorm;
3c8c8da2 519
b250d384 520 else
c83e1237
SC
521 {
522#ifndef __WXMAC__
523 // okay, let convert to ISO_8859-1, available always
b250d384 524 m_OutputEnc = wxFONTENCODING_DEFAULT;
90548138 525#else
c83e1237 526 m_OutputEnc = wxLocale::GetSystemEncoding() ;
90548138 527#endif
c83e1237 528 }
3c8c8da2 529
b250d384 530 m_InputEnc = enc;
daa616fc
VS
531 if (m_OutputEnc == wxFONTENCODING_DEFAULT)
532 GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
533 else
534 GetEntitiesParser()->SetEncoding(m_OutputEnc);
3c8c8da2 535
b250d384
VS
536 if (m_InputEnc == m_OutputEnc) return;
537
538 m_EncConv = new wxEncodingConverter();
3c8c8da2 539 if (!m_EncConv->Init(m_InputEnc,
b250d384
VS
540 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
541 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
3c8c8da2 542 wxCONVERT_SUBSTITUTE))
b250d384 543 { // total failture :-(
3c8c8da2
VZ
544 wxLogError(_("Failed to display HTML document in %s encoding"),
545 wxFontMapper::GetEncodingName(enc).c_str());
b250d384
VS
546 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
547 delete m_EncConv;
548 m_EncConv = NULL;
549 }
550}
2b5f62a0 551#endif
b250d384
VS
552
553
f2c2fa4d 554
5526e819
VS
555
556//-----------------------------------------------------------------------------
557// wxHtmlWinTagHandler
558//-----------------------------------------------------------------------------
559
560IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
561
5526e819
VS
562//-----------------------------------------------------------------------------
563// wxHtmlTagsModule
564//-----------------------------------------------------------------------------
565
d6a6d666
VS
566// NB: This is *NOT* winpars.cpp's initialization and shutdown code!!
567// This module is an ancestor for tag handlers modules defined
568// in m_*.cpp files with TAGS_MODULE_BEGIN...TAGS_MODULE_END construct.
569//
570// Do not add any winpars.cpp shutdown or initialization code to it,
571// create a new module instead!
5526e819
VS
572
573IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
574
5526e819
VS
575bool wxHtmlTagsModule::OnInit()
576{
577 wxHtmlWinParser::AddModule(this);
d1da8872 578 return true;
5526e819
VS
579}
580
5526e819
VS
581void wxHtmlTagsModule::OnExit()
582{
f6bcfd97 583 wxHtmlWinParser::RemoveModule(this);
5526e819 584}
d6a6d666 585
223d09f6 586#endif
5526e819 587