Multiple front-end fixes (#2247)

Fixes:
* Sanitize user-provided content in HTML (Fixes #2193)
* Fix encoding of search query in prev/next pages (Fixes #2229)
* Fix some issues introduced with #2196:
   - Fix alignment of all <h3> elements (Move the inline style from the parent to the <h3> element)
   - Add missing comma on 'dir' HTML attribute (Typo introduced by PR #2196)

Code cleaning:
* Remove unnecessary 'each_sclice' + 'each' double loop in ECR files
* Clean the player's <source> list generation code (in player.ecr)
このコミットが含まれているのは:
Samantaz Fox 2021-07-15 23:01:36 +02:00 committed by GitHub
コミット 56ebef4352
この署名に対応する既知のキーがデータベースに存在しません
GPGキーID: 4AEE18F83AFDEB23
19個のファイルの変更161行の追加169行の削除

ファイルの表示

@ -312,6 +312,8 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false)
author_thumbnail = ""
end
author_name = HTML.escape(child["author"].as_s)
html << <<-END_HTML
<div class="pure-g" style="width:100%">
<div class="channel-profile pure-u-4-24 pure-u-md-2-24">
@ -320,7 +322,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false)
<div class="pure-u-20-24 pure-u-md-22-24">
<p>
<b>
<a class="#{child["authorIsChannelOwner"] == true ? "channel-owner" : ""}" href="#{child["authorUrl"]}">#{child["author"]}</a>
<a class="#{child["authorIsChannelOwner"] == true ? "channel-owner" : ""}" href="#{child["authorUrl"]}">#{author_name}</a>
</b>
<p style="white-space:pre-wrap">#{child["contentHtml"]}</p>
END_HTML

ファイルの表示

@ -9,13 +9,13 @@
<%= translate(locale, "Token") %>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:center">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:center">
<a href="/token_manager"><%= translate(locale, "Token manager") %></a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:right">
<a href="/preferences"><%= translate(locale, "Preferences") %></a>
</h3>
</div>

ファイルの表示

@ -1,6 +1,9 @@
<% ucid = channel.ucid %>
<% author = HTML.escape(channel.author) %>
<% content_for "header" do %>
<title><%= channel.author %> - Invidious</title>
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feed/channel/<%= channel.ucid %>" />
<title><%= author %> - Invidious</title>
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feed/channel/<%= ucid %>" />
<% end %>
<% if channel.banner %>
@ -17,12 +20,12 @@
<div class="pure-u-2-3">
<div class="channel-profile">
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
<span><%= channel.author %></span>
<span><%= author %></span>
</div>
</div>
<div class="pure-u-1-3" style="text-align:right">
<div class="pure-u-1-3">
<h3 style="text-align:right">
<a href="/feed/channel/<%= channel.ucid %>"><i class="icon ion-logo-rss"></i></a>
<a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a>
</h3>
</div>
</div>
@ -34,15 +37,13 @@
</div>
<div class="h-box">
<% ucid = channel.ucid %>
<% author = channel.author %>
<% sub_count_text = number_to_short_text(channel.sub_count) %>
<%= rendered "components/subscribe_widget" %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1-3">
<a href="https://www.youtube.com/channel/<%= channel.ucid %>"><%= translate(locale, "View channel on YouTube") %></a>
<a href="https://www.youtube.com/channel/<%= ucid %>"><%= translate(locale, "View channel on YouTube") %></a>
<div class="pure-u-1 pure-md-1-3">
<a href="/redirect?referer=<%= env.get?("current_page") %>"><%= translate(locale, "Switch Invidious Instance") %></a>
</div>
@ -55,12 +56,12 @@
<% if channel.auto_generated %>
<b><%= translate(locale, "Playlists") %></b>
<% else %>
<a href="/channel/<%= channel.ucid %>/playlists"><%= translate(locale, "Playlists") %></a>
<a href="/channel/<%= ucid %>/playlists"><%= translate(locale, "Playlists") %></a>
<% end %>
</div>
<div class="pure-u-1 pure-md-1-3">
<% if channel.tabs.includes? "community" %>
<a href="/channel/<%= channel.ucid %>/community"><%= translate(locale, "Community") %></a>
<a href="/channel/<%= ucid %>/community"><%= translate(locale, "Community") %></a>
<% end %>
</div>
</div>
@ -72,7 +73,7 @@
<% if sort_by == sort %>
<b><%= translate(locale, sort) %></b>
<% else %>
<a href="/channel/<%= channel.ucid %>?page=<%= page %>&sort_by=<%= sort %>">
<a href="/channel/<%= ucid %>?page=<%= page %>&sort_by=<%= sort %>">
<%= translate(locale, sort) %>
</a>
<% end %>
@ -87,17 +88,15 @@
</div>
<div class="pure-g">
<% items.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% items.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %>
<a href="/channel/<%= channel.ucid %>?page=<%= page - 1 %><% if sort_by != "newest" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<a href="/channel/<%= ucid %>?page=<%= page - 1 %><% if sort_by != "newest" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<%= translate(locale, "Previous page") %>
</a>
<% end %>
@ -105,7 +104,7 @@
<div class="pure-u-1 pure-u-lg-3-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if count == 60 %>
<a href="/channel/<%= channel.ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<a href="/channel/<%= ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<%= translate(locale, "Next page") %>
</a>
<% end %>

ファイルの表示

@ -1,5 +1,8 @@
<% ucid = channel.ucid %>
<% author = HTML.escape(channel.author) %>
<% content_for "header" do %>
<title><%= channel.author %> - Invidious</title>
<title><%= author %> - Invidious</title>
<% end %>
<% if channel.banner %>
@ -16,7 +19,7 @@
<div class="pure-u-2-3">
<div class="channel-profile">
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
<span><%= channel.author %></span>
<span><%= author %></span>
</div>
</div>
<div class="pure-u-1-3" style="text-align:right">
@ -33,8 +36,6 @@
</div>
<div class="h-box">
<% ucid = channel.ucid %>
<% author = channel.author %>
<% sub_count_text = number_to_short_text(channel.sub_count) %>
<%= rendered "components/subscribe_widget" %>
</div>
@ -79,7 +80,7 @@
<script id="community_data" type="application/json">
<%=
{
"ucid" => channel.ucid,
"ucid" => ucid,
"youtube_comments_text" => HTML.escape(translate(locale, "View YouTube comments")),
"comments_text" => HTML.escape(translate(locale, "View `x` comments", "{commentCount}")),
"hide_replies_text" => HTML.escape(translate(locale, "Hide replies")),

ファイルの表示

@ -30,7 +30,7 @@
<p dir="auto"><%= HTML.escape(item.title) %></p>
</a>
<a href="/channel/<%= item.ucid %>">
<p dir=auto"><b><%= HTML.escape(item.author) %></b></p>
<p dir="auto"><b><%= HTML.escape(item.author) %></b></p>
</a>
<% when MixVideo %>
<a href="/watch?v=<%= item.id %>&list=<%= item.rdid %>">
@ -45,7 +45,7 @@
<p dir="auto"><%= HTML.escape(item.title) %></p>
</a>
<a href="/channel/<%= item.ucid %>">
<p dir=auto"><b><%= HTML.escape(item.author) %></b></p>
<p dir="auto"><b><%= HTML.escape(item.author) %></b></p>
</a>
<% when PlaylistVideo %>
<a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.plid %>">
@ -77,7 +77,7 @@
<div class="video-card-row flexible">
<div class="flex-left"><a href="/channel/<%= item.ucid %>">
<p class="channel-name" dir=auto"><%= HTML.escape(item.author) %></p>
<p class="channel-name" dir="auto"><%= HTML.escape(item.author) %></p>
</a></div>
</div>
@ -139,7 +139,7 @@
<div class="video-card-row flexible">
<div class="flex-left"><a href="/channel/<%= item.ucid %>">
<p class="channel-name" dir=auto"><%= HTML.escape(item.author) %></p>
<p class="channel-name" dir="auto"><%= HTML.escape(item.author) %></p>
</a></div>
<div class="flex-right">
<div class="icon-buttons">

ファイルの表示

@ -10,17 +10,22 @@
<% audio_streams.each_with_index do |fmt, i| %>
<source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["mimeType"] %>' label="<%= fmt["bitrate"] %>k" selected="<%= i == 0 ? true : false %>">
<% end %>
<% else %>
<% else %>
<% if params.quality == "dash" %>
<source src="/api/manifest/dash/id/<%= video.id %>?local=true&unique_res=1" type='application/dash+xml' label="dash">
<% end %>
<% fmt_stream.each_with_index do |fmt, i| %>
<% if params.quality %>
<source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["mimeType"] %>' label="<%= fmt["quality"] %>" selected="<%= params.quality == fmt["quality"] %>">
<% else %>
<source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["mimeType"] %>' label="<%= fmt["quality"] %>" selected="<%= i == 0 ? true : false %>">
<% end %>
<%
fmt_stream.each_with_index do |fmt, i|
src_url = "/latest_version?id=#{video.id}&itag=#{fmt["itag"]}"
src_url += "&local=true" if params.local
quality = fmt["quality"]
mimetype = fmt["mimeType"]
selected = params.quality ? (params.quality == quality) : (i == 0)
%>
<source src="<%= src_url %>" type="<%= mimetype %>" label="<%= quality %>" selected="<%= selected %>">
<% end %>
<% end %>

ファイルの表示

@ -1,14 +1,16 @@
<% title = HTML.escape(playlist.title) %>
<% content_for "header" do %>
<title><%= playlist.title %> - Invidious</title>
<title><%= title %> - Invidious</title>
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feed/playlist/<%= plid %>" />
<% end %>
<form class="pure-form" action="/edit_playlist?list=<%= plid %>" method="post">
<div class="pure-g h-box">
<div class="pure-u-2-3">
<h3><input class="pure-input-1" maxlength="150" name="title" type="text" value="<%= playlist.title %>"></h3>
<h3><input class="pure-input-1" maxlength="150" name="title" type="text" value="<%= title %>"></h3>
<b>
<%= playlist.author %> |
<%= HTML.escape(playlist.author) %> |
<%= translate(locale, "`x` videos", "#{playlist.video_count}") %> |
<%= translate(locale, "Updated `x` ago", recode_date(playlist.updated, locale)) %> |
<i class="icon <%= {"ion-md-globe", "ion-ios-unlock", "ion-ios-lock"}[playlist.privacy.value] %>"></i>
@ -55,11 +57,9 @@
</div>
<div class="pure-g">
<% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% videos.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">

ファイルの表示

@ -6,13 +6,13 @@
<div class="pure-u-1-3">
<h3><%= translate(locale, "`x` videos", %(<span id="count">#{user.watched.size}</span>)) %></h3>
</div>
<div class="pure-u-1-3" style="text-align:center">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:center">
<a href="/feed/subscriptions"><%= translate(locale, "`x` subscriptions", %(<span id="count">#{user.subscriptions.size}</span>)) %></a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:right">
<a href="/clear_watch_history"><%= translate(locale, "Clear watch history") %></a>
</h3>
</div>
@ -28,31 +28,27 @@
<script src="/js/watched_widget.js"></script>
<div class="pure-g">
<% watched.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<div class="pure-u-1 pure-u-md-1-4">
<div class="h-box">
<a style="width:100%" href="/watch?v=<%= item %>">
<% if !env.get("preferences").as(Preferences).thin_mode %>
<div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item %>/mqdefault.jpg"/>
<form data-onsubmit="return_false" action="/watch_ajax?action_mark_unwatched=1&id=<%= item %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched">
<a data-onclick="mark_unwatched" data-id="<%= item %>" href="javascript:void(0)">
<button type="submit" style="all:unset">
<i class="icon ion-md-trash"></i>
</button>
</a>
</p>
</form>
</div>
<p></p>
<% end %>
</a>
</div>
</div>
<% end %>
<% watched.each do |item| %>
<div class="pure-u-1 pure-u-md-1-4">
<div class="h-box">
<a style="width:100%" href="/watch?v=<%= item %>">
<% if !env.get("preferences").as(Preferences).thin_mode %>
<div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item %>/mqdefault.jpg"/>
<form data-onsubmit="return_false" action="/watch_ajax?action_mark_unwatched=1&id=<%= item %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.encode_www_form(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched">
<a data-onclick="mark_unwatched" data-id="<%= item %>" href="javascript:void(0)">
<button type="submit" style="all:unset"><i class="icon ion-md-trash"></i></button>
</a>
</p>
</form>
</div>
<p></p>
<% end %>
</a>
</div>
</div>
<% end %>
</div>

ファイルの表示

@ -26,7 +26,7 @@
<form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.encode_www_form(referer) %>&type=google" method="post">
<fieldset>
<% if email %>
<input name="email" type="hidden" value="<%= email %>">
<input name="email" type="hidden" value="<%= HTML.escape(email) %>">
<% else %>
<label for="email"><%= translate(locale, "E-mail") %> :</label>
<input required class="pure-input-1" name="email" type="email" placeholder="<%= translate(locale, "E-mail") %>">
@ -62,7 +62,7 @@
<form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.encode_www_form(referer) %>&type=invidious" method="post">
<fieldset>
<% if email %>
<input name="email" type="hidden" value="<%= email %>">
<input name="email" type="hidden" value="<%= HTML.escape(email) %>">
<% else %>
<label for="email"><%= translate(locale, "User ID") %> :</label>
<input required class="pure-input-1" name="email" type="text" placeholder="<%= translate(locale, "User ID") %>">

ファイルの表示

@ -1,22 +1,20 @@
<% content_for "header" do %>
<title><%= mix.title %> - Invidious</title>
<title><%= HTML.escape(mix.title) %> - Invidious</title>
<% end %>
<div class="pure-g h-box">
<div class="pure-u-2-3">
<h3><%= mix.title %></h3>
<h3><%= HTML.escape(mix.title) %></h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:right">
<a href="/feed/playlist/<%= mix.id %>"><i class="icon ion-logo-rss"></i></a>
</h3>
</div>
</div>
<div class="pure-g">
<% mix.videos.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% mix.videos.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>

ファイルの表示

@ -1,17 +1,20 @@
<% title = HTML.escape(playlist.title) %>
<% author = HTML.escape(playlist.author) %>
<% content_for "header" do %>
<title><%= playlist.title %> - Invidious</title>
<title><%= title %> - Invidious</title>
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feed/playlist/<%= plid %>" />
<% end %>
<div class="pure-g h-box">
<div class="pure-u-2-3">
<h3><%= playlist.title %></h3>
<h3><%= title %></h3>
<% if playlist.is_a? InvidiousPlaylist %>
<b>
<% if playlist.author == user.try &.email %>
<a href="/view_all_playlists"><%= playlist.author %></a> |
<a href="/view_all_playlists"><%= author %></a> |
<% else %>
<%= playlist.author %> |
<%= author %> |
<% end %>
<%= translate(locale, "`x` videos", "#{playlist.video_count}") %> |
<%= translate(locale, "Updated `x` ago", recode_date(playlist.updated, locale)) %> |
@ -26,11 +29,12 @@
</b>
<% else %>
<b>
<a href="/channel/<%= playlist.ucid %>"><%= playlist.author %></a> |
<a href="/channel/<%= playlist.ucid %>"><%= author %></a> |
<%= translate(locale, "`x` videos", "#{playlist.video_count}") %> |
<%= translate(locale, "Updated `x` ago", recode_date(playlist.updated, locale)) %>
</b>
<% end %>
<% if !playlist.is_a? InvidiousPlaylist %>
<div class="pure-u-2-3">
<a href="https://www.youtube.com/playlist?list=<%= playlist.id %>">
@ -40,7 +44,6 @@
<a href="/redirect?referer=<%= env.get?("current_page") %>">
<%= translate(locale, "Switch Invidious Instance") %>
</a>
</div>
<% end %>
</div>
@ -93,11 +96,9 @@
<% end %>
<div class="pure-g">
<% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% videos.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">

ファイルの表示

@ -1,5 +1,8 @@
<% ucid = channel.ucid %>
<% author = HTML.escape(channel.author) %>
<% content_for "header" do %>
<title><%= channel.author %> - Invidious</title>
<title><%= author %> - Invidious</title>
<% end %>
<% if channel.banner %>
@ -16,12 +19,12 @@
<div class="pure-u-2-3">
<div class="channel-profile">
<img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
<span><%= channel.author %></span>
<span><%= author %></span>
</div>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3 style="text-align:right">
<a href="/feed/channel/<%= channel.ucid %>"><i class="icon ion-logo-rss"></i></a>
<a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a>
</h3>
</div>
</div>
@ -33,8 +36,6 @@
</div>
<div class="h-box">
<% ucid = channel.ucid %>
<% author = channel.author %>
<% sub_count_text = number_to_short_text(channel.sub_count) %>
<%= rendered "components/subscribe_widget" %>
</div>
@ -42,7 +43,7 @@
<div class="pure-g h-box">
<div class="pure-g pure-u-1-3">
<div class="pure-u-1 pure-md-1-3">
<a href="https://www.youtube.com/channel/<%= channel.ucid %>/playlists"><%= translate(locale, "View channel on YouTube") %></a>
<a href="https://www.youtube.com/channel/<%= ucid %>/playlists"><%= translate(locale, "View channel on YouTube") %></a>
</div>
<div class="pure-u-1 pure-md-1-3">
@ -50,7 +51,7 @@
</div>
<div class="pure-u-1 pure-md-1-3">
<a href="/channel/<%= channel.ucid %>"><%= translate(locale, "Videos") %></a>
<a href="/channel/<%= ucid %>"><%= translate(locale, "Videos") %></a>
</div>
<div class="pure-u-1 pure-md-1-3">
<% if !channel.auto_generated %>
@ -59,7 +60,7 @@
</div>
<div class="pure-u-1 pure-md-1-3">
<% if channel.tabs.includes? "community" %>
<a href="/channel/<%= channel.ucid %>/community"><%= translate(locale, "Community") %></a>
<a href="/channel/<%= ucid %>/community"><%= translate(locale, "Community") %></a>
<% end %>
</div>
</div>
@ -71,7 +72,7 @@
<% if sort_by == sort %>
<b><%= translate(locale, sort) %></b>
<% else %>
<a href="/channel/<%= channel.ucid %>/playlists?sort_by=<%= sort %>">
<a href="/channel/<%= ucid %>/playlists?sort_by=<%= sort %>">
<%= translate(locale, sort) %>
</a>
<% end %>
@ -86,18 +87,16 @@
</div>
<div class="pure-g">
<% items.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% items.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-md-4-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if continuation %>
<a href="/channel/<%= channel.ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<a href="/channel/<%= ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= HTML.escape(sort_by) %><% end %>">
<%= translate(locale, "Next page") %>
</a>
<% end %>

ファイルの表示

@ -12,9 +12,7 @@
<%= rendered "components/feed_menu" %>
<div class="pure-g">
<% popular_videos.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% popular_videos.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>

ファイルの表示

@ -2,6 +2,8 @@
<title><%= search_query.not_nil!.size > 30 ? HTML.escape(query.not_nil![0,30].rstrip(".") + "...") : HTML.escape(query.not_nil!) %> - Invidious</title>
<% end %>
<% search_query_encoded = env.get?("search").try { |x| URI.encode(x.as(String), space_to_plus: true) } %>
<!-- Search redirection and filtering UI -->
<% if count == 0 %>
<h3 style="text-align: center">
@ -105,7 +107,7 @@
<div class="pure-g h-box v-box">
<div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %>
<a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page - 1 %>">
<a href="/search?q=<%= search_query_encoded %>&page=<%= page - 1 %>">
<%= translate(locale, "Previous page") %>
</a>
<% end %>
@ -113,7 +115,7 @@
<div class="pure-u-1 pure-u-lg-3-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if count >= 20 %>
<a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page + 1 %>">
<a href="/search?q=<%= search_query_encoded %>&page=<%= page + 1 %>">
<%= translate(locale, "Next page") %>
</a>
<% end %>
@ -121,17 +123,15 @@
</div>
<div class="pure-g">
<% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% videos.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
<% if page > 1 %>
<a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page - 1 %>">
<a href="/search?q=<%= search_query_encoded %>&page=<%= page - 1 %>">
<%= translate(locale, "Previous page") %>
</a>
<% end %>
@ -139,7 +139,7 @@
<div class="pure-u-1 pure-u-lg-3-5"></div>
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if count >= 20 %>
<a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page + 1 %>">
<a href="/search?q=<%= search_query_encoded %>&page=<%= page + 1 %>">
<%= translate(locale, "Next page") %>
</a>
<% end %>

ファイルの表示

@ -10,15 +10,15 @@
</a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:center">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:center">
<a href="/feed/history">
<%= translate(locale, "Watch history") %>
</a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:right">
<a href="/data_control?referer=<%= URI.encode_www_form(referer) %>">
<%= translate(locale, "Import/export") %>
</a>
@ -31,7 +31,7 @@
<div class="pure-g<% if channel.deleted %> deleted <% end %>">
<div class="pure-u-2-5">
<h3 style="padding-left:0.5em">
<a href="/channel/<%= channel.id %>"><%= channel.author %></a>
<a href="/channel/<%= channel.id %>"><%= HTML.escape(channel.author) %></a>
</h3>
</div>
<div class="pure-u-2-5"></div>

ファイルの表示

@ -11,13 +11,13 @@
<a href="/subscription_manager"><%= translate(locale, "Manage subscriptions") %></a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:center">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:center">
<a href="/feed/history"><%= translate(locale, "Watch history") %></a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
<div class="pure-u-1-3">
<h3 style="text-align:right">
<a href="/feed/private?token=<%= token %>"><i class="icon ion-logo-rss"></i></a>
</h3>
</div>
@ -34,11 +34,9 @@
<% end %>
<div class="pure-g">
<% notifications.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% notifications.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="h-box">
@ -55,11 +53,9 @@
<script src="/js/watched_widget.js"></script>
<div class="pure-g">
<% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% videos.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">

ファイルの表示

@ -41,9 +41,7 @@
</div>
<div class="pure-g">
<% trending.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% trending.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>

ファイルの表示

@ -16,11 +16,9 @@
</div>
<div class="pure-g">
<% items_created.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% items_created.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>
<div class="pure-g h-box">
@ -30,9 +28,7 @@
</div>
<div class="pure-g">
<% items_saved.each_slice(4) do |slice| %>
<% slice.each do |item| %>
<%= rendered "components/item" %>
<% end %>
<% end %>
<% items_saved.each do |item| %>
<%= rendered "components/item" %>
<% end %>
</div>

ファイルの表示

@ -1,10 +1,15 @@
<% ucid = video.ucid %>
<% title = HTML.escape(video.title) %>
<% author = HTML.escape(video.author) %>
<% content_for "header" do %>
<meta name="thumbnail" content="<%= thumbnail %>">
<meta name="description" content="<%= HTML.escape(video.short_description) %>">
<meta name="keywords" content="<%= video.keywords.join(",") %>">
<meta property="og:site_name" content="Invidious">
<meta property="og:url" content="<%= HOST_URL %>/watch?v=<%= video.id %>">
<meta property="og:title" content="<%= HTML.escape(video.title) %>">
<meta property="og:title" content="<%= title %>">
<meta property="og:image" content="/vi/<%= video.id %>/maxres.jpg">
<meta property="og:description" content="<%= video.short_description %>">
<meta property="og:type" content="video.other">
@ -16,7 +21,7 @@
<meta name="twitter:card" content="player">
<meta name="twitter:site" content="@omarroth1">
<meta name="twitter:url" content="<%= HOST_URL %>/watch?v=<%= video.id %>">
<meta name="twitter:title" content="<%= HTML.escape(video.title) %>">
<meta name="twitter:title" content="<%= title %>">
<meta name="twitter:description" content="<%= video.short_description %>">
<meta name="twitter:image" content="<%= HOST_URL %>/vi/<%= video.id %>/maxres.jpg">
<meta name="twitter:player" content="<%= HOST_URL %>/embed/<%= video.id %>">
@ -24,7 +29,7 @@
<meta name="twitter:player:height" content="720">
<link rel="alternate" href="https://www.youtube.com/watch?v=<%= video.id %>">
<%= rendered "components/player_sources" %>
<title><%= HTML.escape(video.title) %> - Invidious</title>
<title><%= title %> - Invidious</title>
<!-- Description expansion also updates the 'Show more' button to 'Show less' so
we're going to need to do it here in order to allow for translations.
@ -69,7 +74,7 @@ we're going to need to do it here in order to allow for translations.
<div class="h-box">
<h1>
<%= HTML.escape(video.title) %>
<%= title %>
<% if params.listen %>
<a title="<%=translate(locale, "Video mode")%>" href="/watch?<%= env.params.query %>&listen=0">
<i class="icon ion-ios-videocam"></i>
@ -134,8 +139,8 @@ we're going to need to do it here in order to allow for translations.
<div class="pure-control-group">
<label for="playlist_id"><%= translate(locale, "Add to playlist: ") %></label>
<select style="width:100%" name="playlist_id" id="playlist_id">
<% playlists.each do |plid, title| %>
<option data-plid="<%= plid %>" value="<%= plid %>"><%= title %></option>
<% playlists.each do |plid, playlist_title| %>
<option data-plid="<%= plid %>" value="<%= plid %>"><%= HTML.escape(playlist_title) %></option>
<% end %>
</select>
</div>
@ -227,12 +232,10 @@ we're going to need to do it here in order to allow for translations.
<% if !video.author_thumbnail.empty? %>
<img src="/ggpht<%= URI.parse(video.author_thumbnail).request_target %>">
<% end %>
<span id="channel-name"><%= video.author %></span>
<span id="channel-name"><%= author %></span>
</div>
</a>
<% ucid = video.ucid %>
<% author = video.author %>
<% sub_count_text = video.sub_count_text %>
<%= rendered "components/subscribe_widget" %>