Skip to content

Commit

Permalink
Improved the JsValue's returned from CEF, except for arrays and objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
bamidev committed Mar 3, 2024
1 parent 1d1e104 commit 03d7fba
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 19 deletions.
54 changes: 41 additions & 13 deletions c/src/cef/v8_to_string.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef BW_CEF_V8_TO_STRING_HPP
#define BW_CEF_V8_TO_STRING_HPP

#include <string>
#include <vector>


class V8ToString {
public:
Expand All @@ -18,8 +21,13 @@ class V8ToString {
return "null";

// If string
if ( val->IsString() )
return val->GetStringValue();
if ( val->IsString() ) {
std::string string = "\"";
// TODO: Escape the string value:
string += val->GetStringValue();
string += "\"";
return string;
}

// If boolean
if ( val->IsBool() )
Expand All @@ -37,24 +45,44 @@ class V8ToString {
if ( val->IsDouble() )
return intoString( val->GetDoubleValue() );

// If object (unsupported)
if ( val->IsObject() )
return "[object]";

// If array (unsupported)
if ( val->IsArray() )
return "[array]";
// If array
if ( val->IsArray() ) {
std::string string = "[";
for (int i = 0; i < val->GetArrayLength(); i++) {
if (i != 0) {
string += ",";
}
string += convert(val->GetValue(i));
}
string += "]";
return string;
}

// If object
if ( val->IsObject() ) {
std::vector<CefString> keys;
val->GetKeys(keys);
std::string string = "{";
for (size_t i = 0; i < keys.size(); i++) {
std::string key = keys[i];
if (i != 0) {
string += ",";
}
string += key + ":" + convert(val->GetValue(i)).ToString();
}
string += "}";
return string;
}

// If array (unsupported)
if ( val->IsDate() )
return "[date]";
return "date";

// If exception (unsupported)
if ( val->IsFunction() )
return "[function]";
return "function";

// If type is not accounted for, return this string:
return "[unknown type]";
return "unknown type";
}

protected:
Expand Down
5 changes: 5 additions & 0 deletions src/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ impl BrowserWindowHandle {

/// Executes the given javascript code and returns the output as a string.
/// If you don't need the result, see `exec_js`.
///
/// There may be some discrepancies in what JS values are being returned for
/// the same code in different browser engines.
/// For example, Edge WebView2 doesn't return `JsValue::Undefined`, it uses
/// `JsValue::Null` instead.
pub async fn eval_js(&self, js: &str) -> Result<JsValue, JsEvaluationError> {
//
let (tx, rx) = oneshot::channel();
Expand Down
8 changes: 4 additions & 4 deletions src/core/browser_window/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ impl BrowserWindowExt for BrowserWindowImpl {
callback,
data: callback_data,
});

let data_ptr = Box::into_raw(data);

unsafe {
Expand Down Expand Up @@ -246,7 +245,7 @@ unsafe extern "C" fn ffi_handler(
let cmd_string: &str = cmd.into();
let mut args_vec: Vec<JsValue> = Vec::with_capacity(arg_count as usize);
for i in 0..arg_count {
args_vec.push(JsValue::Other((*args.add(i as usize)).into()));
args_vec.push(JsValue::from_string((*args.add(i as usize)).into()));
}

(data.func)(handle, cmd_string, args_vec);
Expand All @@ -262,9 +261,10 @@ unsafe fn ffi_eval_js_callback_result(
let result_val: Result<JsValue, JsEvaluationError> = if error.is_null() {
let result_str = CStr::from_ptr(result)
.to_string_lossy()
.to_owned()
.to_string();
Ok(JsValue::Other(result_str))

// Parse the string
Ok(JsValue::from_string(&result_str))
} else {
Err(JsEvaluationError::new(error))
};
Expand Down
35 changes: 33 additions & 2 deletions src/javascript.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::{borrow::Cow, collections::HashMap, fmt};
use std::{borrow::Cow, collections::HashMap, fmt, str::FromStr};

use json::JsonValue;
pub use num_bigfloat::BigFloat;

/// A JavaScript value.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum JsValue {
Array(Vec<JsValue>),
Boolean(bool),
Expand All @@ -30,6 +30,37 @@ impl JsValue {
}
}

pub fn from_string(string: &str) -> Self {
if string.len() == 0 {
return Self::Other(String::new());
}

// If the symbol starts with a digit, interpret it as a (positive) number
if "0123456789".contains(|c| c == string.chars().nth(0).unwrap()) { println!("XXXXXXXXXXXXXXXX");
return match BigFloat::from_str(string) {
Err(e) => Self::Other(format!("unable to parse number: {}", string)),
Ok(f) => Self::Number(f)
};
}
if string == "null" {
return Self::Null;
}
if string == "undefined" {
return Self::Undefined;
}
if string == "true" {
return Self::Boolean(true);
}
if string == "false" {
return Self::Boolean(false);
}
if string.chars().nth(0) == Some('\"') {
return Self::String(string[1..(string.len()-1)].to_string())
}

Self::Other(string.to_string())
}

fn _from_json(value: JsonValue) -> Self {
match value {
JsonValue::Null => Self::Null,
Expand Down

0 comments on commit 03d7fba

Please sign in to comment.