mirror of
https://github.com/codex-team/editor.js
synced 2024-06-16 04:35:50 +02:00
Merge pull request #104 from codex-team/youtube-plugin-added
Youtube plugin added
This commit is contained in:
commit
67ecaf3932
4232
codex-editor.js
4232
codex-editor.js
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
33
example.html
33
example.html
|
@ -42,7 +42,11 @@
|
||||||
<script src="plugins/twitter/twitter.js"></script>
|
<script src="plugins/twitter/twitter.js"></script>
|
||||||
<link rel="stylesheet" href="plugins/twitter/twitter.css">
|
<link rel="stylesheet" href="plugins/twitter/twitter.css">
|
||||||
|
|
||||||
|
<script src="plugins/embed/embed.js"></script>
|
||||||
|
<link rel="stylesheet" href="plugins/embed/embed.css">
|
||||||
|
|
||||||
<script src="plugins/paste/paste.js"></script>
|
<script src="plugins/paste/paste.js"></script>
|
||||||
|
<script src="plugins/paste/patterns.js"></script>
|
||||||
<link rel="stylesheet" href="plugins/paste/paste.css">
|
<link rel="stylesheet" href="plugins/paste/paste.css">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -71,16 +75,11 @@
|
||||||
},
|
},
|
||||||
paste: {
|
paste: {
|
||||||
type: 'paste',
|
type: 'paste',
|
||||||
iconClassname: '',
|
prepare: paste.prepare,
|
||||||
prepare: pasteTool.prepare,
|
make: paste.make,
|
||||||
make: pasteTool.make,
|
save: paste.save,
|
||||||
appendCallback: null,
|
|
||||||
settings: null,
|
|
||||||
render: null,
|
|
||||||
save: pasteTool.save,
|
|
||||||
enableLineBreaks: false,
|
enableLineBreaks: false,
|
||||||
callbacks: pasteTool.callbacks,
|
callbacks: paste.pasted
|
||||||
allowedToPaste: false
|
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
type: 'code',
|
type: 'code',
|
||||||
|
@ -166,15 +165,19 @@
|
||||||
type: 'twitter',
|
type: 'twitter',
|
||||||
iconClassname: 'ce-icon-twitter',
|
iconClassname: 'ce-icon-twitter',
|
||||||
prepare: twitter.prepare,
|
prepare: twitter.prepare,
|
||||||
make: twitter.make,
|
|
||||||
appendCallback: null,
|
|
||||||
settings: null,
|
|
||||||
render: twitter.render,
|
render: twitter.render,
|
||||||
validate: twitter.validate,
|
validate: twitter.validate,
|
||||||
save: twitter.save,
|
save: twitter.save,
|
||||||
displayInToolbox: false,
|
config : {
|
||||||
enableLineBreaks: false,
|
fetchUrl : ''
|
||||||
allowedToPaste: false
|
}
|
||||||
|
},
|
||||||
|
embed: {
|
||||||
|
type: 'embed',
|
||||||
|
make: embed.make,
|
||||||
|
render: embed.render,
|
||||||
|
save: embed.save,
|
||||||
|
validate: embed.validate,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data : {
|
data : {
|
||||||
|
|
|
@ -263,6 +263,9 @@ var content = (function(content) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (currentInputIndex === codex.state.inputs.length - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
/** Timeout for browsers execution */
|
/** Timeout for browsers execution */
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ var toolbox = (function(toolbox) {
|
||||||
/**
|
/**
|
||||||
* UNREPLACEBLE_TOOLS this types of tools are forbidden to replace even they are empty
|
* UNREPLACEBLE_TOOLS this types of tools are forbidden to replace even they are empty
|
||||||
*/
|
*/
|
||||||
var UNREPLACEBLE_TOOLS = ['image', 'link', 'list', 'instagram', 'twitter'],
|
var UNREPLACEBLE_TOOLS = ['image', 'link', 'list', 'instagram', 'twitter', 'embed'],
|
||||||
tool = codex.tools[codex.toolbar.current],
|
tool = codex.tools[codex.toolbar.current],
|
||||||
workingNode = codex.content.currentNode,
|
workingNode = codex.content.currentNode,
|
||||||
currentInputIndex = codex.caret.inputIndex,
|
currentInputIndex = codex.caret.inputIndex,
|
||||||
|
|
12
plugins/embed/embed.css
Normal file
12
plugins/embed/embed.css
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.ce-redactor .embed {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 15px 0;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.embed__loader {
|
||||||
|
background-image: url("loading.gif") !important;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
208
plugins/embed/embed.js
Normal file
208
plugins/embed/embed.js
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
/**
|
||||||
|
* Embed plugin by gohabereg
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
var embed = function(embed){
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
|
||||||
|
addInternal: function (content) {
|
||||||
|
codex.content.switchBlock(codex.content.currentNode, content, 'video_extended');
|
||||||
|
|
||||||
|
var blockContent = codex.content.currentNode.childNodes[0];
|
||||||
|
blockContent.classList.add('embed__loader');
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
blockContent.classList.remove('embed__loader');
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getHtmlWithEmbedId: function (type, id) {
|
||||||
|
return services[type].html.replace(/<\%\= remote\_id \%\>/g, id);
|
||||||
|
},
|
||||||
|
|
||||||
|
makeElementFromHtml: function(html) {
|
||||||
|
var wrapper = document.createElement('DIV');
|
||||||
|
|
||||||
|
wrapper.innerHTML = html;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
getRemoteId: function(source, execArray) {
|
||||||
|
|
||||||
|
switch(source) {
|
||||||
|
case 'yandex-music-track':
|
||||||
|
id = execArray[2]+'/'+execArray[1];
|
||||||
|
break;
|
||||||
|
case 'yandex-music-playlist':
|
||||||
|
id = execArray[1]+'/'+execArray[2];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
id = execArray[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var services = {
|
||||||
|
vimeo: {
|
||||||
|
regex: /(?:http[s]?:\/\/)?(?:www.)?vimeo\.co(?:.+\/([^\/]\d+)(?:#t=[\d]+)?s?$)/,
|
||||||
|
html: "<iframe src=\"https://player.vimeo.com/video/<%= remote_id %>?title=0&byline=0\" width=\"580\" height=\"320\" frameborder=\"0\"></iframe>",
|
||||||
|
height: 320,
|
||||||
|
width: 580
|
||||||
|
|
||||||
|
},
|
||||||
|
youtube: {
|
||||||
|
regex: /^.*(?:(?:youtu\.be\/)|(?:youtube\.com)\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*)(?:[\?\&]t\=(\d*)|)/,
|
||||||
|
html: "<iframe src=\"https://www.youtube.com/embed/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>",
|
||||||
|
height: 320,
|
||||||
|
width: 580
|
||||||
|
},
|
||||||
|
vk : {
|
||||||
|
regex: /^https?.+vk?.com\/feed\?w=wall\d+_\d+/,
|
||||||
|
html: "<iframe src=\"https://tjournal.ru/proxy/video/<%= remote_id %>?rel=0&showinfo=0&enablejsapi=1&autoplay=1\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>"
|
||||||
|
},
|
||||||
|
coub: {
|
||||||
|
regex: /https?:\/\/coub\.com\/view\/([^\/\?\&]+)/,
|
||||||
|
html: "<iframe src=\"//coub.com/embed/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>",
|
||||||
|
height: 320,
|
||||||
|
width: 580
|
||||||
|
},
|
||||||
|
vine: {
|
||||||
|
regex: /https?:\/\/vine\.co\/v\/([^\/\?\&]+)/,
|
||||||
|
html: "<iframe src=\"https://vine.co/v/<%= remote_id %>/embed/simple/\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>",
|
||||||
|
height: 320,
|
||||||
|
width: 580
|
||||||
|
},
|
||||||
|
imgur: {
|
||||||
|
regex: /https?:\/\/(?:i\.)?imgur\.com.*\/([a-zA-Z0-9]+)(?:\.gifv)?/,
|
||||||
|
html: "<iframe allowfullscreen=\"true\" scrolling=\"no\" src=\"http://imgur.com/<%= remote_id %>/embed\" id=\"imgur-embed-iframe-pub-<%= remote_id %>\" class=\"imgur-embed-iframe-pub\" style=\"height: 500px; width: 540px; border: 1px solid #000\"></iframe>",
|
||||||
|
height: 500,
|
||||||
|
width: 540
|
||||||
|
},
|
||||||
|
gfycat: {
|
||||||
|
regex: /https?:\/\/gfycat\.com(?:\/detail)?\/([a-zA-Z]+)/,
|
||||||
|
html: "<iframe src='https://gfycat.com/ifr/<%= remote_id %>' frameborder='0' scrolling='no' width='580' height='436' allowfullscreen ></iframe>",
|
||||||
|
height: 436,
|
||||||
|
width: 580
|
||||||
|
},
|
||||||
|
'twitch-channel': {
|
||||||
|
regex: /https?:\/\/twitch.tv\/([^\/\?\&]*)/,
|
||||||
|
html: "<iframe src=\"https://player.twitch.tv/?channel=<%= remote_id %>\" frameborder=\"0\" allowfullscreen=\"true\" scrolling=\"no\" height=\"366\" width=\"600\"></iframe>",
|
||||||
|
height: 366,
|
||||||
|
width: 600
|
||||||
|
},
|
||||||
|
'twitch-video': {
|
||||||
|
regex: /https?:\/\/www.twitch.tv\/[^\/\?\&]*\/v\/([0-9]*)/,
|
||||||
|
html: "<iframe src=\"https://player.twitch.tv/?video=v<%= remote_id %>\" frameborder=\"0\" allowfullscreen=\"true\" scrolling=\"no\" height=\"366\" width=\"600\"></iframe>",
|
||||||
|
height: 366,
|
||||||
|
width: 600
|
||||||
|
},
|
||||||
|
'yandex-music-album': {
|
||||||
|
regex: /https?:\/\/music.yandex.ru\/album\/([0-9]*)/,
|
||||||
|
html: "<iframe frameborder=\"0\" style=\"border:none;width:540px;height:400px;\" width=\"540\" height=\"400\" src=\"https://music.yandex.ru/iframe/#album/<%= remote_id %>/\"></iframe>",
|
||||||
|
height: 400,
|
||||||
|
width: 540
|
||||||
|
},
|
||||||
|
'yandex-music-track': {
|
||||||
|
regex: /https?:\/\/music.yandex.ru\/album\/([0-9]*)\/track\/([0-9]*)/,
|
||||||
|
html: "<iframe frameborder=\"0\" style=\"border:none;width:540px;height:100px;\" width=\"540\" height=\"100\" src=\"https://music.yandex.ru/iframe/#track/<%= remote_id %>/\"></iframe>",
|
||||||
|
height: 100,
|
||||||
|
width: 540
|
||||||
|
},
|
||||||
|
'yandex-music-playlist': {
|
||||||
|
regex: /https?:\/\/music.yandex.ru\/users\/([^\/\?\&]*)\/playlists\/([0-9]*)/,
|
||||||
|
html: "<iframe frameborder=\"0\" style=\"border:none;width:540px;height:400px;\" width=\"540\" height=\"400\" src=\"https://music.yandex.ru/iframe/#playlist/<%= remote_id %>/show/cover/description/\"></iframe>",
|
||||||
|
height: 400,
|
||||||
|
width: 540
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
embed.make = function(data, isInternal) {
|
||||||
|
|
||||||
|
if (!data.remote_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var html = methods.getHtmlWithEmbedId(data.source, data.remote_id),
|
||||||
|
block = methods.makeElementFromHtml(html);
|
||||||
|
|
||||||
|
block.dataset.remoteId = data.remote_id;
|
||||||
|
block.dataset.source = data.source;
|
||||||
|
block.dataset.thumbnailUrl = data.thumbnailUrl;
|
||||||
|
|
||||||
|
block.classList.add('embed');
|
||||||
|
|
||||||
|
var sidePadding = (600 - services[data.source].width) / 2 + 'px';
|
||||||
|
|
||||||
|
block.style.padding = '30px ' + sidePadding;
|
||||||
|
|
||||||
|
if (isInternal) {
|
||||||
|
methods.addInternal(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saving JSON output.
|
||||||
|
* Upload data via ajax
|
||||||
|
*/
|
||||||
|
embed.save = function(blockContent) {
|
||||||
|
|
||||||
|
if (!blockContent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var data,
|
||||||
|
source = blockContent.dataset.source;
|
||||||
|
|
||||||
|
data = {
|
||||||
|
source: source,
|
||||||
|
remote_id: blockContent.dataset.remoteId,
|
||||||
|
thumbnailUrl: blockContent.dataset.thumbnailUrl,
|
||||||
|
height: services[source].height,
|
||||||
|
width: services[source].width
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render data
|
||||||
|
*/
|
||||||
|
embed.render = function(data) {
|
||||||
|
return embed.make(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
embed.urlPastedCallback = function(url, pattern) {
|
||||||
|
|
||||||
|
var execArray = pattern.regex.exec(url),
|
||||||
|
id = methods.getRemoteId(pattern.type, execArray);
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
source: pattern.type,
|
||||||
|
remote_id: id,
|
||||||
|
thumbnailUrl: url
|
||||||
|
};
|
||||||
|
|
||||||
|
embed.make(data, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
embed.validate = function(savedData) {
|
||||||
|
|
||||||
|
var source = savedData.source,
|
||||||
|
execArray = services[source].regex.exec(savedData.thumbnailUrl),
|
||||||
|
remoteId = methods.getRemoteId(source, execArray);
|
||||||
|
|
||||||
|
return remoteId == savedData.remote_id;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
|
||||||
|
}({});
|
BIN
plugins/embed/loading.gif
Normal file
BIN
plugins/embed/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -623,6 +623,85 @@ var image = (function(image) {
|
||||||
*/
|
*/
|
||||||
image.uploadImageFromUri = uploadingCallbacks_.ByPaste.uploadImageFromUrl;
|
image.uploadImageFromUri = uploadingCallbacks_.ByPaste.uploadImageFromUrl;
|
||||||
|
|
||||||
|
image.urlPastedCallbacks = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload image by URL
|
||||||
|
*
|
||||||
|
* @uses codex Image tool
|
||||||
|
* @param filename
|
||||||
|
* @returns {Element}
|
||||||
|
*/
|
||||||
|
uploadedImage : function(filename) {
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
background: false,
|
||||||
|
border: false,
|
||||||
|
isStretch: false,
|
||||||
|
file: {
|
||||||
|
url: "upload/redactor_images/" + filename,
|
||||||
|
bigUrl: "upload/redactor_images/" + filename,
|
||||||
|
width: null,
|
||||||
|
height: null,
|
||||||
|
additionalData: "null"
|
||||||
|
},
|
||||||
|
caption: '',
|
||||||
|
cover: null
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Using Image plugin make method */
|
||||||
|
var image = ceImage.make(data);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct upload from pasted path
|
||||||
|
* @param path
|
||||||
|
*/
|
||||||
|
uploadImage : function(path) {
|
||||||
|
|
||||||
|
var ajaxUrl = location.protocol + '//' + location.hostname + ':32769',
|
||||||
|
file,
|
||||||
|
image,
|
||||||
|
current = codex.content.currentNode,
|
||||||
|
beforeSend,
|
||||||
|
success_callback;
|
||||||
|
|
||||||
|
/** When image is uploaded to redactors folder */
|
||||||
|
success_callback = function(data) {
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
return;
|
||||||
|
var file = JSON.parse(data);
|
||||||
|
image = ceImage.urlPastedCallbacks.uploadedImage(file.filename);
|
||||||
|
codex.content.switchBlock(current, image, 'image');
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Before sending XMLHTTP request */
|
||||||
|
beforeSend = function() {
|
||||||
|
var content = current.querySelector('.ce-block__content');
|
||||||
|
content.classList.add('ce-plugin-image__loader');
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Preparing data for XMLHTTP */
|
||||||
|
var data = {
|
||||||
|
url: '/club/fetchImage',
|
||||||
|
type: "POST",
|
||||||
|
data : {
|
||||||
|
url: path
|
||||||
|
},
|
||||||
|
beforeSend : beforeSend,
|
||||||
|
success : success_callback
|
||||||
|
};
|
||||||
|
|
||||||
|
codex.core.ajax(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
|
@ -9,15 +9,11 @@ var instagram = (function(instagram) {
|
||||||
render : function(content) {
|
render : function(content) {
|
||||||
|
|
||||||
codex.content.switchBlock(codex.content.currentNode, content, 'instagram');
|
codex.content.switchBlock(codex.content.currentNode, content, 'instagram');
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
window.instgrm.Embeds.process();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
var blockContent = codex.content.currentNode.childNodes[0];
|
|
||||||
blockContent.classList.add('instagram__loader');
|
|
||||||
|
|
||||||
window.instgrm.Embeds.process();
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
blockContent.classList.remove('instagram__loader');
|
|
||||||
}, 500);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,9 +55,11 @@ var instagram = (function(instagram) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @private
|
||||||
|
*
|
||||||
* Make instagram embed via Widgets method
|
* Make instagram embed via Widgets method
|
||||||
*/
|
*/
|
||||||
instagram.make = function(data, isInternal) {
|
var make_ = function(data, isInternal) {
|
||||||
|
|
||||||
if (!data.instagram_url)
|
if (!data.instagram_url)
|
||||||
return;
|
return;
|
||||||
|
@ -123,9 +121,24 @@ var instagram = (function(instagram) {
|
||||||
* Render data
|
* Render data
|
||||||
*/
|
*/
|
||||||
instagram.render = function(data) {
|
instagram.render = function(data) {
|
||||||
return instagram.make(data);
|
return make_(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callback for instagram url's coming from pasteTool
|
||||||
|
* Using instagram Embed Widgete to render
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
instagram.urlPastedCallback = function(url) {
|
||||||
|
var data = {
|
||||||
|
instagram_url: url
|
||||||
|
};
|
||||||
|
|
||||||
|
make_(data, true);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return instagram;
|
return instagram;
|
||||||
|
|
||||||
})({});
|
})({});
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ var paragraph = (function(paragraph) {
|
||||||
* If pasted URL from instagram, twitter or Image
|
* If pasted URL from instagram, twitter or Image
|
||||||
* it renders via Social widgets content or uploads image and uses Image tool to render
|
* it renders via Social widgets content or uploads image and uses Image tool to render
|
||||||
*/
|
*/
|
||||||
tag.addEventListener('paste', codex.tools.paste.callbacks.pasted, false);
|
tag.addEventListener('paste', codex.tools.paste.callbacks, false);
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Paste plugin.
|
* Paste plugin.
|
||||||
*
|
*
|
||||||
* Listens on paste event and pastes content from:
|
* Listen to clipboard paste event and analize pasted text whit patterns in pattern.js
|
||||||
* - Instagram
|
|
||||||
* - Twitter
|
|
||||||
* - VK
|
|
||||||
* - Facebook
|
|
||||||
* - Image
|
|
||||||
* - External Link
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,212 +9,46 @@
|
||||||
*
|
*
|
||||||
* Main tool settings.
|
* Main tool settings.
|
||||||
*/
|
*/
|
||||||
var pasteTool = {
|
var paste = function(paste){
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make elements to insert or switch
|
|
||||||
*
|
|
||||||
* @uses Core codex.draw module
|
|
||||||
*/
|
|
||||||
pasteTool.ui = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload image by URL
|
|
||||||
*
|
|
||||||
* @uses codex Image tool
|
|
||||||
* @param filename
|
|
||||||
* @returns {Element}
|
|
||||||
*/
|
|
||||||
uploadedImage : function(filename) {
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
background: false,
|
|
||||||
border: false,
|
|
||||||
isStretch: false,
|
|
||||||
file: {
|
|
||||||
url: "upload/redactor_images/" + filename,
|
|
||||||
bigUrl: "upload/redactor_images/" + filename,
|
|
||||||
width: null,
|
|
||||||
height: null,
|
|
||||||
additionalData: "null"
|
|
||||||
},
|
|
||||||
caption: '',
|
|
||||||
cover: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Using Image plugin make method */
|
|
||||||
var image = codex.tools.image.make(data);
|
|
||||||
|
|
||||||
return image;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Callbacks
|
|
||||||
*/
|
|
||||||
pasteTool.callbacks = {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves data
|
* Saves data
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
pasted : function(event) {
|
paste.pasted = function(event) {
|
||||||
|
|
||||||
var clipBoardData = event.clipboardData || window.clipboardData,
|
var clipBoardData = event.clipboardData || window.clipboardData,
|
||||||
content = clipBoardData.getData('Text');
|
content = clipBoardData.getData('Text');
|
||||||
|
|
||||||
var result = pasteTool.callbacks.analize(content);
|
var result = analize(content);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analizes pated string and calls necessary method
|
* Analizes pated string and calls necessary method
|
||||||
*/
|
*/
|
||||||
analize : function(string) {
|
|
||||||
|
|
||||||
var regexTemplates = {
|
var analize = function(string) {
|
||||||
image : /(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*\.(?:jpe?g|gif|png))(?:\?([^#]*))?(?:#(.*))?/i,
|
|
||||||
instagram : new RegExp("http?.+instagram.com\/p?."),
|
|
||||||
twitter : new RegExp("http?.+twitter.com?.+\/"),
|
|
||||||
facebook : /https?.+facebook.+\/\d+\?/,
|
|
||||||
vk : /https?.+vk?.com\/feed\?w=wall\d+_\d+/,
|
|
||||||
},
|
|
||||||
|
|
||||||
image = regexTemplates.image.test(string),
|
var result = false;
|
||||||
instagram = regexTemplates.instagram.exec(string),
|
|
||||||
twitter = regexTemplates.twitter.exec(string),
|
|
||||||
facebook = regexTemplates.facebook.test(string),
|
|
||||||
vk = regexTemplates.vk.test(string);
|
|
||||||
|
|
||||||
if (image) {
|
paste.patterns.map(function(pattern, i){
|
||||||
|
if (pattern.regex.test(string)) {
|
||||||
|
pattern.callback.call(null, string, pattern);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
pasteTool.callbacks.uploadImage(string);
|
return result;
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if (instagram) {
|
};
|
||||||
|
|
||||||
pasteTool.callbacks.instagramMedia(instagram);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if (twitter) {
|
|
||||||
|
|
||||||
pasteTool.callbacks.twitterMedia(twitter);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if (facebook) {
|
|
||||||
|
|
||||||
pasteTool.callbacks.facebookMedia(string);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if (vk) {
|
|
||||||
|
|
||||||
pasteTool.callbacks.vkMedia(string);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direct upload
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
uploadImage : function(path) {
|
|
||||||
|
|
||||||
var ajaxUrl = location.protocol + '//' + location.hostname + ':32769',
|
|
||||||
file,
|
|
||||||
image,
|
|
||||||
current = codex.content.currentNode,
|
|
||||||
beforeSend,
|
|
||||||
success_callback;
|
|
||||||
|
|
||||||
/** When image is uploaded to redactors folder */
|
|
||||||
success_callback = function(data) {
|
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
return;
|
|
||||||
var file = JSON.parse(data);
|
|
||||||
image = pasteTool.ui.uploadedImage(file.filename);
|
|
||||||
codex.content.switchBlock(current, image, 'image');
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Before sending XMLHTTP request */
|
|
||||||
beforeSend = function() {
|
|
||||||
var content = current.querySelector('.ce-block__content');
|
|
||||||
content.classList.add('ce-plugin-image__loader');
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Preparing data for XMLHTTP */
|
|
||||||
var data = {
|
|
||||||
url: '/club/fetchImage',
|
|
||||||
type: "POST",
|
|
||||||
data : {
|
|
||||||
url: path
|
|
||||||
},
|
|
||||||
beforeSend : beforeSend,
|
|
||||||
success : success_callback
|
|
||||||
};
|
|
||||||
|
|
||||||
codex.core.ajax(data);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* callback for instagram url's
|
|
||||||
* Using instagram Embed Widgete to render
|
|
||||||
* @uses Instagram tool
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
instagramMedia : function(url) {
|
|
||||||
|
|
||||||
var fullUrl = url.input,
|
|
||||||
data;
|
|
||||||
|
|
||||||
|
|
||||||
data = {
|
return paste;
|
||||||
instagram_url: fullUrl
|
|
||||||
};
|
|
||||||
|
|
||||||
codex.tools.instagram.make(data, true);
|
}(paste || {});
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* callback for tweets
|
|
||||||
* Using Twittter Widget to render
|
|
||||||
* @uses Twitter tool
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
twitterMedia : function(url) {
|
|
||||||
|
|
||||||
var fullUrl = Array.isArray(url) ? url.input : url,
|
|
||||||
tweetId,
|
|
||||||
arr,
|
|
||||||
data;
|
|
||||||
|
|
||||||
arr = fullUrl.split('/');
|
|
||||||
tweetId = arr.pop();
|
|
||||||
|
|
||||||
/** Example */
|
|
||||||
data = {
|
|
||||||
id: tweetId,
|
|
||||||
id_str: tweetId,
|
|
||||||
status_url: fullUrl
|
|
||||||
};
|
|
||||||
|
|
||||||
codex.tools.twitter.make(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
97
plugins/paste/patterns.js
Normal file
97
plugins/paste/patterns.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* Patterns
|
||||||
|
*
|
||||||
|
* To add plugin create callback function in one and add here this object:
|
||||||
|
* {
|
||||||
|
* type : '', - type of pasted text (for example, 'image', 'url' or your plugin name)
|
||||||
|
* regex : /regex/, - regex for pasted text
|
||||||
|
* callback : yourPlugin.smthPastedCallback - callback function in your plugin which is called when pasted text matches regex
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
var paste = paste || {};
|
||||||
|
|
||||||
|
paste.patterns = [
|
||||||
|
{
|
||||||
|
type: 'image',
|
||||||
|
regex: /(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*\.(?:jpe?g|gif|png))(?:\?([^#]*))?(?:#(.*))?/i,
|
||||||
|
callback: image.urlPastedCallbacks.uploadImage
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'instagram',
|
||||||
|
regex: /http?.+instagram.com\/p\/([a-zA-Z0-9]*)/,
|
||||||
|
callback: instagram.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'twitter',
|
||||||
|
regex: /http?.+twitter.com?.+\//,
|
||||||
|
callback: twitter.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'facebook',
|
||||||
|
regex: /https?.+facebook.+\/\d+\?/,
|
||||||
|
callback: ''//pasteTool.callbacks.facebookMedia
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'vk',
|
||||||
|
regex: /https?.+vk?.com\/feed\?w=wall\d+_\d+/,
|
||||||
|
callback: ''//pasteTool.callbacks.vkMedia
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'youtube',
|
||||||
|
regex: /(?:https?:\/{2})?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)(?:\/watch\?v=|\/)([^\s&]+)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'vimeo',
|
||||||
|
regex: /(?:http[s]?:\/\/)?(?:www.)?vimeo\.co(?:.+\/([^\/]\d+)(?:#t=[\d]+)?s?$)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'coub',
|
||||||
|
regex: /https?:\/\/coub\.com\/view\/([^\/\?\&]+)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'vine',
|
||||||
|
regex: /https?:\/\/vine\.co\/v\/([^\/\?\&]+)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'imgur',
|
||||||
|
regex: /https?:\/\/(?:i\.)?imgur\.com.*\/([a-zA-Z0-9]+)(?:\.gifv)?/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'gfycat',
|
||||||
|
regex: /https?:\/\/gfycat\.com(?:\/detail)?\/([a-zA-Z]+)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'twitch-channel',
|
||||||
|
regex: /https?:\/\/www.twitch.tv\/([^\/\?\&]*)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'twitch-video',
|
||||||
|
regex: /https?:\/\/www.twitch.tv\/[^\/\?\&]*\/v\/([0-9]*)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'yandex-music-album',
|
||||||
|
regex: /https?:\/\/music.yandex.ru\/album\/([0-9]*)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'yandex-music-track',
|
||||||
|
regex: /https?:\/\/music.yandex.ru\/album\/([0-9]*)\/track\/([0-9]*)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'yandex-music-playlist',
|
||||||
|
regex: /https?:\/\/music.yandex.ru\/users\/([^\/\?\&]*)\/playlists\/([0-9]*)/,
|
||||||
|
callback: embed.urlPastedCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
];
|
|
@ -21,16 +21,16 @@ var twitter = (function(twitter) {
|
||||||
|
|
||||||
if (codex.content.currentNode) {
|
if (codex.content.currentNode) {
|
||||||
tweet.dataset.statusUrl = data.status_url;
|
tweet.dataset.statusUrl = data.status_url;
|
||||||
codex.content.switchBlock(codex.content.currentNode, tweet, 'twitter');
|
codex.content.switchBlock(codex.content.currentNode, tweet, 'tweet');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* in case if we need extra data
|
* in case if we need extra data
|
||||||
*/
|
*/
|
||||||
if (!data.user) {
|
if ( !data.user ) {
|
||||||
|
|
||||||
codex.core.ajax({
|
codex.core.ajax({
|
||||||
url : '/writing/tweetInfo?tweetId=' + data.id_str,
|
url : twitter.config.fetchUrl + '?tweetId=' + data.id_str,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
success: function(result) {
|
success: function(result) {
|
||||||
methods.saveTwitterData(result, tweet);
|
methods.saveTwitterData(result, tweet);
|
||||||
|
@ -43,7 +43,7 @@ var twitter = (function(twitter) {
|
||||||
tweet.dataset.profileImageUrlHttps = data.user.profile_image_url_https;
|
tweet.dataset.profileImageUrlHttps = data.user.profile_image_url_https;
|
||||||
tweet.dataset.screenName = data.user.screen_name;
|
tweet.dataset.screenName = data.user.screen_name;
|
||||||
tweet.dataset.name = data.user.name;
|
tweet.dataset.name = data.user.name;
|
||||||
tweet.dataset.id = data.id;
|
tweet.dataset.id = +data.id;
|
||||||
tweet.dataset.idStr = data.id_str;
|
tweet.dataset.idStr = data.id_str;
|
||||||
tweet.dataset.text = data.text;
|
tweet.dataset.text = data.text;
|
||||||
tweet.dataset.createdAt = data.created_at;
|
tweet.dataset.createdAt = data.created_at;
|
||||||
|
@ -62,9 +62,10 @@ var twitter = (function(twitter) {
|
||||||
},
|
},
|
||||||
|
|
||||||
saveTwitterData : function(result, tweet) {
|
saveTwitterData : function(result, tweet) {
|
||||||
|
|
||||||
var data = JSON.parse(result),
|
var data = JSON.parse(result),
|
||||||
twitterContent = tweet;
|
twitterContent = tweet;
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +75,7 @@ var twitter = (function(twitter) {
|
||||||
twitterContent.dataset.profileImageUrlHttps = data.user.profile_image_url_https;
|
twitterContent.dataset.profileImageUrlHttps = data.user.profile_image_url_https;
|
||||||
twitterContent.dataset.screenName = data.user.screen_name;
|
twitterContent.dataset.screenName = data.user.screen_name;
|
||||||
twitterContent.dataset.name = data.user.name;
|
twitterContent.dataset.name = data.user.name;
|
||||||
twitterContent.dataset.id = data.id;
|
twitterContent.dataset.id = +data.id;
|
||||||
twitterContent.dataset.idStr = data.id_str;
|
twitterContent.dataset.idStr = data.id_str;
|
||||||
twitterContent.dataset.text = data.text;
|
twitterContent.dataset.text = data.text;
|
||||||
twitterContent.dataset.createdAt = data.created_at;
|
twitterContent.dataset.createdAt = data.created_at;
|
||||||
|
@ -90,10 +91,15 @@ var twitter = (function(twitter) {
|
||||||
/**
|
/**
|
||||||
* Prepare twitter scripts
|
* Prepare twitter scripts
|
||||||
*/
|
*/
|
||||||
twitter.prepare = function() {
|
twitter.prepare = function(config) {
|
||||||
|
|
||||||
var script = "//platform.twitter.com/widgets.js";
|
var script = "//platform.twitter.com/widgets.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save configs
|
||||||
|
*/
|
||||||
|
twitter.config = config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load script
|
* Load script
|
||||||
*/
|
*/
|
||||||
|
@ -101,12 +107,18 @@ var twitter = (function(twitter) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
twitter.make = function(data) {
|
/**
|
||||||
|
* @private
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
make_ = function(data) {
|
||||||
|
|
||||||
if (!data.id || !data.status_url)
|
if (!data.id || !data.status_url)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!data.id_str && typeof(data.id) === 'number') {
|
if (!data.id_str) {
|
||||||
data.id_str = data.status_url.match(/[^\/]+$/)[0];
|
data.id_str = data.status_url.match(/[^\/]+$/)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +158,31 @@ var twitter = (function(twitter) {
|
||||||
};
|
};
|
||||||
|
|
||||||
twitter.render = function(data) {
|
twitter.render = function(data) {
|
||||||
return twitter.make(data);
|
return make_(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
twitter.urlPastedCallback = function(url) {
|
||||||
|
|
||||||
|
var tweetId,
|
||||||
|
arr,
|
||||||
|
data;
|
||||||
|
|
||||||
|
arr = url.split('/');
|
||||||
|
tweetId = arr.pop();
|
||||||
|
|
||||||
|
/** Example */
|
||||||
|
data = {
|
||||||
|
"media" : true,
|
||||||
|
"conversation" : false,
|
||||||
|
"user" : null,
|
||||||
|
"id" : +tweetId,
|
||||||
|
"text" : null,
|
||||||
|
"created_at" : null,
|
||||||
|
"status_url" : url,
|
||||||
|
"caption" : null
|
||||||
|
};
|
||||||
|
|
||||||
|
make_(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
return twitter;
|
return twitter;
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type":"video_extended",
|
"type":"video_extended",
|
||||||
"data":{
|
"data":{
|
||||||
"source":"youtube",
|
"source":"youtube",
|
||||||
"remote_id":"SqmAjcAPBpA",
|
"remote_id":"SqmAjcAPBpA",
|
||||||
"thumbnailUrl":"http:\/\/tj.local\/preview\/youtube\/SqmAjcAPBpA",
|
"thumbnailUrl":"http:\/\/tj.local\/preview\/youtube\/SqmAjcAPBpA",
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue