summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/lib/summernote/src/js/Renderer.js
diff options
context:
space:
mode:
authorNicolas Lempereur <nle@odoo.com>2015-08-28 17:22:17 +0200
committerNicolas Lempereur <nle@odoo.com>2015-09-29 14:47:24 +0200
commitd33086c03fc1a0882be38ae62989b7f72df20d3b (patch)
tree20b5776f6902916f4c67d9d356e9db2a107eb952 /addons/web_editor/static/lib/summernote/src/js/Renderer.js
parente9ac1bff8bcef56ae09bbba3910202075f7eb89a (diff)
[IMP] web_editor: update summernote up to 2015-08-31
update summernote library up to revision: https://github.com/summernote/summernote/commit/a0f26e300 see https://github.com/summernote/summernote/ for history closes #8704
Diffstat (limited to 'addons/web_editor/static/lib/summernote/src/js/Renderer.js')
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/Renderer.js530
1 files changed, 317 insertions, 213 deletions
diff --git a/addons/web_editor/static/lib/summernote/src/js/Renderer.js b/addons/web_editor/static/lib/summernote/src/js/Renderer.js
index 07584edc453..a6e56bedc16 100644
--- a/addons/web_editor/static/lib/summernote/src/js/Renderer.js
+++ b/addons/web_editor/static/lib/summernote/src/js/Renderer.js
@@ -1,7 +1,12 @@
define([
- 'summernote/core/agent', 'summernote/core/dom', 'summernote/core/func'
-], function (agent, dom, func) {
+ 'summernote/core/agent',
+ 'summernote/core/dom',
+ 'summernote/core/func',
+ 'summernote/core/list'
+], function (agent, dom, func, list) {
/**
+ * @class Renderer
+ *
* renderer
*
* rendering toolbar and editable
@@ -10,14 +15,15 @@ define([
/**
* 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]
+ * @private
+ * @param {String} label button name
+ * @param {Object} [options] button options
+ * @param {String} [options.event] data-event
+ * @param {String} [options.className] button's class name
+ * @param {String} [options.value] data-value
+ * @param {String} [options.title] button's title for popup
+ * @param {String} [options.dropdown] dropdown html
+ * @param {String} [options.hide] data-hide
*/
var tplButton = function (label, options) {
var event = options.event;
@@ -27,9 +33,11 @@ define([
var dropdown = options.dropdown;
var hide = options.hide;
- return '<button type="button"' +
- ' class="btn btn-default btn-sm btn-small' +
- (className ? ' ' + className : '') +
+ return (dropdown ? '<div class="btn-group' +
+ (className ? ' ' + className : '') + '">' : '') +
+ '<button type="button"' +
+ ' class="btn btn-default btn-sm' +
+ ((!dropdown && className) ? ' ' + className : '') +
(dropdown ? ' dropdown-toggle' : '') +
'"' +
(dropdown ? ' data-toggle="dropdown"' : '') +
@@ -38,15 +46,16 @@ define([
(value ? ' data-value=\'' + value + '\'' : '') +
(hide ? ' data-hide=\'' + hide + '\'' : '') +
' tabindex="-1">' +
- label +
- (dropdown ? ' <span class="caret"></span>' : '') +
- '</button>' +
- (dropdown || '');
+ label +
+ (dropdown ? ' <span class="caret"></span>' : '') +
+ '</button>' +
+ (dropdown || '') +
+ (dropdown ? '</div>' : '');
};
/**
* bootstrap icon button template
- *
+ * @private
* @param {String} iconClassName
* @param {Object} [options]
* @param {String} [options.event]
@@ -61,26 +70,28 @@ define([
/**
* bootstrap popover template
- *
+ * @private
* @param {String} className
* @param {String} content
*/
var tplPopover = function (className, content) {
- return '<div class="' + className + ' popover bottom in" style="display: none;">' +
+ var $popover = $('<div class="' + className + ' popover bottom in" style="display: none;">' +
'<div class="arrow"></div>' +
'<div class="popover-content">' +
- content +
'</div>' +
- '</div>';
+ '</div>');
+
+ $popover.find('.popover-content').append(content);
+ return $popover;
};
/**
* bootstrap dialog template
*
* @param {String} className
- * @param {String} [title]
+ * @param {String} [title='']
* @param {String} body
- * @param {String} [footer]
+ * @param {String} [footer='']
*/
var tplDialog = function (className, title, body, footer) {
return '<div class="' + className + ' modal" aria-hidden="false">' +
@@ -92,44 +103,60 @@ define([
'<h4 class="modal-title">' + title + '</h4>' +
'</div>' : ''
) +
- '<form class="note-modal-form">' +
- '<div class="modal-body">' + body + '</div>' +
- (footer ?
- '<div class="modal-footer">' + footer + '</div>' : ''
- ) +
- '</form>' +
+ '<div class="modal-body">' + body + '</div>' +
+ (footer ?
+ '<div class="modal-footer">' + footer + '</div>' : ''
+ ) +
'</div>' +
'</div>' +
'</div>';
};
+ /**
+ * bootstrap dropdown template
+ *
+ * @param {String|String[]} contents
+ * @param {String} [className='']
+ * @param {String} [nodeName='']
+ */
+ var tplDropdown = function (contents, className, nodeName) {
+ var classes = 'dropdown-menu' + (className ? ' ' + className : '');
+ nodeName = nodeName || 'ul';
+ if (contents instanceof Array) {
+ contents = contents.join('');
+ }
+
+ return '<' + nodeName + ' class="' + classes + '">' + contents + '</' + nodeName + '>';
+ };
+
var tplButtonInfo = {
- picture: function (lang) {
- return tplIconButton('fa fa-picture-o', {
+ picture: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.image.image, {
event: 'showImageDialog',
title: lang.image.image,
hide: true
});
},
- link: function (lang) {
- return tplIconButton('fa fa-link', {
+ link: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.link.link, {
event: 'showLinkDialog',
title: lang.link.link,
hide: true
});
},
- table: function (lang) {
- var dropdown = '<ul class="note-table dropdown-menu">' +
- '<div class="note-dimension-picker">' +
- '<div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"></div>' +
- '<div class="note-dimension-picker-highlighted"></div>' +
- '<div class="note-dimension-picker-unhighlighted"></div>' +
- '</div>' +
- '<div class="note-dimension-display"> 1 x 1 </div>' +
- '</ul>';
- return tplIconButton('fa fa-table', {
+ table: function (lang, options) {
+ var dropdown = [
+ '<div class="note-dimension-picker">',
+ '<div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"></div>',
+ '<div class="note-dimension-picker-highlighted"></div>',
+ '<div class="note-dimension-picker-unhighlighted"></div>',
+ '</div>',
+ '<div class="note-dimension-display"> 1 x 1 </div>'
+ ];
+
+ return tplIconButton(options.iconPrefix + options.icons.table.table, {
title: lang.table.table,
- dropdown: dropdown
+ dropdown: tplDropdown(dropdown, 'note-table')
});
},
style: function (lang, options) {
@@ -143,28 +170,54 @@ define([
'</a></li>';
}, '');
- return tplIconButton('fa fa-magic', {
+ return tplIconButton(options.iconPrefix + options.icons.style.style, {
title: lang.style.style,
- dropdown: '<ul class="dropdown-menu">' + items + '</ul>'
+ dropdown: tplDropdown(items)
});
},
fontname: function (lang, options) {
+ var realFontList = [];
var items = options.fontNames.reduce(function (memo, v) {
- if (!agent.isFontInstalled(v)) { return memo; }
- return memo + '<li><a data-event="fontName" href="#" data-value="' + v + '">' +
- '<i class="fa fa-check"></i> ' + v +
+ if (!agent.isFontInstalled(v) && !list.contains(options.fontNamesIgnoreCheck, v)) {
+ return memo;
+ }
+ realFontList.push(v);
+ return memo + '<li><a data-event="fontName" href="#" data-value="' + v + '" style="font-family:\'' + v + '\'">' +
+ '<i class="' + options.iconPrefix + options.icons.misc.check + '"></i> ' + v +
'</a></li>';
}, '');
+
+ var hasDefaultFont = agent.isFontInstalled(options.defaultFontName);
+ var defaultFontName = (hasDefaultFont) ? options.defaultFontName : realFontList[0];
+
var label = '<span class="note-current-fontname">' +
- options.defaultFontName +
+ defaultFontName +
'</span>';
return tplButton(label, {
title: lang.font.name,
- dropdown: '<ul class="dropdown-menu">' + items + '</ul>'
+ className: 'note-fontname',
+ dropdown: tplDropdown(items, 'note-check')
+ });
+ },
+ fontsize: function (lang, options) {
+ var items = options.fontSizes.reduce(function (memo, v) {
+ return memo + '<li><a data-event="fontSize" href="#" data-value="' + v + '">' +
+ '<i class="' + options.iconPrefix + options.icons.misc.check + '"></i> ' + v +
+ '</a></li>';
+ }, '');
+
+ var label = '<span class="note-current-fontsize">11</span>';
+ return tplButton(label, {
+ title: lang.font.size,
+ className: 'note-fontsize',
+ dropdown: tplDropdown(items, 'note-check')
});
},
- color: function (lang) {
- var colorButtonLabel = '<i class="fa fa-font" style="color:black;background-color:yellow;"></i>';
+ color: function (lang, options) {
+ var colorButtonLabel = '<i class="' +
+ options.iconPrefix + options.icons.color.recent +
+ '" style="color:black;background-color:yellow;"></i>';
+
var colorButton = tplButton(colorButtonLabel, {
className: 'note-recent-color',
title: lang.color.recent,
@@ -172,156 +225,168 @@ define([
value: '{"backColor":"yellow"}'
});
- var dropdown = '<ul class="dropdown-menu">' +
- '<li>' +
- '<div class="btn-group">' +
- '<div class="note-palette-title">' + lang.color.background + '</div>' +
- '<div class="note-color-reset" data-event="backColor"' +
- ' data-value="inherit" title="' + lang.color.transparent + '">' +
- lang.color.setTransparent +
- '</div>' +
- '<div class="note-color-palette" data-target-event="backColor"></div>' +
- '</div>' +
- '<div class="btn-group">' +
- '<div class="note-palette-title">' + lang.color.foreground + '</div>' +
- '<div class="note-color-reset" data-event="foreColor" data-value="inherit" title="' + lang.color.reset + '">' +
- lang.color.resetToDefault +
- '</div>' +
- '<div class="note-color-palette" data-target-event="foreColor"></div>' +
- '</div>' +
- '</li>' +
- '</ul>';
+ var items = [
+ '<li><div class="btn-group">',
+ '<div class="note-palette-title">' + lang.color.background + '</div>',
+ '<div class="note-color-reset" data-event="backColor"',
+ ' data-value="inherit" title="' + lang.color.transparent + '">' + lang.color.setTransparent + '</div>',
+ '<div class="note-color-palette" data-target-event="backColor"></div>',
+ '</div><div class="btn-group">',
+ '<div class="note-palette-title">' + lang.color.foreground + '</div>',
+ '<div class="note-color-reset" data-event="foreColor" data-value="inherit" title="' + lang.color.reset + '">',
+ lang.color.resetToDefault,
+ '</div>',
+ '<div class="note-color-palette" data-target-event="foreColor"></div>',
+ '</div></li>'
+ ];
var moreButton = tplButton('', {
title: lang.color.more,
- dropdown: dropdown
+ dropdown: tplDropdown(items)
});
return colorButton + moreButton;
},
- bold: function (lang) {
- return tplIconButton('fa fa-bold', {
+ bold: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.bold, {
event: 'bold',
title: lang.font.bold
});
},
- italic: function (lang) {
- return tplIconButton('fa fa-italic', {
+ italic: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.italic, {
event: 'italic',
title: lang.font.italic
});
},
- underline: function (lang) {
- return tplIconButton('fa fa-underline', {
+ underline: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.underline, {
event: 'underline',
title: lang.font.underline
});
},
- clear: function (lang) {
- return tplIconButton('fa fa-eraser', {
+ strikethrough: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.strikethrough, {
+ event: 'strikethrough',
+ title: lang.font.strikethrough
+ });
+ },
+ superscript: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.superscript, {
+ event: 'superscript',
+ title: lang.font.superscript
+ });
+ },
+ subscript: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.subscript, {
+ event: 'subscript',
+ title: lang.font.subscript
+ });
+ },
+ clear: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.font.clear, {
event: 'removeFormat',
title: lang.font.clear
});
},
- ul: function (lang) {
- return tplIconButton('fa fa-list-ul', {
+ ul: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.lists.unordered, {
event: 'insertUnorderedList',
title: lang.lists.unordered
});
},
- ol: function (lang) {
- return tplIconButton('fa fa-list-ol', {
+ ol: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.lists.ordered, {
event: 'insertOrderedList',
title: lang.lists.ordered
});
},
- paragraph: function (lang) {
- var leftButton = tplIconButton('fa fa-align-left', {
+ paragraph: function (lang, options) {
+ var leftButton = tplIconButton(options.iconPrefix + options.icons.paragraph.left, {
title: lang.paragraph.left,
event: 'justifyLeft'
});
- var centerButton = tplIconButton('fa fa-align-center', {
+ var centerButton = tplIconButton(options.iconPrefix + options.icons.paragraph.center, {
title: lang.paragraph.center,
event: 'justifyCenter'
});
- var rightButton = tplIconButton('fa fa-align-right', {
+ var rightButton = tplIconButton(options.iconPrefix + options.icons.paragraph.right, {
title: lang.paragraph.right,
event: 'justifyRight'
});
- var justifyButton = tplIconButton('fa fa-align-justify', {
+ var justifyButton = tplIconButton(options.iconPrefix + options.icons.paragraph.justify, {
title: lang.paragraph.justify,
event: 'justifyFull'
});
- var outdentButton = tplIconButton('fa fa-outdent', {
+ var outdentButton = tplIconButton(options.iconPrefix + options.icons.paragraph.outdent, {
title: lang.paragraph.outdent,
event: 'outdent'
});
- var indentButton = tplIconButton('fa fa-indent', {
+ var indentButton = tplIconButton(options.iconPrefix + options.icons.paragraph.indent, {
title: lang.paragraph.indent,
event: 'indent'
});
- var dropdown = '<div class="dropdown-menu">' +
- '<div class="note-align btn-group">' +
- leftButton + centerButton + rightButton + justifyButton +
- '</div>' +
- '<div class="note-list btn-group">' +
- indentButton + outdentButton +
- '</div>' +
- '</div>';
+ var dropdown = [
+ '<div class="note-align btn-group">',
+ leftButton + centerButton + rightButton + justifyButton,
+ '</div><div class="note-list btn-group">',
+ indentButton + outdentButton,
+ '</div>'
+ ];
- return tplIconButton('fa fa-align-left', {
+ return tplIconButton(options.iconPrefix + options.icons.paragraph.paragraph, {
title: lang.paragraph.paragraph,
- dropdown: dropdown
+ dropdown: tplDropdown(dropdown, '', 'div')
});
},
height: function (lang, options) {
var items = options.lineHeights.reduce(function (memo, v) {
return memo + '<li><a data-event="lineHeight" href="#" data-value="' + parseFloat(v) + '">' +
- '<i class="fa fa-check"></i> ' + v +
+ '<i class="' + options.iconPrefix + options.icons.misc.check + '"></i> ' + v +
'</a></li>';
}, '');
- return tplIconButton('fa fa-text-height', {
+ return tplIconButton(options.iconPrefix + options.icons.font.height, {
title: lang.font.height,
- dropdown: '<ul class="dropdown-menu">' + items + '</ul>'
+ dropdown: tplDropdown(items, 'note-check')
});
},
- help: function (lang) {
- return tplIconButton('fa fa-question', {
+ help: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.options.help, {
event: 'showHelpDialog',
title: lang.options.help,
hide: true
});
},
- fullscreen: function (lang) {
- return tplIconButton('fa fa-arrows-alt', {
+ fullscreen: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.options.fullscreen, {
event: 'fullscreen',
title: lang.options.fullscreen
});
},
- codeview: function (lang) {
- return tplIconButton('fa fa-code', {
+ codeview: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.options.codeview, {
event: 'codeview',
title: lang.options.codeview
});
},
- undo: function (lang) {
- return tplIconButton('fa fa-undo', {
+ undo: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.history.undo, {
event: 'undo',
title: lang.history.undo
});
},
- redo: function (lang) {
- return tplIconButton('fa fa-repeat', {
+ redo: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.history.redo, {
event: 'redo',
title: lang.history.redo
});
},
- hr: function (lang) {
- return tplIconButton('fa fa-minus', {
+ hr: function (lang, options) {
+ return tplIconButton(options.iconPrefix + options.icons.hr.insert, {
event: 'insertHorizontalRule',
title: lang.hr.insert
});
@@ -330,12 +395,12 @@ define([
var tplPopovers = function (lang, options) {
var tplLinkPopover = function () {
- var linkButton = tplIconButton('fa fa-edit', {
+ var linkButton = tplIconButton(options.iconPrefix + options.icons.link.edit, {
title: lang.link.edit,
event: 'showLinkDialog',
hide: true
});
- var unlinkButton = tplIconButton('fa fa-unlink', {
+ var unlinkButton = tplIconButton(options.iconPrefix + options.icons.link.unlink, {
title: lang.link.unlink,
event: 'unlink'
});
@@ -363,50 +428,50 @@ define([
value: '0.25'
});
- var leftButton = tplIconButton('fa fa-align-left', {
+ var leftButton = tplIconButton(options.iconPrefix + options.icons.image.floatLeft, {
title: lang.image.floatLeft,
event: 'floatMe',
value: 'left'
});
- var rightButton = tplIconButton('fa fa-align-right', {
+ var rightButton = tplIconButton(options.iconPrefix + options.icons.image.floatRight, {
title: lang.image.floatRight,
event: 'floatMe',
value: 'right'
});
- var justifyButton = tplIconButton('fa fa-align-justify', {
+ var justifyButton = tplIconButton(options.iconPrefix + options.icons.image.floatNone, {
title: lang.image.floatNone,
event: 'floatMe',
value: 'none'
});
- var roundedButton = tplIconButton('fa fa-square', {
+ var roundedButton = tplIconButton(options.iconPrefix + options.icons.image.shapeRounded, {
title: lang.image.shapeRounded,
event: 'imageShape',
value: 'img-rounded'
});
- var circleButton = tplIconButton('fa fa-circle', {
+ var circleButton = tplIconButton(options.iconPrefix + options.icons.image.shapeCircle, {
title: lang.image.shapeCircle,
event: 'imageShape',
value: 'img-circle'
});
- var thumbnailButton = tplIconButton('fa fa-picture-o', {
+ var thumbnailButton = tplIconButton(options.iconPrefix + options.icons.image.shapeThumbnail, {
title: lang.image.shapeThumbnail,
event: 'imageShape',
value: 'img-thumbnail'
});
- var noneButton = tplIconButton('fa fa-times', {
+ var noneButton = tplIconButton(options.iconPrefix + options.icons.image.shapeNone, {
title: lang.image.shapeNone,
event: 'imageShape',
value: ''
});
- var removeButton = tplIconButton('fa fa-trash-o', {
+ var removeButton = tplIconButton(options.iconPrefix + options.icons.image.remove, {
title: lang.image.remove,
event: 'removeMedia',
value: 'none'
});
- var content = '<div class="btn-group">' + fullButton + halfButton + quarterButton + '</div>' +
+ var content = (options.disableResizeImage ? '' : '<div class="btn-group">' + fullButton + halfButton + quarterButton + '</div>') +
'<div class="btn-group">' + leftButton + rightButton + justifyButton + '</div>' +
'<div class="btn-group">' + roundedButton + circleButton + thumbnailButton + noneButton + '</div>' +
'<div class="btn-group">' + removeButton + '</div>';
@@ -414,38 +479,50 @@ define([
};
var tplAirPopover = function () {
- var content = '';
+ var $content = $('<div />');
for (var idx = 0, len = options.airPopover.length; idx < len; idx ++) {
var group = options.airPopover[idx];
- content += '<div class="note-' + group[0] + ' btn-group">';
+
+ var $group = $('<div class="note-' + group[0] + ' btn-group">');
for (var i = 0, lenGroup = group[1].length; i < lenGroup; i++) {
- content += tplButtonInfo[group[1][i]](lang, options);
+ var $button = $(tplButtonInfo[group[1][i]](lang, options));
+
+ $button.attr('data-name', group[1][i]);
+
+ $group.append($button);
}
- content += '</div>';
+ $content.append($group);
}
- return tplPopover('note-air-popover', content);
+ return tplPopover('note-air-popover', $content.children());
};
- return '<div class="note-popover">' +
- tplLinkPopover() +
- tplImagePopover() +
- (options.airMode ? tplAirPopover() : '') +
- '</div>';
+ var $notePopover = $('<div class="note-popover" />');
+
+ $notePopover.append(tplLinkPopover());
+ $notePopover.append(tplImagePopover());
+
+ if (options.airMode) {
+ $notePopover.append(tplAirPopover());
+ }
+
+ return $notePopover;
};
- this.tplButtonInfo = tplButtonInfo; // odoo change for overwrite
- this.tplPopovers = tplPopovers; // odoo change for overwrite
+ this.tplButtonInfo = tplButtonInfo; // ODOO: allow access for override
+ this.tplPopovers = tplPopovers; // ODOO: allow access for override
- var tplHandles = function () {
+ var tplHandles = function (options) {
return '<div class="note-handle">' +
'<div class="note-control-selection">' +
'<div class="note-control-selection-bg"></div>' +
'<div class="note-control-holder note-control-nw"></div>' +
'<div class="note-control-holder note-control-ne"></div>' +
'<div class="note-control-holder note-control-sw"></div>' +
- '<div class="note-control-sizing note-control-se"></div>' +
- '<div class="note-control-selection-info"></div>' +
+ '<div class="' +
+ (options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing') +
+ ' note-control-se"></div>' +
+ (options.disableResizeImage ? '' : '<div class="note-control-selection-info"></div>') +
'</div>' +
'</div>';
};
@@ -477,7 +554,6 @@ define([
{ 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 }
];
@@ -489,7 +565,7 @@ define([
{ kbd: '⌘ + Z', text: lang.history.undo },
{ kbd: '⌘ + ⇧ + Z', text: lang.history.redo },
{ kbd: '⌘ + ]', text: lang.paragraph.indent },
- { kbd: '⌘ + [', text: lang.paragraph.oudivent },
+ { kbd: '⌘ + [', text: lang.paragraph.outdent },
{ kbd: '⌘ + ENTER', text: lang.hr.insert }
];
@@ -568,27 +644,27 @@ define([
imageLimitation = '<small>' + lang.image.maximumFileSize + ' : ' + readableSize + '</small>';
}
- var body = '<div class="form-group row-fluid note-group-select-from-files">' +
+ var body = '<div class="form-group row note-group-select-from-files">' +
'<label>' + lang.image.selectFromFiles + '</label>' +
- '<input class="note-image-input" type="file" name="files" accept="image/*" multiple="multiple" />' +
+ '<input class="note-image-input form-control" type="file" name="files" accept="image/*" multiple="multiple" />' +
imageLimitation +
'</div>' +
- '<div class="form-group row-fluid">' +
+ '<div class="form-group row">' +
'<label>' + lang.image.url + '</label>' +
- '<input class="note-image-url form-control span12" type="text" />' +
+ '<input class="note-image-url form-control col-md-12" type="text" />' +
'</div>';
var footer = '<button href="#" class="btn btn-primary note-image-btn disabled" disabled>' + lang.image.insert + '</button>';
return tplDialog('note-image-dialog', lang.image.insert, body, footer);
},
link: function (lang, options) {
- var body = '<div class="form-group row-fluid">' +
+ var body = '<div class="form-group row">' +
'<label>' + lang.link.textToDisplay + '</label>' +
- '<input class="note-link-text form-control span12" type="text" />' +
+ '<input class="note-link-text form-control col-md-12" type="text" />' +
'</div>' +
- '<div class="form-group row-fluid">' +
+ '<div class="form-group row">' +
'<label>' + lang.link.url + '</label>' +
- '<input class="note-link-url form-control span12" type="text" />' +
+ '<input class="note-link-url form-control col-md-12" type="text" value="http://" />' +
'</div>' +
(!options.disableLinkTarget ?
'<div class="checkbox">' +
@@ -606,9 +682,9 @@ define([
'<div class="title">' + lang.shortcut.shortcuts + '</div>' +
(agent.isMac ? tplShortcutTable(lang, options) : replaceMacKeys(tplShortcutTable(lang, options))) +
'<p class="text-center">' +
- '<a href="//hackerwins.github.io/summernote/" target="_blank">Summernote @VERSION</a> · ' +
- '<a href="//github.com/HackerWins/summernote" target="_blank">Project</a> · ' +
- '<a href="//github.com/HackerWins/summernote/issues" target="_blank">Issues</a>' +
+ '<a href="//summernote.org/" target="_blank">Summernote @VERSION</a> · ' +
+ '<a href="//github.com/summernote/summernote" target="_blank">Project</a> · ' +
+ '<a href="//github.com/summernote/summernote/issues" target="_blank">Issues</a>' +
'</p>';
return tplDialog('note-help-dialog', '', body, '');
}
@@ -696,7 +772,7 @@ define([
});
};
- this.createPalette = createPalette; // odoo change for overwrite
+ this.createPalette = createPalette; // ODOO: allow access for override
/**
* create summernote layout (air mode)
@@ -709,24 +785,25 @@ define([
var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];
var id = func.uniqueId();
- $holder.addClass('note-air-editor note-editable');
+ $holder.addClass('note-air-editor note-editable panel-body');
$holder.attr({
- 'data-note-id': id,
+ 'data-note-id': id, // ODOO: we use [data-note-id="{id}"] instead of [id="{id}"]
+ // 'id': 'note-editor-' + id,
'contentEditable': true
});
var body = document.body;
// create Popover
- var $popover = $(this.tplPopovers(langInfo, options)); // odoo change for overwrite
+ var $popover = $(this.tplPopovers(langInfo, options)); // ODOO: user (maybe) overrided method
$popover.addClass('note-air-layout');
$popover.attr('id', 'note-popover-' + id);
$popover.appendTo(body);
createTooltip($popover, keyMap);
- this.createPalette($popover, options); // odoo change for overwrite
+ this.createPalette($popover, options); // ODOO: use (maybe) overrided method
// create Handle
- var $handle = $(tplHandles());
+ var $handle = $(tplHandles(options));
$handle.addClass('note-air-layout');
$handle.attr('id', 'note-handle-' + id);
$handle.appendTo(body);
@@ -751,7 +828,7 @@ define([
var langInfo = options.langInfo;
//01. create Editor
- var $editor = $('<div class="note-editor"></div>');
+ var $editor = $('<div class="note-editor panel panel-default" />');
if (options.width) {
$editor.width(options.width);
}
@@ -761,70 +838,81 @@ define([
$('<div class="note-statusbar">' + (options.disableResizeEditor ? '' : tplStatusbar()) + '</div>').prependTo($editor);
}
- //03. create Editable
+ //03 editing area
+ var $editingArea = $('<div class="note-editing-area" />');
+ //03. create editable
var isContentEditable = !$holder.is(':disabled');
- var $editable = $('<div class="note-editable" contentEditable="' + isContentEditable + '"></div>')
- .prependTo($editor);
+ var $editable = $('<div class="note-editable panel-body" contentEditable="' + isContentEditable + '"></div>').prependTo($editingArea);
+
if (options.height) {
$editable.height(options.height);
}
if (options.direction) {
$editable.attr('dir', options.direction);
}
- if (options.placeholder) {
- $editable.attr('data-placeholder', options.placeholder);
+ var placeholder = $holder.attr('placeholder') || options.placeholder;
+ if (placeholder) {
+ $editable.attr('data-placeholder', placeholder);
}
- $editable.html(dom.html($holder));
+ $editable.html(dom.html($holder) || dom.emptyPara);
//031. create codable
- $('<textarea class="note-codable"></textarea>').prependTo($editor);
+ $('<textarea class="note-codable"></textarea>').prependTo($editingArea);
+
+ //04. create Popover
+ var $popover = $(this.tplPopovers(langInfo, options)).prependTo($editingArea); // ODOO: use (maybe) overrided method
+ this.createPalette($popover, options); // ODOO: use (maybe) overrided method
+ createTooltip($popover, keyMap);
+
+ //05. handle(control selection, ...)
+ $(tplHandles(options)).prependTo($editingArea);
- //04. create Toolbar
- var toolbarHTML = '';
+ $editingArea.prependTo($editor);
+
+ //06. create Toolbar
+ var $toolbar = $('<div class="note-toolbar panel-heading" />');
for (var idx = 0, len = options.toolbar.length; idx < len; idx ++) {
var groupName = options.toolbar[idx][0];
var groupButtons = options.toolbar[idx][1];
- toolbarHTML += '<div class="note-' + groupName + ' btn-group">';
+ var $group = $('<div class="note-' + groupName + ' btn-group" />');
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);
+
+ var $button = $(buttonInfo(langInfo, options));
+ $button.attr('data-name', groupButtons[i]); // set button's alias, becuase to get button element from $toolbar
+ $group.append($button);
}
- toolbarHTML += '</div>';
+ $toolbar.append($group);
}
- toolbarHTML = '<div class="note-toolbar btn-toolbar">' + toolbarHTML + '</div>';
-
- var $toolbar = $(toolbarHTML).prependTo($editor);
var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];
- this.createPalette($toolbar, options); // odoo change for overwrite
+ this.createPalette($toolbar, options); // ODOO: use (maybe) overrided method
createTooltip($toolbar, keyMap, 'bottom');
+ $toolbar.prependTo($editor);
- //05. create Popover
- var $popover = $(this.tplPopovers(langInfo, options)).prependTo($editor); // odoo change for overwrite
- this.createPalette($popover, options); // odoo change for overwrite
- createTooltip($popover, keyMap);
-
- //06. handle(control selection, ...)
- $(tplHandles()).prependTo($editor);
+ //07. create Dropzone
+ $('<div class="note-dropzone"><div class="note-dropzone-message"></div></div>').prependTo($editor);
- //07. create Dialog
- var $dialog = $(tplDialogs(langInfo, options)).prependTo($editor);
+ //08. create Dialog
+ var $dialogContainer = options.dialogsInBody ? $(document.body) : $editor;
+ var $dialog = $(tplDialogs(langInfo, options)).prependTo($dialogContainer);
$dialog.find('button.close, a.modal-close').click(function () {
$(this).closest('.modal').modal('hide');
});
- //08. create Dropzone
- $('<div class="note-dropzone"><div class="note-dropzone-message"></div></div>').prependTo($editor);
-
//09. Editor/Holder switch
$editor.insertAfter($holder);
$holder.hide();
};
+ this.hasNoteEditor = function ($holder) {
+ return this.noteEditorFromHolder($holder).length > 0;
+ };
+
this.noteEditorFromHolder = function ($holder) {
if ($holder.hasClass('note-air-editor')) {
return $holder;
@@ -842,10 +930,6 @@ define([
* @param {Object} options
*/
this.createLayout = function ($holder, options) {
- if (this.noteEditorFromHolder($holder).length) {
- return;
- }
-
if (options.airMode) {
this.createLayoutByAirMode($holder, options);
} else {
@@ -857,20 +941,18 @@ define([
* returns layoutInfo from holder
*
* @param {jQuery} $holder - placeholder
- * @returns {Object}
+ * @return {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();
- }
+ if (!$editor.length) {
+ return;
}
- return layoutInfo;
+
+ // connect $holder to $editor
+ $editor.data('holder', $holder);
+
+ return dom.buildLayoutInfo($editor);
};
/**
@@ -884,31 +966,53 @@ define([
this.removeLayout = function ($holder, layoutInfo, options) {
if (options.airMode) {
$holder.removeClass('note-air-editor note-editable')
- .removeAttr('contentEditable');
+ .removeAttr('contentEditable'); // ODOO: removed id 'id contentEditable'
- layoutInfo.popover.remove();
- layoutInfo.handle.remove();
- layoutInfo.dialog.remove();
+ layoutInfo.popover().remove();
+ layoutInfo.handle().remove();
+ layoutInfo.dialog().remove();
} else {
- $holder.html(layoutInfo.editable.html());
+ $holder.html(layoutInfo.editable().html());
- layoutInfo.editor.remove();
+ if (options.dialogsInBody) {
+ layoutInfo.dialog().remove();
+ }
+ layoutInfo.editor().remove();
$holder.show();
}
};
+ /**
+ *
+ * @return {Object}
+ * @return {function(label, options=):string} return.button {@link #tplButton function to make text button}
+ * @return {function(iconClass, options=):string} return.iconButton {@link #tplIconButton function to make icon button}
+ * @return {function(className, title=, body=, footer=):string} return.dialog {@link #tplDialog function to make dialog}
+ */
this.getTemplate = function () {
return {
button: tplButton,
iconButton: tplIconButton,
- dialog: tplDialog
+ dialog: tplDialog,
+ dropdown: tplDropdown // ODOO: suggest upstream
};
};
+ /**
+ * add button information
+ *
+ * @param {String} name button name
+ * @param {Function} buttonInfo function to make button, reference to {@link #tplButton},{@link #tplIconButton}
+ */
this.addButtonInfo = function (name, buttonInfo) {
tplButtonInfo[name] = buttonInfo;
};
+ /**
+ *
+ * @param {String} name
+ * @param {Function} dialogInfo function to make dialog, reference to {@link #tplDialog}
+ */
this.addDialogInfo = function (name, dialogInfo) {
tplDialogInfo[name] = dialogInfo;
};