Skip to content

Commit

Permalink
Deprecate invoking functions in directives that require values
Browse files Browse the repository at this point in the history
  • Loading branch information
luisherranz committed Feb 13, 2025
1 parent 0740acc commit f0525ed
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 22 deletions.
88 changes: 70 additions & 18 deletions packages/interactivity/src/directives.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ const getGlobalEventDirective = (
.forEach( ( entry ) => {
const eventName = entry.suffix.split( '--', 1 )[ 0 ];
useInit( () => {
const cb = ( event: Event ) => evaluate( entry, event );
const callback = ( event: Event ) =>
evaluate( entry )( event );
const globalVar = type === 'window' ? window : document;
globalVar.addEventListener( eventName, cb );
return () => globalVar.removeEventListener( eventName, cb );
globalVar.addEventListener( eventName, callback );
return () =>
globalVar.removeEventListener( eventName, callback );
} );
} );
};
Expand All @@ -126,15 +128,16 @@ const getGlobalAsyncEventDirective = (
.forEach( ( entry ) => {
const eventName = entry.suffix.split( '--', 1 )[ 0 ];
useInit( () => {
const cb = async ( event: Event ) => {
const callback = async ( event: Event ) => {
await splitTask();
evaluate( entry, event );
evaluate( entry )( event );
};
const globalVar = type === 'window' ? window : document;
globalVar.addEventListener( eventName, cb, {
globalVar.addEventListener( eventName, callback, {
passive: true,
} );
return () => globalVar.removeEventListener( eventName, cb );
return () =>
globalVar.removeEventListener( eventName, callback );
} );
} );
};
Expand Down Expand Up @@ -206,7 +209,8 @@ export default () => {
start = performance.now();
}
}
const result = evaluate( entry );
const cb = evaluate( entry );
const result = cb();
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
if ( globalThis.SCRIPT_DEBUG ) {
performance.measure(
Expand Down Expand Up @@ -239,7 +243,8 @@ export default () => {
start = performance.now();
}
}
const result = evaluate( entry );
const cb = evaluate( entry );
const result = cb();
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
if ( globalThis.SCRIPT_DEBUG ) {
performance.measure(
Expand Down Expand Up @@ -286,7 +291,8 @@ export default () => {
start = performance.now();
}
}
evaluate( entry, event );
const cb = evaluate( entry );
cb( event );
if ( globalThis.IS_GUTENBERG_PLUGIN ) {
if ( globalThis.SCRIPT_DEBUG ) {
performance.measure(
Expand Down Expand Up @@ -332,7 +338,8 @@ export default () => {
}
entries.forEach( async ( entry ) => {
await splitTask();
evaluate( entry, event );
const cb = evaluate( entry );
cb( event );
} );
};
} );
Expand Down Expand Up @@ -360,7 +367,17 @@ export default () => {
.filter( isNonDefaultDirectiveSuffix )
.forEach( ( entry ) => {
const className = entry.suffix;
const result = evaluate( entry );
let result = evaluate( entry );

// Deprecated: Support for function values.
if ( typeof result === 'function' ) {
result =
entry.value[ 0 ] === '!' ? ! result() : result();
warn(
'The use of functions in `data-wp-class` is deprecated and will stop working in a future version of WordPress. Please use derived state instead. See: https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/core-concepts/undestanding-global-state-local-context-and-derived-state/'
);
}

const currentClass = element.props.class || '';
const classFinder = new RegExp(
`(^|\\s)${ className }(\\s|$)`,
Expand Down Expand Up @@ -400,7 +417,16 @@ export default () => {
directive( 'style', ( { directives: { style }, element, evaluate } ) => {
style.filter( isNonDefaultDirectiveSuffix ).forEach( ( entry ) => {
const styleProp = entry.suffix;
const result = evaluate( entry );
let result = evaluate( entry );

// Deprecated: Support for function values.
if ( typeof result === 'function' ) {
result = entry.value[ 0 ] === '!' ? ! result() : result();
warn(
'The use of functions in `data-wp-style` is deprecated and will stop working in a future version of WordPress. Please use derived state instead. See: https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/core-concepts/undestanding-global-state-local-context-and-derived-state/'
);
}

element.props.style = element.props.style || {};
if ( typeof element.props.style === 'string' ) {
element.props.style = cssStringToObject( element.props.style );
Expand Down Expand Up @@ -434,7 +460,16 @@ export default () => {
directive( 'bind', ( { directives: { bind }, element, evaluate } ) => {
bind.filter( isNonDefaultDirectiveSuffix ).forEach( ( entry ) => {
const attribute = entry.suffix;
const result = evaluate( entry );
let result = evaluate( entry );

// Deprecated: Support for function values.
if ( typeof result === 'function' ) {
result = entry.value[ 0 ] === '!' ? ! result() : result();
warn(
'The use of functions in `data-wp-bind` is deprecated and will stop working in a future version of WordPress. Please use derived state instead. See: https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/core-concepts/undestanding-global-state-local-context-and-derived-state/'
);
}

element.props[ attribute ] = result;

/*
Expand Down Expand Up @@ -535,7 +570,16 @@ export default () => {
}

try {
const result = evaluate( entry );
let result = evaluate( entry );

// Deprecated: Support for function values.
if ( typeof result === 'function' ) {
result = entry.value[ 0 ] === '!' ? ! result() : result();
warn(
'The use of functions in `data-wp-text` is deprecated and will stop working in a future version of WordPress. Please use derived state instead. See: https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/core-concepts/undestanding-global-state-local-context-and-derived-state/'
);
}

element.props.children =
typeof result === 'object' ? null : result.toString();
} catch ( e ) {
Expand All @@ -545,7 +589,7 @@ export default () => {

// data-wp-run
directive( 'run', ( { directives: { run }, evaluate } ) => {
run.forEach( ( entry ) => evaluate( entry ) );
run.forEach( ( entry ) => evaluate( entry )() );
} );

// data-wp-each--[item]
Expand All @@ -565,9 +609,17 @@ export default () => {
const inheritedValue = useContext( inheritedContext );

const [ entry ] = each;
const { namespace } = entry;
const { namespace, value } = entry;

let iterable = evaluate( entry );

const iterable = evaluate( entry );
// Deprecated: Support for function values.
if ( typeof iterable === 'function' ) {
iterable = value[ 0 ] === '!' ? ! iterable() : iterable();
warn(
'The use of functions in `data-wp-each` is deprecated and will stop working in a future version of WordPress. Please use derived state instead. See: https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/core-concepts/undestanding-global-state-local-context-and-derived-state/'
);
}

if ( typeof iterable?.[ Symbol.iterator ] !== 'function' ) {
return;
Expand Down
9 changes: 5 additions & 4 deletions packages/interactivity/src/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ interface DirectiveOptions {
}

export interface Evaluate {
( entry: DirectiveEntry, ...args: any[] ): any;
( entry: DirectiveEntry ): any;
}

interface GetEvaluate {
Expand Down Expand Up @@ -231,7 +231,7 @@ const resolve = ( path: string, namespace: string ) => {
// Generate the evaluate function.
export const getEvaluate: GetEvaluate =
( { scope } ) =>
( entry, ...args ) => {
( entry ) => {
let { value: path, namespace } = entry;
if ( typeof path !== 'string' ) {
throw new Error( 'The `value` prop should be a string path' );
Expand All @@ -241,9 +241,10 @@ export const getEvaluate: GetEvaluate =
path[ 0 ] === '!' && !! ( path = path.slice( 1 ) );
setScope( scope );
const value = resolve( path, namespace );
const result = typeof value === 'function' ? value( ...args ) : value;
resetScope();
return hasNegationOperator ? ! result : result;
return hasNegationOperator && typeof value !== 'function'
? ! value
: value;
};

// Separate directives by priority. The resulting array contains objects
Expand Down

0 comments on commit f0525ed

Please sign in to comment.