Generalize commandIconButton functionality of setting active state

This commit is contained in:
Henrik Giesel 2021-04-19 19:56:01 +02:00
parent fcb2ab28e3
commit e60e784152
3 changed files with 41 additions and 28 deletions

View File

@ -5,19 +5,23 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="typescript" context="module">
import { writable } from "svelte/store";
const commandMap = writable(new Map<string, boolean>());
type UpdateMap = Map<string, (event: Event) => boolean>;
type ActiveMap = Map<string, boolean>;
function updateButton(key: string): void {
commandMap.update(
(map: Map<string, boolean>): Map<string, boolean> =>
new Map([...map, [key, document.queryCommandState(key)]])
const updateMap = new Map() as UpdateMap;
const activeMap = writable(new Map() as ActiveMap);
function updateButton(key: string, event: MouseEvent): void {
activeMap.update(
(map: ActiveMap): ActiveMap =>
new Map([...map, [key, updateMap.get(key)(event)]])
);
}
function updateButtons(callback: (key: string) => boolean): void {
commandMap.update(
(map: Map<string, boolean>): Map<string, boolean> => {
const newMap = new Map<string, boolean>();
activeMap.update(
(map: ActiveMap): ActiveMap => {
const newMap = new Map() as ActiveMap;
for (const key of map.keys()) {
newMap.set(key, callback(key));
@ -28,8 +32,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
);
}
export function updateActiveButtons() {
updateButtons((key: string): boolean => document.queryCommandState(key));
export function updateActiveButtons(event: Event) {
updateButtons((key: string): boolean => updateMap.get(key)(event));
}
export function clearActiveButtons() {
@ -43,28 +47,34 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let id: string;
export let className = "";
export let tooltip: string;
export let icon: string;
export let command: string;
export let onClick = () => {
document.execCommand(command);
};
function onClickWrapped(event: MouseEvent): void {
onClick(event);
updateButton(command, event);
}
export let activatable = true;
export let disables = true;
export let dropdownToggle = false;
export let onUpdate = (_event: Event) => document.queryCommandState(command);
updateMap.set(command, onUpdate);
let active = false;
if (activatable) {
updateButton(command);
commandMap.subscribe((map: Map<string, boolean>): (() => void) => {
activeMap.subscribe((map: ActiveMap): (() => void) => {
active = Boolean(map.get(command));
return () => map.delete(command);
});
}
function onClick(): void {
document.execCommand(command);
updateButton(command);
}
export let disables = true;
export let dropdownToggle = false;
</script>
<SquareButton
@ -74,7 +84,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{active}
{disables}
{dropdownToggle}
{onClick}
onClick={onClickWrapped}
on:mount>
{@html icon}
</SquareButton>

View File

@ -113,7 +113,11 @@ export function getFormatBlockGroup(): DynamicSvelteComponent<typeof ButtonGroup
const paragraphButton = commandIconButton({
icon: paragraphIcon,
command: "formatBlock",
onClick: () => {
document.execCommand("formatBlock", false, "p");
},
tooltip: tr.editingUnorderedList(),
activatable: false,
});
const ulButton = commandIconButton({
@ -139,11 +143,6 @@ export function getFormatBlockGroup(): DynamicSvelteComponent<typeof ButtonGroup
return buttonGroup({
id: "blockFormatting",
buttons: [
paragraphButton,
ulButton,
olButton,
listFormatting,
],
buttons: [paragraphButton, ulButton, olButton, listFormatting],
});
}

View File

@ -51,7 +51,11 @@ export function onKey(evt: KeyboardEvent): void {
}
// prefer <br> instead of <div></div>
if (evt.code === "Enter" && !getListItem(currentField) && !getParagraph(currentField)) {
if (
evt.code === "Enter" &&
!getListItem(currentField) &&
!getParagraph(currentField)
) {
evt.preventDefault();
document.execCommand("insertLineBreak");
}