Built files from Bizgaze WebServer
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

summernote-ext-specialchars.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. (function(factory) {
  2. /* global define */
  3. if (typeof define === 'function' && define.amd) {
  4. // AMD. Register as an anonymous module.
  5. define(['jquery'], factory);
  6. } else if (typeof module === 'object' && module.exports) {
  7. // Node/CommonJS
  8. module.exports = factory(require('jquery'));
  9. } else {
  10. // Browser globals
  11. factory(window.jQuery);
  12. }
  13. }(function($) {
  14. $.extend($.summernote.plugins, {
  15. 'specialchars': function(context) {
  16. var self = this;
  17. var ui = $.summernote.ui;
  18. var $editor = context.layoutInfo.editor;
  19. var options = context.options;
  20. var lang = options.langInfo;
  21. var KEY = {
  22. UP: 38,
  23. DOWN: 40,
  24. LEFT: 37,
  25. RIGHT: 39,
  26. ENTER: 13,
  27. };
  28. var COLUMN_LENGTH = 15;
  29. var COLUMN_WIDTH = 35;
  30. var currentColumn = 0;
  31. var currentRow = 0;
  32. var totalColumn = 0;
  33. var totalRow = 0;
  34. // special characters data set
  35. var specialCharDataSet = [
  36. '"', '&', '<', '>', '¡', '¢',
  37. '£', '¤', '¥', '¦', '§',
  38. '¨', '©', 'ª', '«', '¬',
  39. '®', '¯', '°', '±', '²',
  40. '³', '´', 'µ', '¶', '·',
  41. '¸', '¹', 'º', '»', '¼',
  42. '½', '¾', '¿', '×', '÷',
  43. 'ƒ', 'ˆ', '˜', '–', '—',
  44. '‘', '’', '‚', '“', '”',
  45. '„', '†', '‡', '•', '…',
  46. '‰', '′', '″', '‹', '›',
  47. '‾', '⁄', '€', 'ℑ', '℘',
  48. 'ℜ', '™', 'ℵ', '←', '↑',
  49. '→', '↓', '↔', '↵', '⇐',
  50. '⇑', '⇒', '⇓', '⇔', '∀',
  51. '∂', '∃', '∅', '∇', '∈',
  52. '∉', '∋', '∏', '∑', '−',
  53. '∗', '√', '∝', '∞', '∠',
  54. '∧', '∨', '∩', '∪', '∫',
  55. '∴', '∼', '≅', '≈', '≠',
  56. '≡', '≤', '≥', '⊂', '⊃',
  57. '⊄', '⊆', '⊇', '⊕', '⊗',
  58. '⊥', '⋅', '⌈', '⌉', '⌊',
  59. '⌋', '◊', '♠', '♣', '♥',
  60. '♦',
  61. ];
  62. context.memo('button.specialchars', function() {
  63. return ui.button({
  64. contents: '<i class="fa fa-font fa-flip-vertical">',
  65. tooltip: lang.specialChar.specialChar,
  66. click: function() {
  67. self.show();
  68. },
  69. }).render();
  70. });
  71. /**
  72. * Make Special Characters Table
  73. *
  74. * @member plugin.specialChar
  75. * @private
  76. * @return {jQuery}
  77. */
  78. this.makeSpecialCharSetTable = function() {
  79. var $table = $('<table/>');
  80. $.each(specialCharDataSet, function(idx, text) {
  81. var $td = $('<td/>').addClass('note-specialchar-node');
  82. var $tr = (idx % COLUMN_LENGTH === 0) ? $('<tr/>') : $table.find('tr').last();
  83. var $button = ui.button({
  84. callback: function($node) {
  85. $node.html(text);
  86. $node.attr('title', text);
  87. $node.attr('data-value', encodeURIComponent(text));
  88. $node.css({
  89. width: COLUMN_WIDTH,
  90. 'margin-right': '2px',
  91. 'margin-bottom': '2px',
  92. });
  93. },
  94. }).render();
  95. $td.append($button);
  96. $tr.append($td);
  97. if (idx % COLUMN_LENGTH === 0) {
  98. $table.append($tr);
  99. }
  100. });
  101. totalRow = $table.find('tr').length;
  102. totalColumn = COLUMN_LENGTH;
  103. return $table;
  104. };
  105. this.initialize = function() {
  106. var $container = options.dialogsInBody ? $(document.body) : $editor;
  107. var body = '<div class="form-group row-fluid">' + this.makeSpecialCharSetTable()[0].outerHTML + '</div>';
  108. this.$dialog = ui.dialog({
  109. title: lang.specialChar.select,
  110. body: body,
  111. }).render().appendTo($container);
  112. };
  113. this.show = function() {
  114. var text = context.invoke('editor.getSelectedText');
  115. context.invoke('editor.saveRange');
  116. this.showSpecialCharDialog(text).then(function(selectChar) {
  117. context.invoke('editor.restoreRange');
  118. // build node
  119. var $node = $('<span></span>').html(selectChar)[0];
  120. if ($node) {
  121. // insert video node
  122. context.invoke('editor.insertNode', $node);
  123. }
  124. }).fail(function() {
  125. context.invoke('editor.restoreRange');
  126. });
  127. };
  128. /**
  129. * show image dialog
  130. *
  131. * @param {jQuery} $dialog
  132. * @return {Promise}
  133. */
  134. this.showSpecialCharDialog = function(text) {
  135. return $.Deferred(function(deferred) {
  136. var $specialCharDialog = self.$dialog;
  137. var $specialCharNode = $specialCharDialog.find('.note-specialchar-node');
  138. var $selectedNode = null;
  139. var ARROW_KEYS = [KEY.UP, KEY.DOWN, KEY.LEFT, KEY.RIGHT];
  140. var ENTER_KEY = KEY.ENTER;
  141. function addActiveClass($target) {
  142. if (!$target) {
  143. return;
  144. }
  145. $target.find('button').addClass('active');
  146. $selectedNode = $target;
  147. }
  148. function removeActiveClass($target) {
  149. $target.find('button').removeClass('active');
  150. $selectedNode = null;
  151. }
  152. // find next node
  153. function findNextNode(row, column) {
  154. var findNode = null;
  155. $.each($specialCharNode, function(idx, $node) {
  156. var findRow = Math.ceil((idx + 1) / COLUMN_LENGTH);
  157. var findColumn = ((idx + 1) % COLUMN_LENGTH === 0) ? COLUMN_LENGTH : (idx + 1) % COLUMN_LENGTH;
  158. if (findRow === row && findColumn === column) {
  159. findNode = $node;
  160. return false;
  161. }
  162. });
  163. return $(findNode);
  164. }
  165. function arrowKeyHandler(keyCode) {
  166. // left, right, up, down key
  167. var $nextNode;
  168. var lastRowColumnLength = $specialCharNode.length % totalColumn;
  169. if (KEY.LEFT === keyCode) {
  170. if (currentColumn > 1) {
  171. currentColumn = currentColumn - 1;
  172. } else if (currentRow === 1 && currentColumn === 1) {
  173. currentColumn = lastRowColumnLength;
  174. currentRow = totalRow;
  175. } else {
  176. currentColumn = totalColumn;
  177. currentRow = currentRow - 1;
  178. }
  179. } else if (KEY.RIGHT === keyCode) {
  180. if (currentRow === totalRow && lastRowColumnLength === currentColumn) {
  181. currentColumn = 1;
  182. currentRow = 1;
  183. } else if (currentColumn < totalColumn) {
  184. currentColumn = currentColumn + 1;
  185. } else {
  186. currentColumn = 1;
  187. currentRow = currentRow + 1;
  188. }
  189. } else if (KEY.UP === keyCode) {
  190. if (currentRow === 1 && lastRowColumnLength < currentColumn) {
  191. currentRow = totalRow - 1;
  192. } else {
  193. currentRow = currentRow - 1;
  194. }
  195. } else if (KEY.DOWN === keyCode) {
  196. currentRow = currentRow + 1;
  197. }
  198. if (currentRow === totalRow && currentColumn > lastRowColumnLength) {
  199. currentRow = 1;
  200. } else if (currentRow > totalRow) {
  201. currentRow = 1;
  202. } else if (currentRow < 1) {
  203. currentRow = totalRow;
  204. }
  205. $nextNode = findNextNode(currentRow, currentColumn);
  206. if ($nextNode) {
  207. removeActiveClass($selectedNode);
  208. addActiveClass($nextNode);
  209. }
  210. }
  211. function enterKeyHandler() {
  212. if (!$selectedNode) {
  213. return;
  214. }
  215. deferred.resolve(decodeURIComponent($selectedNode.find('button').attr('data-value')));
  216. $specialCharDialog.modal('hide');
  217. }
  218. function keyDownEventHandler(event) {
  219. event.preventDefault();
  220. var keyCode = event.keyCode;
  221. if (keyCode === undefined || keyCode === null) {
  222. return;
  223. }
  224. // check arrowKeys match
  225. if (ARROW_KEYS.indexOf(keyCode) > -1) {
  226. if ($selectedNode === null) {
  227. addActiveClass($specialCharNode.eq(0));
  228. currentColumn = 1;
  229. currentRow = 1;
  230. return;
  231. }
  232. arrowKeyHandler(keyCode);
  233. } else if (keyCode === ENTER_KEY) {
  234. enterKeyHandler();
  235. }
  236. return false;
  237. }
  238. // remove class
  239. removeActiveClass($specialCharNode);
  240. // find selected node
  241. if (text) {
  242. for (var i = 0; i < $specialCharNode.length; i++) {
  243. var $checkNode = $($specialCharNode[i]);
  244. if ($checkNode.text() === text) {
  245. addActiveClass($checkNode);
  246. currentRow = Math.ceil((i + 1) / COLUMN_LENGTH);
  247. currentColumn = (i + 1) % COLUMN_LENGTH;
  248. }
  249. }
  250. }
  251. ui.onDialogShown(self.$dialog, function() {
  252. $(document).on('keydown', keyDownEventHandler);
  253. self.$dialog.find('button').tooltip();
  254. $specialCharNode.on('click', function(event) {
  255. event.preventDefault();
  256. deferred.resolve(decodeURIComponent($(event.currentTarget).find('button').attr('data-value')));
  257. ui.hideDialog(self.$dialog);
  258. });
  259. });
  260. ui.onDialogHidden(self.$dialog, function() {
  261. $specialCharNode.off('click');
  262. self.$dialog.find('button').tooltip('destroy');
  263. $(document).off('keydown', keyDownEventHandler);
  264. if (deferred.state() === 'pending') {
  265. deferred.reject();
  266. }
  267. });
  268. ui.showDialog(self.$dialog);
  269. });
  270. };
  271. },
  272. });
  273. }));