Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video plugin #694

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions src/formats/bbcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,17 +785,38 @@
allowsEmpty: true,
tags: {
iframe: {
'data-youtube-id': null
'data-youtube-id': null,
'data-youtube-start': null
}
},
format: function (element, content) {
element = attr(element, 'data-youtube-id');
var id = attr(element, 'data-youtube-id');
var start = attr(element, 'data-youtube-start');

return element ? '[youtube]' + element + '[/youtube]' : content;
if (start > 0) {
return id ? '[youtube=' + start + ']' + id +
'[/youtube]' : content;
} else {
return id ? '[youtube]' + id + '[/youtube]' : content;
}
},
html: '<iframe width="560" height="315" frameborder="0" ' +
'src="https://www.youtube.com/embed/{0}?wmode=opaque" ' +
'data-youtube-id="{0}" allowfullscreen></iframe>'
html: function (token, attrs, content) {
var pOpts = this.opts;
var id = content;
var start = 0;

if (attrs.defaultattr) {
start = escapeEntities(attrs.defaultattr);
}

return '<iframe ' + pOpts.youtubeParameters + ' ' +
'src="https://www.youtube.com/embed/' + id +
'?start=' + start +
'&wmode=opaque" ' +
'data-youtube-id="' + id + '" ' +
'data-youtube-start="' + start + '">' +
'</iframe>';
}
},
// END_COMMAND

Expand Down
13 changes: 8 additions & 5 deletions src/formats/xhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,20 @@
youtube: {
txtExec: function (caller) {
var editor = this;
var pOpts = editor.opts.parserOptions;

getEditorCommand('youtube')._dropDown(
editor,
caller,
function (id, time) {
function (id, start) {
editor.insertText(
'<iframe width="560" height="315" ' +
'src="https://www.youtube.com/embed/{id}?' +
'wmode=opaque&start=' + time + '" ' +
'<iframe ' + pOpts.youtubeParameters + ' ' +
'src="https://www.youtube.com/embed/' + id +
'?start=' + start +
'&wmode=opaque" ' +
'data-youtube-id="' + id + '" ' +
'frameborder="0" allowfullscreen></iframe>'
'data-youtube-start="' + start + '">' +
'</iframe>'
);
}
);
Expand Down
3 changes: 2 additions & 1 deletion src/icons/material.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
'undo': '<path d="M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z" />',
// Austin Andrews @Templarian - https://materialdesignicons.com/
'unlink': '<path d="M2,5.27L3.28,4L20,20.72L18.73,22L14.73,18H13V16.27L9.73,13H8V11.27L5.5,8.76C4.5,9.5 3.9,10.68 3.9,12C3.9,14.26 5.74,16.1 8,16.1H11V18H8A6,6 0 0,1 2,12C2,10.16 2.83,8.5 4.14,7.41L2,5.27M16,6A6,6 0 0,1 22,12C22,14.21 20.8,16.15 19,17.19L17.6,15.77C19.07,15.15 20.1,13.7 20.1,12C20.1,9.73 18.26,7.9 16,7.9H13V6H16M8,6H11V7.9H9.72L7.82,6H8M16,11V13H14.82L12.82,11H16Z" />',
'youtube': '<path d="M10,16.5V7.5L16,12M20,4.4C19.4,4.2 15.7,4 12,4C8.3,4 4.6,4.19 4,4.38C2.44,4.9 2,8.4 2,12C2,15.59 2.44,19.1 4,19.61C4.6,19.81 8.3,20 12,20C15.7,20 19.4,19.81 20,19.61C21.56,19.1 22,15.59 22,12C22,8.4 21.56,4.91 20,4.4Z" />'
'youtube': '<path d="M10,16.5V7.5L16,12M20,4.4C19.4,4.2 15.7,4 12,4C8.3,4 4.6,4.19 4,4.38C2.44,4.9 2,8.4 2,12C2,15.59 2.44,19.1 4,19.61C4.6,19.81 8.3,20 12,20C15.7,20 19.4,19.81 20,19.61C21.56,19.1 22,15.59 22,12C22,8.4 21.56,4.91 20,4.4Z" />',
'video': '<path d="M10,16.5V7.5L16,12M20,4.4C19.4,4.2 15.7,4 12,4C8.3,4 4.6,4.19 4,4.38C2.44,4.9 2,8.4 2,12C2,15.59 2.44,19.1 4,19.61C4.6,19.81 8.3,20 12,20C15.7,20 19.4,19.81 20,19.61C21.56,19.1 22,15.59 22,12C22,8.4 21.56,4.91 20,4.4Z" />'
};

sceditor.icons.material = function () {
Expand Down
3 changes: 2 additions & 1 deletion src/icons/monocons.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion src/lib/SCEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,22 @@ export default function SCEditor(original, userOptions) {
isRequired = original.required;
original.required = false;

// Plugins should be initiated before the formatters since plugin
// may add/change the handlers and format init should create cache
// with those changes
initPlugins();

// Plugins might change the commands, should re-build it
base.commands = utils
.extend(true, {}, (userOptions.commands || defaultCommands));

var FormatCtor = SCEditor.formats[options.format];
format = FormatCtor ? new FormatCtor() : {};
if ('init' in format) {
format.init.call(base);
}

// create the editor
initPlugins();
initEmoticons();
initToolBar();
initEditor();
Expand Down
4 changes: 3 additions & 1 deletion src/lib/defaultCommands.js
Original file line number Diff line number Diff line change
Expand Up @@ -777,11 +777,13 @@ var defaultCmds = {
},
exec: function (btn) {
var editor = this;
var pOpts = editor.opts.parserOptions;

defaultCmds.youtube._dropDown(editor, btn, function (id, time) {
editor.wysiwygEditorInsertHtml(_tmpl('youtube', {
id: id,
time: time
time: time,
params: pOpts.youtubeParameters
}));
});
},
Expand Down
21 changes: 19 additions & 2 deletions src/lib/defaultOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export default {
*
* @type {string}
*/
plugins: '',
plugins: 'video',

/**
* z-index to set the editor container to. Needed for jQuery UI dialog.
Expand Down Expand Up @@ -350,7 +350,24 @@ export default {
*
* @type {Object}
*/
parserOptions: { },
parserOptions: {
/**
* Parameters that will be added to YouTube frame tag
*
* @type {string}
*/
youtubeParameters: 'width="560" height="315" frameborder="0" ' +
'allowfullscreen',

/**
* Parameters that will be added to Facebook frame tag
*
* @type {string}
*/
facebookParameters: 'width="560" height="315" ' +
'style="border:none;overflow:hidden" scrolling="no" ' +
'frameborder="0" allowTransparency="true" allowFullScreen="true"'
},

/**
* CSS that will be added to the to dropdown menu (eg. z-index)
Expand Down
6 changes: 3 additions & 3 deletions src/lib/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ var _templates = {
'</div>',

youtube:
'<iframe width="560" height="315" frameborder="0" allowfullscreen ' +
'src="https://www.youtube.com/embed/{id}?wmode=opaque&start={time}" ' +
'data-youtube-id="{id}"></iframe>'
'<iframe {params} ' +
'src="https://www.youtube.com/embed/{id}?start={time}&wmode=opaque" ' +
'data-youtube-id="{id}" data-youtube-start="{time}"></iframe>'
};

/**
Expand Down
204 changes: 204 additions & 0 deletions src/plugins/video.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/**
* SCEditor Inline-Code Plugin for BBCode format
* http://www.sceditor.com/
*
* Copyright (C) 2011-2013, Sam Clarke (samclarke.com)
*
* SCEditor is licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* @fileoverview SCEditor Video plugin
* This plugin replaces the youtube command with "add video" command, which
* will recognize youtube and facebook URLs (hopefully other URLs as well
* in the future) and generate the tags accordingly
* @author Alex Betis
*/

(function (sceditor) {
'use strict';

sceditor.plugins.video = function () {
var base = this;

var utils = sceditor.utils;
var dom = sceditor.dom;

/**
* Private functions
* @private
*/
var commandHandler;
var processYoutube;
var processFacebook;
var youtubeHtml;
var facebookHtml;

base.init = function () {
var opts = this.opts;

// Enable for BBCode only
if (opts.format && opts.format !== 'bbcode') {
return;
}

if (opts.toolbar === sceditor.defaultOptions.toolbar) {
opts.toolbar = opts.toolbar.replace(',image,',
',image,video,');

opts.toolbar = opts.toolbar.replace(',youtube', '');
}

// Remove youtube command
sceditor.command.remove('youtube');

// Add new movie command
sceditor.command.set('video', {
exec: commandHandler,
txtExec: commandHandler,
tooltip: 'Insert a video (YouTube, Facebook)'
});

sceditor.formats.bbcode.set('facebook', {
allowsEmpty: true,
tags: {
iframe: {
'data-facebook-id': null
}
},
format: function (element, content) {
var id = dom.attr(element, 'data-facebook-id');

return id ? '[facebook]' + id + '[/facebook]' : content;
},
html: function (token, attrs, content) {
return facebookHtml(this.opts.facebookParameters, content);
}
});
};

youtubeHtml = function (pOpts, id, time) {
return '<iframe ' + pOpts + ' ' +
'src="https://www.youtube.com/embed/' + id +
'?start=' + time +
'&wmode=opaque" ' +
'data-youtube-id="' + id + '" ' +
'data-youtube-start="' + time + '"></iframe>';
};

facebookHtml = function (pOpts, id) {
return '<iframe ' + pOpts + ' ' +
'src="https://www.facebook.com/video/embed?video_id=' +
id + '" ' +
'data-facebook-id="' + id + '"></iframe>';
};

processYoutube = function (editor, val) {
var pOpts = editor.opts.parserOptions;
var idMatch = val.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/);
var timeMatch = val.match(/[&|?](?:star)?t=((\d+[hms]?){1,3})/);
var time = 0;

if (timeMatch) {
utils.each(timeMatch[1].split(/[hms]/), function (i, val) {
if (val !== '') {
time = (time * 60) + Number(val);
}
});
}

if (idMatch && /^[a-zA-Z0-9_\-]{11}$/.test(idMatch[1])) {
var id = idMatch[1];

if (editor.sourceMode()) {
if (time === 0) {
editor.insertText('[youtube]' + id + '[/youtube]');
} else {
editor.insertText('[youtube=' + time + ']' + id +
'[/youtube]');
}
} else {
editor.wysiwygEditorInsertHtml(
youtubeHtml(pOpts.youtubeParameters, id, time));
}

return true;
} else {
return false;
}
};

processFacebook = function (editor, val) {
var pOpts = editor.opts.parserOptions;
var idMatch = val.match(/videos\/(\d+)+|v=(\d+)|vb.\d+\/(\d+)/);

if (idMatch && /^[a-zA-Z0-9]/.test(idMatch[1])) {
var id = idMatch[1];

if (editor.sourceMode()) {
editor.insertText('[facebook]' + id + '[/facebook]');
} else {
editor.wysiwygEditorInsertHtml(
facebookHtml(pOpts.facebookParameters, id));
}

return true;
} else {
return false;
}
};

/**
* Function for the txtExec and exec properties
*
* @param {node} caller
* @private
*/
commandHandler = function (caller) {
var editor = this;
var content = document.createElement('div');

var div;
var label;
var input;
var button;

div = document.createElement('div');
label = document.createElement('label');
label.setAttribute('for', 'link');
label.textContent = editor._('Video URL:');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice image

input = document.createElement('input');
input.type = 'text';
input.id = 'link';
input.dir = 'ltr';
input.placeholder = 'https://';
div.appendChild(label);
div.appendChild(input);

content.appendChild(div);

div = document.createElement('div');
button = document.createElement('input');
button.type = 'button';
button.className = 'button';
button.value = editor._('Insert');
div.appendChild(button);

content.appendChild(div);

button.addEventListener('click', function (e) {
var val = input.value;
var done;

done = processYoutube(editor, val);
if (!done) {
processFacebook(editor, val);
}

editor.closeDropDown(true);
e.preventDefault();
});

editor.createDropDown(caller, 'insertlink', content);
};
};
})(sceditor);
Loading