keyboard.mdx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. ---
  2. title: Keyboard Module
  3. ---
  4. The Keyboard module enables custom behavior for keyboard events in particular contexts. Quill uses this to bind formatting hotkeys and prevent undesirable browser side effects.
  5. ### Key Bindings
  6. Keyboard handlers are bound to a particular key and key modifiers. The `key` is the JavaScript event key code, but string shorthands are allowed for alphanumeric keys and some common keys.
  7. Key modifiers include: `metaKey`, `ctrlKey`, `shiftKey` and `altKey`. In addition, `shortKey` is a platform specific modifier equivalent to `metaKey` on a Mac and `ctrlKey` on Linux and Windows.
  8. Handlers will be called with `this` bound to the keyboard instance and be passed the current selection range.
  9. ```js
  10. quill.keyboard.addBinding({
  11. key: 'B',
  12. shortKey: true
  13. }, function(range, context) {
  14. this.quill.formatText(range, 'bold', true);
  15. });
  16. // addBinding may also be called with one parameter,
  17. // in the same form as in initialization
  18. quill.keyboard.addBinding({
  19. key: 'B',
  20. shortKey: true,
  21. handler: function(range, context) {
  22. }
  23. });
  24. ```
  25. If a modifier key is `false`, it is assumed to mean that modifier is not active. You may also pass `null` to mean any value for the modifier.
  26. ```js
  27. // Only b with no modifier will trigger
  28. quill.keyboard.addBinding({ key: 'B' }, handler);
  29. // Only shift+b will trigger
  30. quill.keyboard.addBinding({ key: 'B', shiftKey: true }, handler);
  31. // Either b or shift+b will trigger
  32. quill.keyboard.addBinding({ key: 'B', shiftKey: null }, handler);
  33. ```
  34. Multiple handlers may be bound to the same key and modifier combination. Handlers will be called synchronously, in the order they were bound. By default, a handler stops propagating to the next handler, unless it explicitly returns `true`.
  35. ```js
  36. quill.keyboard.addBinding({ key: 'tab' }, function(range) {
  37. // I will normally prevent handlers of the tab key
  38. // Return true to let later handlers be called
  39. return true;
  40. });
  41. ```
  42. Note: Since Quill's default handlers are added at initialization, the only way to prevent them is to add yours in the [configuration](#configuration).
  43. ### Context
  44. Contexts enable further specification for handlers to be called only in particular scenarios. Regardless if context is specified, a context object is provided as a second parameter for all handlers.
  45. ```js
  46. // If the user hits backspace at the beginning of list or blockquote,
  47. // remove the format instead delete any text
  48. quill.keyboard.addBinding({ key: Keyboard.keys.BACKSPACE }, {
  49. collapsed: true,
  50. format: ['blockquote', 'list'],
  51. offset: 0
  52. }, function(range, context) {
  53. if (context.format.list) {
  54. this.quill.format('list', false);
  55. } else {
  56. this.quill.format('blockquote', false);
  57. }
  58. });
  59. ```
  60. #### collapsed
  61. If `true`, handler is called only if the user's selection is collapsed, i.e. in cursor form. If `false`, the users's selection must be non-zero length, such as when the user has highlighted text.
  62. #### empty
  63. If `true`, called only if user's selection is on an empty line, `false` for a non-empty line. Note setting empty to be true implies collapsed is also true and offset is 0—otherwise the user's selection would not be on an empty line.
  64. ```js
  65. // If the user hits enter on an empty list, remove the list instead
  66. quill.keyboard.addBinding({ key: Keyboard.keys.ENTER }, {
  67. empty: true, // implies collapsed: true and offset: 0
  68. format: ['list']
  69. }, function(range, context) {
  70. this.quill.format('list', false);
  71. });
  72. ```
  73. #### format
  74. When an Array, handler will be called if *any* of the specified formats are active. When an Object, *all* specified formats conditions must be met. In either case, the format property of the context parameter will be an Object of all current active formats, the same returned by `quill.getFormat()`.
  75. ```js
  76. const context = {
  77. format: {
  78. list: true, // must be on a list, but can be any value
  79. script: 'super', // must be exactly 'super', 'sub' will not suffice
  80. link: false // cannot be in any link
  81. }
  82. };
  83. ```
  84. #### offset
  85. Handler will be only called when the user's selection starts `offset` characters from the beginning of the line. Note this is before printable keys have been applied. This is useful in combination with other context specifications.
  86. #### prefix
  87. Regex that must match the text immediately preceding the user's selection's start position. The text will not match cross format boundaries. The supplied `context.prefix` value will be the entire immediately preceding text, not just the regex match.
  88. ```js
  89. // When the user types space...
  90. quill.keyboard.addBinding({ key: ' ' }, {
  91. collapsed: true,
  92. format: { list: false }, // ...on a line that's not already a list
  93. prefix: /^-$/, // ...following a '-' character
  94. offset: 1, // ...at the 1st position of the line,
  95. // otherwise handler would trigger if the user
  96. // typed hyphen+space mid sentence
  97. }, function(range, context) {
  98. // the space character is consumed by this handler
  99. // so we only need to delete the hyphen
  100. this.quill.deleteText(range.index - 1, 1);
  101. // apply bullet formatting to the line
  102. this.quill.formatLine(range.index, 1, 'list', 'bullet');
  103. // restore selection
  104. this.quill.setSelection(range.index - 1);
  105. // console.log(context.prefix) would print '-'
  106. });
  107. ```
  108. #### suffix
  109. The same as [`prefix`](#prefix) except matching text immediately following the user's selection's end position.
  110. ### Configuration
  111. By default, Quill comes with several useful key bindings, for example indenting lists with tabs. You can add your own upon initialization.
  112. Some bindings are essential to preventing dangerous browser defaults, such as the enter and backspace keys. You cannot remove these bindings to revert to native browser behaviors. However since bindings specified in the configuration will run before Quill's defaults, you can handle special cases and propagate to Quill's otherwise.
  113. Adding a binding with `quill.keyboard.addBinding` will not run before Quill's because the defaults bindings will have been added by that point.
  114. Each binding config must contain `key` and `handler` options, and may optionally include any of the `context` options.
  115. ```javascript
  116. const bindings = {
  117. // This will overwrite the default binding also named 'tab'
  118. tab: {
  119. key: 9,
  120. handler: function() {
  121. // Handle tab
  122. }
  123. },
  124. // There is no default binding named 'custom'
  125. // so this will be added without overwriting anything
  126. custom: {
  127. key: 'B',
  128. shiftKey: true,
  129. handler: function(range, context) {
  130. // Handle shift+b
  131. }
  132. },
  133. list: {
  134. key: 'backspace',
  135. format: ['list'],
  136. handler: function(range, context) {
  137. if (context.offset === 0) {
  138. // When backspace on the first character of a list,
  139. // remove the list instead
  140. this.quill.format('list', false, Quill.sources.USER);
  141. } else {
  142. // Otherwise propogate to Quill's default
  143. return true;
  144. }
  145. }
  146. }
  147. };
  148. const quill = new Quill('#editor', {
  149. modules: {
  150. keyboard: {
  151. bindings: bindings
  152. }
  153. }
  154. });
  155. ```
  156. ### Performance
  157. Like DOM events, Quill key bindings are blocking calls on every match, so it is a bad idea to have a very expensive handler for a very common key binding. Apply the same performance best practices as you would when attaching to common blocking DOM events, like `scroll` or `mousemove`.