quote improved

This commit is contained in:
khaydarov 2017-01-26 03:59:41 +03:00
parent 4864122d39
commit cc49b8fa2c
5 changed files with 2651 additions and 2109 deletions

File diff suppressed because one or more lines are too long

View file

@ -121,16 +121,18 @@
quote_styled: {
type: 'quote_styled',
iconClassname: 'ce-icon-quote',
make: quote.makeBlockToAppend,
appendCallback: null,
settings: quote.makeSettings,
makeSettings: quote.makeSettings,
prepare: quote.prepare,
render: quote.render,
validate: quote.validate,
save: quote.save,
displayInToolbox: true,
enableLineBreaks: true,
showInlineToolbar: true,
allowedToPaste: true
allowedToPaste: true,
config : {
defaultStyle : 'withPhoto'
}
},
image: {
type: 'image',

View file

@ -4,12 +4,12 @@
cursor: pointer;
line-height: 1.3em;
}
.ce_plugin_quote--select_button:not(:last-of-type){
.ce_plugin_quote--select_button:not(:last-of-type){
margin-bottom: 1.5em;
}
.ce_plugin_quote--select_button:hover{
}
.ce_plugin_quote--select_button:hover{
color: #a1b4ec;
}
}
/** Quote Styles */
@ -19,9 +19,12 @@
}
.quoteStyle-withCaption--author {
margin: 0 100px 2em !important;
margin: 5px 0;
background: #fff;
border: 1px solid #ebeef3;
padding: 7px;
text-align: right;
font-size: 1.16em;
font-size: 1em;
font-weight: bold;
color: #000;
line-height: 1.5em;
@ -43,6 +46,8 @@
.quoteStyle-withCaption--blockquote {
margin: 0;
padding: 1.5em 2.0em !important;
border: 1px solid #ebeef3;
background: #fff;
}
.quoteStyle-withCaption--blockquote:focus,
@ -106,23 +111,23 @@
border: 1px solid #ebeef3;
background: #fff;
}
.quoteStyle-withPhoto--photo:hover {
.quoteStyle-withPhoto--photo:hover {
cursor: pointer;
background: #F0F3F6;
}
}
.quoteStyle-withPhoto--photo:hover::after {
.quoteStyle-withPhoto--photo:hover::after {
display: block;
}
}
.authorsPhoto {
.authorsPhoto {
height: 110%;
vertical-align: top;
}
}
.authorsPhoto-wrapper {
.authorsPhoto-wrapper {
border: 0 !important;
}
}
.quoteStyle-withPhoto--photo .ce-icon-picture {
font-family: "codex_editor";
@ -173,8 +178,6 @@
*/
.ce-quote{
padding: 1em 0;
border: 0;
margin: 0;
}
.quoteStyle-withPhoto--author,
.quoteStyle-withPhoto--job,
@ -187,9 +190,10 @@
.quoteStyle-withPhoto--quote{
min-height: 200px;
}
/**
* Current select-type button
*/
* Current select-type button
*/
.ce-quote-settings--selected{
font-weight: bold;
}

View file

@ -0,0 +1,536 @@
/**
*
* Quote plugin
*/
var quote = (function(quote) {
/**
* @private
*
* CSS styles
*/
var elementClasses_ = {
ce_quote : 'ce-quote',
quoteText : 'ce_quote--text',
quoteAuthor : 'ce_quote--author',
authorsJob : 'ce_quote--job',
authorsPhoto : 'authorsPhoto',
authorsPhotoWrapper : 'authorsPhoto-wrapper',
simple : {
text : 'quoteStyle-simple--text'
},
withCaption : {
blockquote : 'quoteStyle-withCaption--blockquote',
author : 'quoteStyle-withCaption--author'
},
withPhoto : {
photo : 'quoteStyle-withPhoto--photo',
author : 'quoteStyle-withPhoto--author',
job : 'quoteStyle-withPhoto--job',
quote : 'quoteStyle-withPhoto--quote',
wrapper : 'quoteStyle-withPhoto--wrapper',
authorHolder : 'quoteStyle-withPhoto--authorWrapper'
},
settings : {
holder : 'ce_plugin_quote--settings',
caption : 'ce_plugin_quote--caption',
buttons : 'ce_plugin_quote--select_button',
selectedType : 'ce-quote-settings--selected'
}
};
/**
* @private
*
*
*/
var methods_ = {
changeStyleClicked : function() {
var changeStyleButton = this,
quote = codex.content.currentNode.querySelector('.' + elementClasses_.ce_quote),
newStyle = changeStyleButton.dataset.style,
styleSelectors = this.parentNode.childNodes;
quote.dataset.quoteStyle = newStyle;
/**
* Mark selected style button
*/
for (var i = styleSelectors.length - 1; i >= 0; i--) {
styleSelectors[i].classList.remove(elementClasses_.settings.selectedType);
}
this.classList.add(elementClasses_.settings.selectedType);
},
/**
* @deprecated
*/
selectTypeQuoteStyle : function(type) {
var quoteStyleFunction;
/**
* Choose Quote style to replace
*/
switch (type) {
case 'simple':
quoteStyleFunction = methods_.makeSimpleQuote;
break;
case 'withCaption':
quoteStyleFunction = methods_.makeQuoteWithCaption;
break;
case 'withPhoto':
quoteStyleFunction = methods_.makeQuoteWithPhoto;
break;
}
return quoteStyleFunction;
},
/**
* @deprecated
*/
addSelectTypeClickListener : function(el, quoteStyle) {
el.addEventListener('click', function () {
/**
* Parsing currentNode to JSON.
*/
var parsedOldQuote = methods_.parseBlockQuote(),
newStyledQuote = quoteStyle(parsedOldQuote);
var wrapper = codex.content.composeNewBlock(newStyledQuote, 'quote');
wrapper.appendChild(newStyledQuote);
codex.content.switchBlock(codex.content.currentNode, newStyledQuote, 'quote');
/** Close settings after replacing */
codex.toolbar.settings.close();
}, false);
},
/**
* @deprecated
*/
makeSimpleQuote : function(data) {
var wrapper = ui_.makeBlock('BLOCKQUOTE', [elementClasses_.simple.text, elementClasses_.quoteText]);
wrapper.innerHTML = data.text || '';
wrapper.dataset.quoteStyle = 'simple';
wrapper.classList.add(elementClasses_.ce_quote);
wrapper.contentEditable = 'true';
return wrapper;
},
/**
* @deprecated
*/
makeQuoteWithCaption : function(data) {
var wrapper = ui_.blockquote(),
text = ui_.makeBlock('DIV', [elementClasses_.withCaption.blockquote, elementClasses_.quoteText]),
author = ui_.makeBlock('DIV', [elementClasses_.withCaption.author, elementClasses_.quoteAuthor]);
/* make text block ontentEditable */
text.contentEditable = 'true';
text.innerHTML = data.text;
/* make Author contentEditable */
author.contentEditable = 'true';
author.textContent = data.cite;
/* Appending created components */
wrapper.dataset.quoteStyle = 'withCaption';
wrapper.classList.add(elementClasses_.ce_quote);
wrapper.appendChild(text);
wrapper.appendChild(author);
return wrapper;
},
makeQuoteWithPhoto : function(data) {
var wrapper = ui_.blockquote(),
photo = ui_.makeBlock('DIV', [elementClasses_.withPhoto.photo]),
author = ui_.makeBlock('DIV', [elementClasses_.withPhoto.author, elementClasses_.quoteAuthor]),
job = ui_.makeBlock('DIV', [elementClasses_.withPhoto.job, elementClasses_.authorsJob]),
quote = ui_.makeBlock('DIV', [elementClasses_.withPhoto.quote, elementClasses_.quoteText]);
/* Default Image src */
if (!data.image) {
var icon = ui_.makeBlock('SPAN', ['ce-icon-picture']);
photo.appendChild(icon);
} else {
var authorsPhoto = ui_.img(elementClasses_.authorsPhoto);
authorsPhoto.src = data.image;
authorsPhoto.dataset.bigUrl = data.image;
photo.classList.add(elementClasses_.authorsPhotoWrapper);
photo.appendChild(authorsPhoto);
}
photo.addEventListener('click', fileUploadClicked_, false);
/* make author block contentEditable */
author.contentEditable = 'true';
author.textContent = data.cite;
/* Author's position and job */
job.contentEditable = 'true';
job.textContent = data.caption;
var authorsWrapper = ui_.makeBlock('DIV', [elementClasses_.withPhoto.authorHolder]);
authorsWrapper.appendChild(author);
authorsWrapper.appendChild(job);
/* make quote text contentEditable */
quote.contentEditable = 'true';
quote.innerHTML = data.text;
wrapper.classList.add(elementClasses_.ce_quote);
wrapper.classList.add(elementClasses_.withPhoto.wrapper);
wrapper.dataset.quoteStyle = 'withPhoto';
wrapper.appendChild(quote);
wrapper.appendChild(photo);
wrapper.appendChild(authorsWrapper);
return wrapper;
},
parseBlockQuote : function(block) {
var currentNode = block || codex.content.currentNode,
photo = currentNode.getElementsByTagName('img')[0],
author = currentNode.querySelector('.' + elementClasses_.quoteAuthor),
job = currentNode.querySelector('.' + elementClasses_.authorsJob),
quote ;
/** Simple quote text placed in Blockquote tag*/
if ( currentNode.dataset.quoteStyle == 'simple' )
quote = currentNode.innerHTML;
else
quote = currentNode.querySelector('.' + elementClasses_.quoteText).innerHTML;
if (job)
job = job.textContent;
if (author)
author = author.textContent;
if (photo)
photo = photo.dataset.bigUrl;
var data = {
style : currentNode.dataset.quoteStyle,
text : quote,
author : author,
job : job,
photo : photo
};
return data;
}
};
/**
* @private
*
* Author image Uploader
*/
var fileUploadClicked_ = function() {
var beforeSend = photoUploadingCallbacks_.beforeSend,
success = photoUploadingCallbacks_.success,
error = photoUploadingCallbacks_.error;
codex.transport.selectAndUpload({
beforeSend: beforeSend,
success: success,
error: error
});
};
/**
* @private
*
*/
var ui_ = {
wrapper : function($classList) {
var el = document.createElement('DIV');
el.classList.add($classList);
return el;
},
blockquote : function() {
var el = document.createElement('BLOCKQUOTE');
return el;
},
img : function(attribute) {
var imageTag = document.createElement('IMG');
imageTag.classList.add(attribute);
return imageTag;
},
makeBlock : function(tag, classList) {
var el = document.createElement(tag);
if ( classList ) {
for( var i = 0; i < classList.length; i++)
el.className += ' ' + classList[i];
}
return el;
}
};
/**
* @private
*
* Callbacks
*/
var photoUploadingCallbacks_ = {
beforeSend : function() {
},
/**
* Success callbacks for uploaded photo.
* Replace upload icon with uploaded photo
*/
success : function(result) {
var parsed = JSON.parse(result),
filename = parsed.filename,
uploadImageWrapper = codex.content.currentNode.querySelector('.' + elementClasses_.withPhoto.photo),
authorsPhoto = quoteTools.ui.img(elementClasses_.authorsPhoto);
authorsPhoto.src = parsed.data.file.url;
/** Remove icon from image wrapper */
uploadImageWrapper.innerHTML = '';
/** Appending uploaded image */
uploadImageWrapper.classList.add(elementClasses_.authorsPhotoWrapper);
uploadImageWrapper.appendChild(authorsPhoto);
authorsPhoto.dataset.bigUrl = parsed.data.file.bigUrl;
},
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
error : function(result) {
console.log('Can\'t upload an image');
}
};
/**
* @private
*
* Make Quote from JSON datasets
*/
var make_ = function(data) {
var tag;
if (data && data.size) {
data.style = quote.config.defaultStyle;
/**
* Supported types
*/
switch (data.style) {
case 'simple':
tag = quoteTools.makeSimpleQuote(data);
break;
case 'withCaption':
tag = quoteTools.makeQuoteWithCaption(data);
break;
case 'withPhoto':
tag = quoteTools.makeQuoteWithPhoto(data);
break;
}
tag.dataset.quoteStyle = data.size;
} else {
var settings = {
"text" : null,
"format" : "html",
"cite" : null,
"caption": null,
"size" : null,
"image" : null
};
tag = methods_.makeQuoteWithPhoto(settings);
}
return tag;
};
var prepareDataForSave_ = function(data) {
};
/**
* @public
*
* Renderer
*
* @param data
*/
quote.render = function(data) {
return make_(data);
};
quote.validate = function(output) {
if (typeof output.text != "string") {
return;
}
return output;
};
quote.save = function(blockContent) {
/**
* Extracts JSON quote data from HTML block
* @param {Text} text, {Text} author, {Object} photo
*/
var parsedblock = methods_.parseBlockQuote(blockContent);
if (parsedblock.style == 'withPhoto') {
parsedblock.style = 'small';
}
data = {
"text" : parsedblock.text,
"format" : "html",
"cite" : parsedblock.author,
"caption": parsedblock.job,
"size" : parsedblock.style,
"image" : parsedblock.photo
};
return data;
};
/**
* @public
*
* Draws settings
*/
quote.makeSettings = function(data) {
var holder = document.createElement('DIV'),
types = {
big : 'По центру',
small : 'Врезка'
},
selectTypeButton;
/** Add holder classname */
holder.className = elementClasses_.settings.holder;
/** Now add type selectors */
for (var type in types){
selectTypeButton = document.createElement('SPAN');
selectTypeButton.textContent = types[type];
selectTypeButton.className = elementClasses_.settings.buttons;
selectTypeButton.dataset.style = type;
if ( type == quote.config.defaultStyle ){
selectTypeButton.classList.add(quoteTools.styles.settings.selectedType);
}
// var quoteStyle = quoteTools.selectTypeQuoteStyle(type);
selectTypeButton.addEventListener('click', methods_.changeStyleClicked, false);
// quoteTools.addSelectTypeClickListener(selectTypeButton, quoteStyle);
holder.appendChild(selectTypeButton);
}
return holder;
};
/**
* @public
* Default path to redactors images
* @type {null}
*/
quote.path = null;
/**
* @public
*
* @type {null}
*/
quote.config = null;
/**
* @public
*
* @param config
*/
quote.prepare = function(config) {
quote.config = config;
};
return quote;
})({});