shortcut.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /**
  2. * @fileOverview
  3. *
  4. * 添加快捷键支持
  5. *
  6. * @author: techird
  7. * @copyright: Baidu FEX, 2014
  8. */
  9. define(function(require, exports, module) {
  10. var kity = require('./kity');
  11. var utils = require('./utils');
  12. var keymap = require('./keymap');
  13. var Minder = require('./minder');
  14. var MinderEvent = require('./event');
  15. /**
  16. * 计算包含 meta 键的 keycode
  17. *
  18. * @param {String|KeyEvent} unknown
  19. */
  20. function getMetaKeyCode(unknown) {
  21. var CTRL_MASK = 0x1000;
  22. var ALT_MASK = 0x2000;
  23. var SHIFT_MASK = 0x4000;
  24. var metaKeyCode = 0;
  25. if (typeof(unknown) == 'string') {
  26. // unknown as string
  27. unknown.toLowerCase().split(/\+\s*/).forEach(function(name) {
  28. switch(name) {
  29. case 'ctrl':
  30. case 'cmd':
  31. metaKeyCode |= CTRL_MASK;
  32. break;
  33. case 'alt':
  34. metaKeyCode |= ALT_MASK;
  35. break;
  36. case 'shift':
  37. metaKeyCode |= SHIFT_MASK;
  38. break;
  39. default:
  40. metaKeyCode |= keymap[name];
  41. }
  42. });
  43. } else {
  44. // unknown as key event
  45. if (unknown.ctrlKey || unknown.metaKey) {
  46. metaKeyCode |= CTRL_MASK;
  47. }
  48. if (unknown.altKey) {
  49. metaKeyCode |= ALT_MASK;
  50. }
  51. if (unknown.shiftKey) {
  52. metaKeyCode |= SHIFT_MASK;
  53. }
  54. metaKeyCode |= unknown.keyCode;
  55. }
  56. return metaKeyCode;
  57. }
  58. kity.extendClass(MinderEvent, {
  59. isShortcutKey: function(keyCombine) {
  60. var keyEvent = this.originEvent;
  61. if (!keyEvent) return false;
  62. return getMetaKeyCode(keyCombine) == getMetaKeyCode(keyEvent);
  63. }
  64. });
  65. Minder.registerInitHook(function() {
  66. this._initShortcutKey();
  67. });
  68. kity.extendClass(Minder, {
  69. _initShortcutKey: function() {
  70. this._bindShortcutKeys();
  71. },
  72. _bindShortcutKeys: function() {
  73. var map = this._shortcutKeys = {};
  74. var has = 'hasOwnProperty';
  75. this.on('keydown', function(e) {
  76. for (var keys in map) {
  77. if (!map[has](keys)) continue;
  78. if (e.isShortcutKey(keys)) {
  79. var fn = map[keys];
  80. if (fn.__statusCondition && fn.__statusCondition != this.getStatus()) return;
  81. fn();
  82. e.preventDefault();
  83. }
  84. }
  85. });
  86. },
  87. addShortcut: function(keys, fn) {
  88. var binds = this._shortcutKeys;
  89. keys.split(/\|\s*/).forEach(function(combine) {
  90. var parts = combine.split('::');
  91. var status;
  92. if (parts.length > 1) {
  93. combine = parts[1];
  94. status = parts[0];
  95. fn.__statusCondition = status;
  96. }
  97. binds[combine] = fn;
  98. });
  99. },
  100. addCommandShortcutKeys: function(cmd, keys) {
  101. var binds = this._commandShortcutKeys || (this._commandShortcutKeys = {});
  102. var obj = {},
  103. km = this;
  104. if (keys) {
  105. obj[cmd] = keys;
  106. } else {
  107. obj = cmd;
  108. }
  109. var minder = this;
  110. utils.each(obj, function(keys, command) {
  111. binds[command] = keys;
  112. minder.addShortcut(keys, function execCommandByShortcut() {
  113. /**
  114. * 之前判断有问题,由 === 0 改为 !== -1
  115. * @editor Naixor
  116. * @Date 2015-12-2
  117. */
  118. if (minder.queryCommandState(command) !== -1) {
  119. minder.execCommand(command);
  120. }
  121. });
  122. });
  123. },
  124. getCommandShortcutKey: function(cmd) {
  125. var binds = this._commandShortcutKeys;
  126. return binds && binds[cmd] || null;
  127. },
  128. /**
  129. * @Desc: 添加一个判断是否支持原生Clipboard的变量,用于对ctrl + v和ctrl + c的处理
  130. * @Editor: Naixor
  131. * @Date: 2015.9.20
  132. */
  133. supportClipboardEvent: (function(window) {
  134. return !!window.ClipboardEvent;
  135. })(window)
  136. });
  137. });