Compare commits
No commits in common. "15ad17e1d75c372f3e2b6b5e810bd559bae9e810" and "90e0553f4ea1a321f35c69960dbb5e0a8d9584fc" have entirely different histories.
15ad17e1d7
...
90e0553f4e
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lexiconga",
|
||||
"version": "2.2.0",
|
||||
"version": "2.1.7",
|
||||
"description": "The quick and easy dictionary builder for constructed languages.",
|
||||
"main": "template-index.html",
|
||||
"repository": "https://github.com/Alamantus/Lexiconga.git",
|
||||
|
|
|
@ -59,7 +59,6 @@ export const DEFAULT_SETTINGS = {
|
|||
useHotkeys: true,
|
||||
showAdvanced: false,
|
||||
defaultTheme: 'default',
|
||||
templates: [],
|
||||
};
|
||||
|
||||
export const DISPLAY_AD_EVERY = 10;
|
||||
|
|
|
@ -94,22 +94,18 @@ export function renderAccountActions() {
|
|||
const accountActionsHTML = `<h3>Account Actions</h3>
|
||||
<label>Change Dictionary<br><select id="accountSettingsChangeDictionary"></select></label>
|
||||
<p><a class="button" id="accountSettingsCreateNewDictionary">Create New Dictionary</a></p>
|
||||
<details>
|
||||
<summary><h4>Request Your Data</h4></summary>
|
||||
<p>
|
||||
Per your <a href="https://www.eugdpr.org/" target="_blank">GDPR</a> rights in Articles 13–15 and 20, we allow you to request any and all data we have stored about you. The only data we have about you personally is your email address and your Public Name, if you decided to set one. All other data (your Dictionary data) is visible and accessible via the Export button under your Dictionary's Settings. Send an email to help@lexicon.ga to request your information.
|
||||
</p>
|
||||
</details>
|
||||
<h4>Request Your Data</h4>
|
||||
<p>
|
||||
Per your <a href="https://www.eugdpr.org/" target="_blank">GDPR</a> rights in Articles 13–15 and 20, we allow you to request any and all data we have stored about you. The only data we have about you personally is your email address and your Public Name, if you decided to set one. All other data (your Dictionary data) is visible and accessible via the Export button under your Dictionary's Settings. Send an email to help@lexicon.ga to request your information.
|
||||
</p>
|
||||
|
||||
<details>
|
||||
<summary><h4>Delete Your Account</h4></summary>
|
||||
<p>
|
||||
Per your <a href="https://www.eugdpr.org/" target="_blank">GDPR</a> rights in Articles 17, if you wish for your account to be deleted, please contact us at help@lexicon.ga, and we will delete your account and all associated dictionaries and words as quickly as possible. Note that you can delete dictionaries yourself via your Dictionary's Settings.
|
||||
</p>
|
||||
<p>
|
||||
Anything that is deleted from our system is permanently and irretrievably removed from our system and cannot be restored, though search engines or internet archives may retain a cached version of your content (there is nothing we can do about this, and you will need to seek out removal of that information by directly contacting the services that are caching your data).
|
||||
</p>
|
||||
</details>
|
||||
<h4>Delete Your Account</h4>
|
||||
<p>
|
||||
Per your <a href="https://www.eugdpr.org/" target="_blank">GDPR</a> rights in Articles 17, if you wish for your account to be deleted, please contact us at help@lexicon.ga, and we will delete your account and all associated dictionaries and words as quickly as possible. Note that you can delete dictionaries yourself via your Dictionary's Settings.
|
||||
</p>
|
||||
<p>
|
||||
Anything that is deleted from our system is permanently and irretrievably removed from our system and cannot be restored, though search engines or internet archives may retain a cached version of your content (there is nothing we can do about this, and you will need to seek out removal of that information by directly contacting the services that are caching your data).
|
||||
</p>
|
||||
`;
|
||||
accountActionsColumn.innerHTML = accountActionsHTML;
|
||||
|
||||
|
|
|
@ -238,51 +238,14 @@ export function importWords() {
|
|||
});
|
||||
} else {
|
||||
const row = results.data;
|
||||
const wordToImport = {
|
||||
const importedWord = addWord({
|
||||
name: removeTags(row.word).trim(),
|
||||
pronunciation: removeTags(row.pronunciation).trim(),
|
||||
partOfSpeech: removeTags(row['part of speech']).trim(),
|
||||
definition: removeTags(row.definition).trim(),
|
||||
details: removeTags(row.explanation).trim(),
|
||||
wordId: getNextId(),
|
||||
};
|
||||
if (typeof row['etymology'] !== 'undefined') {
|
||||
const etymology = removeTags(row['etymology']).trim().split(',').filter(etymology => etymology.trim() !== '');
|
||||
if (etymology.length > 0) {
|
||||
wordToImport.etymology = etymology;
|
||||
}
|
||||
}
|
||||
if (typeof row['etymology (comma-separated)'] !== 'undefined') {
|
||||
const etymology = removeTags(row['etymology (comma-separated)']).trim().split(',').filter(etymology => etymology.trim() !== '');
|
||||
if (etymology.length > 0) {
|
||||
wordToImport.etymology = etymology;
|
||||
}
|
||||
}
|
||||
if (typeof row['related words'] !== 'undefined') {
|
||||
const related = removeTags(row['related words']).trim().split(',').filter(related => related.trim() !== '');
|
||||
if (related.length > 0) {
|
||||
wordToImport.related = related;
|
||||
}
|
||||
}
|
||||
if (typeof row['related words (comma-separated)'] !== 'undefined') {
|
||||
const related = removeTags(row['related words (comma-separated)']).trim().split(',').filter(related => related.trim() !== '');
|
||||
if (related.length > 0) {
|
||||
wordToImport.related = related;
|
||||
}
|
||||
}
|
||||
if (typeof row['principal parts'] !== 'undefined') {
|
||||
const principalParts = removeTags(row['principal parts']).trim().split(',').filter(principalParts => principalParts.trim() !== '');
|
||||
if (principalParts.length > 0) {
|
||||
wordToImport.principalParts = principalParts;
|
||||
}
|
||||
}
|
||||
if (typeof row['principal parts (comma-separated)'] !== 'undefined') {
|
||||
const principalParts = removeTags(row['principal parts (comma-separated)']).trim().split(',').filter(principalParts => principalParts.trim() !== '');
|
||||
if (principalParts.length > 0) {
|
||||
wordToImport.principalParts = principalParts;
|
||||
}
|
||||
}
|
||||
const importedWord = addWord(wordToImport, false);
|
||||
}, false);
|
||||
|
||||
importedWords.push(importedWord);
|
||||
|
||||
|
@ -343,9 +306,6 @@ export function exportWords() {
|
|||
'part of speech': word.partOfSpeech,
|
||||
definition: word.definition,
|
||||
explanation: word.details,
|
||||
'etymology (comma-separated)': typeof word.etymology !== 'undefined' ? word.etymology.join(',') : '',
|
||||
'related words (comma-separated)': typeof word.related !== 'undefined' ? word.related.join(',') : '',
|
||||
'principal parts (comma-separated)': typeof word.principalParts !== 'undefined' ? word.principalParts.join(',') : '',
|
||||
}
|
||||
});
|
||||
const csv = papa.unparse(words, { quotes: true });
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import { renderDictionaryDetails, renderPartsOfSpeech } from './details';
|
||||
import { renderWords } from './words';
|
||||
import { renderTemplateSelectOptions } from './settings';
|
||||
|
||||
export function renderAll() {
|
||||
renderTheme();
|
||||
renderCustomCSS();
|
||||
renderDictionaryDetails();
|
||||
renderPartsOfSpeech();
|
||||
renderTemplateSelectOptions();
|
||||
renderWords();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
import { setupTemplateSelectOptions } from "../setupListeners/settings";
|
||||
|
||||
export function renderTemplateSelectOptions() {
|
||||
const { templates } = window.settings;
|
||||
|
||||
if (typeof templates !== 'undefined') {
|
||||
const templatesOptionsHTML = templates.map((template, index) => {
|
||||
return `<option value="${index.toString()}">${template.name}</options>`;
|
||||
}).join('');
|
||||
|
||||
Array.from(document.getElementsByClassName('template-select')).forEach(select => {
|
||||
select.innerHTML = '<option value="" selected="selected">None Selected</option>' + templatesOptionsHTML;
|
||||
});
|
||||
|
||||
setupTemplateSelectOptions();
|
||||
}
|
||||
}
|
||||
|
||||
export function showTemplateEditor(show = true) {
|
||||
document.getElementById('templateFields').style.display = show ? '' : 'none';
|
||||
if (show) {
|
||||
document.getElementById('templateTextarea').focus();
|
||||
} else {
|
||||
clearTemplateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
export function showSelectedTemplate(template, index) {
|
||||
const nameField = document.getElementById('templateNameField');
|
||||
nameField.value = template.name;
|
||||
nameField.setAttribute('template', index.toString());
|
||||
document.getElementById('templateTextarea').value = template.template;
|
||||
showTemplateEditor(true);
|
||||
}
|
||||
|
||||
export function clearTemplateEditor() {
|
||||
document.getElementById('savedDetailsTemplates').value = '';
|
||||
document.getElementById('templateNameField').value = '';
|
||||
document.getElementById('templateTextarea').value = '';
|
||||
}
|
|
@ -13,58 +13,6 @@ import { getOpenEditForms, translateOrthography, parseReferences, getWordReferen
|
|||
import { renderAd } from '../ads';
|
||||
import { getPublicLink } from '../account/utilities';
|
||||
import { renderPartsOfSpeech } from './details';
|
||||
import { renderTemplateSelectOptions } from './settings';
|
||||
|
||||
export function renderWord(savedWord, isPublic) {
|
||||
const word = highlightSearchTerm({
|
||||
name: removeTags(savedWord.name),
|
||||
pronunciation: removeTags(savedWord.pronunciation),
|
||||
partOfSpeech: removeTags(savedWord.partOfSpeech),
|
||||
definition: removeTags(savedWord.definition),
|
||||
details: parseReferences(removeTags(savedWord.details)),
|
||||
etymology: typeof savedWord.etymology === 'undefined' || savedWord.etymology.length < 1 ? null
|
||||
: savedWord.etymology.map(root => getWordReferenceMarkdown(removeTags(root))).join(', '),
|
||||
related: typeof savedWord.related === 'undefined' || savedWord.related.length < 1 ? null
|
||||
: savedWord.related.map(relatedWord => getWordReferenceMarkdown(removeTags(relatedWord))).join(', '),
|
||||
principalParts: typeof savedWord.principalParts === 'undefined' || savedWord.principalParts.length < 1 ? null
|
||||
: savedWord.principalParts.join(', '),
|
||||
wordId: savedWord.wordId,
|
||||
});
|
||||
const homonymnNumber = getHomonymnNumber(savedWord);
|
||||
const shareLink = window.currentDictionary.hasOwnProperty('externalID') ? getPublicLink() + '/' + word.wordId : '';
|
||||
|
||||
let wordNameDisplay = translateOrthography(word.name);
|
||||
|
||||
return `<article class="entry" id="${word.wordId}">
|
||||
<header>
|
||||
<h4 class="word"><span class="orthographic-translation">${wordNameDisplay}</span>${homonymnNumber > 0 ? ' <sub>' + homonymnNumber.toString() + '</sub>' : ''}</h4>
|
||||
${word.principalParts === null ? '' : `<span class="principalParts">(${word.principalParts})</span>`}
|
||||
<span class="pronunciation">${word.pronunciation}</span>
|
||||
<span class="part-of-speech">${word.partOfSpeech}</span>
|
||||
${isPublic ? `<a class="small button share-link" href="${shareLink}" target="_blank" title="Public Link to Word">➦</a>` : ''}
|
||||
<span class="small button word-option-button">Options</span>
|
||||
<div class="word-option-list" style="display:none;">
|
||||
<div class="word-option" id="edit_${word.wordId}">Edit</div>
|
||||
<div class="word-option" id="delete_${word.wordId}">Delete</div>
|
||||
</div>
|
||||
</header>
|
||||
<dl>
|
||||
<dt class="definition">${word.definition}</dt>
|
||||
<dd class="details">
|
||||
${md(word.details)}
|
||||
</dd>
|
||||
${word.etymology === null && word.related === null ? '' : `<hr>`}
|
||||
${word.etymology === null ? '' : `<dt>Etymology <small>(Root Word${savedWord.etymology.length !== 1 ? 's' : ''})</small></dt>
|
||||
<dd class="etymology">
|
||||
${md(word.etymology).replace(/<\/?p>/g, '')}
|
||||
</dd>`}
|
||||
${word.related === null ? '' : `<dt>Related Word${savedWord.related.length !== 1 ? 's' : ''}</dt>
|
||||
<dd class="related">
|
||||
${md(word.related).replace(/<\/?p>/g, '')}
|
||||
</dd>`}
|
||||
</dl>
|
||||
</article>`;
|
||||
}
|
||||
|
||||
export function renderWords() {
|
||||
let wordsHTML = '';
|
||||
|
@ -104,11 +52,58 @@ export function renderWords() {
|
|||
|
||||
// const { pageStart, pageEnd } = getPaginationData(words);
|
||||
|
||||
// words.slice(pageStart, pageEnd).forEach(savedWord => {
|
||||
words.forEach((savedWord, displayIndex) => {
|
||||
// words.slice(pageStart, pageEnd).forEach(originalWord => {
|
||||
words.forEach((originalWord, displayIndex) => {
|
||||
const word = highlightSearchTerm({
|
||||
name: removeTags(originalWord.name),
|
||||
pronunciation: removeTags(originalWord.pronunciation),
|
||||
partOfSpeech: removeTags(originalWord.partOfSpeech),
|
||||
definition: removeTags(originalWord.definition),
|
||||
details: parseReferences(removeTags(originalWord.details)),
|
||||
etymology: typeof originalWord.etymology === 'undefined' || originalWord.etymology.length < 1 ? null
|
||||
: originalWord.etymology.map(root => getWordReferenceMarkdown(removeTags(root))).join(', '),
|
||||
related: typeof originalWord.related === 'undefined' || originalWord.related.length < 1 ? null
|
||||
: originalWord.related.map(relatedWord => getWordReferenceMarkdown(removeTags(relatedWord))).join(', '),
|
||||
principalParts: typeof originalWord.principalParts === 'undefined' || originalWord.principalParts.length < 1 ? null
|
||||
: originalWord.principalParts.join(', '),
|
||||
wordId: originalWord.wordId,
|
||||
});
|
||||
const homonymnNumber = getHomonymnNumber(originalWord);
|
||||
const shareLink = window.currentDictionary.hasOwnProperty('externalID') ? getPublicLink() + '/' + word.wordId : '';
|
||||
|
||||
wordsHTML += renderAd(displayIndex);
|
||||
|
||||
wordsHTML += renderWord(savedWord, isPublic);
|
||||
let wordNameDisplay = translateOrthography(word.name);
|
||||
|
||||
wordsHTML += `<article class="entry" id="${word.wordId}">
|
||||
<header>
|
||||
<h4 class="word"><span class="orthographic-translation">${wordNameDisplay}</span>${homonymnNumber > 0 ? ' <sub>' + homonymnNumber.toString() + '</sub>' : ''}</h4>
|
||||
${word.principalParts === null ? '' : `<span class="principalParts">(${word.principalParts})</span>`}
|
||||
<span class="pronunciation">${word.pronunciation}</span>
|
||||
<span class="part-of-speech">${word.partOfSpeech}</span>
|
||||
${isPublic ? `<a class="small button share-link" href="${shareLink}" target="_blank" title="Public Link to Word">➦</a>` : ''}
|
||||
<span class="small button word-option-button">Options</span>
|
||||
<div class="word-option-list" style="display:none;">
|
||||
<div class="word-option" id="edit_${word.wordId}">Edit</div>
|
||||
<div class="word-option" id="delete_${word.wordId}">Delete</div>
|
||||
</div>
|
||||
</header>
|
||||
<dl>
|
||||
<dt class="definition">${word.definition}</dt>
|
||||
<dd class="details">
|
||||
${md(word.details)}
|
||||
</dd>
|
||||
${word.etymology === null && word.related === null ? '' : `<hr>`}
|
||||
${word.etymology === null ? '' : `<dt>Etymology <small>(Root Word${originalWord.etymology.length !== 1 ? 's' : ''})</small></dt>
|
||||
<dd class="etymology">
|
||||
${md(word.etymology).replace(/<\/?p>/g, '')}
|
||||
</dd>`}
|
||||
${word.related === null ? '' : `<dt>Related Word${originalWord.related.length !== 1 ? 's' : ''}</dt>
|
||||
<dd class="related">
|
||||
${md(word.related).replace(/<\/?p>/g, '')}
|
||||
</dd>`}
|
||||
</dl>
|
||||
</article>`;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -160,8 +155,6 @@ export function renderEditForm(wordId = false) {
|
|||
wordId = typeof wordId.target === 'undefined' ? wordId : parseInt(this.id.replace('edit_', ''));
|
||||
const word = window.currentDictionary.words.find(w => w.wordId === wordId);
|
||||
if (word) {
|
||||
const wordHasAdvancedFields = (word.hasOwnProperty('etymology') && word.etymology)
|
||||
|| (word.hasOwnProperty('related') && word.related) || (word.hasOwnProperty('principalParts') && word.principalParts);
|
||||
const ipaPronunciationField = `<input id="wordPronunciation_${wordId}" class="ipa-field" maxlength="200" value="${word.pronunciation}"><br>
|
||||
<a class="label-help-button ipa-field-help-button">Field Help</a>`;
|
||||
const plainPronunciationField = `<input id="wordPronunciation_${wordId}" maxlength="200" value="${word.pronunciation}">`;
|
||||
|
@ -184,14 +177,9 @@ export function renderEditForm(wordId = false) {
|
|||
<textarea id="wordDetails_${wordId}" placeholder="Markdown formatting allowed">${word.details}</textarea>
|
||||
</label>
|
||||
<label>
|
||||
<a id="expandAdvancedForm_${wordId}" class="small button expand-advanced-form">${wordHasAdvancedFields || window.settings.showAdvanced ? 'Hide' : 'Show'} Advanced Fields</a>
|
||||
<a id="expandAdvancedForm_${wordId}" class="small button expand-advanced-form">${window.settings.showAdvanced ? 'Hide' : 'Show'} Advanced Fields</a>
|
||||
</label>
|
||||
<div id="advancedForm_${wordId}" class="advanced-word-form" style="display:${wordHasAdvancedFields || window.settings.showAdvanced ? 'block' : 'none'};">
|
||||
<label>Details Field Templates
|
||||
<select id="templateSelect_${wordId}" class="template-select">
|
||||
</select>
|
||||
<small>Choose one to fill the details field. (Note: Will erase anything currently there.)</small>
|
||||
</label>
|
||||
<div id="advancedForm_${wordId}" class="advanced-word-form" style="display:${window.settings.showAdvanced ? 'block' : 'none'};">
|
||||
<label>Etymology / Root Words<br>
|
||||
<input id="wordEtymology_${wordId}" maxlength="2500" placeholder="comma,separated,root,words" value="${word.hasOwnProperty('etymology') ? word.etymology : ''}">
|
||||
</label>
|
||||
|
@ -210,6 +198,5 @@ export function renderEditForm(wordId = false) {
|
|||
document.getElementById(wordId.toString()).innerHTML = editForm;
|
||||
setupWordEditFormButtons();
|
||||
renderPartsOfSpeech(true);
|
||||
renderTemplateSelectOptions();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import { usePhondueDigraphs } from "./KeyboardFire/phondue/ipaField";
|
|||
import { renderWords } from "./render/words";
|
||||
import { addMessage, hasToken, objectValuesAreDifferent } from "./utilities";
|
||||
import { enableHotKeys, disableHotKeys } from "./hotkeys";
|
||||
import { showTemplateEditor, renderTemplateSelectOptions, showSelectedTemplate } from "./render/settings";
|
||||
|
||||
export function loadSettings() {
|
||||
const storedSettings = window.localStorage.getItem(SETTINGS_KEY);
|
||||
|
@ -19,92 +18,16 @@ export function saveSettings() {
|
|||
}
|
||||
|
||||
export function openSettingsModal() {
|
||||
const { useIPAPronunciationField, useHotkeys, showAdvanced, defaultTheme, templates } = window.settings;
|
||||
const { useIPAPronunciationField, useHotkeys, showAdvanced, defaultTheme } = window.settings;
|
||||
|
||||
document.getElementById('settingsUseIPA').checked = useIPAPronunciationField;
|
||||
document.getElementById('settingsUseHotkeys').checked = useHotkeys;
|
||||
document.getElementById('settingsShowAdvanced').checked = showAdvanced;
|
||||
document.getElementById('settingsDefaultTheme').value = defaultTheme;
|
||||
|
||||
renderTemplateSelectOptions();
|
||||
showTemplateEditor(false);
|
||||
|
||||
document.getElementById('settingsModal').style.display = '';
|
||||
}
|
||||
|
||||
export function updateTemplateSelects() {
|
||||
const { templates } = window.settings;
|
||||
|
||||
if (typeof templates !== 'undefined') {
|
||||
const templatesOptionsHTML = templates.map((template, index) => {
|
||||
return `<option value="${index.toString()}">${template.name}</options>`;
|
||||
}).join('');
|
||||
document.getElementById('savedDetailsTemplates').innerHTML = templatesOptionsHTML;
|
||||
|
||||
const templateSelects = document.getElementsByClassName('template-select');
|
||||
Array.from(templateSelects).forEach(select => {
|
||||
select.removeEventListener('click', showWordOptions);
|
||||
select.innerHTML = templatesOptionsHTML;
|
||||
select.addEventListener('click', showWordOptions);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function createTemplate() {
|
||||
window.settings.templates.push({ name: 'New Blank Template', template: '' });
|
||||
const newTemplateIndex = window.settings.templates.length - 1;
|
||||
|
||||
renderTemplateSelectOptions();
|
||||
document.getElementById('savedDetailsTemplates').value = (newTemplateIndex).toString();
|
||||
|
||||
editSavedTemplate(newTemplateIndex);
|
||||
}
|
||||
|
||||
export function saveTemplate() {
|
||||
const nameField = document.getElementById('templateNameField');
|
||||
const name = nameField.value.trim();
|
||||
const index = parseInt(nameField.getAttribute('template'));
|
||||
const template = document.getElementById('templateTextarea').value;
|
||||
window.settings.templates[index] = { name, template };
|
||||
|
||||
let storedSettings = window.localStorage.getItem(SETTINGS_KEY);
|
||||
storedSettings = storedSettings ? JSON.parse(storedSettings) : cloneObject(DEFAULT_SETTINGS);
|
||||
storedSettings.templates = window.settings.templates;
|
||||
window.localStorage.setItem(SETTINGS_KEY, JSON.stringify(storedSettings));
|
||||
addMessage('Templates Saved!');
|
||||
|
||||
showTemplateEditor(false);
|
||||
|
||||
renderTemplateSelectOptions();
|
||||
}
|
||||
|
||||
export function deleteSelectedTemplate() {
|
||||
const nameField = document.getElementById('templateNameField');
|
||||
const index = nameField.getAttribute('template');
|
||||
const name = window.settings.templates[index].name;
|
||||
if (confirm(`Are you sure you want to delete the "${name}" template? This cannot be undone!`)) {
|
||||
delete window.settings.templates[index];
|
||||
window.settings.templates = window.settings.templates.filter(template => template != null);
|
||||
|
||||
saveSettings();
|
||||
|
||||
showTemplateEditor(false);
|
||||
|
||||
renderTemplateSelectOptions();
|
||||
}
|
||||
}
|
||||
|
||||
export function editSavedTemplate(selectEvent) {
|
||||
const { templates } = window.settings;
|
||||
const selectedIndex = typeof selectEvent.target !== 'undefined' ? selectEvent.target.value : selectEvent;
|
||||
|
||||
if (selectedIndex !== '') {
|
||||
showSelectedTemplate(templates[selectedIndex], selectedIndex);
|
||||
} else {
|
||||
showTemplateEditor(false);
|
||||
}
|
||||
}
|
||||
|
||||
export function saveSettingsModal() {
|
||||
const updatedSettings = cloneObject(window.settings);
|
||||
updatedSettings.useIPAPronunciationField = document.getElementById('settingsUseIPA').checked;
|
||||
|
|
|
@ -5,17 +5,14 @@ import { fadeOutElement } from '../utilities';
|
|||
import { setupDetailsTabs } from './details';
|
||||
import { setupWordForm, setupMobileWordFormButton } from './words';
|
||||
import { setupIPAButtons, setupHeaderButtons, setupInfoButtons } from './buttons';
|
||||
import { setupTemplateForm, setupTemplateSelectOptions } from './settings';
|
||||
|
||||
export default function setupListeners() {
|
||||
setupAnnouncements();
|
||||
setupDetailsTabs();
|
||||
setupTemplateForm();
|
||||
setupHeaderButtons();
|
||||
setupWordForm();
|
||||
setupMobileWordFormButton();
|
||||
setupInfoButtons();
|
||||
setupTemplateSelectOptions();
|
||||
if (window.settings.useHotkeys) {
|
||||
enableHotKeys();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
import { insertAtCursor, getInputSelection, setSelectionRange } from '../StackOverflow/inputCursorManagement';
|
||||
import {
|
||||
openSettingsModal,
|
||||
saveSettingsModal,
|
||||
saveAndCloseSettingsModal,
|
||||
createTemplate,
|
||||
saveTemplate
|
||||
} from '../settings';
|
||||
import { openSettingsModal, saveSettingsModal, saveAndCloseSettingsModal } from '../settings';
|
||||
|
||||
export function setupSettingsModal() {
|
||||
document.getElementById('createTemplateButton').addEventListener('click', createTemplate);
|
||||
document.getElementById('saveTemplateButton').addEventListener('click', saveTemplate);
|
||||
|
||||
document.getElementById('settingsButton').addEventListener('click', openSettingsModal);
|
||||
document.getElementById('settingsSave').addEventListener('click', saveSettingsModal);
|
||||
document.getElementById('settingsSaveAndClose').addEventListener('click', saveAndCloseSettingsModal);
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import { createTemplate, saveTemplate, editSavedTemplate, deleteSelectedTemplate } from "../settings";
|
||||
|
||||
export function setupTemplateForm() {
|
||||
document.getElementById('createTemplateButton').addEventListener('click', createTemplate);
|
||||
document.getElementById('saveTemplateButton').addEventListener('click', saveTemplate);
|
||||
document.getElementById('deleteTemplateButton').addEventListener('click', deleteSelectedTemplate);
|
||||
setupSavedTemplatesSelect();
|
||||
}
|
||||
|
||||
export function setupSavedTemplatesSelect() {
|
||||
const savedTemplatesSelect = document.getElementById('savedDetailsTemplates');
|
||||
|
||||
savedTemplatesSelect.removeEventListener('change', editSavedTemplate);
|
||||
savedTemplatesSelect.addEventListener('change', editSavedTemplate);
|
||||
}
|
||||
|
||||
export function setupTemplateSelectOptions() {
|
||||
const fillDetailsWithTemplate = function (e) {
|
||||
if (e.target.value !== '') {
|
||||
const template = window.settings.templates[parseInt(e.target.value)];
|
||||
let detailsId = 'wordDetails' + e.target.id.replace('templateSelect', '');
|
||||
document.getElementById(detailsId).value = template.template;
|
||||
}
|
||||
}
|
||||
Array.from(document.getElementsByClassName('template-select')).forEach(select => {
|
||||
if (select.id !== 'savedDetailsTemplates') {
|
||||
select.removeEventListener('change', fillDetailsWithTemplate);
|
||||
select.addEventListener('change', fillDetailsWithTemplate);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
import { renderWords, renderWord } from "./render/words";
|
||||
import { renderWords } from "./render/words";
|
||||
import { wordExists, addMessage, getNextId, hasToken, getHomonymnIndexes } from "./utilities";
|
||||
import removeDiacritics from "./StackOverflow/removeDiacritics";
|
||||
import { removeTags, getTimestampInSeconds } from "../helpers";
|
||||
import { saveDictionary } from "./dictionaryManagement";
|
||||
import { setupWordOptionButtons, setupWordOptionSelections } from "./setupListeners/words";
|
||||
|
||||
export function validateWord(word, wordId = false) {
|
||||
const errorElementId = wordId === false ? 'wordErrorMessage' : 'wordErrorMessage_' + wordId,
|
||||
|
@ -127,7 +126,7 @@ export function parseReferences(detailsMarkdown) {
|
|||
}
|
||||
|
||||
export function getWordReferenceMarkdown(reference) {
|
||||
let wordToFind = reference.replace(/\{\{|\}\}/g, '');
|
||||
const wordToFind = reference.replace(/\{\{|\}\}/g, '');
|
||||
let homonymn = 0;
|
||||
|
||||
if (wordToFind.includes(':')) {
|
||||
|
@ -228,11 +227,7 @@ export function clearWordForm() {
|
|||
document.getElementById('wordPartOfSpeech').value = '';
|
||||
document.getElementById('wordDefinition').value = '';
|
||||
document.getElementById('wordDetails').value = '';
|
||||
|
||||
document.getElementById('templateSelect').value = '';
|
||||
document.getElementById('wordEtymology').value = '';
|
||||
document.getElementById('wordRelated').value = '';
|
||||
document.getElementById('wordPrincipalParts').value = '';
|
||||
|
||||
document.getElementById('wordName').focus();
|
||||
}
|
||||
|
@ -274,24 +269,11 @@ export function updateWord(word, wordId) {
|
|||
console.error('Could not find word to update');
|
||||
addMessage('Could not find word to update. Please refresh your browser and try again.', 10000, 'error');
|
||||
} else {
|
||||
const isPublic = hasToken() && window.currentDictionary.settings.isPublic;
|
||||
const { sortByDefinition } = window.currentDictionary.settings;
|
||||
const existingWord = window.currentDictionary.words[wordIndex];
|
||||
const needsReRender = (sortByDefinition && word.definition !== existingWord.definition)
|
||||
|| (!sortByDefinition && word.name !== existingWord.name);
|
||||
word.lastUpdated = getTimestampInSeconds();
|
||||
word.createdOn = existingWord.createdOn;
|
||||
word.createdOn = window.currentDictionary.words[wordIndex].createdOn;
|
||||
window.currentDictionary.words[wordIndex] = word;
|
||||
addMessage('Word Updated Successfully');
|
||||
|
||||
if (needsReRender) {
|
||||
sortWords(true);
|
||||
} else {
|
||||
saveDictionary(false);
|
||||
document.getElementById(wordId.toString()).outerHTML = renderWord(window.currentDictionary.words[wordIndex], isPublic);
|
||||
setupWordOptionButtons();
|
||||
setupWordOptionSelections();
|
||||
}
|
||||
sortWords(true);
|
||||
|
||||
if (hasToken()) {
|
||||
import('./account/index.js').then(account => {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
* [Referencing Other Words](#referencing-other-words)
|
||||
* [Maximizing Large Text Boxes](#maximizing-large-text-boxes)
|
||||
* [IPA Auto-Fill Fields](#ipa-auto-fill-fields)
|
||||
* [Advanced Fields](#advanced-fields)
|
||||
* [Entry Management](#entry-management)
|
||||
* [Search/Filter](#searchfilter)
|
||||
* [The Settings Window](#the-settings-window)
|
||||
|
@ -63,28 +62,13 @@ If you have more than one word with the same spelling, the duplicate words will
|
|||
If you need more space to see what you are entering into a word's Details field or any other long text field with a "Maximize" button, clicking "Maximize" will give you a larger view of the text box to enter text in. When you're done writing, click either the "Done" or × button or any of the darker space outside of the larger view, and your text will be in the original text area. It will even preserve your cursor position or highlighted text so you don't lose your place moving from the larger view back to the small (and vice-versa)!
|
||||
|
||||
### IPA Auto-Fill Fields
|
||||
|
||||
You may notice some buttons around the Pronunciation field in the main word form and some other fields in the Details tab of your Dictionary Settings menu. This indicates that the field is using a special feature that generates [International Phonetic Alphabet](https://en.wikipedia.org/wiki/International_Phonetic_Alphabet) (IPA) characters when typing certain combinations of characters. Click the "Field Help" button below the field for instructions on how to use those fields.
|
||||
|
||||
You can also click the "IPA Table" button to display a maximized table that shows all of the characters in the IPA. Clicking them will add it to the pronunciation field wherever you position the cursor in the field. If you hover over the button for an IPA character that is not on a standard keyboard, you can what character combinations will produce that character when you type it in the field.
|
||||
|
||||
If you do not want to use the IPA field feaure, you can turn it off in the Settings. Click the "Settings" button in the top right side of the website, uncheck "Use IPA Auto-Fill", and click "Save" or "Save & Close". The "IPA Table" and "Field Help" buttons will be removed from all fields they were around, and you can use those fields as normal.
|
||||
|
||||
### Advanced Fields
|
||||
Clicking the button labeled "Show Advanced Fields" underneath the **Details** field on any word form will expand the "Advanced Fields" section for that word list. Clicking the button again when it says "Hide Advanced Fields" will hide the section again to make it so you don't have to scroll down to reach the "Add Word" button. The fields in the Advanced Fields section are detailed below:
|
||||
|
||||
- **Details Field Templates:** A dropdown box with any templates you have previously created (see [Templates for Details Fields](#templates-for-details-fields) in the Settings section below to learn how to create a template). Selecting one of the templates will put that template into the Details field for you, _overwriting **anything** that might have already been written there_.
|
||||
- Each time you select a different template (other than the "None Selected" option), it will overwrite anything in the Details field with the template without warning, so please be careful.
|
||||
- Selecting the "None Selected" option at the top of the list will _not_ change the Details field.
|
||||
- **Etymology / Root Words:** Any words that the current word might have stemmed from originally.
|
||||
- Words written here are treated as word references (see [Referencing Other Words](#referencing-other-words) for how to reference a word or a duplicate word) without requiring the \{\{double-curly-braces\}\} as in the Details field. The words referenced here will appear below the word's details in the list.
|
||||
- Separate each individual root word with a comma.
|
||||
- **Related Words:** Any words that might be related to the current word.
|
||||
- Words written here are treated as word references (see [Referencing Other Words](#referencing-other-words) for how to reference a word or a duplicate word) without requiring the \{\{double-curly-braces\}\} as in the Details field. The words referenced here will appear below the word's details in the list.
|
||||
- Separate each individual related word with a comma.
|
||||
- **Principal Parts:** Any words that someone must know in order to conjugate the current word (see the [Wikipedia entry](https://en.wikipedia.org/wiki/Principal_parts) for more details).
|
||||
- Words written here are treated as word references (see [Referencing Other Words](#referencing-other-words) for how to reference a word or a duplicate word) without requiring the \{\{double-curly-braces\}\} as in the Details field. The words referenced here will appear below the word's details in the list.
|
||||
- Separate each individual principal part with a comma.
|
||||
|
||||
### Entry Management
|
||||
After adding some words to your dictionary, you'll see an "Options" button on each entry. Clicking the button reveals Edit and Delete buttons.
|
||||
|
||||
|
@ -118,25 +102,16 @@ When you have a search term or filter applied, you can see the number of results
|
|||
To display _all_ of your words again, clear your search bar and ensure all the "Include Only" checkboxes are checked.
|
||||
|
||||
### The Settings Window
|
||||
|
||||
Clicking the "Settings" button in the top-right side of Lexiconga will show the Settings window with some options.
|
||||
|
||||
- **Use IPA Auto-Fill:** Check this to use character combinations to input International Phonetic Alphabet characters into Pronunciation fields. Use the "Field Help" button for instructions on how to use it and the "IPA Table" to display available characters. Uncheck it to disable the feature and hide the buttons.
|
||||
- **Use Hotkeys:** Check this to enable keyboard combinations to perform different helpful actions (see [Keyboard Shortcuts](#keyboard-shortcuts) below). Unchecking this disables the feature.
|
||||
- Note: If your browser does not support required features, this will be disabled automatically.
|
||||
- **Show Advanced Fields By Default:** Check this to make the advanced fields show on word forms without needing to click the "Show Advanced Fields" button (see [Advanced Fields](#advanced-fields) above). Unchecking this makes it so you need to click the "Show Advanced Fields" button to show the fields each time you edit a word.
|
||||
- **Default Theme:** Choose what color theme new dictionaries will use when they are created.
|
||||
|
||||
After making changes, click the "Save" or "Save & Close" button to save your changes.
|
||||
|
||||
#### Templates for Details Fields
|
||||
Below the "Default Theme" selector is the template editor. Either click "Create New Template" or choose one from the "Saved Templates" dropdown to begin editing the template. Once a new template is created or a saved template is selected, new fields will appear labeled "Template Name" and "Template," plus a "Save Template" and "Delete Template" button.
|
||||
|
||||
You can modify the template's name by editing the "Template Name" field, and whatever you set in the "Template" text area will be used as the template in the Details field of a word form if it is selected (see [Advanced Fields](#advanced-fields) above for more about how this is used).
|
||||
|
||||
After making any changes to a template, click the "Save Template" button below the "Template" field to save it to your browser. Templates are only stored in the browser they were created on and _do not_ get uploaded to your account (if you have one). If you create a template, it will _not be available on any other web browser_ unless you re-create it!
|
||||
|
||||
Clicking the "Delete Template" button will prompt you to confirm that you want to delete it, and if you confirm, it will permanently delete the currently selected template from your browser. There is no way to recover deleted templates!
|
||||
|
||||
### The Dictionary Settings Window
|
||||
|
||||
Clicking the "Edit" button under your dictionary's name will display a window with tabs that each contain different fields and options.
|
||||
|
|
|
@ -134,7 +134,7 @@ switch ($view) {
|
|||
oldLoad && oldLoad();
|
||||
if (UpUp) {
|
||||
UpUp.start({
|
||||
'cache-version': '2.2.0',
|
||||
'cache-version': '2.1.7',
|
||||
'content-url': 'offline.html',
|
||||
'assets': [
|
||||
\"" . implode('","', $files) . "\"
|
||||
|
|
|
@ -15,15 +15,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
|
||||
h4 {
|
||||
display: inline-block;
|
||||
margin: 5px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.share-link {
|
||||
margin-left: $general-padding !important;
|
||||
line-height: 16px !important;
|
||||
|
|
|
@ -12,7 +12,7 @@ html, body {
|
|||
|
||||
header {
|
||||
display: block;
|
||||
padding: 5px ($general-padding / 2);
|
||||
padding: 5px $general-padding;
|
||||
margin: 0 0 5px;
|
||||
|
||||
&#top {
|
||||
|
|
|
@ -109,7 +109,6 @@
|
|||
border-radius: 5px;
|
||||
max-height: 80%;
|
||||
overflow-y: auto;
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
|
@ -197,7 +196,6 @@
|
|||
|
||||
header {
|
||||
position: relative;
|
||||
padding-right: 70px;
|
||||
|
||||
.word-option-button {
|
||||
position: absolute;
|
||||
|
|
|
@ -53,6 +53,7 @@ $mobile-word-form-size: 32px;
|
|||
top: $header-height + ($mobile-word-form-size / 2);
|
||||
left: 0;
|
||||
right: 3%;
|
||||
z-index: 1;
|
||||
|
||||
label:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
|
|
|
@ -143,11 +143,6 @@
|
|||
<a id="expandAdvancedForm" class="small button expand-advanced-form">Show Advanced Fields</a>
|
||||
</label>
|
||||
<div id="advancedForm" class="advanced-word-form" style="display:none;">
|
||||
<label>Details Field Templates
|
||||
<select id="templateSelect" class="template-select">
|
||||
</select>
|
||||
<small>Choose one to fill the details field. (Note: Will erase anything currently there.)</small>
|
||||
</label>
|
||||
<label>Etymology / Root Words<br>
|
||||
<input id="wordEtymology" maxlength="2500" placeholder="comma,separated,root,words">
|
||||
</label>
|
||||
|
@ -244,33 +239,9 @@
|
|||
<option value="grape">Grape</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<h4>Templates for Details Fields</h4>
|
||||
<p>Templates created here are saved only to your local browser.</p>
|
||||
<label>Saved Templates <a id="createTemplateButton" class="label-button">Create New Template</a>
|
||||
<select id="savedDetailsTemplates" class="template-select">
|
||||
</select>
|
||||
</label>
|
||||
<div id="templateFields" style="display:none;">
|
||||
<label>Template Name
|
||||
<input id="templateNameField"><br />
|
||||
<small>If you have chosen a template above, this will overwrite the chosen template.</small>
|
||||
</label>
|
||||
<label>Template<a class="label-button maximize-button">Maximize</a><br>
|
||||
<textarea id="templateTextarea" placeholder="**Era:**
|
||||
|
||||
**Dialect:**
|
||||
|
||||
etc."></textarea>
|
||||
</label>
|
||||
<a id="saveTemplateButton" class="button">Save Template</a>
|
||||
<a id="deleteTemplateButton" class="red button">Delete Template</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div id="accountActions"></div>
|
||||
<div id="accountSettings"></div>
|
||||
</div>
|
||||
<div id="accountActions"></div>
|
||||
</form>
|
||||
</section>
|
||||
<footer>
|
||||
|
@ -431,7 +402,7 @@ ou=ow"></textarea>
|
|||
<label class="button">Import Words <input type="file" id="importWordsCSV" accept="text/csv, .csv"><br>
|
||||
<small>Import a CSV file of words.</small>
|
||||
</label>
|
||||
<a class="small button" download="Lexiconga_import-template.csv" href="data:text/csv;charset=utf-8,%22word%22,%22pronunciation%22,%22part of speech%22,%22definition%22,%22explanation%22,%22etymology %28comma-separated%29%22,%22related words %28comma-separated%29%22,%22principal parts %28comma-separated%29%22%0A">Download an example file with the correct formatting</a>
|
||||
<a class="small button" download="Lexiconga_import-template.csv" href="data:text/csv;charset=utf-8,%22word%22,%22pronunciation%22,%22part of speech%22,%22definition%22,%22explanation%22%0A">Download an example file with the correct formatting</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
Loading…
Reference in New Issue