Преглед на файлове

inspector: add elements for declarations

mattias преди 3 седмици
родител
ревизия
1213f4286d
променени са 3 файла, в които са добавени 164 реда и са изтрити 55 реда
  1. 1 1
      demo/Inspector/InspDemoForm1.pas
  2. 19 1
      demo/Inspector/InspDemoStyles1.pas
  3. 144 53
      demo/Inspector/fresnel.cssstyleinspector.pas

+ 1 - 1
demo/Inspector/InspDemoForm1.pas

@@ -41,7 +41,7 @@ begin
   with Div1 do begin
     Name:='Div1';
     Parent:=Body;
-    Style:='Height: 100px; padding-left: 5px;';
+    Style:='height: 100px; padding-left: 5px;';
   end;
 
   Label1:=TLabel.Create(Self);

+ 19 - 1
demo/Inspector/InspDemoStyles1.pas

@@ -17,6 +17,7 @@ type
     FBody: TBody;
     FCSSStyleInspector: TCSSStyleInspector;
   public
+    procedure ApplyCSS; override;
     property Body: TBody read FBody;
     property CSSStyleInspector: TCSSStyleInspector read FCSSStyleInspector;
   end;
@@ -43,8 +44,25 @@ begin
     Name:='CSSStyleInspector';
     Parent:=Body;
   end;
+end;
+
+procedure TDemoStylesWindow.ApplyCSS;
 
-  Stylesheet.Text:='div { padding: 2px; border: 3px solid blue; margin: 6px; }';
+  procedure W(Prefix: string; El: TFresnelElement);
+  var
+    i: Integer;
+  begin
+    El.CSSClasses.Delimiter:=',';
+    writeln(Prefix,'Name="',El.Name,'":',El.ClassName,' Classes="',El.CSSClasses.DelimitedText,'"');
+    for i:=0 to El.NodeCount-1 do
+      W(Prefix+'  ',El.Nodes[i]);
+  end;
+
+begin
+  inherited ApplyCSS;
+  writeln('TDemoStylesWindow.ApplyCSS START');
+  W('',Self);
+  writeln('TDemoStylesWindow.ApplyCSS END');
 end;
 
 end.

+ 144 - 53
demo/Inspector/fresnel.cssstyleinspector.pas

@@ -18,11 +18,13 @@ type
     FLock: integer;
     FInspectNeeded: boolean;
     FTarget: TFresnelElement;
-    procedure OnTargetDomChanged(Event: TAbstractEvent);
+    procedure OnTargetCSSApplied(Event: TAbstractEvent);
     procedure SetTarget(const AValue: TFresnelElement);
   protected
     procedure Inspect;
-    procedure AddRule(Row: integer; Selectors, Origin: TCSSString; RuleEl: TCSSRuleElement);
+    procedure UpdateRule(Row: integer; Selectors, Origin: TCSSString; RuleEl: TCSSRuleElement);
+    procedure UpdateDeclaration(RuleDiv: TDiv; Row: integer; DeclEl: TCSSDeclarationElement);
+    procedure UpdateLabel(DeclDiv: TDiv; Index: integer; aClass, aCaption: string);
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
   public
     const
@@ -33,6 +35,11 @@ type
       RuleBracketLabelClass = 'CSSStyleInspRuleBracket';
       RuleOriginLabelClass = 'CSSStyleInspOrigin';
       RuleFooterDivClass = 'CSSStyleInspFooter';
+      DeclDivClass = 'CSSStyleInspDecl';
+      DeclKeyLabelClass = 'CSSStyleInspKey';
+      DeclColonLabelClass = 'CSSStyleInspColon';
+      DeclValueLabelClass = 'CSSStyleInspValue';
+      SkippedClass = 'CSSStyleInspSkipped';
   public
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
@@ -62,16 +69,16 @@ begin
     VP:=Target.Viewport;
     if VP<>nil then
     begin
-      VP.AddEventListener(evtViewportCSSApplied,@OnTargetDomChanged);
+      VP.AddEventListener(evtViewportCSSApplied,@OnTargetCSSApplied);
       if VP.Rendered then
         Inspect;
     end;
   end;
 end;
 
-procedure TCSSStyleInspector.OnTargetDomChanged(Event: TAbstractEvent);
+procedure TCSSStyleInspector.OnTargetCSSApplied(Event: TAbstractEvent);
 begin
-  writeln('TCSSStyleInspector.OnTargetDomChanged ',Event.Sender<>nil);
+  writeln('TCSSStyleInspector.OnTargetCSSApplied ',Event.Sender<>nil);
   Inspect;
 end;
 
@@ -113,7 +120,7 @@ begin
     Row:=0;
 
     // Element.Style aka inline style
-    AddRule(Row,'Element.Style','',Target.StyleElement);
+    UpdateRule(Row,'Element.Style','',Target.StyleElement);
     inc(Row);
 
     // CSS rules
@@ -148,7 +155,7 @@ begin
       end;
       writeln('TCSSStyleInspector.Inspect ',i,' Spec=',aRule.Specificity,' Selector="',Selectors,'" Src=',RuleOrigin);
 
-      AddRule(Row,Selectors,RuleOrigin,RuleEl);
+      UpdateRule(Row,Selectors,RuleOrigin,RuleEl);
       inc(Row);
     end;
 
@@ -160,14 +167,11 @@ begin
   end;
 end;
 
-procedure TCSSStyleInspector.AddRule(Row: integer; Selectors, Origin: TCSSString;
+procedure TCSSStyleInspector.UpdateRule(Row: integer; Selectors, Origin: TCSSString;
   RuleEl: TCSSRuleElement);
 var
-  i, j: Integer;
-  ChildEl, KeyEl: TCSSElement;
-  DeclEl: TCSSDeclarationElement;
-  ResolvedKeyEl: TCSSResolvedIdentifierElement;
-  Src: String;
+  i, SubRow: Integer;
+  ChildEl: TCSSElement;
   CurDiv, HeaderDiv, FooterDiv: TDiv;
   BracketCloseLabel, BracketOpenLabel, SelectorLabel, OriginLabel: TLabel;
 begin
@@ -191,8 +195,9 @@ begin
     HeaderDiv.CSSClasses.Text:=RuleHeaderDivClass;
     HeaderDiv.Parent:=CurDiv;
 
+    // todo: highlight not matching rules
     SelectorLabel:=TLabel.Create(Self);
-    SelectorLabel.CSSClasses.Text:=RuleBracketLabelClass;
+    SelectorLabel.CSSClasses.Text:=RuleSelectorLabelClass;
     SelectorLabel.Caption:=Selectors;
     SelectorLabel.Parent:=HeaderDiv;
 
@@ -208,7 +213,7 @@ begin
 
     // footer: "}"
     FooterDiv:=TDiv.Create(Self);
-    FooterDiv.CSSClasses.Text:=RuleHeaderDivClass;
+    FooterDiv.CSSClasses.Text:=RuleFooterDivClass;
     FooterDiv.Parent:=CurDiv;
 
     BracketCloseLabel:=TLabel.Create(Self);
@@ -221,54 +226,131 @@ begin
 
   if RuleEl<>nil then
   begin
+    SubRow:=1;
     for i:=0 to RuleEl.ChildCount-1 do
     begin
       ChildEl:=RuleEl.Children[i];
       //writeln('  Child ',i,' ',ChildEl.ClassName);
       if ChildEl is TCSSDeclarationElement then
       begin
-        DeclEl:=TCSSDeclarationElement(ChildEl);
-        Src:='';
-        if DeclEl.KeyCount<>1 then
-        begin
-          // todo: multi key declaration
-          continue;
-        end;
-        KeyEl:=DeclEl.Keys[0];
-        if KeyEl is TCSSResolvedIdentifierElement then
-        begin
-          ResolvedKeyEl:=TCSSResolvedIdentifierElement(KeyEl);
-          Src+=ResolvedKeyEl.Name;
-
-          Src+=' : ';
-          For j:=0 to DeclEl.ChildCount-1 do
-          begin
-            if j>0 then
-              Src+=', ';
-            Src+=DeclEl.Children[j].AsFormattedString;
-          end;
-          if DeclEl.IsImportant then
-            Src+=' !important';
-          if ResolvedKeyEl.NumericalID<=CSSIDNone then
-          begin
-            // unknown attribute
-            writeln('TCSSStyleInspector.AddRule Unknown attribute: ',i,' "',Src,'"');
-          end else begin
-            // todo: check for validity
-            // todo: check if already set
-            // todo: split shorthands
-            writeln('TCSSStyleInspector.AddRule Known: ',i,' "',Src,'"');
-          end;
-        end else begin
-          // todo: unknown declaration
-          writeln('TCSSStyleInspector.AddRule Invalid: ',i,' "',DeclEl.AsFormattedString,'"');
-        end;
-        // todo: !important
+        UpdateDeclaration(CurDiv,SubRow,TCSSDeclarationElement(ChildEl));
+        inc(SubRow);
       end;
     end;
   end;
 end;
 
+procedure TCSSStyleInspector.UpdateDeclaration(RuleDiv: TDiv; Row: integer;
+  DeclEl: TCSSDeclarationElement);
+var
+  KeyEl: TCSSElement;
+  ResolvedKeyEl: TCSSResolvedIdentifierElement;
+  ValueTxt, KeyTxt: String;
+  i, Index: Integer;
+  DeclDiv: TDiv;
+begin
+  // add or update div
+  if Row<RuleDiv.NodeCount-1 then // -1 for the footer
+  begin
+    DeclDiv:=RuleDiv.Nodes[Row] as TDiv;
+  end else begin
+    DeclDiv:=TDiv.Create(Self);
+    DeclDiv.CSSClasses.text:=DeclDivClass;
+    RuleDiv.InsertBefore(DeclDiv,RuleDiv.Nodes[Row]);
+  end;
+
+  KeyTxt:='';
+  for i:=0 to DeclEl.KeyCount-1 do
+  begin
+    if i>0 then
+      KeyTxt+=', ';
+    KeyTxt+=DeclEl.Keys[i].AsFormattedString;
+  end;
+
+  ValueTxt:='';
+  for i:=0 to DeclEl.ChildCount-1 do
+  begin
+    if i>0 then
+      ValueTxt+=', ';
+    ValueTxt+=DeclEl.Children[i].AsFormattedString;
+  end;
+  if DeclEl.IsImportant then
+    ValueTxt+=' !important';
+
+  Index:=0;
+  if (DeclEl.KeyCount<>1) then
+  begin
+    // unsupported declaration
+  end else begin
+    KeyEl:=DeclEl.Keys[0];
+    if KeyEl is TCSSResolvedIdentifierElement then
+    begin
+      ResolvedKeyEl:=TCSSResolvedIdentifierElement(KeyEl);
+      if ResolvedKeyEl.NumericalID<=CSSIDNone then
+      begin
+        // unknown attribute
+        writeln('TCSSStyleInspector.AddDeclaration Unknown attribute: ',i,' "',ValueTxt,'"');
+      end else begin
+        // todo: check for validity
+        // todo: check if overriden
+        // todo: split shorthands
+        writeln('TCSSStyleInspector.AddDeclaration Known: ',i,' "',ValueTxt,'"');
+        UpdateLabel(DeclDiv,Index,DeclKeyLabelClass,KeyTxt);
+        inc(Index);
+        UpdateLabel(DeclDiv,Index,DeclColonLabelClass,':');
+        inc(Index);
+        UpdateLabel(DeclDiv,Index,DeclValueLabelClass,ValueTxt);
+        inc(Index);
+      end;
+    end else begin
+      // todo: unknown declaration
+      writeln('TCSSStyleInspector.AddDeclaration Invalid: ',i,' "',DeclEl.AsFormattedString,'"');
+    end;
+  end;
+
+  if Index=0 then
+  begin
+    // invalid declaration
+    UpdateLabel(DeclDiv,Index,SkippedClass,KeyTxt+': '+ValueTxt);
+    inc(Index);
+  end;
+
+  // delete old elements
+  while DeclDiv.NodeCount>Index do
+    DeclDiv.Nodes[DeclDiv.NodeCount-1].Free;
+end;
+
+procedure TCSSStyleInspector.UpdateLabel(DeclDiv: TDiv; Index: integer; aClass, aCaption: string);
+var
+  aLabel: TLabel;
+  El: TFresnelElement;
+begin
+  writeln('TCSSStyleInspector.UpdateLabel ',Index,' "',aClass,'" "',aCaption,'"');
+  if Index=DeclDiv.NodeCount then
+  begin
+    // add
+    aLabel:=TLabel.Create(Self);
+    aLabel.CSSClasses.Text:=aClass;
+    aLabel.Caption:=aCaption;
+    aLabel.Parent:=DeclDiv;
+  end else begin
+    // update
+    El:=DeclDiv.Nodes[Index];
+    if El is TLabel then
+    begin
+      // update label
+      aLabel.CSSClasses.Text:=aClass;
+      aLabel.Caption:=aCaption;
+    end else begin
+      // insert label
+      aLabel:=TLabel.Create(Self);
+      aLabel.CSSClasses.Text:=aClass;
+      aLabel.Caption:=aCaption;
+      DeclDiv.InsertBefore(aLabel,El);
+    end;
+  end;
+end;
+
 procedure TCSSStyleInspector.Notification(AComponent: TComponent; Operation: TOperation);
 begin
   inherited Notification(AComponent, Operation);
@@ -297,7 +379,16 @@ end;
 
 class function TCSSStyleInspector.GetCSSTypeStyle: TCSSString;
 begin
-  Result:='.'+RulesDivClass+' {  }';
+  Result:=
+     '.'+RulesDivClass+' { font-color: white; background-color: #333 }'+LineEnding
+    //+'.'+RuleSelectorLabelClass+' {  }'+LineEnding
+    +'.'+RuleBracketLabelClass+' { font-weight: bold; }'+LineEnding
+    //+'.'+RuleOriginLabelClass+' {  }'+LineEnding
+    +'.'+RuleFooterDivClass+' { border-bottom: 1px solid #888; }'+LineEnding
+    +'.'+DeclDivClass+' { margin-left: 30px; }'+LineEnding
+    +'.'+DeclKeyLabelClass+' { font-color: cyan; }'+LineEnding
+    +'.'+DeclColonLabelClass+' { margin-right: 1em; }'+LineEnding
+    ;
 end;
 
 procedure TCSSStyleInspector.BeginUpdate;