Add option to shrink editor images by default (#2071)

+ Don't persist shrinking toggle

Closes #1894
This commit is contained in:
Damien Elmes 2022-09-26 09:47:50 +10:00 committed by GitHub
parent c1176a2e6c
commit 4089e76800
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 142 additions and 14 deletions

View file

@ -61,6 +61,7 @@ editing-underline-text = Underline text
editing-unordered-list = Unordered list
editing-warning-cloze-deletions-will-not-work = Warning, cloze deletions will not work until you switch the type at the top to Cloze.
editing-toggle-mathjax-rendering = Toggle MathJax Rendering
editing-shrink-images = Shrink Images
## You don't need to translate these strings, as they will be replaced with different ones soon.

View file

@ -534,6 +534,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
setColorButtons({});
setTags({});
setMathjaxEnabled({});
setShrinkImages({});
""".format(
json.dumps(data),
json.dumps(collapsed),
@ -545,6 +546,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
json.dumps([text_color, highlight_color]),
json.dumps(self.note.tags),
json.dumps(self.mw.col.get_config("renderMathjax", True)),
json.dumps(self.mw.col.get_config("shrinkEditorImages", True)),
)
if self.addMode:
@ -1159,6 +1161,12 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
self.setupWeb()
self.loadNoteKeepingFocus()
def toggleShrinkImages(self) -> None:
self.mw.col.set_config(
"shrinkEditorImages",
not self.mw.col.get_config("shrinkEditorImages", True),
)
# Links from HTML
######################################################################
@ -1186,6 +1194,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
mathjaxBlock=Editor.insertMathjaxBlock,
mathjaxChemistry=Editor.insertMathjaxChemistry,
toggleMathjax=Editor.toggleMathjax,
toggleShrinkImages=Editor.toggleShrinkImages,
)

View file

@ -14,6 +14,7 @@ module.exports = {
"warn",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
"no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
"import/newline-after-import": "warn",
"import/no-useless-path-segments": "warn",
"simple-import-sort/imports": "warn",

View file

@ -3,9 +3,17 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<style lang="scss">
:global([data-editor-shrink]:not([data-editor-shrink="false"])) {
:global(img) {
max-width: var(--editor-default-max-width);
max-height: var(--editor-default-max-height);
&:is([data-editor-shrink="true"]) {
max-width: var(--editor-shrink-max-width);
max-height: var(--editor-shrink-max-height);
width: auto;
}
&:is([data-editor-shrink="false"]) {
max-width: initial;
max-height: initial;
}
}
</style>

View file

@ -58,6 +58,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import FrameElement from "./FrameElement.svelte";
import { alertIcon } from "./icons";
import ImageHandle from "./image-overlay";
import { shrinkImagesByDefault } from "./image-overlay/ImageOverlay.svelte";
import MathjaxHandle from "./mathjax-overlay";
import MathjaxElement from "./MathjaxElement.svelte";
import Notification from "./Notification.svelte";
@ -210,9 +211,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const fieldSave = new ChangeTimer();
function transformContentBeforeSave(content: string): string {
return content.replace(/ data-editor-shrink="(true|false)"/g, "");
}
function updateField(index: number, content: string): void {
fieldSave.schedule(
() => bridgeCommand(`key:${index}:${getNoteId()}:${content}`),
() =>
bridgeCommand(
`key:${index}:${getNoteId()}:${transformContentBeforeSave(
content,
)}`,
),
600,
);
}
@ -250,6 +260,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const toolbar: Partial<EditorToolbarAPI> = {};
function setShrinkImages(shrinkByDefault: boolean) {
$shrinkImagesByDefault = shrinkByDefault;
}
import { mathjaxConfig } from "../editable/mathjax-element";
import { wrapInternal } from "../lib/wrap";
import { refocusInput } from "./helpers";
@ -283,6 +297,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
wrap,
setMathjaxEnabled,
setInsertSymbolsEnabled,
setShrinkImages,
...oldEditorAdapter,
});
@ -350,7 +365,11 @@ the AddCards dialog) should be implemented in the user of this component.
}}
on:focusout={() => {
$focusedField = null;
bridgeCommand(`blur:${index}:${getNoteId()}:${get(content)}`);
bridgeCommand(
`blur:${index}:${getNoteId()}:${transformContentBeforeSave(
get(content),
)}`,
);
}}
on:mouseenter={() => {
$hoveredField = fields[index];

View file

@ -56,6 +56,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import BlockButtons from "./BlockButtons.svelte";
import InlineButtons from "./InlineButtons.svelte";
import NotetypeButtons from "./NotetypeButtons.svelte";
import OptionsButton from "./OptionsButton.svelte";
import RichTextClozeButtons from "./RichTextClozeButtons.svelte";
import TemplateButtons from "./TemplateButtons.svelte";
@ -108,6 +109,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Item id="cloze">
<RichTextClozeButtons />
</Item>
<Item id="options">
<OptionsButton />
</Item>
</DynamicallySlottable>
</ButtonToolbar>
</div>

View file

@ -0,0 +1,49 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import CheckBox from "../../components/CheckBox.svelte";
import DropdownItem from "../../components/DropdownItem.svelte";
import IconButton from "../../components/IconButton.svelte";
import Popover from "../../components/Popover.svelte";
import WithFloating from "../../components/WithFloating.svelte";
import { bridgeCommand } from "../../lib/bridgecommand";
import * as tr from "../../lib/ftl";
import { shrinkImagesByDefault } from "../image-overlay/ImageOverlay.svelte";
import { cogIcon } from "./icons";
let showFloating = false;
function toggleShrinkImages(_evt: MouseEvent): void {
$shrinkImagesByDefault = !$shrinkImagesByDefault;
bridgeCommand("toggleShrinkImages");
showFloating = false;
}
</script>
<WithFloating
show={showFloating}
placement="bottom"
inline
on:close={() => (showFloating = false)}
let:asReference
>
<span use:asReference>
<IconButton
tooltip={tr.actionsOptions()}
--border-left-radius="5px"
--border-right-radius="5px"
on:click={() => (showFloating = !showFloating)}
>
{@html cogIcon}
</IconButton>
</span>
<Popover slot="floating" --popover-padding-inline="0">
<DropdownItem on:click={toggleShrinkImages}>
<CheckBox value={$shrinkImagesByDefault} />
<span class="d-flex-inline ps-3">{tr.editingShrinkImages()}</span>
</DropdownItem>
</Popover>
</WithFloating>

View file

@ -3,6 +3,7 @@
/// <reference types="../../lib/image-import" />
export { default as cogIcon } from "@mdi/svg/svg/cog.svg";
export { default as colorHelperIcon } from "@mdi/svg/svg/color-helper.svg";
export { default as highlightColorIcon } from "@mdi/svg/svg/format-color-highlight.svg";
export { default as textColorIcon } from "@mdi/svg/svg/format-color-text.svg";

View file

@ -2,6 +2,12 @@
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts" context="module">
import { writable } from "svelte/store";
export const shrinkImagesByDefault = writable(true);
</script>
<script lang="ts">
import { onMount, tick } from "svelte";
@ -27,18 +33,47 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let activeImage: HTMLImageElement | null = null;
/**
* For element dataset attributes which work like the contenteditable attribute
* Returns the value if set, otherwise null.
*/
function isDatasetAttributeFlagSet(
function getBooleanDatasetAttribute(
element: HTMLElement | SVGElement,
attribute: string,
): boolean {
return attribute in element.dataset && element.dataset[attribute] !== "false";
): boolean | null {
return attribute in element.dataset
? element.dataset[attribute] !== "false"
: null;
}
$: isSizeConstrained = activeImage
? isDatasetAttributeFlagSet(activeImage, "editorShrink")
: false;
let isSizeConstrained = false;
$: {
if (activeImage) {
isSizeConstrained =
getBooleanDatasetAttribute(activeImage, "editorShrink") ??
$shrinkImagesByDefault;
}
}
$: {
if ($shrinkImagesByDefault) {
document.documentElement.style.setProperty(
"--editor-default-max-width",
`${maxWidth}px`,
);
document.documentElement.style.setProperty(
"--editor-default-max-height",
`${maxHeight}px`,
);
} else {
document.documentElement.style.setProperty(
"--editor-default-max-width",
"inherit",
);
document.documentElement.style.setProperty(
"--editor-default-max-height",
"inherit",
);
}
}
async function resetHandle(): Promise<void> {
activeImage = null;
@ -181,7 +216,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function toggleActualSize(): void {
if (isSizeConstrained) {
delete activeImage!.dataset.editorShrink;
activeImage!.dataset.editorShrink = "false";
} else {
activeImage!.dataset.editorShrink = "true";
}