source: branches/DirectWeb/UHTMLClasses.pas

Last change on this file was 90, checked in by george, 14 years ago

Přidáno: Knihovny pro práci RSS, generování XML a HTML.

File size: 12.9 KB
Line 
1unit UHTMLClasses;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 UXmlClasses, Classes, SysUtils;
9
10type
11 TStringArray = array of string;
12
13 TDomainAddress = class(TPersistent)
14 private
15 function GetAsString: string;
16 procedure SetAsString(const Value: string);
17 public
18 Levels: array of string;
19 property AsString: string read GetAsString write SetAsString;
20 end;
21
22 TAddrClass = (acA, acB, acC, acD, acE);
23
24 TIpAddress = class(TPersistent)
25 private
26 function GetAddrClass: TAddrClass;
27 function GetAsCardinal: Cardinal;
28 function GetAsString: string;
29 function GetBroadcast: Boolean;
30 procedure SetBroadcast(const Value: Boolean);
31 procedure SetAsCardinal(const Value: Cardinal);
32 procedure SetAsString(const Value: string);
33 public
34 Octets: array[0..3] of Byte;
35 procedure Assign(Source: TPersistent); override;
36 property AsCardinal: Cardinal read GetAsCardinal write SetAsCardinal;
37 property AsString: string read GetAsString write SetAsString;
38 property AddrClass: TAddrClass read GetAddrClass;
39 property Broadcast: Boolean read GetBroadcast write SetBroadcast;
40 end;
41
42 THostAddressState = (asDomainName, asIpAddress);
43 THostAddress = class(TPersistent)
44 private
45 function GetAsString: string;
46 procedure SetAsString(const Value: string);
47 public
48 State: THostAddressState;
49 DomainName: TDomainAddress;
50 IpAddress: TIpAddress;
51 constructor Create;
52 destructor Destroy; override;
53 property AsString: string read GetAsString write SetAsString;
54 end;
55
56 TURL = class(TPersistent)
57 private
58 function GetAsString: string;
59 procedure SetAsString(Value: string);
60 public
61 Scheme: string;
62 UserName: string;
63 Password: string;
64 Host: THostAddress;
65 Port: Word;
66 Path: string;
67 Query: string;
68 Fragment: string;
69 constructor Create;
70 destructor Destroy; override;
71 property AsString: string read GetAsString write SetAsString;
72 end;
73
74 THtmlElement = class
75 private
76 function GetAsXmlElement: TXmlElement; virtual;
77 public
78 Id: string;
79 Name: string;
80 ClassId: string;
81 Style: string;
82 property AsXmlElement: TXmlElement read GetAsXmlElement;
83 end;
84
85 TBlockType = (btNoTag, btBlockLevel, btInline);
86
87 THtmlString = class(THtmlElement)
88 private
89 function GetAsXmlElement: TXmlElement; override;
90 public
91 Text: string;
92 end;
93
94 THtmlBlock = class(THtmlElement)
95 private
96 function GetAsXmlElement: TXmlElement; override;
97 public
98 BlockType: TBlockType;
99 SubItems: TList; // of THtmlElement;
100 constructor Create;
101 destructor Destroy; override;
102 end;
103
104 THtmlLink = class(THtmlElement)
105 private
106 function GetAsXmlElement: TXmlElement; override;
107 public
108 Target: TURL;
109 Content: THtmlElement;
110 constructor Create;
111 destructor Destroy; override;
112 end;
113
114 TSizeUnits = (suPixels, suPercents);
115 THtmlSize = record
116 Width: Integer;
117 Height: Integer;
118 Units: TSizeUnits;
119 end;
120
121 THtmlImage = class(THtmlElement)
122 private
123 function GetAsXmlElement: TXmlElement; override;
124 public
125 Size: THtmlSize;
126 Source: TURL;
127 AlternateText: string;
128 constructor Create;
129 destructor Destroy; override;
130 end;
131
132 THtmlPage = class
133 private
134 function GetAsXmlDocument: TXmlDocument;
135 public
136 Title: string;
137 Charset: string;
138 Body: THtmlBlock;
139 property AsXmlDocument: TXmlDocument read GetAsXmlDocument;
140 constructor Create;
141 destructor Destroy; override;
142 end;
143
144function Explode(Separator: Char; Source: string): TStringArray;
145
146implementation
147
148function Explode(Separator: Char; Source: string): TStringArray;
149begin
150 SetLength(Result, 0);
151 while Pos(Separator, Source) > 0 do begin
152 SetLength(Result, Length(Result) + 1);
153 Result[High(Result)] := Copy(Source, 1, Pos(Separator, Source) - 1);
154 Delete(Source, 1, Length(Result[High(Result)]) + 1);
155 end;
156 SetLength(Result, Length(Result) + 1);
157 Result[High(Result)] := Source;
158end;
159
160function LeftCutString(var Source, Output: string; Delimiter: string; Allowed: string = ''): Boolean;
161var
162 I, J: Integer;
163 Matched: Boolean;
164begin
165 I := 1;
166 Matched := True;
167 while (I < Length(Source)) and Matched do begin
168 Matched := False;
169 if (Source[I] >= 'A') and (Source[I] <= 'Z') then Matched := True;
170 if (Source[I] >= 'a') and (Source[I] <= 'z') then Matched := True;
171 if (Source[I] >= '0') and (Source[I] <= '9') then Matched := True;
172 for J := 1 to Length(Allowed) do
173 if Source[I] = Allowed[J] then Matched := True;
174 if Matched then Inc(I);
175 end;
176 if (Delimiter = Copy(Source, I, Length(Delimiter))) or (I = Length(Source)) then begin
177 Output := Copy(Source, 1, I-1);
178 Delete(Source, 1, Length(Output) + Length(Delimiter));
179 Result := True;
180 end else begin
181 Output := '';
182 Result := False;
183 end;
184end;
185
186function RightCutString(var Source, Output: string; Delimiter: string; Allowed: string = ''): Boolean;
187var
188 I, J: Integer;
189 Matched: Boolean;
190begin
191 I := Length(Source);
192 Matched := True;
193 while (I > 0) and Matched do begin
194 Matched := False;
195 if (Source[I] >= 'A') and (Source[I] <= 'Z') then Matched := True;
196 if (Source[I] >= 'a') and (Source[I] <= 'z') then Matched := True;
197 if (Source[I] >= '0') and (Source[I] <= '9') then Matched := True;
198 for J := 1 to Length(Allowed) do
199 if Source[I] = Allowed[J] then Matched := True;
200 if Matched then Dec(I);
201 end;
202 if (Delimiter = Copy(Source, I - Length(Delimiter) + 1, Length(Delimiter))) or (I = 0) then begin
203 Output := Copy(Source, I+1, Length(Source) - I);
204 Delete(Source, I, Length(Output) + Length(Delimiter));
205 Result := True;
206 end else begin
207 Output := '';
208 Result := False;
209 end;
210end;
211
212{ THtmlPage }
213
214constructor THtmlPage.Create;
215begin
216 Body := THtmlBlock.Create;
217end;
218
219destructor THtmlPage.Destroy;
220begin
221 Body.Free;
222 inherited;
223end;
224
225function THtmlPage.GetAsXmlDocument: TXmlDocument;
226begin
227 Result := TXmlDocument.Create;
228 with Result, Content do begin
229 Formated := True;
230 TagName := 'html';
231 with TXmlTag(SubElements[SubElements.Add(TXmlTag.Create)]) do begin
232 TagName := 'head';
233 with TXmlTag(SubElements[SubElements.Add(TXmlTag.Create)]) do begin
234 TagName := 'title';
235 with TXmlString(SubElements[SubElements.Add(TXmlString.Create)]) do begin
236 Text := Title;
237 end;
238 end;
239 with TXmlTag(SubElements[SubElements.Add(TXmlTag.Create)]) do begin
240 TagName := 'meta';
241 Attributes.AddNameValue('http-equiv', 'Content-Language');
242 Attributes.AddNameValue('content', 'cs');
243 end;
244 with TXmlTag(SubElements[SubElements.Add(TXmlTag.Create)]) do begin
245 TagName := 'meta';
246 Attributes.AddNameValue('http-equiv', 'Content-Type');
247 Attributes.AddNameValue('content', 'text/html; charset=' + Charset);
248 end;
249 end;
250 with TXmlTag(SubElements[SubElements.Add(TXmlTag.Create)]) do begin
251 TagName := 'body';
252 SubElements.Add(Body.AsXmlElement);
253
254
255 end;
256 end;
257end;
258
259{ THtmlBlock }
260
261constructor THtmlBlock.Create;
262begin
263 SubItems := TList.Create;
264end;
265
266destructor THtmlBlock.Destroy;
267var
268 I: Integer;
269begin
270 for I := 0 to SubItems.Count - 1 do THtmlElement(SubItems[I]).Free;
271 SubItems.Free;
272 inherited;
273end;
274
275function THtmlBlock.GetAsXmlElement: TXmlElement;
276var
277 I: Integer;
278begin
279 Result := TXmlTag.Create;
280 with TXmlTag(Result) do begin
281 case BlockType of
282 btBlockLevel: TagName := 'div';
283 btInline: TagName := 'span';
284 btNoTag: TagName := '';
285 end;
286 for I := 0 to SubItems.Count - 1 do
287 SubElements.Add(THtmlElement(SubItems[I]).AsXmlElement);
288 end;
289end;
290
291{ THtmlElement }
292
293function THtmlElement.GetAsXmlElement: TXmlElement;
294begin
295
296end;
297
298{ TIpAddress }
299
300procedure TIpAddress.Assign(Source: TPersistent);
301var
302 I: Integer;
303begin
304 if Assigned(Source) then begin
305 if Source is TIpAddress then begin
306 for I := 0 to High(Octets) do
307 Octets[I] := TIpAddress(Source).Octets[I];
308 end else inherited;
309 end else inherited;
310end;
311
312function TIpAddress.GetAddrClass: TAddrClass;
313begin
314 if (Octets[3] and $80) = 0 then Result := acA
315 else begin
316 if (Octets[3] and $40) = 0 then Result := acB
317 else begin
318 if (Octets[3] and $20) = 0 then Result := acC
319 else begin
320 if (Octets[3] and $10) = 0 then Result := acD
321 else Result := acE;
322 end;
323 end;
324 end;
325end;
326
327function TIpAddress.GetAsCardinal: Cardinal;
328begin
329 Result := Octets[0] or (Octets[1] shl 8) or (Octets[2] shl 16) or (Octets[3] shl 24);
330end;
331
332function TIpAddress.GetAsString: string;
333begin
334 Result := IntToStr(Octets[3]) + '.' + IntToStr(Octets[2]) + '.' +
335 IntToStr(Octets[1]) + '.' + IntToStr(Octets[0]);
336end;
337
338function TIpAddress.GetBroadcast: Boolean;
339begin
340 Result := AsCardinal = High(Cardinal);
341end;
342
343procedure TIpAddress.SetAsCardinal(const Value: Cardinal);
344begin
345 Octets[0] := Byte(Value);
346 Octets[1] := Byte(Value shr 8);
347 Octets[2] := Byte(Value shr 16);
348 Octets[3] := Byte(Value shr 24);
349end;
350
351procedure TIpAddress.SetAsString(const Value: string);
352var
353 Parts: TStringArray;
354begin
355 Parts := Explode('.', Value);
356 try
357// if Length(Parts) = 4 then begin
358 Octets[0] := StrToInt(Parts[3]);
359 Octets[1] := StrToInt(Parts[2]);
360 Octets[2] := StrToInt(Parts[1]);
361 Octets[3] := StrToInt(Parts[0]);
362// end else raise EConvertError.Create('String to IP address conversion error');
363 except
364 raise EConvertError.Create('String to IP address conversion error');
365 end;
366end;
367
368procedure TIpAddress.SetBroadcast(const Value: Boolean);
369begin
370 AsCardinal := High(Cardinal);
371end;
372
373constructor TURL.Create;
374begin
375 Host := THostAddress.Create;
376end;
377
378destructor TURL.Destroy;
379begin
380 Host.Free;
381 inherited;
382end;
383
384function TURL.GetAsString: string;
385begin
386 Result := '';
387 if Scheme <> '' then Result := Scheme + '://';
388 if UserName <> '' then begin
389 Result := Result + UserName;
390 if UserName <> '' then Result := Result + ':' + Password;
391 Result := Result + '@';
392 end;
393 if Host.AsString <> '' then Result := Result + Host.AsString;
394 if Port <> 0 then Result := Result + ':' + IntToStr(Port);
395 if Path <> '' then Result := Result + Path;
396 if Query <> '' then Result := Result + '?' + Query;
397 if Fragment <> '' then Result := Result + '#' + Fragment;
398end;
399
400procedure TURL.SetAsString(Value: string);
401var
402 HostAddr: string;
403 HostPort: string;
404begin
405 LeftCutString(Value, Scheme, '://');
406 if LeftCutString(Value, UserName, ':') then LeftCutString(Value, Password, '@')
407 else LeftCutString(Value, UserName, '@');
408 RightCutString(Value, Fragment, '#');
409 RightCutString(Value, Query, '?', '=&');
410 if LeftCutString(Value, HostAddr, ':', '.') then begin
411 LeftCutString(Value, HostPort, '');
412 Port := StrToInt(HostPort);
413 end else LeftCutString(Value, HostAddr, '', '.');
414 Host.AsString := HostAddr;
415 LeftCutString(Value, Path, '', '/.');
416end;
417
418
419{ TDomainAddress }
420
421function TDomainAddress.GetAsString: string;
422var
423 I: Integer;
424begin
425 Result := '';
426 for I := High(Levels) downto 0 do Result := Result + '.' + Levels[I];
427 Delete(Result, 1, 1);
428end;
429
430procedure TDomainAddress.SetAsString(const Value: string);
431var
432 StrArray: TStringArray;
433 I: Integer;
434begin
435 StrArray := Explode('.', Value);
436 SetLength(Levels, Length(StrArray));
437 for I := 0 to High(StrArray) do Levels[High(StrArray) - I] := StrArray[I];
438end;
439
440{ THtmlLink }
441
442constructor THtmlLink.Create;
443begin
444 Target := TURL.Create;
445end;
446
447destructor THtmlLink.Destroy;
448begin
449 Target.Free;
450 inherited;
451end;
452
453function THtmlLink.GetAsXmlElement: TXmlElement;
454begin
455 Result := TXmlTag.Create;
456 with TXmlTag(Result) do begin
457 TagName := 'a';
458 Attributes.Add('href='+Target.AsString);
459 if Assigned(Content) then SubElements.Add(Content.AsXmlElement);
460 end;
461end;
462
463{ THtmlString }
464
465function THtmlString.GetAsXmlElement: TXmlElement;
466begin
467 Result := TXmlString.Create;
468 TXmlString(Result).Text := Text;
469end;
470
471{ THostAddress }
472
473constructor THostAddress.Create;
474begin
475 DomainName := TDomainAddress.Create;
476 IpAddress := TIpAddress.Create;
477 State := asDomainName;
478 DomainName.AsString := 'localhost';
479end;
480
481destructor THostAddress.Destroy;
482begin
483 DomainName.Free;
484 IpAddress.Free;
485 inherited;
486end;
487
488function THostAddress.GetAsString: string;
489begin
490 case State of
491 asDomainName: Result := DomainName.AsString;
492 asIpAddress: Result := IpAddress.AsString;
493 end;
494end;
495
496procedure THostAddress.SetAsString(const Value: string);
497begin
498 State := asIpAddress;
499 try
500 IpAddress.AsString := Value;
501 except
502 on EConvertError do State := asDomainName;
503 end;
504 if State = asDomainName then DomainName.AsString := Value;
505end;
506
507{ THtmlImage }
508
509constructor THtmlImage.Create;
510begin
511 Source := TURL.Create;
512end;
513
514destructor THtmlImage.Destroy;
515begin
516 Source.Free;
517 inherited;
518end;
519
520function THtmlImage.GetAsXmlElement: TXmlElement;
521begin
522 Result := TXmlTag.Create;
523 with TXmlTag(Result) do begin
524 TagName := 'img';
525 Attributes.AddNameValue('src', Source.AsString);
526 Attributes.AddNameValue('width', IntToStr(Size.Width));
527 Attributes.AddNameValue('height', IntToStr(Size.Height));
528 Attributes.AddNameValue('alt', AlternateText);
529 end;
530end;
531
532end.
Note: See TracBrowser for help on using the repository browser.