2011/12/25 Bernd <prof7...@googlemail.com>:

> every scroll event. The next step should be to find out what exactly
> is going on during a scroll event that causes this to happen every
> time.

Its a bit complicated. It looks up not only the tag name but also
"tag:hover", "tag.class", ".class" and id. And then it merges them all
one after the other into the properties of this tag. And then after
merging these properties this function does something very strange: It
returns one of these 5 property objects back to the caller but it is
not clear which one and for what purpose and also it does not load
tagname.classname if it already has successfully loaded tagname and
other such strange things, very confusing.

I have therefore rewritten the LoadCSSProps() method from scratch and
also added a method to merge two TCSSProps into one (and then let
LoadCSSProps() return an obect with all CSS styles combined) and also
some caching of all these props objects to avoid all the lookups by
name.

The patch is not easy to read without applying because the old and the
new version of LoadCSSProps() has been interleaved with each other
every 5 lines although they do not have much in common.

This patch will probably break some things (or maybe also fix some old
bugs?) I cannot see any visual difference in the lhelp application.
Maybe the person who wrote all this should now say something before
this is blindly applied. This patch changes some of the control flow
and constitutes only my interpretation of what I believe
LoadCSSProps() was initially supposed to do. But the whole ipro
package is a *lot* of code and so it is quite possible that I
misunderstood parts of the code.

Bernd
Index: components/turbopower_ipro/ipcss.inc
===================================================================
--- components/turbopower_ipro/ipcss.inc	(Revision 34407)
+++ components/turbopower_ipro/ipcss.inc	(Arbeitskopie)
@@ -91,6 +91,7 @@
    constructor Create;
    destructor Destroy; override;
    procedure ReadCommands(ACommands: TStrings);
+   procedure MergeAdditionalProps(AProps: TCSSProps);
  end;
 
  { TCSSGlobalProps }
@@ -867,6 +868,39 @@
   end;
 end;
 
+procedure TCSSProps.MergeAdditionalProps(AProps: TCSSProps);
+begin
+  if AProps.Color <> -1 then Color := AProps.Color;
+  if AProps.BGColor <> -1 then BGColor := AProps.BGColor;
+  if AProps.Alignment <> haUnknown then Alignment := AProps.Alignment;
+  if AProps.Font.Name <> '' then Font.Name := AProps.Font.Name;
+  if AProps.Font.Size <> '' then Font.Size := AProps.Font.Size;
+  if AProps.Font.Style <> cfsNormal then Font.Style := AProps.Font.Style;
+  if AProps.Font.Weight <> cfwNormal then Font.Weight := AProps.Font.Weight;
+
+  if AProps.MarginBottom.Style <> cmsNone then
+    FMarginBottom.Style := AProps.MarginBottom.Style;
+  if AProps.MarginBottom.Size <> 0 then
+    FMarginBottom.Size := AProps.MarginBottom.Size;
+
+  if AProps.MarginLeft.Style <> cmsNone then
+    FMarginLeft.Style := AProps.MarginLeft.Style;
+  if AProps.MarginLeft.Size <> 0 then
+    FMarginLeft.Size := AProps.MarginLeft.Size;
+
+  if AProps.MarginRight.Style <> cmsNone then
+    FMarginRight.Style := AProps.MarginRight.Style;
+  if AProps.MarginRight.Size <> 0 then
+    FMarginRight.Size := AProps.MarginRight.Size;
+
+  if AProps.MarginTop.Style <> cmsNone then
+    FMarginTop.Style := AProps.MarginTop.Style;
+  if AProps.MarginTop.Size <> 0 then
+    FMarginTop.Size := AProps.MarginTop.Size;
+
+
+end;
+
 { TCSSGlobalProps }
 
 constructor TCSSGlobalProps.Create;
Index: components/turbopower_ipro/iphtml.pas
===================================================================
--- components/turbopower_ipro/iphtml.pas	(Revision 34407)
+++ components/turbopower_ipro/iphtml.pas	(Arbeitskopie)
@@ -1295,6 +1295,11 @@
     FCSS: TCSSProps;
     FElementName: String;
     //FCSSPropsLoaded: boolean;
+    FCacheCSSPropsMain: TCSSProps;
+    FCacheCSSPropsHover: TCSSProps;
+    FCacheCSSPropsClassOnly: TCSSProps;
+    FCacheCSSPropsNameAndClass: TCSSProps;
+    FCacheCSSPropsIDOnly: TCSSProps;
     {$ENDIF}
     FStyle: string;
     FClassId: string;
@@ -1303,9 +1308,14 @@
   protected
     procedure ParseBaseProps(aOwner : TIpHtml); {virtual;}              {!!.12}
     {$IFDEF IP_LAZARUS}
+    function GetCachingCSSPropsMain: TCSSProps;
+    function GetCachingCSSPropsHover: TCSSProps;
+    function GetCachingCSSPropsClassOnly: TCSSProps;
+    function GetCachingCSSPropsNameAndClass: TCSSProps;
+    function GetCachingCSSPropsIDOnly: TCSSProps;
     function SelectCSSFont(const aFont: string): string;
     procedure ApplyCSSProps(const Element: TCSSProps; const props: TIpHtmlProps);
-    procedure LoadCSSProps(aOwner : TIpHtml; var Element: TCSSProps; const Props: TIpHtmlProps); virtual;
+    procedure LoadCSSProps(var Element: TCSSProps); virtual;
     function ElementName: String;
     function GetFontSizeFromCSS(CurrentFontSize:Integer; aFontSize: string):Integer;
     {$ENDIF}
@@ -1407,7 +1417,7 @@
     procedure SetBgColor(const AValue: TColor);
     procedure SetTextColor(const AValue: TColor);
     {$IFDEF IP_LAZARUS}
-    procedure LoadCSSProps(Owner : TIpHtml; var Element: TCSSProps; const Props: TIpHtmlProps); override;
+    procedure LoadCSSProps(var Element: TCSSProps); override;
     {$ENDIF}
   public
     constructor Create(ParentNode : TIpHtmlNode);
@@ -1661,7 +1671,7 @@
     BGPicture : TPicture;
     procedure Render(const RenderProps: TIpHtmlProps); override;
     {$IFDEF IP_LAZARUS}
-    procedure LoadCSSProps(Owner : TIpHtml; var Element: TCSSProps; const Props: TIpHtmlProps); override;
+    procedure LoadCSSProps(var Element: TCSSProps); override;
     {$ENDIF}
   public
     constructor Create(ParentNode : TIpHtmlNode);
@@ -2284,7 +2294,7 @@
     procedure WidthChanged(Sender: TObject);                           {!!.10}
     function ExpParentWidth: Integer; override;                        {!!.10}
     {$IFDEF IP_LAZARUS}
-    procedure LoadCSSProps(Owner : TIpHtml; var Element: TCSSProps; const Props: TIpHtmlProps); override;
+    procedure LoadCSSProps(var Element: TCSSProps); override;
     {$ENDIF}
   public
     constructor Create(ParentNode : TIpHtmlNode);
@@ -5110,7 +5120,7 @@
   Props.Assign(RenderProps);
   {$IFDEF IP_LAZARUS}
   if Self.InheritsFrom(TIpHtmlNodeCore)then
-    TIpHtmlNodeCore(Self).LoadCSSProps(Owner, Elem, Props);
+    TIpHtmlNodeCore(Self).LoadCSSProps(Elem);
   {$ENDIF}
 //DebugLn(ClassName, ':', FParentNode.className, ':', IntToStr(RenderProps.BgColor));
 //  Inc(DebugParseLevel);
@@ -5276,12 +5286,12 @@
 end;
 
 {$IFDEF IP_LAZARUS}
-procedure TIpHtmlNodeBODY.LoadCSSProps(Owner: TIpHtml; var Element: TCSSProps; const Props: TIpHtmlProps);
+procedure TIpHtmlNodeBODY.LoadCSSProps(var Element: TCSSProps);
 var
   LinkElement: TCSSProps;
 begin
   Props.DelayCache := True;
-  inherited LoadCSSProps(Owner, Element, Props);
+  inherited LoadCSSProps(Element);
   LinkElement := Owner.CSS.GetElement('a:link', '');
   if (LinkElement <> nil) and (LinkElement.Color <> -1) then
     Link := LinkElement.Color;
@@ -7329,7 +7339,7 @@
           CurRow.ParseBaseProps(Self);
           CurRow.Align := ParseAlignment;
           CurRow.VAlign := ParseVAlignment;
-          CurRow.LoadCSSProps(CurRow.Owner, Element, CurRow.Props);
+          CurRow.LoadCSSProps(Element);
           NextRealToken;
           ParseTableRow(CurRow,
                         EndTokens + [IpHtmlTagTRend, IpHtmlTagTR] -
@@ -8339,7 +8349,7 @@
       Background := FindAttribute(htmlAttrBACKGROUND);
       ParseBaseProps(Self);
       {$IFDEF IP_LAZARUS}
-      LoadCSSProps(Owner, Element, props);
+      LoadCSSProps(Element);
       {$ENDIF}
     end;
 
@@ -8357,7 +8367,7 @@
       with TIpHtmlNodeHtml(Parent) do begin
         with TIpHtmlNodeBODY.Create(Parent) do
           {$IFDEF IP_LAZARUS}
-          LoadCSSProps(Owner, Element, props)
+          LoadCSSProps(Element);
           {$ENDIF};
 
         { Make each of FHtml's current children the children of the
@@ -10249,7 +10259,7 @@
   if not RenderProps.IsEqualTo(Props) then
   begin
     Props.Assign(RenderProps);
-    LoadCSSProps(Owner, Elem, Props);
+    LoadCSSProps(Elem);
     SetProps(Props);
   end;
   if ElementQueue.Count = 0 then
@@ -10297,10 +10307,9 @@
   end;
 end;
 
-procedure TIpHtmlNodeBlock.LoadCSSProps(Owner: TIpHtml; var Element: TCSSProps;
-  const Props: TIpHtmlProps);
+procedure TIpHtmlNodeBlock.LoadCSSProps(var Element: TCSSProps);
 begin
-  inherited LoadCSSProps(Owner, Element, Props);
+  inherited LoadCSSProps(Element);
   if Element = nil then
     exit;
 
@@ -10563,7 +10572,7 @@
     Exit;
   end;
   Props.Assign(RenderProps);
-  LoadCSSProps(Owner, Elem, Props);
+  LoadCSSProps(Elem);
   SetProps(Props);
   if ElementQueue.Count = 0 then
     Enqueue;
@@ -10617,7 +10626,7 @@
   if not RenderProps.IsEqualTo(Props) then
   begin
     Props.Assign(RenderProps);
-    LoadCSSProps(Owner, Elem, Props);
+    LoadCSSProps(Elem);
     SetProps(Props);
   end;
   if ElementQueue.Count = 0 then
@@ -12342,7 +12351,7 @@
   Props.Assign(RenderProps);
   Props.Alignment := Align;
   {$IFDEF IP_LAZARUS}
-  LoadCSSProps(Owner, Elem, Props);
+  LoadCSSProps(Elem);
   {$ENDIF}
   inherited SetProps(Props);
 end;
@@ -12380,7 +12389,7 @@
   Props.DelayCache:=True;
   Props.Alignment := Align;
   {$IFDEF IP_LAZARUS}
-  LoadCSSProps(Owner, Elem, Props);
+  LoadCSSProps(Elem);
   {$ENDIF}
   Props.DelayCache:=False;
 end;
@@ -14026,10 +14035,9 @@
 end;
 
 {$IFDEF IP_LAZARUS}
-procedure TIpHtmlNodeTABLE.LoadCSSProps(Owner: TIpHtml; var Element: TCSSProps;
-  const Props: TIpHtmlProps);
+procedure TIpHtmlNodeTABLE.LoadCSSProps(var Element: TCSSProps);
 begin
-  inherited LoadCSSProps(Owner, Element, Props);
+  inherited LoadCSSProps(Element);
   if Element = nil then
     exit;
 //  if Element.BGColor <> -1 then
@@ -15739,6 +15747,41 @@
 
 { TIpHtmlNodeCore }
 
+function TIpHtmlNodeCore.GetCachingCSSPropsMain: TCSSProps;
+begin
+  if FCacheCSSPropsMain = nil then
+    FCacheCSSPropsMain := Owner.CSS.GetElement(ElementName, '');
+  Result := FCacheCSSPropsMain;
+end;
+
+function TIpHtmlNodeCore.GetCachingCSSPropsHover: TCSSProps;
+begin
+  if FCacheCSSPropsHover = nil then
+    FCacheCSSPropsHover := Owner.CSS.GetElement(ElementName + ':hover', '');
+  Result := FCacheCSSPropsHover;
+end;
+
+function TIpHtmlNodeCore.GetCachingCSSPropsClassOnly: TCSSProps;
+begin
+  if FCacheCSSPropsClassOnly = nil then
+    FCacheCSSPropsClassOnly := Owner.CSS.GetElement('', ClassId);
+  Result := FCacheCSSPropsClassOnly;
+end;
+
+function TIpHtmlNodeCore.GetCachingCSSPropsNameAndClass: TCSSProps;
+begin
+  if FCacheCSSPropsNameAndClass = nil then
+    FCacheCSSPropsNameAndClass := Owner.CSS.GetElement(ElementName, ClassId);
+  Result := FCacheCSSPropsNameAndClass;
+end;
+
+function TIpHtmlNodeCore.GetCachingCSSPropsIDOnly: TCSSProps;
+begin
+  if FCacheCSSPropsIDOnly = nil then
+    FCacheCSSPropsIDOnly := Owner.CSS.GetElement(Id);
+  Result := FCacheCSSPropsIDOnly;
+end;
+
 procedure TIpHtmlNodeCore.ParseBaseProps(aOwner : TIpHtml);
 {$IFDEF IP_LAZARUS}
 var
@@ -15764,74 +15807,72 @@
 end;
 
 {$IFDEF IP_LAZARUS}
-procedure TIpHtmlNodeCore.LoadCSSProps(aOwner: TIpHtml; var Element: TCSSProps; const Props: TIpHtmlProps);
+procedure TIpHtmlNodeCore.LoadCSSProps(var Element: TCSSProps);
+{$note rename this "Element" variable to something more meaningful}
 var
-  TmpElement, Hover: TCSSProps;
+  TempProps: TCSSProps;
+  MustFree: Boolean = False;
+
 begin
-  if aOwner.CSS = nil then
-    exit;
-  {
-  WriteLn('FCSSPropsLoaded=',TIpHtmlNodeCore(Self).FCSSPropsLoaded);
-  if FCSSPropsLoaded then
-    exit;
-  FCSSPropsLoaded:=True;
-  }
-  Props.DelayCache:=True;
-  TmpElement := Element;
-  if Element = nil then
+  if Element = nil then begin
+    {$note why is this sometimes called with Element=nil? Fix this!}
+    Element := TCSSProps.Create;
+    MustFree := True;
+  end;
+
+  if Owner.CSS <> nil then
   begin
+    // stypes for all tags with this name
+    TempProps := GetCachingCSSPropsMain; // Owner.CSS.GetElement(ElementName, '');
+    if TempProps <> nil then
+      Element.MergeAdditionalProps(TempProps);
 
-    // process first the Main element
-    Element := aOwner.CSS.GetElement(ElementName, '');
-    if Element <> nil then begin
-      ApplyCSSProps(Element, Props);
+    // styles for tagname:hover
+    TempProps := GetCachingCSSPropsHover; // Owner.CSS.GetElement(ElementName + ':hover', '');
+    if TempProps <> nil then
+    begin
+      Props.DelayCache := True;
+      if TempProps.Color <> -1 then
+        Props.HoverColor := TempProps.Color;
+      if TempProps.BgColor <> -1 then
+        Props.HoverBgColor := TempProps.BgColor;
+      Props.DelayCache:=False;
     end;
 
-    // process Main element hover
-    Hover := aOwner.CSS.GetElement(ElementName + ':hover', '');
-    if Hover <> nil then begin
-      Props.DelayCache:=True;
-      if Hover.Color <> -1 then
-        Props.HoverColor := Hover.Color;
-      if Hover.BgColor <> -1 then
-        Props.HoverBgColor := Hover.BgColor;
-      Props.DelayCache:=False;
-      //ApplyCSSProps(Element, Props);
+    if ClassID <> '' then
+    begin
+      // styles for .class
+      TempProps := GetCachingCSSPropsClassOnly; // Owner.CSS.GetElement(ClassId, '');
+      if TempProps <> nil then
+        Element.MergeAdditionalProps(TempProps);
+
+      // styles for tagname.class
+      TempProps := GetCachingCSSPropsNameAndClass; // Owner.CSS.GetElement(ElementName, ClassId);
+      if TempProps <> nil then
+        Element.MergeAdditionalProps(TempProps);
     end;
 
-    // load the .class if there is one
-    if ClassID<>'' then begin
-      Element := Owner.CSS.GetElement('', ClassId);
-      if Element <> nil then begin
-        ApplyCSSProps(Element, Props);
-      end;
+    if Id <> '' then
+    begin
+      // styles for this ID
+      TempProps := GetCachingCSSPropsIDOnly; // Owner.CSS.GetElement(Id);
+      if TempProps <> nil then
+        Element.MergeAdditionalProps(TempProps);
     end;
-    
-    // then load the element + class if there is one
-    if (Element=nil)and(ClassID<>'') then begin
-      Element := Owner.CSS.GetElement(ElementName, ClassId);
-      if Element=nil then
-      else begin
-        ApplyCSSProps(Element, Props);
-      end;
-    end;
-    
   end;
-  
-  if TmpElement = nil then
-  begin
-    // lookup id elements
-    TmpElement := aOwner.CSS.GetElement(Id);
-    if TmpElement <> nil then begin
-      ApplyCSSProps(TmpElement, Props);
-    end;
-    // lookup local elements for this tag, not from the stylesheet
-    TmpElement := CSS;
-    if TmpElement <> nil then begin
-      ApplyCSSProps(TmpElement, Props);
-    end;
-  end;
+
+  // inline styles
+  TempProps := CSS;
+  if TempProps <> nil then
+    Element.MergeAdditionalProps(TempProps);
+
+  Props.DelayCache:=True;
+  ApplyCSSProps(Element, Props);
   Props.DelayCache:=False;
+
+  if MustFree then
+    // we got nil, so we return nil.
+    FreeAndNil(Element);
 end;
 
 function TIpHtmlNodeCore.SelectCSSFont(const aFont: string): string;
@@ -16925,7 +16966,7 @@
   Props.Assign(RenderProps);
   Props.DelayCache:=True;
   {$IFDEF IP_LAZARUS}
-  LoadCSSProps(Owner, Elem, Props);
+  LoadCSSProps(Elem);
   {$ENDIF}
 //DebugLn('td :', IntToStr(Integer(Props.Alignment)));
   if BgColor <> -1 then
@@ -17109,7 +17150,7 @@
 begin
    result := false;
    {$IFDEF IP_LAZARUS}
-   LoadCSSProps(Owner, Elem, Props);
+   LoadCSSProps(Elem);
    if (props.FontSize <> -1) then
      FControl.Font.Size:= Props.FontSize;
      if Props.FontColor <> -1 then
@@ -17128,7 +17169,7 @@
 begin
   Props.Assign(RenderProps);
   {$IFDEF IP_LAZARUS}
-  LoadCSSProps(Owner, Elem, Props);
+  LoadCSSProps(Elem);
   {$ENDIF}
 end;
 
--
_______________________________________________
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to