UNPKG

@init-kz/editorjs-code-highlight

Version:

A micro code-editor for awesome web pages

249 lines (246 loc) 10.4 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { default: () => EditorJsCodeHighlight }); module.exports = __toCommonJS(index_exports); // src/icon.ts var icon = ` <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: 16px !important; height: 16px !important" x="0" y="0" viewBox="0 0 24 24" style="enable-background:new 0 0 512 512" xml:space="preserve" class=""><g><path d="M1.5 12a.5.5 0 0 1 .5-.5A2.503 2.503 0 0 0 4.5 9V6A2.503 2.503 0 0 1 7 3.5h2a.5.5 0 0 1 0 1H7A1.502 1.502 0 0 0 5.5 6v3a3.5 3.5 0 0 1-1.7 3 3.5 3.5 0 0 1 1.7 3v3A1.502 1.502 0 0 0 7 19.5h2a.5.5 0 0 1 0 1H7A2.503 2.503 0 0 1 4.5 18v-3A2.503 2.503 0 0 0 2 12.5a.5.5 0 0 1-.5-.5zm20.5-.5A2.503 2.503 0 0 1 19.5 9V6A2.503 2.503 0 0 0 17 3.5h-2a.5.5 0 0 0 0 1h2A1.502 1.502 0 0 1 18.5 6v3a3.5 3.5 0 0 0 1.7 3 3.5 3.5 0 0 0-1.7 3v3a1.502 1.502 0 0 1-1.5 1.5h-2a.5.5 0 0 0 0 1h2a2.503 2.503 0 0 0 2.5-2.5v-3a2.503 2.503 0 0 1 2.5-2.5.5.5 0 0 0 0-1z" fill="#000000" opacity="1" data-original="#000000"></path></g></svg> `; // src/index.ts var import_init_code_highlight_ts = __toESM(require("@init-kz/init-code-highlight-ts"), 1); var EditorJsCodeHighlight = class _EditorJsCodeHighlight { sanitize; /** * Editor.js API instance */ api; /** * Stores current block data internally */ _data; readOnly; _CSS = {}; _element = null; editorInstance = null; constructor({ api, data, readOnly }) { this.api = api; this._data = { code: data?.code || _EditorJsCodeHighlight.DEFAULT_PLACEHOLDER, language: data?.language || "html", showlinenumbers: data?.showlinenumbers ?? true, showCopyButton: data?.showCopyButton ?? true }; this._CSS = { block: this.api.styles.block, wrapper: "ce-EditorJsCodeHighlight", settingsButton: this.api.styles.settingsButton, settingsButtonActive: this.api.styles.settingsButtonActive }; this.readOnly = readOnly; this.data = data; } /** * Return Tool data */ get data() { return this._data; } /** * Return Tool data */ set data(data) { this._data = data; } /** * Icon and title for displaying at the Toolbox * * @return {{icon: string, title: string}} */ static get toolbox() { return { icon, title: "Code" }; } /** * Returns true to notify the core that read-only mode is supported * * @return {boolean} */ static get isReadOnlySupported() { return true; } /** * Check if text content is empty and set empty string to inner html. * We need this because some browsers (e.g. Safari) insert <br> into empty contenteditanle elements * * @param {KeyboardEvent} e - key up event */ onKeyUp(e) { if (e.code !== "Backspace" && e.code !== "Delete") { return; } if (this._element) { const { textContent } = this._element; if (textContent === "") { this._element.innerHTML = ""; } } } _updateEditorHeight(length) { let _height = Math.min(length, 100) * 20 + 24; if (this._element) this._element.style.height = _height + "px"; } _debounce(func, timeout = 500) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; } _toggleLineNumbers = () => { this.data.showlinenumbers = !this.data.showlinenumbers; this.editorInstance?.toggleLineNumbers(); }; _updateLanguage = (lang) => { this.data.language = lang; const langDisplay = this._element?.querySelector( ".editorjs-code-highlight_LangDisplay" ); if (langDisplay) { langDisplay.textContent = this.data.language; } this.editorInstance?.updateLanguage(this.data.language); }; save(_) { let resp = { code: this.editorInstance?.getCode() || _EditorJsCodeHighlight.DEFAULT_PLACEHOLDER, language: this.data.language, showlinenumbers: this.data.showlinenumbers, showCopyButton: this.data.showCopyButton }; return resp; } renderSettings() { const settingsContainer = document.createElement("div"); const toggleButton = document.createElement("div"); const toggleButtonInner = document.createElement("div"); toggleButton.classList.add("ce-popover-item"); toggleButtonInner.classList.add("ce-popover-item__title"); if (this.data.showlinenumbers) { toggleButtonInner.innerHTML = this.api.i18n.t("Hide Numbers"); } else { toggleButtonInner.innerHTML = this.api.i18n.t("Show Numbers"); } let string = `<div class="ce-popover-item__icon ce-popover-item__icon--tool"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><line x1="48" y1="40" x2="208" y2="216" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M154.91,157.6a40,40,0,0,1-53.82-59.2" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M135.53,88.71a40,40,0,0,1,32.3,35.53" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M208.61,169.1C230.41,149.58,240,128,240,128S208,56,128,56a126,126,0,0,0-20.68,1.68" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M74,68.6C33.23,89.24,16,128,16,128s32,72,112,72a118.05,118.05,0,0,0,54-12.6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg> </div>`; toggleButton.innerHTML = string; toggleButton.appendChild(toggleButtonInner); toggleButton.addEventListener("click", (e) => { e.target.classList.toggle( this._CSS.settingsButtonActive ); this._toggleLineNumbers(); if (this.data.showlinenumbers) { toggleButtonInner.innerHTML = this.api.i18n.t("Hide Numbers"); } else { toggleButtonInner.innerHTML = this.api.i18n.t("Show Numbers"); } }); const languageEntryInputContainer = document.createElement("div"); languageEntryInputContainer.classList.add( "editorjs-code-highlight_inputContainer" ); let languageEntryInput = document.createElement("div"); languageEntryInput.classList.add("editorjs-code-highlight_input"); languageEntryInput.setAttribute("contenteditable", "true"); languageEntryInput.setAttribute( "data-placeholder", this.api.i18n.t("Enter a language...") ); let languageEntryInputButton = document.createElement("div"); let string2 = `<div class="ce-popover-item__icon ce-popover-item__icon--tool"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M136,136a8,8,0,0,1,8,8,16,16,0,0,1-16,16,24,24,0,0,1-24-24,32,32,0,0,1,32-32,40,40,0,0,1,40,40,48,48,0,0,1-48,48,56,56,0,0,1-56-56,64,64,0,0,1,64-64,72,72,0,0,1,72,72,80,80,0,0,1-80,80,88,88,0,0,1-88-88,96,96,0,0,1,96-96A104,104,0,0,1,240,144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg> </div>`; languageEntryInputButton.innerHTML = string2; languageEntryInputButton.classList.add( "editorjs-code-highlight_inputButton" ); languageEntryInputButton.addEventListener("click", (event) => { let lang = languageEntryInput.textContent; if (lang && lang != "") { this._updateLanguage(lang); } }); languageEntryInputContainer.appendChild(languageEntryInput); languageEntryInputContainer.appendChild(languageEntryInputButton); settingsContainer.appendChild(toggleButton); settingsContainer.appendChild(languageEntryInputContainer); return settingsContainer; } render() { this._element = document.createElement("div"); this._element.classList.add("editorjs-code-highlight_Wrapper"); let editorElem = document.createElement("div"); editorElem.classList.add("editorjs-code-highlight_Editor"); let langdisplay = document.createElement("div"); langdisplay.classList.add("editorjs-code-highlight_LangDisplay"); langdisplay.innerHTML = this.data.language || "html"; this._element.appendChild(editorElem); this._element.appendChild(langdisplay); this.editorInstance = new import_init_code_highlight_ts.default(editorElem, { language: this.data.language, lineNumbers: this.data.showlinenumbers, readonly: this.readOnly, copyButton: this.data.showCopyButton }); this.editorInstance.onUpdate((code) => { let _length = code.split("\n").length; this._updateEditorHeight(_length); }); this.editorInstance.updateCode( this.data.code || _EditorJsCodeHighlight.DEFAULT_PLACEHOLDER ); return this._element; } static get DEFAULT_PLACEHOLDER() { return "// Hello"; } static get enableLineBreaks() { return true; } }; //# sourceMappingURL=index.cjs.map