wikiplus-highlight 2.8.1 → 2.13.1
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/README.md +20 -5
- package/dist/main.min.js +1 -1
- package/dist/main.min.js.map +1 -1
- package/fold.js +104 -38
- package/i18n/en.json +6 -3
- package/i18n/zh-hans.json +6 -3
- package/i18n/zh-hant.json +7 -4
- package/jsconfig.json +3 -0
- package/main.js +245 -177
- package/matchtags.js +45 -51
- package/package.json +2 -1
- package/search.js +14 -35
package/matchtags.js
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
return /\b(?:mw-(?:html|ext)tag-)?bracket\b/.test(type);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
/** Jump to the start of the next line */
|
|
43
43
|
nextLine() {
|
|
44
44
|
if (this.line >= this.max) {
|
|
45
45
|
return;
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
return true;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
/** Jump to the end of the previous line */
|
|
53
53
|
prevLine() {
|
|
54
54
|
if (this.line <= this.min) {
|
|
55
55
|
return;
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
return true;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
/** Jump to the letter after a '>' towards the line end */
|
|
63
63
|
toTagEnd() {
|
|
64
64
|
for (;;) {
|
|
65
65
|
const gt = this.text.indexOf('>', this.ch);
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
/** Jump to a '<' towards the line start */
|
|
78
78
|
toTagStart() {
|
|
79
79
|
for (;;) {
|
|
80
80
|
const lt = this.ch ? this.text.lastIndexOf('<', this.ch - 1) : -1;
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
/** Jump to the start of the last line, or the letter after a ${tagStart} */
|
|
98
98
|
toNextTag() {
|
|
99
99
|
for (;;) {
|
|
100
100
|
tagStart.lastIndex = this.ch;
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
/** Jump to the end of the first line, or a non-bracket '>', or the letter after a tag bracket '>' */
|
|
119
119
|
toPrevTag() {
|
|
120
120
|
for (;;) {
|
|
121
121
|
const gt = this.ch ? this.text.lastIndexOf('>', this.ch - 1) : -1;
|
|
@@ -137,7 +137,10 @@
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* @param {string} tag
|
|
142
|
+
* @returns {CodeMirror.MatchingTag}
|
|
143
|
+
*/
|
|
141
144
|
findMatchingClose(tag) {
|
|
142
145
|
const /** @type {string[]} */ stack = [];
|
|
143
146
|
for (;;) {
|
|
@@ -175,7 +178,10 @@
|
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
|
|
178
|
-
/**
|
|
181
|
+
/**
|
|
182
|
+
* @param {string|undefined} tag
|
|
183
|
+
* @returns {CodeMirror.MatchingTag}
|
|
184
|
+
*/
|
|
179
185
|
findMatchingOpen(tag) {
|
|
180
186
|
const /** @type {string[]} */ stack = [];
|
|
181
187
|
for (;;) {
|
|
@@ -214,36 +220,37 @@
|
|
|
214
220
|
}
|
|
215
221
|
}
|
|
216
222
|
|
|
217
|
-
CodeMirror.defineExtension(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
223
|
+
CodeMirror.defineExtension(
|
|
224
|
+
'findMatchingTag',
|
|
225
|
+
/** @type {function(this: CodeMirror.Editor, CodeMirror.Position): CodeMirror.MatchingTagPair} */
|
|
226
|
+
function(pos) {
|
|
227
|
+
let iter = new Iter(this, pos);
|
|
228
|
+
if (!iter.isTag()) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const end = iter.toTagEnd(),
|
|
232
|
+
to = end && Pos(iter.line, iter.ch);
|
|
233
|
+
const start = end && iter.toTagStart();
|
|
234
|
+
if (!start || cmpPos(iter, pos) > 0) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const tag = start[2].toLowerCase(),
|
|
238
|
+
here = {from: Pos(iter.line, iter.ch), to, tag};
|
|
239
|
+
if (end === 'selfClose' || voidTags.includes(tag)) {
|
|
240
|
+
return {open: here, close: null, at: 'self'};
|
|
241
|
+
}
|
|
233
242
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
if (start[1]) { // closing tag
|
|
244
|
+
return {open: iter.findMatchingOpen(tag), close: here, at: 'close'};
|
|
245
|
+
} // opening tag
|
|
246
|
+
iter = new Iter(this, to);
|
|
247
|
+
return {open: here, close: iter.findMatchingClose(tag), at: 'open'};
|
|
248
|
+
},
|
|
249
|
+
);
|
|
240
250
|
|
|
241
251
|
CodeMirror.defineExtension(
|
|
242
252
|
'findEnclosingTag',
|
|
243
|
-
/**
|
|
244
|
-
* @param {CodeMirror.Position} pos
|
|
245
|
-
* @param {string} tag
|
|
246
|
-
*/
|
|
253
|
+
/** @type {function(this: CodeMirror.Editor, CodeMirror.Position, string): CodeMirror.MatchingTagPair} */
|
|
247
254
|
function(pos, tag) {
|
|
248
255
|
const iter = new Iter(this, pos);
|
|
249
256
|
const open = iter.findMatchingOpen(tag);
|
|
@@ -258,12 +265,7 @@
|
|
|
258
265
|
},
|
|
259
266
|
);
|
|
260
267
|
|
|
261
|
-
|
|
262
|
-
* Used by addon/edit/closetag.js
|
|
263
|
-
* @param {CodeMirror.Editor} cm
|
|
264
|
-
* @param {CodeMirror.Position} pos
|
|
265
|
-
* @param {string} name
|
|
266
|
-
*/
|
|
268
|
+
// Used by addon/edit/closetag.js
|
|
267
269
|
CodeMirror.scanForClosingTag = function(cm, pos, name) {
|
|
268
270
|
const iter = new Iter(cm, pos);
|
|
269
271
|
return iter.findMatchingClose(name);
|
|
@@ -280,7 +282,7 @@
|
|
|
280
282
|
}
|
|
281
283
|
});
|
|
282
284
|
|
|
283
|
-
/** @param {CodeMirror.
|
|
285
|
+
/** @param {CodeMirror.EditorWithMatchingTags} cm */
|
|
284
286
|
function clear(cm) {
|
|
285
287
|
if (cm.state.tagHit) {
|
|
286
288
|
cm.state.tagHit.clear();
|
|
@@ -292,22 +294,14 @@
|
|
|
292
294
|
cm.state.tagOther = null;
|
|
293
295
|
}
|
|
294
296
|
|
|
295
|
-
/** @param {CodeMirror.
|
|
297
|
+
/** @param {CodeMirror.EditorWithMatchingTags} cm */
|
|
296
298
|
function doMatchTags(cm) {
|
|
297
299
|
cm.operation(() => {
|
|
298
300
|
clear(cm);
|
|
299
301
|
if (cm.somethingSelected()) {
|
|
300
302
|
return;
|
|
301
303
|
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* @typedef {object} matchingTag
|
|
305
|
-
* @property {string} at
|
|
306
|
-
* @property {CodeMirror.MarkerRange} open
|
|
307
|
-
* @property {CodeMirror.MarkerRange} close
|
|
308
|
-
*/
|
|
309
|
-
|
|
310
|
-
const /** @type {matchingTag}} */ match = cm.findMatchingTag(cm.getCursor());
|
|
304
|
+
const match = cm.findMatchingTag(cm.getCursor());
|
|
311
305
|
if (!match) {
|
|
312
306
|
return;
|
|
313
307
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikiplus-highlight",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.1",
|
|
4
4
|
"description": "A plugin for the MediaWiki front-end add-on \"Wikiplus\"",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"scripts": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"homepage": "https://github.com/bhsd-harry/Wikiplus-highlight#readme",
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"eslint": "^8.8.0",
|
|
26
|
+
"types-mediawiki": "^1.2.0",
|
|
26
27
|
"uglify-js": "^3.15.5"
|
|
27
28
|
}
|
|
28
29
|
}
|
package/search.js
CHANGED
|
@@ -6,10 +6,7 @@
|
|
|
6
6
|
(() => {
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* @param {string} key
|
|
11
|
-
* @returns {string}
|
|
12
|
-
*/
|
|
9
|
+
/** @param {string} key */
|
|
13
10
|
const msg = key => mw.msg(`wphl-${key}`);
|
|
14
11
|
|
|
15
12
|
// Prepare elements
|
|
@@ -46,24 +43,21 @@
|
|
|
46
43
|
text: msg('addon-search'),
|
|
47
44
|
});
|
|
48
45
|
|
|
49
|
-
const
|
|
50
|
-
const /** @type {
|
|
46
|
+
const escapeRegExp = mw.util.escapeRegExp || mw.RegExp.escape;
|
|
47
|
+
const /** @type {CodeMirror.Mode<undefined>} */ overlay = {token: () => {}};
|
|
51
48
|
|
|
52
49
|
/**
|
|
53
50
|
* 根据搜索字符串生成高亮
|
|
54
51
|
* @param {string|RegExp} str
|
|
55
52
|
*/
|
|
56
53
|
const token = str => {
|
|
57
|
-
|
|
58
|
-
if (typeof str === 'string') {
|
|
59
|
-
initial = RegExp(`[^${escapeRegExp(str[0])}]`, 'i');
|
|
60
|
-
}
|
|
54
|
+
const initial = typeof str === 'string' ? RegExp(`[^${escapeRegExp(str[0])}]`, 'i') : null;
|
|
61
55
|
return /** @param {CodeMirror.StringStream} stream */ stream => {
|
|
62
56
|
if (stream.match(str, true, true)) {
|
|
63
57
|
return 'search';
|
|
64
58
|
}
|
|
65
59
|
stream.next();
|
|
66
|
-
if (
|
|
60
|
+
if (initial) {
|
|
67
61
|
stream.eatWhile(initial);
|
|
68
62
|
}
|
|
69
63
|
};
|
|
@@ -74,17 +68,9 @@
|
|
|
74
68
|
$search.css('background-color', '').off('input', onInput);
|
|
75
69
|
};
|
|
76
70
|
|
|
77
|
-
/**
|
|
78
|
-
* @typedef {object} SearchCursor
|
|
79
|
-
* @property {() => boolean} findNext
|
|
80
|
-
* @property {() => boolean} findPrevious
|
|
81
|
-
* @property {() => CodeMirror.Position} from
|
|
82
|
-
* @property {() => CodeMirror.Position} to
|
|
83
|
-
*/
|
|
84
|
-
|
|
85
71
|
// keyboard event handler of $search
|
|
86
72
|
let /** @type {string|RegExp} */ lastPtn,
|
|
87
|
-
/** @type {SearchCursor} */ cursor;
|
|
73
|
+
/** @type {CodeMirror.SearchCursor} */ cursor;
|
|
88
74
|
/**
|
|
89
75
|
* @param {CodeMirror.Editor} cm
|
|
90
76
|
* @param {boolean} dir
|
|
@@ -95,7 +81,7 @@
|
|
|
95
81
|
return;
|
|
96
82
|
}
|
|
97
83
|
|
|
98
|
-
if (/^\/.+\/i?$/.test(ptn)) {
|
|
84
|
+
if (typeof ptn === 'string' && /^\/.+\/i?$/.test(ptn)) {
|
|
99
85
|
ptn = ptn.endsWith('i')
|
|
100
86
|
? RegExp(ptn.slice(1, -2), 'i')
|
|
101
87
|
: RegExp(ptn.slice(1, -1));
|
|
@@ -107,8 +93,7 @@
|
|
|
107
93
|
lastPtn = ptn;
|
|
108
94
|
cursor = cm.getSearchCursor(ptn, cm.getCursor(), {caseFold: true});
|
|
109
95
|
}
|
|
110
|
-
|
|
111
|
-
let result = cursor[method]();
|
|
96
|
+
let result = dir ? cursor.findNext() : cursor.findPreviouse();
|
|
112
97
|
if (!result) {
|
|
113
98
|
if (dir) {
|
|
114
99
|
cursor = cm.getSearchCursor(ptn, {line: 0, ch: 0}, {caseFold: true});
|
|
@@ -117,7 +102,7 @@
|
|
|
117
102
|
lastCh = cm.getLine(lastLine).length;
|
|
118
103
|
cursor = cm.getSearchCursor(ptn, {line: lastLine, ch: lastCh}, {caseFold: true});
|
|
119
104
|
}
|
|
120
|
-
result = cursor
|
|
105
|
+
result = dir ? cursor.findNext() : cursor.findPreviouse();
|
|
121
106
|
}
|
|
122
107
|
if (result) {
|
|
123
108
|
const from = cursor.from(),
|
|
@@ -147,16 +132,14 @@
|
|
|
147
132
|
lastPtn = '';
|
|
148
133
|
};
|
|
149
134
|
|
|
150
|
-
/** @param {CodeMirror.Editor} doc */
|
|
151
135
|
CodeMirror.commands.findForward = doc => {
|
|
152
136
|
findNext(doc, true);
|
|
153
137
|
};
|
|
154
|
-
/** @param {CodeMirror.Editor} doc */
|
|
155
138
|
CodeMirror.commands.findBackward = doc => {
|
|
156
139
|
findNext(doc, false);
|
|
157
140
|
};
|
|
158
141
|
|
|
159
|
-
const
|
|
142
|
+
const {name} = $.client.profile(),
|
|
160
143
|
focus = name === 'safari'
|
|
161
144
|
? /** @param {CodeMirror.Editor} cm */ cm => {
|
|
162
145
|
cm.focus();
|
|
@@ -193,14 +176,10 @@
|
|
|
193
176
|
reset(cm);
|
|
194
177
|
}
|
|
195
178
|
});
|
|
196
|
-
cm.addKeyMap(
|
|
197
|
-
'Ctrl-F': findNew,
|
|
198
|
-
'Cmd-F': findNew,
|
|
199
|
-
|
|
200
|
-
'Cmd-G': 'findForward',
|
|
201
|
-
'Shift-Ctrl-G': 'findBackward',
|
|
202
|
-
'Shift-Cmd-G': 'findBackward',
|
|
203
|
-
});
|
|
179
|
+
cm.addKeyMap(CodeMirror.keyMap.default === CodeMirror.keyMap.pcDefault
|
|
180
|
+
? {'Ctrl-F': findNew, 'Ctrl-G': 'findForward', 'Shift-Ctrl-G': 'findBackward'}
|
|
181
|
+
: {'Cmd-F': findNew, 'Cmd-G': 'findForward', 'Shift-Cmd-G': 'findBackward'},
|
|
182
|
+
);
|
|
204
183
|
});
|
|
205
184
|
|
|
206
185
|
mw.loader.addStyleTag(
|