fix: innerHTML trusted-types

This commit is contained in:
JellyBrick
2024-11-03 18:16:36 +09:00
parent aab9358d67
commit 516fbff3d7
6 changed files with 51 additions and 16 deletions

View File

@ -8,6 +8,8 @@ import { LoggerPrefix } from '@/utils';
import { t } from '@/i18n';
import { defaultTrustedTypePolicy } from '@/utils/trusted-types';
import { ElementFromHtml } from '../utils/renderer';
import type { RendererContext } from '@/types/contexts';
@ -108,7 +110,9 @@ export const onRendererLoad = ({
ipc.on('downloader-feedback', (feedback: string) => {
if (progress) {
const targetHtml = feedback || t('plugins.downloader.templates.button');
progress.innerHTML = window.trustedTypes?.defaultPolicy ? window.trustedTypes.defaultPolicy.createHTML(targetHtml) : targetHtml;
(progress.innerHTML as string | TrustedHTML) = defaultTrustedTypePolicy
? defaultTrustedTypePolicy.createHTML(targetHtml)
: targetHtml;
} else {
console.warn(
LoggerPrefix,

View File

@ -2,6 +2,8 @@ import { LoggerPrefix } from '@/utils';
import { t } from '@/i18n';
import { defaultTrustedTypePolicy } from '@/utils/trusted-types';
import type { SongInfo } from '@/providers/song-info';
import type { RendererContext } from '@/types/contexts';
import type { LyricsGeniusPluginConfig } from '@/plugins/lyrics-genius/index';
@ -20,7 +22,10 @@ export const onRendererLoad = ({
<yt-formatted-string class="footer style-scope ytmusic-description-shelf-renderer" style="align-self: baseline">
</yt-formatted-string>
`;
lyricsContainer.innerHTML = window.trustedTypes?.defaultPolicy ? window.trustedTypes.defaultPolicy.createHTML(targetHtml) : targetHtml;
(lyricsContainer.innerHTML as string | TrustedHTML) =
defaultTrustedTypePolicy
? defaultTrustedTypePolicy.createHTML(targetHtml)
: targetHtml;
if (lyrics) {
const footer = lyricsContainer.querySelector('.footer');

View File

@ -3,6 +3,8 @@ import sliderHTML from './templates/slider.html?raw';
import { getSongMenu } from '@/providers/dom-elements';
import { singleton } from '@/providers/decorators';
import { defaultTrustedTypePolicy } from '@/utils/trusted-types';
import { ElementFromHtml } from '../utils/renderer';
const slider = ElementFromHtml(sliderHTML);
@ -23,7 +25,10 @@ const updatePlayBackSpeed = () => {
const playbackSpeedElement = document.querySelector('#playback-speed-value');
if (playbackSpeedElement) {
const targetHtml = String(playbackSpeed);
playbackSpeedElement.innerHTML = window.trustedTypes?.defaultPolicy ? trustedTypes.defaultPolicy.createHTML(targetHtml) : targetHtml;
(playbackSpeedElement.innerHTML as string | TrustedHTML) =
defaultTrustedTypePolicy
? defaultTrustedTypePolicy.createHTML(targetHtml)
: targetHtml;
}
};

View File

@ -1,3 +1,5 @@
import { defaultTrustedTypePolicy } from '@/utils/trusted-types';
/**
* Creates a DOM element from an HTML string
* @param html The HTML string
@ -6,7 +8,9 @@
export const ElementFromHtml = (html: string): HTMLElement => {
const template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = window.trustedTypes?.defaultPolicy ? window.trustedTypes.defaultPolicy.createHTML(html) : html;
(template.innerHTML as string | TrustedHTML) = defaultTrustedTypePolicy
? defaultTrustedTypePolicy.createHTML(html)
: html;
return template.content.firstElementChild as HTMLElement;
};

View File

@ -13,6 +13,11 @@ import {
import { loadI18n, setLanguage, t as i18t } from '@/i18n';
import {
defaultTrustedTypePolicy,
registerWindowDefaultTrustedTypePolicy,
} from '@/utils/trusted-types';
import type { PluginConfig } from '@/types/plugins';
import type { YoutubePlayer } from '@/types/youtube-player';
import type { QueueElement } from '@/types/queue';
@ -23,17 +28,7 @@ let isPluginLoaded = false;
let isApiLoaded = false;
let firstDataLoaded = false;
if (
window.trustedTypes &&
window.trustedTypes.createPolicy &&
!window.trustedTypes.defaultPolicy
) {
window.trustedTypes.createPolicy('default', {
createHTML: (input) => input,
createScriptURL: (input) => input,
createScript: (input) => input,
});
}
registerWindowDefaultTrustedTypePolicy();
async function listenForApiLoad() {
if (!isApiLoaded) {
@ -270,7 +265,9 @@ const defineYTMDTransElements = () => {
const key = that.getAttribute('key');
if (key) {
const targetHtml = i18t(key);
that.innerHTML = window.trustedTypes?.defaultPolicy ? window.trustedTypes.defaultPolicy.createHTML(targetHtml) : targetHtml;
(that.innerHTML as string | TrustedHTML) = defaultTrustedTypePolicy
? defaultTrustedTypePolicy.createHTML(targetHtml)
: targetHtml;
}
};
customElements.define(

View File

@ -0,0 +1,20 @@
import type { TrustedTypePolicy } from 'trusted-types/lib';
export let defaultTrustedTypePolicy: Pick<
TrustedTypePolicy<{
createHTML: (input: string) => string;
createScriptURL: (input: string) => string;
createScript: (input: string) => string;
}>,
'name' | 'createHTML' | 'createScript' | 'createScriptURL'
>;
export const registerWindowDefaultTrustedTypePolicy = () => {
if (window.trustedTypes && window.trustedTypes.createPolicy) {
defaultTrustedTypePolicy = window.trustedTypes.createPolicy('default', {
createHTML: (input) => input,
createScriptURL: (input) => input,
createScript: (input) => input,
});
}
};