Skip to content

Commit f40ff8f

Browse files
seungsoo47bwikbs
authored andcommitted
[webview_flutter] Implement addJavascriptChannels() (flutter-tizen#27)
* This plugin exposes a single method called `postMessage` to JavaScript. * This method sends a message over a method channel to the Dart code. Signed-off-by: Seungsoo Lee <[email protected]>
1 parent 598ddb6 commit f40ff8f

File tree

3 files changed

+76
-24
lines changed

3 files changed

+76
-24
lines changed

packages/webview_flutter/tizen/src/webview.cc

+61-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include <Ecore_IMF_Evas.h>
55
#include <Ecore_Input_Evas.h>
6-
#include <flutter/method_channel.h>
76
#include <flutter_platform_view.h>
87
#include <flutter_texture_registrar.h>
98

@@ -58,27 +57,72 @@ double ExtractDoubleFromMap(const flutter::EncodableValue& arguments,
5857

5958
WebView::WebView(flutter::PluginRegistrar* registrar, int viewId,
6059
FlutterTextureRegistrar* textureRegistrar, double width,
61-
double height, const std::string initialUrl)
60+
double height, flutter::EncodableMap& params)
6261
: PlatformView(registrar, viewId),
6362
textureRegistrar_(textureRegistrar),
6463
webViewInstance_(nullptr),
65-
currentUrl_(initialUrl),
6664
width_(width),
6765
height_(height),
6866
tbmSurface_(nullptr) {
6967
SetTextureId(FlutterRegisterExternalTexture(textureRegistrar_));
7068
InitWebView();
71-
auto channel =
72-
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
73-
GetPluginRegistrar()->messenger(), GetChannelName(),
74-
&flutter::StandardMethodCodec::GetInstance());
75-
channel->SetMethodCallHandler(
69+
70+
channel_ = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
71+
GetPluginRegistrar()->messenger(), GetChannelName(),
72+
&flutter::StandardMethodCodec::GetInstance());
73+
channel_->SetMethodCallHandler(
7674
[webview = this](const auto& call, auto result) {
7775
webview->HandleMethodCall(call, std::move(result));
7876
});
77+
78+
auto initialUrl = params[flutter::EncodableValue("initialUrl")];
79+
if (std::holds_alternative<std::string>(initialUrl)) {
80+
currentUrl_ = std::get<std::string>(initialUrl);
81+
} else {
82+
currentUrl_ = "about:blank";
83+
}
84+
85+
auto names = params[flutter::EncodableValue("javascriptChannelNames")];
86+
if (std::holds_alternative<flutter::EncodableList>(names)) {
87+
auto nameList = std::get<flutter::EncodableList>(names);
88+
for (size_t i = 0; i < nameList.size(); i++) {
89+
if (std::holds_alternative<std::string>(nameList[i])) {
90+
RegisterJavaScriptChannelName(std::get<std::string>(nameList[i]));
91+
}
92+
}
93+
}
94+
7995
webViewInstance_->LoadURL(currentUrl_);
8096
}
8197

98+
/**
99+
* Added as a JavaScript interface to the WebView for any JavaScript channel
100+
* that the Dart code sets up.
101+
*
102+
* Exposes a single method named `postMessage` to JavaScript, which sends a
103+
* message over a method channel to the Dart code.
104+
*/
105+
void WebView::RegisterJavaScriptChannelName(const std::string& name) {
106+
LOG_DEBUG("RegisterJavaScriptChannelName(channelName: %s)\n", name.c_str());
107+
108+
std::function<std::string(const std::string&)> cb =
109+
[this, name](const std::string& message) -> std::string {
110+
LOG_DEBUG("Invoke JavaScriptChannel(message: %s)\n", message.c_str());
111+
flutter::EncodableMap map;
112+
map.insert(std::make_pair<flutter::EncodableValue, flutter::EncodableValue>(
113+
flutter::EncodableValue("channel"), flutter::EncodableValue(name)));
114+
map.insert(std::make_pair<flutter::EncodableValue, flutter::EncodableValue>(
115+
flutter::EncodableValue("message"), flutter::EncodableValue(message)));
116+
117+
std::unique_ptr<flutter::EncodableValue> args =
118+
std::make_unique<flutter::EncodableValue>(map);
119+
channel_->InvokeMethod("javascriptChannelMessage", std::move(args));
120+
return "success";
121+
};
122+
123+
webViewInstance_->AddJavaScriptInterface(name, "postMessage", cb);
124+
}
125+
82126
WebView::~WebView() { Dispose(); }
83127

84128
std::string WebView::GetChannelName() {
@@ -543,7 +587,15 @@ void WebView::HandleMethodCall(
543587
result->Error("Invalid Arguments", "Invalid Arguments");
544588
}
545589
} else if (methodName.compare("addJavascriptChannels") == 0) {
546-
result->NotImplemented();
590+
if (std::holds_alternative<flutter::EncodableList>(arguments)) {
591+
auto nameList = std::get<flutter::EncodableList>(arguments);
592+
for (size_t i = 0; i < nameList.size(); i++) {
593+
if (std::holds_alternative<std::string>(nameList[i])) {
594+
RegisterJavaScriptChannelName(std::get<std::string>(nameList[i]));
595+
}
596+
}
597+
}
598+
result->Success();
547599
} else if (methodName.compare("removeJavascriptChannels") == 0) {
548600
result->NotImplemented();
549601
} else if (methodName.compare("clearCache") == 0) {

packages/webview_flutter/tizen/src/webview.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef FLUTTER_PLUGIN_WEBVIEW_FLUTTER_TIZEN_WEVIEW_H_
22
#define FLUTTER_PLUGIN_WEBVIEW_FLUTTER_TIZEN_WEVIEW_H_
33

4+
#include <flutter/method_channel.h>
45
#include <flutter/plugin_registrar.h>
56
#include <flutter/standard_message_codec.h>
67
#include <flutter/standard_method_codec.h>
@@ -21,7 +22,7 @@ class WebView : public PlatformView {
2122
public:
2223
WebView(flutter::PluginRegistrar* registrar, int viewId,
2324
FlutterTextureRegistrar* textureRegistrar, double width,
24-
double height, const std::string initialUrl);
25+
double height, flutter::EncodableMap& params);
2526
~WebView();
2627
virtual void Dispose() override;
2728
virtual void Resize(double width, double height) override;
@@ -43,13 +44,17 @@ class WebView : public PlatformView {
4344
std::string GetChannelName();
4445
const std::string& GetCurrentUrl() { return currentUrl_; }
4546
void InitWebView();
47+
48+
void RegisterJavaScriptChannelName(const std::string& name);
49+
4650
FlutterTextureRegistrar* textureRegistrar_;
4751
LWE::WebContainer* webViewInstance_;
4852
std::string currentUrl_;
4953
double width_;
5054
double height_;
5155
tbm_surface_h tbmSurface_;
5256
bool isMouseLButtonDown_;
57+
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> channel_;
5358
};
5459

5560
#endif // FLUTTER_PLUGIN_WEBVIEW_FLUTTER_TIZEN_WEVIEW_H_
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
#include "webview_factory.h"
2+
13
#include <flutter/method_channel.h>
24
#include <flutter/plugin_registrar.h>
3-
#include <flutter/standard_method_codec.h>
45
#include <flutter/standard_message_codec.h>
6+
#include <flutter/standard_method_codec.h>
57
#include <flutter_platform_view.h>
68
#include <flutter_texture_registrar.h>
79

@@ -11,9 +13,8 @@
1113
#include <string>
1214

1315
#include "log.h"
14-
#include "webview_flutter_tizen_plugin.h"
15-
#include "webview_factory.h"
1616
#include "lwe/LWEWebView.h"
17+
#include "webview_flutter_tizen_plugin.h"
1718

1819
WebViewFactory::WebViewFactory(flutter::PluginRegistrar* registrar,
1920
FlutterTextureRegistrar* textureRegistrar)
@@ -30,19 +31,13 @@ WebViewFactory::WebViewFactory(flutter::PluginRegistrar* registrar,
3031

3132
PlatformView* WebViewFactory::Create(int viewId, double width, double height,
3233
const std::vector<uint8_t>& createParams) {
33-
std::string initialUrl = "about:blank";
34-
auto decoded_value = *GetCodec().DecodeMessage(createParams);
35-
if (std::holds_alternative<flutter::EncodableMap>(decoded_value)) {
36-
flutter::EncodableMap createParams =
37-
std::get<flutter::EncodableMap>(decoded_value);
38-
flutter::EncodableValue initialUrlValue =
39-
createParams[flutter::EncodableValue("initialUrl")];
40-
if (std::holds_alternative<std::string>(initialUrlValue)) {
41-
initialUrl = std::get<std::string>(initialUrlValue);
42-
}
34+
flutter::EncodableMap params;
35+
auto decodedValue = *GetCodec().DecodeMessage(createParams);
36+
if (std::holds_alternative<flutter::EncodableMap>(decodedValue)) {
37+
params = std::get<flutter::EncodableMap>(decodedValue);
4338
}
4439
return new WebView(GetPluginRegistrar(), viewId, textureRegistrar_, width,
45-
height, initialUrl);
40+
height, params);
4641
}
4742

4843
void WebViewFactory::Dispose() { LWE::LWE::Finalize(); }

0 commit comments

Comments
 (0)