Add coexistence checks to all enqueue methods to prevent loading both React and Grid.js assets simultaneously. Changes: - ReactAdmin.php: Only enqueue React assets when ?react=1 - Init.php: Skip Grid.js when React active on admin pages - Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0 - Customer.php, Product.php, License.php: Add coexistence checks Now the toggle between Classic and React versions works correctly. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
95 lines
2.6 KiB
JavaScript
95 lines
2.6 KiB
JavaScript
/**
|
|
* Traverse up through the chain of parent AST nodes returning the first parent
|
|
* the predicate returns a truthy value for.
|
|
*
|
|
* @param {Object} sourceNode The AST node to search from.
|
|
* @param {Function} predicate A predicate invoked for each parent.
|
|
*
|
|
* @return {Object | undefined} The first encountered parent node where the predicate
|
|
* returns a truthy value.
|
|
*/
|
|
function findParent( sourceNode, predicate ) {
|
|
if ( ! sourceNode.parent ) {
|
|
return;
|
|
}
|
|
|
|
if ( predicate( sourceNode.parent ) ) {
|
|
return sourceNode.parent;
|
|
}
|
|
|
|
return findParent( sourceNode.parent, predicate );
|
|
}
|
|
|
|
/**
|
|
* Tests whether the IS_GUTENBERG_PLUGIN variable is used as the condition for an
|
|
* if statement or ternary, triggering a violation if not.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // good
|
|
* if ( process.env.IS_GUTENBERG_PLUGIN ) {
|
|
*
|
|
* // bad
|
|
* const isFeatureActive = process.env.IS_GUTENBERG_PLUGIN;
|
|
* ```
|
|
*
|
|
* @param {Object} node The IS_GUTENBERG_PLUGIN identifier node.
|
|
* @param {Object} context The eslint context object.
|
|
*/
|
|
function isUsedInConditional( node, context ) {
|
|
const conditionalParent = findParent( node, ( candidate ) =>
|
|
[ 'IfStatement', 'ConditionalExpression' ].includes( candidate.type )
|
|
);
|
|
|
|
if ( ! conditionalParent ) {
|
|
return false;
|
|
}
|
|
|
|
// Allow for whitespace as prettier sometimes breaks this on separate lines.
|
|
const textRegex = /^\s*!?\s*process\s*\.\s*env\s*\.\s*IS_GUTENBERG_PLUGIN$/;
|
|
const testSource = context.getSource( conditionalParent.test );
|
|
|
|
if ( ! textRegex.test( testSource ) ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const ERROR_MESSAGE =
|
|
'The `process.env.IS_GUTENBERG_PLUGIN` constant should only be used as the condition in an if statement or ternary expression.';
|
|
|
|
module.exports = {
|
|
meta: {
|
|
type: 'problem',
|
|
schema: [],
|
|
},
|
|
create( context ) {
|
|
return {
|
|
Identifier( node ) {
|
|
// Bypass any identifiers with a node name different to `IS_GUTENBERG_PLUGIN`.
|
|
if ( node.name !== 'IS_GUTENBERG_PLUGIN' ) {
|
|
return;
|
|
}
|
|
|
|
if ( ! isUsedInConditional( node, context ) ) {
|
|
context.report( node, ERROR_MESSAGE );
|
|
}
|
|
},
|
|
// Check for literals, e.g. when 'IS_GUTENBERG_PLUGIN' is used as a string via something like 'window[ 'IS_GUTENBERG_PLUGIN' ]'.
|
|
Literal( node ) {
|
|
// Bypass any identifiers with a node value different to `IS_GUTENBERG_PLUGIN`.
|
|
if ( node.value !== 'IS_GUTENBERG_PLUGIN' ) {
|
|
return;
|
|
}
|
|
|
|
if ( node.parent && node.parent.type === 'MemberExpression' ) {
|
|
if ( ! isUsedInConditional( node, context ) ) {
|
|
context.report( node, ERROR_MESSAGE );
|
|
}
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|