whtmlscn.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 2000 by Berczi Gabor
  4. HTML scanner objects
  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. unit WHTMLScn;
  12. interface
  13. uses Objects,
  14. WHTML;
  15. const
  16. HTMLIndexMagicNo = ord('H')+ord('H') shl 8+ord('I') shl 16+ord('X') shl 24;
  17. HTMLIndexVersion = 2;
  18. type
  19. PHTMLLinkScanner = ^THTMLLinkScanner;
  20. PHTMLLinkScanDocument = ^THTMLLinkScanDocument;
  21. TCustomHTMLLinkScanner = object(THTMLParser)
  22. function DocAddTextChar(C: char): boolean; virtual;
  23. procedure DocAnchor(Entered: boolean); virtual;
  24. public
  25. {a}function CheckURL(const URL: string): boolean; virtual;
  26. {a}function CheckText(const Text: string): boolean; virtual;
  27. {a}procedure AddLink(const LinkText, LinkURL: string); virtual;
  28. {a}function GetDocumentBaseURL: string; virtual;
  29. private
  30. CurLinkText: string;
  31. CurURL: string;
  32. CurName: string;
  33. CurDoc: string;
  34. InAnchor,InNameAnchor: boolean;
  35. LastSynonym: PHTMLLinkScanDocument;
  36. end;
  37. THTMLLinkScanDocument = object(TObject)
  38. constructor Init(const ADocName: string);
  39. function GetName: string;
  40. function GetUniqueName: string;
  41. function GetAliasCount: sw_integer;
  42. function GetAlias(Index: sw_integer): string;
  43. procedure AddAlias(const Alias: string);
  44. constructor Load(var S: TStream);
  45. procedure Store(var S: TStream);
  46. destructor Done; virtual;
  47. private
  48. DocName: PString;
  49. Synonym: PHTMLLinkScanDocument;
  50. Aliases: PStringCollection;
  51. end;
  52. PHTMLLinkScanDocumentCollection = ^THTMLLinkScanDocumentCollection;
  53. THTMLLinkScanDocumentCollection = object(TSortedCollection)
  54. constructor Init(AScanner: PHTMLLinkScanner; ALimit, ADelta: Integer);
  55. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  56. function At(Index: sw_Integer): PHTMLLinkScanDocument;
  57. function SearchDocument(const DocName: string): PHTMLLinkScanDocument;
  58. procedure MoveAliasesToSynonym;
  59. private
  60. Scanner: PHTMLLinkScanner;
  61. end;
  62. THTMLLinkScanner = object(TCustomHTMLLinkScanner)
  63. constructor Init(const ABaseDir: string);
  64. procedure SetBaseDir(const ABaseDir: string);
  65. function GetDocumentCount: sw_integer;
  66. function GetDocumentURL(DocIndex: sw_integer): string;
  67. function GetUniqueDocumentURL(DocIndex: sw_integer): string;
  68. function GetDocumentAliasCount(DocIndex: sw_integer): sw_integer;
  69. function GetDocumentAlias(DocIndex, AliasIndex: sw_integer): string;
  70. constructor LoadDocuments(var S: TStream);
  71. procedure StoreDocuments(var S: TStream);
  72. destructor Done; virtual;
  73. public
  74. procedure AddLink(const LinkText, LinkURL: string); virtual;
  75. private
  76. Documents: PHTMLLinkScanDocumentCollection;
  77. BaseDir: PString;
  78. function ExpandChildURL(const S: string): string;
  79. function NormalizeChildURL(const S: string): string;
  80. end;
  81. THTMLLinkScanState = (ssScheduled,ssProcessing,ssScanned);
  82. PHTMLLinkScanFile = ^THTMLLinkScanFile;
  83. THTMLLinkScanFile = object(TObject)
  84. constructor Init(const ADocumentURL: string);
  85. function GetDocumentURL: string;
  86. destructor Done; virtual;
  87. private
  88. DocumentURL : PString;
  89. public
  90. State : THTMLLinkScanState;
  91. end;
  92. PHTMLLinkScanFileCollection = ^THTMLLinkScanFileCollection;
  93. THTMLLinkScanFileCollection = object(TSortedCollection)
  94. function At(Index: sw_Integer): PHTMLLinkScanFile;
  95. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  96. function SearchFile(const DocURL: string): PHTMLLinkScanFile;
  97. function FindFileWithState(AState: THTMLLinkScanState): PHTMLLinkScanFile;
  98. end;
  99. THTMLLinkScanOption = (soSubDocsOnly);
  100. THTMLLinkScanOptions = set of THTMLLinkScanOption;
  101. THTMLFileLinkScanner = object(THTMLLinkScanner)
  102. constructor Init(const ABaseDir: string);
  103. procedure ProcessDocument(const DocumentURL: string; AOptions: THTMLLinkScanOptions);
  104. destructor Done; virtual;
  105. public
  106. function GetDocumentBaseURL: string; virtual;
  107. procedure AddLink(const LinkText, LinkURL: string); virtual;
  108. function CheckURL(const URL: string): boolean; virtual;
  109. private
  110. Options: THTMLLinkScanOptions;
  111. BaseURL: string;
  112. CurBaseURL: string;
  113. DocumentFiles: PHTMLLinkScanFileCollection;
  114. procedure ScheduleDoc(const DocumentURL: string);
  115. public
  116. procedure ProcessDoc(Doc: PHTMLLinkScanFile); virtual;
  117. end;
  118. procedure RegisterWHTMLScan;
  119. implementation
  120. uses
  121. WUtils;
  122. const
  123. RHTMLLinkScanDocument: TStreamRec = (
  124. ObjType: 19500;
  125. VmtLink: Ofs(TypeOf(THTMLLinkScanDocument)^);
  126. Load: @THTMLLinkScanDocument.Load;
  127. Store: @THTMLLinkScanDocument.Store
  128. );
  129. const
  130. CurrentHTMLIndexVersion : sw_integer = HTMLIndexVersion;
  131. function TCustomHTMLLinkScanner.DocAddTextChar(C: char): boolean;
  132. var Added: boolean;
  133. begin
  134. Added:=false;
  135. if InAnchor then
  136. begin
  137. CurLinkText:=CurLinkText+C;
  138. Added:=true;
  139. end;
  140. if ord(c)>32 then
  141. LastSynonym:=nil;
  142. DocAddTextChar:=Added;
  143. end;
  144. procedure TCustomHTMLLinkScanner.DocAnchor(Entered: boolean);
  145. begin
  146. if Entered then
  147. begin
  148. CurLinkText:='';
  149. if DocGetTagParam('HREF',CurURL)=false then
  150. CurURL:='';
  151. if not DocGetTagParam('NAME',CurName) then
  152. if not DocGetTagParam('ID',CurName) then
  153. CurName:='';
  154. if CurName<>'' then
  155. begin
  156. InNameAnchor:=true;
  157. If Pos('#',CurName)=0 then
  158. CurName:=CurDoc+'#'+CurName;
  159. CurName:=Trim(CurName);
  160. CurName:=CompleteURL(GetDocumentBaseURL,CurName);
  161. if CurURL='' then
  162. CurURL:=CurName;
  163. end
  164. else
  165. CurName:='';
  166. CurURL:=Trim(CurURL);
  167. CurURL:=CompleteURL(GetDocumentBaseURL,CurURL);
  168. end
  169. else
  170. begin
  171. CurLinkText:=Trim(CurLinkText);
  172. if (CurName='') and CheckURL(CurURL) and CheckText(CurLinkText) and
  173. not DisableCrossIndexing then
  174. begin
  175. AddLink(CurLinkText,CurURL);
  176. {$ifdef DEBUG}
  177. DebugMessage('',' Adding ScanLink "'+CurLinkText+'" to "'+
  178. CurURL+'"',1,1);
  179. {$endif DEBUG}
  180. end;
  181. if InNameAnchor and CheckURL(CurName) and CheckText(CurLinkText) then
  182. begin
  183. AddLink(CurLinkText,CurName);
  184. {$ifdef DEBUG}
  185. DebugMessage('',' Adding ScanName '+CurLinkText+' to '+CurName,1,1);
  186. {$endif DEBUG}
  187. end;
  188. InNameAnchor:=false;
  189. end;
  190. InAnchor:=Entered;
  191. end;
  192. function TCustomHTMLLinkScanner.GetDocumentBaseURL: string;
  193. begin
  194. { Abstract }
  195. GetDocumentBaseURL:='';
  196. end;
  197. function TCustomHTMLLinkScanner.CheckURL(const URL: string): boolean;
  198. begin
  199. { Abstract }
  200. CheckURL:=true;
  201. end;
  202. function TCustomHTMLLinkScanner.CheckText(const Text: string): boolean;
  203. begin
  204. { Abstract }
  205. CheckText:=true;
  206. end;
  207. procedure TCustomHTMLLinkScanner.AddLink(const LinkText, LinkURL: string);
  208. begin
  209. { Abstract }
  210. end;
  211. constructor THTMLLinkScanDocument.Init(const ADocName: string);
  212. begin
  213. inherited Init;
  214. SetStr(DocName,ADocName);
  215. New(Aliases, Init(10,10));
  216. Synonym:=nil;
  217. end;
  218. function THTMLLinkScanDocument.GetName: string;
  219. begin
  220. GetName:=GetStr(DocName);
  221. end;
  222. function THTMLLinkScanDocument.GetUniqueName: string;
  223. var
  224. PD: PHTMLLinkScanDocument;
  225. begin
  226. PD:=@Self;
  227. while assigned(PD^.synonym) do
  228. PD:=PD^.Synonym;
  229. GetUniqueName:=GetStr(PD^.DocName);
  230. end;
  231. function THTMLLinkScanDocument.GetAliasCount: sw_integer;
  232. begin
  233. GetAliasCount:=Aliases^.Count;
  234. end;
  235. function THTMLLinkScanDocument.GetAlias(Index: sw_integer): string;
  236. begin
  237. GetAlias:=GetStr(Aliases^.At(Index));
  238. end;
  239. procedure THTMLLinkScanDocument.AddAlias(const Alias: string);
  240. begin
  241. Aliases^.Insert(NewStr(Alias));
  242. end;
  243. constructor THTMLLinkScanDocument.Load(var S: TStream);
  244. var
  245. i: sw_integer;
  246. begin
  247. inherited Init;
  248. DocName:=S.ReadStr;
  249. if assigned(DocName) then
  250. for i:=1 to Length(DocName^) do
  251. if (DocName^[i]='\') or (DocName^[i]='/') then
  252. DocName^[i]:=DirSep;
  253. New(Aliases, Load(S));
  254. end;
  255. procedure THTMLLinkScanDocument.Store(var S: TStream);
  256. begin
  257. S.WriteStr(DocName);
  258. Aliases^.Store(S);
  259. end;
  260. destructor THTMLLinkScanDocument.Done;
  261. begin
  262. inherited Done;
  263. if Assigned(Aliases) then Dispose(Aliases, Done); Aliases:=nil;
  264. if Assigned(DocName) then DisposeStr(DocName); DocName:=nil;
  265. end;
  266. constructor THTMLLinkScanDocumentCollection.Init(AScanner: PHTMLLinkScanner; ALimit, ADelta: Integer);
  267. begin
  268. inherited Init(ALimit,ADelta);
  269. Scanner:=AScanner;
  270. end;
  271. function THTMLLinkScanDocumentCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  272. var R: sw_integer;
  273. K1: PHTMLLinkScanDocument absolute Key1;
  274. K2: PHTMLLinkScanDocument absolute Key2;
  275. S1,S2: string;
  276. begin
  277. S1:=K1^.GetName; S2:=K2^.GetName;
  278. if Assigned(Scanner) then
  279. begin S1:=Scanner^.ExpandChildURL(S1); S2:=Scanner^.ExpandChildURL(S2); end;
  280. S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
  281. if S1<S2 then R:=-1 else
  282. if S1>S2 then R:= 1 else
  283. R:=0;
  284. Compare:=R;
  285. end;
  286. function THTMLLinkScanDocumentCollection.At(Index: sw_Integer): PHTMLLinkScanDocument;
  287. begin
  288. At:=inherited At(Index);
  289. end;
  290. function THTMLLinkScanDocumentCollection.SearchDocument(const DocName: string): PHTMLLinkScanDocument;
  291. var D,P: PHTMLLinkScanDocument;
  292. Index: sw_integer;
  293. begin
  294. New(D, Init(DocName));
  295. if Search(D, Index)=false then P:=nil else
  296. P:=At(Index);
  297. Dispose(D, Done);
  298. SearchDocument:=P;
  299. end;
  300. procedure THTMLLinkScanDocumentCollection.MoveAliasesToSynonym;
  301. procedure MoveAliases(P: PHTMLLinkScanDocument);
  302. var
  303. PD: PHTMLLinkScanDocument;
  304. i: sw_integer;
  305. begin
  306. if not assigned(P^.synonym) then
  307. exit;
  308. PD:=P;
  309. while assigned(PD^.synonym) do
  310. PD:=PD^.Synonym;
  311. For i:=P^.GetAliasCount-1 downto 0 do
  312. begin
  313. PD^.AddAlias(P^.GetAlias(i));
  314. P^.Aliases^.AtFree(i);
  315. end;
  316. end;
  317. begin
  318. ForEach(@MoveAliases);
  319. end;
  320. constructor THTMLLinkScanner.Init(const ABaseDir: string);
  321. begin
  322. inherited Init;
  323. New(Documents, Init(@Self,50,100));
  324. SetBaseDir(ABaseDir);
  325. end;
  326. procedure THTMLLinkScanner.SetBaseDir(const ABaseDir: string);
  327. begin
  328. if Assigned(BaseDir) then DisposeStr(BaseDir);
  329. BaseDir:=NewStr(CompleteDir(ABaseDir));
  330. end;
  331. function THTMLLinkScanner.GetDocumentCount: sw_integer;
  332. begin
  333. GetDocumentCount:=Documents^.Count;
  334. end;
  335. function THTMLLinkScanner.ExpandChildURL(const S: string): string;
  336. begin
  337. ExpandChildURL:=CompleteURL(GetStr(BaseDir),S);
  338. end;
  339. function THTMLLinkScanner.NormalizeChildURL(const S: string): string;
  340. var URL: string;
  341. begin
  342. URL:=S;
  343. if GetStr(BaseDir)<>'' then
  344. if copy(UpcaseStr(S),1,length(GetStr(BaseDir)))=UpcaseStr(GetStr(BaseDir)) then
  345. URL:=copy(S,length(GetStr(BaseDir))+1,length(S));
  346. NormalizeChildURL:=URL;
  347. end;
  348. function THTMLLinkScanner.GetDocumentURL(DocIndex: sw_integer): string;
  349. begin
  350. GetDocumentURL:=ExpandChildURL(Documents^.At(DocIndex)^.GetName);
  351. end;
  352. function THTMLLinkScanner.GetUniqueDocumentURL(DocIndex: sw_integer): string;
  353. begin
  354. GetUniqueDocumentURL:=ExpandChildURL(Documents^.At(DocIndex)^.GetUniqueName);
  355. end;
  356. function THTMLLinkScanner.GetDocumentAliasCount(DocIndex: sw_integer): sw_integer;
  357. begin
  358. GetDocumentAliasCount:=Documents^.At(DocIndex)^.GetAliasCount;
  359. end;
  360. function THTMLLinkScanner.GetDocumentAlias(DocIndex, AliasIndex: sw_integer): string;
  361. begin
  362. GetDocumentAlias:=Documents^.At(DocIndex)^.GetAlias(AliasIndex);
  363. end;
  364. procedure THTMLLinkScanner.AddLink(const LinkText, LinkURL: string);
  365. var D: PHTMLLinkScanDocument;
  366. DoInsert: boolean;
  367. int: sw_integer;
  368. Text: string;
  369. error: word;
  370. begin
  371. D:=Documents^.SearchDocument(LinkURL);
  372. if D=nil then
  373. begin
  374. New(D, Init(NormalizeChildURL(LinkURL)));
  375. Documents^.Insert(D);
  376. end;
  377. If assigned(LastSynonym) then
  378. LastSynonym^.Synonym:=D;
  379. DoInsert:=true;
  380. If (length(LinkText)=0) or (Pos(',',LinkText)=1) then
  381. DoInsert:=false;
  382. Val(LinkText,int,error);
  383. If (Error>1) and (LinkText[Error]=' ') then
  384. Text:=Trim(Copy(LinkText,error+1,length(LinkText)))
  385. else
  386. Text:=LinkText;
  387. IF DoInsert then
  388. D^.AddAlias(Text);
  389. If InNameAnchor then
  390. LastSynonym:=D;
  391. end;
  392. constructor THTMLLinkScanner.LoadDocuments(var S: TStream);
  393. var P,L: longint;
  394. OK: boolean;
  395. PS: PString;
  396. begin
  397. OK:=false;
  398. P:=S.GetPos;
  399. S.Read(L,sizeof(L));
  400. if (S.Status=stOK) and (L=HTMLIndexMagicNo) then
  401. begin
  402. S.Read(L,sizeof(L));
  403. CurrentHTMLIndexVersion:=L;
  404. OK:=(S.Status=stOK);
  405. end;
  406. if not OK then
  407. begin
  408. S.Reset;
  409. S.Seek(P);
  410. end
  411. else
  412. BaseDir:=S.ReadStr;
  413. New(Documents, Load(S));
  414. if not Assigned(Documents) then
  415. Fail;
  416. Documents^.MoveAliasesToSynonym;
  417. CurrentHTMLIndexVersion:=HTMLIndexVersion;
  418. end;
  419. procedure THTMLLinkScanner.StoreDocuments(var S: TStream);
  420. var L: longint;
  421. begin
  422. L:=HTMLIndexMagicNo;
  423. S.Write(L,sizeof(L));
  424. L:=HTMLIndexVersion;
  425. CurrentHTMLIndexVersion:=L;
  426. S.Write(L,sizeof(L));
  427. S.WriteStr(BaseDir);
  428. Documents^.MoveAliasesToSynonym;
  429. Documents^.Store(S);
  430. end;
  431. destructor THTMLLinkScanner.Done;
  432. begin
  433. inherited Done;
  434. if Assigned(Documents) then Dispose(Documents, Done); Documents:=nil;
  435. if Assigned(BaseDir) then DisposeStr(BaseDir); BaseDir:=nil;
  436. end;
  437. constructor THTMLLinkScanFile.Init(const ADocumentURL: string);
  438. begin
  439. inherited Init;
  440. SetStr(DocumentURL,ADocumentURL);
  441. end;
  442. function THTMLLinkScanFile.GetDocumentURL: string;
  443. begin
  444. GetDocumentURL:=GetStr(DocumentURL);
  445. end;
  446. destructor THTMLLinkScanFile.Done;
  447. begin
  448. inherited Done;
  449. if Assigned(DocumentURL) then DisposeStr(DocumentURL); DocumentURL:=nil;
  450. end;
  451. function THTMLLinkScanFileCollection.At(Index: sw_Integer): PHTMLLinkScanFile;
  452. begin
  453. At:=inherited At(Index);
  454. end;
  455. function THTMLLinkScanFileCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  456. var R: integer;
  457. K1: PHTMLLinkScanFile absolute Key1;
  458. K2: PHTMLLinkScanFile absolute Key2;
  459. S1,S2: string;
  460. begin
  461. S1:=UpcaseStr(K1^.GetDocumentURL); S2:=UpcaseStr(K2^.GetDocumentURL);
  462. if S1<S2 then R:=-1 else
  463. if S1>S2 then R:= 1 else
  464. R:=0;
  465. Compare:=R;
  466. end;
  467. function THTMLLinkScanFileCollection.SearchFile(const DocURL: string): PHTMLLinkScanFile;
  468. var P,D: PHTMLLinkScanFile;
  469. Index: sw_integer;
  470. begin
  471. New(D, Init(DocURL));
  472. if Search(D,Index)=false then P:=nil else
  473. P:=At(Index);
  474. Dispose(D, Done);
  475. SearchFile:=P;
  476. end;
  477. function THTMLLinkScanFileCollection.FindFileWithState(AState: THTMLLinkScanState): PHTMLLinkScanFile;
  478. var I: sw_integer;
  479. P,D: PHTMLLinkScanFile;
  480. begin
  481. P:=nil;
  482. for I:=0 to Count-1 do
  483. begin
  484. D:=At(I);
  485. if D^.State=AState then
  486. begin
  487. P:=D;
  488. Break;
  489. end;
  490. end;
  491. FindFileWithState:=P;
  492. end;
  493. constructor THTMLFileLinkScanner.Init(const ABaseDir: string);
  494. begin
  495. inherited Init(ABaseDir);
  496. New(DocumentFiles, Init(50,100));
  497. end;
  498. procedure THTMLFileLinkScanner.ProcessDocument(const DocumentURL: string; AOptions: THTMLLinkScanOptions);
  499. var P: PHTMLLinkScanFile;
  500. begin
  501. CurBaseURL:=''; Options:=AOptions;
  502. ScheduleDoc(DocumentURL);
  503. repeat
  504. P:=DocumentFiles^.FindFileWithState(ssScheduled);
  505. if Assigned(P) then
  506. ProcessDoc(P);
  507. until P=nil;
  508. end;
  509. function THTMLFileLinkScanner.GetDocumentBaseURL: string;
  510. begin
  511. GetDocumentBaseURL:=CurBaseURL;
  512. end;
  513. function THTMLFileLinkScanner.CheckURL(const URL: string): boolean;
  514. var OK: boolean;
  515. begin
  516. if soSubDocsOnly in Options then
  517. OK:=UpcaseStr(copy(URL,1,length(BaseURL)))=UpcaseStr(BaseURL)
  518. else
  519. OK:=true;
  520. CheckURL:=OK;
  521. end;
  522. procedure THTMLFileLinkScanner.AddLink(const LinkText, LinkURL: string);
  523. var D: PHTMLLinkScanFile;
  524. P: sw_integer;
  525. DocURL: string;
  526. begin
  527. P:=Pos('#',LinkURL);
  528. if P=0 then DocURL:=LinkURL else DocURL:=copy(LinkURL,1,P-1);
  529. D:=DocumentFiles^.SearchFile(DocURL);
  530. if Assigned(D)=false then
  531. ScheduleDoc(DocURL);
  532. inherited AddLink(LinkText,LinkURL);
  533. end;
  534. procedure THTMLFileLinkScanner.ProcessDoc(Doc: PHTMLLinkScanFile);
  535. var F: PDOSTextFile;
  536. begin
  537. if Assigned(Doc)=false then Exit;
  538. Doc^.State:=ssProcessing;
  539. CurDoc:=Doc^.GetDocumentURL;
  540. New(F, Init(Doc^.GetDocumentURL));
  541. if Assigned(F) then
  542. begin
  543. CurBaseURL:=CompleteURL(Doc^.GetDocumentURL,'');
  544. Process(F);
  545. Dispose(F, Done);
  546. end
  547. else
  548. begin
  549. {$ifdef DEBUG}
  550. DebugMessage(CurDoc,'file not found',1,1);
  551. {$endif DEBUG}
  552. end;
  553. Doc^.State:=ssScanned;
  554. CurDoc:='';
  555. end;
  556. procedure THTMLFileLinkScanner.ScheduleDoc(const DocumentURL: string);
  557. var D: PHTMLLinkScanFile;
  558. begin
  559. New(D, Init(DocumentURL));
  560. D^.State:=ssScheduled;
  561. DocumentFiles^.Insert(D);
  562. end;
  563. destructor THTMLFileLinkScanner.Done;
  564. begin
  565. inherited Done;
  566. if Assigned(DocumentFiles) then Dispose(DocumentFiles, Done); DocumentFiles:=nil;
  567. end;
  568. procedure RegisterWHTMLScan;
  569. begin
  570. RegisterType(RHTMLLinkScanDocument);
  571. end;
  572. END.