diff --git a/CHANGELOG.md b/CHANGELOG.md index ce1e2a2621..fba777ad9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Svelte changelog +## Unreleased + +* Make `noreferrer` warning less zealous ([#6289](https://github.com/sveltejs/svelte/issues/6289)) +* `trusted-types` CSP compatibility for Web Components ([#8134](https://github.com/sveltejs/svelte/issues/8134)) + ## 3.55.1 * Fix `draw` transition with delay showing a dot at the beginning of the path ([#6816](https://github.com/sveltejs/svelte/issues/6816)) diff --git a/LICENSE.md b/LICENSE.md index cd8f94f4ca..aa74406768 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2016-22 [these people](https://github.com/sveltejs/svelte/graphs/contributors) +Copyright (c) 2016-23 [these people](https://github.com/sveltejs/svelte/graphs/contributors) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 06ef1ba9c1..0d3e8a01bd 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -621,22 +621,23 @@ export default class Element extends Node { const name_attribute = attribute_map.get('name'); const target_attribute = attribute_map.get('target'); - if (target_attribute && target_attribute.get_static_value() === '_blank' && href_attribute) { + // links with target="_blank" should have noopener or noreferrer: https://developer.chrome.com/docs/lighthouse/best-practices/external-anchors-use-rel-noopener/ + // modern browsers add noopener by default, so we only need to check legacy browsers + // legacy browsers don't support noopener so we only check for noreferrer there + if (component.compile_options.legacy && target_attribute && target_attribute.get_static_value() === '_blank' && href_attribute) { const href_static_value = href_attribute.get_static_value() ? href_attribute.get_static_value().toLowerCase() : null; if (href_static_value === null || href_static_value.match(/^(https?:)?\/\//i)) { const rel = attribute_map.get('rel'); if (rel == null || rel.is_static) { const rel_values = rel ? rel.get_static_value().split(regex_any_repeated_whitespaces) : []; - const expected_values = ['noreferrer']; - expected_values.forEach(expected_value => { - if (!rel || rel && rel_values.indexOf(expected_value) < 0) { + if (!rel || !rel_values.includes('noreferrer')) { component.warn(this, { - code: `security-anchor-rel-${expected_value}`, - message: `Security: Anchor with "target=_blank" should have rel attribute containing the value "${expected_value}"` + code: 'security-anchor-rel-noreferrer', + message: + 'Security: Anchor with "target=_blank" should have rel attribute containing the value "noreferrer"' }); - } - }); + } } } } diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 44155f8464..58b7a8317b 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -531,7 +531,10 @@ export default function dom( constructor(options) { super(); - ${css.code && b`this.shadowRoot.innerHTML = \`\`;`} + ${css.code && b` + const style = document.createElement('style'); + style.textContent = \`${css.code.replace(regex_backslashes, '\\\\')}${css_sourcemap_enabled && options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}\` + this.shadowRoot.appendChild(style)`} @init(this, { target: this.shadowRoot, props: ${init_props}, customElement: true }, ${definition}, ${has_create_fragment ? 'create_fragment' : 'null'}, ${not_equal}, ${prop_indexes}, null, ${dirty}); diff --git a/test/js/samples/css-shadow-dom-keyframes/expected.js b/test/js/samples/css-shadow-dom-keyframes/expected.js index 5d65949488..ba7ca9a667 100644 --- a/test/js/samples/css-shadow-dom-keyframes/expected.js +++ b/test/js/samples/css-shadow-dom-keyframes/expected.js @@ -34,7 +34,9 @@ function create_fragment(ctx) { class Component extends SvelteElement { constructor(options) { super(); - this.shadowRoot.innerHTML = ``; + const style = document.createElement('style'); + style.textContent = `div{animation:foo 1s}@keyframes foo{0%{opacity:0}100%{opacity:1}}`; + this.shadowRoot.appendChild(style); init( this, diff --git a/test/validator/samples/security-anchor-rel-noreferer-legacy/_config.js b/test/validator/samples/security-anchor-rel-noreferer-legacy/_config.js new file mode 100644 index 0000000000..52f59c8767 --- /dev/null +++ b/test/validator/samples/security-anchor-rel-noreferer-legacy/_config.js @@ -0,0 +1,3 @@ +export default { + legacy: true +}; diff --git a/test/validator/samples/security-anchor-rel-noreferrer/input.svelte b/test/validator/samples/security-anchor-rel-noreferer-legacy/input.svelte similarity index 100% rename from test/validator/samples/security-anchor-rel-noreferrer/input.svelte rename to test/validator/samples/security-anchor-rel-noreferer-legacy/input.svelte diff --git a/test/validator/samples/security-anchor-rel-noreferrer/warnings.json b/test/validator/samples/security-anchor-rel-noreferer-legacy/warnings.json similarity index 100% rename from test/validator/samples/security-anchor-rel-noreferrer/warnings.json rename to test/validator/samples/security-anchor-rel-noreferer-legacy/warnings.json diff --git a/test/validator/samples/security-anchor-rel-noreferer/input.svelte b/test/validator/samples/security-anchor-rel-noreferer/input.svelte new file mode 100644 index 0000000000..f5361e5cfe --- /dev/null +++ b/test/validator/samples/security-anchor-rel-noreferer/input.svelte @@ -0,0 +1,33 @@ +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +svelte website (invalid) +Same host (valid) +Same host (valid) +Same host (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) +svelte website (valid) + +svelte website (valid) diff --git a/test/validator/samples/security-anchor-rel-noreferer/warnings.json b/test/validator/samples/security-anchor-rel-noreferer/warnings.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/test/validator/samples/security-anchor-rel-noreferer/warnings.json @@ -0,0 +1 @@ +[]