2019-07-14 15:47:29 +03:00
|
|
|
/*
|
|
|
|
* MIT License
|
|
|
|
*
|
2019-11-16 21:51:46 +03:00
|
|
|
* Copyright (c) 2017 Serge Zaitsev, (c) 2019 Tauri Apps
|
2019-07-14 15:47:29 +03:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
#ifndef WEBVIEW_H
|
|
|
|
#define WEBVIEW_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef WEBVIEW_STATIC
|
|
|
|
#define WEBVIEW_API static
|
|
|
|
#else
|
|
|
|
#define WEBVIEW_API extern
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2019-09-12 22:37:40 +03:00
|
|
|
#include <stdarg.h>
|
2019-07-14 15:47:29 +03:00
|
|
|
|
|
|
|
struct webview;
|
|
|
|
|
|
|
|
typedef void (*webview_external_invoke_cb_t)(struct webview *w,
|
|
|
|
const char *arg);
|
|
|
|
|
|
|
|
struct webview {
|
|
|
|
const char *url;
|
|
|
|
const char *title;
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
int resizable;
|
|
|
|
int debug;
|
|
|
|
webview_external_invoke_cb_t external_invoke_cb;
|
|
|
|
struct webview_priv priv;
|
|
|
|
void *userdata;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum webview_dialog_type {
|
|
|
|
WEBVIEW_DIALOG_TYPE_OPEN = 0,
|
|
|
|
WEBVIEW_DIALOG_TYPE_SAVE = 1,
|
|
|
|
WEBVIEW_DIALOG_TYPE_ALERT = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
#define WEBVIEW_DIALOG_FLAG_FILE (0 << 0)
|
|
|
|
#define WEBVIEW_DIALOG_FLAG_DIRECTORY (1 << 0)
|
|
|
|
|
|
|
|
#define WEBVIEW_DIALOG_FLAG_INFO (1 << 1)
|
|
|
|
#define WEBVIEW_DIALOG_FLAG_WARNING (2 << 1)
|
|
|
|
#define WEBVIEW_DIALOG_FLAG_ERROR (3 << 1)
|
|
|
|
#define WEBVIEW_DIALOG_FLAG_ALERT_MASK (3 << 1)
|
|
|
|
|
|
|
|
typedef void (*webview_dispatch_fn)(struct webview *w, void *arg);
|
|
|
|
|
|
|
|
struct webview_dispatch_arg {
|
|
|
|
webview_dispatch_fn fn;
|
|
|
|
struct webview *w;
|
|
|
|
void *arg;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define DEFAULT_URL \
|
|
|
|
"data:text/" \
|
|
|
|
"html,%3C%21DOCTYPE%20html%3E%0A%3Chtml%20lang=%22en%22%3E%0A%3Chead%3E%" \
|
|
|
|
"3Cmeta%20charset=%22utf-8%22%3E%3Cmeta%20http-equiv=%22X-UA-Compatible%22%" \
|
|
|
|
"20content=%22IE=edge%22%3E%3C%2Fhead%3E%0A%3Cbody%3E%3Cdiv%20id=%22app%22%" \
|
|
|
|
"3E%3C%2Fdiv%3E%3Cscript%20type=%22text%2Fjavascript%22%3E%3C%2Fscript%3E%" \
|
|
|
|
"3C%2Fbody%3E%0A%3C%2Fhtml%3E"
|
|
|
|
|
|
|
|
#define CSS_INJECT_FUNCTION \
|
|
|
|
"(function(e){var " \
|
|
|
|
"t=document.createElement('style'),d=document.head||document." \
|
|
|
|
"getElementsByTagName('head')[0];t.setAttribute('type','text/" \
|
|
|
|
"css'),t.styleSheet?t.styleSheet.cssText=e:t.appendChild(document." \
|
|
|
|
"createTextNode(e)),d.appendChild(t)})"
|
|
|
|
|
|
|
|
static const char *webview_check_url(const char *url) {
|
|
|
|
if (url == NULL || strlen(url) == 0) {
|
|
|
|
return DEFAULT_URL;
|
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
|
|
|
WEBVIEW_API int webview(const char *title, const char *url, int width,
|
|
|
|
int height, int resizable);
|
|
|
|
|
|
|
|
WEBVIEW_API int webview_init(struct webview *w);
|
|
|
|
WEBVIEW_API int webview_loop(struct webview *w, int blocking);
|
|
|
|
WEBVIEW_API int webview_eval(struct webview *w, const char *js);
|
|
|
|
WEBVIEW_API int webview_inject_css(struct webview *w, const char *css);
|
|
|
|
WEBVIEW_API void webview_set_title(struct webview *w, const char *title);
|
|
|
|
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen);
|
|
|
|
WEBVIEW_API void webview_set_color(struct webview *w, uint8_t r, uint8_t g,
|
|
|
|
uint8_t b, uint8_t a);
|
|
|
|
WEBVIEW_API void webview_dialog(struct webview *w,
|
|
|
|
enum webview_dialog_type dlgtype, int flags,
|
|
|
|
const char *title, const char *arg,
|
|
|
|
char *result, size_t resultsz);
|
|
|
|
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
|
|
|
|
void *arg);
|
|
|
|
WEBVIEW_API void webview_terminate(struct webview *w);
|
|
|
|
WEBVIEW_API void webview_exit(struct webview *w);
|
|
|
|
WEBVIEW_API void webview_debug(const char *format, ...);
|
|
|
|
WEBVIEW_API void webview_print_log(const char *s);
|
|
|
|
|
|
|
|
#ifdef WEBVIEW_IMPLEMENTATION
|
|
|
|
#undef WEBVIEW_IMPLEMENTATION
|
|
|
|
|
|
|
|
WEBVIEW_API int webview(const char *title, const char *url, int width,
|
|
|
|
int height, int resizable) {
|
|
|
|
struct webview webview;
|
|
|
|
memset(&webview, 0, sizeof(webview));
|
|
|
|
webview.title = title;
|
|
|
|
webview.url = url;
|
|
|
|
webview.width = width;
|
|
|
|
webview.height = height;
|
|
|
|
webview.resizable = resizable;
|
|
|
|
int r = webview_init(&webview);
|
|
|
|
if (r != 0) {
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
while (webview_loop(&webview, 1) == 0) {
|
|
|
|
}
|
|
|
|
webview_exit(&webview);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
WEBVIEW_API void webview_debug(const char *format, ...) {
|
|
|
|
char buf[4096];
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
vsnprintf(buf, sizeof(buf), format, ap);
|
|
|
|
webview_print_log(buf);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int webview_js_encode(const char *s, char *esc, size_t n) {
|
|
|
|
int r = 1; /* At least one byte for trailing zero */
|
|
|
|
for (; *s; s++) {
|
|
|
|
const unsigned char c = *s;
|
|
|
|
if (c >= 0x20 && c < 0x80 && strchr("<>\\'\"", c) == NULL) {
|
|
|
|
if (n > 0) {
|
|
|
|
*esc++ = c;
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
r++;
|
|
|
|
} else {
|
|
|
|
if (n > 0) {
|
|
|
|
snprintf(esc, n, "\\x%02x", (int)c);
|
|
|
|
esc += 4;
|
|
|
|
n -= 4;
|
|
|
|
}
|
|
|
|
r += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
WEBVIEW_API int webview_inject_css(struct webview *w, const char *css) {
|
|
|
|
int n = webview_js_encode(css, NULL, 0);
|
|
|
|
char *esc = (char *)calloc(1, sizeof(CSS_INJECT_FUNCTION) + n + 4);
|
|
|
|
if (esc == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
char *js = (char *)calloc(1, n);
|
|
|
|
webview_js_encode(css, js, n);
|
|
|
|
snprintf(esc, sizeof(CSS_INJECT_FUNCTION) + n + 4, "%s(\"%s\")",
|
|
|
|
CSS_INJECT_FUNCTION, js);
|
|
|
|
int r = webview_eval(w, esc);
|
|
|
|
free(js);
|
|
|
|
free(esc);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WEBVIEW_IMPLEMENTATION */
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* WEBVIEW_H */
|