// ==UserScript== // @name Wider Bilibili // @namespace https://greasyfork.org/users/1125570 // @version 0.4.7 // @author posthumz // @description 哔哩哔哩宽屏体验 // @license MIT // @icon https://www.bilibili.com/favicon.ico // @supportURL https://github.com/posthumz/wider-bilibili/issues // @match http*://*.bilibili.com/* // @grant GM_addStyle // @grant GM_addValueChangeListener // @grant GM_deleteValue // @grant GM_deleteValues // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_setValue // @run-at document-start // @compatible firefox 117+ // @compatible chrome 120+ // @compatible edge 120+ // @noframes // @downloadURL https://update.greasyfork.icu/scripts/474507/Wider%20Bilibili.user.js // @updateURL https://update.greasyfork.icu/scripts/474507/Wider%20Bilibili.meta.js // ==/UserScript== (async function () { 'use strict'; const styles = { video: `/* 播放器 */ :root { --navbar-height: 64px; --upper-nav: 0; --title-height: 0px; --reserve-height: calc(var(--upper-nav) * var(--navbar-height) + var(--title-height)); --player-height: calc(100vh - var(--reserve-height)); } /* 播放器定位 */ #playerWrap.player-wrap, #bilibili-player-wrap { position: absolute; left: 0; right: 0; top: 0; height: auto; /* 番剧页加载时播放器会有右填充 */ padding-right: 0; } #bilibili-player { /* 播放器适应宽高 */ height: auto !important; width: auto !important; box-shadow: none !important; .bpx-player-container { box-shadow: none; } /* Bilibili Evolved 夜间模式样式的优先级很高,所以嵌套在#bilibili-player里面 */ .bpx-player-video-info { color: hsla(0, 0%, 100%, .9) !important; margin-right: 10px; /* 某些页面莫名其妙加了width */ width: auto !important; } .bpx-player-video-btn-dm, .bpx-player-dm-setting, .bpx-player-dm-switch { fill: hsla(0, 0%, 100%, .9) !important; } .bpx-player-dm-hint>a { color: hsla(0, 0%, 100%, .6) !important; fill: hsla(0, 0%, 100%, .6) !important; } } /* 限制高度上限100vh - 预留高度 */ .bpx-player-container:not(:fullscreen) .bpx-player-video-wrap>video { max-height: calc(100vh - var(--reserve-height)); } /* 小窗时仍然保持播放器容器高度 */ .bpx-docker:has(>.bpx-player-container[data-screen="mini"]) { height: var(--player-height); } /* 加载时 */ .bpx-player-container:not([data-screen="mini"]) .bpx-player-video-area:has(>.bpx-state-loading) video, /* 换源时 */ .bpx-player-video-wrap>video:not([src]) { /* 宽高比不详,强制占用全高 */ height: 100vh; } /* 这啥?加载时会导致屏幕超出 */ .bpx-player-cmd-dm-wrap { position: absolute; } /* 加载动画强制显示 */ .bpx-player-loading-panel-blur { display: flex !important; } /* 强制显示播放器控件 */ .bpx-player-top-left-title, .bpx-player-top-left-music, .bpx-player-top-mask { display: block !important; } /* 不然会鬼畜 */ .bpx-player-top-mask { transition-property: none !important; } /* 原弹幕发送区域不显示 */ .bpx-player-sending-area, /* 原宽屏/网页全屏按钮不显示 */ .bpx-player-ctrl-wide, .bpx-player-ctrl-web { display: none; } /* 以防窗口过窄 */ #app { width: 100vw !important; max-width: 100% !important; } /* 导航栏 */ #biliMainHeader { height: auto !important; margin-top: var(--player-height); margin-bottom: 0; position: initial; visibility: initial !important; >.bili-header { min-height: auto !important; >.bili-header__bar { position: relative !important; height: var(--navbar-height); max-width: none; } } /* BiliBili Evolved自定义顶栏加载前,强制显示原生顶栏 */ &:not(:has(>.custom-navbar)) .bili-header__bar { display: flex !important; } /* 自定义顶栏加载后 */ >.custom-navbar { position: relative; z-index: 3 !important; } } /* 自定义顶栏加载前 */ body>.custom-navbar { z-index: 0 !important; } /* 使用 static 才能让播放器的 absolute 正确定位 */ /* 视频、番剧、收藏/稍后再看页 */ .video-container-v1, .left-container, .main-container, .playlist-container--left { position: static !important; } /* 视频页、番剧页、收藏/稍后再看页的下方容器 */ .video-container-v1, .main-container, .playlist-container { padding: 0 var(--layout-padding) !important; max-width: none !important; min-width: auto !important; } .left-container, .plp-l, .playlist-container--left { flex: 1; width: auto; } .plp-r { /* 番剧页加载时不会先使用sticky */ position: sticky !important; padding-top: 0 !important; } /* 以防播放器挡住一些浮窗 */ .playlist-container--left, .bilibili-player-wrap { z-index: 1 !important; } /* 番剧页下方容器 */ .main-container { width: auto !important; box-sizing: border-box; display: flex; /* 番剧页弹窗 */ >:nth-last-child(2)[class^=dialogcoin_coin_dialog_mask] { z-index: 100001; } /* 右下方浮动按钮位置 */ >:last-child[class^=navTools_floatNavExp] { z-index: 2 !important; } } /* 特殊页面 */ .special>.special-cover { max-height: calc(100vh - var(--title-height)); } .player-left-components { padding-right: 30px !important; } .toolbar { padding-top: 0; } /* 视频标题自动高度 */ #viewbox_report, .video-info-container { height: auto; } /* 视频标题换行显示 */ .video-title { white-space: normal !important; } /* bgm浮窗 */ #bgm-entry { z-index: 114514 !important; left: 0 !important; } /* 笔记浮窗 */ .note-pc { z-index: 114514 !important; } .fixed-sidenav-storage { z-index: initial !important; } /* Bilibili Evolved侧栏 */ .be-settings .sidebar { z-index: 114514 !important; }`, t: `#app { /* 单个动态 */ >.bg+.content { width: auto; margin: 10px 0; >.card { margin: 0 var(--layout-padding) } >.sidebar-wrap { right: 58px; margin-right: var(--layout-padding); } } /* 动态页 */ >[class^=bili-dyn-home] { margin: 0 var(--layout-padding); .left { .bili-dyn-live-users { margin-bottom: 10px; position: initial !important; transform: none !important; } } .right { width: initial; .bili-dyn-banner { display: none; } .bili-dyn-topic-box { transform: none !important; } } main { flex: 1 } .bili-dyn-sidebar { right: var(--layout-padding); transform: none; } } }`, space: `/* 新版空间页 */ #app .space-main, .nav-bar__main, .header .header-upinfo { --side-padding: var(--layout-padding) !important; } /* 空间页 */ #app { margin: 0 var(--layout-padding); min-width: 1120px; } #biliMainHeader { height: initial !important; } div.wrapper, .search-page { width: auto !important; margin: 0; } /* 主页 */ #page-index { >div.col-1 { /* 以防不支持round */ max-width: calc(100% - 400px); width: round(down, calc(100% - 400px), 180px); .section { >.content { width: auto; } /* 投稿、投币、点赞 */ &.video>.content, &.coin>.content, .channel-video { margin-left: -10px; overflow: auto !important; scroll-snap-type: both mandatory; >.small-item { padding: 10px !important; scroll-snap-align: start; } &::after { content: none; } } /* 收藏 */ &.fav>.content { margin-top: -14px; margin-left: -10px; >.fav-item { margin: 14px 10px; } } /* 番剧 */ &.bangumi>.content>.large-item { margin-right: 0; } } .article-content { width: calc(100% - 135px); } } } /* 动态 */ #page-dynamic>div.col-1 { width: calc(100% - 360px); } /* 投稿, 搜索 */ #page-video { width: 100% !important; >.col-full { display: flex; >.main-content { flex: 1; .cube-list { width: auto !important; display: flex; flex-wrap: wrap; justify-content: center; } } } } /* 合集 */ .channel-index { width: auto !important; .channel-list { gap: 20px; &::before, &::after { content: none; } .channel-item { margin: 0 !important; } } } /* 收藏夹, 关注 */ #page-fav, #page-follows { .col-full { display: flex !important; .fav-main, .follow-main { flex: 1; } } .fav-content>.fav-video-list { margin: 10px; >.small-item { margin: 10px !important; } } } /* 追番 */ #page-bangumi, #page-pgc { .section>.content { width: initial; .pgc-space-follow-page { padding-left: 0; } } }`, search: `/* 搜索页 */ .i_wrapper { padding: 0 var(--layout-padding) !important; }`, read: `/* 阅读页 */ #app { margin: 0 var(--layout-padding); >.article-detail { width: auto; .article-up-info { width: auto; margin: 0 80px 20px; } .right-side-bar { right: 0; } } }`, opus: `div.opus-detail { width: initial; margin: 0 var(--layout-padding); } .right-sidebar-wrap { margin-left: 0; right: 0; }`, message: `#message-navbar { display: none; } .container { max-width: none !important; width: auto !important; } .space-right-top { padding-top: 0 !important; }`, home: `/* 首页 */ div#i_cecream { max-width: none; } .feed-card, .floor-single-card, .bili-video-card { margin-top: 0px !important; } .palette-button-wrap { left: initial !important; right: 30px; }`, common: `/* This overrides :root style */ html { --layout-padding: 30px; } div.bili-header { min-width: auto !important; max-width: none !important; } /* 搜索栏 */ .center-search-container { min-width: 0; } /* CSS Nesting兼容性检测 */ .wb-button-group::before { content: '内核版本不完全适配脚本,请考虑升级浏览器'; color: red; } /* 脚本选项 */ #wider-bilibili { --wb-bg: var(--Wh0, #FFF); --wb-fg: var(--Ga10, #18191C); --wb-white: rgb(255, 255, 255); --wb-blue: 0, 174, 236; --wb-pink: 255, 102, 153; --wb-red: 248, 90, 84; position: fixed; top: 0; bottom: 0; height: fit-content; max-height: 80vh; left: 0; right: 0; width: fit-content; max-width: 80vw; z-index: 114514; padding: 10px; border-radius: 10px; margin: auto; box-sizing: border-box; overflow: auto; flex-direction: column; gap: 10px; border: 2px solid rgba(var(--wb-blue), 0.8); background-color: var(--wb-bg); color: var(--wb-fg); font-size: 20px; opacity: 0.9; &:popover-open { display: flex; } &:hover { opacity: 1 } >header { position: sticky; z-index: 2; top: -10px; display: flex; justify-content: space-between; margin: -10px; background-color: var(--wb-bg); font-weight: bold; &::before { content: "Wider Bilibili 选项"; align-self: center; margin-left: 10px; margin-right: auto; } } .wb-button-group { display: flex; margin-bottom: 10px; >* { height: 100%; } } div.wb-button-group::before { display: none; } a, #wb-close { padding: 4px; color: var(--wb-fg); display: flex; font-size: 16px; text-wrap: nowrap; transition: opacity .1s; cursor: pointer; &:hover { opacity: 0.75; } &:active { opacity: 0.5; } >svg { width: 20px; height: 20px; fill: currentColor; fill-rule: evenodd; clip-rule: evenodd; } } #wb-close { width: fit-content; height: fit-content; opacity: 1; border-radius: 0; outline: none; box-shadow: none; &:hover { background-color: rgb(var(--wb-red)); } &:active { background-color: rgba(var(--wb-red), 0.75); } } >fieldset { border: none; border-radius: 10px; padding: 10px; margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 15px; background-color: rgba(127, 127, 127, 0.1); &::before { content: attr(name); border-radius: 4px 4px 0 0; border-bottom: 2px solid rgba(127, 127, 127, 0.1); grid-column: 1 / -1; } } [data-option]::after { content: attr(data-option); text-wrap: nowrap; } [data-hint]:hover::before { position: absolute; bottom: 110%; left: 0; right: 0; margin: 0 auto; width: fit-content; padding: 3px 5px; border-radius: 5px; content: attr(data-hint); font-size: 12px; background-color: rgb(var(--wb-blue)); color: var(--wb-white); white-space: pre-line; } label { display: inline-flex; gap: 10px; place-items: center; position: relative; } input, button { box-sizing: content-box; margin: 0; padding: 4px; height: 20px; font-size: 16px; line-height: 1; transition: .2s; &:hover { box-shadow: 0 0 8px rgb(var(--wb-blue)); } &:active { opacity: 0.5; } } input { &[type=checkbox] { box-sizing: content-box; border-radius: 20px; min-width: 40px; background-color: #ccc; appearance: none; cursor: pointer; &::before { content: ""; position: relative; display: block; transition: 0.3s; height: 100%; aspect-ratio: 1/1; border-radius: 50%; background-color: #FFF; } &:checked { background-color: rgb(var(--wb-blue)); } &:checked::before { transform: translateX(20px); } } &[type=number] { width: 40px; border: none; border-radius: 5px; outline: 2px solid rgb(var(--wb-blue)); background: none; color: var(--wb-fg); appearance: textfield; &::-webkit-inner-spin-button { appearance: none; } } } button { border: none; background: none; border-radius: 5px; outline: 1px solid #C9CCD0; &:hover { outline: 2px solid rgb(var(--wb-blue)); } } }`, upperNavigation: `/* 导航栏上置 (默认下置) */ :root { --upper-nav: 1; } #biliMainHeader { margin-top: 0; margin-bottom: var(--player-height); /* 播放器的 z-index 是100000 */ z-index: 114514; } #playerWrap.player-wrap, #bilibili-player-wrap { top: var(--navbar-height); }`, stickyHeader: `#biliMainHeader { position: sticky; top: 0; /* 其他元素 z-index 基本是<100 */ z-index: 100; }`, stickyAside: `#app .left { height: fit-content; position: sticky; top: 72px; }`, reserveTitleBar: `:root { --title-height: calc(100px + (1 - var(--upper-nav)) * var(--navbar-height)); }`, pauseShowControls: `/* 暂停显示控件 */ .bpx-player-container.bpx-state-paused { .bpx-player-top-wrap, .bpx-player-control-top, .bpx-player-control-bottom, .bpx-player-control-mask { opacity: 1 !important; visibility: visible !important; } div.bpx-player-shadow-progress-area { visibility: hidden !important; } .bpx-player-pbp { bottom: 100% !important; margin-bottom: 5px; opacity: 1 !important; left: 0; right: 0; width: auto !important; .bpx-player-pbp-pin { opacity: 1 !important; } } }`, mini: `/* 小窗 */ .bpx-player-container { --mini-width: 320px; /* 最小宽度,以防不可见 */ min-width: 180px; &[data-screen="mini"] { max-width: var(--mini-width) !important; width: auto !important; height: auto !important; /* 以防竖屏视频超出:留出导航栏高度+16px */ .bpx-player-video-wrap>video { max-height: calc(100vh - 16px - var(--navbar-height)); } } } .bpx-player-mini-resizer { position: absolute; left: 0; width: 10px; height: 100%; cursor: ew-resize; }`, hideControls: `.bpx-player-control-mask, .bpx-player-control-top, .bpx-player-control-bottom, .bpx-player-pbp { opacity: 0 !important; } .bpx-player-top-wrap:hover { opacity: 1 !important; } .bpx-player-control-wrap:not(:hover) { .bpx-player-shadow-progress-area { opacity: 1 !important; visibility: visible !important; } } .bpx-player-control-wrap:hover { .bpx-player-control-mask, .bpx-player-control-top, .bpx-player-control-bottom, .bpx-player-pbp { opacity: 1 !important; } }`, fixHeight: `.bpx-player-container:not([data-screen="mini"]) .bpx-player-video-wrap>video { height: 100vh; }`, compactControls: `/* 播放器控件 */ .bpx-player-control-bottom { padding: 0 20px !important; } .bpx-player-control-bottom>* { flex: initial !important; } /* 控件区域 */ .bpx-player-control-bottom-left, .bpx-player-control-bottom-right { min-width: auto !important; gap: 8px; } /* Bilibili Evolved 自定义控件区域 */ .bpx-player-control-bottom-left>.be-video-control-bar-extend { gap: 8px; } /* 减少中间填充空间 */ .bpx-player-control-bottom-center { flex: 1 !important; padding: 0 20px !important; } /* 防止选集/倍速按钮错位 */ .bpx-player-control-bottom-right>.bpx-player-ctrl-btn:hover { padding: 0; } /* 所有按钮控件 */ .bpx-player-ctrl-btn { margin: 0 !important; width: fit-content !important; } .bpx-player-ctrl-time { width: 130px !important; } /* 时间控件 */ .bpx-player-ctrl-time-seek { width: 100% !important; padding: 0 !important; left: 0 !important; } .bpx-player-ctrl-time-label { text-align: center !important; text-indent: 0 !important; } /* 弹幕发送框区域 */ .bpx-player-sending-bar { background-color: transparent !important; max-width: 90% !important; } .bpx-player-video-inputbar { max-width: none !important; } .bpx-player-video-inputbar-wrap { width: auto; }` }; const waitFor = (loaded, desc = "页面加载", retry = 100, interval = 100) => new Promise((resolve, reject) => { const intervalID = setInterval((res = loaded()) => { if (res) { clearInterval(intervalID); console.info(`${desc}已加载`); return resolve(res); } if (--retry === 0) { clearInterval(intervalID); return reject(new Error(`${desc}加载超时`)); } if (retry % 10 === 0) { console.debug(`${desc}等待加载`); } }, interval); }); const observeFor = (className, parent) => new Promise((resolve) => { const elem = parent.getElementsByClassName(className)[0]; if (elem) { return resolve(elem); } new MutationObserver((mutations, observer) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node instanceof HTMLElement && node.classList.contains(className)) { observer.disconnect(); return resolve(node); } } } }).observe(parent, { childList: true }); }); const waitReady = () => new Promise((resolve) => { document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", () => resolve(), { once: true }) : resolve(); }); const html = `