UNPKG

summernote-webpack

Version:
238 lines (197 loc) 6.4 kB
define([ 'summernote/base/core/func', 'summernote/base/core/list', 'summernote/base/core/dom', 'summernote/base/core/range', 'summernote/base/core/key' ], function (func, list, dom, range, key) { var HintPopover = function (context) { var self = this; var ui = $.summernote.ui; var POPOVER_DIST = 5; var hint = context.options.hint || []; var direction = context.options.hintDirection || 'bottom'; var hints = $.isArray(hint) ? hint : [hint]; this.events = { 'summernote.keyup': function (we, e) { if (!e.isDefaultPrevented()) { self.handleKeyup(e); } }, 'summernote.keydown': function (we, e) { self.handleKeydown(e); }, 'summernote.dialog.shown': function () { self.hide(); } }; this.shouldInitialize = function () { return hints.length > 0; }; this.initialize = function () { this.lastWordRange = null; this.$popover = ui.popover({ className: 'note-hint-popover', hideArrow: true, direction: '' }).render().appendTo('body'); this.$popover.hide(); this.$content = this.$popover.find('.popover-content'); this.$content.on('click', '.note-hint-item', function () { self.$content.find('.active').removeClass('active'); $(this).addClass('active'); self.replace(); }); }; this.destroy = function () { this.$popover.remove(); }; this.selectItem = function ($item) { this.$content.find('.active').removeClass('active'); $item.addClass('active'); this.$content[0].scrollTop = $item[0].offsetTop - (this.$content.innerHeight() / 2); }; this.moveDown = function () { var $current = this.$content.find('.note-hint-item.active'); var $next = $current.next(); if ($next.length) { this.selectItem($next); } else { var $nextGroup = $current.parent().next(); if (!$nextGroup.length) { $nextGroup = this.$content.find('.note-hint-group').first(); } this.selectItem($nextGroup.find('.note-hint-item').first()); } }; this.moveUp = function () { var $current = this.$content.find('.note-hint-item.active'); var $prev = $current.prev(); if ($prev.length) { this.selectItem($prev); } else { var $prevGroup = $current.parent().prev(); if (!$prevGroup.length) { $prevGroup = this.$content.find('.note-hint-group').last(); } this.selectItem($prevGroup.find('.note-hint-item').last()); } }; this.replace = function () { var $item = this.$content.find('.note-hint-item.active'); if ($item.length) { var node = this.nodeFromItem($item); this.lastWordRange.insertNode(node); range.createFromNode(node).collapse().select(); this.lastWordRange = null; this.hide(); context.invoke('editor.focus'); } }; this.nodeFromItem = function ($item) { var hint = hints[$item.data('index')]; var item = $item.data('item'); var node = hint.content ? hint.content(item) : item; if (typeof node === 'string') { node = dom.createText(node); } return node; }; this.createItemTemplates = function (hintIdx, items) { var hint = hints[hintIdx]; return items.map(function (item, idx) { var $item = $('<div class="note-hint-item"/>'); $item.append(hint.template ? hint.template(item) : item + ''); $item.data({ 'index': hintIdx, 'item': item }); if (hintIdx === 0 && idx === 0) { $item.addClass('active'); } return $item; }); }; this.handleKeydown = function (e) { if (!this.$popover.is(':visible')) { return; } if (e.keyCode === key.code.ENTER) { e.preventDefault(); this.replace(); } else if (e.keyCode === key.code.UP) { e.preventDefault(); this.moveUp(); } else if (e.keyCode === key.code.DOWN) { e.preventDefault(); this.moveDown(); } }; this.searchKeyword = function (index, keyword, callback) { var hint = hints[index]; if (hint && hint.match.test(keyword) && hint.search) { var matches = hint.match.exec(keyword); hint.search(matches[1], callback); } else { callback(); } }; this.createGroup = function (idx, keyword) { var $group = $('<div class="note-hint-group note-hint-group-' + idx + '"/>'); this.searchKeyword(idx, keyword, function (items) { items = items || []; if (items.length) { $group.html(self.createItemTemplates(idx, items)); self.show(); } }); return $group; }; this.handleKeyup = function (e) { if (list.contains([key.code.ENTER, key.code.UP, key.code.DOWN], e.keyCode)) { if (e.keyCode === key.code.ENTER) { if (this.$popover.is(':visible')) { return; } } } else { var wordRange = context.invoke('editor.createRange').getWordRange(); var keyword = wordRange.toString(); if (hints.length && keyword) { this.$content.empty(); var bnd = func.rect2bnd(list.last(wordRange.getClientRects())); if (bnd) { this.$popover.hide(); this.lastWordRange = wordRange; hints.forEach(function (hint, idx) { if (hint.match.test(keyword)) { self.createGroup(idx, keyword).appendTo(self.$content); } }); // set position for popover after group is created if (direction === 'top') { this.$popover.css({ left: bnd.left, top: bnd.top - this.$popover.outerHeight() - POPOVER_DIST }); } else { this.$popover.css({ left: bnd.left, top: bnd.top + bnd.height + POPOVER_DIST }); } } } else { this.hide(); } } }; this.show = function () { this.$popover.show(); }; this.hide = function () { this.$popover.hide(); }; }; return HintPopover; });