Get in-page player picker to at least show up

This commit is contained in:
Tamius Han 2026-01-23 22:46:37 +01:00
parent 35bb5b477b
commit 7d296e6a3d
3 changed files with 146 additions and 138 deletions

View File

@ -160,14 +160,41 @@
:settings="settings" :settings="settings"
></OtherSiteSettings> ></OtherSiteSettings>
<!--
<PlayerElementSettings <PlayerElementSettings
v-if="selectedTab === 'settings.player-element-settings'" v-if="selectedTab === 'settings.player-element-settings'"
:settings="settings" :settings="settings"
:eventBus="eventBus" :eventBus="eventBus"
> >
</PlayerElementSettings> </PlayerElementSettings>
<PlayerElementWindow
v-if="selectedTab === 'window.player-element-settings'"
:settings="settings"
:eventBus="eventBus"
></PlayerElementWindow> -->
<template v-if="selectedTab === 'window.player-element-advanced-settings'">
<PlayerSelectorAdvancedForm
v-if="settings && siteSettings"
:settings="settings"
:siteSettings="siteSettings"
></PlayerSelectorAdvancedForm>
<template v-else>Loading site settings, please wait ...</template>
</template>
<template v-if="selectedTab === 'window.player-element-settings'">
<PlayerSelectorSimple
v-if="settings && siteSettings"
:site="site"
:eventBus="eventBus"
:settings="settings"
:siteSettings="siteSettings"
></PlayerSelectorSimple>
<template v-else>Loading site settings, please wait ...</template>
</template>
<AutodetectionSettings <AutodetectionSettings
v-if="selectedTab === 'autodetectionSettings'" v-if="selectedTab === 'autodetectionSettings'"
:settings="settings" :settings="settings"
@ -242,6 +269,8 @@ import SiteExtensionSettings from '@components/segments/ExtensionSettings/Panels
import FrameSiteSettings from '@components/segments/ExtensionSettings/Panels/FrameSiteSettings.vue'; import FrameSiteSettings from '@components/segments/ExtensionSettings/Panels/FrameSiteSettings.vue';
import Debugging from '@components/segments/Debugging/Debugging.vue'; import Debugging from '@components/segments/Debugging/Debugging.vue';
import ImportExportSettings from '@components/segments/ImportExportSettings/ImportExportSettings.vue'; import ImportExportSettings from '@components/segments/ImportExportSettings/ImportExportSettings.vue';
import PlayerSelectorAdvancedForm from '@components/segments/PlayerElementSelection/Panels/PlayerSelectorAdvancedForm.vue';
import PlayerSelectorSimple from '@components/segments/PlayerElementSelection/Panels/PlayerSelectorSimple.vue';
import AfterUpdate from '@components/segments/AfterUpdate/AfterUpdate.vue'; import AfterUpdate from '@components/segments/AfterUpdate/AfterUpdate.vue';
@ -250,6 +279,7 @@ import About from '@components/segments/ExtensionInfo/About.vue';
// not component: // not component:
import BrowserDetect from '@src/ext/conf/BrowserDetect' import BrowserDetect from '@src/ext/conf/BrowserDetect'
import WarningsMixin from '../utils/mixins/WarningsMixin.vue';
const AVAILABLE_TABS = { const AVAILABLE_TABS = {
@ -281,11 +311,17 @@ const AVAILABLE_TABS = {
{ id: 'website-extension-settings', label: 'Website exceptions', }, { id: 'website-extension-settings', label: 'Website exceptions', },
] ]
}, },
'window.player-element-settings': { id: 'window.player-element-settings', label: 'Advanced video player options', icon: 'play-box-edit-outline' }, 'window.player-element-settings': {
id: 'window.player-element-settings', label: 'Video player options', icon: 'play-box-edit-outline',
children: [
{id: 'window.player-element-settings', label: 'Video player picker'},
{id: 'window.player-element-advanced-settings', label: 'Advanced options'},
],
},
'autodetectionSettings': {id: 'autodetectionSettings', label: 'Autodetection options', icon: 'auto-fix'}, 'autodetectionSettings': {id: 'autodetectionSettings', label: 'Autodetection options', icon: 'auto-fix'},
'ui-settings': {id: 'ui-settings', label: 'UI settings', icon: 'movie-cog-outline' }, 'ui-settings': {id: 'ui-settings', label: 'UI settings', icon: 'movie-cog-outline' },
'keyboardShortcuts': {id: 'keyboardShortcuts', label: 'Keyboard shortcuts', icon: 'keyboard-outline' }, 'keyboardShortcuts': {id: 'keyboardShortcuts', label: 'Keyboard shortcuts', icon: 'keyboard-outline' },
'playerDetection': {id: 'playerDetection', label: 'Player detection', icon: 'television-play'}, 'settings.player-element-settings': {id: 'settings.player-element-settings', label: 'Player detection', icon: 'television-play'},
'installed': { id: 'installed', label: 'Update completed', icon: 'monitor-arrow-down-variant'}, 'installed': { id: 'installed', label: 'Update completed', icon: 'monitor-arrow-down-variant'},
'updated': { id: 'updated', label: 'Update completed', icon: 'update'}, 'updated': { id: 'updated', label: 'Update completed', icon: 'update'},
@ -299,7 +335,7 @@ const AVAILABLE_TABS = {
const TAB_LOADOUT = { const TAB_LOADOUT = {
'settings': [ 'settings': [
'default-extension-settings', 'default-extension-settings',
'settings.player-element-settings', // 'settings.player-element-settings',
'autodetectionSettings', 'autodetectionSettings',
'ui-settings', 'ui-settings',
'keyboardShortcuts', 'keyboardShortcuts',
@ -344,6 +380,8 @@ export default defineComponent({
OtherSiteSettings, OtherSiteSettings,
PlayerElementSettings, PlayerElementSettings,
PlayerElementWindow, PlayerElementWindow,
PlayerSelectorAdvancedForm,
PlayerSelectorSimple,
AutodetectionSettings, AutodetectionSettings,
KeyboardShortcutSettings, KeyboardShortcutSettings,
UISettings, UISettings,
@ -357,7 +395,9 @@ export default defineComponent({
WhatsNew, WhatsNew,
About, About,
}, },
mixins: [], mixins: [
WarningsMixin
],
data() { data() {
return { return {
statusFlags: { statusFlags: {

View File

@ -1,137 +1,82 @@
<template> <template>
<div class="w-full flex flex-row" style="margin-top: 1rem;"> <div class="w-full flex flex-col" style="margin-top: 1rem;">
<h2 class="text-[1.75em]">Simple video player picker</h2>
<div class="text text-sm text-stone-500">
<p>If your video is not aligned correctly, video player was not detected correctly.</p>
<p>You need to help by selecting the video player. Hover over boxes below. This will highlight part of the screen.</p>
<p>Select the first box that highlights the video player on the page.</p>
</div>
<div class="">
<div class="flex flex-row gap-4">
<button>How to use</button>
</div>
</div>
<!-- PLAYER ELEMENT SELECTOR FOR DUMMIES --> <!-- PLAYER ELEMENT SELECTOR FOR DUMMIES -->
<div style="width: 48%"> <div class="flex flex-col-reverse gap-2">
<div class="sub-panel-content"> <div
<div v-if="showAdvancedOptions" style="display: flex; flex-direction: row">
<div style="display: flex; flex-direction: column">
<div>
<input :checked="playerManualQs"
@change="togglePlayerManualQs"
type="checkbox"
/>
<div>
Use <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors" target="_blank">CSS selector</a> for player<br/>
<small>If defining multiple selectors, separate them with commas.</small>
</div>
</div>
<div>Selector</div>
<input type="text"
v-model="playerQs"
@change="updatePlayerQuerySelector"
@blur="updatePlayerQuerySelector"
:disabled="playerByNodeIndex || !playerManualQs"
/>
</div>
<div style="display: flex; flex-direction: column">
<b>Custom CSS for site</b>
<textarea></textarea>
</div>
</div>
<div style="display: flex; flex-direction: row;">
<div class="element-tree">
<table>
<thead>
<tr>
<th>
<div class="status-relative">
Status <mdicon name="help-circle" @click="showLegend = !showLegend" />
<div v-if="showLegend" class="element-symbol-legend">
<b>Symbols:</b><br />
<mdicon name="alert-remove" class="invalid" /> Element of invalid dimensions<br />
<mdicon name="refresh-auto" class="auto-match" /> Ultrawidify's player detection thinks this should be the player<br />
<mdicon name="bookmark" class="parent-offset-match" /> Site settings say this should be the player (based on counting parents)<br />
<mdicon name="crosshairs" class="qs-match" /> Site settings say this should be the player (based on query selectors)<br />
<mdicon name="check-circle" class="activePlayer" /> Element that is actually the player
</div>
</div>
</th>
<th>Element</th>
<!-- <th>Actions</th> -->
<!-- <th>Quick fixes</th> -->
</tr>
</thead>
<tbody>
<tr
v-for="(element, index) of elementStack" v-for="(element, index) of elementStack"
:key="index" :key="index"
class="element-row" class="py-2 px-4 border border-stone-500 flex flex-col gap-2 text-sm cursor-pointer"
> :class="{
<td> '!border-blue-500': element.heuristics?.autoMatch,
<div class="status"> '!border-teal-800': element.heuristics?.manualElementByParentIndex,
<div '!border-emerald-500': element.heuristics?.qsMatch,
v-if="element.heuristics?.invalidSize" '!border-red-700 bg-red-950/50': element.heuristics?.invalidSize,
class="invalid" '!border-primary-300': element.heuristics?.activePlayer,
> '!pointer-events-none opacity-50': element.tagName == 'video',
<mdicon name="alert-remove" /> }"
</div>
<div
v-if="element.heuristics?.autoMatch"
class="auto-match"
>
<mdicon name="refresh-auto" />
</div>
<div
v-if="element.heuristics?.qsMatch"
class="qs-match"
>
<mdicon name="crosshairs" />
</div>
<div
v-if="element.heuristics?.manualElementByParentIndex"
class="parent-offset-match"
>
<mdicon name="bookmark" />
</div>
<div
v-if="element.heuristics?.activePlayer"
class="activePlayer"
>
<mdicon name="check-circle" />
</div>
</div>
</td>
<td>
<div
class="element-data"
@mouseover="markElement(elementStack.length - index - 1, true)" @mouseover="markElement(elementStack.length - index - 1, true)"
@mouseleave="markElement(elementStack.length - index - 1, false)" @mouseleave="markElement(elementStack.length - index - 1, false)"
@click="setPlayer(elementStack.length - index - 1)" @click="setPlayer(elementStack.length - index - 1)"
> >
<div
v-if="element.heuristics?.autoMatch"
class="text-primary-300 flex flex-row gap-2"
>
<mdicon name="check-circle" /> This element is currently treated as player element.
</div>
<div>
<div class="tag"> <div class="tag">
<b>{{element.tagName}}</b> <i class="id">{{element.id ? `#`:''}}{{element.id}}</i> @ <span class="dimensions">{{element.width}}</span>x<span class="dimensions">{{element.height}}</span> <b>&lt;{{element.tagName}}&gt;</b> <i class="text-red-800">{{element.id ? `#`:''}}{{element.id}}</i> @ <span class="text-blue-500">{{element.width}}</span>x<span class="text-blue-500">{{element.height}}</span>
</div> </div>
<div v-if="element.classList" class="class-list"> <div v-if="element.classList" class="text-nowrap overflow-hidden text-ellipsis text-stone-500/50">
<div v-for="cls of element.classList" :key="cls"> <span v-for="cls of element.classList" :key="cls">.{{cls}}&nbsp;</span>
{{cls}}
</div>
</div>
</div>
</td>
<td>
<div class="flex flex-row">
</div>
</td>
</tr>
</tbody>
</table>
<div class="element-config">
</div> </div>
</div> </div>
<!-- <div class="css-preview">
{{cssStack}} <div
</div> --> v-if="element.heuristics?.qsMatch"
class="text-emerald-600 flex flex-row gap-2"
>
<mdicon name="crosshairs" /> This element matches query string (advanced settings)
</div>
<div
v-if="element.heuristics?.manualElementByParentIndex"
class="text-teal-800 flex flex-row gap-2"
>
<mdicon name="bookmark" /> This element has been manually selected as player element.
</div>
<div
v-if="element.heuristics?.autoMatch"
class="text-blue-500 flex flex-row gap-2"
>
<mdicon name="refresh-auto" /> Automatic detections thinks this is the player.
</div>
<div
v-if="element.heuristics?.invalidSize"
class="text-red-700 flex flex-row gap-2"
>
<mdicon name="alert-remove" /> This element has invalid dimensions
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
@ -156,11 +101,9 @@ export default defineComponent({
}, },
mixins: [], mixins: [],
props: [ props: [
'settings', // not used?
'siteSettings', 'siteSettings',
'frame',
'eventBus', 'eventBus',
'site',
'isPopup'
], ],
created() { created() {
this.eventBus.subscribe( this.eventBus.subscribe(

View File

@ -0,0 +1,25 @@
<script lang="ts">
import { SiteSettings } from '@src/ext/module/settings/SiteSettings'
export default {
data() {
return {
warnings: {
drm: false,
cors: false,
settingsUpdated: false,
extensionDisabled: {
allDisabled: false, // there's no way extension can run on this page
iframesAllowed: false, // page is blacklisted, but embedded content isn't
iframesBlacklisted: false, // page is enabled, but contains embedded content from blacklisted domains
}
}
}
},
methods: {
generateExtensionDisabledWarnings(site: {host: string, hostnames: string[]}) {
const siteSettings = new SiteSettings(this.settings, {site: site.host});
}
}
}
</script>