mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
Disable Bold button in Codable
This commit is contained in:
parent
817dee1a1b
commit
eeb954535f
8 changed files with 81 additions and 32 deletions
|
@ -3,9 +3,8 @@ Copyright: Ankitects Pty Ltd and contributors
|
|||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="typescript">
|
||||
import type { Readable } from "svelte/store";
|
||||
import { getContext, onMount, createEventDispatcher } from "svelte";
|
||||
import { disabledKey, nightModeKey, dropdownKey } from "./contextKeys";
|
||||
import { nightModeKey, dropdownKey } from "./contextKeys";
|
||||
import type { DropdownProps } from "./dropdown";
|
||||
|
||||
export let id: string | undefined = undefined;
|
||||
|
@ -14,7 +13,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
export let tooltip: string | undefined = undefined;
|
||||
export let active = false;
|
||||
export let disables = true;
|
||||
export let disabled = false;
|
||||
export const disables = false; /* unused */
|
||||
export let tabbable = false;
|
||||
|
||||
export let iconSize: number = 75;
|
||||
|
@ -22,9 +22,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
let buttonRef: HTMLButtonElement;
|
||||
|
||||
const disabled = getContext<Readable<boolean>>(disabledKey);
|
||||
$: _disabled = disables && $disabled;
|
||||
|
||||
const nightMode = getContext<boolean>(nightModeKey);
|
||||
const dropdownProps = getContext<DropdownProps>(dropdownKey) ?? { dropdown: false };
|
||||
|
||||
|
@ -43,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
style={`--icon-size: ${iconSize}%`}
|
||||
title={tooltip}
|
||||
{...dropdownProps}
|
||||
disabled={_disabled}
|
||||
{disabled}
|
||||
tabindex={tabbable ? 0 : -1}
|
||||
on:click
|
||||
on:mousedown|preventDefault
|
||||
|
|
16
ts/components/WithContext.svelte
Normal file
16
ts/components/WithContext.svelte
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!--
|
||||
Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="typescript">
|
||||
import type { Readable } from "svelte/store";
|
||||
import { getContext } from "svelte";
|
||||
|
||||
type T = unknown;
|
||||
|
||||
export let key: Symbol | string;
|
||||
|
||||
const store = getContext<Readable<T>>(key);
|
||||
</script>
|
||||
|
||||
<slot context={$store} />
|
|
@ -5,14 +5,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<script lang="typescript" context="module">
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
type UpdaterMap = Map<string, (event: Event) => boolean>;
|
||||
type StateMap = Map<string, boolean>;
|
||||
type KeyType = Symbol | string;
|
||||
type UpdaterMap = Map<KeyType, (event: Event) => boolean>;
|
||||
type StateMap = Map<KeyType, boolean>;
|
||||
|
||||
const updaterMap = new Map() as UpdaterMap;
|
||||
const stateMap = new Map() as StateMap;
|
||||
const stateStore = writable(stateMap);
|
||||
|
||||
function updateAllStateWithCallback(callback: (key: string) => boolean): void {
|
||||
function updateAllStateWithCallback(callback: (key: KeyType) => boolean): void {
|
||||
stateStore.update((map: StateMap): StateMap => {
|
||||
const newMap = new Map() as StateMap;
|
||||
|
||||
|
@ -25,7 +26,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
|
||||
export function updateAllState(event: Event): void {
|
||||
updateAllStateWithCallback((key: string): boolean =>
|
||||
updateAllStateWithCallback((key: KeyType): boolean =>
|
||||
updaterMap.get(key)!(event)
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
updateAllStateWithCallback((): boolean => state);
|
||||
}
|
||||
|
||||
function updateStateByKey(key: string, event: Event): void {
|
||||
function updateStateByKey(key: KeyType, event: Event): void {
|
||||
stateStore.update((map: StateMap): StateMap => {
|
||||
map.set(key, updaterMap.get(key)!(event));
|
||||
return map;
|
||||
|
@ -43,7 +44,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</script>
|
||||
|
||||
<script lang="typescript">
|
||||
export let key: string;
|
||||
export let key: KeyType;
|
||||
export let update: (event: Event) => boolean;
|
||||
|
||||
let state: boolean = false;
|
||||
|
|
|
@ -8,8 +8,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import ButtonGroup from "components/ButtonGroup.svelte";
|
||||
import ButtonGroupItem from "components/ButtonGroupItem.svelte";
|
||||
import IconButton from "components/IconButton.svelte";
|
||||
import WithState from "components/WithState.svelte";
|
||||
import WithShortcut from "components/WithShortcut.svelte";
|
||||
import WithContext from "components/WithContext.svelte";
|
||||
import WithState from "components/WithState.svelte";
|
||||
|
||||
import {
|
||||
boldIcon,
|
||||
|
@ -20,6 +21,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
eraserIcon,
|
||||
} from "./icons";
|
||||
import { appendInParentheses } from "./helpers";
|
||||
import { disabledKey } from "components/contextKeys";
|
||||
import { inCodableKey } from "./contextKeys";
|
||||
|
||||
export let api = {};
|
||||
</script>
|
||||
|
@ -27,6 +30,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<ButtonGroup {api}>
|
||||
<ButtonGroupItem>
|
||||
<WithShortcut shortcut={"Control+B"} let:createShortcut let:shortcutLabel>
|
||||
<WithContext key={disabledKey} let:context={disabled}>
|
||||
<WithContext key={inCodableKey} let:context={inCodable}>
|
||||
<WithState
|
||||
key="bold"
|
||||
update={() => document.queryCommandState("bold")}
|
||||
|
@ -34,8 +39,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
let:updateState
|
||||
>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(tr.editingBoldText(), shortcutLabel)}
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingBoldText(),
|
||||
shortcutLabel
|
||||
)}
|
||||
{active}
|
||||
disabled={disabled || inCodable}
|
||||
on:click={(event) => {
|
||||
document.execCommand("bold");
|
||||
updateState(event);
|
||||
|
@ -45,6 +54,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
{@html boldIcon}
|
||||
</IconButton>
|
||||
</WithState>
|
||||
</WithContext>
|
||||
</WithContext>
|
||||
</WithShortcut>
|
||||
</ButtonGroupItem>
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import "codemirror/addon/fold/xml-fold";
|
|||
import "codemirror/addon/edit/matchtags.js";
|
||||
import "codemirror/addon/edit/closetag.js";
|
||||
|
||||
import { setCodableButtons } from "./toolbar";
|
||||
|
||||
const codeMirrorOptions = {
|
||||
mode: "htmlmixed",
|
||||
theme: "monokai",
|
||||
|
@ -64,6 +66,7 @@ export class Codable extends HTMLTextAreaElement {
|
|||
|
||||
focus(): void {
|
||||
this.codeMirror.focus();
|
||||
setCodableButtons();
|
||||
}
|
||||
|
||||
caretToEnd(): void {
|
||||
|
|
4
ts/editor/contextKeys.ts
Normal file
4
ts/editor/contextKeys.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
export const inCodableKey = Symbol("inCodable");
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import { bridgeCommand } from "./lib";
|
||||
import { nodeIsInline, caretToEnd, getBlockElement } from "./helpers";
|
||||
import { setEditableButtons } from "./toolbar";
|
||||
|
||||
function containsInlineContent(field: Element): boolean {
|
||||
if (field.childNodes.length === 0) {
|
||||
|
@ -38,6 +39,11 @@ export class Editable extends HTMLElement {
|
|||
this.setAttribute("contenteditable", "");
|
||||
}
|
||||
|
||||
focus() {
|
||||
super.focus();
|
||||
setEditableButtons();
|
||||
}
|
||||
|
||||
caretToEnd() {
|
||||
caretToEnd(this);
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
*/
|
||||
|
||||
import { disabledKey, nightModeKey } from "components/contextKeys";
|
||||
import { inCodableKey } from "./contextKeys";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
import EditorToolbar from "./EditorToolbar.svelte";
|
||||
import "./bootstrap.css";
|
||||
|
||||
const disabled = writable(false);
|
||||
const inCodable = writable(false);
|
||||
|
||||
export function initToolbar(i18n: Promise<void>): Promise<EditorToolbar> {
|
||||
let toolbarResolve: (value: EditorToolbar) => void;
|
||||
|
@ -27,6 +29,7 @@ export function initToolbar(i18n: Promise<void>): Promise<EditorToolbar> {
|
|||
|
||||
const context = new Map();
|
||||
context.set(disabledKey, disabled);
|
||||
context.set(inCodableKey, inCodable);
|
||||
context.set(
|
||||
nightModeKey,
|
||||
document.documentElement.classList.contains("night-mode")
|
||||
|
@ -47,6 +50,14 @@ export function disableButtons(): void {
|
|||
disabled.set(true);
|
||||
}
|
||||
|
||||
export function setCodableButtons(): void {
|
||||
inCodable.set(true);
|
||||
}
|
||||
|
||||
export function setEditableButtons(): void {
|
||||
inCodable.set(false);
|
||||
}
|
||||
|
||||
export {
|
||||
updateActiveButtons,
|
||||
clearActiveButtons,
|
||||
|
|
Loading…
Reference in a new issue