mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-12 13:38:36 -07:00
JS: Fourth batch of OFW PR changes
This commit is contained in:
@@ -17,18 +17,16 @@ let views = {
|
||||
empty: emptyView.make(),
|
||||
keyboard: textInputView.makeWith({
|
||||
header: "Enter your name",
|
||||
defaultText: flipper.getName(),
|
||||
defaultTextClear: true,
|
||||
// Props for makeWith() are passed in reverse order, so maxLength must be after defaultText
|
||||
minLength: 0,
|
||||
maxLength: 32,
|
||||
defaultText: flipper.getName(),
|
||||
defaultTextClear: true,
|
||||
}),
|
||||
helloDialog: dialogView.make(),
|
||||
bytekb: byteInputView.makeWith({
|
||||
header: "Look ma, I'm a header text!",
|
||||
defaultData: Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]),
|
||||
// Props for makeWith() are passed in reverse order, so length must be after defaultData
|
||||
length: 8,
|
||||
defaultData: Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]),
|
||||
}),
|
||||
longText: textBoxView.makeWith({
|
||||
text: "This is a very long string that demonstrates the TextBox view. Use the D-Pad to scroll backwards and forwards.\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse rhoncus est malesuada quam egestas ultrices. Maecenas non eros a nulla eleifend vulputate et ut risus. Quisque in mauris mattis, venenatis risus eget, aliquam diam. Fusce pretium feugiat mauris, ut faucibus ex volutpat in. Phasellus volutpat ex sed gravida consectetur. Aliquam sed lectus feugiat, tristique lectus et, bibendum lacus. Ut sit amet augue eu sapien elementum aliquam quis vitae tortor. Vestibulum quis commodo odio. In elementum fermentum massa, eu pellentesque nibh cursus at. Integer eleifend lacus nec purus elementum sodales. Nulla elementum neque urna, non vulputate massa semper sed. Fusce ut nisi vitae dui blandit congue pretium vitae turpis.",
|
||||
|
||||
@@ -24,11 +24,10 @@ let views = {
|
||||
}),
|
||||
textInput: textInput.makeWith({
|
||||
header: "Type JavaScript Code:",
|
||||
defaultText: "2+2",
|
||||
defaultTextClear: true,
|
||||
// Props for makeWith() are passed in reverse order, so maxLength must be after defaultText
|
||||
minLength: 0,
|
||||
maxLength: 256,
|
||||
defaultText: "2+2",
|
||||
defaultTextClear: true,
|
||||
}),
|
||||
loading: loading.make(),
|
||||
};
|
||||
|
||||
@@ -198,12 +198,18 @@ static void js_require(struct mjs* mjs) {
|
||||
|
||||
static void js_parse_int(struct mjs* mjs) {
|
||||
const char* str;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_AT_LEAST, JS_ARG_STR(&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));
|
||||
if(mjs_nargs(mjs) >= 2) {
|
||||
mjs_val_t base_arg = mjs_arg(mjs, 1);
|
||||
if(!mjs_is_number(base_arg)) {
|
||||
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "Base must be a number");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
}
|
||||
base = mjs_get_int(mjs, base_arg);
|
||||
}
|
||||
|
||||
int32_t num;
|
||||
if(strint_to_int32(str, NULL, &num, base) != StrintParseNoError) {
|
||||
num = 0;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
typedef struct {
|
||||
uint8_t* buffer;
|
||||
size_t buffer_size;
|
||||
size_t default_data_size;
|
||||
FuriString* header;
|
||||
FuriSemaphore* input_semaphore;
|
||||
JsEventLoopContract contract;
|
||||
@@ -38,7 +39,14 @@ static bool
|
||||
len_assign(struct mjs* mjs, ByteInput* input, JsViewPropValue value, JsByteKbContext* context) {
|
||||
UNUSED(mjs);
|
||||
UNUSED(input);
|
||||
context->buffer_size = (size_t)(value.number);
|
||||
size_t new_buffer_size = value.number;
|
||||
if(new_buffer_size < context->default_data_size) {
|
||||
// Avoid confusing parameters from user
|
||||
mjs_prepend_errorf(
|
||||
mjs, MJS_BAD_ARGS_ERROR, "length must be larger than defaultData length");
|
||||
return false;
|
||||
}
|
||||
context->buffer_size = new_buffer_size;
|
||||
context->buffer = realloc(context->buffer, context->buffer_size); //-V701
|
||||
byte_input_set_result_callback(
|
||||
input,
|
||||
@@ -57,16 +65,24 @@ static bool default_data_assign(
|
||||
JsByteKbContext* context) {
|
||||
UNUSED(mjs);
|
||||
|
||||
mjs_val_t array_buf = value.array;
|
||||
mjs_val_t array_buf = value.term;
|
||||
if(mjs_is_data_view(array_buf)) {
|
||||
array_buf = mjs_dataview_get_buf(mjs, array_buf);
|
||||
}
|
||||
size_t default_data_len = 0;
|
||||
char* default_data = mjs_array_buf_get_ptr(mjs, array_buf, &default_data_len);
|
||||
memcpy(
|
||||
context->buffer,
|
||||
(uint8_t*)default_data,
|
||||
MIN((size_t)context->buffer_size, default_data_len));
|
||||
char* default_data = mjs_array_buf_get_ptr(mjs, array_buf, &context->default_data_size);
|
||||
if(context->buffer_size < context->default_data_size) {
|
||||
// Ensure buffer is large enough for defaultData
|
||||
context->buffer_size = context->default_data_size;
|
||||
context->buffer = realloc(context->buffer, context->buffer_size); //-V701
|
||||
}
|
||||
memcpy(context->buffer, (uint8_t*)default_data, context->default_data_size);
|
||||
if(context->buffer_size > context->default_data_size) {
|
||||
// Reset previous data after defaultData
|
||||
memset(
|
||||
context->buffer + context->default_data_size,
|
||||
0x00,
|
||||
context->buffer_size - context->default_data_size);
|
||||
}
|
||||
|
||||
byte_input_set_result_callback(
|
||||
input,
|
||||
|
||||
@@ -216,14 +216,14 @@ static bool
|
||||
expected_type = "array";
|
||||
break;
|
||||
}
|
||||
c_value = (JsViewPropValue){.array = value};
|
||||
c_value = (JsViewPropValue){.term = value};
|
||||
} break;
|
||||
case JsViewPropTypeTypedArr: {
|
||||
if(!mjs_is_typed_array(value)) {
|
||||
expected_type = "typed_array";
|
||||
break;
|
||||
}
|
||||
c_value = (JsViewPropValue){.array = value};
|
||||
c_value = (JsViewPropValue){.term = value};
|
||||
} break;
|
||||
case JsViewPropTypeBool: {
|
||||
if(!mjs_is_boolean(value)) {
|
||||
|
||||
@@ -16,8 +16,8 @@ typedef enum {
|
||||
typedef union {
|
||||
const char* string;
|
||||
int32_t number;
|
||||
mjs_val_t array;
|
||||
bool boolean;
|
||||
mjs_val_t term;
|
||||
} JsViewPropValue;
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,9 +33,9 @@ static bool
|
||||
static bool items_assign(struct mjs* mjs, Submenu* submenu, JsViewPropValue value, void* context) {
|
||||
UNUSED(mjs);
|
||||
submenu_reset(submenu);
|
||||
size_t len = mjs_array_length(mjs, value.array);
|
||||
size_t len = mjs_array_length(mjs, value.term);
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
mjs_val_t item = mjs_array_get(mjs, value.array, i);
|
||||
mjs_val_t item = mjs_array_get(mjs, value.term, i);
|
||||
if(!mjs_is_string(item)) return false;
|
||||
submenu_add_item(submenu, mjs_get_string(mjs, &item, NULL), i, choose_callback, context);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
typedef struct {
|
||||
char* buffer;
|
||||
size_t buffer_size;
|
||||
size_t default_text_size;
|
||||
FuriString* header;
|
||||
bool default_text_clear;
|
||||
FuriSemaphore* input_semaphore;
|
||||
@@ -49,7 +50,14 @@ static bool max_len_assign(
|
||||
JsViewPropValue value,
|
||||
JsKbdContext* context) {
|
||||
UNUSED(mjs);
|
||||
context->buffer_size = (size_t)(value.number + 1);
|
||||
size_t new_buffer_size = value.number + 1;
|
||||
if(new_buffer_size < context->default_text_size) {
|
||||
// Avoid confusing parameters from user
|
||||
mjs_prepend_errorf(
|
||||
mjs, MJS_BAD_ARGS_ERROR, "maxLength must be larger than defaultText length");
|
||||
return false;
|
||||
}
|
||||
context->buffer_size = new_buffer_size;
|
||||
context->buffer = realloc(context->buffer, context->buffer_size); //-V701
|
||||
text_input_set_result_callback(
|
||||
input,
|
||||
@@ -70,6 +78,13 @@ static bool default_text_assign(
|
||||
UNUSED(input);
|
||||
|
||||
if(value.string) {
|
||||
context->default_text_size = strlen(value.string) + 1;
|
||||
if(context->buffer_size < context->default_text_size) {
|
||||
// Ensure buffer is large enough for defaultData
|
||||
context->buffer_size = context->default_text_size;
|
||||
context->buffer = realloc(context->buffer, context->buffer_size); //-V701
|
||||
}
|
||||
// Also trim excess previous data with strlcpy()
|
||||
strlcpy(context->buffer, value.string, context->buffer_size);
|
||||
text_input_set_result_callback(
|
||||
input,
|
||||
|
||||
6
applications/system/js_app/types/global.d.ts
vendored
6
applications/system/js_app/types/global.d.ts
vendored
@@ -31,8 +31,10 @@ 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
|
||||
* the last value pushed on the stack.
|
||||
* Reads a file at the specified path and runs it as JS, returning the last evaluated value.
|
||||
*
|
||||
* The result is cached and this filepath will not re-evaluated on future
|
||||
* load() calls for this session.
|
||||
*
|
||||
* @param path The path to the file
|
||||
* @param scope An object to use as global scope while running this file
|
||||
|
||||
Reference in New Issue
Block a user