mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-08-30 21:57:10 +02:00
85 lines
2.8 KiB
JavaScript
85 lines
2.8 KiB
JavaScript
/** @type {import('eslint').Rule.RuleModule} */
|
|
module.exports = {
|
|
meta: {
|
|
type: "problem",
|
|
docs: {
|
|
description:
|
|
"disallow direct mutation of startBinding or endBinding via mutateElement",
|
|
category: "Best Practices",
|
|
recommended: false,
|
|
},
|
|
fixable: null,
|
|
schema: [],
|
|
messages: {
|
|
noDirectBindingMutation:
|
|
"Direct mutation of {{ property }} via mutateElement() is not allowed. Use proper binding update functions instead.",
|
|
},
|
|
},
|
|
|
|
create(context) {
|
|
return {
|
|
CallExpression(node) {
|
|
// Check if this is a call to mutateElement (direct call or method call)
|
|
let isMutateElementCall = false;
|
|
|
|
if (
|
|
node.callee.type === "Identifier" &&
|
|
node.callee.name === "mutateElement"
|
|
) {
|
|
// Direct call: mutateElement()
|
|
isMutateElementCall = true;
|
|
} else if (
|
|
node.callee.type === "MemberExpression" &&
|
|
node.callee.property.type === "Identifier" &&
|
|
node.callee.property.name === "mutateElement"
|
|
) {
|
|
// Method call: something.mutateElement() or this.scene.mutateElement()
|
|
isMutateElementCall = true;
|
|
}
|
|
|
|
if (isMutateElementCall) {
|
|
// mutateElement can have different argument patterns:
|
|
// 1. mutateElement(element, updates) - 2 args
|
|
// 2. mutateElement(element, elementsMap, updates) - 3 args
|
|
// 3. mutateElement(element, updates, options) - 3 args
|
|
let updatesArg = null;
|
|
|
|
if (node.arguments.length >= 2) {
|
|
// Try second argument first (most common pattern)
|
|
const secondArg = node.arguments[1];
|
|
if (secondArg.type === "ObjectExpression") {
|
|
updatesArg = secondArg;
|
|
} else if (node.arguments.length >= 3) {
|
|
// If second arg is not an object, try third argument
|
|
const thirdArg = node.arguments[2];
|
|
if (thirdArg.type === "ObjectExpression") {
|
|
updatesArg = thirdArg;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (updatesArg) {
|
|
// Look for startBinding or endBinding properties
|
|
for (const property of updatesArg.properties) {
|
|
if (
|
|
property.type === "Property" &&
|
|
property.key.type === "Identifier" &&
|
|
(property.key.name === "startBinding" ||
|
|
property.key.name === "endBinding")
|
|
) {
|
|
context.report({
|
|
node: property,
|
|
messageId: "noDirectBindingMutation",
|
|
data: {
|
|
property: property.key.name,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|