Merge branch 'master' into youtube-plugin-added

# Conflicts:
#	codex-editor.js
#	codex-editor.js.map
#	whatwg-fetch.js.map
This commit is contained in:
khaydarov 2017-01-26 16:35:37 +03:00
commit 174f7d1a2b
7 changed files with 774 additions and 454 deletions

View file

@ -122,31 +122,35 @@
showInlineToolbar: true,
enableLineBreaks: true
},
quote: {
type: 'quote',
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',
image_extended: {
type: 'image_extended',
iconClassname: 'ce-icon-picture',
make: image.make,
appendCallback: image.appendCallback,
settings: image.makeSettings,
prepare: image.prepare,
makeSettings: image.makeSettings,
render: image.render,
save: image.save,
isStretched: true,
displayInToolbox: true,
enableLineBreaks: false
config: {
uploadUrl : '/club/fetch'
}
},
instagram: {
type: 'instagram',

View file

@ -3,7 +3,7 @@
* Works with DOM
*
* @author Codex Team
* @version 1.3.6
* @version 1.3.8
*/
var content = (function(content) {
@ -158,6 +158,14 @@ var content = (function(content) {
targetBlock = targetBlock.parentNode;
}
/**
* Check is this block was in feed
* If true, than set switched block also covered
*/
if (targetBlock.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE)) {
newBlock.classList.add(codex.ui.className.BLOCK_IN_FEED_MODE);
}
/** Replacing */
codex.nodes.redactor.replaceChild(newBlock, targetBlock);

View file

@ -1,6 +1,6 @@
{
"name": "codex.editor",
"version": "1.3.2",
"version": "1.3.5",
"description": "Codex Editor. Native JS, based on API and Open Source",
"main": "index.js",
"scripts": {

View file

@ -4,7 +4,15 @@
*
* @version 0.0.1
*/
.ce-image {
.ce-image__wrapper img {
transition: all 500ms ease-in;
will-change: opacity, filter;
}
.ce-image__preview img {
opacity: .5;
filter: blur(1.7px) grayscale(1);
}
/** upload image form */

View file

@ -1,40 +1,47 @@
/**
* Image plugin for codex-editor
* @author CodeX Team <team@ifmo.su>
*
* @version 1.1.3
*/
* Image plugin for codex-editor
* @author CodeX Team <team@ifmo.su>
*
* @version 1.2.0
*/
var image = (function(image) {
var elementClasses = {
/**
* @private
*
* CSS classNames
*/
var elementClasses_ = {
ce_image : 'ce-image',
loading : 'ce-plugin-image__loader',
blockStretched: 'ce-block--stretched',
uploadedImage : {
centered : 'ce-plugin-image__uploaded--centered',
centered : 'ce-plugin-image__uploaded--centered',
stretched : 'ce-plugin-image__uploaded--stretched'
},
imageCaption : 'ce-plugin-image__caption',
imageWrapper : 'ce-plugin-image__wrapper',
formHolder : 'ce-plugin-image__holder',
uploadButton : 'ce-plugin-image__button'
uploadButton : 'ce-plugin-image__button',
imagePreview : 'ce-image__preview'
};
var holder = null;
/** Default path to redactors images */
var path = '/upload/redactor_images/';
var ui = {
/**
*
* @private
*
* UI methods
*/
var ui_ = {
holder : function(){
var element = document.createElement('DIV');
element.classList.add(elementClasses.formHolder);
element.classList.add(elementClasses.ce_image);
element.classList.add(elementClasses_.formHolder);
element.classList.add(elementClasses_.ce_image);
return element;
},
@ -43,7 +50,7 @@ var image = (function(image) {
var button = document.createElement('SPAN');
button.classList.add(elementClasses.uploadButton);
button.classList.add(elementClasses_.uploadButton);
button.innerHTML = '<i class="ce-icon-picture"> </i>';
button.innerHTML += 'Загрузить фотографию';
@ -53,17 +60,18 @@ var image = (function(image) {
},
/**
* @param {string} source - file path
* @param {object} file - file path
* @param {string} style - css class
* @return {object} image - document IMG tag
*/
image : function(source, style) {
image : function(file, style) {
var image = document.createElement('IMG');
image.classList.add(style);
image.src = source;
image.src = file.url;
image.dataset.bigUrl = file.bigUrl;
return image;
},
@ -72,7 +80,7 @@ var image = (function(image) {
var div = document.createElement('div');
div.classList.add(elementClasses.imageWrapper);
div.classList.add(elementClasses_.imageWrapper);
return div;
},
@ -81,7 +89,7 @@ var image = (function(image) {
var div = document.createElement('div');
div.classList.add(elementClasses.imageCaption);
div.classList.add(elementClasses_.imageCaption);
div.contentEditable = true;
return div;
@ -91,14 +99,14 @@ var image = (function(image) {
*/
makeForm : function() {
var holder = ui.holder(),
uploadButton = ui.uploadButton();
var holder = ui_.holder(),
uploadButton = ui_.uploadButton();
holder.appendChild(uploadButton);
uploadButton.addEventListener('click', methods.uploadButtonClicked, false );
uploadButton.addEventListener('click', uploadButtonClicked_, false );
holder = holder;
image.holder = holder;
return holder;
},
@ -113,12 +121,12 @@ var image = (function(image) {
*/
makeImage : function(data, imageTypeClass, stretched) {
var file = data.file.url,
var file = data.file,
text = data.caption,
type = data.type,
image = ui.image(file, imageTypeClass),
caption = ui.caption(),
wrapper = ui.wrapper();
image = ui_.image(file, imageTypeClass),
caption = ui_.caption(),
wrapper = ui_.wrapper();
caption.textContent = text;
@ -135,8 +143,8 @@ var image = (function(image) {
*/
getImage : function(data) {
var image = data.querySelector('.' + elementClasses.uploadedImage.centered) ||
data.querySelector('.' + elementClasses.uploadedImage.stretched);
var image = data.querySelector('.' + elementClasses_.uploadedImage.centered) ||
data.querySelector('.' + elementClasses_.uploadedImage.stretched);
return image;
},
@ -149,12 +157,12 @@ var image = (function(image) {
*/
centeredImage : function(data) {
var file = data.file.url,
var file = data.file,
text = data.caption,
type = data.type,
image = ui.image(file, elementClasses.uploadedImage.centered),
caption = ui.caption(),
wrapper = ui.wrapper();
image = ui_.image(file, elementClasses_.uploadedImage.centered),
caption = ui_.caption(),
wrapper = ui_.wrapper();
caption.textContent = text;
@ -175,16 +183,17 @@ var image = (function(image) {
*/
stretchedImage : function(data) {
var file = data.file.url,
var file = data.file,
text = data.caption,
type = data.type,
image = ui.image(file, elementClasses.uploadedImage.stretched),
caption = ui.caption(),
wrapper = ui.wrapper();
image = ui_.image(file, elementClasses_.uploadedImage.stretched),
caption = ui_.caption(),
wrapper = ui_.wrapper();
caption.textContent = text;
wrapper.dataset.stretched = 'true';
/** Appeding to the wrapper */
wrapper.appendChild(image);
wrapper.appendChild(caption);
@ -192,25 +201,35 @@ var image = (function(image) {
return wrapper;
}
};
var methods = {
/**
* @private
*
* After render callback
*/
var uploadButtonClicked_ = function(event) {
uploadButtonClicked : function(event) {
var beforeSend = uploadingCallbacks_.ByClick.beforeSend,
success = uploadingCallbacks_.ByClick.success,
error = uploadingCallbacks_.ByClick.error;
/** Define callbacks */
codex.transport.selectAndUpload({
beforeSend: photoUploadingCallbacks.beforeSend,
success: photoUploadingCallbacks.success,
error: photoUploadingCallbacks.error
});
},
/** Define callbacks */
codex.transport.selectAndUpload({
beforeSend: beforeSend,
success: success,
error: error
});
};
var methods_ = {
addSelectTypeClickListener : function(el, type) {
el.addEventListener('click', function() {
methods.selectTypeClicked(type);
methods_.selectTypeClicked(type);
}, false);
@ -218,126 +237,348 @@ var image = (function(image) {
selectTypeClicked : function(type) {
var current = codex.content.currentNode,
var current = codex.content.currentNode,
blockContent = current.childNodes[0],
image = ui.getImage(current),
wrapper = current.querySelector('.' + elementClasses.imageWrapper);
image = ui_.getImage(current),
inFeed = false,
wrapper = current.querySelector('.' + elementClasses_.imageWrapper);
if (!image) {
return;
}
/** Clear classList */
current.className = '';
image.className = '';
image.className = '';
/** Add important first-level class ce_block */
current.classList.add(codex.ui.className.BLOCK_CLASSNAME);
if (type === 'stretched') {
image.classList.add(elementClasses.uploadedImage.stretched);
image.classList.add(elementClasses_.uploadedImage.stretched);
blockContent.classList.add(elementClasses.blockStretched);
blockContent.classList.add(elementClasses_.blockStretched);
/** Setting dataset for saver */
wrapper.dataset.stretched = true;
} else if (type === 'centered') {
image.classList.add(elementClasses.uploadedImage.centered);
image.classList.add(elementClasses_.uploadedImage.centered);
blockContent.classList.remove(elementClasses.blockStretched);
blockContent.classList.remove(elementClasses_.blockStretched);
/** Setting dataset for saver */
wrapper.dataset.stretched = false;
}
codex.toolbar.settings.close();
}
};
var photoUploadingCallbacks = {
/** Before sending ajax request */
beforeSend : function() {
holder.classList.add(elementClasses.loading);
},
/** Photo was uploaded successfully */
success : function(result) {
var parsed = JSON.parse(result),
data,
currentBlock = codex.content.currentNode,
imageReady;
/**
* Preparing {Object} data to draw an image
* @uses make method
*/
data = {
background : false,
border : false,
isStretch : false,
file : {
url : path + 'o_' + parsed.filename,
bigUrl : null,
width : null,
height : null,
additionalData : null
},
caption : '',
cover : null
};
imageReady = image.make(data);
/**
* If current block is empty, we can replace it to uploaded image
* Or insert new block
*/
codex.content.switchBlock(holder, imageReady, 'image');
},
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
error : function(result) {
console.log('Choosen file is not an image or image is corrupted');
codex.notifications.errorThrown();
}
};
/**
* Public method
* @private
* Callbacks
*/
image.make = function ( data ) {
var uploadingCallbacks_ = {
var imageHolder;
ByClick : {
/**
* Before sending ajax request
*/
beforeSend : function() {
var input = codex.transport.input,
files = input.files;
var validFileExtensions = ["jpg", "jpeg", "bmp", "gif", "png"];
var type = files[0].type.split('/');
var result = validFileExtensions.some(function(ext) {
return ext == type[1]
});
if (!result) {
return;
}
var reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onload = function(e) {
var data = {
background : false,
border : false,
isstretch : false,
file : {
url : e.target.result,
bigUrl : null,
width : null,
height : null,
additionalData : null
},
caption : '',
cover : null
};
var newImage = make_(data);
codex.content.switchBlock(image.holder, newImage, 'image_extended');
newImage.classList.add(elementClasses_.imagePreview);
/**
* Change holder to image
*/
image.holder = newImage;
};
},
/** Photo was uploaded successfully */
success : function(result) {
var parsed = JSON.parse(result),
data,
currentBlock = codex.content.currentNode;
/**
* Preparing {Object} data to draw an image
* @uses ceImage.make method
*/
data = parsed.data;
image.holder.classList.remove(elementClasses_.imagePreview);
/**
* Change src of image
*/
var newImage = image.holder.getElementsByTagName('IMG')[0];
newImage.src = parsed.data.file.url;
newImage.dataset.bigUrl = parsed.data.file.bigUrl;
},
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
error : function(result) {
var oldHolder = image.holder;
var form = ui_.makeForm();
codex.content.switchBlock(oldHolder, form, 'image_extended');
}
},
ByPaste : {
/**
* Direct upload
* Any URL that contains image extension
* @param url
*/
uploadImageFromUrl : function(path) {
var ajaxUrl = image.config.uploadUrl,
file,
image_plugin,
current = codex.content.currentNode,
beforeSend,
success_callback;
/** When image is uploaded to redactors folder */
success_callback = function(data) {
var imageInfo = JSON.parse(data);
image_plugin.dataset.stretched = false;
image_plugin.dataset.src = imageInfo.file.url;
image_plugin.dataset.bigUrl = imageInfo.file.bigUrl;
image_plugin.dataset.width = imageInfo.file.width;
image_plugin.dataset.height = imageInfo.file.height;
image_plugin.dataset.additionalData = imageInfo.file.additionalData;
image_plugin.classList.remove(elementClasses_.imagePreview);
};
/** Before sending XMLHTTP request */
beforeSend = function() {
var content = current.querySelector('.ce-block__content');
var data = {
background: false,
border: false,
isStretch: false,
file: {
url: path,
bigUrl: null,
width: null,
height: null,
additionalData: null
},
caption: '',
cover: null
};
image_plugin = codex.tools.image_extended.render(data);
image_plugin.classList.add(elementClasses_.imagePreview);
var img = image_plugin.querySelector('img');
codex.content.switchBlock(codex.content.currentNode, image_plugin, 'image_extended');
};
/** Preparing data for XMLHTTP */
var data = {
url: image.config.uploadUrl,
type: "POST",
data : {
url: path
},
beforeSend : beforeSend,
success : success_callback
};
codex.core.ajax(data);
}
}
};
/**
* Default image holder which will be replaced after image upload
* @type {null}
*/
image.holder = null;
/**
* Image path
* @type {null}
*/
image.path = null;
/**
* Plugin configuration
*/
image.config = null;
/**
*
* @private
*
* @param data
* @return {*}
*
*/
var make_ = function ( data ) {
var holder;
if (data) {
if ( data.isStretch !== 'true') {
imageHolder = ui.makeImage(data, elementClasses.uploadedImage.centered, 'false');
if ( data.isstretch || data.isstretch === 'true') {
holder = ui_.makeImage(data, elementClasses_.uploadedImage.stretched, 'true');
} else {
imageHolder = ui.makeImage(data, elementClasses.uploadedImage.stretched, 'true');
holder = ui_.makeImage(data, elementClasses_.uploadedImage.centered, 'false');
}
return holder;
} else {
imageHolder = ui.makeForm();
holder = ui_.makeForm();
return holder;
}
holder = imageHolder;
return imageHolder;
};
/**
* @private
*
* Prepare clear data before save
*
* @param data
*/
var prepareDataForSave_ = function(data) {
};
/**
* @public
* @param config
*/
image.prepare = function(config) {
image.config = config;
};
/**
* @public
*
* this tool works when tool is clicked in toolbox
*/
image.appendCallback = function(event) {
/** Upload image and call success callback*/
methods.uploadButtonClicked(event);
uploadButtonClicked_(event);
};
/**
* @public
*
* @param data
* @return {*}
*/
image.render = function( data ) {
return make_(data);
};
/**
* @public
*
* @param block
* @return {{background: boolean, border: boolean, isstretch: boolean, file: {url: (*|string|Object), bigUrl: (null|*), width: *, height: *, additionalData: null}, caption: (string|*|string), cover: null}}
*/
image.save = function ( block ) {
var content = block,
image = ui_.getImage(content),
caption = content.querySelector('.' + elementClasses_.imageCaption);
var data = {
background : false,
border : false,
isstretch : content.dataset.stretched === 'true' ? true : false,
file : {
url : image.src,
bigUrl : image.dataset.bigUrl,
width : image.width,
height : image.height,
additionalData :null
},
caption : caption.textContent,
cover : null
};
return data;
};
/**
* @public
*
* Settings panel content
* @return {Element} element contains all settings
*/
@ -361,7 +602,7 @@ var image = (function(image) {
selectTypeButton.textContent = types[type];
selectTypeButton.className = 'ce_plugin_image--select_button';
methods.addSelectTypeClickListener(selectTypeButton, type);
methods_.addSelectTypeClickListener(selectTypeButton, type);
holder.appendChild(selectTypeButton);
@ -371,34 +612,10 @@ var image = (function(image) {
};
image.render = function( data ) {
return image.make(data);
};
image.save = function ( block ) {
var content = block,
image = ui.getImage(content),
caption = content.querySelector('.' + elementClasses.imageCaption);
var data = {
background : false,
border : false,
isStretch : content.dataset.stretched,
file : {
url : image.src,
bigUrl : null,
width : image.width,
height : image.height,
additionalData :null
},
caption : caption.textContent,
cover : null
};
return data;
};
/**
* Share as API
*/
image.uploadImageFromUri = uploadingCallbacks_.ByPaste.uploadImageFromUrl;
image.urlPastedCallbacks = {

View file

@ -4,12 +4,12 @@
cursor: pointer;
line-height: 1.3em;
}
.ce_plugin_quote--select_button:not(:last-of-type){
margin-bottom: 1.5em;
}
.ce_plugin_quote--select_button:hover{
color: #a1b4ec;
}
.ce_plugin_quote--select_button:not(:last-of-type){
margin-bottom: 1.5em;
}
.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,11 +46,13 @@
.quoteStyle-withCaption--blockquote {
margin: 0;
padding: 1.5em 2.0em !important;
border: 1px solid #ebeef3;
background: #fff;
}
.quoteStyle-withCaption--blockquote:focus,
.quoteStyle-withCaption--author:focus {
outline: none;
outline: none;
}
.quoteStyle-simple--text:empty::before,
@ -106,23 +111,23 @@
border: 1px solid #ebeef3;
background: #fff;
}
.quoteStyle-withPhoto--photo:hover {
cursor: pointer;
background: #F0F3F6;
}
.quoteStyle-withPhoto--photo:hover {
cursor: pointer;
background: #F0F3F6;
}
.quoteStyle-withPhoto--photo:hover::after {
display: block;
}
.quoteStyle-withPhoto--photo:hover::after {
display: block;
}
.authorsPhoto {
height: 110%;
vertical-align: top;
}
.authorsPhoto {
height: 110%;
vertical-align: top;
}
.authorsPhoto-wrapper {
border: 0 !important;
}
.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

@ -1,19 +1,16 @@
/**
* Codex Team
* @author Khaydarov Murod
*/
*
* Quote plugin
*/
var quote = (function(quote) {
/** Default path to redactors images */
var path = '/upload/redactor_images/';
/**
* Default quote style
* @private
*
* CSS styles
*/
var defaultStyle = 'withPhoto';
var styles = {
var elementClasses_ = {
ce_quote : 'ce-quote',
quoteText : 'ce_quote--text',
@ -48,40 +45,244 @@ var quote = (function(quote) {
}
};
var photoUploadingCallbacks = {
/**
* @private
*
*
*/
var methods_ = {
/**
* Success callbacks for uploaded photo.
* Replace upload icon with uploaded photo
*/
success : function(result) {
changeStyleClicked : function() {
var parsed = JSON.parse(result),
filename = parsed.filename,
uploadImageWrapper = codex.content.currentNode.querySelector('.' + styles.withPhoto.photo),
authorsPhoto = ui.img(styles.authorsPhoto);
var changeStyleButton = this,
quote = codex.content.currentNode.querySelector('.' + elementClasses_.ce_quote),
newStyle = changeStyleButton.dataset.style,
styleSelectors = this.parentNode.childNodes;
authorsPhoto.src = path + 'b_' + filename;
quote.dataset.quoteStyle = newStyle;
/** Remove icon from image wrapper */
uploadImageWrapper.innerHTML = '';
/**
* 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);
/** Appending uploaded image */
uploadImageWrapper.classList.add(styles.authorsPhotoWrapper);
uploadImageWrapper.appendChild(authorsPhoto);
},
/** Error callback. Sends notification to user that something happend or plugin doesn't supports method */
error : function(result) {
/**
* @deprecated
*/
selectTypeQuoteStyle : function(type) {
console.log('Can\'t upload an image');
codex.notifications.errorThrown();
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
});
};
var ui = {
/**
* @private
*
*/
var ui_ = {
wrapper : function($classList) {
@ -102,6 +303,7 @@ var quote = (function(quote) {
},
img : function(attribute) {
var imageTag = document.createElement('IMG');
imageTag.classList.add(attribute);
@ -112,281 +314,130 @@ var quote = (function(quote) {
var el = document.createElement(tag);
if ( classList ) {
for( var i = 0; i < classList.length; i++)
el.className += ' ' + classList[i];
}
return el;
}
};
var methods = {
/**
* @private
*
* Callbacks
*/
var photoUploadingCallbacks_ = {
changeStyleClicked : function() {
var changeStyleButton = this,
quote = codex.content.currentNode.querySelector('.' + styles.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(styles.settings.selectedType);
}
this.classList.add(styles.settings.selectedType);
beforeSend : function() {
},
/**
* @deprecated
* Success callbacks for uploaded photo.
* Replace upload icon with uploaded photo
*/
selectTypeQuoteStyle : function(type) {
success : function(result) {
/**
* Choose Quote style to replace
*/
switch (type) {
case 'simple':
quoteStyleFunction = makeSimpleQuote;
break;
case 'withCaption':
quoteStyleFunction = makeQuoteWithCaption;
break;
case 'withPhoto':
quoteStyleFunction = makeQuoteWithPhoto;
break;
}
return quoteStyleFunction;
var parsed = JSON.parse(result),
filename = parsed.filename,
uploadImageWrapper = codex.content.currentNode.querySelector('.' + elementClasses_.withPhoto.photo),
authorsPhoto = 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;
},
/**
* @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', [styles.simple.text, styles.quoteText]);
wrapper.innerHTML = data.text || '';
wrapper.dataset.quoteStyle = 'simple';
wrapper.classList.add(styles.ce_quote);
wrapper.contentEditable = 'true';
return wrapper;
},
/**
* @deprecated
*/
makeQuoteWithCaption : function(data) {
var wrapper = ui.blockquote(),
text = ui.makeBlock('DIV', [styles.withCaption.blockquote, styles.quoteText]),
author = ui.makeBlock('DIV', [styles.withCaption.author, styles.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(styles.ce_quote);
wrapper.appendChild(text);
wrapper.appendChild(author);
return wrapper;
},
makeQuoteWithPhoto : function(data) {
var wrapper = ui.blockquote(),
photo = ui.makeBlock('DIV', [styles.withPhoto.photo]),
author = ui.makeBlock('DIV', [styles.withPhoto.author, styles.quoteAuthor]),
job = ui.makeBlock('DIV', [styles.withPhoto.job, styles.authorsJob]),
quote = ui.makeBlock('DIV', [styles.withPhoto.quote, styles.quoteText]);
/* Default Image src */
if (!data.photo) {
var icon = ui.makeBlock('SPAN', ['ce-icon-picture']);
photo.appendChild(icon);
} else {
var authorsPhoto = ui.img(styles.authorsPhoto);
authorsPhoto.src = data.photo;
photo.classList.add(styles.authorsPhotoWrapper);
photo.appendChild(authorsPhoto);
}
photo.addEventListener('click', methods.fileUploadClicked, false);
/* make author block contentEditable */
author.contentEditable = 'true';
author.textContent = data.cite;
/* Author's position and job */
job.contentEditable = 'true';
job.textContent = data.job;
var authorsWrapper = ui.makeBlock('DIV', [styles.withPhoto.authorHolder]);
authorsWrapper.appendChild(author);
authorsWrapper.appendChild(job);
/* make quote text contentEditable */
quote.contentEditable = 'true';
quote.innerHTML = data.text;
wrapper.classList.add(styles.ce_quote);
wrapper.classList.add(styles.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('.' + styles.quoteAuthor),
job = currentNode.querySelector('.' + styles.authorsJob),
quote ;
/** Simple quote text placed in Blockquote tag*/
if ( currentNode.dataset.quoteStyle == 'simple' )
quote = currentNode.innerHTML;
else
quote = currentNode.querySelector('.' + styles.quoteText).innerHTML;
if (job)
job = job.textContent;
if (author)
author = author.textContent;
if (photo)
photo = photo.src;
var data = {
style : currentNode.dataset.quoteStyle,
text : quote,
author : author,
job : job,
photo : photo
};
return data;
},
fileUploadClicked : function() {
codex.transport.selectAndUpload({
sucess: photoUploadingCallbacks.success,
error: photoUploadingCallbacks.error
});
/** 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
*/
quote.makeBlockToAppend = function(data) {
var make_ = function(data) {
var tag;
if (data && data.size) {
data.style = 'withPhoto';
data.style = quote.config.defaultStyle;
/**
* Supported types
*/
switch (data.style) {
case 'simple':
tag = methods.makeSimpleQuote(data);
tag = methods_.makeSimpleQuote(data);
break;
case 'withCaption':
tag = methods.makeQuoteWithCaption(data);
tag = methods_.makeQuoteWithCaption(data);
break;
case 'withPhoto':
tag = methods.makeQuoteWithPhoto(data);
tag = methods_.makeQuoteWithPhoto(data);
break;
}
tag.dataset.quoteStyle = data.size;
} else {
var settings = {
style : 'withPhoto',
text : '',
author : '',
job : '',
photo : ''
"text" : null,
"format" : "html",
"cite" : null,
"caption": null,
"size" : null,
"image" : null
};
tag = methods.makeQuoteWithPhoto(settings);
tag = methods_.makeQuoteWithPhoto(settings);
}
return tag;
};
quote.validate = function(data) {
var prepareDataForSave_ = function(data) {
console.log(data);
if (data.style.trim() == '' || data.text.trim() == '' || data.cite.trim() == ''
|| data.size.trim() == '')
return;
return true;
};
/**
* @public
*
* Renderer
*
* @param data
*/
quote.render = function(data) {
return quote.makeBlockToAppend(data);
return make_(data);
};
quote.validate = function(output) {
if (typeof output.text != "string") {
return;
}
return output;
};
quote.save = function(blockContent) {
@ -395,35 +446,40 @@ var quote = (function(quote) {
* Extracts JSON quote data from HTML block
* @param {Text} text, {Text} author, {Object} photo
*/
var parsedblock = methods.parseBlockQuote(blockContent);
var parsedblock = methods_.parseBlockQuote(blockContent);
if (parsedblock.style == 'withPhoto') {
parsedblock.style = 'small';
}
var data = {
data = {
"text" : parsedblock.text,
"format" : "html",
"cite" : parsedblock.author,
"size" : parsedblock.style
"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 : 'Врезка'
// simple : 'Простая цитата',
// withCaption : 'Цитата с подписью',
// withPhoto : 'Цитата с фото и ФИО'
},
selectTypeButton;
/** Add holder classname */
holder.className = styles.settings.holder;
holder.className = elementClasses_.settings.holder;
/** Now add type selectors */
for (var type in types){
@ -431,17 +487,17 @@ var quote = (function(quote) {
selectTypeButton = document.createElement('SPAN');
selectTypeButton.textContent = types[type];
selectTypeButton.className = styles.settings.buttons;
selectTypeButton.className = elementClasses_.settings.buttons;
selectTypeButton.dataset.style = type;
if ( type == defaultStyle ){
selectTypeButton.classList.add(styles.settings.selectedType);
if ( type == quote.config.defaultStyle ){
selectTypeButton.classList.add(quoteTools.styles.settings.selectedType);
}
// var quoteStyle = quoteTools.selectTypeQuoteStyle(type);
selectTypeButton.addEventListener('click', methods.changeStyleClicked, false);
selectTypeButton.addEventListener('click', methods_.changeStyleClicked, false);
// quoteTools.addSelectTypeClickListener(selectTypeButton, quoteStyle);
holder.appendChild(selectTypeButton);
@ -452,6 +508,29 @@ var quote = (function(quote) {
};
/**
* @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;
})({});