Skip to content

Commit

Permalink
fix: 修復 summernote-custom-style 選擇顏色失效、summernote-comment-popover 懸浮框…
Browse files Browse the repository at this point in the history
…閃爍問題 (#5)

* 修復 summernote-custom-style 選擇顏色失效問題
* 修復 summernote-comment-popover 懸浮框閃爍問題
* summernote-comment-popover 改用 jquery function 初始化 popover

Signed-off-by: Clare Wan <lisanwan710@gmail.com>
  • Loading branch information
clare0710 committed May 9, 2024
1 parent bae4001 commit 567993e
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ options = {{
使用 className 初始化 popover

```js
$(a.summernote-comment-popover-anchor[data-toggle="popover"]).popover()
$(a.summernote-comment-popover-anchor[data-toggle="popover"]).hoverPopover()
```

設定 className css
Expand Down
26 changes: 23 additions & 3 deletions src/plugin/custom/summernote-comment-popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@
factory(window.jQuery);
}
}(function ($) {
$.fn.hoverPopover = function () {
if (this && this.length){
this.popover({
trigger: "manual",
})
.on("mouseenter", function () {
$(this).popover("show")

})
.on("mouseleave", function() {
if (!$('.popover:hover').length) {
$(this).popover('hide')
}
})

$(document).on('mouseleave', '.popover', function() {
$(this).popover('hide')
});
}
}
$.extend($.summernote.options, {
commentPopover: {
className: null,
Expand Down Expand Up @@ -102,7 +122,7 @@
layoutInfo.editor.one('mouseenter', function (event) {
let $edit = layoutInfo.editingArea
let $allPopover = $edit.find(`a.${anchorClassName}[data-toggle="popover"]`)
$allPopover.popover()
$allPopover.hoverPopover()
})
}
}
Expand Down Expand Up @@ -444,7 +464,7 @@
.attr("data-content", dataContent)

$popover.popover('dispose')
$popover.popover()
$popover.hoverPopover()

return
}
Expand Down Expand Up @@ -512,7 +532,7 @@
var dataTitle = this.encodeString(title)
$anchor.attr("data-title", dataTitle).attr("data-content", dataContent)

$anchor.popover()
$anchor.hoverPopover()

// reset range
rng = range.createFromNode($anchor[0])
Expand Down
226 changes: 168 additions & 58 deletions src/plugin/custom/summernote-custom-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,160 @@
}
this.updateListCount()
}

/**
* 'colorPalette' copy from 'summernote-v0.8.18/src/js/base/module/Buttons.js' modify click event
*/
this.colorPalette = function(className, tooltip, backColor, foreColor) {
return ui.buttonGroup({
className: 'note-color ' + className,
children: [
ui.button({
className: 'note-current-color-button',
contents: ui.icon(options.icons.font + ' note-recent-color'),
tooltip: tooltip,
click: (e) => {
const $button = $(e.currentTarget);
if (backColor && foreColor) {
context.invoke('customStyle.foreColor', $button.attr('data-foreColor'));
context.invoke('customStyle.backColor', $button.attr('data-backColor'));
} else if (backColor) {
context.invoke('customStyle.backColor', $button.attr('data-backColor'));
} else if (foreColor) {
context.invoke('customStyle.foreColor', $button.attr('data-foreColor'));
}
},
callback: ($button) => {
const $recentColor = $button.find('.note-recent-color');
if (backColor) {
$recentColor.css('background-color', options.colorButton.backColor);
$button.attr('data-backColor', options.colorButton.backColor);
}
if (foreColor) {
$recentColor.css('color', options.colorButton.foreColor);
$button.attr('data-foreColor', options.colorButton.foreColor);
} else {
$recentColor.css('color', 'transparent');
}
},
}),
ui.button({
className: 'dropdown-toggle',
contents: ui.dropdownButtonContents('', options),
tooltip: lang.customStyle.more,
data: {
toggle: 'dropdown',
},
}),
ui.dropdown({
items: (backColor ? [
'<div class="note-palette">',
'<div class="note-palette-title">' + lang.customStyle.background + '</div>',
'<div>',
'<button type="button" class="note-color-reset btn btn-light btn-default" data-event="backColor" data-value="transparent">',
lang.customStyle.transparent,
'</button>',
'</div>',
'<div class="note-holder" data-event="backColor"><!-- back colors --></div>',
'<div>',
'<button type="button" class="note-color-select btn btn-light btn-default" data-event="openPalette" data-value="backColorPicker">',
lang.customStyle.cpSelect,
'</button>',
'<input type="color" id="backColorPicker" class="note-btn note-color-select-btn" value="' + options.colorButton.backColor + '" data-event="backColorPalette">',
'</div>',
'<div class="note-holder-custom" id="backColorPalette" data-event="backColor"></div>',
'</div>',
].join('') : '') +
(foreColor ? [
'<div class="note-palette">',
'<div class="note-palette-title">' + lang.customStyle.foreground + '</div>',
'<div>',
'<button type="button" class="note-color-reset btn btn-light btn-default" data-event="removeFormat" data-value="foreColor">',
lang.customStyle.resetToDefault,
'</button>',
'</div>',
'<div class="note-holder" data-event="foreColor"><!-- fore colors --></div>',
'<div>',
'<button type="button" class="note-color-select btn btn-light btn-default" data-event="openPalette" data-value="foreColorPicker">',
lang.customStyle.cpSelect,
'</button>',
'<input type="color" id="foreColorPicker" class="note-btn note-color-select-btn" value="' + options.colorButton.foreColor + '" data-event="foreColorPalette">',
'</div>',
'<div class="note-holder-custom" id="foreColorPalette" data-event="foreColor"></div>',
'</div>',
].join('') : ''),
callback: ($dropdown) => {
$dropdown.find('.note-holder').each((idx, item) => {
const $holder = $(item);
$holder.append(ui.palette({
colors: options.colors,
colorsName: options.colorsName,
eventName: $holder.data('event'),
container: options.container,
tooltip: options.tooltip,
}).render());
});
var customColors = [['#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF']];
$dropdown.find('.note-holder-custom').each((idx, item) => {
const $holder = $(item);
$holder.append(ui.palette({
colors: customColors,
colorsName: customColors,
eventName: $holder.data('event'),
container: options.container,
tooltip: options.tooltip,
}).render());
});
$dropdown.find('input[type=color]').each((idx, item) => {
$(item).change(function() {
const $chip = $dropdown.find('#' + $(this).data('event')).find('.note-color-btn').first();
const color = this.value.toUpperCase();
$chip.css('background-color', color)
.attr('aria-label', color)
.attr('data-value', color)
.attr('data-original-title', color);
$chip.click();
});
});
},
click: (event) => {
event.stopPropagation();

const $menu = $(event.currentTarget);
const $button = $(event.target);
const eventName = $button.data('event');
const value = $button.attr('data-value');

if (eventName === 'openPalette') {
const $picker = $menu.find('#' + value);
const $palette = $($menu.find('#' + $picker.data('event')).find('.note-color-row')[0]);
// Shift palette chips
const $chip = $palette.find('.note-color-btn').last().detach();

// Set chip attributes
const color = $picker.val();
$chip.css('background-color', color)
.attr('aria-label', color)
.attr('data-value', color)
.attr('data-original-title', color);
$palette.prepend($chip);
$picker.click();
} else {
if (lists.contains(['backColor', 'foreColor'], eventName)) {
const key = eventName === 'backColor' ? 'background-color' : 'color';
const $color = $button.closest('.note-color').find('.note-recent-color');
const $currentButton = $button.closest('.note-color').find('.note-current-color-button');
$color.css(key, value);
$currentButton.attr('data-' + eventName, value);
}
context.invoke('customStyle.' + eventName, value);
}
},
})
]
}).render();
}

this.initEditor = function () {
let $customStyleEditor = this.$dialog.find('.summernote-customStyle-editor')
let $customStyleToolbar = $customStyleEditor.find('.summernote-customStyle-toolbar')
Expand Down Expand Up @@ -339,64 +493,8 @@
return $btn
})

// foreColor and backColor button color palette
let currentColorEvent = (backColor, foreColor) =>
(e) => {
const $button = $(e.currentTarget);
if (backColor && foreColor) {
context.invoke('customStyle.foreColor', $button.attr('data-foreColor'));
context.invoke('customStyle.backColor', $button.attr('data-backColor'));
} else if (backColor) {
context.invoke('customStyle.backColor', $button.attr('data-backColor'));
} else if (foreColor) {
context.invoke('customStyle.foreColor', $button.attr('data-foreColor'));
}
}
let colorEvent = (event) => {
event.stopPropagation();

const $menu = $(event.currentTarget);
const $button = $(event.target);
const eventName = $button.data('event');
const value = $button.attr('data-value');

if (eventName === 'openPalette') {
const $picker = $menu.find('#' + value);
const $palette = $($menu.find('#' + $picker.data('event')).find('.note-color-row')[0]);

// Shift palette chips
const $chip = $palette.find('.note-color-btn').last().detach();

// Set chip attributes
const color = $picker.val();
$chip.css('background-color', color)
.attr('aria-label', color)
.attr('data-value', color)
.attr('data-original-title', color);
$palette.prepend($chip);
$picker.click();
} else {
if (lists.contains(['backColor', 'foreColor'], eventName)) {
const key = eventName === 'backColor' ? 'background-color' : 'color';
const $color = $button.closest('.note-color').find('.note-recent-color');
const $currentButton = $button.closest('.note-color').find('.note-current-color-button');

$color.css(key, value);
$currentButton.attr('data-' + eventName, value);
$menu.dropdown('hide')
}
context.invoke('customStyle.' + eventName, value);
}
}
let $forecolorBtn = context.memo('button.forecolor')()
$forecolorBtn.find('.note-current-color-button').addClass('note-color-forecolor')
.off('click').on('click', currentColorEvent(false, true))
$forecolorBtn.find('.dropdown-menu').off('click').on('click', colorEvent)
let $backcolorBtn = context.memo('button.backcolor')()
$backcolorBtn.find('.note-current-color-button').addClass('note-color-backcolor')
.off('click').on('click', currentColorEvent(true, false))
$backcolorBtn.find('.dropdown-menu').off('click').on('click', colorEvent)

let $forecolorBtn = this.colorPalette('note-color-fore-btn', lang.customStyle.foreground, false, true)
let $backcolorBtn = this.colorPalette('note-color-back-btn', lang.customStyle.background, true, false)

// add buttons to toolbar
$('<div class="note-btn-group btn-group">').append($fontNameBtn).appendTo($customStyleToolbar)
Expand Down Expand Up @@ -791,6 +889,12 @@
hint: '關閉對話框自動儲存樣式設定',
stylePreview: '樣式預覽',
noStyleSelected: '請選擇樣式',
foreground: '字型顏色',
resetToDefault: '預設',
cpSelect: 'Select',
background: '字型背景',
transparent: '透明',
more: '更多'
}
},
'en-US': {
Expand All @@ -804,6 +908,12 @@
hint: 'Close dialog will automatically save style settings',
stylePreview: 'Style Preview',
noStyleSelected: 'Please Select One Style',
foreground: 'Text Color',
resetToDefault: 'Reset to default',
cpSelect: 'Select',
background: 'Background Color',
transparent: 'Transparent',
more: 'More Color'
}
},
});
Expand Down

0 comments on commit 567993e

Please sign in to comment.