Vue.js + базовый javascript, html и css. живите здесь: https://editor.alhinds.com/

Если вы когда-либо использовали GitHub, вы, вероятно, использовали его текстовый редактор. Может быть, вы придумали простую суть, или, возможно, вы внесли простое изменение в существующий коммит, а может быть, именно так вы пишете весь свой код.

Что интересно в редакторе, а также в таких редакторах, как CodePen, Ideone и т. Д., Так это то, что они должны решать, как они собираются поступать с такими вещами, как выделение синтаксиса, различные формы разметки, выделения, интервалы и т. Д. проблем, потому что базовый тег html `‹textarea› очень ограничен.

Посмотреть на себя. Нажмите на большинство сайтов, которые позволяют более богатое форматирование текста или выделение синтаксиса, и обратите внимание, что вы чаще всего фактически не вводите текст в текстовое поле - или, если вы являетесь, текстовое поле находится не там, где оно кажется.

Вот, например, GitHub.

Чтобы мы могли в полной мере использовать преимущества CSS и HTML, GitHub создал вторичный рендеринг ‹div /›, с которым, как мы * думаем *, взаимодействуем, и который включает в себя все наши богатые элементы, наш красивый шрифт и выделение, с лежащим в основе ‹Textarea /›, с которым мы на самом деле взаимодействуем.

Для этого существуют разные уровни сложности, но по сути это довольно простая концепция, которую можно попробовать и реализовать, поэтому я продолжил.

Как я это сделал

Я не хотел слишком углубляться в то, что уже пытались сделать несколько библиотек, но у меня была идея, как реализовать «зеркало» для создания такого же эффекта, как и вышеупомянутый.

Я использую markdown для синтаксического разбора, а highlightjs - для выделения всего остального синтаксиса. Это ослабило мое внимание к простому созданию зеркала, вместо того чтобы беспокоиться о других проблемах синтаксического анализа.

Подобно тому, как я объяснил выше, я использовал ‹textarea /› для хранения вводимого текста, хотя, поиграв с ним, он также работал бы с ванильным contenteditable ‹div /›. Это идеально совпадает с рендером ‹div /›, в котором, по мнению пользователя, он редактирует свой текст.

Результат довольно хороший, нет ощутимой разницы в задержке ввода из-за двойного рендеринга, хотя я не пробовал работать с огромными документами (это не совсем суть проекта).

Ключевой задачей было добиться желаемого расположения, выравнивания и выбора в линейке. Это было нетривиально, поскольку требовалось синхронизировать шрифты, учитывать и правильно отображать пробелы (по умолчанию полосы HTML).

ТАКЖЕ игнорируйте интервал табуляции и размер шрифта, они еще не были динамическими, несмотря на возможность выбора.

Выполнение HTML, Markdown и JS

Довольный исходной структурой, я добавил еще несколько функций, включая выполнение кода JS (с использованием eval :() и ‹iframe›, чтобы обеспечить надлежащий встроенный рендеринг HTML. Вы можете поиграть с ними, просто изменив тип файла. Ура.