Commit a2fa6c3a authored by Christoph Goehre's avatar Christoph Goehre
Browse files

Merge branch 'upstream' into dfsg-upstream

parents 043dfb4d a0ad4cd5
......@@ -11,7 +11,7 @@
<Description>
<!-- thunderbird -->
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
<em:minVersion>3.1</em:minVersion>
<em:minVersion>3.1pre</em:minVersion>
<em:maxVersion>3.1.*</em:maxVersion>
</Description>
</em:targetApplication>
......
......@@ -926,7 +926,7 @@ let gFolderTreeView = {
{
for each (child in fixIterator(folder.subFolders, Components.interfaces.nsIMsgFolder)) {
// if the folder selection is based on a string propery, use that
if (aFolderName == child.getStringProperty("smartFolderName")) {
if (aFolderName == getSmartFolderName(child)) {
folders.push(child);
// Add sub-folders if requested.
if (deep)
......@@ -1485,7 +1485,6 @@ let gFolderTreeView = {
}
return null;
},
/**
* check to see if a folder is a smart folder
*/
......@@ -1495,7 +1494,7 @@ let gFolderTreeView = {
// Also check the folder name itself, as containers do not
// have the smartFolderName property. We check all folders here, since
// a "real" folder might be marked as a child of a smart folder.
let smartFolderName = aFolder.getStringProperty("smartFolderName");
let smartFolderName = getSmartFolderName(aFolder);
return smartFolderName && this.getSmartFolderTypeByName(smartFolderName) ||
this.getSmartFolderTypeByName(aFolder.name);
},
......@@ -1523,7 +1522,7 @@ let gFolderTreeView = {
* special folder, else returns null.
*/
_getSmartFolderType: function ftv_smart__getSmartFolderType(aFolder) {
let smartFolderName = aFolder.getStringProperty("smartFolderName");
let smartFolderName = getSmartFolderName(aFolder);
for each (let [, type] in Iterator(this._flagNameList)) {
if (smartFolderName) {
if (type[1] == smartFolderName)
......@@ -1960,7 +1959,7 @@ ftvItem.prototype = {
.getAtom("specialFolder-"+this._folder.name.replace(' ','')));
}
// if there is a smartFolder name property, add it
let smartFolderName = this._folder.getStringProperty("smartFolderName");
let smartFolderName = getSmartFolderName(this._folder);
if (smartFolderName) {
aProps.AppendElement(Components.classes["@mozilla.org/atom-service;1"]
.getService(Components.interfaces.nsIAtomService)
......@@ -2429,6 +2428,15 @@ function sortFolderItems (aFtvItems) {
aFtvItems.sort(sorter);
}
function getSmartFolderName(aFolder) {
try {
return aFolder.getStringProperty("smartFolderName");
} catch (ex) {
Components.utils.reportError(ex);
return null;
}
}
/**
* Create a subtype - maybe this wants to be in a shared .jsm file somewhere.
*/
......
......@@ -228,17 +228,21 @@ function MailToolboxCustomizeDone(aEvent, customizePopupId)
if (this.UpdateMailToolbar != undefined)
UpdateMailToolbar(focus);
document.getElementById("header-view-toolbox").removeAttribute("doCustomization");
// The GetMail button is stuck in a strange state right now, since the
// customization wrapping preserves its children, but not its initialized
// state. Fix that here.
if (document.getElementById("button-getmsg")) {
// We can't use _teardown here, because it'll remove the Get All menuitem
let popup = document.getElementById("button-getMsgPopup");
let sep = document.getElementById("button-getAllNewMsgSeparator");
while (popup.lastChild != sep)
popup.removeChild(popup.lastChild);
var toolbox = document.getElementsByAttribute("doCustomization", "true")[0];
if (toolbox) {
toolbox.removeAttribute("doCustomization");
// The GetMail button is stuck in a strange state right now, since the
// customization wrapping preserves its children, but not its initialized
// state. Fix that here.
// Fix Bug 565045: Only treat "Get Message Button" if it is in our toolbox
var popup = toolbox.getElementsByAttribute("id", "button-getMsgPopup")[0];
if (popup) {
// We can't use _teardown here, because it'll remove the Get All menuitem
let sep = toolbox.getElementsByAttribute("id", "button-getAllNewMsgSeparator")[0];
while (popup.lastChild != sep)
popup.removeChild(popup.lastChild);
}
}
UpdateJunkButton();
UpdateReplyButtons();
......
......@@ -251,10 +251,6 @@
<constructor>
<![CDATA[
this.mAddresses = new Array;
this.maxLinesBeforeMore = Application.prefs.getValue(
"mailnews.headers.show_n_lines_before_more",
this.maxLinesBeforeMore);
]]>
</constructor>
......@@ -310,6 +306,11 @@
</body>
</method>
<!-- This field is used to buffer the width of the comma node so that
it only has to be determined once during the lifetime of this
widget. Otherwise it would cause an expensive reflow every time. -->
<field name="commaNodeWidth">0</field>
<!-- fillAddressesNode: private method used to create email address
nodes for either our short or long view.
@param aAddressesNode {DOMElement}: the div to add addresses too
......@@ -332,9 +333,12 @@
for (let node = aAddressesNode; node; node = node.parentNode)
node.collapsed = false;
// this ensures that the worst-case "n more" width is considered
this.addNMore(this.mAddresses.length);
var availableWidth = aAddressesNode.clientWidth;
this.more.collapsed = true;
// add addresses until we're done, or we overflow this line
// add addresses until we're done, or we overflow the allowed lines
var i = 0;
for (let curLine = 0, curLineWidth = 0;
i < this.mAddresses.length && (all || curLine < this.maxLinesBeforeMore);
......@@ -346,8 +350,11 @@
if (i > 0) {
if (cached-- > 0)
aAddressesNode.childNodes[i*2 - 1].hidden = false;
else
else {
this.appendComma();
if (this.commaNodeWidth == 0)
this.commaNodeWidth = this.emailAddresses.lastChild.clientWidth;
}
}
// Now add an email address.
......@@ -370,13 +377,27 @@
// (X more).
if (!all) {
// Calculate width and lines
// Calculate width and lines, consider the i+1 comma node if we have to
// <http://www.w3.org/TR/cssom-view/#client-attributes>
// <https://developer.mozilla.org/en/Determining_the_dimensions_of_elements>
curLineWidth += newAddressNode.clientWidth;
if (curLineWidth > availableWidth && i > 0) {
let newLineWidth = i+1 < this.mAddresses.length ?
newAddressNode.clientWidth + this.commaNodeWidth:
newAddressNode.clientWidth;
curLineWidth += newLineWidth;
let overLineWidth = curLineWidth - availableWidth;
if (overLineWidth > 0 && i > 0) {
curLine++;
curLineWidth = 0;
curLineWidth = newLineWidth;
}
// hide the last node spanning into the additional line (n>1)
// also hide it if <30px left after sliding the address (n=1)
if (curLine >= this.maxLinesBeforeMore &&
(this.maxLinesBeforeMore > 1 ||
newLineWidth - overLineWidth < 30)) {
aAddressesNode.lastChild.hidden = true;
i--;
}
}
}
......@@ -420,13 +441,23 @@
<field name="maxLinesBeforeMore">1</field>
<!-- Public method to build the DOM nodes for display, to be called
after all the addresses have been added to the widget. Displays at
most maxAddressesBeforeMore addresses plus a (more) widget which
can be clicked to reveal the rest. -->
after all the addresses have been added to the widget. It uses
fillAddressesNode to display at most maxLinesBeforeMore lines of
addresses plus the (more) widget which can be clicked to reveal
the rest. The "singleline" attribute is set for one line only. -->
<method name="buildViews">
<body>
<![CDATA[
this.fillAddressesNode(this.emailAddresses, false);
this.maxLinesBeforeMore = Application.prefs.getValue(
"mailnews.headers.show_n_lines_before_more",
this.maxLinesBeforeMore);
this.fillAddressesNode(this.emailAddresses,
this.maxLinesBeforeMore < 1);
// force a single line only in the default n=1 case
if (this.maxLinesBeforeMore != 1)
this.longEmailAddresses.removeAttribute("singleline");
]]>
</body>
</method>
......
......@@ -1052,7 +1052,7 @@
<menuseparator id="editMenuAfterSelectSeparator"/>
<menu id="menu_find" label="&findMenu.label;" accesskey="&findMenu.accesskey;">
<menupopup id="menu_FindPopup">
<menuitem id="menu_findCmd" label="&findCmd.label;" key="key_findAgain" accesskey="&findCmd.accesskey;" command="cmd_find"/>
<menuitem id="menu_findCmd" label="&findCmd.label;" key="key_find" accesskey="&findCmd.accesskey;" command="cmd_find"/>
<menuitem id="menu_findAgainCmd" label="&findAgainCmd.label;" key="key_findAgain" accesskey="&findAgainCmd.accesskey;" command="cmd_findAgain"/>
<menuseparator id="editMenuAfterFindSeparator"/>
<menuitem id="searchMailCmd" label="&searchMailCmd.label;"
......
......@@ -86,6 +86,11 @@ var sessionStoreManager =
*/
_shutdownStateSaved: false,
/**
* This is called on startup, and when a new 3 pane window is opened after
* the last 3 pane window was closed (e.g., on the mac, closing the last
* window doesn't shut down the app).
*/
_init: function ssm_init()
{
this._loadSessionFile();
......@@ -116,6 +121,9 @@ var sessionStoreManager =
// delete the file in case there is something crash-inducing about
// the restoration process
sessionFile.remove(false);
// clear the current state so that subsequent writes won't think
// the state hasn't changed.
this._currentStateString = null;
if (data) {
try {
......@@ -238,14 +246,15 @@ var sessionStoreManager =
*/
loadingWindow: function ssm_loadingWindow(aWindow)
{
let firstWindow = !this._initialized;
let firstWindow = !this._initialized || this._shutdownStateSaved;
if (firstWindow)
this._init();
// If we are seeing a new 3-pane, we are obviously not in a shutdown
// state anymore. (This would happen if all the 3panes got closed but
// we did not quit because another window was open and then a 3pane showed
// up again. This can happen in both unit tests and real life.)
// We treat this case like the first window case, and do a session restore.
this._shutdownStateSaved = false;
let windowState = null;
......
......@@ -116,12 +116,10 @@ APP_NAME = $(MOZ_APP_DISPLAYNAME)
ifdef MOZ_DEBUG
APP_NAME := $(APP_NAME)Debug
endif
PROGRAM_LOCATION = ../../../$(DIST)/$(APP_NAME).app/Contents/MacOS/
PROGRAM = $(PROGRAM_LOCATION)thunderbird-bin$(BIN_SUFFIX)
PROGRAM = ../../../$(DIST)/$(APP_NAME).app/
else
# Non-mac options
PROGRAM_LOCATION = ../../../$(DIST)/bin/
PROGRAM = $(PROGRAM_LOCATION)thunderbird$(BIN_SUFFIX)
PROGRAM = ../../../$(DIST)/bin/thunderbird$(BIN_SUFFIX)
endif
mozmill::
......
......@@ -65,10 +65,6 @@ Var PageName
; are a member of the Administrators group.
!define NONADMIN_ELEVATE
; Don't use the PreDirectoryCommon macro's code for finding a pre-existing
; installation directory.
!define NO_INSTDIR_PREDIRCOMMON
; Disabled until a survey url is provided
!define AbortSurveyURL "http://live.mozillamessaging.com/survey/cancel/?page="
......@@ -103,7 +99,6 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
!insertmacro _LoggingShortcutsCommon
!insertmacro AddHandlerValues
!insertmacro CanWriteToInstallDir
!insertmacro ChangeMUIHeaderImage
!insertmacro CheckForFilesInUse
!insertmacro CleanUpdatesDir
......@@ -128,6 +123,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
!insertmacro InstallOnInitCommon
!insertmacro InstallStartCleanupCommon
!insertmacro LeaveDirectoryCommon
!insertmacro LeaveOptionsCommon
!insertmacro OnEndCommon
!insertmacro PreDirectoryCommon
......@@ -481,8 +477,6 @@ Section "-InstallEndCleanup"
${EndIf}
${EndUnless}
${LogHeader} "Updating Uninstall Log With Previous Uninstall Log"
; Refresh desktop icons
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"
......@@ -717,37 +711,10 @@ Function leaveOptions
StrCmp $R0 "1" +1 +2
StrCpy $InstallType ${INSTALLTYPE_CUSTOM}
!ifndef NO_INSTDIR_FROM_REG
SetShellVarContext all ; Set SHCTX to HKLM
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
StrCmp "$R9" "false" +1 fix_install_dir
SetShellVarContext current ; Set SHCTX to HKCU
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
fix_install_dir:
StrCmp "$R9" "false" +2 +1
StrCpy $INSTDIR "$R9"
!endif
${LeaveOptionsCommon}
; If the user doesn't have write access to the installation directory set
; the installation directory to a subdirectory of the All Users application
; directory and if the user can't write to that location set the installation
; directory to a subdirectory of the users local application directory
; (e.g. non-roaming).
${CanWriteToInstallDir} $R8
${If} "$R8" == "false"
SetShellVarContext all ; Set SHCTX to All Users
StrCpy $INSTDIR "$APPDATA\${BrandFullName}\"
${If} ${FileExists} "$INSTDIR"
; Always display the long path if the path already exists.
${GetLongPath} "$INSTDIR" $INSTDIR
${EndIf}
${CanWriteToInstallDir} $R8
${If} "$R8" == "false"
StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\"
${EndIf}
${If} $InstallType == ${INSTALLTYPE_BASIC}
Call CheckExistingInstall
${EndIf}
FunctionEnd
......@@ -757,10 +724,10 @@ Function preDirectory
FunctionEnd
Function leaveDirectory
${LeaveDirectoryCommon} "$(WARN_DISK_SPACE)" "$(WARN_WRITE_ACCESS)"
${If} $InstallType != ${INSTALLTYPE_CUSTOM}
${If} $InstallType == ${INSTALLTYPE_BASIC}
Call CheckExistingInstall
${EndIf}
${LeaveDirectoryCommon} "$(WARN_DISK_SPACE)" "$(WARN_WRITE_ACCESS)"
FunctionEnd
Function preShortcuts
......@@ -778,6 +745,13 @@ Function leaveShortcuts
${MUI_INSTALLOPTIONS_READ} $AddDesktopSC "shortcuts.ini" "Field 2" "State"
${MUI_INSTALLOPTIONS_READ} $AddStartMenuSC "shortcuts.ini" "Field 3" "State"
${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State"
; If Start Menu shortcuts won't be created call CheckExistingInstall here
; since leaveStartMenu will not be called.
${If} $AddStartMenuSC != 1
${AndIf} $InstallType == ${INSTALLTYPE_CUSTOM}
Call CheckExistingInstall
${EndIf}
FunctionEnd
Function preStartMenu
......
......@@ -17,6 +17,7 @@ fi
fr
fy-NL
ga-IE
gd
gl
he
hu
......
......@@ -38,7 +38,7 @@
var MODULE_NAME = "test-mail-account-setup-wizard";
var RELATIVE_ROOT = "../shared-modules";
var MODULE_REQUIRES = ["window-helpers"];
var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
var mozmill = {};
Components.utils.import("resource://mozmill/modules/mozmill.js", mozmill);
......@@ -47,18 +47,21 @@ Components.utils.import("resource://mozmill/modules/controller.js", controller);
var elib = {};
Components.utils.import("resource://mozmill/modules/elementslib.js", elib);
var wh, mc, awc, account, incoming, outgoing;
var wh, awc, account, incoming, outgoing;
var user = {
name: "Yamato Nadeshiko",
email: "yamato.nadeshiko@example.com",
password: "abc12345"
password: "abc12345",
incomingHost: "testin.example.com",
outgoingHost: "testout.example.com",
};
function setupModule(module) {
wh = collector.getModule("window-helpers");
mc = wh.wait_for_existing_window("mail:3pane");
wh.installInto(module);
fdh = collector.getModule("folder-display-helpers");
fdh.installInto(module);
}
// Select File > New > Mail Account to open the Mail Account Setup Wizard
......@@ -161,11 +164,11 @@ function subtest_verify_account(amc) {
},
"incoming server hostname": {
// Note: N in the hostName is uppercase
actual: incoming.hostName, expected: "pop.example.com"
actual: incoming.hostName, expected: user.incomingHost
},
"outgoing server hostname": {
// And this is lowercase
actual: outgoing.hostname, expected: "smtp.example.com"
actual: outgoing.hostname, expected: user.outgoingHost
},
"user real name": { actual: identity.fullName, expected: user.name },
"user email address": { actual: identity.email, expected: user.email }
......@@ -186,3 +189,56 @@ function subtest_verify_account(amc) {
throw new Error("Configured " + i + " is " + config[i].actual +
". It should be " + config[i].expected + ".");
}
/**
* Make sure that we don't re-set the information we get from the config
* file if the password is incorrect.
**/
function test_bad_password_uses_old_settings() {
// Set the pref to load a local autoconfig file.
let pref = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
let pref_name = "mailnews.auto_config_url";
let url = collector.addHttpResource("../account/xml", "autoconfig");
try {
pref.setCharPref(pref_name, url);
// Force .com MIME-Type to text/xml
collector.httpd.registerContentType("com", "text/xml");
mc.sleep(0);
awc = open_mail_account_setup_wizard();
// Input user's account information
awc.e("realname").focus();
input_value(user.name);
awc.keypress(null, "VK_TAB", {});
input_value(user.email);
awc.keypress(null, "VK_TAB", {});
input_value(user.password);
// Load the autoconfig file from http://localhost:433**/autoconfig/example.com
awc.e("next_button").click();
let config = null;
awc.waitForEval("subject.disabled == false", 8000, 600,
awc.e("create_button"));
awc.e("create_button").click();
awc.waitForEval("subject.disabled == false", 8000, 600,
awc.e("create_button"));
awc.e("create_button").click();
// Make sure all the values are the same as in the user object.
awc.sleep(1000);
assert_equals(awc.e("outgoing_server").value, user.outgoingHost,
"Outgoing server changed!");
assert_equals(awc.e("incoming_server").value, user.incomingHost,
"incoming server changed!");
}
finally {
// Clean up
pref.clearUserPref(pref_name);
awc.e("cancel_button").click();;
}
}
......@@ -5,14 +5,14 @@
<displayName>Example</displayName>
<displayShortName>Example</displayShortName>
<incomingServer type="pop3">
<hostname>pop.%EMAILDOMAIN%</hostname>
<hostname>testin.%EMAILDOMAIN%</hostname>
<port>995</port>
<socketType>SSL</socketType>
<username>%EMAILLOCALPART%</username>
<authentication>plain</authentication>
</incomingServer>
<outgoingServer type="smtp">
<hostname>smtp.%EMAILDOMAIN%</hostname>
<hostname>testout.%EMAILDOMAIN%</hostname>
<port>587</port>
<socketType>STARTTLS</socketType>
<username>%EMAILADDRESS%</username>
......
......@@ -141,11 +141,7 @@ function testHTMLComposeWindowSwitchSignatures() {
// class="moz-signature".
assert_equals(node.className, "moz-signature")
node = node.firstChild; // text node containing the signature divider
assert_equals(node.nodeValue, "-- ");
node = node.nextSibling;
assert_equals(node.localName, "br");
node = node.nextSibling;
assert_equals(node.nodeValue, "Tinderbox is soo 90ies");
assert_equals(node.nodeValue, "-- \nTinderbox is soo 90ies");
// Now switch identities!
let menuID = cwc.e("msgIdentity");
......
......@@ -294,9 +294,9 @@ function test_that_msg_without_date_clears_previous_headers() {
* Test various aspects of the (n more) widgetry.
*/
function test_more_widget() {
// generate message with 20 recips (effectively guarantees overflow)
// generate message with 35 recips (effectively guarantees overflow for n=3)
be_in_folder(folder);
let msg = create_message({toCount: 20});
let msg = create_message({toCount: 35});
// add the message to the end of the folder
add_message_to_folder(folder, msg);
......@@ -366,8 +366,9 @@ function subtest_more_widget_display(toDescription) {
let maxLines = prefBranch.getIntPref(
"mailnews.headers.show_n_lines_before_more");
if (numLines > maxLines) {
throw new Error("expected <= " + maxLines + "lines; found " + numLines);
// allow for a 15% tolerance for any padding that may be applied
if (numLines < 0.85*maxLines || numLines > 1.15*maxLines) {
throw new Error("expected == " + maxLines + "lines; found " + numLines);
}
// test that we've got a (more) node and that it's expanded
......@@ -427,10 +428,10 @@ function subtest_more_widget_star_click(toDescription) {
/**
* Make sure the (more) widget hidden pref actually works with a
* non-default value.
*/
*/
function test_more_widget_with_maxlines_of_3(){
// set maxLines to 2
// set maxLines to 3
let prefBranch = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService).getBranch(null);
let maxLines = prefBranch.setIntPref(
......@@ -440,6 +441,49 @@ function test_more_widget_with_maxlines_of_3(){
test_more_widget();
}
/**
* Make sure the (more) widget hidden pref also works with an
* "all" (0) non-default value.
*/
function test_more_widget_with_disabled_more(){
// set maxLines to 0
let prefBranch = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService).getBranch(null);
let maxLines = prefBranch.setIntPref(
"mailnews.headers.show_n_lines_before_more", 0);
// generate message with 35 recips (effectively guarantees overflow for n=3)
be_in_folder(folder);
let msg = create_message({toCount: 35});
// add the message to the end of the folder
add_message_to_folder(folder, msg);
// select and open the last message
let curMessage = select_click_row(-1);
// make sure it loads
wait_for_message_display_completion(mc);
assert_selected_and_displayed(mc, curMessage);
// test that (n more) is gone
let moreNode = mc.a('expandedtoBox', {class: 'moreIndicator'});
if (!moreNode.collapsed) {
throw new Error("more node should be collapsed in n=0 case");
}
// get the description element containing the addresses
let toDescription = mc.a('expandedtoBox', {class: "headerValue"});
// test that we actually have more lines than the 3 we know are filled
let newNumLines = help_get_num_lines(toDescription);
if (newNumLines <= 3) {
throw new Error("number of address lines present in all addresses mode = " +
newNumLines + "<= number of expected minimum of 3 lines filled");
}
}