~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/codetools/laz_dom.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
{
2
 
  BEWARE !!!
3
 
  This is a TEMPORARY file.
4
 
  As soon as it is moved to the fcl, it will be removed.
5
 
}
6
 
 
7
 
{
8
 
    $Id: laz_dom.pas 29456 2011-02-10 22:22:30Z vincents $
9
 
    This file is part of the Free Component Library
10
 
 
11
 
    Implementation of DOM interfaces
12
 
    Copyright (c) 1999-2000 by Sebastian Guenther, sg@freepascal.org
13
 
 
14
 
    See the file COPYING.modifiedLGPL.txt, included in this distribution,
15
 
    for details about the copyright.
16
 
 
17
 
    This program is distributed in the hope that it will be useful,
18
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
 
 
21
 
 **********************************************************************}
22
 
 
23
 
{
24
 
  This unit provides classes which implement the interfaces defined in the
25
 
  DOM (Document Object Model) specification.
26
 
  The current state is:
27
 
  DOM Level 1  -  Almost completely implemented
28
 
  DOM Level 2  -  Partially implemented
29
 
 
30
 
 
31
 
  Specification used for this implementation:
32
 
 
33
 
  "Document Object Model (DOM) Level 2 Specification Version 1.0
34
 
   W3C Candidate Recommendation 07 March, 2000"
35
 
  http://www.w3.org/TR/2000/CR-DOM-Level-2-20000307
36
 
}
37
 
 
38
 
 
39
 
unit Laz_DOM;
40
 
 
41
 
{$MODE objfpc}
42
 
{$H+}
43
 
 
44
 
interface
45
 
 
46
 
{off $DEFINE MEM_CHECK}
47
 
 
48
 
uses
49
 
  {$IFDEF MEM_CHECK}MemCheck,{$ENDIF}
50
 
  SysUtils, Classes, Avl_Tree;
51
 
 
52
 
 
53
 
type
54
 
  TDOMImplementation = class;
55
 
  TDOMDocumentFragment = class;
56
 
  TDOMDocument = class;
57
 
  TDOMNode = class;
58
 
  TDOMNodeList = class;
59
 
  TDOMNamedNodeMap = class;
60
 
  TDOMCharacterData = class;
61
 
  TDOMAttr = class;
62
 
  TDOMElement = class;
63
 
  TDOMText = class;
64
 
  TDOMComment = class;
65
 
  TDOMCDATASection = class;
66
 
  TDOMDocumentType = class;
67
 
  TDOMNotation = class;
68
 
  TDOMEntity = class;
69
 
  TDOMEntityReference = class;
70
 
  TDOMProcessingInstruction = class;
71
 
 
72
 
 
73
 
// -------------------------------------------------------
74
 
//   DOMString
75
 
// -------------------------------------------------------
76
 
  DOMString = String;
77
 
  DOMPChar = PChar;
78
 
//  DOMString = WideString;
79
 
//  DOMPChar = PWideChar;
80
 
 
81
 
 
82
 
// -------------------------------------------------------
83
 
//   DOMException
84
 
// -------------------------------------------------------
85
 
 
86
 
 
87
 
const
88
 
 
89
 
  // DOM Level 1 exception codes:
90
 
 
91
 
  INDEX_SIZE_ERR              = 1;  // index or size is negative, or greater than the allowed value
92
 
  DOMSTRING_SIZE_ERR          = 2;  // Specified range of text does not fit into a DOMString
93
 
  HIERARCHY_REQUEST_ERR       = 3;  // node is inserted somewhere it does not belong
94
 
  WRONG_DOCUMENT_ERR          = 4;  // node is used in a different document than the one that created it (that does not support it)
95
 
  INVALID_CHARACTER_ERR       = 5;  // invalid or illegal character is specified, such as in a name
96
 
  NO_DATA_ALLOWED_ERR         = 6;  // data is specified for a node which does not support data
97
 
  NO_MODIFICATION_ALLOWED_ERR = 7;  // an attempt is made to modify an object where modifications are not allowed
98
 
  NOT_FOUND_ERR               = 8;  // an attempt is made to reference a node in a context where it does not exist
99
 
  NOT_SUPPORTED_ERR           = 9;  // implementation does not support the type of object requested
100
 
  INUSE_ATTRIBUTE_ERR         = 10;  // an attempt is made to add an attribute that is already in use elsewhere
101
 
 
102
 
  // DOM Level 2 exception codes:
103
 
 
104
 
  INVALID_STATE_ERR           = 11;  // an attempt is made to use an object that is not, or is no longer, usable
105
 
  SYNTAX_ERR                  = 12;  // invalid or illegal string specified
106
 
  INVALID_MODIFICATION_ERR    = 13;  // an attempt is made to modify the type of the underlying object
107
 
  NAMESPACE_ERR               = 14;  // an attempt is made to create or change an object in a way which is incorrect with regard to namespaces
108
 
  INVALID_ACCESS_ERR          = 15;  // parameter or operation is not supported by the underlying object
109
 
 
110
 
 
111
 
type
112
 
 
113
 
  EDOMError = class(Exception)
114
 
  public
115
 
    Code: Integer;
116
 
    constructor Create(ACode: Integer; const ASituation: String);
117
 
  end;
118
 
 
119
 
  EDOMIndexSize = class(EDOMError)
120
 
  public
121
 
    constructor Create(const ASituation: String);
122
 
  end;
123
 
 
124
 
  EDOMHierarchyRequest = class(EDOMError)
125
 
  public
126
 
    constructor Create(const ASituation: String);
127
 
  end;
128
 
 
129
 
  EDOMWrongDocument = class(EDOMError)
130
 
  public
131
 
    constructor Create(const ASituation: String);
132
 
  end;
133
 
 
134
 
  EDOMNotFound = class(EDOMError)
135
 
  public
136
 
    constructor Create(const ASituation: String);
137
 
  end;
138
 
 
139
 
  EDOMNotSupported = class(EDOMError)
140
 
  public
141
 
    constructor Create(const ASituation: String);
142
 
  end;
143
 
 
144
 
  EDOMInUseAttribute = class(EDOMError)
145
 
  public
146
 
    constructor Create(const ASituation: String);
147
 
  end;
148
 
 
149
 
  EDOMInvalidState = class(EDOMError)
150
 
  public
151
 
    constructor Create(const ASituation: String);
152
 
  end;
153
 
 
154
 
  EDOMSyntax = class(EDOMError)
155
 
  public
156
 
    constructor Create(const ASituation: String);
157
 
  end;
158
 
 
159
 
  EDOMInvalidModification = class(EDOMError)
160
 
  public
161
 
    constructor Create(const ASituation: String);
162
 
  end;
163
 
 
164
 
  EDOMNamespace = class(EDOMError)
165
 
  public
166
 
    constructor Create(const ASituation: String);
167
 
  end;
168
 
 
169
 
  EDOMInvalidAccess = class(EDOMError)
170
 
  public
171
 
    constructor Create(const ASituation: String);
172
 
  end;
173
 
 
174
 
 
175
 
// -------------------------------------------------------
176
 
//   Node
177
 
// -------------------------------------------------------
178
 
 
179
 
const
180
 
 
181
 
  ELEMENT_NODE = 1;
182
 
  ATTRIBUTE_NODE = 2;
183
 
  TEXT_NODE = 3;
184
 
  CDATA_SECTION_NODE = 4;
185
 
  ENTITY_REFERENCE_NODE = 5;
186
 
  ENTITY_NODE = 6;
187
 
  PROCESSING_INSTRUCTION_NODE = 7;
188
 
  COMMENT_NODE = 8;
189
 
  DOCUMENT_NODE = 9;
190
 
  DOCUMENT_TYPE_NODE = 10;
191
 
  DOCUMENT_FRAGMENT_NODE = 11;
192
 
  NOTATION_NODE = 12;
193
 
 
194
 
 
195
 
type
196
 
 
197
 
  TRefClass = class
198
 
  protected
199
 
    RefCounter: LongInt;
200
 
  public
201
 
    constructor Create;
202
 
    function AddRef: LongInt; virtual;
203
 
    function Release: LongInt; virtual;
204
 
  end;
205
 
 
206
 
  { TDOMNode }
207
 
 
208
 
  TDOMNode = class
209
 
  protected
210
 
    FNodeName, FNodeValue: DOMString;
211
 
    FNodeType: Integer;
212
 
    FParentNode: TDOMNode;
213
 
    FPreviousSibling, FNextSibling: TDOMNode;
214
 
    FOwnerDocument: TDOMDocument;
215
 
 
216
 
    function  GetNodeValue: DOMString; virtual;
217
 
    procedure SetNodeValue(const AValue: DOMString); virtual;
218
 
    function  GetFirstChild: TDOMNode; virtual;
219
 
    function  GetLastChild: TDOMNode; virtual;
220
 
    function  GetAttributes: TDOMNamedNodeMap; virtual;
221
 
 
222
 
  public
223
 
    constructor Create(AOwner: TDOMDocument);
224
 
    
225
 
    // Free NodeList with TDOMNodeList.Release!
226
 
    function GetChildNodes: TDOMNodeList; virtual;
227
 
 
228
 
    property NodeName: DOMString read FNodeName;
229
 
    property NodeValue: DOMString read GetNodeValue write SetNodeValue;
230
 
    property NodeType: Integer read FNodeType;
231
 
    property ParentNode: TDOMNode read FParentNode;
232
 
    property FirstChild: TDOMNode read GetFirstChild;
233
 
    property LastChild: TDOMNode read GetLastChild;
234
 
    property ChildNodes: TDOMNodeList read GetChildNodes;
235
 
    property PreviousSibling: TDOMNode read FPreviousSibling;
236
 
    property NextSibling: TDOMNode read FNextSibling;
237
 
    property Attributes: TDOMNamedNodeMap read GetAttributes;
238
 
    property OwnerDocument: TDOMDocument read FOwnerDocument;
239
 
 
240
 
    function InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; virtual;
241
 
    function ReplaceChild(NewChild, OldChild: TDOMNode): TDOMNode; virtual;
242
 
    function RemoveChild(OldChild: TDOMNode): TDOMNode; virtual;
243
 
    function AppendChild(NewChild: TDOMNode): TDOMNode; virtual;
244
 
    function HasChildNodes: Boolean; virtual;
245
 
    function CloneNode(deep: Boolean): TDOMNode; overload;
246
 
    function IsEmpty: Boolean; virtual;
247
 
 
248
 
    // Extensions to DOM interface:
249
 
    function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; virtual;
250
 
    function FindNode(const ANodeName: DOMString): TDOMNode; virtual;
251
 
  end;
252
 
 
253
 
 
254
 
  { The following class is an implementation specific extension, it is just an
255
 
    extended implementation of TDOMNode, the generic DOM::Node interface
256
 
    implementation. (Its main purpose is to save memory in a big node tree) }
257
 
 
258
 
  TDOMNode_WithChildren = class(TDOMNode)
259
 
  protected
260
 
    FFirstChild, FLastChild: TDOMNode;
261
 
    FChildNodeTree: TAVLTree;// tree of TDOMNode sorted for Name (=> there can be doubles)
262
 
    function GetFirstChild: TDOMNode; override;
263
 
    function GetLastChild: TDOMNode; override;
264
 
    procedure CloneChildren(ACopy: TDOMNode; ACloneOwner: TDOMDocument);
265
 
    procedure AddToChildNodeTree(NewNode: TDOMNode);
266
 
    procedure RemoveFromChildNodeTree(OldNode: TDOMNode);
267
 
  public
268
 
    destructor Destroy; override;
269
 
    function InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode; override;
270
 
    function ReplaceChild(NewChild, OldChild: TDOMNode): TDOMNode; override;
271
 
    function RemoveChild(OldChild: TDOMNode): TDOMNode; override;
272
 
    function AppendChild(NewChild: TDOMNode): TDOMNode; override;
273
 
    function HasChildNodes: Boolean; override;
274
 
    function FindNode(const ANodeName: DOMString): TDOMNode; override;
275
 
  end;
276
 
 
277
 
 
278
 
// -------------------------------------------------------
279
 
//   NodeList
280
 
// -------------------------------------------------------
281
 
 
282
 
  TDOMNodeList = class(TRefClass)
283
 
  protected
284
 
    node: TDOMNode;
285
 
    filter: DOMString;
286
 
    UseFilter: Boolean;
287
 
    function GetCount: LongInt;
288
 
    function GetItem(index: LongWord): TDOMNode;
289
 
  public
290
 
    constructor Create(ANode: TDOMNode; const AFilter: DOMString);
291
 
    property Item[index: LongWord]: TDOMNode read GetItem;
292
 
    property Count: LongInt read GetCount;
293
 
  end;
294
 
 
295
 
 
296
 
// -------------------------------------------------------
297
 
//   NamedNodeMap
298
 
// -------------------------------------------------------
299
 
 
300
 
  TDOMNamedNodeMap = class(TFPList)
301
 
  protected
302
 
    OwnerDocument: TDOMDocument;
303
 
    function GetItem(index: LongWord): TDOMNode;
304
 
    procedure SetItem(index: LongWord; AItem: TDOMNode);
305
 
    function GetLength: LongInt;
306
 
  public
307
 
    constructor Create(AOwner: TDOMDocument);
308
 
 
309
 
    function GetNamedItem(const name: DOMString): TDOMNode;
310
 
    function SetNamedItem(arg: TDOMNode): TDOMNode;
311
 
    function RemoveNamedItem(const name: DOMString): TDOMNode;
312
 
    property Item[index: LongWord]: TDOMNode read GetItem write SetItem; default;
313
 
    property Length: LongInt read GetLength;
314
 
  end;
315
 
 
316
 
 
317
 
// -------------------------------------------------------
318
 
//   CharacterData
319
 
// -------------------------------------------------------
320
 
 
321
 
  TDOMCharacterData = class(TDOMNode)
322
 
  protected
323
 
    function  GetLength: LongInt;
324
 
  public
325
 
    property Data: DOMString read FNodeValue;
326
 
    property Length: LongInt read GetLength;
327
 
    function SubstringData(offset, count: LongWord): DOMString;
328
 
    procedure AppendData(const arg: DOMString);
329
 
    procedure InsertData(offset: LongWord; const arg: DOMString);
330
 
    procedure DeleteData(offset, count: LongWord);
331
 
    procedure ReplaceData(offset, count: LongWord; const arg: DOMString);
332
 
  end;
333
 
 
334
 
 
335
 
// -------------------------------------------------------
336
 
//   DOMImplementation
337
 
// -------------------------------------------------------
338
 
 
339
 
  TDOMImplementation = class
340
 
  public
341
 
    function HasFeature(const feature, version: DOMString): Boolean;
342
 
 
343
 
    // Introduced in DOM Level 2:
344
 
 
345
 
    function CreateDocumentType(const QualifiedName, PublicID,
346
 
      SystemID: DOMString): TDOMDocumentType;
347
 
    function CreateDocument(const NamespaceURI, QualifiedName: DOMString;
348
 
      doctype: TDOMDocumentType): TDOMDocument;
349
 
  end;
350
 
 
351
 
 
352
 
// -------------------------------------------------------
353
 
//   DocumentFragment
354
 
// -------------------------------------------------------
355
 
 
356
 
  TDOMDocumentFragment = class(TDOMNode_WithChildren)
357
 
  public
358
 
    constructor Create(AOwner: TDOMDocument);
359
 
  end;
360
 
 
361
 
 
362
 
// -------------------------------------------------------
363
 
//   Document
364
 
// -------------------------------------------------------
365
 
 
366
 
  TDOMDocument = class(TDOMNode_WithChildren)
367
 
  protected
368
 
    FDocType: TDOMDocumentType;
369
 
    FImplementation: TDOMImplementation;
370
 
    function GetDocumentElement: TDOMElement;
371
 
  public
372
 
    property DocType: TDOMDocumentType read FDocType;
373
 
    property Impl: TDOMImplementation read FImplementation;
374
 
    property DocumentElement: TDOMElement read GetDocumentElement;
375
 
 
376
 
    function CreateElement(const tagName: DOMString): TDOMElement; virtual;
377
 
    function CreateDocumentFragment: TDOMDocumentFragment;
378
 
    function CreateTextNode(const data: DOMString): TDOMText;
379
 
    function CreateComment(const data: DOMString): TDOMComment;
380
 
    function CreateCDATASection(const data: DOMString): TDOMCDATASection;
381
 
      virtual;
382
 
    function CreateProcessingInstruction(const target, data: DOMString):
383
 
      TDOMProcessingInstruction; virtual;
384
 
    function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
385
 
    function CreateEntityReference(const name: DOMString): TDOMEntityReference;
386
 
      virtual;
387
 
    // Free NodeList with TDOMNodeList.Release!
388
 
    function GetElementsByTagName(const tagname: DOMString): TDOMNodeList;
389
 
 
390
 
    // Extensions to DOM interface:
391
 
    constructor Create;
392
 
    function CreateEntity(const data: DOMString): TDOMEntity;
393
 
  end;
394
 
 
395
 
  TXMLDocument = class(TDOMDocument)
396
 
  public
397
 
    // These fields are extensions to the DOM interface:
398
 
    XMLVersion, Encoding, StylesheetType, StylesheetHRef: DOMString;
399
 
 
400
 
    function CreateCDATASection(const data: DOMString): TDOMCDATASection; override;
401
 
    function CreateProcessingInstruction(const target, data: DOMString):
402
 
      TDOMProcessingInstruction; override;
403
 
    function CreateEntityReference(const name: DOMString): TDOMEntityReference; override;
404
 
  end;
405
 
 
406
 
 
407
 
// -------------------------------------------------------
408
 
//   Attr
409
 
// -------------------------------------------------------
410
 
 
411
 
  TDOMAttr = class(TDOMNode_WithChildren)
412
 
  protected
413
 
    FSpecified: Boolean;
414
 
    AttrOwner: TDOMNamedNodeMap;
415
 
    function  GetNodeValue: DOMString; override;
416
 
    procedure SetNodeValue(const AValue: DOMString); override;
417
 
  public
418
 
    constructor Create(AOwner: TDOMDocument);
419
 
 
420
 
    function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
421
 
    property Name: DOMString read FNodeName;
422
 
    property Specified: Boolean read FSpecified;
423
 
    property Value: DOMString read GetNodeValue write SetNodeValue;
424
 
  end;
425
 
 
426
 
 
427
 
// -------------------------------------------------------
428
 
//   Element
429
 
// -------------------------------------------------------
430
 
 
431
 
  { TDOMElement }
432
 
 
433
 
  TDOMElement = class(TDOMNode_WithChildren)
434
 
  private
435
 
    FAttributes: TDOMNamedNodeMap;
436
 
  protected
437
 
    function GetAttributes: TDOMNamedNodeMap; override;
438
 
  public
439
 
    constructor Create(AOwner: TDOMDocument);
440
 
    destructor Destroy; override;
441
 
    function  CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
442
 
    property  TagName: DOMString read FNodeName;
443
 
    function  GetAttribute(const name: DOMString): DOMString;
444
 
    procedure SetAttribute(const name, value: DOMString);
445
 
    procedure RemoveAttribute(const name: DOMString);
446
 
    function  GetAttributeNode(const name: DOMString): TDOMAttr;
447
 
    procedure SetAttributeNode(NewAttr: TDOMAttr);
448
 
    function  RemoveAttributeNode(OldAttr: TDOMAttr): TDOMAttr;
449
 
    // Free NodeList with TDOMNodeList.Release!
450
 
    function  GetElementsByTagName(const name: DOMString): TDOMNodeList;
451
 
    function  IsEmpty: Boolean; override;
452
 
    procedure Normalize;
453
 
 
454
 
    property AttribStrings[const Name: DOMString]: DOMString
455
 
      read GetAttribute write SetAttribute; default;
456
 
  end;
457
 
 
458
 
 
459
 
// -------------------------------------------------------
460
 
//   Text
461
 
// -------------------------------------------------------
462
 
 
463
 
  TDOMText = class(TDOMCharacterData)
464
 
  public
465
 
    constructor Create(AOwner: TDOMDocument);
466
 
    function  CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
467
 
    function SplitText(offset: LongWord): TDOMText;
468
 
  end;
469
 
 
470
 
 
471
 
// -------------------------------------------------------
472
 
//   Comment
473
 
// -------------------------------------------------------
474
 
 
475
 
  TDOMComment = class(TDOMCharacterData)
476
 
  public
477
 
    constructor Create(AOwner: TDOMDocument);
478
 
    function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
479
 
  end;
480
 
 
481
 
 
482
 
// -------------------------------------------------------
483
 
//   CDATASection
484
 
// -------------------------------------------------------
485
 
 
486
 
  TDOMCDATASection = class(TDOMText)
487
 
  public
488
 
    constructor Create(AOwner: TDOMDocument);
489
 
    function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
490
 
  end;
491
 
 
492
 
 
493
 
// -------------------------------------------------------
494
 
//   DocumentType
495
 
// -------------------------------------------------------
496
 
 
497
 
  TDOMDocumentType = class(TDOMNode)
498
 
  protected
499
 
    FEntities, FNotations: TDOMNamedNodeMap;
500
 
  public
501
 
    constructor Create(AOwner: TDOMDocument);
502
 
    function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
503
 
    property Name: DOMString read FNodeName;
504
 
    property Entities: TDOMNamedNodeMap read FEntities;
505
 
    property Notations: TDOMNamedNodeMap read FEntities;
506
 
  end;
507
 
 
508
 
 
509
 
// -------------------------------------------------------
510
 
//   Notation
511
 
// -------------------------------------------------------
512
 
 
513
 
  TDOMNotation = class(TDOMNode)
514
 
  protected
515
 
    FPublicID, FSystemID: DOMString;
516
 
  public
517
 
    constructor Create(AOwner: TDOMDocument);
518
 
    function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; override;
519
 
    property PublicID: DOMString read FPublicID;
520
 
    property SystemID: DOMString read FSystemID;
521
 
  end;
522
 
 
523
 
 
524
 
// -------------------------------------------------------
525
 
//   Entity
526
 
// -------------------------------------------------------
527
 
 
528
 
  TDOMEntity = class(TDOMNode_WithChildren)
529
 
  protected
530
 
    FPublicID, FSystemID, FNotationName: DOMString;
531
 
  public
532
 
    constructor Create(AOwner: TDOMDocument);
533
 
    property PublicID: DOMString read FPublicID;
534
 
    property SystemID: DOMString read FSystemID;
535
 
    property NotationName: DOMString read FNotationName;
536
 
  end;
537
 
 
538
 
 
539
 
// -------------------------------------------------------
540
 
//   EntityReference
541
 
// -------------------------------------------------------
542
 
 
543
 
  TDOMEntityReference = class(TDOMNode_WithChildren)
544
 
  public
545
 
    constructor Create(AOwner: TDOMDocument);
546
 
  end;
547
 
 
548
 
 
549
 
// -------------------------------------------------------
550
 
//   ProcessingInstruction
551
 
// -------------------------------------------------------
552
 
 
553
 
  TDOMProcessingInstruction = class(TDOMNode)
554
 
  public
555
 
    constructor Create(AOwner: TDOMDocument);
556
 
    property Target: DOMString read FNodeName;
557
 
    property Data: DOMString read FNodeValue;
558
 
  end;
559
 
 
560
 
 
561
 
 
562
 
 
563
 
// =======================================================
564
 
// =======================================================
565
 
 
566
 
implementation
567
 
 
568
 
 
569
 
constructor TRefClass.Create;
570
 
begin
571
 
  inherited Create;
572
 
  RefCounter := 1;
573
 
end;
574
 
 
575
 
function TRefClass.AddRef: LongInt;
576
 
begin
577
 
  Inc(RefCounter);
578
 
  Result := RefCounter;
579
 
end;
580
 
 
581
 
function TRefClass.Release: LongInt;
582
 
begin
583
 
  Dec(RefCounter);
584
 
  Result := RefCounter;
585
 
  if RefCounter <= 0 then Free;
586
 
end;
587
 
 
588
 
 
589
 
// -------------------------------------------------------
590
 
//   DOM Exception
591
 
// -------------------------------------------------------
592
 
 
593
 
constructor EDOMError.Create(ACode: Integer; const ASituation: String);
594
 
begin
595
 
  Code := ACode;
596
 
  inherited Create(Self.ClassName + ' in ' + ASituation);
597
 
end;
598
 
 
599
 
constructor EDOMIndexSize.Create(const ASituation: String);    // 1
600
 
begin
601
 
  inherited Create(INDEX_SIZE_ERR, ASituation);
602
 
end;
603
 
 
604
 
constructor EDOMHierarchyRequest.Create(const ASituation: String);    // 3
605
 
begin
606
 
  inherited Create(HIERARCHY_REQUEST_ERR, ASituation);
607
 
end;
608
 
 
609
 
constructor EDOMWrongDocument.Create(const ASituation: String);    // 4
610
 
begin
611
 
  inherited Create(WRONG_DOCUMENT_ERR, ASituation);
612
 
end;
613
 
 
614
 
constructor EDOMNotFound.Create(const ASituation: String);    // 8
615
 
begin
616
 
  inherited Create(NOT_FOUND_ERR, ASituation);
617
 
end;
618
 
 
619
 
constructor EDOMNotSupported.Create(const ASituation: String);    // 9
620
 
begin
621
 
  inherited Create(NOT_SUPPORTED_ERR, ASituation);
622
 
end;
623
 
 
624
 
constructor EDOMInUseAttribute.Create(const ASituation: String);    // 10
625
 
begin
626
 
  inherited Create(INUSE_ATTRIBUTE_ERR, ASituation);
627
 
end;
628
 
 
629
 
constructor EDOMInvalidState.Create(const ASituation: String);    // 11
630
 
begin
631
 
  inherited Create(INVALID_STATE_ERR, ASituation);
632
 
end;
633
 
 
634
 
constructor EDOMSyntax.Create(const ASituation: String);    // 12
635
 
begin
636
 
  inherited Create(SYNTAX_ERR, ASituation);
637
 
end;
638
 
 
639
 
constructor EDOMInvalidModification.Create(const ASituation: String);    // 13
640
 
begin
641
 
  inherited Create(INVALID_MODIFICATION_ERR, ASituation);
642
 
end;
643
 
 
644
 
constructor EDOMNamespace.Create(const ASituation: String);    // 14
645
 
begin
646
 
  inherited Create(NAMESPACE_ERR, ASituation);
647
 
end;
648
 
 
649
 
constructor EDOMInvalidAccess.Create(const ASituation: String);    // 15
650
 
begin
651
 
  inherited Create(INVALID_ACCESS_ERR, ASituation);
652
 
end;
653
 
 
654
 
 
655
 
// -------------------------------------------------------
656
 
//   Node
657
 
// -------------------------------------------------------
658
 
 
659
 
constructor TDOMNode.Create(AOwner: TDOMDocument);
660
 
begin
661
 
  FOwnerDocument := AOwner;
662
 
  inherited Create;
663
 
end;
664
 
 
665
 
function TDOMNode.GetNodeValue: DOMString;
666
 
begin
667
 
  Result := FNodeValue;
668
 
end;
669
 
 
670
 
procedure TDOMNode.SetNodeValue(const AValue: DOMString);
671
 
begin
672
 
  FNodeValue := AValue;
673
 
end;
674
 
 
675
 
function TDOMNode.GetChildNodes: TDOMNodeList;
676
 
begin
677
 
  Result := TDOMNodeList.Create(Self, '*');
678
 
end;
679
 
 
680
 
function TDOMNode.GetFirstChild: TDOMNode;
681
 
begin
682
 
  Result := nil;
683
 
end;
684
 
 
685
 
function TDOMNode.GetLastChild: TDOMNode;
686
 
begin
687
 
  Result := nil;
688
 
end;
689
 
 
690
 
function TDOMNode.GetAttributes: TDOMNamedNodeMap;
691
 
begin
692
 
  Result := nil;
693
 
end;
694
 
 
695
 
function TDOMNode.InsertBefore(NewChild, RefChild: TDOMNode): TDOMNode;
696
 
begin
697
 
  raise EDOMHierarchyRequest.Create('Node.InsertBefore');
698
 
  if (NewChild=nil) and (RefChild=nil) then ;
699
 
  Result:=nil;
700
 
end;
701
 
 
702
 
function TDOMNode.ReplaceChild(NewChild, OldChild: TDOMNode): TDOMNode;
703
 
begin
704
 
  raise EDOMHierarchyRequest.Create('Node.ReplaceChild');
705
 
  if (NewChild=nil) and (OldChild=nil) then ;
706
 
  Result:=nil;
707
 
end;
708
 
 
709
 
function TDOMNode.RemoveChild(OldChild: TDOMNode): TDOMNode;
710
 
begin
711
 
  raise EDOMHierarchyRequest.Create('Node.RemoveChild');
712
 
  if (OldChild=nil) then ;
713
 
  Result:=nil;
714
 
end;
715
 
 
716
 
function TDOMNode.AppendChild(NewChild: TDOMNode): TDOMNode;
717
 
begin
718
 
  raise EDOMHierarchyRequest.Create('Node.AppendChild');
719
 
  if (NewChild=nil) then ;
720
 
  Result:=nil;
721
 
end;
722
 
 
723
 
function TDOMNode.HasChildNodes: Boolean;
724
 
begin
725
 
  Result := False;
726
 
end;
727
 
 
728
 
function TDOMNode.CloneNode(deep: Boolean): TDOMNode;
729
 
begin
730
 
  if deep then ;
731
 
  Result:=CloneNode(deep, FOwnerDocument);
732
 
end;
733
 
 
734
 
function TDOMNode.IsEmpty: Boolean;
735
 
begin
736
 
  Result:=true;
737
 
end;
738
 
 
739
 
function TDOMNode.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
740
 
begin
741
 
  raise EDOMNotSupported.Create('CloneNode not implemented for ' + ClassName);
742
 
  if (deep) and (ACloneOwner=nil) then ;
743
 
  Result:=nil;
744
 
end;
745
 
 
746
 
function TDOMNode.FindNode(const ANodeName: DOMString): TDOMNode;
747
 
var
748
 
  child: TDOMNode;
749
 
begin
750
 
  child := FirstChild;
751
 
  while Assigned(child) do
752
 
  begin
753
 
    if child.NodeName = ANodeName then
754
 
    begin
755
 
      Result := child;
756
 
      exit;
757
 
    end;
758
 
    child := child.NextSibling;
759
 
  end;
760
 
  Result := nil;
761
 
end;
762
 
 
763
 
//------------------------------------------------------------------------------
764
 
 
765
 
function CompareDOMStrings(const s1, s2: DOMPChar; l1, l2: integer): integer;
766
 
var i: integer;
767
 
begin
768
 
  Result:=l1-l2;
769
 
  i:=0;
770
 
  while (i<l1) and (Result=0) do begin
771
 
    Result:=ord(s1[i])-ord(s2[i]);
772
 
    inc(i);
773
 
  end;
774
 
end;
775
 
 
776
 
function CompareDOMNodeWithDOMNode(Node1, Node2: Pointer): integer;
777
 
begin
778
 
  Result:=CompareDOMStrings(DOMPChar(Pointer(TDOMNode(Node1).NodeName)),
779
 
                            DOMPChar(Pointer(TDOMNode(Node2).NodeName)),
780
 
                            length(TDOMNode(Node1).NodeName),
781
 
                            length(TDOMNode(Node2).NodeName)
782
 
                            );
783
 
end;
784
 
 
785
 
function CompareDOMStringWithDOMNode(AKey, ANode: Pointer): integer;
786
 
begin
787
 
  Result:=CompareDOMStrings(DOMPChar(AKey),
788
 
                            DOMPChar(Pointer(TDOMNode(ANode).NodeName)),
789
 
                            length(DOMString(AKey)),
790
 
                            length(TDOMNode(ANode).NodeName)
791
 
                            );
792
 
end;
793
 
 
794
 
 
795
 
function TDOMNode_WithChildren.GetFirstChild: TDOMNode;
796
 
begin
797
 
  Result := FFirstChild;
798
 
end;
799
 
 
800
 
function TDOMNode_WithChildren.GetLastChild: TDOMNode;
801
 
begin
802
 
  Result := FLastChild;
803
 
end;
804
 
 
805
 
destructor TDOMNode_WithChildren.Destroy;
806
 
var
807
 
  child, next: TDOMNode;
808
 
begin
809
 
  if FChildNodeTree<>nil then begin
810
 
    FChildNodeTree.Free;
811
 
    FChildNodeTree:=nil;
812
 
  end;
813
 
  child := FirstChild;
814
 
  while Assigned(child) do
815
 
  begin
816
 
    next := child.NextSibling;
817
 
    child.Free;
818
 
    child := next;
819
 
  end;
820
 
  inherited Destroy;
821
 
end;
822
 
 
823
 
function TDOMNode_WithChildren.InsertBefore(NewChild, RefChild: TDOMNode):
824
 
  TDOMNode;
825
 
begin
826
 
  Result := NewChild;
827
 
 
828
 
  if not Assigned(RefChild) then
829
 
  begin
830
 
    AppendChild(NewChild);
831
 
    exit;
832
 
  end;
833
 
 
834
 
  if NewChild.FOwnerDocument <> FOwnerDocument then
835
 
    raise EDOMWrongDocument.Create('NodeWC.InsertBefore');
836
 
 
837
 
  if RefChild.ParentNode <> Self then
838
 
    raise EDOMHierarchyRequest.Create('NodeWC.InsertBefore');
839
 
 
840
 
  if NewChild.NodeType = DOCUMENT_FRAGMENT_NODE then
841
 
    raise EDOMNotSupported.Create('NodeWC.InsertBefore for DocumentFragment');
842
 
 
843
 
  NewChild.FNextSibling := RefChild;
844
 
  if RefChild = FFirstChild then
845
 
    FFirstChild := NewChild
846
 
  else
847
 
  begin
848
 
    RefChild.FPreviousSibling.FNextSibling := NewChild;
849
 
    NewChild.FPreviousSibling := RefChild.FPreviousSibling;
850
 
  end;
851
 
 
852
 
  RefChild.FPreviousSibling := NewChild;
853
 
  NewChild.FParentNode := Self;
854
 
  AddToChildNodeTree(NewChild);
855
 
end;
856
 
 
857
 
function TDOMNode_WithChildren.ReplaceChild(NewChild, OldChild: TDOMNode):
858
 
  TDOMNode;
859
 
begin
860
 
  InsertBefore(NewChild, OldChild);
861
 
  if Assigned(OldChild) then
862
 
    RemoveChild(OldChild);
863
 
  Result := NewChild;
864
 
end;
865
 
 
866
 
function TDOMNode_WithChildren.RemoveChild(OldChild: TDOMNode):
867
 
  TDOMNode;
868
 
begin
869
 
  if OldChild.ParentNode <> Self then
870
 
    raise EDOMHierarchyRequest.Create('NodeWC.RemoveChild');
871
 
 
872
 
  if OldChild = FFirstChild then
873
 
    FFirstChild := FFirstChild.NextSibling
874
 
  else
875
 
    OldChild.FPreviousSibling.FNextSibling := OldChild.FNextSibling;
876
 
 
877
 
  if OldChild = FLastChild then
878
 
    FLastChild := FLastChild.FPreviousSibling
879
 
  else
880
 
    OldChild.FNextSibling.FPreviousSibling := OldChild.FPreviousSibling;
881
 
 
882
 
  RemoveFromChildNodeTree(OldChild);
883
 
  OldChild.Free;
884
 
  Result:=nil;
885
 
end;
886
 
 
887
 
function TDOMNode_WithChildren.AppendChild(NewChild: TDOMNode): TDOMNode;
888
 
var
889
 
  Parent: TDOMNode;
890
 
begin
891
 
  //writeln('TDOMNode_WithChildren.AppendChild ',NodeName,' NewChild=',NewChild.NodeName);
892
 
  if NewChild.FOwnerDocument <> FOwnerDocument then
893
 
    raise EDOMWrongDocument.Create('NodeWC.AppendChild');
894
 
 
895
 
  Parent := Self;
896
 
  while Assigned(Parent) do
897
 
  begin
898
 
    if Parent = NewChild then
899
 
      raise EDOMHierarchyRequest.Create('NodeWC.AppendChild (cycle in tree)');
900
 
    Parent := Parent.ParentNode;
901
 
  end;
902
 
 
903
 
  if NewChild.FParentNode<>nil then begin
904
 
    //writeln('TDOMNode_WithChildren.AppendChild old NewChild.FParentNode=',NewChild.FParentNode.NodeName);
905
 
    NewChild.FParentNode.RemoveChild(NewChild);
906
 
  end;
907
 
 
908
 
  if NewChild.NodeType = DOCUMENT_FRAGMENT_NODE then
909
 
    raise EDOMNotSupported.Create('NodeWC.AppendChild for DocumentFragments')
910
 
  else begin
911
 
    if Assigned(FFirstChild) then
912
 
    begin
913
 
      FLastChild.FNextSibling := NewChild;
914
 
      NewChild.FPreviousSibling := FLastChild;
915
 
    end else
916
 
      FFirstChild := NewChild;
917
 
    FLastChild := NewChild;
918
 
    NewChild.FParentNode := Self;
919
 
  end;
920
 
  AddToChildNodeTree(NewChild);
921
 
  Result := NewChild;
922
 
end;
923
 
 
924
 
function TDOMNode_WithChildren.HasChildNodes: Boolean;
925
 
begin
926
 
  Result := Assigned(FFirstChild);
927
 
end;
928
 
 
929
 
function TDOMNode_WithChildren.FindNode(const ANodeName: DOMString): TDOMNode;
930
 
var
931
 
  AVLNode: TAVLTreeNode;
932
 
begin
933
 
  Result:=nil;
934
 
  if FChildNodeTree<>nil then begin
935
 
    // use tree for fast search
936
 
    //if FChildNodeTree.ConsistencyCheck<>0 then
937
 
    //  raise exception.Create('TDOMNode_WithChildren.FindNode');
938
 
    AVLNode:=FChildNodeTree.FindKey(DOMPChar(Pointer(ANodeName)),
939
 
                                    @CompareDOMStringWithDOMNode);
940
 
    if AVLNode<>nil then
941
 
      Result:=TDOMNode(AVLNode.Data);
942
 
  end else begin
943
 
    // search in list
944
 
    Result := FirstChild;
945
 
    while Assigned(Result) do begin
946
 
      if CompareDOMStringWithDOMNode(DOMPChar(Pointer(ANodeName)),Result)=0
947
 
      then exit;
948
 
      Result := Result.NextSibling;
949
 
    end;
950
 
  end;
951
 
end;
952
 
 
953
 
procedure TDOMNode_WithChildren.CloneChildren(ACopy: TDOMNode;
954
 
  ACloneOwner: TDOMDocument);
955
 
var
956
 
  node: TDOMNode;
957
 
begin
958
 
  node := FirstChild;
959
 
  while Assigned(node) do
960
 
  begin
961
 
    ACopy.AppendChild(node.CloneNode(True, ACloneOwner));
962
 
    node := node.NextSibling;
963
 
  end;
964
 
end;
965
 
 
966
 
procedure TDOMNode_WithChildren.AddToChildNodeTree(NewNode: TDOMNode);
967
 
var
968
 
  ChildCount: Integer;
969
 
  ANode: TDOMNode;
970
 
  NewNodeAdded: Boolean;
971
 
begin
972
 
  if (FChildNodeTree=nil) then begin
973
 
    // there is no childnodetree yet
974
 
    // Most xml trees contains nodes with only a few child nodes. It would be
975
 
    // overhead to create a tree for only a few children.
976
 
    ChildCount := 0;
977
 
    ANode := FirstChild;
978
 
    while Assigned(ANode) do begin
979
 
      inc(ChildCount);
980
 
      ANode := ANode.NextSibling;
981
 
    end;
982
 
    if ChildCount>5 then begin
983
 
      FChildNodeTree:=TAVLTree.Create(@CompareDOMNodeWithDOMNode);
984
 
      // add all existing children
985
 
      ANode := FirstChild;
986
 
      NewNodeAdded:=false;
987
 
      while Assigned(ANode) do begin
988
 
        if ANode=NewNode then NewNodeAdded:=true;
989
 
        FChildNodeTree.Add(ANode);
990
 
        ANode := ANode.NextSibling;
991
 
      end;
992
 
      if not NewNodeAdded then
993
 
        FChildNodeTree.Add(NewNode);
994
 
    end;
995
 
  end else begin
996
 
    {if (FChildNodeTree.Find(NewNode)<>nil) then begin
997
 
      writeln('TDOMNode_WithChildren.AddToChildNodeTree adding same value ',NewNOde.NodeName);
998
 
      CTDumpStack;
999
 
    end;}
1000
 
    FChildNodeTree.Add(NewNode);
1001
 
  end;
1002
 
  //if FChildNodeTree.ConsistencyCheck<>0 then
1003
 
  //  raise exception.Create('TDOMNode_WithChildren.FindNode');
1004
 
end;
1005
 
 
1006
 
procedure TDOMNode_WithChildren.RemoveFromChildNodeTree(OldNode: TDOMNode);
1007
 
begin
1008
 
  if FChildNodeTree<>nil then
1009
 
    FChildNodeTree.RemovePointer(OldNode);// doubles are allowed, so Remove can not be used
1010
 
  //if (FChildNodeTree<>nil) and (FChildNodeTree.ConsistencyCheck<>0) then
1011
 
  //  raise exception.Create('TDOMNode_WithChildren.FindNode');
1012
 
end;
1013
 
 
1014
 
 
1015
 
// -------------------------------------------------------
1016
 
//   NodeList
1017
 
// -------------------------------------------------------
1018
 
 
1019
 
constructor TDOMNodeList.Create(ANode: TDOMNode; const AFilter: DOMString);
1020
 
begin
1021
 
  inherited Create;
1022
 
  node := ANode;
1023
 
  filter := AFilter;
1024
 
  UseFilter := filter <> '*';
1025
 
end;
1026
 
 
1027
 
function TDOMNodeList.GetCount: LongInt;
1028
 
var
1029
 
  child: TDOMNode;
1030
 
begin
1031
 
  Result := 0;
1032
 
  child := node.FirstChild;
1033
 
  while Assigned(child) do
1034
 
  begin
1035
 
    if (not UseFilter) or (child.NodeName = filter) then
1036
 
      Inc(Result);
1037
 
    child := child.NextSibling;
1038
 
  end;
1039
 
end;
1040
 
 
1041
 
function TDOMNodeList.GetItem(index: LongWord): TDOMNode;
1042
 
var
1043
 
  child: TDOMNode;
1044
 
begin
1045
 
  Result := nil;
1046
 
  child := node.FirstChild;
1047
 
  while Assigned(child) do
1048
 
  begin
1049
 
    if index = 0 then
1050
 
    begin
1051
 
      Result := child;
1052
 
      break;
1053
 
    end;
1054
 
    if (not UseFilter) or (child.NodeName = filter) then
1055
 
      Dec(index);
1056
 
    child := child.NextSibling;
1057
 
  end;
1058
 
end;
1059
 
 
1060
 
 
1061
 
// -------------------------------------------------------
1062
 
//   NamedNodeMap
1063
 
// -------------------------------------------------------
1064
 
 
1065
 
constructor TDOMNamedNodeMap.Create(AOwner: TDOMDocument);
1066
 
begin
1067
 
  inherited Create;
1068
 
  OwnerDocument := AOwner;
1069
 
end;
1070
 
 
1071
 
function TDOMNamedNodeMap.GetItem(index: LongWord): TDOMNode;
1072
 
begin
1073
 
  Result := TDOMNode(Items[index]);
1074
 
end;
1075
 
 
1076
 
procedure TDOMNamedNodeMap.SetItem(index: LongWord; AItem: TDOMNode);
1077
 
begin
1078
 
  Items[index] := AItem;
1079
 
end;
1080
 
 
1081
 
function TDOMNamedNodeMap.GetLength: LongInt;
1082
 
begin
1083
 
  Result := Count;
1084
 
end;
1085
 
 
1086
 
function TDOMNamedNodeMap.GetNamedItem(const name: DOMString): TDOMNode;
1087
 
var
1088
 
  i: Integer;
1089
 
begin
1090
 
  for i := 0 to Count - 1 do
1091
 
  begin
1092
 
    Result := Item[i];
1093
 
    if Result.NodeName = name then
1094
 
      exit;
1095
 
  end;
1096
 
  Result := nil;
1097
 
end;
1098
 
 
1099
 
function TDOMNamedNodeMap.SetNamedItem(arg: TDOMNode): TDOMNode;
1100
 
var
1101
 
  i: Integer;
1102
 
begin
1103
 
  if arg.FOwnerDocument <> OwnerDocument then
1104
 
    raise EDOMWrongDocument.Create('NamedNodeMap.SetNamedItem');
1105
 
 
1106
 
  if arg.NodeType = ATTRIBUTE_NODE then
1107
 
  begin
1108
 
    if Assigned(TDOMAttr(arg).AttrOwner) then
1109
 
      raise EDOMInUseAttribute.Create('NamedNodeMap.SetNamedItem');
1110
 
    TDOMAttr(arg).AttrOwner := Self;
1111
 
  end;
1112
 
 
1113
 
  for i := 0 to Count - 1 do
1114
 
    if Item[i].NodeName = arg.NodeName then
1115
 
    begin
1116
 
      Result := Item[i];
1117
 
      Item[i] := arg;
1118
 
      exit;
1119
 
    end;
1120
 
  Add(arg);
1121
 
  Result := nil;
1122
 
end;
1123
 
 
1124
 
function TDOMNamedNodeMap.RemoveNamedItem(const name: DOMString): TDOMNode;
1125
 
var
1126
 
  i: Integer;
1127
 
begin
1128
 
  for i := 0 to Count - 1 do
1129
 
    if Item[i].NodeName = name then
1130
 
    begin
1131
 
      Result := Item[i];
1132
 
      Result.FParentNode := nil;
1133
 
      exit;
1134
 
    end;
1135
 
  raise EDOMNotFound.Create('NamedNodeMap.RemoveNamedItem');
1136
 
end;
1137
 
 
1138
 
 
1139
 
// -------------------------------------------------------
1140
 
//   CharacterData
1141
 
// -------------------------------------------------------
1142
 
 
1143
 
function TDOMCharacterData.GetLength: LongInt;
1144
 
begin
1145
 
  Result := system.Length(FNodeValue);
1146
 
end;
1147
 
 
1148
 
function TDOMCharacterData.SubstringData(offset, count: LongWord): DOMString;
1149
 
begin
1150
 
  if (offset < 0) or (longint(offset) > Length) or (count < 0) then
1151
 
    raise EDOMIndexSize.Create('CharacterData.SubstringData');
1152
 
  Result := Copy(FNodeValue, offset + 1, count);
1153
 
end;
1154
 
 
1155
 
procedure TDOMCharacterData.AppendData(const arg: DOMString);
1156
 
begin
1157
 
  FNodeValue := FNodeValue + arg;
1158
 
end;
1159
 
 
1160
 
procedure TDOMCharacterData.InsertData(offset: LongWord; const arg: DOMString);
1161
 
begin
1162
 
  if (offset < 0) or (longint(offset) > Length) then
1163
 
    raise EDOMIndexSize.Create('CharacterData.InsertData');
1164
 
 
1165
 
  FNodeValue := Copy(FNodeValue, 1, offset) + arg +
1166
 
    Copy(FNodeValue, offset + 1, Length);
1167
 
end;
1168
 
 
1169
 
procedure TDOMCharacterData.DeleteData(offset, count: LongWord);
1170
 
begin
1171
 
  if (offset < 0) or (longint(offset) > Length) or (count < 0) then
1172
 
    raise EDOMIndexSize.Create('CharacterData.DeleteData');
1173
 
 
1174
 
  FNodeValue := Copy(FNodeValue, 1, offset) +
1175
 
    Copy(FNodeValue, offset + count + 1, Length);
1176
 
end;
1177
 
 
1178
 
procedure TDOMCharacterData.ReplaceData(offset, count: LongWord; const arg: DOMString);
1179
 
begin
1180
 
  DeleteData(offset, count);
1181
 
  InsertData(offset, arg);
1182
 
end;
1183
 
 
1184
 
 
1185
 
// -------------------------------------------------------
1186
 
//   DocumentFragmet
1187
 
// -------------------------------------------------------
1188
 
 
1189
 
constructor TDOMDocumentFragment.Create(AOwner: TDOMDocument);
1190
 
begin
1191
 
  FNodeType := DOCUMENT_FRAGMENT_NODE;
1192
 
  FNodeName := '#document-fragment';
1193
 
  inherited Create(AOwner);
1194
 
end;
1195
 
 
1196
 
 
1197
 
// -------------------------------------------------------
1198
 
//   DOMImplementation
1199
 
// -------------------------------------------------------
1200
 
 
1201
 
function TDOMImplementation.HasFeature(const feature, version: DOMString):
1202
 
  Boolean;
1203
 
begin
1204
 
  Result := False;
1205
 
  if (feature='') and (version='') then ;
1206
 
end;
1207
 
 
1208
 
function TDOMImplementation.CreateDocumentType(const QualifiedName, PublicID,
1209
 
  SystemID: DOMString): TDOMDocumentType;
1210
 
begin
1211
 
  // !!!: Implement this method (easy to do)
1212
 
  raise EDOMNotSupported.Create('DOMImplementation.CreateDocumentType');
1213
 
  if (QualifiedName='') and (PublicID='') and (SystemID='') then ;
1214
 
  Result:=nil;
1215
 
end;
1216
 
 
1217
 
function TDOMImplementation.CreateDocument(const NamespaceURI,
1218
 
  QualifiedName: DOMString; doctype: TDOMDocumentType): TDOMDocument;
1219
 
begin
1220
 
  // !!!: Implement this method (easy to do)
1221
 
  raise EDOMNotSupported.Create('DOMImplementation.CreateDocument');
1222
 
  if (NamespaceURI='') and (QualifiedName='') and (doctype=nil) then ;
1223
 
  Result:=nil;
1224
 
end;
1225
 
 
1226
 
 
1227
 
// -------------------------------------------------------
1228
 
//   Document
1229
 
// -------------------------------------------------------
1230
 
 
1231
 
constructor TDOMDocument.Create;
1232
 
begin
1233
 
  FNodeType := DOCUMENT_NODE;
1234
 
  FNodeName := '#document';
1235
 
  inherited Create(nil);
1236
 
  FOwnerDocument := Self;
1237
 
end;
1238
 
 
1239
 
function TDOMDocument.GetDocumentElement: TDOMElement;
1240
 
var
1241
 
  node: TDOMNode;
1242
 
begin
1243
 
  node := FFirstChild;
1244
 
  while Assigned(node) do
1245
 
  begin
1246
 
    if node.FNodeType = ELEMENT_NODE then
1247
 
    begin
1248
 
      Result := TDOMElement(node);
1249
 
      exit;
1250
 
    end;
1251
 
    node := node.NextSibling;
1252
 
  end;
1253
 
  Result := nil;
1254
 
end;
1255
 
 
1256
 
function TDOMDocument.CreateElement(const tagName: DOMString): TDOMElement;
1257
 
begin
1258
 
  Result := TDOMElement.Create(Self);
1259
 
  Result.FNodeName := tagName;
1260
 
end;
1261
 
 
1262
 
function TDOMDocument.CreateDocumentFragment: TDOMDocumentFragment;
1263
 
begin
1264
 
  Result := TDOMDocumentFragment.Create(Self);
1265
 
end;
1266
 
 
1267
 
function TDOMDocument.CreateTextNode(const data: DOMString): TDOMText;
1268
 
begin
1269
 
  Result := TDOMText.Create(Self);
1270
 
  Result.FNodeValue := data;
1271
 
end;
1272
 
 
1273
 
function TDOMDocument.CreateComment(const data: DOMString): TDOMComment;
1274
 
begin
1275
 
  Result := TDOMComment.Create(Self);
1276
 
  Result.FNodeValue := data;
1277
 
end;
1278
 
 
1279
 
function TDOMDocument.CreateCDATASection(const data: DOMString):
1280
 
  TDOMCDATASection;
1281
 
begin
1282
 
  raise EDOMNotSupported.Create('DOMDocument.CreateCDATASection');
1283
 
  if data='' then ;
1284
 
  Result:=nil;
1285
 
end;
1286
 
 
1287
 
function TDOMDocument.CreateProcessingInstruction(const target,
1288
 
  data: DOMString): TDOMProcessingInstruction;
1289
 
begin
1290
 
  raise EDOMNotSupported.Create('DOMDocument.CreateProcessingInstruction');
1291
 
  if (target='') and (data='') then ;
1292
 
  Result:=nil;
1293
 
end;
1294
 
 
1295
 
function TDOMDocument.CreateAttribute(const name: DOMString): TDOMAttr;
1296
 
begin
1297
 
  Result := TDOMAttr.Create(Self);
1298
 
  Result.FNodeName := name;
1299
 
end;
1300
 
 
1301
 
function TDOMDocument.CreateEntityReference(const name: DOMString):
1302
 
  TDOMEntityReference;
1303
 
begin
1304
 
  raise EDOMNotSupported.Create('DOMDocument.CreateEntityReference');
1305
 
  if name='' then ;
1306
 
  Result:=nil;
1307
 
end;
1308
 
 
1309
 
function TDOMDocument.CreateEntity(const data: DOMString): TDOMEntity;
1310
 
begin
1311
 
  Result := TDOMEntity.Create(Self);
1312
 
  Result.FNodeName := data;
1313
 
end;
1314
 
 
1315
 
function TDOMDocument.GetElementsByTagName(const tagname: DOMString): TDOMNodeList;
1316
 
begin
1317
 
  Result := TDOMNodeList.Create(Self, tagname);
1318
 
end;
1319
 
 
1320
 
 
1321
 
function TXMLDocument.CreateCDATASection(const data: DOMString):
1322
 
  TDOMCDATASection;
1323
 
begin
1324
 
  Result := TDOMCDATASection.Create(Self);
1325
 
  Result.FNodeValue := data;
1326
 
end;
1327
 
 
1328
 
function TXMLDocument.CreateProcessingInstruction(const target,
1329
 
  data: DOMString): TDOMProcessingInstruction;
1330
 
begin
1331
 
  Result := TDOMProcessingInstruction.Create(Self);
1332
 
  Result.FNodeName := target;
1333
 
  Result.FNodeValue := data;
1334
 
end;
1335
 
 
1336
 
function TXMLDocument.CreateEntityReference(const name: DOMString):
1337
 
  TDOMEntityReference;
1338
 
begin
1339
 
  Result := TDOMEntityReference.Create(Self);
1340
 
  Result.FNodeName := name;
1341
 
end;
1342
 
 
1343
 
 
1344
 
// -------------------------------------------------------
1345
 
//   Attr
1346
 
// -------------------------------------------------------
1347
 
 
1348
 
constructor TDOMAttr.Create(AOwner: TDOMDocument);
1349
 
begin
1350
 
  FNodeType := ATTRIBUTE_NODE;
1351
 
  inherited Create(AOwner);
1352
 
end;
1353
 
 
1354
 
function TDOMAttr.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1355
 
begin
1356
 
  Result := TDOMAttr.Create(ACloneOwner);
1357
 
  Result.FNodeName := FNodeName;
1358
 
  TDOMAttr(Result).FSpecified := FSpecified;
1359
 
  if deep then
1360
 
    CloneChildren(Result, ACloneOwner);
1361
 
end;
1362
 
 
1363
 
function TDOMAttr.GetNodeValue: DOMString;
1364
 
var
1365
 
  child: TDOMNode;
1366
 
begin
1367
 
  SetLength(Result, 0);
1368
 
  if Assigned(FFirstChild) then
1369
 
  begin
1370
 
    child := FFirstChild;
1371
 
    while Assigned(child) do
1372
 
    begin
1373
 
      if child.NodeType = ENTITY_REFERENCE_NODE then
1374
 
        Result := Result + '&' + child.NodeName + ';'
1375
 
      else
1376
 
        Result := Result + child.NodeValue;
1377
 
      child := child.NextSibling;
1378
 
    end;
1379
 
  end;
1380
 
end;
1381
 
 
1382
 
procedure TDOMAttr.SetNodeValue(const AValue: DOMString);
1383
 
var
1384
 
  tn: TDOMText;
1385
 
begin
1386
 
  FSpecified := True;
1387
 
  tn := TDOMText.Create(FOwnerDocument);
1388
 
  tn.FNodeValue := AValue;
1389
 
  if Assigned(FFirstChild) then
1390
 
    ReplaceChild(tn, FFirstChild)
1391
 
  else
1392
 
    AppendChild(tn);
1393
 
end;
1394
 
 
1395
 
 
1396
 
// -------------------------------------------------------
1397
 
//   Element
1398
 
// -------------------------------------------------------
1399
 
 
1400
 
constructor TDOMElement.Create(AOwner: TDOMDocument);
1401
 
begin
1402
 
  FNodeType := ELEMENT_NODE;
1403
 
  inherited Create(AOwner);
1404
 
end;
1405
 
 
1406
 
destructor TDOMElement.Destroy;
1407
 
var
1408
 
  i: Integer;
1409
 
begin
1410
 
  {As the attributes are _not_ children of the element node, we have to free
1411
 
   them manually here:}
1412
 
  if FAttributes<>nil then begin
1413
 
    for i := 0 to FAttributes.Count - 1 do
1414
 
      FAttributes[i].Free;
1415
 
    FAttributes.Free;
1416
 
    FAttributes:=nil;
1417
 
  end;
1418
 
  inherited Destroy;
1419
 
end;
1420
 
 
1421
 
function TDOMElement.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1422
 
var
1423
 
  i: Integer;
1424
 
begin
1425
 
  Result := TDOMElement.Create(ACloneOwner);
1426
 
  Result.FNodeName := FNodeName;
1427
 
  if FAttributes<>nil then begin
1428
 
    TDOMElement(Result).GetAttributes;
1429
 
    for i := 0 to FAttributes.Count - 1 do
1430
 
      TDOMElement(Result).FAttributes.Add(FAttributes[i].CloneNode(True, ACloneOwner));
1431
 
  end;
1432
 
  if deep then
1433
 
    CloneChildren(Result, ACloneOwner);
1434
 
end;
1435
 
 
1436
 
function TDOMElement.GetAttributes: TDOMNamedNodeMap;
1437
 
begin
1438
 
  if FAttributes=nil then
1439
 
    FAttributes := TDOMNamedNodeMap.Create(FOwnerDocument);
1440
 
  Result := FAttributes;
1441
 
end;
1442
 
 
1443
 
function TDOMElement.GetAttribute(const name: DOMString): DOMString;
1444
 
var
1445
 
  i: Integer;
1446
 
begin
1447
 
  if FAttributes<>nil then begin
1448
 
    for i := 0 to FAttributes.Count - 1 do
1449
 
      if FAttributes[i].NodeName = name then
1450
 
      begin
1451
 
        Result := FAttributes[i].NodeValue;
1452
 
        exit;
1453
 
      end;
1454
 
  end;
1455
 
  SetLength(Result, 0);
1456
 
end;
1457
 
 
1458
 
procedure TDOMElement.SetAttribute(const name, value: DOMString);
1459
 
var
1460
 
  i: Integer;
1461
 
  attr: TDOMAttr;
1462
 
begin
1463
 
  GetAttributes;
1464
 
  for i := 0 to FAttributes.Count - 1 do
1465
 
    if FAttributes[i].NodeName = name then
1466
 
    begin
1467
 
      FAttributes[i].NodeValue := value;
1468
 
      exit;
1469
 
    end;
1470
 
  attr := TDOMAttr.Create(FOwnerDocument);
1471
 
  attr.FNodeName := name;
1472
 
  attr.NodeValue := value;
1473
 
  FAttributes.Add(attr);
1474
 
end;
1475
 
 
1476
 
procedure TDOMElement.RemoveAttribute(const name: DOMString);
1477
 
var
1478
 
  i: Integer;
1479
 
begin
1480
 
  if FAttributes=nil then exit;
1481
 
  for i := 0 to FAttributes.Count - 1 do
1482
 
    if FAttributes[i].NodeName = name then
1483
 
    begin
1484
 
      FAttributes[i].Free;
1485
 
      FAttributes.Delete(i);
1486
 
      exit;
1487
 
    end;
1488
 
end;
1489
 
 
1490
 
function TDOMElement.GetAttributeNode(const name: DOMString): TDOMAttr;
1491
 
var
1492
 
  i: Integer;
1493
 
begin
1494
 
  if FAttributes<>nil then begin
1495
 
    for i := 0 to FAttributes.Count - 1 do
1496
 
      if FAttributes[i].NodeName = name then
1497
 
      begin
1498
 
        Result := TDOMAttr(FAttributes[i]);
1499
 
        exit;
1500
 
      end;
1501
 
  end;
1502
 
  Result := nil;
1503
 
end;
1504
 
 
1505
 
procedure TDOMElement.SetAttributeNode(NewAttr: TDOMAttr);
1506
 
var
1507
 
  i: Integer;
1508
 
begin
1509
 
  if FAttributes=nil then exit;
1510
 
  for i := 0 to FAttributes.Count - 1 do
1511
 
    if FAttributes[i].NodeName = NewAttr.NodeName then
1512
 
    begin
1513
 
      FAttributes[i].Free;
1514
 
      FAttributes[i] := NewAttr;
1515
 
      exit;
1516
 
    end;
1517
 
end;
1518
 
 
1519
 
function TDOMElement.RemoveAttributeNode(OldAttr: TDOMAttr): TDOMAttr;
1520
 
var
1521
 
  i: Integer;
1522
 
  node: TDOMNode;
1523
 
begin
1524
 
  Result:=nil;
1525
 
  if FAttributes=nil then exit;
1526
 
  for i := 0 to FAttributes.Count - 1 do
1527
 
  begin
1528
 
    node := FAttributes[i];
1529
 
    if node = OldAttr then
1530
 
    begin
1531
 
      FAttributes.Delete(i);
1532
 
      Result := TDOMAttr(node);
1533
 
      exit;
1534
 
    end;
1535
 
  end;
1536
 
end;
1537
 
 
1538
 
function TDOMElement.GetElementsByTagName(const name: DOMString): TDOMNodeList;
1539
 
begin
1540
 
  Result := TDOMNodeList.Create(Self, name);
1541
 
end;
1542
 
 
1543
 
function TDOMElement.IsEmpty: Boolean;
1544
 
begin
1545
 
  Result:=(FAttributes=nil) or (FAttributes.Count=0)
1546
 
end;
1547
 
 
1548
 
procedure TDOMElement.Normalize;
1549
 
begin
1550
 
  // !!!: Not implemented
1551
 
end;
1552
 
 
1553
 
 
1554
 
// -------------------------------------------------------
1555
 
//   Text
1556
 
// -------------------------------------------------------
1557
 
 
1558
 
constructor TDOMText.Create(AOwner: TDOMDocument);
1559
 
begin
1560
 
  FNodeType := TEXT_NODE;
1561
 
  FNodeName := '#text';
1562
 
  inherited Create(AOwner);
1563
 
end;
1564
 
 
1565
 
function TDOMText.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1566
 
begin
1567
 
  Result := TDOMText.Create(ACloneOwner);
1568
 
  Result.FNodeValue := FNodeValue;
1569
 
  if deep and (ACloneOwner=nil) then ;
1570
 
end;
1571
 
 
1572
 
function TDOMText.SplitText(offset: LongWord): TDOMText;
1573
 
begin
1574
 
  if longint(offset) > Length then
1575
 
    raise EDOMIndexSize.Create('Text.SplitText');
1576
 
 
1577
 
  Result := TDOMText.Create(FOwnerDocument);
1578
 
  Result.FNodeValue := Copy(FNodeValue, offset + 1, Length);
1579
 
  FNodeValue := Copy(FNodeValue, 1, offset);
1580
 
  FParentNode.InsertBefore(Result, FNextSibling);
1581
 
end;
1582
 
 
1583
 
 
1584
 
// -------------------------------------------------------
1585
 
//   Comment
1586
 
// -------------------------------------------------------
1587
 
 
1588
 
constructor TDOMComment.Create(AOwner: TDOMDocument);
1589
 
begin
1590
 
  FNodeType := COMMENT_NODE;
1591
 
  FNodeName := '#comment';
1592
 
  inherited Create(AOwner);
1593
 
end;
1594
 
 
1595
 
function TDOMComment.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1596
 
begin
1597
 
  Result := TDOMComment.Create(ACloneOwner);
1598
 
  Result.FNodeValue := FNodeValue;
1599
 
  if deep and (ACloneOwner=nil) then ;
1600
 
end;
1601
 
 
1602
 
 
1603
 
// -------------------------------------------------------
1604
 
//   CDATASection
1605
 
// -------------------------------------------------------
1606
 
 
1607
 
constructor TDOMCDATASection.Create(AOwner: TDOMDocument);
1608
 
begin
1609
 
  inherited Create(AOwner);
1610
 
  FNodeType := CDATA_SECTION_NODE;
1611
 
  FNodeName := '#cdata-section';
1612
 
end;
1613
 
 
1614
 
function TDOMCDATASection.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1615
 
begin
1616
 
  Result := TDOMCDATASection.Create(ACloneOwner);
1617
 
  Result.FNodeValue := FNodeValue;
1618
 
  if deep and (ACloneOwner=nil) then ;
1619
 
end;
1620
 
 
1621
 
 
1622
 
// -------------------------------------------------------
1623
 
//   DocumentType
1624
 
// -------------------------------------------------------
1625
 
 
1626
 
constructor TDOMDocumentType.Create(AOwner: TDOMDocument);
1627
 
begin
1628
 
  FNodeType := DOCUMENT_TYPE_NODE;
1629
 
  inherited Create(AOwner);
1630
 
end;
1631
 
 
1632
 
function TDOMDocumentType.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1633
 
begin
1634
 
  Result := TDOMDocumentType.Create(ACloneOwner);
1635
 
  Result.FNodeName := FNodeName;
1636
 
  if deep and (ACloneOwner=nil) then ;
1637
 
end;
1638
 
 
1639
 
 
1640
 
// -------------------------------------------------------
1641
 
//   Notation
1642
 
// -------------------------------------------------------
1643
 
 
1644
 
constructor TDOMNotation.Create(AOwner: TDOMDocument);
1645
 
begin
1646
 
  FNodeType := NOTATION_NODE;
1647
 
  inherited Create(AOwner);
1648
 
end;
1649
 
 
1650
 
function TDOMNotation.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
1651
 
begin
1652
 
  Result := TDOMNotation.Create(ACloneOwner);
1653
 
  Result.FNodeName := FNodeName;
1654
 
  if deep and (ACloneOwner=nil) then ;
1655
 
end;
1656
 
 
1657
 
 
1658
 
// -------------------------------------------------------
1659
 
//   Entity
1660
 
// -------------------------------------------------------
1661
 
 
1662
 
constructor TDOMEntity.Create(AOwner: TDOMDocument);
1663
 
begin
1664
 
  FNodeType := ENTITY_NODE;
1665
 
  inherited Create(AOwner);
1666
 
end;
1667
 
 
1668
 
 
1669
 
// -------------------------------------------------------
1670
 
//   EntityReference
1671
 
// -------------------------------------------------------
1672
 
 
1673
 
constructor TDOMEntityReference.Create(AOwner: TDOMDocument);
1674
 
begin
1675
 
  FNodeType := ENTITY_REFERENCE_NODE;
1676
 
  inherited Create(AOwner);
1677
 
end;
1678
 
 
1679
 
 
1680
 
// -------------------------------------------------------
1681
 
//   ProcessingInstruction
1682
 
// -------------------------------------------------------
1683
 
 
1684
 
constructor TDOMProcessingInstruction.Create(AOwner: TDOMDocument);
1685
 
begin
1686
 
  FNodeType := PROCESSING_INSTRUCTION_NODE;
1687
 
  inherited Create(AOwner);
1688
 
end;
1689
 
 
1690
 
 
1691
 
end.
1692
 
 
1693