您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script forces the rounded version of the layout (which includes some fewer tweaks applied, which also improves bugs).
// ==UserScript== // @name YouTube - Force rounded corners + tweaks included // @version 2025.06.03 // @description This script forces the rounded version of the layout (which includes some fewer tweaks applied, which also improves bugs). // @author Joey_JTS (original author: xX_LegendCraftd_Xx) // @license MIT // @match *://www.youtube.com/* // @match *://m.youtube.com/* // @namespace https://greasyfork.org/en/users/933798 // @icon https://www.youtube.com/favicon.ico // @run-at document-idle // @grant none // ==/UserScript== // Attributes to remove from <html> const ATTRS = [ "darker-dark-theme", "darker-dark-theme-deprecate" ]; // Regular config keys. const CONFIGS = { BUTTON_REWORK: true } // Experiment flags. const EXPFLAGS = { /* Force rounded corners */ web_button_rework: true, web_button_rework_with_live: true, web_darker_dark_theme: true, web_filled_subscribed_button: true, web_guide_ui_refresh: true, web_modern_ads: true, web_modern_buttons: true, web_modern_chips: true, web_modern_dialogs: true, web_modern_playlists: true, web_modern_subscribe: true, web_rounded_containers: true, web_rounded_thumbnails: true, web_searchbar_style: "rounded_corner_borders_light_btn", web_segmented_like_dislike_button: true, web_sheets_ui_refresh: true, web_snackbar_ui_refresh: true, /* Force rounded watch layout and few tweaks to be included (such as disabling the useless 'watch grid' UI */ kevlar_watch_metadata_refresh: true, kevlar_watch_metadata_refresh_attached_subscribe: true, kevlar_watch_metadata_refresh_clickable_description: true, kevlar_watch_metadata_refresh_compact_view_count: true, kevlar_watch_metadata_refresh_description_info_dedicated_line: true, kevlar_watch_metadata_refresh_description_inline_expander: true, kevlar_watch_metadata_refresh_description_primary_color: true, kevlar_watch_metadata_refresh_for_live_killswitch: true, kevlar_watch_metadata_refresh_full_width_description: true, kevlar_watch_metadata_refresh_narrower_item_wrap: true, kevlar_watch_metadata_refresh_relative_date: true, kevlar_watch_metadata_refresh_top_aligned_actions: true, kevlar_watch_modern_metapanel: true, kevlar_watch_modern_panels: true, kevlar_watch_panel_height_matches_player: true, kevlar_watch_grid: false, kevlar_watch_grid_hide_chips: false, small_avatars_for_comments: false, small_avatars_for_comments_ep: false, web_watch_compact_comments: false, web_watch_compact_comments_ep: false, web_watch_theater_chat: false, web_watch_theater_fixed_chat: false, live_chat_over_engagement_panels: false, live_chat_scaled_height: false, live_chat_smaller_min_height: false, wn_grid_max_item_width: 0, wn_grid_min_item_width: 0, kevlar_set_internal_player_size: false, kevlar_watch_flexy_metadata_height: "136", kevlar_watch_max_player_width: "1280", web_watch_rounded_player_large: false, desktop_delay_player_resizing: false, /* Additional tweaks (which includes disabling ambient lighting and reverting new UI changes except for both web_modern_tabs and web_enable_youtab configs ) */ kevlar_refresh_on_theme_change: false, smartimation_background: false, web_animated_actions: false, web_animated_like: false, web_animated_like_lazy_load: false, enable_channel_page_header_profile_section: false, kevlar_modern_sd_v2: false, web_modern_collections_v2: false, web_modern_tabs: false, web_modern_typography: true, web_enable_youtab: true, kevlar_measure_ambient_mode_idle: false, kevlar_watch_cinematics_invisible: false, web_cinematic_theater_mode: false, web_cinematic_fullscreen: false, enable_cinematic_blur_desktop_loading: false, kevlar_watch_cinematics: false, web_cinematic_masthead: false, web_watch_cinematics_preferred_reduced_motion_default_disabled: false } // Player flags // !!! USE STRINGS FOR VALUES !!! // For example: "true" instead of true const PLYRFLAGS = { web_rounded_containers: "true", web_rounded_thumbnails: "true" } class YTP { static observer = new MutationObserver(this.onNewScript); static _config = {}; static isObject(item) { return (item && typeof item === "object" && !Array.isArray(item)); } static mergeDeep(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (this.isObject(target) && this.isObject(source)) { for (const key in source) { if (this.isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); this.mergeDeep(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return this.mergeDeep(target, ...sources); } static onNewScript(mutations) { for (var mut of mutations) { for (var node of mut.addedNodes) { YTP.bruteforce(); } } } static start() { this.observer.observe(document, {childList: true, subtree: true}); } static stop() { this.observer.disconnect(); } static bruteforce() { if (!window.yt) return; if (!window.yt.config_) return; this.mergeDeep(window.yt.config_, this._config); } static setCfg(name, value) { this._config[name] = value; } static setCfgMulti(configs) { this.mergeDeep(this._config, configs); } static setExp(name, value) { if (!("EXPERIMENT_FLAGS" in this._config)) this._config.EXPERIMENT_FLAGS = {}; this._config.EXPERIMENT_FLAGS[name] = value; } static setExpMulti(exps) { if (!("EXPERIMENT_FLAGS" in this._config)) this._config.EXPERIMENT_FLAGS = {}; this.mergeDeep(this._config.EXPERIMENT_FLAGS, exps); } static decodePlyrFlags(flags) { var obj = {}, dflags = flags.split("&"); for (var i = 0; i < dflags.length; i++) { var dflag = dflags[i].split("="); obj[dflag[0]] = dflag[1]; } return obj; } static encodePlyrFlags(flags) { var keys = Object.keys(flags), response = ""; for (var i = 0; i < keys.length; i++) { if (i > 0) { response += "&"; } response += keys[i] + "=" + flags[keys[i]]; } return response; } static setPlyrFlags(flags) { if (!window.yt) return; if (!window.yt.config_) return; if (!window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS) return; var conCfgs = window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS; if (!("WEB_PLAYER_CONTEXT_CONFIGS" in this._config)) this._config.WEB_PLAYER_CONTEXT_CONFIGS = {}; for (var cfg in conCfgs) { var dflags = this.decodePlyrFlags(conCfgs[cfg].serializedExperimentFlags); this.mergeDeep(dflags, flags); this._config.WEB_PLAYER_CONTEXT_CONFIGS[cfg] = { serializedExperimentFlags: this.encodePlyrFlags(dflags) } } } } window.addEventListener("yt-page-data-updated", function tmp() { YTP.stop(); for (i = 0; i < ATTRS.length; i++) { document.getElementsByTagName("html")[0].removeAttribute(ATTRS[i]); } window.removeEventListener("yt-page-date-updated", tmp); }); YTP.start(); YTP.setCfgMulti(CONFIGS); YTP.setExpMulti(EXPFLAGS); YTP.setPlyrFlags(PLYRFLAGS); function $(q) { return document.querySelector(q); } (function() { let css = ` /* Add rounded corners under the player */ div#ytp-id-17.ytp-popup.ytp-settings-menu, div#ytp-id-18.ytp-popup.ytp-settings-menu { border-radius: 12px !important } div.branding-context-container-inner.ytp-rounded-branding-context { border-radius: 8px !important } .iv-card { border-radius: 8px !important } .ytp-ad-overlay-container.ytp-overlay-ad .ytp-ad-overlay-image img, .ytp-ad-overlay-container.ytp-overlay-ad .ytp-ad-text-overlay, .ytp-ad-overlay-container.ytp-overlay-ad .ytp-ad-enhanced-overlay { border-radius: 8px !important } .ytp-tooltip.ytp-text-detail.ytp-preview .ytp-tooltip-bg { border-top-left-radius: 12px !important; border-bottom-left-radius: 12px !important } .ytp-tooltip.ytp-text-detail.ytp-preview { border-radius: 12px !important } .ytp-ce-video.ytp-ce-medium, .ytp-ce-playlist.ytp-ce-medium, .ytp-ce-medium .ytp-ce-expanding-overlay-background { border-radius: 8px !important } .ytp-autonav-endscreen-upnext-thumbnail { border-radius: 8px !important } .ytp-autonav-endscreen-upnext-button { border-radius: 18px !important } .ytp-videowall-still-image { border-radius: 8px !important } .ytp-sb-subscribe, .ytp-sb-unsubscribe { border-radius: 18px !important } /* Watch page tweaks (including the 'Revert video list' CSS) */ ytd-watch-flexy[rounded-player-large]:not([fullscreen]):not([theater]) #ytd-player.ytd-watch-flexy { border-radius: 0px !important } #actions.ytd-watch-metadata { min-width: auto !important } ytd-watch-flexy[default-layout][reduced-top-margin] #primary.ytd-watch-flexy, ytd-watch-flexy[default-layout][reduced-top-margin] #secondary.ytd-watch-flexy { padding-top: var(--ytd-margin-6x) !important } ytd-watch-metadata[title-headline-xs] h1.ytd-watch-metadata, ytd-watch-metadata[title-headline-m] h1.ytd-watch-metadata { font-family: "YouTube Sans","Roboto",sans-serif !important; font-weight: 600 !important; font-size: 2rem !important; line-height: 2.8rem !important } ytd-comments-header-renderer[compact-header] #title.ytd-comments-header-renderer { margin-bottom: 24px !important } ytd-comments-header-renderer[modern-typography][compact-header] .count-text.ytd-comments-header-renderer { font-size: 2rem !important; line-height: 2.8rem !important; font-weight: 700 !important; max-height: 2.8rem !important; display: flex !important; flex-direction: row-reverse !important } [compact-header] .count-text.ytd-comments-header-renderer { display: flex !important; flex-direction: row-reverse !important } [compact-header] .count-text.ytd-comments-header-renderer span { margin-right: 6px !important } ytd-watch-flexy #comment-teaser.ytd-watch-metadata { display: none } ytd-watch-flexy ytd-rich-item-renderer[rendered-from-rich-grid] { --ytd-rich-item-row-usable-width: 100% !important } ytd-watch-flexy ytd-rich-item-renderer[rendered-from-rich-grid][is-in-first-column] { margin-left: 0 } ytd-watch-flexy ytd-rich-item-renderer ytd-menu-renderer .ytd-menu-renderer[style-target=button] { width: 24px !important; height: 24px !important } ytd-watch-flexy #dismissible.ytd-rich-grid-media { flex-direction: row } ytd-watch-flexy #attached-survey.ytd-rich-grid-media, ytd-watch-flexy #avatar-link.ytd-rich-grid-media, ytd-watch-flexy #avatar-container.ytd-rich-grid-media { display: none } ytd-watch-flexy ytd-thumbnail.ytd-rich-grid-media, ytd-watch-flexy ytd-playlist-thumbnail.ytd-rich-grid-media { margin-right: 8px; height: 94px; width: 168px } ytd-watch-flexy ytd-thumbnail[size=large] a.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large]:before, ytd-watch-flexy ytd-thumbnail[size=large][large-margin] a.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large][large-margin]:before { border-radius: 8px } ytd-watch-flexy ytd-thumbnail[size=large][large-margin] ytd-thumbnail-overlay-time-status-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large][large-margin] ytd-thumbnail-overlay-button-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large][large-margin] ytd-thumbnail-overlay-toggle-button-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large] ytd-thumbnail-overlay-time-status-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large] ytd-thumbnail-overlay-button-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large] ytd-thumbnail-overlay-toggle-button-renderer.ytd-thumbnail { margin: 4px } ytd-watch-flexy ytd-rich-item-renderer, ytd-watch-flexy ytd-rich-grid-row #contents.ytd-rich-grid-row { margin: 0 } ytd-watch-flexy ytd-rich-item-renderer[reduced-bottom-margin] { margin-top: 8px; margin-bottom: 0 } ytd-watch-flexy ytd-rich-grid-renderer[reduced-top-margin] #contents.ytd-rich-grid-renderer { padding-top: 0px } ytd-watch-flexy ytd-rich-grid-media { margin-bottom: 8px } ytd-watch-flexy #details.ytd-rich-grid-media { width: 100%; min-width: 0 } ytd-watch-flexy ytd-video-meta-block[rich-meta] #metadata-line.ytd-video-meta-block, ytd-watch-flexy #channel-name.ytd-video-meta-block { font-family: "Roboto", "Arial", sans-serif; font-size: 1.2rem; line-height: 1.8rem; font-weight: 400 } ytd-watch-flexy #video-title.ytd-rich-grid-media { margin: 0 0 4px 0; display: block; font-family: "Roboto", "Arial", sans-serif; font-size: 1.4rem; line-height: 2rem; font-weight: 500; overflow: hidden; display: block; max-height: 4rem; -webkit-line-clamp: 2; display: box; display: -webkit-box; -webkit-box-orient: vertical; text-overflow: ellipsis; white-space: normal } ytd-watch-flexy h3.ytd-rich-grid-media { margin: 0 } ytd-watch-flexy .title-badge.ytd-rich-grid-media, ytd-watch-flexy .video-badge.ytd-rich-grid-media { margin-top: 0 } ytd-watch-flexy ytd-rich-section-renderer.style-scope.ytd-rich-grid-renderer { display: none } ytd-watch-flexy ytd-rich-grid-renderer[hide-chips-bar] ytd-feed-filter-chip-bar-renderer.ytd-rich-grid-renderer, ytd-watch-flexy ytd-rich-grid-renderer[hide-chips-bar-on-watch] ytd-feed-filter-chip-bar-renderer.ytd-rich-grid-renderer, ytd-watch-flexy ytd-rich-grid-renderer[hide-chips-bar-on-home] #header.ytd-rich-grid-renderer ytd-feed-filter-chip-bar-renderer.ytd-rich-grid-renderer { display: flex; height: 51px; margin-bottom: 8px } ytd-watch-flexy #chips-wrapper.ytd-feed-filter-chip-bar-renderer { position: relative; top: 0 } ytd-watch-flexy ytd-feed-filter-chip-bar-renderer[fluid-width] #chips-content.ytd-feed-filter-chip-bar-renderer { padding: 0 } ytd-watch-flexy yt-chip-cloud-chip-renderer.ytd-feed-filter-chip-bar-renderer, ytd-watch-flexy yt-chip-cloud-chip-renderer.ytd-feed-filter-chip-bar-renderer:first-of-type { margin: 8px; margin-left: 0 } ytd-watch-flexy ytd-button-renderer.ytd-feed-filter-chip-bar-renderer { margin: 0; padding: 0 8px } /* More tweaks to be applied (including removal of annoyances) */ #buttons.ytd-c4-tabbed-header-renderer { flex-direction: row-reverse !important } ytd-channel-tagline-renderer { display: block !important; padding: 0 !important } #content.ytd-channel-tagline-renderer::before { content: "More about this channel"; font-weight: 500 !important } #content.ytd-channel-tagline-renderer { max-width: 162px !important } ytd-browse[page-subtype="channels"] .page-header-view-model-wiz__page-header-description { margin-top: 0px !important; max-width: 236px !important } ytd-browse[page-subtype="channels"] yt-description-preview-view-model .truncated-text-wiz__truncated-text-content:before { content: "More about this channel > "; font-weight: 500 !important } ytd-browse[page-subtype="channels"] button.truncated-text-wiz__absolute-button { display: none !important } #avatar.ytd-c4-tabbed-header-renderer, .yt-spec-avatar-shape__button--button-giant { width: 80px !important; height: 80px !important; margin: 0 24px 0 0 !important; flex: none !important; overflow: hidden !important } .yt-spec-avatar-shape__button--button-giant, .yt-spec-avatar-shape--avatar-size-giant, .yt-spec-avatar-shape__button--button-extra-extra-large, .yt-spec-avatar-shape--avatar-size-extra-extra-large { width: 80px !important; height: 80px !important; margin-right: 0px !important; } #avatar-editor.ytd-c4-tabbed-header-renderer { --ytd-channel-avatar-editor-size: 80px !important } #channel-name.ytd-c4-tabbed-header-renderer { margin-bottom: 0 !important } #channel-header-container.ytd-c4-tabbed-header-renderer { padding-top: 0 !important; align-items: center !important } #inner-header-container.ytd-c4-tabbed-header-renderer { margin-top: 0 !important; align-items: center !important } .yt-content-metadata-view-model-wiz--inline .yt-content-metadata-view-model-wiz__metadata-row { margin-top: 0 !important } yt-formatted-string#channel-pronouns.style-scope.ytd-c4-tabbed-header-renderer, #videos-count { display: none !important } .meta-item.ytd-c4-tabbed-header-renderer { display: block !important } div#channel-header-links.style-scope.ytd-c4-tabbed-header-renderer, .page-header-view-model-wiz__page-header-attribution { display: none !important } ytd-c4-tabbed-header-renderer[use-page-header-style] #channel-name.ytd-c4-tabbed-header-renderer, [page-subtype="channels"] .page-header-view-model-wiz__page-header-title--page-header-title-large { font-size: 2.4em !important; font-weight: 400 !important; line-height: var(--yt-channel-title-line-height, 3rem) !important; margin: 0 !important } span.delimiter.style-scope.ytd-c4-tabbed-header-renderer, .yt-content-metadata-view-model-wiz__delimiter { display: none !important } div#meta.style-scope.ytd-c4-tabbed-header-renderer { width: auto !important } ytd-c4-tabbed-header-renderer[use-page-header-style] #inner-header-container.ytd-c4-tabbed-header-renderer { flex-direction: row !important } div.page-header-banner.style-scope.ytd-c4-tabbed-header-renderer { margin-left: 0px !important; margin-right: 8px !important; border-radius: 0px !important } [has-inset-banner] #page-header-banner.ytd-tabbed-page-header { padding-left: 0 !important; padding-right: 0 !important } ytd-c4-tabbed-header-renderer[use-page-header-style] .page-header-banner.ytd-c4-tabbed-header-renderer, .yt-image-banner-view-model-wiz--inset { border-radius: 0px !important } .yt-content-metadata-view-model-wiz__metadata-text { margin-right: 8px !important } .yt-content-metadata-view-model-wiz__metadata-text, .truncated-text-wiz, .truncated-text-wiz__absolute-button { font-size: 1.4rem !important } .yt-tab-shape-wiz { padding: 0 32px !important; margin-right: 0 !important } .yt-tab-shape-wiz__tab { font-size: 14px !important; font-weight: 500 !important; letter-spacing: var(--ytd-tab-system-letter-spacing) !important; text-transform: uppercase !important } .yt-tab-group-shape-wiz__slider { display: none !important } ytd-browse[page-subtype="channels"] ytd-tabbed-page-header .yt-content-metadata-view-model-wiz__metadata-row--metadata-row-inline { display: flex } ytd-browse[page-subtype="channels"] ytd-tabbed-page-header .yt-content-metadata-view-model-wiz__metadata-text:last-of-type { display: none } ytd-browse[page-subtype="channels"] ytd-tabbed-page-header .yt-content-metadata-view-model-wiz__metadata-text:first-of-type { display: flex } ytd-browse[page-subtype="channels"] .yt-flexible-actions-view-model-wiz--inline { flex-direction: row-reverse } ytd-browse[page-subtype="channels"] .page-header-view-model-wiz__page-header-flexible-actions { margin-top: -56px } ytd-browse[page-subtype="channels"] .yt-flexible-actions-view-model-wiz__action-row { margin-top: 60px } ytd-browse[page-subtype="channels"] .yt-flexible-actions-view-model-wiz__action { padding-right: 8px } ytd-browse[page-subtype="channels"] span.yt-core-attributed-string--link-inherit-color { font-weight: 400 !important } ytd-browse[page-subtype="channels"] .page-header-view-model-wiz__page-header-headline-info { margin-bottom: 8px } #title.ytd-playlist-sidebar-primary-info-renderer, ytd-inline-form-renderer[component-style=INLINE_FORM_STYLE_TITLE] #text-displayed.ytd-inline-form-renderer { font-family: YouTube Sans !important; font-weight: 700 !important } ytd-comments-header-renderer[use-space-between] #title.ytd-comments-header-renderer { justify-content: start !important } #panel-button.ytd-comments-header-renderer { margin-left: 32px; margin-right: 8px } #panel-button .yt-spec-button-shape-next__icon { margin-right: 0 } #panel-button .yt-spec-button-shape-next--size-m { padding-left: 12px; padding-right: 6px } #panel-button .yt-spec-button-shape-next__button-text-content { display: none !important } #panel-button .yt-spec-button-shape-next__icon path { d: path("M10 3H17V7H10V3ZM20 0H0V14H20V0ZM1 1H19V13H1V1Z"); transform: scale(1.20) } div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m[aria-label="Create"] { height: 40px !important; border-radius: 50px !important; color: var(--yt-spec-icon-active-other) !important; background-color: transparent !important } div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading[aria-label="Create"] .yt-spec-button-shape-next__button-text-content { display: none !important } div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading[aria-label="Create"] .yt-spec-button-shape-next__icon { margin-left: -8px !important; margin-right: -8px !important } div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading[aria-label="Create"] path { d: path("M14 13h-3v3H9v-3H6v-2h3V8h2v3h3v2zm3-7H3v12h14v-6.39l4 1.83V8.56l-4 1.83V6m1-1v3.83L22 7v8l-4-1.83V19H2V5h16z") } div#end.style-scope.ytd-masthead .yt-spec-icon-badge-shape--style-overlay.yt-spec-icon-badge-shape--type-cart-refresh .yt-spec-icon-badge-shape__badge { color: #fff !important } ytd-feed-filter-chip-bar-renderer[frosted-glass] ytd-button-renderer.ytd-feed-filter-chip-bar-renderer, ytd-button-renderer.ytd-feed-filter-chip-bar-renderer { background-color: transparent !important } ytd-feed-filter-chip-bar-renderer[frosted-glass] #left-arrow-button.ytd-feed-filter-chip-bar-renderer, #left-arrow-button.ytd-feed-filter-chip-bar-renderer, ytd-feed-filter-chip-bar-renderer[frosted-glass] #right-arrow-button.ytd-feed-filter-chip-bar-renderer, #right-arrow-button.ytd-feed-filter-chip-bar-renderer { background-color: var(--yt-spec-base-background) !important } ytd-feed-filter-chip-bar-renderer[frosted-glass] #left-arrow.ytd-feed-filter-chip-bar-renderer:after, #left-arrow.ytd-feed-filter-chip-bar-renderer:after { background: linear-gradient(to right, var(--yt-spec-base-background) 20%, rgba(255, 255, 255, 0) 80%) !important } ytd-feed-filter-chip-bar-renderer[frosted-glass] #right-arrow.ytd-feed-filter-chip-bar-renderer:before, #right-arrow.ytd-feed-filter-chip-bar-renderer:before { background: linear-gradient(to left, var(--yt-spec-base-background) 20%, rgba(255, 255, 255, 0) 80%) !important } ytd-masthead[frosted-glass=with-chipbar] #background.ytd-masthead, ytd-masthead[frosted-glass=without-chipbar] #background.ytd-masthead, ytd-app[frosted-glass-mode=with-chipbar] #frosted-glass.ytd-app, ytd-app[frosted-glass-mode=without-chipbar] #frosted-glass.ytd-app, #background.ytd-masthead, #frosted-glass.ytd-app { background: var(--yt-spec-base-background) !important; backdrop-filter: none !important } .ytp-cairo-refresh-signature-moments .ytp-play-progress, .ytp-play-progress, .html5-play-progress, ytd-thumbnail-overlay-resume-playback-renderer[enable-refresh-signature-moments-web] #progress.ytd-thumbnail-overlay-resume-playback-renderer, .YtThumbnailOverlayProgressBarHostWatchedProgressBarSegmentModern, .YtChapteredProgressBarChapteredPlayerBarChapterRefresh, .YtChapteredProgressBarChapteredPlayerBarFillRefresh, .YtProgressBarLineProgressBarPlayedRefresh, yt-page-navigation-progress[enable-refresh-signature-moments-web] #progress.yt-page-navigation-progress, ytd-progress-bar-line[enable-refresh-signature-moments-web] .progress-bar-played.ytd-progress-bar-line, #logo-icon > .yt-spec-icon-shape.yt-icon.style-scope.yt-icon-shape > div > svg > g:first-of-type > path:first-of-type, .ytProgressBarLineProgressBarPlayed, .ytProgressBarPlayheadProgressBarPlayheadDot, div.ytp-scrubber-button.ytp-swatch-background-color { background: #ff0000 !important } .ytp-progress-bar .ytp-scrubber-button { opacity: 0 !important } .ytp-progress-bar:hover .ytp-scrubber-button { opacity: 1 !important } [d*="M18 4v15.06l-5.42-3.87-.58-.42-.58.42L6 19.06V4h12m1-1H5v18l7-5 7 5V3z"] { d: path("M22 13h-4v4h-2v-4h-4v-2h4V7h2v4h4v2zm-8-6H2v1h12V7zM2 12h8v-1H2v1zm0 4h8v-1H2v1z") } yt-mealbar-promo-renderer, ytd-video-quality-promo-renderer, ytd-merch-shelf-renderer { display: none !important; } ytd-watch-metadata.ytd-watch-flexy { padding-bottom: 36px !important; } ytd-search-header-renderer .yt-spec-button-shape-next--size-m { flex-direction: row-reverse; } ytd-search-header-renderer .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-trailing .yt-spec-button-shape-next__icon { margin-left: -6px; margin-right: 6px; } /* For YT Mobile */ html[dark] { --yt-spec-base-background: #0f0f0f !important } html:not([dark]) { --yt-spec-base-background: #fff !important } ytm-mobile-topbar-renderer.frosted-glass, ytm-pivot-bar-renderer.frosted-glass, ytm-feed-filter-chip-bar-renderer.frosted-glass { background: var(--yt-spec-base-background) !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important }`; if (typeof GM_addStyle !== "undefined") { GM_addStyle(css); } else { let styleNode = document.createElement("style"); styleNode.appendChild(document.createTextNode(css)); (document.querySelector("head") || document.documentElement).appendChild(styleNode); } })(); // Integrate 'YouTube Video Resize Fix' script (special thanks to CY Fung) /* jshint esversion:8 */ ((__CONTEXT01__) => { 'use strict'; const win = this instanceof Window ? this : window; // Create a unique key for the script and check if it is already running const hkey_script = 'ahceihvpbosz'; if (win[hkey_script]) throw new Error('Duplicated Userscript Calling'); // avoid duplicated scripting win[hkey_script] = true; const insp = o => o ? (o.polymerController || o.inst || o || 0) : (o || 0); const indr = o => insp(o).$ || o.$ || 0; /** @type {globalThis.PromiseConstructor} */ const Promise = (async () => { })().constructor; // YouTube hacks Promise in WaterFox Classic and "Promise.resolve(0)" nevers resolve. const cleanContext = async (win) => { const waitFn = requestAnimationFrame; // shall have been binded to window try { let mx = 16; // MAX TRIAL const frameId = 'vanillajs-iframe-v1' let frame = document.getElementById(frameId); let removeIframeFn = null; if (!frame) { frame = document.createElement('iframe'); frame.id = frameId; const blobURL = typeof webkitCancelAnimationFrame === 'function' && typeof kagi === 'undefined' ? (frame.src = URL.createObjectURL(new Blob([], { type: 'text/html' }))) : null; // avoid Brave Crash frame.sandbox = 'allow-same-origin'; // script cannot be run inside iframe but API can be obtained from iframe let n = document.createElement('noscript'); // wrap into NOSCRPIT to avoid reflow (layouting) n.appendChild(frame); while (!document.documentElement && mx-- > 0) await new Promise(waitFn); // requestAnimationFrame here could get modified by YouTube engine const root = document.documentElement; root.appendChild(n); // throw error if root is null due to exceeding MAX TRIAL if (blobURL) Promise.resolve().then(() => URL.revokeObjectURL(blobURL)); removeIframeFn = (setTimeout) => { const removeIframeOnDocumentReady = (e) => { e && win.removeEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false); e = n; n = win = removeIframeFn = 0; setTimeout ? setTimeout(() => e.remove(), 200) : e.remove(); } if (!setTimeout || document.readyState !== 'loading') { removeIframeOnDocumentReady(); } else { win.addEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false); } } } while (!frame.contentWindow && mx-- > 0) await new Promise(waitFn); const fc = frame.contentWindow; if (!fc) throw "window is not found."; // throw error if root is null due to exceeding MAX TRIAL try { const { requestAnimationFrame, setTimeout, clearTimeout } = fc; const res = { requestAnimationFrame, setTimeout, clearTimeout }; for (let k in res) res[k] = res[k].bind(win); // necessary if (removeIframeFn) Promise.resolve(res.setTimeout).then(removeIframeFn); return res; } catch (e) { if (removeIframeFn) removeIframeFn(); return null; } } catch (e) { console.warn(e); return null; } }; const isWatchPageURL = (url) => { url = url || location; return location.pathname === '/watch' || location.pathname.startsWith('/live/') }; cleanContext(win).then(__CONTEXT02__ => { if (!__CONTEXT02__) return null; const { ResizeObserver } = __CONTEXT01__; const { requestAnimationFrame, setTimeout, clearTimeout } = __CONTEXT02__; const elements = {}; let rid1 = 0; let rid2 = 0; /** @type {MutationObserver | null} */ let attrObserver = null; /** @type {ResizeObserver | null} */ let resizeObserver = null; let isHTMLAttrApplied = false; const core = { begin() { document.addEventListener('yt-player-updated', core.hanlder, true); document.addEventListener('ytd-navigate-finish', core.hanlder, true); }, hanlder: () => { rid1++; if (rid1 > 1e9) rid1 = 9; const tid = rid1; requestAnimationFrame(() => { if (tid !== rid1) return; core.runner(); }) }, async runner() { if (!location.href.startsWith('https://www.youtube.com/')) return; if (!isWatchPageURL()) return; elements.ytdFlexy = document.querySelector('ytd-watch-flexy'); elements.video = document.querySelector('ytd-watch-flexy #movie_player video, ytd-watch-flexy #movie_player audio.video-stream.html5-main-video'); if (elements.ytdFlexy && elements.video) { } else return; elements.moviePlayer = elements.video.closest('#movie_player'); if (!elements.moviePlayer) return; // resize Video let { ytdFlexy } = elements; if (!ytdFlexy.ElYTL) { ytdFlexy.ElYTL = 1; const ytdFlexyCnt = insp(ytdFlexy); if (typeof ytdFlexyCnt.calculateNormalPlayerSize_ === 'function') { ytdFlexyCnt.calculateNormalPlayerSize_ = core.resizeFunc(ytdFlexyCnt.calculateNormalPlayerSize_, 1); } else { console.warn('ytdFlexyCnt.calculateNormalPlayerSize_ is not a function.') } if (typeof ytdFlexyCnt.calculateCurrentPlayerSize_ === 'function') { ytdFlexyCnt.calculateCurrentPlayerSize_ = core.resizeFunc(ytdFlexyCnt.calculateCurrentPlayerSize_, 0); } else { console.warn('ytdFlexyCnt.calculateCurrentPlayerSize_ is not a function.') } } ytdFlexy = null; // when video is fetched elements.video.removeEventListener('canplay', core.triggerResizeDelayed, false); elements.video.addEventListener('canplay', core.triggerResizeDelayed, false); // when video is resized if (resizeObserver) { resizeObserver.disconnect(); resizeObserver = null; } if (typeof ResizeObserver === 'function') { resizeObserver = new ResizeObserver(core.triggerResizeDelayed); resizeObserver.observe(elements.moviePlayer); } // MutationObserver:[collapsed] @ ytd-live-chat-frame#chat if (attrObserver) { attrObserver.takeRecords(); attrObserver.disconnect(); attrObserver = null; } let chat = document.querySelector('ytd-watch-flexy ytd-live-chat-frame#chat'); if (chat) { // resize due to DOM update attrObserver = new MutationObserver(core.triggerResizeDelayed); attrObserver.observe(chat, { attributes: true, attributeFilter: ["collapsed"] }); chat = null; } // resize on idle Promise.resolve().then(core.triggerResizeDelayed); }, resizeFunc(originalFunc, kb) { return function () { rid2++; if (!isHTMLAttrApplied) { isHTMLAttrApplied = true; Promise.resolve(0).then(() => { document.documentElement.classList.add('youtube-video-resize-fix'); }).catch(console.warn); } if (document.fullscreenElement === null) { // calculateCurrentPlayerSize_ shall be always return NaN to make correct positioning of toolbars if (!kb) return { width: NaN, height: NaN }; let ret = core.calculateSize(); if (ret.height > 0 && ret.width > 0) { return ret; } } return originalFunc.apply(this, arguments); } }, calculateSize_() { const { moviePlayer, video } = elements; const rect1 = { width: video.videoWidth, height: video.videoHeight }; // native values independent of css rules if (rect1.width > 0 && rect1.height > 0) { const rect2 = moviePlayer.getBoundingClientRect(); const aspectRatio = rect1.width / rect1.height; let h2 = rect2.width / aspectRatio; let w2 = rect2.height * aspectRatio; return { rect2, h2, w2 }; } return null; }, calculateSize() { let rs = core.calculateSize_(); if (!rs) return { width: NaN, height: NaN }; const { rect2, h2, w2 } = rs; if (h2 > rect2.height) { return { width: w2, height: rect2.height }; } else { return { width: rect2.width, height: h2 }; } }, triggerResizeDelayed: () => { rid2++; if (rid2 > 1e9) rid2 = 9; const tid = rid2; requestAnimationFrame(() => { if (tid !== rid2) return; const { ytdFlexy } = elements; let r = false; const ytdFlexyCnt = insp(ytdFlexy); const windowSize_ = ytdFlexyCnt.windowSize_; if (windowSize_ && typeof ytdFlexyCnt.onWindowResized_ === 'function') { try { ytdFlexyCnt.onWindowResized_(windowSize_); r = true; } catch (e) { } } if (!r) window.dispatchEvent(new Event('resize')); }) } }; core.begin(); // YouTube Watch Page Reflect (WPR) // This script enhances the functionality of YouTube pages by reflecting changes in the page state. (async function youTubeWPR() { let checkPageVisibilityChanged = false; // A WeakSet to keep track of elements being monitored for mutations. const monitorWeakSet = new WeakSet(); /** @type {globalThis.PromiseConstructor} */ const Promise = (async () => { })().constructor; // Function to reflect the current state of the YouTube page. async function _reflect() { await Promise.resolve(); const youtubeWpr = document.documentElement.getAttribute("youtube-wpr"); let s = ''; // Check if the current page is the video watch page. if (isWatchPageURL()) { let watch = document.querySelector("ytd-watch-flexy"); let chat = document.querySelector("ytd-live-chat-frame#chat"); if (watch) { // Determine the state of the chat and video player on the watch page and generate a state string. s += !chat ? 'h0' : (chat.hasAttribute('collapsed') || !document.querySelector('iframe#chatframe')) ? 'h1' : 'h2'; s += watch.hasAttribute('is-two-columns_') ? 's' : 'S'; s += watch.hasAttribute('fullscreen') ? 'F' : 'f'; s += watch.hasAttribute('theater') ? 'T' : 't'; } } // Update the reflected state if it has changed. if (s !== youtubeWpr) { document.documentElement.setAttribute("youtube-wpr", s); } } // Function to reflect changes in specific attributes of monitored elements. async function reflect(nodeName, attrNames, forced) { await Promise.resolve(); if (!forced) { let skip = true; for (const attrName of attrNames) { if (nodeName === 'ytd-live-chat-frame') { if (attrName === 'collapsed') skip = false; } else if (nodeName === 'ytd-watch-flexy') { if (attrName === 'is-two-columns_') skip = false; else if (attrName === 'fullscreen') skip = false; else if (attrName === 'theater') skip = false; } } if (skip) return; } // Log the mutated element and its attributes. // console.log(nodeName, attrNames); // Call _reflect() to update the reflected state. _reflect(); } // Callback function for the MutationObserver that tracks mutations in monitored elements. function callback(mutationsList) { const attrNames = new Set(); let nodeName = null; for (const mutation of mutationsList) { if (nodeName === null && mutation.target) nodeName = mutation.target.nodeName.toLowerCase(); attrNames.add(mutation.attributeName); } reflect(nodeName, attrNames, false); } function getParent(element) { return element.__shady_native_parentNode || element.__shady_parentNode || element.parentNode; } let lastPageTypeChanged = 0; function chatContainerMutationHandler() { if (Date.now() - lastPageTypeChanged < 800) _reflect(); } // Function to start monitoring an element for mutations. function monitor(element) { if (!element) return; if (monitorWeakSet.has(element)) { return; } monitorWeakSet.add(element); const observer = new MutationObserver(callback); observer.observe(element, { attributes: true }); if (element.id === 'chat') { const parentNode = getParent(element); if (parentNode instanceof Element && parentNode.id === 'chat-container' && !monitorWeakSet.has(parentNode)) { monitorWeakSet.add(parentNode); const observer = new MutationObserver(chatContainerMutationHandler); observer.observe(parentNode, { childList: true, subtree: false }); } } return 1; } let timeout = 0; // Function to monitor relevant elements and update the reflected state. let g = async (forced) => { await Promise.resolve(); let b = 0; b = b | monitor(document.querySelector("ytd-watch-flexy")); b = b | monitor(document.querySelector("ytd-live-chat-frame#chat")); if (b || forced) { _reflect(); } } // let renderId = 0; // Event handler function that triggers when the page finishes navigation or page data updates. let eventHandlerFunc = async (evt) => { checkPageVisibilityChanged = true; timeout = Date.now() + 800; g(1); if (evt.type === 'yt-navigate-finish') { // delay required when page type is changed for #chat (home -> watch). setTimeout(() => { g(1); }, 80); } else if (evt.type === 'yt-page-type-changed') { lastPageTypeChanged = Date.now(); // setTimeout(() => { // if (renderId > 1e9) renderId = 9; // const t = ++renderId; // requestAnimationFrame(() => { // if (t !== renderId) return; // g(1); // }); // }, 180); if (typeof requestIdleCallback === 'function') { requestIdleCallback(() => { g(1); }); } } } let loadState = 0; // Function to initialize the script and start monitoring the page. async function actor() { if (loadState === 0) { if (!document.documentElement.hasAttribute("youtube-wpr")) { loadState = 1; document.documentElement.setAttribute("youtube-wpr", ""); document.addEventListener("yt-navigate-finish", eventHandlerFunc, false); document.addEventListener("yt-page-data-updated", eventHandlerFunc, false); document.addEventListener("yt-page-type-changed", eventHandlerFunc, false); } else { loadState = -1; document.removeEventListener("yt-page-data-fetched", actor, false); return; } } if (loadState === 1) { timeout = Date.now() + 800; // Function to continuously monitor elements and update the reflected state. let pf = () => { g(0); if (Date.now() < timeout) requestAnimationFrame(pf); }; pf(); } } // Event listener that triggers when page data is fetched. document.addEventListener("yt-page-data-fetched", actor, false); // Update after visibility changed (looks like there are bugs due to inactive tab) document.addEventListener('visibilitychange', () => { if (document.visibilityState !== 'visible') return; if (checkPageVisibilityChanged) { checkPageVisibilityChanged = false; setTimeout(() => { g(1); }, 100); requestAnimationFrame(() => { g(1); }); } }, false); })(); }); })({ ResizeObserver });