All Downloads are FREE. Search and download functionalities are using the official Maven repository.

web.bower_components.summernote.src.js.Renderer.js Maven / Gradle / Ivy

The newest version!
define([
  'summernote/core/agent', 'summernote/core/dom', 'summernote/core/func'
], function (agent, dom, func) {
  /**
   * renderer
   *
   * rendering toolbar and editable
   */
  var Renderer = function () {

    /**
     * bootstrap button template
     *
     * @param {String} label
     * @param {Object} [options]
     * @param {String} [options.event]
     * @param {String} [options.value]
     * @param {String} [options.title]
     * @param {String} [options.dropdown]
     * @param {String} [options.hide]
     */
    var tplButton = function (label, options) {
      var event = options.event;
      var value = options.value;
      var title = options.title;
      var className = options.className;
      var dropdown = options.dropdown;
      var hide = options.hide;

      return '' +
             (dropdown || '');
    };

    /**
     * bootstrap icon button template
     *
     * @param {String} iconClassName
     * @param {Object} [options]
     * @param {String} [options.event]
     * @param {String} [options.value]
     * @param {String} [options.title]
     * @param {String} [options.dropdown]
     */
    var tplIconButton = function (iconClassName, options) {
      var label = '';
      return tplButton(label, options);
    };

    /**
     * bootstrap popover template
     *
     * @param {String} className
     * @param {String} content
     */
    var tplPopover = function (className, content) {
      return '';
    };

    /**
     * bootstrap dialog template
     *
     * @param {String} className
     * @param {String} [title]
     * @param {String} body
     * @param {String} [footer]
     */
    var tplDialog = function (className, title, body, footer) {
      return '';
    };

    var tplButtonInfo = {
      picture: function (lang) {
        return tplIconButton('fa fa-picture-o', {
          event: 'showImageDialog',
          title: lang.image.image,
          hide: true
        });
      },
      link: function (lang) {
        return tplIconButton('fa fa-link', {
          event: 'showLinkDialog',
          title: lang.link.link,
          hide: true
        });
      },
      table: function (lang) {
        var dropdown = '';
        return tplIconButton('fa fa-table', {
          title: lang.table.table,
          dropdown: dropdown
        });
      },
      style: function (lang, options) {
        var items = options.styleTags.reduce(function (memo, v) {
          var label = lang.style[v === 'p' ? 'normal' : v];
          return memo + '
  • ' + ( (v === 'p' || v === 'pre') ? label : '<' + v + '>' + label + '' ) + '
  • '; }, ''); return tplIconButton('fa fa-magic', { title: lang.style.style, dropdown: '' }); }, fontname: function (lang, options) { var items = options.fontNames.reduce(function (memo, v) { if (!agent.isFontInstalled(v)) { return memo; } return memo + '
  • ' + ' ' + v + '
  • '; }, ''); var label = '' + options.defaultFontName + ''; return tplButton(label, { title: lang.font.name, dropdown: '' }); }, color: function (lang) { var colorButtonLabel = ''; var colorButton = tplButton(colorButtonLabel, { className: 'note-recent-color', title: lang.color.recent, event: 'color', value: '{"backColor":"yellow"}' }); var dropdown = ''; var moreButton = tplButton('', { title: lang.color.more, dropdown: dropdown }); return colorButton + moreButton; }, bold: function (lang) { return tplIconButton('fa fa-bold', { event: 'bold', title: lang.font.bold }); }, italic: function (lang) { return tplIconButton('fa fa-italic', { event: 'italic', title: lang.font.italic }); }, underline: function (lang) { return tplIconButton('fa fa-underline', { event: 'underline', title: lang.font.underline }); }, clear: function (lang) { return tplIconButton('fa fa-eraser', { event: 'removeFormat', title: lang.font.clear }); }, ul: function (lang) { return tplIconButton('fa fa-list-ul', { event: 'insertUnorderedList', title: lang.lists.unordered }); }, ol: function (lang) { return tplIconButton('fa fa-list-ol', { event: 'insertOrderedList', title: lang.lists.ordered }); }, paragraph: function (lang) { var leftButton = tplIconButton('fa fa-align-left', { title: lang.paragraph.left, event: 'justifyLeft' }); var centerButton = tplIconButton('fa fa-align-center', { title: lang.paragraph.center, event: 'justifyCenter' }); var rightButton = tplIconButton('fa fa-align-right', { title: lang.paragraph.right, event: 'justifyRight' }); var justifyButton = tplIconButton('fa fa-align-justify', { title: lang.paragraph.justify, event: 'justifyFull' }); var outdentButton = tplIconButton('fa fa-outdent', { title: lang.paragraph.outdent, event: 'outdent' }); var indentButton = tplIconButton('fa fa-indent', { title: lang.paragraph.indent, event: 'indent' }); var dropdown = ''; return tplIconButton('fa fa-align-left', { title: lang.paragraph.paragraph, dropdown: dropdown }); }, height: function (lang, options) { var items = options.lineHeights.reduce(function (memo, v) { return memo + '
  • ' + ' ' + v + '
  • '; }, ''); return tplIconButton('fa fa-text-height', { title: lang.font.height, dropdown: '' }); }, help: function (lang) { return tplIconButton('fa fa-question', { event: 'showHelpDialog', title: lang.options.help, hide: true }); }, fullscreen: function (lang) { return tplIconButton('fa fa-arrows-alt', { event: 'fullscreen', title: lang.options.fullscreen }); }, codeview: function (lang) { return tplIconButton('fa fa-code', { event: 'codeview', title: lang.options.codeview }); }, undo: function (lang) { return tplIconButton('fa fa-undo', { event: 'undo', title: lang.history.undo }); }, redo: function (lang) { return tplIconButton('fa fa-repeat', { event: 'redo', title: lang.history.redo }); }, hr: function (lang) { return tplIconButton('fa fa-minus', { event: 'insertHorizontalRule', title: lang.hr.insert }); } }; var tplPopovers = function (lang, options) { var tplLinkPopover = function () { var linkButton = tplIconButton('fa fa-edit', { title: lang.link.edit, event: 'showLinkDialog', hide: true }); var unlinkButton = tplIconButton('fa fa-unlink', { title: lang.link.unlink, event: 'unlink' }); var content = 'www.google.com  ' + '
    ' + linkButton + unlinkButton + '
    '; return tplPopover('note-link-popover', content); }; var tplImagePopover = function () { var fullButton = tplButton('100%', { title: lang.image.resizeFull, event: 'resize', value: '1' }); var halfButton = tplButton('50%', { title: lang.image.resizeHalf, event: 'resize', value: '0.5' }); var quarterButton = tplButton('25%', { title: lang.image.resizeQuarter, event: 'resize', value: '0.25' }); var leftButton = tplIconButton('fa fa-align-left', { title: lang.image.floatLeft, event: 'floatMe', value: 'left' }); var rightButton = tplIconButton('fa fa-align-right', { title: lang.image.floatRight, event: 'floatMe', value: 'right' }); var justifyButton = tplIconButton('fa fa-align-justify', { title: lang.image.floatNone, event: 'floatMe', value: 'none' }); var roundedButton = tplIconButton('fa fa-square', { title: lang.image.shapeRounded, event: 'imageShape', value: 'img-rounded' }); var circleButton = tplIconButton('fa fa-circle-o', { title: lang.image.shapeCircle, event: 'imageShape', value: 'img-circle' }); var thumbnailButton = tplIconButton('fa fa-picture-o', { title: lang.image.shapeThumbnail, event: 'imageShape', value: 'img-thumbnail' }); var noneButton = tplIconButton('fa fa-times', { title: lang.image.shapeNone, event: 'imageShape', value: '' }); var removeButton = tplIconButton('fa fa-trash-o', { title: lang.image.remove, event: 'removeMedia', value: 'none' }); var content = '
    ' + fullButton + halfButton + quarterButton + '
    ' + '
    ' + leftButton + rightButton + justifyButton + '
    ' + '
    ' + roundedButton + circleButton + thumbnailButton + noneButton + '
    ' + '
    ' + removeButton + '
    '; return tplPopover('note-image-popover', content); }; var tplAirPopover = function () { var content = ''; for (var idx = 0, len = options.airPopover.length; idx < len; idx ++) { var group = options.airPopover[idx]; content += '
    '; for (var i = 0, lenGroup = group[1].length; i < lenGroup; i++) { content += tplButtonInfo[group[1][i]](lang, options); } content += '
    '; } return tplPopover('note-air-popover', content); }; return '
    ' + tplLinkPopover() + tplImagePopover() + (options.airMode ? tplAirPopover() : '') + '
    '; }; var tplHandles = function () { return '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    '; }; /** * shortcut table template * @param {String} title * @param {String} body */ var tplShortcut = function (title, keys) { var keyClass = 'note-shortcut-col col-xs-6 note-shortcut-'; var body = []; for (var i in keys) { body.push( '
    ' + keys[i].kbd + '
    ' + '
    ' + keys[i].text + '
    ' ); } return '
    ' + title + '
    ' + '
    ' + body.join('
    ') + '
    '; }; var tplShortcutText = function (lang) { var keys = [ { kbd: '⌘ + B', text: lang.font.bold }, { kbd: '⌘ + I', text: lang.font.italic }, { kbd: '⌘ + U', text: lang.font.underline }, { kbd: '⌘ + ⇧ + S', text: lang.font.sdivikethrough }, { kbd: '⌘ + \\', text: lang.font.clear } ]; return tplShortcut(lang.shortcut.textFormatting, keys); }; var tplShortcutAction = function (lang) { var keys = [ { kbd: '⌘ + Z', text: lang.history.undo }, { kbd: '⌘ + ⇧ + Z', text: lang.history.redo }, { kbd: '⌘ + ]', text: lang.paragraph.indent }, { kbd: '⌘ + [', text: lang.paragraph.oudivent }, { kbd: '⌘ + ENTER', text: lang.hr.insert } ]; return tplShortcut(lang.shortcut.action, keys); }; var tplShortcutPara = function (lang) { var keys = [ { kbd: '⌘ + ⇧ + L', text: lang.paragraph.left }, { kbd: '⌘ + ⇧ + E', text: lang.paragraph.center }, { kbd: '⌘ + ⇧ + R', text: lang.paragraph.right }, { kbd: '⌘ + ⇧ + J', text: lang.paragraph.justify }, { kbd: '⌘ + ⇧ + NUM7', text: lang.lists.ordered }, { kbd: '⌘ + ⇧ + NUM8', text: lang.lists.unordered } ]; return tplShortcut(lang.shortcut.paragraphFormatting, keys); }; var tplShortcutStyle = function (lang) { var keys = [ { kbd: '⌘ + NUM0', text: lang.style.normal }, { kbd: '⌘ + NUM1', text: lang.style.h1 }, { kbd: '⌘ + NUM2', text: lang.style.h2 }, { kbd: '⌘ + NUM3', text: lang.style.h3 }, { kbd: '⌘ + NUM4', text: lang.style.h4 }, { kbd: '⌘ + NUM5', text: lang.style.h5 }, { kbd: '⌘ + NUM6', text: lang.style.h6 } ]; return tplShortcut(lang.shortcut.documentStyle, keys); }; var tplExtraShortcuts = function (lang, options) { var extraKeys = options.extraKeys; var keys = []; for (var key in extraKeys) { if (extraKeys.hasOwnProperty(key)) { keys.push({ kbd: key, text: extraKeys[key] }); } } return tplShortcut(lang.shortcut.extraKeys, keys); }; var tplShortcutTable = function (lang, options) { var colClass = 'class="note-shortcut note-shortcut-col col-sm-6 col-xs-12"'; var template = [ '
    ' + tplShortcutAction(lang, options) + '
    ' + '
    ' + tplShortcutText(lang, options) + '
    ', '
    ' + tplShortcutStyle(lang, options) + '
    ' + '
    ' + tplShortcutPara(lang, options) + '
    ' ]; if (options.extraKeys) { template.push('
    ' + tplExtraShortcuts(lang, options) + '
    '); } return '
    ' + template.join('
    ') + '
    '; }; var replaceMacKeys = function (sHtml) { return sHtml.replace(/⌘/g, 'Ctrl').replace(/⇧/g, 'Shift'); }; var tplDialogInfo = { image: function (lang, options) { var imageLimitation = ''; if (options.maximumImageFileSize) { var unit = Math.floor(Math.log(options.maximumImageFileSize) / Math.log(1024)); var readableSize = (options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 + ' ' + ' KMGTP'[unit] + 'B'; imageLimitation = '' + lang.image.maximumFileSize + ' : ' + readableSize + ''; } var body = '
    ' + '' + '' + imageLimitation + '
    ' + '
    ' + '' + '' + '
    '; var footer = ''; return tplDialog('note-image-dialog', lang.image.insert, body, footer); }, link: function (lang, options) { var body = '
    ' + '' + '' + '
    ' + '
    ' + '' + '' + '
    ' + (!options.disableLinkTarget ? '
    ' + '' + '
    ' : '' ); var footer = ''; return tplDialog('note-link-dialog', lang.link.insert, body, footer); }, help: function (lang, options) { var body = '' + '
    ' + lang.shortcut.shortcuts + '
    ' + (agent.isMac ? tplShortcutTable(lang, options) : replaceMacKeys(tplShortcutTable(lang, options))) + '

    ' + 'Summernote @VERSION · ' + 'Project · ' + 'Issues' + '

    '; return tplDialog('note-help-dialog', '', body, ''); } }; var tplDialogs = function (lang, options) { var dialogs = ''; $.each(tplDialogInfo, function (idx, tplDialog) { dialogs += tplDialog(lang, options); }); return '
    ' + dialogs + '
    '; }; var tplStatusbar = function () { return '
    ' + '
    ' + '
    ' + '
    ' + '
    '; }; var representShortcut = function (str) { if (agent.isMac) { str = str.replace('CMD', '⌘').replace('SHIFT', '⇧'); } return str.replace('BACKSLASH', '\\') .replace('SLASH', '/') .replace('LEFTBRACKET', '[') .replace('RIGHTBRACKET', ']'); }; /** * createTooltip * * @param {jQuery} $container * @param {Object} keyMap * @param {String} [sPlacement] */ var createTooltip = function ($container, keyMap, sPlacement) { var invertedKeyMap = func.invertObject(keyMap); var $buttons = $container.find('button'); $buttons.each(function (i, elBtn) { var $btn = $(elBtn); var sShortcut = invertedKeyMap[$btn.data('event')]; if (sShortcut) { $btn.attr('title', function (i, v) { return v + ' (' + representShortcut(sShortcut) + ')'; }); } // bootstrap tooltip on btn-group bug // https://github.com/twbs/bootstrap/issues/5687 }).tooltip({ container: 'body', trigger: 'hover', placement: sPlacement || 'top' }).on('click', function () { $(this).tooltip('hide'); }); }; // createPalette var createPalette = function ($container, options) { var colorInfo = options.colors; $container.find('.note-color-palette').each(function () { var $palette = $(this), eventName = $palette.attr('data-target-event'); var paletteContents = []; for (var row = 0, lenRow = colorInfo.length; row < lenRow; row++) { var colors = colorInfo[row]; var buttons = []; for (var col = 0, lenCol = colors.length; col < lenCol; col++) { var color = colors[col]; buttons.push([''].join('')); } paletteContents.push('
    ' + buttons.join('') + '
    '); } $palette.html(paletteContents.join('')); }); }; /** * create summernote layout (air mode) * * @param {jQuery} $holder * @param {Object} options */ this.createLayoutByAirMode = function ($holder, options) { var langInfo = options.langInfo; var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc']; var id = func.uniqueId(); $holder.addClass('note-air-editor note-editable'); $holder.attr({ 'id': 'note-editor-' + id, 'contentEditable': true }); var body = document.body; // create Popover var $popover = $(tplPopovers(langInfo, options)); $popover.addClass('note-air-layout'); $popover.attr('id', 'note-popover-' + id); $popover.appendTo(body); createTooltip($popover, keyMap); createPalette($popover, options); // create Handle var $handle = $(tplHandles()); $handle.addClass('note-air-layout'); $handle.attr('id', 'note-handle-' + id); $handle.appendTo(body); // create Dialog var $dialog = $(tplDialogs(langInfo, options)); $dialog.addClass('note-air-layout'); $dialog.attr('id', 'note-dialog-' + id); $dialog.find('button.close, a.modal-close').click(function () { $(this).closest('.modal').modal('hide'); }); $dialog.appendTo(body); }; /** * create summernote layout (normal mode) * * @param {jQuery} $holder * @param {Object} options */ this.createLayoutByFrame = function ($holder, options) { var langInfo = options.langInfo; //01. create Editor var $editor = $('
    '); if (options.width) { $editor.width(options.width); } //02. statusbar (resizebar) if (options.height > 0) { $('
    ' + (options.disableResizeEditor ? '' : tplStatusbar()) + '
    ').prependTo($editor); } //03. create Editable var isContentEditable = !$holder.is(':disabled'); var $editable = $('
    ') .prependTo($editor); if (options.height) { $editable.height(options.height); } if (options.direction) { $editable.attr('dir', options.direction); } if (options.placeholder) { $editable.attr('data-placeholder', options.placeholder); } $editable.html(dom.html($holder)); //031. create codable $('').prependTo($editor); //04. create Toolbar var toolbarHTML = ''; for (var idx = 0, len = options.toolbar.length; idx < len; idx ++) { var groupName = options.toolbar[idx][0]; var groupButtons = options.toolbar[idx][1]; toolbarHTML += '
    '; for (var i = 0, btnLength = groupButtons.length; i < btnLength; i++) { var buttonInfo = tplButtonInfo[groupButtons[i]]; // continue creating toolbar even if a button doesn't exist if (!$.isFunction(buttonInfo)) { continue; } toolbarHTML += buttonInfo(langInfo, options); } toolbarHTML += '
    '; } toolbarHTML = '
    ' + toolbarHTML + '
    '; var $toolbar = $(toolbarHTML).prependTo($editor); var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc']; createPalette($toolbar, options); createTooltip($toolbar, keyMap, 'bottom'); //05. create Popover var $popover = $(tplPopovers(langInfo, options)).prependTo($editor); createPalette($popover, options); createTooltip($popover, keyMap); //06. handle(control selection, ...) $(tplHandles()).prependTo($editor); //07. create Dialog var $dialog = $(tplDialogs(langInfo, options)).prependTo($editor); $dialog.find('button.close, a.modal-close').click(function () { $(this).closest('.modal').modal('hide'); }); //08. create Dropzone $('
    ').prependTo($editor); //09. Editor/Holder switch $editor.insertAfter($holder); $holder.hide(); }; this.noteEditorFromHolder = function ($holder) { if ($holder.hasClass('note-air-editor')) { return $holder; } else if ($holder.next().hasClass('note-editor')) { return $holder.next(); } else { return $(); } }; /** * create summernote layout * * @param {jQuery} $holder * @param {Object} options */ this.createLayout = function ($holder, options) { if (this.noteEditorFromHolder($holder).length) { return; } if (options.airMode) { this.createLayoutByAirMode($holder, options); } else { this.createLayoutByFrame($holder, options); } }; /** * returns layoutInfo from holder * * @param {jQuery} $holder - placeholder * @returns {Object} */ this.layoutInfoFromHolder = function ($holder) { var $editor = this.noteEditorFromHolder($holder); if (!$editor.length) { return; } var layoutInfo = dom.buildLayoutInfo($editor); // cache all properties. for (var key in layoutInfo) { if (layoutInfo.hasOwnProperty(key)) { layoutInfo[key] = layoutInfo[key].call(); } } return layoutInfo; }; /** * removeLayout * * @param {jQuery} $holder - placeholder * @param {Object} layoutInfo * @param {Object} options * */ this.removeLayout = function ($holder, layoutInfo, options) { if (options.airMode) { $holder.removeClass('note-air-editor note-editable') .removeAttr('id contentEditable'); layoutInfo.popover.remove(); layoutInfo.handle.remove(); layoutInfo.dialog.remove(); } else { $holder.html(layoutInfo.editable.html()); layoutInfo.editor.remove(); $holder.show(); } }; this.getTemplate = function () { return { button: tplButton, iconButton: tplIconButton, dialog: tplDialog }; }; this.addButtonInfo = function (name, buttonInfo) { tplButtonInfo[name] = buttonInfo; }; this.addDialogInfo = function (name, dialogInfo) { tplDialogInfo[name] = dialogInfo; }; }; return Renderer; });




    © 2015 - 2025 Weber Informatics LLC | Privacy Policy