2 * This file is part of the DOM implementation for KDE.
4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5 * (C) 2006-2007 Allan Sandfeld Jensen (kde@carewolf.com)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
31 // priority of tags. Closing tags of higher priority close tags of lower
33 // Update this list, whenever you change htmltags.*
35 // 0 elements with forbidden close tag and text. They don't get pushed
37 // 1 formatting elements
38 // 3 form nobr noscript
39 // 5 phrasing elements
42 // 8 tbody thead tfoot
44 // 10 body frameset head noembed noframes
47 const unsigned short KDE_NO_EXPORT
DOM::tagPriorityArray
[] = {
160 const tagStatus
DOM::endTagArray
[] = {
162 REQUIRED
, // ID_A == 1
164 REQUIRED
, // ID_ACRONYM
165 REQUIRED
, // ID_ADDRESS
166 REQUIRED
, // ID_APPLET
167 FORBIDDEN
, // ID_AREA
168 REQUIRED
, // ID_AUDIO
170 FORBIDDEN
, // ID_BASE
171 FORBIDDEN
, // ID_BASEFONT
174 REQUIRED
, // ID_BLOCKQUOTE
177 REQUIRED
, // ID_BUTTON
178 REQUIRED
, // ID_CANVAS
179 REQUIRED
, // ID_CAPTION
180 REQUIRED
, // ID_CENTER
184 OPTIONAL
, // ID_COLGROUP
193 REQUIRED
, // ID_EMBED
194 REQUIRED
, // ID_FIELDSET
197 FORBIDDEN
, // ID_FRAME
198 REQUIRED
, // ID_FRAMESET
209 REQUIRED
, // ID_IFRAME
210 REQUIRED
, // ID_ILAYER
211 FORBIDDEN
, // ID_IMAGE
213 FORBIDDEN
, // ID_INPUT
215 FORBIDDEN
, // ID_ISINDEX
217 REQUIRED
, // ID_KEYGEN
218 REQUIRED
, // ID_LABEL
219 REQUIRED
, // ID_LAYER
220 REQUIRED
, // ID_LEGEND
222 FORBIDDEN
, // ID_LINK
223 REQUIRED
, // ID_LISTING
225 REQUIRED
, // ID_MARQUEE
227 FORBIDDEN
, // ID_META
229 REQUIRED
, // ID_NOEMBED
230 REQUIRED
, // ID_NOFRAMES
231 REQUIRED
, // ID_NOSCRIPT
232 REQUIRED
, // ID_NOLAYER
233 REQUIRED
, // ID_OBJECT
235 REQUIRED
, // ID_OPTGROUP
236 OPTIONAL
, // ID_OPTION
238 FORBIDDEN
, // ID_PARAM
239 REQUIRED
, // ID_PLAINTEXT
244 REQUIRED
, // ID_SCRIPT
245 REQUIRED
, // ID_SELECT
246 REQUIRED
, // ID_SMALL
247 FORBIDDEN
, // ID_SOURCE
249 REQUIRED
, // ID_STRIKE
250 REQUIRED
, // ID_STRONG
251 REQUIRED
, // ID_STYLE
254 REQUIRED
, // ID_TABLE
255 OPTIONAL
, // ID_TBODY
257 REQUIRED
, // ID_TEXTAREA
258 OPTIONAL
, // ID_TFOOT
260 OPTIONAL
, // ID_THEAD
261 REQUIRED
, // ID_TITLE
267 REQUIRED
, // ID_VIDEO
273 // This a combination of HTML4.dtd XHTML11.dtd and various extensions
274 // and deprecated elements
275 static const ushort tag_list_inline
[] = {
287 ID_BASEFONT
, // legacy
326 ID_ILAYER
, // deprecated
335 static const ushort tag_list_quirk_inline
[] = {
336 ID_NOSCRIPT
, // block, but parsed as inline in Mozilla and MSIE
340 static const ushort tag_list_block
[] = {
341 ID_TEXT
, // white-space is allowed
372 ID_ISINDEX
, // legacy
374 ID_LAYER
, // deprecated
375 ID_MARQUEE
, // extension
379 // block elements allowed for quirky error recovery
380 static const ushort tag_list_quirk_block
[] = {
387 static const ushort tag_list_select
[] = {
396 static const ushort tag_list_frame
[] = {
404 static const ushort tag_list_head
[] = {
416 static bool check_array(ushort child
, const ushort
*tagList
)
419 while(tagList
[i
] != 0)
421 if(tagList
[i
] == child
) return true;
428 static bool check_block(ushort childID
, bool strict
)
430 return check_array(childID
, tag_list_block
) ||
431 (!strict
&& check_array(childID
, tag_list_quirk_block
));
434 static bool check_inline(ushort childID
, bool strict
)
436 return check_array(childID
, tag_list_inline
) ||
437 (!strict
&& check_array(childID
, tag_list_quirk_inline
));
440 static bool check_flow(ushort childID
, bool strict
)
442 return check_block(childID
, strict
) || check_inline(childID
, strict
);
445 bool DOM::checkChild(ushort tagID
, ushort childID
, bool strict
)
447 //kDebug( 6030 ) << "checkChild: " << tagID << "/" << childID;
449 if (childID
== ID_COMMENT
) return true;
451 // Treat custom elements the same as <span>.
452 if (tagID
> ID_LAST_TAG
)
454 if (childID
> ID_LAST_TAG
)
487 return check_inline(childID
, strict
) || check_block(childID
, strict
);
490 return check_inline(childID
, strict
) ||
491 (!strict
&& childID
== ID_TABLE
);
499 return check_inline(childID
, strict
) ||
500 (!strict
&& check_block(childID
, true) && (childID
< ID_H1
|| childID
> ID_H6
));
519 // BODY: %block | SCRIPT (but even strict sites expect %flow)
520 return check_flow(childID
, strict
);
522 // ADDRESS: %inline *
523 return check_inline(childID
, strict
) ||
524 (!strict
&& childID
== ID_P
);
527 return check_inline(childID
, strict
) ||
528 (!strict
&& check_block(childID
, true) && childID
!= ID_DL
);
548 return check_flow(childID
, strict
);
550 // MAP: ( %block | AREA ) (but "prose" in HTML5)
551 return check_flow(childID
, true) || childID
== ID_AREA
||
552 (!strict
&& childID
== ID_SCRIPT
);
556 // OBJECT: %flow | PARAM *
557 return check_flow(childID
, true) || childID
== ID_PARAM
;
560 return check_flow(childID
, true) || childID
== ID_SOURCE
;
566 return check_flow(childID
, true);
569 return (childID
== ID_DT
|| childID
== ID_DD
|| check_flow(childID
, strict
));
575 // For DIR and MENU, the DTD says - %block, but it contradicts spec language..
576 return (childID
== ID_LI
|| check_flow(childID
, strict
));
578 // FORM: %flow * - FORM
579 return check_flow(childID
, strict
);
581 // LABEL: %inline * - LABEL
582 return check_inline(childID
, strict
) ||
583 (!strict
&& check_block(childID
, true));
585 // KEYGEN does not really allow any children
586 // from outside, just need this to be able
587 // to add the keylengths ourself
588 // Yes, consider it a hack (Dirk)
591 return check_array(childID
, tag_list_select
);
593 // OPTGROUP: OPTION +
594 if(childID
== ID_OPTION
) return true;
602 if(childID
== ID_TEXT
) return true;
605 // FIELDSET: ( TEXT , LEGEND , %flow * )
606 if(childID
== ID_TEXT
) return true;
607 if(childID
== ID_LEGEND
) return true;
608 return check_flow(childID
, strict
);
610 // BUTTON: %flow * - _8
611 return check_flow(childID
, strict
);
613 // TABLE: ( CAPTION ? , ( COL * | COLGROUP * ) , THEAD ? , TFOOT ? , TBODY + )
632 if(childID
== ID_TR
|| childID
== ID_SCRIPT
) return true;
636 if(childID
== ID_COL
) return true;
640 return (childID
== ID_TH
|| childID
== ID_TD
|| childID
== ID_SCRIPT
);
643 return check_array(childID
, tag_list_frame
);
646 return check_array(childID
, tag_list_head
);
648 // HTML: ( HEAD , COMMENT, ( BODY | ( FRAMESET & NOFRAMES ? ) ) )
661 kDebug( 6030 ) << "unhandled tag in dtd.cpp:checkChild(): tagID=" << tagID
<< "!";
666 void DOM::addForbidden(int tagId
, ushort
*forbiddenTags
)
671 // we allow nested anchors. The innermost one wil be taken...
672 //forbiddenTags[ID_A]++;
675 forbiddenTags
[ID_PRE
]++;
676 forbiddenTags
[ID_LISTING
]++;
682 //forbiddenTags[ID_IMAGE]++;
683 //forbiddenTags[ID_IMG]++;
684 forbiddenTags
[ID_OBJECT
]++;
685 forbiddenTags
[ID_EMBED
]++;
686 forbiddenTags
[ID_APPLET
]++;
687 // why forbid them. We can deal with them in PRE
688 //forbiddenTags[ID_BIG]++;
689 //forbiddenTags[ID_SMALL]++;
690 //forbiddenTags[ID_SUB]++;
691 //forbiddenTags[ID_SUP]++;
692 forbiddenTags
[ID_BASEFONT
]++;
695 forbiddenTags
[ID_LABEL
]++;
698 forbiddenTags
[ID_A
]++;
699 forbiddenTags
[ID_INPUT
]++;
700 forbiddenTags
[ID_SELECT
]++;
701 forbiddenTags
[ID_TEXTAREA
]++;
702 forbiddenTags
[ID_LABEL
]++;
703 forbiddenTags
[ID_BUTTON
]++;
704 forbiddenTags
[ID_FORM
]++;
705 forbiddenTags
[ID_ISINDEX
]++;
706 forbiddenTags
[ID_FIELDSET
]++;
707 forbiddenTags
[ID_IFRAME
]++;
714 void DOM::removeForbidden(int tagId
, ushort
*forbiddenTags
)
719 //forbiddenTags[ID_A]--;
722 forbiddenTags
[ID_PRE
]--;
723 forbiddenTags
[ID_LISTING
]--;
729 //forbiddenTags[ID_IMAGE]--;
730 //forbiddenTags[ID_IMG]--;
731 forbiddenTags
[ID_OBJECT
]--;
732 forbiddenTags
[ID_EMBED
]--;
733 forbiddenTags
[ID_APPLET
]--;
734 //forbiddenTags[ID_BIG]--;
735 //forbiddenTags[ID_SMALL]--;
736 //forbiddenTags[ID_SUB]--;
737 //forbiddenTags[ID_SUP]--;
738 forbiddenTags
[ID_BASEFONT
]--;
741 forbiddenTags
[ID_LABEL
]--;
744 forbiddenTags
[ID_A
]--;
745 forbiddenTags
[ID_INPUT
]--;
746 forbiddenTags
[ID_SELECT
]--;
747 forbiddenTags
[ID_TEXTAREA
]--;
748 forbiddenTags
[ID_LABEL
]--;
749 forbiddenTags
[ID_BUTTON
]--;
750 forbiddenTags
[ID_FORM
]--;
751 forbiddenTags
[ID_ISINDEX
]--;
752 forbiddenTags
[ID_FIELDSET
]--;
753 forbiddenTags
[ID_IFRAME
]--;