Commit cfd9a1bf authored by ransome1's avatar ransome1
Browse files

Created more modules, added timeout to file watcher, fixed appx build

parent 8a2cbf64
{
"env": {
"browser": true,
"es2021": true
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
......
......@@ -24,3 +24,5 @@ src/__tests__
build/
test/
package-lock.json
.vs/
.vscode/
{
"name": "sleek",
"productName": "sleek",
"version": "1.0.6-3",
"version": "1.0.6",
"description": "Todo app based on todo.txt for Linux, Windows and MacOS, free and open-source",
"synopsis": "Todo app based on todo.txt for Linux, Windows and MacOS, free and open-source",
"category": "ProjectManagement",
......@@ -47,6 +47,7 @@
"deb",
"freebsd",
"rpm",
"pacman",
"AppImage"
]
},
......@@ -88,6 +89,9 @@
"deb": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"pacman": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"freebsd": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
......@@ -98,7 +102,6 @@
"build:appx": "electron-builder -w appx --publish never",
"build:pacman": "electron-builder -l pacman --publish never",
"build:appimage": "electron-builder -l AppImage --publish never",
"pack": "electron-builder --dir",
"lint": "eslint --ext .js, src --ext .mjs, src",
"jest": "jest",
"mocha": "mocha",
......@@ -113,18 +116,18 @@
"electron-windows-badge": "^1.1.0",
"i18next": "^20.2.2",
"i18next-fs-backend": "^1.1.1",
"jstodotxt": "^0.9.0",
"jstodotxt": "^0.10.0",
"marked": "^2.0.3",
"sass": "^1.34.1",
"vanillajs-datepicker": "^1.1.4"
},
"devDependencies": {
"chai": "^4.3.4",
"electron": "^12.0.5",
"electron": "^13.1.1",
"electron-builder": "22.10.5",
"eslint": "^7.25.0",
"jest": "^26.6.3",
"mocha": "^8.3.2",
"sass": "^1.34.1",
"spectron": "^14.0.0",
"stylelint": "^13.13.1",
"stylelint-config-sass-guidelines": "^8.0.0"
......
......@@ -9,7 +9,7 @@ class Store {
if(process.env.PORTABLE_EXECUTABLE_FILE) {
userDataPath = path.join(path.dirname(process.env.PORTABLE_EXECUTABLE_FILE), 'config', 'sleek');
if(!fs.existsSync(userDataPath)) fs.mkdirSync(userDataPath, {recursive: true});
} else if(!process.env.PORTABLE_EXECUTABLE_FILE && process.platform==="win32") {
} else if(!process.env.PORTABLE_EXECUTABLE_FILE && !process.windowsStore && process.platform==="win32") {
userDataPath = path.dirname(process.execPath);
if(!fs.existsSync(userDataPath)) fs.mkdirSync(userDataPath, {recursive: true});
} else {
......
......@@ -506,7 +506,7 @@
<tr>
<td><a href="https://github.com/matomo-org/matomo" target="_blank">Matomo</a></td>
<td><a href="https://github.com/paulmillr/chokidar" target="_blank">chokidar</a></td>
<td></td>
<td><a href="https://github.com/viktor-shmigol/electron-windows-badge/" target="_blank">Electron Windows Badge</a></td>
<td></td>
</tr>
</table>
......@@ -732,9 +732,6 @@
</p>
</article>
</section>
<script defer src="../node_modules/jstodotxt/jsTodoExtensions.js"></script>
<script defer src="../node_modules/jstodotxt/jsTodoTxt.js"></script>
<script defer src="../node_modules/marked/marked.min.js"></script>
<script defer type="module" src="render.js"></script>
</body>
</html>
"use strict";
import { modal, userData, _paq, translations } from "../render.js";
import { modal, userData, appData, setUserData, translations, handleError, setTheme } from "../render.js";
import { _paq } from "./matomo.mjs";
import { createModalJail } from "../configs/modal.config.mjs";
const reviewSourceforge = document.getElementById("reviewSourceforge");
......@@ -8,7 +9,6 @@ const shareFacebook = document.getElementById("shareFacebook");
const shareLinkedin = document.getElementById("shareLinkedin");
const shareTwitter = document.getElementById("shareTwitter");
const submitIssuesOnGithub = document.getElementById("submitIssuesOnGithub");
const contentTabs = document.querySelectorAll('.modal.content ul li');
const contentTabsCards = document.querySelectorAll('.modal.content section');
const helpTab1Title = document.getElementById("helpTab1Title");
......@@ -69,6 +69,14 @@ const helpTabKeyboardTR15TD1 = document.getElementById("helpTabKeyboardTR15TD1")
const helpTabKeyboardTR16TD1 = document.getElementById("helpTabKeyboardTR16TD1");
const helpTabKeyboardTR17TD1 = document.getElementById("helpTabKeyboardTR17TD1");
const toggleDarkmode = document.getElementById("toggleDarkmode");
const toggleNotifications = document.getElementById("toggleNotifications");
const toggleTray = document.getElementById("toggleTray");
helpTabKeyboardSubtitle.innerHTML = translations.helpTabKeyboardSubtitle;
helpTabKeyboardTR13TD1.innerHTML = translations.helpTabKeyboardTR13TD1;
helpTabKeyboardTR14TD1.innerHTML = translations.helpTabKeyboardTR14TD1;
......@@ -132,6 +140,7 @@ reviewSourceforge.innerHTML = translations.reviewSourceforge;
reviewWindowsStore.innerHTML = translations.reviewWindowsStore;
submitIssuesOnGithub.innerHTML = translations.submitIssuesOnGithub;
contentTabs.forEach(tab => tab.addEventListener("click", function() {
contentTabs.forEach(function(tab) {
tab.classList.remove("is-active");
......@@ -141,6 +150,34 @@ contentTabs.forEach(tab => tab.addEventListener("click", function() {
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Content", "Click on " + this.firstElementChild.innerHTML, this.classList[0]]);
}));
settingsLanguage.onchange = function() {
userData.language = this.value;
window.api.send("userData", ["language", userData.language]);
window.api.send("changeLanguage", this.value);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Settings", "Language changed to: " + this.value]);
}
toggleNotifications.onclick = function() {
//notifications = this.checked;
setUserData('notifications', this.checked);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Setting", "Click on Notifications", this.checked])
}
toggleDarkmode.onclick = function() {
setTheme(true);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Setting", "Click on Dark mode", this.checked])
}
toggleTray.onclick = function() {
setUserData("tray", this.checked);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Setting", "Click on Tray", this.checked])
// restart
window.api.send("restart");
}
toggleNotifications.checked = userData.notifications;
function showTab(tab) {
contentTabsCards.forEach(function(el) {
......@@ -148,8 +185,9 @@ function showTab(tab) {
});
document.getElementById(tab).classList.add("is-active");
}
function showContent(section) {
function showContent(id) {
try {
const section = document.getElementById(id);
// in case a content window was open, it will be closed
modal.forEach(function(el) {
el.classList.remove("is-active");
......@@ -177,4 +215,50 @@ function showContent(section) {
}
}
function setFriendlyLanguageNames() {
try {
appData.languages.forEach((language) => {
// generate user friendly entries for language selection menu
let friendlyLanguageName;
switch (language) {
case "de":
friendlyLanguageName = "Deutsch"
break;
case "en":
friendlyLanguageName = "English"
break;
case "it":
friendlyLanguageName = "Italiano"
break;
case "es":
friendlyLanguageName = "Español"
break;
case "fr":
friendlyLanguageName = "Français"
break;
case "zh":
friendlyLanguageName = "Chinese (简体中文)"
break;
default:
return;
}
var option = document.createElement("option");
option.text = friendlyLanguageName;
option.value = language;
if(language===userData.language) option.selected = true;
settingsLanguage.add(option);
});
return Promise.resolve("Success: Friendly language names added to select field in settings");
} catch(error) {
error.functionName = setFriendlyLanguageNames.name;
return Promise.reject(error);
}
}
setFriendlyLanguageNames().then(function(response) {
console.info(response);
}).catch(function(error) {
handleError(error);
});
export { showContent };
"use strict";
import { translations, userData, _paq } from "../render.js";
import { translations, userData } from "../render.js";
import { _paq } from "./matomo.mjs";
import { resizeInput } from "./form.mjs";
import { RecExtension } from "./todotxtExtensions.mjs";
import "../../node_modules/jstodotxt/jsTodoExtensions.js";
import "../../node_modules/jstodotxt/jsTodoTxt.js";
import Datepicker from "../../node_modules/vanillajs-datepicker/js/Datepicker.js";
import de from "../../node_modules/vanillajs-datepicker/js/i18n/locales/de.js";
import it from "../../node_modules/vanillajs-datepicker/js/i18n/locales/it.js";
......@@ -19,15 +22,15 @@ datePickerInput.addEventListener("changeDate", function (e) {
// we only update the object if there is a date selected. In case of a refresh it would throw an error otherwise
if(e.detail.date) {
// generate the object on what is written into input, so we don't overwrite previous inputs of user
let todo = new TodoTxtItem(document.getElementById("modalFormInput").value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
let todo = new TodoTxtItem(modalFormInput.value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
todo.due = new Date(e.detail.date);
todo.dueString = new Date(e.detail.date.getTime() - (e.detail.date.getTimezoneOffset() * 60000 )).toISOString().split("T")[0];
// if suggestion box was open, it needs to be closed
autoCompleteContainer.classList.remove("is-active");
autoCompleteContainer.blur();
// if a due date is set, the recurrence picker will be shown);
document.getElementById("modalFormInput").value = todo.toString();
document.getElementById("modalFormInput").focus();
modalFormInput.value = todo.toString();
modalFormInput.focus();
resizeInput(datePickerInput);
datePicker.hide();
// trigger matomo event
......@@ -51,10 +54,10 @@ const datePicker = new Datepicker(datePickerInput, {
}
});
document.querySelector(".datepicker .clear-btn").onclick = function() {
let todo = new TodoTxtItem(document.getElementById("modalFormInput").value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
let todo = new TodoTxtItem(modalFormInput.value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
todo.due = undefined;
todo.dueString = undefined;
document.getElementById("modalFormInput").value = todo.toString();
modalFormInput.value = todo.toString();
resizeInput(datePickerInput);
datePicker.hide();
}
......
"use strict";
import { setUserData, userData, handleError, _paq } from "../render.js";
import { setUserData, userData, handleError } from "../render.js";
import { _paq } from "./matomo.mjs";
import { navBtns } from "./navigation.mjs";
import { getHandleElement, startDragging } from "./drawer_handle.mjs";
......@@ -82,7 +83,6 @@ export function showDrawer(variable, buttonId, drawerId) {
setUserData("filterDrawer", false);
return Promise.resolve("Success: Drawer closed");
}
const viewToggleSortCompletedLast = document.getElementById("viewToggleSortCompletedLast");
switch (drawerId) {
case "viewDrawer":
// highlight persisted selection in dropdown
......
"use strict";
import { resetModal, handleError, userData, setUserData, translations } from "../render.js";
import { _paq } from "./matomo.mjs";
import { createModalJail } from "../configs/modal.config.mjs";
const btnOpenTodoFile = document.getElementById("btnOpenTodoFile");
const modalChangeFile = document.getElementById("modalChangeFile");
const modalChangeFileTable = document.getElementById("modalChangeFileTable");
function showFiles() {
try {
let files = userData.files;
modalChangeFile.classList.add("is-active");
modalChangeFile.focus();
modalChangeFileTable.innerHTML = null;
for (let file in files) {
// skip if file doesn't exist
modalChangeFileTable.classList.add("files");
let row = modalChangeFileTable.insertRow(0);
let cell1 = row.insertCell(0);
let cell2 = row.insertCell(1);
let cell3 = row.insertCell(2);
row.setAttribute("data-path", files[file][1]);
if(files[file][0]===1) {
cell1.innerHTML = "<button class=\"button\" disabled>" + translations.selected + "</button>";
} else {
cell1.innerHTML = "<button class=\"button is-link\" tabindex=\"0\">" + translations.select + "</button>";
cell1.onclick = function() {
setUserData("selectedFilters", []);
resetModal().then(response => {
window.api.send("startFileWatcher", this.parentElement.getAttribute("data-path"));
console.info(response);
}).catch(error => {
handleError(error);
});
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "File", "Click on select button"]);
}
cell3.innerHTML = "<a href=\"#\" tabindex=\"0\"><i class=\"fas fa-minus-circle\"></i></a>";
cell3.title = translations.delete;
cell3.onclick = function() {
let path = this.parentElement.getAttribute("data-path");
// remove file from files array
files = files.filter(function(file) {
return file[1] != path;
});
// persist new files array
setUserData("files", files);
// after array is updated, open the modal again
showFiles().then(response => {
console.info(response);
}).catch(error => {
handleError(error);
});
}
}
cell2.innerHTML = files[file][1];
}
// create the modal jail, so tabbing won't leave modal
createModalJail(modalChangeFile);
return Promise.resolve("Success: File changer modal built and opened");
} catch (error) {
return Promise.reject(error);
}
}
btnOpenTodoFile.onclick = function() {
if(typeof userData.files === "object" && userData.files.length>0) {
showFiles().then(response => {
console.info(response);
}).catch(error => {
handleError(error);
});
} else {
window.api.send("openOrCreateFile", "open");
}
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Menu", "Click on Files"]);
}
"use strict";
import { userData, handleError, translations, setUserData, startBuilding, _paq } from "../render.js";
import { items, generateGroups, generateTable } from "./todos.mjs";
import { userData, handleError, translations, setUserData, startBuilding } from "../render.js";
import { _paq } from "./matomo.mjs";
import { items } from "./todos.mjs";
import { isToday, isPast, isFuture } from "./date.mjs";
const todoTableSearch = document.getElementById("todoTableSearch");
......@@ -68,7 +69,7 @@ function deleteFilter(filter, category) {
return Promise.reject(error);
}
}
function filterItems(items, searchString) {
function filterItems(items) {
try {
// selected filters are empty, unless they were persisted
if(userData.selectedFilters && userData.selectedFilters.length>0) {
......@@ -111,8 +112,7 @@ function filterItems(items, searchString) {
}
// apply filters or filter by search string
items = items.filter(function(item) {
if(todoTableSearch.value) searchString = todoTableSearch.value;
if((searchString || todoTableSearch.value) && item.toString().toLowerCase().indexOf(searchString.toLowerCase()) === -1) return false;
if(todoTableSearch.value && item.toString().toLowerCase().indexOf(todoTableSearch.value.toLowerCase()) === -1) return false;
if(!userData.showCompleted && item.complete) return false;
if(!userData.showDueIsToday && item.due && isToday(item.due)) return false;
if(!userData.showDueIsPast && item.due && isPast(item.due)) return false;
......
"use strict";
import { resetModal, handleError, userData, setUserData, translations, _paq } from "../render.js";
import { resetModal, handleError, userData, setUserData, translations } from "../render.js";
import { _paq } from "./matomo.mjs";
import { RecExtension } from "./todotxtExtensions.mjs";
import "../../node_modules/jstodotxt/jsTodoExtensions.js";
import "../../node_modules/jstodotxt/jsTodoTxt.js";
import { generateFilterData } from "./filters.mjs";
import { items, item, setTodoComplete } from "./todos.mjs";
import { datePickerInput } from "./datePicker.mjs";
......@@ -12,13 +15,14 @@ const recurrencePickerInput = document.getElementById("recurrencePickerInput");
const modalTitle = document.getElementById("modalTitle");
const modalFormAlert = document.getElementById("modalFormAlert");
const modalForm = document.getElementById("modalForm");
const modalFormInput = document.getElementById("modalFormInput");
const modalFormInputResize = document.getElementById("modalFormInputResize");
const modalBackground = document.querySelectorAll('.modal-background');
const modalClose = document.querySelectorAll('.close');
const priorityPicker = document.getElementById("priorityPicker");
const btnItemStatus = document.getElementById("btnItemStatus");
document.getElementById("modalFormInput").placeholder = translations.formTodoInputPlaceholder;
modalFormInput.placeholder = translations.formTodoInputPlaceholder;
btnItemStatus.onclick = function() {
setTodoComplete(this.parentElement.parentElement.parentElement.parentElement.getAttribute("data-item")).then(response => {
......@@ -41,7 +45,7 @@ modalFormInputResize.onclick = function() {
if(userData.matomoEvents) _paq.push(["trackEvent", "Form", "Click on Resize"]);
}
document.getElementById("modalFormInput").addEventListener("keyup", event => {
modalFormInput.addEventListener("keyup", event => {
// do not show suggestion container if Escape has been pressed
if(event.key==="Escape") return false;
modalFormInputEvent();
......@@ -112,31 +116,31 @@ function getCaretPosition(inputId) {
}
function positionAutoCompleteContainer() {
// Adjust position of suggestion box to input field
let modalFormInputPosition = document.getElementById("modalFormInput").getBoundingClientRect();
autoCompleteContainer.style.width = document.getElementById("modalFormInput").offsetWidth + "px";
autoCompleteContainer.style.top = modalFormInputPosition.top + document.getElementById("modalFormInput").offsetHeight+2 + "px";
let modalFormInputPosition = modalFormInput.getBoundingClientRect();
autoCompleteContainer.style.width = modalFormInput.offsetWidth + "px";
autoCompleteContainer.style.top = modalFormInputPosition.top + modalFormInput.offsetHeight+2 + "px";
autoCompleteContainer.style.left = modalFormInputPosition.left + "px";
}
function modalFormInputEvent() {
positionAutoCompleteContainer();
// if textarea, resize to content length
if(document.getElementById("modalFormInput").tagName==="TEXTAREA") {
document.getElementById("modalFormInput").style.height="auto";
document.getElementById("modalFormInput").style.height= document.getElementById("modalFormInput").scrollHeight+"px";
if(modalFormInput.tagName==="TEXTAREA") {
modalFormInput.style.height="auto";
modalFormInput.style.height= modalFormInput.scrollHeight+"px";
}
let autoCompleteValue ="";
let autoCompletePrefix = "";
let caretPosition = getCaretPosition(document.getElementById("modalFormInput"));
let caretPosition = getCaretPosition(modalFormInput);
let autoCompleteCategory = "";
if((document.getElementById("modalFormInput").value.charAt(caretPosition-2) === " " || document.getElementById("modalFormInput").value.charAt(caretPosition-2) === "\n") && (document.getElementById("modalFormInput").value.charAt(caretPosition-1) === "@" || document.getElementById("modalFormInput").value.charAt(caretPosition-1) === "+")) {
autoCompleteValue = document.getElementById("modalFormInput").value.substr(caretPosition, document.getElementById("modalFormInput").value.lastIndexOf(" ")).split(" ").shift();
autoCompletePrefix = document.getElementById("modalFormInput").value.charAt(caretPosition-1);
} else if(document.getElementById("modalFormInput").value.charAt(caretPosition) === " ") {
autoCompleteValue = document.getElementById("modalFormInput").value.substr(document.getElementById("modalFormInput").value.lastIndexOf(" ", caretPosition-1)+2).split(" ").shift();
autoCompletePrefix = document.getElementById("modalFormInput").value.charAt(document.getElementById("modalFormInput").value.lastIndexOf(" ", caretPosition-1)+1);
} else if(document.getElementById("modalFormInput").value.charAt(document.getElementById("modalFormInput").value.lastIndexOf(" ", caretPosition)+1) === "@" || document.getElementById("modalFormInput").value.charAt(document.getElementById("modalFormInput").value.lastIndexOf(" ", caretPosition)+1) === "+") {
autoCompleteValue = document.getElementById("modalFormInput").value.substr(document.getElementById("modalFormInput").value.lastIndexOf(" ", caretPosition)+2).split(" ").shift();
autoCompletePrefix = document.getElementById("modalFormInput").value.charAt(document.getElementById("modalFormInput").value.lastIndexOf(" ", caretPosition)+1);
if((modalFormInput.value.charAt(caretPosition-2) === " " || modalFormInput.value.charAt(caretPosition-2) === "\n") && (modalFormInput.value.charAt(caretPosition-1) === "@" || modalFormInput.value.charAt(caretPosition-1) === "+")) {
autoCompleteValue = modalFormInput.value.substr(caretPosition, modalFormInput.value.lastIndexOf(" ")).split(" ").shift();
autoCompletePrefix = modalFormInput.value.charAt(caretPosition-1);
} else if(modalFormInput.value.charAt(caretPosition) === " ") {
autoCompleteValue = modalFormInput.value.substr(modalFormInput.value.lastIndexOf(" ", caretPosition-1)+2).split(" ").shift();
autoCompletePrefix = modalFormInput.value.charAt(modalFormInput.value.lastIndexOf(" ", caretPosition-1)+1);
} else if(modalFormInput.value.charAt(modalFormInput.value.lastIndexOf(" ", caretPosition)+1) === "@" || modalFormInput.value.charAt(modalFormInput.value.lastIndexOf(" ", caretPosition)+1) === "+") {
autoCompleteValue = modalFormInput.value.substr(modalFormInput.value.lastIndexOf(" ", caretPosition)+2).split(" ").shift();
autoCompletePrefix = modalFormInput.value.charAt(modalFormInput.value.lastIndexOf(" ", caretPosition)+1);
} else {
autoCompleteContainer.classList.remove("is-active");
autoCompleteContainer.blur();
......@@ -180,7 +184,7 @@ function setPriority(priority) {
});
}
}
let todo = new TodoTxtItem(document.getElementById("modalFormInput").value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
let todo = new TodoTxtItem(modalFormInput.value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
if((priority==="down" || priority==="up") && !todo.priority) {
todo.priority = "A";
} else if(priority==="up" && todo.priority!="a") {
......@@ -193,7 +197,7 @@ function setPriority(priority) {
todo.priority = null;
}
if(todo.priority===null || todo.priority.match(/[a-z]/i)) {
document.getElementById("modalFormInput").value = todo.toString();
modalFormInput.value = todo.toString();
setPriorityInput(todo.priority);
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Form", "Priority changed to: " + todo.priority]);
......@@ -207,7 +211,7 @@ function setPriority(priority) {
}
function setDueDate(days) {
try {
const todo = new TodoTxtItem(document.getElementById("modalFormInput").value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
const todo = new TodoTxtItem(modalFormInput.value, [ new DueExtension(), new HiddenExtension(), new RecExtension() ]);
if(days===0) {
todo.due = undefined;
todo.dueString = undefined;
......@@ -218,7 +222,7 @@ function setDueDate(days) {
todo.due = new Date(new Date().setDate(new Date().getDate() + days));
todo.dueString = todo.due.toISOString().substr(0, 10);
}
document.getElementById("modalFormInput").value = todo.toString();
modalFormInput.value = todo.toString();
return Promise.resolve("Success: Due date changed to " + todo.dueString)
} catch(error) {
error.functionName = setDueDate.name;
......@@ -234,8 +238,8 @@ function show(todo, templated) {
datePickerInput.value = null;
recurrencePickerInput.value = null;
modalForm.classList.toggle("is-active");
document.getElementById("modalFormInput").value = null;
document.getElementById("modalFormInput").focus();
modalFormInput.value = null;
modalFormInput.focus();
modalFormAlert.innerHTML = null;
modalFormAlert.parentElement.classList.remove("is-active", 'is-warning', 'is-danger');
// here we configure the headline and the footer buttons
......@@ -252,18 +256,18 @@ function show(todo, templated) {
// erase the original creation date and description
todo.date = null;
todo.text = "____________";
document.getElementById("modalFormInput").value = todo.toString();
modalFormInput.value = todo.toString();
modalTitle.innerHTML = translations.addTodo;
// automatically select the placeholder description
let selectStart = document.getElementById("modalFormInput").value.indexOf(todo.text);
let selectStart = modalFormInput.value.indexOf(todo.text);
let selectEnd = selectStart + todo.text.length;
document.getElementById("modalFormInput").setSelectionRange(selectStart, selectEnd);
modalFormInput.setSelectionRange(selectStart, selectEnd);
btnItemStatus.classList.remove("is-active");
} else {
// this is an existing todo task to be edited
// put the initially passed todo to the modal data field
modalForm.setAttribute("data-item", todo.toString());
document.getElementById("modalFormInput").value = todo;
modalFormInput.value = todo;
modalTitle.innerHTML = translations.editTodo;
btnItemStatus.classList.add("is-active");
}
......@@ -293,13 +297,13 @@ function show(todo, templated) {
resizeInput(datePickerInput);
resizeInput(recurrencePickerInput);
// in any case put focus into the input field
document.getElementById("modalFormInput").focus();
modalFormInput.focus();
// if textarea, resize to content length
if(document.getElementById("modalFormInput").tagName==="TEXTAREA") {
document.getElementById("modalFormInput").style.height="auto";
document.getElementById("modalFormInput").style.height= document.getElementById("modalFormInput").scrollHeight+"px";
if(modalFormInput.tagName==="TEXTAREA") {
modalFormInput.style.height="auto";
modalFormInput.style.height= modalFormInput.scrollHeight+"px";
}
// create the modal jail, so tabbing won't leave modal
createModalJail(modalForm);
......@@ -412,23 +416,23 @@ function toggleInputSize(type) {
break;
}
newInputElement.id = "modalFormInput";
newInputElement.value = document.getElementById("modalFormInput").value;