| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/accessibility/features/v8_bindings_utils.h" |
| |
| #include "base/logging.h" |
| #include "base/strings/stringprintf.h" |
| #include "gin/arguments.h" |
| #include "services/accessibility/features/text_decoder.h" |
| #include "services/accessibility/features/text_encoder.h" |
| #include "v8/include/v8-object.h" |
| #include "v8/include/v8-template.h" |
| |
| namespace ax { |
| |
| namespace { |
| |
| // Below are for debugging until we can see console.log/warn/error output. |
| // TODO(crbug.com/1355633): Use blink::mojom::DevToolsAgent interface to attach |
| // to Chrome devtools. |
| static std::string PrintArgs(gin::Arguments* args) { |
| std::string statement; |
| while (!args->PeekNext().IsEmpty()) { |
| v8::String::Utf8Value value(args->isolate(), args->PeekNext()); |
| statement += base::StringPrintf("%s ", *value); |
| args->Skip(); |
| } |
| return statement; |
| } |
| |
| // Provides temporary functionality for atpconsole.log. |
| static void ConsoleLog(gin::Arguments* args) { |
| LOG(ERROR) << "AccessibilityService V8: Info: " << PrintArgs(args); |
| } |
| |
| // Provides temporary functionality for atpconsole.warn. |
| static void ConsoleWarn(gin::Arguments* args) { |
| LOG(ERROR) << "AccessibilityService V8: Error: " << PrintArgs(args); |
| } |
| |
| // Provides temporary functionality for atpconsole.error. |
| static void ConsoleError(gin::Arguments* args) { |
| LOG(ERROR) << "AccessibilityService V8: Error: " << PrintArgs(args); |
| } |
| |
| } // namespace |
| |
| // static |
| void BindingsUtils::AddAtpConsoleTemplate( |
| v8::Isolate* isolate, |
| v8::Local<v8::ObjectTemplate> object_template) { |
| // Use static bindings for console functions for initial development. |
| // Note that "console" seems to be protected in v8 so we have to make |
| // our own, "atpconsole". |
| // TODO(crbug.com/1355633): Use blink::mojom::DevToolsAgent interface to |
| // attach to Chrome devtools and remove these temporary bindings. |
| v8::Local<v8::ObjectTemplate> console_template = |
| v8::ObjectTemplate::New(isolate); |
| console_template->Set( |
| isolate, "log", |
| gin::CreateFunctionTemplate(isolate, base::BindRepeating(&ConsoleLog))); |
| console_template->Set( |
| isolate, "warn", |
| gin::CreateFunctionTemplate(isolate, base::BindRepeating(&ConsoleWarn))); |
| console_template->Set( |
| isolate, "error", |
| gin::CreateFunctionTemplate(isolate, base::BindRepeating(&ConsoleError))); |
| object_template->Set(isolate, "atpconsole", console_template); |
| } |
| |
| // static |
| void BindingsUtils::AddCallHandlerToTemplate( |
| v8::Isolate* isolate, |
| v8::Local<v8::ObjectTemplate>& object_template, |
| const std::string& name, |
| v8::FunctionCallback callback) { |
| v8::Local<v8::FunctionTemplate> fn_template = |
| v8::FunctionTemplate::New(isolate); |
| fn_template->SetCallHandler(callback); |
| object_template->Set(isolate, name.c_str(), fn_template); |
| } |
| |
| // static |
| void BindingsUtils::CreateTextEncoderCallback( |
| const v8::FunctionCallbackInfo<v8::Value>& info) { |
| // Check this is a constructor call: JS should always request |
| // `new TextEncoder()` rather than just `TextEncoder`. |
| DCHECK(info.IsConstructCall()); |
| gin::Handle<TextEncoder> text_encoder = |
| TextEncoder::Create(info.GetIsolate()->GetCurrentContext()); |
| info.GetReturnValue().Set(text_encoder.ToV8()); |
| } |
| |
| // static |
| void BindingsUtils::CreateTextDecoderCallback( |
| const v8::FunctionCallbackInfo<v8::Value>& info) { |
| // Check this is a constructor call: JS should always request |
| // `new TextDecoder()` rather than just `TextDecoder`. |
| DCHECK(info.IsConstructCall()); |
| gin::Handle<TextDecoder> text_decoder = |
| TextDecoder::Create(info.GetIsolate()->GetCurrentContext()); |
| info.GetReturnValue().Set(text_decoder.ToV8()); |
| } |
| |
| } // namespace ax |