2
0
mirror of https://github.com/Ionaru/easy-markdown-editor synced 2025-07-16 06:24:28 -06:00

Merge pull request #141 from firm1/dropdown

feat : allow dropdown menu on toolbar to group secondary buttons
This commit is contained in:
Jeroen Akkerman 2020-03-08 13:22:40 +01:00 committed by GitHub
commit 3096bbe291
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 177 additions and 29 deletions

View File

@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- `inputStyle` and `nativeSpellcheck` options to manage the native language of the browser (Thanks to [@firm1], [#143]).
- Group buttons in drop-down lists by adding a sub-option `children` for the items in the toolbar (Thanks to [@firm1], [#141]).
- `sanitizerFunction` option to allow custom HTML sanitizing in the markdown preview (Thanks to [@adamb70], [#147]).
### Changed
- Delay before assuming that submit of the form as failed is `autosave.submit_delay` instead of `autosave.delay` (Thanks to [@Situphen], [#139]).

View File

@ -351,6 +351,46 @@ var easyMDE = new EasyMDE({
});
```
Put some buttons on dropdown menu
```Javascript
var easyMDE = new EasyMDE({
toolbar: [{
name: "heading",
action: EasyMDE.toggleHeadingSmaller,
className: "fa fa-header",
title: "Headers",
},
"|",
{
name: "others",
className: "fa fa-blind",
title: "others buttons",
children: [
{
name: "image",
action: EasyMDE.drawImage,
className: "fa fa-picture-o",
title: "Image",
},
{
name: "quote",
action: EasyMDE.toggleBlockquote,
className: "fa fa-percent",
title: "Quote",
},
{
name: "link",
action: EasyMDE.drawLink,
className: "fa fa-link",
title: "Link",
}
]
},
// [, ...]
]
});
```
### Keyboard shortcuts

View File

@ -22,7 +22,7 @@
right: 0;
bottom: 0;
height: auto;
z-index: 9;
z-index: 8;
border-right: none !important;
border-bottom-right-radius: 0 !important;
}
@ -72,9 +72,6 @@
.editor-toolbar.fullscreen {
width: 100%;
height: 50px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
@ -119,12 +116,11 @@
padding: 0;
}
.editor-toolbar button {
.editor-toolbar button, .editor-toolbar .easymde-dropdown {
background: transparent;
display: inline-block;
text-align: center;
text-decoration: none !important;
width: 30px;
height: 30px;
margin: 0;
padding: 0;
@ -133,6 +129,10 @@
cursor: pointer;
}
.editor-toolbar button {
width: 30px;
}
.editor-toolbar button.active,
.editor-toolbar button:hover {
background: #fcfcfc;
@ -316,3 +316,29 @@
color: #7f8c8d;
font-style: italic;
}
.editor-toolbar .easymde-dropdown {
position: relative;
background: linear-gradient(to bottom right, #fff 0%, #fff 84%, #333 50%, #333 100%);
border-radius: 0;
border: 1px solid #fff;
}
.editor-toolbar .easymde-dropdown:hover {
background: linear-gradient(to bottom right, #fff 0%, #fff 84%, #333 50%, #333 100%);
}
.easymde-dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
padding: 8px;
z-index: 2;
top: 30px;
}
.easymde-dropdown:active .easymde-dropdown-content,
.easymde-dropdown:focus .easymde-dropdown-content {
display: block;
}

View File

@ -110,15 +110,39 @@ function fixShortcut(name) {
return name;
}
/**
* Create dropdown block
*/
function createToolbarDropdown(options, enableTooltips, shortcuts, parent) {
var el = createToolbarButton(options, false, enableTooltips, shortcuts, 'button', parent);
el.className += ' easymde-dropdown';
var content = document.createElement('div');
content.className = 'easymde-dropdown-content';
for (var childrenIndex = 0; childrenIndex < options.children.length; childrenIndex++) {
var child = options.children[childrenIndex];
var childElement;
if (typeof child === 'string' && child in toolbarBuiltInButtons) {
childElement = createToolbarButton(toolbarBuiltInButtons[child], true, enableTooltips, shortcuts, 'button', parent);
} else {
childElement = createToolbarButton(child, true, enableTooltips, shortcuts, 'button', parent);
}
content.appendChild(childElement);
}
el.appendChild(content);
return el;
}
/**
* Create button element for toolbar.
*/
function createToolbarButton(options, enableTooltips, shortcuts) {
function createToolbarButton(options, enableActions, enableTooltips, shortcuts, markup, parent) {
options = options || {};
var el = document.createElement('button');
var el = document.createElement(markup);
el.className = options.name;
el.setAttribute('type', 'button');
el.setAttribute('type', markup);
enableTooltips = (enableTooltips == undefined) ? true : enableTooltips;
// Properly hande custom shortcuts
@ -167,6 +191,20 @@ function createToolbarButton(options, enableTooltips, shortcuts) {
}
el.appendChild(icon);
if (options.action && enableActions) {
if (typeof options.action === 'function') {
el.onclick = function (e) {
e.preventDefault();
options.action(parent);
};
} else if (typeof options.action === 'string') {
el.onclick = function (e) {
e.preventDefault();
window.open(options.action, '_blank');
};
}
}
return el;
}
@ -1762,7 +1800,7 @@ EasyMDE.prototype.markdown = function (text) {
// Convert the markdown to HTML
var htmlText = marked(text);
// Sanitize HTML
if (this.options.renderingConfig && typeof this.options.renderingConfig.sanitizerFunction === 'function') {
htmlText = this.options.renderingConfig.sanitizerFunction.call(this, htmlText);
@ -2258,24 +2296,12 @@ EasyMDE.prototype.createToolbar = function (items) {
var el;
if (item === '|') {
el = createSep();
} else if (item.children) {
el = createToolbarDropdown(item, self.options.toolbarTips, self.options.shortcuts, self);
} else {
el = createToolbarButton(item, self.options.toolbarTips, self.options.shortcuts);
el = createToolbarButton(item, true, self.options.toolbarTips, self.options.shortcuts, 'button', self);
}
// bind events, special for info
if (item.action) {
if (typeof item.action === 'function') {
el.onclick = function (e) {
e.preventDefault();
item.action(self);
};
} else if (typeof item.action === 'string') {
el.onclick = function (e) {
e.preventDefault();
window.open(item.action, '_blank');
};
}
}
toolbarData[item.name || item] = el;
bar.appendChild(el);

View File

@ -43,18 +43,18 @@ const editor2 = new EasyMDE({
{
name: 'bold',
action: EasyMDE.toggleBold,
className: 'fa fa-bolt',
className: 'fa fas fa-bolt',
title: 'Bold'
},
'|',
'undo',
{
// Separator
name: 'alert',
action: (editor: EasyMDE) => {
alert('This is from a custom button action!');
// Custom functions have access to the `editor` instance.
},
className: 'fa fa-star',
className: 'fa fas fa-star',
title: 'A Custom Button',
noDisable: undefined,
noMobile: false
@ -67,6 +67,29 @@ const editor2 = new EasyMDE({
title: 'A Custom Link',
noDisable: true,
noMobile: true
},
'preview',
{
name: 'links',
className: 'fa fas fa-arrow-down',
title: 'A Custom Link',
children: [
{
name: 'link',
action: 'https://github.com/Ionaru/easy-markdown-editor',
className: 'fa fab fa-github',
title: 'A Custom Link',
noDisable: true,
noMobile: true
},
'preview',
{
name: 'bold',
action: EasyMDE.toggleBold,
className: 'fa fas fa-bold',
title: 'Bold'
},
]
}
]
});

34
types/easymde.d.ts vendored
View File

@ -22,6 +22,29 @@
/// <reference types="codemirror"/>
/// <reference types="marked"/>
interface ArrayOneOrMore<T> extends Array<T> {
0: T
}
type ToolbarButton =
'strikethrough'
| 'code'
| 'table'
| 'redo'
| 'heading'
| 'undo'
| 'heading-bigger'
| 'heading-smaller'
| 'heading-1'
| 'heading-2'
| 'heading-3'
| 'clean-block'
| 'horizontal-rule'
| 'preview'
| 'side-by-side'
| 'fullscreen'
| 'guide';
declare namespace EasyMDE {
interface AutoSaveOptions {
enabled?: boolean;
@ -87,6 +110,15 @@ declare namespace EasyMDE {
onUpdate: (element: HTMLElement) => void;
}
interface ToolbarDropdownIcon {
name: string;
children: ArrayOneOrMore<ToolbarIcon | ToolbarButton>;
className: string;
title: string;
noDisable?: boolean;
noMobile?: boolean;
}
interface ToolbarIcon {
name: string;
action: string | ((editor: EasyMDE) => void);
@ -139,7 +171,7 @@ declare namespace EasyMDE {
status?: boolean | ReadonlyArray<string | StatusBarItem>;
styleSelectedText?: boolean;
tabSize?: number;
toolbar?: boolean | ReadonlyArray<'|' | ToolbarIcon>;
toolbar?: boolean | ReadonlyArray<'|' | ToolbarButton | ToolbarIcon | ToolbarDropdownIcon>;
toolbarTips?: boolean;
onToggleFullScreen?: (goingIntoFullScreen: boolean) => void;
theme?: string;