Paste tool remake and more video-services added

This commit is contained in:
George Berezhnoy 2017-01-12 16:56:06 +03:00
commit 089c8b59de
12 changed files with 277 additions and 289 deletions

View file

@ -2628,7 +2628,7 @@ var codex =
/**
* 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', 'video'],
tool = codex.tools[codex.toolbar.current],
workingNode = codex.content.currentNode,
currentInputIndex = codex.caret.inputIndex,

File diff suppressed because one or more lines are too long

View file

@ -42,12 +42,13 @@
<script src="plugins/twitter/twitter.js"></script>
<link rel="stylesheet" href="plugins/twitter/twitter.css">
<script src="plugins/paste/paste.js"></script>
<link rel="stylesheet" href="plugins/paste/paste.css">
<script src="plugins/video/video.js"></script>
<link rel="stylesheet" href="plugins/video/video.css">
<script src="plugins/paste/paste.js"></script>
<script src="plugins/paste/patterns.js"></script>
<link rel="stylesheet" href="plugins/paste/paste.css">
<script>
codex.start({
textareaId : "codex_area",
@ -73,7 +74,7 @@
render: null,
save: pasteTool.save,
enableLineBreaks: false,
callbacks: pasteTool.callbacks,
callbacks: pasteTool.pasted,
allowedToPaste: false
},
header: {

View file

@ -100,7 +100,7 @@ var toolbox = (function(toolbox) {
/**
* 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', 'video'],
tool = codex.tools[codex.toolbar.current],
workingNode = codex.content.currentNode,
currentInputIndex = codex.caret.inputIndex,

View file

@ -346,7 +346,7 @@ ceImage.ui = {
return wrapper;
}
},
};
@ -399,4 +399,83 @@ ceImage.photoUploadingCallbacks = {
codex.notifications.errorThrown();
}
};
ceImage.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);
}
};

View file

@ -115,3 +115,17 @@ instagramTool.content = {
}
};
/**
* callback for instagram url's coming from pasteTool
* Using instagram Embed Widgete to render
* @param url
*/
instagramTool.urlPastedCallback = function(url) {
var data = {
instagram_url: url
};
codex.tools.instagram.make(data, true);
};

View file

@ -34,7 +34,7 @@ var paragraphTool = {
* If pasted URL from instagram, twitter or Image
* 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;

View file

@ -1,14 +1,6 @@
/**
* Paste plugin.
*
* Listens on paste event and pastes content from:
* - Instagram
* - Twitter
* - VK
* - Facebook
* - Image
* - External Link
*
*/
/**
@ -17,56 +9,6 @@
* Main tool settings.
*/
var pasteTool = {
};
/**
* 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
* @param event
@ -76,7 +18,7 @@ pasteTool.callbacks = {
var clipBoardData = event.clipboardData || window.clipboardData,
content = clipBoardData.getData('Text');
pasteTool.callbacks.analize(content);
pasteTool.analize(content);
},
/**
@ -84,209 +26,13 @@ pasteTool.callbacks = {
*/
analize : function(string) {
var regexTemplates = {
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+/,
video : {
vimeo: {
regex: /(?:http[s]?:\/\/)?(?:www.)?vimeo\.co(?:.+\/([^\/]\d+)(?:#t=[\d]+)?s?$)/,
html: "<iframe src=\"<%= protocol %>//player.vimeo.com/video/<%= remote_id %>?title=0&byline=0\" width=\"580\" height=\"320\" frameborder=\"0\"></iframe>"
},
youtube: {
regex: /^.*(?:(?:youtu\.be\/)|(?:youtube\.com)\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*)(?:[\?\&]t\=(\d*)|)/,
html: "<iframe src=\"<%= protocol %>//www.youtube.com/embed/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>",
timestamp: '?t='
},
coub: {
regex: /https?:\/\/coub\.com\/view\/([^\/\?\&]+)/,
html: "<iframe src=\"https://coub.com/embed/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>"
},
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>"
},
vk: {
regex: /https?:\/\/vk\.com\/.*(?:video)([-_0-9]+)/,
html: "<iframe src=\"https://tjournal.ru/proxy/video/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>"
},
imgur: {
regex: /https?:\/\/(?:i\.)?imgur\.com.*\/([a-zA-Z0-9]+)(?:\.gifv)?/,
html: "<blockquote class=\"imgur-embed-pub\" lang=\"en\" data-id=\"<%= remote_id %>\" data-context=\"false\"></blockquote><script async src=\"//s.imgur.com/min/embed.js\" charset=\"utf-8\"></script>",
square: true
},
gfycat: {
regex: /https?:\/\/gfycat\.com(?:\/detail)?\/([a-zA-Z]+)/,
html: "<iframe src='https://gfycat.com/ifr/<%= remote_id %>' frameborder='0' scrolling='no' width='580' style='-webkit-backface-visibility: hidden;-webkit-transform: scale(1);' ></iframe>",
square: true
}
}
},
pasteTool.patterns.map(function(pattern, i){
if (pattern.regex.test(string)) {
pattern.callback.call(null, string, pattern);
}
})
image = regexTemplates.image.test(string),
instagram = regexTemplates.instagram.exec(string),
twitter = regexTemplates.twitter.exec(string),
facebook = regexTemplates.facebook.test(string),
vk = regexTemplates.vk.test(string);
/**
* Video testing
*/
var youtube = regexTemplates.video.youtube.regex.test(string);
var vimeo = regexTemplates.video.vimeo.regex.test(string);
var coub = regexTemplates.video.coub.regex.test(string);
var vine = regexTemplates.video.vine.regex.test(string);
if (image) {
pasteTool.callbacks.uploadImage(string);
} else if (instagram) {
pasteTool.callbacks.instagramMedia(instagram);
} else if (twitter) {
pasteTool.callbacks.twitterMedia(twitter);
} else if (facebook) {
pasteTool.callbacks.facebookMedia(string);
} else if (vk) {
pasteTool.callbacks.vkMedia(string);
} else if (youtube) {
pasteTool.callbacks.youtubeMedia(string);
} else if (vimeo) {
} else if (vine) {
} else if (coub) {
}
},
/**
* 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 = {
instagram_url: fullUrl
};
codex.tools.instagram.make(data, true);
},
/**
* callback for youtube url's
* Using iframe to render
* @uses video tool
* @param url
*/
youtubeMedia : function(url) {
var data = {
video_url: url
};
codex.tools.video.make(data, true);
},
/**
* callback for tweets
* Using Twittter Widget to render
* @uses Twitter tool
* @param url
*/
twitterMedia : function(url) {
var fullUrl = url.input,
tweetId,
arr,
data;
arr = fullUrl.split('/');
tweetId = arr.pop();
/** Example */
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,
text:"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
created_at:"Tue Jun 28 14:09:12 +0000 2016",
status_url:"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
caption:"Caption"
};
codex.tools.twitter.make(data);
}
};

68
plugins/paste/patterns.js Normal file
View file

@ -0,0 +1,68 @@
/**
* Patterns
*
*/
pasteTool.patterns = [
{
type: 'image',
regex: /(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*\.(?:jpe?g|gif|png))(?:\?([^#]*))?(?:#(.*))?/i,
callback: ceImage.urlPastedCallbacks.uploadImage
},
{
type: 'instagram',
regex: new RegExp("http?.+instagram.com\/p?."),
callback: instagramTool.urlPastedCallback
},
{
type: 'twitter',
regex: new RegExp("http?.+twitter.com?.+\/"),
callback: twitterTool.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: /^.*(?:(?:youtu\.be\/)|(?:youtube\.com)\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*)(?:[\?\&]t\=(\d*)|)/,
callback: videoTool.urlPastedCallbacks.generalCallback
},
{
type: 'vimeo',
regex: /(?:http[s]?:\/\/)?(?:www.)?vimeo\.co(?:.+\/([^\/]\d+)(?:#t=[\d]+)?s?$)/,
callback: videoTool.urlPastedCallbacks.generalCallback
},
{
type: 'coub',
regex: /https?:\/\/coub\.com\/view\/([^\/\?\&]+)/,
callback: videoTool.urlPastedCallbacks.generalCallback
},
{
type: 'vine',
regex: /https?:\/\/vine\.co\/v\/([^\/\?\&]+)/,
callback: videoTool.urlPastedCallbacks.generalCallback
},
{
type: 'vk',
regex: /https?:\/\/vk\.com\/.*(?:video)([-_0-9]+)/,
callback: videoTool.urlPastedCallbacks.generalCallback
},
{
type: 'imgur',
regex: /https?:\/\/(?:i\.)?imgur\.com.*\/([a-zA-Z0-9]+)(?:\.gifv)?/,
callback: videoTool.urlPastedCallbacks.generalCallback
},
{
type: 'gfycat',
regex: /https?:\/\/gfycat\.com(?:\/detail)?\/([a-zA-Z]+)/,
callback: videoTool.urlPastedCallbacks.generalCallback
}
];

View file

@ -88,3 +88,37 @@ twitterTool.content = {
return block;
}
};
/**
* callback for twitter utl's coming from pasteTool
* Using Twittter Widget to render
* @param url
*/
twitterTool.urlPastedCallback = function(url) {
var tweetId,
arr,
data;
arr = url.split('/');
tweetId = arr.pop();
/** Example */
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,
text:"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
created_at:"Tue Jun 28 14:09:12 +0000 2016",
status_url:"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
caption:"Caption"
};
codex.tools.twitter.make(data);
}

View file

@ -6,32 +6,26 @@ var videoTool = {
make : function(data, isInternal) {
if (!data.video_url)
if (!data.video_id)
return;
var properties = {
width: '560',
height: '315',
src: data.video_url,
frameborder: '0',
allowfullscreen: true
};
var html = videoTool.content.getHtmlWithVideoId(data.service, data.video_id),
block = videoTool.content.makeElementFromHtml(html);
var frame = codex.draw.node('IFRAME', 'video', properties);
block.dataset.id = data.video_id;
block.dataset.videoSeirvice = data.service;
if (isInternal) {
frame.src = videoTool.content.makeEmbedUrl(data.video_url);
setTimeout(function() {
/** Render block */
videoTool.content.render(frame);
videoTool.content.render(block);
}, 200);
}
return frame;
return block;
},
@ -47,7 +41,8 @@ var videoTool = {
return;
data = {
video_url: blockContent.src
video_id: blockContent.dataset.id,
service: blockContent.dataset.videoService
};
return data;
@ -59,7 +54,8 @@ var videoTool = {
*/
render : function(data) {
return videoTool.make(data);
}
},
};
@ -77,9 +73,59 @@ videoTool.content = {
},
makeEmbedUrl: function (url) {
getHtmlWithVideoId: function (type, id) {
return videoTool.content.services[type].html.replace("<%= remote_id %>", id);
},
return url.replace(/watch\?v=/, 'embed/');
makeElementFromHtml: function(html) {
var wrapper = document.createElement('DIV');
wrapper.innerHTML = html;
return wrapper.firstElementChild;
},
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>"
},
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>",
timestamp: '?t='
},
coub: {
regex: /https?:\/\/coub\.com\/view\/([^\/\?\&]+)/,
html: "<iframe src=\"//coub.com/embed/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>"
},
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>"
},
vk: {
regex: /https?:\/\/vk\.com\/.*(?:video)([-_0-9]+)/,
html: "<iframe src=\"https://tjournal.ru/proxy/video/<%= remote_id %>\" width=\"580\" height=\"320\" frameborder=\"0\" allowfullscreen></iframe>"
},
imgur: {
regex: /https?:\/\/(?:i\.)?imgur\.com.*\/([a-zA-Z0-9]+)(?:\.gifv)?/,
html: "<blockquote class=\"imgur-embed-pub\" lang=\"en\" data-id=\"<%= remote_id %>\" data-context=\"false\"></blockquote><script async src=\"//s.imgur.com/min/embed.js\" charset=\"utf-8\"></script>"
},
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>",
}
}
};
videoTool.urlPastedCallbacks = {
generalCallback: function(url, pattern) {
var id = pattern.regex.exec(url)[1];
var data = {
video_id: id,
service: pattern.type
};
videoTool.make(data, true);
}
};

File diff suppressed because one or more lines are too long