1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/base/content/sync/aboutSyncTabs.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,266 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Cu = Components.utils; 1.9 + 1.10 +Cu.import("resource://services-sync/main.js"); 1.11 +Cu.import("resource:///modules/PlacesUIUtils.jsm"); 1.12 +Cu.import("resource://gre/modules/PlacesUtils.jsm", this); 1.13 +Cu.import("resource://gre/modules/Services.jsm"); 1.14 + 1.15 +let RemoteTabViewer = { 1.16 + _tabsList: null, 1.17 + 1.18 + init: function () { 1.19 + Services.obs.addObserver(this, "weave:service:login:finish", false); 1.20 + Services.obs.addObserver(this, "weave:engine:sync:finish", false); 1.21 + 1.22 + this._tabsList = document.getElementById("tabsList"); 1.23 + 1.24 + this.buildList(true); 1.25 + }, 1.26 + 1.27 + uninit: function () { 1.28 + Services.obs.removeObserver(this, "weave:service:login:finish"); 1.29 + Services.obs.removeObserver(this, "weave:engine:sync:finish"); 1.30 + }, 1.31 + 1.32 + buildList: function(force) { 1.33 + if (!Weave.Service.isLoggedIn || !this._refetchTabs(force)) 1.34 + return; 1.35 + //XXXzpao We should say something about not being logged in & not having data 1.36 + // or tell the appropriate condition. (bug 583344) 1.37 + 1.38 + this._generateTabList(); 1.39 + }, 1.40 + 1.41 + createItem: function(attrs) { 1.42 + let item = document.createElement("richlistitem"); 1.43 + 1.44 + // Copy the attributes from the argument into the item 1.45 + for (let attr in attrs) 1.46 + item.setAttribute(attr, attrs[attr]); 1.47 + 1.48 + if (attrs["type"] == "tab") 1.49 + item.label = attrs.title != "" ? attrs.title : attrs.url; 1.50 + 1.51 + return item; 1.52 + }, 1.53 + 1.54 + filterTabs: function(event) { 1.55 + let val = event.target.value.toLowerCase(); 1.56 + let numTabs = this._tabsList.getRowCount(); 1.57 + let clientTabs = 0; 1.58 + let currentClient = null; 1.59 + for (let i = 0;i < numTabs;i++) { 1.60 + let item = this._tabsList.getItemAtIndex(i); 1.61 + let hide = false; 1.62 + if (item.getAttribute("type") == "tab") { 1.63 + if (!item.getAttribute("url").toLowerCase().contains(val) && 1.64 + !item.getAttribute("title").toLowerCase().contains(val)) 1.65 + hide = true; 1.66 + else 1.67 + clientTabs++; 1.68 + } 1.69 + else if (item.getAttribute("type") == "client") { 1.70 + if (currentClient) { 1.71 + if (clientTabs == 0) 1.72 + currentClient.hidden = true; 1.73 + } 1.74 + currentClient = item; 1.75 + clientTabs = 0; 1.76 + } 1.77 + item.hidden = hide; 1.78 + } 1.79 + if (clientTabs == 0) 1.80 + currentClient.hidden = true; 1.81 + }, 1.82 + 1.83 + openSelected: function() { 1.84 + let items = this._tabsList.selectedItems; 1.85 + let urls = []; 1.86 + for (let i = 0;i < items.length;i++) { 1.87 + if (items[i].getAttribute("type") == "tab") { 1.88 + urls.push(items[i].getAttribute("url")); 1.89 + let index = this._tabsList.getIndexOfItem(items[i]); 1.90 + this._tabsList.removeItemAt(index); 1.91 + } 1.92 + } 1.93 + if (urls.length) { 1.94 + getTopWin().gBrowser.loadTabs(urls); 1.95 + this._tabsList.clearSelection(); 1.96 + } 1.97 + }, 1.98 + 1.99 + bookmarkSingleTab: function() { 1.100 + let item = this._tabsList.selectedItems[0]; 1.101 + let uri = Weave.Utils.makeURI(item.getAttribute("url")); 1.102 + let title = item.getAttribute("title"); 1.103 + PlacesUIUtils.showBookmarkDialog({ action: "add" 1.104 + , type: "bookmark" 1.105 + , uri: uri 1.106 + , title: title 1.107 + , hiddenRows: [ "description" 1.108 + , "location" 1.109 + , "loadInSidebar" 1.110 + , "keyword" ] 1.111 + }, window.top); 1.112 + }, 1.113 + 1.114 + bookmarkSelectedTabs: function() { 1.115 + let items = this._tabsList.selectedItems; 1.116 + let URIs = []; 1.117 + for (let i = 0;i < items.length;i++) { 1.118 + if (items[i].getAttribute("type") == "tab") { 1.119 + let uri = Weave.Utils.makeURI(items[i].getAttribute("url")); 1.120 + if (!uri) 1.121 + continue; 1.122 + 1.123 + URIs.push(uri); 1.124 + } 1.125 + } 1.126 + if (URIs.length) { 1.127 + PlacesUIUtils.showBookmarkDialog({ action: "add" 1.128 + , type: "folder" 1.129 + , URIList: URIs 1.130 + , hiddenRows: [ "description" ] 1.131 + }, window.top); 1.132 + } 1.133 + }, 1.134 + 1.135 + getIcon: function (iconUri, defaultIcon) { 1.136 + try { 1.137 + let iconURI = Weave.Utils.makeURI(iconUri); 1.138 + return PlacesUtils.favicons.getFaviconLinkForIcon(iconURI).spec; 1.139 + } catch(ex) { 1.140 + // Do nothing. 1.141 + } 1.142 + 1.143 + // Just give the provided default icon or the system's default. 1.144 + return defaultIcon || PlacesUtils.favicons.defaultFavicon.spec; 1.145 + }, 1.146 + 1.147 + _generateTabList: function() { 1.148 + let engine = Weave.Service.engineManager.get("tabs"); 1.149 + let list = this._tabsList; 1.150 + 1.151 + // clear out existing richlistitems 1.152 + let count = list.getRowCount(); 1.153 + if (count > 0) { 1.154 + for (let i = count - 1; i >= 0; i--) 1.155 + list.removeItemAt(i); 1.156 + } 1.157 + 1.158 + let seenURLs = new Set(); 1.159 + let localURLs = engine.getOpenURLs(); 1.160 + 1.161 + for (let [guid, client] in Iterator(engine.getAllClients())) { 1.162 + // Create the client node, but don't add it in-case we don't show any tabs 1.163 + let appendClient = true; 1.164 + 1.165 + client.tabs.forEach(function({title, urlHistory, icon}) { 1.166 + let url = urlHistory[0]; 1.167 + if (!url || localURLs.has(url) || seenURLs.has(url)) { 1.168 + return; 1.169 + } 1.170 + seenURLs.add(url); 1.171 + 1.172 + if (appendClient) { 1.173 + let attrs = { 1.174 + type: "client", 1.175 + clientName: client.clientName, 1.176 + class: Weave.Service.clientsEngine.isMobile(client.id) ? "mobile" : "desktop" 1.177 + }; 1.178 + let clientEnt = this.createItem(attrs); 1.179 + list.appendChild(clientEnt); 1.180 + appendClient = false; 1.181 + clientEnt.disabled = true; 1.182 + } 1.183 + let attrs = { 1.184 + type: "tab", 1.185 + title: title || url, 1.186 + url: url, 1.187 + icon: this.getIcon(icon), 1.188 + } 1.189 + let tab = this.createItem(attrs); 1.190 + list.appendChild(tab); 1.191 + }, this); 1.192 + } 1.193 + }, 1.194 + 1.195 + adjustContextMenu: function(event) { 1.196 + let mode = "all"; 1.197 + switch (this._tabsList.selectedItems.length) { 1.198 + case 0: 1.199 + break; 1.200 + case 1: 1.201 + mode = "single" 1.202 + break; 1.203 + default: 1.204 + mode = "multiple"; 1.205 + break; 1.206 + } 1.207 + let menu = document.getElementById("tabListContext"); 1.208 + let el = menu.firstChild; 1.209 + while (el) { 1.210 + let showFor = el.getAttribute("showFor"); 1.211 + if (showFor) 1.212 + el.hidden = showFor != mode && showFor != "all"; 1.213 + 1.214 + el = el.nextSibling; 1.215 + } 1.216 + }, 1.217 + 1.218 + _refetchTabs: function(force) { 1.219 + if (!force) { 1.220 + // Don't bother refetching tabs if we already did so recently 1.221 + let lastFetch = 0; 1.222 + try { 1.223 + lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch"); 1.224 + } 1.225 + catch (e) { /* Just use the default value of 0 */ } 1.226 + let now = Math.floor(Date.now() / 1000); 1.227 + if (now - lastFetch < 30) 1.228 + return false; 1.229 + } 1.230 + 1.231 + // if Clients hasn't synced yet this session, need to sync it as well 1.232 + if (Weave.Service.clientsEngine.lastSync == 0) 1.233 + Weave.Service.clientsEngine.sync(); 1.234 + 1.235 + // Force a sync only for the tabs engine 1.236 + let engine = Weave.Service.engineManager.get("tabs"); 1.237 + engine.lastModified = null; 1.238 + engine.sync(); 1.239 + Services.prefs.setIntPref("services.sync.lastTabFetch", 1.240 + Math.floor(Date.now() / 1000)); 1.241 + 1.242 + return true; 1.243 + }, 1.244 + 1.245 + observe: function(subject, topic, data) { 1.246 + switch (topic) { 1.247 + case "weave:service:login:finish": 1.248 + this.buildList(true); 1.249 + break; 1.250 + case "weave:engine:sync:finish": 1.251 + if (subject == "tabs") 1.252 + this._generateTabList(); 1.253 + break; 1.254 + } 1.255 + }, 1.256 + 1.257 + handleClick: function(event) { 1.258 + if (event.target.getAttribute("type") != "tab") 1.259 + return; 1.260 + 1.261 + if (event.button == 1) { 1.262 + let url = event.target.getAttribute("url"); 1.263 + openUILink(url, event); 1.264 + let index = this._tabsList.getIndexOfItem(event.target); 1.265 + this._tabsList.removeItemAt(index); 1.266 + } 1.267 + } 1.268 +} 1.269 +