diff --git a/src/index.css b/src/index.css index cc4a48a..fab970f 100644 --- a/src/index.css +++ b/src/index.css @@ -1,14 +1,31 @@ .ce-code__textarea { - min-height: 200px; - font-family: Menlo, Monaco, Consolas, Courier New, monospace; - color: #41314e; - line-height: 1.6em; - font-size: 12px; - background: #f8f7fa; - border: 1px solid #f1f1f4; - box-shadow: none; - white-space: pre; - word-wrap: normal; - overflow-x: auto; - resize: vertical; + min-height: 200px; + font-family: Menlo, Monaco, Consolas, Courier New, monospace; + color: #41314e; + line-height: 1.6em; + font-size: 12px; + background: #f8f7fa; + border: 1px solid #f1f1f4; + box-shadow: none; + white-space: pre; + word-wrap: normal; + overflow-x: auto; + resize: vertical; +} + +.ce-code__dropdown { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearnance: none; + appearnance: none; + min-height: 40px; + margin-bottom: 5px; + line-height: 1.6em; + font-size: 14px; +} + +.ce-code__dropdown select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #000; } diff --git a/src/index.js b/src/index.js index d7506d9..d0c1e57 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,8 @@ /** * Build styles */ -import { getLineStartPosition } from './utils/string'; -import './index.css'; +import { getLineStartPosition } from "./utils/string"; +import "./index.css"; /** * CodeTool for Editor.js @@ -19,7 +19,6 @@ import './index.css'; * Code Tool for the Editor.js allows to include code examples in your articles. */ export default class CodeTool { - /** * Notify core that read-only mode is supported * @@ -59,20 +58,24 @@ export default class CodeTool { this.placeholder = this.api.i18n.t(config.placeholder || CodeTool.DEFAULT_PLACEHOLDER); + this.languages = config.languages; + this.CSS = { baseClass: this.api.styles.block, input: this.api.styles.input, - wrapper: 'ce-code', - textarea: 'ce-code__textarea', + wrapper: "ce-code", + textarea: "ce-code__textarea", + dropdown: "ce-code__dropdown", }; this.nodes = { holder: null, textarea: null, + dropdown: null, }; this.data = { - code: data.code || '', + code: data.code || "", }; this.nodes.holder = this.drawView(); @@ -85,8 +88,33 @@ export default class CodeTool { * @private */ drawView() { - const wrapper = document.createElement('div'), - textarea = document.createElement('textarea'); + const wrapper = document.createElement("div"), + textarea = document.createElement("textarea"); + + if (typeof this.languages === "object" && this.languages.length > 0) { + const dropdown = document.createElement("select"); + + dropdown.classList.add(this.CSS.dropdown, this.CSS.input); + dropdown.value = this.data.languages; + + let isValidLang = true; + + for (const lang of this.languages) { + if (typeof lang !== "string") { + isValidLang = false; + break; + } + + let option = document.createElement("option"); + option.classList.add(`${this.CSS.dropdown}__option`); + option.textContent = lang; + dropdown.appendChild(option); + } + + if (isValidLang) wrapper.appendChild(dropdown); + + this.nodes.dropdown = dropdown; + } wrapper.classList.add(this.CSS.baseClass, this.CSS.wrapper); textarea.classList.add(this.CSS.textarea, this.CSS.input); @@ -103,9 +131,9 @@ export default class CodeTool { /** * Enable keydown handlers */ - textarea.addEventListener('keydown', (event) => { + textarea.addEventListener("keydown", (event) => { switch (event.code) { - case 'Tab': + case "Tab": this.tabHandler(event); break; } @@ -134,9 +162,16 @@ export default class CodeTool { * @public */ save(codeWrapper) { - return { - code: codeWrapper.querySelector('textarea').value, - }; + if (typeof this.languages === "object" && this.languages.length > 0) { + return { + language: codeWrapper.querySelector("select").value, + code: codeWrapper.querySelector("textarea").value, + }; + } else { + return { + code: codeWrapper.querySelector("textarea").value, + }; + } } /** @@ -172,6 +207,9 @@ export default class CodeTool { if (this.nodes.textarea) { this.nodes.textarea.textContent = data.code; } + if (this.nodes.dropdown) { + this.nodes.dropdown.value = data.languages; + } } /** @@ -183,8 +221,9 @@ export default class CodeTool { */ static get toolbox() { return { - icon: ' ', - title: 'Code', + icon: + ' ', + title: "Code", }; } @@ -195,7 +234,7 @@ export default class CodeTool { * @returns {string} */ static get DEFAULT_PLACEHOLDER() { - return 'Enter a code'; + return "Enter a code"; } /** @@ -207,7 +246,7 @@ export default class CodeTool { */ static get pasteConfig() { return { - tags: [ 'pre' ], + tags: ["pre"], }; } @@ -244,7 +283,7 @@ export default class CodeTool { const isShiftPressed = event.shiftKey; const caretPosition = textarea.selectionStart; const value = textarea.value; - const indentation = ' '; + const indentation = " "; let newCaretPosition; @@ -269,7 +308,8 @@ export default class CodeTool { /** * Trim the first two chars from the start of line */ - textarea.value = value.substring(0, currentLineStart) + value.substring(currentLineStart + indentation.length); + textarea.value = + value.substring(0, currentLineStart) + value.substring(currentLineStart + indentation.length); newCaretPosition = caretPosition - indentation.length; }