From 58c1a68ad9023581555b4d9c943dfd447b5c92bf Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Sat, 4 Jan 2020 15:27:45 +0100 Subject: Change embed code --- assets/js/player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'assets/js') diff --git a/assets/js/player.js b/assets/js/player.js index e58af0cd..79788b1e 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -35,7 +35,7 @@ var shareOptions = { title: player_data.title, description: player_data.description, image: player_data.thumbnail, - embedCode: "" + embedCode: "" } var player = videojs('player', options); -- cgit v1.2.3 From dd9f1024f400cf35fcc7d2fbaec6bb45828e5e60 Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Sat, 1 Feb 2020 19:25:03 +0100 Subject: Remove invalid HTML from embed player --- assets/js/player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'assets/js') diff --git a/assets/js/player.js b/assets/js/player.js index 79788b1e..eecc0868 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -35,7 +35,7 @@ var shareOptions = { title: player_data.title, description: player_data.description, image: player_data.thumbnail, - embedCode: "" + embedCode: "" } var player = videojs('player', options); -- cgit v1.2.3 From e3593fe197369c583fc6f91292ff8cc06f87eced Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Mon, 19 Aug 2019 12:10:25 +0200 Subject: js: add support to detect media keys in keydown handler See [0] for all the relevant codes. [0]: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values#Multimedia_keys Fixes a regression introduced in e6b4e1268945777c5d07dfca4362a1af23f6d970. Fixes https://github.com/omarroth/invidious/issues/712. --- assets/js/player.js | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'assets/js') diff --git a/assets/js/player.js b/assets/js/player.js index eecc0868..dc1e633f 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -228,11 +228,24 @@ function set_time_percent(percent) { player.currentTime(newTime); } +function play() { + player.play(); +} + +function pause() { + player.pause(); +} + +function stop() { + player.pause(); + player.currentTime(0); +} + function toggle_play() { if (player.paused()) { - player.play(); + play(); } else { - player.pause(); + pause(); } } @@ -338,9 +351,22 @@ window.addEventListener('keydown', e => { switch (decoratedKey) { case ' ': case 'k': + case 'MediaPlayPause': action = toggle_play; break; + case 'MediaPlay': + action = play; + break; + + case 'MediaPause': + action = pause; + break; + + case 'MediaStop': + action = stop; + break; + case 'ArrowUp': if (isPlayerFocused) { action = increase_volume.bind(this, 0.1); @@ -357,9 +383,11 @@ window.addEventListener('keydown', e => { break; case 'ArrowRight': + case 'MediaFastForward': action = skip_seconds.bind(this, 5); break; case 'ArrowLeft': + case 'MediaTrackPrevious': action = skip_seconds.bind(this, -5); break; case 'l': @@ -391,9 +419,11 @@ window.addEventListener('keydown', e => { break; case 'N': + case 'MediaTrackNext': action = next_video; break; case 'P': + case 'MediaTrackPrevious': // TODO: Add support to play back previous video. break; -- cgit v1.2.3 From a3045a3953c5446887ae2057383023bf35c26253 Mon Sep 17 00:00:00 2001 From: Kyle Copperfield Date: Mon, 2 Mar 2020 15:33:47 +0000 Subject: Use a MediaQueryListener to toggle on demand. Tested on OSX. (#925) Closes #867. --- assets/js/themes.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'assets/js') diff --git a/assets/js/themes.js b/assets/js/themes.js index 90a05c36..c600073d 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -28,6 +28,27 @@ window.addEventListener('load', function () { update_mode(window.localStorage.dark_mode); }); + +var darkScheme = window.matchMedia('(prefers-color-scheme: dark)'); +var lightScheme = window.matchMedia('(prefers-color-scheme: light)'); + +darkScheme.addListener(scheme_switch); +lightScheme.addListener(scheme_switch); + +function scheme_switch (e) { + // ignore this method if we have a preference set + if (localStorage.getItem('dark_mode')) { + return; + } + if (e.matches) { + if (e.media.includes("dark")) { + set_mode(true); + } else if (e.media.includes("light")) { + set_mode(false); + } + } +} + function set_mode (bool) { document.getElementById('dark_theme').media = !bool ? 'none' : ''; document.getElementById('light_theme').media = bool ? 'none' : ''; -- cgit v1.2.3 From 70cbe91776d1de10f2767c6a5ad5912fd705bdd3 Mon Sep 17 00:00:00 2001 From: leonklingele Date: Mon, 16 Mar 2020 06:46:08 +0900 Subject: Migrate to a good Content Security Policy (#1023) So attacks such as XSS (see [0]) will no longer be of an issue. [0]: https://github.com/omarroth/invidious/issues/1022 --- assets/css/embed.css | 10 ++ assets/js/community.js | 2 + assets/js/embed.js | 2 + assets/js/global.js | 3 + assets/js/handlers.js | 141 +++++++++++++++++++++ assets/js/notifications.js | 2 + assets/js/player.js | 3 + assets/js/playlist_widget.js | 2 + .../js/silvermine-videojs-quality-selector.min.js | 5 +- assets/js/subscribe_widget.js | 2 + assets/js/watch.js | 2 + assets/js/watched_widget.js | 2 + src/invidious.cr | 20 +-- src/invidious/comments.cr | 8 +- src/invidious/views/add_playlist_items.ecr | 6 +- src/invidious/views/community.ecr | 16 +-- src/invidious/views/components/item.ecr | 15 +-- src/invidious/views/components/player.ecr | 17 +-- src/invidious/views/components/player_sources.ecr | 1 + .../views/components/subscribe_widget.ecr | 16 +-- src/invidious/views/embed.ecr | 33 ++--- src/invidious/views/history.ecr | 10 +- src/invidious/views/playlist.ecr | 6 +- src/invidious/views/preferences.ecr | 10 +- src/invidious/views/subscription_manager.ecr | 33 +---- src/invidious/views/subscriptions.ecr | 6 +- src/invidious/views/template.ecr | 9 +- src/invidious/views/token_manager.ecr | 33 +---- src/invidious/views/watch.ecr | 34 ++--- 29 files changed, 274 insertions(+), 175 deletions(-) create mode 100644 assets/css/embed.css create mode 100644 assets/js/global.js create mode 100644 assets/js/handlers.js (limited to 'assets/js') diff --git a/assets/css/embed.css b/assets/css/embed.css new file mode 100644 index 00000000..12fefe58 --- /dev/null +++ b/assets/css/embed.css @@ -0,0 +1,10 @@ +#player { + position: fixed; + right: 0; + bottom: 0; + min-width: 100%; + min-height: 100%; + width: auto; + height: auto; + z-index: -100; +} diff --git a/assets/js/community.js b/assets/js/community.js index 754ec6d3..4077f1cd 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -1,3 +1,5 @@ +var community_data = JSON.parse(document.getElementById('community_data').innerHTML); + String.prototype.supplant = function (o) { return this.replace(/{([^{}]*)}/g, function (a, b) { var r = o[b]; diff --git a/assets/js/embed.js b/assets/js/embed.js index 534c30ff..99d2fc53 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -1,3 +1,5 @@ +var video_data = JSON.parse(document.getElementById('video_data').innerHTML); + function get_playlist(plid, retries) { if (retries == undefined) retries = 5; diff --git a/assets/js/global.js b/assets/js/global.js new file mode 100644 index 00000000..efb447fb --- /dev/null +++ b/assets/js/global.js @@ -0,0 +1,3 @@ +// Disable Web Workers. Fixes Video.js CSP violation (created by `new Worker(objURL)`): +// Refused to create a worker from 'blob:http://host/id' because it violates the following Content Security Policy directive: "worker-src 'self'". +window.Worker = undefined; diff --git a/assets/js/handlers.js b/assets/js/handlers.js new file mode 100644 index 00000000..68ba9f4f --- /dev/null +++ b/assets/js/handlers.js @@ -0,0 +1,141 @@ +'use strict'; + +(function() { + var n2a = function(n) { return Array.prototype.slice.call(n); }; + + var video_player = document.getElementById('player'); + if (video_player) { + video_player.onmouseenter = function() { video_player['data-title'] = video_player['title']; video_player['title'] = ''; }; + video_player.onmouseleave = function() { video_player['title'] = video_player['data-title']; video_player['data-title'] = ''; }; + video_player.oncontextmenu = function() { video_player['title'] = video_player['data-title']; }; + } + + // For dynamically inserted elements + document.addEventListener('click', function(e) { + if (!e || !e.target) { return; } + e = e.target; + var handler_name = e.getAttribute('data-onclick'); + switch (handler_name) { + case 'jump_to_time': + var time = e.getAttribute('data-jump-time'); + player.currentTime(time); + break; + case 'get_youtube_replies': + var load_more = e.getAttribute('data-load-more') !== null; + get_youtube_replies(e, load_more); + break; + default: + break; + } + }); + + n2a(document.querySelectorAll('[data-mouse="switch_classes"]')).forEach(function(e) { + var classes = e.getAttribute('data-switch-classes').split(','); + var ec = classes[0]; + var lc = classes[1]; + var onoff = function(on, off) { + var cs = e.getAttribute('class'); + cs = cs.split(off).join(on); + e.setAttribute('class', cs); + }; + e.onmouseenter = function() { onoff(ec, lc); }; + e.onmouseleave = function() { onoff(lc, ec); }; + }); + + n2a(document.querySelectorAll('[data-onsubmit="return_false"]')).forEach(function(e) { + e.onsubmit = function() { return false; }; + }); + + n2a(document.querySelectorAll('[data-onclick="toggle_parent"]')).forEach(function(e) { + e.onclick = function() { toggle_parent(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="mark_watched"]')).forEach(function(e) { + e.onclick = function() { mark_watched(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="mark_unwatched"]')).forEach(function(e) { + e.onclick = function() { mark_unwatched(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="add_playlist_item"]')).forEach(function(e) { + e.onclick = function() { add_playlist_item(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="remove_playlist_item"]')).forEach(function(e) { + e.onclick = function() { remove_playlist_item(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="revoke_token"]')).forEach(function(e) { + e.onclick = function() { revoke_token(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="remove_subscription"]')).forEach(function(e) { + e.onclick = function() { remove_subscription(e); }; + }); + n2a(document.querySelectorAll('[data-onclick="notification_requestPermission"]')).forEach(function(e) { + e.onclick = function() { Notification.requestPermission(); }; + }); + + n2a(document.querySelectorAll('[data-onrange="update_volume_value"]')).forEach(function(e) { + var cb = function() { update_volume_value(e); } + e.oninput = cb; + e.onchange = cb; + }); + + function update_volume_value(element) { + document.getElementById('volume-value').innerText = element.value; + } + + function revoke_token(target) { + var row = target.parentNode.parentNode.parentNode.parentNode.parentNode; + row.style.display = 'none'; + var count = document.getElementById('count'); + count.innerText = count.innerText - 1; + + var referer = window.encodeURIComponent(document.location.href); + var url = '/token_ajax?action_revoke_token=1&redirect=false' + + '&referer=' + referer + + '&session=' + target.getAttribute('data-session'); + var xhr = new XMLHttpRequest(); + xhr.responseType = 'json'; + xhr.timeout = 10000; + xhr.open('POST', url, true); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + if (xhr.status != 200) { + count.innerText = parseInt(count.innerText) + 1; + row.style.display = ''; + } + } + } + + var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value; + xhr.send('csrf_token=' + csrf_token); + } + + function remove_subscription(target) { + var row = target.parentNode.parentNode.parentNode.parentNode.parentNode; + row.style.display = 'none'; + var count = document.getElementById('count'); + count.innerText = count.innerText - 1; + + var referer = window.encodeURIComponent(document.location.href); + var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' + + '&referer=' + referer + + '&c=' + target.getAttribute('data-ucid'); + var xhr = new XMLHttpRequest(); + xhr.responseType = 'json'; + xhr.timeout = 10000; + xhr.open('POST', url, true); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + if (xhr.status != 200) { + count.innerText = parseInt(count.innerText) + 1; + row.style.display = ''; + } + } + } + + var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value; + xhr.send('csrf_token=' + csrf_token); + } +})(); diff --git a/assets/js/notifications.js b/assets/js/notifications.js index fcfc01e7..3d1ec1ed 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -1,3 +1,5 @@ +var notification_data = JSON.parse(document.getElementById('notification_data').innerHTML); + var notifications, delivered; function get_subscriptions(callback, retries) { diff --git a/assets/js/player.js b/assets/js/player.js index eecc0868..75370de6 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -1,3 +1,6 @@ +var player_data = JSON.parse(document.getElementById('player_data').innerHTML); +var video_data = JSON.parse(document.getElementById('video_data').innerHTML); + var options = { preload: 'auto', liveui: true, diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index 5d6ddf87..a29d7ef0 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -1,3 +1,5 @@ +var playlist_data = JSON.parse(document.getElementById('playlist_data').innerHTML); + function add_playlist_item(target) { var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; tile.style.display = 'none'; diff --git a/assets/js/silvermine-videojs-quality-selector.min.js b/assets/js/silvermine-videojs-quality-selector.min.js index e4869564..88621e8d 100644 --- a/assets/js/silvermine-videojs-quality-selector.min.js +++ b/assets/js/silvermine-videojs-quality-selector.min.js @@ -1,3 +1,4 @@ -/*! @silvermine/videojs-quality-selector 2019-09-26 v1.2.2-4-gc134430-dirty */ +/*! @silvermine/videojs-quality-selector 2020-03-02 v1.1.2-36-g64d620a-dirty */ -!function u(o,c,a){function l(e,n){if(!c[e]){if(!o[e]){var t="function"==typeof require&&require;if(!n&&t)return t(e,!0);if(s)return s(e,!0);var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}var i=c[e]={exports:{}};o[e][0].call(i.exports,function(n){return l(o[e][1][n]||n)},i,i.exports,u,o,c,a)}return c[e].exports}for(var s="function"==typeof require&&require,n=0;n":">",'"':""","'":"'","`":"`"},B=h.invert(D);h.escape=W(D),h.unescape=W(B),h.result=function(n,e,t){h.isArray(e)||(e=[e]);var r=e.length;if(!r)return h.isFunction(t)?t.call(n):t;for(var i=0;i/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};function z(n){return"\\"+K[n]}var Y=/(.)^/,K={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},V=/\\|'|\r|\n|\u2028|\u2029/g;h.template=function(u,n,e){!n&&e&&(n=e),n=h.defaults({},n,h.templateSettings);var t,r=RegExp([(n.escape||Y).source,(n.interpolate||Y).source,(n.evaluate||Y).source].join("|")+"|$","g"),o=0,c="__p+='";u.replace(r,function(n,e,t,r,i){return c+=u.slice(o,i).replace(V,z),o=i+n.length,e?c+="'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":t?c+="'+\n((__t=("+t+"))==null?'':__t)+\n'":r&&(c+="';\n"+r+"\n__p+='"),n}),c+="';\n",n.variable||(c="with(obj||{}){\n"+c+"}\n"),c="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+c+"return __p;\n";try{t=new Function(n.variable||"obj","_",c)}catch(n){throw n.source=c,n}function i(n){return t.call(this,n,h)}var a=n.variable||"obj";return i.source="function("+a+"){\n"+c+"}",i},h.chain=function(n){var e=h(n);return e._chain=!0,e};function J(n,e){return n._chain?h(e).chain():e}h.mixin=function(t){return h.each(h.functions(t),function(n){var e=h[n]=t[n];h.prototype[n]=function(){var n=[this._wrapped];return i.apply(n,arguments),J(this,e.apply(h,n))}}),h},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];h.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),"shift"!==e&&"splice"!==e||0!==n.length||delete n[0],J(this,n)}}),h.each(["concat","join","slice"],function(n){var e=r[n];h.prototype[n]=function(){return J(this,e.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},h.prototype.valueOf=h.prototype.toJSON=h.prototype.value,h.prototype.toString=function(){return String(this._wrapped)},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events");e.exports=function(n){var r=n.getComponent("MenuItem");return n.extend(r,{constructor:function(n,e){var t=e.source;if(!i.isObject(t))throw new Error('was not provided a "source" object, but rather: '+typeof t);e=i.extend({selectable:!0,label:t.label},e),r.call(this,n,e),this.source=t},handleClick:function(n){r.prototype.handleClick.call(this,n),this.player().trigger(u.QUALITY_REQUESTED,this.source)}})}},{"../events":5,underscore:2}],4:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events"),o=n("./QualityOption"),c="vjs-quality-changing";e.exports=function(n){var e,r=n.getComponent("MenuButton"),t=o(n);return e=n.extend(r,{constructor:function(t,n){r.call(this,t,n),t.on(u.QUALITY_REQUESTED,function(n,e){this.setSelectedSource(e),t.addClass(c),t.one("loadeddata",function(){t.removeClass(c)})}.bind(this)),t.on(u.QUALITY_SELECTED,function(n,e){this.setSelectedSource(e)}.bind(this)),t.one("ready",function(){this.selectedSrc=t.src(),this.update()}.bind(this)),this.controlText("Open quality selector menu")},setSelectedSource:function(n){var e=n?n.src:void 0;this.selectedSrc!==e&&(this.selectedSrc=e,i.each(this.items,function(n){n.selected(n.source.src===e)}))},createItems:function(){var e=this.player(),n=e.currentSources();return i.map(n,function(n){return new t(e,{source:n,selected:n.src===this.selectedSrc})}.bind(this))},buildWrapperCSSClass:function(){return"vjs-quality-selector "+r.prototype.buildWrapperCSSClass.call(this)}}),n.registerComponent("QualitySelector",e),e}},{"../events":5,"./QualityOption":3,underscore:2}],5:[function(n,e,t){"use strict";e.exports={QUALITY_REQUESTED:"qualityRequested",QUALITY_SELECTED:"qualitySelected"}},{}],6:[function(n,e,t){"use strict";var c=n("underscore"),r=n("./events"),i=n("./components/QualitySelector"),u=n("./middleware/SourceInterceptor"),a=n("./util/SafeSeek");e.exports=function(n){n=n||window.videojs,i(n),u(n),n.hook("setup",function(o){o.on(r.QUALITY_REQUESTED,function(n,e){var t=o.currentSources(),r=o.currentTime(),i=o.playbackRate(),u=o.paused();c.each(t,function(n){n.selected=!1}),c.findWhere(t,{src:e.src}).selected=!0,o._qualitySelectorSafeSeek&&o._qualitySelectorSafeSeek.onQualitySelectionChange(),o.src(t),o.ready(function(){o._qualitySelectorSafeSeek&&!o._qualitySelectorSafeSeek.hasFinished()||(o._qualitySelectorSafeSeek=new a(o,r),o.playbackRate(i)),u||o.play()})})})},e.exports.EVENTS=r},{"./components/QualitySelector":4,"./events":5,"./middleware/SourceInterceptor":7,"./util/SafeSeek":9,underscore:2}],7:[function(n,e,t){"use strict";var u=n("underscore"),o=n("../events");e.exports=function(n){n.use("*",function(i){return{setSource:function(n,e){var t,r=i.currentSources();i._qualitySelectorSafeSeek&&i._qualitySelectorSafeSeek.onPlayerSourcesChange(),t=u.find(r,function(n){return!0===n.selected||"true"===n.selected})||n,i.trigger(o.QUALITY_SELECTED,t),e(null,t)}}})}},{"../events":5,underscore:2}],8:[function(n,e,t){"use strict";n("./index")()},{"./index":6}],9:[function(n,e,t){"use strict";var r=n("class.extend");e.exports=r.extend({init:function(n,e){this._player=n,this._seekToTime=e,this._hasFinished=!1,this._keepThisInstanceWhenPlayerSourcesChange=!1,this._seekWhenSafe()},_seekWhenSafe:function(){this._player.readyState()<3?(this._seekFn=this._seek.bind(this),this._player.one("canplay",this._seekFn)):this._seek()},onPlayerSourcesChange:function(){this._keepThisInstanceWhenPlayerSourcesChange?this._keepThisInstanceWhenPlayerSourcesChange=!1:this.cancel()},onQualitySelectionChange:function(){this.hasFinished()||(this._keepThisInstanceWhenPlayerSourcesChange=!0)},_seek:function(){this._player.currentTime(this._seekToTime),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0},hasFinished:function(){return this._hasFinished},cancel:function(){this._player.off("canplay",this._seekFn),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0}})},{"class.extend":1}]},{},[8]); \ No newline at end of file +!function u(o,c,a){function l(e,n){if(!c[e]){if(!o[e]){var t="function"==typeof require&&require;if(!n&&t)return t(e,!0);if(s)return s(e,!0);var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}var i=c[e]={exports:{}};o[e][0].call(i.exports,function(n){return l(o[e][1][n]||n)},i,i.exports,u,o,c,a)}return c[e].exports}for(var s="function"==typeof require&&require,n=0;n":">",'"':""","'":"'","`":"`"},W=h.invert(P);h.escape=D(P),h.unescape=D(W),h.result=function(n,e,t){h.isArray(e)||(e=[e]);var r=e.length;if(!r)return h.isFunction(t)?t.call(n):t;for(var i=0;i/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};function Y(n){return"\\"+K[n]}var z=/(.)^/,K={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},G=/\\|'|\r|\n|\u2028|\u2029/g;h.template=function(u,n,e){!n&&e&&(n=e),n=h.defaults({},n,h.templateSettings);var t,r=RegExp([(n.escape||z).source,(n.interpolate||z).source,(n.evaluate||z).source].join("|")+"|$","g"),o=0,c="__p+='";u.replace(r,function(n,e,t,r,i){return c+=u.slice(o,i).replace(G,Y),o=i+n.length,e?c+="'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":t?c+="'+\n((__t=("+t+"))==null?'':__t)+\n'":r&&(c+="';\n"+r+"\n__p+='"),n}),c+="';\n",n.variable||(c="with(obj||{}){\n"+c+"}\n"),c="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+c+"return __p;\n";try{t=new Function(n.variable||"obj","_",c)}catch(n){throw n.source=c,n}function i(n){return t.call(this,n,h)}var a=n.variable||"obj";return i.source="function("+a+"){\n"+c+"}",i},h.chain=function(n){var e=h(n);return e._chain=!0,e};function H(n,e){return n._chain?h(e).chain():e}h.mixin=function(t){return h.each(h.functions(t),function(n){var e=h[n]=t[n];h.prototype[n]=function(){var n=[this._wrapped];return i.apply(n,arguments),H(this,e.apply(h,n))}}),h},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];h.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),"shift"!==e&&"splice"!==e||0!==n.length||delete n[0],H(this,n)}}),h.each(["concat","join","slice"],function(n){var e=r[n];h.prototype[n]=function(){return H(this,e.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},h.prototype.valueOf=h.prototype.toJSON=h.prototype.value,h.prototype.toString=function(){return String(this._wrapped)},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events");e.exports=function(n){var r=n.getComponent("MenuItem");return n.extend(r,{constructor:function(n,e){var t=e.source;if(!i.isObject(t))throw new Error('was not provided a "source" object, but rather: '+typeof t);e=i.extend({selectable:!0,label:t.label},e),r.call(this,n,e),this.source=t},handleClick:function(n){r.prototype.handleClick.call(this,n),this.player().trigger(u.QUALITY_REQUESTED,this.source)}})}},{"../events":5,underscore:2}],4:[function(n,e,t){"use strict";var i=n("underscore"),u=n("../events"),o=n("./QualityOption"),c="vjs-quality-changing";e.exports=function(n){var e,r=n.getComponent("MenuButton"),t=o(n);return e=n.extend(r,{constructor:function(t,n){r.call(this,t,n),t.on(u.QUALITY_REQUESTED,function(n,e){this.setSelectedSource(e),t.addClass(c),t.one("loadeddata",function(){t.removeClass(c)})}.bind(this)),t.on(u.PLAYER_SOURCES_CHANGED,function(){this.update()}.bind(this)),t.on(u.QUALITY_SELECTED,function(n,e){this.setSelectedSource(e)}.bind(this)),t.one("ready",function(){this.selectedSrc=t.src(),this.update()}.bind(this)),this.controlText("Open quality selector menu")},setSelectedSource:function(n){var e=n?n.src:void 0;this.selectedSrc!==e&&(this.selectedSrc=e,i.each(this.items,function(n){n.selected(n.source.src===e)}))},createItems:function(){var e=this.player(),n=e.currentSources();return i.map(n,function(n){return new t(e,{source:n,selected:n.src===this.selectedSrc})}.bind(this))},buildWrapperCSSClass:function(){return"vjs-quality-selector "+r.prototype.buildWrapperCSSClass.call(this)}}),n.registerComponent("QualitySelector",e),e}},{"../events":5,"./QualityOption":3,underscore:2}],5:[function(n,e,t){"use strict";e.exports={QUALITY_REQUESTED:"qualityRequested",QUALITY_SELECTED:"qualitySelected",PLAYER_SOURCES_CHANGED:"playerSourcesChanged"}},{}],6:[function(n,e,t){"use strict";var c=n("underscore"),r=n("./events"),i=n("./components/QualitySelector"),u=n("./middleware/SourceInterceptor"),a=n("./util/SafeSeek");e.exports=function(n){n=n||window.videojs,i(n),u(n),n.hook("setup",function(o){o.on(r.QUALITY_REQUESTED,function(n,e){var t=o.currentSources(),r=o.currentTime(),i=o.playbackRate(),u=o.paused();c.each(t,function(n){n.selected=!1}),c.findWhere(t,{src:e.src}).selected=!0,o._qualitySelectorSafeSeek&&o._qualitySelectorSafeSeek.onQualitySelectionChange(),o.src(t),o.ready(function(){o._qualitySelectorSafeSeek&&!o._qualitySelectorSafeSeek.hasFinished()||(o._qualitySelectorSafeSeek=new a(o,r),o.playbackRate(i)),u||o.play()})})})},e.exports.EVENTS=r},{"./components/QualitySelector":4,"./events":5,"./middleware/SourceInterceptor":7,"./util/SafeSeek":9,underscore:2}],7:[function(n,e,t){"use strict";var u=n("underscore"),o=n("../events");e.exports=function(n){n.use("*",function(i){return{setSource:function(n,e){var t,r=i.currentSources();i._qualitySelectorSafeSeek&&i._qualitySelectorSafeSeek.onPlayerSourcesChange(),u.isEqual(r,i._qualitySelectorPreviousSources)||(i.trigger(o.PLAYER_SOURCES_CHANGED,r),i._qualitySelectorPreviousSources=r),t=u.find(r,function(n){return!0===n.selected||"true"===n.selected||"selected"===n.selected})||n,i.trigger(o.QUALITY_SELECTED,t),e(null,t)}}})}},{"../events":5,underscore:2}],8:[function(n,e,t){"use strict";n("./index")()},{"./index":6}],9:[function(n,e,t){"use strict";var r=n("class.extend");e.exports=r.extend({init:function(n,e){this._player=n,this._seekToTime=e,this._hasFinished=!1,this._keepThisInstanceWhenPlayerSourcesChange=!1,this._seekWhenSafe()},_seekWhenSafe:function(){this._player.readyState()<3?(this._seekFn=this._seek.bind(this),this._player.one("canplay",this._seekFn)):this._seek()},onPlayerSourcesChange:function(){this._keepThisInstanceWhenPlayerSourcesChange?this._keepThisInstanceWhenPlayerSourcesChange=!1:this.cancel()},onQualitySelectionChange:function(){this.hasFinished()||(this._keepThisInstanceWhenPlayerSourcesChange=!0)},_seek:function(){this._player.currentTime(this._seekToTime),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0},hasFinished:function(){return this._hasFinished},cancel:function(){this._player.off("canplay",this._seekFn),this._keepThisInstanceWhenPlayerSourcesChange=!1,this._hasFinished=!0}})},{"class.extend":1}]},{},[8]); +//# sourceMappingURL=silvermine-videojs-quality-selector.min.js.map \ No newline at end of file diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index 6c21bffb..216c36fe 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -1,3 +1,5 @@ +var subscribe_data = JSON.parse(document.getElementById('subscribe_data').innerHTML); + var subscribe_button = document.getElementById('subscribe'); subscribe_button.parentNode['action'] = 'javascript:void(0)'; diff --git a/assets/js/watch.js b/assets/js/watch.js index a26cb505..e9ad2ddc 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -1,3 +1,5 @@ +var video_data = JSON.parse(document.getElementById('video_data').innerHTML); + String.prototype.supplant = function (o) { return this.replace(/{([^{}]*)}/g, function (a, b) { var r = o[b]; diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 1e88fa27..ba741974 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -1,3 +1,5 @@ +var watched_data = JSON.parse(document.getElementById('watched_data').innerHTML); + function mark_watched(target) { var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; tile.style.display = 'none'; diff --git a/src/invidious.cr b/src/invidious.cr index e89c2c37..800af0dd 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -248,10 +248,20 @@ spawn do end before_all do |env| - host_url = make_host_url(config, Kemal.config) + begin + preferences = Preferences.from_json(env.request.cookies["PREFS"]?.try &.value || "{}") + rescue + preferences = Preferences.from_json("{}") + end + env.response.headers["X-XSS-Protection"] = "1; mode=block" env.response.headers["X-Content-Type-Options"] = "nosniff" - env.response.headers["Content-Security-Policy"] = "default-src blob: data: 'self' #{host_url} 'unsafe-inline' 'unsafe-eval'; media-src blob: 'self' #{host_url} https://*.googlevideo.com:443" + extra_media_csp = "" + if CONFIG.disabled?("local") || !preferences.local + extra_media_csp += " https://*.googlevideo.com:443" + end + # TODO: Remove style-src's 'unsafe-inline', requires to remove all inline styles (, style=" [..] ") + env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; media-src 'self' blob:#{extra_media_csp}" env.response.headers["Referrer-Policy"] = "same-origin" if (Kemal.config.ssl || config.https_only) && config.hsts @@ -269,12 +279,6 @@ before_all do |env| "/latest_version", }.any? { |r| env.request.resource.starts_with? r } - begin - preferences = Preferences.from_json(env.request.cookies["PREFS"]?.try &.value || "{}") - rescue - preferences = Preferences.from_json("{}") - end - if env.request.cookies.has_key? "SID" sid = env.request.cookies["SID"].value diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 2938247a..4a048d7a 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -294,7 +294,7 @@ def template_youtube_comments(comments, locale, thin_mode)

#{translate(locale, "View `x` replies", number_with_separator(child["replies"]["replyCount"]))} + data-onclick="get_youtube_replies">#{translate(locale, "View `x` replies", number_with_separator(child["replies"]["replyCount"]))}

@@ -413,7 +413,7 @@ def template_youtube_comments(comments, locale, thin_mode)

#{translate(locale, "Load more")} + data-onclick="get_youtube_replies" data-load-more>#{translate(locale, "Load more")}

@@ -451,7 +451,7 @@ def template_reddit_comments(root, locale) html << <<-END_HTML

- [ - ] + [ - ] #{child.author} #{translate(locale, "`x` points", number_with_separator(child.score))} #{translate(locale, "`x` ago", recode_date(child.created_utc, locale))} @@ -556,7 +556,7 @@ def content_to_comment_html(content) video_id = watch_endpoint["videoId"].as_s if length_seconds - text = %(#{text}) + text = %(#{text}) else text = %(#{text}) end diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr index f1899faa..dff0b549 100644 --- a/src/invidious/views/add_playlist_items.ecr +++ b/src/invidious/views/add_playlist_items.ecr @@ -20,9 +20,9 @@

- diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 218cc2d4..fca8c0b6 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -71,14 +71,14 @@ <% end %> - diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 9669aaeb..e9baba2c 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -57,10 +57,10 @@
<% if plid = env.get?("remove_playlist_items") %> -
" method="post"> + " method="post"> ">

- + @@ -103,13 +103,12 @@

<% if env.get? "show_watched" %> - " method="post"> + " method="post"> ">

- + @@ -117,10 +116,10 @@

<% elsif plid = env.get? "add_playlist_items" %> -
" method="post"> + " method="post"> ">

- + diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr index ba6311cb..520d72dd 100644 --- a/src/invidious/views/components/player.ecr +++ b/src/invidious/views/components/player.ecr @@ -1,8 +1,5 @@ - diff --git a/src/invidious/views/components/player_sources.ecr b/src/invidious/views/components/player_sources.ecr index d950e0da..8162546e 100644 --- a/src/invidious/views/components/player_sources.ecr +++ b/src/invidious/views/components/player_sources.ecr @@ -3,6 +3,7 @@ + diff --git a/src/invidious/views/components/subscribe_widget.ecr b/src/invidious/views/components/subscribe_widget.ecr index 471e6c1c..7c579a8a 100644 --- a/src/invidious/views/components/subscribe_widget.ecr +++ b/src/invidious/views/components/subscribe_widget.ecr @@ -19,14 +19,14 @@

<% end %> - diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr index 6c06bf2e..ff8277e8 100644 --- a/src/invidious/views/embed.ecr +++ b/src/invidious/views/embed.ecr @@ -10,32 +10,21 @@ + <%= HTML.escape(video.title) %> - Invidious - - diff --git a/src/invidious/views/history.ecr b/src/invidious/views/history.ecr index 7d7ded2c..2aa8adf7 100644 --- a/src/invidious/views/history.ecr +++ b/src/invidious/views/history.ecr @@ -18,9 +18,9 @@
- @@ -34,10 +34,10 @@ var watched_data = { <% if !env.get("preferences").as(Preferences).thin_mode %> <% if playlist.is_a?(InvidiousPlaylist) && playlist.author == user.try &.email %> - diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr index 17e5804e..7e899133 100644 --- a/src/invidious/views/preferences.ecr +++ b/src/invidious/views/preferences.ecr @@ -2,12 +2,6 @@ <%= translate(locale, "Preferences") %> - Invidious <% end %> - -
@@ -65,7 +59,7 @@ function update_value(element) {
- + <%= preferences.volume %>
@@ -205,7 +199,7 @@ function update_value(element) { <% # Web notifications are only supported over HTTPS %> <% if Kemal.config.ssl || config.https_only %>
<% end %> <% end %> diff --git a/src/invidious/views/subscription_manager.ecr b/src/invidious/views/subscription_manager.ecr index 43d14b37..6cddcd6c 100644 --- a/src/invidious/views/subscription_manager.ecr +++ b/src/invidious/views/subscription_manager.ecr @@ -37,9 +37,9 @@

- " method="post"> + " method="post"> "> - + "> @@ -52,32 +52,3 @@ <% end %>

<% end %> - - diff --git a/src/invidious/views/subscriptions.ecr b/src/invidious/views/subscriptions.ecr index ee31d241..93c58471 100644 --- a/src/invidious/views/subscriptions.ecr +++ b/src/invidious/views/subscriptions.ecr @@ -45,9 +45,9 @@
- diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr index d2ef9c7e..b239d22a 100644 --- a/src/invidious/views/template.ecr +++ b/src/invidious/views/template.ecr @@ -147,13 +147,14 @@
+ <% if env.get? "user" %> - diff --git a/src/invidious/views/token_manager.ecr b/src/invidious/views/token_manager.ecr index b626d99c..e48aec2f 100644 --- a/src/invidious/views/token_manager.ecr +++ b/src/invidious/views/token_manager.ecr @@ -29,9 +29,9 @@

-
" method="post"> + " method="post"> "> - + ">
@@ -44,32 +44,3 @@ <% end %>

<% end %> - - diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index df61abc5..16ac71eb 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -26,23 +26,23 @@ <%= HTML.escape(video.title) %> - Invidious <% end %> - -- cgit v1.2.3 From bd7950b7579426d3acdf881262e802678e2c336d Mon Sep 17 00:00:00 2001 From: Omar Roth Date: Sun, 15 Mar 2020 18:52:49 -0400 Subject: Add toggle_parent to dynamic handlers --- assets/js/handlers.js | 86 +++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'assets/js') diff --git a/assets/js/handlers.js b/assets/js/handlers.js index 68ba9f4f..77062ca6 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -1,78 +1,78 @@ 'use strict'; -(function() { - var n2a = function(n) { return Array.prototype.slice.call(n); }; +(function () { + var n2a = function (n) { return Array.prototype.slice.call(n); }; var video_player = document.getElementById('player'); if (video_player) { - video_player.onmouseenter = function() { video_player['data-title'] = video_player['title']; video_player['title'] = ''; }; - video_player.onmouseleave = function() { video_player['title'] = video_player['data-title']; video_player['data-title'] = ''; }; - video_player.oncontextmenu = function() { video_player['title'] = video_player['data-title']; }; + video_player.onmouseenter = function () { video_player['data-title'] = video_player['title']; video_player['title'] = ''; }; + video_player.onmouseleave = function () { video_player['title'] = video_player['data-title']; video_player['data-title'] = ''; }; + video_player.oncontextmenu = function () { video_player['title'] = video_player['data-title']; }; } // For dynamically inserted elements - document.addEventListener('click', function(e) { + document.addEventListener('click', function (e) { if (!e || !e.target) { return; } e = e.target; var handler_name = e.getAttribute('data-onclick'); switch (handler_name) { - case 'jump_to_time': - var time = e.getAttribute('data-jump-time'); - player.currentTime(time); - break; - case 'get_youtube_replies': - var load_more = e.getAttribute('data-load-more') !== null; - get_youtube_replies(e, load_more); - break; - default: - break; + case 'jump_to_time': + var time = e.getAttribute('data-jump-time'); + player.currentTime(time); + break; + case 'get_youtube_replies': + var load_more = e.getAttribute('data-load-more') !== null; + get_youtube_replies(e, load_more); + break; + case 'toggle_parent': + toggle_parent(e); + break; + default: + break; } }); - n2a(document.querySelectorAll('[data-mouse="switch_classes"]')).forEach(function(e) { + n2a(document.querySelectorAll('[data-mouse="switch_classes"]')).forEach(function (e) { var classes = e.getAttribute('data-switch-classes').split(','); var ec = classes[0]; var lc = classes[1]; - var onoff = function(on, off) { + var onoff = function (on, off) { var cs = e.getAttribute('class'); cs = cs.split(off).join(on); e.setAttribute('class', cs); }; - e.onmouseenter = function() { onoff(ec, lc); }; - e.onmouseleave = function() { onoff(lc, ec); }; + e.onmouseenter = function () { onoff(ec, lc); }; + e.onmouseleave = function () { onoff(lc, ec); }; }); - n2a(document.querySelectorAll('[data-onsubmit="return_false"]')).forEach(function(e) { - e.onsubmit = function() { return false; }; + n2a(document.querySelectorAll('[data-onsubmit="return_false"]')).forEach(function (e) { + e.onsubmit = function () { return false; }; }); - n2a(document.querySelectorAll('[data-onclick="toggle_parent"]')).forEach(function(e) { - e.onclick = function() { toggle_parent(e); }; + n2a(document.querySelectorAll('[data-onclick="mark_watched"]')).forEach(function (e) { + e.onclick = function () { mark_watched(e); }; }); - n2a(document.querySelectorAll('[data-onclick="mark_watched"]')).forEach(function(e) { - e.onclick = function() { mark_watched(e); }; + n2a(document.querySelectorAll('[data-onclick="mark_unwatched"]')).forEach(function (e) { + e.onclick = function () { mark_unwatched(e); }; }); - n2a(document.querySelectorAll('[data-onclick="mark_unwatched"]')).forEach(function(e) { - e.onclick = function() { mark_unwatched(e); }; + n2a(document.querySelectorAll('[data-onclick="add_playlist_item"]')).forEach(function (e) { + e.onclick = function () { add_playlist_item(e); }; }); - n2a(document.querySelectorAll('[data-onclick="add_playlist_item"]')).forEach(function(e) { - e.onclick = function() { add_playlist_item(e); }; + n2a(document.querySelectorAll('[data-onclick="remove_playlist_item"]')).forEach(function (e) { + e.onclick = function () { remove_playlist_item(e); }; }); - n2a(document.querySelectorAll('[data-onclick="remove_playlist_item"]')).forEach(function(e) { - e.onclick = function() { remove_playlist_item(e); }; + n2a(document.querySelectorAll('[data-onclick="revoke_token"]')).forEach(function (e) { + e.onclick = function () { revoke_token(e); }; }); - n2a(document.querySelectorAll('[data-onclick="revoke_token"]')).forEach(function(e) { - e.onclick = function() { revoke_token(e); }; + n2a(document.querySelectorAll('[data-onclick="remove_subscription"]')).forEach(function (e) { + e.onclick = function () { remove_subscription(e); }; }); - n2a(document.querySelectorAll('[data-onclick="remove_subscription"]')).forEach(function(e) { - e.onclick = function() { remove_subscription(e); }; - }); - n2a(document.querySelectorAll('[data-onclick="notification_requestPermission"]')).forEach(function(e) { - e.onclick = function() { Notification.requestPermission(); }; + n2a(document.querySelectorAll('[data-onclick="notification_requestPermission"]')).forEach(function (e) { + e.onclick = function () { Notification.requestPermission(); }; }); - n2a(document.querySelectorAll('[data-onrange="update_volume_value"]')).forEach(function(e) { - var cb = function() { update_volume_value(e); } + n2a(document.querySelectorAll('[data-onrange="update_volume_value"]')).forEach(function (e) { + var cb = function () { update_volume_value(e); } e.oninput = cb; e.onchange = cb; }); @@ -97,7 +97,7 @@ xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.onreadystatechange = function() { + xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status != 200) { count.innerText = parseInt(count.innerText) + 1; @@ -126,7 +126,7 @@ xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.onreadystatechange = function() { + xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status != 200) { count.innerText = parseInt(count.innerText) + 1; -- cgit v1.2.3 From 0e58d99f4e17618d67fb78d79b10a11fb0b0811d Mon Sep 17 00:00:00 2001 From: Omar Roth Date: Fri, 27 Mar 2020 09:47:46 -0500 Subject: Fix player mouseover events --- assets/js/handlers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'assets/js') diff --git a/assets/js/handlers.js b/assets/js/handlers.js index 77062ca6..7ecb5a02 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -3,7 +3,7 @@ (function () { var n2a = function (n) { return Array.prototype.slice.call(n); }; - var video_player = document.getElementById('player'); + var video_player = document.getElementById('player_html5_api'); if (video_player) { video_player.onmouseenter = function () { video_player['data-title'] = video_player['title']; video_player['title'] = ''; }; video_player.onmouseleave = function () { video_player['title'] = video_player['data-title']; video_player['data-title'] = ''; }; -- cgit v1.2.3 From 3f97bebd6956ee1b111a2c23057a4facd6cbef0a Mon Sep 17 00:00:00 2001 From: Omar Roth Date: Tue, 7 Apr 2020 13:34:40 -0500 Subject: Support adding video to playlist from watch page --- assets/js/handlers.js | 3 +++ assets/js/playlist_widget.js | 24 ++++++++++++++++++++++++ src/invidious.cr | 6 ++---- src/invidious/helpers/helpers.cr | 4 +--- src/invidious/views/add_playlist_items.ecr | 2 +- src/invidious/views/playlist.ecr | 2 +- src/invidious/views/watch.ecr | 25 +++++++++++++++++++++++++ 7 files changed, 57 insertions(+), 9 deletions(-) (limited to 'assets/js') diff --git a/assets/js/handlers.js b/assets/js/handlers.js index 7ecb5a02..b3da8d9b 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -55,6 +55,9 @@ n2a(document.querySelectorAll('[data-onclick="mark_unwatched"]')).forEach(function (e) { e.onclick = function () { mark_unwatched(e); }; }); + n2a(document.querySelectorAll('[data-onclick="add_playlist_video"]')).forEach(function (e) { + e.onclick = function () { add_playlist_video(e); }; + }); n2a(document.querySelectorAll('[data-onclick="add_playlist_item"]')).forEach(function (e) { e.onclick = function () { add_playlist_item(e); }; }); diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index a29d7ef0..0ec27859 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -1,5 +1,29 @@ var playlist_data = JSON.parse(document.getElementById('playlist_data').innerHTML); +function add_playlist_video(target) { + var select = target.parentNode.children[0].children[1]; + var option = select.children[select.selectedIndex]; + + var url = '/playlist_ajax?action_add_video=1&redirect=false' + + '&video_id=' + target.getAttribute('data-id') + + '&playlist_id=' + option.getAttribute('data-plid'); + var xhr = new XMLHttpRequest(); + xhr.responseType = 'json'; + xhr.timeout = 10000; + xhr.open('POST', url, true); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + option.innerText = '✓' + option.innerText; + } + } + } + + xhr.send('csrf_token=' + playlist_data.csrf_token); +} + function add_playlist_item(target) { var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; tile.style.display = 'none'; diff --git a/src/invidious.cr b/src/invidious.cr index 74d0c79f..1448c502 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -3131,9 +3131,7 @@ get "/feed/channel/:ucid" do |env| rss = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}").body rss = XML.parse_html(rss) - videos = [] of SearchVideo - - rss.xpath_nodes("//feed/entry").each do |entry| + videos = rss.xpath_nodes("//feed/entry").map do |entry| video_id = entry.xpath_node("videoid").not_nil!.content title = entry.xpath_node("title").not_nil!.content @@ -3145,7 +3143,7 @@ get "/feed/channel/:ucid" do |env| description_html = entry.xpath_node("group/description").not_nil!.to_s views = entry.xpath_node("group/community/statistics").not_nil!.["views"].to_i64 - videos << SearchVideo.new( + SearchVideo.new( title: title, id: video_id, author: author, diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index 2341d3be..e168c55e 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -732,9 +732,7 @@ def cache_annotation(db, id, annotations) body = XML.parse(annotations) nodeset = body.xpath_nodes(%q(/document/annotations/annotation)) - if nodeset == 0 - return - end + return if nodeset == 0 has_legacy_annotations = false nodeset.each do |node| diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr index 07295c1a..09eacbc8 100644 --- a/src/invidious/views/add_playlist_items.ecr +++ b/src/invidious/views/add_playlist_items.ecr @@ -27,7 +27,7 @@ }.to_pretty_json %> - +
<% videos.each_slice(4) do |slice| %> diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr index ccda94d9..7316af14 100644 --- a/src/invidious/views/playlist.ecr +++ b/src/invidious/views/playlist.ecr @@ -76,7 +76,7 @@ }.to_pretty_json %> - + <% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 2a99dd5b..e43282cb 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -101,6 +101,31 @@ <% end %>

+ <% if user %> +
+
+ + +
+ + +
+ + + <% end %> + <% if CONFIG.dmca_content.includes?(video.id) || CONFIG.disabled?("downloads") %>

<%= translate(locale, "Download is disabled.") %>

<% else %> -- cgit v1.2.3 From 3379f3ef610e8f8c0aced4d9162874c63cced7e7 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sun, 8 Nov 2020 22:02:25 +0100 Subject: Update videojs-vtt-thumbnails to latest upstream version Note that the latest version on NPM is over two years old so this was built from source. --- assets/js/player.js | 3 ++- assets/js/videojs-vtt-thumbnails.min.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'assets/js') diff --git a/assets/js/player.js b/assets/js/player.js index edab35bf..f79fbbf3 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -149,7 +149,8 @@ if (!video_data.params.listen && video_data.params.quality === 'dash') { } player.vttThumbnails({ - src: location.origin + '/api/v1/storyboards/' + video_data.id + '?height=90' + src: location.origin + '/api/v1/storyboards/' + video_data.id + '?height=90', + showTimestamp: true }); // Enable annotations diff --git a/assets/js/videojs-vtt-thumbnails.min.js b/assets/js/videojs-vtt-thumbnails.min.js index e1efca62..be86a201 100644 --- a/assets/js/videojs-vtt-thumbnails.min.js +++ b/assets/js/videojs-vtt-thumbnails.min.js @@ -1,7 +1,7 @@ /** * videojs-vtt-thumbnails * @version 0.0.13 - * @copyright 2019 Chris Boustead + * @copyright 2020 Chris Boustead * @license MIT */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],e):t.videojsVttThumbnails=e(t.videojs)}(this,function(i){"use strict";i=i&&i.hasOwnProperty("default")?i.default:i;!function(){function l(t){this.value=t}function t(i){var o,n;function a(t,e){try{var r=i[t](e),s=r.value;s instanceof l?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):u(r.done?"return":"normal",r.value)}catch(t){u("throw",t)}}function u(t,e){switch(t){case"return":o.resolve({value:e,done:!0});break;case"throw":o.reject(e);break;default:o.resolve({value:e,done:!1})}(o=o.next)?a(o.key,o.arg):n=null}this._invoke=function(s,i){return new Promise(function(t,e){var r={key:s,arg:i,resolve:t,reject:e,next:null};n?n=n.next=r:(o=n=r,a(s,i))})},"function"!=typeof i.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(t.prototype[Symbol.asyncIterator]=function(){return this}),t.prototype.next=function(t){return this._invoke("next",t)},t.prototype.throw=function(t){return this._invoke("throw",t)},t.prototype.return=function(t){return this._invoke("return",t)}}();var o={},n={},t=i.registerPlugin||i.plugin,e=function(r){var s=this;this.ready(function(){var t,e;t=s,e=i.mergeOptions(o,r),t.addClass("vjs-vtt-thumbnails"),t.vttThumbnails=new a(t,e)})},a=function(){function r(t,e){return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,r),this.player=t,this.options=e,this.listenForDurationChange(),this.initializeThumbnails(),this.registeredEvents={},this}return r.prototype.src=function(t){this.resetPlugin(),this.options.src=t,this.initializeThumbnails()},r.prototype.detach=function(){this.resetPlugin()},r.prototype.resetPlugin=function(){this.thumbnailHolder&&this.thumbnailHolder.parentNode.removeChild(this.thumbnailHolder),this.progressBar&&this.progressBar.removeEventListener("mouseenter",this.registeredEvents.progressBarMouseEnter),this.progressBar&&this.progressBar.removeEventListener("mouseleave",this.registeredEvents.progressBarMouseLeave),this.progressBar&&this.progressBar.removeEventListener("mousemove",this.registeredEvents.progressBarMouseMove),delete this.registeredEvents.progressBarMouseEnter,delete this.registeredEvents.progressBarMouseLeave,delete this.registeredEvents.progressBarMouseMove,delete this.progressBar,delete this.vttData,delete this.thumbnailHolder,delete this.lastStyle},r.prototype.listenForDurationChange=function(){this.player.on("durationchange",function(){})},r.prototype.initializeThumbnails=function(){var e=this;if(this.options.src){var t=this.getBaseUrl(),r=this.getFullyQualifiedUrl(this.options.src,t);this.getVttFile(r).then(function(t){e.vttData=e.processVtt(t),e.setupThumbnailElement()})}},r.prototype.getBaseUrl=function(){return[window.location.protocol,"//",window.location.hostname,window.location.port?":"+window.location.port:"",window.location.pathname].join("").split(/([^\/]*)$/gi).shift()},r.prototype.getVttFile=function(s){var i=this;return new Promise(function(t,e){var r=new XMLHttpRequest;r.data={resolve:t},r.addEventListener("load",i.vttFileLoaded),r.open("GET",s),r.send()})},r.prototype.vttFileLoaded=function(){this.data.resolve(this.responseText)},r.prototype.setupThumbnailElement=function(t){var e=this;this.progressBar=this.player.$(".vjs-progress-control");var r=document.createElement("div");r.setAttribute("class","vjs-vtt-thumbnail-display"),this.progressBar.appendChild(r),this.thumbnailHolder=r,this.registeredEvents.progressBarMouseEnter=function(){return e.onBarMouseenter()},this.registeredEvents.progressBarMouseLeave=function(){return e.onBarMouseleave()},this.progressBar.addEventListener("mouseenter",this.registeredEvents.progressBarMouseEnter),this.progressBar.addEventListener("mouseleave",this.registeredEvents.progressBarMouseLeave)},r.prototype.onBarMouseenter=function(){var e=this;this.mouseMoveCallback=function(t){e.onBarMousemove(t)},this.registeredEvents.progressBarMouseMove=this.mouseMoveCallback,this.progressBar.addEventListener("mousemove",this.registeredEvents.progressBarMouseMove),this.showThumbnailHolder()},r.prototype.onBarMouseleave=function(){this.registeredEvents.progressBarMouseMove&&this.progressBar.removeEventListener("mousemove",this.registeredEvents.progressBarMouseMove),this.hideThumbnailHolder()},r.prototype.getXCoord=function(t,e){var r=t.getBoundingClientRect(),s=document.documentElement;return e-(r.left+(window.pageXOffset||s.scrollLeft||0))},r.prototype.onBarMousemove=function(t){this.updateThumbnailStyle(this.getXCoord(this.progressBar,t.clientX),this.progressBar.offsetWidth)},r.prototype.getStyleForTime=function(t){for(var e=0;e=r.start&&t ?)([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?[\r\n]{1}.*/gi)){var e=t.split(/[\r\n]/i),r=e[0].split(/ ?--> ?/i),s=r[0],i=r[1],o=e[1],n=a.getVttCss(o);u.push({start:a.getSecondsFromTimestamp(s),end:a.getSecondsFromTimestamp(i),css:n})}}),u},r.prototype.getFullyQualifiedUrl=function(t,e){return 0<=t.indexOf("//")?t:0===e.indexOf("//")?[e.replace(/\/$/gi,""),this.trim(t,"/")].join("/"):0=r.start&&e>1,a=t-(i+o),l=i-o;if(0 ?)([0-9]{2}:)?([0-9]{2}:)?[0-9]{2}(.[0-9]{3})?[\r\n]{1}.*/gi)&&(r=(s=(t=e.split(/[\r\n]/i))[0].split(/ ?--> ?/i))[0],i=s[1],n=t[1],o=a.getVttCss(n),l.push({start:a.getSecondsFromTimestamp(r),end:a.getSecondsFromTimestamp(i),css:o}))}),l},t.getFullyQualifiedUrl=function(e,t){return 0<=e.indexOf("//")?e:0===t.indexOf("//")?[t.replace(/\/$/gi,""),this.trim(e,"/")].join("/"):0