void MainThreadDebugger::querySelectorAllCallback(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() < 1)
    return;
  String selector = toCoreStringWithUndefinedOrNullCheck(info[0]);
  if (selector.isEmpty())
    return;
  Node* node = secondArgumentAsNode(info);
  if (!node || !node->isContainerNode())
    return;
  ExceptionState exceptionState(ExceptionState::ExecutionContext, "$$",
                                "CommandLineAPI", info.Holder(),
                                info.GetIsolate());
  // toV8(elementList) doesn't work here, since we need a proper Array instance,
  // not NodeList.
  StaticElementList* elementList = toContainerNode(node)->querySelectorAll(
      AtomicString(selector), exceptionState);
  if (exceptionState.hadException() || !elementList)
    return;
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  v8::Local<v8::Array> nodes = v8::Array::New(isolate, elementList->length());
  for (size_t i = 0; i < elementList->length(); ++i) {
    Element* element = elementList->item(i);
    if (!createDataPropertyInArray(
             context, nodes, i, toV8(element, info.Holder(), info.GetIsolate()))
             .FromMaybe(false))
      return;
  }
  info.GetReturnValue().Set(nodes);
}
void MainThreadDebugger::xpathSelectorCallback(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() < 1)
    return;
  String selector = toCoreStringWithUndefinedOrNullCheck(info[0]);
  if (selector.isEmpty())
    return;
  Node* node = secondArgumentAsNode(info);
  if (!node || !node->isContainerNode())
    return;

  ExceptionState exceptionState(ExceptionState::ExecutionContext, "$x",
                                "CommandLineAPI", info.Holder(),
                                info.GetIsolate());
  XPathResult* result = XPathEvaluator::create()->evaluate(
      selector, node, nullptr, XPathResult::kAnyType, ScriptValue(),
      exceptionState);
  if (exceptionState.hadException() || !result)
    return;
  if (result->resultType() == XPathResult::kNumberType) {
    info.GetReturnValue().Set(toV8(result->numberValue(exceptionState),
                                   info.Holder(), info.GetIsolate()));
  } else if (result->resultType() == XPathResult::kStringType) {
    info.GetReturnValue().Set(toV8(result->stringValue(exceptionState),
                                   info.Holder(), info.GetIsolate()));
  } else if (result->resultType() == XPathResult::kBooleanType) {
    info.GetReturnValue().Set(toV8(result->booleanValue(exceptionState),
                                   info.Holder(), info.GetIsolate()));
  } else {
    v8::Isolate* isolate = info.GetIsolate();
    v8::Local<v8::Context> context = isolate->GetCurrentContext();
    v8::Local<v8::Array> nodes = v8::Array::New(isolate);
    size_t index = 0;
    while (Node* node = result->iterateNext(exceptionState)) {
      if (exceptionState.hadException())
        return;
      if (!createDataPropertyInArray(
               context, nodes, index++,
               toV8(node, info.Holder(), info.GetIsolate()))
               .FromMaybe(false))
        return;
    }
    info.GetReturnValue().Set(nodes);
  }
}
void MainThreadDebugger::querySelectorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    if (info.Length() < 1)
        return;
    String selector = toCoreStringWithUndefinedOrNullCheck(info[0]);
    if (selector.isEmpty())
        return;
    Node* node = secondArgumentAsNode(info);
    if (!node || !node->isContainerNode())
        return;
    ExceptionState exceptionState(ExceptionState::ExecutionContext, "$", "CommandLineAPI", info.Holder(), info.GetIsolate());
    Element* element = toContainerNode(node)->querySelector(AtomicString(selector), exceptionState);
    if (exceptionState.throwIfNeeded())
        return;
    if (element)
        info.GetReturnValue().Set(toV8(element, info.Holder(), info.GetIsolate()));
    else
        info.GetReturnValue().Set(v8::Null(info.GetIsolate()));
}