Binary file not shown.
@@ -0,0 +1,118 @@
|
||||
(function (factory) {
|
||||
/* global define */
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals: jQuery
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
$.extend($.summernote.plugins, {
|
||||
|
||||
'ts_attach': function (context) {
|
||||
var self = this;
|
||||
|
||||
var ui = $.summernote.ui;
|
||||
var $editor = context.layoutInfo.editor;
|
||||
var options = context.options;
|
||||
var lang = options.langInfo;
|
||||
|
||||
|
||||
context.memo('button.ts_attach', function () {
|
||||
|
||||
var button = ui.button({
|
||||
contents: '<i class="fas fa-paperclip"></i>',
|
||||
tooltip: 'ts_attach',
|
||||
click: function () {
|
||||
self.show()
|
||||
}
|
||||
});
|
||||
|
||||
// create jQuery object from button instance.
|
||||
var $highlight = button.render();
|
||||
return $highlight;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
this.createDialog = function () {
|
||||
|
||||
var $box = $('<div />');
|
||||
var $frame = $('<iframe width="100%" height="444" frameborder="0" scrolling="no" src="'+siteUrl+'index.php?app=attach&ac=editor&ts=list" />');
|
||||
$box.append($frame);
|
||||
return $box.html();
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.showAttachDialog = function () {
|
||||
return $.Deferred(function () {
|
||||
ui.onDialogShown(self.$dialog, function () {
|
||||
|
||||
});
|
||||
|
||||
ui.onDialogHidden(self.$dialog, function () {
|
||||
|
||||
});
|
||||
|
||||
ui.showDialog(self.$dialog);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.show = function () {
|
||||
|
||||
|
||||
this.showAttachDialog().then(function () {
|
||||
self.$dialog.modal('hide');
|
||||
context.invoke('editor.restoreRange');
|
||||
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.initialize = function () {
|
||||
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
||||
|
||||
var body = [''].join('');
|
||||
|
||||
this.$dialog = ui.dialog({
|
||||
className: 'ts-attach',
|
||||
title: '我的附件',
|
||||
body: this.createDialog(),
|
||||
footer: body,
|
||||
//callback: function ($node) {
|
||||
// $node.find('.modal-body').css({
|
||||
// 'max-height': 300,
|
||||
// 'overflow': 'scroll'
|
||||
// });
|
||||
//}
|
||||
}).render().appendTo($container);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
this.destroy = function () {
|
||||
ui.hideDialog(this.$dialog);
|
||||
this.$dialog.remove();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}))
|
||||
@@ -0,0 +1,118 @@
|
||||
(function (factory) {
|
||||
/* global define */
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals: jQuery
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
$.extend($.summernote.plugins, {
|
||||
|
||||
'ts_audio': function (context) {
|
||||
var self = this;
|
||||
|
||||
var ui = $.summernote.ui;
|
||||
var $editor = context.layoutInfo.editor;
|
||||
var options = context.options;
|
||||
var lang = options.langInfo;
|
||||
|
||||
|
||||
context.memo('button.ts_audio', function () {
|
||||
|
||||
var button = ui.button({
|
||||
contents: '<i class="fas fa-headphones"></i>',
|
||||
tooltip: 'ts_audio',
|
||||
click: function () {
|
||||
self.show()
|
||||
}
|
||||
});
|
||||
|
||||
// create jQuery object from button instance.
|
||||
var $highlight = button.render();
|
||||
return $highlight;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
this.createDialog = function () {
|
||||
|
||||
var $box = $('<div />');
|
||||
var $frame = $('<iframe width="100%" height="444" frameborder="0" scrolling="no" src="'+siteUrl+'index.php?app=audio&ac=editor&ts=list" />');
|
||||
$box.append($frame);
|
||||
return $box.html();
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.showAttachDialog = function () {
|
||||
return $.Deferred(function () {
|
||||
ui.onDialogShown(self.$dialog, function () {
|
||||
|
||||
});
|
||||
|
||||
ui.onDialogHidden(self.$dialog, function () {
|
||||
|
||||
});
|
||||
|
||||
ui.showDialog(self.$dialog);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.show = function () {
|
||||
|
||||
|
||||
this.showAttachDialog().then(function () {
|
||||
self.$dialog.modal('hide');
|
||||
context.invoke('editor.restoreRange');
|
||||
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.initialize = function () {
|
||||
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
||||
|
||||
var body = [''].join('');
|
||||
|
||||
this.$dialog = ui.dialog({
|
||||
className: 'ts-audio',
|
||||
title: '我的音频',
|
||||
body: this.createDialog(),
|
||||
footer: body,
|
||||
//callback: function ($node) {
|
||||
// $node.find('.modal-body').css({
|
||||
// 'max-height': 300,
|
||||
// 'overflow': 'scroll'
|
||||
// });
|
||||
//}
|
||||
}).render().appendTo($container);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
this.destroy = function () {
|
||||
ui.hideDialog(this.$dialog);
|
||||
this.$dialog.remove();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}))
|
||||
@@ -0,0 +1,16 @@
|
||||
.ext-databasic {
|
||||
position: relative;
|
||||
display: block;
|
||||
min-height: 50px;
|
||||
background-color: cyan;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border: 1px solid white;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ext-databasic p {
|
||||
color: white;
|
||||
font-size: 1.2em;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
// pull in some summernote core functions
|
||||
var ui = $.summernote.ui;
|
||||
var dom = $.summernote.dom;
|
||||
|
||||
// define the popover plugin
|
||||
var DataBasicPlugin = function(context) {
|
||||
var self = this;
|
||||
var options = context.options;
|
||||
var lang = options.langInfo;
|
||||
|
||||
self.icon = '<i class="fa fa-object-group"/>';
|
||||
|
||||
// add context menu button for dialog
|
||||
context.memo('button.databasic', function() {
|
||||
return ui.button({
|
||||
contents: self.icon,
|
||||
tooltip: lang.databasic.insert,
|
||||
click: context.createInvokeHandler('databasic.showDialog'),
|
||||
}).render();
|
||||
});
|
||||
|
||||
// add popover edit button
|
||||
context.memo('button.databasicDialog', function() {
|
||||
return ui.button({
|
||||
contents: self.icon,
|
||||
tooltip: lang.databasic.edit,
|
||||
click: context.createInvokeHandler('databasic.showDialog'),
|
||||
}).render();
|
||||
});
|
||||
|
||||
// add popover size buttons
|
||||
context.memo('button.databasicSize100', function() {
|
||||
return ui.button({
|
||||
contents: '<span class="note-fontsize-10">100%</span>',
|
||||
tooltip: lang.image.resizeFull,
|
||||
click: context.createInvokeHandler('editor.resize', '1'),
|
||||
}).render();
|
||||
});
|
||||
context.memo('button.databasicSize50', function() {
|
||||
return ui.button({
|
||||
contents: '<span class="note-fontsize-10">50%</span>',
|
||||
tooltip: lang.image.resizeHalf,
|
||||
click: context.createInvokeHandler('editor.resize', '0.5'),
|
||||
}).render();
|
||||
});
|
||||
context.memo('button.databasicSize25', function() {
|
||||
return ui.button({
|
||||
contents: '<span class="note-fontsize-10">25%</span>',
|
||||
tooltip: lang.image.resizeQuarter,
|
||||
click: context.createInvokeHandler('editor.resize', '0.25'),
|
||||
}).render();
|
||||
});
|
||||
|
||||
self.events = {
|
||||
'summernote.init': function(we, e) {
|
||||
// update existing containers
|
||||
$('data.ext-databasic', e.editable).each(function() { self.setContent($(this)); });
|
||||
// TODO: make this an undo snapshot...
|
||||
},
|
||||
'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function() {
|
||||
self.update();
|
||||
},
|
||||
'summernote.dialog.shown': function() {
|
||||
self.hidePopover();
|
||||
},
|
||||
};
|
||||
|
||||
self.initialize = function() {
|
||||
// create dialog markup
|
||||
var $container = options.dialogsInBody ? $(document.body) : context.layoutInfo.editor;
|
||||
|
||||
var body = '<div class="form-group row-fluid">' +
|
||||
'<label>' + lang.databasic.testLabel + '</label>' +
|
||||
'<input class="ext-databasic-test form-control" type="text" />' +
|
||||
'</div>';
|
||||
var footer = '<button href="#" class="btn btn-primary ext-databasic-save">' + lang.databasic.insert + '</button>';
|
||||
|
||||
self.$dialog = ui.dialog({
|
||||
title: lang.databasic.name,
|
||||
fade: options.dialogsFade,
|
||||
body: body,
|
||||
footer: footer,
|
||||
}).render().appendTo($container);
|
||||
|
||||
// create popover
|
||||
self.$popover = ui.popover({
|
||||
className: 'ext-databasic-popover',
|
||||
}).render().appendTo('body');
|
||||
var $content = self.$popover.find('.popover-content');
|
||||
|
||||
context.invoke('buttons.build', $content, options.popover.databasic);
|
||||
};
|
||||
|
||||
self.destroy = function() {
|
||||
self.$popover.remove();
|
||||
self.$popover = null;
|
||||
self.$dialog.remove();
|
||||
self.$dialog = null;
|
||||
};
|
||||
|
||||
self.update = function() {
|
||||
// Prevent focusing on editable when invoke('code') is executed
|
||||
if (!context.invoke('editor.hasFocus')) {
|
||||
self.hidePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
var rng = context.invoke('editor.createRange');
|
||||
var visible = false;
|
||||
|
||||
if (rng.isOnData()) {
|
||||
var $data = $(rng.sc).closest('data.ext-databasic');
|
||||
|
||||
if ($data.length) {
|
||||
var pos = dom.posFromPlaceholder($data[0]);
|
||||
|
||||
self.$popover.css({
|
||||
display: 'block',
|
||||
left: pos.left,
|
||||
top: pos.top,
|
||||
});
|
||||
|
||||
// save editor target to let size buttons resize the container
|
||||
context.invoke('editor.saveTarget', $data[0]);
|
||||
|
||||
visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
// hide if not visible
|
||||
if (!visible) {
|
||||
self.hidePopover();
|
||||
}
|
||||
};
|
||||
|
||||
self.hidePopover = function() {
|
||||
self.$popover.hide();
|
||||
};
|
||||
|
||||
// define plugin dialog
|
||||
self.getInfo = function() {
|
||||
var rng = context.invoke('editor.createRange');
|
||||
|
||||
if (rng.isOnData()) {
|
||||
var $data = $(rng.sc).closest('data.ext-databasic');
|
||||
|
||||
if ($data.length) {
|
||||
// Get the first node on range(for edit).
|
||||
return {
|
||||
node: $data,
|
||||
test: $data.attr('data-test'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
self.setContent = function($node) {
|
||||
$node.html('<p contenteditable="false">' + self.icon + ' ' + lang.databasic.name + ': ' +
|
||||
$node.attr('data-test') + '</p>');
|
||||
};
|
||||
|
||||
self.updateNode = function(info) {
|
||||
self.setContent(info.node
|
||||
.attr('data-test', info.test));
|
||||
};
|
||||
|
||||
self.createNode = function(info) {
|
||||
var $node = $('<data class="ext-databasic"></data>');
|
||||
|
||||
if ($node) {
|
||||
// save node to info structure
|
||||
info.node = $node;
|
||||
// insert node into editor dom
|
||||
context.invoke('editor.insertNode', $node[0]);
|
||||
}
|
||||
|
||||
return $node;
|
||||
};
|
||||
|
||||
self.showDialog = function() {
|
||||
var info = self.getInfo();
|
||||
var newNode = !info.node;
|
||||
context.invoke('editor.saveRange');
|
||||
|
||||
self
|
||||
.openDialog(info)
|
||||
.then(function(dialogInfo) {
|
||||
// [workaround] hide dialog before restore range for IE range focus
|
||||
ui.hideDialog(self.$dialog);
|
||||
context.invoke('editor.restoreRange');
|
||||
|
||||
// insert a new node
|
||||
if (newNode) {
|
||||
self.createNode(info);
|
||||
}
|
||||
|
||||
// update info with dialog info
|
||||
$.extend(info, dialogInfo);
|
||||
|
||||
self.updateNode(info);
|
||||
})
|
||||
.fail(function() {
|
||||
context.invoke('editor.restoreRange');
|
||||
});
|
||||
};
|
||||
|
||||
self.openDialog = function(info) {
|
||||
return $.Deferred(function(deferred) {
|
||||
var $inpTest = self.$dialog.find('.ext-databasic-test');
|
||||
var $saveBtn = self.$dialog.find('.ext-databasic-save');
|
||||
var onKeyup = function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
$saveBtn.trigger('click');
|
||||
}
|
||||
};
|
||||
|
||||
ui.onDialogShown(self.$dialog, function() {
|
||||
context.triggerEvent('dialog.shown');
|
||||
|
||||
$inpTest.val(info.test).on('input', function() {
|
||||
ui.toggleBtn($saveBtn, $inpTest.val());
|
||||
}).trigger('focus').on('keyup', onKeyup);
|
||||
|
||||
$saveBtn
|
||||
.text(info.node ? lang.databasic.edit : lang.databasic.insert)
|
||||
.click(function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
deferred.resolve({ test: $inpTest.val() });
|
||||
});
|
||||
|
||||
// init save button
|
||||
ui.toggleBtn($saveBtn, $inpTest.val());
|
||||
});
|
||||
|
||||
ui.onDialogHidden(self.$dialog, function() {
|
||||
$inpTest.off('input keyup');
|
||||
$saveBtn.off('click');
|
||||
|
||||
if (deferred.state() === 'pending') {
|
||||
deferred.reject();
|
||||
}
|
||||
});
|
||||
|
||||
ui.showDialog(self.$dialog);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Extends summernote
|
||||
$.extend(true, $.summernote, {
|
||||
plugins: {
|
||||
databasic: DataBasicPlugin,
|
||||
},
|
||||
|
||||
options: {
|
||||
popover: {
|
||||
databasic: [
|
||||
['databasic', ['databasicDialog', 'databasicSize100', 'databasicSize50', 'databasicSize25']],
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
// add localization texts
|
||||
lang: {
|
||||
'en-US': {
|
||||
databasic: {
|
||||
name: 'Basic Data Container',
|
||||
insert: 'insert basic data container',
|
||||
edit: 'edit basic data container',
|
||||
testLabel: 'test input',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
}));
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1,311 @@
|
||||
(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
$.extend($.summernote.plugins, {
|
||||
'specialchars': function(context) {
|
||||
var self = this;
|
||||
var ui = $.summernote.ui;
|
||||
|
||||
var $editor = context.layoutInfo.editor;
|
||||
var options = context.options;
|
||||
var lang = options.langInfo;
|
||||
|
||||
var KEY = {
|
||||
UP: 38,
|
||||
DOWN: 40,
|
||||
LEFT: 37,
|
||||
RIGHT: 39,
|
||||
ENTER: 13,
|
||||
};
|
||||
var COLUMN_LENGTH = 15;
|
||||
var COLUMN_WIDTH = 35;
|
||||
|
||||
var currentColumn = 0;
|
||||
var currentRow = 0;
|
||||
var totalColumn = 0;
|
||||
var totalRow = 0;
|
||||
|
||||
// special characters data set
|
||||
var specialCharDataSet = [
|
||||
'"', '&', '<', '>', '¡', '¢',
|
||||
'£', '¤', '¥', '¦', '§',
|
||||
'¨', '©', 'ª', '«', '¬',
|
||||
'®', '¯', '°', '±', '²',
|
||||
'³', '´', 'µ', '¶', '·',
|
||||
'¸', '¹', 'º', '»', '¼',
|
||||
'½', '¾', '¿', '×', '÷',
|
||||
'ƒ', 'ˆ', '˜', '–', '—',
|
||||
'‘', '’', '‚', '“', '”',
|
||||
'„', '†', '‡', '•', '…',
|
||||
'‰', '′', '″', '‹', '›',
|
||||
'‾', '⁄', '€', 'ℑ', '℘',
|
||||
'ℜ', '™', 'ℵ', '←', '↑',
|
||||
'→', '↓', '↔', '↵', '⇐',
|
||||
'⇑', '⇒', '⇓', '⇔', '∀',
|
||||
'∂', '∃', '∅', '∇', '∈',
|
||||
'∉', '∋', '∏', '∑', '−',
|
||||
'∗', '√', '∝', '∞', '∠',
|
||||
'∧', '∨', '∩', '∪', '∫',
|
||||
'∴', '∼', '≅', '≈', '≠',
|
||||
'≡', '≤', '≥', '⊂', '⊃',
|
||||
'⊄', '⊆', '⊇', '⊕', '⊗',
|
||||
'⊥', '⋅', '⌈', '⌉', '⌊',
|
||||
'⌋', '◊', '♠', '♣', '♥',
|
||||
'♦',
|
||||
];
|
||||
|
||||
context.memo('button.specialchars', function() {
|
||||
return ui.button({
|
||||
contents: '<i class="fa fa-font fa-flip-vertical">',
|
||||
tooltip: lang.specialChar.specialChar,
|
||||
click: function() {
|
||||
self.show();
|
||||
},
|
||||
}).render();
|
||||
});
|
||||
|
||||
/**
|
||||
* Make Special Characters Table
|
||||
*
|
||||
* @member plugin.specialChar
|
||||
* @private
|
||||
* @return {jQuery}
|
||||
*/
|
||||
this.makeSpecialCharSetTable = function() {
|
||||
var $table = $('<table/>');
|
||||
$.each(specialCharDataSet, function(idx, text) {
|
||||
var $td = $('<td/>').addClass('note-specialchar-node');
|
||||
var $tr = (idx % COLUMN_LENGTH === 0) ? $('<tr/>') : $table.find('tr').last();
|
||||
|
||||
var $button = ui.button({
|
||||
callback: function($node) {
|
||||
$node.html(text);
|
||||
$node.attr('title', text);
|
||||
$node.attr('data-value', encodeURIComponent(text));
|
||||
$node.css({
|
||||
width: COLUMN_WIDTH,
|
||||
'margin-right': '2px',
|
||||
'margin-bottom': '2px',
|
||||
});
|
||||
},
|
||||
}).render();
|
||||
|
||||
$td.append($button);
|
||||
|
||||
$tr.append($td);
|
||||
if (idx % COLUMN_LENGTH === 0) {
|
||||
$table.append($tr);
|
||||
}
|
||||
});
|
||||
|
||||
totalRow = $table.find('tr').length;
|
||||
totalColumn = COLUMN_LENGTH;
|
||||
|
||||
return $table;
|
||||
};
|
||||
|
||||
this.initialize = function() {
|
||||
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
||||
|
||||
var body = '<div class="form-group row-fluid">' + this.makeSpecialCharSetTable()[0].outerHTML + '</div>';
|
||||
|
||||
this.$dialog = ui.dialog({
|
||||
title: lang.specialChar.select,
|
||||
body: body,
|
||||
}).render().appendTo($container);
|
||||
};
|
||||
|
||||
this.show = function() {
|
||||
var text = context.invoke('editor.getSelectedText');
|
||||
context.invoke('editor.saveRange');
|
||||
this.showSpecialCharDialog(text).then(function(selectChar) {
|
||||
context.invoke('editor.restoreRange');
|
||||
|
||||
// build node
|
||||
var $node = $('<span></span>').html(selectChar)[0];
|
||||
|
||||
if ($node) {
|
||||
// insert video node
|
||||
context.invoke('editor.insertNode', $node);
|
||||
}
|
||||
}).fail(function() {
|
||||
context.invoke('editor.restoreRange');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* show image dialog
|
||||
*
|
||||
* @param {jQuery} $dialog
|
||||
* @return {Promise}
|
||||
*/
|
||||
this.showSpecialCharDialog = function(text) {
|
||||
return $.Deferred(function(deferred) {
|
||||
var $specialCharDialog = self.$dialog;
|
||||
var $specialCharNode = $specialCharDialog.find('.note-specialchar-node');
|
||||
var $selectedNode = null;
|
||||
var ARROW_KEYS = [KEY.UP, KEY.DOWN, KEY.LEFT, KEY.RIGHT];
|
||||
var ENTER_KEY = KEY.ENTER;
|
||||
|
||||
function addActiveClass($target) {
|
||||
if (!$target) {
|
||||
return;
|
||||
}
|
||||
$target.find('button').addClass('active');
|
||||
$selectedNode = $target;
|
||||
}
|
||||
|
||||
function removeActiveClass($target) {
|
||||
$target.find('button').removeClass('active');
|
||||
$selectedNode = null;
|
||||
}
|
||||
|
||||
// find next node
|
||||
function findNextNode(row, column) {
|
||||
var findNode = null;
|
||||
$.each($specialCharNode, function(idx, $node) {
|
||||
var findRow = Math.ceil((idx + 1) / COLUMN_LENGTH);
|
||||
var findColumn = ((idx + 1) % COLUMN_LENGTH === 0) ? COLUMN_LENGTH : (idx + 1) % COLUMN_LENGTH;
|
||||
if (findRow === row && findColumn === column) {
|
||||
findNode = $node;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return $(findNode);
|
||||
}
|
||||
|
||||
function arrowKeyHandler(keyCode) {
|
||||
// left, right, up, down key
|
||||
var $nextNode;
|
||||
var lastRowColumnLength = $specialCharNode.length % totalColumn;
|
||||
|
||||
if (KEY.LEFT === keyCode) {
|
||||
if (currentColumn > 1) {
|
||||
currentColumn = currentColumn - 1;
|
||||
} else if (currentRow === 1 && currentColumn === 1) {
|
||||
currentColumn = lastRowColumnLength;
|
||||
currentRow = totalRow;
|
||||
} else {
|
||||
currentColumn = totalColumn;
|
||||
currentRow = currentRow - 1;
|
||||
}
|
||||
} else if (KEY.RIGHT === keyCode) {
|
||||
if (currentRow === totalRow && lastRowColumnLength === currentColumn) {
|
||||
currentColumn = 1;
|
||||
currentRow = 1;
|
||||
} else if (currentColumn < totalColumn) {
|
||||
currentColumn = currentColumn + 1;
|
||||
} else {
|
||||
currentColumn = 1;
|
||||
currentRow = currentRow + 1;
|
||||
}
|
||||
} else if (KEY.UP === keyCode) {
|
||||
if (currentRow === 1 && lastRowColumnLength < currentColumn) {
|
||||
currentRow = totalRow - 1;
|
||||
} else {
|
||||
currentRow = currentRow - 1;
|
||||
}
|
||||
} else if (KEY.DOWN === keyCode) {
|
||||
currentRow = currentRow + 1;
|
||||
}
|
||||
|
||||
if (currentRow === totalRow && currentColumn > lastRowColumnLength) {
|
||||
currentRow = 1;
|
||||
} else if (currentRow > totalRow) {
|
||||
currentRow = 1;
|
||||
} else if (currentRow < 1) {
|
||||
currentRow = totalRow;
|
||||
}
|
||||
|
||||
$nextNode = findNextNode(currentRow, currentColumn);
|
||||
|
||||
if ($nextNode) {
|
||||
removeActiveClass($selectedNode);
|
||||
addActiveClass($nextNode);
|
||||
}
|
||||
}
|
||||
|
||||
function enterKeyHandler() {
|
||||
if (!$selectedNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
deferred.resolve(decodeURIComponent($selectedNode.find('button').attr('data-value')));
|
||||
$specialCharDialog.modal('hide');
|
||||
}
|
||||
|
||||
function keyDownEventHandler(event) {
|
||||
event.preventDefault();
|
||||
var keyCode = event.keyCode;
|
||||
if (keyCode === undefined || keyCode === null) {
|
||||
return;
|
||||
}
|
||||
// check arrowKeys match
|
||||
if (ARROW_KEYS.indexOf(keyCode) > -1) {
|
||||
if ($selectedNode === null) {
|
||||
addActiveClass($specialCharNode.eq(0));
|
||||
currentColumn = 1;
|
||||
currentRow = 1;
|
||||
return;
|
||||
}
|
||||
arrowKeyHandler(keyCode);
|
||||
} else if (keyCode === ENTER_KEY) {
|
||||
enterKeyHandler();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove class
|
||||
removeActiveClass($specialCharNode);
|
||||
|
||||
// find selected node
|
||||
if (text) {
|
||||
for (var i = 0; i < $specialCharNode.length; i++) {
|
||||
var $checkNode = $($specialCharNode[i]);
|
||||
if ($checkNode.text() === text) {
|
||||
addActiveClass($checkNode);
|
||||
currentRow = Math.ceil((i + 1) / COLUMN_LENGTH);
|
||||
currentColumn = (i + 1) % COLUMN_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui.onDialogShown(self.$dialog, function() {
|
||||
$(document).on('keydown', keyDownEventHandler);
|
||||
|
||||
self.$dialog.find('button').tooltip();
|
||||
|
||||
$specialCharNode.on('click', function(event) {
|
||||
event.preventDefault();
|
||||
deferred.resolve(decodeURIComponent($(event.currentTarget).find('button').attr('data-value')));
|
||||
ui.hideDialog(self.$dialog);
|
||||
});
|
||||
});
|
||||
|
||||
ui.onDialogHidden(self.$dialog, function() {
|
||||
$specialCharNode.off('click');
|
||||
|
||||
self.$dialog.find('button').tooltip('destroy');
|
||||
|
||||
$(document).off('keydown', keyDownEventHandler);
|
||||
|
||||
if (deferred.state() === 'pending') {
|
||||
deferred.reject();
|
||||
}
|
||||
});
|
||||
|
||||
ui.showDialog(self.$dialog);
|
||||
});
|
||||
};
|
||||
},
|
||||
});
|
||||
}));
|
||||
@@ -0,0 +1,182 @@
|
||||
/* https://github.com/DiemenDesign/summernote-cleaner */
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}
|
||||
(function ($) {
|
||||
$.extend(true, $.summernote.lang, {
|
||||
'en-US': {
|
||||
cleaner: {
|
||||
tooltip: 'Cleaner',
|
||||
not: 'Text has been Cleaned!!!',
|
||||
limitText: 'Text',
|
||||
limitHTML: 'HTML'
|
||||
}
|
||||
}
|
||||
});
|
||||
$.extend($.summernote.options, {
|
||||
cleaner: {
|
||||
action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
|
||||
newline: '<br>', // Summernote's default is to use '<p><br></p>'
|
||||
notStyle: 'position:absolute;top:0;left:0;right:0',
|
||||
icon: '<i class="note-icon"><svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 0 14 14" width="14" height="14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg></i>',
|
||||
keepHtml: true, //Remove all Html formats
|
||||
keepOnlyTags: [], // If keepHtml is true, remove all tags except these
|
||||
keepClasses: false, //Remove Classes
|
||||
badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'noscript', 'html'], //Remove full tags with contents
|
||||
badAttributes: ['style', 'start'], //Remove attributes from remaining tags
|
||||
limitChars: 0, // 0|# 0 disables option
|
||||
limitDisplay: 'both', // none|text|html|both
|
||||
limitStop: false // true/false
|
||||
}
|
||||
});
|
||||
$.extend($.summernote.plugins, {
|
||||
'cleaner': function (context) {
|
||||
var self = this,
|
||||
ui = $.summernote.ui,
|
||||
$note = context.layoutInfo.note,
|
||||
$editor = context.layoutInfo.editor,
|
||||
options = context.options,
|
||||
lang = options.langInfo;
|
||||
var cleanText = function (txt, nlO) {
|
||||
var out = txt;
|
||||
if (!options.cleaner.keepClasses) {
|
||||
var sS = /(\n|\r| class=(")?Mso[a-zA-Z]+(")?)/g;
|
||||
out = txt.replace(sS, ' ');
|
||||
}
|
||||
var nL = /(\n)+/g;
|
||||
out = out.replace(nL, nlO);
|
||||
if (options.cleaner.keepHtml) {
|
||||
var cS = new RegExp('<!--(.*?)-->', 'gi');
|
||||
out = out.replace(cS, '');
|
||||
var tS = new RegExp('<(/)*(meta|link|\\?xml:|st1:|o:|font)(.*?)>', 'gi');
|
||||
out = out.replace(tS, '');
|
||||
var bT = options.cleaner.badTags;
|
||||
for (var i = 0; i < bT.length; i++) {
|
||||
tS = new RegExp('<' + bT[i] + '\\b.*>.*</' + bT[i] + '>', 'gi');
|
||||
out = out.replace(tS, '');
|
||||
}
|
||||
var allowedTags = options.cleaner.keepOnlyTags;
|
||||
if (typeof(allowedTags) == "undefined") allowedTags = [];
|
||||
if (allowedTags.length > 0) {
|
||||
allowedTags = (((allowedTags||'') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
|
||||
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi;
|
||||
out = out.replace(tags, function($0, $1) {
|
||||
return allowedTags.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''
|
||||
});
|
||||
}
|
||||
var bA = options.cleaner.badAttributes;
|
||||
for (var ii = 0; ii < bA.length; ii++ ) {
|
||||
//var aS=new RegExp(' ('+bA[ii]+'="(.*?)")|('+bA[ii]+'=\'(.*?)\')', 'gi');
|
||||
var aS = new RegExp(' ' + bA[ii] + '=[\'|"](.*?)[\'|"]', 'gi');
|
||||
out = out.replace(aS, '');
|
||||
aS = new RegExp(' ' + bA[ii] + '[=0-9a-z]', 'gi');
|
||||
out = out.replace(aS, '');
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
if (options.cleaner.action == 'both' || options.cleaner.action == 'button') {
|
||||
context.memo('button.cleaner', function () {
|
||||
var button = ui.button({
|
||||
contents: options.cleaner.icon,
|
||||
tooltip: lang.cleaner.tooltip,
|
||||
container: 'body',
|
||||
click: function () {
|
||||
if ($note.summernote('createRange').toString())
|
||||
$note.summernote('pasteHTML', $note.summernote('createRange').toString());
|
||||
else
|
||||
$note.summernote('code', cleanText($note.summernote('code')));
|
||||
if ($editor.find('.note-status-output').length > 0)
|
||||
$editor.find('.note-status-output').html('<div class="alert alert-success">' + lang.cleaner.not + '</div>');
|
||||
}
|
||||
});
|
||||
return button.render();
|
||||
});
|
||||
}
|
||||
this.events = {
|
||||
'summernote.init': function () {
|
||||
if ($.summernote.interface === 'lite') {
|
||||
$("head").append('<style>.note-statusbar .pull-right{float:right!important}.note-status-output .text-muted{color:#777}.note-status-output .text-primary{color:#286090}.note-status-output .text-success{color:#3c763d}.note-status-output .text-info{color:#31708f}.note-status-output .text-warning{color:#8a6d3b}.note-status-output .text-danger{color:#a94442}.alert{margin:-7px 0 0 0;padding:7px 10px;border:1px solid transparent;border-radius:0}.alert .note-icon{margin-right:5px}.alert-success{color:#3c763d!important;background-color: #dff0d8 !important;border-color:#d6e9c6}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}</style>');
|
||||
}
|
||||
if (options.cleaner.limitChars != 0 || options.cleaner.limitDisplay != 'none') {
|
||||
var textLength = $editor.find(".note-editable").text().replace(/(<([^>]+)>)/ig, "").replace(/( )/, " ");
|
||||
var codeLength = $editor.find('.note-editable').html();
|
||||
var lengthStatus = '';
|
||||
if (textLength.length > options.cleaner.limitChars && options.cleaner.limitChars > 0)
|
||||
lengthStatus += 'text-danger">';
|
||||
else
|
||||
lengthStatus += '">';
|
||||
if (options.cleaner.limitDisplay == 'text' || options.cleaner.limitDisplay == 'both') lengthStatus += lang.cleaner.limitText + ': ' + textLength.length;
|
||||
if (options.cleaner.limitDisplay == 'both') lengthStatus += ' / ';
|
||||
if (options.cleaner.limitDisplay == 'html' || options.cleaner.limitDisplay == 'both') lengthStatus += lang.cleaner.limitHTML + ': ' + codeLength.length;
|
||||
$editor.find('.note-status-output').html('<small class="pull-right ' + lengthStatus + ' </small>');
|
||||
}
|
||||
},
|
||||
'summernote.keydown': function (we, e) {
|
||||
if (options.cleaner.limitChars != 0 || options.cleaner.limitDisplay != 'none') {
|
||||
var textLength = $editor.find(".note-editable").text().replace(/(<([^>]+)>)/ig, "").replace(/( )/, " ");
|
||||
var codeLength = $editor.find('.note-editable').html();
|
||||
var lengthStatus = '';
|
||||
if (options.cleaner.limitStop == true && textLength.length >= options.cleaner.limitChars) {
|
||||
var key = e.keyCode;
|
||||
allowed_keys = [8, 37, 38, 39, 40, 46]
|
||||
if ($.inArray(key, allowed_keys) != -1) {
|
||||
$editor.find('.cleanerLimit').removeClass('text-danger');
|
||||
return true;
|
||||
} else {
|
||||
$editor.find('.cleanerLimit').addClass('text-danger');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
} else {
|
||||
if (textLength.length > options.cleaner.limitChars && options.cleaner.limitChars > 0)
|
||||
lengthStatus += 'text-danger">';
|
||||
else
|
||||
lengthStatus += '">';
|
||||
if (options.cleaner.limitDisplay == 'text' || options.cleaner.limitDisplay == 'both')
|
||||
lengthStatus += lang.cleaner.limitText + ': ' + textLength.length;
|
||||
if (options.cleaner.limitDisplay == 'both')
|
||||
lengthStatus += ' / ';
|
||||
if (options.cleaner.limitDisplay == 'html' || options.cleaner.limitDisplay == 'both')
|
||||
lengthStatus += lang.cleaner.limitHTML + ': ' + codeLength.length;
|
||||
$editor.find('.note-status-output').html('<small class="cleanerLimit pull-right ' + lengthStatus + ' </small>');
|
||||
}
|
||||
}
|
||||
},
|
||||
'summernote.paste': function (we, e) {
|
||||
if (options.cleaner.action == 'both' || options.cleaner.action == 'paste') {
|
||||
e.preventDefault();
|
||||
var ua = window.navigator.userAgent;
|
||||
var msie = ua.indexOf("MSIE ");
|
||||
msie = msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./);
|
||||
var ffox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
||||
if (msie)
|
||||
var text = window.clipboardData.getData("text");
|
||||
else
|
||||
var text = e.originalEvent.clipboardData.getData(options.cleaner.keepHtml ? 'text/html' : 'text/plain');
|
||||
if(text==''){
|
||||
var clipboardData = (event.clipboardData || window.clipboardData);
|
||||
var text = clipboardData.getData('text');
|
||||
}
|
||||
if (text) {
|
||||
if (msie || ffox)
|
||||
setTimeout(function () {
|
||||
$note.summernote('pasteHTML', cleanText(text, options.cleaner.newline));
|
||||
}, 1);
|
||||
else
|
||||
$note.summernote('pasteHTML', cleanText(text, options.cleaner.newline));
|
||||
if ($editor.find('.note-status-output').length > 0)
|
||||
$editor.find('.note-status-output').html('<div class="summernote-cleanerAlert alert alert-success">' + lang.cleaner.not + '</div>');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
@@ -0,0 +1,143 @@
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
$.extend($.summernote.plugins, {
|
||||
'emoji': function (context) {
|
||||
var self = this;
|
||||
var ui = $.summernote.ui;
|
||||
var emojis = ['1', '2', '3', '4', '5','6'];
|
||||
|
||||
var chunk = function (val, chunkSize) {
|
||||
var R = [];
|
||||
for (var i = 0; i < val.length; i += chunkSize)
|
||||
R.push(val.slice(i, i + chunkSize));
|
||||
return R;
|
||||
};
|
||||
|
||||
/*IE polyfill*/
|
||||
if (!Array.prototype.filter) {
|
||||
Array.prototype.filter = function (fun /*, thisp*/) {
|
||||
var len = this.length >>> 0;
|
||||
if (typeof fun != "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = [];
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in this) {
|
||||
var val = this[i];
|
||||
if (fun.call(thisp, val, i, this))
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
var addListener = function () {
|
||||
$(document).on('click', '.closeEmoji', function(){
|
||||
$('#emoji-dropdown').modal('hide');
|
||||
});
|
||||
$(document).on('click', '.selectEmoji', function(){
|
||||
var img = new Image();
|
||||
img.src = '/plugins/pubs/summernote/plugin/emojis/'+$(this).attr('data-value')+'.png';
|
||||
img.alt = $(this).attr('data-value');
|
||||
img.className = 'emoji-icon-inline';
|
||||
context.invoke('editor.insertNode', img);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
var render = function (emojis) {
|
||||
var emoList = '';
|
||||
/*limit list to 24 images*/
|
||||
var emojis = emojis;
|
||||
var chunks = chunk(emojis, 6);
|
||||
for (j = 0; j < chunks.length; j++) {
|
||||
emoList += '<div class="row">';
|
||||
for (var i = 0; i < chunks[j].length; i++) {
|
||||
var emo = chunks[j][i];
|
||||
emoList += '<div class="col-xs-2">' +
|
||||
//'<a href="javascript:void(0)" class="selectEmoji closeEmoji" data-value="' + emo + '"><span class="emoji-icon" style="background-image: url(\'' + document.emojiSource + emo + '.png\');"></span></a>' +
|
||||
'<a href="javascript:void(0)" class="selectEmoji closeEmoji" data-value="' + emo + '"><img src="' + document.emojiSource + emo + '.png" class="emoji-icon" /></a>' +
|
||||
'</div>';
|
||||
}
|
||||
emoList += '</div>';
|
||||
}
|
||||
|
||||
return emoList;
|
||||
};
|
||||
|
||||
var filterEmoji = function (value) {
|
||||
var filtered = emojis.filter(function (el) {
|
||||
return el.indexOf(value) > -1;
|
||||
});
|
||||
return render(filtered);
|
||||
};
|
||||
|
||||
// add emoji button
|
||||
context.memo('button.emoji', function () {
|
||||
// create button
|
||||
var button = ui.button({
|
||||
contents: '<i class="bi bi-emoji-smile"></i>',
|
||||
//tooltip: 'emoji',
|
||||
click: function () {
|
||||
if(document.emojiSource === undefined)
|
||||
document.emojiSource = '';
|
||||
|
||||
//self.$panel.show();
|
||||
$('#emoji-dropdown').modal('show');
|
||||
}
|
||||
});
|
||||
|
||||
// create jQuery object from button instance.
|
||||
var $emoji = button.render();
|
||||
return $emoji;
|
||||
});
|
||||
|
||||
// This events will be attached when editor is initialized.
|
||||
this.events = {
|
||||
// This will be called after modules are initialized.
|
||||
'summernote.init': function (we, e) {
|
||||
addListener();
|
||||
},
|
||||
// This will be called when user releases a key on editable.
|
||||
'summernote.keyup': function (we, e) {
|
||||
}
|
||||
};
|
||||
|
||||
// This method will be called when editor is initialized by $('..').summernote();
|
||||
// You can create elements for plugin
|
||||
this.initialize = function () {
|
||||
|
||||
this.$panel = $('<div class="modal fade" role="dialog" id="emoji-dropdown">' +
|
||||
'<div class="modal-dialog">'+
|
||||
'<div class="modal-content">'+
|
||||
'<div class="modal-header">插入表情'+
|
||||
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'+
|
||||
'</div>'+
|
||||
'<div class="modal-body">'+
|
||||
'<div class="emoji-list">' +
|
||||
render(emojis) +
|
||||
'</div>' +
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'</div>').hide();
|
||||
|
||||
this.$panel.appendTo('body');
|
||||
};
|
||||
|
||||
this.destroy = function () {
|
||||
this.$panel.remove();
|
||||
this.$panel = null;
|
||||
};
|
||||
}
|
||||
});
|
||||
}));
|
||||
@@ -0,0 +1,197 @@
|
||||
/*!
|
||||
* summernote highlight plugin
|
||||
* http://www.hyl.pw/
|
||||
*
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function (factory) {
|
||||
/* global define */
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals: jQuery
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
// Extends plugins for adding highlight.
|
||||
// - plugin is external module for customizing.
|
||||
$.extend($.summernote.plugins, {
|
||||
|
||||
/**
|
||||
* @param {Object} context - context object has status of editor.
|
||||
*/
|
||||
'highlight': function (context) {
|
||||
|
||||
var self = this;
|
||||
|
||||
var ui = $.summernote.ui;
|
||||
var $editor = context.layoutInfo.editor;
|
||||
var options = context.options;
|
||||
var lang = options.langInfo;
|
||||
|
||||
// add button
|
||||
|
||||
context.memo('button.highlight', function () {
|
||||
// create button
|
||||
var button = ui.button({
|
||||
contents: '<i class="bi bi-code"></i>',
|
||||
tooltip: 'highlight',
|
||||
click: function () {
|
||||
self.show()
|
||||
}
|
||||
});
|
||||
|
||||
// create jQuery object from button instance.
|
||||
var $highlight = button.render();
|
||||
return $highlight;
|
||||
});
|
||||
|
||||
this.createDialog = function () {
|
||||
|
||||
var $box = $('<div />');
|
||||
var $selectGroup = $('<div class="form-group" />');
|
||||
var $textGroup = $('<div class="form-group" />');
|
||||
var $select = $('<select class="form-control ext-highlight-select" />');
|
||||
|
||||
var languages = [
|
||||
'bsh', 'c', 'cc', 'cpp', 'cs', 'csh', 'cyc', 'cv', 'htm', 'html',
|
||||
'java', 'js', 'm', 'mxml', 'perl', 'pl', 'pm', 'py', 'php', 'rb',
|
||||
'sh', 'xhtml', 'xml', 'xsl'
|
||||
];
|
||||
|
||||
for (var i = 0; i < languages.length; i++) {
|
||||
$select.append('<option value="' + languages[i] + '">' + languages[i] + '</option>');
|
||||
}
|
||||
|
||||
var $label = $('<label />');
|
||||
$label.html('选择语言');
|
||||
$box.append($selectGroup.append($label));
|
||||
$box.append($selectGroup.append($select));
|
||||
|
||||
var $label = $('<label />');
|
||||
$label.html('输入代码片段');
|
||||
var $textarea = $('<textarea class="ext-highlight-code form-control" rows="10" />');
|
||||
|
||||
$box.append($textGroup.append($label));
|
||||
$box.append($textGroup.append($textarea));
|
||||
|
||||
return $box.html();
|
||||
};
|
||||
|
||||
this.createCodeNode = function (code, select) {
|
||||
var $code = $('<code>');
|
||||
$code.html(code);
|
||||
$code.addClass('language-' + select);
|
||||
|
||||
var $pre = $('<pre>');
|
||||
$pre.html($code)
|
||||
$pre.addClass('prettyprint').addClass('linenums');
|
||||
|
||||
return $pre[0];
|
||||
};
|
||||
|
||||
this.showHighlightDialog = function (codeInfo) {
|
||||
return $.Deferred(function (deferred) {
|
||||
var $extHighlightCode = self.$dialog.find('.ext-highlight-code');
|
||||
var $extHighlightBtn = self.$dialog.find('.ext-highlight-btn');
|
||||
var $extHighlightSelect = self.$dialog.find('.ext-highlight-select');
|
||||
|
||||
ui.onDialogShown(self.$dialog, function () {
|
||||
|
||||
$extHighlightCode.val(codeInfo);
|
||||
|
||||
$extHighlightCode.on('input', function () {
|
||||
ui.toggleBtn($extHighlightBtn, $extHighlightCode.val() != '');
|
||||
codeInfo = $extHighlightCode.val();
|
||||
});
|
||||
|
||||
$extHighlightBtn.one('click', function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
deferred.resolve(self.createCodeNode($extHighlightCode.val(), $extHighlightSelect.val()));
|
||||
|
||||
ui.hideDialog(self.$dialog);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
ui.onDialogHidden(self.$dialog, function () {
|
||||
$extHighlightBtn.off('click');
|
||||
if (deferred.state() === 'pending') {
|
||||
deferred.reject();
|
||||
}
|
||||
});
|
||||
|
||||
ui.showDialog(self.$dialog);
|
||||
});
|
||||
};
|
||||
|
||||
this.getCodeInfo = function () {
|
||||
var text = context.invoke('editor.getSelectedText');
|
||||
return '';
|
||||
};
|
||||
|
||||
this.show = function () {
|
||||
var codeInfo = self.getCodeInfo();
|
||||
context.invoke('editor.saveRange');
|
||||
this.showHighlightDialog(codeInfo).then(function (codeInfo) {
|
||||
self.$dialog.modal('hide');
|
||||
context.invoke('editor.restoreRange');
|
||||
|
||||
if (codeInfo) {
|
||||
context.invoke('editor.insertNode', codeInfo);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//// This events will be attached when editor is initialized.
|
||||
//this.event = {
|
||||
// // This will be called after modules are initialized.
|
||||
// 'summernote.init': function (we, e) {
|
||||
// console.log('summernote initialized', we, e);
|
||||
// },
|
||||
// // This will be called when user releases a key on editable.
|
||||
// 'summernote.keyup': function (we, e) {
|
||||
// console.log('summernote keyup', we, e);
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//// This method will be called when editor is initialized by $('..').summernote();
|
||||
//// You can create elements for plugin
|
||||
this.initialize = function () {
|
||||
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
||||
|
||||
var body = [
|
||||
'<button href="#" class="btn btn-primary ext-highlight-btn disabled" disabled>',
|
||||
'插入代码',
|
||||
'</button>'
|
||||
].join('');
|
||||
|
||||
this.$dialog = ui.dialog({
|
||||
className: 'ext-highlight',
|
||||
title: '插入代码',
|
||||
body: this.createDialog(),
|
||||
footer: body,
|
||||
//callback: function ($node) {
|
||||
// $node.find('.modal-body').css({
|
||||
// 'max-height': 300,
|
||||
// 'overflow': 'scroll'
|
||||
// });
|
||||
//}
|
||||
}).render().appendTo($container);
|
||||
};
|
||||
|
||||
// This methods will be called when editor is destroyed by $('..').summernote('destroy');
|
||||
// You should remove elements on `initialize`.
|
||||
this.destroy = function () {
|
||||
ui.hideDialog(this.$dialog);
|
||||
this.$dialog.remove();
|
||||
};
|
||||
}
|
||||
});
|
||||
}));
|
||||
@@ -0,0 +1,118 @@
|
||||
(function (factory) {
|
||||
/* global define */
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals: jQuery
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
$.extend($.summernote.plugins, {
|
||||
|
||||
'ts_video': function (context) {
|
||||
var self = this;
|
||||
|
||||
var ui = $.summernote.ui;
|
||||
var $editor = context.layoutInfo.editor;
|
||||
var options = context.options;
|
||||
var lang = options.langInfo;
|
||||
|
||||
|
||||
context.memo('button.ts_video', function () {
|
||||
|
||||
var button = ui.button({
|
||||
contents: '<i class="fab fa-youtube"></i>',
|
||||
tooltip: 'ts_video',
|
||||
click: function () {
|
||||
self.show()
|
||||
}
|
||||
});
|
||||
|
||||
// create jQuery object from button instance.
|
||||
var $highlight = button.render();
|
||||
return $highlight;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
this.createDialog = function () {
|
||||
|
||||
var $box = $('<div />');
|
||||
var $frame = $('<iframe width="100%" height="444" frameborder="0" scrolling="no" src="'+siteUrl+'index.php?app=video&ac=editor&ts=list" />');
|
||||
$box.append($frame);
|
||||
return $box.html();
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.showAttachDialog = function () {
|
||||
return $.Deferred(function () {
|
||||
ui.onDialogShown(self.$dialog, function () {
|
||||
|
||||
});
|
||||
|
||||
ui.onDialogHidden(self.$dialog, function () {
|
||||
|
||||
});
|
||||
|
||||
ui.showDialog(self.$dialog);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.show = function () {
|
||||
|
||||
|
||||
this.showAttachDialog().then(function () {
|
||||
self.$dialog.modal('hide');
|
||||
context.invoke('editor.restoreRange');
|
||||
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.initialize = function () {
|
||||
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
||||
|
||||
var body = [''].join('');
|
||||
|
||||
this.$dialog = ui.dialog({
|
||||
className: 'ts-video',
|
||||
title: '我的视频',
|
||||
body: this.createDialog(),
|
||||
footer: body,
|
||||
//callback: function ($node) {
|
||||
// $node.find('.modal-body').css({
|
||||
// 'max-height': 300,
|
||||
// 'overflow': 'scroll'
|
||||
// });
|
||||
//}
|
||||
}).render().appendTo($container);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
this.destroy = function () {
|
||||
ui.hideDialog(this.$dialog);
|
||||
this.$dialog.remove();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}))
|
||||
Reference in New Issue
Block a user