
Если вы заинтересованы в том, чтобы помочь поддерживать одного из самых успешных редакторов текста Wysiwyg в GitHub, сообщите нам! (См. Выпуск № 1503)
Это клон инструментов инструментов Medium.com.
MediumEditor был написан с использованием ванильного JavaScript, никаких дополнительных платформ не требуется.
Демо : http://yabwe.github.io/medium-editor/
Через NPM:
Запустите в консоли: npm install medium-editor
Через Bower:
bower install medium-editor
Через внешний CDN
Для последней версии:
< script src =" //cdn.jsdelivr.net/npm/medium-editor@latest/dist/js/medium-editor.min.js " > </ script >
< link rel =" stylesheet " href =" //cdn.jsdelivr.net/npm/medium-editor@latest/dist/css/medium-editor.min.css " type =" text/css " media =" screen " charset =" utf-8 " >Для пользовательского:
< script src =" //cdn.jsdelivr.net/npm/[email protected]/dist/js/medium-editor.min.js " > </ script >
< link rel =" stylesheet " href =" //cdn.jsdelivr.net/npm/[email protected]/dist/css/medium-editor.min.css " type =" text/css " media =" screen " charset =" utf-8 " >Ручная установка:
Загрузите последний выпуск и прикрепите таблицы стилей среднего редактора к вашей странице:
Найдите файлы, которые ниже упомянули, связывают в папке Dist. (./medium-editor/dist/...)
< link rel =" stylesheet " href =" css/medium-editor.css " > <!-- Core -->
< link rel =" stylesheet " href =" css/themes/default.css " > <!-- or any other theme -->Следующим шагом является ссылка на сценарий редактора
< script src =" js/medium-editor.js " > </ script >Теперь вы можете создать создание нового объекта MediumEditor:
< script > var editor = new MediumEditor ( '.editable' ) ; </ script >Приведенный выше код будет преобразовать все элементы с помощью класса.
Вы также можете передать список элементов HTML:
var elements = document . querySelectorAll ( '.editable' ) ,
editor = new MediumEditor ( elements ) ; MediumEditor также поддерживает Textarea. Если вы предоставите элемент Textarea, скрипт создаст новый Div с contentEditable=true , скрыть Textarea и свяжите значение Textarea с содержанием Div HTML.
Люди внесли вклад в MediumEditor для интеграции с различными рамками и техническими стеками. Взгляните на список существующих оберток и интеграций, которые уже были написаны для MediumEditor!
Посмотреть документацию «MediumEditor» на всех различных вариантах для MediumEditor.
Параметры для настройки среднего редактора передаются в качестве второго аргумента конструктору MediumEditor. Пример:
var editor = new MediumEditor ( '.editor' , {
// options go here
} ) ;'medium-editor-button-active'false | 'Fontawesome'. По умолчанию: false Использование 'fontawesome' в качестве Buttonlabels требует версии 4.1.0 Fontawesome CSS, чтобы быть на странице, чтобы убедиться, что все значки будут отображаться правильно
0falsefalsefalsefalsedocument.body{}truefalseПанель инструментов для MediumEditor реализована как встроенное расширение, которое автоматически отображается всякий раз, когда пользователь выбирает немного текста. Панель инструментов может удерживать любой набор определенных встроенных кнопок, но также может удерживать любые пользовательские кнопки, передаваемые в виде расширений.
Параметры для панели инструментов передаются как объект, который является членом объекта внешних параметров. Пример:
var editor = new MediumEditor ( '.editable' , {
toolbar : {
/* These are the default options for the toolbar,
if nothing is passed this is what is used */
allowMultiParagraphSelection : true ,
buttons : [ 'bold' , 'italic' , 'underline' , 'anchor' , 'h2' , 'h3' , 'quote' ] ,
diffLeft : 0 ,
diffTop : - 10 ,
firstButtonClass : 'medium-editor-button-first' ,
lastButtonClass : 'medium-editor-button-last' ,
relativeContainer : null ,
standardizeSelectionStart : false ,
static : false ,
/* options which only apply when static is true */
align : 'center' ,
sticky : false ,
updateOnEmptySelection : false
}
} ) ;true['bold', 'italic', 'underline', 'anchor', 'h2', 'h3', 'quote']0-10'medium-editor-button-first''medium-editor-button-last'relative а не absolute . По умолчанию: nullfalsefalse static опции:left | center | right - когда статический вариант true , это выравнивает статическую панель инструментов по сравнению с элементом среднего редактора. По умолчанию: centertrue , это позволяет/отключает панель инструментов «прилипать» к видому допу и оставаться видимым на экране, пока прокручивается страница. По умолчанию: falsetrue , это позволяет/отключает обновление состояния кнопок панели инструментов, даже когда выбор обрушен (нет выбора, просто курсор). По умолчанию: false Чтобы отключить панель инструментов (которая также отключает расширение привязки к привязке), установите значение опции toolbar на false :
var editor = new MediumEditor ( '.editable' , {
toolbar : false
} ) ; Поведение кнопки может быть изменено, передавая объект в массив кнопок вместо строки. Это позволяет переопределить некоторые из поведения кнопок по умолчанию. Следующие параметры - некоторые из основных частей кнопок, которые вы можете переопределить, но любая часть MediumEditor.Extension.prototype может быть переопределена с помощью этих параметров кнопки. (Проверьте исходный код для кнопок, чтобы увидеть, что все можно переопределить).
MediumEditor.execAction() Когда нажата кнопка.<b> или <strong> , который указывает, что текст уже смел. Таким образом, массив тагнамов для жирного шрифта будет: ['b', 'strong']useQueryState установлен на true .'font-weight' установленным в 700 или 'bold' , указывает на то, что текст уже смел. Таким образом, объектом стиля для жирного шрифта будет { prop: 'font-weight', value: '700|bold' }useQueryState установлен на true .'|' )document.queryCommandState() . Если действие уже было применено, кнопка будет отображаться как «активная» на панели инструментовdocument.queryCommandState('bold') , который вернет True, если браузер думает, что текст уже смел, и в противном случае ложь в противном случаеinnerHTML , чтобы положить внутрь кнопкиinnerHTML для использования для содержимого кнопки, если опция ButtonLabels для MediumEditor установлена на 'fontawesome' Пример переоценки кнопок (здесь цель состоит в том, чтобы имитировать среду, имея кнопки H1 и H2 , которые на самом деле производят теги <h2> и <h3> соответственно):
var editor = new MediumEditor ( '.editable' , {
toolbar : {
buttons : [
'bold' ,
'italic' ,
{
name : 'h1' ,
action : 'append-h2' ,
aria : 'header type 1' ,
tagNames : [ 'h2' ] ,
contentDefault : '<b>H1</b>' ,
classList : [ 'custom-class-h1' ] ,
attrs : {
'data-custom-attr' : 'attr-value-h1'
}
} ,
{
name : 'h2' ,
action : 'append-h3' ,
aria : 'header type 2' ,
tagNames : [ 'h3' ] ,
contentDefault : '<b>H2</b>' ,
classList : [ 'custom-class-h2' ] ,
attrs : {
'data-custom-attr' : 'attr-value-h2'
}
} ,
'justifyCenter' ,
'quote' ,
'anchor'
]
}
} ) ; Предварительный просмотр якоря представляет собой встроенное расширение, которое автоматически отображает «подсказку», когда пользователь падает над ссылкой в редакторе. Подсказка будет отображать href ссылки, и при нажатии откроется форма редактирования привязки на панели инструментов.
Параметры для предварительного просмотра якоря «подсказка» передаются как объект, который является членом объекта Outter Options. Пример:
var editor = new MediumEditor ( '.editable' , {
anchorPreview : {
/* These are the default options for anchor preview,
if nothing is passed this is what it used */
hideDelay : 500 ,
previewValueSelector : 'a'
}
}
} ) ;500'a'falsetrue Чтобы отключить предварительный просмотр привязки, установите значение опции anchorPreview на false :
var editor = new MediumEditor ( '.editable' , {
anchorPreview : false
} ) ; toolbar: false Option или data-disable-toolbar Attribute), анкер-просмотр автоматически отключен.Обработчик заполнителей-это встроенное расширение, которое отображает текст заполнителей, когда редактор пуст.
Параметры для заполнителя передаются как объект, который является членом объекта внешних опций. Пример:
var editor = new MediumEditor ( '.editable' , {
placeholder : {
/* This example includes the default options for placeholder,
if nothing is passed this is what it used */
text : 'Type your text' ,
hideOnClick : true
}
} ) ; Текст : определяет заполнитель по умолчанию для пустых довольных довольных, когда Placeholder не установлен на False. Вы можете перезаписать его, установив атрибут data-placeholder на элементах редактора. По умолчанию: 'Type your text'
HideOnClick : заставляет заполнителя исчезнуть, как только поле набирает фокус. По умолчанию: true . Чтобы скрыть заполнителя только после того, как начнут печатать, и показывать его снова, как только поле пустое, установите эту опцию на false .
Чтобы отключить заполнитель, установите значение опции placeholder на false :
var editor = new MediumEditor ( '.editable' , {
placeholder : false
} ) ;Форма якоря представляет собой встроенное расширение кнопки, которое позволяет пользователю добавлять/редактировать/удалять ссылки из редактора. Когда «якорь» передается в виде кнопки в списке кнопок, это расширение будет включено и может быть запускается, нажав соответствующую кнопку на панели инструментов.
Параметры для формы якоря передаются как объект, который является членом объекта внешних параметров. Пример:
var editor = new MediumEditor ( '.editable' , {
toolbar : {
buttons : [ 'bold' , 'italic' , 'underline' , 'anchor' ]
} ,
anchor : {
/* These are the default options for anchor form,
if nothing is passed this is what it used */
customClassOption : null ,
customClassOptionText : 'Button' ,
linkValidation : false ,
placeholderText : 'Paste or type a link' ,
targetCheckbox : false ,
targetCheckboxText : 'Open in new window'
}
}
} ) ;null'Button'encodeURI . По умолчанию: false'Paste or type a link'target созданной ссылки. По умолчанию: false'Open in new window'Обработчик вставки-это встроенное расширение, которое пытается отфильтровать контент, когда пользователь встает. Как настраивается фильтры обработчика вставки с помощью определенных параметров.
Параметры для обработки вставки передаются как объект, который является членом объекта Outter Options. Пример:
var editor = new MediumEditor ( '.editable' , {
paste : {
/* This example includes the default options for paste,
if nothing is passed this is what it used */
forcePlainText : true ,
cleanPastedHTML : false ,
cleanReplacements : [ ] ,
cleanAttrs : [ 'class' , 'style' , 'dir' ] ,
cleanTags : [ 'meta' ] ,
unwrapTags : [ ]
}
} ) ;truefalsetrue или при вызове вспомогательного cleanPaste(text) метод. Эти замены выполняются перед заменой строительства. По умолчанию: []true или при вызове вспомогательного cleanPaste(text) метод. Эти замены выполняются после замены встроенных. По умолчанию: []true или при вызове методов cleanPaste(text) или pasteHTML(html,options) . По умолчанию: ['class', 'style', 'dir']true или при вызове методов cleanPaste(text) pasteHTML(html,options) . По умолчанию: ['meta']true или при вызове методов cleanPaste(text) или pasteHTML(html,options) . По умолчанию: []Обработчик команд клавиатуры-это встроенное расширение для сопоставления скомбьманий клавиш с действиями для выполнения в редакторе.
Параметры для клавишников передаются как объект, который является членом объекта Outter Options. Пример:
var editor = new MediumEditor ( '.editable' , {
keyboardCommands : {
/* This example includes the default options for keyboardCommands,
if nothing is passed this is what it used */
commands : [
{
command : 'bold' ,
key : 'B' ,
meta : true ,
shift : false ,
alt : false
} ,
{
command : 'italic' ,
key : 'I' ,
meta : true ,
shift : false ,
alt : false
} ,
{
command : 'underline' ,
key : 'U' ,
meta : true ,
shift : false ,
alt : false
}
] ,
}
} ) ;editor.execAction()false , ярлык будет отключен Чтобы отключить команды клавиатуры, установите значение параметра keyboardCommands на false :
var editor = new MediumEditor ( '.editable' , {
keyboardCommands : false
} ) ;Обработчик автоматической связи-это встроенное расширение, которое автоматически превращает URL-адреса, введенные в текстовое поле в теги HTML-якоря (аналогично функциональности отметки). Эта функция выключена по умолчанию.
Чтобы включить встроенную поддержку автоматической связи, установите значение опции autoLink на true :
var editor = new MediumEditor ( '.editable' , {
autoLink : true
} ) ;Обработчик перетаскивания изображений-это встроенное расширение для обработки перетаскивания и сбрасывания изображений в довольные. Эта функция включена по умолчанию.
Чтобы отключить встроенное перетаскивание изображений, установите значение параметра imageDragging на false :
var editor = new MediumEditor ( '.editable' , {
imageDragging : false
} ) ; Чтобы прекратить предотвращение событий перетаскивания и отключить перетаскивание файлов в целом, предоставьте фиктивное расширение имагедрагинг.
var editor = new MediumEditor ( '.editor' , {
extensions : {
'imageDragging' : { }
}
} ) ;Из -за состояния кода в 5.0.0 редактор всегда предотвращал любые действия по перетаскиванию. У нас будет лучший способ отключить перетаскивание файлов в 6.*
var editor = new MediumEditor ( '.editable' , {
delay : 1000 ,
targetBlank : true ,
toolbar : {
buttons : [ 'bold' , 'italic' , 'quote' ] ,
diffLeft : 25 ,
diffTop : 10 ,
} ,
anchor : {
placeholderText : 'Type a link' ,
customClassOption : 'btn' ,
customClassOptionText : 'Create Button'
} ,
paste : {
cleanPastedHTML : true ,
cleanAttrs : [ 'style' , 'dir' ] ,
cleanTags : [ 'label' , 'meta' ] ,
unwrapTags : [ 'sub' , 'sup' ]
} ,
anchorPreview : {
hideDelay : 300
} ,
placeholder : {
text : 'Click to edit'
}
} ) ; По умолчанию MediumEditor поддерживает кнопки для большинства команд для document.execCommand() .
MediumEditor, по умолчанию, покажет только те кнопки, перечисленные здесь, чтобы избежать огромной панели инструментов:
Это все встроенные кнопки, поддерживаемые MediumEditor.
Проверьте страницу Wiki для списка доступных тем: https://github.com/yabwe/medium-editor/wiki/themes
Посмотреть документацию API объекта MediumEditor на вики для получения подробной информации обо всех методах, поддерживаемых на объекте MediumEditor.
on()importSelection()exportSelection() )saveSelection()document.execCommand('createLink')document.execCommanddocument.queryCommandState(action) для проверки того, применяется ли конкретное действие к выбору.delayinnerHTML элемента в indexinnerHTML в html элемента в indexМожно динамически добавить новые элементы в ваш экземпляр MediumEditor:
var editor = new MediumEditor ( '.editable' ) ;
editor . subscribe ( 'editableInput' , this . _handleEditableInput . bind ( this ) ) ;
// imagine an ajax fetch/any other dynamic functionality which will add new '.editable' elements to the DOM
editor . addElements ( '.editable' ) ;
// OR editor.addElements(document.getElementsByClassName('editable'));
// OR editor.addElements(document.querySelectorAll('.editable')); Передача элементов или множество элементов в addElements(elements) будет:
this.elements .<textarea> элементов:<textarea><div contenteditable=true> элемент и добавьте его в массив элементов. Прямо вперед, просто вызовите removeElements с элементом или множеством элементов, которые вы хотите снести. Каждый элемент сам останется довольным - он просто удалит все обработчики событий и все ссылки на него, чтобы вы могли безопасно удалить его из DOM.
editor . removeElements ( document . querySelector ( '#myElement' ) ) ;
// OR editor.removeElements(document.getElementById('myElement'));
// OR editor.removeElements('#myElement');
// in case you have jQuery and don't exactly know when an element was removed, for example after routing state change
var removedElements = [ ] ;
editor . elements . forEach ( function ( element ) {
// check if the element is still available in current DOM
if ( ! $ ( element ) . parents ( 'body' ) . length ) {
removedElements . push ( element ) ;
}
} ) ;
editor . removeElements ( removedElements ) ; Для наблюдения за любыми изменениями в довольных, используйте пользовательское событие 'editableInput' выявленное с помощью метода subscribe() :
var editor = new MediumEditor ( '.editable' ) ;
editor . subscribe ( 'editableInput' , function ( event , editable ) {
// Do some work
} ) ; Это событие поддерживается во всех браузерах, поддерживаемых MediumEditor (включая IE9+ и Edge)! Чтобы помочь в случаях, когда один экземпляр MediumEditor контролирует несколько элементов, 2 -й аргумент, переданный обработчику событий ( editable в примере выше), будет ссылкой на довольный элемент, который фактически изменился.
Это удобно, когда вам нужно запечатлеть любые модификации элемента довольного, включая:
Почему это интересно и почему вы должны использовать это событие вместо того, чтобы просто прикрепить к input событию на довольном элементе?
Таким образом, для большинства современных браузеров (Chrome, Firefox, Safari и т. Д.), input событие работает очень хорошо. На самом деле, editableInput - это лишь прокси для input события в этих браузерах. Тем не менее, input событие не поддерживается для довольных элементов в IE 9-11 и в основном поддерживается в Microsoft Edge, но не в полной мере.
Таким образом, для правильной поддержки события editableInput в Internet Explorer и Microsoft Edge, MediumEditor использует комбинацию событий selectionchange и keypress , а также мониторинг вызовов document.execCommand .
Проверьте документацию, чтобы узнать, как разрабатывать расширения для MediumEditor.
Здесь можно найти список существующих расширений и плагинов, таких как изображения и носители, таблицы и уценки.
Запустить демонстрацию на местном уровне:
npm install из вашей консоли в корнеnode index.js из корняhttp://localhost:8088/demo/index.html чтобы просмотреть демонстрациюЗадачи разработки среднего размера управляются Grunt. Чтобы установить все необходимые пакеты, просто вызвать:
npm installЧтобы запустить весь тест и создать файлы Dist для тестирования на демо -страницах, просто вызовите:
gruntЭто другие доступные Grunt Tasks:
Исходные файлы расположены внутри каталога SRC . Обязательно внесите изменения в эти файлы, а не файлы в дистанционном каталоге.
Убей некоторых ошибок :)
git checkout -b my-new-feature )git commit -am 'Added some feature' ) без файлов из Dist Directory .git push origin my-new-feature )Чтобы помочь создать последовательный код на протяжении всего проекта, мы используем несколько инструментов, чтобы помочь нам. У них есть плагины для большинства популярных редакторов/IDE, чтобы сделать кодирование для нашего проекта, но вы должны использовать их в своем проекте!
Мы используем Jshint на каждой сборке, чтобы найти простые ошибки и потенциальные проблемы в нашем JS. Вы можете найти наши настройки Jshint в файле .jshintrc в корне проекта.
Мы используем JSC на каждой сборке для обеспечения соблюдения некоторых правил стиля кода, которые мы имеем для нашего проекта. Вы можете найти наши настройки JSCS в файле .jscsrc в корне проекта.
Мы используем EditorConfig для поддержания последовательных стилей кодирования между различными редакторами и IDE. Вы можете найти наши настройки в файле .editorconfig в корне проекта.
Ищете что -нибудь простое для первого вклада? Попробуйте исправить легкую первую ошибку!
https://github.com/yabwe/medium-editor/graphs/contributors
Добавьте здесь свою организацию, и мы можем добавить вас на нашу целевую страницу!
MIT: https://github.com/yabwe/medium-editor/blob/master/license