diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba9839a..2ee588f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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]).
diff --git a/README.md b/README.md
index 01a1ef5..44b4fd9 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/src/css/easymde.css b/src/css/easymde.css
index a027a14..92cf821 100644
--- a/src/css/easymde.css
+++ b/src/css/easymde.css
@@ -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;
+}
diff --git a/src/js/easymde.js b/src/js/easymde.js
index 5e4d8ce..761f604 100644
--- a/src/js/easymde.js
+++ b/src/js/easymde.js
@@ -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);
diff --git a/types/easymde-test.ts b/types/easymde-test.ts
index cc08210..63cfb1d 100644
--- a/types/easymde-test.ts
+++ b/types/easymde-test.ts
@@ -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'
+ },
+ ]
}
]
});
diff --git a/types/easymde.d.ts b/types/easymde.d.ts
index 9391416..0ef9e53 100644
--- a/types/easymde.d.ts
+++ b/types/easymde.d.ts
@@ -22,6 +22,29 @@
///
///
+interface ArrayOneOrMore extends Array {
+ 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;
+ 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;
styleSelectedText?: boolean;
tabSize?: number;
- toolbar?: boolean | ReadonlyArray<'|' | ToolbarIcon>;
+ toolbar?: boolean | ReadonlyArray<'|' | ToolbarButton | ToolbarIcon | ToolbarDropdownIcon>;
toolbarTips?: boolean;
onToggleFullScreen?: (goingIntoFullScreen: boolean) => void;
theme?: string;