shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

summernote-ext-specialchars.js (10765B)


      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 
     19       var $editor = context.layoutInfo.editor;
     20       var options = context.options;
     21       var lang = options.langInfo;
     22 
     23       var KEY = {
     24         UP: 38,
     25         DOWN: 40,
     26         LEFT: 37,
     27         RIGHT: 39,
     28         ENTER: 13
     29       };
     30       var COLUMN_LENGTH = 15;
     31       var COLUMN_WIDTH = 35;
     32 
     33       var currentColumn, currentRow, totalColumn, totalRow = 0;
     34 
     35       // special characters data set
     36       var specialCharDataSet = [
     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       ];
     63 
     64       context.memo('button.specialCharacter', function () {
     65         return ui.button({
     66           contents: '<i class="fa fa-font fa-flip-vertical">',
     67           tooltip: lang.specialChar.specialChar,
     68           click: function () {
     69             self.show();
     70           }
     71         }).render();
     72       });
     73 
     74       /**
     75        * Make Special Characters Table
     76        *
     77        * @member plugin.specialChar
     78        * @private
     79        * @return {jQuery}
     80        */
     81       this.makeSpecialCharSetTable = function () {
     82         var $table = $('<table/>');
     83         $.each(specialCharDataSet, function (idx, text) {
     84           var $td = $('<td/>').addClass('note-specialchar-node');
     85           var $tr = (idx % COLUMN_LENGTH === 0) ? $('<tr/>') : $table.find('tr').last();
     86 
     87           var $button = ui.button({
     88             callback: function ($node) {
     89               $node.html(text);
     90               $node.attr('title', text);
     91               $node.attr('data-value', encodeURIComponent(text));
     92               $node.css({
     93                 width: COLUMN_WIDTH,
     94                 'margin-right': '2px',
     95                 'margin-bottom': '2px'
     96               });
     97             }
     98           }).render();
     99 
    100           $td.append($button);
    101 
    102           $tr.append($td);
    103           if (idx % COLUMN_LENGTH === 0) {
    104             $table.append($tr);
    105           }
    106         });
    107 
    108         totalRow = $table.find('tr').length;
    109         totalColumn = COLUMN_LENGTH;
    110 
    111         return $table;
    112       };
    113 
    114       this.initialize = function () {
    115         var $container = options.dialogsInBody ? $(document.body) : $editor;
    116 
    117         var body = '<div class="form-group row-fluid">' + this.makeSpecialCharSetTable()[0].outerHTML + '</div>';
    118 
    119         this.$dialog = ui.dialog({
    120           title: lang.specialChar.select,
    121           body: body
    122         }).render().appendTo($container);
    123       };
    124 
    125       this.show = function () {
    126         var text = context.invoke('editor.getSelectedText');
    127         context.invoke('editor.saveRange');
    128         this.showSpecialCharDialog(text).then(function (selectChar) {
    129           context.invoke('editor.restoreRange');
    130 
    131           // build node
    132           var $node = $('<span></span>').html(selectChar)[0];
    133 
    134           if ($node) {
    135             // insert video node
    136             context.invoke('editor.insertNode', $node);
    137           }
    138         }).fail(function () {
    139           context.invoke('editor.restoreRange');
    140         });
    141       };
    142 
    143       /**
    144        * show image dialog
    145        *
    146        * @param {jQuery} $dialog
    147        * @return {Promise}
    148        */
    149       this.showSpecialCharDialog = function (text) {
    150         return $.Deferred(function (deferred) {
    151           var $specialCharDialog = self.$dialog;
    152           var $specialCharNode = $specialCharDialog.find('.note-specialchar-node');
    153           var $selectedNode = null;
    154           var ARROW_KEYS = [KEY.UP, KEY.DOWN, KEY.LEFT, KEY.RIGHT];
    155           var ENTER_KEY = KEY.ENTER;
    156 
    157           function addActiveClass($target) {
    158             if (!$target) {
    159               return;
    160             }
    161             $target.find('button').addClass('active');
    162             $selectedNode = $target;
    163           }
    164 
    165           function removeActiveClass($target) {
    166             $target.find('button').removeClass('active');
    167             $selectedNode = null;
    168           }
    169 
    170           // find next node
    171           function findNextNode(row, column) {
    172             var findNode = null;
    173             $.each($specialCharNode, function (idx, $node) {
    174               var findRow = Math.ceil((idx + 1) / COLUMN_LENGTH);
    175               var findColumn = ((idx + 1) % COLUMN_LENGTH === 0) ? COLUMN_LENGTH : (idx + 1) % COLUMN_LENGTH;
    176               if (findRow === row && findColumn === column) {
    177                 findNode = $node;
    178                 return false;
    179               }
    180             });
    181             return $(findNode);
    182           }
    183 
    184           function arrowKeyHandler(keyCode) {
    185             // left, right, up, down key
    186             var $nextNode;
    187             var lastRowColumnLength = $specialCharNode.length % totalColumn;
    188 
    189             if (KEY.LEFT === keyCode) {
    190 
    191               if (currentColumn > 1) {
    192                 currentColumn = currentColumn - 1;
    193               } else if (currentRow === 1 && currentColumn === 1) {
    194                 currentColumn = lastRowColumnLength;
    195                 currentRow = totalRow;
    196               } else {
    197                 currentColumn = totalColumn;
    198                 currentRow = currentRow - 1;
    199               }
    200 
    201             } else if (KEY.RIGHT === keyCode) {
    202 
    203               if (currentRow === totalRow && lastRowColumnLength === currentColumn) {
    204                 currentColumn = 1;
    205                 currentRow = 1;
    206               } else if (currentColumn < totalColumn) {
    207                 currentColumn = currentColumn + 1;
    208               } else {
    209                 currentColumn = 1;
    210                 currentRow = currentRow + 1;
    211               }
    212 
    213             } else if (KEY.UP === keyCode) {
    214               if (currentRow === 1 && lastRowColumnLength < currentColumn) {
    215                 currentRow = totalRow - 1;
    216               } else {
    217                 currentRow = currentRow - 1;
    218               }
    219             } else if (KEY.DOWN === keyCode) {
    220               currentRow = currentRow + 1;
    221             }
    222 
    223             if (currentRow === totalRow && currentColumn > lastRowColumnLength) {
    224               currentRow = 1;
    225             } else if (currentRow > totalRow) {
    226               currentRow = 1;
    227             } else if (currentRow < 1) {
    228               currentRow = totalRow;
    229             }
    230 
    231             $nextNode = findNextNode(currentRow, currentColumn);
    232 
    233             if ($nextNode) {
    234               removeActiveClass($selectedNode);
    235               addActiveClass($nextNode);
    236             }
    237           }
    238 
    239           function enterKeyHandler() {
    240             if (!$selectedNode) {
    241               return;
    242             }
    243 
    244             deferred.resolve(decodeURIComponent($selectedNode.find('button').attr('data-value')));
    245             $specialCharDialog.modal('hide');
    246           }
    247 
    248           function keyDownEventHandler(event) {
    249             event.preventDefault();
    250             var keyCode = event.keyCode;
    251             if (keyCode === undefined || keyCode === null) {
    252               return;
    253             }
    254             // check arrowKeys match
    255             if (ARROW_KEYS.indexOf(keyCode) > -1) {
    256               if ($selectedNode === null) {
    257                 addActiveClass($specialCharNode.eq(0));
    258                 currentColumn = 1;
    259                 currentRow = 1;
    260                 return;
    261               }
    262               arrowKeyHandler(keyCode);
    263             } else if (keyCode === ENTER_KEY) {
    264               enterKeyHandler();
    265             }
    266             return false;
    267           }
    268 
    269           // remove class
    270           removeActiveClass($specialCharNode);
    271 
    272           // find selected node
    273           if (text) {
    274             for (var i = 0; i < $specialCharNode.length; i++) {
    275               var $checkNode = $($specialCharNode[i]);
    276               if ($checkNode.text() === text) {
    277                 addActiveClass($checkNode);
    278                 currentRow = Math.ceil((i + 1) / COLUMN_LENGTH);
    279                 currentColumn = (i + 1) % COLUMN_LENGTH;
    280               }
    281             }
    282           }
    283 
    284           ui.onDialogShown(self.$dialog, function () {
    285 
    286             $(document).on('keydown', keyDownEventHandler);
    287 
    288             self.$dialog.find('button').tooltip();
    289 
    290             $specialCharNode.on('click', function (event) {
    291               event.preventDefault();
    292               deferred.resolve(decodeURIComponent($(event.currentTarget).find('button').attr('data-value')));
    293               ui.hideDialog(self.$dialog);
    294             });
    295 
    296           });
    297 
    298           ui.onDialogHidden(self.$dialog, function () {
    299             $specialCharNode.off('click');
    300 
    301             self.$dialog.find('button').tooltip('destroy');
    302 
    303             $(document).off('keydown', keyDownEventHandler);
    304 
    305             if (deferred.state() === 'pending') {
    306               deferred.reject();
    307             }
    308           });
    309 
    310           ui.showDialog(self.$dialog);
    311         });
    312       };
    313     }
    314   });
    315 }));