View Issue Details

IDProjectCategoryView StatusLast Update
0032322FPCPatchpublic2017-08-24 17:21
ReporterMartokAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version3.1.1Product Build 
Target Version3.2.0Fixed in Version3.1.1 
Summary0032322: Improvements to fcl-xml
DescriptionSome patches for HTML-DOM.

Patch 0001: non-essential, fixes the "buildfclxml" Lazarus project.

Patch 0002: THTMLDocument automatically creates the correct specialized THTMLElement class based on tag name

Patch 0003: Fixes an issue with self-closing tags when parsing HTML: tags would get closed multiple times if THTMLReader.FStack contained "unclosed" tags like
that also don't have efEndTagOptional.
TagsNo tags attached.
Fixed in Revision37048
FPCOldBugId
FPCTarget
Attached Files
  • 0001-Fix-compilation-of-test-project.patch (3,450 bytes)
    From 3f18b0a884b79aee18bc79b56c094a6cf1f1ba1c Mon Sep 17 00:00:00 2001
    From: Martok <martok@martoks-place.de>
    Date: Sun, 20 Aug 2017 01:13:52 +0200
    Subject: [PATCH 1/3] Fix compilation of test project
    
    ---
     .../fcl-xml/{buildfcl-xml.lpi => buildfclxml.lpi}  | 26 ++++++++++++----------
     .../fcl-xml/{buildfcl-xml.pp => buildfclxml.pas}   |  2 +-
     2 files changed, 15 insertions(+), 13 deletions(-)
     rename packages/fcl-xml/{buildfcl-xml.lpi => buildfclxml.lpi} (73%)
     rename packages/fcl-xml/{buildfcl-xml.pp => buildfclxml.pas} (88%)
    
    diff --git a/packages/fcl-xml/buildfcl-xml.lpi b/packages/fcl-xml/buildfclxml.lpi
    similarity index 73%
    rename from packages/fcl-xml/buildfcl-xml.lpi
    rename to packages/fcl-xml/buildfclxml.lpi
    index d179fb8e99..4160da2d53 100644
    --- a/packages/fcl-xml/buildfcl-xml.lpi
    +++ b/packages/fcl-xml/buildfclxml.lpi
    @@ -1,7 +1,7 @@
    -<?xml version="1.0"?>
    +<?xml version="1.0" encoding="UTF-8"?>
     <CONFIG>
       <ProjectOptions>
    -    <Version Value="7"/>
    +    <Version Value="10"/>
         <General>
           <Flags>
             <MainUnitHasUsesSectionForAllUnits Value="False"/>
    @@ -12,12 +12,14 @@
           </Flags>
           <SessionStorage Value="InProjectDir"/>
           <MainUnit Value="0"/>
    -      <TargetFileExt Value=".exe"/>
           <Title Value="buildrtl"/>
         </General>
         <VersionInfo>
    -      <ProjectVersion Value=""/>
    +      <StringTable ProductVersion=""/>
         </VersionInfo>
    +    <BuildModes Count="1">
    +      <Item1 Name="default" Default="True"/>
    +    </BuildModes>
         <PublishOptions>
           <Version Value="2"/>
           <IgnoreBinaries Value="False"/>
    @@ -32,30 +34,30 @@
         </RunParams>
         <Units Count="1">
           <Unit0>
    -        <Filename Value="buildfcl-xml.pp"/>
    +        <Filename Value="buildfclxml.pas"/>
             <IsPartOfProject Value="True"/>
    -        <UnitName Value="buildrtl"/>
           </Unit0>
         </Units>
       </ProjectOptions>
       <CompilerOptions>
    -    <Version Value="8"/>
    +    <Version Value="11"/>
         <SearchPaths>
    -      <IncludeFiles Value="src/"/>
    -      <OtherUnitFiles Value="src/"/>
    -      <UnitOutputDirectory Value="units/$(TargetCPU)-$(TargetOS)"/>
    +      <IncludeFiles Value="src"/>
    +      <OtherUnitFiles Value="src"/>
    +      <UnitOutputDirectory Value="../../../units/$(TargetCPU)-$(TargetOS)/fcl-xml"/>
         </SearchPaths>
         <Parsing>
           <Style Value="2"/>
    +      <SyntaxOptions>
    +        <UseAnsiStrings Value="False"/>
    +      </SyntaxOptions>
         </Parsing>
         <Other>
           <Verbosity>
             <ShowNotes Value="False"/>
             <ShowHints Value="False"/>
           </Verbosity>
    -      <CompilerPath Value="$(CompPath)"/>
           <ExecuteBefore>
    -        <Command Value="cmd.exe /c &quot;if not exist units/$(TargetCPU)-$(TargetOS) mkdir units/$(TargetCPU)-$(TargetOS)&quot;"/>
             <ShowAllMessages Value="True"/>
           </ExecuteBefore>
         </Other>
    diff --git a/packages/fcl-xml/buildfcl-xml.pp b/packages/fcl-xml/buildfclxml.pas
    similarity index 88%
    rename from packages/fcl-xml/buildfcl-xml.pp
    rename to packages/fcl-xml/buildfclxml.pas
    index 47d658a26a..9396078063 100644
    --- a/packages/fcl-xml/buildfcl-xml.pp
    +++ b/packages/fcl-xml/buildfclxml.pas
    @@ -6,7 +6,7 @@ unit buildfclxml;
         uses
           htmldefs, sax, xmlutils, dom, sax_html, dom_html, xmlcfg, xmlread,
           xmlstreaming, xmlwrite, xhtml, htmwrite, xpath, htmlelements, htmlwriter,
    -      xmlconf, sax_xml, xmliconv;
    +      xmlconf, sax_xml;
     
       implementation
     
    -- 
    2.12.0.windows.1
    
    
  • 0002-Make-THTMLDocument-create-appropriate-instance-of-TH.patch (13,068 bytes)
    From b103608e21280df355e8839b4d9dbf4eb85de0c6 Mon Sep 17 00:00:00 2001
    From: Martok <martok@martoks-place.de>
    Date: Sun, 20 Aug 2017 01:16:29 +0200
    Subject: [PATCH 2/3] Make THTMLDocument create appropriate instance of
     THTMLElement
    
    ---
     packages/fcl-xml/src/dom_html.pp | 217 ++++++++++++---------------------------
     1 file changed, 66 insertions(+), 151 deletions(-)
    
    diff --git a/packages/fcl-xml/src/dom_html.pp b/packages/fcl-xml/src/dom_html.pp
    index 45622cf0fe..aaa438cb4b 100644
    --- a/packages/fcl-xml/src/dom_html.pp
    +++ b/packages/fcl-xml/src/dom_html.pp
    @@ -665,87 +665,10 @@ type
         function HashForName(const aName: DOMString): PHashItem;
     
         // Helper functions (not in DOM standard):
    -    function CreateElement(const tagName: DOMString): THTMLElement;
    -    function CreateSubElement: THTMLElement;
    -    function CreateSupElement: THTMLElement;
    -    function CreateSpanElement: THTMLElement;
    -    function CreateBDOElement: THTMLElement;
    -    function CreateTTElement: THTMLElement;
    -    function CreateIElement: THTMLElement;
    -    function CreateBElement: THTMLElement;
    -    function CreateUElement: THTMLElement;
    -    function CreateSElement: THTMLElement;
    -    function CreateStrikeElement: THTMLElement;
    -    function CreateBigElement: THTMLElement;
    -    function CreateSmallElement: THTMLElement;
    -    function CreateEmElement: THTMLElement;
    -    function CreateStrongElement: THTMLElement;
    -    function CreateDfnElement: THTMLElement;
    -    function CreateCodeElement: THTMLElement;
    -    function CreateSampElement: THTMLElement;
    -    function CreateKbdElement: THTMLElement;
    -    function CreateVarElement: THTMLElement;
    -    function CreateCiteElement: THTMLElement;
    -    function CreateAcronymElement: THTMLElement;
    -    function CreateAbbrElement: THTMLElement;
    -    function CreateDDElement: THTMLElement;
    -    function CreateDTElement: THTMLElement;
    -    function CreateNoFramesElement: THTMLElement;
    -    function CreateNoScriptElement: THTMLElement;
    -    function CreateAddressElement: THTMLElement;
    -    function CreateCenterElement: THTMLElement;
    +    function CreateElement(const tagName: DOMString): THTMLElement; override;
         function CreateHtmlElement: THTMLHtmlElement;
         function CreateHeadElement: THTMLHeadElement;
    -    function CreateLinkElement: THTMLLinkElement;
    -{    function CreateTitleElement: THTMLTitleElement;
    -    function CreateMetaElement: THTMLMetaElement;
    -    function CreateBaseElement: THTMLBaseElement;
    -    function CreateIsIndexElement: THTMLIsIndexElement;
    -    function CreateStyleElement: THTMLStyleElement;}
         function CreateBodyElement: THTMLBodyElement;
    -{    function CreateFormElement: THTMLFormElement;
    -    function CreateSelectElement: THTMLSelectElement;
    -    function CreateOptGroupElement: THTMLOptGroupElement;
    -    function CreateOptionElement: THTMLOptionElement;
    -    function CreateInputElement: THTMLInputElement;
    -    function CreateTextAreaElement: THTMLTextAreaElement;
    -    function CreateButtonElement: THTMLButtonElement;
    -    function CreateLabelElement: THTMLLabelElement;
    -    function CreateFieldSetElement: THTMLFieldSetElement;
    -    function CreateLegendElement: THTMLLegendElement;}
    -    function CreateUListElement: THTMLUListElement;
    -    function CreateOListElement: THTMLOListElement;
    -    function CreateDListElement: THTMLDListElement;
    -{    function CreateDirectoryElement: THTMLDirectoryElement;
    -    function CreateMenuElement: THTMLMenuElement;}
    -    function CreateLIElement: THTMLLIElement;
    -{    function CreateDivElement: THTMLDivElement;}
    -    function CreateParagraphElement: THTMLParagraphElement;
    -{    function CreateHeadingElement: THTMLHeadingElement;
    -    function CreateQuoteElement: THTMLQuoteElement;
    -    function CreatePreElement: THTMLPreElement;
    -    function CreateBRElement: THTMLBreElement;
    -    function CreateBaseFontElement: THTMLBaseFontElement;
    -    function CreateFontElement: THTMFontLElement;
    -    function CreateHRElement: THTMLHREElement;
    -    function CreateModElement: THTMLModElement;
    -    function CreateAnchorElement: THTMLAnchorElement;
    -    function CreateImageElement: THTMLImageElement;
    -    function CreateObjectElement: THTMLObjectElement;
    -    function CreateParamElement: THTMLParamElement;
    -    function CreateAppletElement: THTMLAppletElement;
    -    function CreateMapElement: THTMLMapElement;
    -    function CreateAreaElement: THTMLAreaElement;
    -    function CreateScriptElement: THTMLScriptElement;
    -    function CreateTableElement: THTMLTableElement;
    -    function CreateTableCaptionElement: THTMLTableCaptionElement;
    -    function CreateTableColElement: THTMLTableColElement;
    -    function CreateTableSectionElement: THTMLTableSectionElement;
    -    function CreateTableRowElement: THTMLTableRowElement;
    -    function CreateTableCellElement: THTMLTableCellElement;
    -    function CreateFrameSetElement: THTMLFrameSetElement;
    -    function CreateFrameElement: THTMLFrameElement;
    -    function CreateIFrameElement: THTMLIFrameElement;}
       end;
     
     
    @@ -1249,8 +1172,68 @@ begin
     end;
     
     function THTMLDocument.CreateElement(const tagName: DOMString): THTMLElement;
    -begin
    -  Result := THTMLElement.Create(Self);
    +var
    +  elClass: TDOMElementClass;
    +begin
    +  case UpperCase(tagName) of
    +    'HTML'               : elClass:= THTMLHtmlElement;
    +    'HEAD'               : elClass:= THTMLHeadElement;
    +    'BODY'               : elClass:= THTMLBodyElement;
    +    'P'                  : elClass:= THTMLParagraphElement;
    +    'LINK'               : elClass:= THTMLLinkElement;
    +    'TITLE'              : elClass:= THTMLTitleElement;
    +    'META'               : elClass:= THTMLMetaElement;
    +    'BASE'               : elClass:= THTMLBaseElement;
    +    'ISINDEX'            : elClass:= THTMLIsIndexElement;
    +    'STYLE'              : elClass:= THTMLStyleElement;
    +    'FORM'               : elClass:= THTMLFormElement;
    +    'SELECT'             : elClass:= THTMLSelectElement;
    +    'OPTGROUP'           : elClass:= THTMLOptGroupElement;
    +    'OPTION'             : elClass:= THTMLOptionElement;
    +    'INPUT'              : elClass:= THTMLInputElement;
    +    'TEXTAREA'           : elClass:= THTMLTextAreaElement;
    +    'BUTTON'             : elClass:= THTMLButtonElement;
    +    'LABEL'              : elClass:= THTMLLabelElement;
    +    'FIELDSET'           : elClass:= THTMLFieldSetElement;
    +    'LEGEND'             : elClass:= THTMLLegendElement;
    +    'UL'                 : elClass:= THTMLUListElement;
    +    'OL'                 : elClass:= THTMLOListElement;
    +    'DL'                 : elClass:= THTMLDListElement;
    +    'DIRECTORY'          : elClass:= THTMLDirectoryElement;
    +    'MENU'               : elClass:= THTMLMenuElement;
    +    'LI'                 : elClass:= THTMLLIElement;
    +    'DIV'                : elClass:= THTMLDivElement;
    +    'H1','H2','H3','H4','H5',
    +    'H6','H7','H8','H9'  : elClass:= THTMLHeadingElement;
    +    'QUOTE'              : elClass:= THTMLQuoteElement;
    +    'PRE'                : elClass:= THTMLPreElement;
    +    'BR'                 : elClass:= THTMLBRElement;
    +    'BASEFONT'           : elClass:= THTMLBaseFontElement;
    +    'FONT'               : elClass:= THTMLFontElement;
    +    'HR'                 : elClass:= THTMLHRElement;
    +    'MOD'                : elClass:= THTMLModElement;
    +    'A'                  : elClass:= THTMLAnchorElement;
    +    'IMG'                : elClass:= THTMLImageElement;
    +    'OBJECT'             : elClass:= THTMLObjectElement;
    +    'PARAM'              : elClass:= THTMLParamElement;
    +    'APPLET'             : elClass:= THTMLAppletElement;
    +    'MAP'                : elClass:= THTMLMapElement;
    +    'AREA'               : elClass:= THTMLAreaElement;
    +    'SCRIPT'             : elClass:= THTMLScriptElement;
    +    'TABLE'              : elClass:= THTMLTableElement;
    +    'CAPTION'            : elClass:= THTMLTableCaptionElement;
    +  //'TABLECOL'           : elClass:= THTMLTableColElement;
    +    'THEAD','TBODY',
    +    'TFOOT'              : elClass:= THTMLTableSectionElement;
    +    'TR'                 : elClass:= THTMLTableRowElement;
    +    'TD','TH'            : elClass:= THTMLTableCellElement;
    +    'FRAMESET'           : elClass:= THTMLFrameSetElement;
    +    'FRAME'              : elClass:= THTMLFrameElement;
    +    'IFRAME'             : elClass:= THTMLIFrameElement;
    +  else
    +    elClass:= THTMLElement;
    +  end;
    +  Result := THTMLElement(elClass.Create(Self));
       Result.FNSI.QName := FNames.FindOrAdd(DOMPChar(tagName), Length(tagName));
     end;
     
    @@ -1259,87 +1242,19 @@ begin
       Result := FNames.FindOrAdd(DOMPChar(aName), Length(aName));
     end;
     
    -function THTMLDocument.CreateSubElement: THTMLElement; begin Result := CreateElement('sub') end;
    -function THTMLDocument.CreateSupElement: THTMLElement; begin Result := CreateElement('sup') end;
    -function THTMLDocument.CreateSpanElement: THTMLElement; begin Result := CreateElement('span') end;
    -function THTMLDocument.CreateBDOElement: THTMLElement; begin Result := CreateElement('bdo') end;
    -function THTMLDocument.CreateTTElement: THTMLElement; begin Result := CreateElement('tt') end;
    -function THTMLDocument.CreateIElement: THTMLElement; begin Result := CreateElement('i') end;
    -function THTMLDocument.CreateBElement: THTMLElement; begin Result := CreateElement('b') end;
    -function THTMLDocument.CreateUElement: THTMLElement; begin Result := CreateElement('u') end;
    -function THTMLDocument.CreateSElement: THTMLElement; begin Result := CreateElement('s') end;
    -function THTMLDocument.CreateStrikeElement: THTMLElement; begin Result := CreateElement('strike') end;
    -function THTMLDocument.CreateBigElement: THTMLElement; begin Result := CreateElement('big') end;
    -function THTMLDocument.CreateSmallElement: THTMLElement; begin Result := CreateElement('small') end;
    -function THTMLDocument.CreateEmElement: THTMLElement; begin Result := CreateElement('em') end;
    -function THTMLDocument.CreateStrongElement: THTMLElement; begin Result := CreateElement('strong') end;
    -function THTMLDocument.CreateDfnElement: THTMLElement; begin Result := CreateElement('dfn') end;
    -function THTMLDocument.CreateCodeElement: THTMLElement; begin Result := CreateElement('code') end;
    -function THTMLDocument.CreateSampElement: THTMLElement; begin Result := CreateElement('samp') end;
    -function THTMLDocument.CreateKbdElement: THTMLElement; begin Result := CreateElement('kbd') end;
    -function THTMLDocument.CreateVarElement: THTMLElement; begin Result := CreateElement('var') end;
    -function THTMLDocument.CreateCiteElement: THTMLElement; begin Result := CreateElement('cite') end;
    -function THTMLDocument.CreateAcronymElement: THTMLElement; begin Result := CreateElement('acronym') end;
    -function THTMLDocument.CreateAbbrElement: THTMLElement; begin Result := CreateElement('abbr') end;
    -function THTMLDocument.CreateDDElement: THTMLElement; begin Result := CreateElement('dd') end;
    -function THTMLDocument.CreateDTElement: THTMLElement; begin Result := CreateElement('dt') end;
    -function THTMLDocument.CreateNoFramesElement: THTMLElement; begin Result := CreateElement('noframes') end;
    -function THTMLDocument.CreateNoScriptElement: THTMLElement; begin Result := CreateElement('noscript') end;
    -function THTMLDocument.CreateAddressElement: THTMLElement; begin Result := CreateElement('address') end;
    -function THTMLDocument.CreateCenterElement: THTMLElement; begin Result := CreateElement('center') end;
    -
     function THTMLDocument.CreateHtmlElement: THTMLHtmlElement;
     begin
    -  Result := THTMLHtmlElement.Create(Self);
    -  Result.FNSI.QName := HashForName('html');
    +  Result:= CreateElement('HTML') as THTMLHtmlElement;
     end;
     
     function THTMLDocument.CreateHeadElement: THTMLHeadElement;
     begin
    -  Result := THTMLHeadElement.Create(Self);
    -  Result.FNSI.QName := HashForName('head');
    -end;
    -
    -function THTMLDocument.CreateLinkElement: THTMLLinkElement;
    -begin
    -  Result := THTMLLinkElement.Create(Self);
    -  Result.FNSI.QName := HashForName('a');
    +  Result:= CreateElement('HEAD') as THTMLHeadElement;
     end;
     
     function THTMLDocument.CreateBodyElement: THTMLBodyElement;
     begin
    -  Result := THTMLBodyElement.Create(Self);
    -  Result.FNSI.QName := HashForName('body');
    -end;
    -
    -function THTMLDocument.CreateUListElement: THTMLUListElement;
    -begin
    -  Result := THTMLUListElement.Create(Self);
    -  Result.FNSI.QName := HashForName('ul');
    -end;
    -
    -function THTMLDocument.CreateOListElement: THTMLOListElement;
    -begin
    -  Result := THTMLOListElement.Create(Self);
    -  Result.FNSI.QName := HashForName('ol');
    -end;
    -
    -function THTMLDocument.CreateDListElement: THTMLDListElement;
    -begin
    -  Result := THTMLDListElement.Create(Self);
    -  Result.FNSI.QName := HashForName('dl');
    -end;
    -
    -function THTMLDocument.CreateLIElement: THTMLLIElement;
    -begin
    -  Result := THTMLLIElement.Create(Self);
    -  Result.FNSI.QName := HashForName('li');
    -end;
    -//...
    -function THTMLDocument.CreateParagraphElement: THTMLParagraphElement;
    -begin
    -  Result := THTMLParagraphElement.Create(Self);
    -  Result.FNSI.QName := HashForName('p');
    +  Result:= CreateElement('BODY') as THTMLBodyElement;
     end;
     
     { THTMLFormElement }
    -- 
    2.12.0.windows.1
    
    
  • 0003-Do-not-add-elements-that-have-no-children-to-the-ope.patch (1,351 bytes)
    From 84ea557ffedd8d26f827a11cca075113b6e8a856 Mon Sep 17 00:00:00 2001
    From: Martok <martok@martoks-place.de>
    Date: Wed, 23 Aug 2017 13:34:30 +0200
    Subject: [PATCH 3/3] Do not add elements that have no children to the open
     elements stack
    
    Elements without efSubelementContent (or with Empty in W3C jargon) must
    not be on the open tags stack, or they cause confusion when their parents
    are closed.
    ---
     packages/fcl-xml/src/sax_html.pp | 5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/packages/fcl-xml/src/sax_html.pp b/packages/fcl-xml/src/sax_html.pp
    index 4096812499..75a8158a2a 100644
    --- a/packages/fcl-xml/src/sax_html.pp
    +++ b/packages/fcl-xml/src/sax_html.pp
    @@ -553,6 +553,10 @@ begin
               AutoClose(TagName);
               namePush(TagName);
               DoStartElement('', TagName, '', Attr);
    +          if not (efSubelementContent in HTMLElementProps[FStack[FNesting-1]].Flags) then begin
    +            DoEndElement('', TagName, '');
    +            NamePop;
    +          end;
               if FStack[FNesting-1] in [etScript,etStyle] then
               begin
                 NewContext := scScript;
    @@ -668,6 +672,7 @@ begin
       NodeInfo := THTMLNodeInfo.Create;
       NodeInfo.NodeType := ntTag;
       NodeInfo.DOMNode := Element;
    +  NodeInfo.Closed := false;
       if IsFragmentMode then
       begin
         if not FragmentRootSet then
    -- 
    2.12.0.windows.1
    
    

Activities

Martok

2017-08-23 13:45

reporter  

0001-Fix-compilation-of-test-project.patch (3,450 bytes)
From 3f18b0a884b79aee18bc79b56c094a6cf1f1ba1c Mon Sep 17 00:00:00 2001
From: Martok <martok@martoks-place.de>
Date: Sun, 20 Aug 2017 01:13:52 +0200
Subject: [PATCH 1/3] Fix compilation of test project

---
 .../fcl-xml/{buildfcl-xml.lpi => buildfclxml.lpi}  | 26 ++++++++++++----------
 .../fcl-xml/{buildfcl-xml.pp => buildfclxml.pas}   |  2 +-
 2 files changed, 15 insertions(+), 13 deletions(-)
 rename packages/fcl-xml/{buildfcl-xml.lpi => buildfclxml.lpi} (73%)
 rename packages/fcl-xml/{buildfcl-xml.pp => buildfclxml.pas} (88%)

diff --git a/packages/fcl-xml/buildfcl-xml.lpi b/packages/fcl-xml/buildfclxml.lpi
similarity index 73%
rename from packages/fcl-xml/buildfcl-xml.lpi
rename to packages/fcl-xml/buildfclxml.lpi
index d179fb8e99..4160da2d53 100644
--- a/packages/fcl-xml/buildfcl-xml.lpi
+++ b/packages/fcl-xml/buildfclxml.lpi
@@ -1,7 +1,7 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
   <ProjectOptions>
-    <Version Value="7"/>
+    <Version Value="10"/>
     <General>
       <Flags>
         <MainUnitHasUsesSectionForAllUnits Value="False"/>
@@ -12,12 +12,14 @@
       </Flags>
       <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
-      <TargetFileExt Value=".exe"/>
       <Title Value="buildrtl"/>
     </General>
     <VersionInfo>
-      <ProjectVersion Value=""/>
+      <StringTable ProductVersion=""/>
     </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="default" Default="True"/>
+    </BuildModes>
     <PublishOptions>
       <Version Value="2"/>
       <IgnoreBinaries Value="False"/>
@@ -32,30 +34,30 @@
     </RunParams>
     <Units Count="1">
       <Unit0>
-        <Filename Value="buildfcl-xml.pp"/>
+        <Filename Value="buildfclxml.pas"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="buildrtl"/>
       </Unit0>
     </Units>
   </ProjectOptions>
   <CompilerOptions>
-    <Version Value="8"/>
+    <Version Value="11"/>
     <SearchPaths>
-      <IncludeFiles Value="src/"/>
-      <OtherUnitFiles Value="src/"/>
-      <UnitOutputDirectory Value="units/$(TargetCPU)-$(TargetOS)"/>
+      <IncludeFiles Value="src"/>
+      <OtherUnitFiles Value="src"/>
+      <UnitOutputDirectory Value="../../../units/$(TargetCPU)-$(TargetOS)/fcl-xml"/>
     </SearchPaths>
     <Parsing>
       <Style Value="2"/>
+      <SyntaxOptions>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
     </Parsing>
     <Other>
       <Verbosity>
         <ShowNotes Value="False"/>
         <ShowHints Value="False"/>
       </Verbosity>
-      <CompilerPath Value="$(CompPath)"/>
       <ExecuteBefore>
-        <Command Value="cmd.exe /c &quot;if not exist units/$(TargetCPU)-$(TargetOS) mkdir units/$(TargetCPU)-$(TargetOS)&quot;"/>
         <ShowAllMessages Value="True"/>
       </ExecuteBefore>
     </Other>
diff --git a/packages/fcl-xml/buildfcl-xml.pp b/packages/fcl-xml/buildfclxml.pas
similarity index 88%
rename from packages/fcl-xml/buildfcl-xml.pp
rename to packages/fcl-xml/buildfclxml.pas
index 47d658a26a..9396078063 100644
--- a/packages/fcl-xml/buildfcl-xml.pp
+++ b/packages/fcl-xml/buildfclxml.pas
@@ -6,7 +6,7 @@ unit buildfclxml;
     uses
       htmldefs, sax, xmlutils, dom, sax_html, dom_html, xmlcfg, xmlread,
       xmlstreaming, xmlwrite, xhtml, htmwrite, xpath, htmlelements, htmlwriter,
-      xmlconf, sax_xml, xmliconv;
+      xmlconf, sax_xml;
 
   implementation
 
-- 
2.12.0.windows.1

Martok

2017-08-23 13:45

reporter  

0002-Make-THTMLDocument-create-appropriate-instance-of-TH.patch (13,068 bytes)
From b103608e21280df355e8839b4d9dbf4eb85de0c6 Mon Sep 17 00:00:00 2001
From: Martok <martok@martoks-place.de>
Date: Sun, 20 Aug 2017 01:16:29 +0200
Subject: [PATCH 2/3] Make THTMLDocument create appropriate instance of
 THTMLElement

---
 packages/fcl-xml/src/dom_html.pp | 217 ++++++++++++---------------------------
 1 file changed, 66 insertions(+), 151 deletions(-)

diff --git a/packages/fcl-xml/src/dom_html.pp b/packages/fcl-xml/src/dom_html.pp
index 45622cf0fe..aaa438cb4b 100644
--- a/packages/fcl-xml/src/dom_html.pp
+++ b/packages/fcl-xml/src/dom_html.pp
@@ -665,87 +665,10 @@ type
     function HashForName(const aName: DOMString): PHashItem;
 
     // Helper functions (not in DOM standard):
-    function CreateElement(const tagName: DOMString): THTMLElement;
-    function CreateSubElement: THTMLElement;
-    function CreateSupElement: THTMLElement;
-    function CreateSpanElement: THTMLElement;
-    function CreateBDOElement: THTMLElement;
-    function CreateTTElement: THTMLElement;
-    function CreateIElement: THTMLElement;
-    function CreateBElement: THTMLElement;
-    function CreateUElement: THTMLElement;
-    function CreateSElement: THTMLElement;
-    function CreateStrikeElement: THTMLElement;
-    function CreateBigElement: THTMLElement;
-    function CreateSmallElement: THTMLElement;
-    function CreateEmElement: THTMLElement;
-    function CreateStrongElement: THTMLElement;
-    function CreateDfnElement: THTMLElement;
-    function CreateCodeElement: THTMLElement;
-    function CreateSampElement: THTMLElement;
-    function CreateKbdElement: THTMLElement;
-    function CreateVarElement: THTMLElement;
-    function CreateCiteElement: THTMLElement;
-    function CreateAcronymElement: THTMLElement;
-    function CreateAbbrElement: THTMLElement;
-    function CreateDDElement: THTMLElement;
-    function CreateDTElement: THTMLElement;
-    function CreateNoFramesElement: THTMLElement;
-    function CreateNoScriptElement: THTMLElement;
-    function CreateAddressElement: THTMLElement;
-    function CreateCenterElement: THTMLElement;
+    function CreateElement(const tagName: DOMString): THTMLElement; override;
     function CreateHtmlElement: THTMLHtmlElement;
     function CreateHeadElement: THTMLHeadElement;
-    function CreateLinkElement: THTMLLinkElement;
-{    function CreateTitleElement: THTMLTitleElement;
-    function CreateMetaElement: THTMLMetaElement;
-    function CreateBaseElement: THTMLBaseElement;
-    function CreateIsIndexElement: THTMLIsIndexElement;
-    function CreateStyleElement: THTMLStyleElement;}
     function CreateBodyElement: THTMLBodyElement;
-{    function CreateFormElement: THTMLFormElement;
-    function CreateSelectElement: THTMLSelectElement;
-    function CreateOptGroupElement: THTMLOptGroupElement;
-    function CreateOptionElement: THTMLOptionElement;
-    function CreateInputElement: THTMLInputElement;
-    function CreateTextAreaElement: THTMLTextAreaElement;
-    function CreateButtonElement: THTMLButtonElement;
-    function CreateLabelElement: THTMLLabelElement;
-    function CreateFieldSetElement: THTMLFieldSetElement;
-    function CreateLegendElement: THTMLLegendElement;}
-    function CreateUListElement: THTMLUListElement;
-    function CreateOListElement: THTMLOListElement;
-    function CreateDListElement: THTMLDListElement;
-{    function CreateDirectoryElement: THTMLDirectoryElement;
-    function CreateMenuElement: THTMLMenuElement;}
-    function CreateLIElement: THTMLLIElement;
-{    function CreateDivElement: THTMLDivElement;}
-    function CreateParagraphElement: THTMLParagraphElement;
-{    function CreateHeadingElement: THTMLHeadingElement;
-    function CreateQuoteElement: THTMLQuoteElement;
-    function CreatePreElement: THTMLPreElement;
-    function CreateBRElement: THTMLBreElement;
-    function CreateBaseFontElement: THTMLBaseFontElement;
-    function CreateFontElement: THTMFontLElement;
-    function CreateHRElement: THTMLHREElement;
-    function CreateModElement: THTMLModElement;
-    function CreateAnchorElement: THTMLAnchorElement;
-    function CreateImageElement: THTMLImageElement;
-    function CreateObjectElement: THTMLObjectElement;
-    function CreateParamElement: THTMLParamElement;
-    function CreateAppletElement: THTMLAppletElement;
-    function CreateMapElement: THTMLMapElement;
-    function CreateAreaElement: THTMLAreaElement;
-    function CreateScriptElement: THTMLScriptElement;
-    function CreateTableElement: THTMLTableElement;
-    function CreateTableCaptionElement: THTMLTableCaptionElement;
-    function CreateTableColElement: THTMLTableColElement;
-    function CreateTableSectionElement: THTMLTableSectionElement;
-    function CreateTableRowElement: THTMLTableRowElement;
-    function CreateTableCellElement: THTMLTableCellElement;
-    function CreateFrameSetElement: THTMLFrameSetElement;
-    function CreateFrameElement: THTMLFrameElement;
-    function CreateIFrameElement: THTMLIFrameElement;}
   end;
 
 
@@ -1249,8 +1172,68 @@ begin
 end;
 
 function THTMLDocument.CreateElement(const tagName: DOMString): THTMLElement;
-begin
-  Result := THTMLElement.Create(Self);
+var
+  elClass: TDOMElementClass;
+begin
+  case UpperCase(tagName) of
+    'HTML'               : elClass:= THTMLHtmlElement;
+    'HEAD'               : elClass:= THTMLHeadElement;
+    'BODY'               : elClass:= THTMLBodyElement;
+    'P'                  : elClass:= THTMLParagraphElement;
+    'LINK'               : elClass:= THTMLLinkElement;
+    'TITLE'              : elClass:= THTMLTitleElement;
+    'META'               : elClass:= THTMLMetaElement;
+    'BASE'               : elClass:= THTMLBaseElement;
+    'ISINDEX'            : elClass:= THTMLIsIndexElement;
+    'STYLE'              : elClass:= THTMLStyleElement;
+    'FORM'               : elClass:= THTMLFormElement;
+    'SELECT'             : elClass:= THTMLSelectElement;
+    'OPTGROUP'           : elClass:= THTMLOptGroupElement;
+    'OPTION'             : elClass:= THTMLOptionElement;
+    'INPUT'              : elClass:= THTMLInputElement;
+    'TEXTAREA'           : elClass:= THTMLTextAreaElement;
+    'BUTTON'             : elClass:= THTMLButtonElement;
+    'LABEL'              : elClass:= THTMLLabelElement;
+    'FIELDSET'           : elClass:= THTMLFieldSetElement;
+    'LEGEND'             : elClass:= THTMLLegendElement;
+    'UL'                 : elClass:= THTMLUListElement;
+    'OL'                 : elClass:= THTMLOListElement;
+    'DL'                 : elClass:= THTMLDListElement;
+    'DIRECTORY'          : elClass:= THTMLDirectoryElement;
+    'MENU'               : elClass:= THTMLMenuElement;
+    'LI'                 : elClass:= THTMLLIElement;
+    'DIV'                : elClass:= THTMLDivElement;
+    'H1','H2','H3','H4','H5',
+    'H6','H7','H8','H9'  : elClass:= THTMLHeadingElement;
+    'QUOTE'              : elClass:= THTMLQuoteElement;
+    'PRE'                : elClass:= THTMLPreElement;
+    'BR'                 : elClass:= THTMLBRElement;
+    'BASEFONT'           : elClass:= THTMLBaseFontElement;
+    'FONT'               : elClass:= THTMLFontElement;
+    'HR'                 : elClass:= THTMLHRElement;
+    'MOD'                : elClass:= THTMLModElement;
+    'A'                  : elClass:= THTMLAnchorElement;
+    'IMG'                : elClass:= THTMLImageElement;
+    'OBJECT'             : elClass:= THTMLObjectElement;
+    'PARAM'              : elClass:= THTMLParamElement;
+    'APPLET'             : elClass:= THTMLAppletElement;
+    'MAP'                : elClass:= THTMLMapElement;
+    'AREA'               : elClass:= THTMLAreaElement;
+    'SCRIPT'             : elClass:= THTMLScriptElement;
+    'TABLE'              : elClass:= THTMLTableElement;
+    'CAPTION'            : elClass:= THTMLTableCaptionElement;
+  //'TABLECOL'           : elClass:= THTMLTableColElement;
+    'THEAD','TBODY',
+    'TFOOT'              : elClass:= THTMLTableSectionElement;
+    'TR'                 : elClass:= THTMLTableRowElement;
+    'TD','TH'            : elClass:= THTMLTableCellElement;
+    'FRAMESET'           : elClass:= THTMLFrameSetElement;
+    'FRAME'              : elClass:= THTMLFrameElement;
+    'IFRAME'             : elClass:= THTMLIFrameElement;
+  else
+    elClass:= THTMLElement;
+  end;
+  Result := THTMLElement(elClass.Create(Self));
   Result.FNSI.QName := FNames.FindOrAdd(DOMPChar(tagName), Length(tagName));
 end;
 
@@ -1259,87 +1242,19 @@ begin
   Result := FNames.FindOrAdd(DOMPChar(aName), Length(aName));
 end;
 
-function THTMLDocument.CreateSubElement: THTMLElement; begin Result := CreateElement('sub') end;
-function THTMLDocument.CreateSupElement: THTMLElement; begin Result := CreateElement('sup') end;
-function THTMLDocument.CreateSpanElement: THTMLElement; begin Result := CreateElement('span') end;
-function THTMLDocument.CreateBDOElement: THTMLElement; begin Result := CreateElement('bdo') end;
-function THTMLDocument.CreateTTElement: THTMLElement; begin Result := CreateElement('tt') end;
-function THTMLDocument.CreateIElement: THTMLElement; begin Result := CreateElement('i') end;
-function THTMLDocument.CreateBElement: THTMLElement; begin Result := CreateElement('b') end;
-function THTMLDocument.CreateUElement: THTMLElement; begin Result := CreateElement('u') end;
-function THTMLDocument.CreateSElement: THTMLElement; begin Result := CreateElement('s') end;
-function THTMLDocument.CreateStrikeElement: THTMLElement; begin Result := CreateElement('strike') end;
-function THTMLDocument.CreateBigElement: THTMLElement; begin Result := CreateElement('big') end;
-function THTMLDocument.CreateSmallElement: THTMLElement; begin Result := CreateElement('small') end;
-function THTMLDocument.CreateEmElement: THTMLElement; begin Result := CreateElement('em') end;
-function THTMLDocument.CreateStrongElement: THTMLElement; begin Result := CreateElement('strong') end;
-function THTMLDocument.CreateDfnElement: THTMLElement; begin Result := CreateElement('dfn') end;
-function THTMLDocument.CreateCodeElement: THTMLElement; begin Result := CreateElement('code') end;
-function THTMLDocument.CreateSampElement: THTMLElement; begin Result := CreateElement('samp') end;
-function THTMLDocument.CreateKbdElement: THTMLElement; begin Result := CreateElement('kbd') end;
-function THTMLDocument.CreateVarElement: THTMLElement; begin Result := CreateElement('var') end;
-function THTMLDocument.CreateCiteElement: THTMLElement; begin Result := CreateElement('cite') end;
-function THTMLDocument.CreateAcronymElement: THTMLElement; begin Result := CreateElement('acronym') end;
-function THTMLDocument.CreateAbbrElement: THTMLElement; begin Result := CreateElement('abbr') end;
-function THTMLDocument.CreateDDElement: THTMLElement; begin Result := CreateElement('dd') end;
-function THTMLDocument.CreateDTElement: THTMLElement; begin Result := CreateElement('dt') end;
-function THTMLDocument.CreateNoFramesElement: THTMLElement; begin Result := CreateElement('noframes') end;
-function THTMLDocument.CreateNoScriptElement: THTMLElement; begin Result := CreateElement('noscript') end;
-function THTMLDocument.CreateAddressElement: THTMLElement; begin Result := CreateElement('address') end;
-function THTMLDocument.CreateCenterElement: THTMLElement; begin Result := CreateElement('center') end;
-
 function THTMLDocument.CreateHtmlElement: THTMLHtmlElement;
 begin
-  Result := THTMLHtmlElement.Create(Self);
-  Result.FNSI.QName := HashForName('html');
+  Result:= CreateElement('HTML') as THTMLHtmlElement;
 end;
 
 function THTMLDocument.CreateHeadElement: THTMLHeadElement;
 begin
-  Result := THTMLHeadElement.Create(Self);
-  Result.FNSI.QName := HashForName('head');
-end;
-
-function THTMLDocument.CreateLinkElement: THTMLLinkElement;
-begin
-  Result := THTMLLinkElement.Create(Self);
-  Result.FNSI.QName := HashForName('a');
+  Result:= CreateElement('HEAD') as THTMLHeadElement;
 end;
 
 function THTMLDocument.CreateBodyElement: THTMLBodyElement;
 begin
-  Result := THTMLBodyElement.Create(Self);
-  Result.FNSI.QName := HashForName('body');
-end;
-
-function THTMLDocument.CreateUListElement: THTMLUListElement;
-begin
-  Result := THTMLUListElement.Create(Self);
-  Result.FNSI.QName := HashForName('ul');
-end;
-
-function THTMLDocument.CreateOListElement: THTMLOListElement;
-begin
-  Result := THTMLOListElement.Create(Self);
-  Result.FNSI.QName := HashForName('ol');
-end;
-
-function THTMLDocument.CreateDListElement: THTMLDListElement;
-begin
-  Result := THTMLDListElement.Create(Self);
-  Result.FNSI.QName := HashForName('dl');
-end;
-
-function THTMLDocument.CreateLIElement: THTMLLIElement;
-begin
-  Result := THTMLLIElement.Create(Self);
-  Result.FNSI.QName := HashForName('li');
-end;
-//...
-function THTMLDocument.CreateParagraphElement: THTMLParagraphElement;
-begin
-  Result := THTMLParagraphElement.Create(Self);
-  Result.FNSI.QName := HashForName('p');
+  Result:= CreateElement('BODY') as THTMLBodyElement;
 end;
 
 { THTMLFormElement }
-- 
2.12.0.windows.1

Martok

2017-08-23 13:46

reporter  

0003-Do-not-add-elements-that-have-no-children-to-the-ope.patch (1,351 bytes)
From 84ea557ffedd8d26f827a11cca075113b6e8a856 Mon Sep 17 00:00:00 2001
From: Martok <martok@martoks-place.de>
Date: Wed, 23 Aug 2017 13:34:30 +0200
Subject: [PATCH 3/3] Do not add elements that have no children to the open
 elements stack

Elements without efSubelementContent (or with Empty in W3C jargon) must
not be on the open tags stack, or they cause confusion when their parents
are closed.
---
 packages/fcl-xml/src/sax_html.pp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/packages/fcl-xml/src/sax_html.pp b/packages/fcl-xml/src/sax_html.pp
index 4096812499..75a8158a2a 100644
--- a/packages/fcl-xml/src/sax_html.pp
+++ b/packages/fcl-xml/src/sax_html.pp
@@ -553,6 +553,10 @@ begin
           AutoClose(TagName);
           namePush(TagName);
           DoStartElement('', TagName, '', Attr);
+          if not (efSubelementContent in HTMLElementProps[FStack[FNesting-1]].Flags) then begin
+            DoEndElement('', TagName, '');
+            NamePop;
+          end;
           if FStack[FNesting-1] in [etScript,etStyle] then
           begin
             NewContext := scScript;
@@ -668,6 +672,7 @@ begin
   NodeInfo := THTMLNodeInfo.Create;
   NodeInfo.NodeType := ntTag;
   NodeInfo.DOMNode := Element;
+  NodeInfo.Closed := false;
   if IsFragmentMode then
   begin
     if not FragmentRootSet then
-- 
2.12.0.windows.1

Michael Van Canneyt

2017-08-24 10:27

administrator   ~0102341

I have applied patches 1 and 3 as-is.
Patch 2, I modified, since it broke backwards compatibility.

Many thanks for the patches

Issue History

Date Modified Username Field Change
2017-08-23 13:45 Martok New Issue
2017-08-23 13:45 Martok File Added: 0001-Fix-compilation-of-test-project.patch
2017-08-23 13:45 Martok File Added: 0002-Make-THTMLDocument-create-appropriate-instance-of-TH.patch
2017-08-23 13:46 Martok File Added: 0003-Do-not-add-elements-that-have-no-children-to-the-ope.patch
2017-08-23 14:06 Michael Van Canneyt Assigned To => Michael Van Canneyt
2017-08-23 14:06 Michael Van Canneyt Status new => assigned
2017-08-24 10:27 Michael Van Canneyt Fixed in Revision => 37048
2017-08-24 10:27 Michael Van Canneyt Note Added: 0102341
2017-08-24 10:27 Michael Van Canneyt Status assigned => resolved
2017-08-24 10:27 Michael Van Canneyt Fixed in Version => 3.1.1
2017-08-24 10:27 Michael Van Canneyt Resolution open => fixed
2017-08-24 10:27 Michael Van Canneyt Target Version => 3.2.0
2017-08-24 17:21 Martok Status resolved => closed