feat: add todolist feature#194
Conversation
📝 WalkthroughWalkthroughThis PR significantly expands the to-do list feature across the extension with new UI controls (category, priority, due date selectors), import/export functionality, and notification support via a new background service worker. It simultaneously removes Swedish language support and the "newTabTitle" localization key from multiple languages, while adding comprehensive to-do-related translations across 30+ locales. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Background as Background Worker
participant Storage as Chrome Storage
participant Notification as Notifications API
User->>Background: Right-click text → "Add to To Do List"
Background->>Storage: Read chrome.storage.local.todoList
Storage-->>Background: Existing todos array (or empty)
Background->>Background: Create new todo entry<br/>(status: "pending", defaults)
Background->>Storage: Write updated todoList
Background->>Background: Update action badge<br/>with pending count
Storage-->>Background: Change event fired
Background->>Background: Check pending todos<br/>with dueDate
alt Overdue or Due Today
Background->>Notification: Create notification<br/>(localized title/message)
Notification-->>User: Display reminder
end
sequenceDiagram
participant User
participant ToDoUI as To-Do List UI
participant Storage as Chrome Storage
participant Export as Export Handler
User->>ToDoUI: Click "Export" button
ToDoUI->>Storage: Read todoList from<br/>chrome.storage.local or localStorage
Storage-->>ToDoUI: Return todos array
ToDoUI->>Export: Format as JSON
Export-->>User: Trigger download<br/>todo-list.json
rect rgba(0, 200, 0, 0.5)
Note over User,Export: Import Flow (Reverse)
User->>ToDoUI: Click "Import" + select file
ToDoUI->>ToDoUI: Parse JSON
ToDoUI->>ToDoUI: Validate structure
alt Valid JSON
ToDoUI->>Storage: Merge/replace todoList
Storage-->>ToDoUI: Confirm write
ToDoUI->>User: Show success message
else Invalid JSON
ToDoUI->>User: Show error message
end
end
sequenceDiagram
participant User
participant Page as Page Load
participant Background as Background Worker
participant Storage as Chrome Storage
participant Notification as Notifications API
Page->>Background: Start (on extension load)
Background->>Storage: Read todoList
Storage-->>Background: todos array
Background->>Background: Filter pending todos<br/>with dueDate
Background->>Background: Determine overdue/today status
alt Tasks found
Background->>Notification: Create localized notifications
Notification-->>User: Display alerts
end
Background->>Background: Schedule hourly check
loop Every 1 hour
Background->>Storage: Read todoList
Background->>Background: Recheck due status
alt Status changed
Background->>Notification: Update notifications
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 18
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
locales/th.js (1)
145-145:⚠️ Potential issue | 🟡 MinorFix stray quote character in evening greeting.
The Thai evening greeting has a stray single quote character (
') before the Thai text:"สวัสดีตอนเย็น!". This would display incorrectly in the UI."สวัสดีตอนเย็น!"should be:
"สวัสดีตอนเย็น!"🔧 Proposed fix
- "evening": "'สวัสดีตอนเย็น!" + "evening": "สวัสดีตอนเย็น!"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@locales/th.js` at line 145, The "evening" translation string contains a stray leading single-quote character; locate the "evening" key in locales/th.js and remove the extra apostrophe so the value is a proper quoted string (i.e., evening: "สวัสดีตอนเย็น!"), ensuring the surrounding quotes are balanced and no stray characters remain.scripts/languages.js (1)
90-96:⚠️ Potential issue | 🟡 MinorRemove Korean from the comma-decimal locale list.
Including
"ko"here rewrites values like23.5to23,5, so Korean weather/temperature text will be formatted incorrectly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/languages.js` around lines 90 - 96, The list specialDecimalLanguages currently contains "ko", which causes code in the block that checks if (specialDecimalLanguages.includes(language)) and then does text = text.replace(".", ",") to incorrectly change Korean numeric decimals; remove "ko" from the specialDecimalLanguages array so that language === "ko" no longer triggers that replacement (ensure the array literal used to define specialDecimalLanguages is updated accordingly).locales/mr.js (1)
1-186:⚠️ Potential issue | 🟠 MajorThis change regresses Marathi coverage across the existing UI.
scripts/languages.jsandindex.htmlstill request keys likepersonalizationSectionTitle,clockSectionTitle,hideClockBox,hideClockBoxInfo,defaultEngine,PrivacyPolicy,useGPSInfo,bookmarkSortBy, and the theme labels, but they are no longer present here. The result is a mixed Marathi/English interface after switching locales.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@locales/mr.js` around lines 1 - 186, The Marathi locale file is missing several keys referenced elsewhere, causing mixed-language UI; add the missing translation keys to the mr object (e.g., personalizationSectionTitle, clockSectionTitle, hideClockBox, hideClockBoxInfo, PrivacyPolicy, useGPSInfo, bookmarkSortBy and the theme labels such as lightTheme/darkTheme/autoTheme or whatever theme keys other locales use) with Marathi strings matching the style of existing keys so scripts/languages.js and index.html can find them; ensure the keys exactly match the identifiers used in the codebase (e.g., "personalizationSectionTitle", "clockSectionTitle", "hideClockBox", "hideClockBoxInfo", "defaultEngine" if overridden, "PrivacyPolicy", "useGPSInfo", "bookmarkSortBy", and theme label keys) and run a quick locale check against another complete locale to confirm none are missing.scripts/todo-list.js (1)
233-240:⚠️ Potential issue | 🟠 MajorHandle clicks from nested task content.
After adding
.task-content/.task-meta, most clicks land on child nodes, but this branch only runs whenevent.target.tagName === "LI". That makes complete/pending toggling work only on empty padding, not on the task text or badges. Useclosest('li[data-todoitem]')and exclude the edit/pin/remove controls instead.Suggested fix
-todoulList.addEventListener("click", (event) => { - if (event.target.tagName === "LI") { - if (suppressNextClick) return; // Prevent misclick on LI - event.target.classList.toggle("checked"); // Check the clicked LI tag - let id = event.target.dataset.todoitem; +todoulList.addEventListener("click", (event) => { + const li = event.target.closest('li[data-todoitem]'); + if (li && !event.target.closest(".todoremovebtn, .todopinbtn, .todoeditbtn")) { + if (suppressNextClick) return; + li.classList.toggle("checked"); + let id = li.dataset.todoitem; todoList[id].status = ((todoList[id].status === "completed") ? "pending" : "completed"); // Update status SaveToDoData(); // Save Changes }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/todo-list.js` around lines 233 - 240, The click handler currently checks only event.target.tagName === "LI", so clicks on child elements like .task-content or .task-meta are ignored; change the handler to find the nearest ancestor li with a data-todoitem (use event.target.closest('li[data-todoitem]')) and return if none, maintain the existing suppressNextClick check, and also skip toggling when the click originated on control buttons (e.g., selectors for edit/pin/remove or elements with a specific control class). Then toggle the found li's "checked" class, read its dataset.todoitem into id, update todoList[id].status between "completed" and "pending", and call SaveToDoData(); keep references to the existing symbols todoulList (event listener), suppressNextClick, todoList, and SaveToDoData.
🧹 Nitpick comments (1)
todo-import.json (1)
1-11: Test file for JSON import - consider cleanup before merge.This file appears to contain test data for the todo import functionality. If this is intended to remain in the repository, consider:
- Using semantic category keys (e.g.,
"category": "study") instead of localized text to ensure compatibility with the category system- Updating dates to be future dates or using relative date examples
If this is only for testing during development, consider removing it before merging or adding it to
.gitignore.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@todo-import.json` around lines 1 - 11, The test JSON file with key "t1234567890" contains development data that should not be merged as-is; either remove the file from the PR (or add it to .gitignore) if it’s only for testing, or normalize its fields for production: change "category" from localized text to a semantic key (e.g., "category": "study"), update "createdAt" and "dueDate" to valid future or relative-example dates, and ensure "status", "priority", and "pinned" follow the canonical enum/format used by the import system before keeping it in the repo.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@index.html`:
- Around line 101-135: The new task controls lack accessible labels; update the
elements with IDs todoCategory, todoPriority, todoDueDate, todoFilter, and
todoSort (and any action buttons like todoAdd/todoImport/todoExport if
unlabeled) to provide screen-reader friendly names by either adding <label
for="..."> elements associated with each ID or adding descriptive aria-label
attributes (e.g., aria-label="Category", aria-label="Priority", aria-label="Due
date", aria-label="Filter todos", aria-label="Sort todos"); ensure labels are
visible or use visually-hidden CSS for sighted users, and confirm the
todoDueDate input has an appropriate label describing the expected date format.
In `@locales/az.js`:
- Around line 27-30: Add the missing Azeri translation for the main todo title
by restoring the "todoListText" key in this locale object; update locales/az.js
to include "todoListText": "Tapşırıqlar siyahısı" (or the correct Azeri phrase)
alongside the existing keys ("todoListInfo", "todoListHover", "todoPlaceholder")
so `#todoListHeading` and the settings toggle no longer fall back to English.
In `@locales/fr.js`:
- Line 111: Update the French localization entry for the key "userAPI" in
locales/fr.js to a French string; replace the English value "Your weatherAPI
key" with the provided French translation "Votre clé WeatherAPI" so the
"userAPI" property matches the rest of the French locale.
In `@locales/hu.js`:
- Around line 3-162: The Hungarian locale is missing many UI keys so users see
English fallbacks; restore the missing translation keys by adding Hungarian
strings for the listed identifiers (e.g. personalizationSectionTitle,
hideClockBox, hideClockBoxInfo, defaultEngine, gImagesEngine, redditEngine,
wikipediaEngine, quoraEngine, PrivacyPolicy, useGPS, useGPSInfo and all theme
label keys) into locales/hu.js (matching the same key names used in other
locales) so the UI renders fully translated; ensure you add them alongside the
existing entries and follow the same object/key formatting as other locale
entries.
In `@locales/np.js`:
- Line 43: The value for the localization key "todoFilterOverdue" contains mixed
Chinese characters and must be replaced with a correct Nepali string; update the
entry for todoFilterOverdue (in the locales/np object) to a pure Devanagari
translation such as "ढिलो भएको" (or another validated Nepali phrase for
"overdue") and ensure the file is saved with UTF-8 encoding so the Devanagari
characters render correctly.
- Line 50: The Nepali translation value for the key "todoDueOverdue" contains
corrupted/mixed characters; find every occurrence of the "todoDueOverdue" entry
in locales/np.js and replace the corrupted string ("अल标记हेको" and the duplicate
instance) with a correct Devanagari translation such as "म्याद नाघेको" (or
another approved Nepali term for "overdue") so both entries use consistent,
proper Nepali text.
In `@locales/ur.js`:
- Line 89: Replace the incorrect placeholder value for the todoFilterOverdue
key: locate the "todoFilterOverdue" entry and change its value from " mosques"
to a correct Urdu translation for "overdue" such as "تاخیر سے" or "وقت پر نہیں",
ensuring the string uses proper quotes and spacing consistent with other entries
in locales/ur.js.
- Line 96: Replace the incorrect English word "mosques" for the "todoDueOverdue"
key with a proper Urdu label (for example use "مقررہ وقت گزر چکا") and also fix
the other overdue-related translation in this file (the other overdue label
present near the same block) to an appropriate Urdu short form (for example
"تاخیر"); update the values for the keys "todoDueOverdue" and the other overdue
key so both labels are correct Urdu translations.
In `@manifest.json`:
- Line 4: The manifest's "version" field was decremented from 3.3.7 to 3.3.6;
restore/increment it to a monotonically higher semantic version (e.g., "3.3.8"
or the intended new release) in the manifest's "version" key and ensure the same
version is updated in any build/package metadata (release notes/changelog, build
scripts) so Chrome Web Store submission and installed clients remain consistent.
In `@scripts/background.js`:
- Around line 4-17: bgTranslations currently hardcodes only en/zh and uses keys
addTodo/notificationTitle while new locale files use
todoContextMenuAdd/todoNotificationTitle; replace the hardcoded bgTranslations
usage by fetching strings from the extension i18n API (chrome.i18n.getMessage or
browser.i18n.getMessage) at runtime for the two labels instead of relying on
bgTranslations, mapping addTodo -> getMessage('todoContextMenuAdd') and
notificationTitle -> getMessage('todoNotificationTitle'); update any code
referencing bgTranslations.addTodo or bgTranslations.notificationTitle to call
the i18n lookup so all locales are covered and fallbacks are handled by the
platform.
- Around line 100-132: The background check currently re-sends notifications for
every pending task on startup and hourly (checkDueTasks + setInterval) causing
duplicates because the page already emits reminders; change checkDueTasks so it
only notifies a task once per day by persisting a per-task last-notified date
(e.g., add or update a todo.lastNotified or a separate storage map keyed by task
id) and only call chrome.notifications.create when that stored date is different
from today (and update the stored date to today after notifying); alternatively
remove the initial call on service worker start (remove the lone checkDueTasks()
call) if you prefer the page to own startup reminders, and ensure completed
tasks clear their last-notified entry when status changes.
- Around line 128-132: Replace the transient setInterval usage with
chrome.alarms: remove the setInterval(checkDueTasks, 3600000) and instead create
a persistent alarm via chrome.alarms.create(...) to fire hourly, register a
chrome.alarms.onAlarm.addListener that calls checkDueTasks, and keep the initial
one-time checkDueTasks() call on service worker start; update any references to
setInterval and ensure the alarm name matches what the onAlarm handler checks so
checkDueTasks is invoked reliably across service worker restarts.
- Around line 19-27: getBackgroundLanguage currently uses window.localStorage
which is not available in an MV3 service worker; change getBackgroundLanguage()
to an async function that reads chrome.storage.local (e.g., await
chrome.storage.local.get("selectedLanguage")) and returns the stored value or
"en", update getBgTranslation(key) to be async (or accept a resolved language
param) so it awaits getBackgroundLanguage() before indexing bgTranslations, and
update any callers of getBgTranslation/getBackgroundLanguage to await the
promise (e.g., context menu and notification initialization) so no synchronous
localStorage access remains.
In `@scripts/todo-list.js`:
- Around line 128-133: The code is converting a date-only input into an ISO UTC
timestamp (using new Date(dueDateInput.value) and date.setUTCHours(...); dueDate
= date.toISOString()), which causes day shifts across time zones; instead
persist the raw calendar date string from dueDateInput.value (YYYY-MM-DD) or use
a local-date helper so filters/notifications compare dates as calendar days.
Update the logic around dueDateInput/dueDate to assign dueDate =
dueDateInput.value (or pass through a local-date parser) and apply the same
change to the other occurrence around the block handling lines 338-343 to ensure
consistency.
- Around line 333-350: The code is storing escaped HTML into the model by using
sanitizeInput(newTitle) for todo.title and then rendering with innerHTML, which
double-escapes entities; instead assign the raw trimmed text to todo.title (use
previousTitle when empty) and remove sanitizeInput from the model assignment
(references: sanitizeInput, todo.title, previousTitle), then ensure rendering
uses safe text assignment rather than innerHTML (replace
newTaskContent.innerHTML usage with a text-safe render such as setting
textContent or otherwise escaping at render time) so the model keeps raw text
and escaping only happens during render.
- Around line 145-149: The code mutates the DOM directly (creating li via
createTodoItemDOM and appending to todoulList) which breaks active filter/sort
state; instead, after updating the todoList data and calling SaveToDoData(),
stop doing the incremental append/clearing and call renderTodoList() to rebuild
the view from todoList so filters/sorts are applied; update the places that
create DOM nodes (uses of createTodoItemDOM/todoulList.appendChild and
SaveToDoData in the add/edit/complete handlers) to remove direct appendChild and
invoke renderTodoList() after saving.
In `@style.css`:
- Around line 1220-1233: The CSS uses an undefined variable --accent-color-blue
in the .todo-actions button and its :hover rule, so the buttons fall back to
initial colors; fix by either adding a definition for --accent-color-blue (e.g.,
in :root where other blue variables like --darkColor-blue and
--accentLightTint-blue are defined) or update the rules to use an existing
variable name (for example --darkColor-blue or --accentLightTint-blue) and
adjust the hover color to use color-mix with that same defined variable; update
the .todo-actions button and .todo-actions button:hover references accordingly.
- Around line 1518-1528: The CSS selectors for priority badges use localized
class names (.priority-高, .priority-中, .priority-低) but the JS now emits
.priority-high, .priority-medium, and .priority-low; update the selectors in
style.css to target .priority-high, .priority-medium, and .priority-low (keeping
the existing background-color/color-mix values) so the badges receive the
intended colors; also search for any other occurrences of the old localized
class names and replace them with the new English names to keep styles
consistent with scripts/todo-list.js.
---
Outside diff comments:
In `@locales/mr.js`:
- Around line 1-186: The Marathi locale file is missing several keys referenced
elsewhere, causing mixed-language UI; add the missing translation keys to the mr
object (e.g., personalizationSectionTitle, clockSectionTitle, hideClockBox,
hideClockBoxInfo, PrivacyPolicy, useGPSInfo, bookmarkSortBy and the theme labels
such as lightTheme/darkTheme/autoTheme or whatever theme keys other locales use)
with Marathi strings matching the style of existing keys so scripts/languages.js
and index.html can find them; ensure the keys exactly match the identifiers used
in the codebase (e.g., "personalizationSectionTitle", "clockSectionTitle",
"hideClockBox", "hideClockBoxInfo", "defaultEngine" if overridden,
"PrivacyPolicy", "useGPSInfo", "bookmarkSortBy", and theme label keys) and run a
quick locale check against another complete locale to confirm none are missing.
In `@locales/th.js`:
- Line 145: The "evening" translation string contains a stray leading
single-quote character; locate the "evening" key in locales/th.js and remove the
extra apostrophe so the value is a proper quoted string (i.e., evening:
"สวัสดีตอนเย็น!"), ensuring the surrounding quotes are balanced and no stray
characters remain.
In `@scripts/languages.js`:
- Around line 90-96: The list specialDecimalLanguages currently contains "ko",
which causes code in the block that checks if
(specialDecimalLanguages.includes(language)) and then does text =
text.replace(".", ",") to incorrectly change Korean numeric decimals; remove
"ko" from the specialDecimalLanguages array so that language === "ko" no longer
triggers that replacement (ensure the array literal used to define
specialDecimalLanguages is updated accordingly).
In `@scripts/todo-list.js`:
- Around line 233-240: The click handler currently checks only
event.target.tagName === "LI", so clicks on child elements like .task-content or
.task-meta are ignored; change the handler to find the nearest ancestor li with
a data-todoitem (use event.target.closest('li[data-todoitem]')) and return if
none, maintain the existing suppressNextClick check, and also skip toggling when
the click originated on control buttons (e.g., selectors for edit/pin/remove or
elements with a specific control class). Then toggle the found li's "checked"
class, read its dataset.todoitem into id, update todoList[id].status between
"completed" and "pending", and call SaveToDoData(); keep references to the
existing symbols todoulList (event listener), suppressNextClick, todoList, and
SaveToDoData.
---
Nitpick comments:
In `@todo-import.json`:
- Around line 1-11: The test JSON file with key "t1234567890" contains
development data that should not be merged as-is; either remove the file from
the PR (or add it to .gitignore) if it’s only for testing, or normalize its
fields for production: change "category" from localized text to a semantic key
(e.g., "category": "study"), update "createdAt" and "dueDate" to valid future or
relative-example dates, and ensure "status", "priority", and "pinned" follow the
canonical enum/format used by the import system before keeping it in the repo.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ce1addfd-b2fc-4715-b231-3d0fb0b2da39
📒 Files selected for processing (48)
CHANGELOG.mdREADME.mdindex.htmllocales/ar_SA.jslocales/az.jslocales/bn.jslocales/cs.jslocales/de.jslocales/el.jslocales/en.jslocales/es.jslocales/fa.jslocales/fr.jslocales/hi.jslocales/hu.jslocales/idn.jslocales/it.jslocales/ja.jslocales/ko.jslocales/mr.jslocales/np.jslocales/pl.jslocales/pt.jslocales/ru.jslocales/sl.jslocales/ta.jslocales/th.jslocales/tr.jslocales/uk.jslocales/ur.jslocales/uz.jslocales/vi.jslocales/zh.jslocales/zh_TW.jsmanifest(firefox).jsonmanifest.jsonscripts/background.jsscripts/bookmarks.jsscripts/clock.jsscripts/languages.jsscripts/search.jsscripts/shortcuts.jsscripts/theme.jsscripts/todo-list.jsscripts/weather.jsstyle.csstodo-import.jsontools/languagesAnalysis.html
💤 Files with no reviewable changes (4)
- scripts/weather.js
- scripts/bookmarks.js
- scripts/clock.js
- CHANGELOG.md
| <div class="task-controls"> | ||
| <select id="todoCategory"> | ||
| <option value="uncategorized" data-i18n="todoCategoryUncategorized">Uncategorized</option> | ||
| <option value="work" data-i18n="todoCategoryWork">Work</option> | ||
| <option value="life" data-i18n="todoCategoryLife">Life</option> | ||
| <option value="study" data-i18n="todoCategoryStudy">Study</option> | ||
| <option value="other" data-i18n="todoCategoryOther">Other</option> | ||
| </select> | ||
| <select id="todoPriority"> | ||
| <option value="medium" data-i18n="todoPriorityMedium">Medium</option> | ||
| <option value="high" data-i18n="todoPriorityHigh">High</option> | ||
| <option value="low" data-i18n="todoPriorityLow">Low</option> | ||
| </select> | ||
| <input type="date" id="todoDueDate" placeholder="截止日期"> | ||
| <button id="todoAdd">+</button> | ||
| </div> | ||
| </div> | ||
| <div class="todo-actions"> | ||
| <button id="todoImport" data-i18n="importText">Import</button> | ||
| <button id="todoExport" data-i18n="exportText">Export</button> | ||
| </div> | ||
| <div class="todo-filters"> | ||
| <select id="todoFilter"> | ||
| <option value="all" data-i18n="todoFilterAll">All</option> | ||
| <option value="pending" data-i18n="todoFilterPending">Pending</option> | ||
| <option value="completed" data-i18n="todoFilterCompleted">Completed</option> | ||
| <option value="overdue" data-i18n="todoFilterOverdue">Overdue</option> | ||
| <option value="today" data-i18n="todoFilterToday">Today</option> | ||
| </select> | ||
| <select id="todoSort"> | ||
| <option value="created" data-i18n="todoSortCreated">Created</option> | ||
| <option value="priority" data-i18n="todoSortPriority">Priority</option> | ||
| <option value="due" data-i18n="todoSortDue">Due Date</option> | ||
| </select> | ||
| </div> |
There was a problem hiding this comment.
Add accessible labels to the new task controls.
The new category, priority, due-date, filter, and sort controls are unlabeled. Without a <label> or aria-label, screen-reader users only hear the raw control state, not what each control does.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@index.html` around lines 101 - 135, The new task controls lack accessible
labels; update the elements with IDs todoCategory, todoPriority, todoDueDate,
todoFilter, and todoSort (and any action buttons like
todoAdd/todoImport/todoExport if unlabeled) to provide screen-reader friendly
names by either adding <label for="..."> elements associated with each ID or
adding descriptive aria-label attributes (e.g., aria-label="Category",
aria-label="Priority", aria-label="Due date", aria-label="Filter todos",
aria-label="Sort todos"); ensure labels are visible or use visually-hidden CSS
for sighted users, and confirm the todoDueDate input has an appropriate label
describing the expected date format.
| // "todoListText": "To Do List", | ||
| // "todoListInfo": "Show a daily To Do list", | ||
| // "todoListHover": "ToDo List", // Keep this short | ||
| // "todoPlaceholder": "Add task...", | ||
| "todoListInfo": "Gündəlik tapşırıqlar siyahısını göstər", | ||
| "todoListHover": "To-Do Siyahısı", | ||
| "todoPlaceholder": "Tapşırıq əlavə et...", |
There was a problem hiding this comment.
Add the missing todoListText translation.
This locale translates the new todo controls, but the main title key is still missing, so #todoListHeading and the settings toggle fall back to English instead of Azerbaijani.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@locales/az.js` around lines 27 - 30, Add the missing Azeri translation for
the main todo title by restoring the "todoListText" key in this locale object;
update locales/az.js to include "todoListText": "Tapşırıqlar siyahısı" (or the
correct Azeri phrase) alongside the existing keys ("todoListInfo",
"todoListHover", "todoPlaceholder") so `#todoListHeading` and the settings toggle
no longer fall back to English.
| "WeatherApiText": "Entrez votre clé WeatherAPI", | ||
| "WeatherApiSubtext": "Si la fonctionnalité météo ne fonctionne pas", | ||
| "userAPI": "Votre clé WeatherAPI", | ||
| "userAPI": "Your weatherAPI key", |
There was a problem hiding this comment.
Translate userAPI to French.
This string is in English ("Your weatherAPI key") while the rest of the French locale file uses French translations. It should be translated for consistency with other user-facing strings in this locale.
"Votre clé WeatherAPI"🔧 Proposed fix
- "userAPI": "Your weatherAPI key",
+ "userAPI": "Votre clé WeatherAPI",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@locales/fr.js` at line 111, Update the French localization entry for the key
"userAPI" in locales/fr.js to a French string; replace the English value "Your
weatherAPI key" with the provided French translation "Votre clé WeatherAPI" so
the "userAPI" property matches the rest of the French locale.
| // Menu Items | ||
| "feedback": "Visszajelzés", | ||
| "resetsettings": "Beállítások visszaállítása", | ||
| "menuCloseText": "Bezárás", | ||
|
|
||
| // Shortcuts | ||
| "shortcutsText": "Parancsikonok", | ||
| "enableShortcutsText": "Parancsikonok megjelenítése", | ||
| "editShortcutsText": "Parancsikonok szerkesztése", | ||
| "shortcutsInfoText": "Válassza ki a parancsikonokat, amelyeket meg szeretné jeleníteni a kezdőképernyőn", | ||
| "editShortcutsList": "Elmentett parancsikonok", | ||
| "editShortcutsListInfo": "Új parancsikonokat adhatsz hozzá a \"+\" ikonra kattintva, vagy szerkesztheted a meglévőket a parancsikon nevére vagy URL címére kattintva.", | ||
| "adaptiveIconText": "Alkalmazkodó ikonformák", | ||
| "adaptiveIconInfoText": "Parancsikonok kisebbnek fognak tűnni", | ||
| "bookmarksText": "Könyvjelzők", | ||
| "bookmarksInfo": "Könyvjelzők oldalsáv megjelenítése", | ||
| "ai_tools_button": "MI-Eszközök", | ||
| "enable_ai_tools": "Parancsikon az MI-eszközökhöz", | ||
| "googleAppsMenuText": "Google Alkalmazások", | ||
| "googleAppsMenuInfo": "Parancsikonok a Google alkalmazásaihoz", | ||
| "googleAppsHover": "Google Appok", | ||
|
|
||
| // To-do List | ||
| "todoListText": "Teendő lista", | ||
| "todoListInfo": "Napi teendők lista megjelenítése", | ||
| "todoListHover": "Teendő lista", | ||
| "todoPlaceholder": "Feladat hozzáadása...", | ||
| "todoCategoryAll": "Mind", | ||
| "todoCategoryUncategorized": "Kategorizálatlan", | ||
| "todoCategoryWork": "Munka", | ||
| "todoCategoryLife": "Élet", | ||
| "todoCategoryStudy": "Tanulás", | ||
| "todoCategoryOther": "Egyéb", | ||
| "todoPriorityHigh": "Magas", | ||
| "todoPriorityMedium": "Közepes", | ||
| "todoPriorityLow": "Alacsony", | ||
| "todoFilterAll": "Mind", | ||
| "todoFilterPending": "Függőben", | ||
| "todoFilterCompleted": "Kész", | ||
| "todoFilterOverdue": "Lejárt", | ||
| "todoFilterToday": "Ma", | ||
| "todoSortCreated": "Létrehozva", | ||
| "todoSortPriority": "Prioritás", | ||
| "todoSortDue": "Határidő", | ||
| "todoImportSuccess": "Import sikeres!", | ||
| "todoImportFailed": "Import sikertelen: érvénytelen JSON fájl", | ||
| "todoDueOverdue": "Lejárt", | ||
| "todoDueToday": "Ma esedékes", | ||
| "todoNotificationTitle": "Feladat emlékeztető", | ||
| "todoContextMenuAdd": "Hozzáadás a listához", | ||
| "importText": "Import", | ||
| "exportText": "Export", | ||
|
|
||
| // Digital Clock | ||
| "digitalclocktitle": "Digitális óra", | ||
| "digitalclockinfo": "Váltás a digitális órára", | ||
| "timeformattitle": "12 órás formátum", | ||
| "timeformatinfo": "12 órás időformátum használata", | ||
| "greetingtitle": "Üdvözlés", | ||
| "greetinginfo": "Üdvözlet megjelenítése az egyéni szöveg alatt", | ||
|
|
||
| // Misc | ||
| "userTextTitle": "Testreszabható szöveg", | ||
| "userTextInfo": "Egyéni szöveg megjelenítése az óra alatt", | ||
| "fahrenheitCelsiusCheckbox": "Fahrenheit használata", | ||
| "fahrenheitCelsiusText": "Frissítsd az oldalt a módosítások alkalmazásához", | ||
| "micIconTitle": "Mikrofon ikon elrejtése", | ||
| "micIconInfo": "Ha a hangalapú gépelés nem működik", | ||
| "hideSearchWith": "Keresőmotorok elrejtése", | ||
| "hideSearchWithInfo": "Váltás a keresőmotorok között az ikonra kattintva", | ||
| "search_suggestions_button": "Keresési javaslatok", | ||
| "search_suggestions_text": "Keresési javaslatok bekapcsolása", | ||
|
|
||
| // Proxy | ||
| "useproxytitletext": "Proxy megkerülése", | ||
| "useproxyText": "Ha a keresési javaslatok nem működnek", | ||
| "ProxyText": "CORS megkerülő proxy", | ||
| "ProxySubtext": "Saját CORS megkerülő proxy hozzáadása", | ||
| "HostproxyButton": "Saját proxy üzemeltetése", | ||
|
|
||
| // Location | ||
| "UserLocText": "Add meg a tartózkodási helyed", | ||
| "UserLocSubtext": "Ha az időjárás helye nem megfelelő", | ||
| "userLoc": "A városod vagy koordinátáid (földrajzi szélesség, hosszúság)", | ||
|
|
||
| // Weather | ||
| "WeatherApiText": "Add meg a WeatherAPI kulcsodat", | ||
| "WeatherApiSubtext": "Ha az időjárási funkciók nem működnek", | ||
| "userAPI": "A weatherAPI kulcsod", | ||
| "LearnMoreButton": "További információk", | ||
| "saveAPI": "Mentés", | ||
|
|
||
| // Body Items | ||
| // Calendar | ||
| "days": ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], | ||
| "months": ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], | ||
|
|
||
| // Weather | ||
| "humidityLevel": "Páratartalom", | ||
| "feelsLike": "Érzés", | ||
| "location": "Föld", | ||
|
|
||
| // Bookmarks | ||
| "bookmarksHeading": "Könyvjelzők", | ||
| "bookmarkViewAs": "Megjelenítés mint", | ||
| "bookmarkViewGrid": "Rács", | ||
| "bookmarkViewList": "Lista", | ||
| "bookmarkSearch": "Könyvjező keresése", | ||
|
|
||
| // New Tab Item | ||
| "conditionText": "Szia! Hogy vagy ma?", | ||
| "enterBtn": "Keresés", | ||
| "searchPlaceholder": "Írj ide...", | ||
| "listenPlaceholder": "Hallgatlak...", | ||
| "searchWithHint": "Keresés a következővel", | ||
| "userText": "Kattints ide a szerkesztéshez", | ||
|
|
||
| // Greeting | ||
| greeting: { | ||
| "morning": "Jó reggelt!", | ||
| "afternoon": "Jó napot!", | ||
| "evening": "Jó estét!" | ||
| }, | ||
|
|
||
| // Search Engines and rest | ||
| "googleEngine": "Google", | ||
| "duckEngine": "Duck", | ||
| "bingEngine": "Bing", | ||
| "braveEngine": "Brave", | ||
| "youtubeEngine": "YouTube", | ||
|
|
||
| // AI Tools | ||
| "ai_tools": "MI Eszközök", | ||
| "chatGPT": "ChatGPT", | ||
| "gemini": "Gemini", | ||
| "copilot": "Copilot", | ||
| "claude": "Claude", | ||
| "perplexity": "Perplexity", | ||
| "metaAI": "Meta AI", | ||
| "github": "GitHub", | ||
|
|
||
| // Wallpaper and misc | ||
| "uploadWallpaperText": "Háttérkép feltöltése", | ||
| "backupText": "Mentés", | ||
| "restoreText": "Visszaállítás", | ||
| "rangColor": "Szín kiválasztása", | ||
|
|
||
| // Dialog boxes (alerts) | ||
| "confirmWallpaper": "Szeretnél egy újabb képet beállítani a napi háttérképednek?", | ||
| "confirmRestore": "Biztos, hogy vissza akarja állítani a beállításokat? Ezt a műveletet nem lehet visszacsinálni.", | ||
| "Nobackgroundset": "Jelenleg nincs beállítva háttérkép.", | ||
| "clearbackgroundimage": "Biztos, hogy törölni szeretnéd a háttérképet?", | ||
| "ProxyDisclaimer": "Alapértelmezés szerint minden proxy funkció ki van kapcsolva.\n\nHa engedélyezed a keresési javaslatokat és a CORS megkerülő proxy-t, erősen ajánlott saját proxy-t üzemeltetni a fokozott adatvédelem érdekében.\n\n\nA proxy alapértelmezés szerint a https://mynt-proxy.rhythmcorehq.com beállítással működik, ami azt jelenti, hogy minden adat ezen a szolgáltatáson keresztül fog menni, ami adatvédelmi aggályokat vethet fel.", | ||
| "failedbackup": "Sikertelen mentés: ", | ||
| "restorecompleted": "A visszaállítás sikeresen befejeződött!", | ||
| "restorefailed": "Sikertelen visszaállítás: ", | ||
| "invalidBackup": "Érvénytelen mentési fájl", | ||
| "deleteBookmark": "Biztos, hogy törölni szeretnéd a könyvjelzőt \"{title}\"?", | ||
| "UnsupportedBrowser": "A könyvjelzők nem támogatottak a böngészőben", | ||
| }; No newline at end of file |
There was a problem hiding this comment.
This locale now falls back to English for many existing screens.
The file no longer provides several keys that the page still renders, e.g. personalizationSectionTitle, hideClockBox, hideClockBoxInfo, defaultEngine, gImagesEngine, redditEngine, wikipediaEngine, quoraEngine, PrivacyPolicy, useGPS, useGPSInfo, and the theme labels. Hungarian users will get a partially untranslated UI after this change.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@locales/hu.js` around lines 3 - 162, The Hungarian locale is missing many UI
keys so users see English fallbacks; restore the missing translation keys by
adding Hungarian strings for the listed identifiers (e.g.
personalizationSectionTitle, hideClockBox, hideClockBoxInfo, defaultEngine,
gImagesEngine, redditEngine, wikipediaEngine, quoraEngine, PrivacyPolicy,
useGPS, useGPSInfo and all theme label keys) into locales/hu.js (matching the
same key names used in other locales) so the UI renders fully translated; ensure
you add them alongside the existing entries and follow the same object/key
formatting as other locale entries.
| "todoFilterAll": "सबै", | ||
| "todoFilterPending": "पर्खिरहेको", | ||
| "todoFilterCompleted": "पूर्ण", | ||
| "todoFilterOverdue": "अल标记हेको", |
There was a problem hiding this comment.
Fix corrupted Nepali translation for "overdue".
The translation "todoFilterOverdue": "अल标记हेको" contains Chinese characters "标记" mixed with Devanagari script. This is corrupted text that will display incorrectly to users. The correct Nepali translation for "overdue" should be pure Devanagari text, such as "ढिलो भएको" or similar.
Do you need help finding the correct Nepali translation for this term?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@locales/np.js` at line 43, The value for the localization key
"todoFilterOverdue" contains mixed Chinese characters and must be replaced with
a correct Nepali string; update the entry for todoFilterOverdue (in the
locales/np object) to a pure Devanagari translation such as "ढिलो भएको" (or
another validated Nepali phrase for "overdue") and ensure the file is saved with
UTF-8 encoding so the Devanagari characters render correctly.
| if (dueDateInput && dueDateInput.value) { | ||
| // 处理时区问题,确保日期正确 | ||
| const date = new Date(dueDateInput.value); | ||
| // 设置为UTC时间的当天开始,避免时区偏移 | ||
| date.setUTCHours(0, 0, 0, 0); | ||
| dueDate = date.toISOString(); |
There was a problem hiding this comment.
Store due dates as calendar days, not UTC timestamps.
<input type="date"> gives a date-only value, but this converts it to an ISO UTC instant. In non-UTC time zones, the same task can shift a day early/late when today/overdue filters and notifications read it back. Persist the raw YYYY-MM-DD string (or parse with a consistent local-date helper) instead of toISOString().
Also applies to: 338-343
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/todo-list.js` around lines 128 - 133, The code is converting a
date-only input into an ISO UTC timestamp (using new Date(dueDateInput.value)
and date.setUTCHours(...); dueDate = date.toISOString()), which causes day
shifts across time zones; instead persist the raw calendar date string from
dueDateInput.value (YYYY-MM-DD) or use a local-date helper so
filters/notifications compare dates as calendar days. Update the logic around
dueDateInput/dueDate to assign dueDate = dueDateInput.value (or pass through a
local-date parser) and apply the same change to the other occurrence around the
block handling lines 338-343 to ensure consistency.
| const li = createTodoItemDOM(t, rawText, "pending", false, category, priority, dueDate); // Create List item | ||
| todoulList.appendChild(li); // Append the new item to the DOM immediately | ||
| todoInput.value = ""; // Clear Input | ||
| if (dueDateInput) dueDateInput.value = ""; // Clear due date input | ||
| SaveToDoData(); // Save changes |
There was a problem hiding this comment.
Re-render after mutations so filter/sort stays correct.
These paths patch the DOM in place and only persist todoList. With any active filter/sort other than the default view, the UI becomes stale immediately: newly added items appear in the wrong filtered view, completed items remain visible in Pending, and priority/due edits do not re-order the list. After mutating todoList, rebuild the list from renderTodoList() instead of incrementally editing the current DOM.
Also applies to: 233-251, 389-394
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/todo-list.js` around lines 145 - 149, The code mutates the DOM
directly (creating li via createTodoItemDOM and appending to todoulList) which
breaks active filter/sort state; instead, after updating the todoList data and
calling SaveToDoData(), stop doing the incremental append/clearing and call
renderTodoList() to rebuild the view from todoList so filters/sorts are applied;
update the places that create DOM nodes (uses of
createTodoItemDOM/todoulList.appendChild and SaveToDoData in the
add/edit/complete handlers) to remove direct appendChild and invoke
renderTodoList() after saving.
| const newTitle = input.value.trim(); | ||
| todo.title = (newTitle !== "") ? sanitizeInput(newTitle) : previousTitle; //Check for empty title | ||
| const textNode = document.createTextNode(todo.title); | ||
| li.insertBefore(textNode, input); | ||
| todo.title = (newTitle !== "") ? sanitizeInput(newTitle) : previousTitle; | ||
| todo.category = categorySelect.value; | ||
| todo.priority = prioritySelect.value; | ||
| let dueDate = null; | ||
| if (dueDateInput.value) { | ||
| // 处理时区问题,确保日期正确 | ||
| const date = new Date(dueDateInput.value); | ||
| // 设置为UTC时间的当天开始,避免时区偏移 | ||
| date.setUTCHours(0, 0, 0, 0); | ||
| dueDate = date.toISOString(); | ||
| } | ||
| todo.dueDate = dueDate; | ||
|
|
||
| // Recreate the task content and metadata | ||
| const newTaskContent = document.createElement("div"); | ||
| newTaskContent.className = "task-content"; | ||
| newTaskContent.innerHTML = sanitizeInput(todo.title); |
There was a problem hiding this comment.
Don't persist escaped HTML into todo.title.
sanitizeInput(newTitle) stores entities in the model, and the render path escapes again. Titles containing &, <, or > will be corrupted after edit and can show up as entity text later. Store raw text in todo.title and only escape at render time, preferably via textContent.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/todo-list.js` around lines 333 - 350, The code is storing escaped
HTML into the model by using sanitizeInput(newTitle) for todo.title and then
rendering with innerHTML, which double-escapes entities; instead assign the raw
trimmed text to todo.title (use previousTitle when empty) and remove
sanitizeInput from the model assignment (references: sanitizeInput, todo.title,
previousTitle), then ensure rendering uses safe text assignment rather than
innerHTML (replace newTaskContent.innerHTML usage with a text-safe render such
as setting textContent or otherwise escaping at render time) so the model keeps
raw text and escaping only happens during render.
| .todo-actions button { | ||
| padding: 5px 10px; | ||
| background-color: var(--accent-color-blue); | ||
| color: var(--whitishColor-blue); | ||
| border: none; | ||
| border-radius: 5px; | ||
| cursor: pointer; | ||
| font-size: 0.8rem; | ||
| transition: background-color 0.2s ease; | ||
| } | ||
|
|
||
| .todo-actions button:hover { | ||
| background-color: color-mix(in srgb, var(--accent-color-blue) 80%, white); | ||
| } |
There was a problem hiding this comment.
--accent-color-blue is not defined.
This file defines --darkColor-blue / --accentLightTint-blue, but not --accent-color-blue. These button backgrounds will therefore fall back to the initial value, so the import/export buttons won't get the intended theme color.
Suggested fix
.todo-actions button {
padding: 5px 10px;
- background-color: var(--accent-color-blue);
+ background-color: var(--darkColor-blue);
color: var(--whitishColor-blue);
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 0.8rem;
transition: background-color 0.2s ease;
}
.todo-actions button:hover {
- background-color: color-mix(in srgb, var(--accent-color-blue) 80%, white);
+ background-color: color-mix(in srgb, var(--darkColor-blue) 80%, white);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@style.css` around lines 1220 - 1233, The CSS uses an undefined variable
--accent-color-blue in the .todo-actions button and its :hover rule, so the
buttons fall back to initial colors; fix by either adding a definition for
--accent-color-blue (e.g., in :root where other blue variables like
--darkColor-blue and --accentLightTint-blue are defined) or update the rules to
use an existing variable name (for example --darkColor-blue or
--accentLightTint-blue) and adjust the hover color to use color-mix with that
same defined variable; update the .todo-actions button and .todo-actions
button:hover references accordingly.
| .priority-高 { | ||
| background-color: color-mix(in srgb, #ff4757 30%, transparent); | ||
| } | ||
|
|
||
| .priority-中 { | ||
| background-color: color-mix(in srgb, #ffa502 30%, transparent); | ||
| } | ||
|
|
||
| .priority-低 { | ||
| background-color: color-mix(in srgb, #2ed573 30%, transparent); | ||
| } |
There was a problem hiding this comment.
Priority badge selectors no longer match the generated class names.
scripts/todo-list.js now emits priority-high, priority-medium, and priority-low, but these rules still target the old localized class names. As a result, all priority badges render without their severity colors.
Suggested fix
-.priority-高 {
+.priority-high {
background-color: color-mix(in srgb, `#ff4757` 30%, transparent);
}
-.priority-中 {
+.priority-medium {
background-color: color-mix(in srgb, `#ffa502` 30%, transparent);
}
-.priority-低 {
+.priority-low {
background-color: color-mix(in srgb, `#2ed573` 30%, transparent);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .priority-高 { | |
| background-color: color-mix(in srgb, #ff4757 30%, transparent); | |
| } | |
| .priority-中 { | |
| background-color: color-mix(in srgb, #ffa502 30%, transparent); | |
| } | |
| .priority-低 { | |
| background-color: color-mix(in srgb, #2ed573 30%, transparent); | |
| } | |
| .priority-high { | |
| background-color: color-mix(in srgb, `#ff4757` 30%, transparent); | |
| } | |
| .priority-medium { | |
| background-color: color-mix(in srgb, `#ffa502` 30%, transparent); | |
| } | |
| .priority-low { | |
| background-color: color-mix(in srgb, `#2ed573` 30%, transparent); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@style.css` around lines 1518 - 1528, The CSS selectors for priority badges
use localized class names (.priority-高, .priority-中, .priority-低) but the JS now
emits .priority-high, .priority-medium, and .priority-low; update the selectors
in style.css to target .priority-high, .priority-medium, and .priority-low
(keeping the existing background-color/color-mix values) so the badges receive
the intended colors; also search for any other occurrences of the old localized
class names and replace them with the new English names to keep styles
consistent with scripts/todo-list.js.
📌 Description
This PR significantly enhances the To-Do List feature by adding comprehensive task management capabilities including categories, priority levels, due dates, filtering, sorting, and import/export functionality. The original To-Do List only supported basic task creation with pinned/completed status - this update transforms it into a full-featured task management system.
🎨 Visual Changes (Screenshots / Videos)
Testing
Visual Testing
Browser Compatibility
Chrome: Tested
Add task with category and priority




Filter by All/Pending/Completed/Overdue/Today

Sort by Created/Priority/Due

Pin/unpin and complete/delete tasks

Export and import JSON files

Multilingual dropdowns


🔗 Related Issues
Changes Made
scripts/todo-list.js
Added 5 task categories: Uncategorized, Work, Life, Study, Other
Added 3 priority levels: High, Medium, Low with visual badges
Added due date picker with calendar and overdue/today highlighting
Added filtering by: All, Pending, Completed, Overdue, Today
Added sorting by: Created, Priority, Due
Added import/export functionality (JSON format)
Added daily auto-reset (pinned tasks persist, unpinned completed tasks cleared)
Added browser notifications for overdue/due tasks
locales/*.js (18 language files)
Added 20 translation keys for dropdown options, buttons, and messages
Files Modified
scripts/
└── todo-list.js
locales/
✅ Checklist
🤖 AI Assistance (Coding)
Summary
This PR significantly expands the To-Do List feature from basic task creation to a comprehensive task management system. The implementation adds categories (Uncategorized, Work, Life, Study, Other), three priority levels (High, Medium, Low), due date selection with calendar picker, filtering capabilities (All, Pending, Completed, Overdue, Today), sorting options (Created, Priority, Due), JSON import/export functionality, and browser notifications for due/overdue tasks.
Changes
Core Feature Implementation
scripts/todo-list.js: Major expansion to support new data model withcategory,priority,createdAt, anddueDatefields. Added filtering and sorting logic driven by UI controls. Implemented JSON import/export functions and next-day reset with notification system. Storage backend upgraded to usechrome.storage.localwithlocalStoragefallback and legacy data migration.scripts/background.js: New background service worker handling context menu integration ("Add to To Do List") for selected text, managing todo action badge display, and scheduling hourly checks for due/overdue task notifications.manifest.jsonandmanifest(firefox).json: Version bumped to3.3.6. Added permissions forcontextMenus,storage, andnotifications. Added background service worker configuration.index.html: Expanded TodoList UI with new task-controls section (category, priority, due date selectors), separate import/export actions, and filter/sort controls using i18n keys.style.css: Comprehensive CSS updates for new todo UI elements including badge styling for priority levels and due-date states, refined dark-mode filtering, and restructured layout for todo container and task items.Internationalization
newTabTitletranslation key from multiple locale files (bn, cs, en, fr, hi, uk).Language Management
locales/sv.jsscript loading, locale switching, date formatting patterns, and weather width calculations.scripts/languages.js: AddedupdateTodoOptions()helper to dynamically update translated select option text and import/export button labels when language is applied. Stopped updating document title during language application.Infrastructure Updates
scripts/search.js: Updated language-specific hint text lookup to use direct indexing with English fallback.scripts/theme.js: Enhanced dark theme application to explicitly set.accentColorSVG fill styling to#212121.scripts/shortcuts.js: Corrected CSS class name fromshortcutDarkColortoshorcutDarkColorin preset SVG markup for YouTube, Gmail, Telegram, WhatsApp, Twitter, and Discord.scripts/bookmarks.js: Removed keyboard focus forcing on bookmark sidebar open.scripts/clock.jsandscripts/weather.js: Removed Swedish language-specific formatting patterns.Documentation and Examples
README.md: Updated language count from 32 to 31 languages, removed Swedish entry, and adjusted contributor lists.CHANGELOG.md: Removed unreleased entries for dark-mode improvements, language support updates, and widget dragging fixes.todo-import.json: Added example import file with sample todo entry.tools/languagesAnalysis.html: Removed Swedish from language analysis tool.Testing Notes
Per the PR description, Chrome testing was performed with visual screenshots demonstrating the feature across multiple languages (English, Chinese, Spanish, Korean) and showing category/priority dropdowns, calendar picker, task filtering, and JSON export functionality. Firefox compatibility verification is pending.