Skip to content

Commit 1848138

Browse files
fix: use importNode to clone templates for Firefox (#15272)
* fix: use `importNode` to clone templates for Firefox * fix: move `is_firefox` check to line 28 * fix: revert using `is_firefox` too soon
1 parent 5fe0272 commit 1848138

File tree

9 files changed

+14
-44
lines changed

9 files changed

+14
-44
lines changed

.changeset/slow-meals-wait.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: use `importNode` to clone templates for Firefox

packages/svelte/src/compiler/phases/2-analyze/visitors/Attribute.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ export function Attribute(node, context) {
2323
if (node.name === 'value' && parent.name === 'option') {
2424
mark_subtree_dynamic(context.path);
2525
}
26-
27-
// special case <img loading="lazy" />
28-
if (node.name === 'loading' && parent.name === 'img') {
29-
mark_subtree_dynamic(context.path);
30-
}
3126
}
3227

3328
if (is_event_attribute(node)) {

packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,6 @@ export function RegularElement(node, context) {
300300
build_class_directives(class_directives, node_id, context, is_attributes_reactive);
301301
build_style_directives(style_directives, node_id, context, is_attributes_reactive);
302302

303-
// Apply the src and loading attributes for <img> elements after the element is appended to the document
304-
if (node.name === 'img' && (has_spread || lookup.has('loading'))) {
305-
context.state.after_update.push(b.stmt(b.call('$.handle_lazy_img', node_id)));
306-
}
307-
308303
if (
309304
is_load_error_element(node.name) &&
310305
(has_spread || has_use || lookup.has('onload') || lookup.has('onerror'))

packages/svelte/src/internal/client/dom/elements/attributes.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -523,28 +523,3 @@ function srcset_url_equal(element, srcset) {
523523
)
524524
);
525525
}
526-
527-
/**
528-
* @param {HTMLImageElement} element
529-
* @returns {void}
530-
*/
531-
export function handle_lazy_img(element) {
532-
// If we're using an image that has a lazy loading attribute, we need to apply
533-
// the loading and src after the img element has been appended to the document.
534-
// Otherwise the lazy behaviour will not work due to our cloneNode heuristic for
535-
// templates.
536-
if (!hydrating && element.loading === 'lazy') {
537-
var src = element.src;
538-
// @ts-expect-error
539-
element[LOADING_ATTR_SYMBOL] = null;
540-
element.loading = 'eager';
541-
element.removeAttribute('src');
542-
requestAnimationFrame(() => {
543-
// @ts-expect-error
544-
if (element[LOADING_ATTR_SYMBOL] !== 'eager') {
545-
element.loading = 'lazy';
546-
}
547-
element.src = src;
548-
});
549-
}
550-
}

packages/svelte/src/internal/client/dom/operations.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ export var $window;
1111
/** @type {Document} */
1212
export var $document;
1313

14+
/** @type {boolean} */
15+
export var is_firefox;
16+
1417
/** @type {() => Node | null} */
1518
var first_child_getter;
1619
/** @type {() => Node | null} */
@@ -27,6 +30,7 @@ export function init_operations() {
2730

2831
$window = window;
2932
$document = document;
33+
is_firefox = /Firefox/.test(navigator.userAgent);
3034

3135
var element_prototype = Element.prototype;
3236
var node_prototype = Node.prototype;

packages/svelte/src/internal/client/dom/template.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @import { Effect, TemplateNode } from '#client' */
22
import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from './hydration.js';
3-
import { create_text, get_first_child } from './operations.js';
3+
import { create_text, get_first_child, is_firefox } from './operations.js';
44
import { create_fragment_from_html } from './reconciler.js';
55
import { active_effect } from '../runtime.js';
66
import { TEMPLATE_FRAGMENT, TEMPLATE_USE_IMPORT_NODE } from '../../../constants.js';
@@ -48,7 +48,7 @@ export function template(content, flags) {
4848
}
4949

5050
var clone = /** @type {TemplateNode} */ (
51-
use_import_node ? document.importNode(node, true) : node.cloneNode(true)
51+
use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true)
5252
);
5353

5454
if (is_fragment) {

packages/svelte/src/internal/client/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export {
3535
set_attributes,
3636
set_custom_element_data,
3737
set_xlink_attribute,
38-
handle_lazy_img,
3938
set_value,
4039
set_checked,
4140
set_selected,

packages/svelte/src/internal/client/runtime.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
set_component_context,
4040
set_dev_current_component_function
4141
} from './context.js';
42+
import { is_firefox } from './dom/operations.js';
4243

4344
const FLUSH_MICROTASK = 0;
4445
const FLUSH_SYNC = 1;
@@ -333,7 +334,7 @@ export function handle_error(error, effect, previous_effect, component_context)
333334
current_context = current_context.p;
334335
}
335336

336-
const indent = /Firefox/.test(navigator.userAgent) ? ' ' : '\t';
337+
const indent = is_firefox ? ' ' : '\t';
337338
define_property(error, 'message', {
338339
value: error.message + `\n${component_stack.map((name) => `\n${indent}in ${name}`).join('')}\n`
339340
});

packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,8 @@ export default function Skip_static_subtree($$anchor, $$props) {
4242
$.reset(select);
4343

4444
var img = $.sibling(select, 2);
45-
var div_2 = $.sibling(img, 2);
46-
var img_1 = $.child(div_2);
4745

48-
$.reset(div_2);
46+
$.next(2);
4947
$.template_effect(() => $.set_text(text, $$props.title));
50-
$.handle_lazy_img(img);
51-
$.handle_lazy_img(img_1);
5248
$.append($$anchor, fragment);
5349
}

0 commit comments

Comments
 (0)