+procedure THTMLCreate.SetResPopupText(Hint : TResPopupBrowser; threadItem: TThreadItem; StNum, ToNum: Integer; Title, First: Boolean);
+var
+ i: Integer;
+ tmp: string;
+ FileName: string;
+ Line: Integer;
+
+ wkInt: Integer;
+
+ boardPlugIn : TBoardPlugIn;
+ Html: TStringList;
+ ResLink : TResLinkRec;
+begin
+
+ Html := TStringList.Create;
+ try
+ if StNum > ToNum then begin
+ wkInt := StNum;
+ StNum := ToNum;
+ ToNum := wkInt;
+ end;
+
+ //\8dÅ\91å10\83\8c\83X\82Ü\82Å\95\\8e¦
+ if StNum + MAX_POPUP_RES < ToNum then
+ ToNum := StNum + MAX_POPUP_RES;
+
+ Hint.Title := '';
+ Hint.RawDocument := '';
+ Hint.Thread := nil;
+
+ //\83^\83C\83g\83\8b\95\\8e¦
+ if Title then
+ if ThreadItem <> nil then
+ Hint.Title := ThreadItem.Title;
+
+ if ThreadItem <> nil then begin
+ Hint.Thread := ThreadItem;
+ ResLink.FBbs := ThreadItem.ParentBoard.BBSID;
+ ResLink.FKey := ChangeFileExt(ThreadItem.FileName, '');
+ //if ThreadItem.IsBoardPlugInAvailable then begin
+ if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
+ //===== \83v\83\89\83O\83C\83\93\82É\82æ\82é\95\\8e¦
+ //boardPlugIn := ThreadItem.BoardPlugIn;
+ boardPlugIn := ThreadItem.ParentBoard.BoardPlugIn;
+
+ // \83t\83H\83\93\83g\82â\83T\83C\83Y\82Ì\90Ý\92è
+ // \95¶\8e\9a\83R\81[\83h\82Í\83v\83\89\83O\83C\83\93\82É\94C\82¹\82é
+ for i := StNum to ToNum do begin
+ Line := i;
+ //\82±\82±\82Å\82Q\82¿\82á\82ñ\82Ë\82é\82Ìdat\82Ì\8c`\8e®\82Å\82P\8ds\93Ç\82Ý\8d\9e\82ß\82ê\82Î¥¥¥\81B\81«\93Ç\82ß\82é\82æ\82¤\82É\82È\82Á\82½
+ tmp := boardPlugIn.GetDat( DWORD( threadItem ), i );
+ if (tmp <> '') And ( not GikoSys.FAbon.CheckAbonPopupRes(tmp) And( not GikoSys.FAbon.CheckIndividualAbonList(line))) then begin
+ Html.Add(GetResString(Line-1, tmp, @ResLink));
+ end;
+ end;
+ end else begin
+ for i := StNum to ToNum do begin
+ Line := i;
+ FileName := ThreadItem.FilePath;
+ tmp := GikoSys.ReadThreadFile(FileName, Line);
+ if (tmp <> '') And ( not GikoSys.FAbon.CheckAbonPopupRes(tmp) And( not GikoSys.FAbon.CheckIndividualAbonList(line))) then begin
+ Html.Add(GetResString(Line-1, tmp, @ResLink));
+ end;
+ end;
+ end;
+ if (Html.Count > 0) then begin
+ Hint.RawDocument := '<DL>' + Html.Text + '</DL>';
+ end;
+ end;
+ finally
+ Html.Free;
+ end;
+end;
+
+//\83\8a\83\93\83N\82Ì\95¶\8e\9a\97ñ\82©\82ç\83\8c\83X\83|\83b\83v\83A\83b\83v\97p\82ÌURL\82É\95Ï\8a·\82·\82é
+class function THTMLCreate.GetRespopupURL(AText, AThreadURL : string): string;
+var
+ wkInt: Integer;
+begin
+ Result := '';
+ if Pos('about:blank..', AText) = 1 then begin
+ wkInt := LastDelimiter( '/', AThreadURL );
+ if Pos( '?', Copy( AThreadURL, wkInt, MaxInt ) ) = 0 then begin
+ // Thread.URL \82Í PATH_INFO \93n\82µ
+ Result := Copy( AThreadURL, 1, LastDelimiter( '/', AThreadURL ) );
+ wkInt := LastDelimiter( '/', AText );
+ if Pos( '?', Copy( AText, wkInt, MaxInt ) ) = 0 then
+ // Text \82à PATH_INFO \93n\82µ
+ Result := Result + Copy( AText, LastDelimiter( '/', AText ) + 1, MaxInt )
+ else
+ // Text \82Í QUERY_STRING \93n\82µ
+ Result := Result + Copy( AText, LastDelimiter( '?', AText ) + 1, MaxInt );
+ end else begin
+ // Thread.URL \82Í QUERY_STRING \93n\82µ
+ Result := Copy( AThreadURL, 1, LastDelimiter( '?', AThreadURL ) );
+ wkInt := LastDelimiter( '/', AText );
+ if Pos( '?', Copy( AText, wkInt, MaxInt ) ) = 0 then begin
+ // Text \82Í PATH_INFO \93n\82µ
+ // URL \82É\94Â\82Æ\83L\81[\82ª\91«\82ç\82È\82¢\82Ì\82Å Text \82©\82ç\92¸\91Õ\82·\82é
+ wkInt := LastDelimiter( '/', Copy( AText, 1, wkInt - 1 ) );
+ wkInt := LastDelimiter( '/', Copy( AText, 1, wkInt - 1 ) );
+ Result := Copy( Result, 1, Length( Result ) - 1 ) + Copy( AText, wkInt, MaxInt );
+ end else begin
+ // Text \82à QUERY_STRING \93n\82µ
+ Result := Result + Copy( AText, LastDelimiter( '?', AText ) + 1, MaxInt )
+ end;
+ end;
+ end else if Pos('about:blank/bbs/', AText) = 1 then begin
+ //\82µ\82½\82ç\82ÎJBBS\82Ì\8ed\95Ï\82Ì\8bz\8eû
+ AText := CustomStringReplace(AText, 'about:blank/bbs/', 'about:blank../../bbs/');
+ Result := GetRespopupURL(AText, AThreadURL);
+ end else begin
+ Result := AText;
+ end;
+
+end;
+//\8ew\92è\82µ\82½\83p\83X\82É\83X\83L\83\93\82à\82µ\82\82ÍCSS\82Ì\83t\83@\83C\83\8b\82Ì\83R\83s\81[\82ð\8dì\82é
+class procedure THTMLCreate.SkinorCSSFilesCopy(path: string);
+var
+ tmp, tmpD, tmpF: string;
+ current: string;
+ dirs: TStringList;
+ files: TStringList;
+ i, j: Integer;
+begin
+ if GikoSys.Setting.UseSkin then begin
+ current := ExtractFilePath(GikoSys.GetSkinDir);
+ tmp := GikoSys.Setting.CSSFileName;
+ end else if GikoSys.Setting.UseCSS then begin
+ current := ExtractFilePath(GikoSys.GetStyleSheetDir);
+ tmp := ExtractFilePath(GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName);
+ end else begin
+ Exit;
+ end;
+ dirs := TStringList.Create;
+ try
+ dirs.Add(tmp);
+ if tmp <> current then begin
+ GikoSys.GetDirectoryList(current, '*.*', dirs, true);
+ for i := 0 to dirs.Count - 1 do begin
+ files := TStringList.Create;
+ try
+ files.BeginUpdate;
+ gikoSys.GetFileList(dirs[i], '*.*', files, true);
+ files.EndUpdate;
+ tmpD := CustomStringReplace(dirs[i], GikoSys.GetConfigDir, path);
+ if (AnsiPos(dirs[i], tmp) <> 0) and not (DirectoryExists(tmpD)) then
+ ForceDirectories(tmpD);
+
+ if(dirs[i] = tmp) and (dirs[i] <> current) then begin
+ for j := 0 to files.Count - 1 do begin
+ tmpF := CustomStringReplace(files[j], GikoSys.GetConfigDir, path);
+ if not FileExists(tmpF) then begin
+ CopyFile(PChar(files[j]), PChar(tmpF),True);
+ end;
+ end;
+ end;
+ finally
+ files.Free;
+ end;
+ end;
+ end else begin
+ tmpD := CustomStringReplace(dirs[0], GikoSys.GetConfigDir, path);
+ if not DirectoryExists(tmpD) then
+ ForceDirectories(tmpD);
+ tmpF := CustomStringReplace(GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName
+ , GikoSys.GetConfigDir, path);
+ if not FileExists(tmpF) then begin
+ CopyFile(PChar(GikoSys.GetStyleSheetDir + GikoSys.Setting.CSSFileName)
+ , PChar(tmpF), True);
+ end;
+ end;
+ finally
+ dirs.Free;
+ end;
+end;
+{!
+\brief dat\83t\83@\83C\83\8b\82Ì\88ê\83\89\83C\83\93\82ð\95ª\89ð
+\param Line dat\83t\83@\83C\83\8b\82ð\8d\\90¬\82·\82é 1 \8ds
+\return \83\8c\83X\8fî\95ñ
+}
+class procedure THTMLCreate.DivideStrLine(Line: string; PRes: PResRec);
+const
+ delimiter = '<>';
+var
+ pds, pde : PChar;
+ pss, pse : PChar;
+ ppos : PChar;
+begin
+ //\8cÅ\92è
+ PRes.FType := glt2chNew;
+
+ pss := PChar(Line);
+ pse := pss + Length(Line);
+ pds := PChar(delimiter);
+ pde := pds + Length(delimiter);
+
+ ppos := AnsiStrPosEx(pss, pse, pds, pde);
+ if (ppos = nil) then begin
+ Line := CustomStringReplace(Line, '<>', '<>');
+ Line := CustomStringReplace(Line, ',', '<>');
+ Line := CustomStringReplace(Line, '\81\97\81M', ',');
+ end;
+ //Trim\82µ\82Ä\82Í\82¢\82¯\82È\82¢\8bC\82ª\82·\82é\81@by\82à\82¶\82ã
+ PRes.FName := RemoveToken(Line, delimiter);
+ PRes.FMailTo := RemoveToken(Line, delimiter);
+ PRes.FDateTime := RemoveToken(Line, delimiter);
+ PRes.FBody := RemoveToken(Line, delimiter);
+ //\82Q\82¿\82á\82ñ\82Ë\82é\82Æ\82©\82¾\82Æ\81A\96{\95¶\82Ì\90æ\93ª\82É\82P\82Â\94¼\8ap\8bó\94\92\82ª\93ü\82Á\82Ä\82¢\82é\82Ì\82Å\8dí\8f\9c\82·\82é
+ //\91¼\82Ì\8cf\8e¦\94Â\82Å\81A\83\8c\83X\8e©\91Ì\82Ì\8bó\94\92\82©\82à\82µ\82ê\82È\82¢\82¯\82Ç\82»\82ê\82Í\92ú\82ß\82é
+ PRes.FBody := TrimLeft(PRes.FBody);
+ //\8bó\82¾\82Æ\96â\91è\82ª\8bN\82«\82é\82©\82ç\81A\8bó\94\92\82ð\90Ý\92è\82·\82é
+ if PRes.FBody = '' then
+ PRes.FBody := ' ';
+
+ PRes.FTitle := RemoveToken(Line, delimiter);
+end;
+
+{!
+\brief HTML \82©\82ç\83A\83\93\83J\81[\83^\83O\82ð\8dí\8f\9c
+\param s \8c³\82É\82È\82é HTML
+\return \83A\83\93\83J\81[\83^\83O\82ª\8dí\8f\9c\82³\82ê\82½ HTML
+}
+class function THTMLCreate.DeleteLink(const s: string): string;
+var
+ s1: string;
+ s2: string;
+ idx: Integer;
+ i: Integer;
+begin
+ i := 0;
+ Result := '';
+ while True do begin
+ s1 := GikoSys.GetTokenIndex(s, '<a href="', i);
+ s2 := GikoSys.GetTokenIndex(s, '<a href="', i + 1);
+
+ idx := Pos('">', s1);
+ if idx <> 0 then
+ Delete(s1, 1, idx + 1);
+ idx := Pos('">', s2);
+ if idx <> 0 then
+ Delete(s2, 1, idx + 1);
+
+ Result := Result + s1 + s2;
+
+ if s2 = '' then
+ Break;
+
+ inc(i, 2);
+ end;
+end;
+{
+\brief HTML\89»\82Ì\82½\82ß\82Ì\92u\8a·
+\param s \8c³\82É\82È\82é\95¶\8e\9a\97ñ
+\return HTML\82ÌinnerText\82Æ\82µ\82Ä\82ä\82é\82³\82ê\82é\95¶\8e\9a\97ñ
+}
+class function THTMLCreate.RepHtml(const s: string): string;
+begin
+// s := StringReplace(s, '&', '&', [rfReplaceAll]);
+ Result := s;
+ Result := CustomStringReplace(Result, '<', '<');
+ Result := CustomStringReplace(Result, '>', '>');
+// s := StringReplace(s, ' ', ' ', [rfReplaceAll]); //\8ed\97l\95Ï\8dX\82É\82æ\82è \8eg\97p\95s\89Â
+ Result := CustomStringReplace(Result, '"', '"');
+end;
+{
+\brief \83\8c\83X\83G\83f\83B\83^\82Å\82Ì\83v\83\8c\83r\83\85\81[\97pHTML\8dì\90¬
+\param Title \83X\83\8c\83b\83h\83^\83C\83g\83\8b
+\param No \83\8c\83X\94Ô\8d\86
+\param Mail \83\81\81[\83\8b\97\93
+\param Name \96¼\91O\97\93
+\param Body \96{\95¶
+\return \83v\83\8c\83r\83\85\81[\97pHTML
+}
+class function THTMLCreate.CreatePreviewHTML(
+ const Title: string;
+ const No: string;
+ const Mail: string;
+ const Namae: string;
+ const Body: string
+) : string;
+var
+ posTrip : Integer;
+ tripOrigin : string;
+ NameWithTrip: string;
+ DateTime: string;
+begin
+ Result := '<HTML><HEAD>'#13#10
+ + '<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">'#13#10
+ + '<TITLE>' + title + '</TITLE>'#13#10
+ + '</HEAD>'#13#10
+ + '<BODY text="#000000" bgcolor="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">'#13#10
+ + '<FONT COLOR="#FF0000">' + title + '</FONT>'#13#10
+ + '<DL>'#13#10;
+
+ DateTime := FormatDateTime('yyyy/mm/dd(aaa) hh:nn', Now());
+
+ NameWithTrip := Namae;
+ posTrip := AnsiPos( '#', Namae );
+ if posTrip > 0 then begin
+ tripOrigin := Copy( Namae, posTrip + 1, Length( Namae ) );
+ NameWithTrip := Copy( Namae, 1, posTrip - 1 ) + '</B> \81\9f' +
+ get_2ch_trip( PChar( tripOrigin ) ) + '<B>';
+ end;
+ if Mail = '' then begin
+ Result := Result + '<DT>' + No + ' \81F <FONT color="forestgreen"><B>' + NameWithTrip
+ + '</B></FONT> \81F ' + DateTime+ '<BR><DD>' + Body + '<BR><BR><BR>' + #13#10
+ end else begin
+ Result := Result + '<DT>' + No + ' \81F <A href="mailto:' + Mail + '"><B>' + NameWithTrip
+ + '</B></A> [' + Mail + ']\81F ' + DateTime+ '<BR><DD>' + Body + '<BR><BR><BR>' + #13#10;
+ end;
+ Result := Result + '</BODY></HTML>';
+
+end;
+{
+\brief \95\\8e¦\94Í\88Í\8aO\83\8c\83X\94Ô\8d\86\94»\92è\8f\88\97\9d
+\param item \95\\8e¦\83X\83\8c\83b\83h
+\param index \83\8c\83X\94Ô\8d\86
+\return ture:\95\\8e¦\94Í\88Í\8aO false:\95\\8e¦\94Í\88Í\93à
+}
+function THTMLCreate.isOutsideRange( item: TThreadItem; index: Integer ): Boolean;
+begin
+ Result := False;
+ // \95\\8e¦\94Í\88Í\82ð\8cÀ\92è
+ case GikoSys.ResRange of
+ Ord( grrKoko ):
+ if item.Kokomade > (index + 1) then
+ Result := True;
+ Ord( grrNew ):
+ if item.NewReceive > (index + 1) then
+ Result := True;
+ 10..65535:
+ if (GikoSys.Setting.HeadResCount) < (index + 1) then begin
+ if (item.Count - index) > GikoSys.ResRange then begin
+ Result := True;
+ end;
+ end;
+ end;
+end;
+constructor TBufferedWebBrowser.Create(Browser: TWebBrowser; BuffSize: Integer);
+begin
+ inherited Create;
+ Self.Sorted := False;
+ if (Browser = nil) then
+ Raise Exception.Create('Browser is NULL');
+ FBrowser := Browser;
+
+ // \83o\83b\83t\83@\82·\82é\8ds\90\94\82ð
+ if (BuffSize < 0) then begin
+ FBuffSize := 100;
+ end else begin
+ FBuffSize := BuffSize;
+ end;
+ Self.Capacity := FBuffSize + 10;
+end;
+procedure TBufferedWebBrowser.Open;
+begin
+ FBrowserDoc := Idispatch( olevariant(FBrowser.ControlInterface).Document);
+ FBrowserDoc.open;
+ FBrowserDoc.charset := 'Shift_JIS';
+end;
+procedure TBufferedWebBrowser.Close;
+begin
+ Self.Flush;
+ try
+ FBrowserDoc.Close;
+ except
+ end;
+ FBrowser := nil;
+end;
+function TBufferedWebBrowser.Add(const S: string): Integer;
+begin
+ Result := inherited Add(TrimRight(s));
+ if (Self.Count > FBuffSize) then begin
+ FBrowserDoc.Write(Self.Text);
+ Self.Clear;
+ end;
+end;
+procedure TBufferedWebBrowser.Flush ;
+begin
+ if (Self.Count > 0) then begin
+ FBrowserDoc.Write(Self.Text);
+ Self.Clear;
+ end;
+end;
+destructor TBufferedWebBrowser.Destory;
+begin
+ try
+ if (FBrowserDoc <> 0) then begin
+ FBrowserDoc.close;
+ FBrowserDoc := 0;
+ end;
+ except
+ end;
+ inherited;
+end;
+//! \8aÖ\98A\83L\81[\83\8f\81[\83h\83\8a\83\93\83N\8fo\97Í
+function THTMLCreate.getKeywordLink(item: TThreadItem): String;
+const
+ PARA_URL = 'http://p2.2ch.io/getf.cgi?';
+begin
+ Result := '';
+ if (GikoSys.Setting.AddKeywordLink) and (item.ParentBoard.Is2ch) then begin
+ Result := '<p><span id="keyword"><a href="' + PARA_URL
+ + item.URL + '" target="_blank">\8aÖ\98A\83L\81[\83\8f\81[\83h</a></span></p>';
+ end;
+end;