瀏覽代碼

dom: SetStyleAttr: no need for resolver

mattias 11 月之前
父節點
當前提交
d13c341fce
共有 4 個文件被更改,包括 74 次插入43 次删除
  1. 11 0
      demo/Combobox/DemoCombobox.pas
  2. 43 27
      src/base/fcl-css/fpcssresparser.pas
  3. 12 9
      src/base/fresnel.dom.pas
  4. 8 7
      src/base/fresnel.layouter.pas

+ 11 - 0
demo/Combobox/DemoCombobox.pas

@@ -17,6 +17,7 @@ type
     FItemIndex: integer;
     FItemIndex: integer;
     FItems: TStrings;
     FItems: TStrings;
     FOnChange: TNotifyEvent;
     FOnChange: TNotifyEvent;
+    procedure CaptionDivMouseDown(Event: TAbstractEvent);
     function GetCaption: string;
     function GetCaption: string;
     procedure SetCaption(const AValue: string);
     procedure SetCaption(const AValue: string);
     procedure SetItemIndex(const AValue: integer);
     procedure SetItemIndex(const AValue: integer);
@@ -141,6 +142,14 @@ begin
     Result:='';
     Result:='';
 end;
 end;
 
 
+procedure TDemoCombobox.CaptionDivMouseDown(Event: TAbstractEvent);
+begin
+  if Menu.GetStyleAttr('display')='none' then
+    Menu.SetStyleAttr('display','')
+  else
+    Menu.SetStyleAttr('display','none');
+end;
+
 procedure TDemoCombobox.SetCaption(const AValue: string);
 procedure TDemoCombobox.SetCaption(const AValue: string);
 begin
 begin
   if CaptionLabel<>nil then
   if CaptionLabel<>nil then
@@ -161,6 +170,7 @@ begin
     Name:='CaptionDiv';
     Name:='CaptionDiv';
     CSSClasses.Add('ComboboxCaption');
     CSSClasses.Add('ComboboxCaption');
     Parent:=Self;
     Parent:=Self;
+    AddEventListener(evtMouseDown,@CaptionDivMouseDown);
   end;
   end;
 
 
   CaptionLabel:=TLabel.Create(Self);
   CaptionLabel:=TLabel.Create(Self);
@@ -182,6 +192,7 @@ begin
   with Menu do begin
   with Menu do begin
     Name:='Menu';
     Name:='Menu';
     CSSClasses.Add('ComboboxMenu');
     CSSClasses.Add('ComboboxMenu');
+    SetStyleAttr('display','none');
     Parent:=Self;
     Parent:=Self;
   end;
   end;
 
 

+ 43 - 27
src/base/fcl-css/fpcssresparser.pas

@@ -563,11 +563,13 @@ type
     function GetCompString(const aValue: string; const ResValue: TCSSResCompValue): TCSSString; overload;
     function GetCompString(const aValue: string; const ResValue: TCSSResCompValue): TCSSString; overload;
     // low level functions to parse attribute components
     // low level functions to parse attribute components
     function ReadComp(var aComp: TCSSResCompValue): boolean; // true if parsing attribute can continue
     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
     // registry
     function GetAttributeID(const aName: TCSSString; AutoCreate: boolean = false): TCSSNumericalID; virtual;
     function GetAttributeID(const aName: TCSSString; AutoCreate: boolean = false): TCSSNumericalID; virtual;
     function GetAttributeDesc(AttrID: TCSSNumericalID): TCSSAttributeDesc; virtual;
     function GetAttributeDesc(AttrID: TCSSNumericalID): TCSSAttributeDesc; virtual;
@@ -1630,6 +1632,34 @@ begin
 end;
 end;
 
 
 function TCSSBaseResolver.ReadComp(var aComp: TCSSResCompValue): boolean;
 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
 var
   c: TCSSChar;
   c: TCSSChar;
   p: PCSSChar;
   p: PCSSChar;
@@ -1755,7 +1785,7 @@ begin
   aComp.EndP:=p;
   aComp.EndP:=p;
 end;
 end;
 
 
-function TCSSBaseResolver.ReadNumber(var aComp: TCSSResCompValue): boolean;
+class function TCSSBaseResolver.ReadNumber(var aComp: TCSSResCompValue): boolean;
 var
 var
   Negative, HasNumber: Boolean;
   Negative, HasNumber: Boolean;
   Divisor: double;
   Divisor: double;
@@ -1871,9 +1901,8 @@ begin
   //writeln('TCSSBaseResolver.ReadNumber "',p,'" Value=',FloatToCSSStr(aComp.Float),' U=',U,' Kind=',aComp.Kind,' Result=',Result);
   //writeln('TCSSBaseResolver.ReadNumber "',p,'" Value=',FloatToCSSStr(aComp.Float),' U=',U,' Kind=',aComp.Kind,' Result=',Result);
 end;
 end;
 
 
-function TCSSBaseResolver.ReadIdentifier(var aComp: TCSSResCompValue): boolean;
+class function TCSSBaseResolver.ReadIdentifier(var aComp: TCSSResCompValue): boolean;
 var
 var
-  Identifier: TCSSString;
   IsFunc: Boolean;
   IsFunc: Boolean;
   p: PCSSChar;
   p: PCSSChar;
 begin
 begin
@@ -1884,34 +1913,21 @@ begin
   repeat
   repeat
     inc(p);
     inc(p);
   until not (p^ in AlNumIden);
   until not (p^ in AlNumIden);
-  SetString(Identifier,aComp.StartP,p-aComp.StartP);
   IsFunc:=p^='(';
   IsFunc:=p^='(';
   if IsFunc then
   if IsFunc then
   begin
   begin
     // function call
     // function call
+    aComp.Kind:=rvkFunctionUnknown;
     aComp.BracketOpen:=p;
     aComp.BracketOpen:=p;
     if not SkipBrackets(p) then
     if not SkipBrackets(p) then
     begin
     begin
       aComp.EndP:=p;
       aComp.EndP:=p;
       exit;
       exit;
     end;
     end;
-  end;
+  end else
+    aComp.Kind:=rvkKeywordUnknown;
   aComp.EndP:=p;
   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;
   Result:=true;
 end;
 end;
 
 
@@ -2007,7 +2023,7 @@ begin
     SetString(Result,Start,ResValue.EndP-Start);
     SetString(Result,Start,ResValue.EndP-Start);
 end;
 end;
 
 
-procedure TCSSBaseResolver.SkipToEndOfAttribute(var p: PCSSChar);
+class procedure TCSSBaseResolver.SkipToEndOfAttribute(var p: PCSSChar);
 begin
 begin
   repeat
   repeat
     case p^ of
     case p^ of
@@ -2018,7 +2034,7 @@ begin
   until false;
   until false;
 end;
 end;
 
 
-function TCSSBaseResolver.SkipString(var p: PCSSChar): boolean;
+class function TCSSBaseResolver.SkipString(var p: PCSSChar): boolean;
 var
 var
   Delim, c: TCSSChar;
   Delim, c: TCSSChar;
 begin
 begin
@@ -2038,7 +2054,7 @@ begin
   until false;
   until false;
 end;
 end;
 
 
-function TCSSBaseResolver.SkipBrackets(var p: PCSSChar; Lvl: integer): boolean;
+class function TCSSBaseResolver.SkipBrackets(var p: PCSSChar; Lvl: integer): boolean;
 const
 const
   CSSMaxBracketLvl = 10;
   CSSMaxBracketLvl = 10;
 var
 var

+ 12 - 9
src/base/fresnel.dom.pas

@@ -6147,18 +6147,18 @@ begin
   aComp.EndP:=PChar(FStyle);
   aComp.EndP:=PChar(FStyle);
   repeat
   repeat
     // read attribute name
     // read attribute name
-    if not Resolver.ReadComp(aComp) then exit;
-    if not (aComp.Kind in [rvkKeyword,rvkKeywordUnknown]) then exit;
+    if not TCSSResolver.ReadValue(aComp) then exit;
+    if aComp.Kind<>rvkKeywordUnknown then exit;
     l:=aComp.EndP-aComp.StartP;
     l:=aComp.EndP-aComp.StartP;
     Found:=(l=length(AttrName)) and CompareMem(aComp.StartP,NameP,l);
     Found:=(l=length(AttrName)) and CompareMem(aComp.StartP,NameP,l);
     // read colon
     // read colon
-    if not Resolver.ReadComp(aComp) then exit;
+    if not TCSSResolver.ReadValue(aComp) then exit;
     if aComp.StartP^<>':' then exit;
     if aComp.StartP^<>':' then exit;
     // read value
     // read value
     StartP:=nil;
     StartP:=nil;
     EndP:=nil;
     EndP:=nil;
     repeat
     repeat
-      if not Resolver.ReadComp(aComp)  then break;
+      if not TCSSResolver.ReadValue(aComp)  then break;
       if aComp.StartP^=';'  then break;
       if aComp.StartP^=';'  then break;
       if Found and (StartP=nil) then
       if Found and (StartP=nil) then
         StartP:=aComp.StartP;
         StartP:=aComp.StartP;
@@ -6197,7 +6197,7 @@ begin
   ValueEmpty:=true;
   ValueEmpty:=true;
   repeat
   repeat
     // read attribute name
     // read attribute name
-    if not Resolver.ReadComp(aComp) then
+    if not TCSSResolver.ReadValue(aComp) then
     begin
     begin
       if aComp.Kind=rvkInvalid then
       if aComp.Kind=rvkInvalid then
         exit; // syntax error in aValue
         exit; // syntax error in aValue
@@ -6212,21 +6212,21 @@ begin
   aComp.EndP:=PChar(FStyle);
   aComp.EndP:=PChar(FStyle);
   repeat
   repeat
     // read attribute name
     // read attribute name
-    if not Resolver.ReadComp(aComp) then break;
+    if not TCSSResolver.ReadValue(aComp) then break;
     if not (aComp.Kind in [rvkKeyword,rvkKeywordUnknown]) then
     if not (aComp.Kind in [rvkKeyword,rvkKeywordUnknown]) then
       exit; // syntax error in Style
       exit; // syntax error in Style
     NameStartP:=aComp.StartP;
     NameStartP:=aComp.StartP;
     l:=aComp.EndP-aComp.StartP;
     l:=aComp.EndP-aComp.StartP;
     Found:=(l=length(AttrName)) and CompareMem(aComp.StartP,NameP,l);
     Found:=(l=length(AttrName)) and CompareMem(aComp.StartP,NameP,l);
     // read colon
     // read colon
-    if not Resolver.ReadComp(aComp) then
+    if not TCSSResolver.ReadValue(aComp) then
       exit; // syntax error in Style
       exit; // syntax error in Style
     if aComp.StartP^<>':' then exit;
     if aComp.StartP^<>':' then exit;
     // read value
     // read value
     StartP:=nil;
     StartP:=nil;
     EndP:=nil;
     EndP:=nil;
     repeat
     repeat
-      if not Resolver.ReadComp(aComp) then break;
+      if not TCSSResolver.ReadValue(aComp) then break;
       if (aComp.StartP^=';') then
       if (aComp.StartP^=';') then
       begin
       begin
         if Found then
         if Found then
@@ -6269,6 +6269,7 @@ begin
           exit(true); // no change
           exit(true); // no change
         FStyle:=LeftStr(FStyle,StartP-p)+aValue+copy(FStyle,EndP-p+1,length(FStyle));
         FStyle:=LeftStr(FStyle,StartP-p)+aValue+copy(FStyle,EndP-p+1,length(FStyle));
       end;
       end;
+      Include(FStates,fesStyleChanged);
       DomChanged;
       DomChanged;
       exit(true);
       exit(true);
     end;
     end;
@@ -6288,6 +6289,7 @@ begin
   end
   end
   else
   else
     FStyle:=AttrName+':'+aValue;
     FStyle:=AttrName+':'+aValue;
+  Include(FStates,fesStyleChanged);
   DomChanged;
   DomChanged;
   Result:=true;
   Result:=true;
 end;
 end;
@@ -7567,7 +7569,7 @@ begin
   if Value='' then
   if Value='' then
     exit;
     exit;
   aComp.EndP:=PChar(Value);
   aComp.EndP:=PChar(Value);
-  if (not Resolver.ReadComp(aComp)) or (aComp.Kind<>rvkFloat) or IsNan(aComp.Float) then
+  if (not TCSSResolver.ReadValue(aComp)) or (aComp.Kind<>rvkFloat) or IsNan(aComp.Float) then
     exit;
     exit;
   case aComp.FloatUnit of
   case aComp.FloatUnit of
   cuNone:
   cuNone:
@@ -7609,6 +7611,7 @@ begin
     exit;
     exit;
 
 
   aValue:=GetCSSString(CSSRegistry.FresnelAttrs[fcaDisplay].Index,false,Complete);
   aValue:=GetCSSString(CSSRegistry.FresnelAttrs[fcaDisplay].Index,false,Complete);
+
   aComp.EndP:=PChar(aValue);
   aComp.EndP:=PChar(aValue);
   repeat
   repeat
     if not Resolver.ReadComp(aComp) then break;
     if not Resolver.ReadComp(aComp) then break;

+ 8 - 7
src/base/fresnel.layouter.pas

@@ -1638,10 +1638,11 @@ begin
 
 
   ChildEl:=ChildNode.Element;
   ChildEl:=ChildNode.Element;
 
 
-  { $IFDEF VerboseFresnelPlacing}
+  {$IFDEF VerboseFresnelPlacing}
   //if ChildEl.Name='Div1' then
   //if ChildEl.Name='Div1' then
-    writeln('TFLFlowLayouter.PlaceAbsoluteItem ',ChildEl.GetPath,' ',aMode,' Commit=',Commit,' Left=',FloatToCSSStr(ChildNode.Left),',Top=',FloatToCSSStr(ChildNode.Top),',Right=',FloatToCSSStr(ChildNode.Right),',Bottom=',FloatToCSSStr(ChildNode.Bottom),' Width=',FloatToCSSStr(ChildNode.Width),' Height=',FloatToCSSStr(ChildNode.Height),' Default=',FloatToCSSStr(DefaultPos.X),',',FloatToCSSStr(DefaultPos.Y));
-  { $ENDIF}
+    writeln('TFLLineLayouter.PlaceAbsoluteItem ',ChildEl.GetPath,' ',aMode,' Commit=',Commit,' Left=',FloatToCSSStr(ChildNode.Left),',Top=',FloatToCSSStr(ChildNode.Top),',Right=',FloatToCSSStr(ChildNode.Right),',Bottom=',FloatToCSSStr(ChildNode.Bottom),' Width=',FloatToCSSStr(ChildNode.Width),' Height=',FloatToCSSStr(ChildNode.Height),' Default=',FloatToCSSStr(DefaultPos.X),',',FloatToCSSStr(DefaultPos.Y));
+    writeln('TFLLineLayouter.PlaceAbsoluteItem ',CSSRegistry.Keywords[ChildEl.ComputedDisplayOutside],' ',CSSRegistry.Keywords[ChildEl.ComputedDisplayInside],' Style=',ChildEl.Style);
+  {$ENDIF}
   NewLeft:=ChildNode.Left;
   NewLeft:=ChildNode.Left;
   NewTop:=ChildNode.Top;
   NewTop:=ChildNode.Top;
   NewRight:=ChildNode.Right;
   NewRight:=ChildNode.Right;
@@ -1751,11 +1752,11 @@ begin
     r.Bottom:=R.Top+NewHeight;
     r.Bottom:=R.Top+NewHeight;
     ChildEl.UsedContentBox:=r;
     ChildEl.UsedContentBox:=r;
 
 
-    { $IFDEF VerboseFresnelPlacing}
-    writeln('TFLFlowLayouter.PlaceAbsoluteItem '+ChildEl.GetPath+' BorderBox='+ChildEl.UsedBorderBox.ToString);
+    {$IFDEF VerboseFresnelPlacing}
+    writeln('TFLLineLayouter.PlaceAbsoluteItem '+ChildEl.GetPath+' BorderBox='+ChildEl.UsedBorderBox.ToString);
     //if ChildEl.Name='Div1' then
     //if ChildEl.Name='Div1' then
-    //writeln('TFLFlowLayouter.PlaceAbsoluteItem ',ChildEl.GetPath,' ',aMode,' Commit Left=',FloatToCSSStr(ChildNode.Left),',Top=',FloatToCSSStr(ChildNode.Top),',Right=',FloatToCSSStr(ChildNode.Right),',Bottom=',FloatToCSSStr(ChildNode.Bottom),' Width=',FloatToCSSStr(ChildNode.Width),' Height=',FloatToCSSStr(ChildNode.Height));
-    { $ENDIF}
+    //writeln('TFLLineLayouter.PlaceAbsoluteItem ',ChildEl.GetPath,' ',aMode,' Commit Left=',FloatToCSSStr(ChildNode.Left),',Top=',FloatToCSSStr(ChildNode.Top),',Right=',FloatToCSSStr(ChildNode.Right),',Bottom=',FloatToCSSStr(ChildNode.Bottom),' Width=',FloatToCSSStr(ChildNode.Width),' Height=',FloatToCSSStr(ChildNode.Height));
+    {$ENDIF}
   end;
   end;
 end;
 end;