[go: nahoru, domu]

blob: 170f0073e72a20cd13fa703d22c1cb88186ba916 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_ELEMENT_POSITION_GETTER_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_ELEMENT_POSITION_GETTER_H_
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_dom.h"
#include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h"
#include "components/autofill_assistant/browser/devtools/devtools_client.h"
#include "components/autofill_assistant/browser/selector.h"
#include "components/autofill_assistant/browser/web/web_controller_worker.h"
namespace content {
class RenderFrameHost;
} // namespace content
namespace autofill_assistant {
// Worker class to get an element's position in viewport coordinates when it is
// stable and the frame it belongs to has finished its visual update.
class ElementPositionGetter : public WebControllerWorker {
public:
// |devtools_client| must be valid for the lifetime of the instance.
ElementPositionGetter(DevtoolsClient* devtools_client,
int max_rounds,
base::TimeDelta check_interval,
const std::string& optional_node_frame_id);
~ElementPositionGetter() override;
// Callback that receives the position that corresponds to the center
// of an element.
//
// If the operation failed, the status is ELEMENT_UNSTABLE.
// If the operation succeeded, check the coordinate in the getter.
using Callback = base::OnceCallback<void(const ClientStatus&)>;
// The X coordinate of the center of the element, only valid after getting a
// successful callback.
int x() { return point_x_; }
// The Y coordinate of the center of the element, only valid after getting a
// successful callback.
int y() { return point_y_; }
void Start(content::RenderFrameHost* frame_host,
std::string element_object_id,
Callback callback);
private:
void OnVisualStateUpdatedCallback(bool success);
void GetAndWaitBoxModelStable();
void OnGetBoxModelForStableCheck(
const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<dom::GetBoxModelResult> result);
void OnScrollIntoView(const DevtoolsClient::ReplyStatus& reply_status,
std::unique_ptr<runtime::CallFunctionOnResult> result);
void RunNextRound();
void OnResult(int x, int y);
void OnError(const ClientStatus& status);
// Time to wait between two box model checks.
const base::TimeDelta check_interval_;
// Maximum number of checks to run.
int max_rounds_;
raw_ptr<DevtoolsClient> devtools_client_ = nullptr;
std::string object_id_;
int remaining_rounds_ = 0;
Callback callback_;
bool visual_state_updated_ = false;
// If |has_point_| is true, |point_x_| and |point_y_| contain the last
// computed center of the element, in viewport coordinates. Note that
// negative coordinates are valid, in case the element is above or to the
// left of the viewport.
bool has_point_ = false;
int point_x_ = 0;
int point_y_ = 0;
std::string node_frame_id_;
base::WeakPtrFactory<ElementPositionGetter> weak_ptr_factory_;
};
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_ELEMENT_POSITION_GETTER_H_