Explorar o código

dom: flex: started grow

mattias hai 11 meses
pai
achega
bd34d2e864

+ 9 - 0
src/base/fcl-css/fpcssresparser.pas

@@ -539,6 +539,7 @@ type
     CurValue: TCSSString;
     CurComp: TCSSResCompValue;
     function InitParseAttr(Desc: TCSSAttributeDesc; AttrData: TCSSAttributeKeyData; const Value: TCSSString): boolean; virtual; // true if parsing can start
+    procedure InitParseAttr(const Value: TCSSString); virtual;
     // check whole attribute, skipping invalid values, emit warnings:
     function CheckAttribute_Keyword(const AllowedKeywordIDs: TCSSNumericalIDArray): boolean; virtual;
     function CheckAttribute_CommaList_Keyword(const AllowedKeywordIDs: TCSSNumericalIDArray): boolean; virtual;
@@ -1485,6 +1486,14 @@ begin
   Result:=true;
 end;
 
+procedure TCSSBaseResolver.InitParseAttr(const Value: TCSSString);
+begin
+  CurValue:=Value;
+  CurComp:=Default(TCSSResCompValue);
+  CurComp.EndP:=PCSSChar(CurValue);
+  ReadNext;
+end;
+
 function TCSSBaseResolver.CheckAttribute_Keyword(const AllowedKeywordIDs: TCSSNumericalIDArray
   ): boolean;
 begin

+ 173 - 1
src/base/fresnel.dom.pas

@@ -1092,6 +1092,12 @@ type
     function GetComputedBorderRadius(Corner: TFresnelCSSCorner): TFresnelPoint; virtual; // on fail returns 0
     function GetComputedColor(Attr: TFresnelCSSAttribute; const CurrentColor: TFPColor): TFPColor; virtual; // on fail returns transparent
     function GetComputedKeyword(Attr: TFresnelCSSAttribute; const AllowedKeywords: TCSSNumericalIDArray): TCSSNumericalID; virtual;
+    function GetComputedJustifyContent(out SubKW: TCSSNumericalID): TCSSNumericalID; virtual;
+    function GetComputedJustifyItems(out SubKW: TCSSNumericalID): TCSSNumericalID; virtual;
+    function GetComputedJustifySelf(out SubKW: TCSSNumericalID): TCSSNumericalID; virtual;
+    function GetComputedAlignContent(out SubKW: TCSSNumericalID): TCSSNumericalID; virtual;
+    function GetComputedAlignItems(out SubKW: TCSSNumericalID): TCSSNumericalID; virtual;
+    function GetComputedAlignSelf(out SubKW: TCSSNumericalID): TCSSNumericalID; virtual;
     procedure GetComputedMarginBlockStartEndAttr(out aStartAttr, aEndAttr: TFresnelCSSAttribute); virtual;
     procedure GetComputedMarginInlineStartEndAttr(out aStartAttr, aEndAttr: TFresnelCSSAttribute); virtual;
     function GetComputedTextShadow(out aOffsetX, aOffsetY, aRadius: TFresnelLength; out aColor: TFPColor): boolean; virtual; // on fail returns 0
@@ -1124,6 +1130,7 @@ type
     function GetPreferredBorderBox_MaxWidth(MaxWidth: TFresnelLength): TFresnelPoint; virtual; // this element, excluding children, cannot be NaN
     function GetBlockContainer: TFresnelElement; virtual;
     function GetBlockContainerWH(IsHorizontal: boolean; UseNaNOnFail: boolean): TFresnelLength; virtual;
+    function IsBlockFormattingContext: boolean; virtual;
     property DOMIndex: integer read FDOMIndex write FDOMIndex;
     property LayoutNode: TFresnelLayoutNode read FLayoutNode write FLayoutNode;
     // renderer
@@ -6509,7 +6516,40 @@ end;
 
 function TFresnelElement.GetBlockContainer: TFresnelElement;
 begin
-  Result:=Parent;
+  case ComputedPosition of
+  CSSRegistry.kwAbsolute:
+    begin
+      // the containing block is nearest ancestor element that has a position value other than static
+      Result:=Parent;
+      while (Result<>nil) do
+      begin
+        if not (Result.ComputedPosition in [CSSRegistry.kwStatic,CSSIDNone]) then
+          exit;
+        // Note:check for transform<>'none'
+        Result:=Result.Parent;
+      end;
+      Result:=Viewport;
+    end;
+  CSSRegistry.kwFixed:
+    begin
+      // viewport
+      Result:=Viewport;
+    end;
+  else
+    // static, relative, sticky
+    // the containing block is the nearest ancestor element that is either a
+    // block container (such as an inline-block, block, or list-item element)
+    // or establishes a formatting context (such as a table container,
+    // flex container, grid container, or the block container itself)
+    Result:=Parent;
+    while (Result<>nil) do
+    begin
+      if Result.IsBlockFormattingContext then
+        exit;
+      Result:=Result.Parent;
+    end;
+    Result:=Viewport;
+  end;
 end;
 
 function TFresnelElement.GetBlockContainerWH(IsHorizontal: boolean; UseNaNOnFail: boolean
@@ -6533,6 +6573,54 @@ begin
   end;
 end;
 
+function TFresnelElement.IsBlockFormattingContext: boolean;
+// BFC
+// contain internal and external floats
+// surpress margin collapsing
+var
+  aOverflow, aFloat: String;
+begin
+  if Parent=nil then
+    exit(true);
+
+  case ComputedPosition of
+  CSSRegistry.kwAbsolute,
+  CSSRegistry.kwFixed:
+    exit(true);
+  end;
+
+  if ComputedDisplayOutside in [CSSIDNone,CSSRegistry.kwNone] then
+    exit(false);
+
+  case ComputedDisplayOutside of
+  CSSRegistry.kwBlock: exit(true);
+  end;
+
+  case ComputedDisplayInside of
+  //CSSRegistry.kwtable,
+  CSSRegistry.kwFlex,
+  CSSRegistry.kwGrid,
+  //CSSRegistry.kwRuby,
+  CSSRegistry.kwFlowRoot:
+    exit(true);
+  end;
+
+  aOverflow:=ComputedAttribute[fcaOverflow];
+  case aOverflow of
+  'visible',
+  'clip': exit(true);
+  end;
+
+  aFloat:=ComputedAttribute[fcaFloat];
+  case aFloat of
+  '', 'none': ;
+  else
+    exit(true);
+  end;
+
+  Result:=false;
+end;
+
 function TFresnelElement.GetBoundingClientRect: TFresnelRect;
 var
   Node: TFresnelLayoutNode;
@@ -6660,6 +6748,90 @@ begin
   Result:=GetComputedCSSKeyword(CSSRegistry.FresnelAttrs[Attr].Index,AllowedKeywords);
 end;
 
+function TFresnelElement.GetComputedJustifyContent(out SubKW: TCSSNumericalID
+  ): TCSSNumericalID;
+var
+  s: String;
+begin
+  s:=GetComputedString(fcaJustifyContent);
+  Resolver.InitParseAttr(s);
+  if not CSSRegistry.ReadJustifyContent(Resolver,false,Result,SubKW) then
+  begin
+    Result:=0;
+    SubKW:=0;
+  end;
+end;
+
+function TFresnelElement.GetComputedJustifyItems(out SubKW: TCSSNumericalID
+  ): TCSSNumericalID;
+var
+  s: String;
+begin
+  s:=GetComputedString(fcaJustifyItems);
+  Resolver.InitParseAttr(s);
+  if not CSSRegistry.ReadJustifyItems(Resolver,false,Result,SubKW) then
+  begin
+    Result:=0;
+    SubKW:=0;
+  end;
+end;
+
+function TFresnelElement.GetComputedJustifySelf(out SubKW: TCSSNumericalID
+  ): TCSSNumericalID;
+var
+  s: String;
+begin
+  s:=GetComputedString(fcaJustifySelf);
+  Resolver.InitParseAttr(s);
+  if not CSSRegistry.ReadJustifySelf(Resolver,false,Result,SubKW) then
+  begin
+    Result:=0;
+    SubKW:=0;
+  end;
+end;
+
+function TFresnelElement.GetComputedAlignContent(out SubKW: TCSSNumericalID
+  ): TCSSNumericalID;
+var
+  s: String;
+begin
+  s:=GetComputedString(fcaAlignContent);
+  Resolver.InitParseAttr(s);
+  if not CSSRegistry.ReadAlignContent(Resolver,false,Result,SubKW) then
+  begin
+    Result:=0;
+    SubKW:=0;
+  end;
+end;
+
+function TFresnelElement.GetComputedAlignItems(out SubKW: TCSSNumericalID
+  ): TCSSNumericalID;
+var
+  s: String;
+begin
+  s:=GetComputedString(fcaAlignItems);
+  Resolver.InitParseAttr(s);
+  if not CSSRegistry.ReadAlignItems(Resolver,false,Result,SubKW) then
+  begin
+    Result:=0;
+    SubKW:=0;
+  end;
+end;
+
+function TFresnelElement.GetComputedAlignSelf(out SubKW: TCSSNumericalID
+  ): TCSSNumericalID;
+var
+  s: String;
+begin
+  s:=GetComputedString(fcaAlignSelf);
+  Resolver.InitParseAttr(s);
+  if not CSSRegistry.ReadAlignSelf(Resolver,false,Result,SubKW) then
+  begin
+    Result:=0;
+    SubKW:=0;
+  end;
+end;
+
 procedure TFresnelElement.GetComputedMarginBlockStartEndAttr(out aStartAttr,
   aEndAttr: TFresnelCSSAttribute);
 begin

+ 479 - 184
src/base/fresnel.layouter.pas

@@ -79,9 +79,11 @@ type
 
       { TBFCNode - block formatting context node }
 
-      TLineNode = class
+      TLineItem = class
       public
         Node: TSimpleFresnelLayoutNode;
+
+        // computed CSS attributes
         BorderLeft: TFresnelLength;
         BorderRight: TFresnelLength;
         BorderTop: TFresnelLength;
@@ -94,23 +96,34 @@ type
         MarginRight: TFresnelLength;
         MarginTop: TFresnelLength;
         MarginBottom: TFresnelLength;
+
+        // content-boxed:
+        Width: TFresnelLength;
+        Height: TFresnelLength;
+        MinWidth: TFresnelLength;
+        MinHeight: TFresnelLength;
+        MaxWidth: TFresnelLength;
+        MaxHeight: TFresnelLength;
+
+        // computed layout
         BorderBox: TFresnelRect; // left, top, right, bottom
         ContentBoxWidth: TFresnelLength;
         ContentBoxHeight: TFresnelLength;
       end;
-      TLineNodeClass = class of TLineNode;
+      TLineItemClass = class of TLineItem;
 
   protected
-    FLineNodes: TFPList; // list of TLineNode
+    FLineItems: TFPList; // list of TLineItem
     Border: TFresnelRect;
     BoxSizing: TCSSNumericalID;
     Padding: TFresnelRect;
     ContentHeight: TFresnelLength;
     ContentWidth: TFresnelLength;
-    procedure PlaceLineNodes; virtual;
-    procedure PlaceAbsoluteNode(ChildNode: TSimpleFresnelLayoutNode); virtual;
-    procedure ClearLineNodes; virtual;
-    function AddLineNode(ChildNode: TSimpleFresnelLayoutNode; NodeClass: TLineNodeClass): TLineNode; virtual;
+    procedure PlaceLineItems; virtual;
+    procedure PlaceAbsoluteItem(ChildNode: TSimpleFresnelLayoutNode); virtual;
+    procedure ClearLineItems; virtual;
+    function AddLineItem(ChildNode: TSimpleFresnelLayoutNode; NodeClass: TLineItemClass): TLineItem; virtual;
+    procedure ComputeChildAttributes(Item: TLineItem; El: TFresnelElement); virtual;
   public
     destructor Destroy; override;
     procedure Init; override;
@@ -122,9 +135,9 @@ type
   protected
     type
 
-      { TBFCNode - block formatting context node }
+      { TBFCItem - block formatting context }
 
-      TBFCNode = class(TLineNode)
+      TBFCItem = class(TLineItem)
       public
       end;
 
@@ -132,8 +145,8 @@ type
     FBorderBox: TFresnelPoint; // including padding+border, invalid if X<0
     FContentSizeMaxWidth: TFresnelLength;
     // current line
-    FFirstLineNodeIndex: integer;
-    FLastLineNodeIndex: integer;
+    FFirstLineIndex: integer;
+    FLastLineIndex: integer;
     FLineBorderBoxHeight: TFresnelLength;
     FLineBorderBoxLeft: TFresnelLength; // border box of last element relative to parent ContentBox
     FLineBorderBoxRight: TFresnelLength;
@@ -147,7 +160,7 @@ type
     FLastLineMarginBottom: TFresnelLength;
     procedure EndLine(Commit: boolean); virtual;
     procedure StartLine; virtual;
-    procedure PlaceLineNodes; override;
+    procedure PlaceLineItems; override;
   public
     constructor Create(AOwner: TComponent); override;
     procedure Apply; override;
@@ -173,18 +186,27 @@ type
   protected
     type
 
-      { TFlexNode }
+      { TFlexItem }
 
-      TFlexNode = class(TLineNode)
+      TFlexItem = class(TLineItem)
       public
+        Basis: TFresnelLength;
+        Grow: TFresnelLength;
+        Shrink: TFresnelLength;
+        CurMainContentSize: TFresnelLength;
       end;
 
   protected
     FlexDirection: TCSSNumericalID;
     FlexWrap: TCSSNumericalID;
+    JustifyContent, JustifyContentSub: TCSSNumericalID;
+    AlignItems, AlignItemsSub: TCSSNumericalID;
     procedure EndLine(Commit: boolean); virtual;
     procedure StartLine; virtual;
-    procedure PlaceLineNodes; override;
+    procedure FlexLineMainDirection(MaxMainSize, MainGap: TFresnelLength); virtual;
+    procedure FlexLineCrossDirection; virtual;
+    procedure PlaceLineItems; override;
+    procedure ComputeChildAttributes(Item: TLineItem; El: TFresnelElement); override;
   public
     procedure Apply; override;
     procedure Init; override;
@@ -206,8 +228,6 @@ type
   public
     constructor Create(AOwner: TComponent); override;
     procedure Apply(aViewport: TFresnelViewport); override;
-    function NeedBlockFormattingContext(El: TFresnelElement): boolean; virtual;
-    function GetBlockContainer(El: TFresnelElement): TFresnelElement; virtual;
     procedure UpdateLayouter(El: TFresnelElement; LNode: TSimpleFresnelLayoutNode); virtual;
     procedure UpdateLayoutParent(El: TFresnelElement; LNode: TSimpleFresnelLayoutNode); virtual;
     procedure ComputeCSSLayoutNode(El: TFresnelElement); override; // called after basic CSS properties were computed, create the layout nodes
@@ -282,7 +302,7 @@ end;
 
 procedure TFLBlockFormattingContext.EndLine(Commit: boolean);
 begin
-  if FFirstLineNodeIndex<0 then
+  if FFirstLineIndex<0 then
   begin
     // line empty
     exit;
@@ -297,8 +317,8 @@ begin
   //  writeln('TFLBlockFormattingContext.EndLine ',Node.Element.GetPath,' FBorderBox=',FloatToStr(FBorderBox.X),',',FloatToStr(FBorderBox.Y),' FLineBorderBox=r=',FloatToStr(FLineBorderBoxRight),',b=',FloatToStr(FLineBorderBoxBottom),' FLineMargin=r=',FloatToStr(FLineMarginRight),',b=',FloatToStr(FLineMarginBottom),' Pad=r=',FloatToStr(FPaddingRight),',b=',FloatToStr(FPaddingBottom),' BorderWid=r=',FloatToStr(FBorderRight),',b=',FloatToStr(FBorderBottom));
 
   if Commit then
-    PlaceLineNodes;
-  ClearLineNodes;
+    PlaceLineItems;
+  ClearLineItems;
 
   FLastLineBorderBoxBottom:=FLineBorderBoxBottom;
   FLastLineMarginBottom:=FLineMarginBottom;
@@ -307,8 +327,8 @@ end;
 
 procedure TFLBlockFormattingContext.StartLine;
 begin
-  FFirstLineNodeIndex:=-1;
-  FLastLineNodeIndex:=-1;
+  FFirstLineIndex:=-1;
+  FLastLineIndex:=-1;
   FLineBorderBoxHeight:=0;
   FLineBorderBoxLeft:=0;
   FLineBorderBoxRight:=FLineBorderBoxLeft;
@@ -319,16 +339,16 @@ begin
   FLineMarginBottom:=0;
 end;
 
-procedure TFLBlockFormattingContext.PlaceLineNodes;
+procedure TFLBlockFormattingContext.PlaceLineItems;
 var
-  BFCNode: TBFCNode;
+  BFCNode: TBFCItem;
   //ChildNode: TSimpleFresnelLayoutNode;
   //ChildEl: TFresnelElement;
   i: Integer;
 begin
-  for i:=0 to FLineNodes.Count-1 do
+  for i:=0 to FLineItems.Count-1 do
   begin
-    BFCNode:=TBFCNode(FLineNodes[i]);
+    BFCNode:=TBFCItem(FLineItems[i]);
     //ChildNode:=BFCNode.Node;
     //ChildEl:=ChildNode.Element;
 
@@ -417,10 +437,10 @@ var
 
   procedure AddLineNodeCache;
   var
-    N: TBFCNode;
+    N: TBFCItem;
   begin
     FLLog(etDebug,['AddLineNodeCache ',ChildEl.GetPath,' L=',FloatToStr(ChildLeft),',R=',FloatToStr(ChildRight),',W=',FloatToStr(ChildWidth),',H=',FloatToStr(ChildHeight)]);
-    N:=TBFCNode(AddLineNode(ChildNode,TBFCNode));
+    N:=TBFCItem(AddLineItem(ChildNode,TBFCItem));
     N.BorderLeft:=ChildBorderLeft;
     N.BorderRight:=ChildBorderRight;
     N.BorderTop:=ChildBorderTop;
@@ -466,7 +486,8 @@ begin
     //writeln('TFLBlockFormattingContext.ComputeLayoutBorderBox ',ChildEl.GetPath);
 
     // skip hidden
-    if ChildEl.ComputedVisibility=CSSRegistry.kwCollapse then
+    if (ChildEl.ComputedVisibility=CSSRegistry.kwCollapse)
+        or (ChildEl.ComputedDisplayOutside=CSSIDNone) then
     begin
       inc(NodeIndex);
       continue;
@@ -477,7 +498,7 @@ begin
     CSSRegistry.kwStatic,CSSRegistry.kwRelative,CSSRegistry.kwSticky: ;
     else
       if Commit then
-        PlaceAbsoluteNode(ChildNode);
+        PlaceAbsoluteItem(ChildNode);
       inc(NodeIndex);
       continue;
     end;
@@ -489,7 +510,7 @@ begin
     else
       // block -> end line, put element on a line of its own
       IsInline:=false;
-      if FFirstLineNodeIndex>=0 then
+      if FFirstLineIndex>=0 then
       begin
         EndLine(Commit);
         StartLine;
@@ -592,7 +613,7 @@ begin
     end;
 
     NewChildRight:=0;
-    if (FFirstLineNodeIndex>=0) and IsInline then
+    if (FFirstLineIndex>=0) and IsInline then
     begin
       // check if inline element fits in line
       NewChildRight:=FLineBorderBoxRight
@@ -608,11 +629,11 @@ begin
     end;
 
     //debugln(['TFLBlockFormattingContext.ComputeLayoutBorderBox ',ChildEl.Name,' ',ChildHeight,':=BT ',ChildBorderTop,'+PT ',ChildPaddingTop,'+H ',ChildHeight,'+PB ',ChildPaddingBottom,'+BB ',ChildBorderBottom]);
-    if FFirstLineNodeIndex<0 then
+    if FFirstLineIndex<0 then
     begin
       // first element in line
-      FFirstLineNodeIndex:=NodeIndex;
-      FLastLineNodeIndex:=NodeIndex;
+      FFirstLineIndex:=NodeIndex;
+      FLastLineIndex:=NodeIndex;
 
       FLineMarginLeft:=ChildMarginLeft;
       FLineMarginRight:=ChildMarginRight;
@@ -645,7 +666,7 @@ begin
       end;
     end else begin
       // append element to line
-      FLastLineNodeIndex:=NodeIndex;
+      FLastLineIndex:=NodeIndex;
 
       ChildLeft:=FLineBorderBoxRight
                  +Max(FLineMarginRight,ChildMarginLeft) // margin collapsing
@@ -695,12 +716,152 @@ begin
 
 end;
 
-procedure TFLFlexLayouter.PlaceLineNodes;
+procedure TFLFlexLayouter.FlexLineMainDirection(MaxMainSize,
+  MainGap: TFresnelLength);
+const
+  MinAdjust = 0.005;
+var
+  CurMainSize, Dist, SumGrow, SumShrink, NewMainSize: TFresnelLength;
+  i: Integer;
+  Item: TFlexItem;
+begin
+  for i:=0 to FLineItems.Count-1 do
+  begin
+    Item:=TFlexItem(FLineItems[i]);
+    Item.CurMainContentSize:=Item.Basis;
+  end;
+  if not IsNan(MaxMainSize) then
+  begin
+    repeat
+      // compute difference between current size and max size
+      CurMainSize:=0;
+      for i:=0 to FLineItems.Count-1 do
+      begin
+        Item:=TFlexItem(FLineItems[i]);
+        CurMainSize:=CurMainSize+Item.MarginLeft+Item.BorderLeft+Item.PaddingLeft
+          +Item.CurMainContentSize+Item.PaddingRight+Item.BorderRight+Item.MarginRight;
+        if i>0 then
+          CurMainSize:=CurMainSize+MainGap;
+      end;
+      Dist:=MaxMainSize-CurMainSize;
+      if Dist>MinAdjust then
+      begin
+        // try to grow
+        // collect grow factors of all items able to grow
+        SumGrow:=0;
+        for i:=0 to FLineItems.Count-1 do
+        begin
+          Item:=TFlexItem(FLineItems[i]);
+          if Item.Grow<MinAdjust then continue;
+          SumGrow:=SumGrow+Item.Grow;
+        end;
+        if SumGrow=0 then
+          break; // can not grow
+        // grow
+        for i:=0 to FLineItems.Count-1 do
+        begin
+          Item:=TFlexItem(FLineItems[i]);
+          if Item.Grow<MinAdjust then continue;
+          Item.CurMainContentSize:=Item.CurMainContentSize+(Item.Grow/SumGrow)*Dist;
+        end;
+      end else if Dist<-MinAdjust then begin
+        // try to shrink
+        // collect shrink factors of all items able to shrink
+        SumShrink:=0;
+        for i:=0 to FLineItems.Count-1 do
+        begin
+          Item:=TFlexItem(FLineItems[i]);
+          if Item.Shrink<MinAdjust then continue;
+          if Item.CurMainContentSize<MinAdjust then continue;
+          SumShrink:=SumShrink+Item.Shrink;
+        end;
+        if SumShrink=0 then
+          break; // can not shrink
+        // shrink
+        for i:=0 to FLineItems.Count-1 do
+        begin
+          Item:=TFlexItem(FLineItems[i]);
+          if Item.Shrink<MinAdjust then continue;
+          if Item.CurMainContentSize<MinAdjust then continue;
+          Item.CurMainContentSize:=Max(0,Item.CurMainContentSize+(Item.Shrink/SumShrink)*Dist);
+        end;
+      end else
+        break;
+    until false;
+  end;
+
+  // todo: justify-content / align-content
+  for i:=0 to FLineItems.Count-1 do
+  begin
+    Item:=TFlexItem(FLineItems[i]);
+    NewMainSize:=Item.CurMainContentSize;
+    if FlexDirection in [CSSRegistry.kwRow,CSSRegistry.kwRowReverse] then
+    begin
+      if not IsNan(Item.MaxWidth) then
+        NewMainSize:=Min(NewMainSize,Item.MarginLeft+Item.BorderLeft+Item.PaddingLeft
+                          +Item.MaxWidth
+                          +Item.PaddingRight+Item.BorderRight+Item.MarginRight);
+      if not IsNan(Item.MinWidth) then
+        NewMainSize:=Max(NewMainSize,Item.MarginLeft+Item.BorderLeft+Item.PaddingLeft
+                          +Item.MinWidth
+                          +Item.PaddingRight+Item.BorderRight+Item.MarginRight);
+    end else begin
+      if not IsNan(Item.MaxHeight) then
+        NewMainSize:=Min(NewMainSize,Item.MarginTop+Item.BorderTop+Item.PaddingTop
+                          +Item.MaxHeight
+                          +Item.PaddingBottom+Item.BorderBottom+Item.MarginBottom);
+      if not IsNan(Item.MinHeight) then
+        NewMainSize:=Max(NewMainSize,Item.MarginTop+Item.BorderTop+Item.PaddingTop
+                          +Item.MinHeight
+                          +Item.PaddingBottom+Item.BorderBottom+Item.MarginBottom);
+    end;
+  end;
+end;
+
+procedure TFLFlexLayouter.FlexLineCrossDirection;
+begin
+  // all items on line now have their size and position in main direction
+  // -> now compute their cross direction size and position
+  // todo
+end;
+
+procedure TFLFlexLayouter.PlaceLineItems;
 begin
 
   inherited;
 end;
 
+procedure TFLFlexLayouter.ComputeChildAttributes(Item: TLineItem;
+  El: TFresnelElement);
+var
+  FlexItem: TFlexItem;
+begin
+  inherited ComputeChildAttributes(Item, El);
+
+  FlexItem:=Item as TFlexItem;
+  FlexItem.Basis:=El.GetComputedLength(fcaFlexBasis,true);
+  FlexItem.Grow:=El.GetComputedLength(fcaFlexGrow,true);
+  FlexItem.Shrink:=El.GetComputedLength(fcaFlexShrink,true);
+
+  if IsNan(FlexItem.Basis) then
+  begin
+    if FlexDirection in [CSSRegistry.kwRow,CSSRegistry.kwRowReverse]
+    then begin
+      FlexItem.Basis:=FlexItem.Width;
+      if IsNan(FlexItem.Basis) then
+        FlexItem.Basis:=El.GetMaxWidthContentBox;
+      FlexItem.Basis:=FlexItem.Basis+FlexItem.BorderLeft+FlexItem.PaddingLeft+FlexItem.PaddingRight+FlexItem.BorderRight;
+    end else begin
+      FlexItem.Basis:=FlexItem.Height;
+      if IsNan(FlexItem.Basis) then
+        FlexItem.Basis:=100; // todo El.GetMaxHeightContentBox;
+      FlexItem.Basis:=FlexItem.Basis+FlexItem.BorderLeft+FlexItem.PaddingLeft+FlexItem.PaddingRight+FlexItem.BorderRight;
+    end;
+  end;
+  if IsNan(FlexItem.Grow) then FlexItem.Grow:=0;
+  if IsNan(FlexItem.Shrink) then FlexItem.Grow:=1;
+end;
+
 procedure TFLFlexLayouter.Apply;
 var
   El: TFresnelElement;
@@ -750,6 +911,48 @@ begin
   El:=Node.Element;
   FlexDirection:=El.GetComputedKeyword(fcaFlexDirection,CSSRegistry.Chk_FlexDirection_KeywordIDs);
   FlexWrap:=El.GetComputedKeyword(fcaFlexWrap,CSSRegistry.Chk_FlexWrap_KeywordIDs);
+  JustifyContent:=El.GetComputedJustifyContent(JustifyContentSub);
+  AlignItems:=El.GetComputedJustifyContent(AlignItemsSub);
+  //if El.ComputedDirection; // todo direction
+
+  case FlexDirection of
+  CSSRegistry.kwRow:
+    case JustifyContent of
+    CSSRegistry.kwLeft,
+    CSSRegistry.kwStart: JustifyContent:=CSSRegistry.kwFlexStart;
+    CSSRegistry.kwRight,
+    CSSRegistry.kwEnd: JustifyContent:=CSSRegistry.kwFlexEnd;
+    end;
+  CSSRegistry.kwRowReverse:
+    case JustifyContent of
+    CSSRegistry.kwRight,
+    CSSRegistry.kwEnd: JustifyContent:=CSSRegistry.kwFlexStart;
+    CSSRegistry.kwLeft,
+    CSSRegistry.kwStart: JustifyContent:=CSSRegistry.kwFlexEnd;
+    end;
+  CSSRegistry.kwColumn:
+    case JustifyContent of
+    CSSRegistry.kwLeft,
+    CSSRegistry.kwRight,
+    CSSRegistry.kwStart: JustifyContent:=CSSRegistry.kwFlexStart;
+    CSSRegistry.kwEnd: JustifyContent:=CSSRegistry.kwFlexEnd;
+    end;
+  CSSRegistry.kwColumnReverse:
+    case JustifyContent of
+    CSSRegistry.kwLeft,
+    CSSRegistry.kwRight,
+    CSSRegistry.kwEnd: JustifyContent:=CSSRegistry.kwFlexStart;
+    CSSRegistry.kwStart: JustifyContent:=CSSRegistry.kwFlexEnd;
+    end;
+  end;
+  case JustifyContent of
+  CSSRegistry.kwLeft:;
+  //kwNormal,kwStretch,
+  //  kwStart,kwEnd,kwFlexStart,kwFlexEnd,kwCenter,kwLeft,kwRight,
+  //  kwSpaceBetween,kwSpaceAround,kwSpaceEvenly,
+  //  kwSafe,kwUnsafe
+  end;
+
   FGap[false]:=NaN;
   FGap[true]:=NaN;
 end;
@@ -792,60 +995,154 @@ procedure TFLFlexLayouter.ComputeLayout(MaxContentWidth, MaxContentHeight: TFres
 var
   NodeIndex: Integer;
   ChildNode: TSimpleFresnelLayoutNode;
-  ChildEl: TFresnelElement;
-  ChildMargin, ChildBorder, ChildPadding: TFresnelRect;
+  ChildEl, El, Container: TFresnelElement;
+  FlexNode: TFlexItem;
+  MaxMainSize: TFresnelLength; // max content size in main direction
+  CurMainSize: TFresnelLength; // current line size in main direction  without ending margin
+  CurMainMargin: TFresnelLength; // current ending margin in main direction
+  MainGap: TFresnelLength; // gap in main direction
+  Fits: Boolean;
 begin
+  El:=Node.Element;
   NewContentWidth:=0;
   NewContentHeight:=0;
 
+  if FlexDirection in [CSSRegistry.kwRow,CSSRegistry.kwRowReverse] then
+  begin
+    if IsNan(MaxContentWidth) then
+      MaxMainSize:=ContentWidth
+    else
+      MaxMainSize:=MaxContentWidth;
+    MainGap:=GetComputedGap(true);
+  end else begin
+    if IsNan(MaxContentHeight) then
+      MaxMainSize:=ContentHeight
+    else
+      MaxMainSize:=MaxContentHeight;
+    MainGap:=GetComputedGap(false);
+  end;
+  if IsNan(MaxMainSize) then
+  begin
+    Container:=El.GetBlockContainer;
+    if Container<>nil then
+    begin
+      if FlexDirection in [CSSRegistry.kwRow,CSSRegistry.kwRowReverse] then
+        MaxMainSize:=Container.GetComputedLength(fcaWidth,true) // todo Container.BoxSizing
+      else
+        MaxMainSize:=Container.GetComputedLength(fcaHeight,true); // todo Container.BoxSizing
+    end;
+  end;
+
+  CurMainSize:=0;
+  CurMainMargin:=0;
+
   // add elements to the line until full
   StartLine;
   NodeIndex:=0;
-  while NodeIndex<Node.NodeCount do
-  begin
-    ChildNode:=TSimpleFresnelLayoutNode(Node.Nodes[NodeIndex]);
-    ChildEl:=ChildNode.Element;
-
-    // skip collapsed
-    if (ChildEl.ComputedVisibility=CSSRegistry.kwCollapse) then
+  FlexNode:=nil;
+  try
+    while NodeIndex<Node.NodeCount do
     begin
-      inc(NodeIndex);
-      continue;
-    end;
+      ChildNode:=TSimpleFresnelLayoutNode(Node.Nodes[NodeIndex]);
+      ChildEl:=ChildNode.Element;
 
-    // skip position: absolute and fixed
-    case ChildEl.ComputedPosition of
-    CSSRegistry.kwStatic,CSSRegistry.kwRelative,CSSRegistry.kwSticky: ;
-    else
-      if Commit then
-        PlaceAbsoluteNode(ChildNode);
-      inc(NodeIndex);
-      continue;
-    end;
+      // skip collapsed
+      if (ChildEl.ComputedVisibility=CSSRegistry.kwCollapse)
+          or (ChildEl.ComputedDisplayOutside=CSSIDNone) then
+      begin
+        inc(NodeIndex);
+        continue;
+      end;
 
-    ChildMargin.Left:=ChildEl.GetComputedLength(fcaMarginLeft);
-    ChildMargin.Right:=ChildEl.GetComputedLength(fcaMarginRight);
-    ChildMargin.Top:=ChildEl.GetComputedLength(fcaMarginTop);
-    ChildMargin.Bottom:=ChildEl.GetComputedLength(fcaMarginBottom);
+      // skip position: absolute and fixed
+      if ChildEl.ComputedPosition in [CSSRegistry.kwAbsolute,CSSRegistry.kwFixed] then
+      begin
+        if Commit then
+          PlaceAbsoluteItem(ChildNode);
+        inc(NodeIndex);
+        continue;
+      end;
 
-    ChildBorder.Left:=ChildEl.GetComputedBorderWidth(fcaBorderLeftWidth);
-    ChildBorder.Right:=ChildEl.GetComputedBorderWidth(fcaBorderRightWidth);
-    ChildBorder.Top:=ChildEl.GetComputedBorderWidth(fcaBorderTopWidth);
-    ChildBorder.Bottom:=ChildEl.GetComputedBorderWidth(fcaBorderBottomWidth);
+      if FLineItems=nil then FLineItems:=TFPList.Create;
+      FlexNode:=TFlexItem.Create;
+      ComputeChildAttributes(FlexNode,ChildEl);
 
-    ChildPadding.Left:=ChildEl.GetComputedLength(fcaPaddingLeft);
-    ChildPadding.Right:=ChildEl.GetComputedLength(fcaPaddingRight);
-    ChildPadding.Top:=ChildEl.GetComputedLength(fcaPaddingTop);
-    ChildPadding.Bottom:=ChildEl.GetComputedLength(fcaPaddingBottom);
+      if FLineItems.Count>0 then
+      begin
+        Fits:=true;
+        if (FLineItems.Count>0) and (FlexWrap<>CSSRegistry.kwNoWrap) then
+        begin
+          // todo check if node fits into line
+        end;
 
-    //fcaFlexBasis
-    //fcaFlexGrow
-    //fcaFlexShrink
+        if Fits then
+        begin
+          case FlexDirection of
+          CSSRegistry.kwRow:
+            begin
+              CurMainSize:=CurMainSize+MainGap+CurMainMargin+FlexNode.MarginLeft+FlexNode.Basis;
+              CurMainMargin:=FlexNode.MarginRight;
+            end;
+          CSSRegistry.kwRowReverse:
+            begin
+              CurMainSize:=CurMainSize+MainGap+CurMainMargin+FlexNode.MarginRight+FlexNode.Basis;
+              CurMainMargin:=FlexNode.MarginLeft;
+            end;
+          CSSRegistry.kwColumn:
+            begin
+              CurMainSize:=CurMainSize+MainGap+CurMainMargin+FlexNode.MarginTop+FlexNode.Basis;
+              CurMainMargin:=FlexNode.MarginBottom;
+            end;
+          CSSRegistry.kwColumnReverse:
+            begin
+              CurMainSize:=CurMainSize+MainGap+CurMainMargin+FlexNode.MarginBottom+FlexNode.Basis;
+              CurMainMargin:=FlexNode.MarginTop;
+            end;
+          end;
+        end else begin
+          FlexLineMainDirection(MaxMainSize,MainGap);
+          FlexLineCrossDirection;
+          PlaceLineItems;
+          ClearLineItems;
+        end;
+      end;
 
+      if FLineItems.Count=0 then
+      begin
+        // first element in line
+        FLineItems.Add(FlexNode);
+        case FlexDirection of
+        CSSRegistry.kwRow:
+          begin
+            CurMainSize:=FlexNode.MarginLeft+FlexNode.Basis;
+            CurMainMargin:=FlexNode.MarginRight;
+          end;
+        CSSRegistry.kwRowReverse:
+          begin
+            CurMainSize:=FlexNode.MarginRight+FlexNode.Basis;
+            CurMainMargin:=FlexNode.MarginLeft;
+          end;
+        CSSRegistry.kwColumn:
+          begin
+            CurMainSize:=FlexNode.MarginTop+FlexNode.Basis;
+            CurMainMargin:=FlexNode.MarginBottom;
+          end;
+        CSSRegistry.kwColumnReverse:
+          begin
+            CurMainSize:=FlexNode.MarginBottom+FlexNode.Basis;
+            CurMainMargin:=FlexNode.MarginTop;
+          end;
+        end;
+      end;
 
-    inc(NodeIndex);
+
+      inc(NodeIndex);
+    end;
+    EndLine(Commit);
+
+  finally
+    FlexNode.Free;
   end;
-  EndLine(Commit);
 
 end;
 
@@ -920,16 +1217,16 @@ end;
 
 { TFLLineLayouter }
 
-procedure TFLLineLayouter.PlaceLineNodes;
+procedure TFLLineLayouter.PlaceLineItems;
 var
   i: Integer;
-  LineNode: TLineNode;
+  LineNode: TLineItem;
   ChildNode: TSimpleFresnelLayoutNode;
   ChildEl: TFresnelElement;
 begin
-  for i:=0 to FLineNodes.Count-1 do
+  for i:=0 to FLineItems.Count-1 do
   begin
-    LineNode:=TLineNode(FLineNodes[i]);
+    LineNode:=TLineItem(FLineItems[i]);
     ChildNode:=LineNode.Node;
     ChildEl:=ChildNode.Element;
 
@@ -952,7 +1249,7 @@ begin
   end;
 end;
 
-procedure TFLLineLayouter.PlaceAbsoluteNode(ChildNode: TSimpleFresnelLayoutNode);
+procedure TFLLineLayouter.PlaceAbsoluteItem(ChildNode: TSimpleFresnelLayoutNode);
 var
   ChildEl: TFresnelElement;
   ChildLeft, ChildRight, ChildTop, ChildBottom, // MarginBox
@@ -1106,31 +1403,119 @@ begin
   //  '');
 end;
 
-procedure TFLLineLayouter.ClearLineNodes;
+procedure TFLLineLayouter.ClearLineItems;
 var
   i: Integer;
 begin
-  if FLineNodes=nil then
+  if FLineItems=nil then
     exit;
-  for i:=0 to FLineNodes.Count-1 do
-     TObject(FLineNodes[i]).Free;
-  FLineNodes.Clear;
+  for i:=0 to FLineItems.Count-1 do
+     TObject(FLineItems[i]).Free;
+  FLineItems.Clear;
 end;
 
-function TFLLineLayouter.AddLineNode(ChildNode: TSimpleFresnelLayoutNode; NodeClass: TLineNodeClass
-  ): TLineNode;
+function TFLLineLayouter.AddLineItem(ChildNode: TSimpleFresnelLayoutNode; NodeClass: TLineItemClass
+  ): TLineItem;
 begin
   Result:=NodeClass.Create;
-  if FLineNodes=nil then
-    FLineNodes:=TFPList.Create;
-  FLineNodes.Add(Result);
+  if FLineItems=nil then
+    FLineItems:=TFPList.Create;
+  FLineItems.Add(Result);
   Result.Node:=ChildNode;
 end;
 
+procedure TFLLineLayouter.ComputeChildAttributes(Item: TLineItem;
+  El: TFresnelElement);
+
+  procedure WidthToContentBox(var aWidth: TFresnelLength);
+  begin
+    if IsNan(aWidth) then exit;
+    case El.ComputedBoxSizing of
+    CSSRegistry.kwBorderBox:
+      aWidth:=Max(0,aWidth-Item.BorderLeft-Item.PaddingLeft-Item.PaddingRight-Item.BorderRight);
+    CSSRegistry.kwPaddingBox:
+      aWidth:=Max(0,aWidth-Item.PaddingLeft-Item.PaddingRight);
+    else
+      if aWidth<0 then aWidth:=0;
+    end;
+  end;
+
+  function GetCSSWidth(Attr: TFresnelCSSAttribute): TFresnelLength;
+  begin
+    Result:=El.GetComputedLength(Attr,true);
+    WidthToContentBox(Result);
+  end;
+
+  procedure HeightToContentBox(var aHeight: TFresnelLength);
+  begin
+    if IsNan(aHeight) then exit;
+    case El.ComputedBoxSizing of
+    CSSRegistry.kwBorderBox:
+      aHeight:=Max(0,aHeight-Item.BorderTop-Item.PaddingTop-Item.PaddingBottom-Item.BorderBottom);
+    CSSRegistry.kwPaddingBox:
+      aHeight:=Max(0,aHeight-Item.PaddingTop-Item.PaddingBottom);
+    else
+      if aHeight<0 then aHeight:=0;
+    end;
+  end;
+
+  function GetCSSHeight(Attr: TFresnelCSSAttribute): TFresnelLength;
+  begin
+    Result:=El.GetComputedLength(Attr,true);
+    HeightToContentBox(Result);
+  end;
+
+begin
+  Item.MarginLeft:=El.GetComputedLength(fcaMarginLeft);
+  Item.MarginRight:=El.GetComputedLength(fcaMarginRight);
+  Item.MarginTop:=El.GetComputedLength(fcaMarginTop);
+  Item.MarginBottom:=El.GetComputedLength(fcaMarginBottom);
+
+  Item.BorderLeft:=El.GetComputedBorderWidth(fcaBorderLeftWidth);
+  Item.BorderRight:=El.GetComputedBorderWidth(fcaBorderRightWidth);
+  Item.BorderTop:=El.GetComputedBorderWidth(fcaBorderTopWidth);
+  Item.BorderBottom:=El.GetComputedBorderWidth(fcaBorderBottomWidth);
+
+  Item.PaddingLeft:=El.GetComputedLength(fcaPaddingLeft);
+  Item.PaddingRight:=El.GetComputedLength(fcaPaddingRight);
+  Item.PaddingTop:=El.GetComputedLength(fcaPaddingTop);
+  Item.PaddingBottom:=El.GetComputedLength(fcaPaddingBottom);
+
+  Item.Width:=GetCSSWidth(fcaWidth);
+  Item.Height:=GetCSSHeight(fcaHeight);
+  Item.MinWidth:=GetCSSWidth(fcaMinWidth);
+  Item.MinHeight:=GetCSSHeight(fcaMinHeight);
+  Item.MaxWidth:=GetCSSWidth(fcaMaxWidth);
+  Item.MaxHeight:=GetCSSHeight(fcaMaxHeight);
+
+  //writeln('TFLBlockFormattingContext.ComputeLayoutBorderBox ',ChildEl.GetPath,' Commit=',Commit,' ChildWidth=',FloatToStr(ChildWidth),' ChildHeight=',FloatToStr(ChildHeight));
+
+  if (not IsNan(Item.MinWidth)) and (not IsNan(Item.MaxWidth)) and (Item.MinWidth>=Item.MaxWidth) then
+    Item.Width:=Item.MinWidth;
+  if not IsNan(Item.Width) then
+  begin
+    if not IsNan(Item.MaxWidth) then
+      Item.Width:=Min(Item.Width,Item.MaxWidth);
+    if not IsNan(Item.MinWidth) then
+      Item.Width:=Max(Item.Width,Item.MinWidth);
+  end;
+
+  if (not IsNan(Item.MinHeight)) and (not IsNan(Item.MaxHeight)) and (Item.MinHeight>=Item.MaxHeight) then
+    Item.Height:=Item.MinHeight
+  else if not IsNan(Item.Height) then
+  begin
+    if not IsNan(Item.MaxHeight) then
+      Item.Height:=Min(Item.Height,Item.MaxHeight);
+    if not IsNan(Item.MinHeight) then
+      Item.Height:=Max(Item.Height,Item.MinHeight);
+  end;
+
+end;
+
 destructor TFLLineLayouter.Destroy;
 begin
-  ClearLineNodes;
-  FreeAndNil(FLineNodes);
+  ClearLineItems;
+  FreeAndNil(FLineItems);
   inherited Destroy;
 end;
 
@@ -1265,96 +1650,6 @@ begin
   Layout(VPNode);
 end;
 
-function TViewportLayouter.NeedBlockFormattingContext(El: TFresnelElement
-  ): boolean;
-// BFC
-// contain internal and external floats
-// surpress margin collapsing
-var
-  aOverflow, aFloat: String;
-begin
-  if El=nil then
-    exit(false);
-  if El.Parent=nil then
-    exit(true);
-
-  case El.ComputedPosition of
-  CSSRegistry.kwAbsolute,
-  CSSRegistry.kwFixed:
-    exit(true);
-  end;
-
-  if El.ComputedDisplayOutside in [CSSIDNone,CSSRegistry.kwNone] then
-    exit(false);
-
-  case El.ComputedDisplayOutside of
-  CSSRegistry.kwBlock: exit(true);
-  end;
-
-  case El.ComputedDisplayInside of
-  //CSSRegistry.kwtable,
-  CSSRegistry.kwFlex,
-  CSSRegistry.kwGrid,
-  //CSSRegistry.kwRuby,
-  CSSRegistry.kwFlowRoot:
-    exit(true);
-  end;
-
-  aOverflow:=El.ComputedAttribute[fcaOverflow];
-  case aOverflow of
-  'visible',
-  'clip': exit(true);
-  end;
-
-  aFloat:=El.ComputedAttribute[fcaFloat];
-  case aFloat of
-  '', 'none': ;
-  else
-    exit(true);
-  end;
-
-  Result:=false;
-end;
-
-function TViewportLayouter.GetBlockContainer(El: TFresnelElement
-  ): TFresnelElement;
-begin
-  case El.ComputedPosition of
-  CSSRegistry.kwAbsolute:
-    begin
-      // the containing block is nearest ancestor element that has a position value other than static
-      Result:=El.Parent;
-      while (Result<>nil) do
-      begin
-        if not (Result.ComputedPosition in [CSSRegistry.kwSticky,CSSIDNone]) then
-          exit;
-        // Note:check for transform<>'none'
-        Result:=Result.Parent;
-      end;
-      Result:=Viewport;
-    end;
-  CSSRegistry.kwFixed:
-    begin
-      // viewport
-      Result:=Viewport;
-    end;
-  else
-    // static, relative, sticky
-    // the containing block is the nearest ancestor element that is either a
-    // block container (such as an inline-block, block, or list-item element)
-    // or establishes a formatting context (such as a table container,
-    // flex container, grid container, or the block container itself)
-    Result:=El.Parent;
-    while (Result<>nil) do
-    begin
-      if TSimpleFresnelLayoutNode(Result.LayoutNode).Layouter<>nil then
-        exit;
-      Result:=Result.Parent;
-    end;
-    Result:=Viewport;
-  end;
-end;
-
 procedure TViewportLayouter.UpdateLayouter(El: TFresnelElement;
   LNode: TSimpleFresnelLayoutNode);
 var
@@ -1369,7 +1664,7 @@ begin
     CSSRegistry.kwFlex:
       LayouterClass:=TFLFlexLayouter;
     else
-      if NeedBlockFormattingContext(El) then
+      if El.IsBlockFormattingContext then
         LayouterClass:=TFLBlockFormattingContext;
     end;
   end;
@@ -1474,7 +1769,7 @@ begin
   end;
 
   // block container
-  LNode.BlockContainer:=GetBlockContainer(El);
+  LNode.BlockContainer:=El.GetBlockContainer;
   //FLLog(etDebug,['TSimpleFresnelLayouter.ComputeCSS ',El.Name,' BlockContainer=',LNode.BlockContainer.ToString]);
 
   // LayoutParent

+ 34 - 1
tests/base/TCFlexLayout.pas

@@ -5,9 +5,42 @@ unit TCFlexLayout;
 interface
 
 uses
-  Classes, SysUtils;
+  Classes, SysUtils, testregistry, TCFresnelCSS, Fresnel.Controls, Fresnel.DOM;
+
+type
+
+  { TTestFlexLayout }
+
+  TTestFlexLayout = class(TCustomTestFresnelCSS)
+  published
+    procedure TestFlexLayout_Empty;
+    // todo: test padding-left,right,top,bottom percentage uses container's width
+    // todo: test margin-left,right,top,bottom percentage uses container's width
+  end;
 
 implementation
 
+{ TTestFlexLayout }
+
+procedure TTestFlexLayout.TestFlexLayout_Empty;
+var
+  FlexDiv: TDiv;
+begin
+  FlexDiv:=TDiv.Create(Viewport);
+  FlexDiv.Name:='FlexDiv';
+  FlexDiv.Parent:=Viewport;
+
+  Viewport.Stylesheet.Text:=LinesToStr([
+  '#FlexDiv { width: 100px; height: 100px; display: flex; }'
+  ]);
+
+  Viewport.Draw;
+  AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
+  AssertEquals('FlexDiv.ComputedDisplayInside',CSSRegistry.kwFlex,FlexDiv.ComputedDisplayInside);
+  AssertEquals('FlexDiv.ComputedDisplayOutside',CSSRegistry.kwBlock,FlexDiv.ComputedDisplayOutside);
+end;
+
+Initialization
+  RegisterTests([TTestFlexLayout]);
 end.
 

+ 6 - 6
tests/base/TCFlowLayout.pas

@@ -9,9 +9,9 @@ uses
 
 type
 
-  { TTestFresnelFlowLayout }
+  { TTestFlowLayout }
 
-  TTestFresnelFlowLayout = class(TCustomTestFresnelCSS)
+  TTestFlowLayout = class(TCustomTestFresnelCSS)
   published
     procedure TestFlowLayout_BodyDiv;
     procedure TestFlowLayout_SliderRangePoint;
@@ -22,9 +22,9 @@ type
 
 implementation
 
-{ TTestFresnelFlowLayout }
+{ TTestFlowLayout }
 
-procedure TTestFresnelFlowLayout.TestFlowLayout_BodyDiv;
+procedure TTestFlowLayout.TestFlowLayout_BodyDiv;
 var
   Body: TBody;
   Div1: TDiv;
@@ -73,7 +73,7 @@ begin
 
 end;
 
-procedure TTestFresnelFlowLayout.TestFlowLayout_SliderRangePoint;
+procedure TTestFlowLayout.TestFlowLayout_SliderRangePoint;
 var
   Body: TBody;
   SliderDiv, RangeDiv, PointDiv: TDiv;
@@ -143,6 +143,6 @@ begin
 end;
 
 Initialization
-  RegisterTests([TTestFresnelFlowLayout]);
+  RegisterTests([TTestFlowLayout]);
 end.