├── Tab Manager ├── block.png ├── close.png ├── icon.png ├── new.png ├── pin.png ├── trash.png ├── icon48.png ├── random.png ├── horizontal.png ├── vertical.png ├── browser_action.png ├── manifest.json ├── popup.html ├── Window.js ├── background.html ├── dom.js ├── popup.css ├── Tab.js └── TabManager.js └── readme.md /Tab Manager/block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/block.png -------------------------------------------------------------------------------- /Tab Manager/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/close.png -------------------------------------------------------------------------------- /Tab Manager/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/icon.png -------------------------------------------------------------------------------- /Tab Manager/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/new.png -------------------------------------------------------------------------------- /Tab Manager/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/pin.png -------------------------------------------------------------------------------- /Tab Manager/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/trash.png -------------------------------------------------------------------------------- /Tab Manager/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/icon48.png -------------------------------------------------------------------------------- /Tab Manager/random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/random.png -------------------------------------------------------------------------------- /Tab Manager/horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/horizontal.png -------------------------------------------------------------------------------- /Tab Manager/vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/vertical.png -------------------------------------------------------------------------------- /Tab Manager/browser_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsc/Tab-Manager/HEAD/Tab Manager/browser_action.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | This is a google chrome extension which allows you to very easy & fast handle and access your tabs/windows ;) 2 | Have fun with it! 3 | 4 | (maybe there will be a documentation in the future) 5 | -------------------------------------------------------------------------------- /Tab Manager/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tab Manager", 3 | "version": "3.11", 4 | "description": "Let's you very easy and fast handle your tabs!", 5 | "icons":{"128":"icon.png","48":"icon48.png"}, 6 | "permissions": ["tabs"], 7 | "background_page":"background.html", 8 | "browser_action":{ 9 | "default_icon":"browser_action.png", 10 | "default_popup":"popup.html" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tab Manager/popup.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Tab Manager/Window.js: -------------------------------------------------------------------------------- 1 | function Window(w,t){ 2 | var This = Div("window"); 3 | This.TabManager = t; 4 | This.ID = w.id; 5 | This.Window = w; 6 | 7 | var addtab = Div("icon add"); 8 | var closewindow = Div("icon close"); 9 | if(t.Layout == "blocks"){ 10 | This.addClass("block"); 11 | }else{ 12 | addtab.addClass("windowaction"); 13 | closewindow.addClass("windowaction"); 14 | } 15 | 16 | 17 | var tabsperrow = 15; 18 | var tabs = []; 19 | for(var i = 0; i < w.tabs.length; i++){ 20 | console.log(w.tabs[i]); 21 | tabs.push(Tab(w.tabs[i],This)); 22 | if(t.Layout == "vertical"){ 23 | tabs[i].addClass("full"); 24 | } 25 | } 26 | tabs.push(closewindow); 27 | tabs.push(addtab); 28 | 29 | if(t.Layout == "blocks"){ 30 | for(var i = 1; i*i < tabs.length; i++); 31 | tabsperrow = i; 32 | }else if(t.Layout == "vertical"){ 33 | tabsperrow = 1; 34 | } 35 | 36 | 37 | 38 | for(var j = 0; j < tabs.length; j++){ 39 | if(j % tabsperrow == 0 && j && (j < tabs.length-1 || t.Layout == "blocks")){ 40 | This.appendChild(Div("newliner")); 41 | } 42 | This.appendChild(tabs[j]); 43 | 44 | } 45 | 46 | addtab.on("click",function(){ 47 | chrome.tabs.create({windowId:w.id,},function(){ 48 | This.TabManager.Restart(); 49 | }); 50 | }); 51 | 52 | closewindow.on("click",function(){ 53 | chrome.windows.remove(w.id,function(){ 54 | This.TabManager.Restart(); 55 | }); 56 | }); 57 | return This; 58 | } 59 | -------------------------------------------------------------------------------- /Tab Manager/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 63 | 64 | -------------------------------------------------------------------------------- /Tab Manager/dom.js: -------------------------------------------------------------------------------- 1 | function Tag(type,cls,content){ 2 | var tag = document.createElement(type); 3 | if(cls){ 4 | tag.className = cls; 5 | } 6 | if(content){ 7 | if(typeof content == "string"){ 8 | tag.innerHTML = content; 9 | }else{ 10 | for(var i = 2; i < arguments.length; i++){ 11 | tag.appendChild(arguments[i]); 12 | } 13 | } 14 | } 15 | tag.on = function(){ 16 | var tag = this; 17 | var args = arguments; 18 | function remove(){ 19 | for(var i = 0; i < args.length-1; i++){ 20 | tag.removeEventListener(args[i],cb); 21 | } 22 | } 23 | function cb(e){ 24 | args[args.length-1].call(tag,e,remove); 25 | } 26 | for(var i = 0; i < args.length-1; i++){ 27 | tag.addEventListener(args[i],cb); 28 | } 29 | return remove; 30 | } 31 | tag.addClass = function(cls){ 32 | var classes = this.className.split(" "); 33 | for(var i = 0; i < classes.length; i++){ 34 | if(classes[i] == cls){ 35 | return; 36 | } 37 | } 38 | classes.push(cls); 39 | this.className = classes.join(" "); 40 | } 41 | tag.removeClass = function(cls){ 42 | var classes = this.className.split(" "); 43 | for(var i = 0; i < classes.length; i++){ 44 | if(classes[i] == cls){ 45 | classes.splice(i,1); 46 | } 47 | } 48 | this.className = classes.join(" "); 49 | } 50 | tag.hasClass = function(cls){ 51 | var classes = this.className.split(" "); 52 | for(var i = 0; i < classes.length; i++){ 53 | if(classes[i] == cls){ 54 | return true; 55 | } 56 | } 57 | return false; 58 | } 59 | tag.toggleClass = function(cls){ 60 | (this.hasClass(cls)?this.removeClass:this.addClass)(cls); 61 | } 62 | tag.swapClass = function(before,after){ 63 | this.removeClass(before); 64 | this.addClass(after); 65 | } 66 | return tag; 67 | } 68 | function Div(cls,content){ 69 | var args = ["div"]; 70 | for(var i = 0; i < arguments.length; i++){ 71 | args.push(arguments[i]); 72 | } 73 | return Tag.apply(this,args); 74 | } 75 | function Ipt(type,cls, value){ 76 | var args = ["input",cls]; 77 | var tag = Tag.apply(this,args); 78 | tag.setAttribute("type",type); 79 | if(value){ 80 | tag.value = value; 81 | } 82 | return tag; 83 | } 84 | function Txt(cls,value){ 85 | var args = ["text",cls,value]; 86 | return Ipt.apply(this,args); 87 | } 88 | function Btn(value,cls){ 89 | var args = ["button",cls,value]; 90 | return Ipt.apply(this,args); 91 | } 92 | function Sel(cls,options){ 93 | var args = ["select",cls]; 94 | var tag = Tag.apply(this,args); 95 | if(!options){ 96 | options = {}; 97 | } 98 | 99 | for(var a in options){ 100 | var o = Tag("option",0,options[a]); 101 | o.value = a; 102 | tag.appendChild(o); 103 | } 104 | 105 | return tag; 106 | } -------------------------------------------------------------------------------- /Tab Manager/popup.css: -------------------------------------------------------------------------------- 1 | html{ 2 | padding:8px; 3 | margin:0px; 4 | user-select:none; 5 | } 6 | body{ 7 | padding:0px; 8 | margin:0px; 9 | -webkit-user-select:none; 10 | } 11 | .window{ 12 | width:400px; 13 | display:inline-block; 14 | position:relative; 15 | padding-top:10px; 16 | margin-top:10px; 17 | border-top:1px solid #b2b2b2; 18 | } 19 | .window.block{ 20 | border-top:none; 21 | padding-top:0px; 22 | margin-top:0px; 23 | border-left:1px solid #b2b2b2; 24 | padding-left:10px; 25 | margin-left:10px; 26 | } 27 | .window:first-child{ 28 | padding-top:0px; 29 | margin-top:0px; 30 | border-top:none; 31 | padding-left:0px; 32 | margin-left:0px; 33 | border-left:none; 34 | } 35 | .icon{ 36 | height:20px; 37 | width:20px; 38 | box-sizing:border-box; 39 | border:1px solid #b2b2b2; 40 | padding:1px; 41 | border-radius:3px; 42 | background-size:16px 16px; 43 | background-repeat:no-repeat; 44 | background-position:center; 45 | float:left; 46 | margin-left:2px; 47 | font-family:verdana; 48 | font-size:12px; 49 | user-select:none; 50 | cursor:arrow; 51 | } 52 | .icon.incognito{ 53 | border:1px solid #ff0000; 54 | } 55 | .icon:hover{ 56 | border-width:2px; 57 | padding:0px; 58 | } 59 | .tab.selected{ 60 | border:2px solid #3B5686; 61 | padding:0px; 62 | } 63 | .tab{ 64 | float:left; 65 | margin-left:2px; 66 | margin-bottom:2px; 67 | background-image:url(random.png); 68 | } 69 | .tab.full{ 70 | width:340px; 71 | background-position:2px center; 72 | } 73 | .tab.full > .tabtitle{ 74 | width:310px; 75 | height:100%; 76 | white-space:nowrap; 77 | overflow:hidden; 78 | } 79 | .tab:first-child, .newliner + .icon{ 80 | margin-left:0px; 81 | } 82 | .windowaction{ 83 | float:right; 84 | margin-right:2px; 85 | margin-left:0px; 86 | } 87 | .add{ 88 | background-image:url(new.png); 89 | } 90 | .close{ 91 | background-image:url(close.png); 92 | } 93 | .new{ 94 | background-image:url(new.png); 95 | } 96 | .trash{ 97 | background-image:url(trash.png); 98 | } 99 | .blocks{ 100 | background-image:url(block.png); 101 | } 102 | .horizontal{ 103 | background-image:url(horizontal.png); 104 | } 105 | .vertical{ 106 | background-image:url(vertical.png); 107 | } 108 | .pin{ 109 | background-image:url(pin.png); 110 | } 111 | .tab.left > .limiter, .tab.right > .limiter{ 112 | width:2px; 113 | height:20px; 114 | background-color:#000000; 115 | margin-top:-2px; 116 | 117 | } 118 | .tab.left > .limiter{ 119 | margin-left:-4px; 120 | } 121 | .tab.right > .limiter{ 122 | float:right; 123 | margin-right:-4px; 124 | } 125 | .icon.tab.expanded{ 126 | width:340px; 127 | float:left; 128 | background-position:2px center; 129 | margin-left:0px; 130 | font-family:verdana; 131 | font-size:10pt; 132 | padding-left:22px; 133 | white-space:nowrap; 134 | 135 | -webkit-user-select:none; 136 | } 137 | 138 | .newliner{ 139 | clear:both; 140 | margin-right:-2px; 141 | } 142 | input{ 143 | border:1px solid #eeeeee; 144 | border-radius:3px; 145 | height:20px; 146 | box-sizing:border-box; 147 | width:310px; 148 | } 149 | -------------------------------------------------------------------------------- /Tab Manager/Tab.js: -------------------------------------------------------------------------------- 1 | function Tab(t,w){ 2 | var limiter = Div("limiter"); 3 | var This = Div("icon tab"); 4 | 5 | This.Window = w; 6 | This.ID = t.id; 7 | This.Pinned = t.pinned; 8 | This.Tab = t; 9 | if(t.favIconUrl){ 10 | This.style.backgroundImage = "url("+t.favIconUrl+")"; 11 | } 12 | This.title = t.title; 13 | if(This.Window.TabManager.Layout == "vertical"){ 14 | This.style.paddingLeft = "20px"; 15 | This.appendChild(Div("tabtitle",This.title)); 16 | } 17 | if(t.incognito){ 18 | This.addClass("incognito"); 19 | } 20 | 21 | 22 | This.on("mousedown",function(e){ 23 | 24 | var hadClass = This.hasClass("selected"); 25 | This.addClass("selected"); 26 | if(e.shiftKey && This.Window.TabManager.LastClicked){ 27 | var tabs = This.Window.childNodes; 28 | tabs.indexOf = Array.prototype.indexOf; 29 | var i = tabs.indexOf(This.Window.TabManager.LastClicked); 30 | for(var d = i > tabs.indexOf(This)?-1:1; i >= 0 && i < tabs.length && tabs[i] != This; i += d){ 31 | tabs[i].addClass("selected"); 32 | } 33 | } 34 | This.Window.TabManager.LastClicked = This; 35 | 36 | var x = e.clientX; 37 | var y = e.clientY; 38 | 39 | var doubel = Div(); 40 | doubel.style.position = "absolute"; 41 | doubel.style.opacity = "0.0"; 42 | document.body.appendChild(doubel); 43 | 44 | var tabs = This.Window.TabManager.getElementsByClassName("tab selected"); 45 | for(var i = 0; i < tabs.length; i++){ 46 | doubel.appendChild(tabs[i].cloneNode(true)); 47 | } 48 | 49 | function onMouseMove(e){ 50 | if(Math.abs(e.clientX-x) > 5 || Math.abs(e.clientY)-y > 5){ 51 | This.Window.TabManager.Dragging = true; 52 | doubel.style.top = (e.clientY+10)+"px"; 53 | doubel.style.left = (e.clientX+10)+"px"; 54 | doubel.style.opacity = "0.5"; 55 | } 56 | } 57 | function onMouseUp(e){ 58 | document.body.removeChild(doubel); 59 | document.removeEventListener("mousemove",onMouseMove); 60 | document.removeEventListener("mouseup",onMouseUp); 61 | 62 | 63 | console.log(This.Window); 64 | if(!This.Window.TabManager.Dragging){ 65 | if(!e.ctrlKey && !e.shiftKey){ 66 | var tabs = This.Window.TabManager.getElementsByClassName("tab selected"); 67 | for(var i =0; i < tabs.length; i++){ 68 | if(tabs[i] != This){ 69 | tabs[i].removeClass("selected"); 70 | } 71 | } 72 | }else{ 73 | if(hadClass){ 74 | This.removeClass("selected"); 75 | } 76 | } 77 | } 78 | 79 | This.Window.TabManager.Dragging = false; 80 | } 81 | 82 | document.addEventListener("mousemove",onMouseMove); 83 | document.addEventListener("mouseup",onMouseUp); 84 | 85 | }); 86 | 87 | This.on("mousemove",function(e){ 88 | if(This.Window.TabManager.Dragging){ 89 | if(e.clientX > This.offsetLeft+(This.clientWidth)){ 90 | This.swapClass("left","right"); 91 | }else{ 92 | This.swapClass("right","left"); 93 | } 94 | } 95 | }); 96 | 97 | 98 | This.on("mouseout","mouseup",function(){ 99 | This.removeClass("left"); 100 | This.removeClass("right"); 101 | }); 102 | 103 | This.on("mouseup",function(e){ 104 | if(This.Window.TabManager.Dragging){ 105 | var tabs = This.Window.TabManager.getElementsByClassName("tab selected"); 106 | var index = This.Tab.index; 107 | if(This.hasClass("right")){ 108 | index++; 109 | } 110 | var t = []; 111 | for(var i = 0; i < tabs.length; i++){ 112 | t.push(tabs[i].Tab); 113 | } 114 | chrome.extension.sendRequest({action:"move",tabs:t,index:index,windowId:This.Window.ID},function(){ 115 | This.Window.TabManager.Restart(); 116 | }); 117 | }else if(!e.shiftKey && !e.ctrlKey ){ 118 | //chrome.windows.update(This.Tab.windowId,{focused:true}); 119 | chrome.tabs.update(This.ID,{selected:true}); 120 | } 121 | }); 122 | 123 | 124 | This.appendChild(limiter); 125 | 126 | return This; 127 | } 128 | -------------------------------------------------------------------------------- /Tab Manager/TabManager.js: -------------------------------------------------------------------------------- 1 | function TabManager(){ 2 | var This = Div(); 3 | 4 | 5 | 6 | This.Dragging = false; 7 | This.LastClicked = null; 8 | This.Restart = function(){ 9 | console.log("restarting"); 10 | This.Layout = localStorage["layout"]; 11 | if(!This.Layout){ 12 | This.Layout = "horizontal"; 13 | } 14 | This.innerHTML = ""; 15 | chrome.windows.getAll({populate:true},function(windows){ 16 | for(var i = 0; i < windows.length; i++){ 17 | This.appendChild(Window(windows[i],This)); 18 | } 19 | 20 | if(This.Layout == "blocks"){ 21 | var wins = This.getElementsByClassName("window"); 22 | var highest = 0; 23 | for(var i = 0; i < wins.length; i++){ 24 | console.log(wins[i].clientHeight); 25 | if(wins[i].clientHeight > highest){ 26 | highest = wins[i].clientHeight; 27 | } 28 | } 29 | for(var i = 0; i < wins.length; i++){ 30 | wins[i].style.height = highest+"px"; 31 | wins[i].style.width = "auto"; 32 | } 33 | } 34 | 35 | var addwindow; 36 | var deletetabs; 37 | var pintabs; 38 | var search; 39 | var layout; 40 | This.appendChild( 41 | Div("window", 42 | search = Txt(), 43 | layout = Div("icon windowaction "+This.Layout), 44 | deletetabs = Div("icon windowaction trash"), 45 | pintabs = Div("icon windowaction pin"), 46 | addwindow = Div("icon windowaction new") 47 | ) 48 | ); 49 | 50 | search.focus(); 51 | search.select(); 52 | 53 | deletetabs.on("click",function(){ 54 | var tabs = This.getElementsByClassName("tab selected"); 55 | if(tabs.length){ 56 | var t = []; 57 | for(var i = 0; i < tabs.length; i++){ 58 | t.push(tabs[i].Tab); 59 | } 60 | chrome.extension.sendRequest({action:"delete",tabs:t},function(){ 61 | setTimeout(This.Restart,100); 62 | }); 63 | }else{ 64 | chrome.windows.getCurrent(function(w){ 65 | console.log(w); 66 | chrome.tabs.getSelected(w.id,function(t){ 67 | chrome.tabs.remove(t.id,This.Restart); 68 | }); 69 | }); 70 | } 71 | }); 72 | function addWindow(){ 73 | var tabs = This.getElementsByClassName("tab selected"); 74 | var t = []; 75 | for(var i = 0; i < tabs.length; i++){ 76 | t.push(tabs[i].Tab); 77 | } 78 | chrome.extension.sendRequest({action:"new",tabs:t},function(){ 79 | This.Restart(); 80 | }); 81 | } 82 | addwindow.on("click",addWindow); 83 | pintabs.on("click",function(){ 84 | var tabs = This.getElementsByClassName("tab selected"); 85 | if(tabs.length ){ 86 | for(var i = 0; i < tabs.length; i++){ 87 | chrome.tabs.update(tabs[i].ID,{pinned:!tabs[i].Pinned},i==0?This.Restart:function(){}); 88 | } 89 | }else{ 90 | chrome.windows.getCurrent(function(w){ 91 | console.log(w); 92 | chrome.tabs.getSelected(w.id,function(t){ 93 | chrome.tabs.update(t.id,{pinned:!t.pinned},This.Restart); 94 | }); 95 | }); 96 | } 97 | }); 98 | 99 | search.on("keyup",function(){ 100 | var tabs = This.getElementsByClassName("tab"); 101 | for(var i = 0; i < tabs.length; i++){ 102 | var tab = tabs[i]; 103 | if((tab.Tab.title+tab.Tab.url).toLowerCase().indexOf(search.value.toLowerCase()) >= 0){ 104 | tab.addClass("selected"); 105 | }else{ 106 | tab.removeClass("selected"); 107 | } 108 | } 109 | }); 110 | search.on("keydown",function(e){ 111 | console.log(e.keyCode); 112 | if(e.keyCode == 13){ 113 | addWindow(); 114 | } 115 | }); 116 | 117 | layout.on("click",function(){ 118 | if(This.Layout == "blocks"){ 119 | localStorage["layout"] = "horizontal"; 120 | }else if(This.Layout == "horizontal"){ 121 | localStorage["layout"] = "vertical"; 122 | }else{ 123 | localStorage["layout"] = "blocks"; 124 | } 125 | This.Restart(); 126 | }); 127 | }); 128 | } 129 | This.Restart(); 130 | 131 | return This; 132 | } 133 | --------------------------------------------------------------------------------