browser/base/content/sync/aboutSyncTabs.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 const Cu = Components.utils;
michael@0 6
michael@0 7 Cu.import("resource://services-sync/main.js");
michael@0 8 Cu.import("resource:///modules/PlacesUIUtils.jsm");
michael@0 9 Cu.import("resource://gre/modules/PlacesUtils.jsm", this);
michael@0 10 Cu.import("resource://gre/modules/Services.jsm");
michael@0 11
michael@0 12 let RemoteTabViewer = {
michael@0 13 _tabsList: null,
michael@0 14
michael@0 15 init: function () {
michael@0 16 Services.obs.addObserver(this, "weave:service:login:finish", false);
michael@0 17 Services.obs.addObserver(this, "weave:engine:sync:finish", false);
michael@0 18
michael@0 19 this._tabsList = document.getElementById("tabsList");
michael@0 20
michael@0 21 this.buildList(true);
michael@0 22 },
michael@0 23
michael@0 24 uninit: function () {
michael@0 25 Services.obs.removeObserver(this, "weave:service:login:finish");
michael@0 26 Services.obs.removeObserver(this, "weave:engine:sync:finish");
michael@0 27 },
michael@0 28
michael@0 29 buildList: function(force) {
michael@0 30 if (!Weave.Service.isLoggedIn || !this._refetchTabs(force))
michael@0 31 return;
michael@0 32 //XXXzpao We should say something about not being logged in & not having data
michael@0 33 // or tell the appropriate condition. (bug 583344)
michael@0 34
michael@0 35 this._generateTabList();
michael@0 36 },
michael@0 37
michael@0 38 createItem: function(attrs) {
michael@0 39 let item = document.createElement("richlistitem");
michael@0 40
michael@0 41 // Copy the attributes from the argument into the item
michael@0 42 for (let attr in attrs)
michael@0 43 item.setAttribute(attr, attrs[attr]);
michael@0 44
michael@0 45 if (attrs["type"] == "tab")
michael@0 46 item.label = attrs.title != "" ? attrs.title : attrs.url;
michael@0 47
michael@0 48 return item;
michael@0 49 },
michael@0 50
michael@0 51 filterTabs: function(event) {
michael@0 52 let val = event.target.value.toLowerCase();
michael@0 53 let numTabs = this._tabsList.getRowCount();
michael@0 54 let clientTabs = 0;
michael@0 55 let currentClient = null;
michael@0 56 for (let i = 0;i < numTabs;i++) {
michael@0 57 let item = this._tabsList.getItemAtIndex(i);
michael@0 58 let hide = false;
michael@0 59 if (item.getAttribute("type") == "tab") {
michael@0 60 if (!item.getAttribute("url").toLowerCase().contains(val) &&
michael@0 61 !item.getAttribute("title").toLowerCase().contains(val))
michael@0 62 hide = true;
michael@0 63 else
michael@0 64 clientTabs++;
michael@0 65 }
michael@0 66 else if (item.getAttribute("type") == "client") {
michael@0 67 if (currentClient) {
michael@0 68 if (clientTabs == 0)
michael@0 69 currentClient.hidden = true;
michael@0 70 }
michael@0 71 currentClient = item;
michael@0 72 clientTabs = 0;
michael@0 73 }
michael@0 74 item.hidden = hide;
michael@0 75 }
michael@0 76 if (clientTabs == 0)
michael@0 77 currentClient.hidden = true;
michael@0 78 },
michael@0 79
michael@0 80 openSelected: function() {
michael@0 81 let items = this._tabsList.selectedItems;
michael@0 82 let urls = [];
michael@0 83 for (let i = 0;i < items.length;i++) {
michael@0 84 if (items[i].getAttribute("type") == "tab") {
michael@0 85 urls.push(items[i].getAttribute("url"));
michael@0 86 let index = this._tabsList.getIndexOfItem(items[i]);
michael@0 87 this._tabsList.removeItemAt(index);
michael@0 88 }
michael@0 89 }
michael@0 90 if (urls.length) {
michael@0 91 getTopWin().gBrowser.loadTabs(urls);
michael@0 92 this._tabsList.clearSelection();
michael@0 93 }
michael@0 94 },
michael@0 95
michael@0 96 bookmarkSingleTab: function() {
michael@0 97 let item = this._tabsList.selectedItems[0];
michael@0 98 let uri = Weave.Utils.makeURI(item.getAttribute("url"));
michael@0 99 let title = item.getAttribute("title");
michael@0 100 PlacesUIUtils.showBookmarkDialog({ action: "add"
michael@0 101 , type: "bookmark"
michael@0 102 , uri: uri
michael@0 103 , title: title
michael@0 104 , hiddenRows: [ "description"
michael@0 105 , "location"
michael@0 106 , "loadInSidebar"
michael@0 107 , "keyword" ]
michael@0 108 }, window.top);
michael@0 109 },
michael@0 110
michael@0 111 bookmarkSelectedTabs: function() {
michael@0 112 let items = this._tabsList.selectedItems;
michael@0 113 let URIs = [];
michael@0 114 for (let i = 0;i < items.length;i++) {
michael@0 115 if (items[i].getAttribute("type") == "tab") {
michael@0 116 let uri = Weave.Utils.makeURI(items[i].getAttribute("url"));
michael@0 117 if (!uri)
michael@0 118 continue;
michael@0 119
michael@0 120 URIs.push(uri);
michael@0 121 }
michael@0 122 }
michael@0 123 if (URIs.length) {
michael@0 124 PlacesUIUtils.showBookmarkDialog({ action: "add"
michael@0 125 , type: "folder"
michael@0 126 , URIList: URIs
michael@0 127 , hiddenRows: [ "description" ]
michael@0 128 }, window.top);
michael@0 129 }
michael@0 130 },
michael@0 131
michael@0 132 getIcon: function (iconUri, defaultIcon) {
michael@0 133 try {
michael@0 134 let iconURI = Weave.Utils.makeURI(iconUri);
michael@0 135 return PlacesUtils.favicons.getFaviconLinkForIcon(iconURI).spec;
michael@0 136 } catch(ex) {
michael@0 137 // Do nothing.
michael@0 138 }
michael@0 139
michael@0 140 // Just give the provided default icon or the system's default.
michael@0 141 return defaultIcon || PlacesUtils.favicons.defaultFavicon.spec;
michael@0 142 },
michael@0 143
michael@0 144 _generateTabList: function() {
michael@0 145 let engine = Weave.Service.engineManager.get("tabs");
michael@0 146 let list = this._tabsList;
michael@0 147
michael@0 148 // clear out existing richlistitems
michael@0 149 let count = list.getRowCount();
michael@0 150 if (count > 0) {
michael@0 151 for (let i = count - 1; i >= 0; i--)
michael@0 152 list.removeItemAt(i);
michael@0 153 }
michael@0 154
michael@0 155 let seenURLs = new Set();
michael@0 156 let localURLs = engine.getOpenURLs();
michael@0 157
michael@0 158 for (let [guid, client] in Iterator(engine.getAllClients())) {
michael@0 159 // Create the client node, but don't add it in-case we don't show any tabs
michael@0 160 let appendClient = true;
michael@0 161
michael@0 162 client.tabs.forEach(function({title, urlHistory, icon}) {
michael@0 163 let url = urlHistory[0];
michael@0 164 if (!url || localURLs.has(url) || seenURLs.has(url)) {
michael@0 165 return;
michael@0 166 }
michael@0 167 seenURLs.add(url);
michael@0 168
michael@0 169 if (appendClient) {
michael@0 170 let attrs = {
michael@0 171 type: "client",
michael@0 172 clientName: client.clientName,
michael@0 173 class: Weave.Service.clientsEngine.isMobile(client.id) ? "mobile" : "desktop"
michael@0 174 };
michael@0 175 let clientEnt = this.createItem(attrs);
michael@0 176 list.appendChild(clientEnt);
michael@0 177 appendClient = false;
michael@0 178 clientEnt.disabled = true;
michael@0 179 }
michael@0 180 let attrs = {
michael@0 181 type: "tab",
michael@0 182 title: title || url,
michael@0 183 url: url,
michael@0 184 icon: this.getIcon(icon),
michael@0 185 }
michael@0 186 let tab = this.createItem(attrs);
michael@0 187 list.appendChild(tab);
michael@0 188 }, this);
michael@0 189 }
michael@0 190 },
michael@0 191
michael@0 192 adjustContextMenu: function(event) {
michael@0 193 let mode = "all";
michael@0 194 switch (this._tabsList.selectedItems.length) {
michael@0 195 case 0:
michael@0 196 break;
michael@0 197 case 1:
michael@0 198 mode = "single"
michael@0 199 break;
michael@0 200 default:
michael@0 201 mode = "multiple";
michael@0 202 break;
michael@0 203 }
michael@0 204 let menu = document.getElementById("tabListContext");
michael@0 205 let el = menu.firstChild;
michael@0 206 while (el) {
michael@0 207 let showFor = el.getAttribute("showFor");
michael@0 208 if (showFor)
michael@0 209 el.hidden = showFor != mode && showFor != "all";
michael@0 210
michael@0 211 el = el.nextSibling;
michael@0 212 }
michael@0 213 },
michael@0 214
michael@0 215 _refetchTabs: function(force) {
michael@0 216 if (!force) {
michael@0 217 // Don't bother refetching tabs if we already did so recently
michael@0 218 let lastFetch = 0;
michael@0 219 try {
michael@0 220 lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch");
michael@0 221 }
michael@0 222 catch (e) { /* Just use the default value of 0 */ }
michael@0 223 let now = Math.floor(Date.now() / 1000);
michael@0 224 if (now - lastFetch < 30)
michael@0 225 return false;
michael@0 226 }
michael@0 227
michael@0 228 // if Clients hasn't synced yet this session, need to sync it as well
michael@0 229 if (Weave.Service.clientsEngine.lastSync == 0)
michael@0 230 Weave.Service.clientsEngine.sync();
michael@0 231
michael@0 232 // Force a sync only for the tabs engine
michael@0 233 let engine = Weave.Service.engineManager.get("tabs");
michael@0 234 engine.lastModified = null;
michael@0 235 engine.sync();
michael@0 236 Services.prefs.setIntPref("services.sync.lastTabFetch",
michael@0 237 Math.floor(Date.now() / 1000));
michael@0 238
michael@0 239 return true;
michael@0 240 },
michael@0 241
michael@0 242 observe: function(subject, topic, data) {
michael@0 243 switch (topic) {
michael@0 244 case "weave:service:login:finish":
michael@0 245 this.buildList(true);
michael@0 246 break;
michael@0 247 case "weave:engine:sync:finish":
michael@0 248 if (subject == "tabs")
michael@0 249 this._generateTabList();
michael@0 250 break;
michael@0 251 }
michael@0 252 },
michael@0 253
michael@0 254 handleClick: function(event) {
michael@0 255 if (event.target.getAttribute("type") != "tab")
michael@0 256 return;
michael@0 257
michael@0 258 if (event.button == 1) {
michael@0 259 let url = event.target.getAttribute("url");
michael@0 260 openUILink(url, event);
michael@0 261 let index = this._tabsList.getIndexOfItem(event.target);
michael@0 262 this._tabsList.removeItemAt(index);
michael@0 263 }
michael@0 264 }
michael@0 265 }
michael@0 266

mercurial