Skip to content

Commit 10d7990

Browse files
committed
Allow toolbar to be multiline
1 parent ea7b00b commit 10d7990

11 files changed

+114
-18
lines changed

OPTIONS.md

+10
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,16 @@ enables/disables whether the toolbar should be displayed when selecting multiple
232232

233233
The set of buttons to display on the toolbar.
234234

235+
Can also be nested for multiline toolbar:
236+
`[['bold', 'italic', 'underline', 'pre'], ['anchor', 'h2', 'h3', 'quote']]`
237+
238+
**NOTE:**
239+
Depending on the theme you are using, you may need to make some visual
240+
adjustment for proper rendering
241+
(ie. when buttons don't have fixed width).
242+
243+
244+
235245
***
236246
#### `diffLeft`
237247
**Default:** `0`

demo/multiline-toolbar.html

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>medium editor | demo</title>
6+
<link rel="stylesheet" href="css/demo.css">
7+
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css" rel="stylesheet">
8+
<link rel="stylesheet" href="../dist/css/medium-editor.css">
9+
<link rel="stylesheet" href="../dist/css/themes/flat.css" id="medium-editor-theme">
10+
</head>
11+
<body>
12+
<a href="https://github.com/yabwe/medium-editor"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a>
13+
<div class="top-bar">
14+
Theme:
15+
<select id="sel-themes">
16+
<option value="themes/default" selected>default</option>
17+
<option value="themes/roman">roman</option>
18+
<option value="themes/mani">mani</option>
19+
<option value="themes/flat">flat</option>
20+
<option value="themes/bootstrap">bootstrap</option>
21+
<option value="themes/tim">tim</option>
22+
<option value="themes/beagle">beagle</option>
23+
</select>
24+
</div>
25+
<div id="container">
26+
<h1>Medium Editor</h1>
27+
<div class="editable">
28+
<h2>Font Awesome</h2>
29+
<p>My father’s family name being <a href="https://en.wikipedia.org/wiki/Pip_(Great_Expectations)">Pirrip</a>, and my Christian name Philip, my infant tongue could make of both names nothing longer or more explicit than Pip. So, I called myself Pip, and came to be called Pip.</p>
30+
<p>I give Pirrip as my father’s family name, on the authority of his tombstone and my sister,—Mrs. Joe Gargery, who married the blacksmith. As I never saw my father or my mother, and never saw any likeness of either of them (for their days were long before the days of photographs), my first fancies regarding what they were like were unreasonably derived from their tombstones...</p>
31+
</div>
32+
</div>
33+
<p style="text-align: center;"><small><a style="color: #333;" target="_blank" href="http://www.goodreads.com/reader/475-great-expectations">Source</a></small></p>
34+
<script src="../dist/js/medium-editor.js"></script>
35+
<script>
36+
var editor = new MediumEditor('.editable', {
37+
toolbar: {
38+
buttons: [
39+
['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'pre'],
40+
['h2', 'h3', 'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'quote'],
41+
['orderedlist', 'unorderedlist', 'outdent', 'indent', 'anchor', 'image', 'removeFormat']
42+
],
43+
},
44+
buttonLabels: 'fontawesome'
45+
});
46+
cssLink = document.getElementById('medium-editor-theme');
47+
48+
document.getElementById('sel-themes').addEventListener('change', function () {
49+
cssLink.href = '../dist/css/' + this.value + '.css';
50+
});
51+
</script>
52+
</body>
53+
</html>

spec/anchor.spec.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,9 @@ describe('Anchor Button TestCase', function () {
838838
selectElementContentsAndFire(editor.elements[0]);
839839
button = toolbar.getToolbarElement().querySelector('[data-action="createLink"]');
840840
fireEvent(button, 'click');
841-
expect(toolbar.getToolbarActionsElement().style.display).toBe('none');
841+
toolbar.getToolbarActionsElements().forEach(function (el) {
842+
expect(el.style.display).toBe('none');
843+
});
842844
expect(anchorExtension.isDisplayed()).toBe(true);
843845
expect(anchorExtension.showForm).toHaveBeenCalled();
844846
});
@@ -874,7 +876,9 @@ describe('Anchor Button TestCase', function () {
874876
// Click the 'anchor' button in the toolbar
875877
fireEvent(toolbar.getToolbarElement().querySelector('[data-action="createLink"]'), 'click');
876878

877-
expect(toolbar.getToolbarActionsElement().style.display).toBe('none');
879+
toolbar.getToolbarActionsElements().forEach(function (el) {
880+
expect(el.style.display).toBe('none');
881+
});
878882
expect(anchorExtension.isDisplayed()).toBe(true);
879883
expect(anchorExtension.showForm).toHaveBeenCalled();
880884
expect(anchorExtension.getInput().value).toBe('');

spec/fontname.spec.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ describe('Font Name Button TestCase', function () {
3838
selectElementContentsAndFire(editor.elements[0]);
3939
button = toolbar.getToolbarElement().querySelector('[data-action="fontName"]');
4040
fireEvent(button, 'click');
41-
expect(toolbar.getToolbarActionsElement().style.display).toBe('none');
41+
toolbar.getToolbarActionsElements().forEach(function (el) {
42+
expect(el.style.display).toBe('none');
43+
});
4244
expect(fontNameExtension.isDisplayed()).toBe(true);
4345
expect(fontNameExtension.showForm).toHaveBeenCalled();
4446
});

spec/fontsize.spec.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ describe('Font Size Button TestCase', function () {
3838
selectElementContentsAndFire(editor.elements[0]);
3939
button = toolbar.getToolbarElement().querySelector('[data-action="fontSize"]');
4040
fireEvent(button, 'click');
41-
expect(toolbar.getToolbarActionsElement().style.display).toBe('none');
41+
toolbar.getToolbarActionsElements().forEach(function (el) {
42+
expect(el.style.display).toBe('none');
43+
});
4244
expect(fontSizeExtension.isDisplayed()).toBe(true);
4345
expect(fontSizeExtension.showForm).toHaveBeenCalled();
4446
});

src/js/extensions/toolbar.js

+39-9
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@
117117
toolbar.className += ' medium-editor-stalker-toolbar';
118118
}
119119

120-
toolbar.appendChild(this.createToolbarButtons());
120+
this.createToolbarButtons().forEach(function (row) {
121+
toolbar.appendChild(row);
122+
});
121123

122124
// Add any forms that extensions may have
123125
this.forEachExtension(function (extension) {
@@ -132,19 +134,37 @@
132134
},
133135

134136
createToolbarButtons: function () {
137+
var rows = [];
138+
139+
if (Array.isArray(this.buttons[0])) {
140+
this.buttons.forEach(function (row, index) {
141+
rows.push(this.createToolbarButtonsRow(row, index));
142+
}, this);
143+
} else {
144+
rows.push(this.createToolbarButtonsRow(this.buttons, 0));
145+
}
146+
147+
return rows;
148+
},
149+
150+
createToolbarButtonsRow: function (buttons, index) {
135151
var ul = this.document.createElement('ul'),
136152
li,
137153
btn,
138-
buttons,
154+
buttonEls,
139155
extension,
140156
buttonName,
141157
buttonOpts;
142158

143159
ul.id = 'medium-editor-toolbar-actions' + this.getEditorId();
160+
if (index > 0) {
161+
// Preserve backward compatibility and add index only for extra rows
162+
ul.id += '-' + index;
163+
}
144164
ul.className = 'medium-editor-toolbar-actions';
145165
ul.style.display = 'block';
146166

147-
this.buttons.forEach(function (button) {
167+
buttons.forEach(function (button) {
148168
if (typeof button === 'string') {
149169
buttonName = button;
150170
buttonOpts = null;
@@ -169,10 +189,10 @@
169189
}
170190
}, this);
171191

172-
buttons = ul.querySelectorAll('button');
192+
buttonEls = ul.querySelectorAll('button');
173193
if (buttons.length > 0) {
174-
buttons[0].classList.add(this.firstButtonClass);
175-
buttons[buttons.length - 1].classList.add(this.lastButtonClass);
194+
buttonEls[0].classList.add(this.firstButtonClass);
195+
buttonEls[buttonEls.length - 1].classList.add(this.lastButtonClass);
176196
}
177197

178198
return ul;
@@ -202,7 +222,13 @@
202222
},
203223

204224
getToolbarActionsElement: function () {
205-
return this.getToolbarElement().querySelector('.medium-editor-toolbar-actions');
225+
// For backward compatibility
226+
return this.getToolbarActionsElements()[0];
227+
},
228+
229+
getToolbarActionsElements: function () {
230+
var els = this.getToolbarElement().querySelectorAll('.medium-editor-toolbar-actions');
231+
return Array.prototype.slice.call(els);
206232
},
207233

208234
// Toolbar event handlers
@@ -315,15 +341,19 @@
315341

316342
hideToolbarDefaultActions: function () {
317343
if (this.isToolbarDefaultActionsDisplayed()) {
318-
this.getToolbarActionsElement().style.display = 'none';
344+
this.getToolbarActionsElements().forEach(function (el) {
345+
el.style.display = 'none';
346+
});
319347
}
320348
},
321349

322350
showToolbarDefaultActions: function () {
323351
this.hideExtensionForms();
324352

325353
if (!this.isToolbarDefaultActionsDisplayed()) {
326-
this.getToolbarActionsElement().style.display = 'block';
354+
this.getToolbarActionsElements().forEach(function (el) {
355+
el.style.display = 'block';
356+
});
327357
}
328358

329359
// Using setTimeout + options.delay because:

src/sass/themes/beagle.scss

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ $medium-editor-placeholder-color: #f8f5f3;
1010
// theme rules
1111
.medium-toolbar-arrow-under:after {
1212
border-color: $medium-editor-bgcolor transparent transparent transparent;
13-
top: $medium-editor-button-size;
1413
}
1514

1615
.medium-toolbar-arrow-over:before {

src/sass/themes/bootstrap.scss

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ $medium-editor-placeholder-color: #fff;
1111
// theme rules
1212
.medium-toolbar-arrow-under:after {
1313
border-color: $medium-editor-bgcolor transparent transparent transparent;
14-
top: $medium-editor-button-size;
1514
}
1615

1716
.medium-toolbar-arrow-over:before {

src/sass/themes/default.scss

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ $medium-editor-border-radius: 5px;
66
// theme rules
77
.medium-toolbar-arrow-under:after {
88
border-color: $medium-editor-bgcolor transparent transparent transparent;
9-
top: $medium-editor-button-size;
109
}
1110

1211
.medium-toolbar-arrow-over:before {

src/sass/themes/flat.scss

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ $medium-editor-placeholder-color: #fff;
88

99
// theme rules
1010
.medium-toolbar-arrow-under:after {
11-
top: $medium-editor-button-size;
1211
border-color: $medium-editor-bgcolor transparent transparent transparent;
1312
}
1413

src/sass/themes/tim.scss

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ $medium-editor-placeholder-color: #ffedd5;
1111
// theme rules
1212
.medium-toolbar-arrow-under:after {
1313
border-color: $medium-editor-bgcolor transparent transparent transparent;
14-
top: $medium-editor-button-size;
1514
}
1615

1716
.medium-toolbar-arrow-over:before {

0 commit comments

Comments
 (0)