add heading with option for supported heading levels (#65398)

This commit is contained in:
Thomas Jund 2022-05-18 15:19:00 +02:00
parent 52dcdb9bb5
commit 5b542c4e37
6 changed files with 71 additions and 27 deletions

View File

@ -34,9 +34,9 @@ Use Godo
import in your webpage
* dist/css/godo.css
* dist/js.godo.js
* dist/js.godo.min.js
Transform a textarea in godo
Transform a textarea in godo
<script type="module">
import Godo from "./js/godo.js";
@ -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
-------

4
dist/css/godo.css vendored
View File

@ -98,3 +98,7 @@
font-weight: 600;
font-style: italic;
}
.menuicon-hh {
font-variant: small-caps;
font-weight: 900;
}

View File

@ -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) => {

View File

@ -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"
}
}

View File

@ -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 ) {

View File

@ -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
];