aboutsummaryrefslogtreecommitdiff
path: root/ext/js/data
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-02-24 21:54:58 -0500
committerGitHub <noreply@github.com>2021-02-24 21:54:58 -0500
commitae92e0b3781e27d54cbac2570ba2a1b8a6b11999 (patch)
treeb7d7a7171a6cbc25d5f1fc4b4996024c4f73033e /ext/js/data
parent0a76de1b44443cc668882125d73d83d5f7ba8a63 (diff)
AnkiUtil (#1439)
* Add AnkiUtil * Update AnkiConnect to use AnkiUtil * Use AnkiUtil in AnkiNoteBuilder * Replace containsAnyMarker with AnkiUtil.stringContainsAnyFieldMarker * Add AnkiUtil.getFieldMarkers * Add fieldsObjectContainsMarker to AnkiUtil * Remove unused global * Remove unused parameter: enabled * Add cloneFieldMarkerPattern
Diffstat (limited to 'ext/js/data')
-rw-r--r--ext/js/data/anki-note-builder.js30
-rw-r--r--ext/js/data/anki-util.js87
-rw-r--r--ext/js/data/permissions-util.js21
3 files changed, 98 insertions, 40 deletions
diff --git a/ext/js/data/anki-note-builder.js b/ext/js/data/anki-note-builder.js
index e1399f66..f12846b1 100644
--- a/ext/js/data/anki-note-builder.js
+++ b/ext/js/data/anki-note-builder.js
@@ -16,13 +16,14 @@
*/
/* global
+ * AnkiUtil
* TemplateRendererProxy
*/
class AnkiNoteBuilder {
- constructor(enabled) {
- this._markerPattern = /\{([\w-]+)\}/g;
- this._templateRenderer = enabled ? new TemplateRendererProxy() : null;
+ constructor() {
+ this._markerPattern = AnkiUtil.cloneFieldMarkerPattern(true);
+ this._templateRenderer = new TemplateRendererProxy();
}
async createNote({
@@ -46,7 +47,7 @@ class AnkiNoteBuilder {
let duplicateScopeCheckChildren = false;
if (duplicateScope === 'deck-root') {
duplicateScope = 'deck';
- duplicateScopeDeckName = this.getRootDeckName(deckName);
+ duplicateScopeDeckName = AnkiUtil.getRootDeckName(deckName);
duplicateScopeCheckChildren = true;
}
@@ -89,27 +90,6 @@ class AnkiNoteBuilder {
};
}
- containsMarker(fields, marker) {
- marker = `{${marker}}`;
- for (const [, fieldValue] of fields) {
- if (fieldValue.includes(marker)) {
- return true;
- }
- }
- return false;
- }
-
- containsAnyMarker(field) {
- const result = this._markerPattern.test(field);
- this._markerPattern.lastIndex = 0;
- return result;
- }
-
- getRootDeckName(deckName) {
- const index = deckName.indexOf('::');
- return index >= 0 ? deckName.substring(0, index) : deckName;
- }
-
// Private
async _formatField(field, data, templates, errors=null) {
diff --git a/ext/js/data/anki-util.js b/ext/js/data/anki-util.js
new file mode 100644
index 00000000..fc081ddc
--- /dev/null
+++ b/ext/js/data/anki-util.js
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2021 Yomichan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * This class has some general utility functions for working with Anki data.
+ */
+class AnkiUtil {
+ /**
+ * Gets the root deck name of a full deck name. If the deck is a root deck,
+ * the same name is returned. Nested decks are separated using '::'.
+ * @param deckName A string of the deck name.
+ * @returns A string corresponding to the name of the root deck.
+ */
+ static getRootDeckName(deckName) {
+ const index = deckName.indexOf('::');
+ return index >= 0 ? deckName.substring(0, index) : deckName;
+ }
+
+ /**
+ * Checks whether or not any marker is contained in a string.
+ * @param string A string to check.
+ * @return `true` if the text contains an Anki field marker, `false` otherwise.
+ */
+ static stringContainsAnyFieldMarker(string) {
+ const result = this._markerPattern.test(string);
+ this._markerPattern.lastIndex = 0;
+ return result;
+ }
+
+ /**
+ * Gets a list of all markers that are contained in a string.
+ * @param string A string to check.
+ * @return An array of marker strings.
+ */
+ static getFieldMarkers(string) {
+ const pattern = this._markerPattern;
+ const markers = [];
+ while (true) {
+ const match = pattern.exec(string);
+ if (match === null) { break; }
+ markers.push(match[1]);
+ }
+ return markers;
+ }
+
+ /**
+ * Checks whether an object of key-value pairs has a value which contains a specific marker.
+ * @param fieldsObject An object with key-value pairs, where the value corresponds to the field value.
+ * @param marker The marker string to check for, excluding brackets.
+ * @returns `true` if any of the fields contains the marker, `false` otherwise.
+ */
+ static fieldsObjectContainsMarker(fieldsObject, marker) {
+ marker = `{${marker}}`;
+ for (const [, fieldValue] of fieldsObject) {
+ if (fieldValue.includes(marker)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a regular expression which can be used to find markers in a string.
+ * @param global Whether or not the regular expression should have the global flag.
+ * @returns A new `RegExp` instance.
+ */
+ static cloneFieldMarkerPattern(global) {
+ return new RegExp(this._markerPattern.source, global ? 'g' : '');
+ }
+}
+
+// eslint-disable-next-line no-underscore-dangle
+AnkiUtil._markerPattern = /\{([\w-]+)\}/g;
diff --git a/ext/js/data/permissions-util.js b/ext/js/data/permissions-util.js
index bd3a18ce..3a5b5de5 100644
--- a/ext/js/data/permissions-util.js
+++ b/ext/js/data/permissions-util.js
@@ -15,13 +15,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+/* global
+ * AnkiUtil
+ */
+
class PermissionsUtil {
constructor() {
this._ankiFieldMarkersRequiringClipboardPermission = new Set([
'clipboard-image',
'clipboard-text'
]);
- this._ankiMarkerPattern = /\{([\w-]+)\}/g;
}
hasPermissions(permissions) {
@@ -69,7 +72,7 @@ class PermissionsUtil {
}
getRequiredPermissionsForAnkiFieldValue(fieldValue) {
- const markers = this._getAnkiFieldMarkers(fieldValue);
+ const markers = AnkiUtil.getFieldMarkers(fieldValue);
const markerPermissions = this._ankiFieldMarkersRequiringClipboardPermission;
for (const marker of markers) {
if (markerPermissions.has(marker)) {
@@ -99,7 +102,7 @@ class PermissionsUtil {
];
for (const fields of fieldsList) {
for (const fieldValue of Object.values(fields)) {
- const markers = this._getAnkiFieldMarkers(fieldValue);
+ const markers = AnkiUtil.getFieldMarkers(fieldValue);
for (const marker of markers) {
if (fieldMarkersRequiringClipboardPermission.has(marker)) {
return false;
@@ -111,16 +114,4 @@ class PermissionsUtil {
return true;
}
-
- // Private
-
- _getAnkiFieldMarkers(fieldValue) {
- const pattern = this._ankiMarkerPattern;
- const markers = [];
- let match;
- while ((match = pattern.exec(fieldValue)) !== null) {
- markers.push(match[1]);
- }
- return markers;
- }
}