Add hotkeys
This commit is contained in:
parent
ad3141ef6e
commit
15bba03e1d
|
@ -168,8 +168,7 @@
|
|||
<footer>
|
||||
<a class="button" id="settingsSave">Save</a>
|
||||
<a class="button" id="settingsSaveAndClose">Save & Close</a>
|
||||
<a class="red button" onclick="this.parentElement.parentElement.parentElement.style.display='none';">Close Without
|
||||
Saving</a>
|
||||
<a class="red button" onclick="this.parentElement.parentElement.parentElement.style.display='none';">Close Without Saving</a>
|
||||
</footer>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -56,6 +56,7 @@ export const DEFAULT_DICTIONARY = {
|
|||
|
||||
export const DEFAULT_SETTINGS = {
|
||||
useIPAPronunciationField: true,
|
||||
useHotkeys: true,
|
||||
};
|
||||
|
||||
export const DEFAULT_PAGE_SIZE = 50;
|
||||
|
|
|
@ -8,6 +8,14 @@ export function showSection(sectionName) {
|
|||
}
|
||||
}
|
||||
|
||||
export function hideDetailsPanel() {
|
||||
document.getElementById('detailsPanel').style.display = 'none';
|
||||
}
|
||||
|
||||
export function getIsDetailsPanelDisplayed() {
|
||||
return document.getElementById('detailsPanel').style.display !== 'none';
|
||||
}
|
||||
|
||||
function showDescription() {
|
||||
const detailsPanel = document.getElementById('detailsPanel');
|
||||
detailsPanel.style.display = 'block';
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
import { confirmEditWord, submitWordForm } from "./wordManagement";
|
||||
import { showSection, getIsDetailsPanelDisplayed, hideDetailsPanel } from "./displayToggles";
|
||||
import { renderInfoModal, renderMaximizedTextbox } from "./render";
|
||||
import { showSearchModal, clearSearchText } from "./search";
|
||||
import { saveAndCloseSettingsModal, openSettingsModal } from "./settings";
|
||||
import { saveAndCloseEditModal, openEditModal } from "./dictionaryManagement";
|
||||
|
||||
export function enableHotKeys() {
|
||||
document.addEventListener('keydown', hotKeyActions);
|
||||
}
|
||||
|
||||
export function disableHotKeys() {
|
||||
document.removeEventListener('keydown', hotKeyActions);
|
||||
}
|
||||
|
||||
export function hotKeyActions(event) {
|
||||
console.log(event);
|
||||
|
||||
if (typeof event.key === 'undefined' || typeof event.ctrlKey === 'undefined' || typeof event.altKey === 'undefined') {
|
||||
console.warn('Browser does not have required event properties for hotkeys.');
|
||||
disableHotKeys();
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.key) {
|
||||
case 'Escape': hideAllModals(); break;
|
||||
case 'Return':
|
||||
case 'Enter': {
|
||||
if (event.ctrlKey) {
|
||||
if (document.getElementById('settingsModal').style.display !== 'none') {
|
||||
saveAndCloseSettingsModal();
|
||||
} else if (document.getElementById('editModal').style.display !== 'none') {
|
||||
saveAndCloseEditModal();
|
||||
} else {
|
||||
submitWord();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
case 'd': if (event.ctrlKey) {event.preventDefault(); toggleDetailsDisplay()} break;
|
||||
case 'e': if (event.ctrlKey) {event.preventDefault(); openEditModal()} break;
|
||||
case 'h': if (event.ctrlKey) {event.preventDefault(); showHelpModal();} break;
|
||||
case 'm': if (event.ctrlKey) {event.preventDefault(); maximizeTextarea();} break;
|
||||
case 's': {
|
||||
if (event.ctrlKey) {
|
||||
event.preventDefault();
|
||||
hideAllModals();
|
||||
if (event.shiftKey) { // This is a failsafe in case the 'S' case below doesn't work for certain browsers
|
||||
openSettingsModal();
|
||||
} else {
|
||||
showSearchModal();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'S': if (event.ctrlKey) { event.preventDefault(); hideAllModals(); openSettingsModal(); } break;
|
||||
case 'x': if (event.ctrlKey) {event.preventDefault(); clearSearchText();} break;
|
||||
}
|
||||
}
|
||||
|
||||
function hideAllModals() {
|
||||
const permanentModals = ['#searchModal', '#settingsModal', '#editModal'];
|
||||
const hideModals = document.querySelectorAll(permanentModals.join(',')),
|
||||
removeModals = document.querySelectorAll('.modal:not(' + permanentModals.join('):not(') + ')');
|
||||
Array.from(hideModals).forEach(modal => modal.style.display = 'none');
|
||||
Array.from(removeModals).forEach(modal => modal.parentElement.removeChild(modal));
|
||||
}
|
||||
|
||||
function toggleDetailsDisplay() {
|
||||
const activeTab = document.querySelector('#detailsSection nav li.active');
|
||||
console.log(activeTab);
|
||||
Array.from(document.querySelectorAll('#detailsSection nav li')).forEach(li => li.classList.remove('active'));
|
||||
if (activeTab) {
|
||||
switch(activeTab.innerText.trim().toLowerCase()) {
|
||||
case 'description': {
|
||||
document.querySelector('#detailsSection nav li:nth-child(2)').classList.add('active');
|
||||
showSection('details');
|
||||
break;
|
||||
}
|
||||
case 'details': {
|
||||
document.querySelector('#detailsSection nav li:nth-child(3)').classList.add('active');
|
||||
showSection('stats');
|
||||
break;
|
||||
}
|
||||
case 'stats': {
|
||||
hideDetailsPanel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
document.querySelector('#detailsSection nav li:nth-child(1)').classList.add('active');
|
||||
showSection('description');
|
||||
}
|
||||
}
|
||||
|
||||
function submitWord() {
|
||||
const focused = document.activeElement;
|
||||
if (focused && focused.id) {
|
||||
const isSubmittableField = focused.id.includes('wordName') || focused.id.includes('wordDefinition') || focused.id.includes('wordDetails');
|
||||
if (isSubmittableField) {
|
||||
if (focused.parentElement.parentElement.classList.contains('edit-form')) {
|
||||
const wordId = parseInt(focused.parentElement.parentElement.id.replace('editForm_', ''));
|
||||
confirmEditWord(wordId);
|
||||
} else {
|
||||
submitWordForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showHelpModal() {
|
||||
import('../markdown/help.md').then(html => {
|
||||
renderInfoModal(html);
|
||||
});
|
||||
}
|
||||
|
||||
function maximizeTextarea() {
|
||||
const focused = document.activeElement;
|
||||
if (focused) {
|
||||
const maximizeButton = focused.parentElement.querySelector('.maximize-button');
|
||||
console.log(maximizeButton);
|
||||
console.log(maximizeButton.parentElement);
|
||||
if (maximizeButton) {
|
||||
renderMaximizedTextbox(maximizeButton);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -277,7 +277,7 @@ export function renderEditForm(wordId = false) {
|
|||
}
|
||||
|
||||
export function renderIPATable(ipaTableButton) {
|
||||
ipaTableButton = typeof ipaTableButton.target === 'undefined' ? ipaTableButton : ipaTableButton.target;
|
||||
ipaTableButton = typeof ipaTableButton.target === 'undefined' || ipaTableButton.target === '' ? ipaTableButton : ipaTableButton.target;
|
||||
const label = ipaTableButton.parentElement.innerText.replace(/(Field Help|IPA Chart)/g, '').trim();
|
||||
const textBox = ipaTableButton.parentElement.querySelector('input');
|
||||
import('./KeyboardFire/phondue/ipa-table.html').then(html => {
|
||||
|
@ -301,7 +301,8 @@ export function renderIPATable(ipaTableButton) {
|
|||
}
|
||||
|
||||
export function renderMaximizedTextbox(maximizeButton) {
|
||||
maximizeButton = typeof maximizeButton.target === 'undefined' ? maximizeButton : maximizeButton.target;
|
||||
maximizeButton = typeof maximizeButton.target === 'undefined' || maximizeButton.target === '' ? maximizeButton : maximizeButton.target;
|
||||
console.log(maximizeButton.parentElement);
|
||||
const label = maximizeButton.parentElement.innerText.replace(/(\*|Maximize)/g, '').trim();
|
||||
const textBox = maximizeButton.parentElement.querySelector('textarea');
|
||||
const modalElement = document.createElement('section');
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
import { cloneObject, getIndicesOf } from "../helpers";
|
||||
import removeDiacritics from "./StackOverflow/removeDiacritics";
|
||||
import { renderWords } from "./render";
|
||||
|
||||
export function showSearchModal() {
|
||||
document.getElementById('searchModal').style.display = 'block';
|
||||
document.getElementById('searchBox').focus();
|
||||
}
|
||||
|
||||
export function clearSearchText() {
|
||||
document.getElementById('searchBox').value = '';
|
||||
document.getElementById('openSearchModal').value = '';
|
||||
renderWords();
|
||||
}
|
||||
|
||||
export function getSearchTerm() {
|
||||
return document.getElementById('searchBox').value;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import {showSection} from './displayToggles';
|
||||
import {showSection, hideDetailsPanel} from './displayToggles';
|
||||
import { renderWords, renderEditForm, renderMaximizedTextbox, renderInfoModal, renderIPATable } from './render';
|
||||
import { validateWord, addWord, confirmEditWord, cancelEditWord, confirmDeleteWord } from './wordManagement';
|
||||
import { removeTags } from '../helpers';
|
||||
import { getNextId } from './utilities';
|
||||
import { confirmEditWord, cancelEditWord, confirmDeleteWord, submitWordForm } from './wordManagement';
|
||||
import { openEditModal, saveEditModal, saveAndCloseEditModal } from './dictionaryManagement';
|
||||
import { goToNextPage, goToPreviousPage, goToPage } from './pagination';
|
||||
import { insertAtCursor, getInputSelection, setSelectionRange } from './StackOverflow/inputCursorManagement';
|
||||
import { usePhondueDigraphs } from './KeyboardFire/phondue/ipaField';
|
||||
import { openSettingsModal, saveSettingsModal, saveAndCloseSettingsModal } from './settings';
|
||||
import { enableHotKeys } from './hotkeys';
|
||||
import { showSearchModal, clearSearchText } from './search';
|
||||
|
||||
export default function setupListeners() {
|
||||
setupDetailsTabs();
|
||||
|
@ -16,6 +16,9 @@ export default function setupListeners() {
|
|||
setupWordForm();
|
||||
setupMobileWordFormButton();
|
||||
setupInfoButtons();
|
||||
if (window.settings.useHotkeys) {
|
||||
enableHotKeys();
|
||||
}
|
||||
}
|
||||
|
||||
function setupDetailsTabs() {
|
||||
|
@ -33,7 +36,7 @@ function setupDetailsTabs() {
|
|||
const isActive = tab.classList.contains('active');
|
||||
tabs.forEach(t => t.classList.remove('active'));
|
||||
if (isActive) {
|
||||
document.getElementById('detailsPanel').style.display = 'none';
|
||||
hideDetailsPanel();
|
||||
} else {
|
||||
tab.classList.add('active');
|
||||
showSection(section);
|
||||
|
@ -96,15 +99,8 @@ function setupSearchBar() {
|
|||
searchBox.addEventListener('input', event => {
|
||||
openSearchModal.value = event.target.value;
|
||||
});
|
||||
clearSearchButton.addEventListener('click', event => {
|
||||
searchBox.value = '';
|
||||
openSearchModal.value = '';
|
||||
renderWords();
|
||||
});
|
||||
openSearchModal.addEventListener('click', () => {
|
||||
document.getElementById('searchModal').style.display = 'block';
|
||||
searchBox.focus();
|
||||
});
|
||||
clearSearchButton.addEventListener('click', clearSearchText);
|
||||
openSearchModal.addEventListener('click', showSearchModal);
|
||||
|
||||
const toggleDetailsCheck = function() {
|
||||
if (searchExactWords.checked) {
|
||||
|
@ -145,26 +141,7 @@ function setupWordForm() {
|
|||
event.preventDefault();
|
||||
return false;
|
||||
});
|
||||
addWordButton.addEventListener('click', () => {
|
||||
const name = document.getElementById('wordName').value,
|
||||
pronunciation = document.getElementById('wordPronunciation').value,
|
||||
partOfSpeech = document.getElementById('wordPartOfSpeech').value,
|
||||
definition = document.getElementById('wordDefinition').value,
|
||||
details = document.getElementById('wordDetails').value;
|
||||
|
||||
const word = {
|
||||
name: removeTags(name).trim(),
|
||||
pronunciation: removeTags(pronunciation).trim(),
|
||||
partOfSpeech: removeTags(partOfSpeech).trim(),
|
||||
definition: removeTags(definition).trim(),
|
||||
details: removeTags(details).trim(),
|
||||
wordId: getNextId(),
|
||||
};
|
||||
|
||||
if (validateWord(word)) {
|
||||
addWord(word);
|
||||
}
|
||||
});
|
||||
addWordButton.addEventListener('click', submitWordForm);
|
||||
|
||||
setupIPAFields();
|
||||
setupMaximizeButtons();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { renderWords } from "./render";
|
||||
import { wordExists, addMessage } from "./utilities";
|
||||
import { wordExists, addMessage, getNextId } from "./utilities";
|
||||
import removeDiacritics from "./StackOverflow/removeDiacritics";
|
||||
import { removeTags } from "../helpers";
|
||||
import { saveDictionary } from "./dictionaryManagement";
|
||||
|
@ -46,6 +46,27 @@ export function sortWords(render) {
|
|||
}
|
||||
}
|
||||
|
||||
export function submitWordForm() {
|
||||
const name = document.getElementById('wordName').value,
|
||||
pronunciation = document.getElementById('wordPronunciation').value,
|
||||
partOfSpeech = document.getElementById('wordPartOfSpeech').value,
|
||||
definition = document.getElementById('wordDefinition').value,
|
||||
details = document.getElementById('wordDetails').value;
|
||||
|
||||
const word = {
|
||||
name: removeTags(name).trim(),
|
||||
pronunciation: removeTags(pronunciation).trim(),
|
||||
partOfSpeech: removeTags(partOfSpeech).trim(),
|
||||
definition: removeTags(definition).trim(),
|
||||
details: removeTags(details).trim(),
|
||||
wordId: getNextId(),
|
||||
};
|
||||
|
||||
if (validateWord(word)) {
|
||||
addWord(word);
|
||||
}
|
||||
}
|
||||
|
||||
export function addWord(word, render = true) {
|
||||
window.currentDictionary.words.push(word);
|
||||
addMessage('Word Created Successfully');
|
||||
|
@ -75,8 +96,9 @@ export function updateWord(word, wordId) {
|
|||
}
|
||||
}
|
||||
|
||||
export function confirmEditWord() {
|
||||
const wordId = parseInt(this.id.replace('editWordButton_', ''));
|
||||
export function confirmEditWord(id) {
|
||||
const wordId = typeof id.target !== 'undefined' ? parseInt(this.id.replace('editWordButton_', '')) : id;
|
||||
console.log(wordId);
|
||||
const name = document.getElementById('wordName_' + wordId).value,
|
||||
pronunciation = document.getElementById('wordPronunciation_' + wordId).value,
|
||||
partOfSpeech = document.getElementById('wordPartOfSpeech_' + wordId).value,
|
||||
|
|
Loading…
Reference in New Issue