Compare commits

...

4 Commits

14 changed files with 556 additions and 412 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "ultrawidify", "name": "ultrawidify",
"version": "6.0.2", "version": "6.2.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "ultrawidify", "name": "ultrawidify",
"version": "6.0.2", "version": "6.2.0",
"description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.", "description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.",
"author": "Tamius Han <tamius.han@gmail.com>", "author": "Tamius Han <tamius.han@gmail.com>",
"scripts": { "scripts": {

View File

@ -1,351 +1,433 @@
<template> <template>
<div class="flex flex-col tab-root"> <div class="flex flex-col">
<!-- ADD ANY OPTION BARS HERE --> <div class="flex flex-row">
<h1>Video player options</h1>
</div>
<div class="flex flex-row">
<div style="width: 48%">
NEW PLAYER SELECTOR
<div class="sub-panel-content">
<p>
You're probably on this page because Ultrawidify doesn't crop the player correctly.
</p>
<p>
If you hover over the boxes below, the corresponding element will be highlighted with golden outline. Player should be the first element that covers the video player on the page.
</p>
<p>
You need to reload the page for changes to take effect.
</p>
<!-- The rest of the tab --> <!-- <p>
<div class="flex flex-row flex-wrap"> <a @click="showAdvancedOptions = !showAdvancedOptions">
<template v-if="showAdvancedOptions">Hide advanced options</template>
<template v-else>Show advanced options</template>
</a>
</p> -->
<!-- Player element picker --> <div v-if="showAdvancedOptions" style="display: flex; flex-direction: row">
<div class="sub-panel"> <div style="display: flex; flex-direction: column">
<div class="flex flex-row"> <div>
<h1><mdicon name="television-play" :size="32" /> Player element</h1> <input :checked="playerManualQs"
</div> @change="togglePlayerManualQs"
<div class="flex flex-row"> type="checkbox"
<div class="sub-panel-content">
<p>
You're probably on this page because Ultrawidify doesn't crop the player correctly.
</p>
<p>
If you hover over the boxes below, the corresponding element will change (sepia filter + higher brightness + reduced contrast + it gets an outline). Player element
should be the closest element to the video element, for which the sepia/brightness effect covers the area you expect the video will cover.
</p>
<p>
You need to reload the page for changes to take effect.
</p>
<!-- <p>
<a @click="showAdvancedOptions = !showAdvancedOptions">
<template v-if="showAdvancedOptions">Hide advanced options</template>
<template v-else>Show advanced options</template>
</a>
</p> -->
<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>
<div style="display: flex; flex-direction: column"> Use <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors" target="_blank">CSS selector</a> for player<br/>
<b>Custom CSS for site</b> <small>If defining multiple selectors, separate them with commas.</small>
<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"
:key="index"
class="element-row"
>
<td>
<div class="status">
<div
v-if="element.heuristics?.invalidSize"
class="invalid"
>
<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(index, true)"
@mouseleave="markElement(index, false)"
@click="setPlayer(index)"
>
<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>
</div>
<div v-if="element.classList" class="class-list">
<div v-for="cls of element.classList" :key="cls">
{{cls}}
</div>
</div>
</div>
</td>
<td>
<div class="flex flex-row">
<!-- <div @click="designatePlayer(index)">Set as player {{ index }}</div> -->
</div>
</td>
<!-- <td>
<div
class="css-fixes"
>
<div style="width: 100%"><b>Quick fixes:</b></div>
<div
class="css-line"
:class="{'active': cssStack[index]?.includes('width: 100%;')}"
@click="toggleCssForElement(index, 'width: 100%;')"
>
Width: 100%
</div>
<div
class="css-line"
:class="{'active': cssStack[index]?.includes('height: 100%;')}"
@click="toggleCssForElement(index, 'height: 100%;')"
>
Height: 100%
</div>
<div
class="css-line"
:class="{'active': cssStack[index]?.includes('display: flex;')}"
@click="toggleCssForElement(index, 'display: flex;')"
>
Display: flex
</div>
<div class="css-line">
Flex direction:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('flex-direction: row;')}"
@click="toggleCssForElement(index, 'flex-direction', 'row')"
>
row
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('flex-direction: column;')}"
@click="toggleCssForElement(index, 'flex-direction', 'column')"
>
column
</span>
</div>
<div class="css-line">
Justify content:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-content: start;')}"
@click="toggleCssForElement(index, 'justify-content', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-content: center;')}"
@click="toggleCssForElement(index, 'justify-content', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-content: end;')}"
@click="toggleCssForElement(index, 'justify-content', 'end')"
>
end
</span>
</div>
<div class="css-line">
Align items:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-items: start;')}"
@click="toggleCssForElement(index, 'align-items', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-items: center;')}"
@click="toggleCssForElement(index, 'align-items', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-items: end;')}"
@click="toggleCssForElement(index, 'align-items', 'end')"
>
end
</span>
</div>
<div class="css-line">
Justify self:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-self: start;')}"
@click="toggleCssForElement(index, 'justify-self', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-self: center;')}"
@click="toggleCssForElement(index, 'justify-self', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-self: end;')}"
@click="toggleCssForElement(index, 'justify-self', 'end')"
>
end
</span>
</div>
<div class="css-line">
Align self:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-self: start;')}"
@click="toggleCssForElement(index, 'align-self', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-self: center;')}"
@click="toggleCssForElement(index, 'align-self', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-self: end;')}"
@click="toggleCssForElement(index, 'align-self', 'end')"
>
end
</span>
</div>
<div class="css-line">
Text-align:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('text-align: left;')}"
@click="toggleCssForElement(index, 'text-align', 'left')"
>
left
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('text-align: center;')}"
@click="toggleCssForElement(index, 'text-align', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.find(x => x.includes('text-align: right'))}"
@click="toggleCssForElement(index, 'text-align', 'right')"
>
right
</span>
</div>
<div class="css-line">
Position:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('position: relative;')}"
@click="toggleCssForElement(index, 'position', 'relative')"
>
relative
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('position: absolute;')}"
@click="toggleCssForElement(index, 'position', 'absolute')"
>
absolute
</span>
</div>
</div>
</td> -->
</tr>
</tbody>
</table>
<div class="element-config">
</div> </div>
</div> </div>
<div>Selector</div>
<!-- <div class="css-preview"> <input type="text"
{{cssStack}} v-model="playerQs"
</div> --> @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> </div>
<!-- <div class="sub-panel-content"> <div style="display: flex; flex-direction: row;">
<h2>Advanced settings</h2> <div class="element-tree">
</div> --> <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"
:key="index"
class="element-row"
>
<td>
<div class="status">
<div
v-if="element.heuristics?.invalidSize"
class="invalid"
>
<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(index, true)"
@mouseleave="markElement(index, false)"
@click="setPlayer(index)"
>
<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>
</div>
<div v-if="element.classList" class="class-list">
<div v-for="cls of element.classList" :key="cls">
{{cls}}
</div>
</div>
</div>
</td>
<td>
<div class="flex flex-row">
<!-- <div @click="designatePlayer(index)">Set as player {{ index }}</div> -->
</div>
</td>
<!-- <td>
<div
class="css-fixes"
>
<div style="width: 100%"><b>Quick fixes:</b></div>
<div
class="css-line"
:class="{'active': cssStack[index]?.includes('width: 100%;')}"
@click="toggleCssForElement(index, 'width: 100%;')"
>
Width: 100%
</div>
<div
class="css-line"
:class="{'active': cssStack[index]?.includes('height: 100%;')}"
@click="toggleCssForElement(index, 'height: 100%;')"
>
Height: 100%
</div>
<div
class="css-line"
:class="{'active': cssStack[index]?.includes('display: flex;')}"
@click="toggleCssForElement(index, 'display: flex;')"
>
Display: flex
</div>
<div class="css-line">
Flex direction:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('flex-direction: row;')}"
@click="toggleCssForElement(index, 'flex-direction', 'row')"
>
row
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('flex-direction: column;')}"
@click="toggleCssForElement(index, 'flex-direction', 'column')"
>
column
</span>
</div>
<div class="css-line">
Justify content:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-content: start;')}"
@click="toggleCssForElement(index, 'justify-content', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-content: center;')}"
@click="toggleCssForElement(index, 'justify-content', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-content: end;')}"
@click="toggleCssForElement(index, 'justify-content', 'end')"
>
end
</span>
</div>
<div class="css-line">
Align items:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-items: start;')}"
@click="toggleCssForElement(index, 'align-items', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-items: center;')}"
@click="toggleCssForElement(index, 'align-items', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-items: end;')}"
@click="toggleCssForElement(index, 'align-items', 'end')"
>
end
</span>
</div>
<div class="css-line">
Justify self:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-self: start;')}"
@click="toggleCssForElement(index, 'justify-self', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-self: center;')}"
@click="toggleCssForElement(index, 'justify-self', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('justify-self: end;')}"
@click="toggleCssForElement(index, 'justify-self', 'end')"
>
end
</span>
</div>
<div class="css-line">
Align self:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-self: start;')}"
@click="toggleCssForElement(index, 'align-self', 'start')"
>
start
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-self: center;')}"
@click="toggleCssForElement(index, 'align-self', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('align-self: end;')}"
@click="toggleCssForElement(index, 'align-self', 'end')"
>
end
</span>
</div>
<div class="css-line">
Text-align:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('text-align: left;')}"
@click="toggleCssForElement(index, 'text-align', 'left')"
>
left
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('text-align: center;')}"
@click="toggleCssForElement(index, 'text-align', 'center')"
>
center
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.find(x => x.includes('text-align: right'))}"
@click="toggleCssForElement(index, 'text-align', 'right')"
>
right
</span>
</div>
<div class="css-line">
Position:
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('position: relative;')}"
@click="toggleCssForElement(index, 'position', 'relative')"
>
relative
</span> |
<span
class="css-line-suboption"
:class="{'active': cssStack[index]?.includes('position: absolute;')}"
@click="toggleCssForElement(index, 'position', 'absolute')"
>
absolute
</span>
</div>
</div>
</td> -->
</tr>
</tbody>
</table>
<div class="element-config">
</div>
</div>
<!-- <div class="css-preview">
{{cssStack}}
</div> -->
</div>
</div> </div>
</div> </div>
<div style="width: 48%">
<div>EXAMPLE <small style="opacity: 0.5"><br/>ps: i know this ui is shit, no need to tell me</small></div>
<div class="demo-images">
<div class="fig1">
<img src="/res/img/player-select-demo/uw_player_select___too_little.webp" />
<div>If you see this when hovering over the element, you need to select further down the list.</div>
</div>
<div class="fig2">
<div>
<p>
If you see this when hovering over the element, you're hovering over the correct element.
</p>
<p>
In case there's more than one element that covers the entire player and nothing more, select the option that's closest to the top of the list, otherwise in-player UI could break.
</p>
<p>
If in-player UI breaks, you can make the settings window appear from the extension popup.
</p>
</div>
<img src="/res/img/player-select-demo/uw_player_select___just-right.webp" />
</div>
<div class="fig1">
<img src="/res/img/player-select-demo/uw_player_select___too_much.webp" />
<div>If you see this when hovering over the element, you need to select an element closer to the top of the list.</div>
</div>
</div>
</div>
<div style="width: 48%" v-if="false">
<h2>Legacy advanced settings</h2>
<div class="">
<h3>Player element</h3>
<div class="field">
<div class="label">Manually specify player</div>
<input type="checkbox" />
</div>
<div class="field">
<div class="label">Select player by/as:</div>
<div class="select">
<select>
<option>n-th parent of video</option>
<option>Query selectors</option>
</select>
</div>
</div>
<div class="field">
<div class="label">Player is n-th parent of video</div>
<div class="range-input">
<input type="range" min="0" max="100" />
<input />
</div>
</div>
<div class="field">
<div class="label">Query selector for player element</div>
<div class="input">
<input />
</div>
</div>
<div class="field">
<div class="label">In full screen, calculate crop based on monitor resolution</div>
<input type="checkbox" />
</div>
<h3>Video element</h3>
<div class="field">
<div class="label">Select video element automatically</div>
<input type="checkbox">
</div>
<div class="field">
<div class="label">Query selectors</div>
<div class="input">
<input>
</div>
</div>
<div class="field">
<div class="label">Additional styles for video element</div>
<div class="input">
<textarea></textarea>
</div>
</div>
<h3>Additional css for this page</h3>
<div class="field">
<div class="label">Additional CSS for this page</div>
<textarea></textarea>
</div>
</div>
</div>
<!-- <div class="sub-panel-content">
<h2>Advanced settings</h2>
</div> -->
</div> </div>
</div> </div>
</template> </template>
@ -467,6 +549,9 @@ export default({
}) })
</script> </script>
<style lang="scss" src="../../res/css/flex.scss" scoped module></style>
<style lang="scss" src="../res-common/panels.scss" scoped module></style>
<style lang="scss" src="../res-common/common.scss" scoped module></style>
<style lang="scss" scoped> <style lang="scss" scoped>
p { p {
font-size: 1rem; font-size: 1rem;
@ -575,4 +660,32 @@ p {
.tab-root { .tab-root {
width: 100%; width: 100%;
} }
.demo-images {
width: 100%;
display: flex;
flex-direction: column;
padding-top: 2rem;
.fig1, .fig2 {
margin-top: -2rem;
max-height: 18rem;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
.fig1 {
align-self: start;
}
.fig2 {
align-self: end;
}
img {
max-width: 32rem;
}
}
</style> </style>

View File

@ -11,14 +11,15 @@ import AspectRatioType from '../../common/enums/AspectRatioType.enum';
const ExtensionConfPatch = [ const ExtensionConfPatch = [
{ {
forVersion: '6.0.1-1', forVersion: '6.1.1',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
// add new commands // add new commands
userOptions.commands = defaultOptions.commands; userOptions.commands = defaultOptions.commands;
userOptions.actions = defaultOptions.actions;
} }
}, { }, {
// NOTE - when releasing shit, ensure ALL alpha migrations are combined together in one function // NOTE - when releasing shit, ensure ALL alpha migrations are combined together in one function
forVersion: '6.0.1-2', forVersion: '6.1.2',
updateFn: (userOptions, defaultOptions) => { updateFn: (userOptions, defaultOptions) => {
userOptions.commands = defaultOptions.commands; userOptions.commands = defaultOptions.commands;
@ -89,7 +90,7 @@ const ExtensionConfPatch = [
} }
} }
}, { }, {
forVersion: '6.0.1-3', forVersion: '6.0.3',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
delete (userOptions as any).sites['@global'].persistOption; delete (userOptions as any).sites['@global'].persistOption;
delete (userOptions as any).sites['@empty'].persistOption; delete (userOptions as any).sites['@empty'].persistOption;
@ -98,7 +99,7 @@ const ExtensionConfPatch = [
userOptions.sites['@empty'].persistCSA = CropModePersistence.Disabled; userOptions.sites['@empty'].persistCSA = CropModePersistence.Disabled;
} }
}, { }, {
forVersion: '6.0.1-4', forVersion: '6.0.4',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
// deprecated much? // deprecated much?
@ -110,36 +111,36 @@ const ExtensionConfPatch = [
arg: AspectRatioType.Cycle arg: AspectRatioType.Cycle
}] }]
}); });
userOptions.commands.crop.push({ // userOptions.commands.crop.push({
action: 'set-ar', // action: 'set-ar',
label: 'Cycle', // label: 'Cycle',
comment: 'Cycle through crop options', // comment: 'Cycle through crop options',
arguments: { // arguments: {
type: AspectRatioType.Cycle // type: AspectRatioType.Cycle
}, // },
shortcut: { // shortcut: {
key: 'c', // key: 'c',
code: 'KeyC', // code: 'KeyC',
ctrlKey: false, // ctrlKey: false,
metaKey: false, // metaKey: false,
altKey: false, // altKey: false,
shiftKey: false, // shiftKey: false,
onKeyUp: true, // onKeyUp: true,
onKeyDown: false, // onKeyDown: false,
} // }
}); // });
userOptions.commands.crop.push({ // userOptions.commands.crop.push({
action: 'set-ar', // action: 'set-ar',
label: '32:9', // label: '32:9',
comment: 'Crop for 32:9 aspect ratio', // comment: 'Crop for 32:9 aspect ratio',
arguments: { // arguments: {
type: AspectRatioType.Fixed, // type: AspectRatioType.Fixed,
ratio: 3.56 // ratio: 3.56
}, // },
}) // })
} }
}, { }, {
forVersion: '6.0.1-5', forVersion: '6.1.5',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
if (!userOptions.sites['@global'].defaults.alignment || !userOptions.sites['@global'].defaults.alignment.x || !userOptions.sites['@global'].defaults.alignment.y) { if (!userOptions.sites['@global'].defaults.alignment || !userOptions.sites['@global'].defaults.alignment.x || !userOptions.sites['@global'].defaults.alignment.y) {
userOptions.sites['@global'].defaults.alignment = { userOptions.sites['@global'].defaults.alignment = {
@ -150,7 +151,7 @@ const ExtensionConfPatch = [
userOptions.sites['@empty'].defaults.alignment = {x: VideoAlignmentType.Default, y: VideoAlignmentType.Default}; userOptions.sites['@empty'].defaults.alignment = {x: VideoAlignmentType.Default, y: VideoAlignmentType.Default};
} }
}, { }, {
forVersion: '6.0.1-6', forVersion: '6.1.1-6',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
for (const site in userOptions.sites) { for (const site in userOptions.sites) {
userOptions.sites[site].defaultType = userOptions.sites[site].type as any; userOptions.sites[site].defaultType = userOptions.sites[site].type as any;
@ -159,7 +160,7 @@ const ExtensionConfPatch = [
userOptions.sites['@empty'].defaultType = 'modified'; userOptions.sites['@empty'].defaultType = 'modified';
} }
}, { }, {
forVersion: '6.0.2-0', forVersion: '6.1.2-0',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
// remove custom CSS, as it is no longer needed // remove custom CSS, as it is no longer needed
for (const site in userOptions.sites) { for (const site in userOptions.sites) {
@ -185,6 +186,13 @@ const ExtensionConfPatch = [
}, },
userOptions.newFeatureTracker['uw6.ui-popup'] = {show: 10}; userOptions.newFeatureTracker['uw6.ui-popup'] = {show: 10};
} }
}, {
forVersion: '6.1.9',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
userOptions.ui = defaultOptions.ui;
userOptions.arDetect = defaultOptions.arDetect;
userOptions.newFeatureTracker = defaultOptions.newFeatureTracker;
}
} }
]; ];

View File

@ -110,7 +110,6 @@ export default class EventBus {
* @param config * @param config
*/ */
sendToTunnel(command: string, config: any) { sendToTunnel(command: string, config: any) {
console.log('sending to tunnel from eventBus ....', this)
if (!this.disableTunnel) { if (!this.disableTunnel) {
window.parent.postMessage( window.parent.postMessage(
{ {

View File

@ -183,26 +183,31 @@ class Settings {
} }
// apply all remaining patches // apply all remaining patches
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${patches.length - index} settings patches to apply`); try {
while (index < patches.length) { this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${patches.length - index} settings patches to apply`);
const updateFn = patches[index].updateFn; while (index < patches.length) {
delete patches[index].forVersion; const updateFn = patches[index].updateFn;
delete patches[index].updateFn; delete patches[index].forVersion;
delete patches[index].updateFn;
if (Object.keys(patches[index]).length > 0) {
ObjectCopy.overwrite(this.active, patches[index]);
}
if (updateFn) {
try {
updateFn(this.active, this.getDefaultSettings());
} catch (e) {
this.logger?.log('error', 'settings', '[Settings::applySettingsPatches] Failed to execute update function. Keeping settings object as-is. Error:', e);
if (Object.keys(patches[index]).length > 0) {
ObjectCopy.overwrite(this.active, patches[index]);
} }
} if (updateFn) {
index++; try {
updateFn(this.active, this.getDefaultSettings());
} catch (e) {
this.logger?.log('error', 'settings', '[Settings::applySettingsPatches] Failed to execute update function. Keeping settings object as-is. Error:', e);
}
}
index++;
}
} catch (e) {
this.setActive(this.getDefaultSettings());
this.save();
} }
} }

View File

@ -1801,7 +1801,6 @@ export class Aard {
} }
this.testResults.aspectRatioUncertain = false; this.testResults.aspectRatioUncertain = false;
console.log('Updating letterboxWidth - as normal')
this.testResults.letterboxWidth = candidateAvg; this.testResults.letterboxWidth = candidateAvg;
this.testResults.letterboxOffset = diff; this.testResults.letterboxOffset = diff;

View File

@ -89,6 +89,7 @@ class PlayerData {
private observer: ResizeObserver; private observer: ResizeObserver;
private trackChangesTimeout: any; private trackChangesTimeout: any;
private markedElement: HTMLElement;
private ui: UI; private ui: UI;
@ -741,8 +742,37 @@ class PlayerData {
} }
private markElement(data: {parentIndex: number, enable: boolean}) { private markElement(data: {parentIndex: number, enable: boolean}) {
this.elementStack[data.parentIndex].element.style.outline = data.enable ? '5px dashed #fa6' : null; if (data.enable === false) {
this.elementStack[data.parentIndex].element.style.filter = data.enable ? 'sepia(1) brightness(2) contrast(0.5)' : null; this.markedElement.remove();
return;
}
if (this.markedElement) {
this.markedElement.remove();
}
const elementBB = this.elementStack[data.parentIndex].element.getBoundingClientRect();
// console.log('element bounding box:', elementBB);
const div = document.createElement('div');
div.style.position = 'fixed';
div.style.top = `${elementBB.top}px`;
div.style.left = `${elementBB.left}px`;
div.style.width = `${elementBB.width}px`;
div.style.height = `${elementBB.height}px`;
div.style.zIndex = '100';
div.style.border = '5px dashed #fa6';
div.style.pointerEvents = 'none';
div.style.boxSizing = 'border-box';
div.style.backgroundColor = 'rgba(255, 128, 64, 0.25)';
document.body.insertBefore(div, document.body.firstChild);
this.markedElement = div;
// this.elementStack[data.parentIndex].element.style.outline = data.enable ? '5px dashed #fa6' : null;
// this.elementStack[data.parentIndex].element.style.filter = data.enable ? 'sepia(1) brightness(2) contrast(0.5)' : null;
} }
forceRefreshPlayerElement() { forceRefreshPlayerElement() {

View File

@ -50,7 +50,7 @@ class Resizer {
//#endregion //#endregion
//#region HTML elements //#region HTML elements
video: any; video: HTMLVideoElement;
//#endregion //#endregion
//#region data //#region data
@ -692,6 +692,7 @@ class Resizer {
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment); this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment);
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions(); const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
const computedStyles = getComputedStyle(this.video);
// correct any remaining element size discrepancies (applicable only to certain crop strategies!) // correct any remaining element size discrepancies (applicable only to certain crop strategies!)
// NOTE: it's possible that we might also need to apply a similar measure for CropPillarbox strategy // NOTE: it's possible that we might also need to apply a similar measure for CropPillarbox strategy
@ -715,8 +716,8 @@ class Resizer {
// we only need to compensate if alignment is set to anything other than center center // we only need to compensate if alignment is set to anything other than center center
// compensation is equal to half the difference between (zoomed) video size and player size. // compensation is equal to half the difference between (zoomed) video size and player size.
const translate = { const translate = {
x: 0, x: -Math.round(+ (computedStyles.left.replace('px', ''))),
y: 0, y: -Math.round(+ (computedStyles.top.replace('px', '')))
}; };
// NOTE: manual panning is probably broken now. // NOTE: manual panning is probably broken now.
@ -887,17 +888,6 @@ class Resizer {
// add remaining elements // add remaining elements
if (stretchFactors) { if (stretchFactors) {
styleArray.push(`transform: translate(${Math.round(translate.x)}px, ${Math.round(translate.y)}px) scale(${stretchFactors.xFactor}, ${stretchFactors.yFactor}) !important;`); styleArray.push(`transform: translate(${Math.round(translate.x)}px, ${Math.round(translate.y)}px) scale(${stretchFactors.xFactor}, ${stretchFactors.yFactor}) !important;`);
// important — guarantees video will be properly aligned
// Note that position:absolute cannot be put here, otherwise old.reddit /w RES breaks — videos embedded
// from certain hosts will get a height: 0px. This is bad.
// styleArray.push("top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px;");
// important — some websites (cough reddit redesign cough) may impose some dumb max-width and max-height
// restrictions. If site has dumb shit like 'max-width: 100%' and 'max-height: 100vh' in their CSS, that
// shit will prevent us from applying desired crop. This means we need to tell websites to fuck off with
// that crap. We know better.
// styleArray.push("max-width: none !important; max-height: none !important;");
} }
const styleString = `${this.buildStyleString(styleArray)}${extraStyleString || ''}`; // string returned by buildStyleString() should end with ; anyway const styleString = `${this.buildStyleString(styleArray)}${extraStyleString || ''}`; // string returned by buildStyleString() should end with ; anyway

View File

@ -2,7 +2,7 @@
"manifest_version": 3, "manifest_version": 3,
"name": "Ultrawidify", "name": "Ultrawidify",
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.", "description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
"version": "6.0.2", "version": "6.2.0",
"icons": { "icons": {
"32":"res/icons/uw-32.png", "32":"res/icons/uw-32.png",
"64":"res/icons/uw-64.png" "64":"res/icons/uw-64.png"

View File

@ -63,7 +63,7 @@ Browser-related stuff (please ensure this section is correct):
` `
); );
this.mailtoLink = `mailto:tamius.han@gmail.com?subject=%5BUltrawidify%5D%20ENTER%20SUMMARY%20OF%20YOUR%20ISSUE%20HERE&body=${messageTemplate}`; this.mailtoLink = `mailto:tamius.han@gmail.com?subject=%5BUltrawidify%5D%20ENTER%20SUMMARY%20OF%20YOUR%20ISSUE%20HERE&body=${messageTemplate}`;
this.redditLink = `https://www.reddit.com/message/compose?to=xternal7&subject=[Ultrawidify]%20ENTER%20SUMMARY%20OF%20YOUR%20PROBLEM%20HERE&message=${messageTemplate}`; // this.redditLink = `https://www.reddit.com/message/compose?to=xternal7&subject=[Ultrawidify]%20ENTER%20SUMMARY%20OF%20YOUR%20PROBLEM%20HERE&message=${messageTemplate}`;
} }
} }
</script> </script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB