Remove chrome queries in favor of background event listeners
This commit is contained in:
parent
5efd687e8c
commit
316e205783
179
background.js
Normal file
179
background.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
var windows = [];
|
||||
var detached = [];
|
||||
function createWindowStorage(callback){
|
||||
chrome.storage.local.set({'windows':[]},callback);
|
||||
}
|
||||
|
||||
function populateWindowStorage(callback){
|
||||
chrome.windows.getAll({'populate':true},function(result){
|
||||
result.forEach(function(currentWindow,i){
|
||||
if (currentWindow.type=="normal")
|
||||
addWindow(currentWindow,i,function(j){
|
||||
if (j==result.length-1){
|
||||
saveWindows();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clearStorage(callback){
|
||||
chrome.storage.local.clear(callback);
|
||||
}
|
||||
|
||||
function saveWindows(callback){
|
||||
chrome.storage.local.set({'windows':windows},callback);
|
||||
}
|
||||
|
||||
function getWindows(callback){
|
||||
chrome.storage.local.get("windows",callback);
|
||||
}
|
||||
|
||||
function addWindow(currentWindow,i,callback){
|
||||
if (typeof i=='function'){
|
||||
callback = i;
|
||||
}
|
||||
var tabs = currentWindow.tabs!==undefined ? currentWindow.tabs : [];
|
||||
windows.push({'id':currentWindow.id,'name':'Window', 'tabs':tabs});
|
||||
if (callback!==undefined){
|
||||
callback(i);
|
||||
}
|
||||
}
|
||||
|
||||
function findWindowById(windowId){
|
||||
var w = windows.filter(function(currentWindow){
|
||||
return currentWindow.id===windowId;
|
||||
});
|
||||
if (w.length===1){
|
||||
return {'window':w[0],'index':windows.indexOf(w[0])};
|
||||
}
|
||||
else if (w.length===0){
|
||||
throw "Could not find window with id "+windowId;
|
||||
}
|
||||
else{
|
||||
throw "Found more than one window with id "+windowId;
|
||||
}
|
||||
}
|
||||
|
||||
function findTabById(queryWindow,tabId){
|
||||
if (typeof queryWindow=="number"){
|
||||
var result = findWindowById(queryWindow);
|
||||
var windowIndex = result.index;
|
||||
queryWindow = result.window;
|
||||
}
|
||||
var t = queryWindow.tabs.filter(function(currentTab){
|
||||
return currentTab.id==tabId;
|
||||
});
|
||||
if (t.length===1){
|
||||
return {'tab':t[0],'index':queryWindow.tabs.indexOf(t[0]),'window':queryWindow,'windowIndex':windowIndex};
|
||||
}
|
||||
else if (t.length===0){
|
||||
throw "Could not find tab with id "+tabId+" in window with id "+queryWindow.id;
|
||||
}
|
||||
else{
|
||||
throw "Found more than one tab with id "+tabId+" in window with id "+queryWindow.id;
|
||||
}
|
||||
}
|
||||
|
||||
function findTabInWindow(tabId){
|
||||
for (var i=0; i<windows.length; i++){
|
||||
var resultTab = windows[i].tabs.filter(function(currentTab){
|
||||
return currentTab.id===tabId;
|
||||
});
|
||||
if (resultTab.length===1){
|
||||
return {'tab':resultTab[0],'index':windows[i].tabs.indexOf(resultTab[0]),'window':windows[i],'windowIndex':i};
|
||||
}
|
||||
}
|
||||
throw "A tab wasn't found with the id "+tabId;
|
||||
}
|
||||
|
||||
chrome.windows.onCreated.addListener(function(currentWindow){
|
||||
addWindow(currentWindow,saveWindows);
|
||||
});
|
||||
|
||||
chrome.windows.onRemoved.addListener(function(windowId){
|
||||
var result = findWindowById(windowId);
|
||||
windows.splice(result.index,1);
|
||||
saveWindows();
|
||||
});
|
||||
|
||||
chrome.tabs.onCreated.addListener(function(currentTab){
|
||||
var containingWindow = findWindowById(currentTab.windowId);
|
||||
if (containingWindow.window.tabs.indexOf(currentTab)==-1){
|
||||
containingWindow.window.tabs.push(currentTab);
|
||||
saveWindows();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,currentTab){
|
||||
var tab = findTabById(currentTab.windowId, tabId);
|
||||
tab.window.tabs[tab.index] = currentTab;
|
||||
saveWindows();
|
||||
});
|
||||
|
||||
chrome.tabs.onMoved.addListener(function(tabId,objects){
|
||||
var windowId = objects.windowId;
|
||||
var startPos = objects.fromIndex;
|
||||
var endPos = objects.toIndex;
|
||||
var tab = findTabById(windowId, tabId);
|
||||
tabs.window.tabs.splice(startPos,1);
|
||||
tabs.window.tabs.splice(endPos,0,tab.tab);
|
||||
saveWindows();
|
||||
});
|
||||
|
||||
chrome.tabs.onRemoved.addListener(function(tabId,objects){
|
||||
var windowId = objects.windowId;
|
||||
var windowClosing = objects.isWindowClosing;
|
||||
//We don't need to worry about this if the window is closing. If the window is closing, it will be handled by the window remove event.
|
||||
if (!windowClosing){
|
||||
var tab = findTabById(windowId, tabId);
|
||||
tab.window.tabs.splice(tab.index,1);
|
||||
saveWindows();
|
||||
}
|
||||
});
|
||||
|
||||
chrome.tabs.onReplaced.addListener(function(newId,oldId){
|
||||
var tab = findTabInWindow(oldId);
|
||||
tab.window.tabs[tab.index].id=newId;
|
||||
saveWindows();
|
||||
})
|
||||
|
||||
chrome.tabs.onDetached.addListener(function(tabId, objects){
|
||||
var windowId = objects.oldWindowId;
|
||||
var startPos = objects.oldPosition;
|
||||
var tab = findTabById(windowId, tabId);
|
||||
//Add it to the list of detached tabs, which can be used in onAttached.
|
||||
detached.push(tab.tab);
|
||||
tab.window.tabs.splice(tab.index,1);
|
||||
saveWindows();
|
||||
});
|
||||
|
||||
chrome.tabs.onAttached.addListener(function(tabId,objects){
|
||||
var windowId = objects.newWindowId;
|
||||
var endPos = objects.newPosition;
|
||||
var containingWindow = findWindowById(windowId);
|
||||
var detachedTab = detached.filter(function(currentTab){
|
||||
return currentTab.id===tabId;
|
||||
});
|
||||
if (detachedTab.length===1){
|
||||
detachedTab = detachedTab[0];
|
||||
containingWindow.window.tabs.splice(endPos,0,detachedTab);
|
||||
var tabIndex = detached.indexOf(detachedTab);
|
||||
//Remove it from the detached list
|
||||
detached.splice(tabIndex, 1);
|
||||
saveWindows();
|
||||
}
|
||||
});
|
||||
|
||||
//init
|
||||
chrome.storage.local.get('windows',function(result){
|
||||
console.log(result);
|
||||
});
|
||||
|
||||
|
||||
clearStorage(function(){
|
||||
createWindowStorage(function(){
|
||||
populateWindowStorage();
|
||||
});
|
||||
});
|
|
@ -27,7 +27,9 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"background":{
|
||||
"scripts":["background.js"]
|
||||
},
|
||||
"permissions":["tabs","storage","unlimitedStorage"]
|
||||
|
||||
|
||||
|
||||
}
|
286
popup.js
286
popup.js
|
@ -1,142 +1,139 @@
|
|||
var totalHeight = 0; //Total height of the body of the popup
|
||||
//Gets all windows
|
||||
function getWindows(windowList,tabList,callback){
|
||||
if (typeof tabList=='function'){
|
||||
callback = tabList;
|
||||
tabList = null;
|
||||
}
|
||||
removeChildren(windowList);
|
||||
if (tabList==null){
|
||||
chrome.windows.getAll(function(windows){
|
||||
//loop through every window and append it ot the list
|
||||
windows.forEach(function(currentWindow,i){
|
||||
getTabs(currentWindow.id,i,function(li,ul){
|
||||
li.appendChild(ul);
|
||||
windowList.appendChild(li);
|
||||
callback(li);
|
||||
});
|
||||
});
|
||||
|
||||
//Gets windows from storage
|
||||
function getStorage(callback){
|
||||
chrome.storage.local.get("windows",callback);
|
||||
}
|
||||
|
||||
function getWindows(windowList,windows,callback){
|
||||
if (typeof windows==="function"){
|
||||
callback = windows;
|
||||
getStorage(function(data){
|
||||
if (data!=null){
|
||||
setupWindows(windowList,data.windows,callback);
|
||||
}
|
||||
else{
|
||||
throw "Windows is null, this hsould never happen.";
|
||||
}
|
||||
});
|
||||
}
|
||||
else{
|
||||
tabList.forEach(function(tabs,i){
|
||||
setupTabs(tabs,i,function(li,ul){
|
||||
li.appendChild(ul);
|
||||
windowList.appendChild(li);
|
||||
callback(li);
|
||||
});
|
||||
});
|
||||
setupWindows(windowList,windows, callback);
|
||||
}
|
||||
|
||||
}
|
||||
//Gets all tabs in a window and sets them up
|
||||
function getTabs(windowId,windowIndex,callback){
|
||||
var windowTabs = []
|
||||
chrome.tabs.query({'windowId':windowId},function(tabs){
|
||||
tabs.forEach(function(currentTab){
|
||||
setupTab(currentTab,function(li){
|
||||
windowTabs.push(li);
|
||||
|
||||
function setupWindows(windowList,windows,callback){
|
||||
debugger;
|
||||
windows.forEach(function(currentWindow){
|
||||
setupWindowElement(currentWindow, function(windowLi){
|
||||
setupTabs(currentWindow.tabs, function(tabElements){
|
||||
tabElements.forEach(function(currentTab){
|
||||
windowLi.querySelector('ul.tabs').appendChild(currentTab);
|
||||
});
|
||||
windowList.appendChild(windowLi);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
setupTabs(windowTabs,windowIndex,callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//Sets up all tabs to be in their window elements
|
||||
function setupTabs(tabs,windowIndex,callback){
|
||||
function setupWindowElement(currentWindow,callback){
|
||||
var li = document.createElement("li");
|
||||
var ul = document.createElement("ul");
|
||||
var windowName = document.createElement("span");
|
||||
var windowNum = document.createElement("span");
|
||||
var seperator = document.createElement("span");
|
||||
var tabCount = document.createElement("span");
|
||||
var tabWord = document.createElement("span");
|
||||
li.classList.add("window");
|
||||
li.classList.add("noselect");
|
||||
ul.classList.add("tabs");
|
||||
ul.setAttribute("windowId", currentWindow.id);
|
||||
windowName.classList.add("windowName");
|
||||
windowName.textContent = "Window ";
|
||||
windowNum.classList.add("windowIndex");
|
||||
windowNum.textContent = (windowIndex+1).toString();
|
||||
windowName.textContent = currentWindow.name;
|
||||
seperator.textContent=" - "
|
||||
tabCount.classList.add("tabCount");
|
||||
tabCount.textContent = tabs.length.toString();
|
||||
tabCount.textContent = currentWindow.tabs.length.toString();
|
||||
tabWord.classList.add("tabWord");
|
||||
tabWord.textContent = (tabs.length>1 ? " tabs":" tab");
|
||||
tabWord.textContent = (currentWindow.tabs.length>1 ? " tabs":" tab");
|
||||
li.appendChild(windowName);
|
||||
li.appendChild(windowNum);
|
||||
li.appendChild(seperator)
|
||||
li.appendChild(tabCount);
|
||||
li.appendChild(tabWord);
|
||||
tabs.forEach(function(currentTab){
|
||||
ul.appendChild(currentTab);
|
||||
});
|
||||
callback(li,ul);
|
||||
console.log(currentWindow.tabs);
|
||||
li.appendChild(ul);
|
||||
callback(li);
|
||||
}
|
||||
|
||||
function setupTab(currentTab,callback){
|
||||
var li = document.createElement("li");
|
||||
var textSpan = document.createElement("span");
|
||||
var closeButton = document.createElement("i");
|
||||
var pinButton = document.createElement("i");
|
||||
closeButton.classList.add("fa");
|
||||
closeButton.classList.add("fa-remove");
|
||||
closeButton.classList.add("close");
|
||||
closeButton.classList.add("noselect");
|
||||
closeButton.classList.add("pointer");
|
||||
pinButton.classList.add("fa");
|
||||
pinButton.classList.add("fa-thumb-tack");
|
||||
pinButton.classList.add("pin");
|
||||
pinButton.classList.add("noselect");
|
||||
closeButton.classList.add("pointer");
|
||||
if (currentTab.pinned){
|
||||
pinButton.classList.add("pinned");
|
||||
}
|
||||
li.classList.add("tab");
|
||||
li.classList.add("noselect");
|
||||
li.classList.add("pointer");
|
||||
//Setup favicon
|
||||
li.style.backgroundImage = "url(\'"+(currentTab.favIconUrl!==undefined && currentTab.favIconUrl!==null ? currentTab.favIconUrl:"img/default-favicon.png")+"\')";
|
||||
textSpan.classList.add("tabName");
|
||||
textSpan.textContent=currentTab.title;
|
||||
if (textSpan.textContent==""){
|
||||
textSpan.textContent="Untitled";
|
||||
}
|
||||
|
||||
closeButton.onclick = function(event){
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
chrome.tabs.remove(currentTab.id);
|
||||
decrementTabCount(li);
|
||||
li.parentNode.removeChild(li);
|
||||
}
|
||||
pinButton.onclick = function(event){
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (currentTab.pinned || pinButton.classList.contains('pinned')){
|
||||
pinButton.classList.remove("pinned");
|
||||
chrome.tabs.update(currentTab.id, {'pinned':false});
|
||||
}
|
||||
else{
|
||||
function setupTabs(tabs,callback){
|
||||
var tabElements = [];
|
||||
tabs.forEach(function(currentTab){
|
||||
var li = document.createElement("li");
|
||||
var textSpan = document.createElement("span");
|
||||
var closeButton = document.createElement("i");
|
||||
var pinButton = document.createElement("i");
|
||||
li.setAttribute('tabId', currentTab.id);
|
||||
closeButton.classList.add("fa");
|
||||
closeButton.classList.add("fa-remove");
|
||||
closeButton.classList.add("close");
|
||||
closeButton.classList.add("noselect");
|
||||
closeButton.classList.add("pointer");
|
||||
pinButton.classList.add("fa");
|
||||
pinButton.classList.add("fa-thumb-tack");
|
||||
pinButton.classList.add("pin");
|
||||
pinButton.classList.add("noselect");
|
||||
closeButton.classList.add("pointer");
|
||||
if (currentTab.pinned){
|
||||
pinButton.classList.add("pinned");
|
||||
chrome.tabs.update(currentTab.id, {'pinned':true});
|
||||
}
|
||||
}
|
||||
//Switches to the tab clicked
|
||||
li.onclick = function(event){
|
||||
event.stopPropagation();
|
||||
chrome.windows.getCurrent(function(resultWindow){
|
||||
if (currentTab.id!=resultWindow.id){
|
||||
chrome.windows.update(currentTab.windowId,{'focused':true});
|
||||
li.classList.add("tab");
|
||||
li.classList.add("noselect");
|
||||
li.classList.add("pointer");
|
||||
//Setup favicon
|
||||
li.style.backgroundImage = "url(\'"+(currentTab.favIconUrl!==undefined && currentTab.favIconUrl!==null ? currentTab.favIconUrl:"img/default-favicon.png")+"\')";
|
||||
textSpan.classList.add("tabName");
|
||||
textSpan.textContent=currentTab.title;
|
||||
if (textSpan.textContent==""){
|
||||
textSpan.textContent="Untitled";
|
||||
}
|
||||
|
||||
closeButton.onclick = function(event){
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
chrome.tabs.remove(currentTab.id);
|
||||
decrementTabCount(li);
|
||||
li.parentNode.removeChild(li);
|
||||
setHeights();
|
||||
}
|
||||
pinButton.onclick = function(event){
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (currentTab.pinned || pinButton.classList.contains('pinned')){
|
||||
pinButton.classList.remove("pinned");
|
||||
chrome.tabs.update(currentTab.id, {'pinned':false});
|
||||
}
|
||||
chrome.tabs.update(currentTab.id,{'highlighted':true,'active':true});
|
||||
});
|
||||
}
|
||||
|
||||
li.appendChild(textSpan);
|
||||
textSpan.appendChild(pinButton);
|
||||
textSpan.appendChild(closeButton);
|
||||
callback(li);
|
||||
else{
|
||||
pinButton.classList.add("pinned");
|
||||
chrome.tabs.update(currentTab.id, {'pinned':true});
|
||||
}
|
||||
}
|
||||
//Switches to the tab clicked
|
||||
li.onclick = function(event){
|
||||
event.stopPropagation();
|
||||
chrome.windows.getCurrent(function(resultWindow){
|
||||
if (currentTab.id!=resultWindow.id){
|
||||
chrome.windows.update(currentTab.windowId,{'focused':true});
|
||||
}
|
||||
chrome.tabs.update(currentTab.id,{'highlighted':true,'active':true});
|
||||
});
|
||||
}
|
||||
|
||||
li.appendChild(textSpan);
|
||||
textSpan.appendChild(pinButton);
|
||||
textSpan.appendChild(closeButton);
|
||||
tabElements.push(li);
|
||||
});
|
||||
callback(tabElements);
|
||||
}
|
||||
|
||||
function decrementTabCount(tabLi){
|
||||
|
@ -156,34 +153,9 @@ function decrementTabCount(tabLi){
|
|||
throw "Not a tab li";
|
||||
}
|
||||
if (num===0){
|
||||
var index = li.querySelector("span.windowIndex");
|
||||
if (index==null){
|
||||
throw "Not a tab li";
|
||||
}
|
||||
index = parseInt(index.textContent);
|
||||
decrementWindowCount(li.parentNode,index);
|
||||
windows.removeChild(li);
|
||||
}
|
||||
totalHeight = 0;
|
||||
Array.prototype.slice.call(windows.childNodes).forEach(function(child){
|
||||
setHeights(child);
|
||||
});
|
||||
}
|
||||
//Decremeent every window with a lower number than it
|
||||
function decrementWindowCount(windowList,minWindow){
|
||||
Array.prototype.slice.call(windowList.childNodes).forEach(function(child){
|
||||
if (child.tagName.toLowerCase()!='li' || !child.classList.contains("window")){
|
||||
return;
|
||||
}
|
||||
Array.prototype.slice.call(child.childNodes).forEach(function(child2){
|
||||
if (child2.tagName.toLowerCase()!='span' || !child2.classList.contains("windowIndex")){
|
||||
return;
|
||||
}
|
||||
if (parseInt(child2.textContent)>minWindow){
|
||||
child2.textContent=(parseInt(child2.textContent)-1).toString();
|
||||
}
|
||||
});
|
||||
});
|
||||
setHeights();
|
||||
}
|
||||
|
||||
function removeChildren(element){
|
||||
|
@ -191,41 +163,25 @@ function removeChildren(element){
|
|||
element.removeChild(child);
|
||||
});
|
||||
}
|
||||
|
||||
function createSearchableWindows(callback){
|
||||
var result = [];
|
||||
chrome.windows.getAll(function(windows){
|
||||
var tabs = [];
|
||||
windows.forEach(function(currentWindow,i){
|
||||
getTabs(currentWindow.id,i,function(li,ul){
|
||||
tabs = Array.prototype.slice.call(ul.childNodes);
|
||||
result.push(tabs);
|
||||
if (i==windows.length-1){
|
||||
callback(result);
|
||||
}
|
||||
function search(query,callback){
|
||||
getStorage(function(windows){
|
||||
windows = windows.windows;
|
||||
console.log(windows);
|
||||
windows.forEach(function(currentWindow){
|
||||
currentWindow.tabs = currentWindow.tabs.filter(function(currentTab){
|
||||
return currentTab.title.toLowerCase().indexOf(query)>-1;
|
||||
});
|
||||
});
|
||||
callback(windows);
|
||||
});
|
||||
}
|
||||
function search(query,windows,callback){
|
||||
windows = windows.slice(); //Clone the JSON object so we don't modify the origional
|
||||
windows.forEach(function(tabs,i){
|
||||
matchedTabs = [];
|
||||
tabs.forEach(function(currentTab){
|
||||
if (currentTab.textContent.toLowerCase().indexOf(query.toLowerCase())>-1)
|
||||
matchedTabs.push(currentTab);
|
||||
});
|
||||
windows[i] = matchedTabs;
|
||||
});
|
||||
callback(windows);
|
||||
}
|
||||
function setHeights(tabs){
|
||||
function setHeights(){
|
||||
var windows = document.getElementById("windows");
|
||||
var body = document.getElementsByTagName("body")[0];
|
||||
var html = document.getElementsByTagName("html")[0];
|
||||
totalHeight+=tabs.clientHeight;
|
||||
var height = 600+"px";
|
||||
if (totalHeight<600){
|
||||
height = totalHeight+"px";
|
||||
var height = windows.offsetHeight+"px";
|
||||
if (windows.offsetHeight>=600){
|
||||
height = "600px";
|
||||
}
|
||||
html.style.height = height;
|
||||
body.style.height = height;
|
||||
|
@ -235,11 +191,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
var filterInput = document.getElementById("search");
|
||||
getWindows(mainList,setHeights);
|
||||
filterInput.oninput = function(){
|
||||
createSearchableWindows(function(result){
|
||||
search(filterInput.value,result,function(windows){
|
||||
totalHeight = 0;
|
||||
getWindows(mainList, windows, setHeights);
|
||||
});
|
||||
search(filterInput.value,function(windows){
|
||||
removeChildren(mainList);
|
||||
getWindows(mainList,windows,setHeights);
|
||||
});
|
||||
};
|
||||
});
|
Loading…
Reference in a new issue