|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- (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"></i>';
-
- // 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',
- },
- },
- },
-
- });
- }));
|