mirror of https://github.com/artf/grapesjs.git
7 changed files with 10 additions and 402 deletions
@ -1,21 +0,0 @@ |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.Model.extend({ |
|||
|
|||
idAttribute: 'command', |
|||
|
|||
defaults: { |
|||
command: '', |
|||
type: '', |
|||
title: '', |
|||
class: '', |
|||
options: [], |
|||
}, |
|||
|
|||
initialize() { |
|||
var opts = this.get('options'); |
|||
if(opts.length) |
|||
this.set('type', 'select'); |
|||
}, |
|||
|
|||
}); |
|||
@ -1,6 +0,0 @@ |
|||
var Backbone = require('backbone'); |
|||
var CommandButton = require('./CommandButton'); |
|||
|
|||
module.exports = Backbone.Collection.extend({ |
|||
model: CommandButton, |
|||
}); |
|||
@ -1,42 +0,0 @@ |
|||
const CommandButtonView = require('./CommandButtonView'); |
|||
const $ = Backbone.$; |
|||
|
|||
module.exports = CommandButtonView.extend({ |
|||
|
|||
initialize(o, config) { |
|||
CommandButtonView.prototype.initialize.apply(this, arguments); |
|||
}, |
|||
|
|||
getInput() { |
|||
var m = this.model; |
|||
if(!this.input){ |
|||
var cmd = m.get('command'); |
|||
var input = '<select data-edit="' + cmd +'">'; |
|||
var opts = m.get('options'); |
|||
var label = m.get('title') || m.get('command'); |
|||
input += '<option>' + label + '</option>'; |
|||
for(var i = 0, len = opts.length; i < len; i++){ |
|||
var opt = opts[i]; |
|||
var value = opt.value; |
|||
var name = opt.name || value; |
|||
input += '<option value="' + value + '">' + name + '</option>'; |
|||
} |
|||
input += '</select>'; |
|||
this.input = $(input); |
|||
} |
|||
return this.input; |
|||
}, |
|||
|
|||
getInputCont() { |
|||
var input = this.getInput(); |
|||
var pfx = this.ppfx; |
|||
var cont = $('<div class="'+pfx+'field '+pfx+'select"><div class="'+pfx+'sel-arrow"><div class="'+pfx+'d-s-arrow"></div></div></div>'); |
|||
return cont.append(input); |
|||
}, |
|||
|
|||
render(...args) { |
|||
CommandButtonView.prototype.render.apply(this, args); |
|||
this.$el.html(this.getInputCont()); |
|||
return this; |
|||
} |
|||
}); |
|||
@ -1,16 +0,0 @@ |
|||
var Backbone = require('backbone'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
tagName: 'a', |
|||
|
|||
initialize(o, config) { |
|||
this.config = config || {}; |
|||
this.ppfx = this.config.pStylePrefix || ''; |
|||
this.className = this.config.stylePrefix + 'btn ' + this.model.get('class'); |
|||
}, |
|||
|
|||
render() { |
|||
this.$el.addClass(this.className); |
|||
return this; |
|||
} |
|||
}); |
|||
@ -1,76 +0,0 @@ |
|||
var Backbone = require('backbone'); |
|||
var CommandButtonView = require('./CommandButtonView'); |
|||
var CommandButtonSelectView = require('./CommandButtonSelectView'); |
|||
|
|||
module.exports = Backbone.View.extend({ |
|||
|
|||
attributes : { |
|||
'data-role': 'editor-toolbar', |
|||
}, |
|||
|
|||
initialize(o) { |
|||
this.config = o.config || {}; |
|||
var pfx = this.config.stylePrefix || ''; |
|||
this.id = pfx + this.config.toolbarId; |
|||
this.listenTo(this.collection, 'add', this.addTo); |
|||
this.$el.data('helper', 1); |
|||
}, |
|||
|
|||
/** |
|||
* Add new model to the collection |
|||
* @param {Model} model |
|||
* @private |
|||
* */ |
|||
addTo(model) { |
|||
this.add(model); |
|||
}, |
|||
|
|||
/** |
|||
* Render new model inside the view |
|||
* @param {Model} model |
|||
* @param {Object} fragment Fragment collection |
|||
* @private |
|||
* */ |
|||
add(model, fragment) { |
|||
var frag = fragment || null; |
|||
var viewObj = CommandButtonView; |
|||
|
|||
switch (model.get('type')) { |
|||
case 'select': |
|||
viewObj = CommandButtonSelectView; |
|||
break; |
|||
} |
|||
var args = model.get('args'); |
|||
var attrs = { |
|||
'title': model.get('title'), |
|||
'data-edit': model.get('command'), |
|||
}; |
|||
if(args) |
|||
attrs['data-args'] = args; |
|||
var view = new viewObj({ |
|||
model, |
|||
attributes: attrs, |
|||
}, this.config); |
|||
|
|||
var rendered = view.render().el; |
|||
|
|||
if(frag) |
|||
frag.appendChild(rendered); |
|||
else |
|||
this.$el.append(rendered); |
|||
}, |
|||
|
|||
render() { |
|||
var frag = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.add(model, frag); |
|||
}, this); |
|||
|
|||
this.$el.append(frag); |
|||
this.$el.attr('id', this.id ); |
|||
return this; |
|||
} |
|||
|
|||
}); |
|||
@ -1,234 +0,0 @@ |
|||
const Backbone = require('backbone'); |
|||
const $ = Backbone.$; |
|||
|
|||
var readFileIntoDataUrl = fileInfo => { |
|||
var loader = $.Deferred(), |
|||
fReader = new FileReader(); |
|||
fReader.onload = e => { |
|||
loader.resolve(e.target.result); |
|||
}; |
|||
fReader.onerror = loader.reject; |
|||
fReader.onprogress = loader.notify; |
|||
fReader.readAsDataURL(fileInfo); |
|||
return loader.promise(); |
|||
}; |
|||
$.fn.cleanHtml = function () { |
|||
var html = $(this).html(); |
|||
return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, ''); |
|||
}; |
|||
$.fn.wysiwyg = function (userOptions) { |
|||
var editor = this, |
|||
selectedRange, |
|||
options, |
|||
toolbarBtnSelector, |
|||
updateToolbar = () => { |
|||
var actCls = options.activeToolbarClass; |
|||
if (actCls) { |
|||
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () { |
|||
var el = $(this); |
|||
var command = el.data(options.commandRole); |
|||
var doc = editor.get(0).ownerDocument; |
|||
if (doc.queryCommandState(command)) { |
|||
el.addClass(actCls); |
|||
} else { |
|||
el.removeClass(actCls); |
|||
} |
|||
}); |
|||
} |
|||
}, |
|||
execCommand = (commandWithArgs, valueArg) => { |
|||
var commandArr = commandWithArgs.split(' '), |
|||
command = commandArr.shift(), |
|||
args = commandArr.join(' ') + (valueArg || ''); |
|||
//document.execCommand("insertHTML", false, "<span class='own-class'>"+ document.getSelection()+"</span>");
|
|||
editor.get(0).ownerDocument.execCommand("styleWithCSS", false, true); |
|||
editor.get(0).ownerDocument.execCommand(command, 0, args); |
|||
updateToolbar(); |
|||
editor.trigger('change'); |
|||
}, |
|||
/* |
|||
bindHotkeys = function (hotKeys) { |
|||
$.each(hotKeys, function (hotkey, command) { |
|||
editor.keydown(hotkey, function (e) { |
|||
if (editor.attr('contenteditable') && editor.is(':visible')) { |
|||
e.preventDefault(); |
|||
e.stopPropagation(); |
|||
execCommand(command); |
|||
} |
|||
}).keyup(hotkey, function (e) { |
|||
if (editor.attr('contenteditable') && editor.is(':visible')) { |
|||
e.preventDefault(); |
|||
e.stopPropagation(); |
|||
} |
|||
}); |
|||
}); |
|||
}, |
|||
*/ |
|||
getCurrentRange = () => { |
|||
var sel = window.getSelection(); |
|||
if (sel.getRangeAt && sel.rangeCount) { |
|||
return sel.getRangeAt(0); |
|||
} |
|||
}, |
|||
saveSelection = () => { |
|||
selectedRange = getCurrentRange(); |
|||
}, |
|||
restoreSelection = () => { |
|||
var selection = window.getSelection(); |
|||
if (selectedRange) { |
|||
try { |
|||
selection.removeAllRanges(); |
|||
} catch (ex) { |
|||
document.body.createTextRange().select(); |
|||
document.selection.empty(); |
|||
} |
|||
|
|||
selection.addRange(selectedRange); |
|||
} |
|||
}, |
|||
insertFiles = files => { |
|||
editor.focus(); |
|||
$.each(files, (idx, fileInfo) => { |
|||
if (/^image\//.test(fileInfo.type)) { |
|||
$.when(readFileIntoDataUrl(fileInfo)).done(dataUrl => { |
|||
execCommand('insertimage', dataUrl); |
|||
}).fail(e => { |
|||
options.fileUploadError("file-reader", e); |
|||
}); |
|||
} else { |
|||
options.fileUploadError("unsupported-file-type", fileInfo.type); |
|||
} |
|||
}); |
|||
}, |
|||
markSelection = (input, color) => { |
|||
restoreSelection(); |
|||
if (document.queryCommandSupported('hiliteColor')) { |
|||
document.execCommand('hiliteColor', 0, color || 'transparent'); |
|||
} |
|||
saveSelection(); |
|||
input.data(options.selectionMarker, color); |
|||
}, |
|||
bindToolbar = (toolbar, options) => { |
|||
toolbar.find(toolbarBtnSelector).off('click').on('click',function () { |
|||
restoreSelection(); |
|||
//editor.focus(); // cause defocus on selects
|
|||
var doc = editor.get(0).ownerDocument; |
|||
var el = $(this); |
|||
var comm = el.data(options.commandRole); |
|||
var args = el.data('args'); |
|||
if(args){ |
|||
args = args.replace('${content}', doc.getSelection()); |
|||
execCommand(comm, args); |
|||
}else{ |
|||
doc.execCommand(comm); |
|||
} |
|||
saveSelection(); |
|||
}); |
|||
toolbar.find('[data-toggle=dropdown]').on('click', restoreSelection); |
|||
var dName = '[data-' + options.commandRole + ']'; |
|||
toolbar.find('select'+dName).on('webkitspeechchange change', function(){ |
|||
var newValue = this.value; |
|||
restoreSelection(); |
|||
if (newValue) { |
|||
editor.focus(); |
|||
execCommand($(this).data(options.commandRole), newValue); |
|||
} |
|||
saveSelection(); |
|||
}); |
|||
toolbar.find('input[type=text]'+dName,', select'+dName).on('webkitspeechchange change', function () { |
|||
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */ |
|||
this.value = ''; |
|||
restoreSelection(); |
|||
if (newValue) { |
|||
editor.focus(); |
|||
execCommand($(this).data(options.commandRole), newValue); |
|||
} |
|||
saveSelection(); |
|||
}).on('focus', function () { |
|||
var input = $(this); |
|||
if (!input.data(options.selectionMarker)) { |
|||
markSelection(input, options.selectionColor); |
|||
input.focus(); |
|||
} |
|||
}).on('blur', function () { |
|||
var input = $(this); |
|||
if (input.data(options.selectionMarker)) { |
|||
markSelection(input, false); |
|||
} |
|||
}); |
|||
toolbar.find('input[type=file][data-' + options.commandRole + ']').on('change', function () { |
|||
restoreSelection(); |
|||
if (this.type === 'file' && this.files && this.files.length > 0) { |
|||
insertFiles(this.files); |
|||
} |
|||
saveSelection(); |
|||
this.value = ''; |
|||
}); |
|||
}, |
|||
initFileDrops = () => { |
|||
editor.on('dragenter dragover', false) |
|||
.on('drop', e => { |
|||
var dataTransfer = e.originalEvent.dataTransfer; |
|||
e.stopPropagation(); |
|||
e.preventDefault(); |
|||
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) { |
|||
insertFiles(dataTransfer.files); |
|||
} |
|||
}); |
|||
}; |
|||
/** Disable the editor |
|||
* @date 2015-03-19 */ |
|||
if(typeof userOptions=='string' && userOptions=='destroy'){ |
|||
editor.attr('contenteditable', false).off('mouseup keyup mouseout dragenter dragover'); |
|||
$(window).off('touchend'); |
|||
return this; |
|||
} |
|||
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions); |
|||
var dName = '[data-' + options.commandRole + ']'; |
|||
toolbarBtnSelector = 'a'+dName+',button'+dName+',input[type=button]'+dName+', select'+dName; |
|||
//bindHotkeys(options.hotKeys);
|
|||
if (options.dragAndDropImages) { |
|||
initFileDrops(); |
|||
} |
|||
bindToolbar($(options.toolbarSelector), options); |
|||
editor.attr('contenteditable', true).on('mouseup keyup mouseout', () => { |
|||
saveSelection(); |
|||
updateToolbar(); |
|||
}); |
|||
$(window).on('touchend', e => { |
|||
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0), |
|||
currentRange = getCurrentRange(), |
|||
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset); |
|||
if (!clear || isInside) { |
|||
saveSelection(); |
|||
updateToolbar(); |
|||
} |
|||
}); |
|||
return this; |
|||
}; |
|||
$.fn.wysiwyg.defaults = { |
|||
/* |
|||
hotKeys: { |
|||
'ctrl+b meta+b': 'bold', |
|||
'ctrl+i meta+i': 'italic', |
|||
'ctrl+u meta+u': 'underline', |
|||
'ctrl+z meta+z': 'undo', |
|||
'ctrl+y meta+y meta+shift+z': 'redo', |
|||
'ctrl+l meta+l': 'justifyleft', |
|||
'ctrl+r meta+r': 'justifyright', |
|||
'ctrl+e meta+e': 'justifycenter', |
|||
'ctrl+j meta+j': 'justifyfull', |
|||
'shift+tab': 'outdent', |
|||
'tab': 'indent' |
|||
}, |
|||
*/ |
|||
toolbarSelector: '[data-role=editor-toolbar]', |
|||
commandRole: 'edit', |
|||
activeToolbarClass: 'btn-info', |
|||
selectionMarker: 'edit-focus-marker', |
|||
selectionColor: 'darkgrey', |
|||
dragAndDropImages: true, |
|||
fileUploadError(reason, detail) { console.log("File upload error", reason, detail); } |
|||
}; |
|||
|
|||
module.exports = $; |
|||
Loading…
Reference in new issue