You've already forked mediawiki-extensions-monaco-editor
Initial
This commit is contained in:
416
assets/js/scripts.js
Normal file
416
assets/js/scripts.js
Normal file
@ -0,0 +1,416 @@
|
||||
// @see https://microsoft.github.io/monaco-editor/playground.html#interacting-with-the-editor-adding-an-action-to-an-editor-instance
|
||||
(function(){
|
||||
|
||||
let init = function() {
|
||||
let MediaWikiTokenizer = (function () {
|
||||
function MediaWikiTokenizer() {
|
||||
this.ignorecase = true;
|
||||
this.empty = [
|
||||
'area', 'base', 'basefont', 'br', 'col', 'frame',
|
||||
'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'
|
||||
];
|
||||
// escape codes for javascript/CSS strings
|
||||
this.escapes = /\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/;
|
||||
this.tokenizer = {
|
||||
root: [
|
||||
{ include: '@whitespace' },
|
||||
|
||||
// Link reference
|
||||
[/\[\[/, { token: 'string.quote', bracket: '@open', next: '@linkReferenceBlock' }],
|
||||
|
||||
// Template usage
|
||||
[/{{/, { token: 'type.type-$1', bracket: '@open', next: '@templateBlock.$1' }],
|
||||
[/}}/, { token: 'type.type-$1', bracket: '@close' }],
|
||||
|
||||
// Bold
|
||||
[/'''/, { token: 'bold.quote', bracket: '@open', next: '@boldBlock' }],
|
||||
|
||||
// Italic
|
||||
[/''/, { token: 'italic.quote', bracket: '@open', next: '@italicBlock' }],
|
||||
|
||||
// HTML-Style blocks
|
||||
[/<(\w+)\/>/, 'tag.tag-$1'],
|
||||
[/<(\w+)/, {
|
||||
cases: {
|
||||
'@empty': { token: 'tag.tag-$1', next: '@tag.$1', log: 'Push stack to tag.$1' },
|
||||
'@default': { token: 'tag.tag-$1', bracket: '@open', next: '@tag.$1', log: 'Push stack to tag.$1, bracket open' }
|
||||
}
|
||||
}],
|
||||
[/<\/(\w+)\s*>/, { token: 'tag.tag-$1', bracket: '@close', log: 'Close bracket of tag.$1' }],
|
||||
[/&\w+;/, 'string.escape']
|
||||
],
|
||||
boldBlock: [
|
||||
[/'''/, { token: 'bold.quote', bracket: '@close', next: '@pop' }],
|
||||
[/[^''']+/, { token: 'bold' }],
|
||||
// Nested italic + bold, need a style to present both
|
||||
[/''/, { token: "italic.quote", bracket: "@open", next: "@italicBlock" }]
|
||||
],
|
||||
italicBlock: [
|
||||
[/''/, { token: "italic.quote", bracket: "@close", next: "@pop" }],
|
||||
[/[^'']+/, { token: "italic" }]
|
||||
],
|
||||
linkReferenceBlock: [
|
||||
[/\]\]/, { token: "string.quote", bracket: "@close", next: "@pop" }],
|
||||
[/[^\]\]]+/, { token: "string" }]
|
||||
],
|
||||
templateBlock: [
|
||||
[/{{/, { token: 'type.type-$1', bracket: '@open', next: '@templateBlock.$1' }],
|
||||
[/}}/, { token: 'type.type-$2', next: '@pop' }],
|
||||
[/\[\[/, { token: 'string.quote', bracket: '@open', next: '@linkReferenceBlock' }],
|
||||
[/'''/, { token: 'bold.quote', bracket: '@open', next: '@boldBlock' }],
|
||||
[/''/, { token: 'italic.quote', bracket: '@open', next: '@italicBlock' }]
|
||||
],
|
||||
// Tags
|
||||
tag: [
|
||||
[/[ \t\r\n]+/, 'white'],
|
||||
[/(type)(\s*=\s*)(")([^"]+)(")/, ['attribute.name', 'delimiter', 'attribute.value',
|
||||
{ token: 'attribute.value', switchTo: '@tag.$S2.$4' },
|
||||
'attribute.value']],
|
||||
[/(type)(\s*=\s*)(')([^']+)(')/, ['attribute.name', 'delimiter', 'attribute.value',
|
||||
{ token: 'attribute.value', switchTo: '@tag.$S2.$4' },
|
||||
'attribute.value']],
|
||||
[/(\w+)(\s*=\s*)("[^"]*"|'[^']*')/, ['attribute.name', 'delimiter', 'attribute.value']],
|
||||
[/\w+/, 'attribute.name'],
|
||||
[/\/>/, 'tag.tag-$S2', '@pop'],
|
||||
[/>/, {
|
||||
cases: {
|
||||
'$S2==style': { token: 'tag.tag-$S2', switchTo: '@inlineStyle.$S2', nextEmbedded: 'text/css', log: 'Entering CSS section ($S2)' },
|
||||
'$S2==script': {
|
||||
cases: {
|
||||
'$S3': { token: 'tag.tag-$S2', switchTo: '@inlineScript.$S2', nextEmbedded: '$S3' },
|
||||
'@default': { token: 'tag.tag-$S2', switchTo: '@inlineScript.$S2', nextEmbedded: 'javascript', log: 'Entering JS section ($S2)' }
|
||||
}
|
||||
},
|
||||
'@default': { token: 'tag.tag-$S2', next: '@pop', log: 'Entering $S2 section' }
|
||||
}
|
||||
}],
|
||||
],
|
||||
inlineStyle: [
|
||||
[/<\/style\s*>/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop', log: 'Pop stack ($S2)' }]
|
||||
],
|
||||
inlineScript: [
|
||||
[/<\/script\s*>/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop', log: 'Pop stack ($S2)' }]
|
||||
],
|
||||
// scan embedded strings in javascript or css
|
||||
// string.<delimiter>
|
||||
string: [
|
||||
[/[^\\"']+/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
[/["']/, {
|
||||
cases: {
|
||||
'$#==$S2': { token: 'string', next: '@pop' },
|
||||
'@default': 'string'
|
||||
}
|
||||
}]
|
||||
],
|
||||
whitespace: [
|
||||
[/[ \t\r\n]+/, 'white'],
|
||||
[/<!--/, 'comment', '@comment']
|
||||
],
|
||||
comment: [
|
||||
[/[^<\-]+/, 'comment.content'],
|
||||
[/-->/, 'comment', '@pop'],
|
||||
[/<!--/, 'comment.content.invalid'],
|
||||
[/[<\-]/, 'comment.content']
|
||||
]
|
||||
};
|
||||
this.tokenPostfix = "";
|
||||
}
|
||||
return MediaWikiTokenizer;
|
||||
}());
|
||||
|
||||
window.require.config({ paths: { 'vs': '/extensions/MonacoEditor/node_modules/monaco-editor/min/vs' }});
|
||||
window.require(['vs/editor/editor.main'], function() {
|
||||
let el_stock_editor = document.getElementById("wpTextbox1");
|
||||
el_stock_editor.style.display = "none";
|
||||
// Register a new language
|
||||
monaco.languages.register({ id: 'wikitext' });
|
||||
|
||||
// Register a tokens provider for the language
|
||||
monaco.languages.setMonarchTokensProvider('wikitext', new MediaWikiTokenizer());
|
||||
|
||||
// Register a completion item provider for the new language
|
||||
monaco.languages.registerCompletionItemProvider('wikitext', {
|
||||
provideCompletionItems: () => {
|
||||
var suggestions = [{
|
||||
label: 'syntax',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<syntaxhighlight lang="$1">',
|
||||
'$2',
|
||||
'</syntaxhighlight>'
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'syntax inline',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<syntaxhighlight lang="$1" inline>$2</syntaxhighlight>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'code',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<code>$1</code>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'poem',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<poem>$1</poem>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'bullet list',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'* $1',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'numbered list',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'# $1',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'bold',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
"'''$1'''",
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'italic',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
"''$1''",
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'heading 1',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
"= $1 =",
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'heading 2',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'== $1 ==',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'heading 3',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'=== $1 ===',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'heading 4',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'==== $1 ====',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'heading 5',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'===== $1 =====',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'heading 6',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'====== $1 ======',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'category',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'[[Category:$1]]',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'internal link',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'[[$1]]',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'external link',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'[$1 $2]',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'comment',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<!--',
|
||||
'$1',
|
||||
'-->',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'inline comment',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<!-- $1 -->',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'template',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'{{$1}}',
|
||||
''
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'chunk: references',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'== References ==',
|
||||
'{{Reflist}}',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'reference',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<ref>$1</ref>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'reference internal link',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<ref>[[$1]]</ref>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'reference external link',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<ref>[$1 $2]</ref>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'expanded quote',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'{{Quote | $1 | $2 | $3}}',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'quote',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'{{Quote | $1 || $2}}',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'expandable content',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'{{Expandable content | $1}}',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'nowiki',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'<nowiki>$1</nowiki>',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'horizontal rule',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'----',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}, {
|
||||
label: 'related article',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'{{#related:$1}}',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
}];
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
||||
|
||||
let language = 'wikitext';
|
||||
if (typeof RLCONF.wgPageContentModel !== 'undefined') {
|
||||
switch (RLCONF.wgPageContentModel) {
|
||||
case 'css':
|
||||
language = 'css';
|
||||
break;
|
||||
case 'javascript':
|
||||
language = 'javascript';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new editor
|
||||
let monaco_editor_container = document.createElement('div');
|
||||
monaco_editor_container.id = 'monaco-editor'
|
||||
monaco_editor_container.style["min-height"] = '35em';
|
||||
monaco_editor_container.style["max-height"] = '100vh';
|
||||
el_stock_editor.after(monaco_editor_container);
|
||||
|
||||
window.monaco_editor = monaco.editor.create(document.getElementById('monaco-editor'), {
|
||||
value: el_stock_editor.value,
|
||||
scrollBeyondLastLine: false,
|
||||
wordWrap: 'on',
|
||||
fontSize: '13px',
|
||||
language: language,
|
||||
// theme: "vs-dark",
|
||||
});
|
||||
|
||||
// On preview
|
||||
let el_btn_preview = document.querySelector('#wpPreview');
|
||||
el_btn_preview.addEventListener('click', event => {
|
||||
el_stock_editor.value = window.monaco_editor.getValue();
|
||||
});
|
||||
|
||||
// On save
|
||||
let el_btn_save = document.querySelector('#wpSave');
|
||||
el_btn_save.addEventListener('click', event => {
|
||||
el_stock_editor.value = window.monaco_editor.getValue();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function initializer() {
|
||||
if (typeof window.require !== 'undefined') {
|
||||
init();
|
||||
} else {
|
||||
setTimeout(initializer, 20);
|
||||
}
|
||||
}
|
||||
initializer();
|
||||
})();
|
Reference in New Issue
Block a user