dom.pp 43 KB

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