dom.pp 43 KB

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