|
@@ -208,10 +208,17 @@ type
|
|
{ TCSSAttributeValue }
|
|
{ TCSSAttributeValue }
|
|
|
|
|
|
TCSSAttributeValue = class
|
|
TCSSAttributeValue = class
|
|
|
|
+ public
|
|
|
|
+ type
|
|
|
|
+ TState = (
|
|
|
|
+ cavsSource, // value from CSS - simple normalization, e.g. no comments, some spaces differ, floats
|
|
|
|
+ cavsBaseKeywords, // base keywords resolved e.g. "initial" or "inherit"
|
|
|
|
+ cavsComputed, // has final result
|
|
|
|
+ cavsInvalid // skip this value
|
|
|
|
+ );
|
|
public
|
|
public
|
|
AttrID: TCSSNumericalID; // the resolver has substituted all shorthands
|
|
AttrID: TCSSNumericalID; // the resolver has substituted all shorthands
|
|
- Computed: boolean;
|
|
|
|
- Invalid: boolean;
|
|
|
|
|
|
+ State: TState;
|
|
Value: TCSSString; // the resolver has substituted all var() calls
|
|
Value: TCSSString; // the resolver has substituted all var() calls
|
|
end;
|
|
end;
|
|
TCSSAttributeValueArray = array of TCSSAttributeValue;
|
|
TCSSAttributeValueArray = array of TCSSAttributeValue;
|
|
@@ -220,12 +227,12 @@ type
|
|
|
|
|
|
TCSSAttributeValues = class
|
|
TCSSAttributeValues = class
|
|
public
|
|
public
|
|
- AllValue: TCSSString;
|
|
|
|
|
|
+ AllValue: TCSSNumericalID;
|
|
Values: TCSSAttributeValueArray; // the resolver sorts them ascending for AttrID, shorthands are already replaced with longhands
|
|
Values: TCSSAttributeValueArray; // the resolver sorts them ascending for AttrID, shorthands are already replaced with longhands
|
|
procedure SortValues; virtual; // ascending AttrID
|
|
procedure SortValues; virtual; // ascending AttrID
|
|
procedure SwapValues(Index1, Index2: integer);
|
|
procedure SwapValues(Index1, Index2: integer);
|
|
function IndexOf(AttrID: TCSSNumericalID): integer;
|
|
function IndexOf(AttrID: TCSSNumericalID): integer;
|
|
- function GetValue(AttrDesc: TCSSAttributeDesc): TCSSString;
|
|
|
|
|
|
+ procedure SetComputedValue(AttrID: TCSSNumericalID; const aValue: TCSSString);
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -290,7 +297,7 @@ type
|
|
type
|
|
type
|
|
TStyleSheet = class
|
|
TStyleSheet = class
|
|
Source: TCSSString;
|
|
Source: TCSSString;
|
|
- Filename: TCSSString;
|
|
|
|
|
|
+ Name: TCSSString; // case sensitive
|
|
Origin: TCSSOrigin;
|
|
Origin: TCSSOrigin;
|
|
Element: TCSSElement;
|
|
Element: TCSSElement;
|
|
Parsed: boolean;
|
|
Parsed: boolean;
|
|
@@ -352,6 +359,7 @@ type
|
|
// parse stylesheets
|
|
// parse stylesheets
|
|
procedure ParseSource(Index: integer); virtual;
|
|
procedure ParseSource(Index: integer); virtual;
|
|
function ParseCSSSource(const Src: TCSSString; Inline: boolean): TCSSElement; virtual;
|
|
function ParseCSSSource(const Src: TCSSString; Inline: boolean): TCSSElement; virtual;
|
|
|
|
+ procedure ClearElements; virtual;
|
|
|
|
|
|
// resolving rules
|
|
// resolving rules
|
|
procedure ComputeElement(El: TCSSElement); virtual;
|
|
procedure ComputeElement(El: TCSSElement); virtual;
|
|
@@ -391,7 +399,7 @@ type
|
|
function CreateSharedRuleList: TCSSSharedRuleList; virtual; // using FElRules, sets FMergedAttributes
|
|
function CreateSharedRuleList: TCSSSharedRuleList; virtual; // using FElRules, sets FMergedAttributes
|
|
|
|
|
|
// merge properties
|
|
// merge properties
|
|
- procedure InitMerge; virtual;
|
|
|
|
|
|
+ procedure ClearMerge; virtual;
|
|
procedure SetMergedAttribute(AttrID, aSpecifity: TCSSNumericalID; DeclEl: TCSSDeclarationElement);
|
|
procedure SetMergedAttribute(AttrID, aSpecifity: TCSSNumericalID; DeclEl: TCSSDeclarationElement);
|
|
procedure RemoveMergedAttribute(AttrID: TCSSNumericalID);
|
|
procedure RemoveMergedAttribute(AttrID: TCSSNumericalID);
|
|
procedure MergeAttribute(El: TCSSElement; aSpecifity: TCSSSpecifity); virtual;
|
|
procedure MergeAttribute(El: TCSSElement; aSpecifity: TCSSSpecifity); virtual;
|
|
@@ -411,21 +419,24 @@ type
|
|
procedure Init; virtual; // call after adding stylesheets and before computing all nodes
|
|
procedure Init; virtual; // call after adding stylesheets and before computing all nodes
|
|
function GetElPath(El: TCSSElement): TCSSString; virtual;
|
|
function GetElPath(El: TCSSElement): TCSSString; virtual;
|
|
function GetElPos(El: TCSSElement): TCSSString; virtual;
|
|
function GetElPos(El: TCSSElement): TCSSString; virtual;
|
|
- function ParseInlineStyle(const Src: TCSSString): TCSSElement; virtual;
|
|
|
|
|
|
+ function ParseInlineStyle(const Src: TCSSString): TCSSRuleElement; virtual;
|
|
procedure Compute(Node: ICSSNode;
|
|
procedure Compute(Node: ICSSNode;
|
|
InlineStyle: TCSSRuleElement; // inline style of Node
|
|
InlineStyle: TCSSRuleElement; // inline style of Node
|
|
out Rules: TCSSSharedRuleList {owned by resolver};
|
|
out Rules: TCSSSharedRuleList {owned by resolver};
|
|
out Values: TCSSAttributeValues
|
|
out Values: TCSSAttributeValues
|
|
); virtual;
|
|
); virtual;
|
|
function GetAttributeDesc(AttrId: TCSSNumericalID): TCSSAttributeDesc; virtual;
|
|
function GetAttributeDesc(AttrId: TCSSNumericalID): TCSSAttributeDesc; virtual;
|
|
|
|
+ function GetDeclarationValue(Decl: TCSSDeclarationElement): TCSSString; virtual;
|
|
public
|
|
public
|
|
property Options: TCSSResolverOptions read FOptions write SetOptions;
|
|
property Options: TCSSResolverOptions read FOptions write SetOptions;
|
|
property StringComparison: TCSSResStringComparison read FStringComparison;
|
|
property StringComparison: TCSSResStringComparison read FStringComparison;
|
|
public
|
|
public
|
|
// stylesheets
|
|
// stylesheets
|
|
procedure ClearStyleSheets; virtual;
|
|
procedure ClearStyleSheets; virtual;
|
|
- function AddStyleSheet(const aSource, aFilename: TCSSString; anOrigin: TCSSOrigin): TStyleSheet; virtual;
|
|
|
|
|
|
+ function AddStyleSheet(anOrigin: TCSSOrigin; const aName: TCSSString; const aSource: TCSSString): TStyleSheet; virtual;
|
|
|
|
+ procedure ReplaceStyleSheet(Index: integer; const NewSource: TCSSString); virtual;
|
|
function IndexOfStyleSheetWithElement(El: TCSSElement): integer;
|
|
function IndexOfStyleSheetWithElement(El: TCSSElement): integer;
|
|
|
|
+ function IndexOfStyleSheetWithName(anOrigin: TCSSOrigin; const aName: TCSSString): integer;
|
|
function FindStyleSheetWithElement(El: TCSSElement): TStyleSheet;
|
|
function FindStyleSheetWithElement(El: TCSSElement): TStyleSheet;
|
|
property StyleSheetCount: integer read FStyleSheetCount;
|
|
property StyleSheetCount: integer read FStyleSheetCount;
|
|
property StyleSheets[Index: integer]: TStyleSheet read GetStyleSheets;
|
|
property StyleSheets[Index: integer]: TStyleSheet read GetStyleSheets;
|
|
@@ -444,6 +455,7 @@ function CompareCSSSharedRuleArrays(const Rules1, Rules2: TCSSSharedRuleArray):
|
|
function CompareCSSSharedRuleLists(A, B: Pointer): integer;
|
|
function CompareCSSSharedRuleLists(A, B: Pointer): integer;
|
|
function CompareRulesArrayWithCSSSharedRuleList(RuleArray, SharedRuleList: Pointer): integer;
|
|
function CompareRulesArrayWithCSSSharedRuleList(RuleArray, SharedRuleList: Pointer): integer;
|
|
|
|
|
|
|
|
+
|
|
implementation
|
|
implementation
|
|
|
|
|
|
function ComparePointer(Data1, Data2: Pointer): integer;
|
|
function ComparePointer(Data1, Data2: Pointer): integer;
|
|
@@ -570,6 +582,66 @@ end;
|
|
{ TCSSAttributeValues }
|
|
{ TCSSAttributeValues }
|
|
|
|
|
|
procedure TCSSAttributeValues.SortValues;
|
|
procedure TCSSAttributeValues.SortValues;
|
|
|
|
+
|
|
|
|
+ procedure QuickSort(L, R : integer);
|
|
|
|
+ var
|
|
|
|
+ I, J, PivotIdx : integer;
|
|
|
|
+ AttrP: TCSSNumericalID;
|
|
|
|
+ V: TCSSAttributeValue;
|
|
|
|
+ begin
|
|
|
|
+ repeat
|
|
|
|
+ I := L;
|
|
|
|
+ J := R;
|
|
|
|
+ PivotIdx := L + ((R - L) shr 1); { same as ((L + R) div 2), but without the possibility of overflow }
|
|
|
|
+ AttrP := Values[PivotIdx].AttrID;
|
|
|
|
+ repeat
|
|
|
|
+ while (I < PivotIdx) and (AttrP > Values[i].AttrID) do
|
|
|
|
+ Inc(I);
|
|
|
|
+ while (J > PivotIdx) and (AttrP < Values[J].AttrID) do
|
|
|
|
+ Dec(J);
|
|
|
|
+ if I < J then
|
|
|
|
+ begin
|
|
|
|
+ V := Values[I];
|
|
|
|
+ Values[I] := Values[J];
|
|
|
|
+ Values[J] := V;
|
|
|
|
+ if PivotIdx = I then
|
|
|
|
+ begin
|
|
|
|
+ PivotIdx := J;
|
|
|
|
+ Inc(I);
|
|
|
|
+ end
|
|
|
|
+ else if PivotIdx = J then
|
|
|
|
+ begin
|
|
|
|
+ PivotIdx := I;
|
|
|
|
+ Dec(J);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ Inc(I);
|
|
|
|
+ Dec(J);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ until I >= J;
|
|
|
|
+ // sort the smaller range recursively
|
|
|
|
+ // sort the bigger range via the loop
|
|
|
|
+ // Reasons: memory usage is O(log(n)) instead of O(n) and loop is faster than recursion
|
|
|
|
+ if (PivotIdx - L) < (R - PivotIdx) then
|
|
|
|
+ begin
|
|
|
|
+ if (L + 1) < PivotIdx then
|
|
|
|
+ QuickSort(L, PivotIdx - 1);
|
|
|
|
+ L := PivotIdx + 1;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ if (PivotIdx + 1) < R then
|
|
|
|
+ QuickSort(PivotIdx + 1, R);
|
|
|
|
+ if (L + 1) < PivotIdx then
|
|
|
|
+ R := PivotIdx - 1
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ until L >= R;
|
|
|
|
+ end;
|
|
|
|
+
|
|
var
|
|
var
|
|
l: SizeInt;
|
|
l: SizeInt;
|
|
i, j: Integer;
|
|
i, j: Integer;
|
|
@@ -582,8 +654,12 @@ begin
|
|
if Values[i].AttrID>Values[j].AttrID then
|
|
if Values[i].AttrID>Values[j].AttrID then
|
|
SwapValues(i,j);
|
|
SwapValues(i,j);
|
|
end else begin
|
|
end else begin
|
|
- // todo: quicksort
|
|
|
|
- raise ECSSResolver.Create('20240628170311');
|
|
|
|
|
|
+ //for i:=0 to l-1 do
|
|
|
|
+ // writeln('TCSSAttributeValues.SortValues ',i,' ',Values[i]<>nil);
|
|
|
|
+ QuickSort(0,l-1);
|
|
|
|
+ for i:=0 to l-2 do
|
|
|
|
+ if Values[i].AttrID>=Values[i+1].AttrID then
|
|
|
|
+ raise Exception.Create('20240816160749');
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -592,7 +668,7 @@ var
|
|
A, B: TCSSAttributeValue;
|
|
A, B: TCSSAttributeValue;
|
|
AttrId: TCSSNumericalID;
|
|
AttrId: TCSSNumericalID;
|
|
Value: TCSSString;
|
|
Value: TCSSString;
|
|
- Computed: Boolean;
|
|
|
|
|
|
+ aState: TCSSAttributeValue.TState;
|
|
begin
|
|
begin
|
|
A:=Values[Index1];
|
|
A:=Values[Index1];
|
|
B:=Values[Index2];
|
|
B:=Values[Index2];
|
|
@@ -605,9 +681,9 @@ begin
|
|
A.Value:=B.Value;
|
|
A.Value:=B.Value;
|
|
B.Value:=Value;
|
|
B.Value:=Value;
|
|
|
|
|
|
- Computed:=A.Computed;
|
|
|
|
- A.Computed:=B.Computed;
|
|
|
|
- B.Computed:=Computed;
|
|
|
|
|
|
+ aState:=A.State;
|
|
|
|
+ A.State:=B.State;
|
|
|
|
+ B.State:=aState;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TCSSAttributeValues.IndexOf(AttrID: TCSSNumericalID): integer;
|
|
function TCSSAttributeValues.IndexOf(AttrID: TCSSNumericalID): integer;
|
|
@@ -631,17 +707,41 @@ begin
|
|
Result:=-1;
|
|
Result:=-1;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TCSSAttributeValues.GetValue(AttrDesc: TCSSAttributeDesc): TCSSString;
|
|
|
|
|
|
+procedure TCSSAttributeValues.SetComputedValue(AttrID: TCSSNumericalID; const aValue: TCSSString);
|
|
|
|
+
|
|
|
|
+ procedure AddNew;
|
|
|
|
+ var
|
|
|
|
+ Item: TCSSAttributeValue;
|
|
|
|
+ i, l: integer;
|
|
|
|
+ begin
|
|
|
|
+ l:=length(Values);
|
|
|
|
+ i:=l;
|
|
|
|
+ while (i>0) and (Values[i-1].AttrID>AttrID) do dec(i);
|
|
|
|
+ Item:=TCSSAttributeValue.Create;
|
|
|
|
+ Item.AttrID:=AttrID;
|
|
|
|
+ Item.State:=cavsComputed;
|
|
|
|
+ Item.Value:=aValue;
|
|
|
|
+ System.Insert(Item,Values,i);
|
|
|
|
+ end;
|
|
|
|
+
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
- i:=IndexOf(AttrDesc.Index);
|
|
|
|
- if i>=0 then
|
|
|
|
- Result:=Values[i].Value
|
|
|
|
- else if AttrDesc.All then
|
|
|
|
- Result:=AllValue
|
|
|
|
- else
|
|
|
|
- Result:='';
|
|
|
|
|
|
+ if AttrID<=CSSAttributeID_All then
|
|
|
|
+ raise Exception.Create('20240729084610');
|
|
|
|
+ if Values=nil then
|
|
|
|
+ begin
|
|
|
|
+ AddNew;
|
|
|
|
+ end else begin
|
|
|
|
+ i:=IndexOf(AttrID);
|
|
|
|
+ if i>=0 then
|
|
|
|
+ begin
|
|
|
|
+ Values[i].State:=cavsComputed;
|
|
|
|
+ Values[i].Value:=aValue;
|
|
|
|
+ end else begin
|
|
|
|
+ AddNew;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TCSSAttributeValues.Destroy;
|
|
destructor TCSSAttributeValues.Destroy;
|
|
@@ -767,6 +867,28 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TCSSResolver.ClearElements;
|
|
|
|
+var
|
|
|
|
+ i: Integer;
|
|
|
|
+begin
|
|
|
|
+ FLogEntries.Clear;
|
|
|
|
+
|
|
|
|
+ ClearMerge;
|
|
|
|
+ ClearSharedRuleLists;
|
|
|
|
+
|
|
|
|
+ // clear layers
|
|
|
|
+ for i:=0 to length(FLayers)-1 do
|
|
|
|
+ begin
|
|
|
|
+ FLayers[i].ElementCount:=0;
|
|
|
|
+ FLayers[i].Elements:=nil;
|
|
|
|
+ FLayers[i].Name:='';
|
|
|
|
+ end;
|
|
|
|
+ FLayers:=nil;
|
|
|
|
+
|
|
|
|
+ for i:=0 to FStyleSheetCount-1 do
|
|
|
|
+ FreeAndNil(FStyleSheets[i].Element);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TCSSResolver.AddRule(aRule: TCSSRuleElement; Specifity: TCSSSpecifity
|
|
procedure TCSSResolver.AddRule(aRule: TCSSRuleElement; Specifity: TCSSSpecifity
|
|
);
|
|
);
|
|
var
|
|
var
|
|
@@ -887,7 +1009,7 @@ begin
|
|
FSharedRuleLists.Add(Result);
|
|
FSharedRuleLists.Add(Result);
|
|
|
|
|
|
// merge shared properties
|
|
// merge shared properties
|
|
- InitMerge;
|
|
|
|
|
|
+ ClearMerge;
|
|
for i:=0 to length(Result.Rules)-1 do
|
|
for i:=0 to length(Result.Rules)-1 do
|
|
begin
|
|
begin
|
|
RuleArr:=Result.Rules[i];
|
|
RuleArr:=Result.Rules[i];
|
|
@@ -900,7 +1022,7 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TCSSResolver.InitMerge;
|
|
|
|
|
|
+procedure TCSSResolver.ClearMerge;
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
@@ -952,6 +1074,7 @@ var
|
|
AttrP: PMergedAttribute;
|
|
AttrP: PMergedAttribute;
|
|
begin
|
|
begin
|
|
AttrP:=@FMergedAttributes[AttrID];
|
|
AttrP:=@FMergedAttributes[AttrID];
|
|
|
|
+ if AttrP^.Stamp<>FMergedAttributesStamp then exit;
|
|
AttrP^.Stamp:=0;
|
|
AttrP^.Stamp:=0;
|
|
if FMergedAttributeFirst=AttrID then
|
|
if FMergedAttributeFirst=AttrID then
|
|
FMergedAttributeFirst:=AttrP^.Next;
|
|
FMergedAttributeFirst:=AttrP^.Next;
|
|
@@ -1328,7 +1451,7 @@ begin
|
|
Result:=CSSSpecifityNoMatch;
|
|
Result:=CSSSpecifityNoMatch;
|
|
CSSAttributeID_ID,
|
|
CSSAttributeID_ID,
|
|
CSSAttributeID_Class:
|
|
CSSAttributeID_Class:
|
|
- // basic CSS attributes are always defined
|
|
|
|
|
|
+ // id and class are always defined
|
|
Result:=CSSSpecifityClass;
|
|
Result:=CSSSpecifityClass;
|
|
CSSAttributeID_All:
|
|
CSSAttributeID_All:
|
|
// special CSS attributes without a value
|
|
// special CSS attributes without a value
|
|
@@ -2067,7 +2190,7 @@ procedure TCSSResolver.LoadSharedMergedAttributes(
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
- InitMerge;
|
|
|
|
|
|
+ ClearMerge;
|
|
FMergedAllDecl:=SharedMerged.AllDecl;
|
|
FMergedAllDecl:=SharedMerged.AllDecl;
|
|
FMergedAllSpecifity:=SharedMerged.AllSpecifity;
|
|
FMergedAllSpecifity:=SharedMerged.AllSpecifity;
|
|
for i:=0 to length(SharedMerged.Values)-1 do
|
|
for i:=0 to length(SharedMerged.Values)-1 do
|
|
@@ -2126,7 +2249,7 @@ begin
|
|
if TCSSResolverParser.IsWhiteSpace(Value) then
|
|
if TCSSResolverParser.IsWhiteSpace(Value) then
|
|
RemoveMergedAttribute(AttrID)
|
|
RemoveMergedAttribute(AttrID)
|
|
else
|
|
else
|
|
- AttrP^.Complete:=KeyData.Complete or (Pos('var(',Value)<1);
|
|
|
|
|
|
+ AttrP^.Complete:=KeyData.Complete;
|
|
end;
|
|
end;
|
|
AttrID:=NextAttrID;
|
|
AttrID:=NextAttrID;
|
|
end;
|
|
end;
|
|
@@ -2176,31 +2299,35 @@ begin
|
|
if Assigned(AttrDesc.OnSplitShorthand) then
|
|
if Assigned(AttrDesc.OnSplitShorthand) then
|
|
begin
|
|
begin
|
|
RemoveMergedAttribute(AttrID);
|
|
RemoveMergedAttribute(AttrID);
|
|
- if AttrP^.Value<>'' then
|
|
|
|
|
|
+ if AttrP^.Value>'' then
|
|
begin
|
|
begin
|
|
// replace shorthand with longhands, keep already set longhands
|
|
// replace shorthand with longhands, keep already set longhands
|
|
LHAttrIDs:=[];
|
|
LHAttrIDs:=[];
|
|
LHValues:=[];
|
|
LHValues:=[];
|
|
- AttrDesc.OnSplitShorthand(Self,AttrDesc,AttrP^.Value,LHAttrIDs,LHValues);
|
|
|
|
- for i:=0 to length(LHAttrIDs)-1 do
|
|
|
|
|
|
+ InitParseAttr(AttrDesc,nil,AttrP^.Value);
|
|
|
|
+ if not (CurComp.Kind in [rvkNone,rvkInvalid]) then
|
|
begin
|
|
begin
|
|
- SubAttrID:=LHAttrIDs[i];
|
|
|
|
- SubAttrDesc:=GetAttributeDesc(SubAttrID);
|
|
|
|
- if SubAttrDesc=nil then
|
|
|
|
- raise ECSSResolver.Create('20240709194135');
|
|
|
|
- if SubAttrDesc.OnSplitShorthand<>nil then
|
|
|
|
- raise ECSSResolver.Create('20240709194634');
|
|
|
|
- SubAttrP:=@FMergedAttributes[SubAttrID];
|
|
|
|
- if SubAttrP^.Stamp=FMergedAttributesStamp then
|
|
|
|
|
|
+ AttrDesc.OnSplitShorthand(Self,LHAttrIDs,LHValues);
|
|
|
|
+ for i:=0 to length(LHAttrIDs)-1 do
|
|
begin
|
|
begin
|
|
- // longhand already exists -> keep
|
|
|
|
- if SubAttrP^.Specifity<AttrP^.Specifity then
|
|
|
|
- raise ECSSResolver.Create('20240709194537');
|
|
|
|
- end else begin
|
|
|
|
- SetMergedAttribute(SubAttrID,AttrP^.Specifity,nil);
|
|
|
|
- SubAttrP^.Value:=LHValues[i];
|
|
|
|
- SubAttrP^.Complete:=false;
|
|
|
|
- // Note: if NextAttrID=0 then this was the last shorthand
|
|
|
|
|
|
+ SubAttrID:=LHAttrIDs[i];
|
|
|
|
+ SubAttrDesc:=GetAttributeDesc(SubAttrID);
|
|
|
|
+ if SubAttrDesc=nil then
|
|
|
|
+ raise ECSSResolver.Create('20240709194135');
|
|
|
|
+ if SubAttrDesc.OnSplitShorthand<>nil then
|
|
|
|
+ raise ECSSResolver.Create('20240709194634');
|
|
|
|
+ SubAttrP:=@FMergedAttributes[SubAttrID];
|
|
|
|
+ if (SubAttrP^.Stamp=FMergedAttributesStamp) and (SubAttrP^.Specifity>=AttrP^.Specifity) then
|
|
|
|
+ begin
|
|
|
|
+ // longhand already exists -> keep
|
|
|
|
+ end else begin
|
|
|
|
+ SetMergedAttribute(SubAttrID,AttrP^.Specifity,nil);
|
|
|
|
+ SubAttrP^.Value:=LHValues[i];
|
|
|
|
+ if SubAttrP^.Value='' then
|
|
|
|
+ SubAttrP^.Value:=SubAttrDesc.InitialValue;
|
|
|
|
+ SubAttrP^.Complete:=false;
|
|
|
|
+ // Note: if NextAttrID=0 then this was the last shorthand
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -2221,8 +2348,12 @@ begin
|
|
// all
|
|
// all
|
|
if FMergedAllDecl<>nil then
|
|
if FMergedAllDecl<>nil then
|
|
begin
|
|
begin
|
|
- // todo parse FMergedAllDecl and set Result.All
|
|
|
|
- raise ECSSResolver.Create('20240628165049');
|
|
|
|
|
|
+ // set Result.AllValue
|
|
|
|
+ InitParseAttr(CSSRegistry.Attributes[CSSAttributeID_All],nil,GetDeclarationValue(FMergedAllDecl));
|
|
|
|
+ if (CurComp.Kind=rvkKeyword) and IsBaseKeyword(CurComp.KeywordID) then
|
|
|
|
+ begin
|
|
|
|
+ Result.AllValue:=CurComp.KeywordID;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
// count and allocate attributes
|
|
// count and allocate attributes
|
|
@@ -2246,9 +2377,9 @@ begin
|
|
Result.Values[Cnt]:=AttrValue;
|
|
Result.Values[Cnt]:=AttrValue;
|
|
AttrValue.AttrID:=AttrID;
|
|
AttrValue.AttrID:=AttrID;
|
|
AttrValue.Value:=AttrP^.Value;
|
|
AttrValue.Value:=AttrP^.Value;
|
|
- AttrValue.Computed:=false;
|
|
|
|
- inc(Cnt);
|
|
|
|
|
|
+ //writeln('TCSSResolver.CreateValueList ',Cnt,' ',AttrID,' "',AttrValue.Value,'"');
|
|
AttrID:=AttrP^.Next;
|
|
AttrID:=AttrP^.Next;
|
|
|
|
+ inc(Cnt);
|
|
end;
|
|
end;
|
|
|
|
|
|
// sort
|
|
// sort
|
|
@@ -2335,9 +2466,9 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TCSSResolver.ParseInlineStyle(const Src: TCSSString): TCSSElement;
|
|
|
|
|
|
+function TCSSResolver.ParseInlineStyle(const Src: TCSSString): TCSSRuleElement;
|
|
begin
|
|
begin
|
|
- Result:=ParseCSSSource(Src,true);
|
|
|
|
|
|
+ Result:=ParseCSSSource(Src,true) as TCSSRuleElement;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TCSSResolver.GetElPath(El: TCSSElement): TCSSString;
|
|
function TCSSResolver.GetElPath(El: TCSSElement): TCSSString;
|
|
@@ -2362,8 +2493,6 @@ end;
|
|
|
|
|
|
procedure TCSSResolver.Clear;
|
|
procedure TCSSResolver.Clear;
|
|
begin
|
|
begin
|
|
- ClearSharedRuleLists;
|
|
|
|
- FLogEntries.Clear;
|
|
|
|
ClearStyleSheets;
|
|
ClearStyleSheets;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2372,13 +2501,19 @@ var
|
|
OldLen, NewLen: TCSSNumericalID;
|
|
OldLen, NewLen: TCSSNumericalID;
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
- CSSRegistry.ConsistencyCheck;;
|
|
|
|
|
|
+ if CSSRegistry.Modified then
|
|
|
|
+ begin
|
|
|
|
+ CSSRegistry.ConsistencyCheck;
|
|
|
|
+ CSSRegistry.Modified:=false;
|
|
|
|
+ end;
|
|
|
|
+
|
|
FMergedAttributesStamp:=1;
|
|
FMergedAttributesStamp:=1;
|
|
for i:=0 to length(FMergedAttributes)-1 do
|
|
for i:=0 to length(FMergedAttributes)-1 do
|
|
FMergedAttributes[i].Stamp:=0;
|
|
FMergedAttributes[i].Stamp:=0;
|
|
OldLen:=length(FMergedAttributes);
|
|
OldLen:=length(FMergedAttributes);
|
|
NewLen:=OldLen;
|
|
NewLen:=OldLen;
|
|
- if CSSRegistry.AttributeCount>NewLen then NewLen:=CSSRegistry.AttributeCount;
|
|
|
|
|
|
+ if CSSRegistry.AttributeCount>NewLen then
|
|
|
|
+ NewLen:=CSSRegistry.AttributeCount;
|
|
if NewLen>OldLen then
|
|
if NewLen>OldLen then
|
|
begin
|
|
begin
|
|
SetLength(FMergedAttributes,NewLen);
|
|
SetLength(FMergedAttributes,NewLen);
|
|
@@ -2444,18 +2579,23 @@ begin
|
|
Result:=CSSRegistry.Attributes[AttrId];
|
|
Result:=CSSRegistry.Attributes[AttrId];
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TCSSResolver.GetDeclarationValue(Decl: TCSSDeclarationElement): TCSSString;
|
|
|
|
+var
|
|
|
|
+ KeyData: TCSSAttributeKeyData;
|
|
|
|
+begin
|
|
|
|
+ Result:='';
|
|
|
|
+ if Decl=nil then exit;
|
|
|
|
+ if Decl.KeyCount=0 then exit;
|
|
|
|
+ KeyData:=TCSSAttributeKeyData(Decl.Keys[0].CustomData);
|
|
|
|
+ if KeyData=nil then exit;
|
|
|
|
+ Result:=KeyData.Value;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TCSSResolver.ClearStyleSheets;
|
|
procedure TCSSResolver.ClearStyleSheets;
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
begin
|
|
begin
|
|
- // clear layers
|
|
|
|
- for i:=0 to length(FLayers)-1 do
|
|
|
|
- begin
|
|
|
|
- FLayers[i].ElementCount:=0;
|
|
|
|
- FLayers[i].Elements:=nil;
|
|
|
|
- FLayers[i].Name:='';
|
|
|
|
- end;
|
|
|
|
- FLayers:=nil;
|
|
|
|
|
|
+ ClearElements;
|
|
|
|
|
|
// clear stylesheets
|
|
// clear stylesheets
|
|
for i:=0 to FStyleSheetCount-1 do
|
|
for i:=0 to FStyleSheetCount-1 do
|
|
@@ -2466,11 +2606,21 @@ begin
|
|
FStyleSheetCount:=0;
|
|
FStyleSheetCount:=0;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TCSSResolver.AddStyleSheet(const aSource, aFilename: TCSSString;
|
|
|
|
- anOrigin: TCSSOrigin): TStyleSheet;
|
|
|
|
|
|
+function TCSSResolver.AddStyleSheet(anOrigin: TCSSOrigin; const aName: TCSSString;
|
|
|
|
+ const aSource: TCSSString): TStyleSheet;
|
|
var
|
|
var
|
|
- Cnt: SizeInt;
|
|
|
|
|
|
+ Cnt, i: SizeInt;
|
|
begin
|
|
begin
|
|
|
|
+ if aName>'' then
|
|
|
|
+ begin
|
|
|
|
+ i:=IndexOfStyleSheetWithName(anOrigin,aName);
|
|
|
|
+ if i>=0 then
|
|
|
|
+ begin
|
|
|
|
+ ReplaceStyleSheet(i,aSource);
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
Cnt:=length(FStyleSheets);
|
|
Cnt:=length(FStyleSheets);
|
|
if Cnt=FStyleSheetCount then
|
|
if Cnt=FStyleSheetCount then
|
|
begin
|
|
begin
|
|
@@ -2490,9 +2640,9 @@ begin
|
|
inc(FStyleSheetCount);
|
|
inc(FStyleSheetCount);
|
|
|
|
|
|
with Result do begin
|
|
with Result do begin
|
|
- Source:=aSource;
|
|
|
|
- Filename:=aFilename;
|
|
|
|
|
|
+ Name:=aName;
|
|
Origin:=anOrigin;
|
|
Origin:=anOrigin;
|
|
|
|
+ Source:=aSource;
|
|
Parsed:=false;
|
|
Parsed:=false;
|
|
if Element<>nil then
|
|
if Element<>nil then
|
|
FreeAndNil(Element);
|
|
FreeAndNil(Element);
|
|
@@ -2501,6 +2651,21 @@ begin
|
|
ParseSource(FStyleSheetCount-1);
|
|
ParseSource(FStyleSheetCount-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TCSSResolver.ReplaceStyleSheet(Index: integer; const NewSource: TCSSString);
|
|
|
|
+var
|
|
|
|
+ Sheet: TStyleSheet;
|
|
|
|
+begin
|
|
|
|
+ Sheet:=StyleSheets[Index];
|
|
|
|
+ if NewSource=Sheet.Source then exit;
|
|
|
|
+ ClearMerge;
|
|
|
|
+ ClearSharedRuleLists;
|
|
|
|
+ FreeAndNil(Sheet.Element);
|
|
|
|
+ Sheet.Parsed:=false;
|
|
|
|
+ Sheet.Source:=NewSource;
|
|
|
|
+
|
|
|
|
+ ParseSource(Index);
|
|
|
|
+end;
|
|
|
|
+
|
|
function TCSSResolver.IndexOfStyleSheetWithElement(El: TCSSElement): integer;
|
|
function TCSSResolver.IndexOfStyleSheetWithElement(El: TCSSElement): integer;
|
|
var
|
|
var
|
|
aParent: TCSSElement;
|
|
aParent: TCSSElement;
|
|
@@ -2518,6 +2683,20 @@ begin
|
|
exit(i);
|
|
exit(i);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TCSSResolver.IndexOfStyleSheetWithName(anOrigin: TCSSOrigin; const aName: TCSSString
|
|
|
|
+ ): integer;
|
|
|
|
+var
|
|
|
|
+ Sheet: TStyleSheet;
|
|
|
|
+begin
|
|
|
|
+ for Result:=0 to FStyleSheetCount-1 do
|
|
|
|
+ begin
|
|
|
|
+ Sheet:=FStyleSheets[Result];
|
|
|
|
+ if (Sheet.Origin=anOrigin) and (aName=Sheet.Name) then
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ Result:=-1;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TCSSResolver.FindStyleSheetWithElement(El: TCSSElement): TStyleSheet;
|
|
function TCSSResolver.FindStyleSheetWithElement(El: TCSSElement): TStyleSheet;
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|