aboutsummaryrefslogtreecommitdiffstats
path: root/youtube/templates/watch.html
diff options
context:
space:
mode:
authorJesús <heckyel@hyperbola.info>2020-12-14 23:44:29 -0500
committerJesús <heckyel@hyperbola.info>2020-12-14 23:44:29 -0500
commit7a765dc664d20f966e4e52abac1f5372045e166c (patch)
tree641f4de8cc11fd9f3234558f957b7bb6b8faf45b /youtube/templates/watch.html
parent9d0be82e7425641a58a551fefce26385dee2f9d3 (diff)
downloadyt-local-7a765dc664d20f966e4e52abac1f5372045e166c.tar.lz
yt-local-7a765dc664d20f966e4e52abac1f5372045e166c.tar.xz
yt-local-7a765dc664d20f966e4e52abac1f5372045e166c.zip
Change general design theme
Diffstat (limited to 'youtube/templates/watch.html')
-rw-r--r--youtube/templates/watch.html905
1 files changed, 271 insertions, 634 deletions
diff --git a/youtube/templates/watch.html b/youtube/templates/watch.html
index 36b2198..44fc5a7 100644
--- a/youtube/templates/watch.html
+++ b/youtube/templates/watch.html
@@ -3,378 +3,17 @@
{% import "common_elements.html" as common_elements %}
{% import "comments.html" as comments with context %}
{% block style %}
- details > summary{
- background-color: var(--interface-color);
- border-style: outset;
- border-width: 2px;
- font-weight: bold;
- padding-bottom: 2px;
- }
- details > summary:hover{
- text-decoration: underline;
- }
-
- .playability-error{
- height: 360px;
- width: 640px;
- grid-column: 2;
- background-color: var(--video-background-color);
- text-align:center;
- }
- .playability-error span{
- position: relative;
- top: 50%;
- transform: translate(-50%, -50%);
- }
-
- .live-url-choices{
- height: 360px;
- width: 640px;
- grid-column: 2;
- background-color: var(--video-background-color);
- padding: 25px 0px 0px 25px;
- }
- .live-url-choices ol{
- list-style: none;
- padding:0px;
- margin:0px;
- margin-top: 15px;
- }
- .live-url-choices input{
- width: 400px;
- }
- .url-choice-label{
- display: inline-block;
- width: 150px;
- }
-
- {% if settings.theater_mode %}
- /* This is the constant aspect ratio trick
- Percentages in padding-top declarations are based on the width of the
- parent element. We can use this trick to achieve a constant aspect ratio
- for video-container-inner by setting height to 0.
-
- So the video height will decrease if the browser window is narrow,
- but it will keep same aspect ratio. Must use absolute positioning on
- video to keep it inside its container since the container's height is 0.
-
- However, because we widen the video player longer than the video's
- intrinsic width for long video to make scrubbing easier, we can't use
- the aspect ratio to set the height. The height needs to be the
- intrinsic height in these cases. So we use a media query so aspect
- ratio trick is only used if page width is less than or equal to
- intrinsic video width.
- */
- #video-container{
- grid-column: 1 / span 5;
- justify-self: center;
- max-width: 100%;
- width: {{ theater_video_target_width }}px;
- margin-bottom: 10px;
- }
- #video-container-inner{
- height: {{ video_height}}px;
- position: relative;
- }
- @media(max-width:{{ video_width }}px){
- #video-container-inner{
- padding-top: calc(100%*{{video_height}}/{{video_width}});
- height: 0px;
- }
- }
- video{
- background-color: var(--video-background-color);
- position: absolute;
- top: 0px;
- left: 0px;
- width: 100%;
- height: 100%;
- }
- .side-videos{
- grid-row: 2 /span 3;
- width: 400px;
- }
- .video-info{
- width: 640px;
- }
- {% else %}
- #video-container{
- grid-column: 2;
- }
- #video-container, #video-container-inner, video{
- height: 360px;
- width: 640px;
- }
- .side-videos{
- grid-row: 1 /span 4;
- }
- {% endif %}
-
- main{
- display:grid;
- grid-template-columns: 1fr 640px 40px 400px 1fr;
- grid-template-rows: auto auto auto auto;
- align-content: start;
- }
-
- .video-info{
- grid-column: 2;
- grid-row: 2;
- display: grid;
- grid-template-rows: 0fr 0fr 0fr 20px 0fr 0fr;
- grid-template-columns: 1fr 1fr;
- align-content: start;
- }
- .video-info > .title{
- grid-column: 1 / span 2;
- min-width: 0;
- }
- .video-info > .labels{
- justify-self:start;
- list-style: none;
- padding: 0px;
- margin: 5px 0px;
- }
- .video-info > .labels:empty{
- margin: 0px;
- }
- .labels > li{
- display: inline;
- margin-right:5px;
- background-color: var(--interface-color);
- padding: 2px 5px;
- border-style: solid;
- border-width: 1px;
- }
- .video-info > address{
- grid-column: 1;
- grid-row: 3;
- justify-self: start;
- }
- .video-info > .views{
- grid-column: 2;
- grid-row: 3;
- justify-self:end;
- }
- .video-info > time{
- grid-column: 1;
- grid-row: 4;
- justify-self:start;
- }
- .video-info > .likes-dislikes{
- grid-column: 2;
- grid-row: 4;
- justify-self:end;
- }
- .video-info > .external-player-controls{
- justify-self: start;
- grid-row: 5;
- grid-column: 1;
- margin-bottom: 8px;
- }
- #speed-control{
- width: 65px;
- text-align: center;
- background-color: var(--interface-color);
- color: var(--text-color);
- }
- .video-info > .checkbox{
- justify-self:end;
- align-self: start;
-
- grid-row: 5;
- grid-column: 2;
- }
- .video-info > .download-dropdown{
- grid-column:1 / span 2;
- grid-row: 6;
- }
- .video-info > .description{
- background-color:var(--interface-color);
- margin-top:8px;
- white-space: pre-wrap;
- min-width: 0;
- word-wrap: break-word;
- grid-column: 1 / span 2;
- grid-row: 7;
- padding: 5px;
- }
-
- .music-list{
- grid-row:8;
- grid-column: 1 / span 2;
- background-color: var(--interface-color);
- padding-bottom: 7px;
- }
- .music-list table,th,td{
- border: 1px solid;
- }
- .music-list th,td{
- padding-left:4px;
- padding-right:5px;
- }
- .music-list caption{
- text-align:left;
- font-weight:bold;
- margin-bottom:5px;
- }
- .more-info{
- grid-row: 9;
- grid-column: 1 / span 2;
- background-color: var(--interface-color);
- }
- .more-info > summary{
- font-weight: normal;
- border-width: 1px 0px;
- border-style: solid;
- }
- .more-info-content{
- padding: 5px;
- }
- .more-info-content p{
- margin: 8px 0px;
- }
- .comments-area-outer{
- grid-column: 2;
- grid-row: 3;
- margin-top:10px;
- }
- .comments-disabled{
- background-color: var(--interface-color);
- padding: 5px;
- font-weight: bold;
- }
- .comments-area-inner{
- padding-top: 10px;
- }
- .comment{
- width:640px;
- }
-
- .side-videos{
- grid-column: 4;
- max-width: 640px;
- }
- #transcript-details{
- margin-bottom: 10px;
- }
- table#transcript-table {
- border-collapse: collapse;
- width: 100%;
- }
- table#transcript-table td, th {
- border: 1px solid #dddddd;
- }
- div#transcript-div {
- background-color: var(--interface-color);
- padding: 5px;
- }
- .playlist{
- border-style: solid;
- border-width: 2px;
- border-color: lightgray;
- margin-bottom: 10px;
- }
- .playlist-header{
- background-color: var(--interface-color);
- padding: 3px;
- border-bottom-style: solid;
- border-bottom-width: 2px;
- border-bottom-color: lightgray;
- }
- .playlist-header h3{
- margin: 2px;
- }
- .playlist-metadata{
- list-style: none;
- padding: 0px;
- margin: 0px;
- }
- .playlist-metadata li{
- display: inline;
- margin: 2px;
- }
- .playlist-videos{
- height: 300px;
- overflow-y: scroll;
- display: grid;
- grid-auto-rows: 90px;
- grid-row-gap: 10px;
- padding-top: 10px;
- }
- .related-videos-inner{
- padding-top: 10px;
- display: grid;
- grid-auto-rows: 90px;
- grid-row-gap: 10px;
- }
- .thumbnail-box{ /* overides rule in shared.css */
- height: 90px !important;
- width: 120px !important;
- }
-
- /* Put related vids below videos when window is too small */
- /* 1100px instead of 1080 because W3C is full of idiots who include scrollbar width */
- @media (max-width:1100px){
- main{
- grid-template-columns: 1fr 640px 40px 1fr;
- }
- .side-videos{
- margin-top: 10px;
- grid-column: 2;
- grid-row: 3;
- width: initial;
- }
- .comments-area-outer{
- grid-row: 4;
- }
- }
-
- .download-dropdown-content{
- background-color: var(--interface-color);
- padding: 10px;
- list-style: none;
- margin: 0px;
- }
- li.download-format{
- margin-bottom: 7px;
- }
- .format-attributes{
- list-style: none;
- padding: 0px;
- margin: 0px;
- display: flex;
- flex-direction: row;
- }
- .format-attributes li{
- white-space: nowrap;
- max-height: 1.2em;
- }
- .format-ext{
- width: 60px;
- }
- .format-video-quality{
- width: 140px;
- }
- .format-audio-quality{
- width: 120px;
- }
- .format-file-size{
- width: 80px;
- }
- .format-codecs{
- width: 120px;
- }
+ <link href="/youtube.com/static/watch.css" rel="stylesheet">
{% endblock style %}
{% block main %}
{% if playability_error %}
<div class="playability-error">
<span>{{ 'Error: ' + playability_error }}
- {% if invidious_reload_button %}
- <a href="{{ video_url }}&use_invidious=0"><br>
-Reload without invidious (for usage of new identity button).</a>
- {% endif %}
+ {% if invidious_reload_button %}
+ <a href="{{ video_url }}&use_invidious=0"><br>
+ Reload without invidious (for usage of new identity button).</a>
+ {% endif %}
</span>
</div>
{% elif (video_sources.__len__() == 0 or live) and hls_formats.__len__() != 0 %}
@@ -387,143 +26,137 @@ Reload without invidious (for usage of new identity button).</a>
</ol>
</div>
{% else %}
- <div id="video-container">
- <div id="video-container-inner">
- <video controls autofocus class="video" height="{{ video_height }}px">
- {% for video_source in video_sources %}
- <source src="{{ video_source['src'] }}" type="{{ video_source['type'] }}">
- {% endfor %}
+ <figure class="sc-video">
+ <video id="js-video-player" playsinline controls>
+ {% for video_source in video_sources %}
+ <source src="{{ video_source['src'] }}" type="{{ video_source['type'] }}">
+ {% endfor %}
- {% for source in subtitle_sources %}
- {% if source['on'] %}
- <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}" default>
- {% else %}
- <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}">
- {% endif %}
- {% endfor %}
+ {% for source in subtitle_sources %}
+ {% if source['on'] %}
+ <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}" default>
+ {% else %}
+ <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}">
+ {% endif %}
+ {% endfor %}
+ </video>
+ </figure>
- </video>
- </div>
- </div>
{% if time_start != 0 %}
<script>
- document.querySelector('video').currentTime = {{ time_start|tojson }};
+ document.querySelector('js-video-player').currentTime = {{ time_start|tojson }};
</script>
{% endif %}
{% endif %}
- <div class="video-info">
- <h2 class="title">{{ title }}</h2>
- <ul class="labels">
- {%- if unlisted -%}
- <li class="is-unlisted">Unlisted</li>
- {%- endif -%}
- {%- if age_restricted -%}
- <li class="age-restricted">Age-restricted</li>
- {%- endif -%}
- {%- if limited_state -%}
- <li>Limited state</li>
- {%- endif -%}
- {%- if live -%}
- <li>Live</li>
- {%- endif -%}
- </ul>
- <address>Uploaded by <a href="{{ uploader_channel_url }}">{{ uploader }}</a></address>
- <span class="views">{{ view_count }} views</span>
-
-
- <time datetime="$upload_date">Published on {{ time_published }}</time>
- <span class="likes-dislikes">{{ like_count }} likes {{ dislike_count }} dislikes</span>
-
- <div class="external-player-controls">
- <input id="speed-control" type="text">
- <script>
- var video = document.querySelector('video');
- var speedInput = document.querySelector('#speed-control');
- speedInput.addEventListener('keyup', (event) => {
- if (event.key === 'Enter') {
- var speed = parseFloat(speedInput.value);
- if(!isNaN(speed)){
- video.playbackRate = speed;
- }
- }
- });
- </script>
- </div>
- <input class="checkbox" name="video_info_list" value="{{ video_info }}" form="playlist-edit" type="checkbox">
-
- <details class="download-dropdown">
- <summary class="download-dropdown-label">Download</summary>
- <ul class="download-dropdown-content">
- {% for format in download_formats %}
- <li class="download-format">
- <a class="download-link" href="{{ format['url'] }}">
- <ol class="format-attributes">
- <li class="format-ext">{{ format['ext'] }}</li>
- <li class="format-video-quality">{{ format['video_quality'] }}</li>
- <li class="format-audio-quality">{{ format['audio_quality'] }}</li>
- <li class="format-file-size">{{ format['file_size'] }}</li>
- <li class="format-codecs">{{ format['codecs'] }}</li>
- </ol>
- </a>
- </li>
- {% endfor %}
- {% for download in other_downloads %}
- <li class="download-format">
- <a href="{{ download['url'] }}">
- <ol class="format-attributes">
- <li class="format-ext">{{ download['ext'] }}</li>
- <li class="format-label">{{ download['label'] }}</li>
- </ol>
- </a>
- </li>
- {% endfor %}
+ <div class="sc-info">
+ <div class="video-info">
+ <h1 class="v-title">{{ title }}</h1>
+
+ <ul class="labels">
+ {%- if unlisted -%}
+ <li class="is-unlisted">Unlisted</li>
+ {%- endif -%}
+ {%- if age_restricted -%}
+ <li class="age-restricted">Age-restricted</li>
+ {%- endif -%}
+ {%- if limited_state -%}
+ <li>Limited state</li>
+ {%- endif -%}
+ {%- if live -%}
+ <li>Live</li>
+ {%- endif -%}
</ul>
- </details>
+ <address class="v-uploaded">Uploaded by <a href="{{ uploader_channel_url }}">{{ uploader }}</a></address>
+ <span class="v-views">{{ view_count }} views</span>
+ <time class="v-published" datetime="$upload_date">Published on {{ time_published }}</time>
+ <span class="v-likes-dislikes">{{ like_count }} likes {{ dislike_count }} dislikes</span>
+
+ <div class="external-player-controls">
+ <input class="speed" id="speed-control" type="text">
+ <script>
+ (function main() {
+ 'use strict';
+ const video = document.getElementById('js-video-player');
+ const speedInput = document.getElementById('speed-control');
+ speedInput.addEventListener('keyup', (event) => {
+ if (event.key === 'Enter') {
+ let speed = parseFloat(speedInput.value);
+ if(!isNaN(speed)){
+ video.playbackRate = speed;
+ }
+ }
+ });
+ }());
+ </script>
+ </div>
- <span class="description">{{ common_elements.text_runs(description)|escape|urlize|timestamps|safe }}</span>
- <div class="music-list">
- {% if music_list.__len__() != 0 %}
- <hr>
- <table>
- <caption>Music</caption>
- <tr>
- {% for attribute in music_attributes %}
- <th>{{ attribute }}</th>
- {% endfor %}
- </tr>
- {% for track in music_list %}
+ <input class="v-checkbox" name="video_info_list" value="{{ video_info }}" form="playlist-edit" type="checkbox">
+
+ <details class="v-download">
+ <summary class="download-dropdown-label">Download</summary>
+ <ul class="download-dropdown-content">
+ {% for format in download_formats %}
+ <li class="download-format">
+ <a class="download-link" href="{{ format['url'] }}" download="{{ title }}.{{ format['ext'] }}">
+ {{ format['ext'] }} {{ format['video_quality'] }} {{ format['audio_quality'] }} {{ format['file_size'] }} {{ format['codecs'] }}
+ </a>
+ </li>
+ {% endfor %}
+ {% for download in other_downloads %}
+ <li class="download-format">
+ <a href="{{ download['url'] }}" download>
+ {{ download['ext'] }} {{ download['label'] }}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ </details>
+ <span class="v-description">{{ common_elements.text_runs(description)|escape|urlize|timestamps|safe }}</span>
+
+ <div class="v-music-list">
+ {% if music_list.__len__() != 0 %}
+ <hr>
+ <table>
+ <caption>Music</caption>
<tr>
{% for attribute in music_attributes %}
- <td>{{ track.get(attribute.lower(), '') }}</td>
+ <th>{{ attribute }}</th>
{% endfor %}
</tr>
- {% endfor %}
- </table>
- {% endif %}
- </div>
- <details class="more-info">
- <summary>More info</summary>
- <div class="more-info-content">
- <p>Tor exit node: {{ ip_address }}</p>
- {% if invidious_used %}
- <p>Used Invidious as fallback.</p>
- {% endif %}
- <p class="allowed-countries">Allowed countries: {{ allowed_countries|join(', ') }}</p>
-
- {% if settings.use_sponsorblock_js %}
- <ul class="more-actions">
- <li><label><input type=checkbox id=skip_sponsors checked>skip sponsors</label> <span id=skip_n></span>
- </ul>
+ {% for track in music_list %}
+ <tr>
+ {% for attribute in music_attributes %}
+ <td>{{ track.get(attribute.lower(), '') }}</td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </table>
{% endif %}
</div>
- </details>
- </div>
+ <details class="v-more-info">
+ <summary>More info</summary>
+ <div class="more-info-content">
+ <p>Tor exit node: {{ ip_address }}</p>
+ {% if invidious_used %}
+ <p>Used Invidious as fallback.</p>
+ {% endif %}
+ <p class="allowed-countries">Allowed countries: {{ allowed_countries|join(', ') }}</p>
+ {% if settings.use_sponsorblock_js %}
+ <ul class="more-actions">
+ <li><label><input type=checkbox id=skip_sponsors checked>skip sponsors</label> <span id=skip_n></span>
+ </ul>
+ {% endif %}
+ </div>
+ </details>
+ </div>
+
+ <div class="side-videos">
- <div class="side-videos">
- {% if playlist %}
- <div class="playlist">
+ <!-- playlist -->
+ {% if playlist %}
+ <div class="site-playlist">
<div class="playlist-header">
<a href="{{ playlist['url'] }}" title="{{ playlist['title'] }}"><h3>{{ playlist['title'] }}</h3></a>
<ul class="playlist-metadata">
@@ -550,167 +183,171 @@ Reload without invidious (for usage of new identity button).</a>
</nav>
{% if playlist['current_index'] is not none %}
<script>
- // from https://stackoverflow.com/a/6969486
- function escapeRegExp(string) {
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
- }
- var playability_error = {{ 'true' if playability_error else 'false' }};
- var playlist_id = {{ playlist['id']|tojson }};
- playlist_id = escapeRegExp(playlist_id);
-
- // read cookies on whether to autoplay thru playlist
- // pain in the ass:
- // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
- var cookieValue = document.cookie.replace(new RegExp(
- '(?:(?:^|.*;\\s*)autoplay_' + playlist_id + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
- var autoplayEnabled = 0;
- if(cookieValue.length === 0){
- autoplayEnabled = 0;
- } else {
- autoplayEnabled = Number(cookieValue);
- }
-
- // check the checkbox if autoplay is on
- var checkbox = document.querySelector('#autoplay-toggle');
- if(autoplayEnabled){
- checkbox.checked = true;
- }
-
- // listen for checkbox to turn autoplay on and off
- checkbox.addEventListener( 'change', function() {
- if(this.checked) {
- autoplayEnabled = 1;
- document.cookie = 'autoplay_' + playlist_id + '=1';
- } else {
- autoplayEnabled = 0;
- document.cookie = 'autoplay_' + playlist_id + '=0';
- }
- });
-
- if(!playability_error){
- // play the video if autoplay is on
- var vid = document.querySelector('video');
- if(autoplayEnabled){
- vid.play();
- }
- }
-
- var currentIndex = {{ playlist['current_index']|tojson }};
- {% if playlist['current_index']+1 == playlist['items']|length %}
- var nextVideoUrl = null;
- {% else %}
- var nextVideoUrl = {{ (playlist['items'][playlist['current_index']+1]['url'])|tojson }};
- {% endif %}
- var nextVideoDelay = 1000;
-
- // scroll playlist to proper position
- var pl = document.querySelector('.playlist-videos');
- // item height + gap == 100
- pl.scrollTop = 100*currentIndex;
-
- // go to next video when video ends
- // https://stackoverflow.com/a/2880950
- if(nextVideoUrl){
- if(playability_error){
- videoEnded();
- } else {
- vid.addEventListener('ended', videoEnded, false);
- }
- function nextVideo(){
- if(autoplayEnabled){
- window.location.href = nextVideoUrl;
- }
- }
- function videoEnded(e) {
- window.setTimeout(nextVideo, nextVideoDelay);
- }
- }
+ (function main() {
+ // from https://stackoverflow.com/a/6969486
+ function escapeRegExp(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+ }
+ let playability_error = {{ 'true' if playability_error else 'false' }};
+ let playlist_id = {{ playlist['id']|tojson }};
+ playlist_id = escapeRegExp(playlist_id);
+
+ // read cookies on whether to autoplay thru playlist
+ // pain in the ass:
+ // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
+ let cookieValue = document.cookie.replace(new RegExp(
+ '(?:(?:^|.*;\\s*)autoplay_' + playlist_id + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
+ let autoplayEnabled = 0;
+ if(cookieValue.length === 0){
+ autoplayEnabled = 0;
+ } else {
+ autoplayEnabled = Number(cookieValue);
+ }
+
+ // check the checkbox if autoplay is on
+ let checkbox = document.querySelector('#autoplay-toggle');
+ if(autoplayEnabled){
+ checkbox.checked = true;
+ }
+
+ // listen for checkbox to turn autoplay on and off
+ checkbox.addEventListener( 'change', function() {
+ if(this.checked) {
+ autoplayEnabled = 1;
+ document.cookie = 'autoplay_' + playlist_id + '=1';
+ } else {
+ autoplayEnabled = 0;
+ document.cookie = 'autoplay_' + playlist_id + '=0';
+ }
+ });
+
+ const vid = document.getElementById('js-video-player');
+ if(!playability_error){
+ if(autoplayEnabled){
+ vid.play();
+ }
+ }
+
+ let currentIndex = {{ playlist['current_index']|tojson }};
+ {% if playlist['current_index']+1 == playlist['items']|length %}
+ let nextVideoUrl = null;
+ {% else %}
+ let nextVideoUrl = {{ (playlist['items'][playlist['current_index']+1]['url'])|tojson }};
+ {% endif %}
+ let nextVideoDelay = 1000;
+
+ // scroll playlist to proper position
+ let pl = document.querySelector('.playlist-videos');
+ // item height + gap == 100
+ pl.scrollTop = 100*currentIndex;
+
+ // go to next video when video ends
+ // https://stackoverflow.com/a/2880950
+ if(nextVideoUrl){
+ if(playability_error){
+ videoEnded();
+ } else {
+ vid.addEventListener('ended', videoEnded, false);
+ }
+ function nextVideo(){
+ if(autoplayEnabled){
+ window.location.href = nextVideoUrl;
+ }
+ }
+ function videoEnded(e) {
+ window.setTimeout(nextVideo, nextVideoDelay);
+ }
+ }
+ }());
</script>
{% endif %}
{% if playlist['id'] is not none %}
<script>
- // lazy load playlist images
- // copied almost verbatim from
- // https://css-tricks.com/tips-for-rolling-your-own-lazy-loading/
- // IntersectionObserver isn't supported in pre-quantum
- // firefox versions, but the alternative of making it
- // manually is a performance drain, so oh well
- var observer = new IntersectionObserver(lazyLoad, {
-
- // where in relation to the edge of the viewport, we are observing
- rootMargin: "100px",
-
- // how much of the element needs to have intersected
- // in order to fire our loading function
- threshold: 1.0
-
- });
-
- function lazyLoad(elements) {
- elements.forEach(item => {
- if (item.intersectionRatio > 0) {
-
- // set the src attribute to trigger a load
- item.target.src = item.target.dataset.src;
-
- // stop observing this element. Our work here is done!
- observer.unobserve(item.target);
- };
- });
- };
-
- // Tell our observer to observe all img elements with a "lazy" class
- var lazyImages = document.querySelectorAll('img.lazy');
- lazyImages.forEach(img => {
- observer.observe(img);
- });
+ (function main() {
+ // lazy load playlist images
+ // copied almost verbatim from
+ // https://css-tricks.com/tips-for-rolling-your-own-lazy-loading/
+ // IntersectionObserver isn't supported in pre-quantum
+ // firefox versions, but the alternative of making it
+ // manually is a performance drain, so oh well
+ let observer = new IntersectionObserver(lazyLoad, {
+ // where in relation to the edge of the viewport, we are observing
+ rootMargin: "100px",
+ // how much of the element needs to have intersected
+ // in order to fire our loading function
+ threshold: 1.0
+ });
+
+ function lazyLoad(elements) {
+ elements.forEach(item => {
+ if (item.intersectionRatio > 0) {
+ // set the src attribute to trigger a load
+ item.target.src = item.target.dataset.src;
+ // stop observing this element. Our work here is done!
+ observer.unobserve(item.target);
+ };
+ });
+ };
+
+ // Tell our observer to observe all img elements with a "lazy" class
+ let lazyImages = document.querySelectorAll('img.lazy');
+ lazyImages.forEach(img => {
+ observer.observe(img);
+ });
+ }());
</script>
{% endif %}
</div>
- {% endif %}
+ {% endif %}
+ <!-- /playlist -->
+
+ {% if subtitle_sources %}
+ <details id="transcript-details">
+ <summary>Transcript</summary>
+ <div id="transcript-div">
+ <select id="select-tt">
+ {% for source in subtitle_sources %}
+ <option>{{ source['label'] }}</option>
+ {% endfor %}
+ </select>
+ <label for="transcript-use-table">Table view</label>
+ <input id="transcript-use-table" type="checkbox">
+ <table id="transcript-table"></table>
+ </div>
+ </details>
+ {% endif %}
+
- {% if subtitle_sources %}
- <details id="transcript-details">
- <summary>Transcript</summary>
- <div id="transcript-div">
- <select id="select-tt">
- {% for source in subtitle_sources %}
- <option>{{ source['label'] }}</option>
+ {% if settings.related_videos_mode != 0 %}
+ <details class="related-videos-outer" {{'open' if settings.related_videos_mode == 1 else ''}}>
+ <summary>Related Videos</summary>
+ <nav class="related-videos-inner">
+ {% for info in related %}
+ {{ common_elements.item(info, include_badges=false) }}
{% endfor %}
- </select>
- <label for="transcript-use-table">Table view</label>
- <input type="checkbox" id="transcript-use-table">
- <table id="transcript-table"></table>
- </div>
- </details>
- {% endif %}
+ </nav>
+ </details>
+ {% endif %}
- {% if settings.related_videos_mode != 0 %}
- <details class="related-videos-outer" {{'open' if settings.related_videos_mode == 1 else ''}}>
- <summary>Related Videos</summary>
- <nav class="related-videos-inner">
- {% for info in related %}
- {{ common_elements.item(info, include_badges=false) }}
- {% endfor %}
- </nav>
- </details>
- {% endif %}
- </div>
+ </div>
- {% if settings.comments_mode != 0 %}
- {% if comments_disabled %}
- <div class="comments-area-outer comments-disabled">Comments disabled</div>
- {% else %}
- <details class="comments-area-outer" {{'open' if settings.comments_mode == 1 else ''}}>
- <summary>{{ comment_count|commatize }} comment{{'s' if comment_count != 1 else ''}}</summary>
- <section class="comments-area-inner comments-area">
- {% if comments_info %}
- {{ comments.video_comments(comments_info) }}
- {% endif %}
- </section>
- </details>
+ <!-- comments -->
+ {% if settings.comments_mode != 0 %}
+ {% if comments_disabled %}
+ <div class="comments-area-outer comments-disabled">Comments disabled</div>
+ {% else %}
+ <details class="comments-area-outer" {{'open' if settings.comments_mode == 1 else ''}}>
+ <summary>{{ comment_count|commatize }} comment{{'s' if comment_count != 1 else ''}}</summary>
+ <div class="comments-area-inner comments-area">
+ {% if comments_info %}
+ {{ comments.video_comments(comments_info) }}
+ {% endif %}
+ </div>
+ </details>
+ {% endif %}
{% endif %}
- {% endif %}
+
+ </div>
<script> data = {{ js_data|tojson }} </script>
<script src="/youtube.com/static/js/common.js"></script>