Page 1 of 4
How to edit source HTML code before render
Posted: Fri Apr 20, 2018 9:02 am
by yiqianyishi
Hi,
i want to edit the page heml code before render, for example, I want to filter some keywords before the page is displayed.
Can this effect be done? thank you!
Re: How to edit source HTML code before render
Posted: Fri Apr 20, 2018 10:53 am
by salvadordf
Hi,
You can use a response filter to do that. Take a look at the ResponseFilterBrowser demo and read the code comments.
Re: How to edit source HTML code before render
Posted: Mon Apr 23, 2018 10:01 am
by yiqianyishi
I tested the demo program, and I don't understand how, in the Filter_OnFilter event, how do I modify the HTML content of the browser based on some keywords before the browser rendering? In the example, in the Filter_OnFilter event, FStream is used to save the content, and I don't know how to modify the content.
For example, I want to modify the href attribute of the <a> element in HTML. The original page's source code is <a href= "
http://abc.com" >test</a>.
Modified to <a href= "
http://NBA.com" >NBA</a>
Can you give specific help to the code? Thank you。
Re: How to edit source HTML code before render
Posted: Mon Apr 23, 2018 10:40 am
by yiqianyishi
Ask for your help, thank you.
Re: How to edit source HTML code before render
Posted: Mon Apr 23, 2018 10:50 am
by salvadordf
I'm very busy right now but you can modify the TResponseFilterBrowserFrm.Filter_OnFilter procedure to do that.
You should search for a string in the buffer pointed by "data_in", make a copy in a custom memory buffer replacing that string and then call "Move" using your custom memory buffer with the new buffer length.
Re: How to edit source HTML code before render
Posted: Tue Aug 07, 2018 9:35 am
by Student
Hi Salvador, i need to replace resources before rendering, to your instructions i written next code, how do you think it is correct?
Code: Select all
if (data_out <> nil) then
begin
data_out_written := min(data_in_size, data_out_size);
if (data_out_written > 0) then
begin
Fstream.Clear;
Fstream.LoadFromFile(pathtofile+'628.png');
FStream.Seek(0, soBeginning);
data_out_written:=fstream.Size;
Move(Fstream.Memory^, data_out^, data_out_written); // Move(data_in^, data_out^, data_out_written);
aResult := RESPONSE_FILTER_DONE;
end;
end;
Re: How to edit source HTML code before render
Posted: Tue Aug 07, 2018 9:47 am
by salvadordf
I've never replaced resources but according to the CEF3 documents your code should work.
However, you need to check that the stream size is not bigger than data_out_size or you will have an access violation.
It might be easier to modify the link to that resource in the HTML or CSS file.
Re: How to edit source HTML code before render
Posted: Tue Aug 07, 2018 1:20 pm
by Student
The modify the link to that resource in the HTML, this solution will not suit me, i want loading my resources from disk is invisible to the server.
And how i could increase the size data_out_size under the size Fstream that was not an access violation, if size Fstream there will be more data_out_size ?
Re: How to edit source HTML code before render
Posted: Tue Aug 07, 2018 1:34 pm
by Student
Demos response_filter on c++ allow this doing? I bad understanding this language.
https://bitbucket.org/chromiumembedded/ ... ew-default
Re: How to edit source HTML code before render
Posted: Tue Aug 07, 2018 3:03 pm
by salvadordf
These are the code comments for the response filter in CEF3 :
https://bitbucket.org/chromiumembedded/ ... ew-default
Code: Select all
///
// Called to filter a chunk of data. Expected usage is as follows:
//
// A. Read input data from |data_in| and set |data_in_read| to the number of
// bytes that were read up to a maximum of |data_in_size|. |data_in| will
// be NULL if |data_in_size| is zero.
// B. Write filtered output data to |data_out| and set |data_out_written| to
// the number of bytes that were written up to a maximum of
// |data_out_size|. If no output data was written then all data must be
// read from |data_in| (user must set |data_in_read| = |data_in_size|).
// C. Return RESPONSE_FILTER_DONE if all output data was written or
// RESPONSE_FILTER_NEED_MORE_DATA if output data is still pending.
//
// This function will be called repeatedly until the input buffer has been
// fully read (user sets |data_in_read| = |data_in_size|) and there is no more
// input data to filter (the resource response is complete). This function may
// then be called an additional time with an NULL input buffer if the user
// filled the output buffer (set |data_out_written| = |data_out_size|) and
// returned RESPONSE_FILTER_NEED_MORE_DATA to indicate that output data is
// still pending.
//
// Calls to this function will stop when one of the following conditions is
// met:
//
// A. There is no more input data to filter (the resource response is
// complete) and the user sets |data_out_written| = 0 or returns
// RESPONSE_FILTER_DONE to indicate that all data has been written, or;
// B. The user returns RESPONSE_FILTER_ERROR to indicate an error.
//
// Do not keep a reference to the buffers passed to this function.
///
_cef_response_filter_t is the equivalent to
TCustomResponseFilter in Delphi and the
TCustomResponseFilter.OnFilter event is called when CEF3 calls
filter in
_cef_response_filter_t
The most important thing about the response filters is that the TCustomResponseFilter.OnFilter event might be called
multiple times when the resource is too big. In that case the resource will be split into "chunks of data" and each chunk will be passed in the "data_in" parameter.
For example, if the original resource is 95 Kb long you could see that the TCustomResponseFilter.OnFilter event is triggered 10 times with different
data_in_size values.
If you replace the original resource with a shorter resource then you might need less chunks to send the data. In that case you would just set
aResult to
RESPONSE_FILTER_DONE when you write the last chunk of the new resource.
If you replace the original resource with a larger resource then you might need more chunks to send all the data. In that case you would set
aResult to
RESPONSE_FILTER_NEED_MORE_DATA in the last chunk of the original resource. This will trigger the
TCustomResponseFilter.OnFilter event again and you will be able to send another chunk.
I've updated this demo with these comments and fixed a couple of small bugs.