WebOrbiton
v1.0.0.1

StocketBase

137 lines · 3.4 KB
  1. (function (global) {
  2. 'use strict';
  3. ​
  4. const STORAGE_KEY = 'stocketbase_editor_shortcuts';
  5. ​
  6. const DEFAULT_SHORTCUTS = {
  7. bold: { label: 'Bold', combo: 'Ctrl+B' },
  8. italic: { label: 'Italic', combo: 'Ctrl+I' },
  9. underline: { label: 'Underline', combo: 'Ctrl+U' },
  10. strikethrough: { label: 'Strikethrough', combo: 'Ctrl+Shift+X' },
  11. add_block: { label: 'Add block below', combo: 'Ctrl+Enter' },
  12. remove_block: { label: 'Remove block', combo: 'Ctrl+Backspace' },
  13. move_block_up: { label: 'Move block up', combo: 'Ctrl+Shift+ArrowUp' },
  14. move_block_down: { label: 'Move block down', combo: 'Ctrl+Shift+ArrowDown' },
  15. save: { label: 'Save', combo: 'Ctrl+S' },
  16. };
  17. ​
  18. function loadOverrides() {
  19. try {
  20. const raw = window.localStorage.getItem(STORAGE_KEY);
  21. if (!raw) {
  22. return {};
  23. }
  24. const parsed = JSON.parse(raw);
  25. return parsed && typeof parsed === 'object' ? parsed : {};
  26. } catch (error) {
  27. return {};
  28. }
  29. }
  30. ​
  31. function saveOverrides(overrides) {
  32. try {
  33. window.localStorage.setItem(STORAGE_KEY, JSON.stringify(overrides));
  34. return true;
  35. } catch (error) {
  36. return false;
  37. }
  38. }
  39. ​
  40. function getShortcuts() {
  41. const overrides = loadOverrides();
  42. const result = {};
  43. Object.keys(DEFAULT_SHORTCUTS).forEach((key) => {
  44. result[key] = {
  45. label: DEFAULT_SHORTCUTS[key].label,
  46. combo: overrides[key] || DEFAULT_SHORTCUTS[key].combo,
  47. isDefault: !overrides[key],
  48. };
  49. });
  50. return result;
  51. }
  52. ​
  53. function setShortcut(action, combo) {
  54. if (!DEFAULT_SHORTCUTS[action]) {
  55. return false;
  56. }
  57. const overrides = loadOverrides();
  58. if (!combo || combo === DEFAULT_SHORTCUTS[action].combo) {
  59. delete overrides[action];
  60. } else {
  61. overrides[action] = combo;
  62. }
  63. return saveOverrides(overrides);
  64. }
  65. ​
  66. function resetShortcut(action) {
  67. const overrides = loadOverrides();
  68. delete overrides[action];
  69. return saveOverrides(overrides);
  70. }
  71. ​
  72. function resetAllShortcuts() {
  73. return saveOverrides({});
  74. }
  75. ​
  76. function comboFromEvent(event) {
  77. const parts = [];
  78. if (event.ctrlKey || event.metaKey) {
  79. parts.push('Ctrl');
  80. }
  81. if (event.altKey) {
  82. parts.push('Alt');
  83. }
  84. if (event.shiftKey) {
  85. parts.push('Shift');
  86. }
  87. ​
  88. let key = event.key;
  89. const ignoredKeys = ['Control', 'Alt', 'Shift', 'Meta'];
  90. if (ignoredKeys.indexOf(key) !== -1) {
  91. return null;
  92. }
  93. ​
  94. if (key === ' ') {
  95. key = 'Space';
  96. } else if (key.length === 1) {
  97. key = key.toUpperCase();
  98. }
  99. ​
  100. parts.push(key);
  101. return parts.join('+');
  102. }
  103. ​
  104. function matchesCombo(event, combo) {
  105. if (!combo) {
  106. return false;
  107. }
  108. const eventCombo = comboFromEvent(event);
  109. return eventCombo === combo;
  110. }
  111. ​
  112. function findMatchingAction(event, shortcuts) {
  113. const eventCombo = comboFromEvent(event);
  114. if (!eventCombo) {
  115. return null;
  116. }
  117. const keys = Object.keys(shortcuts);
  118. for (let i = 0; i < keys.length; i++) {
  119. if (shortcuts[keys[i]].combo === eventCombo) {
  120. return keys[i];
  121. }
  122. }
  123. return null;
  124. }
  125. ​
  126. global.StocketBaseShortcuts = {
  127. DEFAULT_SHORTCUTS: DEFAULT_SHORTCUTS,
  128. getShortcuts: getShortcuts,
  129. setShortcut: setShortcut,
  130. resetShortcut: resetShortcut,
  131. resetAllShortcuts: resetAllShortcuts,
  132. comboFromEvent: comboFromEvent,
  133. matchesCombo: matchesCombo,
  134. findMatchingAction: findMatchingAction,
  135. };
  136. })(window);
  137. ​