|
@@ -962,7 +962,11 @@ type
|
|
|
FAfterRender: TNotifyEvent;
|
|
|
FBeforeRender: TNotifyEvent;
|
|
|
FComputedBorderBox: TFresnelRect;
|
|
|
+ FComputedBoxSizing: TCSSNumericalID;
|
|
|
FComputedContentBox: TFresnelRect;
|
|
|
+ FComputedDirection: TCSSNumericalID;
|
|
|
+ FComputedVisibility: TCSSNumericalID;
|
|
|
+ FComputedWritingMode: TCSSNumericalID;
|
|
|
FDOMIndex: integer;
|
|
|
FFont: IFresnelFont;
|
|
|
FLayoutNode: TFresnelLayoutNode;
|
|
@@ -987,10 +991,10 @@ type
|
|
|
FChildren: TFPList; // list of TFresnelElement
|
|
|
FCSSClasses: TStrings;
|
|
|
FCSSValues: TCSSAttributeValues;
|
|
|
- FDisplayInside: TCSSNumericalID;
|
|
|
- FDisplayOutside: TCSSNumericalID;
|
|
|
+ FComputedDisplayInside: TCSSNumericalID;
|
|
|
+ FComputedDisplayOutside: TCSSNumericalID;
|
|
|
FParent: TFresnelElement;
|
|
|
- FPosition: TCSSNumericalID;
|
|
|
+ FComputedPosition: TCSSNumericalID;
|
|
|
FResolver: TCSSResolver;
|
|
|
FStyle: string;
|
|
|
FStyleElement: TCSSRuleElement;
|
|
@@ -1012,9 +1016,13 @@ type
|
|
|
procedure FPOObservedChanged(ASender: TObject; Operation: TFPObservedOperation; Data: Pointer); virtual;
|
|
|
// compute
|
|
|
procedure UnsetValue(AttrID: TCSSNumericalID); virtual;
|
|
|
- function ConvertCSSValueToPixel(IsHorizontal: boolean; const Value: string): TFresnelLength; virtual;
|
|
|
+ function ConvertCSSValueToPixel(IsHorizontal: boolean; const Value: string; UseNaNOnFail: boolean): TFresnelLength; virtual;
|
|
|
+ procedure ComputeBoxSizing; virtual;
|
|
|
+ procedure ComputeDirection; virtual;
|
|
|
procedure ComputeDisplay; virtual;
|
|
|
procedure ComputePosition; virtual;
|
|
|
+ procedure ComputeVisibility; virtual;
|
|
|
+ procedure ComputeWritingMode; virtual;
|
|
|
function ComputeAttribute(aDesc: TCSSAttributeDesc; var aValue: String): TCSSAttributeValue.TState; virtual;
|
|
|
function GetShorthandSpaceSeparated(AttrDesc: TCSSAttributeDesc): string;
|
|
|
protected
|
|
@@ -1074,7 +1082,8 @@ type
|
|
|
procedure ComputeCSSValues; virtual; // call resolver to collect CSS values and resolve shorthands
|
|
|
procedure ComputeCSSAfterLayoutNode(Layouter: TFresnelLayouter); virtual; // after layouter node, before layouter traverse children
|
|
|
function GetCSSString(AttrID: TCSSNumericalID; Compute: boolean; out Complete: boolean): string; virtual;
|
|
|
- function GetComputedLength(Attr: TFresnelCSSAttribute; UseNaNOnFail: boolean = false): TFresnelLength; virtual; // on fail returns NaN
|
|
|
+ function GetComputedLength(Attr: TFresnelCSSAttribute; UseNaNOnFail: boolean = false): TFresnelLength; virtual; overload;
|
|
|
+ function GetComputedLength(const aComp: TCSSResCompValue; Attr: TFresnelCSSAttribute; UseNaNOnFail: boolean = false): TFresnelLength; virtual; overload;
|
|
|
function GetComputedString(Attr: TFresnelCSSAttribute): string; virtual;
|
|
|
function GetComputedCSSString(AttrID: TCSSNumericalID): string; virtual; overload;
|
|
|
function GetComputedCSSString(const AttrName: string): string; overload;
|
|
@@ -1094,10 +1103,14 @@ type
|
|
|
procedure WriteComputedAttributes(Title: string);
|
|
|
property ComputedAttribute[Attr: TFresnelCSSAttribute]: string read GetComputedString write SetComputedCSSString;
|
|
|
property ComputedBorderBox: TFresnelRect read FComputedBorderBox write FComputedBorderBox; // relative to layout parent
|
|
|
+ property ComputedBoxSizing: TCSSNumericalID read FComputedBoxSizing;
|
|
|
property ComputedContentBox: TFresnelRect read FComputedContentBox write FComputedContentBox; // relative to layout parent
|
|
|
- property DisplayInside: TCSSNumericalID read FDisplayInside;
|
|
|
- property DisplayOutside: TCSSNumericalID read FDisplayOutside;
|
|
|
- property Position: TCSSNumericalID read FPosition;
|
|
|
+ property ComputedDirection: TCSSNumericalID read FComputedDirection;
|
|
|
+ property ComputedDisplayInside: TCSSNumericalID read FComputedDisplayInside;
|
|
|
+ property ComputedDisplayOutside: TCSSNumericalID read FComputedDisplayOutside;
|
|
|
+ property ComputedPosition: TCSSNumericalID read FComputedPosition;
|
|
|
+ property ComputedVisibility: TCSSNumericalID read FComputedVisibility;
|
|
|
+ property ComputedWritingMode: TCSSNumericalID read FComputedWritingMode;
|
|
|
// CSS pseudo classes
|
|
|
property CSSPseudoClass[Pseudo: TFresnelCSSPseudoClass]: boolean read GetCSSPseudoClass write SetCSSPseudoClass;
|
|
|
// layouter
|
|
@@ -6218,6 +6231,29 @@ end;
|
|
|
|
|
|
function TFresnelElement.GetComputedLength(Attr: TFresnelCSSAttribute; UseNaNOnFail: boolean
|
|
|
): TFresnelLength;
|
|
|
+var
|
|
|
+ s: String;
|
|
|
+ aComp: TCSSResCompValue;
|
|
|
+ AttrID: TCSSNumericalID;
|
|
|
+ Complete: boolean;
|
|
|
+begin
|
|
|
+ if UseNaNOnFail then
|
|
|
+ Result:=NaN
|
|
|
+ else
|
|
|
+ Result:=0;
|
|
|
+
|
|
|
+ AttrID:=CSSRegistry.FresnelAttrs[Attr].Index;
|
|
|
+ s:=GetCSSString(AttrID,true,Complete);
|
|
|
+ if s='' then exit;
|
|
|
+
|
|
|
+ aComp.EndP:=PChar(s);
|
|
|
+ if (not Resolver.ReadComp(aComp)) or (aComp.Kind<>rvkFloat) then
|
|
|
+ exit;
|
|
|
+ Result:=GetComputedLength(aComp,Attr);
|
|
|
+end;
|
|
|
+
|
|
|
+function TFresnelElement.GetComputedLength(const aComp: TCSSResCompValue;
|
|
|
+ Attr: TFresnelCSSAttribute; UseNaNOnFail: boolean): TFresnelLength;
|
|
|
|
|
|
function GetIsHorizontal: boolean;
|
|
|
begin
|
|
@@ -6238,26 +6274,18 @@ function TFresnelElement.GetComputedLength(Attr: TFresnelCSSAttribute; UseNaNOnF
|
|
|
fcaPaddingTop, // padding-top, -bottom percentage uses the container width
|
|
|
fcaPaddingBottom,
|
|
|
fcaBackgroundPositionX,
|
|
|
- fcaBackgroundSize];
|
|
|
+ fcaBackgroundSize,
|
|
|
+ fcaColumnGap];
|
|
|
end;
|
|
|
|
|
|
var
|
|
|
- s: String;
|
|
|
- aComp: TCSSResCompValue;
|
|
|
- AttrID: TCSSNumericalID;
|
|
|
- IsHorizontal, Complete: boolean;
|
|
|
+ IsHorizontal: Boolean;
|
|
|
begin
|
|
|
if UseNaNOnFail then
|
|
|
Result:=NaN
|
|
|
else
|
|
|
Result:=0;
|
|
|
-
|
|
|
- AttrID:=CSSRegistry.FresnelAttrs[Attr].Index;
|
|
|
- s:=GetCSSString(AttrID,true,Complete);
|
|
|
- if s='' then exit;
|
|
|
-
|
|
|
- aComp.EndP:=PChar(s);
|
|
|
- if (not Resolver.ReadComp(aComp)) or (aComp.Kind<>rvkFloat) or IsNan(aComp.Float) then
|
|
|
+ if (aComp.Kind<>rvkFloat) or IsNan(aComp.Float) then
|
|
|
exit;
|
|
|
case aComp.FloatUnit of
|
|
|
cuNone:
|
|
@@ -6272,21 +6300,26 @@ begin
|
|
|
exit(aComp.Float);
|
|
|
cuPercent:
|
|
|
begin
|
|
|
- // todo: depends on attribute
|
|
|
- IsHorizontal:=GetIsHorizontal;
|
|
|
- if IsHorizontal then
|
|
|
- begin
|
|
|
- if Attr in [fcaLeft,fcaRight,fcaWidth,fcaMinWidth,fcaMaxWidth] then
|
|
|
- Result:=GetBlockContainerWH(true,UseNaNOnFail)
|
|
|
- else
|
|
|
- Result:=GetComputedLength(fcaWidth,UseNaNOnFail);
|
|
|
- end else begin
|
|
|
- if Attr in [fcaTop,fcaBottom,fcaHeight,fcaMinHeight,fcaMaxHeight] then
|
|
|
- Result:=GetBlockContainerWH(false,UseNaNOnFail)
|
|
|
+ case Attr of
|
|
|
+ fcaLeft,fcaRight,fcaWidth,fcaMinWidth,fcaMaxWidth:
|
|
|
+ Result:=GetBlockContainerWH(true,UseNaNOnFail);
|
|
|
+ fcaTop,fcaBottom,fcaHeight,fcaMinHeight,fcaMaxHeight:
|
|
|
+ Result:=GetBlockContainerWH(false,UseNaNOnFail);
|
|
|
+ else
|
|
|
+ IsHorizontal:=GetIsHorizontal;
|
|
|
+ if IsHorizontal then
|
|
|
+ Result:=GetComputedLength(fcaWidth,UseNaNOnFail)
|
|
|
else
|
|
|
Result:=GetComputedLength(fcaHeight,UseNaNOnFail);
|
|
|
end;
|
|
|
- if IsNan(Result) then exit;
|
|
|
+ if IsNan(Result) then
|
|
|
+ begin
|
|
|
+ if UseNaNOnFail then
|
|
|
+ Result:=NaN
|
|
|
+ else
|
|
|
+ Result:=0;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
Result:=aComp.Float*Result/100;
|
|
|
exit;
|
|
|
end;
|
|
@@ -6359,7 +6392,8 @@ begin
|
|
|
'medium': exit(1);
|
|
|
'thick': exit(2);
|
|
|
end;
|
|
|
- Result:=ConvertCSSValueToPixel(Attr in [fcaBorderLeftWidth,fcaBorderRightWidth],s);
|
|
|
+ // Note: border-top and border-bottom percentage use container's width
|
|
|
+ Result:=ConvertCSSValueToPixel(true,s,false);
|
|
|
end;
|
|
|
|
|
|
procedure TFresnelElement.WriteComputedAttributes(Title: string);
|
|
@@ -6646,6 +6680,7 @@ var
|
|
|
aValue: String;
|
|
|
aComp: TCSSResCompValue;
|
|
|
Complete: boolean;
|
|
|
+ AttrDesc: TCSSAttributeDesc;
|
|
|
begin
|
|
|
Result:=CSSIDNone;
|
|
|
aValue:=GetCSSString(AttrID,false,Complete);
|
|
@@ -6655,6 +6690,16 @@ begin
|
|
|
if (aComp.Kind=rvkKeyword) and Resolver.IsKeywordIn(aComp.KeywordID,AllowedKeywords) then
|
|
|
exit(aComp.KeywordID);
|
|
|
until false;
|
|
|
+ // use initial value
|
|
|
+ AttrDesc:=CSSRegistry.Attributes[AttrID];
|
|
|
+ aValue:=AttrDesc.InitialValue;
|
|
|
+ aComp.EndP:=PChar(aValue);
|
|
|
+ if Resolver.ReadComp(aComp)
|
|
|
+ and (aComp.Kind=rvkKeyword)
|
|
|
+ and Resolver.IsKeywordIn(aComp.KeywordID,AllowedKeywords) then
|
|
|
+ exit(aComp.KeywordID);
|
|
|
+ // use default
|
|
|
+ Result:=AllowedKeywords[0];
|
|
|
end;
|
|
|
|
|
|
function TFresnelElement.GetComputedTextShadow(out aOffsetX, aOffsetY,
|
|
@@ -7260,34 +7305,46 @@ begin
|
|
|
FCSSValues.Values[i].State:=cavsInvalid;
|
|
|
end;
|
|
|
|
|
|
-function TFresnelElement.ConvertCSSValueToPixel(IsHorizontal: boolean; const Value: string
|
|
|
- ): TFresnelLength;
|
|
|
+function TFresnelElement.ConvertCSSValueToPixel(IsHorizontal: boolean; const Value: string;
|
|
|
+ UseNaNOnFail: boolean): TFresnelLength;
|
|
|
var
|
|
|
aComp: TCSSResCompValue;
|
|
|
begin
|
|
|
- Result:=NaN;
|
|
|
+ if UseNaNOnFail then
|
|
|
+ Result:=NaN
|
|
|
+ else
|
|
|
+ Result:=0;
|
|
|
|
|
|
if Value='' then
|
|
|
exit;
|
|
|
aComp.EndP:=PChar(Value);
|
|
|
if (not Resolver.ReadComp(aComp)) or (aComp.Kind<>rvkFloat) or IsNan(aComp.Float) then
|
|
|
exit;
|
|
|
- Result:=aComp.Float;
|
|
|
case aComp.FloatUnit of
|
|
|
cuNone:
|
|
|
- if Result=0 then
|
|
|
+ if aComp.Float=0 then
|
|
|
begin
|
|
|
- exit;
|
|
|
+ exit(aComp.Float);
|
|
|
end else begin
|
|
|
// number without unit is not allowed for pixel length
|
|
|
- exit(NaN);
|
|
|
+ exit;
|
|
|
end;
|
|
|
cu_px:
|
|
|
- exit;
|
|
|
+ exit(aComp.Float);
|
|
|
end;
|
|
|
if not (aComp.FloatUnit in cuAllLengths) then
|
|
|
- exit(NaN);
|
|
|
- Result:=Result*GetPixPerUnit(aComp.FloatUnit,IsHorizontal);
|
|
|
+ exit;
|
|
|
+ Result:=aComp.Float*GetPixPerUnit(aComp.FloatUnit,IsHorizontal);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelElement.ComputeBoxSizing;
|
|
|
+begin
|
|
|
+ FComputedBoxSizing:=GetComputedKeyword(fcaBoxSizing,CSSRegistry.Chk_BoxSizing_KeywordIDs);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelElement.ComputeDirection;
|
|
|
+begin
|
|
|
+ FComputedDirection:=GetComputedKeyword(fcaDirection,CSSRegistry.Chk_Direction_KeywordIDs);
|
|
|
end;
|
|
|
|
|
|
procedure TFresnelElement.ComputeDisplay;
|
|
@@ -7297,8 +7354,11 @@ var
|
|
|
aComp: TCSSResCompValue;
|
|
|
KW: TCSSNumericalID;
|
|
|
begin
|
|
|
- FDisplayInside:=CSSIDNone;
|
|
|
- FDisplayOutside:=CSSIDNone;
|
|
|
+ FComputedDisplayInside:=CSSIDNone;
|
|
|
+ FComputedDisplayOutside:=CSSIDNone;
|
|
|
+ if FComputedVisibility=CSSRegistry.kwCollapse then
|
|
|
+ exit;
|
|
|
+
|
|
|
aValue:=GetCSSString(CSSRegistry.FresnelAttrs[fcaDisplay].Index,false,Complete);
|
|
|
aComp.EndP:=PChar(aValue);
|
|
|
repeat
|
|
@@ -7309,57 +7369,70 @@ begin
|
|
|
case KW of
|
|
|
CSSRegistry.kwNone:
|
|
|
begin
|
|
|
- FDisplayInside:=CSSRegistry.kwNone;
|
|
|
- FDisplayOutside:=CSSRegistry.kwNone;
|
|
|
+ FComputedDisplayInside:=CSSIDNone;
|
|
|
+ FComputedDisplayOutside:=CSSIDNone;
|
|
|
+ FComputedVisibility:=CSSRegistry.kwCollapse;
|
|
|
break;
|
|
|
end;
|
|
|
CSSRegistry.kwContents:
|
|
|
begin
|
|
|
- FDisplayInside:=CSSRegistry.kwContents;
|
|
|
- FDisplayOutside:=CSSRegistry.kwContents;
|
|
|
+ FComputedDisplayInside:=CSSRegistry.kwContents;
|
|
|
+ FComputedDisplayOutside:=CSSRegistry.kwContents;
|
|
|
break;
|
|
|
end;
|
|
|
CSSRegistry.kwBlock,
|
|
|
CSSRegistry.kwInline:
|
|
|
- if FDisplayOutside=CSSIDNone then
|
|
|
- FDisplayOutside:=KW;
|
|
|
+ if FComputedDisplayOutside=CSSIDNone then
|
|
|
+ FComputedDisplayOutside:=KW;
|
|
|
CSSRegistry.kwFlow,
|
|
|
CSSRegistry.kwFlowRoot,
|
|
|
CSSRegistry.kwGrid,
|
|
|
CSSRegistry.kwFlex:
|
|
|
- if FDisplayInside=CSSIDNone then
|
|
|
- FDisplayInside:=KW;
|
|
|
+ if FComputedDisplayInside=CSSIDNone then
|
|
|
+ FComputedDisplayInside:=KW;
|
|
|
CSSRegistry.kwInlineBlock:
|
|
|
begin
|
|
|
// inline-block -> inline flow-root
|
|
|
- FDisplayOutside:=CSSRegistry.kwInline;
|
|
|
- FDisplayInside:=CSSRegistry.kwFlowRoot;
|
|
|
+ FComputedDisplayOutside:=CSSRegistry.kwInline;
|
|
|
+ FComputedDisplayInside:=CSSRegistry.kwFlowRoot;
|
|
|
+ break;
|
|
|
end;
|
|
|
CSSRegistry.kwInlineFlow:
|
|
|
begin
|
|
|
- FDisplayOutside:=CSSRegistry.kwInline;
|
|
|
- FDisplayInside:=CSSRegistry.kwFlow;
|
|
|
+ FComputedDisplayOutside:=CSSRegistry.kwInline;
|
|
|
+ FComputedDisplayInside:=CSSRegistry.kwFlow;
|
|
|
+ break;
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
until false;
|
|
|
- if (FDisplayOutside=CSSIDNone) and (FDisplayInside>CSSIDNone) then
|
|
|
+ if (FComputedDisplayOutside=CSSIDNone) and (FComputedDisplayInside>CSSIDNone) then
|
|
|
begin
|
|
|
- case FDisplayInside of
|
|
|
+ case FComputedDisplayInside of
|
|
|
CSSRegistry.kwGrid,
|
|
|
CSSRegistry.kwFlex:
|
|
|
- FDisplayOutside:=CSSRegistry.kwBlock;
|
|
|
+ FComputedDisplayOutside:=CSSRegistry.kwBlock;
|
|
|
else
|
|
|
- FDisplayOutside:=CSSRegistry.kwInline;
|
|
|
+ FComputedDisplayOutside:=CSSRegistry.kwInline;
|
|
|
end;
|
|
|
end;
|
|
|
- if (FDisplayInside=CSSIDNone) and (FDisplayOutside>CSSIDNone) then
|
|
|
- FDisplayInside:=CSSRegistry.kwFlow;
|
|
|
+ if (FComputedDisplayInside=CSSIDNone) and (FComputedDisplayOutside>CSSIDNone) then
|
|
|
+ FComputedDisplayInside:=CSSRegistry.kwFlow;
|
|
|
end;
|
|
|
|
|
|
procedure TFresnelElement.ComputePosition;
|
|
|
begin
|
|
|
- FPosition:=GetComputedKeyword(fcaPosition,CSSRegistry.Chk_Position_KeywordIDs);
|
|
|
+ FComputedPosition:=GetComputedKeyword(fcaPosition,CSSRegistry.Chk_Position_KeywordIDs);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelElement.ComputeVisibility;
|
|
|
+begin
|
|
|
+ FComputedVisibility:=GetComputedKeyword(fcaVisibility,CSSRegistry.Chk_Visible_KeywordIDs);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelElement.ComputeWritingMode;
|
|
|
+begin
|
|
|
+ FComputedWritingMode:=GetComputedKeyword(fcaWritingMode,CSSRegistry.Chk_WritingMode_KeywordIDs);
|
|
|
end;
|
|
|
|
|
|
function TFresnelElement.ComputeAttribute(aDesc: TCSSAttributeDesc; var aValue: String
|
|
@@ -7651,8 +7724,12 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+ ComputeVisibility;
|
|
|
ComputeDisplay;
|
|
|
ComputePosition;
|
|
|
+ ComputeBoxSizing;
|
|
|
+ ComputeDirection;
|
|
|
+ ComputeWritingMode;
|
|
|
end;
|
|
|
|
|
|
procedure TFresnelElement.ComputeCSSAfterLayoutNode(Layouter: TFresnelLayouter);
|