From e71466a258a019f9ddbed7848c05dffedcfd4419 Mon Sep 17 00:00:00 2001 From: Maxim Stewart Date: Sat, 5 May 2018 20:02:50 -0500 Subject: [PATCH] New features. --- README.md | 8 ++- src/css/tabsSearch.css | 28 ++++++++- src/icons/plus.png | Bin 0 -> 5883 bytes src/manifest.json | 2 +- src/pages/tabsSearch.html | 9 ++- src/scripts/dragContainersSetup.js | 2 +- src/scripts/eventListeners.js | 37 ++++++----- src/scripts/generateView.js | 95 ++++++++++++++++++++--------- src/scripts/searchTabs.js | 6 +- 9 files changed, 134 insertions(+), 53 deletions(-) create mode 100644 src/icons/plus.png diff --git a/README.md b/README.md index cba0ce9..54f7af0 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,12 @@ Search Firefox tabs and get a list or automatic direct to the searched tab. # Download https://addons.mozilla.org/en-US/firefox/addon/tab-search-smarter/ -# Version: 1.1.6 -Fixed missing tab icon images by loading a generic when icon is unavailable. +# Version: 1.1.8 +Added To Top, To Tab, and To Bottom buttons. +Added New Tab button in tab list +Added visual indicator of currently selected tab +Set initial scroll to go to selected tab + # Images ![1 new list style](images/pic3.jpg) diff --git a/src/css/tabsSearch.css b/src/css/tabsSearch.css index 60eee58..9255704 100644 --- a/src/css/tabsSearch.css +++ b/src/css/tabsSearch.css @@ -21,6 +21,25 @@ html, body { margin-left: 1.5em; } +#udArrows { + position: fixed; + bottom: 0; + margin-left: 40%; +} + +#udArrows button { + font-size: 1.4em; + background-color: rgba(79, 186, 70, 1); + color: rgba(255,255,255,1); +} + +#udArrows button:hover { + background-color: rgba(255,255,255,1); + color: rgba(0,0,0,1); + cursor: pointer; + border-style: none; +} + #searchBar, #errorZone { width: 630px; background: rgb(255,255,255); @@ -38,9 +57,8 @@ html, body { #errorZone { color: red; border-style: dotted; - margin-top: 2em; - padding-top: 0.5em; - padding-bottom: 0.5em; + margin: 6em 0em 0em 2em; + padding: 0.5em 0em 0.5em 0em; } #listZone { @@ -68,6 +86,10 @@ html, body { color: rgba(64,64,64, 0.84); } +.block-focused { + background-color: rgba(53, 103, 14, 0.8); +} + .thumbImg { clear: left; width: 64px; diff --git a/src/icons/plus.png b/src/icons/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd00fd7dece91f19e456d8ddcb00c8807b5b214 GIT binary patch literal 5883 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 -
+
+ + +
+ + +
- diff --git a/src/scripts/dragContainersSetup.js b/src/scripts/dragContainersSetup.js index 513a435..b92cbaa 100644 --- a/src/scripts/dragContainersSetup.js +++ b/src/scripts/dragContainersSetup.js @@ -15,7 +15,7 @@ var drake = dragula() } } - browser.tabs.move(toMoveID, {index: newIndex}).then(); + tabsAction.move(toMoveID, {index: newIndex}).then(); el.className += ' ex-moved'; }).on('over', function (el, container) { container.className += ' ex-over'; diff --git a/src/scripts/eventListeners.js b/src/scripts/eventListeners.js index 0d27020..4430f6f 100644 --- a/src/scripts/eventListeners.js +++ b/src/scripts/eventListeners.js @@ -1,30 +1,37 @@ // Set click events document.addEventListener("click", (e) => { - var target = e.target; - var targetID = target.id; + var target = e.target; + var targetID = target.id; var parentElm = target.parentElement; + var id = 0; if (targetID == "closeBttn") { - var id = parseInt(parentElm.getAttribute("tabID")); + id = parseInt(parentElm.getAttribute("tabID")); - browser.tabs.remove(id).then(function () { - console.log("Removed tab..." + id) - }, onError); + browser.tabs.remove(id); parentElm.parentElement.removeChild(parentElm); } else if (targetID == "iconElm" || targetID == "faveIcon") { - if (targetID == "faveIcon") { - var id = parseInt(parentElm.parentElement.getAttribute("tabID")); - } else { - var id = parseInt(target.getAttribute("tabID")); - } + if (targetID == "faveIcon") + target = parentElm.parentElement; - browser.tabs.update(id, { active: true }).then(function () { - console.log("Selected tab..." + id) - }, onError); + oldElm.setAttribute("class", "block"); + oldElm = target; + target.setAttribute("class", "block block-focused"); + + id = parseInt(target.getAttribute("tabID")); + browser.tabs.update(id, { active: true }); + } else if (targetID == "goTop") { + window.scrollTo(0,0); + } else if (targetID == "goBottom") { + window.scrollTo(0,document.body.scrollHeight); + } else if (targetID == "goToTab") { + // Go to selected and 100px up + oldElm.scrollIntoView(); + window.scrollBy(0, -100); } }); -document.getElementById("searchBar").onkeypress = function(e){ +document.getElementById("searchBar").onkeypress = function () { searchTabs(); } diff --git a/src/scripts/generateView.js b/src/scripts/generateView.js index 137aa5c..2d592a3 100644 --- a/src/scripts/generateView.js +++ b/src/scripts/generateView.js @@ -1,50 +1,89 @@ -const tabQuery = browser.tabs.query({currentWindow: true}); -const searchBar = document.getElementById("searchBar"); -const errHandler = document.getElementById("errorZone"); -const listZone = document.getElementById("listZone"); -const notFoundText = document.createTextNode("Search not found..."); - +const tabsAction = browser.tabs; +const searchBar = document.getElementById("searchBar"); +const errHandler = document.getElementById("errorZone"); +const listZone = document.getElementById("listZone"); +const notFoundText = document.createTextNode("Search not found..."); +var oldElm = ""; +var plusTag = "" function logTabs(tabs) { // tab.url requires the `tabs` permission for (let tab of tabs) { createContainer(tab); } - // Set window position to bottom of list - window.scrollTo(0,document.body.scrollHeight); + addPlusContainer(); + // Set poped-out-window position and 100px up from selected elm + oldElm.scrollIntoView(); + window.scrollBy(0, -100); } function createContainer(tab) { - var id = tab.id; - var spanTag = document.createElement("SPAN"); - var iconText = document.createTextNode(tab.title); - var centerTag = document.createElement("CENTER"); - var closeImgTag = document.createElement("IMG"); - var icoImgTag = document.createElement("IMG"); + var id = tab.id; + var spanTag = document.createElement("SPAN"); + var iconText = document.createTextNode(tab.title); + var centerTag = document.createElement("CENTER"); + var closeImgTag = document.createElement("IMG"); + var icoImgTag = document.createElement("IMG"); - spanTag.title = tab.title; - spanTag.id = "iconElm"; - spanTag.className = "block"; - spanTag.setAttribute("tabID",tab.id); - - closeImgTag.id = "closeBttn"; + spanTag.setAttribute("tabID", tab.id); + spanTag.title = tab.title; + spanTag.id = "iconElm"; + spanTag.className = "block"; + closeImgTag.id = "closeBttn"; closeImgTag.className = "closeImg"; - closeImgTag.src = "../icons/x.png"; - - icoImgTag.id = "faveIcon"; - icoImgTag.className = "thumbImg"; - icoImgTag.onerror = function() { icoImgTag.src = "../icons/tab.png"; } - icoImgTag.src = tab.favIconUrl; + closeImgTag.src = "../icons/x.png"; + icoImgTag.id = "faveIcon"; + icoImgTag.className = "thumbImg"; + icoImgTag.onerror = function() { icoImgTag.src = "../icons/tab.png"; } + icoImgTag.src = tab.favIconUrl; centerTag.appendChild(icoImgTag); spanTag.appendChild(closeImgTag); spanTag.appendChild(centerTag); spanTag.appendChild(iconText); listZone.appendChild(spanTag); + + // Set oldElm so eventListeners.js has starting ref + if (tab.active == true) { + spanTag.className = "block block-focused"; + if (oldElm) { + oldElm.setAttribute("class", "block"); + } + oldElm = spanTag; + } } +function addPlusContainer() { + var spanTag = document.createElement("SPAN"); + var centerTag = document.createElement("CENTER"); + var icoImgTag = document.createElement("IMG"); + + spanTag .addEventListener("click", createTab); + spanTag.title = "Open a new tab..."; + spanTag.className = "block"; + icoImgTag.style = "width: 100%; height:auto"; + icoImgTag.src = "../icons/plus.png"; + + centerTag.appendChild(icoImgTag); + spanTag.appendChild(centerTag); + listZone.appendChild(spanTag); + plusTag = spanTag; +} + +function createTab() { + tabsAction.create({}) + .then(function (tab) { + createContainer(tab); + }).then(function () { + listZone.appendChild(plusTag); + }); +} function onError(error) { console.log(`Error: ${error}`); } -function getAllTabs() { tabQuery.then(logTabs, onError); } -getAllTabs(); +function getTabs(tabs) { + // Get current tab and then list of tabs + tabsAction.query({currentWindow: true}) + .then(logTabs, onError); +} +getTabs(); diff --git a/src/scripts/searchTabs.js b/src/scripts/searchTabs.js index f10fc8a..2c156ce 100644 --- a/src/scripts/searchTabs.js +++ b/src/scripts/searchTabs.js @@ -35,4 +35,8 @@ function clearNodes(targetNode) { } function loadSelTab(id) { browser.tabs.update(id, { active: true }); } -function searchTabs() { tabQuery.then(findTabs, onError); } + +function searchTabs() { + tabsAction.query({currentWindow: true}) + .then(findTabs, onError); +}