wikiplus-highlight 2.60.3 → 3.0.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 +29 -46
- package/dist/main.js +110 -0
- package/package.json +25 -15
- package/styles.css +0 -138
- package/dist/main.min.js +0 -8
- package/dist/main.min.js.map +0 -1
- package/fold.js +0 -264
- package/i18n/en.json +0 -35
- package/i18n/ka.json +0 -35
- package/i18n/zh-hans.json +0 -35
- package/i18n/zh-hant.json +0 -35
- package/lint.js +0 -200
- package/main.js +0 -1006
- package/matchtags.js +0 -324
- package/search.js +0 -258
package/fold.js
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Bhsd <https://github.com/bhsd-harry>
|
|
3
|
-
* @license GPL-3.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
(() => {
|
|
7
|
-
'use strict';
|
|
8
|
-
|
|
9
|
-
const {Pos, cmpPos, Init} = CodeMirror;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 只用于`title`属性的消息,不存在时fallback到键名
|
|
13
|
-
* @param {string} key 消息键
|
|
14
|
-
* @param {string|undefined} argKey 额外参数的消息键
|
|
15
|
-
* @returns {string}
|
|
16
|
-
*/
|
|
17
|
-
const msg = (key, argKey) => {
|
|
18
|
-
const fullKey = `wphl-${key}`,
|
|
19
|
-
message = (argKey === undefined ? mw.msg(fullKey) : mw.msg(fullKey, msg(argKey)))
|
|
20
|
-
.replace(/</gu, '<').replace(/>/gu, '>');
|
|
21
|
-
return message === `⧼${fullKey}⧽` ? key : message;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const braceRegex = /\bmw-template-bracket\b/u,
|
|
25
|
-
$placeholder = $('<span>', {text: '\u22ef', class: 'CodeMirror-widget-unfold'}),
|
|
26
|
-
$delimiter = $('<span>', {text: '|', class: 'cm-mw-template-delimiter'}),
|
|
27
|
-
$tt = $('<div>', {class: 'CodeMirror-tooltip', text: '\uff0d'}).click(
|
|
28
|
-
/** @this {HTMLDivElement} */
|
|
29
|
-
function() {
|
|
30
|
-
const /** @type {CodeMirror.FoldData} */ {cm, from, to, type} = $(this).fadeOut('fast').data(),
|
|
31
|
-
notTag = type === 'template' || type === 'comment',
|
|
32
|
-
$clonedPlaceholder = $placeholder.clone()
|
|
33
|
-
.attr('title', msg('unfold', notTag ? `fold-${type}` : `<${type}>`)),
|
|
34
|
-
mark = cm.markText(from, to, {
|
|
35
|
-
replacedWith: type === 'template'
|
|
36
|
-
? $('<span>', {html: [$delimiter.clone(), $clonedPlaceholder]})[0]
|
|
37
|
-
: $clonedPlaceholder[0],
|
|
38
|
-
selectLeft: type === 'template',
|
|
39
|
-
selectRight: false,
|
|
40
|
-
_isFold: true,
|
|
41
|
-
});
|
|
42
|
-
$clonedPlaceholder.click(() => {
|
|
43
|
-
mark.clear();
|
|
44
|
-
});
|
|
45
|
-
},
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 隐藏tooltip
|
|
50
|
-
* @param {JQuery<HTMLElement>} $tooltip tooltip
|
|
51
|
-
*/
|
|
52
|
-
const hideTooltip = $tooltip => {
|
|
53
|
-
let timeout = -1,
|
|
54
|
-
executeTime = 0;
|
|
55
|
-
return /** @param {number} wait */ (wait, update = true) => {
|
|
56
|
-
if (update || executeTime - Date.now() > wait) {
|
|
57
|
-
clearTimeout(timeout);
|
|
58
|
-
timeout = setTimeout(() => {
|
|
59
|
-
$tooltip.fadeOut('fast');
|
|
60
|
-
timeout = -1;
|
|
61
|
-
}, wait);
|
|
62
|
-
executeTime = Date.now() + wait;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 搜索括号
|
|
69
|
-
* @param {CodeMirror.Editor} cm CodeMirror实例
|
|
70
|
-
* @param {CodeMirror.Position} where 当前位置
|
|
71
|
-
* @param {1|-1} dir 搜索方向
|
|
72
|
-
* @returns {CodeMirror.MarkerRange}
|
|
73
|
-
*/
|
|
74
|
-
const scanForDelimiterAndBracket = (cm, where, dir) => {
|
|
75
|
-
const maxScanLen = 10000,
|
|
76
|
-
maxScanLines = 1000,
|
|
77
|
-
{line, ch} = where,
|
|
78
|
-
lineEnd = dir > 0
|
|
79
|
-
? Math.min(cm.lastLine() + 1, line + maxScanLines)
|
|
80
|
-
: Math.max(cm.firstLine() - 1, line - maxScanLines);
|
|
81
|
-
let stack = 0,
|
|
82
|
-
hasDelimiter = dir < 0,
|
|
83
|
-
/** @type {CodeMirror.Position} */ delimiter;
|
|
84
|
-
for (let {line: l} = where; l !== lineEnd; l += dir) {
|
|
85
|
-
const curLine = cm.getLine(l);
|
|
86
|
-
if (!curLine) {
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
const {length} = curLine;
|
|
90
|
-
if (length > maxScanLen) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
const end = dir > 0 ? length : -1;
|
|
94
|
-
let pos = dir > 0 ? 0 : length - 1;
|
|
95
|
-
if (l === line) {
|
|
96
|
-
pos = ch - (dir > 0 ? 0 : 1); // `dir = 1`时不包含当前字符,`dir = -1`时包含当前字符
|
|
97
|
-
}
|
|
98
|
-
for (; pos !== end; pos += dir) {
|
|
99
|
-
const char = curLine.charAt(pos);
|
|
100
|
-
if (!hasDelimiter && /[^\s|]/u.test(char)) {
|
|
101
|
-
delimiter = Pos(l, pos + 1);
|
|
102
|
-
}
|
|
103
|
-
if (!(hasDelimiter ? /[{}]/u : /[{}|]/u).test(char)) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
const type = cm.getTokenTypeAt(Pos(l, pos + 1)) || '';
|
|
107
|
-
if (char === '|' && stack === 0 && /\bmw-template-delimiter\b/u.test(type)) {
|
|
108
|
-
hasDelimiter = true;
|
|
109
|
-
} else if (char === '|' || !braceRegex.test(type)) {
|
|
110
|
-
continue;
|
|
111
|
-
} else if (dir > 0 && char === '{' || dir < 0 && char === '}') {
|
|
112
|
-
stack++;
|
|
113
|
-
} else if (stack > 0) {
|
|
114
|
-
stack--;
|
|
115
|
-
} else {
|
|
116
|
-
return {from: hasDelimiter && delimiter, to: Pos(l, pos + (dir > 0 ? 0 : 1))};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return {};
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 搜索模板
|
|
125
|
-
* @param {CodeMirror.Editor} cm CodeMirror实例
|
|
126
|
-
* @param {CodeMirror.Position} cursor 当前位置
|
|
127
|
-
* @returns {CodeMirror.MarkerRange}
|
|
128
|
-
*/
|
|
129
|
-
const findEnclosingTemplate = (cm, cursor) => {
|
|
130
|
-
const type = cm.getTokenTypeAt(cursor) || '';
|
|
131
|
-
if (!/\bmw-template\d*(?:-ext\d*)?(?:-link\d*)?-ground\b/u.test(type)
|
|
132
|
-
|| /\bmw-template-(?:bracket|name)\b/u.test(type)
|
|
133
|
-
) {
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
const {to: bracket} = scanForDelimiterAndBracket(cm, cursor, -1);
|
|
137
|
-
if (bracket) {
|
|
138
|
-
const {from, to} = scanForDelimiterAndBracket(cm, bracket, 1);
|
|
139
|
-
return typeof from === 'object' && (from.line < to.line || from.ch < to.ch - 2) ? {from, to} : undefined;
|
|
140
|
-
}
|
|
141
|
-
return undefined;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* 搜索注释
|
|
146
|
-
* @param {CodeMirror.Editor} cm CodeMirror实例
|
|
147
|
-
* @param {CodeMirror.Position} cursor 当前位置
|
|
148
|
-
* @returns {CodeMirror.MarkerRange|undefined}
|
|
149
|
-
*/
|
|
150
|
-
const findEnclosingComment = (cm, cursor) => {
|
|
151
|
-
const {type, string, start, end} = cm.getTokenAt(cursor),
|
|
152
|
-
{ch} = cursor;
|
|
153
|
-
if (!/\bmw-comment\b/u.test(type)
|
|
154
|
-
|| string.startsWith('<!--') && ch <= start + 4
|
|
155
|
-
|| string.endsWith('-->') && ch >= end - 3
|
|
156
|
-
) {
|
|
157
|
-
return undefined;
|
|
158
|
-
}
|
|
159
|
-
const index = cm.indexFromPos(cursor),
|
|
160
|
-
text = cm.getValue(),
|
|
161
|
-
fromIndex = text.slice(0, index - 1).search(/<!--(?:(?!-->).)*$/su);
|
|
162
|
-
let toIndex = text.slice(index).indexOf('-->');
|
|
163
|
-
toIndex = toIndex === -1 ? text.length : toIndex + index;
|
|
164
|
-
return {from: cm.posFromIndex(fromIndex + 4), to: cm.posFromIndex(toIndex)};
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* 显示tooltip
|
|
169
|
-
* @param {CodeMirror.EditorFoldable} cm CodeMirror实例
|
|
170
|
-
*/
|
|
171
|
-
const showTooltip = cm => {
|
|
172
|
-
const {state: {fold: {$tooltip, hide}}} = cm;
|
|
173
|
-
cm.operation(() => {
|
|
174
|
-
if (cm.somethingSelected()) {
|
|
175
|
-
hide(500, false);
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const cursor = cm.getCursor();
|
|
179
|
-
let range = findEnclosingComment(cm, cursor),
|
|
180
|
-
type = 'comment';
|
|
181
|
-
if (!range) {
|
|
182
|
-
const template = findEnclosingTemplate(cm, cursor);
|
|
183
|
-
let tags = cm.findEnclosingTag(cursor);
|
|
184
|
-
if (tags && cmpPos(tags.open.to, tags.close.from) === 0) {
|
|
185
|
-
tags = undefined;
|
|
186
|
-
}
|
|
187
|
-
if (!template && !tags) {
|
|
188
|
-
hide(500, false);
|
|
189
|
-
return;
|
|
190
|
-
} else if (!tags || template && cmpPos(template.from, tags.open.to) > 0) {
|
|
191
|
-
range = template;
|
|
192
|
-
type = 'template';
|
|
193
|
-
} else {
|
|
194
|
-
range = {from: tags.open.to, to: tags.close.from};
|
|
195
|
-
type = tags.open.tag;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
const {top, left} = cm.charCoords(cursor, 'local'),
|
|
199
|
-
height = $tooltip.outerHeight(),
|
|
200
|
-
notTag = type === 'template' || type === 'comment';
|
|
201
|
-
$tooltip.attr('title', msg('fold', notTag ? `fold-${type}` : `<${type}>`))
|
|
202
|
-
.toggleClass('cm-mw-htmltag-name', !notTag)
|
|
203
|
-
.toggleClass('cm-mw-template-name', type === 'template')
|
|
204
|
-
.toggleClass('cm-mw-comment', type === 'comment')
|
|
205
|
-
.css({top: top > height ? top - height : top + 17, left})
|
|
206
|
-
.data({...range, type})
|
|
207
|
-
.show();
|
|
208
|
-
hide(5000);
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
CodeMirror.defineExtension(
|
|
213
|
-
'scanForDelimiterAndBracket',
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* @this {CodeMirror.Editor}
|
|
217
|
-
* @param {CodeMirror.Position} where
|
|
218
|
-
* @param {1|-1} dir
|
|
219
|
-
*/
|
|
220
|
-
function(where, dir) {
|
|
221
|
-
return scanForDelimiterAndBracket(this, where || this.getCursor(), dir || 1);
|
|
222
|
-
},
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
CodeMirror.defineExtension(
|
|
226
|
-
'findEnclosingTemplate',
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* @this {CodeMirror.Editor}
|
|
230
|
-
* @param {CodeMirror.Position} pos
|
|
231
|
-
*/
|
|
232
|
-
function(pos) {
|
|
233
|
-
return findEnclosingTemplate(this, pos || this.getCursor());
|
|
234
|
-
},
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
CodeMirror.defineExtension(
|
|
238
|
-
'findEnclosingComment',
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* @this {CodeMirror.Editor}
|
|
242
|
-
* @param {CodeMirror.Position} pos
|
|
243
|
-
*/
|
|
244
|
-
function(pos) {
|
|
245
|
-
return findEnclosingComment(this, pos || this.getCursor());
|
|
246
|
-
},
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
CodeMirror.defineOption('fold', false, (/** @type {CodeMirror.EditorFoldable} */ cm, val, old) => {
|
|
250
|
-
if (old && old !== Init) {
|
|
251
|
-
cm.off('cursorActivity', showTooltip);
|
|
252
|
-
if (cm.state.fold) {
|
|
253
|
-
cm.state.fold.$tooltip.remove();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
if (val) {
|
|
257
|
-
const $tooltip = $tt.clone(true).data('cm', cm).hide().appendTo(
|
|
258
|
-
$(cm.getScrollerElement()).children('.CodeMirror-sizer'),
|
|
259
|
-
);
|
|
260
|
-
cm.state.fold = {$tooltip, hide: hideTooltip($tooltip)};
|
|
261
|
-
cm.on('cursorActivity', showTooltip);
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
})();
|
package/i18n/en.json
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"wphl-version": "2.60.3",
|
|
3
|
-
"wphl-lang": "en",
|
|
4
|
-
"wphl-addon-search": "<span title=\"Search with a string or a regular expression\">Search</span>",
|
|
5
|
-
"wphl-addon-activeline": "Show the active line",
|
|
6
|
-
"wphl-addon-trailingspace": "Show trailing spaces",
|
|
7
|
-
"wphl-addon-matchbrackets": "Highlight matching/nonmatching brackets",
|
|
8
|
-
"wphl-addon-closebrackets": "Auto-close brackets and quotes",
|
|
9
|
-
"wphl-addon-matchtags": "Highlight matching/nonmatching tags",
|
|
10
|
-
"wphl-addon-fold": "Fold template arguments and tags' innerHTML",
|
|
11
|
-
"wphl-addon-wikieditor": "Add WikiEditor toolbar",
|
|
12
|
-
"wphl-addon-escape": "<span title=\"Ctrl/Cmd + / : HTML encoding\nCtrl/Cmd + \\ : URL decoding or encoding\">Keyboard shortcuts for HTML/URL encoding</span>",
|
|
13
|
-
"wphl-addon-contextmenu": "Open the template or module page when right clicking",
|
|
14
|
-
"wphl-addon-indentwithspace": "Indent JavaScript/CSS/Lua codes with spaces instead of tabs",
|
|
15
|
-
"wphl-addon-indent": "Indent",
|
|
16
|
-
"wphl-addon-othereditors": "Apply selected addons to other editors",
|
|
17
|
-
"wphl-addon-lint": "Wikitext linter (Switch on/off by <code>Ctrl/Cmd + L</code>)",
|
|
18
|
-
"wphl-addon-label": "Please select the addons you wish to load",
|
|
19
|
-
"wphl-addon-notice": "Changes will apply when opening a new Wikiplus dialog.",
|
|
20
|
-
"wphl-addon-title": "Wikiplus Highlight Addons",
|
|
21
|
-
"wphl-search-placeholder": "Search using a string or a regex pattern",
|
|
22
|
-
"wphl-replace-placeholder": "string used in replaceAll",
|
|
23
|
-
"wphl-search-replace": "replaceAll",
|
|
24
|
-
"wphl-replace-count": "The pattern occurs $1 time(s). Do you want to replace them all?",
|
|
25
|
-
"wphl-unfold": "Click here to unfold $1",
|
|
26
|
-
"wphl-fold": "Click here to fold $1",
|
|
27
|
-
"wphl-fold-template": "template arguments",
|
|
28
|
-
"wphl-fold-comment": "HTML comment",
|
|
29
|
-
"wphl-contentmodel": "Please choose the content model:",
|
|
30
|
-
"wphl-feedback": "Bug reports or suggestions are welcome at <a href=\"https://github.com/bhsd-harry/Wikiplus-highlight/issues\" target=\"_blank\">GitHub</a> .",
|
|
31
|
-
"wphl-portlet": "Wikiplus Highlight",
|
|
32
|
-
"wphl-welcome": "Welcome to <b>Wikiplus-highlight</b>!<br>You can change your local settings <a id=\"wphl-settings-notify\" href=\"#\">here</a>.",
|
|
33
|
-
"wphl-welcome-upgrade": "<b>Wikiplus-highlight</b> has been upgraded to $1.<br>You may need to check and update your local settings <a id=\"wphl-settings-notify\" href=\"#\">here</a>.",
|
|
34
|
-
"wphl-welcome-new-addon": "<b>Wikiplus-highlight</b> has been upgraded to $1.<br>This version introduces $2 new {{plural:$2|addon|addons}}.<br>You may need to check and update your local settings <a id=\"wphl-settings-notify\" href=\"#\">here</a>."
|
|
35
|
-
}
|
package/i18n/ka.json
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"wphl-version": "2.60.3",
|
|
3
|
-
"wphl-lang": "ka",
|
|
4
|
-
"wphl-addon-search": "<span title=\"ძებნა ნიშნების მწკრივით ან რეგულარული გაფართოებით\">ძებნა</span>",
|
|
5
|
-
"wphl-addon-activeline": "აქტიური ხაზის მონიშვნა",
|
|
6
|
-
"wphl-addon-trailingspace": "საბოლოო შორისების მონიშვნა",
|
|
7
|
-
"wphl-addon-matchbrackets": "შესაბამისი/შეუსაბამო ფრჩხილების განათება",
|
|
8
|
-
"wphl-addon-closebrackets": "ფრჩხილებისა და ბრჭყალების ავტომატურად დახურვა",
|
|
9
|
-
"wphl-addon-matchtags": "შესაბამისი/შეუსაბამო ტეგების განათება",
|
|
10
|
-
"wphl-addon-fold": "თარგის არგუმენტებისა და HTML-ის ტეგების შეკეცვა",
|
|
11
|
-
"wphl-addon-wikieditor": "ვიკირედაქტორის (WikiEditor) ხელსაწყოთა პანელის დამატება",
|
|
12
|
-
"wphl-addon-escape": "<span title=\"Ctrl/Cmd + / : HTML-კოდირება\nCtrl/Cmd + \\ : URL-კოდირება\">კლავიატურის მალსახმობები HTML/URL-ის კოდირებისათვის</span>",
|
|
13
|
-
"wphl-addon-contextmenu": "თარგის ან მოდულის გვერდის გახსნა მარჯვენა ღილაკზე დაჭერისას",
|
|
14
|
-
"wphl-addon-indentwithspace": "JavaScript/CSS/Lua-ის კოდებში ტაბულაციის ნაცვლად შორისებით შეწევა",
|
|
15
|
-
"wphl-addon-indent": "შეწევა",
|
|
16
|
-
"wphl-addon-othereditors": "არჩეული დანამატების გამოყენება სხვა მომხმარებლებისთვისაც",
|
|
17
|
-
"wphl-addon-lint": "Wikitext linter (Switch on/off by <code>Ctrl/Cmd + L</code>)",
|
|
18
|
-
"wphl-addon-label": "აირჩიეთ ის დანამატები, რომელთა გამოყენებაც გსურთ",
|
|
19
|
-
"wphl-addon-notice": "ცვლილებები აისახება Wikiplus-ის ახალი დიალოგის გახსნისას.",
|
|
20
|
-
"wphl-addon-title": "Wikiplus-ის განათების დანამატები",
|
|
21
|
-
"wphl-search-placeholder": "ძებნა ნიშნების მწკრივის ან რეგულარული გაფართოების ნიმუშის გამოყენებით",
|
|
22
|
-
"wphl-replace-placeholder": "string used in replaceAll",
|
|
23
|
-
"wphl-search-replace": "replaceAll",
|
|
24
|
-
"wphl-replace-count": "The pattern occurs $1 time(s). Do you want to replace them all?",
|
|
25
|
-
"wphl-unfold": "აქ დააწკაპუნეთ, რათა $1 გაიშალოს",
|
|
26
|
-
"wphl-fold": "აქ დააწკაპუნეთ, რათა $1 შეიკეცოს",
|
|
27
|
-
"wphl-fold-template": "თარგის არგუმენტები",
|
|
28
|
-
"wphl-fold-comment": "HTML-ის კომენტარი",
|
|
29
|
-
"wphl-contentmodel": "გთხოვთ, აირჩიოთ შინაარსის მოდელი:",
|
|
30
|
-
"wphl-feedback": "ხარვეზების ან შემოთავაზებების შესახებ მოგვწერეთ <a href=\"https://github.com/bhsd-harry/Wikiplus-highlight/issues\" target=\"_blank\">GitHub</a>-ზე.",
|
|
31
|
-
"wphl-portlet": "Wikiplus-ის განათება",
|
|
32
|
-
"wphl-welcome": "მოგესალმებათ <b>Wikiplus-ის განათება</b>!<br>თქვენი ადგილობრივი პარამეტრების შეცვლა შეგიძლიათ <a id=\"wphl-settings-notify\" href=\"#\">აქ</a>.",
|
|
33
|
-
"wphl-welcome-upgrade": "<b>Wikiplus-ის განათება</b> გაუმჯობესდა $1 ვერსიამდე.<br>თქვენ შესაძლოა ადგილობრივი პარამეტრების ნახვა და განახლება დაგჭირდეთ (იხ. <a id=\"wphl-settings-notify\" href=\"#\">აქ</a>).",
|
|
34
|
-
"wphl-welcome-new-addon": "<b>Wikiplus-ის განათება</b> გაუმჯობესდა $1 ვერსიამდე.<br>ამ ვერსიამ შემოიტანა $2 ახალი დანამატი.<br>თქვენ შესაძლოა ადგილობრივი პარამეტრების ნახვა და განახლება დაგჭირდეთ (იხ. <a id=\"wphl-settings-notify\" href=\"#\">აქ</a>)."
|
|
35
|
-
}
|
package/i18n/zh-hans.json
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"wphl-version": "2.60.3",
|
|
3
|
-
"wphl-lang": "zh-hans",
|
|
4
|
-
"wphl-addon-search": "<span title=\"搜索字符串或正则表达式\">搜索</span>",
|
|
5
|
-
"wphl-addon-activeline": "高亮显示光标所在行",
|
|
6
|
-
"wphl-addon-trailingspace": "显示尾随空格",
|
|
7
|
-
"wphl-addon-matchbrackets": "高亮显示匹配和未匹配的括号",
|
|
8
|
-
"wphl-addon-closebrackets": "自动闭合括号和引号",
|
|
9
|
-
"wphl-addon-matchtags": "高亮显示匹配和未匹配的标签",
|
|
10
|
-
"wphl-addon-fold": "折叠模板参数和标签内部文本",
|
|
11
|
-
"wphl-addon-wikieditor": "添加WikiEditor工具条",
|
|
12
|
-
"wphl-addon-escape": "<span title=\"Ctrl/Cmd + / : HTML编码\nCtrl/Cmd + \\ : URL解码或编码\">添加HTML和URL编码快捷键</span>",
|
|
13
|
-
"wphl-addon-contextmenu": "右键点击可打开模板或模块页面",
|
|
14
|
-
"wphl-addon-indentwithspace": "代码缩进使用空格而非Tab",
|
|
15
|
-
"wphl-addon-indent": "缩进",
|
|
16
|
-
"wphl-addon-othereditors": "将选中的插件用于其他编辑器",
|
|
17
|
-
"wphl-addon-lint": "维基语法检查(使用 <code>Ctrl/Cmd + L</code> 开关)",
|
|
18
|
-
"wphl-addon-label": "请选择您希望加载的插件",
|
|
19
|
-
"wphl-addon-notice": "更改将于打开新的Wikiplus编辑区时生效。",
|
|
20
|
-
"wphl-addon-title": "Wikiplus高亮插件",
|
|
21
|
-
"wphl-search-placeholder": "使用字符串或正则表达式搜索",
|
|
22
|
-
"wphl-replace-placeholder": "用于全文替换的字符串",
|
|
23
|
-
"wphl-search-replace": "全文替换",
|
|
24
|
-
"wphl-replace-count": "全文共有 $1 处待替换,确认替换吗?",
|
|
25
|
-
"wphl-unfold": "点击以展开$1",
|
|
26
|
-
"wphl-fold": "点击以折叠$1",
|
|
27
|
-
"wphl-fold-template": "模板参数",
|
|
28
|
-
"wphl-fold-comment": "HTML注释",
|
|
29
|
-
"wphl-contentmodel": "请选择内容模型:",
|
|
30
|
-
"wphl-feedback": "欢迎将错误报告或是改进建议提交到 <a href=\"https://github.com/bhsd-harry/Wikiplus-highlight/issues\" target=\"_blank\">GitHub</a> !",
|
|
31
|
-
"wphl-portlet": "Wikiplus高亮设置",
|
|
32
|
-
"wphl-welcome": "欢迎使用 <b>Wikiplus-highlight</b>!<br>您可以点击 <a id=\"wphl-settings-notify\" href=\"#\">这里</a> 更改本地设置。",
|
|
33
|
-
"wphl-welcome-upgrade": "<b>Wikiplus-highlight</b> 已升级到 $1。<br>您可能需要点击 <a id=\"wphl-settings-notify\" href=\"#\">这里</a> 查看并更新本地设置。",
|
|
34
|
-
"wphl-welcome-new-addon": "<b>Wikiplus-highlight</b> 已升级到 $1。<br>新版本添加了 $2 个插件,您可能需要点击 <a id=\"wphl-settings-notify\" href=\"#\">这里</a> 查看并更新本地设置。"
|
|
35
|
-
}
|
package/i18n/zh-hant.json
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"wphl-version": "2.60.3",
|
|
3
|
-
"wphl-lang": "zh-hant",
|
|
4
|
-
"wphl-addon-search": "<span title=\"搜尋字串或正規表示式\">搜尋</span>",
|
|
5
|
-
"wphl-addon-activeline": "突出顯示游標所在行",
|
|
6
|
-
"wphl-addon-trailingspace": "顯示尾隨空格",
|
|
7
|
-
"wphl-addon-matchbrackets": "突出顯示匹配和未匹配的括號",
|
|
8
|
-
"wphl-addon-closebrackets": "自動閉合括號和引號 ",
|
|
9
|
-
"wphl-addon-matchtags": "突出顯示匹配和未匹配的標籤",
|
|
10
|
-
"wphl-addon-fold": "摺疊模板參數和標籤內部文字",
|
|
11
|
-
"wphl-addon-wikieditor": "添加WikiEditor工具條",
|
|
12
|
-
"wphl-addon-escape": "<span title=\"Ctrl/Cmd + / : HTML編碼\nCtrl/Cmd + \\ : URL解碼或編碼\">添加HTML和URL編碼快速鍵</span>",
|
|
13
|
-
"wphl-addon-contextmenu": "右鍵點擊可打開模板或模組頁面",
|
|
14
|
-
"wphl-addon-indentwithspace": "代碼縮排使用空格而非Tab",
|
|
15
|
-
"wphl-addon-indent": "縮排",
|
|
16
|
-
"wphl-addon-othereditors": "將選中的外掛程式用於其他編輯器",
|
|
17
|
-
"wphl-addon-lint": "維基語法檢查(使用 <code>Ctrl/Cmd + L</code> 開關)",
|
|
18
|
-
"wphl-addon-label": "請選擇您希望載入的外掛程式",
|
|
19
|
-
"wphl-addon-notice": "更改將於打開新的Wikiplus編輯區時生效。",
|
|
20
|
-
"wphl-addon-title": "Wikiplus突顯外掛程式",
|
|
21
|
-
"wphl-search-placeholder": "使用字串或正規表示式搜尋",
|
|
22
|
-
"wphl-replace-placeholder": "用於全文替換的字符串",
|
|
23
|
-
"wphl-search-replace": "全文替換",
|
|
24
|
-
"wphl-replace-count": "全文共有 $1 處待替換,確認替換嗎?",
|
|
25
|
-
"wphl-unfold": "點擊以展開$1",
|
|
26
|
-
"wphl-fold": "點擊以摺疊$1",
|
|
27
|
-
"wphl-fold-template": "模板參數",
|
|
28
|
-
"wphl-fold-comment": "HTML注釋",
|
|
29
|
-
"wphl-contentmodel": "請選擇內容模型:",
|
|
30
|
-
"wphl-feedback": "歡迎將錯誤報告或是改進建議提交到 <a href=\"https://github.com/bhsd-harry/Wikiplus-highlight/issues\" target=\"_blank\">GitHub</a> !",
|
|
31
|
-
"wphl-portlet": "Wikiplus突顯設定",
|
|
32
|
-
"wphl-welcome": "歡迎使用 <b>Wikiplus-highlight</b>!<br>您可以點擊 <a id=\"wphl-settings-notify\" href=\"#\">這裡</a> 更改本地設定。",
|
|
33
|
-
"wphl-welcome-upgrade": "<b>Wikiplus-highlight</b> 已升級到 $1。<br>您可能需要點擊 <a id=\"wphl-settings-notify\" href=\"#\">這裡</a> 檢視並更新本地設定。",
|
|
34
|
-
"wphl-welcome-new-addon": "<b>Wikiplus-highlight</b> 已升級到 $1。<br>新版本添加了 $2 個外掛程式,您可能需要點擊 <a id=\"wphl-settings-notify\" href=\"#\">這裡</a> 檢視並更新本地設定。"
|
|
35
|
-
}
|
package/lint.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Bhsd <https://github.com/bhsd-harry>
|
|
3
|
-
* @license GPL-3.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
(() => {
|
|
7
|
-
/* global wikiparse */
|
|
8
|
-
'use strict';
|
|
9
|
-
|
|
10
|
-
/** 加载 I18N */
|
|
11
|
-
const {libs: {wphl: {version, storage, addons, lintOptions, CDN, PARSER_CDN, isPc, getMwConfig}}} = mw,
|
|
12
|
-
/** @type {Record<string, string>} */ i18n = storage.getObject('wikiparser-i18n') || {},
|
|
13
|
-
/** @type {Record<string, string>} */ i18nLanguages = {
|
|
14
|
-
zh: 'zh-hans',
|
|
15
|
-
'zh-hans': 'zh-hans',
|
|
16
|
-
'zh-cn': 'zh-hans',
|
|
17
|
-
'zh-my': 'zh-hans',
|
|
18
|
-
'zh-sg': 'zh-hans',
|
|
19
|
-
'zh-hant': 'zh-hant',
|
|
20
|
-
'zh-tw': 'zh-hant',
|
|
21
|
-
'zh-hk': 'zh-hant',
|
|
22
|
-
'zh-mo': 'zh-hant',
|
|
23
|
-
},
|
|
24
|
-
i18nLang = i18nLanguages[mw.config.get('wgUserLanguage')],
|
|
25
|
-
I18N_CDN = i18nLang && `${CDN}/${PARSER_CDN}/i18n/${i18nLang}.json`;
|
|
26
|
-
if (i18nLang) {
|
|
27
|
-
(async () => {
|
|
28
|
-
if (i18n['wphl-version'] !== version || i18n['wphl-lang'] !== i18nLang) {
|
|
29
|
-
Object.assign(
|
|
30
|
-
i18n,
|
|
31
|
-
await $.ajax(`${I18N_CDN}`, {dataType: 'json', cache: true}),
|
|
32
|
-
{'wphl-version': version, 'wphl-lang': i18nLang},
|
|
33
|
-
);
|
|
34
|
-
storage.setObject('wikiparser-i18n', i18n);
|
|
35
|
-
}
|
|
36
|
-
wikiparse.setI18N(i18n);
|
|
37
|
-
})();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const include = mw.config.get('wgNamespaceNumber') === 10 && !mw.config.get('wgPageName').endsWith('/doc'),
|
|
41
|
-
{cmpPos, Pos} = CodeMirror;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* annotationSource
|
|
45
|
-
* @param {string} str wikitext
|
|
46
|
-
* @param {CodeMirror.Editor} cm CodeMirror实例
|
|
47
|
-
* @returns {Promise<CodeMirror.LintAnnotation>}
|
|
48
|
-
*/
|
|
49
|
-
const annotate = async (str, _, cm) => {
|
|
50
|
-
const errors = await cm.Linter.queue(str);
|
|
51
|
-
return errors.map(error => {
|
|
52
|
-
const {startLine, startCol, endLine, endCol, message, severity} = error,
|
|
53
|
-
lineErrors = errors.filter(({startLine: line}) => line === startLine);
|
|
54
|
-
return {
|
|
55
|
-
message: message + '\u200B'.repeat(lineErrors.indexOf(error)),
|
|
56
|
-
severity,
|
|
57
|
-
from: Pos(startLine, startCol),
|
|
58
|
-
to: Pos(endLine, endCol),
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
CodeMirror.registerHelper('lint', 'mediawiki', annotate);
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* start linting
|
|
67
|
-
* @param {CodeMirror.Editor} cm CodeMirror实例
|
|
68
|
-
*/
|
|
69
|
-
const lint = async cm => {
|
|
70
|
-
const mode = cm.getOption('mode');
|
|
71
|
-
if (mode !== 'mediawiki' && mode !== 'text/mediawiki') {
|
|
72
|
-
return;
|
|
73
|
-
} else if (!wikiparse.config) {
|
|
74
|
-
const {config: {values: {wgFormattedNamespaces, wgNamespaceIds}}} = mw,
|
|
75
|
-
{parserFunction: [withPound,, ...modifiers]} = await wikiparse.getConfig(),
|
|
76
|
-
valuesWithPound = new Set(Object.values(withPound));
|
|
77
|
-
let mwConfig = cm.getOption('mwConfig');
|
|
78
|
-
if (!mwConfig.img || !mwConfig.variants || Object.values(mwConfig.functionSynonyms[0]).includes(true)) {
|
|
79
|
-
mwConfig = await getMwConfig('mediawiki');
|
|
80
|
-
}
|
|
81
|
-
const {tags, functionSynonyms: [insensitive, sensitive], doubleUnderscore, img, variants} = mwConfig;
|
|
82
|
-
for (const [k, v] of Object.entries(insensitive)) {
|
|
83
|
-
if (valuesWithPound.has(v) && !k.startsWith('#')) {
|
|
84
|
-
delete insensitive[k];
|
|
85
|
-
insensitive[`#${k}`] = v;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
wikiparse.config = {
|
|
89
|
-
ext: Object.keys(tags),
|
|
90
|
-
namespaces: wgFormattedNamespaces,
|
|
91
|
-
nsid: wgNamespaceIds,
|
|
92
|
-
parserFunction: [
|
|
93
|
-
insensitive,
|
|
94
|
-
Object.keys(sensitive),
|
|
95
|
-
...modifiers,
|
|
96
|
-
],
|
|
97
|
-
doubleUnderscore: doubleUnderscore.map(Object.keys),
|
|
98
|
-
img: Object.fromEntries(Object.entries(img).map(([k, v]) => [k, v.slice(4)])),
|
|
99
|
-
variants,
|
|
100
|
-
};
|
|
101
|
-
wikiparse.setConfig(wikiparse.config);
|
|
102
|
-
}
|
|
103
|
-
cm.Linter = new wikiparse.Linter(include);
|
|
104
|
-
cm.setOption('scrollButtonHeight', 0);
|
|
105
|
-
let /** @type {CodeMirror.LintAnnotation[]} */ errors, /** @type {CodeMirror.LintAnnotation[]} */ warnings;
|
|
106
|
-
const /** @type {Map<CodeMirror.LintAnnotation[], number>} */ positionMap = new Map();
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* jump to next mark
|
|
110
|
-
* @param {CodeMirror.LintAnnotation[]} annotations 错误标记
|
|
111
|
-
*/
|
|
112
|
-
const nextMark = annotations => {
|
|
113
|
-
const {length} = annotations;
|
|
114
|
-
if (length > 0) {
|
|
115
|
-
const cursor = cm.getCursor(),
|
|
116
|
-
iNext = Math.max(0, annotations.findIndex(({from}) => cmpPos(from, cursor) >= 0)),
|
|
117
|
-
offset = positionMap.get(annotations) || 0;
|
|
118
|
-
cm.scrollIntoView(annotations[(iNext + offset) % length].from);
|
|
119
|
-
positionMap.set(annotations, offset + 1);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
const annotateScrollWarn = cm.annotateScrollbar('CodeMirror-lint-scroll-warn'),
|
|
123
|
-
annotateScrollError = cm.annotateScrollbar('CodeMirror-lint-scroll-error'),
|
|
124
|
-
$panelErrorCount = $('<span>', {class: 'wphl-lint-count'}),
|
|
125
|
-
$panelWarnCount = $('<span>', {class: 'wphl-lint-count'}),
|
|
126
|
-
$panelError = $('<span>', {
|
|
127
|
-
class: 'wphl-lint-subpanel',
|
|
128
|
-
html: [$('<span>', {class: 'CodeMirror-lint-marker CodeMirror-lint-marker-error'}), $panelErrorCount],
|
|
129
|
-
}).click(() => {
|
|
130
|
-
nextMark(errors);
|
|
131
|
-
}),
|
|
132
|
-
$panelWarn = $('<span>', {
|
|
133
|
-
class: 'wphl-lint-subpanel',
|
|
134
|
-
html: [$('<span>', {class: 'CodeMirror-lint-marker CodeMirror-lint-marker-warning'}), $panelWarnCount],
|
|
135
|
-
}).click(() => {
|
|
136
|
-
nextMark(warnings);
|
|
137
|
-
}),
|
|
138
|
-
$panelElement = $('<div>', {id: 'wphl-lint-panel', html: [$panelError, $panelWarn]}),
|
|
139
|
-
$lineDiv = $(cm.display.lineDiv);
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* update linting
|
|
143
|
-
* @param {CodeMirror.LintAnnotation[]} annotations all annotations
|
|
144
|
-
*/
|
|
145
|
-
const onUpdateLinting = annotations => {
|
|
146
|
-
errors = annotations.filter(({severity}) => severity !== 'warning');
|
|
147
|
-
warnings = annotations.filter(({severity}) => severity === 'warning');
|
|
148
|
-
annotateScrollWarn.update(warnings);
|
|
149
|
-
annotateScrollError.update(errors);
|
|
150
|
-
$panelErrorCount.text(errors.length);
|
|
151
|
-
$panelWarnCount.text(warnings.length);
|
|
152
|
-
},
|
|
153
|
-
performLint = () => {
|
|
154
|
-
cm.performLint();
|
|
155
|
-
},
|
|
156
|
-
onInput = () => {
|
|
157
|
-
clearTimeout(cm.state.lint.timeout);
|
|
158
|
-
},
|
|
159
|
-
switchOption = () => {
|
|
160
|
-
if (cm.state.lint) {
|
|
161
|
-
cm.setOption('lint', false);
|
|
162
|
-
$lineDiv.off('input', onInput);
|
|
163
|
-
annotateScrollWarn.update([]);
|
|
164
|
-
annotateScrollError.update([]);
|
|
165
|
-
$panelElement.detach();
|
|
166
|
-
} else {
|
|
167
|
-
cm.setOption('lint', {
|
|
168
|
-
delay: 1000, ...lintOptions, selfContain: true, onUpdateLinting,
|
|
169
|
-
});
|
|
170
|
-
$lineDiv.on('input', onInput);
|
|
171
|
-
$panelElement.insertAfter(cm.getWrapperElement());
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
cm.setOption('gutters', ['CodeMirror-lint-markers']);
|
|
175
|
-
switchOption();
|
|
176
|
-
const ctrl = isPc(CodeMirror) ? 'Ctrl' : 'Cmd';
|
|
177
|
-
cm.addKeyMap({[`${ctrl}-K`]: performLint, [`${ctrl}-L`]: switchOption});
|
|
178
|
-
cm.on('cursorActivity', () => {
|
|
179
|
-
positionMap.clear();
|
|
180
|
-
});
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* 分离hook函数以便调试
|
|
185
|
-
* @param {CodeMirror.Editor} cm CodeMirror实例
|
|
186
|
-
*/
|
|
187
|
-
const hook = cm => {
|
|
188
|
-
if (addons.has('lint') && cm.getTextArea
|
|
189
|
-
&& (addons.has('otherEditors') || cm.getTextArea().id === 'Wikiplus-Quickedit')
|
|
190
|
-
) {
|
|
191
|
-
lint(cm);
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
mw.hook('wiki-codemirror').add(hook);
|
|
195
|
-
mw.hook('InPageEdit.quickEdit.codemirror').add(
|
|
196
|
-
/** @param {{cm: CodeMirror.Editor}} */ ({cm: doc}) => hook(doc),
|
|
197
|
-
);
|
|
198
|
-
mw.hook('inspector').add(hook);
|
|
199
|
-
mw.libs.wphl.lintHook = hook;
|
|
200
|
-
})();
|