WebView: GetHtml() is a new method that retrieve the HTML contents of the view.

[GB.GTK3.WEBVIEW]
* NEW: WebView: GetHtml() is a new method that retrieve the HTML contents of the view.

[GB.QT4.WEBVIEW]
* NEW: WebView: GetHtml() is a new method that retrieve the HTML contents of the view.

[GB.QT5.WEBVIEW]
* NEW: WebView: GetHtml() is a new method that retrieve the HTML contents of the view.
This commit is contained in:
Benoît Minisini 2022-07-23 15:40:37 +02:00
parent d053ced083
commit 72d23a24f2
5 changed files with 186 additions and 52 deletions

View file

@ -169,6 +169,39 @@ static gboolean cb_decide_policy(WebKitWebView *widget, WebKitPolicyDecision *de
return FALSE; return FALSE;
} }
static bool start_callback(void *_object)
{
if (THIS->cb_running)
{
GB.Error("Pending asynchronous method");
return TRUE;
}
THIS->cb_running = TRUE;
GB.Ref(THIS);
return FALSE;
}
static void run_callback(void *_object, const char *error)
{
while(THIS->cb_running)
GB.Wait(-1);
if (THIS->cb_error)
{
GB.Error(error, THIS->cb_result);
GB.FreeString(&THIS->cb_result);
}
else
{
GB.ReturnString(GB.FreeStringLater(THIS->cb_result));
THIS->cb_result = NULL;
}
THIS->cb_error = FALSE;
GB.Unref(POINTER(&_object));
}
static void cb_javascript_finished(WebKitWebView *widget, GAsyncResult *result, void *_object) static void cb_javascript_finished(WebKitWebView *widget, GAsyncResult *result, void *_object)
{ {
WebKitJavascriptResult *js_result; WebKitJavascriptResult *js_result;
@ -180,9 +213,9 @@ static void cb_javascript_finished(WebKitWebView *widget, GAsyncResult *result,
js_result = webkit_web_view_run_javascript_finish(widget, result, &error); js_result = webkit_web_view_run_javascript_finish(widget, result, &error);
if (!js_result) if (!js_result)
{ {
THIS->js_result = GB.NewZeroString(error->message); THIS->cb_result = GB.NewZeroString(error->message);
g_error_free(error); g_error_free(error);
THIS->js_error = TRUE; THIS->cb_error = TRUE;
} }
else else
{ {
@ -192,20 +225,69 @@ static void cb_javascript_finished(WebKitWebView *widget, GAsyncResult *result,
exception = jsc_context_get_exception(jsc_value_get_context (value)); exception = jsc_context_get_exception(jsc_value_get_context (value));
if (exception) if (exception)
{ {
THIS->js_result = GB.NewZeroString(jsc_exception_get_message(exception)); THIS->cb_result = GB.NewZeroString(jsc_exception_get_message(exception));
THIS->js_error = TRUE; THIS->cb_error = TRUE;
} }
else else
{ {
THIS->js_result = GB.NewZeroString(json); THIS->cb_result = GB.NewZeroString(json);
} }
g_free(json); g_free(json);
webkit_javascript_result_unref(js_result); webkit_javascript_result_unref(js_result);
} }
GB.Unref(POINTER(&_object)); THIS->cb_running = FALSE;
THIS->js_running = FALSE; }
static char *get_encoding(const char *mimetype)
{
char *p = strstr(mimetype, ";charset=");
if (!p)
return NULL;
p += 9;
if (!strcasecmp(p, "utf-8") || !strcasecmp(p, "utf8"))
return NULL;
return p;
}
static void cb_html_finished(WebKitWebResource *resource, GAsyncResult *result, void *_object)
{
GError *error = NULL;
gsize length = 0;
guchar *html;
char *encoding;
html = webkit_web_resource_get_data_finish(resource, result, &length, &error);
if (!html)
{
THIS->cb_result = GB.NewZeroString(error->message);
g_error_free(error);
THIS->cb_error = TRUE;
return;
}
encoding = get_encoding(webkit_uri_response_get_mime_type(webkit_web_resource_get_response(resource)));
if (encoding)
{
if (GB.ConvString(&THIS->cb_result, (char *)html, length, encoding, "UTF-8"))
{
THIS->cb_result = GB.NewZeroString(GB.GetErrorMessage());
THIS->cb_error = TRUE;
}
}
else
{
THIS->cb_result = GB.NewString((char *)html, length);
}
g_free(html);
THIS->cb_running = FALSE;
} }
static gboolean cb_context_menu(WebKitWebView *web_view, WebKitContextMenu *context_menu, GdkEvent *event, WebKitHitTestResult *hit_test_result, void *_object) static gboolean cb_context_menu(WebKitWebView *web_view, WebKitContextMenu *context_menu, GdkEvent *event, WebKitHitTestResult *hit_test_result, void *_object)
@ -389,28 +471,26 @@ BEGIN_METHOD(WebView_ExecJavascript, GB_STRING script)
script = GB.ToZeroString(ARG(script)); script = GB.ToZeroString(ARG(script));
THIS->js_running = TRUE; if (start_callback(THIS))
GB.Ref(THIS); return;
webkit_web_view_run_javascript(WIDGET, script, NULL, (GAsyncReadyCallback)cb_javascript_finished, (gpointer)THIS); webkit_web_view_run_javascript(WIDGET, script, NULL, (GAsyncReadyCallback)cb_javascript_finished, (gpointer)THIS);
while(THIS->js_running) run_callback(THIS, "Javascript error: &1");
GB.Wait(-1);
if (THIS->js_error)
{
GB.Error("Javascript error: &1", THIS->js_result);
GB.FreeString(&THIS->js_result);
}
else
{
GB.ReturnString(GB.FreeStringLater(THIS->js_result));
THIS->js_result = NULL;
}
THIS->js_error = FALSE;
END_METHOD END_METHOD
BEGIN_METHOD_VOID(WebView_GetHtml)
if (start_callback(THIS))
return;
webkit_web_resource_get_data(webkit_web_view_get_main_resource(WIDGET), NULL, (GAsyncReadyCallback)cb_html_finished, (gpointer)THIS);
run_callback(THIS, "Unable to retrieve HTML contents: &1");
END_METHOD
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
BEGIN_PROPERTY(WebViewHistoryItem_Title) BEGIN_PROPERTY(WebViewHistoryItem_Title)
@ -527,6 +607,8 @@ GB_DESC WebViewDesc[] =
GB_PROPERTY_READ("Link", "s", WebView_Link), GB_PROPERTY_READ("Link", "s", WebView_Link),
GB_METHOD("SetHtml", NULL, WebView_SetHtml, "(Html)s[(Root)s]"), GB_METHOD("SetHtml", NULL, WebView_SetHtml, "(Html)s[(Root)s]"),
GB_METHOD("GetHtml", "s", WebView_GetHtml, NULL),
GB_METHOD("Clear", NULL, WebView_Clear, NULL), GB_METHOD("Clear", NULL, WebView_Clear, NULL),
GB_METHOD("Back", NULL, WebView_Back, NULL), GB_METHOD("Back", NULL, WebView_Back, NULL),

View file

@ -35,12 +35,12 @@ typedef
GTK_PICTURE icon; GTK_PICTURE icon;
void *new_view; void *new_view;
char *link; char *link;
char *js_result; char *cb_result;
unsigned error : 1; unsigned error : 1;
unsigned accept_next : 1; unsigned accept_next : 1;
unsigned got_load_event : 1; unsigned got_load_event : 1;
unsigned js_running : 1; unsigned cb_running : 1;
unsigned js_error : 1; unsigned cb_error : 1;
} }
CWEBVIEW; CWEBVIEW;

View file

@ -336,6 +336,13 @@ BEGIN_METHOD(WebView_ExecJavascript, GB_STRING script)
END_METHOD END_METHOD
BEGIN_METHOD_VOID(WebView_GetHtml)
RETURN_NEW_STRING(WIDGET->page()->mainFrame()->toHtml());
END_METHOD
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
static QWebHistoryItem get_item(QWebHistory *history, int index) static QWebHistoryItem get_item(QWebHistory *history, int index)
@ -495,7 +502,9 @@ GB_DESC WebViewDesc[] =
GB_PROPERTY_READ("Link", "s", WebView_Link), GB_PROPERTY_READ("Link", "s", WebView_Link),
GB_METHOD("SetHtml", NULL, WebView_SetHtml, "(Html)s[(Root)s]"), GB_METHOD("SetHtml", NULL, WebView_SetHtml, "(Html)s[(Root)s]"),
GB_METHOD("Clear", NULL, WebView_Clear, NULL), GB_METHOD("GetHtml", "s", WebView_GetHtml, NULL),
GB_METHOD("Clear", NULL, WebView_Clear, NULL),
GB_METHOD("Back", NULL, WebView_Back, NULL), GB_METHOD("Back", NULL, WebView_Back, NULL),
GB_METHOD("Forward", NULL, WebView_Forward, NULL), GB_METHOD("Forward", NULL, WebView_Forward, NULL),

View file

@ -45,10 +45,10 @@
#define HISTORY (WIDGET->history()) #define HISTORY (WIDGET->history())
static bool _js_exited = FALSE; static bool _cb_exited = FALSE;
static volatile bool _js_running = FALSE; static volatile bool _cb_running = FALSE;
static bool _js_error = FALSE; static bool _cb_error = FALSE;
static char *_js_result = NULL; static char *_cb_result = NULL;
/*typedef /*typedef
struct { struct {
@ -227,9 +227,40 @@ static void set_link(void *_object, const QString &link)
THIS->link = QT.NewString(link); THIS->link = QT.NewString(link);
} }
static bool start_callback()
{
if (_cb_running)
{
GB.Error("Pending asynchronous method");
return true;
}
_cb_running = true;
return false;
}
static void run_callback(const char *error)
{
while(_cb_running)
GB.Wait(-1);
if (_cb_error)
{
GB.Error(error);
GB.FreeString(&_cb_result);
}
else
{
GB.ReturnString(GB.FreeStringLater(_cb_result));
_cb_result = NULL;
}
_cb_error = FALSE;
}
static void cb_javascript_finished(const QVariant &result) static void cb_javascript_finished(const QVariant &result)
{ {
if (_js_exited) if (_cb_exited)
return; return;
QVariantList value; QVariantList value;
@ -238,17 +269,27 @@ static void cb_javascript_finished(const QVariant &result)
QByteArray array = QJsonDocument::fromVariant(value).toJson(QJsonDocument::Compact); QByteArray array = QJsonDocument::fromVariant(value).toJson(QJsonDocument::Compact);
if (array.size() > 2) if (array.size() > 2)
_js_result = GB.NewString(array.constData() + 1, array.size() - 2); _cb_result = GB.NewString(array.constData() + 1, array.size() - 2);
_js_running = FALSE; _cb_running = FALSE;
}
static void cb_html_finished(const QString &result)
{
if (_cb_exited)
return;
_cb_result = QT.NewString(result);
_cb_running = FALSE;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
BEGIN_METHOD_VOID(WebView_exit) BEGIN_METHOD_VOID(WebView_exit)
_js_exited = TRUE; _cb_exited = TRUE;
GB.FreeString(&_js_result); GB.FreeString(&_cb_result);
END_METHOD END_METHOD
@ -446,24 +487,23 @@ BEGIN_METHOD(WebView_ExecJavascript, GB_STRING script)
if (LENGTH(script) == 0) if (LENGTH(script) == 0)
return; return;
_js_running = TRUE; if (start_callback())
return;
WIDGET->page()->runJavaScript(QSTRING_ARG(script), cb_javascript_finished); WIDGET->page()->runJavaScript(QSTRING_ARG(script), cb_javascript_finished);
while(_js_running) run_callback("Javascript error");
GB.Wait(-1);
if (_js_error) END_METHOD
{
GB.Error("Javascript error"); BEGIN_METHOD_VOID(WebView_GetHtml)
GB.FreeString(&_js_result);
} if (start_callback())
else return;
{
GB.ReturnString(GB.FreeStringLater(_js_result)); WIDGET->page()->toHtml(cb_html_finished);
_js_result = NULL;
} run_callback("Unable to retrieve HTML contents");
_js_error = FALSE;
END_METHOD END_METHOD
@ -929,6 +969,8 @@ GB_DESC WebViewDesc[] =
GB_PROPERTY_READ("Link", "s", WebView_Link), GB_PROPERTY_READ("Link", "s", WebView_Link),
GB_METHOD("SetHtml", NULL, WebView_SetHtml, "(Html)s[(Root)s]"), GB_METHOD("SetHtml", NULL, WebView_SetHtml, "(Html)s[(Root)s]"),
GB_METHOD("GetHtml", "s", WebView_GetHtml, NULL),
GB_METHOD("Clear", NULL, WebView_Clear, NULL), GB_METHOD("Clear", NULL, WebView_Clear, NULL),
GB_METHOD("Back", NULL, WebView_Back, NULL), GB_METHOD("Back", NULL, WebView_Back, NULL),

View file

@ -56,6 +56,7 @@ typedef
char *link; char *link;
int history; int history;
int progress; int progress;
char *cb_result;
unsigned cancel : 1; unsigned cancel : 1;
} }
CWEBVIEW; CWEBVIEW;