wikilint 2.22.0 → 2.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/default.json +2 -0
- package/config/minimum.json +1 -0
- package/config/moegirl.json +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/lib/document.js +1 -1
- package/dist/lib/element.d.ts +3 -15
- package/dist/lib/element.js +235 -240
- package/dist/lib/lsp.js +26 -9
- package/dist/lib/node.d.ts +3 -8
- package/dist/lib/node.js +15 -21
- package/dist/lib/text.js +1 -1
- package/dist/mixin/attributesParent.js +2 -3
- package/dist/mixin/elementLike.d.ts +21 -0
- package/dist/mixin/elementLike.js +53 -0
- package/dist/mixin/gapped.js +2 -2
- package/dist/mixin/hidden.js +2 -1
- package/dist/mixin/multiLine.js +2 -2
- package/dist/mixin/nodeLike.d.ts +17 -0
- package/dist/mixin/nodeLike.js +26 -0
- package/dist/mixin/padded.js +2 -1
- package/dist/parser/selector.js +6 -3
- package/dist/src/atom.d.ts +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/link/galleryImage.js +1 -1
- package/dist/src/nested.js +1 -1
- package/dist/src/paramTag/index.d.ts +1 -1
- package/dist/src/syntax.d.ts +1 -1
- package/dist/src/table/base.d.ts +1 -1
- package/dist/src/table/index.d.ts +0 -9
- package/dist/src/table/index.js +2 -6
- package/dist/src/transclude.d.ts +0 -2
- package/dist/src/transclude.js +1 -2
- package/dist/util/debug.js +1 -0
- package/dist/util/sharable.js +1 -1
- package/dist/util/sharable.mjs +1 -1
- package/package.json +2 -3
package/config/default.json
CHANGED
|
@@ -567,6 +567,7 @@
|
|
|
567
567
|
"translation",
|
|
568
568
|
"chart",
|
|
569
569
|
"avatar",
|
|
570
|
+
"img",
|
|
570
571
|
"mentor"
|
|
571
572
|
],
|
|
572
573
|
"variable": [
|
|
@@ -936,6 +937,7 @@
|
|
|
936
937
|
"#头像": "avatar",
|
|
937
938
|
"#頭像": "avatar",
|
|
938
939
|
"#avatar": "avatar",
|
|
940
|
+
"#img": "img",
|
|
939
941
|
"wb報表名稱": "wbreponame",
|
|
940
942
|
"wb报告名": "wbreponame",
|
|
941
943
|
"wbreponame": "wbreponame"
|
package/config/minimum.json
CHANGED
package/config/moegirl.json
CHANGED
|
@@ -396,6 +396,7 @@
|
|
|
396
396
|
"vardefine",
|
|
397
397
|
"vardefineecho",
|
|
398
398
|
"invoke",
|
|
399
|
+
"img",
|
|
399
400
|
"related"
|
|
400
401
|
],
|
|
401
402
|
"variable": [
|
|
@@ -629,6 +630,7 @@
|
|
|
629
630
|
"样式路径": "stylepath",
|
|
630
631
|
"stylepath": "stylepath",
|
|
631
632
|
"msgnw": "msgnw",
|
|
633
|
+
"#img": "img",
|
|
632
634
|
"#related": "related"
|
|
633
635
|
},
|
|
634
636
|
{
|
package/dist/index.d.ts
CHANGED
|
@@ -48,4 +48,4 @@ export = Parser;
|
|
|
48
48
|
export default Parser;
|
|
49
49
|
export type { Config, ConfigData, LintError, TokenTypes, LanguageService, QuickFixData, };
|
|
50
50
|
export type * from './internal';
|
|
51
|
-
declare global { type
|
|
51
|
+
declare global { type WikiParserAcceptable = Record<string, any>; }
|
package/dist/lib/document.js
CHANGED
|
@@ -111,7 +111,7 @@ class EmbeddedDocument {
|
|
|
111
111
|
this.languageId = id;
|
|
112
112
|
this.lineCount = root.getLines().length;
|
|
113
113
|
this.#root = root;
|
|
114
|
-
this.#content =
|
|
114
|
+
this.#content = token.toString();
|
|
115
115
|
this.#offset = token.getAbsoluteIndex();
|
|
116
116
|
this.pre = pre;
|
|
117
117
|
this.#post = post;
|
package/dist/lib/element.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { AstNode } from './node';
|
|
2
2
|
import type { LintError } from '../base';
|
|
3
|
+
import type { ElementLike } from '../mixin/elementLike';
|
|
3
4
|
import type { AstNodes, Token } from '../internal';
|
|
4
5
|
export interface CaretPosition {
|
|
5
6
|
readonly offsetNode: AstNodes;
|
|
6
7
|
readonly offset: number;
|
|
7
8
|
}
|
|
9
|
+
export interface AstElement extends AstNode, ElementLike {
|
|
10
|
+
}
|
|
8
11
|
/**
|
|
9
12
|
* HTMLElement-like
|
|
10
13
|
*
|
|
11
14
|
* 类似HTMLElement
|
|
12
15
|
*/
|
|
13
16
|
export declare abstract class AstElement extends AstNode {
|
|
14
|
-
#private;
|
|
15
17
|
readonly name?: string;
|
|
16
18
|
readonly data: undefined;
|
|
17
19
|
/** number of child nodes / 子节点总数 */
|
|
@@ -44,20 +46,6 @@ export declare abstract class AstElement extends AstNode {
|
|
|
44
46
|
* @param selector selector / 选择器
|
|
45
47
|
*/
|
|
46
48
|
closest<T = Token>(selector: string): T | undefined;
|
|
47
|
-
/**
|
|
48
|
-
* Get the first descendant that matches the selector
|
|
49
|
-
*
|
|
50
|
-
* 符合选择器的第一个后代节点
|
|
51
|
-
* @param selector selector / 选择器
|
|
52
|
-
*/
|
|
53
|
-
querySelector<T = Token>(selector: string): T | undefined;
|
|
54
|
-
/**
|
|
55
|
-
* Get all descendants that match the selector
|
|
56
|
-
*
|
|
57
|
-
* 符合选择器的所有后代节点
|
|
58
|
-
* @param selector selector / 选择器
|
|
59
|
-
*/
|
|
60
|
-
querySelectorAll<T = Token>(selector: string): T[];
|
|
61
49
|
/**
|
|
62
50
|
* Insert a batch of child nodes at the end
|
|
63
51
|
*
|
package/dist/lib/element.js
CHANGED
|
@@ -1,272 +1,267 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
2
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
37
|
exports.AstElement = void 0;
|
|
4
38
|
const string_1 = require("../util/string");
|
|
5
39
|
const debug_1 = require("../util/debug");
|
|
6
40
|
const selector_1 = require("../parser/selector");
|
|
7
41
|
const node_1 = require("./node");
|
|
42
|
+
const elementLike_1 = require("../mixin/elementLike");
|
|
8
43
|
/**
|
|
9
44
|
* HTMLElement-like
|
|
10
45
|
*
|
|
11
46
|
* 类似HTMLElement
|
|
12
47
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
48
|
+
let AstElement = (() => {
|
|
49
|
+
let _classDecorators = [elementLike_1.elementLike];
|
|
50
|
+
let _classDescriptor;
|
|
51
|
+
let _classExtraInitializers = [];
|
|
52
|
+
let _classThis;
|
|
53
|
+
let _classSuper = node_1.AstNode;
|
|
54
|
+
var AstElement = class extends _classSuper {
|
|
55
|
+
static { _classThis = this; }
|
|
56
|
+
static {
|
|
57
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
58
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
59
|
+
AstElement = _classThis = _classDescriptor.value;
|
|
60
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
61
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
62
|
+
}
|
|
63
|
+
/** number of child nodes / 子节点总数 */
|
|
64
|
+
get length() {
|
|
65
|
+
return this.childNodes.length;
|
|
66
|
+
}
|
|
67
|
+
/** @private */
|
|
68
|
+
text(separator) {
|
|
69
|
+
return (0, string_1.text)(this.childNodes, separator);
|
|
70
|
+
}
|
|
29
71
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
72
|
+
* Merge adjacent text child nodes
|
|
73
|
+
*
|
|
74
|
+
* 合并相邻的文本子节点
|
|
32
75
|
*/
|
|
33
|
-
|
|
34
|
-
childNodes.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
76
|
+
normalize() {
|
|
77
|
+
const childNodes = this.getChildNodes();
|
|
78
|
+
/**
|
|
79
|
+
* 移除子节点
|
|
80
|
+
* @param i 移除位置
|
|
81
|
+
*/
|
|
82
|
+
const remove = (i) => {
|
|
83
|
+
childNodes.splice(i, 1);
|
|
84
|
+
childNodes[i - 1]?.setAttribute('nextSibling', childNodes[i]);
|
|
85
|
+
childNodes[i]?.setAttribute('previousSibling', childNodes[i - 1]);
|
|
86
|
+
};
|
|
87
|
+
for (let i = childNodes.length - 1; i >= 0; i--) {
|
|
88
|
+
const { type, data } = childNodes[i];
|
|
89
|
+
if (type !== 'text' || childNodes.length === 1 || this.getGaps(i - (i && 1))) {
|
|
90
|
+
//
|
|
91
|
+
}
|
|
92
|
+
else if (data === '') {
|
|
93
|
+
remove(i);
|
|
94
|
+
}
|
|
45
95
|
}
|
|
96
|
+
this.setAttribute('childNodes', childNodes);
|
|
46
97
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
removeAt(i) {
|
|
56
|
-
return (0, debug_1.setChildNodes)(this, i, 1)[0];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Insert a child node
|
|
60
|
-
*
|
|
61
|
-
* 插入子节点
|
|
62
|
-
* @param node node to be inserted / 待插入的子节点
|
|
63
|
-
* @param i position to be inserted at / 插入位置
|
|
64
|
-
*/
|
|
65
|
-
insertAt(node, i = this.length) {
|
|
66
|
-
(0, debug_1.setChildNodes)(this, i, 0, [node]);
|
|
67
|
-
return node;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Get the closest ancestor node that matches the selector
|
|
71
|
-
*
|
|
72
|
-
* 最近的符合选择器的祖先节点
|
|
73
|
-
* @param selector selector / 选择器
|
|
74
|
-
*/
|
|
75
|
-
closest(selector) {
|
|
76
|
-
const condition = (0, selector_1.getCondition)(selector, this);
|
|
77
|
-
let { parentNode } = this;
|
|
78
|
-
while (parentNode) {
|
|
79
|
-
if (condition(parentNode)) {
|
|
80
|
-
return parentNode;
|
|
81
|
-
}
|
|
82
|
-
({ parentNode } = parentNode);
|
|
98
|
+
/**
|
|
99
|
+
* Remove a child node
|
|
100
|
+
*
|
|
101
|
+
* 移除子节点
|
|
102
|
+
* @param i position of the child node / 移除位置
|
|
103
|
+
*/
|
|
104
|
+
removeAt(i) {
|
|
105
|
+
return (0, debug_1.setChildNodes)(this, i, 1)[0];
|
|
83
106
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Insert a child node
|
|
109
|
+
*
|
|
110
|
+
* 插入子节点
|
|
111
|
+
* @param node node to be inserted / 待插入的子节点
|
|
112
|
+
* @param i position to be inserted at / 插入位置
|
|
113
|
+
*/
|
|
114
|
+
insertAt(node, i = this.length) {
|
|
115
|
+
(0, debug_1.setChildNodes)(this, i, 0, [node]);
|
|
116
|
+
return node;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the closest ancestor node that matches the selector
|
|
120
|
+
*
|
|
121
|
+
* 最近的符合选择器的祖先节点
|
|
122
|
+
* @param selector selector / 选择器
|
|
123
|
+
*/
|
|
124
|
+
closest(selector) {
|
|
125
|
+
const condition = (0, selector_1.getCondition)(selector, this);
|
|
126
|
+
let { parentNode } = this;
|
|
127
|
+
while (parentNode) {
|
|
128
|
+
if (condition(parentNode)) {
|
|
129
|
+
return parentNode;
|
|
130
|
+
}
|
|
131
|
+
({ parentNode } = parentNode);
|
|
101
132
|
}
|
|
133
|
+
return undefined;
|
|
102
134
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
* 符合条件的所有后代节点
|
|
117
|
-
* @param condition 条件
|
|
118
|
-
*/
|
|
119
|
-
#getElementsBy(condition) {
|
|
120
|
-
let descendants = [];
|
|
121
|
-
for (const child of this.childNodes) {
|
|
122
|
-
if (child.type === 'text') {
|
|
123
|
-
continue;
|
|
135
|
+
/**
|
|
136
|
+
* Insert a batch of child nodes at the end
|
|
137
|
+
*
|
|
138
|
+
* 在末尾批量插入子节点
|
|
139
|
+
* @param elements nodes to be inserted / 插入节点
|
|
140
|
+
*/
|
|
141
|
+
append(...elements) {
|
|
142
|
+
this.safeAppend(elements);
|
|
143
|
+
}
|
|
144
|
+
/** @private */
|
|
145
|
+
safeAppend(elements) {
|
|
146
|
+
for (const element of elements) {
|
|
147
|
+
this.insertAt(element);
|
|
124
148
|
}
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Replace all child nodes
|
|
152
|
+
*
|
|
153
|
+
* 批量替换子节点
|
|
154
|
+
* @param elements nodes to be inserted / 新的子节点
|
|
155
|
+
*/
|
|
156
|
+
replaceChildren(...elements) {
|
|
157
|
+
this.safeReplaceChildren(elements);
|
|
158
|
+
}
|
|
159
|
+
/** @private */
|
|
160
|
+
safeReplaceChildren(elements) {
|
|
161
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
162
|
+
this.removeAt(i);
|
|
127
163
|
}
|
|
128
|
-
|
|
164
|
+
this.safeAppend(elements);
|
|
129
165
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
* Insert a batch of child nodes at the end
|
|
144
|
-
*
|
|
145
|
-
* 在末尾批量插入子节点
|
|
146
|
-
* @param elements nodes to be inserted / 插入节点
|
|
147
|
-
*/
|
|
148
|
-
append(...elements) {
|
|
149
|
-
this.safeAppend(elements);
|
|
150
|
-
}
|
|
151
|
-
/** @private */
|
|
152
|
-
safeAppend(elements) {
|
|
153
|
-
for (const element of elements) {
|
|
154
|
-
this.insertAt(element);
|
|
166
|
+
/**
|
|
167
|
+
* Modify the text child node
|
|
168
|
+
*
|
|
169
|
+
* 修改文本子节点
|
|
170
|
+
* @param str new text / 新文本
|
|
171
|
+
* @param i position of the text child node / 子节点位置
|
|
172
|
+
*/
|
|
173
|
+
setText(str, i = 0) {
|
|
174
|
+
i += i < 0 ? this.length : 0;
|
|
175
|
+
const oldText = this.childNodes[i];
|
|
176
|
+
const { data } = oldText;
|
|
177
|
+
oldText.replaceData(str);
|
|
178
|
+
return data;
|
|
155
179
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
*
|
|
160
|
-
* 批量替换子节点
|
|
161
|
-
* @param elements nodes to be inserted / 新的子节点
|
|
162
|
-
*/
|
|
163
|
-
replaceChildren(...elements) {
|
|
164
|
-
this.safeReplaceChildren(elements);
|
|
165
|
-
}
|
|
166
|
-
/** @private */
|
|
167
|
-
safeReplaceChildren(elements) {
|
|
168
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
169
|
-
this.removeAt(i);
|
|
180
|
+
/** @private */
|
|
181
|
+
toString(skip, separator = '') {
|
|
182
|
+
return this.childNodes.map(child => child.toString(skip)).join(separator);
|
|
170
183
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
i += i < 0 ? this.length : 0;
|
|
182
|
-
const oldText = this.childNodes[i];
|
|
183
|
-
const { data } = oldText;
|
|
184
|
-
oldText.replaceData(str);
|
|
185
|
-
return data;
|
|
186
|
-
}
|
|
187
|
-
/** @private */
|
|
188
|
-
toString(skip, separator = '') {
|
|
189
|
-
return this.childNodes.map(child => child.toString(skip)).join(separator);
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Get the caret position from the character index
|
|
193
|
-
*
|
|
194
|
-
* 找到给定位置
|
|
195
|
-
* @param index character index / 位置
|
|
196
|
-
*/
|
|
197
|
-
caretPositionFromIndex(index) {
|
|
198
|
-
LSP: { // eslint-disable-line no-unused-labels
|
|
199
|
-
if (index === undefined) {
|
|
200
|
-
return undefined;
|
|
201
|
-
}
|
|
202
|
-
const { length } = this.toString();
|
|
203
|
-
if (index > length || index < -length) {
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
index += index < 0 ? length : 0;
|
|
207
|
-
let self = this, acc = 0, start = 0;
|
|
208
|
-
while (self.type !== 'text') {
|
|
209
|
-
const { childNodes } = self;
|
|
210
|
-
acc += self.getAttribute('padding');
|
|
211
|
-
for (let i = 0; acc <= index && i < childNodes.length; i++) {
|
|
212
|
-
const cur = childNodes[i], { nextSibling } = cur, str = cur.toString(), l = str.length;
|
|
213
|
-
cur.setAttribute('aIndex', acc);
|
|
214
|
-
acc += l;
|
|
215
|
-
// 优先选择靠前的非文本兄弟节点,但永不进入假节点
|
|
216
|
-
if (acc > index
|
|
217
|
-
|| acc === index && l > 0 && (!nextSibling
|
|
218
|
-
|| nextSibling.type === 'text'
|
|
219
|
-
|| cur.type !== 'text' && (str.trim() || !nextSibling.toString().trim()))) {
|
|
220
|
-
self = cur;
|
|
221
|
-
acc -= l;
|
|
222
|
-
start = acc;
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
acc += self.getGaps(i);
|
|
184
|
+
/**
|
|
185
|
+
* Get the caret position from the character index
|
|
186
|
+
*
|
|
187
|
+
* 找到给定位置
|
|
188
|
+
* @param index character index / 位置
|
|
189
|
+
*/
|
|
190
|
+
caretPositionFromIndex(index) {
|
|
191
|
+
LSP: { // eslint-disable-line no-unused-labels
|
|
192
|
+
if (index === undefined) {
|
|
193
|
+
return undefined;
|
|
226
194
|
}
|
|
227
|
-
|
|
228
|
-
|
|
195
|
+
const { length } = this.toString();
|
|
196
|
+
if (index > length || index < -length) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
index += index < 0 ? length : 0;
|
|
200
|
+
let self = this, acc = 0, start = 0;
|
|
201
|
+
while (self.type !== 'text') {
|
|
202
|
+
const { childNodes } = self;
|
|
203
|
+
acc += self.getAttribute('padding');
|
|
204
|
+
for (let i = 0; acc <= index && i < childNodes.length; i++) {
|
|
205
|
+
const cur = childNodes[i], { nextSibling } = cur, str = cur.toString(), l = str.length;
|
|
206
|
+
cur.setAttribute('aIndex', acc);
|
|
207
|
+
acc += l;
|
|
208
|
+
// 优先选择靠前的非文本兄弟节点,但永不进入假节点
|
|
209
|
+
if (acc > index
|
|
210
|
+
|| acc === index && l > 0 && (!nextSibling
|
|
211
|
+
|| nextSibling.type === 'text'
|
|
212
|
+
|| cur.type !== 'text' && (str.trim() || !nextSibling.toString().trim()))) {
|
|
213
|
+
self = cur;
|
|
214
|
+
acc -= l;
|
|
215
|
+
start = acc;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
acc += self.getGaps(i);
|
|
219
|
+
}
|
|
220
|
+
if (self.childNodes === childNodes) {
|
|
221
|
+
return { offsetNode: self, offset: index - start };
|
|
222
|
+
}
|
|
229
223
|
}
|
|
224
|
+
return { offsetNode: self, offset: index - start };
|
|
230
225
|
}
|
|
231
|
-
return { offsetNode: self, offset: index - start };
|
|
232
226
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Get the closest ancestor element from the character index
|
|
229
|
+
*
|
|
230
|
+
* 找到给定位置所在的最内层非文本节点
|
|
231
|
+
* @param index character index / 位置
|
|
232
|
+
*/
|
|
233
|
+
elementFromIndex(index) {
|
|
234
|
+
LSP: { // eslint-disable-line no-unused-labels
|
|
235
|
+
const node = this.caretPositionFromIndex(index)?.offsetNode;
|
|
236
|
+
return node?.type === 'text' ? node.parentNode : node;
|
|
237
|
+
}
|
|
244
238
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Get the closest ancestor element from the position
|
|
241
|
+
*
|
|
242
|
+
* 找到给定位置所在的最内层非文本节点
|
|
243
|
+
* @param x column number / 列数
|
|
244
|
+
* @param y line number / 行数
|
|
245
|
+
*/
|
|
246
|
+
elementFromPoint(x, y) {
|
|
247
|
+
// eslint-disable-next-line no-unused-labels
|
|
248
|
+
LSP: return this.elementFromIndex(this.indexFromPos(y, x));
|
|
249
|
+
}
|
|
250
|
+
/** @private */
|
|
251
|
+
lint(start = this.getAbsoluteIndex(), re) {
|
|
252
|
+
const errors = [];
|
|
253
|
+
for (let i = 0, cur = start + this.getAttribute('padding'); i < this.length; i++) {
|
|
254
|
+
const child = this.childNodes[i];
|
|
255
|
+
child.setAttribute('aIndex', cur);
|
|
256
|
+
const childErrors = child.lint(cur, re);
|
|
257
|
+
if (childErrors.length > 0) {
|
|
258
|
+
errors.push(...childErrors);
|
|
259
|
+
}
|
|
260
|
+
cur += child.toString().length + this.getGaps(i);
|
|
266
261
|
}
|
|
267
|
-
|
|
262
|
+
return errors;
|
|
268
263
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
264
|
+
};
|
|
265
|
+
return AstElement = _classThis;
|
|
266
|
+
})();
|
|
272
267
|
exports.AstElement = AstElement;
|