aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2021-08-14 22:00:24 +0200
committerTeddy Wing2021-08-14 22:16:01 +0200
commit8a7cc75a035b58bcf12893132cc63e16f6069bff (patch)
treeac1866c8fb2b11f86e0d8e3e70c44087975aa1e7
parente9423bc8c345add2c719a632ae911947bcc4f07f (diff)
downloadnetflix-immersive-8a7cc75a035b58bcf12893132cc63e16f6069bff.tar.bz2
Hide distractions when Seamless controls are added
Seamless controls can be added during the end credits of a series episode. When those controls are added, the "Back to Browse" button appears as well as the mouse cursor. A transparent promo background also appears. Hide the "Back to Browse" button and promo background in CSS. Add a new `seamless` module to handle hiding the mouse cursor. Listen for the addition of the `.SeamlessControls--container` element, which means Seamless controls were activated. At this point, force the cursor to be hidden. Show it again when the user moves the mouse.
-rw-r--r--netflix-immersive.user.js59
-rw-r--r--src/index.ts4
-rw-r--r--src/seamless.ts73
-rw-r--r--src/styles.ts2
4 files changed, 131 insertions, 7 deletions
diff --git a/netflix-immersive.user.js b/netflix-immersive.user.js
index cbb8624..dcfdde6 100644
--- a/netflix-immersive.user.js
+++ b/netflix-immersive.user.js
@@ -131,11 +131,12 @@ function init() {
}
exports.default = init;
-},{"./wait_element":6}],3:[function(require,module,exports){
+},{"./logger":4,"./wait_element":7}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var fullscreen_credits_1 = require("./fullscreen_credits");
var logger_1 = require("./logger");
+var seamless_1 = require("./seamless");
var styles_1 = require("./styles");
var watch_credits_1 = require("./watch_credits");
function main() {
@@ -143,12 +144,13 @@ function main() {
styles_1.default();
fullscreen_credits_1.default();
watch_credits_1.default();
+ seamless_1.default();
}
main();
// Reinitialise when the page changes.
window.onpopstate = main;
-},{"./fullscreen_credits":2,"./logger":4,"./styles":5,"./watch_credits":7}],4:[function(require,module,exports){
+},{"./fullscreen_credits":2,"./logger":4,"./seamless":5,"./styles":6,"./watch_credits":8}],4:[function(require,module,exports){
"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
@@ -171,6 +173,51 @@ exports.default = {
},{}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
+var logger_1 = require("./logger");
+var wait_element_1 = require("./wait_element");
+// Hide the cursor when seamless credits are played.
+function init_mutation_observer(player) {
+ var observer = new MutationObserver(function (mutation_list) {
+ var _loop_1 = function () {
+ var mutation = mutation_list[i];
+ var player_1 = mutation.target;
+ var seamless_controls = document.querySelector('.SeamlessControls--container');
+ if (seamless_controls) {
+ logger_1.default.debug('seamless', 'init_mutation_observer()', 'Handling seamless');
+ var style_el_1 = document.createElement('style');
+ // Hide the cursor.
+ document.head.appendChild(style_el_1);
+ var stylesheet = style_el_1.sheet;
+ stylesheet.insertRule("\n\t\t\t\t\tbody {\n\t\t\t\t\t\tcursor: none !important;\n\t\t\t\t\t}", stylesheet.cssRules.length);
+ document.body.onmousemove = function () {
+ document.head.removeChild(style_el_1);
+ };
+ return { value: void 0 };
+ }
+ };
+ for (var i = 0; i < mutation_list.length; i++) {
+ var state_1 = _loop_1();
+ if (typeof state_1 === "object")
+ return state_1.value;
+ }
+ });
+ observer.observe(player, {
+ childList: true,
+ subtree: true
+ });
+}
+// Initialise the mutation observer when the video player becomes available.
+function init() {
+ wait_element_1.default('.watch-video--player-view')
+ .then(function (player) {
+ init_mutation_observer(player);
+ });
+}
+exports.default = init;
+
+},{"./logger":4,"./wait_element":7}],6:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
// Adds CSS to the page to hide superfluous user interface elements.
function styles() {
var style = document.createElement('style');
@@ -178,12 +225,12 @@ function styles() {
var stylesheet = style.sheet;
// 2021.08.13: May want to remove `.player-view-childrens`, which is now
// replaced by `.advisory-container`.
- stylesheet.insertRule("\n\t\t/* \"Back to Browse\" button that appears when credits are minimised. */\n\t\t.OriginalsPostPlay-BackgroundTrailer .BackToBrowse,\n\n\t\t/* Promo that appears during credis */\n\t\t.OriginalsPostPlay-BackgroundTrailer,\n\n\t\t/* Age rating. */\n\t\t.player-view-childrens,\n\t\t.advisory-container,\n\n\t\t/* \"Watch Credits\" button. */\n\t\t[data-uia=\"watch-credits-seamless-button\"],\n\n\t\t/* Skip buttons. */\n\t\ta[aria-label=\"Skip Intro\"],\n\t\ta[aria-label=\"Skip Recap\"],\n\t\ta[aria-label=\"Next Episode\"],\n\t\t[data-uia=\"next-episode-seamless-button\"] {\n\t\t\tvisibility: hidden !important;\n\t\t}", stylesheet.cssRules.length);
+ stylesheet.insertRule("\n\t\t/* \"Back to Browse\" button that appears when credits are minimised. */\n\t\t.OriginalsPostPlay-BackgroundTrailer .BackToBrowse,\n\t\t.watch-video--seamless-back,\n\n\t\t/* Promo that appears during credis */\n\t\t.OriginalsPostPlay-BackgroundTrailer,\n\t\t.SeamlessControls--background-artwork-visible,\n\n\t\t/* Age rating. */\n\t\t.player-view-childrens,\n\t\t.advisory-container,\n\n\t\t/* \"Watch Credits\" button. */\n\t\t[data-uia=\"watch-credits-seamless-button\"],\n\n\t\t/* Skip buttons. */\n\t\ta[aria-label=\"Skip Intro\"],\n\t\ta[aria-label=\"Skip Recap\"],\n\t\ta[aria-label=\"Next Episode\"],\n\t\t[data-uia=\"next-episode-seamless-button\"] {\n\t\t\tvisibility: hidden !important;\n\t\t}", stylesheet.cssRules.length);
stylesheet.insertRule("\n\t\t/* Remove white border around credits. */\n\t\t.NFPlayer.can-resume:hover {\n\t\t\tborder: none !important;\n\t\t}", stylesheet.cssRules.length);
}
exports.default = styles;
-},{}],6:[function(require,module,exports){
+},{}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var logger_1 = require("./logger");
@@ -203,7 +250,7 @@ function wait_element(selector) {
}
exports.default = wait_element;
-},{"./logger":4}],7:[function(require,module,exports){
+},{"./logger":4}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var controls_1 = require("./controls");
@@ -242,4 +289,4 @@ function init() {
}
exports.default = init;
-},{"./controls":1,"./logger":4,"./wait_element":6}]},{},[3]);
+},{"./controls":1,"./logger":4,"./wait_element":7}]},{},[3]);
diff --git a/src/index.ts b/src/index.ts
index 4d3a951..237d232 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 Teddy Wing
+// Copyright (c) 2020–2021 Teddy Wing
//
// This file is part of Immersive.
//
@@ -17,6 +17,7 @@
import fullscreen_credits from './fullscreen_credits';
import logger from './logger';
+import seamless from './seamless';
import styles from './styles';
import watch_credits from './watch_credits';
@@ -27,6 +28,7 @@ function main () {
styles();
fullscreen_credits();
watch_credits();
+ seamless();
}
diff --git a/src/seamless.ts b/src/seamless.ts
new file mode 100644
index 0000000..50595d9
--- /dev/null
+++ b/src/seamless.ts
@@ -0,0 +1,73 @@
+// Copyright (c) 2021 Teddy Wing
+//
+// This file is part of Immersive.
+//
+// Immersive is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Immersive is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Immersive. If not, see <https://www.gnu.org/licenses/>.
+
+import logger from './logger';
+import wait_element from './wait_element';
+
+
+// Hide the cursor when seamless credits are played.
+function init_mutation_observer (player) {
+ const observer = new MutationObserver(function(mutation_list) {
+ for (var i = 0; i < mutation_list.length; i++) {
+ const mutation = mutation_list[i];
+ const player = mutation.target as HTMLElement;
+
+ const seamless_controls = document.querySelector(
+ '.SeamlessControls--container'
+ );
+
+ if (seamless_controls) {
+ logger.debug('seamless', 'init_mutation_observer()', 'Handling seamless');
+ const style_el = document.createElement('style');
+
+ // Hide the cursor.
+ document.head.appendChild(style_el);
+
+ const stylesheet = style_el.sheet as CSSStyleSheet;
+
+ stylesheet.insertRule(`
+ body {
+ cursor: none !important;
+ }`,
+ stylesheet.cssRules.length
+ );
+
+ document.body.onmousemove = function() {
+ document.head.removeChild(style_el);
+ }
+
+ return;
+ }
+ }
+ });
+
+ observer.observe(
+ player,
+ {
+ childList: true,
+ subtree: true
+ }
+ );
+}
+
+// Initialise the mutation observer when the video player becomes available.
+export default function init () {
+ wait_element('.watch-video--player-view')
+ .then(function(player) {
+ init_mutation_observer(player);
+ });
+}
diff --git a/src/styles.ts b/src/styles.ts
index 3661fff..2b6ba24 100644
--- a/src/styles.ts
+++ b/src/styles.ts
@@ -28,9 +28,11 @@ export default function styles () {
stylesheet.insertRule(`
/* "Back to Browse" button that appears when credits are minimised. */
.OriginalsPostPlay-BackgroundTrailer .BackToBrowse,
+ .watch-video--seamless-back,
/* Promo that appears during credis */
.OriginalsPostPlay-BackgroundTrailer,
+ .SeamlessControls--background-artwork-visible,
/* Age rating. */
.player-view-childrens,