Browse Source

fcl-css: added attribute value check

mattias 2 years ago
parent
commit
2d94575fa8
2 changed files with 43 additions and 0 deletions
  1. 33 0
      packages/fcl-css/src/fpcssresolver.pas
  2. 10 0
      packages/fcl-css/tests/tccssresolver.pp

+ 33 - 0
packages/fcl-css/src/fpcssresolver.pas

@@ -198,6 +198,7 @@ type
     function GetCSSEmpty: boolean;
     function GetCSSDepth: integer;
     procedure SetCSSValue(AttrID: TCSSNumericalID; Value: TCSSElement);
+    function CheckCSSValue(AttrID: TCSSNumericalID; Value: TCSSElement): boolean;
   end;
 
 type
@@ -249,10 +250,18 @@ type
     Next, Prev: TCSSElResolverData;
   end;
 
+  TCSSValueValidity = (
+    cvvNone,
+    cvvValid,
+    cvvInvalid
+    );
+  TCSSValueValidities = set of TCSSValueValidity;
+
   TCSSIdentifierData = class(TCSSElResolverData)
   public
     NumericalID: TCSSNumericalID;
     Kind: TCSSNumericalIDKind;
+    ValueValid: TCSSValueValidity;
   end;
 
   TCSSValueData = class(TCSSElResolverData)
@@ -385,6 +394,7 @@ type
     function PosWord(const SearchWord, Words: TCSSString): integer; virtual;
     function GetSiblingCount(aNode: ICSSNode): integer; virtual;
     procedure MergeProperty(El: TCSSElement; Specifity: TCSSSpecifity); virtual;
+    function CheckAttrValueValidity(AttrID: TCSSNumericalID; aKey, aValue: TCSSElement): boolean; virtual;
     function ResolveIdentifier(El: TCSSIdentifierElement; Kind: TCSSNumericalIDKind): TCSSNumericalID; virtual;
     function ResolveCall(El: TCSSCallElement): TCSSNumericalID; virtual;
     procedure AddElData(El: TCSSElement; ElData: TCSSElResolverData); virtual;
@@ -1674,9 +1684,13 @@ begin
         begin
           if CompAttr^.Specifity>Specifity then
             exit;
+          if not CheckAttrValueValidity(AttrID,aKey,aValue) then
+            exit;
           CompAttr^.Specifity:=Specifity;
           CompAttr^.Value:=aValue;
         end else begin
+          if not CheckAttrValueValidity(AttrID,aKey,aValue) then
+            exit;
           AddComputedAttribute(AttrID,Specifity,aValue);
         end;
       end;
@@ -1686,6 +1700,25 @@ begin
     Log(etError,20220908230855,'Unknown CSS property',El);
 end;
 
+function TCSSResolver.CheckAttrValueValidity(AttrID: TCSSNumericalID; aKey,
+  aValue: TCSSElement): boolean;
+var
+  Data: TCSSIdentifierData;
+begin
+  if not (aKey.CustomData is TCSSIdentifierData) then
+    raise Exception.Create('TCSSResolver.CheckAttrValueValidity 20221019173901');
+  Data:=TCSSIdentifierData(aKey.CustomData);
+  case Data.ValueValid of
+  cvvValid: exit(true);
+  cvvInvalid: exit(false);
+  end;
+  Result:=FNode.CheckCSSValue(AttrID,aValue);
+  if Result then
+    Data.ValueValid:=cvvValid
+  else
+    Data.ValueValid:=cvvInvalid;
+end;
+
 function TCSSResolver.ResolveIdentifier(El: TCSSIdentifierElement;
   Kind: TCSSNumericalIDKind): TCSSNumericalID;
 var

+ 10 - 0
packages/fcl-css/tests/tccssresolver.pp

@@ -90,6 +90,8 @@ type
     function GetCSSTypeID: TCSSNumericalID;
     class function GetAttributeInitialValue(Attr: TDemoNodeAttribute): string; virtual;
     function HasCSSClass(const aClassName: TCSSString): boolean; virtual;
+    function CheckCSSValue(AttrID: TCSSNumericalID; Value: TCSSElement
+      ): boolean; virtual;
     procedure SetCSSValue(AttrID: TCSSNumericalID; Value: TCSSElement); virtual;
     function GetCSSParent: ICSSNode; virtual;
     function GetCSSIndex: integer; virtual;
@@ -1569,6 +1571,14 @@ begin
   Result:=false;
 end;
 
+function TDemoNode.CheckCSSValue(AttrID: TCSSNumericalID; Value: TCSSElement
+  ): boolean;
+begin
+  if (AttrID<DemoAttrIDBase) or (AttrID>ord(High(TDemoNodeAttribute))+DemoAttrIDBase) then
+    exit(false);
+  Result:=Value<>nil;
+end;
+
 procedure TDemoNode.SetCSSValue(AttrID: TCSSNumericalID; Value: TCSSElement);
 var
   Attr: TDemoNodeAttribute;