Bug 1260482 - Use SVGs instead of bitmaps for devices in Synced Tabs menu. r=markh
authorEdouard Oger <eoger@fastmail.com>
Tue, 10 May 2016 10:59:00 -0400
changeset 296880 9e428c5047b338037c9452bdfcb09a487ea5f0e8
parent 296879 7f5cb264eb70c1ed2680fc4487e4fafc72f2e2b6
child 296881 a9e91607762fb4637d7fc2ecb4a7055f35638d34
push id30248
push usercbook@mozilla.com
push dateWed, 11 May 2016 12:51:10 +0000
treeherdermozilla-central@91714307a799 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh
bugs1260482
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1260482 - Use SVGs instead of bitmaps for devices in Synced Tabs menu. r=markh
browser/components/syncedtabs/TabListView.js
browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js
browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js
browser/themes/linux/aboutSyncTabs.css
browser/themes/linux/jar.mn
browser/themes/linux/sync-desktopIcon.png
browser/themes/linux/sync-mobileIcon.png
browser/themes/osx/aboutSyncTabs.css
browser/themes/osx/jar.mn
browser/themes/osx/sync-desktopIcon.png
browser/themes/osx/sync-mobileIcon.png
browser/themes/shared/sync-desktopIcon.svg
browser/themes/shared/sync-mobileIcon.svg
browser/themes/shared/syncedtabs/sidebar.inc.css
browser/themes/windows/aboutSyncTabs.css
browser/themes/windows/jar.mn
browser/themes/windows/sync-desktopIcon.png
browser/themes/windows/sync-mobileIcon.png
services/sync/modules/SyncedTabs.jsm
--- a/browser/components/syncedtabs/TabListView.js
+++ b/browser/components/syncedtabs/TabListView.js
@@ -213,24 +213,26 @@ TabListView.prototype = {
     } else {
       itemNode.classList.remove("closed");
     }
     if (item.selected) {
       itemNode.classList.add("selected");
     } else {
       itemNode.classList.remove("selected");
     }
+    if (item.isMobile) {
+      itemNode.classList.add("device-image-mobile");
+    } else {
+      itemNode.classList.add("device-image-desktop");
+    }
     if (item.focused) {
       itemNode.focus();
     }
     itemNode.dataset.id = item.id;
     itemNode.querySelector(".item-title").textContent = item.name;
-
-    let icon = itemNode.querySelector(".item-icon-container");
-    icon.style.backgroundImage = "url(" + item.icon + ")";
   },
 
   /**
    * Update the element representing a tab, ensuring it's in sync with the
    * underlying data.
    * @param {tab} item - Item to use as a source.
    * @param {Element} itemNode - Element to update.
    */
--- a/browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js
+++ b/browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js
@@ -1,32 +1,32 @@
 "use strict";
 
 const FIXTURE = [
   {
     "id": "7cqCr77ptzX3",
     "type": "client",
     "name": "zcarter's Nightly on MacBook-Pro-25",
-    "icon": "chrome://browser/skin/sync-desktopIcon.png",
+    "isMobile": false,
     "tabs": [
       {
         "type": "tab",
         "title": "Firefox for Android — Mobile Web browser — More ways to customize and protect your privacy — Mozilla",
         "url": "https://www.mozilla.org/en-US/firefox/android/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
         "icon": "chrome://mozapps/skin/places/defaultFavicon.png",
         "client": "7cqCr77ptzX3",
         "lastUsed": 1452124677
       }
     ]
   },
   {
     "id": "2xU5h-4bkWqA",
     "type": "client",
     "name": "laptop",
-    "icon": "chrome://browser/skin/sync-desktopIcon.png",
+    "isMobile": false,
     "tabs": [
       {
         "type": "tab",
         "title": "Firefox for iOS — Mobile Web browser for your iPhone, iPad and iPod touch — Mozilla",
         "url": "https://www.mozilla.org/en-US/firefox/ios/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
         "icon": "moz-anno:favicon:https://www.mozilla.org/media/img/firefox/favicon.dc6635050bf5.ico",
         "client": "2xU5h-4bkWqA",
         "lastUsed": 1451519425
@@ -49,17 +49,17 @@ const FIXTURE = [
         "lastUsed": 1451519725
       }
     ]
   },
   {
     "id": "OL3EJCsdb2JD",
     "type": "client",
     "name": "desktop",
-    "icon": "chrome://browser/skin/sync-desktopIcon.png",
+    "isMobile": false,
     "tabs": []
   }
 ];
 
 let originalSyncedTabsInternal = null;
 
 function* testClean() {
   let syncedTabsDeckComponent = window.SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
--- a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js
+++ b/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js
@@ -3,17 +3,17 @@
 let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
 let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
 
 const FIXTURE = [
   {
     "id": "2xU5h-4bkWqA",
     "type": "client",
     "name": "laptop",
-    "icon": "chrome://browser/skin/sync-desktopIcon.png",
+    "isMobile": false,
     "tabs": [
       {
         "type": "tab",
         "title": "Firefox for iOS — Mobile Web browser for your iPhone, iPad and iPod touch — Mozilla",
         "url": "https://www.mozilla.org/en-US/firefox/ios/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
         "icon": "moz-anno:favicon:https://www.mozilla.org/media/img/firefox/favicon.dc6635050bf5.ico",
         "client": "2xU5h-4bkWqA",
         "lastUsed": 1451519425
@@ -27,17 +27,17 @@ const FIXTURE = [
         "lastUsed": 1451519420
       }
     ]
   },
   {
     "id": "OL3EJCsdb2JD",
     "type": "client",
     "name": "desktop",
-    "icon": "chrome://browser/skin/sync-desktopIcon.png",
+    "isMobile": false,
     "tabs": []
   }
 ];
 
 add_task(function* testGetDataEmpty() {
   let store = new SyncedTabsListStore(SyncedTabs);
   let spy = sinon.spy();
 
--- a/browser/themes/linux/aboutSyncTabs.css
+++ b/browser/themes/linux/aboutSyncTabs.css
@@ -68,20 +68,20 @@ richlistitem[type="client"] {
   margin-top: 2px;
   margin-bottom: 3px;
   width: 42em;
   border-radius: 6px;
   background-color: transparent;
   -moz-user-focus: ignore !important;
 }
 richlistitem.mobile[type="client"] {
-  list-style-image: url("chrome://browser/skin/sync-mobileIcon.png");
+  list-style-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon");
 }
 richlistitem.desktop[type="client"] {
-  list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
+  list-style-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon");
 }
 
 .title,
 .clientName {
   color: #000000;
   font-size: 1.1em;
 }
 
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -117,20 +117,20 @@ browser.jar:
   skin/classic/browser/tabbrowser/tab-stroke-end.png        (tabbrowser/tab-stroke-end.png)
   skin/classic/browser/tabbrowser/tab-stroke-start.png      (tabbrowser/tab-stroke-start.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png      (tabbrowser/tabDragIndicator.png)
 
   skin/classic/browser/sync-16.png
   skin/classic/browser/sync-32.png
   skin/classic/browser/sync-bg.png
   skin/classic/browser/sync-128.png
-  skin/classic/browser/sync-desktopIcon.png
+  skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-horizontalbar.png
   skin/classic/browser/sync-horizontalbar@2x.png
-  skin/classic/browser/sync-mobileIcon.png
+  skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/sync-notification-24.png
   skin/classic/browser/syncProgress-menuPanel.png
   skin/classic/browser/syncProgress-menuPanel@2x.png
   skin/classic/browser/syncProgress-toolbar.png
   skin/classic/browser/syncProgress-toolbar-inverted.png
   skin/classic/browser/syncSetup.css
   skin/classic/browser/syncCommon.css
   skin/classic/browser/syncQuota.css
deleted file mode 100644
index d3d1e27c32c3794e4263e23440867f5812299faf..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a3bda5751570e4a3180cc6857eb2b0f2e89b9b08..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/osx/aboutSyncTabs.css
+++ b/browser/themes/osx/aboutSyncTabs.css
@@ -68,20 +68,20 @@ richlistitem[type="client"] {
   margin-top: 2px;
   margin-bottom: 3px;
   width: 42em;
   border-radius: 6px;
   background-color: transparent;
   -moz-user-focus: ignore !important;
 }
 richlistitem.mobile[type="client"] {
-  list-style-image: url("chrome://browser/skin/sync-mobileIcon.png");
+  list-style-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon");
 }
 richlistitem.desktop[type="client"] {
-  list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
+  list-style-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon");
 }
 
 .title,
 .clientName {
   color: #000000;
   font-size: 1.1em;
 }
 
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -188,20 +188,20 @@ browser.jar:
   skin/classic/browser/tabbrowser/tab-stroke-start.png                   (tabbrowser/tab-stroke-start.png)
   skin/classic/browser/tabbrowser/tab-stroke-start@2x.png                (tabbrowser/tab-stroke-start@2x.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png                   (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/tabbrowser/tabDragIndicator@2x.png                (tabbrowser/tabDragIndicator@2x.png)
   skin/classic/browser/sync-16.png
   skin/classic/browser/sync-32.png
   skin/classic/browser/sync-bg.png
   skin/classic/browser/sync-128.png
-  skin/classic/browser/sync-desktopIcon.png
+  skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-horizontalbar.png
   skin/classic/browser/sync-horizontalbar@2x.png
-  skin/classic/browser/sync-mobileIcon.png
+  skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/sync-notification-24.png
   skin/classic/browser/syncSetup.css
   skin/classic/browser/syncCommon.css
   skin/classic/browser/syncQuota.css
   skin/classic/browser/syncProgress-horizontalbar.png
   skin/classic/browser/syncProgress-horizontalbar@2x.png
   skin/classic/browser/syncProgress-menuPanel.png
   skin/classic/browser/syncProgress-menuPanel@2x.png
deleted file mode 100644
index 4582d7d12eb8a36179faab1315ac2ffae6a941c1..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 376afde296827da2901bebc4e53fe4c1a437ea80..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/sync-desktopIcon.svg
@@ -0,0 +1,22 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    g:not(:target) { display: none; }
+
+    .glyph { fill: #4d4d4d; }
+    .glyph.translucent { fill-opacity: .15; }
+
+    .inverted .glyph { fill: #fff; }
+    .inverted .glyph.translucent { fill-opacity: .15; }
+  </style>
+  <g id="icon">
+    <path class="glyph" d="M15,14H1a1,1,0,0,1-1-1V12.526H16V13A1,1,0,0,1,15,14ZM1,4A1,1,0,0,1,2,3H14a1,1,0,0,1,1,1v8H1V4Zm1,7H14V4H2v7Z"/>
+    <rect class="glyph translucent" x="2" y="4" width="12" height="7"/>
+  </g>
+  <g id="icon-inverted" class="inverted">
+    <path class="glyph" d="M15,14H1a1,1,0,0,1-1-1V12.526H16V13A1,1,0,0,1,15,14ZM1,4A1,1,0,0,1,2,3H14a1,1,0,0,1,1,1v8H1V4Zm1,7H14V4H2v7Z"/>
+    <rect class="glyph translucent" x="2" y="4" width="12" height="7"/>
+  </g>
+</svg>
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/sync-mobileIcon.svg
@@ -0,0 +1,22 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    g:not(:target) { display: none; }
+
+    .glyph { fill: #4d4d4d; }
+    .glyph.translucent { fill-opacity: .15; }
+
+    .inverted .glyph { fill: #fff; }
+    .inverted .glyph.translucent { fill-opacity: .15; }
+  </style>
+  <g id="icon">
+    <path class="glyph" d="M12,16H4a1,1,0,0,1-1-1V1A1,1,0,0,1,4,0h8a1,1,0,0,1,1,1V15A1,1,0,0,1,12,16Zm-4-.684a0.785,0.785,0,1,0-.785-0.785A0.785,0.785,0,0,0,8,15.316ZM12,2H4V13h8V2Z"/>
+    <rect class="glyph translucent" x="4" y="2" width="8" height="11"/>
+  </g>
+  <g id="icon-inverted" class="inverted">
+    <path class="glyph" d="M12,16H4a1,1,0,0,1-1-1V1A1,1,0,0,1,4,0h8a1,1,0,0,1,1,1V15A1,1,0,0,1,12,16Zm-4-.684a0.785,0.785,0,1,0-.785-0.785A0.785,0.785,0,0,0,8,15.316ZM12,2H4V13h8V2Z"/>
+    <rect class="glyph translucent" x="4" y="2" width="8" height="11"/>
+  </g>
+</svg>
--- a/browser/themes/shared/syncedtabs/sidebar.inc.css
+++ b/browser/themes/shared/syncedtabs/sidebar.inc.css
@@ -84,16 +84,32 @@ body {
 .client .item.tab > .item-title-container {
   padding-inline-start: 35px;
 }
 
 .item.tab > .item-title-container {
   padding-inline-start: 20px;
 }
 
+.item.client.device-image-desktop > .item-title-container > .item-icon-container {
+  background-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon");
+}
+
+.item.client.device-image-desktop.selected > .item-title-container > .item-icon-container {
+  background-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon-inverted");
+}
+
+.item.client.device-image-mobile > .item-title-container > .item-icon-container {
+  background-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon");
+}
+
+.item.client.device-image-mobile.selected > .item-title-container > .item-icon-container {
+  background-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon-inverted");
+}
+
 .item.tab > .item-title-container > .item-icon-container {
   background-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 @media (min-resolution: 1.1dppx) {
 .item.tab > .item-title-container > .item-icon-container {
     background-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
   }
--- a/browser/themes/windows/aboutSyncTabs.css
+++ b/browser/themes/windows/aboutSyncTabs.css
@@ -68,20 +68,20 @@ richlistitem[type="client"] {
   margin-top: 2px;
   margin-bottom: 3px;
   width: 42em;
   border-radius: 6px;
   background-color: transparent;
   -moz-user-focus: ignore !important;
 }
 richlistitem.mobile[type="client"] {
-  list-style-image: url("chrome://browser/skin/sync-mobileIcon.png");
+  list-style-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon");
 }
 richlistitem.desktop[type="client"] {
-  list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
+  list-style-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon");
 }
 
 .title,
 .clientName {
   color: #000000;
   font-size: 1.1em;
 }
 
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -195,22 +195,22 @@ browser.jar:
   skin/classic/browser/tabbrowser/tab-stroke-end@2x.png        (tabbrowser/tab-stroke-end@2x.png)
   skin/classic/browser/tabbrowser/tab-stroke-start.png         (tabbrowser/tab-stroke-start.png)
   skin/classic/browser/tabbrowser/tab-stroke-start@2x.png      (tabbrowser/tab-stroke-start@2x.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png         (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/sync-16.png
   skin/classic/browser/sync-32.png
   skin/classic/browser/sync-128.png
   skin/classic/browser/sync-bg.png
-  skin/classic/browser/sync-desktopIcon.png
+  skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-horizontalbar.png
   skin/classic/browser/sync-horizontalbar@2x.png
   skin/classic/browser/sync-horizontalbar-XPVista7.png
   skin/classic/browser/sync-horizontalbar-XPVista7@2x.png
-  skin/classic/browser/sync-mobileIcon.png
+  skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/sync-notification-24.png
   skin/classic/browser/syncSetup.css
   skin/classic/browser/syncCommon.css
   skin/classic/browser/syncQuota.css
   skin/classic/browser/syncProgress-horizontalbar.png
   skin/classic/browser/syncProgress-horizontalbar@2x.png
   skin/classic/browser/syncProgress-horizontalbar-XPVista7.png
   skin/classic/browser/syncProgress-horizontalbar-XPVista7@2x.png
deleted file mode 100644
index e15e5b107ed570c2a96fd83a6c3219ef1186d78c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 616754860813200e32819b8f7efc9a75dd59720d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/services/sync/modules/SyncedTabs.jsm
+++ b/services/sync/modules/SyncedTabs.jsm
@@ -48,24 +48,16 @@ let log = Log.repository.getLogger("Sync
     log.level = appender.level = Log.Level[level] || Log.Level.Debug;
     log.addAppender(appender);
   }
 })();
 
 
 // A private singleton that does the work.
 let SyncedTabsInternal = {
-  _getClientIcon(id) {
-    let isMobile = Weave.Service.clientsEngine.isMobile(id);
-    if (isMobile) {
-      return "chrome://browser/skin/sync-mobileIcon.png";
-    }
-    return "chrome://browser/skin/sync-desktopIcon.png";
-  },
-
   /* Make a "tab" record. Returns a promise */
   _makeTab: Task.async(function* (client, tab, url, showRemoteIcons) {
     let icon;
     if (showRemoteIcons) {
       icon = tab.icon;
     }
     if (!icon) {
       try {
@@ -86,17 +78,17 @@ let SyncedTabsInternal = {
   }),
 
   /* Make a "client" record. Returns a promise for consistency with _makeTab */
   _makeClient: Task.async(function* (client) {
     return {
       id: client.id,
       type: "client",
       name: Weave.Service.clientsEngine.getClientName(client.id),
-      icon:  this._getClientIcon(client.id),
+      icon: Weave.Service.clientsEngine.isMobile(client.id),
       tabs: []
     };
   }),
 
   _tabMatchesFilter(tab, filter) {
     let reFilter = new RegExp(escapeRegExp(filter), "i");
     return tab.url.match(reFilter) || tab.title.match(reFilter);
   },