blob: de3f8601c77ec56d6a7fa9176d1eb5fb954ed80f [file] [log] [blame]
// Copyright 2016 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 PointerEventFactory_h
#define PointerEventFactory_h
#include "core/CoreExport.h"
#include "core/events/PointerEvent.h"
#include "platform/wtf/Allocator.h"
#include "platform/wtf/HashMap.h"
#include "public/platform/WebPointerEvent.h"
#include "public/platform/WebPointerProperties.h"
namespace blink {
// Helper class for tracking the pointer ids for each type of PointerEvents.
// Using id re-mapping at this layer, this class makes sure that regardless of
// the domain of the id (i.e. in touch or pen) the corresponding pointer event
// will have a unique id amongst all pointer events as per pointer events'
// specification. This class intended to behave the same as existing browsers as
// much as possible for compatibility reasons. Particularly it behaves very
// similar to MS Edge to have pointer event ids generated by mouse always equal
// 1 and those that are generated by touch and pen will have increasing ids from
// 2.
class CORE_EXPORT PointerEventFactory {
DISALLOW_NEW();
public:
PointerEventFactory();
~PointerEventFactory();
PointerEvent* Create(const AtomicString& mouse_event_name,
const WebMouseEvent&,
const Vector<WebMouseEvent>&,
LocalDOMWindow*);
PointerEvent* Create(const WebPointerEvent&,
const Vector<WebPointerEvent>&,
LocalDOMWindow*);
PointerEvent* CreatePointerCancelEvent(
const int pointer_id,
TimeTicks platfrom_time_stamp);
// For creating capture events (i.e got/lostpointercapture)
PointerEvent* CreatePointerCaptureEvent(PointerEvent*, const AtomicString&);
// For creating boundary events (i.e pointerout/leave/over/enter)
PointerEvent* CreatePointerBoundaryEvent(PointerEvent*,
const AtomicString&,
EventTarget*);
// Clear all the existing ids.
void Clear();
// When a particular pointerId is removed, the id is considered free even
// though there might have been other PointerEvents that were generated with
// the same id before.
bool Remove(const int);
// Returns all ids of pointers that are capable or scrolling.
Vector<int> GetPointerIdsOfScrollCapablePointers() const;
// Returns whether a pointer id exists and active.
bool IsActive(const int) const;
// Returns whether a pointer id exists and has at least one pressed button.
bool IsActiveButtonsState(const int) const;
// Returns the id of the pointer event corresponding to the given pointer
// properties if exists otherwise s_invalidId.
int GetPointerEventId(const WebPointerProperties&) const;
// Returns pointerType of for the given pointerId if such id is active.
// Otherwise it returns WebPointerProperties::PointerType::Unknown.
WebPointerProperties::PointerType GetPointerType(int pointer_id) const;
static const int kMouseId;
private:
typedef WTF::UnsignedWithZeroKeyHashTraits<int> UnsignedHash;
typedef struct IncomingId : public std::pair<int, int> {
IncomingId() = default;
IncomingId(WebPointerProperties::PointerType pointer_type, int raw_id)
: std::pair<int, int>(static_cast<int>(pointer_type), raw_id) {}
int PointerTypeInt() const { return first; }
WebPointerProperties::PointerType GetPointerType() const {
return static_cast<WebPointerProperties::PointerType>(first);
}
int RawId() const { return second; }
} IncomingId;
typedef struct PointerAttributes {
IncomingId incoming_id;
bool is_active_buttons;
bool can_scroll;
PointerAttributes()
: incoming_id(), is_active_buttons(false), can_scroll(false) {}
PointerAttributes(IncomingId incoming_id,
bool is_active_buttons,
bool can_scroll)
: incoming_id(incoming_id),
is_active_buttons(is_active_buttons),
can_scroll(can_scroll) {}
} PointerAttributes;
int AddIdAndActiveButtons(const IncomingId,
bool is_active_buttons,
bool can_scroll);
bool IsPrimary(const int) const;
void SetIdTypeButtons(PointerEventInit&,
const WebPointerProperties&,
unsigned buttons,
bool can_scroll);
void SetEventSpecificFields(PointerEventInit&, const AtomicString& type);
// Creates pointerevents like boundary and capture events from another
// pointerevent (i.e. up/down/move events).
PointerEvent* CreatePointerEventFrom(PointerEvent*,
const AtomicString&,
EventTarget*);
static const int kInvalidId;
int current_id_;
HashMap<IncomingId,
int,
WTF::PairHash<int, int>,
WTF::PairHashTraits<UnsignedHash, UnsignedHash>>
pointer_incoming_id_mapping_;
HashMap<int, PointerAttributes, WTF::IntHash<int>, UnsignedHash>
pointer_id_mapping_;
int primary_id_[static_cast<int>(
WebPointerProperties::PointerType::kLastEntry) +
1];
int id_count_[static_cast<int>(
WebPointerProperties::PointerType::kLastEntry) +
1];
};
} // namespace blink
#endif // PointerEventFactory_h