mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-22 14:49:59 +08:00
Updated code system to dynamically set php codemirror mode
- Codemirror mode mapping value can now be a function to dynamically set mode depending on actual code content. - Used above system to set php mode type, depending on if '<?php' tags exist in content. Closes #1557
This commit is contained in:
@ -160,7 +160,7 @@ function codePlugin() {
|
|||||||
let cmInstance = editorElem.CodeMirror;
|
let cmInstance = editorElem.CodeMirror;
|
||||||
if (cmInstance) {
|
if (cmInstance) {
|
||||||
Code.setContent(cmInstance, code);
|
Code.setContent(cmInstance, code);
|
||||||
Code.setMode(cmInstance, lang);
|
Code.setMode(cmInstance, lang, code);
|
||||||
}
|
}
|
||||||
let textArea = selectedNode.querySelector('textarea');
|
let textArea = selectedNode.querySelector('textarea');
|
||||||
if (textArea) textArea.textContent = code;
|
if (textArea) textArea.textContent = code;
|
||||||
|
@ -29,8 +29,9 @@ import 'codemirror/mode/yaml/yaml';
|
|||||||
// Addons
|
// Addons
|
||||||
import 'codemirror/addon/scroll/scrollpastend';
|
import 'codemirror/addon/scroll/scrollpastend';
|
||||||
|
|
||||||
// Mapping of potential languages or formats from user input
|
// Mapping of possible languages or formats from user input to their codemirror modes.
|
||||||
// to their proper codemirror modes.
|
// Value can be a mode string or a function that will receive the code content & return the mode string.
|
||||||
|
// The function option is used in the event the exact mode could be dynamic depending on the code.
|
||||||
const modeMap = {
|
const modeMap = {
|
||||||
css: 'css',
|
css: 'css',
|
||||||
c: 'text/x-csrc',
|
c: 'text/x-csrc',
|
||||||
@ -60,7 +61,9 @@ const modeMap = {
|
|||||||
powershell: 'powershell',
|
powershell: 'powershell',
|
||||||
properties: 'properties',
|
properties: 'properties',
|
||||||
ocaml: 'mllike',
|
ocaml: 'mllike',
|
||||||
php: 'php',
|
php: (content) => {
|
||||||
|
return content.includes('<?php') ? 'php' : 'text/x-php';
|
||||||
|
},
|
||||||
py: 'python',
|
py: 'python',
|
||||||
python: 'python',
|
python: 'python',
|
||||||
ruby: 'ruby',
|
ruby: 'ruby',
|
||||||
@ -92,16 +95,17 @@ function highlight() {
|
|||||||
* @param {HTMLElement} elem
|
* @param {HTMLElement} elem
|
||||||
*/
|
*/
|
||||||
function highlightElem(elem) {
|
function highlightElem(elem) {
|
||||||
let innerCodeElem = elem.querySelector('code[class^=language-]');
|
const innerCodeElem = elem.querySelector('code[class^=language-]');
|
||||||
|
elem.innerHTML = elem.innerHTML.replace(/<br\s*[\/]?>/gi ,'\n');
|
||||||
|
const content = elem.textContent.trim();
|
||||||
|
|
||||||
let mode = '';
|
let mode = '';
|
||||||
if (innerCodeElem !== null) {
|
if (innerCodeElem !== null) {
|
||||||
let langName = innerCodeElem.className.replace('language-', '');
|
const langName = innerCodeElem.className.replace('language-', '');
|
||||||
mode = getMode(langName);
|
mode = getMode(langName, content);
|
||||||
}
|
}
|
||||||
elem.innerHTML = elem.innerHTML.replace(/<br\s*[\/]?>/gi ,'\n');
|
|
||||||
let content = elem.textContent.trim();
|
|
||||||
|
|
||||||
let cm = CodeMirror(function(elt) {
|
const cm = CodeMirror(function(elt) {
|
||||||
elem.parentNode.replaceChild(elt, elem);
|
elem.parentNode.replaceChild(elt, elem);
|
||||||
}, {
|
}, {
|
||||||
value: content,
|
value: content,
|
||||||
@ -142,12 +146,24 @@ function addCopyIcon(cmInstance) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for a codemirror code based off a user suggestion
|
* Search for a codemirror code based off a user suggestion
|
||||||
* @param suggestion
|
* @param {String} suggestion
|
||||||
|
* @param {String} content
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function getMode(suggestion) {
|
function getMode(suggestion, content) {
|
||||||
suggestion = suggestion.trim().replace(/^\./g, '').toLowerCase();
|
suggestion = suggestion.trim().replace(/^\./g, '').toLowerCase();
|
||||||
return (typeof modeMap[suggestion] !== 'undefined') ? modeMap[suggestion] : '';
|
|
||||||
|
const modeMapType = typeof modeMap[suggestion];
|
||||||
|
|
||||||
|
if (modeMapType === 'undefined') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modeMapType === 'function') {
|
||||||
|
return modeMap[suggestion](content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return modeMap[suggestion];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,8 +181,8 @@ function getTheme() {
|
|||||||
* @returns {{wrap: Element, editor: *}}
|
* @returns {{wrap: Element, editor: *}}
|
||||||
*/
|
*/
|
||||||
function wysiwygView(elem) {
|
function wysiwygView(elem) {
|
||||||
let doc = elem.ownerDocument;
|
const doc = elem.ownerDocument;
|
||||||
let codeElem = elem.querySelector('code');
|
const codeElem = elem.querySelector('code');
|
||||||
|
|
||||||
let lang = (elem.className || '').replace('language-', '');
|
let lang = (elem.className || '').replace('language-', '');
|
||||||
if (lang === '' && codeElem) {
|
if (lang === '' && codeElem) {
|
||||||
@ -174,9 +190,9 @@ function wysiwygView(elem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
elem.innerHTML = elem.innerHTML.replace(/<br\s*[\/]?>/gi ,'\n');
|
elem.innerHTML = elem.innerHTML.replace(/<br\s*[\/]?>/gi ,'\n');
|
||||||
let content = elem.textContent;
|
const content = elem.textContent;
|
||||||
let newWrap = doc.createElement('div');
|
const newWrap = doc.createElement('div');
|
||||||
let newTextArea = doc.createElement('textarea');
|
const newTextArea = doc.createElement('textarea');
|
||||||
|
|
||||||
newWrap.className = 'CodeMirrorContainer';
|
newWrap.className = 'CodeMirrorContainer';
|
||||||
newWrap.setAttribute('data-lang', lang);
|
newWrap.setAttribute('data-lang', lang);
|
||||||
@ -192,7 +208,7 @@ function wysiwygView(elem) {
|
|||||||
newWrap.appendChild(elt);
|
newWrap.appendChild(elt);
|
||||||
}, {
|
}, {
|
||||||
value: content,
|
value: content,
|
||||||
mode: getMode(lang),
|
mode: getMode(lang, content),
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
lineWrapping: false,
|
lineWrapping: false,
|
||||||
theme: getTheme(),
|
theme: getTheme(),
|
||||||
@ -211,14 +227,14 @@ function wysiwygView(elem) {
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
function popupEditor(elem, modeSuggestion) {
|
function popupEditor(elem, modeSuggestion) {
|
||||||
let content = elem.textContent;
|
const content = elem.textContent;
|
||||||
|
|
||||||
return CodeMirror(function(elt) {
|
return CodeMirror(function(elt) {
|
||||||
elem.parentNode.insertBefore(elt, elem);
|
elem.parentNode.insertBefore(elt, elem);
|
||||||
elem.style.display = 'none';
|
elem.style.display = 'none';
|
||||||
}, {
|
}, {
|
||||||
value: content,
|
value: content,
|
||||||
mode: getMode(modeSuggestion),
|
mode: getMode(modeSuggestion, content),
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
lineWrapping: false,
|
lineWrapping: false,
|
||||||
theme: getTheme()
|
theme: getTheme()
|
||||||
@ -230,8 +246,8 @@ function popupEditor(elem, modeSuggestion) {
|
|||||||
* @param cmInstance
|
* @param cmInstance
|
||||||
* @param modeSuggestion
|
* @param modeSuggestion
|
||||||
*/
|
*/
|
||||||
function setMode(cmInstance, modeSuggestion) {
|
function setMode(cmInstance, modeSuggestion, content) {
|
||||||
cmInstance.setOption('mode', getMode(modeSuggestion));
|
cmInstance.setOption('mode', getMode(modeSuggestion, content));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +9,7 @@ const methods = {
|
|||||||
this.$refs.overlay.components.overlay.hide();
|
this.$refs.overlay.components.overlay.hide();
|
||||||
},
|
},
|
||||||
updateEditorMode(language) {
|
updateEditorMode(language) {
|
||||||
codeLib.setMode(this.editor, language);
|
codeLib.setMode(this.editor, language, this.editor.getValue());
|
||||||
},
|
},
|
||||||
updateLanguage(lang) {
|
updateLanguage(lang) {
|
||||||
this.language = lang;
|
this.language = lang;
|
||||||
|
Reference in New Issue
Block a user