diff --git a/ep.json b/ep.json
index 98d1235..d0a6ac1 100644
--- a/ep.json
+++ b/ep.json
@@ -14,6 +14,7 @@
},
"hooks": {
"eejsBlock_editbarMenuLeft": "ep_headings2/index",
+ "eejsBlock_dd_format_block": "ep_headings2/index",
"collectContentPre": "ep_headings2/static/js/shared",
"collectContentPost": "ep_headings2/static/js/shared",
"ccRegisterBlockElements": "ep_headings2/static/js/shared",
diff --git a/index.js b/index.js
index d038be2..af50b64 100644
--- a/index.js
+++ b/index.js
@@ -18,5 +18,7 @@ const headingsExport = lineAttributeExport({
});
exports.eejsBlock_editbarMenuLeft = template('ep_headings2/templates/editbarButtons.ejs');
+// ep_file_menu_toolbar: paragraph formatting group of the Format menu.
+exports.eejsBlock_dd_format_block = template('ep_headings2/templates/fileMenu.ejs');
exports.stylesForExport = headingsExport.stylesForExport;
exports.getLineHTMLForExport = headingsExport.getLineHTMLForExport;
diff --git a/static/js/index.js b/static/js/index.js
index f44d9d4..a349e85 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -22,7 +22,9 @@ exports.aceDomLineProcessLineAttributes = headings.aceDomLineProcessLineAttribut
// fixed #130.
exports.postAceInit = (hookName, context) => {
toolbarSelect({
- selector: '#heading-selection',
+ // The editbar dropdown and, when ep_file_menu_toolbar is installed, the
+ // copy in the Format menu.
+ selector: '#heading-selection, select.heading-selection',
context,
invoke: (ace, value) => ace.ace_doInsertHeading(value),
op: 'insertheading',
@@ -46,7 +48,8 @@ exports.aceEditEvent = (hookName, call) => {
const attributeManager = call.documentAttributeManager;
const rep = call.rep;
const activeAttributes = {};
- $('#heading-selection').val('dummy').niceSelect('update');
+ const headingSelect = $('#heading-selection, select.heading-selection');
+ headingSelect.val('dummy').niceSelect('update');
const firstLine = rep.selStart[0];
const lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0));
@@ -66,7 +69,7 @@ exports.aceEditEvent = (hookName, call) => {
$.each(activeAttributes, (k, attr) => {
if (attr.count === totalNumberOfLines) {
const ind = tags.indexOf(k);
- $('#heading-selection').val(ind).niceSelect('update');
+ headingSelect.val(ind).niceSelect('update');
}
});
}, 250);
diff --git a/static/tests/backend/specs/filemenu.js b/static/tests/backend/specs/filemenu.js
new file mode 100644
index 0000000..9b1d8d5
--- /dev/null
+++ b/static/tests/backend/specs/filemenu.js
@@ -0,0 +1,55 @@
+'use strict';
+
+const assert = require('assert').strict;
+const fs = require('fs');
+const path = require('path');
+const ejs = require('ep_etherpad-lite/node_modules/ejs');
+
+const root = path.resolve(__dirname, '..', '..', '..', '..');
+const render = (name) =>
+ ejs.render(fs.readFileSync(path.join(root, 'templates', name), 'utf8'), {});
+const locales = JSON.parse(fs.readFileSync(path.join(root, 'locales', 'en.json'), 'utf8'));
+const epJson = JSON.parse(fs.readFileSync(path.join(root, 'ep.json'), 'utf8'));
+
+// Every