mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
merge js stuff
https://github.com/Next-Flip/Momentum-Firmware/commits/js-backport-of-backport/
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include <common/cs_dbg.h>
|
||||
#include <toolbox/path.h>
|
||||
#include <toolbox/stream/file_stream.h>
|
||||
#include <toolbox/strint.h>
|
||||
#include <loader/firmware_api/firmware_api.h>
|
||||
#include <flipper_application/api_hashtable/api_hashtable.h>
|
||||
#include <flipper_application/plugins/composite_resolver.h>
|
||||
@@ -206,87 +207,20 @@ static void js_global_to_string(struct mjs* mjs) {
|
||||
}
|
||||
|
||||
static void js_parse_int(struct mjs* mjs) {
|
||||
mjs_val_t arg = mjs_arg(mjs, 0);
|
||||
if(!mjs_is_string(arg)) {
|
||||
mjs_return(mjs, mjs_mk_number(mjs, 0));
|
||||
return;
|
||||
const char* str;
|
||||
int32_t base = 10;
|
||||
if(mjs_nargs(mjs) == 1) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&str));
|
||||
} else {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&str), JS_ARG_INT32(&base));
|
||||
}
|
||||
size_t str_len = 0;
|
||||
const char* str = mjs_get_string(mjs, &arg, &str_len);
|
||||
if((str_len == 0) || (str == NULL)) {
|
||||
mjs_return(mjs, mjs_mk_number(mjs, 0));
|
||||
return;
|
||||
int32_t num;
|
||||
if(strint_to_int32(str, NULL, &num, base) != StrintParseNoError) {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
int32_t num = 0;
|
||||
int32_t sign = 1;
|
||||
size_t i = 0;
|
||||
|
||||
if(str[0] == '-') {
|
||||
sign = -1;
|
||||
i = 1;
|
||||
} else if(str[0] == '+') {
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for(; i < str_len; i++) {
|
||||
if(str[i] >= '0' && str[i] <= '9') {
|
||||
num = num * 10 + (str[i] - '0');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
num *= sign;
|
||||
|
||||
mjs_return(mjs, mjs_mk_number(mjs, num));
|
||||
}
|
||||
|
||||
static void js_to_upper_case(struct mjs* mjs) {
|
||||
mjs_val_t arg0 = mjs_arg(mjs, 0);
|
||||
|
||||
size_t str_len;
|
||||
const char* str = NULL;
|
||||
if(mjs_is_string(arg0)) {
|
||||
str = mjs_get_string(mjs, &arg0, &str_len);
|
||||
}
|
||||
if(!str) {
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
|
||||
char* upperStr = strdup(str);
|
||||
for(size_t i = 0; i < str_len; i++) {
|
||||
upperStr[i] = toupper(upperStr[i]);
|
||||
}
|
||||
|
||||
mjs_val_t resultStr = mjs_mk_string(mjs, upperStr, ~0, true);
|
||||
free(upperStr);
|
||||
mjs_return(mjs, resultStr);
|
||||
}
|
||||
|
||||
static void js_to_lower_case(struct mjs* mjs) {
|
||||
mjs_val_t arg0 = mjs_arg(mjs, 0);
|
||||
|
||||
size_t str_len;
|
||||
const char* str = NULL;
|
||||
if(mjs_is_string(arg0)) {
|
||||
str = mjs_get_string(mjs, &arg0, &str_len);
|
||||
}
|
||||
if(!str) {
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
|
||||
char* lowerStr = strdup(str);
|
||||
for(size_t i = 0; i < str_len; i++) {
|
||||
lowerStr[i] = tolower(lowerStr[i]);
|
||||
}
|
||||
|
||||
mjs_val_t resultStr = mjs_mk_string(mjs, lowerStr, ~0, true);
|
||||
free(lowerStr);
|
||||
mjs_return(mjs, resultStr);
|
||||
}
|
||||
|
||||
#ifdef JS_DEBUG
|
||||
static void js_dump_write_callback(void* ctx, const char* format, ...) {
|
||||
File* file = ctx;
|
||||
@@ -320,14 +254,14 @@ static int32_t js_thread(void* arg) {
|
||||
mjs_set(
|
||||
mjs,
|
||||
global,
|
||||
"__filepath",
|
||||
"__filename",
|
||||
~0,
|
||||
mjs_mk_string(
|
||||
mjs, furi_string_get_cstr(worker->path), furi_string_size(worker->path), true));
|
||||
mjs_set(
|
||||
mjs,
|
||||
global,
|
||||
"__dirpath",
|
||||
"__dirname",
|
||||
~0,
|
||||
mjs_mk_string(mjs, furi_string_get_cstr(dirpath), furi_string_size(dirpath), true));
|
||||
furi_string_free(dirpath);
|
||||
@@ -338,8 +272,6 @@ static int32_t js_thread(void* arg) {
|
||||
mjs_set(mjs, global, "ffi_address", ~0, MJS_MK_FN(js_ffi_address));
|
||||
mjs_set(mjs, global, "require", ~0, MJS_MK_FN(js_require));
|
||||
mjs_set(mjs, global, "parseInt", ~0, MJS_MK_FN(js_parse_int));
|
||||
mjs_set(mjs, global, "toUpperCase", ~0, MJS_MK_FN(js_to_upper_case));
|
||||
mjs_set(mjs, global, "toLowerCase", ~0, MJS_MK_FN(js_to_lower_case));
|
||||
|
||||
mjs_val_t console_obj = mjs_mk_object(mjs);
|
||||
mjs_set(mjs, console_obj, "log", ~0, MJS_MK_FN(js_console_log));
|
||||
|
||||
@@ -260,6 +260,26 @@ static void js_gui_view_set(struct mjs* mjs) {
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief `View.hasProperty`
|
||||
*/
|
||||
static void js_gui_view_has_property(struct mjs* mjs) {
|
||||
const char* name;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&name));
|
||||
JsGuiViewData* data = JS_GET_CONTEXT(mjs);
|
||||
const JsViewDescriptor* descriptor = data->descriptor;
|
||||
|
||||
for(size_t i = 0; i < descriptor->prop_cnt; i++) {
|
||||
JsViewPropDescriptor prop = descriptor->props[i];
|
||||
if(strcmp(prop.name, name) != 0) continue;
|
||||
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, true));
|
||||
return;
|
||||
}
|
||||
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief `View` destructor
|
||||
*/
|
||||
@@ -284,6 +304,7 @@ static mjs_val_t js_gui_make_view(struct mjs* mjs, const JsViewDescriptor* descr
|
||||
// generic view API
|
||||
mjs_val_t view_obj = mjs_mk_object(mjs);
|
||||
mjs_set(mjs, view_obj, "set", ~0, MJS_MK_FN(js_gui_view_set));
|
||||
mjs_set(mjs, view_obj, "hasProperty", ~0, MJS_MK_FN(js_gui_view_has_property));
|
||||
|
||||
// object data
|
||||
JsGuiViewData* data = malloc(sizeof(JsGuiViewData));
|
||||
|
||||
@@ -49,7 +49,6 @@ static bool max_len_assign(
|
||||
JsViewPropValue value,
|
||||
JsKbdContext* context) {
|
||||
UNUSED(mjs);
|
||||
UNUSED(input);
|
||||
context->buffer_size = (size_t)(value.number + 1);
|
||||
context->buffer = realloc(context->buffer, context->buffer_size); //-V701
|
||||
text_input_set_result_callback(
|
||||
|
||||
@@ -14,6 +14,9 @@ export type MainKey =
|
||||
"F11" | "F12" | "F13" | "F14" | "F15" | "F16" | "F17" | "F18" | "F19" |
|
||||
"F20" | "F21" | "F22" | "F23" | "F24" |
|
||||
|
||||
"NUM0" | "NUM1" | "NUM2" | "NUM3" | "NUM4" | "NUM5" | "NUM6" | "NUM7" |
|
||||
"NUM8" | "NUM9" |
|
||||
|
||||
"\n" | " " | "!" | "\"" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*" |
|
||||
"+" | "," | "-" | "." | "/" | ":" | ";" | "<" | ">" | "=" | "?" | "@" | "[" |
|
||||
"]" | "\\" | "^" | "_" | "`" | "{" | "}" | "|" | "~" |
|
||||
@@ -99,6 +102,6 @@ export declare function altPrint(string: string, delay?: number): void;
|
||||
export declare function altPrintln(string: string, delay?: number): void;
|
||||
|
||||
/**
|
||||
* @brief Releases usb, optional, but allows to interchange with usbdisk
|
||||
* @brief Releases usb, optional, but allows to switch usb profile
|
||||
*/
|
||||
export declare function quit(): void;
|
||||
|
||||
34
applications/system/js_app/types/global.d.ts
vendored
34
applications/system/js_app/types/global.d.ts
vendored
@@ -14,47 +14,37 @@ declare function print(...args: any[]): void;
|
||||
/**
|
||||
* @brief Converts a number to a string
|
||||
* @param value The number to convert to a string
|
||||
* @param base Integer base (`2`...`16`), default: 16
|
||||
* @param base Integer base (`2`...`16`), default: 10
|
||||
*/
|
||||
declare function toString(value: number, base?: number): string;
|
||||
|
||||
/**
|
||||
* @brief Converts a string to a number
|
||||
* @param text The string to convert to a number
|
||||
* @param base Integer base (`2`...`16`), default: 10
|
||||
*/
|
||||
declare function parseInt(text: string): number;
|
||||
|
||||
/**
|
||||
* @brief Transforms a string to upper case
|
||||
* @param text The string to transforms to upper case
|
||||
*/
|
||||
declare function toUpperCase(text: string): string;
|
||||
|
||||
/**
|
||||
* @brief Transforms a string to lower case
|
||||
* @param text The string to transforms to lower case
|
||||
*/
|
||||
declare function toLowerCase(text: string): string;
|
||||
declare function parseInt(text: string, base?: number): number;
|
||||
|
||||
/**
|
||||
* @brief Path to the directory containing the current script
|
||||
*/
|
||||
declare const __dirpath: string;
|
||||
declare const __dirname: string;
|
||||
|
||||
/**
|
||||
* @brief Path to the current script file
|
||||
*/
|
||||
declare const __filepath: string;
|
||||
declare const __filename: string;
|
||||
|
||||
/**
|
||||
* @brief Reads a JS value from a file
|
||||
*
|
||||
* Reads a file at the specified path, interprets it as a JS value and returns
|
||||
* said value.
|
||||
* the last value pushed on the stack.
|
||||
*
|
||||
* @param path The path to the file
|
||||
* @param scope An object to use as global scope while running this file
|
||||
*/
|
||||
declare function load(path: string): any;
|
||||
declare function load(path: string, scope?: object): any;
|
||||
|
||||
/**
|
||||
* @brief Return 1-byte string whose ASCII code is the integer `n`
|
||||
@@ -210,6 +200,14 @@ declare class String {
|
||||
* @param end The index to end substring at
|
||||
*/
|
||||
slice(start: number, end?: number): string;
|
||||
/**
|
||||
* @brief Return this string transformed to upper case
|
||||
*/
|
||||
toUpperCase(): string;
|
||||
/**
|
||||
* @brief Return this string transformed to lower case
|
||||
*/
|
||||
toLowerCase(): string;
|
||||
}
|
||||
|
||||
declare class Boolean { }
|
||||
|
||||
17
applications/system/js_app/types/gui/index.d.ts
vendored
17
applications/system/js_app/types/gui/index.d.ts
vendored
@@ -3,11 +3,28 @@ import type { Contract } from "../event_loop";
|
||||
type Properties = { [K: string]: any };
|
||||
|
||||
export declare class View<Props extends Properties> {
|
||||
/**
|
||||
* Assign value to property by name
|
||||
* @param property Name of the property
|
||||
* @param value Value to assign
|
||||
*/
|
||||
set<P extends keyof Props>(property: P, value: Props[P]): void;
|
||||
/**
|
||||
* Check if property is available
|
||||
* @param name Name of the property
|
||||
*/
|
||||
hasProperty(name: string): boolean;
|
||||
}
|
||||
|
||||
export declare class ViewFactory<Props extends Properties, V extends View<Props>> {
|
||||
/**
|
||||
* Create view instance with default values, can be changed later with set()
|
||||
*/
|
||||
make(): V;
|
||||
/**
|
||||
* Create view instance with custom values, can be changed later with set()
|
||||
* @param initial Dictionary of property names to values
|
||||
*/
|
||||
makeWith(initial: Partial<Props>): V;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user