Bug 1660129 - Add UI for changing CardDAV directory properties. r=mkmelin
I've reused some of the strings from the AB dialog, rather than making new ones, because I expect at some stage we'll either migrate all of the AB strings to Fluent or throw them away and start again. Differential Revision: https://phabricator.services.mozilla.com/D87832 --HG-- rename : mailnews/addrbook/content/abCardDAVDialog.css => mail/themes/shared/mail/cardDAV.css extra : moz-landing-system : lando
This commit is contained in:
Родитель
456da51358
Коммит
d5a474d791
|
@ -10,6 +10,7 @@ subsuite = thunderbird
|
||||||
tags = addrbook
|
tags = addrbook
|
||||||
|
|
||||||
[browser_cardDAV_init.js]
|
[browser_cardDAV_init.js]
|
||||||
|
[browser_cardDAV_properties.js]
|
||||||
[browser_cardDAV_sync.js]
|
[browser_cardDAV_sync.js]
|
||||||
[browser_contact_tree.js]
|
[browser_contact_tree.js]
|
||||||
[browser_directory_tree.js]
|
[browser_directory_tree.js]
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests CardDAV properties dialog.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { CardDAVDirectory } = ChromeUtils.import(
|
||||||
|
"resource:///modules/CardDAVDirectory.jsm"
|
||||||
|
);
|
||||||
|
const { CardDAVServer } = ChromeUtils.import(
|
||||||
|
"resource://testing-common/CardDAVServer.jsm"
|
||||||
|
);
|
||||||
|
|
||||||
|
add_task(async () => {
|
||||||
|
const INTERVAL_PREF = "ldap_2.servers.props.carddav.syncinterval";
|
||||||
|
const TOKEN_PREF = "ldap_2.servers.props.carddav.token";
|
||||||
|
const TOKEN_VALUE = "http://mochi.test/sync/0";
|
||||||
|
const URL_PREF = "ldap_2.servers.props.carddav.url";
|
||||||
|
const URL_VALUE = "https://mochi.test/carddav/test";
|
||||||
|
|
||||||
|
let dirPrefId = MailServices.ab.newAddressBook(
|
||||||
|
"props",
|
||||||
|
undefined,
|
||||||
|
Ci.nsIAbManager.CARDDAV_DIRECTORY_TYPE
|
||||||
|
);
|
||||||
|
Assert.equal(dirPrefId, "ldap_2.servers.props");
|
||||||
|
Assert.equal([...MailServices.ab.directories].length, 3);
|
||||||
|
|
||||||
|
let directory = MailServices.ab.getDirectoryFromId(dirPrefId);
|
||||||
|
let davDirectory = CardDAVDirectory.forFile(directory.fileName);
|
||||||
|
registerCleanupFunction(async () => {
|
||||||
|
let removePromise = promiseDirectoryRemoved();
|
||||||
|
MailServices.ab.deleteAddressBook(directory.URI);
|
||||||
|
await removePromise;
|
||||||
|
|
||||||
|
Assert.equal(davDirectory._syncTimer, null, "sync timer cleaned up");
|
||||||
|
});
|
||||||
|
Assert.equal(directory.dirType, Ci.nsIAbManager.CARDDAV_DIRECTORY_TYPE);
|
||||||
|
|
||||||
|
Services.prefs.setIntPref(INTERVAL_PREF, 0);
|
||||||
|
Services.prefs.setStringPref(TOKEN_PREF, TOKEN_VALUE);
|
||||||
|
Services.prefs.setStringPref(URL_PREF, URL_VALUE);
|
||||||
|
|
||||||
|
Assert.ok(davDirectory);
|
||||||
|
Assert.equal(davDirectory._serverURL, URL_VALUE);
|
||||||
|
Assert.equal(davDirectory._syncToken, TOKEN_VALUE);
|
||||||
|
Assert.equal(davDirectory._syncTimer, null, "no sync scheduled");
|
||||||
|
|
||||||
|
let abWindow = await openAddressBookWindow();
|
||||||
|
let abDocument = abWindow.document;
|
||||||
|
registerCleanupFunction(async () => {
|
||||||
|
await closeAddressBookWindow();
|
||||||
|
Services.prefs.clearUserPref("mail.addr_book.view.startupURI");
|
||||||
|
});
|
||||||
|
|
||||||
|
// This test becomes unreliable if we don't pause for a moment.
|
||||||
|
await new Promise(resolve => abWindow.setTimeout(resolve, 500));
|
||||||
|
|
||||||
|
openDirectory(directory);
|
||||||
|
|
||||||
|
Assert.equal(abWindow.gDirectoryTreeView.rowCount, 4);
|
||||||
|
Assert.equal(abWindow.gDirectoryTreeView.getIndexForId(directory.URI), 2);
|
||||||
|
Assert.equal(abWindow.gDirTree.currentIndex, 2);
|
||||||
|
|
||||||
|
let menu = abDocument.getElementById("dirTreeContext");
|
||||||
|
let menuItem = abDocument.getElementById("dirTreeContext-properties");
|
||||||
|
|
||||||
|
let subtest = async function(expectedValues, newValues, buttonAction) {
|
||||||
|
let shownPromise = BrowserTestUtils.waitForEvent(menu, "popupshown");
|
||||||
|
mailTestUtils.treeClick(EventUtils, abWindow, abWindow.gDirTree, 2, 0, {
|
||||||
|
type: "mousedown",
|
||||||
|
button: 2,
|
||||||
|
});
|
||||||
|
mailTestUtils.treeClick(EventUtils, abWindow, abWindow.gDirTree, 2, 0, {
|
||||||
|
type: "contextmenu",
|
||||||
|
});
|
||||||
|
mailTestUtils.treeClick(EventUtils, abWindow, abWindow.gDirTree, 2, 0, {
|
||||||
|
type: "mouseup",
|
||||||
|
button: 2,
|
||||||
|
});
|
||||||
|
await shownPromise;
|
||||||
|
|
||||||
|
Assert.equal(abWindow.gDirTree.currentIndex, 2);
|
||||||
|
|
||||||
|
let dialogPromise = BrowserTestUtils.promiseAlertDialog(
|
||||||
|
undefined,
|
||||||
|
"chrome://messenger/content/addressbook/abCardDAVProperties.xhtml",
|
||||||
|
async dialogWindow => {
|
||||||
|
let dialogDocument = dialogWindow.document;
|
||||||
|
|
||||||
|
let nameInput = dialogDocument.getElementById("carddav-name");
|
||||||
|
Assert.equal(nameInput.value, expectedValues.name);
|
||||||
|
if ("name" in newValues) {
|
||||||
|
nameInput.value = newValues.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
let urlInput = dialogDocument.getElementById("carddav-url");
|
||||||
|
Assert.equal(urlInput.value, expectedValues.url);
|
||||||
|
if ("url" in newValues) {
|
||||||
|
urlInput.value = newValues.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
let refreshActiveInput = dialogDocument.getElementById(
|
||||||
|
"carddav-refreshActive"
|
||||||
|
);
|
||||||
|
let refreshIntervalInput = dialogDocument.getElementById(
|
||||||
|
"carddav-refreshInterval"
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.equal(refreshActiveInput.checked, expectedValues.refreshActive);
|
||||||
|
Assert.equal(
|
||||||
|
refreshIntervalInput.disabled,
|
||||||
|
!expectedValues.refreshActive
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
"refreshActive" in newValues &&
|
||||||
|
newValues.refreshActive != expectedValues.refreshActive
|
||||||
|
) {
|
||||||
|
EventUtils.synthesizeMouseAtCenter(
|
||||||
|
refreshActiveInput,
|
||||||
|
{},
|
||||||
|
dialogWindow
|
||||||
|
);
|
||||||
|
Assert.equal(refreshIntervalInput.disabled, !newValues.refreshActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.equal(
|
||||||
|
refreshIntervalInput.value,
|
||||||
|
expectedValues.refreshInterval
|
||||||
|
);
|
||||||
|
if ("refreshInterval" in newValues) {
|
||||||
|
refreshIntervalInput.value = newValues.refreshInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogDocument
|
||||||
|
.querySelector("dialog")
|
||||||
|
.getButton(buttonAction)
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
EventUtils.synthesizeMouseAtCenter(menuItem, {}, abWindow);
|
||||||
|
await dialogPromise;
|
||||||
|
|
||||||
|
await new Promise(resolve => abWindow.setTimeout(resolve));
|
||||||
|
};
|
||||||
|
|
||||||
|
info("Open the dialog and cancel it. Nothing should change.");
|
||||||
|
await subtest(
|
||||||
|
{
|
||||||
|
name: "props",
|
||||||
|
url: URL_VALUE,
|
||||||
|
refreshActive: false,
|
||||||
|
refreshInterval: 30,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
"cancel"
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.equal(davDirectory.dirName, "props");
|
||||||
|
Assert.equal(davDirectory._serverURL, URL_VALUE);
|
||||||
|
Assert.equal(davDirectory.getIntValue("carddav.syncinterval", -1), 0);
|
||||||
|
Assert.equal(davDirectory._syncTimer, null, "no sync scheduled");
|
||||||
|
|
||||||
|
info("Open the dialog and accept it. Nothing should change.");
|
||||||
|
await subtest(
|
||||||
|
{
|
||||||
|
name: "props",
|
||||||
|
url: URL_VALUE,
|
||||||
|
refreshActive: false,
|
||||||
|
refreshInterval: 30,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
"accept"
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.equal(davDirectory.dirName, "props");
|
||||||
|
Assert.equal(davDirectory._serverURL, URL_VALUE);
|
||||||
|
Assert.equal(davDirectory.getIntValue("carddav.syncinterval", -1), 0);
|
||||||
|
Assert.equal(davDirectory._syncTimer, null, "no sync scheduled");
|
||||||
|
|
||||||
|
info("Open the dialog and change the values.");
|
||||||
|
await subtest(
|
||||||
|
{
|
||||||
|
name: "props",
|
||||||
|
url: URL_VALUE,
|
||||||
|
refreshActive: false,
|
||||||
|
refreshInterval: 30,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "CardDAV Properties Test",
|
||||||
|
refreshActive: true,
|
||||||
|
refreshInterval: 30,
|
||||||
|
},
|
||||||
|
"accept"
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.equal(davDirectory.dirName, "CardDAV Properties Test");
|
||||||
|
Assert.equal(davDirectory._serverURL, URL_VALUE);
|
||||||
|
Assert.equal(davDirectory.getIntValue("carddav.syncinterval", -1), 30);
|
||||||
|
Assert.notEqual(davDirectory._syncTimer, null, "sync scheduled");
|
||||||
|
let currentSyncTimer = davDirectory._syncTimer;
|
||||||
|
|
||||||
|
info("Open the dialog and accept it. Nothing should change.");
|
||||||
|
await subtest(
|
||||||
|
{
|
||||||
|
name: "CardDAV Properties Test",
|
||||||
|
url: URL_VALUE,
|
||||||
|
refreshActive: true,
|
||||||
|
refreshInterval: 30,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
"accept"
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.equal(davDirectory.dirName, "CardDAV Properties Test");
|
||||||
|
Assert.equal(davDirectory._serverURL, URL_VALUE);
|
||||||
|
Assert.equal(davDirectory.getIntValue("carddav.syncinterval", -1), 30);
|
||||||
|
Assert.equal(
|
||||||
|
davDirectory._syncTimer,
|
||||||
|
currentSyncTimer,
|
||||||
|
"same sync scheduled"
|
||||||
|
);
|
||||||
|
|
||||||
|
info("Open the dialog and change the interval.");
|
||||||
|
await subtest(
|
||||||
|
{
|
||||||
|
name: "CardDAV Properties Test",
|
||||||
|
url: URL_VALUE,
|
||||||
|
refreshActive: true,
|
||||||
|
refreshInterval: 30,
|
||||||
|
},
|
||||||
|
{ refreshInterval: 60 },
|
||||||
|
"accept"
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.equal(davDirectory.dirName, "CardDAV Properties Test");
|
||||||
|
Assert.equal(davDirectory._serverURL, URL_VALUE);
|
||||||
|
Assert.equal(davDirectory.getIntValue("carddav.syncinterval", -1), 60);
|
||||||
|
Assert.greater(
|
||||||
|
davDirectory._syncTimer,
|
||||||
|
currentSyncTimer,
|
||||||
|
"new sync scheduled"
|
||||||
|
);
|
||||||
|
});
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
carddav-url-label =
|
||||||
|
.value = CardDAV URL:
|
||||||
|
.accesskey = V
|
||||||
|
|
||||||
|
carddav-refreshinterval-label =
|
||||||
|
.label = Synchronize:
|
||||||
|
.accesskey = S
|
||||||
|
|
||||||
|
# Variables:
|
||||||
|
# $minutes (integer) - Number of minutes between address book synchronizations
|
||||||
|
carddav-refreshinterval-minutes-value =
|
||||||
|
.label = { $minutes ->
|
||||||
|
[one] every minute
|
||||||
|
*[other] every { $minutes } minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Variables:
|
||||||
|
# $hours (integer) - Number of hours between address book synchronizations
|
||||||
|
carddav-refreshinterval-hours-value =
|
||||||
|
.label = { $hours ->
|
||||||
|
[one] every hour
|
||||||
|
*[other] every { $hours } hours
|
||||||
|
}
|
|
@ -207,6 +207,7 @@
|
||||||
skin/classic/messenger/shared/accountManage.css (../shared/mail/accountManage.css)
|
skin/classic/messenger/shared/accountManage.css (../shared/mail/accountManage.css)
|
||||||
skin/classic/messenger/shared/accountProvisioner.css (../shared/mail/accountProvisioner.css)
|
skin/classic/messenger/shared/accountProvisioner.css (../shared/mail/accountProvisioner.css)
|
||||||
skin/classic/messenger/shared/addressbook.css (../shared/mail/addressbook.css)
|
skin/classic/messenger/shared/addressbook.css (../shared/mail/addressbook.css)
|
||||||
|
skin/classic/messenger/shared/cardDAV.css (../shared/mail/cardDAV.css)
|
||||||
skin/classic/messenger/shared/cardDialog.css (../shared/mail/cardDialog.css)
|
skin/classic/messenger/shared/cardDialog.css (../shared/mail/cardDialog.css)
|
||||||
skin/classic/messenger/shared/chat.css (../../components/im/themes/chat.css)
|
skin/classic/messenger/shared/chat.css (../../components/im/themes/chat.css)
|
||||||
skin/classic/messenger/shared/compacttheme.css (../shared/mail/compacttheme.css)
|
skin/classic/messenger/shared/compacttheme.css (../shared/mail/compacttheme.css)
|
||||||
|
|
|
@ -20,22 +20,6 @@
|
||||||
width: 30em;
|
width: 30em;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
|
||||||
font-weight: normal;
|
|
||||||
text-align: start;
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-container > * {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#carddav-provider {
|
#carddav-provider {
|
||||||
height: 1.8em;
|
height: 1.8em;
|
||||||
}
|
}
|
||||||
|
@ -85,3 +69,33 @@ th {
|
||||||
background-size: 16px 16px;
|
background-size: 16px 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#carddav-properties-table {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content auto;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container > * {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#carddav-refreshActive-cell {
|
||||||
|
/* This shouldn't be necessary, but there's no good combination of checkbox
|
||||||
|
* and label that play nicely with the align-items: baseline above. */
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#carddav-refreshInterval-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#carddav-refreshInterval {
|
||||||
|
flex: 1;
|
||||||
|
margin: 2px 4px;
|
||||||
|
}
|
|
@ -64,7 +64,10 @@ function abNameOKButton(event) {
|
||||||
let newDirName = gNameInput.value.trim();
|
let newDirName = gNameInput.value.trim();
|
||||||
|
|
||||||
// Do not allow an already existing name.
|
// Do not allow an already existing name.
|
||||||
if (MailServices.ab.directoryNameExists(newDirName)) {
|
if (
|
||||||
|
MailServices.ab.directoryNameExists(newDirName) &&
|
||||||
|
(!gDirectory || newDirName != gDirectory.dirName)
|
||||||
|
) {
|
||||||
const kAlertTitle = document
|
const kAlertTitle = document
|
||||||
.getElementById("bundle_addressBook")
|
.getElementById("bundle_addressBook")
|
||||||
.getString("duplicateNameTitle");
|
.getString("duplicateNameTitle");
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
- file, you can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, you can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
|
||||||
<?xml-stylesheet href="chrome://messenger/skin/dialogs.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://messenger/skin/dialogs.css" type="text/css"?>
|
||||||
<?xml-stylesheet href="chrome://messenger/skin/menulist.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://messenger/skin/shared/cardDAV.css" type="text/css"?>
|
||||||
<?xml-stylesheet href="chrome://messenger/content/addressbook/abCardDAVDialog.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://messenger/skin/input-fields.css" type="text/css"?>
|
||||||
<?xml-stylesheet href="chrome://messenger/skin/themeableDialog.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://messenger/skin/themeableDialog.css" type="text/css"?>
|
||||||
|
|
||||||
<window data-l10n-id="carddav-window"
|
<window data-l10n-id="carddav-window"
|
||||||
|
@ -34,34 +34,29 @@
|
||||||
<description data-l10n-id="carddav-experimental-warning"/>
|
<description data-l10n-id="carddav-experimental-warning"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
<html:table>
|
<html:div id="carddav-properties-table">
|
||||||
<html:tr hidden="hidden">
|
<!-- <html:div>
|
||||||
<html:th>
|
|
||||||
<label control="carddav-provider"
|
<label control="carddav-provider"
|
||||||
data-l10n-id="carddav-provider-label"
|
data-l10n-id="carddav-provider-label"
|
||||||
data-l10n-attrs="value,accesskey"/>
|
data-l10n-attrs="value,accesskey"/>
|
||||||
</html:th>
|
</html:div>
|
||||||
<html:td class="input-container">
|
<html:div class="input-container">
|
||||||
<html:select id="carddav-provider" onchange="handleChangeProvider(event);">
|
<html:select id="carddav-provider" onchange="handleChangeProvider(event);">
|
||||||
</html:select>
|
</html:select>
|
||||||
</html:td>
|
</html:div> -->
|
||||||
</html:tr>
|
<html:div>
|
||||||
<html:tr>
|
|
||||||
<html:th>
|
|
||||||
<label control="carddav-url"
|
<label control="carddav-url"
|
||||||
data-l10n-id="carddav-url-label"
|
data-l10n-id="carddav-url-label"
|
||||||
data-l10n-attrs="value,accesskey"/>
|
data-l10n-attrs="value,accesskey"/>
|
||||||
</html:th>
|
</html:div>
|
||||||
|
<html:div class="input-container">
|
||||||
<html:td class="input-container">
|
|
||||||
<html:input id="carddav-url" type="url"
|
<html:input id="carddav-url" type="url"
|
||||||
placeholder="https://carddav.example.com/"
|
placeholder="https://carddav.example.com/"
|
||||||
required="required"
|
required="required"
|
||||||
onblur="handleCardDAVURLBlur(event);"
|
onblur="handleCardDAVURLBlur(event);"
|
||||||
oninput="handleCardDAVURLInput(event);"/>
|
oninput="handleCardDAVURLInput(event);"/>
|
||||||
</html:td>
|
</html:div>
|
||||||
</html:tr>
|
</html:div>
|
||||||
</html:table>
|
|
||||||
|
|
||||||
<vbox id="carddav-statusArea"
|
<vbox id="carddav-statusArea"
|
||||||
align="center"
|
align="center"
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
var { MailServices } = ChromeUtils.import(
|
||||||
|
"resource:///modules/MailServices.jsm"
|
||||||
|
);
|
||||||
|
|
||||||
|
var gDirectory = window.arguments[0].selectedDirectory;
|
||||||
|
var gStringBundle,
|
||||||
|
gNameInput,
|
||||||
|
gURLInput,
|
||||||
|
gRefreshActiveInput,
|
||||||
|
gRefreshMenulist,
|
||||||
|
gAcceptButton;
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
"DOMContentLoaded",
|
||||||
|
() => {
|
||||||
|
gStringBundle = Services.strings.createBundle(
|
||||||
|
"chrome://messenger/locale/addressbook/addressBook.properties"
|
||||||
|
);
|
||||||
|
document.title = gStringBundle.formatStringFromName(
|
||||||
|
"addressBookTitleEdit",
|
||||||
|
[gDirectory.dirName]
|
||||||
|
);
|
||||||
|
|
||||||
|
gNameInput = document.getElementById("carddav-name");
|
||||||
|
gNameInput.value = gDirectory.dirName;
|
||||||
|
gNameInput.addEventListener("input", () => {
|
||||||
|
gAcceptButton.disabled = gNameInput.value.trim() == "";
|
||||||
|
});
|
||||||
|
|
||||||
|
gURLInput = document.getElementById("carddav-url");
|
||||||
|
gURLInput.value = gDirectory.getStringValue("carddav.url", "");
|
||||||
|
|
||||||
|
gRefreshActiveInput = document.getElementById("carddav-refreshActive");
|
||||||
|
gRefreshActiveInput.addEventListener(
|
||||||
|
"command",
|
||||||
|
() => (gRefreshMenulist.disabled = !gRefreshActiveInput.checked)
|
||||||
|
);
|
||||||
|
|
||||||
|
gRefreshMenulist = document.getElementById("carddav-refreshInterval");
|
||||||
|
initRefreshInterval();
|
||||||
|
|
||||||
|
gAcceptButton = document.querySelector("dialog").getButton("accept");
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
window.addEventListener("dialogaccept", event => {
|
||||||
|
let newDirName = gNameInput.value.trim();
|
||||||
|
let newSyncInterval = gRefreshActiveInput.checked
|
||||||
|
? gRefreshMenulist.value
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
if (newDirName != gDirectory.dirName) {
|
||||||
|
// Do not allow an already existing name.
|
||||||
|
if (MailServices.ab.directoryNameExists(newDirName)) {
|
||||||
|
let alertTitle = gStringBundle.GetStringFromName("duplicateNameTitle");
|
||||||
|
let alertText = gStringBundle.formatStringFromName("duplicateNameText", [
|
||||||
|
newDirName,
|
||||||
|
]);
|
||||||
|
Services.prompt.alert(window, alertTitle, alertText);
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gDirectory.dirName = newDirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSyncInterval != gDirectory.getIntValue("carddav.syncinterval", -1)) {
|
||||||
|
gDirectory.setIntValue("carddav.syncinterval", newSyncInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function initRefreshInterval() {
|
||||||
|
function createMenuItem(minutes) {
|
||||||
|
let menuitem = document.createXULElement("menuitem");
|
||||||
|
menuitem.setAttribute("value", minutes);
|
||||||
|
menuitem.setAttribute("data-l10n-attrs", "label");
|
||||||
|
if (minutes < 60) {
|
||||||
|
document.l10n.setAttributes(
|
||||||
|
menuitem,
|
||||||
|
"carddav-refreshinterval-minutes-value",
|
||||||
|
{
|
||||||
|
minutes,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
document.l10n.setAttributes(
|
||||||
|
menuitem,
|
||||||
|
"carddav-refreshinterval-hours-value",
|
||||||
|
{
|
||||||
|
hours: minutes / 60,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
gRefreshMenulist.menupopup.appendChild(menuitem);
|
||||||
|
if (refreshInterval == minutes) {
|
||||||
|
gRefreshMenulist.value = minutes;
|
||||||
|
foundValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return menuitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
let refreshInterval = gDirectory.getIntValue("carddav.syncinterval", 30);
|
||||||
|
if (refreshInterval === null) {
|
||||||
|
refreshInterval = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
let foundValue = false;
|
||||||
|
|
||||||
|
for (let min of [1, 5, 15, 30, 60, 120, 240, 360, 720, 1440]) {
|
||||||
|
createMenuItem(min);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshInterval == 0) {
|
||||||
|
gRefreshMenulist.value = 30; // The default.
|
||||||
|
gRefreshMenulist.disabled = true;
|
||||||
|
foundValue = true;
|
||||||
|
} else {
|
||||||
|
gRefreshActiveInput.checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundValue) {
|
||||||
|
// Special menuitem in case the user changed the value in the config editor.
|
||||||
|
createMenuItem(refreshInterval);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- 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/. -->
|
||||||
|
|
||||||
|
<?xml-stylesheet href="chrome://messenger/skin/dialogs.css" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://messenger/skin/shared/cardDAV.css" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://messenger/skin/input-fields.css" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://messenger/skin/themeableDialog.css" type="text/css"?>
|
||||||
|
|
||||||
|
<!DOCTYPE window SYSTEM "chrome://messenger/locale/addressbook/abAddressBookNameDialog.dtd">
|
||||||
|
|
||||||
|
<window minwidth="500"
|
||||||
|
lightweightthemes="true"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<dialog id="carddav-properties-dialog">
|
||||||
|
|
||||||
|
<linkset>
|
||||||
|
<html:link rel="localization" href="messenger/addressbook/abCardDAVProperties.ftl"/>
|
||||||
|
</linkset>
|
||||||
|
|
||||||
|
<script src="chrome://global/content/globalOverlay.js"/>
|
||||||
|
<script src="chrome://global/content/editMenuOverlay.js"/>
|
||||||
|
<script src="chrome://messenger/content/addressbook/abCardDAVProperties.js"/>
|
||||||
|
<script src="chrome://messenger/content/dialogShadowDom.js"/>
|
||||||
|
|
||||||
|
<div id="carddav-properties-table"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<div>
|
||||||
|
<xul:label control="carddav-name"
|
||||||
|
value="&name.label;"
|
||||||
|
accesskey="&name.accesskey;"/>
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
<input id="carddav-name"
|
||||||
|
type="text"
|
||||||
|
class="input-inline"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<xul:label data-l10n-id="carddav-url-label"
|
||||||
|
data-l10n-attrs="value,accesskey"
|
||||||
|
control="carddav-url"/>
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
<input id="carddav-url"
|
||||||
|
type="url"
|
||||||
|
class="input-inline"
|
||||||
|
readonly="readonly"/>
|
||||||
|
</div>
|
||||||
|
<div id="carddav-refreshActive-cell">
|
||||||
|
<xul:checkbox id="carddav-refreshActive"
|
||||||
|
data-l10n-id="carddav-refreshinterval-label"
|
||||||
|
data-l10n-attrs="label,accesskey"
|
||||||
|
control="carddav-refreshInterval"/>
|
||||||
|
</div>
|
||||||
|
<div id="carddav-refreshInterval-cell">
|
||||||
|
<xul:menulist id="carddav-refreshInterval">
|
||||||
|
<xul:menupopup>
|
||||||
|
<!-- This will be filled programmatically to reduce the number of needed strings -->
|
||||||
|
</xul:menupopup>
|
||||||
|
</xul:menulist>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
</window>
|
|
@ -42,6 +42,9 @@ class CardDAVDirectory extends AddrBookDirectory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get propertiesChromeURI() {
|
||||||
|
return "chrome://messenger/content/addressbook/abCardDAVProperties.xhtml";
|
||||||
|
}
|
||||||
get dirType() {
|
get dirType() {
|
||||||
return Ci.nsIAbManager.CARDDAV_DIRECTORY_TYPE;
|
return Ci.nsIAbManager.CARDDAV_DIRECTORY_TYPE;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +117,14 @@ class CardDAVDirectory extends AddrBookDirectory {
|
||||||
Cr.NS_ERROR_NOT_IMPLEMENTED
|
Cr.NS_ERROR_NOT_IMPLEMENTED
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
setIntValue(name, value) {
|
||||||
|
super.setIntValue(name, value);
|
||||||
|
|
||||||
|
// Capture changes to the sync interval from the UI.
|
||||||
|
if (name == "carddav.syncinterval") {
|
||||||
|
this._scheduleNextSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** CardDAV specific */
|
/** CardDAV specific */
|
||||||
_syncInProgress = false;
|
_syncInProgress = false;
|
||||||
|
|
|
@ -9,9 +9,10 @@ messenger.jar:
|
||||||
content/messenger/addressbook/pref-editdirectories.xhtml (addrbook/prefs/content/pref-editdirectories.xhtml)
|
content/messenger/addressbook/pref-editdirectories.xhtml (addrbook/prefs/content/pref-editdirectories.xhtml)
|
||||||
content/messenger/addressbook/abAddressBookNameDialog.js (addrbook/content/abAddressBookNameDialog.js)
|
content/messenger/addressbook/abAddressBookNameDialog.js (addrbook/content/abAddressBookNameDialog.js)
|
||||||
content/messenger/addressbook/abAddressBookNameDialog.xhtml (addrbook/content/abAddressBookNameDialog.xhtml)
|
content/messenger/addressbook/abAddressBookNameDialog.xhtml (addrbook/content/abAddressBookNameDialog.xhtml)
|
||||||
content/messenger/addressbook/abCardDAVDialog.css (addrbook/content/abCardDAVDialog.css)
|
|
||||||
content/messenger/addressbook/abCardDAVDialog.js (addrbook/content/abCardDAVDialog.js)
|
content/messenger/addressbook/abCardDAVDialog.js (addrbook/content/abCardDAVDialog.js)
|
||||||
content/messenger/addressbook/abCardDAVDialog.xhtml (addrbook/content/abCardDAVDialog.xhtml)
|
content/messenger/addressbook/abCardDAVDialog.xhtml (addrbook/content/abCardDAVDialog.xhtml)
|
||||||
|
content/messenger/addressbook/abCardDAVProperties.js (addrbook/content/abCardDAVProperties.js)
|
||||||
|
content/messenger/addressbook/abCardDAVProperties.xhtml (addrbook/content/abCardDAVProperties.xhtml)
|
||||||
content/messenger/addressbook/abResultsPane.js (addrbook/content/abResultsPane.js)
|
content/messenger/addressbook/abResultsPane.js (addrbook/content/abResultsPane.js)
|
||||||
content/messenger/addressbook/abDragDrop.js (addrbook/content/abDragDrop.js)
|
content/messenger/addressbook/abDragDrop.js (addrbook/content/abDragDrop.js)
|
||||||
content/messenger/addressbook/abMailListDialog.js (addrbook/content/abMailListDialog.js)
|
content/messenger/addressbook/abMailListDialog.js (addrbook/content/abMailListDialog.js)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче