1
// Copyright 2008, Google Inc.
3
// Redistribution and use in source and binary forms, with or without
4
// modification, are permitted provided that the following conditions are met:
6
// 1. Redistributions of source code must retain the above copyright notice,
7
// this list of conditions and the following disclaimer.
8
// 2. Redistributions in binary form must reproduce the above copyright notice,
9
// this list of conditions and the following disclaimer in the documentation
10
// and/or other materials provided with the distribution.
11
// 3. Neither the name of Google Inc. nor the names of its contributors may be
12
// used to endorse or promote products derived from this software without
13
// specific prior written permission.
15
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
#include "gears/console/console.h"
28
#include "gears/base/common/message_service.h"
29
#include "gears/console/log_event.h"
31
DECLARE_DISPATCHER(GearsConsole);
33
const std::string GearsConsole::kModuleName("GearsConsole");
36
void Dispatcher<GearsConsole>::Init() {
37
RegisterMethod("log", &GearsConsole::Log);
38
RegisterProperty("onlog", &GearsConsole::GetOnLog, &GearsConsole::SetOnLog);
41
void GearsConsole::Log(JsCallContext *context) {
44
// Get and sanitize parameters.
45
std::string16 type_str;
46
std::string16 message;
47
scoped_ptr<JsArray> args_array;
49
{ JSPARAM_REQUIRED, JSPARAM_STRING16, &type_str },
50
{ JSPARAM_REQUIRED, JSPARAM_STRING16, &message },
51
{ JSPARAM_OPTIONAL, JSPARAM_ARRAY, as_out_parameter(args_array)},
53
if (!context->GetArguments(ARRAYSIZE(argv), argv)) {
54
assert(context->is_exception_set());
58
// Check input validity.
59
if (type_str.length() == 0) {
60
context->SetException(STRING16(L"type cannot be an empty string."));
64
if (message.length() == 0) {
65
context->SetException(STRING16(L"message cannot be an empty string."));
69
std::string16 msg = message;
70
if (argv[2].was_specified) {
71
InterpolateArgs(&message, args_array.get());
73
LogEvent *log_event = new LogEvent(message, type_str, EnvPageLocationUrl());
74
MessageService::GetInstance()->NotifyObservers(observer_topic_.c_str(),
78
void GearsConsole::GetOnLog(JsCallContext *context) {
79
JsRootedCallback *callback = callback_backend_->GetCallback();
80
if (callback == NULL) {
81
context->SetReturnValue(JSPARAM_NULL, NULL);
83
context->SetReturnValue(JSPARAM_FUNCTION, callback);
87
void GearsConsole::SetOnLog(JsCallContext *context) {
90
// Get & sanitize parameters.
91
JsRootedCallback *function = NULL;
93
{ JSPARAM_OPTIONAL, JSPARAM_FUNCTION, &function },
95
context->GetArguments(ARRAYSIZE(argv), argv);
96
scoped_ptr<JsRootedCallback> scoped_function(function);
98
if (context->is_exception_set())
101
callback_backend_->SetCallback(scoped_function.release());
104
void GearsConsole::Initialize() {
105
if (!callback_backend_.get()) {
107
STRING16(L"console:logstream-") + EnvPageSecurityOrigin().url();
108
callback_backend_.reset(
109
new JsCallbackLoggingBackend(observer_topic_, GetJsRunner(), this));
112
// Create an event monitor to alert us when the page unloads.
113
if (!unload_monitor_.get()) {
114
unload_monitor_.reset(new JsEventMonitor(GetJsRunner(), JSEVENT_UNLOAD,
120
void GearsConsole::InterpolateArgs(std::string16 *message,
121
const JsArray *args) {
122
std::string16::size_type location = 0;
124
if (!args->GetLength(&args_length)) return;
126
for (int i = 0; i < args_length; i++) {
127
// Find the _next_ occurance of %s
128
location = message->find(STRING16(L"%s"), location);
129
if (location == std::string16::npos) break;
131
std::string16 string_value(STRING16(L"<Error converting to string>"));
132
args->GetElementAsStringWithCoercion(i, &string_value);
134
message->replace(location, 2, string_value);
135
location += string_value.size();
139
void GearsConsole::HandleEvent(JsEventType event_type) {
140
assert(event_type == JSEVENT_UNLOAD);
141
// TODO(nigeltao): do we really need to listen to the unload event!?
142
callback_backend_.reset();