Переглянути джерело

TFresnelCSSAttribute: added border-*-style, border-*-color

mattias 1 рік тому
батько
коміт
59d5dfe1ef
1 змінених файлів з 242 додано та 74 видалено
  1. 242 74
      src/base/fresnel.dom.pas

+ 242 - 74
src/base/fresnel.dom.pas

@@ -72,8 +72,16 @@ type
     fcaBorderRightWidth,
     fcaBorderTopWidth,
     fcaBorderBottomWidth,
-    fcaBorderColor, // todo: shorthand for border-[left,right,top,bottom]-color
-    // todo fcaBorderStyle
+    fcaBorderColor, // shorthand for border-[left,right,top,bottom]-color
+    fcaBorderLeftColor,
+    fcaBorderRightColor,
+    fcaBorderTopColor,
+    fcaBorderBottomColor,
+    fcaBorderStyle, // shorthand for border-[left,right,top,bottom]-style
+    fcaBorderLeftStyle,
+    fcaBorderRightStyle,
+    fcaBorderTopStyle,
+    fcaBorderBottomStyle,
     fcaBoxSizing,
     fcaFloat,
     fcaFont, // shorthand
@@ -143,6 +151,15 @@ const
     'border-top-width',
     'border-bottom-width',
     'border-color',
+    'border-left-color',
+    'border-right-color',
+    'border-top-color',
+    'border-bottom-color',
+    'border-style',
+    'border-left-style',
+    'border-right-style',
+    'border-top-style',
+    'border-bottom-style',
     'box-sizing',
     'float',
     'font',
@@ -365,13 +382,17 @@ type
     function CheckCSSZIndex(const AValue: string): boolean; virtual;
     function CheckCSSDirection(const AValue: string): boolean; virtual;
     function CheckOrSetCSSBorder(const AValue: string; Check: boolean): boolean; virtual;
+    function CheckOrSetCSSBorderX(AttrWidth: TFresnelCSSAttribute; const AValue: string; Check: boolean): boolean; virtual;
     function CheckOrSetCSSBorderLeft(const AValue: string; Check: boolean): boolean; virtual;
     function CheckOrSetCSSBorderTop(const AValue: string; Check: boolean): boolean; virtual;
     function CheckOrSetCSSBorderRight(const AValue: string; Check: boolean): boolean; virtual;
     function CheckOrSetCSSBorderBottom(const AValue: string; Check: boolean): boolean; virtual;
     function CheckOrSetCSSBorderWidth(const AValue: string; Check: boolean): boolean; virtual;
     function CheckCSSBorderXWidth(Attr: TFresnelCSSAttribute; const AValue: string): boolean; virtual;
-    function CheckCSSBorderColor(const AValue: string): boolean; virtual;
+    function CheckOrSetCSSBorderColor(const AValue: string; Check: boolean): boolean; virtual;
+    function CheckCSSBorderXColor(Attr: TFresnelCSSAttribute; const AValue: string): boolean; virtual;
+    function CheckOrSetCSSBorderStyle(const AValue: string; Check: boolean): boolean; virtual;
+    function CheckCSSBorderXStyle(Attr: TFresnelCSSAttribute; const AValue: string): boolean; virtual;
     function CheckCSSBoxSizing(const AValue: string): boolean; virtual;
     function CheckCSSFloat(const AValue: string): boolean; virtual;
     function CheckCSSLineHeight(const AValue: string): boolean; virtual;
@@ -1480,6 +1501,8 @@ begin
   fcaBorderRight: CheckOrSetCSSBorderRight(AValue,false);
   fcaBorderBottom: CheckOrSetCSSBorderBottom(AValue,false);
   fcaBorderWidth: CheckOrSetCSSBorderWidth(AValue,false);
+  fcaBorderStyle: CheckOrSetCSSBorderStyle(AValue,false);
+  fcaBorderColor: CheckOrSetCSSBorderColor(AValue,false);
   fcaFont: CheckOrSetCSSFont(AValue,false);
   fcaMargin: CheckOrSetCSSMargin(AValue,false);
   fcaMarginBlock: CheckOrSetCSSMarginBlock(AValue,false);
@@ -1728,103 +1751,127 @@ function TFresnelElement.CheckOrSetCSSBorder(const AValue: string;
   Check: boolean): boolean;
 var
   p: Integer;
-  aWidth: String;
+  aWidth, aStyle, aColor, s: String;
 begin
   // width, style, color
   p:=1;
-  aWidth:=CSSReadNextValue(AValue,p);
-  //aStyle:=CSSReadNextValue(AValue,p);
-  //aColor:=CSSReadNextValue(AValue,p);
-  if Check then
+  s:=CSSReadNextValue(AValue,p);
+  if CheckCSSBorderXWidth(fcaBorderLeftWidth,s) then
   begin
-    Result:=CheckCSSBorderXWidth(fcaBorderLeftWidth,aWidth);
-  end else begin
-    SetCSSElAttribute(fcaBorderLeftWidth,aWidth);
-    SetCSSElAttribute(fcaBorderTopWidth,aWidth);
-    SetCSSElAttribute(fcaBorderRightWidth,aWidth);
-    SetCSSElAttribute(fcaBorderBottomWidth,aWidth);
-    Result:=true;
+    // first value is width
+    aWidth:=s;
+    s:=CSSReadNextValue(AValue,p);
+  end else
+    aWidth:='';
+  if CheckCSSBorderXStyle(fcaBorderLeftStyle,s) then
+  begin
+    // next value is style
+    aStyle:=s;
+    s:=CSSReadNextValue(AValue,p);
+  end else
+    aStyle:='';
+  if CheckCSSBorderXColor(fcaBorderLeftColor,s) then
+  begin
+    // next value is color
+    aColor:=s;
+    s:=CSSReadNextValue(AValue,p);
+  end;
+  if s>'' then
+    exit(false);
+  if not Check then
+  begin
+    if aWidth>'' then
+    begin
+      SetCSSElAttribute(fcaBorderLeftWidth,aWidth);
+      SetCSSElAttribute(fcaBorderRightWidth,aWidth);
+      SetCSSElAttribute(fcaBorderTopWidth,aWidth);
+      SetCSSElAttribute(fcaBorderBottomWidth,aWidth);
+    end;
+    if aStyle>'' then
+    begin
+      SetCSSElAttribute(fcaBorderLeftStyle,aStyle);
+      SetCSSElAttribute(fcaBorderRightStyle,aStyle);
+      SetCSSElAttribute(fcaBorderTopStyle,aStyle);
+      SetCSSElAttribute(fcaBorderBottomStyle,aStyle);
+    end;
+    if aColor>'' then
+    begin
+      SetCSSElAttribute(fcaBorderLeftColor,aColor);
+      SetCSSElAttribute(fcaBorderRightColor,aColor);
+      SetCSSElAttribute(fcaBorderTopColor,aColor);
+      SetCSSElAttribute(fcaBorderBottomColor,aColor);
+    end;
   end;
 end;
 
-function TFresnelElement.CheckOrSetCSSBorderLeft(const AValue: string;
-  Check: boolean): boolean;
+function TFresnelElement.CheckOrSetCSSBorderX(AttrWidth: TFresnelCSSAttribute;
+  const AValue: string; Check: boolean): boolean;
 var
   p: Integer;
-  aWidth: String;
+  aWidth, aStyle, aColor, s: String;
+  AttrStyle, AttrColor: TFresnelCSSAttribute;
 begin
+  AttrStyle:=TFresnelCSSAttribute(ord(AttrWidth)+ord(fcaBorderLeftStyle)-ord(fcaBorderLeftWidth));
+  AttrColor:=TFresnelCSSAttribute(ord(AttrWidth)+ord(fcaBorderLeftColor)-ord(fcaBorderLeftWidth));
+
   // width, style, color
   p:=1;
-  aWidth:=CSSReadNextValue(AValue,p);
-  //aStyle:=CSSReadNextValue(AValue,p);
-  //aColor:=CSSReadNextValue(AValue,p);
-  if Check then
+  s:=CSSReadNextValue(AValue,p);
+  if CheckCSSBorderXWidth(AttrWidth,s) then
+  begin
+    // first value is width
+    aWidth:=s;
+    s:=CSSReadNextValue(AValue,p);
+  end else
+    aWidth:='';
+  if CheckCSSBorderXStyle(AttrStyle,s) then
   begin
-    Result:=CheckCSSBorderXWidth(fcaBorderLeftWidth,aWidth);
+    // next value is style
+    aStyle:=s;
+    s:=CSSReadNextValue(AValue,p);
   end else
+    aStyle:='';
+  if CheckCSSBorderXColor(AttrColor,s) then
+  begin
+    // next value is color
+    aColor:=s;
+    s:=CSSReadNextValue(AValue,p);
+  end;
+  if s>'' then
+    exit(false);
+  if not Check then
   begin
-    SetCSSElAttribute(fcaBorderLeftWidth,aWidth);
+    if aWidth>'' then
+      SetCSSElAttribute(AttrWidth,aWidth);
+    if aStyle>'' then
+      SetCSSElAttribute(AttrStyle,aStyle);
+    if aColor>'' then
+      SetCSSElAttribute(AttrColor,aColor);
   end;
 end;
 
+function TFresnelElement.CheckOrSetCSSBorderLeft(const AValue: string;
+  Check: boolean): boolean;
+begin
+  Result:=CheckOrSetCSSBorderX(fcaBorderLeftWidth,AValue,Check);
+end;
+
 function TFresnelElement.CheckOrSetCSSBorderTop(const AValue: string;
   Check: boolean): boolean;
-var
-  p: Integer;
-  aWidth: String;
 begin
-  // width, style, color
-  p:=1;
-  aWidth:=CSSReadNextValue(AValue,p);
-  //aStyle:=CSSReadNextValue(AValue,p);
-  //aColor:=CSSReadNextValue(AValue,p);
-  if Check then
-  begin
-    Result:=CheckCSSBorderXWidth(fcaBorderTopWidth,aWidth);
-  end else
-  begin
-    SetCSSElAttribute(fcaBorderTopWidth,aWidth);
-  end;
+  Result:=CheckOrSetCSSBorderX(fcaBorderTopWidth,AValue,Check);
 end;
 
 function TFresnelElement.CheckOrSetCSSBorderRight(const AValue: string;
   Check: boolean): boolean;
-var
-  p: Integer;
-  aWidth: String;
 begin
-  // width, style, color
-  p:=1;
-  aWidth:=CSSReadNextValue(AValue,p);
-  //aStyle:=CSSReadNextValue(AValue,p);
-  //aColor:=CSSReadNextValue(AValue,p);
-  if Check then
-  begin
-    Result:=CheckCSSBorderXWidth(fcaBorderRightWidth,aWidth);
-  end else
-  begin
-    SetCSSElAttribute(fcaBorderRightWidth,aWidth);
-  end;
+  Result:=CheckOrSetCSSBorderX(fcaBorderRightWidth,AValue,Check);
 end;
 
 function TFresnelElement.CheckOrSetCSSBorderBottom(const AValue: string;
   Check: boolean): boolean;
-var
-  p: Integer;
-  aWidth: String;
 begin
-  // width, style, color
-  p:=1;
-  aWidth:=CSSReadNextValue(AValue,p);
-  //aStyle:=CSSReadNextValue(AValue,p);
-  //aColor:=CSSReadNextValue(AValue,p);
-  if Check then
-  begin
-    Result:=CheckCSSBorderXWidth(fcaBorderBottomWidth,aWidth);
-  end else
-  begin
-    SetCSSElAttribute(fcaBorderBottomWidth,aWidth);
-  end;
+  Result:=CheckOrSetCSSBorderX(fcaBorderBottomWidth,AValue,Check);
 end;
 
 function TFresnelElement.CheckOrSetCSSBorderWidth(const AValue: string;
@@ -1838,6 +1885,10 @@ begin
   aRight:=CSSReadNextValue(AValue,p);
   aBottom:=CSSReadNextValue(AValue,p);
   aLeft:=CSSReadNextValue(AValue,p);
+  // 1: all four
+  // 2: top and bottom | left and right
+  // 3: top | left and right | bottom
+  // 4: top | left | right | bottom
   if Check then
   begin
     if not CheckCSSBorderXWidth(fcaBorderTopWidth,aTop) then
@@ -1865,21 +1916,129 @@ end;
 
 function TFresnelElement.CheckCSSBorderXWidth(Attr: TFresnelCSSAttribute;
   const AValue: string): boolean;
+// 10px
+var
+  p: integer;
+  aWidth: String;
 begin
-  case AValue of
+  p:=1;
+  aWidth:=CSSReadNextValue(AValue,p);
+  case aWidth of
   'thin',
   'medium',
   'thick': Result:=true;
   else
-    Result:=CheckCSSLength(Attr,AValue,[flcNoNegative]);
-  end
+    Result:=CheckCSSLength(Attr,aWidth,[flcNoNegative]);
+  end;
+end;
+
+function TFresnelElement.CheckOrSetCSSBorderColor(const AValue: string;
+  Check: boolean): boolean;
+var
+  p: Integer;
+  aTop, aRight, aBottom, aLeft: String;
+begin
+  p:=1;
+  aTop:=CSSReadNextValue(AValue,p);
+  aRight:=CSSReadNextValue(AValue,p);
+  aBottom:=CSSReadNextValue(AValue,p);
+  aLeft:=CSSReadNextValue(AValue,p);
+  // 1: all four
+  // 2: top and bottom | left and right
+  // 3: top | left and right | bottom
+  // 4: top | left | right | bottom
+  if Check then
+  begin
+    if not CheckCSSBorderXColor(fcaBorderTopColor,aTop) then
+      exit(false);
+    if (aRight<>'') and not CheckCSSBorderXColor(fcaBorderRightColor,aRight) then
+      exit(false);
+    if (aBottom<>'') and not CheckCSSBorderXColor(fcaBorderBottomColor,aBottom) then
+      exit(false);
+    if (aLeft<>'') and not CheckCSSBorderXColor(fcaBorderLeftColor,aLeft) then
+      exit(false);
+  end else begin
+    if aRight='' then
+      aRight:=aTop;
+    if aBottom='' then
+      aBottom:=aTop;
+    if aLeft='' then
+      aLeft:=aRight;
+    SetCSSElAttribute(fcaBorderLeftColor,aLeft);
+    SetCSSElAttribute(fcaBorderTopColor,aTop);
+    SetCSSElAttribute(fcaBorderRightColor,aRight);
+    SetCSSElAttribute(fcaBorderBottomColor,aBottom);
+  end;
+  Result:=true;
 end;
 
-function TFresnelElement.CheckCSSBorderColor(const AValue: string): boolean;
+function TFresnelElement.CheckCSSBorderXColor(Attr: TFresnelCSSAttribute;
+  const AValue: string): boolean;
 var
   aColor: TFPColor;
 begin
+  if Attr=fcaBorderLeftColor then ;
   Result:=CSSToFPColor(AValue,aColor);
+  if aColor=colBlack then ;
+end;
+
+function TFresnelElement.CheckOrSetCSSBorderStyle(const AValue: string;
+  Check: boolean): boolean;
+var
+  p: Integer;
+  aTop, aRight, aBottom, aLeft: String;
+begin
+  p:=1;
+  aTop:=CSSReadNextValue(AValue,p);
+  aRight:=CSSReadNextValue(AValue,p);
+  aBottom:=CSSReadNextValue(AValue,p);
+  aLeft:=CSSReadNextValue(AValue,p);
+  // 1: all four
+  // 2: top and bottom | left and right
+  // 3: top | left and right | bottom
+  // 4: top | left | right | bottom
+  if Check then
+  begin
+    if not CheckCSSBorderXStyle(fcaBorderTopStyle,aTop) then
+      exit(false);
+    if (aRight<>'') and not CheckCSSBorderXStyle(fcaBorderRightStyle,aRight) then
+      exit(false);
+    if (aBottom<>'') and not CheckCSSBorderXStyle(fcaBorderBottomStyle,aBottom) then
+      exit(false);
+    if (aLeft<>'') and not CheckCSSBorderXStyle(fcaBorderLeftStyle,aLeft) then
+      exit(false);
+  end else begin
+    if aRight='' then
+      aRight:=aTop;
+    if aBottom='' then
+      aBottom:=aTop;
+    if aLeft='' then
+      aLeft:=aRight;
+    SetCSSElAttribute(fcaBorderLeftColor,aLeft);
+    SetCSSElAttribute(fcaBorderTopColor,aTop);
+    SetCSSElAttribute(fcaBorderRightColor,aRight);
+    SetCSSElAttribute(fcaBorderBottomColor,aBottom);
+  end;
+  Result:=true;
+end;
+
+function TFresnelElement.CheckCSSBorderXStyle(Attr: TFresnelCSSAttribute;
+  const AValue: string): boolean;
+begin
+  if Attr=fcaBorderLeftStyle then ;
+  case AValue of
+  'none',
+  'hidden',
+  'dotted',
+  'solid',
+  'double',
+  'groove',
+  'ridge',
+  'inset',
+  'outset': exit(true);
+  else
+    exit(false);
+  end;
 end;
 
 function TFresnelElement.CheckCSSBoxSizing(const AValue: string): boolean;
@@ -3339,7 +3498,16 @@ begin
     fcaBorderRightWidth,
     fcaBorderTopWidth,
     fcaBorderBottomWidth: Result:=CheckCSSBorderXWidth(Attr,s);
-    fcaBorderColor: Result:=CheckCSSBorderColor(s);
+    fcaBorderColor: Result:=CheckOrSetCSSBorderColor(s,true);
+    fcaBorderLeftColor,
+    fcaBorderRightColor,
+    fcaBorderTopColor,
+    fcaBorderBottomColor: Result:=CheckCSSBorderXColor(Attr,s);
+    fcaBorderStyle: Result:=CheckOrSetCSSBorderStyle(s,true);
+    fcaBorderLeftStyle,
+    fcaBorderRightStyle,
+    fcaBorderTopStyle,
+    fcaBorderBottomStyle: Result:=CheckCSSBorderXStyle(Attr,s);
     fcaBoxSizing: Result:=CheckCSSBoxSizing(s);
     fcaFloat: Result:=CheckCSSFloat(s);
     fcaFont: Result:=CheckCSSFontKerning(s);