Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1694)

Unified Diff: ui/events/keycodes/dom/dom_key.h

Issue 1284433002: Revise ui::DomKey to unify character and non-character codes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: IsDead Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/events/event.cc ('k') | ui/events/keycodes/dom/dom_key_data.inc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/keycodes/dom/dom_key.h
diff --git a/ui/events/keycodes/dom/dom_key.h b/ui/events/keycodes/dom/dom_key.h
index 25ea09209b522e649fae8c8f5fe6e6a3438974d8..9c8847869c6ea4bba9b0566b402158e7b1e7473d 100644
--- a/ui/events/keycodes/dom/dom_key.h
+++ b/ui/events/keycodes/dom/dom_key.h
@@ -5,13 +5,154 @@
#ifndef UI_EVENTS_KEYCODES_DOM3_DOM_KEY_H_
#define UI_EVENTS_KEYCODES_DOM3_DOM_KEY_H_
+#include <stdint.h>
+
+#include "base/logging.h"
+
namespace ui {
+// Integer representation of UI Events KeyboardEvent.key value.
+//
+// The semantics follow the web string form[1]: the value is either a
+// Unicode character or one of a defined set of additional values[2].
+// There is one notable difference from the UI Events string key: for
+// the 'Dead' key, this type provides a whole range of values that also
+// encode the associated combining character. (They are not quite the
+// same thing: a dead key is a non-printing operator that modifies a
+// subsequent printing character, whereas a Unicode combining character
+// is a printable character in its own right that attaches to a preceding
+// character in a string.) This allows the interpretation of any keystroke
+// to be carried as a single integer value.
+//
+// DomKey::NONE is a sentinel used to indicate an error or undefined value.
+// It is not the same as Unicode code point 0 (ASCII NUL) or the valid DOM
+// key 'Unidentified'.
+//
+// References:
+// [1] http://www.w3.org/TR/uievents/#widl-KeyboardEvent-key
+// [2] http://www.w3.org/TR/DOM-Level-3-Events-key/
+//
+class DomKey {
+ public:
+ using Base = int32_t;
+
+ private:
+ // Integer representation of DomKey. This is arranged so that DomKey encoded
+ // values are distinct from Unicode code points, so that we can dynamically
+ // verify that they are not accidentally conflated.
+ //
+ // 31 24 16 8 0
+ // | | | | | | | | |
+ // | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+ // | z |c|s| v |
+ //
+ // From low to high:
+ // - |v| is a value whose interpretation depends on the kind of key:
+ // - for a Unicode value, it is the code point (0 <= v <= 0x10FFFF);
+ // - for a dead key, the code point of the associated combining character;
+ // - for others, an arbitrary distinct value.
+ // - |s| is set for a valid symbolic key (i.e. not a Unicode character).
+ // - |c| is set if |v| holds a code point (for either a Unicode character
+ // directly, or a dead-key combining character).
+ // - |z| is reserved and always zero.
+ //
+ // As consequences of this representation,
+ // - all valid DomKey encodings have at least one of |c| or |s| set, so
+ // they can't be confused with raw Unicode characters (where both are 0).
+ // - integer 0 is not a valid encoding, and can be used for DomKey::NONE.
+ //
+ enum { VALUE_BITS = 21 };
+ enum Type : Base {
+ VALUE_MASK = (1L << VALUE_BITS) - 1,
+ TF_SYMBOLIC = (1L << VALUE_BITS),
+ TF_CODEPOINT = (1L << (VALUE_BITS + 1)),
+ TYPE_MASK = TF_CODEPOINT | TF_SYMBOLIC,
+ TYPE_UNICODE = TF_CODEPOINT,
+ TYPE_NON_UNICODE = TF_SYMBOLIC,
+ TYPE_DEAD = TF_CODEPOINT | TF_SYMBOLIC,
+ };
+ static_assert(TYPE_UNICODE != 0 && TYPE_NON_UNICODE != 0 && TYPE_DEAD != 0,
+ "suspicious representation change");
+
+ public:
+ enum InvalidKey : Base { NONE = 0 };
+// |dom_key_data.inc| describes the non-printable DomKey values, and is
+// included here to create constants for them in the DomKey:: scope.
+#define DOM_KEY_MAP_DECLARATION enum Key : Base
+#define DOM_KEY_UNI(key, id, value) id = (TYPE_UNICODE | (value))
+#define DOM_KEY_MAP_BEGIN FIRST_NON_UNICODE = TYPE_NON_UNICODE,
#define DOM_KEY_MAP(key, id) id
-#define DOM_KEY_MAP_DECLARATION enum class DomKey
+#define DOM_KEY_MAP_END LAST_NON_UNICODE
#include "ui/events/keycodes/dom/dom_key_data.inc"
-#undef DOM_KEY_MAP
#undef DOM_KEY_MAP_DECLARATION
+#undef DOM_KEY_MAP_BEGIN
+#undef DOM_KEY_MAP
+#undef DOM_KEY_MAP_END
+#undef DOM_KEY_UNI
+
+ // Create a DomKey, with the undefined-value sentinel DomKey::NONE.
+ DomKey() : value_(NONE) {}
+
+ // Create a DomKey from an encoded integer value. This is implicit so
+ // that DomKey::NAME constants don't need to be explicitly converted
+ // to DomKey.
+ DomKey(Base value) : value_(value) {
+ DCHECK(value == 0 || IsValid()) << value;
+ }
+
+ // Obtain the encoded integer representation of the DomKey.
+ operator Base() const { return value_; }
+
+ // True if the value is a valid DomKey (which excludes DomKey::NONE and
+ // integers not following the DomKey format).
+ bool IsValid() const { return (value_ & TYPE_MASK) != 0; }
+
+ // True if the value is a Unicode code point.
+ bool IsCharacter() const { return (value_ & TYPE_MASK) == TYPE_UNICODE; }
+
+ // True if the value is a dead key.
+ bool IsDeadKey() const { return (value_ & TYPE_MASK) == TYPE_DEAD; }
+
+ // Returns the Unicode code point for a Unicode key.
+ // It is incorrect to call this for other kinds of key.
+ int32_t ToCharacter() const {
+ DCHECK(IsCharacter()) << value_;
+ return value_ & VALUE_MASK;
+ }
+
+ // Returns the associated combining code point for a dead key.
+ // It is incorrect to call this for other kinds of key.
+ int32_t ToDeadKeyCombiningCharacter() const {
+ DCHECK(IsDeadKey()) << value_;
+ return value_ & VALUE_MASK;
+ }
+
+ // Returns a DomKey for the given Unicode character.
+ static DomKey FromCharacter(int32_t character) {
+ DCHECK(character >= 0 && character <= 0x10FFFF);
+ return DomKey(TYPE_UNICODE | character);
+ }
+
+ // Returns a dead-key DomKey for the given combining character.
+ static DomKey DeadKeyFromCombiningCharacter(int32_t combining_character) {
+ DCHECK(combining_character >= 0 && combining_character <= 0x10FFFF);
+ return DomKey(TYPE_DEAD | combining_character);
+ }
+
+ // Provide means to generate constant DomKey::Base values, primarily to
+ // allow conversion tables to be constant, without startup construction.
+ // In the future (cue the theremin) this can be replaced with constexpr
+ // functions.
+ template<Base C> struct Constant {
+ enum : Base {
+ Character = TYPE_UNICODE | C,
+ Dead = TYPE_DEAD | C,
+ };
+ };
+
+ private:
+ Base value_;
+};
} // namespace ui
« no previous file with comments | « ui/events/event.cc ('k') | ui/events/keycodes/dom/dom_key_data.inc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698