add heading with option for supported heading levels (#65398)
This commit is contained in:
parent
52dcdb9bb5
commit
5b542c4e37
12
README.md
12
README.md
|
@ -34,7 +34,7 @@ Use Godo
|
|||
import in your webpage
|
||||
|
||||
* dist/css/godo.css
|
||||
* dist/js.godo.js
|
||||
* dist/js.godo.min.js
|
||||
|
||||
Transform a textarea in godo
|
||||
|
||||
|
@ -48,6 +48,16 @@ Transform a textarea in godo
|
|||
|
||||
For more examples, see dist/index.html.
|
||||
|
||||
Options
|
||||
-----
|
||||
|
||||
Object passed as 2nd parameter
|
||||
|
||||
* `schema`: string / Choose schema that activates the possibilities of the editor.
|
||||
** `basic`: very simple editing: paragraphe, bold & italic.
|
||||
** `headers`: basic schema with titles.
|
||||
* `heading_levels`: array / Specifies which heading levels are supported. 3 levels max. Default `[3, 4]`.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
|
|
@ -98,3 +98,7 @@
|
|||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
.menuicon-hh {
|
||||
font-variant: small-caps;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ const mac = typeof navigator != "undefined" ? /Mac/.test(navigator.platform) : f
|
|||
// You can suppress or map these bindings by passing a `mapKeys`
|
||||
// argument, which maps key names (say `"Mod-B"` to either `false`, to
|
||||
// remove the binding, or a new key name string.
|
||||
export function buildKeymap(schema, mapKeys) {
|
||||
export function buildKeymap(schema, mapKeys, options) {
|
||||
let keys = {}, type;
|
||||
function bind(key, cmd) {
|
||||
if (mapKeys) {
|
||||
|
@ -80,8 +80,11 @@ export function buildKeymap(schema, mapKeys) {
|
|||
bind("Shift-Ctrl-0", setBlockType(type))
|
||||
if (type = schema.nodes.code_block)
|
||||
bind("Shift-Ctrl-\\", setBlockType(type))
|
||||
if (type = schema.nodes.heading)
|
||||
for (let i = 1; i <= 6; i++) bind("Shift-Ctrl-" + i, setBlockType(type, {level: i}))
|
||||
if (type = schema.nodes.heading) {
|
||||
options.heading_levels.forEach( (level, index) => {
|
||||
bind(`Shift-Ctrl-${index+1}`, setBlockType(type, {level: level}))
|
||||
});
|
||||
}
|
||||
if (type = schema.nodes.horizontal_rule) {
|
||||
let hr = type
|
||||
bind("Mod-_", (state, dispatch) => {
|
||||
|
|
|
@ -28,13 +28,33 @@ const languageContent = {
|
|||
"h": {
|
||||
en: {
|
||||
icon: "H",
|
||||
text: "Header"
|
||||
text: "Headline"
|
||||
},
|
||||
fr: {
|
||||
icon: "T",
|
||||
text: "Titre"
|
||||
}
|
||||
},
|
||||
"hh": {
|
||||
en: {
|
||||
icon: "h",
|
||||
text: "Subhead"
|
||||
},
|
||||
fr: {
|
||||
icon: "t",
|
||||
text: "Sous-titre"
|
||||
}
|
||||
},
|
||||
"hhh": {
|
||||
en: {
|
||||
icon: "hh",
|
||||
text: 'Crosshead'
|
||||
},
|
||||
fr: {
|
||||
icon: "tt",
|
||||
text: "Intertitre"
|
||||
}
|
||||
},
|
||||
"i": {
|
||||
en: {
|
||||
icon: "i",
|
||||
|
@ -47,11 +67,11 @@ const languageContent = {
|
|||
},
|
||||
"p": {
|
||||
en: {
|
||||
icon: "P",
|
||||
icon: "p",
|
||||
text: "paragraph",
|
||||
},
|
||||
fr: {
|
||||
icon: "P",
|
||||
icon: "p",
|
||||
text: "paragraphe"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ class Menu {
|
|||
// if single cursor
|
||||
if ($cursor && $cursor.marks()) {
|
||||
const activeMarks = $cursor.marks().map( m => m.type.name);
|
||||
get_is_active = (type) => activeMarks.includes(type.name) ? true : false;;
|
||||
get_is_active = (type) => activeMarks.includes(type.name) ? true : false;
|
||||
this.el.classList.add("fade");
|
||||
|
||||
// else = select range
|
||||
|
@ -118,6 +118,11 @@ function linkItem( type ) {
|
|||
}
|
||||
};
|
||||
|
||||
function setHeader(type, level, icon_id) {
|
||||
return {
|
||||
run: setBlockType(type, {level}), dom: icon(icon_id)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create menu icons
|
||||
// id: defined in languageContent
|
||||
|
@ -130,31 +135,26 @@ function icon(id) {
|
|||
return menuicon;
|
||||
}
|
||||
|
||||
// Create an icon for a heading at the given level
|
||||
function heading( level, type ) {
|
||||
return {
|
||||
run: setBlockType(type, {level}),
|
||||
dom: icon("h")
|
||||
}
|
||||
}
|
||||
|
||||
function blocks( schema ) {
|
||||
function blocks( schema, h_levels ) {
|
||||
let menu = {
|
||||
name : "blocks",
|
||||
h_levels
|
||||
};
|
||||
let type, i = {};
|
||||
|
||||
if (type = schema.nodes.heading) {
|
||||
let icon_id = 'h';
|
||||
h_levels.forEach( (level) => {
|
||||
i["setHeader"+level] = setHeader(type, level, icon_id);
|
||||
icon_id = icon_id + "h";
|
||||
});
|
||||
}
|
||||
if (type = schema.nodes.paragraph) {
|
||||
i.setP = {run: setBlockType(type), dom: icon("p")};
|
||||
}
|
||||
if (type = schema.nodes.heading) {
|
||||
i.setH1 = heading(1, type);
|
||||
i.seth2 = heading(2, type);
|
||||
i.setH3 = heading(3, type);
|
||||
}
|
||||
|
||||
menu.items = i;
|
||||
return menu
|
||||
return menu;
|
||||
}
|
||||
|
||||
function marks( schema ) {
|
||||
|
|
|
@ -27,8 +27,15 @@ export default class Godo {
|
|||
this.textarea.style.display = "none";
|
||||
let displayBlocksMenu = true;
|
||||
|
||||
this.default_options = {
|
||||
schema: "full",
|
||||
heading_levels: [3, 4]
|
||||
}
|
||||
this.options = Object.assign(this.default_options, options);
|
||||
this.options.heading_levels = this.options.heading_levels.slice(0, 3);
|
||||
|
||||
this.schema = (() => {
|
||||
switch(options.schema) {
|
||||
switch(this.options.schema) {
|
||||
case 'basic':
|
||||
displayBlocksMenu = false;
|
||||
return basic_schema;
|
||||
|
@ -47,12 +54,12 @@ export default class Godo {
|
|||
textarea.insertAdjacentElement('afterend', this.editor_wrapper);
|
||||
|
||||
this.marksMenu = menuPlugin(marks(this.schema));
|
||||
this.blocksMenu = menuPlugin(blocks(this.schema));
|
||||
this.blocksMenu = menuPlugin(blocks(this.schema, this.options.heading_levels));
|
||||
|
||||
let plugins_list = [
|
||||
history(),
|
||||
keymap(baseKeymap),
|
||||
keymap(buildKeymap(this.schema)),
|
||||
keymap(buildKeymap(this.schema, null, this.options)),
|
||||
this.marksMenu
|
||||
];
|
||||
|
||||
|
|
Loading…
Reference in New Issue