diff --git a/dist/popup/popup.css b/dist/popup/popup.css index bba6dba..459e6e8 100644 --- a/dist/popup/popup.css +++ b/dist/popup/popup.css @@ -597,7 +597,6 @@ html, body { .-tui-list-manual-filter-indicator { position: absolute; border-radius: 4px; - animation-name: pop; animation-duration: .5s; pointer-events: none; } diff --git a/dist/stylesheets/theming.css b/dist/stylesheets/theming.css index ac80584..7536ec5 100644 --- a/dist/stylesheets/theming.css +++ b/dist/stylesheets/theming.css @@ -26,6 +26,9 @@ --selected-2: rgb(37, 81, 224); --highlight-1: #ff9500; --highlight-1-translucent: #ff835426; + --highlight-2: #fde50b; + --highlight-2-translucent: #fdee4926; + --subtitle: cyan; --input-focus90: #e791ec; /*currently unused*/ --input-focus90t: #ea4af260; /*currently unused*/ @@ -70,6 +73,9 @@ --selected-2: #dce9ff; --highlight-1: #ff9500; --highlight-1-translucent: #ff835426; + --highlight-2: #fde50b; + --highlight-2-translucent: #fdee4926; + --subtitle: darkblue; --input-focus90: #e791ec; /*currently unused*/ --input-focus90t: #ea4af260; /*currently unused*/ diff --git a/src/polyfill.js b/src/polyfill.js index 26de552..d6fb9d5 100644 --- a/src/polyfill.js +++ b/src/polyfill.js @@ -312,3 +312,38 @@ globalScope["t_resetAnimation"] = function (el) { el.style.animation = null; }; +// https://stackoverflow.com/questions/3710204/how-to-check-if-a-string-is-a-valid-json-string +/** + * If you don't care about primitives and only objects then this function + * is for you, otherwise look elsewhere. + * This function will return `false` for any valid json primitive. + * EG, 'true' -> false + * '123' -> false + * 'null' -> false + * '"I'm a string"' -> false + */ +globalScope["t_tryParseJSONObject"] = function (jsonString) { + try { + var o = JSON.parse(jsonString); + + // Handle non-exception-throwing cases: + // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking, + // but... JSON.parse(null) returns null, and typeof null === "object", + // so we must check for that, too. Thankfully, null is falsey, so this suffices: + if (o && typeof o === "object") { + return o; + } + } + catch (e) { } + + return false; +}; + +globalScope["t_sanitizeXMLTags"] = function (text) { + return text.replace(/<\/?([a-zA-Z0-9]+)>/g, match => { + return match.replace('<', '<').replace('>', '>'); + }); +}; + +globalScope["t_errorToString"] = error => `${error.toString()}\n${error.stack || 'No stack trace available.'}`; + diff --git a/src/popup/popup.js b/src/popup/popup.js index a77aec0..4e9444e 100644 --- a/src/popup/popup.js +++ b/src/popup/popup.js @@ -702,8 +702,13 @@ class TUIList { }); // The key down event is also artificially activated by ArrowDown and ArrowUp listeners e.addEventListener("keydown", (evt) => { - onSelection(e, evt); - this.dataInterpret.handleClick(e, this.root.getElementsByClassName("-tui-list-selected"), evt); + // Make sure that the key down event's target matches the current hover, which should be the keydown focus theoretically. + // Otherwise, it is likely that the item was focused but not hovered over, and -tui-list-hover takes precedence over browser hover. + let lastHover = this.root.querySelector(".-tui-list-hover"); + if (evt.target.isSameNode(lastHover)) { + onSelection(e, evt); + this.dataInterpret.handleClick(e, this.root.getElementsByClassName("-tui-list-selected"), evt); + } }); let setHoverToNearest = (reason) => { // Set hover to another element @@ -1382,6 +1387,13 @@ class WindowName extends TUIEditableLabel { return `${this.__currentValue} (${this.windowOrder})`; } } + get verboseValue() { + if (this.__currentValue.trim() === "") { + return this.__initialWindowName; + } else { + return `${this.__currentValue} (Window ${this.windowOrder})`; + } + } get value() { return this.__currentValue; } @@ -1509,10 +1521,12 @@ class TUITabsList extends TUIListDataInterpret { tmp = document.createElement("div"); tmp.className = "title-wrapper"; + let tmp2 = document.createElement("span"); tmp2.className = "title"; tmp2.innerText = data.title; tmp.appendChild(tmp2); + entry.appendChild(tmp); if (data.discarded) entry.setAttribute("data-discarded", ""); diff --git a/src/tapi/ttab.js b/src/tapi/ttab.js index 0f3d4c4..8bedd75 100644 --- a/src/tapi/ttab.js +++ b/src/tapi/ttab.js @@ -10,7 +10,7 @@ export const TTAB_TRACK_UNCHANGING = ["cookieStoreId", "incognito", "openerTabId export const TTAB_TRACK = TTAB_TRACK_ONUPDATED.concat(TTAB_TRACK_ONUPDATED_MANUAL, TTAB_TRACK_ONACTIVATED, TTAB_TRACK_ONMOVED, TTAB_TRACK_ONATTACHED, TTAB_TRACK_UNCHANGING); export const TTAB_SERIALIZE = ["favIconUrl", "isArticle", "mutedInfo", "pinned", "title", "url", "hidden", "discarded", - "isInReaderMode", + "isInReaderMode", "lastAccessed", "active", "windowId", "cookieStoreId", "incognito", "openerTabId"]; @@ -150,7 +150,7 @@ export class TTab { static toTab(ttab, windowId, cookieStoreId) { // ============= FOR REFERENCE ============= // export const TTAB_SERIALIZE = ["favIconUrl", "isArticle", "mutedInfo", "pinned", "title", "url", "hidden", "discarded", - // "isInReaderMode", + // "isInReaderMode", "lastAccessed", // "active", // "windowId", // "cookieStoreId", "incognito", "openerTabId"]; "hidden" is currently not recovered, "openerTabId" must be done separately later