[JAEGER] Merge from tracemonkey.

This commit is contained in:
David Mandelin 2010-08-09 11:36:39 -07:00
Родитель 67cc55f592 7d5c3109d3
Коммит d9ba7c5740
891 изменённых файлов: 29335 добавлений и 23401 удалений

Просмотреть файл

@ -713,6 +713,7 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = {
{&nsAccessibilityAtoms::aria_grabbed, ATTR_VALTOKEN },
{&nsAccessibilityAtoms::aria_haspopup, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsAccessibilityAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsAccessibilityAtoms::aria_label, ATTR_BYPASSOBJ },
{&nsAccessibilityAtoms::aria_labelledby, ATTR_BYPASSOBJ },
{&nsAccessibilityAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
{&nsAccessibilityAtoms::aria_live, ATTR_VALTOKEN },

Просмотреть файл

@ -69,6 +69,9 @@ nsAccDocManager::GetDocAccessible(nsIDocument *aDocument)
if (!aDocument)
return nsnull;
// Ensure CacheChildren is called before we query cache.
nsAccessNode::GetApplicationAccessible()->EnsureChildren();
nsDocAccessible *docAcc =
mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
if (docAcc)

Просмотреть файл

@ -2694,16 +2694,9 @@ nsAccessible::Shutdown()
nsresult
nsAccessible::GetARIAName(nsAString& aName)
{
// First check for label override via aria-label property
nsAutoString label;
if (mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label,
label)) {
label.CompressWhitespace();
aName = label;
return NS_OK;
}
// Second check for label override via aria-labelledby relationship
// aria-labelledby now takes precedence over aria-label
nsresult rv = nsTextEquivUtils::
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_labelledby, label);
if (NS_SUCCEEDED(rv)) {
@ -2711,7 +2704,14 @@ nsAccessible::GetARIAName(nsAString& aName)
aName = label;
}
return rv;
if (label.IsEmpty() &&
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label,
label)) {
label.CompressWhitespace();
aName = label;
}
return NS_OK;
}
nsresult

Просмотреть файл

@ -44,7 +44,6 @@
#include "nsTextEquivUtils.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNSHTMLInputElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDOMNSEditableElement.h"
@ -122,30 +121,23 @@ nsHTMLCheckboxAccessible::GetStateInternal(PRUint32 *aState,
*aState |= nsIAccessibleStates::STATE_CHECKABLE;
PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked
PRBool mixed = PR_FALSE; // or mixed.
PRBool state = PR_FALSE; // Radio buttons and check boxes can be checked or mixed
nsCOMPtr<nsIDOMNSHTMLInputElement> html5CheckboxElement =
do_QueryInterface(mContent);
if (html5CheckboxElement) {
html5CheckboxElement->GetIndeterminate(&mixed);
if (mixed) {
*aState |= nsIAccessibleStates::STATE_MIXED;
return NS_OK; // indeterminate can't be checked at the same time.
}
}
nsCOMPtr<nsIDOMHTMLInputElement> htmlCheckboxElement =
do_QueryInterface(mContent);
if (htmlCheckboxElement) {
htmlCheckboxElement->GetChecked(&checked);
if (checked)
*aState |= nsIAccessibleStates::STATE_CHECKED;
}
htmlCheckboxElement->GetIndeterminate(&state);
if (state) {
*aState |= nsIAccessibleStates::STATE_MIXED;
} else { // indeterminate can't be checked at the same time.
htmlCheckboxElement->GetChecked(&state);
if (state)
*aState |= nsIAccessibleStates::STATE_CHECKED;
}
}
return NS_OK;
}

Просмотреть файл

@ -2,6 +2,7 @@
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=475006
https://bugzilla.mozilla.org/show_bug.cgi?id=391829
https://bugzilla.mozilla.org/show_bug.cgi?id=581952
-->
<head>
<title>Group attributes tests</title>
@ -69,6 +70,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391829
testAttrs("statusChild", {"container-live-role" : "status"}, true);
testAttrs("timerChild", {"container-live-role" : "timer"}, true);
// absent aria-label and aria-labelledby object attribute
testAbsentAttrs("label", {"label" : "foo"});
testAbsentAttrs("labelledby", {"labelledby" : "label"});
// container that has no default live attribute
testAttrs("liveGroup", {"live" : "polite"}, true);
testAttrs("liveGroupChild", {"container-live" : "polite"}, true);
@ -93,11 +98,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391829
title="Extend nsARIAMap to capture ARIA attribute characteristics">
Mozilla Bug 475006
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
title="Add support for container-live-role to object attributes">
Mozilla Bug 391829
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
title="Add support for container-live-role to object attributes">
Mozilla Bug 391829
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=581952"
title="Make explicit that aria-label is not an object attribute">
Mozilla Bug 475006
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -129,6 +139,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391829
<div id="status" role="status">excuse <div id="statusChild">me</div></div>
<div id="timer" role="timer">excuse <div id="timerChild">me</div></div>
<!-- aria-label[ledby] should not be an object attribute -->
<div id="label" role="checkbox" aria-label="foo"></div>
<div id="labelledby" role="checkbox" aria-labelledby="label"></div>
<!-- unusual live case -->
<div id="liveGroup" role="group" aria-live="polite">
excuse <div id="liveGroupChild">me</div>

Просмотреть файл

@ -69,8 +69,8 @@
<!-- bricks -->
<ruleset id="aria">
<rule attr="aria-label" type="string"/>
<rule attr="aria-labelledby" type="ref"/>
<rule attr="aria-label" type="string"/>
</ruleset>
<ruleset id="htmlctrl_start">

Просмотреть файл

@ -23,8 +23,8 @@
// Simple label provided via ARIA
testName("btn_simple_aria_label", "I am a button");
// aria-label and aria-labelledby, expect aria-label
testName("btn_both_aria_labels", "I am a button, two");
// aria-label and aria-labelledby, expect aria-labelledby
testName("btn_both_aria_labels", "text I am a button, two");
//////////////////////////////////////////////////////////////////////////
// aria-labelledby
@ -207,7 +207,7 @@
<br/>
<!-- aria-label plus aria-labelledby -->
<span id="btn_both_aria_labels" role="button" aria-label="I am a button, two"
aria-labelledby="labelledby_text"/>
aria-labelledby="labelledby_text btn_both_aria_labels"/>
<br/>
<!-- aria-labelledby, single relation -->

Просмотреть файл

@ -30,8 +30,8 @@
// Simple label provided via ARIA
testName("btn_simple_aria_label", "I am a button");
// aria-label and aria-labelledby, expect aria-label
testName("btn_both_aria_labels", "I am a button, two");
// aria-label and aria-labelledby, expect aria-labelledby
testName("btn_both_aria_labels", "text I am a button, two");
//////////////////////////////////////////////////////////////////////////
// aria-labelledby
@ -205,9 +205,10 @@
<!-- aria-label, simple label -->
<button id="btn_simple_aria_label" aria-label="I am a button"/>
<!-- aria-label plus aria-labelledby -->
<button id="btn_both_aria_labels" aria-label="I am a button, two"
aria-labelledby="labelledby_text"/>
aria-labelledby="labelledby_text btn_both_aria_labels"/>
<!-- aria-labelledby, single relation -->
<description id="labelledby_text">text</description>

Просмотреть файл

@ -83,10 +83,9 @@
<pre id="test">
</pre>
<!-- button, aria-label, preferred to aria-labelledby -->
<!-- aria-labelledby preferred to aria-label -->
<button id="btn_aria_label"
aria-label="button label"
aria-labelledby="btn_aria_labelledby_text">1</button>
aria-label="button label">1</button>
<br/>
<!-- button, aria-labelledby, preferred to html:label -->
@ -109,10 +108,9 @@
<!-- button, no content, name from @title -->
<button id="btn_title" title="title"></button>
<!-- input, aria-label, preferred to aria-labelledby -->
<!-- input, aria-label -->
<input type="button" id="input_aria_label"
aria-label="button label"
aria-labelledby="aria_labelledby_text_for_input"
value="1"/>
<br/>

Просмотреть файл

@ -61,10 +61,9 @@
<pre id="test">
</pre>
<!-- aria-label, preferred to aria-labelledby -->
<!-- aria-label -->
<a id="aria_label" href="mozilla.org"
aria-label="anchor label"
aria-labelledby="text">1</a>
aria-label="anchor label">1</a>
<br/>
<!-- aria-labelledby, preferred to html:label -->

Просмотреть файл

@ -148,7 +148,7 @@
<tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
tabbrowser="tabbrowser"
setfocus="false">
<tab class="tabbrowser-tab" selected="true"/>
<tab class="tabbrowser-tab" selected="true" fadein="true"/>
</tabs>
<tabbrowser id="tabbrowser"
type="content-primary"

Просмотреть файл

@ -244,6 +244,10 @@ ifeq ($(OS_ARCH),WINNT)
#
ifndef GNU_CC
LDFLAGS += /HEAP:0x40000
ifeq ($(OS_TEST),x86_64)
# set stack to 2MB on x64 build. See bug 582910
LDFLAGS += -STACK:2097152
endif
endif
endif

Просмотреть файл

@ -16,5 +16,5 @@ pref("extensions.testpilot.dataUploadURL", "https://testpilot.mozillalabs.com/su
pref("extensions.testpilot.homepageURL", "https://testpilot.mozillalabs.com/");
pref("extensions.input.happyURL", "https://input.mozilla.com/happy");
pref("extensions.input.sadURL", "https://input.mozilla.com/sad");
pref("extensions.input.happyURL", "http://input.mozilla.com/happy");
pref("extensions.input.sadURL", "http://input.mozilla.com/sad");

Просмотреть файл

@ -85,6 +85,24 @@ pref("app.update.timer", 600000);
// The interval to check for updates (app.update.interval) is defined in
// firefox-branding.js
// Enables some extra Application Update Logging (can reduce performance)
pref("app.update.log", false);
// The |app.update.certs.| preference branch contains branches that are
// sequentially numbered starting at 1 that contain attribute name / value
// pairs for the certificate used by the server that hosts the update xml file
// as specified in the |app.update.url| preference. When these preferences are
// present the following conditions apply for a successful update check:
// 1. the uri scheme must be https
// 2. the preference name must exist as an attribute name on the certificate and
// the value for the name must be the same as the value for the attribute name
// on the certificate.
// If these conditions aren't met it will be treated the same as when there is
// no update available. This validation will not be performed when using the
// |app.update.url.override| preference for update checking.
pref("app.update.certs.1.issuerName", "OU=Equifax Secure Certificate Authority,O=Equifax,C=US");
pref("app.update.certs.1.commonName", "*.mozilla.org");
// Whether or not app updates are enabled
pref("app.update.enabled", true);
@ -100,7 +118,7 @@ pref("app.update.auto", true);
// 1 download no prompt download no prompt if no incompatibilities
// 2 download no prompt prompt
//
// See chart in nsUpdateService.js.in for more details
// See chart in nsUpdateService.js source for more details
//
pref("app.update.mode", 1);
@ -325,6 +343,7 @@ pref("browser.tabs.opentabfor.middleclick", true);
pref("browser.tabs.loadDivertedInBackground", false);
pref("browser.tabs.loadBookmarksInBackground", false);
pref("browser.tabs.tabClipWidth", 140);
pref("browser.tabs.animate", true);
// Where to show tab close buttons:
// 0 on active tab only
@ -913,3 +932,82 @@ pref("browser.taskbar.lists.tasks.enabled", true);
pref("browser.taskbar.lists.refreshInSeconds", 30);
#endif
#endif
#ifdef MOZ_SERVICES_SYNC
// The sync engines to use.
pref("services.sync.registerEngines", "Bookmarks,Form,History,Password,Prefs,Tab");
// Preferences to be synced by default
pref("services.sync.prefs.sync.accessibility.blockautorefresh", true);
pref("services.sync.prefs.sync.accessibility.browsewithcaret", true);
pref("services.sync.prefs.sync.accessibility.typeaheadfind", true);
pref("services.sync.prefs.sync.accessibility.typeaheadfind.linksonly", true);
pref("services.sync.prefs.sync.app.update.mode", true);
pref("services.sync.prefs.sync.browser.download.manager.closeWhenDone", true);
pref("services.sync.prefs.sync.browser.download.manager.retention", true);
pref("services.sync.prefs.sync.browser.download.manager.scanWhenDone", true);
pref("services.sync.prefs.sync.browser.download.manager.showWhenStarting", true);
pref("services.sync.prefs.sync.browser.formfill.enable", true);
pref("services.sync.prefs.sync.browser.link.open_newwindow", true);
pref("services.sync.prefs.sync.browser.offline-apps.notify", true);
pref("services.sync.prefs.sync.browser.safebrowsing.enabled", true);
pref("services.sync.prefs.sync.browser.safebrowsing.malware.enabled", true);
pref("services.sync.prefs.sync.browser.search.selectedEngine", true);
pref("services.sync.prefs.sync.browser.search.update", true);
pref("services.sync.prefs.sync.browser.startup.homepage", true);
pref("services.sync.prefs.sync.browser.startup.page", true);
pref("services.sync.prefs.sync.browser.tabs.autoHide", true);
pref("services.sync.prefs.sync.browser.tabs.closeButtons", true);
pref("services.sync.prefs.sync.browser.tabs.loadInBackground", true);
pref("services.sync.prefs.sync.browser.tabs.warnOnClose", true);
pref("services.sync.prefs.sync.browser.tabs.warnOnOpen", true);
pref("services.sync.prefs.sync.browser.urlbar.autocomplete.enabled", true);
pref("services.sync.prefs.sync.browser.urlbar.autoFill", true);
pref("services.sync.prefs.sync.browser.urlbar.default.behavior", true);
pref("services.sync.prefs.sync.browser.urlbar.maxRichResults", true);
pref("services.sync.prefs.sync.dom.disable_open_during_load", true);
pref("services.sync.prefs.sync.dom.disable_window_flip", true);
pref("services.sync.prefs.sync.dom.disable_window_move_resize", true);
pref("services.sync.prefs.sync.dom.disable_window_open_feature.status", true);
pref("services.sync.prefs.sync.dom.disable_window_status_change", true);
pref("services.sync.prefs.sync.dom.event.contextmenu.enabled", true);
pref("services.sync.prefs.sync.extensions.personas.current", true);
pref("services.sync.prefs.sync.extensions.update.enabled", true);
pref("services.sync.prefs.sync.general.autoScroll", true);
pref("services.sync.prefs.sync.general.smoothScroll", true);
pref("services.sync.prefs.sync.intl.accept_languages", true);
pref("services.sync.prefs.sync.javascript.enabled", true);
pref("services.sync.prefs.sync.layout.spellcheckDefault", true);
pref("services.sync.prefs.sync.lightweightThemes.isThemeSelected", true);
pref("services.sync.prefs.sync.lightweightThemes.usedThemes", true);
pref("services.sync.prefs.sync.network.cookie.cookieBehavior", true);
pref("services.sync.prefs.sync.network.cookie.lifetimePolicy", true);
pref("services.sync.prefs.sync.permissions.default.image", true);
pref("services.sync.prefs.sync.pref.advanced.images.disable_button.view_image", true);
pref("services.sync.prefs.sync.pref.advanced.javascript.disable_button.advanced", true);
pref("services.sync.prefs.sync.pref.downloads.disable_button.edit_actions", true);
pref("services.sync.prefs.sync.pref.privacy.disable_button.cookie_exceptions", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.cache", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.cookies", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.downloads", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.formdata", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.history", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.offlineApps", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.passwords", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.sessions", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.siteSettings", true);
pref("services.sync.prefs.sync.privacy.sanitize.sanitizeOnShutdown", true);
pref("services.sync.prefs.sync.security.OCSP.disable_button.managecrl", true);
pref("services.sync.prefs.sync.security.OCSP.enabled", true);
pref("services.sync.prefs.sync.security.OCSP.require", true);
pref("services.sync.prefs.sync.security.default_personal_cert", true);
pref("services.sync.prefs.sync.security.enable_ssl3", true);
pref("services.sync.prefs.sync.security.enable_tls", true);
pref("services.sync.prefs.sync.security.warn_entering_secure", true);
pref("services.sync.prefs.sync.security.warn_entering_weak", true);
pref("services.sync.prefs.sync.security.warn_leaving_secure", true);
pref("services.sync.prefs.sync.security.warn_submit_insecure", true);
pref("services.sync.prefs.sync.security.warn_viewing_mixed", true);
pref("services.sync.prefs.sync.signon.rememberSignons", true);
pref("services.sync.prefs.sync.spellchecker.dictionary", true);
pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
#endif

Просмотреть файл

@ -0,0 +1,80 @@
<?xml version="1.0"?>
# ***** 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 Weave.
#
# The Initial Developer of the Original Code is the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Edward Lee <edilee@mozilla.com>
# Mike Connor <mconnor@mozilla.com>
# Paul OShannessy <paul@oshannessy.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 *****
<bindings id="tabBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="tab-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox flex="1">
<xul:vbox pack="start">
<xul:image class="tabIcon"
xbl:inherits="src=icon"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:label xbl:inherits="value=title,selected"
crop="end" flex="1" class="title"/>
<xul:label xbl:inherits="value=url,selected"
crop="end" flex="1" class="url"/>
</xul:vbox>
</xul:hbox>
</content>
<handlers>
<handler event="dblclick" button="0">
<![CDATA[
RemoteTabViewer.openSelected();
]]>
</handler>
</handlers>
</binding>
<binding id="client-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox pack="start" align="center" onfocus="event.target.blur()" onselect="return false;">
<xul:image/>
<xul:label xbl:inherits="value=clientName"
class="clientName"
crop="center" flex="1"/>
</xul:hbox>
</content>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,7 @@
richlistitem[type="tab"] {
-moz-binding: url(chrome://browser/content/aboutSyncTabs-bindings.xml#tab-listing);
}
richlistitem[type="client"] {
-moz-binding: url(chrome://browser/content/aboutSyncTabs-bindings.xml#client-listing);
}

Просмотреть файл

@ -0,0 +1,272 @@
/* ***** 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 Weave.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Edward Lee <edilee@mozilla.com>
* Mike Connor <mconnor@mozilla.com>
* Paul OShannessy <paul@oshannessy.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 ***** */
const Cu = Components.utils;
Cu.import("resource://services-sync/service.js");
Cu.import("resource:///modules/PlacesUIUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let RemoteTabViewer = {
_tabsList: null,
init: function () {
Services.obs.addObserver(this, "weave:service:login:finish", false);
Services.obs.addObserver(this, "weave:engine:sync:finish", false);
this._tabsList = document.getElementById("tabsList");
this.buildList(true);
},
uninit: function () {
Services.obs.removeObserver(this, "weave:service:login:finish");
Services.obs.removeObserver(this, "weave:engine:sync:finish");
},
buildList: function(force) {
if (!Weave.Service.isLoggedIn || !this._refetchTabs(force))
return;
//XXXzpao We should say something about not being logged in & not having data
// or tell the appropriate condition. (bug 583344)
this._generateTabList();
},
createItem: function(attrs) {
let item = document.createElement("richlistitem");
// Copy the attributes from the argument into the item
for (let attr in attrs)
item.setAttribute(attr, attrs[attr]);
if (attrs["type"] == "tab")
item.label = attrs.title != "" ? attrs.title : attrs.url;
return item;
},
filterTabs: function(event) {
let val = event.target.value.toLowerCase();
let numTabs = this._tabsList.getRowCount();
let clientTabs = 0;
let currentClient = null;
for (let i = 0;i < numTabs;i++) {
let item = this._tabsList.getItemAtIndex(i);
let hide = false;
if (item.getAttribute("type") == "tab") {
if (item.getAttribute("url").toLowerCase().indexOf(val) == -1 &&
item.getAttribute("title").toLowerCase().indexOf(val) == -1)
hide = true;
else
clientTabs++;
}
else if (item.getAttribute("type") == "client") {
if (currentClient) {
if (clientTabs == 0)
currentClient.hidden = true;
}
currentClient = item;
clientTabs = 0;
}
item.hidden = hide;
}
if (clientTabs == 0)
currentClient.hidden = true;
},
openSelected: function() {
let items = this._tabsList.selectedItems;
let urls = [];
for (let i = 0;i < items.length;i++) {
if (items[i].getAttribute("type") == "tab") {
urls.push(items[i].getAttribute("url"));
let index = this._tabsList.getIndexOfItem(items[i]);
this._tabsList.removeItemAt(index);
}
}
if (urls.length) {
getTopWin().gBrowser.loadTabs(urls);
this._tabsList.clearSelection();
}
},
bookmarkSingleTab: function() {
let item = this._tabsList.selectedItems[0];
let uri = Weave.Utils.makeURI(item.getAttribute("url"));
let title = item.getAttribute("title");
PlacesUIUtils.showMinimalAddBookmarkUI(uri, title);
},
bookmarkSelectedTabs: function() {
let items = this._tabsList.selectedItems;
let URIs = [];
for (let i = 0;i < items.length;i++) {
if (items[i].getAttribute("type") == "tab") {
let uri = Weave.Utils.makeURI(items[i].getAttribute("url"));
if (!uri)
continue;
URIs.push(uri);
}
}
if (URIs.length)
PlacesUIUtils.showMinimalAddMultiBookmarkUI(URIs);
},
_generateTabList: function() {
let engine = Weave.Engines.get("tabs");
let list = this._tabsList;
// clear out existing richlistitems
let count = list.getRowCount();
if (count > 0) {
for (let i = count - 1; i >= 0; i--)
list.removeItemAt(i);
}
for (let [guid, client] in Iterator(engine.getAllClients())) {
// Create the client node, but don't add it in-case we don't show any tabs
let appendClient = true;
let seenURLs = {};
client.tabs.forEach(function({title, urlHistory, icon}) {
let url = urlHistory[0];
if (engine.locallyOpenTabMatchesURL(url) || url in seenURLs)
return;
seenURLs[url] = null;
if (appendClient) {
let attrs = {
type: "client",
clientName: client.clientName,
class: Weave.Clients.isMobile(client.id) ? "mobile" : "desktop"
};
let clientEnt = this.createItem(attrs);
list.appendChild(clientEnt);
appendClient = false;
clientEnt.disabled = true;
}
let attrs = {
type: "tab",
title: title || url,
url: url,
icon: Weave.Utils.getIcon(icon)
}
let tab = this.createItem(attrs);
list.appendChild(tab);
}, this);
}
},
adjustContextMenu: function(event) {
let mode = "all";
switch (this._tabsList.selectedItems.length) {
case 0:
break;
case 1:
mode = "single"
break;
default:
mode = "multiple";
break;
}
let menu = document.getElementById("tabListContext");
let el = menu.firstChild;
while (el) {
let showFor = el.getAttribute("showFor");
if (showFor)
el.hidden = showFor != mode && showFor != "all";
el = el.nextSibling;
}
},
_refetchTabs: function(force) {
if (!force) {
// Don't bother refetching tabs if we already did so recently
let lastFetch = 0;
try {
lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch");
}
catch (e) { /* Just use the default value of 0 */ }
let now = Math.floor(Date.now() / 1000);
if (now - lastFetch < 30)
return false;
}
// if Clients hasn't synced yet this session, need to sync it as well
if (Weave.Clients.lastSync == 0)
Weave.Clients.sync();
// Force a sync only for the tabs engine
let engine = Weave.Engines.get("tabs");
engine.lastModified = null;
engine.sync();
Services.prefs.setIntPref("services.sync.lastTabFetch",
Math.floor(Date.now() / 1000));
return true;
},
observe: function(subject, topic, data) {
switch (topic) {
case "weave:service:login:finish":
this.buildList(true);
break;
case "weave:engine:sync:finish":
if (subject == "tabs")
this._generateTabList();
break;
}
},
handleClick: function(event) {
if (event.target.getAttribute("type") != "tab")
return;
if (event.button == 1) {
let url = event.target.getAttribute("url");
openUILink(url, event);
let index = this._tabsList.getIndexOfItem(event.target);
this._tabsList.removeItemAt(index);
}
}
}

Просмотреть файл

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
# ***** 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 Weave.
#
# The Initial Developer of the Original Code is the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Edward Lee <edilee@mozilla.com>
# Mike Connor <mconnor@mozilla.com>
# Paul OShannessy <paul@oshannessy.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 *****
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/aboutSyncTabs.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/aboutSyncTabs.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % aboutSyncTabsDTD SYSTEM "chrome://browser/locale/aboutSyncTabs.dtd">
%aboutSyncTabsDTD;
]>
<window id="tabs-display"
onload="RemoteTabViewer.init()"
onunload="RemoteTabViewer.uninit()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="&tabs.otherComputers.label;">
<script type="application/javascript;version=1.8" src="chrome://browser/content/aboutSyncTabs.js"/>
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
<html:head>
<html:link rel="icon" href="chrome://browser/skin/sync-16.png"/>
</html:head>
<popupset id="contextmenus">
<popup id="tabListContext">
<menuitem label="&tabs.context.openTab.label;"
accesskey="&tabs.context.openTab.accesskey;"
oncommand="RemoteTabViewer.openSelected()"
showFor="single"/>
<menuitem label="&tabs.context.bookmarkSingleTab.label;"
accesskey="&tabs.context.bookmarkSingleTab.accesskey;"
oncommand="RemoteTabViewer.bookmarkSingleTab(event)"
showFor="single"/>
<menuitem label="&tabs.context.openMultipleTabs.label;"
accesskey="&tabs.context.openMultipleTabs.accesskey;"
oncommand="RemoteTabViewer.openSelected()"
showFor="multiple"/>
<menuitem label="&tabs.context.bookmarkMultipleTabs.label;"
accesskey="&tabs.context.bookmarkMultipleTabs.accesskey;"
oncommand="RemoteTabViewer.bookmarkSelectedTabs()"
showFor="multiple"/>
<menuseparator/>
<menuitem label="&tabs.context.refreshList.label;"
accesskey="&tabs.context.refreshList.accesskey;"
oncommand="RemoteTabViewer.buildList()"
showFor="all"/>
</popup>
</popupset>
<richlistbox context="tabListContext" id="tabsList" seltype="multiple"
align="center" flex="1"
onclick="RemoteTabViewer.handleClick(event)"
oncontextmenu="RemoteTabViewer.adjustContextMenu(event)">
<hbox id="headers" align="center">
<label id="tabsListHeading"
value="&tabs.otherComputers.label;"/>
<spacer flex="1"/>
<textbox type="search"
emptytext="&tabs.searchText.label;"
oncommand="RemoteTabViewer.filterTabs(event)"/>
</hbox>
</richlistbox>
</window>

Просмотреть файл

@ -501,6 +501,12 @@
<menuseparator id="endHistorySeparator"
class="hide-if-empty-places-result"
builder="end"/>
#ifdef MOZ_SERVICES_SYNC
<menuitem id="sync-tabs-menuitem"
label="&syncTabsMenu.label;"
oncommand="BrowserOpenSyncTabs();"
disabled="true"/>
#endif
<menu id="historyUndoMenu"
label="&historyUndoMenu.label;"
disabled="true">
@ -600,6 +606,35 @@
label="&addons.label;"
accesskey="&addons.accesskey;"
command="Tools:Addons"/>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-menu will be showing at once -->
<menuitem id="sync-setup"
label="&syncSetup.label;"
accesskey="&syncSetup.accesskey;"
oncommand="gSyncUI.openSetup()"/>
<menu id="sync-menu"
label="&syncMenu.label;"
accesskey="&syncMenu.accesskey;">
<menupopup id="sync-menu-popup"
onpopupshowing="if (event.target == this) gSyncUI.doUpdateMenu(event);">
<menuitem id="sync-loginitem"
label="&syncLogInItem.label;"
accesskey="&syncLogInItem.accesskey;"
oncommand="gSyncUI.doLogin();"/>
<menuitem id="sync-logoutitem"
label="&syncLogOutItem.label;"
accesskey="&syncLogOutItem.accesskey;"
oncommand="gSyncUI.doLogout();"/>
<menuitem id="sync-syncnowitem"
label="&syncSyncNowItem.label;"
accesskey="&syncSyncNowItem.accesskey;"
oncommand="gSyncUI.doSync(event);"/>
<menuseparator id="sync-lastsyncsep" hidden="true"/>
<menuitem id="sync-lastsyncitem"
disabled="true" hidden="true"/>
</menupopup>
</menu>
#endif
<menuseparator id="devToolsSeparator"/>
<menuitem id="menu_pageinspect"
type="checkbox"

Просмотреть файл

@ -736,6 +736,28 @@ HistoryMenu.prototype = {
"for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
},
toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() {
// This is a no-op if MOZ_SERVICES_SYNC isn't defined
#ifdef MOZ_SERVICES_SYNC
// enable/disable the Tabs From Other Computers menu
let menuitem = document.getElementById("sync-tabs-menuitem");
// If Sync isn't configured yet, then don't show the menuitem.
if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
menuitem.setAttribute("hidden", true);
return;
}
// The tabs engine might never be inited (if services.sync.registerEngines
// is modified), so make sure we avoid undefined errors.
let enabled = Weave.Service.isLoggedIn && Weave.Engines.get("tabs") &&
Weave.Engines.get("tabs").enabled;
menuitem.setAttribute("disabled", !enabled);
menuitem.setAttribute("hidden", false);
#endif
},
_onPopupShowing: function HM__onPopupShowing(aEvent) {
PlacesMenu.prototype._onPopupShowing.apply(this, arguments);
@ -745,6 +767,7 @@ HistoryMenu.prototype = {
this.toggleRecentlyClosedTabs();
this.toggleRecentlyClosedWindows();
this.toggleTabsFromOtherComputers();
},
_onCommand: function HM__onCommand(aEvent) {

Просмотреть файл

@ -0,0 +1,382 @@
# ***** 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 the Bookmarks Sync.
#
# The Initial Developer of the Original Code is the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Dan Mills <thunder@mozilla.com>
# Chris Beard <cbeard@mozilla.com>
# Dan Mosedale <dmose@mozilla.org>
# Paul OShannessy <paul@oshannessy.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 *****
// gSyncUI handles updating the tools menu
let gSyncUI = {
init: function SUI_init() {
let obs = [["weave:service:sync:start", "onActivityStart"],
["weave:service:sync:finish", "onSyncFinish"],
["weave:service:sync:error", "onSyncError"],
["weave:service:sync:delayed", "onSyncDelay"],
["weave:service:setup-complete", "onLoginFinish"],
["weave:service:login:start", "onActivityStart"],
["weave:service:login:finish", "onLoginFinish"],
["weave:service:login:error", "onLoginError"],
["weave:service:logout:finish", "onLogout"],
["weave:service:start-over", "onStartOver"]];
// If this is a browser window?
if (gBrowser) {
obs.push(["weave:notification:added", "onNotificationAdded"],
["weave:notification:removed", "onNotificationRemoved"]);
}
// Add the observers now and remove them on unload
let self = this;
let addRem = function(add) {
obs.forEach(function([topic, func]) {
//XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
// of `this`. Fix in a followup. (bug 583347)
if (add)
Weave.Svc.Obs.add(topic, self[func], self);
else
Weave.Svc.Obs.remove(topic, self[func], self);
});
};
addRem(true);
window.addEventListener("unload", function() addRem(false), false);
// Find the alltabs-popup, only if there is a gBrowser
if (gBrowser) {
let popup = document.getElementById("alltabs-popup");
let self = this;
popup.addEventListener("popupshowing", function() {
self.alltabsPopupShowing();
}, true);
}
this.updateUI();
},
_wasDelayed: false,
_needsSetup: function SUI__needsSetup() {
let firstSync = "";
try {
firstSync = Services.prefs.getCharPref("services.sync.firstSync");
} catch (e) { }
return Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
firstSync == "notReady";
},
updateUI: function SUI_updateUI() {
let needsSetup = this._needsSetup();
document.getElementById("sync-setup").hidden = !needsSetup;
document.getElementById("sync-menu").hidden = needsSetup;
if (gBrowser) {
let showLabel = !Weave.Service.isLoggedIn && !needsSetup;
let button = document.getElementById("sync-status-button");
button.setAttribute("class", showLabel ? "statusbarpanel-iconic-text"
: "statusbarpanel-iconic");
button.image = "chrome://browser/skin/sync-16.png";
if (!Weave.Service.isLoggedIn) {
//XXXzpao When we move the string bundle, we can add more and make this
// say "needs setup" or something similar. (bug 583381)
button.removeAttribute("tooltiptext");
}
}
},
alltabsPopupShowing: function(event) {
// Should we show the menu item?
if (!Weave.Service.isLoggedIn || !Weave.Engines.get("tabs").enabled)
return;
let label = this._stringBundle.GetStringFromName("tabs.fromOtherComputers.label");
let popup = document.getElementById("alltabs-popup");
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("id", "sync-tabs-menuitem");
menuitem.setAttribute("label", label);
menuitem.setAttribute("class", "alltabs-item");
menuitem.setAttribute("oncommand", "BrowserOpenSyncTabs();");
let sep = document.createElement("menuseparator");
sep.setAttribute("id", "sync-tabs-sep");
// Fake the tab object on the menu entries, so that we don't have to worry
// about removing them ourselves. They will just get cleaned up by popup
// binding. This also makes sure the statusbar updates with the URL.
menuitem.tab = { "linkedBrowser": { "currentURI": { "spec": label } } };
sep.tab = { "linkedBrowser": { "currentURI": { "spec": " " } } };
popup.insertBefore(sep, popup.firstChild);
popup.insertBefore(menuitem, sep);
},
// Functions called by observers
onActivityStart: function SUI_onActivityStart() {
//XXXzpao Followup: Do this with a class. (bug 583384)
if (gBrowser)
document.getElementById("sync-status-button").image =
"chrome://browser/skin/sync-16-throbber.png";
},
onSyncFinish: function SUI_onSyncFinish() {
this._onSyncEnd(true);
},
onSyncError: function SUI_onSyncError() {
this._onSyncEnd(false);
},
onSyncDelay: function SUI_onSyncDelay() {
// basically, we want to just inform users that stuff is going to take a while
let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
let description = this._stringBundle.GetStringFromName("error.sync.no_node_found");
let notification = new Weave.Notification(title, description, null, Weave.Notifications.PRIORITY_INFO);
Weave.Notifications.replaceTitle(notification);
this._wasDelayed = true;
},
onLoginFinish: function SUI_onLoginFinish() {
// Clear out any login failure notifications
let title = this._stringBundle.GetStringFromName("error.login.title");
Weave.Notifications.removeAll(title);
this.updateUI();
this._updateLastSyncItem();
},
onLoginError: function SUI_onLoginError() {
// if login fails, any other notifications are essentially moot
Weave.Notifications.removeAll();
// if we haven't set up the client, don't show errors
if (this._needsSetup()) {
this.updateUI();
return;
}
let title = this._stringBundle.GetStringFromName("error.login.title");
let reason = Weave.Utils.getErrorString(Weave.Status.login);
let description =
this._stringBundle.formatStringFromName("error.login.description", [reason], 1);
let buttons = [];
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.login.prefs.label"),
this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
function() { gSyncUI.openPrefs(); return true; }
));
let notification = new Weave.Notification(title, description, null,
Weave.Notifications.PRIORITY_WARNING, buttons);
Weave.Notifications.replaceTitle(notification);
this.updateUI();
},
onLogout: function SUI_onLogout() {
this.updateUI();
},
onStartOver: function SUI_onStartOver() {
this.updateUI();
},
onNotificationAdded: function SUI_onNotificationAdded() {
if (!gBrowser)
return;
let notificationsButton = document.getElementById("sync-notifications-button");
notificationsButton.hidden = false;
let notification = Weave.Notifications.notifications.reduce(function(prev, cur) {
return prev.priority > cur.priority ? prev : cur;
});
let image = notification.priority >= Weave.Notifications.PRIORITY_WARNING ?
"chrome://global/skin/icons/warning-16.png" :
"chrome://global/skin/icons/information-16.png";
notificationsButton.image = image;
notificationsButton.label = notification.title;
},
onNotificationRemoved: function SUI_onNotificationRemoved() {
if (!gBrowser)
return;
if (Weave.Notifications.notifications.length == 0) {
document.getElementById("sync-notifications-button").hidden = true;
}
else {
// Display remaining notifications
this.onNotificationAdded();
}
},
// Commands
doUpdateMenu: function SUI_doUpdateMenu(event) {
this._updateLastSyncItem();
let loginItem = document.getElementById("sync-loginitem");
let logoutItem = document.getElementById("sync-logoutitem");
let syncItem = document.getElementById("sync-syncnowitem");
// Don't allow "login" to be selected in some cases
let offline = Services.io.offline;
let locked = Weave.Service.locked;
let noUser = Weave.Service.username == "";
let notReady = offline || locked || noUser;
loginItem.setAttribute("disabled", notReady);
logoutItem.setAttribute("disabled", notReady);
// Don't allow "sync now" to be selected in some cases
let loggedIn = Weave.Service.isLoggedIn;
let noNode = Weave.Status.sync == Weave.NO_SYNC_NODE_FOUND;
let disableSync = notReady || !loggedIn || noNode;
syncItem.setAttribute("disabled", disableSync);
// Only show one of login/logout
loginItem.setAttribute("hidden", loggedIn);
logoutItem.setAttribute("hidden", !loggedIn);
},
doLogin: function SUI_doLogin() {
Weave.Service.login();
},
doLogout: function SUI_doLogout() {
Weave.Service.logout();
},
doSync: function SUI_doSync() {
Weave.Service.sync();
},
handleStatusbarButton: function SUI_handleStatusbarButton() {
if (Weave.Service.isLoggedIn)
Weave.Service.sync();
else if (this._needsSetup())
this.openSetup();
else
Weave.Service.login();
},
//XXXzpao should be part of syncCommon.js - which we might want to make a module...
// To be fixed in a followup (bug 583366)
openSetup: function SUI_openSetup() {
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/syncSetup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no");
}
},
openPrefs: function SUI_openPrefs() {
openPreferences("paneSync");
},
// Helpers
_updateLastSyncItem: function SUI__updateLastSyncItem() {
let lastSync;
try {
Services.prefs.getCharPref("services.sync.lastSync");
}
catch (e) { };
if (!lastSync)
return;
let lastSyncItem = document.getElementById("sync-lastsyncitem");
// Show the day-of-week and time (HH:MM) of last sync
let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
let lastSyncLabel =
this._stringBundle.formatStringFromName("lastSync.label", [lastSyncDate], 1);
lastSyncItem.setAttribute("label", lastSyncLabel);
lastSyncItem.setAttribute("hidden", "false");
document.getElementById("sync-lastsyncsep").hidden = false;
if (gBrowser)
document.getElementById("sync-status-button").
setAttribute("tooltiptext", lastSyncLabel);
},
_onSyncEnd: function SUI__onSyncEnd(success) {
let title = this._stringBundle.GetStringFromName("error.sync.title");
if (!success) {
let error = Weave.Utils.getErrorString(Weave.Status.sync);
let description =
this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
let priority = Weave.Notifications.PRIORITY_WARNING;
let buttons = [];
if (!Weave.Status.enforceBackoff) {
priority = Weave.Notifications.PRIORITY_INFO;
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
function() { gSyncUI.doSync(); return true; }
));
}
let notification =
new Weave.Notification(title, description, null, priority, buttons);
Weave.Notifications.replaceTitle(notification);
}
else {
// Clear out sync failures on a successful sync
Weave.Notifications.removeAll(title);
}
if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
Weave.Notifications.removeAll(title);
this._wasDelayed = false;
}
this.updateUI();
this._updateLastSyncItem();
}
};
XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
//XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
// but for now just make it work
return Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle("chrome://weave/locale/services/sync.properties");
});

Просмотреть файл

@ -29,26 +29,23 @@ tabbrowser {
max-width: 250px;
min-width: 100px;
width: 0;
-moz-transition: min-width .2s ease-out, max-width .25s ease-out;
}
.tabbrowser-tab:not([fadein]) {
.tabbrowser-tab:not([pinned]):not([fadein]) {
max-width: 1px;
min-width: 1px;
}
.tabbrowser-tab[fadein]:not([pinned]) {
-moz-transition: min-width .2s ease-out, max-width .25s ease-out;
}
.tabbrowser-tab:not([fadein]) > .tab-text,
.tabbrowser-tab:not([fadein]) > .tab-icon-image,
.tabbrowser-tab:not([fadein]) > .tab-close-button {
.tabbrowser-tab:not([fadein]):not([pinned]) > .tab-text,
.tabbrowser-tab:not([fadein]):not([pinned]) > .tab-icon-image,
.tabbrowser-tab:not([fadein]):not([pinned]) > .tab-close-button {
opacity: 0 !important;
}
.tabbrowser-tab[fadein] > .tab-text,
.tabbrowser-tab[fadein] > .tab-icon-image,
.tabbrowser-tab[fadein] > .tab-close-button {
.tabbrowser-tab > .tab-text,
.tabbrowser-tab > .tab-icon-image,
.tabbrowser-tab > .tab-close-button {
-moz-transition: opacity .25s;
}

Просмотреть файл

@ -148,6 +148,14 @@ __defineSetter__("PluralForm", function (val) {
return this.PluralForm = val;
});
#ifdef MOZ_SERVICES_SYNC
XPCOMUtils.defineLazyGetter(this, "Weave", function() {
let tmp = {};
Cu.import("resource://services-sync/service.js", tmp);
return tmp.Weave;
});
#endif
XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
let tmp = {};
Cu.import("resource://gre/modules/PopupNotifications.jsm", tmp);
@ -167,6 +175,10 @@ let gInitialPages = [
#include browser-places.js
#include browser-tabPreviews.js
#ifdef MOZ_SERVICES_SYNC
#include browser-syncui.js
#endif
XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
#ifdef XP_WIN
#ifndef WINCE
@ -1503,6 +1515,11 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
if (Win7Features)
Win7Features.onOpenWindow();
#ifdef MOZ_SERVICES_SYNC
// initialize the sync UI
gSyncUI.init();
#endif
Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
}
@ -1643,6 +1660,11 @@ function nonBrowserWindowDelayedStartup()
// initialize the private browsing UI
gPrivateBrowsingUI.init();
#ifdef MOZ_SERVICES_SYNC
// initialize the sync UI
gSyncUI.init();
#endif
}
function nonBrowserWindowShutdown()
@ -2026,7 +2048,7 @@ function BrowserCloseTabOrWindow() {
#endif
// If the current tab is the last one, this will close the window.
gBrowser.removeCurrentTab();
gBrowser.removeCurrentTab({animate: true});
}
function BrowserTryToCloseWindow()
@ -6715,6 +6737,12 @@ function isTabEmpty(aTab) {
!aTab.hasAttribute("busy");
}
#ifdef MOZ_SERVICES_SYNC
function BrowserOpenSyncTabs() {
switchToTabHavingURI("about:sync-tabs", true);
}
#endif
/**
* Format a URL
* eg:
@ -7743,7 +7771,10 @@ function switchToTabHavingURI(aURI, aOpenNew, aCallback) {
// No opened tab has that url.
if (aOpenNew) {
gBrowser.selectedTab = gBrowser.addTab(aURI.spec);
if (isTabEmpty(gBrowser.selectedTab))
gBrowser.selectedBrowser.loadURI(aURI.spec);
else
gBrowser.selectedTab = gBrowser.addTab(aURI.spec);
if (aCallback) {
let browser = gBrowser.selectedBrowser;
browser.addEventListener("pageshow", function(event) {

Просмотреть файл

@ -442,9 +442,23 @@
label="&brandShortName;"
style="-moz-user-focus: ignore;">
<menupopup id="appmenu-popup">
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"/>
<hbox flex="1" class="split-menuitem">
<menuitem id="appmenu_newTab"
class="split-menuitem-item"
flex="1"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"/>
<menu class="split-menuitem-menu">
<menupopup>
<menuitem id="appmenu_newTab_sub"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"/>
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"/>
</menupopup>
</menu>
</hbox>
<menuseparator/>
<menuitem id="appmenu_savePage"
label="&savePageCmd.label;"
@ -607,7 +621,8 @@
context="toolbar-context-menu">
<toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
context="backForwardMenu" removable="true">
context="backForwardMenu" removable="true"
title="&backForwardItem.title;">
<toolbarbutton id="back-button" class="toolbarbutton-1"
label="&backCmd.label;"
command="Browser:BackOrBackDuplicate"
@ -738,7 +753,8 @@
<toolbaritem id="bookmarks-menu-button-container"
class="chromeclass-toolbar-additional"
removable="true">
removable="true"
title="&bookmarksMenuButton.label;">
<toolbarbutton id="bookmarks-menu-button"
type="menu"
class="toolbarbutton-1"
@ -885,7 +901,7 @@
flex="1"
setfocus="false"
tooltip="tabbrowser-tab-tooltip">
<tab class="tabbrowser-tab" selected="true"/>
<tab class="tabbrowser-tab" selected="true" fadein="true"/>
</tabs>
<toolbarbutton id="new-tab-button"
@ -1021,6 +1037,24 @@
<statusbarpanel id="security-button" class="statusbarpanel-iconic"
hidden="true"
onclick="if (event.button == 0 &amp;&amp; event.detail == 1) displaySecurityInfo();"/>
#ifdef MOZ_SERVICES_SYNC
<statusbarpanel id="sync-status-button"
class="statusbarpanel-iconic-text"
image="chrome://browser/skin/sync-16.png"
label="&syncLogInItem.label;"
oncommand="gSyncUI.handleStatusbarButton();"
onmousedown="event.preventDefault();">
</statusbarpanel>
<separator class="thin"/>
<statusbarpanel id="sync-notifications-button"
class="statusbarpanel-iconic-text"
hidden="true"
popup="sync-notifications-panel">
</statusbarpanel>
<panel id="sync-notifications-panel" position="before_end">
<notificationbox id="sync-notifications-box"/>
</panel>
#endif
<statusbarpanel id="page-report-button" type="menu"
class="statusbarpanel-menu-iconic"
hidden="true"

Просмотреть файл

@ -421,6 +421,7 @@ nsContextMenu.prototype = {
setTarget: function (aNode, aRangeParent, aRangeOffset) {
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
if (aNode.namespaceURI == xulNS ||
aNode.nodeType == Node.DOCUMENT_NODE ||
this.isTargetAFormControl(aNode)) {
this.shouldDisplay = false;
return;
@ -807,7 +808,7 @@ nsContextMenu.prototype = {
this.target.pause();
openDialog("chrome://browser/content/fullscreen-video.xhtml",
"", "chrome,dialog=no", this.target);
"", "chrome,centerscreen,dialog=no", this.target);
},
// Change current window to the URL of the background image.

Просмотреть файл

@ -0,0 +1,228 @@
/* ***** 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 Weave.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Edward Lee <edilee@mozilla.com>
* Mike Connor <mconnor@mozilla.com>
* Paul OShannessy <paul@oshannessy.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 ***** */
Components.utils.import("resource://services-sync/service.js");
Components.utils.import("resource://gre/modules/Services.jsm");
let Change = {
_dialog: null,
_dialogType: null,
_status: null,
_statusIcon: null,
_firstBox: null,
_secondBox: null,
get _currentPasswordInvalid() {
return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
},
get _updatingPassphrase() {
return this._dialogType == "UpdatePassphrase";
},
onLoad: function Change_onLoad() {
/* Load labels */
let box1label = document.getElementById("textBox1Label");
let box2label = document.getElementById("textBox2Label");
let introText = document.getElementById("introText");
let introText2 = document.getElementById("introText2");
let warningText = document.getElementById("warningText");
// load some other elements & info from the window
this._dialog = document.getElementById("change-dialog");
this._dialogType = window.arguments[0];
this._status = document.getElementById("status");
this._statusIcon = document.getElementById("statusIcon");
this._firstBox = document.getElementById("textBox1");
this._secondBox = document.getElementById("textBox2");
this._stringBundle =
Services.strings.createBundle("chrome://browser/locale/syncGenericChange.properties");
switch (this._dialogType) {
case "UpdatePassphrase":
case "ResetPassphrase":
box1label.value = this._str("new.passphrase.label");
if (this._updatingPassphrase) {
document.title = this._str("new.passphrase.title");
introText.textContent = this._str("new.passphrase.introText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("new.passphrase.acceptButton"));
document.getElementById("textBox2Row").hidden = true;
}
else {
document.title = this._str("change.passphrase.title");
box2label.value = this._str("new.passphrase.confirm");
introText.textContent = this._str("change.passphrase.introText");
introText2.textContent = this._str("change.passphrase.introText2");
warningText.textContent = this._str("change.passphrase.warningText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("change.passphrase.acceptButton"));
}
break;
case "ChangePassword":
box1label.value = this._str("new.password.label");
if (this._currentPasswordInvalid) {
document.title = this._str("new.password.title");
introText.textContent = this._str("new.password.introText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("new.password.acceptButton"));
document.getElementById("textBox2Row").hidden = true;
}
else {
document.title = this._str("change.password.title");
box2label.value = this._str("new.password.confirm");
introText.textContent = this._str("change.password.introText");
warningText.textContent = this._str("change.password.warningText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("change.password.acceptButton"));
}
break;
}
},
_clearStatus: function _clearStatus() {
this._status.value = "";
this._statusIcon.removeAttribute("status");
},
_updateStatus: function Change__updateStatus(str, state) {
this._updateStatusWithString(this._str(str), state);
},
_updateStatusWithString: function Change__updateStatusWithString(string, state) {
this._status.value = string;
this._statusIcon.setAttribute("status", state);
let error = state == "error";
this._dialog.getButton("cancel").setAttribute("disabled", !error);
this._dialog.getButton("accept").setAttribute("disabled", !error);
if (state == "success")
window.setTimeout(window.close, 1500);
},
onDialogAccept: function() {
switch (this._dialogType) {
case "UpdatePassphrase":
case "ResetPassphrase":
return this.doChangePassphrase();
break;
case "ChangePassword":
return this.doChangePassword();
break;
}
},
doChangePassphrase: function Change_doChangePassphrase() {
if (this._updatingPassphrase) {
Weave.Service.passphrase = this._firstBox.value;
if (Weave.Service.login()) {
this._updateStatus("change.passphrase.success", "success");
Weave.Service.persistLogin();
}
else {
this._updateStatus("new.passphrase.status.incorrect", "error");
}
}
else {
this._updateStatus("change.passphrase.label", "active");
if (Weave.Service.changePassphrase(this._firstBox.value))
this._updateStatus("change.passphrase.success", "success");
else
this._updateStatus("change.passphrase.error", "error");
}
return false;
},
doChangePassword: function Change_doChangePassword() {
if (this._currentPasswordInvalid) {
Weave.Service.password = this._firstBox.value;
if (Weave.Service.login()) {
this._updateStatus("change.password.status.success", "success");
Weave.Service.persistLogin();
}
else {
this._updateStatus("new.password.status.incorrect", "error");
}
}
else {
this._updateStatus("change.password.status.active", "active");
if (Weave.Service.changePassword(this._firstBox.value))
this._updateStatus("change.password.status.success", "success");
else
this._updateStatus("change.password.status.error", "error");
}
return false;
},
validate: function (event) {
let valid = false;
let errorString = "";
if (this._dialogType == "ChangePassword") {
if (this._currentPasswordInvalid)
[valid, errorString] = gSyncUtils.validatePassword(this._firstBox);
else
[valid, errorString] = gSyncUtils.validatePassword(this._firstBox, this._secondBox);
}
else {
if (this._updatingPassphrase)
[valid, errorString] = gSyncUtils.validatePassphrase(this._firstBox);
else
[valid, errorString] = gSyncUtils.validatePassphrase(this._firstBox, this._secondBox);
}
if (errorString == "")
this._clearStatus();
else
this._updateStatusWithString(errorString, "error");
this._dialog.getButton("accept").disabled = !valid;
},
_str: function Change__string(str) {
return this._stringBundle.GetStringFromName(str);
}
};

Просмотреть файл

@ -0,0 +1,95 @@
<?xml version="1.0"?>
# ***** 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 Weave.
#
# The Initial Developer of the Original Code is the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Edward Lee <edilee@mozilla.com>
# Mike Connor <mconnor@mozilla.com>
# Paul OShannessy <paul@oshannessy.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 *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
id="change-dialog"
windowtype="Weave:ChangeSomething"
buttons="accept,cancel"
onload="Change.onLoad()"
buttondisabledaccept="true"
ondialogaccept="return Change.onDialogAccept();"
defaultButton="accept">
<script type="application/javascript"
src="chrome://browser/content/syncGenericChange.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
<hbox align="top">
<image id="syncIcon"/>
<spacer style="width: 1em"/>
<description flex="1">
<html:p id="introText"/>
<html:p id="introText2"/>
</description>
</hbox>
<separator class="thin"/>
<vbox>
<grid>
<columns>
<column align="right"/>
<column/>
</columns>
<rows>
<row>
<label id="textBox1Label" control="textBox1"/>
<textbox id="textBox1" type="password" oninput="Change.validate(event)"/>
</row>
<row id="textBox2Row">
<label id="textBox2Label" control="textBox2"/>
<textbox id="textBox2" type="password" oninput="Change.validate(event)"/>
</row>
</rows>
</grid>
<description>
<html:p class="data" id="warningText"/>
</description>
<hbox align="center">
<image id="statusIcon" class="statusIcon"/>
<label id="status" class="status" value=" "/>
</hbox>
</vbox>
</dialog>

Просмотреть файл

@ -0,0 +1,748 @@
/* ***** 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 Weave.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Edward Lee <edilee@mozilla.com>
* Mike Connor <mconnor@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
* Paul OShannessy <paul@oshannessy.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 ***** */
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const Cu = Components.utils;
// page consts
const INTRO_PAGE = 0;
const NEW_ACCOUNT_START_PAGE = 1;
const NEW_ACCOUNT_PP_PAGE = 2;
const NEW_ACCOUNT_PREFS_PAGE = 3;
const NEW_ACCOUNT_CAPTCHA_PAGE = 4;
const EXISTING_ACCOUNT_LOGIN_PAGE = 5;
const EXISTING_ACCOUNT_PP_PAGE = 6;
const EXISTING_ACCOUNT_MERGE_PAGE = 7;
const EXISTING_ACCOUNT_CONFIRM_PAGE = 8;
const SETUP_SUCCESS_PAGE = 9;
Cu.import("resource://services-sync/service.js");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
var gSyncSetup = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
captchaBrowser: null,
wizard: null,
_disabledSites: [],
_remoteSites: [Weave.Service.serverURL, "https://api-secure.recaptcha.net"],
status: {
username: false,
password: false,
email: false,
server: false
},
get _usingMainServers() {
if (this._settingUpNew)
return document.getElementById("serverType").selectedItem.value == "main";
return document.getElementById("existingServerType").selectedItem.value == "main";
},
init: function () {
let obs = [
["weave:service:changepph:finish", "onResetPassphrase"],
["weave:service:verify-login:start", "onLoginStart"],
["weave:service:verify-login:error", "onLoginEnd"],
["weave:service:verify-login:finish", "onLoginEnd"]];
// Add the observers now and remove them on unload
let self = this;
let addRem = function(add) {
obs.forEach(function([topic, func]) {
//XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
// of `this`. Fix in a followup. (bug 583347)
if (add)
Weave.Svc.Obs.add(topic, self[func], self);
else
Weave.Svc.Obs.remove(topic, self[func], self);
});
};
addRem(true);
window.addEventListener("unload", function() addRem(false), false);
this.captchaBrowser = document.getElementById("captcha");
this.wizard = document.getElementById("accountSetup");
if (window.arguments && window.arguments[0] == true) {
// we're resetting sync
this._resettingSync = true;
this.wizard.pageIndex = EXISTING_ACCOUNT_MERGE_PAGE;
}
else {
this.wizard.canAdvance = false;
this.captchaBrowser.addProgressListener(this);
Weave.Svc.Prefs.set("firstSync", "notReady");
}
},
updateSyncPrefs: function () {
let syncEverything = document.getElementById("weaveSyncMode").selectedItem.value == "syncEverything";
document.getElementById("syncModeOptions").selectedIndex = syncEverything ? 0 : 1;
if (syncEverything) {
document.getElementById("engine.bookmarks").checked = true;
document.getElementById("engine.passwords").checked = true;
document.getElementById("engine.history").checked = true;
document.getElementById("engine.tabs").checked = true;
document.getElementById("engine.prefs").checked = true;
}
},
startNewAccountSetup: function () {
this._settingUpNew = true;
this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE;
},
useExistingAccount: function () {
this._settingUpNew = false;
this.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE;
},
onResetPassphrase: function () {
document.getElementById("existingPassphrase").value = Weave.Service.passphrase;
this.wizard.advance();
},
onLoginStart: function () {
this.toggleLoginFeedback(false);
},
onLoginEnd: function () {
this.toggleLoginFeedback(true);
},
toggleLoginFeedback: function (stop) {
switch (this.wizard.pageIndex) {
case EXISTING_ACCOUNT_LOGIN_PAGE:
document.getElementById("connect-throbber").hidden = stop;
let feedback = document.getElementById("existingPasswordFeedbackRow");
if (stop) {
let success = Weave.Status.login == Weave.LOGIN_SUCCEEDED ||
Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE;
this._setFeedbackMessage(feedback, success, Weave.Status.login);
}
else
this._setFeedbackMessage(feedback, true);
break;
case EXISTING_ACCOUNT_PP_PAGE:
document.getElementById("passphrase-throbber").hidden = stop;
feedback = document.getElementById("existingPassphraseFeedbackBox");
if (stop) {
let success = Weave.Status.login == Weave.LOGIN_SUCCEEDED;
this._setFeedbackMessage(feedback, success, Weave.Status.login);
document.getElementById("passphraseHelpBox").hidden = success;
}
else
this._setFeedbackMessage(feedback, true);
break;
}
},
handleExpanderClick: function (event) {
let expander = document.getElementById("setupAccountExpander");
let expand = expander.className == "expander-down";
expander.className =
expand ? "expander-up" : "expander-down";
document.getElementById("signInBox").hidden = !expand;
},
setupInitialSync: function () {
let action = document.getElementById("mergeChoiceRadio").selectedItem.id;
switch (action) {
case "resetClient":
// if we're not resetting sync, we don't need to explicitly
// call resetClient
if (!this._resettingSync)
return;
// otherwise, fall through
case "wipeClient":
case "wipeRemote":
Weave.Svc.Prefs.set("firstSync", action);
break;
}
},
// fun with validation!
checkFields: function () {
this.wizard.canAdvance = this.readyToAdvance();
},
readyToAdvance: function () {
switch (this.wizard.pageIndex) {
case INTRO_PAGE:
return false;
case NEW_ACCOUNT_START_PAGE:
for (i in this.status) {
if (!this.status[i])
return false;
}
if (this._usingMainServers)
return document.getElementById("tos").checked;
return true;
case NEW_ACCOUNT_PP_PAGE:
return this.onPassphraseChange();
case EXISTING_ACCOUNT_LOGIN_PAGE:
let hasUser = document.getElementById("existingUsername").value != "";
let hasPass = document.getElementById("existingPassword").value != "";
if (hasUser && hasPass) {
if (this._usingMainServers)
return true;
if (this._validateServer(document.getElementById("existingServerURL"), false))
return true;
}
return false;
case EXISTING_ACCOUNT_PP_PAGE:
return document.getElementById("existingPassphrase").value != "";
}
// we probably shouldn't get here
return true;
},
onUsernameChange: function () {
let feedback = document.getElementById("usernameFeedbackRow");
let val = document.getElementById("weaveUsername").value;
let availCheck = "", str = "";
let available = true;
if (val) {
availCheck = Weave.Service.checkUsername(val);
available = availCheck == "available";
}
if (!available) {
if (availCheck == "notAvailable")
str = "usernameNotAvailable.label";
else
str = availCheck;
}
this._setFeedbackMessage(feedback, available, str);
this.status.username = val && available;
if (available)
Weave.Service.username = val;
this.checkFields();
},
onPasswordChange: function () {
let password = document.getElementById("weavePassword");
let valid, str;
if (password.value == document.getElementById("weavePassphrase").value) {
// xxxmpc - hack, sigh
valid = false;
errorString = Weave.Utils.getErrorString("change.password.pwSameAsPassphrase");
}
else {
let pwconfirm = document.getElementById("weavePasswordConfirm");
[valid, errorString] = gSyncUtils.validatePassword(password, pwconfirm);
}
let feedback = document.getElementById("passwordFeedbackRow");
this._setFeedback(feedback, valid, errorString);
this.status.password = valid;
this.checkFields();
},
onEmailChange: function () {
//XXXzpao Not sure about this regex. Look into it in followup (bug 583650)
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
this.status.email = re.test(document.getElementById("weaveEmail").value);
this._setFeedbackMessage(document.getElementById("emailFeedbackRow"),
this.status.email,
"invalidEmail.label");
this.checkFields();
},
onPassphraseChange: function () {
let el1 = document.getElementById("weavePassphrase");
let valid, str;
// xxxmpc - hack, sigh
if (el1.value == document.getElementById("weavePassword").value) {
valid = false;
str = Weave.Utils.getErrorString("change.passphrase.ppSameAsPassword");
}
else {
let el2 = document.getElementById("weavePassphraseConfirm");
[valid, str] = gSyncUtils.validatePassphrase(el1, el2);
}
let feedback = document.getElementById("passphraseFeedbackRow");
this._setFeedback(feedback, valid, str);
return valid;
},
onPageShow: function() {
switch (this.wizard.pageIndex) {
case INTRO_PAGE:
this.wizard.getButton("next").hidden = true;
this.wizard.getButton("back").hidden = true;
this.wizard.getButton("cancel").label =
this._stringBundle.GetStringFromName("cancelSetup.label");
break;
case NEW_ACCOUNT_PP_PAGE:
this.checkFields();
break;
case NEW_ACCOUNT_START_PAGE:
this.onServerChange();
this.checkFields(); // fall through
case EXISTING_ACCOUNT_LOGIN_PAGE:
case EXISTING_ACCOUNT_MERGE_PAGE:
this.wizard.getButton("next").hidden = false;
this.wizard.getButton("back").hidden = false;
this.wizard.canRewind = !this._resettingSync;
break;
case SETUP_SUCCESS_PAGE:
this.wizard.canRewind = false;
this.wizard.getButton("back").hidden = true;
this.wizard.getButton("cancel").hidden = true;
break;
}
},
onWizardAdvance: function () {
if (!this.wizard.pageIndex)
return true;
switch (this.wizard.pageIndex) {
case NEW_ACCOUNT_PREFS_PAGE:
if (this._settingUpNew) {
// time to load the captcha
// first check for NoScript and whitelist the right sites
this._handleNoScript(true);
this.captchaBrowser.loadURI(Weave.Service.miscAPI + "captcha_html");
return true;
}
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
return false;
case NEW_ACCOUNT_CAPTCHA_PAGE:
let doc = this.captchaBrowser.contentDocument;
let getField = function getField(field) {
let node = doc.getElementById("recaptcha_" + field + "_field");
return node && node.value;
};
this.startThrobber(true);
let username = document.getElementById("weaveUsername").value;
let password = document.getElementById("weavePassword").value;
let email = document.getElementById("weaveEmail").value;
let challenge = getField("challenge");
let response = getField("response");
let error = Weave.Service.createAccount(username, password, email,
challenge, response);
this.startThrobber(false);
if (error == null) {
Weave.Service.username = username;
Weave.Service.password = password;
this._handleNoScript(false);
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
return true;
}
// this could be nicer, but it'll do for now
Weave.Svc.Prompt.alert(window,
this._stringBundle.GetStringFromName("errorCreatingAccount.title"),
Weave.Utils.getErrorString(error));
return false;
case NEW_ACCOUNT_PP_PAGE:
Weave.Service.passphrase = document.getElementById("weavePassphrase").value;
document.getElementById("syncComputerName").value = Weave.Clients.localName;
break;
case EXISTING_ACCOUNT_LOGIN_PAGE:
Weave.Service.username = document.getElementById("existingUsername").value;
Weave.Service.password = document.getElementById("existingPassword").value;
Weave.Service.passphrase = document.getElementById("existingPassphrase").value;
// verifyLogin() will likely return false because we probably don't
// have a passphrase yet (unless the user already entered it
// and hit the back button).
if (!Weave.Service.verifyLogin()
&& Weave.Status.login != Weave.LOGIN_FAILED_NO_PASSPHRASE
&& Weave.Status.login != Weave.LOGIN_FAILED_INVALID_PASSPHRASE) {
let feedback = document.getElementById("existingPasswordFeedbackRow");
this._setFeedbackMessage(feedback, false, Weave.Status.login);
return false;
}
break;
case EXISTING_ACCOUNT_PP_PAGE:
Weave.Service.passphrase = document.getElementById("existingPassphrase").value;
if (Weave.Service.login())
return true;
return false;
case EXISTING_ACCOUNT_MERGE_PAGE:
return this._handleChoice();
case EXISTING_ACCOUNT_CONFIRM_PAGE:
this.setupInitialSync();
if (this._resettingSync) {
this.onWizardFinish();
window.close();
return false;
}
this.wizard.pageIndex = NEW_ACCOUNT_PREFS_PAGE;
document.getElementById("syncComputerName").value = Weave.Clients.localName;
return false;
}
return true;
},
onWizardBack: function () {
switch (this.wizard.pageIndex) {
case NEW_ACCOUNT_START_PAGE:
case EXISTING_ACCOUNT_LOGIN_PAGE:
this.wizard.pageIndex = INTRO_PAGE;
return false;
case EXISTING_ACCOUNT_PP_PAGE: // no idea wtf is up here, but meh!
this.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE;
return false;
case NEW_ACCOUNT_PREFS_PAGE:
if (this._settingUpNew)
return true;
this.wizard.pageIndex = EXISTING_ACCOUNT_CONFIRM_PAGE;
return false;
}
return true;
},
onWizardFinish: function () {
Weave.Status.service == Weave.STATUS_OK;
if (!this._resettingSync) {
function isChecked(element) {
return document.getElementById(element).hasAttribute("checked");
}
let prefs = ["engine.bookmarks", "engine.passwords", "engine.history", "engine.tabs", "engine.prefs"];
for (let i = 0;i < prefs.length;i++) {
Weave.Svc.Prefs.set(prefs[i], isChecked(prefs[i]));
}
this._handleNoScript(false);
if (Weave.Svc.Prefs.get("firstSync", "") == "notReady")
Weave.Svc.Prefs.reset("firstSync");
Weave.Service.persistLogin();
Weave.Svc.Obs.notify("weave:service:setup-complete");
if (this._settingUpNew)
gSyncUtils.openFirstClientFirstrun();
else
gSyncUtils.openAddedClientFirstrun();
}
if (!Weave.Service.isLoggedIn)
Weave.Service.login();
Weave.Service.syncOnIdle(1);
},
onWizardCancel: function () {
if (this._resettingSync)
return;
if (this.wizard.pageIndex == 9) {
this.onWizardFinish();
return;
}
this._handleNoScript(false);
Weave.Service.startOver();
},
// _handleNoScript is needed because it blocks the captcha. So we temporarily
// allow the necessary sites so that we can verify the user is in fact a human.
// This was done with the help of Giorgio (NoScript author). See bug 508112.
_handleNoScript: function (addExceptions) {
// if NoScript isn't installed, or is disabled, bail out.
let ns = Cc["@maone.net/noscript-service;1"];
if (ns == null)
return;
ns = ns.getService().wrappedJSObject;
if (addExceptions) {
this._remoteSites.forEach(function(site) {
site = ns.getSite(site);
if (!ns.isJSEnabled(site)) {
this._disabledSites.push(site); // save status
ns.setJSEnabled(site, true); // allow site
}
}, this);
}
else {
this._disabledSites.forEach(function(site) {
ns.setJSEnabled(site, false);
});
this._disabledSites = [];
}
},
startThrobber: function (start) {
// FIXME: stubbed (bug 583653)
},
onServerChange: function () {
if (this.wizard.pageIndex == EXISTING_ACCOUNT_LOGIN_PAGE) {
if (this._usingMainServers)
Weave.Svc.Prefs.reset("serverURL");
document.getElementById("existingServerRow").hidden = this._usingMainServers;
this.checkFields();
return;
}
document.getElementById("serverRow").hidden = this._usingMainServers;
document.getElementById("TOSRow").hidden = !this._usingMainServers;
let valid = false;
let feedback = document.getElementById("serverFeedbackRow");
if (this._usingMainServers) {
Weave.Svc.Prefs.reset("serverURL");
valid = true;
feedback.hidden = true;
}
else {
let el = document.getElementById("weaveServerURL");
let str = "";
if (el.value) {
valid = this._validateServer(el, true);
let str = valid ? "" : "serverInvalid.label";
this._setFeedbackMessage(feedback, valid, str);
}
else
this._setFeedbackMessage(feedback, true);
}
// recheck username against the new server
if (valid)
this.onUsernameChange();
this.status.server = valid;
this.checkFields();
},
// xxxmpc - checkRemote is a hack, we can't verify a minimal server is live
// without auth, so we won't validate in the existing-server case.
_validateServer: function (element, checkRemote) {
let valid = false;
let val = element.value;
if (!val)
return false;
let uri = Weave.Utils.makeURI(val);
if (!uri)
uri = Weave.Utils.makeURI("https://" + val);
if (uri && checkRemote) {
function isValid(uri) {
Weave.Service.serverURL = uri.spec;
let check = Weave.Service.checkUsername("a");
return (check == "available" || check == "notAvailable");
}
if (uri.schemeIs("http")) {
let uri2 = uri;
uri2.scheme = "https";
if (isValid(uri2))
valid = true;
}
if (!valid)
valid = isValid(uri);
}
else if (uri) {
valid = true;
Weave.Service.serverURL = uri.spec;
}
if (valid)
element.value = Weave.Service.serverURL;
else
Weave.Svc.Prefs.reset("serverURL");
return valid;
},
_handleChoice: function () {
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
document.getElementById("chosenActionDeck").selectedIndex = desc;
switch (desc) {
case 1:
if (this._case1Setup)
break;
// history
let db = Weave.Svc.History.DBConnection;
let daysOfHistory = 0;
let stm = db.createStatement(
"SELECT ROUND(( " +
"strftime('%s','now','localtime','utc') - " +
"( " +
"SELECT visit_date FROM moz_historyvisits " +
"UNION ALL " +
"SELECT visit_date FROM moz_historyvisits_temp " +
"ORDER BY visit_date ASC LIMIT 1 " +
")/1000000 " +
")/86400) AS daysOfHistory ");
if (stm.step())
daysOfHistory = stm.getInt32(0);
document.getElementById("historyCount").value =
this._stringBundle.formatStringFromName("historyCount.label", [daysOfHistory], 1);
// bookmarks
let bookmarks = 0;
stm = db.createStatement(
"SELECT count(*) AS bookmarks " +
"FROM moz_bookmarks b " +
"LEFT JOIN moz_bookmarks t ON " +
"b.parent = t.id WHERE b.type = 1 AND t.parent <> :tag");
stm.params.tag = Weave.Svc.Bookmark.tagsFolder;
if (stm.executeStep())
bookmarks = stm.row.bookmarks;
document.getElementById("bookmarkCount").value =
this._stringBundle.formatStringFromName("bookmarkCount.label", [bookmarks], 1);
// passwords
let logins = Weave.Svc.Login.getAllLogins({});
document.getElementById("passwordCount").value =
this._stringBundle.formatStringFromName("passwordCount.label", [logins.length], 1);
this._case1Setup = true;
break;
case 2:
if (this._case2Setup)
break;
let count = 0;
function appendNode(label) {
let box = document.getElementById("clientList");
let node = document.createElement("label");
node.setAttribute("value", label);
node.setAttribute("class", "data indent");
box.appendChild(node);
}
for each (let name in Weave.Clients.stats.names) {
// Don't list the current client
if (name == Weave.Clients.localName)
continue;
// Only show the first several client names
if (++count <= 5)
appendNode(name);
}
if (count > 5) {
let label =
this._stringBundle.formatStringFromName("additionalClients.label", [count - 5], 1);
appendNode(label);
}
this._case2Setup = true;
break;
}
return true;
},
// sets class and string on a feedback element
// if no property string is passed in, we clear label/style
_setFeedback: function (element, success, string) {
element.hidden = success || !string;
let class = success ? "success" : "error";
let image = element.firstChild.nextSibling.firstChild;
image.setAttribute("status", class);
let label = image.nextSibling;
label.value = string;
},
// shim
_setFeedbackMessage: function (element, success, string) {
let str = "";
if (string) {
try {
str = this._stringBundle.GetStringFromName(string);
} catch(e) {}
if (!str)
str = Weave.Utils.getErrorString(string);
}
this._setFeedback(element, success, str);
},
onStateChange: function(webProgress, request, stateFlags, status) {
// We're only looking for the end of the frame load
if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) == 0)
return;
if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) == 0)
return;
if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) == 0)
return;
// If we didn't find the captcha, assume it's not needed and move on
if (request.QueryInterface(Ci.nsIHttpChannel).responseStatus == 404)
this.onWizardAdvance();
},
onProgressChange: function() {},
onStatusChange: function() {},
onSecurityChange: function() {},
onLocationChange: function () {}
}
// onWizardAdvance() and onPageShow() are run before init(), so we'll set
// wizard & _stringBundle up as lazy getters.
XPCOMUtils.defineLazyGetter(gSyncSetup, "wizard", function() {
return document.getElementById("accountSetup");
});
XPCOMUtils.defineLazyGetter(gSyncSetup, "_stringBundle", function() {
return Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
});

Просмотреть файл

@ -0,0 +1,515 @@
<?xml version="1.0"?>
# ***** 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 Weave.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Edward Lee <edilee@mozilla.com>
# Mike Connor <mconnor@mozilla.com>
# Paul OShannessy <paul@oshannessy.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 *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd">
%brandDTD;
%syncBrandDTD;
%syncSetupDTD;
]>
<wizard id="accountSetup" title="&accountSetupTitle.label;"
windowtype="Weave:AccountSetup"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
onwizardnext="return gSyncSetup.onWizardAdvance()"
onwizardback="return gSyncSetup.onWizardBack()"
onwizardfinish="gSyncSetup.onWizardFinish()"
onwizardcancel="gSyncSetup.onWizardCancel()"
onload="gSyncSetup.init()">
<script type="application/javascript"
src="chrome://browser/content/syncSetup.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<wizardpage id="pickSetupType"
label="&setup.choicePage.title.label;"
onpageshow="gSyncSetup.onPageShow()">
<button id="newAccount"
class="accountChoiceButton"
aria-labelledby="createNewDesc"
oncommand="gSyncSetup.startNewAccountSetup()"
align="center">
<image class="mergeChoiceImage"/>
<vbox class="mergeChoiceButtonBox" flex="1">
<description class="mainDesc" id="createNewDesc">
&setup.choicePage.new.label;
</description>
</vbox>
</button>
<button id="existingAccount"
class="accountChoiceButton"
aria-labelledby="useExistingButton"
oncommand="gSyncSetup.useExistingAccount()"
align="center">
<image class="mergeChoiceImage"/>
<vbox class="mergeChoiceButtonBox" flex="1">
<description class="mainDesc" id="useExistingDesc">
&setup.choicePage.existing.label;
</description>
</vbox>
</button>
</wizardpage>
<wizardpage label="&setup.newAccountPage.title.label;"
id="newAccountStart"
onpageshow="gSyncSetup.onPageShow();">
<grid>
<columns>
<column/>
<column class="inputColumn" flex="1"/>
</columns>
<rows>
<row align="center">
<label control="serverType"
value="&connectTo.label;"/>
<menulist id="serverType" oncommand="gSyncSetup.onServerChange()">
<menupopup>
<menuitem label="&serverType.main.label;"
value="main"/>
<menuitem label="&serverType.custom.label;"
value="custom"/>
</menupopup>
</menulist>
</row>
<row id="serverRow" hidden="true" align="center">
<label value="&signIn.serverURL.label;"
accesskey="&signIn.serverURL.accesskey;"
control="weaveServerURL"/>
<textbox id="weaveServerURL" onchange="gSyncSetup.onServerChange()"/>
</row>
<row id="serverFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="usernameRow" align="center">
<label value="&signIn.username.label;"
accesskey="&signIn.username.accesskey;"
control="weaveUsername"/>
<textbox id="weaveUsername"
onchange="gSyncSetup.onUsernameChange()"/>
</row>
<row id="usernameFeedbackRow"
align="center"
hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="passwordRow" align="center">
<label value="&signIn.password.label;"
accesskey="&signIn.password.accesskey;"
control="weavePassword"/>
<textbox id="weavePassword"
type="password"
onchange="gSyncSetup.onPasswordChange()"/>
</row>
<row id="confirmRow" align="center">
<label value="&setup.confirmPassword.label;"
accesskey="&setup.confirmPassword.accesskey;"
control="weavePasswordConfirm"/>
<textbox id="weavePasswordConfirm"
type="password"
onchange="gSyncSetup.onPasswordChange()"/>
</row>
<row id="passwordFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="emailRow" align="center">
<label value="&setup.emailAddress.label;"
accesskey="&setup.emailAddress.accesskey;"
control="weaveEmail"/>
<textbox id="weaveEmail"
oninput="gSyncSetup.onEmailChange()"/>
</row>
<row id="emailFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="TOSRow" align="center">
<spacer/>
<hbox align="top">
<checkbox id="tos"
accesskey="&setup.tosAgree1.accesskey;"
oncommand="gSyncSetup.checkFields();"/>
<description id="tosDesc" onclick="document.getElementById('tos').click()">
&setup.tosAgree1.label;
<label class="text-link inline-link"
onclick="event.stopPropagation();gSyncUtils.openToS();"
value="&setup.tosLink.label;"/>
&setup.tosAgree2.label;
<label class="text-link inline-link"
onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();"
value="&setup.ppLink.label;"/>
&setup.tosAgree3.label;
</description>
</hbox>
</row>
</rows>
</grid>
</wizardpage>
<wizardpage label="&setup.newPPPage.title.label;"
onpageshow="gSyncSetup.onPageShow();">
<description>
&passphraseDesc.label;
</description>
<spacer/>
<grid>
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row align="center">
<label value="&passphraseEntry.label;"
accesskey="&passphraseEntry.accesskey;"
control="weavePassphrase"/>
<textbox type="password" id="weavePassphrase"
onkeyup="gSyncSetup.checkFields()"
onchange="gSyncSetup.checkFields()"/>
</row>
<row align="center">
<label value="&passphraseConfirm.label;"
accesskey="&passphraseConfirm.accesskey;"
control="weavePassphraseConfirm"/>
<textbox type="password" id="weavePassphraseConfirm"
onkeyup="gSyncSetup.checkFields()"
onchange="gSyncSetup.checkFields()"/>
</row>
</rows>
</grid>
<hbox id="passphraseFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</hbox>
<separator/>
<description class="small">
&passphraseDesc2.label;
</description>
</wizardpage>
<wizardpage label="&setup.newAccountPrefs2.title.label;">
<grid>
<rows>
<row align="center">
<label value="&syncComputerName.label;"
accesskey="&syncComputerName.accesskey;"
control="syncComputerName"/>
<textbox id="syncComputerName" flex="1"
onchange="gSyncUtils.changeName(this)"/>
</row>
<row align="center">
<label value="&syncModeSwitchDesc.label;"
accesskey="&syncModeSwitchDesc.accesskey;"
control="weaveSyncMode"/>
<menulist id="weaveSyncMode"
oncommand="gSyncSetup.updateSyncPrefs()">
<menupopup>
<menuitem label="&syncEverything.label;" value="syncEverything"/>
<menuitem label="&customSync.label;" value="customSync"/>
</menupopup>
</menulist>
</row>
</rows>
</grid>
<separator/>
<deck id="syncModeOptions" class="indent">
<description id="syncEverythingDesc">
&syncEverythingDescription.label;
</description>
<vbox>
<checkbox label="&syncItem.bookmarks.label;"
accesskey="&syncItem.bookmarks.accesskey;"
id="engine.bookmarks"
checked="true"/>
<checkbox label="&syncItem.passwords.label;"
accesskey="&syncItem.passwords.accesskey;"
id="engine.passwords"
checked="true"/>
<checkbox label="&syncItem.prefs.label;"
accesskey="&syncItem.prefs.accesskey;"
id="engine.prefs"
checked="true"/>
<checkbox label="&syncItem.history.label;"
accesskey="&syncItem.history.accesskey;"
id="engine.history"
checked="true"/>
<checkbox label="&syncItem.tabs.label;"
accesskey="&syncItem.tabs.accesskey;"
id="engine.tabs"
checked="true"/>
</vbox>
</deck>
</wizardpage>
<wizardpage label="&setup.captchaPage.title.label;">
<browser height="150"
width="322"
id="captcha"
type="content"
disablehistory="true"/>
</wizardpage>
<wizardpage id="useExisting"
label="&setup.existingAccount.title.label;"
onpageshow="gSyncSetup.onPageShow()">
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row align="center">
<label control="existingServerType"
value="&connectTo.label;"/>
<menulist id="existingServerType" oncommand="gSyncSetup.onServerChange()">
<menupopup>
<menuitem label="&serverType.main.label;"
value="main"/>
<menuitem label="&serverType.custom.label;"
value="custom"/>
</menupopup>
</menulist>
</row>
<row id="existingServerRow" hidden="true" align="center">
<label id="existingServerURLLabel"
value="&signIn.serverURL.label;"
accesskey="&signIn.serverURL.accesskey;"
control="existingServerURL"/>
<textbox id="existingServerURL"
onchange="gSyncSetup.checkFields(event)"/>
</row>
<row id="existingUsernameRow" align="center">
<label id="existingUsernameLabel"
value="&signIn.username.label;"
accesskey="&signIn.username.accesskey;"
control="existingUsername"/>
<textbox id="existingUsername"
oninput="gSyncSetup.checkFields(event)"
onchange="gSyncSetup.checkFields(event)"/>
</row>
<row id="existingUsernameFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="existingPasswordRow" align="center">
<label id="existingPasswordLabel"
value="&signIn.password.label;"
accesskey="&signIn.password.accesskey;"
control="existingPassword"/>
<textbox id="existingPassword"
type="password"
onkeyup="gSyncSetup.checkFields(event)"
onchange="gSyncSetup.checkFields(event)"/>
</row>
<row id="existingPasswordFeedbackRow" align="center" hidden="true">
<label class="text-link small" value="&resetPassword.label;"
onclick="gSyncUtils.resetPassword(); return false;"/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="existingLoginFeedbackRow">
<spacer/>
<hbox id="connect-throbber" hidden="true">
<image/>
<label value="&connecting.label;"/>
</hbox>
</row>
</rows>
</grid>
</wizardpage>
<wizardpage id="existingPassphraseEntry" label="&passphraseGroupbox.label;">
<description>&passphraseDesc3.label;</description>
<textbox type="password" id="existingPassphrase"
onkeyup="gSyncSetup.checkFields(event)"
onchange="gSyncSetup.checkFields(event)"/>
<hbox id="passphrase-throbber" hidden="true">
<image/>
<label value="&verifying.label;"/>
</hbox>
<hbox align="left" id="existingPassphraseFeedbackBox">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</hbox>
<vbox class="small" id="passphraseHelpBox" hidden="true">
<description class="small">&passphraseHelp.label;</description>
<label class="text-link small" value="&changePassphrase.label;"
onclick="gSyncUtils.resetPassphrase(); return false;"/>
</vbox>
</wizardpage>
<wizardpage id="mergeOptionsChoice"
label="&setup.mergeChoicePage.title.label;"
onpageshow="gSyncSetup.onPageShow()">
<radiogroup id="mergeChoiceRadio" pack="start">
<radio id="resetClient"
class="mergeChoiceButton"
aria-labelledby="mergeMain"
aria-describedby="mergeSecondary1 mergeSecondary2"
align="top">
<image class="mergeChoiceImage"/>
<vbox class="mergeChoiceButtonBox" flex="1">
<description class="mainDesc" id="mergeMain">
&choice.merge.main.label;
</description>
<separator class="thin"/>
<description class="normal" id="mergeSecondary2">
&choice.merge.recommend.label;
</description>
</vbox>
</radio>
<radio id="wipeClient"
class="mergeChoiceButton"
aria-labelledby="wipeClientMain"
align="top">
<image class="mergeChoiceImage"/>
<vbox class="mergeChoiceButtonBox" flex="1">
<description class="mainDesc" id="wipeClientMain">
&choice.client.main.label;
</description>
</vbox>
</radio>
<radio id="wipeRemote"
class="mergeChoiceButton"
aria-labelledby="wipeServerMain"
align="top">
<image class="mergeChoiceImage"/>
<vbox class="mergeChoiceButtonBox" flex="1">
<description class="mainDesc" id="wipeServerMain">
&choice.server.main.label;
</description>
</vbox>
</radio>
</radiogroup>
</wizardpage>
<wizardpage id="mergeOptionsConfirm" label="&confirm.caption.label;">
<deck id="chosenActionDeck">
<vbox id="chosenActionMerge">
<hbox pack="start" align="baseline">
<image/>
</hbox>
<separator class="thin"/>
<description class="normal">
&confirm.merge.label;
</description>
</vbox>
<vbox id="chosenActionWipeClient">
<hbox pack="start" align="baseline">
<image/>
</hbox>
<separator class="thin"/>
<description class="normal">
&confirm.client.label;
</description>
<separator class="thin"/>
<vbox id="dataList">
<label class="data indent" id="bookmarkCount"/>
<label class="data indent" id="historyCount"/>
<label class="data indent" id="passwordCount"/>
</vbox>
<separator class="thin"/>
<description class="normal">
&confirm.client.moreinfo.label;
</description>
<separator class="thin"/>
<description class="warning">
&confirm.client.warning.label;
</description>
</vbox>
<vbox id="chosenActionWipeServer">
<hbox pack="start" align="baseline">
<image/>
</hbox>
<separator class="thin"/>
<description class="normal">
&confirm.server.label;
</description>
<separator class="thin"/>
<vbox id="clientList">
</vbox>
<separator class="thin"/>
<description class="warning">
&confirm.server.warning.label;
</description>
</vbox>
</deck>
</wizardpage>
<wizardpage label="&setup.successPage.title.label;"
id="successfulSetup"
onpageshow="gSyncSetup.onPageShow()">
<description>
&setup.successPage.desc.label;
</description>
</wizardpage>
</wizard>

Просмотреть файл

@ -0,0 +1,176 @@
/* ***** 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 Weave.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Edward Lee <edilee@mozilla.com>
* Mike Connor <mconnor@mozilla.com>
* Paul OShannessy <paul@oshannessy.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 ***** */
// Weave should always exist before before this file gets included.
let gSyncUtils = {
// opens in a new window if we're in a modal prefwindow world, in a new tab otherwise
_openLink: function (url) {
let thisDocEl = document.documentElement,
openerDocEl = window.opener && window.opener.document.documentElement;
if (thisDocEl.id == "accountSetup" && window.opener &&
openerDocEl.id == "BrowserPreferences" && !openerDocEl.instantApply)
openUILinkIn(url, "window");
else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
openUILinkIn(url, "window");
else
openUILinkIn(url, "tab");
},
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;
},
openChange: function openChange(type) {
// Just re-show the dialog if it's already open
let openedDialog = Weave.Svc.WinMediator.getMostRecentWindow("Sync:" + type);
if (openedDialog != null) {
openedDialog.focus();
return;
}
// Open up the change dialog
let changeXUL = "chrome://browser/content/syncGenericChange.xul";
let changeOpt = "centerscreen,chrome,dialog,modal,resizable=no";
Weave.Svc.WinWatcher.activeWindow.openDialog(changeXUL, "", changeOpt, type);
},
changePassword: function () {
this.openChange("ChangePassword");
},
resetPassphrase: function () {
this.openChange("ResetPassphrase");
},
updatePassphrase: function () {
this.openChange("UpdatePassphrase");
},
resetPassword: function () {
this._openLink(Weave.Service.pwResetURL);
},
openToS: function () {
this._openLink(Weave.Svc.Prefs.get("termsURL"));
},
openPrivacyPolicy: function () {
this._openLink(Weave.Svc.Prefs.get("privacyURL"));
},
// xxxmpc - fix domain before 1.3 final (bug 583652)
_baseURL: "http://www.mozilla.com/firefox/sync/",
openFirstClientFirstrun: function () {
let url = this._baseURL + "firstrun.html";
this._openLink(url);
},
openAddedClientFirstrun: function () {
let url = this._baseURL + "secondrun.html";
this._openLink(url);
},
/**
* validatePassword / validatePassphrase
*
* @param el1 : the first textbox element in the form
* @param el2 : the second textbox element, if omitted it's an update form
*
* returns [valid, errorString]
*/
validatePassword: function (el1, el2) {
return this._validate(el1, el2, true);
},
validatePassphrase: function (el1, el2) {
return this._validate(el1, el2, false);
},
_validate: function (el1, el2, isPassword) {
let valid = false;
let val1 = el1.value;
let val2 = el2 ? el2.value : "";
let error = "";
if (isPassword) {
if (!el2)
valid = val1.length >= Weave.MIN_PASS_LENGTH;
else if (val1 && val1 == Weave.Service.username)
error = "change.password.pwSameAsUsername";
else if (val1 && val1 == Weave.Service.password)
error = "change.password.pwSameAsPassword";
else if (val1 && val1 == Weave.Service.passphrase)
error = "change.password.pwSameAsPassphrase";
else if (val1 && val2) {
if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH)
valid = true;
else if (val1.length < Weave.MIN_PASS_LENGTH)
error = "change.password.tooShort";
else if (val1 != val2)
error = "change.password.mismatch";
}
}
else {
if (!el2)
valid = val1.length >= Weave.MIN_PP_LENGTH;
else if (val1 == Weave.Service.username)
error = "change.passphrase.ppSameAsUsername";
else if (val1 == Weave.Service.password)
error = "change.passphrase.ppSameAsPassword";
else if (val1 == Weave.Service.passphrase)
error = "change.passphrase.ppSameAsPassphrase";
else if (val1 && val2) {
if (val1 == val2 && val1.length >= Weave.MIN_PP_LENGTH)
valid = true;
else if (val1.length < Weave.MIN_PP_LENGTH)
error = "change.passphrase.tooShort";
else if (val1 != val2)
error = "change.passphrase.mismatch";
}
}
let errorString = error ? Weave.Utils.getErrorString(error) : "";
dump("valid: " + valid + " error: " + errorString + "\n");
return [valid, errorString];
}
}

Просмотреть файл

@ -187,6 +187,7 @@
return;
this.moveTabTo(aTab, this._numPinnedTabs - 1);
aTab.setAttribute("fadein", "true");
aTab.removeAttribute("pinned");
aTab.style.MozMarginStart = "";
this.tabContainer._positionPinnedTabs();
@ -737,8 +738,10 @@
this._lastRelatedTab = null;
var oldBrowser = this.mCurrentBrowser;
if (oldBrowser)
if (oldBrowser) {
oldBrowser.setAttribute("type", "content-targetable");
oldBrowser.docShell.isActive = false;
}
var updatePageReport = false;
if (!oldBrowser ||
@ -747,6 +750,7 @@
updatePageReport = true;
newBrowser.setAttribute("type", "content-primary");
newBrowser.docShell.isActive = true;
this.mCurrentBrowser = newBrowser;
this.mCurrentTab = this.selectedTab;
@ -1093,13 +1097,19 @@
// doesn't go well together with the width transition. So we skip the
// transition in that case.
if (aSkipAnimation ||
this.tabContainer.getAttribute("overflow") == "true") {
this.tabContainer.getAttribute("overflow") == "true" ||
!Services.prefs.getBoolPref("browser.tabs.animate")) {
t.setAttribute("fadein", "true");
setTimeout(function (tabContainer) {
tabContainer._handleNewTab(t);
}, 0, this.tabContainer);
} else {
setTimeout(function () { t.setAttribute("fadein", "true"); }, 0);
setTimeout(function (tabContainer) {
if (t.pinned)
tabContainer._handleNewTab(t);
else
t.setAttribute("fadein", "true");
}, 0, this.tabContainer);
}
this.tabContainer.appendChild(t);
@ -1195,6 +1205,10 @@
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
try {
b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
// We start our browsers out as inactive, and then maintain
// activeness in the tab switcher.
b.docShell.isActive = false;
}
catch (ex) { }
}
@ -1287,9 +1301,10 @@
</method>
<method name="removeCurrentTab">
<parameter name="aParams"/>
<body>
<![CDATA[
this.removeTab(this.mCurrentTab);
this.removeTab(this.mCurrentTab, aParams);
]]>
</body>
</method>
@ -1300,9 +1315,36 @@
<method name="removeTab">
<parameter name="aTab"/>
<parameter name="aParams"/>
<body>
<![CDATA[
this._endRemoveTab(this._beginRemoveTab(aTab, false, null, true));
var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
if (aParams)
var animate = aParams.animate;
if (!this._beginRemoveTab(aTab, false, null, true))
return;
/* Don't animate if:
- the caller didn't opt in
- this is the last tab in the window
- this is a pinned tab
- a bunch of other tabs are already closing (arbitrary threshold)
- the fadein attribute hasn't been set yet
- browser.tabs.animate is false */
if (!animate ||
isLastTab ||
aTab.pinned ||
this._removingTabs.length > 3 ||
aTab.getAttribute("fadein") != "true" ||
!Services.prefs.getBoolPref("browser.tabs.animate")) {
this._endRemoveTab(aTab);
return;
}
this._blurTab(aTab);
aTab.removeAttribute("fadein");
]]>
</body>
</method>
@ -1313,7 +1355,6 @@
false
</field>
<!-- Returns everything that _endRemoveTab needs in an array. -->
<method name="_beginRemoveTab">
<parameter name="aTab"/>
<parameter name="aTabWillBeMoved"/>
@ -1322,14 +1363,14 @@
<body>
<![CDATA[
if (this._removingTabs.indexOf(aTab) > -1 || this._windowIsClosing)
return null;
return false;
var browser = this.getBrowserForTab(aTab);
if (!aTabWillBeMoved) {
let ds = browser.docShell;
if (ds && ds.contentViewer && !ds.contentViewer.permitUnload())
return null;
return false;
}
var closeWindow = false;
@ -1383,18 +1424,26 @@
tab.owner = null;
});
return [aTab, closeWindow, newTab];
aTab._endRemoveArgs = [closeWindow, newTab];
return true;
]]>
</body>
</method>
<method name="_endRemoveTab">
<parameter name="args"/>
<parameter name="aTab"/>
<body>
<![CDATA[
if (!args)
if (!aTab || !aTab._endRemoveArgs)
return;
var [aTab, aCloseWindow, aNewTab] = args;
var [aCloseWindow, aNewTab] = aTab._endRemoveArgs;
aTab._endRemoveArgs = null;
if (this._windowIsClosing) {
aCloseWindow = false;
aNewTab = false;
}
this._lastRelatedTab = null;
@ -1410,7 +1459,7 @@
if (aCloseWindow) {
this._windowIsClosing = true;
while (this._removingTabs.length)
this._endRemoveTab([this._removingTabs[0], false]);
this._endRemoveTab(this._removingTabs[0]);
} else if (!this._windowIsClosing) {
if (aNewTab)
focusAndSelectUrlBar();
@ -1536,13 +1585,13 @@
<body>
<![CDATA[
// That's gBrowser for the other window, not the tab's browser!
var remoteBrowser =
aOtherTab.ownerDocument.defaultView.getBrowser();
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
// First, start teardown of the other browser. Make sure to not
// fire the beforeunload event in the process. Close the other
// window if this was its last tab.
var endRemoveArgs = remoteBrowser._beginRemoveTab(aOtherTab, true, true);
if (!remoteBrowser._beginRemoveTab(aOtherTab, true, true))
return;
// Unhook our progress listener
var ourIndex = aOurTab._tPos;
@ -1569,7 +1618,7 @@
ourBrowser.swapDocShells(aOtherTab.linkedBrowser);
// Finish tearing down the tab that's going away.
remoteBrowser._endRemoveTab(endRemoveArgs);
remoteBrowser._endRemoveTab(aOtherTab);
// Restore the progress listener
tabListener = this.mTabProgressListener(aOurTab, ourBrowser,
@ -2148,7 +2197,7 @@
if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
this.mTabBox.handleCtrlPageUpDown) {
this.removeCurrentTab();
this.removeCurrentTab({animate: true});
aEvent.stopPropagation();
aEvent.preventDefault();
}
@ -2201,7 +2250,6 @@
this.mCurrentTab.linkedPanel = uniqueId;
this.mCurrentTab._tPos = 0;
this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
this.mCurrentTab.setAttribute("fadein", "true");
// set up the shared autoscroll popup
this._autoScrollPopup = this.mCurrentBrowser._createAutoScrollPopup();
@ -2351,6 +2399,10 @@
var tabs = document.getBindingParent(this);
tabs.removeAttribute("overflow");
tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser._endRemoveTab,
tabs.tabbrowser);
tabs._positionPinnedTabs();
]]></handler>
<handler event="overflow"><![CDATA[
@ -2734,8 +2786,15 @@
<handler event="TabSelect" action="this._handleTabSelect();"/>
<handler event="transitionend"><![CDATA[
if (event.propertyName == "max-width")
this._handleNewTab(event.target);
if (event.propertyName != "max-width")
return;
var tab = event.target;
if (tab.getAttribute("fadein") == "true")
this._handleNewTab(tab);
else if (this.tabbrowser._removingTabs.indexOf(tab) > -1)
this.tabbrowser._endRemoveTab(tab);
]]></handler>
<handler event="dblclick"><![CDATA[
@ -2751,7 +2810,7 @@
if (event.target.localName == "tab") {
if (this.childNodes.length > 1 || !this._closeWindowWithLastTab)
this.tabbrowser.removeTab(event.target);
this.tabbrowser.removeTab(event.target, {animate: true});
} else if (event.originalTarget.localName == "box") {
BrowserOpenTab();
} else {
@ -3068,7 +3127,7 @@
// Reset the "ignored click" flag
this._ignoredClick = false;
tabContainer.tabbrowser.removeTab(bindingParent);
tabContainer.tabbrowser.removeTab(bindingParent, {animate: true});
tabContainer._blockDblClick = true;
/* XXXmano hack (see bug 343628):

Просмотреть файл

@ -99,6 +99,7 @@ _BROWSER_FILES = \
title_test.svg \
browser_bug329212.js \
browser_bug356571.js \
browser_bug380960.js \
browser_bug386835.js \
browser_bug405137.js \
browser_bug406216.js \
@ -138,6 +139,7 @@ _BROWSER_FILES = \
browser_bug563588.js \
browser_bug577121.js \
browser_bug580956.js \
browser_bug581242.js \
browser_contextSearchTabPosition.js \
browser_ctrlTab.js \
browser_discovery.js \

Просмотреть файл

@ -0,0 +1,77 @@
function test() {
gBrowser.tabContainer.addEventListener("TabOpen", tabAdded, false);
var tab = gBrowser.addTab("about:blank", { skipAnimation: true });
gBrowser.removeTab(tab);
is(tab.parentNode, null, "tab removed immediately");
waitForExplicitFinish();
Services.prefs.setBoolPref("browser.tabs.animate", true);
nextAsyncText();
}
function tabAdded() {
info("tab added");
}
function cleanup() {
if (Services.prefs.prefHasUserValue("browser.tabs.animate"))
Services.prefs.clearUserPref("browser.tabs.animate");
gBrowser.tabContainer.removeEventListener("TabOpen", tabAdded, false);
finish();
}
var asyncTests = [
function (tab) {
info("closing tab with middle click");
EventUtils.synthesizeMouse(tab, 2, 2, { button: 1 });
},
function (tab) {
info("closing tab with accel+w");
gBrowser.selectedTab = tab;
content.focus();
EventUtils.synthesizeKey("w", { accelKey: true });
},
function (tab) {
info("closing tab by clicking the tab close button");
gBrowser.selectedTab = tab;
var button = document.getAnonymousElementByAttribute(tab, "anonid", "close-button");
EventUtils.synthesizeMouse(button, 2, 2, {});
}
];
function nextAsyncText() {
info("tests left: " + asyncTests.length + "; starting next");
var tab = gBrowser.addTab("about:blank", { skipAnimation: true });
var gotCloseEvent = false;
tab.addEventListener("TabClose", function () {
info("got TabClose event");
gotCloseEvent = true;
const DEFAULT_ANIMATION_LENGTH = 250;
const MAX_WAIT_TIME = DEFAULT_ANIMATION_LENGTH * 5;
var polls = Math.ceil(MAX_WAIT_TIME / DEFAULT_ANIMATION_LENGTH);
var pollTabRemoved = setInterval(function () {
--polls;
if (tab.parentNode && polls > 0)
return;
clearInterval(pollTabRemoved);
is(tab.parentNode, null, "tab removed after at most " + MAX_WAIT_TIME + " ms");
if (asyncTests.length)
nextAsyncText();
else
cleanup();
}, DEFAULT_ANIMATION_LENGTH);
}, false);
asyncTests.shift()(tab);
ok(gotCloseEvent, "got the close event syncronously");
is(tab.parentNode, gBrowser.tabContainer, "tab still exists when it's about to be removed asynchronously");
}

Просмотреть файл

@ -1,4 +1,3 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -12,20 +11,18 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
* The Original Code is bug 581242 test.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2000
* Sindre Dammann <sindrebugzilla@gmail.com>
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vidur Apparao <vidur@netscape.com> (original author)
* Johnny Stenback <jst@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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"),
* 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
@ -37,19 +34,19 @@
*
* ***** END LICENSE BLOCK ***** */
#include "domstubs.idl"
function test() {
// Create a new tab and load about:addons
let blanktab = gBrowser.addTab();
gBrowser.selectedTab = blanktab;
BrowserOpenAddonsMgr();
[scriptable, uuid(a6cf90c7-15b3-11d2-932e-00805f8add32)]
interface nsIDOMNSHTMLImageElement : nsISupports
{
attribute DOMString lowsrc;
readonly attribute boolean complete;
readonly attribute long naturalHeight;
readonly attribute long naturalWidth;
// These attributes are offsets from the closest view (to mimic
// NS4's "offset-from-layer" behavior).
readonly attribute long x;
readonly attribute long y;
};
is(blanktab, gBrowser.selectedTab, "Current tab should be blank tab");
// Verify that about:addons loads
waitForExplicitFinish();
gBrowser.selectedBrowser.addEventListener("load", function() {
let browser = blanktab.linkedBrowser;
is(browser.currentURI.spec, "about:addons", "about:addons should load into blank tab.");
gBrowser.removeTab(blanktab);
finish();
}, true);
}

Просмотреть файл

@ -52,6 +52,17 @@ browser.jar:
* content/browser/web-panels.xul (content/web-panels.xul)
* content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul)
* content/browser/nsContextMenu.js (content/nsContextMenu.js)
#ifdef MOZ_SERVICES_SYNC
* content/browser/aboutSyncTabs.xul (content/aboutSyncTabs.xul)
content/browser/aboutSyncTabs.js (content/aboutSyncTabs.js)
content/browser/aboutSyncTabs.css (content/aboutSyncTabs.css)
* content/browser/aboutSyncTabs-bindings.xml (content/aboutSyncTabs-bindings.xml)
* content/browser/syncSetup.xul (content/syncSetup.xul)
content/browser/syncSetup.js (content/syncSetup.js)
* content/browser/syncGenericChange.xul (content/syncGenericChange.xul)
content/browser/syncGenericChange.js (content/syncGenericChange.js)
content/browser/syncUtils.js (content/syncUtils.js)
#endif
# XXX: We should exclude this one as well (bug 71895)
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
#ifdef XP_MACOSX

Просмотреть файл

@ -96,6 +96,10 @@ static RedirEntry kRedirMap[] = {
nsIAboutModule::ALLOW_SCRIPT },
{ "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
#ifdef MOZ_SERVICES_SYNC
{ "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
nsIAboutModule::ALLOW_SCRIPT },
#endif
};
static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);

Просмотреть файл

@ -202,6 +202,9 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#ifdef MOZ_SERVICES_SYNC
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#endif
#ifndef WINCE
{ NS_PROFILEMIGRATOR_CONTRACTID, &kNS_FIREFOX_PROFILEMIGRATOR_CID },
#if defined(XP_WIN) && !defined(__MINGW32__)

Просмотреть файл

@ -380,6 +380,29 @@ BrowserGlue.prototype = {
temp.WinTaskbarJumpList.startup();
}
#endif
#endif
#ifdef MOZ_SERVICES_SYNC
// Assume that a non-zero value for services.sync.autoconnectDelay should override
if (Services.prefs.prefHasUserValue("services.sync.autoconnectDelay")) {
let prefDelay = Services.prefs.getIntPref("services.sync.autoconnectDelay");
if (prefDelay > 0)
return;
}
// delays are in seconds
const MAX_DELAY = 300;
let delay = 3;
let enum = Services.wm.getEnumerator("navigator:browser");
while (enum.hasMoreElements()) {
delay += enum.getNext().gBrowser.tabs.length;
}
delay = delay <= MAX_DELAY ? delay : MAX_DELAY;
let syncTemp = {};
Cu.import("resource://services-sync/service.js", syncTemp);
syncTemp.Weave.Service.delayedAutoConnect(delay);
#endif
},

Просмотреть файл

@ -32,5 +32,9 @@ browser.jar:
* content/browser/preferences/security.js
* content/browser/preferences/selectBookmark.xul
* content/browser/preferences/selectBookmark.js
#ifdef MOZ_SERVICES_SYNC
* content/browser/preferences/sync.xul
* content/browser/preferences/sync.js
#endif
* content/browser/preferences/tabs.xul
* content/browser/preferences/tabs.js

Просмотреть файл

@ -113,6 +113,10 @@
src="chrome://browser/content/preferences/security.xul"/>
<prefpane id="paneAdvanced" label="&paneAdvanced.title;"
src="chrome://browser/content/preferences/advanced.xul"/>
#ifdef MOZ_SERVICES_SYNC
<prefpane id="paneSync" label="&paneSync.title;"
src="chrome://browser/content/preferences/sync.xul"/>
#endif
#ifdef XP_MACOSX
#include ../../base/content/browserMountPoints.inc

Просмотреть файл

@ -0,0 +1,244 @@
/* ***** 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 Weave.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Edward Lee <edilee@mozilla.com>
* Mike Connor <mconnor@mozilla.com>
* Paul OShannessy <paul@oshannessy.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 ***** */
Components.utils.import("resource://services-sync/service.js");
Components.utils.import("resource://gre/modules/Services.jsm");
const PAGE_NO_ACCOUNT = 0;
const PAGE_HAS_ACCOUNT = 1;
let gSyncPane = {
_stringBundle: null,
prefArray: ["engine.bookmarks", "engine.passwords", "engine.prefs",
"engine.tabs", "engine.history"],
get page() {
return document.getElementById("weavePrefsDeck").selectedIndex;
},
set page(val) {
document.getElementById("weavePrefsDeck").selectedIndex = val;
},
get _usingCustomServer() {
return Weave.Svc.Prefs.isSet("serverURL");
},
onLoginStart: function () {
if (this.page == PAGE_NO_ACCOUNT)
return;
document.getElementById("loginFeedbackRow").hidden = true;
document.getElementById("connectThrobber").hidden = false;
},
onLoginError: function () {
if (this.page == PAGE_NO_ACCOUNT)
return;
document.getElementById("connectThrobber").hidden = true;
document.getElementById("loginFeedbackRow").hidden = false;
let label = document.getElementById("loginError");
label.value = Weave.Utils.getErrorString(Weave.Status.login);
label.className = "error";
},
onLoginFinish: function () {
document.getElementById("connectThrobber").hidden = true;
this.updateWeavePrefs();
},
init: function () {
let obs = [
["weave:service:login:start", "onLoginStart"],
["weave:service:login:error", "onLoginError"],
["weave:service:login:finish", "onLoginFinish"],
["weave:service:start-over", "updateWeavePrefs"],
["weave:service:setup-complete","updateWeavePrefs"],
["weave:service:logout:finish", "updateWeavePrefs"]];
// Add the observers now and remove them on unload
let self = this;
let addRem = function(add) {
obs.forEach(function([topic, func]) {
//XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
// of `this`. Fix in a followup. (bug 583347)
if (add)
Weave.Svc.Obs.add(topic, self[func], self);
else
Weave.Svc.Obs.remove(topic, self[func], self);
});
};
addRem(true);
window.addEventListener("unload", function() addRem(false), false);
this._stringBundle =
Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties");;
this.updateWeavePrefs();
},
updateWeavePrefs: function () {
if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
Weave.Svc.Prefs.get("firstSync", "") == "notReady")
this.page = PAGE_NO_ACCOUNT;
else {
this.page = PAGE_HAS_ACCOUNT;
document.getElementById("currentUser").value = Weave.Service.username;
document.getElementById("syncComputerName").value = Weave.Clients.localName;
if (Weave.Status.service == Weave.LOGIN_FAILED)
this.onLoginError();
this.updateConnectButton();
let syncEverything = this._checkDefaultValues();
document.getElementById("weaveSyncMode").selectedIndex = syncEverything ? 0 : 1;
document.getElementById("syncModeOptions").selectedIndex = syncEverything ? 0 : 1;
document.getElementById("tosPP").hidden = this._usingCustomServer;
}
},
updateConnectButton: function () {
let str = Weave.Service.isLoggedIn ? this._stringBundle.GetStringFromName("disconnect.label")
: this._stringBundle.GetStringFromName("connect.label");
document.getElementById("connectButton").label = str;
},
handleConnectCommand: function () {
Weave.Service.isLoggedIn ? Weave.Service.logout() : Weave.Service.login();
},
startOver: function (showDialog) {
if (showDialog) {
let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL;
let buttonChoice =
Services.prompt.confirmEx(window,
this._stringBundle.GetStringFromName("differentAccount.title"),
this._stringBundle.GetStringFromName("differentAccount.label"),
flags,
this._stringBundle.GetStringFromName("differentAccountConfirm.label"),
null, null, null, {});
// If the user selects cancel, just bail
if (buttonChoice == 1)
return;
}
this.handleExpanderClick();
Weave.Service.startOver();
this.updateWeavePrefs();
document.getElementById("manageAccountExpander").className = "expander-down";
document.getElementById("manageAccountControls").hidden = true;
},
updatePass: function () {
if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED)
gSyncUtils.changePassword();
else
gSyncUtils.updatePassphrase();
},
resetPass: function () {
if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED)
gSyncUtils.resetPassword();
else
gSyncUtils.resetPassphrase();
},
updateSyncPrefs: function () {
let syncEverything = document.getElementById("weaveSyncMode").selectedItem.value == "syncEverything";
document.getElementById("syncModeOptions").selectedIndex = syncEverything ? 0 : 1;
if (syncEverything) {
let prefs = this.prefArray;
for (let i = 0; i < prefs.length; ++i)
document.getElementById(prefs[i]).value = true;
}
},
/**
* Check whether all the preferences values are set to their default values
*
* @param aPrefs an array of pref names to check for
* @returns boolean true if all of the prefs are set to their default values,
* false otherwise
*/
_checkDefaultValues: function () {
let prefs = this.prefArray;
for (let i = 0; i < prefs.length; ++i) {
let pref = document.getElementById(prefs[i]);
if (pref.value != pref.defaultValue)
return false;
}
return true;
},
handleExpanderClick: function () {
//XXXzpao Might be fixed in bug 583441, otherwise we'll need a new bug.
// ok, this is pretty evil, and likely fragile if the prefwindow
// binding changes, but that won't happen in 3.6 *fingers crossed*
let prefwindow = document.documentElement;
let pane = document.getElementById("paneSync");
if (prefwindow._shouldAnimate)
prefwindow._currentHeight = pane.contentHeight;
let expander = document.getElementById("manageAccountExpander");
let expand = expander.className == "expander-down";
expander.className =
expand ? "expander-up" : "expander-down";
document.getElementById("manageAccountControls").hidden = !expand;
// and... shazam
if (prefwindow._shouldAnimate)
prefwindow.animate("null", pane);
},
openSetup: function (resetSync) {
var win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/syncSetup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no", resetSync);
}
},
resetSync: function () {
this.openSetup(true);
}
}

Просмотреть файл

@ -0,0 +1,207 @@
<?xml version="1.0"?>
# ***** 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 Weave.
#
# The Initial Developer of the Original Code is the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Edward Lee <edilee@mozilla.com>
# Mike Connor <mconnor@mozilla.com>
# Paul OShannessy <paul@oshannessy.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 *****
<!DOCTYPE overlay [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
%brandDTD;
%syncBrandDTD;
%syncDTD;
]>
<overlay id="SyncPaneOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<prefpane id="paneSync"
helpTopic="prefs-weave"
onpaneload="gSyncPane.init()">
<preferences>
<preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/>
<preference id="engine.history" name="services.sync.engine.history" type="bool"/>
<preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/>
<preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/>
<preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
</preferences>
<script type="application/javascript"
src="chrome://browser/content/preferences/sync.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
<deck id="weavePrefsDeck">
<vbox id="noAccount" align="center">
<spacer flex="1"/>
<button id="setupButton"
label="&setupButton.label;"
accesskey="&setupButton.accesskey;"
oncommand="gSyncPane.openSetup();"/>
<separator/>
<description id="syncDesc" flex="1">
&weaveDesc.label;
</description>
<spacer flex="3"/>
</vbox>
<vbox id="hasAccount">
<groupbox>
<caption label="&accountGroupboxCaption.label;"/>
<grid>
<rows>
<row align="center">
<label value="&currentUser.label;" control="currentUser"/>
<textbox id="currentUser" readonly="true">
<image/>
</textbox>
<hbox align="center">
<button id="connectButton" oncommand="gSyncPane.handleConnectCommand()"/>
<image id="connectThrobber"
hidden="true"/>
</hbox>
</row>
<row id="loginFeedbackRow" hidden="true">
<spacer/>
<label id="loginError" value=""/>
<hbox>
<label class="text-link"
onclick="gSyncPane.updatePass(); return false;"
value="&updatePass.label;"/>
<label class="text-link"
onclick="gSyncPane.resetPass(); return false;"
value="&resetPass.label;"/>
</hbox>
</row>
<!-- XXXzpao We should make this behave like the "details" view in CRH.
do in followup (bug 583441) -->
<row id="manageAccountControls" hidden="true">
<spacer/>
<vbox class="indent">
<label class="text-link"
onclick="gSyncUtils.changePassword(); return false;"
value="&changePassword.label;"/>
<label class="text-link"
onclick="gSyncUtils.resetPassphrase(); return false;"
value="&changePassphrase.label;"/>
<label class="text-link"
onclick="gSyncPane.resetSync(); return false;"
value="&resetSync.label;"/>
<label class="text-link"
onclick="gSyncPane.startOver(true); return false;"
value="&differentAccount.label;"/>
</vbox>
<spacer/>
</row>
<row>
<spacer/>
<button id="manageAccountExpander"
class="expander-down"
label="&manageAccount.label;"
accesskey="&manageAccount.accesskey;"
align="left"
oncommand="gSyncPane.handleExpanderClick()"/>
<spacer/>
</row>
</rows>
</grid>
</groupbox>
<groupbox>
<caption label="&syncPrefsCaption.label;"/>
<grid>
<rows>
<row align="center">
<label value="&syncComputerName.label;"
accesskey="&syncComputerName.accesskey;"
control="syncComputerName"/>
<textbox id="syncComputerName"
onchange="gSyncUtils.changeName(this)"/>
</row>
<row align="center">
<label value="&syncModeSwitchDesc.label;"
accesskey="&syncModeSwitchDesc.accesskey;"
control="weaveSyncMode"/>
<menulist id="weaveSyncMode" oncommand="gSyncPane.updateSyncPrefs()">
<menupopup>
<menuitem label="&syncEverything.label;" value="syncEverything"/>
<menuitem label="&customSync.label;" value="customSync"/>
</menupopup>
</menulist>
</row>
</rows>
</grid>
<separator/>
<deck id="syncModeOptions" class="indent">
<description id="syncEverythingDesc">
&syncEverythingDescription.label;
</description>
<vbox>
<checkbox label="&syncItem.bookmarks.label;"
accesskey="&syncItem.bookmarks.accesskey;"
preference="engine.bookmarks"/>
<checkbox label="&syncItem.passwords.label;"
accesskey="&syncItem.passwords.accesskey;"
preference="engine.passwords"/>
<checkbox label="&syncItem.prefs.label;"
accesskey="&syncItem.prefs.accesskey;"
preference="engine.prefs"/>
<checkbox label="&syncItem.history.label;"
accesskey="&syncItem.history.accesskey;"
preference="engine.history"/>
<checkbox label="&syncItem.tabs.label;"
accesskey="&syncItem.tabs.accesskey;"
preference="engine.tabs"/>
</vbox>
</deck>
<separator/>
</groupbox>
<hbox id="tosPP" pack="center">
<label class="text-link"
onclick="event.stopPropagation();gSyncUtils.openToS();"
value="&prefs.tosLink.label;"/>
<label class="text-link"
onclick="event.stopPropagation();gSyncUtils.openPP();"
value="&prefs.ppLink.label;"/>
</hbox>
</vbox>
</deck>
</prefpane>
</overlay>

Просмотреть файл

@ -104,6 +104,7 @@ function test() {
pb.privateBrowsingEnabled = false;
Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
gBrowser.getBrowserAtIndex(gBrowser.tabContainer.selectedIndex).contentWindow.focus();
finish();
}, true);
}, true);

Просмотреть файл

@ -111,6 +111,7 @@ function test() {
acceptDialog = 2;
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
gBrowser.getBrowserAtIndex(gBrowser.tabContainer.selectedIndex).contentWindow.focus();
Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
finish();

Просмотреть файл

@ -1 +1 @@
4.0b3pre
4.0b4pre

Просмотреть файл

@ -135,8 +135,10 @@ function test() {
// test names array - NOTE: "bookmarkProperties/description" is an annotation too
var names = testBookmark.annotations.names;
is(names[1], "testing/bookmark/string", "Checking contents of annotation names array");
is(names.length, 4, "Checking the annotation names array after adding 3 annotations");
ok(names.some(function (f) f == "bookmarkProperties/description"), "Checking for description annotation");
ok(names.some(function (f) f == "testing/bookmark/string"), "Checking for string test annotation");
ok(names.some(function (f) f == "testing/bookmark/int"), "Checking for int test annotation");
ok(names.some(function (f) f == "testing/bookmark/double"), "Checking for double test annotation");
// test adding a separator
var testSeparator = testFolder.addSeparator();

Просмотреть файл

@ -377,8 +377,10 @@
@BINPATH@/components/nsPrompter.manifest
@BINPATH@/components/nsPrompter.js
#ifdef MOZ_SERVICES_SYNC
@BINPATH@/components/SyncComponents.manifest
@BINPATH@/components/FormNotifier.js
@BINPATH@/components/Weave.js
@BINPATH@/components/WeaveCrypto.manifest
@BINPATH@/components/WeaveCrypto.js
#endif

Просмотреть файл

@ -0,0 +1,17 @@
<!-- LOCALIZATION NOTE (tabs.otherComputers.label): Keep this in sync with syncTabsMenu.label from browser.dtd -->
<!ENTITY tabs.otherComputers.label "Tabs From Other Computers">
<!ENTITY tabs.searchText.label "Type here to find tabs…">
<!-- LOCALIZATION NOTE (tabs.context.openTab.accesskey, tabs.context.openMultipleTabs.accesskey):
Only one of these will show at a time (based on selection), so reusing accesskey is ok. -->
<!ENTITY tabs.context.openTab.label "Open This Tab">
<!ENTITY tabs.context.openTab.accesskey "O">
<!ENTITY tabs.context.openMultipleTabs.label "Open Selected Tabs">
<!ENTITY tabs.context.openMultipleTabs.accesskey "O">
<!ENTITY tabs.context.bookmarkSingleTab.label "Bookmark This Tab…">
<!ENTITY tabs.context.bookmarkSingleTab.accesskey "B">
<!ENTITY tabs.context.bookmarkMultipleTabs.label "Bookmark Selected Tabs…">
<!ENTITY tabs.context.bookmarkMultipleTabs.accesskey "B">
<!ENTITY tabs.context.refreshList.label "Refresh List">
<!ENTITY tabs.context.refreshList.accesskey "R">

Просмотреть файл

@ -119,6 +119,7 @@
<!ENTITY printButton.label "Print">
<!ENTITY printButton.tooltip "Print this page">
<!ENTITY backForwardItem.title "Back/Forward">
<!ENTITY locationItem.title "Location">
<!ENTITY searchItem.title "Search">
<!ENTITY throbberItem.title "Activity Indicator">
@ -509,3 +510,21 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!-- Name for the tabs toolbar as spoken by screen readers.
The word "toolbar" is appended automatically and should not be contained below! -->
<!ENTITY tabsToolbar.label "Browser tabs">
<!-- LOCALIZATION NOTE (syncTabsMenu.label): This appears in the history menu -->
<!ENTITY syncTabsMenu.label "Tabs From Other Computers">
<!ENTITY syncBrand.shortName.label "Sync">
<!ENTITY syncMenu.label "&syncBrand.shortName.label;">
<!-- LOCALIZATION NOTE (sync.menu.accesskey): This is part of the tools menu, so
don't use a conflicting access key -->
<!ENTITY syncMenu.accesskey "Y">
<!ENTITY syncSetup.label "Set Up &syncBrand.shortName.label;…">
<!ENTITY syncSetup.accesskey "Y">
<!ENTITY syncLogInItem.label "Connect">
<!ENTITY syncLogInItem.accesskey "C">
<!ENTITY syncLogOutItem.label "Disconnect">
<!ENTITY syncLogOutItem.accesskey "D">
<!ENTITY syncSyncNowItem.label "Sync Now">
<!ENTITY syncSyncNowItem.accesskey "S">

Просмотреть файл

@ -14,3 +14,6 @@
<!ENTITY panePrivacy.title "Privacy">
<!ENTITY paneSecurity.title "Security">
<!ENTITY paneAdvanced.title "Advanced">
<!-- LOCALIZATION NOTE (paneSync.title): This should match syncBrand.shortName.label in ../syncBrand.dtd -->
<!ENTITY paneSync.title "Sync">

Просмотреть файл

@ -103,3 +103,12 @@ offlineAppUsage=%1$S %2$S
offlinepermissionstext=The following websites are not allowed to store data for offline use:
offlinepermissionstitle=Offline Data
#### Syncing
connect.label=Connect
disconnect.label=Disconnect
differentAccount.title=Use a Different Account?
differentAccount.label=This will reset all of your Sync account information and preferences.
differentAccountConfirm.label=Reset All Information

Просмотреть файл

@ -0,0 +1,44 @@
<!-- The page shown when not logged in... -->
<!ENTITY setupButton.label "Set Up &syncBrand.fullName.label;">
<!ENTITY setupButton.accesskey "S">
<!ENTITY weaveDesc.label "&syncBrand.fullName.label; lets you access your history, bookmarks, passwords and open tabs across all your devices.">
<!-- The page shown when logged in... -->
<!ENTITY accountGroupboxCaption.label "&syncBrand.fullName.label; Account">
<!ENTITY currentUser.label "Current User:">
<!-- Login error feedback -->
<!ENTITY updatePass.label "Update">
<!ENTITY resetPass.label "Reset">
<!-- Manage Account -->
<!ENTITY manageAccount.label "Manage Account">
<!ENTITY manageAccount.accesskey "A">
<!ENTITY changePassword.label "Change Password">
<!ENTITY changePassphrase.label "Change Secret Phrase">
<!ENTITY resetSync.label "Reset Sync">
<!ENTITY differentAccount.label "Use a Different Account">
<!-- Sync Settings -->
<!ENTITY syncPrefsCaption.label "Browser Sync">
<!ENTITY syncComputerName.label "Computer Name:">
<!ENTITY syncComputerName.accesskey "c">
<!ENTITY syncModeSwitchDesc.label "&brandShortName; will: ">
<!ENTITY syncModeSwitchDesc.accesskey "w">
<!ENTITY syncEverything.label "Sync Everything">
<!ENTITY customSync.label "Use my custom settings">
<!ENTITY syncEverythingDescription.label "Your bookmarks, history, passwords, preferences, and tabs will be synced.">
<!ENTITY syncItem.bookmarks.label "Sync Bookmarks">
<!ENTITY syncItem.bookmarks.accesskey "m">
<!ENTITY syncItem.tabs.label "Sync Tabs">
<!ENTITY syncItem.tabs.accesskey "T">
<!ENTITY syncItem.history.label "Sync History">
<!ENTITY syncItem.history.accesskey "r">
<!ENTITY syncItem.passwords.label "Sync Passwords">
<!ENTITY syncItem.passwords.accesskey "P">
<!ENTITY syncItem.prefs.label "Sync Preferences">
<!ENTITY syncItem.prefs.accesskey "S">
<!-- Footer stuff -->
<!ENTITY prefs.tosLink.label "Terms of Service">
<!ENTITY prefs.ppLink.label "Privacy Policy">

Просмотреть файл

@ -0,0 +1,2 @@
<!ENTITY syncBrand.shortName.label "Sync">
<!ENTITY syncBrand.fullName.label "Firefox Sync">

Просмотреть файл

@ -0,0 +1,37 @@
# LOCALIZATION NOTE (change.password.title): This (and associated change.password/passphrase) are used when the user elects to change their password.
change.password.title = Change your Password
change.password.acceptButton = Change Password
change.password.status.active = Changing your password…
change.password.status.success = Your password has been changed.
change.password.status.error = There was an error changing your password.
change.password.introText = Your password must be at least 8 characters long. It cannot be the same as either your user name or your secret phrase.
change.password.warningText = Note: All of your other devices will be unable to connect to your account once you change this password.
change.passphrase.title = Change your Secret Phrase
change.passphrase.acceptButton = Change Secret Phrase
change.passphrase.label = Changing secret phrase and uploading local data, please wait…
change.passphrase.error = There was an error while changing your secret phrase!
change.passphrase.success = Your secret phrase was successfully changed!
# LOCALIZATION NOTE (change.passphrase.introText) "Sync" should match &syncBrand.shortName.label; from syncBrand.dtd
change.passphrase.introText = Your secret phrase must be at least 12 characters long. Sync uses this phrase as part of encrypting your data.
# LOCALIZATION NOTE (change.passphrase.introText2) "Firefox Sync" should match syncBrand.fullName.label from syncBrand.dtd
change.passphrase.introText2 = You may wish to write this down, as this is never sent over the Internet and is not backed up or synced by Firefox Sync for your security.
# LOCALIZATION NOTE (change.passphrase.warningText) "Sync" should match &syncBrand.shortName.label; from syncBrand.dtd
change.passphrase.warningText = Note: This will erase all data stored on the Sync server and upload new data secured by this phrase. Your other devices will not sync until the secret phrase is entered for that device.
# LOCALIZATION NOTE (new.password.title): This (and associated new.password/passphrase) are used on a second computer when it detects that your password or passphrase has been changed on a different device.
new.password.title = Update Password
new.password.introText = Your password was rejected by the server, please update your password.
new.password.label = Enter your new password
new.password.confirm = Confirm your new password
new.password.acceptButton = Update Password
new.password.status.incorrect = Password incorrect, please try again.
new.passphrase.title = Update Secret Phrase
new.passphrase.introText = Your secret phrase has changed, please enter your new secret phrase
new.passphrase.label = New secret phrase
new.passphrase.confirm = Confirm secret phrase
new.passphrase.acceptButton = Update Secret Phrase
new.passphrase.status.incorrect = Secret phrase incorrect, please try again.

Просмотреть файл

@ -0,0 +1,98 @@
<!ENTITY accountSetupTitle.label "&syncBrand.fullName.label; Setup">
<!-- First page of the wizard -->
<!ENTITY setup.choicePage.title.label "Have you used &syncBrand.fullName.label; before?">
<!ENTITY setup.choicePage.new.label "I've never used &syncBrand.shortName.label; before">
<!ENTITY setup.choicePage.existing.label "I'm already using &syncBrand.shortName.label; on another computer">
<!-- New Account AND Existing Account -->
<!ENTITY connectTo.label "Connect to">
<!ENTITY serverType.main.label "&syncBrand.fullName.label; Server">
<!ENTITY serverType.custom.label "Use a custom server">
<!ENTITY signIn.username.label "User Name">
<!ENTITY signIn.username.accesskey "U">
<!ENTITY signIn.password.label "Password">
<!ENTITY signIn.password.accesskey "P">
<!ENTITY signIn.serverURL.label "Server URL">
<!ENTITY signIn.serverURL.accesskey "L">
<!-- New Account Page 1: Basic Account Info -->
<!ENTITY setup.newAccountPage.title.label "Create your &syncBrand.shortName.label; Account">
<!ENTITY setup.confirmPassword.label "Confirm Password">
<!ENTITY setup.confirmPassword.accesskey "m">
<!ENTITY setup.emailAddress.label "Email Address">
<!ENTITY setup.emailAddress.accesskey "E">
<!-- LOCALIZATION NOTE: tosAgree1, tosLink, tosAgree2, ppLink, tosAgree3 are
joined with implicit white space, so spaces in the strings aren't necessary -->
<!ENTITY setup.tosAgree1.label "I agree to the">
<!ENTITY setup.tosAgree1.accesskey "a">
<!ENTITY setup.tosLink.label "Terms of Service">
<!ENTITY setup.tosAgree2.label "and the">
<!ENTITY setup.ppLink.label "Privacy Policy">
<!ENTITY setup.tosAgree3.label "">
<!ENTITY setup.tosAgree2.accesskey "">
<!-- New Account Page 2: Passphrase Entry -->
<!ENTITY setup.newPPPage.title.label "Enter your Secret Phrase">
<!ENTITY passphraseDesc.label "Please enter a secret phrase. This will be used to encrypt all your data so only you can access it. It is never stored on the server, so don't lose this!">
<!ENTITY passphraseDesc2.label "This must be at least 12 characters long and cannot match your account password.">
<!ENTITY passphraseEntry.label "Secret Phrase">
<!ENTITY passphraseEntry.accesskey "S">
<!ENTITY passphraseConfirm.label "Confirm">
<!ENTITY passphraseConfirm.accesskey "m">
<!-- New Account Page 3: Sync Type Options -->
<!ENTITY setup.newAccountPrefs2.title.label "Browser Sync Preferences">
<!ENTITY syncComputerName.label "Computer Name:">
<!ENTITY syncComputerName.accesskey "c">
<!ENTITY syncModeSwitchDesc.label "&brandShortName; will: ">
<!ENTITY syncModeSwitchDesc.accesskey "w">
<!ENTITY syncEverything.label "Sync Everything">
<!ENTITY customSync.label "Use my custom settings">
<!ENTITY syncEverythingDescription.label "Your bookmarks, history, passwords, preferences, and tabs will be synced.">
<!ENTITY syncItem.bookmarks.label "Sync Bookmarks">
<!ENTITY syncItem.bookmarks.accesskey "m">
<!ENTITY syncItem.tabs.label "Sync Tabs">
<!ENTITY syncItem.tabs.accesskey "T">
<!ENTITY syncItem.history.label "Sync History">
<!ENTITY syncItem.history.accesskey "r">
<!ENTITY syncItem.passwords.label "Sync Passwords">
<!ENTITY syncItem.passwords.accesskey "P">
<!ENTITY syncItem.prefs.label "Sync Preferences">
<!ENTITY syncItem.prefs.accesskey "S">
<!-- New Account Page 4: Captcha -->
<!ENTITY setup.captchaPage.title.label "Please confirm you're not a robot ;)">
<!-- Existing Account Page 1: Login -->
<!ENTITY setup.existingAccount.title.label "Enter Account Information">
<!ENTITY resetPassword.label "Reset Password">
<!ENTITY connecting.label "Connecting…">
<!-- Existing Account Page 2: Passphrase -->
<!ENTITY passphraseGroupbox.label "Enter Secret Phrase">
<!ENTITY passphraseDesc3.label "Please enter your secret phrase. This must be the same secret phrase that you used to encrypt your data.">
<!ENTITY passphraseHelp.label "Your secret phrase is at least 12 characters long and is not your password. You can find your saved secret phrase by going to your other computer and checking the Saved Passwords under Security. If you still cannot get the correct secret phrase, you can choose to reset it, but you will lose any data stored on the server.">
<!ENTITY changePassphrase.label "Change Secret Phrase">
<!ENTITY verifying.label "Verifying…">
<!-- New & Existing Account: Merge Options -->
<!ENTITY setup.mergeChoicePage.title.label "How do you want to start off?">
<!ENTITY choice.merge.main.label "Merge this computer's data with your &syncBrand.shortName.label; data">
<!ENTITY choice.merge.recommend.label "This option is strongly recommended by Mozilla for all users.">
<!ENTITY choice.client.main.label "Replace all data on this computer with your &syncBrand.fullName.label; data">
<!ENTITY choice.server.main.label "Replace all other devices with your local data">
<!-- New & Existing Account: Confirm Merge Options -->
<!ENTITY confirm.caption.label "Confirm your choice">
<!ENTITY confirm.merge.label "You have chosen to merge your data on this computer with the data on your other devices running &syncBrand.fullName.label;.">
<!ENTITY confirm.client.label "All &brandShortName; data on this computer will be deleted, including the following:">
<!ENTITY confirm.client.moreinfo.label "&brandShortName; will then copy your &syncBrand.fullName.label; data to this computer.">
<!ENTITY confirm.client.warning.label "WARNING: This will result in all &brandShortName; data on this computer being replaced!">
<!ENTITY confirm.server.label "The following devices will be overwritten with your local data:">
<!ENTITY confirm.server.warning.label "WARNING: Your local data will replace all &brandShortName; data on these devices!">
<!-- New & Existing Account: Setup Complete -->
<!ENTITY setup.successPage.title.label "Setup Complete!">
<!ENTITY setup.successPage.desc.label "Congratulations! &brandShortName; is now set up to automatically sync your information. Don't forget to install &syncBrand.fullName.label; on all your devices. You can now continue using &brandShortName;.">

Просмотреть файл

@ -0,0 +1,16 @@
cancelSetup.label = Cancel Setup
errorCreatingAccount.title = Error Creating Account
invalidEmail.label = Invalid email address
serverInvalid.label = Please enter a valid server URL
usernameNotAvailable.label = Already in use
# LOCALIZATION NOTE (additionalClients.label, bookmarkCount.label, historyCount.label, passwordCount.label).
# We'll fix the lack of PluralForms in bug 583661.
additionalClients.label = and %S additional devices
bookmarkCount.label = %S bookmarks
historyCount.label = %S days of history
passwordCount.label = %S passwords
# Several other strings are used (via Weave.Status.login), but they come from
# /services/sync */

Просмотреть файл

@ -7,6 +7,9 @@
locale/browser/aboutPrivateBrowsing.dtd (%chrome/browser/aboutPrivateBrowsing.dtd)
locale/browser/aboutRobots.dtd (%chrome/browser/aboutRobots.dtd)
locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
#ifdef MOZ_SERVICES_SYNC
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
#endif
locale/browser/credits.dtd (%chrome/browser/credits.dtd)
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
@ -61,8 +64,17 @@
locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd)
locale/browser/preferences/security.dtd (%chrome/browser/preferences/security.dtd)
#ifdef MOZ_SERVICES_SYNC
locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd)
#endif
locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
locale/browser/sidebar/sidebar.properties (%chrome/browser/sidebar/sidebar.properties)
#ifdef MOZ_SERVICES_SYNC
locale/browser/syncBrand.dtd (%chrome/browser/syncBrand.dtd)
locale/browser/syncSetup.dtd (%chrome/browser/syncSetup.dtd)
locale/browser/syncSetup.properties (%chrome/browser/syncSetup.properties)
locale/browser/syncGenericChange.properties (%chrome/browser/syncGenericChange.properties)
#endif
% locale browser-region @AB_CD@ %locale/browser-region/
locale/browser-region/region.properties (%chrome/browser-region/region.properties)
# the following files are browser-specific overrides

Просмотреть файл

@ -1,24 +1,34 @@
be
ca
cs
da
de
el
en-US
es-AR
es-ES
et
fi
fr
ga-IE
hu
is
it
ko
ku
lt
nb-NO
nl
nn-NO
pa-IN
pl
pt-BR
pt-PT
ro
ru
sk
sv-SE
tr
uk
zh-CN
zh-TW

Просмотреть файл

@ -0,0 +1,97 @@
#tabs-display,
#tabsList {
background-color: transparent;
-moz-appearance: none;
margin: 0;
}
#tabsList {
width: 100%;
}
#tabs-display {
background: #fff url(chrome://browser/skin/sync-bg.png) repeat-x center -80px;
}
#headers {
background: url(chrome://browser/skin/sync-32.png) no-repeat;
margin-top: 4px;
width: 45em;
height: 32px;
-moz-margin-start: 2em;
-moz-margin-end: 2em;
}
#tabsListHeading {
font-size: 140%;
font-weight: bold;
-moz-margin-start: 40px;
}
richlistitem {
-moz-margin-end: 2em;
}
richlistitem[selected="true"],
richlistitem:focus {
outline-style: none;
}
richlistitem[type="tab"] {
min-height: 3em;
border: #999999 1px solid !important;
padding: 2px 5px;
margin-bottom: 4px;
-moz-margin-start: 4em;
-moz-border-radius: 6px;
background-color: menu;
width: 44em;
opacity: 0.9;
-moz-box-shadow:
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 0px;
}
richlistitem[type="tab"][selected="true"] {
background-color: -moz-MenuHover;
}
richlistitem[type="client"] {
min-height: 2em;
color: #000000;
-moz-margin-start: 2em;
margin-top: 2px;
margin-bottom: 3px;
width: 42em;
-moz-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");
}
richlistitem.desktop[type="client"] {
list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
}
.title,
.clientName {
color: #000000;
font-size: 1.1em;
}
.title[selected="true"],
.url[selected="true"] {
color: inherit;
}
.url {
color: -moz-nativehyperlinktext;
font-size: 0.95em;
}
.tabIcon {
-moz-padding-start: 2px;
padding-top: 2px;
}

Просмотреть файл

@ -6,6 +6,9 @@ browser.jar:
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css (aboutCertError.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
@ -59,9 +62,27 @@ browser.jar:
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/mail.png (preferences/mail.png)
skin/classic/browser/preferences/Options.png (preferences/Options.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png)
#endif
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
skin/classic/browser/tabbrowser/progress.png (tabbrowser/progress.png)
skin/classic/browser/tabbrowser/progress-pulsing.png (tabbrowser/progress-pulsing.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-desktopIcon.png
skin/classic/browser/sync-merge.png
skin/classic/browser/sync-mobileIcon.png
skin/classic/browser/sync-usedBefore.png
skin/classic/browser/sync-usedNever.png
skin/classic/browser/sync-wipeClient.png
skin/classic/browser/sync-wipeServer.png
skin/classic/browser/syncSetup.css
skin/classic/browser/syncCommon.css
#endif

Двоичные данные
browser/themes/gnomestripe/browser/preferences/Options-sync.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Просмотреть файл

@ -73,6 +73,12 @@ radio[pane=paneAdvanced] {
-moz-image-region: rect(0px, 224px, 32px, 192px)
}
%ifdef MOZ_SERVICES_SYNC
radio[pane=paneSync] {
list-style-image: url("chrome://browser/skin/preferences/Options-sync.png") !important;
}
%endif
/* Applications Pane */
#BrowserPreferences[animated="true"] #handlersView {
height: 25em;
@ -158,3 +164,40 @@ radio[pane=paneAdvanced] {
#SanitizeDialogPane > groupbox {
margin-top: 0;
}
%ifdef MOZ_SERVICES_SYNC
/* Sync Pane */
#syncDesc {
padding: 0 12em;
}
#currentUser image {
list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
}
#connectThrobber {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.expander-up,
.expander-down {
min-width: 0;
padding: 2px 0;
-moz-padding-start: 2px;
}
.expander-up {
list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
}
.expander-down {
list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
}
.expander-down:hover:active {
list-style-image: url("chrome://global/skin/arrow/arrow-dn-hov.gif");
}
.expander-up:hover:active {
list-style-image: url("chrome://global/skin/arrow/arrow-up-hov.gif");
}
%endif

Двоичные данные
browser/themes/gnomestripe/browser/sync-16-throbber.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.1 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-32.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-bg.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-desktopIcon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 291 B

Двоичные данные
browser/themes/gnomestripe/browser/sync-merge.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.7 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-mobileIcon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 352 B

Двоичные данные
browser/themes/gnomestripe/browser/sync-usedBefore.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-usedNever.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-wipeClient.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичные данные
browser/themes/gnomestripe/browser/sync-wipeServer.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Просмотреть файл

@ -0,0 +1,41 @@
/* The following are used by both syncSetup.xul and syncGenericChange.xul */
.status {
color: -moz-dialogtext;
}
.statusIcon {
-moz-margin-start: 4px;
max-height: 16px;
max-width: 16px;
}
.statusIcon[status="active"] {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.statusIcon[status="error"] {
list-style-image: url("chrome://global/skin/icons/error-16.png");
}
.statusIcon[status="success"] {
list-style-image: url("chrome://global/skin/icons/information-16.png");
}
/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
a separate stylesheet for it. */
.data {
font-size: 90%;
font-weight: bold;
}
dialog#change-dialog {
width: 40em;
}
image#syncIcon {
list-style-image: url("chrome://browser/skin/sync-32.png");
}
#introText {
margin-top: 2px;
}

Просмотреть файл

@ -0,0 +1,117 @@
.wizard-header-icon {
list-style-image: url(chrome://browser/skin/sync-32.png);
}
wizard,
.wizard-page-box,
.wizard-header {
-moz-appearance: none !important;
}
wizard {
background-color: #FFF;
background: url(chrome://browser/skin/sync-bg.png) #FFF repeat-x center -80px;
}
/* Override the text-link style from global.css */
.text-link,
.text-link:focus {
margin: 0px;
padding: 0px;
border: 0px;
}
.accountChoiceButton,
.mergeChoiceButton {
-moz-appearance: none;
border: #999999 1px solid !important;
padding: 2px 3px;
-moz-border-radius: 6px;
background-color: menu;
-moz-box-shadow:
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 0px;
}
.accountChoiceButton:hover,
.mergeChoiceButton[selected="true"] {
background-color: -moz-MenuHover;
color: -moz-MenuHoverText;
}
.mergeChoiceButtonBox {
padding: 0.2em;
}
.success,
.error {
padding: 2px;
-moz-border-radius: 2px;
}
.error {
background-color: #FF0000 !important;
color: #FFFFFF !important;
}
.success {
background-color: #00FF00 !important;
}
.warning {
font-weight: bold;
font-size: 100%;
color: red;
}
.mainDesc {
font-weight: bold;
font-size: 100%;
}
.normal {
font-size: 100%;
}
/* Buttons on first page of wizard */
#newAccount,
#existingAccount {
min-height: 5em;
}
#newAccount image {
list-style-image: url("chrome://browser/skin/sync-usedNever.png");
}
#existingAccount image {
list-style-image: url("chrome://browser/skin/sync-usedBefore.png");
}
.inputColumn {
-moz-margin-end: 2px
}
#tosDesc {
width: 16em;
}
#connect-throbber image,
#passphrase-throbber image {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
/* Merge choice images */
#resetClient .mergeChoiceImage,
#chosenActionMerge image {
list-style-image: url("chrome://browser/skin/sync-merge.png");
}
#wipeClient .mergeChoiceImage,
#chosenActionWipeClient image {
list-style-image: url("chrome://browser/skin/sync-wipeClient.png");
}
#wipeRemote .mergeChoiceImage,
#chosenActionWipeServer image {
list-style-image: url("chrome://browser/skin/sync-wipeServer.png");
}

Просмотреть файл

@ -0,0 +1,97 @@
#tabs-display,
#tabsList {
background-color: transparent;
-moz-appearance: none;
margin: 0;
}
#tabsList {
width: 100%;
}
#tabs-display {
background: #fff url(chrome://browser/skin/sync-bg.png) repeat-x center -80px;
}
#headers {
background: url(chrome://browser/skin/sync-32.png) no-repeat;
margin-top: 4px;
width: 45em;
height: 32px;
-moz-margin-start: 2em;
-moz-margin-end: 2em;
}
#tabsListHeading {
font-size: 140%;
font-weight: bold;
-moz-margin-start: 40px;
}
richlistitem {
-moz-margin-end: 2em;
}
richlistitem[selected="true"],
richlistitem:focus {
outline-style: none;
}
richlistitem[type="tab"] {
min-height: 3em;
border: #999999 1px solid !important;
padding: 2px 5px;
margin-bottom: 4px;
-moz-margin-start: 4em;
-moz-border-radius: 6px;
background-color: menu;
width: 44em;
opacity: 0.9;
-moz-box-shadow:
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 0px;
}
richlistitem[type="tab"][selected="true"] {
background-color: -moz-MenuHover;
}
richlistitem[type="client"] {
min-height: 2em;
color: #000000;
-moz-margin-start: 2em;
margin-top: 2px;
margin-bottom: 3px;
width: 42em;
-moz-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");
}
richlistitem.desktop[type="client"] {
list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
}
.title,
.clientName {
color: #000000;
font-size: 1.1em;
}
.title[selected="true"],
.url[selected="true"] {
color: inherit;
}
.url {
color: -moz-nativehyperlinktext;
font-size: 0.95em;
}
.tabIcon {
-moz-padding-start: 2px;
padding-top: 2px;
}

Просмотреть файл

@ -296,12 +296,6 @@ toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button,
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
margin: 0;
-moz-box-orient: vertical;
}
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]),
toolbar[mode="icons"] #restore-button,
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button,
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
padding: 0 3px;
height: 22px;
border: 1px solid @toolbarbuttonBorderColor@;
@ -311,12 +305,29 @@ toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubut
background-origin: border-box;
}
toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]),
toolbar[mode="icons"] #restore-button,
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button {
toolbar:not([mode="icons"]) .toolbarbutton-1:not([type="menu-button"]),
toolbar:not([mode="icons"]) #restore-button,
toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button,
toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
padding: 0;
height: auto;
border: none;
-moz-box-shadow: none;
background: none;
}
.toolbarbutton-1:not([type="menu-button"]),
#restore-button,
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button {
min-width: 28px;
}
toolbar:not([mode="icons"]) .toolbarbutton-1:not([type="menu-button"]),
toolbar:not([mode="icons"]) #restore-button,
toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button {
min-width: 0;
}
.toolbarbutton-1 > .toolbarbutton-icon,
#restore-button > .toolbarbutton-icon,
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
@ -344,22 +355,24 @@ toolbarbutton[type="menu-button"] {
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
list-style-image: url(chrome://browser/skin/toolbarbutton-dropmarker.png);
}
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
width: 14px;
padding-top: 2px;
-moz-border-start: none !important;
}
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
width: auto;
padding-top: 0;
}
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
-moz-border-radius-topleft: 0;
-moz-border-radius-bottomleft: 0;
}
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-locale-dir(ltr),
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(rtl) {
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-locale-dir(ltr),
toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(rtl) {
-moz-border-radius-topright: 0;
-moz-border-radius-bottomright: 0;
}
@ -406,6 +419,11 @@ toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen
-moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 3px 5px, @loweredShadow@;
}
toolbar[mode="icons"] .toolbarbutton-1 > menupopup,
toolbar[mode="icons"] toolbarbutton[type="menu-button"] > menupopup {
margin-top: 1px;
}
/* unified back/forward button */
#unified-back-forward-button {
@ -2080,3 +2098,8 @@ panel[dimmed="true"] {
opacity: 0.5;
}
/* Sync */
#sync-status-button.statusbarpanel-iconic {
padding: 0 5px;
}

Просмотреть файл

@ -5,6 +5,9 @@ browser.jar:
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css (aboutCertError.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
@ -94,8 +97,11 @@ browser.jar:
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/application.png (preferences/application.png)
skin/classic/browser/preferences/Options.png (preferences/Options.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png)
#endif
skin/classic/browser/preferences/saveFile.png (preferences/saveFile.png)
skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png (tabbrowser/alltabs-box-bkgnd-icon.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
@ -106,3 +112,18 @@ browser.jar:
skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png (tabbrowser/tabbrowser-tabs-bkgnd.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabbrowser/tab-bkgnd.png (tabbrowser/tab-bkgnd.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-desktopIcon.png
skin/classic/browser/sync-merge.png
skin/classic/browser/sync-mobileIcon.png
skin/classic/browser/sync-usedBefore.png
skin/classic/browser/sync-usedNever.png
skin/classic/browser/sync-wipeClient.png
skin/classic/browser/sync-wipeServer.png
skin/classic/browser/syncSetup.css
skin/classic/browser/syncCommon.css
#endif

Просмотреть файл

@ -85,10 +85,10 @@
#placesToolbar > toolbarbutton {
list-style-image: url("chrome://browser/skin/places/toolbar.png");
margin: 4px 6px 5px;
padding: 1px 5px;
-moz-border-radius: 100%;
margin: 4px 4px 5px;
padding: 1px 3px;
border: 1px solid @toolbarbuttonBorderColor@;
-moz-border-radius: @toolbarbuttonCornerRadius@;
-moz-box-shadow: @loweredShadow@;
background: @toolbarbuttonBackground@;
background-origin: border-box;
@ -96,11 +96,9 @@
#placesToolbar > toolbarbutton:not([disabled="true"]):active:hover,
#placesToolbar > toolbarbutton[open="true"] {
background: rgba(0, 0, 0, 0.6);
border-color: transparent;
-moz-box-shadow: @toolbarbuttonPressedInnerShadow@,
@loweredShadow@,
inset 0 0 0 20px @toolbarbuttonPressedBackgroundColor@;
background: @toolbarbuttonPressedBackgroundColor@;
text-shadow: @loweredShadow@;
-moz-box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
}
#placesToolbar > toolbarbutton:-moz-window-inactive {
@ -121,18 +119,17 @@
}
#placesToolbar > toolbarbutton[type="menu"] > .toolbarbutton-menu-dropmarker {
list-style-image: url("chrome://browser/skin/places/folderDropArrow.png");
-moz-image-region: rect(0, 7px, 5px, 0);
list-style-image: url(chrome://browser/skin/toolbarbutton-dropmarker.png);
padding: 0;
margin-top: 1px;
-moz-margin-end: 3px;
-moz-margin-end: 2px;
}
#placesToolbar > toolbarbutton > menupopup {
margin-top: 1px;
}
/* back and forward button */
#placesToolbar > #back-button {
-moz-margin-start: 3px;
}
#back-button:-moz-locale-dir(ltr),
#forward-button:-moz-locale-dir(rtl) {
-moz-image-region: rect(0px, 16px, 16px, 0px);
@ -151,11 +148,13 @@
}
#back-button > .toolbarbutton-icon {
-moz-margin-start: 3px !important;
-moz-margin-end: 2px !important;
}
#forward-button > .toolbarbutton-icon {
-moz-margin-start: 2px !important;
-moz-margin-end: 3px !important;
}
/* organize button */

Двоичные данные
browser/themes/pinstripe/browser/preferences/Options-sync.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Просмотреть файл

@ -119,6 +119,13 @@ radio[pane=paneAdvanced]:active:hover {
-moz-image-region: rect(32px, 224px, 64px, 192px);
}
%ifdef MOZ_SERVICES_SYNC
/* ----- SYNC BUTTON ----- */
radio[pane=paneSync] {
list-style-image: url("chrome://browser/skin/preferences/Options-sync.png");
}
%endif
/* ----- APPLICATIONS PREFPANE ----- */
@ -242,3 +249,36 @@ caption {
#SanitizeDialogPane > groupbox {
margin-top: 0;
}
%ifdef MOZ_SERVICES_SYNC
/* ----- SYNC PANE ----- */
#syncDesc {
padding: 0 12em;
}
#currentUser image {
list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
}
#connectThrobber {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.expander-up,
.expander-down {
-moz-appearance: none;
padding: 0;
min-width: 0;
}
.expander-up {
list-style-image: url("chrome://browser/skin/places/expander-open.png") !important;
}
.expander-down {
list-style-image: url('chrome://browser/skin/places/expander-closed.png') !important
}
%endif

Просмотреть файл

@ -19,6 +19,11 @@
background-position: left center;
}
.searchbar-popup {
margin-top: 4px;
-moz-margin-start: 3px;
}
.searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box {
margin: 0;
padding: 3px 0 2px;

Двоичные данные
browser/themes/pinstripe/browser/sync-16-throbber.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.1 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-32.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-bg.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-desktopIcon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 291 B

Двоичные данные
browser/themes/pinstripe/browser/sync-merge.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.7 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-mobileIcon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 352 B

Двоичные данные
browser/themes/pinstripe/browser/sync-usedBefore.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-usedNever.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-wipeClient.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичные данные
browser/themes/pinstripe/browser/sync-wipeServer.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Просмотреть файл

@ -0,0 +1,41 @@
/* The following are used by both syncSetup.xul and syncGenericChange.xul */
.status {
color: -moz-dialogtext;
}
.statusIcon {
-moz-margin-start: 4px;
max-height: 16px;
max-width: 16px;
}
.statusIcon[status="active"] {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.statusIcon[status="error"] {
list-style-image: url("chrome://global/skin/icons/error-16.png");
}
.statusIcon[status="success"] {
list-style-image: url("chrome://global/skin/icons/information-16.png");
}
/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
a separate stylesheet for it. */
.data {
font-size: 90%;
font-weight: bold;
}
dialog#change-dialog {
width: 40em;
}
image#syncIcon {
list-style-image: url("chrome://browser/skin/sync-32.png");
}
#introText {
margin-top: 2px;
}

Просмотреть файл

@ -0,0 +1,117 @@
.wizard-header-icon {
list-style-image: url(chrome://browser/skin/sync-32.png);
}
wizard,
.wizard-page-box,
.wizard-header {
-moz-appearance: none !important;
}
wizard {
background-color: #FFF;
background: url(chrome://browser/skin/sync-bg.png) #FFF repeat-x center -80px;
}
/* Override the text-link style from global.css */
.text-link,
.text-link:focus {
margin: 0px;
padding: 0px;
border: 0px;
}
.accountChoiceButton,
.mergeChoiceButton {
-moz-appearance: none;
border: #999999 1px solid !important;
padding: 2px 3px;
-moz-border-radius: 6px;
background-color: menu;
-moz-box-shadow:
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 0px;
}
.accountChoiceButton:hover,
.mergeChoiceButton[selected="true"] {
background-color: -moz-MenuHover;
color: -moz-MenuHoverText;
}
.mergeChoiceButtonBox {
padding: 0.2em;
}
.success,
.error {
padding: 2px;
-moz-border-radius: 2px;
}
.error {
background-color: #FF0000 !important;
color: #FFFFFF !important;
}
.success {
background-color: #00FF00 !important;
}
.warning {
font-weight: bold;
font-size: 100%;
color: red;
}
.mainDesc {
font-weight: bold;
font-size: 100%;
}
.normal {
font-size: 100%;
}
/* Buttons on first page of wizard */
#newAccount,
#existingAccount {
min-height: 5em;
}
#newAccount image {
list-style-image: url("chrome://browser/skin/sync-usedNever.png");
}
#existingAccount image {
list-style-image: url("chrome://browser/skin/sync-usedBefore.png");
}
.inputColumn {
-moz-margin-end: 2px
}
#tosDesc {
width: 16em;
}
#connect-throbber image,
#passphrase-throbber image {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
/* Merge choice images */
#resetClient .mergeChoiceImage,
#chosenActionMerge image {
list-style-image: url("chrome://browser/skin/sync-merge.png");
}
#wipeClient .mergeChoiceImage,
#chosenActionWipeClient image {
list-style-image: url("chrome://browser/skin/sync-wipeClient.png");
}
#wipeRemote .mergeChoiceImage,
#chosenActionWipeServer image {
list-style-image: url("chrome://browser/skin/sync-wipeServer.png");
}

Просмотреть файл

@ -0,0 +1,97 @@
#tabs-display,
#tabsList {
background-color: transparent;
-moz-appearance: none;
margin: 0;
}
#tabsList {
width: 100%;
}
#tabs-display {
background: #fff url(chrome://browser/skin/sync-bg.png) repeat-x center -80px;
}
#headers {
background: url(chrome://browser/skin/sync-32.png) no-repeat;
margin-top: 4px;
width: 45em;
height: 32px;
-moz-margin-start: 2em;
-moz-margin-end: 2em;
}
#tabsListHeading {
font-size: 140%;
font-weight: bold;
-moz-margin-start: 40px;
}
richlistitem {
-moz-margin-end: 2em;
}
richlistitem[selected="true"],
richlistitem:focus {
outline-style: none;
}
richlistitem[type="tab"] {
min-height: 3em;
border: #999999 1px solid !important;
padding: 2px 5px;
margin-bottom: 4px;
-moz-margin-start: 4em;
-moz-border-radius: 6px;
background-color: menu;
width: 44em;
opacity: 0.9;
-moz-box-shadow:
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 0px;
}
richlistitem[type="tab"][selected="true"] {
background-color: -moz-MenuHover;
}
richlistitem[type="client"] {
min-height: 2em;
color: #000000;
-moz-margin-start: 2em;
margin-top: 2px;
margin-bottom: 3px;
width: 42em;
-moz-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");
}
richlistitem.desktop[type="client"] {
list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
}
.title,
.clientName {
color: #000000;
font-size: 1.1em;
}
.title[selected="true"],
.url[selected="true"] {
color: inherit;
}
.url {
color: -moz-nativehyperlinktext;
font-size: 0.95em;
}
.tabIcon {
-moz-padding-start: 2px;
padding-top: 2px;
}

Просмотреть файл

@ -415,6 +415,27 @@ toolbarbutton[type="menu-button"][open="true"] > .toolbarbutton-menubutton-dropm
height: 18px;
}
toolbar[iconsize="small"] .toolbarbutton-menubutton-button > .toolbarbutton-icon,
toolbar[iconsize="small"] .toolbarbutton-1 > .toolbarbutton-icon {
margin: 1px;
width: 16px;
height: 16px;
}
/* Default icons have a built-in glow, so they are 18*18px even in small mode,
except for the large back icon, which is why the code below uses 'auto' rather
than 18px. This will pick the correct size based on the image region. */
:-moz-any(
#back-button, #forward-button, #reload-button, #stop-button,
#home-button, #print-button, #downloads-button, #history-button,
#bookmarks-button, #bookmarks-menu-button, #new-tab-button,
#new-window-button, #cut-button, #copy-button, #paste-button,
#fullscreen-button) > .toolbarbutton-icon {
margin: 0 !important;
width: auto !important;
height: auto !important;
}
toolbar[mode="full"] .toolbarbutton-1,
toolbar[mode="full"] .toolbarbutton-menubutton-button {
min-width: 57px;
@ -500,11 +521,6 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button:not([disabled="true"]
0 2px 0 rgba(255,255,255,.4);
}
toolbar:not([iconsize="small"])[mode="icons"] #back-button > .toolbarbutton-icon {
width: auto;
height: auto;
}
toolbar:not([iconsize="small"])[mode="icons"][currentset*="unified-back-forward-button"],
#nav-bar:not([iconsize="small"])[mode="icons"]:not([currentset]) {
padding-top: 3px;

Просмотреть файл

@ -8,6 +8,9 @@ browser.jar:
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon.png)
skin/classic/browser/aboutCertError.css (aboutCertError.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
skin/classic/browser/appmenu-dropmarker.png
* skin/classic/browser/browser.css (browser.css)
@ -74,8 +77,11 @@ browser.jar:
skin/classic/browser/preferences/application.png (preferences/application.png)
skin/classic/browser/preferences/mail.png (preferences/mail.png)
skin/classic/browser/preferences/Options.png (preferences/Options.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png)
#endif
skin/classic/browser/preferences/saveFile.png (preferences/saveFile.png)
skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
@ -84,6 +90,21 @@ browser.jar:
skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)
skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-desktopIcon.png
skin/classic/browser/sync-merge.png
skin/classic/browser/sync-mobileIcon.png
skin/classic/browser/sync-usedBefore.png
skin/classic/browser/sync-usedNever.png
skin/classic/browser/sync-wipeClient.png
skin/classic/browser/sync-wipeServer.png
skin/classic/browser/syncSetup.css
skin/classic/browser/syncCommon.css
#endif
#ifdef XP_WIN
browser.jar:
@ -93,6 +114,9 @@ browser.jar:
* skin/classic/aero/browser/aboutSessionRestore.css (aboutSessionRestore.css)
skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
skin/classic/aero/browser/aboutCertError.css (aboutCertError.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/aboutSyncTabs.css
#endif
skin/classic/aero/browser/actionicon-tab.png (actionicon-tab.png)
skin/classic/aero/browser/appmenu-dropmarker.png
* skin/classic/aero/browser/browser.css (browser-aero.css)
@ -160,9 +184,12 @@ browser.jar:
skin/classic/aero/browser/preferences/application.png (preferences/application-aero.png)
skin/classic/aero/browser/preferences/mail.png (preferences/mail-aero.png)
skin/classic/aero/browser/preferences/Options.png (preferences/Options-aero.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/preferences/Options-sync.png (preferences/Options-sync.png)
#endif
skin/classic/aero/browser/preferences/plugin.png (preferences/plugin-aero.png)
skin/classic/aero/browser/preferences/saveFile.png (preferences/saveFile-aero.png)
skin/classic/aero/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/aero/browser/preferences/preferences.css (preferences/preferences.css)
skin/classic/aero/browser/preferences/applications.css (preferences/applications.css)
skin/classic/aero/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
@ -171,4 +198,19 @@ browser.jar:
skin/classic/aero/browser/tabbrowser/tab.png (tabbrowser/tab.png)
skin/classic/aero/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
skin/classic/aero/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/sync-16-throbber.png
skin/classic/aero/browser/sync-16.png
skin/classic/aero/browser/sync-32.png
skin/classic/aero/browser/sync-bg.png
skin/classic/aero/browser/sync-desktopIcon.png
skin/classic/aero/browser/sync-merge.png
skin/classic/aero/browser/sync-mobileIcon.png
skin/classic/aero/browser/sync-usedBefore.png
skin/classic/aero/browser/sync-usedNever.png
skin/classic/aero/browser/sync-wipeClient.png
skin/classic/aero/browser/sync-wipeServer.png
skin/classic/aero/browser/syncSetup.css
skin/classic/aero/browser/syncCommon.css
#endif
#endif

Двоичные данные
browser/themes/winstripe/browser/preferences/Options-sync.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Просмотреть файл

@ -100,6 +100,12 @@ radio[pane=paneAdvanced][selected="true"] {
-moz-image-region: rect(32px, 224px, 64px, 192px)
}
%ifdef MOZ_SERVICES_SYNC
radio[pane=paneSync] {
list-style-image: url("chrome://browser/skin/preferences/Options-sync.png") !important;
}
%endif
/* Applications Pane */
#BrowserPreferences[animated="true"] #handlersView {
height: 25em;
@ -172,3 +178,38 @@ radio[pane=paneAdvanced][selected="true"] {
.bottomBox {
padding-bottom: 4px;
}
%ifdef MOZ_SERVICES_SYNC
/* Sync Pane */
#syncDesc {
padding: 0 12em;
}
#currentUser image {
list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
}
#connectThrobber {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.expander-up,
.expander-down {
min-width: 0;
margin: 0;
-moz-margin-end: 4px;
}
.expander-up > .button-box,
.expander-down > .button-box {
padding: 0;
}
.expander-up {
list-style-image: url("chrome://global/skin/icons/collapse.png");
}
.expander-down {
list-style-image: url("chrome://global/skin/icons/expand.png");
}
%endif

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше