mirror of
https://github.com/codex-team/editor.js
synced 2024-06-13 03:12:21 +02:00
new feature (#109)
* new feature method validate must be appended to codex.tools. * beta-redactor * before merge * validate is not important setting
This commit is contained in:
parent
7af56b4149
commit
a9a0992217
|
@ -1141,10 +1141,14 @@ var codex =
|
||||||
data: savedData
|
data: savedData
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
if (codex.tools[pluginName].validate) {
|
||||||
* Do not allow empty initial plugins block
|
var result = codex.tools[pluginName].validate(savedData);
|
||||||
*/
|
|
||||||
if (savedData.text.trim() == '' && pluginName == codex.settings.initialBlockPlugin) return;
|
/**
|
||||||
|
* Do not allow invalid data
|
||||||
|
*/
|
||||||
|
if (!result) return;
|
||||||
|
}
|
||||||
|
|
||||||
/** Marks Blocks that will be in main page */
|
/** Marks Blocks that will be in main page */
|
||||||
output.cover = block.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE);
|
output.cover = block.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE);
|
||||||
|
@ -1893,6 +1897,12 @@ var codex =
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toolbar settings
|
||||||
|
*
|
||||||
|
* @version 1.0.3
|
||||||
|
*/
|
||||||
|
|
||||||
var settings = function (settings) {
|
var settings = function (settings) {
|
||||||
|
|
||||||
settings.init = function () {
|
settings.init = function () {
|
||||||
|
@ -1915,13 +1925,17 @@ var codex =
|
||||||
* Append settings content
|
* Append settings content
|
||||||
* It's stored in tool.settings
|
* It's stored in tool.settings
|
||||||
*/
|
*/
|
||||||
if (!codex.tools[toolType] || !codex.core.isDomNode(codex.tools[toolType].settings)) {
|
if (!codex.tools[toolType] || !codex.tools[toolType].settings) {
|
||||||
|
|
||||||
codex.core.log('Plugin \xAB' + toolType + '\xBB has no settings', 'warn');
|
codex.core.log('Plugin \xAB' + toolType + '\xBB has no settings', 'warn');
|
||||||
// codex.nodes.pluginSettings.innerHTML = `Плагин «${toolType}» не имеет настроек`;
|
// codex.nodes.pluginSettings.innerHTML = `Плагин «${toolType}» не имеет настроек`;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
codex.nodes.pluginSettings.appendChild(codex.tools[toolType].settings);
|
/**
|
||||||
|
* Draw settings block
|
||||||
|
*/
|
||||||
|
var settingsBlock = codex.tools[toolType].settings();
|
||||||
|
codex.nodes.pluginSettings.appendChild(settingsBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentBlock = codex.content.currentNode;
|
var currentBlock = codex.content.currentNode;
|
||||||
|
|
File diff suppressed because one or more lines are too long
82
example.html
82
example.html
|
@ -53,11 +53,12 @@
|
||||||
paragraph: {
|
paragraph: {
|
||||||
type: 'paragraph',
|
type: 'paragraph',
|
||||||
iconClassname: 'ce-icon-paragraph',
|
iconClassname: 'ce-icon-paragraph',
|
||||||
make: paragraphTool.make,
|
make: paragraph.make,
|
||||||
appendCallback: null,
|
appendCallback: null,
|
||||||
settings: null,
|
settings: null,
|
||||||
render: paragraphTool.render,
|
render: paragraph.render,
|
||||||
save: paragraphTool.save,
|
validate: paragraph.validate,
|
||||||
|
save: paragraph.save,
|
||||||
enableLineBreaks: false,
|
enableLineBreaks: false,
|
||||||
allowedToPaste: true,
|
allowedToPaste: true,
|
||||||
showInlineToolbar: true
|
showInlineToolbar: true
|
||||||
|
@ -79,43 +80,47 @@
|
||||||
header: {
|
header: {
|
||||||
type: 'header',
|
type: 'header',
|
||||||
iconClassname: 'ce-icon-header',
|
iconClassname: 'ce-icon-header',
|
||||||
make: headerTool.make,
|
make: header.make,
|
||||||
appendCallback: headerTool.appendCallback,
|
appendCallback: header.appendCallback,
|
||||||
settings: headerTool.makeSettings(),
|
settings: header.makeSettings,
|
||||||
render: headerTool.render,
|
render: header.render,
|
||||||
save: headerTool.save,
|
validate: header.validate,
|
||||||
displayInToolbox: true,
|
save: header.save,
|
||||||
|
displayInToolbox: true
|
||||||
// handleTagOnPaste : ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']
|
// handleTagOnPaste : ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
type: 'code',
|
type: 'code',
|
||||||
iconClassname: 'ce-icon-code',
|
iconClassname: 'ce-icon-code',
|
||||||
make: codeTool.make,
|
make: code.make,
|
||||||
appendCallback: null,
|
appendCallback: null,
|
||||||
settings: null,
|
settings: null,
|
||||||
render: codeTool.render,
|
render: code.render,
|
||||||
save: codeTool.save,
|
validate: code.validate,
|
||||||
|
save: code.save,
|
||||||
displayInToolbox: true,
|
displayInToolbox: true,
|
||||||
enableLineBreaks: true
|
enableLineBreaks: true
|
||||||
},
|
},
|
||||||
link: {
|
link: {
|
||||||
type: 'link',
|
type: 'link',
|
||||||
iconClassname: 'ce-icon-link',
|
iconClassname: 'ce-icon-link',
|
||||||
make: linkTool.makeNewBlock,
|
make: link.makeNewBlock,
|
||||||
appendCallback: linkTool.appendCallback,
|
appendCallback: link.appendCallback,
|
||||||
render: linkTool.render,
|
render: link.render,
|
||||||
save: linkTool.save,
|
validate: link.validate,
|
||||||
|
save: link.save,
|
||||||
displayInToolbox: true,
|
displayInToolbox: true,
|
||||||
enableLineBreaks: true
|
enableLineBreaks: true
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
type: 'list',
|
type: 'list',
|
||||||
iconClassname: 'ce-icon-list-bullet',
|
iconClassname: 'ce-icon-list-bullet',
|
||||||
make: listTool.make,
|
make: list.make,
|
||||||
appendCallback: null,
|
appendCallback: null,
|
||||||
settings: listTool.makeSettings(),
|
settings: list.makeSettings,
|
||||||
render: listTool.render,
|
render: list.render,
|
||||||
save: listTool.save,
|
validate: list.validate,
|
||||||
|
save: list.save,
|
||||||
displayInToolbox: true,
|
displayInToolbox: true,
|
||||||
showInlineToolbar: true,
|
showInlineToolbar: true,
|
||||||
enableLineBreaks: true
|
enableLineBreaks: true
|
||||||
|
@ -123,11 +128,12 @@
|
||||||
quote: {
|
quote: {
|
||||||
type: 'quote',
|
type: 'quote',
|
||||||
iconClassname: 'ce-icon-quote',
|
iconClassname: 'ce-icon-quote',
|
||||||
make: quoteTools.makeBlockToAppend,
|
make: quote.makeBlockToAppend,
|
||||||
appendCallback: null,
|
appendCallback: null,
|
||||||
settings: quoteTools.makeSettings(),
|
settings: quote.makeSettings,
|
||||||
render: quoteTools.render,
|
render: quote.render,
|
||||||
save: quoteTools.save,
|
validate: quote.validate,
|
||||||
|
save: quote.save,
|
||||||
displayInToolbox: true,
|
displayInToolbox: true,
|
||||||
enableLineBreaks: true,
|
enableLineBreaks: true,
|
||||||
showInlineToolbar: true,
|
showInlineToolbar: true,
|
||||||
|
@ -136,11 +142,11 @@
|
||||||
image: {
|
image: {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
iconClassname: 'ce-icon-picture',
|
iconClassname: 'ce-icon-picture',
|
||||||
make: ceImage.make,
|
make: image.make,
|
||||||
appendCallback: ceImage.appendCallback,
|
appendCallback: image.appendCallback,
|
||||||
settings: ceImage.makeSettings(),
|
settings: image.makeSettings,
|
||||||
render: ceImage.render,
|
render: image.render,
|
||||||
save: ceImage.save,
|
save: image.save,
|
||||||
isStretched: true,
|
isStretched: true,
|
||||||
displayInToolbox: true,
|
displayInToolbox: true,
|
||||||
enableLineBreaks: false
|
enableLineBreaks: false
|
||||||
|
@ -148,12 +154,13 @@
|
||||||
instagram: {
|
instagram: {
|
||||||
type: 'instagram',
|
type: 'instagram',
|
||||||
iconClassname: 'ce-icon-instagram',
|
iconClassname: 'ce-icon-instagram',
|
||||||
prepare: instagramTool.prepare,
|
prepare: instagram.prepare,
|
||||||
make: instagramTool.make,
|
make: instagram.make,
|
||||||
appendCallback: null,
|
appendCallback: null,
|
||||||
settings: null,
|
settings: null,
|
||||||
render: instagramTool.reneder,
|
render: instagram.reneder,
|
||||||
save: instagramTool.save,
|
validate: instagram.validate,
|
||||||
|
save: instagram.save,
|
||||||
displayInToolbox: false,
|
displayInToolbox: false,
|
||||||
enableLineBreaks: false,
|
enableLineBreaks: false,
|
||||||
allowedToPaste: false
|
allowedToPaste: false
|
||||||
|
@ -161,12 +168,13 @@
|
||||||
twitter: {
|
twitter: {
|
||||||
type: 'twitter',
|
type: 'twitter',
|
||||||
iconClassname: 'ce-icon-twitter',
|
iconClassname: 'ce-icon-twitter',
|
||||||
prepare: twitterTool.prepare,
|
prepare: twitter.prepare,
|
||||||
make: twitterTool.make,
|
make: twitter.make,
|
||||||
appendCallback: null,
|
appendCallback: null,
|
||||||
settings: null,
|
settings: null,
|
||||||
render: twitterTool.render,
|
render: twitter.render,
|
||||||
save: twitterTool.save,
|
validate: twitter.validate,
|
||||||
|
save: twitter.save,
|
||||||
displayInToolbox: false,
|
displayInToolbox: false,
|
||||||
enableLineBreaks: false,
|
enableLineBreaks: false,
|
||||||
allowedToPaste: false
|
allowedToPaste: false
|
||||||
|
|
|
@ -102,12 +102,16 @@ var saver = (function(saver) {
|
||||||
data: savedData
|
data: savedData
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
if (codex.tools[pluginName].validate) {
|
||||||
* Do not allow empty initial plugins block
|
var result = codex.tools[pluginName].validate(savedData);
|
||||||
*/
|
|
||||||
if (savedData.text.trim() == '' && pluginName == codex.settings.initialBlockPlugin)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not allow invalid data
|
||||||
|
*/
|
||||||
|
if (!result)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/** Marks Blocks that will be in main page */
|
/** Marks Blocks that will be in main page */
|
||||||
output.cover = block.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE);
|
output.cover = block.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Toolbar settings
|
||||||
|
*
|
||||||
|
* @version 1.0.3
|
||||||
|
*/
|
||||||
|
|
||||||
var settings = (function(settings) {
|
var settings = (function(settings) {
|
||||||
|
|
||||||
settings.init = function() {
|
settings.init = function() {
|
||||||
|
@ -20,15 +26,18 @@ var settings = (function(settings) {
|
||||||
* Append settings content
|
* Append settings content
|
||||||
* It's stored in tool.settings
|
* It's stored in tool.settings
|
||||||
*/
|
*/
|
||||||
if (!codex.tools[toolType] || !codex.core.isDomNode(codex.tools[toolType].settings) ) {
|
if (!codex.tools[toolType] || !codex.tools[toolType].settings ) {
|
||||||
|
|
||||||
codex.core.log(`Plugin «${toolType}» has no settings`, 'warn');
|
codex.core.log(`Plugin «${toolType}» has no settings`, 'warn');
|
||||||
// codex.nodes.pluginSettings.innerHTML = `Плагин «${toolType}» не имеет настроек`;
|
// codex.nodes.pluginSettings.innerHTML = `Плагин «${toolType}» не имеет настроек`;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
codex.nodes.pluginSettings.appendChild(codex.tools[toolType].settings);
|
/**
|
||||||
|
* Draw settings block
|
||||||
|
*/
|
||||||
|
var settingsBlock = codex.tools[toolType].settings();
|
||||||
|
codex.nodes.pluginSettings.appendChild(settingsBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentBlock = codex.content.currentNode;
|
var currentBlock = codex.content.currentNode;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "codex.editor",
|
"name": "codex.editor",
|
||||||
"version": "1.2.8",
|
"version": "1.3.0",
|
||||||
"description": "Codex Editor. Native JS, based on API and Open Source",
|
"description": "Codex Editor. Native JS, based on API and Open Source",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -2,20 +2,19 @@
|
||||||
* Code Plugin\
|
* Code Plugin\
|
||||||
* Creates code tag and adds content to this tag
|
* Creates code tag and adds content to this tag
|
||||||
*/
|
*/
|
||||||
var codeTool = {
|
|
||||||
|
|
||||||
baseClass : "ce-code",
|
var code = (function(code) {
|
||||||
|
|
||||||
|
var baseClass = "ce-code";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make initial header block
|
* Make initial header block
|
||||||
* @param {object} JSON with block data
|
* @param {object} JSON with block data
|
||||||
* @return {Element} element to append
|
* @return {Element} element to append
|
||||||
*/
|
*/
|
||||||
make : function (data) {
|
code.make = function (data) {
|
||||||
|
|
||||||
var tag = document.createElement('code');
|
var tag = codex.draw.node('CODE', [baseClass], {});
|
||||||
|
|
||||||
tag.classList.add(codeTool.baseClass);
|
|
||||||
|
|
||||||
if (data && data.text) {
|
if (data && data.text) {
|
||||||
tag.innerHTML = data.text;
|
tag.innerHTML = data.text;
|
||||||
|
@ -24,31 +23,36 @@ var codeTool = {
|
||||||
tag.contentEditable = true;
|
tag.contentEditable = true;
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
};
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to render HTML block from JSON
|
* Method to render HTML block from JSON
|
||||||
*/
|
*/
|
||||||
render : function (data) {
|
code.render = function (data) {
|
||||||
|
|
||||||
return codeTool.make(data);
|
return codeTool.make(data);
|
||||||
|
};
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to extract JSON data from HTML block
|
* Method to extract JSON data from HTML block
|
||||||
*/
|
*/
|
||||||
save : function (blockContent){
|
code.save = function (blockContent){
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
text : null,
|
text : blockContent.innerHTML
|
||||||
};
|
};
|
||||||
|
|
||||||
data.text = blockContent.innerHTML;
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
};
|
code.validate = function(data) {
|
||||||
|
|
||||||
|
if (data.text.trim() == '')
|
||||||
|
return;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return code;
|
||||||
|
|
||||||
|
})({});
|
||||||
|
|
|
@ -2,31 +2,71 @@
|
||||||
* Example of making plugin
|
* Example of making plugin
|
||||||
* H e a d e r
|
* H e a d e r
|
||||||
*/
|
*/
|
||||||
var headerTool = {
|
|
||||||
|
var header = (function(header) {
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds click event to passed button
|
||||||
|
*/
|
||||||
|
addSelectTypeClickListener : function (el, type) {
|
||||||
|
|
||||||
|
el.addEventListener('click', function () {
|
||||||
|
|
||||||
|
methods.selectTypeClicked(type);
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces old header with new type
|
||||||
|
* @params {string} type - new header tagName: H1—H6
|
||||||
|
*/
|
||||||
|
selectTypeClicked : function (type) {
|
||||||
|
|
||||||
|
var old_header, new_header;
|
||||||
|
|
||||||
|
/** Now current header stored as a currentNode */
|
||||||
|
old_header = codex.content.currentNode.querySelector('[contentEditable]');
|
||||||
|
|
||||||
|
/** Making new header */
|
||||||
|
new_header = codex.draw.node(type, ['ce-header'], { innerHTML : old_header.innerHTML });
|
||||||
|
new_header.contentEditable = true;
|
||||||
|
new_header.setAttribute('data-placeholder', 'Heading');
|
||||||
|
new_header.dataset.headerData = type;
|
||||||
|
|
||||||
|
codex.content.switchBlock(old_header, new_header, 'header');
|
||||||
|
|
||||||
|
/** Close settings after replacing */
|
||||||
|
codex.toolbar.settings.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make initial header block
|
* Make initial header block
|
||||||
* @param {object} JSON with block data
|
* @param {object} JSON with block data
|
||||||
* @return {Element} element to append
|
* @return {Element} element to append
|
||||||
*/
|
*/
|
||||||
make : function (data) {
|
header.make = function (data) {
|
||||||
|
|
||||||
var availableTypes = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
|
var availableTypes = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
|
||||||
tag;
|
tag;
|
||||||
|
|
||||||
if (data && data.type && availableTypes.includes(data.type)) {
|
if (data && data.type && availableTypes.includes(data.type)) {
|
||||||
|
|
||||||
tag = document.createElement( data.type );
|
tag = codex.draw.node( data.type, [], {} );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save header type in data-attr.
|
* Save header type in data-attr.
|
||||||
* We need it in save method to extract type from HTML to JSON
|
* We need it in save method to extract type from HTML to JSON
|
||||||
*/
|
*/
|
||||||
tag.dataset.headerData = data.type;
|
tag.dataset.headerData = data.type;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
tag = document.createElement( 'H2' );
|
tag = codex.draw.node( 'H2', [], {} );
|
||||||
tag.dataset.headerData = 'H2';
|
tag.dataset.headerData = 'H2';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,120 +85,76 @@ var headerTool = {
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to render HTML block from JSON
|
* Method to render HTML block from JSON
|
||||||
*/
|
*/
|
||||||
render : function (data) {
|
header.render = function (data) {
|
||||||
|
|
||||||
return headerTool.make(data);
|
return this.make(data);
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to extract JSON data from HTML block
|
* Method to extract JSON data from HTML block
|
||||||
*/
|
*/
|
||||||
save : function (blockContent) {
|
header.save = function (blockContent) {
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
"heading-styles": blockContent.dataset.headerData,
|
"heading-styles": blockContent.dataset.headerData,
|
||||||
format:"html",
|
"format": "html",
|
||||||
text : null,
|
"text": blockContent.textContent
|
||||||
|
};
|
||||||
};
|
|
||||||
|
|
||||||
data.text = blockContent.textContent;
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
};
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block appending callback
|
* Block appending callback
|
||||||
*/
|
*/
|
||||||
appendCallback : function (argument) {
|
header.appendCallback = function (argument) {
|
||||||
|
|
||||||
console.log('header appended...');
|
console.log('header appended...');
|
||||||
|
};
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings panel content
|
* Settings panel content
|
||||||
* - - - - - - - - - - - - -
|
* - - - - - - - - - - - - -
|
||||||
* | настройки H1 H2 H3 |
|
* | настройки H1 H2 H3 |
|
||||||
* - - - - - - - - - - - - -
|
* - - - - - - - - - - - - -
|
||||||
* @return {Element} element contains all settings
|
* @return {Element} element contains all settings
|
||||||
*/
|
*/
|
||||||
makeSettings : function () {
|
header.makeSettings = function () {
|
||||||
|
|
||||||
var holder = document.createElement('DIV'),
|
var holder = codex.draw.node('DIV', ['ce_plugin_header--settings'], {} ),
|
||||||
types = {
|
types = {
|
||||||
H2: 'Заголовок раздела',
|
H2: 'Заголовок раздела',
|
||||||
H3: 'Подзаголовок',
|
H3: 'Подзаголовок',
|
||||||
H4: 'Заголовок 3-его уровня'
|
H4: 'Заголовок 3-его уровня'
|
||||||
},
|
},
|
||||||
selectTypeButton;
|
selectTypeButton;
|
||||||
|
|
||||||
/** Add holder classname */
|
|
||||||
holder.className = 'ce_plugin_header--settings';
|
|
||||||
|
|
||||||
/** Now add type selectors */
|
/** Now add type selectors */
|
||||||
for (var type in types){
|
for (var type in types){
|
||||||
|
|
||||||
selectTypeButton = document.createElement('SPAN');
|
selectTypeButton = codex.draw.node('SPAN', ['ce_plugin_header--select_button'], { textContent : types[type] });
|
||||||
|
methods.addSelectTypeClickListener(selectTypeButton, type);
|
||||||
selectTypeButton.textContent = types[type];
|
|
||||||
selectTypeButton.className = 'ce_plugin_header--select_button';
|
|
||||||
|
|
||||||
this.addSelectTypeClickListener(selectTypeButton, type);
|
|
||||||
|
|
||||||
holder.appendChild(selectTypeButton);
|
holder.appendChild(selectTypeButton);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return holder;
|
return holder;
|
||||||
|
};
|
||||||
|
|
||||||
},
|
header.validate = function(data) {
|
||||||
|
|
||||||
/**
|
if (data.text.trim() == '' || data['heading-styles'].trim() == '')
|
||||||
* Binds click event to passed button
|
return;
|
||||||
*/
|
|
||||||
addSelectTypeClickListener : function (el, type) {
|
|
||||||
|
|
||||||
el.addEventListener('click', function () {
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
headerTool.selectTypeClicked(type);
|
return header;
|
||||||
|
|
||||||
}, false);
|
})({});
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replaces old header with new type
|
|
||||||
* @params {string} type - new header tagName: H1—H6
|
|
||||||
*/
|
|
||||||
selectTypeClicked : function (type) {
|
|
||||||
|
|
||||||
var old_header, new_header;
|
|
||||||
|
|
||||||
/** Now current header stored as a currentNode */
|
|
||||||
old_header = codex.content.currentNode.querySelector('[contentEditable]');
|
|
||||||
|
|
||||||
/** Making new header */
|
|
||||||
new_header = document.createElement(type);
|
|
||||||
|
|
||||||
new_header.innerHTML = old_header.innerHTML;
|
|
||||||
new_header.contentEditable = true;
|
|
||||||
new_header.setAttribute('data-placeholder', 'Heading');
|
|
||||||
new_header.classList.add('ce-header');
|
|
||||||
|
|
||||||
new_header.dataset.headerData = type;
|
|
||||||
|
|
||||||
codex.content.switchBlock(old_header, new_header, 'header');
|
|
||||||
|
|
||||||
/** Close settings after replacing */
|
|
||||||
codex.toolbar.settings.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
@ -4,72 +4,350 @@
|
||||||
*
|
*
|
||||||
* @version 1.1.3
|
* @version 1.1.3
|
||||||
*/
|
*/
|
||||||
var ceImage = {
|
|
||||||
|
|
||||||
elementClasses : {
|
var image = (function(image) {
|
||||||
|
|
||||||
|
var elementClasses = {
|
||||||
|
|
||||||
ce_image : 'ce-image',
|
ce_image : 'ce-image',
|
||||||
loading : 'ce-plugin-image__loader',
|
loading : 'ce-plugin-image__loader',
|
||||||
blockStretched: 'ce-block--stretched',
|
blockStretched: 'ce-block--stretched',
|
||||||
uploadedImage : {
|
uploadedImage : {
|
||||||
centered : 'ce-plugin-image__uploaded--centered',
|
centered : 'ce-plugin-image__uploaded--centered',
|
||||||
stretched : 'ce-plugin-image__uploaded--stretched',
|
stretched : 'ce-plugin-image__uploaded--stretched'
|
||||||
},
|
},
|
||||||
imageCaption : 'ce-plugin-image__caption',
|
imageCaption : 'ce-plugin-image__caption',
|
||||||
imageWrapper : 'ce-plugin-image__wrapper',
|
imageWrapper : 'ce-plugin-image__wrapper',
|
||||||
formHolder : 'ce-plugin-image__holder',
|
formHolder : 'ce-plugin-image__holder',
|
||||||
uploadButton : 'ce-plugin-image__button',
|
uploadButton : 'ce-plugin-image__button'
|
||||||
|
};
|
||||||
|
|
||||||
},
|
var holder = null;
|
||||||
|
|
||||||
holder : null,
|
|
||||||
|
|
||||||
/** Default path to redactors images */
|
/** Default path to redactors images */
|
||||||
path : '/upload/redactor_images/',
|
var path = '/upload/redactor_images/';
|
||||||
|
|
||||||
make : function ( data ) {
|
var ui = {
|
||||||
|
|
||||||
var holder;
|
holder : function(){
|
||||||
|
|
||||||
|
var element = document.createElement('DIV');
|
||||||
|
|
||||||
|
element.classList.add(elementClasses.formHolder);
|
||||||
|
element.classList.add(elementClasses.ce_image);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadButton : function(){
|
||||||
|
|
||||||
|
var button = document.createElement('SPAN');
|
||||||
|
|
||||||
|
button.classList.add(elementClasses.uploadButton);
|
||||||
|
|
||||||
|
button.innerHTML = '<i class="ce-icon-picture"> </i>';
|
||||||
|
button.innerHTML += 'Загрузить фотографию';
|
||||||
|
|
||||||
|
return button;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} source - file path
|
||||||
|
* @param {string} style - css class
|
||||||
|
* @return {object} image - document IMG tag
|
||||||
|
*/
|
||||||
|
image : function(source, style) {
|
||||||
|
|
||||||
|
var image = document.createElement('IMG');
|
||||||
|
|
||||||
|
image.classList.add(style);
|
||||||
|
|
||||||
|
image.src = source;
|
||||||
|
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
|
||||||
|
wrapper : function() {
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add(elementClasses.imageWrapper);
|
||||||
|
|
||||||
|
return div;
|
||||||
|
},
|
||||||
|
|
||||||
|
caption : function() {
|
||||||
|
|
||||||
|
var div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add(elementClasses.imageCaption);
|
||||||
|
div.contentEditable = true;
|
||||||
|
|
||||||
|
return div;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Draws form for image upload
|
||||||
|
*/
|
||||||
|
makeForm : function() {
|
||||||
|
|
||||||
|
var holder = ui.holder(),
|
||||||
|
uploadButton = ui.uploadButton();
|
||||||
|
|
||||||
|
holder.appendChild(uploadButton);
|
||||||
|
|
||||||
|
uploadButton.addEventListener('click', methods.uploadButtonClicked, false );
|
||||||
|
|
||||||
|
holder = holder;
|
||||||
|
|
||||||
|
return holder;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @param {string} imageTypeClass - plugin's style
|
||||||
|
* @param {boolean} stretched - stretched or not
|
||||||
|
* @return wrapped block with image and caption
|
||||||
|
*/
|
||||||
|
makeImage : function(data, imageTypeClass, stretched) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ui.image(file, imageTypeClass),
|
||||||
|
caption = ui.caption(),
|
||||||
|
wrapper = ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = stretched;
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTML} data - Rendered block with image
|
||||||
|
*/
|
||||||
|
getImage : function(data) {
|
||||||
|
|
||||||
|
var image = data.querySelector('.' + elementClasses.uploadedImage.centered) ||
|
||||||
|
data.querySelector('.' + elementClasses.uploadedImage.stretched);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @deprecated
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @return wrapped block with image and caption
|
||||||
|
*/
|
||||||
|
centeredImage : function(data) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
image = ui.image(file, elementClasses.uploadedImage.centered),
|
||||||
|
caption = ui.caption(),
|
||||||
|
wrapper = ui.wrapper();
|
||||||
|
|
||||||
|
caption.textContent = text;
|
||||||
|
|
||||||
|
wrapper.dataset.stretched = 'false';
|
||||||
|
|
||||||
|
/** Appeding to the wrapper */
|
||||||
|
wrapper.appendChild(image);
|
||||||
|
wrapper.appendChild(caption);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wraps image and caption
|
||||||
|
* @deprecated
|
||||||
|
* @param {object} data - image information
|
||||||
|
* @return stretched image
|
||||||
|
*/
|
||||||
|
stretchedImage : function(data) {
|
||||||
|
|
||||||
|
var file = data.file.url,
|
||||||
|
text = data.caption,
|
||||||
|
type = data.type,
|
||||||
|
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);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
uploadButtonClicked : function(event) {
|
||||||
|
|
||||||
|
/** Define callbacks */
|
||||||
|
codex.transport.selectAndUpload({
|
||||||
|
beforeSend: photoUploadingCallbacks.beforeSend,
|
||||||
|
success: photoUploadingCallbacks.success,
|
||||||
|
error: photoUploadingCallbacks.error
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
addSelectTypeClickListener : function(el, type) {
|
||||||
|
|
||||||
|
el.addEventListener('click', function() {
|
||||||
|
|
||||||
|
methods.selectTypeClicked(type);
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
selectTypeClicked : function(type) {
|
||||||
|
|
||||||
|
var current = codex.content.currentNode,
|
||||||
|
blockContent = current.childNodes[0],
|
||||||
|
image = ui.getImage(current),
|
||||||
|
wrapper = current.querySelector('.' + elementClasses.imageWrapper);
|
||||||
|
|
||||||
|
/** Clear classList */
|
||||||
|
current.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);
|
||||||
|
|
||||||
|
blockContent.classList.add(elementClasses.blockStretched);
|
||||||
|
|
||||||
|
/** Setting dataset for saver */
|
||||||
|
wrapper.dataset.stretched = true;
|
||||||
|
|
||||||
|
} else if (type === 'centered') {
|
||||||
|
|
||||||
|
image.classList.add(elementClasses.uploadedImage.centered);
|
||||||
|
|
||||||
|
blockContent.classList.remove(elementClasses.blockStretched);
|
||||||
|
|
||||||
|
/** Setting dataset for saver */
|
||||||
|
wrapper.dataset.stretched = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
image.make = function ( data ) {
|
||||||
|
|
||||||
|
var imageHolder;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
||||||
if ( data.isStretch !== 'true') {
|
if ( data.isStretch !== 'true') {
|
||||||
holder = ceImage.ui.makeImage(data, ceImage.elementClasses.uploadedImage.centered, 'false');
|
imageHolder = ui.makeImage(data, elementClasses.uploadedImage.centered, 'false');
|
||||||
} else {
|
} else {
|
||||||
holder = ceImage.ui.makeImage(data, ceImage.elementClasses.uploadedImage.stretched, 'true');
|
imageHolder = ui.makeImage(data, elementClasses.uploadedImage.stretched, 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
return holder;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
holder = ceImage.ui.makeForm();
|
imageHolder = ui.makeForm();
|
||||||
|
|
||||||
return holder;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
holder = imageHolder;
|
||||||
|
return imageHolder;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this tool works when tool is clicked in toolbox
|
* this tool works when tool is clicked in toolbox
|
||||||
*/
|
*/
|
||||||
appendCallback : function(event) {
|
image.appendCallback = function(event) {
|
||||||
|
|
||||||
/** Upload image and call success callback*/
|
/** Upload image and call success callback*/
|
||||||
ceImage.uploadButtonClicked(event);
|
methods.uploadButtonClicked(event);
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings panel content
|
* Settings panel content
|
||||||
* @return {Element} element contains all settings
|
* @return {Element} element contains all settings
|
||||||
*/
|
*/
|
||||||
makeSettings : function () {
|
image.makeSettings = function () {
|
||||||
|
|
||||||
var holder = document.createElement('DIV'),
|
var holder = document.createElement('DIV'),
|
||||||
types = {
|
types = {
|
||||||
centered : 'По центру',
|
centered : 'По центру',
|
||||||
stretched : 'На всю ширину',
|
stretched : 'На всю ширину'
|
||||||
},
|
},
|
||||||
selectTypeButton;
|
selectTypeButton;
|
||||||
|
|
||||||
/** Add holder classname */
|
/** Add holder classname */
|
||||||
|
@ -83,7 +361,7 @@ var ceImage = {
|
||||||
selectTypeButton.textContent = types[type];
|
selectTypeButton.textContent = types[type];
|
||||||
selectTypeButton.className = 'ce_plugin_image--select_button';
|
selectTypeButton.className = 'ce_plugin_image--select_button';
|
||||||
|
|
||||||
this.addSelectTypeClickListener(selectTypeButton, type);
|
methods.addSelectTypeClickListener(selectTypeButton, type);
|
||||||
|
|
||||||
holder.appendChild(selectTypeButton);
|
holder.appendChild(selectTypeButton);
|
||||||
|
|
||||||
|
@ -91,62 +369,18 @@ var ceImage = {
|
||||||
|
|
||||||
return holder;
|
return holder;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
addSelectTypeClickListener : function(el, type) {
|
image.render = function( data ) {
|
||||||
|
|
||||||
el.addEventListener('click', function() {
|
return image.make(data);
|
||||||
|
};
|
||||||
|
|
||||||
ceImage.selectTypeClicked(type);
|
image.save = function ( block ) {
|
||||||
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
selectTypeClicked : function(type) {
|
|
||||||
|
|
||||||
var current = codex.content.currentNode,
|
|
||||||
blockContent = current.childNodes[0],
|
|
||||||
image = ceImage.ui.getImage(current),
|
|
||||||
wrapper = current.querySelector('.' + ceImage.elementClasses.imageWrapper);
|
|
||||||
|
|
||||||
/** Clear classList */
|
|
||||||
current.className = '';
|
|
||||||
image.className = '';
|
|
||||||
|
|
||||||
/** Add important first-level class ce_block */
|
|
||||||
current.classList.add(codex.ui.className.BLOCK_CLASSNAME);
|
|
||||||
|
|
||||||
if (type === 'stretched') {
|
|
||||||
|
|
||||||
image.classList.add(ceImage.elementClasses.uploadedImage.stretched);
|
|
||||||
|
|
||||||
blockContent.classList.add(ceImage.elementClasses.blockStretched);
|
|
||||||
|
|
||||||
/** Setting dataset for saver */
|
|
||||||
wrapper.dataset.stretched = true;
|
|
||||||
|
|
||||||
} else if (type === 'centered') {
|
|
||||||
|
|
||||||
image.classList.add(ceImage.elementClasses.uploadedImage.centered);
|
|
||||||
|
|
||||||
blockContent.classList.remove(ceImage.elementClasses.blockStretched);
|
|
||||||
|
|
||||||
/** Setting dataset for saver */
|
|
||||||
wrapper.dataset.stretched = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function( data ) {
|
|
||||||
|
|
||||||
return this.make(data);
|
|
||||||
},
|
|
||||||
|
|
||||||
save : function ( block ) {
|
|
||||||
|
|
||||||
var content = block,
|
var content = block,
|
||||||
image = ceImage.ui.getImage(content),
|
image = ui.getImage(content),
|
||||||
caption = content.querySelector('.' + ceImage.elementClasses.imageCaption);
|
caption = content.querySelector('.' + elementClasses.imageCaption);
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
background : false,
|
background : false,
|
||||||
|
@ -157,246 +391,15 @@ var ceImage = {
|
||||||
bigUrl : null,
|
bigUrl : null,
|
||||||
width : image.width,
|
width : image.width,
|
||||||
height : image.height,
|
height : image.height,
|
||||||
additionalData :null,
|
additionalData :null
|
||||||
},
|
},
|
||||||
caption : caption.textContent,
|
caption : caption.textContent,
|
||||||
cover : null,
|
cover : null
|
||||||
};
|
};
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
};
|
||||||
|
|
||||||
uploadButtonClicked : function(event) {
|
return image;
|
||||||
|
|
||||||
var beforeSend = ceImage.photoUploadingCallbacks.beforeSend,
|
})({});
|
||||||
success = ceImage.photoUploadingCallbacks.success,
|
|
||||||
error = ceImage.photoUploadingCallbacks.error;
|
|
||||||
|
|
||||||
/** Define callbacks */
|
|
||||||
codex.transport.selectAndUpload({
|
|
||||||
beforeSend,
|
|
||||||
success,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
ceImage.ui = {
|
|
||||||
|
|
||||||
holder : function(){
|
|
||||||
|
|
||||||
var element = document.createElement('DIV');
|
|
||||||
|
|
||||||
element.classList.add(ceImage.elementClasses.formHolder);
|
|
||||||
element.classList.add(ceImage.elementClasses.ce_image);
|
|
||||||
|
|
||||||
return element;
|
|
||||||
},
|
|
||||||
|
|
||||||
uploadButton : function(){
|
|
||||||
|
|
||||||
var button = document.createElement('SPAN');
|
|
||||||
|
|
||||||
button.classList.add(ceImage.elementClasses.uploadButton);
|
|
||||||
|
|
||||||
button.innerHTML = '<i class="ce-icon-picture"> </i>';
|
|
||||||
button.innerHTML += 'Загрузить фотографию';
|
|
||||||
|
|
||||||
return button;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} source - file path
|
|
||||||
* @param {string} style - css class
|
|
||||||
* @return {object} image - document IMG tag
|
|
||||||
*/
|
|
||||||
image : function(source, style) {
|
|
||||||
|
|
||||||
var image = document.createElement('IMG');
|
|
||||||
|
|
||||||
image.classList.add(style);
|
|
||||||
|
|
||||||
image.src = source;
|
|
||||||
|
|
||||||
return image;
|
|
||||||
},
|
|
||||||
|
|
||||||
wrapper : function() {
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
|
||||||
|
|
||||||
div.classList.add(ceImage.elementClasses.imageWrapper);
|
|
||||||
|
|
||||||
return div;
|
|
||||||
},
|
|
||||||
|
|
||||||
caption : function() {
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
|
||||||
|
|
||||||
div.classList.add(ceImage.elementClasses.imageCaption);
|
|
||||||
div.contentEditable = true;
|
|
||||||
|
|
||||||
return div;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Draws form for image upload
|
|
||||||
*/
|
|
||||||
makeForm : function() {
|
|
||||||
|
|
||||||
var holder = ceImage.ui.holder(),
|
|
||||||
uploadButton = ceImage.ui.uploadButton();
|
|
||||||
|
|
||||||
holder.appendChild(uploadButton);
|
|
||||||
|
|
||||||
uploadButton.addEventListener('click', ceImage.uploadButtonClicked, false );
|
|
||||||
|
|
||||||
ceImage.holder = holder;
|
|
||||||
|
|
||||||
return holder;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wraps image and caption
|
|
||||||
* @param {object} data - image information
|
|
||||||
* @param {string} imageTypeClass - plugin's style
|
|
||||||
* @param {boolean} stretched - stretched or not
|
|
||||||
* @return wrapped block with image and caption
|
|
||||||
*/
|
|
||||||
makeImage : function(data, imageTypeClass, stretched) {
|
|
||||||
|
|
||||||
var file = data.file.url,
|
|
||||||
text = data.caption,
|
|
||||||
type = data.type,
|
|
||||||
image = ceImage.ui.image(file, imageTypeClass),
|
|
||||||
caption = ceImage.ui.caption(),
|
|
||||||
wrapper = ceImage.ui.wrapper();
|
|
||||||
|
|
||||||
caption.textContent = text;
|
|
||||||
|
|
||||||
wrapper.dataset.stretched = stretched;
|
|
||||||
/** Appeding to the wrapper */
|
|
||||||
wrapper.appendChild(image);
|
|
||||||
wrapper.appendChild(caption);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {HTML} data - Rendered block with image
|
|
||||||
*/
|
|
||||||
getImage : function(data) {
|
|
||||||
|
|
||||||
var image = data.querySelector('.' + ceImage.elementClasses.uploadedImage.centered) ||
|
|
||||||
data.querySelector('.' + ceImage.elementClasses.uploadedImage.stretched);
|
|
||||||
|
|
||||||
return image;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wraps image and caption
|
|
||||||
* @deprecated
|
|
||||||
* @param {object} data - image information
|
|
||||||
* @return wrapped block with image and caption
|
|
||||||
*/
|
|
||||||
centeredImage : function(data) {
|
|
||||||
|
|
||||||
var file = data.file.url,
|
|
||||||
text = data.caption,
|
|
||||||
type = data.type,
|
|
||||||
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.centered),
|
|
||||||
caption = ceImage.ui.caption(),
|
|
||||||
wrapper = ceImage.ui.wrapper();
|
|
||||||
|
|
||||||
caption.textContent = text;
|
|
||||||
|
|
||||||
wrapper.dataset.stretched = 'false';
|
|
||||||
|
|
||||||
/** Appeding to the wrapper */
|
|
||||||
wrapper.appendChild(image);
|
|
||||||
wrapper.appendChild(caption);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wraps image and caption
|
|
||||||
* @deprecated
|
|
||||||
* @param {object} data - image information
|
|
||||||
* @return stretched image
|
|
||||||
*/
|
|
||||||
stretchedImage : function(data) {
|
|
||||||
|
|
||||||
var file = data.file.url,
|
|
||||||
text = data.caption,
|
|
||||||
type = data.type,
|
|
||||||
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.stretched),
|
|
||||||
caption = ceImage.ui.caption(),
|
|
||||||
wrapper = ceImage.ui.wrapper();
|
|
||||||
|
|
||||||
caption.textContent = text;
|
|
||||||
|
|
||||||
wrapper.dataset.stretched = 'true';
|
|
||||||
/** Appeding to the wrapper */
|
|
||||||
wrapper.appendChild(image);
|
|
||||||
wrapper.appendChild(caption);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
ceImage.photoUploadingCallbacks = {
|
|
||||||
|
|
||||||
/** Before sending ajax request */
|
|
||||||
beforeSend : function() {
|
|
||||||
ceImage.holder.classList.add(ceImage.elementClasses.loading);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Photo was uploaded successfully */
|
|
||||||
success : function(result) {
|
|
||||||
|
|
||||||
var parsed = JSON.parse(result),
|
|
||||||
data,
|
|
||||||
currentBlock = codex.content.currentNode,
|
|
||||||
image;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preparing {Object} data to draw an image
|
|
||||||
* @uses ceImage.make method
|
|
||||||
*/
|
|
||||||
data = {
|
|
||||||
background : false,
|
|
||||||
border : false,
|
|
||||||
isStretch : false,
|
|
||||||
file : {
|
|
||||||
url : ceImage.path + 'o_' + parsed.filename,
|
|
||||||
bigUrl : null,
|
|
||||||
width : null,
|
|
||||||
height : null,
|
|
||||||
additionalData : null,
|
|
||||||
},
|
|
||||||
caption : '',
|
|
||||||
cover : null,
|
|
||||||
};
|
|
||||||
|
|
||||||
image = ceImage.make(data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If current block is empty, we can replace it to uploaded image
|
|
||||||
* Or insert new block
|
|
||||||
*/
|
|
||||||
codex.content.switchBlock(ceImage.holder, image, '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();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -1,106 +0,0 @@
|
||||||
/**
|
|
||||||
* Image plugin for codex-editor
|
|
||||||
* @author CodeX Team <team@ifmo.su>
|
|
||||||
*
|
|
||||||
* @version 0.0.1
|
|
||||||
*/
|
|
||||||
.ce-image {
|
|
||||||
max-width: 700px;
|
|
||||||
margin: 20px auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ce-plugin-image__holder{
|
|
||||||
position: relative;
|
|
||||||
background: #FEFEFE;
|
|
||||||
border: 2px dashed #E8EBF5;
|
|
||||||
border-radius: 55px;
|
|
||||||
margin: 30px 0;
|
|
||||||
padding: 30px 110px 30px 40px;
|
|
||||||
}
|
|
||||||
.ce-plugin-image__holder input{
|
|
||||||
border: 0;
|
|
||||||
background: transparent;
|
|
||||||
outline: none;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
font-size: 1.2em;
|
|
||||||
color: #A5ABBC;
|
|
||||||
}
|
|
||||||
/* Placeholder color for Chrome */
|
|
||||||
.ce-plugin-image__holder input::-webkit-input-placeholder {
|
|
||||||
color: #A5ABBC;
|
|
||||||
}
|
|
||||||
/* Placeholder color for IE 10+ */
|
|
||||||
.ce-plugin-image__holder input:-ms-input-placeholder {
|
|
||||||
color: #A5ABBC;
|
|
||||||
}
|
|
||||||
/* Placeholder color for Firefox 19+ */
|
|
||||||
.ce-plugin-image__holder input::-moz-placeholder {
|
|
||||||
color: #A5ABBC;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.ce-plugin-image__button{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
right: 40px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: "codex_editor";
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: #8990AA;
|
|
||||||
}
|
|
||||||
.ce-plugin-image__button:hover{
|
|
||||||
color: #393F52;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ce-plugin-image__wrapper {
|
|
||||||
margin : 3em 0;
|
|
||||||
}
|
|
||||||
.ce-plugin-image__uploaded--centered {
|
|
||||||
max-width: 700px;
|
|
||||||
display:block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ce-plugin-image__uploaded--stretched {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ce-plugin-image__firstlevel--stretch {
|
|
||||||
margin: 0 !important;
|
|
||||||
max-width: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ce-plugin-image__caption {
|
|
||||||
max-width: 700px;
|
|
||||||
margin: 1em auto;
|
|
||||||
text-align: center;
|
|
||||||
color: #898a8c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ce-plugin-image__caption:empty::before {
|
|
||||||
content: 'Введите подпись';
|
|
||||||
text-align: center;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #a1a5b3;;
|
|
||||||
opacity: .9;
|
|
||||||
transition: opacity 200ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ce-plugin-image__caption:focus::before {
|
|
||||||
opacity: .1;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Settings */
|
|
||||||
.ce_plugin_image--settings{
|
|
||||||
white-space: nowrap;
|
|
||||||
/*padding-right: 10px; */
|
|
||||||
}
|
|
||||||
.ce_plugin_image--select_button{
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 15px;
|
|
||||||
color: #70a1ff;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.ce_plugin_image--select_button:hover{
|
|
||||||
color: #8da8dc;
|
|
||||||
}
|
|
|
@ -1,446 +0,0 @@
|
||||||
/**
|
|
||||||
* Image plugin for codex-editor
|
|
||||||
* @author CodeX Team <team@ifmo.su>
|
|
||||||
*
|
|
||||||
* @version 0.0.2
|
|
||||||
*/
|
|
||||||
var ceImage = {
|
|
||||||
|
|
||||||
elementClasses : {
|
|
||||||
|
|
||||||
ce_image : 'ce-image',
|
|
||||||
uploadedImage : {
|
|
||||||
centered : 'ce-plugin-image__uploaded--centered',
|
|
||||||
stretched : 'ce-plugin-image__uploaded--stretched',
|
|
||||||
},
|
|
||||||
stretch : 'ce_block--stretched',
|
|
||||||
imageCaption : 'ce-plugin-image__caption',
|
|
||||||
imageWrapper : 'ce-plugin-image__wrapper',
|
|
||||||
formHolder : 'ce-plugin-image__holder',
|
|
||||||
uploadButton : 'ce-plugin-image__button',
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Default path to redactors images */
|
|
||||||
path : '/upload/redactor_images/',
|
|
||||||
|
|
||||||
make : function ( data ) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we can't find image or we've got some problems with image path, we show plugin uploader
|
|
||||||
*/
|
|
||||||
if (!data || !data.file.url) {
|
|
||||||
|
|
||||||
holder = ceImage.ui.formView();
|
|
||||||
holder.classList.add(ceImage.elementClasses.ce_image);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if ( data.isStretch !== 'true') {
|
|
||||||
holder = ceImage.ui.imageView(data, ceImage.elementClasses.uploadedImage.centered, 'false');
|
|
||||||
} else {
|
|
||||||
holder = ceImage.ui.imageView(data, ceImage.elementClasses.uploadedImage.stretched, 'true');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return holder;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Settings panel content
|
|
||||||
* @return {Element} element contains all settings
|
|
||||||
*/
|
|
||||||
makeSettings : function () {
|
|
||||||
|
|
||||||
var holder = document.createElement('DIV'),
|
|
||||||
caption = document.createElement('SPAN'),
|
|
||||||
types = {
|
|
||||||
centered : 'По центру',
|
|
||||||
stretched : 'На всю ширину',
|
|
||||||
},
|
|
||||||
selectTypeButton;
|
|
||||||
|
|
||||||
/** Add holder classname */
|
|
||||||
holder.className = 'ce_plugin_image--settings';
|
|
||||||
|
|
||||||
/** Add settings helper caption */
|
|
||||||
caption.textContent = 'Настройки плагина';
|
|
||||||
caption.className = 'ce_plugin_image--caption';
|
|
||||||
|
|
||||||
holder.appendChild(caption);
|
|
||||||
|
|
||||||
/** Now add type selectors */
|
|
||||||
for (var type in types){
|
|
||||||
|
|
||||||
selectTypeButton = document.createElement('SPAN');
|
|
||||||
|
|
||||||
selectTypeButton.textContent = types[type];
|
|
||||||
selectTypeButton.className = 'ce_plugin_image--select_button';
|
|
||||||
|
|
||||||
this.addSelectTypeClickListener(selectTypeButton, type);
|
|
||||||
|
|
||||||
holder.appendChild(selectTypeButton);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return holder;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
addSelectTypeClickListener : function(el, type) {
|
|
||||||
|
|
||||||
el.addEventListener('click', function() {
|
|
||||||
|
|
||||||
ceImage.selectTypeClicked(type);
|
|
||||||
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
selectTypeClicked : function(type) {
|
|
||||||
|
|
||||||
var current = cEditor.content.currentNode,
|
|
||||||
image = ceImage.ui.getImage(current),
|
|
||||||
wrapper = current.querySelector('.' + ceImage.elementClasses.imageWrapper);
|
|
||||||
|
|
||||||
/** Clear classList */
|
|
||||||
current.className = '';
|
|
||||||
image.className = '';
|
|
||||||
|
|
||||||
/** Add important first-level class ce_block */
|
|
||||||
current.classList.add(cEditor.ui.className.BLOCK_CLASSNAME);
|
|
||||||
|
|
||||||
if (type === 'stretched') {
|
|
||||||
|
|
||||||
image.classList.add(ceImage.elementClasses.uploadedImage.stretched);
|
|
||||||
current.classList.add(ceImage.elementClasses.stretch);
|
|
||||||
|
|
||||||
/** Setting dataset for saver */
|
|
||||||
wrapper.dataset.stretched = true;
|
|
||||||
|
|
||||||
} else if (type === 'centered') {
|
|
||||||
|
|
||||||
image.classList.add(ceImage.elementClasses.uploadedImage.centered);
|
|
||||||
|
|
||||||
/** Setting dataset for saver */
|
|
||||||
wrapper.dataset.stretched = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function( data ) {
|
|
||||||
|
|
||||||
return this.make(data);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
save : function ( block ) {
|
|
||||||
|
|
||||||
var data = block[0],
|
|
||||||
image = ceImage.ui.getImage(data),
|
|
||||||
caption = data.querySelector('.' + ceImage.elementClasses.imageCaption);
|
|
||||||
|
|
||||||
var json = {
|
|
||||||
type : 'image',
|
|
||||||
data : {
|
|
||||||
background : false,
|
|
||||||
border : false,
|
|
||||||
isStretch : data.dataset.stretched,
|
|
||||||
file : {
|
|
||||||
url : image.src,
|
|
||||||
bigUrl : null,
|
|
||||||
width : image.width,
|
|
||||||
height : image.height,
|
|
||||||
additionalData :null,
|
|
||||||
},
|
|
||||||
caption : caption.textContent,
|
|
||||||
cover : null,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return json;
|
|
||||||
},
|
|
||||||
|
|
||||||
uploadButtonClicked : function(event) {
|
|
||||||
|
|
||||||
var success = ceImage.photoUploadingCallbacks.success,
|
|
||||||
error = ceImage.photoUploadingCallbacks.error;
|
|
||||||
|
|
||||||
/** Define callbacks */
|
|
||||||
cEditor.transport.selectAndUpload({
|
|
||||||
success,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
pastedImageURL : function(event) {
|
|
||||||
|
|
||||||
var clipboardData = event.clipboardData || window.clipboardData,
|
|
||||||
pastedData = clipboardData.getData('Text'),
|
|
||||||
block = event.target.parentNode;
|
|
||||||
|
|
||||||
ceImage.renderURL(pastedData, block);
|
|
||||||
|
|
||||||
event.stopPropagation();
|
|
||||||
},
|
|
||||||
|
|
||||||
renderURL : function(pastedData, block) {
|
|
||||||
|
|
||||||
Promise.resolve()
|
|
||||||
|
|
||||||
.then(function() {
|
|
||||||
return pastedData;
|
|
||||||
})
|
|
||||||
|
|
||||||
.then(ceImage.urlify)
|
|
||||||
|
|
||||||
.then(function(url) {
|
|
||||||
|
|
||||||
/* Show loader gif **/
|
|
||||||
// block.classList.add(linkTool.elementClasses.loader);
|
|
||||||
|
|
||||||
return fetch('/editor/transport?files=' + encodeURI(url))
|
|
||||||
})
|
|
||||||
|
|
||||||
.then(function(response) {
|
|
||||||
console.log(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
urlify : function (text) {
|
|
||||||
|
|
||||||
var urlRegex = /(https?:\/\/\S+)/g;
|
|
||||||
|
|
||||||
var links = text.match(urlRegex);
|
|
||||||
|
|
||||||
if (links) {
|
|
||||||
console.log(links[0]);
|
|
||||||
return links[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.reject(Error("Url is not matched"));
|
|
||||||
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
ceImage.ui = {
|
|
||||||
|
|
||||||
holder : function(){
|
|
||||||
|
|
||||||
var element = document.createElement('DIV');
|
|
||||||
|
|
||||||
element.classList.add(ceImage.elementClasses.formHolder);
|
|
||||||
|
|
||||||
return element;
|
|
||||||
},
|
|
||||||
|
|
||||||
input : function(){
|
|
||||||
|
|
||||||
var input = document.createElement('INPUT');
|
|
||||||
|
|
||||||
return input;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
uploadButton : function(){
|
|
||||||
|
|
||||||
var button = document.createElement('SPAN');
|
|
||||||
|
|
||||||
button.classList.add(ceImage.elementClasses.uploadButton);
|
|
||||||
|
|
||||||
button.innerHTML = '<i class="ce-icon-picture"></i>';
|
|
||||||
|
|
||||||
return button;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} source - file path
|
|
||||||
* @param {string} style - css class
|
|
||||||
* @return {object} image - document IMG tag
|
|
||||||
*/
|
|
||||||
image : function(source, style) {
|
|
||||||
|
|
||||||
var image = document.createElement('IMG');
|
|
||||||
|
|
||||||
image.classList.add(style);
|
|
||||||
|
|
||||||
image.src = source;
|
|
||||||
|
|
||||||
return image;
|
|
||||||
},
|
|
||||||
|
|
||||||
wrapper : function() {
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
|
||||||
|
|
||||||
div.classList.add(ceImage.elementClasses.imageWrapper);
|
|
||||||
|
|
||||||
return div;
|
|
||||||
},
|
|
||||||
|
|
||||||
caption : function() {
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
|
||||||
|
|
||||||
div.classList.add(ceImage.elementClasses.imageCaption);
|
|
||||||
div.contentEditable = true;
|
|
||||||
|
|
||||||
return div;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draws form for image upload
|
|
||||||
*/
|
|
||||||
formView : function() {
|
|
||||||
|
|
||||||
var holder = ceImage.ui.holder(),
|
|
||||||
uploadButton = ceImage.ui.uploadButton(),
|
|
||||||
input = ceImage.ui.input();
|
|
||||||
|
|
||||||
input.placeholder = 'Paste image URL or file';
|
|
||||||
|
|
||||||
holder.appendChild(uploadButton);
|
|
||||||
holder.appendChild(input);
|
|
||||||
|
|
||||||
input.addEventListener('paste', ceImage.pastedImageURL, false);
|
|
||||||
|
|
||||||
uploadButton.addEventListener('click', ceImage.uploadButtonClicked, false );
|
|
||||||
|
|
||||||
return holder;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wraps image and caption
|
|
||||||
* @param {object} data - image information
|
|
||||||
* @param {string} imageTypeClass - plugin's style
|
|
||||||
* @param {boolean} stretched - stretched or not
|
|
||||||
* @return wrapped block with image and caption
|
|
||||||
*/
|
|
||||||
imageView : function(data, imageTypeClass, stretched) {
|
|
||||||
|
|
||||||
var file = data.file.url,
|
|
||||||
text = data.caption,
|
|
||||||
type = data.type,
|
|
||||||
image = ceImage.ui.image(file, imageTypeClass),
|
|
||||||
caption = ceImage.ui.caption(),
|
|
||||||
wrapper = ceImage.ui.wrapper();
|
|
||||||
|
|
||||||
caption.textContent = text;
|
|
||||||
|
|
||||||
wrapper.dataset.stretched = stretched,
|
|
||||||
/** Appeding to the wrapper */
|
|
||||||
wrapper.appendChild(image);
|
|
||||||
wrapper.appendChild(caption);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {HTML} data - Rendered block with image
|
|
||||||
*/
|
|
||||||
getImage : function(data) {
|
|
||||||
|
|
||||||
var image = data.querySelector('.' + ceImage.elementClasses.uploadedImage.centered) ||
|
|
||||||
data.querySelector('.' + ceImage.elementClasses.uploadedImage.stretched);
|
|
||||||
|
|
||||||
return image;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wraps image and caption
|
|
||||||
* @deprecated
|
|
||||||
* @param {object} data - image information
|
|
||||||
* @return wrapped block with image and caption
|
|
||||||
*/
|
|
||||||
centeredImage : function(data) {
|
|
||||||
|
|
||||||
var file = data.file.url,
|
|
||||||
text = data.caption,
|
|
||||||
type = data.type,
|
|
||||||
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.centered),
|
|
||||||
caption = ceImage.ui.caption(),
|
|
||||||
wrapper = ceImage.ui.wrapper();
|
|
||||||
|
|
||||||
caption.textContent = text;
|
|
||||||
|
|
||||||
wrapper.dataset.stretched = 'false',
|
|
||||||
/** Appeding to the wrapper */
|
|
||||||
wrapper.appendChild(image);
|
|
||||||
wrapper.appendChild(caption);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wraps image and caption
|
|
||||||
* @deprecated
|
|
||||||
* @param {object} data - image information
|
|
||||||
* @return stretched image
|
|
||||||
*/
|
|
||||||
stretchedImage : function(data) {
|
|
||||||
|
|
||||||
var file = data.file.url,
|
|
||||||
text = data.caption,
|
|
||||||
type = data.type,
|
|
||||||
image = ceImage.ui.image(file, ceImage.elementClasses.uploadedImage.stretched),
|
|
||||||
caption = ceImage.ui.caption(),
|
|
||||||
wrapper = ceImage.ui.wrapper();
|
|
||||||
|
|
||||||
caption.textContent = text;
|
|
||||||
|
|
||||||
wrapper.dataset.stretched = 'true',
|
|
||||||
/** Appeding to the wrapper */
|
|
||||||
wrapper.appendChild(image);
|
|
||||||
wrapper.appendChild(caption);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
ceImage.photoUploadingCallbacks = {
|
|
||||||
|
|
||||||
/** Photo was uploaded successfully */
|
|
||||||
success : function(result) {
|
|
||||||
|
|
||||||
var parsed = JSON.parse(result),
|
|
||||||
data,
|
|
||||||
image;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preparing {Object} data to draw an image
|
|
||||||
* @uses ceImage.make method
|
|
||||||
*/
|
|
||||||
data = {
|
|
||||||
background : false,
|
|
||||||
border : false,
|
|
||||||
isStrech : false,
|
|
||||||
file : {
|
|
||||||
url : ceImage.path + 'o_' + parsed.filename,
|
|
||||||
bigUrl : null,
|
|
||||||
width : null,
|
|
||||||
height : null,
|
|
||||||
additionalData : null,
|
|
||||||
},
|
|
||||||
caption : '',
|
|
||||||
cover : null,
|
|
||||||
};
|
|
||||||
|
|
||||||
image = ceImage.make(data);
|
|
||||||
|
|
||||||
/** Replace form to image */
|
|
||||||
var form = cEditor.content.currentNode.querySelector('.' + ceImage.elementClasses.formHolder);
|
|
||||||
|
|
||||||
cEditor.content.switchBlock(form, image, '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');
|
|
||||||
cEditor.notifications.errorThrown();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -2,13 +2,53 @@
|
||||||
* Instagram plugin
|
* Instagram plugin
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
var instagramTool = {
|
var instagram = (function(instagram) {
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
render : function(content) {
|
||||||
|
|
||||||
|
codex.content.switchBlock(codex.content.currentNode, content, 'instagram');
|
||||||
|
|
||||||
|
var blockContent = codex.content.currentNode.childNodes[0];
|
||||||
|
blockContent.classList.add('instagram__loader');
|
||||||
|
|
||||||
|
window.instgrm.Embeds.process();
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
blockContent.classList.remove('instagram__loader');
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drawing html content.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @returns {Element} blockquote - HTML template for Instagram Embed JS
|
||||||
|
*/
|
||||||
|
instagramBlock : function(url) {
|
||||||
|
|
||||||
|
var blockquote = codex.draw.node('BLOCKQUOTE', 'instagram-media instagram', {}),
|
||||||
|
div = codex.draw.node('DIV', '', {}),
|
||||||
|
paragraph = codex.draw.node('P', 'ce-paste__instagram--p', {}),
|
||||||
|
anchor = codex.draw.node('A', '', { href : url });
|
||||||
|
|
||||||
|
blockquote.dataset.instgrmVersion = 4;
|
||||||
|
|
||||||
|
paragraph.appendChild(anchor);
|
||||||
|
div.appendChild(paragraph);
|
||||||
|
blockquote.appendChild(div);
|
||||||
|
|
||||||
|
return blockquote;
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare before usage
|
* Prepare before usage
|
||||||
* Load important scripts to render embed
|
* Load important scripts to render embed
|
||||||
*/
|
*/
|
||||||
prepare : function() {
|
instagram.prepare = function() {
|
||||||
|
|
||||||
var script = "//platform.instagram.com/en_US/embeds.js";
|
var script = "//platform.instagram.com/en_US/embeds.js";
|
||||||
|
|
||||||
|
@ -16,41 +56,44 @@ var instagramTool = {
|
||||||
* Load widget
|
* Load widget
|
||||||
*/
|
*/
|
||||||
codex.core.importScript(script, 'instagramAPI');
|
codex.core.importScript(script, 'instagramAPI');
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make instagram embed via Widgets method
|
* Make instagram embed via Widgets method
|
||||||
*/
|
*/
|
||||||
make : function(data, isInternal) {
|
instagram.make = function(data, isInternal) {
|
||||||
|
|
||||||
if (!data.instagram_url)
|
if (!data.instagram_url)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var block = instagramTool.content.instagramBlock(data.instagram_url);
|
var block = methods.instagramBlock(data.instagram_url);
|
||||||
|
|
||||||
if (isInternal) {
|
if (isInternal) {
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
|
||||||
/** Render block */
|
/** Render block */
|
||||||
instagramTool.content.render(block);
|
methods.render(block);
|
||||||
|
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isInternal) {
|
||||||
|
methods.render(block);
|
||||||
|
}
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
|
};
|
||||||
|
|
||||||
if (!isInternal) {
|
instagram.validate = function(data) {
|
||||||
instagramTool.content.render(block);
|
return true;
|
||||||
}
|
};
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saving JSON output.
|
* Saving JSON output.
|
||||||
* Upload data via ajax
|
* Upload data via ajax
|
||||||
*/
|
*/
|
||||||
save : function(blockContent) {
|
instagram.save = function(blockContent) {
|
||||||
|
|
||||||
var data;
|
var data;
|
||||||
|
|
||||||
|
@ -64,54 +107,25 @@ var instagramTool = {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
|
instagram.validate = function(data) {
|
||||||
|
|
||||||
|
var checkUrl = new RegExp("http?.+instagram.com\/p?.");
|
||||||
|
|
||||||
|
if (!data.instagram_url || checkUrl.exec(data.instagram_url).length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render data
|
* Render data
|
||||||
*/
|
*/
|
||||||
render : function(data) {
|
instagram.render = function(data) {
|
||||||
return instagramTool.make(data);
|
return instagram.make(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
};
|
return instagram;
|
||||||
|
|
||||||
instagramTool.content = {
|
})({});
|
||||||
|
|
||||||
render : function(content) {
|
|
||||||
|
|
||||||
codex.content.switchBlock(codex.content.currentNode, content, 'instagram');
|
|
||||||
|
|
||||||
var blockContent = codex.content.currentNode.childNodes[0];
|
|
||||||
blockContent.classList.add('instagram__loader');
|
|
||||||
|
|
||||||
window.instgrm.Embeds.process();
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
blockContent.classList.remove('instagram__loader');
|
|
||||||
}, 500);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Drawing html content.
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
* @returns {Element} blockquote - HTML template for Instagram Embed JS
|
|
||||||
*/
|
|
||||||
instagramBlock : function(url) {
|
|
||||||
|
|
||||||
var blockquote = codex.draw.node('BLOCKQUOTE', 'instagram-media instagram', {}),
|
|
||||||
div = codex.draw.node('DIV', '', {}),
|
|
||||||
paragraph = codex.draw.node('P', 'ce-paste__instagram--p', {}),
|
|
||||||
anchor = codex.draw.node('A', '', { href : url });
|
|
||||||
|
|
||||||
blockquote.dataset.instgrmVersion = 4;
|
|
||||||
|
|
||||||
paragraph.appendChild(anchor);
|
|
||||||
div.appendChild(paragraph);
|
|
||||||
blockquote.appendChild(div);
|
|
||||||
|
|
||||||
return blockquote;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
|
@ -5,304 +5,313 @@
|
||||||
/**
|
/**
|
||||||
* Link tool plugin
|
* Link tool plugin
|
||||||
*/
|
*/
|
||||||
var linkTool = {
|
|
||||||
|
|
||||||
defaultText : 'Insert link here ...',
|
var link = (function(link) {
|
||||||
ENTER_KEY : 13,
|
|
||||||
|
|
||||||
currentBlock : null,
|
var settings = {
|
||||||
currentInput : null,
|
defaultText : 'Insert link here ...',
|
||||||
elementClasses : {
|
ENTER_KEY : 13,
|
||||||
link : "tool-link-link",
|
currentBlock : null,
|
||||||
image : "tool-link-image",
|
currentInput : null,
|
||||||
title : "tool-link-title",
|
elementClasses : {
|
||||||
description : "tool-link-description",
|
link: "tool-link-link",
|
||||||
loader : "tool-link-loader",
|
image: "tool-link-image",
|
||||||
error : "tool-link-error"
|
title: "tool-link-title",
|
||||||
},
|
description: "tool-link-description",
|
||||||
|
loader: "tool-link-loader",
|
||||||
|
error: "tool-link-error"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var ui = {
|
||||||
|
|
||||||
|
make : function (json) {
|
||||||
|
|
||||||
|
var wrapper = ui.wrapper(),
|
||||||
|
siteImage = ui.image(json.image, settings.elementClasses.image),
|
||||||
|
siteTitle = ui.title(json.title),
|
||||||
|
siteDescription = ui.description(json.description),
|
||||||
|
siteLink = ui.link(json.url, json.url);
|
||||||
|
|
||||||
|
wrapper.appendChild(siteImage);
|
||||||
|
wrapper.appendChild(siteTitle);
|
||||||
|
wrapper.appendChild(siteLink);
|
||||||
|
wrapper.appendChild(siteDescription);
|
||||||
|
|
||||||
|
siteTitle.contentEditable = true;
|
||||||
|
siteDescription.contentEditable = true;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
mainBlock : function () {
|
||||||
|
|
||||||
|
var wrapper = document.createElement('div');
|
||||||
|
|
||||||
|
wrapper.classList.add("ceditor-tool-link");
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
input : function () {
|
||||||
|
|
||||||
|
var inputTag = document.createElement('input');
|
||||||
|
|
||||||
|
inputTag.classList.add("ceditor-tool-link-input");
|
||||||
|
|
||||||
|
inputTag.placeholder = settings.defaultText;
|
||||||
|
|
||||||
|
inputTag.contentEditable = false;
|
||||||
|
|
||||||
|
return inputTag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
wrapper : function () {
|
||||||
|
|
||||||
|
var wrapper = document.createElement('div');
|
||||||
|
|
||||||
|
wrapper.className += 'tool-link-panel clearfix';
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
image : function (imageSrc, imageClass) {
|
||||||
|
|
||||||
|
var imageTag = document.createElement('img');
|
||||||
|
|
||||||
|
imageTag.classList.add(imageClass);
|
||||||
|
|
||||||
|
imageTag.setAttribute('src', imageSrc);
|
||||||
|
|
||||||
|
return imageTag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
link : function (linkUrl, linkText) {
|
||||||
|
|
||||||
|
var linkTag = document.createElement('a');
|
||||||
|
|
||||||
|
linkTag.classList.add(settings.elementClasses.link);
|
||||||
|
|
||||||
|
linkTag.href = linkUrl;
|
||||||
|
|
||||||
|
linkTag.target = "_blank";
|
||||||
|
|
||||||
|
linkTag.innerText = linkText;
|
||||||
|
|
||||||
|
return linkTag;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
title : function (titleText) {
|
||||||
|
|
||||||
|
var titleTag = document.createElement('div');
|
||||||
|
|
||||||
|
titleTag.classList.add("tool-link-content", settings.elementClasses.title);
|
||||||
|
|
||||||
|
titleTag.innerHTML = titleText;
|
||||||
|
|
||||||
|
return titleTag;
|
||||||
|
},
|
||||||
|
|
||||||
|
description : function (descriptionText) {
|
||||||
|
|
||||||
|
var descriptionTag = document.createElement('div');
|
||||||
|
|
||||||
|
descriptionTag.classList.add("tool-link-content", settings.elementClasses.description);
|
||||||
|
|
||||||
|
descriptionTag.innerHTML = descriptionText;
|
||||||
|
|
||||||
|
return descriptionTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
blockPasteCallback : function (event) {
|
||||||
|
|
||||||
|
var clipboardData = event.clipboardData || window.clipboardData,
|
||||||
|
pastedData = clipboardData.getData('Text'),
|
||||||
|
block = event.target.parentNode;
|
||||||
|
|
||||||
|
methods.renderLink(pastedData, block);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
blockKeyDownCallback : function (event) {
|
||||||
|
|
||||||
|
var inputTag = event.target,
|
||||||
|
block = inputTag.parentNode,
|
||||||
|
url;
|
||||||
|
|
||||||
|
if ( block.classList.contains(settings.elementClasses.error) ) {
|
||||||
|
block.classList.remove(settings.elementClasses.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == settings.ENTER_KEY) {
|
||||||
|
|
||||||
|
url = inputTag.value;
|
||||||
|
|
||||||
|
methods.renderLink(url, block);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo move request-url to accepted settings
|
||||||
|
*/
|
||||||
|
renderLink : function (url, block) {
|
||||||
|
|
||||||
|
Promise.resolve()
|
||||||
|
|
||||||
|
.then(function () {
|
||||||
|
return methods.urlify(url);
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (url) {
|
||||||
|
|
||||||
|
/* Show loader gif **/
|
||||||
|
block.classList.add(settings.elementClasses.loader);
|
||||||
|
|
||||||
|
return fetch('/club/linkInfo?url=' + encodeURI(url));
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
|
||||||
|
if (response.status == "200"){
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return Error("Invalid response status: %o", response);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function (json) {
|
||||||
|
methods.composeLinkPreview(json, block);
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function(error) {
|
||||||
|
|
||||||
|
/* Hide loader gif **/
|
||||||
|
block.classList.remove(settings.elementClasses.loader);
|
||||||
|
|
||||||
|
block.classList.add(settings.elementClasses.error);
|
||||||
|
|
||||||
|
codex.core.log('Error while doing things with link paste: %o', 'error', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
urlify : function (text) {
|
||||||
|
|
||||||
|
var urlRegex = /(https?:\/\/\S+)/g;
|
||||||
|
|
||||||
|
var links = text.match(urlRegex);
|
||||||
|
|
||||||
|
if (links) {
|
||||||
|
return links[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(Error("Url is not matched"));
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
composeLinkPreview : function (json, currentBlock) {
|
||||||
|
|
||||||
|
if (json == {}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var previewBlock = ui.make(json);
|
||||||
|
|
||||||
|
settings.currentInput.remove();
|
||||||
|
|
||||||
|
currentBlock.appendChild(previewBlock);
|
||||||
|
|
||||||
|
currentBlock.classList.remove(settings.elementClasses.loader);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make initial header block
|
* Make initial header block
|
||||||
* @param {object} JSON with block data
|
* @param {object} JSON with block data
|
||||||
* @return {Element} element to append
|
* @return {Element} element to append
|
||||||
*/
|
*/
|
||||||
makeNewBlock : function (data) {
|
link.makeNewBlock = function (data) {
|
||||||
|
|
||||||
var wrapper = linkTool.ui.mainBlock(),
|
var wrapper = ui.mainBlock(),
|
||||||
tag = linkTool.ui.input();
|
tag = ui.input();
|
||||||
|
|
||||||
linkTool.currentInput = tag;
|
settings.currentInput = tag;
|
||||||
|
|
||||||
wrapper.appendChild(tag);
|
wrapper.appendChild(tag);
|
||||||
|
|
||||||
wrapper.classList.add('ce-link');
|
wrapper.classList.add('ce-link');
|
||||||
/**
|
/**
|
||||||
* Bind callbacks
|
* Bind callbacks
|
||||||
**/
|
**/
|
||||||
tag.addEventListener('paste', linkTool.blockPasteCallback, false);
|
tag.addEventListener('paste', methods.blockPasteCallback, false);
|
||||||
tag.addEventListener('keydown', linkTool.blockKeyDownCallback, false);
|
tag.addEventListener('keydown', methods.blockKeyDownCallback, false);
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to render HTML block from JSON
|
* Method to render HTML block from JSON
|
||||||
*/
|
*/
|
||||||
render : function (json) {
|
link.render = function (json) {
|
||||||
|
|
||||||
var block = linkTool.ui.mainBlock(),
|
var block = ui.mainBlock(),
|
||||||
tag = linkTool.ui.make(json);
|
tag = ui.make(json);
|
||||||
|
|
||||||
block.classList.add('ce-link');
|
block.classList.add('ce-link');
|
||||||
block.appendChild(tag);
|
block.appendChild(tag);
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
|
link.validate = function (data) {
|
||||||
|
|
||||||
|
if (data.url.trim() == '' || data.title.trim() == '' || data.description.trim() == '')
|
||||||
|
return;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to extract JSON data from HTML block
|
* Method to extract JSON data from HTML block
|
||||||
*/
|
*/
|
||||||
save : function (blockContent){
|
link.save = function (blockContent){
|
||||||
|
|
||||||
var linkElement = linkTool.elementClasses.link;
|
var linkElement = settings.elementClasses.link;
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
url : blockContent.querySelector("." + linkElement).href,
|
url : blockContent.querySelector("." + linkElement).href,
|
||||||
shortLink : blockContent.querySelector("." + linkElement).textContent,
|
shortLink : blockContent.querySelector("." + linkElement).textContent,
|
||||||
image : blockContent.querySelector("." + linkTool.elementClasses.image).src,
|
image : blockContent.querySelector("." + settings.elementClasses.image).src,
|
||||||
title : blockContent.querySelector("." + linkTool.elementClasses.title).textContent,
|
title : blockContent.querySelector("." + settings.elementClasses.title).textContent,
|
||||||
description : blockContent.querySelector("." + linkTool.elementClasses.description).textContent
|
description : blockContent.querySelector("." + settings.elementClasses.description).textContent
|
||||||
};
|
};
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
blockPasteCallback : function (event) {
|
return link;
|
||||||
|
|
||||||
var clipboardData = event.clipboardData || window.clipboardData,
|
})({});
|
||||||
pastedData = clipboardData.getData('Text'),
|
|
||||||
block = event.target.parentNode;
|
|
||||||
|
|
||||||
linkTool.renderLink(pastedData, block);
|
|
||||||
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
blockKeyDownCallback : function (event) {
|
|
||||||
|
|
||||||
var inputTag = event.target,
|
|
||||||
block = inputTag.parentNode,
|
|
||||||
url;
|
|
||||||
|
|
||||||
if ( block.classList.contains(linkTool.elementClasses.error) )
|
|
||||||
{
|
|
||||||
block.classList.remove(linkTool.elementClasses.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.keyCode == linkTool.ENTER_KEY) {
|
|
||||||
|
|
||||||
url = inputTag.value;
|
|
||||||
|
|
||||||
linkTool.renderLink(url, block);
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo move request-url to accepted settings
|
|
||||||
*/
|
|
||||||
renderLink : function (url, block) {
|
|
||||||
|
|
||||||
Promise.resolve()
|
|
||||||
|
|
||||||
.then(function () {
|
|
||||||
return linkTool.urlify(url);
|
|
||||||
})
|
|
||||||
|
|
||||||
.then(function (url) {
|
|
||||||
|
|
||||||
/* Show loader gif **/
|
|
||||||
block.classList.add(linkTool.elementClasses.loader);
|
|
||||||
|
|
||||||
return fetch('/club/linkInfo?url=' + encodeURI(url));
|
|
||||||
})
|
|
||||||
|
|
||||||
.then(function (response) {
|
|
||||||
|
|
||||||
if (response.status == "200"){
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return Error("Invalid response status: %o", response);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
.then(function (json) {
|
|
||||||
console.log(json);
|
|
||||||
linkTool.composeLinkPreview(json, block);
|
|
||||||
})
|
|
||||||
|
|
||||||
.catch(function(error) {
|
|
||||||
|
|
||||||
/* Hide loader gif **/
|
|
||||||
block.classList.remove(linkTool.elementClasses.loader);
|
|
||||||
|
|
||||||
block.classList.add(linkTool.elementClasses.error);
|
|
||||||
|
|
||||||
codex.core.log('Error while doing things with link paste: %o', 'error', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
urlify : function (text) {
|
|
||||||
|
|
||||||
var urlRegex = /(https?:\/\/\S+)/g;
|
|
||||||
|
|
||||||
var links = text.match(urlRegex);
|
|
||||||
|
|
||||||
if (links) {
|
|
||||||
return links[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.reject(Error("Url is not matched"));
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
composeLinkPreview : function (json, currentBlock) {
|
|
||||||
|
|
||||||
if (json == {}) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var previewBlock = linkTool.ui.make(json);
|
|
||||||
|
|
||||||
linkTool.currentInput.remove();
|
|
||||||
|
|
||||||
currentBlock.appendChild(previewBlock);
|
|
||||||
|
|
||||||
currentBlock.classList.remove(linkTool.elementClasses.loader);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
linkTool.ui = {
|
|
||||||
|
|
||||||
make : function (json) {
|
|
||||||
|
|
||||||
var wrapper = this.wrapper(),
|
|
||||||
siteImage = this.image(json.image, linkTool.elementClasses.image),
|
|
||||||
siteTitle = this.title(json.title),
|
|
||||||
siteDescription = this.description(json.description),
|
|
||||||
siteLink = this.link(json.url, json.url);
|
|
||||||
|
|
||||||
wrapper.appendChild(siteImage);
|
|
||||||
wrapper.appendChild(siteTitle);
|
|
||||||
wrapper.appendChild(siteLink);
|
|
||||||
wrapper.appendChild(siteDescription);
|
|
||||||
|
|
||||||
siteTitle.contentEditable = true;
|
|
||||||
siteDescription.contentEditable = true;
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
mainBlock : function () {
|
|
||||||
|
|
||||||
var wrapper = document.createElement('div');
|
|
||||||
|
|
||||||
wrapper.classList.add("ceditor-tool-link");
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
input : function () {
|
|
||||||
|
|
||||||
var inputTag = document.createElement('input');
|
|
||||||
|
|
||||||
inputTag.classList.add("ceditor-tool-link-input");
|
|
||||||
|
|
||||||
inputTag.placeholder = linkTool.defaultText;
|
|
||||||
|
|
||||||
inputTag.contentEditable = false;
|
|
||||||
|
|
||||||
return inputTag;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
wrapper : function () {
|
|
||||||
|
|
||||||
var wrapper = document.createElement('div');
|
|
||||||
|
|
||||||
wrapper.className += 'tool-link-panel clearfix';
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
image : function (imageSrc, imageClass) {
|
|
||||||
|
|
||||||
var imageTag = document.createElement('img');
|
|
||||||
|
|
||||||
imageTag.classList.add(imageClass);
|
|
||||||
|
|
||||||
imageTag.setAttribute('src', imageSrc);
|
|
||||||
|
|
||||||
return imageTag;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
link : function (linkUrl, linkText) {
|
|
||||||
|
|
||||||
var linkTag = document.createElement('a');
|
|
||||||
|
|
||||||
linkTag.classList.add(linkTool.elementClasses.link);
|
|
||||||
|
|
||||||
linkTag.href = linkUrl;
|
|
||||||
|
|
||||||
linkTag.target = "_blank";
|
|
||||||
|
|
||||||
linkTag.innerText = linkText;
|
|
||||||
|
|
||||||
return linkTag;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
title : function (titleText) {
|
|
||||||
|
|
||||||
var titleTag = document.createElement('div');
|
|
||||||
|
|
||||||
titleTag.classList.add("tool-link-content", linkTool.elementClasses.title);
|
|
||||||
|
|
||||||
titleTag.innerHTML = titleText;
|
|
||||||
|
|
||||||
return titleTag;
|
|
||||||
},
|
|
||||||
|
|
||||||
description : function (descriptionText) {
|
|
||||||
|
|
||||||
var descriptionTag = document.createElement('div');
|
|
||||||
|
|
||||||
descriptionTag.classList.add("tool-link-content", linkTool.elementClasses.description);
|
|
||||||
|
|
||||||
descriptionTag.innerHTML = descriptionText;
|
|
||||||
|
|
||||||
return descriptionTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
|
@ -2,22 +2,83 @@
|
||||||
* Code Plugin\
|
* Code Plugin\
|
||||||
* Creates code tag and adds content to this tag
|
* Creates code tag and adds content to this tag
|
||||||
*/
|
*/
|
||||||
var listTool = {
|
var list = (function(list) {
|
||||||
|
|
||||||
baseClass : "tool-list",
|
var baseClass = "tool-list";
|
||||||
elementClasses : {
|
|
||||||
|
var elementClasses = {
|
||||||
li : "tool-list-li"
|
li : "tool-list-li"
|
||||||
},
|
};
|
||||||
|
|
||||||
|
var ui = {
|
||||||
|
|
||||||
|
make: function (blockType) {
|
||||||
|
|
||||||
|
var wrapper = this.block(blockType || 'UL', baseClass);
|
||||||
|
|
||||||
|
wrapper.dataset.type = 'UL';
|
||||||
|
wrapper.contentEditable = true;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
block: function (blockType, blockClass) {
|
||||||
|
|
||||||
|
var block = document.createElement(blockType);
|
||||||
|
|
||||||
|
if (blockClass) block.classList.add(blockClass);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
button: function (buttonType) {
|
||||||
|
|
||||||
|
var types = {
|
||||||
|
unordered: '<i class="ce-icon-list-bullet"></i>Обычный список',
|
||||||
|
ordered: '<i class="ce-icon-list-numbered"></i>Нумерованный список'
|
||||||
|
},
|
||||||
|
button = document.createElement('SPAN');
|
||||||
|
|
||||||
|
button.innerHTML = types[buttonType];
|
||||||
|
|
||||||
|
button.className = 'ce_plugin_list--select_button';
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes block type => OL or UL
|
||||||
|
* @param event
|
||||||
|
* @param blockType
|
||||||
|
*/
|
||||||
|
changeBlockStyle : function (event, blockType) {
|
||||||
|
|
||||||
|
var currentBlock = codex.content.currentNode,
|
||||||
|
newEditable = ui.make(blockType),
|
||||||
|
oldEditable = currentBlock.querySelector("[contenteditable]");
|
||||||
|
|
||||||
|
newEditable.dataset.type = blockType;
|
||||||
|
newEditable.innerHTML = oldEditable.innerHTML;
|
||||||
|
newEditable.classList.add('ce-list');
|
||||||
|
|
||||||
|
codex.content.switchBlock(currentBlock, newEditable, 'list');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make initial header block
|
* Make initial header block
|
||||||
* @param {object} JSON with block data
|
* @param {object} JSON with block data
|
||||||
* @return {Element} element to append
|
* @return {Element} element to append
|
||||||
*/
|
*/
|
||||||
make : function () {
|
list.make = function () {
|
||||||
|
|
||||||
var tag = listTool.ui.make(),
|
var tag = ui.make(),
|
||||||
li = listTool.ui.block("li", "tool-link-li");
|
li = ui.block("li", "tool-link-li");
|
||||||
|
|
||||||
var br = document.createElement("br");
|
var br = document.createElement("br");
|
||||||
|
|
||||||
|
@ -28,21 +89,21 @@ var listTool = {
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to render HTML block from JSON
|
* Method to render HTML block from JSON
|
||||||
*/
|
*/
|
||||||
render : function (data) {
|
list.render = function (data) {
|
||||||
|
|
||||||
var type = data.type == 'ordered' ? 'OL' : 'UL',
|
var type = data.type == 'ordered' ? 'OL' : 'UL',
|
||||||
tag = listTool.ui.make(type);
|
tag = ui.make(type);
|
||||||
|
|
||||||
tag.classList.add('ce-list');
|
tag.classList.add('ce-list');
|
||||||
|
|
||||||
data.items.forEach(function (element, index, array) {
|
data.items.forEach(function (element, index, array) {
|
||||||
|
|
||||||
var newLi = listTool.ui.block("li", listTool.elementClasses.li);
|
var newLi = ui.block("li", listTool.elementClasses.li);
|
||||||
|
|
||||||
newLi.innerHTML = element;
|
newLi.innerHTML = element;
|
||||||
|
|
||||||
|
@ -53,17 +114,32 @@ var listTool = {
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
|
list.validate = function(data) {
|
||||||
|
|
||||||
|
var items = data.items.every(function(item){
|
||||||
|
return item.trim() != '';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!items)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data.type != 'UL' && data.type != 'OL')
|
||||||
|
return;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to extract JSON data from HTML block
|
* Method to extract JSON data from HTML block
|
||||||
*/
|
*/
|
||||||
save : function (blockContent){
|
list.save = function (blockContent){
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
type : null,
|
type : null,
|
||||||
items : [],
|
items : []
|
||||||
};
|
};
|
||||||
|
|
||||||
for(var index = 0; index < blockContent.childNodes.length; index++)
|
for(var index = 0; index < blockContent.childNodes.length; index++)
|
||||||
data.items[index] = blockContent.childNodes[index].textContent;
|
data.items[index] = blockContent.childNodes[index].textContent;
|
||||||
|
@ -72,9 +148,9 @@ var listTool = {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
makeSettings : function(data) {
|
list.makeSettings = function(data) {
|
||||||
|
|
||||||
var holder = document.createElement('DIV'),
|
var holder = document.createElement('DIV'),
|
||||||
selectTypeButton;
|
selectTypeButton;
|
||||||
|
@ -82,16 +158,16 @@ var listTool = {
|
||||||
/** Add holder classname */
|
/** Add holder classname */
|
||||||
holder.className = 'ce_plugin_list--settings';
|
holder.className = 'ce_plugin_list--settings';
|
||||||
|
|
||||||
var orderedButton = listTool.ui.button("ordered"),
|
var orderedButton = ui.button("ordered"),
|
||||||
unorderedButton = listTool.ui.button("unordered");
|
unorderedButton = ui.button("unordered");
|
||||||
|
|
||||||
orderedButton.addEventListener('click', function (event) {
|
orderedButton.addEventListener('click', function (event) {
|
||||||
listTool.changeBlockStyle(event, 'ol');
|
methods.changeBlockStyle(event, 'OL');
|
||||||
codex.toolbar.settings.close();
|
codex.toolbar.settings.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
unorderedButton.addEventListener('click', function (event) {
|
unorderedButton.addEventListener('click', function (event) {
|
||||||
listTool.changeBlockStyle(event, 'ul');
|
methods.changeBlockStyle(event, 'UL');
|
||||||
codex.toolbar.settings.close();
|
codex.toolbar.settings.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -100,58 +176,8 @@ var listTool = {
|
||||||
|
|
||||||
return holder;
|
return holder;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
changeBlockStyle : function (event, blockType) {
|
return list;
|
||||||
|
|
||||||
var currentBlock = codex.content.currentNode,
|
})({});
|
||||||
newEditable = listTool.ui.make(blockType),
|
|
||||||
oldEditable = currentBlock.querySelector("[contenteditable]");
|
|
||||||
|
|
||||||
newEditable.dataset.type = blockType;
|
|
||||||
newEditable.innerHTML = oldEditable.innerHTML;
|
|
||||||
newEditable.classList.add('ce-list');
|
|
||||||
|
|
||||||
codex.content.switchBlock(currentBlock, newEditable, 'list');
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
listTool.ui = {
|
|
||||||
|
|
||||||
make : function (blockType) {
|
|
||||||
|
|
||||||
var wrapper = this.block(blockType || 'UL', listTool.baseClass);
|
|
||||||
|
|
||||||
wrapper.dataset.type = 'ul';
|
|
||||||
wrapper.contentEditable = true;
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
block : function (blockType, blockClass) {
|
|
||||||
|
|
||||||
var block = document.createElement(blockType);
|
|
||||||
|
|
||||||
if ( blockClass ) block.classList.add(blockClass);
|
|
||||||
|
|
||||||
return block;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
button : function (buttonType) {
|
|
||||||
|
|
||||||
var types = {
|
|
||||||
unordered : '<i class="ce-icon-list-bullet"></i>Обычный список',
|
|
||||||
ordered : '<i class="ce-icon-list-numbered"></i>Нумерованный список'
|
|
||||||
},
|
|
||||||
button = document.createElement('SPAN');
|
|
||||||
|
|
||||||
button.innerHTML = types[buttonType];
|
|
||||||
|
|
||||||
button.className = 'ce_plugin_list--select_button';
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* Paragraph Plugin\
|
* Paragraph Plugin
|
||||||
* Creates P tag and adds content to this tag
|
* Creates P tag and adds content to this tag
|
||||||
*/
|
*/
|
||||||
// var tools = require('./../plugins');
|
|
||||||
|
|
||||||
var paragraphTool = {
|
var paragraph = (function(paragraph) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make initial header block
|
* Make initial header block
|
||||||
* @param {object} JSON with block data
|
* @param {object} JSON with block data
|
||||||
* @return {Element} element to append
|
* @return {Element} element to append
|
||||||
*/
|
*/
|
||||||
make : function (data) {
|
paragraph.make = function (data) {
|
||||||
|
|
||||||
var tag = document.createElement('DIV');
|
/** Create Empty DIV */
|
||||||
|
var tag = codex.draw.node('DIV', ['ce-paragraph'], {});
|
||||||
tag.classList.add('ce-paragraph');
|
|
||||||
|
|
||||||
if (data && data.text) {
|
if (data && data.text) {
|
||||||
tag.innerHTML = data.text;
|
tag.innerHTML = data.text;
|
||||||
|
@ -38,32 +36,55 @@ var paragraphTool = {
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to render HTML block from JSON
|
* Method to render HTML block from JSON
|
||||||
*/
|
*/
|
||||||
render : function (data) {
|
paragraph.render = function (data) {
|
||||||
|
|
||||||
return paragraphTool.make(data);
|
return this.make(data);
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to extract JSON data from HTML block
|
* Method to extract JSON data from HTML block
|
||||||
*/
|
*/
|
||||||
save : function (blockContent){
|
paragraph.save = function (blockContent){
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
text : null,
|
text : null,
|
||||||
format: "html",
|
format: "html",
|
||||||
introText: '<<same>>'
|
introText: '<<same>>'
|
||||||
};
|
};
|
||||||
|
|
||||||
data.text = blockContent.innerHTML;
|
data.text = blockContent.innerHTML;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
};
|
/**
|
||||||
|
* Validate data.
|
||||||
|
* Define which objects are important and which are not
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
*
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
paragraph.validate = function(data) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not allow:
|
||||||
|
* - Empty text
|
||||||
|
*/
|
||||||
|
if (data.text.trim() == '')
|
||||||
|
return;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return paragraph;
|
||||||
|
|
||||||
|
})({});
|
||||||
|
|
|
@ -76,7 +76,12 @@ pasteTool.callbacks = {
|
||||||
var clipBoardData = event.clipboardData || window.clipboardData,
|
var clipBoardData = event.clipboardData || window.clipboardData,
|
||||||
content = clipBoardData.getData('Text');
|
content = clipBoardData.getData('Text');
|
||||||
|
|
||||||
pasteTool.callbacks.analize(content);
|
var result = pasteTool.callbacks.analize(content);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,25 +106,32 @@ pasteTool.callbacks = {
|
||||||
if (image) {
|
if (image) {
|
||||||
|
|
||||||
pasteTool.callbacks.uploadImage(string);
|
pasteTool.callbacks.uploadImage(string);
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if (instagram) {
|
} else if (instagram) {
|
||||||
|
|
||||||
pasteTool.callbacks.instagramMedia(instagram);
|
pasteTool.callbacks.instagramMedia(instagram);
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if (twitter) {
|
} else if (twitter) {
|
||||||
|
|
||||||
pasteTool.callbacks.twitterMedia(twitter);
|
pasteTool.callbacks.twitterMedia(twitter);
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if (facebook) {
|
} else if (facebook) {
|
||||||
|
|
||||||
pasteTool.callbacks.facebookMedia(string);
|
pasteTool.callbacks.facebookMedia(string);
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if (vk) {
|
} else if (vk) {
|
||||||
|
|
||||||
pasteTool.callbacks.vkMedia(string);
|
pasteTool.callbacks.vkMedia(string);
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +206,7 @@ pasteTool.callbacks = {
|
||||||
*/
|
*/
|
||||||
twitterMedia : function(url) {
|
twitterMedia : function(url) {
|
||||||
|
|
||||||
var fullUrl = url.input,
|
var fullUrl = Array.isArray(url) ? url.input : url,
|
||||||
tweetId,
|
tweetId,
|
||||||
arr,
|
arr,
|
||||||
data;
|
data;
|
||||||
|
@ -204,19 +216,9 @@ pasteTool.callbacks = {
|
||||||
|
|
||||||
/** Example */
|
/** Example */
|
||||||
data = {
|
data = {
|
||||||
media:true,
|
|
||||||
conversation:false,
|
|
||||||
user:{
|
|
||||||
profile_image_url:"http:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
|
||||||
profile_image_url_https:"https:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
|
||||||
screen_name:"Niketas",
|
|
||||||
name:"Никита Лихачёв"
|
|
||||||
},
|
|
||||||
id: tweetId,
|
id: tweetId,
|
||||||
text:"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
|
id_str: tweetId,
|
||||||
created_at:"Tue Jun 28 14:09:12 +0000 2016",
|
status_url: fullUrl
|
||||||
status_url:"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
|
|
||||||
caption:"Caption"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
codex.tools.twitter.make(data);
|
codex.tools.twitter.make(data);
|
||||||
|
|
|
@ -3,36 +3,360 @@
|
||||||
* @author Khaydarov Murod
|
* @author Khaydarov Murod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var quoteTools = {
|
var quote = (function(quote) {
|
||||||
|
|
||||||
/** Default path to redactors images */
|
/** Default path to redactors images */
|
||||||
path : '/upload/redactor_images/',
|
var path = '/upload/redactor_images/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default quote style
|
* Default quote style
|
||||||
*/
|
*/
|
||||||
defaultStyle : 'withPhoto',
|
var defaultStyle = 'withPhoto';
|
||||||
|
|
||||||
|
var styles = {
|
||||||
|
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var photoUploadingCallbacks = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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('.' + styles.withPhoto.photo),
|
||||||
|
authorsPhoto = ui.img(styles.authorsPhoto);
|
||||||
|
|
||||||
|
authorsPhoto.src = path + 'b_' + filename;
|
||||||
|
|
||||||
|
/** Remove icon from image wrapper */
|
||||||
|
uploadImageWrapper.innerHTML = '';
|
||||||
|
|
||||||
|
/** 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) {
|
||||||
|
|
||||||
|
console.log('Can\'t upload an image');
|
||||||
|
codex.notifications.errorThrown();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
selectTypeQuoteStyle : function(type) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choose Quote style to replace
|
||||||
|
*/
|
||||||
|
switch (type) {
|
||||||
|
case 'simple':
|
||||||
|
quoteStyleFunction = makeSimpleQuote;
|
||||||
|
break;
|
||||||
|
case 'withCaption':
|
||||||
|
quoteStyleFunction = makeQuoteWithCaption;
|
||||||
|
break;
|
||||||
|
case 'withPhoto':
|
||||||
|
quoteStyleFunction = 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', [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
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make Quote from JSON datasets
|
* Make Quote from JSON datasets
|
||||||
*/
|
*/
|
||||||
makeBlockToAppend : function(data) {
|
quote.makeBlockToAppend = function(data) {
|
||||||
|
|
||||||
var tag;
|
var tag;
|
||||||
|
|
||||||
if (data && data.size) {
|
if (data && data.size) {
|
||||||
|
|
||||||
data.style = 'withPhoto';
|
data.style = 'withPhoto';
|
||||||
|
|
||||||
switch (data.style) {
|
switch (data.style) {
|
||||||
case 'simple':
|
case 'simple':
|
||||||
tag = quoteTools.makeSimpleQuote(data);
|
tag = methods.makeSimpleQuote(data);
|
||||||
break;
|
break;
|
||||||
case 'withCaption':
|
case 'withCaption':
|
||||||
tag = quoteTools.makeQuoteWithCaption(data);
|
tag = methods.makeQuoteWithCaption(data);
|
||||||
break;
|
break;
|
||||||
case 'withPhoto':
|
case 'withPhoto':
|
||||||
tag = quoteTools.makeQuoteWithPhoto(data);
|
tag = methods.makeQuoteWithPhoto(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,50 +369,61 @@ var quoteTools = {
|
||||||
photo : ''
|
photo : ''
|
||||||
};
|
};
|
||||||
|
|
||||||
tag = quoteTools.makeQuoteWithPhoto(settings);
|
tag = methods.makeQuoteWithPhoto(settings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
},
|
};
|
||||||
|
|
||||||
render : function(data) {
|
quote.validate = function(data) {
|
||||||
return quoteTools.makeBlockToAppend(data);
|
|
||||||
},
|
|
||||||
|
|
||||||
save : function(blockContent) {
|
console.log(data);
|
||||||
|
if (data.style.trim() == '' || data.text.trim() == '' || data.cite.trim() == ''
|
||||||
|
|| data.size.trim() == '')
|
||||||
|
return;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
quote.render = function(data) {
|
||||||
|
return quote.makeBlockToAppend(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
quote.save = function(blockContent) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts JSON quote data from HTML block
|
* Extracts JSON quote data from HTML block
|
||||||
* @param {Text} text, {Text} author, {Object} photo
|
* @param {Text} text, {Text} author, {Object} photo
|
||||||
*/
|
*/
|
||||||
var parsedblock = quoteTools.parseBlockQuote(blockContent);
|
var parsedblock = methods.parseBlockQuote(blockContent);
|
||||||
data = {
|
|
||||||
style : parsedblock.style,
|
if (parsedblock.style == 'withPhoto') {
|
||||||
text : parsedblock.text,
|
parsedblock.style = 'small';
|
||||||
author : parsedblock.author,
|
}
|
||||||
job : parsedblock.job,
|
var data = {
|
||||||
photo : parsedblock.photo,
|
"text" : parsedblock.text,
|
||||||
"format":"html",
|
"format" : "html",
|
||||||
"cite": parsedblock.author,
|
"cite" : parsedblock.author,
|
||||||
"size": "small"
|
"size" : parsedblock.style
|
||||||
};
|
};
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
};
|
||||||
|
|
||||||
makeSettings : function(data) {
|
quote.makeSettings = function(data) {
|
||||||
|
|
||||||
var holder = document.createElement('DIV'),
|
var holder = document.createElement('DIV'),
|
||||||
types = {
|
types = {
|
||||||
simple : 'Простая цитата',
|
big : 'По центру',
|
||||||
withCaption : 'Цитата с подписью',
|
small : 'Врезка'
|
||||||
withPhoto : 'Цитата с фото и ФИО'
|
// simple : 'Простая цитата',
|
||||||
},
|
// withCaption : 'Цитата с подписью',
|
||||||
|
// withPhoto : 'Цитата с фото и ФИО'
|
||||||
|
},
|
||||||
selectTypeButton;
|
selectTypeButton;
|
||||||
|
|
||||||
/** Add holder classname */
|
/** Add holder classname */
|
||||||
holder.className = quoteTools.styles.settings.holder;
|
holder.className = styles.settings.holder;
|
||||||
|
|
||||||
/** Now add type selectors */
|
/** Now add type selectors */
|
||||||
for (var type in types){
|
for (var type in types){
|
||||||
|
@ -96,17 +431,17 @@ var quoteTools = {
|
||||||
selectTypeButton = document.createElement('SPAN');
|
selectTypeButton = document.createElement('SPAN');
|
||||||
|
|
||||||
selectTypeButton.textContent = types[type];
|
selectTypeButton.textContent = types[type];
|
||||||
selectTypeButton.className = quoteTools.styles.settings.buttons;
|
selectTypeButton.className = styles.settings.buttons;
|
||||||
|
|
||||||
selectTypeButton.dataset.style = type;
|
selectTypeButton.dataset.style = type;
|
||||||
|
|
||||||
if ( type == quoteTools.defaultStyle ){
|
if ( type == defaultStyle ){
|
||||||
selectTypeButton.classList.add(quoteTools.styles.settings.selectedType);
|
selectTypeButton.classList.add(styles.settings.selectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// var quoteStyle = quoteTools.selectTypeQuoteStyle(type);
|
// var quoteStyle = quoteTools.selectTypeQuoteStyle(type);
|
||||||
|
|
||||||
selectTypeButton.addEventListener('click', quoteTools.changeStyleClicked, false);
|
selectTypeButton.addEventListener('click', methods.changeStyleClicked, false);
|
||||||
// quoteTools.addSelectTypeClickListener(selectTypeButton, quoteStyle);
|
// quoteTools.addSelectTypeClickListener(selectTypeButton, quoteStyle);
|
||||||
|
|
||||||
holder.appendChild(selectTypeButton);
|
holder.appendChild(selectTypeButton);
|
||||||
|
@ -115,332 +450,8 @@ var quoteTools = {
|
||||||
|
|
||||||
return holder;
|
return holder;
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
changeStyleClicked : function() {
|
return quote;
|
||||||
|
|
||||||
var changeStyleButton = this,
|
})({});
|
||||||
quote = codex.content.currentNode.querySelector('.' + quoteTools.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(quoteTools.styles.settings.selectedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.classList.add(quoteTools.styles.settings.selectedType);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
selectTypeQuoteStyle : function(type) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Choose Quote style to replace
|
|
||||||
*/
|
|
||||||
switch (type) {
|
|
||||||
case 'simple':
|
|
||||||
quoteStyleFunction = quoteTools.makeSimpleQuote;
|
|
||||||
break;
|
|
||||||
case 'withCaption':
|
|
||||||
quoteStyleFunction = quoteTools.makeQuoteWithCaption;
|
|
||||||
break;
|
|
||||||
case 'withPhoto':
|
|
||||||
quoteStyleFunction = quoteTools.makeQuoteWithPhoto;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return quoteStyleFunction;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
addSelectTypeClickListener : function(el, quoteStyle) {
|
|
||||||
|
|
||||||
el.addEventListener('click', function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parsing currentNode to JSON.
|
|
||||||
*/
|
|
||||||
var parsedOldQuote = quoteTools.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 = quoteTools.ui.makeBlock('BLOCKQUOTE', [quoteTools.styles.simple.text, quoteTools.styles.quoteText]);
|
|
||||||
|
|
||||||
wrapper.innerHTML = data.text || '';
|
|
||||||
|
|
||||||
wrapper.dataset.quoteStyle = 'simple';
|
|
||||||
wrapper.classList.add(quoteTools.styles.ce_quote);
|
|
||||||
wrapper.contentEditable = 'true';
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
makeQuoteWithCaption : function(data) {
|
|
||||||
|
|
||||||
var wrapper = quoteTools.ui.blockquote(),
|
|
||||||
text = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withCaption.blockquote, quoteTools.styles.quoteText]),
|
|
||||||
author = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withCaption.author, quoteTools.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(quoteTools.styles.ce_quote);
|
|
||||||
|
|
||||||
wrapper.appendChild(text);
|
|
||||||
wrapper.appendChild(author);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
makeQuoteWithPhoto : function(data) {
|
|
||||||
|
|
||||||
var wrapper = quoteTools.ui.blockquote(),
|
|
||||||
photo = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.photo]),
|
|
||||||
author = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.author, quoteTools.styles.quoteAuthor]),
|
|
||||||
job = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.job, quoteTools.styles.authorsJob]),
|
|
||||||
quote = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.quote, quoteTools.styles.quoteText]);
|
|
||||||
|
|
||||||
/* Default Image src */
|
|
||||||
if (!data.photo) {
|
|
||||||
|
|
||||||
var icon = quoteTools.ui.makeBlock('SPAN', ['ce-icon-picture']);
|
|
||||||
photo.appendChild(icon);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var authorsPhoto = quoteTools.ui.img(quoteTools.styles.authorsPhoto);
|
|
||||||
authorsPhoto.src = data.photo;
|
|
||||||
|
|
||||||
photo.classList.add(quoteTools.styles.authorsPhotoWrapper);
|
|
||||||
photo.appendChild(authorsPhoto);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
photo.addEventListener('click', quoteTools.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 = quoteTools.ui.makeBlock('DIV', [quoteTools.styles.withPhoto.authorHolder]);
|
|
||||||
authorsWrapper.appendChild(author);
|
|
||||||
authorsWrapper.appendChild(job);
|
|
||||||
|
|
||||||
/* make quote text contentEditable */
|
|
||||||
quote.contentEditable = 'true';
|
|
||||||
quote.innerHTML = data.text;
|
|
||||||
|
|
||||||
wrapper.classList.add(quoteTools.styles.ce_quote);
|
|
||||||
wrapper.classList.add(quoteTools.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('.' + quoteTools.styles.quoteAuthor),
|
|
||||||
job = currentNode.querySelector('.' + quoteTools.styles.authorsJob),
|
|
||||||
quote ;
|
|
||||||
|
|
||||||
/** Simple quote text placed in Blockquote tag*/
|
|
||||||
if ( currentNode.dataset.quoteStyle == 'simple' )
|
|
||||||
quote = currentNode.innerHTML;
|
|
||||||
else
|
|
||||||
quote = currentNode.querySelector('.' + quoteTools.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() {
|
|
||||||
|
|
||||||
var success = quoteTools.photoUploadingCallbacks.success,
|
|
||||||
error = quoteTools.photoUploadingCallbacks.error;
|
|
||||||
|
|
||||||
codex.transport.selectAndUpload({
|
|
||||||
success,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
quoteTools.styles = {
|
|
||||||
|
|
||||||
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'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
quoteTools.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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
quoteTools.photoUploadingCallbacks = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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('.' + quoteTools.styles.withPhoto.photo),
|
|
||||||
authorsPhoto = quoteTools.ui.img(quoteTools.styles.authorsPhoto);
|
|
||||||
|
|
||||||
authorsPhoto.src = quoteTools.path + 'b_' + filename;
|
|
||||||
|
|
||||||
/** Remove icon from image wrapper */
|
|
||||||
uploadImageWrapper.innerHTML = '';
|
|
||||||
|
|
||||||
/** Appending uploaded image */
|
|
||||||
uploadImageWrapper.classList.add(quoteTools.styles.authorsPhotoWrapper);
|
|
||||||
uploadImageWrapper.appendChild(authorsPhoto);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 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');
|
|
||||||
codex.notifications.errorThrown();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -3,12 +3,94 @@
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var twitterTool = {
|
var twitter = (function(twitter) {
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Twitter render method appends content after block
|
||||||
|
* @param tweetId
|
||||||
|
*/
|
||||||
|
twitter : function(data, tweet) {
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
window.twttr.widgets.createTweet(data.id_str, tweet);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
tweet.classList.add('twitter__loader');
|
||||||
|
|
||||||
|
if (codex.content.currentNode) {
|
||||||
|
tweet.dataset.statusUrl = data.status_url;
|
||||||
|
codex.content.switchBlock(codex.content.currentNode, tweet, 'twitter');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* in case if we need extra data
|
||||||
|
*/
|
||||||
|
if (!data.user) {
|
||||||
|
|
||||||
|
codex.core.ajax({
|
||||||
|
url : '/writing/tweetInfo?tweetId=' + data.id_str,
|
||||||
|
type: "GET",
|
||||||
|
success: function(result) {
|
||||||
|
methods.saveTwitterData(result, tweet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tweet.dataset.profileImageUrl = data.user.profile_image_url;
|
||||||
|
tweet.dataset.profileImageUrlHttps = data.user.profile_image_url_https;
|
||||||
|
tweet.dataset.screenName = data.user.screen_name;
|
||||||
|
tweet.dataset.name = data.user.name;
|
||||||
|
tweet.dataset.id = data.id;
|
||||||
|
tweet.dataset.idStr = data.id_str;
|
||||||
|
tweet.dataset.text = data.text;
|
||||||
|
tweet.dataset.createdAt = data.created_at;
|
||||||
|
tweet.dataset.statusUrl = data.status_url;
|
||||||
|
tweet.dataset.media = data.media;
|
||||||
|
|
||||||
|
tweet.classList.remove('twitter__loader');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
twitterBlock : function() {
|
||||||
|
var block = codex.draw.node('DIV', '', { height: "20px" });
|
||||||
|
return block;
|
||||||
|
},
|
||||||
|
|
||||||
|
saveTwitterData : function(result, tweet) {
|
||||||
|
var data = JSON.parse(result),
|
||||||
|
twitterContent = tweet;
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save twitter data via data-attributes
|
||||||
|
*/
|
||||||
|
twitterContent.dataset.profileImageUrl = data.user.profile_image_url;
|
||||||
|
twitterContent.dataset.profileImageUrlHttps = data.user.profile_image_url_https;
|
||||||
|
twitterContent.dataset.screenName = data.user.screen_name;
|
||||||
|
twitterContent.dataset.name = data.user.name;
|
||||||
|
twitterContent.dataset.id = data.id;
|
||||||
|
twitterContent.dataset.idStr = data.id_str;
|
||||||
|
twitterContent.dataset.text = data.text;
|
||||||
|
twitterContent.dataset.createdAt = data.created_at;
|
||||||
|
twitterContent.dataset.media = data.entities.urls.length > 0 ? "false" : "true";
|
||||||
|
|
||||||
|
twitterContent.classList.remove('twitter__loader');
|
||||||
|
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare twitter scripts
|
* Prepare twitter scripts
|
||||||
*/
|
*/
|
||||||
prepare : function() {
|
twitter.prepare = function() {
|
||||||
|
|
||||||
var script = "//platform.twitter.com/widgets.js";
|
var script = "//platform.twitter.com/widgets.js";
|
||||||
|
|
||||||
|
@ -17,74 +99,61 @@ var twitterTool = {
|
||||||
*/
|
*/
|
||||||
codex.core.importScript(script, 'twitterAPI');
|
codex.core.importScript(script, 'twitterAPI');
|
||||||
|
|
||||||
},
|
};
|
||||||
|
|
||||||
make : function(data) {
|
twitter.make = function(data) {
|
||||||
|
|
||||||
if (!data.id)
|
if (!data.id || !data.status_url)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
twitterTool.content.twitter(data.id);
|
if (!data.id_str && typeof(data.id) === 'number') {
|
||||||
},
|
data.id_str = data.status_url.match(/[^\/]+$/)[0];
|
||||||
|
}
|
||||||
|
|
||||||
save : function(blockContent) {
|
var blockContent = methods.twitterBlock();
|
||||||
|
|
||||||
|
methods.twitter(data, blockContent);
|
||||||
|
|
||||||
|
return blockContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
twitter.validate = function(data) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
twitter.save = function(blockContent) {
|
||||||
|
|
||||||
var data;
|
var data;
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
media:true,
|
media:blockContent.dataset.media,
|
||||||
conversation:false,
|
conversation:false,
|
||||||
user:{
|
user:{
|
||||||
profile_image_url:"http:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
profile_image_url: blockContent.dataset.profileImageUrl,
|
||||||
profile_image_url_https:"https:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
|
profile_image_url_https: blockContent.dataset.profileImageUrlHttps,
|
||||||
screen_name:"Niketas",
|
screen_name: blockContent.dataset.screenName,
|
||||||
name:"Никита Лихачёв"
|
name: blockContent.dataset.name
|
||||||
},
|
},
|
||||||
id: blockContent.dataset.tweetId,
|
id: blockContent.dataset.id || blockContent.dataset.tweetId,
|
||||||
text:"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
|
id_str : blockContent.dataset.idStr,
|
||||||
created_at:"Tue Jun 28 14:09:12 +0000 2016",
|
text: blockContent.dataset.text,
|
||||||
status_url:"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
|
created_at: blockContent.dataset.createdAt,
|
||||||
caption:"Caption"
|
status_url: blockContent.dataset.statusUrl,
|
||||||
|
caption: ""
|
||||||
};
|
};
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
},
|
twitter.render = function(data) {
|
||||||
|
return twitter.make(data);
|
||||||
|
};
|
||||||
|
|
||||||
render : function(data) {
|
return twitter;
|
||||||
return twitterTool.make(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
})({});
|
||||||
|
|
||||||
twitterTool.content = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Twitter render method appends content after block
|
|
||||||
* @param tweetId
|
|
||||||
*/
|
|
||||||
twitter : function(tweetId) {
|
|
||||||
|
|
||||||
var tweet = twitterTool.content.twitterBlock();
|
|
||||||
|
|
||||||
codex.content.switchBlock(codex.content.currentNode, tweet, 'twitter');
|
|
||||||
|
|
||||||
var blockContent = codex.content.currentNode.childNodes[0];
|
|
||||||
blockContent.classList.add('twitter__loader');
|
|
||||||
|
|
||||||
window.twttr.widgets.createTweet(tweetId, blockContent);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
blockContent.classList.remove('twitter__loader');
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
/** Remove empty DIV */
|
|
||||||
blockContent.childNodes[0].remove();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
twitterBlock : function() {
|
|
||||||
var block = codex.draw.node('DIV', '', {});
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue