Browse Source

fcl-css: resolver: parse value without registry

mattias 10 months ago
parent
commit
3dc3d83757
1 changed files with 55 additions and 27 deletions
  1. 55 27
      packages/fcl-css/src/fpcssresparser.pas

+ 55 - 27
packages/fcl-css/src/fpcssresparser.pas

@@ -300,6 +300,9 @@ const
 
 
 type
+
+  { TCSSRegistryNamedItem }
+
   TCSSRegistryNamedItem = class
   public
     Name: TCSSString; // case sensitive
@@ -539,6 +542,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;
@@ -559,11 +563,13 @@ type
     function GetCompString(const aValue: string; const ResValue: TCSSResCompValue): TCSSString; overload;
     // low level functions to parse attribute components
     function ReadComp(var aComp: TCSSResCompValue): boolean; // true if parsing attribute can continue
-    function ReadNumber(var aComp: TCSSResCompValue): boolean;
-    function ReadIdentifier(var aComp: TCSSResCompValue): boolean;
-    procedure SkipToEndOfAttribute(var p: PCSSChar);
-    function SkipString(var p: PCSSChar): boolean;
-    function SkipBrackets(var p: PCSSChar; Lvl: integer = 1): boolean;
+    procedure ReadWordID(var aComp: TCSSResCompValue);
+    class function ReadValue(var aComp: TCSSResCompValue): boolean; // true if parsing attribute can continue, not using CSSRegistry
+    class function ReadNumber(var aComp: TCSSResCompValue): boolean;
+    class function ReadIdentifier(var aComp: TCSSResCompValue): boolean;
+    class procedure SkipToEndOfAttribute(var p: PCSSChar);
+    class function SkipString(var p: PCSSChar): boolean;
+    class function SkipBrackets(var p: PCSSChar; Lvl: integer = 1): boolean;
     // registry
     function GetAttributeID(const aName: TCSSString; AutoCreate: boolean = false): TCSSNumericalID; virtual;
     function GetAttributeDesc(AttrID: TCSSNumericalID): TCSSAttributeDesc; virtual;
@@ -1485,6 +1491,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
@@ -1618,6 +1632,34 @@ begin
 end;
 
 function TCSSBaseResolver.ReadComp(var aComp: TCSSResCompValue): boolean;
+begin
+  Result:=ReadValue(aComp);
+  ReadWordID(aComp);
+end;
+
+procedure TCSSBaseResolver.ReadWordID(var aComp: TCSSResCompValue);
+var
+  Identifier: TCSSString;
+begin
+  case aComp.Kind of
+  rvkFunctionUnknown:
+    begin
+      SetString(Identifier,aComp.StartP,aComp.EndP-aComp.StartP);
+      aComp.FunctionID:=CSSRegistry.IndexOfAttrFunction(Identifier);
+      if aComp.FunctionID>CSSIDNone then
+        aComp.Kind:=rvkFunction;
+    end;
+  rvkKeywordUnknown:
+    begin
+      SetString(Identifier,aComp.StartP,aComp.EndP-aComp.StartP);
+      aComp.KeywordID:=CSSRegistry.IndexOfKeyword(Identifier);
+      if aComp.KeywordID>CSSIDNone then
+        aComp.Kind:=rvkKeyword;
+    end;
+  end;
+end;
+
+class function TCSSBaseResolver.ReadValue(var aComp: TCSSResCompValue): boolean;
 var
   c: TCSSChar;
   p: PCSSChar;
@@ -1743,7 +1785,7 @@ begin
   aComp.EndP:=p;
 end;
 
-function TCSSBaseResolver.ReadNumber(var aComp: TCSSResCompValue): boolean;
+class function TCSSBaseResolver.ReadNumber(var aComp: TCSSResCompValue): boolean;
 var
   Negative, HasNumber: Boolean;
   Divisor: double;
@@ -1859,9 +1901,8 @@ begin
   //writeln('TCSSBaseResolver.ReadNumber "',p,'" Value=',FloatToCSSStr(aComp.Float),' U=',U,' Kind=',aComp.Kind,' Result=',Result);
 end;
 
-function TCSSBaseResolver.ReadIdentifier(var aComp: TCSSResCompValue): boolean;
+class function TCSSBaseResolver.ReadIdentifier(var aComp: TCSSResCompValue): boolean;
 var
-  Identifier: TCSSString;
   IsFunc: Boolean;
   p: PCSSChar;
 begin
@@ -1872,34 +1913,21 @@ begin
   repeat
     inc(p);
   until not (p^ in AlNumIden);
-  SetString(Identifier,aComp.StartP,p-aComp.StartP);
   IsFunc:=p^='(';
   if IsFunc then
   begin
     // function call
+    aComp.Kind:=rvkFunctionUnknown;
     aComp.BracketOpen:=p;
     if not SkipBrackets(p) then
     begin
       aComp.EndP:=p;
       exit;
     end;
-  end;
+  end else
+    aComp.Kind:=rvkKeywordUnknown;
   aComp.EndP:=p;
 
-  if IsFunc then
-  begin
-    aComp.FunctionID:=CSSRegistry.IndexOfAttrFunction(Identifier);
-    if aComp.FunctionID>CSSIDNone then
-      aComp.Kind:=rvkFunction
-    else
-      aComp.Kind:=rvkFunctionUnknown;
-  end else begin
-    aComp.KeywordID:=CSSRegistry.IndexOfKeyword(Identifier);
-    if aComp.KeywordID>CSSIDNone then
-      aComp.Kind:=rvkKeyword
-    else
-      aComp.Kind:=rvkKeywordUnknown;
-  end;
   Result:=true;
 end;
 
@@ -1995,7 +2023,7 @@ begin
     SetString(Result,Start,ResValue.EndP-Start);
 end;
 
-procedure TCSSBaseResolver.SkipToEndOfAttribute(var p: PCSSChar);
+class procedure TCSSBaseResolver.SkipToEndOfAttribute(var p: PCSSChar);
 begin
   repeat
     case p^ of
@@ -2006,7 +2034,7 @@ begin
   until false;
 end;
 
-function TCSSBaseResolver.SkipString(var p: PCSSChar): boolean;
+class function TCSSBaseResolver.SkipString(var p: PCSSChar): boolean;
 var
   Delim, c: TCSSChar;
 begin
@@ -2026,7 +2054,7 @@ begin
   until false;
 end;
 
-function TCSSBaseResolver.SkipBrackets(var p: PCSSChar; Lvl: integer): boolean;
+class function TCSSBaseResolver.SkipBrackets(var p: PCSSChar; Lvl: integer): boolean;
 const
   CSSMaxBracketLvl = 10;
 var