mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeMirror
synced 2024-11-23 13:56:44 +00:00
Isolate build step to CM6 library and restructure files to work with RL
CodeMirror 6 requires the use of NPM, but we can still bundle all CM packages into one file, and then everything else (i.e. our code) is managed by ResourceLoader as per usual. This makes contribution considerably easier as we no longer need a build step for each change. CM5 files are now under resources/legacy, and the CM6 files are moved to the root of the resources/ directory. Only one file, codemirror.bundle.js, is managed by Rollup, while everything else is RL. The Rollup output for now is put under resources/lib/ alongside the CM5 upstream files. This patch is *mostly* renames of files, along with changing ECMAScript Module (ESM) syntax into the CommonJS style that ResourceLoader prefers. We also remove more modern JS syntax (i.e. private class methods) that we were able to use before because we had a build step with Babel. This patch should effectively make no user-facing changes, or to the ResourceLoader modules we offer in Extension:CodeMirror. Finally, bump version in extension.json to 6, to match the upstream lib, and add Bhsd as an author :-) Bug: T368053 Change-Id: Ie258e49f5df8db23a7344ac3c4c9300aaa991042
This commit is contained in:
parent
f3be172173
commit
7d3482f89e
4
.babelrc
4
.babelrc
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"presets": ["@babel/preset-env"],
|
|
||||||
"plugins": ["@babel/plugin-transform-private-methods"]
|
|
||||||
}
|
|
34
README.md
34
README.md
|
@ -1,27 +1,30 @@
|
||||||
|
The CodeMirror extension provides syntax highlighting in MediaWiki wikitext editors using
|
||||||
|
the [CodeMirror library](https://codemirror.net/).
|
||||||
|
|
||||||
CodeMirror 6 homepage: [https://www.mediawiki.org/wiki/Extension:CodeMirror/6](https://www.mediawiki.org/wiki/Extension:CodeMirror/6)
|
CodeMirror 6 homepage: [https://www.mediawiki.org/wiki/Extension:CodeMirror/6](https://www.mediawiki.org/wiki/Extension:CodeMirror/6)
|
||||||
|
|
||||||
|
JS documentation: [https://doc.wikimedia.org/CodeMirror](https://doc.wikimedia.org/CodeMirror)
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
As part of the [upgrade to CodeMirror 6](https://phabricator.wikimedia.org/T259059),
|
### Preface
|
||||||
CodeMirror now uses an asset bundler, so during development you'll need to run a script
|
|
||||||
to assemble the frontend assets.
|
Extension:CodeMirror is currently in the process of being upgraded to the new major version, CodeMirror 6.
|
||||||
|
See the [change log](https://www.mediawiki.org/wiki/Extension:CodeMirror/6#Change_log) for details.
|
||||||
|
|
||||||
Use of CodeMirror 6 is controlled by the `wgCodeMirrorV6` configuration setting, or by
|
Use of CodeMirror 6 is controlled by the `wgCodeMirrorV6` configuration setting, or by
|
||||||
passing in `cm6enable=1` in the URL query string.
|
passing in `cm6enable=1` in the URL query string.
|
||||||
|
|
||||||
You can find the v6 frontend source files in `src/`, the compiled sources in
|
CodeMirror 6 requires the use of NPM to bundle the dependencies. These are bundled in
|
||||||
`resources/dist/`, and other frontend assets managed by ResourceLoader in
|
[resources/codemirror.bundle.js](resources/codemirror.bundle.js), built using [Rollup](https://rollupjs.org/),
|
||||||
`resources/*`.
|
and packaged as the `ext.CodeMirror.v6.lib` ResourceLoader module. If you make changes to the
|
||||||
|
versions of the dependencies, you will need to run `npm run build` to update the ResourceLoader module.
|
||||||
|
|
||||||
### Commands
|
### NPM commands
|
||||||
|
|
||||||
_NOTE: Consider using [Fresh](https://gerrit.wikimedia.org/g/fresh/) to run these tasks._
|
_NOTE: Consider using [Fresh](https://gerrit.wikimedia.org/g/fresh/) to run these tasks._
|
||||||
|
|
||||||
* `npm install` to install dependencies.
|
* `npm install` to install dependencies.
|
||||||
* `npm start` to run the bundler in watch mode, reassembling the files on file change.
|
|
||||||
You'll want to keep this running in a separate terminal during development.
|
|
||||||
* `npm run build` to compile the production assets. You *must* run this step before
|
|
||||||
sending the patch or CI will fail (so that sources and built assets are in sync).
|
|
||||||
* `npm run doc` to generate the API documentation.
|
* `npm run doc` to generate the API documentation.
|
||||||
* `npm test` to run the linting tools, JavaScript unit tests, and build checks.
|
* `npm test` to run the linting tools, JavaScript unit tests, and build checks.
|
||||||
* `npm run test:lint` for linting of JS/LESS/CSS.
|
* `npm run test:lint` for linting of JS/LESS/CSS.
|
||||||
|
@ -30,9 +33,8 @@ _NOTE: Consider using [Fresh](https://gerrit.wikimedia.org/g/fresh/) to run thes
|
||||||
* `npm run test:i18n` for linting of i18n messages with banana-checker.
|
* `npm run test:i18n` for linting of i18n messages with banana-checker.
|
||||||
* `npm run test:unit` for the new Jest unit tests.
|
* `npm run test:unit` for the new Jest unit tests.
|
||||||
* `npm run selenium-test` for the Selenium tests.
|
* `npm run selenium-test` for the Selenium tests.
|
||||||
|
* `npm run build` to rebundle the CodeMirror library. If changes are made to the `@codemirror`
|
||||||
|
or `@lezer` dependencies in [package.json](package.json), this command *must* be run before
|
||||||
|
sending the patch or CI will fail.
|
||||||
* Older QUnit tests are in `resources/mode/mediawiki/tests/qunit/`. These have been
|
* Older QUnit tests are in `resources/mode/mediawiki/tests/qunit/`. These have been
|
||||||
replaced and will be removed after the CodeMirror 6 upgrade.
|
replaced and will be removed after the CodeMirror 6 upgrade is complete.
|
||||||
|
|
||||||
## CodeMirror 6 change log
|
|
||||||
|
|
||||||
* See [Extension:CodeMirror/6](https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:CodeMirror/6#Differences_from_CodeMirror_5)
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "CodeMirror",
|
"name": "CodeMirror",
|
||||||
"version": "5.0.0",
|
"version": "6.0.0",
|
||||||
"author": [
|
"author": [
|
||||||
"[https://www.mediawiki.org/wiki/User:Pastakhov Pavel Astakhov]",
|
"[https://www.mediawiki.org/wiki/User:Pastakhov Pavel Astakhov]",
|
||||||
"[https://www.mediawiki.org/wiki/User:Florianschmidtwelzow Florian Schmidt]",
|
"[https://www.mediawiki.org/wiki/User:Florianschmidtwelzow Florian Schmidt]",
|
||||||
"Marijn Haverbeke",
|
"Marijn Haverbeke",
|
||||||
"MusikAnimal",
|
"MusikAnimal",
|
||||||
|
"Bhsd",
|
||||||
"[https://raw.githubusercontent.com/codemirror/CodeMirror/master/AUTHORS CodeMirror contributors]"
|
"[https://raw.githubusercontent.com/codemirror/CodeMirror/master/AUTHORS CodeMirror contributors]"
|
||||||
],
|
],
|
||||||
"url": "https://www.mediawiki.org/wiki/Extension:CodeMirror",
|
"url": "https://www.mediawiki.org/wiki/Extension:CodeMirror",
|
||||||
|
@ -58,9 +59,9 @@
|
||||||
"user.options"
|
"user.options"
|
||||||
],
|
],
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"ext.CodeMirror.js",
|
"legacy/ext.CodeMirror.js",
|
||||||
{
|
{
|
||||||
"name": "ext.CodeMirror.data.js",
|
"name": "legacy/ext.CodeMirror.data.js",
|
||||||
"callback": "MediaWiki\\Extension\\CodeMirror\\DataScript::makeScript"
|
"callback": "MediaWiki\\Extension\\CodeMirror\\DataScript::makeScript"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -74,10 +75,10 @@
|
||||||
"oojs-ui.styles.icons-editing-styling"
|
"oojs-ui.styles.icons-editing-styling"
|
||||||
],
|
],
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"ext.CodeMirror.WikiEditor.js"
|
"legacy/ext.CodeMirror.WikiEditor.js"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"ext.CodeMirror.less"
|
"legacy/ext.CodeMirror.less"
|
||||||
],
|
],
|
||||||
"messages": [
|
"messages": [
|
||||||
"codemirror-toggle-label"
|
"codemirror-toggle-label"
|
||||||
|
@ -89,22 +90,22 @@
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"lib/codemirror/lib/codemirror.css",
|
"lib/codemirror/lib/codemirror.css",
|
||||||
"lib/codemirror-fixes.less"
|
"legacy/codemirror-fixes.less"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ext.CodeMirror.addons": {
|
"ext.CodeMirror.addons": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"addon/edit/matchbrackets-wmde.js"
|
"legacy/addon/matchbrackets-wmde.js"
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"ext.CodeMirror.lib"
|
"ext.CodeMirror.lib"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ext.CodeMirror.mode.mediawiki": {
|
"ext.CodeMirror.mode.mediawiki": {
|
||||||
"packageFiles": "mode/mediawiki/mediawiki.js",
|
"packageFiles": "legacy/mode/mediawiki/mediawiki.js",
|
||||||
"styles": [
|
"styles": [
|
||||||
"mode/mediawiki/mediawiki.less",
|
"codemirror.mediawiki.less",
|
||||||
"mode/mediawiki/colorblind-colors.less"
|
"codemirror.mediawiki.colorblind.less"
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"ext.CodeMirror.lib"
|
"ext.CodeMirror.lib"
|
||||||
|
@ -160,11 +161,11 @@
|
||||||
"ext.CodeMirror"
|
"ext.CodeMirror"
|
||||||
],
|
],
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"modules/ve-cm/ve.ui.CodeMirrorAction.js",
|
"legacy/modules/ve-cm/ve.ui.CodeMirrorAction.js",
|
||||||
"modules/ve-cm/ve.ui.CodeMirrorTool.js"
|
"legacy/modules/ve-cm/ve.ui.CodeMirrorTool.js"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"modules/ve-cm/ve.ui.CodeMirror.less"
|
"legacy/modules/ve-cm/ve.ui.CodeMirror.less"
|
||||||
],
|
],
|
||||||
"messages": [
|
"messages": [
|
||||||
"codemirror-toggle-label"
|
"codemirror-toggle-label"
|
||||||
|
@ -172,21 +173,21 @@
|
||||||
},
|
},
|
||||||
"ext.CodeMirror.v6": {
|
"ext.CodeMirror.v6": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"web2017-polyfills",
|
|
||||||
"mediawiki.api",
|
"mediawiki.api",
|
||||||
"mediawiki.user",
|
"mediawiki.user",
|
||||||
"user.options",
|
"user.options",
|
||||||
"ext.CodeMirror.v6.lib"
|
"ext.CodeMirror.v6.lib"
|
||||||
],
|
],
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"dist/codemirror.js",
|
"codemirror.js",
|
||||||
|
"codemirror.textSelection.js",
|
||||||
{
|
{
|
||||||
"name": "ext.CodeMirror.data.js",
|
"name": "ext.CodeMirror.data.js",
|
||||||
"callback": "MediaWiki\\Extension\\CodeMirror\\DataScript::makeScript"
|
"callback": "MediaWiki\\Extension\\CodeMirror\\DataScript::makeScript"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"ext.CodeMirror.v6.less"
|
"codemirror.less"
|
||||||
],
|
],
|
||||||
"messages": [
|
"messages": [
|
||||||
"codemirror-find",
|
"codemirror-find",
|
||||||
|
@ -234,22 +235,24 @@
|
||||||
"ext.CodeMirror.v6.mode.mediawiki"
|
"ext.CodeMirror.v6.mode.mediawiki"
|
||||||
],
|
],
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"dist/codemirror.mediawiki.js"
|
"codemirror.mediawiki.init.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ext.CodeMirror.v6.lib": {
|
"ext.CodeMirror.v6.lib": {
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"dist/vendor.js"
|
"lib/codemirror6.bundle.dist.js"
|
||||||
],
|
|
||||||
"dependencies": [
|
|
||||||
"web2017-polyfills"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ext.CodeMirror.v6.mode.mediawiki": {
|
"ext.CodeMirror.v6.mode.mediawiki": {
|
||||||
"packageFiles": "dist/codemirror.mode.mediawiki.js",
|
"packageFiles": [
|
||||||
|
"codemirror.mediawiki.js",
|
||||||
|
"codemirror.mediawiki.config.js",
|
||||||
|
"codemirror.mediawiki.bidiIsolation.js",
|
||||||
|
"codemirror.mediawiki.templateFolding.js"
|
||||||
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"mode/mediawiki/mediawiki.less",
|
"codemirror.mediawiki.less",
|
||||||
"mode/mediawiki/colorblind-colors.less"
|
"codemirror.mediawiki.colorblind.less"
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"ext.CodeMirror.v6",
|
"ext.CodeMirror.v6",
|
||||||
|
@ -258,11 +261,10 @@
|
||||||
},
|
},
|
||||||
"ext.CodeMirror.v6.WikiEditor": {
|
"ext.CodeMirror.v6.WikiEditor": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"ext.wikiEditor",
|
"ext.wikiEditor"
|
||||||
"ext.CodeMirror.v6"
|
|
||||||
],
|
],
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"dist/codemirror.wikieditor.js"
|
"codemirror.wikieditor.js"
|
||||||
],
|
],
|
||||||
"messages": [
|
"messages": [
|
||||||
"codemirror-toggle-label"
|
"codemirror-toggle-label"
|
||||||
|
@ -274,7 +276,7 @@
|
||||||
"ext.CodeMirror.v6.mode.mediawiki"
|
"ext.CodeMirror.v6.mode.mediawiki"
|
||||||
],
|
],
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"dist/codemirror.wikieditor.mediawiki.js"
|
"codemirror.wikieditor.mediawiki.init.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -287,8 +289,8 @@
|
||||||
"usecodemirror": 0
|
"usecodemirror": 0
|
||||||
},
|
},
|
||||||
"QUnitTestModule": {
|
"QUnitTestModule": {
|
||||||
"localBasePath": "resources/mode/mediawiki/tests",
|
"localBasePath": "resources/legacy/mode/mediawiki/tests",
|
||||||
"remoteExtPath": "CodeMirror/resources/mode/mediawiki/tests",
|
"remoteExtPath": "CodeMirror/resources/legacy/mode/mediawiki/tests",
|
||||||
"packageFiles": [
|
"packageFiles": [
|
||||||
"qunit/CodeMirror.mediawiki.test.js"
|
"qunit/CodeMirror.mediawiki.test.js"
|
||||||
],
|
],
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
"node_modules/jsdoc-wmf-theme/plugins/default"
|
"node_modules/jsdoc-wmf-theme/plugins/default"
|
||||||
],
|
],
|
||||||
"source": {
|
"source": {
|
||||||
"include": [ "src" ],
|
"include": [ "resources" ],
|
||||||
|
"exclude": [ "resources/legacy", "resources/lib" ],
|
||||||
"includePattern": ".+\\.js$"
|
"includePattern": ".+\\.js$"
|
||||||
},
|
},
|
||||||
"tags": {},
|
"tags": {},
|
||||||
|
@ -25,9 +26,10 @@
|
||||||
"repository": "https://gerrit.wikimedia.org/g/mediawiki/extensions/CodeMirror",
|
"repository": "https://gerrit.wikimedia.org/g/mediawiki/extensions/CodeMirror",
|
||||||
"linkMap": {
|
"linkMap": {
|
||||||
"jQuery.fn.textSelection": "https://doc.wikimedia.org/mediawiki-core/master/js/jQueryPlugins.html#.textSelection",
|
"jQuery.fn.textSelection": "https://doc.wikimedia.org/mediawiki-core/master/js/jQueryPlugins.html#.textSelection",
|
||||||
|
"Compartment": "https://codemirror.net/docs/ref/#state.Compartment",
|
||||||
"Decoration": "https://codemirror.net/docs/ref/#view.Decoration",
|
"Decoration": "https://codemirror.net/docs/ref/#view.Decoration",
|
||||||
"DecorationSet": "https://codemirror.net/docs/ref/#view.DecorationSet",
|
"DecorationSet": "https://codemirror.net/docs/ref/#view.DecorationSet",
|
||||||
|
"Direction": "https://codemirror.net/docs/ref/#view.Direction",
|
||||||
"EditorState": "https://codemirror.net/docs/ref/#state.EditorState",
|
"EditorState": "https://codemirror.net/docs/ref/#state.EditorState",
|
||||||
"EditorView": "https://codemirror.net/docs/ref/#view.EditorView",
|
"EditorView": "https://codemirror.net/docs/ref/#view.EditorView",
|
||||||
"Extension": "https://codemirror.net/docs/ref/#state.Extension",
|
"Extension": "https://codemirror.net/docs/ref/#state.Extension",
|
||||||
|
|
2665
package-lock.json
generated
2665
package-lock.json
generated
File diff suppressed because it is too large
Load diff
24
package.json
24
package.json
|
@ -1,16 +1,15 @@
|
||||||
{
|
{
|
||||||
"name": "CodeMirror",
|
"name": "codemirror",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "rollup -c --watch",
|
"build": "rollup -c",
|
||||||
"build": "rollup -c --environment BUILD:production",
|
|
||||||
"test": "npm run test:lint && npm run test:unit && npm run check-built-assets",
|
"test": "npm run test:lint && npm run test:unit && npm run check-built-assets",
|
||||||
"test:lint": "npm run test:lint:styles && npm run test:lint:js && npm run test:lint:i18n",
|
"test:lint": "npm run test:lint:styles && npm run test:lint:js && npm run test:lint:i18n",
|
||||||
"test:lint:js": "eslint --cache .",
|
"test:lint:js": "eslint --cache .",
|
||||||
"test:lint:styles": "stylelint \"resources/**/*.less\"",
|
"test:lint:styles": "stylelint \"resources/**/*.less\"",
|
||||||
"test:lint:i18n": "banana-checker i18n/",
|
"test:lint:i18n": "banana-checker i18n/",
|
||||||
"test:unit": "jest",
|
"test:unit": "jest",
|
||||||
"check-built-assets": "{ git status src/ | grep \"nothing to commit, working tree clean\"; } && { echo 'CHECKING BUILD SOURCES ARE COMMITTED' && npm run build && git status resources/dist/ | grep \"nothing to commit, working tree clean\" || { npm run node-debug; false; }; }",
|
"check-built-assets": "{ git status src/ | grep \"nothing to commit, working tree clean\"; } && { echo 'CHECKING BUILD SOURCES ARE COMMITTED' && npm run build && git status resources/lib/ | grep \"nothing to commit, working tree clean\" || { npm run node-debug; false; }; }",
|
||||||
"node-debug": "node -v && npm -v && echo 'ERROR: Please ensure that production assets have been built with `npm run build` and commited, and that you are using the correct version of Node/NPM.'",
|
"node-debug": "node -v && npm -v && echo 'ERROR: Please ensure that production assets have been built with `npm run build` and commited, and that you are using the correct version of Node/NPM.'",
|
||||||
"selenium-test": "wdio tests/selenium/wdio.conf.js",
|
"selenium-test": "wdio tests/selenium/wdio.conf.js",
|
||||||
"doc": "jsdoc -c jsdoc.json"
|
"doc": "jsdoc -c jsdoc.json"
|
||||||
|
@ -19,22 +18,18 @@
|
||||||
"node": "18.20.2"
|
"node": "18.20.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-transform-private-methods": "7.23.3",
|
|
||||||
"@babel/preset-env": "7.24.0",
|
|
||||||
"@codemirror/commands": "6.2.5",
|
"@codemirror/commands": "6.2.5",
|
||||||
"@codemirror/language": "6.9.3",
|
"@codemirror/language": "6.9.3",
|
||||||
"@codemirror/search": "6.5.4",
|
"@codemirror/search": "6.5.4",
|
||||||
"@codemirror/state": "6.2.1",
|
"@codemirror/state": "6.2.1",
|
||||||
"@codemirror/view": "6.22.2",
|
"@codemirror/view": "6.22.2",
|
||||||
"@lezer/highlight": "1.2.0",
|
"@lezer/highlight": "1.2.0",
|
||||||
"@rollup/plugin-babel": "6.0.4",
|
|
||||||
"@rollup/plugin-node-resolve": "15.2.3",
|
"@rollup/plugin-node-resolve": "15.2.3",
|
||||||
"@rollup/plugin-terser": "0.4.4",
|
"@wdio/cli": "7.36.0",
|
||||||
"@wdio/cli": "7.30.1",
|
"@wdio/junit-reporter": "7.35.0",
|
||||||
"@wdio/junit-reporter": "7.29.1",
|
"@wdio/local-runner": "7.36.0",
|
||||||
"@wdio/local-runner": "7.30.1",
|
"@wdio/mocha-framework": "7.33.0",
|
||||||
"@wdio/mocha-framework": "7.26.0",
|
"@wdio/spec-reporter": "7.33.0",
|
||||||
"@wdio/spec-reporter": "7.29.1",
|
|
||||||
"@wikimedia/mw-node-qunit": "7.2.0",
|
"@wikimedia/mw-node-qunit": "7.2.0",
|
||||||
"dotenv": "8.2.0",
|
"dotenv": "8.2.0",
|
||||||
"eslint-config-wikimedia": "0.28.2",
|
"eslint-config-wikimedia": "0.28.2",
|
||||||
|
@ -45,8 +40,7 @@
|
||||||
"jsdoc": "4.0.3",
|
"jsdoc": "4.0.3",
|
||||||
"jsdoc-wmf-theme": "1.1.0",
|
"jsdoc-wmf-theme": "1.1.0",
|
||||||
"rollup": "4.13.0",
|
"rollup": "4.13.0",
|
||||||
"rollup-plugin-copy": "3.5.0",
|
|
||||||
"stylelint-config-wikimedia": "0.16.1",
|
"stylelint-config-wikimedia": "0.16.1",
|
||||||
"wdio-mediawiki": "2.3.0"
|
"wdio-mediawiki": "2.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,18 @@
|
||||||
"wikimedia/mediawiki"
|
"wikimedia/mediawiki"
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"sourceType": "commonjs"
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"commonjs": true
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"CodeMirror": "readonly"
|
"Tree": "readonly"
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"max-len": "off"
|
"max-len": "off",
|
||||||
|
"es-x/no-array-prototype-includes": "off"
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
|
18
resources/codemirror.bundle.js
Normal file
18
resources/codemirror.bundle.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* This file is managed by Rollup and bundles all the CodeMirror dependencies
|
||||||
|
* into the single file resources/lib/codemirror6.bundle.dist.js.
|
||||||
|
*/
|
||||||
|
import '@codemirror/commands';
|
||||||
|
import '@codemirror/language';
|
||||||
|
import '@codemirror/search';
|
||||||
|
import '@codemirror/state';
|
||||||
|
import '@codemirror/view';
|
||||||
|
import '@lezer/highlight';
|
||||||
|
|
||||||
|
/* eslint-disable es-x/no-export-ns-from */
|
||||||
|
export * from '@codemirror/commands';
|
||||||
|
export * from '@codemirror/language';
|
||||||
|
export * from '@codemirror/search';
|
||||||
|
export * from '@codemirror/state';
|
||||||
|
export * from '@codemirror/view';
|
||||||
|
export * from '@lezer/highlight';
|
|
@ -1,20 +1,23 @@
|
||||||
import { EditorState, Extension, Compartment } from '@codemirror/state';
|
const {
|
||||||
import {
|
EditorState,
|
||||||
EditorView,
|
EditorView,
|
||||||
drawSelection,
|
Extension,
|
||||||
lineNumbers,
|
Compartment,
|
||||||
highlightSpecialChars,
|
ViewUpdate,
|
||||||
keymap,
|
bracketMatching,
|
||||||
rectangularSelection,
|
|
||||||
crosshairCursor,
|
crosshairCursor,
|
||||||
ViewUpdate
|
defaultKeymap,
|
||||||
} from '@codemirror/view';
|
drawSelection,
|
||||||
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
|
highlightSpecialChars,
|
||||||
import { searchKeymap } from '@codemirror/search';
|
history,
|
||||||
import { bracketMatching } from '@codemirror/language';
|
historyKeymap,
|
||||||
import CodeMirrorTextSelection from './codemirror.textSelection';
|
keymap,
|
||||||
|
lineNumbers,
|
||||||
require( '../ext.CodeMirror.data.js' );
|
rectangularSelection,
|
||||||
|
searchKeymap
|
||||||
|
} = require( 'ext.CodeMirror.v6.lib' );
|
||||||
|
const CodeMirrorTextSelection = require( './codemirror.textSelection.js' );
|
||||||
|
require( './ext.CodeMirror.data.js' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for the CodeMirror editor.
|
* Interface for the CodeMirror editor.
|
||||||
|
@ -381,7 +384,7 @@ class CodeMirror {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Add CodeMirror view to the DOM.
|
// Add CodeMirror view to the DOM.
|
||||||
this.#addCodeMirrorToDom();
|
this.addCodeMirrorToDom();
|
||||||
|
|
||||||
// Hide native textarea and sync CodeMirror contents upon submission.
|
// Hide native textarea and sync CodeMirror contents upon submission.
|
||||||
this.$textarea.hide();
|
this.$textarea.hide();
|
||||||
|
@ -418,7 +421,7 @@ class CodeMirror {
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
#addCodeMirrorToDom() {
|
addCodeMirrorToDom() {
|
||||||
this.$textarea.wrap( '<div class="ext-codemirror-wrapper"></div>' );
|
this.$textarea.wrap( '<div class="ext-codemirror-wrapper"></div>' );
|
||||||
|
|
||||||
this.view = new EditorView( {
|
this.view = new EditorView( {
|
||||||
|
@ -521,4 +524,4 @@ class CodeMirror {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CodeMirror;
|
module.exports = CodeMirror;
|
|
@ -1,15 +1,17 @@
|
||||||
import {
|
const {
|
||||||
Decoration,
|
Decoration,
|
||||||
DecorationSet,
|
DecorationSet,
|
||||||
Direction,
|
Direction,
|
||||||
EditorView,
|
EditorView,
|
||||||
PluginSpec,
|
PluginSpec,
|
||||||
|
Prec,
|
||||||
|
RangeSet,
|
||||||
|
RangeSetBuilder,
|
||||||
ViewPlugin,
|
ViewPlugin,
|
||||||
ViewUpdate
|
ViewUpdate,
|
||||||
} from '@codemirror/view';
|
syntaxTree
|
||||||
import { Prec, RangeSet, RangeSetBuilder } from '@codemirror/state';
|
} = require( 'ext.CodeMirror.v6.lib' );
|
||||||
import { syntaxTree } from '@codemirror/language';
|
const mwModeConfig = require( './codemirror.mediawiki.config.js' );
|
||||||
import { mwModeConfig } from './codemirror.mode.mediawiki.config';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Decoration}
|
* @type {Decoration}
|
||||||
|
@ -122,4 +124,4 @@ const bidiIsolationSpec = {
|
||||||
* @module CodeMirrorBidiIsolation
|
* @module CodeMirrorBidiIsolation
|
||||||
* @see https://codemirror.net/examples/bidi/
|
* @see https://codemirror.net/examples/bidi/
|
||||||
*/
|
*/
|
||||||
export default ViewPlugin.fromClass( CodeMirrorBidiIsolation, bidiIsolationSpec );
|
module.exports = ViewPlugin.fromClass( CodeMirrorBidiIsolation, bidiIsolationSpec );
|
|
@ -1,5 +1,9 @@
|
||||||
import { Tag, tags } from '@lezer/highlight';
|
const {
|
||||||
import { TagStyle, StreamParser } from '@codemirror/language';
|
StreamParser,
|
||||||
|
Tag,
|
||||||
|
TagStyle,
|
||||||
|
tags
|
||||||
|
} = require( 'ext.CodeMirror.v6.lib' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the MediaWiki highlighting mode for CodeMirror.
|
* Configuration for the MediaWiki highlighting mode for CodeMirror.
|
||||||
|
@ -10,7 +14,7 @@ import { TagStyle, StreamParser } from '@codemirror/language';
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // within MediaWiki:
|
* // within MediaWiki:
|
||||||
* import { mwModeConfig } from 'ext.CodeMirror.v6.mode.mediawiki';
|
* const { mwModeConfig } = require( 'ext.CodeMirror.v6.mode.mediawiki' );
|
||||||
* // Reference tags by their constants in the tags property.
|
* // Reference tags by their constants in the tags property.
|
||||||
* if ( tag === mwModeConfig.tags.htmlTagBracket ) {
|
* if ( tag === mwModeConfig.tags.htmlTagBracket ) {
|
||||||
* // …
|
* // …
|
||||||
|
@ -118,7 +122,7 @@ class CodeMirrorModeMediaWikiConfig {
|
||||||
* @return {Object<string>}
|
* @return {Object<string>}
|
||||||
*/
|
*/
|
||||||
get tags() {
|
get tags() {
|
||||||
return {
|
return Object.assign( {
|
||||||
apostrophes: 'character',
|
apostrophes: 'character',
|
||||||
apostrophesBold: 'strong',
|
apostrophesBold: 'strong',
|
||||||
apostrophesItalic: 'emphasis',
|
apostrophesItalic: 'emphasis',
|
||||||
|
@ -160,9 +164,8 @@ class CodeMirrorModeMediaWikiConfig {
|
||||||
templateName: 'moduleKeyword',
|
templateName: 'moduleKeyword',
|
||||||
templateVariable: 'atom',
|
templateVariable: 'atom',
|
||||||
templateVariableBracket: 'brace',
|
templateVariableBracket: 'brace',
|
||||||
templateVariableName: 'variableName',
|
templateVariableName: 'variableName'
|
||||||
...this.#customTags
|
}, this.customTags );
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,7 +178,7 @@ class CodeMirrorModeMediaWikiConfig {
|
||||||
* @return {Object<string>}
|
* @return {Object<string>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
get #customTags() {
|
get customTags() {
|
||||||
return {
|
return {
|
||||||
em: 'mw-em',
|
em: 'mw-em',
|
||||||
error: 'mw-error',
|
error: 'mw-error',
|
||||||
|
@ -203,7 +206,7 @@ class CodeMirrorModeMediaWikiConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are custom tokens (a.k.a. tags) that aren't mapped to any of the standardized tags.
|
* These are custom tokens (a.k.a. tags) that aren't mapped to any of the standardized tags.
|
||||||
* Make sure these are also defined in #customTags() above.
|
* Make sure these are also defined in customTags() above.
|
||||||
*
|
*
|
||||||
* TODO: pass parent Tags in Tag.define() where appropriate for better theming.
|
* TODO: pass parent Tags in Tag.define() where appropriate for better theming.
|
||||||
*
|
*
|
||||||
|
@ -516,4 +519,6 @@ class CodeMirrorModeMediaWikiConfig {
|
||||||
* @member CodeMirrorModeMediaWikiConfig
|
* @member CodeMirrorModeMediaWikiConfig
|
||||||
* @type {CodeMirrorModeMediaWikiConfig}
|
* @type {CodeMirrorModeMediaWikiConfig}
|
||||||
*/
|
*/
|
||||||
export const mwModeConfig = new CodeMirrorModeMediaWikiConfig();
|
const mwModeConfig = new CodeMirrorModeMediaWikiConfig();
|
||||||
|
|
||||||
|
module.exports = mwModeConfig;
|
|
@ -1,5 +1,5 @@
|
||||||
import CodeMirror from './codemirror';
|
const CodeMirror = require( 'ext.CodeMirror.v6' );
|
||||||
import mediaWikiLang from './codemirror.mode.mediawiki';
|
const mediaWikiLang = require( 'ext.CodeMirror.v6.mode.mediawiki' );
|
||||||
|
|
||||||
const textarea = document.getElementById( 'wpTextbox1' );
|
const textarea = document.getElementById( 'wpTextbox1' );
|
||||||
const cm = new CodeMirror( textarea );
|
const cm = new CodeMirror( textarea );
|
|
@ -1,15 +1,15 @@
|
||||||
import {
|
const {
|
||||||
HighlightStyle,
|
HighlightStyle,
|
||||||
LanguageSupport,
|
LanguageSupport,
|
||||||
StreamLanguage,
|
StreamLanguage,
|
||||||
StreamParser,
|
StreamParser,
|
||||||
StringStream,
|
StringStream,
|
||||||
|
Tag,
|
||||||
syntaxHighlighting
|
syntaxHighlighting
|
||||||
} from '@codemirror/language';
|
} = require( 'ext.CodeMirror.v6.lib' );
|
||||||
import { mwModeConfig as modeConfig } from './codemirror.mode.mediawiki.config';
|
const mwModeConfig = require( './codemirror.mediawiki.config.js' );
|
||||||
import { Tag } from '@lezer/highlight';
|
const bidiIsolationExtension = require( './codemirror.mediawiki.bidiIsolation.js' );
|
||||||
import templateFoldingExtension from './codemirror.templateFolding';
|
const templateFoldingExtension = require( './codemirror.mediawiki.templateFolding.js' );
|
||||||
import bidiIsolationExtension from './codemirror.bidiIsolation';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MediaWiki language support for CodeMirror 6.
|
* MediaWiki language support for CodeMirror 6.
|
||||||
|
@ -47,11 +47,11 @@ class CodeMirrorModeMediaWiki {
|
||||||
this.oldStyle = null;
|
this.oldStyle = null;
|
||||||
this.tokens = [];
|
this.tokens = [];
|
||||||
this.oldTokens = [];
|
this.oldTokens = [];
|
||||||
this.tokenTable = modeConfig.tokenTable;
|
this.tokenTable = mwModeConfig.tokenTable;
|
||||||
this.registerGroundTokens();
|
this.registerGroundTokens();
|
||||||
|
|
||||||
// Dynamically register any tags that aren't already in CodeMirrorModeMediaWikiConfig
|
// Dynamically register any tags that aren't already in CodeMirrorModeMediaWikiConfig
|
||||||
Object.keys( this.config.tags ).forEach( ( tag ) => modeConfig.addTag( tag ) );
|
Object.keys( this.config.tags ).forEach( ( tag ) => mwModeConfig.addTag( tag ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +94,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
'mw-template3-ext3-link-ground',
|
'mw-template3-ext3-link-ground',
|
||||||
'mw-template3-ground',
|
'mw-template3-ground',
|
||||||
'mw-template3-link-ground'
|
'mw-template3-link-ground'
|
||||||
].forEach( ( ground ) => modeConfig.addToken( ground ) );
|
].forEach( ( ground ) => mwModeConfig.addToken( ground ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
eatHtmlEntity( stream, style ) {
|
eatHtmlEntity( stream, style ) {
|
||||||
|
@ -109,7 +109,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
ok = stream.eatWhile( /[\w.\-:]/ ) && stream.eat( ';' );
|
ok = stream.eatWhile( /[\w.\-:]/ ) && stream.eat( ';' );
|
||||||
}
|
}
|
||||||
if ( ok ) {
|
if ( ok ) {
|
||||||
return modeConfig.tags.htmlEntity;
|
return mwModeConfig.tags.htmlEntity;
|
||||||
}
|
}
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
@ -120,10 +120,10 @@ class CodeMirrorModeMediaWiki {
|
||||||
|
|
||||||
makeStyle( style, state, endGround ) {
|
makeStyle( style, state, endGround ) {
|
||||||
if ( this.isBold || state.nDt > 0 ) {
|
if ( this.isBold || state.nDt > 0 ) {
|
||||||
style += ' ' + modeConfig.tags.strong;
|
style += ' ' + mwModeConfig.tags.strong;
|
||||||
}
|
}
|
||||||
if ( this.isItalic ) {
|
if ( this.isItalic ) {
|
||||||
style += ' ' + modeConfig.tags.em;
|
style += ' ' + mwModeConfig.tags.em;
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( style, state, endGround );
|
return this.makeLocalStyle( style, state, endGround );
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( stream.eat( char ) ) {
|
if ( stream.eat( char ) ) {
|
||||||
return this.makeLocalStyle( style, state );
|
return this.makeLocalStyle( style, state );
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( modeConfig.tags.error, state );
|
return this.makeLocalStyle( mwModeConfig.tags.error, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,89 +205,89 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( stream.match( /^[^&<[{~]+/ ) ) {
|
if ( stream.match( /^[^&<[{~]+/ ) ) {
|
||||||
if ( stream.eol() ) {
|
if ( stream.eol() ) {
|
||||||
stream.backUp( count );
|
stream.backUp( count );
|
||||||
state.tokenize = this.eatEnd( modeConfig.tags.sectionHeader );
|
state.tokenize = this.eatEnd( mwModeConfig.tags.sectionHeader );
|
||||||
} else if ( stream.match( /^<!--(?!.*?-->.*?=)/, false ) ) {
|
} else if ( stream.match( /^<!--(?!.*?-->.*?=)/, false ) ) {
|
||||||
// T171074: handle trailing comments
|
// T171074: handle trailing comments
|
||||||
stream.backUp( count );
|
stream.backUp( count );
|
||||||
state.tokenize = this.eatBlock( modeConfig.tags.sectionHeader, '<!--', false );
|
state.tokenize = this.eatBlock( mwModeConfig.tags.sectionHeader, '<!--', false );
|
||||||
}
|
}
|
||||||
return modeConfig.tags.section; // style is null
|
return mwModeConfig.tags.section; // style is null
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.section )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.section )( stream, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inVariable( stream, state ) {
|
inVariable( stream, state ) {
|
||||||
if ( stream.match( /^[^{}|]+/ ) ) {
|
if ( stream.match( /^[^{}|]+/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariableName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariableName, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '|' ) ) {
|
if ( stream.eat( '|' ) ) {
|
||||||
state.tokenize = this.inVariableDefault.bind( this );
|
state.tokenize = this.inVariableDefault.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariableDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( '}}}' ) ) {
|
if ( stream.match( '}}}' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariableBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariableBracket, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( '{{{' ) ) {
|
if ( stream.match( '{{{' ) ) {
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariableBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariableBracket, state );
|
||||||
}
|
}
|
||||||
stream.next();
|
stream.next();
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariableName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariableName, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
inVariableDefault( stream, state ) {
|
inVariableDefault( stream, state ) {
|
||||||
if ( stream.match( /^[^{}[<&~]+/ ) ) {
|
if ( stream.match( /^[^{}[<&~]+/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariable, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariable, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( '}}}' ) ) {
|
if ( stream.match( '}}}' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateVariableBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateVariableBracket, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.templateVariable )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.templateVariable )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
inParserFunctionName( stream, state ) {
|
inParserFunctionName( stream, state ) {
|
||||||
// FIXME: {{#name}} and {{uc}} are wrong, must have ':'
|
// FIXME: {{#name}} and {{uc}} are wrong, must have ':'
|
||||||
if ( stream.match( /^#?[^:}{~]+/ ) ) {
|
if ( stream.match( /^#?[^:}{~]+/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.parserFunctionName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.parserFunctionName, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( ':' ) ) {
|
if ( stream.eat( ':' ) ) {
|
||||||
state.tokenize = this.inParserFunctionArguments.bind( this );
|
state.tokenize = this.inParserFunctionArguments.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.parserFunctionDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.parserFunctionDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( '}}' ) ) {
|
if ( stream.match( '}}' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.parserFunctionBracket, state, 'nExt' );
|
return this.makeLocalStyle( mwModeConfig.tags.parserFunctionBracket, state, 'nExt' );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.parserFunction )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.parserFunction )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
inParserFunctionArguments( stream, state ) {
|
inParserFunctionArguments( stream, state ) {
|
||||||
if ( stream.match( /^[^|}{[<&~]+/ ) ) {
|
if ( stream.match( /^[^|}{[<&~]+/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.parserFunction, state );
|
return this.makeLocalStyle( mwModeConfig.tags.parserFunction, state );
|
||||||
} else if ( stream.eat( '|' ) ) {
|
} else if ( stream.eat( '|' ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.parserFunctionDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.parserFunctionDelimiter, state );
|
||||||
} else if ( stream.match( '}}' ) ) {
|
} else if ( stream.match( '}}' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.parserFunctionBracket, state, 'nExt' );
|
return this.makeLocalStyle( mwModeConfig.tags.parserFunctionBracket, state, 'nExt' );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.parserFunction )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.parserFunction )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
eatTemplatePageName( haveAte ) {
|
eatTemplatePageName( haveAte ) {
|
||||||
return ( stream, state ) => {
|
return ( stream, state ) => {
|
||||||
if ( stream.match( /^[\s\u00a0]*\|[\s\u00a0]*/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*\|[\s\u00a0]*/ ) ) {
|
||||||
state.tokenize = this.eatTemplateArgument( true );
|
state.tokenize = this.eatTemplateArgument( true );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*\}\}/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*\}\}/ ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateBracket, state, 'nTemplate' );
|
return this.makeLocalStyle( mwModeConfig.tags.templateBracket, state, 'nTemplate' );
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*<!--.*?-->/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*<!--.*?-->/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.comment, state );
|
return this.makeLocalStyle( mwModeConfig.tags.comment, state );
|
||||||
}
|
}
|
||||||
if ( haveAte && stream.sol() ) {
|
if ( haveAte && stream.sol() ) {
|
||||||
// @todo error message
|
// @todo error message
|
||||||
|
@ -297,14 +297,14 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*[^\s\u00a0|}<{&~]+/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*[^\s\u00a0|}<{&~]+/ ) ) {
|
||||||
state.tokenize = this.eatTemplatePageName( true );
|
state.tokenize = this.eatTemplatePageName( true );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateName, state );
|
||||||
} else if ( stream.eatSpace() ) {
|
} else if ( stream.eatSpace() ) {
|
||||||
if ( stream.eol() === true ) {
|
if ( stream.eol() === true ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateName, state );
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateName, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.templateName )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.templateName )( stream, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,19 +313,19 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( expectArgName && stream.eatWhile( /[^=|}{[<&~]/ ) ) {
|
if ( expectArgName && stream.eatWhile( /[^=|}{[<&~]/ ) ) {
|
||||||
if ( stream.eat( '=' ) ) {
|
if ( stream.eat( '=' ) ) {
|
||||||
state.tokenize = this.eatTemplateArgument( false );
|
state.tokenize = this.eatTemplateArgument( false );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateArgumentName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateArgumentName, state );
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( modeConfig.tags.template, state );
|
return this.makeLocalStyle( mwModeConfig.tags.template, state );
|
||||||
} else if ( stream.eatWhile( /[^|}{[<&~]/ ) ) {
|
} else if ( stream.eatWhile( /[^|}{[<&~]/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.template, state );
|
return this.makeLocalStyle( mwModeConfig.tags.template, state );
|
||||||
} else if ( stream.eat( '|' ) ) {
|
} else if ( stream.eat( '|' ) ) {
|
||||||
state.tokenize = this.eatTemplateArgument( true );
|
state.tokenize = this.eatTemplateArgument( true );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateDelimiter, state );
|
||||||
} else if ( stream.match( '}}' ) ) {
|
} else if ( stream.match( '}}' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateBracket, state, 'nTemplate' );
|
return this.makeLocalStyle( mwModeConfig.tags.templateBracket, state, 'nTemplate' );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.template )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.template )( stream, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
} else {
|
} else {
|
||||||
state.tokenize = this.inExternalLink.bind( this );
|
state.tokenize = this.inExternalLink.bind( this );
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( modeConfig.tags.extLinkProtocol, state );
|
return this.makeLocalStyle( mwModeConfig.tags.extLinkProtocol, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*\]/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*\]/ ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.extLinkBracket, state, 'nLink' );
|
return this.makeLocalStyle( mwModeConfig.tags.extLinkBracket, state, 'nLink' );
|
||||||
}
|
}
|
||||||
if ( stream.eatSpace() ) {
|
if ( stream.eatSpace() ) {
|
||||||
state.tokenize = this.inExternalLinkText.bind( this );
|
state.tokenize = this.inExternalLinkText.bind( this );
|
||||||
|
@ -369,9 +369,9 @@ class CodeMirrorModeMediaWiki {
|
||||||
stream.next();
|
stream.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.makeStyle( modeConfig.tags.extLink, state );
|
return this.makeStyle( mwModeConfig.tags.extLink, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.extLink )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.extLink )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
inExternalLinkText( stream, state ) {
|
inExternalLinkText( stream, state ) {
|
||||||
|
@ -383,12 +383,12 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
if ( stream.eat( ']' ) ) {
|
if ( stream.eat( ']' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.extLinkBracket, state, 'nLink' );
|
return this.makeLocalStyle( mwModeConfig.tags.extLinkBracket, state, 'nLink' );
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[^'\]{&~<]+/ ) ) {
|
if ( stream.match( /^[^'\]{&~<]+/ ) ) {
|
||||||
return this.makeStyle( modeConfig.tags.extLinkText, state );
|
return this.makeStyle( mwModeConfig.tags.extLinkText, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.extLinkText )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.extLinkText )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
inLink( stream, state ) {
|
inLink( stream, state ) {
|
||||||
|
@ -400,24 +400,24 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*#[\s\u00a0]*/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*#[\s\u00a0]*/ ) ) {
|
||||||
state.tokenize = this.inLinkToSection.bind( this );
|
state.tokenize = this.inLinkToSection.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.link, state );
|
return this.makeLocalStyle( mwModeConfig.tags.link, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*\|[\s\u00a0]*/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*\|[\s\u00a0]*/ ) ) {
|
||||||
state.tokenize = this.eatLinkText();
|
state.tokenize = this.eatLinkText();
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.linkDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*\]\]/ ) ) {
|
if ( stream.match( /^[\s\u00a0]*\]\]/ ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkBracket, state, 'nLink' );
|
return this.makeLocalStyle( mwModeConfig.tags.linkBracket, state, 'nLink' );
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[\s\u00a0]*[^\s\u00a0#|\]&~{]+/ ) || stream.eatSpace() ) {
|
if ( stream.match( /^[\s\u00a0]*[^\s\u00a0#|\]&~{]+/ ) || stream.eatSpace() ) {
|
||||||
return this.makeStyle(
|
return this.makeStyle(
|
||||||
`${ modeConfig.tags.linkPageName } ${ modeConfig.tags.pageName }`,
|
`${ mwModeConfig.tags.linkPageName } ${ mwModeConfig.tags.pageName }`,
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return this.eatWikiText(
|
return this.eatWikiText(
|
||||||
`${ modeConfig.tags.linkPageName } ${ modeConfig.tags.pageName }`
|
`${ mwModeConfig.tags.linkPageName } ${ mwModeConfig.tags.pageName }`
|
||||||
)( stream, state );
|
)( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,17 +430,17 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
// FIXME '{{' breaks links, example: [[z{{page]]
|
// FIXME '{{' breaks links, example: [[z{{page]]
|
||||||
if ( stream.match( /^[^|\]&~{}]+/ ) ) {
|
if ( stream.match( /^[^|\]&~{}]+/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkToSection, state );
|
return this.makeLocalStyle( mwModeConfig.tags.linkToSection, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '|' ) ) {
|
if ( stream.eat( '|' ) ) {
|
||||||
state.tokenize = this.eatLinkText();
|
state.tokenize = this.eatLinkText();
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.linkDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( ']]' ) ) {
|
if ( stream.match( ']]' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkBracket, state, 'nLink' );
|
return this.makeLocalStyle( mwModeConfig.tags.linkBracket, state, 'nLink' );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.linkToSection )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.linkToSection )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
eatLinkText() {
|
eatLinkText() {
|
||||||
|
@ -449,28 +449,28 @@ class CodeMirrorModeMediaWiki {
|
||||||
let tmpstyle;
|
let tmpstyle;
|
||||||
if ( stream.match( ']]' ) ) {
|
if ( stream.match( ']]' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkBracket, state, 'nLink' );
|
return this.makeLocalStyle( mwModeConfig.tags.linkBracket, state, 'nLink' );
|
||||||
}
|
}
|
||||||
if ( stream.match( '\'\'\'' ) ) {
|
if ( stream.match( '\'\'\'' ) ) {
|
||||||
linkIsBold = !linkIsBold;
|
linkIsBold = !linkIsBold;
|
||||||
return this.makeLocalStyle(
|
return this.makeLocalStyle(
|
||||||
`${ modeConfig.tags.linkText } ${ modeConfig.tags.apostrophes }`,
|
`${ mwModeConfig.tags.linkText } ${ mwModeConfig.tags.apostrophes }`,
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( stream.match( '\'\'' ) ) {
|
if ( stream.match( '\'\'' ) ) {
|
||||||
linkIsItalic = !linkIsItalic;
|
linkIsItalic = !linkIsItalic;
|
||||||
return this.makeLocalStyle(
|
return this.makeLocalStyle(
|
||||||
`${ modeConfig.tags.linkText } ${ modeConfig.tags.apostrophes }`,
|
`${ mwModeConfig.tags.linkText } ${ mwModeConfig.tags.apostrophes }`,
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
tmpstyle = modeConfig.tags.linkText;
|
tmpstyle = mwModeConfig.tags.linkText;
|
||||||
if ( linkIsBold ) {
|
if ( linkIsBold ) {
|
||||||
tmpstyle += ' ' + modeConfig.tags.strong;
|
tmpstyle += ' ' + mwModeConfig.tags.strong;
|
||||||
}
|
}
|
||||||
if ( linkIsItalic ) {
|
if ( linkIsItalic ) {
|
||||||
tmpstyle += ' ' + modeConfig.tags.em;
|
tmpstyle += ' ' + mwModeConfig.tags.em;
|
||||||
}
|
}
|
||||||
if ( stream.match( /^[^'\]{&~<]+/ ) ) {
|
if ( stream.match( /^[^'\]{&~<]+/ ) ) {
|
||||||
return this.makeStyle( tmpstyle, state );
|
return this.makeStyle( tmpstyle, state );
|
||||||
|
@ -490,23 +490,23 @@ class CodeMirrorModeMediaWiki {
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
|
|
||||||
if ( isHtmlTag ) {
|
if ( isHtmlTag ) {
|
||||||
if ( isCloseTag && !modeConfig.implicitlyClosedHtmlTags[ name ] ) {
|
if ( isCloseTag && !mwModeConfig.implicitlyClosedHtmlTags[ name ] ) {
|
||||||
state.tokenize = this.eatChar( '>', modeConfig.tags.htmlTagBracket );
|
state.tokenize = this.eatChar( '>', mwModeConfig.tags.htmlTagBracket );
|
||||||
} else {
|
} else {
|
||||||
state.tokenize = this.eatHtmlTagAttribute( name );
|
state.tokenize = this.eatHtmlTagAttribute( name );
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( modeConfig.tags.htmlTagName, state );
|
return this.makeLocalStyle( mwModeConfig.tags.htmlTagName, state );
|
||||||
}
|
}
|
||||||
// it is the extension tag
|
// it is the extension tag
|
||||||
if ( isCloseTag ) {
|
if ( isCloseTag ) {
|
||||||
state.tokenize = this.eatChar(
|
state.tokenize = this.eatChar(
|
||||||
'>',
|
'>',
|
||||||
`${ modeConfig.tags.extTagBracket } mw-ext-${ name }`
|
`${ mwModeConfig.tags.extTagBracket } mw-ext-${ name }`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
state.tokenize = this.eatExtTagAttribute( name );
|
state.tokenize = this.eatExtTagAttribute( name );
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( `${ modeConfig.tags.extTagName } mw-ext-${ name }`, state );
|
return this.makeLocalStyle( `${ mwModeConfig.tags.extTagName } mw-ext-${ name }`, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,20 +514,20 @@ class CodeMirrorModeMediaWiki {
|
||||||
return ( stream, state ) => {
|
return ( stream, state ) => {
|
||||||
|
|
||||||
if ( stream.match( /^(?:"[^<">]*"|'[^<'>]*'|[^>/<{&~])+/ ) ) {
|
if ( stream.match( /^(?:"[^<">]*"|'[^<'>]*'|[^>/<{&~])+/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.htmlTagAttribute, state );
|
return this.makeLocalStyle( mwModeConfig.tags.htmlTagAttribute, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '>' ) ) {
|
if ( stream.eat( '>' ) ) {
|
||||||
if ( !( name in modeConfig.implicitlyClosedHtmlTags ) ) {
|
if ( !( name in mwModeConfig.implicitlyClosedHtmlTags ) ) {
|
||||||
state.inHtmlTag.push( name );
|
state.inHtmlTag.push( name );
|
||||||
}
|
}
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.htmlTagBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.htmlTagBracket, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( '/>' ) ) {
|
if ( stream.match( '/>' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.htmlTagBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.htmlTagBracket, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.htmlTagAttribute )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.htmlTagAttribute )( stream, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +546,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
return ( stream, state ) => {
|
return ( stream, state ) => {
|
||||||
|
|
||||||
if ( stream.match( /^(?:"[^">]*"|'[^'>]*'|[^>/<{&~])+/ ) ) {
|
if ( stream.match( /^(?:"[^">]*"|'[^'>]*'|[^>/<{&~])+/ ) ) {
|
||||||
return this.makeLocalStyle( `${ modeConfig.tags.extTagAttribute } mw-ext-${ name }`, state );
|
return this.makeLocalStyle( `${ mwModeConfig.tags.extTagAttribute } mw-ext-${ name }`, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '>' ) ) {
|
if ( stream.eat( '>' ) ) {
|
||||||
state.extName = name;
|
state.extName = name;
|
||||||
|
@ -570,13 +570,13 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.tokenize = this.eatExtTagArea( name );
|
state.tokenize = this.eatExtTagArea( name );
|
||||||
return this.makeLocalStyle( `${ modeConfig.tags.extTagBracket } mw-ext-${ name }`, state );
|
return this.makeLocalStyle( `${ mwModeConfig.tags.extTagBracket } mw-ext-${ name }`, state );
|
||||||
}
|
}
|
||||||
if ( stream.match( '/>' ) ) {
|
if ( stream.match( '/>' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( `${ modeConfig.tags.extTagBracket } mw-ext-${ name }`, state );
|
return this.makeLocalStyle( `${ mwModeConfig.tags.extTagBracket } mw-ext-${ name }`, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( `${ modeConfig.tags.extTagAttribute } mw-ext-${ name }` )( stream, state );
|
return this.eatWikiText( `${ mwModeConfig.tags.extTagAttribute } mw-ext-${ name }` )( stream, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +615,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
stream.next(); // eat <
|
stream.next(); // eat <
|
||||||
stream.next(); // eat /
|
stream.next(); // eat /
|
||||||
state.tokenize = this.eatTagName( name.length, true, false );
|
state.tokenize = this.eatTagName( name.length, true, false );
|
||||||
return this.makeLocalStyle( `${ modeConfig.tags.extTagBracket } mw-ext-${ name }`, state );
|
return this.makeLocalStyle( `${ mwModeConfig.tags.extTagBracket } mw-ext-${ name }`, state );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +623,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
return ( stream, state ) => {
|
return ( stream, state ) => {
|
||||||
let ret;
|
let ret;
|
||||||
if ( state.extMode === false ) {
|
if ( state.extMode === false ) {
|
||||||
ret = modeConfig.tags.extTag;
|
ret = mwModeConfig.tags.extTag;
|
||||||
stream.skipToEnd();
|
stream.skipToEnd();
|
||||||
} else {
|
} else {
|
||||||
ret = `mw-tag-${ state.extName } ` +
|
ret = `mw-tag-${ state.extName } ` +
|
||||||
|
@ -643,7 +643,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
stream.match( '{|' );
|
stream.match( '{|' );
|
||||||
stream.eatSpace();
|
stream.eatSpace();
|
||||||
state.tokenize = this.inTableDefinition.bind( this );
|
state.tokenize = this.inTableDefinition.bind( this );
|
||||||
return modeConfig.tags.tableBracket;
|
return mwModeConfig.tags.tableBracket;
|
||||||
}
|
}
|
||||||
|
|
||||||
inTableDefinition( stream, state ) {
|
inTableDefinition( stream, state ) {
|
||||||
|
@ -651,7 +651,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
state.tokenize = this.inTable.bind( this );
|
state.tokenize = this.inTable.bind( this );
|
||||||
return this.inTable( stream, state );
|
return this.inTable( stream, state );
|
||||||
}
|
}
|
||||||
return this.eatWikiText( modeConfig.tags.tableDefinition )( stream, state );
|
return this.eatWikiText( mwModeConfig.tags.tableDefinition )( stream, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
inTable( stream, state ) {
|
inTable( stream, state ) {
|
||||||
|
@ -661,25 +661,25 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( stream.eat( '-' ) ) {
|
if ( stream.eat( '-' ) ) {
|
||||||
stream.eatSpace();
|
stream.eatSpace();
|
||||||
state.tokenize = this.inTableDefinition.bind( this );
|
state.tokenize = this.inTableDefinition.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '+' ) ) {
|
if ( stream.eat( '+' ) ) {
|
||||||
stream.eatSpace();
|
stream.eatSpace();
|
||||||
state.tokenize = this.eatTableRow( true, false, true );
|
state.tokenize = this.eatTableRow( true, false, true );
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '}' ) ) {
|
if ( stream.eat( '}' ) ) {
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableBracket, state );
|
||||||
}
|
}
|
||||||
stream.eatSpace();
|
stream.eatSpace();
|
||||||
state.tokenize = this.eatTableRow( true, false );
|
state.tokenize = this.eatTableRow( true, false );
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( stream.eat( '!' ) ) {
|
if ( stream.eat( '!' ) ) {
|
||||||
stream.eatSpace();
|
stream.eatSpace();
|
||||||
state.tokenize = this.eatTableRow( true, true );
|
state.tokenize = this.eatTableRow( true, true );
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableDelimiter, state );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.eatWikiText( '' )( stream, state );
|
return this.eatWikiText( '' )( stream, state );
|
||||||
|
@ -689,9 +689,9 @@ class CodeMirrorModeMediaWiki {
|
||||||
eatTableRow( isStart, isHead, isCaption ) {
|
eatTableRow( isStart, isHead, isCaption ) {
|
||||||
let tag = '';
|
let tag = '';
|
||||||
if ( isCaption ) {
|
if ( isCaption ) {
|
||||||
tag = modeConfig.tags.tableCaption;
|
tag = mwModeConfig.tags.tableCaption;
|
||||||
} else if ( isHead ) {
|
} else if ( isHead ) {
|
||||||
tag = modeConfig.tags.strong;
|
tag = mwModeConfig.tags.strong;
|
||||||
}
|
}
|
||||||
return ( stream, state ) => {
|
return ( stream, state ) => {
|
||||||
if ( stream.sol() ) {
|
if ( stream.sol() ) {
|
||||||
|
@ -707,11 +707,11 @@ class CodeMirrorModeMediaWiki {
|
||||||
this.isBold = false;
|
this.isBold = false;
|
||||||
this.isItalic = false;
|
this.isItalic = false;
|
||||||
state.tokenize = this.eatTableRow( true, isHead, isCaption );
|
state.tokenize = this.eatTableRow( true, isHead, isCaption );
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableDelimiter, state );
|
||||||
}
|
}
|
||||||
if ( isStart && stream.eat( '|' ) ) {
|
if ( isStart && stream.eat( '|' ) ) {
|
||||||
state.tokenize = this.eatTableRow( false, isHead, isCaption );
|
state.tokenize = this.eatTableRow( false, isHead, isCaption );
|
||||||
return this.makeLocalStyle( modeConfig.tags.tableDelimiter, state );
|
return this.makeLocalStyle( mwModeConfig.tags.tableDelimiter, state );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.eatWikiText( tag )( stream, state );
|
return this.eatWikiText( tag )( stream, state );
|
||||||
|
@ -721,7 +721,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
eatFreeExternalLinkProtocol( stream, state ) {
|
eatFreeExternalLinkProtocol( stream, state ) {
|
||||||
stream.match( this.urlProtocols );
|
stream.match( this.urlProtocols );
|
||||||
state.tokenize = this.eatFreeExternalLink.bind( this );
|
state.tokenize = this.eatFreeExternalLink.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLinkProtocol, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLinkProtocol, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
eatFreeExternalLink( stream, state ) {
|
eatFreeExternalLink( stream, state ) {
|
||||||
|
@ -731,24 +731,24 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( stream.peek() === '~' ) {
|
if ( stream.peek() === '~' ) {
|
||||||
if ( !stream.match( /^~~~+/, false ) ) {
|
if ( !stream.match( /^~~~+/, false ) ) {
|
||||||
stream.match( /^~*/ );
|
stream.match( /^~*/ );
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLink, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLink, state );
|
||||||
}
|
}
|
||||||
} else if ( stream.peek() === '{' ) {
|
} else if ( stream.peek() === '{' ) {
|
||||||
if ( !stream.match( '{{', false ) ) {
|
if ( !stream.match( '{{', false ) ) {
|
||||||
stream.next();
|
stream.next();
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLink, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLink, state );
|
||||||
}
|
}
|
||||||
} else if ( stream.peek() === '\'' ) {
|
} else if ( stream.peek() === '\'' ) {
|
||||||
if ( !stream.match( '\'\'', false ) ) {
|
if ( !stream.match( '\'\'', false ) ) {
|
||||||
stream.next();
|
stream.next();
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLink, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLink, state );
|
||||||
}
|
}
|
||||||
} else if ( stream.match( /^[).,]+(?=[^\s\u00a0{[\]<>~).,])/ ) ) {
|
} else if ( stream.match( /^[).,]+(?=[^\s\u00a0{[\]<>~).,])/ ) ) {
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLink, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLink, state );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.tokenize = state.stack.pop();
|
state.tokenize = state.stack.pop();
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLink, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLink, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
eatList( stream, state ) {
|
eatList( stream, state ) {
|
||||||
|
@ -757,7 +757,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( mt && !this.isNested( state ) && mt[ 0 ].includes( ';' ) ) {
|
if ( mt && !this.isNested( state ) && mt[ 0 ].includes( ';' ) ) {
|
||||||
state.nDt += mt[ 0 ].split( ';' ).length - 1;
|
state.nDt += mt[ 0 ].split( ';' ).length - 1;
|
||||||
}
|
}
|
||||||
return this.makeLocalStyle( modeConfig.tags.list, state );
|
return this.makeLocalStyle( mwModeConfig.tags.list, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -781,13 +781,13 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( !stream.match( '//', false ) && stream.match( this.urlProtocols ) ) {
|
if ( !stream.match( '//', false ) && stream.match( this.urlProtocols ) ) {
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.eatFreeExternalLink.bind( this );
|
state.tokenize = this.eatFreeExternalLink.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.freeExtLinkProtocol, state );
|
return this.makeLocalStyle( mwModeConfig.tags.freeExtLinkProtocol, state );
|
||||||
}
|
}
|
||||||
ch = stream.next();
|
ch = stream.next();
|
||||||
switch ( ch ) {
|
switch ( ch ) {
|
||||||
case '-':
|
case '-':
|
||||||
if ( stream.match( /^---+/ ) ) {
|
if ( stream.match( /^---+/ ) ) {
|
||||||
return modeConfig.tags.hr;
|
return mwModeConfig.tags.hr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
|
@ -798,7 +798,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
stream.backUp( tmp[ 2 ].length );
|
stream.backUp( tmp[ 2 ].length );
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.eatSectionHeader( tmp[ 3 ].length );
|
state.tokenize = this.eatSectionHeader( tmp[ 3 ].length );
|
||||||
return modeConfig.tags.sectionHeader + ' ' +
|
return mwModeConfig.tags.sectionHeader + ' ' +
|
||||||
/**
|
/**
|
||||||
* Tokens used here include:
|
* Tokens used here include:
|
||||||
* - cm-mw-section-1
|
* - cm-mw-section-1
|
||||||
|
@ -808,12 +808,12 @@ class CodeMirrorModeMediaWiki {
|
||||||
* - cm-mw-section-5
|
* - cm-mw-section-5
|
||||||
* - cm-mw-section-6
|
* - cm-mw-section-6
|
||||||
*/
|
*/
|
||||||
modeConfig.tags[ `sectionHeader${ tmp[ 1 ].length + 1 }` ];
|
mwModeConfig.tags[ `sectionHeader${ tmp[ 1 ].length + 1 }` ];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
stream.backUp( 1 );
|
stream.backUp( 1 );
|
||||||
// fall through
|
// fall through
|
||||||
case '*':
|
case '*':
|
||||||
case '#':
|
case '#':
|
||||||
return this.eatList( stream, state );
|
return this.eatList( stream, state );
|
||||||
|
@ -831,11 +831,11 @@ class CodeMirrorModeMediaWiki {
|
||||||
if ( stream.match( /^:+/ ) ) { // ::{|
|
if ( stream.match( /^:+/ ) ) { // ::{|
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.eatStartTable.bind( this );
|
state.tokenize = this.eatStartTable.bind( this );
|
||||||
return modeConfig.tags.indenting;
|
return mwModeConfig.tags.indenting;
|
||||||
}
|
}
|
||||||
stream.eat( '{' );
|
stream.eat( '{' );
|
||||||
} else {
|
} else {
|
||||||
return modeConfig.tags.skipFormatting;
|
return mwModeConfig.tags.skipFormatting;
|
||||||
}
|
}
|
||||||
// break is not necessary here
|
// break is not necessary here
|
||||||
// falls through
|
// falls through
|
||||||
|
@ -844,7 +844,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
stream.eatSpace();
|
stream.eatSpace();
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.inTableDefinition.bind( this );
|
state.tokenize = this.inTableDefinition.bind( this );
|
||||||
return modeConfig.tags.tableBracket;
|
return mwModeConfig.tags.tableBracket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -867,10 +867,10 @@ class CodeMirrorModeMediaWiki {
|
||||||
this.prepareItalicForCorrection( stream );
|
this.prepareItalicForCorrection( stream );
|
||||||
}
|
}
|
||||||
this.isBold = !this.isBold;
|
this.isBold = !this.isBold;
|
||||||
return this.makeLocalStyle( modeConfig.tags.apostrophesBold, state );
|
return this.makeLocalStyle( mwModeConfig.tags.apostrophesBold, state );
|
||||||
} else if ( stream.eat( '\'' ) ) { // italic
|
} else if ( stream.eat( '\'' ) ) { // italic
|
||||||
this.isItalic = !this.isItalic;
|
this.isItalic = !this.isItalic;
|
||||||
return this.makeLocalStyle( modeConfig.tags.apostrophesItalic, state );
|
return this.makeLocalStyle( mwModeConfig.tags.apostrophesItalic, state );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
|
@ -880,7 +880,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
state.nLink++;
|
state.nLink++;
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.inLink.bind( this );
|
state.tokenize = this.inLink.bind( this );
|
||||||
return this.makeLocalStyle( modeConfig.tags.linkBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.linkBracket, state );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mt = stream.match( this.urlProtocols );
|
mt = stream.match( this.urlProtocols );
|
||||||
|
@ -889,7 +889,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
stream.backUp( mt[ 0 ].length );
|
stream.backUp( mt[ 0 ].length );
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.eatExternalLinkProtocol( mt[ 0 ].length );
|
state.tokenize = this.eatExternalLinkProtocol( mt[ 0 ].length );
|
||||||
return this.makeLocalStyle( modeConfig.tags.extLinkBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.extLinkBracket, state );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -901,7 +901,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.inVariable.bind( this );
|
state.tokenize = this.inVariable.bind( this );
|
||||||
return this.makeLocalStyle(
|
return this.makeLocalStyle(
|
||||||
modeConfig.tags.templateVariableBracket,
|
mwModeConfig.tags.templateVariableBracket,
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
} else if ( stream.match( /^{(?!{(?!{))[\s\u00a0]*/ ) ) {
|
} else if ( stream.match( /^{(?!{(?!{))[\s\u00a0]*/ ) ) {
|
||||||
|
@ -911,7 +911,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.inParserFunctionName.bind( this );
|
state.tokenize = this.inParserFunctionName.bind( this );
|
||||||
return this.makeLocalStyle(
|
return this.makeLocalStyle(
|
||||||
modeConfig.tags.parserFunctionBracket,
|
mwModeConfig.tags.parserFunctionBracket,
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -931,7 +931,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.inParserFunctionName.bind( this );
|
state.tokenize = this.inParserFunctionName.bind( this );
|
||||||
return this.makeLocalStyle(
|
return this.makeLocalStyle(
|
||||||
modeConfig.tags.parserFunctionBracket,
|
mwModeConfig.tags.parserFunctionBracket,
|
||||||
state
|
state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -940,39 +940,39 @@ class CodeMirrorModeMediaWiki {
|
||||||
state.nTemplate++;
|
state.nTemplate++;
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.eatTemplatePageName( false );
|
state.tokenize = this.eatTemplatePageName( false );
|
||||||
return this.makeLocalStyle( modeConfig.tags.templateBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.templateBracket, state );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
isCloseTag = !!stream.eat( '/' );
|
isCloseTag = !!stream.eat( '/' );
|
||||||
tagname = stream.match( /^[^>/\s\u00a0.*,[\]{}$^+?|/\\'`~<=!@#%&()-]+/ );
|
tagname = stream.match( /^[^>/\s\u00a0.*,[\]{}$^+?|/\\'`~<=!@#%&()-]+/ );
|
||||||
if ( stream.match( '!--' ) ) { // comment
|
if ( stream.match( '!--' ) ) { // comment
|
||||||
return chain( this.eatBlock( modeConfig.tags.comment, '-->' ) );
|
return chain( this.eatBlock( mwModeConfig.tags.comment, '-->' ) );
|
||||||
}
|
}
|
||||||
if ( tagname ) {
|
if ( tagname ) {
|
||||||
tagname = tagname[ 0 ].toLowerCase();
|
tagname = tagname[ 0 ].toLowerCase();
|
||||||
if ( tagname in this.config.tags ) {
|
if ( tagname in this.config.tags ) {
|
||||||
// Parser function
|
// Parser function
|
||||||
if ( isCloseTag === true ) {
|
if ( isCloseTag === true ) {
|
||||||
return modeConfig.tags.error;
|
return mwModeConfig.tags.error;
|
||||||
}
|
}
|
||||||
stream.backUp( tagname.length );
|
stream.backUp( tagname.length );
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
state.tokenize = this.eatTagName( tagname.length, isCloseTag, false );
|
state.tokenize = this.eatTagName( tagname.length, isCloseTag, false );
|
||||||
return this.makeLocalStyle( `${ modeConfig.tags.extTagBracket } mw-ext-${ tagname }`, state );
|
return this.makeLocalStyle( `${ mwModeConfig.tags.extTagBracket } mw-ext-${ tagname }`, state );
|
||||||
}
|
}
|
||||||
if ( tagname in modeConfig.permittedHtmlTags ) {
|
if ( tagname in mwModeConfig.permittedHtmlTags ) {
|
||||||
// Html tag
|
// Html tag
|
||||||
if ( isCloseTag === true && tagname !== state.inHtmlTag.pop() ) {
|
if ( isCloseTag === true && tagname !== state.inHtmlTag.pop() ) {
|
||||||
// Increment position so that the closing '>' gets highlighted red.
|
// Increment position so that the closing '>' gets highlighted red.
|
||||||
stream.pos++;
|
stream.pos++;
|
||||||
return modeConfig.tags.error;
|
return mwModeConfig.tags.error;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
isCloseTag === true &&
|
isCloseTag === true &&
|
||||||
tagname in modeConfig.implicitlyClosedHtmlTags
|
tagname in mwModeConfig.implicitlyClosedHtmlTags
|
||||||
) {
|
) {
|
||||||
return modeConfig.tags.error;
|
return mwModeConfig.tags.error;
|
||||||
}
|
}
|
||||||
stream.backUp( tagname.length );
|
stream.backUp( tagname.length );
|
||||||
state.stack.push( state.tokenize );
|
state.stack.push( state.tokenize );
|
||||||
|
@ -980,17 +980,17 @@ class CodeMirrorModeMediaWiki {
|
||||||
tagname.length,
|
tagname.length,
|
||||||
// Opening void tags should also be treated as the closing tag.
|
// Opening void tags should also be treated as the closing tag.
|
||||||
isCloseTag ||
|
isCloseTag ||
|
||||||
( tagname in modeConfig.implicitlyClosedHtmlTags ),
|
( tagname in mwModeConfig.implicitlyClosedHtmlTags ),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
return this.makeLocalStyle( modeConfig.tags.htmlTagBracket, state );
|
return this.makeLocalStyle( mwModeConfig.tags.htmlTagBracket, state );
|
||||||
}
|
}
|
||||||
stream.backUp( tagname.length );
|
stream.backUp( tagname.length );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '~':
|
case '~':
|
||||||
if ( stream.match( /^~{2,4}/ ) ) {
|
if ( stream.match( /^~{2,4}/ ) ) {
|
||||||
return modeConfig.tags.signature;
|
return mwModeConfig.tags.signature;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Maybe double underscored Magic Word such as __TOC__
|
// Maybe double underscored Magic Word such as __TOC__
|
||||||
|
@ -1008,7 +1008,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
}
|
}
|
||||||
// Optimization: skip regex function for EOL and backup-ed symbols
|
// Optimization: skip regex function for EOL and backup-ed symbols
|
||||||
return this.makeStyle( style, state );
|
return this.makeStyle( style, state );
|
||||||
// Check on double underscore Magic Word
|
// Check on double underscore Magic Word
|
||||||
} else if ( tmp === 2 ) {
|
} else if ( tmp === 2 ) {
|
||||||
// The same as the end of function except '_' inside and '__' at the end.
|
// The same as the end of function except '_' inside and '__' at the end.
|
||||||
name = stream.match( /^([^\s\u00a0>}[\]<{'|&:~]+?)__/ );
|
name = stream.match( /^([^\s\u00a0>}[\]<{'|&:~]+?)__/ );
|
||||||
|
@ -1017,7 +1017,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
'__' + name[ 0 ].toLowerCase() in this.config.doubleUnderscore[ 0 ] ||
|
'__' + name[ 0 ].toLowerCase() in this.config.doubleUnderscore[ 0 ] ||
|
||||||
'__' + name[ 0 ] in this.config.doubleUnderscore[ 1 ]
|
'__' + name[ 0 ] in this.config.doubleUnderscore[ 1 ]
|
||||||
) {
|
) {
|
||||||
return modeConfig.tags.doubleUnderscore;
|
return mwModeConfig.tags.doubleUnderscore;
|
||||||
}
|
}
|
||||||
if ( !stream.eol() ) {
|
if ( !stream.eol() ) {
|
||||||
// Two underscore symbols at the end can be the
|
// Two underscore symbols at the end can be the
|
||||||
|
@ -1032,7 +1032,7 @@ class CodeMirrorModeMediaWiki {
|
||||||
case ':':
|
case ':':
|
||||||
if ( state.nDt > 0 && !this.isNested( state ) ) {
|
if ( state.nDt > 0 && !this.isNested( state ) ) {
|
||||||
state.nDt--;
|
state.nDt--;
|
||||||
return modeConfig.tags.indenting;
|
return mwModeConfig.tags.indenting;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1266,14 +1266,14 @@ class CodeMirrorModeMediaWiki {
|
||||||
* @return {LanguageSupport}
|
* @return {LanguageSupport}
|
||||||
* @stable to call
|
* @stable to call
|
||||||
*/
|
*/
|
||||||
export default ( config = { bidiIsolation: false }, mwConfig = null ) => {
|
const mediaWikiLang = ( config = { bidiIsolation: false }, mwConfig = null ) => {
|
||||||
mwConfig = mwConfig || mw.config.get( 'extCodeMirrorConfig' );
|
mwConfig = mwConfig || mw.config.get( 'extCodeMirrorConfig' );
|
||||||
const mode = new CodeMirrorModeMediaWiki( mwConfig );
|
const mode = new CodeMirrorModeMediaWiki( mwConfig );
|
||||||
const parser = mode.mediawiki;
|
const parser = mode.mediawiki;
|
||||||
const lang = StreamLanguage.define( parser );
|
const lang = StreamLanguage.define( parser );
|
||||||
const langExtension = [ syntaxHighlighting(
|
const langExtension = [ syntaxHighlighting(
|
||||||
HighlightStyle.define(
|
HighlightStyle.define(
|
||||||
modeConfig.getTagStyles( parser )
|
mwModeConfig.getTagStyles( parser )
|
||||||
)
|
)
|
||||||
) ];
|
) ];
|
||||||
|
|
||||||
|
@ -1292,3 +1292,5 @@ export default ( config = { bidiIsolation: false }, mwConfig = null ) => {
|
||||||
|
|
||||||
return new LanguageSupport( lang, langExtension );
|
return new LanguageSupport( lang, langExtension );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports = mediaWikiLang;
|
|
@ -1,8 +1,22 @@
|
||||||
import { showTooltip, keymap, Tooltip, KeyBinding } from '@codemirror/view';
|
const {
|
||||||
import { StateField, Extension, EditorState } from '@codemirror/state';
|
EditorState,
|
||||||
import { foldEffect, syntaxTree, ensureSyntaxTree, foldedRanges, unfoldAll, unfoldEffect, codeFolding } from '@codemirror/language';
|
Extension,
|
||||||
import { SyntaxNode, Tree } from '@lezer/common';
|
KeyBinding,
|
||||||
import { mwModeConfig as modeConfig } from './codemirror.mode.mediawiki.config';
|
StateField,
|
||||||
|
SyntaxNode,
|
||||||
|
Tree,
|
||||||
|
Tooltip,
|
||||||
|
codeFolding,
|
||||||
|
ensureSyntaxTree,
|
||||||
|
foldEffect,
|
||||||
|
foldedRanges,
|
||||||
|
keymap,
|
||||||
|
showTooltip,
|
||||||
|
syntaxTree,
|
||||||
|
unfoldAll,
|
||||||
|
unfoldEffect
|
||||||
|
} = require( 'ext.CodeMirror.v6.lib' );
|
||||||
|
const modeConfig = require( './codemirror.mediawiki.config.js' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a SyntaxNode is a template bracket (`{{` or `}}`)
|
* Check if a SyntaxNode is a template bracket (`{{` or `}}`)
|
||||||
|
@ -280,7 +294,7 @@ const foldKeymap = [
|
||||||
* @module CodeMirrorTemplateFolding
|
* @module CodeMirrorTemplateFolding
|
||||||
* @type {Extension}
|
* @type {Extension}
|
||||||
*/
|
*/
|
||||||
export default [
|
const templateFoldingExtension = [
|
||||||
codeFolding( {
|
codeFolding( {
|
||||||
placeholderDOM( view ) {
|
placeholderDOM( view ) {
|
||||||
const element = document.createElement( 'span' );
|
const element = document.createElement( 'span' );
|
||||||
|
@ -314,3 +328,5 @@ export default [
|
||||||
} ),
|
} ),
|
||||||
keymap.of( foldKeymap )
|
keymap.of( foldKeymap )
|
||||||
];
|
];
|
||||||
|
|
||||||
|
module.exports = templateFoldingExtension;
|
|
@ -1,5 +1,4 @@
|
||||||
import { EditorView } from '@codemirror/view';
|
const { EditorSelection, EditorView } = require( 'ext.CodeMirror.v6.lib' );
|
||||||
import { EditorSelection } from '@codemirror/state';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [jQuery.textSelection]{@link jQuery.fn.textSelection} implementation for CodeMirror.
|
* [jQuery.textSelection]{@link jQuery.fn.textSelection} implementation for CodeMirror.
|
||||||
|
@ -230,4 +229,4 @@ class CodeMirrorTextSelection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CodeMirrorTextSelection;
|
module.exports = CodeMirrorTextSelection;
|
|
@ -1,7 +1,10 @@
|
||||||
import CodeMirror from './codemirror';
|
const {
|
||||||
import { EditorSelection, Extension } from '@codemirror/state';
|
EditorSelection,
|
||||||
import { EditorView } from '@codemirror/view';
|
EditorView,
|
||||||
import { LanguageSupport } from '@codemirror/language';
|
Extension,
|
||||||
|
LanguageSupport
|
||||||
|
} = require( 'ext.CodeMirror.v6.lib' );
|
||||||
|
const CodeMirror = require( 'ext.CodeMirror.v6' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CodeMirror integration with
|
* CodeMirror integration with
|
||||||
|
@ -242,4 +245,4 @@ class CodeMirrorWikiEditor extends CodeMirror {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CodeMirrorWikiEditor;
|
module.exports = CodeMirrorWikiEditor;
|
|
@ -1,5 +1,5 @@
|
||||||
import CodeMirrorWikiEditor from './codemirror.wikieditor';
|
const CodeMirrorWikiEditor = require( 'ext.CodeMirror.v6.WikiEditor' );
|
||||||
import mediaWikiLang from './codemirror.mode.mediawiki';
|
const mediaWikiLang = require( 'ext.CodeMirror.v6.mode.mediawiki' );
|
||||||
|
|
||||||
// TODO: remove URL feature flag once bidi isolation is more stable.
|
// TODO: remove URL feature flag once bidi isolation is more stable.
|
||||||
const urlParams = new URLSearchParams( window.location.search );
|
const urlParams = new URLSearchParams( window.location.search );
|
1
resources/dist/codemirror.js
vendored
1
resources/dist/codemirror.js
vendored
File diff suppressed because one or more lines are too long
1
resources/dist/codemirror.mediawiki.js
vendored
1
resources/dist/codemirror.mediawiki.js
vendored
|
@ -1 +0,0 @@
|
||||||
"use strict";var e=require("ext.CodeMirror.v6"),i=require("ext.CodeMirror.v6.mode.mediawiki");require("ext.CodeMirror.v6.lib");var r=new e(document.getElementById("wpTextbox1")),o=new URLSearchParams(window.location.search);r.initialize([r.defaultExtensions,i({bidiIsolation:o.get("cm6bidi")})]);
|
|
1
resources/dist/codemirror.mode.mediawiki.js
vendored
1
resources/dist/codemirror.mode.mediawiki.js
vendored
File diff suppressed because one or more lines are too long
1
resources/dist/codemirror.wikieditor.js
vendored
1
resources/dist/codemirror.wikieditor.js
vendored
|
@ -1 +0,0 @@
|
||||||
"use strict";var e=require("ext.CodeMirror.v6.lib"),t=function(t){function r(t,i){var o;return e._classCallCheck(this,r),(o=e._callSuper(this,r,[t])).langExtension=i,o.useCodeMirror=mw.user.options.get("usecodemirror")>0,o.realtimePreviewHandler=null,o}return e._inherits(r,t),e._createClass(r,[{key:"setCodeMirrorPreference",value:function(t){this.useCodeMirror=t,e._get(e._getPrototypeOf(r.prototype),"setCodeMirrorPreference",this).call(this,t)}},{key:"enableCodeMirror",value:function(){var t=this;if(!this.view){var r=this.$textarea.prop("selectionStart"),i=this.$textarea.prop("selectionEnd"),o=this.$textarea.scrollTop(),a=this.$textarea.is(":focus"),s=[this.defaultExtensions,this.langExtension,e.EditorView.updateListener.of((function(e){e.docChanged&&"function"==typeof t.realtimePreviewHandler&&t.realtimePreviewHandler()}))];if(this.initialize(s),this.addRealtimePreviewHandler(),requestAnimationFrame((function(){t.view.scrollDOM.scrollTop=o})),0!==r||0!==i){var n=e.EditorSelection.range(r,i),d=e.EditorView.scrollIntoView(n);d.value.isSnapshot=!0,this.view.dispatch({selection:e.EditorSelection.create([n]),effects:d})}a&&this.view.focus(),mw.hook("ext.CodeMirror.switch").fire(!0,$(this.view.dom))}}},{key:"addRealtimePreviewHandler",value:function(){var e=this;mw.hook("ext.WikiEditor.realtimepreview.enable").add((function(t){e.realtimePreviewHandler=t.getEventHandler().bind(t)})),mw.hook("ext.WikiEditor.realtimepreview.disable").add((function(){e.realtimePreviewHandler=null}))}},{key:"addCodeMirrorToWikiEditor",value:function(){var e=this,t=this.$textarea.data("wikiEditor-context"),r=t&&t.modules&&t.modules.toolbar;r&&(this.$textarea.wikiEditor("addToToolbar",{section:"main",groups:{codemirror:{tools:{CodeMirror:{label:mw.msg("codemirror-toggle-label"),type:"toggle",oouiIcon:"highlight",action:{type:"callback",execute:function(){return e.switchCodeMirror()}}}}}}}),r.$toolbar.find(".tool[rel=CodeMirror]").attr("id","mw-editbutton-codemirror"),this.readOnly&&this.$textarea.data("wikiEditor-context").$ui.addClass("ext-codemirror-readonly"),this.useCodeMirror&&this.enableCodeMirror(),this.updateToolbarButton(),this.logUsage({editor:"wikitext",enabled:this.useCodeMirror,toggled:!1,edit_start_ts_ms:1e3*parseInt($('input[name="wpStarttime"]').val(),10)||0}))}},{key:"updateToolbarButton",value:function(){var e=$("#mw-editbutton-codemirror");e.toggleClass("mw-editbutton-codemirror-active",this.useCodeMirror),e.data("setActive")&&e.data("setActive")(this.useCodeMirror)}},{key:"switchCodeMirror",value:function(){this.view?(this.setCodeMirrorPreference(!1),this.destroy(),mw.hook("ext.CodeMirror.switch").fire(!1,this.$textarea)):(this.enableCodeMirror(),this.setCodeMirrorPreference(!0)),this.updateToolbarButton(),this.logUsage({editor:"wikitext",enabled:this.useCodeMirror,toggled:!0,edit_start_ts_ms:1e3*parseInt($('input[name="wpStarttime"]').val(),10)||0})}}]),r}(require("ext.CodeMirror.v6"));module.exports=t;
|
|
|
@ -1 +0,0 @@
|
||||||
"use strict";var r=require("ext.CodeMirror.v6.WikiEditor"),i=require("ext.CodeMirror.v6.mode.mediawiki");require("ext.CodeMirror.v6.lib"),require("ext.CodeMirror.v6");var e=new URLSearchParams(window.location.search);mw.loader.getState("ext.wikiEditor")&&mw.hook("wikiEditor.toolbarReady").add((function(o){new r(o,i({bidiIsolation:"rtl"===o.attr("dir")&&e.get("cm6bidi")})).addCodeMirrorToWikiEditor()}));
|
|
1
resources/dist/vendor.js
vendored
1
resources/dist/vendor.js
vendored
File diff suppressed because one or more lines are too long
29
resources/legacy/.eslintrc.json
Normal file
29
resources/legacy/.eslintrc.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"extends": [
|
||||||
|
"wikimedia/client",
|
||||||
|
"wikimedia/jquery",
|
||||||
|
"wikimedia/mediawiki"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "commonjs"
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"CodeMirror": "readonly"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"max-len": "off",
|
||||||
|
"es-x/no-object-assign": "warn"
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"addon/*.js"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"computed-property-spacing": [ "error", "never" ],
|
||||||
|
"indent": [ "error", 2 ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -146,7 +146,6 @@ function init() {
|
||||||
*/
|
*/
|
||||||
function enableCodeMirror() {
|
function enableCodeMirror() {
|
||||||
const config = mw.config.get( 'extCodeMirrorConfig' );
|
const config = mw.config.get( 'extCodeMirrorConfig' );
|
||||||
|
|
||||||
mw.loader.using( codeMirrorCoreModules.concat( config.pluginModules ), () => {
|
mw.loader.using( codeMirrorCoreModules.concat( config.pluginModules ), () => {
|
||||||
const selectionStart = $textbox1.prop( 'selectionStart' ),
|
const selectionStart = $textbox1.prop( 'selectionStart' ),
|
||||||
selectionEnd = $textbox1.prop( 'selectionEnd' ),
|
selectionEnd = $textbox1.prop( 'selectionEnd' ),
|
22861
resources/lib/codemirror6.bundle.dist.js
Normal file
22861
resources/lib/codemirror6.bundle.dist.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,99 +1,18 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const nodeResolve = require( '@rollup/plugin-node-resolve' );
|
const nodeResolve = require( '@rollup/plugin-node-resolve' );
|
||||||
const copy = require( 'rollup-plugin-copy' );
|
|
||||||
const babel = require( '@rollup/plugin-babel' );
|
|
||||||
const terser = require( '@rollup/plugin-terser' );
|
|
||||||
|
|
||||||
const isProduction = process.env.BUILD === 'production';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapping of import paths to ResourceLoader module names.
|
|
||||||
* See usage in 'plugins' below for explanation.
|
|
||||||
*
|
|
||||||
* @type {Object}
|
|
||||||
*/
|
|
||||||
const importAliases = {
|
|
||||||
'./vendor.js': 'ext.CodeMirror.v6.lib',
|
|
||||||
'./codemirror.js': 'ext.CodeMirror.v6',
|
|
||||||
'./codemirror.wikieditor.js': 'ext.CodeMirror.v6.WikiEditor',
|
|
||||||
'./codemirror.mode.mediawiki.js': 'ext.CodeMirror.v6.mode.mediawiki'
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = [
|
module.exports = [
|
||||||
{
|
{
|
||||||
// One entry for each ResourceLoader module that we want to ship.
|
input: 'resources/codemirror.bundle.js',
|
||||||
input: [
|
|
||||||
'src/codemirror.js',
|
|
||||||
'src/codemirror.mode.mediawiki.js',
|
|
||||||
'src/codemirror.mediawiki.js',
|
|
||||||
'src/codemirror.wikieditor.js',
|
|
||||||
'src/codemirror.wikieditor.mediawiki.js'
|
|
||||||
],
|
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
entryFileNames: '[name].js',
|
file: 'resources/lib/codemirror6.bundle.dist.js',
|
||||||
dir: 'resources/dist',
|
format: 'cjs'
|
||||||
|
|
||||||
// Magically makes our ECMAScript Modules work with the
|
|
||||||
// CommonJS-style preferred by ResourceLoader. Ta-da!
|
|
||||||
format: 'cjs',
|
|
||||||
|
|
||||||
// Remove hash from chunked file name. We only want vendor code to be
|
|
||||||
// chunked, and we need the file name to be stable for use by ResourceLoader.
|
|
||||||
chunkFileNames: () => '[name].js',
|
|
||||||
|
|
||||||
// Bundle all vendor code into a single file called 'vendor.js'.
|
|
||||||
// This includes the Babel helpers because they are used by all our modules.
|
|
||||||
manualChunks: ( id ) => {
|
|
||||||
if ( id.includes( 'node_modules' ) || id.includes( 'rollupPluginBabelHelpers' ) ) {
|
|
||||||
return 'vendor';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
nodeResolve(),
|
nodeResolve()
|
||||||
|
]
|
||||||
// HACK: Rollup doesn't know about ResourceLoader and attempts to `require`
|
|
||||||
// modules using a relative path, when they need to match the RL module name.
|
|
||||||
// Here we do string replacements to fix that. This is nasty and brittle, but
|
|
||||||
// otherwise we couldn't offer standalone CodeMirror functionality via RL,
|
|
||||||
// which is necessary for usage in on-wiki scripts and gadgets (T214989).
|
|
||||||
copy( {
|
|
||||||
targets: [ {
|
|
||||||
src: 'resources/dist/*',
|
|
||||||
dest: 'resources/dist/',
|
|
||||||
transform: ( contents ) => {
|
|
||||||
Object.keys( importAliases ).forEach( ( alias ) => {
|
|
||||||
contents = contents.toString().replace(
|
|
||||||
`require("${ alias }")`,
|
|
||||||
`require("${ importAliases[ alias ] }")`
|
|
||||||
);
|
|
||||||
// Yuck, need to do the same with single apostrophes
|
|
||||||
// in the event terser is disabled such as during dev builds.
|
|
||||||
contents = contents.toString().replace(
|
|
||||||
`require('${ alias }')`,
|
|
||||||
`require('${ importAliases[ alias ] }')`
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
return contents;
|
|
||||||
}
|
|
||||||
} ],
|
|
||||||
hook: 'writeBundle'
|
|
||||||
} ),
|
|
||||||
|
|
||||||
isProduction ? babel( { babelHelpers: 'bundled' } ) : null,
|
|
||||||
|
|
||||||
isProduction ? terser() : null
|
|
||||||
],
|
|
||||||
|
|
||||||
onwarn: ( warning, warn ) => {
|
|
||||||
// Suppress "not exported" warnings. We import those for IDE support not for the build.
|
|
||||||
if ( warning.code === 'MISSING_EXPORT' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
warn( warning );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
{
|
|
||||||
"root": true,
|
|
||||||
"extends": [
|
|
||||||
"wikimedia/client-es6",
|
|
||||||
"wikimedia/jquery",
|
|
||||||
"wikimedia/mediawiki"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
|
||||||
"sourceType": "module",
|
|
||||||
"ecmaVersion": 2022
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"commonjs": true
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"Tree": "readonly"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"es-x/no-array-prototype-includes": 0,
|
|
||||||
"es-x/no-class-fields": 0,
|
|
||||||
"es-x/no-rest-spread-properties": 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
import CodeMirror from '../../src/codemirror.js';
|
const CodeMirror = require( '../../resources/codemirror.js' );
|
||||||
import mediaWikiLang from '../../src/codemirror.mode.mediawiki.js';
|
const mediaWikiLang = require( '../../resources/codemirror.mediawiki.js' );
|
||||||
|
|
||||||
const testCases = [
|
const testCases = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { StreamParser } from '@codemirror/language';
|
const { StreamParser } = require( '@codemirror/language' );
|
||||||
import { Tag } from '@lezer/highlight';
|
const { Tag } = require( '@lezer/highlight' );
|
||||||
import CodeMirror from '../../src/codemirror.js';
|
const CodeMirror = require( '../../resources/codemirror.js' );
|
||||||
import mediaWikiLang from '../../src/codemirror.mode.mediawiki.js';
|
const mediaWikiLang = require( '../../resources/codemirror.mediawiki.js' );
|
||||||
import { mwModeConfig } from '../../src/codemirror.mode.mediawiki.config.js';
|
const mwModeConfig = require( '../../resources/codemirror.mediawiki.config.js' );
|
||||||
|
|
||||||
// NOTE: each test case should have a space before the closing </div>
|
// NOTE: each test case should have a space before the closing </div>
|
||||||
// This is to avoid interactive UI components from showing up in the test output.
|
// This is to avoid interactive UI components from showing up in the test output.
|
|
@ -1,5 +1,6 @@
|
||||||
import { EditorView } from '@codemirror/view';
|
/* eslint-disable-next-line n/no-missing-require */
|
||||||
import CodeMirror from '../../src/codemirror.js';
|
const { EditorView } = require( 'ext.CodeMirror.v6.lib' );
|
||||||
|
const CodeMirror = require( '../../resources/codemirror.js' );
|
||||||
const $textarea = $( '<textarea>' ),
|
const $textarea = $( '<textarea>' ),
|
||||||
cm = new CodeMirror( $textarea );
|
cm = new CodeMirror( $textarea );
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
mw.loader = { getState: jest.fn() };
|
mw.loader = { getState: jest.fn() };
|
||||||
|
|
||||||
const CodeMirrorWikiEditor = require( '../../src/codemirror.wikieditor.js' ).default,
|
const CodeMirrorWikiEditor = require( '../../resources/codemirror.wikieditor.js' ),
|
||||||
$textarea = $( '<textarea>' )
|
$textarea = $( '<textarea>' )
|
||||||
.text( 'The Smashing Pumpkins' ),
|
.text( 'The Smashing Pumpkins' ),
|
||||||
cmWe = new CodeMirrorWikiEditor( $textarea );
|
cmWe = new CodeMirrorWikiEditor( $textarea );
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
jest.mock( '../../ext.CodeMirror.data.js', () => jest.fn(), { virtual: true } );
|
const mockBundle = require( '../../resources/lib/codemirror6.bundle.dist.js' );
|
||||||
|
jest.mock( 'ext.CodeMirror.v6.lib', () => mockBundle, { virtual: true } );
|
||||||
|
const mockCodeMirror = require( '../../resources/codemirror.js' );
|
||||||
|
jest.mock( 'ext.CodeMirror.v6', () => mockCodeMirror, { virtual: true } );
|
||||||
|
jest.mock( '../../resources/ext.CodeMirror.data.js', () => jest.fn(), { virtual: true } );
|
||||||
global.mw = require( '@wikimedia/mw-node-qunit/src/mockMediaWiki.js' )();
|
global.mw = require( '@wikimedia/mw-node-qunit/src/mockMediaWiki.js' )();
|
||||||
mw.user = Object.assign( mw.user, {
|
mw.user = Object.assign( mw.user, {
|
||||||
options: {
|
options: {
|
||||||
|
|
Loading…
Reference in a new issue