Refactor options page to use Typescript
Also, I've added and ran eslint, and fixed several minor issues accross
the Typescript codebase.
Bug: translateselectedtext:15
Change-Id: I8cfd67697f9bfb22f6de93b64fd750de66bab863
diff --git a/src/options/elements/options-editor/add-language-dialog.ts b/src/options/elements/options-editor/add-language-dialog.ts
new file mode 100644
index 0000000..155d4e5
--- /dev/null
+++ b/src/options/elements/options-editor/add-language-dialog.ts
@@ -0,0 +1,118 @@
+import {css, html, LitElement} from 'lit';
+import {customElement, property} from 'lit/decorators.js';
+
+import {IsoLang, isoLangs} from '../../../common/consts';
+import {msg} from '../../../common/i18n';
+import {TargetLangs} from '../../../common/options';
+import {DIALOG_STYLES} from '../../shared/dialog-styles';
+import {SHARED_STYLES} from '../../shared/shared-styles';
+
+interface IsoLangWCode extends IsoLang {
+ code: string;
+}
+
+const ALL_LANGUAGES =
+ Object.entries(isoLangs)
+ .map(entry => {
+ const lang: IsoLangWCode = Object.assign(entry[1], {code: entry[0]});
+ return lang;
+ })
+ .sort((a, b) => a.name < b.name ? -1 : (a.name > b.name ? 1 : 0));
+
+@customElement('add-language-dialog')
+export default class AddLanguageDialog extends LitElement {
+ static properties = {
+ languages: {type: Object},
+ };
+ @property({type: Object}) languages: TargetLangs;
+
+ static get styles() {
+ return [
+ SHARED_STYLES,
+ DIALOG_STYLES,
+ css`
+ dialog {
+ max-height: 430px;
+ width: 430px;
+ }
+
+ #language_label {
+ font-size: 12px;
+ }
+
+ select {
+ width: 100%;
+ }
+
+ .action_buttons {
+ border-top: none;
+ padding-top: 0;
+ }
+ `,
+ ];
+ }
+
+ constructor() {
+ super();
+ this.addEventListener('show-add-language-dialog', this.showDialog);
+ }
+
+ render() {
+ const languageCodes = Object.values(this.languages ?? {});
+ const languages = ALL_LANGUAGES
+ .filter(lang => {
+ return !languageCodes.includes(lang.code);
+ })
+ .map(lang => {
+ return html`
+ <option value=${lang.code}>
+ ${lang?.name} (${lang?.nativeName})
+ </option>
+ `;
+ });
+
+ return html`
+ <dialog>
+ <div class="scrollable">
+ <h3>${msg('options_addlanguage')}</h3>
+ <div class="content_area">
+ <label id="language_label" for="select_language">
+ ${msg('options_language_label')}
+ </label>
+ <select id="select_language">${languages}</select>
+ </div>
+ </div>
+ <div class="action_buttons">
+ <button @click=${this.closeDialog}>
+ ${msg('options_cancel')}
+ </button>
+ <button @click=${this.addLanguage}>
+ ${msg('options_addlanguage_addbutton')}
+ </button>
+ </div>
+ </dialog>
+ `;
+ }
+
+ showDialog() {
+ const dialog = this.renderRoot.querySelector('dialog');
+ dialog.showModal();
+ }
+
+ closeDialog() {
+ this.renderRoot.querySelector('dialog').close();
+ }
+
+ addLanguage() {
+ const languageCodes = Object.values(this.languages ?? {});
+ const select = this.renderRoot.querySelector('#select_language') as HTMLSelectElement;
+
+ const newLang = select.value;
+ languageCodes.push(newLang);
+ const translateinto = Object.assign({}, languageCodes);
+ chrome.storage.sync.set({translateinto}, () => {
+ select.selectedIndex = 0;
+ this.closeDialog();
+ });
+ }
+}