* Fixed memory leaks, all nodes are now freed by their parent

* Many cosmetic changes
This commit is contained in:
sg 2000-01-30 22:18:16 +00:00
parent 7381e3fff4
commit b20f194d19

View File

@ -15,7 +15,7 @@
**********************************************************************} **********************************************************************}
{ {
more or less DOM level 1 conformant class library for FreePascal more or less DOM level 1 conformant class library for Free Pascal
} }
{$MODE objfpc} {$MODE objfpc}
@ -147,11 +147,11 @@ type
FPreviousSibling, FNextSibling: TDOMNode; FPreviousSibling, FNextSibling: TDOMNode;
FOwnerDocument: TDOMDocument; FOwnerDocument: TDOMDocument;
function FGetNodeValue: DOMString; virtual; function GetNodeValue: DOMString; virtual;
procedure FSetNodeValue(AValue: DOMString); virtual; procedure SetNodeValue(AValue: DOMString); virtual;
function FGetFirstChild: TDOMNode; virtual; function GetFirstChild: TDOMNode; virtual;
function FGetLastChild: TDOMNode; virtual; function GetLastChild: TDOMNode; virtual;
function FGetAttributes: TDOMNamedNodeMap; virtual; function GetAttributes: TDOMNamedNodeMap; virtual;
constructor Create(AOwner: TDOMDocument); constructor Create(AOwner: TDOMDocument);
public public
@ -159,15 +159,15 @@ type
function GetChildNodes: TDOMNodeList; virtual; function GetChildNodes: TDOMNodeList; virtual;
property NodeName: DOMString read FNodeName; property NodeName: DOMString read FNodeName;
property NodeValue: DOMString read FGetNodeValue write FSetNodeValue; property NodeValue: DOMString read GetNodeValue write SetNodeValue;
property NodeType: Integer read FNodeType; property NodeType: Integer read FNodeType;
property ParentNode: TDOMNode read FParentNode; property ParentNode: TDOMNode read FParentNode;
property FirstChild: TDOMNode read FGetFirstChild; property FirstChild: TDOMNode read GetFirstChild;
property LastChild: TDOMNode read FGetLastChild; property LastChild: TDOMNode read GetLastChild;
property ChildNodes: TDOMNodeList read GetChildNodes; property ChildNodes: TDOMNodeList read GetChildNodes;
property PreviousSibling: TDOMNode read FPreviousSibling; property PreviousSibling: TDOMNode read FPreviousSibling;
property NextSibling: TDOMNode read FNextSibling; property NextSibling: TDOMNode read FNextSibling;
property Attributes: TDOMNamedNodeMap read FGetAttributes; property Attributes: TDOMNamedNodeMap read GetAttributes;
property OwnerDocument: TDOMDocument read FOwnerDocument; property OwnerDocument: TDOMDocument read FOwnerDocument;
function InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; virtual; function InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; virtual;
@ -189,9 +189,10 @@ type
TDOMNode_WithChildren = class(TDOMNode) TDOMNode_WithChildren = class(TDOMNode)
protected protected
FFirstChild, FLastChild: TDOMNode; FFirstChild, FLastChild: TDOMNode;
function FGetFirstChild: TDOMNode; override; function GetFirstChild: TDOMNode; override;
function FGetLastChild: TDOMNode; override; function GetLastChild: TDOMNode; override;
public public
destructor Destroy; override;
function InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; override; function InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; override;
function ReplaceChild(NewChild, OldChild: TDOMNode): TDOMNode; override; function ReplaceChild(NewChild, OldChild: TDOMNode): TDOMNode; override;
function RemoveChild(OldChild: TDOMNode): TDOMNode; override; function RemoveChild(OldChild: TDOMNode): TDOMNode; override;
@ -199,6 +200,7 @@ type
function HasChildNodes: Boolean; override; function HasChildNodes: Boolean; override;
end; end;
// ------------------------------------------------------- // -------------------------------------------------------
// NodeList // NodeList
// ------------------------------------------------------- // -------------------------------------------------------
@ -209,11 +211,11 @@ type
filter: DOMString; filter: DOMString;
UseFilter: Boolean; UseFilter: Boolean;
constructor Create(ANode: TDOMNode; AFilter: DOMString); constructor Create(ANode: TDOMNode; AFilter: DOMString);
function FGetCount: LongWord; function GetCount: LongWord;
function FGetItem(index: LongWord): TDOMNode; function GetItem(index: LongWord): TDOMNode;
public public
property Item[index: LongWord]: TDOMNode read FGetItem; property Item[index: LongWord]: TDOMNode read GetItem;
property Count: LongWord read FGetCount; property Count: LongWord read GetCount;
end; end;
@ -224,17 +226,17 @@ type
TDOMNamedNodeMap = class(TList) TDOMNamedNodeMap = class(TList)
protected protected
OwnerDocument: TDOMDocument; OwnerDocument: TDOMDocument;
function FGetItem(index: LongWord): TDOMNode; function GetItem(index: LongWord): TDOMNode;
procedure FSetItem(index: LongWord; AItem: TDOMNode); procedure SetItem(index: LongWord; AItem: TDOMNode);
function FGetLength: LongWord; function GetLength: LongWord;
constructor Create(AOwner: TDOMDocument); constructor Create(AOwner: TDOMDocument);
public public
function GetNamedItem(const name: DOMString): TDOMNode; function GetNamedItem(const name: DOMString): TDOMNode;
function SetNamedItem(arg: TDOMNode): TDOMNode; function SetNamedItem(arg: TDOMNode): TDOMNode;
function RemoveNamedItem(const name: DOMString): TDOMNode; function RemoveNamedItem(const name: DOMString): TDOMNode;
property Item[index: LongWord]: TDOMNode read FGetItem write FSetItem; property Item[index: LongWord]: TDOMNode read GetItem write SetItem;
property Length: LongWord read FGetLength; property Length: LongWord read GetLength;
end; end;
@ -244,10 +246,10 @@ type
TDOMCharacterData = class(TDOMNode) TDOMCharacterData = class(TDOMNode)
protected protected
function FGetLength: LongWord; function GetLength: LongWord;
public public
property Data: DOMString read FNodeValue; property Data: DOMString read FNodeValue;
property Length: LongWord read FGetLength; property Length: LongWord read GetLength;
function SubstringData(offset, count: LongWord): DOMString; function SubstringData(offset, count: LongWord): DOMString;
procedure AppendData(const arg: DOMString); procedure AppendData(const arg: DOMString);
procedure InsertData(offset: LongWord; const arg: DOMString); procedure InsertData(offset: LongWord; const arg: DOMString);
@ -332,14 +334,14 @@ type
protected protected
FSpecified: Boolean; FSpecified: Boolean;
AttrOwner: TDOMNamedNodeMap; AttrOwner: TDOMNamedNodeMap;
function FGetNodeValue: DOMString; override; function GetNodeValue: DOMString; override;
procedure FSetNodeValue(AValue: DOMString); override; procedure SetNodeValue(AValue: DOMString); override;
constructor Create(AOwner: TDOMDocument); constructor Create(AOwner: TDOMDocument);
public public
property Name: DOMString read FNodeName; property Name: DOMString read FNodeName;
property Specified: Boolean read FSpecified; property Specified: Boolean read FSpecified;
property Value: DOMString read FNodeValue write FSetNodeValue; property Value: DOMString read FNodeValue write SetNodeValue;
end; end;
@ -350,10 +352,11 @@ type
TDOMElement = class(TDOMNode_WithChildren) TDOMElement = class(TDOMNode_WithChildren)
protected protected
FAttributes: TDOMNamedNodeMap; FAttributes: TDOMNamedNodeMap;
function FGetAttributes: TDOMNamedNodeMap; override; function GetAttributes: TDOMNamedNodeMap; override;
constructor Create(AOwner: TDOMDocument); virtual; constructor Create(AOwner: TDOMDocument); virtual;
public public
destructor Destroy; override;
property TagName: DOMString read FNodeName; property TagName: DOMString read FNodeName;
function GetAttribute(const name: DOMString): DOMString; function GetAttribute(const name: DOMString): DOMString;
procedure SetAttribute(const name, value: DOMString); procedure SetAttribute(const name, value: DOMString);
@ -548,12 +551,12 @@ begin
inherited Create; inherited Create;
end; end;
function TDOMNode.FGetNodeValue: DOMString; function TDOMNode.GetNodeValue: DOMString;
begin begin
Result := FNodeValue; Result := FNodeValue;
end; end;
procedure TDOMNode.FSetNodeValue(AValue: DOMString); procedure TDOMNode.SetNodeValue(AValue: DOMString);
begin begin
FNodeValue := AValue; FNodeValue := AValue;
end; end;
@ -563,9 +566,9 @@ begin
Result := TDOMNodeList.Create(Self, '*'); Result := TDOMNodeList.Create(Self, '*');
end; end;
function TDOMNode.FGetFirstChild: TDOMNode; begin Result := nil end; function TDOMNode.GetFirstChild: TDOMNode; begin Result := nil end;
function TDOMNode.FGetLastChild: TDOMNode; begin Result := nil end; function TDOMNode.GetLastChild: TDOMNode; begin Result := nil end;
function TDOMNode.FGetAttributes: TDOMNamedNodeMap; begin Result := nil end; function TDOMNode.GetAttributes: TDOMNamedNodeMap; begin Result := nil end;
function TDOMNode.InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; function TDOMNode.InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode;
begin begin
@ -602,7 +605,7 @@ var
child: TDOMNode; child: TDOMNode;
begin begin
child := FirstChild; child := FirstChild;
while child <> nil do begin while Assigned(child) do begin
if child.NodeName = ANodeName then begin if child.NodeName = ANodeName then begin
Result := child; Result := child;
exit; exit;
@ -613,22 +616,35 @@ begin
end; end;
function TDOMNode_WithChildren.FGetFirstChild: TDOMNode; function TDOMNode_WithChildren.GetFirstChild: TDOMNode;
begin begin
Result := FFirstChild; Result := FFirstChild;
end; end;
function TDOMNode_WithChildren.FGetLastChild: TDOMNode; function TDOMNode_WithChildren.GetLastChild: TDOMNode;
begin begin
Result := FLastChild; Result := FLastChild;
end; end;
destructor TDOMNode_WithChildren.Destroy;
var
child, next: TDOMNode;
begin
child := FirstChild;
while Assigned(child) do begin
next := child.NextSibling;
child.Free;
child := next;
end;
inherited Destroy;
end;
function TDOMNode_WithChildren.InsertBefore(NewChild, RefChild: TDOMNode): function TDOMNode_WithChildren.InsertBefore(NewChild, RefChild: TDOMNode):
TDOMNode; TDOMNode;
var var
i: Integer; i: Integer;
begin begin
if RefChild = nil then begin if not Assigned(RefChild) then begin
AppendChild(NewChild); AppendChild(NewChild);
exit(NewChild); exit(NewChild);
end; end;
@ -676,6 +692,8 @@ begin
FLastChild := nil FLastChild := nil
else else
OldChild.FNextSibling.FPreviousSibling := OldChild.FPreviousSibling; OldChild.FNextSibling.FPreviousSibling := OldChild.FPreviousSibling;
OldChild.Free;
end; end;
function TDOMNode_WithChildren.AppendChild(NewChild: TDOMNode): TDOMNode; function TDOMNode_WithChildren.AppendChild(NewChild: TDOMNode): TDOMNode;
@ -686,7 +704,7 @@ begin
raise EDOMWrongDocument.Create('NodeWC.AppendChild'); raise EDOMWrongDocument.Create('NodeWC.AppendChild');
parent := Self; parent := Self;
while parent <> nil do begin while Assigned(parent) do begin
if parent = NewChild then if parent = NewChild then
raise EDOMHierarchyRequest.Create('NodeWC.AppendChild (cycle in tree)'); raise EDOMHierarchyRequest.Create('NodeWC.AppendChild (cycle in tree)');
parent := parent.ParentNode; parent := parent.ParentNode;
@ -695,15 +713,14 @@ begin
if NewChild.FParentNode = Self then if NewChild.FParentNode = Self then
RemoveChild(NewChild); RemoveChild(NewChild);
if NewChild.NodeType = DOCUMENT_FRAGMENT_NODE then begin if NewChild.NodeType = DOCUMENT_FRAGMENT_NODE then
raise EDOMNotSupported.Create('NodeWC.AppendChild for DocumentFragments'); raise EDOMNotSupported.Create('NodeWC.AppendChild for DocumentFragments')
end else begin else begin
if FLastChild = nil then if Assigned(FFirstChild) then begin
FFirstChild := NewChild
else begin
FLastChild.FNextSibling := NewChild; FLastChild.FNextSibling := NewChild;
NewChild.FPreviousSibling := FLastChild; NewChild.FPreviousSibling := FLastChild;
end; end else
FFirstChild := NewChild;
FLastChild := NewChild; FLastChild := NewChild;
NewChild.FParentNode := Self; NewChild.FParentNode := Self;
end; end;
@ -713,7 +730,7 @@ end;
function TDOMNode_WithChildren.HasChildNodes: Boolean; function TDOMNode_WithChildren.HasChildNodes: Boolean;
begin begin
Result := FFirstChild <> nil; Result := Assigned(FFirstChild);
end; end;
@ -730,27 +747,27 @@ begin
UseFilter := filter <> '*'; UseFilter := filter <> '*';
end; end;
function TDOMNodeList.FGetCount: LongWord; function TDOMNodeList.GetCount: LongWord;
var var
child: TDOMNode; child: TDOMNode;
begin begin
Result := 0; Result := 0;
child := node.FirstChild; child := node.FirstChild;
while child <> nil do begin while Assigned(child) do begin
if (not UseFilter) or (child.NodeName = filter) then if (not UseFilter) or (child.NodeName = filter) then
Inc(Result); Inc(Result);
child := child.NextSibling; child := child.NextSibling;
end; end;
end; end;
function TDOMNodeList.FGetItem(index: LongWord): TDOMNode; function TDOMNodeList.GetItem(index: LongWord): TDOMNode;
var var
child: TDOMNode; child: TDOMNode;
begin begin
Result := nil; Result := nil;
if index < 0 then exit; if index < 0 then exit;
child := node.FirstChild; child := node.FirstChild;
while child <> nil do begin while Assigned(child) do begin
if index = 0 then begin if index = 0 then begin
Result := child; Result := child;
break; break;
@ -772,17 +789,17 @@ begin
OwnerDocument := AOwner; OwnerDocument := AOwner;
end; end;
function TDOMNamedNodeMap.FGetItem(index: LongWord): TDOMNode; function TDOMNamedNodeMap.GetItem(index: LongWord): TDOMNode;
begin begin
Result := TDOMNode(Items[index]); Result := TDOMNode(Items[index]);
end; end;
procedure TDOMNamedNodeMap.FSetItem(index: LongWord; AItem: TDOMNode); procedure TDOMNamedNodeMap.SetItem(index: LongWord; AItem: TDOMNode);
begin begin
Items[index] := AItem; Items[index] := AItem;
end; end;
function TDOMNamedNodeMap.FGetLength: LongWord; function TDOMNamedNodeMap.GetLength: LongWord;
begin begin
Result := LongWord(Count); Result := LongWord(Count);
end; end;
@ -805,7 +822,7 @@ begin
raise EDOMWrongDocument.Create('NamedNodeMap.SetNamedItem'); raise EDOMWrongDocument.Create('NamedNodeMap.SetNamedItem');
if arg.NodeType = ATTRIBUTE_NODE then begin if arg.NodeType = ATTRIBUTE_NODE then begin
if TDOMAttr(arg).AttrOwner <> nil then if Assigned(TDOMAttr(arg).AttrOwner) then
raise EDOMInUseAttribute.Create('NamedNodeMap.SetNamedItem'); raise EDOMInUseAttribute.Create('NamedNodeMap.SetNamedItem');
TDOMAttr(arg).AttrOwner := Self; TDOMAttr(arg).AttrOwner := Self;
end; end;
@ -838,7 +855,7 @@ end;
// CharacterData // CharacterData
// ------------------------------------------------------- // -------------------------------------------------------
function TDOMCharacterData.FGetLength: LongWord; function TDOMCharacterData.GetLength: LongWord;
begin begin
Result := system.Length(FNodeValue); Result := system.Length(FNodeValue);
end; end;
@ -1012,16 +1029,14 @@ begin
inherited Create(AOwner); inherited Create(AOwner);
end; end;
function TDOMAttr.FGetNodeValue: DOMString; function TDOMAttr.GetNodeValue: DOMString;
var var
child: TDOMNode; child: TDOMNode;
begin begin
if FFirstChild = nil then SetLength(Result, 0);
Result := '' if Assigned(FFirstChild) then begin
else begin
Result := '';
child := FFirstChild; child := FFirstChild;
while child <> nil do begin while Assigned(child) do begin
if child.NodeType = ENTITY_REFERENCE_NODE then if child.NodeType = ENTITY_REFERENCE_NODE then
Result := Result + '&' + child.NodeName + ';' Result := Result + '&' + child.NodeName + ';'
else else
@ -1031,14 +1046,14 @@ begin
end; end;
end; end;
procedure TDOMAttr.FSetNodeValue(AValue: DOMString); procedure TDOMAttr.SetNodeValue(AValue: DOMString);
var var
tn: TDOMText; tn: TDOMText;
begin begin
FSpecified := True; FSpecified := True;
tn := TDOMText.Create(FOwnerDocument); tn := TDOMText.Create(FOwnerDocument);
tn.FNodeValue := AValue; tn.FNodeValue := AValue;
if FFirstChild <> nil then if Assigned(FFirstChild) then
ReplaceChild(tn, FFirstChild) ReplaceChild(tn, FFirstChild)
else else
AppendChild(tn); AppendChild(tn);
@ -1056,7 +1071,19 @@ begin
FAttributes := TDOMNamedNodeMap.Create(AOwner); FAttributes := TDOMNamedNodeMap.Create(AOwner);
end; end;
function TDOMElement.FGetAttributes: TDOMNamedNodeMap; destructor TDOMElement.Destroy;
var
i: Integer;
begin
{As the attributes are _not_ childs of the element node, we have to free
them manually here:}
for i := 0 to FAttributes.Count - 1 do
FAttributes.Item[i].Free;
FAttributes.Free;
inherited Destroy;
end;
function TDOMElement.GetAttributes: TDOMNamedNodeMap;
begin begin
Result := FAttributes; Result := FAttributes;
end; end;
@ -1070,7 +1097,7 @@ begin
Result := FAttributes.Item[i].NodeValue; Result := FAttributes.Item[i].NodeValue;
exit; exit;
end; end;
Result := ''; SetLength(Result, 0);
end; end;
procedure TDOMElement.SetAttribute(const name, value: DOMString); procedure TDOMElement.SetAttribute(const name, value: DOMString);
@ -1256,7 +1283,11 @@ end.
{ {
$Log$ $Log$
Revision 1.10 2000-01-07 01:24:34 peter Revision 1.11 2000-01-30 22:18:16 sg
* Fixed memory leaks, all nodes are now freed by their parent
* Many cosmetic changes
Revision 1.10 2000/01/07 01:24:34 peter
* updated copyright to 2000 * updated copyright to 2000
Revision 1.9 2000/01/06 23:55:22 peter Revision 1.9 2000/01/06 23:55:22 peter