зеркало из https://github.com/mozilla/pjs.git
Bug 571898 - port 1.4 Sync UI for Fennec to mobile-browser [r=mbrubeck]
This commit is contained in:
Родитель
f22189c6e6
Коммит
c92b8fa018
|
@ -474,3 +474,8 @@ pref("font.default.x-western", "SwissA");
|
|||
// See bug 545869 for details on why these are set the way they are
|
||||
pref("network.buffer.cache.count", 24);
|
||||
pref("network.buffer.cache.size", 16384);
|
||||
|
||||
// sync service
|
||||
pref("services.sync.client.type", "mobile");
|
||||
pref("services.sync.registerEngines", "Tab,Bookmarks,Form,History,Password");
|
||||
pref("services.sync.autoconnectDelay", 5);
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
|
||||
<!ENTITY % remoteTabsDTD SYSTEM "chrome://browser/locale/aboutTabs.dtd" >
|
||||
%remoteTabsDTD;
|
||||
]>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&remoteTabs.title;</title>
|
||||
<link rel="icon" type="image/png" href="chrome://branding/content/favicon32.png" />
|
||||
<link rel="stylesheet" href="chrome://browser/skin/aboutTabs.css" type="text/css"/>
|
||||
</head>
|
||||
<body onload="RemoteTabViewer.show();">
|
||||
<div id="tabList">
|
||||
</div>
|
||||
|
||||
<script type="application/javascript;version=1.8"><![CDATA[
|
||||
// Make sure this is the only instance of the page
|
||||
Components.utils.import("resource://services-sync/service.js");
|
||||
Weave.Utils.ensureOneOpen(window);
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
let RemoteTabViewer = {
|
||||
get chromeWin() {
|
||||
let chromeWin = window.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem).
|
||||
rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindow).QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
|
||||
delete this.chromeWin;
|
||||
return this.chromeWin = chromeWin;
|
||||
},
|
||||
|
||||
show: function RemoteTabViewer_show() {
|
||||
// Don't do anything if the tabs engine isn't ready
|
||||
if (!Weave.Engines.get("tabs"))
|
||||
return;
|
||||
|
||||
this._maybeNotify();
|
||||
this._populateTabs();
|
||||
this._refetchTabs();
|
||||
},
|
||||
|
||||
_maybeNotify: function _maybeNotify() {
|
||||
// Don't notify if the tab engine has new tabs or the user dismissed it
|
||||
let prefs = Weave.Svc.Prefs;
|
||||
if (prefs.get("notifyTabState") == 0)
|
||||
return;
|
||||
|
||||
// No need to reshow the notification if it's still open
|
||||
let notifyBox = this.chromeWin.getNotificationBox(window);
|
||||
if (notifyBox.getNotificationWithValue("remote-tabs") != null)
|
||||
return;
|
||||
|
||||
let message = Weave.Str.sync.get("remote.notification.label");
|
||||
let notification = notifyBox.appendNotification(message, "remote-tabs", "",
|
||||
notifyBox.PRIORITY_INFO_LOW);
|
||||
|
||||
// Wrap the close function to find out if the user clicks the X
|
||||
let close = notification.close;
|
||||
notification.close = function() {
|
||||
// Once the user dismisses the dialog, remember that and don't show again
|
||||
prefs.set("notifyTabState", 0);
|
||||
close.apply(notification, arguments);
|
||||
};
|
||||
},
|
||||
|
||||
_refetchTabs: function _refetchTabs() {
|
||||
// Don't bother refetching tabs if we already did so recently
|
||||
let lastFetch = Weave.Svc.Prefs.get("lastTabFetch", 0);
|
||||
let now = Math.floor(Date.now() / 1000);
|
||||
if (now - lastFetch < 30)
|
||||
return;
|
||||
|
||||
// Asynchronously fetch the tabs
|
||||
setTimeout(function() {
|
||||
let engine = Weave.Engines.get("tabs");
|
||||
let lastSync = engine.lastSync;
|
||||
|
||||
// Force a sync only for the tabs engine
|
||||
engine.lastModified = null;
|
||||
engine.sync();
|
||||
Weave.Svc.Prefs.set("lastTabFetch", now);
|
||||
|
||||
// Only reload the page if something synced
|
||||
if (engine.lastSync != lastSync)
|
||||
location.reload();
|
||||
}, 0);
|
||||
},
|
||||
|
||||
_populateTabs: function _populateTabs() {
|
||||
// Clear out all child elements from holder first, so we don't
|
||||
// end up adding duplicate rows.
|
||||
let engine = Weave.Engines.get("tabs");
|
||||
let holder = document.getElementById("tabList");
|
||||
if (holder.hasChildNodes()) {
|
||||
while (holder.childNodes.length >= 1)
|
||||
holder.removeChild(holder.firstChild);
|
||||
}
|
||||
|
||||
// Generate the list of tabs
|
||||
let haveTabs = false;
|
||||
for (let [guid, client] in Iterator(engine.getAllClients())) {
|
||||
haveTabs = true;
|
||||
|
||||
// Create the client node, but don't add it in-case we don't show any tabs
|
||||
let appendClient = true;
|
||||
let nameNode = document.createElement("h2");
|
||||
nameNode.textContent = client.clientName;
|
||||
|
||||
client.tabs.forEach(function({title, urlHistory, icon}) {
|
||||
let pageUrl = urlHistory[0];
|
||||
|
||||
// Skip tabs that are already open
|
||||
if (engine.locallyOpenTabMatchesURL(pageUrl))
|
||||
return;
|
||||
|
||||
if (title == "")
|
||||
title = pageUrl;
|
||||
|
||||
let item = document.createElement("div");
|
||||
item.addEventListener("click", function() {
|
||||
item.setAttribute("selected", true);
|
||||
RemoteTabViewer.chromeWin.BrowserUI.newTab(pageUrl);
|
||||
}, false)
|
||||
item.setAttribute("class", "tab");
|
||||
|
||||
let img = document.createElement("img");
|
||||
img.setAttribute("class", "icon");
|
||||
img.src = Weave.Utils.getIcon(icon, "chrome://browser/skin/images/tab.png");
|
||||
|
||||
let tabDiv = document.createElement("div");
|
||||
tabDiv.setAttribute("class", "info");
|
||||
let titleNode = document.createElement("div");
|
||||
titleNode.setAttribute("class", "title");
|
||||
titleNode.textContent = title;
|
||||
let urlNode = document.createElement("div");
|
||||
urlNode.setAttribute("class", "url");
|
||||
urlNode.textContent = pageUrl;
|
||||
tabDiv.appendChild(titleNode);
|
||||
tabDiv.appendChild(urlNode);
|
||||
|
||||
item.appendChild(img);
|
||||
item.appendChild(tabDiv);
|
||||
|
||||
// Append the client name if we haven't yet
|
||||
if (appendClient) {
|
||||
appendClient = false;
|
||||
holder.appendChild(nameNode);
|
||||
}
|
||||
|
||||
holder.appendChild(item);
|
||||
});
|
||||
}
|
||||
|
||||
if (holder.childNodes.length == 0) {
|
||||
// Assume we're pending, but we might already have tabs or have synced
|
||||
let text = Weave.Str.sync.get("remote.pending.label");
|
||||
if (haveTabs)
|
||||
text = Weave.Str.sync.get("remote.opened.label");
|
||||
else if (engine.lastSync != 0)
|
||||
text = Weave.Str.sync.get("remote.missing.label");
|
||||
|
||||
let item = document.createElement("h1");
|
||||
item.textContent = text;
|
||||
document.getElementsByTagName('body')[0].appendChild(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
]]></script>
|
||||
</body>
|
||||
</html>
|
|
@ -86,6 +86,7 @@
|
|||
<script type="application/javascript" src="chrome://browser/content/TileManager.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/BrowserView.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/AnimatedZoom.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/sync.js"/>
|
||||
|
||||
<stringbundleset id="stringbundleset">
|
||||
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
|
||||
|
@ -113,6 +114,7 @@
|
|||
<!-- tabs -->
|
||||
<command id="cmd_newTab" label="&newtab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_closeTab" label="&closetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_remoteTabs" oncommand="WeaveGlue.openRemoteTabs();"/>
|
||||
|
||||
<!-- bookmarking -->
|
||||
<command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
@ -202,6 +204,7 @@
|
|||
<vbox id="tabs" onselect="BrowserUI.selectTab(this);" onclosetab="BrowserUI.closeTab(this)" flex="1"/>
|
||||
<hbox id="tabs-controls">
|
||||
<toolbarbutton id="newtab-button" class="button-image" command="cmd_newTab"/>
|
||||
<toolbarbutton id="remotetabs-button" class="button-image" disabled="true" command="cmd_remoteTabs"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
@ -431,6 +434,21 @@
|
|||
<button id="prefs-clear-data" label="&clearPrivateData.button;" command="cmd_sanitize"/>
|
||||
</setting>
|
||||
</settings>
|
||||
<settings id="prefs-sync" label="&sync.title;">
|
||||
<setting id="sync-user" type="string" title="&sync.username;" />
|
||||
<setting id="sync-pass" type="string" inputtype="password" title="&sync.password;" />
|
||||
<setting id="sync-secret" type="string" inputtype="password" title="&sync.secretPhrase;" />
|
||||
<setting id="sync-device" type="string" title="&sync.deviceName;" onchange="WeaveGlue.changeName(this)"/>
|
||||
<setting id="sync-connect" type="control">
|
||||
<button label="&sync.connect;" oncommand="WeaveGlue.connect();" />
|
||||
</setting>
|
||||
<setting id="sync-disconnect" type="control">
|
||||
<button label="&sync.disconnect;" oncommand="WeaveGlue.disconnect();" />
|
||||
</setting>
|
||||
<setting id="sync-sync" type="control">
|
||||
<button id="sync-syncButton" label="&sync.syncNow;" oncommand="WeaveGlue.sync();" />
|
||||
</setting>
|
||||
</settings>
|
||||
</richlistbox>
|
||||
</notificationbox>
|
||||
</vbox>
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Bookmarks sync code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jono DiCarlo <jdicarlo@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let WeaveGlue = {
|
||||
init: function init() {
|
||||
Components.utils.import("resource://services-sync/service.js");
|
||||
|
||||
this._addListeners();
|
||||
|
||||
// Generating keypairs is expensive on mobile, so disable it
|
||||
Weave.Service.keyGenEnabled = false;
|
||||
},
|
||||
|
||||
openRemoteTabs: function openRemoteTabs() {
|
||||
this._openTab("about:sync-tabs");
|
||||
},
|
||||
|
||||
connect: function connect() {
|
||||
Weave.Service.login(this._settings.user.value, this._settings.pass.value,
|
||||
this._settings.secret.value);
|
||||
Weave.Service.persistLogin();
|
||||
},
|
||||
|
||||
disconnect: function disconnect() {
|
||||
Weave.Service.logout();
|
||||
},
|
||||
|
||||
sync: function sync() {
|
||||
Weave.Service.sync();
|
||||
},
|
||||
|
||||
_addListeners: function _addListeners() {
|
||||
let topics = ["weave:service:sync:start", "weave:service:sync:finish",
|
||||
"weave:service:sync:error", "weave:service:login:start",
|
||||
"weave:service:login:finish", "weave:service:login:error",
|
||||
"weave:service:logout:finish"];
|
||||
|
||||
// For each topic, add or remove _updateOptions as the observer
|
||||
let addRem = function(add) topics.forEach(function(topic) Weave.Svc.
|
||||
Obs[add ? "add" : "remove"](topic, WeaveGlue._updateOptions, WeaveGlue));
|
||||
|
||||
// Add the listeners now, and remove them on unload
|
||||
addRem(true);
|
||||
addEventListener("unload", function() addRem(false), false);
|
||||
},
|
||||
|
||||
_openTab: function _openTab(url) {
|
||||
setTimeout(function() BrowserUI.newTab(url), 0);
|
||||
},
|
||||
|
||||
get _settings() {
|
||||
// Do a quick test to see if the options exist yet
|
||||
let syncButton = document.getElementById("sync-syncButton");
|
||||
if (syncButton == null)
|
||||
return;
|
||||
|
||||
// Get all the setting nodes from the add-ons display
|
||||
let settings = {};
|
||||
let ids = ["user", "pass", "secret", "device", "connect", "disconnect", "sync"];
|
||||
ids.forEach(function(id) {
|
||||
settings[id] = document.getElementById("sync-" + id);
|
||||
});
|
||||
|
||||
// Replace the getter with the collection of settings
|
||||
delete this._settings;
|
||||
return this._settings = settings;
|
||||
},
|
||||
|
||||
_updateOptions: function _updateOptions() {
|
||||
let loggedIn = Weave.Service.isLoggedIn;
|
||||
document.getElementById("remotetabs-button").disabled = !loggedIn;
|
||||
|
||||
// Make sure we're online when connecting/syncing
|
||||
Util.forceOnline();
|
||||
|
||||
// Can't do anything before settings are loaded
|
||||
if (this._settings == null)
|
||||
return;
|
||||
|
||||
// Make some aliases
|
||||
let user = this._settings.user;
|
||||
let pass = this._settings.pass;
|
||||
let secret = this._settings.secret;
|
||||
let connect = this._settings.connect;
|
||||
let device = this._settings.device;
|
||||
let disconnect = this._settings.disconnect;
|
||||
let sync = this._settings.sync;
|
||||
let syncStr = Weave.Str.sync;
|
||||
|
||||
// Make sure the options are in the right state
|
||||
user.collapsed = loggedIn;
|
||||
pass.collapsed = loggedIn;
|
||||
secret.collapsed = loggedIn;
|
||||
connect.collapsed = loggedIn;
|
||||
device.collapsed = !loggedIn;
|
||||
disconnect.collapsed = !loggedIn;
|
||||
sync.collapsed = !loggedIn;
|
||||
|
||||
// Check the lock on a timeout because it's set just after notifying
|
||||
setTimeout(Weave.Utils.bind2(this, function() {
|
||||
// Prevent certain actions when the service is locked
|
||||
if (Weave.Service.locked) {
|
||||
connect.firstChild.disabled = true;
|
||||
sync.firstChild.disabled = true;
|
||||
connect.setAttribute("title", syncStr.get("connecting.label"));
|
||||
sync.setAttribute("title", syncStr.get("lastSyncInProgress.label"));
|
||||
}
|
||||
else {
|
||||
connect.firstChild.disabled = false;
|
||||
sync.firstChild.disabled = false;
|
||||
connect.setAttribute("title", syncStr.get("disconnected.label"));
|
||||
}
|
||||
}), 0);
|
||||
|
||||
// Move the disconnect and sync settings out to make connect the last item
|
||||
let parent = connect.parentNode;
|
||||
if (!loggedIn)
|
||||
parent = parent.parentNode;
|
||||
parent.appendChild(disconnect);
|
||||
parent.appendChild(sync);
|
||||
|
||||
// Dynamically generate some strings
|
||||
let connectedStr = syncStr.get("connected.label", [Weave.Service.username]);
|
||||
disconnect.setAttribute("title", connectedStr);
|
||||
|
||||
// Show the day-of-week and time (HH:MM) of last sync
|
||||
let lastSync = Weave.Svc.Prefs.get("lastSync");
|
||||
if (lastSync != null) {
|
||||
let syncDate = new Date(lastSync).toLocaleFormat("%a %R");
|
||||
let dateStr = syncStr.get("lastSync.label", [syncDate]);
|
||||
sync.setAttribute("title", dateStr);
|
||||
}
|
||||
|
||||
// Show what went wrong with login if necessary
|
||||
let login = Weave.Status.login;
|
||||
if (login == Weave.LOGIN_SUCCEEDED)
|
||||
connect.removeAttribute("desc");
|
||||
else if (login != null)
|
||||
connect.setAttribute("desc", Weave.Str.errors.get(login));
|
||||
|
||||
// Load the values for the string inputs
|
||||
user.value = Weave.Service.username || "";
|
||||
pass.value = Weave.Service.password || "";
|
||||
secret.value = Weave.Service.passphrase || "";
|
||||
device.value = Weave.Clients.localName;
|
||||
},
|
||||
|
||||
changeName: function changeName(input) {
|
||||
// Make sure to update to a modified name, e.g., empty-string -> default
|
||||
Weave.Clients.localName = input.value;
|
||||
input.value = Weave.Clients.localName;
|
||||
}
|
||||
};
|
||||
|
||||
// Wait a little bit before loading a bunch of Weave files from service
|
||||
addEventListener("UIReady", function ready() setTimeout(function() {
|
||||
removeEventListener("UIReady", ready, false);
|
||||
setTimeout(function() WeaveGlue.init(), 5000);
|
||||
}, 0), false);
|
|
@ -16,6 +16,7 @@ chrome.jar:
|
|||
content/aboutCertError.xhtml (content/aboutCertError.xhtml)
|
||||
content/aboutCertError.css (content/aboutCertError.css)
|
||||
content/aboutHome.xhtml (content/aboutHome.xhtml)
|
||||
content/aboutTabs.xhtml (content/aboutTabs.xhtml)
|
||||
content/languages.properties (content/languages.properties)
|
||||
* content/browser.xul (content/browser.xul)
|
||||
* content/browser.js (content/browser.js)
|
||||
|
@ -58,5 +59,6 @@ chrome.jar:
|
|||
content/prompt/select.xul (content/prompt/select.xul)
|
||||
content/prompt/prompt.js (content/prompt/prompt.js)
|
||||
content/AnimatedZoom.js (content/AnimatedZoom.js)
|
||||
content/sync.js (content/sync.js)
|
||||
|
||||
% override chrome://global/content/config.xul chrome://browser/content/config.xul
|
||||
|
|
|
@ -67,6 +67,10 @@ let modules = {
|
|||
home: {
|
||||
uri: "chrome://browser/content/aboutHome.xhtml",
|
||||
privileged: true
|
||||
},
|
||||
"sync-tabs": {
|
||||
uri: "chrome://browser/content/aboutTabs.xhtml",
|
||||
privileged: true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +157,16 @@ AboutHome.prototype = {
|
|||
classID: Components.ID("{b071364f-ab68-4669-a9db-33fca168271a}")
|
||||
}
|
||||
|
||||
function AboutSyncTabs() {}
|
||||
AboutSyncTabs.prototype = {
|
||||
__proto__: AboutGeneric.prototype,
|
||||
classDescription: "About Sync Tabs",
|
||||
contractID: "@mozilla.org/network/protocol/about;1?what=sync-tabs",
|
||||
classID: Components.ID("{d503134a-f6f3-4824-bc3c-09c123177944}")
|
||||
}
|
||||
|
||||
|
||||
function NSGetModule(compMgr, fileSpec)
|
||||
XPCOMUtils.generateModule([AboutFirstrun, AboutFennec, AboutRights,
|
||||
AboutCertError, AboutFirefox, AboutHome]);
|
||||
AboutCertError, AboutFirefox, AboutHome,
|
||||
AboutSyncTabs]);
|
||||
|
|
|
@ -52,6 +52,7 @@ esac
|
|||
|
||||
MOZ_XUL_APP=1
|
||||
MOZ_ENABLE_LIBXUL=1
|
||||
MOZ_SERVICES_SYNC=1
|
||||
MOZ_NO_XPCOM_OBSOLETE=1
|
||||
if test "$LIBXUL_SDK"; then
|
||||
MOZ_XULRUNNER=1
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<!ENTITY remoteTabs.title "Tabs from my other computers">
|
|
@ -18,3 +18,11 @@
|
|||
<!ENTITY homepage.none "Blank Page">
|
||||
<!ENTITY homepage.default "&brandShortName; Start">
|
||||
<!ENTITY homepage.currentpage "Use Current Page">
|
||||
<!ENTITY sync.title "Sync">
|
||||
<!ENTITY sync.username "Username">
|
||||
<!ENTITY sync.password "Password">
|
||||
<!ENTITY sync.secretPhrase "Secret Phrase">
|
||||
<!ENTITY sync.deviceName "Device Name">
|
||||
<!ENTITY sync.connect "Connect">
|
||||
<!ENTITY sync.disconnect "Disconnect">
|
||||
<!ENTITY sync.syncNow "Sync Now">
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
locale/@AB_CD@/browser/about.dtd (%chrome/about.dtd)
|
||||
locale/@AB_CD@/browser/aboutCertError.dtd (%chrome/aboutCertError.dtd)
|
||||
locale/@AB_CD@/browser/aboutHome.dtd (%chrome/aboutHome.dtd)
|
||||
locale/@AB_CD@/browser/aboutTabs.dtd (%chrome/aboutTabs.dtd)
|
||||
locale/@AB_CD@/browser/browser.dtd (%chrome/browser.dtd)
|
||||
locale/@AB_CD@/browser/browser.properties (%chrome/browser.properties)
|
||||
locale/@AB_CD@/browser/config.dtd (%chrome/config.dtd)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
body {
|
||||
color: black;
|
||||
font-family: "Nokia Sans", Tahoma, Arial, Helvetica, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
h2 {
|
||||
background-color: lightgray;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
border-bottom: solid 1px rgb(207, 207, 207);
|
||||
min-height: 70px;
|
||||
padding-right: 32px;
|
||||
position: relative;
|
||||
}
|
||||
.tab[selected] {
|
||||
background-color: #8db8d8;
|
||||
}
|
||||
.icon {
|
||||
height: 32px;
|
||||
left: 16px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
width: 32px;
|
||||
}
|
||||
.info {
|
||||
margin-left: 32px;
|
||||
overflow: hidden;
|
||||
padding-left: 32px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.title {
|
||||
font-size: 24px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.url {
|
||||
color: blue;
|
||||
font-size: 18px;
|
||||
margin-top: 4px;
|
||||
}
|
|
@ -799,6 +799,18 @@ box[type="documenttab"]:only-child .documenttab-close {
|
|||
list-style-image: url("images/newtab-active-64.png");
|
||||
}
|
||||
|
||||
#remotetabs-button {
|
||||
list-style-image: url("images/remotetabs-default-64.png");
|
||||
}
|
||||
|
||||
#remotetabs-button:not([disabled]):hover:active {
|
||||
list-style-image: url("images/remotetabs-active-64.png");
|
||||
}
|
||||
|
||||
#remotetabs-button[disabled] {
|
||||
list-style-image: url("images/remotetabs-disabled-64.png");
|
||||
}
|
||||
|
||||
/* bookmark editor ------------------------------------------------------- */
|
||||
#bookmark-container {
|
||||
padding: 8px; /* core spacing */
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.5 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.6 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 345 B |
|
@ -6,6 +6,7 @@ chrome.jar:
|
|||
aboutPage.css (aboutPage.css)
|
||||
about.css (about.css)
|
||||
aboutHome.css (aboutHome.css)
|
||||
aboutTabs.css (aboutTabs.css)
|
||||
config.css (config.css)
|
||||
firstRun.css (firstRun.css)
|
||||
header.css (header.css)
|
||||
|
@ -67,7 +68,11 @@ chrome.jar:
|
|||
images/console-active-64.png (images/console-active-64.png)
|
||||
images/newtab-default-64.png (images/newtab-default-64.png)
|
||||
images/newtab-active-64.png (images/newtab-active-64.png)
|
||||
images/remotetabs-default-64.png (images/remotetabs-default-64.png)
|
||||
images/remotetabs-active-64.png (images/remotetabs-active-64.png)
|
||||
images/remotetabs-disabled-64.png (images/remotetabs-disabled-64.png)
|
||||
images/remotetabs-32.png (images/remotetabs-32.png)
|
||||
images/tab-32.png (images/tab-32.png)
|
||||
images/mozilla-32.png (images/mozilla-32.png)
|
||||
images/leftcap-default-64.png (images/leftcap-default-64.png)
|
||||
images/leftcap-active-64.png (images/leftcap-active-64.png)
|
||||
|
|
Загрузка…
Ссылка в новой задаче