summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/lib/summernote/src/js/module
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@odoo.com>2015-03-04 14:32:33 +0100
committerChristophe Matthieu <chm@odoo.com>2015-07-10 17:00:13 +0200
commitcebc73ebf9aa2bd6d8026473344af16726effec1 (patch)
tree55a8de23a6cf7f551aeabf58195e7ba8e1c76686 /addons/web_editor/static/lib/summernote/src/js/module
parentc1f39d0ca74486de714ea85f56b6924a9a520757 (diff)
[IMP] web_editor: move summernote & nearest lib from website
Diffstat (limited to 'addons/web_editor/static/lib/summernote/src/js/module')
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Button.js157
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Dialog.js158
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Handle.js44
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Popover.js106
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Toolbar.js58
5 files changed, 523 insertions, 0 deletions
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Button.js b/addons/web_editor/static/lib/summernote/src/js/module/Button.js
new file mode 100644
index 00000000000..512822aeba8
--- /dev/null
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Button.js
@@ -0,0 +1,157 @@
+define([
+ 'summernote/core/list'
+], function (list) {
+ /**
+ * Button
+ */
+ var Button = function () {
+ /**
+ * update button status
+ *
+ * @param {jQuery} $container
+ * @param {Object} styleInfo
+ */
+ this.update = function ($container, styleInfo) {
+ /**
+ * handle dropdown's check mark (for fontname, fontsize, lineHeight).
+ * @param {jQuery} $btn
+ * @param {Number} value
+ */
+ var checkDropdownMenu = function ($btn, value) {
+ $btn.find('.dropdown-menu li a').each(function () {
+ // always compare string to avoid creating another func.
+ var isChecked = ($(this).data('value') + '') === (value + '');
+ this.className = isChecked ? 'checked' : '';
+ });
+ };
+
+ /**
+ * update button state(active or not).
+ *
+ * @param {String} selector
+ * @param {Function} pred
+ */
+ var btnState = function (selector, pred) {
+ var $btn = $container.find(selector);
+ $btn.toggleClass('active', pred());
+ };
+
+ if (styleInfo.image) {
+ var $img = $(styleInfo.image);
+
+ btnState('button[data-event="imageShape"][data-value="img-rounded"]', function () {
+ return $img.hasClass("img-rounded");
+ });
+ btnState('button[data-event="imageShape"][data-value="img-circle"]', function () {
+ return $img.hasClass("img-circle");
+ });
+ btnState('button[data-event="imageShape"][data-value="img-thumbnail"]', function () {
+ return $img.hasClass("img-thumbnail");
+ });
+ btnState('button[data-event="imageShape"]:not([data-value])', function () {
+ return !$img.is(".img-rounded, .img-circle, .img-thumbnail");
+ });
+
+ var imgFloat = $img.css("float");
+ btnState('button[data-event="floatMe"][data-value="left"]', function () {
+ return imgFloat === "left";
+ });
+ btnState('button[data-event="floatMe"][data-value="right"]', function () {
+ return imgFloat === "right";
+ });
+ btnState('button[data-event="floatMe"][data-value="none"]', function () {
+ return imgFloat !== "left" && imgFloat !== "right";
+ });
+
+ var style = $img.attr("style");
+ btnState('button[data-event="resize"][data-value="1"]', function () {
+ return !!/(^|\s)(max-)?width\s*:\s*100%/.test(style);
+ });
+ btnState('button[data-event="resize"][data-value="0.5"]', function () {
+ return !!/(^|\s)(max-)?width\s*:\s*50%/.test(style);
+ });
+ btnState('button[data-event="resize"][data-value="0.25"]', function () {
+ return !!/(^|\s)(max-)?width\s*:\s*25%/.test(style);
+ });
+ return;
+ }
+
+ // fontname
+ var $fontname = $container.find('.note-fontname');
+ if ($fontname.length) {
+ var selectedFont = styleInfo['font-family'];
+ if (!!selectedFont) {
+ selectedFont = list.head(selectedFont.split(','));
+ selectedFont = selectedFont.replace(/\'/g, '');
+ $fontname.find('.note-current-fontname').text(selectedFont);
+ checkDropdownMenu($fontname, selectedFont);
+ }
+ }
+
+ // fontsize
+ var $fontsize = $container.find('.note-fontsize');
+ $fontsize.find('.note-current-fontsize').text(styleInfo['font-size']);
+ checkDropdownMenu($fontsize, parseFloat(styleInfo['font-size']));
+
+ // lineheight
+ var $lineHeight = $container.find('.note-height');
+ checkDropdownMenu($lineHeight, parseFloat(styleInfo['line-height']));
+
+ btnState('button[data-event="bold"]', function () {
+ return styleInfo['font-bold'] === 'bold';
+ });
+ btnState('button[data-event="italic"]', function () {
+ return styleInfo['font-italic'] === 'italic';
+ });
+ btnState('button[data-event="underline"]', function () {
+ return styleInfo['font-underline'] === 'underline';
+ });
+ btnState('button[data-event="strikethrough"]', function () {
+ return styleInfo['font-strikethrough'] === 'strikethrough';
+ });
+ btnState('button[data-event="superscript"]', function () {
+ return styleInfo['font-superscript'] === 'superscript';
+ });
+ btnState('button[data-event="subscript"]', function () {
+ return styleInfo['font-subscript'] === 'subscript';
+ });
+ btnState('button[data-event="justifyLeft"]', function () {
+ return styleInfo['text-align'] === 'left' || styleInfo['text-align'] === 'start';
+ });
+ btnState('button[data-event="justifyCenter"]', function () {
+ return styleInfo['text-align'] === 'center';
+ });
+ btnState('button[data-event="justifyRight"]', function () {
+ return styleInfo['text-align'] === 'right';
+ });
+ btnState('button[data-event="justifyFull"]', function () {
+ return styleInfo['text-align'] === 'justify';
+ });
+ btnState('button[data-event="insertUnorderedList"]', function () {
+ return styleInfo['list-style'] === 'unordered';
+ });
+ btnState('button[data-event="insertOrderedList"]', function () {
+ return styleInfo['list-style'] === 'ordered';
+ });
+ };
+
+ /**
+ * update recent color
+ *
+ * @param {Node} button
+ * @param {String} eventName
+ * @param {value} value
+ */
+ this.updateRecentColor = function (button, eventName, value) {
+ var $color = $(button).closest('.note-color');
+ var $recentColor = $color.find('.note-recent-color');
+ var colorInfo = JSON.parse($recentColor.attr('data-value'));
+ colorInfo[eventName] = value;
+ $recentColor.attr('data-value', JSON.stringify(colorInfo));
+ var sKey = eventName === 'backColor' ? 'background-color' : 'color';
+ $recentColor.find('i').css(sKey, value);
+ };
+ };
+
+ return Button;
+});
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Dialog.js b/addons/web_editor/static/lib/summernote/src/js/module/Dialog.js
new file mode 100644
index 00000000000..8e7cf07b323
--- /dev/null
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Dialog.js
@@ -0,0 +1,158 @@
+define('summernote/module/Dialog', function () {
+ /**
+ * Dialog
+ *
+ * @class
+ */
+ var Dialog = function () {
+
+ /**
+ * toggle button status
+ *
+ * @param {jQuery} $btn
+ * @param {Boolean} isEnable
+ */
+ var toggleBtn = function ($btn, isEnable) {
+ $btn.toggleClass('disabled', !isEnable);
+ $btn.attr('disabled', !isEnable);
+ };
+
+ /**
+ * show image dialog
+ *
+ * @param {jQuery} $editable
+ * @param {jQuery} $dialog
+ * @return {Promise}
+ */
+ this.showImageDialog = function ($editable, $dialog) {
+ return $.Deferred(function (deferred) {
+ var $imageDialog = $dialog.find('.note-image-dialog');
+
+ var $imageInput = $dialog.find('.note-image-input'),
+ $imageUrl = $dialog.find('.note-image-url'),
+ $imageBtn = $dialog.find('.note-image-btn');
+
+ $imageDialog.one('shown.bs.modal', function () {
+ // Cloning imageInput to clear element.
+ $imageInput.replaceWith($imageInput.clone()
+ .on('change', function () {
+ deferred.resolve(this.files || this.value);
+ $imageDialog.modal('hide');
+ })
+ .val('')
+ );
+
+ $imageBtn.click(function (event) {
+ event.preventDefault();
+
+ deferred.resolve($imageUrl.val());
+ $imageDialog.modal('hide');
+ });
+
+ $imageUrl.on('keyup paste', function (event) {
+ var url;
+
+ if (event.type === 'paste') {
+ url = event.originalEvent.clipboardData.getData('text');
+ } else {
+ url = $imageUrl.val();
+ }
+
+ toggleBtn($imageBtn, url);
+ }).val('').trigger('focus');
+ }).one('hidden.bs.modal', function () {
+ $imageInput.off('change');
+ $imageUrl.off('keyup paste');
+ $imageBtn.off('click');
+
+ if (deferred.state() === 'pending') {
+ deferred.reject();
+ }
+ }).modal('show');
+ });
+ };
+
+ /**
+ * Show link dialog and set event handlers on dialog controls.
+ *
+ * @param {jQuery} $dialog
+ * @param {Object} linkInfo
+ * @return {Promise}
+ */
+ this.showLinkDialog = function ($editable, $dialog, linkInfo) {
+ return $.Deferred(function (deferred) {
+ var $linkDialog = $dialog.find('.note-link-dialog');
+
+ var $linkText = $linkDialog.find('.note-link-text'),
+ $linkUrl = $linkDialog.find('.note-link-url'),
+ $linkBtn = $linkDialog.find('.note-link-btn'),
+ $openInNewWindow = $linkDialog.find('input[type=checkbox]');
+
+ $linkDialog.one('shown.bs.modal', function () {
+ $linkText.val(linkInfo.text);
+
+ $linkText.on('input', function () {
+ // if linktext was modified by keyup,
+ // stop cloning text from linkUrl
+ linkInfo.text = $linkText.val();
+ });
+
+ // if no url was given, copy text to url
+ if (!linkInfo.url) {
+ linkInfo.url = linkInfo.text;
+ toggleBtn($linkBtn, linkInfo.text);
+ }
+
+ $linkUrl.on('input', function () {
+ toggleBtn($linkBtn, $linkUrl.val());
+ // display same link on `Text to display` input
+ // when create a new link
+ if (!linkInfo.text) {
+ $linkText.val($linkUrl.val());
+ }
+ }).val(linkInfo.url).trigger('focus').trigger('select');
+
+ $openInNewWindow.prop('checked', linkInfo.newWindow);
+
+ $linkBtn.one('click', function (event) {
+ event.preventDefault();
+
+ deferred.resolve({
+ range: linkInfo.range,
+ url: $linkUrl.val(),
+ text: $linkText.val(),
+ newWindow: $openInNewWindow.is(':checked')
+ });
+ $linkDialog.modal('hide');
+ });
+ }).one('hidden.bs.modal', function () {
+ // detach events
+ $linkText.off('input');
+ $linkUrl.off('input');
+ $linkBtn.off('click');
+
+ if (deferred.state() === 'pending') {
+ deferred.reject();
+ }
+ }).modal('show');
+ }).promise();
+ };
+
+ /**
+ * show help dialog
+ *
+ * @param {jQuery} $dialog
+ */
+ this.showHelpDialog = function ($editable, $dialog) {
+ return $.Deferred(function (deferred) {
+ var $helpDialog = $dialog.find('.note-help-dialog');
+
+ $helpDialog.one('hidden.bs.modal', function () {
+ deferred.resolve();
+ }).modal('show');
+ }).promise();
+ };
+ };
+
+ return Dialog;
+});
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Handle.js b/addons/web_editor/static/lib/summernote/src/js/module/Handle.js
new file mode 100644
index 00000000000..375428faa32
--- /dev/null
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Handle.js
@@ -0,0 +1,44 @@
+define('summernote/module/Handle', function () {
+ /**
+ * Handle
+ */
+ var Handle = function () {
+ /**
+ * update handle
+ * @param {jQuery} $handle
+ * @param {Object} styleInfo
+ * @param {Boolean} isAirMode
+ */
+ this.update = function ($handle, styleInfo, isAirMode) {
+ var $selection = $handle.find('.note-control-selection');
+ if (styleInfo.image) {
+ var $image = $(styleInfo.image);
+ var pos = isAirMode ? $image.offset() : $image.position();
+
+ // include margin
+ var imageSize = {
+ w: $image.outerWidth(true),
+ h: $image.outerHeight(true)
+ };
+
+ $selection.css({
+ display: 'block',
+ left: pos.left,
+ top: pos.top,
+ width: imageSize.w,
+ height: imageSize.h
+ }).data('target', styleInfo.image); // save current image element.
+ var sizingText = imageSize.w + 'x' + imageSize.h;
+ $selection.find('.note-control-selection-info').text(sizingText);
+ } else {
+ $selection.hide();
+ }
+ };
+
+ this.hide = function ($handle) {
+ $handle.children().hide();
+ };
+ };
+
+ return Handle;
+});
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Popover.js b/addons/web_editor/static/lib/summernote/src/js/module/Popover.js
new file mode 100644
index 00000000000..e0531f06c45
--- /dev/null
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Popover.js
@@ -0,0 +1,106 @@
+define([
+ 'summernote/core/func',
+ 'summernote/core/list',
+ 'summernote/module/Button'
+], function (func, list, Button) {
+ /**
+ * Popover (http://getbootstrap.com/javascript/#popovers)
+ */
+ var Popover = function () {
+ var button = new Button();
+
+ this.button = button; // odoo change for overwrite
+
+ /**
+ * returns position from placeholder
+ * @param {Node} placeholder
+ * @param {Boolean} isAirMode
+ */
+ var posFromPlaceholder = function (placeholder, isAirMode) {
+ var $placeholder = $(placeholder);
+ var pos = isAirMode ? $placeholder.offset() : $placeholder.position();
+ var height = $placeholder.outerHeight(true); // include margin
+
+ // popover below placeholder.
+ return {
+ left: pos.left,
+ top: pos.top + height
+ };
+ };
+
+ /**
+ * show popover
+ * @param {jQuery} popover
+ * @param {Position} pos
+ */
+ var showPopover = function ($popover, pos) {
+ $popover.css({
+ display: 'block',
+ left: pos.left,
+ top: pos.top
+ });
+ };
+
+ var PX_POPOVER_ARROW_OFFSET_X = 20;
+
+ /**
+ * update current state
+ * @param {jQuery} $popover - popover container
+ * @param {Object} styleInfo - style object
+ * @param {Boolean} isAirMode
+ */
+ this.update = function ($popover, styleInfo, isAirMode) {
+ button.update($popover, styleInfo);
+
+ var $linkPopover = $popover.find('.note-link-popover');
+ if (styleInfo.anchor) {
+ var $anchor = $linkPopover.find('a');
+ var href = $(styleInfo.anchor).attr('href');
+ $anchor.attr('href', href).html(href);
+ showPopover($linkPopover, posFromPlaceholder(styleInfo.anchor, isAirMode));
+ } else {
+ $linkPopover.hide();
+ }
+
+ var $imagePopover = $popover.find('.note-image-popover');
+ if (styleInfo.image) {
+ showPopover($imagePopover, posFromPlaceholder(styleInfo.image, isAirMode));
+ } else {
+ $imagePopover.hide();
+ }
+
+ var $airPopover = $popover.find('.note-air-popover');
+ if (isAirMode && !styleInfo.range.isCollapsed()) {
+ var rect = list.last(styleInfo.range.getClientRects());
+ if (rect) {
+ var bnd = func.rect2bnd(rect);
+ showPopover($airPopover, {
+ left: Math.max(bnd.left + bnd.width / 2 - PX_POPOVER_ARROW_OFFSET_X, 0),
+ top: bnd.top + bnd.height
+ });
+ }
+ } else {
+ $airPopover.hide();
+ }
+ };
+
+ /**
+ * @param {Node} button
+ * @param {String} eventName
+ * @param {String} value
+ */
+ this.updateRecentColor = function (button, eventName, value) {
+ button.updateRecentColor(button, eventName, value);
+ };
+
+ /**
+ * hide all popovers
+ * @param {jQuery} $popover - popover container
+ */
+ this.hide = function ($popover) {
+ $popover.children().hide();
+ };
+ };
+
+ return Popover;
+});
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Toolbar.js b/addons/web_editor/static/lib/summernote/src/js/module/Toolbar.js
new file mode 100644
index 00000000000..832b7c4c561
--- /dev/null
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Toolbar.js
@@ -0,0 +1,58 @@
+define([
+ 'summernote/core/list',
+ 'summernote/module/Button'
+], function (list, Button) {
+ /**
+ * Toolbar
+ */
+ var Toolbar = function () {
+ var button = new Button();
+
+ this.button = button; // odoo change for overwrite
+
+ this.update = function ($toolbar, styleInfo) {
+ button.update($toolbar, styleInfo);
+ };
+
+ /**
+ * @param {Node} button
+ * @param {String} eventName
+ * @param {String} value
+ */
+ this.updateRecentColor = function (buttonNode, eventName, value) {
+ button.updateRecentColor(buttonNode, eventName, value);
+ };
+
+ /**
+ * activate buttons exclude codeview
+ * @param {jQuery} $toolbar
+ */
+ this.activate = function ($toolbar) {
+ $toolbar.find('button')
+ .not('button[data-event="codeview"]')
+ .removeClass('disabled');
+ };
+
+ /**
+ * deactivate buttons exclude codeview
+ * @param {jQuery} $toolbar
+ */
+ this.deactivate = function ($toolbar) {
+ $toolbar.find('button')
+ .not('button[data-event="codeview"]')
+ .addClass('disabled');
+ };
+
+ this.updateFullscreen = function ($container, bFullscreen) {
+ var $btn = $container.find('button[data-event="fullscreen"]');
+ $btn.toggleClass('active', bFullscreen);
+ };
+
+ this.updateCodeview = function ($container, isCodeview) {
+ var $btn = $container.find('button[data-event="codeview"]');
+ $btn.toggleClass('active', isCodeview);
+ };
+ };
+
+ return Toolbar;
+});