diff options
author | Pierre Rossi <pierre.rossi@digia.com> | 2013-09-09 17:49:18 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-04 12:15:19 +0100 |
commit | a99fdc02797ece15253ff863102d3257945abfab (patch) | |
tree | cead6337f019ab87afff0c0f0865a18d8a075556 /lib/web_contents_adapter.cpp | |
parent | 1b3be641e660f9f87ec290e9adbb42558860ea37 (diff) |
Implement QWebEnginePage::runJavaScript
We can't have QWebFrame::evaluateJavascript in its old form for
several reasons, the first of which being that we don't have a
QWebEngineFrame class anymore. This is worked around by adding
an optional QString parameter with the frame's XPath.
Another issue is that the WebKit1 API was synchronous, and this would
not play nicely with the very asynchronous nature of chromium we're
now sitting on top of. In order to make this obvious when porting, we
rename it to runJavaScript which doesn't return any result.
This also introduces a template member function overload that will
accept function pointers, functors and lambdas,much like Qt5's new
signal/slot syntax, in order to get the result of the javascript
evaluation back.
Change-Id: I64e15a6f5a168936c52a4da2cef6285dfd16e0d5
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'lib/web_contents_adapter.cpp')
-rw-r--r-- | lib/web_contents_adapter.cpp | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/lib/web_contents_adapter.cpp b/lib/web_contents_adapter.cpp index 9f895d2eb..a5eab5648 100644 --- a/lib/web_contents_adapter.cpp +++ b/lib/web_contents_adapter.cpp @@ -48,17 +48,103 @@ #include "web_contents_view_qt.h" #include "web_engine_context.h" -#include "content/public/browser/web_contents.h" +#include "base/values.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/page_zoom.h" #include "content/public/common/renderer_preferences.h" #include <QGuiApplication> #include <QStyleHints> +#include <QVariant> static const int kTestWindowWidth = 800; static const int kTestWindowHeight = 600; +static QVariant fromJSValue(const base::Value *result) +{ + QVariant ret; + switch (result->GetType()) { + case base::Value::TYPE_NULL: + break; + case base::Value::TYPE_BOOLEAN: + { + bool out; + if (result->GetAsBoolean(&out)) + ret.setValue(out); + break; + } + case base::Value::TYPE_INTEGER: + { + int out; + if (result->GetAsInteger(&out)) + ret.setValue(out); + break; + } + case base::Value::TYPE_DOUBLE: + { + double out; + if (result->GetAsDouble(&out)) + ret.setValue(out); + break; + } + case base::Value::TYPE_STRING: + { + base::string16 out; + if (result->GetAsString(&out)) + ret.setValue(toQt(out)); + break; + } + case base::Value::TYPE_LIST: + { + const base::ListValue *out; + if (result->GetAsList(&out)) { + QVariantList list; + list.reserve(out->GetSize()); + for (size_t i = 0; i < out->GetSize(); ++i) { + const base::Value *outVal = 0; + if (out->Get(i, &outVal) && outVal) + list.insert(i, fromJSValue(outVal)); + } + ret.setValue(list); + } + break; + } + case base::Value::TYPE_DICTIONARY: + { + const base::DictionaryValue *out; + if (result->GetAsDictionary(&out)) { + QVariantMap map; + base::DictionaryValue::Iterator it(*out); + while (!it.IsAtEnd()) { + map.insert(toQt(it.key()), fromJSValue(&it.value())); + it.Advance(); + } + ret.setValue(map); + } + break; + } + case base::Value::TYPE_BINARY: + { + const base::BinaryValue *out = static_cast<const base::BinaryValue*>(result); + QByteArray data(out->GetBuffer(), out->GetSize()); + ret.setValue(data); + break; + } + default: + Q_UNREACHABLE(); + break; + } + return ret; +} + +static void callbackOnEvaluateJS(JSCallbackBase *callback, const base::Value *result) +{ + callback->call(fromJSValue(result)); + delete callback; +} + class WebContentsAdapterPrivate { public: WebContentsAdapterPrivate(); @@ -245,3 +331,16 @@ void WebContentsAdapter::enableInspector(bool enable) { ContentBrowserClientQt::Get()->enableInspector(enable); } + +void WebContentsAdapter::runJavaScript(const QString &javaScript, const QString &xPath, JSCallbackBase *func) +{ + Q_D(WebContentsAdapter); + content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); + Q_ASSERT(rvh); + if (!func) + rvh->ExecuteJavascriptInWebFrame(toString16(xPath), toString16(javaScript)); + else { + content::RenderViewHost::JavascriptResultCallback callback = base::Bind(&callbackOnEvaluateJS, func); + rvh->ExecuteJavascriptInWebFrameCallbackResult(toString16(xPath), toString16(javaScript), callback); + } +} |