From 6cc4e6b81a9f2a0275d7fa0c6171658b24a2af8a Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sun, 27 Jan 2002 19:03:10 +0000 Subject: [PATCH] new wxHtmlWindow::OnOpeningURL API git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13854 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/htparser.tex | 34 +++++++++ docs/latex/wx/htwindow.tex | 34 +++++++-- docs/latex/wx/htwinprs.tex | 8 --- include/wx/html/htmlpars.h | 12 +++- include/wx/html/htmlwin.h | 58 +++++++++------ include/wx/html/winpars.h | 2 +- src/html/htmlpars.cpp | 6 ++ src/html/htmlwin.cpp | 8 +-- src/html/m_image.cpp | 142 +++++++++++++++++++++++++++---------- src/html/winpars.cpp | 23 +++++- 10 files changed, 243 insertions(+), 84 deletions(-) diff --git a/docs/latex/wx/htparser.tex b/docs/latex/wx/htparser.tex index b9d848e609..91dd28305d 100644 --- a/docs/latex/wx/htparser.tex +++ b/docs/latex/wx/htparser.tex @@ -134,6 +134,40 @@ Returns pointer to the source being parsed. Setups the parser for parsing the {\it source} string. (Should be overridden in derived class) +\membersection{wxHtmlParser::OpenURL}\label{wxhtmlparseropenurl} + +\func{virtual wxFSFile*}{OpenURL}{\param{wxHtmlURLType }{type}, \param{const wxString\& }{url}} + +Opens given URL and returns {\tt wxFSFile} object that can be used to read data +from it. This method may return NULL in one of two cases: either the URL doesn't +point to any valid resource or the URL is blocked by overriden implementation +of {\it OpenURL} in derived class. + +\wxheading{Parameters} + +\docparam{type}{Indicates type of the resource. Is one of +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxHTML\_URL\_PAGE}}{Opening a HTML page.} +\twocolitem{{\bf wxHTML\_URL\_IMAGE}}{Opening an image.} +\twocolitem{{\bf wxHTML\_URL\_OTHER}}{Opening a resource that doesn't fall into +any other category.} +\end{twocollist}} + +\docparam{url}{URL being opened.} + +\wxheading{Notes} + +Always use this method in tag handlers instead of {\tt GetFS()->OpenFile()} +because it can block the URL and is thus more secure. + +Default behaviour is to call \helpref{wxHtmlWindow::OnOpeningURL}{wxhtmlwindowonopeningurl} +of the associated wxHtmlWindow object (which may decide to block the URL or +redirect it to another one),if there's any, and always open the URL if the +parser is not used with wxHtmlWindow. + +Returned {\tt wxFSFile} object is not guaranteed to point to {\it url}, it might +have been redirected! + \membersection{wxHtmlParser::Parse}\label{wxhtmlparserparse} \func{wxObject*}{Parse}{\param{const wxString\& }{source}} diff --git a/docs/latex/wx/htwindow.tex b/docs/latex/wx/htwindow.tex index ed1f0344d9..36c2f810aa 100644 --- a/docs/latex/wx/htwindow.tex +++ b/docs/latex/wx/htwindow.tex @@ -200,13 +200,39 @@ Also see \helpref{wxHtmlLinkInfo}{wxhtmllinkinfo}. \membersection{wxHtmlWindow::OnOpeningURL}\label{wxhtmlwindowonopeningurl} -\func{virtual bool}{OnOpeningURL}{\param{const wxString\& }{url}} +\func{virtual wxHtmlOpeningStatus}{OnOpeningURL}{\param{wxHtmlURLType }{type},\param{const wxString\& }{url}, \param{wxString *}{redirect}} Called when an URL is being opened (either when the user clicks on a link or -an image is loaded). If the function returns FALSE, the URL won't be fetched. -Default behaviour is to return TRUE. +an image is loaded). The URL will be opened only if OnOpeningURL returns +{\tt wxHTML\_OPEN}. This method is called by +\helpref{wxHtmlParser::OpenURL}{wxhtmlparseropenurl}. +You can override OnOpeningURL to selectively block some +URLs (e.g. for security reasons) or to redirect them elsewhere. Default +behaviour is to always return {\tt wxHTML\_OPEN}. -Also see \helpref{wxHtmlWinParser::CanOpenURL}{wxhtmlwinparsercanopenurl}. +\wxheading{Parameters} + +\docparam{type}{Indicates type of the resource. Is one of +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxHTML\_URL\_PAGE}}{Opening a HTML page.} +\twocolitem{{\bf wxHTML\_URL\_IMAGE}}{Opening an image.} +\twocolitem{{\bf wxHTML\_URL\_OTHER}}{Opening a resource that doesn't fall into +any other category.} +\end{twocollist}} + +\docparam{url}{URL being opened.} + +\docparam{redirect}{Pointer to wxString variable that must be filled with an +URL if OnOpeningURL returns {\tt wxHTML\_REDIRECT}.} + +\wxheading{Return value} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxHTML\_OPEN}}{Open the URL.} +\twocolitem{{\bf wxHTML\_BLOCK}}{Deny access to the URL, \helpref{wxHtmlParser::OpenURL}{wxhtmlparseropenurl} will return NULL.} +\twocolitem{{\bf wxHTML\_REDIRECT}}{Don't open {\it url}, redirect to another +URL. OnOpeningURL must fill {\it *redirect} with the new URL. OnOpeningURL will +be called again on returned URL.} +\end{twocollist} \membersection{wxHtmlWindow::OnSetTitle}\label{wxhtmlwindowonsettitle} diff --git a/docs/latex/wx/htwinprs.tex b/docs/latex/wx/htwinprs.tex index 473a8cd0ea..4ff62130d9 100644 --- a/docs/latex/wx/htwinprs.tex +++ b/docs/latex/wx/htwinprs.tex @@ -43,14 +43,6 @@ Constructor. Don't use the default one, use constructor with Adds \helpref{module}{handlers} to the list of wxHtmlWinParser tag handler. -\membersection{wxHtmlWinParser::CanOpenURL}\label{wxhtmlwinparsercanopenurl} - -\func{virtual bool}{CanOpenURL}{\param{const wxString\& }{url}} - -Call this function to determine whether you are allowed to open given URL. -Default behaviour is to call \helpref{wxHtmlWindow::OnOpeningURL}{wxhtmlwindowonopeningurl} -of the associated wxHtmlWindow object. - \membersection{wxHtmlWinParser::CloseContainer}\label{wxhtmlwinparserclosecontainer} \func{wxHtmlContainerCell*}{CloseContainer}{\void} diff --git a/include/wx/html/htmlpars.h b/include/wx/html/htmlpars.h index 0faf78d4dd..a7f067b5a1 100644 --- a/include/wx/html/htmlpars.h +++ b/include/wx/html/htmlpars.h @@ -31,6 +31,14 @@ class WXDLLEXPORT wxHtmlEntitiesParser; class wxHtmlTextPieces; class wxHtmlParserState; + +enum wxHtmlURLType +{ + wxHTML_URL_PAGE, + wxHTML_URL_IMAGE, + wxHTML_URL_OTHER +}; + // This class handles generic parsing of HTML document : it scans // the document and divide it into blocks of tags (where one block // consists of starting and ending tag and of text between these @@ -48,9 +56,9 @@ public: wxFileSystem* GetFS() const { return m_FS; } - // Returns TRUE if the parser is allowed to open given URL (may be forbidden + // Opens file if the parser is allowed to open given URL (may be forbidden // for security reasons) - virtual bool CanOpenURL(const wxString& url) const { return TRUE; } + virtual wxFSFile *OpenURL(wxHtmlURLType type, const wxString& url) const; // You can simply call this method when you need parsed output. // This method does these things: diff --git a/include/wx/html/htmlwin.h b/include/wx/html/htmlwin.h index 22466f4856..cbda2b6ad3 100644 --- a/include/wx/html/htmlwin.h +++ b/include/wx/html/htmlwin.h @@ -32,6 +32,19 @@ class wxHtmlWinModule; class wxHtmlHistoryArray; class wxHtmlProcessorList; + +// wxHtmlWindow flags: +#define wxHW_SCROLLBAR_NEVER 0x0002 +#define wxHW_SCROLLBAR_AUTO 0x0004 + +// enums for wxHtmlWindow::OnOpeningURL +enum wxHtmlOpeningStatus +{ + wxHTML_OPEN, + wxHTML_BLOCK, + wxHTML_REDIRECT +}; + //-------------------------------------------------------------------------------- // wxHtmlWindow // (This is probably the only class you will directly use.) @@ -106,10 +119,6 @@ public: // Sets fonts to be used when displaying HTML page. void SetFonts(wxString normal_face, wxString fixed_face, const int *sizes); - // Sets the title of the window - // (depending on the information passed to SetRelatedFrame() method) - virtual void OnSetTitle(const wxString& title); - // Sets space between text and window borders. void SetBorders(int b) {m_Borders = b;} @@ -136,8 +145,24 @@ public: // Adds input filter static void AddFilter(wxHtmlFilter *filter); + // Returns a pointer to the parser. + wxHtmlWinParser *GetParser() const { return m_Parser; } + + // Adds HTML processor to this instance of wxHtmlWindow: + void AddProcessor(wxHtmlProcessor *processor); + // Adds HTML processor to wxHtmlWindow class as whole: + static void AddGlobalProcessor(wxHtmlProcessor *processor); + + // what would we do with it? + virtual bool AcceptsFocusFromKeyboard() const { return FALSE; } + + // -- Callbacks -- + + // Sets the title of the window + // (depending on the information passed to SetRelatedFrame() method) + virtual void OnSetTitle(const wxString& title); + // Called when the mouse hovers over a cell: (x, y) are logical coords - // // Default behaviour is to do nothing at all virtual void OnCellMouseHover(wxHtmlCell *cell, wxCoord x, wxCoord y); @@ -151,21 +176,14 @@ public: // call LoadPage(loc) virtual void OnLinkClicked(const wxHtmlLinkInfo& link); - // Called when wxHtmlWindow wants to fetch data from an URL (e.g. when loading - // a page or loading an image). The data are downloaded if and only if - // OnOpeningURL returns TRUE. - virtual bool OnOpeningURL(const wxString& url) const { return TRUE; } - - // Returns a pointer to the parser. - wxHtmlWinParser *GetParser() const { return m_Parser; } - - // Adds HTML processor to this instance of wxHtmlWindow: - void AddProcessor(wxHtmlProcessor *processor); - // Adds HTML processor to wxHtmlWindow class as whole: - static void AddGlobalProcessor(wxHtmlProcessor *processor); - - // what would we do with it? - virtual bool AcceptsFocusFromKeyboard() const { return FALSE; } + // Called when wxHtmlWindow wants to fetch data from an URL (e.g. when + // loading a page or loading an image). The data are downloaded if and only if + // OnOpeningURL returns TRUE. If OnOpeningURL returns wxHTML_REDIRECT, + // it must set *redirect to the new URL + virtual wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType type, + const wxString& url, + wxString *redirect) const + { return wxHTML_OPEN; } protected: void Init(); diff --git a/include/wx/html/winpars.h b/include/wx/html/winpars.h index 396526b92a..4ce8afd0f7 100644 --- a/include/wx/html/winpars.h +++ b/include/wx/html/winpars.h @@ -48,7 +48,7 @@ public: virtual void DoneParser(); virtual wxObject* GetProduct(); - virtual bool CanOpenURL(const wxString& url) const; + virtual wxFSFile *OpenURL(wxHtmlURLType type, const wxString& url) const; // Set's the DC used for parsing. If SetDC() is not called, // parsing won't proceed diff --git a/src/html/htmlpars.cpp b/src/html/htmlpars.cpp index 9efd706bea..69be9d281e 100644 --- a/src/html/htmlpars.cpp +++ b/src/html/htmlpars.cpp @@ -812,4 +812,10 @@ wxChar wxHtmlEntitiesParser::GetEntityChar(const wxString& entity) return GetCharForCode(code); } +wxFSFile *wxHtmlParser::OpenURL(wxHtmlURLType WXUNUSED(type), + const wxString& url) const +{ + return GetFS()->OpenFile(url); +} + #endif diff --git a/src/html/htmlwin.cpp b/src/html/htmlwin.cpp index 9625513f47..212d556d99 100644 --- a/src/html/htmlwin.cpp +++ b/src/html/htmlwin.cpp @@ -263,13 +263,7 @@ bool wxHtmlWindow::LoadPage(const wxString& location) Refresh(FALSE); } - if ( !m_Parser->CanOpenURL(location) ) - { - wxLogError(_("Access denied to document '%s'!"), location.c_str()); - return FALSE; - } - - f = m_FS->OpenFile(location); + f = m_Parser->OpenURL(wxHTML_URL_PAGE, location); if (f == NULL) { diff --git a/src/html/m_image.cpp b/src/html/m_image.cpp index 5f5cc37d91..9fb42a9500 100644 --- a/src/html/m_image.cpp +++ b/src/html/m_image.cpp @@ -292,6 +292,7 @@ public: private: wxBitmap *m_bitmap; int m_bmpW, m_bmpH; + bool m_showFrame:1; wxScrolledWindow *m_window; #if wxUSE_GIF && wxUSE_TIMER wxGIFDecoder *m_gifDecoder; @@ -323,12 +324,55 @@ class wxGIFTimer : public wxTimer // wxHtmlImageCell //-------------------------------------------------------------------------------- +/* XPM */ +static const char * broken_image_xpm[] = { +"29 31 7 1", +" c None", +". c #808080", +"+ c #FFFFFF", +"@ c #C0C0C0", +"# c #000000", +"$ c #333366", +"% c #B2B2B2", +"..................... ", +".+++++++++++++++++++.. ", +".+++++++++++++++++++.@. ", +".++@@@@@@@@@@@@@@@@@.+@. ", +".++@@@@@@@@@@@@@@@@@.++@. ", +".++@@@@@.@@@@.@@@@@@.+++@. ", +".++@@@@@@@@@@@@@@@@@.++++@. ", +".++@@@@@@@@@@@@@@@@@.+++++@. ", +".++@@.@@@@@@@@@@.@@@######## ", +".++@@@@@@@@@@@@@@@@@@$$$$$$#.", +".######@@@@@@@@@@@@@@@.....#.", +" ###@@@@@@@@@@@@@@@++#.", +" #####@@@@@@@@@@++#.", +" #@.@@@@@@@@++#.", +".. ###@@@@@@@++#.", +".+.... #@@@@@@++#.", +".++@@@... ####@@++#.", +".++@@@@@@.. #####.", +".++@@@@@@@@... ", +".++@@@@@@%%%%@. ", +".++@@@@@@%%%%@@.... ", +".++@@@@@@%%%%@@@@@@.... ", +".++@@@@@@%%%%@@@@@@@@@@.... ", +".++@@@@@@@@@@@@@@@@@@@@@@++#.", +".++@@@@@@@@@@@@@@@@@@@@@@++#.", +".++@@@@@@@@@@@@@@@@@@@@@@++#.", +".++@@@@@@@@@@@@@@@@@@@@@@++#.", +".++@@@@@@@@@@@@@@@@@@@@@@++#.", +".++++++++++++++++++++++++++#.", +".++++++++++++++++++++++++++#.", +"############################."}; + wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input, int w, int h, double scale, int align, const wxString& mapname) : wxHtmlCell() { m_window = window ? wxStaticCast(window, wxScrolledWindow) : NULL; m_scale = scale; + m_showFrame = FALSE; m_bitmap = NULL; m_bmpW = w; m_bmpH = h; @@ -341,46 +385,63 @@ wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input, m_physX = m_physY = -1; #endif - wxInputStream *s = input->GetStream(); - - if ( s ) + if ( input ) { - bool readImg = TRUE; - -#if wxUSE_GIF && wxUSE_TIMER - if ( (input->GetLocation().Matches(wxT("*.gif")) || - input->GetLocation().Matches(wxT("*.GIF"))) && m_window ) + wxInputStream *s = input->GetStream(); + + if ( s ) { - m_gifDecoder = new wxGIFDecoder(s, TRUE); - if ( m_gifDecoder->ReadGIF() == wxGIF_OK ) + bool readImg = TRUE; + +#if wxUSE_GIF && wxUSE_TIMER + if ( (input->GetLocation().Matches(wxT("*.gif")) || + input->GetLocation().Matches(wxT("*.GIF"))) && m_window ) { - wxImage img; - if ( m_gifDecoder->ConvertToImage(&img) ) - SetImage(img); + m_gifDecoder = new wxGIFDecoder(s, TRUE); + if ( m_gifDecoder->ReadGIF() == wxGIF_OK ) + { + wxImage img; + if ( m_gifDecoder->ConvertToImage(&img) ) + SetImage(img); - readImg = FALSE; + readImg = FALSE; - if ( m_gifDecoder->IsAnimation() ) - { - m_gifTimer = new wxGIFTimer(this); - m_gifTimer->Start(m_gifDecoder->GetDelay(), TRUE); + if ( m_gifDecoder->IsAnimation() ) + { + m_gifTimer = new wxGIFTimer(this); + m_gifTimer->Start(m_gifDecoder->GetDelay(), TRUE); + } + else + { + wxDELETE(m_gifDecoder); + } } else { wxDELETE(m_gifDecoder); } } - else + + if ( readImg ) +#endif { - wxDELETE(m_gifDecoder); + SetImage(wxImage(*s, wxBITMAP_TYPE_ANY)); } } - - if ( readImg ) -#endif + } + else // input==NULL, use "broken image" bitmap + { + if ( m_bmpW == -1 && m_bmpH == -1 ) + { + m_bmpW == 29, m_bmpH = 31; + } + else { - SetImage(wxImage(*s, wxBITMAP_TYPE_ANY)); + m_showFrame = TRUE; + if ( m_bmpW == -1 ) m_bmpW = 31; + if ( m_bmpH == -1 ) m_bmpH = 33; } + m_bitmap = new wxBitmap(broken_image_xpm); } m_Width = (int)(scale * (double)m_bmpW); @@ -487,7 +548,14 @@ wxHtmlImageCell::~wxHtmlImageCell() void wxHtmlImageCell::Draw(wxDC& dc, int x, int y, int WXUNUSED(view_y1), int WXUNUSED(view_y2)) { - if (m_bitmap) + if ( m_showFrame ) + { + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.SetPen(*wxBLACK_PEN); + dc.DrawRectangle(x + m_PosX, y + m_PosY, m_Width, m_Height); + x++, y++; + } + if ( m_bitmap ) { double us_x, us_y; dc.GetUserScale(&us_x, &us_y); @@ -549,10 +617,8 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA") wxString tmp = tag.GetParam(wxT("SRC")); wxString mn = wxEmptyString; - if ( !m_WParser->CanOpenURL(tmp) ) - return FALSE; - - str = m_WParser->GetFS()->OpenFile(tmp); + str = m_WParser->OpenURL(wxHTML_URL_IMAGE, tmp); + if (tag.HasParam(wxT("WIDTH"))) tag.GetParamAsInt(wxT("WIDTH"), &w); if (tag.HasParam(wxT("HEIGHT"))) @@ -575,18 +641,16 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA") mn = mn.Mid( 1 ); } } - wxHtmlImageCell *cel = NULL; + wxHtmlImageCell *cel = new wxHtmlImageCell( + m_WParser->GetWindow(), + str, w, h, + m_WParser->GetPixelScale(), + al, mn); + cel->SetLink(m_WParser->GetLink()); + cel->SetId(tag.GetParam(wxT("id"))); // may be empty + m_WParser->GetContainer()->InsertCell(cel); if (str) - { - cel = new wxHtmlImageCell(m_WParser->GetWindow(), - str, w, h, - m_WParser->GetPixelScale(), - al, mn); - cel->SetLink(m_WParser->GetLink()); - cel->SetId(tag.GetParam(wxT("id"))); // may be empty - m_WParser->GetContainer()->InsertCell(cel); delete str; - } } } if (tag.GetName() == wxT("MAP")) diff --git a/src/html/winpars.cpp b/src/html/winpars.cpp index 479401d392..86dbfd1b90 100644 --- a/src/html/winpars.cpp +++ b/src/html/winpars.cpp @@ -180,14 +180,31 @@ wxObject* wxHtmlWinParser::GetProduct() return top; } -bool wxHtmlWinParser::CanOpenURL(const wxString& url) const +wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type, + const wxString& url) const { // FIXME - normalize the URL to full path before passing to // OnOpeningURL!! if ( m_Window ) - return m_Window->OnOpeningURL(url); + { + wxString redirect; + wxString myurl(url); + wxHtmlOpeningStatus status; + for (;;) + { + if ( m_Window->OnOpeningURL(type, myurl, &redirect) == wxHTML_REDIRECT ) + myurl = redirect; + else + break; + } + + if ( status == wxHTML_BLOCK ) + return NULL; + else + return GetFS()->OpenFile(myurl); + } else - return TRUE; + return wxHtmlParser::OpenURL(type, url); } void wxHtmlWinParser::AddText(const wxChar* txt) -- 2.45.2