mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-18 15:21:34 +01:00
864 lines
29 KiB
ObjectPascal
864 lines
29 KiB
ObjectPascal
{
|
|
$Id: htmldefs.pp,v 1.2 2006/01/03 23:33:23 lukvdl Exp $
|
|
This file is part of the Free Component Library
|
|
|
|
HTML definitions and utility functions
|
|
Copyright (c) 2000-2002 by
|
|
Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
|
|
unit HTMLDefs;
|
|
|
|
{$MODE objfpc}
|
|
{$H+}
|
|
|
|
interface
|
|
|
|
type
|
|
|
|
THTMLCData = string;
|
|
THTMLID = string;
|
|
THTMLName = string;
|
|
THTMLIDRef = string;
|
|
THTMLIDRefs = string;
|
|
THTMLNumber = longint;
|
|
|
|
THTMLText = THTMLCData;
|
|
THTMLCharsets = THTMLCData;
|
|
THTMLContentTypes = THTMLCData;
|
|
THTMLURI = string;
|
|
THTMLCharacter = char;
|
|
|
|
THTMLDir = (dirEmpty,dirLeftToRight,dirRightToLeft);
|
|
THTMLalign = (alEmpty,alleft,alcenter,alright,aljustify,alchar);
|
|
THTMLvalign = (vaEmpty,vatop,vamiddle,vabottom,vabaseline);
|
|
THTMLframe = (frEmpty,frvoid,frabove,frbelow,frhsides,frvsides,frlefthandsise,frrighthandside,frbox,frborder);
|
|
THTMLrules = (ruEmpty,runone,rugroups,rurows,rucols,ruall);
|
|
THTMLvaluetype = (vtEmpty,vtdata,vtref,vtobject);
|
|
THTMLshape = (shEmpty,shdefault,shrect,shcircle,shpoly);
|
|
THTMLinputtype = (itEmpty,ittext,itpassword,itcheckbox,itradio,itsubmit,itreset,itfile,ithidden,itimage,itbutton);
|
|
THTMLbuttontype = (btEmpty,btsubmit,btreset,btbutton);
|
|
|
|
THTMLColor = (
|
|
clHTMLBlack, clHTMLSilver, clHTMLGray, clHTMLWhite, clHTMLMaroon,
|
|
// #000000 #C0C0C0 #808080 #FFFFFF #800000
|
|
clHTMLRed, clHTMLPurple, clHTMLFuchsia,clHTMLGreen, clHTMLLime, clHTMLOlive,
|
|
// #FF0000 #800080 #FF00FF #008000 #00FF00 #808000
|
|
clHTMLYellow,clHTMLNavy, clHTMLBlue, clHTMLTeal, clHTMLAqua
|
|
// #FFFF00 #000080 #0000FF #008080 #00FFFF
|
|
);
|
|
|
|
THTMLAttributeTag = (
|
|
atabbr, atalink, atacceptcharset, ataccept, ataccesskey, ataction, atalign, atalt, atarchive,
|
|
ataxis, atbackground, atbgcolor, atborder, atcellpadding, atcellspacing, atchar, atcharoff, atcharset,
|
|
atchecked, atcite, atclass, atclassid, atclear, atcode, atcodebase, atcodetype, atcolor, atcols,
|
|
atcolspan, atcompact, atcontent, atcoords, atdata, atdatetime, atdeclare,atdefer,
|
|
atdir, atdisabled, atenctype, atface, atfor, atframe, atframeborder, atheaders,
|
|
atheight, athref, athreflang, athspace, athttpequiv, atid, atismap, atlabel, atlang, atlink,
|
|
atlongdesc, atmarginheight, atmarginwidth, atmaxlength, atmedia, atmethod,
|
|
atmultiple, atname, atnohref, atnoresize, atnoshade, atnowrap, atobject, atonblur, atonchange, atonclick,
|
|
atondblclick, atonfocus, atonkeydown, atonkeypress, atonkeyup, atonload,
|
|
atonmousedown, atonmousemove, atonmouseout, atonmouseover, atonmouseup,
|
|
atonreset, atonselect, atonsubmit, atonunload, atprofile, atprompt, atreadonly,
|
|
atrel, atrev, atrows, atrowspan, atrules, atscheme, atscope, atscrolling,
|
|
atselected, atshape, atsize, atspan, atsrc, atstandby, atstart, atstyle, atsummary,
|
|
attabindex, attarget, attext, attitle, attype, atusemap, atvalign, atvalue,
|
|
atvaluetype, atversion, atvlink, atvspace, atwidth
|
|
);
|
|
THTMLAttributeSet = set of THTMLAttributeTag;
|
|
|
|
THTMLElementTag = (
|
|
eta, etabbr, etacronym, etaddress, etapplet, etarea, etb, etbase,
|
|
etbasefont, etbdo, etbig, etblockquote, etbody, etbr, etbutton,
|
|
etcaption, etcenter, etcite, etcode, etcol, etcolgroup, etdd, etdel,
|
|
etdfn, etdir, etdiv, etdl, etdt, etem, etfieldset, etfont, etform,
|
|
etframe, etframeset, eth1, eth2, eth3, eth4, eth5, eth6, ethead, ethr,
|
|
ethtml, eti, etiframe, etimg, etinput, etins, etisindex, etkbd, etlabel,
|
|
etlegend, etli, etlink, etmap, etmenu, etmeta, etnoframes, etnoscript,
|
|
etobject, etol, etoptgroup, etoption, etp, etparam, etpre, etq, ets,
|
|
etsamp, etscript, etselect, etsmall, etspan, etstrike, etstrong,
|
|
etstyle, etsub, etsup, ettable, ettbody, ettd, ettextarea, ettfoot,
|
|
etth, etthead, ettitle, ettr, ettt, etu, etul, etvar,
|
|
etText, etUnknown
|
|
);
|
|
THTMLElementTagSet = set of THTMLElementTag;
|
|
|
|
THTMLElementFlag = (
|
|
efSubelementContent, // may have subelements
|
|
efPCDATAContent, // may have PCDATA content
|
|
efPreserveWhitespace, // preserve all whitespace
|
|
efDeprecated, // can be dropped in future versions
|
|
efNoChecks, // Checks (attributes,subtags,...) can only be implemented in descendants
|
|
efEndTagOptional
|
|
);
|
|
THTMLElementFlags = set of THTMLElementFlag;
|
|
|
|
PHTMLElementProps = ^THTMLElementProps;
|
|
THTMLElementProps = record
|
|
Name: String;
|
|
Flags: THTMLElementFlags;
|
|
Attributes: THTMLAttributeSet;
|
|
end;
|
|
|
|
|
|
const
|
|
|
|
BooleanAttributes = [atchecked,atdeclare,atdefer,atdisabled,atnohref,atnoresize,
|
|
atmultiple,atreadonly,atselected];
|
|
|
|
DeprecatedAttributes = [atalink, atbackground, atbgcolor, atclear, atcode, atcolor,
|
|
atcompact, atface, athspace, atlink, atnoshade, atnowrap, atobject, atprompt,
|
|
atstart, attext, atvlink, atversion, atvspace];
|
|
|
|
efSubcontent = [efSubelementContent, efPCDATAContent];
|
|
|
|
atsi18n = [atlang, atdir];
|
|
atscoreattrs = [atid,atclass,atstyle,attitle];
|
|
atsevents = [atonclick,atondblclick,atonmousedown,atonmouseup,atonmouseover,
|
|
atonmousemove,atonmouseout,atonkeypress,atonkeydown,atonkeyup];
|
|
atsattrs = atsevents + atscoreattrs + atsi18n;
|
|
atscellhalign = [atalign, atchar, atcharoff];
|
|
|
|
{ etsStructured := [];
|
|
etsDivisions := [];
|
|
etsLists := [];
|
|
etsLinks := [];
|
|
etsObjects := [etImg, etObject, etApplet, etMap, etArea];
|
|
etsForms := [etForm];
|
|
|
|
etsText = etsStructured + etsDivisions + etsLists + etsLinks + etsObjects +
|
|
etsForms +
|
|
etTable + etText + etScript + ; }
|
|
|
|
HTMLElementProps: array[THTMLElementTag] of THTMLElementProps = (
|
|
(Name: 'a'; Flags: efSubcontent;
|
|
Attributes: atsattrs+[atcharset,attype,atname,athref,athreflang,atrel,atrev,
|
|
ataccesskey,atshape,atcoords,attabindex,atonfocus,atonblur]),
|
|
|
|
(Name: 'abbr'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'acronym'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'address'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'applet'; Flags: efSubcontent+[efDeprecated];
|
|
Attributes: atscoreattrs+[atcodebase,atarchive,atalt,atname,atwidth,atheight]),
|
|
|
|
(Name: 'area'; Flags: [];
|
|
Attributes: atsattrs+[atshape,atcoords,athref,atnohref,atalt,attabindex,
|
|
ataccesskey,atonfocus,atonblur]),
|
|
|
|
(Name: 'b'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'base'; Flags: []; Attributes: [athref]),
|
|
|
|
(Name: 'basefont'; Flags: [efDeprecated]; Attributes: [atid]),
|
|
|
|
(Name: 'bdo'; Flags: efSubcontent; Attributes: atscoreattrs+[atlang,atdir]),
|
|
|
|
(Name: 'big'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'blockquote';Flags: [efSubelementContent]; Attributes: atsattrs+[atcite]),
|
|
|
|
(Name: 'body'; Flags: [efSubelementContent];
|
|
Attributes: atsAttrs+[atonload, atonunload]),
|
|
|
|
(Name: 'br'; Flags: []; Attributes: atscoreattrs),
|
|
|
|
(Name: 'button'; Flags: efSubcontent;
|
|
Attributes: atsattrs+[atname,atvalue,attype,atdisabled,attabindex,
|
|
ataccesskey,atonfocus,atonblur]),
|
|
|
|
(Name: 'caption'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'center'; Flags: [efSubelementContent,efDeprecated]; Attributes: []),
|
|
|
|
(Name: 'cite'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'code'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'col'; Flags: [];
|
|
Attributes: atsattrs+atscellhalign+[atvalign,atspan,atwidth]),
|
|
|
|
(Name: 'colgroup'; Flags: [efSubelementContent, efEndTagOptional];
|
|
Attributes: atsattrs+atscellhalign+[atvalign,atspan,atwidth]),
|
|
|
|
(Name: 'dd'; Flags: efSubcontent+[efEndTagOptional]; Attributes: atsattrs),
|
|
|
|
(Name: 'del'; Flags: [efSubelementContent]; Attributes: atsattrs+[atcite,atdatetime]),
|
|
|
|
(Name: 'dfn'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'dir'; Flags: [efSubelementContent,efDeprecated]; Attributes: atsattrs),
|
|
|
|
(Name: 'div'; Flags: efSubContent; Attributes: atsattrs),
|
|
|
|
(Name: 'dl'; Flags: [efSubelementContent]; Attributes: atsattrs),
|
|
|
|
(Name: 'dt'; Flags: [efPCDataContent, efEndTagOptional]; Attributes: atsattrs),
|
|
|
|
(Name: 'em'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'fieldset'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'font'; Flags: efSubcontent+[efDeprecated]; Attributes: atscoreattrs+atsi18n),
|
|
|
|
(Name: 'form'; Flags: [efSubelementContent];
|
|
Attributes: atsattrs+[ataction,atmethod,atenctype,atonsubmit,atonreset,atacceptcharset]),
|
|
|
|
(Name: 'frame'; Flags: [];
|
|
Attributes: atscoreattrs+[atlongdesc,atname,atsrc,atframeborder,
|
|
atmarginwidth,atmarginheight,atnoresize,atscrolling]),
|
|
|
|
(Name: 'frameset'; Flags: efSubcontent;
|
|
Attributes: atsCoreattrs+[atrows,atcols,atonload,atonunload]),
|
|
|
|
(Name: 'h1'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'h2'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'h3'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'h4'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'h5'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'h6'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'head'; Flags: [efSubelementContent]; Attributes: atsi18n+[atprofile]),
|
|
|
|
(Name: 'hr'; Flags: []; Attributes: atscoreattrs+atsevents),
|
|
|
|
(Name: 'html'; Flags: [efSubelementContent]; Attributes: atsi18n),
|
|
|
|
(Name: 'i'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'iframe'; Flags: [efSubelementContent];
|
|
Attributes: atscoreattrs+[atlongdesc,atname,atsrc,atframeborder,atmarginwidth,
|
|
atmarginheight,atscrolling,atalign,atheight,atwidth]),
|
|
|
|
(Name: 'img'; Flags: [];
|
|
Attributes: atsattrs+[atsrc,atalt,atlongdesc,atheight,atwidth,atusemap,atismap]),
|
|
|
|
(Name: 'input'; Flags: [];
|
|
Attributes: atsattrs+[attype,atname,atvalue,atchecked,atdisabled,
|
|
atreadonly,atsize,atmaxlength,atsrc,atalt,atusemap,attabindex,
|
|
ataccesskey,atonfocus,atonblur,atonselect,atonchange,ataccept]),
|
|
|
|
(Name: 'ins'; Flags: [efSubelementContent]; Attributes: atsattrs+[atcite,atdatetime]),
|
|
|
|
(Name: 'isindex'; Flags: [efDeprecated]; Attributes: atscoreattrs+atsi18n),
|
|
|
|
(Name: 'kbd'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'label'; Flags: efSubcontent;
|
|
Attributes: atsattrs+[atfor,ataccesskey,atonfocus,atonblur]),
|
|
|
|
(Name: 'legend'; Flags: efSubcontent; Attributes: atsattrs+[ataccesskey]),
|
|
|
|
(Name: 'li'; Flags: efSubcontent+[efEndTagOptional]; Attributes: atsattrs),
|
|
|
|
(Name: 'link'; Flags: [];
|
|
Attributes: atsattrs+[atcharset,athref,athreflang,attype,atrel,atrev,atmedia]),
|
|
|
|
(Name: 'map'; Flags: [efSubelementContent]; Attributes: atsattrs+[atname]),
|
|
|
|
(Name: 'menu'; Flags: [efSubelementContent,efDeprecated]; Attributes: atsattrs),
|
|
|
|
(Name: 'meta'; Flags: []; Attributes: atsi18n+[athttpequiv,atname,atcontent,atscheme]),
|
|
|
|
(Name: 'noframes'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'noscript'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'object'; Flags: efSubcontent;
|
|
Attributes: atsattrs+[atdeclare,atclassid,atcodebase,atdata,attype,atcodetype,
|
|
atarchive,atstandby,atheight,atwidth,atusemap,atname,attabindex]),
|
|
|
|
(Name: 'ol'; Flags: [efSubelementContent]; Attributes: atsattrs),
|
|
|
|
(Name: 'optgroup'; Flags: efSubcontent; Attributes: atsattrs+[atdisabled,atlabel]),
|
|
|
|
(Name: 'option'; Flags: efSubcontent+[efEndTagOptional];
|
|
Attributes: atsattrs+[atselected,atdisabled,atlabel,atvalue]),
|
|
|
|
(Name: 'p'; Flags: efSubcontent+[efEndTagOptional]; Attributes: atsattrs),
|
|
|
|
(Name: 'param'; Flags: []; Attributes: [atid,atname,atvalue,atvaluetype,attype]),
|
|
|
|
(Name: 'pre'; Flags: efSubcontent + [efPreserveWhitespace]; Attributes: atsattrs),
|
|
|
|
(Name: 'q'; Flags: efSubcontent; Attributes: atsattrs+[atcite]),
|
|
|
|
(Name: 's'; Flags: efSubcontent+[efDeprecated]; Attributes: atsattrs),
|
|
|
|
(Name: 'samp'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'script'; Flags: [efPCDATAContent]; Attributes: [atcharset,attype,atsrc,atdefer]),
|
|
|
|
(Name: 'select'; Flags: [efSubelementContent];
|
|
Attributes: atsattrs+[atname,atsize,atmultiple,atdisabled,attabindex,atonfocus,
|
|
atonblur,atonchange]),
|
|
|
|
(Name: 'small'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'span'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'strike'; Flags: efSubcontent+[efDeprecated]; Attributes: atsattrs),
|
|
|
|
(Name: 'strong'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'style'; Flags: [efPCDATAContent];
|
|
Attributes: atsi18n+[attype,atmedia,attitle]),
|
|
|
|
(Name: 'sub'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'sup'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'table'; Flags: [efSubelementContent];
|
|
Attributes: atsattrs+[atsummary,atwidth,atborder,atframe,atrules,atcellspacing,atcellpadding]),
|
|
|
|
(Name: 'tbody'; Flags: [efSubelementContent]; Attributes: atsattrs+atscellhalign+[atvalign]),
|
|
|
|
(Name: 'td'; Flags: efSubcontent+[efEndTagOptional];
|
|
Attributes: atsattrs+atscellhalign+[atvalign,atabbr,ataxis,atheaders,atscope,atrowspan,atcolspan]),
|
|
|
|
(Name: 'textarea'; Flags: [efPCDATAContent];
|
|
Attributes: atsattrs+[atname,atrows,atcols,atdisabled,atreadonly,attabindex,
|
|
ataccesskey,atonfocus,atonblur,atonselect,atonchange]),
|
|
|
|
(Name: 'tfoot'; Flags: [efSubelementContent,efEndTagOptional]; Attributes: atsattrs+atscellhalign+[atvalign]),
|
|
|
|
(Name: 'th'; Flags: efSubcontent+[efEndTagOptional];
|
|
Attributes: atsattrs+atscellhalign+[atvalign,atabbr,ataxis,atheaders,atscope,atrowspan,atcolspan]),
|
|
|
|
(Name: 'thead'; Flags: [efSubelementContent, efEndTagOptional]; Attributes: atsattrs+atscellhalign+[atvalign]),
|
|
|
|
(Name: 'title'; Flags: efSubcontent; Attributes: atsi18n),
|
|
|
|
(Name: 'tr'; Flags: [efSubelementContent, efEndTagOptional];
|
|
Attributes: atsattrs+atscellhalign+[atvalign]),
|
|
|
|
(Name: 'tt'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'u'; Flags: efSubcontent+[efDeprecated]; Attributes: atsattrs),
|
|
|
|
(Name: 'ul'; Flags: [efSubelementContent]; Attributes: atsattrs),
|
|
|
|
(Name: 'var'; Flags: efSubcontent; Attributes: atsattrs),
|
|
|
|
(Name: 'text'; Flags: efSubcontent; Attributes: []),
|
|
|
|
(Name: 'unknown'; Flags: efSubcontent+[efNoChecks]; Attributes: [])
|
|
|
|
);
|
|
|
|
HTMLAttributeTag : array [THTMLAttributeTag] of String = (
|
|
'abbr', 'alink', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alt', 'archive',
|
|
'axis', 'background', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'char', 'charoff', 'charset',
|
|
'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols',
|
|
'colspan', 'compact', 'content', 'coords', 'data', 'datetime', 'declare', 'defer',
|
|
'dir', 'disabled', 'enctype', 'face', 'for', 'frame', 'frameborder', 'headers',
|
|
'height', 'href', 'hreflang', 'hspace', 'http-equiv', 'id', 'ismap', 'label', 'lang', 'link',
|
|
'longdesc', 'marginheight', 'marginwidth', 'maxlength', 'media', 'method',
|
|
'multiple', 'name', 'nohref', 'noresize', 'noshade', 'nowrap', 'object', 'onblur', 'onchange', 'onclick',
|
|
'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload',
|
|
'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup',
|
|
'onreset', 'onselect', 'onsubmit', 'onunload', 'profile', 'prompt', 'readonly',
|
|
'rel', 'rev', 'rows', 'rowspan', 'rules', 'scheme', 'scope', 'scrolling',
|
|
'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
|
|
'tabindex', 'target', 'text', 'title', 'type', 'usemap', 'valign', 'value',
|
|
'valuetype', 'version', 'vlink', 'vspace', 'width');
|
|
|
|
HTMLColor : array [THTMLColor] of string =
|
|
('Black', 'Silver', 'Gray', 'White', 'Maroon', 'Red', 'Purple', 'Fuchsia',
|
|
'Green', 'Lime', 'Olive', 'Yellow', 'Navy', 'Blue', 'Teal', 'Aqua');
|
|
HTMLDir : array [THTMLDir] of string = ('','LTR','RTL');
|
|
HTMLAlign : array [THTMLalign] of string = ('','left','center','right','justify','char');
|
|
HTMLvalign : array [THTMLvalign] of string = ('','top','middle','bottom','baseline');
|
|
HTMLframe : array [THTMLframe] of string =
|
|
('','void','above','below','hsides','vsides','lhs','rhs','box','border');
|
|
HTMLrules : array [THTMLrules] of string = ('','none','groups','rows','cols','all');
|
|
HTMLvaluetype : array [THTMLvaluetype] of string = ('','data','ref','object');
|
|
HTMLshape : array [THTMLshape] of string = ('','default','rect','circle','poly');
|
|
HTMLinputtype : array [THTMLinputtype] of string = ('','text','password','checkbox',
|
|
'radio','submit','reset','file','hidden','image','button');
|
|
HTMLbuttontype : array [THTMLbuttontype] of string = ('','submit','reset','button');
|
|
|
|
function ResolveHTMLEntityReference(const Name: WideString;
|
|
var Entity: WideChar): Boolean;
|
|
|
|
function IsAutoClose(NewTag, OldTag: THTMLElementTag): Boolean;
|
|
|
|
|
|
implementation
|
|
|
|
uses SysUtils;
|
|
|
|
{ Define which elements auto-close other elements, modelled after libxml2.
|
|
This is an array of variable-length lists, each terminated by etUnknown.
|
|
Indices to first element of each list are provided by AutoCloseIndex array,
|
|
which *must* be updated after any change. }
|
|
const
|
|
AutoCloseTab: array[0..277] of THTMLElementTag = (
|
|
|
|
etform, etform, etp, ethr, eth1, eth2, eth3, eth4, eth5, eth6,
|
|
etdl, etul, etol, etmenu, etdir, etaddress, etpre,
|
|
ethead, etUnknown,
|
|
ethead, etp, etUnknown,
|
|
ettitle, etp, etUnknown,
|
|
etbody, ethead, etstyle, etlink, ettitle, etp, etUnknown,
|
|
etframeset, ethead, etstyle, etlink, ettitle, etp, etUnknown,
|
|
etli, etp, eth1, eth2, eth3, eth4, eth5, eth6, etdl, etaddress,
|
|
etpre, ethead, etli, etUnknown,
|
|
ethr, etp, ethead, etUnknown,
|
|
eth1, etp, ethead, etUnknown,
|
|
eth2, etp, ethead, etUnknown,
|
|
eth3, etp, ethead, etUnknown,
|
|
eth4, etp, ethead, etUnknown,
|
|
eth5, etp, ethead, etUnknown,
|
|
eth6, etp, ethead, etUnknown,
|
|
etdir, etp, ethead, etUnknown,
|
|
etaddress, etp, ethead, etul, etUnknown,
|
|
etpre, etp, ethead, etul, etUnknown,
|
|
etblockquote, etp, ethead, etUnknown,
|
|
etdl, etp, etdt, etmenu, etdir, etaddress, etpre,
|
|
ethead, etUnknown,
|
|
etdt, etp, etmenu, etdir, etaddress, etpre,
|
|
ethead, etdd, etUnknown,
|
|
etdd, etp, etmenu, etdir, etaddress, etpre,
|
|
ethead, etdt, etUnknown,
|
|
etul, etp, ethead, etol, etmenu, etdir, etaddress, etpre, etUnknown,
|
|
etol, etp, ethead, etul, etUnknown,
|
|
etmenu, etp, ethead, etul, etUnknown,
|
|
etp, etp, ethead, eth1, eth2, eth3, eth4, eth5, eth6, etUnknown,
|
|
etdiv, etp, ethead, etUnknown,
|
|
etnoscript, etp, ethead, etUnknown,
|
|
etcenter, etfont, etb, eti, etp, ethead, etUnknown,
|
|
eta, eta, etUnknown,
|
|
etcaption, etp, etUnknown,
|
|
etcolgroup, etcaption, etcolgroup, etcol, etp, etUnknown,
|
|
etcol, etcaption, etcol, etp, etUnknown,
|
|
ettable, etp, ethead, eth1, eth2, eth3, eth4, eth5, eth6, etpre,
|
|
eta, etUnknown,
|
|
etth, etth, ettd, etp, etspan, etfont, eta, etb, eti, etu, etUnknown,
|
|
ettd, etth, ettd, etp, etspan, etfont, eta, etb, eti, etu, etUnknown,
|
|
ettr, etth, ettd, ettr, etcaption, etcol, etcolgroup, etp, etUnknown,
|
|
etthead, etcaption, etcol, etcolgroup, etUnknown,
|
|
ettfoot, etth, ettd, ettr, etcaption, etcol, etcolgroup, etthead,
|
|
ettbody, etp, etUnknown,
|
|
ettbody, etth, ettd, ettr, etcaption, etcol, etcolgroup, etthead,
|
|
ettfoot, ettbody, etp, etUnknown,
|
|
etoptgroup, etoption, etUnknown,
|
|
etoption, etoption, etUnknown,
|
|
etfieldset, etlegend, etp, ethead, eth1, eth2, eth3, eth4, eth5, eth6,
|
|
etpre, eta, etUnknown,
|
|
etUnknown);
|
|
|
|
AutoCloseIndex: array[0..40] of Integer = (
|
|
0, 19, 22, 25, 32, 39, 53, 57, 61, 65, 69,
|
|
73, 77, 81, 85, 90, 95, 99, 108, 117, 126,
|
|
135, 140, 145, 155, 159, 163, 170, 173, 176,
|
|
182, 187, 199, 210, 221, 230, 235, 246, 258,
|
|
261, 264
|
|
);
|
|
|
|
{ HTML entities, each preceded with its code. There is a separate list for
|
|
each entity length, and each list is sorted by character codes.
|
|
The sole purpose of using AnsiString here is staying compatible with Delphi 7,
|
|
which is totally broken with respect to handling wide literals.
|
|
}
|
|
|
|
ent_2 =
|
|
#3#$9C + 'Mu'+
|
|
#3#$9D + 'Nu'+
|
|
#3#$A0 + 'Pi'+
|
|
#3#$9E + 'Xi'+
|
|
#$22#$65+ 'ge'+
|
|
#0#62 + 'gt'+
|
|
#$22#$64+ 'le'+
|
|
#0#60 + 'lt'+
|
|
#3#$BC + 'mu'+
|
|
#$22#$60+ 'ne'+
|
|
#$22#$0B+ 'ni'+
|
|
#3#$BD + 'nu'+
|
|
#$22#$28+ 'or'+
|
|
#3#$C0 + 'pi'+
|
|
#3#$BE + 'xi';
|
|
|
|
ent_3 =
|
|
#3#$A7 + 'Chi'+
|
|
#0#208 + 'ETH'+
|
|
#3#$97 + 'Eta'+
|
|
#3#$A6 + 'Phi'+
|
|
#3#$A8 + 'Psi'+
|
|
#3#$A1 + 'Rho'+
|
|
#3#$A4 + 'Tau'+
|
|
#0#38 + 'amp'+
|
|
#$22#$27+ 'and'+
|
|
#$22#$20+ 'ang'+
|
|
#$22#$29+ 'cap'+
|
|
#3#$C7 + 'chi'+
|
|
#$22#$2A+ 'cup'+
|
|
#0#176 + 'deg'+
|
|
#3#$B7 + 'eta'+
|
|
#0#240 + 'eth'+
|
|
#$22#$2B+ 'int'+
|
|
#$25#$CA+ 'loz'+
|
|
#$20#$0E+ 'lrm'+
|
|
#0#172 + 'not'+
|
|
#3#$C6 + 'phi'+
|
|
#3#$D6 + 'piv'+
|
|
#3#$C8 + 'psi'+
|
|
#0#174 + 'reg'+
|
|
#3#$C1 + 'rho'+
|
|
#$20#$0F+ 'rlm'+
|
|
#0#173 + 'shy'+
|
|
#$22#$3C+ 'sim'+
|
|
#$22#$82+ 'sub'+
|
|
#$22#$11+ 'sum'+
|
|
#$22#$83+ 'sup'+
|
|
#3#$C4 + 'tau'+
|
|
#0#168 + 'uml'+
|
|
#0#165 + 'yen'+
|
|
#$20#$0D+ 'zwj';
|
|
|
|
ent_4 =
|
|
#0#196 + 'Auml'+
|
|
#3#$92 + 'Beta'+
|
|
#0#203 + 'Euml'+
|
|
#3#$99 + 'Iota'+
|
|
#0#207 + 'Iuml'+
|
|
#0#214 + 'Ouml'+
|
|
#0#220 + 'Uuml'+
|
|
#1#$78 + 'Yuml'+
|
|
#3#$96 + 'Zeta'+
|
|
|
|
#0#228 + 'auml'+
|
|
#3#$B2 + 'beta'+
|
|
#$20#$22+ 'bull'+
|
|
#0#162 + 'cent'+
|
|
#2#$C6 + 'circ'+
|
|
#$22#$45+ 'cong'+
|
|
#0#169 + 'copy'+
|
|
#$21#$D3+ 'dArr'+
|
|
#$21#$93+ 'darr'+
|
|
#$20#$03+ 'emsp'+
|
|
#$20#$02+ 'ensp'+
|
|
#0#235 + 'euml'+
|
|
#$20#$AC+ 'euro'+
|
|
#1#$92 + 'fnof'+
|
|
#$21#$D4+ 'hArr'+
|
|
#$21#$94+ 'harr'+
|
|
#3#$B9 + 'iota'+
|
|
#$22#$08+ 'isin'+
|
|
#0#239 + 'iuml'+
|
|
#$21#$D0+ 'lArr'+
|
|
#$23#$29+ 'lang'+
|
|
#$21#$90+ 'larr'+
|
|
#0#175 + 'macr'+
|
|
#0#160 + 'nbsp'+
|
|
#$22#$84+ 'nsub'+
|
|
#0#170 + 'ordf'+
|
|
#0#186 + 'ordm'+
|
|
#0#246 + 'ouml'+
|
|
#0#182 + 'para'+
|
|
#$22#$02+ 'part'+
|
|
#$22#$A5+ 'perp'+
|
|
#$22#$0F+ 'prod'+
|
|
#$22#$1D+ 'prop'+
|
|
#0#34 + 'quot'+
|
|
#$21#$D2+ 'rArr'+
|
|
#$23#$2A+ 'rang'+
|
|
#$21#$92+ 'rarr'+
|
|
#$21#$1C+ 'real'+
|
|
#$22#$C5+ 'sdot'+
|
|
#0#167 + 'sect'+
|
|
#$22#$86+ 'sube'+
|
|
#0#185 + 'sup1'+
|
|
#0#178 + 'sup2'+
|
|
#0#179 + 'sup3'+
|
|
#$22#$87+ 'supe'+
|
|
#$21#$D1+ 'uArr'+
|
|
#$21#$91+ 'uarr'+
|
|
#0#252 + 'uuml'+
|
|
#0#255 + 'yuml'+
|
|
#3#$B6 + 'zeta'+
|
|
#$20#$0C+ 'zwnj';
|
|
|
|
ent_5 =
|
|
#0#198 + 'AElig'+
|
|
#0#194 + 'Acirc'+
|
|
#3#$91 + 'Alpha'+
|
|
#0#197 + 'Aring'+
|
|
#3#$94 + 'Delta'+
|
|
#0#202 + 'Ecirc'+
|
|
#3#$93 + 'Gamma'+
|
|
#0#206 + 'Icirc'+
|
|
#3#$9A + 'Kappa'+
|
|
#1#$52 + 'OElig'+
|
|
#0#212 + 'Ocirc'+
|
|
#3#$A9 + 'Omega'+
|
|
#$20#$33+ 'Prime'+
|
|
#3#$A3 + 'Sigma'+
|
|
#0#222 + 'THORN'+
|
|
#3#$98 + 'Theta'+
|
|
#0#219 + 'Ucirc'+
|
|
|
|
#0#226 + 'acirc'+
|
|
#0#180 + 'acute'+
|
|
#0#230 + 'aelig'+
|
|
#3#$B1 + 'alpha'+
|
|
#0#229 + 'aring'+
|
|
#$22#$48+ 'asymp'+
|
|
#$20#$1E+ 'bdquo'+
|
|
#0#184 + 'cedil'+
|
|
#$26#$63+ 'clubs'+
|
|
#$21#$B5+ 'crarr'+
|
|
#3#$B4 + 'delta'+
|
|
#$26#$66+ 'diams'+
|
|
#0#234 + 'ecirc'+
|
|
#$22#$05+ 'empty'+
|
|
#$22#$61+ 'equiv'+
|
|
#$22#$03+ 'exist'+
|
|
#$20#$44+ 'frasl'+
|
|
#3#$B3 + 'gamma'+
|
|
#0#238 + 'icirc'+
|
|
#0#161 + 'iexcl'+
|
|
#$21#$11+ 'image'+
|
|
#$22#$1E+ 'infin'+
|
|
#3#$BA + 'kappa'+
|
|
#0#171 + 'laquo'+
|
|
#$23#$08+ 'lceil'+
|
|
#$20#$1C+ 'ldquo'+
|
|
#$20#$18+ 'lsquo'+
|
|
#$20#$14+ 'mdash'+
|
|
#0#181 + 'micro'+
|
|
#$22#$12+ 'minus'+
|
|
#$22#$07+ 'nabla'+
|
|
#$20#$13+ 'ndash'+
|
|
#$22#$09+ 'notin'+
|
|
#0#244 + 'ocirc'+
|
|
#1#$53 + 'oelig'+
|
|
#$20#$3E+ 'oline'+
|
|
#3#$C9 + 'omega'+
|
|
#$22#$95+ 'oplus'+
|
|
#0#163 + 'pound'+
|
|
#$20#$32+ 'prime'+
|
|
#$22#$1A+ 'radic'+
|
|
#0#187 + 'raquo'+
|
|
#$23#$09+ 'rceil'+
|
|
#$20#$1D+ 'rdquo'+
|
|
#$20#$19+ 'rsquo'+
|
|
#$20#$1A+ 'sbquo'+
|
|
#3#$C3 + 'sigma'+
|
|
#0#223 + 'szlig'+
|
|
#3#$B8 + 'theta'+
|
|
#0#254 + 'thorn'+
|
|
#2#$DC + 'tilde'+
|
|
#0#215 + 'times'+
|
|
#$21#$22+ 'trade'+
|
|
#0#251 + 'ucirc'+
|
|
#3#$D2 + 'upsih';
|
|
|
|
ent_6 =
|
|
#0#193 + 'Aacute'+
|
|
#0#192 + 'Agrave'+
|
|
#0#195 + 'Atilde'+
|
|
#0#199 + 'Ccedil'+
|
|
#$20#$21+ 'Dagger'+
|
|
#0#201 + 'Eacute'+
|
|
#0#200 + 'Egrave'+
|
|
#0#205 + 'Iacute'+
|
|
#0#204 + 'Igrave'+
|
|
#3#$9B + 'Lambda'+
|
|
#0#209 + 'Ntilde'+
|
|
#0#211 + 'Oacute'+
|
|
#0#210 + 'Ograve'+
|
|
#0#216 + 'Oslash'+
|
|
#0#213 + 'Otilde'+
|
|
#1#$60 + 'Scaron'+
|
|
#0#218 + 'Uacute'+
|
|
#0#217 + 'Ugrave'+
|
|
#0#221 + 'Yacute'+
|
|
|
|
#0#225 + 'aacute'+
|
|
#0#224 + 'agrave'+
|
|
#0#227 + 'atilde'+
|
|
#0#166 + 'brvbar'+
|
|
#0#231 + 'ccedil'+
|
|
#0#164 + 'curren'+
|
|
#$20#$20+ 'dagger'+
|
|
#0#247 + 'divide'+
|
|
#0#233 + 'eacute'+
|
|
#0#232 + 'egrave'+
|
|
#$22#$00+ 'forall'+
|
|
#0#189 + 'frac12'+
|
|
#0#188 + 'frac14'+
|
|
#0#190 + 'frac34'+
|
|
#$26#$65+ 'hearts'+
|
|
#$20#$26+ 'hellip'+
|
|
#0#237 + 'iacute'+
|
|
#0#236 + 'igrave'+
|
|
#0#191 + 'iquest'+
|
|
#3#$BB + 'lambda'+
|
|
#$23#$0A+ 'lfloor'+
|
|
#$22#$17+ 'lowast'+
|
|
#$20#$39+ 'lsaquo'+
|
|
#0#183 + 'middot'+
|
|
#0#241 + 'ntilde'+
|
|
#0#243 + 'oacute'+
|
|
#0#242 + 'ograve'+
|
|
#0#248 + 'oslash'+
|
|
#0#245 + 'otilde'+
|
|
#$22#$97+ 'otimes'+
|
|
#$20#$30+ 'permil'+
|
|
#0#177 + 'plusmn'+
|
|
#$23#$0B+ 'rfloor'+
|
|
#$20#$3A+ 'rsaquo'+
|
|
#1#$61 + 'scaron'+
|
|
#3#$C2 + 'sigmaf'+
|
|
#$26#$60+ 'spades'+
|
|
#$22#$34+ 'there4'+
|
|
#$20#$09+ 'thinsp'+
|
|
#0#250 + 'uacute'+
|
|
#0#249 + 'ugrave'+
|
|
#$21#$18+ 'weierp'+
|
|
#0#253 + 'yacute';
|
|
|
|
ent_7 =
|
|
#3#$95 + 'Epsilon'+
|
|
#3#$9F + 'Omicron'+
|
|
#3#$A5 + 'Upsilon'+
|
|
#$21#$35+ 'alefsym'+
|
|
#3#$B5 + 'epsilon'+
|
|
#3#$BF + 'omicron'+
|
|
#3#$C5 + 'upsilon';
|
|
|
|
ent_8 =
|
|
#3#$D1 + 'thetasym';
|
|
|
|
strs: array[2..8] of string = (
|
|
ent_2, ent_3, ent_4, ent_5, ent_6, ent_7, ent_8
|
|
);
|
|
|
|
function BSearch(P: PWideChar; Len: Integer; const data: string): WideChar;
|
|
var
|
|
L, H, mid, J, C: Integer;
|
|
begin
|
|
Result := #0;
|
|
L := 0;
|
|
H := (Length(data)+1) div (Len+2);
|
|
while L <= H do
|
|
begin
|
|
mid := L + ((H - L) shr 1);
|
|
J := 0;
|
|
repeat
|
|
C := ord(P[J]) - ord(data[mid*(Len+2)+3+J]);
|
|
Inc(J);
|
|
until (C <> 0) or (J >= Len);
|
|
if C > 0 then L := mid + 1 else
|
|
begin
|
|
H := mid - 1;
|
|
if C = 0 then
|
|
begin
|
|
Result := WideChar((ord(data[mid*(Len+2)+1]) shl 8) or ord(data[mid*(Len+2)+2]));
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{
|
|
Remaining issues:
|
|
1) UTF-16 surrogate pairs
|
|
2) HTML accepts uppercase 'X' for hex notation, but XML does not.
|
|
3) 'apos' is used in xml/xhtml, but not in HTML 4.01
|
|
}
|
|
|
|
function ResolveHTMLEntityReference(const Name: WideString;
|
|
var Entity: WideChar): Boolean;
|
|
var
|
|
i, L: Integer;
|
|
value: Integer;
|
|
begin
|
|
L := Length(Name);
|
|
if (L > 1) and (Name[1] = '#') then
|
|
begin
|
|
value := 0;
|
|
if (Name[2] = 'x') or (Name[2] = 'X') then
|
|
begin
|
|
i := 3;
|
|
while i <= L do
|
|
begin
|
|
case Name[i] of
|
|
'0'..'9': Value := Value * 16 + Ord(Name[i]) - Ord('0');
|
|
'a'..'f': Value := Value * 16 + Ord(Name[i]) - (Ord('a') - 10);
|
|
'A'..'F': Value := Value * 16 + Ord(Name[i]) - (Ord('A') - 10);
|
|
else
|
|
Break;
|
|
end;
|
|
Inc(i);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
i := 2;
|
|
while i <= L do
|
|
begin
|
|
case Name[i] of
|
|
'0'..'9': Value := Value * 10 + Ord(Name[i]) - Ord('0');
|
|
else
|
|
Break;
|
|
end;
|
|
Inc(i);
|
|
end;
|
|
end;
|
|
Result := (i = L+1);
|
|
if Result then
|
|
Entity := WideChar(Value);
|
|
end
|
|
else
|
|
begin
|
|
case L of
|
|
2..8: Entity := BSearch(PWideChar(Name), L, strs[L]);
|
|
else
|
|
Entity := #0;
|
|
end;
|
|
Result := (Entity <> #0);
|
|
end;
|
|
end;
|
|
|
|
function IsAutoClose(NewTag, OldTag: THTMLElementTag): Boolean;
|
|
var
|
|
i, j: Integer;
|
|
begin
|
|
Result := False;
|
|
for i := 0 to high(AutoCloseIndex) do
|
|
if NewTag = AutoCloseTab[AutoCloseIndex[i]] then
|
|
begin
|
|
j := AutoCloseIndex[i]+1;
|
|
while AutoCloseTab[j] <> etUnknown do
|
|
begin
|
|
if AutoCloseTab[j] = OldTag then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
Inc(j);
|
|
end;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
end.
|