Merge branch 'next-minor' into develop
This commit is contained in:
commit
0b921c6657
16 changed files with 240 additions and 20 deletions
|
|
@ -14,6 +14,7 @@
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
* Add basic html5 audio/video embedding support [#6418](https://github.com/diaspora/diaspora/pull/6418)
|
||||||
|
|
||||||
# 0.7.3.1
|
# 0.7.3.1
|
||||||
|
|
||||||
|
|
|
||||||
6
Gemfile
6
Gemfile
|
|
@ -26,7 +26,7 @@ gem "json-schema", "2.8.0"
|
||||||
|
|
||||||
# Authentication
|
# Authentication
|
||||||
|
|
||||||
gem "devise", "4.3.0"
|
gem "devise", "4.4.1"
|
||||||
gem "devise_lastseenable", "0.0.6"
|
gem "devise_lastseenable", "0.0.6"
|
||||||
|
|
||||||
# Captcha
|
# Captcha
|
||||||
|
|
@ -122,6 +122,8 @@ source "https://rails-assets.org" do
|
||||||
gem "rails-assets-perfect-scrollbar", "0.6.16"
|
gem "rails-assets-perfect-scrollbar", "0.6.16"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
gem "markdown-it-html5-embed", "1.0.0"
|
||||||
|
|
||||||
# Localization
|
# Localization
|
||||||
|
|
||||||
gem "http_accept_language", "2.1.1"
|
gem "http_accept_language", "2.1.1"
|
||||||
|
|
@ -186,7 +188,7 @@ gem "typhoeus", "1.3.0"
|
||||||
# Views
|
# Views
|
||||||
|
|
||||||
gem "gon", "6.1.0"
|
gem "gon", "6.1.0"
|
||||||
gem "hamlit", "2.8.4"
|
gem "hamlit", "2.8.6"
|
||||||
gem "mobile-fu", "1.4.0"
|
gem "mobile-fu", "1.4.0"
|
||||||
gem "rails-timeago", "2.16.0"
|
gem "rails-timeago", "2.16.0"
|
||||||
gem "will_paginate", "3.1.6"
|
gem "will_paginate", "3.1.6"
|
||||||
|
|
|
||||||
31
Gemfile.lock
31
Gemfile.lock
|
|
@ -133,7 +133,7 @@ GEM
|
||||||
tins (~> 1.6)
|
tins (~> 1.6)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
crass (1.0.2)
|
crass (1.0.3)
|
||||||
cucumber (2.4.0)
|
cucumber (2.4.0)
|
||||||
builder (>= 2.1.2)
|
builder (>= 2.1.2)
|
||||||
cucumber-core (~> 1.5.0)
|
cucumber-core (~> 1.5.0)
|
||||||
|
|
@ -156,7 +156,7 @@ GEM
|
||||||
railties (>= 4, < 5.2)
|
railties (>= 4, < 5.2)
|
||||||
cucumber-wire (0.0.1)
|
cucumber-wire (0.0.1)
|
||||||
database_cleaner (1.6.1)
|
database_cleaner (1.6.1)
|
||||||
devise (4.3.0)
|
devise (4.4.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0, < 5.2)
|
railties (>= 4.1.0, < 5.2)
|
||||||
|
|
@ -187,7 +187,7 @@ GEM
|
||||||
entypo-rails (3.0.0)
|
entypo-rails (3.0.0)
|
||||||
railties (>= 4.1, < 6)
|
railties (>= 4.1, < 6)
|
||||||
equalizer (0.0.11)
|
equalizer (0.0.11)
|
||||||
erubi (1.6.1)
|
erubi (1.7.0)
|
||||||
eslintrb (2.1.0)
|
eslintrb (2.1.0)
|
||||||
execjs
|
execjs
|
||||||
multi_json (>= 1.3)
|
multi_json (>= 1.3)
|
||||||
|
|
@ -273,7 +273,7 @@ GEM
|
||||||
guard-rubocop (1.3.0)
|
guard-rubocop (1.3.0)
|
||||||
guard (~> 2.0)
|
guard (~> 2.0)
|
||||||
rubocop (~> 0.20)
|
rubocop (~> 0.20)
|
||||||
haml (5.0.3)
|
haml (5.0.4)
|
||||||
temple (>= 0.8.0)
|
temple (>= 0.8.0)
|
||||||
tilt
|
tilt
|
||||||
haml_lint (0.26.0)
|
haml_lint (0.26.0)
|
||||||
|
|
@ -282,7 +282,7 @@ GEM
|
||||||
rake (>= 10, < 13)
|
rake (>= 10, < 13)
|
||||||
rubocop (>= 0.49.0)
|
rubocop (>= 0.49.0)
|
||||||
sysexits (~> 1.1)
|
sysexits (~> 1.1)
|
||||||
hamlit (2.8.4)
|
hamlit (2.8.6)
|
||||||
temple (>= 0.8.0)
|
temple (>= 0.8.0)
|
||||||
thor
|
thor
|
||||||
tilt
|
tilt
|
||||||
|
|
@ -306,7 +306,8 @@ GEM
|
||||||
httparty (0.15.6)
|
httparty (0.15.6)
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (0.8.6)
|
i18n (0.9.5)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
i18n-inflector (2.6.7)
|
i18n-inflector (2.6.7)
|
||||||
i18n (>= 0.4.1)
|
i18n (>= 0.4.1)
|
||||||
i18n-inflector-rails (1.0.7)
|
i18n-inflector-rails (1.0.7)
|
||||||
|
|
@ -359,7 +360,7 @@ GEM
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
logging-rails (0.6.0)
|
logging-rails (0.6.0)
|
||||||
logging (>= 1.8)
|
logging (>= 1.8)
|
||||||
loofah (2.1.1)
|
loofah (2.2.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
lumberjack (1.0.12)
|
lumberjack (1.0.12)
|
||||||
|
|
@ -367,6 +368,7 @@ GEM
|
||||||
systemu (~> 2.6.2)
|
systemu (~> 2.6.2)
|
||||||
mail (2.6.6)
|
mail (2.6.6)
|
||||||
mime-types (>= 1.16, < 4)
|
mime-types (>= 1.16, < 4)
|
||||||
|
markdown-it-html5-embed (1.0.0)
|
||||||
markerb (1.1.0)
|
markerb (1.1.0)
|
||||||
memoizable (0.4.2)
|
memoizable (0.4.2)
|
||||||
thread_safe (~> 0.3, >= 0.3.1)
|
thread_safe (~> 0.3, >= 0.3.1)
|
||||||
|
|
@ -377,7 +379,7 @@ GEM
|
||||||
mini_magick (4.8.0)
|
mini_magick (4.8.0)
|
||||||
mini_mime (0.1.4)
|
mini_mime (0.1.4)
|
||||||
mini_portile2 (2.3.0)
|
mini_portile2 (2.3.0)
|
||||||
minitest (5.10.3)
|
minitest (5.11.3)
|
||||||
mobile-fu (1.4.0)
|
mobile-fu (1.4.0)
|
||||||
rack-mobile-detect
|
rack-mobile-detect
|
||||||
rails
|
rails
|
||||||
|
|
@ -473,7 +475,7 @@ GEM
|
||||||
byebug (~> 9.1)
|
byebug (~> 9.1)
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
public_suffix (3.0.0)
|
public_suffix (3.0.0)
|
||||||
rack (2.0.3)
|
rack (2.0.4)
|
||||||
rack-cors (1.0.1)
|
rack-cors (1.0.1)
|
||||||
rack-google-analytics (1.2.0)
|
rack-google-analytics (1.2.0)
|
||||||
actionpack
|
actionpack
|
||||||
|
|
@ -492,7 +494,7 @@ GEM
|
||||||
rack-rewrite (1.5.1)
|
rack-rewrite (1.5.1)
|
||||||
rack-ssl (1.4.1)
|
rack-ssl (1.4.1)
|
||||||
rack
|
rack
|
||||||
rack-test (0.7.0)
|
rack-test (0.8.2)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rails (5.1.4)
|
rails (5.1.4)
|
||||||
actioncable (= 5.1.4)
|
actioncable (= 5.1.4)
|
||||||
|
|
@ -576,7 +578,7 @@ GEM
|
||||||
rainbow (2.2.2)
|
rainbow (2.2.2)
|
||||||
rake
|
rake
|
||||||
raindrops (0.19.0)
|
raindrops (0.19.0)
|
||||||
rake (12.1.0)
|
rake (12.3.0)
|
||||||
rb-fsevent (0.10.2)
|
rb-fsevent (0.10.2)
|
||||||
rb-inotify (0.9.10)
|
rb-inotify (0.9.10)
|
||||||
ffi (>= 0.5.0, < 2)
|
ffi (>= 0.5.0, < 2)
|
||||||
|
|
@ -712,7 +714,7 @@ GEM
|
||||||
unf (~> 0.1.0)
|
unf (~> 0.1.0)
|
||||||
typhoeus (1.3.0)
|
typhoeus (1.3.0)
|
||||||
ethon (>= 0.9.0)
|
ethon (>= 0.9.0)
|
||||||
tzinfo (1.2.3)
|
tzinfo (1.2.5)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.2.0)
|
uglifier (3.2.0)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
|
|
@ -780,7 +782,7 @@ DEPENDENCIES
|
||||||
cucumber-api-steps (= 0.13)
|
cucumber-api-steps (= 0.13)
|
||||||
cucumber-rails (= 1.5.0)
|
cucumber-rails (= 1.5.0)
|
||||||
database_cleaner (= 1.6.1)
|
database_cleaner (= 1.6.1)
|
||||||
devise (= 4.3.0)
|
devise (= 4.4.1)
|
||||||
devise_lastseenable (= 0.0.6)
|
devise_lastseenable (= 0.0.6)
|
||||||
diaspora-prosody-config (= 0.0.7)
|
diaspora-prosody-config (= 0.0.7)
|
||||||
diaspora_federation-json_schema (= 0.2.3)
|
diaspora_federation-json_schema (= 0.2.3)
|
||||||
|
|
@ -801,7 +803,7 @@ DEPENDENCIES
|
||||||
guard-rspec (= 4.7.3)
|
guard-rspec (= 4.7.3)
|
||||||
guard-rubocop (= 1.3.0)
|
guard-rubocop (= 1.3.0)
|
||||||
haml_lint (= 0.26.0)
|
haml_lint (= 0.26.0)
|
||||||
hamlit (= 2.8.4)
|
hamlit (= 2.8.6)
|
||||||
handlebars_assets (= 0.23.2)
|
handlebars_assets (= 0.23.2)
|
||||||
http_accept_language (= 2.1.1)
|
http_accept_language (= 2.1.1)
|
||||||
i18n-inflector-rails (= 1.0.7)
|
i18n-inflector-rails (= 1.0.7)
|
||||||
|
|
@ -815,6 +817,7 @@ DEPENDENCIES
|
||||||
json-schema-rspec (= 0.0.4)
|
json-schema-rspec (= 0.0.4)
|
||||||
leaflet-rails (= 1.2.0)
|
leaflet-rails (= 1.2.0)
|
||||||
logging-rails (= 0.6.0)
|
logging-rails (= 0.6.0)
|
||||||
|
markdown-it-html5-embed (= 1.0.0)
|
||||||
markerb (= 1.1.0)
|
markerb (= 1.1.0)
|
||||||
mini_magick (= 4.8.0)
|
mini_magick (= 4.8.0)
|
||||||
minitest
|
minitest
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
|
app.helpers.allowedEmbedsMime = function(mimetype) {
|
||||||
|
var v = document.createElement(mimetype[1]);
|
||||||
|
return v.canPlayType && v.canPlayType(mimetype[0]) !== "";
|
||||||
|
};
|
||||||
|
|
||||||
app.helpers.textFormatter = function(text, mentions) {
|
app.helpers.textFormatter = function(text, mentions) {
|
||||||
mentions = mentions ? mentions : [];
|
mentions = mentions ? mentions : [];
|
||||||
|
|
||||||
|
|
@ -83,6 +88,30 @@
|
||||||
|
|
||||||
// Bootstrap table markup
|
// Bootstrap table markup
|
||||||
md.renderer.rules.table_open = function () { return "<table class=\"table table-striped\">\n"; };
|
md.renderer.rules.table_open = function () { return "<table class=\"table table-striped\">\n"; };
|
||||||
|
|
||||||
|
var html5medialPlugin = window.markdownitHTML5Embed;
|
||||||
|
md.use(html5medialPlugin, {html5embed: {
|
||||||
|
inline: false,
|
||||||
|
autoAppend: true,
|
||||||
|
renderFn: function handleBarsRenderFn(parsed, mediaAttributes) {
|
||||||
|
var attributes = mediaAttributes[parsed.mediaType];
|
||||||
|
return HandlebarsTemplates["media-embed_tpl"]({
|
||||||
|
mediaType: parsed.mediaType,
|
||||||
|
attributes: attributes,
|
||||||
|
mimetype: parsed.mimeType,
|
||||||
|
sourceURL: parsed.url,
|
||||||
|
title: parsed.title,
|
||||||
|
fallback: parsed.fallback,
|
||||||
|
needsCover: parsed.mediaType === "video"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
attributes: {
|
||||||
|
"audio": "controls preload=none",
|
||||||
|
"video": "preload=none"
|
||||||
|
},
|
||||||
|
isAllowedMimeType: app.helpers.allowedEmbedsMime
|
||||||
|
}});
|
||||||
|
|
||||||
return md.render(text);
|
return md.render(text);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,29 @@ app.views.Content = app.views.Base.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// This function is called when user clicks cover for HTML5 embedded video
|
||||||
|
onVideoThumbClick: function(evt) {
|
||||||
|
var clickedThumb;
|
||||||
|
if ($(evt.target).hasClass("thumb")) {
|
||||||
|
clickedThumb = $(evt.target);
|
||||||
|
} else {
|
||||||
|
clickedThumb = $(evt.target).parent(".thumb");
|
||||||
|
}
|
||||||
|
clickedThumb.find(".video-overlay").addClass("hidden");
|
||||||
|
clickedThumb.parents(".collapsed").children(".expander").click();
|
||||||
|
var video = clickedThumb.find("video");
|
||||||
|
video.attr("controls", "");
|
||||||
|
video.get(0).load();
|
||||||
|
video.get(0).play();
|
||||||
|
clickedThumb.unbind("click");
|
||||||
|
},
|
||||||
|
|
||||||
|
bindMediaEmbedThumbClickEvent: function() {
|
||||||
|
this.$(".media-embed .thumb").bind("click", this.onVideoThumbClick);
|
||||||
|
},
|
||||||
|
|
||||||
postRenderTemplate : function(){
|
postRenderTemplate : function(){
|
||||||
|
this.bindMediaEmbedThumbClickEvent();
|
||||||
_.defer(_.bind(this.collapseOversized, this));
|
_.defer(_.bind(this.collapseOversized, this));
|
||||||
|
|
||||||
// run collapseOversized again after all contained images are loaded
|
// run collapseOversized again after all contained images are loaded
|
||||||
|
|
@ -93,6 +115,8 @@ app.views.StatusMessage = app.views.Content.extend({
|
||||||
|
|
||||||
app.views.ExpandedStatusMessage = app.views.StatusMessage.extend({
|
app.views.ExpandedStatusMessage = app.views.StatusMessage.extend({
|
||||||
postRenderTemplate : function(){
|
postRenderTemplate : function(){
|
||||||
|
this.bindMediaEmbedThumbClickEvent();
|
||||||
|
|
||||||
var photoAttachments = this.$(".photo-attachments");
|
var photoAttachments = this.$(".photo-attachments");
|
||||||
if(photoAttachments.length > 0) {
|
if(photoAttachments.length > 0) {
|
||||||
new app.views.Gallery({ el: photoAttachments });
|
new app.views.Gallery({ el: photoAttachments });
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
//= require markdown-it-sanitizer
|
//= require markdown-it-sanitizer
|
||||||
//= require markdown-it-sub
|
//= require markdown-it-sub
|
||||||
//= require markdown-it-sup
|
//= require markdown-it-sup
|
||||||
|
//= require markdown-it-html5-embed
|
||||||
//= require highlightjs
|
//= require highlightjs
|
||||||
//= require clear-form
|
//= require clear-form
|
||||||
//= require corejs-typeahead
|
//= require corejs-typeahead
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@
|
||||||
@import 'chat';
|
@import 'chat';
|
||||||
@import 'markdown-content';
|
@import 'markdown-content';
|
||||||
@import 'oembed';
|
@import 'oembed';
|
||||||
|
@import 'media-embed';
|
||||||
@import 'post-content';
|
@import 'post-content';
|
||||||
|
|
||||||
// contacts
|
// contacts
|
||||||
|
|
|
||||||
21
app/assets/stylesheets/media-embed.scss
Normal file
21
app/assets/stylesheets/media-embed.scss
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
$stub-bg-color: #ddd;
|
||||||
|
|
||||||
|
.media-embed {
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
.thumb {
|
||||||
|
@include video-overlay;
|
||||||
|
|
||||||
|
background-color: $stub-bg-color;
|
||||||
|
|
||||||
|
video {
|
||||||
|
min-height: 60%;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
audio {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/assets/templates/media-embed_tpl.jst.hbs
Normal file
19
app/assets/templates/media-embed_tpl.jst.hbs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<div class="media-embed">
|
||||||
|
{{#if needsCover}}
|
||||||
|
<div class="thumb">
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<{{mediaType}} {{{attributes}}}>
|
||||||
|
<source type="{{mimetype}}" src="{{sourceURL}}" />
|
||||||
|
{{title}}
|
||||||
|
</{{mediaType}}>
|
||||||
|
|
||||||
|
{{#if needsCover}}
|
||||||
|
<div class="video-overlay">
|
||||||
|
<div class="video-info">
|
||||||
|
<div class="title">{{title}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
@ -9,11 +9,11 @@ screenshot_opts = "--require features --format pretty"
|
||||||
%>
|
%>
|
||||||
|
|
||||||
# 'normal' test runs
|
# 'normal' test runs
|
||||||
default: <%= std_opts %> -r features
|
default: <%= std_opts %> -r features --tags ~@nophantomjs
|
||||||
wip: -r features --tags @wip:3 --wip features
|
wip: -r features --tags @wip:3 --wip features
|
||||||
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip --tags ~@screenshots
|
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip --tags ~@screenshots
|
||||||
|
|
||||||
# screenshot feature
|
# screenshot feature
|
||||||
ref_screens: "<%= screenshot_opts %> --tags @reference-screenshots"
|
ref_screens: "<%= screenshot_opts %> --tags @reference-screenshots"
|
||||||
cmp_screens: "<%= screenshot_opts %> --tags @comparison-screenshots"
|
cmp_screens: "<%= screenshot_opts %> --tags @comparison-screenshots"
|
||||||
all_screens: "<%= screenshot_opts %> --tags @screenshots"
|
all_screens: "<%= screenshot_opts %> --tags @screenshots"
|
||||||
|
|
|
||||||
|
|
@ -436,7 +436,7 @@ en:
|
||||||
size_of_images_q: "Can I customize the size of images in posts or comments?"
|
size_of_images_q: "Can I customize the size of images in posts or comments?"
|
||||||
size_of_images_a: "No. Images are resized automatically to fit the stream or single-post view. Markdown does not have a code for specifying the size of an image."
|
size_of_images_a: "No. Images are resized automatically to fit the stream or single-post view. Markdown does not have a code for specifying the size of an image."
|
||||||
embed_multimedia_q: "How do I embed a video, audio, or other multimedia content into a post?"
|
embed_multimedia_q: "How do I embed a video, audio, or other multimedia content into a post?"
|
||||||
embed_multimedia_a: "You can usually just paste the URL (e.g. http://www.youtube.com/watch?v=nnnnnnnnnnn ) into your post and the video or audio will be embedded automatically. The sites supported include: YouTube, Vimeo, SoundCloud, Flickr and a few more. diaspora* uses oEmbed for this feature. We’re supporting more media sources all the time. Remember to always post simple, full links – no shortened links; no operators after the base URL – and give it a little time before you refresh the page after posting for seeing the preview."
|
embed_multimedia_a: "You can usually just paste the URL (e.g. http://www.youtube.com/watch?v=nnnnnnnnnnn ) into your post and the video or audio will be embedded automatically. The sites supported include: YouTube, Vimeo, SoundCloud, Flickr and a few more. diaspora* uses oEmbed for this feature. If you post a direct link to an audio or video file, diaspora* will embed it using standard HTML5 player. We’re supporting more media sources all the time. Remember to always post simple, full links – no shortened links; no operators after the base URL – and give it a little time before you refresh the page after posting for seeing the preview."
|
||||||
post_location_q: "How do I add my location to a post?"
|
post_location_q: "How do I add my location to a post?"
|
||||||
post_location_a: "Click the pin icon next to the camera in the publisher. This will insert your location from OpenStreetMap. You can edit your location – you might only want to include the city you’re in rather than the specific street address."
|
post_location_a: "Click the pin icon next to the camera in the publisher. This will insert your location from OpenStreetMap. You can edit your location – you might only want to include the city you’re in rather than the specific street address."
|
||||||
post_poll_q: "How do I add a poll to my post?"
|
post_poll_q: "How do I add a poll to my post?"
|
||||||
|
|
|
||||||
22
features/desktop/media-embed.feature
Normal file
22
features/desktop/media-embed.feature
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# We can create a separate cucumber profile that will run these tests with Selenium
|
||||||
|
@nophantomjs
|
||||||
|
@javascript
|
||||||
|
Feature: oembed
|
||||||
|
In order to make videos easy accessible
|
||||||
|
As a user
|
||||||
|
I want the media links in my posts be replaced by an embedded player
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given following user exists:
|
||||||
|
| username | email |
|
||||||
|
| Alice Smith | alice@alice.alice |
|
||||||
|
And I sign in as "alice@alice.alice"
|
||||||
|
|
||||||
|
Scenario: Post a video link
|
||||||
|
When I click the publisher and post "[title](http://example.com/file.ogv)"
|
||||||
|
Then I should see a HTML5 video player
|
||||||
|
|
||||||
|
Scenario: Post an audio link
|
||||||
|
When I click the publisher and post "[title](http://example.com/file.ogg)"
|
||||||
|
Then I should see a HTML5 audio player
|
||||||
|
|
||||||
6
features/step_definitions/media_embed_steps.rb
Normal file
6
features/step_definitions/media_embed_steps.rb
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
Then /^I should see a HTML5 (video|audio) player$/ do |type|
|
||||||
|
find(".post-content .media-embed")
|
||||||
|
find(".stream-container").should have_css(".post-content .media-embed #{type}")
|
||||||
|
end
|
||||||
|
|
@ -26,13 +26,17 @@ module PublishingCukeHelpers
|
||||||
submit_publisher
|
submit_publisher
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def visible_text_from_markdown(text)
|
||||||
|
CGI.unescapeHTML(ActionController::Base.helpers.strip_tags(Diaspora::MessageRenderer.new(text).markdownified.strip))
|
||||||
|
end
|
||||||
|
|
||||||
def submit_publisher
|
def submit_publisher
|
||||||
txt = find("#publisher #status_message_text").value
|
txt = find("#publisher #status_message_text").value
|
||||||
find("#publisher .btn-primary").click
|
find("#publisher .btn-primary").click
|
||||||
# wait for the publisher to be closed
|
# wait for the publisher to be closed
|
||||||
expect(find("#publisher")["class"]).to include("closed")
|
expect(find("#publisher")["class"]).to include("closed")
|
||||||
# wait for the content to appear
|
# wait for the content to appear
|
||||||
expect(find("#main-stream")).to have_content(txt)
|
expect(find("#main-stream")).to have_content(visible_text_from_markdown(txt))
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_and_post(text)
|
def click_and_post(text)
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,54 @@ describe("app.helpers.textFormatter", function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context("media embed", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
spyOn(app.helpers, "allowedEmbedsMime").and.returnValue(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("embeds audio", function() {
|
||||||
|
var html =
|
||||||
|
'<p><a href="https://example.org/file.mp3" target="_blank" rel="noopener noreferrer">title</a></p>\n' +
|
||||||
|
'<div class="media-embed">\n' +
|
||||||
|
"\n" +
|
||||||
|
" <audio controls preload=none>\n" +
|
||||||
|
' <source type="audio/mpeg" src="https://example.org/file.mp3" />\n' +
|
||||||
|
" title\n" +
|
||||||
|
" </audio>\n" +
|
||||||
|
"\n" +
|
||||||
|
"</div>\n";
|
||||||
|
var content = "[title](https://example.org/file.mp3)";
|
||||||
|
var parsed = this.formatter(content);
|
||||||
|
|
||||||
|
expect(parsed).toContain(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("embeds video", function() {
|
||||||
|
var html =
|
||||||
|
'<p><a href="https://example.org/file.mp4" target="_blank" rel="noopener noreferrer">title</a></p>\n' +
|
||||||
|
'<div class="media-embed">\n' +
|
||||||
|
' <div class="thumb">\n' +
|
||||||
|
"\n" +
|
||||||
|
" <video preload=none>\n" +
|
||||||
|
' <source type="video/mp4" src="https://example.org/file.mp4" />\n' +
|
||||||
|
" title\n" +
|
||||||
|
" </video>\n" +
|
||||||
|
"\n" +
|
||||||
|
' <div class="video-overlay">\n' +
|
||||||
|
' <div class="video-info">\n' +
|
||||||
|
' <div class="title">title</div>\n' +
|
||||||
|
" </div>\n" +
|
||||||
|
" </div>\n" +
|
||||||
|
" </div>\n" +
|
||||||
|
"</div>\n";
|
||||||
|
|
||||||
|
var content = "[title](https://example.org/file.mp4)";
|
||||||
|
var parsed = this.formatter(content);
|
||||||
|
|
||||||
|
expect(parsed).toContain(html);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context("real world examples", function(){
|
context("real world examples", function(){
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,43 @@ describe("app.views.Content", function(){
|
||||||
expect(this.view.presenter().location).toEqual(factory.location());
|
expect(this.view.presenter().location).toEqual(factory.location());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// These tests don't work in PhantomJS because it doesn't support HTML5 <video>.
|
||||||
|
if (/PhantomJS/.exec(navigator.userAgent) === null) {
|
||||||
|
describe("onVideoThumbClick", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.post = new app.models.StatusMessage({text: "[title](https://www.w3schools.com/html/mov_bbb.mp4)"});
|
||||||
|
this.view = new app.views.StatusMessage({model: this.post});
|
||||||
|
|
||||||
|
this.view.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
this.view.$("video").stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("hides video overlay", function() {
|
||||||
|
expect(this.view.$(".video-overlay").length).toBe(1);
|
||||||
|
this.view.$(".media-embed .thumb").click();
|
||||||
|
expect(this.view.$(".video-overlay")).toHaveClass("hidden");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("expands posts on click", function() {
|
||||||
|
this.view.$(".collapsible").height(500);
|
||||||
|
this.view.collapseOversized();
|
||||||
|
|
||||||
|
expect(this.view.$(".collapsed").length).toBe(1);
|
||||||
|
this.view.$(".media-embed .thumb").click();
|
||||||
|
expect(this.view.$(".opened").length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("plays video", function(done) {
|
||||||
|
this.view.$("video").on("playing", function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.view.$(".media-embed .thumb").click();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue