Skip to content

Commit d993152

Browse files
committed
Add eslint
1 parent 8d58356 commit d993152

26 files changed

+780
-149
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,21 @@ jobs:
1818
ruby-version: ruby-3.3.7
1919
bundler-cache: true
2020

21-
- name: Lint code for consistent style
21+
- name: Set up Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '20'
25+
cache: 'yarn'
26+
27+
- name: Install JavaScript dependencies
28+
run: yarn install --frozen-lockfile
29+
30+
- name: Lint Ruby code for consistent style
2231
run: bin/rubocop -f github
2332

33+
- name: Lint JavaScript code for consistent style
34+
run: yarn lint
35+
2436
test:
2537
runs-on: ubuntu-latest
2638

eslint.config.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import js from "@eslint/js"
2+
3+
export default [
4+
{
5+
ignores: ["dist/**", "app/**", "node_modules/**", "pkg/**", "test/**", "lib/**", "bin/**", "config/**", "docs/**"]
6+
},
7+
js.configs.recommended,
8+
{
9+
files: ["src/**/*.js"],
10+
languageOptions: {
11+
ecmaVersion: 2022,
12+
sourceType: "module",
13+
globals: {
14+
console: "readonly",
15+
document: "readonly",
16+
window: "readonly",
17+
navigator: "readonly",
18+
HTMLElement: "readonly",
19+
CustomEvent: "readonly",
20+
Element: "readonly",
21+
Node: "readonly",
22+
NodeList: "readonly",
23+
Event: "readonly",
24+
MutationObserver: "readonly",
25+
DOMParser: "readonly",
26+
Blob: "readonly",
27+
File: "readonly",
28+
FileReader: "readonly",
29+
URL: "readonly",
30+
URLSearchParams: "readonly",
31+
Request: "readonly",
32+
Response: "readonly",
33+
FormData: "readonly",
34+
fetch: "readonly",
35+
setTimeout: "readonly",
36+
clearTimeout: "readonly",
37+
setInterval: "readonly",
38+
clearInterval: "readonly",
39+
XMLHttpRequest: "readonly",
40+
requestAnimationFrame: "readonly",
41+
cancelAnimationFrame: "readonly",
42+
customElements: "readonly",
43+
Prism: "readonly"
44+
}
45+
},
46+
rules: {
47+
"array-bracket-spacing": ["error", "always"],
48+
"block-spacing": ["error", "always"],
49+
"camelcase": ["error"],
50+
"comma-spacing": ["error"],
51+
"curly": ["error", "multi-line"],
52+
"dot-notation": ["error"],
53+
"eol-last": ["error"],
54+
"func-style": ["error", "declaration"],
55+
"getter-return": ["error"],
56+
"keyword-spacing": ["error"],
57+
"no-empty": "off",
58+
"no-extra-parens": ["error"],
59+
"no-multi-spaces": ["error", { "exceptions": { "VariableDeclarator": true } }],
60+
"no-multiple-empty-lines": ["error", { "max": 2 }],
61+
"no-restricted-globals": ["error", "event"],
62+
"no-trailing-spaces": ["error"],
63+
"no-unused-vars": ["error", { "vars": "all", "args": "none", "caughtErrors": "none" }],
64+
"no-var": ["error"],
65+
"object-curly-spacing": ["error", "always"],
66+
"prefer-const": ["error"],
67+
"quotes": ["error", "double"],
68+
"semi": ["error", "never"],
69+
"sort-imports": ["error", { "ignoreDeclarationSort": true }]
70+
}
71+
}
72+
]

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@
1212
"author": "Jorge Manrubia <[email protected]>",
1313
"license": "MIT",
1414
"devDependencies": {
15+
"@eslint/js": "^9.15.0",
1516
"@rollup/plugin-node-resolve": "^16.0.1",
1617
"@rollup/plugin-terser": "^0.4.4",
18+
"eslint": "^9.15.0",
1719
"rollup": "^4.44.1",
1820
"rollup-plugin-gzip": "^4.1.1"
1921
},
2022
"scripts": {
2123
"build": "rollup -c",
2224
"build:npm": "rollup -c rollup.config.npm.mjs",
2325
"watch": "rollup -wc",
26+
"lint": "eslint",
2427
"prerelease": "yarn build:npm",
2528
"release": "yarn build:npm && yarn publish"
2629
},

src/config/dom_purify.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import DOMPurify from 'dompurify'
1+
import DOMPurify from "dompurify"
22

33
DOMPurify.addHook("uponSanitizeElement", (node, data) => {
44
if (data.tagName === "strong" || data.tagName === "em") {
5-
node.removeAttribute('class');
5+
node.removeAttribute("class")
66
}
7-
});
7+
})

src/config/theme.js

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,47 @@ export default {
66
underline: "lexxy-content__underline",
77
},
88
codeHighlight: {
9-
atrule: 'code-token__attr',
10-
attr: 'code-token__attr',
11-
'attr-name': 'code-token__attr',
12-
'attr-value': 'code-token__selector',
13-
boolean: 'code-token__property',
14-
bold: 'code-token__variable',
15-
builtin: 'code-token__selector',
16-
cdata: 'code-token__comment',
17-
char: 'code-token__selector',
18-
class: 'code-token__function',
19-
'class-name': 'code-token__function',
20-
color: 'code-token__property',
21-
comment: 'code-token__comment',
22-
constant: 'code-token__property',
23-
coord: 'code-token__property',
24-
decorator: 'code-token__function',
25-
deleted: 'code-token__property',
26-
doctype: 'code-token__comment',
27-
entity: 'code-token__operator',
28-
function: 'code-token__function',
29-
hexcode: 'code-token__property',
30-
important: 'code-token__variable',
31-
inserted: 'code-token__selector',
32-
italic: 'code-token__comment',
33-
keyword: 'code-token__attr',
34-
namespace: 'code-token__variable',
35-
number: 'code-token__property',
36-
operator: 'code-token__operator',
37-
parameter: 'code-token__variable',
38-
prolog: 'code-token__comment',
39-
property: 'code-token__property',
40-
punctuation: 'code-token__punctuation',
41-
regex: 'code-token__variable',
42-
script: 'code-token__function',
43-
selector: 'code-token__selector',
44-
string: 'code-token__selector',
45-
style: 'code-token__function',
46-
symbol: 'code-token__property',
47-
tag: 'code-token__property',
48-
title: 'code-token__function',
49-
url: 'code-token__operator',
50-
variable: 'code-token__variable',
9+
atrule: "code-token__attr",
10+
attr: "code-token__attr",
11+
"attr-name": "code-token__attr",
12+
"attr-value": "code-token__selector",
13+
boolean: "code-token__property",
14+
bold: "code-token__variable",
15+
builtin: "code-token__selector",
16+
cdata: "code-token__comment",
17+
char: "code-token__selector",
18+
class: "code-token__function",
19+
"class-name": "code-token__function",
20+
color: "code-token__property",
21+
comment: "code-token__comment",
22+
constant: "code-token__property",
23+
coord: "code-token__property",
24+
decorator: "code-token__function",
25+
deleted: "code-token__property",
26+
doctype: "code-token__comment",
27+
entity: "code-token__operator",
28+
function: "code-token__function",
29+
hexcode: "code-token__property",
30+
important: "code-token__variable",
31+
inserted: "code-token__selector",
32+
italic: "code-token__comment",
33+
keyword: "code-token__attr",
34+
namespace: "code-token__variable",
35+
number: "code-token__property",
36+
operator: "code-token__operator",
37+
parameter: "code-token__variable",
38+
prolog: "code-token__comment",
39+
property: "code-token__property",
40+
punctuation: "code-token__punctuation",
41+
regex: "code-token__variable",
42+
script: "code-token__function",
43+
selector: "code-token__selector",
44+
string: "code-token__selector",
45+
style: "code-token__function",
46+
symbol: "code-token__property",
47+
tag: "code-token__property",
48+
title: "code-token__function",
49+
url: "code-token__operator",
50+
variable: "code-token__variable",
5151
}
5252
}

src/editor/clipboard.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { marked } from "marked"
2-
import { isUrl } from "../helpers/string_helper";
3-
import { nextFrame } from "../helpers/timing_helpers";
2+
import { isUrl } from "../helpers/string_helper"
3+
import { nextFrame } from "../helpers/timing_helpers"
44
import { dispatch } from "../helpers/html_helper"
55

66
export default class Clipboard {
@@ -63,7 +63,7 @@ export default class Clipboard {
6363
#handlePastedFiles(clipboardData) {
6464
if (!this.editorElement.supportsAttachments) return
6565

66-
const html = clipboardData.getData('text/html')
66+
const html = clipboardData.getData("text/html")
6767
if (html) return // Ignore if image copied from browser since we will load it as a remote image
6868

6969
this.#preservingScrollPosition(() => {

src/editor/command_dispatcher.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import {
22
$getSelection,
33
$isRangeSelection,
4-
PASTE_COMMAND,
54
COMMAND_PRIORITY_LOW,
65
FORMAT_TEXT_COMMAND,
7-
UNDO_COMMAND,
8-
REDO_COMMAND
6+
PASTE_COMMAND,
7+
REDO_COMMAND,
8+
UNDO_COMMAND
99
} from "lexical"
1010

1111
import { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from "@lexical/list"
1212
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode } from "@lexical/rich-text"
13-
import { CodeNode, $isCodeNode } from "@lexical/code"
13+
import { $isCodeNode, CodeNode } from "@lexical/code"
1414
import { $toggleLink } from "@lexical/link"
1515
import { createElement } from "../helpers/html_helper"
1616
import { getListType } from "../helpers/lexical_helper"
@@ -75,7 +75,7 @@ export class CommandDispatcher {
7575

7676
dispatchInsertUnorderedList() {
7777
const selection = $getSelection()
78-
if (!selection) return;
78+
if (!selection) return
7979

8080
const anchorNode = selection.anchor.getNode()
8181

@@ -88,7 +88,7 @@ export class CommandDispatcher {
8888

8989
dispatchInsertOrderedList() {
9090
const selection = $getSelection()
91-
if (!selection) return;
91+
if (!selection) return
9292

9393
const anchorNode = selection.anchor.getNode()
9494

src/editor/contents.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import {
2-
$createParagraphNode, $getSelection, $setSelection, $insertNodes, $isElementNode, $isParagraphNode, $isTextNode,
3-
$isRangeSelection, $createLineBreakNode, $createTextNode, HISTORY_MERGE_TAG, $isNodeSelection, $getNodeByKey, $getRoot
2+
$createLineBreakNode, $createParagraphNode, $createTextNode, $getNodeByKey, $getRoot, $getSelection, $insertNodes,
3+
$isElementNode, $isNodeSelection, $isParagraphNode, $isRangeSelection, $isTextNode, $setSelection, HISTORY_MERGE_TAG
44
} from "lexical"
55

66
import { $generateNodesFromDOM } from "@lexical/html"
77
import { ActionTextAttachmentUploadNode } from "../nodes/action_text_attachment_upload_node"
88
import { CustomActionTextAttachmentNode } from "../nodes/custom_action_text_attachment_node"
9-
import { $toggleLink, $createLinkNode } from "@lexical/link"
9+
import { $createLinkNode, $toggleLink } from "@lexical/link"
1010
import { dispatch, parseHtml } from "../helpers/html_helper"
11-
import { $isListItemNode, $isListNode } from "@lexical/list"
11+
import { $isListNode } from "@lexical/list"
1212
import { getNearestListItemNode } from "../helpers/lexical_helper"
13-
import { nextFrame } from "../helpers/timing_helpers.js";
13+
import { nextFrame } from "../helpers/timing_helpers.js"
1414

1515
export default class Contents {
1616
constructor(editorElement) {
@@ -546,8 +546,8 @@ export default class Contents {
546546
firstParagraph.selectStart()
547547
const currentSelection = $getSelection()
548548
if (currentSelection && $isRangeSelection(currentSelection)) {
549-
currentSelection.anchor.set(firstParagraph.getKey(), 0, 'element')
550-
currentSelection.focus.set(lastParagraph.getKey(), lastParagraph.getChildrenSize(), 'element')
549+
currentSelection.anchor.set(firstParagraph.getKey(), 0, "element")
550+
currentSelection.focus.set(lastParagraph.getKey(), lastParagraph.getChildrenSize(), "element")
551551
}
552552
}
553553

@@ -601,14 +601,14 @@ export default class Contents {
601601
const last = children[children.length - 1]
602602
const beforeLast = children[children.length - 2]
603603

604-
if (($isTextNode(last) && last.getTextContent() === "") && (beforeLast && !$isTextNode(beforeLast))) {
604+
if ($isTextNode(last) && last.getTextContent() === "" && (beforeLast && !$isTextNode(beforeLast))) {
605605
paragraph.append($createLineBreakNode())
606606
}
607607
}
608608
}
609609

610610
#createCustomAttachmentNodeWithHtml(html, options = {}) {
611-
const attachmentConfig = typeof options === 'object' ? options : {}
611+
const attachmentConfig = typeof options === "object" ? options : {}
612612

613613
return new CustomActionTextAttachmentNode({
614614
sgid: attachmentConfig.sgid || null,
@@ -623,6 +623,6 @@ export default class Contents {
623623
}
624624

625625
#shouldUploadFile(file) {
626-
return dispatch(this.editorElement, 'lexxy:file-accept', { file }, true)
626+
return dispatch(this.editorElement, "lexxy:file-accept", { file }, true)
627627
}
628628
}

src/editor/prompt/local_filter_source.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import BaseSource from "./base_source"
2-
import { filterMatches } from "../../helpers/string_helper";
2+
import { filterMatches } from "../../helpers/string_helper"
33

44
export default class LocalFilterSource extends BaseSource {
55
async buildListItems(filter = "") {

src/editor/prompt/remote_filter_source.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import BaseSource from "./base_source"
2-
import { debounceAsync } from "../../helpers/timing_helpers";
2+
import { debounceAsync } from "../../helpers/timing_helpers"
33

44
const DEBOUNCE_INTERVAL = 200
55

0 commit comments

Comments
 (0)