The version of vichan running on lainchan.org
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

188 linhas
4.1KB

  1. (function ($) {
  2. 'use strict';
  3. $.sceditor.plugins.undo = function () {
  4. var base = this;
  5. var editor;
  6. var charChangedCount = 0;
  7. var previousValue;
  8. var undoLimit = 50;
  9. var redoStates = [];
  10. var undoStates = [];
  11. var ignoreNextValueChanged = false;
  12. /**
  13. * Sets the editor to the specified state.
  14. *
  15. * @param {Object} state
  16. * @private
  17. */
  18. var applyState = function (state) {
  19. ignoreNextValueChanged = true;
  20. previousValue = state.value;
  21. editor.sourceMode(state.sourceMode);
  22. editor.val(state.value, false);
  23. editor.focus();
  24. if (state.sourceMode) {
  25. editor.sourceEditorCaret(state.caret);
  26. } else {
  27. editor.getRangeHelper().restoreRange();
  28. }
  29. ignoreNextValueChanged = false;
  30. };
  31. /**
  32. * Caluclates the number of characters that have changed
  33. * between two strings.
  34. *
  35. * @param {String} strA
  36. * @param {String} strB
  37. * @return {String}
  38. * @private
  39. */
  40. var simpleDiff = function (strA, strB) {
  41. var start, end, aLenDiff, bLenDiff,
  42. aLength = strA.length,
  43. bLength = strB.length,
  44. length = Math.max(aLength, bLength);
  45. // Calculate the start
  46. for (start = 0; start < length; start++) {
  47. if (strA.charAt(start) !== strB.charAt(start)) {
  48. break;
  49. }
  50. }
  51. // Calculate the end
  52. aLenDiff = aLength < bLength ? bLength - aLength : 0;
  53. bLenDiff = bLength < aLength ? aLength - bLength : 0;
  54. for (end = length - 1; end >= 0; end--) {
  55. if (strA.charAt(end - aLenDiff) !==
  56. strB.charAt(end - bLenDiff)) {
  57. break;
  58. }
  59. }
  60. return (end - start) + 1;
  61. };
  62. base.init = function () {
  63. // The this variable will be set to the instance of the editor
  64. // calling it, hence why the plugins "this" is saved to the base
  65. // variable.
  66. editor = this;
  67. undoLimit = editor.undoLimit || undoLimit;
  68. // addShortcut is the easiest way to add handlers to specific
  69. // shortcuts
  70. editor.addShortcut('ctrl+z', base.undo);
  71. editor.addShortcut('ctrl+shift+z', base.redo);
  72. editor.addShortcut('ctrl+y', base.redo);
  73. };
  74. base.undo = function () {
  75. var state = undoStates.pop();
  76. var rawEditorValue = editor.val(null, false);
  77. if (state && !redoStates.length && rawEditorValue === state.value) {
  78. state = undoStates.pop();
  79. }
  80. if (state) {
  81. if (!redoStates.length) {
  82. redoStates.push({
  83. 'caret': editor.sourceEditorCaret(),
  84. 'sourceMode': editor.sourceMode(),
  85. 'value': rawEditorValue
  86. });
  87. }
  88. redoStates.push(state);
  89. applyState(state);
  90. }
  91. return false;
  92. };
  93. base.redo = function () {
  94. var state = redoStates.pop();
  95. if (!undoStates.length) {
  96. undoStates.push(state);
  97. state = redoStates.pop();
  98. }
  99. if (state) {
  100. undoStates.push(state);
  101. applyState(state);
  102. }
  103. return false;
  104. };
  105. base.signalReady = function () {
  106. var rawValue = editor.val(null, false);
  107. // Store the initial value as the last value
  108. previousValue = rawValue;
  109. undoStates.push({
  110. 'caret': this.sourceEditorCaret(),
  111. 'sourceMode': this.sourceMode(),
  112. 'value': rawValue
  113. });
  114. };
  115. /**
  116. * Handle the valueChanged signal.
  117. *
  118. * e.rawValue will either be the raw HTML from the WYSIWYG editor with
  119. * the rangeHelper range markers inserted, or it will be the raw value
  120. * of the source editor (BBCode or HTML depening on plugins).
  121. * @return {void}
  122. */
  123. base.signalValuechangedEvent = function (e) {
  124. var rawValue = e.rawValue;
  125. if (undoLimit > 0 && undoStates.length > undoLimit) {
  126. undoStates.shift();
  127. }
  128. // If the editor hasn't fully loaded yet,
  129. // then the previous value won't be set.
  130. if (ignoreNextValueChanged || !previousValue ||
  131. previousValue === rawValue) {
  132. return;
  133. }
  134. // Value has changed so remove all redo states
  135. redoStates.length = 0;
  136. charChangedCount += simpleDiff(previousValue, rawValue);
  137. if (charChangedCount < 20) {
  138. return;
  139. // ??
  140. } else if (charChangedCount < 50 && !/\s$/g.test(e.rawValue)) {
  141. return;
  142. }
  143. undoStates.push({
  144. 'caret': editor.sourceEditorCaret(),
  145. 'sourceMode': editor.sourceMode(),
  146. 'value': rawValue
  147. });
  148. charChangedCount = 0;
  149. previousValue = rawValue;
  150. };
  151. };
  152. }(jQuery));