You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
4.2 KiB
200 lines
4.2 KiB
/* Console binding for browser using duktape and libdom
|
|
*
|
|
* Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
|
|
* Copyright 2015 Daniel Silverstone <dsilvers@netsurf-browser.org>
|
|
*
|
|
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
|
*
|
|
* Released under the terms of the MIT License,
|
|
* http://www.opensource.org/licenses/mit-license
|
|
*/
|
|
|
|
class Console {
|
|
private unsigned int group;
|
|
prologue %{
|
|
#include <nsutils/time.h>
|
|
#include "netsurf/browser_window.h"
|
|
|
|
#define CONSOLE_TIMERS MAGIC(ConsoleTimers)
|
|
|
|
static void
|
|
write_log_entry(duk_context *ctx, unsigned int group, browser_window_console_flags flags)
|
|
{
|
|
/* objs... */
|
|
dukky_push_generics(ctx, "consoleFormatter");
|
|
duk_insert(ctx, 0);
|
|
if (dukky_pcall(ctx, duk_get_top(ctx) - 1, false)) {
|
|
/* Failed to convert somehow, oh dear, you get to keep
|
|
* all the pieces.
|
|
*/
|
|
duk_pop(ctx);
|
|
duk_push_string(ctx, "Oh dear, formatter went banananas");
|
|
}
|
|
/* str?objs?... */
|
|
for (int i = 0; i < duk_get_top(ctx); ++i) {
|
|
(void)duk_safe_to_string(ctx, i);
|
|
}
|
|
/* strs... */
|
|
for (unsigned int u = 0; u < group; ++u) {
|
|
duk_push_lstring(ctx, " ", 1);
|
|
duk_insert(ctx, 0);
|
|
}
|
|
/* spcs... strs... */
|
|
duk_concat(ctx, duk_get_top(ctx));
|
|
/* str */
|
|
|
|
duk_push_global_object(ctx);
|
|
duk_get_prop_string(ctx, -1, PRIVATE_MAGIC);
|
|
window_private_t *priv_win = duk_get_pointer(ctx, -1);
|
|
duk_pop(ctx);
|
|
|
|
duk_size_t msglen;
|
|
const char *msg = duk_safe_to_lstring(ctx, 0, &msglen);
|
|
|
|
if (priv_win == NULL || priv_win->win == NULL || priv_win->closed_down == true ||
|
|
browser_window_console_log(priv_win->win, BW_CS_SCRIPT_CONSOLE,
|
|
msg, msglen,
|
|
flags) != NSERROR_OK) {
|
|
NSLOG(netsurf, DEBUG, "Unable to log: %s", duk_safe_to_string(ctx, 0));
|
|
}
|
|
}
|
|
|
|
%};
|
|
};
|
|
|
|
init Console ()
|
|
%{
|
|
priv->group = 0;
|
|
duk_push_object(ctx);
|
|
duk_put_prop_string(ctx, 0, CONSOLE_TIMERS);
|
|
%}
|
|
|
|
method Console::group ()
|
|
%{
|
|
priv->group ++;
|
|
return 0;
|
|
%}
|
|
|
|
method Console::groupCollapsed ()
|
|
%{
|
|
priv->group ++;
|
|
return 0;
|
|
%}
|
|
|
|
method Console::groupEnd ()
|
|
%{
|
|
if (priv->group)
|
|
priv->group --;
|
|
return 0;
|
|
%}
|
|
|
|
method Console::info()
|
|
%{
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::debug()
|
|
%{
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_DEBUG);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::error()
|
|
%{
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_ERROR);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::log()
|
|
%{
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_LOG);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::warn()
|
|
%{
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_WARN);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::dir()
|
|
%{
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::time()
|
|
%{
|
|
uint64_t time_ms = 0;
|
|
|
|
if (nsu_getmonotonic_ms(&time_ms) != NSUERROR_OK)
|
|
return 0;
|
|
|
|
if (!duk_is_string(ctx, 0)) {
|
|
return duk_error(ctx, DUK_ERR_ERROR, "Console.time() takes a string");
|
|
}
|
|
|
|
duk_set_top(ctx, 1);
|
|
|
|
duk_push_uint(ctx, (duk_uint_t)time_ms);
|
|
|
|
duk_push_this(ctx);
|
|
duk_get_prop_string(ctx, -1, CONSOLE_TIMERS);
|
|
duk_insert(ctx, 0);
|
|
duk_pop(ctx);
|
|
|
|
duk_put_prop(ctx, 0);
|
|
|
|
return 0;
|
|
%}
|
|
|
|
method Console::timeEnd()
|
|
%{
|
|
uint64_t time_ms = 0;
|
|
uint64_t old_time_ms = 0;
|
|
|
|
if (nsu_getmonotonic_ms(&time_ms) != NSUERROR_OK)
|
|
return 0;
|
|
|
|
if (!duk_is_string(ctx, 0)) {
|
|
return duk_error(ctx, DUK_ERR_ERROR, "Console.time() takes a string");
|
|
}
|
|
|
|
duk_set_top(ctx, 1);
|
|
|
|
duk_push_this(ctx);
|
|
duk_get_prop_string(ctx, -1, CONSOLE_TIMERS);
|
|
duk_insert(ctx, 0);
|
|
duk_pop(ctx);
|
|
|
|
duk_dup(ctx, -1);
|
|
duk_get_prop(ctx, 0);
|
|
if (duk_is_undefined(ctx, -1)) {
|
|
duk_pop(ctx);
|
|
duk_push_uint(ctx, (duk_uint_t)time_ms);
|
|
}
|
|
/* timers timername oldval */
|
|
old_time_ms = duk_to_uint32(ctx, -1);
|
|
duk_pop(ctx);
|
|
duk_dup(ctx, -1);
|
|
duk_insert(ctx, 0);
|
|
duk_del_prop(ctx, 0);
|
|
duk_push_string(ctx, "Timer elapsed: ");
|
|
duk_insert(ctx, 0);
|
|
duk_push_sprintf(ctx, "%u ms", (duk_uint_t)(time_ms - old_time_ms));
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
|
|
return 0;
|
|
%}
|
|
|
|
method Console::trace ()
|
|
%{
|
|
duk_idx_t i = duk_push_error_object(ctx, DUK_ERR_ERROR, "Dummy Error");
|
|
duk_get_prop_string(ctx, i, "stack");
|
|
duk_safe_to_string(ctx, -1);
|
|
duk_insert(ctx, 0);
|
|
duk_set_top(ctx, 1);
|
|
write_log_entry(ctx, priv->group, BW_CS_FLAG_LEVEL_INFO);
|
|
return 0;
|
|
%}
|