87e2cf7976
15 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Henrik Giesel
|
6d0a242a1b
|
Fix overwrite surround (#2247)
* Revert "Revert to setFormat() to fix color setting"
This reverts commit
|
||
Damien Elmes
|
b2049209ff |
Re-enable formatting for .ts files
There are some style differences compared to prettier, and not all are necessarily an improvement, but it's much faster now. |
||
Damien Elmes
|
5e0a761b87
|
Move away from Bazel (#2202)
(for upgrading users, please see the notes at the bottom) Bazel brought a lot of nice things to the table, such as rebuilds based on content changes instead of modification times, caching of build products, detection of incorrect build rules via a sandbox, and so on. Rewriting the build in Bazel was also an opportunity to improve on the Makefile-based build we had prior, which was pretty poor: most dependencies were external or not pinned, and the build graph was poorly defined and mostly serialized. It was not uncommon for fresh checkouts to fail due to floating dependencies, or for things to break when trying to switch to an older commit. For day-to-day development, I think Bazel served us reasonably well - we could generally switch between branches while being confident that builds would be correct and reasonably fast, and not require full rebuilds (except on Windows, where the lack of a sandbox and the TS rules would cause build breakages when TS files were renamed/removed). Bazel achieves that reliability by defining rules for each programming language that define how source files should be turned into outputs. For the rules to work with Bazel's sandboxing approach, they often have to reimplement or partially bypass the standard tools that each programming language provides. The Rust rules call Rust's compiler directly for example, instead of using Cargo, and the Python rules extract each PyPi package into a separate folder that gets added to sys.path. These separate language rules allow proper declaration of inputs and outputs, and offer some advantages such as caching of build products and fine-grained dependency installation. But they also bring some downsides: - The rules don't always support use-cases/platforms that the standard language tools do, meaning they need to be patched to be used. I've had to contribute a number of patches to the Rust, Python and JS rules to unblock various issues. - The dependencies we use with each language sometimes make assumptions that do not hold in Bazel, meaning they either need to be pinned or patched, or the language rules need to be adjusted to accommodate them. I was hopeful that after the initial setup work, things would be relatively smooth-sailing. Unfortunately, that has not proved to be the case. Things frequently broke when dependencies or the language rules were updated, and I began to get frustrated at the amount of Anki development time I was instead spending on build system upkeep. It's now about 2 years since switching to Bazel, and I think it's time to cut losses, and switch to something else that's a better fit. The new build system is based on a small build tool called Ninja, and some custom Rust code in build/. This means that to build Anki, Bazel is no longer required, but Ninja and Rust need to be installed on your system. Python and Node toolchains are automatically downloaded like in Bazel. This new build system should result in faster builds in some cases: - Because we're using cargo to build now, Rust builds are able to take advantage of pipelining and incremental debug builds, which we didn't have with Bazel. It's also easier to override the default linker on Linux/macOS, which can further improve speeds. - External Rust crates are now built with opt=1, which improves performance of debug builds. - Esbuild is now used to transpile TypeScript, instead of invoking the TypeScript compiler. This results in faster builds, by deferring typechecking to test/check time, and by allowing more work to happen in parallel. As an example of the differences, when testing with the mold linker on Linux, adding a new message to tags.proto (which triggers a recompile of the bulk of the Rust and TypeScript code) results in a compile that goes from about 22s on Bazel to about 7s in the new system. With the standard linker, it's about 9s. Some other changes of note: - Our Rust workspace now uses cargo-hakari to ensure all packages agree on available features, preventing unnecessary rebuilds. - pylib/anki is now a PEP420 implicit namespace, avoiding the need to merge source files and generated files into a single folder for running. By telling VSCode about the extra search path, code completion now works with generated files without needing to symlink them into the source folder. - qt/aqt can't use PEP420 as it's difficult to get rid of aqt/__init__.py. Instead, the generated files are now placed in a separate _aqt package that's added to the path. - ts/lib is now exposed as @tslib, so the source code and generated code can be provided under the same namespace without a merging step. - MyPy and PyLint are now invoked once for the entire codebase. - dprint will be used to format TypeScript/json files in the future instead of the slower prettier (currently turned off to avoid causing conflicts). It can automatically defer to prettier when formatting Svelte files. - svelte-check is now used for typechecking our Svelte code, which revealed a few typing issues that went undetected with the old system. - The Jest unit tests now work on Windows as well. If you're upgrading from Bazel, updated usage instructions are in docs/development.md and docs/build.md. A summary of the changes: - please remove node_modules and .bazel - install rustup (https://rustup.rs/) - install rsync if not already installed (on windows, use pacman - see docs/windows.md) - install Ninja (unzip from https://github.com/ninja-build/ninja/releases/tag/v1.11.1 and place on your path, or from your distro/homebrew if it's 1.10+) - update .vscode/settings.json from .vscode.dist |
||
Stefan Kangas
|
5551a37f03
|
Fix typos (#2210) | ||
Henrik Giesel
|
9ca13ca3bc
|
Refactor how toolbar buttons get to surround within editor fields (#1931)
* Export surrounder directly from RichTextInput * Change wording in editor/surround * Remove empty line * Change wording * Fix interfaces * Add field description directly in NoteEditor * Strip description logic from ContentEditable * Make RichTextInput position: relative * Make attachToShadow an async function * Apply field styling to field description * Show FieldDescription only if content empty * Remove descriptionStore and descriptionKey * Revert "Make attachToShadow an async function" This reverts commit b62705eadf7335c7ee0c6c8797047e1f1ccdbf44. SvelteActionReturnType does not accept Promise<void> * Fix mess after merge commit * Require registering surround formats |
||
RumovZ
|
42cbe42f06
|
Plaintext import/export (#1850)
* Add crate csv * Add start of csv importing on backend * Add Menomosyne serializer * Add csv and json importing on backend * Add plaintext importing on frontend * Add csv metadata extraction on backend * Add csv importing with GUI * Fix missing dfa file in build Added compile_data_attr, then re-ran cargo/update.py. * Don't use doubly buffered reader in csv * Escape HTML entities if CSV is not HTML Also use name 'is_html' consistently. * Use decimal number as foreign ease (like '2.5') * ForeignCard.ivl → ForeignCard.interval * Only allow fixed set of CSV delimiters * Map timestamp of ForeignCard to native due time * Don't trim CSV records * Document use of empty strings for defaults * Avoid creating CardGenContexts for every note This requires CardGenContext to be generic, so it works both with an owned and borrowed notetype. * Show all accepted file types in import file picker * Add import_json_file() * factor → ease_factor * delimter_from_value → delimiter_from_value * Map columns to fields, not the other way around * Fallback to current config for csv metadata * Add start of new import csv screen * Temporary fix for compilation issue on Linux/Mac * Disable jest bazel action for import-csv Jest fails with an error code if no tests are available, but this would not be noticable on Windows as Jest is not run there. * Fix field mapping issue * Revert "Temporary fix for compilation issue on Linux/Mac" This reverts commit 21f8a261408cdae49ec031aa21a1b659c4f66d82. * Add HtmlSwitch and move Switch to components * Fix spacing and make selectors consistent * Fix shortcut tooltip * Place import button at the top with path * Fix meta column indices * Remove NotetypeForString * Fix queue and type of foreign cards * Support different dupe resolution strategies * Allow dupe resolution selection when importing CSV * Test import of unnormalized text Close #1863. * Fix logging of foreign notes * Implement CSV exports * Use db_scalar() in notes_table_len() * Rework CSV metadata - Notetypes and decks are either defined by a global id or by a column. - If a notetype id is provided, its field map must also be specified. - If a notetype column is provided, fields are now mapped by index instead of name at import time. So the first non-meta column is used for the first field of every note, regardless of notetype. This makes importing easier and should improve compatiblity with files without a notetype column. - Ensure first field can be mapped to a column. - Meta columns must be defined as `#[meta name]:[column index]` instead of in the `#columns` tag. - Column labels contain the raw names defined by the file and must be prettified by the frontend. * Adjust frontend to new backend column mapping * Add force flags for is_html and delimiter * Detect if CSV is HTML by field content * Update dupe resolution labels * Simplify selectors * Fix coalescence of oneofs in TS * Disable meta columns from selection Plus a lot of refactoring. * Make import button stick to the bottom * Write delimiter and html flag into csv * Refetch field map after notetype change * Fix log labels for csv import * Log notes whose deck/notetype was missing * Fix hiding of empty log queues * Implement adding tags to all notes of a csv * Fix dupe resolution not being set in log * Implement adding tags to updated notes of a csv * Check first note field is not empty * Temporary fix for build on Linux/Mac * Fix inverted html check (dae) * Remove unused ftl string * Delimiter → Separator * Remove commented-out line * Don't accept .json files * Tweak tag ftl strings * Remove redundant blur call * Strip sound and add spaces in csv export * Export HTML by default * Fix unset deck in Mnemosyne import Also accept both numbers and strings for notetypes and decks in JSON. * Make DupeResolution::Update the default * Fix missing dot in extension * Make column indices 1-based * Remove StickContainer from TagEditor Fixes line breaking, border and z index on ImportCsvPage. * Assign different key combos to tag editors * Log all updated duplicates Add a log field for the true number of found notes. * Show identical notes as skipped * Split tag-editor into separate ts module (dae) * Add progress for CSV export * Add progress for text import * Tidy-ups after tag-editor split (dae) - import-csv no longer depends on editor - remove some commented lines |
||
Henrik Giesel
|
8b84368e3a
|
Move all buttons to our custom inline surrounding (#1682)
* Clarify some comments * Don't destructure insertion trigger * Make superscript and subscript use domlib/surround * Create new {Text,Highlight}ColorButton * Use domlib/surround for textcolor - However there's still a crucial bug, when you're breaking existing colored span when unsurrounding, their color is not restored * Add underline format to removeFormats * Simplify type of ElementMatcher and ElementClearer for end users * Add some comments for normalize-insertion-ranges * Split normalize-insertion-ranges into remove-adjacent and remove-within * Factor out find-remove from unsurround.ts * Rename merge-mach, simplify remove-within * Clarify some comments * Refactor first reduce * Refactor reduceRight * Flatten functions in merge-ranges * Move some functionality to merge-ranges and do not export * Refactor merge-ranges * Remove createInitialMergeMatch * Finish refactoring of merge-ranges * Refactor merge-ranges to minimal-ranges and add some unit testing * Move more logic into text-node * Remove most most of the logic from remove-adjacent - remove-adjacent is still part of the "merging" logic, as it increases the scope of the child node ranges * Add some tests for edge cases * Merge remove-adjacent logic into minimal-ranges * Refactor unnecessary list destructuring * Add some TODOs * Put removing nodes and adding new nodes into sequence * Refactor MatchResult to MatchType and return clear from matcher * Inline surround/helpers * Shorten name of param * Add another edge case test * Add an example where commonAncestorContainer != normalization level * Fix bug in find-adjacent when find more than one nested nodes * Allow comments for Along type * Simplify find-adjacent by removing intermediate and/or curried functions * Remove extend-adjacent * Add more tests when find-adjacent finds by descension * Fix find-adjacent descending into block-level elements * Add clarifying comment to refusing to descend into block-level elements * Move shifting logic into find-adjacent * Rename file matcher to match-type * Give a first implemention of TreeVertex * Remove MatchType.ALONG - findAdjacent now directly modifies the range * Rename MatchType.MATCH into MatchType.REMOVE * Implement a version of find-within that utilizies match-tree * Turn child node range into a class * Fix bug in new find-adjacent function * Make all find-adjacent tests test for ranges * Surrounding within farthestMatchingAncestor when available * Fix an issue with negligable elements - also rename "along" elements to "negligable" * Add two TODOs to SurroundFormat interface * Have a messy first implementation of the new tree-node algorithm * Maintain whether formatting nodes are covered or within user selection * Move covered and insideRange into TreeNode superclass * Reimplement findAdjacent logic * Add extension logic * Add an evaluate method to nodes * Introduce BlockNode * Add a first evaluate implementation * Add left shift and inner shift logic * Implement SurroundFormatUser * Allow pass in formatter, ascender and merger from outside * Fix insideRange and covered switch-up * Fix MatchNode.prototype.isAscendable * Fix another switch-up of covered and insideRange... * Remove a lot of old code * Have surround functions only return the range - I still cannot think of a good reason why we should return addedNodes and removedNodes, except for testing. * Create formatting-tree directory * Create build-tree directory + Move find-above up to /domlib * Remove range-anchors * Move unsurround logic into no-splitting * Fix extend-merge * Fix inner shift being eroneusly returned as left shift * Fix oversight in SplitRange * Redefine how ranges are recreated * Rename covered to insideMatch and put as fourth parameter instead of third * Keep track of match holes and match leaves * Rename ChildNodeRange to FlatRange * Change signature of matcher * Fix bug in extend-merge * Improve Match class * Utilize cache in TextColorButton * Implement getBaseSurrounder for TextColorButton * Add matchAncestors field to FormattingNode * Introduce matchAncestors and getCache * Do clearing during parsing already - This way, you know whether elements will be removed before getting to Formatting nodes * Make HighlightColorButton use our surround mechanism * Fix a bug with calling .removeAttribute and .hasAttribute * Add side button to RemoveFormat button * Add disabled to remove format side button * Expose remove formats on RemoveFormat button * Reinvent editor/surround as Surrounder class * Fix split-text when working with insert trigger * Try counteracting the contenteditable's auto surrounding * Remove matching elements before normalizing * Rewrite match-type * Move setting match leaves into build * Change editing strings - So that color strings match bold/italic strings better * Fix border radius of List options menu * Implement extensions functionality * Remove some unnecessary code * Fix split range endOffset * Type MatchType * Reformat MatchType + add docs * Fix domlib/surround/apply * Satisfy last tests * Register Surrounder as package * Clarify some comments * Correctly implement reformat * Reformat with inactive eraser formats * Clear empty spans with RemoveFormatButton * Fix Super/Subscript button * Use ftl string for hardcoded tooltip * Adjust wording |
||
Henrik Giesel
|
30bbbaf00b
|
Use eslint for sorting our imports (#1637)
* Make eslint sort our imports * fix missing deps in eslint rule (dae) Caught on Linux due to the stricter sandboxing * Remove exports-last eslint rule (for now?) * Adjust browserslist settings - We use ResizeObserver which is not supported in browsers like KaiOS, Baidu or Android UC * Raise minimum iOS version 13.4 - It's the first version that supports ResizeObserver * Apply new eslint rules to sort imports |
||
Henrik Giesel
|
a981e56008
|
Improved add-on extension API (#1626)
* Add componentHook functionality * Register package NoteEditor * Rename OldEditorAdapter to NoteEditor * Expose instances in component-hook as well * Rename NoteTypeButtons to NotetypeButtons * Move PreviewButton initialization to BrowserEditor.svelte * Remove focusInRichText - Same thing can be done by inspecting activeInput * Satisfy formatter * Fix remaining rebase issues * Add .bazel to .prettierignore * Rename currentField and activeInput to focused{Field,Input} * Move identifier to lib and registration to sveltelib * Fix Dynamic component insertion * Simplify editingInputIsRichText * Give extra warning in svelte/svelte.ts - This was caused by doing a rename of a files, that only differed in case: NoteTypeButtons.svelte to NotetypeButtons.svelte - It was quite tough to figure out, and this console.log might make it easier if it ever happens again * Change signature of contextProperty * Add ts/typings for add-on definition files * Add Anki types in typings/common/index.d.ts * Export without .svelte suffix It conflicts with how Svelte types its packages * Fix left over .svelte import from editor.py * Rename NoteTypeButtons to unrelated to ensure case-only rename * Rename back to NotetypeButtons.svelte * Remove unused component-hook.ts, Fix typing in lifecycle-hooks * Merge runtime-require and register-package into one file + Give some preliminary types to require * Rename uiDidLoad to loaded * Fix eslint / svelte-check * Rename context imports to noteEditorContext * Fix import name mismatch - I wonder why these issues are not caught by svelte-check? * Rename two missed usages of uiDidLoad * Fix ButtonDropdown from having wrong border-radius * Uniformly rename libraries to packages - I don't have a strong opinion on whether to name them libraries or packages, I just think we should have a uniform name. - JS/TS only uses the terms "module" and "namespace", however `package` is a reserved keyword for future use, whereas `library` is not. * Refactor registration.ts into dynamic-slotting - This is part of an effort to refactor the dynamic slotting (extending buttons) functionality out of components like ButtonGroup. * Remove dynamically-slottable logic from ButtonToolbar * Use DynamicallySlottable in editor-toolbar * Fix no border radius on indentation button dropdown * Fix AddonButtons * Remove Item/ButtonGroupItem in deck-options, where it's not necessary * Remove unnecessary uses of Item and ButtonGroupItem * Fix remaining tests * Fix relative imports * Revert change return value of remapBinToSrcDir to ./bazel/out... * Remove typings directory * Adjust comments for dynamic-slottings |
||
Henrik Giesel
|
489eadb352
|
Fix IME input after tab (#1584)
* Avoid initial call of mirror-dom * Disable updateFocus from OldEditorAdapter * fixes IME input duplication bug * Fix saving of latestLocation for ContentEditable * Fix IME after calling placeCaretAfterContent * Export other libraries from domlib/index.ts * Remove dead code + Uncomment code which was mistakenly left commmented |
||
Henrik Giesel
|
739e286b0b
|
Fix some Mathjax issues (#1547)
* Move move-nodes logic into domlib Refactor input-manager Refactor out FocusTrap from EditingArea Remove unnecessary selecting of node from surround Add onInput interface to input-manager Create MathjaxElement.svelte - This should contain all the setup necessary for displaying <anki-mathjax> elements in the rich text input - Does not contain setup necessary for Mathjax Overlay Deal with backwards deletion, when caret inside anki-mathjax Set mathjax elements contenteditable=false Do not undecorate mathjaxx element on disconnect - Fixes issues, where Mathjax might undecorate when it is moved into a different div Add framed element custom element Introduce iterateActions to allow global hooks for RichTextInput Remove some old code Deal with deletion of frame handles Make Anki frame and frame handles restore each other Make FrameElement restore its structure upon modification Frame and strip off framing from MathjaxElement automatically Move FrameHandle to separate FrameStart/FrameEnd Refactor FrameHandle Set data-frames on FrameElement Fix logic error connected to FrameElement Communicate frameHandle move{in,out} to anki-mathjax Clear selection when blurring ContentEditable Make sure frame is destroyed when undecorating Mathjax Use Hairline space instead of zeroWidth - it has better behavior in the contenteditable when placing the caret via clicking Allow detection of block elements with `block` attribute - This way, anki-mathjax block="true" will make field a field be recognized to have block content Make block frame element operater without handles - Clicking on the left/right side of a block mathjax will insert a br element to that side When deleting, remove mathajax-element not just image Update MathjaxButtons to correctly show block state SelectAll when moving into inline anki mathjax Remove CodeMirror autofocus functionality Move it to Mathjaxeditor directly Fix getRangeAt throwing error Update older code to use cross-browser Fix issue with FrameHandles not being properyly removed Satisfy formatting Use === instead of node.isSameNode() Fix issue of focusTrap not initialized * Fix after rebasing * Fix focus not being moved to first field * Add documentation for input-manager and iterate-actions * Export logic of ContentEditable to content-editable * Fix issue with inserting newline right next to inline Mathjax * Fix reframing issue of Mathjax Svelte component * Allow for deletion of Inline Mathjax again * Rename iterate-actions to action-list * Add copyright header * Split off frame-handle from frame-element * Add some comments for framing process * Add mising return types |
||
Henrik Giesel
|
97b28398ea
|
Fix some issues with new surround buttons (#1505)
* Add a store to indicate whether input trigger is active Button state is then indicated by: caretIsInBold XOR boldTriggerActive * Fix surrounding where normalization is tripped up by empty text nodes * Add failing test for unsurrounding * Fix failing test * prohibitOverlapse does not need to be active, if aboveEnd is null * Reinsert Italic and Underline button * Refactor find-adjacent to use sum types * Simplify return value of normalizeAdjacent |
||
Henrik Giesel
|
2778b9220c
|
Mathjax editor improvements (#1502)
* Remove unnecessary stopPropagation of mathjax-overlay events * Use CodeMirror component for MathjaxHandle * Refactor ResizeObserver code in MathjaxHandle * Wrap setRange in CodeMirror in try/catch * Add Mathjax Editor bottom margin * Add custom Enter and Shift+Enter shortcuts for the MathjaxHandle * Format * Move placeCaretAfter to domlib * Move focus back to field after editing Mathjax * Put Cursor after Mathjax after accepting * Add delete button for Mathjax * Change border color of mathjax menu * Refactor into MathjaxMenu * Put caretKeyword in variable * Use one ResizeObserver for all Mathjax images * Add minmimum width for Mathjax editor * is still smaller than minimal window width * Add bazel directories to .prettierignore and format from root * exclude ftl/usage (dae) the json files that live there are output from our tooling, and formatting them means an extra step each time we want to update them also exclude .mypy_cache, which is output by scripts/mypy* * minor ftl tweak: newline -> new line (dae) |
||
Henrik Giesel
|
64d46ca638
|
Reverse-engineer surrounding with execCommand (#1377)
* Add utility functions for saving and restoring the caret location Implement surroundNoSplitting Clarify surroundNoSplitting comments Start implementing surroundSplitting and triggerIfSimpleInput Fix after rebase Implement findBefore / findAfter in lib/surround * to merge adjacent nodes into the surrounding nodes Use new prettier settings with lib/{location,surround} Fix imports that I missed to rename Add some tests for find-adjacent Split find-within from find-adjacent Normalize nodes after insertion in surroundNoSplitting Do not deep clone surroundNode -> no intention of supporting deep nodes, as normalization would be impossible Add some tests concerning nested surrounding nested nodes Select surroundedRange after surrounding Fix ascendWhileSingleInline A flawed first surround/trigger implementation Move trigger out of lib/surround Implement Input Manager as a way to handle bold on empty selection Switch bold button away from execCommand Pass in Matcher instead of selector to find-adjacent and surroundNoSplitting * Also adds a failing test for no-splitting Refactor find-adjacent * add failing test when findBefore's nodes have different amounts of child nodes Change type signature of find-adjacent methods to more single-concern Add test for surrounding where adjacent block becomes three Text elements Make nodes found within surrounded range extend the ranges endOffset Add base parameter to surroundNoSplitting to stop ascending beyond container Stop surrounding from bubbling beyond base in merge-match Make all tests pass Add some failing tests to point to future development Add empty elements as constant Implement a broken version of unsurround Even split text if it creates zero-length texts -> they are still valid, despite what Chromium says Rename {start,end} to {start,end}Container Add more unit tests with surround after a nested element Set endOffset after split-off possibly zero length text nodes Deal with empty elements when surrounding Only include split off end text if zero length Use range anchors instead off calcluating surroundedRange from offsets * this approach allows for removal of base elements when unsurrounding Comment out test which fail because of jsdom bugs We'll be able to enable them again after Jest 28 Make the first unsurround tests pass Add new failing test for unsurround text within tag Fix unsurround Test is deactivated until Jest 28 Rewrite input-manager and trigger callback after insertion Avoid creating zero length text nodes by using insertBefore when appropriate Implement matches vs keepMatches Make shadow root and editable element available on component tree Make WithState work with asynchronous updater functions Add new Bold/Italic/UnderlineButton using our logic Add failing test for unsurrounding * Move surround/ to domlib * Add jest dependency * Make find-within return a sum type array rather than two arrays * Use FoundMatch sum-type for find-above (and find-within) * Fix issue where elements could be cleared twice * if they are IN the range.endContainer * Pass remaining test * Add another failing test * Fix empty text nodes being considered for surrounding * Satisfy svelte check * Make on more type correct * Satisfy remaining tests * Add missing copyright header |
||
Henrik Giesel
|
610ef8f043
|
Save and restore location on ContentEditable (#1481)
* Add utility functions for saving and restoring the caret location * Implement cross-browser.getSelection * Save and restore location on ContentEditable * Fix refocus by clicking on a field that had a non-collapsed selection |