Skip to content

Commit

Permalink
Merge pull request #1758 from bluecat76/develop
Browse files Browse the repository at this point in the history
make Dom accessible in Context for plugins
  • Loading branch information
hackerwins committed Apr 10, 2016
2 parents f46a18d + 8069765 commit a120ac7
Show file tree
Hide file tree
Showing 7 changed files with 355 additions and 12 deletions.
27 changes: 22 additions & 5 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ module.exports = function (grunt) {
},

jscs: {
src: ['*.js', 'src/**/*.js', 'test/**/*.js'],
src: ['*.js', 'src/**/*.js', 'test/**/*.js', 'plugin/**/*.js'],
gruntfile: 'Gruntfile.js',
build: 'build'
},
Expand All @@ -126,6 +126,13 @@ module.exports = function (grunt) {
src: '**/*.js',
dest: 'dist/lang',
ext: '.min.js'
},
{
expand: true,
cwd: 'dist/plugin',
src: '**/*.js',
dest: 'dist/plugin',
ext: '.min.js'
}
]
}
Expand All @@ -135,9 +142,18 @@ module.exports = function (grunt) {
recess: {
dist: {
options: { compile: true, compress: true },
files: {
'dist/summernote.css': ['src/less/summernote.less']
}
files: [
{
'dist/summernote.css': ['src/less/summernote.less']
},
{
expand: true,
cwd: 'dist/plugin',
src: '**/*.css',
dest: 'dist/plugin',
ext: '.min.css'
}
]
}
},

Expand All @@ -160,7 +176,7 @@ module.exports = function (grunt) {
'dist/font/*'
]
}, {
src: ['plugin/**/*.js', 'lang/**/*.js'],
src: ['plugin/**/*.js', 'plugin/**/*.css', 'lang/**/*.js'],
dest: 'dist/'
}]
}
Expand Down Expand Up @@ -245,6 +261,7 @@ module.exports = function (grunt) {
dist: {
files: [
{ src: 'lang/*', dest: 'dist/' },
{ src: 'plugin/**/*', dest: 'dist/' },
{ expand: true, cwd: 'src/icons/dist/font/', src: ['**', '!*.html'], dest: 'dist/font/' },
{ src: 'src/icons/dist/summernote.css', dest: 'src/icons/dist/summernote.less' }
]
Expand Down
16 changes: 16 additions & 0 deletions plugin/databasic/summernote-ext-databasic.css
Original file line number Diff line number Diff line change
@@ -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;
}
303 changes: 303 additions & 0 deletions plugin/databasic/summernote-ext-databasic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
(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
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'
}
}
}

});

}));

0 comments on commit a120ac7

Please sign in to comment.