ui/cocoa/webview.m

changeset 113
dde28a806552
equal deleted inserted replaced
112:c3f2f16fa4b8 113:dde28a806552
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2025 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #import "webview.h"
30 #import "Container.h"
31
32 UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs *args) {
33 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_GENERIC);
34
35 WKWebView *webview = [[WKWebView alloc]init];
36
37 UiLayout layout = UI_ARGS2LAYOUT(args);
38 ui_container_add(obj, webview, &layout);
39
40 if(var) {
41 UiGeneric *value = var->value;
42 value->get = ui_webview_get;
43 value->get_type = ui_webview_get_type;
44 value->set = ui_webview_set;
45 value->destroy = ui_webview_destroy;
46 value->obj = (__bridge void*)webview;
47 if(value->value) {
48 ui_webview_set(value, value->value, UI_WEBVIEW_OBJECT_TYPE);
49 } else {
50 UiWebViewData *data = malloc(sizeof(UiWebViewData));
51 memset(data, 0, sizeof(UiWebViewData));
52 data->webview = (__bridge void*)webview;
53 data->javascript = TRUE;
54 data->zoom = 1;
55 value->value = value;
56 }
57 }
58
59 return (__bridge void*)webview;
60 }
61
62 UiWebViewData* ui_webview_data_clone(UiWebViewData *data) {
63 UiWebViewData *newdata = malloc(sizeof(UiWebViewData));
64 memset(newdata, 0, sizeof(UiWebViewData));
65 newdata->zoom = 1;
66 newdata->javascript = TRUE;
67
68 if(data) {
69 newdata->uri = data->uri ? strdup(data->uri) : NULL;
70 newdata->mimetype = data->mimetype ? strdup(data->mimetype) : NULL;
71 newdata->encoding = data->encoding ? strdup(data->encoding) : NULL;
72 newdata->type = data->type;
73 newdata->javascript = data->javascript;
74 newdata->zoom = data->zoom;
75 if(data->content && data->contentlength > 0) {
76 newdata->content = malloc(data->contentlength + 1);
77 memcpy(newdata->content, data->content, data->contentlength);
78 newdata->content[data->contentlength] = 0;
79 newdata->contentlength = data->contentlength;
80 }
81 }
82
83 return newdata;
84 }
85
86 void ui_webview_data_free(UiWebViewData *data) {
87 if(!data) {
88 return;
89 }
90 free(data->uri);
91 free(data->mimetype);
92 free(data->encoding);
93 free(data->content);
94 free(data);
95 }
96
97 void* ui_webview_get(UiGeneric *g) {
98 UiWebViewData *data = g->value;
99 WKWebView *webview = (__bridge WKWebView*)g->obj;
100
101 if(data->type == WEBVIEW_CONTENT_URL) {
102 (void)ui_webview_get_uri(g); // this updates data->uri
103 }
104 data->zoom = webview.pageZoom;
105
106 return ui_webview_data_clone(g->value);
107 }
108
109 const char* ui_webview_get_type(UiGeneric *g) {
110 return UI_WEBVIEW_OBJECT_TYPE;
111 }
112
113 int ui_webview_set(UiGeneric *g, void *data, const char *type) {
114 if(!data || !type) {
115 return 1;
116 }
117 if(strcmp(type, UI_WEBVIEW_OBJECT_TYPE)) {
118 return 1;
119 }
120 ui_webview_data_free(g->value);
121 g->value = ui_webview_data_clone(data);
122
123 WKWebView *webview = (__bridge WKWebView*)g->obj;
124 UiWebViewData *webd = data;
125 if(webd->type == WEBVIEW_CONTENT_URL) {
126 const char *uri = webd->uri ? webd->uri : "about:blank";
127 NSURL *url = [NSURL URLWithString:[[NSString alloc] initWithUTF8String:uri]];
128 if(url) {
129 NSURLRequest *req = [NSURLRequest requestWithURL:url];
130 if(req) {
131 [webview loadRequest:req];
132 }
133 }
134 } else {
135 NSString *mimetype = [[NSString alloc]initWithUTF8String: webd->mimetype ? webd->mimetype : "text/plain"];
136 NSString *encoding = [[NSString alloc]initWithUTF8String: webd->encoding ? webd->encoding : "UTF-8"];
137 NSString *urlStr = [[NSString alloc]initWithUTF8String: webd->uri ? webd->uri : "file:///"];
138 NSURL *url = [NSURL URLWithString:urlStr];
139 NSData *content = [NSData dataWithBytes:webd->content length:webd->contentlength];
140 if(!url) {
141 url = [NSURL URLWithString:@"about:blank"];
142 }
143 [webview loadData:content MIMEType:mimetype characterEncodingName:encoding baseURL:url];
144 }
145
146 webview.pageZoom = webd->zoom;
147
148 return 1;
149 }
150
151 void ui_webview_destroy(UiGeneric *g) {
152 ui_webview_data_free(g->value);
153 g->value = NULL;
154 }
155
156
157 void ui_webview_load_url(UiGeneric *g, const char *url) {
158 WKWebView *webview = (__bridge WKWebView*)g->obj;
159 UiWebViewData *data = g->value;
160 data->type = WEBVIEW_CONTENT_URL;
161
162 if(!url) {
163 url = "about:blank";
164 }
165
166 NSURL *nsurl = [NSURL URLWithString:[[NSString alloc] initWithUTF8String:url]];
167 if(nsurl) {
168 NSURLRequest *req = [NSURLRequest requestWithURL:nsurl];
169 if(req) {
170 [webview loadRequest:req];
171 }
172 }
173 }
174
175 void ui_webview_load_content(
176 UiGeneric *g,
177 const char *uri,
178 const char *content,
179 size_t contentlength,
180 const char *mimetype,
181 const char *encoding)
182 {
183 UiWebViewData *data = g->value;
184 WKWebView *webview = (__bridge WKWebView*)g->obj;
185
186 data->type = WEBVIEW_CONTENT_CONTENT;
187
188 free(data->uri);
189 data->uri = NULL;
190 free(data->mimetype);
191 free(data->encoding);
192 free(data->content);
193 data->type = WEBVIEW_CONTENT_URL;
194
195 data->content = malloc(contentlength+1);
196 memcpy(data->content, content, contentlength);
197 data->content[contentlength] = 0;
198
199 if(!mimetype) {
200 mimetype = "text/plain";
201 }
202 if(!encoding) {
203 encoding = "UTF-8";
204 }
205
206 data->mimetype = strdup(mimetype);
207 data->encoding = strdup(encoding);
208
209 NSString *mtype = [[NSString alloc]initWithUTF8String:mimetype];
210 NSString *enc = [[NSString alloc]initWithUTF8String:encoding];
211 NSData *ct = [NSData dataWithBytes:content length:contentlength];
212 NSURL *url;
213 if(uri) {
214 NSString *uriStr = [[NSString alloc]initWithUTF8String:uri];
215 url = [NSURL URLWithString:uriStr];
216 } else {
217 url = [NSURL URLWithString:@"file:///"];
218 }
219 [webview loadData:ct MIMEType:mtype characterEncodingName:enc baseURL:url];
220 }
221
222
223 void ui_webview_reload(UiGeneric *g) {
224 WKWebView *webview = (__bridge WKWebView*)g->obj;
225 [webview reload];
226 }
227
228 UiBool ui_webview_can_go_back(UiGeneric *g) {
229 return FALSE;
230 }
231
232 UiBool ui_webview_can_go_forward(UiGeneric *g) {
233 return FALSE;
234 }
235
236 void ui_webview_go_back(UiGeneric *g) {
237
238 }
239
240 void ui_webview_go_forward(UiGeneric *g) {
241
242 }
243
244 const char * ui_webview_get_uri(UiGeneric *g) {
245 UiWebViewData *data = g->value;
246 WKWebView *webview = (__bridge WKWebView*)g->obj;
247
248 free(data->uri);
249 data->uri = NULL;
250
251 NSURL *url = webview.URL;
252 if(url) {
253 NSString *s = [url absoluteString];
254 if(s) {
255 data->uri = strdup(s.UTF8String);
256 }
257 }
258 return data->uri;
259 }
260
261 void ui_webview_enable_javascript(UiGeneric *g, UiBool enable) {
262 // unsupported
263 }
264
265 void ui_webview_set_zoom(UiGeneric *g, double zoom) {
266 WKWebView *webview = (__bridge WKWebView*)g->obj;
267 webview.pageZoom = zoom;
268 }
269
270 double ui_webview_get_zoom(UiGeneric *g) {
271 WKWebView *webview = (__bridge WKWebView*)g->obj;
272 return webview.pageZoom;
273 }

mercurial