janela 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -1
- package/bin/janela.mjs +262 -12
- package/package.json +4 -3
- package/runtime/ios.ts +483 -0
- package/shim/ios/app.cc +330 -0
- package/templates/janela.conf.json +5 -0
- package/templates/react/files/janela.conf.json +5 -0
- package/templates/solid/files/janela.conf.json +5 -0
- package/templates/svelte/files/janela.conf.json +5 -0
- package/templates/vue/files/janela.conf.json +5 -0
- package/vendor-webview/core/include/webview/backends.hh +1 -0
- package/vendor-webview/core/include/webview/detail/backends/cocoa_webkit.hh +4 -1
- package/vendor-webview/core/include/webview/detail/backends/uikit_webkit.hh +460 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSBundle.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSInvocation.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSMethodSignature.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSNotification.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSNumber.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSObject.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSPoint.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSRect.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSSize.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSString.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSURL.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSURLRequest.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSValue.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/types.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/objc/Class.hh +4 -1
- package/vendor-webview/core/include/webview/detail/platform/darwin/objc/autoreleasepool.hh +4 -1
- package/vendor-webview/core/include/webview/detail/platform/darwin/objc/invoke.hh +4 -1
- package/vendor-webview/core/include/webview/detail/platform/darwin/objc/memory.hh +4 -1
- package/vendor-webview/core/include/webview/detail/platform/darwin/objc/objc.hh +4 -1
- package/vendor-webview/core/include/webview/detail/platform/darwin/uikit/UIApplication.hh +80 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/uikit/UIScreen.hh +57 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/uikit/UIView.hh +79 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/uikit/UIViewController.hh +70 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/uikit/UIWindow.hh +67 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/uikit/uikit.hh +43 -0
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/WKOpenPanelParameters.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/WKScriptMessage.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/WKUserContentController.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/WKUserScript.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/WKWebView.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/WKWebViewConfiguration.hh +4 -2
- package/vendor-webview/core/include/webview/detail/platform/darwin/webkit/webkit.hh +4 -2
- package/vendor-webview/core/include/webview/macros.h +12 -2
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MIT License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017 Serge Zaitsev
|
|
5
|
+
* Copyright (c) 2022 Steffen André Langnes
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
|
15
|
+
* all copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
#ifndef WEBVIEW_BACKENDS_UIKIT_WEBKIT_HH
|
|
27
|
+
#define WEBVIEW_BACKENDS_UIKIT_WEBKIT_HH
|
|
28
|
+
|
|
29
|
+
#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
30
|
+
|
|
31
|
+
#include "../../macros.h"
|
|
32
|
+
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_UIKIT)
|
|
34
|
+
|
|
35
|
+
//
|
|
36
|
+
// ====================================================================
|
|
37
|
+
//
|
|
38
|
+
// This implementation uses the UIKit WKWebView backend on iOS and its
|
|
39
|
+
// derivatives. Like the Cocoa backend it is written using the ObjC runtime
|
|
40
|
+
// rather than Objective-C, so the file compiles as plain C++. Pass
|
|
41
|
+
// "-framework UIKit -framework WebKit" to the linker.
|
|
42
|
+
//
|
|
43
|
+
// How this differs from the Cocoa backend, and why:
|
|
44
|
+
//
|
|
45
|
+
// * UIApplicationMain() never returns. On macOS the Cocoa backend starts
|
|
46
|
+
// and stops the run loop during construction so that it can create its
|
|
47
|
+
// window before run() is called; that is not possible here. Instead the
|
|
48
|
+
// web view is built eagerly in the constructor (a WKWebView does not need
|
|
49
|
+
// a window to exist) and only the UIWindow and root view controller are
|
|
50
|
+
// created when the application finishes launching. Everything that acts
|
|
51
|
+
// on the web view — navigate, set_html, init scripts, bind — therefore
|
|
52
|
+
// still works before run().
|
|
53
|
+
//
|
|
54
|
+
// * An iOS application cannot exit itself; Apple's guidance is that the
|
|
55
|
+
// system terminates apps. terminate() is accordingly a no-op.
|
|
56
|
+
//
|
|
57
|
+
// * A phone has no window to title or resize: the window is the screen.
|
|
58
|
+
// set_title() sets the root view controller's title, which is visible
|
|
59
|
+
// only if an embedder puts it in a navigation stack, and set_size() is
|
|
60
|
+
// a no-op. Both report success so that portable code does not have to
|
|
61
|
+
// branch on the platform.
|
|
62
|
+
//
|
|
63
|
+
// ====================================================================
|
|
64
|
+
//
|
|
65
|
+
|
|
66
|
+
#include "../../types.hh"
|
|
67
|
+
#include "../engine_base.hh"
|
|
68
|
+
#include "../platform/darwin/cocoa/NSNotification.hh"
|
|
69
|
+
#include "../platform/darwin/cocoa/NSNumber.hh"
|
|
70
|
+
#include "../platform/darwin/cocoa/NSObject.hh"
|
|
71
|
+
#include "../platform/darwin/cocoa/NSRect.hh"
|
|
72
|
+
#include "../platform/darwin/cocoa/NSString.hh"
|
|
73
|
+
#include "../platform/darwin/cocoa/NSURL.hh"
|
|
74
|
+
#include "../platform/darwin/cocoa/NSURLRequest.hh"
|
|
75
|
+
#include "../platform/darwin/cocoa/NSValue.hh"
|
|
76
|
+
#include "../platform/darwin/objc/objc.hh"
|
|
77
|
+
#include "../platform/darwin/uikit/uikit.hh"
|
|
78
|
+
#include "../platform/darwin/webkit/webkit.hh"
|
|
79
|
+
#include "../user_script.hh"
|
|
80
|
+
|
|
81
|
+
#include <atomic>
|
|
82
|
+
#include <functional>
|
|
83
|
+
#include <list>
|
|
84
|
+
#include <memory>
|
|
85
|
+
#include <string>
|
|
86
|
+
|
|
87
|
+
#include <CoreFoundation/CoreFoundation.h>
|
|
88
|
+
#include <dispatch/dispatch.h>
|
|
89
|
+
// <objc/objc-runtime.h> is an umbrella that only exists in the macOS SDK;
|
|
90
|
+
// these two are present on every Apple platform.
|
|
91
|
+
#include <objc/message.h>
|
|
92
|
+
#include <objc/runtime.h>
|
|
93
|
+
|
|
94
|
+
namespace webview {
|
|
95
|
+
namespace detail {
|
|
96
|
+
|
|
97
|
+
class user_script::impl {
|
|
98
|
+
public:
|
|
99
|
+
impl(id script) : m_script{objc::retain(script)} {}
|
|
100
|
+
|
|
101
|
+
~impl() { objc::release(m_script); }
|
|
102
|
+
|
|
103
|
+
impl(const impl &) = delete;
|
|
104
|
+
impl &operator=(const impl &) = delete;
|
|
105
|
+
impl(impl &&) = delete;
|
|
106
|
+
impl &operator=(impl &&) = delete;
|
|
107
|
+
|
|
108
|
+
id get_native() const { return m_script; }
|
|
109
|
+
|
|
110
|
+
private:
|
|
111
|
+
id m_script{};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// Encapsulate backend in its own namespace to avoid polluting the parent
|
|
115
|
+
// namespace when pulling in commonly-used symbols from other namespaces.
|
|
116
|
+
namespace uikit_webkit {
|
|
117
|
+
|
|
118
|
+
using namespace cocoa;
|
|
119
|
+
using namespace uikit;
|
|
120
|
+
using namespace webkit;
|
|
121
|
+
|
|
122
|
+
class uikit_wkwebview_engine : public engine_base {
|
|
123
|
+
public:
|
|
124
|
+
/// @param window When null, the engine creates the UIWindow and root view
|
|
125
|
+
/// controller itself once the application finishes launching. When
|
|
126
|
+
/// non-null it is taken as a UIView the web view is added to, for
|
|
127
|
+
/// embedders that already own the application and its view hierarchy.
|
|
128
|
+
uikit_wkwebview_engine(bool debug, void *window)
|
|
129
|
+
: engine_base{!window}, m_host_view{static_cast<id>(window)} {
|
|
130
|
+
webview_settings(debug);
|
|
131
|
+
if (!owns_window()) {
|
|
132
|
+
attach_to_host_view();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
uikit_wkwebview_engine(const uikit_wkwebview_engine &) = delete;
|
|
137
|
+
uikit_wkwebview_engine &operator=(const uikit_wkwebview_engine &) = delete;
|
|
138
|
+
uikit_wkwebview_engine(uikit_wkwebview_engine &&) = delete;
|
|
139
|
+
uikit_wkwebview_engine &operator=(uikit_wkwebview_engine &&) = delete;
|
|
140
|
+
|
|
141
|
+
virtual ~uikit_wkwebview_engine() {
|
|
142
|
+
objc::autoreleasepool arp;
|
|
143
|
+
if (m_webview) {
|
|
144
|
+
objc::release(m_webview);
|
|
145
|
+
m_webview = nullptr;
|
|
146
|
+
}
|
|
147
|
+
if (m_controller) {
|
|
148
|
+
objc::release(m_controller);
|
|
149
|
+
m_controller = nullptr;
|
|
150
|
+
}
|
|
151
|
+
if (m_window) {
|
|
152
|
+
objc::release(m_window);
|
|
153
|
+
m_window = nullptr;
|
|
154
|
+
}
|
|
155
|
+
if (m_app_delegate) {
|
|
156
|
+
objc::release(m_app_delegate);
|
|
157
|
+
m_app_delegate = nullptr;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected:
|
|
162
|
+
result<void *> window_impl() override {
|
|
163
|
+
if (m_window) {
|
|
164
|
+
return m_window;
|
|
165
|
+
}
|
|
166
|
+
// Before the application has finished launching there is no window yet.
|
|
167
|
+
return error_info{WEBVIEW_ERROR_INVALID_STATE};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
result<void *> widget_impl() override {
|
|
171
|
+
if (m_webview) {
|
|
172
|
+
return m_webview;
|
|
173
|
+
}
|
|
174
|
+
return error_info{WEBVIEW_ERROR_INVALID_STATE};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
result<void *> browser_controller_impl() override {
|
|
178
|
+
if (m_webview) {
|
|
179
|
+
return m_webview;
|
|
180
|
+
}
|
|
181
|
+
return error_info{WEBVIEW_ERROR_INVALID_STATE};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/// An iOS application cannot terminate itself in a way Apple supports, so
|
|
185
|
+
/// this does nothing. It reports success rather than an error so that code
|
|
186
|
+
/// written against the desktop backends keeps working unchanged.
|
|
187
|
+
noresult terminate_impl() override { return {}; }
|
|
188
|
+
|
|
189
|
+
/// Enters UIApplicationMain, which does not return. Anything an embedder
|
|
190
|
+
/// wants to happen must therefore be arranged before calling run(), or from
|
|
191
|
+
/// a dispatched callback afterwards.
|
|
192
|
+
noresult run_impl() override {
|
|
193
|
+
objc::autoreleasepool arp;
|
|
194
|
+
if (!owns_window()) {
|
|
195
|
+
// The embedder owns the application and is running its own loop.
|
|
196
|
+
return {};
|
|
197
|
+
}
|
|
198
|
+
m_app_delegate = create_app_delegate();
|
|
199
|
+
set_associated_webview(m_app_delegate, this);
|
|
200
|
+
UIApplication_main(nullptr,
|
|
201
|
+
NSString_stringWithUTF8String(app_delegate_class_name));
|
|
202
|
+
return {};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
noresult dispatch_impl(std::function<void()> f) override {
|
|
206
|
+
dispatch_async_f(dispatch_get_main_queue(), new dispatch_fn_t(f),
|
|
207
|
+
(dispatch_function_t)([](void *arg) {
|
|
208
|
+
auto f = static_cast<dispatch_fn_t *>(arg);
|
|
209
|
+
(*f)();
|
|
210
|
+
delete f;
|
|
211
|
+
}));
|
|
212
|
+
return {};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/// A phone has no window chrome to put a title in. The title is set on the
|
|
216
|
+
/// root view controller, where it is visible only if the embedder places
|
|
217
|
+
/// that controller inside a navigation stack.
|
|
218
|
+
noresult set_title_impl(const std::string &title) override {
|
|
219
|
+
objc::autoreleasepool arp;
|
|
220
|
+
if (m_controller) {
|
|
221
|
+
UIViewController_set_title(m_controller, title);
|
|
222
|
+
}
|
|
223
|
+
m_title = title;
|
|
224
|
+
return {};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/// The window is the screen: an app does not choose its size. Accepted and
|
|
228
|
+
/// ignored so that portable code does not have to branch on the platform.
|
|
229
|
+
noresult set_size_impl(int /*width*/, int /*height*/,
|
|
230
|
+
webview_hint_t /*hints*/) override {
|
|
231
|
+
return {};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
noresult navigate_impl(const std::string &url) override {
|
|
235
|
+
objc::autoreleasepool arp;
|
|
236
|
+
WKWebView_loadRequest(
|
|
237
|
+
m_webview, NSURLRequest_requestWithURL(NSURL_URLWithString(url)));
|
|
238
|
+
return {};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
noresult set_html_impl(const std::string &html) override {
|
|
242
|
+
objc::autoreleasepool arp;
|
|
243
|
+
WKWebView_loadHTMLString(m_webview, NSString_stringWithUTF8String(html),
|
|
244
|
+
nullptr);
|
|
245
|
+
return {};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
noresult eval_impl(const std::string &js) override {
|
|
249
|
+
objc::autoreleasepool arp;
|
|
250
|
+
// URL is null before content has begun loading.
|
|
251
|
+
auto nsurl{WKWebView_get_URL(m_webview)};
|
|
252
|
+
if (!nsurl) {
|
|
253
|
+
return {};
|
|
254
|
+
}
|
|
255
|
+
WKWebView_evaluateJavaScript(m_webview, NSString_stringWithUTF8String(js),
|
|
256
|
+
nullptr);
|
|
257
|
+
return {};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
user_script add_user_script_impl(const std::string &js) override {
|
|
261
|
+
objc::autoreleasepool arp;
|
|
262
|
+
auto wk_script{WKUserScript_withSource(
|
|
263
|
+
NSString_stringWithUTF8String(js),
|
|
264
|
+
WKUserScriptInjectionTimeAtDocumentStart, true)};
|
|
265
|
+
// Script is retained when added.
|
|
266
|
+
WKUserContentController_addUserScript(m_manager, wk_script);
|
|
267
|
+
user_script script{
|
|
268
|
+
js, user_script::impl_ptr{new user_script::impl{wk_script},
|
|
269
|
+
[](user_script::impl *p) { delete p; }}};
|
|
270
|
+
return script;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
void remove_all_user_scripts_impl(
|
|
274
|
+
const std::list<user_script> & /*scripts*/) override {
|
|
275
|
+
objc::autoreleasepool arp;
|
|
276
|
+
WKUserContentController_removeAllUserScripts(m_manager);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
bool are_user_scripts_equal_impl(const user_script &first,
|
|
280
|
+
const user_script &second) override {
|
|
281
|
+
auto *wk_first = first.get_impl().get_native();
|
|
282
|
+
auto *wk_second = second.get_impl().get_native();
|
|
283
|
+
return wk_first == wk_second;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/// UIKit has no equivalent of pulling one event off the queue, so the run
|
|
287
|
+
/// loop is spun for a short interval instead. This is only used to deplete
|
|
288
|
+
/// already-queued work; it is not the application's main loop.
|
|
289
|
+
void run_event_loop_while(std::function<bool()> fn) override {
|
|
290
|
+
objc::autoreleasepool arp;
|
|
291
|
+
while (fn()) {
|
|
292
|
+
objc::autoreleasepool arp2;
|
|
293
|
+
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, true);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
private:
|
|
298
|
+
static constexpr auto app_delegate_class_name = "WebviewUIApplicationDelegate";
|
|
299
|
+
|
|
300
|
+
id create_app_delegate() {
|
|
301
|
+
objc::autoreleasepool arp;
|
|
302
|
+
// Avoid crash due to registering same class twice
|
|
303
|
+
auto cls = objc_lookUpClass(app_delegate_class_name);
|
|
304
|
+
if (!cls) {
|
|
305
|
+
cls = objc_allocateClassPair(objc::get_class("UIResponder"),
|
|
306
|
+
app_delegate_class_name, 0);
|
|
307
|
+
class_addProtocol(cls, objc_getProtocol("UIApplicationDelegate"));
|
|
308
|
+
class_addMethod(
|
|
309
|
+
cls, objc::selector("application:didFinishLaunchingWithOptions:"),
|
|
310
|
+
(IMP)(+[](id self, SEL, id, id) -> BOOL {
|
|
311
|
+
auto w = get_associated_webview(self);
|
|
312
|
+
if (w) {
|
|
313
|
+
w->on_application_did_finish_launching();
|
|
314
|
+
}
|
|
315
|
+
return YES;
|
|
316
|
+
}),
|
|
317
|
+
"c@:@@");
|
|
318
|
+
// UIKit instantiates the delegate class itself, so the instance it
|
|
319
|
+
// creates must be able to find the engine. The association is placed on
|
|
320
|
+
// the class, and looked up through it when the instance is called.
|
|
321
|
+
objc_registerClassPair(cls);
|
|
322
|
+
}
|
|
323
|
+
return objc::Class_new(cls);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
static uikit_wkwebview_engine *get_associated_webview(id object) {
|
|
327
|
+
objc::autoreleasepool arp;
|
|
328
|
+
// The delegate UIKit creates is not the instance we made, so the engine is
|
|
329
|
+
// associated with the class object, which both share.
|
|
330
|
+
id cls = reinterpret_cast<id>(object_getClass(object));
|
|
331
|
+
if (id assoc_obj{objc_getAssociatedObject(cls, "webview")}) {
|
|
332
|
+
uikit_wkwebview_engine *w{};
|
|
333
|
+
NSValue_getValue(assoc_obj, &w, sizeof(w));
|
|
334
|
+
return w;
|
|
335
|
+
}
|
|
336
|
+
return nullptr;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
static void set_associated_webview(id object, uikit_wkwebview_engine *w) {
|
|
340
|
+
objc::autoreleasepool arp;
|
|
341
|
+
id cls = reinterpret_cast<id>(object_getClass(object));
|
|
342
|
+
objc_setAssociatedObject(cls, "webview", NSValue_valueWithPointer(w),
|
|
343
|
+
OBJC_ASSOCIATION_RETAIN);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
id create_script_message_handler() {
|
|
347
|
+
objc::autoreleasepool arp;
|
|
348
|
+
constexpr auto class_name = "WebviewWKScriptMessageHandler";
|
|
349
|
+
// Avoid crash due to registering same class twice
|
|
350
|
+
auto cls = objc_lookUpClass(class_name);
|
|
351
|
+
if (!cls) {
|
|
352
|
+
cls = objc_allocateClassPair(objc::get_class("NSObject"), class_name, 0);
|
|
353
|
+
class_addProtocol(cls, objc_getProtocol("WKScriptMessageHandler"));
|
|
354
|
+
class_addMethod(
|
|
355
|
+
cls, objc::selector("userContentController:didReceiveScriptMessage:"),
|
|
356
|
+
(IMP)(+[](id self, SEL, id, id msg) {
|
|
357
|
+
auto w = get_associated_webview(self);
|
|
358
|
+
if (w) {
|
|
359
|
+
w->on_message(
|
|
360
|
+
NSString_get_UTF8String(WKScriptMessage_get_body(msg)));
|
|
361
|
+
}
|
|
362
|
+
}),
|
|
363
|
+
"v@:@@");
|
|
364
|
+
objc_registerClassPair(cls);
|
|
365
|
+
}
|
|
366
|
+
auto instance{objc::Class_new(cls)};
|
|
367
|
+
set_associated_webview(instance, this);
|
|
368
|
+
return instance;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/// Builds the web view. A WKWebView does not need a window, so everything
|
|
372
|
+
/// except the window itself can be set up before the application launches.
|
|
373
|
+
void webview_settings(bool debug) {
|
|
374
|
+
objc::autoreleasepool arp;
|
|
375
|
+
|
|
376
|
+
auto config{objc::autorelease(WKWebViewConfiguration_new())};
|
|
377
|
+
m_manager = WKWebViewConfiguration_get_userContentController(config);
|
|
378
|
+
|
|
379
|
+
auto preferences = WKWebViewConfiguration_get_preferences(config);
|
|
380
|
+
auto yes_value = NSNumber_numberWithBool(true);
|
|
381
|
+
if (debug) {
|
|
382
|
+
NSObject_setValue_forKey(
|
|
383
|
+
preferences, yes_value,
|
|
384
|
+
NSString_stringWithUTF8String("developerExtrasEnabled"));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
m_webview =
|
|
388
|
+
objc::retain(WKWebView_withFrame(NSRectMake(0, 0, 0, 0), config));
|
|
389
|
+
if (debug) {
|
|
390
|
+
// Inspectable via Safari on OS versions that disable it by default.
|
|
391
|
+
WKWebView_set_inspectable(m_webview, true);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
auto script_message_handler =
|
|
395
|
+
objc::autorelease(create_script_message_handler());
|
|
396
|
+
WKUserContentController_addScriptMessageHandler(
|
|
397
|
+
m_manager, script_message_handler,
|
|
398
|
+
NSString_stringWithUTF8String("__webview__"));
|
|
399
|
+
|
|
400
|
+
add_init_script("function(message) {\n\
|
|
401
|
+
return window.webkit.messageHandlers.__webview__.postMessage(message);\n\
|
|
402
|
+
}");
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/// Embedder-owned case: the caller handed us a UIView to live in.
|
|
406
|
+
void attach_to_host_view() {
|
|
407
|
+
objc::autoreleasepool arp;
|
|
408
|
+
UIView_set_frame(m_webview, UIView_get_bounds(m_host_view));
|
|
409
|
+
UIView_set_autoresizingMask(
|
|
410
|
+
m_webview, static_cast<UIViewAutoresizing>(
|
|
411
|
+
UIViewAutoresizingFlexibleWidth |
|
|
412
|
+
UIViewAutoresizingFlexibleHeight));
|
|
413
|
+
UIView_addSubview(m_host_view, m_webview);
|
|
414
|
+
on_window_created();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/// Engine-owned case: build the window and root view controller now that
|
|
418
|
+
/// UIKit is running, and put the already-built web view inside it.
|
|
419
|
+
void on_application_did_finish_launching() {
|
|
420
|
+
objc::autoreleasepool arp;
|
|
421
|
+
|
|
422
|
+
m_window = objc::retain(
|
|
423
|
+
UIWindow_withFrame(UIScreen_get_bounds(UIScreen_get_mainScreen())));
|
|
424
|
+
m_controller = objc::retain(UIViewController_new());
|
|
425
|
+
if (!m_title.empty()) {
|
|
426
|
+
UIViewController_set_title(m_controller, m_title);
|
|
427
|
+
}
|
|
428
|
+
UIWindow_set_rootViewController(m_window, m_controller);
|
|
429
|
+
|
|
430
|
+
auto root_view = UIViewController_get_view(m_controller);
|
|
431
|
+
UIView_set_frame(m_webview, UIView_get_bounds(root_view));
|
|
432
|
+
UIView_set_autoresizingMask(
|
|
433
|
+
m_webview, static_cast<UIViewAutoresizing>(
|
|
434
|
+
UIViewAutoresizingFlexibleWidth |
|
|
435
|
+
UIViewAutoresizingFlexibleHeight));
|
|
436
|
+
UIView_addSubview(root_view, m_webview);
|
|
437
|
+
|
|
438
|
+
UIWindow_makeKeyAndVisible(m_window);
|
|
439
|
+
on_window_created();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
id m_app_delegate{};
|
|
443
|
+
id m_window{};
|
|
444
|
+
id m_controller{};
|
|
445
|
+
id m_host_view{};
|
|
446
|
+
id m_webview{};
|
|
447
|
+
id m_manager{};
|
|
448
|
+
std::string m_title;
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
} // namespace uikit_webkit
|
|
452
|
+
} // namespace detail
|
|
453
|
+
|
|
454
|
+
using browser_engine = detail::uikit_webkit::uikit_wkwebview_engine;
|
|
455
|
+
|
|
456
|
+
} // namespace webview
|
|
457
|
+
|
|
458
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_UIKIT)
|
|
459
|
+
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
460
|
+
#endif // WEBVIEW_BACKENDS_UIKIT_WEBKIT_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -51,6 +52,7 @@ inline id NSBundle_get_bundlePath(id self) {
|
|
|
51
52
|
} // namespace detail
|
|
52
53
|
} // namespace webview
|
|
53
54
|
|
|
54
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
55
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
56
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
55
57
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
56
58
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSBUNDLE_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -61,6 +62,7 @@ inline void NSInvocation_invoke(id self) {
|
|
|
61
62
|
} // namespace detail
|
|
62
63
|
} // namespace webview
|
|
63
64
|
|
|
64
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
65
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
66
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
65
67
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
66
68
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSInvocation_HH
|
package/vendor-webview/core/include/webview/detail/platform/darwin/cocoa/NSMethodSignature.hh
CHANGED
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -47,6 +48,7 @@ inline id NSMethodSignature_signatureWithObjCTypes(const char *types) {
|
|
|
47
48
|
} // namespace detail
|
|
48
49
|
} // namespace webview
|
|
49
50
|
|
|
50
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
51
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
52
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
51
53
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
52
54
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSMETHODSIGNATURE_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -46,6 +47,7 @@ inline id NSNotification_get_object(id self) {
|
|
|
46
47
|
} // namespace detail
|
|
47
48
|
} // namespace webview
|
|
48
49
|
|
|
49
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
50
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
51
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
50
52
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
51
53
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSNOTIFICATION_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -48,6 +49,7 @@ inline id NSNumber_numberWithBool(bool value) {
|
|
|
48
49
|
} // namespace detail
|
|
49
50
|
} // namespace webview
|
|
50
51
|
|
|
51
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
52
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
53
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
52
54
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
53
55
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSNUMBER_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -46,6 +47,7 @@ inline void NSObject_setValue_forKey(id self, id value, id key) {
|
|
|
46
47
|
} // namespace detail
|
|
47
48
|
} // namespace webview
|
|
48
49
|
|
|
49
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
50
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
51
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
50
52
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
51
53
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSOBJECT_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include <CoreGraphics/CoreGraphics.h>
|
|
36
37
|
|
|
@@ -48,6 +49,7 @@ constexpr inline NSPoint NSPointMake(CGFloat x, CGFloat y) {
|
|
|
48
49
|
} // namespace detail
|
|
49
50
|
} // namespace webview
|
|
50
51
|
|
|
51
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
52
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
53
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
52
54
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
53
55
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSPOINT_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include <CoreGraphics/CoreGraphics.h>
|
|
36
37
|
|
|
@@ -48,6 +49,7 @@ constexpr inline NSRect NSRectMake(CGFloat x, CGFloat y, CGFloat w, CGFloat h) {
|
|
|
48
49
|
} // namespace detail
|
|
49
50
|
} // namespace webview
|
|
50
51
|
|
|
51
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
52
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
53
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
52
54
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
53
55
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSRECT_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include <CoreGraphics/CoreGraphics.h>
|
|
36
37
|
|
|
@@ -48,6 +49,7 @@ constexpr inline NSSize NSSizeMake(CGFloat w, CGFloat h) {
|
|
|
48
49
|
} // namespace detail
|
|
49
50
|
} // namespace webview
|
|
50
51
|
|
|
51
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
52
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
53
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
52
54
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
53
55
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSSIZE_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
|
|
@@ -82,6 +83,7 @@ inline const char *NSString_get_UTF8String(id self) {
|
|
|
82
83
|
} // namespace detail
|
|
83
84
|
} // namespace webview
|
|
84
85
|
|
|
85
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
86
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
87
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
86
88
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
87
89
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSSTRING_HH
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
#include "../../../../macros.h"
|
|
32
32
|
|
|
33
|
-
#if defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
33
|
+
#if defined(WEBVIEW_PLATFORM_DARWIN) && \
|
|
34
|
+
(defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
34
35
|
|
|
35
36
|
#include "../objc/objc.hh"
|
|
36
37
|
#include "NSString.hh"
|
|
@@ -58,6 +59,7 @@ inline id NSURL_URLWithString(const std::string &string) {
|
|
|
58
59
|
} // namespace detail
|
|
59
60
|
} // namespace webview
|
|
60
61
|
|
|
61
|
-
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
62
|
+
#endif // defined(WEBVIEW_PLATFORM_DARWIN) &&
|
|
63
|
+
// (defined(WEBVIEW_COCOA) || defined(WEBVIEW_UIKIT))
|
|
62
64
|
#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
|
|
63
65
|
#endif // WEBVIEW_PLATFORM_DARWIN_COCOA_NSURL_HH
|