Comparing version 5.0.0-next.219 to 5.0.0-next.220
@@ -5,3 +5,3 @@ { | ||
"license": "MIT", | ||
"version": "5.0.0-next.219", | ||
"version": "5.0.0-next.220", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "types": "./types/index.d.ts", |
/** @import { Expression } from 'estree' */ | ||
/** @import { Attribute, ExpressionMetadata, ExpressionTag, OnDirective, SvelteNode } from '#compiler' */ | ||
/** @import { Attribute, ExpressionMetadata, ExpressionTag, SvelteNode } from '#compiler' */ | ||
/** @import { ComponentContext } from '../../types' */ | ||
import { is_capture_event, is_passive_event } from '../../../../../../utils.js'; | ||
import { is_capture_event } from '../../../../../../utils.js'; | ||
import { dev, locator } from '../../../../../state.js'; | ||
import * as b from '../../../../../utils/builders.js'; | ||
@@ -139,7 +140,45 @@ | ||
// wrap the handler in a function, so the expression is re-evaluated for each event | ||
return b.function( | ||
null, | ||
[b.rest(b.id('$$args'))], | ||
b.block([b.stmt(b.call(b.member(handler, b.id('apply'), false, true), b.this, b.id('$$args')))]) | ||
); | ||
let call = b.call(b.member(handler, b.id('apply'), false, true), b.this, b.id('$$args')); | ||
if (dev) { | ||
const loc = locator(/** @type {number} */ (node.start)); | ||
const remove_parens = | ||
node.type === 'CallExpression' && | ||
node.arguments.length === 0 && | ||
node.callee.type === 'Identifier'; | ||
call = b.call( | ||
'$.apply', | ||
b.thunk(handler), | ||
b.this, | ||
b.id('$$args'), | ||
b.id(context.state.analysis.name), | ||
loc && b.array([b.literal(loc.line), b.literal(loc.column)]), | ||
has_side_effects(node) && b.true, | ||
remove_parens && b.true | ||
); | ||
} | ||
return b.function(null, [b.rest(b.id('$$args'))], b.block([b.stmt(call)])); | ||
} | ||
/** | ||
* @param {Expression} node | ||
*/ | ||
function has_side_effects(node) { | ||
if ( | ||
node.type === 'CallExpression' || | ||
node.type === 'NewExpression' || | ||
node.type === 'AssignmentExpression' || | ||
node.type === 'UpdateExpression' | ||
) { | ||
return true; | ||
} | ||
if (node.type === 'SequenceExpression') { | ||
return node.expressions.some(has_side_effects); | ||
} | ||
return false; | ||
} |
@@ -0,1 +1,2 @@ | ||
/** @import { Location } from 'locate-character' */ | ||
import { teardown } from '../../reactivity/effects.js'; | ||
@@ -5,2 +6,5 @@ import { define_property, is_array } from '../../../shared/utils.js'; | ||
import { queue_micro_task } from '../task.js'; | ||
import { dev_current_component_function } from '../../runtime.js'; | ||
import { FILENAME } from '../../../../constants.js'; | ||
import * as w from '../../warnings.js'; | ||
@@ -277,1 +281,51 @@ /** @type {Set<string>} */ | ||
} | ||
/** | ||
* In dev, warn if an event handler is not a function, as it means the | ||
* user probably called the handler or forgot to add a `() =>` | ||
* @param {() => (event: Event, ...args: any) => void} thunk | ||
* @param {EventTarget} element | ||
* @param {[Event, ...any]} args | ||
* @param {any} component | ||
* @param {[number, number]} [loc] | ||
* @param {boolean} [remove_parens] | ||
*/ | ||
export function apply( | ||
thunk, | ||
element, | ||
args, | ||
component, | ||
loc, | ||
has_side_effects = false, | ||
remove_parens = false | ||
) { | ||
let handler; | ||
let error; | ||
try { | ||
handler = thunk(); | ||
} catch (e) { | ||
error = e; | ||
} | ||
if (typeof handler === 'function') { | ||
handler.apply(element, args); | ||
} else if (has_side_effects || handler != null) { | ||
const filename = component?.[FILENAME]; | ||
const location = filename | ||
? loc | ||
? ` at ${filename}:${loc[0]}:${loc[1]}` | ||
: ` in ${filename}` | ||
: ''; | ||
const event_name = args[0].type; | ||
const description = `\`${event_name}\` handler${location}`; | ||
const suggestion = remove_parens ? 'remove the trailing `()`' : 'add a leading `() =>`'; | ||
w.event_handler_invalid(description, suggestion); | ||
if (error) { | ||
throw error; | ||
} | ||
} | ||
} |
@@ -39,3 +39,3 @@ export { FILENAME, HMR } from '../../constants.js'; | ||
export { set_class, set_svg_class, set_mathml_class, toggle_class } from './dom/elements/class.js'; | ||
export { event, delegate, replay_events } from './dom/elements/events.js'; | ||
export { apply, event, delegate, replay_events } from './dom/elements/events.js'; | ||
export { autofocus, remove_textarea_child } from './dom/elements/misc.js'; | ||
@@ -42,0 +42,0 @@ export { set_style } from './dom/elements/style.js'; |
@@ -94,15 +94,20 @@ /** @import { Derived } from '#client' */ | ||
export function update_derived(derived) { | ||
var value; | ||
if (DEV) { | ||
if (stack.includes(derived)) { | ||
e.derived_references_self(); | ||
} | ||
try { | ||
if (stack.includes(derived)) { | ||
e.derived_references_self(); | ||
} | ||
stack.push(derived); | ||
} | ||
stack.push(derived); | ||
destroy_derived_children(derived); | ||
var value = update_reaction(derived); | ||
if (DEV) { | ||
stack.pop(); | ||
destroy_derived_children(derived); | ||
value = update_reaction(derived); | ||
} finally { | ||
stack.pop(); | ||
} | ||
} else { | ||
destroy_derived_children(derived); | ||
value = update_reaction(derived); | ||
} | ||
@@ -109,0 +114,0 @@ |
@@ -50,3 +50,5 @@ /** @import { ComponentContext, Effect, EffectNodes, TemplateNode } from '#client' */ | ||
// @ts-expect-error | ||
text.nodeValue = text.__t = value; | ||
text.__t = value; | ||
// It's faster to make the value a string rather than passing a non-string to nodeValue | ||
text.nodeValue = value == null ? '' : value + ''; | ||
} | ||
@@ -53,0 +55,0 @@ } |
@@ -23,2 +23,16 @@ /* This file is generated by scripts/process-messages/index.js. Do not edit! */ | ||
/** | ||
* %handler% should be a function. Did you mean to %suggestion%? | ||
* @param {string} handler | ||
* @param {string} suggestion | ||
*/ | ||
export function event_handler_invalid(handler, suggestion) { | ||
if (DEV) { | ||
console.warn(`%c[svelte] event_handler_invalid\n%c${handler} should be a function. Did you mean to ${suggestion}?`, bold, normal); | ||
} else { | ||
// TODO print a link to the documentation | ||
console.warn("event_handler_invalid"); | ||
} | ||
} | ||
/** | ||
* The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value | ||
@@ -25,0 +39,0 @@ * @param {string} attribute |
@@ -9,3 +9,3 @@ // generated during release, do not modify | ||
*/ | ||
export const VERSION = '5.0.0-next.219'; | ||
export const VERSION = '5.0.0-next.220'; | ||
export const PUBLIC_VERSION = '5'; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2202081
48803