Generalize commandIconButton functionality of setting active state
This commit is contained in:
parent
fcb2ab28e3
commit
e60e784152
@ -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>
|
||||
|
@ -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],
|
||||
});
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user