netsurf/content/handlers/javascript/duktape/Console.bnd
2017-09-06 18:45:35 +01:00

178 lines
3.3 KiB
Plaintext

/* 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>
#define CONSOLE_TIMERS MAGIC(ConsoleTimers)
static void
write_log_entry(duk_context *ctx, unsigned int group, char logtype)
{
/* objs... */
for (int i = 0; i < duk_get_top(ctx); ++i) {
(void)duk_safe_to_string(ctx, i);
}
/* strs... */
duk_push_sprintf(ctx, "%c: ", logtype);
duk_insert(ctx, 0);
/* pfx strs... */
for (unsigned int u = 0; u < group; ++u) {
duk_push_lstring(ctx, " ", 1);
duk_insert(ctx, 0);
}
/* spcs... pfx strs... */
duk_concat(ctx, duk_get_top(ctx));
/* str */
NSLOG(netsurf, INFO, "%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, 'I');
return 0;
%}
method Console::debug()
%{
write_log_entry(ctx, priv->group, 'D');
return 0;
%}
method Console::error()
%{
write_log_entry(ctx, priv->group, 'E');
return 0;
%}
method Console::log()
%{
write_log_entry(ctx, priv->group, 'L');
return 0;
%}
method Console::warn()
%{
write_log_entry(ctx, priv->group, 'W');
return 0;
%}
method Console::dir()
%{
write_log_entry(ctx, priv->group, 'd');
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, "%lu ms", (duk_uint_t)(time_ms - old_time_ms));
write_log_entry(ctx, priv->group, 'T');
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, 'S');
return 0;
%}