dom.pp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635
  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. If UseFilter Then
  792. begin
  793. while Assigned(child) do
  794. begin
  795. if (child.nodename=filter) then
  796. begin
  797. if index=0 then
  798. begin
  799. Result := child;
  800. break;
  801. end;
  802. dec(index);
  803. end;
  804. child := child.NextSibling;
  805. end;
  806. end
  807. else
  808. begin
  809. while Assigned(child) do
  810. begin
  811. if index = 0 then
  812. begin
  813. Result := child;
  814. break;
  815. end;
  816. Dec(index);
  817. child := child.NextSibling;
  818. end;
  819. end
  820. end;
  821. // -------------------------------------------------------
  822. // NamedNodeMap
  823. // -------------------------------------------------------
  824. constructor TDOMNamedNodeMap.Create(AOwner: TDOMDocument);
  825. begin
  826. inherited Create;
  827. OwnerDocument := AOwner;
  828. end;
  829. function TDOMNamedNodeMap.GetItem(index: LongWord): TDOMNode;
  830. begin
  831. Result := TDOMNode(Items[index]);
  832. end;
  833. procedure TDOMNamedNodeMap.SetItem(index: LongWord; AItem: TDOMNode);
  834. begin
  835. Items[index] := AItem;
  836. end;
  837. function TDOMNamedNodeMap.GetLength: LongWord;
  838. begin
  839. Result := Count;
  840. end;
  841. function TDOMNamedNodeMap.GetNamedItem(const name: DOMString): TDOMNode;
  842. var
  843. i: Integer;
  844. begin
  845. for i := 0 to Count - 1 do
  846. begin
  847. Result := Item[i];
  848. if Result.NodeName = name then
  849. exit;
  850. end;
  851. Result := nil;
  852. end;
  853. function TDOMNamedNodeMap.SetNamedItem(arg: TDOMNode): TDOMNode;
  854. var
  855. i: Integer;
  856. begin
  857. if arg.FOwnerDocument <> OwnerDocument then
  858. raise EDOMWrongDocument.Create('NamedNodeMap.SetNamedItem');
  859. if arg.NodeType = ATTRIBUTE_NODE then
  860. begin
  861. if Assigned(TDOMAttr(arg).AttrOwner) then
  862. raise EDOMInUseAttribute.Create('NamedNodeMap.SetNamedItem');
  863. TDOMAttr(arg).AttrOwner := Self;
  864. end;
  865. for i := 0 to Count - 1 do
  866. if Item[i].NodeName = arg.NodeName then
  867. begin
  868. Result := Item[i];
  869. Item[i] := arg;
  870. exit;
  871. end;
  872. Add(arg);
  873. Result := nil;
  874. end;
  875. function TDOMNamedNodeMap.RemoveNamedItem(const name: DOMString): TDOMNode;
  876. var
  877. i: Integer;
  878. begin
  879. for i := 0 to Count - 1 do
  880. if Item[i].NodeName = name then
  881. begin
  882. Result := Item[i];
  883. Result.FParentNode := nil;
  884. exit;
  885. end;
  886. raise EDOMNotFound.Create('NamedNodeMap.RemoveNamedItem');
  887. end;
  888. // -------------------------------------------------------
  889. // CharacterData
  890. // -------------------------------------------------------
  891. function TDOMCharacterData.GetLength: LongWord;
  892. begin
  893. Result := system.Length(FNodeValue);
  894. end;
  895. function TDOMCharacterData.SubstringData(offset, count: LongWord): DOMString;
  896. begin
  897. if (offset > Length) then
  898. raise EDOMIndexSize.Create('CharacterData.SubstringData');
  899. Result := Copy(FNodeValue, offset + 1, count);
  900. end;
  901. procedure TDOMCharacterData.AppendData(const arg: DOMString);
  902. begin
  903. FNodeValue := FNodeValue + arg;
  904. end;
  905. procedure TDOMCharacterData.InsertData(offset: LongWord; const arg: DOMString);
  906. begin
  907. if (offset > Length) then
  908. raise EDOMIndexSize.Create('CharacterData.InsertData');
  909. FNodeValue := Copy(FNodeValue, 1, offset) + arg +
  910. Copy(FNodeValue, offset + 1, Length);
  911. end;
  912. procedure TDOMCharacterData.DeleteData(offset, count: LongWord);
  913. begin
  914. if (offset > Length) then
  915. raise EDOMIndexSize.Create('CharacterData.DeleteData');
  916. FNodeValue := Copy(FNodeValue, 1, offset) +
  917. Copy(FNodeValue, offset + count + 1, Length);
  918. end;
  919. procedure TDOMCharacterData.ReplaceData(offset, count: LongWord; const arg: DOMString);
  920. begin
  921. DeleteData(offset, count);
  922. InsertData(offset, arg);
  923. end;
  924. // -------------------------------------------------------
  925. // DocumentFragmet
  926. // -------------------------------------------------------
  927. constructor TDOMDocumentFragment.Create(AOwner: TDOMDocument);
  928. begin
  929. FNodeType := DOCUMENT_FRAGMENT_NODE;
  930. FNodeName := '#document-fragment';
  931. inherited Create(AOwner);
  932. end;
  933. // -------------------------------------------------------
  934. // DOMImplementation
  935. // -------------------------------------------------------
  936. function TDOMImplementation.HasFeature(const feature, version: DOMString):
  937. Boolean;
  938. begin
  939. Result := False;
  940. if (feature='') and (version='') then ;
  941. end;
  942. function TDOMImplementation.CreateDocumentType(const QualifiedName, PublicID,
  943. SystemID: DOMString): TDOMDocumentType;
  944. begin
  945. // !!!: Implement this method (easy to do)
  946. raise EDOMNotSupported.Create('DOMImplementation.CreateDocumentType');
  947. if (QualifiedName='') and (PublicID='') and (SystemID='') then ;
  948. Result:=nil;
  949. end;
  950. function TDOMImplementation.CreateDocument(const NamespaceURI,
  951. QualifiedName: DOMString; doctype: TDOMDocumentType): TDOMDocument;
  952. begin
  953. // !!!: Implement this method (easy to do)
  954. raise EDOMNotSupported.Create('DOMImplementation.CreateDocument');
  955. if (NamespaceURI='') and (QualifiedName='') and (doctype=nil) then ;
  956. Result:=nil;
  957. end;
  958. // -------------------------------------------------------
  959. // Document
  960. // -------------------------------------------------------
  961. constructor TDOMDocument.Create;
  962. begin
  963. FNodeType := DOCUMENT_NODE;
  964. FNodeName := '#document';
  965. inherited Create(nil);
  966. FOwnerDocument := Self;
  967. end;
  968. function TDOMDocument.GetDocumentElement: TDOMElement;
  969. var
  970. node: TDOMNode;
  971. begin
  972. node := FFirstChild;
  973. while Assigned(node) do
  974. begin
  975. if node.FNodeType = ELEMENT_NODE then
  976. begin
  977. Result := TDOMElement(node);
  978. exit;
  979. end;
  980. node := node.NextSibling;
  981. end;
  982. Result := nil;
  983. end;
  984. function TDOMDocument.CreateElement(const tagName: DOMString): TDOMElement;
  985. begin
  986. Result := TDOMElement.Create(Self);
  987. Result.FNodeName := tagName;
  988. end;
  989. function TDOMDocument.CreateDocumentFragment: TDOMDocumentFragment;
  990. begin
  991. Result := TDOMDocumentFragment.Create(Self);
  992. end;
  993. function TDOMDocument.CreateTextNode(const data: DOMString): TDOMText;
  994. begin
  995. Result := TDOMText.Create(Self);
  996. Result.FNodeValue := data;
  997. end;
  998. function TDOMDocument.CreateComment(const data: DOMString): TDOMComment;
  999. begin
  1000. Result := TDOMComment.Create(Self);
  1001. Result.FNodeValue := data;
  1002. end;
  1003. function TDOMDocument.CreateCDATASection(const data: DOMString):
  1004. TDOMCDATASection;
  1005. begin
  1006. raise EDOMNotSupported.Create('DOMDocument.CreateCDATASection');
  1007. if data='' then ;
  1008. Result:=nil;
  1009. end;
  1010. function TDOMDocument.CreateProcessingInstruction(const target,
  1011. data: DOMString): TDOMProcessingInstruction;
  1012. begin
  1013. raise EDOMNotSupported.Create('DOMDocument.CreateProcessingInstruction');
  1014. if (target='') and (data='') then ;
  1015. Result:=nil;
  1016. end;
  1017. function TDOMDocument.CreateAttribute(const name: DOMString): TDOMAttr;
  1018. begin
  1019. Result := TDOMAttr.Create(Self);
  1020. Result.FNodeName := name;
  1021. end;
  1022. function TDOMDocument.CreateEntityReference(const name: DOMString):
  1023. TDOMEntityReference;
  1024. begin
  1025. raise EDOMNotSupported.Create('DOMDocument.CreateEntityReference');
  1026. if name='' then ;
  1027. Result:=nil;
  1028. end;
  1029. function TDOMDocument.CreateEntity(const data: DOMString): TDOMEntity;
  1030. begin
  1031. Result := TDOMEntity.Create(Self);
  1032. Result.FNodeName := data;
  1033. end;
  1034. function TDOMDocument.GetElementsByTagName(const tagname: DOMString): TDOMNodeList;
  1035. begin
  1036. Result := TDOMNodeList.Create(Self, tagname);
  1037. end;
  1038. function TXMLDocument.CreateCDATASection(const data: DOMString):
  1039. TDOMCDATASection;
  1040. begin
  1041. Result := TDOMCDATASection.Create(Self);
  1042. Result.FNodeValue := data;
  1043. end;
  1044. function TXMLDocument.CreateProcessingInstruction(const target,
  1045. data: DOMString): TDOMProcessingInstruction;
  1046. begin
  1047. Result := TDOMProcessingInstruction.Create(Self);
  1048. Result.FNodeName := target;
  1049. Result.FNodeValue := data;
  1050. end;
  1051. function TXMLDocument.CreateEntityReference(const name: DOMString):
  1052. TDOMEntityReference;
  1053. begin
  1054. Result := TDOMEntityReference.Create(Self);
  1055. Result.FNodeName := name;
  1056. end;
  1057. // -------------------------------------------------------
  1058. // Attr
  1059. // -------------------------------------------------------
  1060. constructor TDOMAttr.Create(AOwner: TDOMDocument);
  1061. begin
  1062. FNodeType := ATTRIBUTE_NODE;
  1063. inherited Create(AOwner);
  1064. end;
  1065. function TDOMAttr.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1066. begin
  1067. Result := TDOMAttr.Create(ACloneOwner);
  1068. Result.FNodeName := FNodeName;
  1069. TDOMAttr(Result).FSpecified := FSpecified;
  1070. if deep then
  1071. CloneChildren(Result, ACloneOwner);
  1072. end;
  1073. function TDOMAttr.GetNodeValue: DOMString;
  1074. var
  1075. child: TDOMNode;
  1076. begin
  1077. SetLength(Result, 0);
  1078. if Assigned(FFirstChild) then
  1079. begin
  1080. child := FFirstChild;
  1081. while Assigned(child) do
  1082. begin
  1083. if child.NodeType = ENTITY_REFERENCE_NODE then
  1084. Result := Result + '&' + child.NodeName + ';'
  1085. else
  1086. Result := Result + child.NodeValue;
  1087. child := child.NextSibling;
  1088. end;
  1089. end;
  1090. end;
  1091. procedure TDOMAttr.SetNodeValue(const AValue: DOMString);
  1092. var
  1093. tn: TDOMText;
  1094. begin
  1095. FSpecified := True;
  1096. tn := TDOMText.Create(FOwnerDocument);
  1097. tn.FNodeValue := AValue;
  1098. if Assigned(FFirstChild) then
  1099. ReplaceChild(tn, FFirstChild)
  1100. else
  1101. AppendChild(tn);
  1102. end;
  1103. // -------------------------------------------------------
  1104. // Element
  1105. // -------------------------------------------------------
  1106. constructor TDOMElement.Create(AOwner: TDOMDocument);
  1107. begin
  1108. FNodeType := ELEMENT_NODE;
  1109. inherited Create(AOwner);
  1110. end;
  1111. destructor TDOMElement.Destroy;
  1112. var
  1113. i: Integer;
  1114. begin
  1115. {As the attributes are _not_ childs of the element node, we have to free
  1116. them manually here:}
  1117. if FAttributes<>nil then begin
  1118. for i := 0 to FAttributes.Count - 1 do
  1119. FAttributes[i].Free;
  1120. FAttributes.Free;
  1121. FAttributes:=nil;
  1122. end;
  1123. inherited Destroy;
  1124. end;
  1125. function TDOMElement.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1126. var
  1127. i: Integer;
  1128. begin
  1129. Result := TDOMElement.Create(ACloneOwner);
  1130. Result.FNodeName := FNodeName;
  1131. if FAttributes<>nil then begin
  1132. TDOMElement(Result).GetAttributes;
  1133. for i := 0 to FAttributes.Count - 1 do
  1134. TDOMElement(Result).FAttributes.Add(FAttributes[i].CloneNode(True, ACloneOwner));
  1135. end;
  1136. if deep then
  1137. CloneChildren(Result, ACloneOwner);
  1138. end;
  1139. function TDOMElement.GetAttributes: TDOMNamedNodeMap;
  1140. begin
  1141. if FAttributes=nil then
  1142. FAttributes := TDOMNamedNodeMap.Create(FOwnerDocument);
  1143. Result := FAttributes;
  1144. end;
  1145. function TDOMElement.GetAttribute(const name: DOMString): DOMString;
  1146. var
  1147. i: Integer;
  1148. begin
  1149. if FAttributes<>nil then begin
  1150. for i := 0 to FAttributes.Count - 1 do
  1151. if FAttributes[i].NodeName = name then
  1152. begin
  1153. Result := FAttributes[i].NodeValue;
  1154. exit;
  1155. end;
  1156. end;
  1157. SetLength(Result, 0);
  1158. end;
  1159. procedure TDOMElement.SetAttribute(const name, value: DOMString);
  1160. var
  1161. i: Integer;
  1162. attr: TDOMAttr;
  1163. begin
  1164. GetAttributes;
  1165. for i := 0 to FAttributes.Count - 1 do
  1166. if FAttributes[i].NodeName = name then
  1167. begin
  1168. FAttributes[i].NodeValue := value;
  1169. exit;
  1170. end;
  1171. attr := TDOMAttr.Create(FOwnerDocument);
  1172. attr.FNodeName := name;
  1173. attr.NodeValue := value;
  1174. FAttributes.Add(attr);
  1175. end;
  1176. procedure TDOMElement.RemoveAttribute(const name: DOMString);
  1177. var
  1178. i: Integer;
  1179. begin
  1180. if FAttributes=nil then exit;
  1181. for i := 0 to FAttributes.Count - 1 do
  1182. if FAttributes[i].NodeName = name then
  1183. begin
  1184. FAttributes[i].Free;
  1185. FAttributes.Delete(i);
  1186. exit;
  1187. end;
  1188. end;
  1189. function TDOMElement.GetAttributeNode(const name: DOMString): TDOMAttr;
  1190. var
  1191. i: Integer;
  1192. begin
  1193. if FAttributes<>nil then begin
  1194. for i := 0 to FAttributes.Count - 1 do
  1195. if FAttributes[i].NodeName = name then
  1196. begin
  1197. Result := TDOMAttr(FAttributes[i]);
  1198. exit;
  1199. end;
  1200. end;
  1201. Result := nil;
  1202. end;
  1203. procedure TDOMElement.SetAttributeNode(NewAttr: TDOMAttr);
  1204. var
  1205. i: Integer;
  1206. begin
  1207. if FAttributes=nil then exit;
  1208. for i := 0 to FAttributes.Count - 1 do
  1209. if FAttributes[i].NodeName = NewAttr.NodeName then
  1210. begin
  1211. FAttributes[i].Free;
  1212. FAttributes[i] := NewAttr;
  1213. exit;
  1214. end;
  1215. end;
  1216. function TDOMElement.RemoveAttributeNode(OldAttr: TDOMAttr): TDOMAttr;
  1217. var
  1218. i: Integer;
  1219. node: TDOMNode;
  1220. begin
  1221. Result:=nil;
  1222. if FAttributes=nil then exit;
  1223. for i := 0 to FAttributes.Count - 1 do
  1224. begin
  1225. node := FAttributes[i];
  1226. if node = OldAttr then
  1227. begin
  1228. FAttributes.Delete(i);
  1229. Result := TDOMAttr(node);
  1230. exit;
  1231. end;
  1232. end;
  1233. end;
  1234. function TDOMElement.GetElementsByTagName(const name: DOMString): TDOMNodeList;
  1235. begin
  1236. Result := TDOMNodeList.Create(Self, name);
  1237. end;
  1238. procedure TDOMElement.Normalize;
  1239. begin
  1240. // !!!: Not implemented
  1241. end;
  1242. // -------------------------------------------------------
  1243. // Text
  1244. // -------------------------------------------------------
  1245. constructor TDOMText.Create(AOwner: TDOMDocument);
  1246. begin
  1247. FNodeType := TEXT_NODE;
  1248. FNodeName := '#text';
  1249. inherited Create(AOwner);
  1250. end;
  1251. function TDOMText.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1252. begin
  1253. Result := TDOMText.Create(ACloneOwner);
  1254. Result.FNodeValue := FNodeValue;
  1255. if deep and (ACloneOwner=nil) then ;
  1256. end;
  1257. function TDOMText.SplitText(offset: LongWord): TDOMText;
  1258. begin
  1259. if offset > Length then
  1260. raise EDOMIndexSize.Create('Text.SplitText');
  1261. Result := TDOMText.Create(FOwnerDocument);
  1262. Result.FNodeValue := Copy(FNodeValue, offset + 1, Length);
  1263. FNodeValue := Copy(FNodeValue, 1, offset);
  1264. FParentNode.InsertBefore(Result, FNextSibling);
  1265. end;
  1266. // -------------------------------------------------------
  1267. // Comment
  1268. // -------------------------------------------------------
  1269. constructor TDOMComment.Create(AOwner: TDOMDocument);
  1270. begin
  1271. FNodeType := COMMENT_NODE;
  1272. FNodeName := '#comment';
  1273. inherited Create(AOwner);
  1274. end;
  1275. function TDOMComment.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1276. begin
  1277. Result := TDOMComment.Create(ACloneOwner);
  1278. Result.FNodeValue := FNodeValue;
  1279. if deep and (ACloneOwner=nil) then ;
  1280. end;
  1281. // -------------------------------------------------------
  1282. // CDATASection
  1283. // -------------------------------------------------------
  1284. constructor TDOMCDATASection.Create(AOwner: TDOMDocument);
  1285. begin
  1286. inherited Create(AOwner);
  1287. FNodeType := CDATA_SECTION_NODE;
  1288. FNodeName := '#cdata-section';
  1289. end;
  1290. function TDOMCDATASection.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1291. begin
  1292. Result := TDOMCDATASection.Create(ACloneOwner);
  1293. Result.FNodeValue := FNodeValue;
  1294. if deep and (ACloneOwner=nil) then ;
  1295. end;
  1296. // -------------------------------------------------------
  1297. // DocumentType
  1298. // -------------------------------------------------------
  1299. constructor TDOMDocumentType.Create(AOwner: TDOMDocument);
  1300. begin
  1301. FNodeType := DOCUMENT_TYPE_NODE;
  1302. inherited Create(AOwner);
  1303. end;
  1304. function TDOMDocumentType.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1305. begin
  1306. Result := TDOMDocumentType.Create(ACloneOwner);
  1307. Result.FNodeName := FNodeName;
  1308. if deep and (ACloneOwner=nil) then ;
  1309. end;
  1310. // -------------------------------------------------------
  1311. // Notation
  1312. // -------------------------------------------------------
  1313. constructor TDOMNotation.Create(AOwner: TDOMDocument);
  1314. begin
  1315. FNodeType := NOTATION_NODE;
  1316. inherited Create(AOwner);
  1317. end;
  1318. function TDOMNotation.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
  1319. begin
  1320. Result := TDOMNotation.Create(ACloneOwner);
  1321. Result.FNodeName := FNodeName;
  1322. if deep and (ACloneOwner=nil) then ;
  1323. end;
  1324. // -------------------------------------------------------
  1325. // Entity
  1326. // -------------------------------------------------------
  1327. constructor TDOMEntity.Create(AOwner: TDOMDocument);
  1328. begin
  1329. FNodeType := ENTITY_NODE;
  1330. inherited Create(AOwner);
  1331. end;
  1332. // -------------------------------------------------------
  1333. // EntityReference
  1334. // -------------------------------------------------------
  1335. constructor TDOMEntityReference.Create(AOwner: TDOMDocument);
  1336. begin
  1337. FNodeType := ENTITY_REFERENCE_NODE;
  1338. inherited Create(AOwner);
  1339. end;
  1340. // -------------------------------------------------------
  1341. // ProcessingInstruction
  1342. // -------------------------------------------------------
  1343. constructor TDOMProcessingInstruction.Create(AOwner: TDOMDocument);
  1344. begin
  1345. FNodeType := PROCESSING_INSTRUCTION_NODE;
  1346. inherited Create(AOwner);
  1347. end;
  1348. end.