Bug 735091 - Sync pane for in-content prefrences. r=jaws,bmcbride
authorDevan Sayles <saylesd1@msu.edu>
Tue, 08 May 2012 19:23:19 -0700
changeset 93580 29de131322c5793c7f3a639653d3deef7d88d647
parent 93579 4953a39c52e6e841eddad41975d0420eabe339e3
child 93581 0fbf6059c2937ea5ce1c2f7dc140daf90bf2437b
push id9210
push userjwein@mozilla.com
push dateWed, 09 May 2012 05:35:43 +0000
treeherdermozilla-inbound@8b195889f55c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws, bmcbride
bugs735091
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 735091 - Sync pane for in-content prefrences. r=jaws,bmcbride
browser/components/preferences/in-content/jar.mn
browser/components/preferences/in-content/preferences.js
browser/components/preferences/in-content/preferences.xul
browser/components/preferences/in-content/sync.js
browser/components/preferences/in-content/sync.xul
--- a/browser/components/preferences/in-content/jar.mn
+++ b/browser/components/preferences/in-content/jar.mn
@@ -9,8 +9,10 @@ browser.jar:
    content/browser/preferences/in-content/privacy.xul
    content/browser/preferences/in-content/privacy.js
 *  content/browser/preferences/in-content/advanced.xul
 *  content/browser/preferences/in-content/advanced.js
 *  content/browser/preferences/in-content/applications.xul
 *  content/browser/preferences/in-content/applications.js
    content/browser/preferences/in-content/content.xul
    content/browser/preferences/in-content/content.js
+   content/browser/preferences/in-content/sync.xul
+   content/browser/preferences/in-content/sync.js
\ No newline at end of file
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -20,16 +20,17 @@ function init_all() {
   gMainPane.init();
 #ifdef XP_WIN
   gTabsPane.init();
 #endif
   gPrivacyPane.init();
   gAdvancedPane.init();
   gApplicationsPane.init();
   gContentPane.init();
+  gSyncPane.init();
   var initFinished = document.createEvent("Event");
   initFinished.initEvent("Initialized", true, true);
   document.dispatchEvent(initFinished);
 }
 
 function gotoPref(page) {
   search(page, "data-category");
   window.history.pushState(page, document.title);
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -91,12 +91,16 @@
     <prefpane flex="1" id="mainPrefPane">
 #include landing.xul
 #include main.xul
 #include tabs.xul
 #include privacy.xul
 #include advanced.xul
 #include applications.xul
 #include content.xul
+
+#ifdef MOZ_SERVICES_SYNC
+#include sync.xul
+#endif
     </prefpane>
   </hbox>
   
 </page>
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/sync.js
@@ -0,0 +1,155 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Components.utils.import("resource://services-sync/service.js");
+
+const PAGE_NO_ACCOUNT = 0;
+const PAGE_HAS_ACCOUNT = 1;
+const PAGE_NEEDS_UPDATE = 2;
+
+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");
+  },
+
+  needsUpdate: function () {
+    this.page = PAGE_NEEDS_UPDATE;
+    let label = document.getElementById("loginError");
+    label.value = Weave.Utils.getErrorString(Weave.Status.login);
+    label.className = "error";
+  },
+
+  init: function () {
+    let topics = ["weave:service:login:error",
+                  "weave:service:login:finish",
+                  "weave:service:start-over",
+                  "weave:service:setup-complete",
+                  "weave:service:logout:finish"];
+
+    // Add the observers now and remove them on unload
+    //XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
+    //        of `this`. Fix in a followup. (bug 583347)
+    topics.forEach(function (topic) {
+      Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this);
+    }, this);
+    window.addEventListener("unload", function() {
+      topics.forEach(function (topic) {
+        Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this);
+      }, gSyncPane);
+    }, 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 if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE ||
+               Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
+      this.needsUpdate();
+    } else {
+      this.page = PAGE_HAS_ACCOUNT;
+      document.getElementById("accountName").value = Weave.Service.account;
+      document.getElementById("syncComputerName").value = Weave.Clients.localName;
+      document.getElementById("tosPP").hidden = this._usingCustomServer;
+    }
+  },
+
+  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 + 
+                  Services.prompt.BUTTON_POS_1_DEFAULT;
+      let buttonChoice =
+        Services.prompt.confirmEx(window,
+                                  this._stringBundle.GetStringFromName("syncUnlink.title"),
+                                  this._stringBundle.GetStringFromName("syncUnlink.label"),
+                                  flags,
+                                  this._stringBundle.GetStringFromName("syncUnlinkConfirm.label"),
+                                  null, null, null, {});
+
+      // If the user selects cancel, just bail
+      if (buttonChoice == 1)
+        return;
+    }
+
+    Weave.Service.startOver();
+    this.updateWeavePrefs();
+  },
+
+  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();
+  },
+
+  /**
+   * Invoke the Sync setup wizard.
+   * 
+   * @param wizardType
+   *        Indicates type of wizard to launch:
+   *          null    -- regular set up wizard
+   *          "pair"  -- pair a device first
+   *          "reset" -- reset sync
+   */
+  openSetup: function (wizardType) {
+    var win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
+    if (win)
+      win.focus();
+    else {
+      window.openDialog("chrome://browser/content/sync/setup.xul",
+                        "weaveSetup", "centerscreen,chrome,resizable=no",
+                        wizardType);
+    }
+  },
+
+  openQuotaDialog: function () {
+    let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
+    if (win)
+      win.focus();
+    else 
+      window.openDialog("chrome://browser/content/sync/quota.xul", "",
+                        "centerscreen,chrome,dialog,modal");
+  },
+
+  openAddDevice: function () {
+    if (!Weave.Utils.ensureMPUnlocked())
+      return;
+    
+    let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
+    if (win)
+      win.focus();
+    else 
+      window.openDialog("chrome://browser/content/sync/addDevice.xul",
+                        "syncAddDevice", "centerscreen,chrome,resizable=no");
+  },
+
+  resetSync: function () {
+    this.openSetup("reset");
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/sync.xul
@@ -0,0 +1,173 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this file,
+   - You can obtain one at http://mozilla.org/MPL/2.0/.  -->
+
+<preferences>
+  <preference id="engine.addons"
+              name="services.sync.engine.addons"
+              type="bool"/>
+  <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/in-content/sync.js"/>
+<script type="application/javascript"
+        src="chrome://browser/content/sync/utils.js"/>
+
+<hbox class="heading" data-category="paneSync" hidden="true">
+  <image class="preference-icon" type="sync"/>
+  <html:h1>&paneSync.title;</html:h1>
+</hbox>
+
+<deck id="weavePrefsDeck" data-category="paneSync" hidden="true">
+  <vbox id="noAccount" align="center">
+    <spacer flex="1"/>
+    <description id="syncDesc">
+      &weaveDesc.label;
+    </description>
+    <separator/>
+    <label class="text-link"
+           onclick="event.stopPropagation(); gSyncPane.openSetup(null);"
+           value="&setupButton.label;"/>
+    <separator/>
+    <label class="text-link"
+           onclick="event.stopPropagation(); gSyncPane.openSetup('pair');"
+           value="&pairDevice.label;"/>
+    <spacer flex="3"/>
+  </vbox>
+
+  <vbox id="hasAccount">
+    <groupbox class="syncGroupBox">
+      <!-- label is set to account name -->
+      <caption id="accountCaption" align="center">
+        <image id="accountCaptionImage"/>
+        <label id="accountName" value=""/>
+      </caption>
+
+      <hbox>
+        <button type="menu"
+                label="&manageAccount.label;"
+                accesskey="&manageAccount.accesskey;">
+          <menupopup>
+            <menuitem label="&viewQuota.label;"
+                      oncommand="gSyncPane.openQuotaDialog();"/>
+            <menuseparator/>
+            <menuitem label="&changePassword2.label;"
+                      oncommand="gSyncUtils.changePassword();"/>
+            <menuitem label="&myRecoveryKey.label;"
+                      oncommand="gSyncUtils.resetPassphrase();"/>
+            <menuseparator/>
+            <menuitem label="&resetSync2.label;"
+                      oncommand="gSyncPane.resetSync();"/>
+          </menupopup>
+        </button>
+      </hbox>
+
+      <hbox>
+        <label id="syncAddDeviceLabel"
+               class="text-link"
+               onclick="gSyncPane.openAddDevice(); return false;"
+               value="&pairDevice.label;"/>
+      </hbox>
+
+      <vbox>
+        <label value="&syncMy.label;" />
+        <richlistbox id="syncEnginesList"
+                     orient="vertical"
+                     onselect="if (this.selectedCount) this.clearSelection();">
+          <richlistitem>
+            <checkbox label="&engine.addons.label;"
+                      accesskey="&engine.addons.accesskey;"
+                      preference="engine.addons"/>
+          </richlistitem>
+          <richlistitem>
+            <checkbox label="&engine.bookmarks.label;"
+                      accesskey="&engine.bookmarks.accesskey;"
+                      preference="engine.bookmarks"/>
+          </richlistitem>
+          <richlistitem>
+            <checkbox label="&engine.passwords.label;"
+                      accesskey="&engine.passwords.accesskey;"
+                      preference="engine.passwords"/>
+          </richlistitem>
+          <richlistitem>
+            <checkbox label="&engine.prefs.label;"
+                      accesskey="&engine.prefs.accesskey;"
+                      preference="engine.prefs"/>
+          </richlistitem>
+          <richlistitem>
+            <checkbox label="&engine.history.label;"
+                      accesskey="&engine.history.accesskey;"
+                      preference="engine.history"/>
+          </richlistitem>
+          <richlistitem>
+            <checkbox label="&engine.tabs.label;"
+                      accesskey="&engine.tabs.accesskey;"
+                      preference="engine.tabs"/>
+          </richlistitem>
+        </richlistbox>
+      </vbox>
+    </groupbox>
+
+    <groupbox class="syncGroupBox">
+      <grid>
+        <columns>
+          <column/>
+          <column flex="1"/>
+        </columns>
+        <rows>
+          <row align="center">
+            <label value="&syncComputerName.label;"
+                   accesskey="&syncComputerName.accesskey;"
+                   control="syncComputerName"/>
+            <textbox id="syncComputerName"
+                     onchange="gSyncUtils.changeName(this)"/>
+          </row>
+        </rows>
+      </grid>
+      <hbox>
+        <label class="text-link"
+               onclick="gSyncPane.startOver(true); return false;"
+               value="&unlinkDevice.label;"/>
+      </hbox>
+    </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.openPrivacyPolicy();"
+             value="&prefs.ppLink.label;"/>
+    </hbox>
+  </vbox>
+
+  <vbox id="needsUpdate" align="center" pack="center">
+    <hbox>
+      <label id="loginError" value=""/>
+      <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>
+    <label class="text-link"
+           onclick="gSyncPane.startOver(true); return false;"
+           value="&unlinkDevice.label;"/>
+  </vbox>
+
+</deck>