- Consolidated duplicate UndoManagers to single instance - Fixed connection promise to only resolve on 'connected' status - Fixed WebSocketProvider import (WebsocketProvider) - Added proper doc.destroy() cleanup - Renamed isPresenceInitialized property to avoid conflict Co-Authored-By: Paperclip <noreply@paperclip.ing>
117 lines
5.0 KiB
JavaScript
117 lines
5.0 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const utils_1 = require("@typescript-eslint/utils");
|
|
const utils_2 = require("../utils");
|
|
const createRule = utils_1.ESLintUtils.RuleCreator.withoutDocs;
|
|
function isComponent(node) {
|
|
return ((node.name.type === "JSXIdentifier" && !(0, utils_2.isDOMElementName)(node.name.name)) ||
|
|
node.name.type === "JSXMemberExpression");
|
|
}
|
|
const voidDOMElementRegex = /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/;
|
|
function isVoidDOMElementName(name) {
|
|
return voidDOMElementRegex.test(name);
|
|
}
|
|
function childrenIsEmpty(node) {
|
|
return node.parent.children.length === 0;
|
|
}
|
|
function childrenIsMultilineSpaces(node) {
|
|
const childrens = node.parent.children;
|
|
return (childrens.length === 1 &&
|
|
childrens[0].type === "JSXText" &&
|
|
childrens[0].value.indexOf("\n") !== -1 &&
|
|
childrens[0].value.replace(/(?!\xA0)\s/g, "") === "");
|
|
}
|
|
exports.default = createRule({
|
|
meta: {
|
|
type: "layout",
|
|
docs: {
|
|
description: "Disallow extra closing tags for components without children.",
|
|
url: "https://github.com/solidjs-community/eslint-plugin-solid/blob/main/docs/self-closing-comp.md",
|
|
},
|
|
fixable: "code",
|
|
schema: [
|
|
{
|
|
type: "object",
|
|
properties: {
|
|
component: {
|
|
type: "string",
|
|
description: "which Solid components should be self-closing when possible",
|
|
enum: ["all", "none"],
|
|
default: "all",
|
|
},
|
|
html: {
|
|
type: "string",
|
|
description: "which native elements should be self-closing when possible",
|
|
enum: ["all", "void", "none"],
|
|
default: "all",
|
|
},
|
|
},
|
|
additionalProperties: false,
|
|
},
|
|
],
|
|
messages: {
|
|
selfClose: "Empty components are self-closing.",
|
|
dontSelfClose: "This element should not be self-closing.",
|
|
},
|
|
},
|
|
defaultOptions: [],
|
|
create(context) {
|
|
function shouldBeSelfClosedWhenPossible(node) {
|
|
if (isComponent(node)) {
|
|
const whichComponents = context.options[0]?.component ?? "all";
|
|
return whichComponents === "all";
|
|
}
|
|
else if (node.name.type === "JSXIdentifier" && (0, utils_2.isDOMElementName)(node.name.name)) {
|
|
const whichComponents = context.options[0]?.html ?? "all";
|
|
switch (whichComponents) {
|
|
case "all":
|
|
return true;
|
|
case "void":
|
|
return isVoidDOMElementName(node.name.name);
|
|
case "none":
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return {
|
|
JSXOpeningElement(node) {
|
|
const canSelfClose = childrenIsEmpty(node) || childrenIsMultilineSpaces(node);
|
|
if (canSelfClose) {
|
|
const shouldSelfClose = shouldBeSelfClosedWhenPossible(node);
|
|
if (shouldSelfClose && !node.selfClosing) {
|
|
context.report({
|
|
node,
|
|
messageId: "selfClose",
|
|
fix(fixer) {
|
|
const openingElementEnding = node.range[1] - 1;
|
|
const closingElementEnding = node.parent.closingElement.range[1];
|
|
const range = [openingElementEnding, closingElementEnding];
|
|
return fixer.replaceTextRange(range, " />");
|
|
},
|
|
});
|
|
}
|
|
else if (!shouldSelfClose && node.selfClosing) {
|
|
context.report({
|
|
node,
|
|
messageId: "dontSelfClose",
|
|
fix(fixer) {
|
|
const sourceCode = context.getSourceCode();
|
|
const tagName = context.getSourceCode().getText(node.name);
|
|
const selfCloseEnding = node.range[1];
|
|
const lastTokens = sourceCode.getLastTokens(node, { count: 3 });
|
|
const isSpaceBeforeSelfClose = sourceCode.isSpaceBetween?.(lastTokens[0], lastTokens[1]);
|
|
const range = [
|
|
isSpaceBeforeSelfClose ? selfCloseEnding - 3 : selfCloseEnding - 2,
|
|
selfCloseEnding,
|
|
];
|
|
return fixer.replaceTextRange(range, `></${tagName}>`);
|
|
},
|
|
});
|
|
}
|
|
}
|
|
},
|
|
};
|
|
},
|
|
});
|