Compare commits
3 Commits
7942d628d4
...
be61709d5d
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | be61709d5d | |
Robbie Antenesse | 572b49a660 | |
Robbie Antenesse | a6c290e31b |
|
@ -3,7 +3,7 @@ import { renderDictionaryDetails, renderPartsOfSpeech } from "./render/details";
|
|||
import { renderAll, renderTheme } from "./render";
|
||||
import { removeTags, cloneObject, getTimestampInSeconds, download, slugify } from "../helpers";
|
||||
import { LOCAL_STORAGE_KEY, DEFAULT_DICTIONARY } from "../constants";
|
||||
import { addMessage, getNextId, hasToken } from "./utilities";
|
||||
import { addMessage, getNextId, hasToken, objectValuesAreDifferent } from "./utilities";
|
||||
import { addWord, sortWords } from "./wordManagement";
|
||||
import { migrateDictionary } from './migration';
|
||||
|
||||
|
@ -13,7 +13,7 @@ export function updateDictionary () {
|
|||
}
|
||||
|
||||
export function openEditModal() {
|
||||
const { name, specification, description, partsOfSpeech } = window.currentDictionary;
|
||||
const { name, specification, description, partsOfSpeech, alphabeticalOrder } = window.currentDictionary;
|
||||
const { consonants, vowels, blends } = window.currentDictionary.details.phonology;
|
||||
const { phonotactics, orthography, grammar } = window.currentDictionary.details;
|
||||
const { allowDuplicates, caseSensitive, sortByDefinition, theme, isPublic } = window.currentDictionary.settings;
|
||||
|
@ -22,6 +22,7 @@ export function openEditModal() {
|
|||
document.getElementById('editSpecification').value = specification;
|
||||
document.getElementById('editDescription').value = description;
|
||||
document.getElementById('editPartsOfSpeech').value = partsOfSpeech.join(',');
|
||||
document.getElementById('editAlphabeticalOrder').value = alphabeticalOrder.join(' ');
|
||||
|
||||
document.getElementById('editConsonants').value = consonants.join(' ');
|
||||
document.getElementById('editVowels').value = vowels.join(' ');
|
||||
|
@ -48,46 +49,56 @@ export function openEditModal() {
|
|||
}
|
||||
|
||||
export function saveEditModal() {
|
||||
window.currentDictionary.name = removeTags(document.getElementById('editName').value.trim());
|
||||
window.currentDictionary.specification = removeTags(document.getElementById('editSpecification').value.trim());
|
||||
window.currentDictionary.description = removeTags(document.getElementById('editDescription').value.trim());
|
||||
window.currentDictionary.partsOfSpeech = document.getElementById('editPartsOfSpeech').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
const updatedDictionary = cloneObject(window.currentDictionary);
|
||||
delete updatedDictionary.words;
|
||||
updatedDictionary.name = removeTags(document.getElementById('editName').value.trim());
|
||||
updatedDictionary.specification = removeTags(document.getElementById('editSpecification').value.trim());
|
||||
updatedDictionary.description = removeTags(document.getElementById('editDescription').value.trim());
|
||||
updatedDictionary.partsOfSpeech = document.getElementById('editPartsOfSpeech').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.alphabeticalOrder = document.getElementById('editAlphabeticalOrder').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
|
||||
window.currentDictionary.details.phonology.consonants = document.getElementById('editConsonants').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.phonology.vowels = document.getElementById('editVowels').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.phonology.blends = document.getElementById('editBlends').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.phonotactics.onset = document.getElementById('editOnset').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.phonotactics.nucleus = document.getElementById('editNucleus').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.phonotactics.coda = document.getElementById('editCoda').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.phonotactics.notes = removeTags(document.getElementById('editPhonotacticsNotes').value.trim());
|
||||
updatedDictionary.details.phonology.consonants = document.getElementById('editConsonants').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.phonology.vowels = document.getElementById('editVowels').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.phonology.blends = document.getElementById('editBlends').value.split(' ').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.phonotactics.onset = document.getElementById('editOnset').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.phonotactics.nucleus = document.getElementById('editNucleus').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.phonotactics.coda = document.getElementById('editCoda').value.split(',').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.phonotactics.notes = removeTags(document.getElementById('editPhonotacticsNotes').value.trim());
|
||||
|
||||
window.currentDictionary.details.orthography.translations = document.getElementById('editTranslations').value.split('\n').map(val => val.trim()).filter(val => val !== '');
|
||||
window.currentDictionary.details.orthography.notes = removeTags(document.getElementById('editOrthography').value.trim());
|
||||
window.currentDictionary.details.grammar.notes = removeTags(document.getElementById('editGrammar').value.trim());
|
||||
updatedDictionary.details.orthography.translations = document.getElementById('editTranslations').value.split('\n').map(val => val.trim()).filter(val => val !== '');
|
||||
updatedDictionary.details.orthography.notes = removeTags(document.getElementById('editOrthography').value.trim());
|
||||
updatedDictionary.details.grammar.notes = removeTags(document.getElementById('editGrammar').value.trim());
|
||||
|
||||
window.currentDictionary.settings.allowDuplicates = !document.getElementById('editPreventDuplicates').checked;
|
||||
window.currentDictionary.settings.caseSensitive = document.getElementById('editCaseSensitive').checked;
|
||||
window.currentDictionary.settings.sortByDefinition = document.getElementById('editSortByDefinition').checked;
|
||||
window.currentDictionary.settings.theme = document.getElementById('editTheme').value;
|
||||
updatedDictionary.settings.allowDuplicates = !document.getElementById('editPreventDuplicates').checked;
|
||||
updatedDictionary.settings.caseSensitive = document.getElementById('editCaseSensitive').checked;
|
||||
updatedDictionary.settings.sortByDefinition = document.getElementById('editSortByDefinition').checked;
|
||||
updatedDictionary.settings.theme = document.getElementById('editTheme').value;
|
||||
|
||||
if (hasToken()) {
|
||||
window.currentDictionary.settings.isPublic = document.getElementById('editIsPublic').checked;
|
||||
updatedDictionary.settings.isPublic = document.getElementById('editIsPublic').checked;
|
||||
} else {
|
||||
window.currentDictionary.settings.isPublic = false;
|
||||
updatedDictionary.settings.isPublic = false;
|
||||
}
|
||||
|
||||
addMessage('Saved ' + window.currentDictionary.specification + ' Successfully');
|
||||
saveDictionary();
|
||||
renderTheme();
|
||||
renderDictionaryDetails();
|
||||
renderPartsOfSpeech();
|
||||
sortWords(true);
|
||||
if (objectValuesAreDifferent(updatedDictionary, window.currentDictionary)) {
|
||||
window.currentDictionary = Object.assign(window.currentDictionary, updatedDictionary);
|
||||
|
||||
if (hasToken()) {
|
||||
import('./account/index.js').then(account => {
|
||||
account.uploadDetailsDirect();
|
||||
account.updateChangeDictionaryOption();
|
||||
})
|
||||
renderTheme();
|
||||
renderDictionaryDetails();
|
||||
renderPartsOfSpeech();
|
||||
sortWords(true);
|
||||
|
||||
addMessage('Saved ' + window.currentDictionary.specification + ' Successfully');
|
||||
saveDictionary();
|
||||
|
||||
if (hasToken()) {
|
||||
import('./account/index.js').then(account => {
|
||||
account.uploadDetailsDirect();
|
||||
account.updateChangeDictionaryOption();
|
||||
})
|
||||
}
|
||||
} else {
|
||||
addMessage('No changes made to Dictionary Settings.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { SETTINGS_KEY, DEFAULT_SETTINGS } from "../constants";
|
|||
import { cloneObject, removeTags } from "../helpers";
|
||||
import { usePhondueDigraphs } from "./KeyboardFire/phondue/ipaField";
|
||||
import { renderWords } from "./render/words";
|
||||
import { addMessage, hasToken } from "./utilities";
|
||||
import { addMessage, hasToken, objectValuesAreDifferent } from "./utilities";
|
||||
import { enableHotKeys, disableHotKeys } from "./hotkeys";
|
||||
|
||||
export function loadSettings() {
|
||||
|
@ -27,9 +27,10 @@ export function openSettingsModal() {
|
|||
}
|
||||
|
||||
export function saveSettingsModal() {
|
||||
window.settings.useIPAPronunciationField = document.getElementById('settingsUseIPA').checked;
|
||||
window.settings.useHotkeys = document.getElementById('settingsUseHotkeys').checked;
|
||||
window.settings.defaultTheme = document.getElementById('settingsDefaultTheme').value;
|
||||
const updatedSettings = cloneObject(window.settings);
|
||||
updatedSettings.useIPAPronunciationField = document.getElementById('settingsUseIPA').checked;
|
||||
updatedSettings.useHotkeys = document.getElementById('settingsUseHotkeys').checked;
|
||||
updatedSettings.defaultTheme = document.getElementById('settingsDefaultTheme').value;
|
||||
|
||||
if (hasToken()) {
|
||||
import('./account/index.js').then(account => {
|
||||
|
@ -40,19 +41,30 @@ export function saveSettingsModal() {
|
|||
email = window.account.email;
|
||||
emailField.value = email;
|
||||
}
|
||||
window.account.email = email;
|
||||
window.account.publicName = removeTags(publicName.value).trim();
|
||||
window.account.allowEmails = document.getElementById('accountSettingsAllowEmails').checked;
|
||||
const updatedAccount = cloneObject(window.account);
|
||||
updatedAccount.email = email;
|
||||
updatedAccount.publicName = removeTags(publicName.value).trim();
|
||||
updatedAccount.allowEmails = document.getElementById('accountSettingsAllowEmails').checked;
|
||||
|
||||
const newPassword = document.getElementById('accountSettingsNewPassword').value;
|
||||
|
||||
account.editAccount(Object.assign({ newPassword }, window.account));
|
||||
if (objectValuesAreDifferent(updatedAccount, window.account)) {
|
||||
window.account = Object.assign(window.account, updatedAccount);
|
||||
account.editAccount(Object.assign({ newPassword }, window.account));
|
||||
} else {
|
||||
addMessage('No changes made to Account.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
saveSettings();
|
||||
toggleHotkeysEnabled();
|
||||
toggleIPAPronunciationFields();
|
||||
if (objectValuesAreDifferent(updatedSettings, window.settings)) {
|
||||
window.settings = Object.assign(window.settings, updatedSettings);
|
||||
saveSettings();
|
||||
toggleHotkeysEnabled();
|
||||
toggleIPAPronunciationFields();
|
||||
} else {
|
||||
addMessage('No changes made to Settings.');
|
||||
}
|
||||
}
|
||||
|
||||
export function saveAndCloseSettingsModal() {
|
||||
|
|
|
@ -176,3 +176,19 @@ export function hideAllModals() {
|
|||
export function hasToken() {
|
||||
return window.isOffline !== true && getCookie('token') !== '';
|
||||
}
|
||||
|
||||
export function objectValuesAreDifferent(newObject, oldObject) {
|
||||
let valuesAreDifferent = false;
|
||||
for (let property in newObject) {
|
||||
if (!oldObject.hasOwnProperty(property) || JSON.stringify(newObject[property]) !== JSON.stringify(oldObject[property])) {
|
||||
valuesAreDifferent = true;
|
||||
}
|
||||
if (typeof newObject[property] === 'object' && !Array.isArray(newObject[property])) {
|
||||
valuesAreDifferent = objectValuesAreDifferent(newObject[property], oldObject[property]);
|
||||
}
|
||||
|
||||
if (valuesAreDifferent) break;
|
||||
}
|
||||
|
||||
return valuesAreDifferent;
|
||||
}
|
||||
|
|
|
@ -35,57 +35,65 @@ export function sortWords(render) {
|
|||
const { alphabeticalOrder } = window.currentDictionary;
|
||||
const sortBy = sortByDefinition ? 'definition' : 'name';
|
||||
|
||||
const ordering = {}; // map for efficient lookup of sortIndex
|
||||
for (let i = 0; i < alphabeticalOrder.length; i++) {
|
||||
ordering[alphabeticalOrder[i]] = i;
|
||||
}
|
||||
|
||||
window.currentDictionary.words.sort((wordA, wordB) => {
|
||||
if (wordA[sortBy] === wordB[sortBy]) return 0;
|
||||
|
||||
const aLetters = wordA[sortBy].split('');
|
||||
const bLetters = wordB[sortBy].split('');
|
||||
|
||||
for (let i = 0; i < aLetters.length; i++) {
|
||||
const a = aLetters[i];
|
||||
if (ordering.hasOwnProperty(a)) { // if a is in the alphabet...
|
||||
if (typeof bLetters[i] !== 'undefined') { // and if wordB has a letter at the same position...
|
||||
const b = bLetters[i];
|
||||
if (ordering.hasOwnProperty(b)) { // and b is in the alphabet then compare the letters
|
||||
const aIndex = ordering[a];
|
||||
const bIndex = ordering[b];
|
||||
if (aIndex === bIndex) { // If the letters are the same, then...
|
||||
// If wordA is shorter than wordB and this is wordA's last letter, then sort a first;
|
||||
if (aLetters.length < bLetters.length && i == aLetters.length - 1) return -1;
|
||||
continue; // Otherwise if it is the same letter, check the next letter
|
||||
}
|
||||
return aIndex - bIndex; // If different and both in alphabet, compare alphabetical order
|
||||
}
|
||||
} else {
|
||||
return 1; // If b is shorter than a after looping, then sort a after
|
||||
}
|
||||
} else if (ordering.hasOwnProperty(bLetters[i])) {
|
||||
return 1; // If a is not in the alphabet but b is, sort a after
|
||||
} else {
|
||||
if (typeof bLetters[i] !== 'undefined') { // and if wordB has a letter at the same position...
|
||||
const b = bLetters[i];
|
||||
if (removeDiacritics(a).toLowerCase() === removeDiacritics(b).toLowerCase()) {
|
||||
if (aLetters.length < bLetters.length && i == aLetters.length - 1) return -1;
|
||||
continue;
|
||||
}
|
||||
return removeDiacritics(a).toLowerCase() > removeDiacritics(b).toLowerCase() ? 1 : -1;
|
||||
} else {
|
||||
return 1; // If b is shorter than a after looping, then sort a after
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('done looping, comparing normally:', wordA[sortBy], wordB[sortBy]);
|
||||
|
||||
// If after looping, the alphabet is still different, just compare the words alphabetically.
|
||||
if (removeDiacritics(wordA[sortBy]).toLowerCase() === removeDiacritics(wordB[sortBy]).toLowerCase()) return 0;
|
||||
return removeDiacritics(wordA[sortBy]).toLowerCase() > removeDiacritics(wordB[sortBy]).toLowerCase() ? 1 : -1;
|
||||
// Sort normally first
|
||||
return wordA[sortBy].localeCompare(wordB[sortBy], 'en', { sensitivity: 'base' }); // This is the smart way to do the below!
|
||||
// if (removeDiacritics(wordA[sortBy]).toLowerCase() === removeDiacritics(wordB[sortBy]).toLowerCase()) return 0;
|
||||
// return removeDiacritics(wordA[sortBy]).toLowerCase() > removeDiacritics(wordB[sortBy]).toLowerCase() ? 1 : -1;
|
||||
});
|
||||
|
||||
if (alphabeticalOrder.length > 0) {
|
||||
// If there's an alphabetical order specified, sort by that after! Any letters not in the alphabet will be unsorted, keeping them in ASCII order
|
||||
const ordering = {}; // map for efficient lookup of sortIndex
|
||||
for (let i = 0; i < alphabeticalOrder.length; i++) {
|
||||
ordering[alphabeticalOrder[i]] = i + 1; // Add 1 to prevent 0 from resolving to false
|
||||
}
|
||||
|
||||
window.currentDictionary.words.sort((wordA, wordB) => {
|
||||
// console.log(alphabeticalOrder, ordering);
|
||||
// console.log('comparing:', wordA[sortBy], wordB[sortBy]);
|
||||
if (wordA[sortBy] === wordB[sortBy]) return 0;
|
||||
|
||||
const aLetters = wordA[sortBy].split('');
|
||||
const bLetters = wordB[sortBy].split('');
|
||||
|
||||
for (let i = 0; i < aLetters.length; i++) {
|
||||
const a = aLetters[i];
|
||||
const b = bLetters[i];
|
||||
// console.log('comparing letters', a, b);
|
||||
if (!b) {
|
||||
// console.log('no b, ', wordA[sortBy], 'is longer than', wordB[sortBy]);
|
||||
return 1;
|
||||
}
|
||||
if (!ordering[a] && !ordering[b]) {
|
||||
// console.log('a and b not in dictionary:', a, b, 'continuing to the next letter');
|
||||
continue;
|
||||
}
|
||||
if (!ordering[a]) {
|
||||
// console.log('a is not in dictionary:', a, 'moving back:', wordA[sortBy]);
|
||||
return 1;
|
||||
}
|
||||
if (!ordering[b]) {
|
||||
// console.log('b is not in dictionary:', b, 'moving forward:', wordA[sortBy]);
|
||||
return -1;
|
||||
}
|
||||
if (ordering[a] === ordering[b]) {
|
||||
// console.log('letters are the same order:', a, b);
|
||||
if (aLetters.length < bLetters.length && i === aLetters.length - 1) {
|
||||
// console.log(a, 'is shorter than', b);
|
||||
return -1;
|
||||
}
|
||||
// console.log(a, 'is the same as', b, 'continuing to the next letter');
|
||||
continue;
|
||||
}
|
||||
// console.log('comparing order:', a, b, 'result:', ordering[a] - ordering[b]);
|
||||
return ordering[a] - ordering[b];
|
||||
}
|
||||
|
||||
// console.log('all of the letters were dumb, no sort');
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
saveDictionary(false);
|
||||
|
||||
|
|
|
@ -255,8 +255,12 @@
|
|||
<label>Parts of Speech <small>(Comma Separated List)</small><br>
|
||||
<input id="editPartsOfSpeech" maxlength="2500" placeholder="Noun,Adjective,Verb">
|
||||
</label>
|
||||
<label>Alphabetical Order <small>(Comma Separated List. Include every letter!)</small><br>
|
||||
<input id="editAlphabeticalOrder" disabled value="English Alphabet">
|
||||
<label>Alphabetical Order <small>(Space Separated List)</small><br>
|
||||
<input id="editAlphabeticalOrder" placeholder="a A b B c C d D ...">
|
||||
<a class="label-help-button" onclick="alert('Include every letter and case! Any letters used in your words that are not specified will be sorted in the default order below your alphabetically custom-sorted words.\n\nLexiconga can only sort by single characters and will sort by the words AS ENTERED, not using orthographic translation.')">
|
||||
Field Info
|
||||
</a>
|
||||
<small>Leave blank for default (case-insensitive ASCII/Unicode sorting)</small>
|
||||
</label>
|
||||
<h3>Phonology</h3>
|
||||
<div class="split three">
|
||||
|
|
Loading…
Reference in New Issue