Bug 61491 - Autocomplete newsgroup names. r=mconley, r=Neil, r=mkmelin, sr=mbanner
This commit is contained in:
Родитель
82c400ec28
Коммит
ee0cc3f6ef
|
@ -3791,16 +3791,22 @@ function LoadIdentity(startup)
|
|||
var idKey = identityElement.value;
|
||||
gCurrentIdentity = MailServices.accounts.getIdentity(idKey);
|
||||
|
||||
let accountKey = null;
|
||||
// Set the account key value on the menu list.
|
||||
if (identityElement.selectedItem) {
|
||||
let accountKey = identityElement.selectedItem.getAttribute("accountkey");
|
||||
accountKey = identityElement.selectedItem.getAttribute("accountkey");
|
||||
identityElement.setAttribute("accountkey", accountKey);
|
||||
hideIrrelevantAddressingOptions(accountKey);
|
||||
}
|
||||
|
||||
let maxRecipients = awGetMaxRecipients();
|
||||
for (let i = 1; i <= maxRecipients; i++)
|
||||
awGetInputElement(i).setAttribute("autocompletesearchparam", idKey);
|
||||
{
|
||||
let params = JSON.parse(awGetInputElement(i).searchParam);
|
||||
params.idKey = idKey;
|
||||
params.accountKey = accountKey;
|
||||
awGetInputElement(i).searchParam = JSON.stringify(params);
|
||||
}
|
||||
|
||||
if (!startup && prevIdentity && idKey != prevIdentity.key)
|
||||
{
|
||||
|
@ -3908,10 +3914,6 @@ function LoadIdentity(startup)
|
|||
function setupAutocomplete()
|
||||
{
|
||||
var autoCompleteWidget = document.getElementById("addressCol2#1");
|
||||
// When autocompleteToMyDomain is off there is no default entry with the domain
|
||||
// appended so reduce the minimum results for a popup to 2 in this case.
|
||||
if (!gCurrentIdentity.autocompleteToMyDomain)
|
||||
autoCompleteWidget.minResultsForPopup = 2;
|
||||
|
||||
// if the pref is set to turn on the comment column, honor it here.
|
||||
// this element then gets cloned for subsequent rows, so they should
|
||||
|
|
|
@ -774,9 +774,9 @@ function DropRecipient(target, recipient)
|
|||
|
||||
function _awSetAutoComplete(selectElem, inputElem)
|
||||
{
|
||||
inputElem.disableAutoComplete = selectElem.value == 'addr_newsgroups' ||
|
||||
selectElem.value == 'addr_followup' ||
|
||||
selectElem.value == 'addr_other';
|
||||
let params = JSON.parse(inputElem.getAttribute('autocompletesearchparam'));
|
||||
params.type = selectElem.value;
|
||||
inputElem.setAttribute('autocompletesearchparam', JSON.stringify(params));
|
||||
}
|
||||
|
||||
function awSetAutoComplete(rowNumber)
|
||||
|
|
|
@ -855,10 +855,11 @@
|
|||
<textbox id="addressCol2#1" class="plain textbox-addressingWidget uri-element"
|
||||
aria-labelledby="addressCol1#1"
|
||||
type="autocomplete" flex="1"
|
||||
autocompletesearch="mydomain addrbook ldap"
|
||||
autocompletesearch="mydomain addrbook ldap news"
|
||||
autocompletesearchparam="{}"
|
||||
timeout="300" maxrows="4"
|
||||
completedefaultindex="true" forcecomplete="true"
|
||||
minresultsforpopup="3" ignoreblurwhilesearching="true"
|
||||
minresultsforpopup="2" ignoreblurwhilesearching="true"
|
||||
ontextentered="awRecipientTextCommand(eventParam, this)"
|
||||
onerrorcommand="awRecipientErrorCommand(eventParam, this)"
|
||||
onchange="onRecipientsInput();"
|
||||
|
|
|
@ -200,6 +200,8 @@
|
|||
@BINPATH@/components/nsBox.js
|
||||
@BINPATH@/components/nsAddrbook.manifest
|
||||
@BINPATH@/components/nsMailNewsCommandLineHandler.js
|
||||
@BINPATH@/components/nsNewsAutoCompleteSearch.js
|
||||
@BINPATH@/components/nsNewsAutoCompleteSearch.manifest
|
||||
@BINPATH@/components/services-crypto-component.xpt
|
||||
#ifndef XP_OS2
|
||||
@BINPATH@/components/shellservice.xpt
|
||||
|
|
|
@ -286,6 +286,13 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
list-style-image: url("chrome://messenger/skin/addressbook/icons/remote-addrbook-error.png");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
-moz-margin-start: 3px;
|
||||
-moz-margin-end: 2px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-pane.png");
|
||||
-moz-image-region: rect(208px 16px 224px 0px);
|
||||
}
|
||||
|
||||
/* ::::: addressing widget ::::: */
|
||||
|
||||
.autocomplete-treebody::-moz-tree-cell-text(comment) {
|
||||
|
|
|
@ -527,6 +527,15 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
}
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: -3px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-pane.png");
|
||||
-moz-image-region: rect(0 160px 16px 144px);
|
||||
}
|
||||
|
||||
/* ::::: addressing widget ::::: */
|
||||
|
||||
#addressingWidget {
|
||||
|
|
|
@ -436,6 +436,13 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
list-style-image: url("chrome://messenger/skin/addressbook/icons/remote-addrbook-error.png");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 5px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder.png");
|
||||
-moz-image-region: rect(0 160px 16px 144px);
|
||||
}
|
||||
|
||||
/* ::::: addressing widget ::::: */
|
||||
|
||||
.autocomplete-treebody::-moz-tree-cell-text(comment) {
|
||||
|
|
|
@ -375,6 +375,13 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
list-style-image: url("chrome://messenger/skin/addressbook/icons/remote-addrbook-error.png");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 3px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder.png");
|
||||
-moz-image-region: rect(0 160px 16px 144px);
|
||||
}
|
||||
|
||||
/* ::::: addressing widget ::::: */
|
||||
|
||||
.autocomplete-treebody::-moz-tree-cell-text(comment) {
|
||||
|
|
|
@ -12,16 +12,20 @@ nsAbAutoCompleteMyDomain.prototype = {
|
|||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Components.interfaces.nsIAutoCompleteSearch]),
|
||||
|
||||
cachedParam: "",
|
||||
cachedIdKey: "",
|
||||
cachedIdentity: null,
|
||||
|
||||
startSearch: function(aString, aParam, aResult, aListener) {
|
||||
applicableHeaders: Set(["addr_to", "addr_cc", "addr_bcc", "addr_reply"]),
|
||||
|
||||
startSearch: function(aString, aSearchParam, aResult, aListener) {
|
||||
let params = JSON.parse(aSearchParam);
|
||||
let applicable = this.applicableHeaders.has(params.type);
|
||||
const ACR = Components.interfaces.nsIAutoCompleteResult;
|
||||
var address = null;
|
||||
if (aString && !aString.contains(",")) {
|
||||
if (aParam != this.cachedParam) {
|
||||
this.cachedIdentity = MailServices.accounts.getIdentity(aParam);
|
||||
this.cachedParam = aParam;
|
||||
if (applicable && aString && !aString.contains(",")) {
|
||||
if (params.idKey != this.cachedIdKey) {
|
||||
this.cachedIdentity = MailServices.accounts.getIdentity(params.idKey);
|
||||
this.cachedIdKey = params.idKey;
|
||||
}
|
||||
if (this.cachedIdentity.autocompleteToMyDomain)
|
||||
address = aString.contains("@") ? aString :
|
||||
|
|
|
@ -80,6 +80,7 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
_commentColumn: 0,
|
||||
_parser: MailServices.headerParser,
|
||||
_abManager: MailServices.ab,
|
||||
applicableHeaders: Set(["addr_to", "addr_cc", "addr_bcc", "addr_reply"]),
|
||||
|
||||
// Private methods
|
||||
|
||||
|
@ -344,7 +345,13 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
*/
|
||||
startSearch: function startSearch(aSearchString, aSearchParam,
|
||||
aPreviousResult, aListener) {
|
||||
let params = JSON.parse(aSearchParam);
|
||||
var result = new nsAbAutoCompleteResult(aSearchString);
|
||||
if (!this.applicableHeaders.has(params.type)) {
|
||||
result.searchResult = ACR.RESULT_IGNORED;
|
||||
aListener.onSearchResult(this, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the search string isn't value, or contains a comma, or the user
|
||||
// hasn't enabled autocomplete, then just return no matches / or the
|
||||
|
@ -428,7 +435,7 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
var dir = allABs.getNext();
|
||||
|
||||
if (dir instanceof Components.interfaces.nsIAbDirectory &&
|
||||
dir.useForAutocomplete(aSearchParam)) {
|
||||
dir.useForAutocomplete(params.idKey)) {
|
||||
this._searchCards(searchQuery, dir, result);
|
||||
this._searchWithinEmails(emailSearchQuery, fullString, dir, result);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,8 @@ nsAbLDAPAutoCompleteSearch.prototype = {
|
|||
|
||||
_parser: MailServices.headerParser,
|
||||
|
||||
applicableHeaders: Set(["addr_to", "addr_cc", "addr_bcc", "addr_reply"]),
|
||||
|
||||
// Private methods
|
||||
|
||||
_checkDuplicate: function _checkDuplicate(card, emailAddress) {
|
||||
|
@ -159,6 +161,10 @@ nsAbLDAPAutoCompleteSearch.prototype = {
|
|||
|
||||
startSearch: function startSearch(aSearchString, aParam,
|
||||
aPreviousResult, aListener) {
|
||||
let params = JSON.parse(aParam);
|
||||
let applicable = this.applicableHeaders.has(params.type);
|
||||
let idKey = params.idKey;
|
||||
|
||||
this._result = new nsAbLDAPAutoCompleteResult(aSearchString);
|
||||
aSearchString = aSearchString.toLocaleLowerCase();
|
||||
|
||||
|
@ -167,7 +173,7 @@ nsAbLDAPAutoCompleteSearch.prototype = {
|
|||
// result ignored.
|
||||
// The comma check is so that we don't autocomplete against the user
|
||||
// entering multiple addresses.
|
||||
if (!aSearchString || aSearchString.contains(",")) {
|
||||
if (!applicable || !aSearchString || aSearchString.contains(",")) {
|
||||
this._result.searchResult = ACR.RESULT_IGNORED;
|
||||
aListener.onSearchResult(this, this._result);
|
||||
return;
|
||||
|
@ -178,9 +184,9 @@ nsAbLDAPAutoCompleteSearch.prototype = {
|
|||
var acDirURI = null;
|
||||
var identity;
|
||||
|
||||
if (aParam) {
|
||||
if (idKey) {
|
||||
try {
|
||||
identity = MailServices.accounts.getIdentity(aParam);
|
||||
identity = MailServices.accounts.getIdentity(idKey);
|
||||
}
|
||||
catch(ex) {
|
||||
Components.utils.reportError("Couldn't get specified identity, falling " +
|
||||
|
|
|
@ -24,6 +24,8 @@ function run_test() {
|
|||
.getService(Components.interfaces.nsIAutoCompleteSearch);
|
||||
|
||||
var obs = new acObserver();
|
||||
let obsNews = new acObserver();
|
||||
let obsFollowup = new acObserver();
|
||||
|
||||
// Set up an identity in the account manager with the default settings
|
||||
let identity = MailServices.accounts.createIdentity();
|
||||
|
@ -32,8 +34,13 @@ function run_test() {
|
|||
identity.autocompleteToMyDomain = false;
|
||||
identity.email = "myemail@foo.invalid";
|
||||
|
||||
// Set up autocomplete parameters
|
||||
let params = JSON.stringify({ idKey: identity.key, type: "addr_to" });
|
||||
let paramsNews = JSON.stringify({ idKey: identity.key, type: "addr_newsgroups" });
|
||||
let paramsFollowup = JSON.stringify({ idKey: identity.key, type: "addr_followup" });
|
||||
|
||||
// Test - Valid search - this should return no results (autocomplete disabled)
|
||||
acs.startSearch("test", identity.key, null, obs);
|
||||
acs.startSearch("test", params, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "test");
|
||||
|
@ -46,7 +53,7 @@ function run_test() {
|
|||
|
||||
// Test - Search with empty string
|
||||
|
||||
acs.startSearch(null, identity.key, null, obs);
|
||||
acs.startSearch(null, params, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, null);
|
||||
|
@ -54,7 +61,7 @@ function run_test() {
|
|||
do_check_eq(obs._result.errorDescription, null);
|
||||
do_check_eq(obs._result.matchCount, 0);
|
||||
|
||||
acs.startSearch("", identity.key, null, obs);
|
||||
acs.startSearch("", params, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "");
|
||||
|
@ -64,7 +71,7 @@ function run_test() {
|
|||
|
||||
// Test - Check ignoring result with comma
|
||||
|
||||
acs.startSearch("a,b", identity.key, null, obs);
|
||||
acs.startSearch("a,b", params, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "a,b");
|
||||
|
@ -74,7 +81,7 @@ function run_test() {
|
|||
|
||||
// Test - Check returning search string with @ sign
|
||||
|
||||
acs.startSearch("a@b", identity.key, null, obs);
|
||||
acs.startSearch("a@b", params, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "a@b");
|
||||
|
@ -88,9 +95,18 @@ function run_test() {
|
|||
do_check_eq(obs._result.getStyleAt(0), "default-match");
|
||||
do_check_eq(obs._result.getImageAt(0), null);
|
||||
|
||||
// No autocomplete for addr_newsgroups!
|
||||
acs.startSearch("a@b", paramsNews, null, obsNews);
|
||||
do_check_true(obsNews._result == null || obsNews._result.matchCount == 0);
|
||||
|
||||
// No autocomplete for addr_followup!
|
||||
acs.startSearch("a@b", paramsFollowup, null, obsFollowup);
|
||||
do_check_true(obsFollowup._result == null || obsFollowup._result.matchCount == 0);
|
||||
|
||||
|
||||
// Test - Add default domain
|
||||
|
||||
acs.startSearch("test1", identity.key, null, obs);
|
||||
acs.startSearch("test1", params, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "test1");
|
||||
|
|
|
@ -105,12 +105,18 @@ function run_test() {
|
|||
.getService(Components.interfaces.nsIAutoCompleteSearch);
|
||||
|
||||
var obs = new acObserver();
|
||||
let obsNews = new acObserver();
|
||||
let obsFollowup = new acObserver();
|
||||
|
||||
// Test - Check disabling of autocomplete
|
||||
|
||||
Services.prefs.setBoolPref("mail.enable_autocomplete", false);
|
||||
|
||||
acs.startSearch("abc", null, null, obs);
|
||||
let param = JSON.stringify({ type: "addr_to" });
|
||||
let paramNews = JSON.stringify({ type: "addr_newsgroups" });
|
||||
let paramFollowup = JSON.stringify({ type: "addr_followup" });
|
||||
|
||||
acs.startSearch("abc", param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "abc");
|
||||
|
@ -122,7 +128,7 @@ function run_test() {
|
|||
|
||||
Services.prefs.setBoolPref("mail.enable_autocomplete", true);
|
||||
|
||||
acs.startSearch(null, null, null, obs);
|
||||
acs.startSearch(null, param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, null);
|
||||
|
@ -133,7 +139,7 @@ function run_test() {
|
|||
|
||||
// Test - Check ignoring result with comma
|
||||
|
||||
acs.startSearch("a,b", null, null, obs);
|
||||
acs.startSearch("a,b", param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "a,b");
|
||||
|
@ -144,7 +150,7 @@ function run_test() {
|
|||
|
||||
// Test - No matches
|
||||
|
||||
acs.startSearch("asjdkljdgfjglkfg", null, null, obs);
|
||||
acs.startSearch("asjdkljdgfjglkfg", param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "asjdkljdgfjglkfg");
|
||||
|
@ -156,7 +162,7 @@ function run_test() {
|
|||
// Test - Matches
|
||||
|
||||
// Basic quick-check
|
||||
acs.startSearch("email", null, null, obs);
|
||||
acs.startSearch("email", param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "email");
|
||||
|
@ -171,10 +177,18 @@ function run_test() {
|
|||
do_check_eq(obs._result.getStyleAt(0), "local-abook");
|
||||
do_check_eq(obs._result.getImageAt(0), "");
|
||||
|
||||
// quick-check that nothing is found for addr_newsgroups
|
||||
acs.startSearch("email", paramNews, null, obsNews);
|
||||
do_check_true(obsNews._result == null || obsNews._result.matchCount == 0);
|
||||
|
||||
// quick-check that nothing is found for addr_followup
|
||||
acs.startSearch("a@b", paramFollowup, null, obsFollowup);
|
||||
do_check_true(obsFollowup._result == null || obsFollowup._result.matchCount == 0);
|
||||
|
||||
// Now quick-check with the address book name in the comment column.
|
||||
Services.prefs.setIntPref("mail.autoComplete.commentColumn", 1);
|
||||
|
||||
acs.startSearch("email", null, null, obs);
|
||||
acs.startSearch("email", param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "email");
|
||||
|
@ -190,7 +204,7 @@ function run_test() {
|
|||
do_check_eq(obs._result.getImageAt(0), "");
|
||||
|
||||
// Check input with different case
|
||||
acs.startSearch("EMAIL", null, null, obs);
|
||||
acs.startSearch("EMAIL", param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, "EMAIL");
|
||||
|
@ -209,7 +223,7 @@ function run_test() {
|
|||
// Now check multiple matches
|
||||
function checkInputItem(element, index, array) {
|
||||
print("Checking " + element.search);
|
||||
acs.startSearch(element.search, null, null, obs);
|
||||
acs.startSearch(element.search, param, null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element.search);
|
||||
|
|
|
@ -171,7 +171,7 @@ function run_test() {
|
|||
|
||||
// Now check multiple matches
|
||||
function checkInputItem(element, index, array) {
|
||||
acs.startSearch(element.search, null, lastResult, obs);
|
||||
acs.startSearch(element.search, JSON.stringify({ type: "addr_to" }), lastResult, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element.search);
|
||||
|
|
|
@ -73,7 +73,7 @@ function run_test()
|
|||
|
||||
function checkInputItem(element, index, array) {
|
||||
print("Checking " + element.search);
|
||||
acs.startSearch(element.search, null, null, obs);
|
||||
acs.startSearch(element.search, JSON.stringify({ type: "addr_to" }), null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element.search);
|
||||
|
|
|
@ -116,7 +116,7 @@ function run_test()
|
|||
print("Checking Initial Searches");
|
||||
|
||||
function checkSearch(element, index, array) {
|
||||
acs.startSearch(element, null, null, obs);
|
||||
acs.startSearch(element, JSON.stringify({ type: "addr_to" }), null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element);
|
||||
|
@ -141,7 +141,7 @@ function run_test()
|
|||
var lastResult = null;
|
||||
|
||||
function checkReductionSearch(element, index, array) {
|
||||
acs.startSearch(element, null, lastResult, obs);
|
||||
acs.startSearch(element, JSON.stringify({ type: "addr_to" }), lastResult, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element);
|
||||
|
|
|
@ -63,7 +63,7 @@ function run_test() {
|
|||
// Now check multiple matches
|
||||
function checkInputItem(element, index, array) {
|
||||
print("Checking " + element.search);
|
||||
acs.startSearch(element.search, null, null, obs);
|
||||
acs.startSearch(element.search, JSON.stringify({ type: "addr_to" }), null, obs);
|
||||
|
||||
do_check_eq(obs._search, acs);
|
||||
do_check_eq(obs._result.searchString, element.search);
|
||||
|
|
|
@ -20,6 +20,11 @@ SOURCES += [
|
|||
'nsNntpUrl.cpp',
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsNewsAutoCompleteSearch.js',
|
||||
'nsNewsAutoCompleteSearch.manifest',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_INCOMPLETE_EXTERNAL_LINKAGE']:
|
||||
FORCE_STATIC_LIB = True
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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/. */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/mailServices.js");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const kACR = Ci.nsIAutoCompleteResult;
|
||||
const kSupportedTypes = Set(["addr_newsgroups", "addr_followup"]);
|
||||
|
||||
function nsNewsAutoCompleteResult(aSearchString) {
|
||||
// Can't create this in the prototype as we'd get the same array for
|
||||
// all instances
|
||||
this._searchResults = [];
|
||||
this.searchString = aSearchString;
|
||||
}
|
||||
|
||||
nsNewsAutoCompleteResult.prototype = {
|
||||
_searchResults: null,
|
||||
|
||||
// nsIAutoCompleteResult
|
||||
|
||||
searchString: null,
|
||||
searchResult: kACR.RESULT_NOMATCH,
|
||||
defaultIndex: -1,
|
||||
errorDescription: null,
|
||||
|
||||
get matchCount() {
|
||||
return this._searchResults.length;
|
||||
},
|
||||
|
||||
getValueAt: function getValueAt(aIndex) {
|
||||
return this._searchResults[aIndex].value;
|
||||
},
|
||||
|
||||
getLabelAt: function getLabelAt(aIndex) {
|
||||
return this._searchResults[aIndex].value;
|
||||
},
|
||||
|
||||
getCommentAt: function getCommentAt(aIndex) {
|
||||
return this._searchResults[aIndex].comment;
|
||||
},
|
||||
|
||||
getStyleAt: function getStyleAt(aIndex) {
|
||||
return "subscribed-news";
|
||||
},
|
||||
|
||||
getImageAt: function getImageAt(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
removeValueAt: function removeValueAt(aRowIndex, aRemoveFromDB) {
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([kACR])
|
||||
}
|
||||
|
||||
function nsNewsAutoCompleteSearch() {}
|
||||
|
||||
nsNewsAutoCompleteSearch.prototype = {
|
||||
// For component registration
|
||||
classDescription: "Newsgroup Autocomplete",
|
||||
classID: Components.ID("e9bb3330-ac7e-11de-8a39-0800200c9a66"),
|
||||
|
||||
cachedAccountKey: "",
|
||||
cachedServer: null,
|
||||
|
||||
/**
|
||||
* Find the newsgroup server associated with the given accountKey.
|
||||
*
|
||||
* @param accountKey The key of the account.
|
||||
* @return The incoming news server (or null if one does not exist).
|
||||
*/
|
||||
_findServer: function _findServer(accountKey) {
|
||||
let account = MailServices.accounts.getAccount(accountKey);
|
||||
|
||||
if (account.incomingServer.type == 'nntp')
|
||||
return account.incomingServer;
|
||||
else
|
||||
return null;
|
||||
},
|
||||
|
||||
// nsIAutoCompleteSearch
|
||||
startSearch: function startSearch(aSearchString, aSearchParam,
|
||||
aPreviousResult, aListener) {
|
||||
let params = JSON.parse(aSearchParam);
|
||||
let result = new nsNewsAutoCompleteResult(aSearchString);
|
||||
if (!params.type || !params.accountKey ||
|
||||
!kSupportedTypes.has(params.type)) {
|
||||
result.searchResult = kACR.RESULT_IGNORED;
|
||||
aListener.onSearchResult(this, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.accountKey != this.cachedAccountKey) {
|
||||
this.cachedAccountKey = params.accountKey;
|
||||
this.cachedServer = this._findServer(params.accountKey);
|
||||
}
|
||||
|
||||
if (this.cachedServer) {
|
||||
let groups = this.cachedServer.rootFolder.subFolders;
|
||||
while (groups.hasMoreElements()) {
|
||||
let curr = groups.getNext().QueryInterface(Ci.nsIMsgFolder);
|
||||
if (curr.prettiestName.contains(aSearchString)) {
|
||||
result._searchResults.push({
|
||||
value: curr.prettiestName,
|
||||
comment: this.cachedServer.prettyName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.matchCount) {
|
||||
result.searchResult = kACR.RESULT_SUCCESS;
|
||||
// If the user does not select anything, use the first entry:
|
||||
result.defaultIndex = 0;
|
||||
}
|
||||
aListener.onSearchResult(this, result);
|
||||
},
|
||||
|
||||
stopSearch: function stopSearch() {
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch])
|
||||
};
|
||||
|
||||
// Module
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([nsNewsAutoCompleteSearch]);
|
|
@ -0,0 +1,2 @@
|
|||
component {e9bb3330-ac7e-11de-8a39-0800200c9a66} nsNewsAutoCompleteSearch.js
|
||||
contract @mozilla.org/autocomplete/search;1?name=news {e9bb3330-ac7e-11de-8a39-0800200c9a66}
|
|
@ -95,6 +95,7 @@ Services.prefs.setBoolPref("mail.strict_threading", true);
|
|||
const NNTP_PORT = 1024+119;
|
||||
|
||||
var _server = null;
|
||||
let _account = null;
|
||||
|
||||
function subscribeServer(incomingServer) {
|
||||
// Subscribe to newsgroups
|
||||
|
@ -111,11 +112,13 @@ function subscribeServer(incomingServer) {
|
|||
function setupLocalServer(port) {
|
||||
if (_server != null)
|
||||
return _server;
|
||||
let server = localAccountUtils.create_incoming_server("nntp", port,
|
||||
null, null);
|
||||
let serverAndAccount =
|
||||
localAccountUtils.create_incoming_server_and_account("nntp", port, null, null);
|
||||
let server = serverAndAccount.server;
|
||||
subscribeServer(server);
|
||||
|
||||
_server = server;
|
||||
_account = serverAndAccount.account;
|
||||
|
||||
return server;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource:///modules/mailServices.js");
|
||||
|
||||
// The basic daemon to use for testing nntpd.js implementations
|
||||
var gDaemon = setupNNTPDaemon();
|
||||
|
||||
const ACR = Components.interfaces.nsIAutoCompleteResult;
|
||||
|
||||
function acObserver() {}
|
||||
|
||||
acObserver.prototype = {
|
||||
_search: null,
|
||||
_result: null,
|
||||
|
||||
onSearchResult: function (aSearch, aResult) {
|
||||
this._search = aSearch;
|
||||
this._result = aResult;
|
||||
}
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
let type = "RFC 977";
|
||||
let localserver = setupLocalServer(NNTP_PORT);
|
||||
let server = makeServer(NNTP_RFC977_handler, gDaemon);
|
||||
server.start(NNTP_PORT);
|
||||
|
||||
// create identity
|
||||
let identity = MailServices.accounts.createIdentity();
|
||||
_account.addIdentity(identity);
|
||||
|
||||
let acs = Components.classes["@mozilla.org/autocomplete/search;1?name=news"]
|
||||
.getService(Components.interfaces.nsIAutoCompleteSearch);
|
||||
let obs;
|
||||
|
||||
let paramsN = JSON.stringify({
|
||||
idKey: identity.key,
|
||||
accountKey: _account.key,
|
||||
type: "addr_newsgroups" });
|
||||
let paramsF = JSON.stringify({
|
||||
idKey: identity.key,
|
||||
accountKey: _account.key,
|
||||
type: "addr_followup" });
|
||||
let paramsMail = JSON.stringify({
|
||||
idKey: identity.key,
|
||||
accountKey: _account.key,
|
||||
type: "addr_to" });
|
||||
|
||||
// misc.test is not subscribed
|
||||
obs = new acObserver();
|
||||
acs.startSearch("misc", paramsN, null, obs);
|
||||
do_check_true(obs._result == null || obs._result.matchCount == 0);
|
||||
|
||||
obs = new acObserver();
|
||||
acs.startSearch("misc", paramsF, null, obs);
|
||||
do_check_true(obs._result == null || obs._result.matchCount == 0);
|
||||
|
||||
obs = new acObserver();
|
||||
acs.startSearch("misc", paramsMail, null, obs);
|
||||
do_check_true(obs._result == null || obs._result.matchCount == 0);
|
||||
|
||||
// test.filter is subscribed
|
||||
obs = new acObserver();
|
||||
acs.startSearch("filter", paramsN, null, obs);
|
||||
do_check_eq(obs._result.matchCount, 1);
|
||||
|
||||
obs = new acObserver();
|
||||
acs.startSearch("filter", paramsF, null, obs);
|
||||
do_check_eq(obs._result.matchCount, 1);
|
||||
|
||||
// ... but no auto-complete should occur for addr_to
|
||||
obs = new acObserver();
|
||||
acs.startSearch("filter", paramsMail, null, obs);
|
||||
do_check_true(obs._result == null || obs._result.matchCount == 0);
|
||||
|
||||
// test.subscribe.empty and test.subscribe.simple are subscribed
|
||||
obs = new acObserver();
|
||||
acs.startSearch("subscribe", paramsN, null, obs);
|
||||
do_check_eq(obs._result.matchCount, 2);
|
||||
|
||||
obs = new acObserver();
|
||||
acs.startSearch("subscribe", paramsF, null, obs);
|
||||
do_check_eq(obs._result.matchCount, 2);
|
||||
|
||||
// ... but no auto-complete should occur for addr_to
|
||||
obs = new acObserver();
|
||||
acs.startSearch("subscribe", paramsMail, null, obs);
|
||||
do_check_true(obs._result == null || obs._result.matchCount == 0);
|
||||
|
||||
// test.subscribe.empty is subscribed, test.empty is not
|
||||
obs = new acObserver();
|
||||
acs.startSearch("empty", paramsN, null, obs);
|
||||
do_check_eq(obs._result.matchCount, 1);
|
||||
|
||||
obs = new acObserver();
|
||||
acs.startSearch("empty", paramsF, null, obs);
|
||||
do_check_eq(obs._result.matchCount, 1);
|
||||
|
||||
server.stop();
|
||||
};
|
|
@ -15,6 +15,7 @@ support-files = postings/*
|
|||
[test_nntpContentLength.js]
|
||||
# The server doesn't support returning sizes! (bug 782629)
|
||||
skip-if = true
|
||||
[test_newsAutocomplete.js]
|
||||
[test_nntpGroupPassword.js]
|
||||
[test_nntpPassword.js]
|
||||
[test_nntpPassword2.js]
|
||||
|
|
|
@ -59,6 +59,23 @@ var localAccountUtils = {
|
|||
* @return The newly-created nsIMsgIncomingServer.
|
||||
*/
|
||||
create_incoming_server: function(aType, aPort, aUsername, aPassword) {
|
||||
let serverAndAccount = localAccountUtils.
|
||||
create_incoming_server_and_account(aType, aPort, aUsername, aPassword);
|
||||
return serverAndAccount.server;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create an nsIMsgIncomingServer and an nsIMsgAccount to go with it.
|
||||
*
|
||||
* @param aType The type of the server (pop3, imap etc).
|
||||
* @param aPort The port the server is on.
|
||||
* @param aUsername The username for the server.
|
||||
* @param aPassword The password for the server.
|
||||
* @return An object with the newly-created nsIMsgIncomingServer as the
|
||||
"server" property and the newly-created nsIMsgAccount as the
|
||||
"account" property.
|
||||
*/
|
||||
create_incoming_server_and_account: function (aType, aPort, aUsername, aPassword) {
|
||||
let server = MailServices.accounts.createIncomingServer(aUsername, "localhost",
|
||||
aType);
|
||||
server.port = aPort;
|
||||
|
@ -80,7 +97,7 @@ var localAccountUtils = {
|
|||
}
|
||||
server.valid = true;
|
||||
|
||||
return server;
|
||||
return {server: server, account: account};
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -758,6 +758,8 @@ bin/libfreebl_32int64_3.so
|
|||
@BINPATH@/components/nsMailNewsCommandLineHandler.js
|
||||
@BINPATH@/components/nsMsgTraitService.js
|
||||
@BINPATH@/components/nsMsgTraitService.manifest
|
||||
@BINPATH@/components/nsNewsAutoCompleteSearch.js
|
||||
@BINPATH@/components/nsNewsAutoCompleteSearch.manifest
|
||||
@BINPATH@/components/nsSMTPProtocolHandler.js
|
||||
@BINPATH@/components/nsSMTPProtocolHandler.manifest
|
||||
@BINPATH@/components/offlineStartup.js
|
||||
|
|
|
@ -2461,9 +2461,18 @@ function LoadIdentity(startup)
|
|||
var idKey = identityElement.value;
|
||||
gCurrentIdentity = gAccountManager.getIdentity(idKey);
|
||||
|
||||
let accountKey = null;
|
||||
if (identityElement.selectedItem)
|
||||
accountKey = identityElement.selectedItem.getAttribute("accountkey");
|
||||
|
||||
let maxRecipients = awGetMaxRecipients();
|
||||
for (let i = 1; i <= maxRecipients; i++)
|
||||
awGetInputElement(i).setAttribute("autocompletesearchparam", idKey);
|
||||
{
|
||||
let params = JSON.parse(awGetInputElement(i).searchParam);
|
||||
params.idKey = idKey;
|
||||
params.accountKey = accountKey;
|
||||
awGetInputElement(i).searchParam = JSON.stringify(params);
|
||||
}
|
||||
|
||||
if (!startup && prevIdentity && idKey != prevIdentity.key)
|
||||
{
|
||||
|
@ -2572,10 +2581,6 @@ function LoadIdentity(startup)
|
|||
function setupAutocomplete()
|
||||
{
|
||||
var autoCompleteWidget = document.getElementById("addressCol2#1");
|
||||
// When autocompleteToMyDomain is off, there is no default entry with the domain
|
||||
// appended, so reduce the minimum results for a popup to 2 in this case.
|
||||
if (!gCurrentIdentity.autocompleteToMyDomain)
|
||||
autoCompleteWidget.minResultsForPopup = 2;
|
||||
|
||||
// if the pref is set to turn on the comment column, honor it here.
|
||||
// this element then gets cloned for subsequent rows, so they should
|
||||
|
|
|
@ -721,9 +721,9 @@ function DropRecipient(recipient)
|
|||
|
||||
function _awSetAutoComplete(selectElem, inputElem)
|
||||
{
|
||||
inputElem.disableAutoComplete = selectElem.value == 'addr_newsgroups' ||
|
||||
selectElem.value == 'addr_followup' ||
|
||||
selectElem.value == 'addr_other';
|
||||
let params = JSON.parse(inputElem.getAttribute('autocompletesearchparam'));
|
||||
params.type = selectElem.value;
|
||||
inputElem.setAttribute('autocompletesearchparam', JSON.stringify(params));
|
||||
}
|
||||
|
||||
function awSetAutoComplete(rowNumber)
|
||||
|
|
|
@ -46,9 +46,10 @@
|
|||
aria-labelledby="addressCol1#1"
|
||||
type="autocomplete" flex="1" maxrows="4"
|
||||
newlines="replacewithcommas"
|
||||
autocompletesearch="mydomain addrbook ldap" timeout="300"
|
||||
autocompletesearch="mydomain addrbook ldap news" timeout="300"
|
||||
autocompletesearchparam="{}"
|
||||
completedefaultindex="true" forcecomplete="true"
|
||||
minresultsforpopup="3" ignoreblurwhilesearching="true"
|
||||
minresultsforpopup="2" ignoreblurwhilesearching="true"
|
||||
ontextentered="awRecipientTextCommand(eventParam, this)"
|
||||
onerrorcommand="awRecipientErrorCommand(eventParam, this)"
|
||||
oninput="gContentChanged=true; setupAutocomplete();" disableonsend="true"
|
||||
|
|
|
@ -215,6 +215,12 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
list-style-image: url("chrome://messenger/skin/addressbook/icons/remote-addrbook-error.gif");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: -3px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-newsgroup.png");
|
||||
}
|
||||
|
||||
/* ::::: lightweight themes ::::: */
|
||||
|
||||
#MsgHeadersToolbar:-moz-lwtheme,
|
||||
|
|
|
@ -256,6 +256,12 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
list-style-image: url("chrome://messenger/skin/addressbook/icons/remote-addrbook-error.gif");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: -3px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-newsgroup.png");
|
||||
}
|
||||
|
||||
/* ::::: lightweight themes ::::: */
|
||||
|
||||
#MsgHeadersToolbar:-moz-lwtheme,
|
||||
|
|
|
@ -200,3 +200,8 @@ treechildren::-moz-tree-image(remote-err) {
|
|||
list-style-image: url("chrome://messenger/skin/addressbook/icons/directory-down.gif");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(subscribed-news) {
|
||||
-moz-margin-start: 3px;
|
||||
-moz-margin-end: -4px;
|
||||
list-style-image: url("chrome://messenger/skin/icons/folder-newsgroup.gif");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче