Skip to content

Commit

Permalink
Trying to implement instance methods
Browse files Browse the repository at this point in the history
  • Loading branch information
eliassjogreen committed Mar 10, 2020
1 parent ab3cb0f commit c7788aa
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 104 deletions.
30 changes: 3 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ edition = "2018"
crate-type = ["cdylib"]

[dependencies]
futures = "0.3.4"
deno_core = "0.35.0"
web-view = "0.6.0"
webview-sys = "0.4.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ the basics are really implemented yet (apart from opening a webview window).
- [ ] Two-way deno bindings (to call deno from javascript)
- [ ] Multiple windows?
- [ ] Easier importing of scripts, images and css
- [ ] Dialog
- [ ] DialogBuilder and WebViewBuilder
- [ ] Examples
- [ ] Tests
51 changes: 36 additions & 15 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,49 @@
import { prepare } from "https://deno.land/x/plugin_prepare/mod.ts";

export interface Options {
const releaseUrl =
"https://github.com/eliassjogreen/deno_webview/releases/download/0.0.1";

const plugin = await prepare({
name: "deno_webview",
urls: {
mac: `${releaseUrl}/libdeno_webview.dylib`,
win: `${releaseUrl}/deno_webview.dll`,
linux: `${releaseUrl}/libdeno_webview.so`
}
});

interface NewArgs {
title: string;
url: string;
width: number;
height: number;
resizable: boolean;
debug: boolean;
content: string;
}

export async function run(options: Options) {
const releaseUrl =
"https://github.com/eliassjogreen/deno_webview/releases/download/0.0.1";
interface EvalArgs {
js: string;
}

const deno_webview: Deno.Plugin = await prepare({
name: "deno_webview",
urls: {
mac: `${releaseUrl}/libdeno_webview.dylib`,
win: `${releaseUrl}/deno_webview.dll`,
linux: `${releaseUrl}/libdeno_webview.so`
}
});
interface InjectCssArgs {
css: string;
}

const { webview_run } = deno_webview.ops;
interface SetColorArgs {
r: number;
g: number;
b: number;
a: number;
}

interface SetTitleArgs {
title: String;
}

interface SetFullscreenArgs {
fullscreen: boolean;
}

webview_run.dispatch(new TextEncoder().encode(JSON.stringify(options)));
interface LoopArgs {
blocking: number;
}
249 changes: 199 additions & 50 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,199 @@
#[macro_use]
extern crate deno_core;
extern crate futures;
extern crate serde;
extern crate serde_json;

use deno_core::CoreOp;
use deno_core::Op;
use deno_core::PluginInitContext;
use deno_core::ZeroCopyBuf;
use serde::{Deserialize, Serialize};
use web_view::*;

#[derive(Serialize, Deserialize)]
struct Options {
title: String,
width: i32,
height: i32,
resizable: bool,
debug: bool,
content: String,
}

fn init(context: &mut dyn PluginInitContext) {
context.register_op("webview_run", Box::new(op_webview_run));
}
init_fn!(init);

pub fn op_webview_run(data: &[u8], zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
webview_run(std::str::from_utf8(data).unwrap()).unwrap();

Op::Sync(Box::new([0]))
}

fn webview_run<'a>(data: &'a str) -> Result<(), serde_json::Error> {
let options: Options = serde_json::from_str(data)?;

let webview = web_view::builder()
.title(&options.title)
.content(Content::Html(options.content))
.size(options.width, options.height)
.resizable(options.resizable)
.debug(options.debug)
.user_data(())
.invoke_handler(|_webview, _arg| Ok(()))
.build()
.unwrap();
webview.run().unwrap();
Ok(())
}
#[macro_use]
extern crate deno_core;
extern crate serde;
extern crate serde_json;
extern crate webview_sys;

use deno_core::{CoreOp, Op, PluginInitContext, ZeroCopyBuf};
use serde::{Deserialize, Serialize};
use std::{ffi::CString, ptr::null_mut};
use webview_sys::*;

#[derive(Serialize, Deserialize)]
struct NewArgs {
title: String,
url: String,
width: i32,
height: i32,
resizable: bool,
debug: bool,
}

#[derive(Serialize, Deserialize)]
struct EvalArgs {
js: String,
}

#[derive(Serialize, Deserialize)]
struct InjectCssArgs {
css: String,
}

#[derive(Serialize, Deserialize)]
struct SetColorArgs {
r: u8,
g: u8,
b: u8,
a: u8,
}

#[derive(Serialize, Deserialize)]
struct SetTitleArgs {
title: String,
}

#[derive(Serialize, Deserialize)]
struct SetFullscreenArgs {
fullscreen: bool,
}

#[derive(Serialize, Deserialize)]
struct LoopArgs {
blocking: i32,
}

static mut CWEBVIEW: Option<*mut CWebView> = None;

fn init(context: &mut dyn PluginInitContext) {
context.register_op("webview_new", Box::new(op_webview_new));
context.register_op("webview_exit", Box::new(op_webview_exit));
context.register_op("webview_eval", Box::new(op_webview_eval));
context.register_op("webview_inject_css", Box::new(op_webview_inject_css));
context.register_op("webview_set_color", Box::new(op_webview_set_color));
context.register_op("webview_set_title", Box::new(op_webview_set_title));
context.register_op(
"webview_set_fullscreen",
Box::new(op_webview_set_fullscreen),
);
context.register_op("webview_loop", Box::new(op_webview_loop));
}
init_fn!(init);

fn op_webview_new(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_some() {
return Op::Sync(Box::new([false as u8]));
}

let args: NewArgs = serde_json::from_slice(data).unwrap();

let title = CString::new(args.title).unwrap();
let url = CString::new(args.url).unwrap();
let width = args.width;
let height = args.height;
let resizable = args.resizable as i32;
let debug = args.debug as i32;

CWEBVIEW = Some(webview_new(
title.as_ptr(),
url.as_ptr(),
width,
height,
resizable,
debug,
None,
null_mut(),
));

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_exit(_data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

webview_exit(CWEBVIEW.unwrap());

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_eval(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

let args: EvalArgs = serde_json::from_slice(data).unwrap();
let js = CString::new(args.js).unwrap();

webview_eval(CWEBVIEW.unwrap(), js.as_ptr());

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_inject_css(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

let args: InjectCssArgs = serde_json::from_slice(data).unwrap();
let css = CString::new(args.css).unwrap();

webview_inject_css(CWEBVIEW.unwrap(), css.as_ptr());

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_set_color(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

let args: SetColorArgs = serde_json::from_slice(data).unwrap();

webview_set_color(CWEBVIEW.unwrap(), args.r, args.g, args.b, args.a);

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_set_title(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

let args: SetTitleArgs = serde_json::from_slice(data).unwrap();
let title = CString::new(args.title).unwrap();

webview_set_title(CWEBVIEW.unwrap(), title.as_ptr());

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_set_fullscreen(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

let args: SetFullscreenArgs = serde_json::from_slice(data).unwrap();
let fullscreen = args.fullscreen as i32;

webview_set_fullscreen(CWEBVIEW.unwrap(), fullscreen);

Op::Sync(Box::new([true as u8]))
}
}

fn op_webview_loop(data: &[u8], _zero_copy: Option<ZeroCopyBuf>) -> CoreOp {
unsafe {
if CWEBVIEW.is_none() {
return Op::Sync(Box::new([false as u8]));
}

let args: LoopArgs = serde_json::from_slice(data).unwrap();
let result = webview_loop(CWEBVIEW.unwrap(), args.blocking);

Op::Sync(Box::new(result.to_be_bytes()))
}
}

0 comments on commit c7788aa

Please sign in to comment.