diff --git a/.babelrc b/.babelrc deleted file mode 100644 index f3377de8f..000000000 --- a/.babelrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "plugins": [ - [ - "prismjs", - { - "languages": ["markup", "css", "clike", "javascript"], - "plugins": ["line-numbers"], - "theme": "coy", - "css": true - } - ] - ] -} diff --git a/editor/css/editable-css.css b/editor/css/editable-css.css index 2c60ae204..793b20538 100644 --- a/editor/css/editable-css.css +++ b/editor/css/editable-css.css @@ -74,8 +74,22 @@ background-color: var(--background-secondary); } -.live .example-choice code { - padding: 10px 0; +.live .example-choice pre { + width: 100%; +} + +.live .example-choice pre .cm-editor { + width: 100%; + height: auto; + text-align: left; + padding: 4px 0; + padding-right: 1rem; + background: none; + border: none; +} + +.live .example-choice .ΝΌ1.cm-editor.cm-focused { + outline: none; } .example-choice-list .example-choice:first-child { diff --git a/editor/css/editor-libs/prism-override.css b/editor/css/editor-libs/prism-override.css deleted file mode 100644 index 3911b29cb..000000000 --- a/editor/css/editor-libs/prism-override.css +++ /dev/null @@ -1,57 +0,0 @@ -/* Prism theme overrides */ -pre[class*="language-"] { - background-image: none; - margin: 0; - border: 0; - box-shadow: none; - overflow: auto; -} - -pre[class*="language-"] > code { - background: none; - border: none; - box-shadow: none; -} - -pre[class*="language-"]:before, -pre[class*="language-"]:after { - width: 0; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background-color: transparent; -} - -code[class*="language-"] { - max-height: 240px; - overflow: auto; -} - -.line-numbers .line-numbers-rows { - background-color: #f5f9fa; - border-right: 0; -} - -.line-numbers-rows > span:before { - color: #333; -} - -/* overrides for increased a11y */ -.token.comment, -.token.block-comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: #58636d; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.function, -.token.builtin, -.token.inserted { - color: #2545a7; -} diff --git a/editor/js/css-examples-libs.js b/editor/js/css-examples-libs.js deleted file mode 100644 index 271db0d28..000000000 --- a/editor/js/css-examples-libs.js +++ /dev/null @@ -1 +0,0 @@ -import Prism from "prismjs"; diff --git a/editor/js/editable-css.js b/editor/js/editable-css.js index 0a51a4106..cfd5c47bc 100644 --- a/editor/js/editable-css.js +++ b/editor/js/editable-css.js @@ -2,10 +2,13 @@ import * as clippy from "./editor-libs/clippy.js"; import * as mceEvents from "./editor-libs/events.js"; import * as mceUtils from "./editor-libs/mce-utils.js"; import * as cssEditorUtils from "./editor-libs/css-editor-utils.js"; +import { + initCodeEditor, + languageCSS, +} from "./editor-libs/codemirror-editor.js"; import "../css/editor-libs/ui-fonts.css"; import "../css/editor-libs/common.css"; -import "../css/editor-libs/prism-override.css"; import "../css/editable-css.css"; (function () { @@ -17,6 +20,12 @@ import "../css/editable-css.css"; var output = document.getElementById("output"); var warningNoSupport = document.getElementById("warning-no-support"); + function applyCodeMirror(target, code) { + var codeMirror = initCodeEditor(target, code, languageCSS(), { + lineNumbers: false, + }); + } + /** * Enables and initializes the live code editor */ @@ -29,6 +38,14 @@ import "../css/editable-css.css"; var exampleChoice = exampleChoices[i]; var choiceButton = document.createElement("button"); var choiceButtonText = document.createElement("span"); + var choiceCode = exampleChoice.querySelector("code"); + + originalChoices.push(choiceCode.textContent); + + applyCodeMirror( + exampleChoice.querySelector("pre"), + choiceCode.textContent + ); choiceButton.setAttribute("type", "button"); choiceButton.classList.add("example-choice-button"); @@ -38,11 +55,11 @@ import "../css/editable-css.css"; choiceButton.append(choiceButtonText); exampleChoice.append(choiceButton); - originalChoices.push(exampleChoice.querySelector("code").textContent); - if (exampleChoice.getAttribute("initial-choice")) { initialChoice = indexOf(exampleChoices, exampleChoice); } + + choiceCode.remove(); } mceEvents.register(); @@ -62,16 +79,15 @@ import "../css/editable-css.css"; var resetButton = document.getElementById("reset"); resetButton.addEventListener("click", function () { - for (var i = 0, l = exampleChoices.length; i < l; i++) { - var highlighted = Prism.highlight( - originalChoices[i], - Prism.languages.css - ); - // IE11 does not support multiple selectors in `remove` - exampleChoices[i].classList.remove("invalid"); - exampleChoices[i].classList.remove("selected"); - exampleChoices[i].querySelector("code").innerHTML = highlighted; - } + exampleChoices.forEach(function (e, i) { + var preEl = e.querySelector("pre"); + // Remove original codemirror + for (const e of preEl.children) { + e.remove(); + } + e.classList.remove("invalid", "selected"); + applyCodeMirror(preEl, originalChoices[i]); + }); // Adding or removing class "invalid" cssEditorUtils.applyInitialSupportWarningState(exampleChoices); diff --git a/editor/js/editor-libs/codemirror-editor.js b/editor/js/editor-libs/codemirror-editor.js index e9386457e..188b4839c 100644 --- a/editor/js/editor-libs/codemirror-editor.js +++ b/editor/js/editor-libs/codemirror-editor.js @@ -1,21 +1,28 @@ -import {EditorView} from "codemirror" -import {EditorState} from "@codemirror/state" -import * as commands from "@codemirror/commands" +import { EditorView } from "codemirror"; +import { EditorState } from "@codemirror/state"; +import * as commands from "@codemirror/commands"; import * as view from "@codemirror/view"; -import {bracketMatching, syntaxHighlighting, indentOnInput, foldKeymap, HighlightStyle, LRLanguage} from "@codemirror/language"; -import {closeBrackets, closeBracketsKeymap} from "@codemirror/autocomplete"; -import {highlightSelectionMatches, searchKeymap} from "@codemirror/search"; -import {lintKeymap} from "@codemirror/lint"; -import {javascript, javascriptLanguage} from "@codemirror/lang-javascript" -import {wast} from "@codemirror/lang-wast"; -import {html} from "@codemirror/lang-html"; -import {css, cssLanguage} from "@codemirror/lang-css"; +import { + bracketMatching, + syntaxHighlighting, + indentOnInput, + foldKeymap, + HighlightStyle, + LRLanguage, +} from "@codemirror/language"; +import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete"; +import { highlightSelectionMatches, searchKeymap } from "@codemirror/search"; +import { lintKeymap } from "@codemirror/lint"; +import { javascript, javascriptLanguage } from "@codemirror/lang-javascript"; +import { wast } from "@codemirror/lang-wast"; +import { html } from "@codemirror/lang-html"; +import { css, cssLanguage } from "@codemirror/lang-css"; -import {parseMixed} from "@lezer/common"; -import {tags} from "@lezer/highlight" -import {parser as jsParser} from "@lezer/javascript" -import {parser as htmlParser} from "@lezer/html" -import {parser as cssParser} from "@lezer/css" +import { parseMixed } from "@lezer/common"; +import { tags } from "@lezer/highlight"; +import { parser as jsParser } from "@lezer/javascript"; +import { parser as htmlParser } from "@lezer/html"; +import { parser as cssParser } from "@lezer/css"; import "../../css/editor-libs/codemirror-override.css"; @@ -23,7 +30,11 @@ import "../../css/editor-libs/codemirror-override.css"; * Adds tab character in current place of selection when Tab button was clicked. * When Tab button was clicked together with shift, tab character is removed from line beginning */ -const TAB_KEY_MAP = {key: "Tab", run: commands.insertTab, shift: commands.indentLess}; +const TAB_KEY_MAP = { + key: "Tab", + run: commands.insertTab, + shift: commands.indentLess, +}; /** * Translates CSS tags from [highlight.js](https://github.com/lezer-parser/css/blob/main/src/highlight.js) to code mirror CSS classes. @@ -63,17 +74,17 @@ const CSS_HIGHLIGHT_STYLE_SPECS = [ * Translates HTML tags from [highlight.js](https://github.com/lezer-parser/html/blob/main/src/highlight.js) to code mirror CSS classes. */ const HTML_HIGHLIGHT_STYLE_SPECS = [ - {tag: [tags.content], class: ""},// Element Content - {tag: [tags.angleBracket], class: "cm-bracket"},// "<", ">" - {tag: [tags.tagName], class: "cm-tag"},// Tag Name - {tag: tags.invalid, class: "tag_invalid"}, - {tag: [tags.attributeName], class: "cm-attribute"},// Attribute Name - {tag: [tags.attributeValue], class: "cm-string"},// Attribute Value - {tag: [tags.definitionOperator], class: ""},// "=" - {tag: [tags.character], class: "cm-atom"},// "<" - {tag: [tags.blockComment], class: "cm-comment"},// - {tag: [tags.processingInstruction], class: "cm-meta"},// - {tag: [tags.documentMeta], class: "cm-meta"},// + { tag: [tags.content], class: "" }, // Element Content + { tag: [tags.angleBracket], class: "cm-bracket" }, // "<", ">" + { tag: [tags.tagName], class: "cm-tag" }, // Tag Name + { tag: tags.invalid, class: "tag_invalid" }, + { tag: [tags.attributeName], class: "cm-attribute" }, // Attribute Name + { tag: [tags.attributeValue], class: "cm-string" }, // Attribute Value + { tag: [tags.definitionOperator], class: "" }, // "=" + { tag: [tags.character], class: "cm-atom" }, // "<" + { tag: [tags.blockComment], class: "cm-comment" }, // + { tag: [tags.processingInstruction], class: "cm-meta" }, // + { tag: [tags.documentMeta], class: "cm-meta" }, // ]; /** @@ -105,14 +116,14 @@ const JS_HIGHLIGHT_STYLE_SPECS = [ * Translates HTML tags from [highlight.js](https://github.com/lezer-parser/javascript/blob/main/src/highlight.js) to code mirror CSS classes. */ const WAST_HIGHLIGHT_STYLE_SPECS = [ - {tag: tags.keyword, class: "cm-keyword"},// "func", "import", "module - {tag: tags.typeName, class: "cm-string"},// "anyref", "dataref", "i31ref", "funcref", "i32", "f64" - {tag: tags.number, class: "cm-number"},// +12.3, -1, 0xFF - {tag: tags.string, class: "cm-string"},// "text" - {tag: tags.variableName, class: "cm-variable-2"},// $var - {tag: tags.lineComment, class: "cm-comment"},// ";;" - {tag: tags.blockComment, class: "cm-comment"},// "(; comment ;)" - {tag: tags.paren, class: ""}// "(", ")" + { tag: tags.keyword, class: "cm-keyword" }, // "func", "import", "module + { tag: tags.typeName, class: "cm-string" }, // "anyref", "dataref", "i31ref", "funcref", "i32", "f64" + { tag: tags.number, class: "cm-number" }, // +12.3, -1, 0xFF + { tag: tags.string, class: "cm-string" }, // "text" + { tag: tags.variableName, class: "cm-variable-2" }, // $var + { tag: tags.lineComment, class: "cm-comment" }, // ";;" + { tag: tags.blockComment, class: "cm-comment" }, // "(; comment ;)" + { tag: tags.paren, class: "" }, // "(", ")" ]; /** @@ -120,7 +131,7 @@ const WAST_HIGHLIGHT_STYLE_SPECS = [ * @return {Extension} - Code Mirror extension attaching class names to a given tags */ function highlighting(specs) { - return syntaxHighlighting(HighlightStyle.define(specs), {fallback: false}); + return syntaxHighlighting(HighlightStyle.define(specs), { fallback: false }); } /** @@ -131,11 +142,11 @@ function highlighting(specs) { * @return {Extension} - Code Mirror extension attaching class names to a given tags, but only to a given language or node tree */ function scopedHighlighting(specs, scope, nodeName = undefined) { - const style = HighlightStyle.define(specs, {scope: scope}); - if(nodeName) { - style.scope = (node) => node.name === nodeName;// This line overrides internal scope check, because alternative parsers don't attach chosen language to props - } - return syntaxHighlighting(style, {fallback: false}); + const style = HighlightStyle.define(specs, { scope: scope }); + if (nodeName) { + style.scope = (node) => node.name === nodeName; // This line overrides internal scope check, because alternative parsers don't attach chosen language to props + } + return syntaxHighlighting(style, { fallback: false }); } /** @@ -143,27 +154,27 @@ function scopedHighlighting(specs, scope, nodeName = undefined) { * @return {*} - first result of provided function */ function memo(callback) { - let value; - return () => value === undefined ? (value = callback(), value) : value; + let value; + return () => (value === undefined ? ((value = callback()), value) : value); } /** * @return {LRLanguage} - new language capable of parsing JavaScript and CSS inside HTML code */ function mixedHTML() { - const mixedHTMLParser = htmlParser.configure({ - wrap: parseMixed(node => { - //ScriptText & StyleText can be found in [html.grammar](https://github.com/lezer-parser/html/blob/main/src/html.grammar) - if(node.name == "ScriptText") { - return {parser: jsParser}; - } else if(node.name == "StyleText") { - return {parser: cssParser}; - } - return null; - }) - }); + const mixedHTMLParser = htmlParser.configure({ + wrap: parseMixed((node) => { + //ScriptText & StyleText can be found in [html.grammar](https://github.com/lezer-parser/html/blob/main/src/html.grammar) + if (node.name == "ScriptText") { + return { parser: jsParser }; + } else if (node.name == "StyleText") { + return { parser: cssParser }; + } + return null; + }), + }); - return LRLanguage.define({parser: mixedHTMLParser}); + return LRLanguage.define({ parser: mixedHTMLParser }); } /** @@ -171,76 +182,72 @@ function mixedHTML() { * This list is mostly based on [basic setup](https://github.com/codemirror/basic-setup) */ const BASE_EXTENSIONS = [ - view.lineNumbers(), - view.highlightSpecialChars(), - commands.history(), - view.gutter(), - view.drawSelection(), - view.dropCursor(), - EditorState.allowMultipleSelections.of(true), - indentOnInput(), - bracketMatching(), - closeBrackets(), - view.rectangularSelection(), - view.crosshairCursor(), - highlightSelectionMatches(), - view.keymap.of([ - ...closeBracketsKeymap, - ...commands.defaultKeymap, - ...searchKeymap, - ...commands.historyKeymap, - ...foldKeymap, - ...lintKeymap, - TAB_KEY_MAP - ]) + view.highlightSpecialChars(), + commands.history(), + view.drawSelection(), + view.dropCursor(), + EditorState.allowMultipleSelections.of(true), + indentOnInput(), + bracketMatching(), + closeBrackets(), + view.rectangularSelection(), + view.crosshairCursor(), + highlightSelectionMatches(), + view.keymap.of([ + ...closeBracketsKeymap, + ...commands.defaultKeymap, + ...searchKeymap, + ...commands.historyKeymap, + ...foldKeymap, + ...lintKeymap, + TAB_KEY_MAP, + ]), ]; /** * Function returning JavaScript language extensions, which should be passed to {initCodeEditor} */ export const languageJavaScript = memo(() => ({ - extensions: [ - javascript(), - highlighting(JS_HIGHLIGHT_STYLE_SPECS) - ] + extensions: [javascript(), highlighting(JS_HIGHLIGHT_STYLE_SPECS)], })); /** * Function returning CSS language extensions, which should be passed to {initCodeEditor} */ export const languageCSS = memo(() => ({ - extensions: [ - css(), - highlighting(CSS_HIGHLIGHT_STYLE_SPECS) - ] + extensions: [css(), highlighting(CSS_HIGHLIGHT_STYLE_SPECS)], })); /** * Function returning WAST language extensions, which should be passed to {initCodeEditor} */ export const languageWAST = memo(() => ({ - extensions: [ - wast(), - EditorView.lineWrapping,//Makes long lines be wrapped to a new line, instead of creating horizontal scrollbar - highlighting(WAST_HIGHLIGHT_STYLE_SPECS) - ] + extensions: [ + wast(), + EditorView.lineWrapping, //Makes long lines be wrapped to a new line, instead of creating horizontal scrollbar + highlighting(WAST_HIGHLIGHT_STYLE_SPECS), + ], })); /** * Function returning HTML language extensions, which should be passed to {initCodeEditor} */ export const languageHTML = memo(() => { - const language = mixedHTML(); - return ({ - extensions: [ - language, - EditorView.lineWrapping,//Makes long lines be wrapped to a new line, instead of creating horizontal scrollbar - //CSS in