[REF] web_editor: improve "Video" dialog design and behavior
Original design by @stefanorigano.
This commit is contained in:
@@ -621,164 +621,80 @@ var fontIconsDialog = Widget.extend({
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
function createVideoNode(url, options) {
|
||||
options = options || {};
|
||||
|
||||
// video url patterns(youtube, instagram, vimeo, dailymotion, youku)
|
||||
var ytRegExp = /^(?:(?:https?:)?\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
||||
var ytMatch = url.match(ytRegExp);
|
||||
|
||||
var igRegExp = /\/\/instagram.com\/p\/(.[a-zA-Z0-9]*)/;
|
||||
var igMatch = url.match(igRegExp);
|
||||
|
||||
var vRegExp = /\/\/vine.co\/v\/(.[a-zA-Z0-9]*)/;
|
||||
var vMatch = url.match(vRegExp);
|
||||
|
||||
var vimRegExp = /\/\/(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/;
|
||||
var vimMatch = url.match(vimRegExp);
|
||||
|
||||
var dmRegExp = /.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/;
|
||||
var dmMatch = url.match(dmRegExp);
|
||||
|
||||
var youkuRegExp = /\/\/v\.youku\.com\/v_show\/id_(\w+)\.html/;
|
||||
var youkuMatch = url.match(youkuRegExp);
|
||||
|
||||
var $video = $('<iframe>');
|
||||
if (ytMatch && ytMatch[1].length === 11) {
|
||||
var youtubeId = ytMatch[1];
|
||||
$video = $('<iframe>', {
|
||||
src: '//www.youtube.com/embed/' + youtubeId,
|
||||
width: '640',
|
||||
height: '360'
|
||||
});
|
||||
} else if (igMatch && igMatch[0].length) {
|
||||
$video = $('<iframe>', {
|
||||
src: igMatch[0] + '/embed/',
|
||||
width: '612',
|
||||
height: '710',
|
||||
scrolling: 'no',
|
||||
allowtransparency: 'true'
|
||||
});
|
||||
} else if (vMatch && vMatch[0].length) {
|
||||
$video = $('<iframe>', {
|
||||
src: vMatch[0] + '/embed/simple',
|
||||
width: '600',
|
||||
height: '600',
|
||||
class: 'vine-embed'
|
||||
});
|
||||
} else if (vimMatch && vimMatch[3].length) {
|
||||
$video = $('<iframe>', {
|
||||
src: '//player.vimeo.com/video/' + vimMatch[3],
|
||||
width: '640',
|
||||
height: '360'
|
||||
});
|
||||
} else if (dmMatch && dmMatch[2].length) {
|
||||
$video = $('<iframe>', {
|
||||
src: '//www.dailymotion.com/embed/video/' + dmMatch[2],
|
||||
width: '640',
|
||||
height: '360'
|
||||
});
|
||||
} else if (youkuMatch && youkuMatch[1].length) {
|
||||
$video = $('<iframe>', {
|
||||
height: '498',
|
||||
width: '510',
|
||||
src: '//player.youku.com/embed/' + youkuMatch[1]
|
||||
});
|
||||
} else {
|
||||
// this is not a known video link. Now what, Cat? Now what?
|
||||
$video = $('<iframe>', {
|
||||
width: '640',
|
||||
height: '360',
|
||||
src: url
|
||||
});
|
||||
}
|
||||
|
||||
if (options.autoplay) {
|
||||
$video.attr("src", $video.attr("src") + "?autoplay=1");
|
||||
}
|
||||
|
||||
$video.attr('frameborder', 0);
|
||||
|
||||
return $video;
|
||||
}
|
||||
|
||||
/**
|
||||
* VideoDialog widget. Lets users change a video, support all summernote
|
||||
* video, and embled iframe
|
||||
* VideoDialog widget. Let users change a video, support all summernote
|
||||
* video, and embed iframe.
|
||||
*/
|
||||
var VideoDialog = Widget.extend({
|
||||
template: 'web_editor.dialog.video',
|
||||
xmlDependencies: ['/web_editor/static/src/xml/editor.xml'],
|
||||
events : _.extend({}, Dialog.prototype.events, {
|
||||
'click input#urlvideo ~ button': 'get_video',
|
||||
'click input#embedvideo ~ button': 'get_embed_video',
|
||||
'change input#autoplay': 'get_video',
|
||||
'change input#urlvideo': 'change_input',
|
||||
'keyup input#urlvideo': 'change_input',
|
||||
'change input#embedvideo': 'change_input',
|
||||
'keyup input#embedvideo': 'change_input',
|
||||
'keydown.dismiss.bs.modal': function () {},
|
||||
}),
|
||||
events : {
|
||||
'change .o_video_dialog_options input': '_onUpdateVideoOption',
|
||||
'input textarea#o_video_text': '_onVideoCodeInput',
|
||||
'change textarea#o_video_text': '_onVideoCodeChange',
|
||||
},
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
init: function (parent, media) {
|
||||
this._super.apply(this, arguments);
|
||||
this.parent = parent;
|
||||
this.media = media;
|
||||
this._onVideoCodeInput = _.debounce(this._onVideoCodeInput, 1000);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
this.$preview = this.$('.preview-container').detach();
|
||||
this.$iframe = this.$("iframe");
|
||||
this.$content = this.$('.o_video_dialog_iframe');
|
||||
|
||||
var $media = $(this.media);
|
||||
if ($media.hasClass("media_iframe_video")) {
|
||||
var src = $media.data('src');
|
||||
this.$("input#urlvideo").val(src);
|
||||
this.$("input#autoplay").prop("checked", (src || "").indexOf("autoplay") >= 0);
|
||||
this.get_video();
|
||||
if ($media.hasClass('media_iframe_video')) {
|
||||
var src = $media.data('src') || '';
|
||||
this.$('textarea#o_video_text').val(src);
|
||||
|
||||
this.$('input#o_video_autoplay').prop('checked', src.indexOf('autoplay=1') >= 0);
|
||||
this.$('input#o_video_hide_controls').prop('checked', src.indexOf('controls=0') >= 0);
|
||||
this.$('input#o_video_loop').prop('checked', src.indexOf('loop=1') >= 0);
|
||||
this.$('input#o_video_hide_fullscreen').prop('checked', src.indexOf('fs=0') >= 0);
|
||||
this.$('input#o_video_hide_yt_logo').prop('checked', src.indexOf('modestbranding=1') >= 0);
|
||||
this.$('input#o_video_hide_dm_logo').prop('checked', src.indexOf('ui-logo=0') >= 0);
|
||||
this.$('input#o_video_hide_dm_share').prop('checked', src.indexOf('sharing-enable=0') >= 0);
|
||||
|
||||
this._updateVideo();
|
||||
}
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
change_input: function (e) {
|
||||
var $input = $(e.target);
|
||||
var $button = $input.parent().find("button");
|
||||
if ($input.val() === "") {
|
||||
$button.addClass("btn-default").removeClass("btn-primary");
|
||||
} else {
|
||||
$button.removeClass("btn-default").addClass("btn-primary");
|
||||
}
|
||||
},
|
||||
get_embed_video: function (event) {
|
||||
event.preventDefault();
|
||||
var embedvideo = this.$("input#embedvideo").val().match(/src=["']?([^"']+)["' ]?/);
|
||||
if (embedvideo) {
|
||||
this.$("input#urlvideo").val(embedvideo[1]);
|
||||
this.get_video(event);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
get_video: function (event) {
|
||||
if (event) event.preventDefault();
|
||||
var $video = createVideoNode(this.$("input#urlvideo").val(), {autoplay: this.$("input#autoplay").is(":checked")});
|
||||
this.$iframe.replaceWith($video);
|
||||
this.$iframe = $video;
|
||||
return false;
|
||||
},
|
||||
save: function () {
|
||||
var video_id = this.$("#video_id").val();
|
||||
if (!video_id) {
|
||||
this.$("button.btn-primary").click();
|
||||
video_id = this.$("#video_id").val();
|
||||
}
|
||||
var $iframe = $(
|
||||
'<div class="media_iframe_video" data-src="'+this.$iframe.attr("src")+'">'+
|
||||
'<div class="css_editable_mode_display"> </div>'+
|
||||
'<div class="media_iframe_video_size" contentEditable="false"> </div>'+
|
||||
'<iframe src="'+this.$iframe.attr("src")+'" frameborder="0" allowfullscreen="allowfullscreen" contentEditable="false"></iframe>'+
|
||||
'</div>');
|
||||
$(this.media).replaceWith($iframe);
|
||||
this.media = $iframe[0];
|
||||
|
||||
return this.media;
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
save: function () {
|
||||
this._updateVideo();
|
||||
|
||||
if (this.$('.o_video_dialog_iframe').is('iframe')) {
|
||||
var $content = $(
|
||||
'<div class="media_iframe_video" data-src="' + this.$content.attr('src') + '">'+
|
||||
'<div class="css_editable_mode_display"> </div>'+
|
||||
'<div class="media_iframe_video_size" contenteditable="false"> </div>'+
|
||||
'<iframe src="' + this.$content.attr('src') + '" frameborder="0" contenteditable="false"></iframe>'+
|
||||
'</div>'
|
||||
);
|
||||
$(this.media).replaceWith($content);
|
||||
this.media = $content[0];
|
||||
return this.media;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
clear: function () {
|
||||
if (this.media.dataset.src) {
|
||||
try {
|
||||
@@ -789,6 +705,205 @@ var VideoDialog = Widget.extend({
|
||||
}
|
||||
this.media.className = this.media.className.replace(/(^|\s)media_iframe_video(\s|$)/g, ' ');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a video node according to the given URL and options. If not
|
||||
* possible, returns an error code.
|
||||
*
|
||||
* @private
|
||||
* @param {string} url
|
||||
* @param {Object} options
|
||||
* @returns {Object}
|
||||
* $video -> the created video jQuery node
|
||||
* type -> the type of the created video
|
||||
* errorCode -> if defined, either '0' for invalid URL or '1' for
|
||||
* unsupported video provider
|
||||
*/
|
||||
_createVideoNode: function (url, options) {
|
||||
options = options || {};
|
||||
|
||||
// Video url patterns(youtube, instagram, vimeo, dailymotion, youku, ...)
|
||||
var ytRegExp = /^(?:(?:https?:)?\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
||||
var ytMatch = url.match(ytRegExp);
|
||||
|
||||
var insRegExp = /(.*)instagram.com\/p\/(.[a-zA-Z0-9]*)/;
|
||||
var insMatch = url.match(insRegExp);
|
||||
|
||||
var vinRegExp = /\/\/vine.co\/v\/(.[a-zA-Z0-9]*)/;
|
||||
var vinMatch = url.match(vinRegExp);
|
||||
|
||||
var vimRegExp = /\/\/(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/;
|
||||
var vimMatch = url.match(vimRegExp);
|
||||
|
||||
var dmRegExp = /.+dailymotion.com\/(video|hub|embed)\/([^_]+)[^#]*(#video=([^_&]+))?/;
|
||||
var dmMatch = url.match(dmRegExp);
|
||||
|
||||
var ykuRegExp = /(.*).youku\.com\/(v_show\/id_|embed\/)(.+)/;
|
||||
var ykuMatch = url.match(ykuRegExp);
|
||||
|
||||
var $video = $('<iframe>').width(1280).height(720).attr('frameborder', 0).addClass('o_video_dialog_iframe');
|
||||
var videoType = 'yt';
|
||||
|
||||
if (!/^(http:\/\/|https:\/\/|\/\/)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(url)){
|
||||
return {errorCode: 0};
|
||||
}
|
||||
|
||||
var autoplay = options.autoplay ? '?autoplay=1' : '?autoplay=0';
|
||||
|
||||
if (ytMatch && ytMatch[1].length === 11) {
|
||||
$video.attr('src', '//www.youtube.com/embed/' + ytMatch[1] + autoplay);
|
||||
} else if (insMatch && insMatch[2].length) {
|
||||
$video.attr('src', '//www.instagram.com/p/' + insMatch[2] + '/embed/');
|
||||
videoType = 'ins';
|
||||
} else if (vinMatch && vinMatch[0].length) {
|
||||
$video.attr('src', vinMatch[0] + '/embed/simple');
|
||||
videoType = 'vin';
|
||||
} else if (vimMatch && vimMatch[3].length) {
|
||||
$video.attr('src', '//player.vimeo.com/video/' + vimMatch[3] + autoplay);
|
||||
videoType = 'vim';
|
||||
} else if (dmMatch && dmMatch[2].length) {
|
||||
var just_id = dmMatch[2].replace('video/','');
|
||||
$video.attr('src', '//www.dailymotion.com/embed/video/' + just_id + autoplay);
|
||||
videoType = 'dm';
|
||||
} else if (ykuMatch && ykuMatch[3].length) {
|
||||
var yku_id = ykuMatch[3].indexOf('.html?') >= 0 ? ykuMatch[3].substring(0, ykuMatch[3].indexOf('.html?')) : ykuMatch[3];
|
||||
$video.attr('src', '//player.youku.com/embed/' + yku_id);
|
||||
videoType = 'yku';
|
||||
} else {
|
||||
return {errorCode: 1};
|
||||
}
|
||||
|
||||
if (options.loop && (ytMatch || vimMatch)) {
|
||||
$video.attr('src', $video.attr('src') + '&loop=1');
|
||||
}
|
||||
if (options.hide_controls && (ytMatch || dmMatch)) {
|
||||
$video.attr('src', $video.attr('src') + '&controls=0');
|
||||
}
|
||||
if (options.hide_fullscreen && ytMatch) {
|
||||
$video.attr('src', $video.attr('src') + '&fs=0');
|
||||
}
|
||||
if (options.hide_yt_logo && ytMatch) {
|
||||
$video.attr('src', $video.attr('src') + '&modestbranding=1');
|
||||
}
|
||||
if (options.hide_dm_logo && dmMatch) {
|
||||
$video.attr('src', $video.attr('src') + '&ui-logo=0');
|
||||
}
|
||||
if (options.hide_dm_share && dmMatch) {
|
||||
$video.attr('src', $video.attr('src') + '&sharing-enable=0');
|
||||
}
|
||||
|
||||
return {$video: $video, type: videoType};
|
||||
},
|
||||
/**
|
||||
* Updates the video preview according to video code and enabled options.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_updateVideo: function () {
|
||||
// Reset the feedback
|
||||
this.$content.empty();
|
||||
this.$('#o_video_form_group').removeClass('has-error has-success');
|
||||
this.$('.o_video_dialog_options li').addClass('hidden');
|
||||
|
||||
// Check video code
|
||||
var $textarea = this.$('textarea#o_video_text');
|
||||
var code = $textarea.val().trim();
|
||||
if (!code) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Detect if we have an embed code rather than an URL
|
||||
var embedMatch = code.match(/(src|href)=["']?([^"']+)?/);
|
||||
if (embedMatch && embedMatch[2].length > 0 && embedMatch[2].indexOf('instagram')){
|
||||
embedMatch[1] = embedMatch[2]; // Instagram embed code is different
|
||||
}
|
||||
var url = embedMatch ? embedMatch[1] : code;
|
||||
|
||||
var query = this._createVideoNode(url, {
|
||||
autoplay: this.$('input#o_video_autoplay').is(':checked'),
|
||||
hide_controls: this.$('input#o_video_hide_controls').is(':checked'),
|
||||
loop: this.$('input#o_video_loop').is(':checked'),
|
||||
hide_fullscreen: this.$('input#o_video_hide_fullscreen').is(':checked'),
|
||||
hide_yt_logo: this.$('input#o_video_hide_yt_logo').is(':checked'),
|
||||
hide_dm_logo: this.$('input#o_video_hide_dm_logo').is(':checked'),
|
||||
hide_dm_share: this.$('input#o_video_hide_dm_share').is(':checked'),
|
||||
});
|
||||
|
||||
var $opt_box = this.$('.o_video_dialog_options');
|
||||
|
||||
// Show / Hide preview elements
|
||||
this.$el.find('.o_video_dialog_preview_text, .media_iframe_video_size').add($opt_box).toggleClass('hidden', !query.$video);
|
||||
// Toggle validation classes
|
||||
this.$el.find('#o_video_form_group').toggleClass('has-error', !query.$video).toggleClass('has-success', !!query.$video);
|
||||
|
||||
// Individually show / hide options base on the video provider
|
||||
$opt_box.find('li.o_' + query.type + '_option').removeClass('hidden');
|
||||
|
||||
// Hide the entire options box if no options are available
|
||||
$opt_box.toggleClass('hidden', $opt_box.find('li:not(.hidden)').length === 0);
|
||||
|
||||
if (query.type === 'yt') {
|
||||
// Youtube only: If 'hide controls' is checked, hide 'fullscreen'
|
||||
// and 'youtube logo' options too
|
||||
this.$('input#o_video_hide_fullscreen, input#o_video_hide_yt_logo').closest('li').toggleClass('hidden', this.$('input#o_video_hide_controls').is(':checked'));
|
||||
}
|
||||
|
||||
var $content = query.$video;
|
||||
if (!$content) {
|
||||
switch (query.errorCode) {
|
||||
case 0:
|
||||
$content = $('<div/>', {
|
||||
class: 'alert alert-danger o_video_dialog_iframe',
|
||||
text: _t("The provided url is not valid"),
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
$content = $('<div/>', {
|
||||
class: 'alert alert-warning o_video_dialog_iframe',
|
||||
text: _t("The provided url does not reference any supported video"),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.$content.replaceWith($content);
|
||||
this.$content = $content;
|
||||
},
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Called when a video option changes -> Updates the video preview.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onUpdateVideoOption: function () {
|
||||
this._updateVideo();
|
||||
},
|
||||
/**
|
||||
* Called when the video code (URL / Iframe) change is confirmed -> Updates
|
||||
* the video preview immediately.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onVideoCodeChange: function () {
|
||||
this._updateVideo();
|
||||
},
|
||||
/**
|
||||
* Called when the video code (URL / Iframe) changes -> Updates the video
|
||||
* preview (note: this function is automatically debounced).
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onVideoCodeInput: function () {
|
||||
this._updateVideo();
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -241,14 +241,6 @@ body .modal {
|
||||
.well {
|
||||
border-color: @gray-lighter;
|
||||
border-top-width: 0;
|
||||
|
||||
label {
|
||||
margin: auto 10px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.o_existing_attachment_cell {
|
||||
@@ -306,6 +298,83 @@ body .modal {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#editor-media-image, #editor-media-document {
|
||||
.well {
|
||||
label {
|
||||
margin: auto 10px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VIDEO TAB
|
||||
#editor-media-video .well {
|
||||
padding: 0;
|
||||
.o-flex-display();
|
||||
.o-flex-flow(row, wrap);
|
||||
|
||||
.o_video_dialog_form {
|
||||
.o-flex(1, 1, auto);
|
||||
min-width: 0;
|
||||
padding: 20px;
|
||||
|
||||
#o_video_form_group {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
> textarea {
|
||||
width: 100%;
|
||||
min-height: 95px;
|
||||
padding-bottom: 25px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
> .o_validate_feedback {
|
||||
.o-position-absolute(auto, 10px, 10px);
|
||||
|
||||
> .fa {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.has-error > .o_validate_feedback > .fa-exclamation-triangle {
|
||||
display: block;
|
||||
}
|
||||
&.has-success > .o_validate_feedback > .fa-check {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#video-preview {
|
||||
position: relative;
|
||||
.o-flex(1, 0, 50%);
|
||||
.o-flex-display();
|
||||
.o-flex-flow(column, nowrap);
|
||||
.o-justify-content(center);
|
||||
|
||||
.o-we-preview-box(0 19px);
|
||||
border: none;
|
||||
|
||||
.media_iframe_video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.o_video_dialog_iframe {
|
||||
.o-we-preview-content();
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
&.alert {
|
||||
.o-animation(fadeInDownSmall, 700ms, @fill-mode: forwards);
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,22 +420,18 @@ body .modal {
|
||||
}
|
||||
|
||||
.o_bg_img_opt_cover_edition {
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid white;
|
||||
padding: 0px 25px 25px 25px;
|
||||
.o-linear-gradient(-150deg, lighten(#2c2c36, 5%), darken(#2c2c36, 10%));
|
||||
.o-we-preview-box();
|
||||
|
||||
h6 {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.o_bg_img_opt_object {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
position: relative;
|
||||
background: white;
|
||||
min-height: 10px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 10px #000;
|
||||
.o-we-preview-content();
|
||||
|
||||
> img {
|
||||
cursor: crosshair;
|
||||
border-top: 1px solid #5A5A5A;
|
||||
|
||||
@@ -85,6 +85,26 @@
|
||||
}
|
||||
|
||||
|
||||
// ============ 'Preview' component Mixins ===============
|
||||
// Create a "preview" work-area to edit/customize specific elements
|
||||
|
||||
.o-we-preview-box(@padding: 0px 25px 25px 25px, @color-text: white ) {
|
||||
padding: @padding;
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid white;
|
||||
.o-linear-gradient(-150deg, @o-we-color-dark, @o-we-color-darker);
|
||||
|
||||
color: @color-text;
|
||||
}
|
||||
|
||||
.o-we-preview-content() {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 15px 2px #000;
|
||||
}
|
||||
|
||||
|
||||
// ============ Preservetion mixins ===============
|
||||
// Used to preserve web_editor and website UI from themes customizations
|
||||
|
||||
|
||||
@@ -187,31 +187,48 @@
|
||||
|
||||
<!-- Video choosing part of the Media Dialog -->
|
||||
<t t-name="web_editor.dialog.video">
|
||||
<form action="#" class="form-inline">
|
||||
<div class="well">
|
||||
<div class="form-group btn-group">
|
||||
<span class="text-muted pull-right" style="margin-left:10px; line-height: 2em;">(Youtube, Vimeo, Dailymotion)</span>
|
||||
<label class="pull-left" for="urlvideo" style="width: 220px; line-height: 2em;">Set a video URL</label>
|
||||
<input class="form-control url pull-left" id="urlvideo" name="url" placeholder="//www.youtube.com/embed/yws1tbgNV7k" style="width: 400px;" t-translation="off" type="text"/>
|
||||
<button class="btn btn-default">Preview</button>
|
||||
<form action="#" class="form-inline well">
|
||||
<div class="o_video_dialog_form">
|
||||
<div class="form-group" id="o_video_form_group">
|
||||
<label class="mt8" for="o_video_text">Video code <small class="text-muted">(URL or Embed)</small></label>
|
||||
<textarea class="form-control url" id="o_video_text" placeholder="Copy-paste your URL or embed code here"/>
|
||||
<label class="control-label o_validate_feedback" for="o_video_text"><i class="fa fa-check"/><i class="fa fa-exclamation-triangle"/></label>
|
||||
</div>
|
||||
<div class="form-group btn-group">
|
||||
<label class="pull-left" for="urlvideo" style="width: 220px; line-height: 2em;">
|
||||
<span class="text-muted">— or —</span>Embed Video (HTML)</label>
|
||||
<input class="form-control url pull-left" id="embedvideo" name="embed" placeholder="<iframe src="//www.youtube.com/embed/yws1tbgNV7k"></iframe>" style="width: 400px;" t-translation="off" type="text"/>
|
||||
<button class="btn btn-default">Preview</button>
|
||||
<div class="text-right">
|
||||
<small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Instagram</i></b>, <b><i>Vine.co</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Youku</i></b> videos</small>
|
||||
</div>
|
||||
<div class="o_video_dialog_options hidden mt48">
|
||||
<small class="text-muted">Options</small>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item o_yt_option o_vim_option o_dm_option">
|
||||
<label class="o_switch mb0"><input id="o_video_autoplay" type="checkbox"/><span/>Autoplay</label>
|
||||
</li>
|
||||
<li class="list-group-item o_yt_option o_vim_option">
|
||||
<label class="o_switch mb0"><input id="o_video_loop" type="checkbox"/><span/>Loop</label>
|
||||
</li>
|
||||
<li class="list-group-item o_yt_option o_dm_option">
|
||||
<label class="o_switch mb0"><input id="o_video_hide_controls" type="checkbox"/><span/>Hide player controls</label>
|
||||
</li>
|
||||
<li class="list-group-item o_yt_option">
|
||||
<label class="o_switch mb0"><input id="o_video_hide_fullscreen" type="checkbox"/><span/>Hide fullscreen button</label>
|
||||
</li>
|
||||
<li class="list-group-item o_yt_option">
|
||||
<label class="o_switch mb0"><input id="o_video_hide_yt_logo" type="checkbox"/><span/>Hide Youtube logo</label>
|
||||
</li>
|
||||
<li class="list-group-item o_dm_option">
|
||||
<label class="o_switch mb0"><input id="o_video_hide_dm_logo" type="checkbox"/><span/>Hide Dailymotion logo</label>
|
||||
</li>
|
||||
<li class="list-group-item o_dm_option">
|
||||
<label class="o_switch mb0"><input id="o_video_hide_dm_share" type="checkbox"/><span/>Hide sharing button</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="video-preview">
|
||||
<div class="o_video_dialog_preview_text small mt16 mb8 hidden">Preview</div>
|
||||
<div class="media_iframe_video">
|
||||
<div class="media_iframe_video_size"/>
|
||||
<iframe allowfullscreen="allowfullscreen" frameborder="0" src=""/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mt8">
|
||||
<div class="checkbox">
|
||||
<label title="The feature might not be supported for every video type">
|
||||
<input id="autoplay" style="margin-right:5px" type="checkbox"/>Autoplay</label>
|
||||
<iframe class="o_video_dialog_iframe" allowfullscreen="allowfullscreen" frameborder="0" src=""/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user