Skip to content

Commit

Permalink
Merge branch 'master' into add-korean
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanVukovic99 authored May 14, 2024
2 parents 8789c2e + a336d17 commit bb8f0a7
Show file tree
Hide file tree
Showing 19 changed files with 863 additions and 421 deletions.
3 changes: 3 additions & 0 deletions docs/anki-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ Flashcard fields can be configured with the following steps:
| `{glossary}` | List of definitions for the term (output format depends on whether running in _grouped_ mode). |
| `{glossary-brief}` | List of definitions for the term in a more compact format. |
| `{glossary-no-dictionary}` | List of definitions for the term, except the dictionary tag is omitted. |
| `{glossary-first}` | First definition for the term (output format depends on whether running in _grouped_ mode). |
| `{glossary-first-brief}` | First definition for the term in a more compact format. |
| `{glossary-first-no-dictionary}` | First definition for the term, except the dictionary tag is omitted. |
| `{part-of-speech}` | Part of speech information for the term. |
| `{phonetic-transcriptions}` | List of phonetic transcriptions for the term. |
| `{pitch-accents}` | List of pitch accent downstep notations for the term. |
Expand Down
5 changes: 4 additions & 1 deletion ext/css/material.css
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ body {
.danger-text {
color: var(--danger-color);
}

.success-text {
color: var(--success-color);
}

/* Icons */
.icon {
Expand Down Expand Up @@ -277,6 +279,7 @@ body {
.icon[data-icon=accessibility] { --icon-image: url(/images/accessibility.svg); }
.icon[data-icon=connection] { --icon-image: url(/images/connection.svg); }
.icon[data-icon=external-link] { --icon-image: url(/images/external-link.svg); }
.icon[data-icon=monitor] { --icon-image: url(/images/monitor.svg); }
.icon[data-icon=material-down-arrow] {
--icon-image: url(/images/material-down-arrow.svg);
--icon-size: var(--material-arrow-dimension2) var(--material-arrow-dimension1);
Expand Down
33 changes: 33 additions & 0 deletions ext/data/templates/anki-field-templates-upgrade-v35.handlebars
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{{<<<<<<<}}
{{#*inline "glossary-brief"}}
{{~> glossary brief=true ~}}
{{/inline}}
{{=======}}
{{#*inline "glossary-brief"}}
{{~> glossary brief=true ~}}
{{/inline}}

{{~#*inline "glossary-first"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~else~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}

{{#*inline "glossary-first-no-dictionary"}}
{{~> glossary-first noDictionaryTag=true ~}}
{{/inline}}

{{#*inline "glossary-first-brief"}}
{{~> glossary-first brief=true ~}}
{{/inline}}
{{>>>>>>>}}
24 changes: 24 additions & 0 deletions ext/data/templates/default-anki-field-templates.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@
{{~> glossary brief=true ~}}
{{/inline}}

{{~#*inline "glossary-first"~}}
<div style="text-align: left;">
{{~#scope~}}
{{~#if (op "===" definition.type "term")~}}
{{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
{{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
{{~#if (op ">" definition.definitions.length 1)~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~else~}}
{{~#with definition.definitions.[0]~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/with~}}
{{~/if~}}
{{~/if~}}
{{~/scope~}}
</div>
{{~/inline~}}

{{#*inline "glossary-first-no-dictionary"}}
{{~> glossary-first noDictionaryTag=true ~}}
{{/inline}}

{{#*inline "glossary-first-brief"}}
{{~> glossary-first brief=true ~}}
{{/inline}}

{{#*inline "kunyomi"}}
{{~#each definition.kunyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
{{/inline}}
Expand Down
1 change: 1 addition & 0 deletions ext/images/monitor.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 10 additions & 7 deletions ext/js/background/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -964,10 +964,10 @@ export class Backend {
// Command handlers

/**
* @param {undefined|{mode: 'existingOrNewTab'|'newTab', query?: string}} params
* @param {undefined|{mode: 'existingOrNewTab'|'newTab'|'popup', query?: string}} params
*/
async _onCommandOpenSearchPage(params) {
/** @type {'existingOrNewTab'|'newTab'} */
/** @type {'existingOrNewTab'|'newTab'|'popup'} */
let mode = 'existingOrNewTab';
let query = '';
if (typeof params === 'object' && params !== null) {
Expand Down Expand Up @@ -1023,6 +1023,8 @@ export class Backend {
case 'newTab':
await this._createTab(queryUrl);
return;
case 'popup':
return;
}
}

Expand All @@ -1034,10 +1036,10 @@ export class Backend {
}

/**
* @param {undefined|{mode: 'existingOrNewTab'|'newTab'}} params
* @param {undefined|{mode: 'existingOrNewTab'|'newTab'|'popup'}} params
*/
async _onCommandOpenSettingsPage(params) {
/** @type {'existingOrNewTab'|'newTab'} */
/** @type {'existingOrNewTab'|'newTab'|'popup'} */
let mode = 'existingOrNewTab';
if (typeof params === 'object' && params !== null) {
mode = this._normalizeOpenSettingsPageMode(params.mode, mode);
Expand Down Expand Up @@ -2544,7 +2546,7 @@ export class Backend {
}

/**
* @param {'existingOrNewTab'|'newTab'} mode
* @param {'existingOrNewTab'|'newTab'|'popup'} mode
*/
async _openSettingsPage(mode) {
const manifest = chrome.runtime.getManifest();
Expand Down Expand Up @@ -2673,13 +2675,14 @@ export class Backend {

/**
* @param {unknown} mode
* @param {'existingOrNewTab'|'newTab'} defaultValue
* @returns {'existingOrNewTab'|'newTab'}
* @param {'existingOrNewTab'|'newTab'|'popup'} defaultValue
* @returns {'existingOrNewTab'|'newTab'|'popup'}
*/
_normalizeOpenSettingsPageMode(mode, defaultValue) {
switch (mode) {
case 'existingOrNewTab':
case 'newTab':
case 'popup':
return mode;
default:
return defaultValue;
Expand Down
3 changes: 3 additions & 0 deletions ext/js/data/anki-template-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export function getStandardFieldMarkers(type) {
'glossary',
'glossary-brief',
'glossary-no-dictionary',
'glossary-first',
'glossary-first-brief',
'glossary-first-no-dictionary',
'part-of-speech',
'pitch-accents',
'pitch-accent-graphs',
Expand Down
11 changes: 10 additions & 1 deletion ext/js/data/options-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,8 @@ export class OptionsUtil {
this._updateVersion31,
this._updateVersion32,
this._updateVersion33,
this._updateVersion34
this._updateVersion34,
this._updateVersion35
];
/* eslint-enable @typescript-eslint/unbound-method */
if (typeof targetVersion === 'number' && targetVersion < result.length) {
Expand Down Expand Up @@ -1277,6 +1278,14 @@ export class OptionsUtil {
await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v34.handlebars');
}

/**
* - Added dynamic handlebars for first dictionary entry only.
* @type {import('options-util').UpdateFunction}
*/
async _updateVersion35(options) {
await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v35.handlebars');
}


/**
* @param {string} url
Expand Down
11 changes: 7 additions & 4 deletions ext/js/input/hotkey-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class HotkeyHandler extends EventDispatcher {
super();
/** @type {Map<string, (argument: unknown) => (boolean|void)>} */
this._actions = new Map();
/** @type {Map<string, import('hotkey-handler').HotkeyHandlers>} */
/** @type {Map<(string | null), import('hotkey-handler').HotkeyHandlers>} */
this._hotkeys = new Map();
/** @type {Map<import('settings').InputsHotkeyScope, import('settings').InputsHotkeyOptions[]>} */
this._hotkeyRegistrations = new Map();
Expand Down Expand Up @@ -171,7 +171,11 @@ export class HotkeyHandler extends EventDispatcher {
* @param {KeyboardEvent} event
*/
_onKeyDown(event) {
const hotkeyInfo = this._hotkeys.get(event.code);
let hotkeyInfo = this._hotkeys.get(event.code);
const modifierKeycodes = ['ControlLeft', 'ControlRight', 'ShiftLeft', 'ShiftRight', 'AltLeft', 'AltRight', 'MetaLeft', 'MetaRight'];
if (modifierKeycodes.includes(event.code)) {
hotkeyInfo = this._hotkeys.get(null); // Hotkeys with only modifiers are stored as null
}
if (typeof hotkeyInfo !== 'undefined') {
const eventModifiers = getActiveModifiers(event);
if (this._invokeHandlers(eventModifiers, hotkeyInfo, event.key)) {
Expand Down Expand Up @@ -228,8 +232,7 @@ export class HotkeyHandler extends EventDispatcher {
this._hotkeys.clear();
for (const [scope, registrations] of this._hotkeyRegistrations.entries()) {
for (const {action, argument, key, modifiers, scopes, enabled} of registrations) {
if (!(enabled && key !== null && action !== '' && scopes.includes(scope))) { continue; }

if (!(enabled && (key !== null || modifiers !== null) && action !== '' && scopes.includes(scope))) { continue; }
let hotkeyInfo = this._hotkeys.get(key);
if (typeof hotkeyInfo === 'undefined') {
hotkeyInfo = {handlers: []};
Expand Down
10 changes: 9 additions & 1 deletion ext/js/pages/action-popup-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,15 @@ class DisplayController {
const result = customHandler(e);
if (typeof result !== 'undefined') { return; }
}
void this._api.commandExec(command, {mode: e.ctrlKey ? 'newTab' : 'existingOrNewTab'});

let mode = 'existingOrNewTab';
if (e.ctrlKey) {
mode = 'newTab';
} else if (e.shiftKey) {
mode = 'popup';
}

void this._api.commandExec(command, {mode: mode});
e.preventDefault();
};
/**
Expand Down
23 changes: 18 additions & 5 deletions ext/js/pages/settings/dictionary-import-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,15 @@ export class DictionaryImportController {
return errors;
}

void this._settingsController.application.api.triggerDatabaseUpdated('dictionary', 'import');
const errors2 = await this._addDictionarySettings(result.sequenced, result.title);

await this._settingsController.application.api.triggerDatabaseUpdated('dictionary', 'import');

if (errors.length > 0) {
const allErrors = [...errors, ...errors2];
allErrors.push(new Error(`Dictionary may not have been imported properly: ${allErrors.length} error${allErrors.length === 1 ? '' : 's'} reported.`));
this._showErrors(allErrors);
errors.push(new Error(`Dictionary may not have been imported properly: ${errors.length} error${errors.length === 1 ? '' : 's'} reported.`));
this._showErrors([...errors, ...errors2]);
} else if (errors2.length > 0) {
this._showErrors(errors2);
}
}

Expand All @@ -258,7 +260,18 @@ export class DictionaryImportController {
* @returns {Promise<Error[]>}
*/
async _addDictionarySettings(sequenced, title) {
const optionsFull = await this._settingsController.getOptionsFull();
let optionsFull;
// Workaround Firefox bug sometimes causing getOptionsFull to fail
for (let i = 0, success = false; (i < 10) && (success === false); i++) {
try {
optionsFull = await this._settingsController.getOptionsFull();
success = true;
} catch (error) {
log.error(error);
}
}
if (!optionsFull) { return [new Error('Failed to automatically set dictionary settings. A page refresh and manual enabling of the dictionary may be required.')]; }

const profileIndex = this._settingsController.profileIndex;
/** @type {import('settings-modifications').Modification[]} */
const targets = [];
Expand Down
36 changes: 24 additions & 12 deletions ext/js/pages/settings/recommended-permissions-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import {EventListenerCollection} from '../../core/event-listener-collection.js';
import {toError} from '../../core/to-error.js';
import {getAllPermissions, setPermissionsGranted} from '../../data/permissions-util.js';
import {querySelectorNotNull} from '../../dom/query-selector.js';

export class RecommendedPermissionsController {
/**
Expand All @@ -27,8 +28,8 @@ export class RecommendedPermissionsController {
constructor(settingsController) {
/** @type {import('./settings-controller.js').SettingsController} */
this._settingsController = settingsController;
/** @type {?NodeListOf<HTMLInputElement>} */
this._originToggleNodes = null;
/** @type {HTMLInputElement} */
this._originToggleNode = querySelectorNotNull(document, '#recommended-permissions-toggle');
/** @type {EventListenerCollection} */
this._eventListeners = new EventListenerCollection();
/** @type {?HTMLElement} */
Expand All @@ -37,11 +38,8 @@ export class RecommendedPermissionsController {

/** */
async prepare() {
this._originToggleNodes = document.querySelectorAll('.recommended-permissions-toggle');
this._errorContainer = document.querySelector('#recommended-permissions-error');
for (const node of this._originToggleNodes) {
node.addEventListener('change', this._onOriginToggleChange.bind(this), false);
}
this._originToggleNode.addEventListener('change', this._onOriginToggleChange.bind(this), false);

this._settingsController.on('permissionsChanged', this._onPermissionsChanged.bind(this));
await this._updatePermissions();
Expand All @@ -55,12 +53,8 @@ export class RecommendedPermissionsController {
_onPermissionsChanged({permissions}) {
this._eventListeners.removeAllEventListeners();
const originsSet = new Set(permissions.origins);
if (this._originToggleNodes !== null) {
for (const node of this._originToggleNodes) {
const {origin} = node.dataset;
node.checked = typeof origin === 'string' && originsSet.has(origin);
}
}
const {origin} = this._originToggleNode.dataset;
this._originToggleNode.checked = typeof origin === 'string' && originsSet.has(origin);
}

/**
Expand All @@ -80,6 +74,7 @@ export class RecommendedPermissionsController {
async _updatePermissions() {
const permissions = await getAllPermissions();
this._onPermissionsChanged({permissions});
this._setWelcomePageText();
}

/**
Expand All @@ -101,4 +96,21 @@ export class RecommendedPermissionsController {
await this._updatePermissions();
return true;
}

/** */
_setWelcomePageText() {
/** @type {HTMLElement | null} */
this._textIfEnabled = document.querySelector('#permissions-enabled');
/** @type {HTMLElement | null} */
this._textIfDisabled = document.querySelector('#permissions-disabled');
if (this._textIfEnabled && this._textIfDisabled) {
if (this._originToggleNode.checked) {
this._textIfEnabled.hidden = false;
this._textIfDisabled.hidden = true;
} else {
this._textIfEnabled.hidden = true;
this._textIfDisabled.hidden = false;
}
}
}
}
22 changes: 6 additions & 16 deletions ext/js/pages/settings/sort-frequency-dictionary-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,12 @@ export class SortFrequencyDictionaryController {
option.textContent = 'None';
fragment.appendChild(option);
for (const {title, counts} of dictionaries) {
if (this._dictionaryHasNoFrequencies(counts)) { continue; }
option = document.createElement('option');
option.value = title;
option.textContent = title;
fragment.appendChild(option);
if (counts.termMeta.freq > 0) {
option = document.createElement('option');
option.value = title;
option.textContent = title;
fragment.appendChild(option);
}
}
const select = /** @type {HTMLSelectElement} */ (this._sortFrequencyDictionarySelect);
select.textContent = '';
Expand Down Expand Up @@ -195,17 +196,6 @@ export class SortFrequencyDictionaryController {
return Math.sign(result);
}

/**
* @param {import('dictionary-importer').SummaryCounts} counts
* @returns {boolean}
*/
_dictionaryHasNoFrequencies(counts) {
if (typeof counts !== 'object' || counts === null) { return false; }
const {termMeta} = counts;
if (typeof termMeta !== 'object' || termMeta === null) { return false; }
return termMeta.freq <= 0;
}

/**
* @param {string} value
* @returns {?import('settings').SortFrequencyDictionaryOrder}
Expand Down
Loading

0 comments on commit bb8f0a7

Please sign in to comment.