Releases: Sv443/BetterYTM
[PREVIEW] 3.1.0 - Release Candidate 1
Important
This version is almost finished but may still contain a few bugs and inconsistencies.
It is highly recommended you fully remove the script and reinstall it once the update is released, as data integrity can't be guaranteed for preview versions.
Click to expand the changelog at the time of 0de089e
- New features:
- Add hotkeys to focus and clear the search bar on both pages (closes #145)
- Improve config menu
- Add a sidenav to toggle off all but one feature category (closes #140)
- Add feature groups with headers to logically group features together
- Add generic markdown sections to render the changelog and an about section
- Remove advanced mode flag from a lot of features since there's much more space now
- 🎵 Show the track number in playlists (by @indierodo) (closes #117)
- 🎵 Use an exponential scale for the volume slider (by @cryeprecision) (closes #157)
- Require double-pressing the number keys within a configurable time frame to skip to the associated timestamp (closes #152)
- 🎵 Automatically close the activity check dialog
- 🎵 Swap like and dislike buttons to match YT's layout
- 🎵 In fullscreen, also hide the player bar on idle
- Changes and improvements:
- 🎵 Overhaul thumbnail overlay to fix massive inconsistencies (closes #143)
- Fix album artwork being fetched with wrong parameters (closes #149)
- Allow manually toggling between thumbnail providers
- Cache resolved AM album artwork URLs similar to how lyrics URLs are currently cached
- 🎵 Decouple volume slider step and scroll step (closes #102)
- 🎵 Make the "improve links" feature also apply to all types of song list items
- Change some default feature values (if left unchanged):
initTimeout: from8to5seconds (because of the now faster init time)rememberSongTimeDuration: from60to180sec- 🎵
thumbnailOverlayITunesImgRes: from1500to2000px frameSkipAmount: from0.0417to0.0166seconds (tbr idk how this happened)
- Migrate to CoreUtils v3.0.0
DataStores - Overhaul contributing.md (part 1)
- Overhaul translations
- Add typedoc documentation for
interface.tsand common dependencies
- 🎵 Overhaul thumbnail overlay to fix massive inconsistencies (closes #143)
- Fixes:
- Fix share tracking parameter not being removed on YT
- Fix inconsistent auto-like button rendering (closes #120)
- Fix DataStores going out of sync across sessions (closes #162)
- Fix auto-like feature not resolving channel names properly (closes #156)
- 🎵 Fix SyntaxError when no AM album artwork found (closes #146)
- Fix Error when clicking on a BytmDialog's exit button (closes #147)
- Fix config menu not closing on Esc press when other dialog over top was closed with Esc
- 🎵 Fix list buttons not disappearing with the native buttons in song lists (closes #86)
- 🎵 Fix anchor improvements feature on the search page (closes #99)
- 🎵 Fix rounded border in fullscreen mode when using the ThemeSong extension
- Fix page scroll bar reappearing after BytmDialog opened over top of the config menu is closed
- Fix inline SVG logo not being swapped in when
watermarkEnabledis off (closes #161) - Fix number input constraints not being respected (closes #56)
Click to expand plugin and internal changes
(I did my best to order these by relevance for each section)- Plugin Changes:
(also refer to version 3.1.0's API docs)- Migration guide:
⚠️ The plugin sublicense agreement was updated to version 2 to clarify points which were worded poorly. Read the latest version here.⚠️ POT. BREAKING: Since BYTM now requires plugin intents to be set, make sure to add all intents required by the authenticated functions your plugin calls to thePluginDefobject'sintentsproperty (which can now also be an array instead of just a bitwise-or'ed number). Read below for a list of functions and their required intents.- If you use the
BytmDialog,ExImDialogorMarkdownDialogclasses directly, switch to the new authenticated functionsgetBytmDialog(),getExImDialog()andgetMarkdownDialog(). Direct access will continue to work until version 4.0.0, but to future-proof your plugin, switch to the new functions as soon as possible, and make sure to add theCreateModalDialogs(32) intent to your plugin definition'sintentsproperty. - If you were using
bytm:readyto reliably wait until all features are initialized, switch tobytm:allReadyinstead.
Thebytm:readyevent is still emitted, but it is now only guaranteed to be emitted when the DOM is loaded and all features have started to initialize. - All
NanoEmittersubclasses and the interface-exposedNanoEmitterclass reference now use CoreUtils' newNanoEmitterclass, which grants you access to the powerfulonMulti()method to listen to multiple events at once, with configurable behavior. - The
intentsprop can now be an array ofPluginIntentenum members.
- API Changes:
⚠️ POT. BREAKING: Plugins will no longer be able to call authenticated functions without the required intents.
Intents are now required to be set in the plugin definition object, though for now they will still all be granted and don't need to be explicitly allowed by the user once after installing yet.
The new intentFullAccess(512) grants all other intents, though you should only use it if your plugin truly requires all intents.
These are the intents that are now required for the respective functions:getFeatures()-ReadFeatureConfig(1) and optionallySeeHiddenConfigValues(4)saveFeatures()-WriteFeatureConfig(2)setLocale()-WriteTranslations(16)getBytmDialog()-CreateModalDialogs(32)getExImDialog()-CreateModalDialogs(32)getMarkdownDialog()-CreateModalDialogs(32)getAutoLikeData()-ReadAutoLikeData(64)saveAutoLikeData()-WriteAutoLikeData(128)getInternals()-InternalAccess(256)
- The dialog classes
BytmDialog,ExImDialogandMarkdownDialogshould now be gotten using the new authenticatedgetBytmDialog(),getExImDialog()andgetMarkdownDialog()functions, respectively.
Using the direct access will work until version 4.0.0, but it is recommended you switch to the new functions as soon as possible. - The
PluginDefobject'sintentsproperty can now be either an array ofPluginIntentvalues or a single number that is the bitwise OR of the intents. - Added a new broadcast system based on the BroadcastChannel API (name:
bytm-broadcast), used for inter-tab communication. Events are relayed via the site eventbytm:siteEvent:broadcast- seesrc/utils/broadcast.tsfor a list of events. - Auth tokens are now in the format of a UUIDv4 instead of a 16-character, 36-radix string.
registerPlugin()now also returns apermissionsobject with theintandarrayproperties, which contain all of the bitwise OR of the plugin's intents and an array of the intents that were actually granted to the plugin. Theintproperty can be used with CoreUtils'bitSetHas()function to check if specific intents were granted.- A URL to the plugin's changelog file can now be specified in the
PluginDefobject'shomepage.changelogproperty.
- API Additions:
- Added new intents
InternalAccess(256) (currently only used bygetInternals()) andFullAccess(512) (grants all intents). - Added new functions to the interface that allow for better interaction with the siteEvents system:
resourceAsString()- Returns a BYTM resource as a string, some of which are cached cross-session in GM storage for better performance.onSiteEvent()- Adds a site event listener.onceSiteEvent()- Adds a site event listener that is only called once and also returns a Promise for use with the async/await pattern.onMultiSiteEvents()- Adds a listener that triggers after one of, or all of the given site events are dispatched, either continuously or just once, with configurable behavior.- 🔒
getBytmDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theBytmDialogclass, which can be used to create new generic dialog instances. - 🔒
getExImDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theExImDialogclass, to export and import serializable data. - 🔒
getMarkdownDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theMarkdownDialogclass, to render a markdown string in a modal dialog. - 🔒
getInternals()(requires intentInternalAccess(256)) - returns some internal function and object references that can be used by core libraries and deeper reaching plugins.
- Added new events:
bytm:preInitPlugin(no arguments) - emitted at the earliest possible point i...
- Added new intents
- Migration guide:
[PREVIEW] 3.1.0 - Prerelease 4
Important
This is an experimental version!
Features might still be unstable or unfinished, so please check back later for the finished release.
Since data integrity isn't ensured in experimental versions, I highly recommend you fully remove the script and reinstall it manually before installing the full release when it's out.
To keep your data, use the config and auto-liked channels menu's export and import functions to create a backup before installing the preview version.
After installing the full release and importing your old data, it will automatically be corrected to the latest format.
Click to expand the changelog at the time of 1681618
- New features:
- Add hotkeys to focus and clear the search bar on both pages (#145)
- Improve config menu
- Add a sidenav to toggle off all but one feature category (#140)
- Add feature groups with headers to logically group features together
- Add generic markdown sections to render the changelog and an about section
- Remove advanced mode flag from a lot of features since there's much more space now
- 🎵 Show the track number in playlists (by @indierodo) (#117)
- 🎵 Use an exponential scale for the volume slider (by @cryeprecision) (#157)
- Require double-pressing the number keys within a configurable time frame to skip to the associated timestamp (#152)
- 🎵 Automatically close the activity check dialog
- 🎵 Swap like and dislike buttons to match YT's layout
- 🎵 In fullscreen, also hide the player bar on idle
- Changes and improvements:
- 🎵 Overhaul thumbnail overlay to fix massive inconsistencies (#143)
- Fix album artwork being fetched with wrong parameters (#149)
- Allow manually toggling between thumbnail providers
- Cache resolved AM album artwork URLs similar to how lyrics URLs are currently cached
- 🎵 Decouple volume slider step and scroll step (#102)
- 🎵 Make the "improve links" feature also apply to all types of song list items
- Change some default feature values (if left unchanged):
initTimeout: from8to5seconds (because of the now faster init time)rememberSongTimeDuration: from60to180sec- 🎵
thumbnailOverlayITunesImgRes: from1500to2000px frameSkipAmount: from0.0417to0.0166seconds (tbr idk how this happened)
- Migrate to CoreUtils v3.0.0
DataStores - Overhaul contributing.md (part 1)
- Overhaul translations
- Add typedoc documentation for
interface.tsand common dependencies
- 🎵 Overhaul thumbnail overlay to fix massive inconsistencies (#143)
- Fixes:
- Fix inconsistent auto-like button rendering (#120)
- Fix DataStores going out of sync across sessions (#162)
- Fix auto-like feature not resolving channel names properly (#156)
- 🎵 Fix SyntaxError when no AM album artwork found (#146)
- Fix Error when clicking on a BytmDialog's exit button (#147)
- Fix config menu not closing on Esc press when other dialog over top was closed with Esc
- 🎵 Fix list buttons not disappearing with the native buttons in song lists (#86)
- 🎵 Fix anchor improvements feature on the search page (#99)
- 🎵 Fix rounded border in fullscreen mode when using the ThemeSong extension
- Fix page scroll bar reappearing after BytmDialog opened over top of the config menu is closed
- Fix inline SVG logo not being swapped in when
watermarkEnabledis off (#161)
Click to expand plugin and internal changes
(I did my best to order these by relevance for each section)- Plugin Changes:
(also refer to version 3.1.0's API docs)- Migration guide:
⚠️ The plugin sublicense agreement was updated to version 2 to clarify points which were worded poorly. Read the latest version here.⚠️ POT. BREAKING: Since BYTM now requires plugin intents to be set, make sure to add all intents required by the authenticated functions your plugin calls to thePluginDefobject'sintentsproperty (which can now also be an array instead of just a bitwise-or'ed number). Read below for a list of functions and their required intents.- If you use the
BytmDialog,ExImDialogorMarkdownDialogclasses directly, switch to the new authenticated functionsgetBytmDialog(),getExImDialog()andgetMarkdownDialog(). Direct access will continue to work until version 4.0.0, but to future-proof your plugin, switch to the new functions as soon as possible, and make sure to add theCreateModalDialogs(32) intent to your plugin definition'sintentsproperty. - If you were using
bytm:readyto reliably wait until all features are initialized, switch tobytm:allReadyinstead.
Thebytm:readyevent is still emitted, but it is now only guaranteed to be emitted when the DOM is loaded and all features have started to initialize. - All
NanoEmittersubclasses and the interface-exposedNanoEmitterclass reference now use CoreUtils' newNanoEmitterclass, which grants you access to the powerfulonMulti()method to listen to multiple events at once, with configurable behavior. - The
intentsprop can now be an array ofPluginIntentenum members.
- API Changes:
⚠️ POT. BREAKING: Plugins will no longer be able to call authenticated functions without the required intents.
Intents are now required to be set in the plugin definition object, though for now they will still all be granted and don't need to be explicitly allowed by the user once after installing yet.
The new intentFullAccess(512) grants all other intents, though you should only use it if your plugin truly requires all intents.
These are the intents that are now required for the respective functions:getFeatures()-ReadFeatureConfig(1) and optionallySeeHiddenConfigValues(4)saveFeatures()-WriteFeatureConfig(2)setLocale()-WriteTranslations(16)getBytmDialog()-CreateModalDialogs(32)getExImDialog()-CreateModalDialogs(32)getMarkdownDialog()-CreateModalDialogs(32)getAutoLikeData()-ReadAutoLikeData(64)saveAutoLikeData()-WriteAutoLikeData(128)getInternals()-InternalAccess(256)
- The dialog classes
BytmDialog,ExImDialogandMarkdownDialogshould now be gotten using the new authenticatedgetBytmDialog(),getExImDialog()andgetMarkdownDialog()functions, respectively.
Using the direct access will work until version 4.0.0, but it is recommended you switch to the new functions as soon as possible. - The
PluginDefobject'sintentsproperty can now be either an array ofPluginIntentvalues or a single number that is the bitwise OR of the intents. - Added a new broadcast system using GM.addValueChangeListener for inter-tab communication. Events are relayed via the site event
bytm:siteEvent:broadcast- seesrc/utils/broadcast.tsfor a list of events. - Auth tokens are now in the format of a UUIDv4 instead of a 16-character, 36-radix string.
registerPlugin()now also returns apermissionsobject with theintandarrayproperties, which contain all of the bitwise OR of the plugin's intents and an array of the intents that were actually granted to the plugin. Theintproperty can be used with CoreUtils'bitSetHas()function to check if specific intents were granted.- A URL to the plugin's changelog file can now be specified in the
PluginDefobject'shomepage.changelogproperty.
- API Additions:
- Added new intents
InternalAccess(256) (currently only used bygetInternals()) andFullAccess(512) (grants all intents). - Added new functions to the interface that allow for better interaction with the siteEvents system:
resourceAsString()- Returns a BYTM resource as a string, some of which are cached cross-session in GM storage for better performance.onSiteEvent()- Adds a site event listener.onceSiteEvent()- Adds a site event listener that is only called once and also returns a Promise for use with the async/await pattern.onMultiSiteEvents()- Adds a listener that triggers after one of, or all of the given site events are dispatched, either continuously or just once, with configurable behavior.- 🔒
getBytmDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theBytmDialogclass, which can be used to create new generic dialog instances. - 🔒
getExImDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theExImDialogclass, to export and import serializable data. - 🔒
getMarkdownDialog()...
- Added new intents
- Migration guide:
[PREVIEW] 3.1.0 - Prerelease 3
Important
This is an experimental version!
Features might still be unstable or unfinished, so please check back later for the finished release.
Since data integrity isn't ensured in experimental versions, I highly recommend you fully remove the script and reinstall it manually before installing the full release when it's out.
To keep your data, use the config and auto-liked channels menu's export and import functions to create a backup before installing the preview version.
After installing the full release and importing your old data, it will automatically be updated to the correct format.
Click to expand the changelog at the time of d1ab7b1
- New features:
- Add hotkeys to focus and clear the search bar on both pages (#145)
- Improve config menu
- Add a sidenav to toggle off all but one feature category (#140)
- Add feature groups with headers to logically group features together
- Add generic markdown sections to render the changelog and an about section
- Remove advanced mode flag from a lot of features since there's much more space now
- 🎵 Show the track number in playlists (by @indierodo) (#117)
- 🎵 Use an exponential scale for the volume slider (by @cryeprecision) (#157)
- Require double-pressing the number keys within a configurable time frame to skip to the associated timestamp (#152)
- 🎵 Automatically close the activity check dialog
- 🎵 Swap like and dislike buttons to match YT's layout
- 🎵 In fullscreen, also hide the player bar on idle
- Changes and improvements:
- 🎵 Overhaul thumbnail overlay to fix massive inconsistencies (#143)
- Fix album artwork being fetched with wrong parameters (#149)
- Allow manually toggling between thumbnail providers
- Cache resolved AM album artwork URLs similar to how lyrics URLs are currently cached
- 🎵 Decouple volume slider step and scroll step (#102)
- 🎵 Make the "improve links" feature also apply to all types of song list items
- Change some default feature values (if left unchanged):
initTimeout: from8to5seconds (because of the now faster init time)rememberSongTimeDuration: from60to180sec- 🎵
thumbnailOverlayITunesImgRes: from1500to2000px frameSkipAmount: from0.0417to0.0166seconds (tbr idk how this happened)
- Migrate to CoreUtils v3.0.0
DataStores - Overhaul contributing.md (part 1)
- Add typedoc documentation for
interface.tsand common dependencies
- 🎵 Overhaul thumbnail overlay to fix massive inconsistencies (#143)
- Fixes:
- Fix inconsistent auto-like button rendering (#120)
- Fix DataStores going out of sync across sessions (#162)
- Fix auto-like feature not resolving channel names properly (#156)
- 🎵 Fix SyntaxError when no AM album artwork found (#146)
- Fix Error when clicking on a BytmDialog's exit button (#147)
- Fix config menu not closing on Esc press when other dialog over top was closed with Esc
- 🎵 Fix list buttons not disappearing with the native buttons in song lists (#86)
- 🎵 Fix anchor improvements feature on the search page (#99)
- 🎵 Fix rounded border in fullscreen mode when using the ThemeSong extension
- Fix page scroll bar reappearing after BytmDialog opened over top of the config menu is closed
Click to expand plugin and internal changes
(I did my best to order these by relevance for each section)- Plugin Changes:
(also refer to version 3.1.0's API docs)- Migration guide:
⚠️ The plugin sublicense agreement was updated to version 2 to clarify points which were worded poorly. Read the latest version here.⚠️ POT. BREAKING: Since BYTM now requires plugin intents to be set, make sure to add all intents required by the authenticated functions your plugin calls to thePluginDefobject'sintentsproperty (which can now also be an array instead of just a bitwise-or'ed number). Read below for a list of functions and their required intents.- If you use the
BytmDialog,ExImDialogorMarkdownDialogclasses directly, switch to the new authenticated functionsgetBytmDialog(),getExImDialog()andgetMarkdownDialog(). Direct access will continue to work until version 4.0.0, but to future-proof your plugin, switch to the new functions as soon as possible, and make sure to add theCreateModalDialogs(32) intent to your plugin definition'sintentsproperty. - If you were using
bytm:readyto reliably wait until all features are initialized, switch tobytm:allReadyinstead.
Thebytm:readyevent is still emitted, but it is now only guaranteed to be emitted when the DOM is loaded and all features have started to initialize. - All
NanoEmittersubclasses and the interface-exposedNanoEmitterclass reference now use CoreUtils' newNanoEmitterclass, which grants you access to the powerfulonMulti()method to listen to multiple events at once, with configurable behavior. - The
intentsprop can now be an array ofPluginIntentenum members.
- API Changes:
⚠️ POT. BREAKING: Plugins will no longer be able to call authenticated functions without the required intents.
Intents are now required to be set in the plugin definition object, though for now they will still all be granted and don't need to be explicitly allowed by the user once after installing yet.
The new intentFullAccess(512) grants all other intents, though you should only use it if your plugin truly requires all intents.
These are the intents that are now required for the respective functions:getFeatures()-ReadFeatureConfig(1) and optionallySeeHiddenConfigValues(4)saveFeatures()-WriteFeatureConfig(2)setLocale()-WriteTranslations(16)getBytmDialog()-CreateModalDialogs(32)getExImDialog()-CreateModalDialogs(32)getMarkdownDialog()-CreateModalDialogs(32)getAutoLikeData()-ReadAutoLikeData(64)saveAutoLikeData()-WriteAutoLikeData(128)getInternals()-InternalAccess(256)
- The dialog classes
BytmDialog,ExImDialogandMarkdownDialogshould now be gotten using the new authenticatedgetBytmDialog(),getExImDialog()andgetMarkdownDialog()functions, respectively.
Using the direct access will work until version 4.0.0, but it is recommended you switch to the new functions as soon as possible. - The
PluginDefobject'sintentsproperty can now be either an array ofPluginIntentvalues or a single number that is the bitwise OR of the intents. - Added a new broadcast system based on the BroadcastChannel API (name:
bytm-broadcast), used for inter-tab communication. Events are relayed via the site eventbytm:siteEvent:broadcast- seesrc/utils/broadcast.tsfor a list of events. - Auth tokens are now in the format of a UUIDv4 instead of a 16-character, 36-radix string.
registerPlugin()now also returns apermissionsobject with theintandarrayproperties, which contain all of the bitwise OR of the plugin's intents and an array of the intents that were actually granted to the plugin. Theintproperty can be used with CoreUtils'bitSetHas()function to check if specific intents were granted.- A URL to the plugin's changelog file can now be specified in the
PluginDefobject'shomepage.changelogproperty.
- API Additions:
- Added new intents
InternalAccess(256) (currently only used bygetInternals()) andFullAccess(512) (grants all intents). - Added new functions to the interface that allow for better interaction with the siteEvents system:
resourceAsString()- Returns a BYTM resource as a string, some of which are cached cross-session in GM storage for better performance.onSiteEvent()- Adds a site event listener.onceSiteEvent()- Adds a site event listener that is only called once and also returns a Promise for use with the async/await pattern.onMultiSiteEvents()- Adds a listener that triggers after one of, or all of the given site events are dispatched, either continuously or just once, with configurable behavior.- 🔒
getBytmDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theBytmDialogclass, which can be used to create new generic dialog instances. - 🔒
getExImDialog()(requires intentCreateModalDialogs(32)) - Returns...
- Added new intents
- Migration guide:
[PREVIEW] 3.1.0 - Prerelease 2
Important
This is an experimental version!
Features might still be unstable or unfinished, so please check back later for the finished release.
Since data integrity isn't ensured in experimental versions, I highly recommend you fully remove the script and reinstall it manually before installing the full release when it's out.
To keep your data, use the config and auto-liked channels menu's export and import functions to create a backup before installing the preview version.
After installing the full release and importing your old data, it will automatically be updated to the correct format.
Click to expand the changelog at the time of 4501b5f
- New Features:
- Improved config menu UX:
- Added a sidenav that displays one group at a time, for a much less overwhelming experience.
- Added feature groups, which further divide each group's features into logical sections.
- Removed advanced mode flag from a lot of features since there's much more breathing room now.
- Removed the dialog title subtexts. Instead, icons will be rendered in the footer, below the sidenav.
- Reordered categories and features to be grouped more logically.
- New configurable hotkeys:
- Focus on the search bar (ShiftF).
- Clear the search bar (ShiftDelete).
- 🎵 Show a track number in the currently playing queue and playlists.
- 🎵 Swap like- and dislike buttons to match the layout on YT.
- Require double-pressing the number keys within a configurable time frame to skip to a specific point in the song.
- 🎵 Automatically close the activity check dialog. Note: Might only work if the browser isn't minimized.
- Improved config menu UX:
- Improvements and Changes:
- Improved script initialization performance.
- 🎵 Overhauled thumbnail overlay to fix inconsistencies.
- Fixed album artwork being fetched with wrong parameters.
- Allow manually toggling between thumbnail providers.
- Cache resolved AM album artwork URLs similar to how lyrics URLs are currently cached.
- 🎵 Decoupled volume slider step and scroll step, allowing for both to work and be configured independently.
- 🎵 The "improve links" feature now also applies to all types of song list items.
Clicking a list item anywhere will now start playing that song. This doesn't affect clicking and dragging them. - The values of some features (if left unchanged), will be updated to the new defaults:
initTimeoutwill be changed from8to5seconds amid initialization performance improvements.rememberSongTimeDurationwill be changed from60to180seconds.thumbnailOverlayITunesImgReswill be changed from1500to2000pixels.
- Made some menu commands usable by default without requiring to be compiled in dev mode, and there's even more when the advanced mode is enabled. See internal changes for a full list.
- Increased the amount of times per second the video/song time is remembered from 2 to 4.
- Fixes:
- Fixed inconsistent auto-like button rendering and channel name resolution on both pages.
- 🎵 Fixed SyntaxError when no AM album artwork found.
- Fixed Error when clicking on a BytmDialog's exit button.
- Fixed interactivity problems with config menu and stacked BytmDialogs when other dialog was opened over top and then closed.
- 🎵 Fixed list buttons not disappearing with the native buttons in song lists.
- 🎵 Fixed anchor improvements feature on the search page.
- 🎵 Fixed rounded border in fullscreen mode when using the ThemeSong extension.
- Fixed changelog URL pointing to the script's build commit version instead of the latest version (this is like the 5th time I fixed this).
- Fixed hotkey inputs not deactivating when the config menu is closed.
Click to expand plugin and internal changes
(I did my best to order these by importance, but it's still a lot, sorry about that.)- Plugin Changes:
(also refer to version 3.1.0's API docs)- Migration guide:
⚠️ POT. BREAKING: Since BYTM now requires plugin intents to be set, make sure to add all intents required by the authenticated functions your plugin calls to thePluginDefobject'sintentsproperty (which can now also be an array instead of just a bitwise-or'ed number). Read below for a list of functions and their required intents.- If you use the
BytmDialog,ExImDialogorMarkdownDialogclasses directly, switch to the new authenticated functionsgetBytmDialog(),getExImDialog()andgetMarkdownDialog(). Direct access will continue to work until version 4.0.0, but to future-proof your plugin, switch to the new functions as soon as possible, and make sure to add theCreateModalDialogs(32) intent to your plugin definition'sintentsproperty. - If you were using
bytm:readyto reliably wait until all features are initialized, switch tobytm:allReadyinstead.
Thebytm:readyevent is still emitted, but it is now only guaranteed to be emitted when the DOM is loaded and all features have started to initialize. - All
NanoEmittersubclasses and the interface-exposedNanoEmitterclass reference now use CoreUtils' newNanoEmitterclass, which grants you access to the powerfulonMulti()method to listen to multiple events at once, with configurable behavior. - The
intentsprop can now be an array ofPluginIntentenum members.
- API Changes:
⚠️ POT. BREAKING: Plugins will no longer be able to call authenticated functions without the required intents.
Intents are now required to be set in the plugin definition object, though for now they will still all be granted and don't need to be explicitly allowed by the user once after installing yet.
The new intentFullAccess(512) grants all other intents, though you should only use it if your plugin truly requires all intents.
These are the intents that are now required for the respective functions:getFeatures()-ReadFeatureConfig(1) and optionallySeeHiddenConfigValues(4)saveFeatures()-WriteFeatureConfig(2)setLocale()-WriteTranslations(16)getBytmDialog()-CreateModalDialogs(32)getExImDialog()-CreateModalDialogs(32)getMarkdownDialog()-CreateModalDialogs(32)getAutoLikeData()-ReadAutoLikeData(64)saveAutoLikeData()-WriteAutoLikeData(128)getInternals()-InternalAccess(256)
- The dialog classes
BytmDialog,ExImDialogandMarkdownDialogshould now be gotten using the new authenticatedgetBytmDialog(),getExImDialog()andgetMarkdownDialog()functions, respectively.
Using the direct access will work until version 4.0.0, but it is recommended you switch to the new functions as soon as possible. - The
PluginDefobject'sintentsproperty can now be either an array ofPluginIntentvalues or a single number that is the bitwise OR of the intents. - Auth tokens are now in the format of a UUIDv4 instead of a 16-character, 36-radix string.
registerPlugin()now also returns apermissionsobject with theintandarrayproperties, which contain all of the bitwise OR of the plugin's intents and an array of the intents that were actually granted to the plugin. Theintproperty can be used with CoreUtils'bitSetHas()function to check if specific intents were granted.
- API Additions:
- Added new intents
InternalAccess(256) (currently only used bygetInternals()) andFullAccess(512) (grants all intents). - Added new functions to the interface that allow for better interaction with the siteEvents system:
resourceAsString()- Returns a BYTM resource as a string, some of which are cached cross-session in GM storage for better performance.onSiteEvent()- Adds a site event listener.onceSiteEvent()- Adds a site event listener that is only called once and also returns a Promise for use with the async/await pattern.onMultiSiteEvents()- Adds a listener that triggers after one of, or all of the given site events are dispatched, either continuously or just once, with configurable behavior.- 🔒
getBytmDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theBytmDialogclass, which can be used to create new generic dialog instances. - 🔒
getExImDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theExImDialogclass, to export and import serializable data. - 🔒
getMarkdownDialog()(requires intentCreateModalDialogs(32)) - Returns a reference to theMarkdownDialogclass, to render a markdown string in a modal dialog. - 🔒
getInternals()(requires intentInternalAccess(256)) - returns some internal function and object references that can be used by core libraries and deeper reaching plugins.
- Added new events:
bytm:preInitPlugin(no arguments) - emitted at the earlie...
- Added new intents
- Migration guide:
[PREVIEW] 3.1.0 - Prerelease 1
Important
This is an experimental version!
Features might still be unstable or unfinished, so please check back later for the finished release.
Since data integrity isn't ensured in experimental versions, I highly recommend you fully remove the script and reinstall it manually before installing the full release when it's out.
To keep your data, use the config and auto-liked channels menu's export and import functions to create a backup before installing the preview version. After updating to the full release and importing it, the data will automatically be migrated to the latest format.
Click to expand the changelog at the time of aee3859
New features:
- Improved config menu UX with a sidenav:
- Removed advanced mode flag from a lot of features since there's much more space now.
- Removed the subtitle elements. Instead, icons will be rendered in the footer, below the sidenav.
- Reordered categories and features to be grouped more logically.
- Added extra info categories to render "About" and "Changelog" sections.
- New configurable hotkeys:
- Focus on the search bar (ShiftF).
- Clear the search bar (ShiftDelete).
- 🎵 Show a track number in the currently playing queue and playlists.
Changes and Improvements:
- 🎵 [🚧 WIP] Overhauled thumbnail overlay to fix massive inconsistencies
- Fixed album artwork being fetched with wrong parameters
- Allow manually toggling between thumbnail providers
- Cache resolved AM album artwork URLs similar to how lyrics URLs are currently cached
- 🎵 Decoupled volume slider step and scroll step
Fixes:
- 🎵 Fixed SyntaxError when no AM album artwork found
- Fixed Error when clicking on a BytmDialog's exit button
- 🎵 Fixed rounded border in fullscreen mode when using the ThemeSong extension
- Fixed changelog URL pointing to the script's build commit version instead of the latest version (this is like the 5th time I fixed this)
Click to expand plugin and internal changes
- Plugin Changes:
- See contributing guide for full documentation
- Added new events:
bytm:siteEvent:cfgMenuMounted(no arguments) - emitted when the config menu is invisibly mounted to the DOM (not opened yet, but modifiable).bytm:siteEvent:configHeaderSelected: (name: LooseUnion<FeatureCategory>)- emitted when a config header is selected in the config menu, with the name of the selected header. This is usually the feature category name, but can also be an info category name (currently just"about"and"changelog").bytm:siteEvent:voteLabelsAdded(no arguments) - emitted after the Return YouTube Dislike vote labels were added to the DOM.bytm:siteEvent:updateVolumeSliderLabel(no arguments) - emitted to make the volume slider label update its text content.
- Added new functions to the interface with the siteEvents system:
onSiteEvent()- Adds a site event listener.onceSiteEvent()- Adds a site event listener that is only called once and also returns a Promise for use with the async/await pattern.onMultiSiteEvents()- Adds a listener for multiple site events at once, with configurable behavior and with a shared callback function.onceMultiSiteEvents()- Adds a listener for multiple site events at once, with configurable behavior and with a shared callback function that is only called once.
- Auth token is now in the format of a UUID instead of a 16-character, 36-radix string.
- Internal Changes:
- Added
NanoEmitterwrapper classMultiNanoEmitterthat allows listening to when one, all, or a given subset of events have been emitted before executing a callback. It shares the same methods as the baseNanoEmitter, but has the new methodsonMulti()andonceMulti()for listening to multiple events. This new class is exposed on the plugin interface next to theNanoEmitterclass. - Made
siteEventssystem use aMultiNanoEmitterinstance instead of aNanoEmitterinstance, so it can now also be used to listen to multiple events at once. - Made plugin-specific
events(returned byregisterPlugin()) use aMultiNanoEmitterinstance too. - Removed
GM.getResourceUrl()entirely in favor of fetching resources from a CDN. - Arguments to the translation functions can now also be an object that map a placeholder key to a string value, e.g.
{ name: "John" }for a translation using the new placeholder syntax, e.g."Hello, ${name}!". - Moved the
generalfeature category to the top of the config menu. - Wrapped feature config elements in a new container element with the ID
bytm-ftconf-category-${categoryName}to allow for the sidenav to disable all but one at a time. - Updated UserUtils to v9.4.3 to fix two bugs related to the template literal placeholder format. This now allows specifying a single placeholder multiple times per translation string.
- Added ability to render custom info categories in the config menu. Their navigation headers will be aligned to the bottom, and they render arbitrary elements. They use the same general formatting as the new feature category containers, just with their own
categoryName(currently just"about"and"changelog"). - Added CSS var
--bytm-menu-bg-highlight-2(hex, opacity 1) as a secondary level of highlight to--bytm-menu-bg-highlight. - Renamed CSS var
--bytm-dialog-height-maxto--bytm-dialog-target-height, but only for the config menu. All BytmDialogs will still use--bytm-dialog-height-max. - Improved number argument resolution of the functions in
src/utils/logging.ts(if the last argument is a number and exceeds the range of the enumLogLevel, it will not be interpreted as a log level anymore, but as a number to be logged).
- Added
- The music note emoji (🎵) tells you that the associated item only applies to YTM and not YT.
- The warning emoji (
⚠️ ) means there was a breaking change in the plugin API.
Release 3.0.0
- Added features:
- 🎵 Automatically scroll to the active song in the queue on page load or video change
- 🎵 Make the player container use all available space on /watch
- New configurable hotkeys:
- 🎵 Skip forwards/backwards by a frame (. / ,)
- Like/dislike video/song (ShiftL / ShiftD)
- 🎵 Open lyrics of current song (O)
- Skip to last remembered video/song time (AltR)
- Reconfigurable skip to beginning & previous/next video/song (ShiftN / ShiftP, disabled by default)
- Reconfigurable play/pause (Pause, disabled by default)
- Changes and improvements:
- Song/video volume will now be restored after BYTM reloads the tab by using the new common
reloadTab()function - Added an adornment icon to identify which features work only on YTM, versus on both sites
- 🎵 Thumbnail overlay improvements:
- Overlay now prefers to use a high res album artwork from Apple Music if the current song is in an album
- Fixed image not being updated while in fullscreen
- 🎵 Made above-queue button container's sticky positioning toggleable with a feature
- Made the resolution of the browser-preferred locale more reliable
- Implemented a more powerful translation system
- Removed the thumbnail overlay fitting option in favor of automatically switching based on the media type
- Song/video volume will now be restored after BYTM reloads the tab by using the new common
- Fixes:
- Sped up installation time by loading all resources except stylesheets via regular
fetch()and the external CDN instead of using@resourcedirectives - Bumped z-index of dialog elements to display them correctly after a recent page update
- Fixed white font color for BYTM config option on YT in light theme
- 🎵 Fixed volume label not being fully hidden along with the slider
- Config menu will now be correctly set as inert when a BytmDialog is opened over top
- 🎵 Fixed "remove from queue" button sometimes deleting playlist entries instead of queue items
- Sped up installation time by loading all resources except stylesheets via regular
Click to expand internal and plugin changes
- Plugin Changes:
- See contributing guide for full documentation
- API changes:
⚠️ BREAKING: RenamedcreateRipple()'sspeedprop values:- From
fastertofastest - From
slowertoslowest
- From
⚠️ BREAKING: MadehasKey()andhasKeyFor()return a Promise to load the given locale if it's not found⚠️ 🎵 BREAKING: RemovedsideBarMiniobserver instance- Made
getCurrentMediaType()return"video"on YT instead of throwing an error - Added property
additionalPropsto theRipplePropsargument increateRipple(), to assign extra props to the created or passed ripple element
- New API functions:
- Added
reloadTab()as a better way to reload the page by keeping the same video time and volume and disabling BYTM features like initial tab volume - Added
getVideoElement()to get the video element (if available) on the current page, on both YT and YTM - Added
getVideoSelector()to get the CSS selector for the video element on the current page, on both YT and YTM - Added
getDefaultFeatures()(callable without registering the plugin) to return the default / fallback feature configuration object - Added
getLikeDislikeBtns()to return the like and dislike buttons on both domains, including the like/dislike state - Added
isIgnoredInputElement()to check if the given or currently focused element is an input element, upon which all other keypress event listeners should be ignored - Added
fetchITunesAlbumInfo()to fetch album info objects from the Apple Music / iTunes API, given an artist and album name
- Added
- New API constants:
- Added
initialParams(URLSearchParams), the search params at the initial point of loading BYTM - Added
sessionStorageAvailable(boolean), whether the browser supports sessionStorage
- Added
- Internal Changes:
- Improved asset caching by using JSDelivr instead of GitHub as a CDN
- Fixed problems with the translation system by implementing UserUtils v9's new system
- Added JSON schemas for all JSON files in
assets
Release 2.2.0
- Changes:
- Replaced the monospace font Cascadia Code with Cousine
- Due to massive incompatibilities on FireMonkey, the script will show an error and not execute under the extension anymore
- Resources now have their integrity checked to make BYTM more resilient against XSS- and MITM-type attacks
- Fixes:
- Fixed errors in TamperMonkey because of missing
@connectdirectives - Fixed locale codes not using the correct format (
en_USinstead of the correct formaten-US) - Fixed changelog not updating on new releases and thus the update notification dialog would also show an outdated changelog
- Fixed auto-like channel toggle button disappearing after changing channel page tabs on both pages
- Fixed duplicate logo if the ThemeSong extension is installed
- Fixed tab opening with the resolved lyrics URL when ctrl-clicking the lyrics button
- Fixed errors in TamperMonkey because of missing
Click to expand internal and plugin changes
- Internal Changes:
- Breaking: Changed the locale code format to match the BCP 47 standard.
As part of this, all_underscores were replaced with-hyphens and the following locales had their country codes corrected:en-UK->en-GBja-JA->ja-JP
- Enabled Subresource Integrity (SRI) hashes for all resources in the metadata block
- Updated UserUtils library to v8.3.1
- Breaking: Changed the locale code format to match the BCP 47 standard.
- Plugin Changes:
- Migration guide:
- Since locale codes now have the format
xx-YYand two were renamed, all plugins must implement those changes
- Since locale codes now have the format
- Migration guide:
Release 2.1.0
- Added features:
- Added a feature to like songs and videos of certain channels (on both sites) automatically.
The button to toggle auto-liking will only show up on channel pages until the next update. Please report any issues you encounter. - Added the ability to show the approximate amount of likes and dislikes on the currently playing song (powered by ReturnYoutubeDislike)
- Added support for themes set by the ThemeSong extension
- Added a dialog for listing the currently installed and active plugins including some metadata
- Added a feature to like songs and videos of certain channels (on both sites) automatically.
- Changes:
- Made song/video time remembering enabled by default on YT too
- Made reset button in config menu a feature of type
button - Welcome menu is now shown on YT too
- Added Ctrl modifier key to every lyrics button to open a lyrics search prompt
- Added Shift and Ctrl modifier keys to the above-queue buttons that will skip prompts or customize their behavior in other ways
- Arrow key and number key skipping works more reliably and now also in the config menu
- Changed default settings for some features.
After updating, if the values were unchanged from their previous default, they will automatically have the new default value:- Remember Song Time Sites: if set to
YTM only, it changes toboth sites - Volume Slider Scroll Sensitivity: if set to
10%, it changes to4%
- Remember Song Time Sites: if set to
- Made some settings require advanced mode that didn't before:
- Fix spacing/layout issues
- Fix HDR issues
- Disable Dark Reader sites
- Remove share tracking parameter sites
- Placement of list/queue buttons
- Removed broken feature "remove upgrade tab"
- Removed unnecessary experimental feature "advancedLyricsFilter" as the API's native search improved a lot
- Made all integration features configurable and gave them their own config category
- Created a prompt dialog to replace the browser's native dialogs, which could accidentally be turned off by the user and would softlock the script
- Fixes:
- Fixed major bug that threw "This document requires 'TrustedHTML' assignment" errors on Chromium browsers
- Adjusted script to UI redesign of playlists
- Fixed song list buttons disappearing when dragging the row around
- Fixed song list buttons not always appearing immediately
- Fixed escape closing all open dialogs instead of one at a time
- Fixed "added to liked songs" toast not being consistently closed
- Fixed messed up time restoration feature on YT because of the
&tparam - Fixed broken autoplay queue delete button after a redesign
- Fixed transparent player bar background in fullscreen being barely readable with thumbnail overlay active
- Fixed thumbnail overlay not updating in fullscreen mode and in the mini player
- Fixed video time restoring breaking after pausing for a longer time
- Fixed toasts being shown with a 1000x higher duration than intended
- Fixed volume slider features not working anymore when display width shrinks to below 1150px
Click to expand internal and plugin changes
- Internal Changes:
- Updated the UserUtils library to v8.0.2
- Removed
compareVersions()andcompareVersionArrays()in favor of including thecompare-versionslibrary - Now using a single query parameter for lyrics lookup
- Added license for plugin-related source code, see license-for-plugins.txt
- Added advanced feature to change the startup timeout (only impacts plugin initialization for now)
- Now using a blue logo is instead of the red BetterYTM logo when the script was compiled in development (preview) mode
- Added Storybook for easier and faster development of components
- Removed the
@updateURLand@downloadURLdirectives because their use is controversial and the script has a built-in update check now - Migrated to pnpm for faster compilation times
- Moved
NanoEmitterclass over to the UserUtils library (it is still re-exported by the plugin interface as before) - Made
getThumbnailUrl()andgetBestThumbnailUrl()use the domainyoutube.comto prevent cross-origin issues - Added custom error instances
LyricsErrorandPluginErrorfor better error handling usinginstanceof - Changed the feature identifier key for
showVotesFormattonumbersFormatas it is now generic and available to plugins through theformatNumber()function - Feature config keys will now be corrected on each page load (meaning missing keys will be set to their default and extra keys will be removed)
- Plugin Changes:
See the contributing guide for the latest documentation of the plugin interface- Changed the way plugins are registered by making the
registerPlugin()function the sole argument passed by thebytm:registerPluginevent. Call this function synchronously to register your plugin. - Plugins will now load at an earlier point in BetterYTM's startup sequence. This means that plugins can now be initialized before the script's features are fully initialized and the DOM is ready. Use site events to wait for the right moment to interact with the page.
- Added new components:
createLongBtn()to create a button with an icon and text (works either as normal or as a toggle button)
The design follows that of the subscribe button on YTM's channel pages, but the consistent class names make it easy to style it differently.createRipple()to create a click ripple animation effect on a given elementshowToast()to show a custom toast notification with a message string or element and durationshowIconToast()to show a custom toast notification with a message string or element, icon and durationshowPrompt()to show a styled dialog that replaces theconfirm(),alert()andprompt()functionsExImDialogclass for creating a BytmDialog instance that is designed for exporting and importing generic data as a string
- Changed components:
- BytmDialog now has the option
removeListenersOnDestroy(true by default) to configure removing all event listeners when the dialog is destroyed - BytmDialog's private members and methods have been changed to protected for easier extension (when using TypeScript)
- BytmDialog now has the option
- Plugin definition changes:
- Some intents were added or moved around in their order. See the new values in
src/types.ts -> enum PluginIntent
- Some intents were added or moved around in their order. See the new values in
- Added interface functions:
setInnerHtml()to set the innerHTML property of an element to a sanitized string using the Trusted Types API and the library DOMPurifygetAutoLikeData()to return the current auto-like data (authenticated function)saveAutoLikeData()to overwrite the auto-like data (authenticated function)fetchVideoVotes()to fetch the approximate like and dislike count of a video from Return Youtube DislikegetDomain()returns the current domain ("yt" or "ytm")waitVideoElementReady()returns a promise that resolves when the video element is readygetCurrentMediaType()(on YTM only) returns the current media type ("video" or "song")tl()returns the translation for the provided translation key and provided localetlp()returns the translation for the provided translation key, including pluralization identifier and provided localeformatNumber()formats a number according to the configured locale and configured or provided format ("short" or "long")
- SelectorObserver /
addSelectorListener()changes:- Added
ytMastheadinstance for the title bar on YT - Renamed all YT-specific instances to have the
ytprefixwatchFlexyrenamed toytWatchFlexywatchMetadatarenamed toytWatchMetadata
- Added new SelectorObserver instance
browseResponsefor pages like/channel/{id}
- Added
- Event changes:
- Added events
bytm:featureInitStarted- emitted when the feature initialization process startsbytm:featureInitialized- emitted every time a feature has been initialized and is passed the feature's identifier stringbytm:dialogClosed- emitted when a BytmDialog is closed and gets passed the instancebytm:dialogClosed:id- emitted only when the dialog with the given ID is closed and gets passed the instancebytm:siteEvent:pathChanged- emitted whenever the URL path (location.pathname) changes
- Now the event
bytm:siteEvent:fullscreenToggledis only emitted once per fullscreen change - Renamed event
bytm:initPluginstobytm:registerPluginto be more consistent - Changed
eventproperty returned byregisterPlugin()from nanoevents Emitter to NanoEmitter instance (see the UserUtils docs)
In practice this changes nothing, but it benefits from plugins having access to the additional methodsonce()for immediately unsubscribing from an event after it was emitted once andunsubscribeAll()to remove all event listeners.
- Added events
- Changed the way plugins are registered by making the
[PREVIEW] 2.1.0 - Release Candidate 2
Click to expand the changes since rc1
- Changes:
- Created a prompt dialog to replace the browser's native dialogs, which could accidentally be turned off by the user and would softlock the script
- Internal Changes:
- Updated the UserUtils library to v7.2.1
- Made
getThumbnailUrl()andgetBestThumbnailUrl()use the domainyoutube.comto prevent cross-origin issues - Changed the way plugins are registered by making the
registerPlugin()function the sole argument passed by thebytm:registerPluginevent. Call this function synchronously to register your plugin. - Plugins will now load at an earlier point in BetterYTM's startup sequence. This means that plugins can now be initialized before the script's features are fully initialized and the DOM is ready. Use site events to wait for the right moment to interact with the page.
- Added new components:
showPrompt()to show a styled dialog that replaces theconfirm(),alert()andprompt()functions
- Plugin definition changes:
- Some intents were added or moved around in their order. See the new values in
src/types.ts -> enum PluginIntent
- Some intents were added or moved around in their order. See the new values in
- Added interface functions:
tl()returns the translation for the provided translation key and provided localetlp()returns the translation for the provided translation key, including pluralization identifier and provided locale
- Renamed event
bytm:initPluginstobytm:registerPluginto be more consistent
This version is almost finished but may still contain a few tiny bugs.
It is highly recommended you fully remove the script and reinstall it manually once the update is released.
[PREVIEW] 2.1.0 - Release Candidate 1
Click to expand the changelog at the time of 0635e65
- Added features:
- Added an experimental feature to like songs and videos of certain channels (on both sites) automatically.
Since this feature is still experimental, to be able to turn it on, you first need to enable advanced mode in the settings.
The button to toggle auto-liking will only show up on channel pages until the next update. Please report any issues you encounter. - Added the ability to show the approximate amount of likes and dislikes on the currently playing song (powered by ReturnYoutubeDislike)
- Added support for themes set by the ThemeSong extension
- Added an experimental feature to like songs and videos of certain channels (on both sites) automatically.
- Changes:
- Made song/video time remembering enabled by default on YT too
- Made reset button in config menu a feature of type
button - Welcome menu is now shown on YT too
- Added Ctrl modifier key to every lyrics button to open a lyrics search prompt
- Added Shift and Ctrl modifier keys to the above-queue buttons that can skip prompts or customize the behavior
- Arrow key and number key skipping works more reliably and now also in the config menu
- Changed default settings for some features.
After updating, if the values were unchanged from their previous default, they will automatically have the new default value:- Remember Song Time Sites: if set to
YTM only, it changes toboth sites - Volume Slider Scroll Sensitivity: if set to
10%, it changes to4%
- Remember Song Time Sites: if set to
- Made some settings require advanced mode that didn't before:
- Fix spacing/layout issues
- Fix HDR issues
- Disable Dark Reader sites
- Remove share tracking parameter sites
- Placement of list/queue buttons
- Removed broken feature "remove upgrade tab"
- Removed unnecessary experimental feature "advancedLyricsFilter" as the API's native search improved a lot
- Made all integration features configurable and gave them their own config category
- Fixes:
- Adjusted script to UI redesign of playlists
- Fixed song list buttons disappearing when dragging the row around
- Fixed song list buttons not always appearing immediately
- Fixed escape closing all open dialogs instead of one at a time
- Fixed "added to liked songs" toast not being consistently closed
- Fixed messed up time restoration feature on YT because of the
&tparam - Fixed broken autoplay queue delete button after a redesign
- Fixed transparent player bar background in fullscreen being barely readable with thumbnail overlay active
- Fixed thumbnail overlay not updating in fullscreen mode and in the mini player
- Fixed video time restoring breaking after pausing for a longer time
- Fixed "This document requires 'TrustedHTML' assignment" error on Chromium browsers
- Fixed toasts being shown with a 1000x higher duration than intended
Click to expand internal and plugin changes
- Internal Changes:
- Updated the UserUtils library to v7.2.1
- Removed
compareVersions()andcompareVersionArrays()in favor of including thecompare-versionslibrary - Now using a single query parameter for lyrics lookup
- Added license for plugin-related source code, see license-for-plugins.txt
- Added advanced feature to change the startup timeout (only impacts plugin initialization for now)
- Now using a blue logo is instead of the red BetterYTM logo when the script was compiled in development (preview) mode
- Fixed missing configuration keys in development/preview mode instead of potentially breaking the script
- Added Storybook for easier and faster development of components
- Removed the
@updateURLand@downloadURLdirectives because their use is controversial and the script has a built-in update check now - Migrated to pnpm for faster compilation times
- Moved
NanoEmitterclass over to the UserUtils library (it is still re-exported by the plugin interface as before)
- Plugin Changes:
See the contributing guide for the latest documentation of the plugin interface- Added new components:
createLongBtn()to create a button with an icon and text (works either as normal or as a toggle button)
The design follows that of the subscribe button on YTM's channel pages, but the consistent class names make it easy to style it differently.showToast()to show a custom toast notification with a message string or element and durationshowIconToast()to show a custom toast notification with a message string or element, icon and durationcreateRipple()to create a click ripple animation effect on a given element (experimental)ExImDialogclass for creating a BytmDialog instance that is designed for exporting and importing generic data as a string
- Changed components:
- BytmDialog now has the option
removeListenersOnDestroy(true by default) to configure removing all event listeners when the dialog is destroyed - BytmDialog's private members and methods have been changed to protected for easier extension (when using TypeScript)
- BytmDialog now has the option
- Added interface functions:
setInnerHtml()to set the innerHTML property of an element to a sanitized string using the Trusted Types API and the library DOMPurifygetAutoLikeData()to return the current auto-like data (authenticated function)saveAutoLikeData()to overwrite the auto-like data (authenticated function)fetchVideoVotes()to fetch the approximate like and dislike count of a video from Return Youtube DislikegetDomain()returns the current domain ("yt" or "ytm")waitVideoElementReady()returns a promise that resolves when the video element is readygetCurrentMediaType()(on YTM only) returns the current media type ("video" or "song")
- SelectorObserver /
addSelectorListener()changes:- Added
ytMastheadinstance for the title bar on YT - Renamed all YT-specific instances to have the
ytprefixwatchFlexyrenamed toytWatchFlexywatchMetadatarenamed toytWatchMetadata
- Added new SelectorObserver instance
browseResponsefor pages like/channel/{id}
- Added
- Event changes:
- Added events
bytm:featureInitStarted- emitted when the feature initialization process startsbytm:featureInitialized- emitted every time a feature has been initialized and is passed the feature's identifier stringbytm:dialogClosed- emitted when a BytmDialog is closed and gets passed the instancebytm:dialogClosed:id- emitted only when the dialog with the given ID is closed and gets passed the instancebytm:siteEvent:pathChanged- emitted whenever the URL path (location.pathname) changes
- Now the event
bytm:siteEvent:fullscreenToggledis only emitted once per fullscreen change - Renamed event
bytm:initPluginstobytm:registerPluginsto be more consistent - Changed
eventproperty returned byregisterPlugin()from nanoevents Emitter to NanoEmitter instance (see the UserUtils docs)
In practice this changes nothing, but it benefits from plugins having access to the additional methodsonce()for immediately unsubscribing from an event after it was emitted once andunsubscribeAll()to remove all event listeners.
- Added events
- Added new components:
This version is almost finished but may still contain a few tiny bugs.
It is highly recommended you fully remove the script and reinstall it manually once the update is released.